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 @@
+
{{ isViewMode ? '项目产品查看' : "项目产品编辑" }}
-
+
选择产品
-
+
保存
@@ -36,16 +36,17 @@
+
-
+
-
+
-
-
+
+
-
+
+
@@ -99,46 +101,50 @@
=(销售价-指导价)/2*数量
- {{ scope.row.splitPrice }}
+ {{ scope.row.splitPrice || '0.00' }}
-
+
@@ -320,13 +408,12 @@ export default {
padding: 20px !important;
box-sizing: border-box;
- .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;
+ }
.btn-group {
gap: 10px;
@@ -338,23 +425,26 @@ export default {
font-size: 12px;
color: #999;
margin-top: 4px;
+ text-align: center;
}
- ::v-deep .el-form-item {
- margin-bottom: 10px !important; // 留间距给错误提示,不被遮挡
- width: 100%; // 占满单元格,提示有足够显示空间
+ ::v-deep .el-form-item {
+ margin-bottom: 10px !important;
+ width: 100%;
display: flex;
flex-direction: column;
- align-items: center; // 内容居中,适配表格
+ align-items: center;
}
- ::v-deep .el-form-item__error {
- position: static !important; // 取消默认绝对定位,避免跑出表格
+
+ ::v-deep .el-form-item__error {
+ position: static !important;
padding: 0 !important;
- margin-top: 2px !important; // 贴紧输入框下方
- font-size: 18px !important; // 小字体适配表格单元格
+ margin-top: 2px !important;
+ font-size: 12px !important;
line-height: 1.2 !important;
- white-space: nowrap; // 提示文字不换行
- text-align: center; // 居中显示,和表格风格统一
+ white-space: nowrap;
+ text-align: center;
+ color: #f56c6c;
}
}
diff --git a/src/views/order/bankReceiptDetail.vue b/src/views/order/bankReceiptDetail.vue
index 2e7635e..c493c97 100644
--- a/src/views/order/bankReceiptDetail.vue
+++ b/src/views/order/bankReceiptDetail.vue
@@ -558,7 +558,7 @@ export default {
margin-left: 25px;
margin-right: 10px;
display: flex;
- align-items: end;
+ align-items: flex-end;
.delete-btn {
display: flex;
diff --git a/src/views/order/category.vue b/src/views/order/category.vue
index 5d1c443..1ff33cc 100644
--- a/src/views/order/category.vue
+++ b/src/views/order/category.vue
@@ -78,10 +78,10 @@ export default {
mounted(){
console.log('this.$route---------------',this.$route)
console.log('this.routeData---------------',this.routeData)
- let arr = [
- {name:'工作台',url:'/wel'}
- ]
- this.$store.commit('SET_ROUTE_DATA',arr)
+ // let arr = [
+ // {name:'工作台',url:'/wel'}
+ // ]
+ // this.$store.commit('SET_ROUTE_DATA',arr)
this.getCategoryList()
// 点击页面空白处关闭右键菜单
document.addEventListener('click', this.closeContextMenu)
diff --git a/src/views/order/month.vue b/src/views/order/month.vue
index 1f3db0d..84e4306 100644
--- a/src/views/order/month.vue
+++ b/src/views/order/month.vue
@@ -55,14 +55,24 @@ export default {
};
},
computed: {
- ...mapGetters(["routeData"]),
+ ...mapGetters(["routeData"]),
+ // 从Vuex获取核心数据
+ ...mapGetters("order", [
+ "getProductSelectState", // 产品选择状态
+ "getProductSelectCustomerId", // 客户ID
+ "getSelectedSubcategoryIds", // 已选小类ID列表
+ "getTempOrderInfo",
+ "getOrderProductEdit",
+ "getOrderMode",
+ "getCurrentOrderId",
+ ]),
},
mounted() {
// 先获取年份参数,再调用接口(调整顺序避免year为空)
this.year = this.$route.query.year;
this.getTemplateDataFromApi();
// 初始化面包屑
- this.$store.commit("SET_ROUTE_DATA", [{ name: "工作台", url: "/wel" }]);
+ // this.$store.commit("SET_ROUTE_DATA", [{ name: "工作台", url: "/wel" }]);
},
methods: {
async getTemplateDataFromApi() {
@@ -148,8 +158,8 @@ export default {
path: "/order/addEdit",
query: {
temData: JSON.stringify(selectedTemplates),
- mode: this.$route.query.mode ? this.$route.query.mode : "",
- orderId: this.$route.query.orderId ? this.$route.query.orderId : "",
+ mode: this.getOrderMode,
+ orderId: this.getCurrentOrderId,
},
});
},
@@ -178,7 +188,7 @@ export default {
// 按钮栏
.btn-group {
display: flex;
- justify-content: end;
+ justify-content: flex-end;
}
// 月份分组容器
@@ -194,7 +204,7 @@ export default {
}
// 模板卡片列表
- .prodct_list{
+ .product_list{
display: flex;
flex-wrap: wrap;
margin-top: 15px;
@@ -225,6 +235,72 @@ export default {
}
}
}
+ // 模板卡片列表
+ .product_list {
+ display: flex;
+ flex-wrap: wrap;
+ margin-top: 15px;
+ // 移除左右 padding,改为用 auto 实现水平居中
+ padding: 0;
+ // 让容器在页面中水平居中
+ margin: 15px auto 0;
+ // 固定一行5个的总宽度(元素宽度+间距)
+ width: calc( (10.42vw + 5vw) * 5 - 5vw );
+ // 让元素均匀分布,两侧留白一致
+ justify-content: flex-start;
+ gap: 5vw;
+ // 模板卡片
+ .product_item {
+ width: 10.42vw;
+ height: 10.42vw;
+ border-radius: 2.08vw;
+ background: #f1ab46;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: #fff;
+ font-size: 2.5vw;
+ text-align: center;
+ cursor: pointer;
+ &:hover {
+ background: #ecb76c;
+ }
+ position: relative;
+ padding: 0 0.5vw;
+ box-sizing: border-box;
+
+ // 选中状态样式
+ &.selected {
+ background: #e0a860;
+ }
+
+ .item-name {
+ width: 100%;
+ height: 80%;
+ display: -webkit-box;
+ -webkit-line-clamp: 4;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+
+ // 选中对勾
+ .item-check {
+ position: absolute;
+ bottom: 10px;
+ right: 10px;
+ width: 1.5vw;
+ height: 1.5vw;
+ background: #1890ff;
+ color: #fff;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 1vw;
+ border-radius: 6px;
+ }
+ }
+ }
}
}
diff --git a/src/views/order/orderAddEdit.vue b/src/views/order/orderAddEdit.vue
index 073f53e..7fb5967 100644
--- a/src/views/order/orderAddEdit.vue
+++ b/src/views/order/orderAddEdit.vue
@@ -1,10 +1,10 @@
-
-
+
+
{{
- mode === "add" ? "订单新增" : mode === "edit" ? "订单编辑" : "订单查看"
+ vuexParams.mode === "add" ? "订单新增" : vuexParams.mode === "edit" ? "订单编辑" : "订单查看"
}}
@@ -15,55 +15,53 @@
@click="handleSave('add')"
class="el-button--big"
v-if="!isViewMode"
- >保存
+ >保存
保存并提交
+ style="margin: 0 20px;"
+ >保存并提交
取消
+ >取消
+
订单的基本信息
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -196,38 +192,34 @@
订单项目信息
- 新增项目
- 选择历史项目
+ 新增项目
+ 选择历史项目
-
+
-
@@ -235,14 +227,14 @@
-
+
{{ scope.row.standardPrice }}
@@ -252,7 +244,7 @@
{{ scope.row.sellingPrice }}
-
+
{{ scope.row.splitPrice }}
@@ -261,38 +253,30 @@
选择产品
+ >选择产品
编辑产品
+ >编辑产品
查看产品
+ >查看产品
- 删除
-
+ >删除
+
确定
-