diff --git a/src/api/business/waybill-manage.js b/src/api/business/waybill-manage.js index 316f053..2ab51d8 100644 --- a/src/api/business/waybill-manage.js +++ b/src/api/business/waybill-manage.js @@ -33,6 +33,25 @@ export const getPunchRecords = waybillId => method: 'get', params: { waybillId }, }); + +/** 运单车辆实时定位 */ +export const locateVehicle = id => + request({ + url: `${baseUrl}/locate`, + method: 'post', + params: { id }, + timeout: 60000, + }); + +/** 运单车辆历史轨迹 */ +export const trackVehicle = (id, startDate, endDate) => + request({ + url: `${baseUrl}/track`, + method: 'post', + params: { id, startDate, endDate }, + timeout: 60000, + }); + export const roadLoading = ids => request({ url: `${baseUrl}/road-loading`, diff --git a/src/api/system/business-process.js b/src/api/system/business-process.js new file mode 100644 index 0000000..3cfcd67 --- /dev/null +++ b/src/api/system/business-process.js @@ -0,0 +1,18 @@ +import request from '@/axios'; + +/** + * 调用 MK processSubmit 提交审核流 + * @param {Object} data + * @param {string} data.templateCode 模板编码 + * @param {string} data.submitIdentity 提交人(手机号) + * @param {string} data.loginName 登录账号(手机号) + * @param {string} data.formInstanceId 业务表单实例 id + * @param {string} [data.subject] 流程标题 + */ +export const processSubmit = data => { + return request({ + url: '/blade-system/businessProcess/processSubmit', + method: 'post', + data, + }); +}; diff --git a/src/api/system/dept.js b/src/api/system/dept.js index 7bf3f68..de1edf6 100644 --- a/src/api/system/dept.js +++ b/src/api/system/dept.js @@ -48,6 +48,32 @@ export const syncIamOrganizations = () => { }); }; +export const syncOaCompany = (current = 1, size = 20, signal) => { + return request({ + url: '/blade-system/dept/sync-oa-company', + method: 'post', + params: { + current, + size, + }, + timeout: 60000, + signal, + }); +}; + +export const syncOaDepartment = (current = 1, size = 20, signal) => { + return request({ + url: '/blade-system/dept/sync-oa-department', + method: 'post', + params: { + current, + size, + }, + timeout: 60000, + signal, + }); +}; + export const update = row => { return request({ url: '/blade-system/dept/submit', diff --git a/src/api/vehicle/customer-archive.js b/src/api/vehicle/customer-archive.js index 9d859f2..98e9f4c 100644 --- a/src/api/vehicle/customer-archive.js +++ b/src/api/vehicle/customer-archive.js @@ -22,6 +22,19 @@ export const getDetail = id => { }); }; +export const getPublicDetail = id => { + return request({ + url: '/blade-transport/customer-archive/public/detail', + method: 'get', + meta: { + isToken: false, + }, + params: { + id, + }, + }); +}; + export const getChangeRecordList = (customerId, current, size) => { return request({ url: '/blade-transport/customer-archive/change-record/list', @@ -34,6 +47,21 @@ export const getChangeRecordList = (customerId, current, size) => { }); }; +export const getPublicChangeRecordList = (customerId, current, size) => { + return request({ + url: '/blade-transport/customer-archive/public/change-record/list', + method: 'get', + meta: { + isToken: false, + }, + params: { + customerId, + current, + size, + }, + }); +}; + export const submit = row => { return request({ url: '/blade-transport/customer-archive/submit', diff --git a/src/option/base/measurement-unit.js b/src/option/base/measurement-unit.js index c135823..5f02982 100644 --- a/src/option/base/measurement-unit.js +++ b/src/option/base/measurement-unit.js @@ -38,6 +38,20 @@ export const createOption = () => ({ menuWidth: 240, menuFixed: 'right', column: [ + { + label: '计量单位编码', + prop: 'unitCode', + minWidth: 150, + search: true, + searchOrder: 4, + searchSpan: 6, + maxlength: 50, + showWordLimit: true, + rules: [ + { required: true, message: '请输入计量单位编码', trigger: 'blur' }, + { max: 50, message: '计量单位编码不能超过50个字', trigger: 'blur' }, + ], + }, { label: '计量单位', prop: 'unitName', diff --git a/src/router/page/index.js b/src/router/page/index.js index 9110d5c..3b8f319 100644 --- a/src/router/page/index.js +++ b/src/router/page/index.js @@ -74,6 +74,16 @@ export default [ isAuth: false, }, }, + { + path: '/vehicle/customer-archive/public-view', + name: '查看客商信息', + component: () => import('@/views/vehicle/customer-archive-public-view.vue'), + meta: { + keepAlive: false, + isTab: false, + isAuth: false, + }, + }, { path: '/', name: '主页', diff --git a/src/views/base/measurement-unit.vue b/src/views/base/measurement-unit.vue index 11d1181..ebd7613 100644 --- a/src/views/base/measurement-unit.vue +++ b/src/views/base/measurement-unit.vue @@ -119,6 +119,7 @@ export default { return this.isAdmin || this.permission?.[code] === true; }, normalizeRow(row) { + row.unitCode = String(row.unitCode || '').trim(); row.unitName = String(row.unitName || '').trim(); row.dimension = String(row.dimension || '').trim(); row.remark = String(row.remark || '').trim(); diff --git a/src/views/business/components/billing-plan-editor.vue b/src/views/business/components/billing-plan-editor.vue index 2984093..6fa3275 100644 --- a/src/views/business/components/billing-plan-editor.vue +++ b/src/views/business/components/billing-plan-editor.vue @@ -157,12 +157,19 @@ @@ -3029,7 +3121,7 @@ import { getList as getProcessConfigList, getVoucherImages as getProcessConfigVoucherImages, } from '@/api/business/process-config'; -import { getPunchRecords as getWaybillPunchRecords } from '@/api/business/waybill-manage'; +import { getPunchRecords as getWaybillPunchRecords, locateVehicle, trackVehicle } from '@/api/business/waybill-manage'; import { getList as getDriverList } from '@/api/transportCapacity/driver'; import { getDictionary } from '@/api/system/dictbiz'; import { getDictionary as getSystemDictionary } from '@/api/system/dict'; @@ -3292,6 +3384,21 @@ export default { waybillRouteChangeRecords: [], waybillRouteChangeDragIndex: -1, waybillRouteChangeSaving: false, + waybillLocateLoading: false, + waybillLocateInfo: null, + waybillLocateHint: '', + waybillLocateMapInstance: null, + waybillLocateMarker: null, + waybillLocateInfoWindow: null, + waybillTrackMode: '', + waybillTrackLoading: false, + waybillTrackInfo: null, + waybillTrackHint: '', + waybillTrackDateRange: [], + waybillTrackMapInstance: null, + waybillTrackPolyline: null, + waybillTrackStartMarker: null, + waybillTrackEndMarker: null, mileageDialog: { visible: false, submitting: false, @@ -4523,6 +4630,13 @@ export default { }); }, closeDetail() { + this.destroyWaybillLocateMap(); + this.destroyWaybillTrackMap(); + this.waybillTrackMode = ''; + this.waybillLocateInfo = null; + this.waybillLocateHint = ''; + this.waybillTrackInfo = null; + this.waybillTrackHint = ''; if (this.isStandaloneWaybillDetailPage) { this.$router.$avueRouter?.closeTag?.(); this.$router.push({ path: '/business/waybill-manage', query: {} }); @@ -4867,7 +4981,262 @@ export default { } }, handleWaybillTrackAction(action) { - this.$message.info(action === 'playback' ? '暂无可回放的物流轨迹' : '暂无车辆实时定位数据'); + if (action === 'playback') { + this.destroyWaybillLocateMap(); + this.waybillTrackMode = 'playback'; + this.waybillLocateInfo = null; + this.waybillLocateHint = ''; + if (!Array.isArray(this.waybillTrackDateRange) || this.waybillTrackDateRange.length !== 2) { + this.waybillTrackDateRange = this.buildDefaultTrackDateRange(); + } + this.loadWaybillTrack(); + return; + } + this.destroyWaybillTrackMap(); + this.waybillTrackMode = 'locate'; + this.waybillTrackInfo = null; + this.waybillTrackHint = ''; + this.loadWaybillLocate(); + }, + buildDefaultTrackDateRange() { + const pad = value => String(value).padStart(2, '0'); + const formatDate = date => + `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`; + const today = new Date(); + const yesterday = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1); + return [formatDate(yesterday), formatDate(today)]; + }, + destroyWaybillLocateMap() { + if (this.waybillLocateMarker) { + this.waybillLocateMarker.setMap(null); + this.waybillLocateMarker = null; + } + if (this.waybillLocateInfoWindow) { + this.waybillLocateInfoWindow.close(); + this.waybillLocateInfoWindow = null; + } + if (this.waybillLocateMapInstance) { + this.waybillLocateMapInstance.destroy(); + this.waybillLocateMapInstance = null; + } + }, + destroyWaybillTrackMap() { + if (this.waybillTrackPolyline) { + this.waybillTrackPolyline.setMap(null); + this.waybillTrackPolyline = null; + } + if (this.waybillTrackStartMarker) { + this.waybillTrackStartMarker.setMap(null); + this.waybillTrackStartMarker = null; + } + if (this.waybillTrackEndMarker) { + this.waybillTrackEndMarker.setMap(null); + this.waybillTrackEndMarker = null; + } + if (this.waybillTrackMapInstance) { + this.waybillTrackMapInstance.destroy(); + this.waybillTrackMapInstance = null; + } + }, + async loadWaybillLocate() { + const waybillId = this.detailRow?.id; + if (!waybillId) { + this.$message.warning('运单信息不完整'); + return; + } + if (!this.detailRow.vehicleNo) { + this.$message.warning('运单未绑定车牌号,无法实时定位'); + return; + } + this.waybillLocateLoading = true; + this.waybillLocateHint = '正在获取车辆实时定位...'; + this.waybillLocateInfo = null; + try { + const locateApi = + typeof this.api.locateVehicle === 'function' ? this.api.locateVehicle : locateVehicle; + const res = await locateApi(waybillId); + const data = res?.data?.data || null; + if (!data || data.longitude == null || data.latitude == null) { + this.waybillLocateInfo = null; + this.waybillLocateHint = '暂无车辆实时定位数据'; + this.$message.warning('暂无车辆实时定位数据'); + return; + } + this.waybillLocateInfo = data; + this.waybillLocateHint = ''; + await this.$nextTick(); + await this.renderWaybillLocateMap(data); + } catch (error) { + this.waybillLocateInfo = null; + this.waybillLocateHint = '实时定位获取失败'; + this.$message.error(error?.message || '实时定位获取失败'); + } finally { + this.waybillLocateLoading = false; + } + }, + async loadWaybillTrack() { + const waybillId = this.detailRow?.id; + if (!waybillId) { + this.$message.warning('运单信息不完整'); + return; + } + if (!this.detailRow.vehicleNo) { + this.$message.warning('运单未绑定车牌号,无法查询历史轨迹'); + return; + } + if (!Array.isArray(this.waybillTrackDateRange) || this.waybillTrackDateRange.length !== 2) { + this.waybillTrackDateRange = this.buildDefaultTrackDateRange(); + } + const [startDate, endDate] = this.waybillTrackDateRange; + this.waybillTrackLoading = true; + this.waybillTrackHint = '正在获取历史轨迹...'; + this.destroyWaybillTrackMap(); + try { + const trackApi = + typeof this.api.trackVehicle === 'function' ? this.api.trackVehicle : trackVehicle; + const res = await trackApi(waybillId, startDate, endDate); + const data = res?.data?.data || null; + const points = Array.isArray(data?.points) ? data.points : []; + if (!data || points.length === 0) { + this.waybillTrackInfo = data || { total: 0, points: [] }; + this.waybillTrackHint = '暂无可回放的物流轨迹'; + this.$message.warning('暂无可回放的物流轨迹'); + return; + } + this.waybillTrackInfo = data; + this.waybillTrackHint = ''; + await this.$nextTick(); + await this.renderWaybillTrackMap(points); + } catch (error) { + this.waybillTrackInfo = null; + this.waybillTrackHint = '历史轨迹获取失败'; + this.$message.error(error?.message || '历史轨迹获取失败'); + } finally { + this.waybillTrackLoading = false; + } + }, + async renderWaybillLocateMap(locateInfo) { + const longitude = Number(locateInfo?.longitude); + const latitude = Number(locateInfo?.latitude); + if (!Number.isFinite(longitude) || !Number.isFinite(latitude)) { + this.$message.warning('定位坐标无效,无法在地图上展示'); + return; + } + try { + await this.loadAmap(); + await this.$nextTick(); + const container = this.$refs.waybillLocateMap; + if (!container || !window.AMap) { + this.$message.warning('高德地图容器未就绪'); + return; + } + this.destroyWaybillLocateMap(); + this.waybillLocateMapInstance = new window.AMap.Map(container, { + zoom: 15, + center: [longitude, latitude], + viewMode: '2D', + resizeEnable: true, + }); + const content = [ + `
`, + `
${locateInfo.vehicleNo || '车辆位置'}
`, + locateInfo.locateTime ? `
时间:${locateInfo.locateTime}
` : '', + locateInfo.address ? `
地址:${locateInfo.address}
` : '', + `
坐标:${longitude}, ${latitude}
`, + `
`, + ].join(''); + this.waybillLocateInfoWindow = new window.AMap.InfoWindow({ + content, + offset: new window.AMap.Pixel(0, -30), + }); + this.waybillLocateMarker = new window.AMap.Marker({ + position: [longitude, latitude], + title: locateInfo.vehicleNo || '车辆位置', + anchor: 'bottom-center', + }); + this.waybillLocateMarker.on('click', () => { + this.waybillLocateInfoWindow.open(this.waybillLocateMapInstance, [longitude, latitude]); + }); + this.waybillLocateMapInstance.add(this.waybillLocateMarker); + this.waybillLocateInfoWindow.open(this.waybillLocateMapInstance, [longitude, latitude]); + this.waybillLocateMapInstance.setFitView([this.waybillLocateMarker], false, [40, 40, 40, 40]); + setTimeout(() => { + this.waybillLocateMapInstance?.resize?.(); + }, 80); + } catch (error) { + window.console.warn('实时定位地图渲染失败', error); + this.$message.error('高德地图渲染失败,请稍后重试'); + } + }, + async renderWaybillTrackMap(points) { + const path = (points || []) + .map(item => [Number(item.longitude), Number(item.latitude)]) + .filter(item => Number.isFinite(item[0]) && Number.isFinite(item[1])); + if (!path.length) { + this.$message.warning('轨迹坐标无效,无法在地图上展示'); + return; + } + try { + await this.loadAmap(); + await this.$nextTick(); + const container = this.$refs.waybillTrackMap; + if (!container || !window.AMap) { + this.$message.warning('高德地图容器未就绪'); + return; + } + this.destroyWaybillTrackMap(); + this.waybillTrackMapInstance = new window.AMap.Map(container, { + zoom: 12, + center: path[0], + viewMode: '2D', + resizeEnable: true, + }); + this.waybillTrackPolyline = new window.AMap.Polyline({ + path, + strokeColor: '#409eff', + strokeWeight: 6, + strokeOpacity: 0.9, + lineJoin: 'round', + lineCap: 'round', + showDir: path.length > 1, + }); + this.waybillTrackStartMarker = new window.AMap.Marker({ + position: path[0], + title: '起点', + anchor: 'bottom-center', + label: { + content: '起', + direction: 'top', + offset: new window.AMap.Pixel(0, -6), + }, + }); + this.waybillTrackEndMarker = new window.AMap.Marker({ + position: path[path.length - 1], + title: '终点', + anchor: 'bottom-center', + label: { + content: '终', + direction: 'top', + offset: new window.AMap.Pixel(0, -6), + }, + }); + this.waybillTrackMapInstance.add([ + this.waybillTrackPolyline, + this.waybillTrackStartMarker, + this.waybillTrackEndMarker, + ]); + this.waybillTrackMapInstance.setFitView( + [this.waybillTrackPolyline, this.waybillTrackStartMarker, this.waybillTrackEndMarker], + false, + [48, 48, 48, 48] + ); + setTimeout(() => { + this.waybillTrackMapInstance?.resize?.(); + }, 80); + } catch (error) { + window.console.warn('历史轨迹地图渲染失败', error); + this.$message.error('高德地图渲染失败,请稍后重试'); + } }, displayStatus(row, prop) { const formatStatus = this.config.formatStatus; @@ -9553,6 +9922,81 @@ export default { border: 1px solid #eff1f7; } + &__waybill-locate { + position: relative; + display: flex; + flex-direction: column; + gap: 10px; + } + + &__waybill-locate-meta { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 8px 16px; + padding: 10px 12px; + border: 1px solid #eff1f7; + background: #fafafa; + color: #606266; + font-size: 13px; + + span { + margin-right: 8px; + color: #909399; + } + + strong { + color: #303133; + font-weight: 600; + } + } + + &__waybill-locate-address { + grid-column: 1 / -1; + } + + &__waybill-locate-map { + width: 100%; + min-height: 320px; + height: 320px; + border: 1px solid #eff1f7; + background: #f5f7fa; + } + + &__waybill-locate-map--track { + min-height: 420px; + height: 420px; + } + + &__waybill-map-tip { + position: absolute; + left: 50%; + top: 50%; + z-index: 2; + transform: translate(-50%, -50%); + padding: 8px 14px; + border-radius: 4px; + background: rgba(255, 255, 255, 0.92); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08); + color: #909399; + font-size: 13px; + text-align: center; + pointer-events: none; + } + + &__waybill-track-toolbar { + display: flex; + flex-wrap: wrap; + gap: 10px; + align-items: center; + margin-bottom: 10px; + color: #606266; + font-size: 13px; + } + + &__waybill-track-total { + color: #909399; + } + &__waybill-track-actions { display: flex; gap: 8px; diff --git a/src/views/business/project-apply.vue b/src/views/business/project-apply.vue index 3f62e96..fe2b8e2 100644 --- a/src/views/business/project-apply.vue +++ b/src/views/business/project-apply.vue @@ -1116,6 +1116,10 @@ export default { total: 0, }, selectionList: [], + // 表单页实例标记:创建时按路由落定,不随 keep-alive 切走后的 $route 变化翻转。 + // 否则 isProjectFormPage 变 false 后容器会从 div 切成 el-dialog(append-to-body), + // 盖住后续打开的页面(如客商档案)。 + isFormPageInstance: false, projectBox: false, dialogType: 'add', dialogReadonly: false, @@ -1308,13 +1312,14 @@ export default { return ['add', 'majorSupplement'].includes(this.dialogType); }, isProjectFormPage() { - return this.$route.path === '/business/project-apply/form'; + return this.isFormPageInstance; }, projectFormContainer() { - return this.isProjectFormPage ? 'div' : 'el-dialog'; + // 表单页实例始终用页面容器,避免 keep-alive 失活时误切弹窗 + return this.isFormPageInstance ? 'div' : 'el-dialog'; }, projectFormContainerProps() { - if (this.isProjectFormPage) return { class: 'project-apply-page-form' }; + if (this.isFormPageInstance) return { class: 'project-apply-page-form' }; return { modelValue: this.projectBox, title: this.projectDialogTitle, @@ -1359,11 +1364,26 @@ export default { this.loadCargoTypeOptions(); this.loadTransportTypeOptions(); this.loadSettlementModeOptions(); - if (this.isProjectFormPage) { + if (this.$route.path === '/business/project-apply/form') { + this.isFormPageInstance = true; this.openProjectFormPage(); } }, + // 标签切走(keep-alive 缓存)或销毁时,收起 append-to-body 的内层弹窗, + // 避免 Teleport 出去的 DOM 继续盖住后续页面。 + deactivated() { + this.closeInnerDialogs(); + }, + beforeUnmount() { + this.closeInnerDialogs(); + }, methods: { + closeInnerDialogs() { + this.changeRecordDetailVisible = false; + this.attachmentDocumentPreviewVisible = false; + this.attachmentImagePreviewVisible = false; + this.userBox = false; + }, buildTableOption() { return { ...option, diff --git a/src/views/system/dept.vue b/src/views/system/dept.vue index 9004b7e..e30e593 100644 --- a/src/views/system/dept.vue +++ b/src/views/system/dept.vue @@ -30,6 +30,14 @@ @click="handleDelete" >删除 + 自动同步组织 + @@ -127,6 +175,8 @@ import { add, getDept, getDeptTree, + syncOaCompany, + syncOaDepartment, } from '@/api/system/dept'; import { getLeaderList } from '@/api/system/user'; import { getList as getCustomerArchiveList } from '@/api/vehicle/customer-archive'; @@ -159,6 +209,20 @@ export default { selectionList: [], query: {}, loading: true, + oaSyncLoading: false, + oaSyncVisible: false, + oaSyncRunning: false, + oaSyncCancelled: false, + oaSyncStatus: 'running', + oaSyncStage: 'company', + oaSyncController: null, + oaSyncProgress: { + current: 0, + size: 20, + total: 0, + synced: 0, + skipped: 0, + }, parentId: 0, page: { pageSize: 10, @@ -443,8 +507,153 @@ export default { }); return ids.join(','); }, + oaSyncDialogTitle() { + if (this.oaSyncStatus === 'done') { + return '同步完成'; + } + if (this.oaSyncStatus === 'cancelled') { + return '已取消同步'; + } + if (this.oaSyncStatus === 'error') { + return '同步失败'; + } + return '自动同步组织'; + }, + oaSyncStageLabel() { + return this.oaSyncStage === 'department' ? '同步部门' : '同步公司'; + }, + oaSyncTotalPage() { + const total = Number(this.oaSyncProgress.total) || 0; + const size = Number(this.oaSyncProgress.size) || 20; + if (total <= 0) { + return this.oaSyncProgress.current || 0; + } + return Math.max(1, Math.ceil(total / size)); + }, + oaSyncPercent() { + if (this.oaSyncStatus === 'done') { + return 100; + } + const totalPage = this.oaSyncTotalPage; + const current = Number(this.oaSyncProgress.current) || 0; + const stageBase = this.oaSyncStage === 'department' ? 50 : 0; + if (totalPage <= 0) { + return stageBase; + } + const stagePercent = Math.min(50, Math.round((current / totalPage) * 50)); + return Math.min(99, stageBase + stagePercent); + }, + oaSyncProgressStatus() { + if (this.oaSyncStatus === 'done') { + return 'success'; + } + if (this.oaSyncStatus === 'error') { + return 'exception'; + } + return undefined; + }, }, methods: { + handleOaOrgSync() { + this.$confirm('确定从OA先同步公司、再同步部门?', '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }).then(() => { + this.startOaOrgSync(); + }); + }, + startOaOrgSync() { + this.oaSyncLoading = true; + this.oaSyncVisible = true; + this.oaSyncRunning = true; + this.oaSyncCancelled = false; + this.oaSyncStatus = 'running'; + this.oaSyncStage = 'company'; + this.oaSyncController = new AbortController(); + this.oaSyncProgress = { + current: 0, + size: 20, + total: 0, + synced: 0, + skipped: 0, + }; + this.runOaOrgSyncPages(); + }, + isOaSyncCanceledError(error) { + return ( + this.oaSyncCancelled || + error?.code === 'ERR_CANCELED' || + error?.name === 'CanceledError' || + error?.name === 'AbortError' + ); + }, + async runOaOrgSyncStage(syncApi) { + const size = 20; + let current = 1; + while (!this.oaSyncCancelled) { + const res = await syncApi(current, size, this.oaSyncController?.signal); + const page = res?.data?.data || {}; + this.oaSyncProgress.current = page.current || current; + this.oaSyncProgress.size = page.size || size; + this.oaSyncProgress.total = page.total || 0; + this.oaSyncProgress.synced += page.syncedCount || 0; + this.oaSyncProgress.skipped += page.skippedCount || 0; + if (page.finished) { + break; + } + current += 1; + } + }, + async runOaOrgSyncPages() { + try { + this.oaSyncStage = 'company'; + await this.runOaOrgSyncStage(syncOaCompany); + if (this.oaSyncCancelled) { + this.oaSyncStatus = 'cancelled'; + return; + } + this.oaSyncStage = 'department'; + this.oaSyncProgress.current = 0; + this.oaSyncProgress.total = 0; + await this.runOaOrgSyncStage(syncOaDepartment); + if (this.oaSyncCancelled) { + this.oaSyncStatus = 'cancelled'; + return; + } + this.oaSyncStatus = 'done'; + } catch (error) { + if (this.isOaSyncCanceledError(error)) { + this.oaSyncStatus = 'cancelled'; + } else { + this.oaSyncStatus = 'error'; + this.$message.error(error?.message || 'OA组织同步失败'); + } + } finally { + this.oaSyncRunning = false; + this.oaSyncLoading = false; + if (this.oaSyncStatus === 'done' || this.oaSyncStatus === 'cancelled') { + this.parentId = 0; + this.data = []; + this.$refs.crud?.refreshTable?.(); + this.onLoad(this.page, this.query); + } + } + }, + cancelOaSync() { + if (!this.oaSyncRunning) { + return; + } + this.oaSyncCancelled = true; + this.oaSyncController?.abort(); + }, + closeOaSyncDialog() { + if (this.oaSyncRunning) { + this.cancelOaSync(); + return; + } + this.oaSyncVisible = false; + }, initData(tenantId) { getDeptTree(tenantId).then(res => { const column = this.findColumn(this.option.column, 'parentId'); @@ -865,3 +1074,66 @@ export default { color: var(--el-color-danger-light-3); } + + diff --git a/src/views/vehicle/customer-archive-public-view.vue b/src/views/vehicle/customer-archive-public-view.vue new file mode 100644 index 0000000..8fb5734 --- /dev/null +++ b/src/views/vehicle/customer-archive-public-view.vue @@ -0,0 +1,88 @@ + + + + + + + diff --git a/src/views/vehicle/customer-archive.vue b/src/views/vehicle/customer-archive.vue index 1325abc..967f2c9 100644 --- a/src/views/vehicle/customer-archive.vue +++ b/src/views/vehicle/customer-archive.vue @@ -1,5 +1,5 @@