Merge branch 'refs/heads/zt-test' into test
# Conflicts: # zt-framework/zt-common/src/main/java/com/zt/plat/framework/common/biz/system/permission/PermissionCommonApi.java # zt-framework/zt-spring-boot-starter-biz-tenant/src/main/java/com/zt/plat/framework/tenant/core/context/DeptContextHolder.java # zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/permission/PermissionServiceImpl.java
This commit is contained in:
67
deployment-databus.yaml
Normal file
67
deployment-databus.yaml
Normal file
@@ -0,0 +1,67 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
namespace: ns-d6a0e78ebd674c279614498e4c57b133
|
||||
name: zt-module-databus
|
||||
labels:
|
||||
app: zt-module-databus
|
||||
annotations:
|
||||
version: "VERSION_PLACEHOLDER"
|
||||
description: DESC_PLACEHOLDER
|
||||
rollout.kubernetes.io/change-cause: "DESC_PLACEHOLDER:VERSION_PLACEHOLDER"
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: zt-module-databus
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: zt-module-databus
|
||||
spec:
|
||||
dnsPolicy: None
|
||||
dnsConfig:
|
||||
nameservers:
|
||||
- "172.16.36.16"
|
||||
- "172.16.36.220"
|
||||
containers:
|
||||
- name: zt-module-databus
|
||||
image: 172.16.46.66:10043/zt/zt-module-databus:VERSION_PLACEHOLDER
|
||||
imagePullPolicy: Always
|
||||
env:
|
||||
- name: TZ
|
||||
value: Asia/Shanghai
|
||||
lifecycle:
|
||||
preStop:
|
||||
exec:
|
||||
command:
|
||||
- "/bin/sh"
|
||||
- "-c"
|
||||
- "sleep 35"
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health
|
||||
port: 48108
|
||||
initialDelaySeconds: 100
|
||||
periodSeconds: 5
|
||||
failureThreshold: 3
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health
|
||||
port: 48108
|
||||
initialDelaySeconds: 100
|
||||
periodSeconds: 10
|
||||
failureThreshold: 5
|
||||
resources:
|
||||
requests:
|
||||
cpu: "500m"
|
||||
memory: "1024Mi"
|
||||
limits:
|
||||
cpu: "500m"
|
||||
memory: "2048Mi"
|
||||
terminationGracePeriodSeconds: 40
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
74
deployment-gateway.yaml
Normal file
74
deployment-gateway.yaml
Normal file
@@ -0,0 +1,74 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
namespace: ns-d6a0e78ebd674c279614498e4c57b133
|
||||
name: zt-gateway
|
||||
labels:
|
||||
app: zt-gateway
|
||||
annotations:
|
||||
version: "VERSION_PLACEHOLDER"
|
||||
description: DESC_PLACEHOLDER
|
||||
rollout.kubernetes.io/change-cause: "DESC_PLACEHOLDER:VERSION_PLACEHOLDER"
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: zt-gateway
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: zt-gateway
|
||||
spec:
|
||||
containers:
|
||||
- name: zt-gateway
|
||||
image: 172.16.46.66:10043/zt/zt-gateway:VERSION_PLACEHOLDER
|
||||
imagePullPolicy: Always
|
||||
env:
|
||||
- name: TZ
|
||||
value: Asia/Shanghai
|
||||
lifecycle:
|
||||
preStop:
|
||||
exec:
|
||||
command:
|
||||
- "/bin/sh"
|
||||
- "-c"
|
||||
- "sleep 35"
|
||||
ports:
|
||||
- containerPort: 48080
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health
|
||||
port: 48080
|
||||
initialDelaySeconds: 100
|
||||
periodSeconds: 5
|
||||
failureThreshold: 3
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health
|
||||
port: 48080
|
||||
initialDelaySeconds: 100
|
||||
periodSeconds: 10
|
||||
failureThreshold: 5
|
||||
resources:
|
||||
requests:
|
||||
cpu: "500m"
|
||||
memory: "1024Mi"
|
||||
limits:
|
||||
cpu: "500m"
|
||||
memory: "2048Mi"
|
||||
terminationGracePeriodSeconds: 40
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
namespace: ns-d6a0e78ebd674c279614498e4c57b133
|
||||
name: zt-gateway
|
||||
spec:
|
||||
type: NodePort
|
||||
selector:
|
||||
app: zt-gateway
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 48080
|
||||
targetPort: 48080
|
||||
nodePort: 30081
|
||||
67
deployment-infra.yaml
Normal file
67
deployment-infra.yaml
Normal file
@@ -0,0 +1,67 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
namespace: ns-d6a0e78ebd674c279614498e4c57b133
|
||||
name: zt-module-infra
|
||||
labels:
|
||||
app: zt-module-infra
|
||||
annotations:
|
||||
version: "VERSION_PLACEHOLDER"
|
||||
description: DESC_PLACEHOLDER
|
||||
rollout.kubernetes.io/change-cause: "DESC_PLACEHOLDER:VERSION_PLACEHOLDER"
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: zt-module-infra
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: zt-module-infra
|
||||
spec:
|
||||
dnsPolicy: None
|
||||
dnsConfig:
|
||||
nameservers:
|
||||
- "172.16.36.16"
|
||||
- "172.16.36.220"
|
||||
containers:
|
||||
- name: zt-module-infra
|
||||
image: 172.16.46.66:10043/zt/zt-module-infra:VERSION_PLACEHOLDER
|
||||
imagePullPolicy: Always
|
||||
env:
|
||||
- name: TZ
|
||||
value: Asia/Shanghai
|
||||
lifecycle:
|
||||
preStop:
|
||||
exec:
|
||||
command:
|
||||
- "/bin/sh"
|
||||
- "-c"
|
||||
- "sleep 35"
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health
|
||||
port: 48082
|
||||
initialDelaySeconds: 100
|
||||
periodSeconds: 5
|
||||
failureThreshold: 3
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health
|
||||
port: 48082
|
||||
initialDelaySeconds: 100
|
||||
periodSeconds: 10
|
||||
failureThreshold: 5
|
||||
resources:
|
||||
requests:
|
||||
cpu: "500m"
|
||||
memory: "1024Mi"
|
||||
limits:
|
||||
cpu: "500m"
|
||||
memory: "2048Mi"
|
||||
terminationGracePeriodSeconds: 40
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
76
deployment-system.yaml
Normal file
76
deployment-system.yaml
Normal file
@@ -0,0 +1,76 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
namespace: ns-d6a0e78ebd674c279614498e4c57b133
|
||||
name: zt-module-system
|
||||
labels:
|
||||
app: zt-module-system
|
||||
annotations:
|
||||
version: "VERSION_PLACEHOLDER"
|
||||
description: DESC_PLACEHOLDER
|
||||
rollout.kubernetes.io/change-cause: "DESC_PLACEHOLDER:VERSION_PLACEHOLDER"
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: zt-module-system
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: zt-module-system
|
||||
spec:
|
||||
affinity:
|
||||
nodeAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchExpressions:
|
||||
- key: kubernetes.io/hostname
|
||||
operator: In
|
||||
values:
|
||||
- node-3
|
||||
dnsPolicy: None
|
||||
dnsConfig:
|
||||
nameservers:
|
||||
- "172.16.36.16"
|
||||
- "172.16.36.220"
|
||||
containers:
|
||||
- name: zt-module-system
|
||||
image: 172.16.46.66:10043/zt/zt-module-system:VERSION_PLACEHOLDER
|
||||
imagePullPolicy: Always
|
||||
env:
|
||||
- name: TZ
|
||||
value: Asia/Shanghai
|
||||
lifecycle:
|
||||
preStop:
|
||||
exec:
|
||||
command:
|
||||
- "/bin/sh"
|
||||
- "-c"
|
||||
- "sleep 35"
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health
|
||||
port: 48081
|
||||
initialDelaySeconds: 100
|
||||
periodSeconds: 5
|
||||
failureThreshold: 3
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health
|
||||
port: 48081
|
||||
initialDelaySeconds: 100
|
||||
periodSeconds: 10
|
||||
failureThreshold: 5
|
||||
resources:
|
||||
requests:
|
||||
cpu: "500m"
|
||||
memory: "1024Mi"
|
||||
limits:
|
||||
cpu: "500m"
|
||||
memory: "2048Mi"
|
||||
terminationGracePeriodSeconds: 40
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
32
pom.xml
32
pom.xml
@@ -25,6 +25,7 @@
|
||||
<module>zt-module-databus</module>
|
||||
<!-- <module>zt-module-rule</module>-->
|
||||
<!-- <module>zt-module-html2pdf</module>-->
|
||||
<!-- <module>zt-server</module>-->
|
||||
</modules>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
@@ -32,7 +33,7 @@
|
||||
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
||||
|
||||
<properties>
|
||||
<revision>3.0.46</revision>
|
||||
<revision>3.0.47-SNAPSHOT</revision>
|
||||
<!-- Maven 相关 -->
|
||||
<java.version>17</java.version>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
@@ -203,7 +204,7 @@
|
||||
<repository>
|
||||
<id>ZT</id>
|
||||
<name>中铜 ZStack 私服</name>
|
||||
<url>http://172.16.46.63:30708/repository/test/</url>
|
||||
<url>http://172.16.46.63:30708/repository/zt-cloud/</url>
|
||||
<releases>
|
||||
<updatePolicy>always</updatePolicy>
|
||||
<checksumPolicy>warn</checksumPolicy>
|
||||
@@ -221,11 +222,11 @@
|
||||
<name>中铜 ZStack 私服</name>
|
||||
<url>http://172.16.46.63:30708/repository/test/</url>
|
||||
</repository>
|
||||
<!-- <snapshotRepository>-->
|
||||
<!-- <id>ZT</id>-->
|
||||
<!-- <name>中铜 ZStack 私服</name>-->
|
||||
<!-- <url>https://your-nexus.example.com/repository/maven-snapshots/</url>-->
|
||||
<!-- </snapshotRepository>-->
|
||||
<snapshotRepository>
|
||||
<id>ZT-snap</id>
|
||||
<name>中铜 ZStack 私服</name>
|
||||
<url>http://172.16.46.63:30708/repository/test-snap/</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
|
||||
<profiles>
|
||||
@@ -242,6 +243,19 @@
|
||||
<config.version>1.0.0</config.version>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>wzy</id>
|
||||
<properties>
|
||||
<env.name>dev</env.name>
|
||||
<!--Nacos 配置-->
|
||||
<config.server-addr>172.16.46.63:30848</config.server-addr>
|
||||
<config.namespace>wzy</config.namespace>
|
||||
<config.group>DEFAULT_GROUP</config.group>
|
||||
<config.username>nacos</config.username>
|
||||
<config.password>P@ssword25</config.password>
|
||||
<config.version>1.0.0</config.version>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>klw-dev</id>
|
||||
<properties>
|
||||
@@ -282,13 +296,13 @@
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>chenbowen</id>
|
||||
<id>haodongqiang</id>
|
||||
<properties>
|
||||
<!-- <env.name>local</env.name>-->
|
||||
<env.name>dev</env.name>
|
||||
<!-- <config.server-addr>localhost:8848</config.server-addr>-->
|
||||
<config.server-addr>172.16.46.63:30848</config.server-addr>
|
||||
<config.namespace>chenbowen</config.namespace>
|
||||
<config.namespace>haodongqiang</config.namespace>
|
||||
<config.group>DEFAULT_GROUP</config.group>
|
||||
<config.username>nacos</config.username>
|
||||
<config.password>P@ssword25</config.password>
|
||||
|
||||
4
sql/dm/20260116角色权限增加菜单是否显示字段.sql
Normal file
4
sql/dm/20260116角色权限增加菜单是否显示字段.sql
Normal file
@@ -0,0 +1,4 @@
|
||||
ALTER TABLE "SYSTEM_ROLE_MENU" ADD COLUMN "SHOW_MENU" BIT DEFAULT ('1') NOT NULL;
|
||||
COMMENT ON COLUMN "SYSTEM_ROLE_MENU"."SHOW_MENU" IS '是否显示菜单';
|
||||
|
||||
CREATE INDEX "IDX_SYSTEM_ROLE_ID_AND_MENU_ID" ON "SYSTEM_ROLE_MENU"(ROLE_ID,MENU_ID);
|
||||
@@ -0,0 +1,7 @@
|
||||
-- 为 API 客户端凭证表添加"是否启用加密"字段
|
||||
-- 2026-01-14
|
||||
|
||||
ALTER TABLE databus_api_client_credential
|
||||
ADD enable_encryption BIT DEFAULT '1' NOT NULL;
|
||||
|
||||
COMMENT ON COLUMN databus_api_client_credential.enable_encryption IS '是否启用加密传输';
|
||||
@@ -339,7 +339,8 @@ CREATE TABLE infra_file (
|
||||
create_time datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
updater varchar(64) DEFAULT '' NULL,
|
||||
update_time datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
deleted bit DEFAULT '0' NOT NULL
|
||||
deleted bit DEFAULT '0' NOT NULL,
|
||||
DOWNLOAD_COUNT INT DEFAULT 0 NOT NULL
|
||||
);
|
||||
|
||||
COMMENT ON COLUMN infra_file.id IS '文件编号';
|
||||
@@ -356,6 +357,7 @@ COMMENT ON COLUMN infra_file.create_time IS '创建时间';
|
||||
COMMENT ON COLUMN infra_file.updater IS '更新者';
|
||||
COMMENT ON COLUMN infra_file.update_time IS '更新时间';
|
||||
COMMENT ON COLUMN infra_file.deleted IS '是否删除';
|
||||
COMMENT ON COLUMN INFRA_FILE.DOWNLOAD_COUNT IS '下载次数';
|
||||
COMMENT ON TABLE infra_file IS '文件表';
|
||||
|
||||
CREATE INDEX idx_infra_file_hash ON infra_file(hash);
|
||||
|
||||
5
sql/dm/添加文件下载次数统计字段.sql
Normal file
5
sql/dm/添加文件下载次数统计字段.sql
Normal file
@@ -0,0 +1,5 @@
|
||||
-- 添加文件下载次数统计字段
|
||||
ALTER TABLE JYGK_TEST.INFRA_FILE
|
||||
ADD DOWNLOAD_COUNT INT DEFAULT 0 NOT NULL;
|
||||
|
||||
COMMENT ON COLUMN JYGK_TEST.INFRA_FILE.DOWNLOAD_COUNT IS '下载次数';
|
||||
42
sql/dm/物料牌号扩展功能.sql
Normal file
42
sql/dm/物料牌号扩展功能.sql
Normal file
@@ -0,0 +1,42 @@
|
||||
-- 表:bse_mtrl_grade_ext
|
||||
CREATE TABLE IF NOT EXISTS bse_mtrl_grade_ext (
|
||||
id BIGINT PRIMARY KEY,
|
||||
CMP_CD VARCHAR(64) NOT NULL,
|
||||
CMP_NM VARCHAR(128),
|
||||
MTRL_CD VARCHAR(128) NOT NULL,
|
||||
MTRL_NM VARCHAR(255),
|
||||
ZH_BRAND VARCHAR(255),
|
||||
EN_BRAND VARCHAR(255),
|
||||
SPC_MDL VARCHAR(255),
|
||||
LINE_TP VARCHAR(64),
|
||||
PKG VARCHAR(255),
|
||||
company_id BIGINT,
|
||||
company_name VARCHAR(128),
|
||||
dept_id BIGINT,
|
||||
dept_name VARCHAR(128),
|
||||
post_id BIGINT,
|
||||
tenant_id BIGINT DEFAULT 1,
|
||||
creator_name VARCHAR(64),
|
||||
updater_name VARCHAR(64),
|
||||
creator VARCHAR(64),
|
||||
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
updater VARCHAR(64),
|
||||
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
deleted BIT DEFAULT 0 NOT NULL
|
||||
);
|
||||
|
||||
-- 索引
|
||||
CREATE INDEX IF NOT EXISTS idx_bse_mtrl_grade_ext_mtrl_cd ON bse_mtrl_grade_ext (MTRL_CD);
|
||||
CREATE INDEX IF NOT EXISTS idx_bse_mtrl_grade_ext_cmp_cd ON bse_mtrl_grade_ext (CMP_CD);
|
||||
|
||||
-- 字段注释(可选)
|
||||
COMMENT ON TABLE bse_mtrl_grade_ext IS '物料牌号扩展';
|
||||
COMMENT ON COLUMN bse_mtrl_grade_ext.CMP_CD IS '公司编码';
|
||||
COMMENT ON COLUMN bse_mtrl_grade_ext.CMP_NM IS '公司名称';
|
||||
COMMENT ON COLUMN bse_mtrl_grade_ext.MTRL_CD IS '物料编码';
|
||||
COMMENT ON COLUMN bse_mtrl_grade_ext.MTRL_NM IS '物料名称';
|
||||
COMMENT ON COLUMN bse_mtrl_grade_ext.ZH_BRAND IS '中文牌号';
|
||||
COMMENT ON COLUMN bse_mtrl_grade_ext.EN_BRAND IS '英文牌号';
|
||||
COMMENT ON COLUMN bse_mtrl_grade_ext.SPC_MDL IS '规格型号';
|
||||
COMMENT ON COLUMN bse_mtrl_grade_ext.LINE_TP IS '线别(material_line_type 字典)';
|
||||
COMMENT ON COLUMN bse_mtrl_grade_ext.PKG IS '包装';
|
||||
10
sql/dm/物料牌号扩展线别字典.sql
Normal file
10
sql/dm/物料牌号扩展线别字典.sql
Normal file
@@ -0,0 +1,10 @@
|
||||
-- 字典类型:线别
|
||||
INSERT INTO system_dict_type (id, name, type, status, create_time, remark)
|
||||
VALUES (202701012001000001, '线别', 'material_line_type', 0, SYSDATE, '物料牌号扩展线别');
|
||||
|
||||
-- 字典数据:随机两项示例
|
||||
INSERT INTO system_dict_data (id, dict_type, label, value, sort, status, color_type, css_class, create_time)
|
||||
VALUES (202701012001000101, 'material_line_type', '单线', 'single', 1, 0, 0, NULL, SYSDATE);
|
||||
|
||||
INSERT INTO system_dict_data (id, dict_type, label, value, sort, status, color_type, css_class, create_time)
|
||||
VALUES (202701012001000102, 'material_line_type', '双线', 'double', 2, 0, 0, NULL, SYSDATE);
|
||||
21
sql/dm/物料牌号扩展菜单.sql
Normal file
21
sql/dm/物料牌号扩展菜单.sql
Normal file
@@ -0,0 +1,21 @@
|
||||
-- 物料牌号扩展菜单(DM 脚本)
|
||||
-- 如父级“物料管理”菜单 ID 不同,请调整 parent_id 默认值 1980093482014994433
|
||||
|
||||
-- 清理旧数据,便于重复执行
|
||||
DELETE FROM system_menu WHERE id IN (202701012002000000,202701012002000001,202701012002000002,202701012002000003,202701012002000004);
|
||||
|
||||
-- 功能菜单
|
||||
INSERT INTO system_menu (
|
||||
id, name, permission, type, sort, parent_id,
|
||||
path, icon, component, component_name, status
|
||||
) VALUES (
|
||||
202701012002000000, '物料牌号扩展', 'base:material-grade-ext:query', 2, 30, 1980093482014994433,
|
||||
'material-grade-ext', 'fa:list-alt', 'base/materialgradeext/index', 'MaterialGradeExt', 0
|
||||
);
|
||||
|
||||
-- 按钮权限
|
||||
INSERT INTO system_menu (id, name, permission, type, sort, parent_id, path, icon, component, status) VALUES
|
||||
(202701012002000001, '物料牌号扩展查询', 'base:material-grade-ext:query', 3, 1, 202701012002000000, '', '', '', 0),
|
||||
(202701012002000002, '物料牌号扩展新增', 'base:material-grade-ext:create', 3, 2, 202701012002000000, '', '', '', 0),
|
||||
(202701012002000003, '物料牌号扩展修改', 'base:material-grade-ext:update', 3, 3, 202701012002000000, '', '', '', 0),
|
||||
(202701012002000004, '物料牌号扩展删除', 'base:material-grade-ext:delete', 3, 4, 202701012002000000, '', '', '', 0);
|
||||
9
sql/dm/短信渠道中铝e办支持_DM8_20260109.sql
Normal file
9
sql/dm/短信渠道中铝e办支持_DM8_20260109.sql
Normal file
@@ -0,0 +1,9 @@
|
||||
-- 短信渠道新增鸿联九五支持(达梦8)
|
||||
-- 1) system_sms_channel 表新增 epid 字段
|
||||
-- 2) system_sms_channel_code 字典新增 HL95 选项
|
||||
|
||||
ALTER TABLE system_sms_channel ADD COLUMN epid VARCHAR(64);
|
||||
COMMENT ON COLUMN system_sms_channel.epid IS '企业编号(epid)';
|
||||
|
||||
INSERT INTO system_dict_data (id, sort, label, value, dict_type, status, color_type, css_class, remark, creator, create_time, updater, update_time, deleted)
|
||||
VALUES (1593, 5, '中铝e办', 'ZLE', 'system_sms_channel_code', 0, '', '', '', '1', '2026-01-09 00:00:00', '1', '2026-01-09 00:00:00', '0');
|
||||
@@ -10,11 +10,11 @@
|
||||
<name>中铜 ZStack 私服</name>
|
||||
<url>http://172.16.46.63:30708/repository/test/</url>
|
||||
</repository>
|
||||
<!-- <snapshotRepository>-->
|
||||
<!-- <id>ZT</id>-->
|
||||
<!-- <name>中铜 ZStack 私服</name>-->
|
||||
<!-- <url>https://your-nexus.example.com/repository/maven-snapshots/</url>-->
|
||||
<!-- </snapshotRepository>-->
|
||||
<snapshotRepository>
|
||||
<id>ZT-snap</id>
|
||||
<name>中铜 ZStack 私服</name>
|
||||
<url>http://172.16.46.63:30708/repository/test-snap/</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
<groupId>com.zt.plat</groupId>
|
||||
<artifactId>zt-dependencies</artifactId>
|
||||
@@ -26,7 +26,7 @@
|
||||
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
||||
|
||||
<properties>
|
||||
<revision>3.0.46</revision>
|
||||
<revision>3.0.47-SNAPSHOT</revision>
|
||||
<flatten-maven-plugin.version>1.6.0</flatten-maven-plugin.version>
|
||||
<!-- 统一依赖管理 -->
|
||||
<spring.boot.version>3.4.5</spring.boot.version>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<module>zt-spring-boot-starter-job</module>
|
||||
<module>zt-spring-boot-starter-mq</module>
|
||||
<module>zt-spring-boot-starter-rpc</module>
|
||||
|
||||
<module>zt-spring-boot-starter-seata-dm</module>
|
||||
<module>zt-spring-boot-starter-excel</module>
|
||||
<module>zt-spring-boot-starter-test</module>
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
<module>zt-spring-boot-starter-biz-data-permission</module>
|
||||
<module>zt-spring-boot-starter-biz-ip</module>
|
||||
<module>zt-spring-boot-starter-biz-business</module>
|
||||
<module>zt-spring-boot-starter-seata-dm</module>
|
||||
</modules>
|
||||
|
||||
<artifactId>zt-framework</artifactId>
|
||||
|
||||
@@ -163,6 +163,33 @@
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk18on</artifactId>
|
||||
<version>1.78.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents.client5</groupId>
|
||||
<artifactId>httpclient5</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents.client5</groupId>
|
||||
<artifactId>httpclient5</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.14</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpmime</artifactId>
|
||||
<version>4.5.14</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -47,5 +47,4 @@ public interface PermissionCommonApi {
|
||||
@Parameter(name = "roleCodes", description = "角色编码", example = "2", required = true)
|
||||
})
|
||||
CommonResult<DeptDataPermissionRespDTO> getDeptDataPermissionWithRoleCodes(@RequestParam("userId") Long userId, @RequestParam("roleCodes") String roleCodes);
|
||||
|
||||
}
|
||||
@@ -15,7 +15,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Schema(description = "分页结果")
|
||||
@Data
|
||||
@Data //TODO 分页结果参考这个
|
||||
public final class PageResult<T> implements Serializable {
|
||||
|
||||
@Schema(description = "数据", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
|
||||
@@ -9,7 +9,7 @@ import java.util.concurrent.*;
|
||||
* 多次提交,一次等待
|
||||
*/
|
||||
public class AsyncLatchUtils {
|
||||
private static final ThreadLocal<List<TaskInfo>> THREADLOCAL = ThreadLocal.withInitial(LinkedList::new);
|
||||
private static final ThreadLocal<List<TaskInfo>> THREAD_LOCAL = ThreadLocal.withInitial(LinkedList::new);
|
||||
|
||||
/**
|
||||
* 提交一个异步任务
|
||||
@@ -17,7 +17,7 @@ public class AsyncLatchUtils {
|
||||
* @param runnable 需要异步执行的具体业务逻辑
|
||||
*/
|
||||
public static void submitTask(Executor executor, Runnable runnable) {
|
||||
THREADLOCAL.get().add(new TaskInfo(executor, runnable));
|
||||
THREAD_LOCAL.get().add(new TaskInfo(executor, runnable));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -25,8 +25,8 @@ public class AsyncLatchUtils {
|
||||
* @return
|
||||
*/
|
||||
private static List<TaskInfo> popTask() {
|
||||
List<TaskInfo> taskInfos = THREADLOCAL.get();
|
||||
THREADLOCAL.remove();
|
||||
List<TaskInfo> taskInfos = THREAD_LOCAL.get();
|
||||
THREAD_LOCAL.remove();
|
||||
return taskInfos;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class AsyncLatchUtils {
|
||||
*/
|
||||
public static boolean waitFor(long timeout, TimeUnit timeUnit) {
|
||||
List<TaskInfo> taskInfos = popTask();
|
||||
if (taskInfos.isEmpty()) {
|
||||
if (taskInfos.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
CountDownLatch latch = new CountDownLatch(taskInfos.size());
|
||||
@@ -57,8 +57,11 @@ public class AsyncLatchUtils {
|
||||
boolean await = false;
|
||||
try {
|
||||
await = latch.await(timeout, timeUnit);
|
||||
} catch (Exception ignored) {}
|
||||
return await;
|
||||
} catch (Exception ignored) {
|
||||
// 恢复中断状态
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
return await;
|
||||
}
|
||||
|
||||
private static final class TaskInfo {
|
||||
|
||||
@@ -0,0 +1,382 @@
|
||||
package com.zt.plat.framework.common.util.http;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.entity.mime.HttpMultipartMode;
|
||||
import org.apache.http.entity.mime.MultipartEntityBuilder;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* HttpClient工具类
|
||||
*
|
||||
* @author luzemin
|
||||
*/
|
||||
@Slf4j
|
||||
public class HttpClientUtils {
|
||||
/**
|
||||
* 请求配置对象
|
||||
*/
|
||||
private static final RequestConfig REQUEST_CONFIG;
|
||||
|
||||
static {
|
||||
/* 设置请求和传输超时时间 */
|
||||
REQUEST_CONFIG = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* post请求传输json参数
|
||||
*
|
||||
* @param url url地址
|
||||
* @param jsonParam 参数
|
||||
* @return JSONObject 请求结果对象
|
||||
*/
|
||||
public static JSONObject httpPost(String url, JSONObject jsonParam) {
|
||||
/* 请求返回结果 */
|
||||
JSONObject jsonResult = null;
|
||||
|
||||
/* 构建连接对象 */
|
||||
CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||
HttpPost httpPost = new HttpPost(url);
|
||||
httpPost.setConfig(REQUEST_CONFIG);
|
||||
|
||||
try {
|
||||
/* 构建请求体 */
|
||||
if (StringUtils.isNotBlank(jsonParam.toJSONString())) {
|
||||
StringEntity entity = new StringEntity(jsonParam.toJSONString(), StandardCharsets.UTF_8);
|
||||
entity.setContentEncoding(StandardCharsets.UTF_8.name());
|
||||
entity.setContentType(ContentType.APPLICATION_JSON.getMimeType());
|
||||
httpPost.setEntity(entity);
|
||||
}
|
||||
|
||||
/* 提交请求,构建响应对象 */
|
||||
CloseableHttpResponse response = httpClient.execute(httpPost);
|
||||
|
||||
/* 处理请求结果 */
|
||||
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
|
||||
HttpEntity responseEntity = response.getEntity();
|
||||
String result = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
|
||||
jsonResult = JSONObject.parseObject(result);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
httpPost.releaseConnection();
|
||||
}
|
||||
return jsonResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* post请求传输String参数 例如:name=Jack&sex=1&type=2
|
||||
* Content-type:application/x-www-form-urlencoded
|
||||
*
|
||||
* @param url url地址
|
||||
* @param strParam 参数
|
||||
* @return JSONObject 请求结果对象
|
||||
*/
|
||||
public static JSONObject httpPost(String url, String strParam) {
|
||||
/* 请求返回结果 */
|
||||
JSONObject jsonResult = null;
|
||||
|
||||
/* 构建连接对象 */
|
||||
CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||
HttpPost httpPost = new HttpPost(url);
|
||||
httpPost.setConfig(REQUEST_CONFIG);
|
||||
|
||||
try {
|
||||
/* 构建请求体 */
|
||||
if (StringUtils.isNotBlank(strParam)) {
|
||||
StringEntity entity = new StringEntity(strParam, StandardCharsets.UTF_8);
|
||||
entity.setContentEncoding(StandardCharsets.UTF_8.name());
|
||||
entity.setContentType(ContentType.APPLICATION_JSON.getMimeType());
|
||||
httpPost.setEntity(entity);
|
||||
}
|
||||
|
||||
/* 提交请求,构建响应对象 */
|
||||
CloseableHttpResponse response = httpClient.execute(httpPost);
|
||||
|
||||
/* 处理请求结果 */
|
||||
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
|
||||
HttpEntity responseEntity = response.getEntity();
|
||||
String result = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
|
||||
jsonResult = JSONObject.parseObject(result);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
httpPost.releaseConnection();
|
||||
}
|
||||
return jsonResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* post请求传输String参数 例如:name=Jack&sex=1&type=2
|
||||
* Content-type:application/x-www-form-urlencoded
|
||||
*
|
||||
* @param url url地址
|
||||
* @param strParam 参数
|
||||
* @param token 身份认证令牌
|
||||
* @return JSONObject 请求结果对象
|
||||
*/
|
||||
public static JSONObject httpPostByToken(String url, String strParam, String token) {
|
||||
/* 请求返回结果 */
|
||||
JSONObject jsonResult = null;
|
||||
|
||||
/* 构建连接对象 */
|
||||
CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||
HttpPost httpPost = new HttpPost(url);
|
||||
httpPost.setConfig(REQUEST_CONFIG);
|
||||
|
||||
try {
|
||||
/* 构建请求体 */
|
||||
if (StringUtils.isNotBlank(strParam)) {
|
||||
StringEntity entity = new StringEntity(strParam, StandardCharsets.UTF_8);
|
||||
entity.setContentEncoding(StandardCharsets.UTF_8.name());
|
||||
entity.setContentType(ContentType.APPLICATION_JSON.getMimeType());
|
||||
httpPost.setEntity(entity);
|
||||
}
|
||||
if (StringUtils.isNotBlank(token)) {
|
||||
httpPost.setHeader("token", token);
|
||||
}
|
||||
|
||||
|
||||
/* 提交请求,构建响应对象 */
|
||||
CloseableHttpResponse response = httpClient.execute(httpPost);
|
||||
|
||||
/* 处理请求结果 */
|
||||
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
|
||||
HttpEntity responseEntity = response.getEntity();
|
||||
String result = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
|
||||
jsonResult = JSONObject.parseObject(result);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
httpPost.releaseConnection();
|
||||
}
|
||||
return jsonResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* post请求传输String参数 例如:name=Jack&sex=1&type=2
|
||||
* Content-type:application/x-www-form-urlencoded
|
||||
*
|
||||
* @param url url地址
|
||||
* @param strParam 参数
|
||||
* @return String 请求结果对象
|
||||
*/
|
||||
public static String httpPostStr(String url, String strParam) {
|
||||
/* 请求返回结果 */
|
||||
String jsonResult = null;
|
||||
|
||||
/* 构建连接对象 */
|
||||
CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||
HttpPost httpPost = new HttpPost(url);
|
||||
httpPost.setConfig(REQUEST_CONFIG);
|
||||
|
||||
try {
|
||||
/* 构建请求体 */
|
||||
if (StringUtils.isNotBlank(strParam)) {
|
||||
StringEntity entity = new StringEntity(strParam, StandardCharsets.UTF_8);
|
||||
entity.setContentEncoding(StandardCharsets.UTF_8.name());
|
||||
entity.setContentType(ContentType.APPLICATION_FORM_URLENCODED.getMimeType());
|
||||
httpPost.setEntity(entity);
|
||||
}
|
||||
|
||||
/* 提交请求,构建响应对象 */
|
||||
CloseableHttpResponse response = httpClient.execute(httpPost);
|
||||
|
||||
/* 处理请求结果 */
|
||||
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
|
||||
HttpEntity responseEntity = response.getEntity();
|
||||
jsonResult = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
httpPost.releaseConnection();
|
||||
}
|
||||
return jsonResult;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* post请求传输String参数 例如:name=Jack&sex=1&type=2
|
||||
* Content-type:application/x-www-form-urlencoded
|
||||
*
|
||||
* @param url url地址
|
||||
* @param strParam 参数
|
||||
* @param token 身份认证字符串
|
||||
* @return String 请求结果对象
|
||||
*/
|
||||
public static String httpPostStrByToken(String url, String strParam, String token) {
|
||||
/* 请求返回结果 */
|
||||
String jsonResult = null;
|
||||
|
||||
/* 构建连接对象 */
|
||||
CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||
HttpPost httpPost = new HttpPost(url);
|
||||
httpPost.setConfig(REQUEST_CONFIG);
|
||||
|
||||
try {
|
||||
/* 构建请求体 */
|
||||
if (StringUtils.isNotBlank(strParam)) {
|
||||
StringEntity entity = new StringEntity(strParam, StandardCharsets.UTF_8);
|
||||
entity.setContentEncoding(StandardCharsets.UTF_8.name());
|
||||
entity.setContentType(ContentType.APPLICATION_JSON.getMimeType());
|
||||
httpPost.setEntity(entity);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(token)) {
|
||||
httpPost.setHeader("token", token);
|
||||
}
|
||||
|
||||
/* 提交请求,构建响应对象 */
|
||||
CloseableHttpResponse response = httpClient.execute(httpPost);
|
||||
|
||||
/* 处理请求结果 */
|
||||
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
|
||||
HttpEntity responseEntity = response.getEntity();
|
||||
jsonResult = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
httpPost.releaseConnection();
|
||||
}
|
||||
return jsonResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据指定的url地址上传文件
|
||||
*
|
||||
* @param mediaName 服务器定义的读取文件流的name
|
||||
* @param url 文件上传url
|
||||
* @param file 文件对象
|
||||
* @return JSONObject 文件上传结果
|
||||
*/
|
||||
public static JSONObject httpFileUpload(String mediaName, String url, MultipartFile file) {
|
||||
/* 请求返回结果 */
|
||||
JSONObject jsonResult = null;
|
||||
|
||||
/* 构建连接对象 */
|
||||
CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||
HttpPost httpPost = new HttpPost(url);
|
||||
httpPost.setConfig(REQUEST_CONFIG);
|
||||
|
||||
/* 构建请求头 */
|
||||
String boundaryStr = UUID.randomUUID().toString();
|
||||
httpPost.setHeader(HttpHeaders.ACCEPT_CHARSET, StandardCharsets.UTF_8.name());
|
||||
httpPost.setHeader(HttpHeaders.CONNECTION, "Keep-Alive");
|
||||
httpPost.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.MULTIPART_FORM_DATA.getMimeType() + ";boundary=" + boundaryStr);
|
||||
|
||||
try {
|
||||
/* 构建文件对象 */
|
||||
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
|
||||
multipartEntityBuilder.setBoundary(boundaryStr)
|
||||
.setContentType(ContentType.APPLICATION_OCTET_STREAM)
|
||||
.setCharset(StandardCharsets.UTF_8)
|
||||
.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
|
||||
multipartEntityBuilder.addBinaryBody(mediaName, file.getInputStream(), ContentType.APPLICATION_OCTET_STREAM, file.getOriginalFilename());
|
||||
HttpEntity entity = multipartEntityBuilder.build();
|
||||
httpPost.setEntity(entity);
|
||||
|
||||
/* 提交请求,构建响应对象 */
|
||||
CloseableHttpResponse response = httpClient.execute(httpPost);
|
||||
|
||||
/* 处理请求结果 */
|
||||
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
|
||||
HttpEntity responseEntity = response.getEntity();
|
||||
String result = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
|
||||
jsonResult = JSONObject.parseObject(result);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
httpPost.releaseConnection();
|
||||
}
|
||||
return jsonResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送get请求
|
||||
*
|
||||
* @param url 路径
|
||||
* @return JSONObject 请求结果对象
|
||||
*/
|
||||
public static JSONObject httpGet(String url) {
|
||||
/* 请求返回结果 */
|
||||
JSONObject jsonResult = null;
|
||||
|
||||
/* 构建连接对象 */
|
||||
CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||
HttpGet httpGet = new HttpGet(url);
|
||||
httpGet.setConfig(REQUEST_CONFIG);
|
||||
|
||||
try {
|
||||
/* 提交请求,构建响应对象 */
|
||||
CloseableHttpResponse response = httpClient.execute(httpGet);
|
||||
|
||||
/* 处理请求结果 */
|
||||
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
|
||||
HttpEntity responseEntity = response.getEntity();
|
||||
String result = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
|
||||
jsonResult = JSONObject.parseObject(result);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
httpGet.releaseConnection();
|
||||
}
|
||||
return jsonResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送get请求
|
||||
*
|
||||
* @param url 路径
|
||||
* @return JSONObject 请求结果对象
|
||||
*/
|
||||
public static String httpGetStr(String url) {
|
||||
/* 请求返回结果 */
|
||||
String jsonResult = null;
|
||||
|
||||
/* 构建连接对象 */
|
||||
CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||
HttpGet httpGet = new HttpGet(url);
|
||||
httpGet.setConfig(REQUEST_CONFIG);
|
||||
|
||||
try {
|
||||
/* 提交请求,构建响应对象 */
|
||||
CloseableHttpResponse response = httpClient.execute(httpGet);
|
||||
|
||||
/* 处理请求结果 */
|
||||
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
|
||||
HttpEntity responseEntity = response.getEntity();
|
||||
jsonResult = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
httpGet.releaseConnection();
|
||||
}
|
||||
return jsonResult;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
package com.zt.plat.framework.common.util.security;
|
||||
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import cn.hutool.crypto.symmetric.SM4;
|
||||
import com.zt.plat.framework.common.util.json.JsonUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
@@ -11,6 +12,7 @@ import javax.crypto.spec.SecretKeySpec;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@@ -27,6 +29,15 @@ public final class CryptoSignatureUtils {
|
||||
private static final String AES_TRANSFORMATION = "AES/ECB/PKCS5Padding";
|
||||
public static final String SIGNATURE_FIELD = "signature";
|
||||
|
||||
private static final String CHARSET = "UTF-8";
|
||||
|
||||
//@Value("${sa.encrypt.sm4.key}")
|
||||
private static String SM4_KEY = "1234567890123456";
|
||||
|
||||
static {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
}
|
||||
|
||||
private CryptoSignatureUtils() {
|
||||
}
|
||||
|
||||
@@ -220,4 +231,91 @@ public final class CryptoSignatureUtils {
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------- 国密方式2 -------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 加密
|
||||
*/
|
||||
public static String enCode(String data) {
|
||||
try {
|
||||
// 第一步: SM4 加密
|
||||
SM4 sm4 = new SM4(hexToBytes(stringToHex(SM4_KEY)));
|
||||
String encryptHex = sm4.encryptHex(data);
|
||||
|
||||
// 第二步: Base64 编码
|
||||
return new String(Base64.getEncoder().encode(encryptHex.getBytes(CHARSET)), CHARSET);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("国密加密失败{}",e.getMessage(),e);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密
|
||||
*/
|
||||
public static String deCode(String data) {
|
||||
try {
|
||||
|
||||
// 第一步: Base64 解码
|
||||
byte[] base64Decode = Base64.getDecoder().decode(data);
|
||||
|
||||
// 第二步: SM4 解密
|
||||
SM4 sm4 = new SM4(hexToBytes(stringToHex(SM4_KEY)));
|
||||
return sm4.decryptStr(new String(base64Decode));
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("国密解密失败{}",e.getMessage(),e);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String stringToHex(String input) {
|
||||
char[] chars = input.toCharArray();
|
||||
StringBuilder hex = new StringBuilder();
|
||||
for (char c : chars) {
|
||||
hex.append(Integer.toHexString((int) c));
|
||||
}
|
||||
return hex.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 16 进制串转字节数组
|
||||
*
|
||||
* @param hex 16进制字符串
|
||||
* @return byte数组
|
||||
*/
|
||||
public static byte[] hexToBytes(String hex) {
|
||||
int length = hex.length();
|
||||
byte[] result;
|
||||
if (length % 2 == 1) {
|
||||
length++;
|
||||
result = new byte[(length / 2)];
|
||||
hex = "0" + hex;
|
||||
} else {
|
||||
result = new byte[(length / 2)];
|
||||
}
|
||||
int j = 0;
|
||||
for (int i = 0; i < length; i += 2) {
|
||||
result[j] = hexToByte(hex.substring(i, i + 2));
|
||||
j++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 16 进制字符转字节
|
||||
*
|
||||
* @param hex 16进制字符 0x00到0xFF
|
||||
* @return byte
|
||||
*/
|
||||
private static byte hexToByte(String hex) {
|
||||
return (byte) Integer.parseInt(hex, 16);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
package com.zt.plat.framework.common.util.security;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.Key;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* 3DES加密解密工具类
|
||||
* 注意:如果websphere下报错:Could not find class 'com.sun.crypto.provider.SunJCE'
|
||||
* 解决方法如下: 下载sunjce_provider.jar放到jdk目录\jre\lib\ext里即可解决
|
||||
*
|
||||
* @author apple
|
||||
*/
|
||||
|
||||
public class DESUtil {
|
||||
|
||||
/**
|
||||
* 默认的密钥
|
||||
*/
|
||||
private static final String strDefaultKey = "cymco-20160329000000000000000ABCGHDYFYSSPPOEWWWDDDSSXX-cymco";
|
||||
|
||||
private Cipher encryptCipher = null;
|
||||
|
||||
private Cipher decryptCipher = null;
|
||||
|
||||
/**
|
||||
* 将byte数组转换为表示16进制值的字符串, 如:byte[]{8,18}转换为:0813, 和public static byte[]
|
||||
* hexStr2ByteArr(String strIn) 互为可逆的转换过程
|
||||
* @param arrB 需要转换的byte数组
|
||||
* @return 转换后的字符串
|
||||
* @throws Exception 本方法不处理任何异常,所有异常全部抛出
|
||||
*/
|
||||
public static String byteArr2HexStr(byte[] arrB) throws Exception {
|
||||
int iLen = arrB.length;
|
||||
// 每个byte用两个字符才能表示,所以字符串的长度是数组长度的两倍
|
||||
StringBuffer sb = new StringBuffer(iLen * 2);
|
||||
for (int i = 0; i < iLen; i++) {
|
||||
int intTmp = arrB[i];
|
||||
// 把负数转换为正数
|
||||
while (intTmp < 0) {
|
||||
intTmp = intTmp + 256;
|
||||
}
|
||||
// 小于0F的数需要在前面补0
|
||||
if (intTmp < 16) {
|
||||
sb.append("0");
|
||||
}
|
||||
sb.append(Integer.toString(intTmp, 16));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将表示16进制值的字符串转换为byte数组, 和public static String byteArr2HexStr(byte[] arrB)
|
||||
* 互为可逆的转换过程
|
||||
* @param strIn 需要转换的字符串
|
||||
* @return 转换后的byte数组
|
||||
* @throws Exception 本方法不处理任何异常,所有异常全部抛出
|
||||
*/
|
||||
public static byte[] hexStr2ByteArr(String strIn) throws Exception {
|
||||
byte[] arrB = strIn.getBytes(StandardCharsets.UTF_8);
|
||||
int iLen = arrB.length;
|
||||
|
||||
// 两个字符表示一个字节,所以字节数组长度是字符串长度除以2
|
||||
byte[] arrOut = new byte[iLen / 2];
|
||||
for (int i = 0; i < iLen; i = i + 2) {
|
||||
String strTmp = new String(arrB, i, 2);
|
||||
arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);
|
||||
}
|
||||
return arrOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认构造方法,使用默认密钥
|
||||
* @throws Exception
|
||||
*/
|
||||
public DESUtil() throws Exception {
|
||||
this(strDefaultKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定密钥构造方法
|
||||
* @param strKey 指定的密钥
|
||||
* @throws Exception
|
||||
*/
|
||||
public DESUtil(String strKey) throws Exception {
|
||||
//Security.addProvider(new com.sun.crypto.provider.SunJCE());
|
||||
Key key = getKey(strKey.getBytes());
|
||||
|
||||
encryptCipher = Cipher.getInstance("DES");
|
||||
encryptCipher.init(Cipher.ENCRYPT_MODE, key);
|
||||
|
||||
decryptCipher = Cipher.getInstance("DES");
|
||||
decryptCipher.init(Cipher.DECRYPT_MODE, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密字节数组
|
||||
* @param arrB 需加密的字节数组
|
||||
* @return 加密后的字节数组
|
||||
* @throws Exception
|
||||
*/
|
||||
public byte[] encrypt(byte[] arrB) throws Exception {
|
||||
return encryptCipher.doFinal(arrB);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密字符串
|
||||
* @param strIn 需加密的字符串
|
||||
* @return 加密后的字符串
|
||||
* @throws Exception
|
||||
*/
|
||||
public String encrypt(String strIn) throws Exception {
|
||||
return byteArr2HexStr(encrypt(strIn.getBytes()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密字节数组
|
||||
* @param arrB 需解密的字节数组
|
||||
* @return 解密后的字节数组
|
||||
* @throws Exception
|
||||
*/
|
||||
public byte[] decrypt(byte[] arrB) throws Exception {
|
||||
return decryptCipher.doFinal(arrB);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密字符串
|
||||
* @param strIn 需解密的字符串
|
||||
* @return 解密后的字符串
|
||||
* @throws Exception
|
||||
*/
|
||||
public String decrypt(String strIn) throws Exception {
|
||||
return new String(decrypt(hexStr2ByteArr(strIn)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 从指定字符串生成密钥,密钥所需的字节数组长度为8位 不足8位时后面补0,超出8位只取前8位
|
||||
* @param arrBTmp 构成该字符串的字节数组
|
||||
* @return 生成的密钥
|
||||
* @throws Exception
|
||||
*/
|
||||
private Key getKey(byte[] arrBTmp) throws Exception {
|
||||
// 创建一个空的8位字节数组(默认值为0)
|
||||
byte[] arrB = new byte[8];
|
||||
|
||||
// 将原始字节数组转换为8位
|
||||
for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {
|
||||
arrB[i] = arrBTmp[i];
|
||||
}
|
||||
|
||||
// 生成密钥
|
||||
Key key = new javax.crypto.spec.SecretKeySpec(arrB, "DES");
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
public static String SHA1(String decript) throws NoSuchAlgorithmException {
|
||||
try {
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-1");
|
||||
digest.update(decript.getBytes());
|
||||
byte messageDigest[] = digest.digest();
|
||||
// Create Hex String
|
||||
StringBuffer hexString = new StringBuffer();
|
||||
// 字节数组转换为 十六进制 数
|
||||
for (int i = 0; i < messageDigest.length; i++) {
|
||||
String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
|
||||
if (shaHex.length() < 2) {
|
||||
hexString.append(0);
|
||||
}
|
||||
hexString.append(shaHex);
|
||||
}
|
||||
return hexString.toString();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static void main(String [] args){
|
||||
DESUtil des;
|
||||
try {
|
||||
des = new DESUtil();
|
||||
String en= des.encrypt("fls123,12121");
|
||||
System.out.println(en);
|
||||
String de = des.decrypt(en);
|
||||
System.out.println(de);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
package com.zt.plat.framework.common.util.validation;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 正则校验工具
|
||||
*
|
||||
* @author luzemin
|
||||
**/
|
||||
public class MatcherSolveUtils {
|
||||
|
||||
/**
|
||||
* 正则校验正数、负数、和小数
|
||||
*/
|
||||
private static final Pattern IS_NUM = Pattern.compile("^(\\-|\\+)?\\d+(\\.\\d+)?$");
|
||||
/**
|
||||
* 正则校验大于0的数字
|
||||
*/
|
||||
private static final Pattern IS_GT_0_NUM = Pattern.compile("(^[0-9]+\\.\\d+$)|(^[0-9]+$)");
|
||||
/**
|
||||
* 正则校验大于等于0的数字
|
||||
*/
|
||||
private static final Pattern IS_GE_EQ_0_NUM = Pattern.compile("(^[0-9]+\\.\\d+$)|(^[1-9]+\\d*$)");
|
||||
/**
|
||||
* 正则校验字母或者数字组成的字符串
|
||||
*/
|
||||
private static final Pattern EN_NUM = Pattern.compile("^[A-Za-z0-9]+$");
|
||||
/**
|
||||
* 中文、英文、数字但不包括下划线等符号
|
||||
*/
|
||||
private static final Pattern EN_CN_NUM = Pattern.compile("^[\\u4E00-\\u9FA5A-Za-z0-9]+$");
|
||||
/**
|
||||
* Email地址
|
||||
*/
|
||||
private static final Pattern EMAIL = Pattern.compile("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$");
|
||||
/**
|
||||
* 域名
|
||||
*/
|
||||
private static final Pattern WWW = Pattern.compile("[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\\.?");
|
||||
/**
|
||||
* InternetURL
|
||||
*/
|
||||
private static final Pattern URL = Pattern.compile("(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]");
|
||||
/**
|
||||
* 手机号码
|
||||
*/
|
||||
private static final Pattern MOBILE_NUM = Pattern.compile("^(13[0-9]|14[5|7]|15[0|1|2|3|4|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\\d{8}$");
|
||||
/**
|
||||
* 车牌号
|
||||
*/
|
||||
private static final Pattern TRUCK_NO = Pattern.compile("^([京津晋冀蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川贵云藏陕甘青宁新][ABCDEFGHJKLMNPQRSTUVWXY][1-9DF][1-9ABCDEFGHJKLMNPQRSTUVWXYZ]\\d{3}[1-9DF]|[京津晋冀蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川贵云藏陕甘青宁新][ABCDEFGHJKLMNPQRSTUVWXY][\\dABCDEFGHJKLNMxPQRSTUVWXYZ]{5})$");
|
||||
|
||||
/**
|
||||
* 电话号码正则表达式(支持手机号码,3-4位区号,7-8位直播号码,1-4位分机号)
|
||||
*/
|
||||
private static final Pattern PHONE_NUM = Pattern.compile("((\\d{11})|^((\\d{7,8})|(\\d{4}|\\d{3})-(\\d{7,8})|(\\d{4}|\\d{3})-(\\d{7,8})-(\\d{4}|\\d{3}|\\d{2}|\\d{1})|(\\d{7,8})-(\\d{4}|\\d{3}|\\d{2}|\\d{1}))$)");
|
||||
/**
|
||||
* 身份证
|
||||
*/
|
||||
private static final Pattern ID_CARD = Pattern.compile("(^\\d{15}$)|(^\\d{18}$)|(^\\d{17}(\\d|X|x)$)");
|
||||
/**
|
||||
* 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线)
|
||||
*/
|
||||
private static final Pattern ACCOUNT = Pattern.compile("^[a-zA-Z][a-zA-Z0-9_]{4,15}$");
|
||||
/**
|
||||
* 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线)
|
||||
*/
|
||||
private static final Pattern PASSWORD = Pattern.compile("^[a-zA-Z]\\w{5,17}$");
|
||||
/**
|
||||
* 强密码(必须包含大小写字母和数字的组合,可以使用特殊字符,长度在8-18之间)
|
||||
*/
|
||||
private static final Pattern PASSWORD_STRONG = Pattern.compile("^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,18}$");
|
||||
|
||||
/**
|
||||
* 正则校验正数、负数、和小数
|
||||
*
|
||||
* @param str 待校验字符串
|
||||
*/
|
||||
public static boolean checkIsNum(String str) {
|
||||
return IS_NUM.matcher(str).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 正则校验大于0的数字
|
||||
*
|
||||
* @param str 待校验字符串t
|
||||
*/
|
||||
public static boolean checkIsGt0Num(String str) {
|
||||
return IS_GT_0_NUM.matcher(str).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 正则校验大于等于0的数字
|
||||
*
|
||||
* @param str 待校验字符串
|
||||
*/
|
||||
public static boolean checkIsGtEq0Num(String str) {
|
||||
return IS_GE_EQ_0_NUM.matcher(str).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 正则校验字母或者数字组成的字符串
|
||||
*
|
||||
* @param str 待校验字符串
|
||||
*/
|
||||
public static boolean checkEnNum(String str) {
|
||||
return EN_NUM.matcher(str).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 中文、英文、数字但不包括下划线等符号
|
||||
*
|
||||
* @param str 待校验字符串
|
||||
*/
|
||||
public static boolean checkEnCnNum(String str) {
|
||||
return EN_CN_NUM.matcher(str).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* Email地址
|
||||
*
|
||||
* @param str 待校验字符串
|
||||
*/
|
||||
public static boolean checkEmail(String str) {
|
||||
return EMAIL.matcher(str).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 域名
|
||||
*
|
||||
* @param str 待校验字符串
|
||||
*/
|
||||
public static boolean checkWww(String str) {
|
||||
return WWW.matcher(str).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* InternetURL
|
||||
*
|
||||
* @param str 待校验字符串
|
||||
*/
|
||||
public static boolean checkInternetURL(String str) {
|
||||
return URL.matcher(str).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 手机号码
|
||||
*
|
||||
* @param str 待校验字符串
|
||||
*/
|
||||
public static boolean checkMobileNum(String str) {
|
||||
return MOBILE_NUM.matcher(str).matches();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 车牌号
|
||||
*
|
||||
* @param str 待校验字符串
|
||||
* @return 校验通过-true,反之-false
|
||||
*/
|
||||
public static boolean checkTruckNo(String str) {
|
||||
return TRUCK_NO.matcher(str).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 电话号码正则表达式(支持手机号码,3-4位区号,7-8位直播号码,1-4位分机号)
|
||||
*
|
||||
* @param str 待校验字符串
|
||||
*/
|
||||
public static boolean checkPhoneNum(String str) {
|
||||
return PHONE_NUM.matcher(str).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 身份证
|
||||
*
|
||||
* @param str 待校验字符串
|
||||
*/
|
||||
public static boolean checkIdCard(String str) {
|
||||
return ID_CARD.matcher(str).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线)
|
||||
*
|
||||
* @param str 待校验字符串
|
||||
*/
|
||||
public static boolean checkAccount(String str) {
|
||||
return ACCOUNT.matcher(str).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线)
|
||||
*
|
||||
* @param str 待校验字符串
|
||||
*/
|
||||
public static boolean checkPassword(String str) {
|
||||
return PASSWORD.matcher(str).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 强密码(必须包含大小写字母和数字的组合,可以使用特殊字符,长度在8-18之间)
|
||||
*
|
||||
* @param str 待校验字符串
|
||||
*/
|
||||
public static boolean checkPasswordStrong(String str) {
|
||||
return PASSWORD_STRONG.matcher(str).matches();
|
||||
}
|
||||
}
|
||||
@@ -21,9 +21,11 @@ public class ZtBusinessAutoConfiguration implements WebMvcConfigurer {
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
// 拦截所有 url,统一进行业务与文件上传请求头校验
|
||||
registry.addInterceptor(new BusinessHeaderInterceptor())
|
||||
.addPathPatterns("/**");
|
||||
.addPathPatterns("/**")
|
||||
.excludePathPatterns("/get*");
|
||||
registry.addInterceptor(new FileUploadHeaderInterceptor())
|
||||
.addPathPatterns("/**");
|
||||
.addPathPatterns("/**")
|
||||
.excludePathPatterns("/get*");
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -33,7 +33,7 @@ public class BusinessDataPermissionEntityScanner {
|
||||
*/
|
||||
private static final Set<String> EXCLUDED_PACKAGE_PREFIXES = Set.of(
|
||||
"com.zt.plat.module.backendlogistics",
|
||||
"com.zt.plat.module.erp",
|
||||
// "com.zt.plat.module.erp",
|
||||
"com.zt.plat.framework.mybatis.core.dataobject.BusinessBaseDO");
|
||||
|
||||
private final Set<String> basePackages;
|
||||
|
||||
@@ -73,7 +73,6 @@ public class DeptContextHolder {
|
||||
ROLE_CODE_LIST.remove();
|
||||
}
|
||||
|
||||
|
||||
public static void clear() {
|
||||
DEPT_ID.remove();
|
||||
COMPANY_ID.remove();
|
||||
|
||||
@@ -11,7 +11,7 @@ import static com.zt.plat.framework.web.core.util.WebFrameworkUtils.HEADER_TENAN
|
||||
*
|
||||
* Producer 发送消息时,将 {@link TenantContextHolder} 租户编号,添加到消息的 Header 中
|
||||
*
|
||||
* @author ZT
|
||||
* @author ZT TODO
|
||||
*/
|
||||
public class TenantRocketMQSendMessageHook implements SendMessageHook {
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ public interface BaseMapperX<T> extends MPJBaseMapper<T> {
|
||||
PageSumSupport.tryAttachSummary(this, queryWrapper, pageResult);
|
||||
return pageResult;
|
||||
}
|
||||
|
||||
//TODO 分页结果参考这个 ===============================
|
||||
// MyBatis Plus 查询
|
||||
IPage<T> mpPage = MyBatisUtils.buildPage(pageParam, sortingFields);
|
||||
selectPage(mpPage, queryWrapper);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<modules>
|
||||
<module>zt-module-databus-api</module>
|
||||
<module>zt-module-databus-server</module>
|
||||
<module>zt-module-databus-server-app</module>
|
||||
</modules>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
19
zt-module-databus/zt-module-databus-server-app/Dockerfile
Normal file
19
zt-module-databus/zt-module-databus-server-app/Dockerfile
Normal file
@@ -0,0 +1,19 @@
|
||||
## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性
|
||||
|
||||
FROM 172.16.46.66:10043/base-service/eclipse-temurin:21-jre
|
||||
|
||||
## 创建目录,并使用它作为工作目录
|
||||
RUN mkdir -p /zt-module-databus-server-app
|
||||
WORKDIR /zt-module-databus-server-app
|
||||
## 将后端项目的 Jar 文件,复制到镜像中
|
||||
COPY ./target/zt-module-databus-server-app.jar app.jar
|
||||
|
||||
## 设置 TZ 时区
|
||||
## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
|
||||
ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms512m -Xmx1024m"
|
||||
|
||||
## 暴露后端项目的 48080 端口
|
||||
EXPOSE 48082
|
||||
|
||||
## 启动后端项目
|
||||
CMD java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar
|
||||
48
zt-module-databus/zt-module-databus-server-app/pom.xml
Normal file
48
zt-module-databus/zt-module-databus-server-app/pom.xml
Normal file
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>zt-module-databus</artifactId>
|
||||
<groupId>com.zt.plat</groupId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<artifactId>zt-module-databus-server-app</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>${project.artifactId}</name>
|
||||
<description>
|
||||
Databus 模块启动器。
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.zt.plat</groupId>
|
||||
<artifactId>zt-module-databus-server</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<!-- 设置构建的 jar 包名 -->
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<!-- 打包 -->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal> <!-- 将引入的 jar 打入其中 -->
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -37,17 +37,11 @@ spring:
|
||||
primary: master
|
||||
datasource:
|
||||
master:
|
||||
#url: jdbc:dm://172.16.46.247:1050?schema=RUOYI-VUE-PRO
|
||||
#username: SYSDBA
|
||||
#password: pgbsci6ddJ6Sqj@e
|
||||
url: jdbc:dm://172.17.11.98:20870?schema=JYGK_TEST
|
||||
username: SYSDBA
|
||||
password: P@ssword25
|
||||
slave: # 模拟从库,可根据自己需要修改 # 模拟从库,可根据自己需要修改
|
||||
lazy: true # 开启懒加载,保证启动速度
|
||||
#url: jdbc:dm://172.16.46.247:1050?schema=RUOYI-VUE-PRO
|
||||
#username: SYSDBA
|
||||
#password: pgbsci6ddJ6Sqj@e
|
||||
url: jdbc:dm://172.17.11.98:20870?schema=JYGK_TEST
|
||||
username: SYSDBA
|
||||
password: P@ssword25
|
||||
@@ -58,8 +52,9 @@ spring:
|
||||
host: 172.16.46.63 # 地址
|
||||
port: 30379 # 端口
|
||||
database: 0 # 数据库索引
|
||||
username: zt-redis # 密码,建议生产环境开启
|
||||
username: zt-redis
|
||||
password: P@ssword25
|
||||
# password: 123456 # 密码,建议生产环境开启
|
||||
|
||||
xxl:
|
||||
job:
|
||||
@@ -192,24 +192,4 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<!-- 设置构建的 jar 包名 -->
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<!-- 打包 -->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal> <!-- 将引入的 jar 打入其中 -->
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -42,6 +42,9 @@ public class ApiClientCredentialRespVO {
|
||||
@Schema(description = "匿名访问固定用户昵称", example = "张三")
|
||||
private String anonymousUserNickname;
|
||||
|
||||
@Schema(description = "是否启用加密", example = "true")
|
||||
private Boolean enableEncryption;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
|
||||
@@ -45,4 +45,8 @@ public class ApiClientCredentialSaveReqVO {
|
||||
@Schema(description = "匿名访问固定用户 ID", example = "1024")
|
||||
private Long anonymousUserId;
|
||||
|
||||
@Schema(description = "是否启用加密", example = "true")
|
||||
@NotNull(message = "启用加密标识不能为空")
|
||||
private Boolean enableEncryption;
|
||||
|
||||
}
|
||||
|
||||
@@ -38,4 +38,6 @@ public class ApiClientCredentialDO extends BaseDO {
|
||||
|
||||
private Long anonymousUserId;
|
||||
|
||||
private Boolean enableEncryption;
|
||||
|
||||
}
|
||||
|
||||
@@ -108,7 +108,9 @@ public class GatewaySecurityFilter extends OncePerRequestFilter {
|
||||
credential = credentialService.findActiveCredential(appId)
|
||||
.orElseThrow(() -> new SecurityValidationException(HttpStatus.UNAUTHORIZED, "应用凭证不存在或已禁用"));
|
||||
boolean allowAnonymous = Boolean.TRUE.equals(credential.getAllowAnonymous());
|
||||
boolean enableEncryption = Boolean.TRUE.equals(credential.getEnableEncryption());
|
||||
ApiAnonymousUserService.AnonymousUserDetails anonymousDetails = null;
|
||||
byte[] requestBody = StreamUtils.copyToByteArray(request.getInputStream());
|
||||
if (allowAnonymous) {
|
||||
Long anonymousUserId = credential.getAnonymousUserId();
|
||||
if (anonymousUserId == null) {
|
||||
@@ -117,24 +119,25 @@ public class GatewaySecurityFilter extends OncePerRequestFilter {
|
||||
anonymousDetails = anonymousUserService.find(anonymousUserId)
|
||||
.orElseThrow(() -> new SecurityValidationException(HttpStatus.UNAUTHORIZED, "匿名访问固定用户不可用"));
|
||||
}
|
||||
|
||||
String timestampHeader = requireHeader(request, TIMESTAMP_HEADER, "缺少时间戳");
|
||||
// 校验时间戳与随机数,防止请求被重放
|
||||
validateTimestamp(timestampHeader, security);
|
||||
String nonce = requireHeader(request, NONCE_HEADER, "缺少随机数");
|
||||
if (nonce.length() < 8) {
|
||||
throw new SecurityValidationException(HttpStatus.BAD_REQUEST, "随机数长度不足");
|
||||
}
|
||||
String signature = requireHeader(request, SIGNATURE_HEADER, "缺少签名");
|
||||
if (enableEncryption){
|
||||
String nonce = requireHeader(request, NONCE_HEADER, "缺少随机数");
|
||||
if (nonce.length() < 8) {
|
||||
throw new SecurityValidationException(HttpStatus.BAD_REQUEST, "随机数长度不足");
|
||||
}
|
||||
String signature = requireHeader(request, SIGNATURE_HEADER, "缺少签名");
|
||||
|
||||
byte[] originalBody = StreamUtils.copyToByteArray(request.getInputStream());
|
||||
// 尝试按凭证配置解密请求体,并构建签名载荷进行校验
|
||||
byte[] decryptedBody = decryptRequestBody(originalBody, credential, security);
|
||||
verifySignature(request, decryptedBody, signature, credential, security, appId, timestampHeader);
|
||||
ensureNonce(tenantId, appId, nonce, security);
|
||||
// 尝试按凭证配置解密请求体,并构建签名载荷进行校验
|
||||
byte[] decryptedBody = decryptRequestBody(requestBody, credential, security);
|
||||
verifySignature(request, decryptedBody, signature, credential, security, appId, timestampHeader);
|
||||
ensureNonce(tenantId, appId, nonce, security);
|
||||
requestBody = decryptedBody;
|
||||
}
|
||||
|
||||
// 使用可重复读取的请求包装,供后续过滤器继续消费
|
||||
CachedBodyHttpServletRequest securedRequest = new CachedBodyHttpServletRequest(request, decryptedBody);
|
||||
CachedBodyHttpServletRequest securedRequest = new CachedBodyHttpServletRequest(request, requestBody);
|
||||
securedRequest.setHeader(APP_ID_HEADER, credential.getAppId());
|
||||
securedRequest.setHeader(HEADER_CREDENTIAL_ID, credential.getId() != null ? String.valueOf(credential.getId()) : null);
|
||||
ApiGatewayAccessLogger.propagateLogIdHeader(securedRequest, accessLogId);
|
||||
@@ -238,6 +241,11 @@ public class GatewaySecurityFilter extends OncePerRequestFilter {
|
||||
private byte[] decryptRequestBody(byte[] originalBody,
|
||||
ApiClientCredentialDO credential,
|
||||
ApiGatewayProperties.Security security) {
|
||||
// 检查是否启用加密,如果未启用则直接返回原文
|
||||
if (credential != null && Boolean.FALSE.equals(credential.getEnableEncryption())) {
|
||||
return originalBody != null ? originalBody : new byte[0];
|
||||
}
|
||||
|
||||
if (originalBody == null || originalBody.length == 0) {
|
||||
return new byte[0];
|
||||
}
|
||||
@@ -390,6 +398,11 @@ public class GatewaySecurityFilter extends OncePerRequestFilter {
|
||||
private void encryptResponse(ContentCachingResponseWrapper responseWrapper,
|
||||
ApiClientCredentialDO credential,
|
||||
ApiGatewayProperties.Security security) throws IOException {
|
||||
// 检查是否启用加密,如果未启用则直接返回,不加密响应
|
||||
if (credential != null && Boolean.FALSE.equals(credential.getEnableEncryption())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!security.isEncryptResponse()) {
|
||||
return;
|
||||
}
|
||||
@@ -524,6 +537,10 @@ public class GatewaySecurityFilter extends OncePerRequestFilter {
|
||||
if (security == null || credential == null) {
|
||||
return false;
|
||||
}
|
||||
// 检查是否启用加密,如果未启用则不加密错误响应
|
||||
if (Boolean.FALSE.equals(credential.getEnableEncryption())) {
|
||||
return false;
|
||||
}
|
||||
if (!security.isEncryptResponse()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -46,9 +46,9 @@ public class HttpStepHandler implements ApiStepHandler {
|
||||
private final WebClient.Builder webClientBuilder;
|
||||
private final ExpressionExecutor expressionExecutor;
|
||||
|
||||
private static final Duration RETRY_DELAY = Duration.ofMillis(200);
|
||||
private static final int RETRY_ATTEMPTS = 3;
|
||||
private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(20);
|
||||
private static final Duration RETRY_DELAY = Duration.ofSeconds(5);
|
||||
private static final int RETRY_ATTEMPTS = 5;
|
||||
private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(40);
|
||||
|
||||
private static final Set<String> DEFAULT_FORWARDED_HEADERS = Set.of(
|
||||
"authorization",
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.zt.plat.module.databus.service.gateway.impl;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
import com.zt.plat.framework.common.exception.util.ServiceExceptionUtil;
|
||||
import com.zt.plat.framework.common.pojo.PageResult;
|
||||
import com.zt.plat.framework.common.util.object.BeanUtils;
|
||||
@@ -11,14 +9,12 @@ import com.zt.plat.module.databus.dal.dataobject.gateway.ApiClientCredentialDO;
|
||||
import com.zt.plat.module.databus.dal.mysql.gateway.ApiClientCredentialMapper;
|
||||
import com.zt.plat.module.databus.service.gateway.ApiAnonymousUserService;
|
||||
import com.zt.plat.module.databus.service.gateway.ApiClientCredentialService;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
@@ -36,16 +32,6 @@ public class ApiClientCredentialServiceImpl implements ApiClientCredentialServic
|
||||
private final ApiClientCredentialMapper credentialMapper;
|
||||
private final ApiAnonymousUserService anonymousUserService;
|
||||
|
||||
private LoadingCache<String, Optional<ApiClientCredentialDO>> credentialCache;
|
||||
|
||||
@PostConstruct
|
||||
public void initCache() {
|
||||
credentialCache = Caffeine.newBuilder()
|
||||
.maximumSize(256)
|
||||
.expireAfterWrite(Duration.ofMinutes(5))
|
||||
.build(this::loadCredentialSync);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<ApiClientCredentialDO> getPage(ApiClientCredentialPageReqVO reqVO) {
|
||||
return credentialMapper.selectPage(reqVO);
|
||||
@@ -67,7 +53,6 @@ public class ApiClientCredentialServiceImpl implements ApiClientCredentialServic
|
||||
credential.setAnonymousUserId(null);
|
||||
}
|
||||
credentialMapper.insert(credential);
|
||||
invalidateCache(credential.getAppId());
|
||||
return credential.getId();
|
||||
}
|
||||
|
||||
@@ -86,8 +71,6 @@ public class ApiClientCredentialServiceImpl implements ApiClientCredentialServic
|
||||
updateObj.setAnonymousUserId(null);
|
||||
}
|
||||
credentialMapper.updateById(updateObj);
|
||||
invalidateCache(existing.getAppId());
|
||||
invalidateCache(updateObj.getAppId());
|
||||
if (!Objects.equals(existing.getAnonymousUserId(), updateObj.getAnonymousUserId())) {
|
||||
anonymousUserService.invalidate(existing.getAnonymousUserId());
|
||||
anonymousUserService.invalidate(updateObj.getAnonymousUserId());
|
||||
@@ -99,7 +82,6 @@ public class ApiClientCredentialServiceImpl implements ApiClientCredentialServic
|
||||
public void delete(Long id) {
|
||||
ApiClientCredentialDO existing = ensureExists(id);
|
||||
credentialMapper.deleteById(id);
|
||||
invalidateCache(existing.getAppId());
|
||||
anonymousUserService.invalidate(existing.getAnonymousUserId());
|
||||
}
|
||||
|
||||
@@ -118,11 +100,7 @@ public class ApiClientCredentialServiceImpl implements ApiClientCredentialServic
|
||||
if (!StringUtils.hasText(appId)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return credentialCache.get(appId.trim());
|
||||
}
|
||||
|
||||
private Optional<ApiClientCredentialDO> loadCredentialSync(String appId) {
|
||||
Optional<ApiClientCredentialDO> credential = credentialMapper.selectByAppId(appId)
|
||||
Optional<ApiClientCredentialDO> credential = credentialMapper.selectByAppId(appId.trim())
|
||||
.filter(item -> Boolean.TRUE.equals(item.getEnabled()));
|
||||
if (credential.isEmpty()) {
|
||||
log.debug("[API-PORTAL] 未找到 appId={} 的有效凭证", appId);
|
||||
@@ -147,13 +125,6 @@ public class ApiClientCredentialServiceImpl implements ApiClientCredentialServic
|
||||
return credential;
|
||||
}
|
||||
|
||||
private void invalidateCache(String appId) {
|
||||
if (!StringUtils.hasText(appId)) {
|
||||
return;
|
||||
}
|
||||
credentialCache.invalidate(appId.trim());
|
||||
}
|
||||
|
||||
private void normalizeAnonymousSettings(ApiClientCredentialSaveReqVO reqVO) {
|
||||
if (Boolean.TRUE.equals(reqVO.getAllowAnonymous())) {
|
||||
if (reqVO.getAnonymousUserId() == null) {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<modules>
|
||||
<module>zt-module-infra-api</module>
|
||||
<module>zt-module-infra-server</module>
|
||||
<module>zt-module-infra-server-app</module>
|
||||
</modules>
|
||||
<artifactId>zt-module-infra</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
@@ -34,4 +34,7 @@ public class FileRespDTO {
|
||||
@Schema(description = "文件内容", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private byte[] content;
|
||||
|
||||
@Schema(description = "文件下载次数")
|
||||
private Integer downloadCount;
|
||||
|
||||
}
|
||||
@@ -3,10 +3,10 @@
|
||||
FROM 172.16.46.66:10043/base-service/eclipse-temurin:21-jre
|
||||
|
||||
## 创建目录,并使用它作为工作目录
|
||||
RUN mkdir -p /zt-module-infra-server
|
||||
WORKDIR /zt-module-infra-server
|
||||
RUN mkdir -p /zt-module-infra-server-app
|
||||
WORKDIR /zt-module-infra-server-app
|
||||
## 将后端项目的 Jar 文件,复制到镜像中
|
||||
COPY ./target/zt-module-infra-server.jar app.jar
|
||||
COPY ./target/zt-module-infra-server-app.jar app.jar
|
||||
|
||||
## 设置 TZ 时区
|
||||
## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
|
||||
48
zt-module-infra/zt-module-infra-server-app/pom.xml
Normal file
48
zt-module-infra/zt-module-infra-server-app/pom.xml
Normal file
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>zt-module-infra</artifactId>
|
||||
<groupId>com.zt.plat</groupId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<artifactId>zt-module-infra-server-app</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>${project.artifactId}</name>
|
||||
<description>
|
||||
infra 模块启动器。
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.zt.plat</groupId>
|
||||
<artifactId>zt-module-infra-server</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<!-- 设置构建的 jar 包名 -->
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<!-- 打包 -->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal> <!-- 将引入的 jar 打入其中 -->
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -149,24 +149,5 @@
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<!-- 设置构建的 jar 包名 -->
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<!-- 打包 -->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal> <!-- 将引入的 jar 打入其中 -->
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -133,6 +133,10 @@ public class FileController {
|
||||
response.setStatus(HttpStatus.NOT_FOUND.value());
|
||||
return;
|
||||
}
|
||||
|
||||
// 统计下载次数
|
||||
fileService.incDownloadCount(configId,path);
|
||||
|
||||
writeAttachment(response, path, content);
|
||||
}
|
||||
|
||||
|
||||
@@ -99,4 +99,7 @@ public class FileRespVO {
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "下载次数")
|
||||
private Integer downloadCount;
|
||||
|
||||
}
|
||||
|
||||
@@ -65,6 +65,11 @@ public class FileDO extends BaseDO {
|
||||
*/
|
||||
private String aesIv;
|
||||
|
||||
/**
|
||||
* 文件下载次数统计
|
||||
*/
|
||||
private Integer downloadCount;
|
||||
|
||||
/**
|
||||
* 是否加密
|
||||
* <p>
|
||||
|
||||
@@ -6,6 +6,8 @@ import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.zt.plat.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
||||
import com.zt.plat.module.infra.dal.dataobject.file.FileDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
|
||||
/**
|
||||
* 文件操作 Mapper
|
||||
@@ -32,4 +34,7 @@ public interface FileMapper extends BaseMapperX<FileDO> {
|
||||
return selectFirstOne(FileDO::getHash, hash);
|
||||
}
|
||||
|
||||
|
||||
@Update("UPDATE INFRA_FILE SET DOWNLOAD_COUNT = DOWNLOAD_COUNT + 1 WHERE CONFIG_ID = #{configId} AND PATH = #{path}")
|
||||
int incDownloadCount(@Param("configId") Long configId, @Param("path") String path);
|
||||
}
|
||||
|
||||
@@ -112,4 +112,11 @@ public interface FileService {
|
||||
FileDO getActiveFileById(Long fileId);
|
||||
|
||||
boolean verifyCode(Long fileId, Long userId, String code) throws Exception;
|
||||
|
||||
/**
|
||||
* 更新文件下载次数
|
||||
* @param configId
|
||||
* @param path
|
||||
*/
|
||||
void incDownloadCount(Long configId, String path);
|
||||
}
|
||||
|
||||
@@ -334,4 +334,9 @@ public class FileServiceImpl implements FileService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incDownloadCount(Long configId, String path) {
|
||||
fileMapper.incDownloadCount(configId, path);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<modules>
|
||||
<module>zt-module-report-api</module>
|
||||
<module>zt-module-report-server</module>
|
||||
<module>zt-module-report-server-app</module>
|
||||
</modules>
|
||||
<artifactId>zt-module-report</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
FROM 172.16.46.66:10043/base-service/eclipse-temurin:21-jre
|
||||
|
||||
## 创建目录,并使用它作为工作目录
|
||||
RUN mkdir -p /zt-module-report-server
|
||||
WORKDIR /zt-module-report-server
|
||||
RUN mkdir -p /zt-module-report-server-app
|
||||
WORKDIR /zt-module-report-server-app
|
||||
## 将后端项目的 Jar 文件,复制到镜像中
|
||||
COPY ./target/zt-module-report-server.jar app.jar
|
||||
COPY ./target/zt-module-report-server-app.jar app.jar
|
||||
|
||||
## 设置 TZ 时区
|
||||
## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
|
||||
48
zt-module-report/zt-module-report-server-app/pom.xml
Normal file
48
zt-module-report/zt-module-report-server-app/pom.xml
Normal file
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>zt-module-report</artifactId>
|
||||
<groupId>com.zt.plat</groupId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<artifactId>zt-module-report-server-app</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>${project.artifactId}</name>
|
||||
<description>
|
||||
report 模块启动器。
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.zt.plat</groupId>
|
||||
<artifactId>zt-module-report-server</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<!-- 设置构建的 jar 包名 -->
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<!-- 打包 -->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal> <!-- 将引入的 jar 打入其中 -->
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -111,23 +111,4 @@
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<!-- 设置构建的 jar 包名 -->
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<!-- 打包 -->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal> <!-- 将引入的 jar 打入其中 -->
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<modules>
|
||||
<module>zt-module-system-api</module>
|
||||
<module>zt-module-system-server</module>
|
||||
<module>zt-module-system-server-app</module>
|
||||
</modules>
|
||||
<artifactId>zt-module-system</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.zt.plat.module.system.api.dept.dto;
|
||||
|
||||
import com.zt.plat.framework.common.enums.CommonStatusEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 公司部门推送消息 Response DTO
|
||||
*
|
||||
* @author ZT
|
||||
*/
|
||||
@Schema(description = "RPC 服务 - 部门推送消息 Response DTO")
|
||||
@Data
|
||||
public class DeptMsgRespDTO {
|
||||
|
||||
|
||||
/**
|
||||
* 主键编号
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 本系统部门 ID
|
||||
*/
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 外部系统标识
|
||||
*/
|
||||
private String systemCode;
|
||||
|
||||
/**
|
||||
* 外部系统组织编码
|
||||
*/
|
||||
private String externalDeptCode;
|
||||
|
||||
/**
|
||||
* 外部系统组织名称
|
||||
*/
|
||||
private String externalDeptName;
|
||||
|
||||
/**
|
||||
* 映射状态
|
||||
* 枚举 {@link CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 是否发送消息
|
||||
*/
|
||||
private Integer isSendMsg;
|
||||
|
||||
}
|
||||
@@ -2,23 +2,27 @@ package com.zt.plat.module.system.api.esp;
|
||||
|
||||
import com.zt.plat.framework.common.pojo.CommonResult;
|
||||
import com.zt.plat.module.system.api.dept.dto.*;
|
||||
import com.zt.plat.module.system.api.esp.dto.EspDto;
|
||||
import com.zt.plat.module.system.enums.ApiConstants;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@FeignClient(name = ApiConstants.NAME)
|
||||
@Tag(name = "RPC 服务 - 部门")
|
||||
@Tag(name = "RPC 服务 - 部门推送消息")
|
||||
public interface EspApi {
|
||||
|
||||
String PREFIX = ApiConstants.PREFIX + "/dept";
|
||||
String PREFIX = ApiConstants.PREFIX + "/dept-esp";
|
||||
|
||||
|
||||
@PostMapping(PREFIX + "/create")
|
||||
@Operation(summary = "新增部门")
|
||||
CommonResult<Long> createDept(@RequestBody DeptSaveReqDTO createReqVO);
|
||||
|
||||
|
||||
@PostMapping(PREFIX + "/pushMsg")
|
||||
@Operation(summary = "推送消息")
|
||||
CommonResult<List<EspDto>> pushMsg(@RequestBody DeptSaveReqDTO syncReqDTO);
|
||||
@Operation(summary = "查询部门消息")
|
||||
CommonResult<List<DeptMsgRespDTO>> selectDepMsg(@RequestBody DeptSaveReqDTO syncReqDTO);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.zt.plat.module.system.api.msg;
|
||||
|
||||
import com.zt.plat.framework.common.pojo.CommonResult;
|
||||
import com.zt.plat.module.system.api.sms.dto.log.SmsLogRespDTO;
|
||||
import com.zt.plat.module.system.api.sms.dto.send.SmsSendSingleToUserReqDTO;
|
||||
import com.zt.plat.module.system.enums.ApiConstants;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
|
||||
@FeignClient(name = ApiConstants.NAME)
|
||||
@Tag(name = "RPC 服务 - 消息发送")
|
||||
public interface MsgSendApi {
|
||||
|
||||
String PREFIX = ApiConstants.PREFIX + "/msg/send";
|
||||
|
||||
@PostMapping(PREFIX + "/sendTextMsg")
|
||||
@Operation(summary = "发送企业微信文本消息", description = "在 mobile 为空时,使用 userId 加载对应 Admin 的手机号")
|
||||
CommonResult<Long> sendTextMsg(@Valid @RequestBody SmsSendSingleToUserReqDTO reqDTO);
|
||||
|
||||
@PostMapping(PREFIX + "/sendImageMsg")
|
||||
@Operation(summary = "发送企业微信图片消息", description = "在 mobile 为空时,使用 userId 加载对应 Member 的手机号")
|
||||
CommonResult<Long> sendImageMsg(@Valid @RequestBody SmsSendSingleToUserReqDTO reqDTO);
|
||||
|
||||
@GetMapping(PREFIX + "/sendVoiceMsg")
|
||||
@Operation(summary = "发送企业微信语音消息")
|
||||
CommonResult<SmsLogRespDTO> getSmsLog(@RequestParam("id") Long id);
|
||||
|
||||
@PostMapping(PREFIX + "/sendVideoMsg")
|
||||
@Operation(summary = "发送企业微信视频消息", description = "在 mobile 为空时,使用 userId 加载对应 Admin 的手机号")
|
||||
CommonResult<Long> sendVideoMsg(@Valid @RequestBody SmsSendSingleToUserReqDTO reqDTO);
|
||||
|
||||
@PostMapping(PREFIX + "/sendFileMsg")
|
||||
@Operation(summary = "发送企业微信文件消息", description = "在 mobile 为空时,使用 userId 加载对应 Member 的手机号")
|
||||
CommonResult<Long> sendFileMsg(@Valid @RequestBody SmsSendSingleToUserReqDTO reqDTO);
|
||||
|
||||
@GetMapping(PREFIX + "/sendTextCardMsg")
|
||||
@Operation(summary = "发送企业微信文本卡片消息")
|
||||
CommonResult<SmsLogRespDTO> sendTextCardMsg(@RequestParam("id") Long id);
|
||||
|
||||
@PostMapping(PREFIX + "/sendTextCardMsgPich01")
|
||||
@Operation(summary = "发送企业微信文本卡片消息 -物资存货智能管理 预警信息", description = "在 mobile 为空时,使用 userId 加载对应 Admin 的手机号")
|
||||
CommonResult<Long> sendTextCardMsgPich01(@Valid @RequestBody SmsSendSingleToUserReqDTO reqDTO);
|
||||
|
||||
@PostMapping(PREFIX + "/sendNewsMsg")
|
||||
@Operation(summary = "发送企业微信图文消息", description = "在 mobile 为空时,使用 userId 加载对应 Member 的手机号")
|
||||
CommonResult<Long> sendNewsMsg(@Valid @RequestBody SmsSendSingleToUserReqDTO reqDTO);
|
||||
|
||||
@GetMapping(PREFIX + "/sendMpNewsMsg")
|
||||
@Operation(summary = "发送企业微信图文消息(mpnews)")
|
||||
CommonResult<SmsLogRespDTO> sendMpNewsMsg(@RequestParam("id") Long id);
|
||||
|
||||
@PostMapping(PREFIX + "/sendMarkdownMsg")
|
||||
@Operation(summary = "发送企业微信小程序通知消息", description = "在 mobile 为空时,使用 userId 加载对应 Admin 的手机号")
|
||||
CommonResult<Long> sendMarkdownMsg(@Valid @RequestBody SmsSendSingleToUserReqDTO reqDTO);
|
||||
|
||||
@PostMapping(PREFIX + "/sendMiniProgramNoticeMsg")
|
||||
@Operation(summary = "发送企业微信图片消息", description = "在 mobile 为空时,使用 userId 加载对应 Member 的手机号")
|
||||
CommonResult<Long> sendMiniProgramNoticeMsg(@Valid @RequestBody SmsSendSingleToUserReqDTO reqDTO);
|
||||
|
||||
@GetMapping(PREFIX + "/sendInteractiveTaskCardMsg")
|
||||
@Operation(summary = "发送企业微信任务卡片消息")
|
||||
CommonResult<SmsLogRespDTO> sendInteractiveTaskCardMsg(@RequestParam("id") Long id);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.zt.plat.module.system.api.sms.dto.code;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class User implements Serializable {
|
||||
/**
|
||||
* 返回码
|
||||
*/
|
||||
private Integer errcode;
|
||||
/**
|
||||
* 对返回码的文本描述内容
|
||||
*/
|
||||
private String errmsg;
|
||||
|
||||
/**
|
||||
* 成员UserID
|
||||
*/
|
||||
private String UserId;
|
||||
|
||||
/**
|
||||
* 手机设备号(由中铝集团在安装时随机生成,删除重装会改变,升级不受影响)
|
||||
*/
|
||||
private String DeviceId;
|
||||
|
||||
/**
|
||||
* 成员身份信息,2:超级管理员, 4:分级管理员,5:普通成员
|
||||
*/
|
||||
private Integer usertype;
|
||||
|
||||
|
||||
/**
|
||||
* 判断受否授权成功
|
||||
*
|
||||
* @return true-授权成功、false-授权失败
|
||||
*/
|
||||
public boolean isAuthorized() {
|
||||
return this.getErrcode() == 0;
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import com.zt.plat.framework.common.validation.Mobile;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Schema(description = "RPC 服务 - 短信发送给 Admin 或者 Member 用户 Request DTO")
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.fhs.core.trans.vo.VO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -20,6 +21,12 @@ public class AdminUserRespDTO implements VO {
|
||||
@Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "小王")
|
||||
private String nickname;
|
||||
|
||||
@Schema(description = "工号", example = "A00123")
|
||||
private String workcode;
|
||||
|
||||
@Schema(description = "备注", example = "我是一个用户")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "租户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long tenantId;
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ public class ApiConstants {
|
||||
|
||||
/**
|
||||
* 服务名
|
||||
*
|
||||
* 注意,需要保证和 spring.application.name 保持一致
|
||||
*/
|
||||
public static final String NAME = "system-server";
|
||||
|
||||
@@ -108,6 +108,9 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode SMS_CHANNEL_DISABLE = new ErrorCode(1_002_011_001, "短信渠道不处于开启状态,不允许选择");
|
||||
ErrorCode SMS_CHANNEL_HAS_CHILDREN = new ErrorCode(1_002_011_002, "无法删除,该短信渠道还有短信模板");
|
||||
ErrorCode SMS_CHANNEL_BALANCE_UNSUPPORTED = new ErrorCode(1_002_011_003, "该短信渠道不支持余额查询");
|
||||
ErrorCode MSG_CHANNEL_NOT_EXISTS = new ErrorCode(1_002_011_004, "消息渠道不存在");
|
||||
|
||||
|
||||
|
||||
// ========== 短信模板 1-002-012-000 ==========
|
||||
ErrorCode SMS_TEMPLATE_NOT_EXISTS = new ErrorCode(1_002_012_000, "短信模板不存在");
|
||||
@@ -122,6 +125,7 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode SMS_SEND_MOBILE_TEMPLATE_PARAM_MISS = new ErrorCode(1_002_013_001, "模板参数({})缺失");
|
||||
ErrorCode SMS_SEND_TEMPLATE_NOT_EXISTS = new ErrorCode(1_002_013_002, "短信模板不存在");
|
||||
ErrorCode SMS_CALLBACK_SIGN_INVALID = new ErrorCode(1_002_013_100, "短信回调签名校验失败");
|
||||
ErrorCode MSG_CALLBACK_SIGN_INVALID = new ErrorCode(1_002_013_101, "消息回调签名校验失败");
|
||||
|
||||
// ========== 短信验证码 1-002-014-000 ==========
|
||||
ErrorCode SMS_CODE_NOT_FOUND = new ErrorCode(1_002_014_000, "验证码不存在");
|
||||
@@ -206,6 +210,8 @@ public interface ErrorCodeConstants {
|
||||
// ========== 用户与部门关系 1-002-029-000 ==========
|
||||
ErrorCode USER_DEPT_NOT_EXISTS = new ErrorCode(1_002_029_000, "用户与部门关系不存在");
|
||||
|
||||
ErrorCode USER_DEPT_SAVE_EXISTS = new ErrorCode(1_002_029_001, "插入用户部门失败");
|
||||
|
||||
// ========== 系统序列号分段明细 1-002-030-000 ==========
|
||||
ErrorCode SEQUENCE_DETAIL_NOT_EXISTS = new ErrorCode(1_002_030_000, "系统序列号分段明细不存在");
|
||||
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
FROM 172.16.46.66:10043/base-service/eclipse-temurin:21-jre
|
||||
|
||||
## 创建目录,并使用它作为工作目录
|
||||
RUN mkdir -p /zt-module-system-server
|
||||
WORKDIR /zt-module-system-server
|
||||
RUN mkdir -p /zt-module-system-server-app
|
||||
WORKDIR /zt-module-system-server-app
|
||||
## 将后端项目的 Jar 文件,复制到镜像中
|
||||
COPY ./target/zt-module-system-server.jar app.jar
|
||||
COPY ./target/zt-module-system-server-app.jar app.jar
|
||||
|
||||
## 设置 TZ 时区
|
||||
## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
|
||||
48
zt-module-system/zt-module-system-server-app/pom.xml
Normal file
48
zt-module-system/zt-module-system-server-app/pom.xml
Normal file
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>zt-module-system</artifactId>
|
||||
<groupId>com.zt.plat</groupId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<artifactId>zt-module-system-server-app</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>${project.artifactId}</name>
|
||||
<description>
|
||||
system 模块启动器。
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.zt.plat</groupId>
|
||||
<artifactId>zt-module-system-server</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<!-- 设置构建的 jar 包名 -->
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<!-- 打包 -->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal> <!-- 将引入的 jar 打入其中 -->
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -103,4 +103,8 @@
|
||||
</root>
|
||||
</springProfile>
|
||||
|
||||
<!-- <logger name="com.zt.plat.module.system.dal" level="DEBUG" additivity="false">-->
|
||||
<!-- <appender-ref ref="STDOUT"/>-->
|
||||
<!-- </logger>-->
|
||||
|
||||
</configuration>
|
||||
@@ -200,26 +200,14 @@
|
||||
<artifactId>hutool-all</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-text</artifactId>
|
||||
<version>1.13.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<!-- 设置构建的 jar 包名 -->
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<!-- 打包 -->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal> <!-- 将引入的 jar 打入其中 -->
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -41,7 +41,7 @@ public class DatabusDeptProviderApiImpl implements DatabusDeptProviderApi {
|
||||
public CommonResult<CursorPageResult<DatabusDeptData>> getPageByCursor(CursorPageReqDTO reqDTO) {
|
||||
// 构建游标查询条件
|
||||
LambdaQueryWrapper<DeptDO> queryWrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
queryWrapper.eq(DeptDO::getDeptSource, 3);
|
||||
// 游标条件:create_time > cursorTime OR (create_time = cursorTime AND id > cursorId)
|
||||
if (!reqDTO.isFirstPage()) {
|
||||
queryWrapper.and(w -> w
|
||||
@@ -105,6 +105,7 @@ public class DatabusDeptProviderApiImpl implements DatabusDeptProviderApi {
|
||||
Long total = null;
|
||||
if (reqDTO.isFirstPage()) {
|
||||
LambdaQueryWrapper<DeptDO> countWrapper = new LambdaQueryWrapper<>();
|
||||
countWrapper.eq(DeptDO::getDeptSource, 3);
|
||||
if (reqDTO.getTenantId() != null) {
|
||||
countWrapper.eq(DeptDO::getTenantId, reqDTO.getTenantId());
|
||||
}
|
||||
@@ -175,6 +176,8 @@ public class DatabusDeptProviderApiImpl implements DatabusDeptProviderApi {
|
||||
@Override
|
||||
public CommonResult<Long> count(Long tenantId) {
|
||||
LambdaQueryWrapper<DeptDO> queryWrapper = new LambdaQueryWrapper<>();
|
||||
// ⚠️ 只统计 userSource = 3 的用户
|
||||
queryWrapper.eq(DeptDO::getDeptSource, 3);
|
||||
if (tenantId != null) {
|
||||
queryWrapper.eq(DeptDO::getTenantId, tenantId);
|
||||
}
|
||||
|
||||
@@ -54,8 +54,8 @@ public class DatabusUserProviderApiImpl implements DatabusUserProviderApi {
|
||||
// 构建游标查询条件
|
||||
LambdaQueryWrapper<AdminUserDO> queryWrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
// ⚠️ 只同步 userSource = 2 的用户
|
||||
queryWrapper.eq(AdminUserDO::getUserSource, 2);
|
||||
// ⚠️ 只同步 userSource = 3 的用户
|
||||
queryWrapper.eq(AdminUserDO::getUserSource, 3);
|
||||
|
||||
// 游标条件:create_time > cursorTime OR (create_time = cursorTime AND id > cursorId)
|
||||
if (!reqDTO.isFirstPage()) {
|
||||
@@ -103,8 +103,8 @@ public class DatabusUserProviderApiImpl implements DatabusUserProviderApi {
|
||||
Long total = null;
|
||||
if (reqDTO.isFirstPage()) {
|
||||
LambdaQueryWrapper<AdminUserDO> countWrapper = new LambdaQueryWrapper<>();
|
||||
// ⚠️ 只统计 userSource = 2 的用户
|
||||
countWrapper.eq(AdminUserDO::getUserSource, 2);
|
||||
// ⚠️ 只统计 userSource = 3 的用户
|
||||
countWrapper.eq(AdminUserDO::getUserSource, 3);
|
||||
if (reqDTO.getTenantId() != null) {
|
||||
countWrapper.eq(AdminUserDO::getTenantId, reqDTO.getTenantId());
|
||||
}
|
||||
@@ -148,8 +148,8 @@ public class DatabusUserProviderApiImpl implements DatabusUserProviderApi {
|
||||
@Override
|
||||
public CommonResult<Long> count(Long tenantId) {
|
||||
LambdaQueryWrapper<AdminUserDO> queryWrapper = new LambdaQueryWrapper<>();
|
||||
// ⚠️ 只统计 userSource = 2 的用户
|
||||
queryWrapper.eq(AdminUserDO::getUserSource, 2);
|
||||
// ⚠️ 只统计 userSource = 3 的用户
|
||||
queryWrapper.eq(AdminUserDO::getUserSource, 3);
|
||||
if (tenantId != null) {
|
||||
queryWrapper.eq(AdminUserDO::getTenantId, tenantId);
|
||||
}
|
||||
|
||||
@@ -2,15 +2,17 @@ package com.zt.plat.module.system.api.esp;
|
||||
|
||||
import com.zt.plat.framework.common.exception.enums.GlobalErrorCodeConstants;
|
||||
import com.zt.plat.framework.common.pojo.CommonResult;
|
||||
import com.zt.plat.framework.common.util.object.ObjectUtils;
|
||||
import com.zt.plat.framework.common.util.object.BeanUtils;
|
||||
import com.zt.plat.module.system.api.dept.dto.DeptMsgRespDTO;
|
||||
import com.zt.plat.module.system.api.dept.dto.DeptSaveReqDTO;
|
||||
import com.zt.plat.module.system.api.esp.dto.EspDto;
|
||||
import com.zt.plat.module.system.controller.admin.dept.vo.dept.DeptSaveReqVO;
|
||||
import com.zt.plat.module.system.service.dept.IEspService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import static com.zt.plat.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@RestController
|
||||
@Validated
|
||||
@@ -18,16 +20,26 @@ public class EspApiImpl implements EspApi {
|
||||
|
||||
|
||||
@Resource
|
||||
private IEspService deptService;
|
||||
private IEspService espService;
|
||||
|
||||
|
||||
@Override
|
||||
public CommonResult<List<EspDto>> pushMsg(DeptSaveReqDTO syncReqDTO)
|
||||
public CommonResult<Long> createDept(DeptSaveReqDTO createReqVO) {
|
||||
DeptSaveReqVO reqVO = BeanUtils.toBean(createReqVO, DeptSaveReqVO.class);
|
||||
Long deptId = espService.createDept(reqVO);
|
||||
return success(deptId);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CommonResult<List<DeptMsgRespDTO>> selectDepMsg(DeptSaveReqDTO syncReqDTO)
|
||||
{
|
||||
if(Objects.isNull(syncReqDTO) || null == syncReqDTO.getId())
|
||||
{
|
||||
return CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),
|
||||
"ID不能为空");
|
||||
}
|
||||
return CommonResult.success(deptService.pushMsg(syncReqDTO));
|
||||
return espService.selectDepMsg(syncReqDTO);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.zt.plat.module.system.api.msg;
|
||||
|
||||
import com.zt.plat.framework.common.pojo.CommonResult;
|
||||
import com.zt.plat.framework.common.util.object.BeanUtils;
|
||||
import com.zt.plat.module.system.api.sms.dto.log.SmsLogRespDTO;
|
||||
import com.zt.plat.module.system.api.sms.dto.send.SmsSendSingleToUserReqDTO;
|
||||
import com.zt.plat.module.system.service.sms.SmsLogService;
|
||||
import com.zt.plat.module.system.service.sms.SmsSendService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import static com.zt.plat.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@RestController
|
||||
@Validated
|
||||
public class MsgSendApiImpl implements MsgSendApi {
|
||||
|
||||
@Resource
|
||||
private SmsSendService smsSendService;
|
||||
@Resource
|
||||
private SmsLogService smsLogService;
|
||||
|
||||
|
||||
@Override
|
||||
public CommonResult<Long> sendTextMsg(SmsSendSingleToUserReqDTO reqDTO) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Long> sendImageMsg(SmsSendSingleToUserReqDTO reqDTO) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<SmsLogRespDTO> getSmsLog(Long id) {
|
||||
return success(BeanUtils.toBean(smsLogService.getSmsLog(id), SmsLogRespDTO.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Long> sendVideoMsg(SmsSendSingleToUserReqDTO reqDTO) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Long> sendFileMsg(SmsSendSingleToUserReqDTO reqDTO) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<SmsLogRespDTO> sendTextCardMsg(Long id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Long> sendTextCardMsgPich01(SmsSendSingleToUserReqDTO reqDTO) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Long> sendNewsMsg(SmsSendSingleToUserReqDTO reqDTO) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<SmsLogRespDTO> sendMpNewsMsg(Long id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Long> sendMarkdownMsg(SmsSendSingleToUserReqDTO reqDTO) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Long> sendMiniProgramNoticeMsg(SmsSendSingleToUserReqDTO reqDTO) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<SmsLogRespDTO> sendInteractiveTaskCardMsg(Long id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import com.zt.plat.module.system.controller.admin.auth.vo.*;
|
||||
import com.zt.plat.module.system.convert.auth.AuthConvert;
|
||||
import com.zt.plat.module.system.dal.dataobject.permission.MenuDO;
|
||||
import com.zt.plat.module.system.dal.dataobject.permission.RoleDO;
|
||||
import com.zt.plat.module.system.dal.dataobject.permission.RoleMenuDO;
|
||||
import com.zt.plat.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import com.zt.plat.module.system.enums.logger.LoginLogTypeEnum;
|
||||
import com.zt.plat.module.system.service.auth.AdminAuthService;
|
||||
@@ -33,7 +34,9 @@ import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.zt.plat.framework.common.pojo.CommonResult.success;
|
||||
@@ -126,7 +129,18 @@ public class AuthController {
|
||||
// 1.3 获得菜单列表
|
||||
Set<Long> menuIds = permissionService.getRoleMenuListByRoleId(convertSet(roles, RoleDO::getId));
|
||||
List<MenuDO> menuList = menuService.getMenuList(menuIds);
|
||||
Set<RoleMenuDO> roleMenuList = permissionService.getByRoleIdAndMenuIds(roleIds, menuIds);
|
||||
Map<Long, RoleMenuDO> roleMenuMap = new HashMap<>(roleMenuList.size());
|
||||
for (RoleMenuDO roleMenu : roleMenuList) {
|
||||
roleMenuMap.put(roleMenu.getMenuId(), roleMenu);
|
||||
}
|
||||
menuList = menuService.filterDisableMenus(menuList);
|
||||
for (MenuDO menu : menuList) {
|
||||
RoleMenuDO roleMenu = roleMenuMap.get(menu.getId());
|
||||
if (roleMenu != null && roleMenu.getShowMenu() != null && !roleMenu.getShowMenu()) {
|
||||
menu.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 拼接结果返回
|
||||
return success(AuthConvert.INSTANCE.convert(user, roles, menuList));
|
||||
|
||||
@@ -123,7 +123,7 @@ public class DeptController {
|
||||
|
||||
@GetMapping("/top-level-list")
|
||||
@Operation(summary = "获取当前用户可访问的顶级部门列表", description = "用于懒加载,返回当前用户所属部门的最顶层祖先部门,如果用户没有关联任何部门则返回空列表")
|
||||
@PreAuthorize("@ss.hasPermission('system:dept:query')")
|
||||
// @PreAuthorize("@ss.hasPermission('system:dept:query')")
|
||||
public CommonResult<List<DeptRespVO>> getTopLevelDeptList() {
|
||||
List<DeptDO> list = deptService.getTopLevelDeptList();
|
||||
return success(BeanUtils.toBean(list, DeptRespVO.class));
|
||||
|
||||
@@ -6,11 +6,13 @@ import com.zt.plat.framework.common.enums.CommonStatusEnum;
|
||||
import com.zt.plat.framework.common.pojo.CommonResult;
|
||||
import com.zt.plat.framework.common.util.collection.CollectionUtils;
|
||||
import com.zt.plat.module.system.controller.admin.permission.vo.permission.PermissionAssignRoleDataScopeReqVO;
|
||||
import com.zt.plat.module.system.controller.admin.permission.vo.permission.PermissionAssignRoleMenuItemReqVO;
|
||||
import com.zt.plat.module.system.controller.admin.permission.vo.permission.PermissionAssignRoleMenuReqVO;
|
||||
import com.zt.plat.module.system.controller.admin.permission.vo.permission.PermissionAssignUserRoleReqVO;
|
||||
import com.zt.plat.module.system.controller.admin.permission.vo.permission.PermissionUserSupervisionRespVO;
|
||||
import com.zt.plat.module.system.dal.dataobject.permission.MenuDO;
|
||||
import com.zt.plat.module.system.dal.dataobject.permission.RoleDO;
|
||||
import com.zt.plat.module.system.dal.dataobject.permission.RoleMenuDO;
|
||||
import com.zt.plat.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import com.zt.plat.module.system.enums.permission.MenuTypeEnum;
|
||||
import com.zt.plat.module.system.service.permission.MenuService;
|
||||
@@ -57,8 +59,16 @@ public class PermissionController {
|
||||
@Parameter(name = "roleId", description = "角色编号", required = true)
|
||||
@GetMapping("/list-role-menus")
|
||||
@PreAuthorize("@ss.hasPermission('system:permission:assign-role-menu')")
|
||||
public CommonResult<Set<Long>> getRoleMenuList(Long roleId) {
|
||||
return success(permissionService.getRoleMenuListByRoleId(roleId));
|
||||
public CommonResult<Set<PermissionAssignRoleMenuItemReqVO>> getRoleMenuList(Long roleId) {
|
||||
Set<Long> menuIds = permissionService.getRoleMenuListByRoleId(roleId);
|
||||
Set<RoleMenuDO> menuList = permissionService.getByRoleIdAndMenuIds(Collections.singleton(roleId), menuIds);
|
||||
Set<PermissionAssignRoleMenuItemReqVO> result = menuList.stream().map(menu -> {
|
||||
PermissionAssignRoleMenuItemReqVO reqVO = new PermissionAssignRoleMenuItemReqVO();
|
||||
reqVO.setId(menu.getMenuId());
|
||||
reqVO.setShowMenu(menu.getShowMenu());
|
||||
return reqVO;
|
||||
}).collect(Collectors.toSet());
|
||||
return success(result);
|
||||
}
|
||||
|
||||
@PostMapping("/assign-role-menu")
|
||||
@@ -66,10 +76,13 @@ public class PermissionController {
|
||||
@PreAuthorize("@ss.hasPermission('system:permission:assign-role-menu')")
|
||||
public CommonResult<Boolean> assignRoleMenu(@Validated @RequestBody PermissionAssignRoleMenuReqVO reqVO) {
|
||||
// 开启多租户的情况下,需要过滤掉未开通的菜单
|
||||
tenantService.handleTenantMenu(menuIds -> reqVO.getMenuIds().removeIf(menuId -> !CollUtil.contains(menuIds, menuId)));
|
||||
tenantService.handleTenantMenu(menuIds -> reqVO.getMenus().removeIf(menu -> !CollUtil.contains(menuIds, menu.getId())));
|
||||
|
||||
// 执行菜单的分配
|
||||
permissionService.assignRoleMenu(reqVO.getRoleId(), reqVO.getMenuIds());
|
||||
permissionService.assignRoleMenu(reqVO.getRoleId(), reqVO.getMenus().stream().map(PermissionAssignRoleMenuItemReqVO::getId).collect(Collectors.toSet()));
|
||||
|
||||
// 更新菜单的显示状态
|
||||
permissionService.updateMenuDisplay(reqVO.getRoleId(), reqVO.getMenus());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.zt.plat.module.system.controller.admin.permission.vo.permission;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
@Schema(description = "管理后台 - 赋予角色菜单--菜单列表 Request VO")
|
||||
@Data
|
||||
public class PermissionAssignRoleMenuItemReqVO {
|
||||
|
||||
@Schema(description = "菜单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "菜单ID不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "是否显示菜单,默认显示(true)")
|
||||
private Boolean showMenu = true;
|
||||
|
||||
@Schema(description = "是否显示菜单按钮是否点击过(避免大量更新数据,只更新点击过的)")
|
||||
private Boolean showMenuChanged = false;
|
||||
|
||||
}
|
||||
@@ -15,7 +15,7 @@ public class PermissionAssignRoleMenuReqVO {
|
||||
@NotNull(message = "角色编号不能为空")
|
||||
private Long roleId;
|
||||
|
||||
@Schema(description = "菜单编号列表", example = "1,3,5")
|
||||
private Set<Long> menuIds = Collections.emptySet(); // 兜底
|
||||
@Schema(description = "菜单编列表")
|
||||
private Set<PermissionAssignRoleMenuItemReqVO> menus = Collections.emptySet(); // 兜底
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.zt.plat.module.system.controller.admin.sms;
|
||||
|
||||
import com.zt.plat.module.system.service.sms.SmsSendService;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Tag(name = "管理后台 - 消息回调")
|
||||
@RestController
|
||||
@RequestMapping("/system/sms/callback")
|
||||
public class MsgCallBackController {
|
||||
|
||||
|
||||
@Resource
|
||||
private SmsSendService smsSendService;
|
||||
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import static com.zt.plat.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 短信回调")
|
||||
@@ -73,4 +74,13 @@ public class SmsCallbackController {
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/zle")
|
||||
@PermitAll
|
||||
@TenantIgnore
|
||||
@Operation(summary = "中铝e办短信的回调")
|
||||
public CommonResult<Boolean> receiveZleSmsStatus(@RequestBody String requestBody) throws Throwable {
|
||||
smsSendService.receiveSmsStatus(SmsChannelEnum.ZLE.getCode(), requestBody);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,11 +6,10 @@ import com.zt.plat.framework.common.pojo.PageParam;
|
||||
import com.zt.plat.framework.common.pojo.PageResult;
|
||||
import com.zt.plat.framework.common.util.object.BeanUtils;
|
||||
import com.zt.plat.framework.excel.core.util.ExcelUtils;
|
||||
import com.zt.plat.module.system.controller.admin.sms.vo.template.SmsTemplatePageReqVO;
|
||||
import com.zt.plat.module.system.controller.admin.sms.vo.template.SmsTemplateRespVO;
|
||||
import com.zt.plat.module.system.controller.admin.sms.vo.template.SmsTemplateSaveReqVO;
|
||||
import com.zt.plat.module.system.controller.admin.sms.vo.template.SmsTemplateSendReqVO;
|
||||
import com.zt.plat.module.system.controller.admin.sms.vo.msg.TextMessage;
|
||||
import com.zt.plat.module.system.controller.admin.sms.vo.template.*;
|
||||
import com.zt.plat.module.system.dal.dataobject.sms.SmsTemplateDO;
|
||||
import com.zt.plat.module.system.service.msg.ISendMsgService;
|
||||
import com.zt.plat.module.system.service.sms.SmsSendService;
|
||||
import com.zt.plat.module.system.service.sms.SmsTemplateService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@@ -19,13 +18,13 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static com.zt.plat.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static com.zt.plat.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
|
||||
import static com.zt.plat.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 短信模板")
|
||||
@@ -37,6 +36,8 @@ public class SmsTemplateController {
|
||||
private SmsTemplateService smsTemplateService;
|
||||
@Resource
|
||||
private SmsSendService smsSendService;
|
||||
@Resource
|
||||
private ISendMsgService sendMsgService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建短信模板")
|
||||
@@ -100,4 +101,18 @@ public class SmsTemplateController {
|
||||
sendReqVO.getTemplateCode(), sendReqVO.getTemplateParams()));
|
||||
}
|
||||
|
||||
@PostMapping("/send-msg")
|
||||
@Operation(summary = "发送消息")
|
||||
@PreAuthorize("@ss.hasPermission('system:sms-template:send-msg')")
|
||||
public CommonResult<Object> sendMsg(@Valid @RequestBody MsgTemplateSendReqVO sendReqVO,TextMessage textMessage) throws Exception{
|
||||
|
||||
String msgtype = textMessage.getMsgtype();
|
||||
if (StringUtils.isBlank(msgtype)){
|
||||
return CommonResult.error(BAD_REQUEST.getCode(), String.format("请求参数缺失:%s",msgtype));
|
||||
}
|
||||
//发送消息到MQ
|
||||
CommonResult<Object> objectCommonResult = sendMsgService.sendTextMsg(sendReqVO,textMessage);
|
||||
return success(objectCommonResult);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.zt.plat.module.system.controller.admin.sms.vo.msg;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 企业微信消息发送对象父类
|
||||
*
|
||||
* @author dongqiang.hao
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class BaseMessage implements Serializable {
|
||||
|
||||
/**
|
||||
* 指定接收消息的成员,成员ID列表(多个接收者用‘|’分隔,最多支持1000个)。特殊情况:指定为”@all”,则向该企业应用的全部成员发送
|
||||
*/
|
||||
private String touser;
|
||||
/**
|
||||
* 指定接收消息的部门,部门ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为”@all”时忽略本参数
|
||||
*/
|
||||
private String toparty;
|
||||
/**
|
||||
* 指定接收消息的标签,标签ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为”@all”时忽略本参数
|
||||
*/
|
||||
private String totag;
|
||||
/**
|
||||
* 企业应用的id,整型。企业内部开发,可在应用的设置页面查看;第三方服务商,可通过接口 获取企业授权信息 获取该参数值
|
||||
*/
|
||||
private String agentid;
|
||||
/**
|
||||
* 消息类型
|
||||
*/
|
||||
private String msgtype;
|
||||
/**
|
||||
* 发送消息的自建应用类型
|
||||
*/
|
||||
private String appType;
|
||||
/**
|
||||
* 表示是否开启重复消息检查,0表示否,1表示是,默认0
|
||||
*/
|
||||
private Integer enable_duplicate_check = 0;
|
||||
/**
|
||||
* 表示是否重复消息检查的时间间隔,默认1800s,最大不超过4小时
|
||||
*/
|
||||
private Integer duplicate_check_interval;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.zt.plat.module.system.controller.admin.sms.vo.msg;
|
||||
|
||||
import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 任务卡片消息按钮对象
|
||||
*
|
||||
* @author luzemin
|
||||
*/
|
||||
@Data
|
||||
public class Btn implements Serializable {
|
||||
|
||||
/**
|
||||
* 按钮key值,用户点击后,会产生任务卡片回调事件,回调事件会带上该key值,只能由数字、字母和“_-@”组成,最长支持128字节
|
||||
*/
|
||||
private String key;
|
||||
|
||||
/**
|
||||
* 按钮名称,最长支持18个字节,超过则截断
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 按钮字体颜色,可选“red”或者“blue”,默认为“blue”
|
||||
*/
|
||||
private String color;
|
||||
|
||||
/**
|
||||
* 按钮字体是否加粗,默认false
|
||||
*/
|
||||
private Boolean is_bold;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.zt.plat.module.system.controller.admin.sms.vo.msg;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 小程序通知消息内容元素对象
|
||||
*
|
||||
* @author luzemin
|
||||
*/
|
||||
@Data
|
||||
public class ContentItem implements Serializable {
|
||||
/**
|
||||
* 元素对象键值,长度10个汉字以内
|
||||
*/
|
||||
private String key;
|
||||
/**
|
||||
* 元素对象值,长度30个汉字以内(支持id转译)
|
||||
*/
|
||||
private String value;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.zt.plat.module.system.controller.admin.sms.vo.msg;
|
||||
|
||||
import com.zt.plat.module.system.framework.sms.core.enums.WxMsgTypeConstant;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
/**
|
||||
* 企业微信文件消息发送对象
|
||||
*
|
||||
* @author luzemin
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
public class FileMessage extends BaseMessage {
|
||||
/**
|
||||
* 消息类型,此时固定为:file
|
||||
*/
|
||||
private final String msgtype = WxMsgTypeConstant.FILE.getCode();
|
||||
|
||||
/**
|
||||
* 企业微信文件消息体对象
|
||||
*/
|
||||
private Media file = new Media();
|
||||
|
||||
/**
|
||||
* 表示是否是保密消息,0表示可对外分享,1表示不能分享且内容显示水印,默认为0
|
||||
*/
|
||||
private Integer safe = 0;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user