From 4b1304917b0b16b09dd50191fab59d96933c0cf3 Mon Sep 17 00:00:00 2001
From: 曹睿 <360930172@qq.com>
Date: 星期二, 17 六月 2025 17:31:11 +0800
Subject: [PATCH] feat: 6月15日任务完90%

---
 src/components/PIMTable/PIMTable.vue |  351 +++++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 236 insertions(+), 115 deletions(-)

diff --git a/src/components/PIMTable/PIMTable.vue b/src/components/PIMTable/PIMTable.vue
index ab817f8..3c9e756 100644
--- a/src/components/PIMTable/PIMTable.vue
+++ b/src/components/PIMTable/PIMTable.vue
@@ -1,25 +1,70 @@
 <template>
-  <el-table ref="multipleTable" v-loading="tableLoading" :border="border" :data="tableData"
-    :header-cell-style="{ background: '#F0F1F5', color: '#333333' }" height="calc(100vh - 18.5em)"
-    :highlight-current-row="highlightCurrentRow" :row-class-name="rowClassName" :row-style="rowStyle" :row-key="rowKey"
-    style="width: 100%" tooltip-effect="dark" @row-click="rowClick" @current-change="currentChange" :show-summary="isShowSummary"
-            :summary-method="summaryMethod"
-    @selection-change="handleSelectionChange" class="lims-table">
-    <el-table-column align="center" type="selection" width="55"  v-if="isSelection"/>
+  <el-table
+    ref="multipleTable"
+    v-loading="tableLoading"
+    :border="border"
+    :data="tableData"
+    :header-cell-style="{ background: '#F0F1F5', color: '#333333' }"
+    height="calc(100vh - 18.5em)"
+    :highlight-current-row="highlightCurrentRow"
+    :row-class-name="rowClassName"
+    :row-style="rowStyle"
+    :row-key="rowKey"
+    style="width: 100%"
+    tooltip-effect="dark"
+    @row-click="rowClick"
+    @current-change="currentChange"
+    :show-summary="isShowSummary"
+    :summary-method="summaryMethod"
+    @selection-change="handleSelectionChange"
+    class="lims-table"
+  >
+    <el-table-column
+      align="center"
+      type="selection"
+      width="55"
+      v-if="isSelection"
+    />
     <el-table-column align="center" label="搴忓彿" type="index" width="60" />
 
-    <el-table-column v-for="(item, index) in column" :key="index" :column-key="item.columnKey"
-      :filter-method="item.filterHandler" :filter-multiple="item.filterMultiple" :filtered-value="item.filteredValue"
-      :filters="item.filters" :fixed="item.fixed" :label="item.label" :prop="item.prop" show-overflow-tooltip
-      :align="item.align" :sortable="!!item.sortable" :type="item.type" :width="item.width">
-      <template v-if="item.hasOwnProperty('colunmTemplate')" #[item.colunmTemplate]="scope">
-        <slot v-if="item.theadSlot" :name="item.theadSlot" :index="scope.$index" :row="scope.row" />
+    <el-table-column
+      v-for="(item, index) in column"
+      :key="index"
+      :column-key="item.columnKey"
+      :filter-method="item.filterHandler"
+      :filter-multiple="item.filterMultiple"
+      :filtered-value="item.filteredValue"
+      :filters="item.filters"
+      :fixed="item.fixed"
+      :label="item.label"
+      :prop="item.prop"
+      show-overflow-tooltip
+      :align="item.align"
+      :sortable="!!item.sortable"
+      :type="item.type"
+      :width="item.width"
+    >
+      <template
+        v-if="item.hasOwnProperty('colunmTemplate')"
+        #[item.colunmTemplate]="scope"
+      >
+        <slot
+          v-if="item.theadSlot"
+          :name="item.theadSlot"
+          :index="scope.$index"
+          :row="scope.row"
+        />
       </template>
 
       <template #default="scope">
         <!-- 鎻掓Ы -->
         <div v-if="item.dataType == 'slot'">
-          <slot v-if="item.slot" :index="scope.$index" :name="item.slot" :row="scope.row" />
+          <slot
+            v-if="item.slot"
+            :index="scope.$index"
+            :name="item.slot"
+            :row="scope.row"
+          />
         </div>
         <!-- 杩涘害鏉� -->
         <div v-else-if="item.dataType == 'progress'">
@@ -27,26 +72,47 @@
         </div>
         <!-- 鍥剧墖 -->
         <div v-else-if="item.dataType == 'image'">
-          <img :src="javaApi + '/img/' + scope.row[item.prop]" alt=""
-            style="width: 40px; height: 40px; margin-top: 10px" />
+          <img
+            :src="javaApi + '/img/' + scope.row[item.prop]"
+            alt=""
+            style="width: 40px; height: 40px; margin-top: 10px"
+          />
         </div>
 
         <!-- tag -->
         <div v-else-if="item.dataType == 'tag'">
-          <el-tag v-if="typeof dataTypeFn(scope.row[item.prop], item.formatData) === 'string'"
+          <el-tag
+            v-if="
+              typeof dataTypeFn(scope.row[item.prop], item.formatData) ===
+              'string'
+            "
             :title="formatters(scope.row[item.prop], item.formatData)"
-            :type="formatType(scope.row[item.prop], item.formatType)">
+            :type="formatType(scope.row[item.prop], item.formatType)"
+          >
             {{ formatters(scope.row[item.prop], item.formatData) }}
           </el-tag>
 
-          <el-tag v-for="(tag, index) in dataTypeFn(scope.row[item.prop], item.formatData)"
-            v-else-if="typeof dataTypeFn(scope.row[item.prop], item.formatData) === 'object'" :key="index"
-            :title="formatters(scope.row[item.prop], item.formatData)" :type="formatType(tag, item.formatType)">
+          <el-tag
+            v-for="(tag, index) in dataTypeFn(
+              scope.row[item.prop],
+              item.formatData
+            )"
+            v-else-if="
+              typeof dataTypeFn(scope.row[item.prop], item.formatData) ===
+              'object'
+            "
+            :key="index"
+            :title="formatters(scope.row[item.prop], item.formatData)"
+            :type="formatType(tag, item.formatType)"
+          >
             {{ item.tagGroup ? tag[item.tagGroup.label] ?? tag : tag }}
           </el-tag>
 
-          <el-tag v-else :title="formatters(scope.row[item.prop], item.formatData)"
-            :type="formatType(scope.row[item.prop], item.formatType)">
+          <el-tag
+            v-else
+            :title="formatters(scope.row[item.prop], item.formatData)"
+            :type="formatType(scope.row[item.prop], item.formatType)"
+          >
             {{ formatters(scope.row[item.prop], item.formatData) }}
           </el-tag>
         </div>
@@ -54,91 +120,146 @@
         <!-- 鎸夐挳 -->
         <div v-else-if="item.dataType == 'action'">
           <template v-for="(o, key) in item.operation" :key="key">
-            <el-button v-show="o.type != 'upload'" size="small" v-if="o.showHide ? o.showHide(scope.row) : true"
-              :disabled="o.disabled ? o.disabled(scope.row) : false" :plain="o.plain" type="primary"
-              :style="{ color: (o.name === '鍒犻櫎' || o.name === 'delete') ? '#f56c6c' : o.color }" link
-              @click="o.clickFun(scope.row)" :key="key">
+            <el-button
+              v-show="o.type != 'upload'"
+              size="small"
+              v-if="o.showHide ? o.showHide(scope.row) : true"
+              :disabled="o.disabled ? o.disabled(scope.row) : false"
+              :plain="o.plain"
+              type="primary"
+              :style="{
+                color:
+                  o.name === '鍒犻櫎' || o.name === 'delete'
+                    ? '#f56c6c'
+                    : o.color,
+              }"
+              link
+              @click="o.clickFun(scope.row)"
+              :key="key"
+            >
               {{ o.name }}
             </el-button>
-            <el-upload :action="javaApi + o.url + '?id=' + (o.uploadIdFun ? o.uploadIdFun(scope.row) : scope.row.id)"
-              ref="uploadRef" size="small" :multiple="o.multiple ? o.multiple : false" :limit="1"
+            <el-upload
+              :action="
+                javaApi +
+                o.url +
+                '?id=' +
+                (o.uploadIdFun ? o.uploadIdFun(scope.row) : scope.row.id)
+              "
+              ref="uploadRef"
+              size="small"
+              :multiple="o.multiple ? o.multiple : false"
+              :limit="1"
               :disabled="o.disabled ? o.disabled(scope.row) : false"
-              :accept="o.accept ? o.accept : '.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar'"
-              v-if="o.type == 'upload'" style="display: inline-block; width: 50px"
-              v-show="o.showHide ? o.showHide(scope.row) : true" :headers="uploadHeader"
+              :accept="
+                o.accept
+                  ? o.accept
+                  : '.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar'
+              "
+              v-if="o.type == 'upload'"
+              style="display: inline-block; width: 50px"
+              v-show="o.showHide ? o.showHide(scope.row) : true"
+              :headers="uploadHeader"
               :before-upload="(file) => beforeUpload(file, scope.$index)"
-              :on-change="(file, fileList) => handleChange(file, fileList, scope.$index)"
-              :on-error="(error, file, fileList) => onError(error, file, fileList, scope.$index)"
-              :on-success="(response, file, fileList) => handleSuccessUp(response, file, fileList, scope.$index)"
-              :on-exceed="onExceed" :show-file-list="false">
-              <el-button :size="o.size ? o.size : 'small'" link type="primary"
-                :disabled="o.disabled ? o.disabled(scope.row) : false">{{ o.name }}</el-button>
+              :on-change="
+                (file, fileList) => handleChange(file, fileList, scope.$index)
+              "
+              :on-error="
+                (error, file, fileList) =>
+                  onError(error, file, fileList, scope.$index)
+              "
+              :on-success="
+                (response, file, fileList) =>
+                  handleSuccessUp(response, file, fileList, scope.$index)
+              "
+              :on-exceed="onExceed"
+              :show-file-list="false"
+            >
+              <el-button
+                :size="o.size ? o.size : 'small'"
+                link
+                type="primary"
+                :disabled="o.disabled ? o.disabled(scope.row) : false"
+                >{{ o.name }}</el-button
+              >
             </el-upload>
           </template>
         </div>
         <!-- 鍙偣鍑荤殑鏂囧瓧 -->
-        <div v-else-if="item.dataType == 'link'" class="cell link" style="width: 100%"
-          @click="goLink(scope.row, item.linkMethod)">
+        <div
+          v-else-if="item.dataType == 'link'"
+          class="cell link"
+          style="width: 100%"
+          @click="goLink(scope.row, item.linkMethod)"
+        >
           <span v-if="!item.formatData">{{ scope.row[item.prop] }}</span>
         </div>
         <!-- 榛樿绾睍绀烘暟鎹� -->
         <div v-else class="cell" style="width: 100%">
           <span v-if="!item.formatData">{{ scope.row[item.prop] }}</span>
-          <span v-else>{{ formatters(scope.row[item.prop], item.formatData) }}</span>
+          <span v-else>{{
+            formatters(scope.row[item.prop], item.formatData)
+          }}</span>
         </div>
       </template>
     </el-table-column>
   </el-table>
-  <pagination v-show="total > 0" :total="total" :layout="page.layout" :page="page.current" :limit="page.size"
-    @pagination="paginationSearch" />
+  <pagination
+    v-show="total > 0"
+    :total="total"
+    :layout="page.layout"
+    :page="page.current"
+    :limit="page.size"
+    @pagination="paginationSearch"
+  />
 </template>
 
 <script setup>
-import pagination from './Pagination.vue'
-import { ref, inject, getCurrentInstance } from "vue"
-import { ElMessage } from "element-plus"
+import pagination from "./Pagination.vue";
+import { ref, inject, getCurrentInstance } from "vue";
+import { ElMessage } from "element-plus";
 
 // 鑾峰彇鍏ㄥ眬鐨� uploadHeader
-const { proxy } = getCurrentInstance()
-const uploadHeader = proxy.uploadHeader
-const javaApi = proxy.javaApi
+const { proxy } = getCurrentInstance();
+const uploadHeader = proxy.uploadHeader;
+const javaApi = proxy.javaApi;
 
 const emit = defineEmits(["pagination"]);
 
 // Filters
 const typeFn = (val, row) => {
-  return typeof val === 'function' ? val(row) : val
-}
+  return typeof val === "function" ? val(row) : val;
+};
 
 const formatters = (val, format) => {
-  return typeof format === 'function' ? format(val) : val
-}
+  return typeof format === "function" ? format(val) : val;
+};
 
 // Props锛堜娇鐢� defineProps 鐨勯潪 TS 褰㈠紡锛�
 const props = defineProps({
   tableLoading: {
     type: Boolean,
-    default: false
+    default: false,
   },
   handleSelectionChange: {
     type: Function,
-    default: () => { }
+    default: () => {},
   },
   summaryMethod: {
     type: Function,
-    default: () => { }
+    default: () => {},
   },
   rowClick: {
     type: Function,
-    default: () => { }
+    default: () => {},
   },
   currentChange: {
     type: Function,
-    default: () => { }
+    default: () => {},
   },
   border: {
     type: Boolean,
-    default: true
+    default: true,
   },
   isSelection: {
     type: Boolean,
@@ -150,31 +271,31 @@
   },
   highlightCurrentRow: {
     type: Boolean,
-    default: false
+    default: false,
   },
   headerCellStyle: {
     type: Object,
-    default: () => ({})
+    default: () => ({}),
   },
   column: {
     type: Array,
-    default: () => []
+    default: () => [],
   },
   rowClassName: {
     type: Function,
-    default: () => ''
+    default: () => "",
   },
   rowStyle: {
     type: [Object, Function],
-    default: () => ({})
+    default: () => ({}),
   },
   tableData: {
     type: Array,
-    default: () => []
+    default: () => [],
   },
   rowKey: {
     type: String,
-    default: undefined
+    default: undefined,
   },
   page: {
     type: Object,
@@ -182,108 +303,108 @@
       total: 0,
       current: 0,
       size: 10,
-      layout: 'total, sizes, prev, pager, next, jumper'
-    })
+      layout: "total, sizes, prev, pager, next, jumper",
+    }),
   },
   total: {
     type: Number,
-    default: 0
-  }
-})
+    default: 0,
+  },
+});
 
 // Data
-const uploadRefs = ref([])
-const currentFiles = ref({})
-const uploadKeys = ref({})
+const uploadRefs = ref([]);
+const currentFiles = ref({});
+const uploadKeys = ref({});
 
 const indexMethod = (index) => {
-  return (props.page.current - 1) * props.page.size + index + 1
-}
+  return (props.page.current - 1) * props.page.size + index + 1;
+};
 
 // 鐐瑰嚮 link 浜嬩欢
 const goLink = (row, linkMethod) => {
   if (!linkMethod) {
-    return ElMessage.warning("璇烽厤缃� link 浜嬩欢")
+    return ElMessage.warning("璇烽厤缃� link 浜嬩欢");
   }
-  const parentMethod = getParentMethod(linkMethod)
-  if (typeof parentMethod === 'function') {
-    parentMethod(row)
+  const parentMethod = getParentMethod(linkMethod);
+  if (typeof parentMethod === "function") {
+    parentMethod(row);
   } else {
-    console.warn(`鐖剁粍浠朵腑鏈壘鍒版柟娉�: ${linkMethod}`)
+    console.warn(`鐖剁粍浠朵腑鏈壘鍒版柟娉�: ${linkMethod}`);
   }
-}
+};
 
 // 鑾峰彇鐖剁粍浠舵柟娉曪紙绀轰緥瀹炵幇锛�
 const getParentMethod = (methodName) => {
-  const parentMethods = inject('parentMethods', {})
-  return parentMethods[methodName]
-}
+  const parentMethods = inject("parentMethods", {});
+  return parentMethods[methodName];
+};
 
 const dataTypeFn = (val, format) => {
   if (typeof format === "function") {
-    return format(val)
-  } else return val
-}
+    return format(val);
+  } else return val;
+};
 
 const formatType = (val, format) => {
   if (typeof format === "function") {
-    return format(val)
-  } else return ""
-}
+    return format(val);
+  } else return "";
+};
 
 // 鏂囦欢鍙樺寲澶勭悊
 const handleChange = (file, fileList, index) => {
   if (fileList.length > 1) {
-    const earliestFile = fileList[0]
-    uploadRefs.value[index]?.handleRemove(earliestFile)
+    const earliestFile = fileList[0];
+    uploadRefs.value[index]?.handleRemove(earliestFile);
   }
-  currentFiles.value[index] = file
-}
+  currentFiles.value[index] = file;
+};
 
 // 鏂囦欢涓婁紶鍓嶆牎楠�
 const beforeUpload = (rawFile, index) => {
-  currentFiles.value[index] = {}
+  currentFiles.value[index] = {};
   if (rawfile.size > 1024 * 1024 * 10 * 10) {
-    ElMessage.error('涓婁紶鏂囦欢涓嶈秴杩�10M')
-    return false
+    ElMessage.error("涓婁紶鏂囦欢涓嶈秴杩�10M");
+    return false;
   }
-  return true
-}
+  return true;
+};
 
 // 涓婁紶鎴愬姛
 const handleSuccessUp = (response, file, fileList, index) => {
   if (response.code == 200) {
     if (uploadRefs[index]) {
-      uploadRefs[index].clearFiles()
+      uploadRefs[index].clearFiles();
     }
-    currentFiles[index] = file
-    ElMessage.success("涓婁紶鎴愬姛")
-    resetUploadComponent(index)
+    currentFiles[index] = file;
+    ElMessage.success("涓婁紶鎴愬姛");
+    resetUploadComponent(index);
   } else {
-    ElMessage.error(response.message)
+    ElMessage.error(response.message);
   }
-}
+};
 
 const resetUploadComponent = (index) => {
-  uploadKeys[index] = Date.now()
-}
+  uploadKeys[index] = Date.now();
+};
 
 // 涓婁紶澶辫触
 const onError = (error, file, fileList, index) => {
-  ElMessage.error('鏂囦欢涓婁紶澶辫触锛岃閲嶈瘯')
+  ElMessage.error("鏂囦欢涓婁紶澶辫触锛岃閲嶈瘯");
   if (uploadRefs.value[index]) {
-    uploadRefs.value[index].clearFiles()
+    uploadRefs.value[index].clearFiles();
   }
-}
+};
 
 // 鏂囦欢鏁伴噺瓒呴檺鎻愮ず
 const onExceed = () => {
-  ElMessage.warning('瓒呭嚭鏂囦欢涓暟')
-}
+  ElMessage.warning("瓒呭嚭鏂囦欢涓暟");
+};
 
 const paginationSearch = ({ page, limit }) => {
   emit("pagination", { page: page, limit: limit });
-}
+};
 </script>
 
 <style scoped lang="scss">
@@ -294,4 +415,4 @@
   padding-right: 0 !important;
   padding-left: 0 !important;
 }
-</style>
\ No newline at end of file
+</style>

--
Gitblit v1.9.3