From a5e2f85d5ccdeb11513fd1ccc9cb3d87e63c6e44 Mon Sep 17 00:00:00 2001 From: wangmeng <1620161711@qq.com> Date: Tue, 10 Feb 2026 09:52:48 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=A0=B7=E5=BC=8F=E7=AD=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/page/login/userlogin.vue | 4 +- src/router/axios.js | 2 +- src/router/views/index.js | 8 +- src/store/modules/order.js | 186 ++++- src/views/approval/approvalDetails.vue | 71 +- src/views/approval/approvalRecord.vue | 12 +- src/views/customer/add.vue | 15 +- src/views/customer/index.vue | 4 +- src/views/order/AddtoTemplate.vue | 406 +++++----- src/views/order/ProjectProductEdit.vue | 358 +++++---- src/views/order/bankReceiptDetail.vue | 2 +- src/views/order/category.vue | 8 +- src/views/order/month.vue | 88 ++- src/views/order/orderAddEdit.vue | 966 ++++++++++++----------- src/views/order/orderChangeLog.vue | 12 +- src/views/order/orderList.vue | 21 +- src/views/order/subcategory.vue | 8 +- src/views/order/year.vue | 4 +- src/views/product/add/add.vue | 29 +- src/views/product/add/edit.vue | 28 +- src/views/product/add/exchangeRate.vue | 23 +- src/views/product/add/subcategory.vue | 3 +- src/views/wel/components/ApprovalTip.vue | 2 +- src/views/wel/index.vue | 4 +- 24 files changed, 1336 insertions(+), 928 deletions(-) diff --git a/src/page/login/userlogin.vue b/src/page/login/userlogin.vue index 54236fa..b763065 100644 --- a/src/page/login/userlogin.vue +++ b/src/page/login/userlogin.vue @@ -100,9 +100,9 @@ roleId: "", //用户名 // username: "admin", - username:'jinchao', + username:'', //密码 - password: "123456", + password: "", // password: "admin", //账号类型 type: "account", diff --git a/src/router/axios.js b/src/router/axios.js index eb482c2..e4df84b 100644 --- a/src/router/axios.js +++ b/src/router/axios.js @@ -50,7 +50,7 @@ axios.interceptors.request.use(config => { config.url = baseUrl + config.url; } if(config.url.indexOf('/api') != -1){ - config.url = config.url.replace('/api','http://192.168.0.220:8090') + config.url = config.url.replace('/api','http://192.168.1.5:8091') } // else{ // config.url = "http://192.168.0.220:8090" + config.url diff --git a/src/router/views/index.js b/src/router/views/index.js index 918eb17..23a8b0b 100644 --- a/src/router/views/index.js +++ b/src/router/views/index.js @@ -231,7 +231,7 @@ export default [{ name: '订单编辑', meta: { i18n: 'order', - keepAlive:true + // keepAlive:true }, component: () => import( /* webpackChunkName: "views" */ '@/views/order/orderAddEdit') @@ -241,7 +241,7 @@ export default [{ name: '项目产品编辑', meta: { i18n: 'edit', - keepAlive: true + // keepAlive: true }, component: () => import( /* webpackChunkName: "views" */ '@/views/order/ProjectProductEdit') @@ -271,7 +271,7 @@ export default [{ meta: { i18n: 'add', title: '选择产品', - keepAlive: true + // keepAlive: true }, component: () => import( /* webpackChunkName: "views" */ '@/views/order/AddtoTemplate') @@ -281,7 +281,6 @@ export default [{ name: '选择', meta: { i18n: 'order', - // keepAlive:true }, component: () => import( /* webpackChunkName: "views" */ '@/views/order/year') @@ -291,7 +290,6 @@ export default [{ name: '选择', meta: { i18n: 'order', - // keepAlive:true }, component: () => import( /* webpackChunkName: "views" */ '@/views/order/month') diff --git a/src/store/modules/order.js b/src/store/modules/order.js index 9914b19..1f3cb4e 100644 --- a/src/store/modules/order.js +++ b/src/store/modules/order.js @@ -2,47 +2,205 @@ const order = { namespaced: true, state: { tempOrderInfo: { - form: {}, + mode: "add", // 页面模式:add/edit/view + orderId: "", // 当前订单ID + customerId: "", // 当前选中的客户ID + sort: "", // 当前操作的项目序号 + originalOrderStatus: null, // 原始订单状态 + type: "", // 回显类型:queryData/temData + productList: [], // 临时产品列表 + productEdit: false, // 新增:标记是否在产品编辑页面 + form: { // 初始化所有字段,避免undefined + id: "", + name: "", + customerCode: "", + deliveryDate: "", + monetaryUnit: "", + standardPrice: "", + sellingPrice: "", + splitPrice: "", + discountAmount: 0.00 // 初始化为0.00,解决优惠金额显示问题 + }, projectList: [], - isTemporaryLeave: false + isTemporaryLeave: false + }, + productSelectState: { + customerId: '', + subcategoryId: '', + selectedSubcategoryIds: [], + leftTableData: [], + rightTableData: [], } }, getters: { - getTempOrderInfo: (state) => state.tempOrderInfo + // 基础getter:获取完整临时订单信息 + getTempOrderInfo: (state) => state.tempOrderInfo, + // 快捷getter + getOrderMode: (state) => state.tempOrderInfo.mode, + isOrderViewMode: (state) => state.tempOrderInfo.mode === "view", + isOrderEditMode: (state) => state.tempOrderInfo.mode === "edit", + hasOrderId: (state) => !!state.tempOrderInfo.orderId, + getCurrentOrderId: (state) => state.tempOrderInfo.orderId, + // 新增:获取productEdit标识 + getOrderProductEdit: (state) => state.tempOrderInfo.productEdit, + // 产品选择相关getter + getProductSelectState: (state) => state.productSelectState, + getProductSelectCustomerId: (state) => state.productSelectState.customerId, + getSelectedSubcategoryIds: (state) => state.productSelectState.selectedSubcategoryIds, + getOrderProductList: (state) => state.tempOrderInfo.productList, }, actions: { + // 保存临时订单信息(支持部分更新) saveTempOrderInfo({ commit }, data) { commit('SET_TEMP_ORDER_INFO', data); }, + // 清空临时订单信息 clearTempOrderInfo({ commit }) { commit('CLEAR_TEMP_ORDER_INFO'); }, + // 设置临时离开标记 setTemporaryLeave({ commit }, val) { commit('SET_TEMPORARY_LEAVE', val); + }, + // 更新项目列表 + updateProjectList({ commit }, newProjectList) { + commit('UPDATE_PROJECT_LIST', newProjectList); + }, + // 更新产品选择状态 + updateProductSelectState({ commit }, payload) { + commit('UPDATE_PRODUCT_SELECT_STATE', payload); + }, + // 清空产品选择状态 + clearProductSelectState({ commit }) { + commit('CLEAR_PRODUCT_SELECT_STATE'); + }, + // 添加已选小类ID + addSelectedSubcategoryId({ commit }, subcategoryId) { + commit('ADD_SELECTED_SUBCATEGORY_ID', subcategoryId); + }, + // 清空产品列表(只清空productList) + clearOrderProductList({ commit }) { + commit('CLEAR_ORDER_PRODUCT_LIST'); + }, + // 新增:单独设置productEdit标识 + setOrderProductEdit({ commit }, val) { + commit('SET_ORDER_PRODUCT_EDIT', val); } }, mutations: { - // 修复:保存数据时继承原有isTemporaryLeave标记,不丢失 + // 修复:安全合并临时订单信息,避免null/undefined SET_TEMP_ORDER_INFO(state, data) { - state.tempOrderInfo = { - ...state.tempOrderInfo, // 保留原有所有属性(包括标记) - form: { ...state.tempOrderInfo.form, ...(data.form || {}) }, - projectList: Array.isArray(data.projectList) ? JSON.parse(JSON.stringify(data.projectList)) : [] - }; + // 1. 校验传入的data是否为合法对象 + if (!data || typeof data !== 'object' || Array.isArray(data)) { + return; + } + + // Debug log + console.log('SET_TEMP_ORDER_INFO called with data:', data); + console.log('Before update - state.tempOrderInfo.mode:', state.tempOrderInfo.mode); + + // 2. 安全合并form:先确保form是对象,再合并 + if (data.form && typeof data.form === 'object' && !Array.isArray(data.form)) { + // 初始化state.tempOrderInfo.form(防止被意外置空) + state.tempOrderInfo.form = state.tempOrderInfo.form || {}; + Object.assign(state.tempOrderInfo.form, data.form); + } + + // 3. 安全更新项目列表:深拷贝保证响应式 + if (Array.isArray(data.projectList)) { + state.tempOrderInfo.projectList = JSON.parse(JSON.stringify(data.projectList)); + } + + // 4. 合并其他属性(排除form和projectList) + const otherData = { ...data }; + delete otherData.form; + delete otherData.projectList; + // 确保合并的目标对象存在 + if (typeof state.tempOrderInfo === 'object') { + Object.assign(state.tempOrderInfo, otherData); + } + + // Debug log + console.log('After update - state.tempOrderInfo.mode:', state.tempOrderInfo.mode); }, - // 修复:清空缓存时重置所有属性,包括标记 + // 修复:重置时保证form字段完整初始化 CLEAR_TEMP_ORDER_INFO(state) { state.tempOrderInfo = { - form: {}, + mode: "add", + orderId: "", + customerId: "", + sort: "", + originalOrderStatus: null, + type: "", + productList: [], + productEdit: false, // 重置为false + form: { // 完整初始化,避免字段缺失 + id: "", + name: "", + customerCode: "", + deliveryDate: "", + monetaryUnit: "", + standardPrice: "", + sellingPrice: "", + splitPrice: "", + discountAmount: 0 // 保持0.00,解决优惠金额显示 + }, projectList: [], isTemporaryLeave: false }; + // 同时清空产品选择状态 + state.productSelectState = { + customerId: '', + subcategoryId: '', + selectedSubcategoryIds: [], + leftTableData: [], + rightTableData: [] + }; }, - // 修复:正确给tempOrderInfo内部的标记赋值 + // 设置临时离开标记 SET_TEMPORARY_LEAVE(state, val) { - state.tempOrderInfo.isTemporaryLeave = val; + state.tempOrderInfo.isTemporaryLeave = !!val; // 转布尔值,避免非预期值 + }, + // 更新项目列表 + UPDATE_PROJECT_LIST(state, newProjectList) { + state.tempOrderInfo.projectList = Array.isArray(newProjectList) + ? JSON.parse(JSON.stringify(newProjectList)) + : []; + }, + // 更新产品选择状态 + UPDATE_PRODUCT_SELECT_STATE(state, payload) { + if (payload && typeof payload === 'object') { + state.productSelectState = { + ...state.productSelectState, + ...payload + }; + } + }, + // 清空产品选择状态 + CLEAR_PRODUCT_SELECT_STATE(state) { + state.productSelectState = { + customerId: '', + subcategoryId: '', + selectedSubcategoryIds: [], + leftTableData: [], + rightTableData: [] + }; + }, + // 添加已选小类ID(去重) + ADD_SELECTED_SUBCATEGORY_ID(state, subcategoryId) { + if (subcategoryId && !state.productSelectState.selectedSubcategoryIds.includes(subcategoryId)) { + state.productSelectState.selectedSubcategoryIds.push(subcategoryId); + } + }, + // 清空产品列表,保留其他临时订单信息 + CLEAR_ORDER_PRODUCT_LIST(state) { + state.tempOrderInfo.productList = []; + }, + // 新增:单独设置productEdit标识 + SET_ORDER_PRODUCT_EDIT(state, val) { + state.tempOrderInfo.productEdit = !!val; // 确保是布尔值 } } }; -export default order; \ No newline at end of file +export default order; diff --git a/src/views/approval/approvalDetails.vue b/src/views/approval/approvalDetails.vue index cba7ab8..8ab9ee8 100644 --- a/src/views/approval/approvalDetails.vue +++ b/src/views/approval/approvalDetails.vue @@ -32,6 +32,10 @@ >{{ orderData.customerName || "-" }} + +
+ 货币单位: + {{ getMonetaryUnitText(orderData.monetaryUnit) }}
交货时间: @@ -50,17 +54,17 @@
公司指导价: - {{ orderData.standardPrice || "" }}元 + {{ orderData.standardPrice || "" }}
销售价: - {{ orderData.sellingPrice || "" }}元 + {{ orderData.sellingPrice || "" }}
分成金额: - {{ orderData.splitPrice || "" }}元 + {{ orderData.splitPrice || "" }}
@@ -69,9 +73,9 @@ 元 + />
@@ -80,10 +84,10 @@ 元 + />
@@ -92,7 +96,7 @@ % @@ -107,7 +111,7 @@ v-model="orderData.exchangeRate" :disabled="isDisabled" placeholder="请输入" - style="width: 150px" + style="width: 10vw" />
@@ -338,7 +342,9 @@ import { getExchangeRateList } from "@/api/approval/approvalDetails.js"; import { searchData } from "@/api/customer/customer.js"; - +import { + getCurrencyList, +} from "@/api/order/orderAddEdit"; export default { components: { basicCrumb, @@ -364,6 +370,7 @@ export default { this.getOrderDetail(orderId); this.orderId = orderId; } + this.loadCurrencyList(); }, methods: { @@ -395,6 +402,25 @@ export default { // 无论成功失败,都关闭加载状态 this.loading = false; } + }, + getMonetaryUnitText(code) { + // 1. 空值处理 + if (!code) return "-"; + // 2. 从货币列表中匹配编码 + const unitItem = this.monetaryUnitList.find(item => item.dictKey === code); + // 3. 匹配到返回展示文本,未匹配到返回原编码(避免展示空) + return unitItem ? unitItem.dictValue : code; + }, + // 加载货币单位列表 + async loadCurrencyList() { + try { + const res = await getCurrencyList(); + if (res.data.code === 200) { + this.monetaryUnitList = res.data.data || []; + } + } catch (err) { + this.$message.error("网络异常,无法加载货币单位列表"); + } }, // 获取汇率列表 getExchangeRateList() { @@ -415,27 +441,20 @@ export default { }, // 新增:计算提成金额核心方法(提成比例变化时触发) calcCommissionPrice() { - // 1. 获取原始值,去除空格,处理空值 - const standardPrice = Number(this.orderData.standardPrice || 0); // 公司指导价 - let commissionRate = this.orderData.commissionRate ? this.orderData.commissionRate.toString().trim() : ''; // 提成比例(可能是字符串) + const standardPrice = Number(this.orderData.standardPrice || 0); + let commissionRate = this.orderData.commissionRate ? this.orderData.commissionRate.toString().trim() : ''; - // 2. 非数字/空值,提成金额置空,直接返回 if (!/^\d+(\.\d+)?$/.test(commissionRate)) { - this.orderData.commissionPrice = ''; + this.orderData.commissionPrice = "0.00"; // 非法值置为0.00 return; } - // 3. 百分比转小数(如输入10 → 0.1),执行计算 提成金额 = 公司指导价 × 提成比例(小数) const rate = Number(commissionRate) / 100; let commissionPrice = standardPrice * rate; - - // 4. 保留2位小数,避免多位小数 - commissionPrice = commissionPrice.toFixed(2); - // 去除末尾的.00, - this.orderData.commissionPrice = commissionPrice.endsWith('.00') ? commissionPrice.split('.')[0] : commissionPrice; + this.orderData.commissionPrice = commissionPrice.toFixed(2); // 强制保留两位小数 }, getContactValue(key) { - // 多层判断:先判断contacts是否存在且是数组,再判断第一个元素是否存在,最后取对应属性 + // 多层判断:先判断contacts是否存在且是数组,再判断第一个素是否存在,最后取对应属性 if ( this.customerDetail.contacts && Array.isArray(this.customerDetail.contacts) && @@ -529,6 +548,7 @@ calcCommissionPrice() { } try { const requestData = { + ...this.orderData, id: this.orderData.id, commissionRate: this.orderData.commissionRate, exchangeRate: this.orderData.exchangeRate, @@ -633,6 +653,9 @@ calcCommissionPrice() { margin-bottom: 10px; // line-height: 32px; font-size: $font-size-26; + height: 2vw; + display: flex; + align-items: center; .label { width: 9.478vw !important; @@ -867,7 +890,7 @@ calcCommissionPrice() { // width: 110px; // font-weight: 500; color: #606266; - text-align: right; + text-align: left; padding-right: 15px; font-size: $font-size-24; width: 10vw; diff --git a/src/views/approval/approvalRecord.vue b/src/views/approval/approvalRecord.vue index f98838b..53ca9cf 100644 --- a/src/views/approval/approvalRecord.vue +++ b/src/views/approval/approvalRecord.vue @@ -32,7 +32,6 @@ v-for="(item, index) in approvalList" :key="index" class="approval-item clickable-item" - @click="handleOperate(item)" > @@ -54,7 +53,7 @@
- 加载更多 + 加载更多
+ diff --git a/src/views/order/AddtoTemplate.vue b/src/views/order/AddtoTemplate.vue index ece0836..351e35e 100644 --- a/src/views/order/AddtoTemplate.vue +++ b/src/views/order/AddtoTemplate.vue @@ -64,12 +64,6 @@ width="80" align="center" > - @@ -142,12 +135,6 @@ width="80" align="center" > - import basicCrumb from "@/components/basic-crumb/main"; import { getProduct } from "@/api/product/product"; -// import { saveSelectedProduct } from "@/api/product/AddtoTemplate"; -import { mapGetters } from "vuex"; +import { mapGetters, mapActions } from "vuex"; + export default { name: "ProductSelect", components: { @@ -172,133 +159,142 @@ export default { }, data() { return { - leftTableData: [], // 左侧待选产品(后端接口返回) - rightTableData: [], // 右侧已选产品 - currentLeftRow: null, // 当前选中的左侧行 - loading: false, // 加载状态 - productId: "", // 存储页面跳转带过来的id - leftSelectedRows: [], // 左侧勾选的行(多选) - rightSelectedRows: [], // 右侧勾选的行(多选) - subcategoryId: "", //小类id - currentRightRow: null, - customerId:'' + // 仅保留临时交互状态(无需持久化) + currentLeftRow: null, // 当前选中的左侧行 + currentRightRow: null, // 当前选中的右侧行 + loading: false, // 加载状态 + leftSelectedRows: [], // 左侧勾选的行(临时) + rightSelectedRows: [], // 右侧勾选的行(临时) }; }, - activated() { - // 1. 获取跳转带回的新小类id - const newSubcategoryId = this.$route.query.subcategoryId || ""; - // console.log("新小类ID:", newSubcategoryId, "旧小类ID:", this.subcategoryId); - // 2. 仅当新ID存在且与旧ID不同时,才请求数据并追加 - // if (newSubcategoryId && newSubcategoryId !== this.subcategoryId) { - // this.subcategoryId = newSubcategoryId; // 更新旧ID为新ID - // this.fetchProductList(); // 请求新小类数据并追加 - // } - this.subcategoryId = newSubcategoryId; // 更新旧ID为新ID - this.fetchProductList(); // 请求新小类数据并追加 - if (!newSubcategoryId || this.$route.query.isClear==true) { - this.resetComponentState(); - } - }, - computed: { - ...mapGetters(["routeData"]) + computed: { + ...mapGetters(["routeData"]), + // 从Vuex获取核心数据 + ...mapGetters("order", [ + "getProductSelectState", // 产品选择状态 + "getProductSelectCustomerId", // 客户ID + "getSelectedSubcategoryIds", // 已选小类ID列表 + "getTempOrderInfo", + "getOrderProductEdit", + "getOrderMode", + "getOrderId", + ]), + // 快捷获取各核心数据 + customerId() { + return this.getTempOrderInfo.customerId ; + }, + // 当前路由传过来的新小类ID + newSubcategoryId() { + return this.$route.query.subcategoryId || ""; }, - mounted(){ - // this.customerId = this.$route.query.customerId ? this.$route.query.customerId:'' + leftTableData() { + return this.getProductSelectState.leftTableData || []; }, + rightTableData() { + return this.getProductSelectState.rightTableData || []; + } + }, + mounted() { + // 初始化页面 + this.initPage(); + // 监听路由参数变化(核心:识别新小类ID并追加数据) + this.$watch( + () => this.$route.query.subcategoryId, + (newId) => { + if (newId) { + this.appendNewSubcategoryData(newId); // 追加新小类数据 + } + }, + { immediate: true } // 首次加载也触发 + ); + }, methods: { - // async fetchProductList() { - // // 校验id是否存在 - // if (!this.subcategoryId) { - // this.$message.warning("缺少模板ID,无法获取产品列表"); - // return; - // } - // try { - // this.loading = true; - // // 调用接口:传递页面跳转过来的id - // const res = await getProduct({ - // catalogId: this.subcategoryId, - // size: 9999, - // current: 1, - // }); - // const data = res.data.data.records || []; - // console.log("data", data); - // // 给后端返回的数据添加序号(index) - // this.leftTableData = data.map((item, idx) => ({ - // ...item, - // index: idx + 1, // 序号从1开始 - // })); - // } catch (error) { - // console.error("请求产品列表失败:", error); - // this.$message.error("网络异常,获取产品列表失败"); - // } finally { - // this.loading = false; - // } - // }, - async fetchProductList() { - if (!this.subcategoryId) { - this.$message.warning("缺少小类ID,无法获取产品列表"); + ...mapActions("order", [ + "updateProductSelectState", // 更新产品选择状态 + "clearProductSelectState", // 清空产品选择状态 + "addSelectedSubcategoryId" // 添加已选小类ID + ]), + // 初始化页面(仅初始化基础参数,不重置数据) + initPage() { + // 1. 初始化客户ID到Vuex(仅首次) + if (!this.customerId && this.$route.query.customerId) { + this.updateProductSelectState({ + customerId: this.$route.query.customerId + }); + } + }, + // 核心:追加新小类的产品数据到左侧表格 + async appendNewSubcategoryData(newSubcategoryId) { + // 跳过:小类ID为空 或 已加载过该小类 + if (!newSubcategoryId || this.getSelectedSubcategoryIds.includes(newSubcategoryId)) { return; } + try { this.loading = true; + // 1. 请求新小类的产品数据 const res = await getProduct({ - catalogId: this.subcategoryId, + catalogId: newSubcategoryId, size: 9999, current: 1, - customerId:this.$route.query.customerId ? this.$route.query.customerId:'', + customerId: this.customerId, }); - const newData = res.data.data.records || []; - console.log("新获取的小类产品数据:", newData); - if (newData.length === 0) { - this.$message.info("该小类下暂无产品"); + const newProductData = res.data.data.records || []; + console.log("新获取的小类产品数据:", newProductData); + + if (newProductData.length === 0) { + this.$message.info(`小类ID:${newSubcategoryId} 下暂无产品`); + // 标记该小类已加载(避免重复请求) + this.addSelectedSubcategoryId(newSubcategoryId); return; } - // 1. 去重逻辑:过滤掉「左侧已存在」和「右侧已选」的产品(根据id) - const existLeftIds = this.leftTableData.map(item => item.id); // 左侧待选已有id - const existRightIds = this.rightTableData.map(item => item.id); // 右侧已选id - const uniqueNewData = newData.filter(item => { - // 仅保留:左侧没有 && 右侧也没有的产品 + // 2. 去重:过滤掉左侧/右侧已存在的产品 + const existLeftIds = this.leftTableData.map(item => item.id); + const existRightIds = this.rightTableData.map(item => item.id); + const uniqueNewProducts = newProductData.filter(item => { return !existLeftIds.includes(item.id) && !existRightIds.includes(item.id); }); - // 2. 追加数据到左侧待选表格不是覆盖 - this.leftTableData = [...this.leftTableData, ...uniqueNewData]; - // 3. 追加后重置左侧序号,保证连续 + + // 3. 追加到左侧表格(Vuex) + const newLeftTableData = [...this.leftTableData, ...uniqueNewProducts]; + await this.updateProductSelectState({ + leftTableData: newLeftTableData, + subcategoryId: newSubcategoryId // 更新当前小类ID + }); + + // 4. 标记该小类已加载(避免重复请求) + this.addSelectedSubcategoryId(newSubcategoryId); + + // 5. 重置序号 this.resetIndex(); - // this.$message.success(`成功追加 ${uniqueNewData.length} 个新产品`); + // this.$message.success(`成功追加 ${uniqueNewProducts.length} 个新产品`); } catch (error) { - console.error("请求产品列表失败:", error); - this.$message.error("网络异常,获取产品列表失败"); + console.error("追加小类产品失败:", error); + this.$message.error("网络异常,获取新小类产品失败"); } finally { this.loading = false; } - }, - resetComponentState() { - this.leftTableData = []; - this.rightTableData = []; - this.subcategoryId = ""; - this.clearSelectionAndCurrentRow(); }, // 左侧表格单行点击 handleLeftRowClick(row) { this.currentLeftRow = row; }, - // 新增:清空表格勾选和当前行 - clearSelectionAndCurrentRow() { - if (this.$refs.leftTable) { - this.$refs.leftTable.clearSelection(); - this.$refs.leftTable.setCurrentRow(null); - } - if (this.$refs.rightTable) { - this.$refs.rightTable.clearSelection(); - this.$refs.rightTable.setCurrentRow(null); - } - this.leftSelectedRows = []; - this.rightSelectedRows = []; - this.currentLeftRow = null; - this.currentRightRow = null; - }, - + // 清空表格勾选和当前行 + clearSelectionAndCurrentRow() { + if (this.$refs.leftTable) { + this.$refs.leftTable.clearSelection(); + this.$refs.leftTable.setCurrentRow(null); + } + if (this.$refs.rightTable) { + this.$refs.rightTable.clearSelection(); + this.$refs.rightTable.setCurrentRow(null); + } + this.leftSelectedRows = []; + this.rightSelectedRows = []; + this.currentLeftRow = null; + this.currentRightRow = null; + }, // 右侧表格单行点击 handleRightRowClick(row) { this.currentRightRow = row; @@ -307,22 +303,18 @@ export default { handleLeftSelectionChange(val) { this.leftSelectedRows = val; }, - // 右侧表格勾选事件(多选) handleRightSelectionChange(val) { this.rightSelectedRows = val; }, - // 左侧表格奇偶行样式 leftTableRowClass({ rowIndex }) { return rowIndex % 2 === 0 ? "" : "row-gray"; }, - // 右侧表格奇偶行样式 rightTableRowClass({ rowIndex }) { return rowIndex % 2 === 0 ? "" : "row-gray"; }, - // 迁移到右侧(待选→已选,支持多选) transferToRight() { if (this.leftSelectedRows.length === 0) { @@ -330,27 +322,33 @@ export default { return; } - // 遍历勾选的行,逐个迁移 + // 1. 复制Vuex中的数据进行操作 + let newLeftData = [...this.leftTableData]; + let newRightData = [...this.rightTableData]; + + // 2. 遍历勾选的行,逐个迁移 this.leftSelectedRows.forEach((row) => { - const leftIdx = this.leftTableData.findIndex( - (item) => item.id === row.id - ); + const leftIdx = newLeftData.findIndex(item => item.id === row.id); if (leftIdx > -1) { - const [movedRow] = this.leftTableData.splice(leftIdx, 1); + const [movedRow] = newLeftData.splice(leftIdx, 1); // 移除不需要的字段(如果有) const { remark, ...rightRow } = movedRow; - console.log("remark",remark) - this.rightTableData.push(rightRow); + newRightData.push(rightRow); } }); - // 清空左侧勾选状态 - this.$refs.leftTable.clearSelection(); + // 3. 更新到Vuex + this.updateProductSelectState({ + leftTableData: newLeftData, + rightTableData: newRightData + }); + + // 4. 清空临时勾选状态 + if (this.$refs.leftTable) { + this.$refs.leftTable.clearSelection(); +} this.leftSelectedRows = []; - // 重置序号(保证连续) - this.resetIndex(); }, - // 迁移到左侧(已选→待选,支持多选) transferToLeft() { if (this.rightSelectedRows.length === 0) { @@ -358,34 +356,50 @@ export default { return; } - // 遍历勾选的行,逐个迁移 + // 1. 复制Vuex中的数据进行操作 + let newLeftData = [...this.leftTableData]; + let newRightData = [...this.rightTableData]; + + // 2. 遍历勾选的行,逐个迁移 this.rightSelectedRows.forEach((row) => { - const rightIdx = this.rightTableData.findIndex( - (item) => item.id === row.id - ); + const rightIdx = newRightData.findIndex(item => item.id === row.id); if (rightIdx > -1) { - const [movedRow] = this.rightTableData.splice(rightIdx, 1); + const [movedRow] = newRightData.splice(rightIdx, 1); // 补全左侧需要的字段 - this.leftTableData.push({ + newLeftData.push({ ...movedRow, remarkCn: movedRow.remarkCn || "", }); } }); - // 清空右侧勾选状态 - this.$refs.rightTable.clearSelection(); + // 3. 更新到Vuex + this.updateProductSelectState({ + leftTableData: newLeftData, + rightTableData: newRightData + }); + + // 4. 清空临时勾选状态 + if (this.$refs.rightTable) { + this.$refs.rightTable.clearSelection(); +} this.rightSelectedRows = []; - // 重置序号(保证连续) - this.resetIndex(); }, - // 重置表格序号(保证序号连续) resetIndex() { - this.leftTableData.forEach((item, idx) => (item.index = idx + 1)); - this.rightTableData.forEach((item, idx) => (item.index = idx + 1)); + const newLeftData = this.leftTableData.map((item, idx) => ({ + ...item, + index: idx + 1 + })); + const newRightData = this.rightTableData.map((item, idx) => ({ + ...item, + index: idx + 1 + })); + this.updateProductSelectState({ + leftTableData: newLeftData, + rightTableData: newRightData + }); }, - // 选择产品 handleSelectProduct() { let arr = [ {name:'工作台',url:'/wel'}] @@ -397,11 +411,12 @@ export default { sort: this.$route.query.sort, mode: this.$route.query.mode ? this.$route.query.mode:'', orderId:this.$route.query.orderId ? this.$route.query.orderId:'', - customerId:this.$route.query.customerId ? this.$route.query.customerId:'', - } + customerId: this.customerId, + // 携带已选小类ID列表(方便分类页识别) + selectedSubcategoryIds: JSON.stringify(this.getSelectedSubcategoryIds) + } }); }, - // 保存已选产品(提交到后端,携带模板ID) async handleSave() { if (this.rightTableData.length === 0) { @@ -422,38 +437,36 @@ export default { name: item.nameCn, //名称 spec: item.specCn, //产品规格 unit: item.unitCn, //单位 - standardPrice: item.standardPrice, //指导价 remarks: item.remarkCn, //备注 multiple:item.multiple ,//倍率 num: item.multiple, //数量 - })), }; + // 跳转前清空Vuex的产品选择状态 + await this.clearProductSelectState(); + if ( - this.$route.query.productEdit && - this.$route.query.productEdit == true + this.getOrderProductEdit ) { - this.resetComponentState(); this.$router.push({ path: "/order/ProjectProductEdit", query: { queryData: JSON.stringify(queryData), - mode: this.$route.query.mode ? this.$route.query.mode:'', - orderId:this.$route.query.orderId ? this.$route.query.orderId:'', - customerId:this.$route.query.customerId ? this.$route.query.customerId:'', - sort:this.$route.query.sort, + // mode: this.$route.query.mode ? this.$route.query.mode:'', + // orderId:this.$route.query.orderId ? this.$route.query.orderId:'', + // customerId: this.customerId, + // sort:this.$route.query.sort, }, }); } else { - this.resetComponentState(); this.$router.push({ path: "/order/addEdit", query: { queryData: JSON.stringify(queryData), - mode: this.$route.query.mode ? this.$route.query.mode:'', - orderId:this.$route.query.orderId ? this.$route.query.orderId:'', - customerId:this.$route.query.customerId ? this.$route.query.customerId:'', + mode: this.getOrderMode, + orderId: this.getOrderId, + // customerId: this.customerId, }, }); } @@ -462,21 +475,18 @@ export default { this.$message.error("网络异常,保存产品失败"); } }, - // 取消操作 handleCancel() { - - this.$router.push({ - path: "/order/addEdit", - query: { - noClear: true, - mode: this.$route.query.mode ? this.$route.query.mode:'', - orderId:this.$route.query.orderId ? this.$route.query.orderId:'', - // customerId:this.customerId||'', - }, - }); - this.resetComponentState(); - + // 清空Vuex状态 + this.clearProductSelectState(); + this.$router.push({ + path: "/order/addEdit", + query: { + noClear: true, + mode: this.$route.query.mode ? this.$route.query.mode:'', + orderId:this.$route.query.orderId ? this.$route.query.orderId:'', + }, + }); }, }, }; @@ -491,13 +501,12 @@ export default { margin: 0 auto; margin-top: 8px; padding: 20px !important; - .pageTitle{ - // font-size: 26px; - font-size:$font-size-title; - margin-bottom: 10px; - width: 100%; - text-align: center; - } + .pageTitle{ + font-size:$font-size-title; + margin-bottom: 10px; + width: 100%; + text-align: center; + } } .page-title { @@ -526,7 +535,6 @@ export default { align-items: center; padding: 0 20px; - .transfer-btn { display: flex; flex-direction: column; @@ -556,44 +564,28 @@ export default { background-color: #f5f7fa !important; } -// 表格单元格样式 -::v-deep .el-table { - // --el-table-row-hover-bg-color: #e6f7ff; - - // .el-table__cell { - // padding: 8px 0; - // font-size: 14px; - // color: #606266; - // } - - // .el-table__header-wrapper th { - // font-weight: 500; - // color: #303133; - // } -} ::v-deep .el-button + .el-button { margin-left: 0 !important; // 移除间距 - } // 放大多选框本身 ::v-deep .el-table .el-checkbox__inner { - width: 30px; - height: 30px; - border-width: 2px; // 让多选框边框也变粗 + width: 30px; + height: 30px; + border-width: 2px; // 让多选框边框也变粗 } // 让对勾变粗、变大 ::v-deep .el-table .el-checkbox__inner::after { - border-width: 2px; // 对勾线条宽度,默认1px - transform: rotate(45deg) scaleY(1); // 确保对勾正常显示 + border-width: 2px; // 对勾线条宽度,默认1px + transform: rotate(45deg) scaleY(1); // 确保对勾正常显示 } // 让多选框在单元格里完全居中 ::v-deep .el-table .el-table-column--selection .cell { - display: flex; - justify-content: center; - align-items: center; - padding: 0; - height: 100%; // 占满单元格高度,垂直居中 + display: flex; + justify-content: center; + align-items: center; + padding: 0; + height: 100%; // 占满单元格高度,垂直居中 } diff --git a/src/views/order/ProjectProductEdit.vue b/src/views/order/ProjectProductEdit.vue index d73c1e5..5bbd1b8 100644 --- a/src/views/order/ProjectProductEdit.vue +++ b/src/views/order/ProjectProductEdit.vue @@ -1,26 +1,26 @@