Просмотр исходного кода

chore: auto bump version and changelog [skip ci]

iwt 1 день назад
Родитель
Сommit
87900e7073

+ 51 - 0
cfc-backend/src/main/java/com/etotem/cfc/controller/HomeController.java

@@ -0,0 +1,51 @@
+package com.etotem.cfc.controller;
+
+import com.etotem.cfc.common.Result;
+import com.etotem.cfc.service.HomeShortcutService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Tag(name = "首页快捷方式", description = "应用库、快捷配置、使用频度")
+@RestController
+@RequestMapping("/api/home")
+public class HomeController {
+
+    @Resource
+    private HomeShortcutService homeShortcutService;
+
+    @Operation(summary = "获取应用库配置 + 用户快捷 + 频度")
+    @PostMapping("/app-library")
+    public Result<?> getAppLibrary(@RequestAttribute("userId") Long userId) {
+        return homeShortcutService.getAppLibrary(userId);
+    }
+
+    @Operation(summary = "保存快捷方式配置")
+    @PostMapping("/shortcut/save")
+    public Result<Void> saveShortcut(@RequestBody Map<String, Object> body,
+                                     @RequestAttribute("userId") Long userId) {
+        @SuppressWarnings("unchecked")
+        List<Map<String, Object>> items = (List<Map<String, Object>>) body.get("items");
+        if (items == null) items = java.util.Collections.emptyList();
+        return homeShortcutService.saveShortcutConfig(userId, items);
+    }
+
+    @Operation(summary = "记录应用进入次数")
+    @PostMapping("/app/enter")
+    public Result<Void> reportEnter(@RequestBody Map<String, String> body,
+                                    @RequestAttribute("userId") Long userId) {
+        String appKey = body.get("appKey");
+        return homeShortcutService.reportEnter(userId, appKey);
+    }
+
+    @Operation(summary = "重置为默认配置(清除所有锁定)")
+    @PostMapping("/shortcut/reset")
+    public Result<Void> resetShortcut(@RequestAttribute("userId") Long userId) {
+        return homeShortcutService.resetToDefault(userId);
+    }
+}

+ 5 - 0
cfc-backend/src/main/java/com/etotem/cfc/mapper/UserAppUsageMapper.java

@@ -2,6 +2,11 @@ package com.etotem.cfc.mapper;
 
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.etotem.cfc.entity.UserAppUsage;
 import com.etotem.cfc.entity.UserAppUsage;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
 
 
 public interface UserAppUsageMapper extends BaseMapper<UserAppUsage> {
 public interface UserAppUsageMapper extends BaseMapper<UserAppUsage> {
+
+    @Select("SELECT * FROM user_app_usage WHERE user_id = #{userId} AND app_key = #{appKey} LIMIT 1")
+    UserAppUsage selectByUserIdAndAppKey(@Param("userId") Long userId, @Param("appKey") String appKey);
 }
 }

+ 6 - 0
cfc-backend/src/main/java/com/etotem/cfc/mapper/UserShortcutConfigMapper.java

@@ -2,6 +2,12 @@ package com.etotem.cfc.mapper;
 
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.etotem.cfc.entity.UserShortcutConfig;
 import com.etotem.cfc.entity.UserShortcutConfig;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import java.util.List;
 
 
 public interface UserShortcutConfigMapper extends BaseMapper<UserShortcutConfig> {
 public interface UserShortcutConfigMapper extends BaseMapper<UserShortcutConfig> {
+
+    @Select("SELECT * FROM user_shortcut_config WHERE user_id = #{userId} ORDER BY locked DESC, sort_order ASC")
+    List<UserShortcutConfig> selectByUserId(@Param("userId") Long userId);
 }
 }

+ 98 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/HomeShortcutService.java

@@ -0,0 +1,98 @@
+package com.etotem.cfc.service;
+
+import com.etotem.cfc.common.Result;
+import com.etotem.cfc.entity.UserShortcutConfig;
+import com.etotem.cfc.entity.UserAppUsage;
+import com.etotem.cfc.mapper.UserShortcutConfigMapper;
+import com.etotem.cfc.mapper.UserAppUsageMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class HomeShortcutService {
+
+    @Resource
+    private UserShortcutConfigMapper userShortcutConfigMapper;
+
+    @Resource
+    private UserAppUsageMapper userAppUsageMapper;
+
+    /**
+     * 返回用户快捷配置 + 频度映射。
+     * 应用库本身是前端常量,后端只需返回用户侧数据。
+     */
+    public Result<Map<String, Object>> getAppLibrary(Long userId) {
+        List<UserShortcutConfig> configs = userShortcutConfigMapper.selectByUserId(userId);
+
+        List<Map<String, Object>> myShortcuts = configs.stream().map(c -> {
+            Map<String, Object> m = new HashMap<>();
+            m.put("appKey", c.getAppKey());
+            m.put("locked", c.getLocked());
+            m.put("sortOrder", c.getSortOrder());
+            return m;
+        }).collect(Collectors.toList());
+
+        List<UserAppUsage> usages = userAppUsageMapper.selectList(null);
+        Map<String, Integer> usageMap = new HashMap<>();
+        for (UserAppUsage u : usages) {
+            usageMap.put(u.getAppKey(), u.getEnterCount());
+        }
+
+        Map<String, Object> resp = new HashMap<>();
+        resp.put("myShortcuts", myShortcuts);
+        resp.put("usage", usageMap);
+        return Result.success(resp);
+    }
+
+    @Transactional
+    public Result<Void> saveShortcutConfig(Long userId, List<Map<String, Object>> items) {
+        userShortcutConfigMapper.delete(
+                new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<UserShortcutConfig>()
+                        .eq("user_id", userId));
+        for (Map<String, Object> item : items) {
+            String appKey = (String) item.get("appKey");
+            if (appKey == null || appKey.isEmpty()) continue;
+            UserShortcutConfig c = new UserShortcutConfig();
+            c.setUserId(userId);
+            c.setAppKey(appKey);
+            c.setLocked(item.get("locked") != null ? ((Number) item.get("locked")).intValue() : 0);
+            c.setSortOrder(item.get("sortOrder") != null ? ((Number) item.get("sortOrder")).intValue() : 0);
+            userShortcutConfigMapper.insert(c);
+        }
+        return Result.success(null);
+    }
+
+    public Result<Void> reportEnter(Long userId, String appKey) {
+        if (userId == null || appKey == null || appKey.isEmpty()) {
+            return Result.error("参数缺失");
+        }
+        UserAppUsage u = userAppUsageMapper.selectByUserIdAndAppKey(userId, appKey);
+        if (u == null) {
+            u = new UserAppUsage();
+            u.setUserId(userId);
+            u.setAppKey(appKey);
+            u.setEnterCount(1);
+            u.setLastEnterAt(new Date());
+            userAppUsageMapper.insert(u);
+        } else {
+            u.setEnterCount(u.getEnterCount() + 1);
+            u.setLastEnterAt(new Date());
+            userAppUsageMapper.updateById(u);
+        }
+        return Result.success(null);
+    }
+
+    @Transactional
+    public Result<Void> resetToDefault(Long userId) {
+        userShortcutConfigMapper.delete(
+                new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<UserShortcutConfig>()
+                        .eq("user_id", userId));
+        return Result.success(null);
+    }
+}

+ 1 - 1
cfc-web/.last_build_commit

@@ -1 +1 @@
-003487ac9962fe48573f856ba1d2cbd7ae7ef52a
+adbd24c86f05ad5d4e60fcecbc08f9633fd3c87b

+ 2 - 2
cfc-web/package-lock.json

@@ -1,12 +1,12 @@
 {
 {
   "name": "cfc-web",
   "name": "cfc-web",
-  "version": "1.0.1454",
+  "version": "1.0.1455",
   "lockfileVersion": 3,
   "lockfileVersion": 3,
   "requires": true,
   "requires": true,
   "packages": {
   "packages": {
     "": {
     "": {
       "name": "cfc-web",
       "name": "cfc-web",
-      "version": "1.0.1454",
+      "version": "1.0.1455",
       "dependencies": {
       "dependencies": {
         "@wangeditor/editor": "^5.1.23",
         "@wangeditor/editor": "^5.1.23",
         "@wangeditor/editor-for-vue": "^1.0.2",
         "@wangeditor/editor-for-vue": "^1.0.2",