Bläddra i källkod

1.1.2开发中

刘洋 9 månader sedan
förälder
incheckning
c8d7f59828

+ 5 - 1
src/components/common/device-manage-new/tab2.vue

@@ -97,7 +97,7 @@
   </my-dialog>
 </template>
 <script name="DeviceManageNewTab2" setup>
-import { ref, computed, onMounted } from 'vue';
+import { ref, computed, onMounted, watch } from 'vue';
 import {
   RUNNING_STATUS,
   DEVICE_SIGN_STATUS,
@@ -446,5 +446,9 @@ const columns = [
     width: 180,
   },
 ];
+const emit = defineEmits(['getTableData']);
+watch(tableData, (val) => {
+  emit('getTableData', val);
+});
 </script>
 <style lang="less" scoped></style>

+ 4 - 2
src/style/global.less

@@ -394,7 +394,6 @@ body {
       display: flex;
       justify-content: space-between;
       align-items: center;
-
       .m-title {
         font-size: 16px;
         color: @dark-text-color;
@@ -402,6 +401,9 @@ body {
         margin-right: 12px;
         flex-grow: 2;
         font-size: 0;
+        &.cytx {
+          font-size: 16px;
+        }
 
         > span {
           display: inline-block;
@@ -583,7 +585,7 @@ body {
       margin-bottom: 5px;
     }
 
-    .t-tabs__header {
+    .t-tabs__header.step-list-header {
       flex-grow: 0;
       flex-shrink: 0;
       width: 140px;

+ 13 - 3
src/views/my-workbenches/workbenches/message-reminder/index.vue

@@ -90,8 +90,15 @@ const params = reactive({
 });
 
 const transParams = computed(() => {
-  let types = params.types.join(',');
-  if(types.length===0) types = Object.keys(MESSAGE_TYPE).join();
+  let arr = [...params.types];
+  let index = arr.indexOf('CYTX');
+  if (index > -1) {
+    arr.splice(index, 1);
+    arr.push('OFFICE_SOP', 'CLOUD_MARK_SOP');
+  }
+  let types = arr.join(',');
+  if (types.length === 0)
+    types = Object.keys(MESSAGE_TYPE).join() + ',OFFICE_SOP,CLOUD_MARK_SOP';
   let status = eval(params.status);
   return { ...params, types, status };
 });
@@ -116,7 +123,10 @@ const fields = ref([
     type: 'multipleSelect',
     labelWidth: 70,
     colSpan: 5,
-    options: dictToOptionList(MESSAGE_TYPE),
+    options: [
+      ...dictToOptionList(MESSAGE_TYPE),
+      { value: 'CYTX', label: '查阅提醒' },
+    ],
     attrs: {
       clearable: true,
     },

+ 99 - 73
src/views/my-workbenches/workbenches/message-reminder/message-list.vue

@@ -4,41 +4,64 @@
       class="message-item cursor-pointer"
       v-for="item in tableData"
       :key="item.id"
-
     >
-      <div class="m-head">
-        <div
-          class="m-title flex items-center"
-          style="max-width: calc(100% - 180px)"
-        >
-          <t-link hover="color" @click="editSopFlowHandle(item)">
-          <span>{{ messageTypeFilter(item.messageType) }}</span>
-<!--          <span class="ellipsis">{{ item.content }}</span>-->
-
-          </t-link>
-          <t-tag
-            theme="danger"
-            variant="light"
-            size="small"
-            v-if="!item.readStatus"
-            >未读</t-tag
+      <template v-if="IS_CYTX(item)">
+        <div class="m-head">
+          <div class="cytx m-title flex items-center">
+            <span>查阅提醒</span>
+            <t-tag
+              theme="danger"
+              variant="light"
+              size="small"
+              v-if="!item.readStatus"
+              >未读</t-tag
+            >
+          </div>
+        </div>
+        <div class="m-body m-t-10px">
+          <div class="m-content">{{ item.content }}</div>
+          <t-space class="m-info" :size="5">
+            <p>查阅流程:{{ item.setupName }} </p>
+            <p>客户类型:{{ customerTypeFilter(item.customType) }}</p>
+            <template #separator>
+              <t-divider layout="vertical" />
+            </template>
+          </t-space>
+        </div>
+      </template>
+      <template v-else>
+        <div class="m-head">
+          <div
+            class="m-title flex items-center"
+            style="max-width: calc(100% - 180px)"
           >
+            <t-link hover="color" @click="editSopFlowHandle(item)">
+              <span>{{ messageTypeFilter(item.messageType) }}</span>
+            </t-link>
+            <t-tag
+              theme="danger"
+              variant="light"
+              size="small"
+              v-if="!item.readStatus"
+              >未读</t-tag
+            >
+          </div>
+
+          <div class="m-time">{{ timestampFilter(item.sendTime, 'mm') }}</div>
         </div>
-
-        <div class="m-time">{{ timestampFilter(item.sendTime, 'mm') }}</div>
-      </div>
-      <div class="m-body m-t-10px" @click="open(item)">
-         <div class="m-content">{{ item.content }}</div>
-        <t-space class="m-info" :size="5">
-          <p>发起人:{{ item.formUser }}</p>
-          <p>服务单元:{{ item.service }} </p>
-          <p>客户类型:{{ customerTypeFilter(item.customType) }}</p>
-          <p>客户名称:{{ item.custom }}</p>
-          <template #separator>
-            <t-divider layout="vertical" />
-          </template>
-        </t-space>
-      </div>
+        <div class="m-body m-t-10px" @click="open(item)">
+          <div class="m-content">{{ item.content }}</div>
+          <t-space class="m-info" :size="5">
+            <p>发起人:{{ item.formUser }}</p>
+            <p>服务单元:{{ item.service }} </p>
+            <p>客户类型:{{ customerTypeFilter(item.customType) }}</p>
+            <p>客户名称:{{ item.custom }}</p>
+            <template #separator>
+              <t-divider layout="vertical" />
+            </template>
+          </t-space>
+        </div>
+      </template>
     </div>
 
     <t-pagination
@@ -59,45 +82,52 @@
 
     <!-- SopStepDialog -->
     <sop-step-dialog
-        v-model:visible="showSopStepDialog"
-        :sop="curSopData"
-        type="fill"
-        @confirm="sopStepConfirm"
+      v-model:visible="showSopStepDialog"
+      :sop="curSopData"
+      type="fill"
+      @confirm="sopStepConfirm"
     ></sop-step-dialog>
     <!-- PlanChangeDialog -->
     <plan-change-dialog
-        v-model:visible="showPlanChangeDialog"
-        :sop="curSopData"
-        type="fill"
-        @confirm="sopStepConfirm"
+      v-model:visible="showPlanChangeDialog"
+      :sop="curSopData"
+      type="fill"
+      @confirm="sopStepConfirm"
     ></plan-change-dialog>
     <!-- QualityIssueDialog -->
     <quality-issue-dialog
-        v-model:visible="showQualityIssueDialog"
-        :sop="curSopData"
-        type="fill"
-        @confirm="sopStepConfirm"
+      v-model:visible="showQualityIssueDialog"
+      :sop="curSopData"
+      type="fill"
+      @confirm="sopStepConfirm"
     ></quality-issue-dialog>
     <violation-flow-dialog
-        v-model:visible="showViolationFlowDialog"
-        :curRow="curSopData"
-        @confirm="sopStepConfirm"
+      v-model:visible="showViolationFlowDialog"
+      :curRow="curSopData"
+      @confirm="sopStepConfirm"
     ></violation-flow-dialog>
   </div>
 </template>
 
 <script setup name="MessageList">
-import {timestampFilter, customerTypeFilter, messageTypeFilter} from '@/utils/filter';
-import QualityIssueDialog from "@/views/sop/sop-manage/quality-issue/quality-issue-dialog.vue";
-import SopStepDialog from "@/views/sop/sop-manage/sop-step/sop-step-dialog.vue";
-import AbnormalAudit from "@/views/work-hours/work-hours-manage/abnormal-check/abnormal-audit.vue";
-import PlanChangeDialog from "@/views/sop/sop-manage/plan-change/plan-change-dialog.vue";
-import {reactive, ref} from "vue";
-import {MessagePlugin} from "tdesign-vue-next";
-import ViolationFlowDialog from "@/views/sop/sop-monitor/violation-registration/flow-dialog.vue";
-import {getViolationBy, setMyMessagesRead} from "@/api/my-workbenches";
-import {sopListApi} from "@/api/sop";
-
+import {
+  timestampFilter,
+  customerTypeFilter,
+  messageTypeFilter,
+} from '@/utils/filter';
+import QualityIssueDialog from '@/views/sop/sop-manage/quality-issue/quality-issue-dialog.vue';
+import SopStepDialog from '@/views/sop/sop-manage/sop-step/sop-step-dialog.vue';
+import AbnormalAudit from '@/views/work-hours/work-hours-manage/abnormal-check/abnormal-audit.vue';
+import PlanChangeDialog from '@/views/sop/sop-manage/plan-change/plan-change-dialog.vue';
+import { reactive, ref, computed } from 'vue';
+import { MessagePlugin } from 'tdesign-vue-next';
+import ViolationFlowDialog from '@/views/sop/sop-monitor/violation-registration/flow-dialog.vue';
+import { getViolationBy, setMyMessagesRead } from '@/api/my-workbenches';
+import { sopListApi } from '@/api/sop';
+
+const IS_CYTX = (item) => {
+  return ['OFFICE_SOP', 'CLOUD_MARK_SOP'].includes(item.messageType);
+};
 const { tableData, pagination, onChange } = defineProps([
   'tableData',
   'pagination',
@@ -114,38 +144,35 @@ const showViolationFlowDialog = ref(false);
 const curSopData = ref({});
 const curRow = ref({});
 
-
-
-
-
 const editSopFlowHandle = (row) => {
   curRow.value = row;
   if (row.messageType === 'AFTER' || row.messageType === 'BEFORE') {
     const params = reactive({
       pageNumber: 1,
       pageSize: 10,
-      serviceId: "",
+      serviceId: '',
       formWidgetMetadataViewList: [],
-      formWidgetMetadataConditionList: [{fieldId: "sopNo", operator: "EQ", fieldValue: row.code}],
-      type: row.objType
+      formWidgetMetadataConditionList: [
+        { fieldId: 'sopNo', operator: 'EQ', fieldValue: row.code },
+      ],
+      type: row.objType,
     });
-    sopListApi(params).then(res => {
+    sopListApi(params).then((res) => {
       if (res.records.length) {
         curSopData.value = res.records[0];
         showSopStepDialog.value = true;
       } else {
         MessagePlugin.error('未找到对应的SOP');
       }
-    })
+    });
 
     return;
   }
   if (row.messageType === 'VIOLATION') {
-    getViolationBy(row.code)
-      .then(res=>{
-          curSopData.value = res;
-          showViolationFlowDialog.value = true;
-      })
+    getViolationBy(row.code).then((res) => {
+      curSopData.value = res;
+      showViolationFlowDialog.value = true;
+    });
     return;
   }
   // if (row.messageType === 'SYSTEM_PLAN_CHANGE') {
@@ -158,7 +185,6 @@ const editSopFlowHandle = (row) => {
   //   return;
   // }
 
-
   MessagePlugin.error('未知类型待办');
 };
 const sopStepConfirm = () => {

+ 11 - 5
src/views/service-unit/dispatch/dispatch-manage/allocation-dialog.vue

@@ -54,9 +54,10 @@
                 bordered
               >
                 <template #roleName="{ row }">
-                  <span v-if="row.roleName === '区域协调人'">{{
-                    row.roleName
-                  }}</span>
+                  <span v-if="row.roleName === '区域协调人'">
+                    <span style="color: red" v-if="IS_CLOUD">* </span>
+                    {{ row.roleName }}</span
+                  >
                   <span v-else
                     ><span style="color: red">* </span>{{ row.roleName }}</span
                   >
@@ -109,7 +110,7 @@
     </template>
   </my-dialog>
 </template>
-<script setup name="PersonDeployDialog">
+<script setup name="AllocationDialog">
 import { computed, onMounted, ref, watch } from 'vue';
 import { MessagePlugin } from 'tdesign-vue-next';
 import { MinusCircleFilledIcon } from 'tdesign-icons-vue-next';
@@ -137,6 +138,9 @@ const props = defineProps({
 });
 const requestInfo = ref({});
 const formRef = ref(null);
+const IS_CLOUD = computed(() => {
+  return props.curRow?.type === 'CLOUD_MARK_SOP_FLOW';
+});
 const init = () => {
   return [
     {
@@ -232,7 +236,9 @@ const roleColumns = [
 ];
 
 const save = async () => {
-  if (!formData.allocationParams[1].userIdList?.length) {
+  if (IS_CLOUD && !formData.allocationParams[0].userIdList?.length) {
+    return MessagePlugin.error('区域协调人必选,且只能选择一个');
+  } else if (!formData.allocationParams[1].userIdList?.length) {
     return MessagePlugin.error('大区经理必选,且只能选择一个');
   } else if (!formData.allocationParams[2].userIdList?.length) {
     return MessagePlugin.error('工程师必选');

+ 6 - 2
src/views/sop/components/dynamic-form-item/LABEL.vue

@@ -14,14 +14,18 @@ const props = defineProps({
   config: { type: Object },
 });
 const titleArr = computed(() => {
-  return JSON.parse(props.config.title || '[]');
+  let title = props.config.title;
+  if (typeof props.config.title === 'string') {
+    title = props.config.title.replace(/[\r|\n|\t]/g, '');
+  }
+  return JSON.parse(title || '[]');
 });
 </script>
 <style lang="less" scoped>
 .label {
   margin: 0 0 15px;
   font-size: 14px;
-  font-weight: bold;
+  // font-weight: bold;
   color: #262626;
   line-height: 24px;
 }

+ 6 - 0
src/views/sop/components/dynamic-form-item/RADIO.vue

@@ -20,6 +20,12 @@
           <span>{{ ')' }}</span>
         </span>
       </t-radio>
+      <image-view
+        v-if="!!config?.dataGrid"
+        :width="100"
+        :height="100"
+        :images="[config?.dataGrid]"
+      ></image-view>
       <div
         v-if="needDefineBtnFormNames.includes(config?.formName)"
         class="define-btn flex items-center"

+ 32 - 0
src/views/sop/components/dynamic-form-item/static-content/DEVICE_IN.vue

@@ -0,0 +1,32 @@
+<template>
+  <div class="static-device-in">
+    <t-tabs v-model="curStep">
+      <t-tab-panel value="设备签收登记" label="设备签收登记">
+        <Tab1 :sop="sop" />
+      </t-tab-panel>
+      <t-tab-panel value="设备去处登记" label="设备去处登记"
+        ><Tab2 :sop="sop" @getTableData="getTableData" />
+      </t-tab-panel>
+    </t-tabs>
+  </div>
+</template>
+<script name="STATIC_DEVICE_IN" setup>
+import { ref } from 'vue';
+import Tab1 from '@/components/common/device-manage-new/tab1.vue';
+import Tab2 from '@/components/common/device-manage-new/tab2.vue';
+const emit = defineEmits(['getTableData']);
+const props = defineProps({
+  visible: Boolean,
+  sop: {
+    type: Object,
+    default() {
+      return {};
+    },
+  },
+});
+const curStep = ref('设备签收登记');
+const getTableData = (val) => {
+  emit('getTableData', val);
+};
+</script>
+<style lang="less" scoped></style>

+ 24 - 1
src/views/sop/sop-manage/sop-step/index.vue

@@ -109,7 +109,11 @@
             :data="formData"
             labelAlign="top"
           >
-            <t-row :gutter="[0, 20]">
+            <!-- 如果是 设备入库登记,则展示固定内容,与动态表单无关 -->
+            <div v-if="IS_DEVICE_IN">
+              <StaticDeviceIn :sop="sop" @get-table-data="getTableData" />
+            </div>
+            <t-row :gutter="[0, 20]" v-else>
               <t-col
                 :span="
                   fullWidthCodes.includes(config.code)
@@ -222,6 +226,7 @@ import {
 import { MessagePlugin } from 'tdesign-vue-next';
 
 import DynamicFormItem from '../../components/dynamic-form-item/index.vue';
+import StaticDeviceIn from '../../components/dynamic-form-item/static-content/DEVICE_IN.vue';
 // import { useRouter, useRoute } from 'vue-router';
 import {
   sopFlowViewApi,
@@ -235,6 +240,11 @@ import { objCopy, timeNumberToText } from '@/utils/tool';
 import { timestampFilter } from '@/utils/filter';
 import bus from '@/utils/bus';
 
+const deviceTableData = ref([]);
+const getTableData = (val) => {
+  deviceTableData.value = val;
+};
+
 const props = defineProps({
   type: {
     type: String,
@@ -339,6 +349,13 @@ const otherRulesPassed = computed(() => {
   return !values.filter((item) => !item).length;
 });
 
+const IS_DEVICE_IN = computed(() => {
+  return (
+    curStepData.value?.formKey === 'cloudmark_sop_device_manager.form' &&
+    props.sop?.type === 'CLOUD_MARK_SOP_FLOW'
+  );
+});
+
 function getFlowApproveHistoryList(data) {
   if (!data) return [];
 
@@ -732,6 +749,12 @@ const submitHandle = async (approve = 'START') => {
   // if (approve) return;
 
   if (IS_FILL_MODE.value) {
+    if (IS_DEVICE_IN.value) {
+      //不允许有使用中的设备
+      if (deviceTableData.value?.find((item) => item.status === 'USING')) {
+        return;
+      }
+    }
     let data = {
       taskId: props.sop.taskId,
       formProperties: getFormData(),