Compare commits
31
Commits
main
..
e8ae05b87b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8ae05b87b | ||
|
|
c4d5db056b | ||
|
|
7b199ba559 | ||
|
|
322ada8428 | ||
|
|
3e9b0fd1a8 | ||
|
|
b734f50f0a | ||
|
|
b04f890664 | ||
|
|
304d7ccde0 | ||
|
|
45a8928564 | ||
|
|
f6f85ed8ce | ||
|
|
3e936b064d | ||
|
|
7c6c7a1b32 | ||
|
|
c8ce45ae38 | ||
|
|
bff563b444 | ||
|
|
63755eab5c | ||
|
|
26c7085ab2 | ||
|
|
53a059f16b | ||
|
|
e0ee8d8c8d | ||
|
|
fa0ff1614b | ||
|
|
3f2481d1eb | ||
|
|
162e10a6fc | ||
|
|
26ff443107 | ||
|
|
02f192cac6 | ||
|
|
530ca0c3ad | ||
|
|
b3ecd77fb2 | ||
|
|
36c0f9a3a0 | ||
|
|
084bb235f8 | ||
|
|
567da03aea | ||
|
|
d5b2e19658 | ||
|
|
cff4debea4 | ||
|
|
ebfa5bf2a0 |
@@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
description: PDA 小屏界面字号与排版标准(以手动进仓页为准)
|
||||||
|
alwaysApply: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# PDA 字号标准
|
||||||
|
|
||||||
|
本项目面向工业 PDA 小屏。新增/改版业务页时,**以后台手动进仓页**(`storeFabricManualIn.vue`)的字号为准,不要用偏小的默认字号。
|
||||||
|
|
||||||
|
共用变量:`@import '@/common/pda-typography.scss';`(或等价路径)。
|
||||||
|
|
||||||
|
## 字号(rpx)
|
||||||
|
|
||||||
|
| 用途 | 字号 | 变量 |
|
||||||
|
|------|------|------|
|
||||||
|
| 表单标签 / 正文 / 输入值 | **36** | `$pda-font-body` |
|
||||||
|
| 扫码输入框 | **36** | `$pda-font-body` |
|
||||||
|
| 占位提示 | **34** | `$pda-font-placeholder` |
|
||||||
|
| 行内操作(取消/修改) | **34** | `$pda-font-action` |
|
||||||
|
| 单位角标(如 KG) | **32** | `$pda-font-unit` |
|
||||||
|
| 顶栏次要文字(设置等) | **32** | `$pda-font-nav-sub` |
|
||||||
|
| 主按钮文字 | **36** | `$pda-font-button` |
|
||||||
|
| 弹层标题 / 选项 | **36** | `$pda-font-popup-title` / `$pda-font-popup-item` |
|
||||||
|
| 弹层取消 / 空态 | **34** | `$pda-font-popup-sub` |
|
||||||
|
|
||||||
|
## 行高与触控
|
||||||
|
|
||||||
|
- 列表行最小高度约 **100rpx**,可略加上下 padding
|
||||||
|
- 扫码输入框高度约 **100rpx**
|
||||||
|
- 主按钮高度约 **92rpx**
|
||||||
|
- 标签列宽约 **200rpx**(中文四字标签)
|
||||||
|
|
||||||
|
## 注意
|
||||||
|
|
||||||
|
- 登录环境选择、出仓明细等已放大过的页面,新改动保持不低于上表
|
||||||
|
- 不要为了“好看”再缩小字号;宁可少露内容、可滚动,也要可读
|
||||||
|
- 选择类弹层(如 `SearchSelectPopup`)与表单页使用同一套字号
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
NODE_ENV = development
|
NODE_ENV = production
|
||||||
VUE_APP_ENV_NAME = zhisheng环境
|
VUE_APP_ENV_NAME = zhoushang环境
|
||||||
VUE_APP_UPGRADE_NAME = erp_pda_pre
|
VUE_APP_UPGRADE_NAME = erp_pda_zhoushang_zhichang
|
||||||
VUE_APP_PRODUCTION_API_URL = https://hcscmpre.zzfzyc.com/hcscm/pda/v1
|
VUE_APP_PRODUCTION_API_URL = https://www.haotopai.com/hcscm_weave/mes/server/pda/v1
|
||||||
VUE_APP_DEV_API_URL = https://hcscmpre.zzfzyc.com/hcscm/pda/v1
|
VUE_APP_DEV_API_URL = https://www.haotopai.com/hcscm_weave/mes/server/pda/v1
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
NODE_ENV = development
|
||||||
|
VUE_APP_ENV_NAME = 本地环境
|
||||||
|
VUE_APP_UPGRADE_NAME = erp_pda_dev
|
||||||
|
VUE_APP_PRODUCTION_API_URL = http://192.168.1.66:7010/hcscm_weave/pda/v1
|
||||||
|
VUE_APP_DEV_API_URL = https://192.168.1.66:7010/hcscm_weave/pda/v1
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
NODE_ENV = development
|
NODE_ENV = development
|
||||||
VUE_APP_ENV_NAME = mes环境
|
VUE_APP_ENV_NAME = mes环境
|
||||||
VUE_APP_UPGRADE_NAME = erp_pda
|
VUE_APP_UPGRADE_NAME = erp_pda
|
||||||
VUE_APP_PRODUCTION_API_URL = https://www.haotopai.com/hcscm/mes/server/pda/v1
|
VUE_APP_PRODUCTION_API_URL = https://www.haotopai.com/hcscm_weave/mes/server/pda/v1
|
||||||
VUE_APP_DEV_API_URL = https://www.haotopai.com/hcscm/mes/server/pda/v1
|
VUE_APP_DEV_API_URL = https://www.haotopai.com/hcscm_weave/mes/server/pda/v1
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
NODE_ENV = development
|
NODE_ENV = development
|
||||||
VUE_APP_ENV_NAME = zhisheng环境
|
VUE_APP_ENV_NAME = zhisheng环境
|
||||||
VUE_APP_UPGRADE_NAME = erp_pda_pre
|
VUE_APP_UPGRADE_NAME = erp_pda_pre
|
||||||
VUE_APP_PRODUCTION_API_URL = https://hcscmpre.zzfzyc.com/hcscm/pda/v1
|
VUE_APP_PRODUCTION_API_URL = https://hcscmpre.zzfzyc.com/hcscm_weave/pda/v1
|
||||||
VUE_APP_DEV_API_URL = https://hcscmpre.zzfzyc.com/hcscm/pda/v1
|
VUE_APP_DEV_API_URL = https://hcscmpre.zzfzyc.com/hcscm_weave/pda/v1
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
NODE_ENV = production
|
||||||
|
VUE_APP_ENV_NAME = zhoushang环境
|
||||||
|
VUE_APP_UPGRADE_NAME = erp_pda_zhoushang_zhichang
|
||||||
|
VUE_APP_PRODUCTION_API_URL = https://www.haotopai.com/hcscm_weave/mes/server/pda/v1
|
||||||
|
VUE_APP_DEV_API_URL = https://www.haotopai.com/hcscm_weave/mes/server/pda/v1
|
||||||
@@ -1,5 +1,20 @@
|
|||||||
# 不使用 pda项目,以后的新需求或者修改 使用 本项目
|
# 不使用 pda项目,以后的新需求或者修改 使用 本项目
|
||||||
|
|
||||||
|
打包正式环境发布:
|
||||||
|
|
||||||
|
先修改 .env 文件,修改为目标请求路径
|
||||||
|
|
||||||
|
NODE_ENV = development
|
||||||
|
VUE_APP_ENV_NAME = 默认环境
|
||||||
|
VUE_APP_UPGRADE_NAME = erp_pda
|
||||||
|
VUE_APP_PRODUCTION_API_URL = https://www.haotopai.com/hcscm/mes/server/pda/v1
|
||||||
|
VUE_APP_DEV_API_URL = https://www.haotopai.com/hcscm/mes/server/pda/v1
|
||||||
|
|
||||||
|
|
||||||
|
HBuilderX中 点击 生成本地打包APP资源
|
||||||
|
|
||||||
|
点击云打包 选择自有证书 输入证书库密码和证书私钥密码:123456 点击快速安心打包
|
||||||
|
|
||||||
# pda-cli
|
# pda-cli
|
||||||
|
|
||||||
## Project setup
|
## Project setup
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
"build": "npm run build:h5",
|
"build": "npm run build:h5",
|
||||||
"build:app-plus": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build",
|
"build:app-plus": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build",
|
||||||
"build:app-plus:zhisheng": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build --mode zhisheng",
|
"build:app-plus:zhisheng": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build --mode zhisheng",
|
||||||
|
"build:app-plus:zhoushang": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build --mode zhoushang",
|
||||||
"build:app-plus:mes": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build --mode mes",
|
"build:app-plus:mes": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build --mode mes",
|
||||||
"build:custom": "cross-env NODE_ENV=production uniapp-cli custom",
|
"build:custom": "cross-env NODE_ENV=production uniapp-cli custom",
|
||||||
"build:h5": "cross-env NODE_ENV=production UNI_PLATFORM=h5 vue-cli-service uni-build",
|
"build:h5": "cross-env NODE_ENV=production UNI_PLATFORM=h5 vue-cli-service uni-build",
|
||||||
@@ -117,6 +118,11 @@
|
|||||||
"Android >= 4.4",
|
"Android >= 4.4",
|
||||||
"ios >= 9"
|
"ios >= 9"
|
||||||
],
|
],
|
||||||
|
"pnpm": {
|
||||||
|
"overrides": {
|
||||||
|
"postcss-urlrewrite": "0.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"uni-app": {
|
"uni-app": {
|
||||||
"scripts": {}
|
"scripts": {}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-7
@@ -20,19 +20,22 @@ const config = {
|
|||||||
// 环境判断
|
// 环境判断
|
||||||
isDevelopment: isDevelopment,
|
isDevelopment: isDevelopment,
|
||||||
|
|
||||||
// 生产环境API URL
|
// 生产环境API URL(服务名段 hcscm_weave)
|
||||||
productionApiUrl: process.env.VUE_APP_PRODUCTION_API_URL || 'https://www.haotopai.com/hcscm/mes/server/pda/v1',
|
productionApiUrl: process.env.VUE_APP_PRODUCTION_API_URL || 'https://www.haotopai.com/hcscm_weave/mes/server/pda/v1',
|
||||||
|
|
||||||
// 开发环境API URL选项
|
// 开发环境API URL选项(仅替换 //域名/ 后第一个路径段 hcscm → hcscm_weave,不改域名)
|
||||||
devApiUrlOptions: [
|
devApiUrlOptions: [
|
||||||
{ label: '测试环境', value: 'https://hcscmtest.zzfzyc.com/hcscm/pda/v1' },
|
{ label: '测试环境', value: 'https://hcscmtest.zzfzyc.com/hcscm_weave/pda/v1' },
|
||||||
{ label: '正式环境', value: process.env.VUE_APP_DEV_API_URL || 'https://www.haotopai.com/hcscm/mes/server/pda/v1' },
|
{ label: '正式环境', value: process.env.VUE_APP_DEV_API_URL || process.env.VUE_APP_PRODUCTION_API_URL || 'https://www.haotopai.com/hcscm_weave/mes/server/pda/v1' },
|
||||||
|
{ label: '本地环境', value: 'http://192.168.1.66:7010/hcscm_weave/pda/v1' },
|
||||||
{ label: '自定义', value: 'custom' }
|
{ label: '自定义', value: 'custom' }
|
||||||
]
|
]
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置后台接口服务的基础地址 - 使用动态API URL
|
export function getTestApiUrl() {
|
||||||
// config.baseUrl = 'https://aidex.vip/api'; // 注释掉固定的baseUrl
|
const test = config.devApiUrlOptions.find(item => item.label === '测试环境');
|
||||||
|
return (test && test.value) || 'https://hcscmtest.zzfzyc.com/hcscm_weave/pda/v1';
|
||||||
|
}
|
||||||
|
|
||||||
export default config;
|
export default config;
|
||||||
|
|||||||
@@ -7,9 +7,71 @@ const install = (Vue, vm) => {
|
|||||||
// 参数配置对象
|
// 参数配置对象
|
||||||
const config = vm.vuex_config;
|
const config = vm.vuex_config;
|
||||||
console.log('install u',config)
|
console.log('install u',config)
|
||||||
|
|
||||||
|
// 坯布出仓单接口前缀(apiurl 已在 config.js 统一配置为 hcscm_weave 服务)
|
||||||
|
const GFM_OTHER_DELIVERY_PREFIX = '/grey_fabric_manage/gfmOtherDeliveryOrder/';
|
||||||
|
const gfmOtherDeliveryUrl = (name) => (vm.$store.state.apiurl || '') + GFM_OTHER_DELIVERY_PREFIX + name;
|
||||||
|
|
||||||
|
// 坯布库存接口前缀
|
||||||
|
const GFM_WAREHOUSE_PREFIX = '/grey_fabric_manage/gfmWarehouse/';
|
||||||
|
const gfmWarehouseUrl = (name) => (vm.$store.state.apiurl || '') + GFM_WAREHOUSE_PREFIX + name;
|
||||||
|
|
||||||
// 将各个定义的接口名称,统一放进对象挂载到vm.$u.api(因为vm就是this,也即this.$u.api)下
|
// 将各个定义的接口名称,统一放进对象挂载到vm.$u.api(因为vm就是this,也即this.$u.api)下
|
||||||
vm.$u.api = {
|
vm.$u.api = {
|
||||||
|
|
||||||
|
// 坯布出仓单(其他出货单)相关接口
|
||||||
|
gfmOtherDeliveryOrder: {
|
||||||
|
// 获取坯布出仓单列表(query: page,size,order_no,audit_status)
|
||||||
|
list: (params = {}) => vm.$u.get(gfmOtherDeliveryUrl('getGfmOtherDeliveryOrderList'), params),
|
||||||
|
// 获取坯布出仓单详情(query: id)
|
||||||
|
detail: (params = {}) => vm.$u.get(gfmOtherDeliveryUrl('getGfmOtherDeliveryOrder'), params),
|
||||||
|
// 新增坯布出仓单(提交表头信息保存,返回 { id })
|
||||||
|
add: (params = {}) => vm.$u.postJson(gfmOtherDeliveryUrl('addGfmOtherDeliveryOrder'), params),
|
||||||
|
// 扫码新增/删除细码(scan_type: 1新增 2删除;勾选锁定维度时附带 *_lock 字段),返回最新详情
|
||||||
|
scanUpdate: (params = {}) => vm.$u.putJson(gfmOtherDeliveryUrl('updateGfmOtherDeliveryOrder'), params),
|
||||||
|
// 审核
|
||||||
|
statusPass: (params = {}) => vm.$u.putJson(gfmOtherDeliveryUrl('updateGfmOtherDeliveryOrderStatusPass'), params),
|
||||||
|
// 消审
|
||||||
|
statusWait: (params = {}) => vm.$u.putJson(gfmOtherDeliveryUrl('updateGfmOtherDeliveryOrderStatusWait'), params),
|
||||||
|
// 驳回
|
||||||
|
statusReject: (params = {}) => vm.$u.putJson(gfmOtherDeliveryUrl('updateGfmOtherDeliveryOrderStatusReject'), params),
|
||||||
|
// 作废
|
||||||
|
statusCancel: (params = {}) => vm.$u.putJson(gfmOtherDeliveryUrl('updateGfmOtherDeliveryOrderStatusCancel'), params),
|
||||||
|
},
|
||||||
|
|
||||||
|
// 坯布库存相关接口
|
||||||
|
gfmWarehouse: {
|
||||||
|
groupSummaryList: (params = {}) => vm.$u.get(gfmWarehouseUrl('getGfmWarehouseSummaryWeavingFactoryStockGroupList'), params),
|
||||||
|
stockSummaryList: (params = {}) => vm.$u.get(gfmWarehouseUrl('getGfmWarehouseSummaryWeavingFactoryStockList'), params),
|
||||||
|
detailList: (params = {}) => vm.$u.get(gfmWarehouseUrl('getGfmWarehouseList'), params),
|
||||||
|
},
|
||||||
|
|
||||||
|
// PDA 生产进仓(排产单细码扫码进仓)
|
||||||
|
productionScheduleOrder: {
|
||||||
|
getScanFineCodeDetail: (params = {}) => vm.$u.get('/produce/productionScheduleOrder/getScanFineCodeDetail', params),
|
||||||
|
scanInWarehouseFineCode: (params = {}) => vm.$u.putJson('/produce/productionScheduleOrder/scanInWarehouseFineCode', params),
|
||||||
|
},
|
||||||
|
|
||||||
|
// 营销体系下拉(路径相对 apiurl:.../pda/v1/saleSystem/getSaleSystemDropdownList)
|
||||||
|
saleSystem: {
|
||||||
|
getDropdownList: (params = {}) => vm.$u.get('/saleSystem/getSaleSystemDropdownList', params),
|
||||||
|
},
|
||||||
|
|
||||||
|
// 往来单位列表(路径相对 apiurl:.../pda/v1/business_unit/list)
|
||||||
|
businessUnit: {
|
||||||
|
list: (params = {}) => vm.$u.get('/business_unit/list', params),
|
||||||
|
},
|
||||||
|
|
||||||
|
// 员工枚举(路径相对 apiurl:.../pda/v1/employee/list_enum)
|
||||||
|
employee: {
|
||||||
|
listEnum: (params = {}) => vm.$u.get('/employee/list_enum', params),
|
||||||
|
},
|
||||||
|
|
||||||
|
// 字典明细枚举(路径相对 apiurl:.../pda/v1/dictionaryDetail/getDictionaryDetailEnumList)
|
||||||
|
dictionary: {
|
||||||
|
getDetailEnumList: (params = {}) => vm.$u.get('/dictionaryDetail/getDictionaryDetailEnumList', params),
|
||||||
|
},
|
||||||
|
|
||||||
// 基础服务:登录登出、身份信息、菜单授权、切换系统、字典数据等
|
// 基础服务:登录登出、身份信息、菜单授权、切换系统、字典数据等
|
||||||
lang: (params = {}) => vm.$u.get('/lang/'+params.lang),
|
lang: (params = {}) => vm.$u.get('/lang/'+params.lang),
|
||||||
index: (params = {}) => vm.$u.get(config.productionApiUrl+'/mobile/index', params),
|
index: (params = {}) => vm.$u.get(config.productionApiUrl+'/mobile/index', params),
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ const install = (Vue, vm) => {
|
|||||||
console.log('request', req);
|
console.log('request', req);
|
||||||
console.log('baseUrl', vm.$store.state.apiurl);
|
console.log('baseUrl', vm.$store.state.apiurl);
|
||||||
console.log('完整URL', vm.$store.state.apiurl + req.url);
|
console.log('完整URL', vm.$store.state.apiurl + req.url);
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
// Android 5.x 等老 PDA 不信任 Let's Encrypt 新证书链,关闭校验证书
|
||||||
|
req.sslVerify = false;
|
||||||
|
// #endif
|
||||||
if (!req.header){
|
if (!req.header){
|
||||||
req.header = [];
|
req.header = [];
|
||||||
}
|
}
|
||||||
@@ -70,8 +74,12 @@ const install = (Vue, vm) => {
|
|||||||
}
|
}
|
||||||
console.log('res',res)
|
console.log('res',res)
|
||||||
if (!(res.data)){
|
if (!(res.data)){
|
||||||
vm.$u.toast('未连接到服务器')
|
const errMsg = String((res && res.errMsg) || '');
|
||||||
return Promise.reject(new Error('未连接到服务器'));
|
const isNetworkError = res.statusCode === -1
|
||||||
|
|| /Unable to resolve host|Failed to connect|request:fail|timeout|网络/i.test(errMsg);
|
||||||
|
const message = isNetworkError ? '当前没有网络,请检查网络后重试' : '未连接到服务器';
|
||||||
|
vm.$u.toast(message)
|
||||||
|
return Promise.reject(new Error(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(res.data.code !== 0) {
|
if(res.data.code !== 0) {
|
||||||
@@ -159,6 +167,9 @@ const install = (Vue, vm) => {
|
|||||||
uni.request({
|
uni.request({
|
||||||
url,
|
url,
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
sslVerify: false,
|
||||||
|
// #endif
|
||||||
header: {
|
header: {
|
||||||
...header,
|
...header,
|
||||||
'Platform': 2,
|
'Platform': 2,
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* PDA 小屏字号标准(以手动进仓页为准)
|
||||||
|
* 业务页请优先引用这些变量,避免字号再次变小。
|
||||||
|
*/
|
||||||
|
|
||||||
|
$pda-font-body: 36rpx;
|
||||||
|
$pda-font-placeholder: 34rpx;
|
||||||
|
$pda-font-action: 34rpx;
|
||||||
|
$pda-font-unit: 32rpx;
|
||||||
|
$pda-font-nav-sub: 32rpx;
|
||||||
|
$pda-font-button: 36rpx;
|
||||||
|
$pda-font-popup-title: 36rpx;
|
||||||
|
$pda-font-popup-item: 36rpx;
|
||||||
|
$pda-font-popup-sub: 34rpx;
|
||||||
|
|
||||||
|
$pda-row-min-height: 100rpx;
|
||||||
|
$pda-scan-input-height: 100rpx;
|
||||||
|
$pda-button-height: 92rpx;
|
||||||
|
$pda-label-width: 200rpx;
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
export const STORAGE_KEY = 'pda_scan_config';
|
||||||
|
|
||||||
|
export const DICTIONARY_TYPE_SCANNER = 10046;
|
||||||
|
|
||||||
|
export const PHONE_SCAN_BRAND = 'phone';
|
||||||
|
|
||||||
|
// 历史误用 brand=newland 表示东集;真正的新大陆是 nlscan
|
||||||
|
const LEGACY_SEUIC_BRANDS = ['newland', '东集', 'idata'];
|
||||||
|
|
||||||
|
export const PHONE_SCAN_CONFIG = {
|
||||||
|
brand: PHONE_SCAN_BRAND,
|
||||||
|
name: '手机扫码',
|
||||||
|
isPhoneScan: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const NO_SETUP_HINT_KEY = 'pda_scan_config_hint_shown';
|
||||||
|
|
||||||
|
export function isPhoneScanConfig(config) {
|
||||||
|
return !!(config && (config.isPhoneScan || config.brand === PHONE_SCAN_BRAND));
|
||||||
|
}
|
||||||
|
|
||||||
|
function migrateLegacySeuicBrand(config) {
|
||||||
|
if (!config || isPhoneScanConfig(config)) {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
const brand = String(config.brand || '');
|
||||||
|
const name = String(config.name || '');
|
||||||
|
const action = String(config.action || '');
|
||||||
|
// 历史内置配置把东集误标成 brand=newland;真正的新大陆是 nlscan
|
||||||
|
const isLegacySeuicLabel = LEGACY_SEUIC_BRANDS.includes(brand) || name === '东集';
|
||||||
|
if (!isLegacySeuicLabel) {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
if (action.includes('nlscan')) {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...config,
|
||||||
|
brand: 'seuic',
|
||||||
|
name: (!name || name === '东集') ? '东大集成(AUTOID)' : name,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function enrichFromBuiltinConfig(config, builtinConfigs = []) {
|
||||||
|
if (!config || !builtinConfigs.length) {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
const builtin = builtinConfigs.find((item) => {
|
||||||
|
return item.action === config.action
|
||||||
|
|| item.name === config.name
|
||||||
|
|| item.brand === config.brand
|
||||||
|
|| (item.brand === 'seuic' && (
|
||||||
|
String(config.name || '').includes('东大')
|
||||||
|
|| String(config.name || '').includes('东集')
|
||||||
|
|| String(config.name || '').includes('AUTOID')
|
||||||
|
|| String(config.action || '').includes('scannerservice.broadcast')
|
||||||
|
));
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!builtin) {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...config,
|
||||||
|
needSetup: builtin.needSetup,
|
||||||
|
setupAction: builtin.setupAction || '',
|
||||||
|
setupParams: builtin.setupParams || null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalizeConfig(raw, builtinConfigs = []) {
|
||||||
|
if (!raw || typeof raw !== 'object') return null;
|
||||||
|
|
||||||
|
const brand = String(raw.brand || raw.id || raw.dictionary_detail_id || raw.name || '');
|
||||||
|
const isPhoneScan = raw.isPhoneScan === true || brand === PHONE_SCAN_BRAND;
|
||||||
|
|
||||||
|
if (isPhoneScan) {
|
||||||
|
return { ...PHONE_SCAN_CONFIG };
|
||||||
|
}
|
||||||
|
|
||||||
|
let config = {
|
||||||
|
brand,
|
||||||
|
name: raw.name || '',
|
||||||
|
action: raw.action || raw.code || '',
|
||||||
|
dataKey: raw.dataKey || raw.data_key || raw.remark || '',
|
||||||
|
needSetup: raw.needSetup != null ? raw.needSetup : !!raw.need_setup,
|
||||||
|
setupAction: raw.setupAction || raw.setup_action || '',
|
||||||
|
setupParams: raw.setupParams || raw.setup_params || null,
|
||||||
|
};
|
||||||
|
|
||||||
|
config = migrateLegacySeuicBrand(config);
|
||||||
|
config = enrichFromBuiltinConfig(config, builtinConfigs);
|
||||||
|
|
||||||
|
if (!config.brand || !config.action || !config.dataKey) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapDictionaryToScannerConfig(raw, builtinConfigs = []) {
|
||||||
|
return normalizeConfig(raw, builtinConfigs);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getScanConfig(builtinConfigs = []) {
|
||||||
|
try {
|
||||||
|
const data = uni.getStorageSync(STORAGE_KEY);
|
||||||
|
const normalized = normalizeConfig(data, builtinConfigs);
|
||||||
|
// 旧 brand=newland(东集) 迁移后写回,避免下次仍读到错误 brand
|
||||||
|
if (normalized && data && String(data.brand || '') !== String(normalized.brand || '')) {
|
||||||
|
try {
|
||||||
|
uni.setStorageSync(STORAGE_KEY, normalized);
|
||||||
|
} catch (e) {
|
||||||
|
console.log('迁移扫码枪配置写回失败', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return normalized;
|
||||||
|
} catch (e) {
|
||||||
|
console.log('读取扫码枪配置失败', e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function saveScanConfig(config) {
|
||||||
|
const normalized = normalizeConfig(config);
|
||||||
|
if (!normalized) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
uni.setStorageSync(STORAGE_KEY, normalized);
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
console.log('保存扫码枪配置失败', e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hasShownNoConfigHint() {
|
||||||
|
try {
|
||||||
|
return !!uni.getStorageSync(NO_SETUP_HINT_KEY);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function markNoConfigHintShown() {
|
||||||
|
try {
|
||||||
|
uni.setStorageSync(NO_SETUP_HINT_KEY, true);
|
||||||
|
} catch (e) {
|
||||||
|
console.log('记录扫码枪提示状态失败', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
+198
-68
@@ -1,98 +1,213 @@
|
|||||||
// common/scanMixin.js
|
// common/scanMixin.js
|
||||||
// 多厂商PDA扫码器兼容方案 - 策略模式 + 配置表驱动
|
// 多厂商PDA扫码器兼容方案 - 策略模式 + 配置表驱动
|
||||||
|
import {
|
||||||
|
getScanConfig,
|
||||||
|
hasShownNoConfigHint,
|
||||||
|
isPhoneScanConfig,
|
||||||
|
markNoConfigHintShown,
|
||||||
|
normalizeConfig,
|
||||||
|
PHONE_SCAN_CONFIG,
|
||||||
|
} from '@/common/scanConfig.js';
|
||||||
|
|
||||||
|
const PDA_DEVICE_KEYWORDS = [
|
||||||
|
'newland', 'nls', 'nlscan', 'sunmi', 'urovo', 'zebra', 'honeywell',
|
||||||
|
'idata', 'seuic', 'autoid', '东集', '东大',
|
||||||
|
];
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
scanReceivers: [], // 支持多个接收器
|
scanReceivers: [],
|
||||||
isPageActive: false,
|
isPageActive: false,
|
||||||
registeredBrands: [] // 已注册的品牌
|
registeredBrands: [],
|
||||||
|
remoteScannerConfigs: [],
|
||||||
|
usePhoneScanFallback: false,
|
||||||
|
_scanCallback: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
// 扫码器配置表 - 方便扩展新厂商
|
|
||||||
getScannerConfigs() {
|
getScannerConfigs() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
brand: 'newland', // 东集
|
// 东大集成 SEUIC / AUTOID 系列(如 AUTOID9),勿与新大陆 nlscan 混淆
|
||||||
name: '东集',
|
brand: 'seuic',
|
||||||
|
name: '东大集成(AUTOID)',
|
||||||
action: 'com.android.server.scannerservice.broadcast',
|
action: 'com.android.server.scannerservice.broadcast',
|
||||||
dataKey: 'scannerdata',
|
dataKey: 'scannerdata',
|
||||||
needSetup: true,
|
needSetup: true,
|
||||||
setupAction: 'com.android.scanner.service_settings',
|
setupAction: 'com.android.scanner.service_settings',
|
||||||
setupParams: {
|
setupParams: {
|
||||||
|
barcode_send_mode: 'BROADCAST',
|
||||||
action_barcode_broadcast: 'com.android.server.scannerservice.broadcast',
|
action_barcode_broadcast: 'com.android.server.scannerservice.broadcast',
|
||||||
key_barcode_broadcast: 'scannerdata',
|
key_barcode_broadcast: 'scannerdata',
|
||||||
endchar: 'ENTER'
|
endchar: 'NONE'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'sunmi', // 商米
|
brand: 'sunmi',
|
||||||
name: '商米',
|
name: '商米',
|
||||||
action: 'com.sunmi.scanner.ACTION_DATA_CODE_RECEIVED',
|
action: 'com.sunmi.scanner.ACTION_DATA_CODE_RECEIVED',
|
||||||
dataKey: 'data',
|
dataKey: 'data',
|
||||||
needSetup: false
|
needSetup: false
|
||||||
},
|
},
|
||||||
// {
|
{
|
||||||
// brand: 'honeywell', // 霍尼韦尔
|
brand: 'urovo',
|
||||||
// name: '霍尼韦尔',
|
name: '优博讯',
|
||||||
// action: 'com.honeywell.decode.intent.action.EDIT_DATA',
|
action: 'android.intent.ACTION_DECODE_DATA',
|
||||||
// dataKey: 'data',
|
dataKey: 'barcode_string',
|
||||||
// needSetup: false
|
needSetup: false
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// brand: 'zebra', // 斑马
|
// 新大陆 Newland,广播为 nlscan.action.SCANNER_RESULT
|
||||||
// name: '斑马',
|
brand: 'nlscan',
|
||||||
// action: 'com.symbol.datawedge.api.RESULT_ACTION',
|
name: '新大陆',
|
||||||
// dataKey: 'com.symbol.datawedge.data_string',
|
action: 'nlscan.action.SCANNER_RESULT',
|
||||||
// needSetup: false
|
dataKey: 'SCAN_BARCODE1',
|
||||||
// },
|
needSetup: false
|
||||||
// {
|
},
|
||||||
// brand: 'idata', // 盈达聚力
|
{ ...PHONE_SCAN_CONFIG },
|
||||||
// name: '盈达聚力',
|
|
||||||
// action: 'android.intent.action.SCANRESULT',
|
|
||||||
// dataKey: 'value',
|
|
||||||
// needSetup: false
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// brand: 'urovo', // 优博讯
|
|
||||||
// name: '优博讯',
|
|
||||||
// action: 'android.intent.ACTION_DECODE_DATA',
|
|
||||||
// dataKey: 'barcode_string',
|
|
||||||
// needSetup: false
|
|
||||||
// }
|
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
|
||||||
// 注册所有扫码广播(推荐方式:同时注册所有厂商)
|
getPhoneScanConfig() {
|
||||||
registerScanBroadcast(scanCallback) {
|
return { ...PHONE_SCAN_CONFIG };
|
||||||
|
},
|
||||||
|
|
||||||
|
isPdaDevice() {
|
||||||
// #ifdef APP-PLUS
|
// #ifdef APP-PLUS
|
||||||
const configs = this.getScannerConfigs();
|
|
||||||
|
|
||||||
configs.forEach(config => {
|
|
||||||
try {
|
try {
|
||||||
this.registerSingleBroadcast(config, scanCallback);
|
const Build = plus.android.importClass('android.os.Build');
|
||||||
this.registeredBrands.push(config.brand);
|
const manufacturer = String(Build.MANUFACTURER || '').toLowerCase();
|
||||||
console.log(`${config.name}扫码广播注册成功`);
|
const model = String(Build.MODEL || '').toLowerCase();
|
||||||
} catch (error) {
|
return PDA_DEVICE_KEYWORDS.some((keyword) => {
|
||||||
console.log(`${config.name}扫码广播注册失败:`, error);
|
return manufacturer.includes(keyword) || model.includes(keyword);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log('检测设备类型失败', error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
if (this.registeredBrands.length > 0) {
|
shouldUsePhoneScan() {
|
||||||
console.log('扫码广播注册完成,已注册厂商:', this.registeredBrands.join(', '));
|
const builtinConfigs = this.getScannerConfigs();
|
||||||
|
const activeConfig = getScanConfig(builtinConfigs);
|
||||||
|
if (activeConfig && isPhoneScanConfig(activeConfig)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!activeConfig && !this.isPdaDevice()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.error('所有扫码广播注册均失败');
|
|
||||||
return false;
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
getAllScannerConfigs() {
|
||||||
|
const builtinConfigs = this.getScannerConfigs();
|
||||||
|
if (!this.remoteScannerConfigs.length) {
|
||||||
|
return builtinConfigs;
|
||||||
|
}
|
||||||
|
|
||||||
|
const configMap = new Map();
|
||||||
|
builtinConfigs.forEach((item) => configMap.set(item.brand, item));
|
||||||
|
this.remoteScannerConfigs.forEach((item) => configMap.set(item.brand, item));
|
||||||
|
if (!configMap.has(PHONE_SCAN_CONFIG.brand)) {
|
||||||
|
configMap.set(PHONE_SCAN_CONFIG.brand, { ...PHONE_SCAN_CONFIG });
|
||||||
|
}
|
||||||
|
return Array.from(configMap.values());
|
||||||
|
},
|
||||||
|
|
||||||
|
getActiveScanConfig() {
|
||||||
|
return getScanConfig(this.getScannerConfigs());
|
||||||
|
},
|
||||||
|
|
||||||
|
getDefaultScanConfig() {
|
||||||
|
const configs = this.getAllScannerConfigs().filter((item) => !isPhoneScanConfig(item));
|
||||||
|
return configs.length ? configs[0] : null;
|
||||||
|
},
|
||||||
|
|
||||||
|
openPhoneScan(options = {}) {
|
||||||
|
const callback = options.callback || this._scanCallback;
|
||||||
|
// #ifdef APP-PLUS || MP-WEIXIN
|
||||||
|
uni.scanCode({
|
||||||
|
scanType: options.scanType || ['qrCode', 'barCode'],
|
||||||
|
success: (res) => {
|
||||||
|
this.handleScanResult(res.result, callback);
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error('手机扫码失败:', err);
|
||||||
|
if (options.fail) {
|
||||||
|
options.fail(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uni.showToast({
|
||||||
|
title: '扫码失败',
|
||||||
|
icon: 'none',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef H5
|
||||||
|
uni.showToast({
|
||||||
|
title: 'H5环境不支持扫码功能',
|
||||||
|
icon: 'none',
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
|
||||||
|
triggerScan() {
|
||||||
|
if (this.usePhoneScanFallback) {
|
||||||
|
this.openPhoneScan();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
registerScanBroadcast(scanCallback) {
|
||||||
|
this._scanCallback = scanCallback;
|
||||||
|
|
||||||
|
// #ifndef APP-PLUS
|
||||||
|
this.usePhoneScanFallback = true;
|
||||||
|
return true;
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
if (this.shouldUsePhoneScan()) {
|
||||||
|
this.usePhoneScanFallback = true;
|
||||||
|
console.log('使用手机扫码模式');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.usePhoneScanFallback = false;
|
||||||
|
const activeConfig = this.getActiveScanConfig();
|
||||||
|
|
||||||
|
if (activeConfig && !isPhoneScanConfig(activeConfig)) {
|
||||||
|
return this.registerScanBroadcastByConfig(activeConfig, scanCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasShownNoConfigHint()) {
|
||||||
|
markNoConfigHintShown();
|
||||||
|
uni.showToast({
|
||||||
|
title: '请先在「我的-扫描设置」配置扫码枪',
|
||||||
|
icon: 'none',
|
||||||
|
duration: 2500,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultConfig = this.getDefaultScanConfig();
|
||||||
|
if (!defaultConfig) {
|
||||||
|
console.error('未找到默认可用的扫码枪配置');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.registerScanBroadcastByConfig(defaultConfig, scanCallback);
|
||||||
// #endif
|
// #endif
|
||||||
},
|
},
|
||||||
|
|
||||||
// 注册指定厂商的扫码广播
|
|
||||||
registerScanBroadcastByBrand(brand, scanCallback) {
|
registerScanBroadcastByBrand(brand, scanCallback) {
|
||||||
// #ifdef APP-PLUS
|
// #ifdef APP-PLUS
|
||||||
const configs = this.getScannerConfigs();
|
const configs = this.getAllScannerConfigs();
|
||||||
const config = configs.find(c => c.brand === brand);
|
const config = configs.find(c => c.brand === brand);
|
||||||
|
|
||||||
if (!config) {
|
if (!config) {
|
||||||
@@ -100,23 +215,46 @@ export default {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isPhoneScanConfig(config)) {
|
||||||
|
this._scanCallback = scanCallback;
|
||||||
|
this.usePhoneScanFallback = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.registerScanBroadcastByConfig(config, scanCallback);
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
|
||||||
|
registerScanBroadcastByConfig(config, scanCallback) {
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
const normalizedConfig = normalizeConfig(config, this.getScannerConfigs());
|
||||||
|
if (!normalizedConfig) {
|
||||||
|
console.error('扫码枪配置无效');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPhoneScanConfig(normalizedConfig)) {
|
||||||
|
this._scanCallback = scanCallback;
|
||||||
|
this.usePhoneScanFallback = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.registerSingleBroadcast(config, scanCallback);
|
this.registerSingleBroadcast(normalizedConfig, scanCallback);
|
||||||
this.registeredBrands.push(config.brand);
|
this.registeredBrands.push(normalizedConfig.brand);
|
||||||
console.log(`${config.name}扫码广播注册成功`);
|
this.usePhoneScanFallback = false;
|
||||||
|
console.log(`${normalizedConfig.name}扫码广播注册成功`);
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`${config.name}扫码广播注册失败:`, error);
|
console.error(`${normalizedConfig.name}扫码广播注册失败:`, error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
},
|
},
|
||||||
|
|
||||||
// 单个广播注册的核心方法
|
|
||||||
registerSingleBroadcast(config, scanCallback) {
|
registerSingleBroadcast(config, scanCallback) {
|
||||||
const main = plus.android.runtimeMainActivity();
|
const main = plus.android.runtimeMainActivity();
|
||||||
|
|
||||||
// 如果需要预配置(如东集)
|
|
||||||
if (config.needSetup && config.setupAction) {
|
if (config.needSetup && config.setupAction) {
|
||||||
try {
|
try {
|
||||||
const Intent = plus.android.importClass('android.content.Intent');
|
const Intent = plus.android.importClass('android.content.Intent');
|
||||||
@@ -133,7 +271,6 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注册广播接收器
|
|
||||||
const IntentFilter = plus.android.importClass('android.content.IntentFilter');
|
const IntentFilter = plus.android.importClass('android.content.IntentFilter');
|
||||||
const filter = new IntentFilter();
|
const filter = new IntentFilter();
|
||||||
filter.addAction(config.action);
|
filter.addAction(config.action);
|
||||||
@@ -148,7 +285,8 @@ export default {
|
|||||||
if (!self.isPageActive) return;
|
if (!self.isPageActive) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
plus.android.importClass('android.content.Intent');
|
// 广播回调里的 intent 需要按实例导入,否则 getStringExtra 不可用
|
||||||
|
plus.android.importClass(intent);
|
||||||
const scanResult = intent.getStringExtra(config.dataKey);
|
const scanResult = intent.getStringExtra(config.dataKey);
|
||||||
|
|
||||||
console.log(`${config.name}扫码结果:`, scanResult);
|
console.log(`${config.name}扫码结果:`, scanResult);
|
||||||
@@ -165,17 +303,14 @@ export default {
|
|||||||
|
|
||||||
main.registerReceiver(receiver, filter);
|
main.registerReceiver(receiver, filter);
|
||||||
|
|
||||||
// 保存接收器引用,用于后续注销
|
|
||||||
this.scanReceivers.push({
|
this.scanReceivers.push({
|
||||||
brand: config.brand,
|
brand: config.brand,
|
||||||
receiver: receiver
|
receiver: receiver
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理扫码结果的统一方法
|
|
||||||
handleScanResult(scanResult, scanCallback) {
|
handleScanResult(scanResult, scanCallback) {
|
||||||
try {
|
try {
|
||||||
// 数据清理:去除空格、换行符等
|
|
||||||
let cleanCode = scanResult.replace(/\s+/g, '').replace(/[\r\n]/g, '');
|
let cleanCode = scanResult.replace(/\s+/g, '').replace(/[\r\n]/g, '');
|
||||||
|
|
||||||
console.log("扫码结果:", cleanCode);
|
console.log("扫码结果:", cleanCode);
|
||||||
@@ -188,7 +323,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 取消所有扫码广播监听
|
|
||||||
unregisterScanBroadcast() {
|
unregisterScanBroadcast() {
|
||||||
// #ifdef APP-PLUS
|
// #ifdef APP-PLUS
|
||||||
if (this.scanReceivers.length === 0) return;
|
if (this.scanReceivers.length === 0) return;
|
||||||
@@ -214,7 +348,6 @@ export default {
|
|||||||
// #endif
|
// #endif
|
||||||
},
|
},
|
||||||
|
|
||||||
// 通用的商品扫描处理方法
|
|
||||||
handleGoodsScan(scanCode, successCallback, errorCallback) {
|
handleGoodsScan(scanCode, successCallback, errorCallback) {
|
||||||
const trimmedCode = scanCode ? scanCode.toString().trim() : "";
|
const trimmedCode = scanCode ? scanCode.toString().trim() : "";
|
||||||
|
|
||||||
@@ -224,17 +357,14 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据业务类型处理不同的扫码逻辑
|
|
||||||
if (this.processScanCode) {
|
if (this.processScanCode) {
|
||||||
this.processScanCode(trimmedCode, successCallback, errorCallback);
|
this.processScanCode(trimmedCode, successCallback, errorCallback);
|
||||||
} else {
|
} else {
|
||||||
// 默认处理方式
|
|
||||||
successCallback && successCallback(trimmedCode);
|
successCallback && successCallback(trimmedCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 页面激活状态管理
|
|
||||||
onShow() {
|
onShow() {
|
||||||
this.isPageActive = true;
|
this.isPageActive = true;
|
||||||
console.log('页面显示,设置 isPageActive 为 true');
|
console.log('页面显示,设置 isPageActive 为 true');
|
||||||
|
|||||||
@@ -0,0 +1,498 @@
|
|||||||
|
/**
|
||||||
|
* 坯布出仓单(其他出货单)常量与数据工具
|
||||||
|
*
|
||||||
|
* 仅存放与接口无关的常量 / 状态映射 / 字段规范化 / 单位换算等纯工具,
|
||||||
|
* 真实接口请求统一注册在 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 STATUS_ACTION_VOICE = {
|
||||||
|
approve: '审核成功',
|
||||||
|
void: '作废成功',
|
||||||
|
};
|
||||||
|
|
||||||
|
// 出仓类型:当前后端仅提供「坯布其他出货单」一种类型的接口
|
||||||
|
export const BILL_TYPES = [
|
||||||
|
{ value: 'other', label: '坯布其他出货单' },
|
||||||
|
];
|
||||||
|
|
||||||
|
/** 列表分页拉取每页条数 */
|
||||||
|
export const LIST_PAGE_SIZE = 100;
|
||||||
|
|
||||||
|
/** 往来单位类型:染厂(接收单位下拉筛选) */
|
||||||
|
export const BUSINESS_UNIT_TYPE_DYEING_FACTORY = 12;
|
||||||
|
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 扫码详情区汇总维度(勾选后随扫码请求把对应 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),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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 || '操作失败');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,274 @@
|
|||||||
|
/**
|
||||||
|
* 坯布库存查询:常量、格式化、查询参数组装
|
||||||
|
*/
|
||||||
|
import {
|
||||||
|
formatRoll,
|
||||||
|
formatWeightKg,
|
||||||
|
fetchAllOrderList,
|
||||||
|
LIST_PAGE_SIZE,
|
||||||
|
} from '@/common/storeFabricBusinessOut';
|
||||||
|
|
||||||
|
export { formatRoll, formatWeightKg, fetchAllOrderList, LIST_PAGE_SIZE };
|
||||||
|
|
||||||
|
/** 第一维度:坯布汇总表格列 */
|
||||||
|
export const GROUP_TABLE_COLUMNS = [
|
||||||
|
{ label: '坯布', key: 'fabric_label', width: 300 },
|
||||||
|
{ label: '仓库名称', key: 'warehouse_name', width: 180 },
|
||||||
|
{ label: '库存匹数', key: 'stock_roll_display', width: 130 },
|
||||||
|
{ label: '库存数量', key: 'stock_weight_display', width: 160 },
|
||||||
|
];
|
||||||
|
|
||||||
|
/** 第二维度:排除上期/本期字段后的表格列 */
|
||||||
|
export const STOCK_TABLE_COLUMNS = [
|
||||||
|
{ label: '颜色', key: 'gray_fabric_color_name', width: 120 },
|
||||||
|
{ label: '坯布编号', key: 'grey_fabric_code', width: 140 },
|
||||||
|
{ label: '坯布名称', key: 'grey_fabric_name', width: 160 },
|
||||||
|
{ label: '等级', key: 'grey_fabric_level_name', width: 100 },
|
||||||
|
{ label: '幅宽', key: 'grey_fabric_width_and_unit_name', width: 120 },
|
||||||
|
{ label: '克重', key: 'grey_fabric_gram_weight_and_unit_name', width: 120 },
|
||||||
|
{ label: '成分', key: 'component', width: 120 },
|
||||||
|
{ label: '客户', key: 'customer_name', width: 120 },
|
||||||
|
{ label: '织厂', key: 'supplier_name', width: 140 },
|
||||||
|
{ label: '机台号', key: 'machine_number', width: 100 },
|
||||||
|
{ label: '针寸数', key: 'needle_size', width: 100 },
|
||||||
|
{ label: '纱批', key: 'yarn_batch', width: 120 },
|
||||||
|
{ label: '原料纱名', key: 'raw_material_yarn_name', width: 140 },
|
||||||
|
{ label: '原料批号', key: 'raw_material_batch_num', width: 120 },
|
||||||
|
{ label: '原料品牌', key: 'raw_material_batch_brand', width: 120 },
|
||||||
|
{ label: '仓库', key: 'warehouse_name', width: 140 },
|
||||||
|
{ label: '收货单位', key: 'receiver_name', width: 140 },
|
||||||
|
{ label: '工厂备注', key: 'warehouse_remark', width: 140 },
|
||||||
|
{ label: '染厂用坯单号', key: 'dye_unit_use_order_no', width: 150 },
|
||||||
|
{ label: '生产通知单号', key: 'produce_order_no', width: 150 },
|
||||||
|
{ label: '出坯单号', key: 'source_code', width: 140 },
|
||||||
|
{ label: '出坯日期', key: 'source_time', width: 120 },
|
||||||
|
{ label: '坯布备注', key: 'source_remark', width: 140 },
|
||||||
|
{ label: '预约匹数', key: 'book_roll_display', width: 110 },
|
||||||
|
{ label: '库存匹数', key: 'stock_roll_display', width: 110 },
|
||||||
|
{ label: '库存数量', key: 'stock_weight_display', width: 140 },
|
||||||
|
{ label: '库存成本', key: 'stock_cost_display', width: 110 },
|
||||||
|
{ label: '单价', key: 'single_price_display', width: 100 },
|
||||||
|
{ label: '毛重成本', key: 'buoyant_weight_price_display', width: 110 },
|
||||||
|
];
|
||||||
|
|
||||||
|
/** 细码明细表格列 */
|
||||||
|
export const WAREHOUSE_DETAIL_COLUMNS = [
|
||||||
|
{ label: '序号', key: 'seq', width: 70 },
|
||||||
|
{ label: '卷号', key: 'volume_number', width: 90 },
|
||||||
|
{ label: '匹数', key: 'roll', width: 90 },
|
||||||
|
{ label: '数量(KG)', key: 'weight', width: 110 },
|
||||||
|
{ label: '条码', key: 'bar_code', width: 240 },
|
||||||
|
{ label: '仓位', key: 'position', width: 100 },
|
||||||
|
{ label: '颜色', key: 'gray_fabric_color_name', width: 100 },
|
||||||
|
{ label: '织厂', key: 'supplier_name', width: 120 },
|
||||||
|
{ label: '机台', key: 'machine_number', width: 90 },
|
||||||
|
{ label: '库龄(天)', key: 'days_of_age', width: 90 },
|
||||||
|
];
|
||||||
|
|
||||||
|
export function formatStockWeightWithUnit(weight, unitName) {
|
||||||
|
const val = formatWeightKg(weight);
|
||||||
|
if (val === 0 && (weight === 0 || weight === '0')) return unitName ? `0 ${unitName}` : '0';
|
||||||
|
if (!weight && weight !== 0) return '-';
|
||||||
|
return unitName ? `${val} ${unitName}` : `${val}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatDisplayCell(value) {
|
||||||
|
if (value === null || value === undefined || value === '') return '-';
|
||||||
|
return String(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toQueryString(params = {}) {
|
||||||
|
return Object.keys(params)
|
||||||
|
.filter((key) => {
|
||||||
|
const val = params[key];
|
||||||
|
return val !== '' && val !== null && val !== undefined;
|
||||||
|
})
|
||||||
|
.map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
|
||||||
|
.join('&');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parsePageQuery(options = {}) {
|
||||||
|
const parsed = { ...options };
|
||||||
|
['grey_fabric_id', 'warehouse_id', 'supplier_id', 'gray_fabric_color_id', 'warehouse_sum_id'].forEach((key) => {
|
||||||
|
if (parsed[key] !== undefined && parsed[key] !== '') {
|
||||||
|
const num = Number(parsed[key]);
|
||||||
|
if (!Number.isNaN(num)) parsed[key] = num;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 第一维度接口筛选:仅坯布编号、坯布名称 */
|
||||||
|
export function buildGroupListQuery(filters = {}) {
|
||||||
|
const params = {};
|
||||||
|
if (filters.grey_fabric_code) params.grey_fabric_code = filters.grey_fabric_code;
|
||||||
|
if (filters.grey_fabric_name) params.grey_fabric_name = filters.grey_fabric_name;
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 第二维度接口筛选:坯布 id + 机台号 */
|
||||||
|
export function buildStockListQuery(filters = {}, context = {}) {
|
||||||
|
const params = {};
|
||||||
|
if (context.grey_fabric_id) params.grey_fabric_id = context.grey_fabric_id;
|
||||||
|
if (filters.machine_number) params.machine_number = filters.machine_number;
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildDetailQuery(row = {}, context = {}) {
|
||||||
|
const params = {};
|
||||||
|
const greyFabricId = row.grey_fabric_id || context.grey_fabric_id;
|
||||||
|
if (greyFabricId) params.grey_fabric_id = greyFabricId;
|
||||||
|
if (row.warehouse_id || context.warehouse_id) {
|
||||||
|
params.warehouse_id = row.warehouse_id || context.warehouse_id;
|
||||||
|
}
|
||||||
|
if (row.supplier_id) params.supplier_id = row.supplier_id;
|
||||||
|
if (row.gray_fabric_color_id) params.gray_fabric_color_id = row.gray_fabric_color_id;
|
||||||
|
if (row.machine_number) params.machine_number = row.machine_number;
|
||||||
|
if (row.yarn_batch) params.yarn_batch = row.yarn_batch;
|
||||||
|
if (row.produce_order_no) params.produce_order_no = row.produce_order_no;
|
||||||
|
if (row.source_code) params.source_code = row.source_code;
|
||||||
|
if (row.id) params.warehouse_sum_id = row.id;
|
||||||
|
if (row.warehouse_sum_id) params.warehouse_sum_id = row.warehouse_sum_id;
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildStockListNavigateQuery(item) {
|
||||||
|
return {
|
||||||
|
grey_fabric_id: item.grey_fabric_id,
|
||||||
|
grey_fabric_code: item.grey_fabric_code || '',
|
||||||
|
grey_fabric_name: item.grey_fabric_name || '',
|
||||||
|
warehouse_id: item.warehouse_id || '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildDetailNavigateQuery(row, context = {}) {
|
||||||
|
const detailQuery = buildDetailQuery(row, context);
|
||||||
|
return {
|
||||||
|
...detailQuery,
|
||||||
|
grey_fabric_code: row.grey_fabric_code || context.grey_fabric_code || '',
|
||||||
|
grey_fabric_name: row.grey_fabric_name || context.grey_fabric_name || '',
|
||||||
|
gray_fabric_color_name: row.gray_fabric_color_name || '',
|
||||||
|
supplier_name: row.supplier_name || '',
|
||||||
|
machine_number: row.machine_number || '',
|
||||||
|
yarn_batch: row.yarn_batch || '',
|
||||||
|
warehouse_name: row.warehouse_name || '',
|
||||||
|
stock_roll: row.stock_roll_display || '',
|
||||||
|
stock_weight: row.stock_weight_display || '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapGroupTableRow(row) {
|
||||||
|
const code = row.grey_fabric_code || '';
|
||||||
|
const name = row.grey_fabric_name || '';
|
||||||
|
return {
|
||||||
|
...row,
|
||||||
|
_key: `${row.grey_fabric_id || ''}_${row.warehouse_id || ''}`,
|
||||||
|
fabric_label: code && name ? `${code}#${name}` : (code || name || '-'),
|
||||||
|
warehouse_name: formatDisplayCell(row.warehouse_name || row.receiver_name),
|
||||||
|
stock_roll_display: formatRoll(row.stock_roll),
|
||||||
|
stock_weight_display: formatStockWeightWithUnit(row.stock_weight, row.unit_name),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapStockTableRow(row) {
|
||||||
|
const unitName = row.unit_name || '';
|
||||||
|
return {
|
||||||
|
...row,
|
||||||
|
_key: row.id || `${row.grey_fabric_id}_${row.gray_fabric_color_id}_${row.supplier_id}_${row.machine_number}`,
|
||||||
|
gray_fabric_color_name: formatDisplayCell(row.gray_fabric_color_name),
|
||||||
|
grey_fabric_code: formatDisplayCell(row.grey_fabric_code),
|
||||||
|
grey_fabric_name: formatDisplayCell(row.grey_fabric_name),
|
||||||
|
grey_fabric_level_name: formatDisplayCell(row.grey_fabric_level_name),
|
||||||
|
grey_fabric_width_and_unit_name: formatDisplayCell(row.grey_fabric_width_and_unit_name),
|
||||||
|
grey_fabric_gram_weight_and_unit_name: formatDisplayCell(row.grey_fabric_gram_weight_and_unit_name),
|
||||||
|
component: formatDisplayCell(row.component),
|
||||||
|
customer_name: formatDisplayCell(row.customer_name),
|
||||||
|
supplier_name: formatDisplayCell(row.supplier_name),
|
||||||
|
machine_number: formatDisplayCell(row.machine_number),
|
||||||
|
needle_size: formatDisplayCell(row.needle_size),
|
||||||
|
yarn_batch: formatDisplayCell(row.yarn_batch),
|
||||||
|
raw_material_yarn_name: formatDisplayCell(row.raw_material_yarn_name),
|
||||||
|
raw_material_batch_num: formatDisplayCell(row.raw_material_batch_num),
|
||||||
|
raw_material_batch_brand: formatDisplayCell(row.raw_material_batch_brand),
|
||||||
|
warehouse_name: formatDisplayCell(row.warehouse_name),
|
||||||
|
receiver_name: formatDisplayCell(row.receiver_name),
|
||||||
|
warehouse_remark: formatDisplayCell(row.warehouse_remark),
|
||||||
|
dye_unit_use_order_no: formatDisplayCell(row.dye_unit_use_order_no),
|
||||||
|
produce_order_no: formatDisplayCell(row.produce_order_no),
|
||||||
|
source_code: formatDisplayCell(row.source_code),
|
||||||
|
source_time: formatDisplayCell((row.source_time || '').slice(0, 10)),
|
||||||
|
source_remark: formatDisplayCell(row.source_remark),
|
||||||
|
book_roll_display: row.book_roll != null && row.book_roll !== '' ? formatRoll(row.book_roll) : '-',
|
||||||
|
stock_roll_display: formatRoll(row.stock_roll),
|
||||||
|
stock_weight_display: formatStockWeightWithUnit(row.stock_weight, unitName),
|
||||||
|
stock_cost_display: row.stock_cost != null && row.stock_cost !== '' ? formatWeightKg(row.stock_cost) : '-',
|
||||||
|
single_price_display: row.single_price != null && row.single_price !== '' ? formatWeightKg(row.single_price) : '-',
|
||||||
|
buoyant_weight_price_display: row.buoyant_weight_price != null && row.buoyant_weight_price !== ''
|
||||||
|
? formatWeightKg(row.buoyant_weight_price) : '-',
|
||||||
|
creator_name: formatDisplayCell(row.creator_name),
|
||||||
|
create_time: formatDisplayCell(row.create_time),
|
||||||
|
update_user_name: formatDisplayCell(row.update_user_name),
|
||||||
|
update_time: formatDisplayCell(row.update_time),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sumStockTotals(list = []) {
|
||||||
|
let roll = 0;
|
||||||
|
let weight = 0;
|
||||||
|
(list || []).forEach((item) => {
|
||||||
|
roll += Number(item.stock_roll || 0);
|
||||||
|
weight += Number(item.stock_weight || 0);
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
roll: formatRoll(roll),
|
||||||
|
weight: formatWeightKg(weight),
|
||||||
|
count: list.length,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sumDetailTotals(list = []) {
|
||||||
|
let roll = 0;
|
||||||
|
let weight = 0;
|
||||||
|
(list || []).forEach((item) => {
|
||||||
|
roll += Number(item.num || 0);
|
||||||
|
weight += Number(item.weight || 0);
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
roll: formatRoll(roll),
|
||||||
|
weight: formatWeightKg(weight),
|
||||||
|
count: list.length,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapWarehouseDetailRows(list = []) {
|
||||||
|
return (list || []).map((item, index) => ({
|
||||||
|
seq: index + 1,
|
||||||
|
volume_number: item.volume_number || '-',
|
||||||
|
roll: item.num != null && item.num !== '' ? formatRoll(item.num) : '-',
|
||||||
|
weight: item.weight != null && item.weight !== '' ? formatWeightKg(item.weight) : '-',
|
||||||
|
bar_code: item.bar_code || item.fabric_piece_code || '-',
|
||||||
|
position: item.warehouse_bin_Name || '-',
|
||||||
|
gray_fabric_color_name: item.gray_fabric_color_name || '-',
|
||||||
|
supplier_name: item.supplier_name || '-',
|
||||||
|
machine_number: item.machine_number || '-',
|
||||||
|
days_of_age: item.days_of_age != null && item.days_of_age !== '' ? item.days_of_age : '-',
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getWarehouseDetailTableWidth(columns = WAREHOUSE_DETAIL_COLUMNS) {
|
||||||
|
const total = columns.reduce((sum, col) => sum + (col.width || 120), 0);
|
||||||
|
return `${total}rpx`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fetchAllWarehouseList(listFn, params = {}, pageSize = LIST_PAGE_SIZE) {
|
||||||
|
return fetchAllOrderList(listFn, params, pageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function calcTableHeight(rowCount, options = {}) {
|
||||||
|
const headerPx = options.headerPx || 44;
|
||||||
|
const rowPx = options.rowPx || 44;
|
||||||
|
const minPx = options.minPx || 200;
|
||||||
|
const maxPx = options.maxPx || 520;
|
||||||
|
const total = headerPx + rowCount * rowPx;
|
||||||
|
return `${Math.min(Math.max(total, minPx), maxPx)}px`;
|
||||||
|
}
|
||||||
@@ -23,6 +23,9 @@ export function request(options) {
|
|||||||
url: apiurl + options.url,
|
url: apiurl + options.url,
|
||||||
method: options.method || 'GET',
|
method: options.method || 'GET',
|
||||||
data: options.data,
|
data: options.data,
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
sslVerify: false,
|
||||||
|
// #endif
|
||||||
header: {
|
header: {
|
||||||
'Platform': 2,
|
'Platform': 2,
|
||||||
'Authorization': token,
|
'Authorization': token,
|
||||||
@@ -363,6 +366,58 @@ function playErrorAudio() {
|
|||||||
errorAudio.play();
|
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',
|
||||||
|
'扫码成功': '/static/audio/scan_ok.wav',
|
||||||
|
'进仓成功': '/static/audio/in_ok.wav',
|
||||||
|
};
|
||||||
|
|
||||||
|
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 {
|
export default {
|
||||||
get apiurl() {
|
get apiurl() {
|
||||||
@@ -375,4 +430,5 @@ export default {
|
|||||||
parGetData,
|
parGetData,
|
||||||
playSuccessAudio,
|
playSuccessAudio,
|
||||||
playErrorAudio,
|
playErrorAudio,
|
||||||
|
playSpeak,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
<template>
|
||||||
|
<view class="myCard">
|
||||||
|
<view class="cardTopName">
|
||||||
|
<text>{{ item.order_no }}</text>
|
||||||
|
<text class="statusTag" :class="'status-' + item.audit_status">{{ item.audit_status_name }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="cardRow">
|
||||||
|
<view>出仓日期:</view>
|
||||||
|
<view>{{ formatTime(item.out_date) }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="cardRow">
|
||||||
|
<view>出仓类型:</view>
|
||||||
|
<view>{{ item.bill_type_name }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="cardRow">
|
||||||
|
<view>接收单位:</view>
|
||||||
|
<view>{{ item.business_unit_name || '-' }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="cardRow">
|
||||||
|
<view>创 建 人:</view>
|
||||||
|
<view>{{ item.create_user_name }} {{ formatTime(item.create_time, 'YYYY-MM-DD') }}</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="item.auditor_name" class="cardRow">
|
||||||
|
<view>审 核 人:</view>
|
||||||
|
<view>{{ item.auditor_name }} {{ formatTime(item.audit_date, 'YYYY-MM-DD') }}</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="!isDetail && !isSelect" class="lookDetail">
|
||||||
|
<text>查看详情</text>
|
||||||
|
<u-icon name="arrow-right" size="36" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { formatDisplayTime } from '@/common/storeFabricBusinessOut';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
item: { type: Object, default: () => ({}) },
|
||||||
|
index: { type: Number, default: 0 },
|
||||||
|
isSelect: { type: Boolean, default: false },
|
||||||
|
isDetail: { type: Boolean, default: false },
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
formatTime: formatDisplayTime,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.cardTopName {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.statusTag {
|
||||||
|
font-size: 24rpx;
|
||||||
|
padding: 4rpx 12rpx;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
.status-0 { background: #f0f0f0; color: #666; }
|
||||||
|
.status-1 { background: #fff7e6; color: #fa8c16; }
|
||||||
|
.status-2 { background: #f6ffed; color: #52c41a; }
|
||||||
|
.status-3 { background: #fff1f0; color: #f5222d; }
|
||||||
|
.status-4 { background: #f5f5f5; color: #999; }
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
<template>
|
||||||
|
<view class="myCard">
|
||||||
|
<view class="cardTopName">
|
||||||
|
<text>{{ item.grey_fabric_code || '-' }}</text>
|
||||||
|
<text class="stockTag">{{ item.stock_roll_display }} 匹</text>
|
||||||
|
</view>
|
||||||
|
<view class="cardRow">
|
||||||
|
<view>坯布名称:</view>
|
||||||
|
<view>{{ item.grey_fabric_name || '-' }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="cardRow">
|
||||||
|
<view>仓 库:</view>
|
||||||
|
<view>{{ item.warehouse_name || item.receiver_name || '-' }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="cardRow">
|
||||||
|
<view>库存数量:</view>
|
||||||
|
<view>{{ item.stock_weight_display }} KG{{ item.unit_label }}</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="!isDetail" class="lookDetail">
|
||||||
|
<text>查看维度汇总</text>
|
||||||
|
<u-icon name="arrow-right" size="36" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
item: { type: Object, default: () => ({}) },
|
||||||
|
index: { type: Number, default: 0 },
|
||||||
|
isDetail: { type: Boolean, default: false },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.cardTopName {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.stockTag {
|
||||||
|
font-size: 24rpx;
|
||||||
|
padding: 4rpx 12rpx;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
font-weight: normal;
|
||||||
|
background: #e6f7ff;
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
<template>
|
||||||
|
<view class="myCard">
|
||||||
|
<view class="cardTopName">
|
||||||
|
<text>{{ item.gray_fabric_color_name || '未分色' }}</text>
|
||||||
|
<text class="stockTag">{{ item.stock_roll_display }} 匹</text>
|
||||||
|
</view>
|
||||||
|
<view class="cardRow">
|
||||||
|
<view>织 厂:</view>
|
||||||
|
<view>{{ item.supplier_name || '-' }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="cardRow">
|
||||||
|
<view>机 台 号:</view>
|
||||||
|
<view>{{ item.machine_number || '-' }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="cardRow">
|
||||||
|
<view>纱 批:</view>
|
||||||
|
<view>{{ item.yarn_batch || '-' }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="cardRow">
|
||||||
|
<view>仓 库:</view>
|
||||||
|
<view>{{ item.warehouse_name || '-' }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="cardRow">
|
||||||
|
<view>幅宽/克重:</view>
|
||||||
|
<view>{{ item.grey_fabric_width_and_unit_name || '-' }} / {{ item.grey_fabric_gram_weight_and_unit_name || '-' }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="cardRow">
|
||||||
|
<view>库存数量:</view>
|
||||||
|
<view>{{ item.stock_weight_display }} KG{{ item.unit_label }}</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="!isDetail" class="lookDetail">
|
||||||
|
<text>查看细码明细</text>
|
||||||
|
<u-icon name="arrow-right" size="36" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
item: { type: Object, default: () => ({}) },
|
||||||
|
index: { type: Number, default: 0 },
|
||||||
|
isDetail: { type: Boolean, default: false },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.cardTopName {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.stockTag {
|
||||||
|
font-size: 24rpx;
|
||||||
|
padding: 4rpx 12rpx;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
font-weight: normal;
|
||||||
|
background: #e6f7ff;
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
<template>
|
||||||
|
<u-popup v-model="visible" mode="center" width="680rpx" border-radius="14" :closeable="true">
|
||||||
|
<view class="popupWrap">
|
||||||
|
<view class="popupTitle">坯布资料</view>
|
||||||
|
<scroll-view scroll-y class="scrollBody">
|
||||||
|
<view class="infoRow" v-for="field in fields" :key="field.key">
|
||||||
|
<text class="label">{{ field.label }}</text>
|
||||||
|
<text class="value">{{ data[field.key] || '-' }}</text>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</u-popup>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { FABRIC_INFO_FIELDS } from '@/common/storeFabricBusinessOut';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
show: { type: Boolean, default: false },
|
||||||
|
data: { type: Object, default: () => ({}) },
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
visible: {
|
||||||
|
get() { return this.show; },
|
||||||
|
set(val) { this.$emit('update:show', val); },
|
||||||
|
},
|
||||||
|
fields() {
|
||||||
|
return FABRIC_INFO_FIELDS;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.popupWrap {
|
||||||
|
padding: 30rpx 30rpx 24rpx;
|
||||||
|
max-height: 80vh;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.popupTitle {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
color: #333;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.scrollBody {
|
||||||
|
flex: 1;
|
||||||
|
height: 62vh;
|
||||||
|
max-height: 62vh;
|
||||||
|
}
|
||||||
|
.infoRow {
|
||||||
|
display: flex;
|
||||||
|
padding: 16rpx 0;
|
||||||
|
border-bottom: 1rpx solid #f0f0f0;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
.label {
|
||||||
|
width: 180rpx;
|
||||||
|
color: #888;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.value {
|
||||||
|
flex: 1;
|
||||||
|
color: #333;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<view v-if="title" class="fabric-out-sectionTitle">{{ title }}</view>
|
||||||
|
<slot name="before-list" />
|
||||||
|
<view class="fabric-out-detailList">
|
||||||
|
<view
|
||||||
|
v-for="row in list"
|
||||||
|
:key="row.group_key || row.id"
|
||||||
|
class="fabric-out-detailCard"
|
||||||
|
>
|
||||||
|
<view class="fabric-out-detailRow" @click="$emit('fabric-info', row)">
|
||||||
|
<text>{{ row.grey_fabric_code }}#{{ row.grey_fabric_name }}</text>
|
||||||
|
<u-icon name="arrow-right" size="32" color="#888" />
|
||||||
|
</view>
|
||||||
|
<view class="fabric-out-detailMeta">
|
||||||
|
<text>匹数:{{ row.roll }}</text>
|
||||||
|
<text>重量:{{ row.weight }}KG</text>
|
||||||
|
<u-button type="primary" size="mini" @click="$emit('fine-code', row)">细码</u-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
list: { type: Array, default: () => [] },
|
||||||
|
title: { type: String, default: '' },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import '@/pages/storefabric/storeFabricBusinessOutPage.scss';
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<template>
|
||||||
|
<view v-if="buttons.length" class="fabric-out-submitView">
|
||||||
|
<view v-for="btn in buttons" :key="btn.action" class="fabric-out-actionBtnWrap">
|
||||||
|
<u-button type="primary" :class="singleBtnClass" @click="$emit('action', btn.action)">
|
||||||
|
{{ btn.label }}
|
||||||
|
</u-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
buttons: { type: Array, default: () => [] },
|
||||||
|
single: { type: Boolean, default: false },
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
singleBtnClass() {
|
||||||
|
return this.single ? 'fabric-out-actionBtn' : '';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import '@/pages/storefabric/storeFabricBusinessOutPage.scss';
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<view v-if="canScan" class="flex-white-plr26 ptb20 bdb_f5 fabric-out-scanRow">
|
||||||
|
<text class="mr26">条码资料</text>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
:value="value"
|
||||||
|
class="fabric-out-scanInput"
|
||||||
|
placeholder="扫描条码"
|
||||||
|
@input="$emit('input', $event.detail.value)"
|
||||||
|
@confirm="$emit('scan')"
|
||||||
|
/>
|
||||||
|
<u-icon
|
||||||
|
v-if="showPhoneScan"
|
||||||
|
class="fabric-out-phoneScanIcon"
|
||||||
|
name="scan"
|
||||||
|
size="80"
|
||||||
|
color="#2979ff"
|
||||||
|
@click="$emit('phone-scan')"
|
||||||
|
/>
|
||||||
|
<checkbox-group @change="$emit('delete-mode-change', $event)">
|
||||||
|
<label class="fabric-out-delCheck">
|
||||||
|
<checkbox :checked="deleteMode" />删除
|
||||||
|
</label>
|
||||||
|
</checkbox-group>
|
||||||
|
</view>
|
||||||
|
<view v-else class="fabric-out-scanTip">{{ disabledTip }}</view>
|
||||||
|
<view v-if="message" class="fabric-out-msgTip">{{ message }}</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
canScan: { type: Boolean, default: false },
|
||||||
|
value: { type: String, default: '' },
|
||||||
|
deleteMode: { type: Boolean, default: false },
|
||||||
|
message: { type: String, default: '' },
|
||||||
|
disabledTip: { type: String, default: '当前状态不可扫码' },
|
||||||
|
showPhoneScan: { type: Boolean, default: false },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import '@/pages/storefabric/storeFabricBusinessOutPage.scss';
|
||||||
|
|
||||||
|
.fabric-out-phoneScanIcon {
|
||||||
|
margin-left: 8rpx;
|
||||||
|
padding: 10rpx 16rpx;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
<template>
|
||||||
|
<view class="fabric-out-scanDetail">
|
||||||
|
<view class="fabric-out-scanDetailRow fabric-out-scanDetailRow--2col">
|
||||||
|
<text class="fabric-out-scanDetailCell">已扫条数:{{ formatCount(detail.scanned_roll) }}条</text>
|
||||||
|
<text class="fabric-out-scanDetailCell">机台库存:{{ formatRoll(detail.machine_stock) }}条</text>
|
||||||
|
</view>
|
||||||
|
<view class="fabric-out-scanDetailRow fabric-out-scanDetailRow--2col">
|
||||||
|
<text class="fabric-out-scanDetailCell">合计条数:{{ formatRoll(detail.total_roll) }}条</text>
|
||||||
|
<text class="fabric-out-scanDetailCell">合计重量:{{ formatWeight(detail.total_weight) }}KG</text>
|
||||||
|
</view>
|
||||||
|
<view class="fabric-out-scanDetailRow">
|
||||||
|
<text class="fabric-out-scanDetailLabel">客户:</text>
|
||||||
|
<text class="fabric-out-scanDetailValue">{{ detail.customer_name || '' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="fabric-out-scanDetailRow">
|
||||||
|
<view class="fabric-out-scanDetailCheck" @click="toggleGroup('produce_order_no')">
|
||||||
|
<checkbox :checked="isGroupChecked('produce_order_no')" />
|
||||||
|
<text class="fabric-out-scanDetailLabel">生产通知单:</text>
|
||||||
|
<text class="fabric-out-scanDetailValue">{{ detail.produce_order_no || '' }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="fabric-out-scanDetailRow">
|
||||||
|
<view class="fabric-out-scanDetailCheck" @click="toggleGroup('grey_fabric_code')">
|
||||||
|
<checkbox :checked="isGroupChecked('grey_fabric_code')" />
|
||||||
|
<text class="fabric-out-scanDetailLabel">布编:</text>
|
||||||
|
<text class="fabric-out-scanDetailValue">{{ detail.grey_fabric_code || '' }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="fabric-out-scanDetailRow">
|
||||||
|
<text class="fabric-out-scanDetailLabel">布名:</text>
|
||||||
|
<text class="fabric-out-scanDetailValue">{{ detail.grey_fabric_name || '' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="fabric-out-scanDetailRow">
|
||||||
|
<view class="fabric-out-scanDetailCheck" @click="toggleGroup('yarn_batch')">
|
||||||
|
<checkbox :checked="isGroupChecked('yarn_batch')" />
|
||||||
|
<text class="fabric-out-scanDetailLabel">纱批:</text>
|
||||||
|
<text class="fabric-out-scanDetailValue">{{ detail.yarn_batch || '' }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="fabric-out-scanDetailRow fabric-out-scanDetailRow--2col">
|
||||||
|
<view class="fabric-out-scanDetailCheck" @click="toggleGroup('machine_number')">
|
||||||
|
<checkbox :checked="isGroupChecked('machine_number')" />
|
||||||
|
<text class="fabric-out-scanDetailLabel">机号:</text>
|
||||||
|
<text class="fabric-out-scanDetailValue">{{ detail.machine_number || '' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="fabric-out-scanDetailCheck" @click="toggleGroup('volume_number')">
|
||||||
|
<checkbox :checked="isGroupChecked('volume_number')" />
|
||||||
|
<text class="fabric-out-scanDetailLabel">布号:</text>
|
||||||
|
<text class="fabric-out-scanDetailValue">{{ detail.volume_number || '' }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="fabric-out-scanDetailRow fabric-out-scanDetailRow--2col">
|
||||||
|
<view class="fabric-out-scanDetailCheck" @click="toggleGroup('grey_fabric_level_name')">
|
||||||
|
<checkbox :checked="isGroupChecked('grey_fabric_level_name')" />
|
||||||
|
<text class="fabric-out-scanDetailLabel">等级:</text>
|
||||||
|
<text class="fabric-out-scanDetailValue">{{ detail.grey_fabric_level_name || '' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="fabric-out-scanDetailCell">
|
||||||
|
<text class="fabric-out-scanDetailLabel">重量:</text>
|
||||||
|
<text class="fabric-out-scanDetailValue">{{ formatWeight(detail.weight) }}Kg</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
detail: { type: Object, default: () => ({}) },
|
||||||
|
groupKeys: { type: Array, default: () => [] },
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
isGroupChecked(key) {
|
||||||
|
return (this.groupKeys || []).includes(key);
|
||||||
|
},
|
||||||
|
toggleGroup(key) {
|
||||||
|
const next = [...(this.groupKeys || [])];
|
||||||
|
const index = next.indexOf(key);
|
||||||
|
if (index >= 0) next.splice(index, 1);
|
||||||
|
else next.push(key);
|
||||||
|
this.$emit('group-change', next);
|
||||||
|
},
|
||||||
|
formatRoll(value) {
|
||||||
|
const n = Number(value || 0);
|
||||||
|
return Number.isInteger(n) ? n : Number(n.toFixed(2));
|
||||||
|
},
|
||||||
|
formatCount(value) {
|
||||||
|
return Number(value || 0);
|
||||||
|
},
|
||||||
|
formatWeight(value) {
|
||||||
|
const n = Number(value || 0);
|
||||||
|
return Number(n.toFixed(2));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import '@/pages/storefabric/storeFabricBusinessOutPage.scss';
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
<template>
|
||||||
|
<u-popup v-model="visible" mode="center" width="94%" border-radius="14" :closeable="true">
|
||||||
|
<view class="popupWrap">
|
||||||
|
<view class="popupTitle">细码</view>
|
||||||
|
<view v-if="!list.length" class="emptyTip">暂无细码数据</view>
|
||||||
|
<scroll-view v-else scroll-x class="tableScroll">
|
||||||
|
<view class="fineTable" :style="{ width: tableWidth }">
|
||||||
|
<view class="tableRow tableHead">
|
||||||
|
<view
|
||||||
|
v-for="col in columns"
|
||||||
|
:key="col.key"
|
||||||
|
class="tableCell headCell"
|
||||||
|
:style="cellStyle(col)"
|
||||||
|
>{{ col.label }}</view>
|
||||||
|
</view>
|
||||||
|
<view v-for="(row, rowIndex) in tableRows" :key="rowIndex" class="tableRow">
|
||||||
|
<view
|
||||||
|
v-for="col in columns"
|
||||||
|
:key="col.key"
|
||||||
|
class="tableCell"
|
||||||
|
:class="{ actionCell: col.key === 'action' && !readonly }"
|
||||||
|
:style="cellStyle(col)"
|
||||||
|
@click="onCellTap(col.key, rowIndex)"
|
||||||
|
>{{ row[col.key] }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
<view v-if="!readonly && list.length" class="tableTip">点击「操作」列删除,将调用扫码删除接口</view>
|
||||||
|
</view>
|
||||||
|
</u-popup>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
getFineCodeTableColumns,
|
||||||
|
getFineCodeTableWidth,
|
||||||
|
mapFineCodeTableRows,
|
||||||
|
} from '@/common/storeFabricBusinessOut';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
show: { type: Boolean, default: false },
|
||||||
|
list: { type: Array, default: () => [] },
|
||||||
|
readonly: { type: Boolean, default: false },
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
visible: {
|
||||||
|
get() { return this.show; },
|
||||||
|
set(val) { this.$emit('update:show', val); },
|
||||||
|
},
|
||||||
|
columns() {
|
||||||
|
return getFineCodeTableColumns(this.readonly);
|
||||||
|
},
|
||||||
|
tableRows() {
|
||||||
|
return mapFineCodeTableRows(this.list, this.readonly);
|
||||||
|
},
|
||||||
|
tableWidth() {
|
||||||
|
return getFineCodeTableWidth(this.columns);
|
||||||
|
},
|
||||||
|
tableScrollHeight() {
|
||||||
|
const rowHeight = 56;
|
||||||
|
const headerHeight = 56;
|
||||||
|
const total = headerHeight + this.list.length * rowHeight;
|
||||||
|
return `${Math.min(Math.max(total, 112), 480)}rpx`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
cellStyle(col) {
|
||||||
|
return {
|
||||||
|
width: `${col.width}rpx`,
|
||||||
|
minWidth: `${col.width}rpx`,
|
||||||
|
maxWidth: `${col.width}rpx`,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onCellTap(key, rowIndex) {
|
||||||
|
if (this.readonly || key !== 'action') return;
|
||||||
|
const item = this.list[rowIndex];
|
||||||
|
if (item) this.$emit('delete', item);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.popupWrap {
|
||||||
|
padding: 24rpx 16rpx 30rpx;
|
||||||
|
max-height: 80vh;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.popupTitle {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
color: #333;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.emptyTip {
|
||||||
|
text-align: center;
|
||||||
|
color: #999;
|
||||||
|
padding: 40rpx 0;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
.tableScroll {
|
||||||
|
width: 100%;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.fineTable {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
border: 1rpx solid #e1e1e1;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.tableRow {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
border-bottom: 1rpx solid #e1e1e1;
|
||||||
|
}
|
||||||
|
.tableRow:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
.tableHead {
|
||||||
|
background: #f1f1f1;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
.tableCell {
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding: 12rpx 8rpx;
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #333;
|
||||||
|
text-align: center;
|
||||||
|
border-right: 1rpx solid #e1e1e1;
|
||||||
|
box-sizing: border-box;
|
||||||
|
word-break: break-all;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
.tableCell:last-child {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
.headCell {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #3e3e3e;
|
||||||
|
}
|
||||||
|
.actionCell {
|
||||||
|
color: #f5222d;
|
||||||
|
}
|
||||||
|
.tableTip {
|
||||||
|
margin-top: 16rpx;
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #999;
|
||||||
|
text-align: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<template>
|
||||||
|
<view class="statusRow">
|
||||||
|
<text class="statusLabel">订单状态</text>
|
||||||
|
<text class="statusTag" :class="'status-' + status">{{ displayName }}</text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { AUDIT_STATUS_MAP, DRAFT_AUDIT_STATUS, DRAFT_AUDIT_STATUS_NAME } from '@/common/storeFabricBusinessOut';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
status: { type: [Number, String], default: 0 },
|
||||||
|
name: { type: String, default: '' },
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
displayName() {
|
||||||
|
if (Number(this.status) === DRAFT_AUDIT_STATUS) return DRAFT_AUDIT_STATUS_NAME;
|
||||||
|
return this.name || AUDIT_STATUS_MAP[Number(this.status)] || '-';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.statusRow {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 20rpx 26rpx;
|
||||||
|
background: #fff;
|
||||||
|
border-bottom: 1rpx solid #f5f5f5;
|
||||||
|
}
|
||||||
|
.statusLabel {
|
||||||
|
font-size: 40rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.statusTag {
|
||||||
|
font-size: 34rpx;
|
||||||
|
padding: 4rpx 12rpx;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
.status-0 { background: #f0f0f0; color: #666; }
|
||||||
|
.status-1 { background: #fff7e6; color: #fa8c16; }
|
||||||
|
.status-2 { background: #f6ffed; color: #52c41a; }
|
||||||
|
.status-3 { background: #fff1f0; color: #f5222d; }
|
||||||
|
.status-4 { background: #f5f5f5; color: #999; }
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
<template>
|
||||||
|
<u-popup v-model="visible" mode="bottom" :safe-area-inset-bottom="true" border-radius="16">
|
||||||
|
<view class="search-select" :style="{ maxHeight: panelMaxHeight + 'px' }">
|
||||||
|
<view class="search-select__bar">
|
||||||
|
<text class="search-select__title">{{ title }}</text>
|
||||||
|
<text class="search-select__cancel" @click="visible = false">取消</text>
|
||||||
|
</view>
|
||||||
|
<view class="search-select__search">
|
||||||
|
<u-search v-model="keyword" :placeholder="placeholder" :show-action="false" />
|
||||||
|
</view>
|
||||||
|
<scroll-view
|
||||||
|
scroll-y
|
||||||
|
class="search-select__list"
|
||||||
|
:style="{ height: listHeight + 'px' }"
|
||||||
|
:enable-back-to-top="false"
|
||||||
|
>
|
||||||
|
<view v-if="!filteredList.length" class="search-select__empty">暂无匹配数据</view>
|
||||||
|
<view
|
||||||
|
v-for="item in filteredList"
|
||||||
|
:key="String(item.value)"
|
||||||
|
class="search-select__item"
|
||||||
|
@click="confirm(item)"
|
||||||
|
>{{ item.label }}</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</u-popup>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
show: { type: Boolean, default: false },
|
||||||
|
title: { type: String, default: '请选择' },
|
||||||
|
placeholder: { type: String, default: '请输入名称搜索' },
|
||||||
|
list: { type: Array, default: () => [] },
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
keyword: '',
|
||||||
|
panelMaxHeight: 520,
|
||||||
|
listHeight: 360,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
visible: {
|
||||||
|
get() { return this.show; },
|
||||||
|
set(val) { this.$emit('update:show', val); },
|
||||||
|
},
|
||||||
|
filteredList() {
|
||||||
|
const keyword = (this.keyword || '').trim().toLowerCase();
|
||||||
|
if (!keyword) return this.list;
|
||||||
|
return this.list.filter((item) => String(item.label || '').toLowerCase().includes(keyword));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
show(val) {
|
||||||
|
if (val) {
|
||||||
|
this.keyword = '';
|
||||||
|
this.calcHeight();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.calcHeight();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
calcHeight() {
|
||||||
|
try {
|
||||||
|
const sys = uni.getSystemInfoSync();
|
||||||
|
const winH = sys.windowHeight || 600;
|
||||||
|
// 弹层约占屏高 65%,列表为弹层去掉标题+搜索后的剩余高度
|
||||||
|
this.panelMaxHeight = Math.floor(winH * 0.65);
|
||||||
|
this.listHeight = Math.max(220, this.panelMaxHeight - 140);
|
||||||
|
} catch (e) {
|
||||||
|
this.panelMaxHeight = 520;
|
||||||
|
this.listHeight = 360;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
confirm(item) {
|
||||||
|
this.visible = false;
|
||||||
|
this.$emit('confirm', item);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import '@/common/pda-typography.scss';
|
||||||
|
|
||||||
|
.search-select {
|
||||||
|
background: #fff;
|
||||||
|
padding-bottom: 20rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.search-select__bar {
|
||||||
|
flex-shrink: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 24rpx 30rpx 12rpx;
|
||||||
|
}
|
||||||
|
.search-select__title {
|
||||||
|
font-size: $pda-font-popup-title;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #202328;
|
||||||
|
}
|
||||||
|
.search-select__cancel {
|
||||||
|
font-size: $pda-font-popup-sub;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
.search-select__search {
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding: 0 24rpx 12rpx;
|
||||||
|
}
|
||||||
|
.search-select__list {
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.search-select__empty {
|
||||||
|
padding: 80rpx 0;
|
||||||
|
text-align: center;
|
||||||
|
color: #999;
|
||||||
|
font-size: $pda-font-popup-sub;
|
||||||
|
}
|
||||||
|
.search-select__item {
|
||||||
|
padding: 32rpx 30rpx;
|
||||||
|
font-size: $pda-font-popup-item;
|
||||||
|
color: #202328;
|
||||||
|
border-bottom: 1px solid #f2f2f2;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
<template>
|
||||||
|
<view class="warehouse-table-wrap" :class="{ 'is-auto-height': isAutoHeight }">
|
||||||
|
<scroll-view scroll-x class="tableScrollX">
|
||||||
|
<wyb-table
|
||||||
|
ref="table"
|
||||||
|
:headers="headers"
|
||||||
|
:contents="contents"
|
||||||
|
:width="tableWidth"
|
||||||
|
:height="height"
|
||||||
|
:first-line-fixed="firstLineFixed"
|
||||||
|
@onCellClick="onCellClick"
|
||||||
|
/>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import wybTable from '@/components/wyb-table/wyb-table.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { wybTable },
|
||||||
|
props: {
|
||||||
|
headers: { type: Array, default: () => [] },
|
||||||
|
contents: { type: Array, default: () => [] },
|
||||||
|
// auto:高度随内容撑开,纵向滚动交给外层 scroll-view,避免与下拉刷新抢手势
|
||||||
|
height: { type: String, default: 'auto' },
|
||||||
|
firstLineFixed: { type: Boolean, default: true },
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isAutoHeight() {
|
||||||
|
return !this.height || this.height === 'auto';
|
||||||
|
},
|
||||||
|
tableWidth() {
|
||||||
|
const total = (this.headers || []).reduce((sum, col) => sum + (col.width || 160), 0);
|
||||||
|
return `${total}rpx`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onCellClick(event) {
|
||||||
|
if (event && event.lineData) {
|
||||||
|
this.$emit('row-click', event.lineData, event);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.warehouse-table-wrap {
|
||||||
|
width: 100%;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.tableScrollX {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
/* 取消表格内部纵向滚动,只保留横向;纵向由页面 scroll-view 处理 */
|
||||||
|
.is-auto-height ::v-deep .wyb-table-scroll-view {
|
||||||
|
height: auto !important;
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: visible;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
+19
@@ -17,6 +17,25 @@ import VueI18n from '@/common/vue-i18n.min.js';
|
|||||||
import lang_zh_CN from '@/common/locales/zh_CN.js';
|
import lang_zh_CN from '@/common/locales/zh_CN.js';
|
||||||
import lang_en from '@/common/locales/en.js';
|
import lang_en from '@/common/locales/en.js';
|
||||||
|
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
// Android 5.x 等老 PDA 不信任 Let's Encrypt 新证书链,全局关闭 HTTPS 证书校验
|
||||||
|
(() => {
|
||||||
|
const patchSslVerify = (methodName) => {
|
||||||
|
const original = uni[methodName];
|
||||||
|
if (typeof original !== 'function') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uni[methodName] = (options = {}) => original({
|
||||||
|
...options,
|
||||||
|
sslVerify: false
|
||||||
|
});
|
||||||
|
};
|
||||||
|
patchSslVerify('request');
|
||||||
|
patchSslVerify('downloadFile');
|
||||||
|
patchSslVerify('uploadFile');
|
||||||
|
})();
|
||||||
|
// #endif
|
||||||
|
|
||||||
Vue.config.productionTip = false;
|
Vue.config.productionTip = false;
|
||||||
|
|
||||||
App.mpType = 'app';
|
App.mpType = 'app';
|
||||||
|
|||||||
+5
-4
@@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"name" : "浩拓技术",
|
"name" : "浩拓织厂",
|
||||||
"appid" : "__UNI__F79F300",
|
"appid" : "__UNI__F79F300",
|
||||||
"description" : "浩拓纺织平台",
|
"description" : "周尚-浩拓织厂",
|
||||||
"versionName" : "1.1.4",
|
"versionName" : "1.1.10",
|
||||||
"versionCode" : 104,
|
"versionCode" : 110,
|
||||||
"transformPx" : false,
|
"transformPx" : false,
|
||||||
"app-plus" : {
|
"app-plus" : {
|
||||||
"optimization" : {
|
"optimization" : {
|
||||||
@@ -31,6 +31,7 @@
|
|||||||
},
|
},
|
||||||
"distribute" : {
|
"distribute" : {
|
||||||
"android" : {
|
"android" : {
|
||||||
|
"packagename" : "uni.UNIF79F300",
|
||||||
"permissions" : [
|
"permissions" : [
|
||||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||||
|
|||||||
+63
-18
@@ -148,6 +148,13 @@
|
|||||||
"navigationBarTitleText": "清除缓存"
|
"navigationBarTitleText": "清除缓存"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/sys/user/scan-settings",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "扫描设置",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/sys/workbench/index",
|
"path": "pages/sys/workbench/index",
|
||||||
"style": {
|
"style": {
|
||||||
@@ -563,6 +570,62 @@
|
|||||||
"enablePullDownRefresh": false
|
"enablePullDownRefresh": false
|
||||||
}
|
}
|
||||||
},{
|
},{
|
||||||
|
"path" : "pages/storefabric/storeFabricBusinessOutList",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText": "坯布出库列表",
|
||||||
|
"enablePullDownRefresh": false
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"path": "pages/storefabric/storeFabricManualIn",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "手动进仓",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"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/storeFabricWarehouseGroupList",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText": "坯布库存",
|
||||||
|
"enablePullDownRefresh": false
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"path" : "pages/storefabric/storeFabricWarehouseStockList",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText": "坯布库存汇总",
|
||||||
|
"enablePullDownRefresh": false
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"path" : "pages/storefabric/storeFabricWarehouseDetail",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText": "细码明细",
|
||||||
|
"enablePullDownRefresh": false
|
||||||
|
}
|
||||||
|
},{
|
||||||
"path" : "pages/storefabric/storefabricstoresearch",
|
"path" : "pages/storefabric/storefabricstoresearch",
|
||||||
"style" :
|
"style" :
|
||||||
{
|
{
|
||||||
@@ -744,30 +807,12 @@
|
|||||||
"backgroundColor": "#ffffff",
|
"backgroundColor": "#ffffff",
|
||||||
"borderStyle": "white",
|
"borderStyle": "white",
|
||||||
"list": [
|
"list": [
|
||||||
{
|
|
||||||
"pagePath": "pages/sys/msg/index",
|
|
||||||
"iconPath": "static/aidex/tabbar/msg_1.png",
|
|
||||||
"selectedIconPath": "static/aidex/tabbar/msg_2.png",
|
|
||||||
"text": "消息"
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// "pagePath": "pages/sys/home/index",
|
|
||||||
// "iconPath": "static/aidex/tabbar/home_1.png",
|
|
||||||
// "selectedIconPath": "static/aidex/tabbar/home_2.png",
|
|
||||||
// "text": "首页"
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
"pagePath": "pages/sys/workbench/index",
|
"pagePath": "pages/sys/workbench/index",
|
||||||
"iconPath": "static/aidex/tabbar/apply_1.png",
|
"iconPath": "static/aidex/tabbar/apply_1.png",
|
||||||
"selectedIconPath": "static/aidex/tabbar/apply_2.png",
|
"selectedIconPath": "static/aidex/tabbar/apply_2.png",
|
||||||
"text": "工作台"
|
"text": "工作台"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"pagePath": "pages/sys/book/index",
|
|
||||||
"iconPath": "static/aidex/tabbar/book_1.png",
|
|
||||||
"selectedIconPath": "static/aidex/tabbar/book_2.png",
|
|
||||||
"text": "通讯录"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"pagePath": "pages/sys/user/index",
|
"pagePath": "pages/sys/user/index",
|
||||||
"iconPath": "static/aidex/tabbar/my_1.png",
|
"iconPath": "static/aidex/tabbar/my_1.png",
|
||||||
|
|||||||
@@ -17,6 +17,14 @@
|
|||||||
</u-form-item>
|
</u-form-item>
|
||||||
<u-form-item label-width="130" label="条码资料:">
|
<u-form-item label-width="130" label="条码资料:">
|
||||||
<input type="text" v-model="QRBarCode" maxlength="-1" style="width: 170px" @confirm="SalePickBillDetailScan" />
|
<input type="text" v-model="QRBarCode" maxlength="-1" style="width: 170px" @confirm="SalePickBillDetailScan" />
|
||||||
|
<u-icon
|
||||||
|
v-if="usePhoneScanFallback"
|
||||||
|
name="scan"
|
||||||
|
size="44"
|
||||||
|
color="#2979ff"
|
||||||
|
style="margin-left: 8px;"
|
||||||
|
@click="handlePhoneScan"
|
||||||
|
/>
|
||||||
<checkbox-group @change="handleAllCrockNoChange">
|
<checkbox-group @change="handleAllCrockNoChange">
|
||||||
<checkbox :checked="AllCrockNoScanStatus">整缸</checkbox>
|
<checkbox :checked="AllCrockNoScanStatus">整缸</checkbox>
|
||||||
</checkbox-group>
|
</checkbox-group>
|
||||||
@@ -182,21 +190,16 @@ export default {
|
|||||||
|
|
||||||
onUnload() {
|
onUnload() {
|
||||||
this.isPageActive = false;
|
this.isPageActive = false;
|
||||||
// #ifdef APP-PLUS
|
|
||||||
this.unregisterScanBroadcast();
|
this.unregisterScanBroadcast();
|
||||||
// #endif
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onHide() {
|
onHide() {
|
||||||
this.isPageActive = false;
|
this.isPageActive = false;
|
||||||
// #ifdef APP-PLUS
|
|
||||||
this.unregisterScanBroadcast();
|
this.unregisterScanBroadcast();
|
||||||
// #endif
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onShow() {
|
onShow() {
|
||||||
this.isPageActive = true;
|
this.isPageActive = true;
|
||||||
// #ifdef APP-PLUS
|
|
||||||
this.registerScanBroadcast((scanResult) => {
|
this.registerScanBroadcast((scanResult) => {
|
||||||
console.log("配布单详情-扫码结果:", scanResult);
|
console.log("配布单详情-扫码结果:", scanResult);
|
||||||
this.QRBarCode = scanResult;
|
this.QRBarCode = scanResult;
|
||||||
@@ -204,10 +207,13 @@ export default {
|
|||||||
this.handleScans();
|
this.handleScans();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// #endif
|
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
handlePhoneScan() {
|
||||||
|
this.openPhoneScan();
|
||||||
|
},
|
||||||
|
|
||||||
playSuccess() {
|
playSuccess() {
|
||||||
util.playSuccessAudio();
|
util.playSuccessAudio();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,215 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<view class="fabric-out-page">
|
||||||
|
|
||||||
|
<OrderStatusBar class="fabric-out-mt32" :status="displayAuditStatus" :name="displayAuditStatusName" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<view class="flex-white-plr26 ptb10 bdb_f5">
|
||||||
|
|
||||||
|
<text class="mr26">出仓单号</text>
|
||||||
|
|
||||||
|
<u-input disabled placeholder="保存后自动生成" v-model="form.order_no" />
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="flex-white-plr26 ptb20 bdb_f5">
|
||||||
|
|
||||||
|
<text class="mr26">出仓类型</text>
|
||||||
|
|
||||||
|
<view>{{ getBillTypeName() }}</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view @click="pickerSelectFun('接收单位')" class="flex-white-plr26 ptb20 bdb_f5">
|
||||||
|
|
||||||
|
<text class="mr26">接收单位<text class="redXingh">*</text></text>
|
||||||
|
|
||||||
|
<view :class="form.business_unit_name ? '' : 'cBlack'">
|
||||||
|
|
||||||
|
{{ form.business_unit_name || '请选择' }}
|
||||||
|
|
||||||
|
<u-icon v-if="headerEditable" class="ml26" name="arrow-right" size="40" color="#888888"></u-icon>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<view class="flex-white-plr26 ptb20 bdb_f5">
|
||||||
|
|
||||||
|
<text class="mr26">{{ dateLabel }}<text class="redXingh">*</text></text>
|
||||||
|
|
||||||
|
<picker mode="date" :value="form.delivery_time" :disabled="!headerEditable" @change="bindDateChange">
|
||||||
|
|
||||||
|
<view>{{ form.delivery_time }}</view>
|
||||||
|
|
||||||
|
</picker>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<view class="flex-white-plr26-column ptb20 mt32">
|
||||||
|
|
||||||
|
<view style="margin-bottom: 8rpx;"><text>单据备注</text></view>
|
||||||
|
|
||||||
|
<u-input v-model="form.remark" :disabled="!headerEditable" type="textarea" :border="true" :height="100" :auto-height="true" />
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FabricOutDetailList
|
||||||
|
|
||||||
|
:list="form.item_data"
|
||||||
|
|
||||||
|
@fabric-info="openFabricInfo"
|
||||||
|
|
||||||
|
@fine-code="openFineCode"
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
<FabricOutScanBar
|
||||||
|
slot="before-list"
|
||||||
|
:can-scan="canScan"
|
||||||
|
:value="QRBarCode"
|
||||||
|
:delete-mode="BarCodeDelStatus"
|
||||||
|
:message="BillDataMessage"
|
||||||
|
disabled-tip="请先提交保存后再扫码"
|
||||||
|
:show-phone-scan="usePhoneScanFallback"
|
||||||
|
@input="QRBarCode = $event"
|
||||||
|
@scan="handleScan"
|
||||||
|
@phone-scan="handlePhoneScan"
|
||||||
|
@delete-mode-change="BarCodeDelChange"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FabricOutScanDetail
|
||||||
|
slot="before-list"
|
||||||
|
:detail="scanDetail"
|
||||||
|
:group-keys="scanGroupKeys"
|
||||||
|
@group-change="scanGroupKeys = $event"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</FabricOutDetailList>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FabricOutFooter
|
||||||
|
|
||||||
|
v-if="!headerSaved"
|
||||||
|
|
||||||
|
:buttons="[{ label: '提交保存', action: 'save' }]"
|
||||||
|
|
||||||
|
single
|
||||||
|
|
||||||
|
@action="submitSave"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FabricOutFooter
|
||||||
|
|
||||||
|
v-else
|
||||||
|
|
||||||
|
:buttons="statusActionButtons"
|
||||||
|
|
||||||
|
@action="handleStatusAction"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<search-select-popup
|
||||||
|
:show.sync="selectShow"
|
||||||
|
title="选择接收单位"
|
||||||
|
placeholder="请输入染厂名称"
|
||||||
|
:list="selectList"
|
||||||
|
@confirm="selectConfirmFun"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FabricInfoPopup :show.sync="fabricInfoShow" :data="currentFabricInfo" />
|
||||||
|
|
||||||
|
<FineCodePopup :show.sync="fineCodeShow" :list="currentFineCodes" :readonly="false" @delete="onDeleteFineCode" />
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import formMixin from './storeFabricBusinessOutMixin.js';
|
||||||
|
|
||||||
|
import FabricInfoPopup from '@/components/storefabric/FabricInfoPopup.vue';
|
||||||
|
|
||||||
|
import FineCodePopup from '@/components/storefabric/FineCodePopup.vue';
|
||||||
|
|
||||||
|
import OrderStatusBar from '@/components/storefabric/OrderStatusBar.vue';
|
||||||
|
|
||||||
|
import FabricOutDetailList from '@/components/storefabric/FabricOutDetailList.vue';
|
||||||
|
|
||||||
|
import FabricOutScanBar from '@/components/storefabric/FabricOutScanBar.vue';
|
||||||
|
|
||||||
|
import FabricOutScanDetail from '@/components/storefabric/FabricOutScanDetail.vue';
|
||||||
|
|
||||||
|
import FabricOutFooter from '@/components/storefabric/FabricOutFooter.vue';
|
||||||
|
|
||||||
|
import SearchSelectPopup from '@/components/storefabric/SearchSelectPopup.vue';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
|
||||||
|
components: {
|
||||||
|
|
||||||
|
FabricInfoPopup,
|
||||||
|
|
||||||
|
FineCodePopup,
|
||||||
|
|
||||||
|
OrderStatusBar,
|
||||||
|
|
||||||
|
FabricOutDetailList,
|
||||||
|
|
||||||
|
FabricOutScanBar,
|
||||||
|
|
||||||
|
FabricOutScanDetail,
|
||||||
|
|
||||||
|
FabricOutFooter,
|
||||||
|
|
||||||
|
SearchSelectPopup,
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
mixins: [formMixin],
|
||||||
|
|
||||||
|
onLoad() {
|
||||||
|
|
||||||
|
uni.setNavigationBarTitle({ title: '新增坯布出仓单' });
|
||||||
|
|
||||||
|
this.pageMode = 'add';
|
||||||
|
|
||||||
|
this.loadBaseDropdowns();
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
|
||||||
|
@import '@/pages/storefabric/storeFabricBusinessOutPage.scss';
|
||||||
|
|
||||||
|
page {
|
||||||
|
background-color: #F8F8F8;
|
||||||
|
padding-bottom: 260rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
<template>
|
||||||
|
<view class="fabric-out-page">
|
||||||
|
<OrderStatusBar class="fabric-out-mt32" :status="displayAuditStatus" :name="displayAuditStatusName" />
|
||||||
|
|
||||||
|
<view class="flex-white-plr26 ptb10 bdb_f5">
|
||||||
|
<text class="mr26">出仓单号</text>
|
||||||
|
<text>{{ form.order_no }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex-white-plr26 ptb20 bdb_f5">
|
||||||
|
<text class="mr26">出仓类型</text>
|
||||||
|
<text>{{ getBillTypeName() }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex-white-plr26 ptb20 bdb_f5">
|
||||||
|
<text class="mr26">接收单位</text>
|
||||||
|
<text>{{ form.business_unit_name || '-' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex-white-plr26 ptb20 bdb_f5">
|
||||||
|
<text class="mr26">{{ dateLabel }}</text>
|
||||||
|
<text>{{ form.delivery_time }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex-white-plr26 ptb20 bdb_f5">
|
||||||
|
<text class="mr26">单据备注</text>
|
||||||
|
<text>{{ form.remark || '-' }}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<FabricOutDetailList
|
||||||
|
:list="form.item_data"
|
||||||
|
@fabric-info="openFabricInfo"
|
||||||
|
@fine-code="openFineCode"
|
||||||
|
>
|
||||||
|
<FabricOutScanBar
|
||||||
|
slot="before-list"
|
||||||
|
:can-scan="canScan"
|
||||||
|
:value="QRBarCode"
|
||||||
|
:delete-mode="BarCodeDelStatus"
|
||||||
|
:message="BillDataMessage"
|
||||||
|
:show-phone-scan="usePhoneScanFallback"
|
||||||
|
@input="QRBarCode = $event"
|
||||||
|
@scan="handleScan"
|
||||||
|
@phone-scan="handlePhoneScan"
|
||||||
|
@delete-mode-change="BarCodeDelChange"
|
||||||
|
/>
|
||||||
|
<FabricOutScanDetail
|
||||||
|
slot="before-list"
|
||||||
|
:detail="scanDetail"
|
||||||
|
:group-keys="scanGroupKeys"
|
||||||
|
@group-change="scanGroupKeys = $event"
|
||||||
|
/>
|
||||||
|
</FabricOutDetailList>
|
||||||
|
|
||||||
|
<FabricOutFooter :buttons="statusActionButtons" @action="handleStatusAction" />
|
||||||
|
|
||||||
|
<search-select-popup
|
||||||
|
:show.sync="selectShow"
|
||||||
|
title="选择接收单位"
|
||||||
|
placeholder="请输入染厂名称"
|
||||||
|
:list="selectList"
|
||||||
|
@confirm="selectConfirmFun"
|
||||||
|
/>
|
||||||
|
<FabricInfoPopup :show.sync="fabricInfoShow" :data="currentFabricInfo" />
|
||||||
|
<FineCodePopup :show.sync="fineCodeShow" :list="currentFineCodes" :readonly="false" @delete="onDeleteFineCode" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import formMixin from './storeFabricBusinessOutMixin.js';
|
||||||
|
import FabricInfoPopup from '@/components/storefabric/FabricInfoPopup.vue';
|
||||||
|
import FineCodePopup from '@/components/storefabric/FineCodePopup.vue';
|
||||||
|
import OrderStatusBar from '@/components/storefabric/OrderStatusBar.vue';
|
||||||
|
import FabricOutDetailList from '@/components/storefabric/FabricOutDetailList.vue';
|
||||||
|
import FabricOutScanBar from '@/components/storefabric/FabricOutScanBar.vue';
|
||||||
|
import FabricOutScanDetail from '@/components/storefabric/FabricOutScanDetail.vue';
|
||||||
|
import FabricOutFooter from '@/components/storefabric/FabricOutFooter.vue';
|
||||||
|
import SearchSelectPopup from '@/components/storefabric/SearchSelectPopup.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
FabricInfoPopup,
|
||||||
|
FineCodePopup,
|
||||||
|
OrderStatusBar,
|
||||||
|
FabricOutDetailList,
|
||||||
|
FabricOutScanBar,
|
||||||
|
FabricOutScanDetail,
|
||||||
|
FabricOutFooter,
|
||||||
|
SearchSelectPopup,
|
||||||
|
},
|
||||||
|
mixins: [formMixin],
|
||||||
|
onLoad(e) {
|
||||||
|
uni.setNavigationBarTitle({ title: '编辑坯布出仓单' });
|
||||||
|
this.pageMode = 'edit';
|
||||||
|
if (e.id) {
|
||||||
|
this.loadOrder(Number(e.id), { rejectIfLocked: true });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import '@/pages/storefabric/storeFabricBusinessOutPage.scss';
|
||||||
|
page {
|
||||||
|
background-color: #F8F8F8;
|
||||||
|
padding-bottom: 260rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,548 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<view class="filterBar">
|
||||||
|
<u-search
|
||||||
|
v-model="filters.order_no"
|
||||||
|
placeholder="出仓单号"
|
||||||
|
:show-action="false"
|
||||||
|
@search="applySearch"
|
||||||
|
@custom="applySearch"
|
||||||
|
@clear="applySearch"
|
||||||
|
/>
|
||||||
|
<view class="filterBtn" :class="{ 'filterBtn--active': hasActiveFilter }" @click="filterShow = true">
|
||||||
|
<view class="filterBtn__icon">
|
||||||
|
<u-icon name="list" size="44" :color="hasActiveFilter ? '#2979ff' : '#666'"></u-icon>
|
||||||
|
<view v-if="hasActiveFilter" class="filterBtn__badge"></view>
|
||||||
|
</view>
|
||||||
|
<text>筛选</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<scroll-view scroll-y :style="{ height: scrollHeight }" refresher-enabled
|
||||||
|
:refresher-triggered="triggered" @refresherrefresh="onRefresh">
|
||||||
|
<dataNull v-if="list.length === 0" src="/src/static/img/chahua/gjNull.png"
|
||||||
|
title="暂无坯布出仓单" title1="请点击右下角按钮新增">
|
||||||
|
</dataNull>
|
||||||
|
<view v-for="(item, index) in list" :key="item.id" @click="goView(item)">
|
||||||
|
<FabricOutItem :item="item" :index="index" />
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
|
||||||
|
<addBtn url="./storeFabricBusinessOutAdd"></addBtn>
|
||||||
|
|
||||||
|
<u-popup v-model="filterShow" mode="right" width="580rpx" :safe-area-inset-bottom="true" @close="cancelFilterEdit">
|
||||||
|
<view class="filterPanel">
|
||||||
|
<view class="filterTitle">筛选条件</view>
|
||||||
|
<view class="filterItem">
|
||||||
|
<text class="filterLabel">出仓单号</text>
|
||||||
|
<view class="filterInput">
|
||||||
|
<u-input
|
||||||
|
v-model="filters.order_no"
|
||||||
|
placeholder="请输入出仓单号"
|
||||||
|
:height="100"
|
||||||
|
:custom-style="{ fontSize: '36rpx', color: '#202328' }"
|
||||||
|
placeholder-style="color: #aeb4bf; font-size: 34rpx;"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="filterItem">
|
||||||
|
<text class="filterLabel">出仓日期</text>
|
||||||
|
<view class="dateRow">
|
||||||
|
<picker class="datePicker" mode="date" :value="filters.start_date" @change="e => filters.start_date = e.detail.value">
|
||||||
|
<view class="dateInput" :class="{ 'dateInput--placeholder': !filters.start_date }">
|
||||||
|
{{ filters.start_date || '开始日期' }}
|
||||||
|
</view>
|
||||||
|
</picker>
|
||||||
|
<text class="dateSeparator">~</text>
|
||||||
|
<picker class="datePicker" mode="date" :value="filters.end_date" @change="e => filters.end_date = e.detail.value">
|
||||||
|
<view class="dateInput" :class="{ 'dateInput--placeholder': !filters.end_date }">
|
||||||
|
{{ filters.end_date || '结束日期' }}
|
||||||
|
</view>
|
||||||
|
</picker>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="filterItem" @click="openDeliveryUnitSelect">
|
||||||
|
<text class="filterLabel">出仓单位</text>
|
||||||
|
<view class="filterValue">{{ deliveryUnitLabel || '全部' }} <u-icon name="arrow-right" size="36"></u-icon></view>
|
||||||
|
</view>
|
||||||
|
<view class="filterItem" @click="openBusinessUnitSelect">
|
||||||
|
<text class="filterLabel">接收单位</text>
|
||||||
|
<view class="filterValue">{{ businessUnitLabel || '全部' }} <u-icon name="arrow-right" size="36"></u-icon></view>
|
||||||
|
</view>
|
||||||
|
<view class="filterItem" @click="openStatusSelect">
|
||||||
|
<text class="filterLabel">订单状态</text>
|
||||||
|
<view class="filterValue">{{ statusLabel || '全部' }} <u-icon name="arrow-right" size="36"></u-icon></view>
|
||||||
|
</view>
|
||||||
|
<view class="filterActions">
|
||||||
|
<u-button type="warning" size="medium" @click="resetFilter">重置</u-button>
|
||||||
|
<u-button type="primary" size="medium" @click="applyFilter">确定</u-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</u-popup>
|
||||||
|
|
||||||
|
<u-select
|
||||||
|
class="pdaSelect"
|
||||||
|
v-model="statusSelectShow"
|
||||||
|
title="选择订单状态"
|
||||||
|
:list="statusSelectList"
|
||||||
|
:default-value="statusSelectDefault"
|
||||||
|
@confirm="onStatusConfirm"
|
||||||
|
></u-select>
|
||||||
|
<u-select
|
||||||
|
class="pdaSelect"
|
||||||
|
v-model="unitSelectShow"
|
||||||
|
title="选择出仓单位"
|
||||||
|
:list="unitSelectList"
|
||||||
|
:default-value="unitSelectDefault"
|
||||||
|
@confirm="onUnitConfirm"
|
||||||
|
></u-select>
|
||||||
|
<search-select-popup
|
||||||
|
:show.sync="businessUnitSelectShow"
|
||||||
|
title="选择接收单位"
|
||||||
|
placeholder="请输入染厂名称"
|
||||||
|
:list="businessUnitSelectList"
|
||||||
|
@confirm="onBusinessUnitConfirm"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import addBtn from '@/components/addBtn/addBtn.vue';
|
||||||
|
import FabricOutItem from '@/components/card/storeFabricBusinessOutItem.vue';
|
||||||
|
import SearchSelectPopup from '@/components/storefabric/SearchSelectPopup.vue';
|
||||||
|
import {
|
||||||
|
getStatusOptions,
|
||||||
|
AUDIT_STATUS,
|
||||||
|
AUDIT_STATUS_MAP,
|
||||||
|
BILL_TYPES,
|
||||||
|
BUSINESS_UNIT_TYPE_DYEING_FACTORY,
|
||||||
|
formatRoll,
|
||||||
|
mapToSelectOptions,
|
||||||
|
fetchAllOrderList,
|
||||||
|
} from '@/common/storeFabricBusinessOut';
|
||||||
|
|
||||||
|
const FILTER_STORAGE_KEY = 'storeFabricBusinessOutListFilters';
|
||||||
|
|
||||||
|
const createDefaultFilters = () => ({
|
||||||
|
order_no: '',
|
||||||
|
start_date: '',
|
||||||
|
end_date: '',
|
||||||
|
delivery_unit_id: '',
|
||||||
|
delivery_unit_name: '',
|
||||||
|
business_unit_id: '',
|
||||||
|
business_unit_name: '',
|
||||||
|
audit_status: AUDIT_STATUS.PENDING,
|
||||||
|
});
|
||||||
|
|
||||||
|
const normalizeFilters = (value) => {
|
||||||
|
const filters = createDefaultFilters();
|
||||||
|
if (!value || typeof value !== 'object' || Array.isArray(value)) return filters;
|
||||||
|
|
||||||
|
Object.keys(filters).forEach((key) => {
|
||||||
|
if (typeof value[key] === 'string' || typeof value[key] === 'number') {
|
||||||
|
filters[key] = value[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!filters.delivery_unit_id) filters.delivery_unit_name = '';
|
||||||
|
if (!filters.business_unit_id) filters.business_unit_name = '';
|
||||||
|
return filters;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { addBtn, FabricOutItem, SearchSelectPopup },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
list: [],
|
||||||
|
scrollHeight: '667px',
|
||||||
|
triggered: false,
|
||||||
|
filterShow: false,
|
||||||
|
statusSelectShow: false,
|
||||||
|
unitSelectShow: false,
|
||||||
|
businessUnitSelectShow: false,
|
||||||
|
unitSelectType: '',
|
||||||
|
deliveryUnitOptions: [],
|
||||||
|
businessUnitOptions: [],
|
||||||
|
unitOptionsLoading: false,
|
||||||
|
billTypeName: (BILL_TYPES[0] || {}).label || '坯布其他出货单',
|
||||||
|
filters: createDefaultFilters(),
|
||||||
|
appliedFilters: createDefaultFilters(),
|
||||||
|
statusSelectList: [
|
||||||
|
{ value: '', label: '全部' },
|
||||||
|
...getStatusOptions(),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
statusLabel() {
|
||||||
|
if (this.filters.audit_status === '' || this.filters.audit_status === null) return '';
|
||||||
|
return AUDIT_STATUS_MAP[Number(this.filters.audit_status)] || '';
|
||||||
|
},
|
||||||
|
deliveryUnitLabel() {
|
||||||
|
return this.filters.delivery_unit_name || '';
|
||||||
|
},
|
||||||
|
businessUnitLabel() {
|
||||||
|
return this.filters.business_unit_name || '';
|
||||||
|
},
|
||||||
|
unitSelectList() {
|
||||||
|
return [{ value: '', label: '全部' }, ...this.deliveryUnitOptions];
|
||||||
|
},
|
||||||
|
businessUnitSelectList() {
|
||||||
|
return [{ value: '', label: '全部' }, ...this.businessUnitOptions];
|
||||||
|
},
|
||||||
|
statusSelectDefault() {
|
||||||
|
const index = this.statusSelectList.findIndex(
|
||||||
|
(item) => String(item.value) === String(this.filters.audit_status)
|
||||||
|
);
|
||||||
|
return [index >= 0 ? index : 0];
|
||||||
|
},
|
||||||
|
unitSelectDefault() {
|
||||||
|
const index = this.unitSelectList.findIndex(
|
||||||
|
(item) => String(item.value) === String(this.filters.delivery_unit_id)
|
||||||
|
);
|
||||||
|
return [index >= 0 ? index : 0];
|
||||||
|
},
|
||||||
|
hasActiveFilter() {
|
||||||
|
const filters = this.appliedFilters;
|
||||||
|
return Boolean(
|
||||||
|
String(filters.order_no || '').trim()
|
||||||
|
|| filters.start_date
|
||||||
|
|| filters.end_date
|
||||||
|
|| filters.delivery_unit_id
|
||||||
|
|| filters.business_unit_id
|
||||||
|
|| (filters.audit_status !== '' && filters.audit_status !== null)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onLoad() {
|
||||||
|
uni.setNavigationBarTitle({ title: '坯布出库列表' });
|
||||||
|
this.restoreFilterCache();
|
||||||
|
uni.getSystemInfo({
|
||||||
|
success: (res) => {
|
||||||
|
this.scrollHeight = `${res.windowHeight - 50}px`;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onShow() {
|
||||||
|
this.loadList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
restoreFilterCache() {
|
||||||
|
try {
|
||||||
|
const filters = normalizeFilters(uni.getStorageSync(FILTER_STORAGE_KEY));
|
||||||
|
this.filters = { ...filters };
|
||||||
|
this.appliedFilters = { ...filters };
|
||||||
|
} catch (e) {
|
||||||
|
this.filters = createDefaultFilters();
|
||||||
|
this.appliedFilters = createDefaultFilters();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
saveFilterCache() {
|
||||||
|
try {
|
||||||
|
uni.setStorageSync(FILTER_STORAGE_KEY, { ...this.appliedFilters });
|
||||||
|
} catch (e) {
|
||||||
|
// 缓存失败不影响列表筛选
|
||||||
|
}
|
||||||
|
},
|
||||||
|
commitFilters() {
|
||||||
|
const filters = normalizeFilters(this.filters);
|
||||||
|
this.filters = { ...filters };
|
||||||
|
this.appliedFilters = { ...filters };
|
||||||
|
this.saveFilterCache();
|
||||||
|
this.loadList();
|
||||||
|
},
|
||||||
|
applySearch() {
|
||||||
|
this.commitFilters();
|
||||||
|
},
|
||||||
|
cancelFilterEdit() {
|
||||||
|
this.filters = { ...this.appliedFilters };
|
||||||
|
},
|
||||||
|
loadDeliveryUnitOptions() {
|
||||||
|
if (this.deliveryUnitOptions.length) return Promise.resolve(this.deliveryUnitOptions);
|
||||||
|
return this.$u.api.businessUnit.list({})
|
||||||
|
.then((res) => {
|
||||||
|
this.deliveryUnitOptions = mapToSelectOptions(res);
|
||||||
|
return this.deliveryUnitOptions;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.deliveryUnitOptions = [];
|
||||||
|
return this.deliveryUnitOptions;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
loadBusinessUnitOptions() {
|
||||||
|
if (this.businessUnitOptions.length) return Promise.resolve(this.businessUnitOptions);
|
||||||
|
return this.$u.api.businessUnit.list({ unit_type_id: BUSINESS_UNIT_TYPE_DYEING_FACTORY })
|
||||||
|
.then((res) => {
|
||||||
|
this.businessUnitOptions = mapToSelectOptions(res);
|
||||||
|
return this.businessUnitOptions;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.businessUnitOptions = [];
|
||||||
|
return this.businessUnitOptions;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
openUnitSelect(type) {
|
||||||
|
if (this.unitOptionsLoading) return;
|
||||||
|
this.unitOptionsLoading = true;
|
||||||
|
const loadFn = type === 'delivery' ? this.loadDeliveryUnitOptions : this.loadBusinessUnitOptions;
|
||||||
|
loadFn.call(this)
|
||||||
|
.then((list) => {
|
||||||
|
if (!list.length) {
|
||||||
|
uni.showToast({ title: '暂无可选单位', icon: 'none' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.unitSelectType = type;
|
||||||
|
this.unitSelectShow = true;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.unitOptionsLoading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
openDeliveryUnitSelect() {
|
||||||
|
this.openUnitSelect('delivery');
|
||||||
|
},
|
||||||
|
openBusinessUnitSelect() {
|
||||||
|
if (this.unitOptionsLoading) return;
|
||||||
|
this.unitOptionsLoading = true;
|
||||||
|
this.loadBusinessUnitOptions()
|
||||||
|
.then((list) => {
|
||||||
|
if (!list.length) {
|
||||||
|
uni.showToast({ title: '暂无可选单位', icon: 'none' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.businessUnitSelectShow = true;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.unitOptionsLoading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onBusinessUnitConfirm(item) {
|
||||||
|
this.filters.business_unit_id = item.value;
|
||||||
|
this.filters.business_unit_name = item.value ? item.label : '';
|
||||||
|
},
|
||||||
|
onUnitConfirm(e) {
|
||||||
|
const item = e[0] || {};
|
||||||
|
if (this.unitSelectType === 'delivery') {
|
||||||
|
this.filters.delivery_unit_id = item.value;
|
||||||
|
this.filters.delivery_unit_name = item.value ? item.label : '';
|
||||||
|
} else {
|
||||||
|
this.filters.business_unit_id = item.value;
|
||||||
|
this.filters.business_unit_name = item.value ? item.label : '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
loadList() {
|
||||||
|
const filters = this.appliedFilters;
|
||||||
|
const params = {};
|
||||||
|
if (filters.order_no) params.order_no = filters.order_no;
|
||||||
|
if (filters.audit_status !== '' && filters.audit_status !== null) {
|
||||||
|
params.audit_status = filters.audit_status;
|
||||||
|
}
|
||||||
|
fetchAllOrderList((p) => this.$u.api.gfmOtherDeliveryOrder.list(p), params)
|
||||||
|
.then((rows) => {
|
||||||
|
this.triggered = false;
|
||||||
|
this.list = rows.map(this.mapToCard).filter(this.matchClientFilter);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
this.triggered = false;
|
||||||
|
this.list = [];
|
||||||
|
uni.showToast({ title: err.message || '加载失败', icon: 'none' });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
mapToCard(order) {
|
||||||
|
return {
|
||||||
|
id: order.id,
|
||||||
|
order_no: order.order_no || '',
|
||||||
|
out_date: (order.delivery_time || '').slice(0, 10),
|
||||||
|
bill_type_name: this.billTypeName,
|
||||||
|
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 || '',
|
||||||
|
create_user_name: order.creator_name || '',
|
||||||
|
create_time: order.create_time || '',
|
||||||
|
auditor_name: order.auditer_name || '',
|
||||||
|
audit_date: order.audit_time || '',
|
||||||
|
audit_status: order.audit_status,
|
||||||
|
audit_status_name: order.audit_status_name || AUDIT_STATUS_MAP[order.audit_status] || '',
|
||||||
|
total_roll: formatRoll(order.total_roll),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
// 后端列表仅支持 单号/状态 过滤,出仓日期与单位在前端做本地过滤
|
||||||
|
matchClientFilter(item) {
|
||||||
|
const filters = this.appliedFilters;
|
||||||
|
if (filters.start_date && item.out_date < filters.start_date) return false;
|
||||||
|
if (filters.end_date && item.out_date > filters.end_date) return false;
|
||||||
|
if (filters.delivery_unit_id && String(item.delivery_unit_id) !== String(filters.delivery_unit_id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (filters.business_unit_id && String(item.business_unit_id) !== String(filters.business_unit_id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
onRefresh() {
|
||||||
|
this.triggered = true;
|
||||||
|
this.loadList();
|
||||||
|
},
|
||||||
|
goView(item) {
|
||||||
|
const page = Number(item.audit_status) === AUDIT_STATUS.PENDING
|
||||||
|
? 'storeFabricBusinessOutEdit'
|
||||||
|
: 'storeFabricBusinessOutView';
|
||||||
|
uni.navigateTo({ url: `./${page}?id=${item.id}` });
|
||||||
|
},
|
||||||
|
openStatusSelect() { this.statusSelectShow = true; },
|
||||||
|
onStatusConfirm(e) { this.filters.audit_status = e[0].value; },
|
||||||
|
resetFilter() {
|
||||||
|
this.filters = createDefaultFilters();
|
||||||
|
},
|
||||||
|
applyFilter() {
|
||||||
|
this.commitFilters();
|
||||||
|
this.filterShow = false;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import '@/common/pda-typography.scss';
|
||||||
|
|
||||||
|
page { background-color: #F8F8F8; }
|
||||||
|
.filterBar { display: flex; align-items: center; padding: 16rpx 20rpx; background: #fff; gap: 16rpx; }
|
||||||
|
.filterBtn {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 88rpx;
|
||||||
|
min-height: 76rpx;
|
||||||
|
padding: 6rpx 8rpx;
|
||||||
|
border: 2rpx solid transparent;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-size: $pda-font-nav-sub;
|
||||||
|
line-height: 1.2;
|
||||||
|
color: #666;
|
||||||
|
transition: color 0.2s, background-color 0.2s, border-color 0.2s;
|
||||||
|
}
|
||||||
|
.filterBtn--active {
|
||||||
|
color: #2979ff;
|
||||||
|
background: #eef5ff;
|
||||||
|
border-color: #9fc5ff;
|
||||||
|
}
|
||||||
|
.filterBtn__icon {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.filterBtn__badge {
|
||||||
|
position: absolute;
|
||||||
|
top: -3rpx;
|
||||||
|
right: -7rpx;
|
||||||
|
width: 13rpx;
|
||||||
|
height: 13rpx;
|
||||||
|
border: 3rpx solid #fff;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #ff4d4f;
|
||||||
|
box-sizing: content-box;
|
||||||
|
}
|
||||||
|
.filterPanel {
|
||||||
|
min-height: 100%;
|
||||||
|
padding: 32rpx 28rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.filterTitle {
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
font-size: $pda-font-popup-title;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #202328;
|
||||||
|
}
|
||||||
|
.filterItem { margin-bottom: 28rpx; }
|
||||||
|
.filterLabel {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 14rpx;
|
||||||
|
font-size: $pda-font-body;
|
||||||
|
line-height: 1.35;
|
||||||
|
color: #555b66;
|
||||||
|
}
|
||||||
|
.filterInput {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
min-height: $pda-row-min-height;
|
||||||
|
padding: 0 18rpx;
|
||||||
|
background: #f5f6f8;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
::v-deep .filterInput .u-input__input {
|
||||||
|
font-size: $pda-font-body !important;
|
||||||
|
color: #202328;
|
||||||
|
}
|
||||||
|
::v-deep .filterInput .u-input__input::placeholder {
|
||||||
|
font-size: $pda-font-placeholder;
|
||||||
|
color: #aeb4bf;
|
||||||
|
}
|
||||||
|
.filterValue {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
min-height: $pda-row-min-height;
|
||||||
|
padding: 0 18rpx;
|
||||||
|
background: #f5f6f8;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-size: $pda-font-body;
|
||||||
|
color: #202328;
|
||||||
|
}
|
||||||
|
.dateRow {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10rpx;
|
||||||
|
}
|
||||||
|
.datePicker {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
.dateInput {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: $pda-row-min-height;
|
||||||
|
padding: 0 8rpx;
|
||||||
|
background: #f5f6f8;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-size: $pda-font-body;
|
||||||
|
color: #202328;
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.dateInput--placeholder {
|
||||||
|
font-size: $pda-font-placeholder;
|
||||||
|
color: #7d8490;
|
||||||
|
}
|
||||||
|
.dateSeparator {
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-size: $pda-font-body;
|
||||||
|
color: #555b66;
|
||||||
|
}
|
||||||
|
.filterActions {
|
||||||
|
display: flex;
|
||||||
|
gap: 20rpx;
|
||||||
|
margin-top: 40rpx;
|
||||||
|
}
|
||||||
|
.filterActions .u-btn {
|
||||||
|
flex: 1;
|
||||||
|
height: $pda-button-height !important;
|
||||||
|
line-height: $pda-button-height !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
font-size: $pda-font-button !important;
|
||||||
|
}
|
||||||
|
::v-deep .pdaSelect .u-select__header {
|
||||||
|
height: $pda-row-min-height;
|
||||||
|
}
|
||||||
|
::v-deep .pdaSelect .u-select__header__btn,
|
||||||
|
::v-deep .pdaSelect .u-select__header__title,
|
||||||
|
::v-deep .pdaSelect .u-select__body__picker-view__item {
|
||||||
|
font-size: $pda-font-popup-item !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,399 @@
|
|||||||
|
/**
|
||||||
|
* 坯布出仓单(其他出货单)表单 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,
|
||||||
|
BUSINESS_UNIT_TYPE_DYEING_FACTORY,
|
||||||
|
normalizeOrder,
|
||||||
|
mapToSelectOptions,
|
||||||
|
getFineCodeScanCode,
|
||||||
|
canScanAtStatus,
|
||||||
|
isLockedOrderStatus,
|
||||||
|
getFormStatusActionButtons,
|
||||||
|
orderToFormFields,
|
||||||
|
confirmOrderStatusAction,
|
||||||
|
STATUS_ACTION_VOICE,
|
||||||
|
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;
|
||||||
|
if (this.canScan && this.isEditable) {
|
||||||
|
this.registerScanBroadcast((scanResult) => {
|
||||||
|
this.QRBarCode = scanResult.trim().replace(/[\r\n]/g, '');
|
||||||
|
this.$nextTick(() => this.handleScan());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onHide() {
|
||||||
|
this.isPageActive = false;
|
||||||
|
this.unregisterScanBroadcast();
|
||||||
|
},
|
||||||
|
onUnload() {
|
||||||
|
this.isPageActive = false;
|
||||||
|
this.unregisterScanBroadcast();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handlePhoneScan() {
|
||||||
|
this.openPhoneScan();
|
||||||
|
},
|
||||||
|
registerOrderScanBroadcast() {
|
||||||
|
this.registerScanBroadcast((scanResult) => {
|
||||||
|
this.QRBarCode = scanResult.trim().replace(/[\r\n]/g, '');
|
||||||
|
this.$nextTick(() => this.handleScan());
|
||||||
|
});
|
||||||
|
},
|
||||||
|
syncCanScanFromStatus(status) {
|
||||||
|
const nextCanScan = this.isEditable && canScanAtStatus(status);
|
||||||
|
if (this.canScan && !nextCanScan) {
|
||||||
|
this.unregisterScanBroadcast();
|
||||||
|
}
|
||||||
|
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({ unit_type_id: BUSINESS_UNIT_TYPE_DYEING_FACTORY })
|
||||||
|
.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(item) {
|
||||||
|
if (!item || this.selectType !== '接收单位') return;
|
||||||
|
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.playSpeak('扫码出仓成功');
|
||||||
|
})
|
||||||
|
.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);
|
||||||
|
const voice = STATUS_ACTION_VOICE[action] || '';
|
||||||
|
this.showSuccess(voice || '操作成功', voice);
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
showError(message) {
|
||||||
|
util.playErrorAudio();
|
||||||
|
uni.showModal({ title: '提示', content: message, showCancel: false });
|
||||||
|
},
|
||||||
|
showSuccess(message, speakText) {
|
||||||
|
if (speakText) util.playSpeak(speakText);
|
||||||
|
else util.playSuccessAudio();
|
||||||
|
uni.showToast({ title: message, icon: 'success' });
|
||||||
|
},
|
||||||
|
getBillTypeName() {
|
||||||
|
return this.billTypeName;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
/* 坯布出仓单页面共用样式(新增/编辑/查看) */
|
||||||
|
.fabric-out-page {
|
||||||
|
background-color: #F8F8F8;
|
||||||
|
padding-bottom: 260rpx;
|
||||||
|
}
|
||||||
|
.fabric-out-mt32 {
|
||||||
|
margin-top: 32rpx;
|
||||||
|
}
|
||||||
|
.fabric-out-page .flex-white-plr26,
|
||||||
|
.fabric-out-page .flex-white-plr26-column,
|
||||||
|
.fabric-out-page .flex-white-plr26 text,
|
||||||
|
.fabric-out-page .flex-white-plr26 view,
|
||||||
|
.fabric-out-page .u-input__input,
|
||||||
|
.fabric-out-page .uni-input-input,
|
||||||
|
.fabric-out-page .uni-textarea-textarea {
|
||||||
|
font-size: 40rpx;
|
||||||
|
}
|
||||||
|
.fabric-out-page .redXingh {
|
||||||
|
font-size: 40rpx;
|
||||||
|
}
|
||||||
|
.fabric-out-page .u-btn {
|
||||||
|
font-size: 36rpx !important;
|
||||||
|
height: 88rpx;
|
||||||
|
line-height: 88rpx;
|
||||||
|
}
|
||||||
|
.fabric-out-sectionTitle {
|
||||||
|
font-size: 42rpx;
|
||||||
|
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: 36rpx;
|
||||||
|
background: #fff7e6;
|
||||||
|
margin: 16rpx 26rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
.fabric-out-msgTip {
|
||||||
|
padding: 12rpx 26rpx;
|
||||||
|
color: #52c41a;
|
||||||
|
font-size: 36rpx;
|
||||||
|
}
|
||||||
|
.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: 38rpx;
|
||||||
|
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: 36rpx;
|
||||||
|
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: 36rpx;
|
||||||
|
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: 36rpx;
|
||||||
|
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-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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
<template>
|
||||||
|
<view class="fabric-out-page">
|
||||||
|
<OrderStatusBar class="fabric-out-mt32" :status="order.audit_status" :name="order.audit_status_name" />
|
||||||
|
|
||||||
|
<view class="flex-white-plr26 ptb10 bdb_f5">
|
||||||
|
<text class="mr26">出仓单号</text>
|
||||||
|
<text>{{ order.order_no }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex-white-plr26 ptb20 bdb_f5">
|
||||||
|
<text class="mr26">出仓类型</text>
|
||||||
|
<text>{{ billTypeName }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex-white-plr26 ptb20 bdb_f5">
|
||||||
|
<text class="mr26">接收单位</text><text>{{ order.business_unit_name }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex-white-plr26 ptb20 bdb_f5">
|
||||||
|
<text class="mr26">出货日期</text><text>{{ formatTime(order.delivery_time) }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex-white-plr26 ptb20 bdb_f5">
|
||||||
|
<text class="mr26">单据备注</text><text>{{ order.remark || '-' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex-white-plr26 ptb20 bdb_f5">
|
||||||
|
<text class="mr26">创建人</text><text>{{ order.creator_name }} {{ formatTime(order.create_time, 'YYYY-MM-DD') }}</text>
|
||||||
|
</view>
|
||||||
|
<view v-if="order.auditer_name" class="flex-white-plr26 ptb20 bdb_f5">
|
||||||
|
<text class="mr26">审核人</text><text>{{ order.auditer_name }} {{ formatTime(order.audit_time, 'YYYY-MM-DD') }}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<FabricOutDetailList
|
||||||
|
:title="detailTitle"
|
||||||
|
:list="order.item_data"
|
||||||
|
@fabric-info="openFabricInfo"
|
||||||
|
@fine-code="openFineCode"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FabricOutFooter :buttons="actionButtons" @action="handleAction" />
|
||||||
|
|
||||||
|
<FabricInfoPopup :show.sync="fabricInfoShow" :data="currentFabricInfo" />
|
||||||
|
<FineCodePopup :show.sync="fineCodeShow" :list="currentFineCodes" :readonly="true" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import util from '@/common/util';
|
||||||
|
import FabricInfoPopup from '@/components/storefabric/FabricInfoPopup.vue';
|
||||||
|
import FineCodePopup from '@/components/storefabric/FineCodePopup.vue';
|
||||||
|
import OrderStatusBar from '@/components/storefabric/OrderStatusBar.vue';
|
||||||
|
import FabricOutDetailList from '@/components/storefabric/FabricOutDetailList.vue';
|
||||||
|
import FabricOutFooter from '@/components/storefabric/FabricOutFooter.vue';
|
||||||
|
import {
|
||||||
|
BILL_TYPES,
|
||||||
|
normalizeOrder,
|
||||||
|
getViewStatusActionButtons,
|
||||||
|
confirmOrderStatusAction,
|
||||||
|
formatDisplayTime,
|
||||||
|
STATUS_ACTION_VOICE,
|
||||||
|
} from '@/common/storeFabricBusinessOut';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { FabricInfoPopup, FineCodePopup, OrderStatusBar, FabricOutDetailList, FabricOutFooter },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
orderId: 0,
|
||||||
|
order: {},
|
||||||
|
billTypeName: (BILL_TYPES[0] || {}).label || '坯布其他出货单',
|
||||||
|
fabricInfoShow: false,
|
||||||
|
fineCodeShow: false,
|
||||||
|
currentFabricInfo: {},
|
||||||
|
currentFineCodes: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
actionButtons() {
|
||||||
|
return getViewStatusActionButtons(this.order.audit_status);
|
||||||
|
},
|
||||||
|
detailTitle() {
|
||||||
|
return `出仓细码(共 ${this.order.total_roll || 0} 匹 / ${this.order.total_weight || 0} KG)`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onLoad(e) {
|
||||||
|
uni.setNavigationBarTitle({ title: '查看坯布出仓单' });
|
||||||
|
if (e.id) {
|
||||||
|
this.orderId = Number(e.id);
|
||||||
|
this.refreshOrder();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onShow() {
|
||||||
|
if (this.orderId) this.refreshOrder();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
formatTime: formatDisplayTime,
|
||||||
|
refreshOrder() {
|
||||||
|
this.$u.api.gfmOtherDeliveryOrder.detail({ id: this.orderId })
|
||||||
|
.then((res) => {
|
||||||
|
const order = normalizeOrder(res);
|
||||||
|
if (!order) {
|
||||||
|
this.showError('单据不存在');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.order = order;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
this.showError(err.message || '加载单据失败');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
openFabricInfo(row) {
|
||||||
|
this.currentFabricInfo = { ...row };
|
||||||
|
this.fabricInfoShow = true;
|
||||||
|
},
|
||||||
|
openFineCode(row) {
|
||||||
|
this.currentFineCodes = [...(row.fine_codes || [])];
|
||||||
|
this.fineCodeShow = true;
|
||||||
|
},
|
||||||
|
handleAction(action) {
|
||||||
|
if (action === 'edit') {
|
||||||
|
uni.navigateTo({ url: `./storeFabricBusinessOutEdit?id=${this.orderId}` });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
confirmOrderStatusAction(this, {
|
||||||
|
orderId: this.orderId,
|
||||||
|
action,
|
||||||
|
onSuccess: () => this.$u.api.gfmOtherDeliveryOrder.detail({ id: this.orderId })
|
||||||
|
.then((res) => {
|
||||||
|
uni.hideLoading();
|
||||||
|
const order = normalizeOrder(res);
|
||||||
|
if (order) this.order = order;
|
||||||
|
const voice = STATUS_ACTION_VOICE[action] || '';
|
||||||
|
if (voice) util.playSpeak(voice);
|
||||||
|
else util.playSuccessAudio();
|
||||||
|
uni.showToast({ title: voice || '操作成功', icon: 'success' });
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
showError(message) {
|
||||||
|
util.playErrorAudio();
|
||||||
|
uni.showModal({ title: '提示', content: message, showCancel: false });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import '@/pages/storefabric/storeFabricBusinessOutPage.scss';
|
||||||
|
page {
|
||||||
|
background-color: #F8F8F8;
|
||||||
|
padding-bottom: 260rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,561 @@
|
|||||||
|
<template>
|
||||||
|
<view class="manual-in">
|
||||||
|
<common-navbar title="手动进仓">
|
||||||
|
<template #right>
|
||||||
|
<view class="manual-in__setting" @click="navToSetting">
|
||||||
|
<u-icon name="setting" color="#333333" size="34"></u-icon>
|
||||||
|
<text>设置</text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</common-navbar>
|
||||||
|
|
||||||
|
<view class="manual-in__scan">
|
||||||
|
<input
|
||||||
|
class="manual-in__scan-input"
|
||||||
|
type="text"
|
||||||
|
confirm-type="done"
|
||||||
|
:focus="scanFocus"
|
||||||
|
v-model="scanCode"
|
||||||
|
placeholder="请点击扫描/输入布票编码"
|
||||||
|
placeholder-class="manual-in__placeholder"
|
||||||
|
@confirm="onScanConfirm"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="manual-in__panel">
|
||||||
|
<view class="manual-in__row">
|
||||||
|
<text class="manual-in__label">布票编码</text>
|
||||||
|
<text class="manual-in__value">{{ detail.fabric_piece_code || '-' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="manual-in__row">
|
||||||
|
<text class="manual-in__label">生产单号</text>
|
||||||
|
<text class="manual-in__value">{{ detail.production_order_no || '-' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="manual-in__row">
|
||||||
|
<text class="manual-in__label">机台</text>
|
||||||
|
<text class="manual-in__value">{{ detail.machine_number || '-' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="manual-in__row">
|
||||||
|
<text class="manual-in__label">布种名称</text>
|
||||||
|
<text class="manual-in__value">{{ detail.grey_fabric_name || '-' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="manual-in__row">
|
||||||
|
<text class="manual-in__label">坯布编号</text>
|
||||||
|
<text class="manual-in__value">{{ detail.grey_fabric_code || '-' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="manual-in__row manual-in__row--input">
|
||||||
|
<text class="manual-in__label">重量</text>
|
||||||
|
<view class="manual-in__right">
|
||||||
|
<input
|
||||||
|
class="manual-in__field"
|
||||||
|
type="digit"
|
||||||
|
v-model="weightKg"
|
||||||
|
placeholder="请输入"
|
||||||
|
placeholder-class="manual-in__placeholder"
|
||||||
|
/>
|
||||||
|
<text class="manual-in__unit">KG</text>
|
||||||
|
<text class="manual-in__action" @click="clearWeight">取消</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="manual-in__row manual-in__row--input" @click="openLevelPicker">
|
||||||
|
<text class="manual-in__label">等级</text>
|
||||||
|
<view class="manual-in__right">
|
||||||
|
<text :class="levelDisplayName ? 'manual-in__field-text' : 'manual-in__placeholder'">
|
||||||
|
{{ levelDisplayName || '请选择等级' }}
|
||||||
|
</text>
|
||||||
|
<text class="manual-in__action" @click.stop="clearLevel">取消</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="manual-in__row manual-in__row--input" @click="openInspectorPicker">
|
||||||
|
<text class="manual-in__label">查布工</text>
|
||||||
|
<view class="manual-in__right">
|
||||||
|
<text :class="detail.inspector_name ? 'manual-in__field-text' : 'manual-in__placeholder'">
|
||||||
|
{{ detail.inspector_name || '请选择查布工' }}
|
||||||
|
</text>
|
||||||
|
<text class="manual-in__action" @click.stop="clearInspector">取消</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="manual-in__row manual-in__row--input">
|
||||||
|
<text class="manual-in__label">存放仓位</text>
|
||||||
|
<view class="manual-in__right">
|
||||||
|
<input
|
||||||
|
class="manual-in__field"
|
||||||
|
type="text"
|
||||||
|
v-model="warehouseBinName"
|
||||||
|
placeholder="/"
|
||||||
|
placeholder-class="manual-in__placeholder"
|
||||||
|
/>
|
||||||
|
<text class="manual-in__action" @click="editWarehouseBin">修改</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="manual-in__row" v-if="detail.volume_number != null && detail.volume_number !== ''">
|
||||||
|
<text class="manual-in__label">卷号</text>
|
||||||
|
<text class="manual-in__value">{{ detail.volume_number }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="manual-in__footer">
|
||||||
|
<u-button
|
||||||
|
type="primary"
|
||||||
|
shape="circle"
|
||||||
|
:loading="submitting"
|
||||||
|
:disabled="submitting || loadingDetail"
|
||||||
|
@click="submitInWarehouse"
|
||||||
|
>确定进仓</u-button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<SearchSelectPopup
|
||||||
|
:show.sync="levelPickerShow"
|
||||||
|
title="选择等级"
|
||||||
|
placeholder="请输入等级名称"
|
||||||
|
:list="levelOptions"
|
||||||
|
@confirm="onLevelConfirm"
|
||||||
|
/>
|
||||||
|
<SearchSelectPopup
|
||||||
|
:show.sync="inspectorPickerShow"
|
||||||
|
title="选择查布工"
|
||||||
|
placeholder="请输入查布工姓名"
|
||||||
|
:list="inspectorOptions"
|
||||||
|
@confirm="onInspectorConfirm"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import CommonNavbar from '@/components/common-navbar/index';
|
||||||
|
import SearchSelectPopup from '@/components/storefabric/SearchSelectPopup.vue';
|
||||||
|
import scanMixin from '@/common/scanMixin.js';
|
||||||
|
import util from '@/common/util.js';
|
||||||
|
import { formatWeightKg } from '@/common/storeFabricBusinessOut.js';
|
||||||
|
|
||||||
|
// 坯布等级字典 id(与后台字典配置一致)
|
||||||
|
const DICTIONARY_TYPE_GREY_FABRIC_LEVEL = 10025;
|
||||||
|
// 查布工岗位 duty(验布/查布相关)
|
||||||
|
const INSPECTOR_DUTY = '20004,20011';
|
||||||
|
const WEIGHT_SCALE = 10000;
|
||||||
|
|
||||||
|
function emptyDetail() {
|
||||||
|
return {
|
||||||
|
fabric_piece_code: '',
|
||||||
|
production_order_no: '',
|
||||||
|
machine_number: '',
|
||||||
|
grey_fabric_name: '',
|
||||||
|
grey_fabric_code: '',
|
||||||
|
inspection_weight: null,
|
||||||
|
grey_fabric_level_id: [],
|
||||||
|
grey_fabric_level_name: '',
|
||||||
|
inspector_id: null,
|
||||||
|
inspector_name: '',
|
||||||
|
volume_number: '',
|
||||||
|
grey_fabric_id: '',
|
||||||
|
id: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function toWeightInt(kg) {
|
||||||
|
const raw = String(kg == null ? '' : kg).trim();
|
||||||
|
if (!raw) return null;
|
||||||
|
const n = Number(raw);
|
||||||
|
if (!Number.isFinite(n) || n <= 0) return null;
|
||||||
|
return Math.round(n * WEIGHT_SCALE);
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatDisplayWeightKg(value) {
|
||||||
|
if (value == null || value === '') return '';
|
||||||
|
const n = Number(value);
|
||||||
|
if (!Number.isFinite(n) || n <= 0) return '';
|
||||||
|
return String(formatWeightKg(n));
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeLevelIds(value) {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
return value.map((item) => Number(item)).filter((item) => Number.isFinite(item));
|
||||||
|
}
|
||||||
|
if (value == null || value === '') return [];
|
||||||
|
const n = Number(value);
|
||||||
|
return Number.isFinite(n) ? [n] : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { CommonNavbar, SearchSelectPopup },
|
||||||
|
mixins: [scanMixin],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
scanCode: '',
|
||||||
|
scanFocus: true,
|
||||||
|
submitting: false,
|
||||||
|
loadingDetail: false,
|
||||||
|
warehouseBinId: null,
|
||||||
|
warehouseBinName: '',
|
||||||
|
weightKg: '',
|
||||||
|
detail: emptyDetail(),
|
||||||
|
levelPickerShow: false,
|
||||||
|
levelOptions: [],
|
||||||
|
levelOptionsLoaded: false,
|
||||||
|
inspectorPickerShow: false,
|
||||||
|
inspectorOptions: [],
|
||||||
|
inspectorOptionsLoaded: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
levelDisplayName() {
|
||||||
|
return this.detail.grey_fabric_level_name || '';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onLoad() {
|
||||||
|
this.registerScanBroadcast(this.handleScanCode);
|
||||||
|
this.loadLevelOptions();
|
||||||
|
this.loadInspectorOptions();
|
||||||
|
},
|
||||||
|
onShow() {
|
||||||
|
this.scanFocus = false;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.scanFocus = true;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
navToSetting() {
|
||||||
|
uni.navigateTo({ url: '/pages/sys/user/scan-settings' });
|
||||||
|
},
|
||||||
|
clearWeight() {
|
||||||
|
this.weightKg = '';
|
||||||
|
this.detail.inspection_weight = null;
|
||||||
|
},
|
||||||
|
clearLevel() {
|
||||||
|
this.detail.grey_fabric_level_id = [];
|
||||||
|
this.detail.grey_fabric_level_name = '';
|
||||||
|
},
|
||||||
|
clearInspector() {
|
||||||
|
this.detail.inspector_id = null;
|
||||||
|
this.detail.inspector_name = '';
|
||||||
|
},
|
||||||
|
editWarehouseBin() {
|
||||||
|
uni.showModal({
|
||||||
|
title: '存放仓位',
|
||||||
|
editable: true,
|
||||||
|
placeholderText: '请输入仓位名称',
|
||||||
|
content: this.warehouseBinName || '',
|
||||||
|
success: (res) => {
|
||||||
|
if (!res.confirm) return;
|
||||||
|
this.warehouseBinName = (res.content || '').trim();
|
||||||
|
this.warehouseBinId = null;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
async loadLevelOptions() {
|
||||||
|
try {
|
||||||
|
const res = await this.$u.api.dictionary.getDetailEnumList({
|
||||||
|
dictionary_id: DICTIONARY_TYPE_GREY_FABRIC_LEVEL,
|
||||||
|
status: 1,
|
||||||
|
size: 200,
|
||||||
|
});
|
||||||
|
const list = Array.isArray(res) ? res : (Array.isArray(res && res.list) ? res.list : []);
|
||||||
|
this.levelOptions = list
|
||||||
|
.map((item) => ({
|
||||||
|
value: item.id,
|
||||||
|
label: item.name || item.code || String(item.id),
|
||||||
|
}))
|
||||||
|
.filter((item) => item.value != null);
|
||||||
|
this.levelOptionsLoaded = true;
|
||||||
|
} catch (error) {
|
||||||
|
console.log('加载坯布等级枚举失败', error);
|
||||||
|
this.levelOptions = [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async openLevelPicker() {
|
||||||
|
if (!this.levelOptionsLoaded || !this.levelOptions.length) {
|
||||||
|
await this.loadLevelOptions();
|
||||||
|
}
|
||||||
|
if (!this.levelOptions.length) {
|
||||||
|
this.$u.toast('暂无等级可选,请检查等级字典配置');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.levelPickerShow = true;
|
||||||
|
},
|
||||||
|
onLevelConfirm(item) {
|
||||||
|
if (!item) return;
|
||||||
|
this.detail.grey_fabric_level_id = [Number(item.value)];
|
||||||
|
this.detail.grey_fabric_level_name = item.label || '';
|
||||||
|
},
|
||||||
|
async loadInspectorOptions() {
|
||||||
|
try {
|
||||||
|
const res = await this.$u.api.employee.listEnum({
|
||||||
|
size: 50,
|
||||||
|
duty: INSPECTOR_DUTY,
|
||||||
|
});
|
||||||
|
const list = Array.isArray(res) ? res : (Array.isArray(res && res.list) ? res.list : []);
|
||||||
|
this.inspectorOptions = list
|
||||||
|
.map((item) => ({
|
||||||
|
value: item.id,
|
||||||
|
label: item.name || item.employee_name || item.real_name || item.code || String(item.id),
|
||||||
|
}))
|
||||||
|
.filter((item) => item.value != null);
|
||||||
|
this.inspectorOptionsLoaded = true;
|
||||||
|
} catch (error) {
|
||||||
|
console.log('加载查布工枚举失败', error);
|
||||||
|
this.inspectorOptions = [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async openInspectorPicker() {
|
||||||
|
if (!this.inspectorOptionsLoaded || !this.inspectorOptions.length) {
|
||||||
|
await this.loadInspectorOptions();
|
||||||
|
}
|
||||||
|
if (!this.inspectorOptions.length) {
|
||||||
|
this.$u.toast('暂无查布工可选');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.inspectorPickerShow = true;
|
||||||
|
},
|
||||||
|
onInspectorConfirm(item) {
|
||||||
|
if (!item) return;
|
||||||
|
this.detail.inspector_id = Number(item.value);
|
||||||
|
this.detail.inspector_name = item.label || '';
|
||||||
|
},
|
||||||
|
handleScanCode(scanResult) {
|
||||||
|
const code = String(scanResult || '').trim().replace(/[\r\n]/g, '');
|
||||||
|
if (!code) return;
|
||||||
|
this.fetchScanDetail(code);
|
||||||
|
},
|
||||||
|
onScanConfirm() {
|
||||||
|
const code = String(this.scanCode || '').trim();
|
||||||
|
if (!code) {
|
||||||
|
this.$u.toast('请扫描或输入布票编码');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.fetchScanDetail(code);
|
||||||
|
},
|
||||||
|
async fetchScanDetail(code) {
|
||||||
|
if (this.loadingDetail) return;
|
||||||
|
this.loadingDetail = true;
|
||||||
|
this.scanCode = code;
|
||||||
|
try {
|
||||||
|
const res = await this.$u.api.productionScheduleOrder.getScanFineCodeDetail({
|
||||||
|
fabric_piece_code: code,
|
||||||
|
});
|
||||||
|
this.applyScanDetail(res, code);
|
||||||
|
} catch (error) {
|
||||||
|
console.log('扫码获取细码失败', error);
|
||||||
|
this.detail = {
|
||||||
|
...emptyDetail(),
|
||||||
|
fabric_piece_code: code,
|
||||||
|
};
|
||||||
|
this.weightKg = '';
|
||||||
|
} finally {
|
||||||
|
this.loadingDetail = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
applyScanDetail(res, fallbackCode) {
|
||||||
|
const data = res || {};
|
||||||
|
const levelIds = normalizeLevelIds(data.grey_fabric_level_id);
|
||||||
|
this.detail = {
|
||||||
|
...emptyDetail(),
|
||||||
|
fabric_piece_code: data.fabric_piece_code || fallbackCode || '',
|
||||||
|
production_order_no: data.production_order_no || '',
|
||||||
|
machine_number: data.machine_number || '',
|
||||||
|
grey_fabric_name: data.grey_fabric_name || '',
|
||||||
|
grey_fabric_code: data.grey_fabric_code || '',
|
||||||
|
inspection_weight: formatDisplayWeightKg(data.inspection_weight) ? data.inspection_weight : null,
|
||||||
|
grey_fabric_level_id: levelIds,
|
||||||
|
grey_fabric_level_name: data.grey_fabric_level_name || '',
|
||||||
|
inspector_id: data.inspector_id != null ? data.inspector_id : null,
|
||||||
|
inspector_name: data.inspector_name || '',
|
||||||
|
};
|
||||||
|
this.weightKg = formatDisplayWeightKg(data.inspection_weight);
|
||||||
|
this.scanCode = this.detail.fabric_piece_code;
|
||||||
|
util.playSpeak('扫码成功');
|
||||||
|
},
|
||||||
|
async submitInWarehouse() {
|
||||||
|
const fabricPieceCode = String(this.detail.fabric_piece_code || this.scanCode || '').trim();
|
||||||
|
if (!fabricPieceCode) {
|
||||||
|
this.$u.toast('请先扫描或输入布票编码');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const actualWeight = toWeightInt(this.weightKg);
|
||||||
|
if (actualWeight == null) {
|
||||||
|
this.$u.toast('请输入有效重量');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const levelIds = normalizeLevelIds(this.detail.grey_fabric_level_id);
|
||||||
|
if (!levelIds.length) {
|
||||||
|
this.$u.toast('请选择等级');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.submitting) return;
|
||||||
|
this.submitting = true;
|
||||||
|
try {
|
||||||
|
const payload = {
|
||||||
|
fabric_piece_code: fabricPieceCode,
|
||||||
|
actual_weight: actualWeight,
|
||||||
|
electronic_scale_weight: actualWeight,
|
||||||
|
grey_fabric_level_id: levelIds,
|
||||||
|
};
|
||||||
|
const inspectorName = String(this.detail.inspector_name || '').trim();
|
||||||
|
if (inspectorName) {
|
||||||
|
payload.inspector_name = inspectorName;
|
||||||
|
}
|
||||||
|
if (this.detail.inspector_id != null && this.detail.inspector_id !== '') {
|
||||||
|
payload.inspector_id = Number(this.detail.inspector_id);
|
||||||
|
}
|
||||||
|
const binName = String(this.warehouseBinName || '').trim();
|
||||||
|
if (binName && binName !== '/') {
|
||||||
|
payload.warehouse_bin_name = binName;
|
||||||
|
}
|
||||||
|
if (this.warehouseBinId != null && this.warehouseBinId !== '') {
|
||||||
|
payload.warehouse_bin_id = Number(this.warehouseBinId);
|
||||||
|
}
|
||||||
|
const res = await this.$u.api.productionScheduleOrder.scanInWarehouseFineCode(payload);
|
||||||
|
if (res) {
|
||||||
|
this.detail.volume_number = res.volume_number != null ? res.volume_number : this.detail.volume_number;
|
||||||
|
this.detail.grey_fabric_id = res.grey_fabric_id != null ? res.grey_fabric_id : this.detail.grey_fabric_id;
|
||||||
|
this.detail.id = res.id != null ? res.id : this.detail.id;
|
||||||
|
if (res.fabric_piece_code) {
|
||||||
|
this.detail.fabric_piece_code = res.fabric_piece_code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const volumeText = res && res.volume_number != null ? `,卷号 ${res.volume_number}` : '';
|
||||||
|
util.playSpeak('进仓成功');
|
||||||
|
this.$u.toast(`进仓成功${volumeText}`);
|
||||||
|
this.resetForNextScan();
|
||||||
|
} catch (error) {
|
||||||
|
console.log('手动进仓失败', error);
|
||||||
|
} finally {
|
||||||
|
this.submitting = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resetForNextScan() {
|
||||||
|
this.scanCode = '';
|
||||||
|
this.detail = emptyDetail();
|
||||||
|
this.weightKg = '';
|
||||||
|
this.warehouseBinId = null;
|
||||||
|
this.warehouseBinName = '';
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.scanFocus = false;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.scanFocus = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/common/pda-typography.scss';
|
||||||
|
|
||||||
|
.manual-in {
|
||||||
|
min-height: 100vh;
|
||||||
|
background: #f5f6f8;
|
||||||
|
padding-bottom: 180rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-in__setting {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8rpx;
|
||||||
|
font-size: $pda-font-nav-sub;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-in__scan {
|
||||||
|
margin: 16rpx 0;
|
||||||
|
padding: 0 28rpx;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-in__scan-input {
|
||||||
|
height: $pda-scan-input-height;
|
||||||
|
font-size: $pda-font-body;
|
||||||
|
color: #202328;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-in__placeholder {
|
||||||
|
color: #b0b4bb;
|
||||||
|
font-size: $pda-font-placeholder;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-in__panel {
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-in__row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
min-height: $pda-row-min-height;
|
||||||
|
padding: 12rpx 28rpx;
|
||||||
|
border-bottom: 1rpx solid #eceff3;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-in__row--input {
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-in__label {
|
||||||
|
width: $pda-label-width;
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-size: $pda-font-body;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-in__value {
|
||||||
|
flex: 1;
|
||||||
|
font-size: $pda-font-body;
|
||||||
|
color: #202328;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-in__right {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 18rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-in__field {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
text-align: right;
|
||||||
|
font-size: $pda-font-body;
|
||||||
|
color: #202328;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-in__field-text {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
text-align: right;
|
||||||
|
font-size: $pda-font-body;
|
||||||
|
color: #202328;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-in__unit {
|
||||||
|
font-size: $pda-font-unit;
|
||||||
|
color: #666;
|
||||||
|
padding: 6rpx 14rpx;
|
||||||
|
border: 1rpx solid #d7dbe3;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-in__action {
|
||||||
|
font-size: $pda-font-action;
|
||||||
|
color: #2f78e6;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-in__footer {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
padding: 24rpx 40rpx calc(24rpx + env(safe-area-inset-bottom));
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 -4rpx 16rpx rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .manual-in__footer .u-btn {
|
||||||
|
height: $pda-button-height !important;
|
||||||
|
line-height: $pda-button-height !important;
|
||||||
|
font-size: $pda-font-button !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,260 @@
|
|||||||
|
<template>
|
||||||
|
<view class="warehouse-detail-page">
|
||||||
|
<view class="infoCard">
|
||||||
|
<view class="infoTitle">坯布资料</view>
|
||||||
|
<view class="infoRow">
|
||||||
|
<text class="infoLabel">坯布编号</text>
|
||||||
|
<text class="infoValue">{{ header.grey_fabric_code || '-' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="infoRow">
|
||||||
|
<text class="infoLabel">坯布名称</text>
|
||||||
|
<text class="infoValue">{{ header.grey_fabric_name || '-' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="infoRow">
|
||||||
|
<text class="infoLabel">颜 色</text>
|
||||||
|
<text class="infoValue">{{ header.gray_fabric_color_name || '-' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="infoRow">
|
||||||
|
<text class="infoLabel">织 厂</text>
|
||||||
|
<text class="infoValue">{{ header.supplier_name || '-' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="infoRow">
|
||||||
|
<text class="infoLabel">机 台 号</text>
|
||||||
|
<text class="infoValue">{{ header.machine_number || '-' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="infoRow">
|
||||||
|
<text class="infoLabel">纱 批</text>
|
||||||
|
<text class="infoValue">{{ header.yarn_batch || '-' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="infoRow">
|
||||||
|
<text class="infoLabel">仓 库</text>
|
||||||
|
<text class="infoValue">{{ header.warehouse_name || '-' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="infoRow">
|
||||||
|
<text class="infoLabel">汇总库存</text>
|
||||||
|
<text class="infoValue">{{ header.stock_roll || '-' }} 匹 / {{ header.stock_weight || '-' }} KG</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="summaryBar">
|
||||||
|
<text>细码:{{ totals.count }} 条 / {{ totals.roll }} 匹 / {{ totals.weight }} KG</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<scroll-view
|
||||||
|
scroll-y
|
||||||
|
:style="{ height: scrollHeight }"
|
||||||
|
refresher-enabled
|
||||||
|
:refresher-triggered="triggered"
|
||||||
|
@refresherrefresh="onRefresh"
|
||||||
|
>
|
||||||
|
<dataNull
|
||||||
|
v-if="tableRows.length === 0"
|
||||||
|
src="/src/static/img/chahua/gjNull.png"
|
||||||
|
title="暂无细码明细"
|
||||||
|
title1="请返回上一级调整筛选条件"
|
||||||
|
/>
|
||||||
|
<scroll-view v-else scroll-x class="tableScroll">
|
||||||
|
<view class="fineTable" :style="{ width: tableWidth }">
|
||||||
|
<view class="tableRow tableHead">
|
||||||
|
<view
|
||||||
|
v-for="col in columns"
|
||||||
|
:key="col.key"
|
||||||
|
class="tableCell headCell"
|
||||||
|
:style="cellStyle(col)"
|
||||||
|
>{{ col.label }}</view>
|
||||||
|
</view>
|
||||||
|
<view v-for="(row, rowIndex) in tableRows" :key="rowIndex" class="tableRow">
|
||||||
|
<view
|
||||||
|
v-for="col in columns"
|
||||||
|
:key="col.key"
|
||||||
|
class="tableCell"
|
||||||
|
:style="cellStyle(col)"
|
||||||
|
>{{ row[col.key] }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
WAREHOUSE_DETAIL_COLUMNS,
|
||||||
|
buildDetailQuery,
|
||||||
|
fetchAllWarehouseList,
|
||||||
|
getWarehouseDetailTableWidth,
|
||||||
|
mapWarehouseDetailRows,
|
||||||
|
parsePageQuery,
|
||||||
|
sumDetailTotals,
|
||||||
|
} from '@/common/storeFabricWarehouse';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
rawList: [],
|
||||||
|
scrollHeight: '667px',
|
||||||
|
triggered: false,
|
||||||
|
columns: WAREHOUSE_DETAIL_COLUMNS,
|
||||||
|
header: {
|
||||||
|
grey_fabric_id: '',
|
||||||
|
grey_fabric_code: '',
|
||||||
|
grey_fabric_name: '',
|
||||||
|
gray_fabric_color_name: '',
|
||||||
|
supplier_name: '',
|
||||||
|
machine_number: '',
|
||||||
|
yarn_batch: '',
|
||||||
|
warehouse_name: '',
|
||||||
|
stock_roll: '',
|
||||||
|
stock_weight: '',
|
||||||
|
},
|
||||||
|
queryParams: {},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
tableRows() {
|
||||||
|
return mapWarehouseDetailRows(this.rawList);
|
||||||
|
},
|
||||||
|
tableWidth() {
|
||||||
|
return getWarehouseDetailTableWidth(this.columns);
|
||||||
|
},
|
||||||
|
totals() {
|
||||||
|
return sumDetailTotals(this.rawList);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onLoad(options) {
|
||||||
|
const parsed = parsePageQuery(options || {});
|
||||||
|
this.header = {
|
||||||
|
grey_fabric_id: parsed.grey_fabric_id || '',
|
||||||
|
grey_fabric_code: parsed.grey_fabric_code || '',
|
||||||
|
grey_fabric_name: parsed.grey_fabric_name || '',
|
||||||
|
gray_fabric_color_name: parsed.gray_fabric_color_name || '',
|
||||||
|
supplier_name: parsed.supplier_name || '',
|
||||||
|
machine_number: parsed.machine_number || '',
|
||||||
|
yarn_batch: parsed.yarn_batch || '',
|
||||||
|
warehouse_name: parsed.warehouse_name || '',
|
||||||
|
stock_roll: parsed.stock_roll || '',
|
||||||
|
stock_weight: parsed.stock_weight || '',
|
||||||
|
};
|
||||||
|
this.queryParams = buildDetailQuery(parsed, parsed);
|
||||||
|
uni.setNavigationBarTitle({ title: '细码明细' });
|
||||||
|
uni.getSystemInfo({
|
||||||
|
success: (res) => {
|
||||||
|
this.scrollHeight = `${res.windowHeight - 360}px`;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!this.queryParams.grey_fabric_id) {
|
||||||
|
uni.showToast({ title: '缺少坯布参数', icon: 'none' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.loadList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
cellStyle(col) {
|
||||||
|
return {
|
||||||
|
width: `${col.width}rpx`,
|
||||||
|
minWidth: `${col.width}rpx`,
|
||||||
|
maxWidth: `${col.width}rpx`,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
loadList() {
|
||||||
|
fetchAllWarehouseList((p) => this.$u.api.gfmWarehouse.detailList(p), this.queryParams)
|
||||||
|
.then((rows) => {
|
||||||
|
this.triggered = false;
|
||||||
|
this.rawList = rows || [];
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
this.triggered = false;
|
||||||
|
this.rawList = [];
|
||||||
|
uni.showToast({ title: err.message || '加载失败', icon: 'none' });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onRefresh() {
|
||||||
|
this.triggered = true;
|
||||||
|
this.loadList();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
page { background-color: #F8F8F8; }
|
||||||
|
.warehouse-detail-page { min-height: 100%; padding-bottom: 24rpx; }
|
||||||
|
.infoCard {
|
||||||
|
margin: 20rpx 24rpx 0;
|
||||||
|
padding: 20rpx 24rpx;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
}
|
||||||
|
.infoTitle {
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.infoRow {
|
||||||
|
display: flex;
|
||||||
|
font-size: 26rpx;
|
||||||
|
padding: 8rpx 0;
|
||||||
|
}
|
||||||
|
.infoLabel {
|
||||||
|
width: 160rpx;
|
||||||
|
color: #999;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.infoValue {
|
||||||
|
flex: 1;
|
||||||
|
color: #333;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
.summaryBar {
|
||||||
|
margin: 16rpx 24rpx 0;
|
||||||
|
padding: 12rpx 16rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
.tableScroll {
|
||||||
|
width: 100%;
|
||||||
|
margin: 16rpx 24rpx 0;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.fineTable {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
border: 1rpx solid #e1e1e1;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.tableRow {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
border-bottom: 1rpx solid #e1e1e1;
|
||||||
|
}
|
||||||
|
.tableRow:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
.tableHead {
|
||||||
|
background: #f1f1f1;
|
||||||
|
}
|
||||||
|
.tableCell {
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding: 12rpx 8rpx;
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #333;
|
||||||
|
text-align: center;
|
||||||
|
border-right: 1rpx solid #e1e1e1;
|
||||||
|
box-sizing: border-box;
|
||||||
|
word-break: break-all;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
.tableCell:last-child {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
.headCell {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #3e3e3e;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
<template>
|
||||||
|
<view class="warehouse-page">
|
||||||
|
<view class="filterBar">
|
||||||
|
<u-search
|
||||||
|
v-model="filters.grey_fabric_code"
|
||||||
|
placeholder="坯布编号"
|
||||||
|
shape="square"
|
||||||
|
:show-action="false"
|
||||||
|
height="64"
|
||||||
|
@search="loadList"
|
||||||
|
@custom="loadList"
|
||||||
|
/>
|
||||||
|
<u-search
|
||||||
|
v-model="filters.grey_fabric_name"
|
||||||
|
placeholder="坯布名称"
|
||||||
|
shape="square"
|
||||||
|
:show-action="false"
|
||||||
|
height="64"
|
||||||
|
@search="loadList"
|
||||||
|
@custom="loadList"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="summaryBar">
|
||||||
|
<text>合计:{{ totals.roll }} 匹 / {{ totals.weight }} KG({{ totals.count }} 条)</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<scroll-view
|
||||||
|
scroll-y
|
||||||
|
:style="{ height: scrollHeight }"
|
||||||
|
refresher-enabled
|
||||||
|
:refresher-triggered="triggered"
|
||||||
|
@refresherrefresh="onRefresh"
|
||||||
|
>
|
||||||
|
<dataNull
|
||||||
|
v-if="!loading && tableContents.length === 0"
|
||||||
|
src="/src/static/img/chahua/gjNull.png"
|
||||||
|
title="暂无库存汇总"
|
||||||
|
title1="请输入坯布编号或名称查询"
|
||||||
|
/>
|
||||||
|
<view v-else-if="tableContents.length" class="tableBox">
|
||||||
|
<WarehouseDataTable
|
||||||
|
:headers="tableHeaders"
|
||||||
|
:contents="tableContents"
|
||||||
|
height="auto"
|
||||||
|
@row-click="goStockList"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import WarehouseDataTable from '@/components/storefabric/WarehouseDataTable.vue';
|
||||||
|
import {
|
||||||
|
GROUP_TABLE_COLUMNS,
|
||||||
|
buildGroupListQuery,
|
||||||
|
buildStockListNavigateQuery,
|
||||||
|
fetchAllWarehouseList,
|
||||||
|
mapGroupTableRow,
|
||||||
|
sumStockTotals,
|
||||||
|
toQueryString,
|
||||||
|
} from '@/common/storeFabricWarehouse';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { WarehouseDataTable },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
list: [],
|
||||||
|
scrollHeight: '667px',
|
||||||
|
triggered: false,
|
||||||
|
loading: false,
|
||||||
|
tableHeaders: GROUP_TABLE_COLUMNS,
|
||||||
|
filters: {
|
||||||
|
grey_fabric_code: '',
|
||||||
|
grey_fabric_name: '',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
tableContents() {
|
||||||
|
return this.list.map(mapGroupTableRow);
|
||||||
|
},
|
||||||
|
totals() {
|
||||||
|
return sumStockTotals(this.list);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onLoad() {
|
||||||
|
uni.setNavigationBarTitle({ title: '坯布库存' });
|
||||||
|
uni.getSystemInfo({
|
||||||
|
success: (res) => {
|
||||||
|
this.scrollHeight = `${res.windowHeight - 108}px`;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
this.loadList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
loadList() {
|
||||||
|
if (this.loading) return;
|
||||||
|
this.loading = true;
|
||||||
|
const params = buildGroupListQuery(this.filters);
|
||||||
|
fetchAllWarehouseList((p) => this.$u.api.gfmWarehouse.groupSummaryList(p), params)
|
||||||
|
.then((rows) => {
|
||||||
|
this.triggered = false;
|
||||||
|
this.list = rows || [];
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
this.triggered = false;
|
||||||
|
this.list = [];
|
||||||
|
uni.showToast({ title: err.message || '加载失败', icon: 'none' });
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onRefresh() {
|
||||||
|
this.triggered = true;
|
||||||
|
this.loadList();
|
||||||
|
},
|
||||||
|
goStockList(row) {
|
||||||
|
const query = buildStockListNavigateQuery(row);
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `./storeFabricWarehouseStockList?${toQueryString(query)}`,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
page { background-color: #F8F8F8; }
|
||||||
|
.warehouse-page { min-height: 100%; }
|
||||||
|
.filterBar {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8rpx;
|
||||||
|
padding: 12rpx 20rpx;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.summaryBar {
|
||||||
|
padding: 10rpx 24rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #666;
|
||||||
|
background: #fff;
|
||||||
|
border-top: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
.tableBox {
|
||||||
|
padding: 12rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,153 @@
|
|||||||
|
<template>
|
||||||
|
<view class="warehouse-page">
|
||||||
|
<view class="fabricHeader">
|
||||||
|
<view class="fabricCode">{{ context.grey_fabric_code || '-' }}</view>
|
||||||
|
<view class="fabricName">{{ context.grey_fabric_name || '-' }}</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="filterBar">
|
||||||
|
<u-search
|
||||||
|
v-model="filters.machine_number"
|
||||||
|
placeholder="机台号"
|
||||||
|
:show-action="false"
|
||||||
|
@search="loadList"
|
||||||
|
@custom="loadList"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="summaryBar">
|
||||||
|
<text>合计:{{ totals.roll }} 匹 / {{ totals.weight }} KG({{ totals.count }} 条)</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<scroll-view
|
||||||
|
scroll-y
|
||||||
|
:style="{ height: scrollHeight }"
|
||||||
|
refresher-enabled
|
||||||
|
:refresher-triggered="triggered"
|
||||||
|
@refresherrefresh="onRefresh"
|
||||||
|
>
|
||||||
|
<dataNull
|
||||||
|
v-if="tableContents.length === 0"
|
||||||
|
src="/src/static/img/chahua/gjNull.png"
|
||||||
|
title="暂无维度汇总"
|
||||||
|
title1="请调整机台号筛选后重试"
|
||||||
|
/>
|
||||||
|
<view v-else class="tableBox">
|
||||||
|
<WarehouseDataTable
|
||||||
|
:headers="tableHeaders"
|
||||||
|
:contents="tableContents"
|
||||||
|
height="auto"
|
||||||
|
@row-click="goDetail"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import WarehouseDataTable from '@/components/storefabric/WarehouseDataTable.vue';
|
||||||
|
import {
|
||||||
|
STOCK_TABLE_COLUMNS,
|
||||||
|
buildDetailNavigateQuery,
|
||||||
|
buildStockListQuery,
|
||||||
|
fetchAllWarehouseList,
|
||||||
|
mapStockTableRow,
|
||||||
|
parsePageQuery,
|
||||||
|
sumStockTotals,
|
||||||
|
toQueryString,
|
||||||
|
} from '@/common/storeFabricWarehouse';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { WarehouseDataTable },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
list: [],
|
||||||
|
scrollHeight: '667px',
|
||||||
|
triggered: false,
|
||||||
|
tableHeaders: STOCK_TABLE_COLUMNS,
|
||||||
|
context: {
|
||||||
|
grey_fabric_id: '',
|
||||||
|
grey_fabric_code: '',
|
||||||
|
grey_fabric_name: '',
|
||||||
|
warehouse_id: '',
|
||||||
|
},
|
||||||
|
filters: {
|
||||||
|
machine_number: '',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
tableContents() {
|
||||||
|
return this.list.map(mapStockTableRow);
|
||||||
|
},
|
||||||
|
totals() {
|
||||||
|
return sumStockTotals(this.list);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onLoad(options) {
|
||||||
|
const parsed = parsePageQuery(options || {});
|
||||||
|
this.context = {
|
||||||
|
grey_fabric_id: parsed.grey_fabric_id || '',
|
||||||
|
grey_fabric_code: parsed.grey_fabric_code || '',
|
||||||
|
grey_fabric_name: parsed.grey_fabric_name || '',
|
||||||
|
warehouse_id: parsed.warehouse_id || '',
|
||||||
|
};
|
||||||
|
const title = this.context.grey_fabric_name
|
||||||
|
? `${this.context.grey_fabric_name} 库存汇总`
|
||||||
|
: '坯布库存汇总';
|
||||||
|
uni.setNavigationBarTitle({ title });
|
||||||
|
uni.getSystemInfo({
|
||||||
|
success: (res) => {
|
||||||
|
this.scrollHeight = `${res.windowHeight - 120}px`;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!this.context.grey_fabric_id) {
|
||||||
|
uni.showToast({ title: '缺少坯布参数', icon: 'none' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.loadList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
loadList() {
|
||||||
|
const params = buildStockListQuery(this.filters, this.context);
|
||||||
|
fetchAllWarehouseList((p) => this.$u.api.gfmWarehouse.stockSummaryList(p), params)
|
||||||
|
.then((rows) => {
|
||||||
|
this.triggered = false;
|
||||||
|
this.list = rows || [];
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
this.triggered = false;
|
||||||
|
this.list = [];
|
||||||
|
uni.showToast({ title: err.message || '加载失败', icon: 'none' });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onRefresh() {
|
||||||
|
this.triggered = true;
|
||||||
|
this.loadList();
|
||||||
|
},
|
||||||
|
goDetail(row) {
|
||||||
|
const query = buildDetailNavigateQuery(row, this.context);
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `./storeFabricWarehouseDetail?${toQueryString(query)}`,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
page { background-color: #F8F8F8; }
|
||||||
|
.warehouse-page { min-height: 100%; }
|
||||||
|
.fabricHeader { padding: 20rpx 24rpx; background: #fff; border-bottom: 1rpx solid #f0f0f0; }
|
||||||
|
.fabricCode { font-size: 30rpx; font-weight: bold; color: #333; }
|
||||||
|
.fabricName { margin-top: 8rpx; font-size: 26rpx; color: #666; }
|
||||||
|
.filterBar { padding: 16rpx 20rpx; background: #fff; }
|
||||||
|
.summaryBar {
|
||||||
|
padding: 12rpx 24rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
background: #fff;
|
||||||
|
border-top: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
.tableBox { padding: 16rpx 12rpx; }
|
||||||
|
</style>
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -31,6 +31,14 @@
|
|||||||
</view>
|
</view>
|
||||||
<u-form-item label-width="150" label="条码资料:">
|
<u-form-item label-width="150" label="条码资料:">
|
||||||
<input type="text" maxlength="-1" v-model="QRBarCode" style="width:200px;" @confirm="GoodsCheckBillDetailScan" />
|
<input type="text" maxlength="-1" v-model="QRBarCode" style="width:200px;" @confirm="GoodsCheckBillDetailScan" />
|
||||||
|
<u-icon
|
||||||
|
v-if="usePhoneScanFallback"
|
||||||
|
name="scan"
|
||||||
|
size="44"
|
||||||
|
color="#2979ff"
|
||||||
|
style="margin-left: 8px;"
|
||||||
|
@click="handlePhoneScan"
|
||||||
|
/>
|
||||||
<checkbox-group @change="BarCodeDelChange">
|
<checkbox-group @change="BarCodeDelChange">
|
||||||
<checkbox ref="checkBoxRef" :checked="BarCodeDelStatus">删除</checkbox>
|
<checkbox ref="checkBoxRef" :checked="BarCodeDelStatus">删除</checkbox>
|
||||||
</checkbox-group>
|
</checkbox-group>
|
||||||
@@ -193,28 +201,20 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
onUnload() {
|
onUnload() {
|
||||||
// #ifdef APP-PLUS
|
|
||||||
this.isPageActive = false;
|
this.isPageActive = false;
|
||||||
this.unregisterScanBroadcast();
|
this.unregisterScanBroadcast();
|
||||||
// #endif
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onHide() {
|
onHide() {
|
||||||
// 页面隐藏时
|
|
||||||
this.isPageActive = false;
|
this.isPageActive = false;
|
||||||
// #ifdef APP-PLUS
|
|
||||||
this.unregisterScanBroadcast();
|
this.unregisterScanBroadcast();
|
||||||
// #endif
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onShow() {
|
onShow() {
|
||||||
// 页面显示时
|
|
||||||
this.isPageActive = true;
|
this.isPageActive = true;
|
||||||
// #ifdef APP-PLUS
|
|
||||||
this.registerScanBroadcast((scanResult) => {
|
this.registerScanBroadcast((scanResult) => {
|
||||||
console.log("扫码结果:", scanResult);
|
console.log("扫码结果:", scanResult);
|
||||||
|
|
||||||
// 处理扫描结果,按照原有逻辑
|
|
||||||
if(!this.StoreName){
|
if(!this.StoreName){
|
||||||
this.showError('请先选择仓库');
|
this.showError('请先选择仓库');
|
||||||
return;
|
return;
|
||||||
@@ -240,9 +240,11 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// #endif
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
handlePhoneScan() {
|
||||||
|
this.openPhoneScan();
|
||||||
|
},
|
||||||
|
|
||||||
// 添加通用错误提示方法
|
// 添加通用错误提示方法
|
||||||
showError(message) {
|
showError(message) {
|
||||||
|
|||||||
@@ -12,6 +12,14 @@
|
|||||||
<u-form-item label-width="150" label="条码资料:">
|
<u-form-item label-width="150" label="条码资料:">
|
||||||
<input type="text" v-model="QRBarCode" maxlength="-1" style="width:200px;"
|
<input type="text" v-model="QRBarCode" maxlength="-1" style="width:200px;"
|
||||||
@confirm="GoodsCheckBillDetailScan" />
|
@confirm="GoodsCheckBillDetailScan" />
|
||||||
|
<u-icon
|
||||||
|
v-if="usePhoneScanFallback"
|
||||||
|
name="scan"
|
||||||
|
size="44"
|
||||||
|
color="#2979ff"
|
||||||
|
style="margin-left: 8px;"
|
||||||
|
@click="handlePhoneScan"
|
||||||
|
/>
|
||||||
<checkbox-group @change="BarCodeDelChange">
|
<checkbox-group @change="BarCodeDelChange">
|
||||||
<checkbox ref="checkBoxRef" :checked="BarCodeDelStatus">删除</checkbox>
|
<checkbox ref="checkBoxRef" :checked="BarCodeDelStatus">删除</checkbox>
|
||||||
</checkbox-group>
|
</checkbox-group>
|
||||||
@@ -147,36 +155,30 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
onShow() {
|
onShow() {
|
||||||
// 设置页面激活状态
|
|
||||||
this.isPageActive = true;
|
this.isPageActive = true;
|
||||||
|
|
||||||
// #ifdef APP-PLUS
|
|
||||||
this.registerScanBroadcast((scanResult) => {
|
this.registerScanBroadcast((scanResult) => {
|
||||||
console.log("扫码结果:", scanResult);
|
console.log("扫码结果:", scanResult);
|
||||||
|
|
||||||
// 处理扫描结果
|
|
||||||
this.QRBarCode = scanResult;
|
this.QRBarCode = scanResult;
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.GoodsCheckBillDetailScan();
|
this.GoodsCheckBillDetailScan();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// #endif
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onHide() {
|
onHide() {
|
||||||
this.isPageActive = false;
|
this.isPageActive = false;
|
||||||
// #ifdef APP-PLUS
|
|
||||||
this.unregisterScanBroadcast();
|
this.unregisterScanBroadcast();
|
||||||
// #endif
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onUnload() {
|
onUnload() {
|
||||||
this.isPageActive = false;
|
this.isPageActive = false;
|
||||||
// #ifdef APP-PLUS
|
|
||||||
this.unregisterScanBroadcast();
|
this.unregisterScanBroadcast();
|
||||||
// #endif
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
handlePhoneScan() {
|
||||||
|
this.openPhoneScan();
|
||||||
|
},
|
||||||
|
|
||||||
// 添加通用错误提示方法
|
// 添加通用错误提示方法
|
||||||
showError(message) {
|
showError(message) {
|
||||||
this.playError();
|
this.playError();
|
||||||
|
|||||||
@@ -26,6 +26,14 @@
|
|||||||
<u-form-item label-width="150" label="条码资料:" :class="{ 'input-highlight': shouldHighlightQR }">
|
<u-form-item label-width="150" label="条码资料:" :class="{ 'input-highlight': shouldHighlightQR }">
|
||||||
<input type="text" v-model="QRBarCode" maxlength="-1" style="width:150px;"
|
<input type="text" v-model="QRBarCode" maxlength="-1" style="width:150px;"
|
||||||
@confirm="GoodsStoreStationMoveScan" />
|
@confirm="GoodsStoreStationMoveScan" />
|
||||||
|
<u-icon
|
||||||
|
v-if="usePhoneScanFallback"
|
||||||
|
name="scan"
|
||||||
|
size="44"
|
||||||
|
color="#2979ff"
|
||||||
|
style="margin-left: 8px;"
|
||||||
|
@click="handlePhoneScan"
|
||||||
|
/>
|
||||||
</u-form-item>
|
</u-form-item>
|
||||||
<u-form-item>
|
<u-form-item>
|
||||||
<text class="title">{{ BillDataMessage }}</text>
|
<text class="title">{{ BillDataMessage }}</text>
|
||||||
@@ -150,10 +158,8 @@ export default {
|
|||||||
this.StoreNameID = getApp().globalData.StoreNameID;
|
this.StoreNameID = getApp().globalData.StoreNameID;
|
||||||
this.StoreName = getApp().globalData.StoreName;
|
this.StoreName = getApp().globalData.StoreName;
|
||||||
};
|
};
|
||||||
// #ifdef APP-PLUS
|
|
||||||
// 使用 scanMixin 的方法注册扫码广播,传入自定义回调
|
// 使用 scanMixin 的方法注册扫码广播,传入自定义回调
|
||||||
this.registerScanBroadcast(this.handleScanCode);
|
this.registerScanBroadcast(this.handleScanCode);
|
||||||
// #endif
|
|
||||||
},
|
},
|
||||||
// onUnload, onHide, onShow 已由 scanMixin 自动处理
|
// onUnload, onHide, onShow 已由 scanMixin 自动处理
|
||||||
/* onBackPress() {
|
/* onBackPress() {
|
||||||
@@ -174,6 +180,10 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
handlePhoneScan() {
|
||||||
|
this.openPhoneScan();
|
||||||
|
},
|
||||||
|
|
||||||
playSuccess() {
|
playSuccess() {
|
||||||
util.playSuccessAudio();
|
util.playSuccessAudio();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,13 +8,12 @@
|
|||||||
<!-- <u-tabs :list="list" :is-scroll="false" :current="current" @change="onClickItem"></u-tabs> -->
|
<!-- <u-tabs :list="list" :is-scroll="false" :current="current" @change="onClickItem"></u-tabs> -->
|
||||||
<!-- <view v-if="current === 0"> -->
|
<!-- <view v-if="current === 0"> -->
|
||||||
<view class="list">
|
<view class="list">
|
||||||
<template v-if="isDevelopment">
|
<view class="list-call env-call">
|
||||||
<view class="list-call">
|
<view class="iconfont icon-link" style="font-size: 28px;color:#5473e8;"></view>
|
||||||
<view class="iconfont icon-link" style="font-size: 22px;color:#5473e8;"></view>
|
|
||||||
<view style="width: 100%;">
|
<view style="width: 100%;">
|
||||||
<view class="server-selector" @click="showServerPicker">
|
<view class="server-selector" @click="showServerPicker">
|
||||||
<text>{{ getApiUrlLabel() }}</text>
|
<text>{{ getApiUrlLabel() }}</text>
|
||||||
<view class="iconfont icon-arrow-down" style="font-size: 16px;"></view>
|
<view class="iconfont icon-arrow-down"></view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -23,7 +22,6 @@
|
|||||||
<input class="u-input" type="text" v-model="customApiUrl" maxlength="100" placeholder="请输入服务器地址"
|
<input class="u-input" type="text" v-model="customApiUrl" maxlength="100" placeholder="请输入服务器地址"
|
||||||
@blur="handleBlurInputUrl" />
|
@blur="handleBlurInputUrl" />
|
||||||
</view>
|
</view>
|
||||||
</template>
|
|
||||||
<view class="list-call">
|
<view class="list-call">
|
||||||
<view class="iconfont icon-avatar" style="font-size: 22px;color:#5473e8;"></view>
|
<view class="iconfont icon-avatar" style="font-size: 22px;color:#5473e8;"></view>
|
||||||
<input class="u-input" type="text" v-model="login.username" maxlength="32"
|
<input class="u-input" type="text" v-model="login.username" maxlength="32"
|
||||||
@@ -105,7 +103,7 @@
|
|||||||
<!-- </view>-->
|
<!-- </view>-->
|
||||||
<!-- </view>-->
|
<!-- </view>-->
|
||||||
<!-- </div>-->
|
<!-- </div>-->
|
||||||
<u-picker v-model="showApiUrlPicker" mode="selector" :range="apiUrlList" range-key="label"
|
<u-picker class="login-env-picker" v-model="showApiUrlPicker" mode="selector" :range="apiUrlList" range-key="label"
|
||||||
@confirm="onApiUrlConfirm" @cancel="showApiUrlPicker = false"></u-picker>
|
@confirm="onApiUrlConfirm" @cancel="showApiUrlPicker = false"></u-picker>
|
||||||
<!-- 版本信息显示 -->
|
<!-- 版本信息显示 -->
|
||||||
<view class="version-info">
|
<view class="version-info">
|
||||||
@@ -118,7 +116,7 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2013-Now http://aidex.vip All rights reserved.
|
* Copyright (c) 2013-Now http://aidex.vip All rights reserved.
|
||||||
*/
|
*/
|
||||||
import config from '@/common/config.js';
|
import config, { getTestApiUrl } from '@/common/config.js';
|
||||||
import base64 from '@/common/base64.js';
|
import base64 from '@/common/base64.js';
|
||||||
import util from '@/common/util.js';
|
import util from '@/common/util.js';
|
||||||
import md5 from '@/common/md5.js';
|
import md5 from '@/common/md5.js';
|
||||||
@@ -136,10 +134,9 @@ export default {
|
|||||||
password: ""
|
password: ""
|
||||||
},
|
},
|
||||||
showApiUrlPicker: false,
|
showApiUrlPicker: false,
|
||||||
// 根据环境设置默认URL和选项
|
selectedApiUrl: getTestApiUrl(),
|
||||||
selectedApiUrl: config.isDevelopment ? config.devApiUrlOptions[0].value : config.productionApiUrl,
|
customApiUrl: 'http://192.168.1.66:50002/hcscm_weave/pda/v1',
|
||||||
customApiUrl: 'http://192.168.1.66:50002/hcscm/pda/v1',
|
apiUrlList: config.devApiUrlOptions,
|
||||||
apiUrlList: config.isDevelopment ? config.devApiUrlOptions : [],
|
|
||||||
phoneNo: '',
|
phoneNo: '',
|
||||||
//username: '',
|
//username: '',
|
||||||
//password: '',
|
//password: '',
|
||||||
@@ -168,16 +165,9 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
onShow() {
|
onShow() {
|
||||||
// 只在开发环境读取存储的URL
|
const testUrl = getTestApiUrl();
|
||||||
if (config.isDevelopment) {
|
util.updateApiUrl(testUrl);
|
||||||
uni.getStorage({
|
this.selectedApiUrl = testUrl;
|
||||||
key: 'ApiUrl',
|
|
||||||
success: (e) => {
|
|
||||||
util.updateApiUrl(e.data);
|
|
||||||
this.selectedApiUrl = e.data;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
uni.getStorage({
|
uni.getStorage({
|
||||||
key: 'UserInfo',
|
key: 'UserInfo',
|
||||||
@@ -300,21 +290,12 @@ export default {
|
|||||||
title: '登录中...'
|
title: '登录中...'
|
||||||
});
|
});
|
||||||
|
|
||||||
let currentApiUrl;
|
const currentApiUrl = this.selectedApiUrl === 'custom' ? this.customApiUrl : this.selectedApiUrl;
|
||||||
|
|
||||||
if (config.isDevelopment) {
|
|
||||||
// 开发环境:使用选择的URL
|
|
||||||
currentApiUrl = this.selectedApiUrl === 'custom' ? this.customApiUrl : this.selectedApiUrl;
|
|
||||||
if (!currentApiUrl || currentApiUrl.length === 0) {
|
if (!currentApiUrl || currentApiUrl.length === 0) {
|
||||||
this.$u.toast('请输入服务器地址');
|
this.$u.toast('请输入服务器地址');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 更新store中的URL
|
|
||||||
this.$store.dispatch('updateApiUrl', currentApiUrl);
|
this.$store.dispatch('updateApiUrl', currentApiUrl);
|
||||||
} else {
|
|
||||||
// 生产环境:使用固定的生产URL
|
|
||||||
currentApiUrl = config.productionApiUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.login.username.length == 0) {
|
if (this.login.username.length == 0) {
|
||||||
this.$u.toast('请输入账号');
|
this.$u.toast('请输入账号');
|
||||||
@@ -339,14 +320,11 @@ export default {
|
|||||||
var aLoginUserData = res;
|
var aLoginUserData = res;
|
||||||
|
|
||||||
//console.log('--aLoginUserData->>' + JSON.stringify(aLoginUserData));
|
//console.log('--aLoginUserData->>' + JSON.stringify(aLoginUserData));
|
||||||
// 只在开发环境保存 apiurl 到本地存储
|
|
||||||
if (config.isDevelopment) {
|
|
||||||
uni.setStorage({
|
uni.setStorage({
|
||||||
key: 'ApiUrl',
|
key: 'ApiUrl',
|
||||||
data: currentApiUrl
|
data: currentApiUrl
|
||||||
});
|
});
|
||||||
util.updateApiUrl(currentApiUrl);
|
util.updateApiUrl(currentApiUrl);
|
||||||
}
|
|
||||||
// 保存 token 到本地存储
|
// 保存 token 到本地存储
|
||||||
uni.setStorageSync('RemoteTokenData', aLoginUserData);
|
uni.setStorageSync('RemoteTokenData', aLoginUserData);
|
||||||
|
|
||||||
@@ -456,19 +434,15 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleBlurInputUrl(e) {
|
handleBlurInputUrl(e) {
|
||||||
// 只在开发环境处理自定义URL
|
|
||||||
if (config.isDevelopment) {
|
|
||||||
const url = e.detail.value.trim();
|
const url = e.detail.value.trim();
|
||||||
if (url) {
|
if (url) {
|
||||||
this.customApiUrl = url;
|
this.customApiUrl = url;
|
||||||
// 保存到本地存储
|
|
||||||
uni.setStorage({
|
uni.setStorage({
|
||||||
key: 'ApiUrl',
|
key: 'ApiUrl',
|
||||||
data: url
|
data: url
|
||||||
});
|
});
|
||||||
util.updateApiUrl(url);
|
util.updateApiUrl(url);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -476,14 +450,25 @@ export default {
|
|||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import 'index.scss';
|
@import 'index.scss';
|
||||||
|
|
||||||
|
.env-call {
|
||||||
|
height: auto;
|
||||||
|
min-height: 140rpx;
|
||||||
|
}
|
||||||
|
|
||||||
.server-selector {
|
.server-selector {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 10rpx 0;
|
min-height: 80rpx;
|
||||||
|
padding: 16rpx 0;
|
||||||
|
font-size: 40rpx;
|
||||||
border-bottom: 1px solid #eee;
|
border-bottom: 1px solid #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.server-selector .icon-arrow-down {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
.list-call {
|
.list-call {
|
||||||
.u-select {
|
.u-select {
|
||||||
margin-bottom: 10rpx;
|
margin-bottom: 10rpx;
|
||||||
@@ -598,3 +583,23 @@ export default {
|
|||||||
margin-left: 10rpx;
|
margin-left: 10rpx;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.login-env-picker {
|
||||||
|
::v-deep .u-picker-header,
|
||||||
|
::v-deep .u-btn-picker {
|
||||||
|
height: 100rpx;
|
||||||
|
font-size: 36rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .u-picker-body {
|
||||||
|
height: 560rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .u-column-item,
|
||||||
|
::v-deep .u-line-1 {
|
||||||
|
height: 88rpx;
|
||||||
|
font-size: 40rpx;
|
||||||
|
line-height: 88rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -42,10 +42,12 @@
|
|||||||
<u-cell-item icon="question-circle" :iconStyle="{ color: '#ff8d06' }" title="常见问题" @click="navTo('problem')"></u-cell-item>
|
<u-cell-item icon="question-circle" :iconStyle="{ color: '#ff8d06' }" title="常见问题" @click="navTo('problem')"></u-cell-item>
|
||||||
<u-cell-item icon="kefu-ermai" :iconStyle="{ color: '#5f8dff' }" title="意见反馈" @click="navTo('comment')"></u-cell-item>
|
<u-cell-item icon="kefu-ermai" :iconStyle="{ color: '#5f8dff' }" title="意见反馈" @click="navTo('comment')"></u-cell-item>
|
||||||
<u-cell-item icon="map" :iconStyle="{ color: '#316ede' }" title="账号安全" @click="navTo('pwd')"></u-cell-item>
|
<u-cell-item icon="map" :iconStyle="{ color: '#316ede' }" title="账号安全" @click="navTo('pwd')"></u-cell-item>
|
||||||
|
<u-cell-item icon="scan" :iconStyle="{ color: '#36cfc9' }" title="扫描设置" @click="navTo('scan-settings')"></u-cell-item>
|
||||||
<u-cell-item icon="order" :iconStyle="{ color: '#59bdf9' }" title="清除缓存" @click="navTo('clear-cache')"></u-cell-item>
|
<u-cell-item icon="order" :iconStyle="{ color: '#59bdf9' }" title="清除缓存" @click="navTo('clear-cache')"></u-cell-item>
|
||||||
<!--<u-cell-item icon="account" :iconStyle="{ color: '#27c0dc' }" title="关于我们" @click="navTo('about')"></u-cell-item>
|
<!--<u-cell-item icon="account" :iconStyle="{ color: '#27c0dc' }" title="关于我们" @click="navTo('about')"></u-cell-item>
|
||||||
<u-cell-item icon="kefu-ermai" :iconStyle="{ color: '#ff8a00' }" title="联系客服" @click="navTo('service')"></u-cell-item>!-->
|
<u-cell-item icon="kefu-ermai" :iconStyle="{ color: '#ff8a00' }" title="联系客服" @click="navTo('service')"></u-cell-item>!-->
|
||||||
<u-gap height="20" bg-color="#f5f5f5"></u-gap>
|
<u-gap height="20" bg-color="#f5f5f5"></u-gap>
|
||||||
|
<u-cell-item icon="reload" :iconStyle="{ color: '#19be6b' }" title="版本更新" @click="upgrade"></u-cell-item>
|
||||||
<u-cell-item icon="setting" :iconStyle="{ color: '#2767dc' }" title="系统设置" @click="navTo('setting')"></u-cell-item>
|
<u-cell-item icon="setting" :iconStyle="{ color: '#2767dc' }" title="系统设置" @click="navTo('setting')"></u-cell-item>
|
||||||
</u-cell-group>
|
</u-cell-group>
|
||||||
</view>
|
</view>
|
||||||
@@ -54,6 +56,8 @@
|
|||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import CommonNavbar from "@/components/common-navbar/index";
|
import CommonNavbar from "@/components/common-navbar/index";
|
||||||
|
import app_upgrade from '@/uni_modules/app-upgrade/js_sdk/index.js';
|
||||||
|
import config from '@/common/config.js';
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2013-Now http://aidex.vip All rights reserved.
|
* Copyright (c) 2013-Now http://aidex.vip All rights reserved.
|
||||||
*/
|
*/
|
||||||
@@ -101,25 +105,29 @@ export default {
|
|||||||
},
|
},
|
||||||
upgrade(){
|
upgrade(){
|
||||||
// #ifdef APP-PLUS
|
// #ifdef APP-PLUS
|
||||||
this.$u.api.upgradeCheck().then(res => {
|
app_upgrade(async () => {
|
||||||
if (res.result == 'true'){
|
const appInfo = await new Promise((resolve) => {
|
||||||
uni.showModal({
|
plus.runtime.getProperty(plus.runtime.appid, (inf) => {
|
||||||
title: '提示',
|
resolve(inf);
|
||||||
content: res.message + '是否下载更新?',
|
|
||||||
showCancel: true,
|
|
||||||
success: function (res2) {
|
|
||||||
if (res2.confirm) {
|
|
||||||
plus.runtime.openURL(res.data.apkUrl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}else{
|
|
||||||
this.$u.toast(res.message);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
const res = await this.$u.api.upgradeCheck({
|
||||||
|
app_name: config.upgradeName,
|
||||||
|
current_version: appInfo.version
|
||||||
|
});
|
||||||
|
if (!res.download_url) {
|
||||||
|
this.$u.toast('当前版本已是最新版');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
changelog: res.message + ',最新版本:' + res.latest_version,
|
||||||
|
status: res.need_update ? 1 : 0,
|
||||||
|
path: res.download_url
|
||||||
|
};
|
||||||
|
}, 1);
|
||||||
// #endif
|
// #endif
|
||||||
// #ifndef APP-PLUS
|
// #ifndef APP-PLUS
|
||||||
this.$u.toast('小程序端或H5端无需检查更新')
|
this.$u.toast('小程序端或H5端已是最新版,无需检查更新!');
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,244 @@
|
|||||||
|
<template>
|
||||||
|
<view class="wrap">
|
||||||
|
<common-navbar title="扫描设置"></common-navbar>
|
||||||
|
<u-gap height="20" bg-color="#f5f5f5"></u-gap>
|
||||||
|
<u-cell-group :border="false">
|
||||||
|
<u-cell-item title="扫码方式" :value="form.name || '请选择'" @click="brandSelectShow = true"></u-cell-item>
|
||||||
|
<template v-if="!form.isPhoneScan">
|
||||||
|
<u-cell-item title="广播动作" :arrow="false">
|
||||||
|
<u-input
|
||||||
|
slot="right-icon"
|
||||||
|
v-model="form.action"
|
||||||
|
placeholder="请输入广播动作"
|
||||||
|
input-align="right"
|
||||||
|
:clearable="false"
|
||||||
|
></u-input>
|
||||||
|
</u-cell-item>
|
||||||
|
<u-cell-item title="数据标签" :arrow="false">
|
||||||
|
<u-input
|
||||||
|
slot="right-icon"
|
||||||
|
v-model="form.dataKey"
|
||||||
|
placeholder="请输入数据标签"
|
||||||
|
input-align="right"
|
||||||
|
:clearable="false"
|
||||||
|
></u-input>
|
||||||
|
</u-cell-item>
|
||||||
|
</template>
|
||||||
|
</u-cell-group>
|
||||||
|
<view class="form-footer">
|
||||||
|
<u-button type="primary" :loading="submitting" @click="submit">确定</u-button>
|
||||||
|
</view>
|
||||||
|
<u-select v-model="brandSelectShow" :list="brandSelectList" @confirm="onBrandConfirm"></u-select>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import CommonNavbar from '@/components/common-navbar/index';
|
||||||
|
import scanMixin from '@/common/scanMixin.js';
|
||||||
|
import {
|
||||||
|
getScanConfig,
|
||||||
|
DICTIONARY_TYPE_SCANNER,
|
||||||
|
isPhoneScanConfig,
|
||||||
|
mapDictionaryToScannerConfig,
|
||||||
|
PHONE_SCAN_BRAND,
|
||||||
|
saveScanConfig,
|
||||||
|
} from '@/common/scanConfig.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
CommonNavbar,
|
||||||
|
},
|
||||||
|
mixins: [scanMixin],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
brandSelectShow: false,
|
||||||
|
submitting: false,
|
||||||
|
configList: [],
|
||||||
|
form: {
|
||||||
|
brand: '',
|
||||||
|
name: '',
|
||||||
|
action: '',
|
||||||
|
dataKey: '',
|
||||||
|
isPhoneScan: false,
|
||||||
|
needSetup: false,
|
||||||
|
setupAction: '',
|
||||||
|
setupParams: null,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
brandSelectList() {
|
||||||
|
return this.configList.map((item) => ({
|
||||||
|
value: item.brand,
|
||||||
|
label: item.name,
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onLoad() {
|
||||||
|
this.loadConfigList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async loadConfigList() {
|
||||||
|
try {
|
||||||
|
const res = await this.$u.api.dictionary.getDetailEnumList({
|
||||||
|
dictionary_id: DICTIONARY_TYPE_SCANNER,
|
||||||
|
});
|
||||||
|
const list = Array.isArray(res) ? res : (Array.isArray(res && res.list) ? res.list : []);
|
||||||
|
const builtinConfigs = this.getScannerConfigs();
|
||||||
|
if (list.length) {
|
||||||
|
this.configList = list
|
||||||
|
.map((item) => mapDictionaryToScannerConfig(item, builtinConfigs))
|
||||||
|
.filter(Boolean);
|
||||||
|
this.remoteScannerConfigs = this.configList.filter((item) => !isPhoneScanConfig(item));
|
||||||
|
} else {
|
||||||
|
this.useFallbackConfigList();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log('获取扫码枪字典配置失败,使用内置配置', error);
|
||||||
|
this.useFallbackConfigList();
|
||||||
|
}
|
||||||
|
this.ensurePhoneScanOption();
|
||||||
|
this.ensureSeuicOption();
|
||||||
|
this.ensureNlscanOption();
|
||||||
|
this.initFormFromSaved();
|
||||||
|
},
|
||||||
|
useFallbackConfigList() {
|
||||||
|
this.configList = this.getScannerConfigs();
|
||||||
|
this.remoteScannerConfigs = [];
|
||||||
|
},
|
||||||
|
ensurePhoneScanOption() {
|
||||||
|
const phoneConfig = this.getPhoneScanConfig();
|
||||||
|
if (!this.configList.find((item) => item.brand === PHONE_SCAN_BRAND)) {
|
||||||
|
this.configList.push(phoneConfig);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ensureBuiltinScannerOption(brand) {
|
||||||
|
const builtinConfig = this.getScannerConfigs().find((item) => item.brand === brand);
|
||||||
|
if (!builtinConfig) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const exists = this.configList.some((item) => {
|
||||||
|
return item.brand === builtinConfig.brand || item.action === builtinConfig.action;
|
||||||
|
});
|
||||||
|
if (exists) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const phoneIndex = this.configList.findIndex((item) => item.brand === PHONE_SCAN_BRAND);
|
||||||
|
if (phoneIndex >= 0) {
|
||||||
|
this.configList.splice(phoneIndex, 0, builtinConfig);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.configList.push(builtinConfig);
|
||||||
|
},
|
||||||
|
ensureSeuicOption() {
|
||||||
|
this.ensureBuiltinScannerOption('seuic');
|
||||||
|
},
|
||||||
|
ensureNlscanOption() {
|
||||||
|
this.ensureBuiltinScannerOption('nlscan');
|
||||||
|
},
|
||||||
|
initFormFromSaved() {
|
||||||
|
const savedConfig = getScanConfig(this.getScannerConfigs());
|
||||||
|
if (savedConfig) {
|
||||||
|
this.applyConfig(savedConfig);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this.isPdaDevice()) {
|
||||||
|
this.applyConfig(this.getPhoneScanConfig());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const pdaConfigs = this.configList.filter((item) => !isPhoneScanConfig(item));
|
||||||
|
if (pdaConfigs.length) {
|
||||||
|
this.applyConfig(pdaConfigs[0]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
applyConfig(config) {
|
||||||
|
const isPhoneScan = isPhoneScanConfig(config);
|
||||||
|
this.form = {
|
||||||
|
brand: config.brand || '',
|
||||||
|
name: config.name || '',
|
||||||
|
action: config.action || '',
|
||||||
|
dataKey: config.dataKey || '',
|
||||||
|
isPhoneScan,
|
||||||
|
needSetup: !!config.needSetup,
|
||||||
|
setupAction: config.setupAction || '',
|
||||||
|
setupParams: config.setupParams || null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onBrandConfirm(selected) {
|
||||||
|
const brand = selected[0]?.value;
|
||||||
|
const config = this.configList.find((item) => item.brand === brand);
|
||||||
|
if (config) {
|
||||||
|
this.applyConfig(config);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
submit() {
|
||||||
|
if (!this.form.brand) {
|
||||||
|
this.$u.toast('请选择扫码方式');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let payload;
|
||||||
|
if (this.form.isPhoneScan) {
|
||||||
|
payload = this.getPhoneScanConfig();
|
||||||
|
} else {
|
||||||
|
const action = (this.form.action || '').trim();
|
||||||
|
const dataKey = (this.form.dataKey || '').trim();
|
||||||
|
if (!action) {
|
||||||
|
this.$u.toast('请输入广播动作');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!dataKey) {
|
||||||
|
this.$u.toast('请输入数据标签');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
payload = {
|
||||||
|
...this.form,
|
||||||
|
action,
|
||||||
|
dataKey,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
this.submitting = true;
|
||||||
|
if (!saveScanConfig(payload)) {
|
||||||
|
this.submitting = false;
|
||||||
|
this.$u.toast('保存失败');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
this.unregisterScanBroadcast();
|
||||||
|
const registered = this.registerScanBroadcastByConfig(payload, null);
|
||||||
|
if (!registered) {
|
||||||
|
this.submitting = false;
|
||||||
|
this.$u.toast('保存成功,但广播注册失败');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
this.submitting = false;
|
||||||
|
this.$u.toast('保存成功');
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.navigateBack();
|
||||||
|
}, 500);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-footer {
|
||||||
|
padding: 40rpx 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .u-cell_title {
|
||||||
|
color: #202328;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .u-input__input {
|
||||||
|
min-width: 360rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -4,7 +4,6 @@
|
|||||||
<u-cell-group :border="false">
|
<u-cell-group :border="false">
|
||||||
<u-cell-item title="通用" @click="navTo('/pages/sys/user/currency')" :arrow="true"></u-cell-item>
|
<u-cell-item title="通用" @click="navTo('/pages/sys/user/currency')" :arrow="true"></u-cell-item>
|
||||||
<u-gap height="20" bg-color="#f5f5f5"></u-gap>
|
<u-gap height="20" bg-color="#f5f5f5"></u-gap>
|
||||||
<u-cell-item title="版本更新" @click="upgrade()" :arrow="true"></u-cell-item>
|
|
||||||
<u-cell-item title="隐私政策" @click="navTo('')" :arrow="true"></u-cell-item>
|
<u-cell-item title="隐私政策" @click="navTo('')" :arrow="true"></u-cell-item>
|
||||||
<u-cell-item title="用户协议" @click="navTo('')" :arrow="true"></u-cell-item>
|
<u-cell-item title="用户协议" @click="navTo('')" :arrow="true"></u-cell-item>
|
||||||
</u-cell-group>
|
</u-cell-group>
|
||||||
@@ -18,10 +17,6 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2013-Now http://aidex.vip All rights reserved.
|
* Copyright (c) 2013-Now http://aidex.vip All rights reserved.
|
||||||
*/
|
*/
|
||||||
import app_upgrade from '@/uni_modules/app-upgrade/js_sdk/index.js'
|
|
||||||
import util from '@/common/util.js';
|
|
||||||
import config from '../../../common/config';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -34,36 +29,6 @@ export default {
|
|||||||
url: url
|
url: url
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
upgrade(){
|
|
||||||
// #ifdef APP-PLUS
|
|
||||||
app_upgrade(async ()=>{
|
|
||||||
// 获取应用信息
|
|
||||||
const appInfo = await new Promise((resolve) => {
|
|
||||||
plus.runtime.getProperty(plus.runtime.appid, (inf) => {
|
|
||||||
resolve(inf);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
const res = await this.$u.api.upgradeCheck({
|
|
||||||
app_name: config.upgradeName,
|
|
||||||
current_version: appInfo.version
|
|
||||||
})
|
|
||||||
console.log('res',res)
|
|
||||||
if(!res.download_url){
|
|
||||||
this.$u.toast('当前版本已是最新版');
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
changelog: res.message + ',最新版本:' + res.latest_version,
|
|
||||||
|
|
||||||
status: res.need_update ? 1 : 0, // 0 无新版本 | 1 有新版本
|
|
||||||
path: res.download_url // 新apk地址
|
|
||||||
}
|
|
||||||
}, 1)
|
|
||||||
// #endif
|
|
||||||
// #ifndef APP-PLUS
|
|
||||||
this.$u.toast('小程序端或H5端已是最新版,无需检查更新!');
|
|
||||||
// #endif
|
|
||||||
},
|
|
||||||
openSettings() {
|
openSettings() {
|
||||||
// #ifdef APP-PLUS
|
// #ifdef APP-PLUS
|
||||||
uni.getSystemInfo({
|
uni.getSystemInfo({
|
||||||
|
|||||||
+249
-260
@@ -1,315 +1,304 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="wrap">
|
<view class="app-center">
|
||||||
<common-navbar title="工作台" :showBack="false">
|
<view class="app-center__status" :style="{ height: statusBarHeight + 'px' }"></view>
|
||||||
<template #right>
|
<view class="app-center__header">
|
||||||
<view class="scan_box">
|
<text class="app-center__version">v{{ appVersion }}</text>
|
||||||
<u-icon name="scan" color="#333333" size="46" @click="handleScan"></u-icon>
|
<text class="app-center__title">工作台</text>
|
||||||
|
<view class="app-center__setting" @click="navTo('/pages/sys/user/setting')">
|
||||||
|
<u-icon name="setting" color="#333333" size="34"></u-icon>
|
||||||
|
<text>设置</text>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
|
||||||
</common-navbar>
|
|
||||||
<view class="workbench-title">销售管理</view>
|
|
||||||
<view class="toolbar">
|
|
||||||
<u-grid class="grid" :col="4" :border="false">
|
|
||||||
<u-grid-item :index="0" @click="navTo('/pages/saleship/salepickscan')">
|
|
||||||
<view class="home-icon icon-color05">
|
|
||||||
<i class="iconfont icon-hetongguanli"></i>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="grid-text">成品配布</view>
|
|
||||||
</u-grid-item>
|
<view class="app-center__grid">
|
||||||
<u-grid-item :index="1" @click="navTo('/pages/storegoods/QRBarCodeReview')">
|
<view
|
||||||
<view class="home-icon icon-color02">
|
v-for="item in menuList"
|
||||||
<i class="iconfont icon-mall-bag"></i>
|
:key="item.path"
|
||||||
|
class="menu-card"
|
||||||
|
:class="item.tone"
|
||||||
|
hover-class="menu-card--pressed"
|
||||||
|
@click="navTo(item.path)"
|
||||||
|
>
|
||||||
|
<image class="menu-card__bg" :src="item.bg" mode="aspectFill"></image>
|
||||||
|
<view class="menu-card__mask"></view>
|
||||||
|
<text class="menu-card__quote">“</text>
|
||||||
|
<view v-if="item.tag" class="menu-card__tag">
|
||||||
|
<text>{{ item.tag }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="grid-text">标签检测</view>
|
<view class="menu-card__body">
|
||||||
</u-grid-item>
|
<text class="menu-card__name">{{ item.name }}</text>
|
||||||
</u-grid>
|
<text class="menu-card__en">{{ item.en }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="workbench-title">成品管理</view>
|
<view class="menu-card__arrow">
|
||||||
<view class="toolbar">
|
<text>›</text>
|
||||||
<u-grid class="grid" :col="4" :border="false">
|
|
||||||
<u-grid-item :index="0" @click="navTo('/pages/storegoods/dyeworksDyeback')">
|
|
||||||
<view class="home-icon icon-color04">
|
|
||||||
<i class="iconfont icon-finance"></i>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="grid-text">染整进仓</view>
|
|
||||||
</u-grid-item>
|
|
||||||
<u-grid-item :index="1" @click="navTo('/pages/storegoods/storeGoodsBusinessIn')">
|
|
||||||
<view class="home-icon icon-color03">
|
|
||||||
<i class="iconfont icon-mall-bag"></i>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="grid-text">成品进仓</view>
|
|
||||||
</u-grid-item>
|
|
||||||
<u-grid-item :index="2" @click="navTo('/pages/storegoods/storeGoodsBusinessOut')">
|
|
||||||
<view class="home-icon icon-color12">
|
|
||||||
<i class="iconfont icon-baoxiaodan"></i>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="grid-text">成品出仓</view>
|
|
||||||
</u-grid-item>
|
|
||||||
<u-grid-item @click="navTo('/pages/storegoods/storeGoodsBusinessCheck')">
|
|
||||||
<view class="home-icon icon-color04">
|
|
||||||
<i class="iconfont icon-shenpi"></i>
|
|
||||||
</view>
|
|
||||||
<view class="grid-text">成品盘点</view>
|
|
||||||
</u-grid-item>
|
|
||||||
<u-grid-item @click="navTo('/pages/storegoods/storeGoodsBusinessStationMoveOnly')">
|
|
||||||
<view class="home-icon icon-color04">
|
|
||||||
<i class="iconfont icon-shenpi"></i>
|
|
||||||
</view>
|
|
||||||
<view class="grid-text">成品移架</view>
|
|
||||||
</u-grid-item>
|
|
||||||
<u-grid-item @click="navTo('/pages/storegoods/storegoodsstoresearch')">
|
|
||||||
<view class="home-icon icon-color04">
|
|
||||||
<i class="iconfont icon-shenpi"></i>
|
|
||||||
</view>
|
|
||||||
<view class="grid-text">成品库存</view>
|
|
||||||
</u-grid-item>
|
|
||||||
<u-grid-item @click="navTo('/pages/storegoods/storegoodsstoreallin')">
|
|
||||||
<view class="home-icon icon-color04">
|
|
||||||
<i class="iconfont icon-shenpi"></i>
|
|
||||||
</view>
|
|
||||||
<view class="grid-text">进仓查询</view>
|
|
||||||
</u-grid-item>
|
|
||||||
<u-grid-item @click="navTo('/pages/storegoods/storegoodsstoreallout')">
|
|
||||||
<view class="home-icon icon-color04">
|
|
||||||
<i class="iconfont icon-shenpi"></i>
|
|
||||||
</view>
|
|
||||||
<view class="grid-text">出仓查询</view>
|
|
||||||
</u-grid-item>
|
|
||||||
</u-grid>
|
|
||||||
</view>
|
|
||||||
<!--
|
|
||||||
<view class="workbench-title">坯布管理</view>
|
|
||||||
<view class="toolbar">
|
|
||||||
<u-grid class="grid" :col="4" :border="false">
|
|
||||||
<u-grid-item :index="0" @click="navTo('/pages/storefabric/storefabricInStore')">
|
|
||||||
<view class="home-icon icon-color04">
|
|
||||||
<i class="iconfont icon-hetongguanli"></i>
|
|
||||||
</view>
|
|
||||||
<view class="grid-text">坯布进仓</view>
|
|
||||||
</u-grid-item>
|
|
||||||
<u-grid-item :index="1" @click="navTo('/pages/storefabric/storefabricOutStore')">
|
|
||||||
<view class="home-icon icon-color03">
|
|
||||||
<i class="iconfont icon-chucha"></i>
|
|
||||||
</view>
|
|
||||||
<view class="grid-text">坯布出仓</view>
|
|
||||||
</u-grid-item>
|
|
||||||
<u-grid-item :index="2" @click="navTo('')">
|
|
||||||
<view class="home-icon icon-color12">
|
|
||||||
<i class="iconfont icon-ribao"></i>
|
|
||||||
</view>
|
|
||||||
<view class="grid-text">坯布盘点</view>
|
|
||||||
</u-grid-item>
|
|
||||||
<u-grid-item @click="navTo('')">
|
|
||||||
<view class="home-icon icon-color04">
|
|
||||||
<i class="iconfont icon-tongzhi"></i>
|
|
||||||
</view>
|
|
||||||
<view class="grid-text">坯布移架</view>
|
|
||||||
</u-grid-item>
|
|
||||||
<u-grid-item @click="navTo('/pages/storefabric/storefabricstoresearch')">
|
|
||||||
<view class="home-icon icon-color05">
|
|
||||||
<i class="iconfont icon-huiyishi"></i>
|
|
||||||
</view>
|
|
||||||
<view class="grid-text">坯布库存</view>
|
|
||||||
</u-grid-item>
|
|
||||||
<u-grid-item @click="navTo('/pages/storefabric/storefabricstoreallin')">
|
|
||||||
<view class="home-icon icon-color05">
|
|
||||||
<i class="iconfont icon-huiyishi"></i>
|
|
||||||
</view>
|
|
||||||
<view class="grid-text">进仓查询</view>
|
|
||||||
</u-grid-item>
|
|
||||||
<u-grid-item @click="navTo('/pages/storefabric/storefabricstoreallout')">
|
|
||||||
<view class="home-icon icon-color05">
|
|
||||||
<i class="iconfont icon-huiyishi"></i>
|
|
||||||
</view>
|
|
||||||
<view class="grid-text">出仓查询</view>
|
|
||||||
</u-grid-item>
|
|
||||||
</u-grid>
|
|
||||||
</view>
|
|
||||||
-->
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import CommonNavbar from "@/components/common-navbar/index";
|
|
||||||
import scanMixin from '@/common/scanMixin.js';
|
import scanMixin from '@/common/scanMixin.js';
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2013-Now http://aidex.vip All rights reserved.
|
* Copyright (c) 2013-Now http://aidex.vip All rights reserved.
|
||||||
*/
|
*/
|
||||||
export default {
|
export default {
|
||||||
components: {
|
|
||||||
CommonNavbar,
|
|
||||||
},
|
|
||||||
mixins: [scanMixin],
|
mixins: [scanMixin],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
show: false,
|
statusBarHeight: 20,
|
||||||
head: "/static/aidex/images/head.png",
|
appVersion: '1.1.10',
|
||||||
imgList: [
|
menuList: [
|
||||||
{ image: "/static/aidex/banner/banner01.png" },
|
{
|
||||||
//{image: '/static/aidex/banner/banner02.png'},
|
name: '坯布出库',
|
||||||
//{image: '/static/aidex/banner/banner03.png'}
|
en: 'FABRIC OUT',
|
||||||
],
|
tag: '出库',
|
||||||
todoCount: 3,
|
path: '/pages/storefabric/storeFabricBusinessOutList',
|
||||||
// scanReceiver 和 isPageActive 已由 scanMixin 提供
|
tone: 'tone-out',
|
||||||
|
bg: '/static/img/workbench/fabric-out.jpg'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '坯布库存',
|
||||||
|
en: 'FABRIC STOCK',
|
||||||
|
tag: '库存',
|
||||||
|
path: '/pages/storefabric/storeFabricWarehouseGroupList',
|
||||||
|
tone: 'tone-stock',
|
||||||
|
bg: '/static/img/workbench/fabric-stock.jpg'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '手动进仓',
|
||||||
|
en: 'MANUAL ENTRY',
|
||||||
|
tag: '进仓',
|
||||||
|
path: '/pages/storefabric/storeFabricManualIn',
|
||||||
|
tone: 'tone-in',
|
||||||
|
bg: '/static/img/workbench/fabric-stock.jpg'
|
||||||
|
}
|
||||||
|
]
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
onLoad() {
|
onLoad() {
|
||||||
|
const sys = uni.getSystemInfoSync();
|
||||||
|
this.statusBarHeight = sys.statusBarHeight || 20;
|
||||||
// #ifdef APP-PLUS
|
// #ifdef APP-PLUS
|
||||||
// 使用 scanMixin 的方法注册扫码广播,传入自定义回调
|
plus.runtime.getProperty(plus.runtime.appid, (inf) => {
|
||||||
this.registerScanBroadcast(this.handleScanCode);
|
if (inf && inf.version) {
|
||||||
|
this.appVersion = inf.version;
|
||||||
|
}
|
||||||
|
});
|
||||||
// #endif
|
// #endif
|
||||||
|
this.registerScanBroadcast(this.handleScanCode);
|
||||||
},
|
},
|
||||||
// onUnload, onHide, onShow 已由 scanMixin 自动处理
|
|
||||||
|
|
||||||
computed: {
|
|
||||||
contentStyle() {
|
|
||||||
const navHeight = getStatusBarHeight() + 44;
|
|
||||||
return {
|
|
||||||
height: `${navHeight}px`,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
// 自定义扫码处理回调 - 处理本页面特有的扫码逻辑
|
|
||||||
handleScanCode(scanResult) {
|
handleScanCode(scanResult) {
|
||||||
console.log('工作台-扫码结果:', scanResult);
|
|
||||||
const cleanResult = scanResult.trim().replace(/[\r\n]/g, '');
|
const cleanResult = scanResult.trim().replace(/[\r\n]/g, '');
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: '/pages/saleship/salepickscandetail?order_no=' + cleanResult
|
url: '/pages/saleship/salepickscandetail?order_no=' + cleanResult
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
navTo(url) {
|
navTo(url) {
|
||||||
uni.navigateTo({
|
uni.navigateTo({ url });
|
||||||
url: url,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
imgListClick(index) {
|
|
||||||
console.log(`点击了第${index + 1}页图片`);
|
|
||||||
},
|
|
||||||
itemClick(index) {
|
|
||||||
console.log(index);
|
|
||||||
},
|
|
||||||
// 处理扫码(手动点击扫码按钮)
|
|
||||||
handleScan() {
|
|
||||||
// uni.navigateTo({
|
|
||||||
// url: '/pages/saleship/salepickscandetail?order_no=FPD-PB-202412270196'
|
|
||||||
// })
|
|
||||||
// return
|
|
||||||
// #ifdef APP-PLUS || MP-WEIXIN
|
|
||||||
uni.scanCode({
|
|
||||||
scanType: ['qrCode', 'barCode'], // 同时支持二维码和条形码
|
|
||||||
success: (res) => {
|
|
||||||
console.log('扫码成功:', res);
|
|
||||||
const cleanResult = res.result.trim().replace(/[\r\n]/g, '');
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/saleship/salepickscandetail?order_no=' + cleanResult
|
|
||||||
})
|
|
||||||
},
|
|
||||||
fail: (err) => {
|
|
||||||
console.error('扫码失败:', err);
|
|
||||||
uni.showToast({
|
|
||||||
title: '扫码失败',
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #ifdef H5
|
|
||||||
uni.showToast({
|
|
||||||
title: "H5环境不支持扫码功能",
|
|
||||||
icon: "error",
|
|
||||||
});
|
|
||||||
// #endif
|
|
||||||
},
|
|
||||||
// 处理扫码成功
|
|
||||||
handleScanSuccess(result) {
|
|
||||||
try {
|
|
||||||
// 这里可以根据实际需求处理扫码结果
|
|
||||||
// 例如:验证扫码结果的格式或内容
|
|
||||||
if (this.validateScanResult(result)) {
|
|
||||||
// 扫码验证通过,执行其他逻辑
|
|
||||||
uni.showToast({
|
|
||||||
title: "执行成功",
|
|
||||||
icon: "success",
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
uni.showToast({
|
|
||||||
title: "无效的二维码",
|
|
||||||
icon: "none",
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
console.error("处理扫码结果失败:", error);
|
|
||||||
uni.showToast({
|
|
||||||
title: "处理失败",
|
|
||||||
icon: "none",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// registerScanBroadcast 和 unregisterScanBroadcast 已由 scanMixin 提供
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "index.scss";
|
page {
|
||||||
|
background: #eef1f4;
|
||||||
|
}
|
||||||
|
|
||||||
.scan_box {
|
.app-center {
|
||||||
|
min-height: 100vh;
|
||||||
|
background: #eef1f4;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-center__header {
|
||||||
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
height: 88rpx;
|
||||||
.scan_text {
|
padding: 0 24rpx;
|
||||||
font-size: 12px;
|
background: #ffffff;
|
||||||
color: #2979ff;
|
border-bottom: 1rpx solid #e5e8ec;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.banner-box {
|
.app-center__version {
|
||||||
padding: 0 2%;
|
position: absolute;
|
||||||
width: 96%;
|
left: 24rpx;
|
||||||
height: 170rpx;
|
font-size: 24rpx;
|
||||||
margin: 30rpx 0 30rpx;
|
color: #9aa3ad;
|
||||||
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.u-swiper-wrap {
|
.app-center__title {
|
||||||
padding: 0 10px;
|
font-size: 36rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #1f2430;
|
||||||
|
letter-spacing: 2rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.banner-pic {
|
.app-center__setting {
|
||||||
width: 47%;
|
position: absolute;
|
||||||
float: left;
|
right: 24rpx;
|
||||||
display: inline-block;
|
display: flex;
|
||||||
margin: 0 1.5%;
|
align-items: center;
|
||||||
}
|
gap: 6rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
.banner-pic image {
|
|
||||||
width: 100%;
|
|
||||||
height: 170rpx;
|
|
||||||
border-radius: 12rpx;
|
|
||||||
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.u-mode-light-info {
|
|
||||||
background-color: #ffffff;
|
|
||||||
color: #666666;
|
|
||||||
border: 1px solid #e9ecf6;
|
|
||||||
font-size: 12px;
|
|
||||||
padding: 2px 8px;
|
|
||||||
position: relative;
|
|
||||||
top: -3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workbench-title {
|
|
||||||
font-size: 32rpx;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333333;
|
color: #333333;
|
||||||
padding: 15px 30rpx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.home-icon i.icon-tongzhi {
|
.app-center__grid {
|
||||||
font-size: 22px;
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 28rpx 48rpx 40rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-card {
|
||||||
|
position: relative;
|
||||||
|
width: 310rpx;
|
||||||
|
height: 200rpx;
|
||||||
|
margin-bottom: 22rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
box-sizing: border-box;
|
||||||
|
box-shadow: 0 6rpx 14rpx rgba(20, 40, 70, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-card--pressed {
|
||||||
|
opacity: 0.88;
|
||||||
|
transform: scale(0.985);
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-card__bg {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 0;
|
||||||
|
opacity: 0.38;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-card__mask {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-card__quote {
|
||||||
|
position: absolute;
|
||||||
|
left: 14rpx;
|
||||||
|
top: 2rpx;
|
||||||
|
font-size: 48rpx;
|
||||||
|
line-height: 1;
|
||||||
|
color: rgba(255, 255, 255, 0.55);
|
||||||
|
font-weight: 700;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-card__tag {
|
||||||
|
position: absolute;
|
||||||
|
top: 14rpx;
|
||||||
|
right: 48rpx;
|
||||||
|
padding: 2rpx 12rpx;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
background: #ffffff;
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-card__tag text {
|
||||||
|
font-size: 20rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-card__body {
|
||||||
|
position: absolute;
|
||||||
|
left: 22rpx;
|
||||||
|
right: 22rpx;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-42%);
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-card__name {
|
||||||
|
display: block;
|
||||||
|
font-size: 34rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #ffffff;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-card__en {
|
||||||
|
display: block;
|
||||||
|
margin-top: 8rpx;
|
||||||
|
font-size: 18rpx;
|
||||||
|
letter-spacing: 1rpx;
|
||||||
|
color: rgba(255, 255, 255, 0.88);
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-card__arrow {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 48rpx;
|
||||||
|
height: 42rpx;
|
||||||
|
background: #eef1f4;
|
||||||
|
border-top-left-radius: 16rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-card__arrow text {
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #8a93a0;
|
||||||
|
line-height: 1;
|
||||||
|
margin-top: -4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tone-out {
|
||||||
|
background: #e14b3b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tone-out .menu-card__mask {
|
||||||
|
background: rgba(225, 75, 59, 0.72);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tone-out .menu-card__tag text {
|
||||||
|
color: #e14b3b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tone-stock {
|
||||||
|
background: #2f78e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tone-stock .menu-card__mask {
|
||||||
|
background: rgba(47, 120, 230, 0.72);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tone-stock .menu-card__tag text {
|
||||||
|
color: #2f78e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tone-in {
|
||||||
|
background: #3f51b5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tone-in .menu-card__mask {
|
||||||
|
background: rgba(63, 81, 181, 0.72);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tone-in .menu-card__tag text {
|
||||||
|
color: #3f51b5;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 204 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 137 KiB |
+8
-21
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2013-Now http://aidex.vip All rights reserved.
|
* Copyright (c) 2013-Now http://aidex.vip All rights reserved.
|
||||||
*/
|
*/
|
||||||
import config from '@/common/config.js';
|
import config, { getTestApiUrl } from '@/common/config.js';
|
||||||
import util from '@/common/util.js';
|
import util from '@/common/util.js';
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Vuex from 'vuex'
|
import Vuex from 'vuex'
|
||||||
@@ -21,19 +21,13 @@ try{
|
|||||||
|
|
||||||
// 初始化API URL
|
// 初始化API URL
|
||||||
function initApiUrl() {
|
function initApiUrl() {
|
||||||
if (config.isDevelopment) {
|
const testUrl = getTestApiUrl();
|
||||||
// 开发环境:从存储读取,如果没有则使用测试环境
|
|
||||||
try {
|
try {
|
||||||
const savedApiUrl = uni.getStorageSync('ApiUrl');
|
uni.setStorageSync('ApiUrl', testUrl);
|
||||||
return savedApiUrl || config.devApiUrlOptions[0].value;
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('读取存储的 apiurl 失败', e);
|
console.log('写入测试环境地址失败', e);
|
||||||
return config.devApiUrlOptions[0].value;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 生产环境:使用固定的生产URL
|
|
||||||
return config.productionApiUrl;
|
|
||||||
}
|
}
|
||||||
|
return testUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 需要永久存储,且下次APP启动需要取出的,在state中的变量名
|
// 需要永久存储,且下次APP启动需要取出的,在state中的变量名
|
||||||
@@ -105,13 +99,7 @@ const store = new Vuex.Store({
|
|||||||
state.vuex_notificationAudio = audio;
|
state.vuex_notificationAudio = audio;
|
||||||
},
|
},
|
||||||
SET_API_URL(state, url) {
|
SET_API_URL(state, url) {
|
||||||
// 生产环境不允许修改URL
|
|
||||||
if (!config.isDevelopment) {
|
|
||||||
console.warn('生产环境不允许修改API URL');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
state.apiurl = url
|
state.apiurl = url
|
||||||
// 同时保存到本地存储
|
|
||||||
uni.setStorageSync('ApiUrl', url)
|
uni.setStorageSync('ApiUrl', url)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -173,6 +161,9 @@ const store = new Vuex.Store({
|
|||||||
uni.request({
|
uni.request({
|
||||||
url: util.apiurl + "/product/fpmArrangeOrder/getFpmArrangeOrderList",
|
url: util.apiurl + "/product/fpmArrangeOrder/getFpmArrangeOrderList",
|
||||||
method: "GET",
|
method: "GET",
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
sslVerify: false,
|
||||||
|
// #endif
|
||||||
header: {
|
header: {
|
||||||
platform: "2",
|
platform: "2",
|
||||||
Authorization: uni.getStorageSync("RemoteTokenData").token,
|
Authorization: uni.getStorageSync("RemoteTokenData").token,
|
||||||
@@ -221,10 +212,6 @@ const store = new Vuex.Store({
|
|||||||
name: 'vuex_messageList',
|
name: 'vuex_messageList',
|
||||||
value: newList
|
value: newList
|
||||||
});
|
});
|
||||||
uni.setTabBarBadge({
|
|
||||||
index: 0,
|
|
||||||
text: `${newList.length}`
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
// 使用 $uStore 方式更新状态
|
// 使用 $uStore 方式更新状态
|
||||||
commit('$uStore', {
|
commit('$uStore', {
|
||||||
|
|||||||
Reference in New Issue
Block a user