zhangjie 1 жил өмнө
parent
commit
21787a09a2

+ 1 - 0
src/style/global.less

@@ -496,6 +496,7 @@ body {
       padding: 16px;
       border-top: 1px solid @light-border-color;
       flex-direction: row-reverse;
+      min-height: 65px;
     }
   }
 }

+ 1 - 1
src/views/resource-guard/person-guard/person-files/add-person-file-dialog.vue

@@ -13,7 +13,7 @@
         <t-col :span="4">
           <t-form-item label="人员档案编号">
             <span v-if="isEdit">{{ formData.code }}</span>
-            <span>系统生成</span>
+            <span v-else>系统生成</span>
           </t-form-item>
         </t-col>
         <t-col :span="4">

+ 5 - 1
src/views/sop/components/dynamic-form-item/SELECT.vue

@@ -31,7 +31,11 @@ const getOptionsApi = () => {
 };
 const getOptions = async () => {
   if (props.config.options) {
-    options.value = props.config.options;
+    let data = props.config.options;
+    if (typeof data === 'string') {
+      data = JSON.parse(data);
+    }
+    options.value = data;
     return;
   }
 

+ 112 - 2
src/views/sop/components/dynamic-form-item/SIGN.vue

@@ -1,5 +1,115 @@
 <template>
-  <div>手写签名组件待定...</div>
+  <div :class="['sign-box', { 'is-disabled': disabled }]">
+    <div v-if="!disabled">
+      <t-button size="small" @click="clear">清除</t-button>
+    </div>
+    <canvas ref="canvasRef" width="600" height="300"></canvas>
+  </div>
 </template>
 
-<script setup name="SIGN"></script>
+<script setup name="SIGN">
+import { computed, onMounted, ref, watch } from 'vue';
+const props = defineProps({
+  config: { type: Object },
+  modelValue: { type: String },
+});
+const emit = defineEmits(['update:modelValue', 'change']);
+
+const valueData = ref('');
+const canvasRef = ref(null);
+
+const disabled = computed(() => {
+  return !props.config?.writable;
+});
+
+const emitChange = () => {
+  valueData.value = canvasRef.value.toDataURL();
+  emit('update:modelValue', valueData.value);
+  emit('change', valueData.value);
+};
+
+const initCanvas = () => {
+  const ctx = canvasRef.value.getContext('2d');
+  let isDrawing = false;
+  canvasRef.value.addEventListener('mousedown', (e) => {
+    isDrawing = true;
+    ctx.moveTo(e.offsetX, e.offsetY);
+  });
+  canvasRef.value.addEventListener('mousemove', (e) => {
+    if (isDrawing) {
+      ctx.lineTo(e.offsetX, e.offsetY);
+      ctx.lineWidth = 1;
+      // ctx.strokeStyle = '#000';
+      ctx.stroke();
+    }
+  });
+  canvasRef.value.addEventListener('mouseup', (e) => {
+    isDrawing = false;
+
+    emitChange();
+  });
+};
+
+const clear = () => {
+  canvasRef.value.width = canvasRef.value.width;
+  canvasRef.value.height = canvasRef.value.height;
+};
+
+const drawImg = () => {
+  if (!valueData.value) return;
+
+  const img = new Image();
+  img.onload = function () {
+    const ctx = canvasRef.value.getContext('2d');
+    ctx.drawImage(img, 0, 0);
+  };
+  img.onerror = function (e) {
+    reject(e);
+  };
+  img.src = valueData.value;
+};
+
+onMounted(() => {
+  if (disabled.value) return;
+  initCanvas();
+});
+
+watch(
+  () => props.modelValue,
+  (val, oldval) => {
+    if (val === oldval) return;
+    valueData.value = val;
+
+    if (val) {
+      drawImg();
+    }
+  },
+  {
+    immediate: true,
+  }
+);
+</script>
+
+<style lang="less" scoped>
+.sign-box {
+  position: relative;
+  > canvas {
+    box-shadow: 0 0 1px #333;
+    margin-top: 10px;
+  }
+
+  &.is-disabled {
+    &::after {
+      cursor: not-allowed;
+      display: block;
+      content: '';
+      position: absolute;
+      top: 0;
+      left: 0;
+      right: 0;
+      bottom: 0;
+      z-index: 99;
+    }
+  }
+}
+</style>

+ 12 - 1
src/views/sop/components/dynamic-form-item/UPLOAD_IMAGE.vue

@@ -19,7 +19,7 @@
   </t-upload>
 </template>
 <script setup name="UploadImage">
-import { ref } from 'vue';
+import { ref, watch } from 'vue';
 import { MessagePlugin } from 'tdesign-vue-next';
 import { uploadFiles } from '@/api/common';
 import { getFileMD5 } from '@/utils/crypto';
@@ -92,4 +92,15 @@ const handleChange = () => {
   emit('update:modelValue', data);
   emit('change', data);
 };
+
+watch(
+  () => props.modelValue,
+  (val, oldval) => {
+    if (val === oldval) return;
+    files.value = val;
+  },
+  {
+    immediate: true,
+  }
+);
 </script>

+ 54 - 26
src/views/sop/sop-manage/sop-step/index.vue

@@ -86,7 +86,6 @@
         :key="item.taskKey"
         :value="item.value"
         :label="item.label"
-        :disabled="item.disabled"
       >
         <t-form
           ref="form"
@@ -117,22 +116,24 @@
           </t-row>
         </t-form>
         <t-space class="sop-step-footer">
-          <t-button v-if="IS_EDIT_MODE" theme="primary" @click="saveHandle"
-            >提交</t-button
-          >
-          <t-button
-            v-if="!IS_EDIT_MODE"
-            theme="primary"
-            @click="submitHandle('START')"
-            >提交</t-button
-          >
+          <template v-if="showAction">
+            <t-button v-if="IS_EDIT_MODE" theme="primary" @click="saveHandle"
+              >提交</t-button
+            >
+            <t-button
+              v-if="!IS_EDIT_MODE"
+              theme="primary"
+              @click="submitHandle('START')"
+              >提交</t-button
+            >
 
-          <t-button
-            v-if="!IS_EDIT_MODE"
-            theme="default"
-            @click="submitHandle('DRAFT')"
-            >保存草稿</t-button
-          >
+            <t-button
+              v-if="!IS_EDIT_MODE"
+              theme="default"
+              @click="submitHandle('DRAFT')"
+              >保存草稿</t-button
+            >
+          </template>
         </t-space>
       </t-tab-panel>
     </t-tabs>
@@ -216,6 +217,8 @@ const allFormData = ref({});
 const allSteps = ref([]);
 const tabs = ref([]);
 const curStep = ref('');
+const currFlowTaskResultSetup = ref(null);
+const curStepSetup = ref(1);
 const flowId = props.sop.flowId;
 const crmInfo = ref({});
 
@@ -233,7 +236,6 @@ const initNew = async () => {
     return {
       value: item.taskName,
       label: item.taskName,
-      disabled: false,
     };
   });
   curStep.value = tabs.value.slice(-1)[0].value;
@@ -242,8 +244,9 @@ const initFill = async () => {
   loading.value = true;
   const res = await sopFlowViewApi({ flowId });
   crmInfo.value = res.crmInfo;
-  loading.value = false;
   curStep.value = res.currFlowTaskResult.taskName;
+  currFlowTaskResultSetup.value = res.currFlowTaskResult.setup;
+  curStepSetup.value = res.currFlowTaskResult.setup;
   res.flowTaskHistoryList = res.flowTaskHistoryList || [];
   res.flowTaskHistoryList.forEach((item) => {
     item.formProperty.forEach((v) => {
@@ -256,18 +259,24 @@ const initFill = async () => {
       return {
         value: item.taskName,
         label: item.taskName,
-        disabled: true,
       };
     }),
     {
       value: res.currFlowTaskResult.taskName,
       label: res.currFlowTaskResult.taskName,
-      disabled: false,
     },
   ];
+  allSteps.value.forEach((item) => {
+    item.formProperty.forEach((prop) => {
+      prop.value = prop.value ? JSON.parse(prop.value).value : null;
+    });
+  });
+  loading.value = false;
 };
 const initEdit = async () => {
   loading.value = true;
+  const flowRes = await sopFlowViewApi({ flowId });
+  crmInfo.value = flowRes.crmInfo;
   const res = await sopEditApi(props.sop.id);
   loading.value = false;
 
@@ -289,10 +298,13 @@ const initEdit = async () => {
     return {
       value: item.taskName,
       label: item.taskName,
-      disabled: false,
     };
   });
   curStep.value = tabs.value.slice(-1)[0].value;
+  const curStepData = allSteps.value.find(
+    (item) => item.taskName === curStep.value
+  );
+  curStepSetup.value = curStepData.setup;
 };
 const init = () => {
   if (IS_FILL_MODE.value) {
@@ -308,6 +320,19 @@ const init = () => {
 };
 init();
 
+const showAction = computed(() => {
+  if ((IS_EDIT_MODE.value && curStepSetup.value !== 1) || IS_NEW_MODE.value)
+    return true;
+
+  if (
+    IS_FILL_MODE.value &&
+    curStepSetup.value === currFlowTaskResultSetup.value
+  )
+    return true;
+
+  return false;
+});
+
 const curFormConfig = computed(() => {
   const stepData = allSteps.value.find(
     (item) => item.taskName === curStep.value
@@ -318,20 +343,17 @@ const curFormConfig = computed(() => {
   formProperty.forEach((item) => {
     if (IS_EDIT_MODE.value) {
       item.value = allFormData.value[item.formName];
-    } else if (IS_FILL_MODE.value) {
-      item.value = item.value ? JSON.parse(item.value).value : null;
-      // item.value = null;
     }
   });
 
   // 填报时第一步的特殊处理
-  if ((IS_FILL_MODE.value || IS_NEW_MODE.value) && stepData.setup === 1) {
+  if (stepData.setup === 1) {
     // region_user_id_1 区域协调人
     // engineer_user_id_1 实施工程师
     // assistant_engineer_user_id_1 助理工程师
     formProperty.forEach((field) => {
       // 区域协调人
-      if (field.formId.startsWith('region_user') && !field.value) {
+      if (field.formId.startsWith('region_user')) {
         field.value = crmInfo.value.regionCoordinatorId;
         field.options = [
           {
@@ -390,6 +412,10 @@ const stepChange = () => {
   if (IS_EDIT_MODE.value) {
     allFormData.value = { ...allFormData.value, ...formData.value };
   }
+  const curStepData = allSteps.value.find(
+    (item) => item.taskName === curStep.value
+  );
+  curStepSetup.value = curStepData.setup;
 };
 
 const itemValueChange = ({ prop, value }) => {
@@ -433,6 +459,8 @@ const submitHandle = async (approve = 'START') => {
   if (approve === 'START') {
     const valid = await form.value[0].validate();
     if (valid !== true) return;
+
+    approve = curStepSetup.value === 1 ? 'START' : 'PASS';
   }
 
   if (IS_FILL_MODE.value) {