Initial project

This commit is contained in:
Timi
2025-07-08 16:31:30 +08:00
parent 1c6a45c8c2
commit ae0f56a6dc
356 changed files with 21123 additions and 109 deletions
+101
View File
@@ -0,0 +1,101 @@
server:
port: 8091
shutdown: graceful
# 开发环境语言,激活开发配置时,多语言系统始终使用此语言环境
dev:
lang: zh_CN
# 日志配置
logging:
config: config/logback.xml
# Spring
spring:
profiles:
active: prod
servlet:
multipart:
max-file-size: 4GB
max-request-size: 4GB
lifecycle:
timeout-per-shutdown-phase: 32s
async:
thread-pool:
core-pool-size: 16
max-pool-size: 32
queueCapacity: 16
keep-alive-seconds: 60
thread-name-prefix: thread-pool-task-executor-
await-termination-seconds: 60
mail: # 邮件配置
host: smtp.qq.com
username: imyeyu@qq.com
password: saodifhaposjfoas
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
default-encoding: UTF-8
mvc: # JSON 序列化
converters:
preferred-json-mapper: gson # 返回 JSON 序列化使用 GSON
redis: # Redis 数据库
host: dev.vm.imyeyu.test
port: 6379
password:
timeout: 8000
database:
locker: 0 # ID: Integer 全局锁,ID 规范:应用:模块:业务:方法
multilingual: 1 # ID: Multilingual 多语言缓存
multilingual-map: 2 # Key: ID 多语言键缓存
article-ranking: 3 # AID: ArticleRanking(JSON) 热门文章排位
article-read: 4 # IP: [AID..] IP 阅读文章记录
user-token: 5 # TOKEN: LONG 用户登录令牌
user-exp-flag: 6 # UID: NULL 用户登录经验标记,暂时没有值,数据死亡时间为次日零时
user-email-verify: 7 # AES_KEY: UID 邮箱验证密钥缓存
user-reset-pw-verify: 8 # AES_KEY: UID 重置密码密钥缓存
qps-limit: 9 # APP.IP.method: COUNT_IN_LIFE_CYCLE 接口访问频率控制(多个系统公用,需要 App 标记)
setting: 10 # Setting: SettingValue 系统配置
fmc-player-token: 11 # TOKEN: USER_ID|PLAYER_ID MC 登录缓存
lettuce: # 连接池配置
pool:
max-wait: -1
max-idle: 8
min-idle: 0
max-active: 8
datasource: # 数据库配置
timiserver:
jdbc-url: jdbc:mysql://dev.vm.imyeyu.test:3306/timi_server?serverTimezone=UTC&characterEncoding=UTF-8
username: root
password: 123123
driver-class-name: com.mysql.cj.jdbc.Driver
forevermc:
jdbc-url: jdbc:mysql://dev.vm.imyeyu.test:3306/authme?serverTimezone=UTC&characterEncoding=UTF-8
username: root
password: 123123
driver-class-name: com.mysql.cj.jdbc.Driver
gitea:
jdbc-url: jdbc:mysql://dev.vm.imyeyu.test:3306/authme?serverTimezone=UTC&characterEncoding=UTF-8
username: root
password: 123123
driver-class-name: com.mysql.cj.jdbc.Driver
data:
mongodb:
host: dev.vm.imyeyu.test
port: 27017
database: db
username: root
password: qweqwe123
# CORS 跨域
cors:
# 允许访问的客户端域名,如:http://web.xxx.com,* 表示不做任何限制(不做任何限制时 allow-credentials 无效)
allow-origin:
- "http://localhost:8080"
allow-methods: "*" # 允许请求的方法名,多个方法名逗号分割,如:GET, POST, PUT, DELETE, OPTIONS
allow-credentials: true # 是否允许请求带有验证信息,若要获取客户端域下的 Cookie 或 Session 时,设置为 true
allow-headers: "*" # 允许服务端访问的客户端请求头,多个请求头逗号分割,如:Content-BizType
+9
View File
@@ -0,0 +1,9 @@
______ _ __ _ _
/ __\ (_)_ __ ___ _ _ ___ _ _ _ _ ___ ___ _ __ ___ \ \ \ \
/ . . \ ' | | '_ _ \| | | |/ _ \ | | | | | | / __/ _ \| '_ _ \ \ \ \ \
( ) | | | | | | | |_| | __/ |_| | |_| || (_| (_) | | | | | | ) ) ) )
'\ ___ /' |_|_| |_| |_|\__, |\___|\__, |\__,_(_)___\___/|_| |_| |_| / / / /
--'---'-------------------|___/------|___/-----------------------------/_/_/_/
Banner drawn by https://patorjk.com/software/taag for Ivrit
Spring Boot Version: ${spring-boot.version}
+25
View File
@@ -0,0 +1,25 @@
<configuration>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<charset>UTF-8</charset>
<pattern>[%d{HH:mm:ss.SSS}][%-5level][%-54logger{54}] %msg%n</pattern>
</encoder>
<filter class="com.imyeyu.server.modules.system.util.LoggerFilter" />
</appender>
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>./logs/debug.log</file>
<encoder>
<charset>UTF-8</charset>
<pattern>[%d{HH:mm:ss.SSS}][%-5level][%-54logger{54}] %msg%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>./logs/debug/debug.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<filter class="com.imyeyu.server.modules.system.util.LoggerFilter" />
</appender>
<root level="info">
<appender-ref ref="file" />
<appender-ref ref="console" />
</root>
</configuration>
@@ -0,0 +1,65 @@
<?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="com.imyeyu.server.modules.blog.mapper.ArticleMapper">
<sql id="table">article</sql>
<!-- 查询列表的文章字段 -->
<sql id="listColumn">
article.id,
article.type,
article.title,
article.digest,
article.likes,
article.reads,
article.created_at,
article.updated_at
</sql>
<!-- 主页列表 -->
<sql id="normalCondition">
FROM
article
WHERE
1 &lt; article.id
AND article.deleted_at IS NULL
</sql>
<select id="count" resultType="long">
SELECT COUNT(1) <include refid="normalCondition" />
</select>
<select id="list" resultType="com.imyeyu.server.modules.blog.entity.Article">
SELECT
<include refid="listColumn" />
<include refid="normalCondition" />
ORDER BY
COALESCE(article.updated_at, article.created_at) DESC
LIMIT
#{offset}, #{limit}
</select>
<!-- 根据关键字获取列表 -->
<sql id="byKeywordCondition">
FROM
article
WHERE
1 &lt; article.id
AND (
article.title LIKE CONCAT('%', #{keyword}, '%')
OR article.digest LIKE CONCAT('%', #{keyword}, '%')
)
AND article.deleted_at IS NULL
</sql>
<select id="countByKeyword" resultType="long">
SELECT COUNT(1) <include refid="byKeywordCondition" />
</select>
<select id="selectByKeyword" resultType="com.imyeyu.server.modules.blog.entity.Article">
SELECT
<include refid="listColumn" />
<include refid="byKeywordCondition" />
ORDER BY
COALESCE(article.updated_at, article.created_at) DESC
LIMIT
#{offset}, #{limit}
</select>
</mapper>
@@ -0,0 +1,22 @@
<?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="com.imyeyu.server.modules.common.mapper.AttachmentMapper">
<sql id="table">attachment</sql>
<select id="listByAttachType" resultType="com.imyeyu.server.modules.common.entity.Attachment">
SELECT
*
FROM
<include refid="table" />
WHERE
biz_type = #{bizType}
AND biz_id = #{bizId}
<if test="attachTypes != null and 0 &lt; attachTypes.length">
AND attach_type IN
<foreach collection="attachTypes" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</if>
AND deleted_at IS NULL
AND destroy_at IS NULL
</select>
</mapper>
@@ -0,0 +1,143 @@
<?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="com.imyeyu.server.modules.common.mapper.CommentMapper">
<sql id="table">comment</sql>
<!-- 主评论 -->
<select id="list" resultMap="listResult">
SELECT
-- 主评论
comment.id,
comment.biz_type,
comment.biz_id,
comment.user_id,
comment.nick,
comment.content,
comment.created_at,
-- 回复数量
reply_count.reply_length,
-- 回复
reply.id AS reply_id,
reply.comment_id,
reply.sender_id,
reply.sender_nick,
reply.receiver_id,
reply.receiver_nick,
reply.content AS reply_content,
reply.created_at AS reply_created_at
FROM (
-- 查询主评论
SELECT
*
FROM
<include refid="table" />
WHERE
biz_type = #{bizType}
AND biz_id = #{bizId}
AND deleted_at IS NULL
ORDER BY
created_at ${orderMap.createdAt}
LIMIT
#{offset}, #{limit}
) AS comment
LEFT JOIN (
-- 查询前 6 条回复(时间升序)
SELECT
*
FROM (
SELECT
comment_reply.*,
ROW_NUMBER() OVER (
PARTITION BY comment_id
ORDER BY created_at ASC
) AS seq
FROM
comment_reply
WHERE
deleted_at IS NULL
) AS reply
WHERE
seq &lt; 7
) AS reply
ON
reply.comment_id = comment.id
LEFT JOIN(
-- 统计回复总数
SELECT
comment_id AS id,
COUNT(*) AS reply_length
FROM
comment_reply
WHERE
deleted_at IS NULL
GROUP BY
comment_id
) AS reply_count
ON
reply_count.id = comment.id
</select>
<resultMap id="listResult" type="com.imyeyu.server.modules.common.vo.comment.CommentView">
<id property="id" column="id" />
<result property="userId" column="user_id" />
<result property="nick" column="nick" />
<result property="content" column="content" />
<result property="repliesLength" column="reply_length" />
<result property="createdAt" column="created_at" />
<!-- 关联回复 -->
<collection property="replies" ofType="com.imyeyu.server.modules.common.vo.comment.CommentReplyView">
<id property="id" column="reply_id" />
<result property="commentId" column="comment_id" />
<result property="senderId" column="sender_id" />
<result property="senderNick" column="sender_nick" />
<result property="receiverId" column="receiver_id" />
<result property="receiverNick" column="receiver_nick" />
<result property="content" column="reply_content" />
<result property="createdAt" column="reply_created_at" />
</collection>
</resultMap>
<select id="countAll" resultType="long">
SELECT
SUM(result.total_comment + result.total_reply)
FROM (
SELECT
COUNT(DISTINCT comment.id) AS total_comment,
COUNT(comment_reply.comment_id) AS total_reply
FROM
comment
LEFT JOIN
comment_reply
ON
comment_reply.comment_id = comment.id
WHERE
comment.biz_type = #{bizType}
AND comment.biz_id = #{bizId}
AND comment.deleted_at IS NULL
AND comment_reply.deleted_at IS NULL
) AS result
</select>
<sql id="byUserIdCondition">
FROM
<include refid="table" />
WHERE
user_id = #{userId}
AND deleted_at IS NULL
</sql>
<select id="countByUserId" resultType="long">
SELECT COUNT(1) <include refid="byUserIdCondition" />
</select>
<select id="listByUserId" resultType="com.imyeyu.server.modules.common.vo.comment.CommentView">
SELECT
id,
biz_type,
biz_id,
content,
created_at
<include refid="byUserIdCondition" />
ORDER BY
created_at ${orderMap.createdAt}
LIMIT
#{offset}, #{limit}
</select>
</mapper>
@@ -0,0 +1,35 @@
<?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="com.imyeyu.server.modules.common.mapper.IconMapper">
<sql id="table">icon</sql>
<!-- 根据标签获取部分 -->
<sql id="byLabel">
FROM (
SELECT
id
FROM
icon_labels
WHERE
${lang} LIKE CONCAT('%', #{label}, '%')
AND icon_labels.deleted_at IS NULL
) AS labels
LEFT JOIN
icon_label
ON
icon_label.icon_label_id = labels.id
AND labels.id IS NOT NULL
LEFT JOIN
<include refid="table" />
ON
icon.id = icon_label.icon_id
WHERE
icon.id IS NOT NULL
AND icon.deleted_at IS NULL
</sql>
<select id="countByLabel" resultType="long">
SELECT COUNT(1) <include refid="byLabel" />
</select>
<select id="listByLabel" resultType="com.imyeyu.server.modules.common.entity.Icon">
SELECT icon.* <include refid="byLabel" /> LIMIT #{offset}, #{limit}
</select>
</mapper>
@@ -0,0 +1,11 @@
<?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="com.imyeyu.server.modules.common.mapper.MultilingualMapper">
<select id="selectByKeyList" resultType="com.imyeyu.server.modules.common.entity.Multilingual">
SELECT * FROM multilingual WHERE key IN
<foreach collection='keys' item='item' open='(' separator=',' close=')'>
#{item}
</foreach>
AND deleted_at IS NULL
</select>
</mapper>
@@ -0,0 +1,16 @@
<?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="com.imyeyu.server.modules.common.mapper.SettingMapper">
<sql id="table">setting</sql>
<select id="listByKeys">
SELECT
*
FROM
<include refid="table" />
WHERE
key IN
<foreach collection="keys" item="key" open="(" separator="," close=")">
#{key}
</foreach>
</select>
</mapper>
@@ -0,0 +1,55 @@
<?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="com.imyeyu.server.modules.common.mapper.TaskMapper">
<!-- 所有公开任务 -->
<select id="listAll4Public" resultMap="findAll4PublicResult">
SELECT
id,
name,
digest,
status,
td.*
FROM
task
LEFT JOIN (
SELECT
*
FROM (
-- 任务详情
SELECT
id AS detial_id,
task_id,
bizType,
status AS tdStatus,
digest AS tdDigest,
created_at,
ROW_NUMBER() OVER (PARTITION BY task_id ORDER BY created_at DESC) AS seq
FROM
task_detail
WHERE
deleted_at IS NULL
) AS cr
WHERE
seq &lt; 7
) AS td
ON
td.task_id = task.id
WHERE
is_public = 1
AND deleted_at IS NULL
</select>
<resultMap id="findAll4PublicResult" type="com.imyeyu.server.modules.common.entity.Task">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="digest" column="digest"/>
<result property="status" column="status"/>
<!-- 关联任务 -->
<collection property="details" ofType="com.imyeyu.server.modules.common.entity.TaskDetail">
<id property="id" column="detial_id"/>
<result property="bizType" column="bizType"/>
<result property="status" column="tdStatus"/>
<result property="digest" column="tdDigest"/>
<result property="createdAt" column="created_at"/>
</collection>
</resultMap>
</mapper>
@@ -0,0 +1,5 @@
<?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="com.imyeyu.server.modules.common.mapper.UserConfigMapper">
<sql id="table">user_config</sql>
</mapper>
@@ -0,0 +1,4 @@
<?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="com.imyeyu.server.modules.common.mapper.UserPrivacyMapper">
</mapper>
@@ -0,0 +1,5 @@
<?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="com.imyeyu.server.modules.common.mapper.UserProfileMapper">
<sql id="table">user_profile</sql>
</mapper>
@@ -0,0 +1,40 @@
<?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="com.imyeyu.server.modules.git.mapper.IssueMapper">
<sql id="table">git_issue</sql>
<sql id="pageCondition">
repository_id = #{issuePage.repositoryId}
<if test="issuePage.type != null">
AND type = #{issuePage.type}
</if>
<if test="issuePage.status != null">
AND status = #{issuePage.status}
</if>
<if test="issuePage.keyword != null and issuePage.keyword != ''">
AND (
title LIKE CONCAT('%', #{issuePage.keyword}, '%')
OR description LIKE CONCAT('%', #{issuePage.keyword}, '%')
)
</if>
AND deleted_at IS NULL
</sql>
<select id="countByIssuePage" resultType="long">
SELECT COUNT(1) FROM <include refid="table" /> WHERE <include refid="pageCondition" />
</select>
<select id="listByIssuePage" resultType="com.imyeyu.server.modules.git.entity.Issue">
SELECT
id,
title,
type,
status,
created_at
FROM
<include refid="table" />
WHERE
<include refid="pageCondition" />
ORDER BY
COALESCE(updated_at, created_at) DESC
LIMIT
#{offset}, #{limit}
</select>
</mapper>
@@ -0,0 +1,40 @@
<?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="com.imyeyu.server.modules.git.mapper.MergeMapper">
<sql id="table">git_merge</sql>
<sql id="pageCondition">
repository_id = #{mergePage.repositoryId}
<if test="mergePage.type != null">
AND type = #{mergePage.type}
</if>
<if test="mergePage.status != null">
AND status = #{mergePage.status}
</if>
<if test="mergePage.keyword != null and mergePage.keyword != ''">
AND (
title LIKE CONCAT('%', #{mergePage.keyword}, '%')
OR description LIKE CONCAT('%', #{mergePage.keyword}, '%')
)
</if>
AND deleted_at IS NULL
</sql>
<select id="countByMergePage" resultType="long">
SELECT COUNT(1) FROM <include refid="table" /> WHERE <include refid="pageCondition" />
</select>
<select id="listByMergePage" resultType="com.imyeyu.server.modules.git.entity.Merge">
SELECT
id,
title,
type,
status,
created_at
FROM
<include refid="table" />
WHERE
<include refid="pageCondition" />
ORDER BY
COALESCE(updated_at, created_at) DESC
LIMIT
#{offset}, #{limit}
</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="com.imyeyu.server.modules.git.mapper.ReleaseMapper">
<sql id="table">git_release</sql>
<select id="listByRepositoryId" resultMap="listByRepositoryIdResult">
SELECT
release.*,
attachment.id AS attachmentId,
attachment.biz_type,
attachment.biz_id,
attachment.lid_title,
attachment.name,
attachment.size
FROM
<include refid="table" /> AS release
LEFT JOIN
attachment
ON
attachment.biz_type = '${@com.imyeyu.timiserver.modules.common.entity.Attachment$BizType@GIT}'
AND attachment.biz_id = release.id
AND attachment.attach_type = '${@com.imyeyu.timiserver.modules.git.bean.AttachType@RELEASE}'
AND attachment.deleted_at IS NULL
WHERE
release.repository_id = #{repositoryId}
AND release.deleted_at IS NULL
ORDER BY
COALESCE(release.updated_at, release.created_at) DESC
LIMIT
#{offset}, #{limit}
</select>
<resultMap id="listByRepositoryIdResult" type="com.imyeyu.server.modules.git.vo.release.ReleaseView" autoMapping="true">
<id property="id" column="id" />
<!-- 关联附件 -->
<collection property="attachmentList" ofType="com.imyeyu.server.modules.common.vo.attachment.AttachmentView">
<id property="id" column="attachmentId" />
<result property="bizType" column="biz_type" />
<result property="bizId" column="biz_id" />
<result property="lidTitle" column="lid_title" />
<result property="name" column="name" />
<result property="size" column="size" />
</collection>
</resultMap>
</mapper>
@@ -0,0 +1,52 @@
<?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="com.imyeyu.server.modules.gitea.mapper.ActionMapper">
<select id="count" resultType="long">
SELECT
COUNT(*)
FROM
action
WHERE
1 = 1
<if test="repoId != null">
AND action.repo_id = #{repoId}
</if>
<if test="branch != null">
AND action.ref_name LIKE CONCAT('%', #{branch})
</if>
<if test="operation != null">
AND action.op_type = #{operation.value}
</if>
</select>
<select id="list" resultType="com.imyeyu.server.modules.gitea.bean.ActionLogDTO">
SELECT
repository.id AS repo_id,
repository.name AS repo_name,
operator.id AS operator_id,
action.ref_name,
action.content,
action.created_unix * 1000 AS operatedAt
FROM
action
INNER JOIN
repository ON action.repo_id = repository.id
INNER JOIN
user AS operator ON action.act_user_id = operator.id
WHERE
1 = 1
<if test="repoId != null">
AND action.repo_id = #{repoId}
</if>
<if test="branch != null">
AND action.ref_name LIKE CONCAT('%', #{branch})
</if>
<if test="operation != null">
AND action.op_type = #{operation.value}
</if>
ORDER BY
action.created_unix DESC,
action.id DESC
LIMIT
#{offset}, #{limit}
</select>
</mapper>
@@ -0,0 +1,33 @@
<?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="com.imyeyu.server.modules.minecraft.mapper.PackMapper">
<!-- 获取 -->
<select id="listPacks" resultMap="listPacksResult">
SELECT
pack.*,
source.name AS sourceName,
source.type AS sourceType,
source.data AS sourceData,
source.is_default
FROM
minecraft_pack AS pack
LEFT JOIN
minecraft_pack_source AS source
ON
source.pack_id = pack.id
WHERE
pack.deleted_at IS NULL
AND source.deleted_at IS NULL
ORDER BY
pack.is_deprecated, pack.created_at DESC, source.order ASC
</select>
<resultMap id="listPacksResult" type="com.imyeyu.server.modules.minecraft.entity.MinecraftPack" autoMapping="true">
<id property="id" column="id" />
<collection property="sourceList" ofType="com.imyeyu.server.modules.minecraft.entity.MinecraftPackSource" autoMapping="false">
<result property="name" column="sourceName" />
<result property="type" column="sourceType" />
<result property="data" column="sourceData" />
<result property="isDefault" column="is_default" />
</collection>
</resultMap>
</mapper>
@@ -0,0 +1,4 @@
<?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="com.imyeyu.server.modules.minecraft.mapper.PlayerMapper">
</mapper>
@@ -0,0 +1,56 @@
<?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="com.imyeyu.server.modules.system.mapper.AsyncTaskMapper">
<sql id="table">async_task</sql>
<insert id="insert">
INSERT INTO <include refid="table" /> (
uuid,
name,
type,
message,
status,
progress,
can_pause,
can_interrupt,
is_periodical,
cron,
start_at,
interrupt_at,
error_at,
died_at,
created_at
) VALUES (
#{uuid},
#{name},
#{type},
#{message},
#{status},
#{progress},
#{canPause},
#{canInterrupt},
#{isPeriodical},
#{cron},
#{startAt},
#{interruptAt},
#{errorAt},
#{diedAt},
#{createdAt}
)
</insert>
<update id="update" parameterType="com.imyeyu.server.modules.system.entity.AsyncTask">
UPDATE
<include refid="table" />
SET
name = #{name},
type = #{type},
message = #{message},
status = #{status},
progress = #{progress},
start_at = #{startAt},
interrupt_at = #{interruptAt},
error_at = #{errorAt},
died_at = #{diedAt}
WHERE
uuid = #{uuid}
</update>
</mapper>
@@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<title>Title</title>
<style>
<#include "StyleSheet.ftl" />
</style>
<style>
.btn {
color: #FFF !important;
width: 7rem;
margin: 32px auto 48px auto;
border: none;
display: block;
padding: 8px 24px;
font-size: 15px;
text-align: center;
background: #53BD93;
text-decoration: none !important;
}
.btn:hover {
background: #5AC79B;
}
.tips {
margin: 12px 0 6px 0;
}
</style>
</head>
<body>
<div class="root">
<div class="mail">
<#if user.data.hasWrapper>
<img
class="wrapper ir-${user.data.wrapperType?lower_case}"
src="https://res.imyeyu.net/user/wrapper/${user.id}.png"
/>
<#else>
<img class="wrapper ir-pixelated" src="https://res.imyeyu.net/user/wrapper/default.png" />
</#if>
<h4 class="title">
<span class="pink bold">${user.name} </span>
<span>您好,您正在验证</span>
<span class="pink bold"> 夜雨博客 </span>
<span>的邮箱绑定,请在 10 分钟内点击下面的按钮完成校验,让我确定这是你的电子邮箱,不要泄露此邮件内容。</span>
</h4>
<a class="btn" href="${url}" multilingualField="_blank">继续完成验证</a>
<aside class="tips center gray">如果这不是你本人操作,请无视此邮件</aside>
<#include "Footer.ftl" />
</div>
<div class="line1"></div>
<div class="line2"></div>
<div class="line3"></div>
</div>
</body>
</html>
+11
View File
@@ -0,0 +1,11 @@
<footer class="footer font12 center">
<p>这是由系统自动发送的邮件,请不要回复</p>
<p>
<span>如果这封邮件打扰到您,请直接屏蔽本邮箱或登录</span>
<a href="https://www.imyeyu.net">夜雨博客</a>
<span>个人空间中的设置随时关闭</span>
</p>
<p>&nbsp;</p>
<p>朝朝频顾惜,夜夜不相忘</p>
<p>Copyright &copy; 2017 - ${.now?string["yyyy"]} 夜雨 All Rights Reserved 版权所有</p>
</footer>
@@ -0,0 +1,92 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<title>Title</title>
<style>
<#include "StyleSheet.ftl" />
</style>
<style>
.comment {
width: 80%;
display: flex;
margin: 16px auto 4px auto;
font-size: 14px;
align-items: center;
justify-content: space-between;
}
.comment .content {
display: flex;
align-items: center;
}
.comment .content .avatar {
width: 22px;
height: 22px;
border: 1px solid #777;
margin-right: 4px;
}
.comment .content h4 {
margin: 0;
}
.comment .content .data {
width: 15rem;
}
.sign-in-tips {
margin-top: 20px;
}
</style>
</head>
<body>
<div class="root">
<div class="mail">
<#if user.data.hasWrapper>
<img
class="wrapper ir-${user.data.wrapperType?lower_case}"
src="https://res.imyeyu.net/user/wrapper/${user.id}.png"
/>
<#else>
<img class="wrapper ir-pixelated" src="https://res.imyeyu.net/user/wrapper/default.png" />
</#if>
<h4 class="title">
<span class="pink bold">${user.name} </span>
<span>您好,您在</span>
<span class="pink bold"> 夜雨博客 </span>
<span>的评论收到以下回复</span>
<span class="gray">(24 小时内)</span>
</h4>
<#list reminds as remind>
<section class="comment">
<div class="content">
<#if remind.reply.sender??>
<#if remind.reply.sender.data.avatarType>
<img
class="avatar ir-${remind.reply.sender.data.avatarType?lower_case}"
src="https://res.imyeyu.net/user/avatar/${remind.reply.sender.id}.png"
/>
<#else>
<img class="avatar ir-pixelated" src="https://res.imyeyu.net/user/avatar/default.png" />
</#if>
<h4>${remind.reply.sender.name} 说:</h4>
<#else>
<img class="avatar ir-pixelated" src="https://res.imyeyu.net/user/avatar/default.png" />
<h4>${remind.reply.senderNick} 说:</h4>
</#if>
<p class="data clip-text">${remind.reply.data}</p>
</div>
<span class="gray time font12">${remind.reply.createdAt?number_to_datetime?string("yyyy-MM-dd HH:mm:ss")}</span>
</section>
</#list>
<p class="sign-in-tips gray font12 center">本邮件仅作摘要提醒,登录博客查看详细信息</p>
<#include "Footer.ftl" />
</div>
<div class="line1"></div>
<div class="line2"></div>
<div class="line3"></div>
</div>
</body>
</html>
@@ -0,0 +1,63 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<title>Title</title>
<style>
<#include "StyleSheet.ftl" />
</style>
<style>
.btn {
color: #FFF !important;
width: 7rem;
margin: 32px auto 48px auto;
border: none;
display: block;
padding: 8px 24px;
font-size: 15px;
text-align: center;
background: #53BD93;
text-decoration: none !important;
}
.btn:hover {
background: #5AC79B;
}
.tips {
margin: 12px 0 6px 0;
}
</style>
</head>
<body>
<div class="root">
<div class="mail">
<#if user.data.hasWrapper>
<img
class="wrapper ir-${user.data.wrapperType?lower_case}"
src="https://res.imyeyu.net/user/wrapper/${user.id}.png"
alt="user wrapper"
/>
<#else>
<img
class="wrapper ir-pixelated"
src="https://res.imyeyu.net/user/wrapper/default.png"
alt="user wrapper"
/>
</#if>
<h4 class="title">
<span class="pink bold">${user.name} </span>
<span>您好,</span>
<span class="pink bold">夜雨博客 </span>
<span>收到了您的重置密码请求,请在 10 分钟内点击下面的按钮继续完成,不要泄露此邮件内容。</span>
</h4>
<a class="btn" href="${url}" multilingualField="_blank">重置密码</a>
<aside class="tips center gray">如果这不是你本人操作,请无视此邮件</aside>
<#include "Footer.ftl" />
</div>
<div class="line1"></div>
<div class="line2"></div>
<div class="line3"></div>
</div>
</body>
</html>
+163
View File
@@ -0,0 +1,163 @@
/* 基本样式 */
.font12 {
font-size: 12px;
}
.gray {
color: #999;
}
.pink {
color: #FF7A9B;
}
.bold {
font-weight: bold;
}
.center {
text-align: center;
}
a {
cursor: pointer !important;
}
p {
margin: 0;
}
.clip-text {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.ir-pixelated {
image-rendering: pixelated;
}
.ir-auto {
image-rendering: auto;
}
.ir-smooth {
image-rendering: smooth;
}
/* 布局样式 */
.root {
width: 42rem;
margin: 24px auto;
position: relative;
}
.mail {
margin: 0 3rem;
box-shadow: 0 0 8px rgba(0, 0, 0, .5);
background: #F4F4F4;
}
.wrapper {
width: 100%;
display: block;
border-bottom: 1px solid #CDDEF0;
}
.title {
margin: 4px 12px;
}
.footer {
color: #555;
padding: 12px 0;
margin-top: 32px;
}
.line1 {
height: 3px;
z-index: -1;
position: relative;
margin-top: -50px;
background: #FF7A9B;
}
.line1::before {
content: "";
left: 0;
width: 50%;
height: 3px;
bottom: 0;
position: absolute;
background: #FF7A9B;
transform: rotate(-30deg);
transform-origin: 0 0;
}
.line1::after {
content: "";
right: 0;
width: 50%;
height: 3px;
bottom: 0;
position: absolute;
background: #FF7A9B;
transform: rotate(30deg);
transform-origin: 100% 0;
}
.line2,
.line3 {
width: 3px;
height: 200px;
position: absolute;
background: linear-gradient(to bottom, rgba(255,122,155,1) 0%, rgba(255,255,255,0) 100%);;
}
.line2::before,
.line3::before {
content: "";
width: 200px;
height: 40px;
position: absolute;
background: #FFF;
}
.line2::before {
top: 33px;
left: 12px;
transform: rotate(16deg);
}
.line3::before {
top: 32px;
right: 12px;
transform: rotate(-16deg);
}
.line2::after,
.line3::after {
content: "";
top: -1px;
width: 21.8rem;
height: 3px;
position: absolute;
background: #FF7A9B;
}
.line2::after {
left: 2px;
transform: rotate(16deg);
transform-origin: 0 0;
}
.line3::after {
right: 2px;
transform: rotate(-16deg);
transform-origin: 100% 0;
}
.line3 {
right: 0;
}