Răsfoiți Sursa

首页,table列设置修改

zhangqing 1 an în urmă
părinte
comite
7ae861bb4a

+ 23 - 0
src/api/home/index.js

@@ -0,0 +1,23 @@
+import request from '@/utils/request'
+
+// 查询订单统计
+export async function getOrderCount(params) {
+  const res = await request.get(`/aps/index/orderCount`, {
+    params
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 准时交付率&完成率
+export async function deliveryCompletionRate(params) {
+  const res = await request.get(`/aps/index/deliveryCompletionRate`, {
+    params
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 209 - 0
src/mixins/tableColumnsMixin.js

@@ -0,0 +1,209 @@
+import request from '@/utils/request';
+
+export default {
+  data() {
+    return {
+      newColumns: []
+    };
+  },
+  created() {
+    //从服务器获取缓存列表配置
+    this.getTabColumns();
+    // 创建防抖函数并绑定this
+    this.debouncedHandleColumnChange = this.debounce(
+      this.handleColumnChangeImpl,
+      1000
+    );
+  },
+  methods: {
+    // 实际的列变更处理逻辑
+    handleColumnChangeImpl() {
+      try {
+        const list = this.getStorage(this.cacheKeyUrl + 'Cols');
+        if (list) {
+          this.saveColumns(list);
+        }
+      } catch (error) {
+        console.error('处理列配置出错:', error);
+      }
+    },
+
+    // 列表变化回调
+    handleColumnChange() {
+      this.debouncedHandleColumnChange();
+    },
+
+    // 获取table-column配置
+    async getTabColumns() {
+      const res = await this.getByTableId(this.cacheKeyUrl);
+      if (res?.columnConfig?.length > 0) {
+        //对比接口返回和本地columns
+        let { nlist, type } = this.columnsContrast(res.columnConfig);
+        //有更新则更新服务缓存配置
+        if (type) {
+          this.saveColumns(nlist);
+        }
+        this.setStorage(this.cacheKeyUrl + 'Cols', nlist);
+        // 更新列
+        if (this._computedWatchers && this._computedWatchers.columns) {
+          // console.log('columns 是计算属性');
+          this.columnsVersion++;
+        } else {
+          // console.log('columns 是 data 属性');
+          this.columns = [...this.columns];
+          this.newColumns = [...this.newColumns];
+        }
+      }
+    },
+    //服务器和本地配置columns对比
+    columnsContrast(list) {
+      const key = 'label';
+      var updateType = 0;
+      let sList = list.filter((d, i, r) => {
+        return d[key];
+      });
+      let devColumns =
+        this.newColumns?.length > 0 ? this.newColumns : this.columns;
+      let dList = devColumns.filter((d, i, r) => {
+        return d[key] && d[key] !== '序号';
+      });
+      const keysA = new Set(sList.map((item) => item[key]));
+      const keysB = new Set(dList.map((item) => item[key]));
+      // 本地 比 缓存服务端 多的对象(新增)
+      const added = dList.filter((item) => {
+        return !keysA.has(item[key]) && (item.prop || item.label === '操作');
+      });
+      // 本地 比 缓存服务端 少的对象(删除)
+      const removed = sList.filter((item) => !keysB.has(item[key]));
+      const removedPropSet = new Set(removed.map((item) => item[key]));
+      // 删除 缓存中 中被移除的对象
+      const keptA = list.filter((item) => !removedPropSet.has(item[key]));
+      added.forEach((item) => {
+        //新增columns字段prop参数为必填
+        if (item.prop) {
+          item.id = item.prop;
+        } else if (item.columnKey) {
+          item.id = item.columnKey;
+        }
+        item.checked = true;
+      });
+
+      if (added.length > 0 || removed.length > 0) {
+        updateType = 1;
+      }
+
+      // 更新项:key 存在但内容变化
+      const dMap = new Map(dList.map((item) => [item[key], item]));
+      const updated = keptA.map((sItem) => {
+        const dItem = dMap.get(sItem[key]);
+        if (dItem && dItem.prop && sItem.prop !== dItem.prop) {
+          updateType = 1;
+          // 记录旧值和新值
+          const oldValue = sItem.prop;
+          const newValue = dItem.prop;
+          // 遍历所有属性,动态替换匹配旧值的字段
+          const updatedItem = { ...sItem };
+          Object.keys(updatedItem).forEach((k) => {
+            if (updatedItem[k] === oldValue) {
+              updatedItem[k] = newValue;
+            }
+          });
+          return updatedItem;
+        }
+        return sItem;
+      });
+
+      // 合并保留的对象和新增的对象
+      return { nlist: [...updated, ...added], type: updateType };
+    },
+
+    // 提交columns配置
+    async saveColumns(e) {
+      const data = {
+        tableId: this.cacheKeyUrl,
+        columnConfig: e
+      };
+      const msg = await this.saveTableConfig(data);
+      // console.log('列配置保存成功:', msg);
+      return msg;
+    },
+
+    //获取localstorage缓存
+    setStorage(key, value) {
+      try {
+        localStorage.setItem(key, JSON.stringify(value));
+      } catch (e) {
+        console.log('LocalStorage 存储错误:', e);
+        if (e.name === 'QuotaExceededError') {
+          this.clearCacheByPrefix(); //缓存不足,清除
+          localStorage.setItem(key, JSON.stringify(value));
+        }
+      }
+    },
+
+    //缓存不足清除缓存
+    clearCacheByPrefix() {
+      const prefix = 'Cols'; // 标识后缀
+      Object.keys(localStorage).forEach((key) => {
+        if (key.endsWith(prefix)) {
+          localStorage.removeItem(key);
+          // console.log(`已清除缓存: ${key}`);
+        }
+      });
+      // console.log('缓存清除完成');
+    },
+
+    //设置localstorage缓存
+    getStorage(key) {
+      try {
+        const value = localStorage.getItem(key);
+        return value ? JSON.parse(value) : null;
+      } catch (e) {
+        console.error('LocalStorage 解析错误:', e);
+        return null;
+      }
+    },
+
+    //防抖函数
+    debounce(fn, delay) {
+      let timer = null;
+      return (...args) => {
+        clearTimeout(timer);
+        timer = setTimeout(() => {
+          fn.apply(this, args);
+        }, delay);
+      };
+    },
+
+    //获取column记录接口
+    async getByTableId(key) {
+      try {
+        const res = await request.get(
+          `/sys/table-config/getByTableId/${key}`,
+          {}
+        );
+        if (res.data.code == 0) {
+          return res.data.data;
+        }
+      } catch (error) {
+        console.error('获取列配置失败:', error);
+      }
+    },
+
+    // 添加column记录接口
+    async saveTableConfig(data) {
+      try {
+        const res = await request({
+          url: '/sys/table-config/save',
+          method: 'post',
+          data
+        });
+        if (res.data.code == 0) {
+          return res.data.data;
+        }
+      } catch (error) {
+        console.error('保存列配置失败:', error);
+      }
+    }
+  }
+};

+ 6 - 0
src/views/aps/capacity/index.vue

@@ -352,12 +352,18 @@ export default {
         if (valid) {
           if (this.form.id != null) {
             updateCapacity(this.form).then(response => {
+              if (response.data.code == -1) {
+                return;
+              } 
               this.$message.success("修改成功");
               this.open = false;
               this.getList();
             });
           } else {
             addCapacity(this.form).then(response => {
+              if (response.data.code == -1) {
+                return;
+              } 
               this.$message.success("新增成功");
               this.open = false;
               this.getList();

+ 9 - 3
src/views/hangingWorkOrder/index.vue

@@ -6,7 +6,8 @@
         ref="table"
         :columns="columns"
         :datasource="datasource"
-        cache-key="workOrderTable"
+        :cache-key="cacheKeyUrl"
+        @columns-change="handleColumnChange"
       >
         <template v-slot:Weight="{ row }">
           <span>{{ row.weight | weightFilter }}</span>
@@ -44,11 +45,13 @@ import {
   getPutMeshWorkOrderByPage,
   issuedPutMeshWorkOrder
 } from '@/api/mergePutMesh/mergePutMesh';
+import tabMixins from '@/mixins/tableColumnsMixin';
+
 export default {
   components: {
     OrderSearch
   },
-  mixins: [dictMixins],
+  mixins: [dictMixins, tabMixins],
   data() {
     return {
       visible: false,
@@ -58,12 +61,15 @@ export default {
         id: ''
       },
 
-      current: null
+      current: null,
+      cacheKeyUrl: '79025f25-aps-hangingWorkOrder',
+      columnsVersion:1
     };
   },
   computed: {
     // 表格列配置
     columns() {
+      const num = this.columnsVersion;
       return [
         {
           columnKey: 'index',

+ 64 - 12
src/views/home/index.vue

@@ -23,8 +23,8 @@
         <div class="item">
           <div class="header"> 7日内需要交付订单 </div>
           <div class="content">
-            <p><span>订单数</span><span>3/10</span></p>
-            <p><span>产品量</span><span>558/1860</span></p>
+            <p><span>订单数</span><span>{{ orderCount7.formedOrders + '/' + orderCount7.orders }}</span></p>
+            <p><span>产品量</span><span>{{ orderCount7.formedNum + '/' + orderCount7.productNum }}</span></p>
           </div>
         </div>
       </el-col>
@@ -32,8 +32,8 @@
         <div class="item">
           <div class="header"> 本月需要完成订单 </div>
           <div class="content">
-            <p><span>订单数</span><span>3/10</span></p>
-            <p><span>产品量</span><span>558/1860</span></p>
+            <p><span>订单数</span><span>{{ orderCount30.formedOrders + '/' + orderCount30.orders }}</span></p>
+            <p><span>产品量</span><span>{{ orderCount30.formedNum + '/' + orderCount30.productNum }}</span></p>
           </div>
         </div>
       </el-col>
@@ -69,6 +69,9 @@
 
           <ele-pro-table ref="table" height="calc(100%)" :columns="columns" :datasource="datasource"
             :needPage="false" :toolbar="false">
+            <template v-slot="">
+
+            </template>
           </ele-pro-table>
 
 
@@ -96,6 +99,7 @@ import {
 import { getList } from '@/api/workOrder/index'
 import VChart from 'vue-echarts';
 import { echartsMixin } from '@/utils/echarts-mixin';
+import { getOrderCount, deliveryCompletionRate } from '@/api/home/index'
 // 按需加载 echarts
 use([
   CanvasRenderer,
@@ -148,11 +152,25 @@ export default {
       form: {
         finishTime: '',
         timeType: '1'
-      }
+      },
+      orderCount7: {}, // 7天内订单情况
+      orderCount30: {}, // 30天内订单情况
+      orderCountYear: [], // 年度订单情况
+      date: [], //日期
+      productNum: [], //任务量
+      completeNum: [], //完成量
+      completionRate: [],//达成率
+      deliveryRate: [],//交付率
+      orders: [],//应完成订单
+      formedOrders: [],//已完成订单数
     };
   },
 
-  created() { },
+  created() { 
+    this.getOrderCount(0);
+    this.getOrderCount(7);
+    this.getYearRate();
+  },
   mounted() {
     this.pieOption = pieOption([
       { value: 60, name: '人员异常' },
@@ -182,7 +200,7 @@ export default {
         {
           name: '任务量',
           barWidth: '25%',
-          data: [50, 78, 88, 76, 75, 91, 50, 78, 88, 76, 75, 91],
+          data: this.productNum,
           type: 'bar',
           yAxisIndex: 0, // 使用第一个Y轴
           itemStyle: {
@@ -192,7 +210,7 @@ export default {
         {
           name: '完成量',
           barWidth: '25%',
-          data: [50, 78, 88, 76, 75, 91, 50, 78, 88, 76, 75, 91],
+          data: this.completeNum,
           type: 'bar',
           yAxisIndex: 0, // 使用第一个Y轴
           itemStyle: {
@@ -202,7 +220,7 @@ export default {
         {
           name: '达成率',
           symbolSize: 10,
-          data: [50, 78, 88, 76, 75, 91, 50, 78, 88, 76, 75, 91],
+          data: this.completionRate,
           type: 'line',
           smooth: true,
           yAxisIndex: 1, // 使用第一个Y轴
@@ -231,21 +249,21 @@ export default {
         {
           name: '应完成订单',
           barWidth: '25%',
-          data: [50, 78, 88, 76, 75, 91, 78, 87, 81, 67, 95, 73],
+          data: this.orders,
           type: 'bar',
           yAxisIndex: 0 // 使用第一个Y轴
         },
         {
           name: '实际完成订单',
           barWidth: '25%',
-          data: [50, 78, 88, 76, 75, 91, 78, 87, 81, 67, 95, 73],
+          data: this.formedOrders,
           type: 'bar',
           yAxisIndex: 0 // 使用第一个Y轴
         },
         {
           name: '准时交付率',
           symbolSize: 10,
-          data: [50, 78, 88, 76, 75, 91, 78, 87, 81, 67, 95, 73],
+          data: this.deliveryRate,
           type: 'line',
           smooth: true,
           yAxisIndex: 1, // 使用第一个Y轴
@@ -274,6 +292,40 @@ export default {
         pageNum: page,
         size: limit
       });
+    },
+
+    //获取订单统计
+    async getOrderCount(days) {
+      let params = {
+        days: days,
+        factoriesId: 0
+      };
+      let rest = await getOrderCount(params);
+      if (days === 7) {
+        this.orderCount7 = rest;
+      } else if (days === 0) {
+        this.orderCount30 = rest;
+      } 
+    },
+
+    //年度准时交付率&完成率
+    async getYearRate() {
+      let params = {
+        startDate: new Date().getFullYear() + '-01-01',
+        endDate: new Date().getFullYear() + '-12-31',
+        factoriesId: 0
+      }
+      let rest = await deliveryCompletionRate(params);
+      console.log(rest)
+      for (let i = 0; i < rest.length; i++) {
+        this.date.push(rest[i].deliveryRateDate);
+        this.productNum.push(rest[i].productNum);
+        this.completeNum.push(rest[i].formedNum);
+        this.completionRate.push(rest[i].completionRate);
+        this.deliveryRate.push(rest[i].deliveryRate);
+        this.orders.push(rest[i].orders);
+        this.formedOrders.push(rest[i].formedOrders);
+      }
     }
   }
 };

+ 4 - 2
src/views/productionPlan/factoryPlan.vue

@@ -1,6 +1,6 @@
 <template>
   <div>
-    <homeIndex :timeDimensionPlanType="3" ></homeIndex>
+    <homeIndex :timeDimensionPlanType="3" :cacheKeyUrl="cacheKeyUrl"></homeIndex>
   </div>
 </template>
 
@@ -10,7 +10,9 @@
     components: { homeIndex },
     name: 'factoryPlan',
     data() {
-      return {};
+      return {
+        cacheKeyUrl: '9409b6c7-aps-factoryPlan'
+      };
     }
   };
 </script>

+ 54 - 47
src/views/productionPlan/index.vue

@@ -118,11 +118,12 @@
         :datasource="datasource"
         row-key="code"
         :selection.sync="selection"
-        :cache-key="`${activeName}ProductionPlanTable`"
+        :cache-key="cacheKeyUrl"
         @sort-change="onSortChange"
         autoAmendPage
         :parse-data="parseData"
         @update:selection="handleSelectionChange"
+        @columns-change="handleColumnChange"
       >
         <template v-slot:batchNo="{ row }">
           <el-link type="primary" :underline="false">
@@ -317,7 +318,10 @@
   import { getCode } from '@/api/codeManagement';
   import { fieldModel } from '@/api/saleOrder';
   import { debounce } from 'lodash';
+  import tabMixins from '@/mixins/tableColumnsMixin';
+
   export default {
+    mixins: [tabMixins],
     components: {
       productionPlanSearch,
       unpackDialog,
@@ -329,7 +333,8 @@
       homogeneityInspectInstallDialog
     },
     props: {
-      timeDimensionPlanType: { type: Number, default: 1 }
+      timeDimensionPlanType: { type: Number, default: 1 },
+      cacheKeyUrl: { type: String, default: '513b2388-aps-productionPlan' }
     },
     data() {
       return {
@@ -381,7 +386,8 @@
         // factoryShow: false,
         factoryType: 3,
         factoryObj: {},
-        cardSpan: 3
+        cardSpan: 3,
+        columnsVersion:1
       };
     },
     computed: {
@@ -390,6 +396,7 @@
       },
       // 表格列配置
       columns() {
+        const num = this.columnsVersion
         const opt = {
           first: [],
           second: [
@@ -565,33 +572,33 @@
             minWidth: 100
           },
 
-          {
-            prop: '',
-            label: '已排产数量',
-            align: 'center',
-            showOverflowTooltip: true
-          },
-
-          {
-            prop: '',
-            label: '未排产数量',
-            align: 'center',
-            showOverflowTooltip: true
-          },
-
-          {
-            prop: '',
-            label: '已生产数量',
-            align: 'center',
-            showOverflowTooltip: true
-          },
-
-          {
-            prop: '',
-            label: '未生产数量',
-            align: 'center',
-            showOverflowTooltip: true
-          },
+          // {
+          //   prop: '',
+          //   label: '已排产数量',
+          //   align: 'center',
+          //   showOverflowTooltip: true
+          // },
+
+          // {
+          //   prop: '',
+          //   label: '未排产数量',
+          //   align: 'center',
+          //   showOverflowTooltip: true
+          // },
+
+          // {
+          //   prop: '',
+          //   label: '已生产数量',
+          //   align: 'center',
+          //   showOverflowTooltip: true
+          // },
+
+          // {
+          //   prop: '',
+          //   label: '未生产数量',
+          //   align: 'center',
+          //   showOverflowTooltip: true
+          // },
 
           {
             prop: 'factoriesName',
@@ -599,23 +606,23 @@
             align: 'center'
           },
 
-          {
-            prop: '',
-            label: '合格品数',
-            align: 'center'
-          },
-
-          {
-            prop: '',
-            label: '不合格品数',
-            align: 'center'
-          },
-
-          {
-            prop: '',
-            label: '合格率',
-            align: 'center'
-          },
+          // {
+          //   prop: '',
+          //   label: '合格品数',
+          //   align: 'center'
+          // },
+
+          // {
+          //   prop: '',
+          //   label: '不合格品数',
+          //   align: 'center'
+          // },
+
+          // {
+          //   prop: '',
+          //   label: '合格率',
+          //   align: 'center'
+          // },
 
           {
             prop: 'moCount',

+ 4 - 2
src/views/productionPlan/temporaryPlan.vue

@@ -1,6 +1,6 @@
 <template>
   <div>
-    <homeIndex :timeDimensionPlanType="2"></homeIndex>
+    <homeIndex :timeDimensionPlanType="2" :cacheKeyUrl="cacheKeyUrl"></homeIndex>
   </div>
 </template>
 
@@ -10,7 +10,9 @@
     components: { homeIndex },
     name: 'factoryPlan',
     data() {
-      return {};
+      return {
+        cacheKeyUrl: 'c9395382-aps-temporaryPlan'
+      };
     }
   };
 </script>

+ 9 - 2
src/views/saleOrder/index.vue

@@ -28,6 +28,8 @@
         height="calc(100vh - 335px)"
         row-key="id"
         @sort-change="onSortChange"
+        @columns-change="handleColumnChange"
+        :cache-key="cacheKeyUrl"
       >
         <template v-slot:code="{ row }">
           <el-link :underline="false" type="primary" @click="openDetails(row)">
@@ -125,9 +127,11 @@
   import dictMixins from '@/mixins/dictMixins';
   import { debounce } from 'lodash';
   import { Alert } from 'element-ui';
+  import tabMixins from '@/mixins/tableColumnsMixin';
+
   export default {
     name: 'saleOrder',
-    mixins: [dictMixins],
+    mixins: [dictMixins,tabMixins],
     components: {
       OrderSearch,
       OrderDetail,
@@ -143,7 +147,9 @@
         activeName: 'first',
         selection: [],
 
-        newColumns: []
+        newColumns: [],
+        cacheKeyUrl: 'c32a9c7d-aps-saleOrder',
+        columnsVersion: 1
       };
     },
 
@@ -153,6 +159,7 @@
         return this.$store.state.user.info.clientEnvironmentId;
       },
       columns() {
+        const version = this.columnsVersion;
         return [
           {
             width: 45,

+ 9 - 2
src/views/workOrder/index.vue

@@ -23,7 +23,8 @@
         :parse-data="parseData"
       > -->
       <ele-pro-table ref="table" :columns="newColumns" :datasource="datasource" cache-key="workOrderTable" row-key="id"
-        @sort-change="onSortChange" autoAmendPage :parse-data="parseData">
+        @sort-change="onSortChange" autoAmendPage :parse-data="parseData" :cache-key="cacheKeyUrl" @columns-change="handleColumnChange"
+        >
         <!-- :key="activeName" -->
         <!-- :selection.sync="selection" -->
         <!-- @update:selection="handleSelectionChange" -->
@@ -151,7 +152,10 @@ import { fieldModel } from '@/api/saleOrder';
 
 import { debounce } from 'lodash';
 import PlanStatistics from "@/components/statistics/PlanStatistics.vue";
+import tabMixins from '@/mixins/tableColumnsMixin';
+
 export default {
+  mixins: [tabMixins],
   components: {
     PlanStatistics,
     OrderSearch,
@@ -208,7 +212,9 @@ export default {
       teamsList: [],
       crewList: [],
 
-      current: null
+      current: null,
+      cacheKeyUrl: '3cbbdff9-aps-workOrder',
+      columnsVersion:1
     };
   },
   computed: {
@@ -220,6 +226,7 @@ export default {
     },
     // 表格列配置
     columns() {
+      const num = this.columnsVersion
       return [
         {
           columnKey: 'index',