Kaynağa Gözat

表单组件库修改

快乐的梦鱼 2 ay önce
ebeveyn
işleme
e81cda890d

+ 4 - 4
src/common/components/dynamicf/ComponentRender.vue

@@ -1,7 +1,7 @@
 <template>
   <!-- 在下方添加自定义组件 -->
   <!-- 业务代码开始 -->
-  <template v-if="formDefineItem.type === 'richtext'">
+  <template v-if="item.type === 'richtext'">
     <RichTextEditor
       ref="itemRef"
       :modelValue="modelValue"
@@ -9,7 +9,7 @@
       v-bind="params"
     />
   </template>
-  <template v-else-if="formDefineItem.type === 'recorder'">
+  <template v-else-if="item.type === 'recorder'">
     <Recorder
       ref="itemRef"
       :modelValue="modelValue"
@@ -19,7 +19,7 @@
   </template>
   <!-- 业务代码结束 -->
   <template v-else>
-    <text>Fallback: unknow form type {{ formDefineItem.type }}</text>
+    <text>Fallback: unknow form type '{{ item.type }}' item: {{  JSON.stringify(item) }}</text>
   </template>
 </template>
 
@@ -33,7 +33,7 @@ const props = defineProps({
   modelValue: {
     type: null
   },
-  formDefineItem: {
+  item: {
     type: Object as PropType<IDynamicFormItem>,
     default: () => ({})
   },

+ 1 - 1
src/common/components/form/RichTextEditor.vue

@@ -7,7 +7,7 @@
     <view class="d-flex flex-row gap-sss align-center mt-2">
       <Button icon="browse" text="预览" size="small" @click="preview" />
       <Button icon="edit" text="编辑" size="small" @click="edit" type="primary" />
-      <text v-if="maxLength > 0">{{ modelValue.length }}/{{ maxLength }} 字</text>
+      <text v-if="maxLength > 0">{{ modelValue?.length || 0 }}/{{ maxLength }} 字</text>
     </view>
   </view>
 </template>

+ 1 - 1
src/components/dynamic/DynamicForm.ts

@@ -8,7 +8,7 @@ export interface IDynamicFormOptions {
   /**
    * 表单额外属性
    */
-  formAdditionaProps?: FormProps;  
+  formAdditionaProps?: Omit<FormProps, 'model'>;  
   /**
    * 表单校验规则
    */

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

@@ -3,14 +3,14 @@
     ref="formEditor"
     :name="name"
     v-bind="finalOptions.formAdditionaProps"
-    :model="model"
+    :model="model || {}"
     :rules="finalOptions.formRules"
     @submit="(e) => emit('submit', e)"
     @submitFailed="() => emit('finishFailed')"
   >
     <DynamicFormRoot 
       :options="finalOptions"
-      :model="model.value"
+      :model="model"
       :name="name"
     />
   </Form>

+ 1 - 1
src/components/dynamic/DynamicFormControl.vue

@@ -239,7 +239,7 @@ import RadioIdField from './wrappers/RadioIdField.vue';
 import type { RadioIdFieldProps } from './wrappers/RadioIdField';
 import Rate, { type RateProps } from '../form/Rate.vue';
 import ComponentConfigs from '@/common/components/dynamicf/ComponentConfigs';
-import ComponentRender from '@/common/component/dynamicf/ComponentRender.vue';
+import ComponentRender from '@/common/components/dynamicf/ComponentRender.vue';
 import type { Rules } from 'async-validator';
 
 export interface FormCeilProps {

Dosya farkı çok büyük olduğundan ihmal edildi
+ 3 - 0
src/components/dynamic/Images/IconAdd.vue


+ 3 - 0
src/components/dynamic/Images/IconCheck.vue

@@ -0,0 +1,3 @@
+<template>
+  <svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M369.792 704.32L930.304 128 1024 223.616 369.984 896l-20.288-20.864-0.128 0.128L0 516.8 96.128 423.68l273.664 280.64z"></path></svg>
+</template>

Dosya farkı çok büyük olduğundan ihmal edildi
+ 3 - 0
src/components/dynamic/Images/IconDelete.vue


+ 3 - 0
src/components/dynamic/Images/IconDown.vue

@@ -0,0 +1,3 @@
+<template>
+  <svg  viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M904 332c0-8.189-3.124-16.379-9.372-22.628-12.497-12.496-32.759-12.496-45.256 0L512 646.745 174.628 309.372c-12.497-12.496-32.758-12.496-45.255 0-12.497 12.498-12.497 32.758 0 45.256l360 360c12.497 12.496 32.758 12.496 45.255 0l360-360C900.876 348.379 904 340.189 904 332z"></path></svg>
+</template>

Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
src/components/dynamic/Images/IconError.svg


+ 3 - 0
src/components/dynamic/Images/IconUp.vue

@@ -0,0 +1,3 @@
+<template>
+  <svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M904 692c0 8.189-3.124 16.379-9.372 22.628-12.497 12.496-32.759 12.496-45.256 0L512 377.255 174.628 714.628c-12.497 12.496-32.758 12.496-45.255 0-12.497-12.498-12.497-32.758 0-45.256l360-360c12.497-12.496 32.758-12.496 45.255 0l360 360C900.876 675.621 904 683.811 904 692z"></path></svg>
+</template>

Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
src/components/dynamic/Images/IconWarning.svg


+ 2 - 2
src/components/dynamic/group/FormGroup.vue

@@ -19,7 +19,7 @@
 
 <script lang="ts" setup>
 import { ref } from "vue";
-import Row from "../DynamicFormBasicControls/Layout/Row.vue";
+import Row from "@/components/layout/grid/Row.vue";
 import IconDown from "../Images/IconDown.vue";
 
 const props = defineProps({
@@ -74,7 +74,7 @@ const collapsed = ref(props.collapsed);
 
 <style lang="scss">
 .dynamic-form-group {
-  padding: 10px;
+  padding: 10px 0;
   background-color: var(--dynamic-form-background-color);
   border-radius: var(--dynamic-form-border-radius);
 

+ 0 - 6
src/components/dynamic/nest/DynamicFormItemContainer.vue

@@ -37,7 +37,6 @@
           <span v-if="item.label" class="dynamic-form-object-title">{{ evaluateCallback(item.label) }}</span>
         </template>
       </DynamicFormItemNormal>
-      <DynamicFormItemEditorContainerEmptyNote v-if="showContainerEmptyNote" />
       <!--循环子条目-->
       <DynamicFormItemContainer 
         v-for="(child, k) in item.children"
@@ -65,7 +64,6 @@
       checkType="object"
     >
       <FormGroup :title="evaluateCallback(item.label)" v-bind="(item.additionalProps as object)">
-        <DynamicFormItemEditorContainerEmptyNote v-if="showContainerEmptyNote" />
         <Row v-bind="item.rowProps">
           <!--循环子条目-->
           <DynamicFormItemContainer 
@@ -89,7 +87,6 @@
     </DynamicFormCheckEmpty>
     <!--扁平组-->
     <FormGroup v-else-if="item.type === 'flat-group'" :title="evaluateCallback(item.label)" v-bind="(item.additionalProps as object)">
-      <DynamicFormItemEditorContainerEmptyNote v-if="showContainerEmptyNote" />
       <Row v-bind="item.rowProps">
         <!--循环子条目-->
         <DynamicFormItemContainer 
@@ -126,7 +123,6 @@
       :parentName="parentName"
     >
       <template #insertion>
-        <DynamicFormItemEditorContainerEmptyNote v-if="showContainerEmptyNote" />
         <Row v-bind="item.rowProps">
           <!--循环子条目-->
           <DynamicFormItemContainer 
@@ -172,7 +168,6 @@
         :parentName="name"
       >
         <template #insertion>
-          <DynamicFormItemEditorContainerEmptyNote v-if="showContainerEmptyNote" />
           <FormArrayGroup
             :model="(finalModel as unknown as unknown[])"
             :item="item"
@@ -231,7 +226,6 @@
         :isLast="isLast"
       >
         <template #insertion>
-          <DynamicFormItemEditorContainerEmptyNote v-if="showContainerEmptyNote" />
           <FormArrayGroup
             :model="(finalModel as unknown as unknown[])"
             :item="item"

+ 1 - 0
src/components/form/Form.vue

@@ -132,6 +132,7 @@ const props = withDefaults(defineProps<FormProps>(), {
   addRequireMark: true,
   clearValidResult: true,
   colon: true,
+  model: () => ({}),
 });
 
 const currentFocusField = ref<FormItemInternalContext>();

+ 4 - 0
src/components/form/UploaderField.vue

@@ -55,6 +55,10 @@ defineExpose({
   getUploaderRef: () => uploaderRef.value,
 })
 
+export interface UploaderFieldInstance {
+  getUploaderRef: () => UploaderInstance;
+}
+
 defineOptions({
   options: {
     styleIsolation: "shared",

+ 22 - 0
src/components/index.scss

@@ -22,3 +22,25 @@
 wx-action-sheet-item {
   padding: 0!important;
 }
+
+:root {
+  --dynamic-form-primary-color: #1a91f3;
+  --dynamic-form-primary-color2: #79bbff;
+  --dynamic-form-error-color: #e74a4a;
+  --dynamic-form-error-color2: #ffdddd;
+  --dynamic-form-warning-color: #f5a623;
+  --dynamic-form-warning-color2: #ffe5ac;
+  --dynamic-form-secondary-color: #666;
+  --dynamic-form-background-color: #f7f7f7;
+  --dynamic-form-background-hover-color: #ebebeb;
+  --dynamic-form-placeholder-color: #bbbbbb;
+  --dynamic-form-border-color: #dcdfe6;
+  --dynamic-form-base-color: #fff;
+  --dynamic-form-text-color: #333;
+  --dynamic-form-text-light-color: #fff;
+  --dynamic-form-shadow-color: rgba(0, 0, 0, 0.06);
+  --dynamic-form-shadow-darker-color: rgba(0, 0, 0, 0.1);
+  --dynamic-form-shadow-primary-color: rgba(26, 145, 243, 0.2);
+  --dynamic-form-shadow-error-color: rgba(232, 74, 74, 0.2);
+  --dynamic-form-item-nest-margin: 20px;
+}

+ 6 - 0
src/components/layout/grid/Col.vue

@@ -7,6 +7,7 @@
       flexBasis: pec > 0 ? `${pec}%` : undefined,
       marginLeft: offset ? `${(offset / GRID_SIZE) * 100}%` : undefined,
       maxWidth: pec > 0 ? `${pec}%` : undefined,
+      flexShrink: shrink ? 1 : 0,
       ...(innerStyle || {}),
     }"
   >
@@ -35,6 +36,11 @@ export interface ColProps extends FlexProps {
    * 列元素宽度
    */
   span?: number;
+  /**
+   * 是否允许缩小
+   * @default false
+   */
+  shrink?: boolean;
 }
 
 defineOptions({

+ 2 - 2
src/components/layout/grid/Row.vue

@@ -5,7 +5,7 @@
     :style="{
       display: inline ? 'flex-inline' : 'flex',
       flex: flex,
-      flexWrap: wrap !== false ? 'wrap' : 'nowrap',
+      flexWrap: wrap ? 'wrap' : 'nowrap',
       gap: resolveThemeSize(gutter),
       ...(innerStyle || {}),
     }"
@@ -49,7 +49,7 @@ const props = withDefaults(defineProps<RowProps>(), {
    */
   gutter: 0,
   flex: 1,
-  wrap: false,
+  wrap: true,
   inline: false,
 })
 

+ 31 - 20
src/pages/dig/forms/common.vue

@@ -4,16 +4,9 @@
     <FlexCol :padding="30">
       <DynamicForm
         ref="formRef"
-        :formDefine="formDefine"
-        :formProps="({
-          labelWidth: '200rpx',
-          labelAlign: 'left',
-          innerStyle: {
-            borderRadius: '20rpx',
-            overflow: 'hidden',
-          },
-        })"
-        :formGlobalParams="querys"
+        :options="formDefine"
+        :model="formModel"formModel
+        :globalParams="querys"
       />
       <Height :height="20" />
       <Button type="primary" @click="submit">提交</Button>
@@ -23,7 +16,7 @@
 </template>
 
 <script setup lang="ts">
-import { ref } from 'vue';
+import { ref, type Ref } from 'vue';
 import { showError } from '@/common/composeabe/ErrorDisplay';
 import { useLoadQuerys } from '@/common/composeabe/LoadQuerys';
 import { getVillageInfoForm } from './forms';
@@ -38,27 +31,42 @@ import type { IDynamicFormOptions, IDynamicFormRef } from '@/components/dynamic'
 import Height from '@/components/layout/space/Height.vue';
 import { backAndCallOnPageBack } from '@/components/utils/PageAction';
 import XBarSpace from '@/components/layout/space/XBarSpace.vue';
+import { toast } from '@/components/utils/DialogAction';
 
 const loading = ref(false);
 const subTitle = ref('');
 
 const formRef = ref<IDynamicFormRef>();
-const formDefine = ref<IDynamicFormOptions>();
+const formModel = ref(new CommonInfoModel()) as Ref<CommonInfoModel>;
+const formDefine = ref<IDynamicFormOptions>({
+  formItems: [],
+  formAdditionaProps: {
+    labelWidth: '200rpx',
+    labelAlign: 'left',
+    innerStyle: {
+      borderRadius: '20rpx',
+      overflow: 'hidden',
+    },
+  },
+});
 
 async function submit() {
   if (!formRef.value)
     return;
   try {
-    const data = await formRef.value.submitForm<CommonInfoModel>();
-    if (!data)
-      return;
+    await formRef.value.validate();
+  } catch {
+    toast('有必填项未填写,请检查');
+    return;
+  }
+  try {
     loading.value = true;
-    data.type = querys.value.subId;
+    formModel.value.type = querys.value.subId;
     await VillageInfoApi.updateInfo(
       querys.value.subType,
       querys.value.villageId,
       querys.value.villageVolunteerId,
-      data,
+      formModel.value as CommonInfoModel,
     );
   } catch (e) {
     showError(e);
@@ -92,8 +100,11 @@ const { querys } = useLoadQuerys({
 
   try {
     const [model, forms] = getVillageInfoForm(querys.subType, querys.subId);
-    formRef.value.initFormData(() => new model());
-    formDefine.value = forms(formRef as any);
+    formModel.value = new model() as any;
+    formDefine.value = {
+      ...formDefine.value,
+      ...forms(formRef as any)
+    };
     if (querys.id >= 0)
       formData = await VillageInfoApi.getInfo(
         querys.subType, 
@@ -111,7 +122,7 @@ const { querys } = useLoadQuerys({
   }
 
   if (formData) {
-    formRef.value.loadFormData(formData);
+    formModel.value = formData as any;
   }
 });
 </script>

+ 412 - 0
src/pages/dig/forms/data/building.ts

@@ -0,0 +1,412 @@
+import VillageInfoApi, { VillageBulidingInfo } from "@/api/inhert/VillageInfoApi";
+import type { CheckBoxListProps } from "@/components/dynamic/wrappers/CheckBoxList.vue";
+import type { PickerIdFieldProps } from "@/components/dynamic/wrappers/PickerIdField";
+import type { FieldProps } from "@/components/form/Field.vue";
+import type { SingleForm } from "../forms";
+
+export const villageInfoBuildingForm : SingleForm = [VillageBulidingInfo, () => ({
+  formItems: [
+    {
+      label: '建筑名称', 
+      name: 'name', 
+      type: 'text', 
+      defaultValue: '',
+      additionalProps: {
+        placeholder: '请输入建筑名称',
+      },
+      rules:  [{
+        required: true,
+        message: '请输入建筑名称',
+      }] 
+    }, 
+    {
+      label: '建筑编码', 
+      name: 'code', 
+      type: 'text', 
+      defaultValue: '',
+      additionalProps: {
+        placeholder: '请输入建筑编码',
+      },
+      rules:  [{
+        required: true,
+        message: '请输入建筑编码',
+      }] 
+    },
+    {
+      label: '产权归属', 
+      name: 'ownership',
+      type: 'select-id', 
+      additionalProps: {
+        loadData: async () => 
+        (await VillageInfoApi.getCategoryChildList(152))
+          .map((p) => ({
+            value: p.id,
+            text: p.title,
+          }))
+        ,
+      } as PickerIdFieldProps,
+      formProps: { showRightArrow: true } as FieldProps,
+      rules: [{
+        required: true,
+        message: '请选择产权归属',
+      }],
+    },
+    {
+      label: '位置', 
+      name: 'position', 
+      type: 'text', 
+      defaultValue: '',
+      additionalProps: {
+        placeholder: '请输入位置',
+      },
+      rules:  [{
+        required: true,
+        message: '请输入位置',
+      }] 
+    },
+    {
+      label: '建筑类型', 
+      name: 'buildingType',
+      type: 'select-id', 
+      additionalProps: {
+        loadData: async () => 
+        (await VillageInfoApi.getCategoryChildList(163))
+          .map((p) => ({
+            value: p.id,
+            text: p.title,
+          }))
+        ,
+      } as PickerIdFieldProps,
+      formProps: { showRightArrow: true } as FieldProps,
+      rules: [{
+        required: true,
+        message: '请选择建筑类型',
+      }],
+    },
+    {
+      label: '建筑中的故事', 
+      name: 'story', 
+      type: 'richtext', 
+      defaultValue: '',
+      additionalProps: {
+        placeholder: '请输入建筑中的故事',
+        maxLength: 200,
+        showWordLimit: true, 
+      },
+      rules:  [{
+        required: true,
+        message: '请输入建筑中的故事',
+      }] 
+    },
+    {
+      label: '保护级别', 
+      name: 'protectionLevel',
+      type: 'select-id', 
+      additionalProps: {
+        loadData: async () => 
+        (await VillageInfoApi.getCategoryChildList(171))
+          .map((p) => ({
+            value: p.id,
+            text: p.title,
+          }))
+        ,
+      } as PickerIdFieldProps,
+      formProps: { showRightArrow: true } as FieldProps,
+      rules: [{
+        required: true,
+        message: '请选择建筑类型',
+      }],
+    },
+    {
+      label: '总占地面积', 
+      name: 'area', 
+      type: 'text', 
+      defaultValue: '',
+      additionalProps: {
+        placeholder: '请输入总占地面积',
+      },
+      rules:  [{
+        required: true,
+        message: '请输入总占地面积',
+      }] 
+    },
+    {
+      label: '建筑面积', 
+      name: 'buildingArea', 
+      type: 'text', 
+      defaultValue: '',
+      additionalProps: {
+        placeholder: '请输入建筑面积',
+      },
+      rules:  [{
+        required: true,
+        message: '请输入建筑面积',
+      }] 
+    },
+    {
+      label: '建筑层数', 
+      name: 'floor', 
+      type: 'number', 
+      defaultValue: 0,
+      additionalProps: {
+        min: 0,
+        max: 1000,
+      },
+      rules:  [{
+        required: true,
+        message: '请输入建筑层数',
+      }] 
+    },
+    {
+      label: '所含建筑幢数', 
+      name: 'num', 
+      type: 'number', 
+      defaultValue: 0,
+      additionalProps: {
+        min: 0,
+        max: 1000,
+      },
+      rules:  [{
+        required: true,
+        message: '请输入所含建筑幢数',
+      }] 
+    },
+    {
+      label: '始建时间(年)', 
+      name: 'age', 
+      type: 'number', 
+      defaultValue: 2025,
+      additionalProps: {
+        min: -50000,
+        max: 2000,
+      },
+      rules:  [{
+        required: true,
+        message: '请输入始建时间',
+      }] 
+    },
+    {
+      label: '功能特点', 
+      name: 'funcFeatures', 
+      type: 'richtext', 
+      defaultValue: '',
+      additionalProps: {
+        placeholder: '请输入功能特点',
+        maxLength: 200,
+        showWordLimit: true, 
+      },
+      rules:  [{
+        required: true,
+        message: '请输入功能特点',
+      }] 
+    },
+    {
+      label: '承重结构(多选)', 
+      name: 'bearingType', 
+      type: 'check-box-list', 
+      additionalProps: {
+        multiple: true,
+        loadData: async () => 
+        (await VillageInfoApi.getCategoryChildList(246))
+          .map((p) => ({
+            value: p.id,
+            text: p.title,
+          }))
+        ,
+      } as CheckBoxListProps,
+      defaultValue: [],
+      rules: [{
+        required: true,
+        message: '请选择类型',
+      }],
+    },
+    {
+      label: '其他建筑类型', 
+      name: 'otherBuildingType', 
+      type: 'text', 
+      defaultValue: '',
+      additionalProps: { placeholder: '其他建筑类型' },
+      rules: []
+    },
+    {
+      label: '居民建筑类型', 
+      name: 'residentialBuildingType', 
+      type: 'text', 
+      defaultValue: '',
+      additionalProps: { placeholder: '居民建筑类型' },
+      rules: []
+    },
+    {
+      label: '其他保护级别', 
+      name: 'otherProtectionLevel', 
+      type: 'text', 
+      defaultValue: '',
+      additionalProps: { placeholder: '其他保护级别' },
+      rules: []
+    },
+    {
+      label: '修缮过程', 
+      name: 'repairProcess', 
+      type: 'text', 
+      defaultValue: '',
+      additionalProps: { placeholder: '修缮过程' },
+      rules: []
+    },
+    {
+      label: '建筑风貌', 
+      name: 'architecturalStyle', 
+      type: 'text', 
+      defaultValue: '',
+      additionalProps: { placeholder: '建筑风貌' },
+      rules: []
+    },
+    {
+      label: '院落布局', 
+      name: 'layout', 
+      type: 'text', 
+      defaultValue: '',
+      additionalProps: { placeholder: '院落布局' },
+      rules: []
+    },
+    {
+      label: '其他承重结构类型', 
+      name: 'otherBearing', 
+      type: 'text', 
+      defaultValue: '',
+      additionalProps: { placeholder: '其他承重结构类型' },
+      rules: []
+    },
+    {
+      label: '屋面形式(多选)', 
+      name: 'roofForm', 
+      type: 'check-box-list', 
+      additionalProps: {
+        multiple: true,
+        loadData: async () => 
+        (await VillageInfoApi.getCategoryChildList(264))
+          .map((p) => ({
+            value: p.id,
+            text: p.title,
+          }))
+        ,
+      } as CheckBoxListProps,
+      defaultValue: [],
+      rules: [],
+    },
+    {
+      label: '屋面形式说明', 
+      name: 'roofDescribe', 
+      type: 'text', 
+      defaultValue: '',
+      additionalProps: { placeholder: '屋面形式说明' },
+      rules: []
+    },
+    {
+      label: '围护墙体(多选)', 
+      name: 'wallType', 
+      type: 'check-box-list', 
+      additionalProps: {
+        multiple: true,
+        loadData: async () => 
+        (await VillageInfoApi.getCategoryChildList(271))
+          .map((p) => ({
+            value: p.id,
+            text: p.title,
+          }))
+        ,
+      } as CheckBoxListProps,
+      defaultValue: [],
+      rules: [],
+    },
+    {
+      label: '围护墙体说明', 
+      name: 'otherBuildingType', 
+      type: 'text', 
+      defaultValue: '',
+      additionalProps: { placeholder: '围护墙体说明' },
+      rules: []
+    },
+    {
+      label: '地面做法(多选)', 
+      name: 'floorType', 
+      type: 'check-box-list', 
+      additionalProps: {
+        multiple: true,
+        loadData: async () => 
+        (await VillageInfoApi.getCategoryChildList(258))
+          .map((p) => ({
+            value: p.id,
+            text: p.title,
+          }))
+        ,
+      } as CheckBoxListProps,
+      defaultValue: [],
+      rules: [],
+    },
+    {
+      label: '地面做法说明', 
+      name: 'floorDescribe', 
+      type: 'text', 
+      defaultValue: '',
+      additionalProps: { placeholder: '地面做法说明' },
+      rules: []
+    },
+    {
+      label: '特殊工艺做法', 
+      name: 'specialProcess', 
+      type: 'text', 
+      defaultValue: '',
+      additionalProps: { placeholder: '特殊工艺做法' },
+      rules: []
+    },
+    {
+      label: '历史功能', 
+      name: 'funcHistory', 
+      type: 'text', 
+      defaultValue: '',
+      additionalProps: { placeholder: '历史功能' },
+      rules: []
+    },
+    {
+      label: '现状用途(多选)', 
+      name: 'purpose', 
+      type: 'check-box-list', 
+      additionalProps: {
+        multiple: true,
+        loadData: async () => 
+        (await VillageInfoApi.getCategoryChildList(252))
+          .map((p) => ({
+            value: p.id,
+            text: p.title,
+          }))
+        ,
+      } as CheckBoxListProps,
+      defaultValue: [],
+      rules: [],
+    },
+    {
+      label: '其他现状用途', 
+      name: 'otherPurpose', 
+      type: 'text', 
+      defaultValue: '',
+      additionalProps: { placeholder: '其他现状用途' },
+      rules: []
+    },
+    {
+      label: '改扩建情况及维修状况', 
+      name: 'repair', 
+      type: 'text', 
+      defaultValue: '',
+      additionalProps: { placeholder: '改扩建情况及维修状况' },
+      rules: []
+    },
+    {
+      label: '改扩建情况及维修状况说明', 
+      name: 'repairDescribe', 
+      type: 'text', 
+      defaultValue: '',
+      additionalProps: { placeholder: '改扩建情况及维修状况说明' },
+      rules: []
+    },
+  ] 
+})]

+ 63 - 0
src/pages/dig/forms/data/common.ts

@@ -0,0 +1,63 @@
+import { useAliOssUploadCo } from "@/common/components/upload/AliOssUploadCo";
+import type { IDynamicFormOptions, IDynamicFormRef } from "@/components/dynamic";
+import type { UploaderFieldProps } from "@/components/form/UploaderField.vue";
+import type { Ref } from "vue";
+
+export const villageCommonContent : (model: Ref<IDynamicFormRef>) => IDynamicFormOptions = (model) => ({
+  formItems: [
+    {
+      name: 'a',
+      type: 'flat-group',
+      childrenColProps: { span: 24 },
+      children: [
+        {
+          label: '文章标题',
+          name: 'title',
+          type: 'text',
+          defaultValue: '',
+          additionalProps: {
+            placeholder: '请输入标题',
+          },
+          rules: [{
+            required: true,
+            message: '请输入文章标题',
+          }]
+        },
+        {
+          label: '主要内容',
+          name: 'content',
+          type: 'richtext',
+          defaultValue: '',
+          additionalProps: {
+            placeholder: '请输入介绍内容',
+            maxLength: 1000,
+          },
+          rules: [{
+            required: true,
+            message: '请输入内容',
+          }]
+        },
+        {
+          label: '相关图片(可选)',
+          name: 'images',
+          type: 'uploader',
+          defaultValue: '',
+          additionalProps: {
+            upload: useAliOssUploadCo('xiangyuan/common'),
+            maxFileSize: 1024 * 1024 * 20,
+            maxUploadCount: 20,
+          } as UploaderFieldProps,
+          rules: []
+        },
+      ],
+    },
+    {
+      name: 'b',
+      type: 'flat-group',
+      childrenColProps: { span: 24 },
+      children: [
+          
+      ],
+    },
+  ]
+});

+ 69 - 0
src/pages/dig/forms/data/cultural.ts

@@ -0,0 +1,69 @@
+import VillageInfoApi, { VillageBulidingInfo } from "@/api/inhert/VillageInfoApi";
+import type { SingleForm } from "../forms";
+import type { IDynamicFormItemCallbackAdditionalProps } from "@/components/dynamic";
+import type { PickerIdFieldProps } from "@/components/dynamic/wrappers/PickerIdField";
+import type { FieldProps } from "@/components/form/Field.vue";
+
+export const villageInfoFolkCultureForm : SingleForm = [VillageBulidingInfo, () => ({
+  formItems: [
+    {
+      label: '名称',
+      name: 'name',
+      type: 'text',
+      defaultValue: '',
+      additionalProps: {
+        placeholder: '请输入名称',
+      },
+      rules:  [{
+        required: true,
+        message: '请输入名称',
+      }]
+    }, 
+    {
+      label: '详情',
+      name: 'details',
+      type: 'richtext',
+      defaultValue: '',
+      additionalProps: {
+        placeholder: '请输入详情',
+        maxLength: 200,
+        showWordLimit: true, 
+      },
+      rules:  [{
+        required: true,
+        message: '请输入详情',
+      }]
+    }, 
+    {
+      label: '村落非遗项目', 
+      name: 'ichId',
+      type: 'select-id', 
+      defaultValue: null,
+      additionalProps: {
+        loadData: {
+          callback: (m, r, p, i) => async () => 
+            (await VillageInfoApi.getList(
+              'ich', undefined, undefined,
+              i.formGlobalParams.villageId,
+              i.formGlobalParams.villageVolunteerId
+            )).map((p) => ({
+              value: p.id,
+              text: p.title,
+            }))
+        },
+      } as IDynamicFormItemCallbackAdditionalProps<PickerIdFieldProps>,
+      formProps: { showRightArrow: true } as FieldProps,
+      rules: [],
+    },
+    {
+      label: '文化资源关联内容ID',
+      name: 'details',
+      type: 'text',
+      defaultValue: '',
+      additionalProps: {
+        placeholder: '输入文化资源关联内容ID',
+      },
+      rules:  []
+    }, 
+  ]
+})];

+ 35 - 0
src/pages/dig/forms/data/food.ts

@@ -0,0 +1,35 @@
+import { VillageBulidingInfo } from "@/api/inhert/VillageInfoApi";
+import type { SingleForm } from "../forms";
+
+export const villageInfoFoodProductsForm : SingleForm = [VillageBulidingInfo, () => ({
+  formItems: [
+    {
+      label: '名称',
+      name: 'name',
+      type: 'text',
+      defaultValue: '',
+      additionalProps: {
+        placeholder: '请输入名称',
+      },
+      rules:  [{
+        required: true,
+        message: '请输入名称',
+      }]
+    }, 
+    {
+      label: '详情',
+      name: 'details',
+      type: 'richtext',
+      defaultValue: '',
+      additionalProps: {
+        placeholder: '请输入详情',
+        maxLength: 200,
+        showWordLimit: true, 
+      },
+      rules:  [{
+        required: true,
+        message: '请输入详情',
+      }]
+    },
+  ]
+})];

Dosya farkı çok büyük olduğundan ihmal edildi
+ 297 - 862
src/pages/dig/forms/forms.ts