From 567da03aea9707df2460b77e13d660b93e145cd0 Mon Sep 17 00:00:00 2001
From: xuan <1359774872@qq.com>
Date: Wed, 17 Jun 2026 16:59:31 +0800
Subject: [PATCH] =?UTF-8?q?feat(storefabric):=20=E6=96=B0=E5=A2=9E?=
=?UTF-8?q?=E5=9D=AF=E5=B8=83=E5=87=BA=E5=BA=93=E7=9B=B8=E5=85=B3=E9=A1=B5?=
=?UTF-8?q?=E9=9D=A2=E5=8F=8A=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 在 manifest.json 中添加 Android 包名配置
- 在 package.json 中添加 pnpm 依赖覆盖配置
- 在 pages.json 中注册坯布出库相关页面路由
- 重命名 storefabricBusinessOutAdd.vue 为 storeFabricBusinessOutAdd.vue
- 重构坯布出库新增页面,优化界面布局和交互逻辑
- 添加坯布出库列表、编辑、查看等功能页面
- 集成订单状态栏、面料信息弹窗、细码弹窗等组件
- 实现坯布出库详情列表和扫码功能模块
- 优化表单验证和数据提交流程
---
package.json | 5 +
src/common/storeFabricBusinessOut.js | 549 +++++++++
.../card/storeFabricBusinessOutItem.vue | 66 +
.../storefabric/FabricInfoPopup.vue | 73 ++
.../storefabric/FabricOutDetailList.vue | 36 +
.../storefabric/FabricOutFooter.vue | 27 +
.../storefabric/FabricOutScanBar.vue | 38 +
.../storefabric/FabricOutScanDetail.vue | 154 +++
src/components/storefabric/FineCodePopup.vue | 160 +++
src/components/storefabric/OrderStatusBar.vue | 49 +
src/manifest.json | 1 +
src/pages.json | 28 +
.../storefabric/storeFabricBusinessOutAdd.vue | 214 ++++
.../storeFabricBusinessOutEdit.vue | 95 ++
.../storeFabricBusinessOutList.vue | 268 +++++
.../storeFabricBusinessOutMixin.js | 404 +++++++
.../storeFabricBusinessOutPage.scss | 160 +++
.../storeFabricBusinessOutView.vue | 145 +++
.../storefabric/storefabricBusinessOutAdd.vue | 1057 -----------------
默认模块.openapi.json | 593 +++++++++
20 files changed, 3065 insertions(+), 1057 deletions(-)
create mode 100644 src/common/storeFabricBusinessOut.js
create mode 100644 src/components/card/storeFabricBusinessOutItem.vue
create mode 100644 src/components/storefabric/FabricInfoPopup.vue
create mode 100644 src/components/storefabric/FabricOutDetailList.vue
create mode 100644 src/components/storefabric/FabricOutFooter.vue
create mode 100644 src/components/storefabric/FabricOutScanBar.vue
create mode 100644 src/components/storefabric/FabricOutScanDetail.vue
create mode 100644 src/components/storefabric/FineCodePopup.vue
create mode 100644 src/components/storefabric/OrderStatusBar.vue
create mode 100644 src/pages/storefabric/storeFabricBusinessOutAdd.vue
create mode 100644 src/pages/storefabric/storeFabricBusinessOutEdit.vue
create mode 100644 src/pages/storefabric/storeFabricBusinessOutList.vue
create mode 100644 src/pages/storefabric/storeFabricBusinessOutMixin.js
create mode 100644 src/pages/storefabric/storeFabricBusinessOutPage.scss
create mode 100644 src/pages/storefabric/storeFabricBusinessOutView.vue
delete mode 100644 src/pages/storefabric/storefabricBusinessOutAdd.vue
create mode 100644 默认模块.openapi.json
diff --git a/package.json b/package.json
index 1ece49e..b85b13c 100644
--- a/package.json
+++ b/package.json
@@ -117,6 +117,11 @@
"Android >= 4.4",
"ios >= 9"
],
+ "pnpm": {
+ "overrides": {
+ "postcss-urlrewrite": "0.3.0"
+ }
+ },
"uni-app": {
"scripts": {}
}
diff --git a/src/common/storeFabricBusinessOut.js b/src/common/storeFabricBusinessOut.js
new file mode 100644
index 0000000..665dbc5
--- /dev/null
+++ b/src/common/storeFabricBusinessOut.js
@@ -0,0 +1,549 @@
+/**
+ * 坯布出仓单(其他出货单)常量与数据工具
+ *
+ * 仅存放与接口无关的常量 / 状态映射 / 字段规范化 / 单位换算等纯工具,
+ * 真实接口请求统一注册在 src/common/http.api.js 的 vm.$u.api.gfmOtherDeliveryOrder 下。
+ */
+import dayjs from 'dayjs';
+
+// 审核状态(对应 openapi common.OrderStatus)
+export const AUDIT_STATUS = {
+ PENDING: 1, // 待审核
+ APPROVED: 2, // 已审核
+ REJECTED: 3, // 已驳回
+ VOIDED: 4, // 已作废
+};
+
+/** 前端草稿态(未保存) */
+export const DRAFT_AUDIT_STATUS = 0;
+export const DRAFT_AUDIT_STATUS_NAME = '待保存';
+
+export const AUDIT_STATUS_MAP = {
+ 1: '待审核',
+ 2: '已审核',
+ 3: '已驳回',
+ 4: '已作废',
+};
+
+/** 坯布资料弹窗字段 */
+export const FABRIC_INFO_FIELDS = [
+ { label: '坯布编号', key: 'grey_fabric_code' },
+ { label: '名称', key: 'grey_fabric_name' },
+ { label: '客户', key: 'customer_name' },
+ { label: '幅宽', key: 'grey_fabric_width' },
+ { label: '克重', key: 'grey_fabric_gram_weight' },
+ { label: '纱批', key: 'yarn_batch' },
+ { label: '针寸数', key: 'needle_size' },
+ { label: '原料纱名称', key: 'raw_material_yarn_name' },
+ { label: '原料批号', key: 'raw_material_batch_num' },
+ { label: '原料品牌', key: 'raw_material_batch_brand' },
+ { label: '颜色', key: 'gray_fabric_color_name' },
+ { label: '等级', key: 'grey_fabric_level_name' },
+ { label: '机台号', key: 'machine_number' },
+ { label: '织造工艺', key: 'weaving_process' },
+ { label: '坯布备注', key: 'grey_fabric_remark' },
+];
+
+/** 细码表格列(不含操作列) */
+export const FINE_CODE_TABLE_COLUMNS = [
+ { label: '序号', key: 'seq', width: 70 },
+ { label: '卷号', key: 'roll_no', width: 90 },
+ { label: '匹数', key: 'roll', width: 90 },
+ { label: '数量(重量)', key: 'weight', width: 120 },
+ { label: '条码', key: 'bar_code', width: 260 },
+ { label: '仓位', key: 'position', width: 110 },
+];
+
+/** 审核状态变更操作配置(apiKey 对应 gfmOtherDeliveryOrder 下的方法名) */
+export const STATUS_ACTION_CONFIG = {
+ approve: { status: AUDIT_STATUS.APPROVED, msg: '确认审核该单据?', apiKey: 'statusPass' },
+ void: { status: AUDIT_STATUS.VOIDED, msg: '确认作废该单据?', apiKey: 'statusCancel' },
+ unapprove: { status: AUDIT_STATUS.PENDING, msg: '确认消审该单据?', apiKey: 'statusWait' },
+};
+
+// 出仓类型:当前后端仅提供「坯布其他出货单」一种类型的接口
+export const BILL_TYPES = [
+ { value: 'other', label: '坯布其他出货单' },
+];
+
+/** 列表分页拉取每页条数 */
+export const LIST_PAGE_SIZE = 100;
+
+export function getStatusOptions() {
+ return Object.keys(AUDIT_STATUS_MAP).map((value) => ({
+ value,
+ label: AUDIT_STATUS_MAP[value],
+ }));
+}
+
+/** 将下拉/列表接口响应转为 u-select 所需的 { value, label } */
+export function mapToSelectOptions(data) {
+ const list = Array.isArray(data) ? data : (data && (data.list || data.items || data.records)) || [];
+ return list.map((item) => ({
+ value: item.id,
+ label: item.name || item.label || item.code || String(item.id),
+ }));
+}
+
+// 匹数:后端以 0.01 匹存储(乘以100的整数),展示需除以100
+export function formatRoll(value) {
+ const n = Number(value || 0) / 100;
+ return Number.isInteger(n) ? n : Number(n.toFixed(2));
+}
+
+// 重量:后端整数存储(×10000),展示需除以 10000 为 KG
+export function formatWeightKg(value) {
+ const n = Number(value || 0) / 10000;
+ return Number(n.toFixed(2));
+}
+
+/** 从详情对象取展示用总重量(优先用原始值换算) */
+export function getOrderDisplayWeight(order) {
+ if (!order) return 0;
+ if (order._raw?.total_weight != null) return formatWeightKg(order._raw.total_weight);
+ return order.total_weight ?? 0;
+}
+
+/** 从细码取展示用重量(优先用原始值换算) */
+export function getFineCodeDisplayWeight(fineCode) {
+ if (!fineCode) return 0;
+ if (fineCode.raw_weight != null) return formatWeightKg(fineCode.raw_weight);
+ return fineCode.weight || 0;
+}
+
+/**
+ * 将接口详情数据规范化为页面使用的结构
+ */
+export function normalizeOrder(order) {
+ if (!order) return null;
+ const itemData = groupItemData((order.item_data || []).map((item) => normalizeItem(item)));
+ return {
+ id: order.id,
+ order_no: order.order_no || '',
+ audit_status: order.audit_status,
+ audit_status_name: order.audit_status_name || AUDIT_STATUS_MAP[order.audit_status] || '',
+ // 表头
+ sale_system_id: order.sale_system_id || '',
+ sale_system_name: order.sale_system_name || '',
+ delivery_unit_id: order.delivery_unit_id || '',
+ delivery_unit_name: order.delivery_unit_name || '',
+ business_unit_id: order.business_unit_id || '',
+ business_unit_name: order.business_unit_name || '',
+ delivery_time: (order.delivery_time || '').slice(0, 10),
+ remark: order.remark || '',
+ // 人员/时间
+ creator_name: order.creator_name || '',
+ create_time: order.create_time || '',
+ auditer_name: order.auditer_name || '',
+ audit_time: order.audit_time || '',
+ // 汇总
+ total_roll: formatRoll(order.total_roll),
+ total_weight: formatWeightKg(order.total_weight),
+ item_data: itemData,
+ _raw: 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 的维度会随扫码请求传给后端) */
+export const SCAN_GROUP_OPTIONS = [
+ { key: 'produce_order_no', label: '合同' },
+ { key: 'grey_fabric_code', label: '布编' },
+ { key: 'yarn_batch', label: '纱批' },
+ { key: 'machine_number', label: '机号' },
+ { key: 'volume_number', label: '布号' },
+ { key: 'grey_fabric_level_name', label: '等级' },
+];
+
+/** 勾选维度对应扫码接口锁定字段名(PDAScanGfmOtherDeliveryOrderParam) */
+export const SCAN_MERGE_FIELD_MAP = {
+ produce_order_no: 'produce_order_no_lock',
+ grey_fabric_code: 'grey_fabric_code_lock',
+ yarn_batch: 'yarn_batch_lock',
+ machine_number: 'machine_number_lock',
+ grey_fabric_level_name: 'grey_fabric_level_id_lock',
+};
+
+/** 构建扫码新增/删除请求参数(勾选锁定维度时附带当前详情区字段值) */
+export function buildScanUpdateParams({ id, scanCode, scanType, groupKeys = [], detail = {} }) {
+ const params = {
+ id: Number(id),
+ scan_code: scanCode,
+ scan_type: scanType,
+ };
+ (groupKeys || []).forEach((key) => {
+ const apiKey = SCAN_MERGE_FIELD_MAP[key];
+ if (!apiKey) return;
+ if (apiKey === 'grey_fabric_level_id_lock') {
+ const levelIds = detail.grey_fabric_level_id;
+ params.grey_fabric_level_id_lock = Array.isArray(levelIds) ? levelIds : [];
+ return;
+ }
+ const value = detail[key];
+ params[apiKey] = value != null && value !== '' ? value : '';
+ });
+ return params;
+}
+
+export function getEmptyScanDetail() {
+ return {
+ customer_id: '',
+ customer_name: '',
+ produce_order_no: '',
+ grey_fabric_code: '',
+ grey_fabric_name: '',
+ yarn_batch: '',
+ machine_number: '',
+ volume_number: '',
+ grey_fabric_level_id: [],
+ grey_fabric_level_name: '',
+ weight: 0,
+ scanned_roll: 0,
+ machine_stock: 0,
+ total_roll: 0,
+ total_weight: 0,
+ };
+}
+
+/** 扫码接口响应是否包含条码详情字段 */
+export function hasScanDetailFields(raw) {
+ if (!raw) return false;
+ return raw.scanned_total_roll != null
+ || raw.summary_stock_roll != null
+ || !!raw.customer_name
+ || !!raw.grey_fabric_code
+ || !!raw.produce_order_no;
+}
+
+/** 从扫码接口返回的详情构建扫码详情区数据 */
+export function buildScanDetailFromOrderResponse(order) {
+ const raw = order?._raw || order;
+ if (!hasScanDetailFields(raw)) return null;
+ const detail = {
+ customer_id: raw.customer_id || '',
+ customer_name: raw.customer_name || '',
+ produce_order_no: raw.produce_order_no || '',
+ grey_fabric_code: raw.grey_fabric_code || '',
+ grey_fabric_name: raw.grey_fabric_name || '',
+ yarn_batch: raw.yarn_batch || '',
+ machine_number: raw.machine_number || '',
+ volume_number: raw.volume_number || '',
+ grey_fabric_level_id: raw.grey_fabric_level_id || [],
+ grey_fabric_level_name: raw.grey_fabric_level_name || '',
+ weight: 0,
+ scanned_roll: formatRoll(raw.scanned_total_roll),
+ machine_stock: raw.summary_stock_roll != null ? formatRoll(raw.summary_stock_roll) : 0,
+ total_roll: order?.total_roll ?? 0,
+ total_weight: getOrderDisplayWeight(order),
+ };
+ return detail;
+}
+
+/** 在单据明细中定位本次扫描的坯布行与细码 */
+export function findScanContext(itemData, scanCode) {
+ const code = (scanCode || '').trim();
+ if (!code) return null;
+ for (const item of itemData || []) {
+ for (const fc of item.fine_codes || []) {
+ const candidates = [
+ fc.fabric_piece_code,
+ fc.bar_code,
+ fc.roll_no,
+ fc.scan_code,
+ ].filter(Boolean).map(String);
+ if (candidates.includes(code)) {
+ return { item, fineCode: fc };
+ }
+ }
+ }
+ return null;
+}
+
+/** 根据扫码上下文构建详情区展示数据 */
+export function buildScanDetailFromContext(context, order) {
+ if (!context) return getEmptyScanDetail();
+ const { item, fineCode } = context;
+ const groupKey = getItemGroupKey(item);
+ let scannedRoll = 0;
+ (order.item_data || []).forEach((row) => {
+ if (getItemGroupKey(row) !== groupKey) return;
+ (row.fine_codes || []).forEach((fc) => {
+ scannedRoll += Number(fc.roll || 0);
+ });
+ });
+ return {
+ 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: fineCode.fabric_piece_code || fineCode.roll_no || fineCode.bar_code || '',
+ grey_fabric_level_name: item.grey_fabric_level_name || '',
+ weight: getFineCodeDisplayWeight(fineCode),
+ scanned_roll: Number(scannedRoll.toFixed(2)),
+ machine_stock: item.machine_stock ?? 0,
+ total_roll: order.total_roll ?? 0,
+ total_weight: getOrderDisplayWeight(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 {
+ id: item.id,
+ grey_fabric_id: item.grey_fabric_id || '',
+ grey_fabric_code: item.grey_fabric_code || '',
+ grey_fabric_name: item.grey_fabric_name || '',
+ customer_name: item.customer_name || '',
+ produce_order_no: item.produce_order_no || item.contract_no || item.sale_contract_no || item.grey_fabric_contract_no || '',
+ machine_stock: machineStockRaw != null ? formatRoll(machineStockRaw) : 0,
+ grey_fabric_width: item.grey_fabric_width_and_unit_name || item.grey_fabric_width || '',
+ grey_fabric_gram_weight: item.grey_fabric_gram_weight_and_unit_name || item.grey_fabric_gram_weight || '',
+ yarn_batch: item.yarn_batch || '',
+ needle_size: item.needle_size || '',
+ raw_material_yarn_name: item.raw_material_yarn_name || '',
+ raw_material_batch_num: item.raw_material_batch_num || '',
+ raw_material_batch_brand: item.raw_material_batch_brand || '',
+ gray_fabric_color_name: item.gray_fabric_color_name || '',
+ grey_fabric_level_name: item.grey_fabric_level_name || '',
+ machine_number: item.machine_number || '',
+ weaving_process: item.weaving_process || '',
+ grey_fabric_remark: item.grey_fabric_remark || '',
+ roll: formatRoll(item.roll),
+ weight: formatWeightKg(item.total_weight),
+ fine_codes: (item.item_fc_data || []).map((fc) => ({
+ id: fc.id,
+ roll_no: fc.volume_number || '',
+ fabric_piece_code: fc.fabric_piece_code || '',
+ bar_code: fc.fabric_piece_code || fc.bar_code || '',
+ position: fc.position || '',
+ raw_weight: fc.weight,
+ weight: formatWeightKg(fc.weight),
+ roll: formatRoll(fc.roll),
+ // 删除细码走 scanUpdate,优先 fabric_piece_code,其次卷号
+ scan_code: fc.fabric_piece_code || fc.volume_number || fc.bar_code || '',
+ })),
+ };
+}
+
+/** 细码扫码/删除时传给 scanUpdate 的 scan_code(fabric_piece_code 或卷号) */
+export function getFineCodeScanCode(fineCode) {
+ if (!fineCode) return '';
+ return fineCode.fabric_piece_code
+ || fineCode.scan_code
+ || fineCode.bar_code
+ || fineCode.roll_no
+ || '';
+}
+
+/** 坯布明细归类 key:优先 grey_fabric_id,否则 code + name */
+export function getItemGroupKey(item) {
+ if (item.grey_fabric_id) return `id:${item.grey_fabric_id}`;
+ return `code:${item.grey_fabric_code}|${item.grey_fabric_name}`;
+}
+
+/** 将相同坯布的 item_data 合并为一行,细码 item_fc_data 汇总展示 */
+export function groupItemData(items) {
+ const grouped = new Map();
+ (items || []).forEach((item) => {
+ const groupKey = getItemGroupKey(item);
+ const existing = grouped.get(groupKey);
+ if (!existing) {
+ grouped.set(groupKey, {
+ ...item,
+ group_key: groupKey,
+ source_ids: [item.id],
+ fine_codes: [...(item.fine_codes || [])],
+ });
+ return;
+ }
+ existing.source_ids.push(item.id);
+ existing.fine_codes.push(...(item.fine_codes || []));
+ existing.roll = Number((existing.roll + item.roll).toFixed(2));
+ existing.weight = Number((existing.weight + item.weight).toFixed(2));
+ });
+ return Array.from(grouped.values()).map((row) => ({
+ ...row,
+ id: row.grey_fabric_id || row.group_key,
+ }));
+}
+
+// 构造审核状态变更接口的入参(id 为字符串)
+export function buildStatusParam(id, auditStatus) {
+ return { id: String(id), audit_status: auditStatus };
+}
+
+export function formatDisplayTime(value, format = 'YYYY-MM-DD') {
+ if (!value) return '';
+ const parsed = dayjs(value);
+ return parsed.isValid() ? parsed.format(format) : String(value).slice(0, 10);
+}
+
+export function canScanAtStatus(status) {
+ return [AUDIT_STATUS.PENDING, AUDIT_STATUS.REJECTED].includes(status);
+}
+
+export function isLockedOrderStatus(status) {
+ return [AUDIT_STATUS.APPROVED, AUDIT_STATUS.VOIDED].includes(status);
+}
+
+/** 分页拉取全部列表(直至末页) */
+export function fetchAllOrderList(listFn, params = {}, pageSize = LIST_PAGE_SIZE) {
+ const loadPage = (page, acc) => listFn({ ...params, page, size: pageSize })
+ .then((res) => {
+ const batch = Array.isArray(res) ? res : (res && res.list) || [];
+ const merged = acc.concat(batch);
+ if (batch.length < pageSize) return merged;
+ return loadPage(page + 1, merged);
+ });
+ return loadPage(1, []);
+}
+
+/** 新增/编辑页底部:审核、作废 */
+export function getFormStatusActionButtons(headerSaved, orderId, status) {
+ if (!headerSaved || !orderId || !canScanAtStatus(status)) return [];
+ return [
+ { label: '审核', action: 'approve' },
+ { label: '作废', action: 'void' },
+ ];
+}
+
+/** 查看页底部:编辑、审核、作废 / 消审 */
+export function getViewStatusActionButtons(status) {
+ if (status === AUDIT_STATUS.PENDING || status === AUDIT_STATUS.REJECTED) {
+ return [
+ { label: '编辑', action: 'edit' },
+ { label: '审核', action: 'approve' },
+ { label: '作废', action: 'void' },
+ ];
+ }
+ if (status === AUDIT_STATUS.APPROVED) {
+ return [{ label: '消审', action: 'unapprove' }];
+ }
+ return [];
+}
+
+/** 将 normalizeOrder 结果映射为表单字段 */
+export function orderToFormFields(order) {
+ return {
+ order_no: order.order_no,
+ business_unit_id: order.business_unit_id,
+ business_unit_name: order.business_unit_name,
+ delivery_time: order.delivery_time,
+ remark: order.remark,
+ item_data: order.item_data,
+ };
+}
+
+export function getFineCodeTableColumns(readonly) {
+ const cols = [...FINE_CODE_TABLE_COLUMNS];
+ if (!readonly) cols.push({ label: '操作', key: 'action', width: 90 });
+ return cols;
+}
+
+export function mapFineCodeTableRows(list, readonly) {
+ return (list || []).map((item, index) => ({
+ seq: index + 1,
+ roll_no: item.roll_no || '-',
+ roll: item.roll != null && item.roll !== '' ? item.roll : '-',
+ weight: item.weight != null && item.weight !== '' ? `${item.weight}` : '-',
+ bar_code: item.bar_code || '-',
+ position: item.position || '-',
+ action: readonly ? '' : '删除',
+ }));
+}
+
+export function getFineCodeTableWidth(columns) {
+ const total = (columns || []).reduce((sum, col) => sum + (col.width || 120), 0);
+ return `${total}rpx`;
+}
+
+/**
+ * 确认并执行审核状态变更(新增/编辑/查看页共用)
+ * @param {Vue} vm 页面实例,需有 $u.api 与 showError
+ * @param {{ orderId: number, action: string, onSuccess?: Function }} options
+ */
+export function confirmOrderStatusAction(vm, { orderId, action, onSuccess }) {
+ const cfg = STATUS_ACTION_CONFIG[action];
+ if (!cfg || !orderId) return;
+ const api = vm.$u.api.gfmOtherDeliveryOrder;
+ const requestFn = api[cfg.apiKey];
+ if (typeof requestFn !== 'function') return;
+ uni.showModal({
+ title: '提示',
+ content: cfg.msg,
+ success: (res) => {
+ if (!res.confirm) return;
+ uni.showLoading({ title: '处理中...' });
+ requestFn(buildStatusParam(orderId, cfg.status))
+ .then(() => {
+ if (typeof onSuccess === 'function') return onSuccess();
+ uni.hideLoading();
+ })
+ .catch((e) => {
+ uni.hideLoading();
+ if (vm.showError) vm.showError(e.message || '操作失败');
+ });
+ },
+ });
+}
diff --git a/src/components/card/storeFabricBusinessOutItem.vue b/src/components/card/storeFabricBusinessOutItem.vue
new file mode 100644
index 0000000..9ac4b18
--- /dev/null
+++ b/src/components/card/storeFabricBusinessOutItem.vue
@@ -0,0 +1,66 @@
+
+
+
+ {{ item.order_no }}
+ {{ item.audit_status_name }}
+
+
+ 出仓日期:
+ {{ formatTime(item.out_date) }}
+
+
+ 出仓类型:
+ {{ item.bill_type_name }}
+
+
+ 接收单位:
+ {{ item.business_unit_name || '-' }}
+
+
+ 创 建 人:
+ {{ item.create_user_name }} {{ formatTime(item.create_time, 'YYYY-MM-DD') }}
+
+
+ 审 核 人:
+ {{ item.auditor_name }} {{ formatTime(item.audit_date, 'YYYY-MM-DD') }}
+
+
+ 查看详情
+
+
+
+
+
+
+
diff --git a/src/components/storefabric/FabricInfoPopup.vue b/src/components/storefabric/FabricInfoPopup.vue
new file mode 100644
index 0000000..8aeb92b
--- /dev/null
+++ b/src/components/storefabric/FabricInfoPopup.vue
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/storefabric/FabricOutDetailList.vue b/src/components/storefabric/FabricOutDetailList.vue
new file mode 100644
index 0000000..a4f5529
--- /dev/null
+++ b/src/components/storefabric/FabricOutDetailList.vue
@@ -0,0 +1,36 @@
+
+
+ {{ title }}
+
+
+
+
+ {{ row.grey_fabric_code }}#{{ row.grey_fabric_name }}
+
+
+
+ 匹数:{{ row.roll }}
+ 重量:{{ row.weight }}KG
+ 细码
+
+
+
+
+
+
+
+
+
diff --git a/src/components/storefabric/FabricOutFooter.vue b/src/components/storefabric/FabricOutFooter.vue
new file mode 100644
index 0000000..35bda00
--- /dev/null
+++ b/src/components/storefabric/FabricOutFooter.vue
@@ -0,0 +1,27 @@
+
+
+
+
+ {{ btn.label }}
+
+
+
+
+
+
+
+
diff --git a/src/components/storefabric/FabricOutScanBar.vue b/src/components/storefabric/FabricOutScanBar.vue
new file mode 100644
index 0000000..9d80a9d
--- /dev/null
+++ b/src/components/storefabric/FabricOutScanBar.vue
@@ -0,0 +1,38 @@
+
+
+
+ 条码资料
+
+
+
+
+
+ {{ disabledTip }}
+ {{ message }}
+
+
+
+
+
+
diff --git a/src/components/storefabric/FabricOutScanDetail.vue b/src/components/storefabric/FabricOutScanDetail.vue
new file mode 100644
index 0000000..2c5b166
--- /dev/null
+++ b/src/components/storefabric/FabricOutScanDetail.vue
@@ -0,0 +1,154 @@
+
+
+
+ 已扫条数:{{ formatCount(detail.scanned_roll) }}条
+ 机台库存:{{ formatRoll(detail.machine_stock) }}条
+
+
+ 合计条数:{{ formatRoll(detail.total_roll) }}条
+ 合计重量:{{ formatWeight(detail.total_weight) }}KG
+
+
+ 客户:
+ {{ detail.customer_name || '' }}
+
+
+
+
+ 生产通知单:
+ {{ detail.produce_order_no || '' }}
+
+
+
+ 布编:
+ {{ detail.grey_fabric_code || '' }}
+
+
+
+ 布名:
+ {{ detail.grey_fabric_name || '' }}
+
+
+
+
+ 纱批:
+ {{ detail.yarn_batch || '' }}
+
+
+
+
+
+ 机号:
+ {{ detail.machine_number || '' }}
+
+
+
+ 布号:
+ {{ detail.volume_number || '' }}
+
+
+
+
+
+ 等级:
+ {{ detail.grey_fabric_level_name || '' }}
+
+
+ 重量:
+ {{ formatWeight(detail.weight) }}Kg
+
+
+
+
+
+
+ {{ col.label }}
+
+ 暂无数据~~
+
+ {{ formatCell(row, col.key) }}
+
+
+
+
+
+
+
+
+
diff --git a/src/components/storefabric/FineCodePopup.vue b/src/components/storefabric/FineCodePopup.vue
new file mode 100644
index 0000000..754e21f
--- /dev/null
+++ b/src/components/storefabric/FineCodePopup.vue
@@ -0,0 +1,160 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/storefabric/OrderStatusBar.vue b/src/components/storefabric/OrderStatusBar.vue
new file mode 100644
index 0000000..7ca07cc
--- /dev/null
+++ b/src/components/storefabric/OrderStatusBar.vue
@@ -0,0 +1,49 @@
+
+
+ 订单状态
+ {{ displayName }}
+
+
+
+
+
+
diff --git a/src/manifest.json b/src/manifest.json
index 8531b22..ab0f93e 100644
--- a/src/manifest.json
+++ b/src/manifest.json
@@ -31,6 +31,7 @@
},
"distribute" : {
"android" : {
+ "packagename" : "uni.UNIF79F300",
"permissions" : [
"",
"",
diff --git a/src/pages.json b/src/pages.json
index 422a2d3..29ad84e 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -569,6 +569,34 @@
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
+ },{
+ "path" : "pages/storefabric/storeFabricBusinessOutList",
+ "style" :
+ {
+ "navigationBarTitleText": "坯布出库列表",
+ "enablePullDownRefresh": false
+ }
+ },{
+ "path" : "pages/storefabric/storeFabricBusinessOutAdd",
+ "style" :
+ {
+ "navigationBarTitleText": "新增坯布出仓单",
+ "enablePullDownRefresh": false
+ }
+ },{
+ "path" : "pages/storefabric/storeFabricBusinessOutEdit",
+ "style" :
+ {
+ "navigationBarTitleText": "编辑坯布出仓单",
+ "enablePullDownRefresh": false
+ }
+ },{
+ "path" : "pages/storefabric/storeFabricBusinessOutView",
+ "style" :
+ {
+ "navigationBarTitleText": "查看坯布出仓单",
+ "enablePullDownRefresh": false
+ }
},{
"path" : "pages/storefabric/storefabricstoresearch",
"style" :
diff --git a/src/pages/storefabric/storeFabricBusinessOutAdd.vue b/src/pages/storefabric/storeFabricBusinessOutAdd.vue
new file mode 100644
index 0000000..294bcc7
--- /dev/null
+++ b/src/pages/storefabric/storeFabricBusinessOutAdd.vue
@@ -0,0 +1,214 @@
+
+
+
+
+
+
+
+
+
+
+ 出仓单号
+
+
+
+
+
+
+
+ 出仓类型
+
+ {{ getBillTypeName() }}
+
+
+
+
+
+ 接收单位*
+
+
+
+ {{ form.business_unit_name || '请选择' }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ dateLabel }}*
+
+
+
+ {{ form.delivery_time }}
+
+
+
+
+
+
+
+
+
+ 单据备注
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/storefabric/storeFabricBusinessOutEdit.vue b/src/pages/storefabric/storeFabricBusinessOutEdit.vue
new file mode 100644
index 0000000..b5364c1
--- /dev/null
+++ b/src/pages/storefabric/storeFabricBusinessOutEdit.vue
@@ -0,0 +1,95 @@
+
+
+
+
+
+ 出仓单号
+ {{ form.order_no }}
+
+
+ 出仓类型
+ {{ getBillTypeName() }}
+
+
+ 接收单位
+ {{ form.business_unit_name || '-' }}
+
+
+ {{ dateLabel }}
+ {{ form.delivery_time }}
+
+
+ 单据备注
+ {{ form.remark || '-' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/storefabric/storeFabricBusinessOutList.vue b/src/pages/storefabric/storeFabricBusinessOutList.vue
new file mode 100644
index 0000000..233202c
--- /dev/null
+++ b/src/pages/storefabric/storeFabricBusinessOutList.vue
@@ -0,0 +1,268 @@
+
+
+
+
+
+
+ 筛选
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 筛选条件
+
+ 出仓单号
+
+
+
+ 出仓日期
+
+ filters.start_date = e.detail.value">
+ {{ filters.start_date || '开始日期' }}
+
+ ~
+ filters.end_date = e.detail.value">
+ {{ filters.end_date || '结束日期' }}
+
+
+
+
+ 出仓单位
+ {{ deliveryUnitLabel || '全部' }}
+
+
+ 接收单位
+ {{ businessUnitLabel || '全部' }}
+
+
+ 订单状态
+ {{ statusLabel || '全部' }}
+
+
+ 重置
+ 确定
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/storefabric/storeFabricBusinessOutMixin.js b/src/pages/storefabric/storeFabricBusinessOutMixin.js
new file mode 100644
index 0000000..e689c72
--- /dev/null
+++ b/src/pages/storefabric/storeFabricBusinessOutMixin.js
@@ -0,0 +1,404 @@
+/**
+ * 坯布出仓单(其他出货单)表单 mixin(新增/编辑共用)
+ *
+ * 业务说明:
+ * 1. 后端当前仅提供「坯布其他出货单」一种类型的接口,故出仓类型固定为 other,
+ * 表头保留接收单位(business_unit) / 出货日期 / 备注 等字段。
+ * 2. 用户先填写表头并「提交保存」(addGfmOtherDeliveryOrder),拿到出仓单 id 后即可扫码;
+ * 扫码新增/删除细码走 updateGfmOtherDeliveryOrder;勾选锁定维度时附带 *_lock 字段,操作后用返回的最新详情刷新。
+ * 3. 后端没有「修改表头」接口,保存成功或编辑进入后表头变为只读,仅可扫码维护细码。
+ */
+import util from '@/common/util';
+import scanMixin from '@/common/scanMixin.js';
+import {
+ AUDIT_STATUS_MAP,
+ BILL_TYPES,
+ normalizeOrder,
+ mapToSelectOptions,
+ getFineCodeScanCode,
+ canScanAtStatus,
+ isLockedOrderStatus,
+ getFormStatusActionButtons,
+ orderToFormFields,
+ confirmOrderStatusAction,
+ DRAFT_AUDIT_STATUS,
+ DRAFT_AUDIT_STATUS_NAME,
+ getEmptyScanDetail,
+ findScanContext,
+ buildScanDetailFromContext,
+ buildScanDetailFromOrderResponse,
+ buildScanUpdateParams,
+ getOrderDisplayWeight,
+ getFineCodeDisplayWeight,
+} from '@/common/storeFabricBusinessOut';
+
+export default {
+ mixins: [scanMixin],
+ data() {
+ return {
+ pageMode: 'add',
+ orderId: 0,
+ form: this.getEmptyForm(),
+ headerSaved: false,
+ selectShow: false,
+ selectList: [],
+ selectType: '',
+ canScan: false,
+ QRBarCode: '',
+ BarCodeDelStatus: false,
+ BillDataMessage: '',
+ currentScanItem: null,
+ fabricInfoShow: false,
+ fineCodeShow: false,
+ currentFabricInfo: {},
+ currentFineCodes: [],
+ currentGroupKey: '',
+ scanDetail: getEmptyScanDetail(),
+ scanGroupKeys: [],
+ lastScanCode: '',
+ billTypeName: (BILL_TYPES[0] || {}).label || '坯布其他出货单',
+ auditStatus: 0,
+ businessUnitOptions: [],
+ dropdownLoading: false,
+ };
+ },
+ computed: {
+ isReadonly() {
+ return this.pageMode === 'view';
+ },
+ isEditable() {
+ return this.pageMode === 'add' || this.pageMode === 'edit';
+ },
+ // 表头是否可编辑:仅新增且未保存时可编辑(后端无修改表头接口)
+ headerEditable() {
+ return this.pageMode === 'add' && !this.headerSaved;
+ },
+ dateLabel() {
+ return '出货日期';
+ },
+ /** 表头保存后,待审核/已驳回状态下显示审核、作废 */
+ statusActionButtons() {
+ return getFormStatusActionButtons(this.headerSaved, this.orderId, this.auditStatus);
+ },
+ displayAuditStatus() {
+ if (this.pageMode === 'add' && !this.headerSaved) return DRAFT_AUDIT_STATUS;
+ return this.auditStatus;
+ },
+ displayAuditStatusName() {
+ if (this.pageMode === 'add' && !this.headerSaved) return DRAFT_AUDIT_STATUS_NAME;
+ return AUDIT_STATUS_MAP[this.auditStatus] || '';
+ },
+ },
+ onShow() {
+ this.isPageActive = true;
+ // #ifdef APP-PLUS
+ if (this.canScan && this.isEditable) {
+ this.registerScanBroadcast((scanResult) => {
+ this.QRBarCode = scanResult.trim().replace(/[\r\n]/g, '');
+ this.$nextTick(() => this.handleScan());
+ });
+ }
+ // #endif
+ },
+ onHide() {
+ this.isPageActive = false;
+ // #ifdef APP-PLUS
+ this.unregisterScanBroadcast();
+ // #endif
+ },
+ onUnload() {
+ this.isPageActive = false;
+ // #ifdef APP-PLUS
+ this.unregisterScanBroadcast();
+ // #endif
+ },
+ methods: {
+ registerOrderScanBroadcast() {
+ // #ifdef APP-PLUS
+ this.registerScanBroadcast((scanResult) => {
+ this.QRBarCode = scanResult.trim().replace(/[\r\n]/g, '');
+ this.$nextTick(() => this.handleScan());
+ });
+ // #endif
+ },
+ syncCanScanFromStatus(status) {
+ const nextCanScan = this.isEditable && canScanAtStatus(status);
+ if (this.canScan && !nextCanScan) {
+ // #ifdef APP-PLUS
+ this.unregisterScanBroadcast();
+ // #endif
+ }
+ this.canScan = nextCanScan;
+ },
+ loadBaseDropdowns() {
+ if (this.dropdownLoading) return Promise.resolve();
+ if (this.businessUnitOptions.length) {
+ return Promise.resolve();
+ }
+ this.dropdownLoading = true;
+ return this.ensureBusinessUnitOptions().finally(() => {
+ this.dropdownLoading = false;
+ });
+ },
+ ensureBusinessUnitOptions() {
+ if (this.businessUnitOptions.length) return Promise.resolve(this.businessUnitOptions);
+ return this.$u.api.businessUnit.list({})
+ .then((res) => {
+ this.businessUnitOptions = mapToSelectOptions(res);
+ return this.businessUnitOptions;
+ });
+ },
+ getEmptyForm() {
+ return {
+ order_no: '',
+ business_unit_id: '',
+ business_unit_name: '',
+ delivery_time: this.$u.timeFormat(new Date(), 'yyyy-mm-dd'),
+ remark: '',
+ item_data: [],
+ };
+ },
+ loadOrder(id, options = {}) {
+ const { rejectIfLocked = false } = options;
+ return this.$u.api.gfmOtherDeliveryOrder.detail({ id })
+ .then((res) => {
+ const order = normalizeOrder(res);
+ if (!order) {
+ this.showError('单据不存在');
+ return null;
+ }
+ if (rejectIfLocked && isLockedOrderStatus(order.audit_status)) {
+ this.showError('当前状态不可编辑');
+ setTimeout(() => uni.navigateBack(), 1500);
+ return null;
+ }
+ this.orderId = order.id;
+ this.auditStatus = order.audit_status;
+ this.headerSaved = true;
+ this.form = orderToFormFields(order);
+ this.refreshScanDetailTotals(order);
+ this.syncCanScanFromStatus(order.audit_status);
+ if (this.canScan) this.registerOrderScanBroadcast();
+ return order;
+ })
+ .catch((e) => {
+ this.showError(e.message || '加载单据失败');
+ return null;
+ });
+ },
+ pickerSelectFun(type) {
+ if (!this.headerEditable) return;
+ this.selectType = type;
+ const openPicker = (list) => {
+ if (!list.length) {
+ this.showError('暂无可选数据');
+ return;
+ }
+ this.selectList = list;
+ this.selectShow = true;
+ };
+ if (type === '接收单位') {
+ this.ensureBusinessUnitOptions()
+ .then(openPicker)
+ .catch((e) => this.showError(e.message || '加载单位列表失败'));
+ }
+ },
+ selectConfirmFun(e) {
+ const item = e[0];
+ if (this.selectType === '接收单位') {
+ this.form.business_unit_id = item.value;
+ this.form.business_unit_name = item.label;
+ }
+ },
+ bindDateChange(e) {
+ this.form.delivery_time = e.detail.value;
+ },
+ validateForm() {
+ if (!this.form.business_unit_id) return '请选择接收单位';
+ if (!this.form.delivery_time) return '请选择出货日期';
+ return '';
+ },
+ buildAddParam() {
+ return {
+ business_unit_id: Number(this.form.business_unit_id),
+ delivery_time: this.form.delivery_time,
+ remark: this.form.remark || '',
+ };
+ },
+ submitSave() {
+ if (this.headerSaved) {
+ this.showError('表头已保存,请直接扫码维护细码');
+ return;
+ }
+ const err = this.validateForm();
+ if (err) {
+ this.showError(err);
+ return;
+ }
+ uni.showLoading({ title: '保存中...' });
+ this.$u.api.gfmOtherDeliveryOrder.add(this.buildAddParam())
+ .then((res) => {
+ this.orderId = (res && res.id) || 0;
+ if (!this.orderId) {
+ throw new Error('保存失败,未返回单据ID');
+ }
+ return this.$u.api.gfmOtherDeliveryOrder.detail({ id: this.orderId });
+ })
+ .then((detail) => {
+ uni.hideLoading();
+ const order = normalizeOrder(detail);
+ this.applyOrder(order);
+ this.headerSaved = true;
+ this.syncCanScanFromStatus(order.audit_status);
+ this.showSuccess('保存成功,可以扫码');
+ this.registerOrderScanBroadcast();
+ })
+ .catch((e) => {
+ uni.hideLoading();
+ this.showError(e.message || '保存失败');
+ });
+ },
+ applyOrder(order) {
+ if (!order) return;
+ this.auditStatus = order.audit_status;
+ Object.assign(this.form, orderToFormFields(order));
+ this.refreshScanDetailTotals(order);
+ },
+ refreshScanDetailTotals(order) {
+ this.scanDetail = {
+ ...this.scanDetail,
+ total_roll: order.total_roll ?? 0,
+ total_weight: getOrderDisplayWeight(order),
+ };
+ },
+ applyScanDetail(scanCode, order, scanType) {
+ const fromResponse = buildScanDetailFromOrderResponse(order);
+ if (fromResponse) {
+ const context = findScanContext(order.item_data, scanCode);
+ if (context) {
+ fromResponse.weight = getFineCodeDisplayWeight(context.fineCode);
+ }
+ this.scanDetail = fromResponse;
+ if (scanType !== 2) this.lastScanCode = scanCode;
+ else if (this.lastScanCode === scanCode) this.lastScanCode = '';
+ return;
+ }
+ const context = findScanContext(order.item_data, scanCode);
+ if (context) {
+ this.scanDetail = buildScanDetailFromContext(context, order);
+ this.lastScanCode = scanCode;
+ return;
+ }
+ if (scanType === 2 && this.lastScanCode === scanCode) {
+ this.scanDetail = {
+ ...getEmptyScanDetail(),
+ total_roll: order.total_roll ?? 0,
+ total_weight: getOrderDisplayWeight(order),
+ };
+ this.lastScanCode = '';
+ return;
+ }
+ this.refreshScanDetailTotals(order);
+ },
+ handleScan() {
+ const code = (this.QRBarCode || '').trim();
+ if (!this.canScan || !this.orderId) {
+ this.showError('请先提交保存后再扫码');
+ this.QRBarCode = '';
+ return;
+ }
+ if (!code) {
+ this.QRBarCode = '';
+ return;
+ }
+ const scanType = this.BarCodeDelStatus ? 2 : 1;
+ this.doScanUpdate(code, scanType);
+ },
+ BarCodeDelChange(e) {
+ this.BarCodeDelStatus = (e.detail.value || []).length > 0;
+ },
+ /** 扫码新增/删除细码,统一走 scanUpdate 接口 */
+ doScanUpdate(scanCode, scanType, options = {}) {
+ const { refreshFineCodes = false } = options;
+ uni.showLoading({ title: scanType === 2 ? '删除中...' : '处理中...' });
+ return this.$u.api.gfmOtherDeliveryOrder.scanUpdate(buildScanUpdateParams({
+ id: this.orderId,
+ scanCode,
+ scanType,
+ groupKeys: this.scanGroupKeys,
+ detail: this.scanDetail,
+ }))
+ .then((detail) => {
+ uni.hideLoading();
+ const order = normalizeOrder(detail);
+ this.form.item_data = order.item_data;
+ this.auditStatus = order.audit_status;
+ this.applyScanDetail(scanCode, order, scanType);
+ if (refreshFineCodes) {
+ const row = order.item_data.find((i) => (i.group_key || String(i.id)) === this.currentGroupKey);
+ this.currentFineCodes = row ? [...row.fine_codes] : [];
+ }
+ this.BillDataMessage = scanType === 2 ? '删除成功' : '扫描成功';
+ this.QRBarCode = '';
+ if (scanType === 2) this.showSuccess('删除成功');
+ else util.playSuccessAudio();
+ })
+ .catch((e) => {
+ uni.hideLoading();
+ this.showError(e.message || (scanType === 2 ? '删除失败' : '扫码失败'));
+ this.QRBarCode = '';
+ });
+ },
+ openFabricInfo(row) {
+ this.currentFabricInfo = { ...row };
+ this.fabricInfoShow = true;
+ },
+ openFineCode(row) {
+ this.currentGroupKey = row.group_key || String(row.id);
+ this.currentFineCodes = [...(row.fine_codes || [])];
+ this.fineCodeShow = true;
+ },
+ onDeleteFineCode(fineCode) {
+ if (this.isReadonly || !this.canScan) return;
+ const scanCode = getFineCodeScanCode(fineCode);
+ if (!scanCode) {
+ this.showError('该细码缺少条码,无法删除');
+ return;
+ }
+ uni.showModal({
+ title: '提示',
+ content: `确认删除细码 ${scanCode}?`,
+ success: (res) => {
+ if (!res.confirm) return;
+ this.doScanUpdate(scanCode, 2, { refreshFineCodes: true });
+ },
+ });
+ },
+ handleStatusAction(action) {
+ confirmOrderStatusAction(this, {
+ orderId: this.orderId,
+ action,
+ onSuccess: () => this.$u.api.gfmOtherDeliveryOrder.detail({ id: this.orderId })
+ .then((detail) => {
+ uni.hideLoading();
+ const order = normalizeOrder(detail);
+ if (!order) return;
+ this.applyOrder(order);
+ this.syncCanScanFromStatus(order.audit_status);
+ this.showSuccess('操作成功');
+ }),
+ });
+ },
+ showError(message) {
+ util.playErrorAudio();
+ uni.showModal({ title: '提示', content: message, showCancel: false });
+ },
+ showSuccess(message) {
+ util.playSuccessAudio();
+ uni.showToast({ title: message, icon: 'success' });
+ },
+ getBillTypeName() {
+ return this.billTypeName;
+ },
+ },
+};
diff --git a/src/pages/storefabric/storeFabricBusinessOutPage.scss b/src/pages/storefabric/storeFabricBusinessOutPage.scss
new file mode 100644
index 0000000..9c35fe7
--- /dev/null
+++ b/src/pages/storefabric/storeFabricBusinessOutPage.scss
@@ -0,0 +1,160 @@
+/* 坯布出仓单页面共用样式(新增/编辑/查看) */
+.fabric-out-page {
+ background-color: #F8F8F8;
+ padding-bottom: 260rpx;
+}
+.fabric-out-mt32 {
+ margin-top: 32rpx;
+}
+.fabric-out-sectionTitle {
+ font-size: 30rpx;
+ font-weight: bold;
+ padding: 24rpx 26rpx 12rpx;
+ border-left: 6rpx solid #007AFF;
+ margin: 20rpx 26rpx 0;
+}
+.fabric-out-scanTip {
+ padding: 20rpx 26rpx;
+ color: #fa8c16;
+ font-size: 26rpx;
+ background: #fff7e6;
+ margin: 16rpx 26rpx;
+ border-radius: 8rpx;
+}
+.fabric-out-msgTip {
+ padding: 12rpx 26rpx;
+ color: #52c41a;
+ font-size: 26rpx;
+}
+.fabric-out-detailList {
+ padding: 0 26rpx;
+}
+.fabric-out-detailCard {
+ background: #fff;
+ border-radius: 12rpx;
+ padding: 20rpx;
+ margin-bottom: 16rpx;
+}
+.fabric-out-detailRow {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ font-size: 28rpx;
+ font-weight: bold;
+ padding-bottom: 12rpx;
+ border-bottom: 1rpx solid #f0f0f0;
+}
+.fabric-out-detailMeta {
+ display: flex;
+ align-items: center;
+ gap: 20rpx;
+ padding-top: 12rpx;
+ font-size: 26rpx;
+ color: #666;
+}
+.fabric-out-scanRow {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 16rpx;
+}
+.fabric-out-scanInput {
+ width: 200px;
+ flex: 1;
+ min-width: 160px;
+}
+.fabric-out-delCheck {
+ display: flex;
+ align-items: center;
+ font-size: 26rpx;
+ color: #666;
+ white-space: nowrap;
+}
+.fabric-out-scanDetail {
+ background: #fff;
+ margin: 0 26rpx 16rpx;
+ border-radius: 8rpx;
+ overflow: hidden;
+}
+.fabric-out-scanDetailRow {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ padding: 16rpx 20rpx;
+ border-bottom: 1rpx solid #f0f0f0;
+ font-size: 26rpx;
+ color: #333;
+}
+.fabric-out-scanDetailRow--2col {
+ justify-content: space-between;
+ gap: 12rpx;
+}
+.fabric-out-scanDetailCell {
+ flex: 1;
+ min-width: 0;
+}
+.fabric-out-scanDetailCheck {
+ display: flex;
+ align-items: center;
+ flex: 1;
+ min-width: 0;
+ gap: 4rpx;
+}
+.fabric-out-scanDetailLabel {
+ color: #333;
+ flex-shrink: 0;
+}
+.fabric-out-scanDetailValue {
+ color: #333;
+ word-break: break-all;
+}
+.fabric-out-scanDetailTableScroll {
+ width: 100%;
+}
+.fabric-out-scanDetailTable {
+ min-width: 100%;
+}
+.fabric-out-scanDetailTableRow {
+ display: flex;
+ border-bottom: 1rpx solid #f0f0f0;
+}
+.fabric-out-scanDetailTableHead {
+ background: #f5f5f5;
+ font-weight: bold;
+}
+.fabric-out-scanDetailTableCell {
+ padding: 14rpx 8rpx;
+ font-size: 24rpx;
+ color: #333;
+ text-align: center;
+ box-sizing: border-box;
+ word-break: break-all;
+}
+.fabric-out-scanDetailEmpty {
+ padding: 24rpx;
+ text-align: center;
+ font-size: 26rpx;
+ color: #999;
+}
+.fabric-out-submitView {
+ width: 100%;
+ padding: 16rpx 26rpx 26rpx;
+ background: #fff;
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ border-top: 1rpx solid #f1f1f1;
+ display: flex;
+ z-index: 100;
+ box-sizing: border-box;
+}
+.fabric-out-actionBtnWrap {
+ flex: 1;
+ min-width: 0;
+}
+.fabric-out-actionBtnWrap + .fabric-out-actionBtnWrap {
+ margin-left: 20rpx;
+}
+.fabric-out-actionBtn {
+ flex: 1;
+}
diff --git a/src/pages/storefabric/storeFabricBusinessOutView.vue b/src/pages/storefabric/storeFabricBusinessOutView.vue
new file mode 100644
index 0000000..8e913bd
--- /dev/null
+++ b/src/pages/storefabric/storeFabricBusinessOutView.vue
@@ -0,0 +1,145 @@
+
+
+
+
+
+ 出仓单号
+ {{ order.order_no }}
+
+
+ 出仓类型
+ {{ billTypeName }}
+
+
+ 接收单位{{ order.business_unit_name }}
+
+
+ 出货日期{{ formatTime(order.delivery_time) }}
+
+
+ 单据备注{{ order.remark || '-' }}
+
+
+ 创建人{{ order.creator_name }} {{ formatTime(order.create_time, 'YYYY-MM-DD') }}
+
+
+ 审核人{{ order.auditer_name }} {{ formatTime(order.audit_time, 'YYYY-MM-DD') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/storefabric/storefabricBusinessOutAdd.vue b/src/pages/storefabric/storefabricBusinessOutAdd.vue
deleted file mode 100644
index 0e6d54b..0000000
--- a/src/pages/storefabric/storefabricBusinessOutAdd.vue
+++ /dev/null
@@ -1,1057 +0,0 @@
-
-
-
-
- 出仓凭证
-
- 出仓日期 {{$u.timeFormat(GoodsOutBillDate, 'yyyy-mm-dd')}}
-
-
- 单据类型*
- {{BillTypeName ? BillTypeName : '请选择'}}
-
-
-
-
- 仓库名称*
- {{StoreName ? StoreName : '请选择'}}
-
-
-
-
- 调至仓库*
- {{ToStoreName ? ToStoreName : '请选择'}}
-
-
-
-
- 往来单位*
- {{CustomerName ? CustomerName : '请选择'}}
-
-
-
-
- 营销部门*
- {{PlanDepartmentName ? PlanDepartmentName : '请选择'}}
-
-
-
-
- 销 售 员:{{SaleUserName}}
-
-
-
-
- 备注内容
-
-
-
-
-
-
- 整缸
-
-
- 删除
-
-
-
- {{BillDataMessage}}
-
-
- 成品编号:{{FabricGoodsNo}}
- 成品重量:{{GoodsQty}}KG
-
-
- 成品色号:{{GoodsCodeNo}}
- 成品颜色:{{GoodsCodeName}}
-
-
- 成品缸号:{{CrockNo}}
- 缸号卷号:{{GoodsBillNo}}
-
-
- 本单条数:{{BillSumRoll}}条
- 本单重量:{{BillSumQty}}KG
-
-
- 本色条数:{{GoodsCodeSumRoll}}条
- 本色重量:{{GoodsCodeSumQty}}KG
-
-
- 本缸条数:{{CrockNoSumRoll}}条
- 本缸重量:{{CrockNoSumQty}}KG
-
-
-
-
-
-
-
-
-
-
-
- {{pageType ? '保存' : '提交'}}
-
-
-
- {{commitType ? '消审' : '审核'}}
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/默认模块.openapi.json b/默认模块.openapi.json
new file mode 100644
index 0000000..298dfd6
--- /dev/null
+++ b/默认模块.openapi.json
@@ -0,0 +1,593 @@
+{
+ "openapi": "3.0.1",
+ "info": {
+ "title": "默认模块",
+ "description": "erp管理系统",
+ "version": "1.0.0",
+ "contact": {}
+ },
+ "tags": [
+ {
+ "name": "【PDA-坯布出仓单】"
+ }
+ ],
+ "paths": {
+ "/hcscm_weave/pda/v1/grey_fabric_manage/gfmOtherDeliveryOrder/updateGfmOtherDeliveryOrder": {
+ "put": {
+ "summary": "PDA扫码新增/删除坯布出仓单细码",
+ "deprecated": false,
+ "description": "扫描坯布条码进行新增或删除;操作完成后返回最新出仓单详情(含表头、详情及细码),供前端刷新展示",
+ "tags": [
+ "【PDA-坯布出仓单】"
+ ],
+ "parameters": [
+ {
+ "name": "Platform",
+ "in": "header",
+ "description": "终端ID",
+ "required": true,
+ "example": "",
+ "schema": {
+ "type": "integer"
+ }
+ },
+ {
+ "name": "Authorization",
+ "in": "header",
+ "description": "token",
+ "required": true,
+ "example": "",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/grey_fabric_manage.PDAScanGfmOtherDeliveryOrderParam"
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/grey_fabric_manage.GetGfmOtherDeliveryOrderData"
+ }
+ }
+ },
+ "headers": {}
+ }
+ },
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ]
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "common.BusinessClose": {
+ "type": "integer",
+ "enum": [
+ 1,
+ 2
+ ],
+ "x-enum-comments": {
+ "BusinessCloseNo": "开启",
+ "BusinessCloseYes": "关闭"
+ },
+ "x-enum-varnames": [
+ "BusinessCloseNo",
+ "BusinessCloseYes"
+ ]
+ },
+ "common.OrderStatus": {
+ "type": "integer",
+ "enum": [
+ 1,
+ 2,
+ 3,
+ 4
+ ],
+ "x-enum-comments": {
+ "OrderStatusAudited": "已审核",
+ "OrderStatusPendingAudit": "待审核",
+ "OrderStatusRejected": "已驳回",
+ "OrderStatusVoided": "已作废"
+ },
+ "x-enum-varnames": [
+ "OrderStatusPendingAudit",
+ "OrderStatusAudited",
+ "OrderStatusRejected",
+ "OrderStatusVoided"
+ ]
+ },
+ "grey_fabric_manage.GetGfmOtherDeliveryOrderData": {
+ "type": "object",
+ "properties": {
+ "audit_status": {
+ "description": "审核状态",
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/common.OrderStatus"
+ }
+ ]
+ },
+ "audit_status_name": {
+ "description": "审核状态name",
+ "type": "string"
+ },
+ "audit_time": {
+ "description": "审核时间",
+ "type": "string"
+ },
+ "auditer_id": {
+ "description": "审核人ID (关联user.id)",
+ "type": "integer"
+ },
+ "auditer_name": {
+ "description": "审核人名称",
+ "type": "string"
+ },
+ "business_close": {
+ "description": "业务关闭",
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/common.BusinessClose"
+ }
+ ]
+ },
+ "business_close_name": {
+ "description": "业务关闭状态name",
+ "type": "string"
+ },
+ "business_close_time": {
+ "description": "业务关闭时间",
+ "type": "string"
+ },
+ "business_close_user_id": {
+ "description": "业务关闭操作人",
+ "type": "integer"
+ },
+ "business_close_user_name": {
+ "description": "业务关闭操作人名",
+ "type": "string"
+ },
+ "business_unit_id": {
+ "description": "往来单位id,必填",
+ "type": "integer"
+ },
+ "business_unit_name": {
+ "description": "往来单位name",
+ "type": "string"
+ },
+ "create_time": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "creator_id": {
+ "description": "创建人",
+ "type": "integer"
+ },
+ "creator_name": {
+ "description": "创建人",
+ "type": "string"
+ },
+ "customer_id": {
+ "description": "该条码所属客户id",
+ "type": "integer"
+ },
+ "customer_name": {
+ "description": "该条码所属客户",
+ "type": "string"
+ },
+ "delivery_time": {
+ "description": "出货日期,必",
+ "type": "string"
+ },
+ "delivery_unit_id": {
+ "description": "出货单位id,必填",
+ "type": "integer"
+ },
+ "delivery_unit_name": {
+ "description": "出货单位name",
+ "type": "string"
+ },
+ "department_id": {
+ "description": "下单用户所属部门",
+ "type": "integer"
+ },
+ "grey_fabric_code": {
+ "description": "坯布编号",
+ "type": "string"
+ },
+ "grey_fabric_level_id": {
+ "description": "坯布等级id",
+ "type": "array",
+ "items": {
+ "type": "integer"
+ }
+ },
+ "grey_fabric_level_name": {
+ "description": "坯布等级",
+ "type": "string"
+ },
+ "grey_fabric_name": {
+ "description": "坯布名称",
+ "type": "string"
+ },
+ "id": {
+ "description": "记录ID",
+ "type": "integer"
+ },
+ "item_data": {
+ "description": "坯布信息",
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/grey_fabric_manage.GetGfmOtherDeliveryOrderItemData"
+ }
+ },
+ "machine_number": {
+ "description": "机台号",
+ "type": "string"
+ },
+ "number": {
+ "description": "编号流水:每日重新更新",
+ "type": "integer"
+ },
+ "order_no": {
+ "description": "单据编号",
+ "type": "string"
+ },
+ "produce_order_no": {
+ "description": "生产通知单号",
+ "type": "string"
+ },
+ "remark": {
+ "description": "备注",
+ "type": "string"
+ },
+ "sale_system_id": {
+ "description": "营销体系id,必填",
+ "type": "integer"
+ },
+ "sale_system_name": {
+ "description": "营销体系name",
+ "type": "string"
+ },
+ "scanned_total_roll": {
+ "description": "PDA扫码操作后补充返回的统计及当前条码信息",
+ "type": "integer"
+ },
+ "summary_stock_roll": {
+ "description": "该条码汇总库存条数",
+ "type": "number"
+ },
+ "total_roll": {
+ "description": "总匹数,0.01匹",
+ "type": "number"
+ },
+ "total_weight": {
+ "description": "总数量,xxx/g",
+ "type": "integer"
+ },
+ "update_time": {
+ "description": "修改时间",
+ "type": "string"
+ },
+ "update_user_name": {
+ "description": "修改人",
+ "type": "string"
+ },
+ "updater_id": {
+ "description": "修改人",
+ "type": "integer"
+ },
+ "volume_number": {
+ "description": "卷号",
+ "type": "string"
+ },
+ "yarn_batch": {
+ "description": "纱批",
+ "type": "string"
+ }
+ }
+ },
+ "grey_fabric_manage.GetGfmOtherDeliveryOrderItemData": {
+ "type": "object",
+ "properties": {
+ "create_time": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "creator_id": {
+ "description": "创建人",
+ "type": "integer"
+ },
+ "creator_name": {
+ "description": "创建人",
+ "type": "string"
+ },
+ "customer_id": {
+ "description": "客户id,必填",
+ "type": "integer"
+ },
+ "customer_name": {
+ "description": "客户名",
+ "type": "string"
+ },
+ "gray_fabric_color_id": {
+ "description": "坯布颜色id",
+ "type": "integer"
+ },
+ "gray_fabric_color_name": {
+ "description": "颜色名",
+ "type": "string"
+ },
+ "grey_fabric_code": {
+ "description": "坯布编号,必",
+ "type": "string"
+ },
+ "grey_fabric_gram_weight": {
+ "description": "坯布克重",
+ "type": "string"
+ },
+ "grey_fabric_gram_weight_and_unit_name": {
+ "description": "坯布克重及单位名称",
+ "type": "string"
+ },
+ "grey_fabric_gram_weight_unit_id": {
+ "description": "坯布克重单位id(字典)",
+ "type": "integer"
+ },
+ "grey_fabric_gram_weight_unit_name": {
+ "description": "坯布克重单位名称",
+ "type": "string"
+ },
+ "grey_fabric_id": {
+ "description": "坯布id",
+ "type": "integer"
+ },
+ "grey_fabric_level_id": {
+ "description": "坯布等级id",
+ "type": "array",
+ "items": {
+ "type": "integer"
+ }
+ },
+ "grey_fabric_level_name": {
+ "description": "等级名",
+ "type": "string"
+ },
+ "grey_fabric_name": {
+ "description": "坯布名,必",
+ "type": "string"
+ },
+ "grey_fabric_other_delivery_id": {
+ "description": "坯布出货单id",
+ "type": "integer"
+ },
+ "grey_fabric_remark": {
+ "description": "坯布备注",
+ "type": "string"
+ },
+ "grey_fabric_width": {
+ "description": "坯布幅宽",
+ "type": "string"
+ },
+ "grey_fabric_width_and_unit_name": {
+ "description": "坯布幅宽及单位名称",
+ "type": "string"
+ },
+ "grey_fabric_width_unit_id": {
+ "description": "坯布幅宽单位id(字典)",
+ "type": "integer"
+ },
+ "grey_fabric_width_unit_name": {
+ "description": "坯布幅宽单位名称",
+ "type": "string"
+ },
+ "id": {
+ "description": "记录ID",
+ "type": "integer"
+ },
+ "item_fc_data": {
+ "description": "细码",
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/grey_fabric_manage.GetGfmOtherDeliveryOrderItemFineCodeData"
+ }
+ },
+ "machine_number": {
+ "description": "机台号",
+ "type": "string"
+ },
+ "needle_size": {
+ "description": "针寸数",
+ "type": "string"
+ },
+ "order_no": {
+ "description": "单据编号",
+ "type": "string"
+ },
+ "raw_material_batch_brand": {
+ "description": "原料品牌",
+ "type": "string"
+ },
+ "raw_material_batch_num": {
+ "description": "原料批号",
+ "type": "string"
+ },
+ "raw_material_yarn_name": {
+ "description": "原料纱名",
+ "type": "string"
+ },
+ "remark": {
+ "description": "备注",
+ "type": "string"
+ },
+ "roll": {
+ "description": "出货匹数,必,乘100xx/0.01匹",
+ "type": "integer"
+ },
+ "total_weight": {
+ "description": "总数量,xxx/g;细码中所有数量字段总和",
+ "type": "integer"
+ },
+ "update_time": {
+ "description": "修改时间",
+ "type": "string"
+ },
+ "update_user_name": {
+ "description": "修改人",
+ "type": "string"
+ },
+ "updater_id": {
+ "description": "修改人",
+ "type": "integer"
+ },
+ "warehouse_sum_id": {
+ "description": "汇总库存id",
+ "type": "integer"
+ },
+ "weaving_process": {
+ "description": "织造工艺",
+ "type": "string"
+ },
+ "yarn_batch": {
+ "description": "纱批",
+ "type": "string"
+ }
+ }
+ },
+ "grey_fabric_manage.GetGfmOtherDeliveryOrderItemFineCodeData": {
+ "type": "object",
+ "properties": {
+ "bar_code": {
+ "description": "条码",
+ "type": "string"
+ },
+ "create_time": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "creator_id": {
+ "description": "创建人",
+ "type": "integer"
+ },
+ "creator_name": {
+ "description": "创建人",
+ "type": "string"
+ },
+ "fabric_piece_code": {
+ "description": "条码",
+ "type": "string"
+ },
+ "gfm_other_delivery_item_id": {
+ "description": "坯布出货信息id",
+ "type": "integer"
+ },
+ "grey_fabric_stock_id": {
+ "description": "坯布仓库-坯布库存id",
+ "type": "integer"
+ },
+ "id": {
+ "description": "记录ID",
+ "type": "integer"
+ },
+ "position": {
+ "description": "仓位",
+ "type": "string"
+ },
+ "roll": {
+ "description": "匹数,必;乘100xx/0.01匹",
+ "type": "integer"
+ },
+ "update_time": {
+ "description": "修改时间",
+ "type": "string"
+ },
+ "update_user_name": {
+ "description": "修改人",
+ "type": "string"
+ },
+ "updater_id": {
+ "description": "修改人",
+ "type": "integer"
+ },
+ "volume_number": {
+ "description": "卷号",
+ "type": "string"
+ },
+ "warehouse_bin_id": {
+ "description": "仓位id",
+ "type": "integer"
+ },
+ "weight": {
+ "description": "数量,xxx/g",
+ "type": "integer"
+ }
+ }
+ },
+ "grey_fabric_manage.PDAScanGfmOtherDeliveryOrderParam": {
+ "type": "object",
+ "properties": {
+ "grey_fabric_code_lock": {
+ "description": "坯布编号锁定",
+ "type": "string"
+ },
+ "grey_fabric_level_id_lock": {
+ "description": "坯布等级锁定",
+ "type": "array",
+ "items": {
+ "type": "integer"
+ }
+ },
+ "id": {
+ "description": "坯布出仓单id,必填",
+ "type": "integer"
+ },
+ "machine_number_lock": {
+ "description": "机台锁定",
+ "type": "string"
+ },
+ "produce_order_no_lock": {
+ "description": "生产通知单锁定",
+ "type": "string"
+ },
+ "scan_code": {
+ "description": "扫描的坯布条码(细码条码fabric_piece_code 或 卷号volume_number),必填",
+ "type": "string"
+ },
+ "scan_type": {
+ "description": "操作类型:1扫码新增 2扫码删除,必填",
+ "type": "integer"
+ },
+ "yarn_batch_lock": {
+ "description": "纱批锁定",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "responses": {},
+ "securitySchemes": {
+ "ApiKeyAuth": {
+ "type": "apiKey",
+ "name": "Authorization",
+ "in": "header"
+ }
+ }
+ },
+ "servers": [],
+ "security": []
+}
\ No newline at end of file