快乐的梦鱼 před 4 dny
rodič
revize
31feaea508

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 5645 - 586
package-lock.json


+ 5 - 5
package.json

@@ -64,12 +64,12 @@
   },
   "devDependencies": {
     "@dcloudio/types": "3.4.19",
-    "@dcloudio/uni-automator": "3.0.0-4080720251210001",
-    "@dcloudio/uni-cli-shared": "3.0.0-4080720251210001",
-    "@dcloudio/uni-stacktracey": "3.0.0-4080720251210001",
-    "@dcloudio/vite-plugin-uni": "3.0.0-4080720251210001",
+    "@dcloudio/uni-automator": "3.0.0-5000720260410001",
+    "@dcloudio/uni-cli-shared": "3.0.0-5000720260410001",
+    "@dcloudio/uni-stacktracey": "3.0.0-5000720260410001",
+    "@dcloudio/vite-plugin-uni": "3.0.0-5000720260410001",
     "@inquirer/prompts": "^8.3.0",
-    "@vue/runtime-core": "3.5.27",
+    "@vue/runtime-core": "3.5.34",
     "@vue/tsconfig": "^0.1.3",
     "ali-oss": "^6.23.0",
     "archiver": "^7.0.1",

+ 1 - 0
src/api/collect/AssessmentContent.ts

@@ -259,6 +259,7 @@ export class SelfAssessmentDetail extends DataModel<SelfAssessmentDetail> {
   deductPoints = 0 as number;
   points = 0 as number;
   self = null as number|null;
+  sign = '' as string|null;
   ichUnit = null as number|null;
   unitPoints = 0 as number;
   county = null as number|null;

+ 52 - 6
src/components/dynamic/DynamicForm.vue

@@ -10,16 +10,56 @@
     @submit="(e) => emit('submit', e)"
     @submitFailed="() => emit('finishFailed')"
   >
-    <DynamicFormRoot 
-      :options="finalOptions"
-      :model="model"
-      :name="name"
+    <!--空显示-->
+    <slot name="empty" v-if="options.formItems?.length == 0 || !model">
+      <div v-if="options.emptyText" class="dynamic-form-item-empty">{{ options.emptyText }}</div>
+    </slot>
+    <Alert
+      v-else-if="(typeof model !== 'object' && !options.suppressRootError)"
+      type="warning"
+      message="DynamicForm: model is not a object!"
+      :description="`At form ${name || 'unnamed'} Root`"
     />
+    <template v-else>
+      <template v-for="(item, index) in options.formItems" :key="index">
+        <template v-if="item.type === 'insertion'">
+          <slot name="insertion" :data="item" />
+        </template>
+        <!--表单条目渲染核心-->
+        <DynamicFormItemContainer 
+          v-else
+          :item="item"
+          :name="item.name"
+          :rawModel="finalModel"
+          :model="finalModel[item.name]"
+          :parentModel="finalModel"
+          :isFirst="index === 0"
+          :isLast="index === options.formItems.length - 1"
+          @update:model="(v: unknown) => finalModel[item.name] = v"
+          :disabled="options.disabled"
+        >
+          <template #arrayButtonAdd="props">
+            <slot name="formArrayButtonAdd" :onClick="props.onClick" />
+          </template>
+          <template #arrayButtons="props">
+            <slot name="formArrayButtons"
+              :onDeleteClick="props.onDeleteClick"
+              :onUpClick="props.onUpClick"
+              :onDownClick="props.onDownClick" 
+            />
+          </template>
+          <template #formCeil="values">
+            <slot name="formCeil" :data="values.data" />
+          </template>
+        </DynamicFormItemContainer>
+      </template>
+      <slot name="endButton" />
+    </template>
   </Form>
 </template>
 
 <script setup lang="ts">
-import { computed, onMounted, provide, ref, shallowRef, toRef, toRefs, type PropType } from 'vue';
+import { computed, onMounted, provide, ref, toRef, toRefs, type PropType } from 'vue';
 import Form, { type FormInstance } from '../form/Form.vue';
 import { 
   type IDynamicFormOptions, type IDynamicFormItem, type IDynamicFormRef, 
@@ -29,7 +69,8 @@ import {
   MESSAGE_RELOAD,
   type IDynamicFormWidgetRef
 } from '.';
-import DynamicFormRoot from './nest/DynamicFormRoot.vue';
+import DynamicFormItemContainer from './nest/DynamicFormItemContainer.vue';
+import Alert from '@/components/feedback/Alert.vue';
 
 const props = defineProps({	
   /**
@@ -68,6 +109,11 @@ const finalOptions = computed<IDynamicFormOptions>(() => ({
   ...defaultDynamicFormOptions,
   ...options.value,
 }));
+const finalModel = computed(() => {
+  if (typeof props.model !== 'object')
+    return {};
+  return props.model;
+});
 
 provide('rawModel', model);
 provide('globalParams', toRef(props, 'globalParams'));

+ 15 - 3
src/components/dynamic/nest/DynamicFormItemContainer.vue

@@ -52,7 +52,11 @@
         :isLast="k === (item.children?.length || 0) - 1"
         @update:model="(v: unknown) => (model as IDynamicFormObject)[child.name] = v"
         :disabled="disabled || evaluateCallback(item.disabled)"
-      />
+      >
+        <template #formCeil="values">
+          <slot name="formCeil" :data="values.data" />
+        </template>
+      </DynamicFormItemContainerFuckMp>
     </DynamicFormCheckEmpty>
     <!--对象组-->
     <DynamicFormCheckEmpty 
@@ -81,7 +85,11 @@
             :isLast="k === (item.children?.length || 0) - 1"
             @update:model="(v: unknown) => (model as IDynamicFormObject)[child.name] = v"
             :disabled="disabled || evaluateCallback(item.disabled)"
-          />
+          >
+            <template #formCeil="values">
+              <slot name="formCeil" :data="values.data" />
+            </template>
+          </DynamicFormItemContainerFuckMp>
         </Row>
       </FormGroup>
     </DynamicFormCheckEmpty>
@@ -264,7 +272,11 @@
                 :isLast="isLast"
                 :disabled="disabled || evaluateCallback(item.disabled)"
                 @update:model="(v: unknown) => onUpdateValue(v)"
-              />
+              >
+                <template #formCeil="values">
+                  <slot name="formCeil" :data="values.data" />
+                </template>
+              </DynamicFormItemContainerFuckMp>
             </template>
           </FormArrayGroup>
         </template>

+ 0 - 85
src/components/dynamic/nest/DynamicFormRoot.vue

@@ -1,85 +0,0 @@
-<!-- eslint-disable vue/no-mutating-props -->
-<template>
-  <!--空显示-->
-  <slot name="empty" v-if="options.formItems?.length == 0 || !model">
-    <div v-if="options.emptyText" class="dynamic-form-item-empty">{{ options.emptyText }}</div>
-  </slot>
-  <Alert
-    v-else-if="(typeof model !== 'object' && !options.suppressRootError)"
-    type="warning"
-    message="DynamicForm: model is not a object!"
-    :description="`At form ${name || 'unnamed'} Root`"
-  />
-  <template v-else>
-    <!--表单条目渲染核心-->
-    <DynamicFormItemContainer 
-      v-for="(item, index) in options.formItems"
-      :key="index"
-      :item="item"
-      :name="item.name"
-      :rawModel="finalModel"
-      :model="finalModel[item.name]"
-      :parentModel="finalModel"
-      :isFirst="index === 0"
-      :isLast="index === options.formItems.length - 1"
-      @update:model="(v: unknown) => finalModel[item.name] = v"
-      :disabled="options.disabled"
-    >
-      <template #arrayButtonAdd="props">
-        <slot name="formArrayButtonAdd" :onClick="props.onClick" />
-      </template>
-      <template #arrayButtons="props">
-        <slot name="formArrayButtons"
-          :onDeleteClick="props.onDeleteClick"
-          :onUpClick="props.onUpClick"
-          :onDownClick="props.onDownClick" 
-        />
-      </template>
-      <template #formCeil="{ data }">
-        <slot name="formCeil"
-          :name="data.name"
-          :item="data.item"
-          :model="data.model"
-          :onModelUpdate="data.onModelUpdate"
-          :rawModel="data.rawModel"
-          :parentModel="data.parentModel"
-          :parent="data.parent"
-          :rules="data.item.rules"
-          :disabled="data.disabled"
-          :additionalProps="data.additionalProps"
-        />
-      </template>
-    </DynamicFormItemContainer>
-    <slot name="endButton" />
-  </template>
-</template>
-
-<script lang="ts" setup>
-import { computed, inject, type PropType } from 'vue';
-import DynamicFormItemContainer from './DynamicFormItemContainer.vue';
-import type { IDynamicFormObject, IDynamicFormOptions } from '..';
-import Alert from '@/components/feedback/Alert.vue';
-
-/**
- * 动态表单组件。
- */
-const props = defineProps({
-  model: {
-    type: Object as PropType<IDynamicFormObject>,
-    default: null
-  },
-  options: {
-    type: Object as PropType<IDynamicFormOptions>,
-    default: null
-  },
-  name: {
-    type: String,
-    default: ''
-  }
-});
-const finalModel = computed(() => {
-  if (typeof props.model !== 'object')
-    return {};
-  return props.model;
-});
-</script>

+ 104 - 0
src/pages/collect/assessment/components/EvaluationFormBlock.vue

@@ -0,0 +1,104 @@
+<template>
+  <DynamicForm
+    ref="formRef"
+    :model="currentForm"
+    :options="formOptions"
+  >
+    <template #insertion="{ data }">
+      <FlexCol v-if="data.name === 'insertCheckList'">
+        <H3>自查项目选择</H3>
+        <FlexCol gap="gap.md">
+          <FlexCol v-for="(item, index) in checkItemList" :key="item.id" gap="gap.md">
+            <Text fontConfig="subTitleText" :text="`${index + 1}. ${item.name}`" />
+            <FlexCol v-if="item.checkType == 2" gap="gap.sm">
+              <FlexRow v-for="child in item.children" :key="child.id" justify="space-between">
+                <CheckBox
+                  :text="`${child.name} (${child.points}分)`"
+                  :modelValue="hasCheckedItem(child.id)" 
+                  @update:modelValue="setCheckedItem(item as CheckItemInfo, child as CheckItemInfo, $event)" 
+                />
+                <Stepper 
+                  v-if="hasCheckedItem(child.id)"
+                  :min="0"
+                  :max="20"
+                  :step="1"
+                  :modelValue="getCheckedItemCount(child.id) ?? 0" 
+                  @update:modelValue="setCheckedItem(item as CheckItemInfo, child as CheckItemInfo, $event)" 
+                />
+                <view v-else></view>
+              </FlexRow>
+            </FlexCol>
+            <FlexCol v-else gap="gap.sm">
+              <CheckBox 
+                v-for="child in item.children" :key="child.id"
+                :text="`${child.name} (${child.points}分)`"
+                :modelValue="hasCheckedItem(child.id)" 
+                @update:modelValue="setCheckedItem(item as CheckItemInfo, child as CheckItemInfo, $event)" 
+              />
+            </FlexCol>
+          </FlexCol>
+        </FlexCol>
+      </FlexCol>
+      <slot v-else name="formCeil" :data="data" />
+    </template>
+  </DynamicForm>
+</template>
+
+<script setup lang="ts">
+import DynamicForm from '@/components/dynamic/DynamicForm.vue';
+import FlexCol from '@/components/layout/FlexCol.vue';
+import H3 from '@/components/typography/H3.vue';
+import Text from '@/components/basic/Text.vue';
+import FlexRow from '@/components/layout/FlexRow.vue';
+import CheckBox from '@/components/form/CheckBox.vue';
+import Stepper from '@/components/form/Stepper.vue';
+import { SelfAssessmentCheckItemAnswer, type CheckItemInfo, type SelfAssessmentDetail } from '@/api/collect/AssessmentContent';
+import type { IDynamicFormOptions } from '@/components/dynamic';
+import { ArrayUtils } from '@imengyu/imengyu-utils';
+
+const props = defineProps<{   
+  currentForm: SelfAssessmentDetail;
+  formOptions: IDynamicFormOptions;
+  checkItemList: CheckItemInfo[];
+  currentFormCheckItems: SelfAssessmentCheckItemAnswer[];
+}>();
+
+function hasCheckedItem(id: number) {
+  return props.currentFormCheckItems.some(item => item.id === id);
+}
+function getCheckedItemCount(id: number) {
+  console.log('getCheckedItemCount', id);
+  return props.currentFormCheckItems.find(item => item.id === id)?.count;
+}
+function setCheckedItem(checkItem: CheckItemInfo, childItem: CheckItemInfo, count: number|boolean) {
+  if (!props.currentForm)
+    return;
+  if (typeof count === 'boolean') {
+    count = count ? 1 : 0;
+  }
+  console.log('setCheckedItem', childItem.id, count);
+  let item = props.currentFormCheckItems.find(item => item.id === childItem.id);
+  if (!item) {
+    item = new SelfAssessmentCheckItemAnswer();
+    props.currentFormCheckItems.push(item);
+  }
+  if (item.count === count)
+    return;
+  item.id = childItem.id;
+  item.points = childItem.points;
+  item.count = count;
+  switch (checkItem.checkType) {
+    case 1: {
+      /** 单选,清除其他选项 */
+      const allChildren = checkItem.children.map(child => child.id);
+      props.currentFormCheckItems.forEach(item => {
+        if (allChildren.includes(item.id) && item.id !== childItem.id)
+          item.count = 0;
+      });
+      break;
+    }
+  }
+  if (item.count === 0)
+    ArrayUtils.remove(props.currentFormCheckItems, item);
+}
+</script>

+ 24 - 111
src/pages/collect/assessment/evaluation-form.vue

@@ -12,48 +12,11 @@
             <Button type="primary" @click="createForm">去填写评估表</Button>
           </Result>
           <FlexCol v-else gap="gap.md">
-            <DynamicForm
-              ref="form1Ref"
-              :model="currentForm"
-              :options="formOptions"
-            />
-            <Button @click="navTo('/pages/test/test')">test</Button>
-            <H3>自查项目选择</H3>
-            <FlexCol v-if="checkItemList && checkItemList.length > 0" gap="gap.md">
-              <FlexCol v-for="(item, index) in checkItemList" :key="item.id" gap="gap.md">
-                <Text fontConfig="subTitleText" :text="`${index + 1}. ${item.name}`" />
-                <FlexCol v-if="item.checkType == 2" gap="gap.sm">
-                  <FlexRow v-for="child in item.children" :key="child.id" justify="space-between">
-                    <CheckBox
-                      :text="`${child.name} (${child.points}分)`"
-                      :modelValue="hasCheckedItem(child.id)" 
-                      @update:modelValue="setCheckedItem(item as CheckItemInfo, child as CheckItemInfo, $event)" 
-                    />
-                    <Stepper 
-                      v-if="hasCheckedItem(child.id)"
-                      :min="0"
-                      :max="20"
-                      :step="1"
-                      :modelValue="getCheckedItemCount(child.id) ?? 0" 
-                      @update:modelValue="setCheckedItem(item as CheckItemInfo, child as CheckItemInfo, $event)" 
-                    />
-                    <view v-else></view>
-                  </FlexRow>
-                </FlexCol>
-                <FlexCol v-else gap="gap.sm">
-                  <CheckBox 
-                    v-for="child in item.children" :key="child.id"
-                    :text="`${child.name} (${child.points}分)`"
-                    :modelValue="hasCheckedItem(child.id)" 
-                    @update:modelValue="setCheckedItem(item as CheckItemInfo, child as CheckItemInfo, $event)" 
-                  />
-                </FlexCol>
-              </FlexCol>
-            </FlexCol>
-            <DynamicForm
-              ref="form3Ref"
-              :model="currentForm"
-              :options="formOptionsEnd"
+            <EvaluationFormBlock
+              :currentForm="(currentForm as SelfAssessmentDetail)"
+              :formOptions="formOptions"
+              :checkItemList="(checkItemList as CheckItemInfo[])"
+              :currentFormCheckItems="(currentFormCheckItems as SelfAssessmentCheckItemAnswer[])"
             />
             <FlexRow align="center" justify="space-between">
               <H3>自评总分</H3>
@@ -74,7 +37,7 @@ import { computed, ref } from 'vue';
 import { useSimpleDataLoader } from '@/components/composeabe/loader/SimpleDataLoader';
 import { useAuthStore } from '@/store/auth';
 import { useLoadQuerys } from '@/components/composeabe/LoadQuerys';
-import { ArrayUtils, assertNotNull, formatError, waitTimeOut } from '@imengyu/imengyu-utils';
+import { assertNotNull, formatError, waitTimeOut } from '@imengyu/imengyu-utils';
 import { toast, alert } from '@/components/dialog/CommonRoot';
 import AssessmentContentApi, {
   SelfAssessmentDetail,
@@ -87,19 +50,16 @@ import Result from '@/components/feedback/Result.vue';
 import FlexCol from '@/components/layout/FlexCol.vue';
 import Height from '@/components/layout/space/Height.vue';
 import SimplePageContentLoader from '@/components/loader/SimplePageContentLoader.vue';
-import DynamicForm from '@/components/dynamic/DynamicForm.vue';
 import H3 from '@/components/typography/H3.vue';
 import FlexRow from '@/components/layout/FlexRow.vue';
 import Text from '@/components/basic/Text.vue';
 import XBarSpace from '@/components/layout/space/XBarSpace.vue';
-import CheckBox from '@/components/form/CheckBox.vue';
-import Stepper from '@/components/form/Stepper.vue';
 import type { IDynamicFormOptions, IDynamicFormRef } from '@/components/dynamic';
 import type { RadioValueProps } from '@/components/dynamic/wrappers/RadioValue';
 import type { FieldProps } from '@/components/form/Field.vue';
 import type { SignatureFieldProps } from '@/components/form/SignatureField.vue';
 import { useImageSimpleUploadCo } from '@/common/components/upload/ImageUploadCo';
-import { navTo } from '@/components/utils/PageAction';
+import EvaluationFormBlock from './components/EvaluationFormBlock.vue';
 
 let loaded = false;
 
@@ -116,10 +76,9 @@ const currentForm = ref<SelfAssessmentDetail | null>(null);
 const currentFormCheckItems = ref<SelfAssessmentCheckItemAnswer[]>([]);
 const authStore = useAuthStore();
 
-const form1Ref = ref<IDynamicFormRef | null>(null);
-const form3Ref = ref<IDynamicFormRef | null>(null);
+const formRef = ref<IDynamicFormRef | null>(null);
 
-const formOptions = ref<IDynamicFormOptions>({
+const formOptions : IDynamicFormOptions = {
   formAdditionaProps: {
     labelFlex: 4,
     inputFlex: 8,
@@ -188,24 +147,10 @@ const formOptions = ref<IDynamicFormOptions>({
         },
       ],
     },
-  ],
-  formRules: {
-    inheritor: [{ required: true, message: '请输入传承人名称' }],
-    unit: [{ required: true, message: '请输入项目保护单位' }],
-    ichName: [{ required: true, message: '请输入项目名称' }],
-    mobile: [{ required: true, message: '请输入联系电话' }],
-    idCard: [{ required: true, message: '请输入身份证号' }],
-    level: [{ required: true, message: '请选择级别' }],
-    address: [{ required: true, message: '请输入家庭住址' }],
-    content: [{ required: true, message: '请填写自评报告' }],
-    self: [{ required: true, message: '请选择自我评估' }],
-  },
-});
-const formOptionsEnd = ref<IDynamicFormOptions>({
-  formAdditionaProps: {
-    labelPosition: 'top',
-  },
-  formItems: [
+    {
+      type: 'insertion',
+      name: 'insertCheckList',
+    },
     {
       type: 'flat-group',
       label: '传承人自查评估',
@@ -262,10 +207,19 @@ const formOptionsEnd = ref<IDynamicFormOptions>({
     },
   ],
   formRules: {
+    inheritor: [{ required: true, message: '请输入传承人名称' }],
+    unit: [{ required: true, message: '请输入项目保护单位' }],
+    ichName: [{ required: true, message: '请输入项目名称' }],
+    mobile: [{ required: true, message: '请输入联系电话' }],
+    idCard: [{ required: true, message: '请输入身份证号' }],
+    level: [{ required: true, message: '请选择级别' }],
+    address: [{ required: true, message: '请输入家庭住址' }],
+    content: [{ required: true, message: '请填写自评报告' }],
     self: [{ required: true, message: '请选择自我评估' }],
     sign: [{ required: true, message: '请传承人签名' }],
   },
-});
+};
+
 const checkItemList = ref<CheckItemInfo[]>([]);
 
 const totalPoints = computed(() => {
@@ -291,44 +245,6 @@ async function loadCheckItems() {
   checkItemList.value = await AssessmentContentApi.getCheckItems(Number(currentForm.value.level));
   currentFormCheckItems.value = currentForm.value.checkItems.concat();
 }
-function hasCheckedItem(id: number) {
-  return currentFormCheckItems.value.some(item => item.id === id);
-}
-function getCheckedItemCount(id: number) {
-  console.log('getCheckedItemCount', id);
-  return currentFormCheckItems.value.find(item => item.id === id)?.count;
-}
-function setCheckedItem(checkItem: CheckItemInfo, childItem: CheckItemInfo, count: number|boolean) {
-  if (!currentForm.value)
-    return;
-  if (typeof count === 'boolean') {
-    count = count ? 1 : 0;
-  }
-  console.log('setCheckedItem', childItem.id, count);
-  let item = currentFormCheckItems.value.find(item => item.id === childItem.id);
-  if (!item) {
-    item = new SelfAssessmentCheckItemAnswer();
-    currentFormCheckItems.value.push(item);
-  }
-  if (item.count === count)
-    return;
-  item.id = childItem.id;
-  item.points = childItem.points;
-  item.count = count;
-  switch (checkItem.checkType) {
-    case 1: {
-      /** 单选,清除其他选项 */
-      const allChildren = checkItem.children.map(child => child.id);
-      currentFormCheckItems.value.forEach(item => {
-        if (allChildren.includes(item.id) && item.id !== childItem.id)
-          item.count = 0;
-      });
-      break;
-    }
-  }
-  if (item.count === 0)
-    ArrayUtils.remove(currentFormCheckItems.value, item);
-}
 
 const submitLoading = ref(false);
 
@@ -343,10 +259,8 @@ async function createForm() {
 }
 async function saveForm() {
   const detail = currentForm.value;
-
   try {
-    await form1Ref.value?.validate();
-    await form3Ref.value?.validate();
+    await formRef.value?.validate();
   } catch (error) {
     toast('请填写完整信息');
     return;
@@ -354,7 +268,6 @@ async function saveForm() {
 
   submitLoading.value = true;
   currentForm.value!.checkItems = currentFormCheckItems.value;
-
   try {
     assertNotNull(detail, 'currentForm is null');
     await AssessmentContentApi.saveSelfAssessment(detail as SelfAssessmentDetail);