feat: 坯布出仓增加操作语音并精简扫码明细

This commit is contained in:
2026-10-13 17:13:01 +08:00
parent 322ada8428
commit 7b199ba559
14 changed files with 78 additions and 159 deletions
+7 -61
View File
@@ -61,6 +61,12 @@ export const STATUS_ACTION_CONFIG = {
unapprove: { status: AUDIT_STATUS.PENDING, msg: '确认消审该单据?', apiKey: 'statusWait' },
};
/** 审核 / 作废成功后播放的语音文案 */
export const STATUS_ACTION_VOICE = {
approve: '审核成功',
void: '作废成功',
};
// 出仓类型:当前后端仅提供「坯布其他出货单」一种类型的接口
export const BILL_TYPES = [
{ value: 'other', label: '坯布其他出货单' },
@@ -147,17 +153,7 @@ export function normalizeOrder(order) {
};
}
/** 扫码详情区表格列 */
export const SCAN_DETAIL_TABLE_COLUMNS = [
{ label: '坯布编号', key: 'grey_fabric_code', width: 140 },
{ label: '坯布名称', key: 'grey_fabric_name', width: 140 },
{ label: '纱批', key: 'yarn_batch', width: 120 },
{ label: '机号', key: 'machine_number', width: 100 },
{ label: '条数', key: 'roll', width: 80 },
{ label: '重量', key: 'weight', width: 100 },
];
/** 扫码详情区汇总维度(勾选后参与表格分组;带 lock 的维度会随扫码请求传给后端) */
/** 扫码详情区汇总维度(勾选后随扫码请求把对应 lock 字段传给后端) */
export const SCAN_GROUP_OPTIONS = [
{ key: 'produce_order_no', label: '合同' },
{ key: 'grey_fabric_code', label: '布编' },
@@ -300,56 +296,6 @@ export function buildScanDetailFromContext(context, order) {
};
}
function aggregateScanTableRows(rows, keys) {
const map = new Map();
rows.forEach((row) => {
const groupId = keys.map((k) => row[k] || '').join('|');
const existing = map.get(groupId);
if (!existing) {
map.set(groupId, { ...row, roll: 0, raw_weight: 0 });
}
const agg = map.get(groupId);
agg.roll = Number((agg.roll + Number(row.roll || 0)).toFixed(2));
agg.raw_weight = Number(agg.raw_weight || 0) + Number(row.raw_weight || 0);
});
return Array.from(map.values()).map((row) => ({
...row,
weight: formatWeightKg(row.raw_weight),
}));
}
/** 构建扫码详情区汇总表格数据 */
export function buildScanDetailTableRows(itemData, groupKeys = []) {
const rows = [];
(itemData || []).forEach((item) => {
(item.fine_codes || []).forEach((fc) => {
rows.push({
customer_name: item.customer_name || '',
produce_order_no: item.produce_order_no || item.contract_no || '',
grey_fabric_code: item.grey_fabric_code || '',
grey_fabric_name: item.grey_fabric_name || '',
yarn_batch: item.yarn_batch || '',
machine_number: item.machine_number || '',
volume_number: fc.roll_no || fc.fabric_piece_code || '',
grey_fabric_level_name: item.grey_fabric_level_name || '',
roll: fc.roll || 0,
raw_weight: fc.raw_weight != null ? fc.raw_weight : 0,
});
});
});
if (!rows.length) return [];
const keys = (groupKeys || []).filter(Boolean);
if (!keys.length) {
return aggregateScanTableRows(rows, ['grey_fabric_code', 'grey_fabric_name', 'yarn_batch', 'machine_number']);
}
return aggregateScanTableRows(rows, keys);
}
export function getScanDetailTableWidth(columns) {
const total = (columns || []).reduce((sum, col) => sum + (col.width || 120), 0);
return `${total}rpx`;
}
export function normalizeItem(item) {
const machineStockRaw = item.machine_stock_roll ?? item.machine_stock ?? item.machine_inventory_roll;
return {
+51
View File
@@ -366,6 +366,56 @@ function playErrorAudio() {
errorAudio.play();
}
// 坯布出仓等业务的固定中文提示语音
const SPEAK_AUDIO = {
'扫码出仓成功': '/static/audio/scan_out_ok.mp3',
'删除成功': '/static/audio/delete_ok.mp3',
'提交成功': '/static/audio/submit_ok.mp3',
'审核成功': '/static/audio/audit_ok.mp3',
'作废成功': '/static/audio/void_ok.mp3',
};
const speakAudioMap = {};
function stopOtherSpeak(exceptText) {
Object.keys(speakAudioMap).forEach((key) => {
if (key === exceptText || !speakAudioMap[key]) return;
try {
speakAudioMap[key].stop();
} catch (e) {}
});
if (successAudio) {
try {
successAudio.stop();
} catch (e) {}
}
}
function playSpeak(text) {
const src = SPEAK_AUDIO[text];
if (!src) return;
stopOtherSpeak(text);
const prev = speakAudioMap[text];
if (prev) {
try {
prev.stop();
prev.destroy();
} catch (e) {}
speakAudioMap[text] = undefined;
}
const audio = uni.createInnerAudioContext();
audio.autoplay = true;
audio.src = src;
audio.onError((res) => {
console.log('语音播放失败', text, res && res.errMsg);
try {
audio.destroy();
} catch (e) {}
if (speakAudioMap[text] === audio) speakAudioMap[text] = undefined;
});
speakAudioMap[text] = audio;
}
export default {
get apiurl() {
@@ -378,4 +428,5 @@ export default {
parGetData,
playSuccessAudio,
playErrorAudio,
playSpeak,
};