运营段修改
This commit is contained in:
parent
b4cc51c1d1
commit
59f490f323
23
.deployrc.js
Normal file
23
.deployrc.js
Normal file
@ -0,0 +1,23 @@
|
||||
// .deployrc.js (ESM 格式)
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
export default {
|
||||
host: '112.74.106.216',
|
||||
port: 22, // 默认 SSH 端口
|
||||
username: 'root',
|
||||
|
||||
// 密码和私钥二选一
|
||||
password: 'Smt1618?',
|
||||
privateKey: null, // 示例: readFileSync(resolve(process.env.HOME, '.ssh/id_rsa')),
|
||||
|
||||
// 部署路径
|
||||
remotePath: '/opt/1panel/apps/openresty/openresty/www/sites/www.amzups.com/index',
|
||||
|
||||
// 是否清空目标目录
|
||||
cleanRemote: true
|
||||
|
||||
// 高级选项 (可选)
|
||||
// uploadIgnore: ['*.map', 'tmp/*'],
|
||||
// execAfterDeploy: 'sudo systemctl restart nginx'
|
||||
};
|
@ -7,6 +7,10 @@ VITE_APP_ENV = 'development'
|
||||
# 开发环境
|
||||
VITE_APP_BASE_API = '/dev-api'
|
||||
|
||||
VITE_BACKEND_URL = 'http://localhost:8080'
|
||||
|
||||
#VITE_BACKEND_URL = 'http://112.74.106.216:8080'
|
||||
|
||||
# 应用访问路径 例如使用前缀 /admin/
|
||||
VITE_APP_CONTEXT_PATH = '/'
|
||||
|
||||
|
@ -16,6 +16,8 @@ VITE_APP_SNAILJOB_ADMIN = '/snail-job'
|
||||
# 生产环境
|
||||
VITE_APP_BASE_API = '/prod-api'
|
||||
|
||||
VITE_BACKEND_URL = 'http://112.74.106.216:8080'
|
||||
|
||||
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
||||
VITE_BUILD_COMPRESS = gzip
|
||||
|
||||
|
90
deploy.js
Normal file
90
deploy.js
Normal file
@ -0,0 +1,90 @@
|
||||
import { NodeSSH } from 'node-ssh';
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs';
|
||||
import process from 'node:process';
|
||||
|
||||
// 动态导入配置文件(支持文件不存在的情况)
|
||||
const loadConfig = async () => {
|
||||
try {
|
||||
const { default: config } = await import('./.deployrc.js');
|
||||
return config;
|
||||
} catch (error) {
|
||||
if (error.code !== 'ERR_MODULE_NOT_FOUND') throw error;
|
||||
|
||||
return {
|
||||
host: process.env.DEPLOY_HOST,
|
||||
port: process.env.DEPLOY_PORT || 22,
|
||||
username: process.env.DEPLOY_USER,
|
||||
password: process.env.DEPLOY_PASSWORD,
|
||||
privateKey: process.env.DEPLOY_PRIVATE_KEY_PATH ? fs.readFileSync(path.resolve(process.env.DEPLOY_PRIVATE_KEY_PATH)) : null,
|
||||
remotePath: process.env.DEPLOY_REMOTE_PATH,
|
||||
cleanRemote: process.env.DEPLOY_CLEAN === 'true'
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const ssh = new NodeSSH();
|
||||
|
||||
async function deploy() {
|
||||
try {
|
||||
// 加载配置
|
||||
const config = await loadConfig();
|
||||
validateConfig(config);
|
||||
|
||||
// 连接服务器
|
||||
console.log('🔄 Connecting to server...');
|
||||
await ssh.connect({
|
||||
host: config.host,
|
||||
port: config.port,
|
||||
username: config.username,
|
||||
password: config.password,
|
||||
privateKey: config.privateKey
|
||||
});
|
||||
|
||||
// 确保目录存在
|
||||
console.log('📂 Ensuring remote directory exists...');
|
||||
await ssh.execCommand(`mkdir -p ${config.remotePath}`);
|
||||
|
||||
// 清理目录
|
||||
if (config.cleanRemote) {
|
||||
console.log('🧹 Cleaning remote directory...');
|
||||
await ssh.execCommand(`rm -rf ${config.remotePath}/*`);
|
||||
}
|
||||
|
||||
// 上传文件
|
||||
console.log('🚀 Uploading files...');
|
||||
const uploadResult = await ssh.putDirectory('./dist', config.remotePath, {
|
||||
recursive: true,
|
||||
concurrency: 10,
|
||||
tick: (localPath, remotePath, error) => {
|
||||
const relativePath = path.relative(process.cwd(), localPath);
|
||||
console[error ? 'error' : 'log'](`${error ? '❌' : '✅'} ${error ? 'Failed' : 'Uploaded'}: ${relativePath}`);
|
||||
}
|
||||
});
|
||||
|
||||
if (!uploadResult) throw new Error('Upload failed without specific error');
|
||||
|
||||
console.log('🎉 Deployment completed successfully!');
|
||||
} catch (error) {
|
||||
console.error('🔥 Deployment failed:', error.message);
|
||||
process.exit(1);
|
||||
} finally {
|
||||
ssh.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
function validateConfig(config) {
|
||||
const requiredFields = ['host', 'username', 'remotePath'];
|
||||
const missing = requiredFields.filter((field) => !config[field]);
|
||||
|
||||
if (missing.length) {
|
||||
throw new Error(`Missing required config fields: ${missing.join(', ')}`);
|
||||
}
|
||||
|
||||
if (!config.password && !config.privateKey) {
|
||||
throw new Error('Either password or privateKey must be provided');
|
||||
}
|
||||
}
|
||||
|
||||
// 执行部署
|
||||
deploy();
|
@ -60,6 +60,8 @@ export default [
|
||||
globals: {
|
||||
// 自动导入的配置 undef
|
||||
...autoImportGlobals.globals,
|
||||
process: 'readonly',
|
||||
require: 'readonly',
|
||||
DialogOption: 'readonly',
|
||||
LayoutSetting: 'readonly'
|
||||
}
|
||||
|
@ -9,6 +9,8 @@
|
||||
"scripts": {
|
||||
"dev": "vite serve --mode development",
|
||||
"build:prod": "vite build --mode production",
|
||||
"deploy": "node deploy.js",
|
||||
"build-and-deploy": "npm run build:prod && npm run deploy",
|
||||
"build:dev": "vite build --mode development",
|
||||
"preview": "vite preview",
|
||||
"lint:eslint": "eslint",
|
||||
@ -40,6 +42,7 @@
|
||||
"image-conversion": "2.1.1",
|
||||
"js-cookie": "3.0.5",
|
||||
"jsencrypt": "3.3.2",
|
||||
"node-ssh": "^13.2.1",
|
||||
"nprogress": "0.2.0",
|
||||
"pinia": "2.2.6",
|
||||
"screenfull": "6.0.2",
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 4.1 KiB |
@ -29,7 +29,7 @@ export const getInquiryRequest = (id: string | number): AxiosPromise<InquiryRequ
|
||||
});
|
||||
};
|
||||
|
||||
export const createWithDesAndChannel = (destination: string, channelId: string, date: string): AxiosPromise<void> => {
|
||||
export const createWithDesAndChannel = (destination: string | number, channelId: string, date: string): AxiosPromise<void> => {
|
||||
return request({
|
||||
url: '/amz/inquiryRequest/create/' + destination + '/' + channelId + '/' + date,
|
||||
method: 'get'
|
||||
@ -44,7 +44,7 @@ export const createWithDesAndChannel = (destination: string, channelId: string,
|
||||
* @param date
|
||||
*/
|
||||
|
||||
export const queryWithDesAndChannel = (destination: string, channelId: string, date: string): AxiosPromise<LogisticsQuoteVO[]> => {
|
||||
export const queryWithDesAndChannel = (destination: string | number, channelId: string, date: string): AxiosPromise<LogisticsQuoteVO[]> => {
|
||||
return request({
|
||||
url: '/amz/inquiryRequest/query/' + destination + '/' + channelId + '/' + date,
|
||||
method: 'get'
|
||||
|
@ -1,6 +1,6 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { LogisticsOrderVO, LogisticsOrderForm, LogisticsOrderQuery, createOrderForm } from '@/api/amz/logisticsOrder/types';
|
||||
import { LogisticsOrderVO, LogisticsOrderForm, LogisticsOrderQuery, createOrderForm, InquiryQuoteStatusVO } from '@/api/amz/logisticsOrder/types';
|
||||
|
||||
/**
|
||||
* 查询物流订单列表
|
||||
@ -20,13 +20,24 @@ export const listLogisticsOrder = (query?: LogisticsOrderQuery): AxiosPromise<Lo
|
||||
* 查询物流订单详细
|
||||
* @param id
|
||||
*/
|
||||
export const getLogisticsOrder = (id: string | number): AxiosPromise<LogisticsOrderVO> => {
|
||||
export const getLogisticsOrder = (id: string | number): AxiosPromise<InquiryQuoteStatusVO> => {
|
||||
return request({
|
||||
url: '/amz/logisticsOrder/' + id,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
// /**
|
||||
// * 查询物流订单详细
|
||||
// * @param id
|
||||
// */
|
||||
// export const getTodayQuoteStatus = (): AxiosPromise<InquiryQuoteStatusVO[]> => {
|
||||
// return request({
|
||||
// url: '/amz/logisticsOrder/today-quote-status',
|
||||
// method: 'get'
|
||||
// });
|
||||
// };
|
||||
|
||||
/**
|
||||
* 新增物流订单
|
||||
* @param data
|
||||
|
@ -55,6 +55,18 @@ export interface LogisticsOrderVO {
|
||||
shelfTimeliness: number;
|
||||
}
|
||||
|
||||
export interface InquiryQuoteStatusVO {
|
||||
// private Long inquiryId;
|
||||
// private String inquiryNo;
|
||||
// private Long providerId;
|
||||
// private String quoteStatus; // "已报价" 或 "未报价"
|
||||
|
||||
inquiryId: string | number;
|
||||
inquiryNo: string;
|
||||
providerId: string | number;
|
||||
quoteStatus: string;
|
||||
}
|
||||
|
||||
export interface LogisticsOrderForm extends BaseEntity {
|
||||
/**
|
||||
* 主键(应用层生成的全局唯一ID,如雪花算法)
|
||||
@ -84,7 +96,7 @@ export interface LogisticsOrderForm extends BaseEntity {
|
||||
/**
|
||||
* 物流渠道(如空运/海运/快递等)
|
||||
*/
|
||||
logisticsChannel?: string;
|
||||
channelName?: string;
|
||||
|
||||
/**
|
||||
* 目的地仓库名称或编码
|
||||
|
@ -1,6 +1,8 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { LogisticsQuoteVO, LogisticsQuoteForm, LogisticsQuoteQuery } from '@/api/amz/logisticsQuote/types';
|
||||
import { InquiryQuoteStatusVO } from '@/api/amz/logisticsOrder/types';
|
||||
import { UnwrapRef } from 'vue';
|
||||
|
||||
/**
|
||||
* 查询物流报价列表
|
||||
@ -24,7 +26,7 @@ export const listLogisticsQuote = (query?: LogisticsQuoteQuery): AxiosPromise<Lo
|
||||
* @param date
|
||||
*/
|
||||
|
||||
export const queryLogisticsQuote = (destination: string, channelId: string, date: string): AxiosPromise<LogisticsQuoteVO[]> => {
|
||||
export const queryLogisticsQuote = (destination: string | number, channelId: string, date: string): AxiosPromise<LogisticsQuoteVO[]> => {
|
||||
return request({
|
||||
url: '/amz/logisticsQuote/query/' + destination + '/' + channelId + '/' + date,
|
||||
method: 'get'
|
||||
@ -46,7 +48,7 @@ export const getLogisticsQuote = (id: string | number): AxiosPromise<LogisticsQu
|
||||
* 查询 今天的报价情况
|
||||
* @param id
|
||||
*/
|
||||
export const getTodayQuoteStatus = () => {
|
||||
export const getTodayQuoteStatus = (): AxiosPromise<InquiryQuoteStatusVO[]> => {
|
||||
return request({
|
||||
url: '/amz/logisticsQuote/today-quote-status',
|
||||
method: 'get'
|
||||
@ -77,6 +79,18 @@ export const addMostLogisticsQuote = (data: LogisticsQuoteForm) => {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取物流报价建议
|
||||
* @param data
|
||||
*/
|
||||
export const checkPriceQuoteByBo = (data: LogisticsQuoteForm) => {
|
||||
return request({
|
||||
url: '/amz/logisticsQuote/check-quote-price',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改物流报价
|
||||
* @param data
|
||||
|
@ -16,6 +16,14 @@ export const listShipmentPlan = (query?: ShipmentPlanQuery): AxiosPromise<Shipme
|
||||
});
|
||||
};
|
||||
|
||||
export const listShipmentPlanOrder = (query?: ShipmentPlanQuery): AxiosPromise<ShipmentPlanVO[]> => {
|
||||
return request({
|
||||
url: '/amz/shipmentPlan/list/order',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询货件计划详细
|
||||
* @param id
|
||||
@ -27,6 +35,16 @@ export const getShipmentPlan = (id: string | number): AxiosPromise<ShipmentPlanV
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取今天的货件计划数据
|
||||
* @param id
|
||||
*/
|
||||
export const takeTodayAmzPlanData = () => {
|
||||
return request({
|
||||
url: '/amz/shipmentPlan/take-today-amz-plan-data',
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询货件计划详细
|
||||
|
@ -1,3 +1,7 @@
|
||||
import { LogisticsOrderVO } from '@/api/amz/logisticsOrder/types';
|
||||
import { LogisticsOrderDetailVO } from '@/api/amz/logisticsOrderDetail/types';
|
||||
import { ShipmentItemVO } from '@/api/amz/shipmentItem/types';
|
||||
|
||||
export interface ShipmentPlanVO {
|
||||
/**
|
||||
* 主键ID
|
||||
@ -32,7 +36,7 @@ export interface ShipmentPlanVO {
|
||||
/**
|
||||
* 物流中心编码
|
||||
*/
|
||||
destination: string | number;
|
||||
destination: string;
|
||||
|
||||
/**
|
||||
* 运输模式
|
||||
@ -57,7 +61,7 @@ export interface ShipmentPlanVO {
|
||||
/**
|
||||
* 同步时间
|
||||
*/
|
||||
syncTime: string;
|
||||
receivingTime: string;
|
||||
|
||||
/**
|
||||
* 计划发货日期
|
||||
@ -99,7 +103,205 @@ export interface ShipmentPlanVO {
|
||||
*/
|
||||
isSta: string;
|
||||
|
||||
/**
|
||||
* 货件唯一编号
|
||||
*/
|
||||
shipmentUniqueId: string | number;
|
||||
|
||||
/**
|
||||
* STA任务编号
|
||||
*/
|
||||
inboundPlanId: string | number;
|
||||
|
||||
/**
|
||||
* 运营操作货件状态
|
||||
*/
|
||||
fbaStatus: string;
|
||||
|
||||
/**
|
||||
* 总箱子数量
|
||||
*/
|
||||
boxQuantity: number;
|
||||
|
||||
/**
|
||||
* 箱子尺寸
|
||||
*/
|
||||
boxSize: string;
|
||||
|
||||
/**
|
||||
* 供应商称重(单位:KG,物流商实际测量值)
|
||||
*/
|
||||
vendorWeight: number;
|
||||
|
||||
/**
|
||||
* 套数(系统中的申报量)
|
||||
*/
|
||||
setTotal: number;
|
||||
|
||||
/**
|
||||
* 渠道ID
|
||||
*/
|
||||
channelId: string | number;
|
||||
|
||||
/**
|
||||
* 物流渠道
|
||||
*/
|
||||
channelName: string;
|
||||
}
|
||||
|
||||
export interface ShipmentPlanOrderVO {
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
id: string | number;
|
||||
|
||||
/**
|
||||
* 关联系统ID
|
||||
*/
|
||||
sid: string | number;
|
||||
|
||||
/**
|
||||
* 货件编号
|
||||
*/
|
||||
shipmentId: string | number;
|
||||
|
||||
/**
|
||||
* 货件名称
|
||||
*/
|
||||
shipmentName: string;
|
||||
|
||||
/**
|
||||
* 是否关闭
|
||||
*/
|
||||
isClosed: string;
|
||||
|
||||
/**
|
||||
* 货件状态
|
||||
*/
|
||||
shipmentStatus: string;
|
||||
|
||||
/**
|
||||
* 物流中心编码
|
||||
*/
|
||||
destination: string;
|
||||
|
||||
/**
|
||||
* 运输模式
|
||||
*/
|
||||
shippingMode: string;
|
||||
|
||||
/**
|
||||
* 运输方案
|
||||
*/
|
||||
shippingSolution: string;
|
||||
|
||||
/**
|
||||
* 最后更新时间
|
||||
*/
|
||||
gmtModified: string;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
gmtCreate: string;
|
||||
|
||||
/**
|
||||
* 同步时间
|
||||
*/
|
||||
receivingTime: string;
|
||||
|
||||
/**
|
||||
* 计划发货日期
|
||||
*/
|
||||
staShipmentDate: string;
|
||||
|
||||
/**
|
||||
* 预计到货开始日
|
||||
*/
|
||||
staDeliveryStartDate: string;
|
||||
|
||||
/**
|
||||
* 预计到货截止日
|
||||
*/
|
||||
staDeliveryEndDate: string;
|
||||
|
||||
/**
|
||||
* 发货地址
|
||||
*/
|
||||
shipFromAddress: string;
|
||||
|
||||
/**
|
||||
* 收货地址
|
||||
*/
|
||||
shipToAddress: string;
|
||||
|
||||
/**
|
||||
* 参考编号
|
||||
*/
|
||||
referenceId: string | number;
|
||||
|
||||
/**
|
||||
* 入库计划ID
|
||||
*/
|
||||
staInboundPlanId: string | number;
|
||||
|
||||
/**
|
||||
* 是否STA计划
|
||||
*/
|
||||
isSta: string;
|
||||
|
||||
/**
|
||||
* 货件唯一编号
|
||||
*/
|
||||
shipmentUniqueId: string | number;
|
||||
|
||||
/**
|
||||
* STA任务编号
|
||||
*/
|
||||
inboundPlanId: string | number;
|
||||
|
||||
/**
|
||||
* 运营操作货件状态
|
||||
*/
|
||||
fbaStatus: string;
|
||||
|
||||
/**
|
||||
* 总箱子数量
|
||||
*/
|
||||
boxQuantity: number;
|
||||
|
||||
/**
|
||||
* 箱子尺寸
|
||||
*/
|
||||
boxSize: string;
|
||||
|
||||
/**
|
||||
* 供应商称重(单位:KG,物流商实际测量值)
|
||||
*/
|
||||
logisticsWeight: number;
|
||||
|
||||
/**
|
||||
* 套数(系统中的申报量)
|
||||
*/
|
||||
setTotal: number;
|
||||
|
||||
/**
|
||||
* 渠道ID
|
||||
*/
|
||||
channelId: string | number;
|
||||
|
||||
/**
|
||||
* 物流渠道
|
||||
*/
|
||||
channelName: string;
|
||||
|
||||
order?: LogisticsOrderVO;
|
||||
|
||||
detailList?: LogisticsOrderDetailVO[];
|
||||
|
||||
itemVoList?: ShipmentItemVO[];
|
||||
|
||||
quote?: LogisticsOrderVO;
|
||||
}
|
||||
|
||||
export interface ShipmentPlanForm extends BaseEntity {
|
||||
@ -136,7 +338,7 @@ export interface ShipmentPlanForm extends BaseEntity {
|
||||
/**
|
||||
* 物流中心编码
|
||||
*/
|
||||
destination?: string | number;
|
||||
destination?: string;
|
||||
|
||||
/**
|
||||
* 运输模式
|
||||
@ -161,7 +363,7 @@ export interface ShipmentPlanForm extends BaseEntity {
|
||||
/**
|
||||
* 同步时间
|
||||
*/
|
||||
syncTime?: string;
|
||||
receivingTime?: string;
|
||||
|
||||
/**
|
||||
* 计划发货日期
|
||||
@ -203,10 +405,53 @@ export interface ShipmentPlanForm extends BaseEntity {
|
||||
*/
|
||||
isSta?: string;
|
||||
|
||||
/**
|
||||
* 货件唯一编号
|
||||
*/
|
||||
shipmentUniqueId?: string | number;
|
||||
|
||||
/**
|
||||
* STA任务编号
|
||||
*/
|
||||
inboundPlanId?: string | number;
|
||||
|
||||
/**
|
||||
* 运营操作货件状态
|
||||
*/
|
||||
fbaStatus?: string;
|
||||
|
||||
/**
|
||||
* 总箱子数量
|
||||
*/
|
||||
boxQuantity?: number;
|
||||
|
||||
/**
|
||||
* 箱子尺寸
|
||||
*/
|
||||
boxSize?: string;
|
||||
|
||||
/**
|
||||
* 供应商称重
|
||||
*/
|
||||
vendorWeight?: number;
|
||||
|
||||
/**
|
||||
* 套数(系统中的申报量)
|
||||
*/
|
||||
setTotal?: number;
|
||||
|
||||
/**
|
||||
* 渠道ID
|
||||
*/
|
||||
channelId?: string | number;
|
||||
|
||||
/**
|
||||
* 物流渠道
|
||||
*/
|
||||
channelName?: string;
|
||||
}
|
||||
|
||||
export interface ShipmentPlanQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 关联系统ID
|
||||
*/
|
||||
@ -235,7 +480,7 @@ export interface ShipmentPlanQuery extends PageQuery {
|
||||
/**
|
||||
* 物流中心编码
|
||||
*/
|
||||
destination?: string | number;
|
||||
destination?: string;
|
||||
|
||||
/**
|
||||
* 运输模式
|
||||
@ -260,7 +505,7 @@ export interface ShipmentPlanQuery extends PageQuery {
|
||||
/**
|
||||
* 同步时间
|
||||
*/
|
||||
syncTime?: string;
|
||||
receivingTime?: string;
|
||||
|
||||
/**
|
||||
* 计划发货日期
|
||||
@ -302,11 +547,53 @@ export interface ShipmentPlanQuery extends PageQuery {
|
||||
*/
|
||||
isSta?: string;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 货件唯一编号
|
||||
*/
|
||||
shipmentUniqueId?: string | number;
|
||||
|
||||
/**
|
||||
* STA任务编号
|
||||
*/
|
||||
inboundPlanId?: string | number;
|
||||
|
||||
/**
|
||||
* 运营操作货件状态
|
||||
*/
|
||||
fbaStatus?: string;
|
||||
|
||||
/**
|
||||
* 总箱子数量
|
||||
*/
|
||||
boxQuantity?: number;
|
||||
|
||||
/**
|
||||
* 箱子尺寸
|
||||
*/
|
||||
boxSize?: string;
|
||||
|
||||
/**
|
||||
* 供应商称重(单位:KG,物流商实际测量值)
|
||||
*/
|
||||
logisticsWeight?: number;
|
||||
|
||||
/**
|
||||
* 套数(系统中的申报量)
|
||||
*/
|
||||
setTotal?: number;
|
||||
|
||||
/**
|
||||
* 渠道ID
|
||||
*/
|
||||
channelId?: string | number;
|
||||
|
||||
/**
|
||||
* 物流渠道
|
||||
*/
|
||||
channelName?: string;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -19,6 +19,66 @@ export interface ShipmentTrackingVO {
|
||||
*/
|
||||
trackingNumber: string;
|
||||
|
||||
/**
|
||||
* 本地箱子编号
|
||||
*/
|
||||
localBoxId: string | number;
|
||||
|
||||
/**
|
||||
* 包裹唯一标识
|
||||
*/
|
||||
packageId: string | number;
|
||||
|
||||
/**
|
||||
* 总数量
|
||||
*/
|
||||
total: number;
|
||||
|
||||
/**
|
||||
* 重量
|
||||
*/
|
||||
weight: number;
|
||||
|
||||
/**
|
||||
* 重量单位
|
||||
*/
|
||||
weightUnit: string;
|
||||
|
||||
/**
|
||||
* 长度
|
||||
*/
|
||||
length: number;
|
||||
|
||||
/**
|
||||
* 宽度
|
||||
*/
|
||||
width: string | number;
|
||||
|
||||
/**
|
||||
* 高度
|
||||
*/
|
||||
height: number;
|
||||
|
||||
/**
|
||||
* 尺寸单位
|
||||
*/
|
||||
lengthUnit: string;
|
||||
|
||||
/**
|
||||
* 箱子展示名称
|
||||
*/
|
||||
boxName: string;
|
||||
|
||||
/**
|
||||
* 货件唯一编号
|
||||
*/
|
||||
shipmentUniqueId: string | number;
|
||||
|
||||
/**
|
||||
* STA任务编号
|
||||
*/
|
||||
inboundPlanId: string | number;
|
||||
|
||||
}
|
||||
|
||||
export interface ShipmentTrackingForm extends BaseEntity {
|
||||
@ -42,6 +102,66 @@ export interface ShipmentTrackingForm extends BaseEntity {
|
||||
*/
|
||||
trackingNumber?: string;
|
||||
|
||||
/**
|
||||
* 本地箱子编号
|
||||
*/
|
||||
localBoxId?: string | number;
|
||||
|
||||
/**
|
||||
* 包裹唯一标识
|
||||
*/
|
||||
packageId?: string | number;
|
||||
|
||||
/**
|
||||
* 总数量
|
||||
*/
|
||||
total?: number;
|
||||
|
||||
/**
|
||||
* 重量
|
||||
*/
|
||||
weight?: number;
|
||||
|
||||
/**
|
||||
* 重量单位
|
||||
*/
|
||||
weightUnit?: string;
|
||||
|
||||
/**
|
||||
* 长度
|
||||
*/
|
||||
length?: number;
|
||||
|
||||
/**
|
||||
* 宽度
|
||||
*/
|
||||
width?: string | number;
|
||||
|
||||
/**
|
||||
* 高度
|
||||
*/
|
||||
height?: number;
|
||||
|
||||
/**
|
||||
* 尺寸单位
|
||||
*/
|
||||
lengthUnit?: string;
|
||||
|
||||
/**
|
||||
* 箱子展示名称
|
||||
*/
|
||||
boxName?: string;
|
||||
|
||||
/**
|
||||
* 货件唯一编号
|
||||
*/
|
||||
shipmentUniqueId?: string | number;
|
||||
|
||||
/**
|
||||
* STA任务编号
|
||||
*/
|
||||
inboundPlanId?: string | number;
|
||||
|
||||
}
|
||||
|
||||
export interface ShipmentTrackingQuery extends PageQuery {
|
||||
@ -61,6 +181,66 @@ export interface ShipmentTrackingQuery extends PageQuery {
|
||||
*/
|
||||
trackingNumber?: string;
|
||||
|
||||
/**
|
||||
* 本地箱子编号
|
||||
*/
|
||||
localBoxId?: string | number;
|
||||
|
||||
/**
|
||||
* 包裹唯一标识
|
||||
*/
|
||||
packageId?: string | number;
|
||||
|
||||
/**
|
||||
* 总数量
|
||||
*/
|
||||
total?: number;
|
||||
|
||||
/**
|
||||
* 重量
|
||||
*/
|
||||
weight?: number;
|
||||
|
||||
/**
|
||||
* 重量单位
|
||||
*/
|
||||
weightUnit?: string;
|
||||
|
||||
/**
|
||||
* 长度
|
||||
*/
|
||||
length?: number;
|
||||
|
||||
/**
|
||||
* 宽度
|
||||
*/
|
||||
width?: string | number;
|
||||
|
||||
/**
|
||||
* 高度
|
||||
*/
|
||||
height?: number;
|
||||
|
||||
/**
|
||||
* 尺寸单位
|
||||
*/
|
||||
lengthUnit?: string;
|
||||
|
||||
/**
|
||||
* 箱子展示名称
|
||||
*/
|
||||
boxName?: string;
|
||||
|
||||
/**
|
||||
* 货件唯一编号
|
||||
*/
|
||||
shipmentUniqueId?: string | number;
|
||||
|
||||
/**
|
||||
* STA任务编号
|
||||
*/
|
||||
inboundPlanId?: string | number;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 269 KiB After Width: | Height: | Size: 19 KiB |
Binary file not shown.
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 4.1 KiB |
98
src/components/EnhancedTable/index.vue
Normal file
98
src/components/EnhancedTable/index.vue
Normal file
@ -0,0 +1,98 @@
|
||||
<!-- EnhancedTable.vue -->
|
||||
<template>
|
||||
<div class="enhanced-table-container">
|
||||
<!-- 列控制按钮 -->
|
||||
<div class="column-control">
|
||||
<el-tooltip content="列配置" placement="left">
|
||||
<el-button circle size="small" class="control-btn" @click="showConfigDialog = true">
|
||||
<el-icon>
|
||||
<Operation />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
|
||||
<!-- 列配置弹窗 -->
|
||||
<el-dialog v-model="showConfigDialog" title="列显示配置" width="500px">
|
||||
<el-checkbox-group v-model="visibleKeys">
|
||||
<el-row :gutter="20">
|
||||
<el-col v-for="col in configurableColumns" :key="col.uniqueKey" :span="8">
|
||||
<el-checkbox :value="col.uniqueKey" :disabled="col.fixed">
|
||||
{{ col.displayLabel }}
|
||||
</el-checkbox>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-checkbox-group>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 动态渲染表格 -->
|
||||
<el-table ref="tableRef" v-bind="$attrs" :data="tableData" v-loading="loading" @current-change="handleCurrentChange" highlight-current-row>
|
||||
<template v-for="col in visibleColumns" :key="col.uniqueKey">
|
||||
<component :is="col.component" v-bind="col.props">
|
||||
<template v-for="(slot, name) in col.slots" #[name]="scope">
|
||||
<slot :name="name" v-bind="scope" />
|
||||
</template>
|
||||
</component>
|
||||
</template>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch, useSlots, onMounted } from 'vue';
|
||||
|
||||
// 生成稳定唯一键(核心修复)
|
||||
const generateStableKey = (node) => {
|
||||
// 特殊列处理(如展开列)
|
||||
if (node.props?.type) {
|
||||
return `special_${node.props.type}`;
|
||||
}
|
||||
|
||||
// 有prop的列:prop+label双校验
|
||||
if (node.props?.prop) {
|
||||
return `prop_${node.props.prop}_${node.props.label || 'nolabel'}`;
|
||||
}
|
||||
|
||||
// 无prop但有label的列:label+组件名哈希
|
||||
if (node.props?.label) {
|
||||
return `label_${node.props.label.replace(/\W/g, '_')}_${hashCode(node.type?.name)}`;
|
||||
}
|
||||
|
||||
// 最终回退方案(使用slot哈希)
|
||||
return `slot_${hashCode(JSON.stringify(node.children))}`;
|
||||
};
|
||||
|
||||
// 哈希函数(生成8位标识)
|
||||
const hashCode = (str) => {
|
||||
let hash = 0;
|
||||
for (let i = 0; i < (str || '').length; i++) {
|
||||
hash = (hash << 5) - hash + str.charCodeAt(i);
|
||||
hash |= 0;
|
||||
}
|
||||
return Math.abs(hash).toString(16).padStart(8, '0');
|
||||
};
|
||||
|
||||
// 解析列配置(带缓存)
|
||||
const parsedColumns = ref([]);
|
||||
const parseColumns = () => {
|
||||
const slots = useSlots().default?.();
|
||||
parsedColumns.value = (slots || [])
|
||||
.filter((node) => !node.type?.toString().includes('Comment'))
|
||||
.map((node) => ({
|
||||
uniqueKey: generateStableKey(node),
|
||||
label: node.props?.label,
|
||||
component: node.type,
|
||||
props: node.props,
|
||||
slots: node.children,
|
||||
fixed: !!node.props?.type
|
||||
}));
|
||||
};
|
||||
|
||||
// 初始化列配置
|
||||
onMounted(parseColumns);
|
||||
watch(useSlots(), parseColumns, { deep: true });
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 保持原有样式不变 */
|
||||
</style>
|
126
src/components/LTable/index.vue
Normal file
126
src/components/LTable/index.vue
Normal file
@ -0,0 +1,126 @@
|
||||
<!-- 最后修改之前封装的组件 -->
|
||||
<template>
|
||||
<div class="l-table">
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="props.tableModule.dataList"
|
||||
border
|
||||
height="100%"
|
||||
style="width: 100%; overflow-y: scroll"
|
||||
v-loading="props.tableModule.loading"
|
||||
@selection-change="props.tableModule.selectChange"
|
||||
:row-class-name="tableRowClassName"
|
||||
:cell-class-name="tableCellClassName"
|
||||
@cell-dblclick="cellDblClick"
|
||||
>
|
||||
<el-table-column type="selection" width="50" align="center" />
|
||||
<!-- v-for 循环拿到了外层,在 el-table-column 判断 item.show 就可以了 -->
|
||||
<template v-if="tableChildren == '1'" v-for="(item, index) in props.tableModule.columns">
|
||||
<el-table-column
|
||||
:prop="item.prop"
|
||||
:label="item.label"
|
||||
:align="item.align || 'left'"
|
||||
:width="item.width"
|
||||
:min-width="item.min_width"
|
||||
:fixed="item.fixed"
|
||||
v-if="item.show"
|
||||
>
|
||||
<template slot-scope="scope" #default="scope">
|
||||
<div v-if="item.type == 'switch'">
|
||||
<el-switch
|
||||
v-model="scope.row[item.prop]"
|
||||
:active-value="item.activeValue"
|
||||
:inactive-value="item.inactiveValue"
|
||||
@change="props.tableModule.switchChange(scope.row)"
|
||||
>
|
||||
</el-switch>
|
||||
</div>
|
||||
<div v-else-if="item.type == 'status'">
|
||||
<el-tag :type="item.color ? item.color[scope.row[item.prop]] : ''"
|
||||
>{{ props.tableModule.fieldChange(scope.row[item.prop], item.option) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<div v-else-if="item.type == 'image'">
|
||||
<el-image style="width: 60px; height: 60px" :src="scope.row[item.prop]" :preview-src-list="[scope.row[item.prop]]"> </el-image>
|
||||
</div>
|
||||
<div v-else-if="item.type == 'time'">{{ formatDate(scope.row[item.prop]) }}</div>
|
||||
<div v-else-if="item.isEdit">
|
||||
<el-input
|
||||
v-model="scope.row[item.prop]"
|
||||
:placeholder="'请输入' + item.label"
|
||||
@blur="inputBlur(scope.row)"
|
||||
autofocus
|
||||
ref="inputRef"
|
||||
v-if="scope.row['index'] == rowIndex && scope.column['index'] == columnIndex"
|
||||
/>
|
||||
<div v-else>{{ scope.row[item.prop] }}</div>
|
||||
</div>
|
||||
<div v-else>{{ scope.row[item.prop] }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
<!-- 这里无论循环一级还是二级都需要在template上去写循环 -->
|
||||
<template v-else-if="tableChildren == '2'" v-for="(one, index) in props.tableModule.columns">
|
||||
<el-table-column :label="one.label" v-if="one.show">
|
||||
<template v-for="item in props.tableModule.columns[index].children">
|
||||
<el-table-column
|
||||
:prop="item.prop"
|
||||
:label="item.label"
|
||||
:align="item.align || 'left'"
|
||||
:width="item.width"
|
||||
:min-width="item.min_width"
|
||||
:fixed="item.fixed"
|
||||
v-if="item.show"
|
||||
>
|
||||
<template slot-scope="scope" #default="scope">
|
||||
<div v-if="item.type == 'switch'">
|
||||
<el-switch
|
||||
v-model="scope.row[item.prop]"
|
||||
:active-value="item.activeValue"
|
||||
:inactive-value="item.inactiveValue"
|
||||
@change="props.tableModule.switchChange(scope.row)"
|
||||
>
|
||||
</el-switch>
|
||||
</div>
|
||||
<div v-else-if="item.type == 'status'">
|
||||
<el-tag :type="item.color ? item.color[scope.row[item.prop]] : ''"
|
||||
>{{ props.tableModule.fieldChange(scope.row[item.prop], item.option) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<div v-else-if="item.type == 'image'">
|
||||
<el-image style="width: 60px; height: 60px" :src="scope.row[item.prop]" :preview-src-list="[scope.row[item.prop]]"> </el-image>
|
||||
</div>
|
||||
<div v-else-if="item.type == 'time'">{{ formatDate(scope.row[item.prop]) }}</div>
|
||||
<div v-else-if="item.isEdit">
|
||||
<el-input
|
||||
v-model="scope.row[item.prop]"
|
||||
:placeholder="'请输入' + item.label"
|
||||
@blur="inputBlur(scope.row)"
|
||||
autofocus
|
||||
ref="inputRef"
|
||||
v-if="scope.row['index'] == rowIndex && scope.column['index'] == columnIndex"
|
||||
/>
|
||||
<div v-else>{{ scope.row[item.prop] }}</div>
|
||||
</div>
|
||||
<div v-else>{{ scope.row[item.prop] }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
<slot name="event"></slot>
|
||||
</el-table>
|
||||
<div class="l-pages">
|
||||
<!-- 分页 -->
|
||||
<el-pagination
|
||||
:current-page="props.tableModule.pages.page"
|
||||
:page-size.sync="props.tableModule.pages.limit"
|
||||
:page-sizes="pageSizes"
|
||||
:layout="layout"
|
||||
:total="props.tableModule.pages.total"
|
||||
@size-change="props.tableModule.sizeChange"
|
||||
@current-change="props.tableModule.currentChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
237
src/components/OrderDetailFileUpload/index.vue
Normal file
237
src/components/OrderDetailFileUpload/index.vue
Normal file
@ -0,0 +1,237 @@
|
||||
<template>
|
||||
<div class="upload-file">
|
||||
<el-upload
|
||||
ref="fileUploadRef"
|
||||
multiple
|
||||
:action="uploadFileUrl"
|
||||
:before-upload="handleBeforeUpload"
|
||||
:file-list="fileList"
|
||||
:limit="limit"
|
||||
:on-error="handleUploadError"
|
||||
:on-exceed="handleExceed"
|
||||
:on-success="handleUploadSuccess"
|
||||
:show-file-list="false"
|
||||
:headers="headers"
|
||||
class="upload-file-uploader"
|
||||
>
|
||||
<!-- 上传按钮 -->
|
||||
<el-button plain icon="Plus" type="warning">导入文件</el-button>
|
||||
</el-upload>
|
||||
<!-- 上传提示 -->
|
||||
<div v-if="showTip" class="el-upload__tip">
|
||||
请上传
|
||||
<template v-if="fileSize">
|
||||
大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
|
||||
</template>
|
||||
<template v-if="fileType">
|
||||
格式为 <b style="color: #f56c6c">{{ fileType.join('/') }}</b>
|
||||
</template>
|
||||
的文件
|
||||
</div>
|
||||
<!-- 文件列表 -->
|
||||
<transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
|
||||
<li v-for="(file, index) in fileList" :key="file.uid" class="el-upload-list__item ele-upload-list__item-content">
|
||||
<el-link :href="`${file.url}`" :underline="false" target="_blank">
|
||||
<span class="el-icon-document"> {{ getFileName(file.name) }} </span>
|
||||
</el-link>
|
||||
<div class="ele-upload-list__item-content-action">
|
||||
<el-button type="danger" link @click="handleDelete(index)">删除</el-button>
|
||||
</div>
|
||||
</li>
|
||||
</transition-group>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { propTypes } from '@/utils/propTypes';
|
||||
import { delOss, listByIds } from '@/api/system/oss';
|
||||
import { globalHeaders } from '@/utils/request';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: [String, Object, Array],
|
||||
default: () => []
|
||||
},
|
||||
// 数量限制
|
||||
limit: propTypes.number.def(5),
|
||||
// 大小限制(MB)
|
||||
fileSize: propTypes.number.def(5),
|
||||
// 文件类型, 例如['png', 'jpg', 'jpeg']
|
||||
fileType: propTypes.array.def(['doc', 'xls', 'ppt', 'txt', 'pdf']),
|
||||
// 是否显示提示
|
||||
isShowTip: propTypes.bool.def(true)
|
||||
});
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
const number = ref(0);
|
||||
const uploadList = ref<any[]>([]);
|
||||
|
||||
const baseUrl = import.meta.env.VITE_APP_BASE_API;
|
||||
const uploadFileUrl = ref(baseUrl + '/amz/logisticsOrderDetail/importData'); // 上传文件服务器地址
|
||||
const headers = ref(globalHeaders());
|
||||
|
||||
const fileList = ref<any[]>([]);
|
||||
const showTip = computed(() => props.isShowTip && (props.fileType || props.fileSize));
|
||||
|
||||
const fileUploadRef = ref<ElUploadInstance>();
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
async (val) => {
|
||||
if (val) {
|
||||
let temp = 1;
|
||||
// 首先将值转为数组
|
||||
let list: any[] = [];
|
||||
if (Array.isArray(val)) {
|
||||
list = val;
|
||||
} else {
|
||||
const res = await listByIds(val);
|
||||
list = res.data.map((oss) => {
|
||||
return {
|
||||
name: oss.originalName,
|
||||
url: oss.url,
|
||||
ossId: oss.ossId
|
||||
};
|
||||
});
|
||||
}
|
||||
// 然后将数组转为对象数组
|
||||
fileList.value = list.map((item) => {
|
||||
item = { name: item.name, url: item.url, ossId: item.ossId };
|
||||
item.uid = item.uid || new Date().getTime() + temp++;
|
||||
return item;
|
||||
});
|
||||
} else {
|
||||
fileList.value = [];
|
||||
return [];
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
|
||||
// 上传前校检格式和大小
|
||||
const handleBeforeUpload = (file: any) => {
|
||||
// 校检文件类型
|
||||
if (props.fileType.length) {
|
||||
const fileName = file.name.split('.');
|
||||
const fileExt = fileName[fileName.length - 1];
|
||||
const isTypeOk = props.fileType.indexOf(fileExt) >= 0;
|
||||
if (!isTypeOk) {
|
||||
proxy?.$modal.msgError(`文件格式不正确, 请上传${props.fileType.join('/')}格式文件!`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 校检文件名是否包含特殊字符
|
||||
if (file.name.includes(',')) {
|
||||
proxy?.$modal.msgError('文件名不正确,不能包含英文逗号!');
|
||||
return false;
|
||||
}
|
||||
// 校检文件大小
|
||||
if (props.fileSize) {
|
||||
const isLt = file.size / 1024 / 1024 < props.fileSize;
|
||||
if (!isLt) {
|
||||
proxy?.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
proxy?.$modal.loading('正在上传文件,请稍候...');
|
||||
number.value++;
|
||||
return true;
|
||||
};
|
||||
|
||||
// 文件个数超出
|
||||
const handleExceed = () => {
|
||||
proxy?.$modal.msgError(`上传文件数量不能超过 ${props.limit} 个!`);
|
||||
};
|
||||
|
||||
// 上传失败
|
||||
const handleUploadError = () => {
|
||||
proxy?.$modal.msgError('上传文件失败');
|
||||
};
|
||||
|
||||
// 上传成功回调
|
||||
const handleUploadSuccess = (res: any, file: UploadFile) => {
|
||||
if (res.code === 200) {
|
||||
// uploadList.value.push({
|
||||
// name: res.data.fileName,
|
||||
// url: res.data.url,
|
||||
// ossId: res.data.ossId
|
||||
// });
|
||||
// uploadedSuccessfully();
|
||||
proxy?.$modal.msgSuccess('上传文件成功');
|
||||
} else {
|
||||
// number.value--;
|
||||
// proxy?.$modal.closeLoading();
|
||||
// proxy?.$modal.msgError(res.msg);
|
||||
// fileUploadRef.value?.handleRemove(file);
|
||||
// uploadedSuccessfully();
|
||||
proxy?.$modal.msgError('上传文件失败');
|
||||
}
|
||||
proxy?.$modal.closeLoading();
|
||||
};
|
||||
|
||||
// 删除文件
|
||||
const handleDelete = (index: number) => {
|
||||
let ossId = fileList.value[index].ossId;
|
||||
delOss(ossId);
|
||||
fileList.value.splice(index, 1);
|
||||
emit('update:modelValue', listToString(fileList.value));
|
||||
};
|
||||
|
||||
// 上传结束处理
|
||||
const uploadedSuccessfully = () => {
|
||||
if (number.value > 0 && uploadList.value.length === number.value) {
|
||||
fileList.value = fileList.value.filter((f) => f.url !== undefined).concat(uploadList.value);
|
||||
uploadList.value = [];
|
||||
number.value = 0;
|
||||
emit('update:modelValue', listToString(fileList.value));
|
||||
proxy?.$modal.closeLoading();
|
||||
}
|
||||
};
|
||||
|
||||
// 获取文件名称
|
||||
const getFileName = (name: string) => {
|
||||
// 如果是url那么取最后的名字 如果不是直接返回
|
||||
if (name.lastIndexOf('/') > -1) {
|
||||
return name.slice(name.lastIndexOf('/') + 1);
|
||||
} else {
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
// 对象转成指定字符串分隔
|
||||
const listToString = (list: any[], separator?: string) => {
|
||||
let strs = '';
|
||||
separator = separator || ',';
|
||||
list.forEach((item) => {
|
||||
if (item.ossId) {
|
||||
strs += item.ossId + separator;
|
||||
}
|
||||
});
|
||||
return strs != '' ? strs.substring(0, strs.length - 1) : '';
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.upload-file-uploader {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.upload-file-list .el-upload-list__item {
|
||||
border: 1px solid #e4e7ed;
|
||||
line-height: 2;
|
||||
margin-bottom: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.upload-file-list .ele-upload-list__item-content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.ele-upload-list__item-content-action .el-link {
|
||||
margin-right: 10px;
|
||||
}
|
||||
</style>
|
@ -129,6 +129,8 @@ const roleNmae = computed(() => {
|
||||
return '物流商';
|
||||
} else if (roles.includes('yunying')) {
|
||||
return '运营';
|
||||
} else if (roles.includes('manager')) {
|
||||
return '管理员';
|
||||
} else {
|
||||
return '普通用户';
|
||||
}
|
||||
|
@ -91,6 +91,9 @@
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['amz:amazonStore:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="指定运营" placement="top">
|
||||
<el-button link type="primary" icon="Avatar" @click="changeUser(scope.row)" v-hasPermi="['amz:amazonStore:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['amz:amazonStore:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
@ -152,6 +155,7 @@
|
||||
import { listAmazonStore, getAmazonStore, delAmazonStore, addAmazonStore, updateAmazonStore, collectAmzStoreData } from '@/api/amz/amazonStore';
|
||||
import { AmazonStoreVO, AmazonStoreQuery, AmazonStoreForm } from '@/api/amz/amazonStore/types';
|
||||
import AssignUser from '@/views/amz/amazonStore/assignUser.vue';
|
||||
import { getInquiryRequest } from '@/api/amz/inquiryRequest';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
@ -283,6 +287,17 @@ const handleAdd = () => {
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: AmazonStoreVO) => {
|
||||
reset();
|
||||
const _id = row?.id || ids.value[0];
|
||||
form.value.id = _id;
|
||||
console.log('form.value.id', _id);
|
||||
const res = await getInquiryRequest(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
dialog.visible = true;
|
||||
dialog.title = '修改亚马逊店铺信息';
|
||||
};
|
||||
|
||||
const changeUser = async (row?: AmazonStoreVO) => {
|
||||
reset();
|
||||
const _id = row?.id || ids.value[0];
|
||||
form.value.id = _id;
|
||||
|
@ -234,6 +234,12 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="时效" prop="leadTime">
|
||||
<div class="kgprice">
|
||||
<el-input-number v-model="minDay" :min="1" :max="100">
|
||||
<template #suffix>
|
||||
<span>天</span>
|
||||
</template>
|
||||
</el-input-number>
|
||||
到
|
||||
<el-input-number v-model="quoteForm.leadTime" :min="1" :max="100">
|
||||
<template #suffix>
|
||||
<span>天</span>
|
||||
@ -242,7 +248,11 @@
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="附加费" prop="surcharge">
|
||||
<el-input v-model="quoteForm.surcharge" placeholder="请输入附加费" />
|
||||
<el-input-number v-model="quoteForm.surcharge" :precision="2" :step="0.1" :min="1" :max="100">
|
||||
<template #suffix>
|
||||
<span>元</span>
|
||||
</template>
|
||||
</el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="报价生效起止日期" prop="quoteDate">
|
||||
<el-date-picker
|
||||
@ -279,7 +289,7 @@
|
||||
import { listInquiryRequest, getInquiryRequest, delInquiryRequest, addInquiryRequest, updateInquiryRequest } from '@/api/amz/inquiryRequest';
|
||||
import { InquiryRequestVO, InquiryRequestQuery, InquiryRequestForm } from '@/api/amz/inquiryRequest/types';
|
||||
import { LogisticsMostQuoteForm, LogisticsQuoteForm } from '@/api/amz/logisticsQuote/types';
|
||||
import { addMostLogisticsQuote } from '@/api/amz/logisticsQuote';
|
||||
import { addMostLogisticsQuote, checkPriceQuoteByBo, getTodayQuoteStatus } from '@/api/amz/logisticsQuote';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
@ -294,6 +304,8 @@ const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
|
||||
const minDay = ref(0);
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const inquiryRequestFormRef = ref<ElFormInstance>();
|
||||
|
||||
@ -329,6 +341,7 @@ const initQuoteForm: LogisticsMostQuoteForm = {
|
||||
price: 10,
|
||||
leadTime: 10,
|
||||
surcharge: undefined,
|
||||
channelName: undefined,
|
||||
quoteStartDate: undefined,
|
||||
quoteEndDate: undefined,
|
||||
quoteDate: [] as Date[],
|
||||
@ -403,6 +416,11 @@ const getList = async () => {
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
const queryTodayQuoteStatus = async () => {
|
||||
const res = await getTodayQuoteStatus();
|
||||
console.log('queryTodayQuoteStatus', res);
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
@ -478,11 +496,33 @@ const submitQuoteForm = async () => {
|
||||
data.quoteForm.quoteEndDate = data.quoteForm.quoteDate[1];
|
||||
data.quoteForm.isSubmitted = 'Y';
|
||||
console.log('submitQuoteForm', data.quoteForm);
|
||||
const res = await addMostLogisticsQuote(data.quoteForm);
|
||||
const res = await checkPriceQuoteByBo(data.quoteForm);
|
||||
console.log('submitQuoteForm', res);
|
||||
if (res.code === 200) {
|
||||
ElMessage.success('提交成功');
|
||||
quoteDialog.visible = false;
|
||||
// ElMessage.success('提交成功');
|
||||
// quoteDialog.visible = false;
|
||||
|
||||
if (res.data === true) {
|
||||
const res = await addMostLogisticsQuote(data.quoteForm);
|
||||
if (res.code === 200) {
|
||||
ElMessage.success('提交成功');
|
||||
quoteDialog.visible = false;
|
||||
}
|
||||
} else {
|
||||
ElMessageBox.confirm('价格没有竞争力,问他是否需要修改价格?', '提示', {
|
||||
confirmButtonText: '确认提交',
|
||||
cancelButtonText: '修改价格',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(async () => {
|
||||
const res = await addMostLogisticsQuote(data.quoteForm);
|
||||
if (res.code === 200) {
|
||||
ElMessage.success('提交成功');
|
||||
quoteDialog.visible = false;
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -515,8 +555,8 @@ const handleSubmit = async (row?: InquiryRequestVO) => {
|
||||
data.quoteForm.channelName = row.channelName;
|
||||
quoteDialog.visible = true;
|
||||
console.log(row.effectiveStartTime);
|
||||
// data.quoteForm.quoteDate[0] = row.effectiveStartTime;
|
||||
// data.quoteForm.quoteDate[1] = row.effectiveEndTime;
|
||||
// quoteForm.quoteDate[0] = row.effectiveStartTime;
|
||||
// quoteForm.quoteDate[1] = row.effectiveEndTime;
|
||||
const dateString = row.effectiveStartTime.replace(' ', 'T');
|
||||
const dateString2 = row.effectiveEndTime.replace(' ', 'T');
|
||||
const date = new Date(dateString); // 生成 Date 对象
|
||||
@ -538,6 +578,7 @@ const handleExport = () => {
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
queryTodayQuoteStatus();
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
|
@ -90,13 +90,27 @@
|
||||
<dict-tag :options="biz_shipping_method" :value="scope.row.shippingMethod" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<el-table-column label="操作" v-hasRoles="['superadmin']" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['amz:logisticsChannel:edit']"></el-button>
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="Edit"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasRoles="['superadmin']"
|
||||
v-hasPermi="['amz:logisticsChannel:edit']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['amz:logisticsChannel:remove']"></el-button>
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="Delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasRoles="['superadmin']"
|
||||
v-hasPermi="['amz:logisticsChannel:remove']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
@ -10,36 +10,15 @@
|
||||
<el-form-item label="订单编号" prop="orderId">
|
||||
<el-input v-model="queryParams.orderId" placeholder="请输入订单编号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="物流商ID" prop="logisticsProviderId">
|
||||
<el-input v-model="queryParams.logisticsProviderId" placeholder="请输入物流商ID" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="物流商名称" prop="logisticsProviderName">
|
||||
<el-input v-model="queryParams.logisticsProviderName" placeholder="请输入物流商名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="物流渠道" prop="logisticsChannel">
|
||||
<el-input v-model="queryParams.logisticsChannel" placeholder="请输入物流渠道" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="目的地仓库名称或编码" prop="destination">
|
||||
<el-form-item label="仓库名称" prop="destination">
|
||||
<el-input v-model="queryParams.destination" placeholder="请输入目的地仓库名称或编码" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="总箱子数量" prop="boxQuantity">
|
||||
<el-input v-model="queryParams.boxQuantity" placeholder="请输入总箱子数量" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="总货件数量" prop="shipmentQuantity">
|
||||
<el-input v-model="queryParams.shipmentQuantity" placeholder="请输入总货件数量" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="亚马逊仓库实际上架日期" prop="amazonShelfDate">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="queryParams.amazonShelfDate"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择亚马逊仓库实际上架日期"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="上架时效" prop="shelfTimeliness">
|
||||
<el-input v-model="queryParams.shelfTimeliness" placeholder="请输入上架时效" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
@ -78,7 +57,7 @@
|
||||
<el-table-column label="订单编号" align="center" prop="orderId" />
|
||||
<el-table-column label="创建日期" align="center" prop="createTime" />
|
||||
<el-table-column label="物流商名称" align="center" prop="logisticsProviderName" />
|
||||
<el-table-column label="物流渠道" align="center" prop="logisticsChannel" />
|
||||
<el-table-column label="物流渠道" align="center" prop="channelName" />
|
||||
<el-table-column label="目的地仓库名称或编码" align="center" prop="destination" />
|
||||
<el-table-column label="总箱子数量" align="center" prop="boxQuantity" />
|
||||
<el-table-column label="总货件数量" align="center" prop="shipmentQuantity" />
|
||||
@ -103,7 +82,7 @@
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['amz:logisticsOrder:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-button type="primary" @click="openDetail(scope.row)" v-hasRoles="['wuliu']"> 编辑订单明细</el-button>
|
||||
<el-button link size="small" type="primary" @click="openDetail(scope.row)" v-hasRoles="['wuliu']"> 编辑订单明细 </el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@ -129,7 +108,7 @@
|
||||
<el-input v-model="form.logisticsProviderName" placeholder="请输入物流商名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="物流渠道" prop="logisticsChannel">
|
||||
<el-input v-model="form.logisticsChannel" placeholder="请输入物流渠道" />
|
||||
<el-input v-model="form.channelName" placeholder="请输入物流渠道" />
|
||||
</el-form-item>
|
||||
<el-form-item label="目的地仓库名称或编码" prop="destination">
|
||||
<el-input v-model="form.destination" placeholder="请输入目的地仓库名称或编码" />
|
||||
@ -167,6 +146,14 @@
|
||||
<h4>订单明细</h4>
|
||||
</template>
|
||||
<template #default>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Document" @click="handleExportDetail"> 导出模板文件</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<OrderDetailFileUpload :file-type="['xlsx', 'xls']" :file-size="20" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<HotTable class="hot-container" ref="hotTable" :settings="hotSettings" :data="processedData" :key="tableKey"></HotTable>
|
||||
<pagination
|
||||
v-show="detailTotal > 0"
|
||||
@ -303,12 +290,11 @@ const hotSettings = ref({
|
||||
'订单号',
|
||||
'FBA货件编号',
|
||||
'FBA箱号',
|
||||
'物流商ID',
|
||||
'物流商名称',
|
||||
'物流渠道',
|
||||
'目的地仓库',
|
||||
'计划数量',
|
||||
'实际货件数量',
|
||||
'实际数量',
|
||||
'物流追踪号',
|
||||
'物流商计重',
|
||||
'称重差异',
|
||||
@ -334,17 +320,33 @@ const hotSettings = ref({
|
||||
{ data: 'fbaShipmentId', className: 'htCenter', readOnly: true },
|
||||
// ... 其他数据列配置
|
||||
{ data: 'fbaBoxNumber', className: 'htCenter', readOnly: true }, // FBA箱号
|
||||
{ data: 'logisticsProviderId', className: 'htCenter', readOnly: true }, // 物流商ID
|
||||
{ data: 'logisticsProviderName', className: 'htCenter', readOnly: true }, // 物流商名称
|
||||
{ data: 'logisticsChannel', className: 'htCenter', readOnly: true }, // 物流渠道
|
||||
{ data: 'destinationWarehouse', className: 'htCenter', readOnly: true }, // 目的地仓库
|
||||
{ data: 'plannedQuantity', className: 'htCenter', readOnly: true }, // 计划数量
|
||||
{ data: 'actualShipmentQuantity', className: 'htCenter', readOnly: true }, // 实际货件数量
|
||||
{ data: 'shipmentQuantity', className: 'htCenter', readOnly: false, type: 'numeric' }, // 实际数量
|
||||
{ data: 'trackingNumber', className: 'htCenter', readOnly: false }, // 物流追踪号
|
||||
{ data: 'logisticsWeight', className: 'htCenter', readOnly: true }, // 物流商计重
|
||||
{
|
||||
data: 'logisticsWeight',
|
||||
className: 'htCenter',
|
||||
readOnly: false,
|
||||
type: 'numeric',
|
||||
renderer: function (instance, td, row, col, prop, value, cellProperties) {
|
||||
// 调用默认的数字渲染器以保持格式(如千分位)
|
||||
// 处理单位显示
|
||||
if (typeof value === 'number' && !isNaN(value)) {
|
||||
td.textContent = value.toLocaleString() + ' kg'; // 添加单位
|
||||
}
|
||||
|
||||
// 确保居中对齐(可选,若 className 已生效可省略)
|
||||
return td;
|
||||
}
|
||||
}, // 物流商计重
|
||||
{
|
||||
data: 'weightDiff', // 称重差异
|
||||
className: 'htCenter',
|
||||
readOnly: true,
|
||||
type: 'numeric',
|
||||
renderer: (instance, td) => {
|
||||
// 添加差异颜色标识
|
||||
const value = instance.getDataAtCell(td.row, td.col);
|
||||
@ -353,9 +355,39 @@ const hotSettings = ref({
|
||||
return td;
|
||||
}
|
||||
},
|
||||
{ data: 'pricePerKg', className: 'htCenter', readOnly: true }, // 物流单价
|
||||
{ data: 'logisticsBillingWeight', className: 'htCenter', readOnly: true }, // 物流计价重量
|
||||
{ data: 'otherLogisticsFee', className: 'htCenter', readOnly: true }, // 其他物流费用
|
||||
{
|
||||
data: 'pricePerKg',
|
||||
className: 'htCenter',
|
||||
type: 'numeric',
|
||||
readOnly: true,
|
||||
renderer: function (instance, td, row, col, prop, value, cellProperties) {
|
||||
// 调用默认的数字渲染器以保持格式(如千分位)
|
||||
// 处理单位显示
|
||||
if (typeof value === 'number' && !isNaN(value)) {
|
||||
td.textContent = value.toLocaleString() + ' 元/kg'; // 添加单位
|
||||
}
|
||||
|
||||
// 确保居中对齐(可选,若 className 已生效可省略)
|
||||
return td;
|
||||
}
|
||||
}, // 物流单价
|
||||
{ data: 'logisticsBillingWeight', className: 'htCenter', type: 'numeric', readOnly: true }, // 物流计价重量
|
||||
{
|
||||
data: 'otherLogisticsFee',
|
||||
className: 'htCenter',
|
||||
type: 'numeric',
|
||||
readOnly: false,
|
||||
renderer: function (instance, td, row, col, prop, value, cellProperties) {
|
||||
// 调用默认的数字渲染器以保持格式(如千分位)
|
||||
// 处理单位显示
|
||||
if (typeof value === 'number' && !isNaN(value)) {
|
||||
td.textContent = value.toLocaleString() + ' 元'; // 添加单位
|
||||
}
|
||||
|
||||
// 确保居中对齐(可选,若 className 已生效可省略)
|
||||
return td;
|
||||
}
|
||||
}, // 其他物流费用
|
||||
{ data: 'totalFee', className: 'htCenter', readOnly: true }, // 费用合计
|
||||
{
|
||||
data: 'logisticsStatus',
|
||||
@ -410,46 +442,20 @@ const hotSettings = ref({
|
||||
className: 'htCenter' // 单元格内容居中
|
||||
},
|
||||
{
|
||||
// 操作列
|
||||
// renderer: (instance, td, row, col, prop, value, cellProperties) => {
|
||||
// const canEdit = checkPermi(['amz:logisticsOrderDetail:edit']);
|
||||
// const canDelete = checkPermi(['amz:logisticsOrderDetail:remove']);
|
||||
//
|
||||
// td.innerHTML = `
|
||||
// <div class="action-buttons">
|
||||
// ${
|
||||
// canEdit
|
||||
// ? `
|
||||
// <button
|
||||
// class="edit-btn"
|
||||
// data-row="${row}"
|
||||
// :disabled="buttonLoading"
|
||||
// >
|
||||
// <i class="icon-edit"></i>
|
||||
// </button>
|
||||
// `
|
||||
// : ''
|
||||
// }
|
||||
// ${
|
||||
// canDelete
|
||||
// ? `
|
||||
// <button
|
||||
// class="delete-btn"
|
||||
// data-row="${row}"
|
||||
// :disabled="buttonLoading"
|
||||
// >
|
||||
// <i class="icon-delete"></i>
|
||||
// </button>
|
||||
// `
|
||||
// : ''
|
||||
// }
|
||||
// </div>
|
||||
// `;
|
||||
// td.className = 'htCenter';
|
||||
// return td;
|
||||
// },
|
||||
readOnly: true,
|
||||
width: 150
|
||||
data: 'timeliness',
|
||||
readOnly: false,
|
||||
width: 150,
|
||||
type: 'numeric',
|
||||
renderer: function (instance, td, row, col, prop, value, cellProperties) {
|
||||
// 调用默认的数字渲染器以保持格式(如千分位)
|
||||
// 处理单位显示
|
||||
if (typeof value === 'number' && !isNaN(value)) {
|
||||
td.textContent = value.toLocaleString() + ' 天'; // 添加单位
|
||||
}
|
||||
|
||||
// 确保居中对齐(可选,若 className 已生效可省略)
|
||||
return td;
|
||||
}
|
||||
}
|
||||
],
|
||||
afterOnCellMouseDown: (event, coords) => {
|
||||
@ -524,7 +530,7 @@ const initFormData: LogisticsOrderForm = {
|
||||
orderId: undefined,
|
||||
logisticsProviderId: undefined,
|
||||
logisticsProviderName: undefined,
|
||||
logisticsChannel: undefined,
|
||||
channelName: undefined,
|
||||
destination: undefined,
|
||||
boxQuantity: undefined,
|
||||
shipmentQuantity: undefined,
|
||||
@ -710,6 +716,16 @@ const handleExport = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const handleExportDetail = () => {
|
||||
proxy?.download(
|
||||
'amz/logisticsOrderDetail/export',
|
||||
{
|
||||
...queryDetailParams.value
|
||||
},
|
||||
`logisticsOrderDetail_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
|
@ -4,9 +4,6 @@
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="物流商用户ID" prop="userId">
|
||||
<el-input v-model="queryParams.userId" placeholder="请输入物流商用户ID" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="目的地" prop="destination">
|
||||
<el-input v-model="queryParams.destination" placeholder="请输入目的地" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
@ -25,9 +22,6 @@
|
||||
<el-form-item label="报价生效日期" prop="quoteDate">
|
||||
<el-date-picker clearable v-model="queryParams.quoteDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择报价生效日期" />
|
||||
</el-form-item>
|
||||
<el-form-item label="渠道ID" prop="channelId">
|
||||
<el-input v-model="queryParams.channelId" placeholder="请输入渠道ID" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="单位" prop="unit">
|
||||
<el-input v-model="queryParams.unit" placeholder="请输入单位" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
@ -92,12 +86,12 @@
|
||||
<el-table-column label="物流商" align="center" prop="logisticsName" />
|
||||
<el-table-column label="目的地" align="center" prop="destination" />
|
||||
<el-table-column label="渠道名称" align="center" prop="channelName" />
|
||||
<el-table-column label="基础价格" align="center" prop="price">
|
||||
<el-table-column label="基础价格" align="center" sortable prop="price">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.price + '元/kg' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="时效" align="center" prop="leadTime">
|
||||
<el-table-column label="时效" align="center" sortable prop="leadTime">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.leadTime + '天' }}</span>
|
||||
</template>
|
||||
@ -129,7 +123,7 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单位" align="center" prop="unit" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<el-table-column label="操作" align="center" v-hasRoles="['wuliu']" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button
|
||||
|
@ -29,12 +29,7 @@
|
||||
<el-input v-model="queryParams.sku" placeholder="请输入商品SKU" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="有效期" prop="expiration">
|
||||
<el-date-picker clearable
|
||||
v-model="queryParams.expiration"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择有效期"
|
||||
/>
|
||||
<el-date-picker clearable v-model="queryParams.expiration" type="date" value-format="YYYY-MM-DD" placeholder="请选择有效期" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
@ -49,16 +44,20 @@
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['amz:shipmentItem:add']">新增</el-button>
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['amz:shipmentItem:add']">新增 </el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['amz:shipmentItem:edit']">修改</el-button>
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['amz:shipmentItem:edit']"
|
||||
>修改
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['amz:shipmentItem:remove']">删除</el-button>
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['amz:shipmentItem:remove']"
|
||||
>删除
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['amz:shipmentItem:export']">导出</el-button>
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['amz:shipmentItem:export']">导出 </el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
@ -125,11 +124,7 @@
|
||||
<el-input v-model="form.sku" placeholder="请输入商品SKU" />
|
||||
</el-form-item>
|
||||
<el-form-item label="有效期" prop="expiration">
|
||||
<el-date-picker clearable
|
||||
v-model="form.expiration"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="请选择有效期">
|
||||
<el-date-picker clearable v-model="form.expiration" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择有效期">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
@ -176,10 +171,10 @@ const initFormData: ShipmentItemForm = {
|
||||
prepInstruction: undefined,
|
||||
prepOwner: undefined,
|
||||
sku: undefined,
|
||||
expiration: undefined,
|
||||
}
|
||||
expiration: undefined
|
||||
};
|
||||
const data = reactive<PageData<ShipmentItemForm, ShipmentItemQuery>>({
|
||||
form: {...initFormData},
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
@ -192,40 +187,19 @@ const data = reactive<PageData<ShipmentItemForm, ShipmentItemQuery>>({
|
||||
prepOwner: undefined,
|
||||
sku: undefined,
|
||||
expiration: undefined,
|
||||
params: {
|
||||
}
|
||||
params: {}
|
||||
},
|
||||
rules: {
|
||||
id: [
|
||||
{ required: true, message: "主键ID不能为空", trigger: "blur" }
|
||||
],
|
||||
shipmentId: [
|
||||
{ required: true, message: "关联货件ID不能为空", trigger: "blur" }
|
||||
],
|
||||
msku: [
|
||||
{ required: true, message: "商家SKU不能为空", trigger: "blur" }
|
||||
],
|
||||
fnsku: [
|
||||
{ required: true, message: "仓储编码不能为空", trigger: "blur" }
|
||||
],
|
||||
quantityShipped: [
|
||||
{ required: true, message: "发货量不能为空", trigger: "blur" }
|
||||
],
|
||||
quantityReceived: [
|
||||
{ required: true, message: "收货量不能为空", trigger: "blur" }
|
||||
],
|
||||
prepInstruction: [
|
||||
{ required: true, message: "预处理说明不能为空", trigger: "blur" }
|
||||
],
|
||||
prepOwner: [
|
||||
{ required: true, message: "责任方不能为空", trigger: "blur" }
|
||||
],
|
||||
sku: [
|
||||
{ required: true, message: "商品SKU不能为空", trigger: "blur" }
|
||||
],
|
||||
expiration: [
|
||||
{ required: true, message: "有效期不能为空", trigger: "blur" }
|
||||
],
|
||||
id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }],
|
||||
shipmentId: [{ required: true, message: '关联货件ID不能为空', trigger: 'blur' }],
|
||||
msku: [{ required: true, message: '商家SKU不能为空', trigger: 'blur' }],
|
||||
fnsku: [{ required: true, message: '仓储编码不能为空', trigger: 'blur' }],
|
||||
quantityShipped: [{ required: true, message: '发货量不能为空', trigger: 'blur' }],
|
||||
quantityReceived: [{ required: true, message: '收货量不能为空', trigger: 'blur' }],
|
||||
prepInstruction: [{ required: true, message: '预处理说明不能为空', trigger: 'blur' }],
|
||||
prepOwner: [{ required: true, message: '责任方不能为空', trigger: 'blur' }],
|
||||
sku: [{ required: true, message: '商品SKU不能为空', trigger: 'blur' }],
|
||||
expiration: [{ required: true, message: '有效期不能为空', trigger: 'blur' }]
|
||||
}
|
||||
});
|
||||
|
||||
@ -238,55 +212,55 @@ const getList = async () => {
|
||||
shipmentItemList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
}
|
||||
};
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = {...initFormData};
|
||||
form.value = { ...initFormData };
|
||||
shipmentItemFormRef.value?.resetFields();
|
||||
}
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
};
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
};
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: ShipmentItemVO[]) => {
|
||||
ids.value = selection.map(item => item.id);
|
||||
ids.value = selection.map((item) => item.id);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
};
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
reset();
|
||||
dialog.visible = true;
|
||||
dialog.title = "添加货品明细";
|
||||
}
|
||||
dialog.title = '添加货品明细';
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: ShipmentItemVO) => {
|
||||
reset();
|
||||
const _id = row?.id || ids.value[0]
|
||||
const _id = row?.id || ids.value[0];
|
||||
const res = await getShipmentItem(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
dialog.visible = true;
|
||||
dialog.title = "修改货品明细";
|
||||
}
|
||||
dialog.title = '修改货品明细';
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
@ -294,32 +268,36 @@ const submitForm = () => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
if (form.value.id) {
|
||||
await updateShipmentItem(form.value).finally(() => buttonLoading.value = false);
|
||||
await updateShipmentItem(form.value).finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
await addShipmentItem(form.value).finally(() => buttonLoading.value = false);
|
||||
await addShipmentItem(form.value).finally(() => (buttonLoading.value = false));
|
||||
}
|
||||
proxy?.$modal.msgSuccess("操作成功");
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: ShipmentItemVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除货品明细编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
|
||||
await proxy?.$modal.confirm('是否确认删除货品明细编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
|
||||
await delShipmentItem(_ids);
|
||||
proxy?.$modal.msgSuccess("删除成功");
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
}
|
||||
};
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download('amz/shipmentItem/export', {
|
||||
...queryParams.value
|
||||
}, `shipmentItem_${new Date().getTime()}.xlsx`)
|
||||
}
|
||||
proxy?.download(
|
||||
'amz/shipmentItem/export',
|
||||
{
|
||||
...queryParams.value
|
||||
},
|
||||
`shipmentItem_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
|
@ -1,413 +1,444 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="关联系统ID" prop="sid">
|
||||
<el-input v-model="queryParams.sid" placeholder="请输入关联系统ID" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="货件编号" prop="shipmentId">
|
||||
<el-input v-model="queryParams.shipmentId" placeholder="请输入货件编号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="货件名称" prop="shipmentName">
|
||||
<el-input v-model="queryParams.shipmentName" placeholder="请输入货件名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="物流中心编码" prop="destination">
|
||||
<el-input v-model="queryParams.destination" placeholder="请输入物流中心编码" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="运输模式" prop="shippingMode">
|
||||
<el-input v-model="queryParams.shippingMode" placeholder="请输入运输模式" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="运输方案" prop="shippingSolution">
|
||||
<el-input v-model="queryParams.shippingSolution" placeholder="请输入运输方案" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="最后更新时间" prop="gmtModified">
|
||||
<el-date-picker clearable v-model="queryParams.gmtModified" type="date" value-format="YYYY-MM-DD" placeholder="请选择最后更新时间" />
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="gmtCreate">
|
||||
<el-date-picker clearable v-model="queryParams.gmtCreate" type="date" value-format="YYYY-MM-DD" placeholder="请选择创建时间" />
|
||||
</el-form-item>
|
||||
<el-form-item label="同步时间" prop="syncTime">
|
||||
<el-date-picker clearable v-model="queryParams.syncTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择同步时间" />
|
||||
</el-form-item>
|
||||
<el-form-item label="计划发货日期" prop="staShipmentDate">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="queryParams.staShipmentDate"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择计划发货日期"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="预计到货开始日" prop="staDeliveryStartDate">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="queryParams.staDeliveryStartDate"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择预计到货开始日"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="预计到货截止日" prop="staDeliveryEndDate">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="queryParams.staDeliveryEndDate"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择预计到货截止日"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="参考编号" prop="referenceId">
|
||||
<el-input v-model="queryParams.referenceId" placeholder="请输入参考编号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="入库计划ID" prop="staInboundPlanId">
|
||||
<el-input v-model="queryParams.staInboundPlanId" placeholder="请输入入库计划ID" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['amz:shipmentPlan:add']">新增 </el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['amz:shipmentPlan:edit']"
|
||||
>修改
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['amz:shipmentPlan:remove']"
|
||||
>删除
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['amz:shipmentPlan:export']">导出 </el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="shipmentPlanList" @current-change="handleCurrentChange" highlight-current-row ref="singleTableRef">
|
||||
<el-table-column type="expand">
|
||||
<template #default="props">
|
||||
<el-descriptions size="small" border title="货件详情">
|
||||
<el-descriptions-item label="货件名称">{{ props.row.shipmentName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="是否关闭">{{ props.row.isClosed }}</el-descriptions-item>
|
||||
<el-descriptions-item label="货件状态">{{ props.row.shipmentStatus }}</el-descriptions-item>
|
||||
<el-descriptions-item label="运输模式">{{ props.row.shippingMode }}</el-descriptions-item>
|
||||
<el-descriptions-item label="运输方案">{{ props.row.shippingSolution }}</el-descriptions-item>
|
||||
<el-descriptions-item label="入库计划ID">{{ props.row.staInboundPlanId }}</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="同步时间">{{ parseTime(props.row.gmtCreate, '{y}-{m}-{d}') }} </el-descriptions-item>
|
||||
<el-descriptions-item label="计划发货日期">{{ parseTime(props.row.staShipmentDate, '{y}-{m}-{d}') }} </el-descriptions-item>
|
||||
<el-descriptions-item label="预计到货开始日">{{ parseTime(props.row.staDeliveryStartDate, '{y}-{m}-{d}') }} </el-descriptions-item>
|
||||
<el-descriptions-item label="预计到货截止日">{{ parseTime(props.row.staDeliveryEndDate, '{y}-{m}-{d}') }} </el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="领星ID" align="center" prop="sid" />
|
||||
<el-table-column label="货件编号" align="center" prop="shipmentId" />
|
||||
|
||||
<el-table-column label="物流中心编码" align="center" prop="destination" />
|
||||
|
||||
<el-table-column label="最后更新时间" align="center" prop="gmtModified" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.gmtModified, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="gmtCreate" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.gmtCreate, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="150" label="发货地址" align="center" prop="shipFromAddress">
|
||||
<template #default="{ row }">
|
||||
<el-button @click="openAddressDialog(row.shipFromAddress)"> 查看详情</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="150" label="收货地址" align="center" prop="shipToAddress">
|
||||
<template #default="{ row }">
|
||||
<el-button @click="openAddressDialog(row.shipToAddress)"> 查看详情</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="参考编号" align="center" prop="referenceId" />
|
||||
<el-table-column label="是否STA计划" align="center" prop="isSta" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['amz:shipmentPlan:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<!-- <el-tooltip content="删除" placement="top">-->
|
||||
<!-- <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['amz:shipmentPlan:remove']"></el-button>-->
|
||||
<!-- </el-tooltip>-->
|
||||
<el-tooltip content="发货" placement="top">
|
||||
<el-button link type="primary" icon="Promotion" @click="handleSend(scope.row)" v-hasPermi="['amz:shipmentPlan:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
<!-- 添加或修改货件计划对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="shipmentPlanFormRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="关联系统ID" prop="sid">
|
||||
<el-input v-model="form.sid" placeholder="请输入关联系统ID" />
|
||||
</el-form-item>
|
||||
<el-form-item label="货件编号" prop="shipmentId">
|
||||
<el-input v-model="form.shipmentId" placeholder="请输入货件编号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="货件名称" prop="shipmentName">
|
||||
<el-input v-model="form.shipmentName" placeholder="请输入货件名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="物流中心编码" prop="destination">
|
||||
<el-input v-model="form.destination" placeholder="请输入物流中心编码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="运输模式" prop="shippingMode">
|
||||
<el-input v-model="form.shippingMode" placeholder="请输入运输模式" />
|
||||
</el-form-item>
|
||||
<el-form-item label="运输方案" prop="shippingSolution">
|
||||
<el-input v-model="form.shippingSolution" placeholder="请输入运输方案" />
|
||||
</el-form-item>
|
||||
<el-form-item label="最后更新时间" prop="gmtModified">
|
||||
<el-date-picker clearable v-model="form.gmtModified" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择最后更新时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="gmtCreate">
|
||||
<el-date-picker clearable v-model="form.gmtCreate" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择创建时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="同步时间" prop="syncTime">
|
||||
<el-date-picker clearable v-model="form.syncTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择同步时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="计划发货日期" prop="staShipmentDate">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="form.staShipmentDate"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="请选择计划发货日期"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="预计到货开始日" prop="staDeliveryStartDate">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="form.staDeliveryStartDate"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="请选择预计到货开始日"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="预计到货截止日" prop="staDeliveryEndDate">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="form.staDeliveryEndDate"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="请选择预计到货截止日"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="参考编号" prop="referenceId">
|
||||
<el-input v-model="form.referenceId" placeholder="请输入参考编号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="入库计划ID" prop="staInboundPlanId">
|
||||
<el-input v-model="form.staInboundPlanId" placeholder="请输入入库计划ID" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
<el-watermark :content="['Element+', 'Element Plus']">
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="关联系统ID" prop="sid">
|
||||
<el-input v-model="queryParams.sid" placeholder="请输入关联系统ID" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="货件编号" prop="shipmentId">
|
||||
<el-input v-model="queryParams.shipmentId" placeholder="请输入货件编号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="货件名称" prop="shipmentName">
|
||||
<el-input v-model="queryParams.shipmentName" placeholder="请输入货件名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="物流中心编码" prop="destination">
|
||||
<el-input v-model="queryParams.destination" placeholder="请输入物流中心编码" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="运输模式" prop="shippingMode">
|
||||
<el-input v-model="queryParams.shippingMode" placeholder="请输入运输模式" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="运输方案" prop="shippingSolution">
|
||||
<el-input v-model="queryParams.shippingSolution" placeholder="请输入运输方案" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="最后更新时间" prop="gmtModified">
|
||||
<el-date-picker clearable v-model="queryParams.gmtModified" type="date" value-format="YYYY-MM-DD" placeholder="请选择最后更新时间" />
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="gmtCreate">
|
||||
<el-date-picker clearable v-model="queryParams.gmtCreate" type="date" value-format="YYYY-MM-DD" placeholder="请选择创建时间" />
|
||||
</el-form-item>
|
||||
<el-form-item label="同步时间" prop="syncTime">
|
||||
<el-date-picker clearable v-model="queryParams.syncTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择同步时间" />
|
||||
</el-form-item>
|
||||
<el-form-item label="计划发货日期" prop="staShipmentDate">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="queryParams.staShipmentDate"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择计划发货日期"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="预计到货开始日" prop="staDeliveryStartDate">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="queryParams.staDeliveryStartDate"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择预计到货开始日"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="预计到货截止日" prop="staDeliveryEndDate">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="queryParams.staDeliveryEndDate"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择预计到货截止日"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="参考编号" prop="referenceId">
|
||||
<el-input v-model="queryParams.referenceId" placeholder="请输入参考编号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="入库计划ID" prop="staInboundPlanId">
|
||||
<el-input v-model="queryParams.staInboundPlanId" placeholder="请输入入库计划ID" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- 详情对话框 -->
|
||||
<el-dialog v-model="dialogVisible" title="地址详细信息" width="60%">
|
||||
<el-table :data="addressTableData">
|
||||
<el-table-column prop="key" label="字段" width="180" />
|
||||
<el-table-column prop="value" label="值" />
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
</transition>
|
||||
|
||||
<el-dialog v-model="channelDialogVisible" title="查询报价" width="60%">
|
||||
<!-- <el-radio-group v-model="form.status">-->
|
||||
<!-- <el-radio v-for="dict in biz_transport_channel" :key="dict.value" :value="dict.value">-->
|
||||
<!-- {{ dict.label }}-->
|
||||
<!-- </el-radio>-->
|
||||
<!-- </el-radio-group>-->
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['amz:shipmentPlan:add']"> 新增 </el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['amz:shipmentPlan:edit']"
|
||||
>修改
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['amz:shipmentPlan:remove']"
|
||||
>删除
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['amz:shipmentPlan:export']">导出 </el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="snycTodayPlan" v-hasPermi="['amz:shipmentPlan:export']"
|
||||
>同步今天的货件
|
||||
</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<!-- <el-radio-group v-model="form.status">-->
|
||||
<!-- <!– 按国家分组循环 –>-->
|
||||
<!-- <div v-for="(transportDict, country) in groupedChannels" :key="country">-->
|
||||
<!-- <!– 国家标题 –>-->
|
||||
<!-- <div class="country-title">{{ country }}</div>-->
|
||||
<el-table v-loading="loading" :data="shipmentPlanList" @current-change="handleCurrentChange" highlight-current-row ref="singleTableRef">
|
||||
<el-table-column type="expand">
|
||||
<template #default="props">
|
||||
<el-descriptions size="small" border title="货件详情">
|
||||
<el-descriptions-item label="货件名称">{{ props.row.shipmentName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="是否关闭">
|
||||
<dict-tag :options="sys_zero_one" :value="props.row.isClosed" />
|
||||
</el-descriptions-item>
|
||||
<!-- <el-descriptions-item label="货件状态">{{ props.row.shipmentStatus }}</el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="运输模式">{{ props.row.shippingMode }}</el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="运输方案">{{ props.row.shippingSolution }}</el-descriptions-item>-->
|
||||
<el-descriptions-item label="入库计划ID">{{ props.row.staInboundPlanId }}</el-descriptions-item>
|
||||
|
||||
<!-- <!– 运输方式子分组 –>-->
|
||||
<!-- <div-->
|
||||
<!-- v-for="(channels, transport) in transportDict"-->
|
||||
<!-- :key="transport"-->
|
||||
<!-- class="transport-group"-->
|
||||
<!-- >-->
|
||||
<!-- <el-radio-->
|
||||
<!-- v-for="dict in channels"-->
|
||||
<!-- :key="dict.value"-->
|
||||
<!-- :value="dict.value"-->
|
||||
<!-- border-->
|
||||
<!-- class="channel-item"-->
|
||||
<!-- >-->
|
||||
<!-- {{ transport }} - {{ getChannelName(dict.label) }}-->
|
||||
<!-- </el-radio>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </el-radio-group>-->
|
||||
<el-form :model="form" label-width="auto" style="max-width: 600px">
|
||||
<el-form-item label="目的地仓库">
|
||||
<el-input v-model="currentDes" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="渠道选择">
|
||||
<!-- <el-collapse v-model="activeCollapse">-->
|
||||
<!-- <!– 遍历国家分组 –>-->
|
||||
<!-- <el-collapse-item v-for="(countryGroup, country) in groupedChannels" :key="country" :title="getCountryName(country)" :name="country">-->
|
||||
<!-- <!– 遍历运输方式 –>-->
|
||||
<!-- <div v-for="(methodGroup, method) in countryGroup" :key="method">-->
|
||||
<!-- <div class="shipping-method-title">-->
|
||||
<!-- {{ getShippingMethodName(method) }}-->
|
||||
<!-- </div>-->
|
||||
<!-- <el-radio-group v-model="selectedChannel" @change="handleChannelSelect">-->
|
||||
<!-- <!– 遍历具体渠道 –>-->
|
||||
<!-- <div v-for="channel in methodGroup" :key="channel.id" class="channel-item">-->
|
||||
<!-- <el-radio :label="channel.id">-->
|
||||
<!-- {{ getChannelLabel(channel.channelName) }}-->
|
||||
<!-- </el-radio>-->
|
||||
<!-- <div class="channel-description">{{ channel.description }}</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </el-radio-group>-->
|
||||
<!-- </div>-->
|
||||
<!-- </el-collapse-item>-->
|
||||
<!-- </el-collapse>-->
|
||||
<el-cascader
|
||||
v-model="selectedChannel"
|
||||
placeholder="请选择渠道"
|
||||
:props="{ emitPath: false }"
|
||||
:options="groupedChannels"
|
||||
@change="cascaderChange"
|
||||
:show-all-levels="false"
|
||||
filterable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="日期选择">
|
||||
<el-date-picker v-model="shipDate" type="date" placeholder="Pick a day" value-format="YYYY-MM-DD" :size="size" />
|
||||
</el-form-item>
|
||||
<el-button :loading="buttonLoading" type="primary" @click="checkPrice()">查询报价</el-button>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="dialogTableVisible" title="已经存在的询价单" width="1800">
|
||||
<el-table :data="tableData" style="width: 100%" border stripe>
|
||||
<!-- 基础文本列 -->
|
||||
<el-table-column prop="inquiryNo" label="询价编号" width="180" />
|
||||
<el-table-column prop="channelName" label="渠道名称" width="200" />
|
||||
<el-table-column prop="transportChannel" label="运输方式" width="120" />
|
||||
<el-table-column prop="quoteDate" label="询价日期" width="200" />
|
||||
<!-- 时间格式化列 -->
|
||||
<el-table-column prop="deadline" label="截止时间" width="180">
|
||||
<template #default="{ row }">
|
||||
{{ formatTime(row.deadline) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="effectiveStartTime" label="生效开始时间" width="180">
|
||||
<template #default="{ row }">
|
||||
{{ formatTime(row.effectiveStartTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="effectiveEndTime" label="生效结束时间" width="180">
|
||||
<template #default="{ row }">
|
||||
{{ formatTime(row.effectiveEndTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 状态标签列 -->
|
||||
<el-table-column prop="inquiryStatus" label="询价状态" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="statusTagType(row.inquiryStatus)" effect="light">
|
||||
{{ row.inquiryStatus }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 其他信息列 -->
|
||||
<el-table-column prop="destination" label="目的地" width="120" />
|
||||
|
||||
<el-table-column prop="requesterId" label="请求方ID" width="120" />
|
||||
|
||||
<!-- 空值处理 -->
|
||||
<el-table-column prop="targetProviders" label="目标供应商">
|
||||
<template #default="{ row }">
|
||||
{{ row.targetProviders || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<el-drawer size="60%" v-model="drawer" :direction="direction">
|
||||
<template #header>
|
||||
<h4>物流商报价</h4>
|
||||
</template>
|
||||
<template #default>
|
||||
<el-table v-loading="loading" :data="logisticsQuoteList" @selection-change="handleSelectionChange">
|
||||
<el-table-column label="物流商用户ID" align="center" prop="userId" />
|
||||
<el-table-column label="目的地" align="center" prop="destination" />
|
||||
<el-table-column label="渠道名称" align="center" prop="channelName" />
|
||||
<el-table-column label="基础价格" align="center" prop="price" />
|
||||
<el-table-column label="时效" align="center" prop="leadTime" />
|
||||
<el-table-column label="附加费" align="center" prop="surcharge" />
|
||||
<el-table-column label="报价生效日期" align="center" prop="quoteDate" width="80">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.quoteDate, '{y}-{m}-{d}') }}</span>
|
||||
<el-descriptions-item label="创建时间">{{ parseTime(props.row.gmtCreate, '{y}-{m}-{d}') }} </el-descriptions-item>
|
||||
<!-- <el-descriptions-item label="计划发货日期">{{ parseTime(props.row.staShipmentDate, '{y}-{m}-{d}') }} </el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="预计到货开始日">{{ parseTime(props.row.staDeliveryStartDate, '{y}-{m}-{d}') }} </el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="预计到货截止日">{{ parseTime(props.row.staDeliveryEndDate, '{y}-{m}-{d}') }} </el-descriptions-item>-->
|
||||
</el-descriptions>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="领星ID" align="center" prop="sid" />
|
||||
<el-table-column label="货件编号" align="center" prop="shipmentId" />
|
||||
<el-table-column label="商品详情" align="center">
|
||||
<template #default="scope">
|
||||
<el-popover placement="top" :width="600" trigger="hover" @show="showPop(scope.row)">
|
||||
<template #reference>
|
||||
<el-button style="margin-right: 16px">查看</el-button>
|
||||
</template>
|
||||
<el-table :data="scope.row.itemVoList">
|
||||
<el-table-column width="200" property="productName" label="品名" />
|
||||
<el-table-column width="200" property="msku" label="msku" />
|
||||
</el-table>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="物流中心编码" align="center" prop="destination" />
|
||||
<el-table-column label="箱子数量" align="center" prop="boxNum" />
|
||||
<el-table-column label="货件状态" align="center" prop="gmtCreate" width="180">
|
||||
<template #default="scope">
|
||||
<el-tag>{{ scope.row.shipmentStatus }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="发货日期" align="center" prop="gmtCreate" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.staShipmentDate, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="150" label="发货地址" align="center" prop="shipFromAddress">
|
||||
<template #default="{ row }">
|
||||
<el-button @click="openAddressDialog(row.shipFromAddress)"> 查看详情</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="150" label="收货地址" align="center" prop="shipToAddress">
|
||||
<template #default="{ row }">
|
||||
<el-button @click="openAddressDialog(row.shipToAddress)"> 查看详情</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="是否STA计划" align="center" prop="isSta">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="sys_zero_one" :value="scope.row.isSta" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="提交状态" align="center" prop="isSubmitted" />
|
||||
<el-table-column label="报价备注" align="center" prop="remark" />
|
||||
<el-table-column label="渠道类型" align="center" prop="channelType" />
|
||||
<el-table-column label="是否双清包税" align="center" prop="isDdp" />
|
||||
<el-table-column label="单位" align="center" prop="unit" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button text size="small" type="primary" @click="createOrder(scope.row)" v-hasPermi="['amz:logisticsQuote:edit']">
|
||||
创建货运订单
|
||||
</el-button>
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['amz:shipmentPlan:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<!-- <el-tooltip content="删除" placement="top">-->
|
||||
<!-- <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['amz:shipmentPlan:remove']"></el-button>-->
|
||||
<!-- </el-tooltip>-->
|
||||
<el-tooltip content="发货" placement="top">
|
||||
<el-button link type="primary" icon="Promotion" @click="handleSend(scope.row)" v-hasPermi="['amz:shipmentPlan:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
<template #footer>
|
||||
<div style="flex: auto">
|
||||
<el-button @click="cancelClick">取消</el-button>
|
||||
<el-button type="primary" @click="confirmClick">确认</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</div>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
<!-- 添加或修改货件计划对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="shipmentPlanFormRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="关联系统ID" prop="sid">
|
||||
<el-input v-model="form.sid" placeholder="请输入关联系统ID" />
|
||||
</el-form-item>
|
||||
<el-form-item label="货件编号" prop="shipmentId">
|
||||
<el-input v-model="form.shipmentId" placeholder="请输入货件编号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="货件名称" prop="shipmentName">
|
||||
<el-input v-model="form.shipmentName" placeholder="请输入货件名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="物流中心编码" prop="destination">
|
||||
<el-input v-model="form.destination" placeholder="请输入物流中心编码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="运输模式" prop="shippingMode">
|
||||
<el-input v-model="form.shippingMode" placeholder="请输入运输模式" />
|
||||
</el-form-item>
|
||||
<el-form-item label="运输方案" prop="shippingSolution">
|
||||
<el-input v-model="form.shippingSolution" placeholder="请输入运输方案" />
|
||||
</el-form-item>
|
||||
<el-form-item label="最后更新时间" prop="gmtModified">
|
||||
<el-date-picker clearable v-model="form.gmtModified" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择最后更新时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="gmtCreate">
|
||||
<el-date-picker clearable v-model="form.gmtCreate" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择创建时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="同步时间" prop="syncTime">
|
||||
<el-date-picker clearable v-model="form.syncTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择同步时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="计划发货日期" prop="staShipmentDate">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="form.staShipmentDate"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="请选择计划发货日期"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="预计到货开始日" prop="staDeliveryStartDate">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="form.staDeliveryStartDate"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="请选择预计到货开始日"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="预计到货截止日" prop="staDeliveryEndDate">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="form.staDeliveryEndDate"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="请选择预计到货截止日"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="参考编号" prop="referenceId">
|
||||
<el-input v-model="form.referenceId" placeholder="请输入参考编号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="入库计划ID" prop="staInboundPlanId">
|
||||
<el-input v-model="form.staInboundPlanId" placeholder="请输入入库计划ID" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- 详情对话框 -->
|
||||
<el-dialog v-model="dialogVisible" title="地址详细信息" width="60%">
|
||||
<el-table :data="addressTableData">
|
||||
<el-table-column prop="key" label="字段" width="180" />
|
||||
<el-table-column prop="value" label="值" />
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="channelDialogVisible" title="查询报价" width="60%">
|
||||
<!-- <el-radio-group v-model="form.status">-->
|
||||
<!-- <el-radio v-for="dict in biz_transport_channel" :key="dict.value" :value="dict.value">-->
|
||||
<!-- {{ dict.label }}-->
|
||||
<!-- </el-radio>-->
|
||||
<!-- </el-radio-group>-->
|
||||
|
||||
<!-- <el-radio-group v-model="form.status">-->
|
||||
<!-- <!– 按国家分组循环 –>-->
|
||||
<!-- <div v-for="(transportDict, country) in groupedChannels" :key="country">-->
|
||||
<!-- <!– 国家标题 –>-->
|
||||
<!-- <div class="country-title">{{ country }}</div>-->
|
||||
|
||||
<!-- <!– 运输方式子分组 –>-->
|
||||
<!-- <div-->
|
||||
<!-- v-for="(channels, transport) in transportDict"-->
|
||||
<!-- :key="transport"-->
|
||||
<!-- class="transport-group"-->
|
||||
<!-- >-->
|
||||
<!-- <el-radio-->
|
||||
<!-- v-for="dict in channels"-->
|
||||
<!-- :key="dict.value"-->
|
||||
<!-- :value="dict.value"-->
|
||||
<!-- border-->
|
||||
<!-- class="channel-item"-->
|
||||
<!-- >-->
|
||||
<!-- {{ transport }} - {{ getChannelName(dict.label) }}-->
|
||||
<!-- </el-radio>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </el-radio-group>-->
|
||||
<el-form :model="form" label-width="auto" style="max-width: 600px">
|
||||
<el-form-item label="目的地仓库">
|
||||
<el-input v-model="currentDes" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="渠道选择">
|
||||
<!-- <el-collapse v-model="activeCollapse">-->
|
||||
<!-- <!– 遍历国家分组 –>-->
|
||||
<!-- <el-collapse-item v-for="(countryGroup, country) in groupedChannels" :key="country" :title="getCountryName(country)" :name="country">-->
|
||||
<!-- <!– 遍历运输方式 –>-->
|
||||
<!-- <div v-for="(methodGroup, method) in countryGroup" :key="method">-->
|
||||
<!-- <div class="shipping-method-title">-->
|
||||
<!-- {{ getShippingMethodName(method) }}-->
|
||||
<!-- </div>-->
|
||||
<!-- <el-radio-group v-model="selectedChannel" @change="handleChannelSelect">-->
|
||||
<!-- <!– 遍历具体渠道 –>-->
|
||||
<!-- <div v-for="channel in methodGroup" :key="channel.id" class="channel-item">-->
|
||||
<!-- <el-radio :label="channel.id">-->
|
||||
<!-- {{ getChannelLabel(channel.channelName) }}-->
|
||||
<!-- </el-radio>-->
|
||||
<!-- <div class="channel-description">{{ channel.description }}</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </el-radio-group>-->
|
||||
<!-- </div>-->
|
||||
<!-- </el-collapse-item>-->
|
||||
<!-- </el-collapse>-->
|
||||
<el-cascader
|
||||
v-model="selectedChannel"
|
||||
placeholder="请选择渠道"
|
||||
:props="{ emitPath: false }"
|
||||
:options="groupedChannels"
|
||||
@change="cascaderChange"
|
||||
:show-all-levels="false"
|
||||
filterable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="日期选择">
|
||||
<el-date-picker v-model="shipDate" type="date" placeholder="Pick a day" value-format="YYYY-MM-DD" :size="size" />
|
||||
</el-form-item>
|
||||
<el-button :loading="buttonLoading" type="primary" @click="checkPrice()">查询报价</el-button>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="dialogTableVisible" title="已经存在的询价单" width="1800">
|
||||
<el-table :data="tableData" style="width: 100%" border stripe>
|
||||
<!-- 基础文本列 -->
|
||||
<el-table-column prop="inquiryNo" label="询价编号" width="180" />
|
||||
<el-table-column prop="channelName" label="渠道名称" width="200" />
|
||||
<el-table-column prop="transportChannel" label="运输方式" width="120" />
|
||||
<el-table-column prop="quoteDate" label="询价日期" width="200" />
|
||||
<!-- 时间格式化列 -->
|
||||
<el-table-column prop="deadline" label="截止时间" width="180">
|
||||
<template #default="{ row }">
|
||||
{{ formatTime(row.deadline) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="effectiveStartTime" label="生效开始时间" width="180">
|
||||
<template #default="{ row }">
|
||||
{{ formatTime(row.effectiveStartTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="effectiveEndTime" label="生效结束时间" width="180">
|
||||
<template #default="{ row }">
|
||||
{{ formatTime(row.effectiveEndTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 状态标签列 -->
|
||||
<el-table-column prop="inquiryStatus" label="询价状态" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="statusTagType(row.inquiryStatus)" effect="light">
|
||||
{{ row.inquiryStatus }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 其他信息列 -->
|
||||
<el-table-column prop="destination" label="目的地" width="120" />
|
||||
|
||||
<el-table-column prop="requesterId" label="请求方ID" width="120" />
|
||||
|
||||
<!-- 空值处理 -->
|
||||
<el-table-column prop="targetProviders" label="目标供应商">
|
||||
<template #default="{ row }">
|
||||
{{ row.targetProviders || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<el-drawer size="60%" v-model="drawer" :direction="direction">
|
||||
<template #header>
|
||||
<h4>物流商报价</h4>
|
||||
</template>
|
||||
<template #default>
|
||||
<el-table v-loading="loading" :data="logisticsQuoteList" @selection-change="handleSelectionChange">
|
||||
<el-table-column label="物流商用户ID" align="center" prop="userId" />
|
||||
<el-table-column label="目的地" align="center" prop="destination" />
|
||||
<el-table-column label="渠道名称" align="center" prop="channelName" />
|
||||
<el-table-column label="基础价格" align="center" prop="price" />
|
||||
<el-table-column label="时效" align="center" prop="leadTime" />
|
||||
<el-table-column label="附加费" align="center" prop="surcharge" />
|
||||
<el-table-column label="报价生效日期" align="center" prop="quoteDate" width="80">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.quoteDate, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="提交状态" align="center" prop="isSubmitted" />
|
||||
<el-table-column label="报价备注" align="center" prop="remark" />
|
||||
<el-table-column label="渠道类型" align="center" prop="channelType" />
|
||||
<el-table-column label="是否双清包税" align="center" prop="isDdp" />
|
||||
<el-table-column label="单位" align="center" prop="unit" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button text size="small" type="primary" @click="createOrder(scope.row)" v-hasPermi="['amz:logisticsQuote:edit']">
|
||||
创建货运订单
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
<template #footer>
|
||||
<div style="flex: auto">
|
||||
<el-button @click="cancelClick">取消</el-button>
|
||||
<el-button type="primary" @click="confirmClick">确认</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</el-watermark>
|
||||
</template>
|
||||
|
||||
<script setup name="ShipmentPlan" lang="ts">
|
||||
import { listShipmentPlan, getShipmentPlan, delShipmentPlan, addShipmentPlan, updateShipmentPlan } from '@/api/amz/shipmentPlan';
|
||||
import {
|
||||
listShipmentPlan,
|
||||
getShipmentPlan,
|
||||
delShipmentPlan,
|
||||
addShipmentPlan,
|
||||
updateShipmentPlan,
|
||||
takeTodayAmzPlanData
|
||||
} from '@/api/amz/shipmentPlan';
|
||||
import { listAllLogisticsChannel } from '@/api/amz/logisticsChannel';
|
||||
import type { DrawerProps } from 'element-plus';
|
||||
import { createWithDesAndChannel, queryWithDesAndChannel } from '@/api/amz/inquiryRequest';
|
||||
@ -423,6 +454,8 @@ import { createLogisticsOrder } from '@/api/amz/logisticsOrder';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { biz_transport_channel } = toRefs<any>(proxy?.useDict('biz_transport_channel'));
|
||||
|
||||
const { sys_zero_one } = toRefs<any>(proxy?.useDict('sys_zero_one'));
|
||||
|
||||
const shipmentPlanList = ref<ShipmentPlanVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
@ -460,7 +493,13 @@ const initFormData: ShipmentPlanForm = {
|
||||
shipToAddress: undefined,
|
||||
referenceId: undefined,
|
||||
staInboundPlanId: undefined,
|
||||
isSta: undefined
|
||||
isSta: undefined,
|
||||
boxQuantity: undefined,
|
||||
boxSize: undefined,
|
||||
logisticsWeight: undefined,
|
||||
setTotal: undefined,
|
||||
channelId: undefined,
|
||||
channelName: undefined
|
||||
};
|
||||
const data = reactive<PageData<ShipmentPlanForm, ShipmentPlanQuery>>({
|
||||
form: { ...initFormData },
|
||||
@ -486,6 +525,12 @@ const data = reactive<PageData<ShipmentPlanForm, ShipmentPlanQuery>>({
|
||||
referenceId: undefined,
|
||||
staInboundPlanId: undefined,
|
||||
isSta: undefined,
|
||||
boxQuantity: undefined,
|
||||
boxSize: undefined,
|
||||
logisticsWeight: undefined,
|
||||
setTotal: undefined,
|
||||
channelId: undefined,
|
||||
channelName: undefined,
|
||||
params: {}
|
||||
},
|
||||
rules: {
|
||||
@ -532,6 +577,7 @@ const createOrder = async (row: ShipmentPlanVO) => {
|
||||
} else {
|
||||
ElMessage.error('创建失败');
|
||||
}
|
||||
drawer.value = false;
|
||||
};
|
||||
|
||||
const dialogTableVisible = ref(false);
|
||||
@ -598,7 +644,7 @@ const cascaderChange = (value) => {
|
||||
};
|
||||
|
||||
function confirmClick() {
|
||||
ElMessageBox.confirm(`Are you confirm to chose ${radio1.value} ?`)
|
||||
ElMessageBox.confirm(`你确定要关闭 ${radio1.value} ?`)
|
||||
.then(() => {
|
||||
drawer.value = false;
|
||||
})
|
||||
@ -688,8 +734,8 @@ function transformChannels(channels) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const currentDes = ref('');
|
||||
const currentFBAData = ref('');
|
||||
const currentDes = ref<string | number>('');
|
||||
const currentFBAData = ref<ShipmentPlanVO>();
|
||||
|
||||
// 分组后的渠道数据
|
||||
const groupedChannels = computed(() => {
|
||||
@ -781,24 +827,26 @@ const checkPrice = async () => {
|
||||
if (requestQuote.total == 0) {
|
||||
console.log('询价单也没数据');
|
||||
channelDialogVisible.value = false;
|
||||
ElMessageBox.confirm('未查询到价格信息,是否要向物流商发布询价?', 'Warning', {
|
||||
ElMessageBox.confirm('未查询到价格信息,是否要向物流商发布询价?', '提醒', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(async () => {
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: 'Delete completed'
|
||||
});
|
||||
const res2 = await createWithDesAndChannel(currentDes.value, selectedChannel.value, shipDate.value);
|
||||
console.log('checkPriceEnd2', res2);
|
||||
if (res2.code == 200) {
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '询价单创建成功'
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
type: 'info',
|
||||
message: 'Delete canceled'
|
||||
});
|
||||
// ElMessage({
|
||||
// type: 'info',
|
||||
// message: 'Delete canceled'
|
||||
// });
|
||||
});
|
||||
} else {
|
||||
//显示询价单
|
||||
@ -833,6 +881,15 @@ const handleSend = async (row?: ShipmentPlanVO) => {
|
||||
currentFBAData.value = row;
|
||||
currentDes.value = row.destination;
|
||||
};
|
||||
|
||||
const snycTodayPlan = async () => {
|
||||
const res = await takeTodayAmzPlanData();
|
||||
if (res.code == 200) {
|
||||
proxy?.$modal.msgSuccess('同步成功');
|
||||
await getList();
|
||||
}
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
shipmentPlanFormRef.value?.validate(async (valid: boolean) => {
|
||||
|
907
src/views/amz/shipmentPlanAsk/index.vue
Normal file
907
src/views/amz/shipmentPlanAsk/index.vue
Normal file
@ -0,0 +1,907 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="货件编号" prop="shipmentId">
|
||||
<el-input v-model="queryParams.shipmentId" placeholder="请输入货件编号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="货件名称" prop="shipmentName">
|
||||
<el-input v-model="queryParams.shipmentName" placeholder="请输入货件名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="物流中心编码" prop="destination">
|
||||
<el-input v-model="queryParams.destination" placeholder="请输入物流中心编码" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasRoles="['superadmin']" v-hasPermi="['amz:shipmentPlan:add']"
|
||||
>新增
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['amz:shipmentPlan:edit']"
|
||||
>修改
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['amz:shipmentPlan:remove']"
|
||||
>删除
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['amz:shipmentPlan:export']">导出 </el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="snycTodayPlan" v-hasPermi="['amz:shipmentPlan:export']"
|
||||
>同步今天的货件
|
||||
</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="shipmentPlanList" @current-change="handleCurrentChange" highlight-current-row ref="singleTableRef">
|
||||
<el-table-column type="expand">
|
||||
<template #default="props">
|
||||
<el-descriptions size="small" border title="货件详情">
|
||||
<el-descriptions-item label="货件名称">{{ props.row.shipmentName }}</el-descriptions-item>
|
||||
<!-- <el-descriptions-item label="货件状态">{{ props.row.shipmentStatus }}</el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="运输模式">{{ props.row.shippingMode }}</el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="运输方案">{{ props.row.shippingSolution }}</el-descriptions-item>-->
|
||||
<el-descriptions-item label="入库计划ID">{{ props.row.staInboundPlanId }}</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="创建时间">{{ parseTime(props.row.gmtCreate, '{y}-{m}-{d}') }} </el-descriptions-item>
|
||||
<!-- <el-descriptions-item label="计划发货日期">{{ parseTime(props.row.staShipmentDate, '{y}-{m}-{d}') }} </el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="预计到货开始日">{{ parseTime(props.row.staDeliveryStartDate, '{y}-{m}-{d}') }} </el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="预计到货截止日">{{ parseTime(props.row.staDeliveryEndDate, '{y}-{m}-{d}') }} </el-descriptions-item>-->
|
||||
</el-descriptions>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="发货日期" align="center" prop="gmtCreate" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.staShipmentDate, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="店铺名称" align="center" prop="sellerName" />
|
||||
<el-table-column label="货件编号" align="center" prop="shipmentId" />
|
||||
<el-table-column label="商品详情" align="center">
|
||||
<template #default="scope">
|
||||
<el-popover placement="top" :width="600" trigger="hover" @show="showPop(scope.row)">
|
||||
<template #reference>
|
||||
<el-button style="margin-right: 16px">查看</el-button>
|
||||
</template>
|
||||
<el-table :data="scope.row.itemVoList">
|
||||
<el-table-column width="200" property="productName" label="品名" />
|
||||
<el-table-column width="200" property="msku" label="msku" />
|
||||
<el-table-column width="150" property="asin" label="asin" />
|
||||
</el-table>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="物流中心编码" align="center" prop="destination" />
|
||||
<el-table-column label="总箱子数量" align="center" prop="boxQuantity" />
|
||||
<el-table-column label="箱子尺寸" align="center" prop="boxSize" />
|
||||
<el-table-column label="供应商称重" align="center" prop="vendorWeight" />
|
||||
<el-table-column label="套数" align="center" prop="setTotal" />
|
||||
<!-- <el-table-column label="渠道ID" align="center" prop="channelId" />-->
|
||||
|
||||
<el-table-column width="150" label="仓库配送地址" align="center" prop="shipToAddress">
|
||||
<template #default="{ row }">
|
||||
<el-button @click="openAddressDialog(row.shipToAddress)"> 查看详情</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="亚马逊货件状态" align="center" width="180">
|
||||
<template #default="scope">
|
||||
<el-tag>{{ scope.row.shipmentStatus }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="物流渠道" align="center" prop="channelName" />
|
||||
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['amz:shipmentPlan:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<!-- <el-tooltip content="删除" placement="top">-->
|
||||
<!-- <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['amz:shipmentPlan:remove']"></el-button>-->
|
||||
<!-- </el-tooltip>-->
|
||||
|
||||
<el-button link type="primary" size="small" @click="handleSend(scope.row)" v-hasPermi="['amz:shipmentPlan:remove']">询价 </el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
<!-- 添加或修改货件计划对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="shipmentPlanFormRef" :model="form" :rules="rules" label-width="120px">
|
||||
<el-form-item label="货件编号" prop="shipmentId">
|
||||
<el-input v-model="form.shipmentId" placeholder="请输入货件编号" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="货件名称" prop="shipmentName">
|
||||
<el-input v-model="form.shipmentName" placeholder="请输入货件名称" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="物流中心编码" prop="destination">
|
||||
<el-input v-model="form.destination" placeholder="请输入物流中心编码" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="物流渠道">
|
||||
<el-cascader
|
||||
ref="channelCascaderRef"
|
||||
v-model="selectedChannel"
|
||||
:props="{ emitPath: false }"
|
||||
placeholder="请选择渠道"
|
||||
:options="groupedChannels"
|
||||
@change="cascaderChange"
|
||||
:show-all-levels="false"
|
||||
filterable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="总箱子数量" prop="boxQuantity">
|
||||
<el-input v-model="form.boxQuantity" placeholder="请输入总箱子数量" />
|
||||
</el-form-item>
|
||||
<el-form-item label="箱子尺寸" prop="boxSize">
|
||||
<el-input v-model="form.boxSize" placeholder="请输入箱子尺寸" />
|
||||
</el-form-item>
|
||||
<el-form-item label="供应商称重" prop="vendorWeight">
|
||||
<el-input v-model="form.vendorWeight" placeholder="请输入供应商称重" />
|
||||
</el-form-item>
|
||||
<el-form-item label="套数" prop="setTotal">
|
||||
<el-input v-model="form.setTotal" placeholder="请输入套数" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- 详情对话框 -->
|
||||
<el-dialog v-model="dialogVisible" title="地址详细信息" width="60%">
|
||||
<el-table :data="addressTableData">
|
||||
<el-table-column prop="key" label="字段" width="180" />
|
||||
<el-table-column prop="value" label="值" />
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="channelDialogVisible" title="查询报价" width="60%">
|
||||
<!-- <el-radio-group v-model="form.status">-->
|
||||
<!-- <el-radio v-for="dict in biz_transport_channel" :key="dict.value" :value="dict.value">-->
|
||||
<!-- {{ dict.label }}-->
|
||||
<!-- </el-radio>-->
|
||||
<!-- </el-radio-group>-->
|
||||
|
||||
<!-- <el-radio-group v-model="form.status">-->
|
||||
<!-- <!– 按国家分组循环 –>-->
|
||||
<!-- <div v-for="(transportDict, country) in groupedChannels" :key="country">-->
|
||||
<!-- <!– 国家标题 –>-->
|
||||
<!-- <div class="country-title">{{ country }}</div>-->
|
||||
|
||||
<!-- <!– 运输方式子分组 –>-->
|
||||
<!-- <div-->
|
||||
<!-- v-for="(channels, transport) in transportDict"-->
|
||||
<!-- :key="transport"-->
|
||||
<!-- class="transport-group"-->
|
||||
<!-- >-->
|
||||
<!-- <el-radio-->
|
||||
<!-- v-for="dict in channels"-->
|
||||
<!-- :key="dict.value"-->
|
||||
<!-- :value="dict.value"-->
|
||||
<!-- border-->
|
||||
<!-- class="channel-item"-->
|
||||
<!-- >-->
|
||||
<!-- {{ transport }} - {{ getChannelName(dict.label) }}-->
|
||||
<!-- </el-radio>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </el-radio-group>-->
|
||||
<el-form :model="form" label-width="auto" style="max-width: 600px">
|
||||
<el-form-item label="目的地仓库">
|
||||
<el-input v-model="currentDes" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="渠道选择">
|
||||
<!-- <el-collapse v-model="activeCollapse">-->
|
||||
<!-- <!– 遍历国家分组 –>-->
|
||||
<!-- <el-collapse-item v-for="(countryGroup, country) in groupedChannels" :key="country" :title="getCountryName(country)" :name="country">-->
|
||||
<!-- <!– 遍历运输方式 –>-->
|
||||
<!-- <div v-for="(methodGroup, method) in countryGroup" :key="method">-->
|
||||
<!-- <div class="shipping-method-title">-->
|
||||
<!-- {{ getShippingMethodName(method) }}-->
|
||||
<!-- </div>-->
|
||||
<!-- <el-radio-group v-model="selectedChannel" @change="handleChannelSelect">-->
|
||||
<!-- <!– 遍历具体渠道 –>-->
|
||||
<!-- <div v-for="channel in methodGroup" :key="channel.id" class="channel-item">-->
|
||||
<!-- <el-radio :label="channel.id">-->
|
||||
<!-- {{ getChannelLabel(channel.channelName) }}-->
|
||||
<!-- </el-radio>-->
|
||||
<!-- <div class="channel-description">{{ channel.description }}</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </el-radio-group>-->
|
||||
<!-- </div>-->
|
||||
<!-- </el-collapse-item>-->
|
||||
<!-- </el-collapse>-->
|
||||
<el-cascader
|
||||
v-model="selectedChannel"
|
||||
placeholder="请选择渠道"
|
||||
:props="{ emitPath: false }"
|
||||
:options="groupedChannels"
|
||||
@change="cascaderChange"
|
||||
:show-all-levels="false"
|
||||
filterable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="日期选择">
|
||||
<el-date-picker v-model="shipDate" type="date" placeholder="Pick a day" value-format="YYYY-MM-DD" :size="size" />
|
||||
</el-form-item>
|
||||
<el-button :loading="buttonLoading" type="primary" @click="checkPrice()">查询报价</el-button>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="dialogTableVisible" title="已经存在的询价单" width="1800">
|
||||
<el-table :data="tableData" style="width: 100%" border stripe>
|
||||
<!-- 基础文本列 -->
|
||||
<el-table-column prop="inquiryNo" label="询价编号" width="180" />
|
||||
<el-table-column prop="channelName" label="渠道名称" width="200" />
|
||||
<el-table-column prop="transportChannel" label="运输方式" width="120" />
|
||||
<el-table-column prop="quoteDate" label="询价日期" width="200" />
|
||||
<!-- 时间格式化列 -->
|
||||
<el-table-column prop="deadline" label="截止时间" width="180">
|
||||
<template #default="{ row }">
|
||||
{{ formatTime(row.deadline) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="effectiveStartTime" label="生效开始时间" width="180">
|
||||
<template #default="{ row }">
|
||||
{{ formatTime(row.effectiveStartTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="effectiveEndTime" label="生效结束时间" width="180">
|
||||
<template #default="{ row }">
|
||||
{{ formatTime(row.effectiveEndTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 状态标签列 -->
|
||||
<el-table-column prop="inquiryStatus" label="询价状态" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="statusTagType(row.inquiryStatus)" effect="light">
|
||||
{{ row.inquiryStatus }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 其他信息列 -->
|
||||
<el-table-column prop="destination" label="目的地" width="120" />
|
||||
|
||||
<el-table-column prop="requesterId" label="请求方ID" width="120" />
|
||||
|
||||
<!-- 空值处理 -->
|
||||
<el-table-column prop="targetProviders" label="目标供应商">
|
||||
<template #default="{ row }">
|
||||
{{ row.targetProviders || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<el-drawer size="60%" v-model="drawer" :direction="direction">
|
||||
<template #header>
|
||||
<h4>物流商报价</h4>
|
||||
</template>
|
||||
<template #default>
|
||||
<el-table v-loading="loading" :data="logisticsQuoteList" @selection-change="handleSelectionChange">
|
||||
<el-table-column label="物流商用户ID" align="center" prop="userId" />
|
||||
<el-table-column label="目的地" align="center" prop="destination" />
|
||||
<el-table-column label="渠道名称" align="center" prop="channelName" />
|
||||
<el-table-column label="基础价格" align="center" prop="price" />
|
||||
<el-table-column label="时效" align="center" prop="leadTime" />
|
||||
<el-table-column label="附加费" align="center" prop="surcharge" />
|
||||
<el-table-column label="报价生效日期" align="center" prop="quoteDate" width="80">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.quoteDate, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="提交状态" align="center" prop="isSubmitted" />
|
||||
<el-table-column label="报价备注" align="center" prop="remark" />
|
||||
<el-table-column label="渠道类型" align="center" prop="channelType" />
|
||||
<el-table-column label="是否双清包税" align="center" prop="isDdp" />
|
||||
<el-table-column label="单位" align="center" prop="unit" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button text size="small" type="primary" @click="createOrder(scope.row)" v-hasPermi="['amz:logisticsQuote:edit']">
|
||||
创建货运订单
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
<template #footer>
|
||||
<div style="flex: auto">
|
||||
<el-button @click="cancelClick">取消</el-button>
|
||||
<el-button type="primary" @click="confirmClick">确认</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="ShipmentPlan" lang="ts">
|
||||
import {
|
||||
listShipmentPlan,
|
||||
getShipmentPlan,
|
||||
delShipmentPlan,
|
||||
addShipmentPlan,
|
||||
updateShipmentPlan,
|
||||
takeTodayAmzPlanData
|
||||
} from '@/api/amz/shipmentPlan';
|
||||
import { listAllLogisticsChannel } from '@/api/amz/logisticsChannel';
|
||||
import type { DrawerProps } from 'element-plus';
|
||||
import { createWithDesAndChannel, queryWithDesAndChannel } from '@/api/amz/inquiryRequest';
|
||||
|
||||
import { queryLogisticsQuote } from '@/api/amz/logisticsQuote';
|
||||
|
||||
import { ShipmentPlanVO, ShipmentPlanQuery, ShipmentPlanForm } from '@/api/amz/shipmentPlan/types';
|
||||
import { ElTable } from 'element-plus';
|
||||
import { LogisticsQuoteVO } from '@/api/amz/logisticsQuote/types';
|
||||
import { createOrderForm } from '@/api/amz/logisticsOrder/types';
|
||||
import { createLogisticsOrder } from '@/api/amz/logisticsOrder';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { biz_transport_channel } = toRefs<any>(proxy?.useDict('biz_transport_channel'));
|
||||
|
||||
const { sys_zero_one } = toRefs<any>(proxy?.useDict('sys_zero_one'));
|
||||
|
||||
const shipmentPlanList = ref<ShipmentPlanVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const shipmentPlanFormRef = ref<ElFormInstance>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const initFormData: ShipmentPlanForm = {
|
||||
id: undefined,
|
||||
sid: undefined,
|
||||
shipmentId: undefined,
|
||||
shipmentName: undefined,
|
||||
isClosed: undefined,
|
||||
shipmentStatus: undefined,
|
||||
destination: undefined,
|
||||
shippingMode: undefined,
|
||||
shippingSolution: undefined,
|
||||
gmtModified: undefined,
|
||||
gmtCreate: undefined,
|
||||
syncTime: undefined,
|
||||
staShipmentDate: undefined,
|
||||
staDeliveryStartDate: undefined,
|
||||
staDeliveryEndDate: undefined,
|
||||
shipFromAddress: undefined,
|
||||
shipToAddress: undefined,
|
||||
referenceId: undefined,
|
||||
staInboundPlanId: undefined,
|
||||
isSta: undefined,
|
||||
boxQuantity: undefined,
|
||||
boxSize: undefined,
|
||||
vendorWeight: undefined,
|
||||
setTotal: undefined,
|
||||
channelId: undefined,
|
||||
channelName: undefined
|
||||
};
|
||||
const data = reactive<PageData<ShipmentPlanForm, ShipmentPlanQuery>>({
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
sid: undefined,
|
||||
shipmentId: undefined,
|
||||
shipmentName: undefined,
|
||||
isClosed: undefined,
|
||||
shipmentStatus: undefined,
|
||||
destination: undefined,
|
||||
shippingMode: undefined,
|
||||
shippingSolution: undefined,
|
||||
gmtModified: undefined,
|
||||
gmtCreate: undefined,
|
||||
syncTime: undefined,
|
||||
staShipmentDate: undefined,
|
||||
staDeliveryStartDate: undefined,
|
||||
staDeliveryEndDate: undefined,
|
||||
shipFromAddress: undefined,
|
||||
shipToAddress: undefined,
|
||||
referenceId: undefined,
|
||||
staInboundPlanId: undefined,
|
||||
isSta: undefined,
|
||||
fbaStatus: 'ask',
|
||||
boxQuantity: undefined,
|
||||
boxSize: undefined,
|
||||
vendorWeight: undefined,
|
||||
setTotal: undefined,
|
||||
channelId: undefined,
|
||||
channelName: undefined,
|
||||
params: {}
|
||||
},
|
||||
rules: {
|
||||
id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }],
|
||||
sid: [{ required: true, message: '关联系统ID不能为空', trigger: 'blur' }],
|
||||
shipmentId: [{ required: true, message: '货件编号不能为空', trigger: 'blur' }],
|
||||
shipmentName: [{ required: true, message: '货件名称不能为空', trigger: 'blur' }],
|
||||
isClosed: [{ required: true, message: '是否关闭不能为空', trigger: 'blur' }],
|
||||
shipmentStatus: [{ required: true, message: '货件状态不能为空', trigger: 'change' }],
|
||||
destination: [{ required: true, message: '物流中心编码不能为空', trigger: 'blur' }],
|
||||
shippingMode: [{ required: true, message: '运输模式不能为空', trigger: 'blur' }],
|
||||
shippingSolution: [{ required: true, message: '运输方案不能为空', trigger: 'blur' }],
|
||||
gmtModified: [{ required: true, message: '最后更新时间不能为空', trigger: 'blur' }],
|
||||
gmtCreate: [{ required: true, message: '创建时间不能为空', trigger: 'blur' }],
|
||||
syncTime: [{ required: true, message: '同步时间不能为空', trigger: 'blur' }],
|
||||
staShipmentDate: [{ required: true, message: '计划发货日期不能为空', trigger: 'blur' }],
|
||||
staDeliveryStartDate: [{ required: true, message: '预计到货开始日不能为空', trigger: 'blur' }],
|
||||
staDeliveryEndDate: [{ required: true, message: '预计到货截止日不能为空', trigger: 'blur' }],
|
||||
shipFromAddress: [{ required: true, message: '发货地址不能为空', trigger: 'blur' }],
|
||||
shipToAddress: [{ required: true, message: '收货地址不能为空', trigger: 'blur' }],
|
||||
referenceId: [{ required: true, message: '参考编号不能为空', trigger: 'blur' }],
|
||||
staInboundPlanId: [{ required: true, message: '入库计划ID不能为空', trigger: 'blur' }],
|
||||
isSta: [{ required: true, message: '是否STA计划不能为空', trigger: 'blur' }]
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
const createOrderData = ref<createOrderForm>({
|
||||
fbaShipmentId: undefined,
|
||||
logicQuoteId: undefined
|
||||
});
|
||||
|
||||
const createOrder = async (row: ShipmentPlanVO) => {
|
||||
// 创建货运订单
|
||||
console.log('row', row);
|
||||
console.log('currentFBAData', currentFBAData.value);
|
||||
createOrderData.value.fbaShipmentId = currentFBAData.value.shipmentId;
|
||||
createOrderData.value.logicQuoteId = row.id;
|
||||
const res = await createLogisticsOrder(createOrderData.value);
|
||||
console.log('res', res);
|
||||
if (res.code === 200) {
|
||||
ElMessage.success('创建成功');
|
||||
} else {
|
||||
ElMessage.error('创建失败');
|
||||
}
|
||||
drawer.value = false;
|
||||
};
|
||||
|
||||
const dialogTableVisible = ref(false);
|
||||
|
||||
const logisticsQuoteList = ref<LogisticsQuoteVO[]>([]);
|
||||
|
||||
const tableData = ref([
|
||||
{
|
||||
channelId: '1902912289404719106',
|
||||
channelName: '美国-海运-美森正班船',
|
||||
deadline: '2025-03-22 11:00:00',
|
||||
destination: 'LGB8',
|
||||
effectiveEndTime: '2025-03-30 15:30:19',
|
||||
effectiveStartTime: '2025-03-23 15:30:19',
|
||||
id: '1903348528587018242',
|
||||
inquiryNo: 'INQ20250322000004',
|
||||
inquiryStatus: 'OPEN',
|
||||
quoteDate: '2025-03-22 00:00:00',
|
||||
requesterId: 1,
|
||||
targetProviders: null,
|
||||
transportChannel: 'sea'
|
||||
}
|
||||
]);
|
||||
|
||||
// 时间格式化方法
|
||||
const formatTime = (timeString) => {
|
||||
return timeString.replace(' ', '\n'); // 换行显示日期时间
|
||||
};
|
||||
|
||||
// 状态标签样式
|
||||
const statusTagType = (status) => {
|
||||
switch (status) {
|
||||
case 'OPEN':
|
||||
return 'success';
|
||||
case 'CLOSED':
|
||||
return 'info';
|
||||
case 'EXPIRED':
|
||||
return 'warning';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
const drawer = ref(false);
|
||||
const direction = ref<DrawerProps['direction']>('ltr');
|
||||
const radio1 = ref('Option 1');
|
||||
const handleClose = (done: () => void) => {
|
||||
ElMessageBox.confirm('Are you sure you want to close this?')
|
||||
.then(() => {
|
||||
done();
|
||||
})
|
||||
.catch(() => {
|
||||
// catch error
|
||||
});
|
||||
};
|
||||
|
||||
function cancelClick() {
|
||||
drawer.value = false;
|
||||
}
|
||||
|
||||
const channelCascaderRef = ref(null);
|
||||
const cascaderChange = (value) => {
|
||||
console.log(value);
|
||||
console.log('selectedChannel', selectedChannel);
|
||||
console.log('groupedChannels', groupedChannels);
|
||||
|
||||
// console.log('channelCascaderRef', channelCascaderRef);
|
||||
console.log('label====', channelCascaderRef.value.getCheckedNodes()[0].label);
|
||||
};
|
||||
|
||||
function confirmClick() {
|
||||
ElMessageBox.confirm(`你确定要关闭 ${radio1.value} ?`)
|
||||
.then(() => {
|
||||
drawer.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
// catch error
|
||||
});
|
||||
}
|
||||
|
||||
const getLocalDate = () => {
|
||||
const today = new Date();
|
||||
const year = today.getFullYear();
|
||||
const month = String(today.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(today.getDate()).padStart(2, '0');
|
||||
return `${year}-${month}-${day}`;
|
||||
};
|
||||
const shipDate = ref(getLocalDate());
|
||||
/** 查询货件计划列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listShipmentPlan(queryParams.value);
|
||||
shipmentPlanList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
let channelTableData = ref([]);
|
||||
|
||||
const getAllChannelData = async () => {
|
||||
const res = await listAllLogisticsChannel();
|
||||
console.log('getAllChannelData');
|
||||
console.log(res);
|
||||
channelTableData.value = res.rows;
|
||||
console.log('groupedChannels:', groupedChannels.value);
|
||||
};
|
||||
|
||||
// 定义映射关系,将编码转换为中文标签
|
||||
const countryMap = {
|
||||
us: '美国'
|
||||
// 可扩展其他国家的映射
|
||||
};
|
||||
|
||||
const shippingMethodMap = {
|
||||
air: '空运',
|
||||
sea: '海运'
|
||||
// 可扩展其他运输方式
|
||||
};
|
||||
|
||||
function transformChannels(channels) {
|
||||
const result = [];
|
||||
const countryGroups = {}; // 按国家缓存顶级节点
|
||||
|
||||
channels.forEach((channel) => {
|
||||
const { country, shippingMethod, channelName, id } = channel;
|
||||
|
||||
// 处理国家节点
|
||||
const countryValue = country;
|
||||
const countryLabel = countryMap[country] || country;
|
||||
if (!countryGroups[countryValue]) {
|
||||
countryGroups[countryValue] = {
|
||||
value: countryValue,
|
||||
label: countryLabel,
|
||||
children: []
|
||||
};
|
||||
result.push(countryGroups[countryValue]);
|
||||
}
|
||||
|
||||
// 处理运输方式节点
|
||||
const methodValue = shippingMethod;
|
||||
const methodLabel = shippingMethodMap[shippingMethod] || shippingMethod;
|
||||
let methodNode = countryGroups[countryValue].children.find((m) => m.value === methodValue);
|
||||
if (!methodNode) {
|
||||
methodNode = {
|
||||
value: methodValue,
|
||||
label: methodLabel,
|
||||
children: []
|
||||
};
|
||||
countryGroups[countryValue].children.push(methodNode);
|
||||
}
|
||||
|
||||
// 添加渠道节点
|
||||
methodNode.children.push({
|
||||
value: id,
|
||||
label: channelName
|
||||
});
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const currentDes = ref<string | number>('');
|
||||
const currentFBAData = ref<ShipmentPlanVO>();
|
||||
|
||||
// 分组后的渠道数据
|
||||
const groupedChannels = computed(() => {
|
||||
// return channelTableData.value.reduce((acc, channel) => {
|
||||
// const country = channel.country;
|
||||
// const method = channel.shippingMethod;
|
||||
//
|
||||
// if (!acc[country]) acc[country] = {};
|
||||
// if (!acc[country][method]) acc[country][method] = [];
|
||||
//
|
||||
// acc[country][method].push(channel);
|
||||
// return acc;
|
||||
// }, {});
|
||||
return transformChannels(channelTableData.value);
|
||||
});
|
||||
|
||||
// 从渠道名称中提取显示标签(移除国家+运输方式前缀)
|
||||
const getChannelLabel = (name) => {
|
||||
return name.split('-').slice(2).join('-');
|
||||
};
|
||||
|
||||
// 获取国家显示名称
|
||||
const getCountryName = (code) => {
|
||||
return countryMap[code] || code.toUpperCase();
|
||||
};
|
||||
|
||||
// 获取运输方式显示名称
|
||||
const getShippingMethodName = (method) => {
|
||||
return shippingMethodMap[method] || method;
|
||||
};
|
||||
|
||||
// 交互逻辑
|
||||
const activeCollapse = ref(['us']); // 默认展开美国
|
||||
const selectedChannel = ref(null);
|
||||
|
||||
const handleChannelSelect = (channelId) => {
|
||||
console.log('Selected channel ID:', channelId);
|
||||
// 这里可以触发自定义事件或调用API
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
};
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = { ...initFormData };
|
||||
shipmentPlanFormRef.value?.resetFields();
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: ShipmentPlanVO[]) => {
|
||||
ids.value = selection.map((item) => item.id);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
};
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
reset();
|
||||
dialog.visible = true;
|
||||
dialog.title = '添加货件计划';
|
||||
};
|
||||
|
||||
const checkPrice = async () => {
|
||||
form.value.fbaStatus = 'send';
|
||||
|
||||
console.log('checkPrice', currentDes.value, selectedChannel.value);
|
||||
//查询报价单
|
||||
console.log('sshipDate.value', shipDate.value);
|
||||
if (currentFBAData.value.channelId == null) {
|
||||
ElMessage({
|
||||
type: 'warning',
|
||||
message: '请先设置渠道!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const updateForm = ref({
|
||||
id: currentFBAData.value.id,
|
||||
fbaStatus: 'send'
|
||||
});
|
||||
await updateShipmentPlan(updateForm.value).finally(() => (buttonLoading.value = false));
|
||||
|
||||
const res = await queryLogisticsQuote(currentDes.value, currentFBAData.value.channelId, shipDate.value);
|
||||
console.log('查询报价单', res);
|
||||
if (res.total == 0) {
|
||||
//查询询价单
|
||||
const requestQuote = await queryWithDesAndChannel(currentDes.value, currentFBAData.value.channelId, shipDate.value);
|
||||
console.log('查询询价单', requestQuote);
|
||||
if (requestQuote.total == 0) {
|
||||
console.log('询价单也没数据');
|
||||
channelDialogVisible.value = false;
|
||||
const res2 = await createWithDesAndChannel(currentDes.value, currentFBAData.value.channelId, shipDate.value);
|
||||
console.log('checkPriceEnd2', res2);
|
||||
if (res2.code == 200) {
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '询价单创建成功'
|
||||
});
|
||||
}
|
||||
} else {
|
||||
//显示询价单
|
||||
// channelDialogVisible.value = false;
|
||||
// dialogTableVisible.value = true;
|
||||
// tableData.value = requestQuote.rows;
|
||||
// console.log('requestQuote.rows', requestQuote.rows);
|
||||
// console.log('tableData', tableData.value);
|
||||
ElMessage.success('已经有人询价了');
|
||||
}
|
||||
} else {
|
||||
//显示报价单
|
||||
ElMessage.success('已经有人报价了');
|
||||
|
||||
// channelDialogVisible.value = false;
|
||||
// drawer.value = true;
|
||||
// logisticsQuoteList.value = res.rows;
|
||||
}
|
||||
getList();
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: ShipmentPlanVO) => {
|
||||
reset();
|
||||
const _id = row?.id || ids.value[0];
|
||||
const res = await getShipmentPlan(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
console.log('form.value', form.value);
|
||||
selectedChannel.value = res.data.channelId;
|
||||
console.log('selectedChannel', selectedChannel);
|
||||
dialog.visible = true;
|
||||
dialog.title = '修改货件计划';
|
||||
};
|
||||
|
||||
const handleSend = async (row?: ShipmentPlanVO) => {
|
||||
// reset();
|
||||
// channelDialogVisible.value = true;
|
||||
console.log(row);
|
||||
currentFBAData.value = row;
|
||||
currentDes.value = row.destination;
|
||||
checkPrice();
|
||||
};
|
||||
|
||||
const showPop = async (row: any) => {
|
||||
console.log('row', row);
|
||||
};
|
||||
|
||||
const snycTodayPlan = async () => {
|
||||
const res = await takeTodayAmzPlanData();
|
||||
if (res.code == 200) {
|
||||
proxy?.$modal.msgSuccess('同步成功');
|
||||
await getList();
|
||||
}
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
console.log('selectedChannel', selectedChannel);
|
||||
console.log('groupedChannels', groupedChannels);
|
||||
|
||||
// console.log('channelCascaderRef', channelCascaderRef);
|
||||
console.log('label====', channelCascaderRef.value.getCheckedNodes()[0].label);
|
||||
form.value.channelName = channelCascaderRef.value.getCheckedNodes()[0].label;
|
||||
form.value.channelId = selectedChannel;
|
||||
const updateForm = ref({
|
||||
id: form.value.id,
|
||||
boxQuantity: form.value.boxQuantity,
|
||||
boxSize: form.value.boxSize,
|
||||
vendorWeight: form.value.vendorWeight,
|
||||
setTotal: form.value.setTotal,
|
||||
channelId: selectedChannel,
|
||||
channelName: channelCascaderRef.value.getCheckedNodes()[0].label
|
||||
});
|
||||
shipmentPlanFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
if (updateForm.value.id) {
|
||||
await updateShipmentPlan(updateForm.value).finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
await addShipmentPlan(updateForm.value).finally(() => (buttonLoading.value = false));
|
||||
}
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: ShipmentPlanVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除货件计划编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
|
||||
await delShipmentPlan(_ids);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
};
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download(
|
||||
'amz/shipmentPlan/export',
|
||||
{
|
||||
...queryParams.value
|
||||
},
|
||||
`shipmentPlan_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
};
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const addressTableData = ref([]);
|
||||
|
||||
const channelDialogVisible = ref(false);
|
||||
|
||||
// 转换对象为表格需要的数组格式
|
||||
const convertAddressToTableData = (address) => {
|
||||
return Object.entries(address).map(([key, value]) => ({
|
||||
key: key,
|
||||
value: value
|
||||
}));
|
||||
};
|
||||
|
||||
// 打开对话框
|
||||
const openAddressDialog = (address) => {
|
||||
addressTableData.value = convertAddressToTableData(address);
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
const currentRow = ref();
|
||||
const singleTableRef = ref<InstanceType<typeof ElTable>>();
|
||||
|
||||
const handleCurrentChange = (val: ShipmentPlanVO | undefined) => {
|
||||
currentRow.value = val;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
getAllChannelData();
|
||||
});
|
||||
</script>
|
883
src/views/amz/shipmentPlanQuery/index.vue
Normal file
883
src/views/amz/shipmentPlanQuery/index.vue
Normal file
@ -0,0 +1,883 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="货件编号" prop="shipmentId">
|
||||
<el-input v-model="queryParams.shipmentId" placeholder="请输入货件编号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="货件名称" prop="shipmentName">
|
||||
<el-input v-model="queryParams.shipmentName" placeholder="请输入货件名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="物流中心编码" prop="destination">
|
||||
<el-input v-model="queryParams.destination" placeholder="请输入物流中心编码" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasRoles="['superadmin']" v-hasPermi="['amz:shipmentPlan:add']"
|
||||
>新增
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Edit"
|
||||
:disabled="single"
|
||||
@click="handleUpdate()"
|
||||
v-hasRoles="['superadmin']"
|
||||
v-hasPermi="['amz:shipmentPlan:edit']"
|
||||
>修改
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="Delete"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete()"
|
||||
v-hasRoles="['superadmin']"
|
||||
v-hasPermi="['amz:shipmentPlan:remove']"
|
||||
>删除
|
||||
</el-button>
|
||||
</el-col>
|
||||
<!-- <el-col :span="1.5">-->
|
||||
<!-- <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['amz:shipmentPlan:export']">导出 </el-button>-->
|
||||
<!-- </el-col>-->
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="shipmentPlanList" @current-change="handleCurrentChange" highlight-current-row ref="singleTableRef">
|
||||
<el-table-column type="expand">
|
||||
<template #default="props">
|
||||
<el-descriptions size="small" border title="货件详情">
|
||||
<el-descriptions-item label="货件名称">{{ props.row.shipmentName }}</el-descriptions-item>
|
||||
<!-- <el-descriptions-item label="货件状态">{{ props.row.shipmentStatus }}</el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="运输模式">{{ props.row.shippingMode }}</el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="运输方案">{{ props.row.shippingSolution }}</el-descriptions-item>-->
|
||||
<el-descriptions-item label="入库计划ID">{{ props.row.staInboundPlanId }}</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="创建时间">{{ props.row.gmtCreate }}</el-descriptions-item>
|
||||
<!-- <el-descriptions-item label="计划发货日期">{{ parseTime(props.row.staShipmentDate, '{y}-{m}-{d}') }} </el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="预计到货开始日">{{ parseTime(props.row.staDeliveryStartDate, '{y}-{m}-{d}') }} </el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="预计到货截止日">{{ parseTime(props.row.staDeliveryEndDate, '{y}-{m}-{d}') }} </el-descriptions-item>
|
||||
-->
|
||||
<el-descriptions-item label="时效">{{ props.row.quote.leadTime + ' 天' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="订单创建时间">{{ props.row.order.createTime }}</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="亚马逊接收日期">{{ props.row.receivingTime }}</el-descriptions-item>
|
||||
<el-descriptions-item label="上架天数">{{ props.row.order.createTime }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="发货日期" align="center" prop="gmtCreate" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.staShipmentDate, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="店铺名称" align="center" prop="sellerName" />
|
||||
<el-table-column label="货件编号" align="center" prop="shipmentId" />
|
||||
<el-table-column label="商品详情" align="center">
|
||||
<template #default="scope">
|
||||
<el-popover placement="top" :width="600" trigger="hover" @show="showPop(scope.row)">
|
||||
<template #reference>
|
||||
<el-button style="margin-right: 16px">查看</el-button>
|
||||
</template>
|
||||
<el-table :data="scope.row.itemVoList">
|
||||
<el-table-column width="200" property="productName" label="品名" />
|
||||
<el-table-column width="200" property="msku" label="msku" />
|
||||
<el-table-column width="150" property="asin" label="asin" />
|
||||
|
||||
</el-table>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="150" label="货件明细" align="center" prop="shipToAddress">
|
||||
<template #default="{ row }">
|
||||
<el-button @click="openDetailDialog(row.detailList)"> 查看详情</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="物流中心编码" align="center" prop="destination" />
|
||||
<el-table-column label="总箱子数量" align="center" prop="boxQuantity" />
|
||||
<el-table-column label="箱子尺寸" align="center" prop="boxSize" />
|
||||
<el-table-column label="供应商称重" align="center" prop="vendorWeight" />
|
||||
<el-table-column label="套数" align="center" prop="setTotal" />
|
||||
<!-- <el-table-column label="渠道ID" align="center" prop="channelId" />-->
|
||||
|
||||
<el-table-column width="150" label="仓库配送地址" align="center" prop="shipToAddress">
|
||||
<template #default="{ row }">
|
||||
<el-button @click="openAddressDialog(row.shipToAddress)"> 查看详情</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="亚马逊货件状态" align="center" prop="gmtCreate" width="180">
|
||||
<template #default="scope">
|
||||
<el-tag>{{ scope.row.shipmentStatus }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="物流渠道" align="center" prop="channelName" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="Edit"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasRoles="['superadmin']"
|
||||
v-hasPermi="['amz:shipmentPlan:edit']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="发货" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="Promotion"
|
||||
@click="handleSend(scope.row)"
|
||||
v-hasRoles="['superadmin']"
|
||||
v-hasPermi="['amz:shipmentPlan:remove']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
<!-- 添加或修改货件计划对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="shipmentPlanFormRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="关联系统ID" prop="sid">
|
||||
<el-input v-model="form.sid" placeholder="请输入关联系统ID" />
|
||||
</el-form-item>
|
||||
<el-form-item label="货件编号" prop="shipmentId">
|
||||
<el-input v-model="form.shipmentId" placeholder="请输入货件编号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="货件名称" prop="shipmentName">
|
||||
<el-input v-model="form.shipmentName" placeholder="请输入货件名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="物流中心编码" prop="destination">
|
||||
<el-input v-model="form.destination" placeholder="请输入物流中心编码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="运输模式" prop="shippingMode">
|
||||
<el-input v-model="form.shippingMode" placeholder="请输入运输模式" />
|
||||
</el-form-item>
|
||||
<el-form-item label="运输方案" prop="shippingSolution">
|
||||
<el-input v-model="form.shippingSolution" placeholder="请输入运输方案" />
|
||||
</el-form-item>
|
||||
<el-form-item label="最后更新时间" prop="gmtModified">
|
||||
<el-date-picker clearable v-model="form.gmtModified" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择最后更新时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="gmtCreate">
|
||||
<el-date-picker clearable v-model="form.gmtCreate" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择创建时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="参考编号" prop="referenceId">
|
||||
<el-input v-model="form.referenceId" placeholder="请输入参考编号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="入库计划ID" prop="staInboundPlanId">
|
||||
<el-input v-model="form.staInboundPlanId" placeholder="请输入入库计划ID" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- 详情对话框 -->
|
||||
<el-dialog v-model="dialogVisible" title="地址详细信息" width="60%">
|
||||
<el-table :data="addressTableData">
|
||||
<el-table-column prop="key" label="字段" width="180" />
|
||||
<el-table-column prop="value" label="值" />
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="detailDialogVisible" title="货件明细" width="60%">
|
||||
<el-table :data="detailTableData">
|
||||
<el-table-column label="FBA货件编号" align="center" prop="fbaShipmentId" />
|
||||
<el-table-column label="FBA箱号" align="center" prop="fbaBoxNumber" />
|
||||
<el-table-column label="物流商名称" align="center" prop="logisticsProviderName" />
|
||||
<el-table-column label="实际货件数量" align="center" prop="shipmentQuantity" />
|
||||
<el-table-column label="物流称重" align="center" prop="logisticsWeight">
|
||||
<template #default="scope">
|
||||
{{ scope.row.logisticsWeight != null ? `${scope.row.logisticsWeight} kg` : '' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="物流追踪号" align="center" prop="trackingNumber">
|
||||
<template #default="scope">
|
||||
<el-link :underline="true" type="success" :href="`https://t.17track.net/zh-cn#nums=${scope.row.trackingNumber}`" target="_blank">
|
||||
{{ scope.row.trackingNumber }}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="物流状态" align="center" prop="logisticsStatus">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="biz_logistics_status" :value="scope.row.logisticsStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="更新时间" align="center" prop="updateTime" />
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="channelDialogVisible" title="查询报价" width="60%">
|
||||
<el-form :model="form" label-width="auto" style="max-width: 600px">
|
||||
<el-form-item label="目的地仓库">
|
||||
<el-input v-model="currentDes" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="渠道选择">
|
||||
<el-cascader
|
||||
v-model="selectedChannel"
|
||||
placeholder="请选择渠道"
|
||||
:props="{ emitPath: false }"
|
||||
:options="groupedChannels"
|
||||
@change="cascaderChange"
|
||||
:show-all-levels="false"
|
||||
filterable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="日期选择">
|
||||
<el-date-picker v-model="shipDate" type="date" placeholder="Pick a day" value-format="YYYY-MM-DD" :size="size" />
|
||||
</el-form-item>
|
||||
<el-button :loading="buttonLoading" type="primary" @click="checkPrice()">查询报价</el-button>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="dialogTableVisible" title="已经存在的询价单" width="1800">
|
||||
<el-table :data="tableData" style="width: 100%" border stripe>
|
||||
<!-- 基础文本列 -->
|
||||
<el-table-column prop="inquiryNo" label="询价编号" width="180" />
|
||||
<el-table-column prop="channelName" label="渠道名称" width="200" />
|
||||
<el-table-column prop="transportChannel" label="运输方式" width="120" />
|
||||
<el-table-column prop="quoteDate" label="询价日期" width="200" />
|
||||
<!-- 时间格式化列 -->
|
||||
<el-table-column prop="deadline" label="截止时间" width="180">
|
||||
<template #default="{ row }">
|
||||
{{ formatTime(row.deadline) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="effectiveStartTime" label="生效开始时间" width="180">
|
||||
<template #default="{ row }">
|
||||
{{ formatTime(row.effectiveStartTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="effectiveEndTime" label="生效结束时间" width="180">
|
||||
<template #default="{ row }">
|
||||
{{ formatTime(row.effectiveEndTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 状态标签列 -->
|
||||
<el-table-column prop="inquiryStatus" label="询价状态" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="statusTagType(row.inquiryStatus)" effect="light">
|
||||
{{ row.inquiryStatus }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 其他信息列 -->
|
||||
<el-table-column prop="destination" label="目的地" width="120" />
|
||||
|
||||
<el-table-column prop="requesterId" label="请求方ID" width="120" />
|
||||
|
||||
<!-- 空值处理 -->
|
||||
<el-table-column prop="targetProviders" label="目标供应商">
|
||||
<template #default="{ row }">
|
||||
{{ row.targetProviders || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<el-drawer size="60%" v-model="drawer" :direction="direction">
|
||||
<template #header>
|
||||
<h4>物流商报价</h4>
|
||||
</template>
|
||||
<template #default>
|
||||
<el-table v-loading="loading" :data="logisticsQuoteList" @selection-change="handleSelectionChange">
|
||||
<el-table-column label="物流商用户ID" align="center" prop="userId" />
|
||||
<el-table-column label="目的地" align="center" prop="destination" />
|
||||
<el-table-column label="渠道名称" align="center" prop="channelName" />
|
||||
<el-table-column label="基础价格" align="center" prop="price" />
|
||||
<el-table-column label="时效" align="center" prop="leadTime" />
|
||||
<el-table-column label="附加费" align="center" prop="surcharge" />
|
||||
<el-table-column label="报价生效日期" align="center" prop="quoteDate" width="80">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.quoteDate, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="提交状态" align="center" prop="isSubmitted" />
|
||||
<el-table-column label="报价备注" align="center" prop="remark" />
|
||||
<el-table-column label="渠道类型" align="center" prop="channelType" />
|
||||
<el-table-column label="是否双清包税" align="center" prop="isDdp" />
|
||||
<el-table-column label="单位" align="center" prop="unit" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button text size="small" type="primary" @click="createOrder(scope.row)" v-hasPermi="['amz:logisticsQuote:edit']">
|
||||
创建货运订单
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
<template #footer>
|
||||
<div style="flex: auto">
|
||||
<el-button @click="cancelClick">取消</el-button>
|
||||
<el-button type="primary" @click="confirmClick">确认</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="ShipmentPlan" lang="ts">
|
||||
import {
|
||||
listShipmentPlan,
|
||||
getShipmentPlan,
|
||||
delShipmentPlan,
|
||||
addShipmentPlan,
|
||||
updateShipmentPlan,
|
||||
takeTodayAmzPlanData,
|
||||
listShipmentPlanOrder
|
||||
} from '@/api/amz/shipmentPlan';
|
||||
import { listAllLogisticsChannel } from '@/api/amz/logisticsChannel';
|
||||
import type { DrawerProps } from 'element-plus';
|
||||
import { createWithDesAndChannel, queryWithDesAndChannel } from '@/api/amz/inquiryRequest';
|
||||
|
||||
import { queryLogisticsQuote } from '@/api/amz/logisticsQuote';
|
||||
|
||||
import { ShipmentPlanVO, ShipmentPlanQuery, ShipmentPlanForm, ShipmentPlanOrderVO } from '@/api/amz/shipmentPlan/types';
|
||||
import { ElTable } from 'element-plus';
|
||||
import { LogisticsQuoteVO } from '@/api/amz/logisticsQuote/types';
|
||||
import { createOrderForm } from '@/api/amz/logisticsOrder/types';
|
||||
import { createLogisticsOrder } from '@/api/amz/logisticsOrder';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { biz_logistics_status } = toRefs<any>(proxy?.useDict('biz_logistics_status'));
|
||||
|
||||
const { sys_zero_one } = toRefs<any>(proxy?.useDict('sys_zero_one'));
|
||||
|
||||
const shipmentPlanList = ref<ShipmentPlanOrderVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const shipmentPlanFormRef = ref<ElFormInstance>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const initFormData: ShipmentPlanForm = {
|
||||
id: undefined,
|
||||
sid: undefined,
|
||||
shipmentId: undefined,
|
||||
shipmentName: undefined,
|
||||
isClosed: undefined,
|
||||
shipmentStatus: undefined,
|
||||
destination: undefined,
|
||||
shippingMode: undefined,
|
||||
shippingSolution: undefined,
|
||||
gmtModified: undefined,
|
||||
gmtCreate: undefined,
|
||||
syncTime: undefined,
|
||||
staShipmentDate: undefined,
|
||||
staDeliveryStartDate: undefined,
|
||||
staDeliveryEndDate: undefined,
|
||||
shipFromAddress: undefined,
|
||||
shipToAddress: undefined,
|
||||
referenceId: undefined,
|
||||
staInboundPlanId: undefined,
|
||||
isSta: undefined
|
||||
};
|
||||
const data = reactive<PageData<ShipmentPlanForm, ShipmentPlanQuery>>({
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
sid: undefined,
|
||||
shipmentId: undefined,
|
||||
shipmentName: undefined,
|
||||
isClosed: undefined,
|
||||
shipmentStatus: undefined,
|
||||
destination: undefined,
|
||||
shippingMode: undefined,
|
||||
shippingSolution: undefined,
|
||||
gmtModified: undefined,
|
||||
gmtCreate: undefined,
|
||||
syncTime: undefined,
|
||||
staShipmentDate: undefined,
|
||||
staDeliveryStartDate: undefined,
|
||||
staDeliveryEndDate: undefined,
|
||||
shipFromAddress: undefined,
|
||||
shipToAddress: undefined,
|
||||
referenceId: undefined,
|
||||
staInboundPlanId: undefined,
|
||||
isSta: undefined,
|
||||
fbaStatus: 'query',
|
||||
params: {}
|
||||
},
|
||||
rules: {
|
||||
id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }],
|
||||
sid: [{ required: true, message: '关联系统ID不能为空', trigger: 'blur' }],
|
||||
shipmentId: [{ required: true, message: '货件编号不能为空', trigger: 'blur' }],
|
||||
shipmentName: [{ required: true, message: '货件名称不能为空', trigger: 'blur' }],
|
||||
isClosed: [{ required: true, message: '是否关闭不能为空', trigger: 'blur' }],
|
||||
shipmentStatus: [{ required: true, message: '货件状态不能为空', trigger: 'change' }],
|
||||
destination: [{ required: true, message: '物流中心编码不能为空', trigger: 'blur' }],
|
||||
shippingMode: [{ required: true, message: '运输模式不能为空', trigger: 'blur' }],
|
||||
shippingSolution: [{ required: true, message: '运输方案不能为空', trigger: 'blur' }],
|
||||
gmtModified: [{ required: true, message: '最后更新时间不能为空', trigger: 'blur' }],
|
||||
gmtCreate: [{ required: true, message: '创建时间不能为空', trigger: 'blur' }],
|
||||
syncTime: [{ required: true, message: '同步时间不能为空', trigger: 'blur' }],
|
||||
staShipmentDate: [{ required: true, message: '计划发货日期不能为空', trigger: 'blur' }],
|
||||
staDeliveryStartDate: [{ required: true, message: '预计到货开始日不能为空', trigger: 'blur' }],
|
||||
staDeliveryEndDate: [{ required: true, message: '预计到货截止日不能为空', trigger: 'blur' }],
|
||||
shipFromAddress: [{ required: true, message: '发货地址不能为空', trigger: 'blur' }],
|
||||
shipToAddress: [{ required: true, message: '收货地址不能为空', trigger: 'blur' }],
|
||||
referenceId: [{ required: true, message: '参考编号不能为空', trigger: 'blur' }],
|
||||
staInboundPlanId: [{ required: true, message: '入库计划ID不能为空', trigger: 'blur' }],
|
||||
isSta: [{ required: true, message: '是否STA计划不能为空', trigger: 'blur' }]
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
const createOrderData = ref<createOrderForm>({
|
||||
fbaShipmentId: undefined,
|
||||
logicQuoteId: undefined
|
||||
});
|
||||
|
||||
const showPop = async (row: any) => {
|
||||
console.log('row', row);
|
||||
};
|
||||
|
||||
const createOrder = async (row: ShipmentPlanVO) => {
|
||||
// 创建货运订单
|
||||
console.log('row', row);
|
||||
console.log('currentFBAData', currentFBAData.value);
|
||||
createOrderData.value.fbaShipmentId = currentFBAData.value.shipmentId;
|
||||
createOrderData.value.logicQuoteId = row.id;
|
||||
const res = await createLogisticsOrder(createOrderData.value);
|
||||
console.log('res', res);
|
||||
if (res.code === 200) {
|
||||
ElMessage.success('创建成功');
|
||||
} else {
|
||||
ElMessage.error('创建失败');
|
||||
}
|
||||
drawer.value = false;
|
||||
};
|
||||
|
||||
const dialogTableVisible = ref(false);
|
||||
|
||||
const logisticsQuoteList = ref<LogisticsQuoteVO[]>([]);
|
||||
|
||||
const tableData = ref([
|
||||
{
|
||||
channelId: '1902912289404719106',
|
||||
channelName: '美国-海运-美森正班船',
|
||||
deadline: '2025-03-22 11:00:00',
|
||||
destination: 'LGB8',
|
||||
effectiveEndTime: '2025-03-30 15:30:19',
|
||||
effectiveStartTime: '2025-03-23 15:30:19',
|
||||
id: '1903348528587018242',
|
||||
inquiryNo: 'INQ20250322000004',
|
||||
inquiryStatus: 'OPEN',
|
||||
quoteDate: '2025-03-22 00:00:00',
|
||||
requesterId: 1,
|
||||
targetProviders: null,
|
||||
transportChannel: 'sea'
|
||||
}
|
||||
]);
|
||||
|
||||
// 时间格式化方法
|
||||
const formatTime = (timeString) => {
|
||||
return timeString.replace(' ', '\n'); // 换行显示日期时间
|
||||
};
|
||||
|
||||
// 状态标签样式
|
||||
const statusTagType = (status) => {
|
||||
switch (status) {
|
||||
case 'OPEN':
|
||||
return 'success';
|
||||
case 'CLOSED':
|
||||
return 'info';
|
||||
case 'EXPIRED':
|
||||
return 'warning';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
const drawer = ref(false);
|
||||
const direction = ref<DrawerProps['direction']>('ltr');
|
||||
const radio1 = ref('Option 1');
|
||||
const handleClose = (done: () => void) => {
|
||||
ElMessageBox.confirm('Are you sure you want to close this?')
|
||||
.then(() => {
|
||||
done();
|
||||
})
|
||||
.catch(() => {
|
||||
// catch error
|
||||
});
|
||||
};
|
||||
|
||||
function cancelClick() {
|
||||
drawer.value = false;
|
||||
}
|
||||
|
||||
const cascaderChange = (value) => {
|
||||
console.log(value);
|
||||
console.log('selectedChannel', selectedChannel);
|
||||
};
|
||||
|
||||
function confirmClick() {
|
||||
ElMessageBox.confirm(`你确定要关闭 ${radio1.value} ?`)
|
||||
.then(() => {
|
||||
drawer.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
// catch error
|
||||
});
|
||||
}
|
||||
|
||||
const getLocalDate = () => {
|
||||
const today = new Date();
|
||||
const year = today.getFullYear();
|
||||
const month = String(today.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(today.getDate()).padStart(2, '0');
|
||||
return `${year}-${month}-${day}`;
|
||||
};
|
||||
const shipDate = ref(getLocalDate());
|
||||
/** 查询货件计划列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listShipmentPlanOrder(queryParams.value);
|
||||
shipmentPlanList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
let channelTableData = ref([]);
|
||||
|
||||
const getAllChannelData = async () => {
|
||||
const res = await listAllLogisticsChannel();
|
||||
console.log('getAllChannelData');
|
||||
console.log(res);
|
||||
channelTableData.value = res.rows;
|
||||
console.log('groupedChannels:', groupedChannels.value);
|
||||
};
|
||||
|
||||
// 定义映射关系,将编码转换为中文标签
|
||||
const countryMap = {
|
||||
us: '美国'
|
||||
// 可扩展其他国家的映射
|
||||
};
|
||||
|
||||
const shippingMethodMap = {
|
||||
air: '空运',
|
||||
sea: '海运'
|
||||
// 可扩展其他运输方式
|
||||
};
|
||||
|
||||
function transformChannels(channels) {
|
||||
const result = [];
|
||||
const countryGroups = {}; // 按国家缓存顶级节点
|
||||
|
||||
channels.forEach((channel) => {
|
||||
const { country, shippingMethod, channelName, id } = channel;
|
||||
|
||||
// 处理国家节点
|
||||
const countryValue = country;
|
||||
const countryLabel = countryMap[country] || country;
|
||||
if (!countryGroups[countryValue]) {
|
||||
countryGroups[countryValue] = {
|
||||
value: countryValue,
|
||||
label: countryLabel,
|
||||
children: []
|
||||
};
|
||||
result.push(countryGroups[countryValue]);
|
||||
}
|
||||
|
||||
// 处理运输方式节点
|
||||
const methodValue = shippingMethod;
|
||||
const methodLabel = shippingMethodMap[shippingMethod] || shippingMethod;
|
||||
let methodNode = countryGroups[countryValue].children.find((m) => m.value === methodValue);
|
||||
if (!methodNode) {
|
||||
methodNode = {
|
||||
value: methodValue,
|
||||
label: methodLabel,
|
||||
children: []
|
||||
};
|
||||
countryGroups[countryValue].children.push(methodNode);
|
||||
}
|
||||
|
||||
// 添加渠道节点
|
||||
methodNode.children.push({
|
||||
value: id,
|
||||
label: channelName
|
||||
});
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const currentDes = ref<string | number>('');
|
||||
const currentFBAData = ref<ShipmentPlanVO>();
|
||||
|
||||
// 分组后的渠道数据
|
||||
const groupedChannels = computed(() => {
|
||||
// return channelTableData.value.reduce((acc, channel) => {
|
||||
// const country = channel.country;
|
||||
// const method = channel.shippingMethod;
|
||||
//
|
||||
// if (!acc[country]) acc[country] = {};
|
||||
// if (!acc[country][method]) acc[country][method] = [];
|
||||
//
|
||||
// acc[country][method].push(channel);
|
||||
// return acc;
|
||||
// }, {});
|
||||
return transformChannels(channelTableData.value);
|
||||
});
|
||||
|
||||
// 从渠道名称中提取显示标签(移除国家+运输方式前缀)
|
||||
const getChannelLabel = (name) => {
|
||||
return name.split('-').slice(2).join('-');
|
||||
};
|
||||
|
||||
// 获取国家显示名称
|
||||
const getCountryName = (code) => {
|
||||
return countryMap[code] || code.toUpperCase();
|
||||
};
|
||||
|
||||
// 获取运输方式显示名称
|
||||
const getShippingMethodName = (method) => {
|
||||
return shippingMethodMap[method] || method;
|
||||
};
|
||||
|
||||
// 交互逻辑
|
||||
const activeCollapse = ref(['us']); // 默认展开美国
|
||||
const selectedChannel = ref(null);
|
||||
|
||||
const handleChannelSelect = (channelId) => {
|
||||
console.log('Selected channel ID:', channelId);
|
||||
// 这里可以触发自定义事件或调用API
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
};
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = { ...initFormData };
|
||||
shipmentPlanFormRef.value?.resetFields();
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: ShipmentPlanVO[]) => {
|
||||
ids.value = selection.map((item) => item.id);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
};
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
reset();
|
||||
dialog.visible = true;
|
||||
dialog.title = '添加货件计划';
|
||||
};
|
||||
|
||||
const checkPrice = async () => {
|
||||
console.log('checkPrice', currentDes.value, selectedChannel.value);
|
||||
//查询报价单
|
||||
console.log('sshipDate.value', shipDate.value);
|
||||
const res = await queryLogisticsQuote(currentDes.value, selectedChannel.value, shipDate.value);
|
||||
console.log('查询报价单', res);
|
||||
if (res.total == 0) {
|
||||
//查询询价单
|
||||
const requestQuote = await queryWithDesAndChannel(currentDes.value, selectedChannel.value, shipDate.value);
|
||||
console.log('查询询价单', requestQuote);
|
||||
if (requestQuote.total == 0) {
|
||||
console.log('询价单也没数据');
|
||||
channelDialogVisible.value = false;
|
||||
ElMessageBox.confirm('未查询到价格信息,是否要向物流商发布询价?', '提醒', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(async () => {
|
||||
const res2 = await createWithDesAndChannel(currentDes.value, selectedChannel.value, shipDate.value);
|
||||
console.log('checkPriceEnd2', res2);
|
||||
if (res2.code == 200) {
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '询价单创建成功'
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// ElMessage({
|
||||
// type: 'info',
|
||||
// message: 'Delete canceled'
|
||||
// });
|
||||
});
|
||||
} else {
|
||||
//显示询价单
|
||||
channelDialogVisible.value = false;
|
||||
dialogTableVisible.value = true;
|
||||
tableData.value = requestQuote.rows;
|
||||
console.log('requestQuote.rows', requestQuote.rows);
|
||||
console.log('tableData', tableData.value);
|
||||
}
|
||||
} else {
|
||||
//显示报价单
|
||||
channelDialogVisible.value = false;
|
||||
drawer.value = true;
|
||||
logisticsQuoteList.value = res.rows;
|
||||
}
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: ShipmentPlanVO) => {
|
||||
reset();
|
||||
const _id = row?.id || ids.value[0];
|
||||
const res = await getShipmentPlan(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
dialog.visible = true;
|
||||
dialog.title = '修改货件计划';
|
||||
};
|
||||
|
||||
const handleSend = async (row?: ShipmentPlanVO) => {
|
||||
reset();
|
||||
channelDialogVisible.value = true;
|
||||
console.log(row);
|
||||
currentFBAData.value = row;
|
||||
currentDes.value = row.destination;
|
||||
};
|
||||
|
||||
const snycTodayPlan = async () => {
|
||||
const res = await takeTodayAmzPlanData();
|
||||
if (res.code == 200) {
|
||||
proxy?.$modal.msgSuccess('同步成功');
|
||||
await getList();
|
||||
}
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
shipmentPlanFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
if (form.value.id) {
|
||||
await updateShipmentPlan(form.value).finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
await addShipmentPlan(form.value).finally(() => (buttonLoading.value = false));
|
||||
}
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: ShipmentPlanVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除货件计划编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
|
||||
await delShipmentPlan(_ids);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
};
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download(
|
||||
'amz/shipmentPlan/export',
|
||||
{
|
||||
...queryParams.value
|
||||
},
|
||||
`shipmentPlan_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
};
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const detailDialogVisible = ref(false);
|
||||
|
||||
const addressTableData = ref([]);
|
||||
|
||||
const detailTableData = ref([]);
|
||||
|
||||
const channelDialogVisible = ref(false);
|
||||
|
||||
// 转换对象为表格需要的数组格式
|
||||
const convertAddressToTableData = (address) => {
|
||||
return Object.entries(address).map(([key, value]) => ({
|
||||
key: key,
|
||||
value: value
|
||||
}));
|
||||
};
|
||||
|
||||
// 打开对话框
|
||||
const openAddressDialog = (address) => {
|
||||
addressTableData.value = convertAddressToTableData(address);
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
const openDetailDialog = (detail) => {
|
||||
detailTableData.value = detail;
|
||||
detailDialogVisible.value = true;
|
||||
};
|
||||
|
||||
const currentRow = ref();
|
||||
const singleTableRef = ref<InstanceType<typeof ElTable>>();
|
||||
|
||||
const handleCurrentChange = (val: ShipmentPlanVO | undefined) => {
|
||||
currentRow.value = val;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
getAllChannelData();
|
||||
});
|
||||
</script>
|
932
src/views/amz/shipmentPlanSend/index.vue
Normal file
932
src/views/amz/shipmentPlanSend/index.vue
Normal file
@ -0,0 +1,932 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="货件编号" prop="shipmentId">
|
||||
<el-input v-model="queryParams.shipmentId" placeholder="请输入货件编号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="货件名称" prop="shipmentName">
|
||||
<el-input v-model="queryParams.shipmentName" placeholder="请输入货件名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="物流中心编码" prop="destination">
|
||||
<el-input v-model="queryParams.destination" placeholder="请输入物流中心编码" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasRoles="['superadmin']" v-hasPermi="['amz:shipmentPlan:add']"
|
||||
>新增
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Edit"
|
||||
:disabled="single"
|
||||
@click="handleUpdate()"
|
||||
v-hasRoles="['superadmin']"
|
||||
v-hasPermi="['amz:shipmentPlan:edit']"
|
||||
>修改
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="Delete"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete()"
|
||||
v-hasRoles="['superadmin']"
|
||||
v-hasPermi="['amz:shipmentPlan:remove']"
|
||||
>删除
|
||||
</el-button>
|
||||
</el-col>
|
||||
<!-- <el-col :span="1.5">-->
|
||||
<!-- <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['amz:shipmentPlan:export']">导出 </el-button>-->
|
||||
<!-- </el-col>-->
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="shipmentPlanList" @current-change="handleCurrentChange" highlight-current-row ref="singleTableRef">
|
||||
<el-table-column type="expand">
|
||||
<template #default="props">
|
||||
<el-descriptions size="small" border title="货件详情">
|
||||
<el-descriptions-item label="货件名称">{{ props.row.shipmentName }}</el-descriptions-item>
|
||||
<!-- <el-descriptions-item label="货件状态">{{ props.row.shipmentStatus }}</el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="运输模式">{{ props.row.shippingMode }}</el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="运输方案">{{ props.row.shippingSolution }}</el-descriptions-item>-->
|
||||
<el-descriptions-item label="入库计划ID">{{ props.row.staInboundPlanId }}</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="创建时间">{{ parseTime(props.row.gmtCreate, '{y}-{m}-{d}') }} </el-descriptions-item>
|
||||
<!-- <el-descriptions-item label="计划发货日期">{{ parseTime(props.row.staShipmentDate, '{y}-{m}-{d}') }} </el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="预计到货开始日">{{ parseTime(props.row.staDeliveryStartDate, '{y}-{m}-{d}') }} </el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="预计到货截止日">{{ parseTime(props.row.staDeliveryEndDate, '{y}-{m}-{d}') }} </el-descriptions-item>-->
|
||||
</el-descriptions>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="发货日期" align="center" prop="gmtCreate" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.staShipmentDate, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="店铺名称" align="center" prop="sellerName" />
|
||||
<el-table-column label="货件编号" align="center" prop="shipmentId" />
|
||||
<el-table-column label="商品详情" align="center">
|
||||
<template #default="scope">
|
||||
<el-popover placement="top" :width="600" trigger="hover" @show="showPop(scope.row)">
|
||||
<template #reference>
|
||||
<el-button style="margin-right: 16px">查看</el-button>
|
||||
</template>
|
||||
<el-table :data="scope.row.itemVoList">
|
||||
<el-table-column width="200" property="productName" label="品名" />
|
||||
<el-table-column width="200" property="msku" label="msku" />
|
||||
<el-table-column width="150" property="asin" label="asin" />
|
||||
</el-table>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="物流中心编码" align="center" prop="destination" />
|
||||
<el-table-column label="总箱子数量" align="center" prop="boxQuantity" />
|
||||
<el-table-column label="箱子尺寸" align="center" prop="boxSize" />
|
||||
<el-table-column label="供应商称重" align="center" prop="vendorWeight" />
|
||||
<el-table-column label="套数" align="center" prop="setTotal" />
|
||||
<!-- <el-table-column label="渠道ID" align="center" prop="channelId" />-->
|
||||
|
||||
<el-table-column width="150" label="仓库配送地址" align="center" prop="shipToAddress">
|
||||
<template #default="{ row }">
|
||||
<el-button @click="openAddressDialog(row.shipToAddress)"> 查看详情</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="亚马逊货件状态" align="center" prop="gmtCreate" width="180">
|
||||
<template #default="scope">
|
||||
<el-tag>{{ scope.row.shipmentStatus }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="物流渠道" align="center" prop="channelName" />
|
||||
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['amz:shipmentPlan:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<!-- <el-tooltip content="删除" placement="top">-->
|
||||
<!-- <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['amz:shipmentPlan:remove']"></el-button>-->
|
||||
<!-- </el-tooltip>-->
|
||||
|
||||
<el-button link type="primary" size="small" @click="handleSend(scope.row)" v-hasPermi="['amz:shipmentPlan:remove']">查询报价 </el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
<!-- 添加或修改货件计划对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="shipmentPlanFormRef" :model="form" :rules="rules" label-width="120px">
|
||||
<el-form-item label="货件编号" prop="shipmentId">
|
||||
<el-input v-model="form.shipmentId" placeholder="请输入货件编号" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="货件名称" prop="shipmentName">
|
||||
<el-input v-model="form.shipmentName" placeholder="请输入货件名称" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="物流中心编码" prop="destination">
|
||||
<el-input v-model="form.destination" placeholder="请输入物流中心编码" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="物流渠道">
|
||||
<el-cascader
|
||||
ref="channelCascaderRef"
|
||||
v-model="selectedChannel"
|
||||
:props="{ emitPath: false }"
|
||||
placeholder="请选择渠道"
|
||||
:options="groupedChannels"
|
||||
@change="cascaderChange"
|
||||
:show-all-levels="false"
|
||||
filterable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="总箱子数量" prop="boxQuantity">
|
||||
<el-input v-model="form.boxQuantity" placeholder="请输入总箱子数量" />
|
||||
</el-form-item>
|
||||
<el-form-item label="箱子尺寸" prop="boxSize">
|
||||
<el-input v-model="form.boxSize" placeholder="请输入箱子尺寸" />
|
||||
</el-form-item>
|
||||
<el-form-item label="供应商称重" prop="vendorWeight">
|
||||
<el-input v-model="form.vendorWeight" placeholder="请输入供应商称重" />
|
||||
</el-form-item>
|
||||
<el-form-item label="套数" prop="setTotal">
|
||||
<el-input v-model="form.setTotal" placeholder="请输入套数" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- 详情对话框 -->
|
||||
<el-dialog v-model="dialogVisible" title="地址详细信息" width="60%">
|
||||
<el-table :data="addressTableData">
|
||||
<el-table-column prop="key" label="字段" width="180" />
|
||||
<el-table-column prop="value" label="值" />
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="channelDialogVisible" title="查询报价" width="60%">
|
||||
<!-- <el-radio-group v-model="form.status">-->
|
||||
<!-- <el-radio v-for="dict in biz_transport_channel" :key="dict.value" :value="dict.value">-->
|
||||
<!-- {{ dict.label }}-->
|
||||
<!-- </el-radio>-->
|
||||
<!-- </el-radio-group>-->
|
||||
|
||||
<!-- <el-radio-group v-model="form.status">-->
|
||||
<!-- <!– 按国家分组循环 –>-->
|
||||
<!-- <div v-for="(transportDict, country) in groupedChannels" :key="country">-->
|
||||
<!-- <!– 国家标题 –>-->
|
||||
<!-- <div class="country-title">{{ country }}</div>-->
|
||||
|
||||
<!-- <!– 运输方式子分组 –>-->
|
||||
<!-- <div-->
|
||||
<!-- v-for="(channels, transport) in transportDict"-->
|
||||
<!-- :key="transport"-->
|
||||
<!-- class="transport-group"-->
|
||||
<!-- >-->
|
||||
<!-- <el-radio-->
|
||||
<!-- v-for="dict in channels"-->
|
||||
<!-- :key="dict.value"-->
|
||||
<!-- :value="dict.value"-->
|
||||
<!-- border-->
|
||||
<!-- class="channel-item"-->
|
||||
<!-- >-->
|
||||
<!-- {{ transport }} - {{ getChannelName(dict.label) }}-->
|
||||
<!-- </el-radio>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </el-radio-group>-->
|
||||
<el-form :model="form" label-width="auto" style="max-width: 600px">
|
||||
<el-form-item label="目的地仓库">
|
||||
<el-input v-model="currentDes" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="渠道选择">
|
||||
<!-- <el-collapse v-model="activeCollapse">-->
|
||||
<!-- <!– 遍历国家分组 –>-->
|
||||
<!-- <el-collapse-item v-for="(countryGroup, country) in groupedChannels" :key="country" :title="getCountryName(country)" :name="country">-->
|
||||
<!-- <!– 遍历运输方式 –>-->
|
||||
<!-- <div v-for="(methodGroup, method) in countryGroup" :key="method">-->
|
||||
<!-- <div class="shipping-method-title">-->
|
||||
<!-- {{ getShippingMethodName(method) }}-->
|
||||
<!-- </div>-->
|
||||
<!-- <el-radio-group v-model="selectedChannel" @change="handleChannelSelect">-->
|
||||
<!-- <!– 遍历具体渠道 –>-->
|
||||
<!-- <div v-for="channel in methodGroup" :key="channel.id" class="channel-item">-->
|
||||
<!-- <el-radio :label="channel.id">-->
|
||||
<!-- {{ getChannelLabel(channel.channelName) }}-->
|
||||
<!-- </el-radio>-->
|
||||
<!-- <div class="channel-description">{{ channel.description }}</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </el-radio-group>-->
|
||||
<!-- </div>-->
|
||||
<!-- </el-collapse-item>-->
|
||||
<!-- </el-collapse>-->
|
||||
<el-cascader
|
||||
v-model="selectedChannel"
|
||||
placeholder="请选择渠道"
|
||||
:props="{ emitPath: false }"
|
||||
:options="groupedChannels"
|
||||
@change="cascaderChange"
|
||||
:show-all-levels="false"
|
||||
filterable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="日期选择">
|
||||
<el-date-picker v-model="shipDate" type="date" placeholder="Pick a day" value-format="YYYY-MM-DD" :size="size" />
|
||||
</el-form-item>
|
||||
<el-button :loading="buttonLoading" type="primary" @click="checkPrice()">查询报价</el-button>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="dialogTableVisible" title="已经存在的询价单" width="1800">
|
||||
<el-table :data="tableData" style="width: 100%" border stripe>
|
||||
<!-- 基础文本列 -->
|
||||
<el-table-column prop="inquiryNo" label="询价编号" width="180" />
|
||||
<el-table-column prop="channelName" label="渠道名称" width="200" />
|
||||
<el-table-column prop="transportChannel" label="运输方式" width="120" />
|
||||
<el-table-column prop="quoteDate" label="询价日期" width="200" />
|
||||
<!-- 时间格式化列 -->
|
||||
<el-table-column prop="deadline" label="截止时间" width="180">
|
||||
<template #default="{ row }">
|
||||
{{ formatTime(row.deadline) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="effectiveStartTime" label="生效开始时间" width="180">
|
||||
<template #default="{ row }">
|
||||
{{ formatTime(row.effectiveStartTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="effectiveEndTime" label="生效结束时间" width="180">
|
||||
<template #default="{ row }">
|
||||
{{ formatTime(row.effectiveEndTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 状态标签列 -->
|
||||
<el-table-column prop="inquiryStatus" label="询价状态" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="statusTagType(row.inquiryStatus)" effect="light">
|
||||
{{ row.inquiryStatus }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 其他信息列 -->
|
||||
<el-table-column prop="destination" label="目的地" width="120" />
|
||||
|
||||
<el-table-column prop="requesterId" label="请求方ID" width="120" />
|
||||
|
||||
<!-- 空值处理 -->
|
||||
<el-table-column prop="targetProviders" label="目标供应商">
|
||||
<template #default="{ row }">
|
||||
{{ row.targetProviders || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<el-drawer size="80%" v-model="drawer" :direction="direction">
|
||||
<template #header>
|
||||
<h4>物流商报价</h4>
|
||||
</template>
|
||||
<template #default>
|
||||
<el-table v-loading="loading" :data="logisticsQuoteList" @selection-change="handleSelectionChange">
|
||||
<el-table-column label="物流商用户ID" align="center" prop="userId" />
|
||||
<el-table-column label="目的地" align="center" prop="destination" />
|
||||
<el-table-column label="渠道名称" align="center" prop="channelName" />
|
||||
<el-table-column label="基础价格" align="center" prop="price" />
|
||||
<el-table-column label="时效" align="center" prop="leadTime" />
|
||||
<el-table-column label="附加费" align="center" prop="surcharge" />
|
||||
<el-table-column label="报价生效日期" align="center" prop="quoteDate" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.quoteDate, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="提交状态" align="center" prop="isSubmitted" />
|
||||
<el-table-column label="报价备注" align="center" prop="remark" />
|
||||
<el-table-column label="渠道类型" align="center" prop="channelType" />
|
||||
<el-table-column label="是否双清包税" align="center" prop="isDdp" />
|
||||
<el-table-column label="单位" align="center" prop="unit" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button text size="small" type="primary" @click="createOrder(scope.row)" v-hasPermi="['amz:shipmentPlan:edit']">
|
||||
创建货运订单
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
<template #footer>
|
||||
<div style="flex: auto">
|
||||
<el-button @click="cancelClick">取消</el-button>
|
||||
<el-button type="primary" @click="confirmClick">确认</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="ShipmentPlan" lang="ts">
|
||||
import {
|
||||
listShipmentPlan,
|
||||
getShipmentPlan,
|
||||
delShipmentPlan,
|
||||
addShipmentPlan,
|
||||
updateShipmentPlan,
|
||||
takeTodayAmzPlanData
|
||||
} from '@/api/amz/shipmentPlan';
|
||||
import { listAllLogisticsChannel } from '@/api/amz/logisticsChannel';
|
||||
import type { DrawerProps } from 'element-plus';
|
||||
import { createWithDesAndChannel, queryWithDesAndChannel } from '@/api/amz/inquiryRequest';
|
||||
|
||||
import { queryLogisticsQuote } from '@/api/amz/logisticsQuote';
|
||||
|
||||
import { ShipmentPlanVO, ShipmentPlanQuery, ShipmentPlanForm } from '@/api/amz/shipmentPlan/types';
|
||||
import { ElTable } from 'element-plus';
|
||||
import { LogisticsQuoteVO } from '@/api/amz/logisticsQuote/types';
|
||||
import { createOrderForm } from '@/api/amz/logisticsOrder/types';
|
||||
import { createLogisticsOrder } from '@/api/amz/logisticsOrder';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { biz_transport_channel } = toRefs<any>(proxy?.useDict('biz_transport_channel'));
|
||||
|
||||
const { sys_zero_one } = toRefs<any>(proxy?.useDict('sys_zero_one'));
|
||||
|
||||
const shipmentPlanList = ref<ShipmentPlanVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const shipmentPlanFormRef = ref<ElFormInstance>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const initFormData: ShipmentPlanForm = {
|
||||
id: undefined,
|
||||
sid: undefined,
|
||||
shipmentId: undefined,
|
||||
shipmentName: undefined,
|
||||
isClosed: undefined,
|
||||
shipmentStatus: undefined,
|
||||
destination: undefined,
|
||||
shippingMode: undefined,
|
||||
shippingSolution: undefined,
|
||||
gmtModified: undefined,
|
||||
gmtCreate: undefined,
|
||||
syncTime: undefined,
|
||||
staShipmentDate: undefined,
|
||||
staDeliveryStartDate: undefined,
|
||||
staDeliveryEndDate: undefined,
|
||||
shipFromAddress: undefined,
|
||||
shipToAddress: undefined,
|
||||
referenceId: undefined,
|
||||
staInboundPlanId: undefined,
|
||||
isSta: undefined,
|
||||
boxQuantity: undefined,
|
||||
boxSize: undefined,
|
||||
vendorWeight: undefined,
|
||||
setTotal: undefined,
|
||||
channelId: undefined,
|
||||
channelName: undefined
|
||||
};
|
||||
const data = reactive<PageData<ShipmentPlanForm, ShipmentPlanQuery>>({
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
sid: undefined,
|
||||
shipmentId: undefined,
|
||||
shipmentName: undefined,
|
||||
isClosed: undefined,
|
||||
shipmentStatus: undefined,
|
||||
destination: undefined,
|
||||
shippingMode: undefined,
|
||||
shippingSolution: undefined,
|
||||
gmtModified: undefined,
|
||||
gmtCreate: undefined,
|
||||
syncTime: undefined,
|
||||
staShipmentDate: undefined,
|
||||
staDeliveryStartDate: undefined,
|
||||
staDeliveryEndDate: undefined,
|
||||
shipFromAddress: undefined,
|
||||
shipToAddress: undefined,
|
||||
referenceId: undefined,
|
||||
staInboundPlanId: undefined,
|
||||
isSta: undefined,
|
||||
fbaStatus: 'send',
|
||||
boxQuantity: undefined,
|
||||
boxSize: undefined,
|
||||
vendorWeight: undefined,
|
||||
setTotal: undefined,
|
||||
channelId: undefined,
|
||||
channelName: undefined,
|
||||
params: {}
|
||||
},
|
||||
rules: {
|
||||
id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }],
|
||||
sid: [{ required: true, message: '关联系统ID不能为空', trigger: 'blur' }],
|
||||
shipmentId: [{ required: true, message: '货件编号不能为空', trigger: 'blur' }],
|
||||
shipmentName: [{ required: true, message: '货件名称不能为空', trigger: 'blur' }],
|
||||
isClosed: [{ required: true, message: '是否关闭不能为空', trigger: 'blur' }],
|
||||
shipmentStatus: [{ required: true, message: '货件状态不能为空', trigger: 'change' }],
|
||||
destination: [{ required: true, message: '物流中心编码不能为空', trigger: 'blur' }],
|
||||
shippingMode: [{ required: true, message: '运输模式不能为空', trigger: 'blur' }],
|
||||
shippingSolution: [{ required: true, message: '运输方案不能为空', trigger: 'blur' }],
|
||||
gmtModified: [{ required: true, message: '最后更新时间不能为空', trigger: 'blur' }],
|
||||
gmtCreate: [{ required: true, message: '创建时间不能为空', trigger: 'blur' }],
|
||||
syncTime: [{ required: true, message: '同步时间不能为空', trigger: 'blur' }],
|
||||
staShipmentDate: [{ required: true, message: '计划发货日期不能为空', trigger: 'blur' }],
|
||||
staDeliveryStartDate: [{ required: true, message: '预计到货开始日不能为空', trigger: 'blur' }],
|
||||
staDeliveryEndDate: [{ required: true, message: '预计到货截止日不能为空', trigger: 'blur' }],
|
||||
shipFromAddress: [{ required: true, message: '发货地址不能为空', trigger: 'blur' }],
|
||||
shipToAddress: [{ required: true, message: '收货地址不能为空', trigger: 'blur' }],
|
||||
referenceId: [{ required: true, message: '参考编号不能为空', trigger: 'blur' }],
|
||||
staInboundPlanId: [{ required: true, message: '入库计划ID不能为空', trigger: 'blur' }],
|
||||
isSta: [{ required: true, message: '是否STA计划不能为空', trigger: 'blur' }]
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
const createOrderData = ref<createOrderForm>({
|
||||
fbaShipmentId: undefined,
|
||||
logicQuoteId: undefined
|
||||
});
|
||||
|
||||
const createOrder = async (row: ShipmentPlanVO) => {
|
||||
// 创建货运订单
|
||||
console.log('row', row);
|
||||
console.log('currentFBAData', currentFBAData.value);
|
||||
createOrderData.value.fbaShipmentId = currentFBAData.value.shipmentId;
|
||||
createOrderData.value.logicQuoteId = row.id;
|
||||
const res = await createLogisticsOrder(createOrderData.value);
|
||||
console.log('res', res);
|
||||
if (res.code === 200) {
|
||||
ElMessage.success('创建成功');
|
||||
const updateForm = ref({
|
||||
id: currentFBAData.value.id,
|
||||
fbaStatus: 'query'
|
||||
});
|
||||
await updateShipmentPlan(updateForm.value).finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
ElMessage.error('创建失败');
|
||||
}
|
||||
drawer.value = false;
|
||||
};
|
||||
|
||||
const dialogTableVisible = ref(false);
|
||||
|
||||
const logisticsQuoteList = ref<LogisticsQuoteVO[]>([]);
|
||||
|
||||
const tableData = ref([
|
||||
{
|
||||
channelId: '1902912289404719106',
|
||||
channelName: '美国-海运-美森正班船',
|
||||
deadline: '2025-03-22 11:00:00',
|
||||
destination: 'LGB8',
|
||||
effectiveEndTime: '2025-03-30 15:30:19',
|
||||
effectiveStartTime: '2025-03-23 15:30:19',
|
||||
id: '1903348528587018242',
|
||||
inquiryNo: 'INQ20250322000004',
|
||||
inquiryStatus: 'OPEN',
|
||||
quoteDate: '2025-03-22 00:00:00',
|
||||
requesterId: 1,
|
||||
targetProviders: null,
|
||||
transportChannel: 'sea'
|
||||
}
|
||||
]);
|
||||
|
||||
// 时间格式化方法
|
||||
const formatTime = (timeString) => {
|
||||
return timeString.replace(' ', '\n'); // 换行显示日期时间
|
||||
};
|
||||
|
||||
// 状态标签样式
|
||||
const statusTagType = (status) => {
|
||||
switch (status) {
|
||||
case 'OPEN':
|
||||
return 'success';
|
||||
case 'CLOSED':
|
||||
return 'info';
|
||||
case 'EXPIRED':
|
||||
return 'warning';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
const drawer = ref(false);
|
||||
const direction = ref<DrawerProps['direction']>('ltr');
|
||||
const radio1 = ref('Option 1');
|
||||
const handleClose = (done: () => void) => {
|
||||
ElMessageBox.confirm('Are you sure you want to close this?')
|
||||
.then(() => {
|
||||
done();
|
||||
})
|
||||
.catch(() => {
|
||||
// catch error
|
||||
});
|
||||
};
|
||||
|
||||
function cancelClick() {
|
||||
drawer.value = false;
|
||||
}
|
||||
|
||||
const channelCascaderRef = ref(null);
|
||||
const cascaderChange = (value) => {
|
||||
console.log(value);
|
||||
console.log('selectedChannel', selectedChannel);
|
||||
console.log('groupedChannels', groupedChannels);
|
||||
|
||||
// console.log('channelCascaderRef', channelCascaderRef);
|
||||
console.log('label====', channelCascaderRef.value.getCheckedNodes()[0].label);
|
||||
};
|
||||
|
||||
function confirmClick() {
|
||||
ElMessageBox.confirm(`你确定要关闭 ${radio1.value} ?`)
|
||||
.then(() => {
|
||||
drawer.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
// catch error
|
||||
});
|
||||
}
|
||||
|
||||
const getLocalDate = () => {
|
||||
const today = new Date();
|
||||
const year = today.getFullYear();
|
||||
const month = String(today.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(today.getDate()).padStart(2, '0');
|
||||
return `${year}-${month}-${day}`;
|
||||
};
|
||||
const shipDate = ref(getLocalDate());
|
||||
/** 查询货件计划列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listShipmentPlan(queryParams.value);
|
||||
shipmentPlanList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
let channelTableData = ref([]);
|
||||
|
||||
const getAllChannelData = async () => {
|
||||
const res = await listAllLogisticsChannel();
|
||||
console.log('getAllChannelData');
|
||||
console.log(res);
|
||||
channelTableData.value = res.rows;
|
||||
console.log('groupedChannels:', groupedChannels.value);
|
||||
};
|
||||
|
||||
// 定义映射关系,将编码转换为中文标签
|
||||
const countryMap = {
|
||||
us: '美国'
|
||||
// 可扩展其他国家的映射
|
||||
};
|
||||
|
||||
const shippingMethodMap = {
|
||||
air: '空运',
|
||||
sea: '海运'
|
||||
// 可扩展其他运输方式
|
||||
};
|
||||
|
||||
function transformChannels(channels) {
|
||||
const result = [];
|
||||
const countryGroups = {}; // 按国家缓存顶级节点
|
||||
|
||||
channels.forEach((channel) => {
|
||||
const { country, shippingMethod, channelName, id } = channel;
|
||||
|
||||
// 处理国家节点
|
||||
const countryValue = country;
|
||||
const countryLabel = countryMap[country] || country;
|
||||
if (!countryGroups[countryValue]) {
|
||||
countryGroups[countryValue] = {
|
||||
value: countryValue,
|
||||
label: countryLabel,
|
||||
children: []
|
||||
};
|
||||
result.push(countryGroups[countryValue]);
|
||||
}
|
||||
|
||||
// 处理运输方式节点
|
||||
const methodValue = shippingMethod;
|
||||
const methodLabel = shippingMethodMap[shippingMethod] || shippingMethod;
|
||||
let methodNode = countryGroups[countryValue].children.find((m) => m.value === methodValue);
|
||||
if (!methodNode) {
|
||||
methodNode = {
|
||||
value: methodValue,
|
||||
label: methodLabel,
|
||||
children: []
|
||||
};
|
||||
countryGroups[countryValue].children.push(methodNode);
|
||||
}
|
||||
|
||||
// 添加渠道节点
|
||||
methodNode.children.push({
|
||||
value: id,
|
||||
label: channelName
|
||||
});
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const currentDes = ref<string | number>('');
|
||||
const currentFBAData = ref<ShipmentPlanVO>();
|
||||
|
||||
// 分组后的渠道数据
|
||||
const groupedChannels = computed(() => {
|
||||
// return channelTableData.value.reduce((acc, channel) => {
|
||||
// const country = channel.country;
|
||||
// const method = channel.shippingMethod;
|
||||
//
|
||||
// if (!acc[country]) acc[country] = {};
|
||||
// if (!acc[country][method]) acc[country][method] = [];
|
||||
//
|
||||
// acc[country][method].push(channel);
|
||||
// return acc;
|
||||
// }, {});
|
||||
return transformChannels(channelTableData.value);
|
||||
});
|
||||
|
||||
// 从渠道名称中提取显示标签(移除国家+运输方式前缀)
|
||||
const getChannelLabel = (name) => {
|
||||
return name.split('-').slice(2).join('-');
|
||||
};
|
||||
|
||||
// 获取国家显示名称
|
||||
const getCountryName = (code) => {
|
||||
return countryMap[code] || code.toUpperCase();
|
||||
};
|
||||
|
||||
// 获取运输方式显示名称
|
||||
const getShippingMethodName = (method) => {
|
||||
return shippingMethodMap[method] || method;
|
||||
};
|
||||
|
||||
// 交互逻辑
|
||||
const activeCollapse = ref(['us']); // 默认展开美国
|
||||
const selectedChannel = ref(null);
|
||||
|
||||
const handleChannelSelect = (channelId) => {
|
||||
console.log('Selected channel ID:', channelId);
|
||||
// 这里可以触发自定义事件或调用API
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
};
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = { ...initFormData };
|
||||
shipmentPlanFormRef.value?.resetFields();
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: ShipmentPlanVO[]) => {
|
||||
ids.value = selection.map((item) => item.id);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
};
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
reset();
|
||||
dialog.visible = true;
|
||||
dialog.title = '添加货件计划';
|
||||
};
|
||||
|
||||
const checkPrice = async () => {
|
||||
// form.value.fbaStatus = 'send';
|
||||
//
|
||||
// const updateForm = ref({
|
||||
// id: currentFBAData.value.id,
|
||||
// fbaStatus: 'send'
|
||||
// });
|
||||
// await updateShipmentPlan(updateForm.value).finally(() => (buttonLoading.value = false));
|
||||
|
||||
console.log('checkPrice', currentDes.value, selectedChannel.value);
|
||||
//查询报价单
|
||||
console.log('sshipDate.value', shipDate.value);
|
||||
if (currentFBAData.value.channelId == null) {
|
||||
ElMessage({
|
||||
type: 'warning',
|
||||
message: '请先设置渠道!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const res = await queryLogisticsQuote(currentDes.value, currentFBAData.value.channelId, shipDate.value);
|
||||
console.log('查询报价单', res);
|
||||
if (res.total == 0) {
|
||||
// //查询询价单
|
||||
// const requestQuote = await queryWithDesAndChannel(currentDes.value, currentFBAData.value.channelId, shipDate.value);
|
||||
// console.log('查询询价单', requestQuote);
|
||||
// if (requestQuote.total == 0) {
|
||||
// console.log('询价单也没数据');
|
||||
// channelDialogVisible.value = false;
|
||||
// ElMessageBox.confirm('未查询到价格信息,是否要向物流商发布询价?', '提醒', {
|
||||
// confirmButtonText: '确定',
|
||||
// cancelButtonText: '取消',
|
||||
// type: 'warning'
|
||||
// })
|
||||
// .then(async () => {
|
||||
// const res2 = await createWithDesAndChannel(currentDes.value, currentFBAData.value.channelId, shipDate.value);
|
||||
// console.log('checkPriceEnd2', res2);
|
||||
// if (res2.code == 200) {
|
||||
// ElMessage({
|
||||
// type: 'success',
|
||||
// message: '询价单创建成功'
|
||||
// });
|
||||
// }
|
||||
// })
|
||||
// .catch(() => {
|
||||
// // ElMessage({
|
||||
// // type: 'info',
|
||||
// // message: 'Delete canceled'
|
||||
// // });
|
||||
// });
|
||||
// } else {
|
||||
// //显示询价单
|
||||
// // channelDialogVisible.value = false;
|
||||
// // dialogTableVisible.value = true;
|
||||
// // tableData.value = requestQuote.rows;
|
||||
// // console.log('requestQuote.rows', requestQuote.rows);
|
||||
// // console.log('tableData', tableData.value);
|
||||
// ElMessage.success('已经有人询价了');
|
||||
// }
|
||||
ElMessage.warning('暂时没有物流商报价');
|
||||
} else {
|
||||
//显示报价单
|
||||
// ElMessage.success('已经有人报价了');
|
||||
|
||||
channelDialogVisible.value = false;
|
||||
drawer.value = true;
|
||||
logisticsQuoteList.value = res.rows;
|
||||
}
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: ShipmentPlanVO) => {
|
||||
reset();
|
||||
const _id = row?.id || ids.value[0];
|
||||
const res = await getShipmentPlan(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
dialog.visible = true;
|
||||
dialog.title = '修改货件计划';
|
||||
};
|
||||
|
||||
const handleSend = async (row?: ShipmentPlanVO) => {
|
||||
// reset();
|
||||
// channelDialogVisible.value = true;
|
||||
console.log(row);
|
||||
currentFBAData.value = row;
|
||||
currentDes.value = row.destination;
|
||||
checkPrice();
|
||||
};
|
||||
|
||||
|
||||
const showPop = async (row: any) => {
|
||||
console.log('row', row);
|
||||
};
|
||||
|
||||
const snycTodayPlan = async () => {
|
||||
const res = await takeTodayAmzPlanData();
|
||||
if (res.code == 200) {
|
||||
proxy?.$modal.msgSuccess('同步成功');
|
||||
await getList();
|
||||
}
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
console.log('selectedChannel', selectedChannel);
|
||||
console.log('groupedChannels', groupedChannels);
|
||||
|
||||
// console.log('channelCascaderRef', channelCascaderRef);
|
||||
console.log('label====', channelCascaderRef.value.getCheckedNodes()[0].label);
|
||||
form.value.channelName = channelCascaderRef.value.getCheckedNodes()[0].label;
|
||||
form.value.channelId = selectedChannel;
|
||||
const updateForm = ref({
|
||||
id: form.value.id,
|
||||
boxQuantity: form.value.boxQuantity,
|
||||
boxSize: form.value.boxSize,
|
||||
vendorWeight: form.value.vendorWeight,
|
||||
setTotal: form.value.setTotal,
|
||||
channelId: selectedChannel,
|
||||
channelName: channelCascaderRef.value.getCheckedNodes()[0].label
|
||||
});
|
||||
shipmentPlanFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
if (updateForm.value.id) {
|
||||
await updateShipmentPlan(updateForm.value).finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
await addShipmentPlan(updateForm.value).finally(() => (buttonLoading.value = false));
|
||||
}
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: ShipmentPlanVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除货件计划编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
|
||||
await delShipmentPlan(_ids);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
};
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download(
|
||||
'amz/shipmentPlan/export',
|
||||
{
|
||||
...queryParams.value
|
||||
},
|
||||
`shipmentPlan_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
};
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const addressTableData = ref([]);
|
||||
|
||||
const channelDialogVisible = ref(false);
|
||||
|
||||
// 转换对象为表格需要的数组格式
|
||||
const convertAddressToTableData = (address) => {
|
||||
return Object.entries(address).map(([key, value]) => ({
|
||||
key: key,
|
||||
value: value
|
||||
}));
|
||||
};
|
||||
|
||||
// 打开对话框
|
||||
const openAddressDialog = (address) => {
|
||||
addressTableData.value = convertAddressToTableData(address);
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
const currentRow = ref();
|
||||
const singleTableRef = ref<InstanceType<typeof ElTable>>();
|
||||
|
||||
const handleCurrentChange = (val: ShipmentPlanVO | undefined) => {
|
||||
currentRow.value = val;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
getAllChannelData();
|
||||
});
|
||||
</script>
|
@ -13,6 +13,42 @@
|
||||
<el-form-item label="物流单号" prop="trackingNumber">
|
||||
<el-input v-model="queryParams.trackingNumber" placeholder="请输入物流单号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="本地箱子编号" prop="localBoxId">
|
||||
<el-input v-model="queryParams.localBoxId" placeholder="请输入本地箱子编号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="包裹唯一标识" prop="packageId">
|
||||
<el-input v-model="queryParams.packageId" placeholder="请输入包裹唯一标识" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="总数量" prop="total">
|
||||
<el-input v-model="queryParams.total" placeholder="请输入总数量" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="重量" prop="weight">
|
||||
<el-input v-model="queryParams.weight" placeholder="请输入重量" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="重量单位" prop="weightUnit">
|
||||
<el-input v-model="queryParams.weightUnit" placeholder="请输入重量单位" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="长度" prop="length">
|
||||
<el-input v-model="queryParams.length" placeholder="请输入长度" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="宽度" prop="width">
|
||||
<el-input v-model="queryParams.width" placeholder="请输入宽度" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="高度" prop="height">
|
||||
<el-input v-model="queryParams.height" placeholder="请输入高度" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="尺寸单位" prop="lengthUnit">
|
||||
<el-input v-model="queryParams.lengthUnit" placeholder="请输入尺寸单位" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="箱子展示名称" prop="boxName">
|
||||
<el-input v-model="queryParams.boxName" placeholder="请输入箱子展示名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="货件唯一编号" prop="shipmentUniqueId">
|
||||
<el-input v-model="queryParams.shipmentUniqueId" placeholder="请输入货件唯一编号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="STA任务编号" prop="inboundPlanId">
|
||||
<el-input v-model="queryParams.inboundPlanId" placeholder="请输入STA任务编号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
@ -26,16 +62,20 @@
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['amz:shipmentTracking:add']">新增</el-button>
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['amz:shipmentTracking:add']"> 新增 </el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['amz:shipmentTracking:edit']">修改</el-button>
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['amz:shipmentTracking:edit']"
|
||||
>修改
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['amz:shipmentTracking:remove']">删除</el-button>
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['amz:shipmentTracking:remove']"
|
||||
>删除
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['amz:shipmentTracking:export']">导出</el-button>
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['amz:shipmentTracking:export']">导出 </el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
@ -46,6 +86,18 @@
|
||||
<el-table-column label="关联货件ID" align="center" prop="shipmentId" />
|
||||
<el-table-column label="箱号" align="center" prop="boxId" />
|
||||
<el-table-column label="物流单号" align="center" prop="trackingNumber" />
|
||||
<el-table-column label="本地箱子编号" align="center" prop="localBoxId" />
|
||||
<!-- <el-table-column label="包裹唯一标识" align="center" prop="packageId" />-->
|
||||
<el-table-column label="总数量" align="center" prop="total" />
|
||||
<el-table-column label="重量" align="center" prop="weight" />
|
||||
<el-table-column label="重量单位" align="center" prop="weightUnit" />
|
||||
<el-table-column label="长度" align="center" prop="length" />
|
||||
<el-table-column label="宽度" align="center" prop="width" />
|
||||
<el-table-column label="高度" align="center" prop="height" />
|
||||
<el-table-column label="尺寸单位" align="center" prop="lengthUnit" />
|
||||
<el-table-column label="箱子展示名称" align="center" prop="boxName" />
|
||||
<!-- <el-table-column label="货件唯一编号" align="center" prop="shipmentUniqueId" />-->
|
||||
<!-- <el-table-column label="STA任务编号" align="center" prop="inboundPlanId" />-->
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
@ -75,6 +127,42 @@
|
||||
<el-form-item label="物流单号" prop="trackingNumber">
|
||||
<el-input v-model="form.trackingNumber" placeholder="请输入物流单号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="本地箱子编号" prop="localBoxId">
|
||||
<el-input v-model="form.localBoxId" placeholder="请输入本地箱子编号" />
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="包裹唯一标识" prop="packageId">-->
|
||||
<!-- <el-input v-model="form.packageId" placeholder="请输入包裹唯一标识" />-->
|
||||
<!-- </el-form-item>-->
|
||||
<el-form-item label="总数量" prop="total">
|
||||
<el-input v-model="form.total" placeholder="请输入总数量" />
|
||||
</el-form-item>
|
||||
<el-form-item label="重量" prop="weight">
|
||||
<el-input v-model="form.weight" placeholder="请输入重量" />
|
||||
</el-form-item>
|
||||
<el-form-item label="重量单位" prop="weightUnit">
|
||||
<el-input v-model="form.weightUnit" placeholder="请输入重量单位" />
|
||||
</el-form-item>
|
||||
<el-form-item label="长度" prop="length">
|
||||
<el-input v-model="form.length" placeholder="请输入长度" />
|
||||
</el-form-item>
|
||||
<el-form-item label="宽度" prop="width">
|
||||
<el-input v-model="form.width" placeholder="请输入宽度" />
|
||||
</el-form-item>
|
||||
<el-form-item label="高度" prop="height">
|
||||
<el-input v-model="form.height" placeholder="请输入高度" />
|
||||
</el-form-item>
|
||||
<el-form-item label="尺寸单位" prop="lengthUnit">
|
||||
<el-input v-model="form.lengthUnit" placeholder="请输入尺寸单位" />
|
||||
</el-form-item>
|
||||
<el-form-item label="箱子展示名称" prop="boxName">
|
||||
<el-input v-model="form.boxName" placeholder="请输入箱子展示名称" />
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="货件唯一编号" prop="shipmentUniqueId">-->
|
||||
<!-- <el-input v-model="form.shipmentUniqueId" placeholder="请输入货件唯一编号" />-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="STA任务编号" prop="inboundPlanId">-->
|
||||
<!-- <el-input v-model="form.inboundPlanId" placeholder="请输入STA任务编号" />-->
|
||||
<!-- </el-form-item>-->
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
@ -87,7 +175,13 @@
|
||||
</template>
|
||||
|
||||
<script setup name="ShipmentTracking" lang="ts">
|
||||
import { listShipmentTracking, getShipmentTracking, delShipmentTracking, addShipmentTracking, updateShipmentTracking } from '@/api/amz/shipmentTracking';
|
||||
import {
|
||||
listShipmentTracking,
|
||||
getShipmentTracking,
|
||||
delShipmentTracking,
|
||||
addShipmentTracking,
|
||||
updateShipmentTracking
|
||||
} from '@/api/amz/shipmentTracking';
|
||||
import { ShipmentTrackingVO, ShipmentTrackingQuery, ShipmentTrackingForm } from '@/api/amz/shipmentTracking/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
@ -114,31 +208,58 @@ const initFormData: ShipmentTrackingForm = {
|
||||
shipmentId: undefined,
|
||||
boxId: undefined,
|
||||
trackingNumber: undefined,
|
||||
}
|
||||
localBoxId: undefined,
|
||||
packageId: undefined,
|
||||
total: undefined,
|
||||
weight: undefined,
|
||||
weightUnit: undefined,
|
||||
length: undefined,
|
||||
width: undefined,
|
||||
height: undefined,
|
||||
lengthUnit: undefined,
|
||||
boxName: undefined,
|
||||
shipmentUniqueId: undefined,
|
||||
inboundPlanId: undefined
|
||||
};
|
||||
const data = reactive<PageData<ShipmentTrackingForm, ShipmentTrackingQuery>>({
|
||||
form: {...initFormData},
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
shipmentId: undefined,
|
||||
boxId: undefined,
|
||||
trackingNumber: undefined,
|
||||
params: {
|
||||
}
|
||||
localBoxId: undefined,
|
||||
packageId: undefined,
|
||||
total: undefined,
|
||||
weight: undefined,
|
||||
weightUnit: undefined,
|
||||
length: undefined,
|
||||
width: undefined,
|
||||
height: undefined,
|
||||
lengthUnit: undefined,
|
||||
boxName: undefined,
|
||||
shipmentUniqueId: undefined,
|
||||
inboundPlanId: undefined,
|
||||
params: {}
|
||||
},
|
||||
rules: {
|
||||
id: [
|
||||
{ required: true, message: "主键ID不能为空", trigger: "blur" }
|
||||
],
|
||||
shipmentId: [
|
||||
{ required: true, message: "关联货件ID不能为空", trigger: "blur" }
|
||||
],
|
||||
boxId: [
|
||||
{ required: true, message: "箱号不能为空", trigger: "blur" }
|
||||
],
|
||||
trackingNumber: [
|
||||
{ required: true, message: "物流单号不能为空", trigger: "blur" }
|
||||
],
|
||||
id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }],
|
||||
shipmentId: [{ required: true, message: '关联货件ID不能为空', trigger: 'blur' }],
|
||||
boxId: [{ required: true, message: '箱号不能为空', trigger: 'blur' }],
|
||||
trackingNumber: [{ required: true, message: '物流单号不能为空', trigger: 'blur' }],
|
||||
localBoxId: [{ required: true, message: '本地箱子编号不能为空', trigger: 'blur' }],
|
||||
packageId: [{ required: true, message: '包裹唯一标识不能为空', trigger: 'blur' }],
|
||||
total: [{ required: true, message: '总数量不能为空', trigger: 'blur' }],
|
||||
weight: [{ required: true, message: '重量不能为空', trigger: 'blur' }],
|
||||
weightUnit: [{ required: true, message: '重量单位不能为空', trigger: 'blur' }],
|
||||
length: [{ required: true, message: '长度不能为空', trigger: 'blur' }],
|
||||
width: [{ required: true, message: '宽度不能为空', trigger: 'blur' }],
|
||||
height: [{ required: true, message: '高度不能为空', trigger: 'blur' }],
|
||||
lengthUnit: [{ required: true, message: '尺寸单位不能为空', trigger: 'blur' }],
|
||||
boxName: [{ required: true, message: '箱子展示名称不能为空', trigger: 'blur' }],
|
||||
shipmentUniqueId: [{ required: true, message: '货件唯一编号不能为空', trigger: 'blur' }],
|
||||
inboundPlanId: [{ required: true, message: 'STA任务编号不能为空', trigger: 'blur' }]
|
||||
}
|
||||
});
|
||||
|
||||
@ -151,55 +272,55 @@ const getList = async () => {
|
||||
shipmentTrackingList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
}
|
||||
};
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = {...initFormData};
|
||||
form.value = { ...initFormData };
|
||||
shipmentTrackingFormRef.value?.resetFields();
|
||||
}
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
};
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
};
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: ShipmentTrackingVO[]) => {
|
||||
ids.value = selection.map(item => item.id);
|
||||
ids.value = selection.map((item) => item.id);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
};
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
reset();
|
||||
dialog.visible = true;
|
||||
dialog.title = "添加物流追踪";
|
||||
}
|
||||
dialog.title = '添加物流追踪';
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: ShipmentTrackingVO) => {
|
||||
reset();
|
||||
const _id = row?.id || ids.value[0]
|
||||
const _id = row?.id || ids.value[0];
|
||||
const res = await getShipmentTracking(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
dialog.visible = true;
|
||||
dialog.title = "修改物流追踪";
|
||||
}
|
||||
dialog.title = '修改物流追踪';
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
@ -207,32 +328,36 @@ const submitForm = () => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
if (form.value.id) {
|
||||
await updateShipmentTracking(form.value).finally(() => buttonLoading.value = false);
|
||||
await updateShipmentTracking(form.value).finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
await addShipmentTracking(form.value).finally(() => buttonLoading.value = false);
|
||||
await addShipmentTracking(form.value).finally(() => (buttonLoading.value = false));
|
||||
}
|
||||
proxy?.$modal.msgSuccess("操作成功");
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: ShipmentTrackingVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除物流追踪编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
|
||||
await proxy?.$modal.confirm('是否确认删除物流追踪编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
|
||||
await delShipmentTracking(_ids);
|
||||
proxy?.$modal.msgSuccess("删除成功");
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
}
|
||||
};
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download('amz/shipmentTracking/export', {
|
||||
...queryParams.value
|
||||
}, `shipmentTracking_${new Date().getTime()}.xlsx`)
|
||||
}
|
||||
proxy?.download(
|
||||
'amz/shipmentTracking/export',
|
||||
{
|
||||
...queryParams.value
|
||||
},
|
||||
`shipmentTracking_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
|
@ -81,7 +81,10 @@
|
||||
</el-form>
|
||||
<!-- 底部 -->
|
||||
<div class="el-login-footer">
|
||||
<span>Copyright © 2005 瑷胜科技 All Rights Reserved.</span>
|
||||
<span
|
||||
>Copyright © 2005 瑷胜科技 <el-link type="primary" href="https://beian.miit.gov.cn/" target="_blank">粤ICP备2025398203号</el-link> All Rights
|
||||
Reserved.</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -275,7 +275,7 @@ const dialog = reactive<DialogOption>({
|
||||
const getList = () => {
|
||||
loading.value = true;
|
||||
listRole(proxy?.addDateRange(queryParams.value, dateRange.value)).then((res) => {
|
||||
roleList.value = res.rows;
|
||||
roleList.value = res.rows.filter(item => item.roleKey !== 'superadmin');
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
});
|
||||
|
@ -60,7 +60,7 @@
|
||||
<template #header>
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="1.5">
|
||||
<el-button v-has-permi="['system:user:add']" type="primary" plain icon="Plus" @click="handleAdd()">新增</el-button>
|
||||
<el-button v-has-permi="['system:user:add']" type="primary" plain icon="Plus" @click="handleAdd()"> 新增 </el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-has-permi="['system:user:edit']" type="success" plain :disabled="single" icon="Edit" @click="handleUpdate()">
|
||||
@ -76,13 +76,15 @@
|
||||
<el-dropdown class="mt-[1px]">
|
||||
<el-button plain type="info">
|
||||
更多
|
||||
<el-icon class="el-icon--right"><arrow-down /></el-icon
|
||||
></el-button>
|
||||
<el-icon class="el-icon--right">
|
||||
<arrow-down />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item icon="Download" @click="importTemplate">下载模板</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permi="['system:user:import']" icon="Top" @click="handleImport">导入数据</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permi="['system:user:export']" icon="Download" @click="handleExport">导出数据</el-dropdown-item>
|
||||
<el-dropdown-item v-has-permi="['system:user:import']" icon="Top" @click="handleImport">导入数据 </el-dropdown-item>
|
||||
<el-dropdown-item v-has-permi="['system:user:export']" icon="Download" @click="handleExport"> 导出数据 </el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
@ -199,7 +201,7 @@
|
||||
<el-col :span="12">
|
||||
<el-form-item label="状态">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio v-for="dict in sys_normal_disable" :key="dict.value" :value="dict.value">{{ dict.label }}</el-radio>
|
||||
<el-radio v-for="dict in sys_normal_disable" :key="dict.value" :value="dict.value">{{ dict.label }} </el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -268,9 +270,12 @@
|
||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
<template #tip>
|
||||
<div class="text-center el-upload__tip">
|
||||
<div class="el-upload__tip"><el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据</div>
|
||||
<div class="el-upload__tip">
|
||||
<el-checkbox v-model="upload.updateSupport" />
|
||||
是否更新已经存在的用户数据
|
||||
</div>
|
||||
<span>仅允许导入xls、xlsx格式文件。</span>
|
||||
<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="importTemplate">下载模板</el-link>
|
||||
<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="importTemplate">下载模板 </el-link>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
@ -287,7 +292,7 @@
|
||||
<script setup name="User" lang="ts">
|
||||
import api from '@/api/system/user';
|
||||
import { UserForm, UserQuery, UserVO } from '@/api/system/user/types';
|
||||
import {DeptTreeVO, DeptVO} from '@/api/system/dept/types';
|
||||
import { DeptTreeVO, DeptVO } from '@/api/system/dept/types';
|
||||
import { RoleVO } from '@/api/system/role/types';
|
||||
import { PostQuery, PostVO } from '@/api/system/post/types';
|
||||
import { treeselect } from '@/api/system/dept';
|
||||
@ -437,7 +442,7 @@ const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await api.listUser(proxy?.addDateRange(queryParams.value, dateRange.value));
|
||||
loading.value = false;
|
||||
userList.value = res.rows;
|
||||
userList.value = res.rows.filter((user) => user.userId !== 1);
|
||||
total.value = res.total;
|
||||
};
|
||||
|
||||
@ -450,7 +455,7 @@ const getDeptTree = async () => {
|
||||
|
||||
/** 过滤禁用的部门 */
|
||||
const filterDisabledDept = (deptList: DeptTreeVO[]) => {
|
||||
return deptList.filter(dept => {
|
||||
return deptList.filter((dept) => {
|
||||
if (dept.disabled) {
|
||||
return false;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ export default defineConfig(({ mode, command }: ConfigEnv): UserConfig => {
|
||||
open: true,
|
||||
proxy: {
|
||||
[env.VITE_APP_BASE_API]: {
|
||||
target: 'http://localhost:8080',
|
||||
target: env.VITE_BACKEND_URL,
|
||||
changeOrigin: true,
|
||||
ws: true,
|
||||
rewrite: (path) => path.replace(new RegExp('^' + env.VITE_APP_BASE_API), '')
|
||||
|
Loading…
x
Reference in New Issue
Block a user