Browse Source

📦 村落昵称显示与修改

快乐的梦鱼 3 days ago
parent
commit
0b8e54a8b0

+ 16 - 0
src/api/light/LightVillageApi.ts

@@ -432,6 +432,22 @@ export class LightVillageApi extends AppServerRequestModule<DataModel> {
     });
   }
 
+  /**
+   * 修改本志愿者在本村的昵称
+   * POST /village/volunteer/nicknameSave
+   */
+  async nicknameSave(params: {
+    /** 村社ID */
+    villageId: number;
+    /** 村社昵称 */
+    villageNickname: string;
+  }) {
+    return await this.post<KeyValue>('/village/volunteer/nicknameSave', '修改志愿者昵称', {
+      village_id: params.villageId,
+      village_nickname: params.villageNickname,
+    });
+  }
+
 }
 
 

+ 65 - 0
src/pages/home/village/dialogs/ChangeNickDialog.vue

@@ -0,0 +1,65 @@
+<template>
+  <CommonDialog v-model:show="show" title="修改昵称" :showDivider="false">
+    <FlexCol gap="gap.lg" padding="padding.md" width="600rpx">
+      <Text textAlign="center" text="修改您在本村的昵称,可以方便大家认识您" fontConfig="contentSpeicalText" />
+      <Height :height="10" />
+      <Field v-model="name" placeholder="请输入昵称" type="text" showWordLimit :maxLength="30" />
+      <Height :height="20" />
+      <FlexRow justify="space-around" gap="gap.md">
+        <FrameButton text="返回" @click="show = false" width="220rpx" />
+        <FrameButton primary text="提交" @click="addSubmit" :loading="submiting" width="220rpx" />
+      </FlexRow>
+    </FlexCol>
+  </CommonDialog>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue';
+import { toast } from '@/components/dialog/CommonRoot';
+import { showError } from '@/common/composeabe/ErrorDisplay';
+import { useVillageStore } from '@/store/village';
+import CommonDialog from '@/common/components/CommonDialog.vue';
+import FrameButton from '@/common/components/FrameButton.vue';
+import Text from '@/components/basic/Text.vue';
+import FlexCol from '@/components/layout/FlexCol.vue';
+import FlexRow from '@/components/layout/FlexRow.vue';
+import Height from '@/components/layout/space/Height.vue';
+import Field from '@/components/form/Field.vue';
+import LightVillageApi from '@/api/light/LightVillageApi';
+
+const show = ref(false);
+const props = defineProps<{
+  villageId: number;
+}>();
+const emit = defineEmits(['finish']);
+const villageStore = useVillageStore();
+
+const submiting = ref(false);
+const name = ref('');
+
+async function addSubmit() {
+  try {
+    submiting.value = true;
+    await LightVillageApi.nicknameSave({
+      villageId: props.villageId,
+      villageNickname: name.value,
+    });
+    toast({ content: '提交成功' });
+    show.value = false;
+    villageStore.loadMyJoinedVillages();
+    setTimeout(() => {
+      villageStore.reloadVillageInfo();
+    }, 500);
+  } catch (e) {
+    showError(e);
+  } finally {
+    submiting.value = false;
+  }
+}
+
+defineExpose({
+  show: () => {
+    show.value = true;
+  },
+});
+</script>

+ 44 - 14
src/pages/home/village/introd/card.vue

@@ -33,13 +33,31 @@
               {{ isFollowed ? '已关注' : '关注' }}
             </Button>
           </BubbleTip>
+          <FlexRow 
+            v-if="isJoined"
+            gap="gap.md"
+            radius="radius.lgr"
+            backgroundColor="background.tertiary"
+          >
+            <Avatar 
+              :src="authStore.userInfo?.avatar" 
+              :size="65"
+              defaultAvatar="https://xy.wenlvti.net/app_static/images/mine/DefaultAvatar.png"
+            />
+            <FlexCol gap="gap.sm" :padding="[0,30,0,0]">
+              <Text :text="displayMyName" fontSize="23" :lines="1" :maxWidth="200" fontConfig="lightImportantTitle" />
+              <IconButton icon="edit-filling" size="26" @click="changeNickRef?.show()">
+                <Text text="改昵称" fontSize="22" fontConfig="subText" />
+              </IconButton>
+            </FlexCol>
+          </FlexRow>
           <Button 
+            v-else
             icon="https://xy.wenlvti.net/app_static/images/village/IconFollow.png"
             radius="radius.lgr"
+            text="加入"
             @click="handleGoJoin()"
-          >
-            {{ isJoined ? '已加入' : '加入' }}
-          </Button>
+          />
         </FlexRow>
       </FlexRow>
 
@@ -263,6 +281,11 @@
     v-if="villageStore.currentVillage"
     :villageId="villageStore.currentVillage.id"
   />
+  <ChangeNickDialog 
+    v-if="villageStore.currentVillage"
+    :villageId="villageStore.currentVillage.id"
+    ref="changeNickRef"
+  />  
   <Popup 
     :show="showUnLight"
     :zIndex="100"
@@ -304,8 +327,10 @@ import { useSimpleDataLoader } from '@/components/composeabe/loader/SimpleDataLo
 import { useVillageStore } from '@/store/village';
 import { useRequireLogin } from '@/common/composeabe/RequireLogin';
 import { useFollow } from '../composeabe/Follow';
-import { ArrayUtils, assertNotNull, FormatUtils, waitTimeOut } from '@imengyu/imengyu-utils';
+import { useGetNotice } from '../composeabe/GetNotice';
+import { assertNotNull, FormatUtils, waitTimeOut } from '@imengyu/imengyu-utils';
 import { navTo } from '@/components/utils/PageAction';
+import { confirm } from '@/components/dialog/CommonRoot';
 import HomeTitle from '@/common/components/parts/HomeTitle.vue';
 import Icon from '@/components/basic/Icon.vue';
 import Text from '@/components/basic/Text.vue';
@@ -331,13 +356,18 @@ import Button from '@/components/basic/Button.vue';
 import BubbleTip from '@/components/feedback/BubbleTip.vue';
 import MemoryTimeOut from '@/components/composeabe/MemoryTimeOut';
 import TextEllipsis from '@/components/display/TextEllipsis.vue';
-import { confirm, toast } from '@/components/dialog/CommonRoot';
-import { useGetNotice } from '../composeabe/GetNotice';
 import OfficialApi from '@/api/light/OfficialApi';
 import FrameButton from '@/common/components/FrameButton.vue';
 import Width from '@/components/layout/space/Width.vue';
 import Popup from '@/components/dialog/Popup.vue';
 import Image from '@/components/basic/Image.vue';
+import Avatar from '@/components/display/Avatar.vue';
+import ChangeNickDialog from '../dialogs/ChangeNickDialog.vue';
+
+const emit = defineEmits<{
+  (e: 'goTree'): void;
+  (e: 'goJoin'): void;
+}>();
 
 const authStore = useAuthStore();
 const { getIsVolunteer } = useUserTools();
@@ -351,9 +381,6 @@ const { onPublishSuccess } = useOfficialAccount(() => {
 });
 const villageStore = useVillageStore();
 const { isFollowed, onFollow, onUnFollow } = useFollow();
-const isLight = computed(() => {
-  return villageStore.currentVillage?.isLight ?? false;
-});
 const { getIsJoinedVillage } = useUserTools();
 const isOfficialEmpty = ref(false);
 const isJoined = ref(false);
@@ -387,11 +414,13 @@ const villageInfoLoader = useSimpleDataLoader(async () => {
     latitude: village?.latitude || 0,
   };
 });
-
-const emit = defineEmits<{
-  (e: 'goTree'): void;
-  (e: 'goJoin'): void;
-}>();
+const isLight = computed(() => {
+  return villageStore.currentVillage?.isLight ?? false;
+});
+const displayMyName = computed(() => {
+  const villageInfoInList = villageStore.myJoinedVillages.find(v => v.id === villageStore.currentVillage?.id);
+  return villageInfoInList?.villageNickname || authStore.userInfo?.nickname || authStore.userInfo?.username || '暂无昵称';
+});
 
 const rankActiveTag = ref('文化积分');
 const listActiveTag = ref('广场');
@@ -532,6 +561,7 @@ const { currentNoticeContent, noticeListLoader } = useGetNotice(() => villageSto
 
 const upgradeRef = ref<InstanceType<typeof UpgradeDialog>>();
 const villageGalleryRef = ref<InstanceType<typeof VillageGallery>>();
+const changeNickRef = ref<InstanceType<typeof ChangeNickDialog>>();
 
 watch(() => villageStore.currentVillage, async () => {
   await waitTimeOut(100);