feat: 积分商城-供应商-对账
This commit is contained in:
@@ -6,6 +6,7 @@ const suppliedServiceBaseUrl = String(process.env.SUPPLIED_SERVICE_BASE_URL || '
|
|||||||
const addressRoutes = new Map([
|
const addressRoutes = new Map([
|
||||||
['/supplierOpenApi/pointOrder/queryOrderInfo', '/supplierOpenApi/pointOrder/queryOrderInfo'],
|
['/supplierOpenApi/pointOrder/queryOrderInfo', '/supplierOpenApi/pointOrder/queryOrderInfo'],
|
||||||
['/supplierOpenApi/pointOrder/queryReconciliationInfo', '/supplierOpenApi/pointOrder/queryReconciliationInfo'],
|
['/supplierOpenApi/pointOrder/queryReconciliationInfo', '/supplierOpenApi/pointOrder/queryReconciliationInfo'],
|
||||||
|
['/supplierOpenApi/pointOrder/applyForInvoices', '/supplierOpenApi/pointOrder/applyForInvoices'],
|
||||||
['/supplierOpenApi/pointOrder/unReconciledMsg', '/supplierOpenApi/pointOrder/unReconciledMsg'],
|
['/supplierOpenApi/pointOrder/unReconciledMsg', '/supplierOpenApi/pointOrder/unReconciledMsg'],
|
||||||
['/supplierOpenApi/pointOrder/reconciliationResult', '/supplierOpenApi/pointOrder/reconciliationResult']
|
['/supplierOpenApi/pointOrder/reconciliationResult', '/supplierOpenApi/pointOrder/reconciliationResult']
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ const saveUser = data => {
|
|||||||
export const useUserStore = defineStore('joyfulSelectionUser', {
|
export const useUserStore = defineStore('joyfulSelectionUser', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
userId: '',
|
userId: '',
|
||||||
|
encryptedParam: '',
|
||||||
supplierIdentification: '',
|
supplierIdentification: '',
|
||||||
supplierId: '',
|
supplierId: '',
|
||||||
supplierName: '',
|
supplierName: '',
|
||||||
@@ -58,10 +59,11 @@ export const useUserStore = defineStore('joyfulSelectionUser', {
|
|||||||
this.loadUser()
|
this.loadUser()
|
||||||
}
|
}
|
||||||
|
|
||||||
const nextUserId = query.userId || ''
|
const encryptedParam = query.AplParmObjct || query.aplParmObjct || ''
|
||||||
|
|
||||||
if (nextUserId && nextUserId !== this.userId) {
|
if (encryptedParam) {
|
||||||
this.userId = nextUserId
|
this.encryptedParam = encryptedParam
|
||||||
|
this.userId = ''
|
||||||
this.pointsBalance = 0
|
this.pointsBalance = 0
|
||||||
}
|
}
|
||||||
if (!this.supplierIdentification) {
|
if (!this.supplierIdentification) {
|
||||||
@@ -90,7 +92,10 @@ export const useUserStore = defineStore('joyfulSelectionUser', {
|
|||||||
if (!this.loaded) {
|
if (!this.loaded) {
|
||||||
this.loadUser()
|
this.loadUser()
|
||||||
}
|
}
|
||||||
if (!this.userId || !this.supplierIdentification || this.hasToken) {
|
if (!this.supplierIdentification || (!this.encryptedParam && this.hasToken)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!this.encryptedParam) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (this.loadingToken && bridgeTokenPromise) {
|
if (this.loadingToken && bridgeTokenPromise) {
|
||||||
@@ -104,10 +109,12 @@ export const useUserStore = defineStore('joyfulSelectionUser', {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const data = await postFunction('supplier-token', {
|
const data = await postFunction('supplier-token', {
|
||||||
userId: this.userId,
|
AplParmObjct: this.encryptedParam,
|
||||||
supplierIdentification: this.supplierIdentification
|
supplierIdentification: this.supplierIdentification
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.userId = data?.userId || ''
|
||||||
|
this.encryptedParam = ''
|
||||||
this.supplierId = data?.supplierId || this.supplierId
|
this.supplierId = data?.supplierId || this.supplierId
|
||||||
this.supplierName = data?.supplierName || this.supplierName
|
this.supplierName = data?.supplierName || this.supplierName
|
||||||
this.persistUser()
|
this.persistUser()
|
||||||
|
|||||||
@@ -0,0 +1,551 @@
|
|||||||
|
/*
|
||||||
|
Navicat Premium Dump SQL
|
||||||
|
|
||||||
|
Source Server : localhost
|
||||||
|
Source Server Type : MySQL
|
||||||
|
Source Server Version : 80046 (8.0.46)
|
||||||
|
Source Host : 127.0.0.1:10086
|
||||||
|
Source Schema : supplier_db
|
||||||
|
|
||||||
|
Target Server Type : MySQL
|
||||||
|
Target Server Version : 80046 (8.0.46)
|
||||||
|
File Encoding : 65001
|
||||||
|
|
||||||
|
Date: 02/09/2026 11:08:42
|
||||||
|
*/
|
||||||
|
|
||||||
|
SET NAMES utf8mb4;
|
||||||
|
SET FOREIGN_KEY_CHECKS = 0;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for cartitem
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `cartitem`;
|
||||||
|
CREATE TABLE `cartitem` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT,
|
||||||
|
`userId` int NOT NULL,
|
||||||
|
`productId` int NOT NULL,
|
||||||
|
`skuText` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
|
||||||
|
`quantity` int NOT NULL DEFAULT 1,
|
||||||
|
`createdAt` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||||
|
`updatedAt` datetime(3) NOT NULL,
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
UNIQUE INDEX `CartItem_userId_productId_skuText_key`(`userId` ASC, `productId` ASC, `skuText` ASC) USING BTREE,
|
||||||
|
INDEX `CartItem_productId_fkey`(`productId` ASC) USING BTREE
|
||||||
|
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Records of cartitem
|
||||||
|
-- ----------------------------
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for supplier_after_sale
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `supplier_after_sale`;
|
||||||
|
CREATE TABLE `supplier_after_sale` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT COMMENT '供应商售后单主键ID',
|
||||||
|
`serviceOrderId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '售后业务单号',
|
||||||
|
`supplierId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '供应商ID',
|
||||||
|
`userId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '用户ID',
|
||||||
|
`mainOrderId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '关联主单ID',
|
||||||
|
`subOrderId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '关联子单ID',
|
||||||
|
`serviceType` int NOT NULL COMMENT '售后类型:4退货,5换货',
|
||||||
|
`serviceState` int NOT NULL DEFAULT 0 COMMENT '售后状态:0商家待审核,1审核通过,2审核拒绝,3用户已寄回,4商家已收货,5已完成,6已取消',
|
||||||
|
`auditStatus` int NOT NULL DEFAULT 0 COMMENT '审核状态:0待审核,1审核通过,2审核拒绝',
|
||||||
|
`logisticsState` int NOT NULL DEFAULT 0 COMMENT '物流状态:0无物流,1待用户寄回,2用户已寄回,3商家已收货,4商家已发货,5用户已收货',
|
||||||
|
`amount` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '售后金额',
|
||||||
|
`reason` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '售后原因',
|
||||||
|
`auditRemark` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '审核备注',
|
||||||
|
`userLogisticsNo` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '用户寄回物流单号',
|
||||||
|
`userLogisticsCompany` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '用户寄回物流公司',
|
||||||
|
`merchantLogisticsNo` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '商家换货物流单号',
|
||||||
|
`merchantLogisticsCompany` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '商家换货物流公司',
|
||||||
|
`applyTime` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '申请时间',
|
||||||
|
`auditTime` datetime(3) NULL DEFAULT NULL COMMENT '审核时间',
|
||||||
|
`userShipTime` datetime(3) NULL DEFAULT NULL COMMENT '用户寄回时间',
|
||||||
|
`merchantReceiveTime` datetime(3) NULL DEFAULT NULL COMMENT '商家收货时间',
|
||||||
|
`merchantShipTime` datetime(3) NULL DEFAULT NULL COMMENT '商家发货时间',
|
||||||
|
`finishTime` datetime(3) NULL DEFAULT NULL COMMENT '完成时间',
|
||||||
|
`requestBody` json NULL COMMENT '原始业务请求体',
|
||||||
|
`createTime` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||||
|
`updateTime` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
|
||||||
|
`deleted` int NOT NULL DEFAULT 0 COMMENT '删除状态:0未删除,1已删除',
|
||||||
|
`reasonType` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
|
||||||
|
`problemDescription` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL,
|
||||||
|
`pickupMethod` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
|
||||||
|
`pickupName` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
|
||||||
|
`pickupMobile` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
|
||||||
|
`pickupAddress` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL,
|
||||||
|
`images` json NULL,
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
UNIQUE INDEX `supplier_after_sale_serviceOrderId_key`(`serviceOrderId` ASC) USING BTREE,
|
||||||
|
INDEX `supplier_after_sale_supplierId_mainOrderId_idx`(`supplierId` ASC, `mainOrderId` ASC) USING BTREE,
|
||||||
|
INDEX `supplier_after_sale_supplierId_userId_idx`(`supplierId` ASC, `userId` ASC) USING BTREE,
|
||||||
|
INDEX `supplier_after_sale_subOrderId_idx`(`subOrderId` ASC) USING BTREE,
|
||||||
|
INDEX `supplier_after_sale_serviceType_serviceState_idx`(`serviceType` ASC, `serviceState` ASC) USING BTREE,
|
||||||
|
INDEX `supplier_after_sale_auditStatus_logisticsState_idx`(`auditStatus` ASC, `logisticsState` ASC) USING BTREE
|
||||||
|
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '供应商退款售后流程表' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Records of supplier_after_sale
|
||||||
|
-- ----------------------------
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for supplier_info
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `supplier_info`;
|
||||||
|
CREATE TABLE `supplier_info` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||||
|
`supplierIdentification` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '供应商唯一标识',
|
||||||
|
`supplierId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '供应商ID',
|
||||||
|
`supplierName` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '供应商名称',
|
||||||
|
`clientId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '平台分配的客户端ID',
|
||||||
|
`clientSecret` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '平台分配的客户端密钥',
|
||||||
|
`supplierApiUrl` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '供应商开放接口地址',
|
||||||
|
`sroNo` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT 'BAB7服务商编号',
|
||||||
|
`createTime` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||||
|
`updateTime` datetime(3) NOT NULL COMMENT '更新时间',
|
||||||
|
`creator` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '创建人',
|
||||||
|
`updator` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '更新人',
|
||||||
|
`version` int NOT NULL DEFAULT 0 COMMENT '版本号',
|
||||||
|
`deleted` int NOT NULL DEFAULT 0,
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
UNIQUE INDEX `supplier_info_supplierIdentification_key`(`supplierIdentification` ASC) USING BTREE,
|
||||||
|
UNIQUE INDEX `supplier_info_supplierId_key`(`supplierId` ASC) USING BTREE
|
||||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '供应商信息表' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Records of supplier_info
|
||||||
|
-- ----------------------------
|
||||||
|
INSERT INTO `supplier_info` VALUES (1, 'joyful-selection', '99999999', '悦享优选', 'pmall_5f8c2d91a7b34e3db1c9f4e6a8d2b7c1', 'pmsec_8d7f4c1a9b3e6f2d5c8a1e7b9f4d6c2a3b8e1f5d9c7a6b4e2f1a8c3d6b9e7f', NULL, NULL, '2026-07-28 15:16:35.000', '2026-07-28 15:16:35.000', 'system', 'system', 0, 0);
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for supplier_invoice_info
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `supplier_invoice_info`;
|
||||||
|
CREATE TABLE `supplier_invoice_info` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT COMMENT '发票信息主键ID',
|
||||||
|
`invoiceBizId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '发票业务唯一ID,优先使用发票号或事件订单号',
|
||||||
|
`supplierId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '供应商ID',
|
||||||
|
`userId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '用户ID',
|
||||||
|
`mainOrderId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '关联主单ID',
|
||||||
|
`subOrderId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '关联子单ID',
|
||||||
|
`settlementId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '结算单号',
|
||||||
|
`invoiceCode` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '发票代码或纳税识别号',
|
||||||
|
`invoiceIds` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '发票号码列表,多个用英文逗号分隔',
|
||||||
|
`orderIds` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '关联订单号列表,多个用英文逗号分隔',
|
||||||
|
`invoiceStatus` int NOT NULL DEFAULT 0 COMMENT '发票状态:0已记录,1已申请,2已开票,3失败',
|
||||||
|
`fileId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '发票文件ID',
|
||||||
|
`filePath` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '发票文件路径',
|
||||||
|
`requestBody` json NULL COMMENT '原始业务请求体',
|
||||||
|
`createTime` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||||
|
`updateTime` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
|
||||||
|
`deleted` int NOT NULL DEFAULT 0 COMMENT '删除状态:0未删除,1已删除',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
UNIQUE INDEX `supplier_invoice_info_invoiceBizId_key`(`invoiceBizId` ASC) USING BTREE,
|
||||||
|
INDEX `supplier_invoice_info_supplierId_mainOrderId_idx`(`supplierId` ASC, `mainOrderId` ASC) USING BTREE,
|
||||||
|
INDEX `supplier_invoice_info_settlementId_idx`(`settlementId` ASC) USING BTREE,
|
||||||
|
INDEX `supplier_invoice_info_invoiceCode_idx`(`invoiceCode` ASC) USING BTREE
|
||||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '供应商发票信息表' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Records of supplier_invoice_info
|
||||||
|
-- ----------------------------
|
||||||
|
INSERT INTO `supplier_invoice_info` VALUES (1, 'INV_ORD20260729134300_001', '99999999', '17a7f8ad3ee947b4a26175049a9c253d', 'ORD20260729134300', 'ORD20260729134300_001', NULL, NULL, 'INV_ORD20260729134300_001', 'ORD20260729134300_001', 2, NULL, NULL, '{\"time\": 1785303898394, \"amount\": 20.02, \"reason\": \"发票信息\", \"userId\": \"17a7f8ad3ee947b4a26175049a9c253d\", \"orderId\": \"ORD20260729134300_001\", \"orderIds\": \"ORD20260729134300_001\", \"orderType\": 11, \"invoiceIds\": \"INV_ORD20260729134300_001\", \"subOrderId\": \"ORD20260729134300_001\", \"supplierId\": \"99999999\", \"mainOrderId\": \"ORD20260729134300\", \"invoiceBizId\": \"INV_ORD20260729134300_001\"}', '2026-07-29 05:45:01.657', '2026-07-29 05:45:01.657', 0);
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for supplier_order_main
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `supplier_order_main`;
|
||||||
|
CREATE TABLE `supplier_order_main` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT,
|
||||||
|
`orderId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '主订单ID',
|
||||||
|
`orderNumberId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '主订单编号',
|
||||||
|
`supplierId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '供应商ID',
|
||||||
|
`userId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '平台用户ID',
|
||||||
|
`aplName` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '应用名称',
|
||||||
|
`addressId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '收货地址ID',
|
||||||
|
`remark` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '订单备注',
|
||||||
|
`createTime` datetime(3) NULL DEFAULT NULL COMMENT '订单创建时间',
|
||||||
|
`updateTime` datetime(3) NULL DEFAULT NULL COMMENT '订单更新时间',
|
||||||
|
`deliveryTime` datetime(3) NULL DEFAULT NULL COMMENT '发货时间',
|
||||||
|
`orderFinishTime` datetime(3) NULL DEFAULT NULL COMMENT '订单完成时间',
|
||||||
|
`completeTime` datetime(3) NULL DEFAULT NULL COMMENT '交易完成时间',
|
||||||
|
`deliveryStatus` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '配送状态',
|
||||||
|
`freightCost` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '运费积分金额',
|
||||||
|
`wPayOrAPayFreightCost` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '微信或支付宝支付运费金额',
|
||||||
|
`refund` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '积分退款金额',
|
||||||
|
`wPayOrAPayRefund` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '微信或支付宝退款金额',
|
||||||
|
`logisticsOrderId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '物流单号',
|
||||||
|
`crrgBsnNm` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '承运商名称',
|
||||||
|
`orderState` int NOT NULL DEFAULT 0 COMMENT '订单状态:0待付款,1待发货,2待收货,3已取消,4已完成兼容旧值,5已完成,6换货,7退货,8废除',
|
||||||
|
`isSplit` tinyint NOT NULL DEFAULT 0 COMMENT '主单是否拆单:0未拆单,1已拆单',
|
||||||
|
`splitTime` datetime(3) NULL DEFAULT NULL COMMENT '主单拆单时间',
|
||||||
|
`totalPrice` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '订单总金额',
|
||||||
|
`wPayOrAPay` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '微信或支付宝支付金额',
|
||||||
|
`pointsPrice` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '积分支付金额',
|
||||||
|
`invoiceCode` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '发票编码',
|
||||||
|
`createAt` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '记录创建时间',
|
||||||
|
`updateAt` datetime(3) NOT NULL COMMENT '记录更新时间',
|
||||||
|
`deleted` int NOT NULL DEFAULT 0 COMMENT '删除状态:0未删除,1已删除',
|
||||||
|
`payTime` datetime NULL DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
UNIQUE INDEX `supplier_order_main_orderId_key`(`orderId` ASC) USING BTREE
|
||||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '供应商主订单表' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Records of supplier_order_main
|
||||||
|
-- ----------------------------
|
||||||
|
INSERT INTO `supplier_order_main` VALUES (1, 'ORD20260901165221', 'TR20260901165221752', '99999999', 'c281e124321c8db3a14f0a7c86046c3c', '积分商城', 'addr-1788252731181', '', '2026-09-01 08:52:21.752', '2026-09-01 08:55:56.487', '2026-09-01 08:55:23.144', NULL, '2026-09-01 08:55:56.487', '1', 0.00, 0.00, 0.00, 0.00, '20260901', '韵达快递', 5, 1, '2026-09-01 08:52:25.891', 10.01, 0.00, 10.01, NULL, '2026-09-01 08:52:21.766', '2026-09-01 08:55:56.526', 0, '2026-09-01 08:52:26');
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for supplier_order_operate_log
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `supplier_order_operate_log`;
|
||||||
|
CREATE TABLE `supplier_order_operate_log` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT COMMENT '订单操作日志主键ID',
|
||||||
|
`supplierId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '供应商ID',
|
||||||
|
`userId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '用户ID',
|
||||||
|
`mainOrderId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '主单ID',
|
||||||
|
`subOrderId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '子单ID',
|
||||||
|
`operateType` int NOT NULL COMMENT '操作类型:1创建待支付,2支付成功,3拆单,4取消主单,5取消子单,6取消已支付未拆单整单,7确认收货,8已完成,9退款,10换货,11废除子单,12发票信息',
|
||||||
|
`beforeState` int NULL DEFAULT NULL COMMENT '操作前订单状态',
|
||||||
|
`afterState` int NULL DEFAULT NULL COMMENT '操作后订单状态',
|
||||||
|
`beforeSplit` int NULL DEFAULT NULL COMMENT '操作前拆单状态:0未拆单,1已拆单',
|
||||||
|
`afterSplit` int NULL DEFAULT NULL COMMENT '操作后拆单状态:0未拆单,1已拆单',
|
||||||
|
`remark` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '操作备注',
|
||||||
|
`operator` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '操作人或系统标识',
|
||||||
|
`createTime` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||||
|
`deleted` int NOT NULL DEFAULT 0 COMMENT '删除状态:0未删除,1已删除',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
INDEX `supplier_order_operate_log_supplierId_mainOrderId_idx`(`supplierId` ASC, `mainOrderId` ASC) USING BTREE,
|
||||||
|
INDEX `supplier_order_operate_log_subOrderId_idx`(`subOrderId` ASC) USING BTREE,
|
||||||
|
INDEX `supplier_order_operate_log_operateType_idx`(`operateType` ASC) USING BTREE
|
||||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '供应商订单操作日志表' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Records of supplier_order_operate_log
|
||||||
|
-- ----------------------------
|
||||||
|
INSERT INTO `supplier_order_operate_log` VALUES (1, '99999999', 'c281e124321c8db3a14f0a7c86046c3c', 'ORD20260901165221', 'ORD20260901165221_001', 7, 1, 2, NULL, NULL, NULL, 'api', '2026-09-01 08:55:23.165', 0);
|
||||||
|
INSERT INTO `supplier_order_operate_log` VALUES (2, '99999999', 'c281e124321c8db3a14f0a7c86046c3c', 'ORD20260901165221', 'ORD20260901165221_001', 8, 2, 5, NULL, NULL, '确认收货', 'system', '2026-09-01 08:55:56.515', 0);
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for supplier_order_product
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `supplier_order_product`;
|
||||||
|
CREATE TABLE `supplier_order_product` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT,
|
||||||
|
`subOrderId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '所属子订单ID',
|
||||||
|
`sku` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '商品SKU编码',
|
||||||
|
`number` int NOT NULL COMMENT '商品购买数量',
|
||||||
|
`price` decimal(10, 2) NOT NULL COMMENT '商品成交单价',
|
||||||
|
`name` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '商品名称快照',
|
||||||
|
`taxRate` decimal(5, 4) NOT NULL DEFAULT 0.1300 COMMENT '商品税率快照',
|
||||||
|
`productImgUrl` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '商品图片地址',
|
||||||
|
`fileId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '平台文件ID或图片ID',
|
||||||
|
`filePath` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '文件存储路径',
|
||||||
|
`picInfo` json NULL COMMENT '商品图片列表快照,JSON数组',
|
||||||
|
`createAt` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '记录创建时间',
|
||||||
|
`updateAt` datetime(3) NOT NULL COMMENT '记录更新时间',
|
||||||
|
`deleted` int NOT NULL DEFAULT 0 COMMENT '删除状态:0未删除,1已删除',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
INDEX `supplier_order_product_subOrderId_idx`(`subOrderId` ASC) USING BTREE
|
||||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '供应商子订单商品表' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Records of supplier_order_product
|
||||||
|
-- ----------------------------
|
||||||
|
INSERT INTO `supplier_order_product` VALUES (1, 'ORD20260901165221_001', '2-cream-standard', 1, 10.01, '手机壳', 0.1300, 'https://ts3.tc.mm.bing.net/th/id/OIP-C.MkmCbLoY2S4zqzMeHvCDMQHaHD?w=128&h=108&c=7&qlt=90&bgcl=f61537&r=0&o=6&dpr=1.3&pid=13.1', 'https://ts3.tc.mm.bing.net/th/id/OIP-C.MkmCbLoY2S4zqzMeHvCDMQHaHD?w=128&h=108&c=7&qlt=90&bgcl=f61537&r=0&o=6&dpr=1.3&pid=13.1', 'https://ts3.tc.mm.bing.net/th/id/OIP-C.MkmCbLoY2S4zqzMeHvCDMQHaHD?w=128&h=108&c=7&qlt=90&bgcl=f61537&r=0&o=6&dpr=1.3&pid=13.1', '[\"https://ts3.tc.mm.bing.net/th/id/OIP-C.MkmCbLoY2S4zqzMeHvCDMQHaHD?w=128&h=108&c=7&qlt=90&bgcl=f61537&r=0&o=6&dpr=1.3&pid=13.1\"]', '2026-09-01 08:52:21.780', '2026-09-01 08:52:21.780', 0);
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for supplier_order_push_log
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `supplier_order_push_log`;
|
||||||
|
CREATE TABLE `supplier_order_push_log` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT COMMENT '订单推送日志主键ID',
|
||||||
|
`supplierId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '供应商ID',
|
||||||
|
`userId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '用户ID',
|
||||||
|
`mainOrderId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '主单ID',
|
||||||
|
`orderId` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '推送订单ID,多个子单用英文逗号分隔',
|
||||||
|
`orderType` int NULL DEFAULT NULL COMMENT '推送事件类型:1取消主单,2拆单子单,3取消子单,7取消已支付未拆单整单',
|
||||||
|
`apiPath` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '推送接口路径',
|
||||||
|
`requestBody` json NULL COMMENT '推送请求体',
|
||||||
|
`responseBody` json NULL COMMENT '推送响应体',
|
||||||
|
`httpStatus` int NULL DEFAULT NULL COMMENT 'HTTP状态码',
|
||||||
|
`resultCode` int NULL DEFAULT NULL COMMENT '远程业务返回码',
|
||||||
|
`pushStatus` int NOT NULL DEFAULT 0 COMMENT '推送状态:0待推送,1推送成功,2推送失败',
|
||||||
|
`retryCount` int NOT NULL DEFAULT 0 COMMENT '重试次数',
|
||||||
|
`errorMessage` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '失败原因',
|
||||||
|
`lastPushTime` datetime(3) NULL DEFAULT NULL COMMENT '最后推送时间',
|
||||||
|
`nextRetryTime` datetime(3) NULL DEFAULT NULL COMMENT '下次重试时间',
|
||||||
|
`createTime` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||||
|
`updateTime` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
|
||||||
|
`deleted` int NOT NULL DEFAULT 0 COMMENT '删除状态:0未删除,1已删除',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
INDEX `supplier_order_push_log_supplierId_mainOrderId_idx`(`supplierId` ASC, `mainOrderId` ASC) USING BTREE,
|
||||||
|
INDEX `supplier_order_push_log_orderType_pushStatus_idx`(`orderType` ASC, `pushStatus` ASC) USING BTREE,
|
||||||
|
INDEX `supplier_order_push_log_nextRetryTime_idx`(`nextRetryTime` ASC) USING BTREE
|
||||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '供应商订单远程推送日志表' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Records of supplier_order_push_log
|
||||||
|
-- ----------------------------
|
||||||
|
INSERT INTO `supplier_order_push_log` VALUES (1, '99999999', 'c281e124321c8db3a14f0a7c86046c3c', 'ORD20260901165221', 'ORD20260901165221_001', 6, '/pointOrder/pushOrderInfoMsg', '{\"time\": 1788252956480, \"userId\": \"c281e124321c8db3a14f0a7c86046c3c\", \"orderId\": \"ORD20260901165221_001\", \"orderType\": 6, \"supplierId\": \"99999999\", \"mainOrderId\": \"ORD20260901165221\"}', '{\"message\": \"成功\", \"resultCode\": 0}', 200, 0, 1, 0, NULL, '2026-09-01 08:55:56.601', NULL, '2026-09-01 08:55:56.534', '2026-09-01 08:55:56.604', 0);
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for supplier_order_sub
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `supplier_order_sub`;
|
||||||
|
CREATE TABLE `supplier_order_sub` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT,
|
||||||
|
`orderId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '子订单ID',
|
||||||
|
`orderNumberId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '子订单编号',
|
||||||
|
`mainOrderId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '所属主订单ID',
|
||||||
|
`supplierId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '供应商ID',
|
||||||
|
`token` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '平台桥接访问令牌快照',
|
||||||
|
`userId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '平台用户ID',
|
||||||
|
`aplName` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '应用名称',
|
||||||
|
`addressId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '收货地址ID',
|
||||||
|
`remark` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '订单备注',
|
||||||
|
`createTime` datetime(3) NULL DEFAULT NULL COMMENT '订单创建时间',
|
||||||
|
`updateTime` datetime(3) NULL DEFAULT NULL COMMENT '订单更新时间',
|
||||||
|
`deliveryTime` datetime(3) NULL DEFAULT NULL COMMENT '发货时间',
|
||||||
|
`orderFinishTime` datetime(3) NULL DEFAULT NULL COMMENT '订单完成时间',
|
||||||
|
`completeTime` datetime(3) NULL DEFAULT NULL COMMENT '交易完成时间',
|
||||||
|
`deliveryStatus` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '配送状态',
|
||||||
|
`freightCost` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '运费积分金额',
|
||||||
|
`wPayOrAPayFreightCost` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '微信或支付宝支付运费金额',
|
||||||
|
`refund` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '积分退款金额',
|
||||||
|
`wPayOrAPayRefund` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '微信或支付宝退款金额',
|
||||||
|
`logisticsOrderId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '物流单号',
|
||||||
|
`crrgBsnNm` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '承运商名称',
|
||||||
|
`orderState` int NOT NULL DEFAULT 0 COMMENT '订单状态:0待付款,1待发货,2待收货,3已取消,4已完成兼容旧值,5已完成,6换货,7退货,8废除',
|
||||||
|
`totalPrice` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '子订单总金额',
|
||||||
|
`wPayOrAPay` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '微信或支付宝支付金额',
|
||||||
|
`pointsPrice` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '积分支付金额',
|
||||||
|
`invoiceCode` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '发票编码',
|
||||||
|
`createAt` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '记录创建时间',
|
||||||
|
`updateAt` datetime(3) NOT NULL COMMENT '记录更新时间',
|
||||||
|
`deleted` int NOT NULL DEFAULT 0 COMMENT '删除状态:0未删除,1已删除',
|
||||||
|
`payTime` datetime NULL DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
UNIQUE INDEX `supplier_order_sub_orderId_key`(`orderId` ASC) USING BTREE,
|
||||||
|
INDEX `supplier_order_sub_mainOrderId_idx`(`mainOrderId` ASC) USING BTREE
|
||||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '供应商子订单表' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Records of supplier_order_sub
|
||||||
|
-- ----------------------------
|
||||||
|
INSERT INTO `supplier_order_sub` VALUES (1, 'ORD20260901165221_001', 'TR20260901165221752_001', 'ORD20260901165221', '99999999', NULL, 'c281e124321c8db3a14f0a7c86046c3c', '积分商城', 'addr-1788252731181', '', '2026-09-01 08:52:21.752', '2026-09-01 08:55:56.487', '2026-09-01 08:55:23.144', '2026-09-01 08:55:56.487', '2026-09-01 08:55:56.487', '1', 0.00, 0.00, 0.00, 0.00, '20260901', '韵达快递', 5, 10.01, 0.00, 10.01, NULL, '2026-09-01 08:52:21.776', '2026-09-01 08:55:56.509', 0, '2026-09-01 08:52:26');
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for supplier_points_ledger
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `supplier_points_ledger`;
|
||||||
|
CREATE TABLE `supplier_points_ledger` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT COMMENT '积分流水主键ID',
|
||||||
|
`ledgerNo` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '流水号,业务唯一',
|
||||||
|
`supplierId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '供应商ID',
|
||||||
|
`userId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '用户ID',
|
||||||
|
`mainOrderId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '关联主单ID',
|
||||||
|
`subOrderId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '关联子单ID',
|
||||||
|
`bizType` int NOT NULL COMMENT '业务类型:1支付消费,2取消返还,3退货退款,4人工调整',
|
||||||
|
`direction` int NOT NULL COMMENT '流水方向:1增加,2扣减',
|
||||||
|
`points` decimal(10, 2) NOT NULL COMMENT '积分变动金额',
|
||||||
|
`beforePoints` decimal(10, 2) NULL DEFAULT NULL COMMENT '变动前积分余额',
|
||||||
|
`afterPoints` decimal(10, 2) NULL DEFAULT NULL COMMENT '变动后积分余额',
|
||||||
|
`remark` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '流水备注',
|
||||||
|
`createTime` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||||
|
`updateTime` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
|
||||||
|
`deleted` int NOT NULL DEFAULT 0 COMMENT '删除状态:0未删除,1已删除',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
UNIQUE INDEX `supplier_points_ledger_ledgerNo_key`(`ledgerNo` ASC) USING BTREE,
|
||||||
|
INDEX `supplier_points_ledger_supplierId_userId_idx`(`supplierId` ASC, `userId` ASC) USING BTREE,
|
||||||
|
INDEX `supplier_points_ledger_mainOrderId_idx`(`mainOrderId` ASC) USING BTREE,
|
||||||
|
INDEX `supplier_points_ledger_subOrderId_idx`(`subOrderId` ASC) USING BTREE
|
||||||
|
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '供应商用户积分消费流水表' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Records of supplier_points_ledger
|
||||||
|
-- ----------------------------
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for supplier_product
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `supplier_product`;
|
||||||
|
CREATE TABLE `supplier_product` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT COMMENT '商品主键ID',
|
||||||
|
`sku` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '商品SKU编码',
|
||||||
|
`number` int NOT NULL DEFAULT 0 COMMENT '默认购买数量或导入数量',
|
||||||
|
`price` decimal(10, 2) NOT NULL COMMENT '商品销售价格',
|
||||||
|
`name` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '商品名称',
|
||||||
|
`taxRate` decimal(5, 4) NOT NULL DEFAULT 0.1300 COMMENT '商品税率',
|
||||||
|
`picInfo` json NULL COMMENT '商品图片列表,JSON数组',
|
||||||
|
`description` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '商品简短描述',
|
||||||
|
`detail` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '商品详情描述',
|
||||||
|
`originPrice` decimal(10, 2) NULL DEFAULT NULL COMMENT '商品原价',
|
||||||
|
`imageUrl` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '商品主图地址',
|
||||||
|
`categoryId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '商品分类ID',
|
||||||
|
`category` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '商品分类名称',
|
||||||
|
`tag` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '商品标签',
|
||||||
|
`sales` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '商品销量展示文案',
|
||||||
|
`stock` int NOT NULL DEFAULT 0 COMMENT '商品库存',
|
||||||
|
`sortOrder` int NOT NULL DEFAULT 0 COMMENT '排序值,越小越靠前',
|
||||||
|
`enabled` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否启用',
|
||||||
|
`deleted` int NOT NULL DEFAULT 0 COMMENT '删除状态:0未删除,1已删除',
|
||||||
|
`createdAt` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||||
|
`updatedAt` datetime(3) NOT NULL COMMENT '更新时间',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
UNIQUE INDEX `supplier_product_sku_key`(`sku` ASC) USING BTREE
|
||||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '供应商商品信息表' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Records of supplier_product
|
||||||
|
-- ----------------------------
|
||||||
|
INSERT INTO `supplier_product` VALUES (1, 'SKU001', 2, 149.99, '蓝牙耳机', 0.1300, '[\"https://ts3.tc.mm.bing.net/th/id/OIP-C.im_WvX9bWGyvagEZp4Pz0AHaGX?w=142&h=108&c=7&qlt=90&bgcl=a01e15&r=0&o=6&dpr=1.3&pid=13.1\", \"https://ts3.tc.mm.bing.net/th/id/OIP-C.MkmCbLoY2S4zqzMeHvCDMQHaHD?w=128&h=108&c=7&qlt=90&bgcl=f61537&r=0&o=6&dpr=1.3&pid=13.1\"]', '轻盈佩戴,稳定连接,通勤运动都好用', '轻盈佩戴,稳定连接,通勤运动都好用。精选品质商品,适合积分商城兑换和日常福利采购场景。', 199.99, 'https://ts3.tc.mm.bing.net/th/id/OIP-C.im_WvX9bWGyvagEZp4Pz0AHaGX?w=142&h=108&c=7&qlt=90&bgcl=a01e15&r=0&o=6&dpr=1.3&pid=13.1', 'digitalAppliance', '数码家电', '积分兑换', '1.2万件', 180, 1, 1, 0, '2026-07-28 09:43:03.406', '2026-07-28 09:43:03.406');
|
||||||
|
INSERT INTO `supplier_product` VALUES (2, 'SKU002', 1, 10.01, '手机壳', 0.1300, '[\"https://ts3.tc.mm.bing.net/th/id/OIP-C.MkmCbLoY2S4zqzMeHvCDMQHaHD?w=128&h=108&c=7&qlt=90&bgcl=f61537&r=0&o=6&dpr=1.3&pid=13.1\", \"https://ts2.tc.mm.bing.net/th/id/OIP-C.CKSBSB33LwT9qJD_Yhb1mwHaKk?w=132&h=108&c=7&qlt=90&bgcl=2e287d&r=0&o=6&dpr=1.3&pid=13.1\"]', '防滑耐磨,贴合机身,日常保护更安心', '防滑耐磨,贴合机身,日常保护更安心。精选品质商品,适合积分商城兑换和日常福利采购场景。', 19.90, 'https://ts3.tc.mm.bing.net/th/id/OIP-C.MkmCbLoY2S4zqzMeHvCDMQHaHD?w=128&h=108&c=7&qlt=90&bgcl=f61537&r=0&o=6&dpr=1.3&pid=13.1', 'digitalAppliance', '数码家电', '赠品', '5632件', 187, 2, 1, 0, '2026-07-28 09:43:03.427', '2026-07-28 09:43:03.427');
|
||||||
|
INSERT INTO `supplier_product` VALUES (3, 'SKU003', 1, 99.00, '智能音箱 Pro', 0.1300, '[\"https://ts2.tc.mm.bing.net/th/id/OIP-C.CKSBSB33LwT9qJD_Yhb1mwHaKk?w=132&h=108&c=7&qlt=90&bgcl=2e287d&r=0&o=6&dpr=1.3&pid=13.1\", \"https://tse1-mm.cn.bing.net/th/id/OIP-C.StrDRqennoZNbzSPZapKZwHaEJ?w=286&h=180&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3\"]', '语音唤醒,沉浸音效,适合卧室和书房', '语音唤醒,沉浸音效,适合卧室和书房。精选品质商品,适合积分商城兑换和日常福利采购场景。', 139.00, 'https://ts2.tc.mm.bing.net/th/id/OIP-C.CKSBSB33LwT9qJD_Yhb1mwHaKk?w=132&h=108&c=7&qlt=90&bgcl=2e287d&r=0&o=6&dpr=1.3&pid=13.1', 'digitalAppliance', '数码家电', '热门推荐', '2.1万件', 194, 3, 1, 0, '2026-07-28 09:43:03.431', '2026-07-28 09:43:03.431');
|
||||||
|
INSERT INTO `supplier_product` VALUES (4, 'SKU004', 1, 129.00, '奶油白迷你烤箱', 0.1300, '[\"https://tse1-mm.cn.bing.net/th/id/OIP-C.StrDRqennoZNbzSPZapKZwHaEJ?w=286&h=180&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3\", \"https://tse3-mm.cn.bing.net/th/id/OIP-C.ynSetSr3z884UC6sEp4yiwHaEJ?w=331&h=186&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3\"]', '小巧不占地,早餐烘焙好帮手', '小巧不占地,早餐烘焙好帮手。精选品质商品,适合积分商城兑换和日常福利采购场景。', 169.00, 'https://tse1-mm.cn.bing.net/th/id/OIP-C.StrDRqennoZNbzSPZapKZwHaEJ?w=286&h=180&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3', 'homeLiving', '居家生活', '新品上架', '1.2万件', 201, 4, 1, 0, '2026-07-28 09:43:03.435', '2026-07-28 09:43:03.435');
|
||||||
|
INSERT INTO `supplier_product` VALUES (5, 'SKU005', 1, 69.90, '北欧陶瓷餐具套装', 0.1300, '[\"https://tse3-mm.cn.bing.net/th/id/OIP-C.ynSetSr3z884UC6sEp4yiwHaEJ?w=331&h=186&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3\", \"https://ts3.tc.mm.bing.net/th/id/OIP-C.im_WvX9bWGyvagEZp4Pz0AHaGX?w=142&h=108&c=7&qlt=90&bgcl=a01e15&r=0&o=6&dpr=1.3&pid=13.1\"]', '简约釉色,日常用餐更有仪式感', '简约釉色,日常用餐更有仪式感。精选品质商品,适合积分商城兑换和日常福利采购场景。', 99.90, 'https://tse3-mm.cn.bing.net/th/id/OIP-C.ynSetSr3z884UC6sEp4yiwHaEJ?w=331&h=186&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3', 'homeLiving', '居家生活', '品质精选', '6453件', 208, 5, 1, 0, '2026-07-28 09:43:03.438', '2026-07-28 09:43:03.438');
|
||||||
|
INSERT INTO `supplier_product` VALUES (6, 'SKU006', 1, 179.00, '纯棉舒适四件套', 0.1300, '[\"https://ts3.tc.mm.bing.net/th/id/OIP-C.im_WvX9bWGyvagEZp4Pz0AHaGX?w=142&h=108&c=7&qlt=90&bgcl=a01e15&r=0&o=6&dpr=1.3&pid=13.1\", \"https://ts3.tc.mm.bing.net/th/id/OIP-C.MkmCbLoY2S4zqzMeHvCDMQHaHD?w=128&h=108&c=7&qlt=90&bgcl=f61537&r=0&o=6&dpr=1.3&pid=13.1\"]', '柔软亲肤,安心睡眠,四季可用', '柔软亲肤,安心睡眠,四季可用。精选品质商品,适合积分商城兑换和日常福利采购场景。', 229.00, 'https://ts3.tc.mm.bing.net/th/id/OIP-C.im_WvX9bWGyvagEZp4Pz0AHaGX?w=142&h=108&c=7&qlt=90&bgcl=a01e15&r=0&o=6&dpr=1.3&pid=13.1', 'homeLiving', '居家生活', '积分兑换', '8321件', 215, 6, 1, 0, '2026-07-28 09:43:03.441', '2026-07-28 09:43:03.441');
|
||||||
|
INSERT INTO `supplier_product` VALUES (7, 'SKU007', 1, 99.90, '植萃保湿护肤礼盒', 0.1300, '[\"https://ts3.tc.mm.bing.net/th/id/OIP-C.MkmCbLoY2S4zqzMeHvCDMQHaHD?w=128&h=108&c=7&qlt=90&bgcl=f61537&r=0&o=6&dpr=1.3&pid=13.1\", \"https://ts2.tc.mm.bing.net/th/id/OIP-C.CKSBSB33LwT9qJD_Yhb1mwHaKk?w=132&h=108&c=7&qlt=90&bgcl=2e287d&r=0&o=6&dpr=1.3&pid=13.1\"]', '补水保湿,清爽不黏腻', '补水保湿,清爽不黏腻。精选品质商品,适合积分商城兑换和日常福利采购场景。', 139.90, 'https://ts3.tc.mm.bing.net/th/id/OIP-C.MkmCbLoY2S4zqzMeHvCDMQHaHD?w=128&h=108&c=7&qlt=90&bgcl=f61537&r=0&o=6&dpr=1.3&pid=13.1', 'beautyCare', '美妆个护', '礼盒精选', '4820件', 222, 7, 1, 0, '2026-07-28 09:43:03.443', '2026-07-28 09:43:03.443');
|
||||||
|
INSERT INTO `supplier_product` VALUES (8, 'SKU008', 1, 59.90, '香氛洗护旅行套装', 0.1300, '[\"https://ts2.tc.mm.bing.net/th/id/OIP-C.CKSBSB33LwT9qJD_Yhb1mwHaKk?w=132&h=108&c=7&qlt=90&bgcl=2e287d&r=0&o=6&dpr=1.3&pid=13.1\", \"https://tse1-mm.cn.bing.net/th/id/OIP-C.StrDRqennoZNbzSPZapKZwHaEJ?w=286&h=180&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3\"]', '温和清洁,清新留香,出行便携', '温和清洁,清新留香,出行便携。精选品质商品,适合积分商城兑换和日常福利采购场景。', 89.90, 'https://ts2.tc.mm.bing.net/th/id/OIP-C.CKSBSB33LwT9qJD_Yhb1mwHaKk?w=132&h=108&c=7&qlt=90&bgcl=2e287d&r=0&o=6&dpr=1.3&pid=13.1', 'beautyCare', '美妆个护', '新品上架', '7932件', 229, 8, 1, 0, '2026-07-28 09:43:03.446', '2026-07-28 09:43:03.446');
|
||||||
|
INSERT INTO `supplier_product` VALUES (9, 'SKU009', 1, 49.90, '便携补光化妆镜', 0.1300, '[\"https://tse1-mm.cn.bing.net/th/id/OIP-C.StrDRqennoZNbzSPZapKZwHaEJ?w=286&h=180&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3\", \"https://tse3-mm.cn.bing.net/th/id/OIP-C.ynSetSr3z884UC6sEp4yiwHaEJ?w=331&h=186&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3\"]', '高清镜面,柔光补妆,随身携带', '高清镜面,柔光补妆,随身携带。精选品质商品,适合积分商城兑换和日常福利采购场景。', 79.90, 'https://tse1-mm.cn.bing.net/th/id/OIP-C.StrDRqennoZNbzSPZapKZwHaEJ?w=286&h=180&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3', 'beautyCare', '美妆个护', '热门推荐', '3651件', 236, 9, 1, 0, '2026-07-28 09:43:03.450', '2026-07-28 09:43:03.450');
|
||||||
|
INSERT INTO `supplier_product` VALUES (10, 'SKU010', 1, 59.90, '橙意零食礼盒', 0.1300, '[\"https://tse3-mm.cn.bing.net/th/id/OIP-C.ynSetSr3z884UC6sEp4yiwHaEJ?w=331&h=186&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3\", \"https://ts3.tc.mm.bing.net/th/id/OIP-C.im_WvX9bWGyvagEZp4Pz0AHaGX?w=142&h=108&c=7&qlt=90&bgcl=a01e15&r=0&o=6&dpr=1.3&pid=13.1\"]', '精选零食组合,办公室分享刚刚好', '精选零食组合,办公室分享刚刚好。精选品质商品,适合积分商城兑换和日常福利采购场景。', 89.90, 'https://tse3-mm.cn.bing.net/th/id/OIP-C.ynSetSr3z884UC6sEp4yiwHaEJ?w=331&h=186&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3', 'foodDrink', '食品饮料', '礼盒精选', '6324件', 243, 10, 1, 0, '2026-07-28 09:43:03.453', '2026-07-28 09:43:03.453');
|
||||||
|
INSERT INTO `supplier_product` VALUES (11, 'SKU011', 1, 49.90, '咖啡随行杯组合', 0.1300, '[\"https://ts3.tc.mm.bing.net/th/id/OIP-C.im_WvX9bWGyvagEZp4Pz0AHaGX?w=142&h=108&c=7&qlt=90&bgcl=a01e15&r=0&o=6&dpr=1.3&pid=13.1\", \"https://ts3.tc.mm.bing.net/th/id/OIP-C.MkmCbLoY2S4zqzMeHvCDMQHaHD?w=128&h=108&c=7&qlt=90&bgcl=f61537&r=0&o=6&dpr=1.3&pid=13.1\"]', '锁温防漏,通勤随行更方便', '锁温防漏,通勤随行更方便。精选品质商品,适合积分商城兑换和日常福利采购场景。', 69.90, 'https://ts3.tc.mm.bing.net/th/id/OIP-C.im_WvX9bWGyvagEZp4Pz0AHaGX?w=142&h=108&c=7&qlt=90&bgcl=a01e15&r=0&o=6&dpr=1.3&pid=13.1', 'foodDrink', '食品饮料', '积分兑换', '3520件', 250, 11, 1, 0, '2026-07-28 09:43:03.456', '2026-07-28 09:43:03.456');
|
||||||
|
INSERT INTO `supplier_product` VALUES (12, 'SKU012', 1, 69.90, '下午茶点心礼盒', 0.1300, '[\"https://ts3.tc.mm.bing.net/th/id/OIP-C.MkmCbLoY2S4zqzMeHvCDMQHaHD?w=128&h=108&c=7&qlt=90&bgcl=f61537&r=0&o=6&dpr=1.3&pid=13.1\", \"https://ts2.tc.mm.bing.net/th/id/OIP-C.CKSBSB33LwT9qJD_Yhb1mwHaKk?w=132&h=108&c=7&qlt=90&bgcl=2e287d&r=0&o=6&dpr=1.3&pid=13.1\"]', '多种风味,一盒满足甜咸口味', '多种风味,一盒满足甜咸口味。精选品质商品,适合积分商城兑换和日常福利采购场景。', 99.90, 'https://ts3.tc.mm.bing.net/th/id/OIP-C.MkmCbLoY2S4zqzMeHvCDMQHaHD?w=128&h=108&c=7&qlt=90&bgcl=f61537&r=0&o=6&dpr=1.3&pid=13.1', 'foodDrink', '食品饮料', '品质精选', '4891件', 257, 12, 1, 0, '2026-07-28 09:43:03.459', '2026-07-28 09:43:03.459');
|
||||||
|
INSERT INTO `supplier_product` VALUES (13, 'SKU013', 1, 39.90, '安心儿童水杯', 0.1300, '[\"https://ts2.tc.mm.bing.net/th/id/OIP-C.CKSBSB33LwT9qJD_Yhb1mwHaKk?w=132&h=108&c=7&qlt=90&bgcl=2e287d&r=0&o=6&dpr=1.3&pid=13.1\", \"https://tse1-mm.cn.bing.net/th/id/OIP-C.StrDRqennoZNbzSPZapKZwHaEJ?w=286&h=180&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3\"]', '轻巧易握,防摔耐用,出门好携带', '轻巧易握,防摔耐用,出门好携带。精选品质商品,适合积分商城兑换和日常福利采购场景。', 59.90, 'https://ts2.tc.mm.bing.net/th/id/OIP-C.CKSBSB33LwT9qJD_Yhb1mwHaKk?w=132&h=108&c=7&qlt=90&bgcl=2e287d&r=0&o=6&dpr=1.3&pid=13.1', 'motherBaby', '母婴玩具', '新品上架', '4250件', 264, 13, 1, 0, '2026-07-28 09:43:03.462', '2026-07-28 09:43:03.462');
|
||||||
|
INSERT INTO `supplier_product` VALUES (14, 'SKU014', 1, 89.00, '益智积木套装', 0.1300, '[\"https://tse1-mm.cn.bing.net/th/id/OIP-C.StrDRqennoZNbzSPZapKZwHaEJ?w=286&h=180&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3\", \"https://tse3-mm.cn.bing.net/th/id/OIP-C.ynSetSr3z884UC6sEp4yiwHaEJ?w=331&h=186&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3\"]', '色彩柔和,锻炼动手能力', '色彩柔和,锻炼动手能力。精选品质商品,适合积分商城兑换和日常福利采购场景。', 129.00, 'https://tse1-mm.cn.bing.net/th/id/OIP-C.StrDRqennoZNbzSPZapKZwHaEJ?w=286&h=180&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3', 'motherBaby', '母婴玩具', '热门推荐', '2186件', 271, 14, 1, 0, '2026-07-28 09:43:03.465', '2026-07-28 09:43:03.465');
|
||||||
|
INSERT INTO `supplier_product` VALUES (15, 'SKU015', 1, 69.90, '柔光儿童夜灯', 0.1300, '[\"https://tse3-mm.cn.bing.net/th/id/OIP-C.ynSetSr3z884UC6sEp4yiwHaEJ?w=331&h=186&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3\", \"https://ts3.tc.mm.bing.net/th/id/OIP-C.im_WvX9bWGyvagEZp4Pz0AHaGX?w=142&h=108&c=7&qlt=90&bgcl=a01e15&r=0&o=6&dpr=1.3&pid=13.1\"]', '温和光线,陪伴睡前时光', '温和光线,陪伴睡前时光。精选品质商品,适合积分商城兑换和日常福利采购场景。', 99.90, 'https://tse3-mm.cn.bing.net/th/id/OIP-C.ynSetSr3z884UC6sEp4yiwHaEJ?w=331&h=186&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3', 'motherBaby', '母婴玩具', '品质精选', '3548件', 278, 15, 1, 0, '2026-07-28 09:43:03.469', '2026-07-28 09:43:03.469');
|
||||||
|
INSERT INTO `supplier_product` VALUES (16, 'SKU016', 1, 149.00, '大容量电脑背包', 0.1300, '[\"https://ts3.tc.mm.bing.net/th/id/OIP-C.im_WvX9bWGyvagEZp4Pz0AHaGX?w=142&h=108&c=7&qlt=90&bgcl=a01e15&r=0&o=6&dpr=1.3&pid=13.1\", \"https://ts3.tc.mm.bing.net/th/id/OIP-C.MkmCbLoY2S4zqzMeHvCDMQHaHD?w=128&h=108&c=7&qlt=90&bgcl=f61537&r=0&o=6&dpr=1.3&pid=13.1\"]', '分区收纳,通勤出行更轻松', '分区收纳,通勤出行更轻松。精选品质商品,适合积分商城兑换和日常福利采购场景。', 199.00, 'https://ts3.tc.mm.bing.net/th/id/OIP-C.im_WvX9bWGyvagEZp4Pz0AHaGX?w=142&h=108&c=7&qlt=90&bgcl=a01e15&r=0&o=6&dpr=1.3&pid=13.1', 'fashionBag', '服饰鞋包', '积分兑换', '1.6万件', 285, 16, 1, 0, '2026-07-28 09:43:03.472', '2026-07-28 09:43:03.472');
|
||||||
|
INSERT INTO `supplier_product` VALUES (17, 'SKU017', 1, 79.90, '轻巧通勤斜挎包', 0.1300, '[\"https://ts3.tc.mm.bing.net/th/id/OIP-C.MkmCbLoY2S4zqzMeHvCDMQHaHD?w=128&h=108&c=7&qlt=90&bgcl=f61537&r=0&o=6&dpr=1.3&pid=13.1\", \"https://ts2.tc.mm.bing.net/th/id/OIP-C.CKSBSB33LwT9qJD_Yhb1mwHaKk?w=132&h=108&c=7&qlt=90&bgcl=2e287d&r=0&o=6&dpr=1.3&pid=13.1\"]', '简洁百搭,日常出门更实用', '简洁百搭,日常出门更实用。精选品质商品,适合积分商城兑换和日常福利采购场景。', 109.90, 'https://ts3.tc.mm.bing.net/th/id/OIP-C.MkmCbLoY2S4zqzMeHvCDMQHaHD?w=128&h=108&c=7&qlt=90&bgcl=f61537&r=0&o=6&dpr=1.3&pid=13.1', 'fashionBag', '服饰鞋包', '新品上架', '5321件', 292, 17, 1, 0, '2026-07-28 09:43:03.475', '2026-07-28 09:43:03.475');
|
||||||
|
INSERT INTO `supplier_product` VALUES (18, 'SKU018', 1, 69.90, '柔软撞色丝巾礼盒', 0.1300, '[\"https://ts2.tc.mm.bing.net/th/id/OIP-C.CKSBSB33LwT9qJD_Yhb1mwHaKk?w=132&h=108&c=7&qlt=90&bgcl=2e287d&r=0&o=6&dpr=1.3&pid=13.1\", \"https://tse1-mm.cn.bing.net/th/id/OIP-C.StrDRqennoZNbzSPZapKZwHaEJ?w=286&h=180&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3\"]', '细腻亲肤,点亮日常穿搭', '细腻亲肤,点亮日常穿搭。精选品质商品,适合积分商城兑换和日常福利采购场景。', 99.90, 'https://ts2.tc.mm.bing.net/th/id/OIP-C.CKSBSB33LwT9qJD_Yhb1mwHaKk?w=132&h=108&c=7&qlt=90&bgcl=2e287d&r=0&o=6&dpr=1.3&pid=13.1', 'fashionBag', '服饰鞋包', '礼盒精选', '2680件', 299, 18, 1, 0, '2026-07-28 09:43:03.479', '2026-07-28 09:43:03.479');
|
||||||
|
INSERT INTO `supplier_product` VALUES (19, 'SKU019', 1, 49.90, '运动保温水杯', 0.1300, '[\"https://tse1-mm.cn.bing.net/th/id/OIP-C.StrDRqennoZNbzSPZapKZwHaEJ?w=286&h=180&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3\", \"https://tse3-mm.cn.bing.net/th/id/OIP-C.ynSetSr3z884UC6sEp4yiwHaEJ?w=331&h=186&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3\"]', '长效锁温,户外运动随行', '长效锁温,户外运动随行。精选品质商品,适合积分商城兑换和日常福利采购场景。', 79.90, 'https://tse1-mm.cn.bing.net/th/id/OIP-C.StrDRqennoZNbzSPZapKZwHaEJ?w=286&h=180&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3', 'sportsOutdoor', '运动户外', '热门推荐', '7342件', 306, 19, 1, 0, '2026-07-28 09:43:03.483', '2026-07-28 09:43:03.483');
|
||||||
|
INSERT INTO `supplier_product` VALUES (20, 'SKU020', 1, 99.00, '筋膜放松按摩仪 Mini', 0.1300, '[\"https://tse3-mm.cn.bing.net/th/id/OIP-C.ynSetSr3z884UC6sEp4yiwHaEJ?w=331&h=186&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3\", \"https://ts3.tc.mm.bing.net/th/id/OIP-C.im_WvX9bWGyvagEZp4Pz0AHaGX?w=142&h=108&c=7&qlt=90&bgcl=a01e15&r=0&o=6&dpr=1.3&pid=13.1\"]', '轻巧便携,缓解久坐酸胀', '轻巧便携,缓解久坐酸胀。精选品质商品,适合积分商城兑换和日常福利采购场景。', 149.00, 'https://tse3-mm.cn.bing.net/th/id/OIP-C.ynSetSr3z884UC6sEp4yiwHaEJ?w=331&h=186&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3', 'sportsOutdoor', '运动户外', '积分兑换', '3921件', 313, 20, 1, 0, '2026-07-28 09:43:03.486', '2026-07-28 09:43:03.486');
|
||||||
|
INSERT INTO `supplier_product` VALUES (21, 'SKU021', 1, 79.00, '户外露营灯', 0.1300, '[\"https://ts3.tc.mm.bing.net/th/id/OIP-C.im_WvX9bWGyvagEZp4Pz0AHaGX?w=142&h=108&c=7&qlt=90&bgcl=a01e15&r=0&o=6&dpr=1.3&pid=13.1\", \"https://ts3.tc.mm.bing.net/th/id/OIP-C.MkmCbLoY2S4zqzMeHvCDMQHaHD?w=128&h=108&c=7&qlt=90&bgcl=f61537&r=0&o=6&dpr=1.3&pid=13.1\"]', '多档照明,露营夜晚更安心', '多档照明,露营夜晚更安心。精选品质商品,适合积分商城兑换和日常福利采购场景。', 119.00, 'https://ts3.tc.mm.bing.net/th/id/OIP-C.im_WvX9bWGyvagEZp4Pz0AHaGX?w=142&h=108&c=7&qlt=90&bgcl=a01e15&r=0&o=6&dpr=1.3&pid=13.1', 'sportsOutdoor', '运动户外', '新品上架', '2568件', 320, 21, 1, 0, '2026-07-28 09:43:03.489', '2026-07-28 09:43:03.489');
|
||||||
|
INSERT INTO `supplier_product` VALUES (22, 'SKU022', 1, 59.90, '悦享精选礼包', 0.1300, '[\"https://ts3.tc.mm.bing.net/th/id/OIP-C.MkmCbLoY2S4zqzMeHvCDMQHaHD?w=128&h=108&c=7&qlt=90&bgcl=f61537&r=0&o=6&dpr=1.3&pid=13.1\", \"https://ts2.tc.mm.bing.net/th/id/OIP-C.CKSBSB33LwT9qJD_Yhb1mwHaKk?w=132&h=108&c=7&qlt=90&bgcl=2e287d&r=0&o=6&dpr=1.3&pid=13.1\"]', '多场景精选好物,福利兑换优选', '多场景精选好物,福利兑换优选。精选品质商品,适合积分商城兑换和日常福利采购场景。', 89.90, 'https://ts3.tc.mm.bing.net/th/id/OIP-C.MkmCbLoY2S4zqzMeHvCDMQHaHD?w=128&h=108&c=7&qlt=90&bgcl=f61537&r=0&o=6&dpr=1.3&pid=13.1', 'recommend', '精选推荐', '精选推荐', '8820件', 327, 22, 1, 0, '2026-07-28 09:43:03.492', '2026-07-28 09:43:03.492');
|
||||||
|
INSERT INTO `supplier_product` VALUES (23, 'SKU023', 1, 119.00, '品质生活组合装', 0.1300, '[\"https://ts2.tc.mm.bing.net/th/id/OIP-C.CKSBSB33LwT9qJD_Yhb1mwHaKk?w=132&h=108&c=7&qlt=90&bgcl=2e287d&r=0&o=6&dpr=1.3&pid=13.1\", \"https://tse1-mm.cn.bing.net/th/id/OIP-C.StrDRqennoZNbzSPZapKZwHaEJ?w=286&h=180&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3\"]', '居家、通勤、日用好物组合', '居家、通勤、日用好物组合。精选品质商品,适合积分商城兑换和日常福利采购场景。', 159.00, 'https://ts2.tc.mm.bing.net/th/id/OIP-C.CKSBSB33LwT9qJD_Yhb1mwHaKk?w=132&h=108&c=7&qlt=90&bgcl=2e287d&r=0&o=6&dpr=1.3&pid=13.1', 'recommend', '精选推荐', '热门推荐', '6902件', 334, 23, 1, 0, '2026-07-28 09:43:03.495', '2026-07-28 09:43:03.495');
|
||||||
|
INSERT INTO `supplier_product` VALUES (24, 'SKU024', 1, 39.90, '积分兑换惊喜盒', 0.1300, '[\"https://tse1-mm.cn.bing.net/th/id/OIP-C.StrDRqennoZNbzSPZapKZwHaEJ?w=286&h=180&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3\", \"https://tse3-mm.cn.bing.net/th/id/OIP-C.ynSetSr3z884UC6sEp4yiwHaEJ?w=331&h=186&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3\"]', '随机精选商品,兑换更有新鲜感', '随机精选商品,兑换更有新鲜感。精选品质商品,适合积分商城兑换和日常福利采购场景。', 69.90, 'https://tse1-mm.cn.bing.net/th/id/OIP-C.StrDRqennoZNbzSPZapKZwHaEJ?w=286&h=180&c=7&r=0&o=7&cb=thfc1falcon&dpr=1.3&pid=1.7&rm=3', 'recommend', '精选推荐', '限时秒杀', '5310件', 341, 24, 1, 0, '2026-07-28 09:43:03.498', '2026-07-28 09:43:03.498');
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for supplier_reconciliation_order
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `supplier_reconciliation_order`;
|
||||||
|
CREATE TABLE `supplier_reconciliation_order` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
|
`supplierId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '供应商ID',
|
||||||
|
`orderId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '子订单ID',
|
||||||
|
`mainOrderId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '主订单ID',
|
||||||
|
`userId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '用户ID',
|
||||||
|
`reconciliationStatus` tinyint NOT NULL DEFAULT 0 COMMENT '对账状态:0未对账,1对账成功,2对账异常',
|
||||||
|
`diffType` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '差异类型',
|
||||||
|
`diffReason` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '差异说明',
|
||||||
|
`platformTotalPrice` decimal(12, 2) NULL DEFAULT NULL COMMENT '平台订单总金额',
|
||||||
|
`platformCashAmount` decimal(12, 2) NULL DEFAULT NULL COMMENT '平台现金支付金额',
|
||||||
|
`platformPointsPrice` decimal(12, 2) NULL DEFAULT NULL COMMENT '平台积分支付金额',
|
||||||
|
`platformRefundPrice` decimal(12, 2) NULL DEFAULT NULL COMMENT '平台退款金额',
|
||||||
|
`supplierTotalPrice` decimal(12, 2) NULL DEFAULT NULL COMMENT '供应商订单总金额',
|
||||||
|
`supplierCashAmount` decimal(12, 2) NULL DEFAULT NULL COMMENT '供应商现金支付金额',
|
||||||
|
`supplierPointsPrice` decimal(12, 2) NULL DEFAULT NULL COMMENT '供应商积分支付金额',
|
||||||
|
`supplierRefundPrice` decimal(12, 2) NULL DEFAULT NULL COMMENT '供应商退款金额',
|
||||||
|
`reconciliationBatchNo` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '对账批次号',
|
||||||
|
`reconciliationTime` datetime(3) NULL DEFAULT NULL COMMENT '对账完成时间',
|
||||||
|
`resultPayload` json NULL COMMENT '对账回调原始结果',
|
||||||
|
`createAt` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||||
|
`updateAt` datetime(3) NOT NULL,
|
||||||
|
`deleted` int NOT NULL DEFAULT 0,
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
UNIQUE INDEX `uk_supplier_order`(`supplierId` ASC, `orderId` ASC) USING BTREE,
|
||||||
|
INDEX `idx_supplier_status`(`supplierId` ASC, `reconciliationStatus` ASC) USING BTREE,
|
||||||
|
INDEX `idx_batch_no`(`reconciliationBatchNo` ASC) USING BTREE,
|
||||||
|
INDEX `idx_main_order`(`mainOrderId` ASC) USING BTREE
|
||||||
|
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '供应商子订单对账结果表' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Records of supplier_reconciliation_order
|
||||||
|
-- ----------------------------
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for supplier_refund_exchange
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `supplier_refund_exchange`;
|
||||||
|
CREATE TABLE `supplier_refund_exchange` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT COMMENT '售后记录主键ID',
|
||||||
|
`serviceOrderId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '退货/换货业务单号',
|
||||||
|
`supplierId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '供应商ID',
|
||||||
|
`userId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '用户ID',
|
||||||
|
`mainOrderId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '关联主单ID',
|
||||||
|
`subOrderId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '关联子单ID',
|
||||||
|
`serviceType` int NOT NULL COMMENT '售后类型:4退货,5换货',
|
||||||
|
`serviceState` int NOT NULL DEFAULT 0 COMMENT '售后状态:0已创建,1处理中,2已完成,3已取消',
|
||||||
|
`amount` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '售后金额',
|
||||||
|
`reason` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '售后原因',
|
||||||
|
`requestBody` json NULL COMMENT '原始业务请求体',
|
||||||
|
`createTime` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||||
|
`updateTime` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
|
||||||
|
`deleted` int NOT NULL DEFAULT 0 COMMENT '删除状态:0未删除,1已删除',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
UNIQUE INDEX `supplier_refund_exchange_serviceOrderId_key`(`serviceOrderId` ASC) USING BTREE,
|
||||||
|
INDEX `supplier_refund_exchange_supplierId_mainOrderId_idx`(`supplierId` ASC, `mainOrderId` ASC) USING BTREE,
|
||||||
|
INDEX `supplier_refund_exchange_subOrderId_idx`(`subOrderId` ASC) USING BTREE,
|
||||||
|
INDEX `supplier_refund_exchange_serviceType_serviceState_idx`(`serviceType` ASC, `serviceState` ASC) USING BTREE
|
||||||
|
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '供应商退货换货售后记录表' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Records of supplier_refund_exchange
|
||||||
|
-- ----------------------------
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for supplier_user_address
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `supplier_user_address`;
|
||||||
|
CREATE TABLE `supplier_user_address` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT COMMENT '地址主键ID',
|
||||||
|
`addressId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '地址业务ID',
|
||||||
|
`supplierId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '供应商ID',
|
||||||
|
`userId` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '用户ID',
|
||||||
|
`name` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '收货人姓名',
|
||||||
|
`tel` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '收货人手机号',
|
||||||
|
`province` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '省',
|
||||||
|
`city` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '市',
|
||||||
|
`county` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '区县',
|
||||||
|
`addressDetail` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '详细地址',
|
||||||
|
`areaCode` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '地区编码',
|
||||||
|
`postalCode` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '邮政编码',
|
||||||
|
`isDefault` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否默认地址',
|
||||||
|
`createTime` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||||
|
`updateTime` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
|
||||||
|
`deleted` int NOT NULL DEFAULT 0 COMMENT '删除状态:0未删除,1已删除',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
UNIQUE INDEX `supplier_user_address_addressId_key`(`addressId` ASC) USING BTREE,
|
||||||
|
INDEX `supplier_user_address_supplierId_userId_idx`(`supplierId` ASC, `userId` ASC) USING BTREE,
|
||||||
|
INDEX `supplier_user_address_supplierId_userId_isDefault_idx`(`supplierId` ASC, `userId` ASC, `isDefault` ASC) USING BTREE
|
||||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '供应商用户收货地址表' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Records of supplier_user_address
|
||||||
|
-- ----------------------------
|
||||||
|
INSERT INTO `supplier_user_address` VALUES (1, 'addr-1785395646503', '99999999', 'b2397ac9a67f476c9833471d27709db1', '谌盼兮', '13545478393', '吉林省', '白山市', '临江市', '未来科技城', '220681', '430213', 1, '2026-07-30 07:14:06.541', '2026-07-30 07:29:34.829', 0);
|
||||||
|
INSERT INTO `supplier_user_address` VALUES (2, 'addr-1788252731181', '99999999', 'c281e124321c8db3a14f0a7c86046c3c', '谌盼兮', '19090230905', '湖北省', '武汉市', '洪山区', '中国地质大学', '420111', '430074', 1, '2026-09-01 08:52:11.226', '2026-09-01 08:52:11.226', 0);
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for user
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `user`;
|
||||||
|
CREATE TABLE `user` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT,
|
||||||
|
`mobile` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||||
|
`nickname` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
|
||||||
|
`avatarUrl` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
|
||||||
|
`points` int NOT NULL DEFAULT 0,
|
||||||
|
`createdAt` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||||
|
`updatedAt` datetime(3) NOT NULL,
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
UNIQUE INDEX `User_mobile_key`(`mobile` ASC) USING BTREE
|
||||||
|
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Records of user
|
||||||
|
-- ----------------------------
|
||||||
|
|
||||||
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
@@ -16,6 +16,8 @@ import { orderListService } from '../services/order-list.service.js'
|
|||||||
import { orderPushEventService, type OrderPushEventInput } from '../services/order-push-event.service.js'
|
import { orderPushEventService, type OrderPushEventInput } from '../services/order-push-event.service.js'
|
||||||
import {
|
import {
|
||||||
supplierOpenOrderService,
|
supplierOpenOrderService,
|
||||||
|
type SupplierInvoiceApplyRequest,
|
||||||
|
type SupplierInvoiceQueryRequest,
|
||||||
type SupplierOrderQueryRequest,
|
type SupplierOrderQueryRequest,
|
||||||
type SupplierReconciliationQueryRequest
|
type SupplierReconciliationQueryRequest
|
||||||
} from '../services/supplier-open-order.service.js'
|
} from '../services/supplier-open-order.service.js'
|
||||||
@@ -261,3 +263,37 @@ export const supplierReconciliationInfoController = withErrorBoundary(async (req
|
|||||||
|
|
||||||
return Response.json(await supplierOpenOrderService.queryReconciliationInfo(body))
|
return Response.json(await supplierOpenOrderService.queryReconciliationInfo(body))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const supplierInvoiceApplyController = withErrorBoundary(async (request: Request, _context: Context) => {
|
||||||
|
const methodResponse = guardMethod(request, ['POST'])
|
||||||
|
if (methodResponse) return methodResponse
|
||||||
|
|
||||||
|
let body: SupplierInvoiceApplyRequest
|
||||||
|
try {
|
||||||
|
body = supplierOpenOrderService.parseBody(await readJson<SupplierInvoiceApplyRequest>(request)) as SupplierInvoiceApplyRequest
|
||||||
|
} catch (error) {
|
||||||
|
return Response.json({
|
||||||
|
resultCode: 400,
|
||||||
|
message: error instanceof Error ? error.message : '请求参数解密失败'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response.json(await supplierOpenOrderService.applyForInvoices(body))
|
||||||
|
})
|
||||||
|
|
||||||
|
export const supplierInvoiceInfoController = withErrorBoundary(async (request: Request, _context: Context) => {
|
||||||
|
const methodResponse = guardMethod(request, ['POST'])
|
||||||
|
if (methodResponse) return methodResponse
|
||||||
|
|
||||||
|
let body: SupplierInvoiceQueryRequest
|
||||||
|
try {
|
||||||
|
body = supplierOpenOrderService.parseBody(await readJson<SupplierInvoiceQueryRequest>(request)) as SupplierInvoiceQueryRequest
|
||||||
|
} catch (error) {
|
||||||
|
return Response.json({
|
||||||
|
resultCode: 400,
|
||||||
|
message: error instanceof Error ? error.message : '请求参数解密失败'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response.json(await supplierOpenOrderService.queryInvoicesInfo(body))
|
||||||
|
})
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ type SupplierInfoRequest = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SupplierTokenRequest = {
|
type SupplierTokenRequest = {
|
||||||
userId?: string
|
AplParmObjct?: string
|
||||||
supplierIdentification?: string
|
supplierIdentification?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,10 +39,10 @@ export const supplierTokenController = withErrorBoundary(async (request: Request
|
|||||||
if (methodResponse) return methodResponse
|
if (methodResponse) return methodResponse
|
||||||
|
|
||||||
const body = await readJson<SupplierTokenRequest>(request)
|
const body = await readJson<SupplierTokenRequest>(request)
|
||||||
const userId = String(body.userId || '').trim()
|
const encryptedParam = String(body.AplParmObjct || '').trim()
|
||||||
const supplierIdentification = String(body.supplierIdentification || '').trim().toLowerCase()
|
const supplierIdentification = String(body.supplierIdentification || '').trim().toLowerCase()
|
||||||
|
|
||||||
return toHttpResponse(await supplierService.warmSupplierToken(userId, supplierIdentification))
|
return toHttpResponse(await supplierService.warmSupplierToken(encryptedParam, supplierIdentification))
|
||||||
})
|
})
|
||||||
|
|
||||||
export const supplierPointsController = withErrorBoundary(async (request: Request, _context: Context) => {
|
export const supplierPointsController = withErrorBoundary(async (request: Request, _context: Context) => {
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ import {
|
|||||||
orderPayController,
|
orderPayController,
|
||||||
orderPushEventController,
|
orderPushEventController,
|
||||||
orderShipController,
|
orderShipController,
|
||||||
|
supplierInvoiceApplyController,
|
||||||
|
supplierInvoiceInfoController,
|
||||||
supplierOrderInfoController,
|
supplierOrderInfoController,
|
||||||
supplierReconciliationInfoController
|
supplierReconciliationInfoController
|
||||||
} from './controllers/order.controller.js'
|
} from './controllers/order.controller.js'
|
||||||
@@ -107,6 +109,8 @@ const handlers: Record<string, FunctionHandler> = {
|
|||||||
'merchant-product-delete': merchantProductDeleteController,
|
'merchant-product-delete': merchantProductDeleteController,
|
||||||
'supplier-debug-tokens': supplierDebugTokensController,
|
'supplier-debug-tokens': supplierDebugTokensController,
|
||||||
'supplier-info': supplierInfoController,
|
'supplier-info': supplierInfoController,
|
||||||
|
'supplier-invoice-apply': supplierInvoiceApplyController,
|
||||||
|
'supplier-invoice-info': supplierInvoiceInfoController,
|
||||||
'supplier-order-info': supplierOrderInfoController,
|
'supplier-order-info': supplierOrderInfoController,
|
||||||
'supplier-reconciliation-info': supplierReconciliationInfoController,
|
'supplier-reconciliation-info': supplierReconciliationInfoController,
|
||||||
'supplier-reconciliation-result': supplierReconciliationResultController,
|
'supplier-reconciliation-result': supplierReconciliationResultController,
|
||||||
@@ -200,6 +204,8 @@ router.all('/api/:name', async ctx => dispatch(ctx.params.name)(ctx))
|
|||||||
router.all('/api/admin/:name', async ctx => dispatch(ctx.params.name)(ctx))
|
router.all('/api/admin/:name', async ctx => dispatch(ctx.params.name)(ctx))
|
||||||
router.post('/supplierOpenApi/pointOrder/queryOrderInfo', dispatch('supplier-order-info'))
|
router.post('/supplierOpenApi/pointOrder/queryOrderInfo', dispatch('supplier-order-info'))
|
||||||
router.post('/supplierOpenApi/pointOrder/queryReconciliationInfo', dispatch('supplier-reconciliation-info'))
|
router.post('/supplierOpenApi/pointOrder/queryReconciliationInfo', dispatch('supplier-reconciliation-info'))
|
||||||
|
router.post('/supplierOpenApi/pointOrder/applyForInvoices', dispatch('supplier-invoice-apply'))
|
||||||
|
router.post('/supplierOpenApi/pointOrder/queryInvoicesInfo', dispatch('supplier-invoice-info'))
|
||||||
router.post('/supplierOpenApi/pointOrder/reconciliationResult', dispatch('supplier-reconciliation-result'))
|
router.post('/supplierOpenApi/pointOrder/reconciliationResult', dispatch('supplier-reconciliation-result'))
|
||||||
router.post('/supplierOpenApi/pointOrder/unReconciledMsg', dispatch('supplier-unreconciled-msg'))
|
router.post('/supplierOpenApi/pointOrder/unReconciledMsg', dispatch('supplier-unreconciled-msg'))
|
||||||
router.post('/supplierOpenApi/debug/tokens', dispatch('supplier-debug-tokens'))
|
router.post('/supplierOpenApi/debug/tokens', dispatch('supplier-debug-tokens'))
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { supplierDao } from '../dao/supplier.dao.js'
|
|||||||
import { orderDao } from '../dao/order.dao.js'
|
import { orderDao } from '../dao/order.dao.js'
|
||||||
import { ORDER_EVENT_TYPE, ORDER_STATE } from '../constants/order.js'
|
import { ORDER_EVENT_TYPE, ORDER_STATE } from '../constants/order.js'
|
||||||
import { logger } from '../utils/logger.js'
|
import { logger } from '../utils/logger.js'
|
||||||
|
import { prisma } from '../utils/prisma.js'
|
||||||
import { sm4CbcDecrypt, verifySupplierOpenSignature } from '../utils/supplier-open-crypto.js'
|
import { sm4CbcDecrypt, verifySupplierOpenSignature } from '../utils/supplier-open-crypto.js'
|
||||||
|
|
||||||
export type SupplierOrderQueryRequest = {
|
export type SupplierOrderQueryRequest = {
|
||||||
@@ -11,6 +12,7 @@ export type SupplierOrderQueryRequest = {
|
|||||||
orderId?: string
|
orderId?: string
|
||||||
timestamp?: number
|
timestamp?: number
|
||||||
AplParmObjct?: string
|
AplParmObjct?: string
|
||||||
|
RsrvFld1?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SupplierReconciliationQueryRequest = {
|
export type SupplierReconciliationQueryRequest = {
|
||||||
@@ -24,10 +26,51 @@ export type SupplierReconciliationQueryRequest = {
|
|||||||
pageSize?: number
|
pageSize?: number
|
||||||
timestamp?: number
|
timestamp?: number
|
||||||
AplParmObjct?: string
|
AplParmObjct?: string
|
||||||
|
RsrvFld1?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const parseBody = (body: SupplierOrderQueryRequest) => {
|
export type SupplierInvoiceApplyRequest = {
|
||||||
if (!body.AplParmObjct) return body
|
supplierId?: string
|
||||||
|
token?: string
|
||||||
|
settlementId?: string
|
||||||
|
orderIds?: string
|
||||||
|
orderNum?: number
|
||||||
|
orderTotalPrice?: number | string
|
||||||
|
invoiceDate?: string
|
||||||
|
invoiceTitle?: string
|
||||||
|
invoiceCode?: string
|
||||||
|
invoiceAddress?: string
|
||||||
|
invoiceContact?: string
|
||||||
|
invoiceNakedPrice?: number | string
|
||||||
|
invoiceTaxPrice?: number | string
|
||||||
|
invoiceType?: string
|
||||||
|
invoiceContent?: string
|
||||||
|
remark?: string
|
||||||
|
bankAccount?: string
|
||||||
|
registeredAddress?: string
|
||||||
|
bankName?: string
|
||||||
|
timestamp?: number
|
||||||
|
AplParmObjct?: string
|
||||||
|
RsrvFld1?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type SupplierInvoiceQueryRequest = {
|
||||||
|
supplierId?: string
|
||||||
|
token?: string
|
||||||
|
settlementId?: string
|
||||||
|
timestamp?: number
|
||||||
|
AplParmObjct?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
type SupplierOpenEncryptedRequest = {
|
||||||
|
AplParmObjct?: string
|
||||||
|
ApiParamObject?: string
|
||||||
|
RsrvFld1?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const parseBody = <T extends SupplierOpenEncryptedRequest>(body: T) => {
|
||||||
|
const encryptedData = body.AplParmObjct || body.ApiParamObject
|
||||||
|
if (!encryptedData) return body
|
||||||
|
|
||||||
const keyHex = process.env.SUPPLIER_OPEN_SM4_KEY_HEX || process.env.SM4CBC_KEY_HEX || ''
|
const keyHex = process.env.SUPPLIER_OPEN_SM4_KEY_HEX || process.env.SM4CBC_KEY_HEX || ''
|
||||||
const ivHex = process.env.SUPPLIER_OPEN_SM4_IV_HEX || process.env.SM4CBC_IV_HEX || ''
|
const ivHex = process.env.SUPPLIER_OPEN_SM4_IV_HEX || process.env.SM4CBC_IV_HEX || ''
|
||||||
@@ -35,7 +78,10 @@ const parseBody = (body: SupplierOrderQueryRequest) => {
|
|||||||
throw new Error('供应商开放接口SM4配置缺失')
|
throw new Error('供应商开放接口SM4配置缺失')
|
||||||
}
|
}
|
||||||
|
|
||||||
return JSON.parse(sm4CbcDecrypt(body.AplParmObjct, keyHex, ivHex)) as SupplierOrderQueryRequest
|
return {
|
||||||
|
...JSON.parse(sm4CbcDecrypt(encryptedData, keyHex, ivHex)),
|
||||||
|
RsrvFld1: body.RsrvFld1
|
||||||
|
} as T
|
||||||
}
|
}
|
||||||
|
|
||||||
const toText = (date?: Date | null) => {
|
const toText = (date?: Date | null) => {
|
||||||
@@ -223,5 +269,160 @@ export const supplierOpenOrderService = {
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
return { resultCode: 0, message: '成功', totalPage, currentPage: page, orderInfos }
|
return { resultCode: 0, message: '成功', totalPage, currentPage: page, orderInfos }
|
||||||
|
},
|
||||||
|
|
||||||
|
async applyForInvoices(body: SupplierInvoiceApplyRequest) {
|
||||||
|
const supplierId = String(body.supplierId || '').trim()
|
||||||
|
const token = String(body.token || '').trim()
|
||||||
|
const settlementId = String(body.settlementId || '').trim()
|
||||||
|
const orderIds = [...new Set(String(body.orderIds || '')
|
||||||
|
.split(',')
|
||||||
|
.map(item => item.trim())
|
||||||
|
.filter(Boolean))]
|
||||||
|
const orderNum = Number(body.orderNum || 0)
|
||||||
|
const orderTotalPrice = Number(body.orderTotalPrice)
|
||||||
|
const timestamp = Number(body.timestamp || 0)
|
||||||
|
|
||||||
|
logger.info('supplier open invoice apply', { supplierId, settlementId, orderCount: orderIds.length, timestamp })
|
||||||
|
|
||||||
|
if (!supplierId || !token || !timestamp || !settlementId || !orderIds.length) {
|
||||||
|
return { resultCode: 400, message: '供应商、结算单、订单或签名信息不能为空' }
|
||||||
|
}
|
||||||
|
if (!body.invoiceDate || !body.invoiceTitle || !body.invoiceCode || !body.invoiceAddress || !body.invoiceContact) {
|
||||||
|
return { resultCode: 400, message: '开票日期、抬头、纳税人识别号、地址和联系电话不能为空' }
|
||||||
|
}
|
||||||
|
if (!Number.isInteger(orderNum) || orderNum <= 0 || !Number.isFinite(orderTotalPrice) || orderTotalPrice < 0) {
|
||||||
|
return { resultCode: 400, message: '订单数量或订单总金额不正确' }
|
||||||
|
}
|
||||||
|
|
||||||
|
const supplier = await supplierDao.findActiveBySupplierId(supplierId)
|
||||||
|
if (!supplier) {
|
||||||
|
return { resultCode: 404, message: '供应商信息不存在' }
|
||||||
|
}
|
||||||
|
if (!verifySupplierOpenSignature(supplier.supplierId, String(body.RsrvFld1 || supplier.clientId), timestamp, token)) {
|
||||||
|
return { resultCode: 401, message: '签名无效或已过期' }
|
||||||
|
}
|
||||||
|
|
||||||
|
const orders = await orderDao.findOpenApiSubOrders(supplierId, orderIds)
|
||||||
|
if (orders.length !== orderIds.length || orderNum !== orderIds.length) {
|
||||||
|
return { resultCode: 400, message: '订单数量校验不通过' }
|
||||||
|
}
|
||||||
|
|
||||||
|
const actualTotalPrice = orders.reduce((total, order) => total + Number(order.totalPrice || 0), 0)
|
||||||
|
if (Math.abs(actualTotalPrice - orderTotalPrice) >= 0.01) {
|
||||||
|
return { resultCode: 400, message: '订单总金额校验不通过' }
|
||||||
|
}
|
||||||
|
|
||||||
|
const orderIdText = orderIds.join(',')
|
||||||
|
const firstOrder = orders[0]
|
||||||
|
await orderDao.transaction(async tx => {
|
||||||
|
await tx.supplierInvoiceInfo.upsert({
|
||||||
|
where: { invoiceBizId: settlementId },
|
||||||
|
update: {
|
||||||
|
supplierId,
|
||||||
|
userId: firstOrder?.userId || null,
|
||||||
|
mainOrderId: firstOrder?.mainOrderId || null,
|
||||||
|
subOrderId: firstOrder?.orderId || null,
|
||||||
|
settlementId,
|
||||||
|
invoiceCode: body.invoiceCode,
|
||||||
|
orderIds: orderIdText,
|
||||||
|
invoiceStatus: 1,
|
||||||
|
requestBody: JSON.parse(JSON.stringify(body)),
|
||||||
|
deleted: 0
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
invoiceBizId: settlementId,
|
||||||
|
supplierId,
|
||||||
|
userId: firstOrder?.userId || null,
|
||||||
|
mainOrderId: firstOrder?.mainOrderId || null,
|
||||||
|
subOrderId: firstOrder?.orderId || null,
|
||||||
|
settlementId,
|
||||||
|
invoiceCode: body.invoiceCode,
|
||||||
|
orderIds: orderIdText,
|
||||||
|
invoiceStatus: 1,
|
||||||
|
requestBody: JSON.parse(JSON.stringify(body))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
return { resultCode: 0, message: '开票申请已受理' }
|
||||||
|
},
|
||||||
|
|
||||||
|
async queryInvoicesInfo(body: SupplierInvoiceQueryRequest) {
|
||||||
|
const supplierId = String(body.supplierId || '').trim()
|
||||||
|
const token = String(body.token || '').trim()
|
||||||
|
const settlementId = String(body.settlementId || '').trim()
|
||||||
|
const timestamp = Number(body.timestamp || 0)
|
||||||
|
|
||||||
|
if (!supplierId || !token || !timestamp || !settlementId) {
|
||||||
|
return { resultCode: 400, message: '供应商、结算单或签名信息不能为空' }
|
||||||
|
}
|
||||||
|
|
||||||
|
const supplier = await supplierDao.findActiveBySupplierId(supplierId)
|
||||||
|
if (!supplier) {
|
||||||
|
return { resultCode: 404, message: '供应商信息不存在' }
|
||||||
|
}
|
||||||
|
if (!verifySupplierOpenSignature(supplier.supplierId, supplier.clientId, timestamp, token)) {
|
||||||
|
return { resultCode: 401, message: '签名无效或已过期' }
|
||||||
|
}
|
||||||
|
|
||||||
|
const records = await prisma.supplierInvoiceInfo.findMany({
|
||||||
|
where: { supplierId, settlementId, deleted: 0 },
|
||||||
|
orderBy: { createTime: 'asc' }
|
||||||
|
})
|
||||||
|
const completedRecords = records.filter(item => item.invoiceStatus === 2)
|
||||||
|
const failedRecords = records.filter(item => item.invoiceStatus === 3)
|
||||||
|
const application = records.find(item => item.invoiceStatus === 1)
|
||||||
|
const applicationOrderIds = String(application?.orderIds || '')
|
||||||
|
const invoiceInfos = completedRecords.flatMap(record => {
|
||||||
|
const payload = record.requestBody && typeof record.requestBody === 'object'
|
||||||
|
? record.requestBody as Record<string, unknown>
|
||||||
|
: {}
|
||||||
|
const invoiceIds = String(record.invoiceIds || record.invoiceBizId)
|
||||||
|
.split(',')
|
||||||
|
.map(item => item.trim())
|
||||||
|
.filter(Boolean)
|
||||||
|
|
||||||
|
return invoiceIds.map(invoiceId => ({
|
||||||
|
invoiceId,
|
||||||
|
invoiceCode: record.invoiceCode || '',
|
||||||
|
invoiceDate: payload.invoiceDate || null,
|
||||||
|
invoiceNakeAmount: Number(payload.invoiceNakeAmount || payload.invoiceNakedPrice || 0),
|
||||||
|
invoiceTaxRate: Number(payload.invoiceTaxRate || 0),
|
||||||
|
invoiceTaxAmount: Number(payload.invoiceTaxAmount || payload.invoiceTaxPrice || 0),
|
||||||
|
invoiceAmount: Number(payload.invoiceAmount || 0),
|
||||||
|
invoiceType: Number(payload.invoiceType || 0),
|
||||||
|
url: payload.url || record.filePath || '',
|
||||||
|
imageEncode: payload.imageEncode || '',
|
||||||
|
fileType: payload.fileType || '',
|
||||||
|
checkCode: payload.checkCode || '',
|
||||||
|
invoiceAddress: payload.invoiceAddress || ''
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
|
||||||
|
const completedOrderIds = completedRecords
|
||||||
|
.flatMap(item => String(item.orderIds || '').split(','))
|
||||||
|
.map(item => item.trim())
|
||||||
|
.filter(Boolean)
|
||||||
|
const sucOrderIds = completedRecords.length && !completedOrderIds.length
|
||||||
|
? applicationOrderIds.split(',').map(item => item.trim()).filter(Boolean)
|
||||||
|
: completedOrderIds
|
||||||
|
const failOrderIds = failedRecords.length ? applicationOrderIds : ''
|
||||||
|
const failMsg = failedRecords.length
|
||||||
|
? String((failedRecords[0].requestBody as Record<string, unknown> | null)?.failMsg || '开票失败')
|
||||||
|
: completedRecords.length ? '' : '发票尚未开具'
|
||||||
|
|
||||||
|
return {
|
||||||
|
resultCode: 0,
|
||||||
|
message: '成功',
|
||||||
|
getInvoiceInfo: {
|
||||||
|
bSuccess: completedRecords.length ? 0 : 1,
|
||||||
|
settlementId,
|
||||||
|
sucOrderIds: [...new Set(sucOrderIds)].join(','),
|
||||||
|
failOrderIds,
|
||||||
|
failMsg,
|
||||||
|
invoiceInfos
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { supplierDao } from '../dao/supplier.dao.js'
|
|||||||
import { bridgeFetchWithAuth, findSupplierByIdentification, getBridgeApiBase, getBridgeToken, warmBridgeToken } from '../utils/bridge-auth.js'
|
import { bridgeFetchWithAuth, findSupplierByIdentification, getBridgeApiBase, getBridgeToken, warmBridgeToken } from '../utils/bridge-auth.js'
|
||||||
import { sha256 } from '../utils/crypto.js'
|
import { sha256 } from '../utils/crypto.js'
|
||||||
import { logger } from '../utils/logger.js'
|
import { logger } from '../utils/logger.js'
|
||||||
import { createSupplierOpenSignature } from '../utils/supplier-open-crypto.js'
|
import { createSupplierOpenSignature, sm4CbcDecrypt } from '../utils/supplier-open-crypto.js'
|
||||||
import { serviceFail, serviceOk } from '../types/service-result.js'
|
import { serviceFail, serviceOk } from '../types/service-result.js'
|
||||||
|
|
||||||
type BridgePointsResponse = {
|
type BridgePointsResponse = {
|
||||||
@@ -33,11 +33,29 @@ export const supplierService = {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
async warmSupplierToken(userId: string, supplierIdentification: string) {
|
async warmSupplierToken(encryptedParam: string, supplierIdentification: string) {
|
||||||
logger.info('supplier token warmup', { userId, supplierIdentification })
|
logger.info('supplier token warmup', { supplierIdentification })
|
||||||
|
|
||||||
if (!userId || !supplierIdentification) {
|
if (!encryptedParam || !supplierIdentification) {
|
||||||
return serviceFail('用户信息和供应商唯一标识不能为空')
|
return serviceFail('加密用户参数和供应商唯一标识不能为空')
|
||||||
|
}
|
||||||
|
|
||||||
|
const keyHex = process.env.SUPPLIER_OPEN_SM4_KEY_HEX || process.env.SM4CBC_KEY_HEX || ''
|
||||||
|
const ivHex = process.env.SUPPLIER_OPEN_SM4_IV_HEX || process.env.SM4CBC_IV_HEX || ''
|
||||||
|
if (!keyHex || !ivHex) {
|
||||||
|
return serviceFail('供应商开放接口SM4配置缺失', 500, 'SM4_CONFIG_MISSING')
|
||||||
|
}
|
||||||
|
|
||||||
|
let userId = ''
|
||||||
|
try {
|
||||||
|
const decrypted = sm4CbcDecrypt(encryptedParam.replace(/ /g, '+'), keyHex, ivHex)
|
||||||
|
const params = JSON.parse(decrypted) as { userId?: string }
|
||||||
|
userId = String(params.userId || '').trim()
|
||||||
|
} catch (error) {
|
||||||
|
return serviceFail('用户参数解密失败', 400, 'INVALID_USER_PARAM')
|
||||||
|
}
|
||||||
|
if (!userId) {
|
||||||
|
return serviceFail('用户信息不能为空', 400, 'USER_ID_MISSING')
|
||||||
}
|
}
|
||||||
|
|
||||||
const supplier = await findSupplierByIdentification(supplierIdentification).catch(error => error)
|
const supplier = await findSupplierByIdentification(supplierIdentification).catch(error => error)
|
||||||
|
|||||||
@@ -0,0 +1,359 @@
|
|||||||
|
import { createHash } from 'node:crypto'
|
||||||
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
|
||||||
|
import path from 'node:path'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
|
const PAGE_WIDTH = 842
|
||||||
|
const PAGE_HEIGHT = 595
|
||||||
|
|
||||||
|
const findFont = requestedPath => {
|
||||||
|
const candidates = [
|
||||||
|
requestedPath,
|
||||||
|
process.env.INVOICE_PDF_FONT_PATH,
|
||||||
|
'C:/Windows/Fonts/simhei.ttf',
|
||||||
|
'C:/Windows/Fonts/msyh.ttf',
|
||||||
|
'/usr/share/fonts/truetype/noto/NotoSansCJK-Regular.ttf',
|
||||||
|
'/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf'
|
||||||
|
].filter(Boolean)
|
||||||
|
const fontPath = candidates.find(candidate => existsSync(candidate))
|
||||||
|
if (!fontPath) {
|
||||||
|
throw new Error('未找到可用字体,请通过 INVOICE_PDF_FONT_PATH 指定支持中文的 TTF 字体')
|
||||||
|
}
|
||||||
|
if (path.extname(fontPath).toLowerCase() !== '.ttf') {
|
||||||
|
throw new Error('模拟发票工具仅支持 TTF 字体')
|
||||||
|
}
|
||||||
|
return fontPath
|
||||||
|
}
|
||||||
|
|
||||||
|
const readTableDirectory = font => {
|
||||||
|
const tableCount = font.readUInt16BE(4)
|
||||||
|
const tables = new Map()
|
||||||
|
for (let index = 0; index < tableCount; index += 1) {
|
||||||
|
const offset = 12 + index * 16
|
||||||
|
tables.set(font.toString('ascii', offset, offset + 4), {
|
||||||
|
offset: font.readUInt32BE(offset + 8),
|
||||||
|
length: font.readUInt32BE(offset + 12)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return tables
|
||||||
|
}
|
||||||
|
|
||||||
|
const createGlyphMapper = font => {
|
||||||
|
const cmapTable = readTableDirectory(font).get('cmap')
|
||||||
|
if (!cmapTable) throw new Error('字体缺少 cmap 字符映射表')
|
||||||
|
const base = cmapTable.offset
|
||||||
|
const count = font.readUInt16BE(base + 2)
|
||||||
|
let format12Offset = null
|
||||||
|
let format4Offset = null
|
||||||
|
|
||||||
|
for (let index = 0; index < count; index += 1) {
|
||||||
|
const record = base + 4 + index * 8
|
||||||
|
const platformId = font.readUInt16BE(record)
|
||||||
|
const encodingId = font.readUInt16BE(record + 2)
|
||||||
|
const subtableOffset = base + font.readUInt32BE(record + 4)
|
||||||
|
const format = font.readUInt16BE(subtableOffset)
|
||||||
|
if (format === 12 && (platformId === 0 || (platformId === 3 && encodingId === 10))) {
|
||||||
|
format12Offset = subtableOffset
|
||||||
|
}
|
||||||
|
if (format === 4 && (platformId === 0 || platformId === 3)) {
|
||||||
|
format4Offset = subtableOffset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fromFormat12 = codePoint => {
|
||||||
|
if (format12Offset === null) return 0
|
||||||
|
const groupCount = font.readUInt32BE(format12Offset + 12)
|
||||||
|
let low = 0
|
||||||
|
let high = groupCount - 1
|
||||||
|
while (low <= high) {
|
||||||
|
const middle = (low + high) >> 1
|
||||||
|
const group = format12Offset + 16 + middle * 12
|
||||||
|
const start = font.readUInt32BE(group)
|
||||||
|
const end = font.readUInt32BE(group + 4)
|
||||||
|
if (codePoint < start) high = middle - 1
|
||||||
|
else if (codePoint > end) low = middle + 1
|
||||||
|
else return font.readUInt32BE(group + 8) + codePoint - start
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
const fromFormat4 = codePoint => {
|
||||||
|
if (format4Offset === null || codePoint > 0xffff) return 0
|
||||||
|
const segmentCount = font.readUInt16BE(format4Offset + 6) / 2
|
||||||
|
const endCodes = format4Offset + 14
|
||||||
|
const startCodes = endCodes + segmentCount * 2 + 2
|
||||||
|
const deltas = startCodes + segmentCount * 2
|
||||||
|
const rangeOffsets = deltas + segmentCount * 2
|
||||||
|
for (let index = 0; index < segmentCount; index += 1) {
|
||||||
|
const end = font.readUInt16BE(endCodes + index * 2)
|
||||||
|
if (codePoint > end) continue
|
||||||
|
const start = font.readUInt16BE(startCodes + index * 2)
|
||||||
|
if (codePoint < start) return 0
|
||||||
|
const delta = font.readInt16BE(deltas + index * 2)
|
||||||
|
const rangeOffsetPosition = rangeOffsets + index * 2
|
||||||
|
const rangeOffset = font.readUInt16BE(rangeOffsetPosition)
|
||||||
|
if (rangeOffset === 0) return (codePoint + delta) & 0xffff
|
||||||
|
const glyphPosition = rangeOffsetPosition + rangeOffset + (codePoint - start) * 2
|
||||||
|
if (glyphPosition + 2 > font.length) return 0
|
||||||
|
const glyph = font.readUInt16BE(glyphPosition)
|
||||||
|
return glyph === 0 ? 0 : (glyph + delta) & 0xffff
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return codePoint => fromFormat12(codePoint) || fromFormat4(codePoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
const utf16Hex = value => {
|
||||||
|
const buffer = Buffer.from(value, 'utf16le')
|
||||||
|
buffer.swap16()
|
||||||
|
return buffer.toString('hex').toUpperCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
const createPdfWriter = () => {
|
||||||
|
const objects = []
|
||||||
|
return {
|
||||||
|
add(body) {
|
||||||
|
objects.push(Buffer.isBuffer(body) ? body : Buffer.from(body, 'binary'))
|
||||||
|
return objects.length
|
||||||
|
},
|
||||||
|
save(outputPath) {
|
||||||
|
const header = Buffer.from('%PDF-1.7\n%\xFF\xFF\xFF\xFF\n', 'binary')
|
||||||
|
const chunks = [header]
|
||||||
|
const offsets = [0]
|
||||||
|
let cursor = header.length
|
||||||
|
objects.forEach((body, index) => {
|
||||||
|
offsets.push(cursor)
|
||||||
|
const prefix = Buffer.from(`${index + 1} 0 obj\n`, 'ascii')
|
||||||
|
const suffix = Buffer.from('\nendobj\n', 'ascii')
|
||||||
|
chunks.push(prefix, body, suffix)
|
||||||
|
cursor += prefix.length + body.length + suffix.length
|
||||||
|
})
|
||||||
|
const xrefOffset = cursor
|
||||||
|
const xref = [`xref\n0 ${objects.length + 1}\n`, '0000000000 65535 f \n']
|
||||||
|
for (let index = 1; index <= objects.length; index += 1) {
|
||||||
|
xref.push(`${String(offsets[index]).padStart(10, '0')} 00000 n \n`)
|
||||||
|
}
|
||||||
|
xref.push(`trailer\n<< /Size ${objects.length + 1} /Root 1 0 R >>\nstartxref\n${xrefOffset}\n%%EOF\n`)
|
||||||
|
chunks.push(Buffer.from(xref.join(''), 'ascii'))
|
||||||
|
mkdirSync(path.dirname(outputPath), { recursive: true })
|
||||||
|
writeFileSync(outputPath, Buffer.concat(chunks))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const streamObject = (dictionary, data) => Buffer.concat([
|
||||||
|
Buffer.from(`<< ${dictionary} /Length ${data.length} >>\nstream\n`, 'ascii'),
|
||||||
|
data,
|
||||||
|
Buffer.from('\nendstream', 'ascii')
|
||||||
|
])
|
||||||
|
|
||||||
|
const money = value => Number(value || 0).toFixed(2)
|
||||||
|
|
||||||
|
const chineseAmount = value => {
|
||||||
|
const digits = '零壹贰叁肆伍陆柒捌玖'
|
||||||
|
const units = ['', '拾', '佰', '仟', '万', '拾', '佰', '仟', '亿', '拾', '佰', '仟']
|
||||||
|
const amount = Math.max(Number(value || 0), 0)
|
||||||
|
const integer = Math.floor(amount)
|
||||||
|
const chars = String(integer).split('').reverse()
|
||||||
|
let result = ''
|
||||||
|
let pendingZero = false
|
||||||
|
chars.forEach((char, index) => {
|
||||||
|
const digit = Number(char)
|
||||||
|
if (digit === 0) {
|
||||||
|
pendingZero = result.length > 0
|
||||||
|
if (index === 4 || index === 8) result = units[index] + result
|
||||||
|
} else {
|
||||||
|
result = `${digits[digit]}${units[index]}${pendingZero ? '零' : ''}${result}`
|
||||||
|
pendingZero = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const cents = Math.round((amount - integer) * 100)
|
||||||
|
const jiao = Math.floor(cents / 10)
|
||||||
|
const fen = cents % 10
|
||||||
|
return `${result || '零'}元${jiao ? `${digits[jiao]}角` : ''}${fen ? `${digits[fen]}分` : '整'}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalizeInvoice = input => {
|
||||||
|
const digest = createHash('sha256').update(JSON.stringify(input)).digest('hex').toUpperCase()
|
||||||
|
const total = Number(input.orderTotalPrice || 0)
|
||||||
|
const taxRate = Number(input.taxRate ?? 0.13)
|
||||||
|
const naked = Number(input.invoiceNakedPrice ?? total / (1 + taxRate))
|
||||||
|
const tax = Number(input.invoiceTaxPrice ?? total - naked)
|
||||||
|
return {
|
||||||
|
...input,
|
||||||
|
invoiceDate: input.invoiceDate || new Date().toISOString().slice(0, 10),
|
||||||
|
invoiceNumber: input.invoiceNumber || digest.slice(0, 20),
|
||||||
|
checkCode: input.checkCode || digest.slice(20, 40),
|
||||||
|
sellerName: input.sellerName || '模拟积分商城供应商',
|
||||||
|
sellerTaxId: input.sellerTaxId || input.supplierId || 'SIMULATED-SUPPLIER',
|
||||||
|
sellerAddress: input.sellerAddress || '模拟供应商注册地址',
|
||||||
|
sellerContact: input.sellerContact || '400-000-0000',
|
||||||
|
invoiceContent: input.invoiceContent || '积分商城商品',
|
||||||
|
orderNum: Number(input.orderNum || 1),
|
||||||
|
total,
|
||||||
|
naked,
|
||||||
|
tax,
|
||||||
|
taxRate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const generateMockInvoicePdf = (invoiceInput, outputPath, options = {}) => {
|
||||||
|
const invoice = normalizeInvoice(invoiceInput)
|
||||||
|
const fontPath = findFont(options.fontPath)
|
||||||
|
const font = readFileSync(fontPath)
|
||||||
|
const glyphFor = createGlyphMapper(font)
|
||||||
|
const glyphUnicode = new Map()
|
||||||
|
const commands = []
|
||||||
|
|
||||||
|
const encode = value => Array.from(String(value ?? '')).map(character => {
|
||||||
|
const glyph = glyphFor(character.codePointAt(0))
|
||||||
|
if (glyph && !glyphUnicode.has(glyph)) glyphUnicode.set(glyph, character)
|
||||||
|
return glyph.toString(16).padStart(4, '0')
|
||||||
|
}).join('').toUpperCase()
|
||||||
|
const text = (value, x, y, size = 10, color = '0 0 0') => {
|
||||||
|
commands.push(`BT /F1 ${size} Tf ${color} rg 1 0 0 1 ${x} ${y} Tm <${encode(value)}> Tj ET`)
|
||||||
|
}
|
||||||
|
const line = (x1, y1, x2, y2, width = 0.7, color = '0.45 0.12 0.12') => {
|
||||||
|
commands.push(`${color} RG ${width} w ${x1} ${y1} m ${x2} ${y2} l S`)
|
||||||
|
}
|
||||||
|
const rect = (x, y, width, height, color = '0.45 0.12 0.12') => {
|
||||||
|
commands.push(`${color} RG 0.7 w ${x} ${y} ${width} ${height} re S`)
|
||||||
|
}
|
||||||
|
const wrappedText = (value, x, y, maxChars, size = 9, lineHeight = 13) => {
|
||||||
|
const characters = Array.from(String(value || ''))
|
||||||
|
for (let index = 0; index < characters.length; index += maxChars) {
|
||||||
|
text(characters.slice(index, index + maxChars).join(''), x, y - index / maxChars * lineHeight, size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
commands.push('1 1 1 rg 0 0 842 595 re f')
|
||||||
|
text('增值税电子普通发票(模拟)', 280, 548, 22, '0.65 0.05 0.05')
|
||||||
|
line(274, 540, 568, 540, 1.2, '0.65 0.05 0.05')
|
||||||
|
text('仅供系统联调测试,禁止报销', 302, 522, 11, '0.75 0.1 0.1')
|
||||||
|
|
||||||
|
text(`发票号码:${invoice.invoiceNumber}`, 610, 555, 9)
|
||||||
|
text(`开票日期:${invoice.invoiceDate}`, 610, 538, 9)
|
||||||
|
text(`校验码:${invoice.checkCode}`, 610, 521, 9)
|
||||||
|
text(`结算单号:${invoice.settlementId || ''}`, 50, 521, 9)
|
||||||
|
|
||||||
|
rect(42, 188, 758, 320)
|
||||||
|
line(42, 414, 800, 414)
|
||||||
|
line(42, 320, 800, 320)
|
||||||
|
line(42, 280, 800, 280)
|
||||||
|
line(42, 226, 800, 226)
|
||||||
|
line(120, 414, 120, 508)
|
||||||
|
line(120, 320, 120, 414)
|
||||||
|
line(475, 414, 475, 508)
|
||||||
|
line(475, 320, 475, 414)
|
||||||
|
|
||||||
|
text('购买方', 68, 457, 12, '0.55 0.05 0.05')
|
||||||
|
text('销售方', 68, 365, 12, '0.55 0.05 0.05')
|
||||||
|
text('名称:', 132, 488, 9)
|
||||||
|
wrappedText(invoice.invoiceTitle, 180, 488, 26, 9)
|
||||||
|
text('纳税人识别号:', 132, 464, 9)
|
||||||
|
text(invoice.invoiceCode, 235, 464, 9)
|
||||||
|
text('地址、电话:', 487, 488, 9)
|
||||||
|
wrappedText(`${invoice.invoiceAddress || ''} ${invoice.invoiceContact || ''}`, 574, 488, 20, 8)
|
||||||
|
text('开户行及账号:', 487, 448, 9)
|
||||||
|
wrappedText(`${invoice.bankName || ''} ${invoice.bankAccount || ''}`, 574, 448, 20, 8)
|
||||||
|
|
||||||
|
text('名称:', 132, 395, 9)
|
||||||
|
text(invoice.sellerName, 180, 395, 9)
|
||||||
|
text('纳税人识别号:', 132, 371, 9)
|
||||||
|
text(invoice.sellerTaxId, 235, 371, 9)
|
||||||
|
text('地址、电话:', 487, 395, 9)
|
||||||
|
wrappedText(`${invoice.sellerAddress} ${invoice.sellerContact}`, 574, 395, 20, 8)
|
||||||
|
text('开户行及账号:', 487, 350, 9)
|
||||||
|
wrappedText(`${invoice.sellerBankName || '模拟银行'} ${invoice.sellerBankAccount || '0000000000000000'}`, 574, 350, 20, 8)
|
||||||
|
|
||||||
|
const columns = [42, 290, 382, 440, 495, 580, 655, 720, 800]
|
||||||
|
columns.slice(1, -1).forEach(x => line(x, 226, x, 320))
|
||||||
|
;['货物或应税劳务、服务名称', '规格型号', '单位', '数量', '单价', '金额', '税率', '税额'].forEach((label, index) => {
|
||||||
|
text(label, columns[index] + 7, 300, index === 0 ? 9 : 8)
|
||||||
|
})
|
||||||
|
wrappedText(`*商品*${invoice.invoiceContent}`, 50, 263, 28, 9)
|
||||||
|
text(invoice.invoiceType || '电子发票', 300, 263, 8)
|
||||||
|
text('项', 401, 263, 9)
|
||||||
|
text(invoice.orderNum, 458, 263, 9)
|
||||||
|
text(money(invoice.naked / invoice.orderNum), 503, 263, 8)
|
||||||
|
text(money(invoice.naked), 590, 263, 8)
|
||||||
|
text(`${(invoice.taxRate * 100).toFixed(0)}%`, 674, 263, 8)
|
||||||
|
text(money(invoice.tax), 730, 263, 8)
|
||||||
|
|
||||||
|
text('合计', 240, 203, 10)
|
||||||
|
text(`¥${money(invoice.naked)}`, 590, 203, 10)
|
||||||
|
text(`¥${money(invoice.tax)}`, 730, 203, 10)
|
||||||
|
text(`价税合计(大写):${chineseAmount(invoice.total)}`, 52, 164, 11)
|
||||||
|
text(`(小写):¥${money(invoice.total)}`, 600, 164, 11)
|
||||||
|
text(`订单号:${invoice.orderIds || ''}`, 52, 132, 8)
|
||||||
|
wrappedText(`备注:${invoice.remark || '模拟开票,仅用于开发与联调测试'}`, 52, 111, 70, 8)
|
||||||
|
text('收款人:模拟收款员', 52, 65, 9)
|
||||||
|
text('复核:模拟复核员', 285, 65, 9)
|
||||||
|
text('开票人:模拟开票员', 510, 65, 9)
|
||||||
|
text('销售方(章)', 682, 65, 9, '0.7 0.05 0.05')
|
||||||
|
|
||||||
|
commands.push('q 0.92 0.92 0.92 rg BT /F1 34 Tf 0.866 0.5 -0.5 0.866 235 170 Tm')
|
||||||
|
commands.push(`<${encode('模拟发票 禁止报销')}> Tj ET Q`)
|
||||||
|
commands.push('0.75 0.08 0.08 RG 2 w 798 88 m 798 111.196 779.196 130 756 130 c 732.804 130 714 111.196 714 88 c 714 64.804 732.804 46 756 46 c 779.196 46 798 64.804 798 88 c S')
|
||||||
|
|
||||||
|
const content = Buffer.from(commands.join('\n'), 'ascii')
|
||||||
|
const toUnicodeEntries = [...glyphUnicode.entries()].map(([glyph, character]) =>
|
||||||
|
`<${glyph.toString(16).padStart(4, '0').toUpperCase()}> <${utf16Hex(character)}>`)
|
||||||
|
const toUnicodeBlocks = []
|
||||||
|
for (let index = 0; index < toUnicodeEntries.length; index += 100) {
|
||||||
|
const entries = toUnicodeEntries.slice(index, index + 100)
|
||||||
|
toUnicodeBlocks.push(`${entries.length} beginbfchar`, ...entries, 'endbfchar')
|
||||||
|
}
|
||||||
|
const toUnicode = Buffer.from([
|
||||||
|
'/CIDInit /ProcSet findresource begin', '12 dict begin', 'begincmap',
|
||||||
|
'/CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def',
|
||||||
|
'/CMapName /MockInvoiceUnicode def', '/CMapType 2 def',
|
||||||
|
'1 begincodespacerange', '<0000> <FFFF>', 'endcodespacerange',
|
||||||
|
...toUnicodeBlocks,
|
||||||
|
'endcmap', 'CMapName currentdict /CMap defineresource pop', 'end', 'end'
|
||||||
|
].join('\n'), 'ascii')
|
||||||
|
|
||||||
|
const writer = createPdfWriter()
|
||||||
|
writer.add('<< /Type /Catalog /Pages 2 0 R >>')
|
||||||
|
writer.add('<< /Type /Pages /Kids [3 0 R] /Count 1 >>')
|
||||||
|
writer.add(`<< /Type /Page /Parent 2 0 R /MediaBox [0 0 ${PAGE_WIDTH} ${PAGE_HEIGHT}] /Resources << /Font << /F1 5 0 R >> >> /Contents 4 0 R >>`)
|
||||||
|
writer.add(streamObject('', content))
|
||||||
|
writer.add('<< /Type /Font /Subtype /Type0 /BaseFont /MockInvoiceFont /Encoding /Identity-H /DescendantFonts [6 0 R] /ToUnicode 9 0 R >>')
|
||||||
|
writer.add('<< /Type /Font /Subtype /CIDFontType2 /BaseFont /MockInvoiceFont /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> /FontDescriptor 7 0 R /DW 1000 /CIDToGIDMap /Identity >>')
|
||||||
|
writer.add('<< /Type /FontDescriptor /FontName /MockInvoiceFont /Flags 4 /FontBBox [-1000 -1000 3000 3000] /ItalicAngle 0 /Ascent 1000 /Descent -300 /CapHeight 800 /StemV 80 /FontFile2 8 0 R >>')
|
||||||
|
writer.add(streamObject(`/Length1 ${font.length}`, font))
|
||||||
|
writer.add(streamObject('', toUnicode))
|
||||||
|
writer.save(outputPath)
|
||||||
|
return outputPath
|
||||||
|
}
|
||||||
|
|
||||||
|
const parseArguments = argv => {
|
||||||
|
const options = {}
|
||||||
|
for (let index = 0; index < argv.length; index += 1) {
|
||||||
|
if (argv[index] === '--input') options.input = argv[++index]
|
||||||
|
else if (argv[index] === '--data') options.data = argv[++index]
|
||||||
|
else if (argv[index] === '--output') options.output = argv[++index]
|
||||||
|
else if (argv[index] === '--font') options.font = argv[++index]
|
||||||
|
}
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
||||||
|
try {
|
||||||
|
const options = parseArguments(process.argv.slice(2))
|
||||||
|
if (!options.input && !options.data) {
|
||||||
|
throw new Error('请使用 --input <json文件> 或 --data <json字符串> 传入开票信息')
|
||||||
|
}
|
||||||
|
const input = options.input
|
||||||
|
? JSON.parse(readFileSync(path.resolve(options.input), 'utf8'))
|
||||||
|
: JSON.parse(options.data)
|
||||||
|
const defaultName = `mock-invoice-${String(input.settlementId || Date.now()).replace(/[^a-zA-Z0-9_-]/g, '_')}.pdf`
|
||||||
|
const outputPath = path.resolve(options.output || path.join('output', 'pdf', defaultName))
|
||||||
|
generateMockInvoicePdf(input, outputPath, { fontPath: options.font })
|
||||||
|
console.log(outputPath)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error instanceof Error ? error.message : String(error))
|
||||||
|
process.exitCode = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user