Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
J
jiedao-api-boot-master
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lanbaoming
jiedao-api-boot-master
Commits
56d736c3
Commit
56d736c3
authored
Nov 20, 2024
by
honghy
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
短信功能实作
parent
dea7eb34
Changes
100
Show whitespace changes
Inline
Side-by-side
Showing
100 changed files
with
3609 additions
and
608 deletions
+3609
-608
20241120.sql
sql/v3.1/20241120.sql
+161
-0
PhoneUtil.java
...der/yudao/framework/common/util/validation/PhoneUtil.java
+1
-1
SendchampHttp.java
...n/iocoder/yudao/framework/http/example/SendchampHttp.java
+41
-22
YCloudWhatsappHttp.java
...oder/yudao/framework/http/example/YCloudWhatsappHttp.java
+73
-38
SmsClient.java
...cn/iocoder/yudao/framework/sms/core/client/SmsClient.java
+23
-6
SmsLogDTO.java
...ocoder/yudao/framework/sms/core/client/dto/SmsLogDTO.java
+180
-0
SmsTemplateDTO.java
...r/yudao/framework/sms/core/client/dto/SmsTemplateDTO.java
+82
-0
SmsClientFactoryImpl.java
.../framework/sms/core/client/impl/SmsClientFactoryImpl.java
+13
-4
AliyunSmsClient.java
...ramework/sms/core/client/impl/aliyun/AliyunSmsClient.java
+110
-14
DebugDingTalkSmsClient.java
...rk/sms/core/client/impl/debug/DebugDingTalkSmsClient.java
+10
-3
SendchampSmsClient.java
...rk/sms/core/client/impl/sendchamp/SendchampSmsClient.java
+201
-0
SendchampSmsCodeMapping.java
...s/core/client/impl/sendchamp/SendchampSmsCodeMapping.java
+19
-0
YCloudSmsClient.java
...ramework/sms/core/client/impl/yCloud/YCloudSmsClient.java
+159
-0
YCloudSmsCodeMapping.java
...ork/sms/core/client/impl/yCloud/YCloudSmsCodeMapping.java
+22
-0
YunpianSmsClient.java
...mework/sms/core/client/impl/yunpian/YunpianSmsClient.java
+11
-3
ReceiveStatusEnum.java
...der/yudao/framework/sms/core/enums/ReceiveStatusEnum.java
+22
-0
SmsChannelEnum.java
...ocoder/yudao/framework/sms/core/enums/SmsChannelEnum.java
+2
-0
CacheConstants.java
...yudao/framework/apollo/core/constants/CacheConstants.java
+22
-0
TransportTypeEnum.java
.../iocoder/yudao/module/member/enums/TransportTypeEnum.java
+2
-0
AppAuthCheckCodeReqVO.java
.../member/controller/app/auth/vo/AppAuthCheckCodeReqVO.java
+2
-6
AppAuthSendSmsReqVO.java
...le/member/controller/app/auth/vo/AppAuthSendSmsReqVO.java
+19
-7
AppEmailReqVO.java
...o/module/member/controller/app/auth/vo/AppEmailReqVO.java
+0
-4
AuthConvert.java
...iocoder/yudao/module/member/convert/auth/AuthConvert.java
+4
-4
MemberAuthServiceImpl.java
...dao/module/member/service/auth/MemberAuthServiceImpl.java
+12
-11
MemberUserServiceImpl.java
...dao/module/member/service/user/MemberUserServiceImpl.java
+2
-2
OrderCargoControlServiceImpl.java
...rvice/orderCargoControl/OrderCargoControlServiceImpl.java
+8
-3
OrderCargoControlPickServiceImpl.java
...derCargoControlPick/OrderCargoControlPickServiceImpl.java
+44
-30
OrderWarehouseInServiceImpl.java
...service/orderWarehouseIn/OrderWarehouseInServiceImpl.java
+61
-34
OrderSendSmsReqVO.java
...ocoder/yudao/module/order/vo/order/OrderSendSmsReqVO.java
+16
-6
RedeemRewardApi.java
...coder/yudao/module/reward/api/reward/RedeemRewardApi.java
+1
-2
RedeemRewardRespDTO.java
...dao/module/reward/api/reward/dto/RedeemRewardRespDTO.java
+21
-0
RedeemRewardApiImpl.java
...r/yudao/module/reward/api/reward/RedeemRewardApiImpl.java
+9
-4
AppRedeemRewardController.java
...ward/controller/app/redeem/AppRedeemRewardController.java
+3
-2
BoxOrderSmsLogDO.java
...udao/module/shipment/dal/dataobject/BoxOrderSmsLogDO.java
+5
-5
BoxOrderSmsLogMapper.java
...yudao/module/shipment/dal/mysql/BoxOrderSmsLogMapper.java
+7
-6
BoxService.java
...iocoder/yudao/module/shipment/service/box/BoxService.java
+5
-5
BoxServiceImpl.java
...der/yudao/module/shipment/service/box/BoxServiceImpl.java
+38
-40
BoxAirCheckoutServiceImpl.java
...ent/service/boxAirCheckout/BoxAirCheckoutServiceImpl.java
+3
-3
BoxArrivalServiceImpl.java
...le/shipment/service/boxArrival/BoxArrivalServiceImpl.java
+10
-12
BoxArrivalAirServiceImpl.java
...pment/service/boxArrivalAir/BoxArrivalAirServiceImpl.java
+10
-8
BoxCabinetServiceImpl.java
...le/shipment/service/boxCabinet/BoxCabinetServiceImpl.java
+2
-5
BoxClearanceServiceImpl.java
...hipment/service/boxClearance/BoxClearanceServiceImpl.java
+10
-10
BoxOrderSmsLogBackVO.java
...dule/shipment/vo/boxOrderSmsLog/BoxOrderSmsLogBackVO.java
+8
-6
BoxOrderSmsLogBaseVO.java
...dule/shipment/vo/boxOrderSmsLog/BoxOrderSmsLogBaseVO.java
+4
-6
BoxOrderSmsLogQueryVO.java
...ule/shipment/vo/boxOrderSmsLog/BoxOrderSmsLogQueryVO.java
+7
-5
BoxController.java
...yudao/module/shipment/controller/admin/BoxController.java
+21
-23
SmsSendApi.java
...va/cn/iocoder/yudao/module/system/api/sms/SmsSendApi.java
+11
-0
SmsCodeCheckReqDTO.java
...ao/module/system/api/sms/dto/code/SmsCodeCheckReqDTO.java
+1
-4
SmsCodeSendReqDTO.java
...dao/module/system/api/sms/dto/code/SmsCodeSendReqDTO.java
+14
-5
SmsCodeUseReqDTO.java
...udao/module/system/api/sms/dto/code/SmsCodeUseReqDTO.java
+1
-4
SmsSendSingleToUserReqDTOV2.java
.../system/api/sms/dto/send/SmsSendSingleToUserReqDTOV2.java
+48
-0
ErrorCodeConstants.java
...iocoder/yudao/module/system/enums/ErrorCodeConstants.java
+3
-0
SmsCountryCodeEnum.java
...der/yudao/module/system/enums/sms/SmsCountryCodeEnum.java
+25
-0
SmsIsOrdersEnum.java
...ocoder/yudao/module/system/enums/sms/SmsIsOrdersEnum.java
+21
-0
SmsIsTransportEnum.java
...der/yudao/module/system/enums/sms/SmsIsTransportEnum.java
+21
-0
SmsMessageTypeEnum.java
...der/yudao/module/system/enums/sms/SmsMessageTypeEnum.java
+22
-0
SmsNodeEnum.java
...cn/iocoder/yudao/module/system/enums/sms/SmsNodeEnum.java
+87
-0
SystemStatusEnum.java
...coder/yudao/module/system/enums/sms/SystemStatusEnum.java
+21
-0
SmsSendApiImpl.java
...n/iocoder/yudao/module/system/api/sms/SmsSendApiImpl.java
+8
-0
SmsCallbackController.java
...le/system/controller/admin/sms/SmsCallbackController.java
+17
-1
SmsNodeController.java
...module/system/controller/admin/sms/SmsNodeController.java
+95
-0
SmsLogExcelVO.java
...ule/system/controller/admin/sms/vo/log/SmsLogExcelVO.java
+20
-0
SmsLogExportReqVO.java
...system/controller/admin/sms/vo/log/SmsLogExportReqVO.java
+20
-0
SmsLogPageReqVO.java
...e/system/controller/admin/sms/vo/log/SmsLogPageReqVO.java
+18
-0
SmsLogRespVO.java
...dule/system/controller/admin/sms/vo/log/SmsLogRespVO.java
+18
-0
SmsNodeBackVO.java
...system/controller/admin/sms/vo/smsNode/SmsNodeBackVO.java
+77
-0
SmsNodeBaseVO.java
...system/controller/admin/sms/vo/smsNode/SmsNodeBaseVO.java
+55
-0
SmsNodeCreateReqVO.java
...m/controller/admin/sms/vo/smsNode/SmsNodeCreateReqVO.java
+14
-0
SmsNodeQueryVO.java
...ystem/controller/admin/sms/vo/smsNode/SmsNodeQueryVO.java
+55
-0
SmsNodeUpdateReqVO.java
...m/controller/admin/sms/vo/smsNode/SmsNodeUpdateReqVO.java
+18
-0
SmsTemplateBaseVO.java
...m/controller/admin/sms/vo/template/SmsTemplateBaseVO.java
+23
-9
SmsTemplateExcelVO.java
.../controller/admin/sms/vo/template/SmsTemplateExcelVO.java
+16
-4
SmsTemplateExportReqVO.java
...troller/admin/sms/vo/template/SmsTemplateExportReqVO.java
+12
-0
SmsTemplatePageReqVO.java
...ontroller/admin/sms/vo/template/SmsTemplatePageReqVO.java
+12
-0
SmsLogConvert.java
...ocoder/yudao/module/system/convert/sms/SmsLogConvert.java
+4
-1
SmsNodeConvert.java
...coder/yudao/module/system/convert/sms/SmsNodeConvert.java
+55
-0
SmsTemplateConvert.java
...r/yudao/module/system/convert/sms/SmsTemplateConvert.java
+3
-0
SmsCodeDO.java
...der/yudao/module/system/dal/dataobject/sms/SmsCodeDO.java
+2
-3
SmsLogDO.java
...oder/yudao/module/system/dal/dataobject/sms/SmsLogDO.java
+29
-14
SmsNodeDO.java
...der/yudao/module/system/dal/dataobject/sms/SmsNodeDO.java
+76
-0
SmsTemplateDO.java
...yudao/module/system/dal/dataobject/sms/SmsTemplateDO.java
+16
-1
SmsCodeMapper.java
...oder/yudao/module/system/dal/mysql/sms/SmsCodeMapper.java
+3
-3
SmsLogMapper.java
...coder/yudao/module/system/dal/mysql/sms/SmsLogMapper.java
+16
-3
SmsNodeMapper.java
...oder/yudao/module/system/dal/mysql/sms/SmsNodeMapper.java
+66
-0
SmsTemplateMapper.java
.../yudao/module/system/dal/mysql/sms/SmsTemplateMapper.java
+9
-0
SmsSendConsumer.java
.../yudao/module/system/mq/consumer/sms/SmsSendConsumer.java
+29
-29
SmsSendConsumerV2.java
...udao/module/system/mq/consumer/sms/SmsSendConsumerV2.java
+30
-0
SmsSendMessageV2.java
.../yudao/module/system/mq/message/sms/SmsSendMessageV2.java
+50
-0
SmsProducer.java
...oder/yudao/module/system/mq/producer/sms/SmsProducer.java
+4
-0
EmailCodeServiceImpl.java
...module/system/service/mail/impl/EmailCodeServiceImpl.java
+110
-110
QuerySendDetails.java
...der/yudao/module/system/service/sms/QuerySendDetails.java
+80
-0
SmsCodeServiceImpl.java
...r/yudao/module/system/service/sms/SmsCodeServiceImpl.java
+35
-38
SmsLogService.java
...ocoder/yudao/module/system/service/sms/SmsLogService.java
+29
-0
SmsLogServiceImpl.java
...er/yudao/module/system/service/sms/SmsLogServiceImpl.java
+71
-0
SmsNodeService.java
...coder/yudao/module/system/service/sms/SmsNodeService.java
+83
-0
SmsNodeServiceImpl.java
...r/yudao/module/system/service/sms/SmsNodeServiceImpl.java
+235
-0
SmsSendService.java
...coder/yudao/module/system/service/sms/SmsSendService.java
+83
-14
SmsSendServiceImpl.java
...r/yudao/module/system/service/sms/SmsSendServiceImpl.java
+182
-0
SmsTemplateService.java
...r/yudao/module/system/service/sms/SmsTemplateService.java
+10
-0
SmsTemplateServiceImpl.java
...dao/module/system/service/sms/SmsTemplateServiceImpl.java
+60
-25
No files found.
sql/v3.1/20241120.sql
0 → 100644
View file @
56d736c3
-- 短信模板
ALTER
TABLE
system_sms_template
ADD
node_value
varchar
(
100
)
comment
'节点'
,
add
transport_id
int
comment
'运输方式'
,
add
message_type
tinyint
default
1
comment
'发送类型'
,
add
language
varchar
(
100
)
comment
'语言'
;
ALTER
TABLE
system_sms_channel
MODIFY
api_secret
VARCHAR
(
200
)
COMMENT
'短信 API 的秘钥'
;
-- 新增数据字典渠道类型
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`
)
VALUES
(
3
,
'Sendchamp'
,
'SENDCHAMP'
,
'system_sms_channel_code'
,
0
,
'primary'
,
''
,
NULL
,
'2741'
,
'2024-10-28 09:11:18'
,
'2741'
,
'2024-10-28 09:12:13'
,
b
'0'
,
'Sendchamp'
);
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`
)
VALUES
(
4
,
'Ycloud'
,
'YCLOUD'
,
'system_sms_channel_code'
,
0
,
'primary'
,
''
,
NULL
,
'2741'
,
'2024-10-28 09:12:55'
,
'2741'
,
'2024-10-28 09:12:55'
,
b
'0'
,
'Ycloud'
);
-- 新增渠道
INSERT
INTO
`jiedao`
.
`system_sms_channel`
(
`id`
,
`signature`
,
`code`
,
`status`
,
`remark`
,
`api_key`
,
`api_secret`
,
`callback_url`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
,
`signature_en`
)
VALUES
(
7
,
'sendchamp'
,
'SENDCHAMP'
,
0
,
''
,
'ecit@ewchina.net'
,
'sendchamp_live_$2a$10$vQPdaDjl96Ybc5tzFmZYg.nqGirXuJBGDqJArthZnFR8P9mM5Z/JO'
,
''
,
'2741'
,
'2024-10-26 17:06:44'
,
'2741'
,
'2024-10-28 15:16:39'
,
b
'0'
,
'sendchamp'
);
INSERT
INTO
`jiedao`
.
`system_sms_channel`
(
`id`
,
`signature`
,
`code`
,
`status`
,
`remark`
,
`api_key`
,
`api_secret`
,
`callback_url`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
,
`signature_en`
)
VALUES
(
8
,
'ycloud'
,
'YCLOUD'
,
0
,
NULL
,
'ecit@ewchina.net'
,
'gAAAAABl5ZDpoKnKVaK0scmWo7GQeKDA1sn3OZBeMXUz211vZv5QqSEtr7_LD5ISTqSD0PnWLRWavYmJ3nQJiutT-sgp0dyHR2HIL6FYEhD3t2CNuoHJoSIOia5ffo_rjfxW_pk8co0i7UMTYANNGxsRNJLQTu_Alw=='
,
NULL
,
'2741'
,
'2024-10-26 17:12:50'
,
'2741'
,
'2024-10-28 15:16:18'
,
b
'0'
,
'ycloud'
);
-- 短信日志新增字段
alter
table
system_sms_log
add
node_id
bigint
comment
'节点id'
,
add
node_template_sn
int
default
1
comment
'节点模板序列号'
,
add
message_type
tinyint
comment
'发送类型'
;
-- 短信验证码
ALTER
TABLE
system_sms_code
CHANGE
scene
node_value
varchar
(
100
)
not
NULL
comment
'节点'
;
ALTER
TABLE
ecw_box_order_sms_log
CHANGE
scene
node_value
varchar
(
100
)
not
NULL
comment
'节点'
;
/*==============================================================*/
/* Table: system_sms_node */
/*==============================================================*/
create
table
system_sms_node
(
id
bigint
(
0
)
NOT
NULL
AUTO_INCREMENT
COMMENT
'编号'
,
node_value
varchar
(
100
)
not
null
comment
'节点'
,
is_transport
tinyint
not
null
comment
'是否匹配运输方式(0:否,1:是)'
,
transport_id
tinyint
not
null
comment
'运输方式ID'
,
is_orders
tinyint
not
null
comment
'多订单(0:否,1:是)'
,
country_id
bigint
not
null
comment
'国家区号id'
,
country_code
varchar
(
30
)
not
null
comment
'国家区号,和订单中国家区号保持一致'
,
status
tinyint
not
null
comment
'启用状态(0:开启,1:关闭)'
,
template_id_one
bigint
not
null
comment
'模板1'
,
template_id_two
bigint
comment
'模板2'
,
template_id_three
bigint
comment
'模板3'
,
template_id_four
bigint
comment
'模板4'
,
`creator`
varchar
(
64
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_unicode_ci
NULL
DEFAULT
''
COMMENT
'创建者'
,
`create_time`
datetime
(
0
)
NOT
NULL
DEFAULT
CURRENT_TIMESTAMP
(
0
)
COMMENT
'创建时间'
,
`updater`
varchar
(
64
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_unicode_ci
NULL
DEFAULT
''
COMMENT
'更新者'
,
`update_time`
datetime
(
0
)
NOT
NULL
DEFAULT
CURRENT_TIMESTAMP
(
0
)
ON
UPDATE
CURRENT_TIMESTAMP
(
0
)
COMMENT
'更新时间'
,
`deleted`
bit
(
1
)
NOT
NULL
DEFAULT
b
'0'
COMMENT
'是否删除'
,
primary
key
(
id
)
USING
BTREE
)
CHARACTER
SET
=
utf8mb4
COLLATE
=
utf8mb4_unicode_ci
COMMENT
=
'短信节点表'
;
-- 菜单 SQL
INSERT
INTO
`system_menu`
(
`name`
,
`permission`
,
`menu_type`
,
`sort`
,
`parent_id`
,
`path`
,
`icon`
,
`component`
,
`status`
)
VALUES
(
'短信节点管理'
,
''
,
2
,
3
,
1093
,
'sms-node'
,
'phone'
,
'system/sms/smsNode'
,
0
);
-- 按钮父菜单ID
SELECT
@
parentId
:
=
LAST_INSERT_ID
();
-- 按钮 SQL
INSERT
INTO
`system_menu`
(
`name`
,
`permission`
,
`menu_type`
,
`sort`
,
`parent_id`
,
`path`
,
`icon`
,
`component`
,
`status`
)
VALUES
(
'短信节点查询'
,
'system:sms-node:query'
,
3
,
1
,
@
parentId
,
''
,
''
,
''
,
0
);
INSERT
INTO
`system_menu`
(
`name`
,
`permission`
,
`menu_type`
,
`sort`
,
`parent_id`
,
`path`
,
`icon`
,
`component`
,
`status`
)
VALUES
(
'短信节点创建'
,
'system:sms-node:create'
,
3
,
2
,
@
parentId
,
''
,
''
,
''
,
0
);
INSERT
INTO
`system_menu`
(
`name`
,
`permission`
,
`menu_type`
,
`sort`
,
`parent_id`
,
`path`
,
`icon`
,
`component`
,
`status`
)
VALUES
(
'短信节点更新'
,
'system:sms-node:update'
,
3
,
3
,
@
parentId
,
''
,
''
,
''
,
0
);
INSERT
INTO
`system_menu`
(
`name`
,
`permission`
,
`menu_type`
,
`sort`
,
`parent_id`
,
`path`
,
`icon`
,
`component`
,
`status`
)
VALUES
(
'短信节点删除'
,
'system:sms-node:delete'
,
3
,
4
,
@
parentId
,
''
,
''
,
''
,
0
);
INSERT
INTO
`system_menu`
(
`name`
,
`permission`
,
`menu_type`
,
`sort`
,
`parent_id`
,
`path`
,
`icon`
,
`component`
,
`status`
)
VALUES
(
'短信节点导出'
,
'system:sms-node:export'
,
3
,
5
,
@
parentId
,
''
,
''
,
''
,
0
);
INSERT
INTO
`jiedao`
.
`system_dict_type`
(
`name`
,
`type`
,
`status`
,
`remark`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'短信节点'
,
'system_sms_node_node'
,
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`
)
VALUES
(
1
,
'会员用户 - 手机号注册'
,
'user-sms-reg'
,
'system_sms_node_node'
,
0
,
'default'
,
''
,
'0'
,
'2740'
,
'2024-11-05 14:22:53'
,
'2740'
,
'2024-11-05 14:24:33'
,
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`
)
VALUES
(
2
,
'会员用户 - 手机号登陆'
,
'user-sms-login'
,
'system_sms_node_node'
,
0
,
'default'
,
''
,
'1'
,
'2740'
,
'2024-11-05 14:23:27'
,
'2740'
,
'2024-11-05 14:24:39'
,
b
'0'
,
'user-sms-login'
);
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`
)
VALUES
(
3
,
'会员用户 - 解绑手机'
,
'user-sms-update-mobile'
,
'system_sms_node_node'
,
0
,
'default'
,
''
,
'2'
,
'2740'
,
'2024-11-05 14:23:43'
,
'2740'
,
'2024-11-05 14:24:41'
,
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`
)
VALUES
(
4
,
'会员用户 - 忘记密码'
,
'user-sms-reset-password'
,
'system_sms_node_node'
,
0
,
'default'
,
''
,
'3'
,
'2740'
,
'2024-11-05 14:24:05'
,
'2740'
,
'2024-11-05 14:24:43'
,
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`
)
VALUES
(
5
,
'订单 - 控货权转移'
,
'transfer-control-goods'
,
'system_sms_node_node'
,
0
,
'default'
,
''
,
'4'
,
'2740'
,
'2024-11-05 14:26:08'
,
'2740'
,
'2024-11-05 14:26:20'
,
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`
)
VALUES
(
6
,
'订单 - 放货验证短信'
,
'delivery-verification-sms'
,
'system_sms_node_node'
,
0
,
'default'
,
''
,
'5'
,
'2740'
,
'2024-11-05 14:26:36'
,
'2740'
,
'2024-11-05 14:26:36'
,
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`
)
VALUES
(
7
,
'订单 - 放货成功通知'
,
'notification-successful-delivery'
,
'system_sms_node_node'
,
0
,
'default'
,
''
,
'6'
,
'2740'
,
'2024-11-05 14:32:40'
,
'2740'
,
'2024-11-05 14:32:44'
,
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`
)
VALUES
(
8
,
'订单 - 取消放货通知'
,
'notification-successful-cancel-delivery'
,
'system_sms_node_node'
,
0
,
'default'
,
''
,
'7'
,
'2740'
,
'2024-11-05 14:33:12'
,
'2740'
,
'2024-11-05 14:33:12'
,
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`
)
VALUES
(
9
,
'出货 - 到港通知'
,
'shipment-arrival'
,
'system_sms_node_node'
,
0
,
'default'
,
''
,
NULL
,
'2740'
,
'2024-11-12 17:13:30'
,
'2740'
,
'2024-11-12 17:13:30'
,
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`
)
VALUES
(
10
,
'出货 - 清关通知'
,
'shipment-customs-clearance'
,
'system_sms_node_node'
,
0
,
'default'
,
''
,
NULL
,
'2740'
,
'2024-11-12 17:13:52'
,
'2740'
,
'2024-11-12 17:13:52'
,
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`
)
VALUES
(
11
,
'出货 - 装柜通知'
,
'shipment-cabinet'
,
'system_sms_node_node'
,
0
,
'default'
,
''
,
NULL
,
'2740'
,
'2024-11-12 17:20:24'
,
'2740'
,
'2024-11-12 17:20:24'
,
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`
)
VALUES
(
12
,
'出货 - 封柜反审'
,
'shipment-close-container'
,
'system_sms_node_node'
,
0
,
'default'
,
''
,
NULL
,
'2740'
,
'2024-11-12 17:22:02'
,
'2740'
,
'2024-11-12 17:22:02'
,
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`
)
VALUES
(
13
,
'入仓控货通知'
,
'warehouse-in-control'
,
'system_sms_node_node'
,
0
,
'default'
,
''
,
NULL
,
'2740'
,
'2024-11-12 17:22:30'
,
'2740'
,
'2024-11-12 17:22:30'
,
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`
)
VALUES
(
14
,
'入仓通知'
,
'warehouse-in'
,
'system_sms_node_node'
,
0
,
'default'
,
''
,
NULL
,
'2740'
,
'2024-11-12 17:23:11'
,
'2740'
,
'2024-11-12 17:23:11'
,
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`
)
VALUES
(
15
,
'追加通知'
,
'warehouse-in-append'
,
'system_sms_node_node'
,
0
,
'default'
,
''
,
NULL
,
'2740'
,
'2024-11-12 17:23:52'
,
'2740'
,
'2024-11-12 17:23:52'
,
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`
)
VALUES
(
16
,
'入仓-非控货代收货款'
,
'warehouse-in-collect-of-goods'
,
'system_sms_node_node'
,
0
,
'default'
,
''
,
NULL
,
'2740'
,
'2024-11-12 17:24:22'
,
'2740'
,
'2024-11-12 17:24:22'
,
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`
)
VALUES
(
17
,
'出仓通知'
,
'air-shipment-warehouse'
,
'system_sms_node_node'
,
0
,
'default'
,
''
,
NULL
,
'2740'
,
'2024-11-14 15:15:58'
,
'2740'
,
'2024-11-14 17:55:52'
,
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`
)
VALUES
(
18
,
'会员用户 - 兑换礼品'
,
'user-sms-redeem-reward'
,
'system_sms_node_node'
,
0
,
'default'
,
''
,
NULL
,
'2740'
,
'2024-11-20 09:52:56'
,
'2740'
,
'2024-11-20 09:52:56'
,
b
'0'
,
'会员用户 - 兑换礼品'
);
INSERT
INTO
`jiedao`
.
`system_dict_type`
(
`name`
,
`type`
,
`status`
,
`remark`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'发送类型'
,
'system_sms_template_message_type'
,
0
,
NULL
,
'2740'
,
'2024-11-04 17:07:41'
,
'2740'
,
'2024-11-04 17:07:41'
,
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`
)
VALUES
(
3
,
'email'
,
'3'
,
'system_sms_template_message_type'
,
0
,
'default'
,
''
,
NULL
,
'2740'
,
'2024-11-04 17:20:21'
,
'2740'
,
'2024-11-04 17:20:21'
,
b
'0'
,
'email'
);
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`
)
VALUES
(
2
,
'whatsapp'
,
'2'
,
'system_sms_template_message_type'
,
0
,
'default'
,
''
,
NULL
,
'2740'
,
'2024-11-04 17:20:00'
,
'2740'
,
'2024-11-04 17:20:00'
,
b
'0'
,
'whatsapp'
);
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`
)
VALUES
(
1
,
'短信'
,
'1'
,
'system_sms_template_message_type'
,
0
,
'default'
,
''
,
NULL
,
'2740'
,
'2024-11-04 17:17:48'
,
'2740'
,
'2024-11-04 17:18:16'
,
b
'0'
,
'message'
);
INSERT
INTO
`jiedao`
.
`system_dict_type`
(
`name`
,
`type`
,
`status`
,
`remark`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'模板语言'
,
'system_sms_template_language'
,
0
,
NULL
,
'2740'
,
'2024-11-04 17:38:08'
,
'2740'
,
'2024-11-04 17:38:08'
,
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`
)
VALUES
(
1
,
'en'
,
'en'
,
'system_sms_template_language'
,
0
,
'default'
,
''
,
NULL
,
'2740'
,
'2024-11-04 17:40:55'
,
'2740'
,
'2024-11-04 17:40:55'
,
b
'0'
,
'en'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'air-shipment-warehouse'
,
1
,
3
,
1
,
0
,
'0'
,
0
,
51
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-14 15:17:49'
,
'2740'
,
'2024-11-15 09:45:52'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'air-shipment-warehouse'
,
1
,
3
,
0
,
0
,
'0'
,
0
,
50
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-14 15:17:36'
,
'2740'
,
'2024-11-15 09:45:44'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'warehouse-in'
,
1
,
3
,
0
,
0
,
'0'
,
0
,
47
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-13 17:11:09'
,
'2740'
,
'2024-11-13 17:11:09'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'warehouse-in-control'
,
1
,
3
,
0
,
0
,
'0'
,
0
,
46
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-13 17:10:40'
,
'2740'
,
'2024-11-13 17:10:40'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'warehouse-in-append'
,
1
,
3
,
0
,
0
,
'0'
,
0
,
65
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-13 17:09:51'
,
'2740'
,
'2024-11-13 17:09:51'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'warehouse-in-collect-of-goods'
,
1
,
1
,
0
,
0
,
'0'
,
0
,
41
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-13 10:50:18'
,
'2740'
,
'2024-11-13 10:50:18'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'warehouse-in-append'
,
1
,
1
,
0
,
0
,
'0'
,
0
,
34
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-13 10:49:47'
,
'2740'
,
'2024-11-13 10:49:47'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'warehouse-in'
,
1
,
1
,
0
,
0
,
'0'
,
0
,
32
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-13 10:48:58'
,
'2740'
,
'2024-11-19 14:17:19'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'warehouse-in-control'
,
1
,
1
,
0
,
0
,
'0'
,
0
,
31
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-13 10:48:36'
,
'2740'
,
'2024-11-13 10:48:36'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'shipment-close-container'
,
1
,
1
,
0
,
0
,
'0'
,
0
,
39
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-13 10:48:08'
,
'2740'
,
'2024-11-13 10:48:08'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'shipment-cabinet'
,
1
,
3
,
1
,
0
,
'0'
,
0
,
64
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-13 10:29:02'
,
'2740'
,
'2024-11-13 10:29:02'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'shipment-cabinet'
,
1
,
3
,
0
,
0
,
'0'
,
0
,
63
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-13 10:28:48'
,
'2740'
,
'2024-11-13 10:28:48'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'shipment-cabinet'
,
1
,
1
,
1
,
0
,
'0'
,
0
,
21
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-13 10:09:37'
,
'2740'
,
'2024-11-13 10:09:37'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'shipment-cabinet'
,
1
,
1
,
0
,
0
,
'0'
,
0
,
45
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-13 10:09:04'
,
'2740'
,
'2024-11-13 10:09:04'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'shipment-customs-clearance'
,
1
,
3
,
1
,
0
,
'0'
,
0
,
53
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-13 10:07:59'
,
'2740'
,
'2024-11-13 10:07:59'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'shipment-customs-clearance'
,
1
,
3
,
0
,
0
,
'0'
,
0
,
52
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-13 10:07:46'
,
'2740'
,
'2024-11-13 10:07:46'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'shipment-customs-clearance'
,
1
,
1
,
1
,
0
,
'0'
,
0
,
23
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-13 10:02:56'
,
'2740'
,
'2024-11-13 10:02:56'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'shipment-customs-clearance'
,
1
,
1
,
0
,
0
,
'0'
,
0
,
43
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-13 10:02:41'
,
'2740'
,
'2024-11-13 10:02:41'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'shipment-arrival'
,
1
,
3
,
1
,
0
,
'0'
,
0
,
49
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-13 09:58:16'
,
'2740'
,
'2024-11-13 09:58:16'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'shipment-arrival'
,
1
,
3
,
0
,
0
,
'0'
,
0
,
48
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-13 09:58:02'
,
'2740'
,
'2024-11-13 09:58:02'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'shipment-arrival'
,
1
,
1
,
1
,
0
,
'0'
,
0
,
22
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-13 09:57:40'
,
'2740'
,
'2024-11-13 09:57:40'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'shipment-arrival'
,
1
,
1
,
0
,
0
,
'0'
,
0
,
44
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-13 09:57:12'
,
'2740'
,
'2024-11-13 09:57:23'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'notification-successful-cancel-delivery'
,
0
,
0
,
0
,
0
,
'0'
,
0
,
42
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-12 11:13:47'
,
'2740'
,
'2024-11-12 17:53:38'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'notification-successful-delivery'
,
0
,
0
,
0
,
0
,
'0'
,
0
,
36
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-12 11:09:38'
,
'2740'
,
'2024-11-12 17:53:49'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'delivery-verification-sms'
,
0
,
0
,
0
,
0
,
'0'
,
0
,
38
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-08 16:16:21'
,
'2740'
,
'2024-11-08 16:16:21'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'transfer-control-goods'
,
0
,
0
,
0
,
0
,
'0'
,
0
,
37
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-08 15:50:53'
,
'2740'
,
'2024-11-08 15:50:53'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'user-sms-update-mobile'
,
0
,
0
,
0
,
0
,
'0'
,
0
,
16
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-08 15:00:45'
,
'2740'
,
'2024-11-08 15:00:45'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'user-sms-reset-password'
,
0
,
0
,
0
,
0
,
'0'
,
0
,
15
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-08 14:18:49'
,
'2740'
,
'2024-11-08 14:18:49'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'user-sms-login'
,
0
,
0
,
0
,
0
,
'0'
,
0
,
14
,
60
,
NULL
,
NULL
,
'2740'
,
'2024-11-06 14:16:31'
,
'2740'
,
'2024-11-11 15:11:03'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
'user-sms-reg'
,
0
,
0
,
0
,
0
,
'0'
,
0
,
13
,
59
,
NULL
,
NULL
,
'2740'
,
'2024-11-05 15:00:37'
,
'2740'
,
'2024-11-08 13:59:18'
,
b
'0'
);
INSERT
INTO
`jiedao`
.
`system_sms_node`
(
`id`
,
`node_value`
,
`is_transport`
,
`transport_id`
,
`is_orders`
,
`country_id`
,
`country_code`
,
`status`
,
`template_id_one`
,
`template_id_two`
,
`template_id_three`
,
`template_id_four`
,
`creator`
,
`create_time`
,
`updater`
,
`update_time`
,
`deleted`
)
VALUES
(
33
,
'user-sms-redeem-reward'
,
0
,
0
,
0
,
0
,
'0'
,
0
,
55
,
NULL
,
NULL
,
NULL
,
'2740'
,
'2024-11-20 09:54:21'
,
'2740'
,
'2024-11-20 09:54:21'
,
b
'0'
);
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/validation/PhoneUtil.java
View file @
56d736c3
...
...
@@ -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
().
orElse
Get
(
null
);
DictDataRespDTO
dto
=
dtos
.
stream
().
filter
(
d
->
d
.
getValue
().
trim
().
equals
(
code
.
trim
())).
findFirst
().
orElse
(
null
);
if
(
Objects
.
nonNull
(
dto
))
{
// 优先获取中文
rule
=
dto
.
getLabel
();
...
...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/http/example/SendchampHttp.java
View file @
56d736c3
...
...
@@ -4,6 +4,7 @@ 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.SneakyThrows
;
import
org.jetbrains.annotations.NotNull
;
import
java.util.HashMap
;
...
...
@@ -16,52 +17,70 @@ import java.util.Map;
**/
public
class
SendchampHttp
{
private
static
final
String
SMS_URL
=
"https://api.sendchamp.com/api/v1/sms/send"
;
private
static
final
String
SMS_URL
=
"https://api.sendchamp.com/api/v1/sms/send"
;
public
void
postReq
(
Map
<
String
,
Object
>
param
,
Map
<
String
,
String
>
header
){
private
static
final
String
RECEIVE_URL
=
"https://api.sendchamp.com/api/v1/sms/status/"
;
public
Response
postReq
(
Map
<
String
,
Object
>
param
,
Map
<
String
,
String
>
header
)
{
HttpClient
client
=
HttpClientFactory
.
get
(
Request
.
Util
.
OkHttp
);
Request
req
=
Request
.
create
(
SMS_URL
,
Request
.
Method
.
POST
,
param
);
Request
req
=
Request
.
create
(
SMS_URL
,
Request
.
Method
.
POST
,
param
);
req
.
setParamFormat
(
Request
.
ParamFormat
.
JSON
);
try
{
Response
res
=
client
.
execute
(
req
,
Request
.
Option
.
create
(
0
,
0
,
header
));
System
.
out
.
println
(
"response code ---------------------------->"
+
res
.
getCode
());
System
.
out
.
println
(
"response content is --------------------》"
+
res
.
getBody
());
Response
res
=
client
.
execute
(
req
,
Request
.
Option
.
create
(
0
,
0
,
header
));
System
.
out
.
println
(
"response code ---------------------------->"
+
res
.
getCode
());
System
.
out
.
println
(
"response content is --------------------》"
+
res
.
getBody
());
return
res
;
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
e
);
}
}
@SneakyThrows
public
Response
getReceiveStatus
(
Map
<
String
,
String
>
header
,
String
id
)
{
HttpClient
client
=
HttpClientFactory
.
get
(
Request
.
Util
.
OkHttp
);
Request
req
=
Request
.
create
(
RECEIVE_URL
+
id
,
Request
.
Method
.
GET
,
""
);
try
{
Response
res
=
client
.
execute
(
req
,
Request
.
Option
.
create
(
0
,
0
,
header
));
System
.
out
.
println
(
"response code ---------------------------->"
+
res
.
getCode
());
System
.
out
.
println
(
"response content is --------------------》"
+
res
.
getBody
());
return
res
;
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
e
);
}
}
@NotNull
p
rivate
static
Map
<
String
,
String
>
setHeader
(
String
apiKey
)
{
Map
<
String
,
String
>
header
=
new
HashMap
<>();
header
.
put
(
"Accept"
,
"application/json,text/plain,*/*"
);
p
ublic
static
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
;
}
@NotNull
p
rivate
static
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"
);
p
ublic
static
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
){
public
static
void
main
(
String
[]
args
)
{
SendchampHttp
test
=
new
SendchampHttp
();
String
to
=
"2348140352000"
;
// String to = "2348140352000";
String
to
=
"8618926674857"
;
String
senderName
=
"Sendchamp"
;
//信息如果超过200字符,需要拆成多条短信,多次发送
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
=
setParams
(
to
,
message
,
senderName
);
Map
<
String
,
Object
>
param
=
setParams
(
to
,
message
,
senderName
);
String
apiKey
=
"Bearer sendchamp_live_$2a$10$vQPdaDjl96Ybc5tzFmZYg.nqGirXuJBGDqJArthZnFR8P9mM5Z/JO"
;
Map
<
String
,
String
>
header
=
setHeader
(
apiKey
);
test
.
postReq
(
param
,
header
);
Map
<
String
,
String
>
header
=
setHeader
(
apiKey
);
test
.
getReceiveStatus
(
header
,
"66e6e9df-b454-4df7-a968-af944a535757"
);
}
...
...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/http/example/YCloudWhatsappHttp.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
framework
.
http
.
example
;
import
cn.iocoder.yudao.framework.common.util.json.JsonUtils
;
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.SneakyThrows
;
import
java.
util.ArrayList
;
import
java.
util.HashMap
;
import
java.
util.List
;
import
java.util.
Map
;
import
java.
time.ZoneId
;
import
java.
time.ZonedDateTime
;
import
java.
time.format.DateTimeFormatter
;
import
java.util.
*
;
/**
* @author wuxian
...
...
@@ -19,32 +20,45 @@ public class YCloudWhatsappHttp {
private
HttpClient
client
=
null
;
//请求地址
private
static
final
String
WA_URL
=
"https://api.ycloud.com/v2/whatsapp/messages/sendDirectly"
;
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/"
;
public
YCloudWhatsappHttp
()
{
init
();
}
private
void
init
(){
private
void
init
()
{
client
=
HttpClientFactory
.
get
(
Request
.
Util
.
OkHttp
);
}
@SneakyThrows
public
void
postWhatsapp
(
Map
<
String
,
String
>
header
,
Map
<
String
,
Object
>
param
)
{
Request
req
=
Request
.
create
(
WA_URL
,
Request
.
Method
.
POST
,
param
);
public
Response
postWhatsapp
(
Map
<
String
,
String
>
header
,
Map
<
String
,
Object
>
param
)
{
Request
req
=
Request
.
create
(
WA_URL
,
Request
.
Method
.
POST
,
param
);
req
.
setParamFormat
(
Request
.
ParamFormat
.
JSON
);
Response
res
=
client
.
execute
(
req
,
Request
.
Option
.
create
(
0
,
0
,
header
));
System
.
out
.
println
(
"response code ---------------------------->"
+
res
.
getCode
());
System
.
out
.
println
(
"response content is --------------------》"
+
res
.
getBody
());
Response
res
=
client
.
execute
(
req
,
Request
.
Option
.
create
(
0
,
0
,
header
));
System
.
out
.
println
(
"response code ---------------------------->"
+
res
.
getCode
());
System
.
out
.
println
(
"response content is --------------------》"
+
res
.
getBody
());
return
res
;
}
@SneakyThrows
public
Response
getReceiveStatus
(
Map
<
String
,
String
>
header
,
String
id
)
{
Request
req
=
Request
.
create
(
RECEIVE_URL
+
id
,
Request
.
Method
.
GET
,
""
);
Response
res
=
client
.
execute
(
req
,
Request
.
Option
.
create
(
0
,
0
,
header
));
System
.
out
.
println
(
"response code ---------------------------->"
+
res
.
getCode
());
System
.
out
.
println
(
"response content is --------------------》"
+
res
.
getBody
());
return
res
;
}
/**
*
* @param code 验证码
* @param templateName 模板名称
* @param lanCode 语言编号
* @param to 接收手机号
* @return 参数
*/
p
rivate
Map
<
String
,
Object
>
setParams
(
String
code
,
String
templateName
,
String
lanCode
)
{
p
ublic
Map
<
String
,
Object
>
setParams
(
String
code
,
String
templateName
,
String
lanCode
,
String
to
)
{
Map
<
String
,
Object
>
template
=
new
HashMap
<>();
Map
<
String
,
String
>
language
=
new
HashMap
<>();
Components
components
=
new
Components
();
...
...
@@ -69,44 +83,65 @@ public class YCloudWhatsappHttp {
list2
.
add
(
components
);
list2
.
add
(
button
);
language
.
put
(
"code"
,
lanCode
);
language
.
put
(
"policy"
,
"deterministic"
);
language
.
put
(
"code"
,
lanCode
);
language
.
put
(
"policy"
,
"deterministic"
);
template
.
put
(
"language"
,
language
);
template
.
put
(
"name"
,
templateName
);
template
.
put
(
"components"
,
list2
);
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"
,
"8618102810628"
);
param
.
put
(
"type"
,
"template"
);
param
.
put
(
"template"
,
template
);
param
.
put
(
"from"
,
"8618022485824"
);
param
.
put
(
"to"
,
to
);
param
.
put
(
"type"
,
"template"
);
param
.
put
(
"template"
,
template
);
return
param
;
}
//构建http请求的头
p
rivate
Map
<
String
,
String
>
setHeader
(
String
apiKey
)
{
Map
<
String
,
String
>
header
=
new
HashMap
<>();
header
.
put
(
"Accept"
,
"application/json"
);
p
ublic
Map
<
String
,
String
>
setHeader
(
String
apiKey
)
{
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
){
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
));
// String code = "8888";
// String templateName = "ec_verification";
// String lanCode = "en";
// test.postWhatsapp(test.setHeader(apiKey), test.setParams(code, templateName, lanCode, "8618926674857"));
Response
response
=
test
.
getReceiveStatus
(
test
.
setHeader
(
apiKey
),
"67370e34334f011e030dfd7b"
);
Map
<
String
,
Object
>
responseObj
=
JsonUtils
.
parseObject
(
response
.
getBody
(),
Map
.
class
);
String
status
=
(
String
)
responseObj
.
get
(
"status"
);
if
(
status
!=
null
&&
(
"delivered"
.
equals
(
status
)
||
"read"
.
equals
(
status
)))
{
System
.
out
.
println
(
status
);
String
deliverTime
=
(
String
)
responseObj
.
get
(
"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
Date
localDate
=
Date
.
from
(
localDateTime
.
toInstant
());
// 输出本地时间
System
.
out
.
println
(
"本地时间: "
+
localDate
);
}
else
{
System
.
out
.
println
(
"null"
);
}
}
}
@lombok
.
Setter
@lombok
.
Getter
class
Parameters
{
class
Parameters
{
private
String
type
;
private
String
text
;
...
...
@@ -125,7 +160,7 @@ class Button {
private
String
type
;
private
String
sub_type
;
private
String
index
;
private
List
<
Object
>
parameters
=
null
;
private
List
<
Object
>
parameters
=
null
;
}
...
...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/sms/core/client/SmsClient.java
View file @
56d736c3
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
;
...
...
@@ -34,6 +32,18 @@ public interface SmsClient {
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,11 @@ public interface SmsClient {
*/
SmsCommonResult
<
SmsTemplateRespDTO
>
getSmsTemplate
(
String
apiTemplateId
);
/**
* 查询短信发送状态
*
* @param smsLogDO
* @return
*/
SmsLogDTO
getReceiveStatus
(
SmsLogDTO
smsLogDO
);
}
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/sms/core/client/dto/SmsLogDTO.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
framework
.
sms
.
core
.
client
.
dto
;
import
cn.iocoder.yudao.framework.common.util.spring.enums.UserTypeEnum
;
import
cn.iocoder.yudao.framework.sms.core.enums.SmsFrameworkErrorCodeConstants
;
import
com.baomidou.mybatisplus.annotation.TableField
;
import
com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler
;
import
lombok.Data
;
import
lombok.ToString
;
import
java.util.Date
;
import
java.util.Map
;
/**
* 日志dto
*
* @author Jayden
* @date 2024/11/6
*/
@Data
@ToString
(
callSuper
=
true
)
public
class
SmsLogDTO
{
/**
* 自增编号
*/
private
Long
id
;
// ========= 渠道相关字段 =========
/**
* 短信渠道编号
* <p>
*/
private
Long
channelId
;
/**
* 短信渠道编码
* <p>
*/
private
String
channelCode
;
// ========= 模板相关字段 =========
/**
* 模板编号
* <p>
*/
private
Long
templateId
;
/**
* 模板编码
* <p>
*/
private
String
templateCode
;
/**
* 短信类型
* <p>
*/
private
Integer
templateType
;
/**
*
*/
private
String
templateContent
;
/**
*
*/
@TableField
(
typeHandler
=
JacksonTypeHandler
.
class
)
private
Map
<
String
,
Object
>
templateParams
;
/**
* 短信 API 的模板编号
* <p>
*/
private
String
apiTemplateId
;
// ========= 手机相关字段 =========
/**
* 手机号
*/
private
String
mobile
;
/**
* 用户编号
*/
private
Long
userId
;
/**
* 用户类型
* <p>
* 枚举 {@link UserTypeEnum}
*/
private
Integer
userType
;
// ========= 发送相关字段 =========
/**
* 发送状态
* <p>
*/
private
Integer
sendStatus
;
/**
* 发送时间
*/
private
Date
sendTime
;
/**
* 发送结果的编码
* <p>
* 枚举 {@link SmsFrameworkErrorCodeConstants}
*/
private
Integer
sendCode
;
/**
* 发送结果的提示
* <p>
* 一般情况下,使用 {@link SmsFrameworkErrorCodeConstants}
* 异常情况下,通过格式化 Exception 的提示存储
*/
private
String
sendMsg
;
/**
* 短信 API 发送结果的编码
* <p>
* 由于第三方的错误码可能是字符串,所以使用 String 类型
*/
private
String
apiSendCode
;
/**
* 短信 API 发送失败的提示
*/
private
String
apiSendMsg
;
/**
* 短信 API 发送返回的唯一请求 ID
* <p>
* 用于和短信 API 进行定位于排错
*/
private
String
apiRequestId
;
/**
* 短信 API 发送返回的序号
* <p>
* 用于和短信 API 平台的发送记录关联
*/
private
String
apiSerialNo
;
// ========= 接收相关字段 =========
/**
* 接收状态
* <p>
*/
private
Integer
receiveStatus
;
/**
* 接收时间
*/
private
Date
receiveTime
;
/**
* 短信 API 接收结果的编码
*/
private
String
apiReceiveCode
;
/**
* 短信 API 接收结果的提示
*/
private
String
apiReceiveMsg
;
/**
* 重发的短信日志id
*/
private
Long
smsLogId
;
/**
* 重发次数
*/
private
Integer
num
;
/**
* 短信节点表id
*/
private
Long
nodeId
;
/**
* 节点模板序列号
*/
private
Integer
nodeTemplateSn
;
/**
* 发送类型
*/
private
Integer
messageType
;
}
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/sms/core/client/dto/SmsTemplateDTO.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
framework
.
sms
.
core
.
client
.
dto
;
import
lombok.Data
;
import
lombok.ToString
;
/**
* 模板dto
*
* @author Jayden
* @date 2024/11/6
*/
@Data
@ToString
(
callSuper
=
true
)
public
class
SmsTemplateDTO
{
/**
* 自增编号
*/
private
Long
id
;
// ========= 模板相关字段 =========
/**
* 短信类型
*/
private
Integer
type
;
/**
* 启用状态
*/
private
Integer
status
;
/**
* 模板编码,保证唯一
*/
private
String
code
;
/**
* 模板名称
*/
private
String
name
;
/**
* 模板内容
*/
private
String
content
;
/**
* 备注
*/
private
String
remark
;
/**
* 短信 API 的模板编号
*/
private
String
apiTemplateId
;
// ========= 渠道相关字段 =========
/**
* 短信渠道编号
*/
private
Long
channelId
;
/**
* 短信渠道编码
*/
private
String
channelCode
;
/**
* 节点
*/
private
String
nodeValue
;
/**
* 运输方式
*/
private
Long
transportId
;
/**
* 发送类型
*/
private
Integer
messageType
;
/**
* 语言
*/
private
String
language
;
}
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/sms/core/client/impl/SmsClientFactoryImpl.java
View file @
56d736c3
...
...
@@ -4,6 +4,8 @@ import cn.iocoder.yudao.framework.sms.core.client.SmsClient;
import
cn.iocoder.yudao.framework.sms.core.client.SmsClientFactory
;
import
cn.iocoder.yudao.framework.sms.core.client.impl.aliyun.AliyunSmsClient
;
import
cn.iocoder.yudao.framework.sms.core.client.impl.debug.DebugDingTalkSmsClient
;
import
cn.iocoder.yudao.framework.sms.core.client.impl.sendchamp.SendchampSmsClient
;
import
cn.iocoder.yudao.framework.sms.core.client.impl.yCloud.YCloudSmsClient
;
import
cn.iocoder.yudao.framework.sms.core.client.impl.yunpian.YunpianSmsClient
;
import
cn.iocoder.yudao.framework.sms.core.enums.SmsChannelEnum
;
import
cn.iocoder.yudao.framework.sms.core.property.SmsChannelProperties
;
...
...
@@ -33,7 +35,7 @@ public class SmsClientFactoryImpl implements SmsClientFactory {
/**
* 短信客户端 Map
* key:渠道编码,使用 {@link SmsChannelProperties#getCode()} ()}
*
*
<p>
* 注意,一些场景下,需要获得某个渠道类型的客户端,所以需要使用它。
* 例如说,解析短信接收结果,是相对通用的,不需要使用某个渠道编号的 {@link #channelIdClients}
*/
...
...
@@ -78,9 +80,16 @@ public class SmsClientFactoryImpl implements SmsClientFactory {
Assert
.
notNull
(
channelEnum
,
String
.
format
(
"渠道类型(%s) 为空"
,
channelEnum
));
// 创建客户端
switch
(
channelEnum
)
{
case
ALIYUN:
return
new
AliyunSmsClient
(
properties
);
case
YUN_PIAN:
return
new
YunpianSmsClient
(
properties
);
case
DEBUG_DING_TALK:
return
new
DebugDingTalkSmsClient
(
properties
);
case
ALIYUN:
return
new
AliyunSmsClient
(
properties
);
case
YUN_PIAN:
return
new
YunpianSmsClient
(
properties
);
case
DEBUG_DING_TALK:
return
new
DebugDingTalkSmsClient
(
properties
);
case
SENDCHAMP:
return
new
SendchampSmsClient
(
properties
);
case
YCLOUD:
return
new
YCloudSmsClient
(
properties
);
}
// 创建失败,错误日志 + 抛出异常
log
.
error
(
"[createSmsClient][配置({}) 找不到合适的客户端实现]"
,
properties
);
...
...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/sms/core/client/impl/aliyun/AliyunSmsClient.java
View file @
56d736c3
...
...
@@ -3,20 +3,21 @@ package cn.iocoder.yudao.framework.sms.core.client.impl.aliyun;
import
cn.hutool.core.lang.Assert
;
import
cn.hutool.core.util.ReflectUtil
;
import
cn.hutool.core.util.StrUtil
;
import
cn.iocoder.yudao.framework.common.util.collection.MapUtils
;
import
cn.iocoder.yudao.framework.common.util.json.JsonUtils
;
import
cn.iocoder.yudao.framework.common.util.json.core.KeyValue
;
import
cn.iocoder.yudao.framework.sms.core.client.SmsCommonResult
;
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
cn.iocoder.yudao.framework.sms.core.client.impl.AbstractSmsClient
;
import
cn.iocoder.yudao.framework.sms.core.enums.ReceiveStatusEnum
;
import
cn.iocoder.yudao.framework.sms.core.enums.SmsTemplateAuditStatusEnum
;
import
cn.iocoder.yudao.framework.sms.core.property.SmsChannelProperties
;
import
cn.iocoder.yudao.framework.common.util.collection.MapUtils
;
import
cn.iocoder.yudao.framework.common.util.json.JsonUtils
;
import
com.aliyuncs.AcsRequest
;
import
com.aliyuncs.AcsResponse
;
import
com.aliyuncs.DefaultAcsClient
;
import
com.aliyuncs.IAcsClient
;
import
com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsRequest
;
import
com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse
;
import
com.aliyuncs.dysmsapi.model.v20170525.QuerySmsTemplateRequest
;
import
com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest
;
import
com.aliyuncs.exceptions.ClientException
;
...
...
@@ -25,9 +26,11 @@ import com.aliyuncs.profile.IClientProfile;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
com.fasterxml.jackson.annotation.JsonProperty
;
import
com.google.common.annotations.VisibleForTesting
;
import
io.undertow.util.DateUtils
;
import
lombok.Data
;
import
lombok.extern.slf4j.Slf4j
;
import
java.text.SimpleDateFormat
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Objects
;
...
...
@@ -56,6 +59,8 @@ public class AliyunSmsClient extends AbstractSmsClient {
*/
private
volatile
IAcsClient
client
;
private
static
final
String
DELIVERED_STATUS
=
"DELIVERED"
;
public
AliyunSmsClient
(
SmsChannelProperties
properties
)
{
super
(
properties
,
new
AliyunSmsCodeMapping
());
Assert
.
notEmpty
(
properties
.
getApiKey
(),
"apiKey 不能为空"
);
...
...
@@ -74,9 +79,9 @@ public class AliyunSmsClient extends AbstractSmsClient {
// 构建参数
SendSmsRequest
request
=
new
SendSmsRequest
();
request
.
setPhoneNumbers
(
mobile
);
if
(
mobile
.
startsWith
(
"0086"
)||
mobile
.
startsWith
(
"86"
)||
mobile
.
startsWith
(
"+86"
)||
mobile
.
startsWith
(
"+0086"
))
{
if
(
mobile
.
startsWith
(
"0086"
)
||
mobile
.
startsWith
(
"86"
)
||
mobile
.
startsWith
(
"+86"
)
||
mobile
.
startsWith
(
"+0086"
))
{
request
.
setSignName
(
properties
.
getSignature
());
}
else
{
}
else
{
request
.
setSignName
(
properties
.
getSignatureEn
());
}
request
.
setTemplateCode
(
apiTemplateId
);
...
...
@@ -116,10 +121,14 @@ public class AliyunSmsClient extends AbstractSmsClient {
@VisibleForTesting
Integer
convertSmsTemplateAuditStatus
(
Integer
templateStatus
)
{
switch
(
templateStatus
)
{
case
0
:
return
SmsTemplateAuditStatusEnum
.
CHECKING
.
getStatus
();
case
1
:
return
SmsTemplateAuditStatusEnum
.
SUCCESS
.
getStatus
();
case
2
:
return
SmsTemplateAuditStatusEnum
.
FAIL
.
getStatus
();
default
:
throw
new
IllegalArgumentException
(
String
.
format
(
"未知审核状态(%d)"
,
templateStatus
));
case
0
:
return
SmsTemplateAuditStatusEnum
.
CHECKING
.
getStatus
();
case
1
:
return
SmsTemplateAuditStatusEnum
.
SUCCESS
.
getStatus
();
case
2
:
return
SmsTemplateAuditStatusEnum
.
FAIL
.
getStatus
();
default
:
throw
new
IllegalArgumentException
(
String
.
format
(
"未知审核状态(%d)"
,
templateStatus
));
}
}
...
...
@@ -150,9 +159,96 @@ public class AliyunSmsClient extends AbstractSmsClient {
return
ex
.
getErrMsg
()
+
" => "
+
ex
.
getErrorDescription
();
}
@Override
public
SmsCommonResult
<
SmsSendRespDTO
>
sendSmsV2
(
Long
sendLogId
,
String
mobile
,
SmsTemplateDTO
smsTemplateDTO
,
List
<
KeyValue
<
String
,
Object
>>
templateParams
)
{
// 构建参数
SendSmsRequest
request
=
new
SendSmsRequest
();
request
.
setPhoneNumbers
(
mobile
);
String
apiTemplateId
=
smsTemplateDTO
.
getApiTemplateId
();
request
.
setSignName
(
properties
.
getSignature
());
request
.
setTemplateCode
(
apiTemplateId
);
request
.
setTemplateParam
(
JsonUtils
.
toJsonString
(
MapUtils
.
convertMap
(
templateParams
)));
request
.
setOutId
(
String
.
valueOf
(
sendLogId
));
// 执行请求
return
invoke
(
request
,
response
->
new
SmsSendRespDTO
().
setSerialNo
(
response
.
getBizId
()));
}
/**
* 短信接收状态
* 获取短信日志的接收状态
* 通过调用阿里云短信服务的查询接口,更新短信日志的接收状态
*
* @param smsLogDO 短信日志实体,包含查询所需的参数,如手机号、发送时间等
* @return 更新了接收状态的短信日志实体
*/
@Override
public
SmsLogDTO
getReceiveStatus
(
SmsLogDTO
smsLogDO
)
{
// 初始化短信日志DTO,并默认设置接收状态为未接收到
SmsLogDTO
smsLogDTO
=
new
SmsLogDTO
();
smsLogDTO
.
setReceiveStatus
(
ReceiveStatusEnum
.
Receive_STATUS_20
.
getValue
());
// 创建查询发送详情的请求
QuerySendDetailsRequest
querySendDetailsRequest
=
new
QuerySendDetailsRequest
();
// 设置查询参数,包括手机号(去掉国际拨号)、页大小、当前页、发送日期和业务ID
querySendDetailsRequest
.
setPhoneNumber
(
removeCountryCode
(
smsLogDO
.
getMobile
()));
querySendDetailsRequest
.
setPageSize
(
1L
);
querySendDetailsRequest
.
setCurrentPage
(
1L
);
querySendDetailsRequest
.
setSendDate
(
formatDate
(
smsLogDO
.
getSendTime
()));
querySendDetailsRequest
.
setBizId
(
smsLogDO
.
getApiSerialNo
());
// 初始化查询响应对象
QuerySendDetailsResponse
acsResponse
=
null
;
try
{
// 发起查询请求并获取响应
acsResponse
=
client
.
getAcsResponse
(
querySendDetailsRequest
);
}
catch
(
ClientException
e
)
{
// 如果查询出错,记录日志并返回初始化的短信日志DTO
log
.
error
(
"Error querying send details: "
,
e
);
return
smsLogDTO
;
}
// 如果查询成功且有查询结果,更新短信日志的接收状态
if
(
acsResponse
!=
null
&&
!
acsResponse
.
getSmsSendDetailDTOs
().
isEmpty
())
{
// 获取第一条查询结果
QuerySendDetailsResponse
.
SmsSendDetailDTO
smsSendDetailDTO
=
acsResponse
.
getSmsSendDetailDTOs
().
get
(
0
);
// 如果短信发送成功,更新接收状态为已接收到,并设置接收时间
if
(
DELIVERED_STATUS
.
equals
(
smsSendDetailDTO
.
getErrCode
()))
{
smsLogDTO
.
setReceiveStatus
(
ReceiveStatusEnum
.
Receive_STATUS_10
.
getValue
());
String
receiveDate
=
smsSendDetailDTO
.
getReceiveDate
();
if
(
receiveDate
!=
null
)
{
smsLogDTO
.
setReceiveTime
(
DateUtils
.
parseDate
(
receiveDate
));
}
}
}
// 返回更新后的短信日志DTO
return
smsLogDTO
;
}
/**
* 去掉手机号开头的国家代码 "86"
*
* @param phoneNumber 包含国家代码的手机号
* @return 去掉国家代码后的手机号
*/
public
static
String
removeCountryCode
(
String
phoneNumber
)
{
// 使用 replaceFirst 方法去掉开头的 "86"
return
phoneNumber
.
replaceFirst
(
"^86"
,
""
);
}
/**
* 将 Date 对象格式化为指定格式的字符串
*
* @param date 需要格式化的 Date 对象
* @return 格式化后的字符串,格式为 "yyyyMMdd"
*/
public
static
String
formatDate
(
Date
date
)
{
SimpleDateFormat
outputFormat
=
new
SimpleDateFormat
(
"yyyyMMdd"
);
return
outputFormat
.
format
(
date
);
}
/**
* 短信接收状态
* <p>
* 参见 https://help.aliyun.com/document_detail/101867.html 文档
*
* @author 捷道源码
...
...
@@ -198,14 +294,14 @@ public class AliyunSmsClient extends AbstractSmsClient {
private
String
bizId
;
/**
* 用户序列号
*
*
<p>
* 这里我们传递的是 SysSmsLogDO 的日志编号
*/
@JsonProperty
(
"out_id"
)
private
String
outId
;
/**
* 短信长度,例如说 1、2、3
*
*
<p>
* 140 字节算一条短信,短信长度超过 140 字节时会拆分成多条短信发送
*/
@JsonProperty
(
"sms_size"
)
...
...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/sms/core/client/impl/debug/DebugDingTalkSmsClient.java
View file @
56d736c3
...
...
@@ -9,9 +9,7 @@ import cn.hutool.crypto.digest.HmacAlgorithm;
import
cn.hutool.http.HttpUtil
;
import
cn.iocoder.yudao.framework.common.util.json.core.KeyValue
;
import
cn.iocoder.yudao.framework.sms.core.client.SmsCommonResult
;
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
cn.iocoder.yudao.framework.sms.core.client.impl.AbstractSmsClient
;
import
cn.iocoder.yudao.framework.sms.core.enums.SmsTemplateAuditStatusEnum
;
import
cn.iocoder.yudao.framework.sms.core.property.SmsChannelProperties
;
...
...
@@ -93,4 +91,13 @@ public class DebugDingTalkSmsClient extends AbstractSmsClient {
return
SmsCommonResult
.
build
(
"0"
,
"success"
,
null
,
data
,
codeMapping
);
}
@Override
public
SmsCommonResult
<
SmsSendRespDTO
>
sendSmsV2
(
Long
logId
,
String
mobile
,
SmsTemplateDTO
smsTemplateDTO
,
List
<
KeyValue
<
String
,
Object
>>
templateParams
)
{
return
null
;
}
@Override
public
SmsLogDTO
getReceiveStatus
(
SmsLogDTO
smsLogDO
)
{
return
null
;
}
}
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/sms/core/client/impl/sendchamp/SendchampSmsClient.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
framework
.
sms
.
core
.
client
.
impl
.
sendchamp
;
import
cn.hutool.core.lang.Assert
;
import
cn.iocoder.yudao.framework.common.util.json.JsonUtils
;
import
cn.iocoder.yudao.framework.common.util.json.core.KeyValue
;
import
cn.iocoder.yudao.framework.http.core.Response
;
import
cn.iocoder.yudao.framework.http.example.SendchampHttp
;
import
cn.iocoder.yudao.framework.sms.core.client.SmsCommonResult
;
import
cn.iocoder.yudao.framework.sms.core.client.dto.*
;
import
cn.iocoder.yudao.framework.sms.core.client.impl.AbstractSmsClient
;
import
cn.iocoder.yudao.framework.sms.core.enums.ReceiveStatusEnum
;
import
cn.iocoder.yudao.framework.sms.core.enums.SmsTemplateAuditStatusEnum
;
import
cn.iocoder.yudao.framework.sms.core.property.SmsChannelProperties
;
import
com.fasterxml.jackson.annotation.JsonProperty
;
import
lombok.Data
;
import
lombok.extern.slf4j.Slf4j
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
/**
* Sendchamp客户端
*/
@Slf4j
public
class
SendchampSmsClient
extends
AbstractSmsClient
{
// 创建HTTP客户端实例,用于发送短信
private
final
SendchampHttp
sendchampHttp
=
new
SendchampHttp
();
// 定义发送方名称,此处为固定值
private
final
String
senderName
=
"Sendchamp"
;
public
SendchampSmsClient
(
SmsChannelProperties
properties
)
{
super
(
properties
,
new
SendchampSmsCodeMapping
());
Assert
.
notEmpty
(
properties
.
getApiKey
(),
"apiKey 不能为空"
);
Assert
.
notEmpty
(
properties
.
getApiSecret
(),
"apiSecret 不能为空"
);
}
@Override
protected
void
doInit
()
{
}
@Override
protected
SmsCommonResult
<
SmsSendRespDTO
>
doSendSms
(
Long
sendLogId
,
String
mobile
,
String
apiTemplateId
,
List
<
KeyValue
<
String
,
Object
>>
templateParams
)
throws
Throwable
{
return
null
;
}
/**
* 发送短信服务(版本2)
* 该方法用于发送短信,会根据模板内容和参数动态生成短信内容,并处理发送过程
*
* @param logId 日志ID,用于追踪和记录
* @param mobile 手机号码,短信接收方
* @param smsTemplateDTO 短信模板信息,包括模板内容等
* @param templateParams 模板参数,用于替换模板中的占位符
* @return 返回短信发送结果,包括状态码、消息ID等信息
*/
@Override
public
SmsCommonResult
<
SmsSendRespDTO
>
sendSmsV2
(
Long
logId
,
String
mobile
,
SmsTemplateDTO
smsTemplateDTO
,
List
<
KeyValue
<
String
,
Object
>>
templateParams
)
{
SmsCommonResult
<
SmsSendRespDTO
>
smsCommonResult
=
SmsCommonResult
.
build
(
"400"
,
"Bad Request"
,
null
,
null
,
codeMapping
);
// 获取短信模板内容
String
content
=
smsTemplateDTO
.
getContent
();
// 如果有模板参数,则进行参数替换
if
(
templateParams
!=
null
)
{
for
(
KeyValue
<
String
,
Object
>
entry
:
templateParams
)
{
// 对键和值进行转义,以确保安全性
String
key
=
escapeKey
(
entry
.
getKey
());
String
value
=
escapeValue
(
entry
.
getValue
());
// 构建正则表达式,用于匹配模板中的占位符
String
regex
=
"\\$\\{"
+
key
+
"\\}"
;
Pattern
pattern
=
Pattern
.
compile
(
regex
);
Matcher
matcher
=
pattern
.
matcher
(
content
);
// 将匹配到的占位符替换为实际值
content
=
matcher
.
replaceAll
(
value
);
}
}
try
{
// 如果信息超过200字符,需要拆分成多条短信发送
List
<
String
>
messages
=
splitContent
(
content
,
200
);
for
(
String
message
:
messages
)
{
// 设置发送短信所需的参数
Map
<
String
,
Object
>
param
=
sendchampHttp
.
setParams
(
mobile
,
message
,
senderName
);
// 设置请求头,包含认证信息
Map
<
String
,
String
>
header
=
sendchampHttp
.
setHeader
(
"Bearer "
+
properties
.
getApiSecret
());
// 发送POST请求
Response
response
=
sendchampHttp
.
postReq
(
param
,
header
);
// 获取响应体
String
result
=
response
.
getBody
();
// 解析响应结果
Map
<?,
?>
responseObj
=
JsonUtils
.
parseObject
(
result
,
Map
.
class
);
Map
<
String
,
Object
>
data
=
(
Map
<
String
,
Object
>)
responseObj
.
get
(
"data"
);
// 构建发送结果
smsCommonResult
=
SmsCommonResult
.
build
(
String
.
valueOf
(
responseObj
.
get
(
"status"
)),
String
.
valueOf
(
responseObj
.
get
(
"message"
)),
String
.
valueOf
(
data
.
get
(
"business_id"
)),
null
,
codeMapping
);
smsCommonResult
.
setData
(
new
SmsSendRespDTO
().
setSerialNo
(
String
.
valueOf
(
data
.
get
(
"business_id"
))));
}
}
catch
(
Exception
e
)
{
// 记录发送短信时发生的错误
log
.
error
(
"Error sending SMS: "
,
e
);
// 返回内部服务器错误结果
return
SmsCommonResult
.
build
(
"500"
,
"Internal Server Error"
,
null
,
null
,
codeMapping
);
}
// 返回请求结果
return
smsCommonResult
;
}
@Override
public
SmsLogDTO
getReceiveStatus
(
SmsLogDTO
smsLogDO
)
{
// 初始化短信日志DTO,并默认设置接收状态为未接收到
SmsLogDTO
smsLogDTO
=
new
SmsLogDTO
();
smsLogDTO
.
setReceiveStatus
(
ReceiveStatusEnum
.
Receive_STATUS_20
.
getValue
());
return
smsLogDTO
;
}
/**
* 转义键
* 对键进行转义,以防止恶意代码注入
*
* @param key 待转义的键
* @return 转义后的键
*/
private
String
escapeKey
(
String
key
)
{
return
key
.
replaceAll
(
"[^a-zA-Z0-9_]"
,
""
);
}
/**
* 转义值
* 对值进行转义,以防止恶意代码注入
*
* @param value 待转义的值
* @return 转义后的值
*/
private
String
escapeValue
(
Object
value
)
{
if
(
value
instanceof
String
)
{
return
((
String
)
value
).
replaceAll
(
"[^a-zA-Z0-9_]"
,
""
);
}
return
value
.
toString
();
}
/**
* 拆分内容
* 将内容拆分成多个部分,每个部分不超过 maxLength 字符
*
* @param content 待拆分的内容
* @param maxLength 每个部分的最大长度
* @return 拆分后的内容列表
*/
private
List
<
String
>
splitContent
(
String
content
,
int
maxLength
)
{
List
<
String
>
messages
=
new
ArrayList
<>();
int
start
=
0
;
while
(
start
<
content
.
length
())
{
int
end
=
Math
.
min
(
start
+
maxLength
,
content
.
length
());
messages
.
add
(
content
.
substring
(
start
,
end
));
start
=
end
;
}
return
messages
;
}
@Override
protected
List
<
SmsReceiveRespDTO
>
doParseSmsReceiveStatus
(
String
text
)
throws
Throwable
{
return
null
;
}
@Override
protected
SmsCommonResult
<
SmsTemplateRespDTO
>
doGetSmsTemplate
(
String
apiTemplateId
)
throws
Throwable
{
SmsTemplateRespDTO
data
=
new
SmsTemplateRespDTO
().
setId
(
apiTemplateId
).
setContent
(
""
)
.
setAuditStatus
(
SmsTemplateAuditStatusEnum
.
SUCCESS
.
getStatus
()).
setAuditReason
(
""
);
return
SmsCommonResult
.
build
(
"accepted"
,
"accepted"
,
null
,
data
,
codeMapping
);
}
/**
* 短信接收状态
* <p>
* @author 捷道源码
*/
@Data
public
static
class
SmsReceiveStatus
{
/**
* module
*/
@JsonProperty
(
"module"
)
private
String
module
;
/**
* reference
*/
@JsonProperty
(
"reference"
)
private
String
reference
;
/**
* 状态
*/
@JsonProperty
(
"status"
)
private
String
status
;
}
}
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/sms/core/client/impl/sendchamp/SendchampSmsCodeMapping.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
framework
.
sms
.
core
.
client
.
impl
.
sendchamp
;
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
;
/**
* sendchamp SmsCodeMapping 实现类
*/
public
class
SendchampSmsCodeMapping
implements
SmsCodeMapping
{
@Override
public
ErrorCode
apply
(
String
apiCode
)
{
switch
(
apiCode
)
{
case
"accepted"
:
return
GlobalErrorCodeConstants
.
SUCCESS
;
}
return
SmsFrameworkErrorCodeConstants
.
SMS_UNKNOWN
;
}
}
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/sms/core/client/impl/yCloud/YCloudSmsClient.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
framework
.
sms
.
core
.
client
.
impl
.
yCloud
;
import
cn.hutool.core.lang.Assert
;
import
cn.iocoder.yudao.framework.common.util.json.JsonUtils
;
import
cn.iocoder.yudao.framework.common.util.json.core.KeyValue
;
import
cn.iocoder.yudao.framework.http.core.Response
;
import
cn.iocoder.yudao.framework.http.example.YCloudWhatsappHttp
;
import
cn.iocoder.yudao.framework.sms.core.client.SmsCommonResult
;
import
cn.iocoder.yudao.framework.sms.core.client.dto.*
;
import
cn.iocoder.yudao.framework.sms.core.client.impl.AbstractSmsClient
;
import
cn.iocoder.yudao.framework.sms.core.client.impl.sendchamp.SendchampSmsCodeMapping
;
import
cn.iocoder.yudao.framework.sms.core.enums.ReceiveStatusEnum
;
import
cn.iocoder.yudao.framework.sms.core.enums.SmsTemplateAuditStatusEnum
;
import
cn.iocoder.yudao.framework.sms.core.property.SmsChannelProperties
;
import
lombok.extern.slf4j.Slf4j
;
import
java.time.ZoneId
;
import
java.time.ZonedDateTime
;
import
java.time.format.DateTimeFormatter
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Map
;
/**
* ycloud客户端
*
* @author Jayden
* @date 2024/11/7
*/
@Slf4j
public
class
YCloudSmsClient
extends
AbstractSmsClient
{
// 创建HTTP客户端实例,用于发送短信
private
final
YCloudWhatsappHttp
yCloudWhatsappHttp
=
new
YCloudWhatsappHttp
();
public
YCloudSmsClient
(
SmsChannelProperties
properties
)
{
super
(
properties
,
new
SendchampSmsCodeMapping
());
Assert
.
notEmpty
(
properties
.
getApiKey
(),
"apiKey 不能为空"
);
Assert
.
notEmpty
(
properties
.
getApiSecret
(),
"apiSecret 不能为空"
);
}
@Override
protected
void
doInit
()
{
}
@Override
protected
SmsCommonResult
<
SmsSendRespDTO
>
doSendSms
(
Long
sendLogId
,
String
mobile
,
String
apiTemplateId
,
List
<
KeyValue
<
String
,
Object
>>
templateParams
)
throws
Throwable
{
return
null
;
}
/**
* 发送短信V2版本
* 该方法用于发送短信,根据提供的日志ID、手机号码、短信模板和模板参数进行短信发送
* 主要逻辑包括处理模板参数、调用HTTP工具发送短信以及解析响应结果
*
* @param logId 日志ID,用于追踪和记录发送短信的日志
* @param mobile 手机号码,指定短信接收者的电话号码
* @param smsTemplateDTO 短信模板数据传输对象,包含短信模板的相关信息
* @param templateParams 模板参数列表,包含短信模板中的变量和对应的值
* @return 返回一个通用的结果对象,包含短信发送的相关信息和结果状态
*/
@Override
public
SmsCommonResult
<
SmsSendRespDTO
>
sendSmsV2
(
Long
logId
,
String
mobile
,
SmsTemplateDTO
smsTemplateDTO
,
List
<
KeyValue
<
String
,
Object
>>
templateParams
)
{
// 默认验证码为空字符串
String
code
=
""
;
// 如果模板参数不为空,则遍历模板参数以获取验证码
if
(
templateParams
!=
null
)
{
for
(
KeyValue
<
String
,
Object
>
entry
:
templateParams
)
{
code
=
(
String
)
entry
.
getValue
();
}
}
// 发送短信并获取响应
Response
response
=
yCloudWhatsappHttp
.
postWhatsapp
(
yCloudWhatsappHttp
.
setHeader
(
properties
.
getApiSecret
()),
yCloudWhatsappHttp
.
setParams
(
code
,
smsTemplateDTO
.
getApiTemplateId
(),
smsTemplateDTO
.
getLanguage
(),
mobile
));
// 解析结果
Map
<
String
,
Object
>
responseObj
=
JsonUtils
.
parseObject
(
response
.
getBody
(),
Map
.
class
);
// 构建短信发送结果对象
SmsCommonResult
<
SmsSendRespDTO
>
smsCommonResult
=
SmsCommonResult
.
build
(
String
.
valueOf
(
responseObj
.
get
(
"status"
)),
String
.
valueOf
(
responseObj
.
get
(
"status"
)),
String
.
valueOf
(
responseObj
.
get
(
"id"
)),
null
,
codeMapping
);
// 设置短信发送结果的详细信息
smsCommonResult
.
setData
(
new
SmsSendRespDTO
().
setSerialNo
(
String
.
valueOf
(
responseObj
.
get
(
"id"
))));
// 返回短信发送结果
return
smsCommonResult
;
}
/**
* 获取短信接收状态
* 本方法通过调用第三方API来获取短信的实际接收状态,并更新短信日志DTO中的相关信息
*
* @param smsLogDO 短信日志DTO,包含需要查询接收状态的短信的相关信息
* @return 返回更新了接收状态和接收时间的短信日志DTO
*/
@Override
public
SmsLogDTO
getReceiveStatus
(
SmsLogDTO
smsLogDO
)
{
// 初始化短信日志DTO,并默认设置接收状态为未接收到
SmsLogDTO
smsLogDTO
=
new
SmsLogDTO
();
smsLogDTO
.
setReceiveStatus
(
ReceiveStatusEnum
.
Receive_STATUS_20
.
getValue
());
try
{
// 发送短信并获取响应
Response
response
=
yCloudWhatsappHttp
.
getReceiveStatus
(
yCloudWhatsappHttp
.
setHeader
(
properties
.
getApiSecret
()),
smsLogDO
.
getApiSerialNo
());
// 解析响应内容为Map对象,以便后续处理
Map
<
String
,
Object
>
responseObj
=
JsonUtils
.
parseObject
(
response
.
getBody
(),
Map
.
class
);
// 获取短信状态
String
status
=
(
String
)
responseObj
.
get
(
"status"
);
// 如果短信状态为已送达或已读取,则进一步处理
if
(
status
!=
null
&&
(
"delivered"
.
equals
(
status
)
||
"read"
.
equals
(
status
)))
{
// 获取送达时间
String
deliverTime
=
(
String
)
responseObj
.
get
(
"deliverTime"
);
// 解析并转换送达时间为本地时间
Date
localDate
=
parseAndConvertToLocalDate
(
deliverTime
);
// 更新短信日志DTO的接收时间和接收状态
smsLogDTO
.
setReceiveTime
(
localDate
);
smsLogDTO
.
setReceiveStatus
(
ReceiveStatusEnum
.
Receive_STATUS_10
.
getValue
());
}
}
catch
(
Exception
e
)
{
// 记录异常信息
log
.
error
(
"Error occurred while getting receive status: "
,
e
);
// 保持默认的接收状态为未接收到
smsLogDTO
.
setReceiveStatus
(
ReceiveStatusEnum
.
Receive_STATUS_20
.
getValue
());
}
// 返回更新后的短信日志DTO
return
smsLogDTO
;
}
/**
* 解析并转换时间为本地时间
* 本方法将给定的ISO 8601格式的日期时间字符串解析为日期对象,并转换为本地时间
*
* @param deliverTime ISO 8601格式的日期时间字符串
* @return 返回转换后的本地时间日期对象
*/
private
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
());
}
@Override
protected
List
<
SmsReceiveRespDTO
>
doParseSmsReceiveStatus
(
String
text
)
{
throw
new
UnsupportedOperationException
(
"无回调"
);
}
@Override
protected
SmsCommonResult
<
SmsTemplateRespDTO
>
doGetSmsTemplate
(
String
apiTemplateId
)
{
SmsTemplateRespDTO
data
=
new
SmsTemplateRespDTO
().
setId
(
apiTemplateId
).
setContent
(
""
)
.
setAuditStatus
(
SmsTemplateAuditStatusEnum
.
SUCCESS
.
getStatus
()).
setAuditReason
(
""
);
return
SmsCommonResult
.
build
(
"accepted"
,
"accepted"
,
null
,
data
,
codeMapping
);
}
}
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/sms/core/client/impl/yCloud/YCloudSmsCodeMapping.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
framework
.
sms
.
core
.
client
.
impl
.
yCloud
;
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
;
/**
* ycloud SmsCodeMapping 实现类
*
* @author Jayden
* @date 2024/11/7
*/
public
class
YCloudSmsCodeMapping
implements
SmsCodeMapping
{
@Override
public
ErrorCode
apply
(
String
apiCode
)
{
switch
(
apiCode
)
{
case
"success"
:
return
GlobalErrorCodeConstants
.
SUCCESS
;
}
return
SmsFrameworkErrorCodeConstants
.
SMS_UNKNOWN
;
}
}
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/sms/core/client/impl/yunpian/YunpianSmsClient.java
View file @
56d736c3
...
...
@@ -6,9 +6,7 @@ import cn.hutool.core.util.StrUtil;
import
cn.hutool.core.util.URLUtil
;
import
cn.iocoder.yudao.framework.common.util.json.core.KeyValue
;
import
cn.iocoder.yudao.framework.sms.core.client.SmsCommonResult
;
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
cn.iocoder.yudao.framework.sms.core.client.impl.AbstractSmsClient
;
import
cn.iocoder.yudao.framework.sms.core.enums.SmsTemplateAuditStatusEnum
;
import
cn.iocoder.yudao.framework.sms.core.property.SmsChannelProperties
;
...
...
@@ -148,6 +146,16 @@ public class YunpianSmsClient extends AbstractSmsClient {
return
sendResult
.
getMsg
()
+
" => "
+
sendResult
.
getDetail
();
}
@Override
public
SmsCommonResult
<
SmsSendRespDTO
>
sendSmsV2
(
Long
logId
,
String
mobile
,
SmsTemplateDTO
smsTemplateDTO
,
List
<
KeyValue
<
String
,
Object
>>
templateParams
)
{
return
null
;
}
@Override
public
SmsLogDTO
getReceiveStatus
(
SmsLogDTO
smsLogDO
)
{
return
null
;
}
/**
* 短信接收状态
*
...
...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/sms/core/enums/ReceiveStatusEnum.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
framework
.
sms
.
core
.
enums
;
import
lombok.AllArgsConstructor
;
import
lombok.Getter
;
/**
* 短信接收状态
*
* @author jayden
*/
@Getter
@AllArgsConstructor
public
enum
ReceiveStatusEnum
{
RECEIVE_STATUS_0
(
"等待结果"
,
0
),
Receive_STATUS_10
(
"接收成功"
,
10
),
Receive_STATUS_20
(
"接收失败"
,
20
);
private
String
name
;
private
Integer
value
;
}
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/sms/core/enums/SmsChannelEnum.java
View file @
56d736c3
...
...
@@ -17,6 +17,8 @@ public enum SmsChannelEnum {
DEBUG_DING_TALK
(
"DEBUG_DING_TALK"
,
"调试(钉钉)"
),
YUN_PIAN
(
"YUN_PIAN"
,
"云片"
),
ALIYUN
(
"ALIYUN"
,
"阿里云"
),
SENDCHAMP
(
"SENDCHAMP"
,
"Sendchamp"
),
YCLOUD
(
"YCLOUD"
,
"Ycloud"
)
// TENCENT("TENCENT", "腾讯云"),
// HUA_WEI("HUA_WEI", "华为云"),
;
...
...
yudao-framework/yudao-spring-boot-starter-config/src/main/java/cn/iocoder/yudao/framework/apollo/core/constants/CacheConstants.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
framework
.
apollo
.
core
.
constants
;
/**
* 缓存的key 常量
*
* @author Jayden
* @date 2024/11/6
*/
public
class
CacheConstants
{
public
static
final
String
COLON
=
":"
;
/**
* 短信节点表缓存
*/
public
static
final
String
SYSTEM_SMS_NODE_KEY
=
"system_sms_node:"
;
/**
* 短信节点表缓存
*/
public
static
final
String
SYSTEM_SMS_TEMPLATE_KEY
=
"system_sms_template:"
;
}
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/TransportTypeEnum.java
View file @
56d736c3
...
...
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.member.enums;
import
java.util.stream.Stream
;
public
enum
TransportTypeEnum
{
OTHER
(
0
,
"其他"
),
OCEAN_LCL
(
1
,
"海运拼柜"
),
SPECIAL_LINE_AIR_FREIGHT
(
3
,
"专线空运"
);
...
...
@@ -22,6 +23,7 @@ public enum TransportTypeEnum {
public
String
getName
()
{
return
name
;
}
public
static
TransportTypeEnum
parseByValue
(
int
value
)
{
return
Stream
.
of
(
values
()).
filter
(
e
->
e
.
getValue
()
==
value
).
findAny
().
orElse
(
null
);
}
...
...
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthCheckCodeReqVO.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
member
.
controller
.
app
.
auth
.
vo
;
import
cn.iocoder.yudao.framework.common.validation.InEnum
;
import
cn.iocoder.yudao.framework.common.validation.Mobile
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.AllArgsConstructor
;
...
...
@@ -36,9 +33,8 @@ public class AppAuthCheckCodeReqVO {
@Pattern
(
regexp
=
"^[0-9]+$"
,
message
=
"{app.auth.captcha.pattern}"
)
private
String
code
;
@ApiModelProperty
(
value
=
"
发送场景"
,
example
=
"1"
,
notes
=
"对应 SmsSceneEnum 枚举
"
)
@ApiModelProperty
(
value
=
"
节点
"
)
@NotNull
(
message
=
"{app.sms.scene.not.blank}"
)
@InEnum
(
value
=
SmsSceneEnum
.
class
,
message
=
"{app.sms.scene.not.range}"
)
private
Integer
scene
;
private
String
nodeValue
;
}
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSendSmsReqVO.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
member
.
controller
.
app
.
auth
.
vo
;
import
cn.iocoder.yudao.framework.common.validation.InEnum
;
import
cn.iocoder.yudao.framework.common.validation.Mobile
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
...
...
@@ -25,12 +22,27 @@ public class AppAuthSendSmsReqVO {
// @Mobile(message = "incorrect mobile number")
private
String
mobile
;
@ApiModelProperty
(
value
=
"发送场景(0注册1登录2修改手机3忘记密码)"
,
example
=
"1"
,
notes
=
"对应 SmsSceneEnum 枚举"
)
@NotNull
(
message
=
"{app.sms.scene.not.blank}"
)
@InEnum
(
value
=
SmsSceneEnum
.
class
,
message
=
"{app.sms.scene.not.range}"
)
private
Integer
scene
;
@ApiModelProperty
(
value
=
"业务节点"
,
required
=
true
)
@NotNull
(
message
=
"节点不能为空"
)
private
String
nodeValue
;
@ApiModelProperty
(
value
=
"区号"
,
required
=
true
)
@NotNull
(
message
=
"区号不能为空"
)
private
String
areaCode
;
@ApiModelProperty
(
value
=
"是否匹配运输方式"
,
required
=
true
)
@NotNull
(
message
=
"是否匹配运输方式不能为空"
)
private
Integer
isTransport
;
@ApiModelProperty
(
value
=
"运输方式"
,
required
=
true
)
@NotNull
(
message
=
"运输方式不能空"
)
private
Integer
transportId
;
@ApiModelProperty
(
value
=
"是否多订单不能为空"
,
required
=
true
)
@NotNull
(
message
=
"是否多订单不能为空"
)
private
Integer
isOrders
;
@ApiModelProperty
(
value
=
"发送类型不能为空"
,
required
=
true
)
@NotNull
(
message
=
"发送类型不能为空"
)
private
Integer
messageType
;
}
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppEmailReqVO.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
member
.
controller
.
app
.
auth
.
vo
;
import
cn.iocoder.yudao.framework.common.validation.InEnum
;
import
cn.iocoder.yudao.framework.common.validation.Mobile
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
import
lombok.experimental.Accessors
;
import
javax.validation.constraints.Email
;
import
javax.validation.constraints.NotNull
;
/**
* @author Administrator
...
...
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java
View file @
56d736c3
...
...
@@ -8,7 +8,7 @@ import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
import
cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO
;
import
cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO
;
import
cn.iocoder.yudao.module.system.api.social.dto.SocialUserUnbindReqDTO
;
import
cn.iocoder.yudao.module.system.enums.sms.Sms
Scen
eEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.Sms
Nod
eEnum
;
import
org.mapstruct.Mapper
;
import
org.mapstruct.Mapping
;
import
org.mapstruct.factory.Mappers
;
...
...
@@ -32,8 +32,8 @@ public interface AuthConvert {
SocialUserUnbindReqDTO
convert
(
Long
userId
,
Integer
userType
,
AppAuthSocialUnbindReqVO
reqVO
);
SmsCodeSendReqDTO
convert
(
AppAuthSendSmsReqVO
reqVO
);
SmsCodeUseReqDTO
convert
(
AppAuthResetPasswordReqVO
reqVO
,
Sms
Scen
eEnum
scene
,
String
usedIp
);
SmsCodeUseReqDTO
convert
(
AppAuthSmsLoginReqVO
reqVO
,
Integer
scen
e
,
String
usedIp
);
SmsCodeUseReqDTO
convert
(
AppAuthRegReqVO
reqVO
,
Integer
scen
e
,
String
usedIp
);
SmsCodeUseReqDTO
convert
(
AppAuthResetPasswordReqVO
reqVO
,
Sms
Nod
eEnum
scene
,
String
usedIp
);
SmsCodeUseReqDTO
convert
(
AppAuthSmsLoginReqVO
reqVO
,
String
nodeValu
e
,
String
usedIp
);
SmsCodeUseReqDTO
convert
(
AppAuthRegReqVO
reqVO
,
String
nodeValu
e
,
String
usedIp
);
}
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java
View file @
56d736c3
...
...
@@ -2,11 +2,12 @@ package cn.iocoder.yudao.module.member.service.auth;
import
cn.hutool.core.lang.Assert
;
import
cn.hutool.core.util.StrUtil
;
import
cn.iocoder.yudao.framework.common.util.spring.enums.CommonStatusEnum
;
import
cn.iocoder.yudao.framework.common.util.spring.enums.UserTypeEnum
;
import
cn.iocoder.yudao.framework.common.util.date.DateUtils
;
import
cn.iocoder.yudao.framework.common.util.monitor.TracerUtils
;
import
cn.iocoder.yudao.framework.common.util.servlet.ServletUtils
;
import
cn.iocoder.yudao.framework.common.util.spring.enums.CommonStatusEnum
;
import
cn.iocoder.yudao.framework.common.util.spring.enums.UserTypeEnum
;
import
cn.iocoder.yudao.framework.common.util.validation.PhoneUtil
;
import
cn.iocoder.yudao.framework.i18n.core.I18nMessage
;
import
cn.iocoder.yudao.framework.security.core.LoginUser
;
import
cn.iocoder.yudao.framework.security.core.authentication.MultiUsernamePasswordAuthenticationToken
;
...
...
@@ -31,7 +32,7 @@ import cn.iocoder.yudao.module.system.api.social.SocialUserApi;
import
cn.iocoder.yudao.module.system.controller.admin.mail.vo.template.MailTemplateSendReqVO
;
import
cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum
;
import
cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.Sms
Scen
eEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.Sms
Nod
eEnum
;
import
cn.iocoder.yudao.module.system.service.mail.MailSendService
;
import
com.google.common.annotations.VisibleForTesting
;
import
lombok.extern.slf4j.Slf4j
;
...
...
@@ -113,7 +114,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
@Override
public
String
reg
(
@Valid
AppAuthRegReqVO
reqVO
,
String
userIp
,
String
userAgent
,
Boolean
isAutoLogin
)
{
// 校验验证码
smsCodeApi
.
useSmsCode
(
AuthConvert
.
INSTANCE
.
convert
(
reqVO
,
Sms
SceneEnum
.
MEMBER_REG
.
getScen
e
(),
userIp
));
smsCodeApi
.
useSmsCode
(
AuthConvert
.
INSTANCE
.
convert
(
reqVO
,
Sms
NodeEnum
.
MEMBER_REG
.
getNodeValu
e
(),
userIp
));
MemberUserDO
userByMobile
=
userService
.
checkPhoneUnique
(
reqVO
.
getAreaCode
(),
reqVO
.
getMobile
());
if
(
userByMobile
!=
null
)
{
...
...
@@ -164,7 +165,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
@Transactional
public
String
smsLogin
(
AppAuthSmsLoginReqVO
reqVO
,
String
userIp
,
String
userAgent
)
{
// 校验验证码
smsCodeApi
.
useSmsCode
(
AuthConvert
.
INSTANCE
.
convert
(
reqVO
,
Sms
SceneEnum
.
MEMBER_LOGIN
.
getScen
e
(),
userIp
));
smsCodeApi
.
useSmsCode
(
AuthConvert
.
INSTANCE
.
convert
(
reqVO
,
Sms
NodeEnum
.
MEMBER_LOGIN
.
getNodeValu
e
(),
userIp
));
// 获得获得注册用户
MemberUserDO
user
=
userService
.
createUserIfAbsent
(
reqVO
.
getMobile
(),
reqVO
.
getAreaCode
(),
userIp
,
reqVO
.
getLoginPlatform
());
...
...
@@ -388,7 +389,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
MemberUserDO
userDO
=
checkUserIfExists
(
reqVO
.
getMobile
());
// 使用验证码
smsCodeApi
.
useSmsCode
(
AuthConvert
.
INSTANCE
.
convert
(
reqVO
,
Sms
Scen
eEnum
.
MEMBER_FORGET_PASSWORD
,
smsCodeApi
.
useSmsCode
(
AuthConvert
.
INSTANCE
.
convert
(
reqVO
,
Sms
Nod
eEnum
.
MEMBER_FORGET_PASSWORD
,
getClientIP
()));
// 更新密码
...
...
@@ -430,7 +431,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
MemberUserDO
userDO
=
checkUserIfExists
(
reqVO
.
getMobile
());
// 使用验证码
smsCodeApi
.
useSmsCode
(
AuthConvert
.
INSTANCE
.
convert
(
reqVO
,
Sms
Scen
eEnum
.
MEMBER_FORGET_PASSWORD
,
smsCodeApi
.
useSmsCode
(
AuthConvert
.
INSTANCE
.
convert
(
reqVO
,
Sms
Nod
eEnum
.
MEMBER_FORGET_PASSWORD
,
getClientIP
()));
// 更新密码
...
...
@@ -451,10 +452,10 @@ public class MemberAuthServiceImpl implements MemberAuthService {
public
void
sendSmsCode
(
Long
userId
,
AppAuthSendSmsReqVO
reqVO
)
{
String
mobileCode
=
reqVO
.
getAreaCode
()
+
StrUtil
.
COLON
+
reqVO
.
getMobile
();
paramValidatorApi
.
validatorMobile
(
mobileCode
);
//
String mobile = PhoneUtil.formatPhone(mobileCode);
//
if (StringUtils.isNotBlank(mobile)) {
//
reqVO.setMobile(mobile);
//
}
String
mobile
=
PhoneUtil
.
formatPhone
(
mobileCode
);
if
(
StringUtils
.
isNotBlank
(
mobile
))
{
reqVO
.
setMobile
(
mobile
);
}
// TODO 要根据不同的场景,校验是否有用户
smsCodeApi
.
sendSmsCode
(
AuthConvert
.
INSTANCE
.
convert
(
reqVO
).
setCreateIp
(
getClientIP
()));
}
...
...
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java
View file @
56d736c3
...
...
@@ -40,7 +40,7 @@ import cn.iocoder.yudao.module.member.vo.userOperationLog.UserOperationLogCreate
import
cn.iocoder.yudao.module.product.service.coupon.CouponService
;
import
cn.iocoder.yudao.module.system.api.sms.SmsCodeApi
;
import
cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO
;
import
cn.iocoder.yudao.module.system.enums.sms.Sms
Scen
eEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.Sms
Nod
eEnum
;
import
com.alibaba.excel.util.CollectionUtils
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
...
...
@@ -333,7 +333,7 @@ public class MemberUserServiceImpl implements MemberUserService {
.setScene(SmsSceneEnum.MEMBER_UPDATE_MOBILE.getScene()).setUsedIp(getClientIP()));*/
// 使用新验证码
smsCodeApi
.
useSmsCode
(
new
SmsCodeUseReqDTO
().
setMobile
(
reqVO
.
getMobile
()).
setCode
(
reqVO
.
getCode
())
.
set
Scene
(
SmsSceneEnum
.
MEMBER_UPDATE_MOBILE
.
getScen
e
()).
setUsedIp
(
getClientIP
()));
.
set
NodeValue
(
SmsNodeEnum
.
MEMBER_UPDATE_MOBILE
.
getNodeValu
e
()).
setUsedIp
(
getClientIP
()));
// 更新用户手机
memberUserMapper
.
updateById
(
MemberUserDO
.
builder
().
id
(
userId
).
mobile
(
reqVO
.
getMobile
()).
areaCode
(
reqVO
.
getAreaCode
()).
build
());
...
...
yudao-module-order/yudao-module-order-core/src/main/java/cn/iocoder/yudao/module/order/service/orderCargoControl/OrderCargoControlServiceImpl.java
View file @
56d736c3
...
...
@@ -42,7 +42,7 @@ import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
import
cn.iocoder.yudao.module.system.api.sms.SmsCodeApi
;
import
cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO
;
import
cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO
;
import
cn.iocoder.yudao.module.system.enums.sms.Sms
Scen
eEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.Sms
Nod
eEnum
;
import
cn.iocoder.yudao.module.system.framework.ue.UeProperties
;
import
com.alibaba.excel.EasyExcel
;
import
com.alibaba.excel.ExcelWriter
;
...
...
@@ -154,7 +154,7 @@ public class OrderCargoControlServiceImpl extends AbstractService<OrderCargoCont
if
(
StringUtils
.
isNotBlank
(
createReqVO
.
getCode
())
&&
(
StringUtils
.
isBlank
(
createReqVO
.
getControlPassword
())
||
isPasswordError
||
isPasswordNull
))
{
SmsCodeUseReqDTO
smsCodeSendReqDTO
=
new
SmsCodeUseReqDTO
();
smsCodeSendReqDTO
.
setUsedIp
(
getClientIP
());
smsCodeSendReqDTO
.
set
Scene
(
SmsSceneEnum
.
TRANSFER_CONTROL_GOODS
.
getScen
e
());
smsCodeSendReqDTO
.
set
NodeValue
(
SmsNodeEnum
.
TRANSFER_CONTROL_GOODS
.
getNodeValu
e
());
smsCodeSendReqDTO
.
setCode
(
String
.
valueOf
(
createReqVO
.
getCode
()));
smsCodeSendReqDTO
.
setMobile
(
orgOrderCargoControlDO
.
getPhone
());
smsCodeApi
.
useSmsCode
(
smsCodeSendReqDTO
);
...
...
@@ -294,7 +294,12 @@ public class OrderCargoControlServiceImpl extends AbstractService<OrderCargoCont
public
void
sendSmsCode
(
Long
loginUserId
,
OrderSendSmsReqVO
reqVO
,
MemberUserDO
memberUserDO
)
{
SmsCodeSendReqDTO
smsCodeSendReqDTO
=
new
SmsCodeSendReqDTO
();
smsCodeSendReqDTO
.
setCreateIp
(
getClientIP
());
smsCodeSendReqDTO
.
setScene
(
reqVO
.
getScene
());
smsCodeSendReqDTO
.
setNodeValue
(
reqVO
.
getNodeValue
());
smsCodeSendReqDTO
.
setIsTransport
(
reqVO
.
getIsTransport
());
smsCodeSendReqDTO
.
setTransportId
(
reqVO
.
getTransportId
());
smsCodeSendReqDTO
.
setIsOrders
(
reqVO
.
getIsOrders
());
smsCodeSendReqDTO
.
setMessageType
(
reqVO
.
getMessageType
());
OrderCargoControlDO
orderCargoControlDO
=
this
.
getOne
(
new
LambdaQueryWrapper
<
OrderCargoControlDO
>()
.
eq
(
OrderCargoControlDO:
:
getOrderId
,
reqVO
.
getOrderId
())
.
eq
(
OrderCargoControlDO:
:
getIsActual
,
Boolean
.
TRUE
)
...
...
yudao-module-order/yudao-module-order-core/src/main/java/cn/iocoder/yudao/module/order/service/orderCargoControlPick/OrderCargoControlPickServiceImpl.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
order
.
service
.
orderCargoControlPick
;
import
java.math.BigDecimal
;
import
java.math.RoundingMode
;
import
java.text.MessageFormat
;
import
java.util.*
;
import
java.util.stream.Collectors
;
import
cn.hutool.core.collection.CollectionUtil
;
import
cn.hutool.core.date.DateUtil
;
import
cn.hutool.core.util.StrUtil
;
import
cn.iocoder.yudao.framework.common.
util.spring.enums.UserTypeEnum
;
import
cn.iocoder.yudao.framework.common.
pojo.PageResult
;
import
cn.iocoder.yudao.framework.common.util.date.DateUtils
;
import
cn.iocoder.yudao.framework.common.util.spring.enums.UserTypeEnum
;
import
cn.iocoder.yudao.framework.dict.core.dto.DictDataRespDTO
;
import
cn.iocoder.yudao.framework.i18n.core.I18nMessage
;
import
cn.iocoder.yudao.framework.mybatis.core.service.AbstractService
;
import
cn.iocoder.yudao.framework.mybatis.core.vo.PageVO
;
import
cn.iocoder.yudao.framework.security.core.LoginUser
;
import
cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils
;
import
cn.iocoder.yudao.module.bpm.api.BpmCreateServiceFactory
;
...
...
@@ -23,12 +20,16 @@ import cn.iocoder.yudao.module.ecw.api.internalMessage.dto.InternalMessageCreate
import
cn.iocoder.yudao.module.ecw.api.paramValid.ParamValidatorApi
;
import
cn.iocoder.yudao.module.member.api.user.MemberUserApi
;
import
cn.iocoder.yudao.module.member.api.user.dto.UserRespDTO
;
import
cn.iocoder.yudao.module.member.enums.TransportTypeEnum
;
import
cn.iocoder.yudao.module.order.convert.approval.OrderApprovalConvert
;
import
cn.iocoder.yudao.module.order.convert.orderCargoControlPick.OrderCargoControlPickConvert
;
import
cn.iocoder.yudao.module.order.dal.dataobject.approval.OrderApprovalDO
;
import
cn.iocoder.yudao.module.order.dal.dataobject.order.OrderDO
;
import
cn.iocoder.yudao.module.order.dal.dataobject.orderCargoControl.OrderCargoControlDO
;
import
cn.iocoder.yudao.module.order.dal.dataobject.orderCargoControlPick.OrderCargoControlPickDO
;
import
cn.iocoder.yudao.module.order.dal.mysql.approval.OrderApprovalMapper
;
import
cn.iocoder.yudao.module.order.dal.mysql.orderCargoControl.OrderCargoControlMapper
;
import
cn.iocoder.yudao.module.order.dal.mysql.orderCargoControlPick.OrderCargoControlPickMapper
;
import
cn.iocoder.yudao.module.order.dal.mysql.orderPickup.OrderPickupMapper
;
import
cn.iocoder.yudao.module.order.dto.OrderCargoControlReleaseInfoDto
;
import
cn.iocoder.yudao.module.order.param.OrderControlLogParam
;
...
...
@@ -37,12 +38,19 @@ import cn.iocoder.yudao.module.order.service.order.OrderQueryService;
import
cn.iocoder.yudao.module.order.service.order.OrderService
;
import
cn.iocoder.yudao.module.order.service.orderCargoControl.OrderCargoControlService
;
import
cn.iocoder.yudao.module.order.vo.order.OrderBackPageVO
;
import
cn.iocoder.yudao.module.order.vo.orderCargoControlPick.OrderCargoControlPickApplyVO
;
import
cn.iocoder.yudao.module.order.vo.orderCargoControlPick.OrderCargoControlPickCreateReqVO
;
import
cn.iocoder.yudao.module.order.vo.orderCargoControlPick.OrderCargoControlPickQueryVO
;
import
cn.iocoder.yudao.module.order.vo.orderCargoControlPick.OrderCargoControlPickUpdateReqVO
;
import
cn.iocoder.yudao.module.system.api.dict.DictDataApi
;
import
cn.iocoder.yudao.module.system.api.sms.SmsCodeApi
;
import
cn.iocoder.yudao.module.system.api.sms.SmsSendApi
;
import
cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO
;
import
cn.iocoder.yudao.module.system.api.sms.dto.send.SmsSendSingleToUserReqDTO
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum
;
import
cn.iocoder.yudao.module.system.api.sms.dto.send.SmsSendSingleToUserReqDTOV2
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsIsOrdersEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsIsTransportEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsMessageTypeEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsNodeEnum
;
import
com.alibaba.fastjson.JSONObject
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper
;
...
...
@@ -53,15 +61,13 @@ import org.springframework.security.crypto.password.PasswordEncoder;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.validation.annotation.Validated
;
import
cn.iocoder.yudao.framework.mybatis.core.vo.PageVO
;
import
cn.iocoder.yudao.framework.mybatis.core.service.AbstractService
;
import
cn.iocoder.yudao.module.order.vo.orderCargoControlPick.*
;
import
cn.iocoder.yudao.module.order.dal.dataobject.orderCargoControlPick.OrderCargoControlPickDO
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.module.order.convert.orderCargoControlPick.OrderCargoControlPickConvert
;
import
cn.iocoder.yudao.module.order.dal.mysql.orderCargoControlPick.OrderCargoControlPickMapper
;
import
javax.annotation.Resource
;
import
java.math.BigDecimal
;
import
java.math.RoundingMode
;
import
java.text.MessageFormat
;
import
java.util.*
;
import
java.util.stream.Collectors
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
apollo
.
core
.
constants
.
Constants
.
CUSTOMER_USER_APPROVAL_ID
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
apollo
.
core
.
constants
.
Constants
.
CUSTOMER_USER_TO_ADMIN
;
...
...
@@ -69,7 +75,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
servlet
.
ServletUtils
.
getClientIP
;
import
static
cn
.
iocoder
.
yudao
.
module
.
member
.
enums
.
ErrorCodeConstants
.
USER_PASSWORD_FAILED
;
import
static
cn
.
iocoder
.
yudao
.
module
.
order
.
enums
.
ErrorCodeConstants
.*;
import
static
cn
.
iocoder
.
yudao
.
module
.
system
.
enums
.
sms
.
Sms
Scen
eEnum
.
NOTIFICATION_SUCCESS_DELIVERY
;
import
static
cn
.
iocoder
.
yudao
.
module
.
system
.
enums
.
sms
.
Sms
Nod
eEnum
.
NOTIFICATION_SUCCESS_DELIVERY
;
/**
* 订单控货人放货记录 Service 实现类
...
...
@@ -250,7 +256,7 @@ public class OrderCargoControlPickServiceImpl extends AbstractService<OrderCargo
smsCodeSendReqDTO
.
setCode
(
createReqVO
.
getCode
());
smsCodeSendReqDTO
.
setMobile
(
orderCargoControlDO
.
getPhone
());
smsCodeSendReqDTO
.
setUsedIp
(
getClientIP
());
smsCodeSendReqDTO
.
set
Scene
(
SmsSceneEnum
.
DELIVERY_VERIFICATION_SMS
.
getScen
e
());
smsCodeSendReqDTO
.
set
NodeValue
(
SmsNodeEnum
.
DELIVERY_VERIFICATION_SMS
.
getNodeValu
e
());
smsCodeApi
.
useSmsCode
(
smsCodeSendReqDTO
);
isPasswordPick
=
false
;
}
...
...
@@ -525,7 +531,7 @@ public class OrderCargoControlPickServiceImpl extends AbstractService<OrderCargo
smsCodeSendReqDTO
.
setCode
(
orderCargoControlPickApplyVO
.
getCode
());
smsCodeSendReqDTO
.
setMobile
(
orderCargoControlDO
.
getPhone
());
smsCodeSendReqDTO
.
setUsedIp
(
getClientIP
());
smsCodeSendReqDTO
.
set
Scene
(
SmsSceneEnum
.
DELIVERY_VERIFICATION_SMS
.
getScen
e
());
smsCodeSendReqDTO
.
set
NodeValue
(
SmsNodeEnum
.
DELIVERY_VERIFICATION_SMS
.
getNodeValu
e
());
smsCodeApi
.
useSmsCode
(
smsCodeSendReqDTO
);
OrderDO
orderDO
=
orderService
.
getById
(
orderCargoControlPickApplyVO
.
getOrderId
());
...
...
@@ -1100,7 +1106,7 @@ public class OrderCargoControlPickServiceImpl extends AbstractService<OrderCargo
.
set
(
OrderDO:
:
getReleaseNum
,
count
)
.
set
(
OrderDO:
:
getReleaseRatio
,
new
BigDecimal
(
count
).
divide
(
new
BigDecimal
(
orderDO
.
getSumNum
()),
2
,
RoundingMode
.
HALF_UP
).
multiply
(
new
BigDecimal
(
"100"
)))
.
eq
(
OrderDO:
:
getOrderId
,
orderCargoControlPickDO
.
getOrderId
()));
}
else
{
}
else
{
// 放完货的改为放货中
orderService
.
update
(
new
LambdaUpdateWrapper
<
OrderDO
>()
.
set
(
OrderDO:
:
getReleaseNum
,
count
)
...
...
@@ -1162,7 +1168,7 @@ public class OrderCargoControlPickServiceImpl extends AbstractService<OrderCargo
controlLogParam
.
setApprovalId
(
orderApprovalDO
.
getOrderApprovalId
());
controlLogParams
.
add
(
controlLogParam
);
// 发送取消放货短信通知
this
.
smsSendSendSingle
(
orderDO
,
Sms
SceneEnum
.
NOTIFICATION_SUCCESS_CANCEL_DELIVERY
,
0
,
null
,
orderCargoControlPickDO
);
this
.
smsSendSendSingle
(
orderDO
,
Sms
NodeEnum
.
NOTIFICATION_SUCCESS_CANCEL_DELIVERY
.
getNodeValue
()
,
0
,
null
,
orderCargoControlPickDO
);
}
}
orderApprovalMapper
.
updateById
(
orderApprovalDO
);
...
...
@@ -1205,7 +1211,7 @@ public class OrderCargoControlPickServiceImpl extends AbstractService<OrderCargo
return
releaseWeight
;
}
private
void
smsSendSendSingle
(
OrderDO
orderDO
,
S
msSceneEnum
smsSceneEnum
,
Integer
num
,
String
seasoningCondimentsOrderNumbers
,
OrderCargoControlPickDO
orderCargoControlPickDO
)
{
private
void
smsSendSendSingle
(
OrderDO
orderDO
,
S
tring
nodeValue
,
Integer
num
,
String
seasoningCondimentsOrderNumbers
,
OrderCargoControlPickDO
orderCargoControlPickDO
)
{
Map
<
String
,
Object
>
templateParams
=
new
HashMap
<>(
10
);
Calendar
calendar
=
Calendar
.
getInstance
();
int
year
=
calendar
.
get
(
Calendar
.
YEAR
);
...
...
@@ -1226,7 +1232,7 @@ public class OrderCargoControlPickServiceImpl extends AbstractService<OrderCargo
templateParams
.
put
(
"order2"
,
seasoningCondimentsOrderNumbers
);
}
// 定义发送短信的对象map,避免收发货人相同的重复发送
Map
<
String
,
SmsSendSingleToUserReqDTO
>
smsMap
=
new
HashMap
<>(
2
);
Map
<
String
,
SmsSendSingleToUserReqDTO
V2
>
smsMap
=
new
HashMap
<>(
2
);
// OrderConsignorDO orderConsignorDO = orderConsignorService.getOne(new LambdaQueryWrapper<OrderConsignorDO>().eq(OrderConsignorDO::getOrderId, orderDO.getOrderId())
// .orderByDesc(OrderConsignorDO::getId)
// .last("limit 1"));
...
...
@@ -1234,11 +1240,15 @@ public class OrderCargoControlPickServiceImpl extends AbstractService<OrderCargo
String
consignorCountryCode
=
orderCargoControlPickDO
.
getCountryCode
();
String
consignorPhone
=
orderCargoControlPickDO
.
getPhone
();
Long
consignorCustomerId
=
0L
;
// 当前控货人不一定绑定了客户信息,默认给0
SmsSendSingleToUserReqDTO
reqDTO
=
new
SmsSendSingleToUserReqDTO
();
SmsSendSingleToUserReqDTO
V2
reqDTO
=
new
SmsSendSingleToUserReqDTOV2
();
reqDTO
.
setAreaCode
(
consignorCountryCode
);
reqDTO
.
setMobile
(
consignorPhone
);
reqDTO
.
setUserId
(
consignorCustomerId
);
reqDTO
.
setTemplateCode
(
smsSceneEnum
.
getTemplateCode
());
reqDTO
.
setNodeValue
(
nodeValue
);
reqDTO
.
setIsTransport
(
SmsIsTransportEnum
.
SMS_ORDERS_1
.
getValue
());
reqDTO
.
setTransportId
(
orderDO
.
getTransportId
());
reqDTO
.
setIsOrders
(
SmsIsOrdersEnum
.
SMS_ORDERS_0
.
getValue
());
reqDTO
.
setMessageType
(
SmsMessageTypeEnum
.
SMS_MESSAGE_TYPE_1
.
getValue
());
reqDTO
.
setTemplateParams
(
templateParams
);
smsMap
.
put
(
consignorCountryCode
+
consignorPhone
,
reqDTO
);
...
...
@@ -1250,15 +1260,19 @@ public class OrderCargoControlPickServiceImpl extends AbstractService<OrderCargo
String
consigneeCountryCode
=
orderCargoControlPickDO
.
getConsigneeCountryCode
();
String
consigneePhone
=
orderCargoControlPickDO
.
getConsigneePhone
();
Long
consigneeCustomerId
=
0L
;
// 放货记录中的收货人信息未关联客户信息,默认给0
reqDTO
=
new
SmsSendSingleToUserReqDTO
();
reqDTO
=
new
SmsSendSingleToUserReqDTO
V2
();
reqDTO
.
setAreaCode
(
consigneeCountryCode
);
reqDTO
.
setMobile
(
consigneePhone
);
reqDTO
.
setUserId
(
consigneeCustomerId
);
reqDTO
.
setTemplateCode
(
smsSceneEnum
.
getTemplateCode
());
reqDTO
.
setNodeValue
(
nodeValue
);
reqDTO
.
setIsTransport
(
SmsIsTransportEnum
.
SMS_ORDERS_0
.
getValue
());
reqDTO
.
setTransportId
(
TransportTypeEnum
.
OTHER
.
getValue
());
reqDTO
.
setIsOrders
(
SmsIsOrdersEnum
.
SMS_ORDERS_0
.
getValue
());
reqDTO
.
setMessageType
(
SmsMessageTypeEnum
.
SMS_MESSAGE_TYPE_1
.
getValue
());
reqDTO
.
setTemplateParams
(
templateParams
);
smsMap
.
put
(
consigneeCountryCode
+
consigneePhone
,
reqDTO
);
for
(
Map
.
Entry
<
String
,
SmsSendSingleToUserReqDTO
>
entry
:
smsMap
.
entrySet
())
{
smsSendApi
.
sendSingleSmsToAdmin
(
entry
.
getValue
());
for
(
Map
.
Entry
<
String
,
SmsSendSingleToUserReqDTO
V2
>
entry
:
smsMap
.
entrySet
())
{
smsSendApi
.
sendSingleSmsToAdmin
V2
(
entry
.
getValue
());
}
}
...
...
@@ -1274,7 +1288,7 @@ public class OrderCargoControlPickServiceImpl extends AbstractService<OrderCargo
}
OrderDO
orderDO
=
orderService
.
getById
(
orderCargoControlPickDO
.
getOrderId
());
// 发送放货短信通知
this
.
smsSendSendSingle
(
orderDO
,
NOTIFICATION_SUCCESS_DELIVERY
,
orderCargoControlPickDO
.
getPickNum
(),
null
,
orderCargoControlPickDO
);
this
.
smsSendSendSingle
(
orderDO
,
NOTIFICATION_SUCCESS_DELIVERY
.
getNodeValue
()
,
orderCargoControlPickDO
.
getPickNum
(),
null
,
orderCargoControlPickDO
);
// 需要处理订单状态
OrderCargoControlReleaseInfoDto
releaseInfoDto
=
orderCargoControlMapper
.
getOrderCargoControlReleaseInfo
(
orderCargoControlPickDO
.
getOrderId
());
if
(
Objects
.
nonNull
(
releaseInfoDto
))
{
...
...
yudao-module-order/yudao-module-order-core/src/main/java/cn/iocoder/yudao/module/order/service/orderWarehouseIn/OrderWarehouseInServiceImpl.java
View file @
56d736c3
...
...
@@ -5,9 +5,9 @@ import cn.hutool.core.collection.CollectionUtil;
import
cn.hutool.core.date.DateTime
;
import
cn.hutool.core.date.DateUtil
;
import
cn.hutool.core.util.StrUtil
;
import
cn.iocoder.yudao.framework.apollo.core.event.box.BoxCheckOrderSchedulingEvent
;
import
cn.iocoder.yudao.framework.apollo.core.event.Order.OrderApprovalTypeCheckEvent
;
import
cn.iocoder.yudao.framework.apollo.core.event.QueryChannelInfoEvent
;
import
cn.iocoder.yudao.framework.apollo.core.event.box.BoxCheckOrderSchedulingEvent
;
import
cn.iocoder.yudao.framework.apollo.core.event.box.BoxOrderRevokeWarehouseCheckEvent
;
import
cn.iocoder.yudao.framework.apollo.core.event.box.BoxOrderShipmentWarehouseInEvent
;
import
cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil
;
...
...
@@ -106,8 +106,11 @@ import cn.iocoder.yudao.module.product.vo.productbrandempower.GetFeeTypeProductB
import
cn.iocoder.yudao.module.product.vo.productbrandempower.GetFeeTypeProductBrandEmpowerRespVO
;
import
cn.iocoder.yudao.module.system.api.dict.DictDataApi
;
import
cn.iocoder.yudao.module.system.api.sms.SmsSendApi
;
import
cn.iocoder.yudao.module.system.api.sms.dto.send.SmsSendSingleToUserReqDTO
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum
;
import
cn.iocoder.yudao.module.system.api.sms.dto.send.SmsSendSingleToUserReqDTOV2
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsIsOrdersEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsIsTransportEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsMessageTypeEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsNodeEnum
;
import
cn.iocoder.yudao.module.wealth.dal.dataobject.receivable.ReceivableDO
;
import
cn.iocoder.yudao.module.wealth.service.receivable.ReceivableService
;
import
cn.iocoder.yudao.module.wealth.vo.receivable.ReceivableQueryVO
;
...
...
@@ -2321,24 +2324,26 @@ public class OrderWarehouseInServiceImpl extends AbstractService<OrderWarehouseI
paramMap
.
put
(
"cbm"
,
chargeWeight
);
String
templateCode
=
SmsSceneEnum
.
WAREHOUSE_IN_APPEND
.
getTemplateCod
e
();
String
nodeValue
=
SmsNodeEnum
.
WAREHOUSE_IN_APPEND
.
getNodeValu
e
();
log
.
info
(
"warehouseInSendSms追加入仓短信 orderNo={}"
,
orderDO
.
getOrderNo
());
SmsSendSingleToUserReqDTO
reqDTO
=
new
SmsSendSingleToUserReqDTO
();
SmsSendSingleToUserReqDTO
V2
reqDTO
=
new
SmsSendSingleToUserReqDTOV2
();
reqDTO
.
setTemplateParams
(
paramMap
);
reqDTO
.
set
TemplateCode
(
templateCod
e
);
reqDTO
.
set
NodeValue
(
nodeValu
e
);
reqDTO
.
setUserId
(
consignorCustomerId
);
reqDTO
.
setMobile
(
consignorPhone
);
reqDTO
.
setAreaCode
(
consignorCountryCode
);
reqDTO
.
setIsTransport
(
SmsIsTransportEnum
.
SMS_ORDERS_1
.
getValue
());
reqDTO
.
setTransportId
(
orderDO
.
getTransportId
());
reqDTO
.
setIsOrders
(
SmsIsOrdersEnum
.
SMS_ORDERS_0
.
getValue
());
reqDTO
.
setMessageType
(
SmsMessageTypeEnum
.
SMS_MESSAGE_TYPE_1
.
getValue
());
// 发送追加通知短信
this
.
smsSendNotice
(
consignorCountryCode
,
consignorPhone
,
consignorCustomerId
,
templateCode
,
paramMap
);
smsSendApi
.
sendSingleSmsToAdminV2
(
reqDTO
);
}
else
{
// 入仓短信 发送给发货人与收货人
String
templateCode
=
SmsSceneEnum
.
WAREHOUSE_IN
.
getTemplateCode
();
if
(
orderDO
.
getTransportId
()
==
3
)
{
templateCode
=
SmsSceneEnum
.
AIR_WAREHOUSE_IN
.
getTemplateCode
();
}
String
nodeValue
=
SmsNodeEnum
.
WAREHOUSE_IN
.
getNodeValue
();
log
.
info
(
"warehouseInSendSms入仓短信 orderNo={}"
,
orderDO
.
getOrderNo
());
try
{
// 控货 就发给控货人, 非控货就发给发件人和收件人
...
...
@@ -2377,14 +2382,20 @@ public class OrderWarehouseInServiceImpl extends AbstractService<OrderWarehouseI
// cargoControlParamMap.put("collectofgoods", orderDO.getCollectionProxy() + currencyName);
// templateCode = SmsSceneEnum.WAREHOUSE_IN_CONTROL_COLLECT_OF_GOODS.getTemplateCode();
// } else {
if
(
orderDO
.
getTransportId
()
==
3
)
{
templateCode
=
SmsSceneEnum
.
AIR_WAREHOUSE_IN_CONTROL
.
getTemplateCode
();
}
else
{
templateCode
=
SmsSceneEnum
.
WAREHOUSE_IN_CONTROL
.
getTemplateCode
();
}
nodeValue
=
SmsNodeEnum
.
WAREHOUSE_IN_CONTROL
.
getNodeValue
();
// }
// 给控货人发送入仓控货成功短信
this
.
smsSendNotice
(
cargoControlCode
,
cargoControlPhone
,
cargoControlCustomerId
,
templateCode
,
cargoControlParamMap
);
SmsSendSingleToUserReqDTOV2
reqDTO
=
new
SmsSendSingleToUserReqDTOV2
();
reqDTO
.
setTemplateParams
(
cargoControlParamMap
);
reqDTO
.
setNodeValue
(
nodeValue
);
reqDTO
.
setUserId
(
cargoControlCustomerId
);
reqDTO
.
setMobile
(
cargoControlPhone
);
reqDTO
.
setAreaCode
(
cargoControlCode
);
reqDTO
.
setIsTransport
(
SmsIsTransportEnum
.
SMS_ORDERS_1
.
getValue
());
reqDTO
.
setTransportId
(
orderDO
.
getTransportId
());
reqDTO
.
setIsOrders
(
SmsIsOrdersEnum
.
SMS_ORDERS_0
.
getValue
());
reqDTO
.
setMessageType
(
SmsMessageTypeEnum
.
SMS_MESSAGE_TYPE_1
.
getValue
());
smsSendApi
.
sendSingleSmsToAdminV2
(
reqDTO
);
}
}
else
{
Map
<
String
,
Object
>
consignorParamMap
=
new
HashMap
<>();
...
...
@@ -2416,16 +2427,22 @@ public class OrderWarehouseInServiceImpl extends AbstractService<OrderWarehouseI
consignorParamMap
.
put
(
"collectofgoods"
,
orderDO
.
getCollectionProxy
()
+
currencyName
);
consigneeParamMap
.
put
(
"collectofgoods"
,
orderDO
.
getCollectionProxy
()
+
currencyName
);
// 入仓通知
if
(
orderDO
.
getTransportId
()
==
3
)
{
templateCode
=
SmsSceneEnum
.
AIR_WAREHOUSE_IN_COLLECT_OF_GOODS
.
getTemplateCode
();
}
else
{
templateCode
=
SmsSceneEnum
.
WAREHOUSE_IN_COLLECT_OF_GOODS
.
getTemplateCode
();
}
nodeValue
=
SmsNodeEnum
.
WAREHOUSE_IN_COLLECT_OF_GOODS
.
getNodeValue
();
log
.
info
(
"warehouseInSendSms非控货代收货款入仓短信 orderNo={}"
,
orderDO
.
getOrderNo
());
}
// 给发货人发送短信
this
.
smsSendNotice
(
consignorCountryCode
,
consignorPhone
,
consignorCustomerId
,
templateCode
,
consignorParamMap
);
SmsSendSingleToUserReqDTOV2
reqDTO
=
new
SmsSendSingleToUserReqDTOV2
();
reqDTO
.
setTemplateParams
(
consignorParamMap
);
reqDTO
.
setNodeValue
(
nodeValue
);
reqDTO
.
setUserId
(
consignorCustomerId
);
reqDTO
.
setMobile
(
consignorPhone
);
reqDTO
.
setAreaCode
(
consignorCountryCode
);
reqDTO
.
setIsTransport
(
SmsIsTransportEnum
.
SMS_ORDERS_1
.
getValue
());
reqDTO
.
setTransportId
(
orderDO
.
getTransportId
());
reqDTO
.
setIsOrders
(
SmsIsOrdersEnum
.
SMS_ORDERS_0
.
getValue
());
reqDTO
.
setMessageType
(
SmsMessageTypeEnum
.
SMS_MESSAGE_TYPE_1
.
getValue
());
smsSendApi
.
sendSingleSmsToAdminV2
(
reqDTO
);
// 收货人 短信发送信息
OrderConsigneeDO
orderConsigneeDO
=
orderConsigneeService
.
getOne
(
new
LambdaQueryWrapper
<
OrderConsigneeDO
>().
eq
(
OrderConsigneeDO:
:
getOrderId
,
orderDO
.
getOrderId
())
...
...
@@ -2457,7 +2474,17 @@ public class OrderWarehouseInServiceImpl extends AbstractService<OrderWarehouseI
}
if
(!
StringUtils
.
equals
(
consignorCountryCode
.
concat
(
consignorPhone
),
consigneeCountryCode
.
concat
(
consigneePhone
)))
{
// 给收货人发送短信
this
.
smsSendNotice
(
consigneeCountryCode
,
consigneePhone
,
consigneeCustomerId
,
templateCode
,
consigneeParamMap
);
SmsSendSingleToUserReqDTOV2
reqDTO2
=
new
SmsSendSingleToUserReqDTOV2
();
reqDTO2
.
setTemplateParams
(
consigneeParamMap
);
reqDTO2
.
setNodeValue
(
nodeValue
);
reqDTO2
.
setUserId
(
consigneeCustomerId
);
reqDTO2
.
setMobile
(
consigneePhone
);
reqDTO2
.
setAreaCode
(
consigneeCountryCode
);
reqDTO2
.
setIsTransport
(
SmsIsTransportEnum
.
SMS_ORDERS_1
.
getValue
());
reqDTO2
.
setTransportId
(
orderDO
.
getTransportId
());
reqDTO2
.
setIsOrders
(
SmsIsOrdersEnum
.
SMS_ORDERS_0
.
getValue
());
reqDTO2
.
setMessageType
(
SmsMessageTypeEnum
.
SMS_MESSAGE_TYPE_1
.
getValue
());
smsSendApi
.
sendSingleSmsToAdminV2
(
reqDTO2
);
}
}
}
...
...
@@ -2472,16 +2499,16 @@ public class OrderWarehouseInServiceImpl extends AbstractService<OrderWarehouseI
}
}
private
void
smsSendNotice
(
String
countryCode
,
String
phone
,
Long
customerId
,
String
templateCode
,
Map
<
String
,
Object
>
paramMap
)
{
SmsSendSingleToUserReqDTO
reqDTO
=
new
SmsSendSingleToUserReqDTO
();
reqDTO
.
setTemplateParams
(
paramMap
);
reqDTO
.
setTemplateCode
(
templateCode
);
reqDTO
.
setUserId
(
customerId
);
reqDTO
.
setMobile
(
phone
);
reqDTO
.
setAreaCode
(
countryCode
);
// 给发货人发送短信
smsSendApi
.
sendSingleSmsToAdmin
(
reqDTO
);
}
//
private void smsSendNotice(String countryCode, String phone, Long customerId, String templateCode, Map<String, Object> paramMap) {
//
SmsSendSingleToUserReqDTO reqDTO = new SmsSendSingleToUserReqDTO();
//
reqDTO.setTemplateParams(paramMap);
//
reqDTO.setTemplateCode(templateCode);
//
reqDTO.setUserId(customerId);
//
reqDTO.setMobile(phone);
//
reqDTO.setAreaCode(countryCode);
//
// 给发货人发送短信
// smsSendApi.sendSingleSmsToAdminV2
(reqDTO);
//
}
private
void
warehouseInSendInternalMessage
(
OrderWarehouseInFinishReqVO
finishReqVO
,
OrderDO
orderDO
,
OrderConsignorDO
orderConsignorDO
,
String
exceptionContent
)
{
if
(
orderDO
.
getHasSendWarehouseInNotice
())
{
...
...
yudao-module-order/yudao-module-order-core/src/main/java/cn/iocoder/yudao/module/order/vo/order/OrderSendSmsReqVO.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
order
.
vo
.
order
;
import
cn.iocoder.yudao.framework.common.validation.InEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
...
...
@@ -16,9 +14,21 @@ public class OrderSendSmsReqVO {
@NotNull
(
message
=
"{order.id.not.null}"
)
private
Long
orderId
;
@ApiModelProperty
(
value
=
"发送场景(4 控货全转移 5 放货验证短信 6 放货成功通知)"
,
example
=
"1"
,
notes
=
"对应 SmsSceneEnum 枚举"
,
required
=
true
)
@NotNull
(
message
=
"{app.sms.scene.not.blank}"
)
@InEnum
(
value
=
SmsSceneEnum
.
class
,
message
=
"{app.sms.scene.not.range}"
)
private
Integer
scene
;
/**
* 发送场景
*/
@NotNull
(
message
=
"业务节点不能为空"
)
private
String
nodeValue
;
@NotNull
(
message
=
"是否匹配运输方式不能为空"
)
private
Integer
isTransport
;
@NotNull
(
message
=
"运输方式不能空"
)
private
Integer
transportId
;
@NotNull
(
message
=
"是否多订单不能为空"
)
private
Integer
isOrders
;
@NotNull
(
message
=
"发送类型不能为空"
)
private
Integer
messageType
;
}
yudao-module-reward/yudao-module-reward-api/src/main/java/cn/iocoder/yudao/module/reward/api/reward/RedeemRewardApi.java
View file @
56d736c3
...
...
@@ -57,7 +57,6 @@ public interface RedeemRewardApi {
/**
* 兑换礼品发送验证码
* @param memberId
*/
void
sendSmsCode
(
Long
memberId
);
void
sendSmsCode
(
RedeemRewardRespDTO
reqVO
);
}
yudao-module-reward/yudao-module-reward-api/src/main/java/cn/iocoder/yudao/module/reward/api/reward/dto/RedeemRewardRespDTO.java
View file @
56d736c3
...
...
@@ -4,6 +4,8 @@ import io.swagger.annotations.ApiModel;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
import
javax.validation.constraints.NotNull
;
@Data
@ApiModel
(
"管理后台 - 礼品兑换 Response VO"
)
public
class
RedeemRewardRespDTO
{
...
...
@@ -14,4 +16,23 @@ public class RedeemRewardRespDTO {
private
String
msgZh
;
@ApiModelProperty
(
value
=
"兑换操作详情英文"
)
private
String
msgEn
;
@ApiModelProperty
(
value
=
"会员id"
)
@NotNull
(
message
=
"会员id不能为空"
)
private
Long
memberId
;
@NotNull
(
message
=
"业务节点不能为空"
)
private
String
nodeValue
;
@NotNull
(
message
=
"是否匹配运输方式不能为空"
)
private
Integer
isTransport
;
@NotNull
(
message
=
"运输方式不能空"
)
private
Integer
transportId
;
@NotNull
(
message
=
"是否多订单不能为空"
)
private
Integer
isOrders
;
@NotNull
(
message
=
"发送类型不能为空"
)
private
Integer
messageType
;
}
yudao-module-reward/yudao-module-reward-impl/src/main/java/cn/iocoder/yudao/module/reward/api/reward/RedeemRewardApiImpl.java
View file @
56d736c3
...
...
@@ -25,7 +25,7 @@ import cn.iocoder.yudao.module.reward.util.RewardGenCodeUtils;
import
cn.iocoder.yudao.module.system.api.sms.SmsCodeApi
;
import
cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO
;
import
cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO
;
import
cn.iocoder.yudao.module.system.enums.sms.Sms
Scen
eEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.Sms
Nod
eEnum
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
...
...
@@ -86,7 +86,7 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
smsCodeUseReqDTO
.
setMobile
(
memberUser
.
getMobile
());
smsCodeUseReqDTO
.
setCode
(
appRedeemRewardReqVO
.
getCode
());
smsCodeUseReqDTO
.
setUsedIp
(
getClientIP
());
smsCodeUseReqDTO
.
set
Scene
(
SmsSceneEnum
.
MEMBER_REDEEM_REWARD
.
getScen
e
());
smsCodeUseReqDTO
.
set
NodeValue
(
SmsNodeEnum
.
MEMBER_REDEEM_REWARD
.
getNodeValu
e
());
smsCodeApi
.
useSmsCode
(
smsCodeUseReqDTO
);
}
// 校验收货人信息
...
...
@@ -282,7 +282,8 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
}
@Override
public
void
sendSmsCode
(
Long
memberId
)
{
public
void
sendSmsCode
(
RedeemRewardRespDTO
reqVO
)
{
Long
memberId
=
reqVO
.
getMemberId
();
UserRespDTO
memberUserApiUser
=
memberUserApi
.
getUser
(
memberId
);
if
(
memberUserApiUser
==
null
)
{
throw
exception
(
USER_NOT_EXISTS
);
...
...
@@ -291,8 +292,12 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
smsCodeSendReqDTO
.
setMobile
(
memberUserApiUser
.
getMobile
());
smsCodeSendReqDTO
.
setAreaCode
(
memberUserApiUser
.
getAreaCode
());
smsCodeSendReqDTO
.
setCreateIp
(
getClientIP
());
smsCodeSendReqDTO
.
setScene
(
SmsSceneEnum
.
MEMBER_REDEEM_REWARD
.
getScene
());
smsCodeSendReqDTO
.
setNodeValue
(
reqVO
.
getNodeValue
());
smsCodeSendReqDTO
.
setIsTransport
(
reqVO
.
getIsTransport
());
smsCodeSendReqDTO
.
setTransportId
(
reqVO
.
getTransportId
());
smsCodeSendReqDTO
.
setIsOrders
(
reqVO
.
getIsOrders
());
smsCodeSendReqDTO
.
setMessageType
(
reqVO
.
getMessageType
());
smsCodeApi
.
sendSmsCode
(
smsCodeSendReqDTO
);
}
...
...
yudao-module-reward/yudao-module-reward-impl/src/main/java/cn/iocoder/yudao/module/reward/controller/app/redeem/AppRedeemRewardController.java
View file @
56d736c3
...
...
@@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
import
cn.iocoder.yudao.framework.idempotent.core.annotation.Idempotent
;
import
cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog
;
import
cn.iocoder.yudao.module.reward.api.reward.RedeemRewardApi
;
import
cn.iocoder.yudao.module.reward.api.reward.dto.RedeemRewardRespDTO
;
import
cn.iocoder.yudao.module.reward.controller.app.redeem.vo.*
;
import
cn.iocoder.yudao.module.reward.service.redeem.RewardRedeemService
;
import
cn.iocoder.yudao.module.reward.vo.reward.RewardRedeemPageRespVO
;
...
...
@@ -74,8 +75,8 @@ public class AppRedeemRewardController {
@ApiOperation
(
value
=
"兑换礼品发送手机验证码"
)
@OperateLog
(
enable
=
false
)
// 避免 Post 请求被记录操作日志
@Idempotent
(
timeout
=
5
)
public
CommonResult
<
Boolean
>
sendSmsCode
(
@RequestBody
@Valid
AppRewardRedeemReqV
O
reqVO
)
{
redeemRewardApi
.
sendSmsCode
(
reqVO
.
getMemberId
()
);
public
CommonResult
<
Boolean
>
sendSmsCode
(
@RequestBody
@Valid
RedeemRewardRespDT
O
reqVO
)
{
redeemRewardApi
.
sendSmsCode
(
reqVO
);
return
success
(
true
);
}
}
yudao-module-shipment/yudao-module-shipment-core/src/main/java/cn/iocoder/yudao/module/shipment/dal/dataobject/BoxOrderSmsLogDO.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
shipment
.
dal
.
dataobject
;
import
lombok.*
;
import
java.util.*
;
import
com.baomidou.mybatisplus.annotation.*
;
import
cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO
;
import
com.baomidou.mybatisplus.annotation.TableId
;
import
com.baomidou.mybatisplus.annotation.TableName
;
import
lombok.*
;
/**
* 出货短信记录 DO
...
...
@@ -47,7 +47,7 @@ public class BoxOrderSmsLogDO extends BaseDO {
/**
* 场景编码
*/
private
Integer
scen
e
;
private
String
nodeValu
e
;
/**
* 说明
*/
...
...
yudao-module-shipment/yudao-module-shipment-core/src/main/java/cn/iocoder/yudao/module/shipment/dal/mysql/BoxOrderSmsLogMapper.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
shipment
.
dal
.
mysql
;
import
java.util.*
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.mybatis.core.query.LambdaQuery
;
import
cn.iocoder.yudao.framework.mybatis.core.mapper.AbstractMapper
;
import
cn.iocoder.yudao.
module.shipment.dal.dataobject.BoxOrderSmsLogDO
;
import
cn.iocoder.yudao.
framework.mybatis.core.query.LambdaQuery
;
import
cn.iocoder.yudao.framework.mybatis.core.vo.PageVO
;
import
cn.iocoder.yudao.module.shipment.dal.dataobject.BoxOrderSmsLogDO
;
import
cn.iocoder.yudao.module.shipment.vo.boxOrderSmsLog.BoxOrderSmsLogQueryVO
;
import
org.apache.ibatis.annotations.Mapper
;
import
cn.iocoder.yudao.module.shipment.vo.boxOrderSmsLog.*
;
import
java.util.List
;
/**
* 出货短信记录 Mapper
...
...
@@ -25,7 +26,7 @@ public interface BoxOrderSmsLogMapper extends AbstractMapper<BoxOrderSmsLogDO> {
.
eqIfPresent
(
BoxOrderSmsLogDO:
:
getOrderNo
,
vo
.
getOrderNo
())
.
eqIfPresent
(
BoxOrderSmsLogDO:
:
getMarks
,
vo
.
getMarks
())
.
eqIfPresent
(
BoxOrderSmsLogDO:
:
getSelfNo
,
vo
.
getSelfNo
())
.
eqIfPresent
(
BoxOrderSmsLogDO:
:
get
Scene
,
vo
.
getScen
e
())
.
eqIfPresent
(
BoxOrderSmsLogDO:
:
get
NodeValue
,
vo
.
getNodeValu
e
())
.
eqIfPresent
(
BoxOrderSmsLogDO:
:
getTemplateCode
,
vo
.
getTemplateCode
())
.
eqIfPresent
(
BoxOrderSmsLogDO:
:
getDescription
,
vo
.
getDescription
())
.
betweenIfPresent
(
BoxOrderSmsLogDO:
:
getCreateTime
,
vo
.
getBeginCreateTime
(),
vo
.
getEndCreateTime
())
...
...
@@ -45,7 +46,7 @@ public interface BoxOrderSmsLogMapper extends AbstractMapper<BoxOrderSmsLogDO> {
.
eqIfPresent
(
BoxOrderSmsLogDO:
:
getOrderNo
,
vo
.
getOrderNo
())
.
eqIfPresent
(
BoxOrderSmsLogDO:
:
getMarks
,
vo
.
getMarks
())
.
eqIfPresent
(
BoxOrderSmsLogDO:
:
getSelfNo
,
vo
.
getSelfNo
())
.
eqIfPresent
(
BoxOrderSmsLogDO:
:
get
Scene
,
vo
.
getScen
e
())
.
eqIfPresent
(
BoxOrderSmsLogDO:
:
get
NodeValue
,
vo
.
getNodeValu
e
())
.
eqIfPresent
(
BoxOrderSmsLogDO:
:
getTemplateCode
,
vo
.
getTemplateCode
())
.
eqIfPresent
(
BoxOrderSmsLogDO:
:
getDescription
,
vo
.
getDescription
())
.
betweenIfPresent
(
BoxOrderSmsLogDO:
:
getCreateTime
,
vo
.
getBeginCreateTime
(),
vo
.
getEndCreateTime
())
...
...
yudao-module-shipment/yudao-module-shipment-core/src/main/java/cn/iocoder/yudao/module/shipment/service/box/BoxService.java
View file @
56d736c3
...
...
@@ -35,7 +35,7 @@ import cn.iocoder.yudao.module.shipment.vo.boxPreloadSection.BoxLoadSectionBackV
import
cn.iocoder.yudao.module.shipment.vo.boxTally.BoxGuanlianOrderBackVO
;
import
cn.iocoder.yudao.module.shipment.vo.boxTally.BoxOrderLocationUpdateReq
;
import
cn.iocoder.yudao.module.shipment.vo.boxTally.BoxTallyBackVO
;
import
cn.iocoder.yudao.module.system.enums.sms.Sms
Scen
eEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.Sms
Nod
eEnum
;
import
org.springframework.context.annotation.Description
;
import
javax.validation.Valid
;
...
...
@@ -141,11 +141,11 @@ public interface BoxService extends IService<BoxDO> {
* 发送短信
*
* @param shipment 出货单
* @param sms
Scen
eEnum 场景
* @param sms
Nod
eEnum 场景
*/
void
sendSms
(
Long
shipment
,
Sms
SceneEnum
smsScen
eEnum
);
void
sendSms
(
Long
shipment
,
Sms
NodeEnum
smsNod
eEnum
);
void
sendSms
(
Long
shipmentId
,
Collection
<
Long
>
orderIdList
,
Sms
SceneEnum
smsScen
eEnum
);
void
sendSms
(
Long
shipmentId
,
Collection
<
Long
>
orderIdList
,
Sms
NodeEnum
smsNod
eEnum
);
/**
* 新增销售日志
...
...
yudao-module-shipment/yudao-module-shipment-core/src/main/java/cn/iocoder/yudao/module/shipment/service/box/BoxServiceImpl.java
View file @
56d736c3
...
...
@@ -189,11 +189,14 @@ import cn.iocoder.yudao.module.shipment.vo.boxTally.BoxTallyBackVO;
import
cn.iocoder.yudao.module.shipment.vo.boxTally.BoxTallyVO
;
import
cn.iocoder.yudao.module.shipment.vo.boxTrailer.BoxTrailerBackVO
;
import
cn.iocoder.yudao.module.system.api.sms.SmsSendApi
;
import
cn.iocoder.yudao.module.system.api.sms.dto.send.SmsSendSingleToUserReqDTO
;
import
cn.iocoder.yudao.module.system.api.sms.dto.send.SmsSendSingleToUserReqDTO
V2
;
import
cn.iocoder.yudao.module.system.api.user.AdminUserApi
;
import
cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataPageReqVO
;
import
cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsIsOrdersEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsIsTransportEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsMessageTypeEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsNodeEnum
;
import
cn.iocoder.yudao.module.system.service.dict.DictDataService
;
import
cn.iocoder.yudao.module.wealth.dal.dataobject.receivable.ReceivableDO
;
import
cn.iocoder.yudao.module.wealth.service.receivable.ReceivableService
;
...
...
@@ -1594,7 +1597,7 @@ public class BoxServiceImpl extends AbstractService<BoxMapper, BoxDO> implements
@Override
public
void
sendSms
(
Long
shipmentId
,
Sms
SceneEnum
smsScen
eEnum
)
{
public
void
sendSms
(
Long
shipmentId
,
Sms
NodeEnum
smsNod
eEnum
)
{
// log.info("出货单【{}】, 暂停出货短信通知发送", shipmentId);
// if (Boolean.TRUE){
// return;
...
...
@@ -1605,12 +1608,12 @@ public class BoxServiceImpl extends AbstractService<BoxMapper, BoxDO> implements
log
.
error
(
"出货单【{}】, 未找到订单,发送短信失败"
,
shipmentId
);
return
;
}
log
.
info
(
"出货单【{}】, {}短信发送"
,
shipmentId
,
sms
Scen
eEnum
.
getDescription
());
sendSms
(
shipmentId
,
orderIdList
,
sms
Scen
eEnum
);
log
.
info
(
"出货单【{}】, {}短信发送"
,
shipmentId
,
sms
Nod
eEnum
.
getDescription
());
sendSms
(
shipmentId
,
orderIdList
,
sms
Nod
eEnum
);
}
@Override
public
void
sendSms
(
Long
shipmentId
,
Collection
<
Long
>
orderIdList
,
Sms
SceneEnum
smsScen
eEnum
)
{
public
void
sendSms
(
Long
shipmentId
,
Collection
<
Long
>
orderIdList
,
Sms
NodeEnum
smsNod
eEnum
)
{
// 对订单列表进行分组, 统计通知发送人的订单数量,当通知人的订单数量大于1,切换模板,合并订单号逗号连接发送一次
Map
<
String
,
List
<
Map
<
String
,
String
>>>
sendPhoneMap
=
new
HashMap
<>();
Map
<
String
,
Object
>
templateParams
=
new
HashMap
<>();
...
...
@@ -1621,17 +1624,17 @@ public class BoxServiceImpl extends AbstractService<BoxMapper, BoxDO> implements
long
count
=
boxOrderSmsLogService
.
count
(
new
LambdaQueryWrapper
<
BoxOrderSmsLogDO
>()
.
eq
(
BoxOrderSmsLogDO:
:
getOrderId
,
orderId
)
.
eq
(
BoxOrderSmsLogDO:
:
getShipmentId
,
shipmentId
)
.
eq
(
BoxOrderSmsLogDO:
:
get
Scene
,
smsSceneEnum
.
getScen
e
()));
.
eq
(
BoxOrderSmsLogDO:
:
get
NodeValue
,
smsNodeEnum
.
getNodeValu
e
()));
if
(
count
>
0
)
{
// 当前货柜的当前订单已发送过短信,则不再发送
log
.
info
(
"出货单【{}】,订单ID【{}】, {}短信已发送过"
,
shipmentId
,
orderId
,
sms
Scen
eEnum
.
getDescription
());
log
.
info
(
"出货单【{}】,订单ID【{}】, {}短信已发送过"
,
shipmentId
,
orderId
,
sms
Nod
eEnum
.
getDescription
());
continue
;
}
OrderBackVO
orderBackVO
=
orderQueryService
.
getOrder
(
orderId
);
String
orderNo
=
orderBackVO
.
getOrderNo
();
String
marks
=
orderBackVO
.
getMarks
();
// 封装货柜订单短信发送记录
this
.
addBoxOrderSmsLog
(
shipmentId
,
sms
Scen
eEnum
,
boxOrderSmsLogDOList
,
orderId
,
orderNo
,
marks
);
this
.
addBoxOrderSmsLog
(
shipmentId
,
sms
Nod
eEnum
,
boxOrderSmsLogDOList
,
orderId
,
orderNo
,
marks
);
Map
<
String
,
String
>
orderMap
=
new
HashMap
<>(
2
);
orderMap
.
put
(
"orderNo"
,
orderNo
);
...
...
@@ -1679,10 +1682,11 @@ public class BoxServiceImpl extends AbstractService<BoxMapper, BoxDO> implements
marks
.
append
(
m
);
}
if
(
i
%
3
==
0
||
i
==
orderNoList
.
size
())
{
String
templateCode
=
smsSceneEnum
.
getTemplateCode
();
String
nodeValue
=
smsNodeEnum
.
getNodeValue
();
Integer
isOrders
=
SmsIsOrdersEnum
.
SMS_ORDERS_0
.
getValue
();
this
.
setTimeParams
(
templateParams
);
templateParams
.
put
(
"marks"
,
marks
);
switch
(
sms
Scen
eEnum
)
{
switch
(
sms
Nod
eEnum
)
{
case
SHIPMENT_CABINET:
BoxCabinetDO
boxCabinetDO
=
boxCabinetService
.
getByShipmentId
(
boxDO
.
getId
());
if
(
Objects
.
nonNull
(
boxCabinetDO
)
&&
Objects
.
nonNull
(
boxCabinetDO
.
getLdBoxTime
()))
{
...
...
@@ -1695,7 +1699,8 @@ public class BoxServiceImpl extends AbstractService<BoxMapper, BoxDO> implements
}
// 装柜通知
if
(
orderNoList
.
size
()
>
1
)
{
templateCode
=
SmsSceneEnum
.
SHIPMENT_CABINETS
.
getTemplateCode
();
nodeValue
=
SmsNodeEnum
.
SHIPMENT_CABINET
.
getNodeValue
();
isOrders
=
SmsIsOrdersEnum
.
SMS_ORDERS_1
.
getValue
();
templateParams
.
put
(
"orders"
,
orders
.
toString
());
}
else
{
templateParams
.
put
(
"order"
,
orders
.
toString
());
...
...
@@ -1712,7 +1717,8 @@ public class BoxServiceImpl extends AbstractService<BoxMapper, BoxDO> implements
templateParams
.
put
(
"day"
,
shipmentWarehouseTime
.
dayOfMonth
());
}
if
(
orderNoList
.
size
()
>
1
)
{
templateCode
=
SmsSceneEnum
.
AIR_SHIPMENT_WAREHOUSES
.
getTemplateCode
();
nodeValue
=
SmsNodeEnum
.
AIR_SHIPMENT_WAREHOUSE
.
getNodeValue
();
isOrders
=
SmsIsOrdersEnum
.
SMS_ORDERS_1
.
getValue
();
templateParams
.
put
(
"orders"
,
orders
.
toString
());
}
else
{
templateParams
.
put
(
"order"
,
orders
.
toString
());
...
...
@@ -1724,53 +1730,45 @@ public class BoxServiceImpl extends AbstractService<BoxMapper, BoxDO> implements
break
;
case
SHIPMENT_ARRIVAL:
// 到港通知
if
(
orderNoList
.
size
()
>
1
)
{
templateCode
=
SmsSceneEnum
.
SHIPMENT_ARRIVALS
.
getTemplateCode
();
templateParams
.
put
(
"orders"
,
orders
.
toString
());
}
else
{
templateParams
.
put
(
"order"
,
orders
.
toString
());
}
break
;
case
AIR_SHIPMENT_ARRIVAL:
// 空运到港通知
// 单号:${orders}( 航班号:${number})的货物已到港,清关中。如您的是控货单请及时放货,客服电话:400 9009962(9:00--18:00)
if
(
orderNoList
.
size
()
>
1
)
{
templateCode
=
SmsSceneEnum
.
AIR_SHIPMENT_ARRIVALS
.
getTemplateCod
e
();
}
nodeValue
=
SmsNodeEnum
.
SHIPMENT_ARRIVAL
.
getNodeValu
e
();
isOrders
=
SmsIsOrdersEnum
.
SMS_ORDERS_1
.
getValue
();
templateParams
.
put
(
"orders"
,
orders
.
toString
());
}
else
{
templateParams
.
put
(
"order"
,
orders
.
toString
());
}
break
;
case
SHIPMENT_CUSTOMS_CLEARANCE:
//清关通知2023.2.9号新excel模板调整为 柜号{number},具体如下:
//【捷道货运】单号${orders}(柜号${number})已清关。为了避免产生目的港仓租,请及时放货/提货。客服电话:400 9009962(9:00--18:00)。
if
(
orderNoList
.
size
()
>
1
)
{
templateCode
=
SmsSceneEnum
.
SHIPMENT_CUSTOMS_CLEARANCES
.
getTemplateCode
();
templateParams
.
put
(
"orders"
,
orders
.
toString
());
}
else
{
templateParams
.
put
(
"order"
,
orders
.
toString
());
}
break
;
case
AIR_SHIPMENT_CUSTOMS_CLEARANCE:
//清关通知2023.2.9号新excel模板调整为 柜号{number},具体如下:
// 单号${orders}(航班号${number})已清关。为了避免产生目的港仓租,请及时放货/提货。客服电话:400 9009962(9:00--18:00)。
if
(
orderNoList
.
size
()
>
1
)
{
templateCode
=
SmsSceneEnum
.
AIR_SHIPMENT_CUSTOMS_CLEARANCES
.
getTemplateCod
e
();
}
nodeValue
=
SmsNodeEnum
.
SHIPMENT_CUSTOMS_CLEARANCE
.
getNodeValu
e
();
isOrders
=
SmsIsOrdersEnum
.
SMS_ORDERS_1
.
getValue
();
templateParams
.
put
(
"orders"
,
orders
.
toString
());
}
else
{
templateParams
.
put
(
"order"
,
orders
.
toString
());
}
break
;
default
:
return
;
}
SmsSendSingleToUserReqDTO
reqDTO
=
new
SmsSendSingleToUserReqDTO
();
SmsSendSingleToUserReqDTO
V2
reqDTO
=
new
SmsSendSingleToUserReqDTOV2
();
reqDTO
.
setTemplateParams
(
templateParams
);
reqDTO
.
set
TemplateCode
(
templateCod
e
);
reqDTO
.
set
NodeValue
(
nodeValu
e
);
reqDTO
.
setUserId
(
0L
);
reqDTO
.
setMobile
(
phone
);
reqDTO
.
setAreaCode
(
areaCode
);
reqDTO
.
setIsTransport
(
SmsIsTransportEnum
.
SMS_ORDERS_1
.
getValue
());
reqDTO
.
setTransportId
(
Integer
.
valueOf
(
boxDO
.
getTransportType
()));
reqDTO
.
setIsOrders
(
isOrders
);
reqDTO
.
setMessageType
(
SmsMessageTypeEnum
.
SMS_MESSAGE_TYPE_1
.
getValue
());
//给收发货人发送短信
smsSendApi
.
sendSingleSmsToAdmin
(
reqDTO
);
smsSendApi
.
sendSingleSmsToAdmin
V2
(
reqDTO
);
// 发送短信后初始化参数值
orders
=
null
;
marks
=
null
;
...
...
@@ -1795,15 +1793,15 @@ public class BoxServiceImpl extends AbstractService<BoxMapper, BoxDO> implements
}
}
private
void
addBoxOrderSmsLog
(
Long
shipmentId
,
Sms
SceneEnum
smsScen
eEnum
,
List
<
BoxOrderSmsLogDO
>
boxOrderSmsLogDOList
,
Long
orderId
,
String
orderNo
,
String
marks
)
{
private
void
addBoxOrderSmsLog
(
Long
shipmentId
,
Sms
NodeEnum
smsNod
eEnum
,
List
<
BoxOrderSmsLogDO
>
boxOrderSmsLogDOList
,
Long
orderId
,
String
orderNo
,
String
marks
)
{
BoxOrderSmsLogDO
boxOrderSmsLogDO
=
new
BoxOrderSmsLogDO
();
boxOrderSmsLogDO
.
setShipmentId
(
shipmentId
);
boxOrderSmsLogDO
.
setOrderId
(
orderId
);
boxOrderSmsLogDO
.
setOrderNo
(
orderNo
);
boxOrderSmsLogDO
.
setMarks
(
marks
);
boxOrderSmsLogDO
.
set
Scene
(
smsSceneEnum
.
getScen
e
());
boxOrderSmsLogDO
.
setTemplateCode
(
sms
Scen
eEnum
.
getTemplateCode
());
boxOrderSmsLogDO
.
setDescription
(
sms
Scen
eEnum
.
getDescription
());
boxOrderSmsLogDO
.
set
NodeValue
(
smsNodeEnum
.
getNodeValu
e
());
boxOrderSmsLogDO
.
setTemplateCode
(
sms
Nod
eEnum
.
getTemplateCode
());
boxOrderSmsLogDO
.
setDescription
(
sms
Nod
eEnum
.
getDescription
());
boxOrderSmsLogDO
.
setCreator
(
SecurityFrameworkUtils
.
getLoginUserId
().
toString
());
boxOrderSmsLogDO
.
setCreateTime
(
new
Date
());
boxOrderSmsLogDOList
.
add
(
boxOrderSmsLogDO
);
...
...
yudao-module-shipment/yudao-module-shipment-core/src/main/java/cn/iocoder/yudao/module/shipment/service/boxAirCheckout/BoxAirCheckoutServiceImpl.java
View file @
56d736c3
...
...
@@ -33,7 +33,7 @@ import cn.iocoder.yudao.module.shipment.vo.boxAirCheckout.BoxAirCheckoutCreateRe
import
cn.iocoder.yudao.module.shipment.vo.boxAirCheckout.BoxAirCheckoutPDAVO
;
import
cn.iocoder.yudao.module.shipment.vo.boxAirCheckout.BoxAirCheckoutQueryVO
;
import
cn.iocoder.yudao.module.shipment.vo.boxAirCheckout.BoxAirCheckoutUpdateReqVO
;
import
cn.iocoder.yudao.module.system.enums.sms.Sms
Scen
eEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.Sms
Nod
eEnum
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
org.springframework.beans.BeanUtils
;
...
...
@@ -168,7 +168,7 @@ public class BoxAirCheckoutServiceImpl extends AbstractService<BoxAirCheckoutMap
//出仓添加业绩日志
boxService
.
addTargetLog
(
shipmentId
,
TargetLogEnum
.
LOADING
,
checkoutTime
);
// 出仓短信通知
boxService
.
sendSms
(
shipmentId
,
Sms
Scen
eEnum
.
AIR_SHIPMENT_WAREHOUSE
);
boxService
.
sendSms
(
shipmentId
,
Sms
Nod
eEnum
.
AIR_SHIPMENT_WAREHOUSE
);
//插入操作日志
boxOpLogService
.
createBoxOpLog
(
boxDO
.
getId
(),
checkout
.
getStatus
(),
checkout
.
getText
(),
checkout
.
getTextEn
(),
null
);
}
...
...
yudao-module-shipment/yudao-module-shipment-core/src/main/java/cn/iocoder/yudao/module/shipment/service/boxArrival/BoxArrivalServiceImpl.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
shipment
.
service
.
boxArrival
;
import
java.util.*
;
import
javax.annotation.Resour
ce
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.mybatis.core.service.AbstractServi
ce
;
import
cn.iocoder.yudao.framework.mybatis.core.vo.PageVO
;
import
cn.iocoder.yudao.module.order.enums.OrderStatusEnum
;
import
cn.iocoder.yudao.module.shipment.convert.BoxArrivalConvert
;
import
cn.iocoder.yudao.module.shipment.dal.dataobject.BoxArrivalDO
;
...
...
@@ -16,15 +16,17 @@ import cn.iocoder.yudao.module.shipment.service.boxOpLog.BoxOpLogService;
import
cn.iocoder.yudao.module.shipment.vo.boxArrival.BoxArrivalCreateReqVO
;
import
cn.iocoder.yudao.module.shipment.vo.boxArrival.BoxArrivalQueryVO
;
import
cn.iocoder.yudao.module.shipment.vo.boxArrival.BoxArrivalUpdateReqVO
;
import
cn.iocoder.yudao.module.system.enums.sms.Sms
Scen
eEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.Sms
Nod
eEnum
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.context.annotation.Lazy
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.validation.annotation.Validated
;
import
cn.iocoder.yudao.framework.mybatis.core.vo.PageVO
;
import
cn.iocoder.yudao.framework.mybatis.core.service.AbstractService
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
javax.annotation.Resource
;
import
java.util.Collection
;
import
java.util.Date
;
import
java.util.List
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
exception
.
util
.
ServiceExceptionUtil
.
exception
;
import
static
cn
.
iocoder
.
yudao
.
module
.
shipment
.
enums
.
ErrorCodeConstants
.
BOX_NOT_EXISTS
;
...
...
@@ -101,11 +103,7 @@ public class BoxArrivalServiceImpl extends AbstractService<BoxArrivalMapper, Box
//确认到港
//发送短信通知
if
(
StringUtils
.
equals
(
"3"
,
boxDO
.
getTransportType
()))
{
boxService
.
sendSms
(
shipmentId
,
SmsSceneEnum
.
AIR_SHIPMENT_ARRIVAL
);
}
else
{
boxService
.
sendSms
(
shipmentId
,
SmsSceneEnum
.
SHIPMENT_ARRIVAL
);
}
boxService
.
sendSms
(
shipmentId
,
SmsNodeEnum
.
SHIPMENT_ARRIVAL
);
//修改订单状态为已到港
...
...
yudao-module-shipment/yudao-module-shipment-core/src/main/java/cn/iocoder/yudao/module/shipment/service/boxArrivalAir/BoxArrivalAirServiceImpl.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
shipment
.
service
.
boxArrivalAir
;
import
java.util.*
;
import
java.util.stream.Collectors
;
import
javax.annotation.Resource
;
import
cn.iocoder.yudao.framework.common.exception.ServiceException
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX
;
import
cn.iocoder.yudao.framework.mybatis.core.service.AbstractService
;
import
cn.iocoder.yudao.framework.mybatis.core.vo.PageVO
;
import
cn.iocoder.yudao.module.order.dal.dataobject.order.OrderDO
;
import
cn.iocoder.yudao.module.order.enums.OrderStatusEnum
;
import
cn.iocoder.yudao.module.order.service.order.OrderQueryService
;
...
...
@@ -13,7 +12,6 @@ import cn.iocoder.yudao.module.shipment.convert.BoxArrivalAirConvert;
import
cn.iocoder.yudao.module.shipment.dal.dataobject.BoxArrivalAirDO
;
import
cn.iocoder.yudao.module.shipment.dal.dataobject.BoxDO
;
import
cn.iocoder.yudao.module.shipment.dal.dataobject.boxArrivalOrder.BoxArrivalOrderDO
;
import
cn.iocoder.yudao.module.shipment.dal.dataobject.boxClearanceOrder.BoxClearanceOrderDO
;
import
cn.iocoder.yudao.module.shipment.dal.mysql.BoxArrivalAirMapper
;
import
cn.iocoder.yudao.module.shipment.enums.*
;
import
cn.iocoder.yudao.module.shipment.service.box.BoxService
;
...
...
@@ -25,6 +23,7 @@ import cn.iocoder.yudao.module.shipment.vo.boxArrivalAir.BoxArrivalAirQueryVO;
import
cn.iocoder.yudao.module.shipment.vo.boxArrivalAir.BoxArrivalAirUpdateReqVO
;
import
cn.iocoder.yudao.module.shipment.vo.boxArrivalOrder.BoxArrivalOrderAllCreateVO
;
import
cn.iocoder.yudao.module.shipment.vo.boxArrivalOrder.BoxArrivalOrderCreateVO
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsNodeEnum
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.springframework.beans.BeanUtils
;
...
...
@@ -32,9 +31,10 @@ import org.springframework.context.annotation.Lazy;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.validation.annotation.Validated
;
import
cn.iocoder.yudao.framework.mybatis.core.vo.PageVO
;
import
cn.iocoder.yudao.framework.mybatis.core.service.AbstractService
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
javax.annotation.Resource
;
import
java.util.*
;
import
java.util.stream.Collectors
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
exception
.
util
.
ServiceExceptionUtil
.
exception
;
import
static
cn
.
iocoder
.
yudao
.
module
.
shipment
.
enums
.
ErrorCodeConstants
.
BOX_NOT_EXISTS
;
...
...
@@ -152,6 +152,8 @@ public class BoxArrivalAirServiceImpl extends AbstractService<BoxArrivalAirMappe
.
eq
(
BoxArrivalOrderDO:
:
getShipmentId
,
shipmentId
)
);
if
(
arrivalCount
==
arrivalOrders
.
size
())
{
//发送短信通知
boxService
.
sendSms
(
shipmentId
,
SmsNodeEnum
.
SHIPMENT_ARRIVAL
);
SapStatueEnum
sapStatueEnum
=
SapStatueEnum
.
HAS_ARRIVE
;
boxDO
.
setSapStatus
(
sapStatueEnum
.
getSapStatus
());
boxDO
.
setDgDate
(
actTime
);
...
...
yudao-module-shipment/yudao-module-shipment-core/src/main/java/cn/iocoder/yudao/module/shipment/service/boxCabinet/BoxCabinetServiceImpl.java
View file @
56d736c3
...
...
@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.shipment.service.boxCabinet;
import
java.util.*
;
import
javax.annotation.Resource
;
import
cn.hutool.core.collection.CollectionUtil
;
import
cn.iocoder.yudao.framework.common.exception.ServiceException
;
import
cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX
;
import
cn.iocoder.yudao.module.order.enums.TargetLogEnum
;
...
...
@@ -11,7 +10,6 @@ import cn.iocoder.yudao.module.shipment.convert.BoxCabinetConvert;
import
cn.iocoder.yudao.module.shipment.dal.dataobject.BoxBookSeaDO
;
import
cn.iocoder.yudao.module.shipment.dal.dataobject.BoxCabinetDO
;
import
cn.iocoder.yudao.module.shipment.dal.dataobject.BoxDO
;
import
cn.iocoder.yudao.module.shipment.dal.dataobject.BoxPreloadGoodsDO
;
import
cn.iocoder.yudao.module.shipment.dal.mysql.BoxBookSeaMapper
;
import
cn.iocoder.yudao.module.shipment.dal.mysql.BoxCabinetMapper
;
import
cn.iocoder.yudao.module.shipment.enums.*
;
...
...
@@ -20,8 +18,7 @@ import cn.iocoder.yudao.module.shipment.service.boxOpLog.BoxOpLogService;
import
cn.iocoder.yudao.module.shipment.vo.boxCabinet.BoxCabinetCreateReqVO
;
import
cn.iocoder.yudao.module.shipment.vo.boxCabinet.BoxCabinetQueryVO
;
import
cn.iocoder.yudao.module.shipment.vo.boxCabinet.BoxCabinetUpdateReqVO
;
import
cn.iocoder.yudao.module.shipment.vo.boxPreloadGoods.BoxPreloadGoodsQueryVO
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsNodeEnum
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONArray
;
import
com.alibaba.fastjson.JSONObject
;
...
...
@@ -166,7 +163,7 @@ public class BoxCabinetServiceImpl extends AbstractService<BoxCabinetMapper, Box
boxService
.
addTargetLog
(
shipmentId
,
TargetLogEnum
.
LOADING
,
ldBoxTime
);
//发送短信
try
{
boxService
.
sendSms
(
shipmentId
,
Sms
Scen
eEnum
.
SHIPMENT_CABINET
);
boxService
.
sendSms
(
shipmentId
,
Sms
Nod
eEnum
.
SHIPMENT_CABINET
);
}
catch
(
Exception
e
)
{
log
.
error
(
e
.
getMessage
());
}
...
...
yudao-module-shipment/yudao-module-shipment-core/src/main/java/cn/iocoder/yudao/module/shipment/service/boxClearance/BoxClearanceServiceImpl.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
shipment
.
service
.
boxClearance
;
import
java.util.*
;
import
java.util.stream.Collectors
;
import
javax.annotation.Resource
;
import
cn.hutool.core.collection.CollectionUtil
;
import
cn.iocoder.yudao.framework.common.exception.ServiceException
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.mybatis.core.service.AbstractService
;
import
cn.iocoder.yudao.framework.mybatis.core.vo.PageVO
;
import
cn.iocoder.yudao.module.bpm.enums.BpmProcessInstanceResultEnum
;
import
cn.iocoder.yudao.module.order.dal.dataobject.order.OrderDO
;
import
cn.iocoder.yudao.module.order.enums.OrderStatusEnum
;
...
...
@@ -28,7 +27,7 @@ import cn.iocoder.yudao.module.shipment.vo.boxClearance.BoxClearanceQueryVO;
import
cn.iocoder.yudao.module.shipment.vo.boxClearance.BoxClearanceUpdateReqVO
;
import
cn.iocoder.yudao.module.shipment.vo.boxClearanceOrder.BoxClearanceOrderAllCreateVO
;
import
cn.iocoder.yudao.module.shipment.vo.boxClearanceOrder.BoxClearanceOrderCreateVO
;
import
cn.iocoder.yudao.module.system.enums.sms.Sms
Scen
eEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.Sms
Nod
eEnum
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.google.common.base.Joiner
;
import
org.apache.commons.collections4.CollectionUtils
;
...
...
@@ -36,9 +35,10 @@ import org.springframework.context.annotation.Lazy;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.validation.annotation.Validated
;
import
cn.iocoder.yudao.framework.mybatis.core.vo.PageVO
;
import
cn.iocoder.yudao.framework.mybatis.core.service.AbstractService
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
javax.annotation.Resource
;
import
java.util.*
;
import
java.util.stream.Collectors
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
exception
.
util
.
ServiceExceptionUtil
.
exception
;
import
static
cn
.
iocoder
.
yudao
.
module
.
shipment
.
enums
.
ErrorCodeConstants
.
BOX_NOT_EXISTS
;
...
...
@@ -118,7 +118,7 @@ public class BoxClearanceServiceImpl extends AbstractService<BoxClearanceMapper,
if
(
clClearTime
!=
null
)
{
boxOpLogService
.
createBoxOpLog
(
shipmentId
,
ClStatueEnum
.
HAS_CLEARANCE
.
getClStatus
(),
"已清关,待到仓"
,
""
,
null
);
//发送清关短信
boxService
.
sendSms
(
shipmentId
,
Sms
Scen
eEnum
.
SHIPMENT_CUSTOMS_CLEARANCE
);
boxService
.
sendSms
(
shipmentId
,
Sms
Nod
eEnum
.
SHIPMENT_CUSTOMS_CLEARANCE
);
}
//修改订单状态为已清关
...
...
@@ -274,7 +274,7 @@ public class BoxClearanceServiceImpl extends AbstractService<BoxClearanceMapper,
if
(
clearTime
!=
null
)
{
boxOpLogService
.
createBoxOpLog
(
shipmentId
,
ClStatueEnum
.
HAS_CLEARANCE
.
getClStatus
(),
"已清关,待到仓"
,
""
,
null
);
//发送清关短信
boxService
.
sendSms
(
shipmentId
,
clearanceOrders
,
Sms
SceneEnum
.
AIR_
SHIPMENT_CUSTOMS_CLEARANCE
);
boxService
.
sendSms
(
shipmentId
,
clearanceOrders
,
Sms
NodeEnum
.
SHIPMENT_CUSTOMS_CLEARANCE
);
}
//修改订单状态为已清关
...
...
yudao-module-shipment/yudao-module-shipment-core/src/main/java/cn/iocoder/yudao/module/shipment/vo/boxOrderSmsLog/BoxOrderSmsLogBackVO.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
shipment
.
vo
.
boxOrderSmsLog
;
import
lombok.*
;
import
java.util.*
;
import
io.swagger.annotations.*
;
import
com.alibaba.excel.annotation.ExcelProperty
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
import
org.springframework.format.annotation.DateTimeFormat
;
import
java.util.Date
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
date
.
DateUtils
.
FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND
;
/**
...
...
@@ -40,9 +42,9 @@ public class BoxOrderSmsLogBackVO {
@ApiModelProperty
(
value
=
"自编号"
)
private
String
selfNo
;
@ExcelProperty
(
"
场景编码
"
)
@ApiModelProperty
(
value
=
"
场景编码
"
)
private
Integer
scen
e
;
@ExcelProperty
(
"
节点
"
)
@ApiModelProperty
(
value
=
"
节点
"
)
private
String
nodeValu
e
;
@ExcelProperty
(
"说明"
)
@ApiModelProperty
(
value
=
"说明"
)
...
...
yudao-module-shipment/yudao-module-shipment-core/src/main/java/cn/iocoder/yudao/module/shipment/vo/boxOrderSmsLog/BoxOrderSmsLogBaseVO.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
shipment
.
vo
.
boxOrderSmsLog
;
import
lombok.*
;
import
java.util.*
;
import
io.swagger.annotations.*
;
import
javax.validation.constraints.*
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
/**
* 出货短信记录 Base VO,提供给添加、修改、详细的子 VO 使用
...
...
@@ -27,8 +25,8 @@ public class BoxOrderSmsLogBaseVO {
@ApiModelProperty
(
value
=
"自编号"
)
private
String
selfNo
;
@ApiModelProperty
(
value
=
"
场景编码
"
)
private
Integer
scen
e
;
@ApiModelProperty
(
value
=
"
节点
"
)
private
String
nodeValu
e
;
@ApiModelProperty
(
value
=
"说明"
)
private
String
templateCode
;
...
...
yudao-module-shipment/yudao-module-shipment-core/src/main/java/cn/iocoder/yudao/module/shipment/vo/boxOrderSmsLog/BoxOrderSmsLogQueryVO.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
shipment
.
vo
.
boxOrderSmsLog
;
import
lombok.*
;
import
java.util.*
;
import
io.swagger.annotations.*
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
import
org.springframework.format.annotation.DateTimeFormat
;
import
java.util.Date
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
date
.
DateUtils
.
FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND
;
@Data
...
...
@@ -26,8 +28,8 @@ public class BoxOrderSmsLogQueryVO {
@ApiModelProperty
(
value
=
"自编号"
)
private
String
selfNo
;
@ApiModelProperty
(
value
=
"
场景编码
"
)
private
Integer
scen
e
;
@ApiModelProperty
(
value
=
"
节点
"
)
private
String
nodeValu
e
;
@ApiModelProperty
(
value
=
"说明"
)
private
String
templateCode
;
...
...
yudao-module-shipment/yudao-module-shipment-rest/src/main/java/cn/iocoder/yudao/module/shipment/controller/admin/BoxController.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
shipment
.
controller
.
admin
;
import
cn.iocoder.yudao.framework.common.pojo.CommonResult
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.excel.util.ExcelUtils
;
import
cn.iocoder.yudao.framework.i18n.core.I18nMessage
;
import
cn.iocoder.yudao.framework.idempotent.core.annotation.Idempotent
;
import
cn.iocoder.yudao.framework.limiter.dynamic.DynamicRateLimiter
;
import
cn.iocoder.yudao.framework.mybatis.core.vo.PageVO
;
import
cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog
;
import
cn.iocoder.yudao.framework.redis.helper.RedisHelper
;
import
cn.iocoder.yudao.module.order.vo.order.OrderBackPageVO
;
import
cn.iocoder.yudao.module.order.vo.orderSplit.OrderSplitBackVO
;
import
cn.iocoder.yudao.module.shipment.convert.BoxConvert
;
import
cn.iocoder.yudao.module.shipment.dal.dataobject.BoxDO
;
import
cn.iocoder.yudao.module.shipment.service.box.BoxService
;
import
cn.iocoder.yudao.module.shipment.vo.box.*
;
import
cn.iocoder.yudao.module.shipment.vo.boxTally.BoxGuanlianOrderBackVO
;
import
cn.iocoder.yudao.module.shipment.vo.boxTally.BoxOrderLocationUpdateReq
;
import
cn.iocoder.yudao.module.shipment.vo.boxTally.BoxTallyBackVO
;
import
cn.iocoder.yudao.module.system.api.file.FileMakeApi
;
import
cn.iocoder.yudao.module.system.api.file.dto.FileMakeReqDTO
;
import
cn.iocoder.yudao.module.system.enums.download.DownloadTypeEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.Sms
Scen
eEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.Sms
Nod
eEnum
;
import
com.alibaba.fastjson.JSONObject
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiImplicitParam
;
import
io.swagger.annotations.ApiImplicitParams
;
import
io.swagger.annotations.ApiOperation
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.bind.annotation.*
;
import
javax.annotation.Resource
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
io.swagger.annotations.*
;
import
javax.validation.*
;
import
javax.servlet.http.*
;
import
java.io.*
;
import
javax.servlet.http.HttpServletResponse
;
import
javax.validation.Valid
;
import
java.io.IOException
;
import
java.text.MessageFormat
;
import
java.util.*
;
import
java.util.Collection
;
import
java.util.List
;
import
java.util.concurrent.TimeUnit
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.common.pojo.CommonResult
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
pojo
.
CommonResult
.
error
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
pojo
.
CommonResult
.
success
;
import
cn.iocoder.yudao.framework.excel.util.ExcelUtils
;
import
cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
operatelog
.
core
.
enums
.
OperateTypeEnum
.*;
import
static
cn
.
iocoder
.
yudao
.
framework
.
operatelog
.
core
.
enums
.
OperateTypeEnum
.
EXPORT
;
import
static
cn
.
iocoder
.
yudao
.
module
.
shipment
.
controller
.
admin
.
constant
.
Constant
.
BOX_UPDATE_KEY
;
import
static
cn
.
iocoder
.
yudao
.
module
.
shipment
.
enums
.
ErrorCodeConstants
.
BOX_UPDATE_REPEAT_COMMIT
;
import
cn.iocoder.yudao.module.shipment.vo.box.*
;
import
cn.iocoder.yudao.module.shipment.service.box.BoxService
;
@Validated
@RestController
@Api
(
tags
=
"管理后台 - 出货"
)
...
...
@@ -323,8 +321,8 @@ public class BoxController {
@ApiImplicitParam
(
name
=
"shipmentId"
,
value
=
"出货单ID"
,
required
=
true
,
example
=
"1024"
,
dataTypeClass
=
Long
.
class
),
@ApiImplicitParam
(
name
=
"scene"
,
value
=
"场景编号"
,
required
=
true
,
example
=
"20"
,
dataTypeClass
=
String
.
class
)
})
public
CommonResult
<
Boolean
>
shipmentSmsSend
(
@RequestParam
(
"shipmentId"
)
Long
shipmentId
,
@RequestParam
(
"scene"
)
Integer
scene
)
{
boxService
.
sendSms
(
shipmentId
,
Sms
Scen
eEnum
.
getCodeByScene
(
scene
));
public
CommonResult
<
Boolean
>
shipmentSmsSend
(
@RequestParam
(
"shipmentId"
)
Long
shipmentId
,
@RequestParam
(
"scene"
)
String
scene
)
{
boxService
.
sendSms
(
shipmentId
,
Sms
Nod
eEnum
.
getCodeByScene
(
scene
));
return
success
(
true
);
}
...
...
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/SmsSendApi.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
api
.
sms
;
import
cn.iocoder.yudao.module.system.api.sms.dto.send.SmsSendSingleToUserReqDTO
;
import
cn.iocoder.yudao.module.system.api.sms.dto.send.SmsSendSingleToUserReqDTOV2
;
import
javax.validation.Valid
;
...
...
@@ -21,6 +22,16 @@ public interface SmsSendApi {
*/
Long
sendSingleSmsToAdmin
(
@Valid
SmsSendSingleToUserReqDTO
reqDTO
);
/**
* 发送单条短信给 Admin 用户
*
* 在 mobile 为空时,使用 userId 加载对应 Admin 的手机号
*
* @param reqDTO 发送请求
* @return 发送日志编号
*/
Long
sendSingleSmsToAdminV2
(
@Valid
SmsSendSingleToUserReqDTOV2
reqDTO
);
/**
* 发送单条短信给 Member 用户
*
...
...
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/dto/code/SmsCodeCheckReqDTO.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
api
.
sms
.
dto
.
code
;
import
cn.iocoder.yudao.framework.common.validation.InEnum
;
import
cn.iocoder.yudao.framework.common.validation.Mobile
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum
;
import
lombok.Data
;
import
javax.validation.constraints.NotEmpty
;
...
...
@@ -26,8 +24,7 @@ public class SmsCodeCheckReqDTO {
* 发送场景
*/
@NotNull
(
message
=
"发送场景不能为空"
)
@InEnum
(
SmsSceneEnum
.
class
)
private
Integer
scene
;
private
String
nodeValue
;
/**
* 验证码
*/
...
...
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/dto/code/SmsCodeSendReqDTO.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
api
.
sms
.
dto
.
code
;
import
cn.iocoder.yudao.framework.common.validation.InEnum
;
import
cn.iocoder.yudao.framework.common.validation.Mobile
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum
;
import
lombok.Data
;
import
javax.validation.constraints.NotEmpty
;
...
...
@@ -25,9 +23,8 @@ public class SmsCodeSendReqDTO {
/**
* 发送场景
*/
@NotNull
(
message
=
"发送场景不能为空"
)
@InEnum
(
SmsSceneEnum
.
class
)
private
Integer
scene
;
@NotNull
(
message
=
"业务节点不能为空"
)
private
String
nodeValue
;
/**
* 发送 IP
*/
...
...
@@ -36,4 +33,16 @@ public class SmsCodeSendReqDTO {
@NotNull
(
message
=
"国家区号不能为空"
)
private
String
areaCode
;
@NotNull
(
message
=
"是否匹配运输方式不能为空"
)
private
Integer
isTransport
;
@NotNull
(
message
=
"运输方式不能空"
)
private
Integer
transportId
;
@NotNull
(
message
=
"是否多订单不能为空"
)
private
Integer
isOrders
;
@NotNull
(
message
=
"发送类型不能为空"
)
private
Integer
messageType
;
}
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/dto/code/SmsCodeUseReqDTO.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
api
.
sms
.
dto
.
code
;
import
cn.iocoder.yudao.framework.common.validation.InEnum
;
import
cn.iocoder.yudao.framework.common.validation.Mobile
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum
;
import
lombok.Data
;
import
javax.validation.constraints.NotEmpty
;
...
...
@@ -26,8 +24,7 @@ public class SmsCodeUseReqDTO {
* 发送场景
*/
@NotNull
(
message
=
"发送场景不能为空"
)
@InEnum
(
SmsSceneEnum
.
class
)
private
Integer
scene
;
private
String
nodeValue
;
/**
* 验证码
*/
...
...
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/dto/send/SmsSendSingleToUserReqDTOV2.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
api
.
sms
.
dto
.
send
;
import
lombok.Data
;
import
javax.validation.constraints.NotNull
;
import
java.util.Map
;
/**
* 短信发送给 Admin 或者 Member 用户
*
* @author 捷道源码
*/
@Data
public
class
SmsSendSingleToUserReqDTOV2
{
/**
* 用户编号
*/
@NotNull
(
message
=
"用户编号不能为空"
)
private
Long
userId
;
@NotNull
(
message
=
"手机号不能为空"
)
private
String
mobile
;
@NotNull
(
message
=
"节点不能为空"
)
private
String
nodeValue
;
@NotNull
(
message
=
"区号不能为空"
)
private
String
areaCode
;
@NotNull
(
message
=
"是否匹配运输方式不能为空"
)
private
Integer
isTransport
;
@NotNull
(
message
=
"运输方式不能空"
)
private
Integer
transportId
;
@NotNull
(
message
=
"是否多订单不能为空"
)
private
Integer
isOrders
;
@NotNull
(
message
=
"发送类型不能为空"
)
private
Integer
messageType
;
/**
* 短信模板参数
*/
private
Map
<
String
,
Object
>
templateParams
;
}
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java
View file @
56d736c3
...
...
@@ -89,6 +89,9 @@ public interface ErrorCodeConstants {
ErrorCode
SMS_SEND_MOBILE_TEMPLATE_PARAM_MISS
=
new
ErrorCode
(
1002013001
,
"模板参数({})缺失"
);
ErrorCode
SMS_SEND_TEMPLATE_NOT_EXISTS
=
new
ErrorCode
(
1002013002
,
"短信模板不存在"
);
// ========== 短信节点 1002013100 ==========
ErrorCode
SMS_NODE_NOT_EXISTS
=
new
ErrorCode
(
1002013100
,
"短信节点不存在"
);
// ========== 短信验证码 1002014000 ==========
ErrorCode
SMS_CODE_NOT_FOUND
=
new
ErrorCode
(
1002014000
,
"验证码不存在"
);
ErrorCode
SMS_CODE_EXPIRED
=
new
ErrorCode
(
1002014001
,
"验证码已过期"
);
...
...
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsCountryCodeEnum.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
enums
.
sms
;
import
cn.hutool.core.util.ArrayUtil
;
import
cn.iocoder.yudao.framework.common.util.json.core.IntArrayValuable
;
import
lombok.AllArgsConstructor
;
import
lombok.Getter
;
import
java.util.Arrays
;
/**
* 国家编号枚举
*
* @author jayden
*/
@Getter
@AllArgsConstructor
public
enum
SmsCountryCodeEnum
{
SMS_COUNTRY_CODE_0
(
"全部"
,
"0"
),
SMS_COUNTRY_CODE_1
(
"其他"
,
"1"
);
private
String
name
;
private
String
value
;
}
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsIsOrdersEnum.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
enums
.
sms
;
import
lombok.AllArgsConstructor
;
import
lombok.Getter
;
/**
* 是否多订单枚举
*
* @author jayden
*/
@Getter
@AllArgsConstructor
public
enum
SmsIsOrdersEnum
{
SMS_ORDERS_0
(
"否"
,
0
),
SMS_ORDERS_1
(
"是"
,
1
);
private
String
name
;
private
Integer
value
;
}
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsIsTransportEnum.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
enums
.
sms
;
import
lombok.AllArgsConstructor
;
import
lombok.Getter
;
/**
* 是否匹配运输方式枚举
*
* @author jayden
*/
@Getter
@AllArgsConstructor
public
enum
SmsIsTransportEnum
{
SMS_ORDERS_0
(
"否"
,
0
),
SMS_ORDERS_1
(
"是"
,
1
);
private
String
name
;
private
Integer
value
;
}
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsMessageTypeEnum.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
enums
.
sms
;
import
lombok.AllArgsConstructor
;
import
lombok.Getter
;
/**
* 发送类型枚举
*
* @author jayden
*/
@Getter
@AllArgsConstructor
public
enum
SmsMessageTypeEnum
{
SMS_MESSAGE_TYPE_1
(
"短信"
,
1
),
SMS_MESSAGE_TYPE_2
(
"whatsapp"
,
2
),
SMS_MESSAGE_TYPE_3
(
"email"
,
3
);
private
String
name
;
private
Integer
value
;
}
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsNodeEnum.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
enums
.
sms
;
import
cn.hutool.core.util.ArrayUtil
;
import
lombok.AllArgsConstructor
;
import
lombok.Getter
;
/**
* 用户短信验证码发送场景的枚举
*
* @author 捷道源码
*/
@Getter
@AllArgsConstructor
public
enum
SmsNodeEnum
{
MEMBER_REG
(
"user-sms-reg"
,
"user-sms-reg"
,
"会员用户 - 手机号注册"
),
//测了
MEMBER_LOGIN
(
"user-sms-login"
,
"user-sms-login"
,
"会员用户 - 手机号登陆"
),
//测了
MEMBER_UPDATE_MOBILE
(
"user-sms-update-mobile"
,
"user-sms-update-mobile"
,
"会员用户 - 解绑手机"
),
//测了
MEMBER_FORGET_PASSWORD
(
"user-sms-reset-password"
,
"user-sms-reset-password"
,
"会员用户 - 忘记密码"
),
//测了
TRANSFER_CONTROL_GOODS
(
"transfer-control-goods"
,
"transfer-control-goods"
,
"订单 - 控货权转移"
),
//测了
DELIVERY_VERIFICATION_SMS
(
"delivery-verification-sms"
,
"delivery-verification-sms"
,
"订单 - 放货验证短信"
),
//测了
NOTIFICATION_SUCCESS_DELIVERY
(
"notification-successful-delivery"
,
"notification-successful-delivery"
,
"订单 - 放货成功通知"
),
//测了
NOTIFICATION_SUCCESS_CANCEL_DELIVERY
(
"notification-successful-cancel-delivery"
,
"notification-successful-cancel-delivery"
,
"订单 - 取消放货通知"
),
//测了
// NOTIFICATION_SUCCESS_SEASONING_CONDIMENTS("notification-successful-seasoning-condiments", "notification-successful-seasoning-condiments", "订单 - 调货通知"),//暂时没发现调用
MEMBER_REDEEM_REWARD
(
"user-sms-redeem-reward"
,
"user-sms-redeem-reward"
,
"会员用户 - 兑换礼品"
),
// SHIPMENT_ARRIVALS("shipment-arrivals", "shipment-arrivals", "出货 - 到港通知(多订单)"),//
// SHIPMENT_CUSTOMS_CLEARANCES("shipment-customs-clearances", "shipment-customs-clearances", "出货 - 清关通知(多订单)"),//
// SHIPMENT_CABINETS("shipment-cabinets", "shipment-cabinets", "出货 - 装柜通知(多订单)"),//
SHIPMENT_ARRIVAL
(
"shipment-arrival"
,
"shipment-arrival"
,
"出货 - 到港通知"
),
//h
SHIPMENT_CUSTOMS_CLEARANCE
(
"shipment-customs-clearance"
,
"shipment-customs-clearance"
,
"出货 - 清关通知"
),
//h
SHIPMENT_CABINET
(
"shipment-cabinet"
,
"shipment-cabinet"
,
"出货 - 装柜通知"
),
//h
SHIPMENT_CLOSE_CONTAINER
(
"shipment-close-container"
,
"shipment-close-container"
,
"出货 - 封柜反审"
),
//好像没发信息
WAREHOUSE_IN_CONTROL
(
"warehouse-in-control"
,
"warehouse-in-control"
,
"入仓控货通知"
),
//h
WAREHOUSE_IN
(
"warehouse-in"
,
"warehouse-in"
,
"入仓通知"
),
//h
WAREHOUSE_IN_APPEND
(
"warehouse-in-append"
,
"warehouse-in-append"
,
"追加通知"
),
//k
WAREHOUSE_IN_CONTROL_COLLECT_OF_GOODS
(
"warehouse-in-control-collect-of-goods"
,
"warehouse-in-control-collect-of-goods"
,
"入仓-控货代收货款"
),
//无此功能
WAREHOUSE_IN_COLLECT_OF_GOODS
(
"warehouse-in-collect-of-goods"
,
"warehouse-in-collect-of-goods"
,
"入仓-非控货代收货款"
),
//h
/** 空运新增模板 **/
// AIR_WAREHOUSE_IN_CONTROL("air-warehouse-in-control", "air-warehouse-in-control", "入仓控货通知"),//x
// AIR_WAREHOUSE_IN("air-warehouse-in", "air-warehouse-in", "入仓通知"),//x
// AIR_SHIPMENT_ARRIVAL("air-shipment-arrival", "air-shipment-arrival", "出货 - 到港通知"),//x
// AIR_SHIPMENT_ARRIVALS("air-shipment-arrivals", "air-shipment-arrivals", "出货 - 到港通知(多订单)"),//x
// AIR_SHIPMENT_CUSTOMS_CLEARANCE("air-shipment-customs-clearance", "air-shipment-customs-clearance", "出货 - 清关通知"),//
// AIR_SHIPMENT_CUSTOMS_CLEARANCES("air-shipment-customs-clearances", "air-shipment-customs-clearances", "出货 - 清关通知(多订单)"),//
AIR_SHIPMENT_WAREHOUSE
(
"air-shipment-warehouse"
,
"air-shipment-warehouse"
,
"出货 - 出仓通知"
),
//
// AIR_SHIPMENT_WAREHOUSES("air-shipment-warehouses", "air-shipment-warehouses", "出货 - 出仓通知(多订单)"),//
// AIR_WAREHOUSE_IN_COLLECT_OF_GOODS("air-warehouse-in-collect-of-goods", "air-warehouse-in-collect-of-goods", "入仓-非控货代收货款"),//
;
/**
* 验证场景的编号
*/
private
final
String
nodeValue
;
/**
* 模版编码
*/
private
final
String
templateCode
;
/**
* 描述
*/
private
final
String
description
;
public
static
SmsNodeEnum
getCodeByScene
(
String
scene
)
{
return
ArrayUtil
.
firstMatch
(
sceneEnum
->
sceneEnum
.
getNodeValue
().
equals
(
scene
),
values
());
}
}
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SystemStatusEnum.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
enums
.
sms
;
import
lombok.AllArgsConstructor
;
import
lombok.Getter
;
/**
* 系统状态枚举
*
* @author jayden
*/
@Getter
@AllArgsConstructor
public
enum
SystemStatusEnum
{
SYSTEM_STATUS_0
(
"开启"
,
0
),
SYSTEM_STATUS_1
(
"关闭"
,
1
);
private
String
name
;
private
Integer
value
;
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/api/sms/SmsSendApiImpl.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
api
.
sms
;
import
cn.iocoder.yudao.module.system.api.sms.dto.send.SmsSendSingleToUserReqDTO
;
import
cn.iocoder.yudao.module.system.api.sms.dto.send.SmsSendSingleToUserReqDTOV2
;
import
cn.iocoder.yudao.module.system.service.sms.SmsSendService
;
import
org.springframework.stereotype.Service
;
import
org.springframework.validation.annotation.Validated
;
...
...
@@ -25,6 +26,13 @@ public class SmsSendApiImpl implements SmsSendApi {
reqDTO
.
getTemplateCode
(),
reqDTO
.
getTemplateParams
(),
reqDTO
.
getAreaCode
());
}
@Override
public
Long
sendSingleSmsToAdminV2
(
SmsSendSingleToUserReqDTOV2
reqDTO
)
{
return
smsSendService
.
sendSingleSmsToAdminV2
(
reqDTO
.
getMobile
(),
reqDTO
.
getUserId
(),
reqDTO
.
getNodeValue
(),
reqDTO
.
getAreaCode
(),
reqDTO
.
getIsOrders
(),
reqDTO
.
getIsTransport
(),
reqDTO
.
getTransportId
(),
reqDTO
.
getMessageType
(),
reqDTO
.
getTemplateParams
());
}
@Override
public
Long
sendSingleSmsToMember
(
SmsSendSingleToUserReqDTO
reqDTO
)
{
return
smsSendService
.
sendSingleSmsToMember
(
reqDTO
.
getMobile
(),
reqDTO
.
getUserId
(),
...
...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsCallbackController.java
View file @
56d736c3
...
...
@@ -2,13 +2,17 @@ package cn.iocoder.yudao.module.system.controller.admin.sms;
import
cn.hutool.core.util.URLUtil
;
import
cn.hutool.extra.servlet.ServletUtil
;
import
cn.iocoder.yudao.module.system.service.sms.SmsSendService
;
import
cn.iocoder.yudao.framework.common.pojo.CommonResult
;
import
cn.iocoder.yudao.framework.common.util.json.JsonUtils
;
import
cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog
;
import
cn.iocoder.yudao.framework.sms.core.client.impl.sendchamp.SendchampSmsClient
;
import
cn.iocoder.yudao.framework.sms.core.enums.SmsChannelEnum
;
import
cn.iocoder.yudao.module.system.service.sms.SmsLogService
;
import
cn.iocoder.yudao.module.system.service.sms.SmsSendService
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiImplicitParam
;
import
io.swagger.annotations.ApiOperation
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestParam
;
...
...
@@ -27,6 +31,9 @@ public class SmsCallbackController {
@Resource
private
SmsSendService
smsSendService
;
@Autowired
private
SmsLogService
smsLogService
;
@PostMapping
(
"/yunpian"
)
@ApiOperation
(
value
=
"云片短信的回调"
,
notes
=
"参见 https://www.yunpian.com/official/document/sms/zh_cn/domestic_push_report 文档"
)
@ApiImplicitParam
(
name
=
"sms_status"
,
value
=
"发送状态"
,
required
=
true
,
example
=
"[{具体内容}]"
,
dataTypeClass
=
String
.
class
)
...
...
@@ -46,4 +53,13 @@ public class SmsCallbackController {
return
success
(
true
);
}
@PostMapping
(
"/sendchamp"
)
@ApiOperation
(
value
=
"sendchamp短信的回调"
,
notes
=
"参见 https://help.aliyun.com/document_detail/120998.html 文档"
)
@OperateLog
(
enable
=
false
)
public
CommonResult
<
Boolean
>
receiveSendchampSmsStatus
(
HttpServletRequest
request
)
throws
Throwable
{
String
text
=
ServletUtil
.
getBody
(
request
);
SendchampSmsClient
.
SmsReceiveStatus
smsReceiveStatus
=
JsonUtils
.
parseObject
(
text
,
SendchampSmsClient
.
SmsReceiveStatus
.
class
);
smsLogService
.
updateSendchampReceive
(
smsReceiveStatus
);
return
success
(
true
);
}
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsNodeController.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
controller
.
admin
.
sms
;
import
cn.iocoder.yudao.framework.mybatis.core.vo.PageVO
;
import
cn.iocoder.yudao.module.system.convert.sms.SmsNodeConvert
;
import
cn.iocoder.yudao.module.system.service.sms.SmsNodeService
;
import
org.springframework.web.bind.annotation.*
;
import
javax.annotation.Resource
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
io.swagger.annotations.*
;
import
javax.validation.constraints.*
;
import
javax.validation.*
;
import
javax.servlet.http.*
;
import
java.util.*
;
import
java.io.IOException
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.common.pojo.CommonResult
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
pojo
.
CommonResult
.
success
;
import
cn.iocoder.yudao.framework.excel.util.ExcelUtils
;
import
cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
operatelog
.
core
.
enums
.
OperateTypeEnum
.*;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.smsNode.*
;
import
cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsNodeDO
;
@Validated
@RestController
@Api
(
tags
=
"管理后台 - 短信节点"
)
@RequestMapping
(
"/system/sms-node"
)
public
class
SmsNodeController
{
@Resource
private
SmsNodeService
smsNodeService
;
@PostMapping
(
"/create"
)
@ApiOperation
(
"创建短信节点"
)
@PreAuthorize
(
"@ss.hasPermission('system:sms-node:create')"
)
public
CommonResult
<
Long
>
createSmsNode
(
@Valid
@RequestBody
SmsNodeCreateReqVO
createReqVO
)
{
return
success
(
smsNodeService
.
createSmsNode
(
createReqVO
));
}
@PutMapping
(
"/update"
)
@ApiOperation
(
"更新短信节点"
)
@PreAuthorize
(
"@ss.hasPermission('system:sms-node:update')"
)
public
CommonResult
<
Boolean
>
updateSmsNode
(
@Valid
@RequestBody
SmsNodeUpdateReqVO
updateReqVO
)
{
smsNodeService
.
updateSmsNode
(
updateReqVO
);
return
success
(
true
);
}
@DeleteMapping
(
"/delete"
)
@ApiOperation
(
"删除短信节点"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"编号"
,
required
=
true
,
example
=
"1024"
,
dataTypeClass
=
Long
.
class
)
@PreAuthorize
(
"@ss.hasPermission('system:sms-node:delete')"
)
public
CommonResult
<
Boolean
>
deleteSmsNode
(
@RequestParam
(
"id"
)
Long
id
)
{
smsNodeService
.
deleteSmsNode
(
id
);
return
success
(
true
);
}
@GetMapping
(
"/get"
)
@ApiOperation
(
"获得短信节点"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"编号"
,
required
=
true
,
example
=
"1024"
,
dataTypeClass
=
Long
.
class
)
@PreAuthorize
(
"@ss.hasPermission('system:sms-node:query')"
)
public
CommonResult
<
SmsNodeBackVO
>
getSmsNode
(
@RequestParam
(
"id"
)
Long
id
)
{
SmsNodeDO
smsNode
=
smsNodeService
.
getSmsNode
(
id
);
return
success
(
SmsNodeConvert
.
INSTANCE
.
convert
(
smsNode
));
}
@GetMapping
(
"/list"
)
@ApiOperation
(
"获得短信节点列表"
)
@ApiImplicitParam
(
name
=
"ids"
,
value
=
"编号列表"
,
required
=
true
,
example
=
"1024,2048"
,
dataTypeClass
=
List
.
class
)
@PreAuthorize
(
"@ss.hasPermission('system:sms-node:query')"
)
public
CommonResult
<
List
<
SmsNodeBackVO
>>
getSmsNodeList
(
@RequestParam
(
"ids"
)
Collection
<
Long
>
ids
)
{
List
<
SmsNodeDO
>
list
=
smsNodeService
.
getSmsNodeList
(
ids
);
return
success
(
SmsNodeConvert
.
INSTANCE
.
convertList
(
list
));
}
@GetMapping
(
"/page"
)
@ApiOperation
(
"获得短信节点分页"
)
@PreAuthorize
(
"@ss.hasPermission('system:sms-node:query')"
)
public
CommonResult
<
PageResult
<
SmsNodeBackVO
>>
getSmsNodePage
(
@Valid
SmsNodeQueryVO
query
,
PageVO
page
)
{
PageResult
<
SmsNodeDO
>
pageResult
=
smsNodeService
.
getSmsNodePage
(
query
,
page
);
return
success
(
SmsNodeConvert
.
INSTANCE
.
convertPage
(
pageResult
));
}
@GetMapping
(
"/export-excel"
)
@ApiOperation
(
"导出短信节点 Excel"
)
@PreAuthorize
(
"@ss.hasPermission('system:sms-node:export')"
)
@OperateLog
(
type
=
EXPORT
)
public
void
exportSmsNodeExcel
(
@Valid
SmsNodeQueryVO
query
,
HttpServletResponse
response
)
throws
IOException
{
List
<
SmsNodeDO
>
list
=
smsNodeService
.
getSmsNodeList
(
query
);
// 导出 Excel
List
<
SmsNodeBackVO
>
datas
=
SmsNodeConvert
.
INSTANCE
.
convertList
(
list
);
ExcelUtils
.
write
(
response
,
"短信节点.xls"
,
"数据"
,
SmsNodeBackVO
.
class
,
datas
);
}
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogExcelVO.java
View file @
56d736c3
...
...
@@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.excel.convert.DictConvert;
import
cn.iocoder.yudao.framework.excel.convert.JsonConvert
;
import
cn.iocoder.yudao.module.system.enums.DictTypeConstants
;
import
com.alibaba.excel.annotation.ExcelProperty
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
import
java.util.Date
;
...
...
@@ -107,4 +108,23 @@ public class SmsLogExcelVO {
*/
@ExcelProperty
(
value
=
"重发次数"
)
private
Integer
num
;
/**
* 短信节点表id
*/
@ExcelProperty
(
value
=
"短信节点表id"
)
private
Long
nodeId
;
/**
* 节点模板序列号
*/
@ExcelProperty
(
value
=
"节点模板序列号"
)
private
Integer
nodeTemplateSn
;
/**
* 发送类型
*/
@ExcelProperty
(
value
=
"发送类型"
)
private
Integer
messageType
;
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogExportReqVO.java
View file @
56d736c3
...
...
@@ -55,4 +55,24 @@ public class SmsLogExportReqVO {
@ApiModelProperty
(
value
=
"重发次数"
)
private
Integer
num
;
/**
* 短信节点表id
*/
@ApiModelProperty
(
value
=
"短信节点表id"
)
private
Long
nodeId
;
/**
* 节点模板序列号
*/
@ApiModelProperty
(
value
=
"节点模板序列号"
)
private
Integer
nodeTemplateSn
;
/**
* 发送类型
*/
@ApiModelProperty
(
value
=
"发送类型"
)
private
Integer
messageType
;
@ApiModelProperty
(
value
=
"短信 API 发送返回的序号"
)
private
String
apiSerialNo
;
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogPageReqVO.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
controller
.
admin
.
sms
.
vo
.
log
;
import
cn.iocoder.yudao.framework.common.pojo.PageParam
;
import
com.alibaba.excel.annotation.ExcelProperty
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
...
...
@@ -62,4 +63,21 @@ public class SmsLogPageReqVO extends PageParam {
private
Integer
num
;
/**
* 短信节点表id
*/
@ApiModelProperty
(
value
=
"短信节点表id"
)
private
Long
nodeId
;
/**
* 节点模板序列号
*/
@ApiModelProperty
(
value
=
"节点模板序列号"
)
private
Integer
nodeTemplateSn
;
/**
* 发送类型
*/
@ApiModelProperty
(
value
=
"发送类型"
)
private
Integer
messageType
;
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogRespVO.java
View file @
56d736c3
...
...
@@ -97,4 +97,22 @@ public class SmsLogRespVO {
@ApiModelProperty
(
value
=
"重发次数"
)
private
Integer
num
;
/**
* 短信节点表id
*/
@ApiModelProperty
(
value
=
"短信节点表id"
)
private
Long
nodeId
;
/**
* 节点模板序列号
*/
@ApiModelProperty
(
value
=
"节点模板序列号"
)
private
Integer
nodeTemplateSn
;
/**
* 发送类型
*/
@ApiModelProperty
(
value
=
"发送类型"
)
private
Integer
messageType
;
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/smsNode/SmsNodeBackVO.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
controller
.
admin
.
sms
.
vo
.
smsNode
;
import
lombok.*
;
import
java.util.*
;
import
io.swagger.annotations.*
;
import
com.alibaba.excel.annotation.ExcelProperty
;
import
cn.iocoder.yudao.framework.excel.annotations.DictFormat
;
import
cn.iocoder.yudao.framework.excel.convert.DictConvert
;
import
org.springframework.format.annotation.DateTimeFormat
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
date
.
DateUtils
.
FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND
;
/**
* 短信节点 Response VO
*
* @author jayden
*/
@Data
@ApiModel
(
"管理后台 - 短信节点 Response VO"
)
public
class
SmsNodeBackVO
{
@ExcelProperty
(
"编号"
)
@ApiModelProperty
(
value
=
"编号"
,
required
=
true
)
private
Long
id
;
@ExcelProperty
(
"节点"
)
@ApiModelProperty
(
value
=
"节点"
,
required
=
true
)
private
String
nodeValue
;
@ExcelProperty
(
value
=
"运输方式"
,
converter
=
DictConvert
.
class
)
@DictFormat
(
"transport_type"
)
// TODO 代码优化:建议设置到对应的 XXXDictTypeConstants 枚举类中
@ApiModelProperty
(
value
=
"运输方式"
,
required
=
true
)
private
Long
transportId
;
@ExcelProperty
(
"国家区号"
)
@ApiModelProperty
(
value
=
"国家区号"
,
required
=
true
)
private
Long
countryId
;
@ExcelProperty
(
"国家区号"
)
@ApiModelProperty
(
value
=
"国家区号,和订单中国家区号保持一致"
,
required
=
true
)
private
String
countryCode
;
@ExcelProperty
(
"启用状态"
)
@ApiModelProperty
(
value
=
"启用状态(0:启用,1:关闭)"
,
required
=
true
)
private
Integer
status
;
@ExcelProperty
(
"模板1"
)
@ApiModelProperty
(
value
=
"模板1"
,
required
=
true
)
private
Long
templateIdOne
;
@ExcelProperty
(
"模板2"
)
@ApiModelProperty
(
value
=
"模板2"
)
private
Long
templateIdTwo
;
@ExcelProperty
(
"模板3"
)
@ApiModelProperty
(
value
=
"模板3"
)
private
Long
templateIdThree
;
@ExcelProperty
(
"模板4"
)
@ApiModelProperty
(
value
=
"模板4"
)
private
Long
templateIdFour
;
@ExcelProperty
(
"创建时间"
)
@DateTimeFormat
(
pattern
=
FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND
)
@ApiModelProperty
(
value
=
"创建时间"
,
required
=
true
)
private
Date
createTime
;
@ExcelProperty
(
"是否匹配运输方式"
)
@ApiModelProperty
(
value
=
"是否匹配运输方式"
,
required
=
true
)
private
Integer
isTransport
;
@ExcelProperty
(
"多订单"
)
@ApiModelProperty
(
value
=
"多订单"
,
required
=
true
)
private
Integer
isOrders
;
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/smsNode/SmsNodeBaseVO.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
controller
.
admin
.
sms
.
vo
.
smsNode
;
import
com.alibaba.excel.annotation.ExcelProperty
;
import
lombok.*
;
import
java.util.*
;
import
io.swagger.annotations.*
;
import
javax.validation.constraints.*
;
/**
* 短信节点 Base VO,提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public
class
SmsNodeBaseVO
{
@ApiModelProperty
(
value
=
"节点"
,
required
=
true
)
@NotNull
(
message
=
"节点不能为空"
)
private
String
nodeValue
;
@ApiModelProperty
(
value
=
"运输方式ID"
,
required
=
true
)
@NotNull
(
message
=
"运输方式ID不能为空"
)
private
Long
transportId
;
@ApiModelProperty
(
value
=
"国家区号id"
,
required
=
true
)
@NotNull
(
message
=
"国家区号id不能为空"
)
private
Long
countryId
;
@ApiModelProperty
(
value
=
"国家区号,和订单中国家区号保持一致"
,
required
=
true
)
@NotNull
(
message
=
"国家区号,和订单中国家区号保持一致不能为空"
)
private
String
countryCode
;
@ApiModelProperty
(
value
=
"启用状态(0:启用,1:关闭)"
,
required
=
true
)
@NotNull
(
message
=
"启用状态(0:启用,1:关闭)不能为空"
)
private
Integer
status
;
@ApiModelProperty
(
value
=
"模板1"
,
required
=
true
)
@NotNull
(
message
=
"模板1不能为空"
)
private
Long
templateIdOne
;
@ApiModelProperty
(
value
=
"模板2"
)
private
Long
templateIdTwo
;
@ApiModelProperty
(
value
=
"模板3"
)
private
Long
templateIdThree
;
@ApiModelProperty
(
value
=
"模板4"
)
private
Long
templateIdFour
;
@ApiModelProperty
(
value
=
"是否匹配运输方式"
,
required
=
true
)
private
Integer
isTransport
;
@ApiModelProperty
(
value
=
"多订单"
,
required
=
true
)
private
Integer
isOrders
;
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/smsNode/SmsNodeCreateReqVO.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
controller
.
admin
.
sms
.
vo
.
smsNode
;
import
lombok.*
;
import
java.util.*
;
import
io.swagger.annotations.*
;
import
javax.validation.constraints.*
;
@Data
@ToString
(
callSuper
=
true
)
@EqualsAndHashCode
(
callSuper
=
true
)
@ApiModel
(
"管理后台 - 短信节点创建 Request VO"
)
public
class
SmsNodeCreateReqVO
extends
SmsNodeBaseVO
{
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/smsNode/SmsNodeQueryVO.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
controller
.
admin
.
sms
.
vo
.
smsNode
;
import
lombok.*
;
import
java.util.*
;
import
io.swagger.annotations.*
;
import
cn.iocoder.yudao.framework.common.pojo.PageParam
;
import
org.springframework.format.annotation.DateTimeFormat
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
date
.
DateUtils
.
FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND
;
@Data
@ApiModel
(
"管理后台 - 短信节点查询 VO"
)
public
class
SmsNodeQueryVO
{
@ApiModelProperty
(
value
=
"节点"
)
private
String
nodeValue
;
@ApiModelProperty
(
value
=
"运输方式ID"
)
private
Long
transportId
;
@ApiModelProperty
(
value
=
"国家区号id"
)
private
Long
countryId
;
@ApiModelProperty
(
value
=
"国家区号,和订单中国家区号保持一致"
)
private
String
countryCode
;
@ApiModelProperty
(
value
=
"启用状态(0:启用,1:关闭)"
)
private
Integer
status
;
@ApiModelProperty
(
value
=
"模板1"
)
private
Long
templateIdOne
;
@ApiModelProperty
(
value
=
"模板2"
)
private
Long
templateIdTwo
;
@ApiModelProperty
(
value
=
"模板3"
)
private
Long
templateIdThree
;
@ApiModelProperty
(
value
=
"模板4"
)
private
Long
templateIdFour
;
@DateTimeFormat
(
pattern
=
FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND
)
@ApiModelProperty
(
value
=
"开始创建时间"
)
private
Date
beginCreateTime
;
@DateTimeFormat
(
pattern
=
FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND
)
@ApiModelProperty
(
value
=
"结束创建时间"
)
private
Date
endCreateTime
;
@ApiModelProperty
(
value
=
"是否匹配运输方式"
,
required
=
true
)
private
Integer
isTransport
;
@ApiModelProperty
(
value
=
"多订单"
,
required
=
true
)
private
Integer
isOrders
;
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/smsNode/SmsNodeUpdateReqVO.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
controller
.
admin
.
sms
.
vo
.
smsNode
;
import
lombok.*
;
import
java.util.*
;
import
io.swagger.annotations.*
;
import
javax.validation.constraints.*
;
@ApiModel
(
"管理后台 - 短信节点更新 Request VO"
)
@Data
@EqualsAndHashCode
(
callSuper
=
true
)
@ToString
(
callSuper
=
true
)
public
class
SmsNodeUpdateReqVO
extends
SmsNodeBaseVO
{
@ApiModelProperty
(
value
=
"编号"
,
required
=
true
)
@NotNull
(
message
=
"编号不能为空"
)
private
Long
id
;
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateBaseVO.java
View file @
56d736c3
...
...
@@ -6,9 +6,9 @@ import lombok.Data;
import
javax.validation.constraints.NotNull
;
/**
* 短信模板 Base VO,提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
* 短信模板 Base VO,提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public
class
SmsTemplateBaseVO
{
...
...
@@ -43,11 +43,25 @@ public class SmsTemplateBaseVO {
@NotNull
(
message
=
"短信渠道编号不能为空"
)
private
Long
channelId
;
@ApiModelProperty
(
value
=
"短信 API 的英文模板编号"
,
required
=
true
,
example
=
"4383920"
)
@NotNull
(
message
=
"短信 API 的英文模板编号不能为空"
)
private
String
apiTemplateIdEn
;
// @ApiModelProperty(value = "短信 API 的英文模板编号", required = true, example = "4383920")
// @NotNull(message = "短信 API 的英文模板编号不能为空")
// private String apiTemplateIdEn;
//
// @ApiModelProperty(value = "英文模板内容", required = true, example = "你好,{name}。你长的太{like}啦!")
// @NotNull(message = "英文模板内容不能为空")
// private String contentEn;
@ApiModelProperty
(
value
=
"英文模板内容"
,
required
=
true
,
example
=
"你好,{name}。你长的太{like}啦!"
)
@NotNull
(
message
=
"英文模板内容不能为空"
)
private
String
contentEn
;
@ApiModelProperty
(
value
=
"节点"
,
required
=
true
)
@NotNull
(
message
=
"节点不能为空"
)
private
String
nodeValue
;
@ApiModelProperty
(
value
=
"运输方式"
,
required
=
true
)
@NotNull
(
message
=
"运输方式不能为空"
)
private
Long
transportId
;
@ApiModelProperty
(
value
=
"发送类型"
,
required
=
true
)
private
Integer
messageType
;
@ApiModelProperty
(
value
=
"语言"
)
private
String
language
;
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateExcelVO.java
View file @
56d736c3
...
...
@@ -52,9 +52,21 @@ public class SmsTemplateExcelVO {
@ExcelProperty
(
"创建时间"
)
private
Date
createTime
;
@ExcelProperty
(
"英文模板内容"
)
private
String
contentEn
;
// @ExcelProperty("英文模板内容")
// private String contentEn;
//
// @ExcelProperty("短信 API 的英文模板编号")
// private String apiTemplateIdEn;
@ExcelProperty
(
"短信 API 的英文模板编号"
)
private
String
apiTemplateIdEn
;
@ExcelProperty
(
value
=
"节点"
)
private
String
nodeValue
;
@ExcelProperty
(
value
=
"运输方式"
)
private
Long
transportId
;
@ExcelProperty
(
value
=
"发送类型"
)
private
Integer
messageType
;
@ExcelProperty
(
value
=
"语言"
)
private
String
language
;
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateExportReqVO.java
View file @
56d736c3
...
...
@@ -44,4 +44,16 @@ public class SmsTemplateExportReqVO {
@ApiModelProperty
(
value
=
"短信 API 的英文模板编号"
,
example
=
"4383920"
,
notes
=
"模糊匹配"
)
private
String
apiTemplateIdEn
;
@ApiModelProperty
(
value
=
"节点"
)
private
String
nodeValue
;
@ApiModelProperty
(
value
=
"运输方式"
)
private
Long
transportId
;
@ApiModelProperty
(
value
=
"发送类型"
)
private
Integer
messageType
;
@ApiModelProperty
(
value
=
"语言"
)
private
String
language
;
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplatePageReqVO.java
View file @
56d736c3
...
...
@@ -49,4 +49,16 @@ public class SmsTemplatePageReqVO extends PageParam {
@ApiModelProperty
(
value
=
"短信 API 的英文模板编号"
,
example
=
"4383920"
,
notes
=
"模糊匹配"
)
private
String
apiTemplateIdEn
;
@ApiModelProperty
(
value
=
"节点"
)
private
String
nodeValue
;
@ApiModelProperty
(
value
=
"运输方式"
)
private
Long
transportId
;
@ApiModelProperty
(
value
=
"发送类型"
)
private
Integer
messageType
;
@ApiModelProperty
(
value
=
"语言"
)
private
String
language
;
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/convert/sms/SmsLogConvert.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
convert
.
sms
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.sms.core.client.dto.SmsLogDTO
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.log.SmsLogExcelVO
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.log.SmsLogRespVO
;
import
cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsLogDO
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
org.mapstruct.Mapper
;
import
org.mapstruct.factory.Mappers
;
...
...
@@ -21,6 +22,8 @@ public interface SmsLogConvert {
SmsLogRespVO
convert
(
SmsLogDO
bean
);
SmsLogDTO
toDto
(
SmsLogDO
smsLogDO
);
List
<
SmsLogRespVO
>
convertList
(
List
<
SmsLogDO
>
list
);
PageResult
<
SmsLogRespVO
>
convertPage
(
PageResult
<
SmsLogDO
>
page
);
...
...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/convert/sms/SmsNodeConvert.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
convert
.
sms
;
import
java.util.*
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.smsNode.SmsNodeBackVO
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.smsNode.SmsNodeCreateReqVO
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.smsNode.SmsNodeUpdateReqVO
;
import
cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsNodeDO
;
import
org.mapstruct.Mapper
;
import
org.mapstruct.factory.Mappers
;
/**
* 短信节点 Convert
* @author jayden
*/
@Mapper
public
interface
SmsNodeConvert
{
/*****转换MapStruct*****/
SmsNodeConvert
INSTANCE
=
Mappers
.
getMapper
(
SmsNodeConvert
.
class
);
/***
* 创建VO转实体
* @param bean
* @return
*/
SmsNodeDO
convert
(
SmsNodeCreateReqVO
bean
);
/***
* 修改VO转实体
* @param bean
* @return
*/
SmsNodeDO
convert
(
SmsNodeUpdateReqVO
bean
);
/***
* 实体转返回VO
* @param bean
* @return
*/
SmsNodeBackVO
convert
(
SmsNodeDO
bean
);
/***
* 实体列表转返回VO列表
* @param list
* @return
*/
List
<
SmsNodeBackVO
>
convertList
(
List
<
SmsNodeDO
>
list
);
/***
* 实体分页转返回分页
* @param page
* @return
*/
PageResult
<
SmsNodeBackVO
>
convertPage
(
PageResult
<
SmsNodeDO
>
page
);
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/convert/sms/SmsTemplateConvert.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
convert
.
sms
;
import
cn.iocoder.yudao.framework.sms.core.client.dto.SmsTemplateDTO
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplateCreateReqVO
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplateExcelVO
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplateRespVO
;
...
...
@@ -20,6 +21,8 @@ public interface SmsTemplateConvert {
SmsTemplateDO
convert
(
SmsTemplateUpdateReqVO
bean
);
SmsTemplateDTO
toDto
(
SmsTemplateDO
smsTemplateDO
);
SmsTemplateRespVO
convert
(
SmsTemplateDO
bean
);
List
<
SmsTemplateRespVO
>
convertList
(
List
<
SmsTemplateDO
>
list
);
...
...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/sms/SmsCodeDO.java
View file @
56d736c3
...
...
@@ -34,11 +34,10 @@ public class SmsCodeDO extends BaseDO {
*/
private
String
code
;
/**
*
发送场景
*
业务节点
*
* 枚举 {@link SmsCodeDO}
*/
private
Integer
scen
e
;
private
String
nodeValu
e
;
/**
* 创建 IP
*/
...
...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/sms/SmsLogDO.java
View file @
56d736c3
...
...
@@ -8,6 +8,7 @@ import cn.iocoder.yudao.framework.sms.core.enums.SmsFrameworkErrorCodeConstants;
import
com.baomidou.mybatisplus.annotation.TableField
;
import
com.baomidou.mybatisplus.annotation.TableName
;
import
com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.*
;
import
java.util.Date
;
...
...
@@ -37,13 +38,13 @@ public class SmsLogDO extends BaseDO {
/**
* 短信渠道编号
*
*
<p>
* 关联 {@link SmsChannelDO#getId()}
*/
private
Long
channelId
;
/**
* 短信渠道编码
*
*
<p>
* 冗余 {@link SmsChannelDO#getCode()}
*/
private
String
channelCode
;
...
...
@@ -52,19 +53,19 @@ public class SmsLogDO extends BaseDO {
/**
* 模板编号
*
*
<p>
* 关联 {@link SmsTemplateDO#getId()}
*/
private
Long
templateId
;
/**
* 模板编码
*
*
<p>
* 冗余 {@link SmsTemplateDO#getCode()}
*/
private
String
templateCode
;
/**
* 短信类型
*
*
<p>
* 冗余 {@link SmsTemplateDO#getType()}
*/
private
Integer
templateType
;
...
...
@@ -79,7 +80,7 @@ public class SmsLogDO extends BaseDO {
private
Map
<
String
,
Object
>
templateParams
;
/**
* 短信 API 的模板编号
*
*
<p>
* 冗余 {@link SmsTemplateDO#getApiTemplateId()}
*/
private
String
apiTemplateId
;
...
...
@@ -96,7 +97,7 @@ public class SmsLogDO extends BaseDO {
private
Long
userId
;
/**
* 用户类型
*
*
<p>
* 枚举 {@link UserTypeEnum}
*/
private
Integer
userType
;
...
...
@@ -105,7 +106,7 @@ public class SmsLogDO extends BaseDO {
/**
* 发送状态
*
*
<p>
* 枚举 {@link SmsSendStatusEnum}
*/
private
Integer
sendStatus
;
...
...
@@ -115,20 +116,20 @@ public class SmsLogDO extends BaseDO {
private
Date
sendTime
;
/**
* 发送结果的编码
*
*
<p>
* 枚举 {@link SmsFrameworkErrorCodeConstants}
*/
private
Integer
sendCode
;
/**
* 发送结果的提示
*
*
<p>
* 一般情况下,使用 {@link SmsFrameworkErrorCodeConstants}
* 异常情况下,通过格式化 Exception 的提示存储
*/
private
String
sendMsg
;
/**
* 短信 API 发送结果的编码
*
*
<p>
* 由于第三方的错误码可能是字符串,所以使用 String 类型
*/
private
String
apiSendCode
;
...
...
@@ -138,13 +139,13 @@ public class SmsLogDO extends BaseDO {
private
String
apiSendMsg
;
/**
* 短信 API 发送返回的唯一请求 ID
*
*
<p>
* 用于和短信 API 进行定位于排错
*/
private
String
apiRequestId
;
/**
* 短信 API 发送返回的序号
*
*
<p>
* 用于和短信 API 平台的发送记录关联
*/
private
String
apiSerialNo
;
...
...
@@ -153,7 +154,7 @@ public class SmsLogDO extends BaseDO {
/**
* 接收状态
*
*
<p>
* 枚举 {@link SmsReceiveStatusEnum}
*/
private
Integer
receiveStatus
;
...
...
@@ -179,5 +180,19 @@ public class SmsLogDO extends BaseDO {
*/
private
Integer
num
;
/**
* 短信节点表id
*/
private
Long
nodeId
;
/**
* 节点模板序列号
*/
private
Integer
nodeTemplateSn
;
/**
* 发送类型
*/
private
Integer
messageType
;
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/sms/SmsNodeDO.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
dal
.
dataobject
.
sms
;
import
lombok.*
;
import
java.util.*
;
import
com.baomidou.mybatisplus.annotation.*
;
import
cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO
;
/**
* 短信节点 DO
*
* @author jayden
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName
(
"system_sms_node"
)
@EqualsAndHashCode
(
callSuper
=
true
)
@ToString
(
callSuper
=
true
)
public
class
SmsNodeDO
extends
BaseDO
{
/**
* 编号
*/
@TableId
private
Long
id
;
/**
* 节点
*/
private
String
nodeValue
;
/**
* 运输方式ID
*
*/
private
Integer
transportId
;
/**
* 国家区号id
*/
private
Long
countryId
;
/**
* 国家区号,和订单中国家区号保持一致
*/
private
String
countryCode
;
/**
* 启用状态(0:启用,1:关闭)
*/
private
Integer
status
;
/**
* 模板1
*/
private
Long
templateIdOne
;
/**
* 模板2
*/
@TableField
(
updateStrategy
=
FieldStrategy
.
IGNORED
)
private
Long
templateIdTwo
;
/**
* 模板3
*/
@TableField
(
updateStrategy
=
FieldStrategy
.
IGNORED
)
private
Long
templateIdThree
;
/**
* 模板4
*/
@TableField
(
updateStrategy
=
FieldStrategy
.
IGNORED
)
private
Long
templateIdFour
;
/**
* 是否匹配运输方式(0:否,1:是)
*/
private
Integer
isTransport
;
/**
* 多订单(0:否,1:是)
*/
private
Integer
isOrders
;
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/sms/SmsTemplateDO.java
View file @
56d736c3
...
...
@@ -95,5 +95,20 @@ public class SmsTemplateDO extends BaseDO {
* 短信 API 的英文模板编号
*/
private
String
apiTemplateIdEn
;
/**
* 节点
*/
private
String
nodeValue
;
/**
* 运输方式
*/
private
Long
transportId
;
/**
* 发送类型
*/
private
Integer
messageType
;
/**
* 语言
*/
private
String
language
;
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/sms/SmsCodeMapper.java
View file @
56d736c3
...
...
@@ -16,13 +16,13 @@ public interface SmsCodeMapper extends BaseMapperX<SmsCodeDO> {
* 获得手机号的最后一个手机验证码
*
* @param mobile 手机号
* @param
scen
e 发送场景,选填
* @param
nodeValu
e 发送场景,选填
* @param code 验证码 选填
* @return 手机验证码
*/
default
SmsCodeDO
selectLastByMobile
(
String
mobile
,
String
code
,
Integer
scen
e
)
{
default
SmsCodeDO
selectLastByMobile
(
String
mobile
,
String
code
,
String
nodeValu
e
)
{
return
selectOne
(
new
QueryWrapperX
<
SmsCodeDO
>()
.
eq
(
"mobile"
,
mobile
).
eqIfPresent
(
"
scene"
,
scen
e
).
eqIfPresent
(
"code"
,
code
)
.
eq
(
"mobile"
,
mobile
).
eqIfPresent
(
"
node_value"
,
nodeValu
e
).
eqIfPresent
(
"code"
,
code
)
.
between
(
"create_time"
,
DateUtil
.
beginOfDay
(
new
Date
()),
DateUtil
.
endOfDay
(
new
Date
()))
.
orderByDesc
(
"id"
).
last
(
SqlConstants
.
LIMIT1
));
}
...
...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/sms/SmsLogMapper.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
dal
.
mysql
.
sms
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.log.SmsLogExportReqVO
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.log.SmsLogPageReqVO
;
import
cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsLogDO
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX
;
import
cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.log.SmsLogExportReqVO
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.log.SmsLogPageReqVO
;
import
cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsLogDO
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.ibatis.annotations.Delete
;
import
org.apache.ibatis.annotations.Mapper
;
...
...
@@ -18,6 +19,8 @@ public interface SmsLogMapper extends BaseMapperX<SmsLogDO> {
return
selectPage
(
reqVO
,
new
QueryWrapperX
<
SmsLogDO
>()
.
eqIfPresent
(
"channel_id"
,
reqVO
.
getChannelId
())
.
eqIfPresent
(
"template_id"
,
reqVO
.
getTemplateId
())
.
eqIfPresent
(
"node_id"
,
reqVO
.
getNodeId
())
.
eqIfPresent
(
"node_template_sn"
,
reqVO
.
getNodeTemplateSn
())
.
likeIfPresent
(
"mobile"
,
reqVO
.
getMobile
())
.
eqIfPresent
(
"send_status"
,
reqVO
.
getSendStatus
())
.
betweenIfPresent
(
"send_time"
,
reqVO
.
getBeginSendTime
(),
reqVO
.
getEndSendTime
())
...
...
@@ -30,11 +33,14 @@ public interface SmsLogMapper extends BaseMapperX<SmsLogDO> {
return
selectList
(
new
QueryWrapperX
<
SmsLogDO
>()
.
eqIfPresent
(
"channel_id"
,
reqVO
.
getChannelId
())
.
eqIfPresent
(
"template_id"
,
reqVO
.
getTemplateId
())
.
eqIfPresent
(
"node_id"
,
reqVO
.
getNodeId
())
.
eqIfPresent
(
"node_template_sn"
,
reqVO
.
getNodeTemplateSn
())
.
likeIfPresent
(
"mobile"
,
reqVO
.
getMobile
())
.
eqIfPresent
(
"send_status"
,
reqVO
.
getSendStatus
())
.
betweenIfPresent
(
"send_time"
,
reqVO
.
getBeginSendTime
(),
reqVO
.
getEndSendTime
())
.
eqIfPresent
(
"receive_status"
,
reqVO
.
getReceiveStatus
())
.
betweenIfPresent
(
"receive_time"
,
reqVO
.
getBeginReceiveTime
(),
reqVO
.
getEndReceiveTime
())
.
eq
(
StringUtils
.
isNotBlank
(
reqVO
.
getApiSerialNo
()),
"api_serial_no"
,
reqVO
.
getApiSerialNo
())
.
orderByDesc
(
"id"
));
}
...
...
@@ -42,4 +48,11 @@ public interface SmsLogMapper extends BaseMapperX<SmsLogDO> {
"DELETE FROM system_sms_log WHERE date(create_time) <= date(date_sub(now(), interval 90 day))"
})
int
clearLog
(
Integer
day
);
default
List
<
SmsLogDO
>
selectReceiveList
()
{
return
selectList
(
new
QueryWrapperX
<
SmsLogDO
>()
.
apply
(
"create_time >= NOW() - INTERVAL 20 HOUR"
)
.
eq
(
"template_type"
,
2
)
.
lt
(
"num"
,
1
)
.
ne
(
"receive_status"
,
10
));
}
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/sms/SmsNodeMapper.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
dal
.
mysql
.
sms
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.mybatis.core.mapper.AbstractMapper
;
import
cn.iocoder.yudao.framework.mybatis.core.query.LambdaQuery
;
import
cn.iocoder.yudao.framework.mybatis.core.vo.PageVO
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.smsNode.SmsNodeQueryVO
;
import
cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsNodeDO
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.ibatis.annotations.Mapper
;
import
java.util.List
;
/**
* 短信节点 Mapper
*
* @author jayden
*/
@Mapper
public
interface
SmsNodeMapper
extends
AbstractMapper
<
SmsNodeDO
>
{
@Override
default
PageResult
<
SmsNodeDO
>
selectPage
(
PageVO
page
,
Object
object
)
{
if
(
object
instanceof
SmsNodeQueryVO
)
{
SmsNodeQueryVO
vo
=
(
SmsNodeQueryVO
)
object
;
return
selectPage
(
page
,
new
LambdaQuery
<
SmsNodeDO
>()
.
eq
(
StringUtils
.
isNotBlank
(
vo
.
getNodeValue
()),
SmsNodeDO:
:
getNodeValue
,
vo
.
getNodeValue
())
.
eqIfPresent
(
SmsNodeDO:
:
getTransportId
,
vo
.
getTransportId
())
.
eqIfPresent
(
SmsNodeDO:
:
getCountryId
,
vo
.
getCountryId
())
.
eqIfPresent
(
SmsNodeDO:
:
getCountryCode
,
vo
.
getCountryCode
())
.
eqIfPresent
(
SmsNodeDO:
:
getIsTransport
,
vo
.
getIsTransport
())
.
eqIfPresent
(
SmsNodeDO:
:
getIsOrders
,
vo
.
getIsOrders
())
.
eqIfPresent
(
SmsNodeDO:
:
getStatus
,
vo
.
getStatus
())
.
eqIfPresent
(
SmsNodeDO:
:
getTemplateIdOne
,
vo
.
getTemplateIdOne
())
.
eqIfPresent
(
SmsNodeDO:
:
getTemplateIdTwo
,
vo
.
getTemplateIdTwo
())
.
eqIfPresent
(
SmsNodeDO:
:
getTemplateIdThree
,
vo
.
getTemplateIdThree
())
.
eqIfPresent
(
SmsNodeDO:
:
getTemplateIdFour
,
vo
.
getTemplateIdFour
())
.
betweenIfPresent
(
SmsNodeDO:
:
getCreateTime
,
vo
.
getBeginCreateTime
(),
vo
.
getEndCreateTime
())
.
orderByDesc
(
SmsNodeDO:
:
getId
));
}
return
null
;
}
@Override
default
List
<
SmsNodeDO
>
selectList
(
Object
object
)
{
if
(
object
instanceof
SmsNodeQueryVO
)
{
SmsNodeQueryVO
vo
=
(
SmsNodeQueryVO
)
object
;
return
selectList
(
new
LambdaQuery
<
SmsNodeDO
>()
.
eq
(
StringUtils
.
isNotBlank
(
vo
.
getNodeValue
()),
SmsNodeDO:
:
getNodeValue
,
vo
.
getNodeValue
())
.
eqIfPresent
(
SmsNodeDO:
:
getTransportId
,
vo
.
getTransportId
())
.
eqIfPresent
(
SmsNodeDO:
:
getCountryId
,
vo
.
getCountryId
())
.
eqIfPresent
(
SmsNodeDO:
:
getCountryCode
,
vo
.
getCountryCode
())
.
eqIfPresent
(
SmsNodeDO:
:
getIsTransport
,
vo
.
getIsTransport
())
.
eqIfPresent
(
SmsNodeDO:
:
getIsOrders
,
vo
.
getIsOrders
())
.
eqIfPresent
(
SmsNodeDO:
:
getStatus
,
vo
.
getStatus
())
.
eqIfPresent
(
SmsNodeDO:
:
getTemplateIdOne
,
vo
.
getTemplateIdOne
())
.
eqIfPresent
(
SmsNodeDO:
:
getTemplateIdTwo
,
vo
.
getTemplateIdTwo
())
.
eqIfPresent
(
SmsNodeDO:
:
getTemplateIdThree
,
vo
.
getTemplateIdThree
())
.
eqIfPresent
(
SmsNodeDO:
:
getTemplateIdFour
,
vo
.
getTemplateIdFour
())
.
betweenIfPresent
(
SmsNodeDO:
:
getCreateTime
,
vo
.
getBeginCreateTime
(),
vo
.
getEndCreateTime
())
.
orderByDesc
(
SmsNodeDO:
:
getId
));
}
return
null
;
}
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/sms/SmsTemplateMapper.java
View file @
56d736c3
...
...
@@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplateExportReqVO
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplatePageReqVO
;
import
cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsTemplateDO
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.ibatis.annotations.Mapper
;
import
org.apache.ibatis.annotations.Select
;
...
...
@@ -26,6 +27,10 @@ public interface SmsTemplateMapper extends BaseMapperX<SmsTemplateDO> {
return
selectPage
(
reqVO
,
new
LambdaQueryWrapperX
<
SmsTemplateDO
>()
.
eqIfPresent
(
SmsTemplateDO:
:
getType
,
reqVO
.
getType
())
.
eqIfPresent
(
SmsTemplateDO:
:
getStatus
,
reqVO
.
getStatus
())
.
eq
(
StringUtils
.
isNotBlank
(
reqVO
.
getNodeValue
()),
SmsTemplateDO:
:
getNodeValue
,
reqVO
.
getNodeValue
())
.
eqIfPresent
(
SmsTemplateDO:
:
getTransportId
,
reqVO
.
getTransportId
())
.
eqIfPresent
(
SmsTemplateDO:
:
getMessageType
,
reqVO
.
getMessageType
())
.
eqIfPresent
(
SmsTemplateDO:
:
getLanguage
,
reqVO
.
getLanguage
())
.
likeIfPresent
(
SmsTemplateDO:
:
getCode
,
reqVO
.
getCode
())
.
likeIfPresent
(
SmsTemplateDO:
:
getContent
,
reqVO
.
getContent
())
.
likeIfPresent
(
SmsTemplateDO:
:
getContentEn
,
reqVO
.
getContentEn
())
...
...
@@ -40,6 +45,10 @@ public interface SmsTemplateMapper extends BaseMapperX<SmsTemplateDO> {
return
selectList
(
new
LambdaQueryWrapperX
<
SmsTemplateDO
>()
.
eqIfPresent
(
SmsTemplateDO:
:
getType
,
reqVO
.
getType
())
.
eqIfPresent
(
SmsTemplateDO:
:
getStatus
,
reqVO
.
getStatus
())
.
eq
(
StringUtils
.
isNotBlank
(
reqVO
.
getNodeValue
()),
SmsTemplateDO:
:
getNodeValue
,
reqVO
.
getNodeValue
())
.
eqIfPresent
(
SmsTemplateDO:
:
getTransportId
,
reqVO
.
getTransportId
())
.
eqIfPresent
(
SmsTemplateDO:
:
getMessageType
,
reqVO
.
getMessageType
())
.
eqIfPresent
(
SmsTemplateDO:
:
getLanguage
,
reqVO
.
getLanguage
())
.
likeIfPresent
(
SmsTemplateDO:
:
getCode
,
reqVO
.
getCode
())
.
likeIfPresent
(
SmsTemplateDO:
:
getContent
,
reqVO
.
getContent
())
.
likeIfPresent
(
SmsTemplateDO:
:
getApiTemplateId
,
reqVO
.
getApiTemplateId
())
...
...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/mq/consumer/sms/SmsSendConsumer.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
mq
.
consumer
.
sms
;
import
cn.iocoder.yudao.module.system.mq.message.sms.SmsSendMessage
;
import
cn.iocoder.yudao.module.system.service.sms.SmsSendService
;
import
cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.Resource
;
/**
* 针对 {@link SmsSendMessage} 的消费者
*
* @author zzf
*/
@Component
@Slf4j
public
class
SmsSendConsumer
extends
AbstractStreamMessageListener
<
SmsSendMessage
>
{
@Resource
private
SmsSendService
smsSendService
;
@Override
public
void
onMessage
(
SmsSendMessage
message
)
{
log
.
info
(
"[onMessage][消息内容({})]"
,
message
);
smsSendService
.
doSendSms
(
message
);
}
}
//
package cn.iocoder.yudao.module.system.mq.consumer.sms;
//
//
import cn.iocoder.yudao.module.system.mq.message.sms.SmsSendMessage;
//
import cn.iocoder.yudao.module.system.service.sms.SmsSendService;
//
import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener;
//
import lombok.extern.slf4j.Slf4j;
//
import org.springframework.stereotype.Component;
//
//
import javax.annotation.Resource;
//
/
//
**
//
* 针对 {@link SmsSendMessage} 的消费者
//
*
//
* @author zzf
//
*/
//
@Component
//
@Slf4j
//
public class SmsSendConsumer extends AbstractStreamMessageListener<SmsSendMessage> {
//
//
@Resource
//
private SmsSendService smsSendService;
//
//
@Override
//
public void onMessage(SmsSendMessage message) {
//
log.info("[onMessage][消息内容({})]", message);
//
smsSendService.doSendSms(message);
//
}
//
//
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/mq/consumer/sms/SmsSendConsumerV2.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
mq
.
consumer
.
sms
;
import
cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener
;
import
cn.iocoder.yudao.module.system.mq.message.sms.SmsSendMessage
;
import
cn.iocoder.yudao.module.system.mq.message.sms.SmsSendMessageV2
;
import
cn.iocoder.yudao.module.system.service.sms.SmsSendService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.Resource
;
/**
* 针对 {@link SmsSendMessage} 的消费者
*
* @author zzf
*/
@Component
@Slf4j
public
class
SmsSendConsumerV2
extends
AbstractStreamMessageListener
<
SmsSendMessageV2
>
{
@Resource
private
SmsSendService
smsSendService
;
@Override
public
void
onMessage
(
SmsSendMessageV2
message
)
{
log
.
info
(
"[onMessageV2][消息内容({})]"
,
message
);
smsSendService
.
doSendSmsV2
(
message
);
}
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/mq/message/sms/SmsSendMessageV2.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
mq
.
message
.
sms
;
import
cn.iocoder.yudao.framework.common.util.json.core.KeyValue
;
import
cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessage
;
import
cn.iocoder.yudao.framework.sms.core.client.dto.SmsTemplateDTO
;
import
cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsTemplateDO
;
import
lombok.Data
;
import
lombok.EqualsAndHashCode
;
import
javax.validation.constraints.NotNull
;
import
java.util.List
;
/**
* 短信发送消息
*
* @author 捷道源码
*/
@Data
@EqualsAndHashCode
(
callSuper
=
true
)
public
class
SmsSendMessageV2
extends
AbstractStreamMessage
{
/**
* 短信日志编号
*/
@NotNull
(
message
=
"短信日志编号不能为空"
)
private
Long
logId
;
/**
* 手机号
*/
@NotNull
(
message
=
"手机号不能为空"
)
private
String
mobile
;
/**
* 模板
*/
@NotNull
(
message
=
"模板不能为空"
)
private
SmsTemplateDTO
smsTemplateDTO
;
/**
* 短信模板参数
*/
private
List
<
KeyValue
<
String
,
Object
>>
templateParams
;
@Override
public
String
getStreamKey
()
{
return
"system.sms.send"
;
}
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/mq/producer/sms/SmsProducer.java
View file @
56d736c3
...
...
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.mq.producer.sms;
import
cn.iocoder.yudao.framework.common.util.json.core.KeyValue
;
import
cn.iocoder.yudao.module.system.mq.message.sms.SmsChannelRefreshMessage
;
import
cn.iocoder.yudao.module.system.mq.message.sms.SmsSendMessage
;
import
cn.iocoder.yudao.module.system.mq.message.sms.SmsSendMessageV2
;
import
cn.iocoder.yudao.module.system.mq.message.sms.SmsTemplateRefreshMessage
;
import
cn.iocoder.yudao.framework.mq.core.RedisMQTemplate
;
import
lombok.extern.slf4j.Slf4j
;
...
...
@@ -56,4 +57,7 @@ public class SmsProducer {
redisMQTemplate
.
send
(
message
);
}
public
void
sendSmsSendMessageV2
(
SmsSendMessageV2
message
)
{
redisMQTemplate
.
send
(
message
);
}
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/mail/impl/EmailCodeServiceImpl.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
service
.
mail
.
impl
;
import
cn.hutool.core.lang.Assert
;
import
cn.hutool.core.map.MapUtil
;
import
cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil
;
import
cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeCheckReqDTO
;
import
cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO
;
import
cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO
;
import
cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsCodeDO
;
import
cn.iocoder.yudao.module.system.dal.mysql.sms.SmsCodeMapper
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum
;
import
cn.iocoder.yudao.module.system.framework.sms.SmsCodeProperties
;
import
cn.iocoder.yudao.module.system.service.sms.SmsCodeService
;
import
cn.iocoder.yudao.module.system.service.sms.SmsSendService
;
import
org.springframework.stereotype.Service
;
import
org.springframework.validation.annotation.Validated
;
import
javax.annotation.Resource
;
import
java.util.Date
;
import
static
cn
.
hutool
.
core
.
util
.
RandomUtil
.
randomInt
;
import
static
cn
.
iocoder
.
yudao
.
module
.
system
.
enums
.
ErrorCodeConstants
.*;
/**
* 短信验证码 Service 实现类
*
* @author 捷道源码
*/
@Service
@Validated
public
class
EmailCodeServiceImpl
implements
EmailCodeService
{
@Resource
private
SmsCodeProperties
smsCodeProperties
;
@Resource
private
SmsCodeMapper
smsCodeMapper
;
@Resource
private
SmsSendService
smsSendService
;
@Override
public
void
sendEmailCode
(
SmsCodeSendReqDTO
reqDTO
)
{
SmsSceneEnum
sceneEnum
=
SmsSceneEnum
.
getCodeByScene
(
reqDTO
.
getScene
());
Assert
.
notNull
(
sceneEnum
,
"验证码场景({}) 查找不到配置"
,
reqDTO
.
getScene
());
// 创建验证码
String
code
=
createSmsCode
(
reqDTO
.
getMobile
(),
reqDTO
.
getScene
(),
reqDTO
.
getCreateIp
());
// 发送验证码
smsSendService
.
sendSingleSms
(
reqDTO
.
getAreaCode
()+
reqDTO
.
getMobile
(),
null
,
null
,
sceneEnum
.
getTemplateCode
(),
MapUtil
.
of
(
"code"
,
code
));
}
private
String
createSmsCode
(
String
mobile
,
Integer
scene
,
String
ip
)
{
// 校验是否可以发送验证码,不用筛选场景
SmsCodeDO
lastSmsCode
=
smsCodeMapper
.
selectLastByMobile
(
mobile
,
null
,
null
);
if
(
lastSmsCode
!=
null
)
{
if
(
lastSmsCode
.
getTodayIndex
()
>=
smsCodeProperties
.
getSendMaximumQuantityPerDay
())
{
// 超过当天发送的上限。
throw
ServiceExceptionUtil
.
exception
(
SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY
);
}
if
(
System
.
currentTimeMillis
()
-
lastSmsCode
.
getCreateTime
().
getTime
()
<
smsCodeProperties
.
getSendFrequency
().
toMillis
())
{
// 发送过于频繁
throw
ServiceExceptionUtil
.
exception
(
SMS_CODE_SEND_TOO_FAST
);
}
// TODO 芋艿:提升,每个 IP 每天可发送数量
// TODO 芋艿:提升,每个 IP 每小时可发送数量
}
// 创建验证码记录
String
code
=
String
.
valueOf
(
randomInt
(
smsCodeProperties
.
getBeginCode
(),
smsCodeProperties
.
getEndCode
()
+
1
));
SmsCodeDO
newSmsCode
=
SmsCodeDO
.
builder
().
mobile
(
mobile
).
code
(
code
)
.
scene
(
scene
).
todayIndex
(
lastSmsCode
!=
null
?
lastSmsCode
.
getTodayIndex
()
+
1
:
1
)
.
createIp
(
ip
).
used
(
false
).
build
();
smsCodeMapper
.
insert
(
newSmsCode
);
return
code
;
}
@Override
public
void
useSmsCode
(
SmsCodeUseReqDTO
reqDTO
)
{
// 检测验证码是否有效
SmsCodeDO
lastSmsCode
=
this
.
checkSmsCode0
(
reqDTO
.
getMobile
(),
reqDTO
.
getCode
(),
reqDTO
.
getScene
());
// 使用验证码
smsCodeMapper
.
updateById
(
SmsCodeDO
.
builder
().
id
(
lastSmsCode
.
getId
())
.
used
(
true
).
usedTime
(
new
Date
()).
usedIp
(
reqDTO
.
getUsedIp
()).
build
());
}
@Override
public
void
checkSmsCode
(
SmsCodeCheckReqDTO
reqDTO
)
{
checkSmsCode0
(
reqDTO
.
getMobile
(),
reqDTO
.
getCode
(),
reqDTO
.
getScene
());
}
public
SmsCodeDO
checkSmsCode0
(
String
mobile
,
String
code
,
Integer
scene
)
{
// 校验验证码
SmsCodeDO
lastSmsCode
=
smsCodeMapper
.
selectLastByMobile
(
mobile
,
code
,
scene
);
// 若验证码不存在,抛出异常
if
(
lastSmsCode
==
null
)
{
throw
ServiceExceptionUtil
.
exception
(
SMS_CODE_NOT_FOUND
);
}
// 超过时间
if
(
System
.
currentTimeMillis
()
-
lastSmsCode
.
getCreateTime
().
getTime
()
>=
smsCodeProperties
.
getExpireTimes
().
toMillis
())
{
// 验证码已过期
throw
ServiceExceptionUtil
.
exception
(
SMS_CODE_EXPIRED
);
}
// 判断验证码是否已被使用
if
(
Boolean
.
TRUE
.
equals
(
lastSmsCode
.
getUsed
()))
{
throw
ServiceExceptionUtil
.
exception
(
SMS_CODE_USED
);
}
return
lastSmsCode
;
}
}
//
package cn.iocoder.yudao.module.system.service.mail.impl;
//
//
import cn.hutool.core.lang.Assert;
//
import cn.hutool.core.map.MapUtil;
//
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
//
import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeCheckReqDTO;
//
import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
//
import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
//
import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsCodeDO;
//
import cn.iocoder.yudao.module.system.dal.mysql.sms.SmsCodeMapper;
//
import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
//
import cn.iocoder.yudao.module.system.framework.sms.SmsCodeProperties;
//
import cn.iocoder.yudao.module.system.service.sms.SmsCodeService;
//
import cn.iocoder.yudao.module.system.service.sms.SmsSendService;
//
import org.springframework.stereotype.Service;
//
import org.springframework.validation.annotation.Validated;
//
//
import javax.annotation.Resource;
//
import java.util.Date;
//
//
import static cn.hutool.core.util.RandomUtil.randomInt;
//
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
//
/
//
**
//
* 短信验证码 Service 实现类
//
*
//
* @author 捷道源码
//
*/
//
@Service
//
@Validated
//
public class EmailCodeServiceImpl implements EmailCodeService {
//
//
@Resource
//
private SmsCodeProperties smsCodeProperties;
//
//
@Resource
//
private SmsCodeMapper smsCodeMapper;
//
//
@Resource
//
private SmsSendService smsSendService;
//
//
@Override
//
public void sendEmailCode(SmsCodeSendReqDTO reqDTO) {
//
SmsSceneEnum sceneEnum = SmsSceneEnum.getCodeByScene(reqDTO.getScene());
//
Assert.notNull(sceneEnum, "验证码场景({}) 查找不到配置", reqDTO.getScene());
//
// 创建验证码
//
String code = createSmsCode(reqDTO.getMobile(), reqDTO.getScene(), reqDTO.getCreateIp());
//
// 发送验证码
//
smsSendService.sendSingleSms(reqDTO.getAreaCode()+reqDTO.getMobile(), null, null,
//
sceneEnum.getTemplateCode(), MapUtil.of("code", code));
//
}
//
//
private String createSmsCode(String mobile, Integer scene, String ip) {
//
// 校验是否可以发送验证码,不用筛选场景
//
SmsCodeDO lastSmsCode = smsCodeMapper.selectLastByMobile(mobile, null,null);
//
if (lastSmsCode != null) {
//
if (lastSmsCode.getTodayIndex() >= smsCodeProperties.getSendMaximumQuantityPerDay()) { // 超过当天发送的上限。
//
throw ServiceExceptionUtil.exception(SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY);
//
}
//
if (System.currentTimeMillis() - lastSmsCode.getCreateTime().getTime()
//
< smsCodeProperties.getSendFrequency().toMillis()) { // 发送过于频繁
//
throw ServiceExceptionUtil.exception(SMS_CODE_SEND_TOO_FAST);
//
}
//
// TODO 芋艿:提升,每个 IP 每天可发送数量
//
// TODO 芋艿:提升,每个 IP 每小时可发送数量
//
}
//
//
// 创建验证码记录
//
String code = String.valueOf(randomInt(smsCodeProperties.getBeginCode(), smsCodeProperties.getEndCode() + 1));
//
SmsCodeDO newSmsCode = SmsCodeDO.builder().mobile(mobile).code(code)
//
.scene(scene).todayIndex(lastSmsCode != null ? lastSmsCode.getTodayIndex() + 1 : 1)
//
.createIp(ip).used(false).build();
//
smsCodeMapper.insert(newSmsCode);
//
return code;
//
}
//
//
@Override
//
public void useSmsCode(SmsCodeUseReqDTO reqDTO) {
//
// 检测验证码是否有效
//
SmsCodeDO lastSmsCode = this.checkSmsCode0(reqDTO.getMobile(), reqDTO.getCode(), reqDTO.getScene());
//
// 使用验证码
//
smsCodeMapper.updateById(SmsCodeDO.builder().id(lastSmsCode.getId())
//
.used(true).usedTime(new Date()).usedIp(reqDTO.getUsedIp()).build());
//
}
//
//
@Override
//
public void checkSmsCode(SmsCodeCheckReqDTO reqDTO) {
//
checkSmsCode0(reqDTO.getMobile(), reqDTO.getCode(), reqDTO.getScene());
//
}
//
//
public SmsCodeDO checkSmsCode0(String mobile, String code, Integer scene) {
//
// 校验验证码
//
SmsCodeDO lastSmsCode = smsCodeMapper.selectLastByMobile(mobile,code,scene);
//
// 若验证码不存在,抛出异常
//
if (lastSmsCode == null) {
//
throw ServiceExceptionUtil.exception(SMS_CODE_NOT_FOUND);
//
}
//
// 超过时间
//
if (System.currentTimeMillis() - lastSmsCode.getCreateTime().getTime()
//
>= smsCodeProperties.getExpireTimes().toMillis()) { // 验证码已过期
//
throw ServiceExceptionUtil.exception(SMS_CODE_EXPIRED);
//
}
//
// 判断验证码是否已被使用
//
if (Boolean.TRUE.equals(lastSmsCode.getUsed())) {
//
throw ServiceExceptionUtil.exception(SMS_CODE_USED);
//
}
//
return lastSmsCode;
//
}
//
//
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/sms/QuerySendDetails.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
service
.
sms
;
import
com.aliyuncs.DefaultAcsClient
;
import
com.aliyuncs.IAcsClient
;
import
com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsRequest
;
import
com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse
;
import
com.aliyuncs.profile.DefaultProfile
;
import
com.aliyuncs.profile.IClientProfile
;
import
java.text.ParseException
;
import
java.text.SimpleDateFormat
;
import
java.util.Date
;
import
java.util.List
;
/**
* @author Jayden
* @date 2024/11/12
*/
public
class
QuerySendDetails
{
/**
* <b>description</b> :
* <p>使用AK&SK初始化账号Client</p>
*
* @return Client
* @throws Exception
*/
public
static
IAcsClient
createClient
()
throws
Exception
{
// 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
// 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378657.html。
String
key
=
"LTAIh5ooNeMRzsuz"
;
String
secret
=
"jdqgtCP2Z0nZllEcxMiX8pv8qUDOTq"
;
IClientProfile
profile
=
DefaultProfile
.
getProfile
(
"cn-hangzhou"
,
key
,
secret
);
IAcsClient
defaultAcsClient
=
new
DefaultAcsClient
(
profile
);
return
defaultAcsClient
;
}
public
static
void
main
(
String
[]
args_
)
throws
Exception
{
String
key
=
"LTAIh5ooNeMRzsuz"
;
String
secret
=
"jdqgtCP2Z0nZllEcxMiX8pv8qUDOTq"
;
IClientProfile
profile
=
DefaultProfile
.
getProfile
(
"cn-hangzhou"
,
key
,
secret
);
IAcsClient
client
=
new
DefaultAcsClient
(
profile
);
QuerySendDetailsRequest
querySendDetailsRequest
=
new
QuerySendDetailsRequest
();
querySendDetailsRequest
.
setPhoneNumber
(
"233591972886"
);
querySendDetailsRequest
.
setPageSize
(
1L
);
querySendDetailsRequest
.
setCurrentPage
(
1L
);
querySendDetailsRequest
.
setSendDate
(
"20240905"
);
querySendDetailsRequest
.
setBizId
(
"373707825513736449^0"
);
QuerySendDetailsResponse
acsResponse
=
client
.
getAcsResponse
(
querySendDetailsRequest
);
List
<
QuerySendDetailsResponse
.
SmsSendDetailDTO
>
smsSendDetailDTOs
=
acsResponse
.
getSmsSendDetailDTOs
();
String
receiveDate
=
smsSendDetailDTOs
.
get
(
0
).
getReceiveDate
();
System
.
out
.
println
(
convertDateFormat
(
receiveDate
));
}
/**
* 将日期字符串从 "yyyy-MM-dd HH:mm:ss" 格式转换为 "yyyyMMdd" 格式
*
* @param inputDateStr 输入的日期字符串,格式为 "yyyy-MM-dd HH:mm:ss"
* @return 转换后的日期字符串,格式为 "yyyyMMdd"
*/
public
static
String
convertDateFormat
(
String
inputDateStr
)
{
SimpleDateFormat
inputFormat
=
new
SimpleDateFormat
(
"yyyy-MM-dd HH:mm:ss"
);
SimpleDateFormat
outputFormat
=
new
SimpleDateFormat
(
"yyyyMMdd"
);
try
{
// 解析输入的日期字符串
Date
date
=
inputFormat
.
parse
(
inputDateStr
);
// 格式化日期为输出格式
return
outputFormat
.
format
(
date
);
}
catch
(
ParseException
e
)
{
// 处理解析异常
e
.
printStackTrace
();
return
null
;
}
}
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsCodeServiceImpl.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
service
.
sms
;
import
cn.hutool.core.lang.Assert
;
import
cn.hutool.core.map.MapUtil
;
import
cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil
;
import
cn.iocoder.yudao.framework.web.config.BusinessProperties
;
...
...
@@ -9,14 +8,12 @@ import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
import
cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO
;
import
cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsCodeDO
;
import
cn.iocoder.yudao.module.system.dal.mysql.sms.SmsCodeMapper
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum
;
import
cn.iocoder.yudao.module.system.framework.sms.SmsCodeProperties
;
import
org.springframework.stereotype.Service
;
import
org.springframework.validation.annotation.Validated
;
import
javax.annotation.Resource
;
import
java.util.Date
;
import
java.util.Objects
;
import
static
cn
.
hutool
.
core
.
util
.
RandomUtil
.
randomInt
;
import
static
cn
.
iocoder
.
yudao
.
module
.
system
.
enums
.
ErrorCodeConstants
.*;
...
...
@@ -44,38 +41,38 @@ public class SmsCodeServiceImpl implements SmsCodeService {
@Override
public
void
sendSmsCode
(
SmsCodeSendReqDTO
reqDTO
)
{
SmsSceneEnum
sceneEnum
=
SmsSceneEnum
.
getCodeByScene
(
reqDTO
.
getScene
());
Assert
.
notNull
(
sceneEnum
,
"验证码场景({}) 查找不到配置"
,
reqDTO
.
getScene
());
// if (Objects.nonNull(businessProperties) && businessProperties.isDebug()){
//
SmsSceneEnum sceneEnum = SmsSceneEnum.getCodeByScene(reqDTO.getScene());
//
Assert.notNull(sceneEnum, "验证码场景({}) 查找不到配置", reqDTO.getScene());
// if (Objects.nonNull(businessProperties) && businessProperties.isDebug())
{
// // TODO debug业务模式下不需要生成发送验证码,固定使用9999
// return;
// }
// 创建验证码
String
code
=
createSmsCode
(
reqDTO
.
getMobile
(),
reqDTO
.
get
Scen
e
(),
reqDTO
.
getCreateIp
());
String
code
=
createSmsCode
(
reqDTO
.
getMobile
(),
reqDTO
.
get
NodeValu
e
(),
reqDTO
.
getCreateIp
());
// 发送验证码
smsSendService
.
sendSingleSms
(
reqDTO
.
getAreaCode
()
+
reqDTO
.
getMobile
(),
null
,
null
,
sceneEnum
.
getTemplateCode
(),
MapUtil
.
of
(
"code"
,
code
)
);
smsSendService
.
sendSingleSms
V2
(
reqDTO
.
getAreaCode
()
+
reqDTO
.
getMobile
(),
null
,
null
,
reqDTO
.
getNodeValue
(),
reqDTO
.
getAreaCode
(),
reqDTO
.
getIsOrders
(),
reqDTO
.
getIsTransport
()
,
reqDTO
.
getTransportId
(),
reqDTO
.
getMessageType
(),
MapUtil
.
of
(
"code"
,
code
),
null
,
1
);
}
private
String
createSmsCode
(
String
mobile
,
Integer
scen
e
,
String
ip
)
{
private
String
createSmsCode
(
String
mobile
,
String
nodeValu
e
,
String
ip
)
{
// 校验是否可以发送验证码,不用筛选场景
SmsCodeDO
lastSmsCode
=
smsCodeMapper
.
selectLastByMobile
(
mobile
,
null
,
null
);
if
(
lastSmsCode
!=
null
)
{
if
(
lastSmsCode
.
getTodayIndex
()
>=
smsCodeProperties
.
getSendMaximumQuantityPerDay
())
{
// 超过当天发送的上限。
throw
ServiceExceptionUtil
.
exception
(
SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY
);
}
if
(
System
.
currentTimeMillis
()
-
lastSmsCode
.
getCreateTime
().
getTime
()
<
smsCodeProperties
.
getSendFrequency
().
toMillis
())
{
// 发送过于频繁
throw
ServiceExceptionUtil
.
exception
(
SMS_CODE_SEND_TOO_FAST
);
}
// TODO 芋艿:提升,每个 IP 每天可发送数量
// TODO 芋艿:提升,每个 IP 每小时可发送数量
}
//
if (lastSmsCode != null) {
//
if (lastSmsCode.getTodayIndex() >= smsCodeProperties.getSendMaximumQuantityPerDay()) { // 超过当天发送的上限。
//
throw ServiceExceptionUtil.exception(SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY);
//
}
//
if (System.currentTimeMillis() - lastSmsCode.getCreateTime().getTime()
//
< smsCodeProperties.getSendFrequency().toMillis()) { // 发送过于频繁
//
throw ServiceExceptionUtil.exception(SMS_CODE_SEND_TOO_FAST);
//
}
//
// TODO 芋艿:提升,每个 IP 每天可发送数量
//
// TODO 芋艿:提升,每个 IP 每小时可发送数量
//
}
// 创建验证码记录
String
code
=
String
.
valueOf
(
randomInt
(
smsCodeProperties
.
getBeginCode
(),
smsCodeProperties
.
getEndCode
()
+
1
));
SmsCodeDO
newSmsCode
=
SmsCodeDO
.
builder
().
mobile
(
mobile
).
code
(
code
)
.
scene
(
scen
e
).
todayIndex
(
lastSmsCode
!=
null
?
lastSmsCode
.
getTodayIndex
()
+
1
:
1
)
.
nodeValue
(
nodeValu
e
).
todayIndex
(
lastSmsCode
!=
null
?
lastSmsCode
.
getTodayIndex
()
+
1
:
1
)
.
createIp
(
ip
).
used
(
false
).
build
();
smsCodeMapper
.
insert
(
newSmsCode
);
return
code
;
...
...
@@ -84,20 +81,20 @@ public class SmsCodeServiceImpl implements SmsCodeService {
@Override
public
void
useSmsCode
(
SmsCodeUseReqDTO
reqDTO
)
{
if
(
Objects
.
equals
(
reqDTO
.
getCode
(),
"9999"
))
{
return
;
}
if
(
Objects
.
nonNull
(
businessProperties
)
&&
businessProperties
.
isDebug
())
{
// TODO debug业务模式下不需要生成发送验证码,固定使用9999
if
(
Objects
.
equals
(
reqDTO
.
getCode
(),
"9999"
))
{
return
;
}
else
{
throw
ServiceExceptionUtil
.
exception
(
SMS_CODE_NOT_FOUND
);
}
}
//
if (Objects.equals(reqDTO.getCode(), "9999")) {
//
return;
//
}
//
//
if (Objects.nonNull(businessProperties) && businessProperties.isDebug()) {
//
// TODO debug业务模式下不需要生成发送验证码,固定使用9999
//
if (Objects.equals(reqDTO.getCode(), "9999")) {
//
return;
//
} else {
//
throw ServiceExceptionUtil.exception(SMS_CODE_NOT_FOUND);
//
}
//
}
// 检测验证码是否有效
SmsCodeDO
lastSmsCode
=
this
.
checkSmsCode0
(
reqDTO
.
getMobile
(),
reqDTO
.
getCode
(),
reqDTO
.
get
Scen
e
());
SmsCodeDO
lastSmsCode
=
this
.
checkSmsCode0
(
reqDTO
.
getMobile
(),
reqDTO
.
getCode
(),
reqDTO
.
get
NodeValu
e
());
// 使用验证码
smsCodeMapper
.
updateById
(
SmsCodeDO
.
builder
().
id
(
lastSmsCode
.
getId
())
.
used
(
true
).
usedTime
(
new
Date
()).
usedIp
(
reqDTO
.
getUsedIp
()).
build
());
...
...
@@ -105,12 +102,12 @@ public class SmsCodeServiceImpl implements SmsCodeService {
@Override
public
void
checkSmsCode
(
SmsCodeCheckReqDTO
reqDTO
)
{
checkSmsCode0
(
reqDTO
.
getMobile
(),
reqDTO
.
getCode
(),
reqDTO
.
get
Scen
e
());
checkSmsCode0
(
reqDTO
.
getMobile
(),
reqDTO
.
getCode
(),
reqDTO
.
get
NodeValu
e
());
}
public
SmsCodeDO
checkSmsCode0
(
String
mobile
,
String
code
,
Integer
scen
e
)
{
public
SmsCodeDO
checkSmsCode0
(
String
mobile
,
String
code
,
String
nodeValu
e
)
{
// 校验验证码
SmsCodeDO
lastSmsCode
=
smsCodeMapper
.
selectLastByMobile
(
mobile
,
code
,
scen
e
);
SmsCodeDO
lastSmsCode
=
smsCodeMapper
.
selectLastByMobile
(
mobile
,
code
,
nodeValu
e
);
// 若验证码不存在,抛出异常
if
(
lastSmsCode
==
null
)
{
throw
ServiceExceptionUtil
.
exception
(
SMS_CODE_NOT_FOUND
);
...
...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsLogService.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
service
.
sms
;
import
cn.iocoder.yudao.framework.sms.core.client.impl.sendchamp.SendchampSmsClient
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.log.SmsLogExportReqVO
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.log.SmsLogPageReqVO
;
import
cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsLogDO
;
...
...
@@ -36,6 +37,27 @@ public interface SmsLogService {
Long
createSmsLog
(
String
mobile
,
Long
userId
,
Integer
userType
,
Boolean
isSend
,
SmsTemplateDO
template
,
String
templateContent
,
Map
<
String
,
Object
>
templateParams
,
String
apiTemplateId
,
Long
smsLogId
);
/**
* 创建短信日志
*
* @param mobile 手机号
* @param userId 用户编号
* @param userType 用户类型
* @param isSend 是否发送
* @param template 短信模板
* @param templateContent 短信内容
* @param templateParams 短信参数
* @param apiTemplateId 短信 API 的模板编号
* @param smsLogId 重发短信时的原短信日志id
* @param nodeId 节点id
* @param nodeTemplateSn 节点模板序列号
* @param messageType 发送类型
* @return 发送日志编号
*/
Long
createSmsLogV2
(
String
mobile
,
Long
userId
,
Integer
userType
,
Boolean
isSend
,
SmsTemplateDO
template
,
String
templateContent
,
Map
<
String
,
Object
>
templateParams
,
String
apiTemplateId
,
Long
smsLogId
,
Long
nodeId
,
Integer
nodeTemplateSn
,
Integer
messageType
);
/**
* 更新日志的发送结果
*
...
...
@@ -90,4 +112,11 @@ public interface SmsLogService {
void
updateBatchSmsLog
(
List
<
SmsLogDO
>
resendSmsLogList
);
List
<
SmsLogDO
>
selectReceiveList
();
/**
* 更新sendchamp回调状态
* @param smsReceiveStatus
*/
void
updateSendchampReceive
(
SendchampSmsClient
.
SmsReceiveStatus
smsReceiveStatus
);
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsLogServiceImpl.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
service
.
sms
;
import
cn.iocoder.yudao.framework.common.pojo.CommonResult
;
import
cn.iocoder.yudao.framework.sms.core.client.impl.sendchamp.SendchampSmsClient
;
import
cn.iocoder.yudao.framework.sms.core.enums.ReceiveStatusEnum
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.log.SmsLogExportReqVO
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.log.SmsLogPageReqVO
;
import
cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsLogDO
;
...
...
@@ -55,6 +57,57 @@ public class SmsLogServiceImpl implements SmsLogService {
return
logDO
.
getId
();
}
/**
* 创建短信日志
*
* @param mobile 手机号
* @param userId 用户编号
* @param userType 用户类型
* @param isSend 是否发送
* @param template 短信模板
* @param templateContent 短信内容
* @param templateParams 短信参数
* @param apiTemplateId 短信 API 的模板编号
* @param smsLogId 重发短信时的原短信日志id
* @param nodeId 节点id
* @param nodeTemplateSn 节点模板序列号
* @param messageType 发送类型
* @return 发送日志编号
*/
@Override
public
Long
createSmsLogV2
(
String
mobile
,
Long
userId
,
Integer
userType
,
Boolean
isSend
,
SmsTemplateDO
template
,
String
templateContent
,
Map
<
String
,
Object
>
templateParams
,
String
apiTemplateId
,
Long
smsLogId
,
Long
nodeId
,
Integer
nodeTemplateSn
,
Integer
messageType
)
{
SmsLogDO
.
SmsLogDOBuilder
logBuilder
=
SmsLogDO
.
builder
();
// 根据是否要发送,设置状态
logBuilder
.
sendStatus
(
Objects
.
equals
(
isSend
,
true
)
?
SmsSendStatusEnum
.
INIT
.
getStatus
()
:
SmsSendStatusEnum
.
IGNORE
.
getStatus
());
// 设置手机相关字段
logBuilder
.
mobile
(
mobile
).
userId
(
userId
).
userType
(
userType
);
// 设置模板相关字段
logBuilder
.
templateId
(
template
.
getId
()).
templateCode
(
template
.
getCode
()).
templateType
(
template
.
getType
());
logBuilder
.
templateContent
(
templateContent
).
templateParams
(
templateParams
)
.
apiTemplateId
(
apiTemplateId
);
// 设置渠道相关字段
logBuilder
.
channelId
(
template
.
getChannelId
()).
channelCode
(
template
.
getChannelCode
());
// 设置接收相关字段
logBuilder
.
receiveStatus
(
SmsReceiveStatusEnum
.
INIT
.
getStatus
());
// 重发短信的原短信日志id
logBuilder
.
smsLogId
(
smsLogId
);
// 默认重发次数是0
logBuilder
.
num
(
0
);
// 节点id
logBuilder
.
nodeId
(
nodeId
);
// 节点模板序列号
logBuilder
.
nodeTemplateSn
(
nodeTemplateSn
);
// 默认重发次数是0
logBuilder
.
messageType
(
messageType
);
// 发送类型
SmsLogDO
logDO
=
logBuilder
.
build
();
smsLogMapper
.
insert
(
logDO
);
return
logDO
.
getId
();
}
@Override
public
void
updateSmsSendResult
(
Long
id
,
Integer
sendCode
,
String
sendMsg
,
String
apiSendCode
,
String
apiSendMsg
,
...
...
@@ -100,4 +153,22 @@ public class SmsLogServiceImpl implements SmsLogService {
public
void
updateBatchSmsLog
(
List
<
SmsLogDO
>
resendSmsLogList
)
{
smsLogMapper
.
updateBatch
(
resendSmsLogList
);
}
@Override
public
List
<
SmsLogDO
>
selectReceiveList
()
{
return
smsLogMapper
.
selectReceiveList
();
}
@Override
public
void
updateSendchampReceive
(
SendchampSmsClient
.
SmsReceiveStatus
smsReceiveStatus
)
{
if
(
"delivered"
.
equals
(
smsReceiveStatus
.
getStatus
()))
{
List
<
SmsLogDO
>
smsLogDOS
=
smsLogMapper
.
selectList
(
new
SmsLogExportReqVO
().
setApiSerialNo
(
smsReceiveStatus
.
getReference
()));
if
(
smsLogDOS
!=
null
)
{
SmsLogDO
smsLogDO
=
smsLogDOS
.
get
(
0
);
smsLogDO
.
setReceiveStatus
(
ReceiveStatusEnum
.
Receive_STATUS_10
.
getValue
());
smsLogDO
.
setReceiveTime
(
new
Date
());
smsLogMapper
.
updateById
(
smsLogDO
);
}
}
}
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsNodeService.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
service
.
sms
;
import
java.util.*
;
import
javax.validation.*
;
import
cn.iocoder.yudao.framework.mybatis.core.vo.PageVO
;
import
cn.iocoder.yudao.framework.mybatis.core.service.IService
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.smsNode.*
;
import
cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsNodeDO
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
/**
* 短信节点 Service 接口
*
* @author jayden
*/
public
interface
SmsNodeService
extends
IService
<
SmsNodeDO
>
{
/**
* 创建短信节点
*
* @param createReqVO 创建信息
* @return 编号
*/
Long
createSmsNode
(
@Valid
SmsNodeCreateReqVO
createReqVO
);
/**
* 更新短信节点
*
* @param updateReqVO 更新信息
*/
void
updateSmsNode
(
@Valid
SmsNodeUpdateReqVO
updateReqVO
);
/**
* 删除短信节点
*
* @param id 编号
*/
void
deleteSmsNode
(
Long
id
);
/**
* 获得短信节点
*
* @param id 编号
* @return 短信节点
*/
SmsNodeDO
getSmsNode
(
Long
id
);
/**
* 获得短信节点列表
*
* @param ids 编号
* @return 短信节点列表
*/
List
<
SmsNodeDO
>
getSmsNodeList
(
Collection
<
Long
>
ids
);
/**
* 获得短信节点分页
*
* @param page 分页查询
* @param query 查询
* @return 短信节点分页
*/
PageResult
<
SmsNodeDO
>
getSmsNodePage
(
SmsNodeQueryVO
query
,
PageVO
page
);
/**
* 获得短信节点列表, 用于 Excel 导出
*
* @param query 查询
* @return 短信节点列表
*/
List
<
SmsNodeDO
>
getSmsNodeList
(
SmsNodeQueryVO
query
);
/**
* 构建缓存键
* 根据SmsNodeDO对象的属性生成一个唯一的缓存键
* 这是为了确保每个配置项在缓存中都有一个唯一的标识
*
* @param smsNodeDO SmsNodeDO 对象
* @return 缓存键
*/
String
buildCacheKey
(
SmsNodeDO
smsNodeDO
);
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsNodeServiceImpl.java
0 → 100644
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
service
.
sms
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.mybatis.core.service.AbstractService
;
import
cn.iocoder.yudao.framework.mybatis.core.vo.PageVO
;
import
cn.iocoder.yudao.framework.redis.helper.RedisHelper
;
import
cn.iocoder.yudao.framework.sms.core.client.SmsClient
;
import
cn.iocoder.yudao.framework.sms.core.client.SmsClientFactory
;
import
cn.iocoder.yudao.framework.sms.core.client.dto.SmsLogDTO
;
import
cn.iocoder.yudao.framework.sms.core.enums.ReceiveStatusEnum
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.smsNode.SmsNodeCreateReqVO
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.smsNode.SmsNodeQueryVO
;
import
cn.iocoder.yudao.module.system.controller.admin.sms.vo.smsNode.SmsNodeUpdateReqVO
;
import
cn.iocoder.yudao.module.system.convert.sms.SmsLogConvert
;
import
cn.iocoder.yudao.module.system.convert.sms.SmsNodeConvert
;
import
cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsLogDO
;
import
cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsNodeDO
;
import
cn.iocoder.yudao.module.system.dal.mysql.sms.SmsNodeMapper
;
import
com.alibaba.fastjson.JSON
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.scheduling.annotation.Scheduled
;
import
org.springframework.stereotype.Service
;
import
org.springframework.validation.annotation.Validated
;
import
javax.annotation.PostConstruct
;
import
javax.annotation.Resource
;
import
java.util.Collection
;
import
java.util.List
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
apollo
.
core
.
constants
.
CacheConstants
.
SYSTEM_SMS_NODE_KEY
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
exception
.
util
.
ServiceExceptionUtil
.
exception
;
import
static
cn
.
iocoder
.
yudao
.
module
.
system
.
enums
.
ErrorCodeConstants
.
SMS_NODE_NOT_EXISTS
;
/**
* 短信节点 Service 实现类
*
* @author jayden
*/
@Slf4j
@Service
@Validated
public
class
SmsNodeServiceImpl
extends
AbstractService
<
SmsNodeMapper
,
SmsNodeDO
>
implements
SmsNodeService
{
@Resource
private
SmsNodeMapper
smsNodeMapper
;
@Autowired
private
RedisHelper
redisHelper
;
@Autowired
private
SmsLogService
smsLogService
;
@Autowired
private
SmsClientFactory
smsClientFactory
;
@Autowired
private
SmsSendService
smsSendService
;
/**
* 项目启动时,初始化参数到缓存
*/
@PostConstruct
public
void
init
()
{
loadingConfigCache
();
}
/**
* 加载参数缓存数据
* 该方法从数据库中读取短信节点配置,并将它们缓存到Redis中
* 这样做是为了提高配置数据的读取效率,避免频繁访问数据库
*/
public
void
loadingConfigCache
()
{
try
{
// 从数据库中选择所有短信节点数据对象
List
<
SmsNodeDO
>
smsNodeDOList
=
smsNodeMapper
.
selectList
();
for
(
SmsNodeDO
smsNodeDO
:
smsNodeDOList
)
{
// 构建缓存键
String
key
=
buildCacheKey
(
smsNodeDO
);
// 将对象转换为JSON字符串作为缓存值
String
value
=
JSON
.
toJSONString
(
smsNodeDO
);
// 将键值对存入Redis缓存
redisHelper
.
set
(
key
,
value
);
redisHelper
.
set
(
SYSTEM_SMS_NODE_KEY
+
smsNodeDO
.
getId
(),
value
);
// 记录日志信息
// log.info("Cache key: {}, value: {}", key, value);
}
}
catch
(
Exception
e
)
{
// 记录错误日志信息
log
.
error
(
"Error loading config cache"
,
e
);
}
}
/**
* 构建缓存键
* 根据SmsNodeDO对象的属性生成一个唯一的缓存键
* 这是为了确保每个配置项在缓存中都有一个唯一的标识
*
* @param smsNodeDO SmsNodeDO 对象
* @return 缓存键
*/
@Override
public
String
buildCacheKey
(
SmsNodeDO
smsNodeDO
)
{
// 使用格式化字符串构建缓存键,SYSTEM_SMS_NODE_KEY:短信节点:是否匹配运输方式:运输方式:是否多订单:国家代码:启用状态
return
String
.
format
(
"%s%s:%s:%s:%s:%s:%s"
,
SYSTEM_SMS_NODE_KEY
,
smsNodeDO
.
getNodeValue
(),
smsNodeDO
.
getIsTransport
(),
smsNodeDO
.
getTransportId
(),
smsNodeDO
.
getIsOrders
(),
smsNodeDO
.
getCountryCode
(),
smsNodeDO
.
getStatus
());
}
/**
* 每半小时执行一次
* 短信重发定时任务
*/
@Scheduled
(
cron
=
"0 0/30 * * * ?"
)
public
void
scheduleReceiveRefresh
()
{
try
{
// 获取需要重发短信的日志列表
List
<
SmsLogDO
>
smsLogs
=
smsLogService
.
selectReceiveList
();
if
(
smsLogs
!=
null
)
{
for
(
SmsLogDO
smsLog
:
smsLogs
)
{
try
{
processSmsLog
(
smsLog
);
}
catch
(
Exception
e
)
{
log
.
error
(
"Error processing sms log: {}"
,
smsLog
,
e
);
}
}
// 批量更新短信日志
smsLogService
.
updateBatchSmsLog
(
smsLogs
);
}
}
catch
(
Exception
e
)
{
log
.
error
(
"Error in scheduleReceiveRefresh"
,
e
);
}
}
/**
* 处理短信日志
*
* @param smsLog 短信日志对象
*/
private
void
processSmsLog
(
SmsLogDO
smsLog
)
{
// 根据渠道ID获取短信客户端
SmsClient
smsClient
=
smsClientFactory
.
getSmsClient
(
smsLog
.
getChannelId
());
// 获取短信接收状态
SmsLogDTO
receiveStatus
=
smsClient
.
getReceiveStatus
(
SmsLogConvert
.
INSTANCE
.
toDto
(
smsLog
));
smsLog
.
setReceiveStatus
(
receiveStatus
.
getReceiveStatus
());
// 接收失败,则重发
if
(
ReceiveStatusEnum
.
Receive_STATUS_20
.
getValue
()
==
receiveStatus
.
getReceiveStatus
())
{
smsLog
.
setReceiveTime
(
receiveStatus
.
getReceiveTime
());
smsLog
.
setNum
(
1
);
// 从Redis中获取短信节点信息
String
node
=
redisHelper
.
get
(
SYSTEM_SMS_NODE_KEY
+
smsLog
.
getNodeId
());
if
(
node
==
null
)
{
return
;
}
// 解析短信节点信息
SmsNodeDO
smsNodeDO
=
JSON
.
parseObject
(
node
,
SmsNodeDO
.
class
);
// 调用短信发送服务重新发送短信
smsSendService
.
sendSingleSmsV2
(
smsLog
.
getMobile
(),
smsLog
.
getUserId
(),
smsLog
.
getUserType
(),
smsNodeDO
.
getNodeValue
(),
smsNodeDO
.
getCountryCode
(),
smsNodeDO
.
getIsOrders
(),
smsNodeDO
.
getIsTransport
(),
smsNodeDO
.
getTransportId
(),
smsLog
.
getMessageType
(),
smsLog
.
getTemplateParams
(),
smsLog
.
getId
(),
smsLog
.
getNodeTemplateSn
()
+
1
);
}
}
@Override
public
Long
createSmsNode
(
SmsNodeCreateReqVO
createReqVO
)
{
// 插入
SmsNodeDO
smsNode
=
SmsNodeConvert
.
INSTANCE
.
convert
(
createReqVO
);
smsNodeMapper
.
insert
(
smsNode
);
// 设置新的缓存
redisHelper
.
set
(
buildCacheKey
(
smsNode
),
JSON
.
toJSONString
(
smsNode
));
redisHelper
.
set
(
SYSTEM_SMS_NODE_KEY
+
smsNode
.
getId
(),
JSON
.
toJSONString
(
smsNode
));
// 返回
return
smsNode
.
getId
();
}
@Override
public
void
updateSmsNode
(
SmsNodeUpdateReqVO
updateReqVO
)
{
// 校验存在
SmsNodeDO
smsNodeDO
=
this
.
validateSmsNodeExists
(
updateReqVO
.
getId
());
// 更新
SmsNodeDO
updateObj
=
SmsNodeConvert
.
INSTANCE
.
convert
(
updateReqVO
);
smsNodeMapper
.
updateById
(
updateObj
);
// 删除旧的缓存
redisHelper
.
delete
(
buildCacheKey
(
smsNodeDO
));
// 设置新的缓存
redisHelper
.
set
(
buildCacheKey
(
updateObj
),
JSON
.
toJSONString
(
updateObj
));
redisHelper
.
set
(
SYSTEM_SMS_NODE_KEY
+
updateObj
.
getId
(),
JSON
.
toJSONString
(
updateObj
));
}
@Override
public
void
deleteSmsNode
(
Long
id
)
{
// 校验存在
SmsNodeDO
smsNodeDO
=
this
.
validateSmsNodeExists
(
id
);
// 删除
smsNodeMapper
.
deleteById
(
id
);
// 删除缓存中的短信节点信息
redisHelper
.
delete
(
buildCacheKey
(
smsNodeDO
));
redisHelper
.
delete
(
SYSTEM_SMS_NODE_KEY
+
id
);
}
private
SmsNodeDO
validateSmsNodeExists
(
Long
id
)
{
SmsNodeDO
smsNodeDO
=
smsNodeMapper
.
selectById
(
id
);
if
(
smsNodeDO
==
null
)
{
throw
exception
(
SMS_NODE_NOT_EXISTS
);
}
return
smsNodeDO
;
}
@Override
public
SmsNodeDO
getSmsNode
(
Long
id
)
{
return
smsNodeMapper
.
selectById
(
id
);
}
@Override
public
List
<
SmsNodeDO
>
getSmsNodeList
(
Collection
<
Long
>
ids
)
{
return
smsNodeMapper
.
selectBatchIds
(
ids
);
}
@Override
public
PageResult
<
SmsNodeDO
>
getSmsNodePage
(
SmsNodeQueryVO
query
,
PageVO
page
)
{
return
smsNodeMapper
.
selectPage
(
page
,
query
);
}
@Override
public
List
<
SmsNodeDO
>
getSmsNodeList
(
SmsNodeQueryVO
query
)
{
return
smsNodeMapper
.
selectList
(
query
);
}
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsSendService.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
service
.
sms
;
import
cn.iocoder.yudao.framework.common.validation.Mobile
;
import
cn.iocoder.yudao.module.system.mq.message.sms.SmsSendMessage
;
import
cn.iocoder.yudao.module.system.mq.message.sms.SmsSendMessageV2
;
import
javax.validation.constraints.NotEmpty
;
import
javax.validation.constraints.NotNull
;
import
java.util.Collection
;
import
java.util.List
;
import
java.util.Map
;
...
...
@@ -15,7 +19,7 @@ public interface SmsSendService {
/**
* 发送单条短信给管理后台的用户
*
*
<p>
* 在 mobile 为空时,使用 userId 加载对应管理员的手机号
*
* @param mobile 手机号
...
...
@@ -27,10 +31,28 @@ public interface SmsSendService {
Long
sendSingleSmsToAdmin
(
String
mobile
,
Long
userId
,
String
templateCode
,
Map
<
String
,
Object
>
templateParams
,
String
areaCode
);
/**
* 发送短信服务方法
* 该方法负责根据提供的参数构建短信发送请求,并处理发送逻辑
*
* @param mobile 手机号码
* @param userId 用户ID
* @param nodeValue 节点值,用于确定短信内容
* @param areaCode 区域代码,用于确定短信发送的国家或地区
* @param isOrders 订单相关标志
* @param isTransport 物流相关标志
* @param transportId 物流
* @param messageType 发送类型
* @param templateParams 短信模板参数
*/
Long
sendSingleSmsToAdminV2
(
@Mobile
@NotEmpty
(
message
=
"手机号不能为空"
)
String
mobile
,
Long
userId
,
@NotNull
(
message
=
"业务节点不能为空"
)
String
nodeValue
,
@NotNull
(
message
=
"国家区号不能为空"
)
String
areaCode
,
@NotNull
(
message
=
"是否多订单不能为空"
)
Integer
isOrders
,
@NotNull
(
message
=
"是否匹配运输方式不能为空"
)
Integer
isTransport
,
@NotNull
(
message
=
"运输方式不能空"
)
Integer
transportId
,
@NotNull
(
message
=
"发送类型不能为空"
)
Integer
messageType
,
Map
<
String
,
Object
>
templateParams
);
/**
* 发送单条短信给用户 APP 的用户
*
*
<p>
* 在 mobile 为空时,使用 userId 加载对应会员的手机号
*
* @param mobile 手机号
...
...
@@ -42,6 +64,25 @@ public interface SmsSendService {
Long
sendSingleSmsToMember
(
String
mobile
,
Long
userId
,
String
templateCode
,
Map
<
String
,
Object
>
templateParams
,
String
areaCode
);
/**
* 发送单条短信给用户 APP 的用户
*
* @param mobile 手机号码
* @param userId 用户ID
* @param nodeValue 节点值,用于确定短信内容
* @param areaCode 区域代码,用于确定短信发送的国家或地区
* @param isOrders 订单相关标志
* @param isTransport 物流相关标志
* @param transportId 物流
* @param messageType 发送类型
* @param templateParams 短信模板参数
*/
Long
sendSingleSmsToMemberV2
(
@Mobile
@NotEmpty
(
message
=
"手机号不能为空"
)
String
mobile
,
Long
userId
,
@NotNull
(
message
=
"业务节点不能为空"
)
String
nodeValue
,
@NotNull
(
message
=
"国家区号不能为空"
)
String
areaCode
,
@NotNull
(
message
=
"是否多订单不能为空"
)
Integer
isOrders
,
@NotNull
(
message
=
"是否匹配运输方式不能为空"
)
Integer
isTransport
,
@NotNull
(
message
=
"运输方式不能空"
)
Integer
transportId
,
@NotNull
(
message
=
"发送类型不能为空"
)
Integer
messageType
,
Map
<
String
,
Object
>
templateParams
);
/**
* 发送单条短信给用户
*
...
...
@@ -56,7 +97,26 @@ public interface SmsSendService {
String
templateCode
,
Map
<
String
,
Object
>
templateParams
);
/**
* 发送短信服务方法
* 该方法负责根据提供的参数构建短信发送请求,并处理发送逻辑
*
* @param mobile 手机号码
* @param userId 用户ID
* @param userType 用户类型
* @param nodeValue 节点值,用于确定短信内容
* @param areaCode 区域代码,用于确定短信发送的国家或地区
* @param isOrders 订单相关标志
* @param isTransport 物流相关标志
* @param transportId 物流
* @param messageType 发送类型
* @param templateParams 短信模板参数
* @param smsLogId 重发短信时的原短信日志id
* @param nodeTemplateSn 模板序号
*/
Long
sendSingleSmsV2
(
@Mobile
@NotEmpty
(
message
=
"手机号不能为空"
)
String
mobile
,
Long
userId
,
Integer
userType
,
@NotNull
(
message
=
"业务节点不能为空"
)
String
nodeValue
,
@NotNull
(
message
=
"国家区号不能为空"
)
String
areaCode
,
@NotNull
(
message
=
"是否多订单不能为空"
)
Integer
isOrders
,
@NotNull
(
message
=
"是否匹配运输方式不能为空"
)
Integer
isTransport
,
@NotNull
(
message
=
"运输方式不能空"
)
Integer
transportId
,
@NotNull
(
message
=
"发送类型不能为空"
)
Integer
messageType
,
Map
<
String
,
Object
>
templateParams
,
Long
smsLogId
,
Integer
nodeTemplateSn
);
void
resendSingleSmsBySmsLogIds
(
Collection
<
Long
>
smsLogIds
);
...
...
@@ -73,6 +133,14 @@ public interface SmsSendService {
*/
void
doSendSms
(
SmsSendMessage
message
);
/**
* 执行真正的短信发送
* 注意,该方法仅仅提供给 MQ Consumer 使用
*
* @param message 短信
*/
void
doSendSmsV2
(
SmsSendMessageV2
message
);
/**
* 接收短信的接收结果
*
...
...
@@ -82,4 +150,5 @@ public interface SmsSendService {
*/
void
receiveSmsStatus
(
String
channelCode
,
String
text
)
throws
Throwable
;
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceImpl.java
View file @
56d736c3
...
...
@@ -6,22 +6,31 @@ import cn.hutool.core.util.StrUtil;
import
cn.iocoder.yudao.framework.common.util.json.core.KeyValue
;
import
cn.iocoder.yudao.framework.common.util.spring.enums.CommonStatusEnum
;
import
cn.iocoder.yudao.framework.common.util.spring.enums.UserTypeEnum
;
import
cn.iocoder.yudao.framework.redis.helper.RedisHelper
;
import
cn.iocoder.yudao.framework.sms.core.client.SmsClient
;
import
cn.iocoder.yudao.framework.sms.core.client.SmsClientFactory
;
import
cn.iocoder.yudao.framework.sms.core.client.SmsCommonResult
;
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.SmsTemplateDTO
;
import
cn.iocoder.yudao.framework.web.config.BusinessProperties
;
import
cn.iocoder.yudao.module.member.api.user.MemberUserApi
;
import
cn.iocoder.yudao.module.member.api.user.dto.UserRespDTO
;
import
cn.iocoder.yudao.module.system.convert.sms.SmsTemplateConvert
;
import
cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsChannelDO
;
import
cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsLogDO
;
import
cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsNodeDO
;
import
cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsTemplateDO
;
import
cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsCountryCodeEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.SystemStatusEnum
;
import
cn.iocoder.yudao.module.system.mq.message.sms.SmsSendMessage
;
import
cn.iocoder.yudao.module.system.mq.message.sms.SmsSendMessageV2
;
import
cn.iocoder.yudao.module.system.mq.producer.sms.SmsProducer
;
import
cn.iocoder.yudao.module.system.service.user.AdminUserService
;
import
com.alibaba.fastjson.JSON
;
import
com.google.common.annotations.VisibleForTesting
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
org.springframework.util.Assert
;
...
...
@@ -62,6 +71,12 @@ public class SmsSendServiceImpl implements SmsSendService {
@Resource
private
BusinessProperties
businessProperties
;
@Autowired
private
SmsNodeService
smsNodeService
;
@Autowired
private
RedisHelper
redisHelper
;
@Override
public
Long
sendSingleSmsToAdmin
(
String
mobile
,
Long
userId
,
String
templateCode
,
Map
<
String
,
Object
>
templateParams
,
String
areaCode
)
{
// 如果 mobile 为空,则加载用户编号对应的手机号
...
...
@@ -76,6 +91,21 @@ public class SmsSendServiceImpl implements SmsSendService {
return
this
.
sendSingleSms
(
areaCode
+
mobile
,
userId
,
UserTypeEnum
.
ADMIN
.
getValue
(),
templateCode
,
templateParams
);
}
@Override
public
Long
sendSingleSmsToAdminV2
(
String
mobile
,
Long
userId
,
String
nodeValue
,
String
areaCode
,
Integer
isOrders
,
Integer
isTransport
,
Integer
transportId
,
Integer
messageType
,
Map
<
String
,
Object
>
templateParams
)
{
// 如果 mobile 为空,则加载用户编号对应的手机号
if
(
StrUtil
.
isEmpty
(
mobile
))
{
AdminUserDO
user
=
adminUserService
.
getUser
(
userId
);
if
(
user
!=
null
)
{
mobile
=
user
.
getMobile
();
areaCode
=
"86"
;
//TODO 待管理端用户信息存入国家区号
}
}
// 执行发送
return
this
.
sendSingleSmsV2
(
areaCode
+
mobile
,
userId
,
UserTypeEnum
.
ADMIN
.
getValue
(),
nodeValue
,
areaCode
,
isOrders
,
isTransport
,
transportId
,
messageType
,
templateParams
,
null
,
1
);
}
@Override
public
Long
sendSingleSmsToMember
(
String
mobile
,
Long
userId
,
String
templateCode
,
Map
<
String
,
Object
>
templateParams
,
String
areaCode
)
{
// 如果 mobile 为空,则加载用户编号对应的手机号
...
...
@@ -90,6 +120,21 @@ public class SmsSendServiceImpl implements SmsSendService {
return
this
.
sendSingleSms
(
areaCode
+
mobile
,
userId
,
UserTypeEnum
.
MEMBER
.
getValue
(),
templateCode
,
templateParams
);
}
@Override
public
Long
sendSingleSmsToMemberV2
(
String
mobile
,
Long
userId
,
String
nodeValue
,
String
areaCode
,
Integer
isOrders
,
Integer
isTransport
,
Integer
transportId
,
Integer
messageType
,
Map
<
String
,
Object
>
templateParams
)
{
// 如果 mobile 为空,则加载用户编号对应的手机号
if
(
StrUtil
.
isEmpty
(
mobile
))
{
UserRespDTO
user
=
memberUserApi
.
getUser
(
userId
);
if
(
user
!=
null
)
{
mobile
=
user
.
getMobile
();
areaCode
=
user
.
getAreaCode
();
//TODO 待管理端用户信息存入国家区号
}
}
// 执行发送
return
this
.
sendSingleSmsV2
(
areaCode
+
mobile
,
userId
,
UserTypeEnum
.
MEMBER
.
getValue
(),
nodeValue
,
areaCode
,
isOrders
,
isTransport
,
transportId
,
messageType
,
templateParams
,
null
,
1
);
}
@Override
public
Long
sendSingleSms
(
String
mobile
,
Long
userId
,
Integer
userType
,
String
templateCode
,
Map
<
String
,
Object
>
templateParams
)
{
...
...
@@ -224,6 +269,21 @@ public class SmsSendServiceImpl implements SmsSendService {
sendResult
.
getData
()
!=
null
?
sendResult
.
getData
().
getSerialNo
()
:
null
);
}
@Override
public
void
doSendSmsV2
(
SmsSendMessageV2
message
)
{
SmsTemplateDTO
smsTemplateDTO
=
message
.
getSmsTemplateDTO
();
// 获得渠道对应的 SmsClient 客户端
SmsClient
smsClient
=
smsClientFactory
.
getSmsClient
(
smsTemplateDTO
.
getChannelId
());
Assert
.
notNull
(
smsClient
,
String
.
format
(
"短信客户端(%d) 不存在"
,
smsTemplateDTO
.
getChannelId
()));
// 发送短信
SmsCommonResult
<
SmsSendRespDTO
>
sendResult
=
smsClient
.
sendSmsV2
(
message
.
getLogId
(),
message
.
getMobile
(),
smsTemplateDTO
,
message
.
getTemplateParams
());
smsLogService
.
updateSmsSendResult
(
message
.
getLogId
(),
sendResult
.
getCode
(),
sendResult
.
getMsg
(),
sendResult
.
getApiCode
(),
sendResult
.
getApiMsg
(),
sendResult
.
getApiRequestId
(),
sendResult
.
getData
()
!=
null
?
sendResult
.
getData
().
getSerialNo
()
:
null
);
}
@Override
public
void
receiveSmsStatus
(
String
channelCode
,
String
text
)
throws
Throwable
{
// 获得渠道对应的 SmsClient 客户端
...
...
@@ -239,4 +299,126 @@ public class SmsSendServiceImpl implements SmsSendService {
result
.
getSuccess
(),
result
.
getReceiveTime
(),
result
.
getErrorCode
(),
result
.
getErrorCode
()));
}
/**
* 发送短信服务方法V2版本
* 该方法负责根据提供的参数构建短信发送请求,并处理发送逻辑
*
* @param mobile 手机号码
* @param userId 用户ID
* @param userType 用户类型
* @param nodeValue 节点值,用于确定短信内容
* @param areaCode 区域代码,用于确定短信发送的国家或地区
* @param isOrders 订单相关标志
* @param isTransport 物流相关标志
* @param transportId 物流
* @param messageType 发送类型
* @param templateParams 短信模板参数
* @param smsLogId 重发短信时的原短信日志id
* @param nodeTemplateSn 模板序号
*/
@Override
public
Long
sendSingleSmsV2
(
String
mobile
,
Long
userId
,
Integer
userType
,
String
nodeValue
,
String
areaCode
,
Integer
isOrders
,
Integer
isTransport
,
Integer
transportId
,
Integer
messageType
,
Map
<
String
,
Object
>
templateParams
,
Long
smsLogId
,
Integer
nodeTemplateSn
)
{
// 创建SmsNodeDO对象并设置相关属性
SmsNodeDO
smsNodeDO
=
new
SmsNodeDO
()
.
setNodeValue
(
nodeValue
)
.
setIsTransport
(
isTransport
)
.
setTransportId
(
transportId
)
.
setIsOrders
(
isOrders
)
.
setCountryCode
(
areaCode
)
.
setStatus
(
SystemStatusEnum
.
SYSTEM_STATUS_0
.
getValue
());
// 构建缓存键,用于查询短信节点缓存
String
cacheKey
=
smsNodeService
.
buildCacheKey
(
smsNodeDO
);
String
smsNodeCache
=
redisHelper
.
get
(
cacheKey
);
// 第一次找不到,则在全部国家里面找
if
(
smsNodeCache
==
null
)
{
smsNodeDO
.
setCountryCode
(
SmsCountryCodeEnum
.
SMS_COUNTRY_CODE_0
.
getValue
());
cacheKey
=
smsNodeService
.
buildCacheKey
(
smsNodeDO
);
smsNodeCache
=
redisHelper
.
get
(
cacheKey
);
// 第二次找不到,则在其他国家里面找
if
(
smsNodeCache
==
null
)
{
smsNodeDO
.
setCountryCode
(
SmsCountryCodeEnum
.
SMS_COUNTRY_CODE_1
.
getValue
());
cacheKey
=
smsNodeService
.
buildCacheKey
(
smsNodeDO
);
smsNodeCache
=
redisHelper
.
get
(
cacheKey
);
}
}
// 如果 still null, throw exception
if
(
smsNodeCache
==
null
)
{
throw
exception
(
SMS_SEND_TEMPLATE_NOT_EXISTS
);
}
// 解析缓存获取短信节点信息
SmsNodeDO
smsNode
=
JSON
.
parseObject
(
smsNodeCache
,
SmsNodeDO
.
class
);
String
smsTemplateDO
=
null
;
// 从缓存中获取短信模板信息
for
(
int
i
=
nodeTemplateSn
;
i
<=
4
;
i
++)
{
nodeTemplateSn
=
i
;
Long
templateId
=
getTemplateIdBySn
(
smsNode
,
nodeTemplateSn
);
if
(
templateId
!=
null
)
{
String
key
=
smsTemplateService
.
buildCacheKey
(
new
SmsTemplateDO
().
setId
(
templateId
).
setMessageType
(
messageType
).
setStatus
(
SystemStatusEnum
.
SYSTEM_STATUS_0
.
getValue
()));
String
smsTemplate
=
redisHelper
.
get
(
key
);
if
(
smsTemplate
!=
null
)
{
smsTemplateDO
=
smsTemplate
;
break
;
}
}
}
if
(
smsTemplateDO
==
null
)
{
// throw exception(SMS_SEND_TEMPLATE_NOT_EXISTS);
return
null
;
}
// 解析缓存获取短信模板信息
SmsTemplateDO
smsTemplate
=
JSON
.
parseObject
(
smsTemplateDO
,
SmsTemplateDO
.
class
);
// 格式化短信模板内容
String
content
=
smsTemplateService
.
formatSmsTemplateContent
(
smsTemplate
.
getContent
(),
templateParams
);
// 创建短信发送日志
Long
sendLogId
=
smsLogService
.
createSmsLogV2
(
mobile
,
userId
,
userType
,
true
,
smsTemplate
,
content
,
templateParams
,
smsTemplate
.
getApiTemplateId
(),
smsLogId
,
smsNode
.
getId
(),
nodeTemplateSn
,
messageType
);
// 构建有序的模板参数。为什么放在这个位置,是提前保证模板参数的正确性,而不是到了插入发送日志
List
<
KeyValue
<
String
,
Object
>>
newTemplateParams
=
this
.
buildTemplateParams
(
smsTemplate
,
templateParams
);
// 创建SmsSendMessageV2对象并设置相关属性
SmsSendMessageV2
smsSendMessage
=
new
SmsSendMessageV2
()
.
setLogId
(
sendLogId
)
.
setMobile
(
mobile
)
.
setSmsTemplateDTO
(
SmsTemplateConvert
.
INSTANCE
.
toDto
(
smsTemplate
))
.
setTemplateParams
(
newTemplateParams
);
smsProducer
.
sendSmsSendMessageV2
(
smsSendMessage
);
// 根据debug配置决定是否发送短信
// if (Objects.isNull(businessProperties) || !businessProperties.isDebug()) {
// smsProducer.sendSmsSendMessageV2(smsSendMessage);
// }
return
sendLogId
;
}
/**
* 根据节点模板序号获取模板ID
*
* @param smsNode 短信节点信息
* @param sn 模板序号
* @return 对应的模板ID,如果找不到则返回null
*/
private
Long
getTemplateIdBySn
(
SmsNodeDO
smsNode
,
int
sn
)
{
switch
(
sn
)
{
case
1
:
return
smsNode
.
getTemplateIdOne
();
case
2
:
return
smsNode
.
getTemplateIdTwo
();
case
3
:
return
smsNode
.
getTemplateIdThree
();
case
4
:
return
smsNode
.
getTemplateIdFour
();
default
:
return
null
;
}
}
}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateService.java
View file @
56d736c3
...
...
@@ -25,6 +25,16 @@ public interface SmsTemplateService {
*/
void
initLocalCache
();
/**
* 构建缓存键
* 根据smsTemplateDO对象的属性生成一个唯一的缓存键
* 这是为了确保每个配置项在缓存中都有一个唯一的标识
*
* @param smsTemplateDO smsTemplateDO 对象
* @return 缓存键
*/
public
String
buildCacheKey
(
SmsTemplateDO
smsTemplateDO
);
/**
* 获得短信模板,从缓存中
*
...
...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImpl.java
View file @
56d736c3
package
cn
.
iocoder
.
yudao
.
module
.
system
.
service
.
sms
;
import
cn.hutool.core.collection.CollUtil
;
import
cn.hutool.core.collection.CollectionUtil
;
import
cn.hutool.core.util.ReUtil
;
import
cn.hutool.core.util.StrUtil
;
import
cn.iocoder.yudao.framework.
common.util.spring.enums.CommonStatusEnum
;
import
cn.iocoder.yudao.framework.
apollo.core.constants.CacheConstants
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.common.util.collection.CollectionUtils
;
import
cn.iocoder.yudao.framework.common.util.spring.enums.CommonStatusEnum
;
import
cn.iocoder.yudao.framework.redis.helper.RedisHelper
;
import
cn.iocoder.yudao.framework.sms.core.client.SmsClient
;
import
cn.iocoder.yudao.framework.sms.core.client.SmsClientFactory
;
import
cn.iocoder.yudao.framework.sms.core.client.SmsCommonResult
;
...
...
@@ -20,9 +20,10 @@ import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsChannelDO;
import
cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsTemplateDO
;
import
cn.iocoder.yudao.module.system.dal.mysql.sms.SmsTemplateMapper
;
import
cn.iocoder.yudao.module.system.mq.producer.sms.SmsProducer
;
import
com.alibaba.fastjson.JSON
;
import
com.google.common.annotations.VisibleForTesting
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.
scheduling.annotation.Schedul
ed
;
import
org.springframework.
beans.factory.annotation.Autowir
ed
;
import
org.springframework.stereotype.Service
;
import
org.springframework.util.Assert
;
...
...
@@ -67,10 +68,13 @@ public class SmsTemplateServiceImpl implements SmsTemplateService {
@Resource
private
SmsProducer
smsProducer
;
@Autowired
private
RedisHelper
redisHelper
;
/**
* 短信模板缓存
* key:短信模板编码 {@link SmsTemplateDO#getCode()}
*
*
<p>
* 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
*/
private
volatile
Map
<
String
,
SmsTemplateDO
>
smsTemplateCache
;
...
...
@@ -87,11 +91,32 @@ public class SmsTemplateServiceImpl implements SmsTemplateService {
if
(
CollUtil
.
isEmpty
(
smsTemplateList
))
{
return
;
}
for
(
SmsTemplateDO
smsTemplateDO
:
smsTemplateList
)
{
// 构建缓存键
String
key
=
buildCacheKey
(
smsTemplateDO
);
// 将对象转换为JSON字符串作为缓存值
String
value
=
JSON
.
toJSONString
(
smsTemplateDO
);
// 将键值对存入Redis缓存
redisHelper
.
set
(
key
,
value
);
}
// 写入缓存
smsTemplateCache
=
CollectionUtils
.
convertMap
(
smsTemplateList
,
SmsTemplateDO:
:
getCode
);
maxUpdateTime
=
CollectionUtils
.
getMaxValue
(
smsTemplateList
,
SmsTemplateDO:
:
getUpdateTime
);
log
.
info
(
"[initLocalCache][初始化 SmsTemplate 数量为 {}]"
,
smsTemplateList
.
size
());
// smsTemplateCache = CollectionUtils.convertMap(smsTemplateList, SmsTemplateDO::getCode);
// maxUpdateTime = CollectionUtils.getMaxValue(smsTemplateList, SmsTemplateDO::getUpdateTime);
// log.info("[initLocalCache][初始化 SmsTemplate 数量为 {}]", smsTemplateList.size());
}
/**
* 构建缓存键
* 根据smsTemplateDO对象的属性生成一个唯一的缓存键
* 这是为了确保每个配置项在缓存中都有一个唯一的标识
*
* @param smsTemplateDO smsTemplateDO 对象
* @return 缓存键
*/
@Override
public
String
buildCacheKey
(
SmsTemplateDO
smsTemplateDO
)
{
// 使用格式化字符串构建缓存键,SYSTEM_SMS_TEMPLATE_KEY:id:发送类型:启用状态
return
String
.
format
(
"%s%s:%s:%s"
,
CacheConstants
.
SYSTEM_SMS_TEMPLATE_KEY
,
smsTemplateDO
.
getId
(),
smsTemplateDO
.
getMessageType
(),
smsTemplateDO
.
getStatus
());
}
/**
...
...
@@ -115,7 +140,7 @@ public class SmsTemplateServiceImpl implements SmsTemplateService {
return
smsTemplateMapper
.
selectList
();
}
@Scheduled
(
fixedDelay
=
SCHEDULER_PERIOD
,
initialDelay
=
SCHEDULER_PERIOD
)
//
@Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
public
void
schedulePeriodicRefresh
()
{
initLocalCache
();
}
...
...
@@ -149,20 +174,22 @@ public class SmsTemplateServiceImpl implements SmsTemplateService {
// 校验短信模板
checkApiTemplate
(
createReqVO
.
getChannelId
(),
createReqVO
.
getApiTemplateId
());
// 英文短信模板校验
checkApiTemplate
(
createReqVO
.
getChannelId
(),
createReqVO
.
getApiTemplateIdEn
());
//
checkApiTemplate(createReqVO.getChannelId(), createReqVO.getApiTemplateIdEn());
// 插入
SmsTemplateDO
template
=
SmsTemplateConvert
.
INSTANCE
.
convert
(
createReqVO
);
List
<
String
>
paramsZh
=
parseTemplateContentParams
(
createReqVO
.
getContent
());
List
<
String
>
paramsEn
=
parseTemplateContentParams
(
createReqVO
.
getContentEn
());
List
<
String
>
params
=
(
List
<
String
>)
CollectionUtil
.
union
(
paramsZh
,
paramsEn
);
//
List<String> paramsEn = parseTemplateContentParams(createReqVO.getContentEn());
//
List<String> params = (List<String>) CollectionUtil.union(paramsZh, paramsEn);
template
.
setParams
(
params
);
template
.
setParams
(
params
Zh
);
template
.
setChannelCode
(
channelDO
.
getCode
());
smsTemplateMapper
.
insert
(
template
);
// 发送刷新消息
smsProducer
.
sendSmsTemplateRefreshMessage
();
// smsProducer.sendSmsTemplateRefreshMessage();
// 设置新的缓存
redisHelper
.
set
(
buildCacheKey
(
template
),
JSON
.
toJSONString
(
template
));
// 返回
return
template
.
getId
();
}
...
...
@@ -170,7 +197,7 @@ public class SmsTemplateServiceImpl implements SmsTemplateService {
@Override
public
void
updateSmsTemplate
(
SmsTemplateUpdateReqVO
updateReqVO
)
{
// 校验存在
this
.
validateSmsTemplateExists
(
updateReqVO
.
getId
());
SmsTemplateDO
smsTemplateDO
=
this
.
validateSmsTemplateExists
(
updateReqVO
.
getId
());
// 校验短信渠道
SmsChannelDO
channelDO
=
checkSmsChannel
(
updateReqVO
.
getChannelId
());
// 校验短信编码是否重复
...
...
@@ -181,29 +208,37 @@ public class SmsTemplateServiceImpl implements SmsTemplateService {
// 更新
SmsTemplateDO
updateObj
=
SmsTemplateConvert
.
INSTANCE
.
convert
(
updateReqVO
);
List
<
String
>
paramsZh
=
parseTemplateContentParams
(
updateObj
.
getContent
());
List
<
String
>
paramsEn
=
parseTemplateContentParams
(
updateObj
.
getContentEn
());
List
<
String
>
params
=
(
List
<
String
>)
CollectionUtil
.
union
(
paramsZh
,
paramsEn
);
updateObj
.
setParams
(
params
);
//
List<String> paramsEn = parseTemplateContentParams(updateObj.getContentEn());
//
List<String> params = (List<String>) CollectionUtil.union(paramsZh, paramsEn);
updateObj
.
setParams
(
params
Zh
);
updateObj
.
setChannelCode
(
channelDO
.
getCode
());
smsTemplateMapper
.
updateById
(
updateObj
);
// 发送刷新消息
smsProducer
.
sendSmsTemplateRefreshMessage
();
// smsProducer.sendSmsTemplateRefreshMessage();
// 删除旧的缓存
redisHelper
.
delete
(
buildCacheKey
(
smsTemplateDO
));
// 设置新的缓存
redisHelper
.
set
(
buildCacheKey
(
updateObj
),
JSON
.
toJSONString
(
updateObj
));
}
@Override
public
void
deleteSmsTemplate
(
Long
id
)
{
// 校验存在
this
.
validateSmsTemplateExists
(
id
);
SmsTemplateDO
smsTemplateDO
=
this
.
validateSmsTemplateExists
(
id
);
// 更新
smsTemplateMapper
.
deleteById
(
id
);
// 发送刷新消息
smsProducer
.
sendSmsTemplateRefreshMessage
();
// smsProducer.sendSmsTemplateRefreshMessage();
// 删除缓存中的短信节点信息
redisHelper
.
delete
(
buildCacheKey
(
smsTemplateDO
));
}
private
void
validateSmsTemplateExists
(
Long
id
)
{
if
(
smsTemplateMapper
.
selectById
(
id
)
==
null
)
{
private
SmsTemplateDO
validateSmsTemplateExists
(
Long
id
)
{
SmsTemplateDO
SmsTemplateDO
=
smsTemplateMapper
.
selectById
(
id
);
if
(
SmsTemplateDO
==
null
)
{
throw
exception
(
SMS_TEMPLATE_NOT_EXISTS
);
}
return
SmsTemplateDO
;
}
@Override
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment