feat: 默认测试环境并优化出仓与网络提示

This commit is contained in:
郭鸿轩 2026-09-24 17:56:06 +08:00
parent 53a059f16b
commit 26c7085ab2
10 changed files with 182 additions and 43 deletions

View File

@ -26,14 +26,16 @@ const config = {
// 开发环境API URL选项(仅替换 //域名/ 后第一个路径段 hcscm → hcscm_weave,不改域名)
devApiUrlOptions: [
{ label: '测试环境', value: 'https://hcscmtest.zzfzyc.com/hcscm_weave/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: process.env.VUE_APP_DEV_API_URL || 'https://www.haotopai.com/hcscm_weave/mes/server/pda/v1' },
{ label: '自定义', value: 'custom' }
]
}
// 设置后台接口服务的基础地址 - 使用动态API URL
// config.baseUrl = 'https://aidex.vip/api'; // 注释掉固定的baseUrl
export function getTestApiUrl() {
const test = config.devApiUrlOptions.find(item => item.label === '测试环境');
return (test && test.value) || 'https://hcscmtest.zzfzyc.com/hcscm_weave/pda/v1';
}
export default config;

View File

@ -70,8 +70,12 @@ const install = (Vue, vm) => {
}
console.log('res',res)
if (!(res.data)){
vm.$u.toast('未连接到服务器')
return Promise.reject(new Error('未连接到服务器'));
const errMsg = String((res && res.errMsg) || '');
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) {

View File

@ -69,8 +69,8 @@ export const BILL_TYPES = [
/** 列表分页拉取每页条数 */
export const LIST_PAGE_SIZE = 100;
/** 往来单位类型:织厂(接收单位下拉筛选) */
export const BUSINESS_UNIT_TYPE_KNITTING_FACTORY = 11;
/** 往来单位类型:染厂(接收单位下拉筛选) */
export const BUSINESS_UNIT_TYPE_DYEING_FACTORY = 12;
export function getStatusOptions() {
return Object.keys(AUDIT_STATUS_MAP).map((value) => ({

View File

@ -0,0 +1,100 @@
<template>
<u-popup v-model="visible" mode="bottom" :safe-area-inset-bottom="true" border-radius="16">
<view class="search-select">
<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">
<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: '',
};
},
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 = '';
},
},
methods: {
confirm(item) {
this.visible = false;
this.$emit('confirm', item);
},
},
};
</script>
<style scoped>
.search-select {
background: #fff;
padding-bottom: 20rpx;
}
.search-select__bar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx 30rpx 12rpx;
}
.search-select__title {
font-size: 32rpx;
font-weight: bold;
color: #202328;
}
.search-select__cancel {
font-size: 28rpx;
color: #888;
}
.search-select__search {
padding: 0 24rpx 12rpx;
}
.search-select__list {
height: 640rpx;
}
.search-select__empty {
padding: 80rpx 0;
text-align: center;
color: #999;
font-size: 28rpx;
}
.search-select__item {
padding: 28rpx 30rpx;
font-size: 30rpx;
color: #202328;
border-bottom: 1px solid #f2f2f2;
}
</style>

View File

@ -122,7 +122,13 @@
<u-select v-model="selectShow" :list="selectList" @confirm="selectConfirmFun"></u-select>
<search-select-popup
:show.sync="selectShow"
title="选择接收单位"
placeholder="请输入染厂名称"
:list="selectList"
@confirm="selectConfirmFun"
/>
<FabricInfoPopup :show.sync="fabricInfoShow" :data="currentFabricInfo" />
@ -152,6 +158,8 @@ import FabricOutScanDetail from '@/components/storefabric/FabricOutScanDetail.vu
import FabricOutFooter from '@/components/storefabric/FabricOutFooter.vue';
import SearchSelectPopup from '@/components/storefabric/SearchSelectPopup.vue';
export default {
@ -172,6 +180,8 @@ export default {
FabricOutFooter,
SearchSelectPopup,
},
mixins: [formMixin],

View File

@ -51,7 +51,13 @@
<FabricOutFooter :buttons="statusActionButtons" @action="handleStatusAction" />
<u-select v-model="selectShow" :list="selectList" @confirm="selectConfirmFun"></u-select>
<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>
@ -66,6 +72,7 @@ import FabricOutDetailList from '@/components/storefabric/FabricOutDetailList.vu
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: {
@ -76,6 +83,7 @@ export default {
FabricOutScanBar,
FabricOutScanDetail,
FabricOutFooter,
SearchSelectPopup,
},
mixins: [formMixin],
onLoad(e) {

View File

@ -60,24 +60,32 @@
<u-select v-model="statusSelectShow" :list="statusSelectList" @confirm="onStatusConfirm"></u-select>
<u-select v-model="unitSelectShow" :list="unitSelectList" @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_MAP,
BILL_TYPES,
BUSINESS_UNIT_TYPE_KNITTING_FACTORY,
BUSINESS_UNIT_TYPE_DYEING_FACTORY,
formatRoll,
mapToSelectOptions,
fetchAllOrderList,
} from '@/common/storeFabricBusinessOut';
export default {
components: { addBtn, FabricOutItem },
components: { addBtn, FabricOutItem, SearchSelectPopup },
data() {
return {
list: [],
@ -86,6 +94,7 @@ export default {
filterShow: false,
statusSelectShow: false,
unitSelectShow: false,
businessUnitSelectShow: false,
unitSelectType: '',
deliveryUnitOptions: [],
businessUnitOptions: [],
@ -119,8 +128,10 @@ export default {
return this.filters.business_unit_name || '';
},
unitSelectList() {
const options = this.unitSelectType === 'delivery' ? this.deliveryUnitOptions : this.businessUnitOptions;
return [{ value: '', label: '全部' }, ...options];
return [{ value: '', label: '全部' }, ...this.deliveryUnitOptions];
},
businessUnitSelectList() {
return [{ value: '', label: '全部' }, ...this.businessUnitOptions];
},
},
onLoad() {
@ -150,7 +161,7 @@ export default {
},
loadBusinessUnitOptions() {
if (this.businessUnitOptions.length) return Promise.resolve(this.businessUnitOptions);
return this.$u.api.businessUnit.list({ unit_type_id: BUSINESS_UNIT_TYPE_KNITTING_FACTORY })
return this.$u.api.businessUnit.list({ unit_type_id: BUSINESS_UNIT_TYPE_DYEING_FACTORY })
.then((res) => {
this.businessUnitOptions = mapToSelectOptions(res);
return this.businessUnitOptions;
@ -181,7 +192,23 @@ export default {
this.openUnitSelect('delivery');
},
openBusinessUnitSelect() {
this.openUnitSelect('business');
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] || {};

View File

@ -13,7 +13,7 @@ import scanMixin from '@/common/scanMixin.js';
import {
AUDIT_STATUS_MAP,
BILL_TYPES,
BUSINESS_UNIT_TYPE_KNITTING_FACTORY,
BUSINESS_UNIT_TYPE_DYEING_FACTORY,
normalizeOrder,
mapToSelectOptions,
getFineCodeScanCode,
@ -136,7 +136,7 @@ export default {
},
ensureBusinessUnitOptions() {
if (this.businessUnitOptions.length) return Promise.resolve(this.businessUnitOptions);
return this.$u.api.businessUnit.list({ unit_type_id: BUSINESS_UNIT_TYPE_KNITTING_FACTORY })
return this.$u.api.businessUnit.list({ unit_type_id: BUSINESS_UNIT_TYPE_DYEING_FACTORY })
.then((res) => {
this.businessUnitOptions = mapToSelectOptions(res);
return this.businessUnitOptions;
@ -197,12 +197,10 @@ export default {
.catch((e) => this.showError(e.message || '加载单位列表失败'));
}
},
selectConfirmFun(e) {
const item = e[0];
if (this.selectType === '接收单位') {
this.form.business_unit_id = item.value;
this.form.business_unit_name = item.label;
}
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;

View File

@ -116,7 +116,7 @@
/**
* 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 util from '@/common/util.js';
import md5 from '@/common/md5.js';
@ -134,10 +134,7 @@ export default {
password: ""
},
showApiUrlPicker: false,
// 暂时在打包后也展示服务器选项;生产包默认正式环境
selectedApiUrl: config.isDevelopment
? config.devApiUrlOptions[0].value
: ((config.devApiUrlOptions.find(item => item.label === '正式环境') || {}).value || config.productionApiUrl),
selectedApiUrl: getTestApiUrl(),
customApiUrl: 'http://192.168.1.66:50002/hcscm_weave/pda/v1',
apiUrlList: config.devApiUrlOptions,
phoneNo: '',
@ -168,13 +165,9 @@ export default {
},
onShow() {
uni.getStorage({
key: 'ApiUrl',
success: (e) => {
util.updateApiUrl(e.data);
this.selectedApiUrl = e.data;
}
});
const testUrl = getTestApiUrl();
util.updateApiUrl(testUrl);
this.selectedApiUrl = testUrl;
uni.getStorage({
key: 'UserInfo',

View File

@ -1,7 +1,7 @@
/**
* 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 Vue from 'vue'
import Vuex from 'vuex'
@ -21,16 +21,13 @@ try{
// 初始化API URL
function initApiUrl() {
const fallbackUrl = config.isDevelopment
? config.devApiUrlOptions[0].value
: ((config.devApiUrlOptions.find(item => item.label === '正式环境') || {}).value || config.productionApiUrl);
const testUrl = getTestApiUrl();
try {
const savedApiUrl = uni.getStorageSync('ApiUrl');
return savedApiUrl || fallbackUrl;
uni.setStorageSync('ApiUrl', testUrl);
} catch (e) {
console.log('读取存储的 apiurl 失败', e);
return fallbackUrl;
console.log('写入测试环境地址失败', e);
}
return testUrl;
}
// 需要永久存储,且下次APP启动需要取出的,在state中的变量名