1、基础数据修复bug

2、客商模块修复bug
This commit is contained in:
2026-08-06 02:57:55 +08:00
parent e5a7aca09e
commit c339852e04
24 changed files with 1612 additions and 548 deletions

View File

@@ -24,10 +24,9 @@
<el-button
type="primary"
icon="el-icon-plus"
plain
v-if="hasPermission('common_cargo_add')"
@click="$refs.crud.rowAdd()"
>
>建常用货物
</el-button>
<el-button
type="primary"
@@ -113,7 +112,7 @@
clearable
maxlength="20"
show-word-limit
placeholder="请输入货物编号"
placeholder="请输入"
:disabled="dialogReadonly || dialogType === 'edit'"
@input="handleCargoCodeInput"
/>
@@ -144,6 +143,10 @@
</div>
</template>
<template #packageBrand="{ row }">
{{ [row.packageType, row.brand].filter(Boolean).join(' / ') || '-' }}
</template>
<template #menu="{ row, index }">
<el-link
type="primary"
@@ -192,6 +195,7 @@
import * as api from '@/api/business/common-cargo';
import { getList as getCargoTypeList } from '@/api/base/cargo-type';
import { exportBlob } from '@/api/common';
import { getDeptTree } from '@/api/system/dept';
import { config, excelOption, option } from '@/option/business/common-cargo';
import { priceUnitOptions } from '@/option/business/common';
import { getToken } from '@/utils/auth';
@@ -221,6 +225,7 @@ export default {
secondCargoTypeLoading: false,
firstCargoTypeOptions: [],
secondCargoTypeOptions: [],
deptOptions: [],
page: {
pageSize: 10,
pageSizes: [10, 20, 50, 100],
@@ -247,6 +252,9 @@ export default {
return this.selectionList.map(item => item.id).join(',');
},
},
created() {
this.initDeptTree();
},
methods: {
hasPermission(code) {
return this.isAdmin || this.validData(this.permission && this.permission[code], false);
@@ -256,6 +264,28 @@ export default {
if (Array.isArray(data)) return data;
return (data && data.records) || [];
},
initDeptTree() {
getDeptTree(this.userInfo.tenantId).then(res => {
this.deptOptions = this.flattenDept(res.data.data || []);
const deptColumn = this.findColumn(this.option.column, 'searchDeptId');
if (deptColumn) {
deptColumn.dicData = this.deptOptions;
}
});
},
flattenDept(tree, level = 0) {
const result = [];
tree.forEach(item => {
result.push({
label: `${' '.repeat(level)}${item.title || item.deptName || item.name}`,
value: item.id,
});
if (item.children && item.children.length) {
result.push(...this.flattenDept(item.children, level + 1));
}
});
return result;
},
normalizeCargoTypeOptions(list = []) {
return list
.map(item => ({
@@ -319,11 +349,12 @@ export default {
const second = this.secondCargoTypeOptions.find(item => item.cargoCode === value);
this.form.secondCargoTypeName = second ? second.cargoName : '';
this.form.secondCargoTypeCode = second ? second.cargoCode : '';
this.form.cargoCode = second ? String(second.cargoCode).slice(0, 4) : '';
this.syncCargoCodePrefix();
},
getCargoCodePrefix() {
return this.form.secondCargoTypeCode && this.form.firstCargoTypeCode
? this.form.firstCargoTypeCode
return this.form.secondCargoTypeCode
? String(this.form.secondCargoTypeCode).slice(0, 4)
: '';
},
syncCargoCodePrefix() {
@@ -383,13 +414,13 @@ export default {
return false;
}
const cargoCode = String(row.cargoCode || '');
const prefix = row.firstCargoTypeCode;
const prefix = String(row.secondCargoTypeCode || '').slice(0, 4);
if (!cargoCode || cargoCode === prefix) {
this.$message.warning('请输入货物编号');
return false;
}
if (!cargoCode.startsWith(prefix)) {
this.$message.warning('货物编号需拼接级货物类型编号在前面');
this.$message.warning('货物编号需拼接级货物类型编号在前面');
return false;
}
if (cargoCode.length > 20) {

View File

@@ -24,10 +24,25 @@
<el-button
type="primary"
icon="el-icon-plus"
plain
v-if="hasPermission('common_route_add')"
@click="$refs.crud.rowAdd()"
>
>建路线
</el-button>
<el-button
type="primary"
icon="el-icon-upload"
plain
v-if="config.importUrl && hasPermission('common_route_import')"
@click="handleImport"
>批量导入
</el-button>
<el-button
type="primary"
icon="el-icon-download"
plain
v-if="config.templateUrl && hasPermission('common_route_template')"
@click="handleTemplate"
>下载模板
</el-button>
<el-button
type="primary"
@@ -57,10 +72,10 @@
/>
<el-input
v-model="form.departureAddress"
readonly
placeholder="请输入并选择地址"
suffix-icon="el-icon-location"
:disabled="dialogReadonly"
@click="openRouteMapDialog('departure')"
/>
<el-tooltip content="选择常用地址" placement="top">
<el-button
@@ -84,10 +99,10 @@
/>
<el-input
v-model="form.arrivalAddress"
readonly
placeholder="请输入并选择地址"
suffix-icon="el-icon-location"
:disabled="dialogReadonly"
@click="openRouteMapDialog('arrival')"
/>
<el-tooltip content="选择常用地址" placement="top">
<el-button
@@ -133,6 +148,16 @@
@load="onLoad(page, query)"
/>
<el-dialog :title="`${config.title}导入`" append-to-body v-model="excelBox" width="555px">
<avue-form :option="excelOptionConfig" v-model="excelForm">
<template #excelTemplate>
<el-button type="primary" @click="handleTemplate">
点击下载<i class="el-icon-download el-icon--right"></i>
</el-button>
</template>
</avue-form>
</el-dialog>
<el-dialog
title="选择常用地址"
append-to-body
@@ -238,6 +263,48 @@
<el-button @click="addressDialogVisible = false">关闭</el-button>
</template>
</el-dialog>
<el-dialog
title="地图选择地址"
append-to-body
v-model="routeMapVisible"
width="920px"
@opened="initRouteAmap"
>
<div class="common-route-page__map-toolbar">
<el-input
v-model="routeMapKeyword"
clearable
placeholder="输入地址关键词"
@keyup.enter="searchRouteMapKeyword"
/>
<el-button
type="primary"
:icon="Search"
:loading="routeMapLoading"
@click="searchRouteMapKeyword"
>
搜索
</el-button>
</div>
<div ref="routeAmap" class="common-route-page__map"></div>
<div class="common-route-page__map-info">
<span>{{ routeMapStatus }}</span>
<span v-if="routeMapSelected.regionName"
>发货/收货地{{ routeMapSelected.regionName }}</span
>
</div>
<template #footer>
<el-button @click="routeMapVisible = false">取消</el-button>
<el-button
type="primary"
:disabled="!routeMapSelected.longitude"
@click="confirmRouteMapPick"
>
确定
</el-button>
</template>
</el-dialog>
</basic-container>
</template>
@@ -247,18 +314,24 @@ import { getList as getCommonAddressList } from '@/api/base/common-address';
import { exportBlob } from '@/api/common';
import { getDeptTree } from '@/api/system/dept';
import { addressTypeOptions } from '@/option/base/common-address';
import { config, option } from '@/option/business/common-route';
import { config, excelOption, option } from '@/option/business/common-route';
import { getToken } from '@/utils/auth';
import { openImportDialog } from '@/utils/import-excel';
import { downloadXls } from '@/utils/util';
import { List } from '@element-plus/icons-vue';
import { List, Search } from '@element-plus/icons-vue';
import { mapGetters } from 'vuex';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
const AMAP_KEY = '653b7cf105ad7fb8ec9b2f5198ade315';
const AMAP_SECURITY_CODE = '5aab65c632e48ebae0d0e28f5b28e21a';
let amapLoader;
export default {
data() {
return {
List,
Search,
config,
option,
form: {},
@@ -266,12 +339,24 @@ export default {
loading: true,
data: [],
dialogReadonly: false,
excelBox: false,
excelForm: {},
excelOptionConfig: excelOption,
addressTypeOptions,
addressDialogVisible: false,
addressTarget: '',
addressQuery: {},
addressData: [],
addressLoading: false,
routeMapVisible: false,
routeMapTarget: '',
routeMapLoading: false,
routeMapKeyword: '',
routeMapStatus: '可搜索地址或点击地图选点',
routeMapSelected: {},
routeAmap: null,
routeAmapMarker: null,
routeAmapGeocoder: null,
deptOptions: [],
page: {
pageSize: 10,
@@ -313,9 +398,22 @@ export default {
},
initDeptTree() {
getDeptTree(this.userInfo.tenantId).then(res => {
this.deptOptions = this.flattenDept(res.data.data || []);
const deptTree = res.data.data || [];
this.deptOptions = this.flattenDept(deptTree);
const deptColumn = this.findColumn(this.option.column, 'searchDeptId');
if (deptColumn) {
deptColumn.dicData = this.buildDeptTree(deptTree);
}
});
},
buildDeptTree(tree) {
return tree.map(item => ({
label: item.title || item.deptName || item.name,
value: item.id,
children:
item.children && item.children.length ? this.buildDeptTree(item.children) : undefined,
}));
},
flattenDept(tree, level = 0) {
const result = [];
tree.forEach(item => {
@@ -400,6 +498,246 @@ export default {
this.form[`${prefix}Contact`] = address.contactName || this.form[`${prefix}Contact`] || '';
this.form[`${prefix}Phone`] = address.contactPhone || this.form[`${prefix}Phone`] || '';
},
openRouteMapDialog(target) {
if (this.dialogReadonly) return;
const prefix = target === 'departure' ? 'departure' : 'arrival';
this.routeMapTarget = prefix;
this.routeMapKeyword = this.form[`${prefix}Address`] || this.form[`${prefix}Name`] || '';
this.routeMapSelected = this.buildRouteMapSelection({
lng: this.form[`${prefix}Longitude`],
lat: this.form[`${prefix}Latitude`],
address: this.form[`${prefix}Address`],
regionName: this.form[`${prefix}Name`],
});
this.routeMapStatus = this.routeMapSelected.longitude
? '已加载当前选点,可重新选点'
: '可搜索地址或点击地图选点';
this.routeMapVisible = true;
},
loadAmap() {
if (window.AMap && window.AMap.Map) {
return Promise.resolve();
}
if (!amapLoader) {
amapLoader = new Promise((resolve, reject) => {
window._AMapSecurityConfig = {
securityJsCode: AMAP_SECURITY_CODE,
};
const script = document.createElement('script');
script.src = `https://webapi.amap.com/maps?v=2.0&key=${AMAP_KEY}`;
script.async = true;
script.onload = resolve;
script.onerror = () => reject(new Error('高德地图组件加载失败'));
document.body.appendChild(script);
});
}
return amapLoader;
},
initRouteAmap() {
this.loadAmap()
.then(() => {
this.$nextTick(() => {
if (!this.routeAmap) {
const center = this.toLngLat(
this.routeMapSelected.longitude || 116.40769,
this.routeMapSelected.latitude || 39.89945
);
this.routeAmap = new window.AMap.Map(this.$refs.routeAmap, {
center,
zoom: this.routeMapSelected.longitude ? 14 : 11,
});
window.AMap.plugin(['AMap.ToolBar', 'AMap.Geocoder'], () => {
this.routeAmap.addControl(new window.AMap.ToolBar());
if (!this.routeAmapGeocoder) {
this.routeAmapGeocoder = new window.AMap.Geocoder();
}
});
this.routeAmap.on('click', event => this.pickRouteMapPoint(event.lnglat));
} else if (typeof this.routeAmap.resize === 'function') {
this.routeAmap.resize();
}
if (this.routeMapSelected.longitude) {
this.renderRouteMapMarker(
this.toLngLat(this.routeMapSelected.longitude, this.routeMapSelected.latitude)
);
}
});
})
.catch(() => {
this.$message.error('高德地图组件加载失败,请稍后重试或重新打开弹窗');
this.routeMapVisible = false;
});
},
searchRouteMapKeyword() {
const keyword = String(this.routeMapKeyword || '').trim();
if (!keyword) {
this.$message.warning('请输入地址关键词');
return;
}
this.loadAmap()
.then(() => {
this.routeMapLoading = true;
return this.ensureRouteAmapGeocoder();
})
.then(() => this.runAmapGeocode('location', keyword))
.then(result => {
const point = this.resolveMapPoint(result);
if (!point) {
this.routeMapStatus = '未找到匹配地址';
this.$message.warning('地图搜索无匹配地址');
return;
}
this.pickRouteMapPoint(point, keyword);
})
.catch(() => {
this.routeMapStatus = '地图搜索失败';
this.$message.error('地图搜索失败,请稍后重试');
})
.finally(() => {
this.routeMapLoading = false;
});
},
pickRouteMapPoint(lnglat, keyword) {
const longitude = this.getPointLng(lnglat);
const latitude = this.getPointLat(lnglat);
if (longitude === undefined || latitude === undefined) {
this.$message.warning('选点坐标无效');
return;
}
const point = this.toLngLat(longitude, latitude);
this.renderRouteMapMarker(point);
this.routeMapSelected = this.buildRouteMapSelection({
lng: longitude,
lat: latitude,
address: keyword,
});
this.routeMapStatus = '正在反查地址...';
this.ensureRouteAmapGeocoder()
.then(() => this.runAmapGeocode('address', point))
.then(result => {
const address = this.resolveMapAddress(result);
this.routeMapSelected = {
...this.routeMapSelected,
detailAddress: address.detailAddress || this.routeMapSelected.detailAddress,
regionName: address.regionName || this.routeMapSelected.regionName,
};
this.routeMapKeyword = this.routeMapSelected.detailAddress || this.routeMapKeyword;
this.routeMapStatus = this.routeMapSelected.detailAddress || '已选点,可确认回填';
})
.catch(() => {
this.routeMapStatus = '反查地址失败';
this.$message.error('反查地址失败,请重新选点');
});
},
renderRouteMapMarker(point) {
if (!this.routeAmap || !window.AMap) return;
if (this.routeAmapMarker) {
this.routeAmapMarker.setMap(null);
}
this.routeAmapMarker = new window.AMap.Marker({ position: point });
this.routeAmapMarker.setMap(this.routeAmap);
this.routeAmap.setCenter(point);
},
confirmRouteMapPick() {
if (!this.routeMapSelected.longitude) {
this.$message.warning('请先搜索或点击地图完成选点');
return;
}
const prefix = this.routeMapTarget;
this.form[`${prefix}Address`] =
this.routeMapSelected.detailAddress || this.form[`${prefix}Address`];
this.form[`${prefix}Name`] = this.routeMapSelected.regionName || this.form[`${prefix}Name`];
this.form[`${prefix}Longitude`] = this.routeMapSelected.longitude;
this.form[`${prefix}Latitude`] = this.routeMapSelected.latitude;
this.routeMapVisible = false;
this.$refs.crud?.validateField?.(`${prefix}Address`);
},
buildRouteMapSelection({ lng, lat, address, regionName }) {
return {
longitude: this.formatCoordinate(lng),
latitude: this.formatCoordinate(lat),
detailAddress: address || '',
regionName: regionName || '',
};
},
formatCoordinate(value) {
if (value === undefined || value === null || value === '') return '';
const numberValue = Number(value);
return Number.isFinite(numberValue) ? numberValue.toFixed(6) : '';
},
toLngLat(lng, lat) {
return new window.AMap.LngLat(Number(lng), Number(lat));
},
getPointLng(point) {
if (!point) return undefined;
if (typeof point.getLng === 'function') return point.getLng();
return point.lng ?? point.lon;
},
getPointLat(point) {
if (!point) return undefined;
if (typeof point.getLat === 'function') return point.getLat();
return point.lat;
},
ensureRouteAmapGeocoder() {
if (this.routeAmapGeocoder) return Promise.resolve(this.routeAmapGeocoder);
return new Promise((resolve, reject) => {
if (!window.AMap || !window.AMap.plugin) {
reject(new Error('高德地图组件未就绪'));
return;
}
window.AMap.plugin(['AMap.Geocoder'], () => {
try {
this.routeAmapGeocoder = new window.AMap.Geocoder();
resolve(this.routeAmapGeocoder);
} catch (error) {
reject(error);
}
});
});
},
runAmapGeocode(action, input) {
return new Promise((resolve, reject) => {
const timer = window.setTimeout(() => {
reject(new Error('高德地图请求超时'));
}, 10000);
const done = (status, result) => {
window.clearTimeout(timer);
if (status === 'complete' && result) {
resolve(result);
return;
}
reject(new Error('高德地图请求失败'));
};
try {
if (action === 'location') {
this.routeAmapGeocoder.getLocation(input, done);
} else {
this.routeAmapGeocoder.getAddress(input, done);
}
} catch (error) {
window.clearTimeout(timer);
reject(error);
}
});
},
resolveMapPoint(result) {
if (!result) return null;
const geocode = Array.isArray(result.geocodes) ? result.geocodes[0] : null;
if (geocode && geocode.location) return geocode.location;
if (result.location) return result.location;
if (result.lnglat) return result.lnglat;
if (result.getLng || result.lng || result.lon) return result;
return null;
},
resolveMapAddress(result = {}) {
const regeocode = result.regeocode || {};
const component = regeocode.addressComponent || {};
const city = Array.isArray(component.city) ? '' : component.city;
return {
detailAddress: regeocode.formattedAddress || '',
regionName: [component.province, city, component.district].filter(Boolean).join(''),
};
},
normalizeRow(row) {
const submitRow = { ...row };
Object.keys(submitRow).forEach(key => {
@@ -609,6 +947,27 @@ export default {
});
});
},
handleTemplate() {
NProgress.start();
exportBlob(
config.templateUrl,
{
[this.website.tokenHeader]: getToken(),
},
{ feedback: true }
)
.then(res => {
downloadXls(res.data, `${config.title}模板.xlsx`);
})
.finally(() => {
NProgress.done();
});
},
handleImport() {
const column = this.excelOptionConfig.column.find(item => item.prop === 'excelFile');
column.action = config.importUrl;
openImportDialog(this, config.title, () => this.onLoad(this.page, this.query));
},
},
};
</script>
@@ -650,5 +1009,31 @@ export default {
justify-content: flex-end;
margin-top: 14px;
}
&__map-toolbar {
display: flex;
gap: 8px;
margin-bottom: 12px;
.el-input {
flex: 1;
min-width: 0;
}
}
&__map {
width: 100%;
height: 420px;
border: 1px solid #eff1f7;
}
&__map-info {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-top: 10px;
color: #606266;
line-height: 1.6;
}
}
</style>

View File

@@ -24,7 +24,6 @@
<el-button
type="primary"
:icon="actionButtonLikeSearch ? undefined : 'el-icon-plus'"
:plain="!actionButtonLikeSearch"
v-if="canCreate"
@click="$refs.crud.rowAdd()"
>{{ config.createText || '新增' }}

View File

@@ -24,10 +24,9 @@
<el-button
type="primary"
icon="el-icon-plus"
plain
v-if="hasPermission('process_config_add')"
@click="$refs.crud.rowAdd()"
>
>建过程配置
</el-button>
<el-button
type="primary"
@@ -53,13 +52,23 @@
</el-tag>
</template>
<template #includedNodes="{ row }">
<span class="process-config-page__node-value">
{{ formatProcessNodes(row.includedNodes) }}
</span>
</template>
<template #basicInfo-form>
<div class="process-config-page__section">
<div class="dialog-section-title">基本信息</div>
<el-row :gutter="16">
<el-col :span="12">
<el-col :span="8">
<div class="process-config-page__field">
<span class="process-config-page__field-label">配置名称</span>
<span
class="process-config-page__field-label process-config-page__field-label--required"
>
配置名称
</span>
<el-input
v-model="form.configName"
:disabled="dialogReadonly"
@@ -68,9 +77,13 @@
/>
</div>
</el-col>
<el-col :span="12">
<el-col :span="8">
<div class="process-config-page__field">
<span class="process-config-page__field-label">项目</span>
<span
class="process-config-page__field-label process-config-page__field-label--required"
>
项目
</span>
<el-select
v-model="selectedProjectId"
clearable
@@ -92,33 +105,33 @@
</el-select>
</div>
</el-col>
<el-col :span="12">
<el-col :span="8">
<div class="process-config-page__field">
<span class="process-config-page__field-label">默认后台完成运输天数</span>
<span class="process-config-page__field-label">运输完成时限</span>
<div class="process-config-page__finish-days">
<span>默认</span>
<el-input
v-model="form.defaultFinishDays"
:disabled="dialogReadonly"
maxlength="3"
placeholder="X"
placeholder="请输入"
@input="handleFinishDaysInput"
/>
<span>天后完成运输</span>
<span>天后完成运输</span>
</div>
</div>
</el-col>
<el-col :span="12">
<el-col :span="24">
<div class="process-config-page__field">
<span class="process-config-page__field-label">备注</span>
<el-input
v-model="form.remark"
:disabled="dialogReadonly"
:rows="3"
maxlength="500"
placeholder="请输入"
show-word-limit
type="textarea"
:rows="4"
:disabled="dialogReadonly"
maxlength="500"
show-word-limit
placeholder="请输入"
/>
</div>
</el-col>
@@ -196,7 +209,7 @@
<el-radio-group
v-model="row.confirmMode"
:disabled="dialogReadonly || !row.enabled"
@change="syncNodeFields"
@change="handleReturnConfirmChange(row)"
>
<el-radio label="yes"></el-radio>
<el-radio label="no_confirm_complete">无需确认完成</el-radio>
@@ -390,6 +403,7 @@
<script>
import * as api from '@/api/business/process-config';
import { getList as getProjectList } from '@/api/business/project-apply';
import { getDeptTree } from '@/api/system/dept';
import { exportBlob } from '@/api/common';
import { config, option } from '@/option/business/process-config';
import { getToken } from '@/utils/auth';
@@ -513,11 +527,35 @@ export default {
created() {
this.resetNodeRows();
this.loadProjectOptions('');
this.initDeptOptions();
},
methods: {
hasPermission(code) {
return this.isAdmin || this.validData(this.permission && this.permission[code], false);
},
handleReturnConfirmChange(row) {
row.confirmInternal = row.confirmMode === 'yes';
this.syncNodeFields();
},
initDeptOptions() {
getDeptTree(this.userInfo.tenantId).then(res => {
const deptColumn = this.findColumn(this.option.column, 'searchDeptId');
if (deptColumn) {
deptColumn.dicData = this.flattenDept(res.data.data || []);
}
});
},
flattenDept(tree, level = 0) {
return tree.flatMap(item => [
{
label: `${' '.repeat(level)}${item.title || item.deptName || item.name}`,
value: item.id,
},
...(item.children && item.children.length
? this.flattenDept(item.children, level + 1)
: []),
]);
},
displayStatus(status) {
const statusMap = {
0: '草稿',
@@ -526,6 +564,13 @@ export default {
};
return statusMap[status] || status || '未知';
},
formatProcessNodes(nodes) {
return String(nodes || '')
.split(/[,]/)
.map(item => item.trim())
.filter(Boolean)
.join('-');
},
statusTagType(status) {
if (status === 1) return 'success';
if (status === 2) return 'info';
@@ -558,7 +603,7 @@ export default {
voucherTypes: [],
frequencyDays: '1',
timeStart: '00:00',
timeEnd: '24:00',
timeEnd: '23:59',
supportCargo: false,
supportVoucher: false,
voucherOptions: [],
@@ -705,7 +750,7 @@ export default {
result.push(`打卡定位:${node.location ? '是' : '否'}`);
if (node.punch) {
result.push(`打卡频次:每${node.frequencyDays || 1}天打卡1次`);
result.push(`打卡时段:${node.timeStart || '00:00'}-${node.timeEnd || '24:00'}`);
result.push(`打卡时段:${node.timeStart || '00:00'}-${node.timeEnd || '23:59'}`);
}
} else {
result.push(`打卡操作:${node.punch ? '是' : '否'}`);
@@ -744,9 +789,15 @@ export default {
this.$message.warning('项目不能为空');
return false;
}
if (row.defaultFinishDays && !/^[1-9]\d{0,2}$/.test(String(row.defaultFinishDays))) {
this.$message.warning('请输入正整数');
return false;
if (row.defaultFinishDays !== undefined && row.defaultFinishDays !== '') {
if (!Number.isInteger(Number(row.defaultFinishDays)) || Number(row.defaultFinishDays) < 0) {
this.$message.warning('完成天数不能小于0');
return false;
}
if (Number(row.defaultFinishDays) > 999) {
this.$message.warning('完成天数不能超过999');
return false;
}
}
if (row.remark && row.remark.length > 500) {
this.$message.warning('备注不能超过500个字符');
@@ -774,43 +825,61 @@ export default {
loading();
}
},
rowSave(row, done, loading) {
this.syncNodeFields();
const submitRow = this.normalizeRow(row);
if (!this.validateRow(submitRow)) {
this.stopSubmitLoading(loading);
return;
needsDuplicateVoucherConfirm() {
const signNode = this.nodeRows.find(item => item.key === 'sign');
const returnNode = this.nodeRows.find(item => item.key === 'return');
const hasSignVoucher =
signNode &&
signNode.enabled &&
signNode.uploadVoucher &&
signNode.voucherTypes.includes('签收单');
const hasReturnVoucher =
returnNode &&
returnNode.enabled &&
returnNode.uploadVoucher &&
returnNode.voucherTypes.includes('签收单');
return hasSignVoucher && hasReturnVoucher;
},
confirmDuplicateVoucher() {
if (!this.needsDuplicateVoucherConfirm()) {
return Promise.resolve();
}
api.submit(submitRow).then(
() => {
this.onLoad(this.page);
this.$message({ type: 'success', message: '操作成功!' });
done();
},
error => {
window.console.log(error);
this.stopSubmitLoading(loading);
return this.$confirm(
'签收与回单同时勾选了上传凭证,司机将需重复上传凭证,是否确认?',
'提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}
);
},
rowUpdate(row, index, done, loading) {
submitRow(row, done, loading) {
this.syncNodeFields();
const submitRow = this.normalizeRow(row);
if (!this.validateRow(submitRow)) {
this.stopSubmitLoading(loading);
return;
}
api.submit(submitRow).then(
() => {
this.confirmDuplicateVoucher()
.then(() => api.submit(submitRow))
.then(() => {
this.onLoad(this.page);
this.$message({ type: 'success', message: '操作成功!' });
done();
},
error => {
window.console.log(error);
})
.catch(error => {
if (error !== 'cancel' && error !== 'close') {
window.console.log(error);
}
this.stopSubmitLoading(loading);
}
);
});
},
rowSave(row, done, loading) {
this.submitRow(row, done, loading);
},
rowUpdate(row, index, done, loading) {
this.submitRow(row, done, loading);
},
rowDel(row) {
this.$confirm('确定将选择数据删除?', {
@@ -914,7 +983,11 @@ export default {
onLoad(page, params = {}) {
this.loading = true;
api
.getList(page.currentPage, page.pageSize, { ...params, ...this.query, allDept: 0 })
.getList(page.currentPage, page.pageSize, {
...params,
...this.query,
allDept: this.isAdmin ? 1 : 0,
})
.then(res => {
const result = res.data.data || {};
this.page.total = result.total || 0;
@@ -928,7 +1001,7 @@ export default {
buildExportParams() {
return {
...this.query,
allDept: 0,
allDept: this.isAdmin ? 1 : 0,
ids: this.ids,
[this.website.tokenHeader]: getToken(),
};
@@ -1004,6 +1077,17 @@ export default {
font-weight: 500;
text-align: right;
white-space: nowrap;
&--required::before {
margin-right: 4px;
color: #f56c6c;
content: '*';
}
}
&__node-value {
white-space: normal;
word-break: break-all;
}
&__finish-days {

View File

@@ -20,7 +20,6 @@
<el-button
type="primary"
icon="el-icon-plus"
plain
v-if="canMajorProjectSupplement"
@click="openProjectDialog('majorSupplement')"
>
@@ -29,7 +28,6 @@
<el-button
type="primary"
icon="el-icon-plus"
plain
v-if="canCreate"
@click="openProjectDialog('add')"
>
@@ -1568,7 +1566,11 @@ export default {
const loadingKey = type === '客户' ? 'customerLoading' : 'carrierLoading';
const optionsKey = type === '客户' ? 'customerOptions' : 'carrierOptions';
this[loadingKey] = true;
getCustomerArchiveList(1, 100, { customerType: type, status: 1 })
getCustomerArchiveList(1, 100, {
customerType: type,
status: 1,
...(type === '客户' ? { approvalStatus: 'approved' } : {}),
})
.then(res => {
const records = (res.data.data && res.data.data.records) || [];
const selectedOptions = this.buildCustomerOptionsFromRows(