Bläddra i källkod

1.1.0开发中

刘洋 1 år sedan
förälder
incheckning
2b42222ede

+ 7 - 0
src/api/sop.js

@@ -272,3 +272,10 @@ export const getSopFastOptionsApi = (params) =>
     url: '/api/admin/sop/quick/list',
     params,
   });
+
+export const saveSopFastOptionsApi = (data) =>
+  request({
+    url: '/api/admin/sop/quick/save',
+    data,
+    loading: true,
+  });

+ 36 - 10
src/components/global/tag-list/index.vue

@@ -11,10 +11,21 @@
           </t-form-item>
         </t-form>
       </div>
-      <t-button type="primary" class="m-l-10px" @click="save">保存</t-button>
+      <t-button
+        type="primary"
+        class="m-l-10px"
+        @click="save"
+        :disabled="list.length >= 5"
+        >保存</t-button
+      >
     </div>
     <div class="tag-list flex">
-      <div class="fast-tag" v-for="item in list" :key="item.id">
+      <div
+        class="fast-tag"
+        v-for="item in list"
+        :key="item.id"
+        @click="tagClick(item)"
+      >
         <span class="title">{{ item.name }}</span>
         <MultiplyIcon class="icon" />
       </div>
@@ -24,16 +35,17 @@
 <script name="TagList" setup>
 import { MultiplyIcon } from 'tdesign-icons-vue-next';
 import { ref, onMounted, reactive } from 'vue';
-import { getSopFastOptionsApi } from '@/api/sop';
+import { getSopFastOptionsApi, saveSopFastOptionsApi } from '@/api/sop';
+import { MessagePlugin } from 'tdesign-vue-next';
+const emit = defineEmits(['tagClick']);
 const formRef = ref();
-const emit = defineEmits(['saveFastOption']);
 const props = defineProps({
   type: String,
   contentType: String,
-  // content: {
-  //   type: Object,
-  //   default: () => ({}),
-  // },
+  fastOptionContent: {
+    type: Array,
+    default: () => [],
+  },
 });
 const formData = reactive({
   name: '',
@@ -56,12 +68,26 @@ onMounted(() => {
 const save = async () => {
   const valid = await formRef.value?.validate();
   if (valid !== true) return;
-  emit('saveFastOption', formData.name);
+
+  saveSopFastOptionsApi({
+    content: JSON.stringify(props.fastOptionContent),
+    type: props.type,
+    contentType: props.contentType,
+    name: formData.name,
+  }).then(() => {
+    MessagePlugin.success('保存成功');
+    formData.name = '';
+    getList();
+  });
+};
+const tagClick = (item) => {
+  let content = JSON.parse(item.content);
+  emit('tagClick', content);
 };
 </script>
 <style lang="less" scoped>
 .tag-list-box {
-  padding-bottom: 15px;
+  padding-bottom: 10px;
 }
 .tag-list {
   padding: 5px 0;

+ 100 - 100
src/views/sop/components/select-filter/config.js

@@ -72,106 +72,106 @@ export const operatorConfig = [
   },
 ];
 
-export const staticMetadata = [
-  {
-    code: 'TEXT',
-    fieldId: 'serviceName',
-    fieldTitle: '服务单元',
-  },
-  {
-    code: 'TEXT',
-    fieldId: 'sopNo',
-    fieldTitle: 'SOP流水号',
-  },
-  {
-    code: 'TEXT',
-    fieldId: 'crmNo',
-    fieldTitle: '项目单号',
-  },
-  {
-    code: 'DATE',
-    fieldId: 'beginTime',
-    fieldTitle: '派单时间',
-  },
-  {
-    code: 'TEXT',
-    fieldId: 'customManagerName',
-    fieldTitle: '客户经理',
-  },
-  {
-    code: 'SINGLE_SELECT',
-    fieldId: 'customManagerType',
-    fieldTitle: '客户类型',
-    options: dictToOptionList(CUSTOMER_TYPE),
-  },
-  {
-    code: 'TEXT',
-    fieldId: 'customName',
-    fieldTitle: '客户名称',
-  },
-  {
-    code: 'TEXT',
-    fieldId: 'crmName',
-    fieldTitle: '项目名称',
-  },
-  {
-    code: 'TEXT',
-    fieldId: 'productName',
-    fieldTitle: '实施产品',
-  },
-  {
-    code: 'TEXT',
-    fieldId: 'serviceName',
-    fieldTitle: '服务单元',
-  },
-  {
-    code: 'DATE',
-    fieldId: 'examStartTime',
-    fieldTitle: '考试开始时间',
-  },
-  {
-    code: 'DATE',
-    fieldId: 'examEndTime',
-    fieldTitle: '考试结束时间',
-  },
-  {
-    code: 'TEXT',
-    fieldId: 'flowCreateName',
-    fieldTitle: '提交人',
-  },
-  {
-    code: 'DATE',
-    fieldId: 'flowCreateTime',
-    fieldTitle: '提交时间',
-  },
-  {
-    code: 'DATE',
-    fieldId: 'flowUpdateTime',
-    fieldTitle: '更新时间',
-  },
-  {
-    code: 'SINGLE_SELECT',
-    fieldId: 'status',
-    fieldTitle: '流程状态',
-    // options: dictToOptionList(FLOW_STATUS).filter(
-    //   (item) => item.value !== 'END'
-    // ),
-    options: [
-      { value: 'AUDITING', label: '进行中' },
-      { value: 'FINISH', label: '已完结' },
-    ],
-  },
-  {
-    code: 'TEXT',
-    fieldId: 'taskName',
-    fieldTitle: '流程节点',
-  },
-  {
-    code: 'TEXT',
-    fieldId: 'pendApproveName',
-    fieldTitle: '当前节点负责人',
-  },
-];
+// export const staticMetadata = [
+//   {
+//     code: 'TEXT',
+//     fieldId: 'serviceName',
+//     fieldTitle: '服务单元',
+//   },
+//   {
+//     code: 'TEXT',
+//     fieldId: 'sopNo',
+//     fieldTitle: 'SOP流水号',
+//   },
+//   {
+//     code: 'TEXT',
+//     fieldId: 'crmNo',
+//     fieldTitle: '项目单号',
+//   },
+//   {
+//     code: 'DATE',
+//     fieldId: 'beginTime',
+//     fieldTitle: '派单时间',
+//   },
+//   {
+//     code: 'TEXT',
+//     fieldId: 'customManagerName',
+//     fieldTitle: '客户经理',
+//   },
+//   {
+//     code: 'SINGLE_SELECT',
+//     fieldId: 'customManagerType',
+//     fieldTitle: '客户类型',
+//     options: dictToOptionList(CUSTOMER_TYPE),
+//   },
+//   {
+//     code: 'TEXT',
+//     fieldId: 'customName',
+//     fieldTitle: '客户名称',
+//   },
+//   {
+//     code: 'TEXT',
+//     fieldId: 'crmName',
+//     fieldTitle: '项目名称',
+//   },
+//   {
+//     code: 'TEXT',
+//     fieldId: 'productName',
+//     fieldTitle: '实施产品',
+//   },
+//   {
+//     code: 'TEXT',
+//     fieldId: 'serviceName',
+//     fieldTitle: '服务单元',
+//   },
+//   {
+//     code: 'DATE',
+//     fieldId: 'examStartTime',
+//     fieldTitle: '考试开始时间',
+//   },
+//   {
+//     code: 'DATE',
+//     fieldId: 'examEndTime',
+//     fieldTitle: '考试结束时间',
+//   },
+//   {
+//     code: 'TEXT',
+//     fieldId: 'flowCreateName',
+//     fieldTitle: '提交人',
+//   },
+//   {
+//     code: 'DATE',
+//     fieldId: 'flowCreateTime',
+//     fieldTitle: '提交时间',
+//   },
+//   {
+//     code: 'DATE',
+//     fieldId: 'flowUpdateTime',
+//     fieldTitle: '更新时间',
+//   },
+//   {
+//     code: 'SINGLE_SELECT',
+//     fieldId: 'status',
+//     fieldTitle: '流程状态',
+//     // options: dictToOptionList(FLOW_STATUS).filter(
+//     //   (item) => item.value !== 'END'
+//     // ),
+//     options: [
+//       { value: 'AUDITING', label: '进行中' },
+//       { value: 'FINISH', label: '已完结' },
+//     ],
+//   },
+//   {
+//     code: 'TEXT',
+//     fieldId: 'taskName',
+//     fieldTitle: '流程节点',
+//   },
+//   {
+//     code: 'TEXT',
+//     fieldId: 'pendApproveName',
+//     fieldTitle: '当前节点负责人',
+//   },
+// ];
 
 export const specialUserMeta = [
   'region_user_id_1',

+ 28 - 6
src/views/sop/components/select-filter/index.vue

@@ -82,6 +82,13 @@
             </div>
           </div>
         </div>
+        <div class="p-l-10px p-r-10px">
+          <tag-list
+            :type="type"
+            :contentType="contentType"
+            :fastOptionContent="fastOptionContent"
+          ></tag-list>
+        </div>
         <div class="filter-footer">
           <t-button variant="outline" size="small" @click="clearHandle">
             <template #icon><svg-icon name="clear" color="#262626" /></template
@@ -103,13 +110,15 @@
 
 <script setup name="SelectFilter">
 import { randomCode } from '@/utils/tool';
-import { ref, computed, reactive } from 'vue';
-import { getOperatorByCode, staticMetadata } from './config';
+import { ref, computed, reactive, watch } from 'vue';
+import { getOperatorByCode } from './config';
 import FieldValue from './field-value.vue';
 import { MessagePlugin } from 'tdesign-vue-next';
 
 const emit = defineEmits(['confirm']);
 const props = defineProps({
+  type: String,
+  contentType: String,
   metadata: {
     type: Array,
     default() {
@@ -125,10 +134,16 @@ const toggleVisible = () => {
 
 const dataList = ref([]);
 
-const metadataList = computed(() => {
-  // return [...props.metadata, ...staticMetadata];
-  return [...props.metadata];
-});
+// const metadataList = computed(() => {
+//   return [...props.metadata];
+// });
+const metadataList = ref([...props.metadata]);
+watch(
+  () => props.metadata,
+  (val) => {
+    metadataList.value = [...(val || [])];
+  }
+);
 
 const selections = ['SINGLE_SELECT', 'MULTIPLE_SELECT', 'CHECKBOX', 'RADIO'];
 const fieldChange = (row) => {
@@ -184,6 +199,13 @@ const confirmHandle = () => {
   emit('confirm', dataList.value, formWidgetMetadataOperation.value);
   toggleVisible();
 };
+
+const fastOptionContent = computed(() => {
+  return {
+    dataList: dataList.value,
+    metadataList: metadataList.value,
+  };
+});
 </script>
 
 <style lang="less">

+ 12 - 6
src/views/sop/components/select-metadata.vue

@@ -37,7 +37,7 @@
             <tag-list
               :type="type"
               :contentType="contentType"
-              @saveFastOption="saveFastOption"
+              :fastOptionContent="fastOptionContent"
             ></tag-list>
           </template>
         </t-select>
@@ -51,12 +51,16 @@ import { onMounted, ref, useAttrs, watch, computed } from 'vue';
 import { cloneDeep } from 'lodash-es';
 import { metadataListApi } from '@/api/sop';
 
-const emit = defineEmits(['update:modelValue', 'change', 'saveFastOption']);
+const emit = defineEmits(['update:modelValue', 'change']);
 const props = defineProps({
   modelValue: { type: Array },
   type: { type: String, default: 'OFFICE_SOP_FLOW' },
   originColumns: { type: Array, default: [] },
   contentType: { type: String },
+  fastOptionContent: {
+    type: Array,
+    default: () => [],
+  },
 });
 
 const attrs = useAttrs();
@@ -100,7 +104,12 @@ const onChange = () => {
   );
   emit('change', selectedData);
 };
-
+watch(
+  () => props.originColumns,
+  () => {
+    search();
+  }
+);
 watch(
   () => props.modelValue,
   (val) => {
@@ -111,9 +120,6 @@ watch(
     immediate: true,
   }
 );
-const saveFastOption = (name) => {
-  emit('saveFastOption', name);
-};
 </script>
 
 <style lang="less" scoped>

+ 3 - 2
src/views/sop/components/sop-sort-panel/index.vue

@@ -63,7 +63,7 @@
 <script setup name="SopSortPanel">
 import { randomCode } from '@/utils/tool';
 import { ref, computed, reactive } from 'vue';
-import { staticMetadata } from '../select-filter/config';
+// import { staticMetadata } from '../select-filter/config';
 import { MessagePlugin } from 'tdesign-vue-next';
 
 const emit = defineEmits(['confirm']);
@@ -82,7 +82,8 @@ const toggleVisible = () => {
 };
 const fieldId = ref('');
 const metadataList = computed(() => {
-  return [...props.metadata, ...staticMetadata];
+  // return [...props.metadata, ...staticMetadata];
+  return [...props.metadata];
 });
 const fieldIdChange = (fieldId) => {
   if (!fieldId) {

+ 146 - 90
src/views/sop/sop-manage/student-sop/index.vue

@@ -16,7 +16,7 @@
         @change="metadataChange"
         :originColumns="originColumns"
         contentType="VIEW"
-        @saveFastOption="saveFastOption"
+        :fastOptionContent="formWidgetMetadataViewList"
       ></select-metadata>
       <t-button variant="outline" @click="handleRefresh">
         <template #icon><svg-icon name="refresh" color="#262626" /></template>
@@ -45,6 +45,8 @@
       <select-filter
         :metadata="formWidgetMetadataViewList"
         @confirm="filterConfirm"
+        type="CLOUD_MARK_SOP_FLOW"
+        contentType="SEARCH"
       ></select-filter>
     </div>
     <SearchForm :fields="fields" :params="params" :search="search">
@@ -57,7 +59,7 @@
           }"
         ></select-service-unit>
       </template>
-      <template #aaa="{ item, params }">
+      <template #leadId="{ item, params }">
         <select-type-user
           v-model="params[item.prop]"
           type="REGION_MANAGER"
@@ -214,9 +216,9 @@
 </template>
 
 <script setup name="StudentSop">
-import { ref, reactive, computed } from 'vue';
+import { ref, reactive, computed, watch } from 'vue';
 import useFetchTable from '@/hooks/useFetchTable';
-import { sopListApi, sopBatchCancelApi } from '@/api/sop';
+import { sopListApi, sopBatchCancelApi, getSopFastOptionsApi } from '@/api/sop';
 import { timestampFilter } from '@/utils/filter';
 import SelectFilter from '../../components/select-filter/index.vue';
 import SelectMetadata from '../../components/select-metadata.vue';
@@ -240,8 +242,14 @@ const selectedRowKeys = ref([]);
 const selectChange = (value) => {
   selectedRowKeys.value = value;
 };
-const originColumns = [
-  { fieldId: 'serviceName', fieldTitle: '服务单元', width: 160, code: 'TEXT' },
+const originColumns = ref([]);
+const defaultTableColumns = [
+  {
+    fieldId: 'serviceName',
+    fieldTitle: '服务单元',
+    width: 160,
+    code: 'TEXT',
+  },
   { fieldId: 'sopNo', fieldTitle: 'SOP流水号', width: 200, code: 'TEXT' },
   { fieldId: 'crmNo', fieldTitle: '项目单号', width: 200, code: 'TEXT' },
   { fieldId: 'beginTime', fieldTitle: '派单时间', width: 180, code: 'DATE' },
@@ -260,7 +268,12 @@ const originColumns = [
   },
   { fieldId: 'customName', fieldTitle: '客户名称', width: 140, code: 'TEXT' },
   { fieldId: 'crmName', fieldTitle: '项目名称', minWidth: 160, code: 'TEXT' },
-  { fieldId: 'productName', fieldTitle: '实施产品', width: 120, code: 'TEXT' },
+  {
+    fieldId: 'productName',
+    fieldTitle: '实施产品',
+    width: 120,
+    code: 'TEXT',
+  },
   {
     fieldId: 'examStartTime',
     fieldTitle: '考试开始时间',
@@ -273,7 +286,12 @@ const originColumns = [
     width: 180,
     code: 'DATE',
   },
-  { fieldId: 'flowCreateName', fieldTitle: '提交人', width: 140, code: 'TEXT' },
+  {
+    fieldId: 'flowCreateName',
+    fieldTitle: '提交人',
+    width: 140,
+    code: 'TEXT',
+  },
   {
     fieldId: 'flowCreateTime',
     fieldTitle: '提交时间',
@@ -304,7 +322,30 @@ const originColumns = [
     code: 'SINGLE_SELECT',
   },
 ];
-const originFieldIds = originColumns.map((item) => item.fieldId);
+originColumns.value = cloneDeep(defaultTableColumns);
+const getCustomColumns = (id) => {
+  getSopFastOptionsApi({
+    type: 'CLOUD_MARK_SOP_FLOW',
+    contentType: 'VIEW',
+  }).then((res) => {
+    if (res && res?.length) {
+      let option = res.find((item) => item.id == id);
+      let data = JSON.parse(option.content || '[]').map((item) => {
+        if (item.options && typeof item.options === 'string') {
+          item.options = JSON.parse(item.options);
+        }
+        return item;
+      });
+      originColumns.value = data;
+    } else {
+      originColumns.value = [];
+    }
+  });
+};
+
+const originFieldIds = computed(() => {
+  return originColumns.value.map((item) => item.fieldId);
+});
 
 const columns = computed(() => {
   const defaultColumns = [
@@ -343,84 +384,90 @@ const columns = computed(() => {
   }
 });
 
-const fields = ref([
-  {
-    prop: 'serviceId',
-    label: '服务单元',
-    type: 'select',
-    labelWidth: 75,
-    colSpan: 4,
-    cell: 'service',
-  },
-  {
-    prop: 'aaa',
-    label: '大区经理',
-    labelWidth: 75,
-    colSpan: 4,
-    cell: 'aaa',
-  },
-  {
-    prop: 'bbb',
-    label: '客户名称',
-    labelWidth: 75,
-    colSpan: 4,
-  },
-  {
-    prop: 'ccc',
-    label: '当前节点',
-    type: 'select',
-    labelWidth: 75,
-    colSpan: 4,
-    options: [],
-  },
-  {
-    prop: 'ddd',
-    label: '客户经理',
-    labelWidth: 75,
-    colSpan: 4,
-  },
-  {
-    prop: 'eee',
-    label: '打卡在时限内',
-    type: 'select',
-    labelWidth: 100,
-    colSpan: 4,
-    options: [],
-  },
-  {
-    prop: 'fff',
-    label: '项目名称',
-    labelWidth: 75,
-    colSpan: 4,
-  },
-  {
-    prop: 'ggg',
-    label: 'sop号',
-    labelWidth: 75,
-    colSpan: 4,
-  },
-  {
-    prop: 'hhh',
-    label: '快捷搜索',
-    type: 'select',
-    labelWidth: 75,
-    colSpan: 4,
-    options: [],
-  },
-  {
-    prop: 'iii',
-    label: '快捷显示',
-    type: 'select',
-    labelWidth: 75,
-    colSpan: 4,
-    options: [],
-  },
-  {
-    prop: 'buttons',
-    colSpan: 4,
-    labelWidth: 16,
-  },
-]);
+const fields = computed(() => {
+  return [
+    {
+      prop: 'serviceId',
+      label: '服务单元',
+      type: 'select',
+      labelWidth: 104,
+      colSpan: 6,
+      cell: 'service',
+    },
+    {
+      prop: 'leadId',
+      label: '大区经理',
+      labelWidth: 104,
+      colSpan: 6,
+      cell: 'leadId',
+    },
+    {
+      prop: 'customName',
+      label: '客户名称',
+      labelWidth: 104,
+      colSpan: 6,
+    },
+    {
+      prop: 'taskKey',
+      label: '当前节点',
+      type: 'select',
+      labelWidth: 104,
+      colSpan: 6,
+      options:
+        appStore
+          .getFlowDetailByType('CLOUD_MARK_SOP_FLOW')
+          ?.setupList?.map((item) => ({ value: item, label: item })) || [],
+    },
+    {
+      prop: 'crmUserId',
+      label: '客户经理',
+      labelWidth: 104,
+      colSpan: 6,
+    },
+
+    {
+      prop: 'crmName',
+      label: '项目名称',
+      labelWidth: 104,
+      colSpan: 6,
+    },
+    {
+      prop: 'sopNo',
+      label: 'sop号',
+      labelWidth: 104,
+      colSpan: 6,
+    },
+    {
+      prop: 'fastSearch',
+      label: '快捷搜索',
+      type: 'select',
+      labelWidth: 104,
+      colSpan: 6,
+      options: [],
+    },
+    {
+      prop: 'fastColumns',
+      label: '快捷显示',
+      type: 'select',
+      labelWidth: 104,
+      colSpan: 6,
+      options: [],
+    },
+    {
+      prop: 'eee',
+      label: '打卡在时限内',
+      type: 'select',
+      labelWidth: 104,
+      colSpan: 6,
+      options: [],
+    },
+    {
+      prop: 'buttons',
+      colSpan: 6,
+      labelWidth: 16,
+    },
+  ];
+});
 const params = reactive({
   serviceId: '',
   formWidgetMetadataViewList: cloneDeep(originColumns),
@@ -428,9 +475,10 @@ const params = reactive({
   formWidgetMetadataOrderList: [],
   formWidgetMetadataOperation: 'AND',
 });
+
 const transParams = computed(() => {
   let formWidgetMetadataViewList = params.formWidgetMetadataViewList.filter(
-    (item) => !originFieldIds.includes(item.fieldId)
+    (item) => !originFieldIds.value.includes(item.fieldId)
   );
   return { ...params, formWidgetMetadataViewList, type: 'CLOUD_MARK_SOP_FLOW' };
 });
@@ -450,7 +498,12 @@ const {
 
 const formWidgetMetadataViewList = ref(cloneDeep(originColumns));
 const metadataChange = (vals) => {
-  formWidgetMetadataViewList.value = vals;
+  formWidgetMetadataViewList.value = vals.map((item) => {
+    if (item.options && typeof item.options === 'string') {
+      item.options = JSON.parse(item.options);
+    }
+    return item;
+  });
   search();
 };
 
@@ -554,5 +607,8 @@ const toDeviceManage = (row) => {
   showDeviceManage.value = true;
 };
 
-const saveFastOption = (name) => {};
+watch(originColumns, () => {
+  params.formWidgetMetadataViewList = cloneDeep(originColumns.value);
+  formWidgetMetadataViewList.value = cloneDeep(originColumns.value);
+});
 </script>