Просмотр исходного кода

📦 优化点亮村落逻辑,已是志愿者则认领村庄

快乐的梦鱼 недель назад: 2
Родитель
Сommit
de06b64ba7
3 измененных файлов с 232 добавлено и 6 удалено
  1. 26 1
      src/api/inhert/VillageApi.ts
  2. 135 0
      src/pages/home/light/form/claim.ts
  3. 71 5
      src/pages/home/light/submit.vue

+ 26 - 1
src/api/inhert/VillageApi.ts

@@ -126,6 +126,31 @@ export class VolunteerInfo extends DataModel<VolunteerInfo> {
   collectModuleText = '';
 }
 
+export class VillageClaimInfo extends DataModel<VillageClaimInfo> {
+  constructor() {
+    super(VillageClaimInfo, '村落认领');
+    this.setNameMapperCase('Camel', 'Snake');
+    this._convertTable = {
+      villageId: { clientSide: 'number', serverSide: 'number', clientSideRequired: true },
+      sex: { clientSide: 'number', serverSide: 'number' },
+      type: [
+        { clientSide: 'splitCommaArray', serverSide: 'commaArrayMerge' },
+        { clientSide: 'array', clientSideChildDataModel: 'string', serverSide: 'original' },
+      ],
+    };
+  }
+
+  villageId = 0;
+  name = '';
+  type = ['villager'] as string[];
+  mobile = '';
+  address = '';
+  claimReason = '';
+  job = '';
+  unit = '';
+  sex = 3;
+}
+
 export class VillageMenuListItem extends DataModel<VillageMenuListItem> {
   constructor() {
     super(VillageMenuListItem, "村落菜单列表");
@@ -211,7 +236,7 @@ export class VillageApi extends AppServerRequestModule<DataModel> {
     });
     return transformArrayDataModel<VillageListItem>(VillageListItem, transformSomeToArray(res.data), `村落`, true);
   }
-  async claimVallage(data: any) {
+  async claimVallage(data: VillageClaimInfo) {
     return this.post('/village/village/addVillageClaim', '认领村落', data);
   }
   async getVallageList(level?: number, status?: number, region?: string) {

+ 135 - 0
src/pages/home/light/form/claim.ts

@@ -0,0 +1,135 @@
+import type { IDynamicFormOptions, IDynamicFormRef } from '@/components/dynamic';
+import type { CheckBoxListProps } from '@/components/dynamic/wrappers/CheckBoxList.vue';
+import type { RadioValueProps } from '@/components/dynamic/wrappers/RadioValue';
+import type { FieldProps } from '@/components/form/Field.vue';
+import type { FormProps } from '@/components/form/Form.vue';
+import type { RuleItem } from 'async-validator';
+import type { Ref } from 'vue';
+import type { VolunteerInfo } from '@/api/inhert/VillageApi';
+import { VillageClaimInfo } from '@/api/inhert/VillageApi';
+
+function hasClaimType(formRef: Ref<IDynamicFormRef | undefined>, value: string) {
+  const type = formRef.value?.getValueByPath('type');
+  if (Array.isArray(type))
+    return type.includes(value);
+  return type === value;
+}
+
+export function fillClaimFromVolunteer(model: VillageClaimInfo, volunteer: VolunteerInfo) {
+  model.name = volunteer.name || '';
+  model.mobile = volunteer.mobile || '';
+  model.address = volunteer.address || '';
+  model.sex = volunteer.sex || 3;
+  model.job = (volunteer as VolunteerInfo & { job?: string }).job || '';
+  model.unit = (volunteer as VolunteerInfo & { unit?: string }).unit || '';
+  model.claimReason = (volunteer as VolunteerInfo & { claimReason?: string }).claimReason || '';
+  if (volunteer.type) {
+    model.type = volunteer.type.includes(',')
+      ? volunteer.type.split(',').map((s) => s.trim()).filter(Boolean)
+      : [volunteer.type];
+  }
+}
+
+export function getClaimVillageForm(options: {
+  formRef: Ref<IDynamicFormRef | undefined>,
+}): IDynamicFormOptions {
+  return {
+    formItems: [
+      {
+        name: 'groupClaim',
+        type: 'flat-simple',
+        childrenColProps: { span: 24 },
+        children: [
+          {
+            label: '真实姓名',
+            name: 'name',
+            type: 'text',
+            additionalProps: { placeholder: '请输入真实姓名' },
+            rules: [{ required: true, message: '请输入真实姓名' }],
+          },
+          {
+            label: '认领类型',
+            name: 'type',
+            type: 'check-box-list',
+            defaultValue: ['villager'],
+            additionalProps: {
+              multiple: true,
+              vertical: true,
+              useCell: true,
+              loadData: async () => [
+                { text: '村民', value: 'villager' },
+                { text: '志愿者', value: 'volunteer' },
+                { text: '管理人员', value: 'staff' },
+              ],
+            } as CheckBoxListProps,
+            rules: [{ required: true, message: '请选择认领类型' }],
+          },
+          {
+            label: '性别',
+            name: 'sex',
+            type: 'radio-value',
+            defaultValue: 3,
+            additionalProps: {
+              options: [
+                { text: '男', value: 1 },
+                { text: '女', value: 2 },
+                { text: '未知', value: 3 },
+              ],
+            } as RadioValueProps,
+          },
+          {
+            label: '联系方式',
+            name: 'mobile',
+            type: 'text',
+            additionalProps: { placeholder: '请输入手机号' },
+            rules: [{ required: true, message: '请输入联系方式' }],
+          },
+          {
+            label: '居住地址',
+            name: 'address',
+            type: 'text',
+            additionalProps: { placeholder: '请输入居住地址' },
+          },
+          {
+            label: '工作单位',
+            name: 'unit',
+            type: 'text',
+            additionalProps: { placeholder: '请输入工作单位' },
+            show: { callback: () => hasClaimType(options.formRef, 'staff') },
+            rules: [{
+              required: true,
+              message: '请输入工作单位',
+            }] as RuleItem[],
+          },
+          {
+            label: '职位',
+            name: 'job',
+            type: 'text',
+            additionalProps: { placeholder: '请输入职位' },
+            show: { callback: () => hasClaimType(options.formRef, 'staff') },
+            rules: [{
+              required: true,
+              message: '请输入职位',
+            }] as RuleItem[],
+          },
+          {
+            label: '申请理由',
+            name: 'claimReason',
+            type: 'textarea',
+            additionalProps: {
+              placeholder: '请说明认领该村落的原因',
+              showWordLimit: true,
+              maxLength: 200,
+            } as FieldProps,
+          },
+        ],
+      },
+    ],
+    formAdditionaProps: {
+      labelPosition: 'top',
+      innerStyle: {
+        radius: '10rpx',
+      },
+    } as Omit<FormProps, 'model'>,
+  };
+}

+ 71 - 5
src/pages/home/light/submit.vue

@@ -11,12 +11,28 @@
         <Height :height="20" />
         <Button block type="primary" @click="registerSubmit" :loading="registerFormLoading">提交</Button>
       </FlexCol>
+      <!--认领-->
+      <FlexCol v-else-if="step === 'add'">
+        <Alert 
+          type="info"
+          message="您已经是志愿者,请填写以下信息,认领当前村落"
+        />
+        <DynamicForm
+          ref="addFormRef"
+          :model="addFormModel"
+          :options="addFormDefine"
+        />
+        <Height :height="20" />
+        <Button block type="primary" @click="addSubmit" :loading="addFormLoading">提交</Button>
+      </FlexCol>
       <!--注册完成-->
       <Result 
         v-else-if="step === 'finished'" 
         status="success"
-        title="注册志愿者成功"
-        description="请等待管理员审核,在此期间,可以在社区中先逛逛,学习如何采编村社文化资源信息吧"
+        :title="finishedMode === 'claim' ? '认领申请已提交' : '注册志愿者成功'"
+        :description="finishedMode === 'claim'
+          ? '请等待管理员审核认领申请,审核通过后即可采编该村落文化资源'
+          : '请等待管理员审核,在此期间,可以在社区中先逛逛,学习如何采编村社文化资源信息吧'"
       >
         <Height :size="20" />
         <Button type="primary" @click="back()">进入首页</Button>
@@ -67,9 +83,11 @@ import { showError } from '@/common/composeabe/ErrorDisplay';
 import { useLoadQuerys } from '@/common/composeabe/LoadQuerys';
 import { onMounted, ref } from 'vue';
 import { getVolunteerForm } from '@/pages/dig/admin/data/volunteer';
-import VillageApi, { VillageListItem, VolunteerInfo } from '@/api/inhert/VillageApi';
+import VillageApi, { VillageClaimInfo, VillageListItem, VolunteerInfo } from '@/api/inhert/VillageApi';
 import type { IDynamicFormOptions, IDynamicFormRef } from '@/components/dynamic';
 import { assertNotNull, waitTimeOut } from '@imengyu/imengyu-utils';
+import { fillClaimFromVolunteer, getClaimVillageForm } from './form/claim';
+import Alert from '@/components/feedback/Alert.vue';
 
 /**
  * 分享注册页面
@@ -81,7 +99,8 @@ const { init } = useAppInit();
 const { querys } = useLoadQuerys({ 
   villageId: 0,  
 });
-const step = ref<'register'|'finished'|'error'>('register');
+const step = ref<'register' | 'add' | 'finished' | 'error'>('register');
+const finishedMode = ref<'register' | 'claim'>('register');
 const village = ref<VillageListItem>();
 
 onMounted(async () => {
@@ -89,7 +108,24 @@ onMounted(async () => {
     step.value = 'error';
     return;
   }
-  village.value = JSON.parse(uni.getStorageSync('VillageTemp') || '{}'),
+  village.value = JSON.parse(uni.getStorageSync('VillageTemp') || '{}');
+
+  if (authStore.isLogged) {
+    try {
+      const volunteerInfo = await VillageApi.getVolunteerInfo();
+      if (volunteerInfo) {
+        step.value = 'add';
+        addFormDefine.value = getClaimVillageForm({ formRef: addFormRef });
+        const model = new VillageClaimInfo();
+        model.villageId = querys.value.villageId;
+        fillClaimFromVolunteer(model, volunteerInfo);
+        addFormModel.value = model;
+        return;
+      }
+    } catch {
+    }
+  }
+
   await waitTimeOut(1000);
 
   registerFormDefine.value = getVolunteerForm({
@@ -151,6 +187,7 @@ async function registerSubmit() {
     await authStore.loginResultHandle(loginRes, UserApi.LOGIN_TYPE_USER);
     await init();
     toast({ content: '注册成功' });
+    finishedMode.value = 'register';
     step.value = 'finished';
   } catch (e) {
     showError(e);
@@ -158,4 +195,33 @@ async function registerSubmit() {
     registerFormLoading.value = false;
   }
 }
+
+const addFormLoading = ref(false);
+const addFormRef = ref<IDynamicFormRef>();
+const addFormModel = ref<VillageClaimInfo>(new VillageClaimInfo());
+const addFormDefine = ref<IDynamicFormOptions>();
+
+async function addSubmit() {
+  if (!addFormRef.value || !addFormModel.value)
+    return;
+  try {
+    await addFormRef.value.validate();
+  } catch (e) {
+    toast({ content: '有必填项未填写,请检查' });
+    return;
+  }
+
+  try {
+    addFormLoading.value = true;
+    addFormModel.value.villageId = querys.value.villageId;
+    await VillageApi.claimVallage(addFormModel.value as VillageClaimInfo);
+    toast({ content: '提交成功' });
+    finishedMode.value = 'claim';
+    step.value = 'finished';
+  } catch (e) {
+    showError(e);
+  } finally {
+    addFormLoading.value = false;
+  }
+}
 </script>