Преглед изворни кода

聊天日志,切片,智谱标准接口,提示词。

S0025136190 пре 11 месеци
родитељ
комит
65b78541a6
23 измењених фајлова са 1185 додато и 61 уклоњено
  1. 141 5
      takai-admin/src/main/java/com/takai/web/controller/bigmodel/BigModelController.java
  2. 44 9
      takai-admin/src/main/java/com/takai/web/controller/system/SysLoginController.java
  3. 13 2
      takai-admin/src/main/resources/application.yml
  4. 16 0
      takai-bigmodel/src/main/java/com/takai/bigmodel/domain/dto/AsyncCompletions.java
  5. 24 0
      takai-bigmodel/src/main/java/com/takai/bigmodel/domain/dto/AsyncResult.java
  6. 9 1
      takai-bigmodel/src/main/java/com/takai/bigmodel/domain/dto/DialogReqDTO.java
  7. 15 0
      takai-bigmodel/src/main/java/com/takai/bigmodel/domain/dto/DialogRespDTO.java
  8. 78 0
      takai-bigmodel/src/main/java/com/takai/bigmodel/domain/entity/AssistantParams.java
  9. 158 0
      takai-bigmodel/src/main/java/com/takai/bigmodel/domain/entity/CompletionsParams.java
  10. 24 0
      takai-bigmodel/src/main/java/com/takai/bigmodel/domain/entity/SearchObject.java
  11. 24 0
      takai-bigmodel/src/main/java/com/takai/bigmodel/domain/entity/ToolsObject.java
  12. 9 2
      takai-bigmodel/src/main/java/com/takai/bigmodel/mapper/DialogMapper.java
  13. 22 2
      takai-bigmodel/src/main/java/com/takai/bigmodel/service/IBigModelService.java
  14. 368 16
      takai-bigmodel/src/main/java/com/takai/bigmodel/service/impl/BigModelServiceImpl.java
  15. 77 15
      takai-bigmodel/src/main/resources/mapper/bm/DialogMapper.xml
  16. 65 0
      takai-common/src/main/java/com/takai/common/config/BigModelConfig.java
  17. 5 0
      takai-common/src/main/java/com/takai/common/constant/Constants.java
  18. 5 0
      takai-common/src/main/java/com/takai/common/core/domain/AjaxResult.java
  19. 5 7
      takai-common/src/main/java/com/takai/common/core/domain/model/LoginBody.java
  20. 3 1
      takai-framework/src/main/java/com/takai/framework/config/SecurityConfig.java
  21. 6 0
      takai-framework/src/main/java/com/takai/framework/security/handle/LogoutSuccessHandlerImpl.java
  22. 73 0
      takai-framework/src/main/java/com/takai/framework/web/service/SysLoginService.java
  23. 1 1
      takai-framework/src/main/java/com/takai/framework/web/service/SysRegisterService.java

+ 141 - 5
takai-admin/src/main/java/com/takai/web/controller/bigmodel/BigModelController.java

@@ -1,25 +1,33 @@
 package com.takai.web.controller.bigmodel;
 
+import com.takai.bigmodel.domain.dto.AsyncCompletions;
+import com.takai.bigmodel.domain.dto.AsyncResult;
 import com.takai.bigmodel.domain.dto.DialogReqDTO;
 import com.takai.bigmodel.domain.dto.DialogRespDTO;
+import com.takai.bigmodel.domain.entity.AssistantParams;
 import com.takai.bigmodel.domain.entity.BmApplication;
+import com.takai.bigmodel.domain.entity.CompletionsParams;
 import com.takai.bigmodel.domain.entity.SseParams;
 import com.takai.bigmodel.service.IBigModelService;
+import com.takai.common.annotation.Log;
 import com.takai.common.config.BigModelConfig;
 import com.takai.common.core.controller.BaseController;
 import com.takai.common.core.domain.AjaxResult;
-import com.takai.common.core.domain.entity.SysDept;
+import com.takai.common.enums.BusinessType;
+import com.takai.common.utils.poi.ExcelUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.MediaType;
-import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 智谱接口
@@ -59,6 +67,11 @@ public class BigModelController extends BaseController {
         return success(apps);
     }
 
+    /**
+     * 报错聊天记录
+     * @param dialogReqDTO
+     * @return
+     */
     @PostMapping("/dialog/save")
     public AjaxResult saveDialog(@RequestBody DialogReqDTO dialogReqDTO)
     {
@@ -66,11 +79,134 @@ public class BigModelController extends BaseController {
         return success();
     }
 
-    @GetMapping("/dialog/list")
-    public AjaxResult dialogList()
+    /**
+     * 聊天集合
+     * @return
+     */
+    @GetMapping("/dialog/list/{appId}")
+    public AjaxResult dialogList(@PathVariable String appId)
     {
-        List<DialogRespDTO> dialogs = bigModelService.getDialogList();
+        List<Object> dialogs = bigModelService.getDialogList(appId);
         return success(dialogs);
     }
 
+    /**
+     * 聊天详情
+     * @param dialogId
+     * @return
+     */
+    @GetMapping("/dialog/detail/{dialogId}")
+    public AjaxResult dialogDetail(@PathVariable String dialogId)
+    {
+        DialogRespDTO detail = bigModelService.getDialogDetail(dialogId);
+        return success(detail);
+    }
+
+    /**
+     * 删除聊天记录
+     * @param id
+     * @return
+     */
+    @DeleteMapping("/dialog/del/{id}")
+    public AjaxResult delDialog(@PathVariable String id)
+    {
+        bigModelService.DelDialogDetail(id);
+        return success();
+    }
+
+    /**
+     * 聊天标题重命名
+     * @param dialogReqDTO
+     * @return
+     */
+    @PutMapping("/dialog/update")
+    public AjaxResult updateDialog(@RequestBody DialogReqDTO dialogReqDTO)
+    {
+        bigModelService.updateDialog(dialogReqDTO);
+        return success();
+    }
+
+    /**
+     * 聊天消息导出
+     * @param response
+     * @param id
+     *
+     */
+    @Log(title = "聊天详情", businessType = BusinessType.EXPORT)
+//    @PreAuthorize("@ss.hasPermi('bigmodel:api:export')")
+    @PostMapping("/dialog/export/{id}")
+    public void export(HttpServletResponse response, @PathVariable String id) {
+        List<DialogRespDTO> dialogs = bigModelService.exportExcel(id);
+        ExcelUtil<DialogRespDTO> util = new ExcelUtil(DialogRespDTO.class);
+        util.exportExcel(response, dialogs, "聊天记录");
+    }
+
+    /**
+     * 聊天标准接口
+     * @param params
+     * @return
+     */
+    @PostMapping("/completions")
+    public SseEmitter getCompletions(@RequestBody CompletionsParams params){
+        return bigModelService.getCompletions(params);
+    }
+
+    /**
+     * 切片信息接口
+     * @param requestId
+     * @return
+     */
+    @GetMapping("/slice_info/{requestId}")
+    public AjaxResult sliceInfo(@PathVariable String requestId)
+    {
+        String json = bigModelService.getSliceInfo(requestId);
+        return success(json);
+    }
+
+    /**
+     * 异步 (提示词)
+     * @param params
+     * @return
+     */
+    @PostMapping("/async/completions")
+    public AjaxResult getAsyncCompletions(@RequestBody CompletionsParams params){
+        AsyncCompletions json = bigModelService.getAsyncCompletions(params);
+        return success(json);
+    }
+
+    /**
+     * 调用异步返回的数据
+     * @param id
+     * @return
+     */
+    @GetMapping("/async_result/{id}")
+    public AjaxResult getAsyncResult(@PathVariable String id)
+    {
+        AsyncResult json = bigModelService.getAsyncResult(id);
+        return success(json);
+    }
+
+    /**
+     * 联网聊天接口
+     * @param params
+     * @return
+     */
+    @PostMapping("/assistant")
+    public SseEmitter assistant(@RequestBody AssistantParams params){
+        return bigModelService.assistant(params);
+    }
+
+    /**
+     * 预设问题
+     */
+    @GetMapping("/presets")
+    public AjaxResult presets(){
+        Map<String, String> map = new HashMap();
+        map.put("123", "预设问题1");
+        map.put("456", "预设问题2");
+        map.put("789", "预设问题3");
+        map.put("100", "预设问题4");
+        return success(map);
+    }
+
 }

+ 44 - 9
takai-admin/src/main/java/com/takai/web/controller/system/SysLoginController.java

@@ -1,12 +1,13 @@
 package com.takai.web.controller.system;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
+
+import com.takai.common.utils.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 import com.takai.common.constant.Constants;
 import com.takai.common.core.domain.AjaxResult;
 import com.takai.common.core.domain.entity.SysMenu;
@@ -17,6 +18,8 @@ import com.takai.framework.web.service.SysLoginService;
 import com.takai.framework.web.service.SysPermissionService;
 import com.takai.system.service.ISysMenuService;
 
+import javax.servlet.http.HttpServletRequest;
+
 /**
  * 登录验证
  * 
@@ -45,9 +48,11 @@ public class SysLoginController
     {
         AjaxResult ajax = AjaxResult.success();
         // 生成令牌
-        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
-                loginBody.getUuid());
-        ajax.put(Constants.TOKEN, token);
+//        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
+//                loginBody.getUuid());
+//        ajax.put(Constants.TOKEN, token);
+        Map<String, Object> map  = loginService.login(loginBody.getUserName(), loginBody.getPassword());
+        ajax.put("data", map);
         return ajax;
     }
 
@@ -62,8 +67,8 @@ public class SysLoginController
     {
         AjaxResult ajax = AjaxResult.success();
         // 生成令牌
-        String token = loginService.getToken(loginBody.getUsername(), loginBody.getPassword());
-        ajax.put(Constants.TOKEN, token);
+        String token = loginService.getToken(loginBody.getUserName(), loginBody.getPassword());
+        ajax.put("token", token);
         return ajax;
     }
 
@@ -99,4 +104,34 @@ public class SysLoginController
         List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
         return AjaxResult.success(menuService.buildMenus(menus));
     }
+
+    /**
+     * token校验
+     * @param token
+     * @return
+     */
+    @GetMapping("/checkToken")
+    public AjaxResult checkToken(@RequestHeader String token){
+        boolean status = loginService.checkToken(token);
+        if(status){
+            AjaxResult ajax = AjaxResult.success();
+            Map<String, Object> map = new HashMap();
+            map.put("status", status);
+            ajax.put("data", map);
+            return ajax;
+        }else{
+            AjaxResult ajax = AjaxResult.errors("请求访问:/checkToken,认证失败,无法访问系统资源", null);
+            return ajax;
+        }
+    }
+
+    /**
+     * 退出登录
+     * @return
+     */
+    @PostMapping("/logout")
+    public AjaxResult logout(){
+        loginService.logout();
+        return AjaxResult.success();
+    }
 }

+ 13 - 2
takai-admin/src/main/resources/application.yml

@@ -74,7 +74,7 @@ spring:
     # 端口,默认为6379
     port: 6379
     # 数据库索引
-    database: 0
+    database: 6
     # 密码
     password:
     # 连接超时时间
@@ -145,4 +145,15 @@ bigmodel:
   #知识库列表
   knowledge: /knowledge
   #应用列表
-  application: /application
+  application: /application
+  #同步GLM-4
+  completions: https://open.bigmodel.cn/api/paas/v4/chat/completions
+  #切片信息
+  sliceInfo: /v2/{request_id}/slice_info
+  #异步GLM-4
+  asyncCompletions: https://open.bigmodel.cn/api/paas/v4/async/chat/completions
+  #异步GLM-4调用结束后使用任务结果查询
+  asyncResult: https://open.bigmodel.cn/api/paas/v4/async-result/{id}
+  #智能体会话
+  assistant: https://open.bigmodel.cn/api/paas/v4/assistant
+

+ 16 - 0
takai-bigmodel/src/main/java/com/takai/bigmodel/domain/dto/AsyncCompletions.java

@@ -0,0 +1,16 @@
+package com.takai.bigmodel.domain.dto;
+
+import lombok.Data;
+
+@Data
+public class AsyncCompletions {
+
+    private String id;
+
+    private String model;
+
+    private String request_id;
+
+    private String task_status;
+
+}

+ 24 - 0
takai-bigmodel/src/main/java/com/takai/bigmodel/domain/dto/AsyncResult.java

@@ -0,0 +1,24 @@
+package com.takai.bigmodel.domain.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class AsyncResult {
+
+    private List choices;
+
+    private String created;
+
+    private String id;
+
+    private String model;
+
+    private String request_id;
+
+    private String task_status;
+
+    private Object usage;
+
+}

+ 9 - 1
takai-bigmodel/src/main/java/com/takai/bigmodel/domain/dto/DialogReqDTO.java

@@ -8,9 +8,17 @@ import java.util.List;
 @Data
 public class DialogReqDTO {
 
-    @NotNull(message = "id不能为空")
+    //@NotNull(message = "id不能为空")
     private String id;
 
+    private String appId;
+
+    private String knowledgeId;
+
+    private String userId;
+
+    private String dialogName;
+
     private List<DialogDetailReqDTO> messages;
 
 

+ 15 - 0
takai-bigmodel/src/main/java/com/takai/bigmodel/domain/dto/DialogRespDTO.java

@@ -1,5 +1,6 @@
 package com.takai.bigmodel.domain.dto;
 
+import com.takai.common.annotation.Excel;
 import lombok.Data;
 
 import java.time.LocalDateTime;
@@ -7,18 +8,32 @@ import java.time.LocalDateTime;
 @Data
 public class DialogRespDTO {
 
+    @Excel(name = "日志ID")
     private String id;
 
+    @Excel(name = "AppID")
+    private String appId;
+
+    @Excel(name = "知识库ID")
+    private String knowledgeIdd;
+
+    @Excel(name = "用户ID")
+    private String userId;
+
     private String did;
 
+    @Excel(name = "聊天标题")
     private String dialog_name;
 
     private String dialog_id;
 
+    @Excel(name = "类型")
     private String type;
 
+    @Excel(name = "聊天内容")
     private String content;
 
+    @Excel(name = "创建时间")
     private LocalDateTime create_time;
 
 

+ 78 - 0
takai-bigmodel/src/main/java/com/takai/bigmodel/domain/entity/AssistantParams.java

@@ -0,0 +1,78 @@
+package com.takai.bigmodel.domain.entity;
+
+import java.util.List;
+
+public class AssistantParams {
+
+    private static final long serialVersionUID = 1L;
+
+    private String assistant_id;
+
+    private String conversation_id;
+
+    private String model;
+
+    private Boolean stream;
+
+    private List<Object> messages;
+
+    private List<Object> attachments;
+
+    private Object metadata;
+
+    public String getAssistant_id() {
+        return assistant_id;
+    }
+
+    public void setAssistant_id(String assistant_id) {
+        this.assistant_id = assistant_id;
+    }
+
+    public String getConversation_id() {
+        return conversation_id;
+    }
+
+    public void setConversation_id(String conversation_id) {
+        this.conversation_id = conversation_id;
+    }
+
+    public String getModel() {
+        return model;
+    }
+
+    public void setModel(String model) {
+        this.model = model;
+    }
+
+    public Boolean getStream() {
+        return stream;
+    }
+
+    public void setStream(Boolean stream) {
+        this.stream = stream;
+    }
+
+    public List<Object> getMessages() {
+        return messages;
+    }
+
+    public void setMessages(List<Object> messages) {
+        this.messages = messages;
+    }
+
+    public List<Object> getAttachments() {
+        return attachments;
+    }
+
+    public void setAttachments(List<Object> attachments) {
+        this.attachments = attachments;
+    }
+
+    public Object getMetadata() {
+        return metadata;
+    }
+
+    public void setMetadata(Object metadata) {
+        this.metadata = metadata;
+    }
+}

+ 158 - 0
takai-bigmodel/src/main/java/com/takai/bigmodel/domain/entity/CompletionsParams.java

@@ -0,0 +1,158 @@
+package com.takai.bigmodel.domain.entity;
+
+import java.util.List;
+
+public class CompletionsParams {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 要调用的模型编码
+     */
+    private String model;
+
+    /**
+     * messages
+     */
+    private List<PromptObject> messages;
+
+    /**
+     *区分每次请求的唯一标识符。如果用户端未提供,平台将默认生成。 唯一
+     */
+    private String request_id;
+
+    private Boolean do_sample;
+
+    private Boolean stream;
+
+    private Float temperature;
+
+    private Float top_p;
+
+    private Integer max_tokens;
+
+    private Object response_format;
+
+    private List stop;
+
+    private List<ToolsObject> tools;
+
+    private String type;
+
+    private String tool_choice;
+
+    private String user_id;
+
+    public String getModel() {
+        return model;
+    }
+
+    public void setModel(String model) {
+        this.model = model;
+    }
+
+    public List<PromptObject> getMessages() {
+        return messages;
+    }
+
+    public void setMessages(List<PromptObject> messages) {
+        this.messages = messages;
+    }
+
+    public String getRequest_id() {
+        return request_id;
+    }
+
+    public void setRequest_id(String request_id) {
+        this.request_id = request_id;
+    }
+
+    public Boolean getDo_sample() {
+        return do_sample;
+    }
+
+    public void setDo_sample(Boolean do_sample) {
+        this.do_sample = do_sample;
+    }
+
+    public Boolean getStream() {
+        return stream;
+    }
+
+    public void setStream(Boolean stream) {
+        this.stream = stream;
+    }
+
+    public Float getTemperature() {
+        return temperature;
+    }
+
+    public void setTemperature(Float temperature) {
+        this.temperature = temperature;
+    }
+
+    public Float getTop_p() {
+        return top_p;
+    }
+
+    public void setTop_p(Float top_p) {
+        this.top_p = top_p;
+    }
+
+    public Integer getMax_tokens() {
+        return max_tokens;
+    }
+
+    public void setMax_tokens(Integer max_tokens) {
+        this.max_tokens = max_tokens;
+    }
+
+    public Object getResponse_format() {
+        return response_format;
+    }
+
+    public void setResponse_format(Object response_format) {
+        this.response_format = response_format;
+    }
+
+    public List getStop() {
+        return stop;
+    }
+
+    public void setStop(List stop) {
+        this.stop = stop;
+    }
+
+
+    public List<ToolsObject> getTools() {
+        return tools;
+    }
+
+    public void setTools(List<ToolsObject> tools) {
+        this.tools = tools;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getTool_choice() {
+        return tool_choice;
+    }
+
+    public void setTool_choice(String tool_choice) {
+        this.tool_choice = tool_choice;
+    }
+
+    public String getUser_id() {
+        return user_id;
+    }
+
+    public void setUser_id(String user_id) {
+        this.user_id = user_id;
+    }
+}

+ 24 - 0
takai-bigmodel/src/main/java/com/takai/bigmodel/domain/entity/SearchObject.java

@@ -0,0 +1,24 @@
+package com.takai.bigmodel.domain.entity;
+
+public class SearchObject {
+
+    private Boolean enable;
+
+    private Boolean search_result;
+
+    public Boolean getEnable() {
+        return enable;
+    }
+
+    public void setEnable(Boolean enable) {
+        this.enable = enable;
+    }
+
+    public Boolean getSearch_result() {
+        return search_result;
+    }
+
+    public void setSearch_result(Boolean search_result) {
+        this.search_result = search_result;
+    }
+}

+ 24 - 0
takai-bigmodel/src/main/java/com/takai/bigmodel/domain/entity/ToolsObject.java

@@ -0,0 +1,24 @@
+package com.takai.bigmodel.domain.entity;
+
+public class ToolsObject {
+
+    private String type;
+
+    private SearchObject web_search;
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public SearchObject getWeb_search() {
+        return web_search;
+    }
+
+    public void setWeb_search(SearchObject web_search) {
+        this.web_search = web_search;
+    }
+}

+ 9 - 2
takai-bigmodel/src/main/java/com/takai/bigmodel/mapper/DialogMapper.java

@@ -1,6 +1,7 @@
 package com.takai.bigmodel.mapper;
 
 import com.takai.bigmodel.domain.dto.DialogDetailReqDTO;
+import com.takai.bigmodel.domain.dto.DialogReqDTO;
 import com.takai.bigmodel.domain.dto.DialogRespDTO;
 import com.takai.bigmodel.domain.entity.BmApplication;
 
@@ -17,7 +18,7 @@ public interface DialogMapper
      * 查询消息信息
      * @return 消息信息
      */
-    public List<DialogRespDTO> selectDialogList();
+    public List<DialogRespDTO> selectDialogList(String appId);
 
 
     /**
@@ -41,7 +42,7 @@ public interface DialogMapper
      * @param dialogId
      * @return 结果
      */
-    public void insertDialog(String dialogId);
+    public void insertDialog(DialogReqDTO dto);
 
     /**
      * 新增对话消息头表信息
@@ -51,7 +52,13 @@ public interface DialogMapper
      */
     public void insertDialogDetail(DialogDetailReqDTO dialogId);
 
+    DialogRespDTO selectDialogDetail(String dialogId);
 
+    int delDialog(String id);
 
+    int delDialogDetail(String dialogId);
 
+    void updateDialog(DialogReqDTO dialogReqDTO);
+
+    List<DialogRespDTO> selectDialogExport(String appId);
 }

+ 22 - 2
takai-bigmodel/src/main/java/com/takai/bigmodel/service/IBigModelService.java

@@ -1,12 +1,14 @@
 package com.takai.bigmodel.service;
 
+import com.takai.bigmodel.domain.dto.AsyncCompletions;
+import com.takai.bigmodel.domain.dto.AsyncResult;
 import com.takai.bigmodel.domain.dto.DialogReqDTO;
 import com.takai.bigmodel.domain.dto.DialogRespDTO;
 import com.takai.bigmodel.domain.entity.*;
-import com.takai.common.core.domain.entity.SysDictData;
 import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * 智谱 业务层
@@ -61,5 +63,23 @@ public interface IBigModelService
 
     void saveDialog(DialogReqDTO dialogReqDTO);
 
-    List<DialogRespDTO> getDialogList();
+    List<Object> getDialogList(String appId);
+
+    DialogRespDTO getDialogDetail(String dialogId);
+
+    SseEmitter getCompletions(CompletionsParams params);
+
+    String getSliceInfo(String requestId);
+
+    AsyncCompletions getAsyncCompletions(CompletionsParams params);
+
+    AsyncResult getAsyncResult(String id);
+
+    SseEmitter assistant(AssistantParams params);
+
+    void DelDialogDetail(String id);
+
+    void updateDialog(DialogReqDTO dialogReqDTO);
+
+    List<DialogRespDTO> exportExcel(String id);
 }

+ 368 - 16
takai-bigmodel/src/main/java/com/takai/bigmodel/service/impl/BigModelServiceImpl.java

@@ -3,14 +3,13 @@ package com.takai.bigmodel.service.impl;
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONArray;
 import com.alibaba.fastjson2.JSONObject;
-import com.takai.bigmodel.domain.dto.DialogDetailReqDTO;
-import com.takai.bigmodel.domain.dto.DialogReqDTO;
-import com.takai.bigmodel.domain.dto.DialogRespDTO;
+import com.takai.bigmodel.domain.dto.*;
 import com.takai.bigmodel.domain.entity.*;
 import com.takai.bigmodel.mapper.*;
 import com.takai.bigmodel.service.IBigModelService;
 import com.takai.common.config.BigModelConfig;
 import com.takai.common.core.redis.RedisCache;
+import com.takai.common.utils.uuid.IdUtils;
 import lombok.extern.slf4j.Slf4j;
 import okhttp3.*;
 import okhttp3.sse.EventSource;
@@ -24,10 +23,13 @@ import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
 
 import javax.validation.constraints.NotNull;
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
+import java.util.*;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 /**
  * 智谱 业务层处理
@@ -376,6 +378,12 @@ public class BigModelServiceImpl implements IBigModelService
 
         OkHttpClient client = buildOkHttpClient();
         List<BmApplication> applicationList = new ArrayList<>();
+        // 默认一个
+//        BmApplication application = BmApplication.builder()
+//                .appId("1234567890123456789").build();
+//        List<BmApplication> l = bmApplicationMapper.selectApplicationList(application);
+//        applicationList.addAll(l);
+
         try {
             Response response = client.newCall(request).execute();
             if(response.isSuccessful()) {
@@ -401,6 +409,24 @@ public class BigModelServiceImpl implements IBigModelService
                                 .build();
                         applicationList.add(bmApplication);
                     }
+                }else{
+                    // 默认一个
+                    String uuid = IdUtils.simpleUUID();
+                    BmApplication bmApplication = BmApplication.builder()
+                            .appId(uuid)
+                            .name("default")
+                            .desc("default")
+                            .prompt("frist")
+                            .topP("0.1")
+                            .temperature("0.05")
+                            .knowledgeIds("["+uuid+"]")
+                            .sliceCount(4)
+                            .model("glm-4-plus")
+                            .iconColor("blue")
+                            .iconType("robot_assist")
+                            .build();
+                    bmApplicationMapper.insertApplication(bmApplication);
+                    applicationList.add(bmApplication);
                 }
             } else {
                 log.error("智谱 获取应用列表失败:", response);
@@ -493,24 +519,331 @@ public class BigModelServiceImpl implements IBigModelService
 
     @Override
     public void saveDialog(DialogReqDTO dialogReqDTO) {
-        String dialogId = dialogReqDTO.getId();
-        String id = dialogMapper.selectDialogById(dialogId);
-        if(id == null) {
-            dialogMapper.insertDialog(dialogId);
-        }
+        //String dialogId = dialogReqDTO.getId();
+        //String id = dialogMapper.selectDialogById(dialogId);
+//        if(id == null) {
+//            String i = dialogMapper.insertDialog(dialogReqDTO);
+//        }
+        String uuid = IdUtils.fastSimpleUUID();
+        dialogReqDTO.setId(uuid);
+        dialogMapper.insertDialog(dialogReqDTO);
         for(DialogDetailReqDTO dto  : dialogReqDTO.getMessages()) {
-            dto.setDialogId(dialogId);
-            String detailId = dialogMapper.selectDialogDetailById(dto.getId());
+            dto.setDialogId(uuid);
+            String detailId = dialogMapper.selectDialogDetailById(uuid);
             if(detailId == null) {
+                String detailUuid = IdUtils.fastSimpleUUID();
+                dto.setId(detailUuid);
                 dialogMapper.insertDialogDetail(dto);
             }
         }
     }
 
     @Override
-    public List<DialogRespDTO> getDialogList() {
-        List<DialogRespDTO> dialogRespDTOS = dialogMapper.selectDialogList();
-        return dialogRespDTOS;
+    public List<Object> getDialogList(String appId) {
+        List<DialogRespDTO> dialogRespDTOS = dialogMapper.selectDialogList(appId);
+        //当前日期
+        LocalDate today = LocalDate.now();
+        //根据时间分组降序排序
+        NavigableMap<LocalDateTime, List<DialogRespDTO>> groupList = dialogRespDTOS.stream().collect(Collectors.groupingBy(DialogRespDTO::getCreate_time, TreeMap::new, Collectors.toList())).descendingMap();
+        List<Object> obj = new ArrayList();
+        if(!groupList.isEmpty()){
+            for(Map.Entry<LocalDateTime, List<DialogRespDTO>> entry: groupList.entrySet()){
+                // 对比两个时间相差多少天
+                long daysBetween = ChronoUnit.DAYS.between(today, entry.getKey());
+                Map<String, Object> m = new HashMap();
+                m.put("key", System.currentTimeMillis());
+                m.put("type", "group");
+                if(daysBetween == 0l){
+                    m.put("label", "今天");
+                    m.put("children", setValue(entry.getValue()));
+                    obj.add(m);
+                }else{
+                    m.put("label", -daysBetween+"天前");
+                    m.put("children", setValue(entry.getValue()));
+                    obj.add(m);
+                }
+            }
+        }
+        return obj;
+    }
+
+    @Override
+    public DialogRespDTO getDialogDetail(String dialogId) {
+        DialogRespDTO detail = dialogMapper.selectDialogDetail(dialogId);
+        return detail;
+    }
+
+    @Override
+    public SseEmitter getCompletions(CompletionsParams params) {
+        String url = bigModelConfig.getCompletions();
+        System.out.println("------------------------"+url+"------------------------");
+        SseEmitter sseEmitter = new SseEmitter(0L);
+        JSONObject json = new JSONObject();
+        json.put("model",params.getModel());
+        json.put("messages",params.getMessages());
+        json.put("stream", params.getStream());
+        json.put("request_id", params.getRequest_id());
+//        json.put("tools", params.getTools());
+//        json.put("tool_choice", params.getTool_choice());
+        RequestBody requestBody = FormBody.create(MediaType.parse("application/json; charset=utf-8") , json.toJSONString());
+
+        Request request = buildPostRequest(url,requestBody);
+        // 使用EventSourceListener处理来自服务器的SSE事件
+        EventSourceListener listener = new EventSourceListener() {
+            private String preData = "";
+            //图片识别
+            private String symbolData = "";
+            @Override
+            public void onOpen(@NotNull EventSource eventSource, @NotNull Response response) {
+                log.info("智谱 Connection opened.");
+            }
+            @Override
+            public void onClosed(@NotNull EventSource eventSource) {
+                log.info("智谱 Connection closed.");
+                sseEmitter.complete();
+            }
+            @Override
+            public void onEvent(@NotNull EventSource eventSource,  String id,  String type, @NotNull String data) {
+                try {
+                    boolean isJsonObj = isJsonObject(data);
+                    if(isJsonObj){
+                        JSONObject jsonObj = JSON.parseObject(data);
+                        if(jsonObj != null){
+                            log.info("jsonObj", jsonObj.toJSONString());
+                            JSONArray array = jsonObj.getJSONArray("choices");
+                            if(array != null){
+                                for (int i=0; i<array.size(); i++) {
+                                    JSONObject json = new JSONObject();
+                                    JSONObject msgs = array.getJSONObject(i);
+                                    boolean status  = msgs.containsKey("finish_reason");
+                                    JSONObject s = msgs.getJSONObject("delta");
+                                    json.put("id", String.valueOf(jsonObj.get("id")));
+                                    if(status){
+                                        json.put("event", "finish");
+                                    }else{
+                                        json.put("event", "add");
+                                    }
+                                    json.put("data", String.valueOf(s.get("content")));
+                                    log.info("智谱返回信息:" + json);
+                                    send(sseEmitter,json);
+                                }
+                            }
+                        }
+                    }
+                } catch (Exception e) {
+                    log.error("智谱 推送数据失败", e);
+                }
+            }
+            @Override
+            public void onFailure(@NotNull EventSource eventSource, Throwable t, Response response) {
+                log.error("智谱 Connection failed.", t);
+                sseEmitter.completeWithError(t);
+            }
+
+            private void send(SseEmitter sseEmitter, Object obj) {
+                try {
+                    sseEmitter.send(obj);
+                } catch (IOException e) {
+                    log.error("智谱 推送数据失败", e);
+                }
+            }
+        };
+        OkHttpClient client = buildOkHttpClient();
+        EventSource.Factory factory = EventSources.createFactory(client);
+        factory.newEventSource(request, listener);
+        return sseEmitter;
+    }
+
+    @Override
+    public String getSliceInfo(String requestId) {
+        String body = null;
+        String url = bigModelConfig.getBaseurl() + bigModelConfig.getSliceInfo().replace("{request_id}",requestId);
+        Request request = buildGetRequest(url);
+        OkHttpClient client = buildOkHttpClient();
+        try {
+            Response response = client.newCall(request).execute();
+            if(response.isSuccessful()) {
+                body = response.body().string();
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        return body;
+    }
+
+    @Override
+    public AsyncCompletions getAsyncCompletions(CompletionsParams params) {
+        String url = bigModelConfig.getAsyncCompletions();
+        JSONObject json = new JSONObject();
+        json.put("model",params.getModel());
+        json.put("messages",params.getMessages());
+        RequestBody requestBody = FormBody.create(MediaType.parse("application/json; charset=utf-8") , json.toJSONString());
+
+        Request request = buildPostRequest(url,requestBody);
+        OkHttpClient client = buildOkHttpClient();
+        AsyncCompletions result = null;
+        try {
+            Response response = client.newCall(request).execute();
+            if(response.isSuccessful()){
+                String body = response.body().string();
+                JSONObject jsonObj = JSON.parseObject(body);
+                result = JSONObject.parseObject(String.valueOf(jsonObj), AsyncCompletions.class);
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        return result;
+    }
+
+    @Override
+    public AsyncResult getAsyncResult(String id) {
+        String url = bigModelConfig.getAsyncResult().replace("{id}", id);
+        Request request = buildGetRequest(url);
+        OkHttpClient client = buildOkHttpClient();
+        AsyncResult vo = null;
+        try {
+            Response response = client.newCall(request).execute();
+            if(response.isSuccessful()){
+                String body = response.body().string();
+                JSONObject jsonObj = JSON.parseObject(body);
+                vo = JSONObject.parseObject(String.valueOf(jsonObj), AsyncResult.class);
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+
+        return vo;
+    }
+
+    @Override
+    public SseEmitter assistant(AssistantParams params) {
+        String url = bigModelConfig.getAssistant();
+        log.info("------------------------"+url+"------------------------");
+        SseEmitter sseEmitter = new SseEmitter(0L);
+        JSONObject json = new JSONObject();
+        json.put("assistant_id", params.getAssistant_id());
+        json.put("model", params.getModel());
+        json.put("messages",params.getMessages());
+        json.put("stream", params.getStream());
+        RequestBody requestBody = FormBody.create(MediaType.parse("application/json; charset=utf-8") , json.toJSONString());
+
+        Request request = buildPostRequest(url,requestBody);
+        // 使用EventSourceListener处理来自服务器的SSE事件
+        EventSourceListener listener = new EventSourceListener() {
+            private String preData = "";
+            //图片识别
+            private String symbolData = "";
+            @Override
+            public void onOpen(@NotNull EventSource eventSource, @NotNull Response response) {
+                log.info("智谱 Connection opened.");
+            }
+            @Override
+            public void onClosed(@NotNull EventSource eventSource) {
+                log.info("智谱 Connection closed.");
+                sseEmitter.complete();
+            }
+            @Override
+            public void onEvent(@NotNull EventSource eventSource,  String id,  String type, @NotNull String data) {
+                try {
+                    log.info("----------assistant---------"+data+"----------------assistant--------------");
+                    boolean status = isJsonObject(data);
+                    if(status){
+                        JSONObject jsonObj = JSON.parseObject(data);
+                        if(jsonObj != null){
+                            JSONArray array = jsonObj.getJSONArray("choices");
+                            if(array != null){
+                                for(int i=0; i<array.size(); i++){
+                                    JSONObject obj = array.getJSONObject(i);
+                                    JSONObject deltaObj = obj.getJSONObject("delta");
+                                    String role = String.valueOf(deltaObj.get("role"));
+                                    boolean toolStatus = deltaObj.containsKey("tool_calls");
+                                    if("tool".equals(role) && toolStatus){
+                                        JSONObject json = new JSONObject();
+                                        json.put("id", jsonObj.get("id"));
+                                        json.put("assistant_id", jsonObj.get("assistant_id"));
+                                        json.put("conversation_id", jsonObj.get("conversation_id"));
+                                        JSONArray toolArray = deltaObj.getJSONArray("tool_calls");
+                                        if(toolArray != null){
+                                            for(int j=0; j<toolArray.size(); j++){
+                                                JSONObject toolObj = toolArray.getJSONObject(j);
+                                                String toolType = String.valueOf(toolObj.get("type"));
+                                                JSONObject webObj = toolObj.getJSONObject("web_browser");
+                                                JSONObject codeObj = toolObj.getJSONObject("code_interpreter");
+                                                json.put("event", "add");
+                                                if("web_browser".equals(toolType) && webObj != null){
+                                                    if(webObj.containsKey("input")){
+                                                        json.put("data", webObj.get("input"));
+                                                    }
+                                                    if(webObj.containsKey("outputs")){
+                                                        json.put("data", webObj.getJSONArray("outputs"));
+                                                    }
+                                                }else if("code_interpreter".equals(toolType) && codeObj != null){
+                                                    if(codeObj.containsKey("input")){
+                                                        json.put("data", codeObj.get("input"));
+                                                    }
+                                                    if(codeObj.containsKey("outputs")){
+                                                        json.put("data", codeObj.getJSONArray("outputs"));
+                                                    }
+                                                }
+                                                log.info("智谱返回信息:" + json);
+                                                send(sseEmitter,json);
+                                            }
+                                        }
+                                    }else{
+                                        boolean finishStatus = deltaObj.containsKey("finish_reason");
+                                        if(finishStatus){
+                                            json.put("event", "finish");
+                                        }else{
+                                            json.put("event", "add");
+                                        }
+                                        json.put("data", deltaObj.get("content"));
+                                        log.info("智谱返回信息:" + json);
+                                        send(sseEmitter,json);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                } catch (Exception e) {
+                    log.error("智谱 推送数据失败", e);
+                }
+            }
+            @Override
+            public void onFailure(@NotNull EventSource eventSource, Throwable t, Response response) {
+                log.error("智谱 Connection failed.", t);
+                sseEmitter.completeWithError(t);
+            }
+
+            private void send(SseEmitter sseEmitter, Object obj) {
+                try {
+                    sseEmitter.send(obj);
+                } catch (IOException e) {
+                    log.error("智谱 推送数据失败", e);
+                }
+            }
+        };
+        OkHttpClient client = buildOkHttpClient();
+        EventSource.Factory factory = EventSources.createFactory(client);
+        factory.newEventSource(request, listener);
+        return sseEmitter;
+    }
+
+    @Override
+    public void DelDialogDetail(String id) {
+        int result = dialogMapper.delDialog(id);
+        if(result > 0){
+            dialogMapper.delDialogDetail(id);
+        }
+    }
+
+    @Override
+    public void updateDialog(DialogReqDTO dialogReqDTO) {
+        dialogMapper.updateDialog(dialogReqDTO);
+    }
+
+    @Override
+    public List<DialogRespDTO> exportExcel(String id) {
+        return dialogMapper.selectDialogExport(id);
     }
 
     private Request buildGetRequest(String url) {
@@ -537,5 +870,24 @@ public class BigModelServiceImpl implements IBigModelService
                 .build();
     }
 
+    private boolean isJsonObject(String data){
+        try {
+            JSON.parseObject(data);
+            return true;
+        }catch (Exception e){
+            return false;
+        }
+    }
+
+    private List<Map<String, Object>> setValue(List<DialogRespDTO> list){
+        List<Map<String, Object>> l = new ArrayList();
+        for (DialogRespDTO vo : list) {
+            Map<String, Object> map = new HashMap();
+            map.put("key", vo.getId());
+            map.put("label", vo.getDialog_name());
+            l.add(map);
+        }
+        return l;
+    }
 
 }

+ 77 - 15
takai-bigmodel/src/main/resources/mapper/bm/DialogMapper.xml

@@ -44,44 +44,106 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 	</select>
 
 	<select id="selectDialogList"  resultMap="DialogResult">
-		select d.id
-		,d.dialog_name
-		,dd.id as did
-		,dd.type
-		,dd.content
-		,dd.dialog_id
-		,dd.create_time
+		select
+			max(d.id) as id,
+			d.app_id as appId,
+			d.knowledge_id as knowledgeId,
+			d.user_id as userId,
+			d.dialog_name,
+			date_format(d.create_time, '%Y-%m-%d') as create_time,
+			dd.id as did,
+		    dd.type,
+			dd.content,
+			dd.dialog_id
 		from dialog d
 		left join dialog_detail dd on d.id = dd.dialog_id
-		order by d.id asc
+		where d.app_id = #{appId}
+		GROUP BY d.app_id,d.create_time
+		ORDER BY d.create_time desc
 	</select>
  	
- 	<insert id="insertDialog" parameterType="String">
+ 	<insert id="insertDialog" parameterType="DialogReqDTO">
  		insert into dialog(
- 			<if test="dialogId != null">id,</if>
+		    id,
+			<if test="appId != null">app_id,</if>
+			<if test="knowledgeId != null">knowledge_id,</if>
+			<if test="userId != null">user_id,</if>
+			<if test="dialogName != null">dialog_name,</if>
  			create_time
  		)values(
-			<if test="dialogId != null">#{dialogId},</if>
+			#{id},
+			<if test="appId != null">#{appId},</if>
+			<if test="knowledgeId != null">#{knowledgeId},</if>
+			<if test="userId != null">#{userId},</if>
+			<if test="dialogName != null">#{dialogName},</if>
  			sysdate()
  		)
 	</insert>
 
 	<insert id="insertDialogDetail" parameterType="DialogDetailReqDTO">
 		insert into dialog_detail(
-		<if test="id != null">id,</if>
+		id,
 		<if test="dialogId != null">dialog_id,</if>
 		<if test="role != null">type,</if>
 		<if test="content != null">content,</if>
 		<if test="role != null">create_by,</if>
-		<if test="date != null">create_time</if>
+		create_time
 		)values(
-		<if test="id != null">#{id},</if>
+		#{id},
 		<if test="dialogId != null">#{dialogId},</if>
 		<if test="role != null">#{role},</if>
 		<if test="content != null">#{content},</if>
 		<if test="role != null">#{role},</if>
-		<if test="date != null">#{date}</if>
+		sysdate()
 		)
 	</insert>
+
+	<select id="selectDialogDetail"  resultMap="DialogResult">
+		select
+			d.id,
+			d.app_id as appId,
+			d.knowledge_id as knowledgeId,
+			d.user_id as userId,
+			d.dialog_name,
+			dd.id as did,
+			dd.type,
+			dd.content,
+			dd.dialog_id,
+			dd.create_time
+		from dialog d
+		left join dialog_detail dd on d.id = dd.dialog_id
+		where dd.dialog_id = #{dialogId}
+	</select>
+
+	<delete id="delDialog" parameterType="String">
+		delete from dialog where id = #{id}
+	</delete>
+
+	<delete id="delDialogDetail" parameterType="String">
+		delete from dialog_detail where dialog_id = #{dialogId}
+	</delete>
+
+	<update id="updateDialog" parameterType="DialogDetailReqDTO">
+		update dialog set dialog_name = #{dialogName} where id = #{id}
+	</update>
+
+	<select id="selectDialogExport"  resultMap="DialogResult">
+		select
+			max(d.id) as id,
+			d.app_id as appId,
+			d.knowledge_id as knowledgeId,
+			d.user_id as userId,
+			d.dialog_name,
+			d.create_time,
+			dd.id as did,
+			dd.type,
+			dd.content,
+			dd.dialog_id
+		from dialog d
+		left join dialog_detail dd on d.id = dd.dialog_id
+		where d.id = #{id}
+		GROUP BY d.app_id,d.create_time
+		ORDER BY d.create_time desc
+	</select>
 	
 </mapper> 

+ 65 - 0
takai-common/src/main/java/com/takai/common/config/BigModelConfig.java

@@ -27,6 +27,31 @@ public class BigModelConfig
     /** 应用列表 地址 */
     private String application;
 
+    /**
+     * 同步GLM-4
+     */
+    private String completions;
+
+    /**
+     * 切片信息
+     */
+    private String sliceInfo;
+
+    /**
+     * 异步GLM-4
+     */
+    private String asyncCompletions;
+
+    /**
+     * 任务结果查询(异步返回结果)
+     */
+    private String asyncResult;
+
+    /**
+     * 智能体会话
+     */
+    private String assistant;
+
 
     public String getBigModelApiKey()
     {
@@ -85,4 +110,44 @@ public class BigModelConfig
     public void setApplication(String application) {
         this.application = application;
     }
+
+    public String getCompletions() {
+        return completions;
+    }
+
+    public void setCompletions(String completions) {
+        this.completions = completions;
+    }
+
+    public String getSliceInfo() {
+        return sliceInfo;
+    }
+
+    public void setSliceInfo(String sliceInfo) {
+        this.sliceInfo = sliceInfo;
+    }
+
+    public String getAsyncCompletions() {
+        return asyncCompletions;
+    }
+
+    public void setAsyncCompletions(String asyncCompletions) {
+        this.asyncCompletions = asyncCompletions;
+    }
+
+    public String getAsyncResult() {
+        return asyncResult;
+    }
+
+    public void setAsyncResult(String asyncResult) {
+        this.asyncResult = asyncResult;
+    }
+
+    public String getAssistant() {
+        return assistant;
+    }
+
+    public void setAssistant(String assistant) {
+        this.assistant = assistant;
+    }
 }

+ 5 - 0
takai-common/src/main/java/com/takai/common/constant/Constants.java

@@ -69,6 +69,11 @@ public class Constants
      */
     public static final Integer CAPTCHA_EXPIRATION = 2;
 
+    /**
+     * 验证码有效期(分钟)
+     */
+    public static final Integer TOKEN_EXPIRATION = 20;
+
     /**
      * 令牌
      */

+ 5 - 0
takai-common/src/main/java/com/takai/common/core/domain/AjaxResult.java

@@ -200,6 +200,11 @@ public class AjaxResult extends HashMap<String, Object>
         return Objects.equals(HttpStatus.ERROR, this.get(CODE_TAG));
     }
 
+    public static AjaxResult errors(String msg, Object data)
+    {
+        return new AjaxResult(HttpStatus.UNAUTHORIZED, msg, data);
+    }
+
     /**
      * 方便链式调用
      *

+ 5 - 7
takai-common/src/main/java/com/takai/common/core/domain/model/LoginBody.java

@@ -10,7 +10,7 @@ public class LoginBody
     /**
      * 用户名
      */
-    private String username;
+    private String userName;
 
     /**
      * 用户密码
@@ -27,14 +27,12 @@ public class LoginBody
      */
     private String uuid;
 
-    public String getUsername()
-    {
-        return username;
+    public String getUserName() {
+        return userName;
     }
 
-    public void setUsername(String username)
-    {
-        this.username = username;
+    public void setUserName(String userName) {
+        this.userName = userName;
     }
 
     public String getPassword()

+ 3 - 1
takai-framework/src/main/java/com/takai/framework/config/SecurityConfig.java

@@ -111,7 +111,9 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 // 过滤请求
                 .authorizeRequests()
                 // 对于登录login 注册register 验证码captchaImage 允许匿名访问
-                .antMatchers("/login", "/register", "/captchaImage","/getToken","/**/sse-invoke","/**/application/list","/bigmodel/api/dialog/*").permitAll()
+                .antMatchers("/login", "/register", "/captchaImage","/getToken","/**/sse-invoke","/**/application/list","/bigmodel/api/dialog/**",
+                        "/**/completions", "/**/slice_info/**", "/**/async_result/**", "/**/assistant/**", "/getInfo",
+                        "/checkToken", "/**/presets/**").permitAll()
                 // 静态资源,可匿名访问
                 .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
                 .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()

+ 6 - 0
takai-framework/src/main/java/com/takai/framework/security/handle/LogoutSuccessHandlerImpl.java

@@ -4,6 +4,8 @@ import java.io.IOException;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+
+import com.takai.common.core.redis.RedisCache;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.security.core.Authentication;
@@ -29,6 +31,9 @@ public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler
     @Autowired
     private TokenService tokenService;
 
+    @Autowired
+    private RedisCache redisCache;
+
     /**
      * 退出处理
      * 
@@ -47,6 +52,7 @@ public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler
             // 记录用户退出日志
             AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功"));
         }
+        redisCache.deleteObject("login_token");
         ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.success("退出成功")));
     }
 }

+ 73 - 0
takai-framework/src/main/java/com/takai/framework/web/service/SysLoginService.java

@@ -1,9 +1,11 @@
 package com.takai.framework.web.service;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
 
 import com.takai.common.utils.SecurityUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@@ -31,7 +33,10 @@ import com.takai.framework.security.context.AuthenticationContextHolder;
 import com.takai.system.service.ISysConfigService;
 import com.takai.system.service.ISysUserService;
 
+import java.util.HashMap;
+import java.util.Map;
 import java.util.UUID;
+import java.util.concurrent.TimeUnit;
 
 /**
  * 登录校验方法
@@ -41,6 +46,10 @@ import java.util.UUID;
 @Component
 public class SysLoginService
 {
+    // 令牌自定义标识
+    @Value("${token.header}")
+    private String header;
+
     @Autowired
     private TokenService tokenService;
 
@@ -202,4 +211,68 @@ public class SysLoginService
         //19b5bca9593844ecbb3d8bd8f9d88eaf
         //bcc5e847c7d24319a49e752b4019ea7f
     }
+
+    public Map<String, Object> login(String username, String password)
+    {
+        // 登录前置校验
+        loginPreCheck(username, password);
+        // 用户验证
+        Authentication authentication = null;
+        try
+        {
+            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
+            AuthenticationContextHolder.setContext(authenticationToken);
+            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
+            authentication = authenticationManager.authenticate(authenticationToken);
+        }
+        catch (Exception e)
+        {
+            if (e instanceof BadCredentialsException)
+            {
+                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
+                throw new UserPasswordNotMatchException();
+            }
+            else
+            {
+                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
+                throw new ServiceException(e.getMessage());
+            }
+        }
+        finally
+        {
+            AuthenticationContextHolder.clearContext();
+        }
+        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
+        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
+        recordLoginInfo(loginUser.getUserId());
+
+        // 生成token
+        String login_token = tokenService.createToken(loginUser);
+        redisCache.setCacheObject("login_token", login_token, Constants.TOKEN_EXPIRATION, TimeUnit.MINUTES);
+        Map<String, Object> map = new HashMap();
+        map.put("userId", loginUser.getUserId());
+        map.put("nickName", loginUser.getUser().getNickName());
+        map.put("token", login_token);
+        return map;
+    }
+
+    public boolean checkToken(String token){
+        String loginToken = redisCache.getCacheObject("login_token");
+        if(StringUtils.isNotEmpty(loginToken) && loginToken.equals(token)){
+            return true;
+        }
+        return false;
+    }
+
+
+    public void logout(){
+        SysUser user = SecurityUtils.getLoginUser().getUser();
+        SysUser sysUser = new SysUser();
+        sysUser.setUserId(user.getUserId());
+        sysUser.setLoginIp(IpUtils.getIpAddr());
+        sysUser.setStatus(Constants.LOGOUT);
+        sysUser.setUpdateTime(DateUtils.getNowDate());
+        userService.updateUserProfile(sysUser);
+        redisCache.deleteObject("login_token");
+    }
 }

+ 1 - 1
takai-framework/src/main/java/com/takai/framework/web/service/SysRegisterService.java

@@ -40,7 +40,7 @@ public class SysRegisterService
      */
     public String register(RegisterBody registerBody)
     {
-        String msg = "", username = registerBody.getUsername(), password = registerBody.getPassword();
+        String msg = "", username = registerBody.getUserName(), password = registerBody.getPassword();
         SysUser sysUser = new SysUser();
         sysUser.setUserName(username);