This commit is contained in:
oneao committed 2026-04-24 17:28:11 +08:00
1 parent 07e0001b87
commit 46cbb2f50d
543 files changed
+32576 -4231

No files matched your search

@@ -0,0 +1,60 @@
server:
port: 8084
netty:
port: 8090
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: net.sourceforge.jtds.jdbc.Driver
# url: jdbc:jtds:sqlserver://192.168.1.189:1433;databaseName=G3-Link
url: jdbc:jtds:sqlserver://117.72.182.135:1433;databaseName=G3-Link
username: sa
# password: "g3soft"
password: "zhang520.."
# druid 连接池管理
druid:
# 初始化时建立物理连接的个数
initial-size: 5
# 连接池的最小空闲数量
min-idle: 5
# 连接池最大连接数量
max-active: 20
# 获取连接时最大等待时间,单位毫秒
max-wait: 60000
# 申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
test-while-idle: true
# 既作为检测的间隔时间又作为testWhileIdel执行的依据
time-between-eviction-runs-millis: 60000
# 销毁线程时检测当前连接的最后活动时间和当前时间差大于该值时,关闭当前连接(配置连接在池中的最小生存时间)
min-evictable-idle-time-millis: 30000
# 用来检测数据库连接是否有效的sql 必须是一个查询语句(oracle中为 select 1 from dual) validation-query: select 'x'
# 申请连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
test-on-borrow: false
# 归还连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
test-on-return: false
# 是否缓存preparedStatement, 也就是PSCache,PSCache对支持游标的数据库性能提升巨大,比如说oracle,在mysql下建议关闭。
pool-prepared-statements: false
# 置监控统计拦截的filters,去掉后监控界面sql无法统计,stat: 监控统计、Slf4j:日志记录、waLL: 防御sqL注入
filters: stat,wall,slf4j
# 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
max-pool-prepared-statement-per-connection-size: -1
# 合并多个DruidDataSource的监控数据
use-global-data-source-stat: true
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connect-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
stat-view-servlet:
# 是否启用StatViewServlet默认值true
enabled: true
# 访问路径为/druid时,跳转到StatViewServlet
url-pattern: /druid/*
# 是否能够重置数据
reset-enable: false
# 需要账号密码才能访问控制台,默认为root
login-username: root
login-password: root
# IP白名单
allow: 127.0.0.1
# IP黑名单(共同存在时,deny优先于allow)
deny:
@@ -0,0 +1,58 @@
server:
port: 8090
netty:
port: 8080
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: net.sourceforge.jtds.jdbc.Driver
url: jdbc:jtds:sqlserver://127.0.0.1:1433;databaseName=G3-Link56
username: sa
password: ""
# druid 连接池管理
druid:
# 初始化时建立物理连接的个数
initial-size: 5
# 连接池的最小空闲数量
min-idle: 5
# 连接池最大连接数量
max-active: 20
# 获取连接时最大等待时间,单位毫秒
max-wait: 60000
# 申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
test-while-idle: true
# 既作为检测的间隔时间又作为testWhileIdel执行的依据
time-between-eviction-runs-millis: 60000
# 销毁线程时检测当前连接的最后活动时间和当前时间差大于该值时,关闭当前连接(配置连接在池中的最小生存时间)
min-evictable-idle-time-millis: 30000
# 用来检测数据库连接是否有效的sql 必须是一个查询语句(oracle中为 select 1 from dual) validation-query: select 'x'
# 申请连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
test-on-borrow: false
# 归还连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
test-on-return: false
# 是否缓存preparedStatement, 也就是PSCache,PSCache对支持游标的数据库性能提升巨大,比如说oracle,在mysql下建议关闭。
pool-prepared-statements: false
# 置监控统计拦截的filters,去掉后监控界面sql无法统计,stat: 监控统计、Slf4j:日志记录、waLL: 防御sqL注入
filters: stat,wall,slf4j
# 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
max-pool-prepared-statement-per-connection-size: -1
# 合并多个DruidDataSource的监控数据
use-global-data-source-stat: true
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connect-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
stat-view-servlet:
# 是否启用StatViewServlet默认值true
enabled: true
# 访问路径为/druid时,跳转到StatViewServlet
url-pattern: /druid/*
# 是否能够重置数据
reset-enable: false
# 需要账号密码才能访问控制台,默认为root
login-username: root
login-password: root
# IP白名单
allow: 127.0.0.1
# IP黑名单(共同存在时,deny优先于allow)
deny:
@@ -0,0 +1,42 @@
server:
servlet:
context-path: / # 应用的访问路径
tomcat:
uri-encoding: UTF-8 # URI编码
accept-count: 1000 # 连接数满后的排队数
threads:
max: 800 # 最大线程数
min-spare: 100 # 初始化的线程数
max-http-header-size: 64KB
logging:
level:
com.client: debug # 调试级别的日志
org.springframework: warn # 仅显示警告级别及以上的Spring日志
spring:
profiles:
active: prod
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
mail:
host: smtp.163.com #邮箱服务器地址
username: hi_itao@163.com #邮箱账号
password: RSchPDWrKwVcyMG7 #邮箱授权码
default-encoding: utf-8 #默认编码
mybatis-plus:
# 对应的 XML 文件位置
mapperLocations: classpath*:mapper/**/*Mapper.xml
# configLocation: classpath:mybatis/mybatis-config.xml
configuration:
cache-enabled: true
use-generated-keys: true
default-executor-type: simple
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true
global-config:
db-config:
logic-delete-field: deleted
logic-not-delete-value: 0
logic-delete-value: 1
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.link56.base.mapper.AreaMapper">
<sql id="area_columns">
b_id AS id,
b_xh AS xh,
b_name AS name,
b_father_id AS fatherId,
b_canuse AS canuse,
b_bz AS bz,
b_field AS field,
b_order AS [order]
</sql>
<select id="listAllArea" resultType="cn.link56.base.model.po.Area">
SELECT <include refid="area_columns"/> FROM b_area_sheng WHERE b_canuse = '1'
UNION ALL
SELECT <include refid="area_columns"/> FROM b_area_shi WHERE b_canuse = '1'
UNION ALL
SELECT <include refid="area_columns"/> FROM b_area_qu WHERE b_canuse = '1'
ORDER BY [order]
</select>
</mapper>
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.link56.company.mapper.CompanyMapper">
<select id="listRecommend" resultType="cn.link56.company.model.middle.RecommendCompanyRow">
SELECT
sheng.b_name AS shengName,
shi.b_name AS shiName,
c.b_id AS companyId,
c.b_name AS companyName,
c.b_recommend_color AS color
FROM b_area_shi shi
JOIN b_area_sheng sheng
ON shi.b_father_id = sheng.b_id
LEFT JOIN b_company c
ON c.b_canuse = '1'
AND c.b_recommend = '1'
AND c.b_area LIKE '%' + shi.b_name + '%'
WHERE
shi.b_canuse = '1'
AND shi.b_visible = '1'
AND sheng.b_canuse = '1'
ORDER BY
sheng.b_order ASC,
shi.b_order ASC
</select>
<select id="selectCompanyByUserId" resultType="cn.link56.company.model.po.Company">
SELECT
c.b_id as id,
c.b_name as name,
c.b_logo as logo,
c.b_profile as profile,
c.b_area as area,
c.b_industry as industry
FROM
b_company c
INNER JOIN b_company_user cu ON cu.b_company_id = c.b_id
WHERE
cu.b_id = #{userId}
</select>
</mapper>
@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.link56.im.mapper.ImFriendMapper">
<select id="selectFriend" resultType="cn.link56.im.model.vo.QueryFriendVO">
SELECT *
FROM (
SELECT
f.b_friend_id AS friendId,
u.b_name AS friendName,
u.b_avatar AS friendAvatar,
f.b_unread_count AS unreadCount,
m.b_send_time AS lastMessageTime,
m.b_type AS lastMessageType,
m.b_content AS lastMessageContent,
ROW_NUMBER() OVER (
ORDER BY
<if test="id != null and id != 0">
CASE WHEN f.b_id = #{id} THEN 0 ELSE 1 END,
</if>
m.b_send_time DESC
) AS rn
FROM b_im_friend f
LEFT JOIN b_company_user u ON f.b_friend_id = u.b_id
LEFT JOIN b_im_private_message m ON f.b_last_message_id = m.b_id
WHERE f.b_user_id = #{userId}
<if test="name != null and name != ''">
AND u.b_name LIKE '%' + #{name} + '%'
</if>
) t
WHERE t.rn BETWEEN #{offset} AND #{limit}
</select>
<select id="selectFriendTotal" resultType="java.lang.Long">
SELECT COUNT(*)
FROM b_im_friend f
LEFT JOIN b_company_user u ON f.b_friend_id = u.b_id
WHERE f.b_user_id = #{userId}
<if test="name != null and name != ''">
AND u.b_name LIKE '%' + #{name} + '%'
</if>
</select>
<update id="incrementUnreadAndUpdateLastMessage">
UPDATE b_im_friend
SET
b_last_message_id = #{lastMessageId},
b_unread_count = b_unread_count + 1,
b_update_time = GETDATE()
WHERE b_user_id = #{userId} and b_friend_id = #{friendId}
</update>
<update id="decreaseUnreadCount">
UPDATE b_im_friend
SET
b_unread_count = 0,
b_update_time = GETDATE()
WHERE b_user_id = #{userId} and b_friend_id = #{friendId}
</update>
<select id="selectFriendProfile" resultType="cn.link56.im.model.vo.FriendProfileVO">
SELECT
f.b_friend_id AS friendId,
u.b_name AS friendName,
u.b_avatar AS friendAvatar,
f.b_unread_count AS unreadCount,
m.b_send_time AS lastMessageTime,
m.b_type AS lastMessageType,
m.b_content AS lastMessageContent
FROM b_im_friend f
INNER JOIN b_company_user u ON f.b_friend_id = u.b_id
LEFT JOIN b_im_private_message m ON f.b_last_message_id = m.b_id
WHERE f.b_user_id = #{userId} AND f.b_friend_id = #{friendId}
</select>
</mapper>
@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.link56.im.mapper.ImGroupMapper">
<select id="selectGroup" resultType="cn.link56.im.model.vo.QueryGroupVO">
SELECT *
FROM (
SELECT
g.b_id AS groupId,
g.b_name AS groupName,
g.b_avatar AS groupAvatar,
gu.b_unread_count AS unreadCount,
m.b_send_time AS lastMessageTime,
m.b_type AS lastMessageType,
m.b_content AS lastMessageContent,
u.b_name AS lastMessageSenderName,
ROW_NUMBER() OVER (
ORDER BY
CASE WHEN #{id} IS NOT NULL AND #{id} != 0 AND g.b_id = #{id} THEN 0 ELSE 1 END,
m.b_send_time DESC
) AS rn
FROM b_im_group g
INNER JOIN b_im_group_user gu ON g.b_id = gu.b_group_id
LEFT JOIN b_im_group_message m ON g.b_last_message_id = m.b_id
LEFT JOIN b_company_user u ON m.b_sender_id = u.b_id
WHERE gu.b_user_id = #{userId}
<if test="name != null and name != ''">
AND g.b_name LIKE '%' + #{name} + '%'
</if>
) t
WHERE t.rn BETWEEN #{offset} AND #{limit}
</select>
<select id="selectGroupTotal" resultType="java.lang.Long">
SELECT COUNT(DISTINCT g.b_id)
FROM b_im_group g
INNER JOIN b_im_group_user gu ON g.b_id = gu.b_group_id
WHERE gu.b_user_id = #{userId}
<if test="name != null and name != ''">
AND g.b_name LIKE '%' + #{name} + '%'
</if>
</select>
<select id="selectGroupProfile"
resultType="cn.link56.im.model.vo.GroupProfileVO">
SELECT
g.b_id AS groupId,
g.b_name AS groupName,
g.b_avatar AS groupAvatar,
gu.b_unread_count AS unreadCount
FROM b_im_group g
INNER JOIN b_im_group_user gu ON g.b_id = gu.b_group_id
WHERE gu.b_user_id = #{userId}
AND g.b_id = #{groupId}
</select>
</mapper>
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.link56.im.mapper.ImGroupMessageMapper">
<select id="selectGroupMessages" resultType="cn.link56.im.model.vo.QueryGroupMessageVO">
SELECT TOP (#{pageSize})
gm.b_id AS id,
gm.b_group_id AS groupId,
gm.b_sender_id AS senderId,
u.b_name AS senderName,
u.b_avatar AS senderAvatar,
gm.b_content AS content,
gm.b_type AS type,
gm.b_send_time AS sendTime
FROM b_im_group_message gm
LEFT JOIN b_company_user u ON gm.b_sender_id = u.b_id
WHERE gm.b_group_id = #{groupId}
<if test="beforeTimestamp != null and beforeId != null">
AND (
gm.b_send_time &lt; #{beforeTimestamp}
OR (gm.b_send_time = #{beforeTimestamp} AND gm.b_id &lt; #{beforeId})
)
</if>
ORDER BY gm.b_send_time DESC, gm.b_id DESC
</select>
</mapper>
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.link56.im.mapper.ImGroupUserMapper">
<select id="selectGroupUsers" resultType="cn.link56.im.model.vo.QueryGroupUserVO" parameterType="map">
SELECT
gu.b_group_id AS groupId,
cu.b_id AS userId,
cu.b_avatar AS userAvatar,
cu.b_name AS userName
FROM
b_im_group_user gu
INNER JOIN
b_company_user cu
ON gu.b_user_id = cu.b_id
WHERE
gu.b_group_id = #{groupId}
<if test="userName != null and userName != ''">
AND cu.b_name LIKE '%' + #{userName} + '%'
</if>
</select>
</mapper>
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.link56.im.mapper.ImPrivateMessageMapper">
<select id="selectPrivateMessages" resultType="cn.link56.im.model.vo.QueryPrivateMessageVO">
SELECT TOP (#{pageSize})
b_id AS id,
b_sender_id AS senderId,
b_receiver_id AS receiverId,
b_content AS content,
b_type AS type,
b_send_time AS sendTime
FROM b_im_private_message
WHERE
(
(b_sender_id = #{userId} AND b_receiver_id = #{friendId})
OR
(b_sender_id = #{friendId} AND b_receiver_id = #{userId})
)
<if test="beforeTimestamp != null and beforeId != null">
AND (
b_send_time &lt; #{beforeTimestamp}
OR (b_send_time = #{beforeTimestamp} AND b_id &lt; #{beforeId})
)
</if>
ORDER BY b_send_time DESC, b_id DESC
</select>
</mapper>
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.link56.post.mapper.PostCommentMapper">
<resultMap id="CommentListMap" type="cn.link56.post.model.vo.PostCommentVO">
<id property="id" column="b_id"/>
<result property="rootId" column="b_root_id"/>
<result property="fatherId" column="b_father_id"/>
<result property="content" column="b_content"/>
<result property="createTime" column="b_create_time"/>
<!-- 映射发布公司 -->
<association property="publishUser" javaType="cn.link56.post.model.vo.PostCommentVO$User">
<result property="id" column="pub_user_id"/>
<result property="companyId" column="pub_company_id"/>
<result property="name" column="pub_user_name"/>
<result property="avatar" column="pub_user_avatar"/>
</association>
<!-- 映射回复公司 -->
<association property="replyUser" javaType="cn.link56.post.model.vo.PostCommentVO$User">
<result property="id" column="rep_user_id"/>
<result property="companyId" column="rep_company_id"/>
<result property="name" column="rep_user_name"/>
<result property="avatar" column="rep_user_avatar"/>
</association>
</resultMap>
<select id="selectComments" resultMap="CommentListMap">
SELECT c.*,
pc.b_id AS pub_user_id,pc.b_company_id AS pub_company_id,pc.b_name AS pub_user_name,pc.b_avatar AS pub_user_avatar,
rc.b_id AS rep_user_id,rc.b_company_id AS rep_company_id,rc.b_name AS rep_user_name,rc.b_avatar AS rep_user_avatar
FROM b_post_comment c
LEFT JOIN b_company_user pc ON c.b_create_by = pc.b_id
LEFT JOIN b_company_user rc ON (
SELECT b_create_by FROM b_post_comment WHERE b_id = c.b_father_id
) = rc.b_id
WHERE c.b_post_id = #{postId} AND c.b_deleted = 0
ORDER BY c.b_create_time
</select>
</mapper>
@@ -0,0 +1,196 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.link56.post.mapper.PostMapper">
<resultMap id="QueryEditorPostVOMap"
type="cn.link56.post.model.vo.QueryEditorPostVO">
<id property="id" column="id"/>
<result property="title" column="title"/>
<!-- tags 字符串 → List<String> -->
<result
property="tags"
column="tagsString"
typeHandler="cn.link56.common.mybatis.StringListTypeHandler"/>
<result property="publishTime" column="publishTime"/>
<result property="updateTime" column="updateTime"/>
<result property="status" column="status"/>
<result property="viewCount" column="viewCount"/>
<result property="likeCount" column="likeCount"/>
<result property="favoriteCount" column="favoriteCount"/>
<result property="commentCount" column="commentCount"/>
</resultMap>
<resultMap id="QueryPublicPostVOMap"
type="cn.link56.post.model.vo.QueryPublicPostVO">
<id property="id" column="id"/>
<result property="title" column="title"/>
<!-- tags 字符串 → List<String> -->
<result
property="tags"
column="tagsString"
typeHandler="cn.link56.common.mybatis.StringListTypeHandler"/>
<result property="companyId" column="companyId"/>
<result property="companyName" column="companyName"/>
<result property="viewCount" column="viewCount"/>
<result property="commentCount" column="commentCount"/>
<result property="activeTime" column="activeTime"/>
</resultMap>
<select id="selectEditorPostPage" resultMap="QueryEditorPostVOMap">
SELECT *
FROM (
SELECT
p.b_id AS id,
p.b_title AS title,
p.b_tag AS tagsString,
p.b_update_time AS updateTime,
p.b_publish_time AS publishTime,
p.b_status AS status,
ISNULL(ps.b_view_count, 0) AS viewCount,
ISNULL(ps.b_comment_count, 0) AS commentCount,
ROW_NUMBER() OVER (ORDER BY p.b_update_time DESC) AS rn
FROM b_post p
LEFT JOIN b_post_stat ps ON ps.b_post_id = p.b_id
<where>
<if test="userId != null">
AND p.b_create_by = #{userId}
</if>
<if test="status != null and status != -1">
AND p.b_status = #{status}
</if>
<if test="title != null and title != ''">
AND p.b_title LIKE '%' + #{title} + '%'
</if>
<if test="year != null and year != ''">
AND YEAR(p.b_update_time) = #{year}
</if>
<if test="month != null and month != ''">
AND MONTH(p.b_update_time) = #{month}
</if>
AND p.b_deleted = 0
</where>
) t
WHERE t.rn BETWEEN #{offset} AND #{limit}
</select>
<select id="selectEditorPostTotal" resultType="java.lang.Long">
SELECT COUNT(*)
FROM b_post p
<where>
<if test="userId != null">
AND p.b_create_by = #{userId}
</if>
<if test="status != null and status != -1">
AND p.b_status = #{status}
</if>
<if test="title != null and title != ''">
AND p.b_title LIKE '%' + #{title} + '%'
</if>
<if test="year != null and year != ''">
AND YEAR(p.b_update_time) = #{year}
</if>
<if test="month != null and month != ''">
AND MONTH(p.b_update_time) = #{month}
</if>
AND p.b_deleted = 0
</where>
</select>
<select id="selectPublicPostPage" resultMap="QueryPublicPostVOMap">
SELECT
t.id,
t.title,
t.tagsString,
t.companyId,
t.companyName,
t.viewCount,
t.commentCount,
t.activeTime
FROM (
SELECT
p.b_id AS id,
p.b_title AS title,
p.b_tag AS tagsString,
p.b_company_id AS companyId,
bc.b_name AS companyName,
ISNULL(ps.b_view_count, 0) AS viewCount,
ISNULL(ps.b_comment_count, 0) AS commentCount,
p.b_active_time AS activeTime,
ROW_NUMBER() OVER (
ORDER BY p.b_update_time DESC
) AS rn
FROM b_post p
LEFT JOIN b_company bc
ON bc.b_id = p.b_company_id
LEFT JOIN b_post_stat ps
ON ps.b_post_id = p.b_id
<where>
p.b_status = 1
<if test="title != null and title != ''">
AND p.b_title LIKE '%' + #{title} + '%'
</if>
<if test="tag != null and tag != ''">
AND p.b_tag LIKE '%' + #{tag} + '%'
</if>
AND p.b_deleted = 0
</where>
) t
WHERE t.rn BETWEEN #{offset} AND #{limit}
</select>
<select id="selectPublicPostTotal" resultType="java.lang.Long">
SELECT COUNT(1)
FROM b_post p
<where>
AND p.b_status = 1
<if test="title != null and title != ''">
AND p.b_title LIKE '%' + #{title} + '%'
</if>
<if test="tag != null and tag != ''">
AND p.b_tag LIKE '%' + #{tag} + '%'
</if>
AND p.b_deleted = 0
</where>
</select>
<!-- 批量软删除用户的帖子 -->
<delete id="deleteUserPosts">
UPDATE b_post
SET b_deleted = 1,
update_by = #{updateBy},
update_time = GETDATE()
WHERE b_create_by IN
<foreach item="userId" collection="userIds" open="(" separator="," close=")">
#{userId}
</foreach>
AND b_deleted = 0
</delete>
</mapper>
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.link56.post.mapper.PostStatMapper">
<update id="increaseViewCount">
UPDATE b_post_stat
SET
b_view_count = b_view_count + #{count},
b_update_time = GETDATE()
WHERE b_post_id = #{postId}
</update>
<update id="increaseCommentCount">
UPDATE b_post_stat
SET
b_comment_count = b_comment_count + #{count},
b_update_time = GETDATE()
WHERE b_post_id = #{postId}
</update>
<update id="decreaseCommentCount">
UPDATE b_post_stat
SET
b_comment_count = CASE
WHEN b_comment_count - #{count} &lt; 0 THEN 0
ELSE b_comment_count - #{count}
END,
b_update_time = GETDATE()
WHERE b_post_id = #{postId}
</update>
</mapper>
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 日志存放路径 -->
<property name="log.path" value="D:\\link56-log" />
<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-info.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-error.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 系统模块日志级别控制 -->
<logger name="cn.link56" level="info" />
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn" />
<root level="info">
<appender-ref ref="console" />
</root>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="file_info" />
<appender-ref ref="file_error" />
</root>
</configuration>
@@ -0,0 +1,524 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="x-apple-disable-message-reformatting" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="color-scheme" content="light dark" />
<meta name="supported-color-schemes" content="light dark" />
<title></title>
<style type="text/css" rel="stylesheet" media="all">
/* Base ------------------------------ */
@import url("https://fonts.googleapis.com/css?family=Nunito+Sans:400,700&display=swap");
body {
width: 100% !important;
height: 100%;
margin: 0;
-webkit-text-size-adjust: none;
}
a {
color: #3869D4;
}
a img {
border: none;
}
td {
word-break: break-word;
}
.preheader {
display: none !important;
visibility: hidden;
mso-hide: all;
font-size: 1px;
line-height: 1px;
max-height: 0;
max-width: 0;
opacity: 0;
overflow: hidden;
}
/* Type ------------------------------ */
body,
td,
th {
font-family: "Nunito Sans", Helvetica, Arial, sans-serif;
}
h1 {
margin-top: 0;
color: #333333;
font-size: 22px;
font-weight: bold;
text-align: left;
}
h2 {
margin-top: 0;
color: #333333;
font-size: 16px;
font-weight: bold;
text-align: left;
}
h3 {
margin-top: 0;
color: #333333;
font-size: 14px;
font-weight: bold;
text-align: left;
}
td,
th {
font-size: 16px;
}
p,
ul,
ol,
blockquote {
margin: .4em 0 1.1875em;
font-size: 16px;
line-height: 1.625;
}
p.sub {
font-size: 13px;
}
/* Utilities ------------------------------ */
.align-right {
text-align: right;
}
.align-left {
text-align: left;
}
.align-center {
text-align: center;
}
.u-margin-bottom-none {
margin-bottom: 0;
}
/* Buttons ------------------------------ */
.button {
background-color: #3869D4;
border-top: 10px solid #3869D4;
border-right: 18px solid #3869D4;
border-bottom: 10px solid #3869D4;
border-left: 18px solid #3869D4;
display: inline-block;
color: #FFF;
text-decoration: none;
border-radius: 3px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.16);
-webkit-text-size-adjust: none;
box-sizing: border-box;
}
.button--green {
background-color: #22BC66;
border-top: 10px solid #22BC66;
border-right: 18px solid #22BC66;
border-bottom: 10px solid #22BC66;
border-left: 18px solid #22BC66;
}
.button--red {
background-color: #FF6136;
border-top: 10px solid #FF6136;
border-right: 18px solid #FF6136;
border-bottom: 10px solid #FF6136;
border-left: 18px solid #FF6136;
}
@media only screen and (max-width: 500px) {
.button {
width: 100% !important;
text-align: center !important;
}
}
/* Attribute list ------------------------------ */
.attributes {
margin: 0 0 21px;
}
.attributes_content {
background-color: #F4F4F7;
padding: 16px;
}
.attributes_item {
padding: 0;
}
/* Related Items ------------------------------ */
.related {
width: 100%;
margin: 0;
padding: 25px 0 0 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.related_item {
padding: 10px 0;
color: #CBCCCF;
font-size: 15px;
line-height: 18px;
}
.related_item-title {
display: block;
margin: .5em 0 0;
}
.related_item-thumb {
display: block;
padding-bottom: 10px;
}
.related_heading {
border-top: 1px solid #CBCCCF;
text-align: center;
padding: 25px 0 10px;
}
/* Discount Code ------------------------------ */
.discount {
width: 100%;
margin: 0;
padding: 24px;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
background-color: #F4F4F7;
border: 2px dashed #CBCCCF;
}
.discount_heading {
text-align: center;
}
.discount_body {
text-align: center;
font-size: 15px;
}
/* Social Icons ------------------------------ */
.social {
width: auto;
}
.social td {
padding: 0;
width: auto;
}
.social_icon {
height: 20px;
margin: 0 8px 10px 8px;
padding: 0;
}
/* Data table ------------------------------ */
.purchase {
width: 100%;
margin: 0;
padding: 35px 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.purchase_content {
width: 100%;
margin: 0;
padding: 25px 0 0 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.purchase_item {
padding: 10px 0;
color: #51545E;
font-size: 15px;
line-height: 18px;
}
.purchase_heading {
padding-bottom: 8px;
border-bottom: 1px solid #EAEAEC;
}
.purchase_heading p {
margin: 0;
color: #85878E;
font-size: 12px;
}
.purchase_footer {
padding-top: 15px;
border-top: 1px solid #EAEAEC;
}
.purchase_total {
margin: 0;
text-align: right;
font-weight: bold;
color: #333333;
}
.purchase_total--label {
padding: 0 15px 0 0;
}
body {
background-color: #F2F4F6;
color: #51545E;
}
p {
color: #51545E;
}
.email-wrapper {
width: 100%;
margin: 0;
padding: 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
background-color: #F2F4F6;
}
.email-content {
width: 100%;
margin: 0;
padding: 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
/* Masthead ----------------------- */
.email-masthead {
padding: 25px 0;
text-align: center;
}
.email-masthead_logo {
width: 94px;
}
.email-masthead_name {
font-size: 16px;
font-weight: bold;
color: #A8AAAF;
text-decoration: none;
text-shadow: 0 1px 0 white;
}
/* Body ------------------------------ */
.email-body {
width: 100%;
margin: 0;
padding: 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.email-body_inner {
width: 570px;
margin: 0 auto;
padding: 0;
-premailer-width: 570px;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
background-color: #FFFFFF;
}
.email-footer {
width: 570px;
margin: 0 auto;
padding: 0;
-premailer-width: 570px;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
text-align: center;
}
.email-footer p {
color: #A8AAAF;
}
.body-action {
width: 100%;
margin: 30px auto;
padding: 0;
font-size: 42px;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
text-align: center;
}
.body-sub {
margin-top: 25px;
padding-top: 25px;
border-top: 1px solid #EAEAEC;
}
.content-cell {
padding: 45px;
}
/*Media Queries ------------------------------ */
@media only screen and (max-width: 600px) {
.email-body_inner,
.email-footer {
width: 100% !important;
}
}
@media (prefers-color-scheme: dark) {
body,
.email-body,
.email-body_inner,
.email-content,
.email-wrapper,
.email-masthead,
.email-footer {
background-color: #333333 !important;
color: #FFF !important;
}
p,
ul,
ol,
blockquote,
h1,
h2,
h3,
span,
.purchase_item {
color: #FFF !important;
}
.attributes_content,
.discount {
background-color: #222 !important;
}
.email-masthead_name {
text-shadow: none !important;
}
}
:root {
color-scheme: light dark;
supported-color-schemes: light dark;
}
</style>
<!--[if mso]>
<style type="text/css">
.f-fallback {
font-family: Arial, sans-serif;
}
</style>
<![endif]-->
</head>
<body>
<span class="preheader">Use this link to reset your password. The link is only valid for 24 hours.</span>
<table class="email-wrapper" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td align="center">
<table class="email-content" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td class="email-masthead">
<a href="http://link56.net/" class="f-fallback email-masthead_name">
link56
</a>
</td>
</tr>
<!-- Email Body -->
<tr>
<td class="email-body" width="570" cellpadding="0" cellspacing="0">
<table class="email-body_inner" align="center" width="570" cellpadding="0" cellspacing="0"
role="presentation">
<!-- Body content -->
<tr>
<td class="content-cell">
<div class="f-fallback">
<h1>您好</h1>
<p>
您正在 <strong>link56</strong> 平台进行<strong>找回密码</strong>操作,
密码如下,请注意保存。
</p>
<p class="body-action">
[[${Password}]]
</p>
<p>如果不是您本人操作,请忽略此邮件,或如有疑问,请 <a
href="{{SupportUrl}}">联系客服</a>。</p>
<p>
感谢,<br>
link56 团队
</p>
</div>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<table class="email-footer" align="center" width="570" cellpadding="0" cellspacing="0"
role="presentation">
<tr>
<td class="content-cell" align="center">
<p class="f-fallback sub align-center">
宁波江东远通计算机有限公司
</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
@@ -0,0 +1,525 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="x-apple-disable-message-reformatting" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="color-scheme" content="light dark" />
<meta name="supported-color-schemes" content="light dark" />
<title></title>
<style type="text/css" rel="stylesheet" media="all">
/* Base ------------------------------ */
@import url("https://fonts.googleapis.com/css?family=Nunito+Sans:400,700&display=swap");
body {
width: 100% !important;
height: 100%;
margin: 0;
-webkit-text-size-adjust: none;
}
a {
color: #3869D4;
}
a img {
border: none;
}
td {
word-break: break-word;
}
.preheader {
display: none !important;
visibility: hidden;
mso-hide: all;
font-size: 1px;
line-height: 1px;
max-height: 0;
max-width: 0;
opacity: 0;
overflow: hidden;
}
/* Type ------------------------------ */
body,
td,
th {
font-family: "Nunito Sans", Helvetica, Arial, sans-serif;
}
h1 {
margin-top: 0;
color: #333333;
font-size: 22px;
font-weight: bold;
text-align: left;
}
h2 {
margin-top: 0;
color: #333333;
font-size: 16px;
font-weight: bold;
text-align: left;
}
h3 {
margin-top: 0;
color: #333333;
font-size: 14px;
font-weight: bold;
text-align: left;
}
td,
th {
font-size: 16px;
}
p,
ul,
ol,
blockquote {
margin: .4em 0 1.1875em;
font-size: 16px;
line-height: 1.625;
}
p.sub {
font-size: 13px;
}
/* Utilities ------------------------------ */
.align-right {
text-align: right;
}
.align-left {
text-align: left;
}
.align-center {
text-align: center;
}
.u-margin-bottom-none {
margin-bottom: 0;
}
/* Buttons ------------------------------ */
.button {
background-color: #3869D4;
border-top: 10px solid #3869D4;
border-right: 18px solid #3869D4;
border-bottom: 10px solid #3869D4;
border-left: 18px solid #3869D4;
display: inline-block;
color: #FFF;
text-decoration: none;
border-radius: 3px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.16);
-webkit-text-size-adjust: none;
box-sizing: border-box;
}
.button--green {
background-color: #22BC66;
border-top: 10px solid #22BC66;
border-right: 18px solid #22BC66;
border-bottom: 10px solid #22BC66;
border-left: 18px solid #22BC66;
}
.button--red {
background-color: #FF6136;
border-top: 10px solid #FF6136;
border-right: 18px solid #FF6136;
border-bottom: 10px solid #FF6136;
border-left: 18px solid #FF6136;
}
@media only screen and (max-width: 500px) {
.button {
width: 100% !important;
text-align: center !important;
}
}
/* Attribute list ------------------------------ */
.attributes {
margin: 0 0 21px;
}
.attributes_content {
background-color: #F4F4F7;
padding: 16px;
}
.attributes_item {
padding: 0;
}
/* Related Items ------------------------------ */
.related {
width: 100%;
margin: 0;
padding: 25px 0 0 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.related_item {
padding: 10px 0;
color: #CBCCCF;
font-size: 15px;
line-height: 18px;
}
.related_item-title {
display: block;
margin: .5em 0 0;
}
.related_item-thumb {
display: block;
padding-bottom: 10px;
}
.related_heading {
border-top: 1px solid #CBCCCF;
text-align: center;
padding: 25px 0 10px;
}
/* Discount Code ------------------------------ */
.discount {
width: 100%;
margin: 0;
padding: 24px;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
background-color: #F4F4F7;
border: 2px dashed #CBCCCF;
}
.discount_heading {
text-align: center;
}
.discount_body {
text-align: center;
font-size: 15px;
}
/* Social Icons ------------------------------ */
.social {
width: auto;
}
.social td {
padding: 0;
width: auto;
}
.social_icon {
height: 20px;
margin: 0 8px 10px 8px;
padding: 0;
}
/* Data table ------------------------------ */
.purchase {
width: 100%;
margin: 0;
padding: 35px 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.purchase_content {
width: 100%;
margin: 0;
padding: 25px 0 0 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.purchase_item {
padding: 10px 0;
color: #51545E;
font-size: 15px;
line-height: 18px;
}
.purchase_heading {
padding-bottom: 8px;
border-bottom: 1px solid #EAEAEC;
}
.purchase_heading p {
margin: 0;
color: #85878E;
font-size: 12px;
}
.purchase_footer {
padding-top: 15px;
border-top: 1px solid #EAEAEC;
}
.purchase_total {
margin: 0;
text-align: right;
font-weight: bold;
color: #333333;
}
.purchase_total--label {
padding: 0 15px 0 0;
}
body {
background-color: #F2F4F6;
color: #51545E;
}
p {
color: #51545E;
}
.email-wrapper {
width: 100%;
margin: 0;
padding: 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
background-color: #F2F4F6;
}
.email-content {
width: 100%;
margin: 0;
padding: 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
/* Masthead ----------------------- */
.email-masthead {
padding: 25px 0;
text-align: center;
}
.email-masthead_logo {
width: 94px;
}
.email-masthead_name {
font-size: 16px;
font-weight: bold;
color: #A8AAAF;
text-decoration: none;
text-shadow: 0 1px 0 white;
}
/* Body ------------------------------ */
.email-body {
width: 100%;
margin: 0;
padding: 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.email-body_inner {
width: 570px;
margin: 0 auto;
padding: 0;
-premailer-width: 570px;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
background-color: #FFFFFF;
}
.email-footer {
width: 570px;
margin: 0 auto;
padding: 0;
-premailer-width: 570px;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
text-align: center;
}
.email-footer p {
color: #A8AAAF;
}
.body-action {
width: 100%;
margin: 30px auto;
padding: 0;
font-size: 42px;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
text-align: center;
}
.body-sub {
margin-top: 25px;
padding-top: 25px;
border-top: 1px solid #EAEAEC;
}
.content-cell {
padding: 45px;
}
/*Media Queries ------------------------------ */
@media only screen and (max-width: 600px) {
.email-body_inner,
.email-footer {
width: 100% !important;
}
}
@media (prefers-color-scheme: dark) {
body,
.email-body,
.email-body_inner,
.email-content,
.email-wrapper,
.email-masthead,
.email-footer {
background-color: #333333 !important;
color: #FFF !important;
}
p,
ul,
ol,
blockquote,
h1,
h2,
h3,
span,
.purchase_item {
color: #FFF !important;
}
.attributes_content,
.discount {
background-color: #222 !important;
}
.email-masthead_name {
text-shadow: none !important;
}
}
:root {
color-scheme: light dark;
supported-color-schemes: light dark;
}
</style>
<!--[if mso]>
<style type="text/css">
.f-fallback {
font-family: Arial, sans-serif;
}
</style>
<![endif]-->
</head>
<body>
<span class="preheader">Use this link to reset your password. The link is only valid for 24 hours.</span>
<table class="email-wrapper" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td align="center">
<table class="email-content" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td class="email-masthead">
<a href="http://link56.net/" class="f-fallback email-masthead_name">
link56
</a>
</td>
</tr>
<!-- Email Body -->
<tr>
<td class="email-body" width="570" cellpadding="0" cellspacing="0">
<table class="email-body_inner" align="center" width="570" cellpadding="0" cellspacing="0"
role="presentation">
<!-- Body content -->
<tr>
<td class="content-cell">
<div class="f-fallback">
<h1>您好</h1>
<p>
您正在 <strong>link56</strong> 平台进行<strong>登录</strong>操作,
系统已为您生成邮箱验证码。
<strong>该验证码仅在 10 分钟内有效。</strong>
</p>
<p class="body-action">
[[${Code}]]
</p>
<p>如果不是您本人操作,请忽略此邮件,或如有疑问,请 <a
href="{{SupportUrl}}">联系客服</a>。</p>
<p>
感谢,<br>
link56 团队
</p>
</div>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<table class="email-footer" align="center" width="570" cellpadding="0" cellspacing="0"
role="presentation">
<tr>
<td class="content-cell" align="center">
<p class="f-fallback sub align-center">
宁波江东远通计算机有限公司
</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
@@ -0,0 +1,527 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="x-apple-disable-message-reformatting" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="color-scheme" content="light dark" />
<meta name="supported-color-schemes" content="light dark" />
<title></title>
<style type="text/css" rel="stylesheet" media="all">
/* Base ------------------------------ */
@import url("https://fonts.googleapis.com/css?family=Nunito+Sans:400,700&display=swap");
body {
width: 100% !important;
height: 100%;
margin: 0;
-webkit-text-size-adjust: none;
}
a {
color: #3869D4;
}
a img {
border: none;
}
td {
word-break: break-word;
}
.preheader {
display: none !important;
visibility: hidden;
mso-hide: all;
font-size: 1px;
line-height: 1px;
max-height: 0;
max-width: 0;
opacity: 0;
overflow: hidden;
}
/* Type ------------------------------ */
body,
td,
th {
font-family: "Nunito Sans", Helvetica, Arial, sans-serif;
}
h1 {
margin-top: 0;
color: #333333;
font-size: 22px;
font-weight: bold;
text-align: left;
}
h2 {
margin-top: 0;
color: #333333;
font-size: 16px;
font-weight: bold;
text-align: left;
}
h3 {
margin-top: 0;
color: #333333;
font-size: 14px;
font-weight: bold;
text-align: left;
}
td,
th {
font-size: 16px;
}
p,
ul,
ol,
blockquote {
margin: .4em 0 1.1875em;
font-size: 16px;
line-height: 1.625;
}
p.sub {
font-size: 13px;
}
/* Utilities ------------------------------ */
.align-right {
text-align: right;
}
.align-left {
text-align: left;
}
.align-center {
text-align: center;
}
.u-margin-bottom-none {
margin-bottom: 0;
}
/* Buttons ------------------------------ */
.button {
background-color: #3869D4;
border-top: 10px solid #3869D4;
border-right: 18px solid #3869D4;
border-bottom: 10px solid #3869D4;
border-left: 18px solid #3869D4;
display: inline-block;
color: #FFF;
text-decoration: none;
border-radius: 3px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.16);
-webkit-text-size-adjust: none;
box-sizing: border-box;
}
.button--green {
background-color: #22BC66;
border-top: 10px solid #22BC66;
border-right: 18px solid #22BC66;
border-bottom: 10px solid #22BC66;
border-left: 18px solid #22BC66;
}
.button--red {
background-color: #FF6136;
border-top: 10px solid #FF6136;
border-right: 18px solid #FF6136;
border-bottom: 10px solid #FF6136;
border-left: 18px solid #FF6136;
}
@media only screen and (max-width: 500px) {
.button {
width: 100% !important;
text-align: center !important;
}
}
/* Attribute list ------------------------------ */
.attributes {
margin: 0 0 21px;
}
.attributes_content {
background-color: #F4F4F7;
padding: 16px;
}
.attributes_item {
padding: 0;
}
/* Related Items ------------------------------ */
.related {
width: 100%;
margin: 0;
padding: 25px 0 0 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.related_item {
padding: 10px 0;
color: #CBCCCF;
font-size: 15px;
line-height: 18px;
}
.related_item-title {
display: block;
margin: .5em 0 0;
}
.related_item-thumb {
display: block;
padding-bottom: 10px;
}
.related_heading {
border-top: 1px solid #CBCCCF;
text-align: center;
padding: 25px 0 10px;
}
/* Discount Code ------------------------------ */
.discount {
width: 100%;
margin: 0;
padding: 24px;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
background-color: #F4F4F7;
border: 2px dashed #CBCCCF;
}
.discount_heading {
text-align: center;
}
.discount_body {
text-align: center;
font-size: 15px;
}
/* Social Icons ------------------------------ */
.social {
width: auto;
}
.social td {
padding: 0;
width: auto;
}
.social_icon {
height: 20px;
margin: 0 8px 10px 8px;
padding: 0;
}
/* Data table ------------------------------ */
.purchase {
width: 100%;
margin: 0;
padding: 35px 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.purchase_content {
width: 100%;
margin: 0;
padding: 25px 0 0 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.purchase_item {
padding: 10px 0;
color: #51545E;
font-size: 15px;
line-height: 18px;
}
.purchase_heading {
padding-bottom: 8px;
border-bottom: 1px solid #EAEAEC;
}
.purchase_heading p {
margin: 0;
color: #85878E;
font-size: 12px;
}
.purchase_footer {
padding-top: 15px;
border-top: 1px solid #EAEAEC;
}
.purchase_total {
margin: 0;
text-align: right;
font-weight: bold;
color: #333333;
}
.purchase_total--label {
padding: 0 15px 0 0;
}
body {
background-color: #F2F4F6;
color: #51545E;
}
p {
color: #51545E;
}
.email-wrapper {
width: 100%;
margin: 0;
padding: 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
background-color: #F2F4F6;
}
.email-content {
width: 100%;
margin: 0;
padding: 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
/* Masthead ----------------------- */
.email-masthead {
padding: 25px 0;
text-align: center;
}
.email-masthead_logo {
width: 94px;
}
.email-masthead_name {
font-size: 16px;
font-weight: bold;
color: #A8AAAF;
text-decoration: none;
text-shadow: 0 1px 0 white;
}
/* Body ------------------------------ */
.email-body {
width: 100%;
margin: 0;
padding: 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.email-body_inner {
width: 570px;
margin: 0 auto;
padding: 0;
-premailer-width: 570px;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
background-color: #FFFFFF;
}
.email-footer {
width: 570px;
margin: 0 auto;
padding: 0;
-premailer-width: 570px;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
text-align: center;
}
.email-footer p {
color: #A8AAAF;
}
.body-action {
width: 100%;
margin: 30px auto;
padding: 0;
font-size: 42px;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
text-align: center;
}
.body-sub {
margin-top: 25px;
padding-top: 25px;
border-top: 1px solid #EAEAEC;
}
.content-cell {
padding: 45px;
}
/*Media Queries ------------------------------ */
@media only screen and (max-width: 600px) {
.email-body_inner,
.email-footer {
width: 100% !important;
}
}
@media (prefers-color-scheme: dark) {
body,
.email-body,
.email-body_inner,
.email-content,
.email-wrapper,
.email-masthead,
.email-footer {
background-color: #333333 !important;
color: #FFF !important;
}
p,
ul,
ol,
blockquote,
h1,
h2,
h3,
span,
.purchase_item {
color: #FFF !important;
}
.attributes_content,
.discount {
background-color: #222 !important;
}
.email-masthead_name {
text-shadow: none !important;
}
}
:root {
color-scheme: light dark;
supported-color-schemes: light dark;
}
</style>
<!--[if mso]>
<style type="text/css">
.f-fallback {
font-family: Arial, sans-serif;
}
</style>
<![endif]-->
</head>
<body>
<span class="preheader">Use this link to reset your password. The link is only valid for 24 hours.</span>
<table class="email-wrapper" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td align="center">
<table class="email-content" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td class="email-masthead">
<a href="http://link56.net/" class="f-fallback email-masthead_name">
link56
</a>
</td>
</tr>
<!-- Email Body -->
<tr>
<td class="email-body" width="570" cellpadding="0" cellspacing="0">
<table class="email-body_inner" align="center" width="570" cellpadding="0" cellspacing="0"
role="presentation">
<!-- Body content -->
<tr>
<td class="content-cell">
<div class="f-fallback">
<h1>您好</h1>
<p>
您正在 <strong>link56</strong> 平台进行<strong>注册</strong>操作,
系统已为您生成邮箱验证码。
<strong>该验证码仅在 10 分钟内有效。</strong>
</p>
<p class="body-action">
[[${Code}]]
</p>
<p>如果不是您本人操作,请忽略此邮件,或如有疑问,请 <a
href="{{SupportUrl}}">联系客服</a>。</p>
<p>
感谢,<br>
link56 团队
</p>
</div>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<table class="email-footer" align="center" width="570" cellpadding="0" cellspacing="0"
role="presentation">
<tr>
<td class="content-cell" align="center">
<p class="f-fallback sub align-center">
宁波江东远通计算机有限公司
</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
@@ -0,0 +1,526 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="x-apple-disable-message-reformatting" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="color-scheme" content="light dark" />
<meta name="supported-color-schemes" content="light dark" />
<title></title>
<style type="text/css" rel="stylesheet" media="all">
/* Base ------------------------------ */
@import url("https://fonts.googleapis.com/css?family=Nunito+Sans:400,700&display=swap");
body {
width: 100% !important;
height: 100%;
margin: 0;
-webkit-text-size-adjust: none;
}
a {
color: #3869D4;
}
a img {
border: none;
}
td {
word-break: break-word;
}
.preheader {
display: none !important;
visibility: hidden;
mso-hide: all;
font-size: 1px;
line-height: 1px;
max-height: 0;
max-width: 0;
opacity: 0;
overflow: hidden;
}
/* Type ------------------------------ */
body,
td,
th {
font-family: "Nunito Sans", Helvetica, Arial, sans-serif;
}
h1 {
margin-top: 0;
color: #333333;
font-size: 22px;
font-weight: bold;
text-align: left;
}
h2 {
margin-top: 0;
color: #333333;
font-size: 16px;
font-weight: bold;
text-align: left;
}
h3 {
margin-top: 0;
color: #333333;
font-size: 14px;
font-weight: bold;
text-align: left;
}
td,
th {
font-size: 16px;
}
p,
ul,
ol,
blockquote {
margin: .4em 0 1.1875em;
font-size: 16px;
line-height: 1.625;
}
p.sub {
font-size: 13px;
}
/* Utilities ------------------------------ */
.align-right {
text-align: right;
}
.align-left {
text-align: left;
}
.align-center {
text-align: center;
}
.u-margin-bottom-none {
margin-bottom: 0;
}
/* Buttons ------------------------------ */
.button {
background-color: #3869D4;
border-top: 10px solid #3869D4;
border-right: 18px solid #3869D4;
border-bottom: 10px solid #3869D4;
border-left: 18px solid #3869D4;
display: inline-block;
color: #FFF;
text-decoration: none;
border-radius: 3px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.16);
-webkit-text-size-adjust: none;
box-sizing: border-box;
}
.button--green {
background-color: #22BC66;
border-top: 10px solid #22BC66;
border-right: 18px solid #22BC66;
border-bottom: 10px solid #22BC66;
border-left: 18px solid #22BC66;
}
.button--red {
background-color: #FF6136;
border-top: 10px solid #FF6136;
border-right: 18px solid #FF6136;
border-bottom: 10px solid #FF6136;
border-left: 18px solid #FF6136;
}
@media only screen and (max-width: 500px) {
.button {
width: 100% !important;
text-align: center !important;
}
}
/* Attribute list ------------------------------ */
.attributes {
margin: 0 0 21px;
}
.attributes_content {
background-color: #F4F4F7;
padding: 16px;
}
.attributes_item {
padding: 0;
}
/* Related Items ------------------------------ */
.related {
width: 100%;
margin: 0;
padding: 25px 0 0 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.related_item {
padding: 10px 0;
color: #CBCCCF;
font-size: 15px;
line-height: 18px;
}
.related_item-title {
display: block;
margin: .5em 0 0;
}
.related_item-thumb {
display: block;
padding-bottom: 10px;
}
.related_heading {
border-top: 1px solid #CBCCCF;
text-align: center;
padding: 25px 0 10px;
}
/* Discount Code ------------------------------ */
.discount {
width: 100%;
margin: 0;
padding: 24px;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
background-color: #F4F4F7;
border: 2px dashed #CBCCCF;
}
.discount_heading {
text-align: center;
}
.discount_body {
text-align: center;
font-size: 15px;
}
/* Social Icons ------------------------------ */
.social {
width: auto;
}
.social td {
padding: 0;
width: auto;
}
.social_icon {
height: 20px;
margin: 0 8px 10px 8px;
padding: 0;
}
/* Data table ------------------------------ */
.purchase {
width: 100%;
margin: 0;
padding: 35px 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.purchase_content {
width: 100%;
margin: 0;
padding: 25px 0 0 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.purchase_item {
padding: 10px 0;
color: #51545E;
font-size: 15px;
line-height: 18px;
}
.purchase_heading {
padding-bottom: 8px;
border-bottom: 1px solid #EAEAEC;
}
.purchase_heading p {
margin: 0;
color: #85878E;
font-size: 12px;
}
.purchase_footer {
padding-top: 15px;
border-top: 1px solid #EAEAEC;
}
.purchase_total {
margin: 0;
text-align: right;
font-weight: bold;
color: #333333;
}
.purchase_total--label {
padding: 0 15px 0 0;
}
body {
background-color: #F2F4F6;
color: #51545E;
}
p {
color: #51545E;
}
.email-wrapper {
width: 100%;
margin: 0;
padding: 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
background-color: #F2F4F6;
}
.email-content {
width: 100%;
margin: 0;
padding: 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
/* Masthead ----------------------- */
.email-masthead {
padding: 25px 0;
text-align: center;
}
.email-masthead_logo {
width: 94px;
}
.email-masthead_name {
font-size: 16px;
font-weight: bold;
color: #A8AAAF;
text-decoration: none;
text-shadow: 0 1px 0 white;
}
/* Body ------------------------------ */
.email-body {
width: 100%;
margin: 0;
padding: 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.email-body_inner {
width: 570px;
margin: 0 auto;
padding: 0;
-premailer-width: 570px;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
background-color: #FFFFFF;
}
.email-footer {
width: 570px;
margin: 0 auto;
padding: 0;
-premailer-width: 570px;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
text-align: center;
}
.email-footer p {
color: #A8AAAF;
}
.body-action {
width: 100%;
margin: 30px auto;
padding: 0;
font-size: 42px;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
text-align: center;
}
.body-sub {
margin-top: 25px;
padding-top: 25px;
border-top: 1px solid #EAEAEC;
}
.content-cell {
padding: 45px;
}
/*Media Queries ------------------------------ */
@media only screen and (max-width: 600px) {
.email-body_inner,
.email-footer {
width: 100% !important;
}
}
@media (prefers-color-scheme: dark) {
body,
.email-body,
.email-body_inner,
.email-content,
.email-wrapper,
.email-masthead,
.email-footer {
background-color: #333333 !important;
color: #FFF !important;
}
p,
ul,
ol,
blockquote,
h1,
h2,
h3,
span,
.purchase_item {
color: #FFF !important;
}
.attributes_content,
.discount {
background-color: #222 !important;
}
.email-masthead_name {
text-shadow: none !important;
}
}
:root {
color-scheme: light dark;
supported-color-schemes: light dark;
}
</style>
<!--[if mso]>
<style type="text/css">
.f-fallback {
font-family: Arial, sans-serif;
}
</style>
<![endif]-->
</head>
<body>
<span class="preheader">Use this link to reset your password. The link is only valid for 24 hours.</span>
<table class="email-wrapper" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td align="center">
<table class="email-content" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td class="email-masthead">
<a href="http://link56.net/" class="f-fallback email-masthead_name">
link56
</a>
</td>
</tr>
<!-- Email Body -->
<tr>
<td class="email-body" width="570" cellpadding="0" cellspacing="0">
<table class="email-body_inner" align="center" width="570" cellpadding="0" cellspacing="0"
role="presentation">
<!-- Body content -->
<tr>
<td class="content-cell">
<div class="f-fallback">
<h1>您好</h1>
<p>
您正在 <strong>link56</strong> 平台进行<strong>认证邮箱修改</strong>操作,
系统已为您生成邮箱验证码。
<strong>该验证码仅在 10 分钟内有效。</strong>
</p>
<p class="body-action">
[[${Code}]]
</p>
<p>如果不是您本人操作,请忽略此邮件,或如有疑问,请 <a
href="{{SupportUrl}}">联系客服</a>。</p>
<p>
感谢,<br>
link56 团队
</p>
</div>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<table class="email-footer" align="center" width="570" cellpadding="0" cellspacing="0"
role="presentation">
<tr>
<td class="content-cell" align="center">
<p class="f-fallback sub align-center">
宁波江东远通计算机有限公司
</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>