From 6d7ed38105752f33f09ab11e687adb99b6c4c3b5 Mon Sep 17 00:00:00 2001 From: XuJiacheng Date: Wed, 17 Dec 2025 11:39:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B4=E7=90=86=EF=BC=9A=E6=B8=85=E9=99=A4?= =?UTF-8?q?=E6=97=A0=E7=94=A8=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- WxCheckApi/.config/dotnet-tools.json | 13 - WxCheckApi/.vscode/launch.json | 35 - WxCheckApi/.vscode/tasks.json | 41 - WxCheckApi/API文档.md | 766 --------------- WxCheckApi/CSRedisCacheHelper.cs | 199 ---- WxCheckApi/Controllers/CheckController.cs | 869 ------------------ WxCheckApi/Controllers/LoginController.cs | 324 ------- .../Controllers/WeatherForecastController.cs | 33 - WxCheckApi/Program.cs | 70 -- .../PublishProfiles/FolderProfile.pubxml | 20 - .../PublishProfiles/FolderProfile.pubxml.user | 9 - .../PublishProfiles/FolderProfile1.pubxml | 20 - .../FolderProfile1.pubxml.user | 9 - WxCheckApi/Properties/launchSettings.json | 31 - WxCheckApi/WeatherForecast.cs | 13 - WxCheckApi/WxCheckApi.csproj | 16 - WxCheckApi/WxCheckApi.http | 6 - WxCheckApi/WxCheckApi.slnx | 4 - WxCheckApi/appsettings.Development.json | 8 - WxCheckApi/appsettings.json | 25 - WxCheckApi/wx_xcx_check.sql | 86 -- 21 files changed, 2597 deletions(-) delete mode 100644 WxCheckApi/.config/dotnet-tools.json delete mode 100644 WxCheckApi/.vscode/launch.json delete mode 100644 WxCheckApi/.vscode/tasks.json delete mode 100644 WxCheckApi/API文档.md delete mode 100644 WxCheckApi/CSRedisCacheHelper.cs delete mode 100644 WxCheckApi/Controllers/CheckController.cs delete mode 100644 WxCheckApi/Controllers/LoginController.cs delete mode 100644 WxCheckApi/Controllers/WeatherForecastController.cs delete mode 100644 WxCheckApi/Program.cs delete mode 100644 WxCheckApi/Properties/PublishProfiles/FolderProfile.pubxml delete mode 100644 WxCheckApi/Properties/PublishProfiles/FolderProfile.pubxml.user delete mode 100644 WxCheckApi/Properties/PublishProfiles/FolderProfile1.pubxml delete mode 100644 WxCheckApi/Properties/PublishProfiles/FolderProfile1.pubxml.user delete mode 100644 WxCheckApi/Properties/launchSettings.json delete mode 100644 WxCheckApi/WeatherForecast.cs delete mode 100644 WxCheckApi/WxCheckApi.csproj delete mode 100644 WxCheckApi/WxCheckApi.http delete mode 100644 WxCheckApi/WxCheckApi.slnx delete mode 100644 WxCheckApi/appsettings.Development.json delete mode 100644 WxCheckApi/appsettings.json delete mode 100644 WxCheckApi/wx_xcx_check.sql diff --git a/WxCheckApi/.config/dotnet-tools.json b/WxCheckApi/.config/dotnet-tools.json deleted file mode 100644 index d4937e0..0000000 --- a/WxCheckApi/.config/dotnet-tools.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "version": 1, - "isRoot": true, - "tools": { - "dotnet-ef": { - "version": "9.0.10", - "commands": [ - "dotnet-ef" - ], - "rollForward": false - } - } -} \ No newline at end of file diff --git a/WxCheckApi/.vscode/launch.json b/WxCheckApi/.vscode/launch.json deleted file mode 100644 index e85d64d..0000000 --- a/WxCheckApi/.vscode/launch.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - // 使用 IntelliSense 找出 C# 调试存在哪些属性 - // 将悬停用于现有属性的说明 - // 有关详细信息,请访问 https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md。 - "name": ".NET Core Launch (web)", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build", - // 如果已更改目标框架,请确保更新程序路径。 - "program": "${workspaceFolder}/bin/Debug/net8.0/WxCheckApi.dll", - "args": [], - "cwd": "${workspaceFolder}", - "stopAtEntry": false, - // 启用在启动 ASP.NET Core 时启动 Web 浏览器。有关详细信息: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser - "serverReadyAction": { - "action": "openExternally", - "pattern": "\\bNow listening on:\\s+(https?://\\S+)" - }, - "env": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "sourceFileMap": { - "/Views": "${workspaceFolder}/Views" - } - }, - { - "name": ".NET Core Attach", - "type": "coreclr", - "request": "attach" - } - ] -} \ No newline at end of file diff --git a/WxCheckApi/.vscode/tasks.json b/WxCheckApi/.vscode/tasks.json deleted file mode 100644 index aeffa9e..0000000 --- a/WxCheckApi/.vscode/tasks.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "build", - "command": "dotnet", - "type": "process", - "args": [ - "build", - "${workspaceFolder}/WxCheckApi.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary;ForceNoAlign" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "publish", - "command": "dotnet", - "type": "process", - "args": [ - "publish", - "${workspaceFolder}/WxCheckApi.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary;ForceNoAlign" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "watch", - "command": "dotnet", - "type": "process", - "args": [ - "watch", - "run", - "--project", - "${workspaceFolder}/WxCheckApi.csproj" - ], - "problemMatcher": "$msCompile" - } - ] -} \ No newline at end of file diff --git a/WxCheckApi/API文档.md b/WxCheckApi/API文档.md deleted file mode 100644 index 89e758f..0000000 --- a/WxCheckApi/API文档.md +++ /dev/null @@ -1,766 +0,0 @@ -# 微信小程序:语音信息打卡 API 接口文档 - -本文档详细描述了WxCheck项目中Login控制器和Check控制器的所有API接口,包括接口功能、请求参数、响应格式以及调用示例。 - -## 基础信息 - -- **API基础路径**:`https://wx-xcx-check.blv-oa.com:4433/api/[controller]/[action]` -- **请求方式**:POST - -## 统一响应格式 - -所有接口返回以下统一格式的JSON响应: - -```json -{ - "success": true/false, - "message": "操作结果描述", - "data": {...}, // 可选,返回的具体数据 - "error": "错误信息" // 可选,错误时返回 -} -``` - -## 1. Login控制器接口 - -### 1.1 用户注册接口 - -#### 接口描述 -用户信息更新功能,根据传入的UserKey更新用户的UserName、WeChatName和PhoneNumber信息。 - -#### 接口路径 -`/api/Login/Register` - -#### 请求参数 - -| 参数名 | 类型 | 必填 | 描述 | -|--------|------|------|------| -| UserName | string | 否 | 用户名(可以为空) | -| UserKey | string | 是 | 用户唯一标识键 | -| WeChatName | string | 否 | 微信名称 | -| PhoneNumber | string | 否 | 电话号码 | -| AvatarUrl | string | 否 | 头像地址 | - -#### 请求示例 - -```json -{ - "UserName": "张三", - "UserKey": "openid_from_wechat", - "WeChatName": "张三的微信", - "PhoneNumber": "13800138000", - "AvatarUrl": "https://example.com/avatar.jpg" -} -``` - -#### 响应示例 - -**成功响应:** -```json -{ - "success": true, - "data": { - "Id": 1, - "UserName": "张三", - "UserKey": "openid_from_wechat", - "WeChatName": "张三的微信", - "PhoneNumber": "13800138000", - "AvatarUrl": "https://example.com/avatar.jpg", - "FirstLoginTime": "2023-10-31T10:00:00", - "IsDisabled": false, - "CreateTime": "2023-10-31T10:00:00", - "UpdateTime": "2023-10-31T15:30:00", - "Token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." - } -} -``` - -**失败响应:** - -```json -{ - "success": false, - "message": "用户不存在" -} -``` - -```json -{ - "success": false, - "message": "更新用户信息失败", - "error": "数据库连接错误" -} -``` - -### 1.2 用户登录接口 - -#### 接口描述 -用户登录功能,将微信小程序code转换为OpenID并验证用户身份。如果用户不存在,则自动创建新用户记录。无论用户是否存在,都返回完整的用户信息和Token。 - -#### 接口路径 -`/api/Login/Login` - -#### 请求参数 - -| 参数名 | 类型 | 必填 | 描述 | -|--------|------|------|------| -| Code | string | 是 | 微信小程序登录凭证code,用于获取OpenID | - -#### 请求示例 - -```json -{ - "Code": "wx_login_code_here" -} -``` - -#### 响应示例 - -**成功响应(已存在用户):** -```json -{ - "success": true, - "data": { - "Id": 1, - "UserName": "张三", - "UserKey": "openid_from_wechat", - "WeChatName": "张三的微信", - "PhoneNumber": "13800138000", - "AvatarUrl": "https://example.com/avatar.jpg", - "FirstLoginTime": "2023-10-31T10:00:00", - "IsDisabled": false, - "CreateTime": "2023-10-31T10:00:00", - "UpdateTime": "2023-10-31T10:00:00", - "Token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." - } -} -``` - -**成功响应(新用户自动注册):** -```json -{ - "success": true, - "data": { - "Id": 2, - "UserName": "", - "UserKey": "new_openid_from_wechat", - "WeChatName": "", - "PhoneNumber": "", - "AvatarUrl": "", - "FirstLoginTime": "2023-10-31T16:00:00", - "IsDisabled": false, - "CreateTime": "2023-10-31T16:00:00", - "UpdateTime": "2023-10-31T16:00:00", - "Token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." - } -} -``` - -**失败响应:** -```json -{ - "success": false, - "message": "用户已被禁用" -} -``` - -```json -{ - "success": false, - "message": "获取微信OpenID失败", - "error": "微信API调用失败" -} -``` - -## 2. Check控制器接口 - -### 2.1 检查地址接口 - -#### 接口描述 -根据会话记录的GUID查询经纬度信息,并转换为详细地址更新到数据库中。 - -#### 接口路径 -`/api/Check/CheckAddress` - -#### 请求参数 - -| 参数名 | 类型 | 必填 | 描述 | -|--------|------|------|------| -| Guid | string | 是 | 会话唯一标识 | - -#### 请求示例 - -```json -{ - "Guid": "会话唯一标识" -} -``` - -#### 响应示例 - -**成功响应:** -```json -{ - "success": true, - "message": "地址更新成功", - "address": "北京市海淀区中关村南大街5号" -} -``` - -**失败响应:** -```json -{ - "success": false, - "message": "记录不存在或已被删除" -} -``` - -```json -{ - "success": false, - "message": "更新失败", - "error": "数据库操作错误" -} -``` - -### 2.2 添加会话记录接口 - -#### 接口描述 -添加新的会话记录到系统中。 - -#### 接口路径 -`/api/Check/AddConversation` - -#### 请求参数 - -| 参数名 | 类型 | 必填 | 描述 | -|--------|------|------|------| -| UserKey | string | 是 | 用户唯一标识键 | -| ConversationContent | string | 是 | 会话内容 | -| SendMethod | string | 是 | 发送方式 | -| UserLocation | string | 否 | 用户定位信息(经纬度格式:"纬度,经度") | -| MessageType | int | 否 | 1:公有消息,2:私有消息 | -| Guid | string | 否 | 会话唯一标识(不提供则系统自动生成) | - -#### 请求示例 - -```json -{ - "UserKey": "user_123456", - "ConversationContent": "这是一条测试消息", - "SendMethod": "文本", - "UserLocation": "39.9087,116.3975", - "MessageType": 1 -} -``` - -#### 响应示例 - -**成功响应:** -```json -{ - "success": true, - "message": "收到!", - "conversationGuid": "会话唯一标识", - "receivedTime": "2023-10-31 10:05:00" -} -``` - -**失败响应:** -```json -{ - "success": false, - "message": "发送失败", - "error": "数据库操作错误" -} -``` - -### 2.3 查询会话记录接口 - -#### 接口描述 -根据用户唯一标识键查询该用户的所有会话记录。 - -#### 接口路径 -`https://wx-xcx-check.blv-oa.com/api/Check/GetConversations` - -#### 请求参数 - -| 参数名 | 类型 | 必填 | 描述 | -|--------|------|------|------| -| UserKey | string | 是 | 用户唯一标识键 | -| MessageType | int | 否 | 0:不判断消息类型(默认),1:只返回公有消息,2:只返回私有消息 | - -#### 请求示例 - -```json -{ - "UserKey": "user_123456", - "MessageType": 0 -} -``` - -#### 响应示例 - -**成功响应:** -```json -{ - "success": true, - "data": [ - { - "Id": 1, - "Guid": "会话唯一标识", - "UserKey": "user_123456", - "ConversationContent": "这是一条测试消息", - "SendMethod": "文本", - "UserLocation": "北京市海淀区", - "Latitude": "39.9087", - "Longitude": "116.3975", - "RecordTime": "2023-10-31T10:05:00", - "RecordTimeUTCStamp": 1698732300000, - "IsDeleted": false, - "CreateTime": "2023-10-31T10:05:00", - "MessageType": 1 - }, - { - "Id": 2, - "Guid": "会话唯一标识", - "UserKey": "user_123456", - "ConversationContent": "这是第二条测试消息", - "SendMethod": "图片", - "UserLocation": "北京市朝阳区", - "Latitude": "39.9180", - "Longitude": "116.4272", - "RecordTime": "2023-10-31T10:06:00", - "RecordTimeUTCStamp": 1698732360000, - "IsDeleted": false, - "CreateTime": "2023-10-31T10:06:00", - "MessageType": 2 - } - ] -} -``` - -**失败响应:** -```json -{ - "success": false, - "message": "查询失败", - "error": "数据库连接错误" -} -``` - -### 2.4 分页查询会话记录接口 - -#### 接口描述 -分页查询用户的会话记录,每页默认10条,按时间戳从**最新到最旧**排序,支持根据消息类型进行过滤。 - -#### 接口路径 -`https://wx-xcx-check.blv-oa.com:4433/api/Check/GetConversationsByPage` - -#### 请求参数 - -| 参数名 | 类型 | 必填 | 描述 | -|--------|------|------|------| -| UserKey | string | 是 | 用户唯一标识键 | -| Page | int | 否 | 页码,默认为1,小于1时自动设为1 | -| PageSize | int | 否 | 每页数量,默认为10,最大100,小于1时自动设为10 | -| MessageType | int | 否 | 0:不判断消息类型(默认),1:只返回公有消息,2:只返回私有消息 | - -#### 请求示例 - -```json -{ - "UserKey": "user_123456", - "Page": 1, - "PageSize": 10, - "MessageType": 0 -} -``` - -#### 响应示例 - -**成功响应:** -```json -{ - "success": true, - "data": { - "conversations": [ - { - "Id": 1, - "Guid": "会话唯一标识", - "UserKey": "user_123456", - "ConversationContent": "这是一条测试消息", - "SendMethod": "文本", - "UserLocation": "北京市海淀区", - "Latitude": "39.9087", - "Longitude": "116.3975", - "RecordTime": "2023-10-31T10:00:00", - "RecordTimeUTCStamp": 1698727200000, - "IsDeleted": false, - "CreateTime": "2023-10-31T10:00:00", - "MessageType": 1 - }, - { - "Id": 2, - "Guid": "会话唯一标识", - "UserKey": "user_123456", - "ConversationContent": "这是一条私有消息", - "SendMethod": "文本", - "UserLocation": "北京市朝阳区", - "Latitude": "39.9180", - "Longitude": "116.4272", - "RecordTime": "2023-10-31T09:55:00", - "RecordTimeUTCStamp": 1698724500000, - "IsDeleted": false, - "CreateTime": "2023-10-31T09:55:00", - "MessageType": 2 - } - ], - "totalCount": 25, - "page": 1, - "pageSize": 10, - "totalPages": 3 - } -} -``` - -**失败响应:** -```json -{ - "success": false, - "message": "查询失败", - "error": "数据库操作错误" -} -``` - -### 2.5 根据GUID查询会话记录接口 - -#### 接口描述 -根据会话唯一标识(GUID)查询会话记录详情,不考虑IsDeleted状态。 - -#### 接口路径 -`/api/Check/GetConversationByGuid` - -#### 请求参数 - -| 参数名 | 类型 | 必填 | 描述 | -|--------|------|------|------| -| Guid | string | 是 | 会话唯一标识 | - -#### 请求示例 - -```json -{ - "Guid": "会话唯一标识" -} -``` - -#### 响应示例 - -**成功响应:** -```json -{ - "success": true, - "message": "查询成功", - "data": { - "Id": 1, - "Guid": "会话唯一标识", - "UserKey": "user_123456", - "ConversationContent": "这是一条测试消息", - "SendMethod": "文本", - "UserLocation": "北京市海淀区", - "Latitude": "39.9087", - "Longitude": "116.3975", - "RecordTime": "2023-10-31T10:05:00", - "RecordTimeUTCStamp": 1698732300000, - "IsDeleted": false, - "CreateTime": "2023-10-31T10:05:00", - "MessageType": 1 - } -} -``` - -**失败响应:** -```json -{ - "success": false, - "message": "未找到该记录" -} -``` - -```json -{ - "success": false, - "message": "查询失败", - "error": "数据库操作错误" -} -``` - -### 2.6 更新会话记录接口 - -#### 接口描述 -更新指定GUID的会话记录,需要验证UserKey的权限。每次更新时,RecordTime会自动更新为当前时间。 - -#### 接口路径 -`/api/Check/UpdateConversation` - -#### 请求参数 - -| 参数名 | 类型 | 必填 | 描述 | -|--------|------|------|------| -| Guid | string | 是 | 会话唯一标识 | -| UserKey | string | 是 | 用户唯一标识键(用于权限验证) | -| ConversationContent | string | 是 | 新的会话内容 | -| SendMethod | string | 是 | 新的发送方式 | -| UserLocation | string | 否 | 新的用户定位信息 | -| MessageType | int | 否 | 1:公有消息,2:私有消息 | - -#### 请求示例 - -```json -{ - "Guid": "会话唯一标识", - "UserKey": "user_123456", - "ConversationContent": "更新后的会话内容", - "SendMethod": "文本", - "UserLocation": "北京市西城区", - "MessageType": 1 -} -``` - -#### 响应示例 - -**成功响应:** -```json -{ - "success": true, - "message": "更新成功", - "receivedTime": "2023-10-31 10:10:00" -} -``` - -**失败响应:** -```json -{ - "success": false, - "message": "记录不存在或无权限修改" -} -``` - -```json -{ - "success": false, - "message": "更新失败", - "error": "数据库操作错误" -} -``` - -### 2.7 删除会话记录接口 - -#### 接口描述 -软删除会话记录(将IsDeleted标记为1),需要验证UserKey的权限。 - -#### 接口路径 -`/api/Check/DeleteConversation` - -#### 请求参数 - -| 参数名 | 类型 | 必填 | 描述 | -|--------|------|------|------| -| Guid | string | 是 | 会话唯一标识 | -| UserKey | string | 是 | 用户唯一标识键(用于权限验证) | - -#### 请求示例 - -```json -{ - "Guid": "会话唯一标识", - "UserKey": "user_123456" -} -``` - -#### 响应示例 - -**成功响应:** -```json -{ - "success": true, - "message": "删除成功" -} -``` - -**失败响应:** -```json -{ - "success": false, - "message": "记录不存在或已被删除" -} -``` - -```json -{ - "success": false, - "message": "删除失败", - "error": "数据库操作错误" -} -``` - -### 2.8 从Redis Stream读取消息接口 - -#### 接口描述 -从Redis Stream读取新的会话消息。 - -#### 接口路径 -`/api/Check/ReadMessageFromRedis` - -#### 请求参数 - -| 参数名 | 类型 | 必填 | 描述 | -|--------|------|------|------| -| GroupName | string | 否 | 消费组名称,默认:xcx_group | -| ConsumerName | string | 否 | 消费者名称,默认:consumer_时间戳 | -| Count | int | 否 | 读取消息数量,默认:1 | - -#### 请求示例 - -```json -{ - "GroupName": "xcx_group", - "ConsumerName": "consumer_1", - "Count": 5 -} -``` - -#### 响应示例 - -**成功响应:** -```json -{ - "success": true, - "message": "成功读取消息", - "data": [ - { - "MessageId": "1635739200000-0", - "Id": "1", - "Guid": "会话唯一标识", - "UserKey": "user_123456", - "ConversationContent": "测试消息", - "SendMethod": "文本", - "UserLocation": "北京市海淀区", - "Latitude": "39.9087", - "Longitude": "116.3975", - "RecordTime": "2023-10-31T10:00:00", - "RecordTimeUTCStamp": "1698727200000", - "IsDeleted": "false", - "CreateTime": "2023-10-31T10:00:00", - "MessageType": "1", - "UserName": "张三", - "WeChatName": "张三的微信", - "PhoneNumber": "13800138000", - "AvatarUrl": "https://example.com/avatar.jpg" - } - ] -} -``` - -**失败响应:** -```json -{ - "success": false, - "message": "读取消息失败", - "error": "Redis操作错误" -} -``` - -## 3. 接口调用说明 - -### 3.1 HTTP客户端调用示例(JavaScript) - -```javascript -// 封装API请求函数 -async function callApi(endpoint, data) { - try { - const response = await fetch(`http://your-api-domain/api${endpoint}`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify(data) - }); - - const result = await response.json(); - return result; - } catch (error) { - console.error('API调用失败:', error); - throw error; - } -} - -// 用户信息更新示例 -async function updateUser() { - const result = await callApi('/Login/Register', { - UserName: '张三', - UserKey: 'openid_from_wechat', - WeChatName: '张三的微信', - PhoneNumber: '13800138000' - }); - - if (result.success) { - console.log('用户信息更新成功'); - } else { - console.log('用户信息更新失败:', result.message); - } -} - -// 用户登录示例 -async function loginUser() { - const result = await callApi('/Login/Login', { - Code: 'wx_login_code_here' - }); - - if (result.success) { - console.log('登录成功,用户信息:', result.data); - // 保存用户信息和Token到本地存储 - localStorage.setItem('userInfo', JSON.stringify(result.data)); - localStorage.setItem('token', result.data.Token); - } else { - console.log('登录失败:', result.message); - } -} - -// 添加会话示例 -async function addConversation() { - const result = await callApi('/Check/AddConversation', { - UserKey: 'user_123456', - ConversationContent: '测试会话内容', - SendMethod: '文本', - UserLocation: '北京', - MessageType: 0 - }); - - if (result.success) { - console.log('会话添加成功'); - } else { - console.log('会话添加失败:', result.message); - } -} -``` - -### 3.2 常见错误处理 - -1. **数据库连接错误**:检查数据库服务是否正常运行,连接字符串是否正确 -2. **权限验证失败**:确保提供的UserKey与操作资源匹配 -3. **记录不存在**:在更新或删除前确认记录ID和UserKey的正确性 -4. **网络错误**:检查API服务是否正常运行,网络连接是否稳定 - -## 4. 安全注意事项 - -1. **参数验证**:所有接口都应在前端进行基本的数据格式验证 -2. **UserKey保护**:UserKey作为用户身份标识,应妥善保护,避免泄露 -3. **错误信息处理**:生产环境中应避免返回详细的错误信息,防止信息泄露 -4. **请求频率限制**:建议在生产环境中对API接口实施请求频率限制,防止滥用 - -## 5. 接口维护信息 - -- **最后更新时间**:2023-11-01 -- **维护人员**:系统管理员 -- **版本号**:v1.2.0 \ No newline at end of file diff --git a/WxCheckApi/CSRedisCacheHelper.cs b/WxCheckApi/CSRedisCacheHelper.cs deleted file mode 100644 index fef4abb..0000000 --- a/WxCheckApi/CSRedisCacheHelper.cs +++ /dev/null @@ -1,199 +0,0 @@ -using CSRedis; -using System; -using System.Collections.Generic; -using System.Configuration; -using System.Linq; -using System.Text; -using static CSRedis.CSRedisClient; - -namespace Common -{ - /// - /// Redis缓存辅助类 - /// - public class CSRedisCacheHelper - { - public static CSRedisClient? redis; - public static CSRedisClient? redis14; - public static CSRedisClient? redis15; - - private const string ip = "127.0.0.1"; - //private const string port = "6379"; - private const string port = "6800"; - static CSRedisCacheHelper() - { - var redisHostStr = string.Format("{0}:{1}", ip, port); - if (!string.IsNullOrEmpty(redisHostStr)) - { - redis = new CSRedisClient(redisHostStr + ",password=,defaultDatabase=0"); - redis15 = new CSRedisClient(redisHostStr + ",password=,defaultDatabase=15"); - var DingYueMsg = ("CellCorelDRAWUser", new Action(async (args) => - { - string body = args.Body; - })); - - CSRedisCacheHelper.redis.Subscribe(DingYueMsg); - } - } - /// - /// 添加缓存 - /// - /// - /// - /// - public static void Set(string key, T value, int ExpireTime) - { - redis?.Set(key, value, ExpireTime * 60); - } - - public static T Get(string key) - { - return redis.Get(key); - } - - public static void Forever(string key, T value) - { - redis.Set(key, value, -1); - } - public static void Del(string key) - { - redis.Del(key); - } - public static void ListPush(string key, T value) - { - redis.LPush(key, value); - } - - /// - /// 判断是否存在 - /// - /// - /// - - public static bool Contains(string key) - { - bool result = redis.Exists(key); - return result; - } - - public static string? XAdd(string key, params (string, string)[] fieldValues) - { - try - { - var result = redis.XAdd(key, fieldValues); - return result; - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($"XAdd error: {ex.Message}"); - return null; - } - } - - public static string? XReadGroup(string key, string group, string consumer, int count = 1, string id = null) - { - try - { - id = id ?? ">"; - var result = redis.XReadGroup(group, consumer, count, 0, (key, id)); - - if (result != null && result.Length > 0) - { - // 处理消息 - var messages = new List>(); - - foreach (var streamResult in result) - { - foreach (var entry in streamResult.data) - { - var message = new Dictionary - { - ["Id"] = entry.id, - ["Values"] = entry.items - }; - - messages.Add(message); - - // 确认消息已处理 - redis.XAck(key, group, entry.id); - } - } - - return System.Text.Json.JsonSerializer.Serialize(messages); - } - - return null; - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($"XReadGroup error: {ex.Message}"); - return null; - } - } - - public static (string key, (string id, string items)[] data)[] XReadGroup(string group, string consumer, long count, long block, params (string key, string id)[] streams) - { - try - { - var result = redis.XReadGroup(group, consumer, count, block, streams); - - if (result != null && result.Length > 0) - { - // 处理消息并确认已处理 - var processedResults = new List<(string key, (string id, string items)[] data)>(); - - foreach (var streamResult in result) - { - var messages = new List<(string id, string items)>(); - - foreach (var entry in streamResult.data) - { - // 确认消息已处理 - redis.XAck(streamResult.key, group, entry.id); - - // entry是一个元组 (string id, string[] items) - // 我们需要将string[] items转换为string items - var itemsArray = entry.items; - var itemsString = string.Join(",", itemsArray); - messages.Add((entry.id, itemsString)); - } - - processedResults.Add((streamResult.key, messages.ToArray())); - } - - return processedResults.ToArray(); - } - - return Array.Empty<(string key, (string id, string items)[] data)>(); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($"XReadGroup error: {ex.Message}"); - return Array.Empty<(string key, (string id, string items)[] data)>(); - } - } - - public static bool XGroupCreate(string key, string group, string id = "0") - { - try - { - redis.XGroupCreate(key, group, id, true); - return true; - } - catch - { - return false; - } - } - - /// - /// 发布消息 - /// - /// - /// - public static void Publish(string Topic, string Payload) - { - CSRedisCacheHelper.redis.PublishNoneMessageId(Topic, Payload); - } - } -} diff --git a/WxCheckApi/Controllers/CheckController.cs b/WxCheckApi/Controllers/CheckController.cs deleted file mode 100644 index f76e5ed..0000000 --- a/WxCheckApi/Controllers/CheckController.cs +++ /dev/null @@ -1,869 +0,0 @@ -using Common; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.IdentityModel.Tokens; -using MySql.Data.MySqlClient; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Net.Http; -using System.Text.Json; -using System.Threading.Tasks; -using System.Web; - -namespace WxCheckApi.Controllers -{ - [Route("api/[controller]/[action]")] - [ApiController] - public class CheckController : ControllerBase - { - private readonly MySqlConnection _connection; - private readonly HttpClient _httpClient; - private readonly IConfiguration _configuration; - - public CheckController(MySqlConnection connection, IHttpClientFactory httpClientFactory, IConfiguration configuration) - { - _connection = connection; - _httpClient = httpClientFactory.CreateClient(); - _configuration = configuration; - } - - // 将经纬度转换为地址信息 - public async Task ConvertCoordinatesToAddress(string longitude,string latitude) - { - try - { - // 使用高德地图API进行逆地理编码 - string apiKey = _configuration["AmapApi:ApiKey"] ?? "4d5cb7818664ada68ae5f68783b8bd4c"; - string url = $"https://restapi.amap.com/v3/geocode/regeo?output=json&location={longitude},{latitude}&key={apiKey}&radius=1000&extensions=all"; - - var response = await _httpClient.GetStringAsync(url); - var jsonDoc = JsonDocument.Parse(response); - var root = jsonDoc.RootElement; - - - - if (root.GetProperty("status").GetString() == "1" && root.TryGetProperty("regeocode", out var regeocodeElement) && regeocodeElement.ValueKind != JsonValueKind.Null) - { - - if (regeocodeElement.TryGetProperty("formatted_address", out var formatted_address)) - { - return formatted_address.ToString(); - } - if (regeocodeElement.TryGetProperty("addressComponent", out var addressComponent)) - { - string province = addressComponent.TryGetProperty("province", out var provinceElement) && provinceElement.ValueKind == JsonValueKind.String ? provinceElement.GetString() : ""; - string city = addressComponent.TryGetProperty("city", out var cityElement) && cityElement.ValueKind == JsonValueKind.String ? cityElement.GetString() : ""; - string district = addressComponent.TryGetProperty("district", out var districtElement) && districtElement.ValueKind == JsonValueKind.String ? districtElement.GetString() : ""; - string township = addressComponent.TryGetProperty("township", out var townshipElement) && townshipElement.ValueKind == JsonValueKind.String ? townshipElement.GetString() : ""; - - // 获取街道和门牌号信息 - string street = ""; - string streetNumber = ""; - double distance = 0; - - // 方法1:从addressComponent获取街道信息 - if (addressComponent.TryGetProperty("streetNumber", out var streetNumberElement) && streetNumberElement.ValueKind == JsonValueKind.Object) - { - street = streetNumberElement.TryGetProperty("street", out var streetElement) && streetElement.ValueKind == JsonValueKind.String ? streetElement.GetString() : ""; - streetNumber = streetNumberElement.TryGetProperty("number", out var numberElement) && numberElement.ValueKind == JsonValueKind.String ? numberElement.GetString() : ""; - - // 获取距离信息 - if (streetNumberElement.TryGetProperty("distance", out var distanceElement) && distanceElement.ValueKind == JsonValueKind.String) - { - double.TryParse(distanceElement.GetString(), out distance); - } - } - - // 方法2:如果方法1没有获取到街道信息,尝试从aoi信息中获取 - if (string.IsNullOrEmpty(street) && regeocodeElement.TryGetProperty("aois", out var aoisElement) && aoisElement.ValueKind == JsonValueKind.Array) - { - var aoisArray = aoisElement.EnumerateArray(); - foreach (var aoi in aoisArray) - { - if (aoi.TryGetProperty("name", out var aoiNameElement) && aoiNameElement.ValueKind == JsonValueKind.String) - { - street = aoiNameElement.GetString(); - break; // 取第一个AOI作为街道信息 - } - } - } - - // 方法3:如果前两种方法都没有获取到街道信息,尝试从pois信息中获取 - if (string.IsNullOrEmpty(street) && regeocodeElement.TryGetProperty("pois", out var poisElement) && poisElement.ValueKind == JsonValueKind.Array) - { - var poisArray = poisElement.EnumerateArray(); - foreach (var poi in poisArray) - { - if (poi.TryGetProperty("name", out var poiNameElement) && poiNameElement.ValueKind == JsonValueKind.String) - { - street = poiNameElement.GetString(); - break; // 取第一个POI作为街道信息 - } - } - } - - // 方法4:如果以上方法都没有获取到街道信息,尝试从formatted_address中解析 - if (string.IsNullOrEmpty(street) && regeocodeElement.TryGetProperty("formatted_address", out var formattedAddressElement) && formattedAddressElement.ValueKind == JsonValueKind.String) - { - string formattedAddress = formattedAddressElement.GetString(); - // 尝试从格式化地址中提取街道信息 - // 格式化地址通常格式为:省 市 区 街道 具体地址 - - // 使用字符串数组作为分隔符 - string[] separators = { " ", "省", "市", "区", "县", "镇", "街道", "路", "巷", "号" }; - var addressParts = formattedAddress.Split(separators, StringSplitOptions.RemoveEmptyEntries); - - // 查找可能包含街道信息的部分 - for (int i = 0; i < addressParts.Length; i++) - { - var part = addressParts[i]; - // 如果部分包含"路"、"街"、"巷"等关键词,可能是街道信息 - if (part.Contains("路") || part.Contains("街") || part.Contains("巷") || part.Contains("道")) - { - street = part; - // 如果下一个部分存在且不是区县名称,可能是门牌号 - if (i + 1 < addressParts.Length && - !addressParts[i + 1].Contains("区") && - !addressParts[i + 1].Contains("县")) - { - streetNumber = addressParts[i + 1]; - } - break; - } - } - } - - // 方法5:如果仍然没有获取到街道信息,尝试从nearestRoad信息中获取 - if (string.IsNullOrEmpty(street) && regeocodeElement.TryGetProperty("streetNumber", out var nearestStreetElement) && - nearestStreetElement.ValueKind == JsonValueKind.Object) - { - if (nearestStreetElement.TryGetProperty("street", out var nearestStreetNameElement) && nearestStreetNameElement.ValueKind == JsonValueKind.String) - { - street = nearestStreetNameElement.GetString(); - } - } - - // 构建详细地址字符串 - string address = ""; - if (!string.IsNullOrEmpty(province)) - { - address += province; - } - if (!string.IsNullOrEmpty(city) && city != province) - { - address += " " + city; - } - if (!string.IsNullOrEmpty(district)) - { - address += " " + district; - } - if (!string.IsNullOrEmpty(township)) - { - address += " " + township; - } - if (!string.IsNullOrEmpty(street)) - { - address += " " + street; - } - if (!string.IsNullOrEmpty(streetNumber)) - { - address += " " + streetNumber; - } - - // 如果有距离信息,添加到地址后面 - if (distance > 0) - { - address += $" {distance:F1}米"; - } - if (string.IsNullOrEmpty(address)) - { - return "未获取到位置信息(高德返回值为空) " + latitude + "," + longitude; - } - return address.Trim(); - } - } - - return latitude + "," + longitude; ; // 如果API调用失败,返回原始值 - } - catch (Exception) - { - return latitude + "," + longitude; ; // 如果发生异常,返回原始值 - } - } - - [HttpPost] - public async Task CheckAddress([FromBody] CheckAddressRequest request) - { - try - { - if (_connection.State != ConnectionState.Open) - { - await _connection.OpenAsync(); - } - - // 从数据库查询经纬度信息 - string latitude = ""; - string longitude = ""; - - using (MySqlCommand cmd = new MySqlCommand("SELECT Latitude, Longitude FROM xcx_conversation WHERE Guid = @Guid AND IsDeleted = 0", _connection)) - { - cmd.Parameters.AddWithValue("@Guid", request.Guid); - - using (var reader = await cmd.ExecuteReaderAsync()) - { - if (await reader.ReadAsync()) - { - latitude = reader.IsDBNull(0) ? "" : reader.GetString(0); - longitude = reader.IsDBNull(1) ? "" : reader.GetString(1); - } - else - { - return NotFound(new { success = false, message = "记录不存在或已被删除" }); - } - } - } - - // 转换经纬度为地址 - var address = await ConvertCoordinatesToAddress(longitude, latitude); - - // 更新数据库中的UserLocation字段 - using (MySqlCommand cmd = new MySqlCommand("UPDATE xcx_conversation SET UserLocation = @UserLocation WHERE Guid = @Guid AND IsDeleted = 0", _connection)) - { - cmd.Parameters.AddWithValue("@Guid", request.Guid); - cmd.Parameters.AddWithValue("@UserLocation", address); - - int rowsAffected = await cmd.ExecuteNonQueryAsync(); - - if (rowsAffected == 0) - { - return NotFound(new { success = false, message = "记录不存在或已被删除" }); - } - } - - return Ok(new { success = true, message = "地址更新成功", address = address }); - } - catch (Exception ex) - { - return StatusCode(500, new { success = false, message = "更新失败", error = ex.Message }); - } - finally - { - if (_connection.State == ConnectionState.Open) - { - await _connection.CloseAsync(); - } - } - } - // 添加会话记录 - [HttpPost] - public async Task AddConversation([FromBody] ConversationRequest request) - { - DateTime nowtime = DateTime.Now; - try - { - if (_connection.State != ConnectionState.Open) - { - await _connection.OpenAsync(); - } - - // 解析经纬度并转换为地址 - string address = ""; - string latitude = ""; - string longitude = ""; - - // 否则尝试从UserLocation字段解析 - if (!string.IsNullOrEmpty(request.UserLocation)) - { - string[] parts = request.UserLocation.Split(','); - if (parts.Length == 2) - { - if (double.TryParse(parts[0], out double lat) && double.TryParse(parts[1], out double lng)) - { - longitude = lng.ToString(); - latitude = lat.ToString(); - address = "";// await ConvertCoordinatesToAddress(latitude, longitude); - } - } - } - - // 生成GUID - string conversationGuid = string.IsNullOrEmpty(request.Guid) ? Guid.NewGuid().ToString("N") : request.Guid; - long conversationId = 0; - using (MySqlCommand cmd = new MySqlCommand("INSERT INTO xcx_conversation (UserKey, ConversationContent, SendMethod, UserLocation, Latitude, Longitude, RecordTime, RecordTimeUTCStamp, IsDeleted, CreateTime, MessageType, Guid, SpeakingTime) VALUES (@UserKey, @ConversationContent, @SendMethod, @UserLocation, @Latitude, @Longitude, @RecordTime, @RecordTimeUTCStamp, @IsDeleted, @CreateTime, @MessageType, @Guid, @SpeakingTime); SELECT LAST_INSERT_ID();", _connection)) - { - cmd.Parameters.AddWithValue("@UserKey", request.UserKey); - cmd.Parameters.AddWithValue("@MessageType", request.MessageType); - cmd.Parameters.AddWithValue("@ConversationContent", request.ConversationContent); - cmd.Parameters.AddWithValue("@SendMethod", request.SendMethod); - cmd.Parameters.AddWithValue("@UserLocation", address); - cmd.Parameters.AddWithValue("@Latitude", latitude); - cmd.Parameters.AddWithValue("@Longitude", longitude); - cmd.Parameters.AddWithValue("@RecordTime", nowtime); - cmd.Parameters.AddWithValue("@CreateTime", nowtime); - cmd.Parameters.AddWithValue("@RecordTimeUTCStamp", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()); - cmd.Parameters.AddWithValue("@IsDeleted", 0); - cmd.Parameters.AddWithValue("@Guid", conversationGuid); - cmd.Parameters.AddWithValue("@SpeakingTime", request.SpeakingTime); - - object result = await cmd.ExecuteScalarAsync(); - conversationId = Convert.ToInt64(result); - } - - // 查询刚插入的记录,并左连接用户表 - if (conversationId > 0) - { - string query = @"SELECT convs.Id, convs.Guid, convs.UserKey, convs.ConversationContent, convs.SendMethod, - convs.UserLocation, convs.Latitude, convs.Longitude, convs.RecordTime, - convs.RecordTimeUTCStamp, convs.IsDeleted, convs.CreateTime, convs.MessageType, convs.SpeakingTime, - users.UserName, users.WeChatName, users.PhoneNumber, users.AvatarUrl - FROM xcx_conversation AS convs - LEFT JOIN xcx_users AS users ON convs.UserKey = users.UserKey - WHERE convs.Guid = @Guid"; - - using (MySqlCommand cmd = new MySqlCommand(query, _connection)) - { - cmd.Parameters.AddWithValue("@Guid", conversationGuid); - using (var reader = await cmd.ExecuteReaderAsync()) - { - if (await reader.ReadAsync()) - { - // 构建要发送到Redis的数据 - var messageData = new Dictionary - { - ["Id"] = reader.GetInt64(0).ToString(), - ["Guid"] = reader.IsDBNull(1) ? "" : reader.GetString(1), - ["UserKey"] = reader.GetString(2), - ["ConversationContent"] = reader.GetString(3), - ["SendMethod"] = reader.GetString(4), - ["UserLocation"] = reader.IsDBNull(5) ? "" : reader.GetString(5), - ["Latitude"] = reader.IsDBNull(6) ? "" : reader.GetString(6), - ["Longitude"] = reader.IsDBNull(7) ? "" : reader.GetString(7), - ["RecordTime"] = reader.GetDateTime(8).ToString("yyyy-MM-dd HH:mm:ss"), - ["RecordTimeUTCStamp"] = reader.GetInt64(9).ToString(), - ["IsDeleted"] = reader.GetBoolean(10).ToString(), - ["CreateTime"] = reader.GetDateTime(11).ToString("yyyy-MM-dd HH:mm:ss"), - ["MessageType"] = reader.GetInt32(12).ToString(), - ["SpeakingTime"] = reader.IsDBNull(13) ? "" : reader.GetInt32(13).ToString(), - ["UserName"] = reader.IsDBNull(14) ? "" : reader.GetString(14), - ["WeChatName"] = reader.IsDBNull(15) ? "" : reader.GetString(15), - ["PhoneNumber"] = reader.IsDBNull(16) ? "" : reader.GetString(16), - ["AvatarUrl"] = reader.IsDBNull(17) ? "" : reader.GetString(17) - }; - - // 发送到Redis Stream - try - { - // 确保Stream和Group存在 - CSRedisCacheHelper.XGroupCreate("xcx_msg", "xcx_group", "0"); - - // 将Dictionary转换为params (string, string)[]格式 - var fieldValues = messageData.SelectMany(kvp => new (string, string)[] { (kvp.Key, kvp.Value) }).ToArray(); - - // 添加消息到Stream - string messageId = CSRedisCacheHelper.XAdd("xcx_msg", fieldValues); - - // 记录日志(可选) - System.Diagnostics.Debug.WriteLine($"消息已发送到Redis Stream: {messageId}"); - } - catch (Exception ex) - { - // 记录错误但不影响主流程 - System.Diagnostics.Debug.WriteLine($"发送到Redis Stream失败: {ex.Message}"); - } - } - } - } - } - - return Ok(new { success = true, message = "收到!", conversationGuid, receivedTime = nowtime.ToString("yyyy-MM-dd HH:mm:ss") }); - } - catch (Exception ex) - { - return StatusCode(500, new { success = false, message = "发送失败", error = ex.Message }); - } - finally - { - if (_connection.State == ConnectionState.Open) - { - await _connection.CloseAsync(); - } - } - } - - // 根据UserKey查询会话记录 - [HttpPost] - public async Task GetConversations([FromBody] UserKeyRequest request) - { - try - { - if (_connection.State != ConnectionState.Open) - { - await _connection.OpenAsync(); - } - - List conversations = new List(); - - // 构建查询SQL,根据MessageType参数决定是否添加过滤条件 - string query = "SELECT Id, Guid, UserKey, ConversationContent, SendMethod, UserLocation, Latitude, Longitude, RecordTime, RecordTimeUTCStamp, IsDeleted, CreateTime, MessageType, SpeakingTime FROM xcx_conversation WHERE UserKey = @UserKey AND IsDeleted = 0"; - if (request.MessageType == 1) - { - query += " AND MessageType = @MessageType"; - } - query += " ORDER BY RecordTimeUTCStamp DESC"; - - using (MySqlCommand cmd = new MySqlCommand(query, _connection)) - { - cmd.Parameters.AddWithValue("@UserKey", request.UserKey); - - using (var reader = await cmd.ExecuteReaderAsync()) - { - while (await reader.ReadAsync()) - { - conversations.Add(new ConversationResponse - { - Id = reader.GetInt64(0), - Guid = reader.IsDBNull(1) ? "" : reader.GetString(1), - UserKey = reader.GetString(2), - ConversationContent = reader.GetString(3), - SendMethod = reader.GetString(4), - UserLocation = reader.IsDBNull(5) ? "" : reader.GetString(5), - Latitude = reader.IsDBNull(6) ? "" : reader.GetString(6), - Longitude = reader.IsDBNull(7) ? "" : reader.GetString(7), - RecordTime = reader.GetDateTime(8), - RecordTimeUTCStamp = reader.GetInt64(9), - IsDeleted = reader.GetBoolean(10), - CreateTime = reader.GetDateTime(11), - MessageType = reader.GetInt32(12), - SpeakingTime = reader.IsDBNull(13) ? null : reader.GetInt32(13) - }); - } - } - } - - return Ok(new { success = true, data = conversations.OrderBy(z => z.RecordTimeUTCStamp) }); - } - catch (Exception ex) - { - return StatusCode(500, new { success = false, message = "查询失败", error = ex.Message }); - } - finally - { - if (_connection.State == ConnectionState.Open) - { - await _connection.CloseAsync(); - } - } - } - - // 更新会话记录 - [HttpPost] - public async Task UpdateConversation([FromBody] UpdateConversationRequest request) - { - try - { - if (_connection.State != ConnectionState.Open) - { - await _connection.OpenAsync(); - } - - DateTime nowtime = DateTime.Now; - using (MySqlCommand cmd = new MySqlCommand("UPDATE xcx_conversation SET ConversationContent = @ConversationContent, SendMethod = @SendMethod, UserLocation = @UserLocation, MessageType = @MessageType, RecordTime = @RecordTime WHERE Guid = @Guid AND UserKey = @UserKey", _connection)) - { - cmd.Parameters.AddWithValue("@Guid", request.Guid); - cmd.Parameters.AddWithValue("@UserKey", request.UserKey); - cmd.Parameters.AddWithValue("@ConversationContent", request.ConversationContent); - cmd.Parameters.AddWithValue("@SendMethod", request.SendMethod); - cmd.Parameters.AddWithValue("@UserLocation", request.UserLocation ?? ""); - cmd.Parameters.AddWithValue("@MessageType", request.MessageType); - cmd.Parameters.AddWithValue("@RecordTime", nowtime); - - int rowsAffected = await cmd.ExecuteNonQueryAsync(); - - if (rowsAffected == 0) - { - return NotFound(new { success = false, message = "记录不存在或无权限修改" }); - } - } - - return Ok(new { success = true, message = "更新成功" , receivedTime = nowtime.ToString("yyyy-MM-dd HH:mm:ss") }); - } - catch (Exception ex) - { - return StatusCode(500, new { success = false, message = "更新失败", error = ex.Message }); - } - finally - { - if (_connection.State == ConnectionState.Open) - { - await _connection.CloseAsync(); - } - } - } - - // 软删除会话记录 - [HttpPost] - public async Task DeleteConversation([FromBody] DeleteConversationRequest request) - { - try - { - if (_connection.State != ConnectionState.Open) - { - await _connection.OpenAsync(); - } - - using (MySqlCommand cmd = new MySqlCommand("UPDATE xcx_conversation SET IsDeleted = 1 WHERE Guid = @Guid AND UserKey = @UserKey AND IsDeleted = 0", _connection)) - { - cmd.Parameters.AddWithValue("@Guid", request.Guid); - cmd.Parameters.AddWithValue("@UserKey", request.UserKey); - - int rowsAffected = await cmd.ExecuteNonQueryAsync(); - - if (rowsAffected == 0) - { - return NotFound(new { success = false, message = "记录不存在或已被删除" }); - } - } - - return Ok(new { success = true, message = "删除成功" }); - } - catch (Exception ex) - { - return StatusCode(500, new { success = false, message = "删除失败", error = ex.Message }); - } - finally - { - if (_connection.State == ConnectionState.Open) - { - await _connection.CloseAsync(); - } - } - } - // 根据GUID查询会话记录(不考虑IsDeleted状态) - [HttpPost] - public async Task GetConversationByGuid([FromBody] GetConversationByGuidRequest request) - { - try - { - if (_connection.State != ConnectionState.Open) - { - await _connection.OpenAsync(); - } - - // 查询记录,不考虑IsDeleted状态 - string query = @"SELECT Id, Guid, UserKey, ConversationContent, SendMethod, UserLocation, - Latitude, Longitude, RecordTime, RecordTimeUTCStamp, IsDeleted, CreateTime, MessageType, SpeakingTime - FROM xcx_conversation - WHERE Guid = @Guid"; - - using (MySqlCommand cmd = new MySqlCommand(query, _connection)) - { - cmd.Parameters.AddWithValue("@Guid", request.Guid); - - using (var reader = await cmd.ExecuteReaderAsync()) - { - if (await reader.ReadAsync()) - { - var conversation = new ConversationResponse - { - Id = reader.GetInt64(0), - Guid = reader.IsDBNull(1) ? "" : reader.GetString(1), - UserKey = reader.GetString(2), - ConversationContent = reader.GetString(3), - SendMethod = reader.GetString(4), - UserLocation = reader.IsDBNull(5) ? "" : reader.GetString(5), - Latitude = reader.IsDBNull(6) ? "" : reader.GetString(6), - Longitude = reader.IsDBNull(7) ? "" : reader.GetString(7), - RecordTime = reader.GetDateTime(8), - RecordTimeUTCStamp = reader.GetInt64(9), - IsDeleted = reader.GetBoolean(10), - CreateTime = reader.GetDateTime(11), - MessageType = reader.GetInt32(12), - SpeakingTime = reader.IsDBNull(13) ? null : reader.GetInt32(13) - }; - - return Ok(new { success = true, message = "查询成功", data = conversation }); - } - else - { - return NotFound(new { success = false, message = "未找到该记录" }); - } - } - } - } - catch (Exception ex) - { - return StatusCode(500, new { success = false, message = "查询失败", error = ex.Message }); - } - finally - { - if (_connection.State == ConnectionState.Open) - { - await _connection.CloseAsync(); - } - } - } - - // 分页查询会话记录 - [HttpPost] - public async Task GetConversationsByPage([FromBody] PaginationRequest request) - { - try - { - if (_connection.State != ConnectionState.Open) - { - await _connection.OpenAsync(); - } - - // 验证并设置默认值 - if (request.Page < 1) request.Page = 1; - if (request.PageSize < 1 || request.PageSize > 100) request.PageSize = 10; - - int offset = (request.Page - 1) * request.PageSize; - - List conversations = new List(); - - // 构建分页查询SQL,根据MessageType参数决定是否添加过滤条件 - string query = @"SELECT Id, Guid, UserKey, ConversationContent, SendMethod, UserLocation, Latitude, Longitude, RecordTime, RecordTimeUTCStamp, IsDeleted, CreateTime, MessageType, SpeakingTime - FROM xcx_conversation - WHERE UserKey = @UserKey AND IsDeleted = 0"; - if (request.MessageType == 1) - { - query += " AND MessageType = @MessageType"; - } - query += " ORDER BY RecordTimeUTCStamp DESC LIMIT @Offset, @Limit"; - - using (MySqlCommand cmd = new MySqlCommand(query, _connection)) - { - cmd.Parameters.AddWithValue("@UserKey", request.UserKey); - if (request.MessageType == 1) - { - cmd.Parameters.AddWithValue("@MessageType", request.MessageType); - } - cmd.Parameters.AddWithValue("@Offset", offset); - cmd.Parameters.AddWithValue("@Limit", request.PageSize); - - using (var reader = await cmd.ExecuteReaderAsync()) - { - while (await reader.ReadAsync()) - { - conversations.Add(new ConversationResponse - { - Id = reader.GetInt64(0), - Guid = reader.IsDBNull(1) ? "" : reader.GetString(1), - UserKey = reader.GetString(2), - ConversationContent = reader.GetString(3), - SendMethod = reader.GetString(4), - UserLocation = reader.IsDBNull(5) ? "" : reader.GetString(5), - Latitude = reader.IsDBNull(6) ? "" : reader.GetString(6), - Longitude = reader.IsDBNull(7) ? "" : reader.GetString(7), - RecordTime = reader.GetDateTime(8), - RecordTimeUTCStamp = reader.GetInt64(9), - IsDeleted = reader.GetBoolean(10), - CreateTime = reader.GetDateTime(11), - MessageType = reader.GetInt32(12), - SpeakingTime = reader.IsDBNull(13) ? null : reader.GetInt32(13) - }); - } - } - } - - // 查询总数,根据MessageType参数决定是否添加过滤条件 - int totalCount = 0; - string countQuery = "SELECT COUNT(*) FROM xcx_conversation WHERE UserKey = @UserKey AND IsDeleted = 0"; - if (request.MessageType == 1) - { - countQuery += " AND MessageType = @MessageType"; - } - - using (MySqlCommand countCmd = new MySqlCommand(countQuery, _connection)) - { - countCmd.Parameters.AddWithValue("@UserKey", request.UserKey); - if (request.MessageType == 1) - { - countCmd.Parameters.AddWithValue("@MessageType", request.MessageType); - } - totalCount = Convert.ToInt32(await countCmd.ExecuteScalarAsync()); - } - - int totalPages = (int)Math.Ceiling((double)totalCount / request.PageSize); - - return Ok(new { - success = true, - data = new { - conversations = conversations.OrderBy(z => z.RecordTimeUTCStamp), - totalCount = totalCount, - page = request.Page, - pageSize = request.PageSize, - totalPages = totalPages - } - }); - } - catch (Exception ex) - { - return StatusCode(500, new { success = false, message = "查询失败", error = ex.Message }); - } - finally - { - if (_connection.State == ConnectionState.Open) - { - await _connection.CloseAsync(); - } - } - } - - // 从Redis Stream读取消息 - [HttpPost] - public async Task ReadMessageFromRedis([FromBody] RedisMessageRequest request) - { - try - { - // 确保Stream和Group存在 - CSRedisCacheHelper.XGroupCreate("xcx_msg", "xcx_group", "0"); - - // 从Redis Stream读取消息 - string groupName = request.GroupName ?? "xcx_group"; - string consumerName = request.ConsumerName ?? "consumer_" + DateTime.Now.Ticks; - - string messages = CSRedisCacheHelper.XReadGroup("xcx_msg", groupName, consumerName, request.Count ?? 1); - - if (string.IsNullOrEmpty(messages)) - { - return Ok(new { success = true, message = "没有新消息", data = new List() }); - } - - // 解析消息 - var messageList = new List(); - - try - { - var messageEntries = System.Text.Json.JsonSerializer.Deserialize>>(messages); - - if (messageEntries != null) - { - foreach (var entry in messageEntries) - { - if (entry.TryGetValue("Id", out var id) && - entry.TryGetValue("Values", out var values)) - { - var messageData = new Dictionary(); - - // 如果Values是JsonElement,需要进一步解析 - if (values is JsonElement valuesElement && valuesElement.ValueKind == JsonValueKind.Object) - { - foreach (var property in valuesElement.EnumerateObject()) - { - messageData[property.Name] = property.Value.GetString() ?? ""; - } - } - else if (values is Dictionary valuesDict) - { - messageData = valuesDict; - } - - messageData["MessageId"] = id.ToString(); - messageList.Add(messageData); - } - } - } - } - catch (Exception parseEx) - { - // 如果解析失败,尝试直接返回原始消息 - System.Diagnostics.Debug.WriteLine($"解析消息失败: {parseEx.Message}"); - messageList.Add(new { RawMessage = messages }); - } - - return Ok(new { success = true, message = "成功读取消息", data = messageList }); - } - catch (Exception ex) - { - return StatusCode(500, new { success = false, message = "读取消息失败", error = ex.Message }); - } - } - } - - // 请求和响应模型 - public class ConversationRequest - { - public string UserKey { get; set; } - public string ConversationContent { get; set; } - public string SendMethod { get; set; } - public string UserLocation { get; set; } - public double Latitude { get; set; } - public double Longitude { get; set; } - public int MessageType { get; set; } = 1; // 1:公有,2:私有 - public string? Guid { get; set; } // 会话唯一标识 - public int? SpeakingTime { get; set; } // 对话时长 - } - - public class UserKeyRequest - { - public string UserKey { get; set; } - public int MessageType { get; set; } = 0; // 0:不判断消息类型,1:公有,2:私有 - } - - public class PaginationRequest - { - public string UserKey { get; set; } - public int Page { get; set; } = 1; // 默认第一页 - public int PageSize { get; set; } = 10; // 默认每页10条 - public int MessageType { get; set; } = 0; // 0:不判断消息类型,1:公有,2:私有 - } - - public class UpdateConversationRequest - { - public long? Id { get; set; } - public string Guid { get; set; } // 会话唯一标识 - public string UserKey { get; set; } - public string ConversationContent { get; set; } - public string SendMethod { get; set; } - public string UserLocation { get; set; } - public int MessageType { get; set; } = 0; - public int? SpeakingTime { get; set; } - } - - public class DeleteConversationRequest - { - public long? Id { get; set; } - public string Guid { get; set; } // 会话唯一标识 - public string UserKey { get; set; } - } - public class CheckAddressRequest - { - public long? Id { get; set; } - public string Guid { get; set; } // 会话唯一标识 - } - public class GetConversationByGuidRequest - { - public long? Id { get; set; } - public string Guid { get; set; } // 会话唯一标识 - } - - public class ConversationResponse - { - public long Id { get; set; } - public string Guid { get; set; } // 会话唯一标识 - public string UserKey { get; set; } - public string ConversationContent { get; set; } - public string SendMethod { get; set; } - public string UserLocation { get; set; } - public string Latitude { get; set; } - public string Longitude { get; set; } - public DateTime RecordTime { get; set; } - public long RecordTimeUTCStamp { get; set; } - public bool IsDeleted { get; set; } - public DateTime CreateTime { get; set; } - public int MessageType { get; set; } // 1:公有消息,2:私有消息 - public int? SpeakingTime { get; set; } - } - - public class RedisMessageRequest - { - public string GroupName { get; set; } = "xcx_group"; - public string ConsumerName { get; set; } - public int? Count { get; set; } = 1; - } -} diff --git a/WxCheckApi/Controllers/LoginController.cs b/WxCheckApi/Controllers/LoginController.cs deleted file mode 100644 index 0d83282..0000000 --- a/WxCheckApi/Controllers/LoginController.cs +++ /dev/null @@ -1,324 +0,0 @@ -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.IdentityModel.Tokens; -using MySql.Data.MySqlClient; -using System; -using System.Data; -using System.IdentityModel.Tokens.Jwt; -using System.Security.Claims; -using System.Text; -using System.Threading.Tasks; -using System.Net.Http; -using System.Text.Json; - -namespace WxCheckMvc.Controllers -{ - [Route("api/[controller]/[action]")] - [ApiController] - public class LoginController : ControllerBase - { - private readonly MySqlConnection _connection; - private readonly IHttpClientFactory _httpClientFactory; - public IConfiguration? configuration { get; set; } - - public LoginController(MySqlConnection connection, IHttpClientFactory httpClientFactory, IConfiguration? configuration) - { - _connection = connection; - _httpClientFactory = httpClientFactory; - this.configuration = configuration; - } - - // 获取微信小程序OpenID - private async Task GetWxOpenIdAsync(string code) - { - try - { - var appId = configuration["WeChat:AppId"]; - var appSecret = configuration["WeChat:AppSecret"]; - - if (string.IsNullOrEmpty(appId) || string.IsNullOrEmpty(appSecret)) - { - throw new Exception("微信小程序配置缺失"); - } - - var httpClient = _httpClientFactory.CreateClient(); - var url = $"https://api.weixin.qq.com/sns/jscode2session?appid={appId}&secret={appSecret}&js_code={code}&grant_type=authorization_code"; - - var response = await httpClient.GetAsync(url); - response.EnsureSuccessStatusCode(); - - var responseContent = await response.Content.ReadAsStringAsync(); - var jsonDocument = JsonDocument.Parse(responseContent); - - if (jsonDocument.RootElement.TryGetProperty("openid", out var openidElement)) - { - return openidElement.GetString(); - } - else - { - // 如果有错误信息,抛出异常 - if (jsonDocument.RootElement.TryGetProperty("errcode", out var errcodeElement) && - jsonDocument.RootElement.TryGetProperty("errmsg", out var errmsgElement)) - { - throw new Exception($"获取OpenID失败: {errcodeElement.GetInt32()} - {errmsgElement.GetString()}"); - } - throw new Exception("获取OpenID失败: 响应中未包含openid"); - } - } - catch (Exception ex) - { - throw new Exception($"获取微信OpenID时发生错误: {ex.Message}"); - } - } - - - private string GetToken(string entity) - { - string TokenString; - var claims = new Claim[] - { - new Claim(ClaimTypes.NameIdentifier, Guid.NewGuid().ToString()), - new Claim(ClaimTypes.Name, entity) - }; - - var secretByte = Encoding.UTF8.GetBytes(configuration["JwT:SecretKey"]); - var signingKey = new SymmetricSecurityKey(secretByte); - var a = SecurityAlgorithms.HmacSha256; - - var signingCredentials = new SigningCredentials(signingKey, a); - - var token = new JwtSecurityToken( - issuer: configuration["JwT:Issuer"], - audience: configuration["JwT:Audience"],//接收 - claims: claims,//存放的用户信息 - notBefore: DateTime.UtcNow,//发布时间 - expires: DateTime.UtcNow.AddMonths(12), - signingCredentials: signingCredentials - //有效期设置为1天signingCredentials //数字名 - ); - TokenString = new JwtSecurityTokenHandler().WriteToken(token); - return TokenString; - } - - // 用户注册接口 - [HttpPost] - public async Task Register([FromBody] RegisterRequest request) - { - try - { - if (_connection.State != ConnectionState.Open) - { - await _connection.OpenAsync(); - } - - // 检查用户是否存在 - UserResponse user = null; - using (MySqlCommand checkCmd = new MySqlCommand("SELECT Id, UserName, UserKey, WeChatName, PhoneNumber, AvatarUrl, FirstLoginTime, IsDisabled, CreateTime, UpdateTime FROM xcx_users WHERE UserKey = @UserKey", _connection)) - { - checkCmd.Parameters.AddWithValue("@UserKey", request.UserKey); - using (var reader = await checkCmd.ExecuteReaderAsync()) - { - if (await reader.ReadAsync()) - { - user = new UserResponse - { - Id = reader.GetInt64(0), - UserName = reader.IsDBNull(1) ? "" : reader.GetString(1), - UserKey = reader.GetString(2), - WeChatName = reader.IsDBNull(3) ? "" : reader.GetString(3), - PhoneNumber = reader.IsDBNull(4) ? "" : reader.GetString(4), - AvatarUrl = reader.IsDBNull(5) ? "" : reader.GetString(5), - FirstLoginTime = reader.GetDateTime(6), - IsDisabled = reader.GetBoolean(7), - CreateTime = reader.GetDateTime(8), - UpdateTime = reader.GetDateTime(9) - }; - } - } - } - - if (user == null) - { - return NotFound(new { success = false, message = "用户不存在" }); - } - - // 更新用户信息 - using (MySqlCommand cmd = new MySqlCommand("UPDATE xcx_users SET UserName = @UserName, WeChatName = @WeChatName, PhoneNumber = @PhoneNumber, AvatarUrl = @AvatarUrl, UpdateTime = NOW() WHERE UserKey = @UserKey", _connection)) - { - cmd.Parameters.AddWithValue("@UserName", request.UserName ?? (object)DBNull.Value); - cmd.Parameters.AddWithValue("@WeChatName", request.WeChatName ?? ""); - cmd.Parameters.AddWithValue("@PhoneNumber", request.PhoneNumber ?? ""); - cmd.Parameters.AddWithValue("@AvatarUrl", request.AvatarUrl ?? (object)DBNull.Value); - cmd.Parameters.AddWithValue("@UserKey", request.UserKey); - - await cmd.ExecuteNonQueryAsync(); - } - - // 获取更新后的用户信息 - UserResponse updatedUser = null; - using (MySqlCommand cmd = new MySqlCommand("SELECT Id, UserName, UserKey, WeChatName, PhoneNumber, AvatarUrl, FirstLoginTime, IsDisabled, CreateTime, UpdateTime FROM xcx_users WHERE UserKey = @UserKey", _connection)) - { - cmd.Parameters.AddWithValue("@UserKey", request.UserKey); - using (var reader = await cmd.ExecuteReaderAsync()) - { - if (await reader.ReadAsync()) - { - updatedUser = new UserResponse - { - Id = reader.GetInt64(0), - UserName = reader.IsDBNull(1) ? "" : reader.GetString(1), - UserKey = reader.GetString(2), - WeChatName = reader.IsDBNull(3) ? "" : reader.GetString(3), - PhoneNumber = reader.IsDBNull(4) ? "" : reader.GetString(4), - AvatarUrl = reader.IsDBNull(5) ? "" : reader.GetString(5), - FirstLoginTime = reader.GetDateTime(6), - IsDisabled = reader.GetBoolean(7), - CreateTime = reader.GetDateTime(8), - UpdateTime = reader.GetDateTime(9), - Token = GetToken(request.UserKey) - }; - } - } - } - - return Ok(new { success = true, data = updatedUser }); - } - catch (Exception ex) - { - return StatusCode(500, new { success = false, message = "更新用户信息失败", error = ex.Message }); - } - finally - { - if (_connection.State == ConnectionState.Open) - { - await _connection.CloseAsync(); - } - } - } - - // 用户登录接口 - [HttpPost] - public async Task Login([FromBody] LoginRequest request) - { - try - { - string openId; - try - { - openId = await GetWxOpenIdAsync(request.Code); - } - catch (Exception ex) - { - return BadRequest(new { success = false, message = "获取微信OpenID失败", error = ex.Message }); - } - - if (_connection.State != ConnectionState.Open) - { - await _connection.OpenAsync(); - } - - UserResponse user = null; - - // 检查用户是否存在 - using (MySqlCommand checkCmd = new MySqlCommand("SELECT COUNT(1) FROM xcx_users WHERE UserKey = @UserKey", _connection)) - { - checkCmd.Parameters.AddWithValue("@UserKey", openId); - int count = Convert.ToInt32(await checkCmd.ExecuteScalarAsync()); - - // 如果用户不存在,则注册新用户 - if (count == 0) - { - using (MySqlCommand insertCmd = new MySqlCommand("INSERT INTO xcx_users (UserKey, FirstLoginTime, IsDisabled, CreateTime, UpdateTime) VALUES (@UserKey, @FirstLoginTime, @IsDisabled, NOW(), NOW())", _connection)) - { - insertCmd.Parameters.AddWithValue("@UserKey", openId); - insertCmd.Parameters.AddWithValue("@FirstLoginTime", DateTime.Now); - insertCmd.Parameters.AddWithValue("@IsDisabled", 0); // 默认启用 - - await insertCmd.ExecuteNonQueryAsync(); - } - } - } - - // 获取用户信息 - using (MySqlCommand cmd = new MySqlCommand("SELECT Id, UserName, UserKey, WeChatName, PhoneNumber, AvatarUrl, FirstLoginTime, IsDisabled, CreateTime, UpdateTime FROM xcx_users WHERE UserKey = @UserKey", _connection)) - { - cmd.Parameters.AddWithValue("@UserKey", openId); - - using (var reader = await cmd.ExecuteReaderAsync()) - { - if (await reader.ReadAsync()) - { - user = new UserResponse - { - Id = reader.GetInt64(0), - UserName = reader.IsDBNull(1) ? "" : reader.GetString(1), - UserKey = reader.GetString(2), - WeChatName = reader.IsDBNull(3) ? "" : reader.GetString(3), - PhoneNumber = reader.IsDBNull(4) ? "" : reader.GetString(4), - AvatarUrl = reader.IsDBNull(5) ? "" : reader.GetString(5), - FirstLoginTime = reader.GetDateTime(6), - IsDisabled = reader.GetBoolean(7), - CreateTime = reader.GetDateTime(8), - UpdateTime = reader.GetDateTime(9), - Token = GetToken(openId) - }; - } - } - } - - if (user == null) - { - return NotFound(new { success = false, message = "用户不存在" }); - } - - if (user.IsDisabled) - { - return Ok(new { success = false, message = "用户已被禁用" }); - } - - return Ok(new { success = true, data = user }); - } - catch (Exception ex) - { - return StatusCode(500, new { success = false, message = "登录失败", error = ex.Message }); - } - finally - { - if (_connection.State == ConnectionState.Open) - { - await _connection.CloseAsync(); - } - } - } - } - - // 请求和响应模型 - public class RegisterRequest - { - public string UserName { get; set; } - public string UserKey { get; set; } // 改为直接传入UserKey - public string WeChatName { get; set; } - public string PhoneNumber { get; set; } - public string AvatarUrl { get; set; } - } - - public class LoginRequest - { - public string Code { get; set; } - } - - public class UserResponse - { - public long Id { get; set; } - public string UserName { get; set; } - public string UserKey { get; set; } - public string WeChatName { get; set; } - public string PhoneNumber { get; set; } - public string AvatarUrl { get; set; } - public DateTime FirstLoginTime { get; set; } - public bool IsDisabled { get; set; } - public DateTime CreateTime { get; set; } - public DateTime UpdateTime { get; set; } - public string Token { get; set; } - } -} diff --git a/WxCheckApi/Controllers/WeatherForecastController.cs b/WxCheckApi/Controllers/WeatherForecastController.cs deleted file mode 100644 index 80548eb..0000000 --- a/WxCheckApi/Controllers/WeatherForecastController.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Microsoft.AspNetCore.Mvc; - -namespace WxCheckApi.Controllers -{ - [ApiController] - [Route("[controller]")] - public class WeatherForecastController : ControllerBase - { - private static readonly string[] Summaries = new[] - { - "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" - }; - - private readonly ILogger _logger; - - public WeatherForecastController(ILogger logger) - { - _logger = logger; - } - - [HttpGet] - public IEnumerable Get() - { - return Enumerable.Range(1, 5).Select(index => new WeatherForecast - { - Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), - TemperatureC = Random.Shared.Next(-20, 55), - Summary = Summaries[Random.Shared.Next(Summaries.Length)] - }) - .ToArray(); - } - } -} diff --git a/WxCheckApi/Program.cs b/WxCheckApi/Program.cs deleted file mode 100644 index de9a6f4..0000000 --- a/WxCheckApi/Program.cs +++ /dev/null @@ -1,70 +0,0 @@ -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.IdentityModel.Tokens; -using MySql.Data.MySqlClient; -using System.Text; - -var builder = WebApplication.CreateBuilder(args); - -// Add services to the container. -builder.Services.AddControllers(); - -// 添加HttpClientFactory -builder.Services.AddHttpClient(); - -// 添加数据库连接 -builder.Services.AddScoped(sp => { - var connectionString = builder.Configuration.GetConnectionString("MySQLConnection"); - return new MySqlConnection(connectionString); -}); - -builder.Services.AddAuthorization(); -builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) - .AddJwtBearer(option => - { - string DefaultKey = "B,EZipeApY3cNj3~4RP0UMR=H>9x8.1!E85wmZ]]py2d$Y?5"; - var sec = Encoding.UTF8.GetBytes(builder.Configuration["JWT:SecretKey"] ?? DefaultKey); - - option.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters() - { - ValidateIssuer = true, - ValidateAudience = true, - ValidateLifetime = true, - - ValidateIssuerSigningKey = true, - ValidIssuer = builder.Configuration["JwT:Issuer"], - ValidAudience = builder.Configuration["JwT:Audience"], - IssuerSigningKey = new SymmetricSecurityKey(sec) - }; - - option.Events = new JwtBearerEvents - { - OnMessageReceived = context => - { - var token = context.Request.Headers["token"].FirstOrDefault(); - if (string.IsNullOrEmpty(token)) - { - // 如果没有找到 token 头部,则继续检查 Authorization 头部 - token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last(); - } - // 如果找到了 token,则将其设置到 HttpContext 中 - if (!string.IsNullOrEmpty(token)) - { - context.Token = token; - } - return Task.CompletedTask; - } - }; - }); - - -var app = builder.Build(); - -// Configure the HTTP request pipeline. -app.UseAuthentication(); // 添加认证中间件 -app.UseAuthorization(); // 使用授权中间件 - -app.UseAuthorization(); - -app.MapControllers(); - -app.Run(); diff --git a/WxCheckApi/Properties/PublishProfiles/FolderProfile.pubxml b/WxCheckApi/Properties/PublishProfiles/FolderProfile.pubxml deleted file mode 100644 index ebb3203..0000000 --- a/WxCheckApi/Properties/PublishProfiles/FolderProfile.pubxml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - true - false - true - Release - Any CPU - FileSystem - bin\Release\net8.0\publish\ - FileSystem - <_TargetId>Folder - - net8.0 - win-x64 - e545c738-a21b-71f3-9fb9-a68d8018822d - false - - \ No newline at end of file diff --git a/WxCheckApi/Properties/PublishProfiles/FolderProfile.pubxml.user b/WxCheckApi/Properties/PublishProfiles/FolderProfile.pubxml.user deleted file mode 100644 index 8da1dc5..0000000 --- a/WxCheckApi/Properties/PublishProfiles/FolderProfile.pubxml.user +++ /dev/null @@ -1,9 +0,0 @@ - - - - - <_PublishTargetUrl>E:\Project\WxCheck\WxCheckApi\bin\Release\net8.0\publish\ - True|2025-11-08T01:48:12.8385703Z||;True|2025-11-07T15:09:26.3902793+08:00||;True|2025-11-07T11:51:31.5643958+08:00||;True|2025-11-07T11:50:44.2146653+08:00||;True|2025-11-04T14:29:55.7628000+08:00||;False|2025-11-04T14:29:50.0660192+08:00||;True|2025-11-04T14:20:52.6380538+08:00||;True|2025-11-04T10:14:31.0406197+08:00||;True|2025-11-04T10:01:51.9971474+08:00||;True|2025-11-04T09:53:16.2195499+08:00||;True|2025-11-04T09:45:30.2430508+08:00||;True|2025-11-04T08:52:40.6424728+08:00||;True|2025-11-03T21:04:36.1464303+08:00||;True|2025-11-03T20:46:33.3635634+08:00||;True|2025-11-03T20:45:29.5368625+08:00||;True|2025-11-03T20:42:14.5975957+08:00||;True|2025-11-03T20:40:43.0062117+08:00||;True|2025-11-03T20:16:38.4711929+08:00||;True|2025-11-03T20:14:42.8936169+08:00||;True|2025-11-03T19:35:15.7051947+08:00||;True|2025-11-03T19:01:58.6546141+08:00||;True|2025-11-03T17:59:30.0861681+08:00||;True|2025-11-03T16:15:01.5245126+08:00||;True|2025-11-03T16:06:34.1178642+08:00||;True|2025-10-31T17:30:06.3039818+08:00||;True|2025-10-31T16:20:12.7490590+08:00||;True|2025-10-31T15:10:14.4751645+08:00||; - - - \ No newline at end of file diff --git a/WxCheckApi/Properties/PublishProfiles/FolderProfile1.pubxml b/WxCheckApi/Properties/PublishProfiles/FolderProfile1.pubxml deleted file mode 100644 index ebb3203..0000000 --- a/WxCheckApi/Properties/PublishProfiles/FolderProfile1.pubxml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - true - false - true - Release - Any CPU - FileSystem - bin\Release\net8.0\publish\ - FileSystem - <_TargetId>Folder - - net8.0 - win-x64 - e545c738-a21b-71f3-9fb9-a68d8018822d - false - - \ No newline at end of file diff --git a/WxCheckApi/Properties/PublishProfiles/FolderProfile1.pubxml.user b/WxCheckApi/Properties/PublishProfiles/FolderProfile1.pubxml.user deleted file mode 100644 index f27bde1..0000000 --- a/WxCheckApi/Properties/PublishProfiles/FolderProfile1.pubxml.user +++ /dev/null @@ -1,9 +0,0 @@ - - - - - <_PublishTargetUrl>E:\Project_Class\WX_XCX\WxCheck_Wx_Prod\WxCheckApi\bin\Release\net8.0\publish\ - True|2025-12-05T03:46:42.6952752Z||;True|2025-12-03T17:28:08.6000818+08:00||;True|2025-12-03T15:36:17.3153352+08:00||;True|2025-12-03T15:34:35.0408800+08:00||;True|2025-12-03T15:32:13.7754473+08:00||;True|2025-12-03T15:23:43.3405041+08:00||;True|2025-12-03T11:08:15.0823391+08:00||;True|2025-12-03T11:04:29.8829020+08:00||;True|2025-12-03T11:00:07.4056298+08:00||;True|2025-12-03T10:56:38.5220608+08:00||;True|2025-12-03T10:51:59.6142114+08:00||; - - - \ No newline at end of file diff --git a/WxCheckApi/Properties/launchSettings.json b/WxCheckApi/Properties/launchSettings.json deleted file mode 100644 index 813d77d..0000000 --- a/WxCheckApi/Properties/launchSettings.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:6041", - "sslPort": 0 - } - }, - "profiles": { - "http": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "launchUrl": "weatherforecast", - "applicationUrl": "http://localhost:5065", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "weatherforecast", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} diff --git a/WxCheckApi/WeatherForecast.cs b/WxCheckApi/WeatherForecast.cs deleted file mode 100644 index 68c85aa..0000000 --- a/WxCheckApi/WeatherForecast.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace WxCheckApi -{ - public class WeatherForecast - { - public DateOnly Date { get; set; } - - public int TemperatureC { get; set; } - - public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); - - public string? Summary { get; set; } - } -} diff --git a/WxCheckApi/WxCheckApi.csproj b/WxCheckApi/WxCheckApi.csproj deleted file mode 100644 index 2f1bbef..0000000 --- a/WxCheckApi/WxCheckApi.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - - diff --git a/WxCheckApi/WxCheckApi.http b/WxCheckApi/WxCheckApi.http deleted file mode 100644 index d2802ef..0000000 --- a/WxCheckApi/WxCheckApi.http +++ /dev/null @@ -1,6 +0,0 @@ -@WxCheckApi_HostAddress = http://localhost:5065 - -GET {{WxCheckApi_HostAddress}}/weatherforecast/ -Accept: application/json - -### diff --git a/WxCheckApi/WxCheckApi.slnx b/WxCheckApi/WxCheckApi.slnx deleted file mode 100644 index c5d2b4b..0000000 --- a/WxCheckApi/WxCheckApi.slnx +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/WxCheckApi/appsettings.Development.json b/WxCheckApi/appsettings.Development.json deleted file mode 100644 index 0c208ae..0000000 --- a/WxCheckApi/appsettings.Development.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - } -} diff --git a/WxCheckApi/appsettings.json b/WxCheckApi/appsettings.json deleted file mode 100644 index c12022d..0000000 --- a/WxCheckApi/appsettings.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "JwT": { - "SecretKey": "1%猜U36eraIYI?3s9dI}46an不Nn>P]3)$9:dCnS5=ajAu%8B5]15hF到20T20QBD]Mt9}2z76jO#Glg&0yDy7k-2zVdt&Z5ur>=l)QF2^1&Dq04m76U2P9wvlWf", - "Issuer": "微信小程序token", - "Audience": "W*u93xxp*08DnW@%6}5Tjh6bE?;hW" - }, - "WeChat": { - "AppId": "wx42e9add0f91af98b", - "AppSecret": "5620f00b40297efaf3d197d61ae184d6" - }, - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "AllowedHosts": "*", - "ConnectionStrings": { - "MySQLConnection": "Server=47.119.147.104;Database=wx_xcx_check;user id=root;password=hbfjW6A_eob;port=3307;" - }, - "AmapApi": { - "ApiKey": "4d5cb7818664ada68ae5f68783b8bd4c" - } - -} diff --git a/WxCheckApi/wx_xcx_check.sql b/WxCheckApi/wx_xcx_check.sql deleted file mode 100644 index 5a221b1..0000000 --- a/WxCheckApi/wx_xcx_check.sql +++ /dev/null @@ -1,86 +0,0 @@ -/* - Navicat Premium Dump SQL - - Source Server : 47.119.147.104 - Source Server Type : MariaDB - Source Server Version : 120002 (12.0.2-MariaDB) - Source Host : 47.119.147.104:3307 - Source Schema : wx_xcx_check - - Target Server Type : MariaDB - Target Server Version : 120002 (12.0.2-MariaDB) - File Encoding : 65001 - - Date: 05/12/2025 11:40:09 -*/ - -SET NAMES utf8mb4; -SET FOREIGN_KEY_CHECKS = 0; - --- ---------------------------- --- Table structure for xcx_conversation --- ---------------------------- -DROP TABLE IF EXISTS `xcx_conversation`; -CREATE TABLE `xcx_conversation` ( - `Id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', - `UserKey` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '用户唯一标识键', - `ConversationContent` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '会话内容', - `MessageType` int(11) NOT NULL DEFAULT 1 COMMENT '信息类型:1-公有,2-私有', - `SendMethod` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '发送方式', - `UserLocation` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '用户定位信息', - `RecordTime` datetime NOT NULL COMMENT '记录时间', - `RecordTimeUTCStamp` bigint(20) NOT NULL COMMENT '记录时间的UTC时间戳', - `IsDeleted` tinyint(4) NULL DEFAULT 0 COMMENT '是否删除:0-正常,1-删除', - `CreateTime` datetime NULL DEFAULT current_timestamp() COMMENT '创建时间', - `Latitude` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '纬度', - `Longitude` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '经度', - `Guid` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT 'GUID', - `SpeakingTime` int(11) NULL DEFAULT NULL COMMENT '对话时长', - PRIMARY KEY (`Id`) USING BTREE, - INDEX `idx_userkey`(`UserKey` ASC) USING BTREE, - INDEX `idx_utcstamp`(`RecordTimeUTCStamp` ASC) USING BTREE, - INDEX `idx_deleted`(`IsDeleted` ASC) USING BTREE, - INDEX `idx_recordtime`(`RecordTime` ASC) USING BTREE, - INDEX `idx_messagetype`(`MessageType` ASC) USING BTREE, - INDEX `idx_guid`(`Guid` ASC) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 418 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会话记录表' ROW_FORMAT = Dynamic; - --- ---------------------------- --- Table structure for xcx_log --- ---------------------------- -DROP TABLE IF EXISTS `xcx_log`; -CREATE TABLE `xcx_log` ( - `Id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', - `RecordTime` datetime NOT NULL COMMENT '记录时间', - `UserKey` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '用户唯一标识键', - `OperationContent` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '操作内容', - `UserLocation` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '用户定位信息', - `Impact` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '产生的影响', - `CreateTime` datetime NULL DEFAULT current_timestamp() COMMENT '创建时间', - PRIMARY KEY (`Id`) USING BTREE, - INDEX `idx_userkey`(`UserKey` ASC) USING BTREE, - INDEX `idx_recordtime`(`RecordTime` ASC) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志表' ROW_FORMAT = Dynamic; - --- ---------------------------- --- Table structure for xcx_users --- ---------------------------- -DROP TABLE IF EXISTS `xcx_users`; -CREATE TABLE `xcx_users` ( - `Id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', - `UserName` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '用户名', - `UserKey` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '用户唯一标识键', - `WeChatName` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '微信名称', - `PhoneNumber` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '电话号码', - `FirstLoginTime` datetime NOT NULL COMMENT '首次登录时间', - `IsDisabled` tinyint(4) NULL DEFAULT 0 COMMENT '是否禁用:0-启用,1-禁用', - `CreateTime` datetime NULL DEFAULT current_timestamp() COMMENT '创建时间', - `UpdateTime` datetime NULL DEFAULT current_timestamp() ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `AvatarUrl` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '头像地址', - PRIMARY KEY (`Id`) USING BTREE, - UNIQUE INDEX `idx_userkey`(`UserKey` ASC) USING BTREE, - INDEX `idx_disabled`(`IsDisabled` ASC) USING BTREE, - INDEX `idx_logintime`(`FirstLoginTime` ASC) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 22 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '小程序用户表' ROW_FORMAT = Dynamic; - -SET FOREIGN_KEY_CHECKS = 1;