Commit 05dfabfa authored by 332784038@qq.com's avatar 332784038@qq.com

Merge branch 'release' into zhengyi_dev

parents 86b0e26c d1d89434
......@@ -2,5 +2,4 @@
根目录下直接执行 mvn clean install package '-Dmaven.test.skip=true' 命令,将项目进行初始化的打包,预计需要 1 分钟左右。
首次启动运行YudaoServerApplication
首次启动运行YudaoServerApplication
services:
api-jiedao-test-operator:
image: harbor.jiedao.com/api-jiedao-test-operator:latest
container_name: api-jiedao-test-operator
ports:
- "9091:9001"
environment:
env: uat
volumes:
- '/etc/localtime:/etc/localtime'
- '/jiedao/docker/test/apps/jiedao/api/logs/operator:/logs'
- '/jiedao/docker/test/apps/jiedao/static:/app/static'
- '/jiedao/docker/test/apps/jiedao/fonts/zh:/usr/share/fonts/zh'
restart: always
ulimits:
nproc: 65535
nofile:
soft: 32000
hard: 40000
deploy:
resources:
limits:
cpus: '3'
memory: 3G
networks:
app-net:
ipv4_address: 10.10.0.120
networks:
app-net:
external: true
SET FOREIGN_KEY_CHECKS=0;
ALTER TABLE `jiedao`.`member_user` ADD COLUMN `code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '会员编号' AFTER `id`;
ALTER TABLE `member_user` ADD COLUMN `code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '会员编号' AFTER `id`;
ALTER TABLE `jiedao`.`member_user` ADD COLUMN `country` int NULL DEFAULT NULL COMMENT '国家' AFTER `control_password`;
ALTER TABLE `member_user` ADD COLUMN `country` int NULL DEFAULT NULL COMMENT '国家' AFTER `control_password`;
ALTER TABLE `jiedao`.`member_user` ADD COLUMN `city` int NULL DEFAULT NULL COMMENT '城市' AFTER `country`;
ALTER TABLE `member_user` ADD COLUMN `city` int NULL DEFAULT NULL COMMENT '城市' AFTER `country`;
ALTER TABLE `jiedao`.`member_user` ADD COLUMN `referral_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '推荐码' AFTER `open_id`;
ALTER TABLE `member_user` ADD COLUMN `referral_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '推荐码' AFTER `open_id`;
ALTER TABLE `jiedao`.`member_user` ADD COLUMN `register_platform` int NULL DEFAULT 0 COMMENT '注册平台' AFTER `referral_code`;
ALTER TABLE `member_user` ADD COLUMN `register_platform` int NULL DEFAULT 0 COMMENT '注册平台' AFTER `referral_code`;
ALTER TABLE `jiedao`.`member_user` ADD UNIQUE INDEX `code`(`code` ASC) USING BTREE;
ALTER TABLE `member_user` ADD UNIQUE INDEX `code`(`code` ASC) USING BTREE;
UPDATE `member_user` SET `country` = 130,`city` = 360 WHERE `area_code` = '86';
SET FOREIGN_KEY_CHECKS=1;
\ No newline at end of file
This diff is collapsed.
SET FOREIGN_KEY_CHECKS = 0;
INSERT INTO `jiedao`.`system_sms_template` (`id`, `type`, `status`, `code`, `name`, `content`, `params`, `remark`, `api_template_id`, `channel_id`, `channel_code`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `content_en`, `api_template_id_en`) VALUES (55, 3, 0, 'user-sms-redeem-reward', '积分兑换验证码', '积分兑换验证码:${code},请勿将验证码泄露给他人,以免造成不必要的损失,两分钟之内有效!', '[\"code\"]', NULL, 'SMS_471775248', 6, 'ALIYUN', '2696', '2024-08-20 10:06:06', '2696', '2024-08-20 10:14:39', b'0', '[ECLogistics]Your login code is:{code}, do not disclose this code to others to avoid any unnecessary loss, within 20 minutes effective!', 'SMS_199790126');
INSERT INTO `system_sms_template` (`type`, `status`, `code`, `name`, `content`, `params`, `remark`, `api_template_id`, `channel_id`, `channel_code`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `content_en`, `api_template_id_en`) VALUES ( 3, 0, 'user-sms-redeem-reward', '积分兑换验证码', '积分兑换验证码:${code},请勿将验证码泄露给他人,以免造成不必要的损失,两分钟之内有效!', '[\"code\"]', NULL, 'SMS_471775248', 6, 'ALIYUN', '2696', '2024-08-20 10:06:06', '2696', '2024-08-20 10:14:39', b'0', '[ECLogistics]Your login code is:{code}, do not disclose this code to others to avoid any unnecessary loss, within 20 minutes effective!', 'SMS_199790126');
SET FOREIGN_KEY_CHECKS = 1;
\ No newline at end of file
......@@ -56,11 +56,13 @@ INSERT INTO `system_dict_type` (`name`, `type`, `status`, `remark`, `creator`, `
VALUES ('客户跟进类型', 'customer_followup_type', 0, NULL, '1', now(), '1', now(), b'0');
INSERT INTO `system_dict_data` (`sort`, `value`, `label`, `label_en`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`)
VALUES (1, '1', '维系拜访', 'Follow-up Visit', 'customer_followup_type', 0, 'default', '', NULL, '1', now(), '115', now(), b'0');
VALUES (4, '1', '维护拜访', 'Maintenance visits', 'customer_followup_type', 0, 'default', '', NULL, '1', now(), '115', now(), b'0');
INSERT INTO `system_dict_data` (`sort`, `value`, `label`, `label_en`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`)
VALUES (2, '2', '商机跟进', 'Business opportunities', 'customer_followup_type', 0, 'default', '', NULL, '1', now(), '115', now(), b'0');
VALUES (1, '2', '商机跟进', 'Business opportunities', 'customer_followup_type', 0, 'default', '', NULL, '1', now(), '115', now(), b'0');
INSERT INTO `system_dict_data` (`sort`, `value`, `label`, `label_en`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`)
VALUES (3, '3', '联合拜访', 'Joint visit', 'customer_followup_type', 0, 'default', '', NULL, '1', now(), '115', now(), b'0');
VALUES (2, '3', '新业务开发', 'New business development', 'customer_followup_type', 0, 'default', '', NULL, '1', now(), '115', now(), b'0');
INSERT INTO `system_dict_data` (`sort`, `value`, `label`, `label_en`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`)
VALUES (3, '4', '复购跟进', 'Follow up on repeat purchases', 'customer_followup_type', 0, 'default', '', NULL, '1', now(), '115', now(), b'0');
INSERT INTO `system_dict_type` (`name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`)
......
-- 补充跟进字典
INSERT INTO `system_dict_type`(`name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES ( '销售阶段', 'sale_stage', 0, '销售阶段', '2702', '2024-11-26 18:32:06', '2702', '2024-11-26 18:32:06', b'0');
INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`) VALUES (14, '达到承诺(协议客户适用)', '14', 'sale_stage', 0, 'default', '', '达到承诺(协议客户适用)', '2702', '2024-11-26 18:51:41', '2702', '2024-11-26 18:51:41', b'0', 'Fulfill commitments (applicable to agreement clients)');
INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`) VALUES (13, '未来机会(三个月)', '13', 'sale_stage', 0, 'default', '', '未来机会(三个月)', '2702', '2024-11-26 18:51:10', '2702', '2024-11-26 18:51:10', b'0', 'Future Opportunities (Three Months)');
INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`) VALUES (12, '输单', '12', 'sale_stage', 0, 'default', '', '输单', '2702', '2024-11-26 18:50:47', '2702', '2024-11-26 18:50:47', b'0', 'Single loss');
INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`) VALUES (11, '赢单', '11', 'sale_stage', 0, 'default', '', '赢单', '2702', '2024-11-26 18:50:22', '2702', '2024-11-26 18:50:22', b'0', 'Winning orders');
INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`) VALUES (10, '跟进货物入仓', '10', 'sale_stage', 0, 'default', '', '跟进货物入仓', '2702', '2024-11-26 18:50:00', '2702', '2024-11-26 18:50:00', b'0', 'Follow up on the goods entering the warehouse');
INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`) VALUES (9, '同意发货', '9', 'sale_stage', 0, 'default', '', '同意发货', '2702', '2024-11-26 18:49:14', '2702', '2024-11-26 18:49:14', b'0', 'Agree to ship');
INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`) VALUES (8, '维护拜访', '8', 'sale_stage', 0, 'default', '', '维护拜访', '2702', '2024-11-26 18:46:25', '2702', '2024-11-26 18:46:25', b'0', 'Maintenance visits');
INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`) VALUES (7, '特殊申请(优惠、服务)', '7', 'sale_stage', 0, 'default', '', '特殊申请(优惠、服务)', '2702', '2024-11-26 18:45:45', '2702', '2024-11-26 18:46:45', b'0', 'Special applications (discounts, services)');
INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`) VALUES (6, '潜力挖潜', '6', 'sale_stage', 0, 'default', '', '潜力挖潜', '2702', '2024-11-26 18:36:25', '2702', '2024-11-26 18:46:59', b'0', 'Potential tapping');
INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`) VALUES (5, '报价(给方案)', '5', 'sale_stage', 0, 'default', '', '报价(给方案)', '2702', '2024-11-26 18:36:02', '2702', '2024-11-26 18:47:15', b'0', 'Quotation (for proposal)');
INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`) VALUES (4, '复购跟进', '4', 'sale_stage', 0, 'default', '', '复购跟进', '2702', '2024-11-26 18:35:28', '2702', '2024-11-26 18:47:35', b'0', 'Follow up on repeat purchases');
INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`) VALUES (3, '需求确认', '3', 'sale_stage', 0, 'default', '', '需求确认', '2702', '2024-11-26 18:35:13', '2702', '2024-11-26 18:48:09', b'0', 'Requirement Validate');
INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`) VALUES (2, '新业务开发', '2', 'sale_stage', 0, 'default', '', '新业务开发', '2702', '2024-11-26 18:34:51', '2702', '2024-11-26 18:48:25', b'0', 'new business development');
INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`) VALUES (1, '新询盘', '1', 'sale_stage', 0, 'default', '', '新询盘', '2702', '2024-11-26 18:34:26', '2702', '2024-11-26 18:48:39', b'0', 'New inquiry');
-- 补充跟进记录的销售阶段字段值
alter table ecw_customer_followup
add COLUMN `sale_stage` int DEFAULT NULL COMMENT '跟进销售阶段:详情看字典类型sale_stage' after `follow_type`;
-- 订单线路id补充索引
ALTER TABLE `ecw_order` ADD INDEX line_id (`line_id`);
\ No newline at end of file
-- 控货订单数据刷新
-- 更新历史控货订单数据要求:
-- 1.订单控货=是 && 控货状态=控货中/部分控货 && 订单创建时间<=2024-11.28 00:00 && 订单发货人电话=订单收货人电话,更新订单限制修改收货人=否
UPDATE ecw_order o
join ecw_order_consignor nor
on o.order_id = nor.order_id
join ecw_order_consignee nee
on o.order_id = nee.order_id
SET o.is_limit_update_consignee = 0
WHERE o.is_cargo_control = 1 AND o.create_time <= '2024-11.28 00:00:00' AND nor.country_code = nee.country_code AND nor.phone = nee.phone;
-- 添加常用客户提货网点sql
INSERT INTO `system_dict_type`(`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`,
`update_time`, `deleted`)
VALUES (null, '常用提货网点', 'pickup_points', 0, NULL, '115', '2024-11-29 14:39:24', '115',
'2024-11-29 14:39:24', b'0');
INSERT INTO `system_dict_data` (`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`,
`creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`)
VALUES
(1, 'Alaba', '1', 'pickup_points', 0, 'default', '', NULL, '1', '2024-11-29 14:39:24', '115', '2024-11-29 14:39:24', b'0', 'Alaba'),
(2, 'Tradefair', '2', 'pickup_points', 0, 'default', '', NULL, '1', '2024-11-29 14:39:24', '115', '2024-11-29 14:39:24', b'0', 'Tradefair'),
(3, 'Island', '3', 'pickup_points', 0, 'default', '', NULL, '1', '2024-11-29 14:39:24', '115', '2024-11-29 14:39:24', b'0', 'Island'),
(4, 'Oshodi', '4', 'pickup_points', 0, 'default', '', NULL, '1', '2024-11-29 14:39:24', '115', '2024-11-29 14:39:24', b'0', 'Oshodi'),
(5, 'Onitsha', '5', 'pickup_points', 0, 'default', '', NULL, '1', '2024-11-29 14:39:24', '115', '2024-11-29 14:39:24', b'0', 'Onitsha'),
(6, 'Kano', '6', 'pickup_points', 0, 'default', '', NULL, '1', '2024-11-29 14:39:24', '115', '2024-11-29 14:39:24', b'0', 'Kano'),
(7, 'Odunade', '7', 'pickup_points', 0, 'default', '', NULL, '1', '2024-11-29 14:39:24', '115', '2024-11-29 14:39:24', b'0', 'Odunade'),
(8, 'Accra', '8', 'pickup_points', 0, 'default', '', NULL, '1', '2024-11-29 14:39:24', '115', '2024-11-29 14:39:24', b'0', 'Accra'),
(9, 'Kumasi', '9', 'pickup_points', 0, 'default', '', NULL, '1', '2024-11-29 14:39:24', '115', '2024-11-29 14:39:24', b'0', 'Kumasi'),
(10, 'Abidjan', '10', 'pickup_points', 0, 'default', '', NULL, '1', '2024-11-29 14:39:24', '115', '2024-11-29 14:39:24', b'0', 'Abidjan'),
(11, 'Dar es Salaam', '11', 'pickup_points', 0, 'default', '', NULL, '1', '2024-11-29 14:39:24', '115', '2024-11-29 14:39:24', b'0', 'Dar es Salaam'),
(12, 'Dubai', '12', 'pickup_points', 0, 'default', '', NULL, '1', '2024-11-29 14:39:24', '115', '2024-11-29 14:39:24', b'0', 'Dubai'),
(13, 'Nairobi', '13', 'pickup_points', 0, 'default', '', NULL, '1', '2024-11-29 14:39:24', '115', '2024-11-29 14:39:24', b'0', 'Nairobi'),
(14, 'Mombasa', '14', 'pickup_points', 0, 'default', '', NULL, '1', '2024-11-29 14:39:24', '115', '2024-11-29 14:39:24', b'0', 'Mombasa'),
(15, 'Nakuru', '15', 'pickup_points', 0, 'default', '', NULL, '1', '2024-11-29 14:39:24', '115', '2024-11-29 14:39:24', b'0', 'Nakuru'),
(16, 'Maputo', '16', 'pickup_points', 0, 'default', '', NULL, '1', '2024-11-29 14:39:24', '115', '2024-11-29 14:39:24', b'0', 'Maputo'),
(17, 'Beira', '17', 'pickup_points', 0, 'default', '', NULL, '1', '2024-11-29 14:39:24', '115', '2024-11-29 14:39:24', b'0', 'Beira'),
(18, 'Chimoio', '18', 'pickup_points', 0, 'default', '', NULL, '1', '2024-11-29 14:39:24', '115', '2024-11-29 14:39:24', b'0', 'Chimoio'),
(19, 'Quelimane', '19', 'pickup_points', 0, 'default', '', NULL, '1', '2024-11-29 14:39:24', '115', '2024-11-29 14:39:24', b'0', 'Quelimane'),
(20, 'Nampula', '20', 'pickup_points', 0, 'default', '', NULL, '1', '2024-11-29 14:39:24', '115', '2024-11-29 14:39:24', b'0', 'Nampula');
\ No newline at end of file
-- 管理端复制订单权限按钮
INSERT INTO `system_menu`( `name`, `permission`, `menu_type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `is_show_in_menu_bar`, `name_en`, `keepalive`, `redirect`, `badge_field`) VALUES ('复制订单', 'ecw:order:copy', 3, 0, 1852, '', '', '', 0, '119', '2024-10-23 23:10:39', '119', '2024-10-23 23:10:39', b'0', b'1', 'Order Copy', b'0', NULL, NULL);
-- 增加订单产品项最后单价变更时间
alter table ecw_order_item
add COLUMN `last_freight_charge_price_time` datetime DEFAULT NULL COMMENT '运费最后单价变更时间';
alter table ecw_order_item
add COLUMN `last_clearance_charge_price_time` datetime DEFAULT NULL COMMENT '清关费最后单价变更时间';
-- 批量更新订单产品项的最后单价变更时间
update ecw_order_item set `last_freight_charge_price_time` = update_time where last_freight_charge_price_time is null;
update ecw_order_item set `last_clearance_charge_price_time` = update_time where last_clearance_charge_price_time is null;
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
# 刷新应收款基准币种
UPDATE ecw_receivable er
SET base_currency_id = (SELECT er.import_currency5
FROM ecw_region er
WHERE er.id = (SELECT eoo.objective_country_id
FROM ecw_order_objective eoo
WHERE eoo.order_id = er.order_id))
WHERE base_currency_id IS NULL;
# 刷新银行明细流水号
UPDATE ecw_receipt_item AS t1
JOIN (
SELECT
id,
CONCAT(
'YHMX',
DATE_FORMAT(create_time, '%Y%m%d'),
LPAD(ROW_NUMBER() OVER (PARTITION BY DATE(create_time) ORDER BY create_time), 5, '0')
) AS new_serial_number
FROM ecw_receipt_item
) AS t2
ON t1.id = t2.id
SET t1.serial_number = t2.new_serial_number
WHERE t1.serial_number IS NULL;
# 刷新银行明细审核通过时间
UPDATE ecw_receipt_item
SET approval_time = update_time
WHERE approval_time IS NULL AND `status` = 1;
# 刷新银行明细核销币种
UPDATE ecw_receipt_item eri SET eri.write_off_currency_id = (
SELECT er.base_currency_id
FROM ecw_receivable er
WHERE er.receipt_id = eri.receipt_id
AND er.deleted = 0
AND er.base_currency_id IS NOT NULL
LIMIT 1
) WHERE eri.deleted = 0 AND eri.write_off_currency_id IS NULL;
# 刷新银行明细汇率,银行收款明细-币种≠应收所在自编号对应的核算币种,但是跟收款单-应收费用的币种相同
UPDATE ecw_receipt_item eri
SET eri.rate = (
SELECT era.write_off_rate
FROM ecw_receipt_account era
WHERE eri.receipt_id = era.receipt_id
AND era.currency_id = eri.currency_id
AND era.deleted = 0
AND era.write_off_rate IS NOT NULL
LIMIT 1
)
WHERE eri.`status` = 1
AND eri.deleted = 0
AND EXISTS (
SELECT 1
FROM ecw_receipt_account era
WHERE eri.receipt_id = era.receipt_id
AND era.currency_id = eri.currency_id
AND era.deleted = 0
AND era.write_off_rate IS NOT NULL
);
# 查询银行收款明细-币种≠应收所在自编号对应的核算币种,跟收款单-应收费用的币种也无法匹配
SELECT
eri.id,
eri.serial_number,
eri.receipt_id,
era.id aid,
eri.currency_id ic,
era.currency_id ac,
era.write_off_rate
FROM
ecw_receipt_item eri
LEFT JOIN ecw_receipt_account era ON eri.receipt_id = era.receipt_id
AND eri.currency_id = era.currency_id
AND era.deleted = 0
WHERE
eri.`status` = 1
AND eri.deleted = 0
AND era.id IS NULL;
# 刷新银行收款明细-币种≠应收所在自编号对应的核算币种,跟收款单-应收费用的币种也无法匹配
UPDATE ecw_receipt_item eri
JOIN (
SELECT
eri.id
FROM
ecw_receipt_item eri
LEFT JOIN ecw_receipt_account era
ON eri.receipt_id = era.receipt_id
AND eri.currency_id = era.currency_id
AND era.deleted = 0
WHERE
eri.`status` = 1
AND eri.deleted = 0
AND era.id IS NULL
) AS to_update ON eri.id = to_update.id
SET eri.rate = IFNULL((
SELECT eer.currency_rate
FROM ecw_exchange_rate eer
WHERE eer.source_currency_id = eri.currency_id
AND eer.target_currency_id = eri.write_off_currency_id
),1)
WHERE eri.`status` = 1
AND eri.deleted = 0;
# 更新收款单生成路径
UPDATE ecw_receipt SET generate_path = 0 WHERE generate_path IS NULL;
# 刷新应收款优惠金额
UPDATE ecw_receivable er
SET er.discount_total = 0 WHERE er.discount_total IS NULL;
# 刷新应收款汇率
# 应收明细币种=基准币种
UPDATE ecw_receivable er
SET er.exchange_rate = 1 WHERE er.exchange_rate IS NULL AND er.receipt_id IS NOT NULL AND er.currency_id = er.base_currency_id AND er.deleted = 0;
# 应收明细基准币种是美元
UPDATE ecw_receivable er
SET er.exchange_rate = (
SELECT
era.write_off_rate
FROM
ecw_receipt_account era
WHERE
era.receipt_id = er.receipt_id
AND era.currency_id = er.currency_id
AND era.deleted = 0
AND era.write_off_rate IS NOT NULL
LIMIT 1
)
WHERE
er.receipt_id IS NOT NULL
AND er.base_currency_id = 1
AND er.currency_id != 1
AND er.deleted = 0;
# 应收明细基准币种不是美元
UPDATE ecw_receivable er
SET er.exchange_rate = (SELECT eer.currency_rate FROM ecw_exchange_rate eer WHERE eer.source_currency_id = er.currency_id AND eer.target_currency_id = er.base_currency_id )
WHERE er.exchange_rate IS NULL AND er.receipt_id IS NOT NULL AND er.base_currency_id != 1 AND er.deleted = 0;
# 刷新应收款基准金额
UPDATE ecw_receivable er
SET er.base_amount = er.exchange_rate * (er.tax_amount - er.discount_total)
WHERE er.base_amount IS NULL AND er.receipt_id IS NOT NULL AND er.exchange_rate IS NOT NULL;
# 修改收款单已核销待开票状态
UPDATE `ecw_receipt` SET `state` = 4 WHERE `state` = 5;
# 刷新应收明细账户ID
UPDATE ecw_receipt_item eri SET eri.account_id = (SELECT eba.id FROM ecw_bank_account eba WHERE eba.ba_account_name = eri.account_name AND eba.ba_bank_name = eri.account_bank_name AND eba.ba_account_num = eri.account_no AND eba.deleted = 0) WHERE eri.deleted = 0;
# 刷新收款明细-应收明细-收入归属(银行帐号设置收入归属之后执行)
UPDATE ecw_receivable_write_off_record erwor
SET erwor.income_belong = (SELECT eba.ba_income_belong FROM ecw_receipt_item eri LEFT JOIN ecw_bank_account eba ON eri.account_id = eba.id WHERE erwor.receipt_item_id = eri.id)
WHERE erwor.income_belong IS NULL;
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
alter table ecw_channel add COLUMN `bubble_exempt_weight` decimal(15,2) DEFAULT NULL COMMENT '免泡重量';
SELECT @parentId := (SELECT id FROM system_menu WHERE name LIKE '订单');
INSERT INTO jiedao.system_menu
(name, permission, menu_type, sort, parent_id, `path`, icon, component, status, creator, create_time, updater, update_time, deleted, is_show_in_menu_bar, name_en, keepalive, redirect, badge_field)
VALUES('重泡货操作权限', '', 1, 1, @parentId, 'order pao buttons', '#', NULL, 0, '1', '2024-11-20 17:16:53', '1', '2024-11-20 17:16:53', 0, 0, 'Order PAO Buttons', 0, NULL, NULL);
SELECT @parentId := (SELECT id FROM system_menu WHERE name LIKE '重泡货操作权限');
INSERT INTO jiedao.system_menu
(name, permission, menu_type, sort, parent_id, `path`, icon, component, status, creator, create_time, updater, update_time, deleted, is_show_in_menu_bar, name_en, keepalive, redirect, badge_field)
VALUES('设为半泡', 'ecw:weight_deal:half_throw', 3, 1, @parentId, '', '', '', 0, '1', '2024-11-20 17:22:48', '1', '2024-11-20 17:34:50', 0, 1, 'semi Bubble', 0, NULL, NULL);
INSERT INTO jiedao.system_menu
(name, permission, menu_type, sort, parent_id, `path`, icon, component, status, creator, create_time, updater, update_time, deleted, is_show_in_menu_bar, name_en, keepalive, redirect, badge_field)
VALUES('设为全泡', 'ecw:weight_deal:process', 3, 1, @parentId, '', '', '', 0, '1', '2024-11-20 17:25:46', '1', '2024-11-20 17:35:04', 0, 1, 'full Bubble', 0, NULL, NULL);
INSERT INTO jiedao.system_menu
(name, permission, menu_type, sort, parent_id, `path`, icon, component, status, creator, create_time, updater, update_time, deleted, is_show_in_menu_bar, name_en, keepalive, redirect, badge_field)
VALUES('设为普货', 'ecw:weight_deal:general_cargo', 3, 1, @parentId, '', '', '', 0, '1', '2024-11-20 17:28:52', '1', '2024-11-20 17:35:26', 0, 1, 'normal Cargo', 0, NULL, NULL);
ALTER TABLE system_dict_data ADD COLUMN label_fr VARCHAR(100) COMMENT '字典标签法文';
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(101, '客户放货推荐', '101', 'customer_source', 0, 'default', '', NULL, '1', '2024-11-19 10:34:42', '1', '2024-11-19 14:48:21', 0, 'Shipper Release', 'Libération Expéditeur');
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(5, '后台放货信息获得', '5', 'customer_from', 0, 'default', '', NULL, '1', '2024-11-25 18:20:55', '1', '2024-11-25 18:21:25', 0, 'Cargo', NULL);
This diff is collapsed.
-- 订单V值获取积分,首单修改成多选,添加全部选项
INSERT INTO jiedao.system_dict_type (name, `type`, status, remark, creator, create_time, updater, update_time, deleted) VALUES('是否选择', 'yes_or_no_or_all', 0, NULL, '1', '2024-12-06 10:39:28', '1', '2024-12-06 10:39:28', 0);
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(0, '是', '0', 'yes_or_no_or_all', 0, 'default', '', NULL, '1', '2024-12-06 10:51:10', '1', '2024-12-06 10:51:10', 0, 'YES', 'YES');
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(1, '否', '1', 'yes_or_no_or_all', 0, 'default', '', NULL, '1', '2024-12-06 10:51:42', '1', '2024-12-06 10:51:42', 0, 'NO', 'NO');
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(2, '不限', '2', 'yes_or_no_or_all', 0, 'default', '', NULL, '1', '2024-12-06 10:53:29', '1', '2024-12-06 10:53:29', 0, 'ALL', 'ALL');
-- 订单V值获取积分,客户方字典添加
INSERT INTO jiedao.system_dict_type (name, `type`, status, remark, creator, create_time, updater, update_time, deleted) VALUES('客户方', 'customer_side', 0, '客户方:1.发货人 2.收货人', '1', '2024-12-07 13:50:41', '1', '2024-12-07 13:50:41', 0);
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(0, '发货人', '1', 'customer_side', 0, 'default', '', NULL, '1', '2024-12-09 15:53:27', '1', '2024-12-09 15:53:27', 0, 'shipper', 'shipper');
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(0, '收货人', '2', 'customer_side', 0, 'default', '', NULL, '1', '2024-12-09 15:53:48', '1', '2024-12-09 15:53:48', 0, 'consignee', 'consignee');
-- app站内信,添加英文、法文字段
ALTER TABLE ecw_web_internal_message
ADD COLUMN title_en VARCHAR(255) COMMENT '标题英文',
ADD COLUMN title_fr VARCHAR(255) COMMENT '标题法文',
ADD COLUMN content_en LONGTEXT COMMENT '内容英文',
ADD COLUMN content_fr LONGTEXT COMMENT '内容法文';
-- 站内信为英法字段赋值
UPDATE ecw_web_internal_message
SET title_en = title,
title_fr = title,
content_en = content,
content_fr = content;
This diff is collapsed.
ALTER TABLE member_user_level_config
ADD COLUMN level INT COMMENT '等级',
ADD COLUMN status INT COMMENT '状态(0.未发布,1.已启用,2.已禁用,3.已过期)',
ADD COLUMN rule_number VARCHAR(20) COMMENT '规则编号',
ADD COLUMN validity_period INT COMMENT '等级有效期',
ADD COLUMN accumulation_period INT COMMENT '积分累计周期',
ADD COLUMN start_date DATETIME COMMENT '积分开始累计时间',
ADD COLUMN enable_date DATETIME COMMENT '启用日期',
ADD COLUMN start_time DATETIME COMMENT '等级规则有效期开始时间',
ADD COLUMN end_time DATETIME COMMENT '等级规则有效期结束时间',
ADD COLUMN description VARCHAR(200) COMMENT '等级说明',
ADD COLUMN sort INT COMMENT '匹配顺序(限制为数字)';
INSERT INTO jiedao.system_menu (name, permission, menu_type, sort, parent_id, `path`, icon, component, status, creator, create_time, updater, update_time, deleted, is_show_in_menu_bar, name_en, keepalive, redirect, badge_field) VALUES('会员等级设置', '', 2, 1, 1520, 'operatingLevel', '#', 'ecw/memberManagement/operatingLevel', 0, '1', '2024-12-13 14:37:24', '1', '2024-12-13 15:14:29', 0, 0, '会员等级设置', 0, NULL, NULL);
CREATE TABLE `jiedao`.`member_user_level_log`
(
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`config_id` bigint NOT NULL COMMENT '会员等级配置id',
`operator` VARCHAR(255) NOT NULL COMMENT '操作人',
`remarks` TEXT NULL COMMENT '备注',
`operate_type` INT NOT NULL COMMENT '操作类型',
`bpm_process_id` BIGINT NULL COMMENT '流程ID',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '会员等级日志表' ROW_FORMAT = Dynamic;
INSERT INTO jiedao.system_dict_type (name, `type`, status, remark, creator, create_time, updater, update_time, deleted) VALUES('会员等级', 'membership_levels', 0, NULL, '1', '2024-12-12 14:03:26', '1', '2024-12-12 14:09:37', 0);
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(0, '青铜会员', '1', 'membership_levels', 0, 'default', '', NULL, '1', '2024-12-12 14:10:46', '1', '2024-12-12 14:17:06', 0, 'Bronze Member', 'Bronze Member');
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(0, '银级会员', '2', 'membership_levels', 0, 'default', '', NULL, '1', '2024-12-12 14:14:17', '1', '2024-12-12 14:17:25', 0, 'Silver Member', 'Silver Member');
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(0, '黄金级会员', '3', 'membership_levels', 0, 'default', '', NULL, '1', '2024-12-12 14:15:09', '1', '2024-12-12 14:17:37', 0, 'Gold Member', 'Gold Member');
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(0, '白金级会员', '4', 'membership_levels', 0, 'default', '', NULL, '1', '2024-12-12 14:15:59', '1', '2024-12-12 14:17:48', 0, 'Platinum Member', 'Platinum Member');
INSERT INTO jiedao.system_dict_type
(name, `type`, status, remark, creator, create_time, updater, update_time, deleted)
VALUES('用户等级操作类型', 'member_user_operate_log', 0, NULL, '1', '2024-12-25 09:55:40', '1', '2024-12-25 09:55:40', 0);
INSERT INTO jiedao.system_dict_data
(sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr)
VALUES(0, '升级', '1', 'member_user_operate_log', 0, 'default', '', NULL, '1', '2024-12-25 09:58:31', '1', '2024-12-25 10:07:04', 0, 'Upgrade', 'Mise à niveau');
INSERT INTO jiedao.system_dict_data
(sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr)
VALUES(1, '降级', '2', 'member_user_operate_log', 0, 'default', '', NULL, '1', '2024-12-25 09:58:50', '1', '2024-12-25 10:06:59', 0, 'Downgrade', 'Rétrogradation');
INSERT INTO jiedao.system_dict_data
(sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr)
VALUES(2, '修改信息', '3', 'member_user_operate_log', 0, 'default', '', NULL, '1', '2024-12-25 09:59:24', '1', '2024-12-25 10:06:54', 0, 'Modify Information', 'Modifier les informations');
CREATE TABLE `jiedao`.`member_user_level_details`
(
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`config_id` bigint NOT NULL COMMENT '会员等级配置id',
`member_id` bigint NOT NULL COMMENT '会员id',
`level` INT NULL COMMENT '等级',
`validity_period` INT NULL COMMENT '等级有效期',
`specific_settings` bit(1) NOT NULL DEFAULT b'0' COMMENT '特殊设置(0关闭 1开启)',
`remarks` TEXT NULL COMMENT '备注',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '会员等级详情表' ROW_FORMAT = Dynamic;
CREATE TABLE `jiedao`.`member_user_level_operate_log`
(
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`config_id` bigint NOT NULL COMMENT '会员等级配置id',
`config_name` VARCHAR(255) NOT NULL COMMENT '会员等级配置名称',
`member_id` bigint NOT NULL COMMENT '会员id',
`operator` VARCHAR(255) NOT NULL COMMENT '操作人',
`remarks` TEXT NULL COMMENT '说明',
`level` INT COMMENT '等级',
`operate_type` INT NOT NULL COMMENT '操作类型',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '会员等级操作记录日志表' ROW_FORMAT = Dynamic;
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
-- 短信模板
INSERT INTO `jiedao`.`infra_job`(`name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES ('短信接收', 1, 'smsReceiveJob', '1', '0 0/30 * * * ?', 0, 0, 0, '1', '2024-11-21 11:57:39', '2741', '2024-11-25 11:36:19', b'0');
-- 控货订单多语言
ALTER TABLE ecw_order_control_log add type_en VARCHAR(64) comment '变更类型英文',add type_fr VARCHAR(64) comment '变更类型法文',add msg_en VARCHAR(1000) comment '变更描述英文',add msg_fr VARCHAR(1000) comment '变更描述法文';
UPDATE jiedao.system_need_know
SET
content_zh='<h2 class="ql-align-center" style="white-space: normal;">《控货权转移须知》</h2><p style="white-space: normal;"><br/></p><p>1、为保证控货的安全性,请仔细核对号码再进行货权转移处理,一经确认无法修改;</p><p>2、请填写正确的联系信息,以便及时接收有关货物动态的短信通知;</p><p>3、一经货权转移,默认原发货人已收齐货款,货权即转移给新的号码;</p><p>免责声明:捷道公司不对买卖双方的货款结算进行担保;</p><p style="white-space: normal;"><br/></p>',
content_en='<h2 class="ql-align-center" style="white-space: normal;">Notes on Transfer of on hold shipment</h2><p style="white-space: normal;"><br/></p><p>1. To ensure the safety of on hold goods , please carefully check the number before transferring the ownership of the goods. Once confirmed, it cannot be modified;</p><p>2. Please fill in the correct contact information so that you can receive SMS notifications about the dynamics of the goods in a timely manner;</p><p>3. Once the ownership of the goods is transferred, it is assumed that the original consignor has received the full payment, and the ownership of the goods will be transferred to the new number;</p><p>Disclaimer: E&C Company does not guarantee the payment settlement between the buyer and the seller;</p><p style="white-space: normal;"><br/></p>',
title_fr='控货权转移须知',
content_fr='<h2 class="ql-align-center" style="white-space: normal;">Notes sur le transfert de marchandises en contrôle</h2><p style="white-space: normal;"><br/></p><p>1. Pour garantir la sécurité des marchandises en contrôle, veuillez vérifier attentivement le numéro de destinataire avant de transférer la propriété des marchandises. Une fois confirmé, il ne pourra plus être modifié.</p><p>2. Veuillez renseigner les coordonnées correctes afin de recevoir des notifications SMS concernant les mouvements des marchandises en temps opportun.</p><p>3. Une fois que la propriété des marchandises transférée, il est supposé que l’expéditeur initial a reçu le paiement intégral, et la propriété des marchandises sera transférée au nouveau numéro de destinataire.</p><p>Clause de non-responsabilité : La société E&C ne garantit pas le règlement des paiements entre l’acheteur et le vendeur.</p><p style="white-space: normal;"><br/></p>'
WHERE know_type='controltransfer';
UPDATE jiedao.system_need_know
SET
content_zh='<h2 class="ql-align-center" style="white-space: normal;">《捷道放货须知》</h2><p>请您仔细阅读我们的放货须知,如果您对此须知中有任何部分存在疑问,请联系我司客服,如您已确认放货表示您已清楚我司控放货流程及风险。</p><p><br/></p><p>1. 请仔细核对入仓号/提货单号及放货号码再进行放货处理;</p><p>2. 一经系统操作确认放货,则表明我司已获得您的授权,我司将根据约定向收货人放货;</p><p>3. 如电话号码填错,请在当天12小时内联系我司,我司尽可能协助挽回,如无法追回,捷道不承担由发货人提供错误号码导致的损失;</p><p>4. 捷道公司经授权放货不对买卖双方的货款结算进行担保;</p><p><br/></p>',
content_en='<h2 class="ql-align-center" style="white-space: normal;">E&C release instructions</h2><p>Please read our release instructions carefully. If you have any questions about any part of this notice, please contact our customer service. If you have confirmed the release of the goods, it means that you are aware of our release process and risks.</p><p><br/></p><p>1.Please carefully check the warehouse entry number/Packing list number and receiver number before releasing the goods.</p><p>2. Once the system operation confirms the release of the goods, it means that our company has obtained your authorization and we will release the goods to the consignee according to the agreement.</p><p>3. If the phone number is incorrect, please contact our company within 12 hours on the same day. Our company will try its best to help recover it. If it cannot be recovered, E&C will not bear the loss caused by the shipper providing the wrong number;</p><p>4. E&C Company does not guarantee the payment settlement between the buyer and the seller after authorized release;</p><p><br/></p>',
title_fr='控放货须知',
content_fr='<h2 class="ql-align-center" style="white-space: normal;">Instructions de libération E&C</h2><p>Veuillez lire attentivement nos instructions de libération. Si vous avez des questions concernant une partie de cet avis, veuillez contacter notre service client. Une fois que vous avez confirmé la libération des marchandises, cela signifie que vous êtes conscient de notre processus de libération et des risques associés.</p><p><br/></p><p>1.Veuillez vérifier soigneusement le numéro d''entrée en entrepôt / numéro de packing liste et le numéro du destinataire avant de libérer les marchandises.</p><p>2.Une fois que l''opération système confirme la libération des marchandises, cela signifie que notre entreprise a obtenu votre autorisation et nous libérerons les marchandises au destinataire conformément à l''accord.</p><p>3.Si le numéro de téléphone est incorrect, veuillez contacter notre entreprise dans un délai de 12 heures le jour même. Notre entreprise fera de son mieux pour aider à récupérer la situation. Si cela ne peut être récupéré, E&C ne sera pas responsable des pertes causées par l''expéditeur ayant fourni un numéro incorrect.</p><p>4.La société E&C ne garantit pas le règlement des paiements entre l''acheteur et le vendeur après la libération autorisée.</p><p><br/></p>'
WHERE know_type='control';
INSERT INTO jiedao.system_dict_type (name, `type`, status, remark, creator, create_time, updater, update_time, deleted) VALUES('开启状态', 'enable_status', 0, NULL, '1', '2024-12-12 14:24:01', '1', '2024-12-12 14:24:01', 0);
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(0, '未发布', '0', 'enable_status', 0, 'default', '', NULL, '1', '2024-12-12 14:24:47', '1', '2024-12-12 14:24:47', 0, 'Unreleased', 'Unreleased');
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(1, '已启用', '1', 'enable_status', 0, 'default', '', NULL, '1', '2024-12-12 14:25:15', '1', '2024-12-12 14:25:22', 0, 'Enabled', 'Enabled');
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(2, '已禁用', '2', 'enable_status', 0, 'default', '', NULL, '1', '2024-12-12 14:25:44', '1', '2024-12-12 14:25:44', 0, 'Disabled', 'Disabled');
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(3, '已过期', '3', 'enable_status', 0, 'default', '', NULL, '1', '2024-12-12 14:26:01', '1', '2024-12-12 14:26:01', 0, 'Expired', 'Expired');
ALTER TABLE member_user_level_details MODIFY COLUMN validity_period DATE NULL COMMENT '等级有效期';
\ No newline at end of file
UPDATE jiedao.system_dict_data SET label='目的港(放)',label_en='Shipper Release', label_fr='Libération Expéditeur' WHERE sort=101 and value =101 and dict_type ='customer_source';
\ No newline at end of file
ALTER TABLE member_user_level_config MODIFY `icon` varchar(255) COMMENT '图标';
-- 【后台-会员详情-】详情、更新 这两个按钮没有实现配置权限需求
INSERT INTO `jiedao`.`system_menu`(`name`, `permission`, `menu_type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `is_show_in_menu_bar`, `name_en`, `keepalive`, `redirect`, `badge_field`) VALUES ('会员等级详情', 'member:detail', 3, 7, 1521, '', '', '', 0, '2741', '2025-01-02 15:04:36', '2741', '2025-01-02 15:05:52', b'0', b'1', 'Member Detail', b'0', NULL, NULL);
INSERT INTO `jiedao`.`system_menu`(`name`, `permission`, `menu_type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `is_show_in_menu_bar`, `name_en`, `keepalive`, `redirect`, `badge_field`) VALUES ('会员等级详情更新', 'member:detail:update', 3, 8, 1521, '', '', '', 0, '2741', '2025-01-02 15:06:31', '2741', '2025-01-02 15:06:31', b'0', b'1', 'Member Detail Update', b'0', NULL, NULL);
This diff is collapsed.
ALTER TABLE member_user_level_details MODIFY COLUMN `config_id` bigint DEFAULT NULL COMMENT '会员等级配置id'
ALTER TABLE member_user_level_operate_log MODIFY COLUMN `config_id` bigint DEFAULT NULL COMMENT '会员等级配置id';
ALTER table member_user_level_operate_log MODIFY COLUMN `config_name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '会员等级配置名称';
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(0, '会员升级', 'levelUpdate', 'need_know_type', 0, 'default', '', NULL, '1', '2024-12-31 10:46:03', '1', '2024-12-31 11:09:39', 0, 'Membership Upgrade', 'Mise à niveau de l''adhésion');
INSERT INTO jiedao.system_need_know (know_type, title_zh, title_en, content_zh, content_en, status, creator, create_time, updater, update_time, deleted, title_fr, content_fr) VALUES('levelUpdate', '会员升级', 'Membership Upgrade', '<p><span style="text-wrap-mode: wrap;"></span><span style="text-wrap-mode: wrap;">尊敬的{username}, 恭喜您已升级成为我们{levelName}</span><span style="text-wrap-mode: wrap;">会员,会员权限将于</span>{validityPeriod}<span style="text-wrap-mode: wrap;">日到期;如有疑问请联系400-900-9962</span></p>', '<p>Dear {username}, congratulations on becoming our {levelName} member. Your membership will expire on {validityPeriod}. If you have any questions, please contact 400-900-9962</p>', 0, '1', '2024-12-31 10:52:05', '1', '2024-12-31 17:31:44', 0, 'Mise à niveau de l''adhésion', '<p>Cher {username}, félicitations pour devenir notre membre {levelName}. Votre adhésion expirera le {validityPeriod}. Si vous avez des questions, veuillez contacter 400-900-9962</p>');
SELECT @parentId := (SELECT id FROM system_menu WHERE name LIKE '重泡货操作权限');
INSERT INTO jiedao.system_menu (name, permission, menu_type, sort, parent_id, `path`, icon, component, status, creator, create_time, updater, update_time, deleted, is_show_in_menu_bar, name_en, keepalive, redirect, badge_field) VALUES('设为免泡', 'ecw:weight_deal:all_process', 3, 1, @parentId, '', '', '', 0, '1', '2025-01-03 15:48:57', '1', '2025-01-03 15:48:57', 0, 1, '设为免泡', 0, NULL, NULL);
\ No newline at end of file
ALTER TABLE ecw_banner_pop
ADD COLUMN title_fr VARCHAR(64) NULL COMMENT '法文标题',
ADD COLUMN html_web_fr TEXT NULL COMMENT 'web网页法文',
ADD COLUMN html_app_fr TEXT NULL COMMENT 'app网页法文';
\ No newline at end of file
INSERT INTO jiedao.system_dict_type (name, `type`, status, remark, creator, create_time, updater, update_time, deleted) VALUES('app订单状态', 'app_order_status', 0, 'app订单状态', '1', '2025-01-09 15:21:58', '1', '2025-01-21 10:40:24', 0);
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(0, '已取消', '6,7,88', 'app_order_status', 0, 'default', '', NULL, '1', '2025-01-09 15:22:41', '1', '2025-01-21 10:46:16', 0, 'Order canceled', 'Commande annulée');
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(1, '待入仓', '0,2,3', 'app_order_status', 0, 'default', '', NULL, '1', '2025-01-09 15:26:48', '1', '2025-01-21 10:47:04', 0, 'Order placed', 'Commande passée');
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(2, '已入仓', '5,10501,10502,10503,10504,8,9,10,11,132409', 'app_order_status', 0, 'default', '', NULL, '1', '2025-01-09 15:30:27', '1', '2025-01-21 10:47:26', 0, 'Received', 'Reçu');
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(3, '运输中', '132411,12325,12,13,132412,17', 'app_order_status', 0, 'default', '', NULL, '1', '2025-01-09 15:32:55', '1', '2025-01-21 11:16:05', 0, 'In shipment', 'Expédié');
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(4, '清关中', '118428,14,15,18', 'app_order_status', 0, 'default', '', NULL, '1', '2025-01-09 15:34:31', '1', '2025-01-21 11:16:38', 0, 'under clearing', 'En cours de règlement');
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(5, '可提货', '16', 'app_order_status', 0, 'default', '', NULL, '1', '2025-01-09 15:36:48', '1', '2025-01-21 11:17:07', 0, 'Cleared out', 'Régularisé');
INSERT INTO jiedao.system_dict_data (sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted, label_en, label_fr) VALUES(6, '已提货', '20,21', 'app_order_status', 0, 'default', '', NULL, '1', '2025-01-09 15:38:02', '1', '2025-01-21 11:17:32', 0, 'Collected', 'Collecté');
\ No newline at end of file
INSERT INTO `jiedao`.`system_dict_type`(`name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES ('短信限流', 'system_sms_limit', 0, NULL, '1', '2024-10-31 10:08:50', '1', '2024-10-31 10:08:50', b'0');
INSERT INTO `jiedao`.`system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`,`label_fr`) VALUES (1, '限流时间', '10,1', 'system_sms_limit', 0, 'default', '', '例:10,1(每天请求十次)', '2740', '2024-11-05 14:22:53', '2740', '2024-11-05 14:24:33', b'0', 'Current limiting time','Temps de limitation actuelle');
ALTER TABLE ecw_offer
ADD sale_stage tinyint comment '销售阶段',
ADD customer_status tinyint comment '客户状态',
ADD cargo_status tinyint comment '货物状态',
ADD inquiry_source tinyint comment '询盘来源',
ADD manufacturer VARCHAR(255) comment '厂家',
ADD manufacturer_phone VARCHAR(255) comment '厂家电话',
ADD reason_dict tinyint comment '原因数据字典',
ADD estimated_shipping_time datetime comment '预计发货时间';
INSERT INTO `jiedao`.`system_dict_type`(`name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES ('客户状态', 'ecw_offer_customer_status', 0, NULL, '1', '2025-02-11 10:08:50', '1', '2025-02-11 10:08:50', b'0');
INSERT INTO `jiedao`.`system_dict_type`(`name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES ('货物状态', 'ecw_offer_cargo_status', 0, NULL, '1', '2025-02-11 10:08:50', '1', '2025-02-11 10:08:50', b'0');
INSERT INTO `jiedao`.`system_dict_type`(`name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES ('询盘来源', 'ecw_offer_inquiry_source', 0, NULL, '1', '2025-02-11 10:08:50', '1', '2025-02-11 10:08:50', b'0');
INSERT INTO `jiedao`.`system_dict_type`(`name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES ('输单原因', 'ecw_offer_reason_dict', 0, NULL, '1', '2025-02-11 10:08:50', '1', '2025-02-11 10:08:50', b'0');
INSERT INTO `jiedao`.`system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`, `label_fr`) VALUES (3, '关系(指定)', '3', 'ecw_offer_reason_dict', 0, 'default', '', NULL, '2741', '2025-02-11 16:31:08', '2741', '2025-02-11 16:31:08', b'0', 'Specified Relationship', 'Relation Spécifiée');
INSERT INTO `jiedao`.`system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`, `label_fr`) VALUES (2, '服务', '2', 'ecw_offer_reason_dict', 0, 'default', '', NULL, '2741', '2025-02-11 16:30:46', '2741', '2025-02-11 16:30:46', b'0', 'Service', 'Service');
INSERT INTO `jiedao`.`system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`, `label_fr`) VALUES (1, '价格', '1', 'ecw_offer_reason_dict', 0, 'default', '', NULL, '2741', '2025-02-11 16:30:12', '2741', '2025-02-11 16:30:12', b'0', 'Price', 'Prix');
INSERT INTO `jiedao`.`system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`, `label_fr`) VALUES (6, '目的港线索', '6', 'ecw_offer_inquiry_source', 0, 'default', '', NULL, '2741', '2025-02-11 16:12:52', '2741', '2025-02-11 16:12:52', b'0', 'Destination Port Leads', 'Pistes du Port de Destination');
INSERT INTO `jiedao`.`system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`, `label_fr`) VALUES (5, '公海(注意下掉时间)', '5', 'ecw_offer_inquiry_source', 0, 'default', '', NULL, '2741', '2025-02-11 16:12:27', '2741', '2025-02-11 16:12:27', b'0', 'Open Sea (Note the Drop Time)', 'Mer Ouverte (Notez le Temps de Chute)');
INSERT INTO `jiedao`.`system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`, `label_fr`) VALUES (4, '市场部', '4', 'ecw_offer_inquiry_source', 0, 'default', '', NULL, '2741', '2025-02-11 16:12:00', '2741', '2025-02-11 16:12:00', b'0', 'Marketing Department', 'Département Marketing');
INSERT INTO `jiedao`.`system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`, `label_fr`) VALUES (3, '收货人推荐', '3', 'ecw_offer_inquiry_source', 0, 'default', '', NULL, '2741', '2025-02-11 16:11:25', '2741', '2025-02-11 16:11:25', b'0', 'Consignee Recommendation', 'Recommandation de Destinataire');
INSERT INTO `jiedao`.`system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`, `label_fr`) VALUES (2, '发货人推荐', '2', 'ecw_offer_inquiry_source', 0, 'default', '', NULL, '2741', '2025-02-11 16:10:58', '2741', '2025-02-11 16:10:58', b'0', 'Shipper Recommendation', 'Recommandation d\'Expéditeur');
INSERT INTO `jiedao`.`system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`, `label_fr`) VALUES (1, '成交客户复购', '1', 'ecw_offer_inquiry_source', 0, 'default', '', NULL, '2741', '2025-02-11 16:07:14', '2741', '2025-02-11 16:07:14', b'0', 'Repeat Purchase by Closed Customers', 'Achat Répété par Clients Fermés');
INSERT INTO `jiedao`.`system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`, `label_fr`) VALUES (4, '货好,尾款已付', '4', 'ecw_offer_cargo_status', 0, 'default', '', NULL, '2741', '2025-02-11 16:01:33', '2741', '2025-02-11 16:01:33', b'0', 'Goods ready, final payment made', 'Marchandises prêtes, paiement final effectué');
INSERT INTO `jiedao`.`system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`, `label_fr`) VALUES (3, '货好,未付尾款', '3', 'ecw_offer_cargo_status', 0, 'default', '', NULL, '2741', '2025-02-11 16:01:06', '2741', '2025-02-11 16:01:06', b'0', 'Goods ready, final payment not made', 'Marchandises prêtes, paiement final non effectué');
INSERT INTO `jiedao`.`system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`, `label_fr`) VALUES (2, '已下订金,货物生产中', '2', 'ecw_offer_cargo_status', 0, 'default', '', NULL, '2741', '2025-02-11 16:00:43', '2741', '2025-02-11 16:00:43', b'0', 'Deposit paid, goods in production', 'Acompte versé, production en cours');
INSERT INTO `jiedao`.`system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`, `label_fr`) VALUES (1, '未向工厂下单', '1', 'ecw_offer_cargo_status', 0, 'default', '', NULL, '2741', '2025-02-11 16:00:19', '2741', '2025-02-11 16:00:19', b'0', 'Order not placed with the factory', 'Commande non passée à l\'usine');
INSERT INTO `jiedao`.`system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`, `label_fr`) VALUES (6, '回访', '6', 'ecw_offer_customer_status', 0, 'default', '', NULL, '2741', '2025-02-11 15:57:13', '2741', '2025-02-11 15:57:13', b'0', 'Follow-up Visit', 'Visite de Suivi');
INSERT INTO `jiedao`.`system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`, `label_fr`) VALUES (5, '增量', '5', 'ecw_offer_customer_status', 0, 'default', '', NULL, '2741', '2025-02-11 15:56:52', '2741', '2025-02-11 15:56:52', b'0', 'Increment', 'Incrément');
INSERT INTO `jiedao`.`system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`, `label_fr`) VALUES (4, '流失', '4', 'ecw_offer_customer_status', 0, 'default', '', NULL, '2741', '2025-02-11 15:54:07', '2741', '2025-02-11 15:54:07', b'0', 'Loss', 'Perte');
INSERT INTO `jiedao`.`system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`, `label_fr`) VALUES (3, '轻货', '3', 'ecw_offer_customer_status', 0, 'default', '', NULL, '2741', '2025-02-11 15:52:32', '2741', '2025-02-11 15:52:32', b'0', 'Light Cargo', 'Marchandises Légères');
INSERT INTO `jiedao`.`system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`, `label_fr`) VALUES (2, '重货', '2', 'ecw_offer_customer_status', 0, 'default', '', NULL, '2741', '2025-02-11 15:52:10', '2741', '2025-02-11 15:52:10', b'0', 'Heavy Cargo', 'Marchandises Lourdes');
INSERT INTO `jiedao`.`system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`, `label_fr`) VALUES (1, '线索', '1', 'ecw_offer_customer_status', 0, 'default', '', NULL, '2741', '2025-02-11 15:50:47', '2741', '2025-02-11 15:50:47', b'0', 'Clue', 'Indice');
ALTER TABLE ecw_offer
modify COLUMN `remarks` text COMMENT '备注';
CREATE TABLE IF NOT EXISTS `ecw_currency_rate` (
`id` BIGINT AUTO_INCREMENT,
`source_id` BIGINT NOT NULL COMMENT '原币种',
`target_id` BIGINT NOT NULL COMMENT '支付币种',
`source_amount` DECIMAL(14, 4) NOT NULL COMMENT '原币种金额',
`target_amount` DECIMAL(14, 4) NOT NULL COMMENT '支付币种金额',
`countries` JSON NOT NULL COMMENT '国家',
`expiration` DATE NOT NULL COMMENT '有效日期',
`remarks` VARCHAR(255) NULL COMMENT '备注',
`creator` VARCHAR(32) NOT NULL COMMENT '创建者',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
`updater` VARCHAR(32) NOT NULL COMMENT '更新者',
`update_time` DATETIME NOT NULL COMMENT '更新时间',
`deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`)
) COMMENT '币种汇率表';
CREATE TABLE IF NOT EXISTS `ecw_currency_rate_log` (
`id` BIGINT AUTO_INCREMENT,
`rate_id` BIGINT NOT NULL COMMENT '汇率编号',
`source_amount1` DECIMAL(14, 4) NOT NULL COMMENT '修改前原币种金额',
`source_amount2` DECIMAL(14, 4) NOT NULL COMMENT '修改后原币种金额',
`target_amount1` DECIMAL(14, 4) NOT NULL COMMENT '修改前支付币种金额',
`target_amount2` DECIMAL(14, 4) NOT NULL COMMENT '修改后支付币种金额',
`expiration1` DATE NOT NULL COMMENT '修改前有效期',
`expiration2` DATE NOT NULL COMMENT '修改后有效期',
`remarks` VARCHAR(255) NULL COMMENT '备注',
`creator` VARCHAR(32) NOT NULL COMMENT '创建者',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
`updater` VARCHAR(32) NOT NULL COMMENT '更新者',
`update_time` DATETIME NOT NULL COMMENT '更新时间',
`deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`)
) COMMENT '币种汇率变更表';
BEGIN;
INSERT INTO `system_dict_type` (`name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`)
VALUES ('货币汇率状态', 'currency_rate_status', 0, NULL, '1', '2022-05-23 23:29:07', '1', '2022-05-23 23:34:59', b'0');
INSERT INTO `system_dict_data`
(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `label_en`)
VALUES
(0, '已过期', '1', 'currency_rate_status', 0, 'warning', '', NULL, '1', '2022-11-18 00:18:34', '1', '2023-01-15 18:09:43', b'0', 'Expired'),
(1, '生效中', '0', 'currency_rate_status', 0, 'warning', '', NULL, '1', '2022-11-18 00:18:34', '1', '2023-01-15 18:09:43', b'0', 'Active');
SET @parent = 1244;
INSERT INTO `system_menu` (`name`, `permission`, `menu_type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `is_show_in_menu_bar`, `name_en`, `keepalive`, `redirect`)
VALUES ('货币汇率', 'ecw:currency:rate:query', 2, 3, @parent, 'currencyRate', 'money', 'ecw/currencyRate/index', 0, '115', '2023-07-09 16:02:32', '115', '2023-07-12 22:33:09', b'0', b'1', 'currency rate', b'0', NULL);
SET @parent = LAST_INSERT_ID();
INSERT INTO `system_menu`
(`name`, `permission`, `menu_type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `is_show_in_menu_bar`, `name_en`, `keepalive`, `redirect`)
VALUES
('货币汇率新增', 'ecw:currency:rate:create', 3, 1, @parent, '', '', '', 0, '115', '2023-07-09 16:02:32', '115', '2023-07-12 22:33:09', b'0', b'0', 'create', b'0', NULL),
('货币汇率编辑', 'ecw:currency:rate:update', 3, 2, @parent, '', '', '', 0, '115', '2023-07-09 16:02:32', '115', '2023-07-12 22:33:09', b'0', b'0', 'update', b'0', NULL),
('货币汇率删除', 'ecw:currency:rate:delete', 3, 3, @parent, '', '', '', 0, '115', '2023-07-09 16:02:32', '115', '2023-07-12 22:33:09', b'0', b'0', 'delete', b'0', NULL),
('货币汇率日志', 'ecw:currency:rate:history', 3, 4, @parent, '', '', '', 0, '115', '2023-07-09 16:02:32', '115', '2023-07-12 22:33:09', b'0', b'0', 'history', b'0', NULL);
COMMIT;
\ No newline at end of file
ALTER TABLE ecw_offer
add COLUMN `special_offers` varchar(255) COMMENT '优惠信息';
update ecw_customer_followup set sale_stage=0 where sale_stage in (1,2)
update ecw_customer_followup set sale_stage=1 where sale_stage in (3,4,8);
update ecw_customer_followup set sale_stage=2 where sale_stage =6;
update ecw_customer_followup set sale_stage=3 where sale_stage =7;
update ecw_customer_followup set sale_stage=4 where sale_stage in (5,9) ;
update ecw_customer_followup set sale_stage=5 where sale_stage =10;
update ecw_customer_followup set sale_stage=6 where sale_stage =11;
update ecw_customer_followup set sale_stage=7 where sale_stage =14;
update ecw_customer_followup set sale_stage=8 where sale_stage =12;
update ecw_customer_followup set sale_stage=9 where sale_stage =13;
......@@ -21,6 +21,7 @@
<knife4j.version>3.0.2</knife4j.version>
<swagger-annotations.version>1.5.22</swagger-annotations.version>
<servlet.versoin>2.5</servlet.versoin>
<okhttp.version>4.9.3</okhttp.version>
<!-- DB 相关 -->
<mysql.version>5.1.46</mysql.version>
<druid.version>1.2.9</druid.version>
......@@ -51,6 +52,7 @@
<mapstruct.version>1.4.1.Final</mapstruct.version>
<hutool.version>5.6.1</hutool.version>
<pinyin4j.version>2.5.0</pinyin4j.version>
<jackson.version>2.16.1</jackson.version>
<!--修改版本 2.2.7 -->
<easyexcel.verion>2.2.7</easyexcel.verion>
<ooxml.verion>1.0</ooxml.verion>
......@@ -436,6 +438,29 @@
<artifactId>ueditor-spring-boot-starter</artifactId>
<version>${ueditor.version}</version>
</dependency>
<!-- okhttp -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${okhttp.version}</version>
</dependency>
<!-- jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- xml -->
</dependencies>
</dependencyManagement>
</project>
......@@ -406,11 +406,16 @@ public class CodeUtils {
* * ➢ 海空联运:22年发往莫桑比克的城市Maputo—JMSA2200001M——(国家+运输方式+年份+4位数字+城市)
* @return java.lang.String
*/
public static String getOddOrderNumbers(String maxOddOrderNumbers, String countryShort, String countryAirShort, String transportShort, String cityShort,
Boolean isExternalWarehouse, Boolean isConcentrateTransport) {
//定义变量(最新的单号)
public static String getOddOrderNumbers(String maxOddOrderNumbers,
String countryShort,
String countryAirShort,
String transportShort,
String cityShort,
Boolean isExternalWarehouse,
Boolean isConcentrateTransport) {
// 定义变量(最新的单号)
String newOddOrderNO = "";
//获取当前日期并将其进行格式化
// 获取当前日期并将其进行格式化
String formatDate = getDateTime("yy");
if (isExternalWarehouse == null) {
isExternalWarehouse = false;
......@@ -421,38 +426,91 @@ public class CodeUtils {
if (countryAirShort == null) {
countryAirShort = "";
}
//订单前缀(非空运和整柜订单)
StringBuilder orderPrefix = new StringBuilder();
orderPrefix.append(countryShort).append(transportShort).append(formatDate);
// 海运拼柜结尾参数是目的地城市代码,专线空运结尾参数是始发地城市代码
// TODO 整柜订单编号结尾参数暂时不存在,海空联运的结尾暂时同海运拼柜
int endIndex = (StringUtils.equals(transportShort, "A") ? 0 : cityShort.length());
//判断数据中的最大单号是否存在,是否包含当前日期
// 判断数据中的最大单号是否存在,是否包含当前日期
if (StringUtils.isNotEmpty(maxOddOrderNumbers) && maxOddOrderNumbers.contains(formatDate)) {
//截取后四位数
String endNum = StringUtils.equals(transportShort, "F") ? maxOddOrderNumbers.substring(5) :
(StringUtils.equals(transportShort, "SA") ? maxOddOrderNumbers.substring(isExternalWarehouse && isConcentrateTransport ? 6 : (isExternalWarehouse || isConcentrateTransport ? 5 : 4), maxOddOrderNumbers.length() - endIndex) :
(StringUtils.equals(transportShort, "A") ? maxOddOrderNumbers.substring(isExternalWarehouse && isConcentrateTransport ? 5 : (isExternalWarehouse || isConcentrateTransport ? 4 : 3), maxOddOrderNumbers.length() - endIndex) :
maxOddOrderNumbers.substring(isExternalWarehouse && isConcentrateTransport ? 6 : (isExternalWarehouse || isConcentrateTransport ? 5 : 4), maxOddOrderNumbers.length() - endIndex)));
//把截取的最后四位数解析为int
String endNum;
switch (transportShort) {
case "F":
endNum = maxOddOrderNumbers.substring(5);
break;
case "A":
int startIndexA = isExternalWarehouse && isConcentrateTransport ? 5 : (isExternalWarehouse || isConcentrateTransport ? 4 : 3);
endNum = maxOddOrderNumbers.substring(startIndexA, maxOddOrderNumbers.length() - endIndex);
break;
default:
int startIndexDefault;
if (isExternalWarehouse && isConcentrateTransport) {
startIndexDefault = 2+orderPrefix.length();
} else if (isExternalWarehouse || isConcentrateTransport) {
startIndexDefault = 1+orderPrefix.length();;
} else {
startIndexDefault = orderPrefix.length();;
}
endNum = maxOddOrderNumbers.substring(startIndexDefault, maxOddOrderNumbers.length() - endIndex);
break;
}
// 检查是否成功截取
if (endNum == null || endNum.isEmpty()) {
throw new IllegalArgumentException("Invalid maxOddOrderNumbers format");
}
// 把截取的最后四位数解析为int
int endIntNum = Integer.parseInt(endNum);
//在将其加1(自增1)
int newEndIntNum = (StringUtils.equals(transportShort, "SA") ? 10000 : 100000) + endIntNum + 1;
//把10000或100000的1去掉,获取到最新的后5位
// 在将其加1(自增1)
int base = 100000;
int newEndIntNum = base + endIntNum + 1;
// 把10000或100000的1去掉,获取到最新的后5位
String newEndNum = String.valueOf(newEndIntNum).substring(1);
//生成单号
newOddOrderNO = StringUtils.equals(transportShort, "F") ? "ECF" + formatDate + newEndNum :
(isExternalWarehouse ? "X" : "") + (isConcentrateTransport ? "J" : "") +
(StringUtils.equals(transportShort, "A") ? transportShort + formatDate + newEndNum + countryAirShort : countryShort + transportShort + formatDate + newEndNum + cityShort);
//将单号返回
return newOddOrderNO;
// 生成单号
StringBuilder newOddOrderNOBuilder = new StringBuilder();
if (StringUtils.equals(transportShort, "F")) {
newOddOrderNOBuilder.append("ECF").append(formatDate).append(newEndNum);
} else {
if (isExternalWarehouse) {
newOddOrderNOBuilder.append("X");
}
if (isConcentrateTransport) {
newOddOrderNOBuilder.append("J");
}
if (StringUtils.equals(transportShort, "A")) {
newOddOrderNOBuilder.append(transportShort).append(formatDate).append(newEndNum).append(countryAirShort);
} else {
newOddOrderNOBuilder.append(countryShort).append(transportShort).append(formatDate).append(newEndNum).append(cityShort);
}
}
newOddOrderNO = newOddOrderNOBuilder.toString();
} else {
//如果为空(第一次生成)或者当前最大订单号的日期与当前日期不一致说明需要重新计数生成单号
newOddOrderNO = StringUtils.equals(transportShort, "F") ? "ECF" + formatDate + "00001" :
(isExternalWarehouse ? "X" : "") + (isConcentrateTransport ? "J" : "") +
(StringUtils.equals(transportShort, "A") ? transportShort + formatDate + "00001" + countryAirShort : countryShort + transportShort + formatDate + "00001" + cityShort);
//将单号返回
return newOddOrderNO;
// 如果为空(第一次生成)或者当前最大订单号的日期与当前日期不一致说明需要重新计数生成单号
StringBuilder newOddOrderNOBuilder = new StringBuilder();
if (StringUtils.equals(transportShort, "F")) {
newOddOrderNOBuilder.append("ECF").append(formatDate).append("00001");
} else {
if (isExternalWarehouse) {
newOddOrderNOBuilder.append("X");
}
if (isConcentrateTransport) {
newOddOrderNOBuilder.append("J");
}
if (StringUtils.equals(transportShort, "A")) {
newOddOrderNOBuilder.append(transportShort).append(formatDate).append("00001").append(countryAirShort);
} else {
newOddOrderNOBuilder.append(countryShort).append(transportShort).append(formatDate).append("00001").append(cityShort);
}
}
newOddOrderNO = newOddOrderNOBuilder.toString();
}
return newOddOrderNO;
}
/**
* 根据订单编号生成条纹编码
*
......
......@@ -3,6 +3,9 @@ package cn.iocoder.yudao.framework.common.util.date;
import cn.hutool.core.date.DateUtil;
import java.time.Duration;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
......@@ -167,4 +170,24 @@ public class DateUtils {
calendar.add(Calendar.DAY_OF_MONTH, days);
return calendar.getTime();
}
/**
* 解析并转换时间为本地时间
* 本方法将给定的ISO 8601格式的日期时间字符串解析为日期对象,并转换为本地时间
*
* @param deliverTime ISO 8601格式的日期时间字符串
* @return 返回转换后的本地时间日期对象
*/
public static Date parseAndConvertToLocalDate(String deliverTime) {
// 定义 ISO 8601 格式的日期时间解析器
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX");
// 将字符串解析为 ZonedDateTime 对象
ZonedDateTime utcDateTime = ZonedDateTime.parse(deliverTime, formatter);
// 获取本地时区
ZoneId localZoneId = ZoneId.systemDefault();
// 将 UTC 时间转换为本地时间
ZonedDateTime localDateTime = utcDateTime.withZoneSameInstant(localZoneId);
// 将 ZonedDateTime 转换为 Date
return Date.from(localDateTime.toInstant());
}
}
......@@ -162,7 +162,7 @@ public class PhoneUtil {
try {
List<DictDataRespDTO> dtos = DictFrameworkUtils.listDictDatasFromCache("phone_number_rule");
if (CollUtil.isNotEmpty(dtos)) {
DictDataRespDTO dto = dtos.stream().filter(d -> d.getValue().trim().equals(code.trim())).findFirst().orElseGet(null);
DictDataRespDTO dto = dtos.stream().filter(d -> d.getValue().trim().equals(code.trim())).findFirst().orElse(null);
if (Objects.nonNull(dto)) {
// 优先获取中文
rule = dto.getLabel();
......@@ -171,9 +171,10 @@ public class PhoneUtil {
rule = dto.getLabelEn();
}
}
}else {
log.error("未获取到手机号自定义规则, code: %s, mobile: %s->", code, mobile);
}
}
catch (Exception e) {
} catch (Exception e) {
log.error(String.format("获取手机号规则失败, code: %s, mobile: %s->", code, mobile), e);
}
......
......@@ -19,6 +19,10 @@ public class DictDataRespDTO {
* 字典英文标签
*/
private String labelEn;
/**
* 字典法文标签
*/
private String labelFr;
/**
* 字典值
*/
......
package cn.iocoder.yudao.framework.http.collection;
import java.util.Collection;
/**
* 集合工具类
* @author Wenyi Feng
* @since 2018-10-15
*/
public class CollectionUtils {
/**
* 如果集合为{@code null}或者空,则返回{@code true}。
* 否则,返回{@code false}
*
* @param collection 待检查的集合
* @return 集合是否为空
*/
public static boolean isEmpty(Collection<?> collection) {
return collection == null || collection.isEmpty();
}
/**
* 判断数组是空数组
*
* @param array 待判断的数据
* @return true:空 / false:非空
*/
public static boolean isEmpty(String[] array) {
return array == null || array.length == 0;
}
/**
* 如果集合不为{@code null}或者空,则返回{@code true}。
* 否则,返回{@code false}
*
* @param collection 待检查的集合
* @return 集合是否不为空
*/
public static boolean isNotEmpty(Collection<?> collection) {
return !isEmpty(collection);
}
/**
* 判断数组不是空数组
*
* @param array 待判断的数据
* @return true:非空 / false:空
*/
public static boolean isNotEmpty(String[] array) {
return !isEmpty(array);
}
}
package cn.iocoder.yudao.framework.http.collection;
import java.util.Map;
/**
* Map工具类
* <ul>
* <li>判断Map是否为空</li>
* <li>判断Map是否不为空</li>
* </ul>
*
* @author Wenyi Feng
* @since 2018-11-17
*/
public class MapUtils {
/**
* 判断Map是否为空
*
* @param map 待判断的Map
* @return 是否为空,true:空;false:不为空
*/
public static boolean isEmpty(Map<?, ?> map) {
if (map == null){
return true;
}
return map.isEmpty();
}
/**
* 判断Map是否不为空
*
* @param map 待判断的Map
* @return 是否不为空,true:不为空;false:空
*/
public static boolean isNotEmpty(Map<?, ?> map) {
return !isEmpty(map);
}
}
package cn.iocoder.yudao.framework.http.convert;
import cn.iocoder.yudao.framework.http.util.StrUtils;
/**
* 进制转换工具类
* @author Wenyi Feng.
*/
public class HexUtils {
/**
* 二进制转十六进制
*
* @param bytes [ellipsis]
* @return [ellipsis]
*/
public static String bin2Hex(byte[] bytes) {
if (bytes == null || bytes.length == 0) {
return null;
}
StringBuilder sb = new StringBuilder();
for (byte aByte : bytes) {
String hex = Integer.toHexString(aByte & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
/**
* 16进制转化为 2进制
*
* @param hexStr 16进制字符串
* @return byte[]
*/
public static byte[] hex2Bin(String hexStr) {
if (StrUtils.isBlank(hexStr)) {
return null;
}
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i < hexStr.length() / 2; i++) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
}
\ No newline at end of file
package cn.iocoder.yudao.framework.http.convert;
import cn.iocoder.yudao.framework.http.util.StrUtils;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
/**
* 参数处理工具类
* @author Wenyi Feng
* @since 2018-10-28
*/
public class ParamUtils {
/**
* 将Map型转为请求参数型
*
* @param data Map类型的参数
* @return url请求的参数
* @throws UnsupportedEncodingException 异常
*/
public static String getUrlParamsByMap(Map<String, String> data) throws UnsupportedEncodingException {
if (data == null || data.isEmpty()) {
return null;
}
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> i : data.entrySet()) {
sb.append(i.getKey())
.append("=")
.append(URLEncoder.encode(i.getValue(), StandardCharsets.UTF_8.toString()))
.append("&");
}
String str = sb.toString();
return str.substring(0, str.length() - 1);
}
/**
* 将url参数转换成map
* @param param [ellipsis]
* @return 参数Map
*/
public static Map<String, String> getUrlParams(String param) {
Map<String, String> map = new HashMap<>();
if (StrUtils.isBlank(param)) {
return map;
}
String[] params = param.split("&");
for (String s : params) {
String[] p = s.split("=");
if (p.length == 2) {
map.put(p[0], p[1]);
}
}
return map;
}
}
package cn.iocoder.yudao.framework.http.core;
import cn.iocoder.yudao.framework.http.collection.MapUtils;
import cn.iocoder.yudao.framework.http.util.StrUtils;
import lombok.Getter;
import lombok.Setter;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSocketFactory;
import java.io.File;
import java.util.*;
/**
* 请求所需要参数
*
* @author Erwin Feng
* @since 2022-11-18
*/
@Getter
@Setter
public class Request {
private static final String PARAM_DEFAULT_KEY = "__default__";
/**
* 请求地址
*/
private String url;
/**
* 请求方式
*/
private Method method;
/**
* 请求参数
*/
@Getter
private Map<String, Object> param;
private ParamFormat paramFormat = ParamFormat.STRING;
private List<FileBo> fileList;
/**
* 请求工具
*/
private Util util = Util.OkHttp;
public enum ParamFormat {
STRING, FORM, JSON
}
/**
* 请求方法枚举
*/
public enum Method {
GET, POST, PUT, PATCH, DELETE
}
/**
* 请求工具枚举
*/
public enum Util {
// JDK,
OkHttp,
// AsyncHttpClient
}
/**
* 日志级别枚举
*/
public enum LogLevel {
DEBUG, INFO, ERROR
}
/**
* 创建 Request
*
* @param url 请求地址
* @param method 请求方法
* @param param 请求参数
* @return Request
*/
public static Request create(String url, Method method, String param) {
Request request = new Request();
request.setUrl(url);
request.setMethod(method);
request.setParam(param);
return request;
}
/**
* 创建 Request
*
* @param url 请求地址
* @param method 请求方法
* @param param 请求参数
* @return Request
*/
public static Request create(String url, Method method, Map<String, Object> param) {
Request request = new Request();
request.setUrl(url);
request.setMethod(method);
request.setParam(param);
return request;
}
/**
* 请求可选参数
*/
@Getter
@Setter
public static class Option {
/**
* 连接超时时间,秒,默认5秒
*/
private Integer connectTimeoutSecond = 5;
/**
* 读取超时时间,秒,默认45秒
*/
private Integer readTimeoutSecond = 45;
/**
* 请求头
*/
private Map<String, String> headers = new HashMap<>();
/**
* ssl
*/
private SSLSocketFactory sslContextFactory;
/**
* HostnameVerifier
*/
private HostnameVerifier hostnameVerifier;
/**
* 日志级别
*/
private LogLevel logLevel;
/**
* 创建 Request.Option
*
* @param connectTimeoutSecond 连接超时时间,秒
* @param readTimeoutSecond 读取超时时间,秒
* @return Request.Option
*/
public static Option create(Integer connectTimeoutSecond, Integer readTimeoutSecond) {
Option option = new Option();
Optional.ofNullable(connectTimeoutSecond).ifPresent(option::setConnectTimeoutSecond);
Optional.ofNullable(readTimeoutSecond).ifPresent(option::setReadTimeoutSecond);
return option;
}
/**
* 创建 Request.Option
*
* @param connectTimeoutSecond 连接超时时间,秒
* @param readTimeoutSecond 读取超时时间,秒
* @param headers http headers
* @return Request.Option
*/
public static Option create(Integer connectTimeoutSecond, Integer readTimeoutSecond, Map<String, String> headers) {
Option option = new Option();
Optional.ofNullable(connectTimeoutSecond).ifPresent(option::setConnectTimeoutSecond);
Optional.ofNullable(readTimeoutSecond).ifPresent(option::setReadTimeoutSecond);
Optional.ofNullable(headers).ifPresent(option::setHeaders);
return option;
}
}
public Request setParam(String param) {
if (StrUtils.isNotBlank(param)) {
Map<String, Object> map = new HashMap<>();
map.put(PARAM_DEFAULT_KEY, param);
this.param = map;
}
return this;
}
public Request setParam(Map<String, Object> map) {
this.param = map;
return this;
}
public Request bak(Map<String, Object> map) {
if (MapUtils.isEmpty(map)) {
return this;
}
StringJoiner stringJoiner = new StringJoiner("&", "", "");
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (StrUtils.isNotBlank(entry.getKey())) {
stringJoiner.add(entry.getKey() + "=" + entry.getValue());
}
}
String param = stringJoiner.toString();
return setParam(param);
}
public static class MediaConstant {
/**
* application/json
*/
public static final String APPLICATION_JSON_VALUE = "application/json";
/**
* application/...form...
*/
public static final String APPLICATION_FORM_VALUE = "application/x-www-form-urlencoded";
}
@Getter
@Setter
public static class FileBo {
private String paramName = "file";
private String fileName;
private File file;
}
}
\ No newline at end of file
package cn.iocoder.yudao.framework.http.core;
import lombok.Getter;
import lombok.Setter;
/**
* @author Erwin Feng
* @since 2022-11-24
*/
@Getter
@Setter
public class Response {
private int code;
private String msg;
private String body;
}
package cn.iocoder.yudao.framework.http.core.client;
import cn.iocoder.yudao.framework.http.core.Request;
import cn.iocoder.yudao.framework.http.core.Response;
import java.io.IOException;
import java.util.Objects;
/**
* HTTP 请求客户端 接口
*
* @author Erwin Feng
* @since 2022-11-24
*/
public interface HttpClient {
String PARAM_DEFAULT_KEY = "__default__";
/**
* 执行 http 请求
*
* @param request 请求
* @param option http 可选配置
* @return http 响应结果
* @throws IOException IO 异常
*/
Response execute(Request request, Request.Option option) throws IOException;
default Integer getTimeoutSecond(Integer timeoutSecond) {
if (Objects.nonNull(timeoutSecond) && timeoutSecond > 0) {
return timeoutSecond;
}
return null;
}
}
package cn.iocoder.yudao.framework.http.core.client;
import cn.iocoder.yudao.framework.http.core.Request;
import cn.iocoder.yudao.framework.http.core.client.impl.OkHttpClient;
/**
* HTTP CLIENT 工厂
*
* @author Erwin Feng
* @since 2022-11-24
*/
public class HttpClientFactory {
/**
* 获取 http client
*
* @param httpUtil http 工具
* @return http client 实现
*/
public static HttpClient get(Request.Util httpUtil) {
if (Request.Util.OkHttp == httpUtil) {
return new OkHttpClient();
} else {
throw new RuntimeException("not find http util: " + httpUtil.name());
}
}
}
package cn.iocoder.yudao.framework.http.exception;
import java.io.PrintWriter;
import java.io.StringWriter;
/**
* 异常工具类
*
* @author Erwin Feng
* @since 2020/8/13
*/
public class ExceptionUtils {
/**
* 获取异常栈信息
*
* @param throwable 异常
* @return 异常信息
*/
public static String getStackTrace(Throwable throwable) {
if (throwable == null) {
return "";
}
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw, Boolean.TRUE);
throwable.printStackTrace(pw);
return sw.getBuffer().toString();
}
}
package cn.iocoder.yudao.framework.http.sms;
import cn.iocoder.yudao.framework.http.core.Request;
import cn.iocoder.yudao.framework.http.core.Response;
import cn.iocoder.yudao.framework.http.util.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.Map;
/**
* BulksmsHttp 类用于处理与 Bulksms 相关的 HTTP 请求。
* 主要功能包括发送短信和设置短信参数。
*
* @author wuxian
* @since 2024-11-27
**/
@Slf4j
public class BulksmsHttp {
// 请求的URL地址
private static final String REQ_URL = "https://portal.nigeriabulksms.com/api/";
/**
* 发送请求到 Bulksms 服务器。
*
* @param param 请求参数
* @return 响应对象
*/
public Response sendReq(Map<String, Object> param) {
// 设置请求头
Map<String, String> header = new HashMap<>();
header.put("Accept", "text/html,application/xhtml+xml,application/xml");
header.put("Content-Type", "application/json");
// 发送POST请求
return HttpUtils.post(REQ_URL, param, header, Request.ParamFormat.FORM);
}
/**
* 设置发送短信的参数。
*
* @param mobiles 接收短信的手机号
* @param message 短信内容
* @param senderName 发送者名称
* @param username 用户名
* @param password 密码
* @return 参数映射
*/
public Map<String, Object> setParams(String mobiles, String message, String senderName, String username, String password) {
Map<String, Object> param = new HashMap<>();
param.put("username", username);
param.put("password", password);
param.put("mobiles", mobiles);
param.put("message", message);
param.put("sender", senderName);
return param;
}
public static void main(String[] args) {
BulksmsHttp test = new BulksmsHttp();
String mobiles = "2347087010202";
String sender = "ECLogistics";
String message = "Good day This is E&C logistics(ship from China to Nigeria),It has been a while since we last worked together,and we would like to reestablish our partnership. Our main service:GROUPAGE/FULL CONTAINER/AIR CARGO/COMPRESSING/CONSOLITAION .We value your business and would appreciate the opportunity to serve you once again.Have a Nice day! My WA :+861 592 035 652 7";
String username = "ecit@ewchina.net";
String password = "0z@@vtj1h";
Map<String, Object> param = test.setParams(mobiles, sender, message, username, password);
test.sendReq(param);
}
}
package cn.iocoder.yudao.framework.http.sms;
import cn.iocoder.yudao.framework.http.core.Request;
import cn.iocoder.yudao.framework.http.core.Response;
import cn.iocoder.yudao.framework.http.util.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.Map;
/**
* SendChampHttp类用于处理与SendChamp API相关的HTTP请求,以发送短信和获取短信状态
* 该类包含了构造请求参数和请求头的方法,以及执行HTTP请求的方法
*
* @author wuxian
* @since 2024-10-23
**/
@Slf4j
public class SendChampHttp {
// 定义发送短信的API URL
private static final String SMS_URL = "https://api.sendchamp.com/api/v1/sms/send";
// 定义获取短信状态的API URL前缀
private static final String RECEIVE_URL = "https://api.sendchamp.com/api/v1/sms/status/";
/**
* 发送POST请求以发送短信
*
* @param param 请求参数,包含短信的接收者、消息内容等
* @param header 请求头,包含API密钥等信息
* @return 返回API的响应结果
*/
public Response postReq(Map<String, Object> param, Map<String, String> header) {
return HttpUtils.post(SMS_URL, param, header, Request.ParamFormat.JSON);
}
/**
* 发送GET请求以获取短信发送状态
*
* @param header 请求头,包含API密钥等信息
* @param id 短信发送的唯一标识符
* @return 返回API的响应结果
*/
public Response getReceiveStatus(Map<String, String> header, String id) {
return HttpUtils.get(RECEIVE_URL + id, header, "");
}
/**
* 设置HTTP请求的头信息
*
* @param apiKey SendChamp API密钥
* @return 返回构造好的请求头Map对象
*/
public Map<String, String> setHeader(String apiKey) {
Map<String, String> header = new HashMap<>();
header.put("Accept", "application/json,text/plain,*/*");
header.put("Content-Type", "application/json");
header.put("Authorization", apiKey);
return header;
}
/**
* 设置发送短信的请求参数
*
* @param to 短信接收者的电话号码
* @param message 短信内容
* @param senderName 发送者名称
* @return 返回构造好的请求参数Map对象
*/
public Map<String, Object> setParams(String to, String message, String senderName) {
Map<String, Object> param = new HashMap<>();
param.put("to", to);
param.put("message", message);
param.put("sender_name", senderName);
param.put("route", "dnd");
return param;
}
public static void main(String[] args) {
SendChampHttp test = new SendChampHttp();
String to = "8618926674857";
String senderName = "ECLogistics";
String message = "Good day!This is E&C logistics(ship from China to Nigeria),It has been a while since we last worked together, and we would like to reestablish our partnership. Our main service: GROUPAGE/FULL CONTAINE";
Map<String, Object> param = test.setParams(to, message, senderName);
String apiKey = "Bearer sendchamp_live_$2a$10$vQPdaDjl96Ybc5tzFmZYg.nqGirXuJBGDqJArthZnFR8P9mM5Z/JO";
Map<String, String> header = test.setHeader(apiKey);
test.postReq(param, header);
// test.getReceiveStatus(header, "66e6e9df-b454-4df7-a968-af944a535757");
}
}
package cn.iocoder.yudao.framework.http.sms;
import cn.iocoder.yudao.framework.http.core.Request;
import cn.iocoder.yudao.framework.http.core.Response;
import cn.iocoder.yudao.framework.http.core.client.HttpClient;
import cn.iocoder.yudao.framework.http.core.client.HttpClientFactory;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author wuxian
* @since 2024-10-23
**/
@Slf4j
public class WhisperClientHttp {
public void testPost(){
// HttpResponse<String> response = Unirest.post("https://whispersms.xyz/api/send_message/")
// .header("Authorization", "Api_key gAAAAABl5ZDpoKnKVaK0scmWo7GQeKDA1sn3OZBeMXUz211vZv5QqSEtr7_LD5ISTqSD0PnWLRWavYmJ3nQJiutT-sgp0dyHR2HIL6FYEhD3t2CNuoHJoSIOia5ffo_rjfxW_pk8co0i7UMTYANNGxsRNJLQTu_Alw==")
// //.header("Authorization","Token 0371a29044432d36cc2508b7ce51e70f466c7d95")
// .header("Content-Type", "application/json")
// .body("{\"contacts\": [\"8618102810628\"],\"sender_id\": \"EC\",\"message\": \"say hello everybody.\",\"priority_route\": False,\"campaign_name\": \"mytest\"}")
// .asString();
// System.out.println("response is ------------------------>"+response.getBody());;
}
public void postReq(List<String> phonenums, String message){
HttpClient client = HttpClientFactory.get(Request.Util.OkHttp);
String sendUrl = "https://whispersms.xyz/whisper/send_message/";
//String sendUrl = "https://whispersms.xyz/api/send_message/";
Map<String, Object> param = new HashMap<>();
param.put("contacts",phonenums);
param.put("message",message);
param.put("sender_id","EC");
param.put("priority_route","False");
param.put("campaign_name","EClogistics");
Map<String, String> header = new HashMap<>();
//header.put("Accept","application/json,text/plain,*/*");
header.put("Content-Type", "application/json");
header.put("Authorization","Token 0371a29044432d36cc2508b7ce51e70f466c7d95");
//header.put("Authorization", "Api_key gAAAAABl5ZDpoKnKVaK0scmWo7GQeKDA1sn3OZBeMXUz211vZv5QqSEtr7_LD5ISTqSD0PnWLRWavYmJ3nQJiutT-sgp0dyHR2HIL6FYEhD3t2CNuoHJoSIOia5ffo_rjfxW_pk8co0i7UMTYANNGxsRNJLQTu_Alw==");
Request req = Request.create(sendUrl,Request.Method.POST,param);
req.setParamFormat(Request.ParamFormat.JSON);
try {
Response res = client.execute(req,Request.Option.create(0,0,header));
log.info("response code ---------------------------->"+res.getCode());
log.info("response content is --------------------》"+res.getBody());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args){
WhisperClientHttp test = new WhisperClientHttp();
//test.testPost();
List<String> phonenums = new ArrayList<>();
phonenums.add("8618102810628");
phonenums.add("2348140352000");
String message = "Good day !This is E&C logistics(ship from China to Nigeria) ,It has been a while since we last worked together, and we would like to reestablish our partnership. " +
"Our main service: GROUPAGE/FULL CONTAINER/AIR CARGO/COMPRESSING/CONSOLITAION ." +
"We value your business and would appreciate the opportunity to serve you once again." +
"Have a Nice day! My wa :+8615920356527";
test.postReq(phonenums,message);
//test.testPost();
}
}
package cn.iocoder.yudao.framework.http.sms;
import cn.iocoder.yudao.framework.http.core.Request;
import cn.iocoder.yudao.framework.http.core.Response;
import cn.iocoder.yudao.framework.http.util.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* YCloudWhatsappHttp类用于处理与 Whatsapp 相关的 HTTP 请求,以发送短信和获取短信状态。
*
* @author wuxian
* @since 2024-10-30
**/
@Slf4j
public class YCloudWhatsappHttp {
//请求地址
private static final String WA_URL = "https://api.ycloud.com/v2/whatsapp/messages/sendDirectly";
private static final String RECEIVE_URL = "https://api.ycloud.com/v2/whatsapp/messages/";
/**
* 发送WhatsApp消息
*
* @param header 请求头,包含认证信息
* @param param 请求参数,包含消息内容
* @return 响应结果
*/
public Response postWhatsapp(Map<String, String> header, Map<String, Object> param) {
return HttpUtils.post(WA_URL, param, header, Request.ParamFormat.JSON);
}
/**
* 获取消息发送状态
*
* @param header 请求头,包含认证信息
* @param id 消息ID
* @return 响应结果
*/
public Response getReceiveStatus(Map<String, String> header, String id) {
return HttpUtils.get(RECEIVE_URL + id, header, "");
}
/**
* 设置请求参数
*
* @param code 验证码
* @param templateName 模板名称
* @param lanCode 语言编号
* @param to 接收手机号
* @return 参数
*/
public Map<String, Object> setParams(String code, String templateName, String lanCode, String to) {
//构建模板参数
Map<String, Object> template = new HashMap<>();
Map<String, String> language = new HashMap<>();
Parameters parameters = new Parameters();
Button button = new Button();
button.setIndex("0");
button.setType("button");
button.setSub_type("url");
//模板包含语言(language)、组件(components),组件包含参数(parameters)
parameters.setType("text");
parameters.setText(code);
List<Object> list1 = new ArrayList<>();
list1.add(parameters);
//构建json中的组件
button.setParameters(list1);
List<Object> list2 = new ArrayList<>();
list2.add(new Components().setType("body").setParameters(list1));
list2.add(button);
language.put("code", lanCode);
language.put("policy", "deterministic");
template.put("language", language);
template.put("name", templateName);
template.put("components", list2);
//构建最终requestBody的json
Map<String, Object> param = new HashMap<>();
param.put("from", "8618022485824");
param.put("to", to);
param.put("type", "template");
param.put("template", template);
return param;
}
/**
* 设置请求头
*
* @param apiKey API密钥
* @return 请求头
*/
public Map<String, String> setHeader(String apiKey) {
//构建http请求的头
Map<String, String> header = new HashMap<>();
header.put("Accept", "application/json");
header.put("Content-Type", "application/json");
header.put("X-API-Key", apiKey);
return header;
}
public static void main(String[] args) {
YCloudWhatsappHttp test = new YCloudWhatsappHttp();
String apiKey = "9dbd912f56c101e53b23cb7b758ffda8";
String code = "8888";
String templateName = "ec_verification";
String lanCode = "en";
test.postWhatsapp(test.setHeader(apiKey), test.setParams(code, templateName, lanCode, "8618926674857"));
}
}
@lombok.Setter
@lombok.Getter
class Parameters {
private String type;
private String text;
}
@lombok.Setter
@lombok.Getter
class Components {
private String type;
private List<Object> parameters = null;
}
@lombok.Setter
@lombok.Getter
class Button {
private String type;
private String sub_type;
private String index;
private List<Object> parameters = null;
}
package cn.iocoder.yudao.framework.http.util;
import cn.iocoder.yudao.framework.http.core.Request;
import cn.iocoder.yudao.framework.http.core.Response;
import cn.iocoder.yudao.framework.http.core.client.HttpClient;
import cn.iocoder.yudao.framework.http.core.client.HttpClientFactory;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
/**
* Http 工具类
*
* @author Jayden
* @date 2024/11/28
*/
@Slf4j
public class HttpUtils {
// 创建一个HttpClient实例,用于执行HTTP请求
private static final HttpClient HTTP_CLIENT = HttpClientFactory.get(Request.Util.OkHttp);
/**
* 发送POST请求并返回响应结果
*
* @param url 请求的URL地址
* @param params 请求参数,键值对形式
* @param headers 请求头,键值对形式
* @param paramFormat 请求参数的格式
* @return Response对象,包含响应结果
*/
public static Response post(String url, Map<String, Object> params, Map<String, String> headers, Request.ParamFormat paramFormat) {
// 创建请求对象,指定URL、请求方法和参数
Request request = Request.create(url, Request.Method.POST, params);
request.setParamFormat(paramFormat);
try {
// 执行请求并获取响应
Response response = HTTP_CLIENT.execute(request, Request.Option.create(0, 0, headers));
// 记录响应码和响应内容
log.info("response code ---------------------------->" + response.getCode());
log.info("response content is --------------------》" + response.getBody());
return response;
} catch (Exception e) {
// 记录错误信息并抛出运行时异常
log.error("Error executing POST request: " + e.getMessage(), e);
throw new RuntimeException("Error executing POST request: " + e.getMessage(), e);
}
}
/**
* 执行GET请求
*
* @param url 请求的URL
* @param headers 请求头,键值对形式
* @return 返回响应对象,包含响应码、响应内容等信息
* @throws RuntimeException 如果执行请求时发生异常,则抛出运行时异常
*/
public static Response get(String url, Map<String, String> headers, String param) {
// 创建请求对象,指定URL和请求方法
Request request = Request.create(url, Request.Method.GET, param);
try {
// 执行请求并获取响应
Response response = HTTP_CLIENT.execute(request, Request.Option.create(0, 0, headers));
// 记录响应码和响应内容
log.info("response code ---------------------------->" + response.getCode());
log.info("response content is --------------------》" + response.getBody());
return response;
} catch (Exception e) {
// 记录错误信息并抛出运行时异常
log.error("Error executing GET request: " + e.getMessage(), e);
throw new RuntimeException("Error executing GET request: " + e.getMessage(), e);
}
}
}
......@@ -65,7 +65,7 @@ public class I18nMessage {
* @return
*/
public static String getMessage(String message, Integer lang) {
Locale locale = lang == 0 ? Locale.SIMPLIFIED_CHINESE : Locale.ENGLISH;
Locale locale = Languages.getLocaleByCode(lang);
try {
return accessor.getMessage(message, locale);
} catch (Exception e) {
......
......@@ -19,7 +19,11 @@ public enum LangEnum {
ZH("zh", 0),
/*** 英文 */
EN("en", 1);
EN("en", 1),
/*** 法文 */
FR("fr", 2);
private String language;
......
package cn.iocoder.yudao.framework.i18n.core;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Locale;
@Getter
public enum Languages {
SIMPLIFIED_CHINESE(0, Locale.SIMPLIFIED_CHINESE),
ENGLISH(1, Locale.ENGLISH),
// 集成法语
FRENCH(2, Locale.FRENCH);
private int code;
private Locale locale;
Languages(int code, Locale locale) {
this.code = code;
this.locale = locale;
}
public int getCode() {
return code;
}
public Locale getLocale() {
return locale;
}
public static Locale getLocaleByCode(int code) {
for (Languages languages : values()) {
if (languages.getCode() == code) {
return languages.getLocale();
}
}
// 默认返回简体中文
return SIMPLIFIED_CHINESE.getLocale();
}
}
......@@ -2,6 +2,7 @@ package cn.iocoder.yudao.framework.idempotent.core.aop;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.yudao.framework.i18n.core.I18nMessage;
import cn.iocoder.yudao.framework.idempotent.core.annotation.Idempotent;
import cn.iocoder.yudao.framework.idempotent.core.keyresolver.IdempotentKeyResolver;
import cn.iocoder.yudao.framework.idempotent.core.redis.IdempotentRedisDAO;
......@@ -49,7 +50,7 @@ public class IdempotentAspect {
// 锁定失败,抛出异常
if (!success) {
log.info("[beforePointCut][方法({}) 参数({}) 存在重复请求]", joinPoint.getSignature().toString(), joinPoint.getArgs());
throw new ServiceException(GlobalErrorCodeConstants.REPEATED_REQUESTS.getCode(), idempotent.message());
throw new ServiceException(GlobalErrorCodeConstants.REPEATED_REQUESTS.getCode(), I18nMessage.getMessage(GlobalErrorCodeConstants.REPEATED_REQUESTS.getMsg()));
}
}
......
......@@ -111,6 +111,8 @@ public class YudaoMQAutoConfiguration {
.autoAcknowledge(false) // 不自动 ack
.cancelOnError(throwable -> false); // 默认配置,发生异常就取消消费,显然不符合预期;因此,我们设置为 false
container.register(builder.build(), listener);
log.info("[redisMessageListenerContainer][注册 streamKey({}) 对应的监听器({})]",
listener.getStreamKey(), listener.getClass().getName());
});
return container;
}
......
package cn.iocoder.yudao.framework.security.core.util;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
* RSA加密解密
*
* @author jayden
**/
public class RsaUtils
{
// Rsa 私钥
public static String privateKey = "MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEA4TgukNwXxZ16sdy26bXMlCLLZMz4PlVYEQjGf2S/P0YvkDqSLxxaTTFpy83ZGizimYebnvfLtMmLzG/9gemVuwIDAQABAkA7X3E/NRZ7PTnEO9hookmtX8LY7wQegqc1zmdt3CRizGJRB7/9LzDqvnOIvqqm+EoiZLjUUNKVkOom0FI2u32hAiEA8UtmegwiMaqmE4xrjqocLRAR0aVWV7i4fSTcSvLVCcsCIQDu8fvGY9wfVKEGgyfcJHuORowDAbYYXOulxC6sEW7l0QIgE1J2Yk+WbWO86NPVyRbWKsWep6sVvvCL1XmeKmJHrQECIQDGAEmVbTyDzdodjmNiXezwye7NswZVC/LNi1LtjQircQIhAIpF1rvPvxXkE7KvWTePrCWeU/+c6e1ylG7sPYumc1cx";
/**
* 私钥解密
*
* @param text 待解密的文本
* @return 解密后的文本
*/
public static String decryptByPrivateKey(String text) throws Exception
{
return decryptByPrivateKey(privateKey, text);
}
/**
* 公钥解密
*
* @param publicKeyString 公钥
* @param text 待解密的信息
* @return 解密后的文本
*/
public static String decryptByPublicKey(String publicKeyString, String text) throws Exception
{
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] result = cipher.doFinal(Base64.decodeBase64(text));
return new String(result);
}
/**
* 私钥加密
*
* @param privateKeyString 私钥
* @param text 待加密的信息
* @return 加密后的文本
*/
public static String encryptByPrivateKey(String privateKeyString, String text) throws Exception
{
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] result = cipher.doFinal(text.getBytes());
return Base64.encodeBase64String(result);
}
/**
* 私钥解密
*
* @param privateKeyString 私钥
* @param text 待解密的文本
* @return 解密后的文本
*/
public static String decryptByPrivateKey(String privateKeyString, String text) throws Exception
{
PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] result = cipher.doFinal(Base64.decodeBase64(text));
return new String(result);
}
/**
* 公钥加密
*
* @param publicKeyString 公钥
* @param text 待加密的文本
* @return 加密后的文本
*/
public static String encryptByPublicKey(String publicKeyString, String text) throws Exception
{
X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] result = cipher.doFinal(text.getBytes());
return Base64.encodeBase64String(result);
}
/**
* 构建RSA密钥对
*
* @return 生成后的公私钥信息
*/
public static RsaKeyPair generateKeyPair() throws NoSuchAlgorithmException
{
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(512);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded());
String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
return new RsaKeyPair(publicKeyString, privateKeyString);
}
/**
* RSA密钥对对象
*/
public static class RsaKeyPair
{
private final String publicKey;
private final String privateKey;
public RsaKeyPair(String publicKey, String privateKey)
{
this.publicKey = publicKey;
this.privateKey = privateKey;
}
public String getPublicKey()
{
return publicKey;
}
public String getPrivateKey()
{
return privateKey;
}
}
}
package cn.iocoder.yudao.framework.sms.core.client;
import cn.iocoder.yudao.framework.common.util.json.core.KeyValue;
import cn.iocoder.yudao.framework.sms.core.client.dto.SmsReceiveRespDTO;
import cn.iocoder.yudao.framework.sms.core.client.dto.SmsSendRespDTO;
import cn.iocoder.yudao.framework.sms.core.client.dto.SmsTemplateRespDTO;
import cn.iocoder.yudao.framework.sms.core.client.dto.*;
import java.util.List;
......@@ -25,15 +23,27 @@ public interface SmsClient {
/**
* 发送消息
*
* @param logId 日志编号
* @param mobile 手机号
* @param apiTemplateId 短信 API 的模板编号
* @param logId 日志编号
* @param mobile 手机号
* @param apiTemplateId 短信 API 的模板编号
* @param templateParams 短信模板参数。通过 List 数组,保证参数的顺序
* @return 短信发送结果
*/
SmsCommonResult<SmsSendRespDTO> sendSms(Long logId, String mobile, String apiTemplateId,
List<KeyValue<String, Object>> templateParams);
/**
* 发送消息
*
* @param logId 日志编号
* @param mobile 手机号
* @param smsTemplateDTO 模板
* @param templateParams 短信模板参数。通过 List 数组,保证参数的顺序
* @return 短信发送结果
*/
SmsCommonResult<SmsSendRespDTO> sendSmsV2(Long logId, String mobile, SmsTemplateDTO smsTemplateDTO,
List<KeyValue<String, Object>> templateParams);
/**
* 解析接收短信的接收结果
*
......@@ -51,4 +61,9 @@ public interface SmsClient {
*/
SmsCommonResult<SmsTemplateRespDTO> getSmsTemplate(String apiTemplateId);
/**
* 查询短信发送状态
*
*/
SmsLogDTO getReceiveStatus(SmsLogDTO smsLogDO);
}
......@@ -11,9 +11,9 @@ import lombok.ToString;
/**
* 短信的 CommonResult 拓展类
*
* <p>
* 考虑到不同的平台,返回的 code 和 msg 是不同的,所以统一额外返回 {@link #apiCode} 和 {@link #apiMsg} 字段
*
* <p>
* 另外,一些短信平台(例如说阿里云、腾讯云)会返回一个请求编号,用于排查请求失败的问题,我们设置到 {@link #apiRequestId} 字段
*
* @author 捷道源码
......@@ -25,7 +25,7 @@ public class SmsCommonResult<T> extends CommonResult<T> {
/**
* API 返回错误码
*
* <p>
* 由于第三方的错误码可能是字符串,所以使用 String 类型
*/
private String apiCode;
......
package cn.iocoder.yudao.framework.sms.core.client.dto;
import lombok.Data;
/**
* SendChamp发送返回结果
*
* 该类用于封装SendChamp发送操作的返回结果,包括发送状态码、数据信息、错误信息等
* 主要用于处理和解析SendChamp API的响应内容
*
* @author Jayden
* @date 2024/11/23
*/
@Data
public class SendChampResult {
// 响应状态码,用于表示发送操作的结果状态
private int code;
// 发送数据信息,包括发送消息的ID、业务ID和总联系人数
private Data data;
// 错误信息,用于描述发送操作中可能出现的错误详情
private String errors;
// 消息信息,通常用于提供更详细的响应描述
private String message;
// 响应状态,以字符串形式表示发送操作的状态
private String status;
/**
* 发送数据信息
* 该内部类用于详细描述发送操作的相关数据,包括发送消息的唯一标识、业务标识和联系人的总数
*/
@lombok.Data
public static class Data {
// 发送消息的唯一标识符
private String id;
// 业务标识符,用于关联发送消息的特定业务
private String businessId;
// 总联系人数,表示发送消息所涉及的联系人数量
private int totalContacts;
}
}
......@@ -40,7 +40,7 @@ public class SmsReceiveRespDTO {
private String serialNo;
/**
* 短信日志编号
*
* <p>
* 对应 SysSmsLogDO 的编号
*/
private Long logId;
......
......@@ -21,7 +21,7 @@ public class SmsTemplateRespDTO {
private String content;
/**
* 审核状态
*
* <p>
* 枚举 {@link SmsTemplateAuditStatusEnum}
*/
private Integer auditStatus;
......
......@@ -7,8 +7,8 @@ import cn.iocoder.yudao.framework.sms.core.enums.SmsFrameworkErrorCodeConstants;
/**
* 阿里云的 SmsCodeMapping 实现类
*
* 参见 https://help.aliyun.com/document_detail/101346.htm 文档
* <p>
* 参见 <a href="https://help.aliyun.com/document_detail/101346.htm">...</a> 文档
*
* @author 捷道源码
*/
......
package cn.iocoder.yudao.framework.sms.core.client.impl.bulk;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.yudao.framework.sms.core.client.SmsCodeMapping;
import cn.iocoder.yudao.framework.sms.core.enums.SmsFrameworkErrorCodeConstants;
import org.apache.commons.lang3.StringUtils;
/**
* Bulk SmsCodeMapping 实现类
*
* @author Jayden
*/
public class BulkSmsCodeMapping implements SmsCodeMapping {
@Override
public ErrorCode apply(String apiCode) {
if (StringUtils.isNotBlank(apiCode) && "OK".equals(apiCode)) {
return GlobalErrorCodeConstants.SUCCESS;
}
return SmsFrameworkErrorCodeConstants.SMS_UNKNOWN;
}
}
......@@ -17,6 +17,9 @@ public enum SmsChannelEnum {
DEBUG_DING_TALK("DEBUG_DING_TALK", "调试(钉钉)"),
YUN_PIAN("YUN_PIAN", "云片"),
ALIYUN("ALIYUN", "阿里云"),
SENDCHAMP("SENDCHAMP", "Sendchamp"),
YCLOUD("YCLOUD", "Ycloud"),
BULK("BULK", "bulk")
// TENCENT("TENCENT", "腾讯云"),
// HUA_WEI("HUA_WEI", "华为云"),
;
......@@ -32,7 +35,9 @@ public enum SmsChannelEnum {
public static SmsChannelEnum getByCode(String code) {
SmsChannelEnum channelEnum = ArrayUtil.firstMatch(o -> o.getCode().equals(code), values());
if (null == channelEnum) { return DEBUG_DING_TALK; }
if (null == channelEnum) {
return DEBUG_DING_TALK;
}
return channelEnum;
}
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment