快乐的梦鱼 před 2 měsíci
rodič
revize
b62e71591c

+ 12 - 2
src/api/inhert/VillageApi.ts

@@ -85,8 +85,15 @@ export class VolunteerInfo extends DataModel<VolunteerInfo> {
       id: { clientSide: 'number', serverSide: 'number', clientSideRequired: true },
       points: [{ clientSide: 'number', serverSide: 'number' }, { clientSide: CONVERTER_ADD_DEFAULT, clientSideParam: { defaultValue: 0 } }],
       level: [{ clientSide: 'number', serverSide: 'number' }, { clientSide: CONVERTER_ADD_DEFAULT, clientSideParam: { defaultValue: 0 } }],
-      collectModule: { clientSide: 'splitCommaArray', serverSide: 'commaArrayMerge' },
+      collectModule: [
+        { clientSide: 'splitCommaArray',serverSide: 'commaArrayMerge' },
+        { clientSide: 'array', clientSideChildDataModel: 'number', serverSide: 'original' },
+      ],
       birthday: { clientSide: 'date', serverSide: 'undefined' },
+      catalogIds: [
+        { clientSide: 'splitCommaArray', serverSide: 'commaArrayMerge' },
+        { clientSide: 'array', clientSideChildDataModel: 'number', serverSide: 'original' },
+      ],
     }
   }
 
@@ -109,7 +116,7 @@ export class VolunteerInfo extends DataModel<VolunteerInfo> {
   sexText = '';
   statusText = '';
   catalogIds = [] as number[];
-  collectModule = [] as string[];
+  collectModule = [] as number[];
   collectModuleText = '';
 }
 
@@ -150,6 +157,8 @@ export class VillageCatalogListItem extends DataModel<VillageCatalogListItem> {
         this.typeId = findAProp(this.otherParams, [
           { type: 'endWith', name: 'type' },
           { type: 'match', name: 'nature' },
+          { type: 'match', name: 'cultural' },
+          { type: 'selectAtLestOne' },
         ]);
       }
     }
@@ -226,6 +235,7 @@ export class VillageApi extends AppServerRequestModule<DataModel> {
     return (this.post('/village/volunteer/add', data.toServerSide(), '添加志愿者')) ;
   }
   async updateVolunteer(data: VolunteerInfo) {
+    console.log('updateVolunteer', data.toServerSide());
     return (this.post('/village/volunteer/save', data.toServerSide(), '更新志愿者')) ;
   }
   async getVolunteerInfoByIdAdmin(id: number) {

+ 2 - 0
src/common/composeabe/LoadQuerys.ts

@@ -17,6 +17,8 @@ export function useLoadQuerys<T extends Record<string, any>>(
       for (const key in querys.value) {
         if (typeof defaults[key] === 'number')
           (querys.value as Record<string, any>)[key] = Number(_querys[key]); 
+        else if (typeof defaults[key] === 'boolean')
+          (querys.value as Record<string, any>)[key] = _querys[key] === 'true'; 
         else
           querys.value[key] = _querys[key];
       }

+ 6 - 0
src/common/utils/ConvertRgeistry.ts

@@ -39,6 +39,12 @@ export function registryConvert() {
     key: 'SplitCommaArray',
     targetType: 'splitCommaArray',
     converter: (source, key, type) => {
+      if (typeof source === 'object' && source instanceof Array) {
+        return {
+          success: true,
+          result: source || [],
+        }
+      }
       if (typeof source === 'string') {
         if (source === '') 
           return { success: true, result: [] }

+ 3 - 3
src/components/dynamic/DynamicForm.vue

@@ -71,10 +71,10 @@ provide('globalParams', toRef(props, 'globalParams'));
 provide('finalOptions', finalOptions);
 
 const formEditor = ref<FormInstance>();
-const widgetsRefMap = ref<Record<string,() => unknown>>({});
+const widgetsRefMap = ref(new Map<string,() => unknown>());
 const messageCenterMap = new Map<string, IDynamicFormMessageCenterCallback>();
   
-provide('widgetsRefMap', widgetsRefMap.value);
+provide('widgetsRefMap', widgetsRefMap);
 provide('messageCenter', {
   addInstance: (name: string, fn: IDynamicFormMessageCenterCallback) => messageCenterMap.set(name, fn),
   removeInstance: (name: string) => messageCenterMap.delete(name),
@@ -82,7 +82,7 @@ provide('messageCenter', {
 
 //获取组件引用
 function getFormItemControlRef(key: string) {
-  return widgetsRefMap.value[key]?.();
+  return widgetsRefMap.value.get(key)?.();
 }
 
 //通过路径访问

+ 3 - 0
src/components/dynamic/DynamicFormControl.vue

@@ -386,6 +386,7 @@ const data = computed<FormCeilProps>(() => {
 })
 
 const itemRef = ref();
+const widgetsRefMap = inject<Ref<Map<string, unknown>>>('widgetsRefMap');
  
 function onValueChanged(v: any) {
   props.item.watch?.(props.model, v, props.rawModel, getComponentRef());
@@ -399,9 +400,11 @@ function getComponentRef() {
 
 onMounted(() => {
   props.item.mounted?.(props.model, props.rawModel, getComponentRef());
+  widgetsRefMap?.value?.set(props.item.name, getComponentRef);
 })
 onBeforeUnmount(() => {
   props.item.beforeUnmount?.(props.model, props.rawModel, getComponentRef()); 
+  widgetsRefMap?.value?.delete(props.item.name);
 })
 
 defineOptions({

+ 5 - 1
src/components/form/UploaderField.vue

@@ -78,7 +78,11 @@ onMounted(() => {
 });
 
 defineExpose({
-  getUploaderRef: () => uploaderRef.value,
+  getUploaderRef: () => {
+    console.log('getUploaderRef', uploaderRef.value);
+    
+    return uploaderRef.value
+  },
 })
 
 export interface UploaderFieldInstance {

+ 9 - 5
src/pages/dig/admin.vue

@@ -32,15 +32,14 @@
         </Touchable>
       </button>
 
-      <Touchable 
+      <FlexRow 
         v-for="item in listLoader.list.value"
         :key="item.id" 
         backgroundColor="white" 
         radius="20"
+        justify="space-between"
         :padding="20"
         :gap="20"
-        direction="row"
-        @click="goDetail(item.id)"
       >
         <Image :src="item.image" width="150rpx" height="150rpx" round radius="30" />
         <FlexCol>
@@ -49,7 +48,11 @@
           <Text :fontSize="26" :text="`地址:${item.address || ''}`" />
           <Text :fontSize="26" :text="`可采编:${item.collectModuleText || '暂无'}`" />
         </FlexCol>
-      </Touchable>
+        <FlexRow align="center" :flexShrink="0">
+          <NButton @click="goDetail(item.id, true)">改密码</NButton>
+          <NButton type="primary" @click="goDetail(item.id)">编辑</NButton>
+        </FlexRow>
+      </FlexRow>
     </FlexCol>
     <SimplePageListLoader :loader="listLoader" :noEmpty="true">
       <template #empty>
@@ -120,11 +123,12 @@ function newData() {
     villageVolunteerId: querys.value.villageVolunteerId,  
   });
 }
-function goDetail(id: number) {
+function goDetail(id: number, onlyPassword: boolean = false) {
   navTo('./admin/volunteer', { 
     id,
     villageId: querys.value.id,  
     villageVolunteerId: querys.value.villageVolunteerId,  
+    onlyPassword,
   });
 }
 function search() {

+ 121 - 98
src/pages/dig/admin/volunteer.vue

@@ -45,107 +45,125 @@ const formRef = ref<IDynamicFormRef>();
 const formModel = ref<VolunteerInfo>();
 const formDefine : IDynamicFormOptions = {
   formItems: [
-    { 
-      label: '用户名', name: 'username', type: 'text',
-      additionalProps: { 
-        placeholder: '请输入用户名',
-      },
-      rules: [{ required: true, message: '请输入用户名' }],
-      show: { callback: () => isNew.value },
-    },
-    {
-      label: '密码',
-      name: 'password',
-      type: 'text',
-      additionalProps: { 
-        placeholder: '请输入密码',
-        type: 'password',
-      } as FieldProps,
-      rules: [{ required: true, message: '请输入密码' }],
-    },
     {
-      label: '确认密码',
-      name: 'passwordRepeat',
-      type: 'text',
-      additionalProps: { 
-        placeholder: '请再输入一次密码',
-        type: 'password',
-      } as FieldProps,
-      rules: [
-        { required: true, message: '请再输入一次密码' },
-        {
-          async validator(rule, value) {
-            if (value != formRef.value?.getValueByPath('password'))
-              throw '两次输入密码不一致,请检查';
+      name: 'groupBase',
+      type: 'flat-simple',
+      children: [
+        { 
+          label: '用户名', name: 'username', type: 'text',
+          additionalProps: { 
+            placeholder: '请输入用户名',
           },
-        }
-      ] as RuleItem[],
-    },
-    {
-      label: '真实名称', name: 'name', type: 'text',
-      additionalProps: { placeholder: '请输入真实名称' },
-      rules: [{ required: true, message: '请输入真实名称' }],
-    },
-    {
-      label: '手机号', name: 'mobile', type: 'text',
-      additionalProps: { placeholder: '请输入手机号' },
-      rules: [{ required: true, message: '请输入手机号' }],
-    },
-    { 
-      label: '区域', name: 'regionId', type: 'select-id',
-      additionalProps: {
-        placeholder: '请选择区域',
-        disabled: { callback: () => !isNew.value },
-        loadData: async () => (await CommonContent.getCategoryList(1)).map(p => ({ text: p.title, value: p.id, raw: p }))
-      } as IDynamicFormItemCallbackAdditionalProps<PickerIdFieldProps>,
-      rules: [{ required: true, message: '请选择区域' }],
+          rules: [{ required: true, message: '请输入用户名' }],
+          show: { callback: () => isNew.value },
+        },
+        {
+          label: '密码',
+          name: 'password',
+          type: 'text',
+          additionalProps: { 
+            placeholder: '请输入密码',
+            type: 'password',
+          } as FieldProps,
+          rules: [{ required: true, message: '请输入密码' }],
+          show: { callback: () => isNew.value || querys.value.onlyPassword },
+        },
+        {
+          label: '确认密码',
+          name: 'passwordRepeat',
+          type: 'text',
+          additionalProps: { 
+            placeholder: '请再输入一次密码',
+            type: 'password',
+          } as FieldProps,
+          rules: [
+            { required: true, message: '请再输入一次密码' },
+            {
+              async validator(rule, value) {
+                if (value != formRef.value?.getValueByPath('password'))
+                  throw '两次输入密码不一致,请检查';
+              },
+            }
+          ] as RuleItem[],
+          show: { callback: () => isNew.value || querys.value.onlyPassword },
+        },
+      ]
     },
     {
-      label: '性别', name: 'sex', type: 'radio-value',
-      additionalProps: {
-        options: [
-          { text: '男', value: 1 },
-          { text: '女', value: 2 }
-        ]
-      } as RadioValueProps,
-    },
-    { 
-      label: '头像', name: 'image', type: 'uploader',
-      additionalProps: {
-        single: true,
-        
-        maxFileSize: 1024 * 1024 * 10,
-        upload: useAliOssUploadCo('xiangyuan/volunteer/images')
-      } as UploaderFieldProps,
-    },
-    { label: '地址', name: 'address', type: 'text', additionalProps: { placeholder: '请输入地址' } },
-    { 
-      label: '介绍', 
-      name: 'intro', 
-      type: 'textarea', 
-      additionalProps: { 
-        placeholder: '请输入介绍',
-        showWordLimit: true,
-        maxLength: 200,
-      } as FieldProps,
-    },
-    { 
-      label: '采集版块', name: 'catalogIds', type: 'check-box-tree', 
-      additionalProps: { 
-        placeholder: '请选择采集版块',
-        vertical: true,
-        multiple: true,
-        loadData: async (pid) => (await VillageApi.getCatalogList(querys.value.villageId, pid)).map((p) => ({
-          text: p.title,
-          value: p.id,
-          hasChildren: p.haschild,
-        })),
-      } as CheckBoxTreeListProps,
-    },
-    { 
-      label: '村落认领说明', name: 'claimReason', type: 'text', 
-      additionalProps: { placeholder: '请输入村落认领说明' } ,
-      show: { callback: () => isNew.value },
+      name: 'groupExtra',
+      type: 'flat-simple',
+      show: { callback: () => querys.value.onlyPassword == false },
+      childrenColProps: {
+        span: 24,
+      },
+      children: [
+        {
+          label: '真实名称', name: 'name', type: 'text',
+          additionalProps: { placeholder: '请输入真实名称' },
+          rules: [{ required: true, message: '请输入真实名称' }],
+        },
+        {
+          label: '手机号', name: 'mobile', type: 'text',
+          additionalProps: { placeholder: '请输入手机号' },
+          rules: [{ required: true, message: '请输入手机号' }],
+        },
+        { 
+          label: '区域', name: 'regionId', type: 'select-id',
+          additionalProps: {
+            placeholder: '请选择区域',
+            disabled: { callback: () => !isNew.value },
+            loadData: async () => (await CommonContent.getCategoryList(1)).map(p => ({ text: p.title, value: p.id, raw: p }))
+          } as IDynamicFormItemCallbackAdditionalProps<PickerIdFieldProps>,
+          rules: [{ required: true, message: '请选择区域' }],
+        },
+        {
+          label: '性别', name: 'sex', type: 'radio-value',
+          additionalProps: {
+            options: [
+              { text: '男', value: 1 },
+              { text: '女', value: 2 }
+            ]
+          } as RadioValueProps,
+        },
+        { 
+          label: '头像', name: 'image', type: 'uploader',
+          additionalProps: {
+            single: true,
+
+            maxFileSize: 1024 * 1024 * 10,
+            upload: useAliOssUploadCo('xiangyuan/volunteer/images')
+          } as UploaderFieldProps,
+        },
+        { label: '地址', name: 'address', type: 'text', additionalProps: { placeholder: '请输入地址' } },
+        { 
+          label: '介绍', 
+          name: 'intro', 
+          type: 'textarea', 
+          additionalProps: { 
+            placeholder: '请输入介绍',
+            showWordLimit: true,
+            maxLength: 200,
+          } as FieldProps,
+        },
+        { 
+          label: '采集版块', name: 'catalogIds', type: 'check-box-tree', 
+          additionalProps: { 
+            placeholder: '请选择采集版块',
+            vertical: true,
+            multiple: true,
+            loadData: async (pid) => (await VillageApi.getCatalogList(querys.value.villageId, pid)).map((p) => ({
+              text: p.title,
+              value: p.id,
+              hasChildren: p.haschild,
+            })),
+          } as CheckBoxTreeListProps,
+        },
+        { 
+          label: '村落认领说明', name: 'claimReason', type: 'text', 
+          additionalProps: { placeholder: '请输入村落认领说明' } ,
+          show: { callback: () => isNew.value },
+        },
+      ]
     },
   ],
   formAdditionaProps: {
@@ -169,6 +187,8 @@ async function submit() {
   try {
     loading.value = true;
     formModel.value!.villageId = querys.value.villageId;
+    console.log('formModel.value', formModel.value);
+    
     if (querys.value.id >= 0) {
       await VillageApi.updateVolunteer(formModel.value!);
     } else {
@@ -198,6 +218,7 @@ function backPrev(needRefresh: boolean) {
 const { querys } = useLoadQuerys({ 
   villageId: 0,  
   villageVolunteerId: 0,
+  onlyPassword: false,
   id: 0,
 }, async (querys) => {
   loading.value = true;
@@ -222,8 +243,10 @@ const { querys } = useLoadQuerys({
   }
    
   await nextTick();
-
   formRef.value.initDefaultValuesToModel();
+
+  console.log('formModel.value', formModel.value);
+  
 });
 const isNew = computed(() => querys.value.id < 0);
 

+ 5 - 11
src/pages/dig/components/CollectModuleList.vue

@@ -47,23 +47,20 @@ const props = defineProps<{
 }>();
 
 async function loadList() {
-  const { villageId, taskName, taskPid } = props;
-  if (taskName) {
-    currentTaskDefItems.value = TaskMenuDef[taskName].list.concat();
-    currentTaskBanner.value = TaskMenuDef[taskName].banner;
+  if (props.taskName) {
+    currentTaskDefItems.value = TaskMenuDef[props.taskName].list.concat();
+    currentTaskBanner.value = TaskMenuDef[props.taskName].banner;
   } else {
     currentTaskDefItems.value = TaskRootDef
   }
-  if (taskPid >= 0) {
-    const res = (await VillageApi.getCatalogList(villageId, taskPid));
+  if (props.taskPid >= 0) {
+    const res = (await VillageApi.getCatalogList(props.villageId, props.taskPid));
     if (res.length === 0)
       return;
     currentTaskDefItems.value = res
       .map(item => {
         try {
           const collectModuleInternalName = getCollectModuleInternalNameById(item.collectModuleId);
-          if (!collectModuleInternalName && item.collectModuleId)
-            throw new Error('您暂无权限采集该板块');
           const formDefine = collectModuleInternalName ? getVillageInfoForm(collectModuleInternalName, -1) : undefined;
           return {
             ...item,
@@ -136,7 +133,4 @@ const handleClick = (item: TaskMenuDefItem) => {
     item.onClick();
   }
 }
-
-
-
 </script>

+ 2 - 2
src/pages/dig/details.vue

@@ -86,14 +86,14 @@ const { canCollect, isEmpty } = useCollectStore();
 const { goForm } = useTaskEntryForm();
 
 function goCollect() {
-  if (!canCollect('collect')) {
+  /* if (!canCollect('collect')) {
     uni.showToast({
       title: '您当前没有可采编随手记的权限',
       icon: 'none',
       duration: 2000
     });
     return;
-  }
+  } */
   goForm('collect', 1, '随手记')
 }
 </script>

+ 106 - 102
src/pages/dig/forms/data/cultural.ts

@@ -92,110 +92,114 @@ export const villageInfoCulture : GroupForm = {
       },
     ],
   }), { title: '历史文献', typeName: 'culturalType', }],
-  [4]: [CommonInfoModel, (m) => ({
-    formItems: [
-      ...villageCommonContent(m, {
-        title: '口述历史',
-        showTitle: true,
-        noCloseExtra: true,
-      }).formItems.slice(0, 1),
-      {
-        label: '口述人', 
-        name: 'speakerId',
-        type: 'select-id', 
-        additionalProps: {
-          loadData: { 
-            callback(_, m, p, i) { 
-              const collectStore = useCollectStore();
-              return async () => (await VillageInfoApi.getList(
-                collectStore.getCollectModuleId('speaker'),
-                'speaker', undefined, undefined,
-                i.formGlobalParams.villageId,
-                i.formGlobalParams.villageVolunteerId
-              ))
-              .map((p) => ({
-                value: p.id,
-                text: p.name,
-              }))
-            } 
-          },
-        } as IDynamicFormItemCallbackAdditionalProps<PickerIdFieldProps>,
-        formProps: { showRightArrow: true } as FieldProps,
-        rules: [{
-          required: true,
-          message: '请选择口述人',
-        }],
-      },
-      {
-        label: '口述人管理',
-        type: 'button',
-        name: 'manage',
-        defaultValue: '',
-        additionalProps: {
-          text: '口述人管理',
-          onClick: { callback(v, m, p, i) {
-            return () => {
-              const collectStore = useCollectStore();
-              if (!collectStore.getCollectModuleId('speaker')) {
-                uni.showToast({
-                  title: '您暂无权限采编口述人,请联系管理员。',
-                  icon: 'none',
-                  duration: 3000
+  [4]: [CommonInfoModel, (m) => {
+    const common = villageCommonContent(m, {
+      title: '口述历史',
+      showTitle: true,
+      noCloseExtra: true,
+    }).formItems;
+    common.splice(1, 1);
+    return {
+      formItems: [
+        ...common,
+        {
+          label: '口述人', 
+          name: 'speakerId',
+          type: 'select-id', 
+          additionalProps: {
+            loadData: { 
+              callback(_, m, p, i) { 
+                const collectStore = useCollectStore();
+                return async () => (await VillageInfoApi.getList(
+                  collectStore.getCollectModuleId('speaker'),
+                  'speaker', undefined, undefined,
+                  i.formGlobalParams.villageId,
+                  i.formGlobalParams.villageVolunteerId
+                ))
+                .map((p) => ({
+                  value: p.id,
+                  text: p.name,
+                }))
+              } 
+            },
+          } as IDynamicFormItemCallbackAdditionalProps<PickerIdFieldProps>,
+          formProps: { showRightArrow: true } as FieldProps,
+          rules: [{
+            required: true,
+            message: '请选择口述人',
+          }],
+        },
+        {
+          label: '口述人管理',
+          type: 'button',
+          name: 'manage',
+          defaultValue: '',
+          additionalProps: {
+            text: '口述人管理',
+            onClick: { callback(v, m, p, i) {
+              return () => {
+                const collectStore = useCollectStore();
+                if (!collectStore.getCollectModuleId('speaker')) {
+                  uni.showToast({
+                    title: '您暂无权限采编口述人,请联系管理员。',
+                    icon: 'none',
+                    duration: 3000
+                  });
+                  return;
+                }
+                goFormStatic(
+                  i.formGlobalParams.villageId,
+                  i.formGlobalParams.villageVolunteerId,
+                  'speaker',
+                  1,
+                  undefined,
+                  undefined,
+                  '口述人管理'
+                );
+              }
+            } } as IDynamicFormItemCallback<() => void>,
+          } as IDynamicFormItemCallbackAdditionalProps<ButtonProp>,
+          formProps: {
+            inputAlign: 'right'
+          } as FieldProps,
+        },
+        {
+          label: '口述历史视频/录音',
+          name: 'video',
+          type: 'uploader',
+          defaultValue: '',
+          additionalProps: {
+            upload: useAliOssUploadCo('xiangyuan/cultural/video'),
+            chooseType: 'video',
+            maxFileSize: 1024 * 1024 * 20,
+            single: true,
+          } as UploaderFieldProps,
+          formProps: {
+            extraMessage: '您可以上传已经录制好的口述历史视频/录音,也可以点击下方按钮录制新的音频。但小程序中录音时长最长10分钟,如需更长时间,请使用系统相机拍摄。',
+          } as FieldProps,
+        },
+        {
+          label: '',
+          name: 'video1',
+          type: 'recorder',
+          defaultValue: '',
+          additionalProps: {
+            onRecordDone: (path: string) => {
+              if (m.value.getValueByPath('video')) {
+                (m.value.getFormItemControlRef<UploaderFieldInstance>('annex')?.getUploaderRef() as UploaderInstance).addItemAndUpload({
+                  filePath: path,
+                  state: 'notstart',
+                });
+              } else {
+                (m.value.getFormItemControlRef<UploaderFieldInstance>('video')?.getUploaderRef() as UploaderInstance).addItemAndUpload({
+                  filePath: path,
+                  state: 'notstart',
                 });
-                return;
               }
-              goFormStatic(
-                i.formGlobalParams.villageId,
-                i.formGlobalParams.villageVolunteerId,
-                'speaker',
-                1,
-                undefined,
-                undefined,
-                '口述人管理'
-              );
-            }
-          } } as IDynamicFormItemCallback<() => void>,
-        } as IDynamicFormItemCallbackAdditionalProps<ButtonProp>,
-        formProps: {
-          inputAlign: 'right'
-        } as FieldProps,
-      },
-      {
-        label: '口述历史视频/录音',
-        name: 'video',
-        type: 'uploader',
-        defaultValue: '',
-        additionalProps: {
-          upload: useAliOssUploadCo('xiangyuan/cultural/video'),
-          chooseType: 'video',
-          maxFileSize: 1024 * 1024 * 20,
-          single: true,
-        } as UploaderFieldProps,
-        formProps: {
-          extraMessage: '您可以上传已经录制好的口述历史视频/录音,也可以点击下方按钮录制新的音频。但小程序中录音时长最长10分钟,如需更长时间,请使用系统相机拍摄。',
-        } as FieldProps,
-      },
-      {
-        label: '',
-        name: 'video1',
-        type: 'recorder',
-        defaultValue: '',
-        additionalProps: {
-          onRecordDone: (path: string) => {
-            if (m.value.getValueByPath('video')) {
-              (m.value.getFormItemControlRef<UploaderFieldInstance>('annex')?.getUploaderRef() as UploaderInstance).addItemAndUpload({
-                filePath: path,
-                state: 'notstart',
-              });
-            } else {
-              (m.value.getFormItemControlRef<UploaderFieldInstance>('video')?.getUploaderRef() as UploaderInstance).addItemAndUpload({
-                filePath: path,
-                state: 'notstart',
-              });
             }
-          }
+          },
         },
-      },
-    ],
-  }), { title: '口述历史', typeName: 'culturalType', }],
+      ],
+    }
+  }, { title: '口述历史', typeName: 'culturalType', }],
 }

+ 3 - 3
src/pages/dig/forms/list.vue

@@ -56,6 +56,9 @@ import { useSimplePageListLoader } from '@/common/composeabe/SimplePageListLoade
 import { ref } from 'vue';
 import { DataDateUtils } from '@imengyu/js-request-transform';
 import { useLoadQuerys } from '@/common/composeabe/LoadQuerys';
+import { useCollectStore } from '@/store/collect';
+import { onPullDownRefresh } from '@dcloudio/uni-app';
+import { navTo } from '@/components/utils/PageAction';
 import SimplePageListLoader from '@/common/components/SimplePageListLoader.vue';
 import VillageInfoApi from '@/api/inhert/VillageInfoApi';
 import Image from '@/components/basic/Image.vue';
@@ -65,13 +68,10 @@ import SearchBar from '@/components/form/SearchBar.vue';
 import FlexCol from '@/components/layout/FlexCol.vue';
 import FlexRow from '@/components/layout/FlexRow.vue';
 import Text from '@/components/basic/Text.vue';
-import { navTo } from '@/components/utils/PageAction';
 import Height from '@/components/layout/space/Height.vue';
 import H4 from '@/components/typography/H4.vue';
 import Touchable from '@/components/feedback/Touchable.vue';
 import XBarSpace from '@/components/layout/space/XBarSpace.vue';
-import { useCollectStore } from '@/store/collect';
-import { onPullDownRefresh } from '@dcloudio/uni-app';
 
 const subTitle = ref('');
 const searchText = ref('');

+ 1 - 1
src/pages/home/index.vue

@@ -147,7 +147,7 @@ const recommendLoader = useSimpleDataLoader(async () => {
 });
 
 const discoverLoader = useSimpleDataLoader(async () => {
-  return (await VillageInfoApi.getListForDiscover(undefined, 1, 10)).list.map((item) => {
+  return (await VillageInfoApi.getListForDiscover(1, 10)).list.map((item) => {
     return {
       ...item,
       image: (item.thumbnail || item.image) as string,

+ 10 - 6
src/pages/home/village/details.vue

@@ -8,6 +8,7 @@
         :interval="2000"
         :duration="1000"
         :style="{
+          width: '100%',
           height: '500rpx',
         }"
       >
@@ -16,6 +17,7 @@
             :src="item" 
             :radius="20"
             :height="500"
+            :width="750"
             mode="aspectFill"
             touchable
             @click="onPreviewImage(k)"
@@ -23,7 +25,7 @@
         </swiper-item>
       </swiper>
 
-      <FlexCol :padding="20" :radius="20">
+      <FlexCol :padding="20" :radius="20" :gap="20">
 
         <FlexCol>
           <SubTitle :title="data.villageName" />
@@ -50,18 +52,19 @@
           </FlexCol>
         </FlexCol>
 
-        <FlexCol :margin="[20, 0, 0, 0]" wrap>
-          <FlexCol 
+        <FlexRow :margin="[40, 0, 40, 0]" wrap>
+          <Touchable 
             v-for="(tag, key) in tagsData"
             :key="key"
             width="20%"
             align="center"
+            direction="column"
             @click="goList(tag)"
           >
-            <Image :src="tag.image" width="100%" mode="widthFix"></Image>
+            <Image :src="tag.image" width="80%" mode="widthFix"></Image>
             <Text fontConfig="subText" textAlign="center">{{ tag.title }}</Text>
-          </FlexCol>
-        </FlexCol>
+          </Touchable>
+        </FlexRow>
 
         <FlexCol :margin="[20, 0, 30, 0]">
           <SubTitle title="地理位置" />
@@ -136,6 +139,7 @@ import Image from '@/components/basic/Image.vue';
 import Text from '@/components/basic/Text.vue';
 import FlexRow from '@/components/layout/FlexRow.vue';
 import Cell from '@/components/basic/Cell.vue';
+import Touchable from '@/components/feedback/Touchable.vue';
 
 const EmptyImage = 'https://mncdn.wenlvti.net/app_static/minnan/EmptyImage.png';
 

+ 5 - 2
src/store/collect.ts

@@ -30,6 +30,7 @@ export const useCollectStore = defineStore('collect', () => {
     return collectableModules.value.get(module);
   }
   function getCollectModuleInternalNameById(id: number) {
+    console.log('collectableModules.value', id, collectableModules.value);
     for (const [key, value] of collectableModules.value) {
       if (value == id) {
         for (const k2 in CollectableModulesNameMapping) {
@@ -49,16 +50,18 @@ export const useCollectStore = defineStore('collect', () => {
     const needRemoveKeys = new Set<string>();
     if (!authStore.isAdmin) {
       for (const [key,id] of collectableModulesMap)
-        if (!collectableModules.includes(key))
+        if (!collectableModules.includes(id))
           needRemoveKeys.add(key);
     }
     for (const key of needRemoveKeys)
       collectableModulesMap.delete(key);
     collectableCatalogs.value = res.catalogIds || [];
+    console.log('collectableModulesMap', collectableModulesMap);
+    
     setCollectableModules(collectableModulesMap);
   }
   
-  const isEmpty = computed(() => collectableModules.value.size === 0);
+  const isEmpty = computed(() => collectableModules.value.size === 0 && collectableCatalogs.value.length === 0);
 
   return { 
     isEmpty,