feat(core): 实现用户积分计算逻辑

- 新增积分规则处理模块
- 集成积分计算到相关业务流程中

fix(file): 修复上传工具中路径乱码和非法字符问题

- 使用 UTF-8 编码统一路径解析
- 增加路径合法性校验

fix(user): 修正用户 Passkey 生成与验证流程

- 修复部分场景下 Passkey 未生成的问题
- 调整 Passkey 校验逻辑,确保唯一性和安全性

Change-Id: Id5eacb20f354a07de01413474095c2b2b9b49231
diff --git a/ruoyi-admin/src/main/resources/mapper/system/SysUserPasskeyMapper.xml b/ruoyi-admin/src/main/resources/mapper/system/SysUserPasskeyMapper.xml
new file mode 100644
index 0000000..949ac4f
--- /dev/null
+++ b/ruoyi-admin/src/main/resources/mapper/system/SysUserPasskeyMapper.xml
@@ -0,0 +1,62 @@
+<?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.ruoyi.authentication.mapper.SysUserPasskeyMapper">
+    
+    <resultMap type="SysUserPasskey" id="SysUserPasskeyResult">
+        <result property="userId"    column="user_id"    />
+        <result property="passkey"    column="passkey"    />
+        <result property="createdAt"    column="created_at"    />
+    </resultMap>
+
+    <sql id="selectSysUserPasskeyVo">
+        select user_id, passkey, created_at from sys_user_passkey
+    </sql>
+
+    <select id="selectSysUserPasskeyList" parameterType="SysUserPasskey" resultMap="SysUserPasskeyResult">
+        <include refid="selectSysUserPasskeyVo"/>
+        <where>  
+            <if test="passkey != null  and passkey != ''"> and passkey = #{passkey}</if>
+        </where>
+    </select>
+    
+    <select id="selectSysUserPasskeyByUserId" parameterType="Long" resultMap="SysUserPasskeyResult">
+        <include refid="selectSysUserPasskeyVo"/>
+        where user_id = #{userId}
+    </select>
+
+    <insert id="insertSysUserPasskey" parameterType="SysUserPasskey">
+        insert into sys_user_passkey
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="userId != null">user_id,</if>
+            <if test="passkey != null and passkey != ''">passkey,</if>
+            <if test="createdAt != null">created_at,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="userId != null">#{userId},</if>
+            <if test="passkey != null and passkey != ''">#{passkey},</if>
+            <if test="createdAt != null">#{createdAt},</if>
+         </trim>
+    </insert>
+
+    <update id="updateSysUserPasskey" parameterType="SysUserPasskey">
+        update sys_user_passkey
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="passkey != null and passkey != ''">passkey = #{passkey},</if>
+            <if test="createdAt != null">created_at = #{createdAt},</if>
+        </trim>
+        where user_id = #{userId}
+    </update>
+
+    <delete id="deleteSysUserPasskeyByUserId" parameterType="Long">
+        delete from sys_user_passkey where user_id = #{userId}
+    </delete>
+
+    <delete id="deleteSysUserPasskeyByUserIds" parameterType="String">
+        delete from sys_user_passkey where user_id in 
+        <foreach item="userId" collection="array" open="(" separator="," close=")">
+            #{userId}
+        </foreach>
+    </delete>
+</mapper>
\ No newline at end of file
diff --git a/ruoyi-admin/src/main/resources/mapper/system/UserScoreMapper.xml b/ruoyi-admin/src/main/resources/mapper/system/UserScoreMapper.xml
new file mode 100644
index 0000000..2f0f7fc
--- /dev/null
+++ b/ruoyi-admin/src/main/resources/mapper/system/UserScoreMapper.xml
@@ -0,0 +1,78 @@
+<?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.ruoyi.authentication.mapper.UserScoreMapper">
+    
+    <resultMap type="UserScore" id="UserScoreResult">
+        <result property="userId"    column="user_id"    />
+        <result property="uploaded"    column="uploaded"    />
+        <result property="downloaded"    column="downloaded"    />
+        <result property="bonus"    column="bonus"    />
+        <result property="score"    column="score"    />
+        <result property="updatedAt"    column="updated_at"    />
+    </resultMap>
+
+    <sql id="selectUserScoreVo">
+        select user_id, uploaded, downloaded, bonus, score, updated_at from user_score
+    </sql>
+
+    <select id="selectUserScoreList" parameterType="UserScore" resultMap="UserScoreResult">
+        <include refid="selectUserScoreVo"/>
+        <where>  
+            <if test="uploaded != null  and uploaded != ''"> and uploaded = #{uploaded}</if>
+            <if test="downloaded != null  and downloaded != ''"> and downloaded = #{downloaded}</if>
+            <if test="bonus != null "> and bonus = #{bonus}</if>
+            <if test="score != null "> and score = #{score}</if>
+            <if test="updatedAt != null "> and updated_at = #{updatedAt}</if>
+        </where>
+    </select>
+    
+    <select id="selectUserScoreByUserId" parameterType="Long" resultMap="UserScoreResult">
+        <include refid="selectUserScoreVo"/>
+        where user_id = #{userId}
+    </select>
+
+    <insert id="insertUserScore" parameterType="UserScore">
+        insert into user_score
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="userId != null">user_id,</if>
+            <if test="uploaded != null">uploaded,</if>
+            <if test="downloaded != null">downloaded,</if>
+            <if test="bonus != null">bonus,</if>
+
+            <if test="updatedAt != null">updated_at,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="userId != null">#{userId},</if>
+            <if test="uploaded != null">#{uploaded},</if>
+            <if test="downloaded != null">#{downloaded},</if>
+            <if test="bonus != null">#{bonus},</if>
+
+            <if test="updatedAt != null">#{updatedAt},</if>
+         </trim>
+    </insert>
+
+    <update id="updateUserScore" parameterType="UserScore">
+        update user_score
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="uploaded != null">uploaded = #{uploaded},</if>
+            <if test="downloaded != null">downloaded = #{downloaded},</if>
+            <if test="bonus != null">bonus = #{bonus},</if>
+
+            <if test="updatedAt != null">updated_at = #{updatedAt},</if>
+        </trim>
+        where user_id = #{userId}
+    </update>
+
+    <delete id="deleteUserScoreByUserId" parameterType="Long">
+        delete from user_score where user_id = #{userId}
+    </delete>
+
+    <delete id="deleteUserScoreByUserIds" parameterType="String">
+        delete from user_score where user_id in 
+        <foreach item="userId" collection="array" open="(" separator="," close=")">
+            #{userId}
+        </foreach>
+    </delete>
+</mapper>
\ No newline at end of file