From ca330fc695b8b6b65d3eb8699c4c40f42de49994 Mon Sep 17 00:00:00 2001 From: wangys <3401275564@qq.com> Date: Tue, 30 Dec 2025 18:38:24 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 ++- difyPlugin/.vscode/launch.json | 17 +++++++++++++++++ difyPlugin/.vscode/settings.json | 0 urbanLifelineServ/.vscode/launch.json | 14 -------------- .../java/org/xyzh/ai/client/DifyApiClient.java | 5 ++--- .../ai/service/impl/AgentChatServiceImpl.java | 4 +++- .../ai/src/main/resources/application-dev.yml | 8 +++++++- .../ai/src/main/resources/application.yml | 1 + .../file/src/main/resources/application.yml | 6 +++--- .../src/main/resources/application-dev.yml | 8 +++++++- 10 files changed, 42 insertions(+), 24 deletions(-) create mode 100644 difyPlugin/.vscode/launch.json create mode 100644 difyPlugin/.vscode/settings.json diff --git a/.gitignore b/.gitignore index 42eae94a..c121daee 100644 --- a/.gitignore +++ b/.gitignore @@ -202,4 +202,5 @@ cython_debug/ 江西城市生命线-可交互原型/frontend/node_modules/* THAI-Platform/* urbanLifelineWeb/packages/wechat_demo/* -urbanLifelineWeb/packages/workcase_wechat/unpackage/* \ No newline at end of file +urbanLifelineWeb/packages/workcase_wechat/unpackage/* +docs/AI训练资料 \ No newline at end of file diff --git a/difyPlugin/.vscode/launch.json b/difyPlugin/.vscode/launch.json new file mode 100644 index 00000000..3ef0a12c --- /dev/null +++ b/difyPlugin/.vscode/launch.json @@ -0,0 +1,17 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "DifyPlugin: FastAPI", + "type": "debugpy", + "request": "launch", + "program": "run.py", + "cwd": "${workspaceFolder}", + "python": "F:\\Environment\\conda\\envs\\difyPlugin\\python.exe", + "env": { + "PYTHONPATH": "${workspaceFolder}/difyPlugin" + }, + "jinja": true + } + ] +} \ No newline at end of file diff --git a/difyPlugin/.vscode/settings.json b/difyPlugin/.vscode/settings.json new file mode 100644 index 00000000..e69de29b diff --git a/urbanLifelineServ/.vscode/launch.json b/urbanLifelineServ/.vscode/launch.json index 2fee27d0..0fc9038e 100644 --- a/urbanLifelineServ/.vscode/launch.json +++ b/urbanLifelineServ/.vscode/launch.json @@ -1,20 +1,6 @@ { "version": "0.2.0", "configurations": [ - { - "type": "java", - "name": "URLQRCodeParseTest", - "request": "launch", - "mainClass": "org.xyzh.workcase.test.URLQRCodeParseTest", - "projectName": "workcase" - }, - { - "type": "java", - "name": "QRCodeTest", - "request": "launch", - "mainClass": "org.xyzh.workcase.test.QRCodeTest", - "projectName": "workcase" - }, { "type": "java", "name": "AesEncryptUtil", diff --git a/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/client/DifyApiClient.java b/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/client/DifyApiClient.java index bd5c419c..53c84a69 100644 --- a/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/client/DifyApiClient.java +++ b/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/client/DifyApiClient.java @@ -284,9 +284,8 @@ public class DifyApiClient { dataMap.put("process_rule", defaultProcessRule); } - // 默认设置文档形式和语言 - dataMap.put("doc_form", "text_model"); - dataMap.put("doc_language", "Chinese"); + // 只保留官方支持的参数 + // doc_form 和 doc_language 不是请求参数,移除 String dataJson = JSON.toJSONString(dataMap); logger.info("上传文档到知识库: datasetId={}, file={}, data={}", datasetId, originalFilename, dataJson); diff --git a/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/service/impl/AgentChatServiceImpl.java b/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/service/impl/AgentChatServiceImpl.java index 925fb3c9..2e0e3880 100644 --- a/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/service/impl/AgentChatServiceImpl.java +++ b/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/service/impl/AgentChatServiceImpl.java @@ -300,6 +300,7 @@ public class AgentChatServiceImpl implements AgentChatService { sessionData.put("apiKey", agent.getApiKey()); sessionData.put("outer", agent.getIsOuter()); sessionData.put("service", prepareData.getService()); + sessionData.put("isGuest", "guest".equals(loginDomain.getUser().getStatus())); String cacheKey = CHAT_SESSION_PREFIX + sessionId; redisService.set(cacheKey, sessionData, SESSION_TTL, TimeUnit.SECONDS); @@ -335,6 +336,7 @@ public class AgentChatServiceImpl implements AgentChatService { String apiKey = (String) sessionData.get("apiKey"); String service = (String) sessionData.get("service"); Boolean outer = (Boolean) sessionData.get("outer"); + Boolean isGuest = (Boolean) sessionData.get("isGuest"); @SuppressWarnings("unchecked") List filesData = (List) sessionData.get("filesData"); @@ -375,7 +377,7 @@ public class AgentChatServiceImpl implements AgentChatService { if(outer && NonUtils.isNotEmpty(service)){ TbKnowledge filter = new TbKnowledge(); filter.setService(service); - filter.setCategory("external"); + filter.setCategory(isGuest?"external":"internal"); ResultDomain knowledgeRD = knowledgeService.listKnowledges(filter); List datasets = new ArrayList<>(); if(knowledgeRD.getSuccess()){ diff --git a/urbanLifelineServ/ai/src/main/resources/application-dev.yml b/urbanLifelineServ/ai/src/main/resources/application-dev.yml index da48f901..310d49ba 100644 --- a/urbanLifelineServ/ai/src/main/resources/application-dev.yml +++ b/urbanLifelineServ/ai/src/main/resources/application-dev.yml @@ -29,7 +29,12 @@ security: spring: application: name: ai-service - + # 文件上传配置 + servlet: + multipart: + enabled: true + max-file-size: 500MB + max-request-size: 500MB # ================== Spring Cloud Nacos ================== cloud: nacos: @@ -72,6 +77,7 @@ dubbo: name: urban-lifeline-agent qos-enable: false protocol: + payload: 110100480 name: dubbo port: -1 registry: diff --git a/urbanLifelineServ/ai/src/main/resources/application.yml b/urbanLifelineServ/ai/src/main/resources/application.yml index dc0f506e..35253da8 100644 --- a/urbanLifelineServ/ai/src/main/resources/application.yml +++ b/urbanLifelineServ/ai/src/main/resources/application.yml @@ -72,6 +72,7 @@ dubbo: name: urban-lifeline-agent qos-enable: false protocol: + payload: 110100480 name: dubbo port: -1 registry: diff --git a/urbanLifelineServ/file/src/main/resources/application.yml b/urbanLifelineServ/file/src/main/resources/application.yml index d6036770..0570b2ea 100644 --- a/urbanLifelineServ/file/src/main/resources/application.yml +++ b/urbanLifelineServ/file/src/main/resources/application.yml @@ -29,7 +29,6 @@ security: spring: application: name: file-service - # ================== Spring Cloud Nacos ================== cloud: nacos: @@ -57,8 +56,8 @@ spring: servlet: multipart: enabled: true - max-file-size: 100MB - max-request-size: 100MB + max-file-size: 500MB + max-request-size: 500MB # ================== SpringDoc ================== springdoc: @@ -79,6 +78,7 @@ dubbo: name: urban-lifeline-file qos-enable: false protocol: + payload: 110100480 name: dubbo port: -1 registry: diff --git a/urbanLifelineServ/workcase/src/main/resources/application-dev.yml b/urbanLifelineServ/workcase/src/main/resources/application-dev.yml index f10a3546..930a8654 100644 --- a/urbanLifelineServ/workcase/src/main/resources/application-dev.yml +++ b/urbanLifelineServ/workcase/src/main/resources/application-dev.yml @@ -32,7 +32,12 @@ security: spring: application: name: workcase-service - + # 文件上传配置 + servlet: + multipart: + enabled: true + max-file-size: 500MB + max-request-size: 500MB # ================== Spring Cloud Nacos ================== cloud: nacos: @@ -75,6 +80,7 @@ dubbo: name: urban-lifeline-workcase qos-enable: false protocol: + payload: 110100480 name: dubbo port: -1 registry: From 4e04e4599e90db0921a7e3dbb504038c37939496 Mon Sep 17 00:00:00 2001 From: wangys <3401275564@qq.com> Date: Tue, 30 Dec 2025 19:16:51 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E7=9F=A5=E8=AF=86=E5=BA=93=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=88=A0=E9=99=A4=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/xyzh/ai/controller/KnowledgeController.java | 8 ++++---- .../packages/shared/src/api/ai/aiKnowledge.ts | 4 ++-- .../workcase/src/views/admin/knowledge/KnowLedgeView.vue | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/controller/KnowledgeController.java b/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/controller/KnowledgeController.java index a65ebb79..56b03532 100644 --- a/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/controller/KnowledgeController.java +++ b/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/controller/KnowledgeController.java @@ -235,10 +235,10 @@ public class KnowledgeController { * @since 2025-12-18 */ @PreAuthorize("hasAuthority('ai:knowledge:file:delete')") - @DeleteMapping("/file/{fileId}") - public ResultDomain deleteFile(@PathVariable("fileId") @NotBlank String fileId) { - logger.info("删除知识库文件: fileId={}", fileId); - return knowledgeService.deleteKnowledgeFileById(fileId); + @DeleteMapping("/file/{fileRootId}") + public ResultDomain deleteFile(@PathVariable("fileRootId") @NotBlank String fileRootId) { + logger.info("删除知识库文件: fileId={}", fileRootId); + return knowledgeService.deleteKnowledgeFileById(fileRootId); } /** diff --git a/urbanLifelineWeb/packages/shared/src/api/ai/aiKnowledge.ts b/urbanLifelineWeb/packages/shared/src/api/ai/aiKnowledge.ts index 61e6986e..583ac287 100644 --- a/urbanLifelineWeb/packages/shared/src/api/ai/aiKnowledge.ts +++ b/urbanLifelineWeb/packages/shared/src/api/ai/aiKnowledge.ts @@ -162,8 +162,8 @@ export const aiKnowledgeAPI = { * 删除知识库文件 * @param fileId 文件ID */ - async deleteFile(fileId: string): Promise> { - const response = await api.delete(`${this.baseUrl}/file/${fileId}`) + async deleteFile(fileRootId: string): Promise> { + const response = await api.delete(`${this.baseUrl}/file/${fileRootId}`) return response.data }, diff --git a/urbanLifelineWeb/packages/workcase/src/views/admin/knowledge/KnowLedgeView.vue b/urbanLifelineWeb/packages/workcase/src/views/admin/knowledge/KnowLedgeView.vue index 6ffa3bc4..19c2028e 100644 --- a/urbanLifelineWeb/packages/workcase/src/views/admin/knowledge/KnowLedgeView.vue +++ b/urbanLifelineWeb/packages/workcase/src/views/admin/knowledge/KnowLedgeView.vue @@ -278,7 +278,7 @@ const deleteFile = async (row: DocumentItem) => { cancelButtonText: '取消', type: 'warning' }) - const result = await aiKnowledgeAPI.deleteFile(row.id) + const result = await aiKnowledgeAPI.deleteFile(row.fileRootId) if (result.success) { ElMessage.success('删除成功') fetchDocuments(activeKnowledgeId.value) From 5ce012000b8344f979b0c6ef042acd65f6b26b23 Mon Sep 17 00:00:00 2001 From: wangys <3401275564@qq.com> Date: Tue, 30 Dec 2025 20:54:48 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=E7=9F=A5=E8=AF=86=E5=BA=93=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E6=95=B0=E9=87=8F=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/org/xyzh/ai/mapper/TbKnowledgeMapper.java | 2 ++ .../java/org/xyzh/ai/service/impl/KnowledgeServiceImpl.java | 4 ++++ .../ai/src/main/resources/mapper/TbKnowledgeMapper.xml | 6 ++++++ 3 files changed, 12 insertions(+) diff --git a/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/mapper/TbKnowledgeMapper.java b/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/mapper/TbKnowledgeMapper.java index 01592252..58a7eca7 100644 --- a/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/mapper/TbKnowledgeMapper.java +++ b/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/mapper/TbKnowledgeMapper.java @@ -32,6 +32,8 @@ public interface TbKnowledgeMapper { */ int deleteKnowledge(TbKnowledge knowledge); + int updateKnowledgeFileCount(String knowledgeId, int num); + /** * 根据ID查询知识库 */ diff --git a/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/service/impl/KnowledgeServiceImpl.java b/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/service/impl/KnowledgeServiceImpl.java index 43de2d3f..d9daa98a 100644 --- a/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/service/impl/KnowledgeServiceImpl.java +++ b/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/service/impl/KnowledgeServiceImpl.java @@ -533,6 +533,7 @@ public class KnowledgeServiceImpl implements KnowledgeService { knowledgeFile.setDifyFileId(difyFileId); knowledgeFile.setVersion(1); + knowledgeMapper.updateKnowledgeFileCount(knowledgeId, 1); int rows = knowledgeFileMapper.insertKnowledgeFile(knowledgeFile); if (rows > 0) { logger.info("保存知识库文件记录成功: knowledgeId={}, fileId={}, difyFileId={}", knowledgeId, fileId, difyFileId); @@ -722,10 +723,13 @@ public class KnowledgeServiceImpl implements KnowledgeService { if (!difyDocIds.isEmpty()) { aiFileUploadService.batchDeleteFilesFromDify(knowledge.getDifyDatasetId(), difyDocIds); } + }else{ + return ResultDomain.failure("知识库未关联Dify"); } // 3. 软删除本地记录和minio文件 int rows = knowledgeFileMapper.deleteFilesByRootId(fileRootId); + knowledgeMapper.updateKnowledgeFileCount(knowledge.getKnowledgeId(), -1); if (rows > 0) { logger.info("删除知识库文件成功: fileRootId={}", fileRootId); for (TbKnowledgeFile file : versions) { diff --git a/urbanLifelineServ/ai/src/main/resources/mapper/TbKnowledgeMapper.xml b/urbanLifelineServ/ai/src/main/resources/mapper/TbKnowledgeMapper.xml index 1fb778ad..70a379e0 100644 --- a/urbanLifelineServ/ai/src/main/resources/mapper/TbKnowledgeMapper.xml +++ b/urbanLifelineServ/ai/src/main/resources/mapper/TbKnowledgeMapper.xml @@ -112,6 +112,12 @@ WHERE knowledge_id = #{knowledgeId} AND deleted = false + + UPDATE ai.tb_knowledge + SET document_count = document_count + #{fileCount} + WHERE knowledge_id = #{knowledgeId} AND deleted = false + + SELECT r.room_id, r.optsn, r.workcase_id, r.room_name, r.room_type, r.status, - r.guest_id, r.guest_name, r.ai_session_id, r.message_count, + r.guest_id, r.guest_name, r.ai_session_id, r.message_count, r.device_code, r.last_message_time, r.last_message, r.comment_level, r.closed_by, r.closed_time, r.creator, r.create_time, r.update_time, r.delete_time, r.deleted, COALESCE(m.unread_count, 0) as unread_count diff --git a/urbanLifelineWeb/packages/workcase/src/types/workcase/chatRoom.ts b/urbanLifelineWeb/packages/workcase/src/types/workcase/chatRoom.ts index 3ff50bdb..b63298ec 100644 --- a/urbanLifelineWeb/packages/workcase/src/types/workcase/chatRoom.ts +++ b/urbanLifelineWeb/packages/workcase/src/types/workcase/chatRoom.ts @@ -13,6 +13,7 @@ export interface TbChatRoomDTO extends BaseDTO { status?: string guestId?: string guestName?: string + deviceCode?: string aiSessionId?: string currentAgentId?: string agentCount?: number @@ -164,6 +165,7 @@ export interface ChatRoomVO extends BaseVO { status?: string guestId?: string guestName?: string + deviceCode?: string aiSessionId?: string currentAgentId?: string currentAgentName?: string diff --git a/urbanLifelineWeb/packages/workcase/src/views/public/ChatRoom/ChatRoomView.vue b/urbanLifelineWeb/packages/workcase/src/views/public/ChatRoom/ChatRoomView.vue index 2aa200b1..5e0fc663 100644 --- a/urbanLifelineWeb/packages/workcase/src/views/public/ChatRoom/ChatRoomView.vue +++ b/urbanLifelineWeb/packages/workcase/src/views/public/ChatRoom/ChatRoomView.vue @@ -189,7 +189,7 @@ import { Client } from '@stomp/stompjs' // WebSocket配置 (通过Nginx代理访问网关,再到workcase服务) // SockJS URL (http://) const getWsUrl = () => { - const token = localStorage.getItem('token')! + const token = JSON.parse(localStorage.getItem('token')!).value const protocol = window.location.protocol const host = window.location.host return `${protocol}//${host}/api/urban-lifeline/workcase/ws/chat-sockjs?token=${encodeURIComponent(token)}` @@ -557,32 +557,6 @@ const startMeeting = async () => { } return } - - // 没有活跃会议,创建新会议 - const createResult = await workcaseChatAPI.createVideoMeeting({ - roomId: currentRoomId.value, - meetingName: currentRoom.value?.roomName || '视频会议' - }) - - if (createResult.success && createResult.data) { - const currentMeetingId = createResult.data.meetingId! - - // 开始会议 - await workcaseChatAPI.startVideoMeeting(currentMeetingId) - - // 加入会议获取会议页面URL - const joinResult = await workcaseChatAPI.joinVideoMeeting(currentMeetingId) - if (joinResult.success && joinResult.data?.iframeUrl) { - // 使用router跳转到JitsiMeetingView页面,附加roomId参数用于返回 - const meetingUrl = joinResult.data.iframeUrl + `&roomId=${currentRoomId.value}` - router.push(meetingUrl) - ElMessage.success('会议已创建') - } else { - ElMessage.error(joinResult.message || '获取会议链接失败') - } - } else { - ElMessage.error(createResult.message || '创建会议失败') - } } catch (error) { console.error('发起会议失败:', error) ElMessage.error('发起会议失败') @@ -707,8 +681,16 @@ const subscribeToRoom = (roomId: string) => { // 避免重复添加自己发送的普通消息 // 但会议消息(meet类型)始终添加,因为它是系统生成的通知 if (chatMessage.messageType === 'meet' || chatMessage.senderId !== loginDomain.user.userId) { - messages.value.push(chatMessage) - scrollToBottom() + // 会议消息延时处理,等待数据库事务提交 + if (chatMessage.messageType === 'meet') { + console.log('[ChatRoom] 收到会议消息,延时1秒后刷新') + setTimeout(() => { + loadMessages(roomId) + }, 1000) + } else { + messages.value.push(chatMessage) + scrollToBottom() + } } }) } diff --git a/urbanLifelineWeb/packages/workcase_wechat/pages/chatRoom/chatRoom/chatRoom.uvue b/urbanLifelineWeb/packages/workcase_wechat/pages/chatRoom/chatRoom/chatRoom.uvue index f872ed28..df920823 100644 --- a/urbanLifelineWeb/packages/workcase_wechat/pages/chatRoom/chatRoom/chatRoom.uvue +++ b/urbanLifelineWeb/packages/workcase_wechat/pages/chatRoom/chatRoom/chatRoom.uvue @@ -784,6 +784,16 @@ function handleNewMessage(message: ChatRoomMessageVO) { return } + // 会议消息延时处理,等待数据库事务提交 + if (message.messageType === 'meet') { + console.log('[chatRoom] 收到会议消息,延时1秒后刷新') + setTimeout(async () => { + // 重新加载最新消息,确保获取到完整的会议消息数据 + await loadMessages() + }, 1000) + return + } + // 添加新消息到列表 messages.push(message) nextTick(() => scrollToBottom()) diff --git a/urbanLifelineWeb/packages/workcase_wechat/pages/index/index.scss b/urbanLifelineWeb/packages/workcase_wechat/pages/index/index.scss index 0cc4288c..16853d0b 100644 --- a/urbanLifelineWeb/packages/workcase_wechat/pages/index/index.scss +++ b/urbanLifelineWeb/packages/workcase_wechat/pages/index/index.scss @@ -696,3 +696,110 @@ opacity: 1; } } + +// 设备代码输入弹窗样式 +.device-code-modal { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 1000; + display: flex; + align-items: center; + justify-content: center; +} + +.modal-mask { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); +} + +.modal-content { + position: relative; + background-color: white; + border-radius: 16px; + width: 80%; + max-width: 320px; + padding: 20px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); +} + +.modal-header { + margin-bottom: 20px; +} + +.modal-title { + font-size: 18px; + font-weight: 600; + color: #333; + text-align: center; + display: block; +} + +.modal-body { + margin-bottom: 20px; +} + +.device-code-input { + width: 100%; + height: 44px; + padding: 0 12px; + border: 1px solid #ddd; + border-radius: 8px; + font-size: 16px; + background-color: #f9f9f9; + box-sizing: border-box; +} + +.device-code-input:focus { + border-color: #007AFF; + background-color: white; + outline: none; +} + +.modal-footer { + display: flex; + flex-direction: row; + gap: 12px; +} + +.modal-btn { + flex: 1; + height: 44px; + border-radius: 8px; + border: none; + font-size: 16px; + font-weight: 500; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: all 0.2s; +} + +.modal-btn.cancel { + background-color: #f5f5f5; + color: #666; +} + +.modal-btn.cancel:active { + background-color: #e5e5e5; +} + +.modal-btn.confirm { + background-color: #007AFF; + color: white; +} + +.modal-btn.confirm:active { + background-color: #0056b3; +} + +.modal-btn .btn-text { + font-size: 16px; +} diff --git a/urbanLifelineWeb/packages/workcase_wechat/pages/index/index.uvue b/urbanLifelineWeb/packages/workcase_wechat/pages/index/index.uvue index 6a90f8bf..3744829a 100644 --- a/urbanLifelineWeb/packages/workcase_wechat/pages/index/index.uvue +++ b/urbanLifelineWeb/packages/workcase_wechat/pages/index/index.uvue @@ -148,6 +148,33 @@ + + + + + + + 请输入设备代码 + + + + + + + + + + - diff --git a/urbanLifelineWeb/packages/workcase_wechat/types/workcase/chatRoom.ts b/urbanLifelineWeb/packages/workcase_wechat/types/workcase/chatRoom.ts index 8bad3526..4aca5422 100644 --- a/urbanLifelineWeb/packages/workcase_wechat/types/workcase/chatRoom.ts +++ b/urbanLifelineWeb/packages/workcase_wechat/types/workcase/chatRoom.ts @@ -13,8 +13,9 @@ export interface TbChatRoomDTO extends BaseDTO { roomType?: string status?: string guestId?: string - commentLevel?: number guestName?: string + deviceCode?: string + commentLevel?: number aiSessionId?: string currentAgentId?: string agentCount?: number @@ -164,8 +165,9 @@ export interface ChatRoomVO extends BaseVO { roomType?: string status?: string guestId?: string - commentLevel?: string guestName?: string + commentLevel?: string + deviceCode?: string aiSessionId?: string currentAgentId?: string currentAgentName?: string diff --git a/修改点.md b/修改点.md new file mode 100644 index 00000000..ede63519 --- /dev/null +++ b/修改点.md @@ -0,0 +1,4 @@ +1. createTableWorkcase.sql 修改了tb_chat_room 增加了device_code字段。修改相关dto\vo\xml。 +2. WorkcaseChatController.java 修改创建聊天室的接口,增加了deviceCode字段必传。 +3. 修改workcase/types/workcase/chatRoom.ts里的dto和vo。修改workcase_wechat/types/workcase/chatRoom.ts的dto和vo +4. 修改workcase_wechat/pages/index/index.uvue。新增const deviceCode = ref('');只有这个有值时,才让用户创建聊天室和工单(工单自动填入表单),否则弹窗让用户填写 \ No newline at end of file From a3e09bfa2c17e270478d2637d648d02ba0ef408e Mon Sep 17 00:00:00 2001 From: wangys <3401275564@qq.com> Date: Wed, 31 Dec 2025 10:45:29 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E7=9F=A5=E8=AF=86=E5=BA=93=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E4=B8=8A=E4=BC=A0=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/org/xyzh/ai/mapper/TbKnowledgeMapper.java | 2 +- .../ai/src/main/resources/mapper/TbKnowledgeMapper.xml | 2 +- .../workcase/src/views/admin/knowledge/KnowLedgeView.vue | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/mapper/TbKnowledgeMapper.java b/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/mapper/TbKnowledgeMapper.java index 58a7eca7..561b8412 100644 --- a/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/mapper/TbKnowledgeMapper.java +++ b/urbanLifelineServ/ai/src/main/java/org/xyzh/ai/mapper/TbKnowledgeMapper.java @@ -32,7 +32,7 @@ public interface TbKnowledgeMapper { */ int deleteKnowledge(TbKnowledge knowledge); - int updateKnowledgeFileCount(String knowledgeId, int num); + int updateKnowledgeFileCount(@Param("knowledgeId") String knowledgeId, @Param("num") Integer num); /** * 根据ID查询知识库 diff --git a/urbanLifelineServ/ai/src/main/resources/mapper/TbKnowledgeMapper.xml b/urbanLifelineServ/ai/src/main/resources/mapper/TbKnowledgeMapper.xml index 70a379e0..7c27ab65 100644 --- a/urbanLifelineServ/ai/src/main/resources/mapper/TbKnowledgeMapper.xml +++ b/urbanLifelineServ/ai/src/main/resources/mapper/TbKnowledgeMapper.xml @@ -114,7 +114,7 @@ UPDATE ai.tb_knowledge - SET document_count = document_count + #{fileCount} + SET document_count = document_count + #{num} WHERE knowledge_id = #{knowledgeId} AND deleted = false diff --git a/urbanLifelineWeb/packages/workcase/src/views/admin/knowledge/KnowLedgeView.vue b/urbanLifelineWeb/packages/workcase/src/views/admin/knowledge/KnowLedgeView.vue index 19c2028e..0e42e839 100644 --- a/urbanLifelineWeb/packages/workcase/src/views/admin/knowledge/KnowLedgeView.vue +++ b/urbanLifelineWeb/packages/workcase/src/views/admin/knowledge/KnowLedgeView.vue @@ -306,7 +306,7 @@ const customKnowledgeUpload = async (files: File[]) => { const result = await aiKnowledgeAPI.uploadToKnowledge(files[0], targetKnowledgeId) if (result.success) { ElMessage.success('文件上传成功') - fetchKnowledges() + // fetchKnowledges() fetchDocuments(activeKnowledgeId.value) } else { throw new Error(result.message || '上传失败') @@ -316,7 +316,7 @@ const customKnowledgeUpload = async (files: File[]) => { const result = await aiKnowledgeAPI.batchUploadToKnowledge(files, targetKnowledgeId) if (result.success) { ElMessage.success('文件上传成功') - fetchKnowledges() + // fetchKnowledges() fetchDocuments(activeKnowledgeId.value) } else { throw new Error(result.message || '上传失败') From 6e8fa092a544ca0bf8b29065af718f58f926166c Mon Sep 17 00:00:00 2001 From: wangys <3401275564@qq.com> Date: Wed, 31 Dec 2025 11:13:23 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E8=81=8A=E5=A4=A9=E5=AE=A4=E5=90=8C=E6=AD=A5ai=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E9=A1=BA=E5=BA=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/xyzh/workcase/service/ChatRoomServiceImpl.java | 9 +++++++-- .../src/main/resources/mapper/TbChatMessageMapper.xml | 4 ++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/urbanLifelineServ/workcase/src/main/java/org/xyzh/workcase/service/ChatRoomServiceImpl.java b/urbanLifelineServ/workcase/src/main/java/org/xyzh/workcase/service/ChatRoomServiceImpl.java index adf5095b..03d5d3cd 100644 --- a/urbanLifelineServ/workcase/src/main/java/org/xyzh/workcase/service/ChatRoomServiceImpl.java +++ b/urbanLifelineServ/workcase/src/main/java/org/xyzh/workcase/service/ChatRoomServiceImpl.java @@ -122,7 +122,11 @@ public class ChatRoomServiceImpl implements ChatRoomService { } // 从AI同步对话历史 if(NonUtils.isNotEmpty(chatRoom.getAiSessionId())){ - syncAiChatMessages(chatRoom); + try{ + syncAiChatMessages(chatRoom); + }catch(Exception ex){ + return ResultDomain.failure("创建失败"); + } } return ResultDomain.success("创建成功", chatRoom); @@ -680,7 +684,8 @@ public class ChatRoomServiceImpl implements ChatRoomService { roomMsg.setMessageType("text"); roomMsg.setStatus("sent"); roomMsg.setFiles(aiMsg.getFiles()); - roomMsg.setSendTime(new Date(baseTime + i * 1000L)); + roomMsg.setSendTime(aiMsg.getCreateTime()); + roomMsg.setCreateTime(aiMsg.getCreateTime()); roomMsg.setIsAiMessage(true); roomMsg.setAiMessageId(aiMsg.getMessageId()); roomMsg.setCreator(chatRoom.getGuestId()); diff --git a/urbanLifelineServ/workcase/src/main/resources/mapper/TbChatMessageMapper.xml b/urbanLifelineServ/workcase/src/main/resources/mapper/TbChatMessageMapper.xml index dd2ced13..108c4866 100644 --- a/urbanLifelineServ/workcase/src/main/resources/mapper/TbChatMessageMapper.xml +++ b/urbanLifelineServ/workcase/src/main/resources/mapper/TbChatMessageMapper.xml @@ -62,6 +62,8 @@ , is_ai_message , ai_message_id , status + , send_time + , create_time ) VALUES ( #{optsn}, #{messageId}, #{roomId}, #{senderId}, #{senderType}, #{senderName}, #{content}, #{creator} , #{messageType} @@ -71,6 +73,8 @@ , #{isAiMessage} , #{aiMessageId} , #{status} + , send_time + , #{createTime} ) From 1c207c24393c90cb0a9a7d1ab68077674cb16b1a Mon Sep 17 00:00:00 2001 From: wangys <3401275564@qq.com> Date: Wed, 31 Dec 2025 11:19:50 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E4=BF=AE=E6=AD=A3token=E5=82=A8=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../packages/platform/src/views/public/Login/Login.vue | 3 +-- urbanLifelineWeb/packages/workcase/src/router/index.ts | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/urbanLifelineWeb/packages/platform/src/views/public/Login/Login.vue b/urbanLifelineWeb/packages/platform/src/views/public/Login/Login.vue index 5be1119c..f32aebb2 100644 --- a/urbanLifelineWeb/packages/platform/src/views/public/Login/Login.vue +++ b/urbanLifelineWeb/packages/platform/src/views/public/Login/Login.vue @@ -134,10 +134,9 @@ async function handleLogin() { if (response.success && response.data) { const loginData = response.data - // 8. 保存 Token + // 8. 保存 Token(只用 TokenManager,避免格式不一致) if (loginData.token) { TokenManager.setToken(loginData.token, loginForm.rememberMe) - localStorage.setItem('token', loginData.token) } // 9. 保存 LoginDomain 到 LocalStorage diff --git a/urbanLifelineWeb/packages/workcase/src/router/index.ts b/urbanLifelineWeb/packages/workcase/src/router/index.ts index 7729243a..a68dc7c8 100644 --- a/urbanLifelineWeb/packages/workcase/src/router/index.ts +++ b/urbanLifelineWeb/packages/workcase/src/router/index.ts @@ -64,9 +64,9 @@ router.beforeEach(async (to, from, next) => { const newToken = loginDomain.token // 保存到localStorage(覆盖旧的登录状态) - localStorage.setItem('token', newToken) - localStorage.setItem('loginDomain', JSON.stringify(loginDomain)) + // 只用 TokenManager 存储 token,避免格式不一致 TokenManager.setToken(newToken) + localStorage.setItem('loginDomain', JSON.stringify(loginDomain)) console.log('[Workcase Router] Token验证成功,登录状态已刷新') } else {