Jelajahi Sumber

feat: 修改评价

DESKTOP-USV654P\pc 1 Minggu lalu
induk
melakukan
4e441202c2

+ 7 - 0
src/views/evaluate/maintenance/data.config.ts

@@ -7,6 +7,13 @@ import { postEvaluateTemplateChangeStatus } from '/@/services/apis/EvaluateTempl
 import { useMessage } from '/@/hooks/web/useMessage';
 
 import { requestMagicApi } from '/@/api/magicApi';
+import { BasicOptionModel } from '/@/api/model/baseModel';
+
+export const problemOptions: BasicOptionModel[] = [
+  { label: '打分题', value: '1' },
+  { label: '单选题', value: '2' },
+  { label: '多选题', value: '3' },
+];
 
 export const tableColumns: BasicColumn[] = [
   {

+ 66 - 81
src/views/evaluate/maintenance/term.vue

@@ -46,20 +46,18 @@
               dataIndex: 'action',
               slots: { customRender: 'action' },
             }"
-            @edit-change="handelDetailChange"
           >
             <template #action="{ record, index }">
               <TableAction :actions="createActions(record, field, index)" />
             </template>
             <template #toolbar>
-              <Button type="primary" ghost @click="addDetailRow(model, field)" block>
-                添加一行
-              </Button>
+              <Button type="primary" ghost @click="addDetailRow(field)" block> 添加一行 </Button>
             </template>
           </BasicTable>
         </div>
       </template>
     </BasicForm>
+    <FormEdit @register="registerEditModal" @success="handleSuccess" />
   </BasicDrawer>
 </template>
 <script setup lang="ts">
@@ -79,6 +77,10 @@
   } from '/@/services/apis/EvaluateItemController';
 
   import { buildUUID } from '/@/utils/uuid';
+  import FormEdit from './termEdit.vue';
+  import { useModal } from '/@/components/Modal';
+
+  const [registerEditModal, { openModal }] = useModal();
 
   const isUpdate = ref(true);
   const modelRef = ref({});
@@ -131,6 +133,8 @@
               problem: ic.problem,
               score: ic.score,
               inputNotNull: ic.inputNotNull === 1,
+              type: ic.type,
+              optionJson: ic.optionJson,
             });
           });
         formData[`table${index}`] = tableData;
@@ -185,54 +189,74 @@
     // rowTotal.value--;
   };
 
-  const addDetailRow = (model, field) => {
-    const item = model[field] || [];
-    item.push({
+  const addDetailRow = (field) => {
+    const item = {
       key: buildUUID(),
       problem: '',
       score: 0,
+      type: 1,
       inputNotNull: true,
+    };
+
+    openModal(true, {
+      isUpdate: false,
+      baseData: {
+        field: field,
+        item: item,
+        index: -1,
+      },
     });
-    model[field] = item;
-    setFieldsValue(model);
+    // setFieldsValue(model);
   };
 
-  const createActions = (record: EditRecordRow, field: String, index: Number): ActionItem[] => {
-    if (!record.editable) {
-      return [
-        {
-          label: '编辑',
-          disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.key : false,
-          onClick: handleDetailEdit.bind(null, record),
-        },
-        {
-          label: '上移',
-          disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.key : false,
-          onClick: handelDetailMove.bind(null, field, index, 1),
-        },
-        {
-          label: '下移',
-          disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.key : false,
-          onClick: handelDetailMove.bind(null, field, index, 2),
-        },
-        {
-          label: '删除',
-          disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.key : false,
-          onClick: handleDetailDelete.bind(null, record, field),
-        },
-      ];
+  const editDetailRow = (record, field, index) => {
+    openModal(true, {
+      isUpdate: true,
+      baseData: {
+        field: field,
+        index: index,
+        item: { ...record },
+      },
+    });
+    // setFieldsValue(model);
+  };
+
+  const handleSuccess = async (baseData, isUpdate) => {
+    const formData = getFieldsValue();
+    const { field, item, index } = baseData;
+
+    if (!isUpdate) {
+      const dataRow = formData[`${field}`] || [];
+      dataRow.push({ ...item });
+      formData[`${field}`] = dataRow;
+      setFieldsValue(formData);
+    } else {
+      formData[`${field}`][index] = { ...item };
+      setFieldsValue(formData);
     }
+  };
+
+  const createActions = (record: EditRecordRow, field: String, index: Number): ActionItem[] => {
     return [
       {
-        label: '保存',
-        onClick: handleDetailSave.bind(null, record),
+        label: '编辑',
+        disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.key : false,
+        onClick: editDetailRow.bind(null, record, field, index),
       },
       {
-        label: '取消',
-        popConfirm: {
-          title: '是否取消编辑',
-          confirm: handleDetailCancel.bind(null, record),
-        },
+        label: '上移',
+        disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.key : false,
+        onClick: handelDetailMove.bind(null, field, index, 1),
+      },
+      {
+        label: '下移',
+        disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.key : false,
+        onClick: handelDetailMove.bind(null, field, index, 2),
+      },
+      {
+        label: '删除',
+        disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.key : false,
+        onClick: handleDetailDelete.bind(null, record, field),
       },
     ];
   };
@@ -262,16 +286,6 @@
     setFieldsValue(formData);
   };
 
-  const handleDetailEdit = (record: EditRecordRow) => {
-    currentEditKeyRef.value = record.key;
-    record.onEdit?.(true);
-  };
-
-  const handleDetailCancel = (record: EditRecordRow) => {
-    currentEditKeyRef.value = '';
-    record.onEdit?.(false, false);
-  };
-
   const handleDetailDelete = (record: EditRecordRow, field: string) => {
     currentEditKeyRef.value = '';
     const formData = getFieldsValue();
@@ -279,37 +293,6 @@
     setFieldsValue(formData);
   };
 
-  const handleDetailSave = async (record: EditRecordRow) => {
-    // 校验
-    // createMessage.loading({ content: '正在保存...', duration: 0, key: 'saving' });
-    const valid = await record.onValid?.();
-    if (valid) {
-      try {
-        // const data = cloneDeep(record.editValueRefs);
-        const pass = await record.onEdit?.(false, true);
-        if (pass) {
-          currentEditKeyRef.value = '';
-          // const formData = getFieldsValue();
-          // console.log('handleDetailSave', data, field);
-          // formData[field] = data;
-          // setFieldsValue({})
-          // console.log('handleDetailSave from', formData);
-        }
-        // createMessage.success({ content: '数据已保存', key: 'saving' });
-      } catch (error) {
-        // createMessage.error({ content: '保存失败', key: 'saving' });
-      }
-    } else {
-      // createMessage.error({ content: '请完善数据', key: 'saving' });
-    }
-  };
-
-  const handelDetailChange = ({ column, value, record }) => {
-    if (column.dataIndex === 'id') {
-      //   record.editValueRefs.name4.value = `${value}`;
-    }
-  };
-
   const getTitle = computed(() => (!unref(isUpdate) ? '评价项' : '评价项'));
   const handleSubmit = async () => {
     try {
@@ -327,6 +310,8 @@
               score: item.score,
               inputNotNull: item.inputNotNull ? 1 : 0,
               problem: item.problem,
+              type: item.type,
+              optionJson: item.optionJson,
             });
           });
       }

+ 212 - 0
src/views/evaluate/maintenance/termEdit.vue

@@ -0,0 +1,212 @@
+<template>
+  <BasicModal
+    @ok="handleSubmit"
+    :destroyOnClose="true"
+    :maskClosable="false"
+    v-bind="$attrs"
+    @register="registerModal"
+    :title="getTitle"
+    :width="1002"
+    showFooter
+  >
+    <BasicForm @register="registerForm">
+      <template #title="{ model }">
+        说明:
+        <span v-if="model.type === '1'">打分题最低可打分为0分,最高可打分为设置的题目分数</span>
+        <span v-if="model.type === '2'">单选题选项最高可设置分数为题目分数</span>
+        <span v-if="model.type === '3'">多选题选项总分必须等于题目分数</span>
+      </template>
+      <template #optionJson="{ model, field }">
+        <div v-if="model[field]">
+          <div class="flex items-center mb-2" v-for="(item, index) in model[field]" :key="index">
+            <div class="flex-1">
+              <Input v-model:value="item.name" placeholder="请输入选项" />
+            </div>
+            <div class="ml-2">~</div>
+            <div class="ml-2">
+              <InputNumber
+                v-model:value="item.score"
+                placeholder="分数"
+                :min="0"
+                defaultValue="0"
+              />
+            </div>
+            <Button type="link" class="ml-2" @click="handelDelete(model, field, index)"
+              >删除</Button
+            >
+          </div>
+        </div>
+        <div>
+          <Button @click="handelAdd(model, field)">添加</Button>
+        </div>
+      </template>
+    </BasicForm>
+  </BasicModal>
+</template>
+<script setup lang="ts">
+  import { ref, computed, unref } from 'vue';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, useForm } from '/@/components/Form/index';
+
+  import { problemOptions } from './data.config';
+  import { Button } from '/@/components/Button';
+  import { Input, InputNumber } from 'ant-design-vue';
+
+  const isUpdate = ref(true);
+  const modelRef = ref({});
+  const emit = defineEmits(['success', 'register']);
+  const { createMessage } = useMessage();
+  const [registerForm, { validate, setFieldsValue, resetFields }] = useForm({
+    labelWidth: 100,
+    schemas: [
+      {
+        label: '题目名称',
+        field: 'problem',
+        component: 'Input',
+        required: true,
+        colProps: { span: 24 },
+      },
+      {
+        label: '题目类型',
+        field: 'type',
+        component: 'Select',
+        required: true,
+        colProps: { span: 24 },
+        componentProps: {
+          options: problemOptions,
+          getPopupContainer: () => document.body,
+        },
+      },
+      {
+        label: '题目分数',
+        field: 'score',
+        component: 'InputNumber',
+        required: true,
+        colProps: { span: 24 },
+      },
+      {
+        label: ' ',
+        field: 'title',
+        component: 'Title',
+        colProps: { span: 24 },
+        slot: 'title',
+      },
+      {
+        label: ' 选项配置',
+        field: 'optionJson',
+        component: 'Input',
+        colProps: { span: 24 },
+        slot: 'optionJson',
+        required: true,
+        ifShow: ({ values }) => {
+          return values.type !== '1';
+        },
+      },
+      {
+        label: '是否必填',
+        field: 'inputNotNull',
+        component: 'Switch',
+        colProps: { span: 24 },
+        componentProps: {
+          checkedValue: true,
+          unCheckedValue: false,
+        },
+      },
+    ],
+    showActionButtonGroup: false,
+  });
+
+  const [registerModal, { closeModal, setModalProps }] = useModalInner(async (data) => {
+    resetFields();
+    setModalProps({ confirmLoading: false });
+    isUpdate.value = !!data?.isUpdate;
+
+    modelRef.value = { ...data.baseData };
+    const formatData = { ...data.baseData.item };
+    formatData.type = formatData.type || '1';
+    if (formatData.type !== '1') {
+      formatData.optionJson = JSON.parse(formatData.optionJson);
+    }
+    setFieldsValue({
+      ...formatData,
+    });
+  });
+
+  const getTitle = computed(() => (!unref(isUpdate) ? '新增题目' : '编辑题目'));
+  const handleSubmit = async () => {
+    try {
+      const values = await validate();
+      setModalProps({ confirmLoading: true });
+      if (values.type !== '1') {
+        if (!values.optionJson) {
+          createMessage.warning(`选项配置不能为空`);
+          return false;
+        }
+        for (let i = 0; i < values.optionJson.length; i++) {
+          //   console.log('values.optionJson[i]', values.optionJson[i]);
+          if (!values.optionJson[i].name) {
+            createMessage.warning(`第${i + 1}选项内容不能为空`);
+            return false;
+          }
+        }
+        if (!checkScore(values)) return false;
+        values.optionJson = JSON.stringify(values.optionJson);
+      }
+      const postParams: any = unref(modelRef);
+      Object.assign(postParams, { item: values });
+
+      //   createMessage.success('操作成功');
+      closeModal();
+      emit('success', postParams, unref(isUpdate));
+    } finally {
+      setModalProps({ confirmLoading: false });
+    }
+  };
+
+  const handelAdd = (model, field) => {
+    const optionJson = model[field] || [];
+    optionJson.push({ name: '', score: 0 });
+    model[field] = optionJson;
+    // setFieldsValue(model);
+  };
+
+  const handelDelete = (model, field, index) => {
+    const optionJson = model[field];
+    optionJson.splice(index, 1);
+    model[field] = optionJson;
+    // setFieldsValue(model);
+  };
+
+  const checkScore = (values) => {
+    if (!values.score) {
+      return true;
+    }
+    let success = true;
+    if (values.type === '3') {
+      //    计算多选题总分
+      let total = 0;
+      values.optionJson.forEach((item) => {
+        total += Number(item.score);
+      });
+      if (total > values.score) {
+        createMessage.warning('选项分值总和不能大于题目分值');
+        success = false;
+      }
+    }
+    if (values.type === '2') {
+      //    计算单选题最大分
+      let max = 0;
+      values.optionJson.forEach((item) => {
+        max = Math.max(max, Number(item.score));
+      });
+      if (max > values.score) {
+        success = false;
+        createMessage.warning('选项分值不能大于题目分值');
+      }
+    }
+    return success;
+  };
+</script>
+
+<style scoped lang="less"></style>