mirror of
https://gitee.com/san-bing/JChargePointProtocol
synced 2026-05-06 10:59:57 +08:00
* !44 comment * !39 添加下行日志打印 * !36 扩展计价领域模型 * !35 webui 初步成型 * !34 webui 初步成型
This commit is contained in:
43
jcpp-app/src/main/resources/mapper/AttributeMapper.xml
Normal file
43
jcpp-app/src/main/resources/mapper/AttributeMapper.xml
Normal file
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
开源代码,仅供学习和交流研究使用,商用请联系三丙
|
||||
微信:mohan_88888
|
||||
抖音:程序员三丙
|
||||
付费课程知识星球:https://t.zsxq.com/aKtXo
|
||||
|
||||
-->
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="sanbing.jcpp.app.dal.mapper.AttributeMapper">
|
||||
|
||||
<!-- 查询实体的所有属性 -->
|
||||
<select id="findByEntity" resultType="sanbing.jcpp.app.dal.entity.Attribute">
|
||||
SELECT * FROM t_attr WHERE entity_id = #{entityId}
|
||||
</select>
|
||||
|
||||
<!-- 查询实体的特定属性 -->
|
||||
<select id="findByEntityAndKey" resultType="sanbing.jcpp.app.dal.entity.Attribute">
|
||||
SELECT * FROM t_attr WHERE entity_id = #{entityId} AND attr_key = #{attrKey}
|
||||
</select>
|
||||
|
||||
<!-- 查询实体在指定属性类型下的所有属性 (兼容原JPA方法) -->
|
||||
<select id="findAllByEntityIdAndAttributeType" resultType="sanbing.jcpp.app.dal.entity.Attribute">
|
||||
SELECT * FROM t_attr WHERE entity_id = #{entityId}
|
||||
</select>
|
||||
|
||||
<!-- 根据实体ID和属性键列表查询属性 -->
|
||||
<select id="findAllByIdAndAttrKey" resultType="sanbing.jcpp.app.dal.entity.Attribute">
|
||||
SELECT * FROM t_attr
|
||||
WHERE entity_id = #{entityId}
|
||||
AND attr_key IN
|
||||
<foreach collection="attrKeys" item="key" open="(" separator="," close=")">
|
||||
#{key}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<!-- 删除指定实体的指定属性 -->
|
||||
<delete id="deleteByEntityIdAndKey">
|
||||
DELETE FROM t_attr WHERE entity_id = #{entityId} AND attr_key = #{attrKey}
|
||||
</delete>
|
||||
|
||||
</mapper>
|
||||
176
jcpp-app/src/main/resources/mapper/GunMapper.xml
Normal file
176
jcpp-app/src/main/resources/mapper/GunMapper.xml
Normal file
@@ -0,0 +1,176 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
开源代码,仅供学习和交流研究使用,商用请联系三丙
|
||||
微信:mohan_88888
|
||||
抖音:程序员三丙
|
||||
付费课程知识星球:https://t.zsxq.com/aKtXo
|
||||
|
||||
-->
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="sanbing.jcpp.app.dal.mapper.GunMapper">
|
||||
|
||||
<!-- 充电枪带状态信息的分页查询 -->
|
||||
<select id="selectGunWithStatusPage" resultType="sanbing.jcpp.app.adapter.response.GunWithStatusResponse">
|
||||
SELECT
|
||||
<!-- 充电枪基本信息 -->
|
||||
g.id,
|
||||
g.created_time,
|
||||
g.updated_time,
|
||||
g.gun_name,
|
||||
g.gun_no,
|
||||
g.gun_code,
|
||||
g.station_id,
|
||||
g.pile_id,
|
||||
g.additional_info,
|
||||
g.version,
|
||||
|
||||
<!-- 充电站信息 -->
|
||||
s.station_name,
|
||||
|
||||
<!-- 充电桩信息 -->
|
||||
p.pile_name,
|
||||
p.pile_code,
|
||||
|
||||
<!-- 状态相关属性 -->
|
||||
a_run_status.str_v as run_status
|
||||
|
||||
FROM t_gun g
|
||||
|
||||
<!-- LEFT JOIN 获取充电站信息 -->
|
||||
LEFT JOIN t_station s ON g.station_id = s.id
|
||||
|
||||
<!-- LEFT JOIN 获取充电桩信息 -->
|
||||
LEFT JOIN t_pile p ON g.pile_id = p.id
|
||||
|
||||
<!-- LEFT JOIN 获取充电枪运行状态属性 -->
|
||||
LEFT JOIN t_attr a_run_status ON (
|
||||
a_run_status.entity_id = g.id AND
|
||||
a_run_status.attr_key = 'gunRunStatus'
|
||||
)
|
||||
|
||||
<!-- 动态WHERE条件 -->
|
||||
<where>
|
||||
<if test="request.gunName != null and request.gunName != ''">
|
||||
AND g.gun_name LIKE CONCAT('%', #{request.gunName}, '%')
|
||||
</if>
|
||||
<if test="request.gunCode != null and request.gunCode != ''">
|
||||
AND g.gun_code LIKE CONCAT('%', #{request.gunCode}, '%')
|
||||
</if>
|
||||
<if test="request.stationId != null">
|
||||
AND g.station_id = #{request.stationId}
|
||||
</if>
|
||||
<if test="request.pileId != null">
|
||||
AND g.pile_id = #{request.pileId}
|
||||
</if>
|
||||
<if test="request.gunNo != null and request.gunNo != ''">
|
||||
AND g.gun_no = #{request.gunNo}
|
||||
</if>
|
||||
<if test="request.runStatus != null">
|
||||
AND a_run_status.str_v = #{request.runStatus.code}
|
||||
</if>
|
||||
</where>
|
||||
|
||||
<!-- 动态ORDER BY -->
|
||||
ORDER BY
|
||||
<choose>
|
||||
<when test="request.sortField == 'gunName'">
|
||||
g.gun_name ${request.sortOrder}
|
||||
</when>
|
||||
<when test="request.sortField == 'gunCode'">
|
||||
g.gun_code ${request.sortOrder}
|
||||
</when>
|
||||
<when test="request.sortField == 'gunNo'">
|
||||
g.gun_no ${request.sortOrder}
|
||||
</when>
|
||||
<when test="request.sortField == 'runStatus'">
|
||||
a_run_status.str_v ${request.sortOrder}
|
||||
</when>
|
||||
<when test="request.sortField == 'createdTime'">
|
||||
g.created_time ${request.sortOrder}
|
||||
</when>
|
||||
<when test="request.sortField == 'updatedTime'">
|
||||
g.updated_time ${request.sortOrder}
|
||||
</when>
|
||||
<otherwise>
|
||||
g.created_time DESC
|
||||
</otherwise>
|
||||
</choose>
|
||||
</select>
|
||||
|
||||
<!-- 根据充电桩编码和充电枪编码查询充电枪 -->
|
||||
<select id="selectByPileCodeAndGunCode" resultType="sanbing.jcpp.app.dal.entity.Gun">
|
||||
SELECT g.* FROM t_gun g
|
||||
INNER JOIN t_pile p ON g.pile_id = p.id
|
||||
WHERE p.pile_code = #{pileCode} AND g.gun_code = #{gunCode}
|
||||
</select>
|
||||
|
||||
<!-- 统计充电桩下的充电枪数量 -->
|
||||
<select id="countByPileId" resultType="long">
|
||||
SELECT COUNT(*) FROM t_gun WHERE pile_id = #{pileId}
|
||||
</select>
|
||||
|
||||
<!-- 统计空闲状态的充电枪数量 (IDLE) -->
|
||||
<select id="countIdleGuns" resultType="long">
|
||||
SELECT COUNT(*) FROM t_gun g
|
||||
LEFT JOIN t_attr a ON (a.entity_id = g.id AND a.attr_key = #{statusKey})
|
||||
WHERE a.str_v = #{status}
|
||||
</select>
|
||||
|
||||
<!-- 统计已插枪未充电状态的充电枪数量 (INSERTED) -->
|
||||
<select id="countInsertedGuns" resultType="long">
|
||||
SELECT COUNT(*) FROM t_gun g
|
||||
LEFT JOIN t_attr a ON (a.entity_id = g.id AND a.attr_key = #{statusKey})
|
||||
WHERE a.str_v = #{status}
|
||||
</select>
|
||||
|
||||
<!-- 统计充电中状态的充电枪数量 (CHARGING) -->
|
||||
<select id="countChargingGuns" resultType="long">
|
||||
SELECT COUNT(*) FROM t_gun g
|
||||
LEFT JOIN t_attr a ON (a.entity_id = g.id AND a.attr_key = #{statusKey})
|
||||
WHERE a.str_v = #{status}
|
||||
</select>
|
||||
|
||||
<!-- 统计充电完成状态的充电枪数量 (CHARGE_COMPLETE) -->
|
||||
<select id="countChargeCompleteGuns" resultType="long">
|
||||
SELECT COUNT(*) FROM t_gun g
|
||||
LEFT JOIN t_attr a ON (a.entity_id = g.id AND a.attr_key = #{statusKey})
|
||||
WHERE a.str_v = #{status}
|
||||
</select>
|
||||
|
||||
<!-- 统计放电准备状态的充电枪数量 (DISCHARGE_READY) -->
|
||||
<select id="countDischargeReadyGuns" resultType="long">
|
||||
SELECT COUNT(*) FROM t_gun g
|
||||
LEFT JOIN t_attr a ON (a.entity_id = g.id AND a.attr_key = #{statusKey})
|
||||
WHERE a.str_v = #{status}
|
||||
</select>
|
||||
|
||||
<!-- 统计放电中状态的充电枪数量 (DISCHARGING) -->
|
||||
<select id="countDischargingGuns" resultType="long">
|
||||
SELECT COUNT(*) FROM t_gun g
|
||||
LEFT JOIN t_attr a ON (a.entity_id = g.id AND a.attr_key = #{statusKey})
|
||||
WHERE a.str_v = #{status}
|
||||
</select>
|
||||
|
||||
<!-- 统计放电完成状态的充电枪数量 (DISCHARGE_COMPLETE) -->
|
||||
<select id="countDischargeCompleteGuns" resultType="long">
|
||||
SELECT COUNT(*) FROM t_gun g
|
||||
LEFT JOIN t_attr a ON (a.entity_id = g.id AND a.attr_key = #{statusKey})
|
||||
WHERE a.str_v = #{status}
|
||||
</select>
|
||||
|
||||
<!-- 统计预约状态的充电枪数量 (RESERVED) -->
|
||||
<select id="countReservedGuns" resultType="long">
|
||||
SELECT COUNT(*) FROM t_gun g
|
||||
LEFT JOIN t_attr a ON (a.entity_id = g.id AND a.attr_key = #{statusKey})
|
||||
WHERE a.str_v = #{status}
|
||||
</select>
|
||||
|
||||
<!-- 统计故障状态的充电枪数量 (FAULT) -->
|
||||
<select id="countFaultGuns" resultType="long">
|
||||
SELECT COUNT(*) FROM t_gun g
|
||||
LEFT JOIN t_attr a ON (a.entity_id = g.id AND a.attr_key = #{statusKey})
|
||||
WHERE a.str_v = #{status}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
166
jcpp-app/src/main/resources/mapper/PileMapper.xml
Normal file
166
jcpp-app/src/main/resources/mapper/PileMapper.xml
Normal file
@@ -0,0 +1,166 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
开源代码,仅供学习和交流研究使用,商用请联系三丙
|
||||
微信:mohan_88888
|
||||
抖音:程序员三丙
|
||||
付费课程知识星球:https://t.zsxq.com/aKtXo
|
||||
|
||||
-->
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="sanbing.jcpp.app.dal.mapper.PileMapper">
|
||||
|
||||
<!-- 充电桩带状态信息的分页查询 -->
|
||||
<select id="selectPileWithStatusPage" resultType="sanbing.jcpp.app.adapter.response.PileWithStatusResponse">
|
||||
SELECT
|
||||
<!-- 充电桩基本信息 -->
|
||||
p.id,
|
||||
p.created_time,
|
||||
p.updated_time,
|
||||
p.pile_name,
|
||||
p.pile_code,
|
||||
p.protocol,
|
||||
p.station_id,
|
||||
p.brand,
|
||||
p.model,
|
||||
p.manufacturer,
|
||||
p.type,
|
||||
p.additional_info,
|
||||
p.version,
|
||||
|
||||
<!-- 状态相关属性 -->
|
||||
a_status.str_v as status,
|
||||
a_connected.last_update_ts as connected_at,
|
||||
a_disconnected.last_update_ts as disconnected_at,
|
||||
a_last_active.last_update_ts as last_active_time
|
||||
|
||||
FROM t_pile p
|
||||
|
||||
<!-- LEFT JOIN 获取充电桩状态属性 -->
|
||||
LEFT JOIN t_attr a_status ON (
|
||||
a_status.entity_id = p.id AND
|
||||
a_status.attr_key = #{statusKey.code}
|
||||
)
|
||||
|
||||
<!-- LEFT JOIN 获取最后连接时间属性 -->
|
||||
LEFT JOIN t_attr a_connected ON (
|
||||
a_connected.entity_id = p.id AND
|
||||
a_connected.attr_key = #{connectedAtKey.code}
|
||||
)
|
||||
|
||||
<!-- LEFT JOIN 获取最后断开时间属性 -->
|
||||
LEFT JOIN t_attr a_disconnected ON (
|
||||
a_disconnected.entity_id = p.id AND
|
||||
a_disconnected.attr_key = #{disconnectedAtKey.code}
|
||||
)
|
||||
|
||||
<!-- LEFT JOIN 获取最后活跃时间属性 -->
|
||||
LEFT JOIN t_attr a_last_active ON (
|
||||
a_last_active.entity_id = p.id AND
|
||||
a_last_active.attr_key = #{lastActiveTimeKey.code}
|
||||
)
|
||||
|
||||
<!-- 动态WHERE条件 -->
|
||||
<where>
|
||||
<if test="request.pileName != null and request.pileName != ''">
|
||||
AND p.pile_name LIKE CONCAT('%', #{request.pileName}, '%')
|
||||
</if>
|
||||
<if test="request.pileCode != null and request.pileCode != ''">
|
||||
AND p.pile_code LIKE CONCAT('%', #{request.pileCode}, '%')
|
||||
</if>
|
||||
<if test="request.protocol != null and request.protocol != ''">
|
||||
AND p.protocol = #{request.protocol}
|
||||
</if>
|
||||
<if test="request.stationId != null">
|
||||
AND p.station_id = #{request.stationId}
|
||||
</if>
|
||||
<if test="request.brand != null and request.brand != ''">
|
||||
AND p.brand LIKE CONCAT('%', #{request.brand}, '%')
|
||||
</if>
|
||||
<if test="request.model != null and request.model != ''">
|
||||
AND p.model LIKE CONCAT('%', #{request.model}, '%')
|
||||
</if>
|
||||
<if test="request.manufacturer != null and request.manufacturer != ''">
|
||||
AND p.manufacturer LIKE CONCAT('%', #{request.manufacturer}, '%')
|
||||
</if>
|
||||
<if test="request.type != null">
|
||||
AND p.type = #{request.type}
|
||||
</if>
|
||||
<if test="request.status != null">
|
||||
AND a_status.str_v = #{request.status.code}
|
||||
</if>
|
||||
</where>
|
||||
|
||||
<!-- 动态ORDER BY -->
|
||||
ORDER BY
|
||||
<choose>
|
||||
<when test="request.sortField == 'pileName'">
|
||||
p.pile_name ${request.sortOrder}
|
||||
</when>
|
||||
<when test="request.sortField == 'pileCode'">
|
||||
p.pile_code ${request.sortOrder}
|
||||
</when>
|
||||
<when test="request.sortField == 'protocol'">
|
||||
p.protocol ${request.sortOrder}
|
||||
</when>
|
||||
<when test="request.sortField == 'brand'">
|
||||
p.brand ${request.sortOrder}
|
||||
</when>
|
||||
<when test="request.sortField == 'model'">
|
||||
p.model ${request.sortOrder}
|
||||
</when>
|
||||
<when test="request.sortField == 'manufacturer'">
|
||||
p.manufacturer ${request.sortOrder}
|
||||
</when>
|
||||
<when test="request.sortField == 'type'">
|
||||
p.type ${request.sortOrder}
|
||||
</when>
|
||||
<when test="request.sortField == 'status'">
|
||||
a_status.str_v ${request.sortOrder}
|
||||
</when>
|
||||
<when test="request.sortField == 'connectedAt'">
|
||||
a_connected.last_update_ts ${request.sortOrder}
|
||||
</when>
|
||||
<when test="request.sortField == 'disconnectedAt'">
|
||||
a_disconnected.last_update_ts ${request.sortOrder}
|
||||
</when>
|
||||
<when test="request.sortField == 'lastActiveTime'">
|
||||
a_last_active.last_update_ts ${request.sortOrder}
|
||||
</when>
|
||||
<when test="request.sortField == 'createdTime'">
|
||||
p.created_time ${request.sortOrder}
|
||||
</when>
|
||||
<when test="request.sortField == 'updatedTime'">
|
||||
p.updated_time ${request.sortOrder}
|
||||
</when>
|
||||
<otherwise>
|
||||
p.created_time DESC
|
||||
</otherwise>
|
||||
</choose>
|
||||
</select>
|
||||
|
||||
<!-- 根据充电桩编码查询充电桩 -->
|
||||
<select id="selectByCode" resultType="sanbing.jcpp.app.dal.entity.Pile">
|
||||
SELECT * FROM t_pile WHERE pile_code = #{pileCode}
|
||||
</select>
|
||||
|
||||
<!-- 统计充电站下的充电桩数量 -->
|
||||
<select id="countByStationId" resultType="long">
|
||||
SELECT COUNT(*) FROM t_pile WHERE station_id = #{stationId}
|
||||
</select>
|
||||
|
||||
<!-- 统计在线充电桩数量 -->
|
||||
<select id="countOnlinePiles" resultType="long">
|
||||
SELECT COUNT(*) FROM t_pile p
|
||||
LEFT JOIN t_attr a ON (a.entity_id = p.id AND a.attr_key = #{statusKey})
|
||||
WHERE a.str_v = #{onlineStatus}
|
||||
</select>
|
||||
|
||||
<!-- 统计离线充电桩数量(包括未设置状态的) -->
|
||||
<select id="countOfflinePiles" resultType="long">
|
||||
SELECT COUNT(*) FROM t_pile p
|
||||
LEFT JOIN t_attr a ON (a.entity_id = p.id AND a.attr_key = #{statusKey})
|
||||
WHERE a.str_v IS NULL OR a.str_v = #{offlineStatus}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
131
jcpp-app/src/main/resources/sql/schema-init.sql
Normal file
131
jcpp-app/src/main/resources/sql/schema-init.sql
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 开源代码,仅供学习和交流研究使用,商用请联系三丙
|
||||
* 微信:mohan_88888
|
||||
* 抖音:程序员三丙
|
||||
* 付费课程知识星球:https://t.zsxq.com/aKtXo
|
||||
*/
|
||||
|
||||
-- 数据库版本表
|
||||
CREATE TABLE IF NOT EXISTS t_schema_version
|
||||
(
|
||||
version varchar(32) not null primary key
|
||||
);
|
||||
|
||||
-- 插入初始版本
|
||||
INSERT INTO t_schema_version (version) VALUES ('1.0.0') ON CONFLICT (version) DO NOTHING;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS t_user
|
||||
(
|
||||
id uuid not null
|
||||
constraint owner_pkey
|
||||
primary key,
|
||||
created_time timestamp default CURRENT_TIMESTAMP not null,
|
||||
updated_time timestamp,
|
||||
additional_info jsonb,
|
||||
status varchar(16) not null,
|
||||
user_name varchar(255) not null,
|
||||
user_credentials jsonb not null,
|
||||
authority varchar(32),
|
||||
version int default 1
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uni_user_name
|
||||
on t_user (user_name);
|
||||
|
||||
-- 为t_user表的字段添加注释
|
||||
COMMENT ON COLUMN t_user.authority IS '用户权限: SYS_ADMIN, TENANT_ADMIN, CUSTOMER_USER, REFRESH_TOKEN, PRE_VERIFICATION_TOKEN';
|
||||
|
||||
-- 为authority字段创建索引,便于按权限查询用户
|
||||
CREATE INDEX IF NOT EXISTS idx_user_authority
|
||||
on t_user (authority);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS t_station
|
||||
(
|
||||
id uuid not null
|
||||
constraint station_pkey
|
||||
primary key,
|
||||
created_time timestamp default CURRENT_TIMESTAMP not null,
|
||||
updated_time timestamp,
|
||||
additional_info jsonb,
|
||||
station_name varchar(255) not null,
|
||||
station_code varchar(255) not null,
|
||||
longitude double precision,
|
||||
latitude double precision,
|
||||
province varchar(255),
|
||||
city varchar(255),
|
||||
county varchar(255),
|
||||
address varchar(255),
|
||||
version int default 1
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uni_station_code
|
||||
on t_station (station_code);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS t_pile
|
||||
(
|
||||
id uuid not null
|
||||
constraint pile_pkey
|
||||
primary key,
|
||||
created_time timestamp default CURRENT_TIMESTAMP not null,
|
||||
updated_time timestamp,
|
||||
additional_info jsonb,
|
||||
pile_name varchar(255) not null,
|
||||
pile_code varchar(255) not null,
|
||||
protocol varchar(255) not null,
|
||||
station_id uuid not null,
|
||||
brand varchar(255),
|
||||
model varchar(255),
|
||||
manufacturer varchar(255),
|
||||
type varchar(16) not null,
|
||||
version int default 1
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uni_pile_code
|
||||
on t_pile (pile_code);
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS t_gun
|
||||
(
|
||||
id uuid not null
|
||||
primary key,
|
||||
created_time timestamp default CURRENT_TIMESTAMP not null,
|
||||
updated_time timestamp default CURRENT_TIMESTAMP not null,
|
||||
additional_info varchar(255),
|
||||
gun_no varchar(255) not null,
|
||||
gun_name varchar(255) not null,
|
||||
gun_code varchar(255) not null,
|
||||
station_id uuid not null,
|
||||
pile_id uuid not null,
|
||||
version int default 1
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_gun_pile_id
|
||||
on t_gun (pile_id);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_gun_pile_gun_code
|
||||
on t_gun (pile_id, gun_code);
|
||||
|
||||
|
||||
|
||||
CREATE SEQUENCE IF NOT EXISTS attr_kv_version_seq cache 1;
|
||||
|
||||
-- 属性表:存储充电桩、充电枪的最新属性数据(如状态等)
|
||||
-- 采用键值对存储结构设计
|
||||
CREATE TABLE IF NOT EXISTS t_attr
|
||||
(
|
||||
entity_id uuid not null, -- 实体ID (UUID保证全局唯一)
|
||||
attr_key varchar(255) not null, -- 属性键 (字符串类型提高可读性)
|
||||
bool_v boolean, -- 布尔值
|
||||
str_v varchar(10000000), -- 字符串值
|
||||
long_v bigint, -- 长整型值
|
||||
dbl_v double precision, -- 双精度值
|
||||
json_v json, -- JSON值
|
||||
last_update_ts bigint not null, -- 最后更新时间戳
|
||||
version int default 0 not null, -- 版本号,用于乐观锁
|
||||
PRIMARY KEY (entity_id, attr_key)
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
153
jcpp-app/src/main/resources/xss-policy.xml
Normal file
153
jcpp-app/src/main/resources/xss-policy.xml
Normal file
@@ -0,0 +1,153 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
|
||||
开源代码,仅供学习和交流研究使用,商用请联系三丙
|
||||
微信:mohan_88888
|
||||
抖音:程序员三丙
|
||||
付费课程知识星球:https://t.zsxq.com/aKtXo
|
||||
|
||||
-->
|
||||
<anti-samy-rules>
|
||||
|
||||
<directives>
|
||||
<directive name="omitXmlDeclaration" value="true"/>
|
||||
<directive name="omitDoctypeDeclaration" value="false"/>
|
||||
<directive name="maxInputSize" value="100000"/>
|
||||
<directive name="embedStyleSheets" value="false"/>
|
||||
<directive name="useXHTML" value="true"/>
|
||||
<directive name="formatOutput" value="true"/>
|
||||
</directives>
|
||||
|
||||
<common-regexps>
|
||||
|
||||
<!--
|
||||
From W3C:
|
||||
This attribute assigns a class name or set of class names to an
|
||||
element. Any number of elements may be assigned the same class
|
||||
name or names. Multiple class names must be separated by white
|
||||
space characters.
|
||||
-->
|
||||
<regexp name="htmlTitle" value="[a-zA-Z0-9\s\-_',:\[\]!\./\\\(\)&]*"/>
|
||||
|
||||
<!-- force non-empty with a '+' at the end instead of '*'
|
||||
-->
|
||||
<regexp name="onsiteURL" value="([\p{L}\p{N}\p{Zs}/\.\?=&\-~])+"/>
|
||||
|
||||
<!-- ([\w\\/\.\?=&;\#-~]+|\#(\w)+)
|
||||
-->
|
||||
|
||||
<!-- ([\p{L}/ 0-9&\#-.?=])*
|
||||
-->
|
||||
<regexp name="offsiteURL"
|
||||
value="(\s)*((ht|f)tp(s?)://|mailto:)[A-Za-z0-9]+[~a-zA-Z0-9-_\.@\#\$%&;:,\?=/\+!\(\)]*(\s)*"/>
|
||||
</common-regexps>
|
||||
|
||||
<common-attributes>
|
||||
|
||||
<attribute name="lang"
|
||||
description="'lang'属性用于告诉浏览器元素的属性值和内容使用的语言">
|
||||
|
||||
<regexp-list>
|
||||
<regexp value="[a-zA-Z]{2,20}"/>
|
||||
</regexp-list>
|
||||
</attribute>
|
||||
|
||||
<attribute name="title"
|
||||
description="'title'属性提供当用户将鼠标悬停在元素上时显示的工具提示文本">
|
||||
|
||||
<regexp-list>
|
||||
<regexp name="htmlTitle"/>
|
||||
</regexp-list>
|
||||
</attribute>
|
||||
|
||||
<attribute name="href" onInvalid="filterTag">
|
||||
|
||||
<regexp-list>
|
||||
<regexp name="onsiteURL"/>
|
||||
<regexp name="offsiteURL"/>
|
||||
</regexp-list>
|
||||
</attribute>
|
||||
|
||||
<attribute name="align"
|
||||
description="HTML元素的'align'属性是一个方向词,如'left'、'right'或'center'">
|
||||
|
||||
<literal-list>
|
||||
<literal value="center"/>
|
||||
<literal value="left"/>
|
||||
<literal value="right"/>
|
||||
<literal value="justify"/>
|
||||
<literal value="char"/>
|
||||
</literal-list>
|
||||
</attribute>
|
||||
<attribute name="style"
|
||||
description="'style'属性使用严格的语法为用户提供更改标签内容的多个属性的能力"/>
|
||||
</common-attributes>
|
||||
|
||||
<global-tag-attributes>
|
||||
<attribute name="title"/>
|
||||
<attribute name="lang"/>
|
||||
<attribute name="style"/>
|
||||
</global-tag-attributes>
|
||||
|
||||
<tags-to-encode>
|
||||
<tag>g</tag>
|
||||
<tag>grin</tag>
|
||||
</tags-to-encode>
|
||||
|
||||
<tag-rules>
|
||||
|
||||
<tag name="script" action="remove"/>
|
||||
<tag name="noscript" action="remove"/>
|
||||
<tag name="iframe" action="remove"/>
|
||||
<tag name="frameset" action="remove"/>
|
||||
<tag name="frame" action="remove"/>
|
||||
<tag name="noframes" action="remove"/>
|
||||
<tag name="head" action="remove"/>
|
||||
<tag name="title" action="remove"/>
|
||||
<tag name="base" action="remove"/>
|
||||
<tag name="style" action="remove"/>
|
||||
<tag name="link" action="remove"/>
|
||||
<tag name="input" action="remove"/>
|
||||
<tag name="textarea" action="remove"/>
|
||||
|
||||
<tag name="br" action="remove"/>
|
||||
|
||||
<tag name="p" action="remove"/>
|
||||
<tag name="div" action="remove"/>
|
||||
<tag name="span" action="remove"/>
|
||||
<tag name="i" action="remove"/>
|
||||
<tag name="b" action="remove"/>
|
||||
<tag name="strong" action="remove"/>
|
||||
<tag name="s" action="remove"/>
|
||||
<tag name="strike" action="remove"/>
|
||||
<tag name="u" action="remove"/>
|
||||
<tag name="em" action="remove"/>
|
||||
<tag name="blockquote" action="remove"/>
|
||||
<tag name="tt" action="remove"/>
|
||||
|
||||
<tag name="a" action="remove"/>
|
||||
|
||||
<tag name="ul" action="remove"/>
|
||||
<tag name="ol" action="remove"/>
|
||||
<tag name="li" action="remove"/>
|
||||
<tag name="dl" action="remove"/>
|
||||
<tag name="dt" action="remove"/>
|
||||
<tag name="dd" action="remove"/>
|
||||
</tag-rules>
|
||||
|
||||
<css-rules>
|
||||
<property name="text-decoration" default="none"
|
||||
description="文本装饰样式">
|
||||
|
||||
<category-list>
|
||||
<category value="visual"/>
|
||||
</category-list>
|
||||
|
||||
<literal-list>
|
||||
<literal value="underline"/>
|
||||
<literal value="overline"/>
|
||||
<literal value="line-through"/>
|
||||
</literal-list>
|
||||
</property>
|
||||
</css-rules>
|
||||
</anti-samy-rules>
|
||||
Reference in New Issue
Block a user