Commit 433632d1 by linjinhong

fix:修改惠立彩图片处理逻辑

parent 6c8146f3
{"apiApiHost":"https://11factory.jomalls.com/api","fileApiUrl":"https://11factory.jomalls.com/upload/factory","visionUrl":"https://console.jomalls.com","configPath":"D:\\work\\electron-printer\\config\\env.json"}
\ No newline at end of file
{
"apiApiHost": "https://factory.jomalls.com/api",
"fileApiUrl": "https://factory.jomalls.com/upload/factory",
"visionUrl": "https://console.jomalls.com",
"configPath": "D:\\work\\electron-printer\\config\\env.json"
}
......@@ -140,13 +140,14 @@ export default {
CN: "factory/podJomallOrderProductCn/downloadDesignImages",
US: "factory/podJomallOrderProductUs/downloadDesignImages",
GC: "factory/podJomallOrder/downloadByProduction",
HLC: "factory/podJomallOrderProductUs/downloadCompatibleDesignImages",
USHLC: "factory/podJomallOrderProductUs/downloadCompatibleDesignImages",
CNHLC: "factory/podJomallOrderProductCn/downloadCompatibleDesignImages",
};
try {
let url = urlMap[params.orderType];
if (params.device == 3) {
url = urlMap["HLC"];
url = params.orderType == "CN" ? urlMap["CNHLC"] : urlMap["USHLC"];
}
const { data } = await axios.post(`${env}/${url}`, [...params.ids], {
headers: { "jwt-token": token },
......
const Store = require("electron-store");
const store = new Store({ watch: true });
// ===== 私有缓存 Map + 缓存刷新方法 =====
let orderCacheMap = new Map(); // 模块内私有缓存,key是最终唯一newId(如123_1
const DEFAULT_UNIQUE_KEY = "newId";
// ===== 1. 核心常量定义 =====
const DEFAULT_UNIQUE_KEY = "newId"; // 订单内部唯一标识字段(保持原始前缀
const MAX_LIMIT_RECORD_KEY = "originalIdMaxLimitRecord"; // 永久上限标记(保留你的原有逻辑)
// 刷新缓存:从 electron-store 读取数组,转为 Map 存入缓存
function refreshOrderCache(uniqueKey = DEFAULT_UNIQUE_KEY) {
const currentArray = store.get("orderInfo") || [];
const newMap = new Map();
currentArray.forEach((item) => {
if (item && item[uniqueKey]) {
newMap.set(item[uniqueKey], item);
}
});
orderCacheMap = newMap; // 更新缓存 Map
}
// 初始化缓存(模块加载时执行一次)
refreshOrderCache();
// ===== 2. 核心内存缓存 =====
let orderCacheMap = new Map(); // key格式:前缀-数字(如AAAF...-1),value:原始订单对象
// 辅助工具函数:将 Map 转回对象数组
function mapToArray(dataMap) {
return Array.from(dataMap.values());
// ===== 3. 永久上限标记方法(保留你的原有核心逻辑,无改动) =====
/**
* 获取已达永久上限的原始newId Map
* @returns {Map<string|number, boolean>} 永久上限标识Map
*/
function getMaxLimitFlagMap() {
const limitRecord = store.get(MAX_LIMIT_RECORD_KEY) || {};
return new Map(Object.entries(limitRecord));
}
// ===== 新增:处理重复 newId 的核心辅助方法(更新后缀为_,适配num固定上限) =====
/**
* 提取原始 newId(去除后缀 _1、_2 等,避免解析原始newId中的-)
* @param {string|number} uniqueValue 最终存储的唯一 newId(如 123_1)
* @returns {string|number} 原始 newId(如 123)
* 标记原始newId为永久上限(无法再添加)
* @param {string|number} originalNewId 原始newId前缀
*/
function getOriginalNewId(uniqueValue) {
if (typeof uniqueValue !== "string" && typeof uniqueValue !== "number") {
return uniqueValue;
}
const strValue = String(uniqueValue);
const suffixIndex = strValue.lastIndexOf("_"); // 改为 _ 分割后缀
// 判断是否是 任意字符_数字 格式的后缀,避免误拆正常包含_的newId
if (suffixIndex > 0 && /^\d+$/.test(strValue.slice(suffixIndex + 1))) {
return strValue.slice(0, suffixIndex);
function setPermanentMaxLimit(originalNewId) {
if (!originalNewId) return;
const limitMap = getMaxLimitFlagMap();
if (!limitMap.has(originalNewId)) {
limitMap.set(originalNewId, true);
store.set(MAX_LIMIT_RECORD_KEY, Object.fromEntries(limitMap));
console.log(`已标记 ${originalNewId} 为永久上限,后续无法再添加`);
}
return uniqueValue;
}
/**
* 统计相同原始 newId 的订单当前已添加数量
* @param {string|number} originalNewId 原始 newId
* @returns {number} 相同原始 newId 的已添加订单数量
* 判断原始newId是否已达永久上限
* @param {string|number} originalNewId 原始newId前缀
* @returns {boolean} 是否永久上限
*/
function countSameOriginalNewId(originalNewId) {
let count = 0;
orderCacheMap.forEach((item) => {
const itemOriginalId = getOriginalNewId(item[DEFAULT_UNIQUE_KEY]);
if (itemOriginalId === originalNewId) {
count++;
}
});
return count;
function isOriginalIdPermanentLimit(originalNewId) {
if (!originalNewId) return false;
const limitMap = getMaxLimitFlagMap();
return limitMap.has(originalNewId) && limitMap.get(originalNewId);
}
// ===== 4. 核心辅助方法(根据newId前缀查找最新订单,核心逻辑) =====
/**
* 处理单个订单的重复 newId,生成唯一 newId 并校验 num 上限
* @param {object} orderObj 传入的订单对象(必须携带 num 字段作为上限)
* @returns {object|null} 处理后的订单对象(带唯一 newId),超过上限返回 null
* 根据原始newId前缀,查找匹配的最新一条订单
* @param {string|number} targetNewId 原始newId前缀
* @returns {object|null} {cacheKey: 最新缓存key, order: 最新订单对象},无匹配返回null
*/
function handleDuplicateNewId(orderObj) {
if (!orderObj || !orderObj[DEFAULT_UNIQUE_KEY]) {
console.warn("订单无效:缺少必要的 newId 字段");
return null;
}
function getLatestOrderByPrefixNewId(targetNewId, type) {
if (!targetNewId || orderCacheMap.size === 0) return null;
// 正则匹配:以targetNewId开头,后跟-数字结尾(严格匹配cacheKey格式)
const prefixReg = new RegExp(`^${targetNewId}-(\\d+)$`);
let matchedKeyWithSuffix = [];
console.log(60, orderCacheMap);
// 遍历缓存,筛选匹配前缀的订单
orderCacheMap.forEach((order, cacheKey) => {
const regMatch = cacheKey.match(prefixReg);
if (regMatch) {
const suffix = parseInt(regMatch[1], 10) || 0;
matchedKeyWithSuffix.push({
cacheKey: cacheKey,
suffix: suffix,
order: order,
});
}
});
// 1. 校验 num 字段(必须是有效数字且大于0)
const numLimit = orderObj.num;
if (typeof numLimit !== "number" || numLimit <= 0 || isNaN(numLimit)) {
console.warn("订单无效:num 必须是大于 0 的有效数字(作为添加上限)");
// 无匹配结果返回null
if (matchedKeyWithSuffix.length === 0) {
console.log(`未找到以${targetNewId}为前缀的订单`);
return null;
}
// 2. 获取原始 newId + 统计当前已添加数量
const originalNewId = orderObj[DEFAULT_UNIQUE_KEY];
const existingCount = countSameOriginalNewId(originalNewId);
// ===== 核心新增:根据type过滤,只保留满足条件的条目 =====
if (type) {
// 传入type时才执行过滤,提高灵活性
matchedKeyWithSuffix = matchedKeyWithSuffix.filter((item) => {
const { order } = item;
// 1. 容错:判断saveImgList是否存在且为数组,避免报错
if (!order.saveImgList || !Array.isArray(order.saveImgList)) {
return false;
}
// 2. 查找是否存在:title===type 且 power===false
const matchImgItem = order.saveImgList.find((imgItem) => {
return imgItem.title === type && imgItem.power === false;
});
// 3. 存在则保留该条目,否则过滤掉
return !!matchImgItem;
});
if (matchedKeyWithSuffix.length === 0) {
console.log(
`未找到以${targetNewId}为前缀、且type=${type}(power=false)的订单`,
);
return null; // 直接返回null,终止后续逻辑,避免报错
}
}
// 按后缀降序排序,取最新一条
matchedKeyWithSuffix.sort((a, b) => b.suffix - a.suffix);
const latestItem = matchedKeyWithSuffix[0];
// 3. 校验:已添加数量 >= 上限,禁止添加
if (existingCount >= numLimit) {
console.warn(
`添加失败:${originalNewId} 已达到添加上限 ${numLimit},无法继续添加`,
);
// 无匹配结果返回null
if (matchedKeyWithSuffix.length === 0) {
console.log(`未找到以${targetNewId}为前缀的订单`);
return null;
}
// 4. 生成新的唯一 newId(原始Id_序号,序号=已存在数量+1),保留原始 num 上限(固定不修改)
const newUniqueId = `${originalNewId}_${existingCount + 1}`;
console.log(
`找到以${targetNewId}为前缀的最新订单,cacheKey:${latestItem.cacheKey},后缀:${latestItem.suffix}`,
);
return {
...orderObj,
[DEFAULT_UNIQUE_KEY]: newUniqueId,
// num: numLimit // 直接保留传入的 num 上限,无需修改
cacheKey: latestItem.cacheKey,
order: latestItem.order,
};
}
// ===== 5. 基础辅助方法(缓存刷新、格式转换) =====
/**
* 刷新内存缓存(从本地存储加载数据)
*/
function refreshOrderCache() {
const currentArray = store.get("orderInfo") || [];
const newCacheMap = new Map();
// 重新构建缓存key:前缀-数字,保持格式一致
currentArray.forEach((item) => {
if (item && item[DEFAULT_UNIQUE_KEY]) {
const itemPrefix = item[DEFAULT_UNIQUE_KEY];
// 查找该前缀对应的所有订单,生成连续后缀
const samePrefixItems = currentArray.filter(
(i) => i[DEFAULT_UNIQUE_KEY] === itemPrefix,
);
samePrefixItems.forEach((sameItem, index) => {
const cacheKey = `${itemPrefix}-${index + 1}`;
newCacheMap.set(cacheKey, sameItem);
console.log("cacheKey", cacheKey);
});
}
});
orderCacheMap = newCacheMap;
console.log("缓存已从本地存储刷新完成");
}
/**
* Map转数组(辅助批量操作)
* @param {Map} dataMap 待转换的Map
* @returns {Array} 转换后的数组
*/
function mapToArray(dataMap) {
return Array.from(dataMap.values());
}
// ===== 6. 初始化缓存(模块加载时执行) =====
refreshOrderCache();
// ===== 7. 公开API(暴露给外部调用,核心逻辑+原有基础配置) =====
module.exports = {
// 原有基础方法(保持不变,直接复用)
// === 原有基础配置方法(无改动,保留你的初始逻辑) ===
setVersion: (version) => {
store.set("desktoVersion", version);
},
getVersion: () => store.get("desktoVersion") || "print",
setNowDate: (version) => {
store.set("nowDate", version);
},
getNowDate: () => store.get("nowDate") || "",
setSkip: (value) => {
store.set("skipValue", value);
},
getSkipValue: () => store.get("skipValue") || 2,
setSkipVersion: (value) => {
store.set("skipVersion", value);
},
getSkipVersion: () => store.get("skipVersion") || "1.0",
setApi: (value) => {
store.set("hostApi", value);
},
......@@ -127,29 +193,44 @@ module.exports = {
visionUrl: "https://console.jomalls.com",
configPath: "",
},
setBoard: (version) => {
store.set("desktoBoard", version);
},
getBoard: () => store.get("desktoBoard") || 3,
setLocation: (version, locationKey) => {
if (!locationKey) return;
store.set(locationKey, version);
},
getLocation: (locationKey) => store.get(locationKey) || "",
getLocation: (locationKey) => {
if (!locationKey) return "";
return store.get(locationKey) || "";
},
setDesktopDevice: (version) => {
store.set("desktopDevice", version);
},
getDesktopDevice: () => store.get("desktopDevice") || 1,
// ===== 基于缓存 Map 优化的 orderInfo 方法(更新后) =====
getOrderInfo: () => {
return store.get("orderInfo");
},
getOrderInfoMap: () => {
return orderCacheMap;
},
setOrderInfo: (newData, uniqueKey = DEFAULT_UNIQUE_KEY) => {
// === 订单核心操作方法(最终逻辑,传入newId前缀处理最新一条) ===
/**
* 获取所有订单数据
* @returns {Array} 所有订单数组
*/
getOrderInfo: () => store.get("orderInfo") || [],
/**
* 获取订单内存缓存Map
* @returns {Map} 订单缓存Map
*/
getOrderInfoMap: () => orderCacheMap,
/**
* 批量设置订单(保留永久上限逻辑,不修改订单内部数据)
* @param {Array|Map} newData 待批量添加的订单数据
*/
setOrderInfo: (newData) => {
let newObjArray = [];
if (newData instanceof Map) {
newObjArray = mapToArray(newData);
......@@ -160,128 +241,299 @@ module.exports = {
return;
}
// 批量处理重复 newId + 校验 num 上限
const handledArray = [];
const batchOriginalIdCount = new Map();
newObjArray.forEach((item) => {
if (
!item ||
!item[uniqueKey] ||
!item[DEFAULT_UNIQUE_KEY] ||
typeof item.num !== "number" ||
!Number.isInteger(item.num) ||
item.num <= 0
) {
console.warn("批量添加跳过无效订单:缺少 newId 或 有效 num 上限");
console.warn("批量添加跳过无效订单:缺少newId或有效num永久上限");
return;
}
const originalNewId = item[uniqueKey];
const originalNewId = item[DEFAULT_UNIQUE_KEY];
const numLimit = item.num;
// 合并缓存中的计数和同批次内的计数
const cacheCount = countSameOriginalNewId(originalNewId);
const batchCount = batchOriginalIdCount.get(originalNewId) || 0;
const currentTotalCount = cacheCount + batchCount;
// 校验:当前总数量 >= 上限,禁止添加该订单
if (currentTotalCount >= numLimit) {
// 永久上限校验
if (isOriginalIdPermanentLimit(originalNewId)) {
console.warn(
`批量添加跳过:${originalNewId} 已达到添加上限 ${numLimit}`,
`批量添加跳过:${originalNewId} 已达到永久上限 ${numLimit},无法再添加`,
);
return;
}
// 生成唯一 newId(_ 后缀)
const newUniqueId = `${originalNewId}_${currentTotalCount + 1}`;
// 更新批次计数
batchOriginalIdCount.set(originalNewId, batchCount + 1);
// 存入处理后的数组(保留原始 num 上限)
handledArray.push({
...item,
[uniqueKey]: newUniqueId,
// 统计当前前缀对应的订单数量
let currentCount = 0;
orderCacheMap.forEach((cacheItem, cacheKey) => {
const prefixReg = new RegExp(`^${originalNewId}-(\\d+)$`);
if (cacheKey.match(prefixReg)) {
currentCount++;
}
});
});
// 写入 store 和缓存
store.set("orderInfo", handledArray);
const newMap = new Map();
handledArray.forEach((item) => {
if (item && item[uniqueKey]) {
newMap.set(item[uniqueKey], item);
// 上限校验
if (currentCount >= numLimit) {
console.warn(
`批量添加跳过:${originalNewId} 已达到永久上限 ${numLimit}`,
);
setPermanentMaxLimit(originalNewId);
return;
}
// 不修改订单内部数据,直接存入
handledArray.push(item);
if (currentCount + 1 === numLimit) {
setPermanentMaxLimit(originalNewId);
}
});
orderCacheMap = newMap;
// 写入本地存储并刷新缓存
store.set("orderInfo", handledArray);
refreshOrderCache();
console.log("批量订单已添加完成,缓存已更新");
},
addToOrderInfo: (newOrderObj, uniqueKey = DEFAULT_UNIQUE_KEY) => {
/**
* 单个添加订单(保留永久上限逻辑,不修改订单内部数据)
* @param {object} newOrderObj 待添加的单个订单
*/
addToOrderInfo: (newOrderObj) => {
if (
typeof newOrderObj !== "object" ||
newOrderObj === null ||
!newOrderObj[uniqueKey]
!newOrderObj[DEFAULT_UNIQUE_KEY]
) {
console.warn("添加失败:请传入包含 newId 的有效订单对象");
return;
}
if (
typeof newOrderObj.num !== "number" ||
!Number.isInteger(newOrderObj.num) ||
newOrderObj.num <= 0
) {
console.warn("添加失败:请传入包含 newId 的有效对象");
console.warn("添加失败:订单缺少有效num永久上限(正整数)");
return;
}
// 核心:处理重复 newId + 校验 num 上限,生成唯一标识
const handledOrder = handleDuplicateNewId(newOrderObj);
if (!handledOrder) return; // 超过上限或无效则直接返回
const originalNewId = newOrderObj[DEFAULT_UNIQUE_KEY];
const numLimit = newOrderObj.num;
const uniqueValue = handledOrder[uniqueKey];
// 写入缓存 Map
orderCacheMap.set(uniqueValue, handledOrder);
// 永久上限校验
if (isOriginalIdPermanentLimit(originalNewId)) {
console.warn(
`添加失败:${originalNewId} 已达到永久上限 ${numLimit},无法再添加`,
);
return;
}
// 同步到 electron-store
const newArray = mapToArray(orderCacheMap);
store.set("orderInfo", newArray);
},
// 统计当前前缀对应的订单数量
let currentCount = 0;
orderCacheMap.forEach((cacheItem, cacheKey) => {
const prefixReg = new RegExp(`^${originalNewId}-(\\d+)$`);
if (cacheKey.match(prefixReg)) {
currentCount++;
}
});
removeFromOrderInfo: (uniqueValue, uniqueKey = DEFAULT_UNIQUE_KEY) => {
// 直接操作缓存 Map
const targetObj = orderCacheMap.get(uniqueValue);
if (!targetObj) {
console.log(`未找到 ${uniqueKey}=${uniqueValue} 的对象,删除失败`);
// 上限校验
if (currentCount >= numLimit) {
console.warn(`添加失败:${originalNewId} 已达到永久上限 ${numLimit}`);
setPermanentMaxLimit(originalNewId);
return;
}
// 删除缓存中的对象(无需更新 num,因为 num 是固定上限)
orderCacheMap.delete(uniqueValue);
const newArray = mapToArray(orderCacheMap);
store.set("orderInfo", newArray);
// 不修改订单内部数据,追加写入
const originalOrderArray = store.get("orderInfo") || [];
originalOrderArray.push(newOrderObj);
store.set("orderInfo", originalOrderArray);
refreshOrderCache();
console.log(`成功删除 ${uniqueValue},num 作为固定上限无需更新`);
// 达到上限标记永久限制
if (currentCount + 1 === numLimit) {
setPermanentMaxLimit(originalNewId);
}
console.log(`订单 ${originalNewId} 已添加完成,缓存已更新`);
},
/**
* 查询:传入newId前缀,获取匹配的最新一条订单
* @param {string|number} targetNewId 原始newId前缀
* @returns {object|null} 最新订单对象
*/
getOrderInfoItem: (targetNewId, type) => {
const latestResult = getLatestOrderByPrefixNewId(targetNewId, type);
if (!latestResult) {
console.log(`无匹配${targetNewId}的最新订单`);
return null;
}
return latestResult.order;
},
updateOrderInfoItem: (
uniqueValue,
newOrderObj,
uniqueKey = DEFAULT_UNIQUE_KEY,
) => {
if (typeof newOrderObj !== "object" || newOrderObj === null) {
console.warn("修改失败:请传入有效对象");
/**
* 删除:传入newId前缀,只删除「saveImgList所有power都为true」的最新一条订单(避免误伤)
* @param {string|number} targetNewId 原始newId前缀
* @param {string} [type] 可选,订单筛选辅助类型(保留兼容)
*/
removeFromOrderInfo: (targetNewId) => {
if (!targetNewId || orderCacheMap.size === 0) {
console.log(`无有效参数或缓存为空,无法执行删除`);
return;
}
// 步骤1:获取targetNewId前缀对应的所有匹配订单(未过滤power)
const prefixReg = new RegExp(`^${targetNewId}-(\\d+)$`);
let matchedKeyWithSuffix = [];
orderCacheMap.forEach((order, cacheKey) => {
const regMatch = cacheKey.match(prefixReg);
if (regMatch) {
const suffix = parseInt(regMatch[1], 10) || 0;
matchedKeyWithSuffix.push({
cacheKey: cacheKey, // 保留唯一cacheKey
suffix: suffix,
order: order,
});
}
});
// 步骤2:无前缀匹配订单,直接返回
if (matchedKeyWithSuffix.length === 0) {
console.log(`未找到以${targetNewId}为前缀的订单`);
return;
}
// 步骤3:核心筛选:保留「saveImgList中所有power都为true」的订单
const qualifiedOrders = matchedKeyWithSuffix.filter((item) => {
const { order } = item;
// 容错1:saveImgList不存在或非数组,视为不满足条件
if (!order.saveImgList || !Array.isArray(order.saveImgList)) {
return false;
}
// 容错2:saveImgList为空数组,视为不满足条件
if (order.saveImgList.length === 0) {
return false;
}
// 核心判断:every() 验证所有条目都满足 power === true
return order.saveImgList.every((imgItem) => {
return !!imgItem && imgItem.power === true;
});
});
// 步骤4:无满足条件的订单,返回提示
if (qualifiedOrders.length === 0) {
console.log(
`未找到以${targetNewId}为前缀、且saveImgList所有power都为true的订单`,
);
return;
}
const targetObj = orderCacheMap.get(uniqueValue);
if (!targetObj) {
console.log(`未找到 ${uniqueKey}=${uniqueValue} 的对象,修改失败`);
// 步骤5:按后缀降序排序,取最新一条(只删这一条)
qualifiedOrders.sort((a, b) => b.suffix - a.suffix);
const latestQualifiedItem = qualifiedOrders[0];
const {
cacheKey: toDeleteCacheKey,
order: toDeleteOrder,
} = latestQualifiedItem;
// 步骤6:【核心修复】用「唯一cacheKey」精准匹配,只删除目标订单(避免误伤)
const originalOrderArray = store.get("orderInfo") || [];
// 先构建「本地订单数组」与「cacheKey」的映射关系(因为本地订单没有cacheKey,需要反向匹配)
const orderToCacheKeyMap = new Map();
originalOrderArray.forEach((item) => {
if (item && item[DEFAULT_UNIQUE_KEY]) {
const itemPrefix = item[DEFAULT_UNIQUE_KEY];
const samePrefixItems = originalOrderArray.filter(
(i) => i[DEFAULT_UNIQUE_KEY] === itemPrefix,
);
samePrefixItems.forEach((sameItem, index) => {
const itemCacheKey = `${itemPrefix}-${index + 1}`;
// 用「订单深拷贝字符串」作为map的key,避免引用问题(精准匹配订单)
const sameItemKey = JSON.stringify(sameItem);
orderToCacheKeyMap.set(sameItemKey, itemCacheKey);
});
}
});
// 精准过滤:只删除「cacheKey等于toDeleteCacheKey」的订单
const newOrderArray = originalOrderArray.filter((item) => {
const itemKey = JSON.stringify(item);
const itemCacheKey = orderToCacheKeyMap.get(itemKey) || "";
// 只保留「cacheKey不等于要删除的cacheKey」的订单,精准无误伤
return itemCacheKey !== toDeleteCacheKey;
});
// 步骤7:调试日志,确认过滤效果(避免全删)
console.log(`删除前订单数组长度:${originalOrderArray.length}`);
console.log(`删除后订单数组长度:${newOrderArray.length}`);
console.log(`要删除的目标cacheKey:${toDeleteCacheKey}`);
if (originalOrderArray.length - newOrderArray.length > 1) {
console.warn("警告!删除了超过1条订单,可能存在cacheKey重复问题");
return;
}
if (originalOrderArray.length === newOrderArray.length) {
console.warn("过滤失效!未删除任何订单");
return;
}
// 保留唯一 newId 和 原始 num 上限(禁止修改这两个字段,避免冲突)
const updatedObj = {
...targetObj,
...newOrderObj,
[uniqueKey]: targetObj[uniqueKey], // 锁定唯一 newId(_ 后缀格式)
num: targetObj.num, // 锁定 num 固定上限,不允许修改
};
orderCacheMap.set(uniqueValue, updatedObj);
const newArray = mapToArray(orderCacheMap);
store.set("orderInfo", newArray);
// 步骤8:加固写入本地存储+刷新缓存
store.set("orderInfo", newOrderArray);
refreshOrderCache();
console.log(
`成功删除${targetNewId}对应的订单(cacheKey:${toDeleteCacheKey},仅删除1条),缓存已更新`,
);
},
getOrderInfoItem: (uniqueValue) => {
const targetObj = orderCacheMap.get(uniqueValue);
return targetObj || null;
/**
* 更新:传入newId前缀,更新匹配的最新一条订单
* @param {string|number} targetNewId 原始newId前缀
* @param {object} newOrderFields 要更新的字段对象
*/
updateOrderInfoItem: (targetNewId, newOrderFields, type) => {
if (typeof newOrderFields !== "object" || newOrderFields === null) {
console.warn("修改失败:请传入有效字段对象");
return;
}
const latestResult = getLatestOrderByPrefixNewId(targetNewId, type);
console.log(targetNewId, latestResult);
if (!latestResult) {
console.log(`无匹配${targetNewId}的最新订单可修改`);
return;
}
const { cacheKey, order } = latestResult;
const originalOrderArray = store.get("orderInfo") || [];
// 合并更新字段,不修改订单内部核心数据
const newOrderArray = originalOrderArray.map((item) => {
if (JSON.stringify(item) === JSON.stringify(order)) {
return {
...item,
...newOrderFields,
};
}
return item;
});
// 写入本地存储并刷新缓存
store.set("orderInfo", newOrderArray);
refreshOrderCache();
console.log(
`成功更新${targetNewId}对应的最新订单(cacheKey:${cacheKey}),缓存已更新`,
);
},
clearMaxLimitRecord: () => {
return store.set(MAX_LIMIT_RECORD_KEY, {});
},
};
......@@ -20,7 +20,7 @@ const {
setApi,
setDesktopDevice,
getDesktopDevice,
getOrderInfo,
getOrderInfoMap,
getOrderInfoItem,
addToOrderInfo,
updateOrderInfoItem,
......@@ -104,7 +104,7 @@ export default {
"hsla(209, 100%, 56%, 0.73)",
"#c7158577",
],
faceType: "1",
faceType: "A",
};
},
computed: {
......@@ -179,25 +179,16 @@ export default {
item.productionFile,
getLocation("downloadLocation2"),
);
// this.$api.post("/copySingleImageFn", {
// imgPath: item.productionFile,
// targetPath: getLocation("downloadLocation1"),
// });
// this.$api.post("/copySingleImageFn", {
// imgPath: item.productionFile,
// targetPath: getLocation("downloadLocation2"),
// });
// this.$message.success("图片已发送目标文件夹下");
} catch (error) {
this.$message.error("发送失败");
console.log(error);
}
//更新数据到本地数据
updateOrderInfoItem(this.detail.newId, this.detail);
updateOrderInfoItem(this.detail.newId, this.detail, this.faceType);
}
console.log("updateOrderInfoItemitem", item);
console.log("本地数据updateOrderInfoItem:", getOrderInfo());
console.log("本地数据updateOrderInfoItem:", getOrderInfoMap());
}
},
// deep: true,
......@@ -259,9 +250,9 @@ export default {
if (canCallApi) {
console.log("生产完成");
removeFromOrderInfo(data.newId);
await removeFromOrderInfo(data.newId);
bus.$emit("busEmit", { value: data.newId, type: "completeMessage" });
console.log("本地数据removeFromOrderInfo:", getOrderInfo());
console.log("本地数据removeFromOrderInfo:", getOrderInfoMap());
//生产完成后在本地删除
return;
await this.$api.post("/completeDelivery", params);
......@@ -387,17 +378,7 @@ export default {
}
return new File([u8arr], fileName, { type: "image/png" });
},
// async downloadImage() {
// if (!this.detail || Object.keys(this.detail).length === 0)
// return this.$message.warning("请扫描生产单号");
// let params = {
// productionNo: this.detail.factorySubOrderNumber,
// imgList: this.imgList,
// };
// let res = await this.$api.post("/downloadByDesignId", params);
// this.$message.success(res.msg);
// },
async saveImgByUrl(url) {
try {
let res = await this.$api.post("/saveImgByUrl", { url });
......@@ -406,8 +387,10 @@ export default {
throw new Error(e.message); // 或者直接 throw e;
}
},
async hasDesignImagesCanvasJsonList(designImagesCanvasJsonList, bool) {
let imageResList = [];
//当adjustable有值时 直接赋值宽高
if (
!this.checked &&
this.detail.diyId &&
......@@ -443,23 +426,20 @@ export default {
// }
}
}
if (!imageResList.length && !bool) {
// console.log(347, this.orderType);
// 根据生产单号查找 素材图片 下载到本地 然后返回本地地址去显示
// 根据生产单号查找 素材图片 下载到本地 然后返回本地地址去显示
if (!imageResList.length && !bool) {
let res = await this.$api.post("/downloadBySubOrderNumber", {
ids: [this.detail.id],
device: this.$store.state.desktopDevice,
orderType: this.orderType,
});
// console.log("downloadBySubOrderNumber", res);
if (!res.data.length) return this.$message.warning("未找到素材图!");
res.data.forEach((el) => {
imageResList = imageResList.concat(el.list || []);
});
} else if (bool) {
//如果有本地数据 则直接获取本地数据同图片
imageResList = this.detail?.saveImgList || [];
console.log("imageResList", imageResList);
}
......@@ -476,7 +456,6 @@ export default {
if (imageResList.length) {
let pathUrl = imageResList[0].productionFile;
setTimeout(async () => {
// await this.focusExplorerWindow(pathUrl);
const pathParts = pathUrl.split("\\");
pathParts.pop();
// 使用 join() 将剩余部分重新拼接成路径
......@@ -522,7 +501,6 @@ export default {
type: "sendFile",
value: [...newImgList],
};
// console.log(387, obj);
if (
this.detail.mssWidth &&
......@@ -544,13 +522,16 @@ export default {
//如果该数据的图片第一次出现且素材图大于1张则把该数据储存到本地
if (newImgList.length > 1 && !bool) {
addToOrderInfo(this.detail);
console.log("本地数据addToOrderInfo", getOrderInfo());
console.log("本地数据addToOrderInfo", getOrderInfoMap());
}
if (this.desktopDevice == 3) obj.faceType = this.faceType;
bus.$emit("busEmit", obj);
}
},
async getDataInfo() {
//查询后先检查当前是否有数据,有则先走生产完成
if (
this.detail &&
Object.keys(this.detail).length > 0 &&
......@@ -558,13 +539,13 @@ export default {
) {
await this.setData(this.detail);
}
//判断生产单号是否为空
if (this.productionNo === "")
return this.$message.warning("请录入生产单号");
const today = moment(new Date()).format("YYYY-MM-DD");
console.log("today", today);
//判断上一单未勾选是否跳过
if (!this.isAutoFinish && today != getNowDate()) {
this.$confirm("请注意自动完成上一单未勾选", "提示", {
confirmButtonText: "跳过提示",
......@@ -576,11 +557,10 @@ export default {
});
}
//判断生产单号是US CN GC(老pod),并设置 setOrderType
if (this.productionNo.includes("_")) {
const parts = this.productionNo.split("_");
// 查找第一个包含"PSC"的片段
const pscPart = parts.find((part) => part.includes("PSC"));
if (pscPart) {
this.$store.commit(
"setOrderType",
......@@ -604,13 +584,11 @@ export default {
}
try {
//获取本地数组
const arr = await getOrderInfo();
//查询当前生产单号是否在本地数据
const localItem = getOrderInfoItem(this.productionNo)
? { data: getOrderInfoItem(this.productionNo) }
const localItem = getOrderInfoItem(this.productionNo, this.faceType)
? { data: getOrderInfoItem(this.productionNo, this.faceType) }
: null;
console.log("本地数据getOrderInfoItem", getOrderInfo());
console.log("本地数据getOrderInfoItem", getOrderInfoMap());
let findByPodProductionNo;
const apiRequestParams = {
thirdSubOrderNumber: this.productionNo,
......@@ -620,20 +598,9 @@ export default {
//判断是否为惠立彩
if (this.desktopDevice === 3) {
if (arr.length > 0) {
//如果查询到生产单号 直接复制否则调用接口获取详情
findByPodProductionNo =
localItem ||
(await this.$api.post(
"/findByPodProductionNo",
apiRequestParams,
));
} else {
findByPodProductionNo = await this.$api.post(
"/findByPodProductionNo",
apiRequestParams,
);
}
findByPodProductionNo =
localItem ||
(await this.$api.post("/findByPodProductionNo", apiRequestParams));
} else {
findByPodProductionNo = await this.$api.post(
"/findByPodProductionNo",
......@@ -643,9 +610,12 @@ export default {
this.detail = findByPodProductionNo.data;
//赋值当前扫码为生产单号的标识
this.detail["newId"] = this.productionNo;
if (!this.detail["newId"]) {
this.detail["newId"] = this.productionNo;
}
let designImagesCanvasJsonList = this.detail.drParam;
//获取下载素材
await this.hasDesignImagesCanvasJsonList(
designImagesCanvasJsonList,
this.desktopDevice === 3 ? (localItem ? true : false) : false,
......@@ -1076,8 +1046,8 @@ export default {
<div>当前打印:</div>
<el-select v-model="faceType" placeholder="请选择" class="FaceType">
<el-option label="A面 / 正面" value="1"></el-option>
<el-option label="B面 / 反面" value="2"></el-option>
<el-option label="A面 / 正面" value="A"></el-option>
<el-option label="B面 / 反面" value="B"></el-option>
</el-select>
</div>
</div>
......
......@@ -77,7 +77,13 @@ export default {
unitToPx,
getCurrentItem(item) {
// let setting = this.$dataStore.get("setting");
this.item.y = item.y - item.h / 2;
if (item.y != 0) {
this.item.y = item.y - item.h / 2;
console.log(93, item);
} else {
item.y == 0;
}
this.item.x = item.x - item.w / 2;
this.$dataStore.set(
"position_before_px",
......
......@@ -17,8 +17,9 @@ const {
getDesktopDevice,
setLocation,
getLocation,
getOrderInfo,
getOrderInfoMap,
setOrderInfo,
clearMaxLimitRecord,
} = require("@/server/utils/store");
export default {
......@@ -122,7 +123,7 @@ export default {
},
returnItem() {
// console.log(128, this.imgList);
console.log("returnItem", this.imgList[this.selectIndex]);
if (this.selectIndex < 0 && this.imgList.length) {
// this.showImgSetting = false;
......@@ -132,9 +133,9 @@ export default {
// console.log("item", item);
if (item) {
item = JSON.parse(JSON.stringify(item));
item.x = Number(item.x) - Number(item.w);
item.y = Number(item.y) + Number(item.h) / 2;
// item = JSON.parse(JSON.stringify(item));
// item.x = Number(item.x) - Number(item.w);
// item.y = 0;
return JSON.parse(JSON.stringify(this.imgList[this.selectIndex]));
}
this.showImgSetting = false;
......@@ -212,12 +213,17 @@ export default {
downloadLocation2: getLocation("downloadLocation2"),
logList: [],
activeName: "1",
localeData: getOrderInfo(),
localeData: getOrderInfoMap(),
faceType: "",
expandStatus: {},
};
},
watch: {
imgList: {
async handler(newValue) {
console.log(223, newValue);
console.log(223, this.returnItem);
const image = document.getElementById("imgBox");
if (newValue.length && image) {
......@@ -289,6 +295,8 @@ export default {
// `获取当前图片在压板中的大小公式:\n 宽度:${image?.clientWidth}(image.clientWidth)px /${this.WHproportion}(扩大比例)=${w}\n 高度:${image?.clientHeight}(image.clientHeight)px /${this.WHproportion}(扩大比例)=${h}`,
// );
}
// console.log("触发了");
// console.log("newValue", newValue);
this.$store.commit("changeImgList", this.imgList);
},
......@@ -504,7 +512,7 @@ export default {
},
indexChange(v) {
// console.log(v);
console.log("indexChange");
if (this.imgList.length === 0) return;
let index = !this.imgList[this.selectIndex] ? 0 : this.selectIndex;
......@@ -626,6 +634,8 @@ export default {
break;
case "x_center":
this.$set(this.imgList[this.selectIndex], "x", Number(w));
this.$set(this.imgList[this.selectIndex], "y", 0);
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
break;
case "y_center":
......@@ -657,6 +667,7 @@ export default {
}
},
formChange(form) {
console.log("formChange");
// if (this.selectIndex === -1) this.selectIndex = 0
if (!this.imgList[this.selectIndex]) return;
let f = JSON.parse(JSON.stringify(form));
......@@ -676,12 +687,15 @@ export default {
this.showImgSetting = false;
},
dragStop(data, item) {
console.log("dragStop");
this.$set(item, "y", data.y);
this.$set(item, "x", data.x);
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
this.getCutArea();
},
resizeStop(data, item) {
console.log("resizeStop");
if (this.selectIndex < 0 && this.imgList.length) this.selectIndex = 0;
this.$set(item, "y", data.y);
this.$set(item, "w", data.w);
......@@ -786,32 +800,33 @@ export default {
let h = bh / 2;
let width_px, height_px, rate, x, y;
let data = await that.getImageSize(files[i].url);
console.log("w", w);
console.log("h", h);
if (size && !files[i].isCut) {
// console.log("size", size);
console.log("size", size);
width_px = that.WHproportion * mmToPx(size.width);
height_px = that.WHproportion * mmToPx(size.height);
x = w * that.WHproportion;
y = (height_px / 2) * that.WHproportion;
y = h * that.WHproportion;
rate = height_px / width_px;
} else {
// console.log("data", data);
console.log("data", data);
rate = data.height / data.width;
// console.log(679, rate);
if (rate > 1) {
height_px = bh * (7.5 / 10);
// width_px = height_px / rate > bw ? bw : height_px / rate;
width_px = height_px / rate;
x = width_px / 2;
y = h;
x = w;
y = height_px / 2;
} else {
width_px = bw * (2 / 3);
// height_px = width_px * rate > bh ? bh : width_px * rate;
height_px = width_px * rate;
x = w;
y = height_px / 2;
x = width_px / 2;
y = h;
}
}
this.currentImgData = { ...data };
......@@ -830,9 +845,10 @@ export default {
that.selectIndex = that.imgList.length - 1;
that.showImgSetting = true;
that.$nextTick(() => {
that.ev("center");
});
// that.$nextTick(() => {
// that.ev("x_center");
// });
// setTimeout(() => {
// that.ev("center");
// }, 1000);
......@@ -845,6 +861,8 @@ export default {
addFile(file, callback) {
let that = this;
let bw = document.getElementById("line").clientWidth;
console.log("addFile");
// let bh = document.getElementById("line").clientHeight;
that.$nextTick(() => {
that.getImageSize(file.url).then((data) => {
......@@ -1040,7 +1058,7 @@ export default {
async downloadImg(type) {
let res = await this.$api.post("/downloadBySubOrderNumber", {
ids: [this.detail.id],
device: this.$store.state.desktopDevice,
device: this.newDesktopDevice,
orderType: this.orderType,
});
if (res.data.length === 0) return this.$message.warning("未找到素材图!");
......@@ -1236,8 +1254,22 @@ export default {
},
clearLocalFn() {
setOrderInfo([]);
clearMaxLimitRecord([]);
this.localeData = [];
},
// 切换单个 Map Key 的展开/收起状态
toggleExpand(mapKey) {
// 用 $set 确保响应式(Map Key 可能为非字符串类型)
this.$set(this.expandStatus, mapKey, !this.expandStatus[mapKey]);
},
// 格式化 Map Value,美化排版,保留所有内部 key
formatJson(data) {
if (typeof data !== "object" || data === null) {
return JSON.stringify(data, null, 2);
}
// 自动保留 Value 内部的所有 key,美化缩进
return JSON.stringify(data, null, 2);
},
},
mounted() {
this.imgHeight = window.screen.height + "px";
......@@ -1249,7 +1281,7 @@ export default {
switch (type) {
case "completeMessage":
this.logList.unshift(`订单:${value}生产完成`);
this.localeData = getOrderInfo();
this.localeData = getOrderInfoMap();
break;
case "grid":
this.row = value.row;
......@@ -1275,7 +1307,6 @@ export default {
case "sendFile":
this.hasSize = !!size;
this.detail.designImageSize = size;
// console.log(this.detail, "this.detail");
this.imgList = [];
this.selectImgList = [];
......@@ -1284,10 +1315,13 @@ export default {
this.selectImgList = value;
if (this.newDesktopDevice == 3) {
const index = this.selectImgList.findIndex(
(el) => el.power === false,
);
this.selectImgIndex = index;
if (v.faceType) {
this.faceType = v.faceType;
const index = this.selectImgList.findIndex(
(el) => el.title === v.faceType,
);
this.selectImgIndex = index;
}
} else {
this.selectImgIndex = 0;
}
......@@ -1305,7 +1339,7 @@ export default {
);
}
}
this.localeData = getOrderInfo();
this.localeData = getOrderInfoMap();
break;
default:
break;
......@@ -1408,7 +1442,7 @@ export default {
{{ img.title }}
</div>
<div
v-if="img.power && i != selectImgList.length - 1"
v-if="img.power && img.title != faceType"
class="printTitle"
>
已打印
......@@ -1755,7 +1789,7 @@ export default {
</div>
</div>
</div>
<!-- <div
<div
class="print-tip"
:style="{ left: isView ? '' : '22%' }"
v-if="
......@@ -1769,7 +1803,7 @@ export default {
>该生产单无需拖动设计,直接打印</b
>
<b style="color: red" v-else>该生产单需要拖动设计打印</b>
</div> -->
</div>
</div>
<img
......@@ -1811,15 +1845,24 @@ export default {
v-html="formatLog(value)"
></div>
</el-tab-pane>
<el-tab-pane label="本地数据" name="2" class="tabBox"
><div
v-for="(value, index) in localeData"
:key="index"
<el-tab-pane label="本地数据" name="2" class="tabBox">
<div
v-for="(mapValue, mapKey) in localeData"
:key="mapKey"
class="localItem"
>
<pre class="json-pre">{{
JSON.stringify(value, null, 2)
}}</pre>
<!-- ① 展开/收起切换 + 直接展示 Map 原始 key -->
<div class="json-toggle" @click="toggleExpand(mapKey)">
{{ expandStatus[mapKey] ? "▼" : "▶" }} 订单标识:{{
mapValue[0]
}}
</div>
<!-- ② 展开后展示 Map Value,保留原有 json-pre 样式 -->
<pre v-if="expandStatus[mapKey]" class="json-pre"
>{{ formatJson(mapValue) }}
</pre
>
</div></el-tab-pane
>
</el-tabs>
......@@ -2349,4 +2392,75 @@ img {
.status-complete {
color: #85ce61;
}
.logBox {
flex: 1;
height: 100%;
.tabBox {
padding: 0 10px;
font-size: 12px;
height: 100%;
.localItem {
margin-bottom: 10px;
}
// 新增:展开/收起切换按钮
.json-toggle {
cursor: pointer;
font-size: 12px;
margin: 4px 0;
color: #1890ff;
user-select: none;
}
.json-toggle:hover {
color: #40a9ff;
}
// 新增:JSON 内容容器
.json-content {
margin-left: 20px;
padding-left: 10px;
border-left: 1px dashed #e8e8e8;
}
// 新增:嵌套内容缩进
.nested {
margin-left: 20px;
}
// 新增:JSON 项和值
.json-view {
font-family: "Courier New", Courier, monospace;
}
.json-item {
margin: 2px 0;
}
.json-value {
font-size: 12px;
color: #666;
margin: 4px 0;
}
// 保留你原有的 json-pre 样式(可复用)
.json-pre,
.json-view {
white-space: pre-wrap; /* 关键:允许换行 */
word-break: break-word; /* 允许在单词内换行 */
word-wrap: break-word; /* 旧版属性,为了兼容性 */
overflow-wrap: break-word; /* 现代标准 */
font-family: "Courier New", Courier, monospace;
font-size: 12px;
line-height: 1.4;
margin: 0;
padding: 8px;
background: #f5f5f5;
border-radius: 3px;
border: 1px solid #e8e8e8;
}
}
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment