Browse Source

Merge branch 'ecp' of http://git.echepei.com/gubersail/gubersail-platform-ui into ecp

Qukatie 1 month ago
parent
commit
afe1868d40

+ 84 - 47
src/components/forecast-form/forecast-form-mixin.js

@@ -370,7 +370,7 @@ export default {
             if (this.initialFormData) {
               this.formData = this.cleanAndFormatFormData(this.initialFormData)
             } else {
-              // 使用 initFormData,确保新增模式默认填入“下个月”而不是当前月
+              // 使用 initFormData,确保新增模式默认填入"下个月"而不是当前月
               this.initFormData()
             }
 
@@ -542,6 +542,68 @@ export default {
    */
   methods: {
     /**
+     * 创建物料匹配器函数
+     * @description 提取通用的物料匹配逻辑,避免代码重复
+     * @param {Object} material - 要匹配的物料对象
+     * @returns {Function} 匹配器函数
+     * @private
+     */
+    createMaterialMatcher(/** @type {Object} */ material) {
+      const id = material?.id
+      const goodsId = material?.goodsId
+      const code = material?.code
+
+      return (/** @type {Object} */ target) => {
+        if (id != null && target?.id != null && String(id) === String(target.id)) return true
+        if (goodsId != null && target?.goodsId != null && String(goodsId) === String(target.goodsId)) return true
+        if (code && target?.code && String(code) === String(target.code)) return true
+        return false
+      }
+    },
+
+    /**
+     * 优化的物料过滤算法
+     * @description 使用Map提高查找性能,避免循环嵌套
+     * @param {Array} stockTableData - 表格中的物料数据
+     * @param {Array} stockDescList - 可选的物料数据源
+     * @returns {Array} 过滤后的可选物料列表
+     * @private
+     */
+    optimizeStockSelectOptions(/** @type {Array} */ stockTableData, /** @type {Array} */ stockDescList) {
+      try {
+        const table = Array.isArray(stockTableData) ? stockTableData : []
+        const source = Array.isArray(stockDescList) ? stockDescList : []
+
+        // 使用Map构建已存在物料的快速查找索引
+        const materialMap = new Map()
+        table.forEach(item => {
+          if (item?.id != null) {
+            materialMap.set(`id:${String(item.id)}`, true)
+          }
+          if (item?.goodsId != null) {
+            materialMap.set(`goods:${String(item.goodsId)}`, true)
+          }
+          if (item?.code) {
+            materialMap.set(`code:${String(item.code)}`, true)
+          }
+        })
+
+        // 过滤掉已在表格中的物料
+        return source.filter(item => {
+          if (item?.id != null && materialMap.has(`id:${String(item.id)}`)) return false
+          if (item?.goodsId != null && materialMap.has(`goods:${String(item.goodsId)}`)) return false
+          if (item?.code && materialMap.has(`code:${String(item.code)}`)) return false
+          return true
+        }).map(item => ({
+          label: item?.cname || item?.code || '',
+          value: String(item?.id || '')
+        }))
+      } catch (e) {
+        console.warn('优化物料过滤算法失败:', e)
+        return []
+      }
+    },
+    /**
      * 创建初始表单数据
      * @description 创建销售预测表单的初始数据结构
      * @returns {ForecastFormModel} 初始化的表单数据对象
@@ -1023,7 +1085,6 @@ export default {
         // 先结束 Avue 内置的按钮loading,避免未调用 done 导致一直loading
         if (typeof done === 'function') done()
 
-            console.log(this.formData)
         // 采用旧实现风格:通过 this.$refs.forecastForm.validate 回调进行校验
         if (this.$refs && this.$refs.forecastForm && typeof this.$refs.forecastForm.validate === 'function') {
           this.$refs.forecastForm.validate((valid) => {
@@ -1037,9 +1098,7 @@ export default {
                   console.groupEnd && console.groupEnd()
                 }
               }
-              // 校验失败时,如存在 loading 回调(部分版本提供),尝试恢复按钮状态
               if (typeof loading === 'function') loading()
-              // 通知父组件校验失败,便于父侧重置保存按钮loading
               this.$emit && this.$emit(FORECAST_FORM_EVENTS.SUBMIT_ERROR, { message: '表单校验未通过' })
               return
             }
@@ -1233,15 +1292,18 @@ export default {
         this.selectedStockId = null
         // 重置选择状态
         this.selectedRowKeys = []
+
         const res = await getUserLinkGoods()
         const payload = res && res.data && res.data.data ? res.data.data : null
         const brandList = (payload && payload.pjpfBrandDescList) || []
         const stockList = (payload && payload.pjpfStockDescList) || []
+
         this.brandDescList = brandList
         // 存储库存列表供选择用,不直接展示到表格
         this.stockDescList = stockList
         // 默认显示全部物料至下方表格,预测数量默认 1,用户可手动删除不需要的物料
         this.stockTableData = stockList.map(item => ({ ...item, forecastQuantity: 1 }))
+
         // 根据表格中已有的物料,过滤下拉选项
         this.updateStockSelectOptions()
         // 规范化分页并回显选择(新增模式首次加载)
@@ -1256,7 +1318,7 @@ export default {
 
     /**
      * 导入所选物料到下方表格
-     * @description 仅在点击"导入物料"按钮后,将选择的物料行添加到表格,默认预测数量为 0
+     * @description 仅在点击"导入物料"按钮后,将选择的物料行添加到表格,默认预测数量为 1
      * @returns {void}
      * @this {ForecastFormMixinComponent & Vue}
      */
@@ -1273,24 +1335,10 @@ export default {
         return
       }
 
-      // 防止重复导入 - 使用多个字段进行更全面的重复检查
-      const exists = this.stockTableData.some(row => {
-        // 优先使用 id 进行匹配
-        if (row.id !== undefined && row.id !== null && stock.id !== undefined && stock.id !== null && String(row.id) === String(stock.id)) {
-          return true
-        }
-        // 使用 goodsId 进行匹配
-        if (row.goodsId !== undefined && row.goodsId !== null && stock.goodsId !== undefined && stock.goodsId !== null && String(row.goodsId) === String(stock.goodsId)) {
-          return true
-        }
-        // 使用 code 进行匹配
-        if (row.code && stock.code && String(row.code) === String(stock.code)) {
-          return true
-        }
-        return false
-      })
+      // 使用通用匹配器检查是否重复导入
+      const isDuplicate = this.stockTableData.some(this.createMaterialMatcher(stock))
 
-      if (exists) {
+      if (isDuplicate) {
         this.$message.warning('该物料已在列表中')
         this.selectedStockId = null
         return
@@ -1425,30 +1473,15 @@ export default {
 
     /**
      * 更新物料下拉选项(过滤已在表格中的物料)
+     * @description 使用优化的过滤算法,提高性能和可维护性
      * @returns {void}
      */
     updateStockSelectOptions() {
       try {
-        const table = Array.isArray(this.stockTableData) ? this.stockTableData : []
-        const source = Array.isArray(this.stockDescList) ? this.stockDescList : []
-
-        const idSet = new Set(table.filter(r => r && r.id !== undefined && r.id !== null).map(r => String(r.id)))
-        const goodsIdSet = new Set(table.filter(r => r && r.goodsId !== undefined && r.goodsId !== null).map(r => String(r.goodsId)))
-        const codeSet = new Set(table.filter(r => r && r.code).map(r => String(r.code)))
-
-        const options = source
-          .filter(item => {
-            const byId = item && item.id !== undefined && item.id !== null && idSet.has(String(item.id))
-            const byGoods = item && item.goodsId !== undefined && item.goodsId !== null && goodsIdSet.has(String(item.goodsId))
-            const byCode = item && item.code && codeSet.has(String(item.code))
-            return !(byId || byGoods || byCode)
-          })
-          .map(item => ({
-            label: /** @type {any} */ (item.cname || item.code || ''),
-            value: /** @type {any} */ (String(item.id))
-          }))
-
+        // 使用优化的过滤算法
+        const options = this.optimizeStockSelectOptions(this.stockTableData, this.stockDescList)
         this.stockSelectOptions = options
+
         // 如果当前选中不在可选项中,则清空
         const hasSelected = options.some(opt => opt && opt.value === this.selectedStockId)
         if (!hasSelected) {
@@ -1599,19 +1632,23 @@ export default {
      */
     async mergeEchoStoreInventory() {
       try {
-        if (!Array.isArray(this.stockTableData) || this.stockTableData.length === 0) return
+        if (!Array.isArray(this.stockTableData) || this.stockTableData.length === 0) {
+          return
+        }
+
         const res = await getUserLinkGoods()
         const payload = res && res.data && res.data.data ? res.data.data : null
         const stockList = (payload && payload.pjpfStockDescList) || []
-        if (!Array.isArray(stockList) || stockList.length === 0) return
+        if (!Array.isArray(stockList) || stockList.length === 0) {
+          return
+        }
 
         // 在编辑模式下,确保"导入物料"的选择器有数据可选
         // 不修改现有表格数据,仅补齐选择来源
         this.stockDescList = stockList
-        this.stockSelectOptions = stockList.map(item => ({
-          label: item.cname,
-          value: item.id
-        }))
+
+        // ✅ 修复:使用优化的过滤方法,正确过滤已在表格中的物料
+        this.updateStockSelectOptions()
 
         // 构建基于 goodsId 与 code 的索引映射
         /** @type {Map<string, string|undefined>} */

+ 2 - 0
src/components/order-form/material-detail-mixin.js

@@ -583,6 +583,8 @@ export default {
      */
     prepareMaterialDetailData(material) {
       return {
+        // 保证每条导入的明细都有唯一id,满足表格校验与行标识需求
+        id: String(material.id || this.generateUniqueId()),
         itemId: material.itemId,
         itemCode: material.itemCode,
         itemName: material.itemName,

+ 9 - 6
src/components/order-form/order-form-mixin.js

@@ -991,12 +991,13 @@ export default {
          */
         this.$emit(ORDER_FORM_EVENTS.SAVE_SUCCESS, response.data.data)
 
-        // 保持在当前页:编辑模式不返回列表,仅在新增模式返回列表
-        if (!this.isEdit) {
-          // 新增模式:保存成功后返回列表
-          this.handleBack()
-        } else {
-          // 编辑模式:留在当前页,方便继续编辑
+        // 保持在当前页:新增与编辑模式均不主动返回列表
+        // 编辑模式:保存成功后刷新订单详情,已保存的物料置为不可删除
+        if (this.isEdit) {
+          const savedId = (response && response.data && response.data.data && response.data.data.id) || this.orderId || (this.formData && this.formData.id)
+          if (savedId) {
+            await this.loadOrderDetail(String(savedId))
+          }
         }
 
       } catch (error) {
@@ -1054,6 +1055,8 @@ export default {
           if (orderId) {
             await this.loadOrderDetail(orderId)
           }
+          // 提交动作完成后返回订单列表页
+          this.handleBack()
         } else {
           this.$message.error((response && response.data && response.data.msg) || '提交失败')
         }

+ 14 - 0
src/components/order-form/order-form.vue

@@ -212,6 +212,20 @@ export default {
       immediate: true
     },
 
+    // 监听编辑模式切换:当从新增切到编辑且已拿到ID时,主动加载详情
+    isEdit: {
+      handler(newVal, oldVal) {
+        if (newVal && !oldVal) {
+          this.$nextTick(() => {
+            const id = this.orderId || (this.formData && this.formData.id)
+            if (id) {
+              this.loadOrderDetail(String(id))
+            }
+          })
+        }
+      }
+    },
+
     /**
      * 监听表单数据变化,用于地址回显
      * @description 当表单数据中的客户编码和地址相关字段都有值时,触发地址选择组件的回显

+ 1 - 0
src/mixins/survey/surveyCrudMixin.js

@@ -29,6 +29,7 @@ export default {
         calcHeight: 80,
         tip: false,
         searchShow: true,
+        searchIcon: true,
         searchMenuSpan: 12,
         searchIndex: 3,
         border: true,

+ 1 - 1
src/router/views/index.js

@@ -381,7 +381,7 @@ export default [
                 },
                 component: () =>
                     import(
-                        /* webpackChunkName: "views" */ "@/views/forecast-summary/index"
+                        /* webpackChunkName: "views" */ "@/views/forecast-summary/index.vue"
                     )
             }
         ]

+ 1 - 1
src/views/announcement/mixins/announcementIndex.js

@@ -185,7 +185,7 @@ export default {
                 viewBtn: false,
                 selection: true,
                 excelBtn: false,
-                columnBtn: false,
+                columnBtn: true,
                 delBtn: false,
                 dialogClickModal: false,
                 column: [

+ 1 - 0
src/views/claim/claimMixin.js

@@ -180,6 +180,7 @@ export default {
         calcHeight: 30,
         tip: false,
         searchShow: true,
+        searchIcon: true,
         searchMenuSpan: 12,
         searchIndex: 3,
         border: true,

+ 1 - 0
src/views/complaint/complaintMixin.js

@@ -177,6 +177,7 @@ export default {
         calcHeight: 30,
         tip: false,
         searchShow: true,
+        searchIcon: true,
         searchMenuSpan: 18,
         searchIndex: 3,
         border: true,

+ 1 - 0
src/views/forecast-audit/auditIndex.js

@@ -63,6 +63,7 @@ export default {
         height: 'auto',
         calcHeight: 30,
         searchShow: true,
+        searchIcon: true,
         searchMenuSpan: 18,
         searchIndex: 3,
         border: true,

+ 5 - 0
src/views/forecast-audit/index.scss

@@ -346,4 +346,9 @@
       line-height: 1.5;
     }
   }
+}
+
+// 修复 el-col-md-8 宽度问题
+::v-deep .el-col-md-8 {
+  width: 24.33333% !important;
 }

+ 4 - 0
src/views/forecast-audit/index.vue

@@ -276,6 +276,10 @@ export default {
 </script>
 
 <style scoped>
+
+::v-deep .el-col-md-8 {
+  width: 24.33333% !important;
+}
 .order-expand-content {
   padding: 8px 0 16px 0;
 }

+ 0 - 226
src/views/forecast-summary/index.scss

@@ -2,229 +2,3 @@
  * 经销商销售预测汇总页面样式
  * @description 定义预测汇总页面的样式规则
  */
-
-.forecast-summary {
-  .el-tag {
-    &.el-tag--success {
-      background-color: #f0f9ff;
-      border-color: #67c23a;
-      color: #67c23a;
-    }
-
-    &.el-tag--warning {
-      background-color: #fdf6ec;
-      border-color: #e6a23c;
-      color: #e6a23c;
-    }
-
-    &.el-tag--danger {
-      background-color: #fef0f0;
-      border-color: #f56c6c;
-      color: #f56c6c;
-    }
-
-    &.el-tag--info {
-      background-color: #f4f4f5;
-      border-color: #909399;
-      color: #909399;
-    }
-  }
-
-  // 表格行样式
-  .avue-crud {
-    .el-table {
-      .el-table__row {
-        &:hover {
-          background-color: #f5f7fa;
-        }
-      }
-
-      // 表头样式
-      .el-table__header-wrapper {
-        .el-table__header {
-          th {
-            background-color: #fafafa;
-            color: #606266;
-            font-weight: 500;
-          }
-        }
-      }
-
-      // 单元格样式
-      .el-table__body-wrapper {
-        .el-table__body {
-          td {
-            padding: 8px 0;
-
-            .cell {
-              padding: 0 10px;
-              line-height: 1.5;
-            }
-          }
-        }
-      }
-    }
-
-    // 分页样式
-    .el-pagination {
-      margin-top: 20px;
-      text-align: right;
-
-      .el-pagination__total {
-        color: #606266;
-        font-weight: normal;
-      }
-
-      .el-pager {
-        .number {
-          &.active {
-            background-color: #409eff;
-            color: #fff;
-          }
-        }
-      }
-    }
-
-    // 搜索区域样式
-    .avue-crud__search {
-      background-color: #f8f9fa;
-      border: 1px solid #e9ecef;
-      border-radius: 4px;
-      padding: 15px;
-      margin-bottom: 15px;
-
-      .el-form-item {
-        margin-bottom: 10px;
-
-        .el-form-item__label {
-          color: #606266;
-          font-weight: 500;
-        }
-
-        .el-input,
-        .el-select {
-          width: 100%;
-        }
-      }
-
-      .avue-crud__search-btn {
-        text-align: right;
-        margin-top: 10px;
-
-        .el-button {
-          margin-left: 10px;
-        }
-      }
-    }
-  }
-
-  // 数字右对齐
-  .text-right {
-    text-align: right;
-  }
-
-  // 文本省略
-  .text-ellipsis {
-    overflow: hidden;
-    text-overflow: ellipsis;
-    white-space: nowrap;
-  }
-
-  // 状态标签样式增强
-  .status-tag {
-    font-weight: 500;
-    border-radius: 12px;
-    padding: 2px 8px;
-    font-size: 12px;
-  }
-
-  // 响应式设计
-  @media (max-width: 768px) {
-    .avue-crud {
-      .avue-crud__search {
-        .el-form-item {
-          .el-form-item__label {
-            width: 100% !important;
-            text-align: left !important;
-          }
-
-          .el-form-item__content {
-            margin-left: 0 !important;
-          }
-        }
-      }
-    }
-  }
-}
-
-// 全局样式覆盖
-.el-table {
-  .forecast-quantity-cell {
-    font-family: 'Courier New', monospace;
-    font-weight: 500;
-    color: #409eff;
-  }
-
-  .approval-status-cell {
-    .el-tag {
-      font-weight: 500;
-    }
-  }
-
-  .datetime-cell {
-    color: #909399;
-    font-size: 13px;
-  }
-}
-
-  // 行展开区样式(复用订单页样式类名,便于统一风格)
-  .order-expand-content {
-    padding: 16px 24px;
-    background-color: #fafafa;
-    border-left: 3px solid #409eff;
-  }
-
-  .expand-header {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    margin-bottom: 16px;
-    padding-bottom: 8px;
-    border-bottom: 1px solid #e4e7ed;
-
-    h4 {
-      margin: 0;
-      color: #303133;
-      font-size: 16px;
-      font-weight: 600;
-    }
-  }
-
-  .order-code {
-    color: #606266;
-    font-size: 14px;
-    background-color: #f0f2f5;
-    padding: 4px 8px;
-    border-radius: 4px;
-  }
-
-  .expand-body {
-    margin-top: 12px;
-  }
-
-  .forecast-summary .toolbar {
-    display: flex;
-    justify-content: flex-end;
-    margin-bottom: 12px;
-    .el-button + .el-button {
-      margin-left: 8px;
-    }
-  }
-
-@media screen and (max-width: 768px) {
-  .forecast-summary {
-    .toolbar {
-      margin-bottom: 10px;
-    }
-  }
-}

+ 230 - 2
src/views/forecast-summary/index.vue

@@ -159,6 +159,234 @@ export default {
 }
 </script>
 
-<style lang="scss">
-@import './index.scss';
+<style lang="scss" scoped >
+::v-deep .el-col-md-8 {
+  width: 24.33333% !important;
+}
+
+.forecast-summary {
+  .el-tag {
+    &.el-tag--success {
+      background-color: #f0f9ff;
+      border-color: #67c23a;
+      color: #67c23a;
+    }
+
+    &.el-tag--warning {
+      background-color: #fdf6ec;
+      border-color: #e6a23c;
+      color: #e6a23c;
+    }
+
+    &.el-tag--danger {
+      background-color: #fef0f0;
+      border-color: #f56c6c;
+      color: #f56c6c;
+    }
+
+    &.el-tag--info {
+      background-color: #f4f4f5;
+      border-color: #909399;
+      color: #909399;
+    }
+  }
+
+  // 表格行样式
+  .avue-crud {
+    .el-table {
+      .el-table__row {
+        &:hover {
+          background-color: #f5f7fa;
+        }
+      }
+
+      // 表头样式
+      .el-table__header-wrapper {
+        .el-table__header {
+          th {
+            background-color: #fafafa;
+            color: #606266;
+            font-weight: 500;
+          }
+        }
+      }
+
+      // 单元格样式
+      .el-table__body-wrapper {
+        .el-table__body {
+          td {
+            padding: 8px 0;
+
+            .cell {
+              padding: 0 10px;
+              line-height: 1.5;
+            }
+          }
+        }
+      }
+    }
+
+    // 分页样式
+    .el-pagination {
+      margin-top: 20px;
+      text-align: right;
+
+      .el-pagination__total {
+        color: #606266;
+        font-weight: normal;
+      }
+
+      .el-pager {
+        .number {
+          &.active {
+            background-color: #409eff;
+            color: #fff;
+          }
+        }
+      }
+    }
+
+    // 搜索区域样式
+    .avue-crud__search {
+      background-color: #f8f9fa;
+      border: 1px solid #e9ecef;
+      border-radius: 4px;
+      padding: 15px;
+      margin-bottom: 15px;
+
+      .el-form-item {
+        margin-bottom: 10px;
+
+        .el-form-item__label {
+          color: #606266;
+          font-weight: 500;
+        }
+
+        .el-input,
+        .el-select {
+          width: 100%;
+        }
+      }
+
+      .avue-crud__search-btn {
+        text-align: right;
+        margin-top: 10px;
+
+        .el-button {
+          margin-left: 10px;
+        }
+      }
+    }
+  }
+
+  // 数字右对齐
+  .text-right {
+    text-align: right;
+  }
+
+  // 文本省略
+  .text-ellipsis {
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+
+  // 状态标签样式增强
+  .status-tag {
+    font-weight: 500;
+    border-radius: 12px;
+    padding: 2px 8px;
+    font-size: 12px;
+  }
+
+  // 响应式设计
+  @media (max-width: 768px) {
+    .avue-crud {
+      .avue-crud__search {
+        .el-form-item {
+          .el-form-item__label {
+            width: 100% !important;
+            text-align: left !important;
+          }
+
+          .el-form-item__content {
+            margin-left: 0 !important;
+          }
+        }
+      }
+    }
+  }
+}
+
+// 全局样式覆盖
+.el-table {
+  .forecast-quantity-cell {
+    font-family: 'Courier New', monospace;
+    font-weight: 500;
+    color: #409eff;
+  }
+
+  .approval-status-cell {
+    .el-tag {
+      font-weight: 500;
+    }
+  }
+
+  .datetime-cell {
+    color: #909399;
+    font-size: 13px;
+  }
+}
+
+  // 行展开区样式(复用订单页样式类名,便于统一风格)
+  .order-expand-content {
+    padding: 16px 24px;
+    background-color: #fafafa;
+    border-left: 3px solid #409eff;
+  }
+
+  .expand-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 16px;
+    padding-bottom: 8px;
+    border-bottom: 1px solid #e4e7ed;
+
+    h4 {
+      margin: 0;
+      color: #303133;
+      font-size: 16px;
+      font-weight: 600;
+    }
+  }
+
+  .order-code {
+    color: #606266;
+    font-size: 14px;
+    background-color: #f0f2f5;
+    padding: 4px 8px;
+    border-radius: 4px;
+  }
+
+  .expand-body {
+    margin-top: 12px;
+  }
+
+  .forecast-summary .toolbar {
+    display: flex;
+    justify-content: flex-end;
+    margin-bottom: 12px;
+    .el-button + .el-button {
+      margin-left: 8px;
+    }
+  }
+
+@media screen and (max-width: 768px) {
+  .forecast-summary {
+    .toolbar {
+      margin-bottom: 10px;
+    }
+  }
+}
 </style>

+ 1 - 0
src/views/forecast-summary/summaryIndex.js

@@ -80,6 +80,7 @@ import { safeBigInt } from '@/util/util'
          calcHeight: 30,
          tip: false,
          searchShow: true,
+         searchIcon: true,
          searchMenuSpan: 12,
          searchIndex: 3,
          border: true,

+ 5 - 0
src/views/image-store-apply/index.scss

@@ -109,4 +109,9 @@
 
 .dialog-footer {
   text-align: right;
+}
+
+// 修复 el-col-md-8 宽度问题
+::v-deep .el-col-md-8 {
+  width: 24.33333% !important;
 }

+ 1 - 0
src/views/image-store-apply/mixins/imageStoreApplyIndex.js

@@ -91,6 +91,7 @@ export default {
         calcHeight: 30,
         tip: false,
         searchShow: true,
+        searchIcon: true,
         searchMenuSpan: 6,
         searchIndex: 3,
         border: true,

+ 5 - 0
src/views/lead/index.vue

@@ -224,4 +224,9 @@ export default {
     white-space: normal !important;
     color: #f56c6c !important;
 }
+
+// 修复 el-col-md-8 宽度问题
+::v-deep .el-col-md-8 {
+    width: 24.33333% !important;
+}
 </style>

+ 1 - 0
src/views/lead/mixins/leadIndex.js

@@ -303,6 +303,7 @@ export default {
                 calcHeight: 30,
                 tip: false,
                 searchShow: true,
+                searchIcon: true,
                 searchMenuSpan: 6,
                 searchIndex: 3,
                 border: true,

+ 5 - 0
src/views/marketing-activity/index.scss

@@ -253,4 +253,9 @@
     .activity-detail-dialog {
         width: 90% !important;
     }
+}
+
+// 修复 el-col-md-8 宽度问题
+::v-deep .el-col-md-8 {
+    width: 24.33333% !important;
 }

+ 1 - 0
src/views/marketing-activity/mixins/marketingActivityIndex.js

@@ -206,6 +206,7 @@ export default {
                 calcHeight: 30,
                 tip: false,
                 searchShow: true,
+                searchIcon: true,
                 searchMenuSpan: 18,
                 searchIndex: 3,
                 border: true,

+ 5 - 0
src/views/order/factory/index.vue

@@ -89,6 +89,8 @@ export default {
     opt.menu = true
     // 工厂端列表不需要操作列
     opt.menu = false
+    opt.searchMenuSpan = 18;
+    opt.searchIndex = 3;
 
     return {
       option: opt,
@@ -222,6 +224,9 @@ export default {
 </script>
 
 <style scoped>
+::v-deep .el-col-md-8 {
+  width: 24.33333% !important;
+}
 .order-expand-content { padding: 8px 12px; }
 .expand-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
 .order-code { color: #666; font-size: 12px; }

+ 41 - 6
src/views/order/order/index-avue.vue

@@ -422,7 +422,7 @@ export default {
      * @param {OrderItem} orderData - 保存后的订单数据
      * @returns {void}
      */
-    handleFormSaveSuccess(orderData) {
+    async handleFormSaveSuccess(orderData) {
       if (this.isEditMode) {
         // 编辑模式:保持在表单页,不返回列表
         this.orderFormVisible = true
@@ -431,11 +431,46 @@ export default {
         // 后台刷新列表数据,不影响停留在表单
         this.onLoad(this.page)
       } else {
-        // 新增模式:保存后返回列表
-        this.orderFormVisible = false
-        this.isEditMode = false
-        this.editOrderId = null
-        this.onLoad(this.page)
+        // 新增模式:保存后停留当前页并切换到编辑模式,显示提交按钮
+        this.orderFormVisible = true
+        this.isEditMode = true
+        // 尝试从响应数据拿ID;若无则从列表首条获取ID
+        const respId = orderData && orderData.id ? String(orderData.id) : null
+        if (respId) {
+          this.editOrderId = respId
+        } else {
+          try {
+            const latestId = await this.fetchLatestOrderId()
+            if (latestId) {
+              this.editOrderId = String(latestId)
+            }
+          } catch (e) {
+            // 获取最新ID失败,保留当前状态,用户仍可手动返回列表
+            // eslint-disable-next-line no-console
+            console.warn('获取最新订单ID失败:', e)
+          } finally {
+            // 刷新列表数据,保持数据最新
+            this.onLoad(this.page)
+          }
+        }
+      }
+    },
+
+    /**
+     * 获取最新创建的订单ID(列表第一页第一条)
+     * @returns {Promise<string|number|null>}
+     */
+    async fetchLatestOrderId() {
+      try {
+        const res = await getOrderList(1, 1, {})
+        const data = res && res.data && res.data.data
+        const records = data && Array.isArray(data.records) ? data.records : []
+        const first = records[0]
+        return (first && first.id) ? first.id : null
+      } catch (error) {
+        // eslint-disable-next-line no-console
+        console.error('fetchLatestOrderId error:', error)
+        return null
       }
     },
 

+ 1 - 0
src/views/order/order/option.js

@@ -50,6 +50,7 @@ export const option = {
   calcHeight: 30,
   tip: false,
   searchShow: true,
+  searchIcon: true,
   searchMenuSpan: 6,
   border: true,
   index: true,

+ 3 - 0
src/views/survey/index-avue.vue

@@ -86,6 +86,9 @@ export default {
 </script>
 
 <style lang="scss" scoped>
+::v-deep .el-col-md-8 {
+  width: 24.33333% !important;
+}
 .survey-management-avue {
   // 题目编辑弹窗样式
   ::v-deep .question-editor-dialog {