فهرست منبع

显示字段和筛选条件md

zhangjie 1 سال پیش
والد
کامیت
a1cec0404b

+ 6 - 0
src/style/tdesign-reset.less

@@ -64,9 +64,15 @@
 .t-button {
 .t-button {
   &:not(.t-button--icon-only) .svg-icon {
   &:not(.t-button--icon-only) .svg-icon {
     margin-right: 8px;
     margin-right: 8px;
+  }
+  .svg-icon {
     width: 13px;
     width: 13px;
     height: 13px;
     height: 13px;
   }
   }
+  &.t-size-s .svg-icon {
+    width: 11px;
+    height: 11px;
+  }
 
 
   &.t-button--theme-default:hover {
   &.t-button--theme-default:hover {
     .svg-icon use {
     .svg-icon use {

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

@@ -1,3 +1,6 @@
+import { CUSTOMER_TYPE, FLOW_STATUS } from '@/config/constants';
+import { dictToOptionList } from '@/utils/tool';
+
 const fieldCodes = [
 const fieldCodes = [
   'NUMBER',
   'NUMBER',
   'DATE',
   'DATE',
@@ -69,6 +72,101 @@ 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),
+  },
+  {
+    code: 'TEXT',
+    fieldId: 'taskName',
+    fieldTitle: '流程节点',
+  },
+  {
+    code: 'TEXT',
+    fieldId: 'pendApproveName',
+    fieldTitle: '当前节点负责人',
+  },
+];
+
 export function getOperatorByCode(code) {
 export function getOperatorByCode(code) {
   return operatorConfig
   return operatorConfig
     .filter((item) => item.range.includes(code))
     .filter((item) => item.range.includes(code))

+ 1 - 0
src/views/sop/components/select-filter/field-value.vue

@@ -20,6 +20,7 @@
     multiple
     multiple
     :options="field.options || []"
     :options="field.options || []"
     placeholder="请选择"
     placeholder="请选择"
+    :min-collapsed-num="1"
     style="width: 100%"
     style="width: 100%"
     @change="emitChange"
     @change="emitChange"
   ></t-select>
   ></t-select>

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

@@ -1,5 +1,9 @@
 <template>
 <template>
-  <t-popup class="select-filter" placement="bottom-left" :visible="visible">
+  <t-popup
+    overlayClassName="select-filter"
+    placement="bottom-left"
+    :visible="visible"
+  >
     <t-button variant="outline" @click="toggleVisible">
     <t-button variant="outline" @click="toggleVisible">
       <template #icon><svg-icon name="filter" color="#262626" /></template>
       <template #icon><svg-icon name="filter" color="#262626" /></template>
       筛选条件
       筛选条件
@@ -24,7 +28,7 @@
                   @change="fieldChange(item)"
                   @change="fieldChange(item)"
                 >
                 >
                   <t-option
                   <t-option
-                    v-for="item in metadata"
+                    v-for="item in metadataList"
                     :key="item.fieldId"
                     :key="item.fieldId"
                     :label="item.fieldTitle"
                     :label="item.fieldTitle"
                     :value="item.fieldId"
                     :value="item.fieldId"
@@ -85,8 +89,8 @@
 
 
 <script setup name="SelectFilter">
 <script setup name="SelectFilter">
 import { randomCode } from '@/utils/tool';
 import { randomCode } from '@/utils/tool';
-import { ref, watch, computed, reactive } from 'vue';
-import { getOperatorByCode } from './config';
+import { ref, computed, reactive } from 'vue';
+import { getOperatorByCode, staticMetadata } from './config';
 import FieldValue from './field-value.vue';
 import FieldValue from './field-value.vue';
 import { MessagePlugin } from 'tdesign-vue-next';
 import { MessagePlugin } from 'tdesign-vue-next';
 
 
@@ -107,20 +111,29 @@ const toggleVisible = () => {
 
 
 const dataList = ref([]);
 const dataList = ref([]);
 
 
+const metadataList = computed(() => {
+  return [...props.metadata, ...staticMetadata];
+});
+
+const selections = ['SINGLE_SELECT', 'MULTIPLE_SELECT', 'CHECKBOX', 'RADIO'];
 const fieldChange = (row) => {
 const fieldChange = (row) => {
-  const metad = props.metadata.find((item) => item.fieldId === row.fieldId);
+  const metad = metadataList.value.find((item) => item.fieldId === row.fieldId);
   row.code = metad.code;
   row.code = metad.code;
   row.operatorList = getOperatorByCode(metad.code);
   row.operatorList = getOperatorByCode(metad.code);
-  row.fieldValue = null;
+  if (metad.options) row.options = metad.options;
   row.operator = '';
   row.operator = '';
 
 
   // value
   // value
-  const selections = ['SINGLE_SELECT', 'MULTIPLE_SELECT', 'CHECKBOX', 'RADIO'];
+  row.fieldValue = null;
   if (selections.includes(row.code)) row.fieldValue = [];
   if (selections.includes(row.code)) row.fieldValue = [];
 };
 };
 const operatorChange = (row) => {
 const operatorChange = (row) => {
+  if (row.operator === 'RANGE' || selections.includes(row.code)) {
+    row.fieldValue = [];
+    return;
+  }
+
   row.fieldValue = null;
   row.fieldValue = null;
-  if (row.operator === 'RANGE') row.fieldValue = [];
 };
 };
 
 
 const addHandle = () => {
 const addHandle = () => {
@@ -158,6 +171,13 @@ const confirmHandle = () => {
 };
 };
 </script>
 </script>
 
 
+<style lang="less">
+.select-filter {
+  .t-popup__content {
+    padding: 0;
+  }
+}
+</style>
 <style lang="less" scoped>
 <style lang="less" scoped>
 .filter-box {
 .filter-box {
   width: 640px;
   width: 640px;

+ 28 - 15
src/views/sop/components/select-metadata.vue

@@ -11,16 +11,22 @@
           filterable
           filterable
           clearable
           clearable
           popupVisible
           popupVisible
+          multiple
           :min-collapsed-num="1"
           :min-collapsed-num="1"
           :popup-props="{
           :popup-props="{
             attach: 'scrollParent',
             attach: 'scrollParent',
             overlayInnerStyle: {
             overlayInnerStyle: {
-              width: '300px',
+              width: '260px',
             },
             },
           }"
           }"
           v-bind="attrs"
           v-bind="attrs"
           @change="onChange"
           @change="onChange"
         >
         >
+          <template #panelTopContent>
+            <div class="t-select-option t-size-m">
+              <t-checkbox v-model="all" @change="allChange">全选</t-checkbox>
+            </div>
+          </template>
           <t-option
           <t-option
             v-for="item in optionList"
             v-for="item in optionList"
             :key="item.fieldId"
             :key="item.fieldId"
@@ -40,17 +46,13 @@ import { metadataListApi } from '@/api/sop';
 
 
 const emit = defineEmits(['update:modelValue', 'change']);
 const emit = defineEmits(['update:modelValue', 'change']);
 const props = defineProps({
 const props = defineProps({
-  modelValue: { type: [Number, String, Array], default: '' },
+  modelValue: { type: Array },
   type: { type: String, default: 'OFFICE_SOP_FLOW' },
   type: { type: String, default: 'OFFICE_SOP_FLOW' },
 });
 });
 const attrs = useAttrs();
 const attrs = useAttrs();
 
 
-const isMultiple = computed(() => {
-  const multiple = attrs.multiple;
-  return multiple === '' || multiple;
-});
-
-let selected = ref('');
+let all = ref(false);
+let selected = ref([]);
 let optionList = ref([]);
 let optionList = ref([]);
 const search = async () => {
 const search = async () => {
   optionList.value = [];
   optionList.value = [];
@@ -69,14 +71,25 @@ onMounted(() => {
   search();
   search();
 });
 });
 
 
+const allChange = () => {
+  if (all.value) {
+    selected.value = optionList.value.map((item) => item.fieldId);
+    emit('update:modelValue', selected.value);
+    emit('change', optionList.value);
+  } else {
+    selected.value = [];
+    emit('update:modelValue', selected.value);
+    emit('change', []);
+  }
+};
+
 const onChange = () => {
 const onChange = () => {
-  const selectedData = isMultiple.value
-    ? optionList.value.filter(
-        (item) => selected.value && selected.value.includes(item.fieldName)
-      )
-    : optionList.value.filter((item) => selected.value === item.fieldName);
+  all.value = selected.value.length === optionList.value.length;
+  const selectedData = optionList.value.filter(
+    (item) => selected.value && selected.value.includes(item.fieldId)
+  );
   emit('update:modelValue', selected.value);
   emit('update:modelValue', selected.value);
-  emit('change', isMultiple.value ? selectedData : selectedData[0]);
+  emit('change', selectedData);
 };
 };
 
 
 watch(
 watch(
@@ -92,7 +105,7 @@ watch(
 
 
 <style lang="less" scoped>
 <style lang="less" scoped>
 .metadata-options {
 .metadata-options {
-  width: 300px;
+  width: 260px;
   padding: 5px 0;
   padding: 5px 0;
   border-radius: 3px;
   border-radius: 3px;
   background-color: #fff;
   background-color: #fff;

+ 0 - 1
src/views/sop/sop-manage/office-sop/index.vue

@@ -11,7 +11,6 @@
       </t-button>
       </t-button>
       <select-metadata
       <select-metadata
         v-model="params.formWidgetMetadataList"
         v-model="params.formWidgetMetadataList"
-        multiple
         type="OFFICE_SOP_FLOW"
         type="OFFICE_SOP_FLOW"
         @change="metadataChange"
         @change="metadataChange"
       ></select-metadata>
       ></select-metadata>

+ 33 - 13
src/views/sop/sop-manage/student-sop/index.vue

@@ -11,8 +11,8 @@
       </t-button>
       </t-button>
       <select-metadata
       <select-metadata
         v-model="params.formWidgetMetadataList"
         v-model="params.formWidgetMetadataList"
-        multiple
         type="CLOUD_MARK_SOP_FLOW"
         type="CLOUD_MARK_SOP_FLOW"
+        @change="metadataChange"
       ></select-metadata>
       ></select-metadata>
       <t-button variant="outline" @click="handleRefresh">
       <t-button variant="outline" @click="handleRefresh">
         <template #icon><svg-icon name="refresh" color="#262626" /></template>
         <template #icon><svg-icon name="refresh" color="#262626" /></template>
@@ -39,6 +39,15 @@
       <template #service="{ item, params }">
       <template #service="{ item, params }">
         <select-service-unit v-model="params[item.prop]"></select-service-unit>
         <select-service-unit v-model="params[item.prop]"></select-service-unit>
       </template>
       </template>
+      <template #buttons>
+        <t-space :size="16">
+          <select-filter
+            :metadata="formWidgetMetadataList"
+            @confirm="filterConfirm"
+          ></select-filter>
+          <t-button theme="primary" @click="search">搜索</t-button>
+        </t-space>
+      </template>
     </SearchForm>
     </SearchForm>
 
 
     <div class="flex-1 page-wrap">
     <div class="flex-1 page-wrap">
@@ -151,6 +160,7 @@ import { ref, reactive, computed } from 'vue';
 import useFetchTable from '@/hooks/useFetchTable';
 import useFetchTable from '@/hooks/useFetchTable';
 import { sopListApi, sopBatchCancelApi } from '@/api/sop';
 import { sopListApi, sopBatchCancelApi } from '@/api/sop';
 import { timestampFilter } from '@/utils/filter';
 import { timestampFilter } from '@/utils/filter';
+import SelectFilter from '../../components/select-filter/index.vue';
 import SelectMetadata from '../../components/select-metadata.vue';
 import SelectMetadata from '../../components/select-metadata.vue';
 import SopStepDialog from '../sop-step/sop-step-dialog.vue';
 import SopStepDialog from '../sop-step/sop-step-dialog.vue';
 import QualityIssueDialog from '../quality-issue/quality-issue-dialog.vue';
 import QualityIssueDialog from '../quality-issue/quality-issue-dialog.vue';
@@ -206,17 +216,9 @@ const fields = ref([
     cell: 'service',
     cell: 'service',
   },
   },
   {
   {
-    type: 'buttons',
-    colSpan: 3,
-    children: [
-      {
-        type: 'button',
-        text: '搜索',
-        onClick: () => {
-          search();
-        },
-      },
-    ],
+    prop: 'buttons',
+    colSpan: 4,
+    labelWidth: 16,
   },
   },
 ]);
 ]);
 const params = reactive({
 const params = reactive({
@@ -235,6 +237,23 @@ const {
   onChange,
   onChange,
 } = useFetchTable(sopListApi, { params: transParams });
 } = useFetchTable(sopListApi, { params: transParams });
 
 
+const formWidgetMetadataList = ref([]);
+const metadataChange = (vals) => {
+  formWidgetMetadataList.value = vals;
+};
+
+const filterData = ref([]);
+const filterConfirm = (data) => {
+  // console.log(data);
+  filterData.value = data.map((item) => {
+    return {
+      fieldId: item.fieldId,
+      operator: item.operator,
+      fieldValue: item.fieldValue,
+    };
+  });
+};
+
 const handleSort = () => {
 const handleSort = () => {
   // TODO:
   // TODO:
 };
 };
@@ -269,6 +288,8 @@ const handleBatchCancel = () => {
   });
   });
 };
 };
 
 
+const curSopData = ref({});
+
 const showAddViolationDialog = ref(false);
 const showAddViolationDialog = ref(false);
 const createViolationHandle = (row) => {
 const createViolationHandle = (row) => {
   curSopData.value = row;
   curSopData.value = row;
@@ -276,7 +297,6 @@ const createViolationHandle = (row) => {
 };
 };
 
 
 const showSopStepDialog = ref(false);
 const showSopStepDialog = ref(false);
-const curSopData = ref({});
 const curSopType = ref('');
 const curSopType = ref('');
 const editSopFlowHandle = (row, type = 'fill') => {
 const editSopFlowHandle = (row, type = 'fill') => {
   curSopType.value = type;
   curSopType.value = type;