初始化小程序端
This commit is contained in:
@@ -14,7 +14,8 @@ App({
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
globalData: {
|
globalData: {
|
||||||
userInfo: null
|
userInfo: null,
|
||||||
|
baseUrl: 'https://你的域名' // 后端 API 根地址
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,35 @@
|
|||||||
{
|
{
|
||||||
"pages": [
|
"pages": [
|
||||||
"pages/index/index",
|
"pages/logs/logs",
|
||||||
"pages/logs/logs"
|
"pages/chat/chat"
|
||||||
],
|
],
|
||||||
"window": {
|
"window": {
|
||||||
"navigationBarTextStyle": "black",
|
"navigationBarTextStyle": "black",
|
||||||
"navigationBarTitleText": "Weixin",
|
"navigationBarTitleText": "宝来威智能AI",
|
||||||
"navigationBarBackgroundColor": "#ffffff"
|
"navigationBarBackgroundColor": "#ffffff"
|
||||||
},
|
},
|
||||||
|
"__usePrivacyCheck__": true,
|
||||||
"style": "v2",
|
"style": "v2",
|
||||||
"componentFramework": "glass-easel",
|
"componentFramework": "glass-easel",
|
||||||
"sitemapLocation": "sitemap.json",
|
"sitemapLocation": "sitemap.json",
|
||||||
"lazyCodeLoading": "requiredComponents"
|
"lazyCodeLoading": "requiredComponents",
|
||||||
}
|
"plugins": {
|
||||||
|
"WechatSI": {
|
||||||
|
"version": "0.3.6",
|
||||||
|
"provider": "wx069ba97219f66d99"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requiredPrivateInfos": ["getLocation"] ,
|
||||||
|
|
||||||
|
"permission": {
|
||||||
|
"scope.userLocation": {
|
||||||
|
"desc": "用于打卡/显示附近门店"
|
||||||
|
},
|
||||||
|
|
||||||
|
"scope.record": {
|
||||||
|
"desc": "需要录音权限以实现语音输入功能"
|
||||||
|
},
|
||||||
|
"scope.speechRecognition": { "desc": "需要语音识别权限" },
|
||||||
|
"requiredBackgroundModes": ["audio"]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,18 +1,247 @@
|
|||||||
// logs.js
|
import { authorizeBatch } from '../../utils/authorize'
|
||||||
const util = require('../../utils/util.js')
|
const util = require('../../utils/util.js')
|
||||||
|
|
||||||
Page({
|
Page({
|
||||||
data: {
|
data: {
|
||||||
logs: []
|
isAgree: false,
|
||||||
},
|
openid:"",
|
||||||
|
showAuthModal: false,
|
||||||
|
userInfo: null,
|
||||||
|
needReg: false,
|
||||||
|
openid: '',
|
||||||
|
avatarUrl: '/images/Blvlogo.png',
|
||||||
|
nickName: '',
|
||||||
|
form: {
|
||||||
|
name: '',
|
||||||
|
phone: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
onLoad() {
|
onLoad() {
|
||||||
|
this.handleLogin()
|
||||||
|
},
|
||||||
|
onAvatar(e) {
|
||||||
|
////////debugger
|
||||||
|
this.setData({ avatarUrl: e.detail.avatarUrl }) // 用户选的头像
|
||||||
|
},
|
||||||
|
onNick(e) {
|
||||||
|
this.setData({ nickName: e.detail.value }) // 用户输入的昵称
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inputName(e) {this.setData({'form.name': e.detail.value})},
|
||||||
|
inputPhone(e) {this.setData({'form.phone': e.detail.value})},
|
||||||
|
async submitReg() {
|
||||||
|
|
||||||
|
try {
|
||||||
|
wx.showLoading({ title: '登录中...', mask: true });
|
||||||
|
|
||||||
|
// 获取微信code
|
||||||
|
const loginRes = await new Promise((resolve, reject) => {
|
||||||
|
wx.login({
|
||||||
|
success: resolve,
|
||||||
|
fail: reject
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!loginRes.code) {
|
||||||
|
throw new Error('获取登录凭证失败');
|
||||||
|
}
|
||||||
|
const nickName = this.data.nickName;
|
||||||
|
let form =this.data.form
|
||||||
|
let openid =this.data.openid
|
||||||
|
let avatarUrl =this.data.avatarUrl
|
||||||
|
// 发送到后端
|
||||||
|
const apiRes = await new Promise((resolve, reject) => {
|
||||||
|
wx.request({
|
||||||
|
url: 'https://wx-xcx-check.blv-oa.com:4433/api/Login/Register',
|
||||||
|
method: 'POST',
|
||||||
|
data: {
|
||||||
|
UserName:form.name ,
|
||||||
|
UserKey: openid,
|
||||||
|
WeChatName:nickName,
|
||||||
|
PhoneNumber:form.phone,
|
||||||
|
AvatarUrl:avatarUrl
|
||||||
|
},
|
||||||
|
|
||||||
|
success: res =>{
|
||||||
|
if (res.data.success && res.data.data.userName && res.data.data.weChatName && res.data.data.phoneNumber) {
|
||||||
|
wx.setStorageSync('openid', res.data.data.userKey);
|
||||||
|
this.setData({openid:res.data.data.userKey});
|
||||||
|
wx.navigateTo({url: '/pages/chat/chat'});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
wx.showToast({
|
||||||
|
title: '登录失败:'+ res.data.message,
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
this.setData({needReg: true});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: reject
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('登录失败:', error);
|
||||||
|
wx.showToast({
|
||||||
|
title: `登录失败: ${error.message || '未知错误'}`,
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
wx.hideLoading();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
onAgreeChange(e) {
|
||||||
|
|
||||||
|
console.log(e)
|
||||||
|
this.setData({ isAgree: e.detail.value.length > 0 });
|
||||||
|
},
|
||||||
|
|
||||||
|
openContract() {
|
||||||
|
wx.openPrivacyContract({
|
||||||
|
success: () => console.log('已打开协议'),
|
||||||
|
fail: (e) => console.log('打开失败', e)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 添加新方法
|
||||||
|
|
||||||
|
// 显示授权弹窗
|
||||||
|
showAuthModal() {
|
||||||
|
this.setData({ showAuthModal: true });
|
||||||
|
},
|
||||||
|
|
||||||
|
// 取消授权
|
||||||
|
onAuthCancel() {
|
||||||
|
this.setData({ showAuthModal: false });
|
||||||
|
wx.showToast({ title: '授权已取消', icon: 'none' });
|
||||||
|
},
|
||||||
|
// 获取用户信息
|
||||||
|
async onGetUserInfo(e) {
|
||||||
|
try {
|
||||||
|
if (e.detail.errMsg !== 'getUserInfo:ok') {
|
||||||
|
throw new Error('用户拒绝了授权');
|
||||||
|
}
|
||||||
|
|
||||||
|
const userInfo = e.detail.userInfo;
|
||||||
this.setData({
|
this.setData({
|
||||||
logs: (wx.getStorageSync('logs') || []).map(log => {
|
userInfo,
|
||||||
return {
|
showAuthModal: false
|
||||||
date: util.formatTime(new Date(log)),
|
});
|
||||||
timeStamp: log
|
//////////debugger
|
||||||
}
|
// 保存到全局
|
||||||
})
|
getApp().globalData.userInfo = userInfo;
|
||||||
|
await this.onGetAuth()
|
||||||
|
// 继续登录流程
|
||||||
|
await this.completeLogin();
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取用户信息失败:'+error);
|
||||||
|
wx.showToast({
|
||||||
|
title: error.message || '获取用户信息失败',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async onGetAuth() {
|
||||||
|
const res = await authorizeBatch([
|
||||||
|
'scope.record',
|
||||||
|
'scope.userLocation'
|
||||||
|
])
|
||||||
|
|
||||||
|
if (true) {//if (res.ok) {
|
||||||
|
wx.showToast({ title: '全部授权成功' })
|
||||||
|
} else {
|
||||||
|
wx.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: `您拒绝了 ${res.denied.map(s => SCOPE_MAP[s]).join('、')},部分功能可能无法使用`,
|
||||||
|
showCancel: false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 完整的登录流程
|
||||||
|
async completeLogin() {
|
||||||
|
|
||||||
|
try {
|
||||||
|
wx.showLoading({ title: '登录中...', mask: true });
|
||||||
|
|
||||||
|
// 获取微信code
|
||||||
|
const loginRes = await new Promise((resolve, reject) => {
|
||||||
|
wx.login({
|
||||||
|
success: resolve,
|
||||||
|
fail: reject
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!loginRes.code) {
|
||||||
|
throw new Error('获取登录凭证失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送到后端
|
||||||
|
const apiRes = await new Promise((resolve, reject) => {
|
||||||
|
wx.request({
|
||||||
|
url: 'https://wx-xcx-check.blv-oa.com:4433/api/Login/Login',
|
||||||
|
method: 'POST',
|
||||||
|
data: {Code: loginRes.code},
|
||||||
|
success: res =>{
|
||||||
|
wx.hideLoading()
|
||||||
|
if (res.data.success){
|
||||||
|
this.setData({openid: res.data.data.userKey});
|
||||||
|
console.log(this.data.openid)
|
||||||
|
wx.setStorageSync('openid', res.data.data.userKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.data.success && res.data.data.userName && res.data.data.weChatName && res.data.data.phoneNumber) {
|
||||||
|
wx.navigateTo({url: '/pages/chat/chat'});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
wx.showToast({
|
||||||
|
title: `登录失败: 用户未注册。请先填写完整信息再进行登录`,
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
this.setData({needReg: true});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: reject
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('登录失败:', error);
|
||||||
|
wx.showToast({
|
||||||
|
title: `登录失败: ${error.message || '未知错误'}`,
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
wx.hideLoading();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改原有登录方法
|
||||||
|
handleLogin: async function() {
|
||||||
|
|
||||||
|
if (this.data.isAgree) {
|
||||||
|
// 如果已有用户信息,直接完成登录
|
||||||
|
// if (this.data.userInfo) {
|
||||||
|
await this.completeLogin();
|
||||||
|
// } else {
|
||||||
|
// // 否则显示授权弹窗
|
||||||
|
// this.showAuthModal();
|
||||||
|
// }
|
||||||
|
}else{
|
||||||
|
// 提示为勾选用户协议
|
||||||
|
wx.showToast({
|
||||||
|
title: '请先勾选用户协议',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
return; // 拦截后续登录逻辑
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,6 +1,76 @@
|
|||||||
<!--logs.wxml-->
|
<!-- pages/login/login.wxml -->
|
||||||
<scroll-view class="scrollarea" scroll-y type="list">
|
<view class="login-container">
|
||||||
<block wx:for="{{logs}}" wx:key="timeStamp" wx:for-item="log">
|
<!-- 顶部 Logo / 标题 -->
|
||||||
<view class="log-item">{{index + 1}}. {{log.date}}</view>
|
<view class="head">
|
||||||
</block>
|
<image src="/images/Blvlogo.png" mode="aspectFit" class="logo"/>
|
||||||
</scroll-view>
|
<text class="title">宝来威工作助手</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 微信登录按钮 -->
|
||||||
|
<view wx:if="{{!needReg}}" class="wx-login-box">
|
||||||
|
<button class="wx-btn" open-type="getUserProfile" bindtap="handleLogin">
|
||||||
|
微信一键登录
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 信息补全表单 -->
|
||||||
|
<view wx:else class="reg-form">
|
||||||
|
<text class="tip">请补全信息</text>
|
||||||
|
<!-- 头像 -->
|
||||||
|
<!--index.wxml-->
|
||||||
|
<view class="avatar-box " >
|
||||||
|
<button open-type="chooseAvatar" bindchooseavatar="onAvatar" style="margin: 0; padding: 0;height: 32px;width:90%; ">
|
||||||
|
<image src="{{avatarUrl}}" style="height: 30px;width: 30px;" />
|
||||||
|
</button>
|
||||||
|
<text class="tip">点击更换头像</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 昵称 -->
|
||||||
|
<input type="nickname" class="input" placeholder="请输入昵称" bindblur="onNick" />
|
||||||
|
|
||||||
|
|
||||||
|
<input
|
||||||
|
class="input"
|
||||||
|
placeholder="用户名称"
|
||||||
|
value="{{form.name}}"
|
||||||
|
bindinput="inputName"
|
||||||
|
maxlength="20"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
class="input"
|
||||||
|
placeholder="联系电话"
|
||||||
|
type="number"
|
||||||
|
value="{{form.phone}}"
|
||||||
|
bindinput="inputPhone"
|
||||||
|
maxlength="11"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<button class="submit-btn" style="display: flex; flex-direction:column; justify-content: center; " bindtap="submitReg">进入聊天</button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部协议 -->
|
||||||
|
|
||||||
|
<view class="footer">
|
||||||
|
<checkbox-group bindchange="onAgreeChange" class="agree-line">
|
||||||
|
<checkbox value="1" checked="{{isAgree}}" />
|
||||||
|
<text class="txt">登录须要勾选</text>
|
||||||
|
<text class="link" bindtap="openContract">《用户协议》</text>
|
||||||
|
</checkbox-group>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<!-- 在文件底部添加 -->
|
||||||
|
<!-- <view class="auth-modal" hidden="{{!showAuthModal}}">
|
||||||
|
<view class="auth-content">
|
||||||
|
<view class="auth-header">获取用户信息</view>
|
||||||
|
<view class="auth-body">
|
||||||
|
我们需要获取您的头像和昵称以提供更好的服务
|
||||||
|
</view>
|
||||||
|
<view class="auth-footer">
|
||||||
|
<button class="auth-btn" bindtap="onAuthCancel">取消</button>
|
||||||
|
<button class="auth-btn primary" open-type="getUserInfo" bindgetuserinfo="onGetUserInfo">授权</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view> -->
|
||||||
@@ -14,3 +14,137 @@ page {
|
|||||||
.log-item:last-child {
|
.log-item:last-child {
|
||||||
padding-bottom: env(safe-area-inset-bottom);
|
padding-bottom: env(safe-area-inset-bottom);
|
||||||
}
|
}
|
||||||
|
/* pages/login/login.wxss */
|
||||||
|
.login-container{ height:100vh; display:flex; flex-direction:column; align-items:center; justify-content:center; background:#f5f5f5; }
|
||||||
|
|
||||||
|
.head{ margin-bottom:60rpx; text-align:center; }
|
||||||
|
.logo{ width:120rpx; height:120rpx; }
|
||||||
|
.title{ display:block; font-size:48rpx; color:#333; margin-top:20rpx; }
|
||||||
|
|
||||||
|
.wx-login-box{ width:80%; }
|
||||||
|
.wx-btn{width:100%;
|
||||||
|
height:88rpx;
|
||||||
|
/* 移除 line-height,使用 Flex 布局 */
|
||||||
|
display: flex;
|
||||||
|
justify-content: center; /* 水平居中 */
|
||||||
|
align-items: center; /* 垂直居中 */
|
||||||
|
background:#07C160;
|
||||||
|
color:#fff;
|
||||||
|
border-radius:12rpx;
|
||||||
|
font-size:32rpx; }
|
||||||
|
.icon-wechat{ margin-right:10rpx; }
|
||||||
|
|
||||||
|
.reg-form{ width:80%; }
|
||||||
|
.tip{ font-size:28rpx; color:#666; margin-bottom:40rpx; }
|
||||||
|
.input{ width:100%; height:88rpx; background:#fff; border:1rpx solid #ddd; border-radius:12rpx; padding:0 20rpx; margin-bottom:30rpx; font-size:30rpx; }
|
||||||
|
.submit-btn{ width:100%; height:88rpx; background:#07C160; color:#fff; border-radius:12rpx; font-size:32rpx; }
|
||||||
|
|
||||||
|
.footer{ position:absolute; bottom:40rpx; font-size:24rpx; color:#999; }
|
||||||
|
.link{ color:#576B95; }
|
||||||
|
/* 授权弹窗样式 */
|
||||||
|
.auth-modal {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: rgba(0,0,0,0.5);
|
||||||
|
z-index: 999;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-content {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 16rpx 16rpx 0 0;
|
||||||
|
padding: 30rpx;
|
||||||
|
animation: slideUp 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideUp {
|
||||||
|
from { transform: translateY(100%); }
|
||||||
|
to { transform: translateY(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-header {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-body {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-btn {
|
||||||
|
flex: 1;
|
||||||
|
margin: 0 10rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
background: #f2f2f2;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-btn.primary {
|
||||||
|
background: #07C160;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
/*index.wxss*/
|
||||||
|
.avatar-box {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 96rpx;
|
||||||
|
height: 96rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 2rpx solid #e7e7e7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip {
|
||||||
|
margin-top: 8rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
/* wxss */
|
||||||
|
.agree-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
.agree-row checkbox {
|
||||||
|
margin-right: 8rpx;
|
||||||
|
}
|
||||||
|
.link {
|
||||||
|
color: #1989fa;
|
||||||
|
margin-left: 4rpx;
|
||||||
|
}
|
||||||
|
.footer{
|
||||||
|
padding: 20rpx;
|
||||||
|
/* background: #fff; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.agree-line{
|
||||||
|
display: flex;
|
||||||
|
align-items: center; /* 关键:垂直居中 */
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agree-line checkbox{
|
||||||
|
margin-right: 8rpx; /* 文字和框间距 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.link{
|
||||||
|
color: #1989fa;
|
||||||
|
margin-left: 4rpx;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"compileType": "miniprogram",
|
"compileType": "miniprogram",
|
||||||
"libVersion": "trial",
|
"libVersion": "3.11.0",
|
||||||
"packOptions": {
|
"packOptions": {
|
||||||
"ignore": [],
|
"ignore": [],
|
||||||
"include": []
|
"include": []
|
||||||
@@ -36,6 +36,6 @@
|
|||||||
"tabIndent": "auto",
|
"tabIndent": "auto",
|
||||||
"tabSize": 2
|
"tabSize": 2
|
||||||
},
|
},
|
||||||
"appid": "wx1322e65d8a20d902",
|
"appid": "wx42e9add0f91af98b",
|
||||||
"simulatorPluginLibVersion": {}
|
"simulatorPluginLibVersion": {}
|
||||||
}
|
}
|
||||||
@@ -15,9 +15,10 @@
|
|||||||
"useStaticServer": false,
|
"useStaticServer": false,
|
||||||
"useLanDebug": false,
|
"useLanDebug": false,
|
||||||
"showES6CompileOption": false,
|
"showES6CompileOption": false,
|
||||||
"bigPackageSizeSupport": false,
|
"bigPackageSizeSupport": true,
|
||||||
"checkInvalidKey": true,
|
"checkInvalidKey": true,
|
||||||
"ignoreDevUnusedFiles": true
|
"ignoreDevUnusedFiles": true
|
||||||
},
|
},
|
||||||
"libVersion": "3.11.0"
|
"libVersion": "3.11.0",
|
||||||
|
"condition": {}
|
||||||
}
|
}
|
||||||
35
WxCheckApi/.vscode/launch.json
vendored
Normal file
35
WxCheckApi/.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
41
WxCheckApi/.vscode/tasks.json
vendored
Normal file
41
WxCheckApi/.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -173,7 +173,56 @@
|
|||||||
|
|
||||||
## 2. Check控制器接口
|
## 2. Check控制器接口
|
||||||
|
|
||||||
### 2.1 添加会话记录接口
|
### 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 添加会话记录接口
|
||||||
|
|
||||||
#### 接口描述
|
#### 接口描述
|
||||||
添加新的会话记录到系统中。
|
添加新的会话记录到系统中。
|
||||||
@@ -188,8 +237,9 @@
|
|||||||
| UserKey | string | 是 | 用户唯一标识键 |
|
| UserKey | string | 是 | 用户唯一标识键 |
|
||||||
| ConversationContent | string | 是 | 会话内容 |
|
| ConversationContent | string | 是 | 会话内容 |
|
||||||
| SendMethod | string | 是 | 发送方式 |
|
| SendMethod | string | 是 | 发送方式 |
|
||||||
| UserLocation | string | 否 | 用户定位信息 |
|
| UserLocation | string | 否 | 用户定位信息(经纬度格式:"纬度,经度") |
|
||||||
| MessageType | int | 否 | 1:公有消息,2:私有消息 |
|
| MessageType | int | 否 | 1:公有消息,2:私有消息 |
|
||||||
|
| Guid | string | 否 | 会话唯一标识(不提供则系统自动生成) |
|
||||||
|
|
||||||
#### 请求示例
|
#### 请求示例
|
||||||
|
|
||||||
@@ -198,8 +248,8 @@
|
|||||||
"UserKey": "user_123456",
|
"UserKey": "user_123456",
|
||||||
"ConversationContent": "这是一条测试消息",
|
"ConversationContent": "这是一条测试消息",
|
||||||
"SendMethod": "文本",
|
"SendMethod": "文本",
|
||||||
"UserLocation": "北京市海淀区",
|
"UserLocation": "39.9087,116.3975",
|
||||||
"MessageType": 0
|
"MessageType": 1
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -209,7 +259,9 @@
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"success": true,
|
"success": true,
|
||||||
"message": "收到!"
|
"message": "收到!",
|
||||||
|
"conversationGuid": "会话唯一标识",
|
||||||
|
"receivedTime": "2023-10-31 10:05:00"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -222,7 +274,7 @@
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2.2 查询会话记录接口
|
### 2.3 查询会话记录接口
|
||||||
|
|
||||||
#### 接口描述
|
#### 接口描述
|
||||||
根据用户唯一标识键查询该用户的所有会话记录。
|
根据用户唯一标识键查询该用户的所有会话记录。
|
||||||
@@ -255,27 +307,33 @@
|
|||||||
"data": [
|
"data": [
|
||||||
{
|
{
|
||||||
"Id": 1,
|
"Id": 1,
|
||||||
|
"Guid": "会话唯一标识",
|
||||||
"UserKey": "user_123456",
|
"UserKey": "user_123456",
|
||||||
"ConversationContent": "这是一条测试消息",
|
"ConversationContent": "这是一条测试消息",
|
||||||
"SendMethod": "文本",
|
"SendMethod": "文本",
|
||||||
"UserLocation": "北京市海淀区",
|
"UserLocation": "北京市海淀区",
|
||||||
|
"Latitude": "39.9087",
|
||||||
|
"Longitude": "116.3975",
|
||||||
"RecordTime": "2023-10-31T10:05:00",
|
"RecordTime": "2023-10-31T10:05:00",
|
||||||
"RecordTimeUTCStamp": 1698732300000,
|
"RecordTimeUTCStamp": 1698732300000,
|
||||||
"IsDeleted": false,
|
"IsDeleted": false,
|
||||||
"CreateTime": "2023-10-31T10:05:00",
|
"CreateTime": "2023-10-31T10:05:00",
|
||||||
"MessageType": 0
|
"MessageType": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Id": 2,
|
"Id": 2,
|
||||||
|
"Guid": "会话唯一标识",
|
||||||
"UserKey": "user_123456",
|
"UserKey": "user_123456",
|
||||||
"ConversationContent": "这是第二条测试消息",
|
"ConversationContent": "这是第二条测试消息",
|
||||||
"SendMethod": "图片",
|
"SendMethod": "图片",
|
||||||
"UserLocation": "北京市朝阳区",
|
"UserLocation": "北京市朝阳区",
|
||||||
|
"Latitude": "39.9180",
|
||||||
|
"Longitude": "116.4272",
|
||||||
"RecordTime": "2023-10-31T10:06:00",
|
"RecordTime": "2023-10-31T10:06:00",
|
||||||
"RecordTimeUTCStamp": 1698732360000,
|
"RecordTimeUTCStamp": 1698732360000,
|
||||||
"IsDeleted": false,
|
"IsDeleted": false,
|
||||||
"CreateTime": "2023-10-31T10:06:00",
|
"CreateTime": "2023-10-31T10:06:00",
|
||||||
"MessageType": 1
|
"MessageType": 2
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -290,7 +348,7 @@
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2.3 分页查询会话记录接口
|
### 2.4 分页查询会话记录接口
|
||||||
|
|
||||||
#### 接口描述
|
#### 接口描述
|
||||||
分页查询用户的会话记录,每页默认10条,按时间戳从**最新到最旧**排序,支持根据消息类型进行过滤。
|
分页查询用户的会话记录,每页默认10条,按时间戳从**最新到最旧**排序,支持根据消息类型进行过滤。
|
||||||
@@ -328,27 +386,33 @@
|
|||||||
"conversations": [
|
"conversations": [
|
||||||
{
|
{
|
||||||
"Id": 1,
|
"Id": 1,
|
||||||
|
"Guid": "会话唯一标识",
|
||||||
"UserKey": "user_123456",
|
"UserKey": "user_123456",
|
||||||
"ConversationContent": "这是一条测试消息",
|
"ConversationContent": "这是一条测试消息",
|
||||||
"SendMethod": "文本",
|
"SendMethod": "文本",
|
||||||
"UserLocation": "北京市海淀区",
|
"UserLocation": "北京市海淀区",
|
||||||
|
"Latitude": "39.9087",
|
||||||
|
"Longitude": "116.3975",
|
||||||
"RecordTime": "2023-10-31T10:00:00",
|
"RecordTime": "2023-10-31T10:00:00",
|
||||||
"RecordTimeUTCStamp": 1698727200000,
|
"RecordTimeUTCStamp": 1698727200000,
|
||||||
"IsDeleted": false,
|
"IsDeleted": false,
|
||||||
"CreateTime": "2023-10-31T10:00:00",
|
"CreateTime": "2023-10-31T10:00:00",
|
||||||
"MessageType": 0
|
"MessageType": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Id": 2,
|
"Id": 2,
|
||||||
|
"Guid": "会话唯一标识",
|
||||||
"UserKey": "user_123456",
|
"UserKey": "user_123456",
|
||||||
"ConversationContent": "这是一条私有消息",
|
"ConversationContent": "这是一条私有消息",
|
||||||
"SendMethod": "文本",
|
"SendMethod": "文本",
|
||||||
"UserLocation": "北京市朝阳区",
|
"UserLocation": "北京市朝阳区",
|
||||||
|
"Latitude": "39.9180",
|
||||||
|
"Longitude": "116.4272",
|
||||||
"RecordTime": "2023-10-31T09:55:00",
|
"RecordTime": "2023-10-31T09:55:00",
|
||||||
"RecordTimeUTCStamp": 1698724500000,
|
"RecordTimeUTCStamp": 1698724500000,
|
||||||
"IsDeleted": false,
|
"IsDeleted": false,
|
||||||
"CreateTime": "2023-10-31T09:55:00",
|
"CreateTime": "2023-10-31T09:55:00",
|
||||||
"MessageType": 1
|
"MessageType": 2
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"totalCount": 25,
|
"totalCount": 25,
|
||||||
@@ -368,10 +432,73 @@
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2.3 更新会话记录接口
|
### 2.5 根据GUID查询会话记录接口
|
||||||
|
|
||||||
#### 接口描述
|
#### 接口描述
|
||||||
更新指定ID的会话记录,需要验证UserKey的权限。
|
根据会话唯一标识(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`
|
`/api/Check/UpdateConversation`
|
||||||
@@ -380,7 +507,7 @@
|
|||||||
|
|
||||||
| 参数名 | 类型 | 必填 | 描述 |
|
| 参数名 | 类型 | 必填 | 描述 |
|
||||||
|--------|------|------|------|
|
|--------|------|------|------|
|
||||||
| Id | long | 是 | 会话记录ID |
|
| Guid | string | 是 | 会话唯一标识 |
|
||||||
| UserKey | string | 是 | 用户唯一标识键(用于权限验证) |
|
| UserKey | string | 是 | 用户唯一标识键(用于权限验证) |
|
||||||
| ConversationContent | string | 是 | 新的会话内容 |
|
| ConversationContent | string | 是 | 新的会话内容 |
|
||||||
| SendMethod | string | 是 | 新的发送方式 |
|
| SendMethod | string | 是 | 新的发送方式 |
|
||||||
@@ -391,12 +518,12 @@
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"Id": 1,
|
"Guid": "会话唯一标识",
|
||||||
"UserKey": "user_123456",
|
"UserKey": "user_123456",
|
||||||
"ConversationContent": "更新后的会话内容",
|
"ConversationContent": "更新后的会话内容",
|
||||||
"SendMethod": "文本",
|
"SendMethod": "文本",
|
||||||
"UserLocation": "北京市西城区",
|
"UserLocation": "北京市西城区",
|
||||||
"MessageType": 0
|
"MessageType": 1
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -406,7 +533,8 @@
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"success": true,
|
"success": true,
|
||||||
"message": "会话更新成功"
|
"message": "更新成功",
|
||||||
|
"receivedTime": "2023-10-31 10:10:00"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -414,7 +542,7 @@
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"success": false,
|
"success": false,
|
||||||
"message": "会话记录不存在或无权限修改"
|
"message": "记录不存在或无权限修改"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -426,7 +554,7 @@
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2.4 删除会话记录接口
|
### 2.7 删除会话记录接口
|
||||||
|
|
||||||
#### 接口描述
|
#### 接口描述
|
||||||
软删除会话记录(将IsDeleted标记为1),需要验证UserKey的权限。
|
软删除会话记录(将IsDeleted标记为1),需要验证UserKey的权限。
|
||||||
@@ -438,14 +566,14 @@
|
|||||||
|
|
||||||
| 参数名 | 类型 | 必填 | 描述 |
|
| 参数名 | 类型 | 必填 | 描述 |
|
||||||
|--------|------|------|------|
|
|--------|------|------|------|
|
||||||
| Id | long | 是 | 会话记录ID |
|
| Guid | string | 是 | 会话唯一标识 |
|
||||||
| UserKey | string | 是 | 用户唯一标识键(用于权限验证) |
|
| UserKey | string | 是 | 用户唯一标识键(用于权限验证) |
|
||||||
|
|
||||||
#### 请求示例
|
#### 请求示例
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"Id": 1,
|
"Guid": "会话唯一标识",
|
||||||
"UserKey": "user_123456"
|
"UserKey": "user_123456"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -456,7 +584,7 @@
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"success": true,
|
"success": true,
|
||||||
"message": "会话删除成功"
|
"message": "删除成功"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -464,7 +592,7 @@
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"success": false,
|
"success": false,
|
||||||
"message": "会话记录不存在或已被删除"
|
"message": "记录不存在或已被删除"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -476,6 +604,73 @@
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 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. 接口调用说明
|
||||||
|
|
||||||
### 3.1 HTTP客户端调用示例(JavaScript)
|
### 3.1 HTTP客户端调用示例(JavaScript)
|
||||||
@@ -568,4 +763,4 @@ async function addConversation() {
|
|||||||
|
|
||||||
- **最后更新时间**:2023-11-01
|
- **最后更新时间**:2023-11-01
|
||||||
- **维护人员**:系统管理员
|
- **维护人员**:系统管理员
|
||||||
- **版本号**:v1.1.0
|
- **版本号**:v1.2.0
|
||||||
@@ -208,9 +208,9 @@ namespace WxCheckApi.Controllers
|
|||||||
string latitude = "";
|
string latitude = "";
|
||||||
string longitude = "";
|
string longitude = "";
|
||||||
|
|
||||||
using (MySqlCommand cmd = new MySqlCommand("SELECT Latitude, Longitude FROM xcx_conversation WHERE Id = @Id AND IsDeleted = 0", _connection))
|
using (MySqlCommand cmd = new MySqlCommand("SELECT Latitude, Longitude FROM xcx_conversation WHERE Guid = @Guid AND IsDeleted = 0", _connection))
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue("@Id", request.Id);
|
cmd.Parameters.AddWithValue("@Guid", request.Guid);
|
||||||
|
|
||||||
using (var reader = await cmd.ExecuteReaderAsync())
|
using (var reader = await cmd.ExecuteReaderAsync())
|
||||||
{
|
{
|
||||||
@@ -230,9 +230,9 @@ namespace WxCheckApi.Controllers
|
|||||||
var address = await ConvertCoordinatesToAddress(longitude, latitude);
|
var address = await ConvertCoordinatesToAddress(longitude, latitude);
|
||||||
|
|
||||||
// 更新数据库中的UserLocation字段
|
// 更新数据库中的UserLocation字段
|
||||||
using (MySqlCommand cmd = new MySqlCommand("UPDATE xcx_conversation SET UserLocation = @UserLocation WHERE Id = @Id AND IsDeleted = 0", _connection))
|
using (MySqlCommand cmd = new MySqlCommand("UPDATE xcx_conversation SET UserLocation = @UserLocation WHERE Guid = @Guid AND IsDeleted = 0", _connection))
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue("@Id", request.Id);
|
cmd.Parameters.AddWithValue("@Guid", request.Guid);
|
||||||
cmd.Parameters.AddWithValue("@UserLocation", address);
|
cmd.Parameters.AddWithValue("@UserLocation", address);
|
||||||
|
|
||||||
int rowsAffected = await cmd.ExecuteNonQueryAsync();
|
int rowsAffected = await cmd.ExecuteNonQueryAsync();
|
||||||
@@ -261,6 +261,7 @@ namespace WxCheckApi.Controllers
|
|||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<IActionResult> AddConversation([FromBody] ConversationRequest request)
|
public async Task<IActionResult> AddConversation([FromBody] ConversationRequest request)
|
||||||
{
|
{
|
||||||
|
DateTime nowtime = DateTime.Now;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_connection.State != ConnectionState.Open)
|
if (_connection.State != ConnectionState.Open)
|
||||||
@@ -288,8 +289,10 @@ namespace WxCheckApi.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 生成GUID
|
||||||
|
string conversationGuid = string.IsNullOrEmpty(request.Guid) ? Guid.NewGuid().ToString("N") : request.Guid;
|
||||||
long conversationId = 0;
|
long conversationId = 0;
|
||||||
using (MySqlCommand cmd = new MySqlCommand("INSERT INTO xcx_conversation (UserKey, ConversationContent, SendMethod, UserLocation, Latitude, Longitude, RecordTime, RecordTimeUTCStamp, IsDeleted, CreateTime, MessageType) VALUES (@UserKey, @ConversationContent, @SendMethod, @UserLocation, @Latitude, @Longitude, @RecordTime, @RecordTimeUTCStamp, @IsDeleted, NOW(), @MessageType); SELECT LAST_INSERT_ID();", _connection))
|
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("@UserKey", request.UserKey);
|
||||||
cmd.Parameters.AddWithValue("@MessageType", request.MessageType);
|
cmd.Parameters.AddWithValue("@MessageType", request.MessageType);
|
||||||
@@ -298,9 +301,12 @@ namespace WxCheckApi.Controllers
|
|||||||
cmd.Parameters.AddWithValue("@UserLocation", address);
|
cmd.Parameters.AddWithValue("@UserLocation", address);
|
||||||
cmd.Parameters.AddWithValue("@Latitude", latitude);
|
cmd.Parameters.AddWithValue("@Latitude", latitude);
|
||||||
cmd.Parameters.AddWithValue("@Longitude", longitude);
|
cmd.Parameters.AddWithValue("@Longitude", longitude);
|
||||||
cmd.Parameters.AddWithValue("@RecordTime", DateTime.Now);
|
cmd.Parameters.AddWithValue("@RecordTime", nowtime);
|
||||||
|
cmd.Parameters.AddWithValue("@CreateTime", nowtime);
|
||||||
cmd.Parameters.AddWithValue("@RecordTimeUTCStamp", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
|
cmd.Parameters.AddWithValue("@RecordTimeUTCStamp", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
|
||||||
cmd.Parameters.AddWithValue("@IsDeleted", 0);
|
cmd.Parameters.AddWithValue("@IsDeleted", 0);
|
||||||
|
cmd.Parameters.AddWithValue("@Guid", conversationGuid);
|
||||||
|
cmd.Parameters.AddWithValue("@SpeakingTime", request.SpeakingTime);
|
||||||
|
|
||||||
object result = await cmd.ExecuteScalarAsync();
|
object result = await cmd.ExecuteScalarAsync();
|
||||||
conversationId = Convert.ToInt64(result);
|
conversationId = Convert.ToInt64(result);
|
||||||
@@ -309,18 +315,17 @@ namespace WxCheckApi.Controllers
|
|||||||
// 查询刚插入的记录,并左连接用户表
|
// 查询刚插入的记录,并左连接用户表
|
||||||
if (conversationId > 0)
|
if (conversationId > 0)
|
||||||
{
|
{
|
||||||
string query = @"SELECT convs.Id, convs.UserKey, convs.ConversationContent, convs.SendMethod,
|
string query = @"SELECT convs.Id, convs.Guid, convs.UserKey, convs.ConversationContent, convs.SendMethod,
|
||||||
convs.UserLocation, convs.Latitude, convs.Longitude, convs.RecordTime,
|
convs.UserLocation, convs.Latitude, convs.Longitude, convs.RecordTime,
|
||||||
convs.RecordTimeUTCStamp, convs.IsDeleted, convs.CreateTime, convs.MessageType,
|
convs.RecordTimeUTCStamp, convs.IsDeleted, convs.CreateTime, convs.MessageType, convs.SpeakingTime,
|
||||||
users.UserName, users.WeChatName, users.PhoneNumber, users.AvatarUrl
|
users.UserName, users.WeChatName, users.PhoneNumber, users.AvatarUrl
|
||||||
FROM xcx_conversation AS convs
|
FROM xcx_conversation AS convs
|
||||||
LEFT JOIN xcx_users AS users ON convs.UserKey = users.UserKey
|
LEFT JOIN xcx_users AS users ON convs.UserKey = users.UserKey
|
||||||
WHERE convs.Id = @Id";
|
WHERE convs.Guid = @Guid";
|
||||||
|
|
||||||
using (MySqlCommand cmd = new MySqlCommand(query, _connection))
|
using (MySqlCommand cmd = new MySqlCommand(query, _connection))
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue("@Id", conversationId);
|
cmd.Parameters.AddWithValue("@Guid", conversationGuid);
|
||||||
|
|
||||||
using (var reader = await cmd.ExecuteReaderAsync())
|
using (var reader = await cmd.ExecuteReaderAsync())
|
||||||
{
|
{
|
||||||
if (await reader.ReadAsync())
|
if (await reader.ReadAsync())
|
||||||
@@ -329,21 +334,23 @@ namespace WxCheckApi.Controllers
|
|||||||
var messageData = new Dictionary<string, string>
|
var messageData = new Dictionary<string, string>
|
||||||
{
|
{
|
||||||
["Id"] = reader.GetInt64(0).ToString(),
|
["Id"] = reader.GetInt64(0).ToString(),
|
||||||
["UserKey"] = reader.GetString(1),
|
["Guid"] = reader.IsDBNull(1) ? "" : reader.GetString(1),
|
||||||
["ConversationContent"] = reader.GetString(2),
|
["UserKey"] = reader.GetString(2),
|
||||||
["SendMethod"] = reader.GetString(3),
|
["ConversationContent"] = reader.GetString(3),
|
||||||
["UserLocation"] = reader.IsDBNull(4) ? "" : reader.GetString(4),
|
["SendMethod"] = reader.GetString(4),
|
||||||
["Latitude"] = reader.IsDBNull(5) ? "" : reader.GetString(5),
|
["UserLocation"] = reader.IsDBNull(5) ? "" : reader.GetString(5),
|
||||||
["Longitude"] = reader.IsDBNull(6) ? "" : reader.GetString(6),
|
["Latitude"] = reader.IsDBNull(6) ? "" : reader.GetString(6),
|
||||||
["RecordTime"] = reader.GetDateTime(7).ToString("yyyy-MM-dd HH:mm:ss"),
|
["Longitude"] = reader.IsDBNull(7) ? "" : reader.GetString(7),
|
||||||
["RecordTimeUTCStamp"] = reader.GetInt64(8).ToString(),
|
["RecordTime"] = reader.GetDateTime(8).ToString("yyyy-MM-dd HH:mm:ss"),
|
||||||
["IsDeleted"] = reader.GetBoolean(9).ToString(),
|
["RecordTimeUTCStamp"] = reader.GetInt64(9).ToString(),
|
||||||
["CreateTime"] = reader.GetDateTime(10).ToString("yyyy-MM-dd HH:mm:ss"),
|
["IsDeleted"] = reader.GetBoolean(10).ToString(),
|
||||||
["MessageType"] = reader.GetInt32(11).ToString(),
|
["CreateTime"] = reader.GetDateTime(11).ToString("yyyy-MM-dd HH:mm:ss"),
|
||||||
["UserName"] = reader.IsDBNull(12) ? "" : reader.GetString(12),
|
["MessageType"] = reader.GetInt32(12).ToString(),
|
||||||
["WeChatName"] = reader.IsDBNull(13) ? "" : reader.GetString(13),
|
["SpeakingTime"] = reader.IsDBNull(13) ? "" : reader.GetInt32(13).ToString(),
|
||||||
["PhoneNumber"] = reader.IsDBNull(14) ? "" : reader.GetString(14),
|
["UserName"] = reader.IsDBNull(14) ? "" : reader.GetString(14),
|
||||||
["AvatarUrl"] = reader.IsDBNull(15) ? "" : reader.GetString(15)
|
["WeChatName"] = reader.IsDBNull(15) ? "" : reader.GetString(15),
|
||||||
|
["PhoneNumber"] = reader.IsDBNull(16) ? "" : reader.GetString(16),
|
||||||
|
["AvatarUrl"] = reader.IsDBNull(17) ? "" : reader.GetString(17)
|
||||||
};
|
};
|
||||||
|
|
||||||
// 发送到Redis Stream
|
// 发送到Redis Stream
|
||||||
@@ -371,7 +378,7 @@ namespace WxCheckApi.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(new { success = true, message = "收到!", conversationId = conversationId });
|
return Ok(new { success = true, message = "收到!", conversationGuid, receivedTime = nowtime.ToString("yyyy-MM-dd HH:mm:ss") });
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -400,7 +407,7 @@ namespace WxCheckApi.Controllers
|
|||||||
List<ConversationResponse> conversations = new List<ConversationResponse>();
|
List<ConversationResponse> conversations = new List<ConversationResponse>();
|
||||||
|
|
||||||
// 构建查询SQL,根据MessageType参数决定是否添加过滤条件
|
// 构建查询SQL,根据MessageType参数决定是否添加过滤条件
|
||||||
string query = "SELECT Id, UserKey, ConversationContent, SendMethod, UserLocation, Latitude, Longitude, RecordTime, RecordTimeUTCStamp, IsDeleted, CreateTime, MessageType FROM xcx_conversation WHERE UserKey = @UserKey AND IsDeleted = 0";
|
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)
|
if (request.MessageType == 1)
|
||||||
{
|
{
|
||||||
query += " AND MessageType = @MessageType";
|
query += " AND MessageType = @MessageType";
|
||||||
@@ -418,17 +425,19 @@ namespace WxCheckApi.Controllers
|
|||||||
conversations.Add(new ConversationResponse
|
conversations.Add(new ConversationResponse
|
||||||
{
|
{
|
||||||
Id = reader.GetInt64(0),
|
Id = reader.GetInt64(0),
|
||||||
UserKey = reader.GetString(1),
|
Guid = reader.IsDBNull(1) ? "" : reader.GetString(1),
|
||||||
ConversationContent = reader.GetString(2),
|
UserKey = reader.GetString(2),
|
||||||
SendMethod = reader.GetString(3),
|
ConversationContent = reader.GetString(3),
|
||||||
UserLocation = reader.IsDBNull(4) ? "" : reader.GetString(4),
|
SendMethod = reader.GetString(4),
|
||||||
Latitude = reader.IsDBNull(5) ? "" : reader.GetString(5),
|
UserLocation = reader.IsDBNull(5) ? "" : reader.GetString(5),
|
||||||
Longitude = reader.IsDBNull(6) ? "" : reader.GetString(6),
|
Latitude = reader.IsDBNull(6) ? "" : reader.GetString(6),
|
||||||
RecordTime = reader.GetDateTime(7),
|
Longitude = reader.IsDBNull(7) ? "" : reader.GetString(7),
|
||||||
RecordTimeUTCStamp = reader.GetInt64(8),
|
RecordTime = reader.GetDateTime(8),
|
||||||
IsDeleted = reader.GetBoolean(9),
|
RecordTimeUTCStamp = reader.GetInt64(9),
|
||||||
CreateTime = reader.GetDateTime(10),
|
IsDeleted = reader.GetBoolean(10),
|
||||||
MessageType = reader.GetInt32(11)
|
CreateTime = reader.GetDateTime(11),
|
||||||
|
MessageType = reader.GetInt32(12),
|
||||||
|
SpeakingTime = reader.IsDBNull(13) ? null : reader.GetInt32(13)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -460,14 +469,16 @@ namespace WxCheckApi.Controllers
|
|||||||
await _connection.OpenAsync();
|
await _connection.OpenAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
using (MySqlCommand cmd = new MySqlCommand("UPDATE xcx_conversation SET ConversationContent = @ConversationContent, SendMethod = @SendMethod, UserLocation = @UserLocation, MessageType = @MessageType WHERE Id = @Id AND UserKey = @UserKey", _connection))
|
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("@Id", request.Id);
|
cmd.Parameters.AddWithValue("@Guid", request.Guid);
|
||||||
cmd.Parameters.AddWithValue("@UserKey", request.UserKey);
|
cmd.Parameters.AddWithValue("@UserKey", request.UserKey);
|
||||||
cmd.Parameters.AddWithValue("@ConversationContent", request.ConversationContent);
|
cmd.Parameters.AddWithValue("@ConversationContent", request.ConversationContent);
|
||||||
cmd.Parameters.AddWithValue("@SendMethod", request.SendMethod);
|
cmd.Parameters.AddWithValue("@SendMethod", request.SendMethod);
|
||||||
cmd.Parameters.AddWithValue("@UserLocation", request.UserLocation ?? "");
|
cmd.Parameters.AddWithValue("@UserLocation", request.UserLocation ?? "");
|
||||||
cmd.Parameters.AddWithValue("@MessageType", request.MessageType);
|
cmd.Parameters.AddWithValue("@MessageType", request.MessageType);
|
||||||
|
cmd.Parameters.AddWithValue("@RecordTime", nowtime);
|
||||||
|
|
||||||
int rowsAffected = await cmd.ExecuteNonQueryAsync();
|
int rowsAffected = await cmd.ExecuteNonQueryAsync();
|
||||||
|
|
||||||
@@ -477,7 +488,7 @@ namespace WxCheckApi.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(new { success = true, message = "更新成功" });
|
return Ok(new { success = true, message = "更新成功" , receivedTime = nowtime.ToString("yyyy-MM-dd HH:mm:ss") });
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -503,9 +514,9 @@ namespace WxCheckApi.Controllers
|
|||||||
await _connection.OpenAsync();
|
await _connection.OpenAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
using (MySqlCommand cmd = new MySqlCommand("UPDATE xcx_conversation SET IsDeleted = 1 WHERE Id = @Id AND UserKey = @UserKey AND IsDeleted = 0", _connection))
|
using (MySqlCommand cmd = new MySqlCommand("UPDATE xcx_conversation SET IsDeleted = 1 WHERE Guid = @Guid AND UserKey = @UserKey AND IsDeleted = 0", _connection))
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue("@Id", request.Id);
|
cmd.Parameters.AddWithValue("@Guid", request.Guid);
|
||||||
cmd.Parameters.AddWithValue("@UserKey", request.UserKey);
|
cmd.Parameters.AddWithValue("@UserKey", request.UserKey);
|
||||||
|
|
||||||
int rowsAffected = await cmd.ExecuteNonQueryAsync();
|
int rowsAffected = await cmd.ExecuteNonQueryAsync();
|
||||||
@@ -530,6 +541,70 @@ namespace WxCheckApi.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 根据GUID查询会话记录(不考虑IsDeleted状态)
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> 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]
|
[HttpPost]
|
||||||
@@ -551,7 +626,7 @@ namespace WxCheckApi.Controllers
|
|||||||
List<ConversationResponse> conversations = new List<ConversationResponse>();
|
List<ConversationResponse> conversations = new List<ConversationResponse>();
|
||||||
|
|
||||||
// 构建分页查询SQL,根据MessageType参数决定是否添加过滤条件
|
// 构建分页查询SQL,根据MessageType参数决定是否添加过滤条件
|
||||||
string query = @"SELECT Id, UserKey, ConversationContent, SendMethod, UserLocation, Latitude, Longitude, RecordTime, RecordTimeUTCStamp, IsDeleted, CreateTime, MessageType
|
string query = @"SELECT Id, Guid, UserKey, ConversationContent, SendMethod, UserLocation, Latitude, Longitude, RecordTime, RecordTimeUTCStamp, IsDeleted, CreateTime, MessageType, SpeakingTime
|
||||||
FROM xcx_conversation
|
FROM xcx_conversation
|
||||||
WHERE UserKey = @UserKey AND IsDeleted = 0";
|
WHERE UserKey = @UserKey AND IsDeleted = 0";
|
||||||
if (request.MessageType == 1)
|
if (request.MessageType == 1)
|
||||||
@@ -577,17 +652,19 @@ namespace WxCheckApi.Controllers
|
|||||||
conversations.Add(new ConversationResponse
|
conversations.Add(new ConversationResponse
|
||||||
{
|
{
|
||||||
Id = reader.GetInt64(0),
|
Id = reader.GetInt64(0),
|
||||||
UserKey = reader.GetString(1),
|
Guid = reader.IsDBNull(1) ? "" : reader.GetString(1),
|
||||||
ConversationContent = reader.GetString(2),
|
UserKey = reader.GetString(2),
|
||||||
SendMethod = reader.GetString(3),
|
ConversationContent = reader.GetString(3),
|
||||||
UserLocation = reader.IsDBNull(4) ? "" : reader.GetString(4),
|
SendMethod = reader.GetString(4),
|
||||||
Latitude = reader.IsDBNull(5) ? "" : reader.GetString(5),
|
UserLocation = reader.IsDBNull(5) ? "" : reader.GetString(5),
|
||||||
Longitude = reader.IsDBNull(6) ? "" : reader.GetString(6),
|
Latitude = reader.IsDBNull(6) ? "" : reader.GetString(6),
|
||||||
RecordTime = reader.GetDateTime(7),
|
Longitude = reader.IsDBNull(7) ? "" : reader.GetString(7),
|
||||||
RecordTimeUTCStamp = reader.GetInt64(8),
|
RecordTime = reader.GetDateTime(8),
|
||||||
IsDeleted = reader.GetBoolean(9),
|
RecordTimeUTCStamp = reader.GetInt64(9),
|
||||||
CreateTime = reader.GetDateTime(10),
|
IsDeleted = reader.GetBoolean(10),
|
||||||
MessageType = reader.GetInt32(11)
|
CreateTime = reader.GetDateTime(11),
|
||||||
|
MessageType = reader.GetInt32(12),
|
||||||
|
SpeakingTime = reader.IsDBNull(13) ? null : reader.GetInt32(13)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -718,6 +795,8 @@ namespace WxCheckApi.Controllers
|
|||||||
public double Latitude { get; set; }
|
public double Latitude { get; set; }
|
||||||
public double Longitude { get; set; }
|
public double Longitude { get; set; }
|
||||||
public int MessageType { get; set; } = 1; // 1:公有,2:私有
|
public int MessageType { get; set; } = 1; // 1:公有,2:私有
|
||||||
|
public string? Guid { get; set; } // 会话唯一标识
|
||||||
|
public int? SpeakingTime { get; set; } // 对话时长
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UserKeyRequest
|
public class UserKeyRequest
|
||||||
@@ -736,27 +815,37 @@ namespace WxCheckApi.Controllers
|
|||||||
|
|
||||||
public class UpdateConversationRequest
|
public class UpdateConversationRequest
|
||||||
{
|
{
|
||||||
public long Id { get; set; }
|
public long? Id { get; set; }
|
||||||
|
public string Guid { get; set; } // 会话唯一标识
|
||||||
public string UserKey { get; set; }
|
public string UserKey { get; set; }
|
||||||
public string ConversationContent { get; set; }
|
public string ConversationContent { get; set; }
|
||||||
public string SendMethod { get; set; }
|
public string SendMethod { get; set; }
|
||||||
public string UserLocation { get; set; }
|
public string UserLocation { get; set; }
|
||||||
public int MessageType { get; set; } = 0;
|
public int MessageType { get; set; } = 0;
|
||||||
|
public int? SpeakingTime { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DeleteConversationRequest
|
public class DeleteConversationRequest
|
||||||
{
|
{
|
||||||
public long Id { get; set; }
|
public long? Id { get; set; }
|
||||||
|
public string Guid { get; set; } // 会话唯一标识
|
||||||
public string UserKey { get; set; }
|
public string UserKey { get; set; }
|
||||||
}
|
}
|
||||||
public class CheckAddressRequest
|
public class CheckAddressRequest
|
||||||
{
|
{
|
||||||
public long Id { get; set; }
|
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 class ConversationResponse
|
||||||
{
|
{
|
||||||
public long Id { get; set; }
|
public long Id { get; set; }
|
||||||
|
public string Guid { get; set; } // 会话唯一标识
|
||||||
public string UserKey { get; set; }
|
public string UserKey { get; set; }
|
||||||
public string ConversationContent { get; set; }
|
public string ConversationContent { get; set; }
|
||||||
public string SendMethod { get; set; }
|
public string SendMethod { get; set; }
|
||||||
@@ -768,6 +857,7 @@ namespace WxCheckApi.Controllers
|
|||||||
public bool IsDeleted { get; set; }
|
public bool IsDeleted { get; set; }
|
||||||
public DateTime CreateTime { get; set; }
|
public DateTime CreateTime { get; set; }
|
||||||
public int MessageType { get; set; } // 1:公有消息,2:私有消息
|
public int MessageType { get; set; } // 1:公有消息,2:私有消息
|
||||||
|
public int? SpeakingTime { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RedisMessageRequest
|
public class RedisMessageRequest
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ using System.Threading.Tasks;
|
|||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace WxCheckApi.Controllers
|
namespace WxCheckMvc.Controllers
|
||||||
{
|
{
|
||||||
[Route("api/[controller]/[action]")]
|
[Route("api/[controller]/[action]")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
|
|||||||
20
WxCheckApi/Properties/PublishProfiles/FolderProfile1.pubxml
Normal file
20
WxCheckApi/Properties/PublishProfiles/FolderProfile1.pubxml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
|
||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<DeleteExistingFiles>true</DeleteExistingFiles>
|
||||||
|
<ExcludeApp_Data>false</ExcludeApp_Data>
|
||||||
|
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
|
||||||
|
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
|
||||||
|
<LastUsedPlatform>Any CPU</LastUsedPlatform>
|
||||||
|
<PublishProvider>FileSystem</PublishProvider>
|
||||||
|
<PublishUrl>bin\Release\net8.0\publish\</PublishUrl>
|
||||||
|
<WebPublishMethod>FileSystem</WebPublishMethod>
|
||||||
|
<_TargetId>Folder</_TargetId>
|
||||||
|
<SiteUrlToLaunchAfterPublish />
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
|
<ProjectGuid>e545c738-a21b-71f3-9fb9-a68d8018822d</ProjectGuid>
|
||||||
|
<SelfContained>false</SelfContained>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
|
||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<_PublishTargetUrl>E:\Project_Class\WX_XCX\WxCheck_Wx_Prod\WxCheckApi\bin\Release\net8.0\publish\</_PublishTargetUrl>
|
||||||
|
<History>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||;</History>
|
||||||
|
<LastFailureDetails />
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
<Solution>
|
<Solution>
|
||||||
|
<Project Path="../WxCheckMvc/WxCheckMvc.csproj" Id="5f5aee53-ea7f-4a13-a039-d664f136a7f8" />
|
||||||
<Project Path="WxCheckApi.csproj" />
|
<Project Path="WxCheckApi.csproj" />
|
||||||
</Solution>
|
</Solution>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
Target Server Version : 120002 (12.0.2-MariaDB)
|
Target Server Version : 120002 (12.0.2-MariaDB)
|
||||||
File Encoding : 65001
|
File Encoding : 65001
|
||||||
|
|
||||||
Date: 07/11/2025 15:03:55
|
Date: 05/12/2025 11:40:09
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SET NAMES utf8mb4;
|
SET NAMES utf8mb4;
|
||||||
@@ -34,13 +34,16 @@ CREATE TABLE `xcx_conversation` (
|
|||||||
`CreateTime` datetime NULL DEFAULT current_timestamp() COMMENT '创建时间',
|
`CreateTime` datetime NULL DEFAULT current_timestamp() COMMENT '创建时间',
|
||||||
`Latitude` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL 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 '经度',
|
`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,
|
PRIMARY KEY (`Id`) USING BTREE,
|
||||||
INDEX `idx_userkey`(`UserKey` ASC) USING BTREE,
|
INDEX `idx_userkey`(`UserKey` ASC) USING BTREE,
|
||||||
INDEX `idx_utcstamp`(`RecordTimeUTCStamp` ASC) USING BTREE,
|
INDEX `idx_utcstamp`(`RecordTimeUTCStamp` ASC) USING BTREE,
|
||||||
INDEX `idx_deleted`(`IsDeleted` ASC) USING BTREE,
|
INDEX `idx_deleted`(`IsDeleted` ASC) USING BTREE,
|
||||||
INDEX `idx_recordtime`(`RecordTime` ASC) USING BTREE,
|
INDEX `idx_recordtime`(`RecordTime` ASC) USING BTREE,
|
||||||
INDEX `idx_messagetype`(`MessageType` ASC) USING BTREE
|
INDEX `idx_messagetype`(`MessageType` ASC) USING BTREE,
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 57 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会话记录表' ROW_FORMAT = Dynamic;
|
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
|
-- Table structure for xcx_log
|
||||||
@@ -78,6 +81,6 @@ CREATE TABLE `xcx_users` (
|
|||||||
UNIQUE INDEX `idx_userkey`(`UserKey` ASC) USING BTREE,
|
UNIQUE INDEX `idx_userkey`(`UserKey` ASC) USING BTREE,
|
||||||
INDEX `idx_disabled`(`IsDisabled` ASC) USING BTREE,
|
INDEX `idx_disabled`(`IsDisabled` ASC) USING BTREE,
|
||||||
INDEX `idx_logintime`(`FirstLoginTime` ASC) USING BTREE
|
INDEX `idx_logintime`(`FirstLoginTime` ASC) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '小程序用户表' ROW_FORMAT = Dynamic;
|
) ENGINE = InnoDB AUTO_INCREMENT = 22 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '小程序用户表' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
SET FOREIGN_KEY_CHECKS = 1;
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
|
|||||||
13
WxCheckMvc/.config/dotnet-tools.json
Normal file
13
WxCheckMvc/.config/dotnet-tools.json
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"isRoot": true,
|
||||||
|
"tools": {
|
||||||
|
"dotnet-ef": {
|
||||||
|
"version": "10.0.0",
|
||||||
|
"commands": [
|
||||||
|
"dotnet-ef"
|
||||||
|
],
|
||||||
|
"rollForward": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
199
WxCheckMvc/CSRedisCacheHelper.cs
Normal file
199
WxCheckMvc/CSRedisCacheHelper.cs
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
using CSRedis;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using static CSRedis.CSRedisClient;
|
||||||
|
|
||||||
|
namespace Common
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Redis缓存辅助类
|
||||||
|
/// </summary>
|
||||||
|
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<SubscribeMessageEventArgs>(async (args) =>
|
||||||
|
{
|
||||||
|
string body = args.Body;
|
||||||
|
}));
|
||||||
|
|
||||||
|
CSRedisCacheHelper.redis.Subscribe(DingYueMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 添加缓存
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
public static void Set<T>(string key, T value, int ExpireTime)
|
||||||
|
{
|
||||||
|
redis?.Set(key, value, ExpireTime * 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T Get<T>(string key)
|
||||||
|
{
|
||||||
|
return redis.Get<T>(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Forever<T>(string key, T value)
|
||||||
|
{
|
||||||
|
redis.Set(key, value, -1);
|
||||||
|
}
|
||||||
|
public static void Del(string key)
|
||||||
|
{
|
||||||
|
redis.Del(key);
|
||||||
|
}
|
||||||
|
public static void ListPush<T>(string key, T value)
|
||||||
|
{
|
||||||
|
redis.LPush(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 判断是否存在
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
|
||||||
|
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<Dictionary<string, object>>();
|
||||||
|
|
||||||
|
foreach (var streamResult in result)
|
||||||
|
{
|
||||||
|
foreach (var entry in streamResult.data)
|
||||||
|
{
|
||||||
|
var message = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发布消息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Topic"></param>
|
||||||
|
/// <param name="Payload"></param>
|
||||||
|
public static void Publish(string Topic, string Payload)
|
||||||
|
{
|
||||||
|
CSRedisCacheHelper.redis.PublishNoneMessageId(Topic, Payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
960
WxCheckMvc/Controllers/CheckController.cs
Normal file
960
WxCheckMvc/Controllers/CheckController.cs
Normal file
@@ -0,0 +1,960 @@
|
|||||||
|
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;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace WxCheckMvc.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]/[action]")]
|
||||||
|
[ApiController]
|
||||||
|
public class CheckController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly MySqlConnection _connection;
|
||||||
|
private readonly HttpClient _httpClient;
|
||||||
|
private readonly IConfiguration _configuration;
|
||||||
|
private readonly IWebHostEnvironment _environment;
|
||||||
|
|
||||||
|
public CheckController(MySqlConnection connection, IHttpClientFactory httpClientFactory, IConfiguration configuration, IWebHostEnvironment environment)
|
||||||
|
{
|
||||||
|
_connection = connection;
|
||||||
|
_httpClient = httpClientFactory.CreateClient();
|
||||||
|
_configuration = configuration;
|
||||||
|
_environment = environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> UploadFile(IFormFile file, [FromForm] string rootPathType, [FromForm] string userKey)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (file == null || file.Length == 0)
|
||||||
|
{
|
||||||
|
return BadRequest(new { success = false, message = "请选择文件" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 确定保存路径
|
||||||
|
// 默认使用 Avatar,如果传入了 rootPathType 则使用传入值
|
||||||
|
string folderName = "Avatar";
|
||||||
|
if (!string.IsNullOrWhiteSpace(rootPathType))
|
||||||
|
{
|
||||||
|
// 安全检查:只允许字母、数字、下划线,防止路径遍历
|
||||||
|
if (rootPathType.Any(c => !char.IsLetterOrDigit(c) && c != '_'))
|
||||||
|
{
|
||||||
|
return BadRequest(new { success = false, message = "rootPathType 包含非法字符,只允许字母、数字和下划线" });
|
||||||
|
}
|
||||||
|
folderName = rootPathType;
|
||||||
|
}
|
||||||
|
|
||||||
|
string webRootPath = _environment.WebRootPath;
|
||||||
|
string uploadDir = Path.Combine(webRootPath, folderName);
|
||||||
|
|
||||||
|
// 如果文件夹不存在,则创建
|
||||||
|
if (!Directory.Exists(uploadDir))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(uploadDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 生成唯一文件名并保存
|
||||||
|
string fileExtension = Path.GetExtension(file.FileName);
|
||||||
|
string newFileName = Guid.NewGuid().ToString("N") + fileExtension;
|
||||||
|
string filePath = Path.Combine(uploadDir, newFileName);
|
||||||
|
|
||||||
|
using (var stream = new FileStream(filePath, FileMode.Create))
|
||||||
|
{
|
||||||
|
await file.CopyToAsync(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建返回URL
|
||||||
|
string relativePath = $"/{folderName}/{newFileName}";
|
||||||
|
string fullUrl = $"{Request.Scheme}://{Request.Host}{relativePath}";
|
||||||
|
|
||||||
|
// 3. 如果提供了 UserKey,更新数据库中的 AvatarUrl
|
||||||
|
if (!string.IsNullOrWhiteSpace(userKey))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_connection.State != ConnectionState.Open)
|
||||||
|
{
|
||||||
|
await _connection.OpenAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
string updateSql = "UPDATE xcx_users SET AvatarUrl = @AvatarUrl, UpdateTime = NOW() WHERE UserKey = @UserKey";
|
||||||
|
using (MySqlCommand cmd = new MySqlCommand(updateSql, _connection))
|
||||||
|
{
|
||||||
|
cmd.Parameters.AddWithValue("@AvatarUrl", fullUrl);
|
||||||
|
cmd.Parameters.AddWithValue("@UserKey", userKey);
|
||||||
|
|
||||||
|
await cmd.ExecuteNonQueryAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (_connection.State == ConnectionState.Open)
|
||||||
|
{
|
||||||
|
await _connection.CloseAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(new { success = true, message = "上传成功", url = fullUrl, path = relativePath });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// 确保连接关闭
|
||||||
|
if (_connection.State == ConnectionState.Open)
|
||||||
|
{
|
||||||
|
await _connection.CloseAsync();
|
||||||
|
}
|
||||||
|
return StatusCode(500, new { success = false, message = "上传失败", error = ex.Message });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将经纬度转换为地址信息
|
||||||
|
public async Task<string> 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<IActionResult> 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<IActionResult> 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<string, string>
|
||||||
|
{
|
||||||
|
["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<IActionResult> GetConversations([FromBody] UserKeyRequest request)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_connection.State != ConnectionState.Open)
|
||||||
|
{
|
||||||
|
await _connection.OpenAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ConversationResponse> conversations = new List<ConversationResponse>();
|
||||||
|
|
||||||
|
// 构建查询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<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> 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<ConversationResponse> conversations = new List<ConversationResponse>();
|
||||||
|
|
||||||
|
// 构建分页查询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<IActionResult> 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<string>() });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析消息
|
||||||
|
var messageList = new List<object>();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var messageEntries = System.Text.Json.JsonSerializer.Deserialize<List<Dictionary<string, object>>>(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<string, string>();
|
||||||
|
|
||||||
|
// 如果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<string, string> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
32
WxCheckMvc/Controllers/HomeController.cs
Normal file
32
WxCheckMvc/Controllers/HomeController.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using WxCheckMvc.Models;
|
||||||
|
|
||||||
|
namespace WxCheckMvc.Controllers
|
||||||
|
{
|
||||||
|
public class HomeController : Controller
|
||||||
|
{
|
||||||
|
private readonly ILogger<HomeController> _logger;
|
||||||
|
|
||||||
|
public HomeController(ILogger<HomeController> logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IActionResult Index()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IActionResult Privacy()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
|
||||||
|
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||||
|
public IActionResult Error()
|
||||||
|
{
|
||||||
|
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
324
WxCheckMvc/Controllers/LoginController.cs
Normal file
324
WxCheckMvc/Controllers/LoginController.cs
Normal file
@@ -0,0 +1,324 @@
|
|||||||
|
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<string> 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<IActionResult> 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<IActionResult> 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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
9
WxCheckMvc/Models/ErrorViewModel.cs
Normal file
9
WxCheckMvc/Models/ErrorViewModel.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace WxCheckMvc.Models
|
||||||
|
{
|
||||||
|
public class ErrorViewModel
|
||||||
|
{
|
||||||
|
public string? RequestId { get; set; }
|
||||||
|
|
||||||
|
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||||
|
}
|
||||||
|
}
|
||||||
80
WxCheckMvc/Program.cs
Normal file
80
WxCheckMvc/Program.cs
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
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.AddControllersWithViews();
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD>HttpClientFactory
|
||||||
|
builder.Services.AddHttpClient();
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD><DDBF><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
builder.Services.AddScoped<MySqlConnection>(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))
|
||||||
|
{
|
||||||
|
// <20><><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD>ҵ<EFBFBD> token ͷ<><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Authorization ͷ<><CDB7>
|
||||||
|
token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
|
||||||
|
}
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD> token<65><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD> HttpContext <20><>
|
||||||
|
if (!string.IsNullOrEmpty(token))
|
||||||
|
{
|
||||||
|
context.Token = token;
|
||||||
|
}
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
// Configure the HTTP request pipeline.
|
||||||
|
if (!app.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseExceptionHandler("/Home/Error");
|
||||||
|
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
||||||
|
app.UseHsts();
|
||||||
|
}
|
||||||
|
|
||||||
|
app.UseHttpsRedirection();
|
||||||
|
app.UseStaticFiles();
|
||||||
|
|
||||||
|
app.UseRouting();
|
||||||
|
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
app.MapControllerRoute(
|
||||||
|
name: "default",
|
||||||
|
pattern: "{controller=Home}/{action=Index}/{id?}");
|
||||||
|
|
||||||
|
app.Run();
|
||||||
20
WxCheckMvc/Properties/PublishProfiles/FolderProfile.pubxml
Normal file
20
WxCheckMvc/Properties/PublishProfiles/FolderProfile.pubxml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
|
||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<DeleteExistingFiles>true</DeleteExistingFiles>
|
||||||
|
<ExcludeApp_Data>false</ExcludeApp_Data>
|
||||||
|
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
|
||||||
|
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
|
||||||
|
<LastUsedPlatform>Any CPU</LastUsedPlatform>
|
||||||
|
<PublishProvider>FileSystem</PublishProvider>
|
||||||
|
<PublishUrl>bin\Release\net8.0\publish\</PublishUrl>
|
||||||
|
<WebPublishMethod>FileSystem</WebPublishMethod>
|
||||||
|
<_TargetId>Folder</_TargetId>
|
||||||
|
<SiteUrlToLaunchAfterPublish />
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
|
<ProjectGuid>5f5aee53-ea7f-4a13-a039-d664f136a7f8</ProjectGuid>
|
||||||
|
<SelfContained>false</SelfContained>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
|
||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<_PublishTargetUrl>E:\Project_Class\WX_XCX\WxCheck_Wx_Prod\WxCheckMvc\bin\Release\net8.0\publish\</_PublishTargetUrl>
|
||||||
|
<History>True|2025-12-05T10:56:51.7439135Z||;True|2025-12-05T17:44:11.4130698+08:00||;</History>
|
||||||
|
<LastFailureDetails />
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
38
WxCheckMvc/Properties/launchSettings.json
Normal file
38
WxCheckMvc/Properties/launchSettings.json
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:13325",
|
||||||
|
"sslPort": 44342
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"applicationUrl": "http://localhost:5141",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"https": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"applicationUrl": "https://localhost:7233;http://localhost:5141",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
WxCheckMvc/Views/Home/Index.cshtml
Normal file
8
WxCheckMvc/Views/Home/Index.cshtml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
@{
|
||||||
|
ViewData["Title"] = "Home Page";
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<h1 class="display-4">Welcome</h1>
|
||||||
|
<p>Learn about <a href="https://learn.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
|
||||||
|
</div>
|
||||||
6
WxCheckMvc/Views/Home/Privacy.cshtml
Normal file
6
WxCheckMvc/Views/Home/Privacy.cshtml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
@{
|
||||||
|
ViewData["Title"] = "Privacy Policy";
|
||||||
|
}
|
||||||
|
<h1>@ViewData["Title"]</h1>
|
||||||
|
|
||||||
|
<p>Use this page to detail your site's privacy policy.</p>
|
||||||
25
WxCheckMvc/Views/Shared/Error.cshtml
Normal file
25
WxCheckMvc/Views/Shared/Error.cshtml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
@model ErrorViewModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Error";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h1 class="text-danger">Error.</h1>
|
||||||
|
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||||
|
|
||||||
|
@if (Model.ShowRequestId)
|
||||||
|
{
|
||||||
|
<p>
|
||||||
|
<strong>Request ID:</strong> <code>@Model.RequestId</code>
|
||||||
|
</p>
|
||||||
|
}
|
||||||
|
|
||||||
|
<h3>Development Mode</h3>
|
||||||
|
<p>
|
||||||
|
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
|
||||||
|
It can result in displaying sensitive information from exceptions to end users.
|
||||||
|
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
|
||||||
|
and restarting the app.
|
||||||
|
</p>
|
||||||
49
WxCheckMvc/Views/Shared/_Layout.cshtml
Normal file
49
WxCheckMvc/Views/Shared/_Layout.cshtml
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>@ViewData["Title"] - WxCheckMvc</title>
|
||||||
|
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
|
||||||
|
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
|
||||||
|
<link rel="stylesheet" href="~/WxCheckMvc.styles.css" asp-append-version="true" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">WxCheckMvc</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
|
||||||
|
aria-expanded="false" aria-label="Toggle navigation">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
|
||||||
|
<ul class="navbar-nav flex-grow-1">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
<div class="container">
|
||||||
|
<main role="main" class="pb-3">
|
||||||
|
@RenderBody()
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="border-top footer text-muted">
|
||||||
|
<div class="container">
|
||||||
|
© 2025 - WxCheckMvc - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
<script src="~/lib/jquery/dist/jquery.min.js"></script>
|
||||||
|
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script src="~/js/site.js" asp-append-version="true"></script>
|
||||||
|
@await RenderSectionAsync("Scripts", required: false)
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
48
WxCheckMvc/Views/Shared/_Layout.cshtml.css
Normal file
48
WxCheckMvc/Views/Shared/_Layout.cshtml.css
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/* Please see documentation at https://learn.microsoft.com/aspnet/core/client-side/bundling-and-minification
|
||||||
|
for details on configuring this project to bundle and minify static web assets. */
|
||||||
|
|
||||||
|
a.navbar-brand {
|
||||||
|
white-space: normal;
|
||||||
|
text-align: center;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #0077cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #1b6ec2;
|
||||||
|
border-color: #1861ac;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-pills .nav-link.active, .nav-pills .show > .nav-link {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #1b6ec2;
|
||||||
|
border-color: #1861ac;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-top {
|
||||||
|
border-top: 1px solid #e5e5e5;
|
||||||
|
}
|
||||||
|
.border-bottom {
|
||||||
|
border-bottom: 1px solid #e5e5e5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-shadow {
|
||||||
|
box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
|
||||||
|
}
|
||||||
|
|
||||||
|
button.accept-policy {
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
white-space: nowrap;
|
||||||
|
line-height: 60px;
|
||||||
|
}
|
||||||
2
WxCheckMvc/Views/Shared/_ValidationScriptsPartial.cshtml
Normal file
2
WxCheckMvc/Views/Shared/_ValidationScriptsPartial.cshtml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
|
||||||
|
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
|
||||||
3
WxCheckMvc/Views/_ViewImports.cshtml
Normal file
3
WxCheckMvc/Views/_ViewImports.cshtml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
@using WxCheckMvc
|
||||||
|
@using WxCheckMvc.Models
|
||||||
|
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
3
WxCheckMvc/Views/_ViewStart.cshtml
Normal file
3
WxCheckMvc/Views/_ViewStart.cshtml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
@{
|
||||||
|
Layout = "_Layout";
|
||||||
|
}
|
||||||
16
WxCheckMvc/WxCheckMvc.csproj
Normal file
16
WxCheckMvc/WxCheckMvc.csproj
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="CSRedisCore" Version="3.8.807" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.22" />
|
||||||
|
<PackageReference Include="MySql.Data" Version="8.4.0" />
|
||||||
|
<PackageReference Include="System.Text.Json" Version="8.0.6" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
7
WxCheckMvc/WxCheckMvc.csproj.user
Normal file
7
WxCheckMvc/WxCheckMvc.csproj.user
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ActiveDebugProfile>https</ActiveDebugProfile>
|
||||||
|
<NameOfLastUsedPublishProfile>E:\Project_Class\WX_XCX\WxCheck_Wx_Prod\WxCheckMvc\Properties\PublishProfiles\FolderProfile.pubxml</NameOfLastUsedPublishProfile>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
24
WxCheckMvc/WxCheckMvc.sln
Normal file
24
WxCheckMvc/WxCheckMvc.sln
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.5.2.0
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WxCheckMvc", "WxCheckMvc.csproj", "{DB5FCFC7-0359-F923-6D06-09CD18BA5F14}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{DB5FCFC7-0359-F923-6D06-09CD18BA5F14}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{DB5FCFC7-0359-F923-6D06-09CD18BA5F14}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{DB5FCFC7-0359-F923-6D06-09CD18BA5F14}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{DB5FCFC7-0359-F923-6D06-09CD18BA5F14}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {B93F140C-6356-4EF1-9849-4C37778126C2}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
8
WxCheckMvc/appsettings.Development.json
Normal file
8
WxCheckMvc/appsettings.Development.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
WxCheckMvc/appsettings.json
Normal file
25
WxCheckMvc/appsettings.json
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
BIN
WxCheckMvc/bin/Debug/net8.0/BouncyCastle.Cryptography.dll
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/BouncyCastle.Cryptography.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Debug/net8.0/CSRedisCore.dll
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/CSRedisCore.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Debug/net8.0/Google.Protobuf.dll
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/Google.Protobuf.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Debug/net8.0/K4os.Compression.LZ4.Streams.dll
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/K4os.Compression.LZ4.Streams.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Debug/net8.0/K4os.Compression.LZ4.dll
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/K4os.Compression.LZ4.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Debug/net8.0/K4os.Hash.xxHash.dll
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/K4os.Hash.xxHash.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
WxCheckMvc/bin/Debug/net8.0/Microsoft.IdentityModel.Logging.dll
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/Microsoft.IdentityModel.Logging.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
WxCheckMvc/bin/Debug/net8.0/Microsoft.IdentityModel.Tokens.dll
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/Microsoft.IdentityModel.Tokens.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Debug/net8.0/Microsoft.Win32.SystemEvents.dll
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/Microsoft.Win32.SystemEvents.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Debug/net8.0/MySql.Data.dll
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/MySql.Data.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Debug/net8.0/Newtonsoft.Json.dll
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/Newtonsoft.Json.dll
Normal file
Binary file not shown.
Binary file not shown.
BIN
WxCheckMvc/bin/Debug/net8.0/System.Drawing.Common.dll
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/System.Drawing.Common.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Debug/net8.0/System.IdentityModel.Tokens.Jwt.dll
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/System.IdentityModel.Tokens.Jwt.dll
Normal file
Binary file not shown.
Binary file not shown.
BIN
WxCheckMvc/bin/Debug/net8.0/System.Security.Permissions.dll
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/System.Security.Permissions.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Debug/net8.0/System.Windows.Extensions.dll
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/System.Windows.Extensions.dll
Normal file
Binary file not shown.
489
WxCheckMvc/bin/Debug/net8.0/WxCheckMvc.deps.json
Normal file
489
WxCheckMvc/bin/Debug/net8.0/WxCheckMvc.deps.json
Normal file
@@ -0,0 +1,489 @@
|
|||||||
|
{
|
||||||
|
"runtimeTarget": {
|
||||||
|
"name": ".NETCoreApp,Version=v8.0",
|
||||||
|
"signature": ""
|
||||||
|
},
|
||||||
|
"compilationOptions": {},
|
||||||
|
"targets": {
|
||||||
|
".NETCoreApp,Version=v8.0": {
|
||||||
|
"WxCheckMvc/1.0.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"CSRedisCore": "3.8.807",
|
||||||
|
"Microsoft.AspNetCore.Authentication.JwtBearer": "8.0.22",
|
||||||
|
"MySql.Data": "8.4.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"WxCheckMvc.dll": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"BouncyCastle.Cryptography/2.2.1": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/net6.0/BouncyCastle.Cryptography.dll": {
|
||||||
|
"assemblyVersion": "2.0.0.0",
|
||||||
|
"fileVersion": "2.2.1.47552"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"CSRedisCore/3.8.807": {
|
||||||
|
"dependencies": {
|
||||||
|
"Newtonsoft.Json": "13.0.1"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard2.0/CSRedisCore.dll": {
|
||||||
|
"assemblyVersion": "3.8.807.0",
|
||||||
|
"fileVersion": "3.8.807.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Google.Protobuf/3.25.1": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/net5.0/Google.Protobuf.dll": {
|
||||||
|
"assemblyVersion": "3.25.1.0",
|
||||||
|
"fileVersion": "3.25.1.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"K4os.Compression.LZ4/1.3.5": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/net6.0/K4os.Compression.LZ4.dll": {
|
||||||
|
"assemblyVersion": "1.3.5.0",
|
||||||
|
"fileVersion": "1.3.5.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"K4os.Compression.LZ4.Streams/1.3.5": {
|
||||||
|
"dependencies": {
|
||||||
|
"K4os.Compression.LZ4": "1.3.5",
|
||||||
|
"K4os.Hash.xxHash": "1.0.8"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net6.0/K4os.Compression.LZ4.Streams.dll": {
|
||||||
|
"assemblyVersion": "1.3.5.0",
|
||||||
|
"fileVersion": "1.3.5.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"K4os.Hash.xxHash/1.0.8": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/net6.0/K4os.Hash.xxHash.dll": {
|
||||||
|
"assemblyVersion": "1.0.8.0",
|
||||||
|
"fileVersion": "1.0.8.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.AspNetCore.Authentication.JwtBearer/8.0.22": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "7.1.2"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Microsoft.AspNetCore.Authentication.JwtBearer.dll": {
|
||||||
|
"assemblyVersion": "8.0.22.0",
|
||||||
|
"fileVersion": "8.0.2225.52808"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.IdentityModel.Abstractions/7.1.2": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Microsoft.IdentityModel.Abstractions.dll": {
|
||||||
|
"assemblyVersion": "7.1.2.0",
|
||||||
|
"fileVersion": "7.1.2.41121"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.IdentityModel.JsonWebTokens/7.1.2": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.IdentityModel.Tokens": "7.1.2"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Microsoft.IdentityModel.JsonWebTokens.dll": {
|
||||||
|
"assemblyVersion": "7.1.2.0",
|
||||||
|
"fileVersion": "7.1.2.41121"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.IdentityModel.Logging/7.1.2": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.IdentityModel.Abstractions": "7.1.2"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Microsoft.IdentityModel.Logging.dll": {
|
||||||
|
"assemblyVersion": "7.1.2.0",
|
||||||
|
"fileVersion": "7.1.2.41121"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.IdentityModel.Protocols/7.1.2": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.IdentityModel.Logging": "7.1.2",
|
||||||
|
"Microsoft.IdentityModel.Tokens": "7.1.2"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Microsoft.IdentityModel.Protocols.dll": {
|
||||||
|
"assemblyVersion": "7.1.2.0",
|
||||||
|
"fileVersion": "7.1.2.41121"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.IdentityModel.Protocols.OpenIdConnect/7.1.2": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.IdentityModel.Protocols": "7.1.2",
|
||||||
|
"System.IdentityModel.Tokens.Jwt": "7.1.2"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Microsoft.IdentityModel.Protocols.OpenIdConnect.dll": {
|
||||||
|
"assemblyVersion": "7.1.2.0",
|
||||||
|
"fileVersion": "7.1.2.41121"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.IdentityModel.Tokens/7.1.2": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.IdentityModel.Logging": "7.1.2"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/Microsoft.IdentityModel.Tokens.dll": {
|
||||||
|
"assemblyVersion": "7.1.2.0",
|
||||||
|
"fileVersion": "7.1.2.41121"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.Win32.SystemEvents/4.7.0": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard2.0/Microsoft.Win32.SystemEvents.dll": {
|
||||||
|
"assemblyVersion": "4.0.2.0",
|
||||||
|
"fileVersion": "4.700.19.56404"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtimeTargets": {
|
||||||
|
"runtimes/win/lib/netcoreapp3.0/Microsoft.Win32.SystemEvents.dll": {
|
||||||
|
"rid": "win",
|
||||||
|
"assetType": "runtime",
|
||||||
|
"assemblyVersion": "4.0.2.0",
|
||||||
|
"fileVersion": "4.700.19.56404"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"MySql.Data/8.4.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"BouncyCastle.Cryptography": "2.2.1",
|
||||||
|
"Google.Protobuf": "3.25.1",
|
||||||
|
"K4os.Compression.LZ4.Streams": "1.3.5",
|
||||||
|
"System.Configuration.ConfigurationManager": "4.4.1",
|
||||||
|
"System.Security.Permissions": "4.7.0",
|
||||||
|
"ZstdSharp.Port": "0.7.1"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/MySql.Data.dll": {
|
||||||
|
"assemblyVersion": "8.4.0.0",
|
||||||
|
"fileVersion": "8.4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtimeTargets": {
|
||||||
|
"runtimes/win-x64/native/comerr64.dll": {
|
||||||
|
"rid": "win-x64",
|
||||||
|
"assetType": "native",
|
||||||
|
"fileVersion": "4.1.0.0"
|
||||||
|
},
|
||||||
|
"runtimes/win-x64/native/gssapi64.dll": {
|
||||||
|
"rid": "win-x64",
|
||||||
|
"assetType": "native",
|
||||||
|
"fileVersion": "4.1.0.0"
|
||||||
|
},
|
||||||
|
"runtimes/win-x64/native/k5sprt64.dll": {
|
||||||
|
"rid": "win-x64",
|
||||||
|
"assetType": "native",
|
||||||
|
"fileVersion": "4.1.0.0"
|
||||||
|
},
|
||||||
|
"runtimes/win-x64/native/krb5_64.dll": {
|
||||||
|
"rid": "win-x64",
|
||||||
|
"assetType": "native",
|
||||||
|
"fileVersion": "4.1.0.0"
|
||||||
|
},
|
||||||
|
"runtimes/win-x64/native/krbcc64.dll": {
|
||||||
|
"rid": "win-x64",
|
||||||
|
"assetType": "native",
|
||||||
|
"fileVersion": "4.1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Newtonsoft.Json/13.0.1": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard2.0/Newtonsoft.Json.dll": {
|
||||||
|
"assemblyVersion": "13.0.0.0",
|
||||||
|
"fileVersion": "13.0.1.25517"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Configuration.ConfigurationManager/4.4.1": {
|
||||||
|
"dependencies": {
|
||||||
|
"System.Security.Cryptography.ProtectedData": "4.4.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard2.0/System.Configuration.ConfigurationManager.dll": {
|
||||||
|
"assemblyVersion": "4.0.0.0",
|
||||||
|
"fileVersion": "4.6.25921.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Drawing.Common/4.7.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.Win32.SystemEvents": "4.7.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard2.0/System.Drawing.Common.dll": {
|
||||||
|
"assemblyVersion": "4.0.0.1",
|
||||||
|
"fileVersion": "4.6.26919.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtimeTargets": {
|
||||||
|
"runtimes/unix/lib/netcoreapp3.0/System.Drawing.Common.dll": {
|
||||||
|
"rid": "unix",
|
||||||
|
"assetType": "runtime",
|
||||||
|
"assemblyVersion": "4.0.2.0",
|
||||||
|
"fileVersion": "4.700.19.56404"
|
||||||
|
},
|
||||||
|
"runtimes/win/lib/netcoreapp3.0/System.Drawing.Common.dll": {
|
||||||
|
"rid": "win",
|
||||||
|
"assetType": "runtime",
|
||||||
|
"assemblyVersion": "4.0.2.0",
|
||||||
|
"fileVersion": "4.700.19.56404"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.IdentityModel.Tokens.Jwt/7.1.2": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.IdentityModel.JsonWebTokens": "7.1.2",
|
||||||
|
"Microsoft.IdentityModel.Tokens": "7.1.2"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net8.0/System.IdentityModel.Tokens.Jwt.dll": {
|
||||||
|
"assemblyVersion": "7.1.2.0",
|
||||||
|
"fileVersion": "7.1.2.41121"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Security.Cryptography.ProtectedData/4.4.0": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard2.0/System.Security.Cryptography.ProtectedData.dll": {
|
||||||
|
"assemblyVersion": "4.0.2.0",
|
||||||
|
"fileVersion": "4.6.25519.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtimeTargets": {
|
||||||
|
"runtimes/win/lib/netstandard2.0/System.Security.Cryptography.ProtectedData.dll": {
|
||||||
|
"rid": "win",
|
||||||
|
"assetType": "runtime",
|
||||||
|
"assemblyVersion": "4.0.2.0",
|
||||||
|
"fileVersion": "4.6.25519.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Security.Permissions/4.7.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"System.Windows.Extensions": "4.7.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/netcoreapp3.0/System.Security.Permissions.dll": {
|
||||||
|
"assemblyVersion": "4.0.3.0",
|
||||||
|
"fileVersion": "4.700.19.56404"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Windows.Extensions/4.7.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"System.Drawing.Common": "4.7.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/netcoreapp3.0/System.Windows.Extensions.dll": {
|
||||||
|
"assemblyVersion": "4.0.1.0",
|
||||||
|
"fileVersion": "4.700.19.56404"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtimeTargets": {
|
||||||
|
"runtimes/win/lib/netcoreapp3.0/System.Windows.Extensions.dll": {
|
||||||
|
"rid": "win",
|
||||||
|
"assetType": "runtime",
|
||||||
|
"assemblyVersion": "4.0.1.0",
|
||||||
|
"fileVersion": "4.700.19.56404"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ZstdSharp.Port/0.7.1": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/net7.0/ZstdSharp.dll": {
|
||||||
|
"assemblyVersion": "0.7.1.0",
|
||||||
|
"fileVersion": "0.7.1.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"libraries": {
|
||||||
|
"WxCheckMvc/1.0.0": {
|
||||||
|
"type": "project",
|
||||||
|
"serviceable": false,
|
||||||
|
"sha512": ""
|
||||||
|
},
|
||||||
|
"BouncyCastle.Cryptography/2.2.1": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-A6Zr52zVqJKt18ZBsTnX0qhG0kwIQftVAjLmszmkiR/trSp8H+xj1gUOzk7XHwaKgyREMSV1v9XaKrBUeIOdvQ==",
|
||||||
|
"path": "bouncycastle.cryptography/2.2.1",
|
||||||
|
"hashPath": "bouncycastle.cryptography.2.2.1.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"CSRedisCore/3.8.807": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-fu0ZGIRdq1q0dZR+ecJxajfdLiRNWBR+UKx9Ob43rSwPQT/9duIJ8DLThkDjlx/0CHtX8oktv3rYAHS/mIy8bw==",
|
||||||
|
"path": "csrediscore/3.8.807",
|
||||||
|
"hashPath": "csrediscore.3.8.807.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Google.Protobuf/3.25.1": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-Sw9bq4hOD+AaS3RrnmP5IT25cyZ/T1qpM0e8+G+23Nojhv7+ScJFPEAQo1m4EFQWhXoI4FRZDrK+wjHCPw9yxg==",
|
||||||
|
"path": "google.protobuf/3.25.1",
|
||||||
|
"hashPath": "google.protobuf.3.25.1.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"K4os.Compression.LZ4/1.3.5": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-TS4mqlT0X1OlnvOGNfl02QdVUhuqgWuCnn7UxupIa7C9Pb6qlQ5yZA2sPhRh0OSmVULaQU64KV4wJuu//UyVQQ==",
|
||||||
|
"path": "k4os.compression.lz4/1.3.5",
|
||||||
|
"hashPath": "k4os.compression.lz4.1.3.5.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"K4os.Compression.LZ4.Streams/1.3.5": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-M0NufZI8ym3mm6F6HMSPz1jw7TJGdY74fjAtbIXATmnAva/8xLz50eQZJI9tf9mMeHUaFDg76N1BmEh8GR5zeA==",
|
||||||
|
"path": "k4os.compression.lz4.streams/1.3.5",
|
||||||
|
"hashPath": "k4os.compression.lz4.streams.1.3.5.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"K4os.Hash.xxHash/1.0.8": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-Wp2F7BamQ2Q/7Hk834nV9vRQapgcr8kgv9Jvfm8J3D0IhDqZMMl+a2yxUq5ltJitvXvQfB8W6K4F4fCbw/P6YQ==",
|
||||||
|
"path": "k4os.hash.xxhash/1.0.8",
|
||||||
|
"hashPath": "k4os.hash.xxhash.1.0.8.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.AspNetCore.Authentication.JwtBearer/8.0.22": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-3lqhBK+t4u8Ajl2je5UC9jCoDI+8zLz/YBVjwxQKfFF9NyzACf4QQmlmKnpH/LdkVSxCjLwvJ1ko4k0EAgy8cg==",
|
||||||
|
"path": "microsoft.aspnetcore.authentication.jwtbearer/8.0.22",
|
||||||
|
"hashPath": "microsoft.aspnetcore.authentication.jwtbearer.8.0.22.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.IdentityModel.Abstractions/7.1.2": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-33eTIA2uO/L9utJjZWbKsMSVsQf7F8vtd6q5mQX7ZJzNvCpci5fleD6AeANGlbbb7WX7XKxq9+Dkb5e3GNDrmQ==",
|
||||||
|
"path": "microsoft.identitymodel.abstractions/7.1.2",
|
||||||
|
"hashPath": "microsoft.identitymodel.abstractions.7.1.2.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.IdentityModel.JsonWebTokens/7.1.2": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-cloLGeZolXbCJhJBc5OC05uhrdhdPL6MWHuVUnkkUvPDeK7HkwThBaLZ1XjBQVk9YhxXE2OvHXnKi0PLleXxDg==",
|
||||||
|
"path": "microsoft.identitymodel.jsonwebtokens/7.1.2",
|
||||||
|
"hashPath": "microsoft.identitymodel.jsonwebtokens.7.1.2.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.IdentityModel.Logging/7.1.2": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-YCxBt2EeJP8fcXk9desChkWI+0vFqFLvBwrz5hBMsoh0KJE6BC66DnzkdzkJNqMltLromc52dkdT206jJ38cTw==",
|
||||||
|
"path": "microsoft.identitymodel.logging/7.1.2",
|
||||||
|
"hashPath": "microsoft.identitymodel.logging.7.1.2.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.IdentityModel.Protocols/7.1.2": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-SydLwMRFx6EHPWJ+N6+MVaoArN1Htt92b935O3RUWPY1yUF63zEjvd3lBu79eWdZUwedP8TN2I5V9T3nackvIQ==",
|
||||||
|
"path": "microsoft.identitymodel.protocols/7.1.2",
|
||||||
|
"hashPath": "microsoft.identitymodel.protocols.7.1.2.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.IdentityModel.Protocols.OpenIdConnect/7.1.2": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-6lHQoLXhnMQ42mGrfDkzbIOR3rzKM1W1tgTeMPLgLCqwwGw0d96xFi/UiX/fYsu7d6cD5MJiL3+4HuI8VU+sVQ==",
|
||||||
|
"path": "microsoft.identitymodel.protocols.openidconnect/7.1.2",
|
||||||
|
"hashPath": "microsoft.identitymodel.protocols.openidconnect.7.1.2.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.IdentityModel.Tokens/7.1.2": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-oICJMqr3aNEDZOwnH5SK49bR6Z4aX0zEAnOLuhloumOSuqnNq+GWBdQyrgILnlcT5xj09xKCP/7Y7gJYB+ls/g==",
|
||||||
|
"path": "microsoft.identitymodel.tokens/7.1.2",
|
||||||
|
"hashPath": "microsoft.identitymodel.tokens.7.1.2.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Microsoft.Win32.SystemEvents/4.7.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-mtVirZr++rq+XCDITMUdnETD59XoeMxSpLRIII7JRI6Yj0LEDiO1pPn0ktlnIj12Ix8bfvQqQDMMIF9wC98oCA==",
|
||||||
|
"path": "microsoft.win32.systemevents/4.7.0",
|
||||||
|
"hashPath": "microsoft.win32.systemevents.4.7.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"MySql.Data/8.4.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-NA273x7ybutfGwGbF2cd8rLVM5t7AkZCzRHr/+tGms1FeMlfl+LgfjHXcb5qN1QxFpeNQQKZ+vqZw8v/S8gUiA==",
|
||||||
|
"path": "mysql.data/8.4.0",
|
||||||
|
"hashPath": "mysql.data.8.4.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Newtonsoft.Json/13.0.1": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==",
|
||||||
|
"path": "newtonsoft.json/13.0.1",
|
||||||
|
"hashPath": "newtonsoft.json.13.0.1.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"System.Configuration.ConfigurationManager/4.4.1": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-jz3TWKMAeuDEyrPCK5Jyt4bzQcmzUIMcY9Ud6PkElFxTfnsihV+9N/UCqvxe1z5gc7jMYAnj7V1COMS9QKIuHQ==",
|
||||||
|
"path": "system.configuration.configurationmanager/4.4.1",
|
||||||
|
"hashPath": "system.configuration.configurationmanager.4.4.1.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"System.Drawing.Common/4.7.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-v+XbyYHaZjDfn0ENmJEV1VYLgGgCTx1gnfOBcppowbpOAriglYgGCvFCPr2EEZyBvXlpxbEsTwkOlInl107ahA==",
|
||||||
|
"path": "system.drawing.common/4.7.0",
|
||||||
|
"hashPath": "system.drawing.common.4.7.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"System.IdentityModel.Tokens.Jwt/7.1.2": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-Thhbe1peAmtSBFaV/ohtykXiZSOkx59Da44hvtWfIMFofDA3M3LaVyjstACf2rKGn4dEDR2cUpRAZ0Xs/zB+7Q==",
|
||||||
|
"path": "system.identitymodel.tokens.jwt/7.1.2",
|
||||||
|
"hashPath": "system.identitymodel.tokens.jwt.7.1.2.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"System.Security.Cryptography.ProtectedData/4.4.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-cJV7ScGW7EhatRsjehfvvYVBvtiSMKgN8bOVI0bQhnF5bU7vnHVIsH49Kva7i7GWaWYvmEzkYVk1TC+gZYBEog==",
|
||||||
|
"path": "system.security.cryptography.protecteddata/4.4.0",
|
||||||
|
"hashPath": "system.security.cryptography.protecteddata.4.4.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"System.Security.Permissions/4.7.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-dkOV6YYVBnYRa15/yv004eCGRBVADXw8qRbbNiCn/XpdJSUXkkUeIvdvFHkvnko4CdKMqG8yRHC4ox83LSlMsQ==",
|
||||||
|
"path": "system.security.permissions/4.7.0",
|
||||||
|
"hashPath": "system.security.permissions.4.7.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"System.Windows.Extensions/4.7.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-CeWTdRNfRaSh0pm2gDTJFwVaXfTq6Xwv/sA887iwPTneW7oMtMlpvDIO+U60+3GWTB7Aom6oQwv5VZVUhQRdPQ==",
|
||||||
|
"path": "system.windows.extensions/4.7.0",
|
||||||
|
"hashPath": "system.windows.extensions.4.7.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"ZstdSharp.Port/0.7.1": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-Idgg+mJEyAujqDPzA3APy9dNoyw0YQcNA65GgYjktDRtJ+nvx/hv+J+m6Eax3JJMGEYGy04oc5YNP6ZvQ3Y1vQ==",
|
||||||
|
"path": "zstdsharp.port/0.7.1",
|
||||||
|
"hashPath": "zstdsharp.port.0.7.1.nupkg.sha512"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
WxCheckMvc/bin/Debug/net8.0/WxCheckMvc.dll
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/WxCheckMvc.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Debug/net8.0/WxCheckMvc.exe
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/WxCheckMvc.exe
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Debug/net8.0/WxCheckMvc.pdb
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/WxCheckMvc.pdb
Normal file
Binary file not shown.
19
WxCheckMvc/bin/Debug/net8.0/WxCheckMvc.runtimeconfig.json
Normal file
19
WxCheckMvc/bin/Debug/net8.0/WxCheckMvc.runtimeconfig.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"runtimeOptions": {
|
||||||
|
"tfm": "net8.0",
|
||||||
|
"frameworks": [
|
||||||
|
{
|
||||||
|
"name": "Microsoft.NETCore.App",
|
||||||
|
"version": "8.0.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Microsoft.AspNetCore.App",
|
||||||
|
"version": "8.0.0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"configProperties": {
|
||||||
|
"System.GC.Server": true,
|
||||||
|
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
WxCheckMvc/bin/Debug/net8.0/ZstdSharp.dll
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/ZstdSharp.dll
Normal file
Binary file not shown.
8
WxCheckMvc/bin/Debug/net8.0/appsettings.Development.json
Normal file
8
WxCheckMvc/bin/Debug/net8.0/appsettings.Development.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
WxCheckMvc/bin/Debug/net8.0/appsettings.json
Normal file
9
WxCheckMvc/bin/Debug/net8.0/appsettings.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*"
|
||||||
|
}
|
||||||
Binary file not shown.
BIN
WxCheckMvc/bin/Debug/net8.0/runtimes/win-x64/native/comerr64.dll
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/runtimes/win-x64/native/comerr64.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Debug/net8.0/runtimes/win-x64/native/gssapi64.dll
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/runtimes/win-x64/native/gssapi64.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Debug/net8.0/runtimes/win-x64/native/k5sprt64.dll
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/runtimes/win-x64/native/k5sprt64.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Debug/net8.0/runtimes/win-x64/native/krb5_64.dll
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/runtimes/win-x64/native/krb5_64.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Debug/net8.0/runtimes/win-x64/native/krbcc64.dll
Normal file
BIN
WxCheckMvc/bin/Debug/net8.0/runtimes/win-x64/native/krbcc64.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
WxCheckMvc/bin/Release/net8.0/BouncyCastle.Cryptography.dll
Normal file
BIN
WxCheckMvc/bin/Release/net8.0/BouncyCastle.Cryptography.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Release/net8.0/CSRedisCore.dll
Normal file
BIN
WxCheckMvc/bin/Release/net8.0/CSRedisCore.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Release/net8.0/Google.Protobuf.dll
Normal file
BIN
WxCheckMvc/bin/Release/net8.0/Google.Protobuf.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Release/net8.0/K4os.Compression.LZ4.Streams.dll
Normal file
BIN
WxCheckMvc/bin/Release/net8.0/K4os.Compression.LZ4.Streams.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Release/net8.0/K4os.Compression.LZ4.dll
Normal file
BIN
WxCheckMvc/bin/Release/net8.0/K4os.Compression.LZ4.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Release/net8.0/K4os.Hash.xxHash.dll
Normal file
BIN
WxCheckMvc/bin/Release/net8.0/K4os.Hash.xxHash.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
WxCheckMvc/bin/Release/net8.0/Microsoft.IdentityModel.Tokens.dll
Normal file
BIN
WxCheckMvc/bin/Release/net8.0/Microsoft.IdentityModel.Tokens.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Release/net8.0/Microsoft.Win32.SystemEvents.dll
Normal file
BIN
WxCheckMvc/bin/Release/net8.0/Microsoft.Win32.SystemEvents.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Release/net8.0/MySql.Data.dll
Normal file
BIN
WxCheckMvc/bin/Release/net8.0/MySql.Data.dll
Normal file
Binary file not shown.
BIN
WxCheckMvc/bin/Release/net8.0/Newtonsoft.Json.dll
Normal file
BIN
WxCheckMvc/bin/Release/net8.0/Newtonsoft.Json.dll
Normal file
Binary file not shown.
Binary file not shown.
BIN
WxCheckMvc/bin/Release/net8.0/System.Drawing.Common.dll
Normal file
BIN
WxCheckMvc/bin/Release/net8.0/System.Drawing.Common.dll
Normal file
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user