短报文教学
This commit is contained in:
1
.eslintignore
Normal file
1
.eslintignore
Normal file
@@ -0,0 +1 @@
|
|||||||
|
coverage
|
||||||
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
logs/
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
|
node_modules/
|
||||||
|
*-lock.json
|
||||||
|
*-lock.yaml
|
||||||
|
yarn.lock
|
||||||
|
coverage/
|
||||||
|
.idea/
|
||||||
|
run/
|
||||||
|
.DS_Store
|
||||||
|
*.sw*
|
||||||
|
*.un~
|
||||||
|
typings/
|
||||||
|
.nyc_output/
|
||||||
10
.sequelizerc
Normal file
10
.sequelizerc
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
"config": path.join(__dirname, 'database/config.json'),
|
||||||
|
'migrations-path': path.join(__dirname, 'database/migrations'),
|
||||||
|
'seeders-path': path.join(__dirname, 'database/seeders'),
|
||||||
|
'models-path': path.join(__dirname, 'app/model'),
|
||||||
|
};
|
||||||
31
README.md
Normal file
31
README.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# open-map-assistant
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## QuickStart
|
||||||
|
|
||||||
|
<!-- add docs here for user -->
|
||||||
|
|
||||||
|
see [egg docs][egg] for more detail.
|
||||||
|
|
||||||
|
### Development
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm i
|
||||||
|
npm run dev
|
||||||
|
open http://localhost:7001/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deploy
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm start
|
||||||
|
npm stop
|
||||||
|
```
|
||||||
|
|
||||||
|
### npm scripts
|
||||||
|
|
||||||
|
- Use `npm run lint` to check code style.
|
||||||
|
- Use `npm test` to run unit test.
|
||||||
|
|
||||||
|
[egg]: https://eggjs.org
|
||||||
96
app/controller/home.js
Normal file
96
app/controller/home.js
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
const BaseController = require('../core/base_controller.js');
|
||||||
|
|
||||||
|
const fileName = "home";
|
||||||
|
|
||||||
|
class HomeController extends BaseController {
|
||||||
|
// token状态查询接口
|
||||||
|
async tokenStatus() {
|
||||||
|
const { ctx } = this;
|
||||||
|
try {
|
||||||
|
const uid = this.decryptRequest(ctx.request.body.uid).split('?')[0];
|
||||||
|
let rdmcode = await this.checkUid(ctx, uid);
|
||||||
|
if (!rdmcode) {
|
||||||
|
this.setResponse(ctx, 401, 'token 过期或错误', "none");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const result = await ctx.service.home.tokenStatus(uid);
|
||||||
|
if (result == "error") {
|
||||||
|
this.setResponse(ctx, 500, '服务器错误', "none");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (result) {
|
||||||
|
this.setResponse(ctx, 200, 'token 状态查询成功', "deconstruction", result);
|
||||||
|
} else {
|
||||||
|
this.setResponse(ctx, 404, 'token 状态查询失败', "none");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
const blockName = fileName + "--" + "tokenStatus";
|
||||||
|
ctx.app.middleware.log('../../controllerLog', blockName + ">>>>" + error);
|
||||||
|
this.setResponse(ctx, 500, '服务器错误', "none");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用户获取短期token的接口
|
||||||
|
async getUserToken() {
|
||||||
|
const { ctx } = this;
|
||||||
|
try {
|
||||||
|
const uid = this.decryptRequest(ctx.request.body.uid).split('?')[0];
|
||||||
|
if (uid == "") {
|
||||||
|
this.setResponse(ctx, 404, '获取临时 token 失败', "none");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let rdmcode = await this.checkUid(ctx);
|
||||||
|
if (!rdmcode) {
|
||||||
|
this.setResponse(ctx, 401, 'token 过期或错误', "none");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const result = await ctx.service.home.getUserToken(uid);
|
||||||
|
if (result == "error") {
|
||||||
|
this.setResponse(ctx, 500, '服务器错误', "none");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (result) {
|
||||||
|
this.setResponse(ctx, 200, '获取临时 token 成功', "none");
|
||||||
|
} else {
|
||||||
|
this.setResponse(ctx, 404, '获取临时 token 失败', "none");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
const blockName = fileName + "--" + "getUserToken";
|
||||||
|
ctx.app.middleware.log('../../controllerLog', blockName + ">>>>" + error);
|
||||||
|
this.setResponse(ctx, 500, '服务器错误', "none");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用户延续短期token有效时间的接口
|
||||||
|
async lifeHold() {
|
||||||
|
const { ctx } = this;
|
||||||
|
try {
|
||||||
|
const uid = this.decryptRequest(ctx.request.body.uid).split('?')[0];
|
||||||
|
if (uid == "") {
|
||||||
|
this.setResponse(ctx, 404, '延续临时 token 有效时间失败', "none");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let rdmcode = await this.checkUid(ctx);
|
||||||
|
if (!rdmcode) {
|
||||||
|
this.setResponse(ctx, 401, 'token 过期或错误', "none");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const result = await ctx.service.home.lifeHold(uid);
|
||||||
|
if (result == "error") {
|
||||||
|
this.setResponse(ctx, 500, '服务器错误', "none");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (result) {
|
||||||
|
this.setResponse(ctx, 200, '延续临时 token 有效时间成功', "none");
|
||||||
|
} else {
|
||||||
|
this.setResponse(ctx, 404, '延续临时 token 有效时间失败', "none");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
const blockName = fileName + "--" + "lifeHold";
|
||||||
|
ctx.app.middleware.log('../../controllerLog', blockName + ">>>>" + error);
|
||||||
|
this.setResponse(ctx, 500, '服务器错误', "none");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = HomeController;
|
||||||
73
app/controller/teaching.js
Normal file
73
app/controller/teaching.js
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
const BaseController = require('../core/base_controller.js');
|
||||||
|
|
||||||
|
const fileName = "teaching";
|
||||||
|
|
||||||
|
class TeachingController extends BaseController {
|
||||||
|
// 获取最近发送的一条信息
|
||||||
|
async getMsg() {
|
||||||
|
const { ctx } = this;
|
||||||
|
try {
|
||||||
|
const redis = ctx.app.redis;
|
||||||
|
const token = ctx.request.query.token;
|
||||||
|
this.banManager(redis, token);
|
||||||
|
const result = await ctx.service.teaching.getMsg(redis, token);
|
||||||
|
if (result == "error") {
|
||||||
|
this.setResponse(ctx, 500, '服务器错误', "none");
|
||||||
|
} else if (result.code == 401) {
|
||||||
|
this.setResponse(ctx, 't401', 'token 过期或错误', "none");
|
||||||
|
} else if (result.code == 403) {
|
||||||
|
this.setResponse(ctx, 403, '此 token 已进入黑名单,请等待解封后再使用', "none");
|
||||||
|
} else if (result.code == 200) {
|
||||||
|
delete result.code;
|
||||||
|
const data = {
|
||||||
|
userData: result.userData,
|
||||||
|
responseTime: new Date()
|
||||||
|
};
|
||||||
|
this.setResponse(ctx, 200, '最近消息查询成功', "deconstruction", data);
|
||||||
|
} else {
|
||||||
|
this.setResponse(ctx, 404, '最近消息查询失败', "none");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
const blockName = fileName + "--" + "getMsg";
|
||||||
|
ctx.app.middleware.log('../../controllerLog', blockName + ">>>>" + error);
|
||||||
|
this.setResponse(ctx, 500, '服务器错误', "none");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取若干条历史消息
|
||||||
|
async getHistory() {
|
||||||
|
const { ctx } = this;
|
||||||
|
try {
|
||||||
|
const redis = ctx.app.redis;
|
||||||
|
const { token, limit, offset } = ctx.request.query;
|
||||||
|
this.banManager(redis, token);
|
||||||
|
const result = await ctx.service.teaching.getHistory(redis, token, limit, offset);
|
||||||
|
if (result == "error") {
|
||||||
|
this.setResponse(ctx, 500, '服务器错误', "none");
|
||||||
|
} else if (result.code == 401) {
|
||||||
|
this.setResponse(ctx, 't401', 'token 过期或错误', "none");
|
||||||
|
} else if (result.code == 403) {
|
||||||
|
this.setResponse(ctx, 403, '此 token 已进入黑名单,请等待解封后再使用', "none");
|
||||||
|
} else if (result.code == 200) {
|
||||||
|
delete result.code;
|
||||||
|
let historyMsg = [];
|
||||||
|
result.userData.rows.forEach(element => {
|
||||||
|
historyMsg.push(element.dataValues);
|
||||||
|
});
|
||||||
|
const data = {
|
||||||
|
userData: historyMsg,
|
||||||
|
total: result.userData.count
|
||||||
|
};
|
||||||
|
this.setResponse(ctx, 200, '历史消息查询成功', "deconstruction", data);
|
||||||
|
} else {
|
||||||
|
this.setResponse(ctx, 404, '历史消息查询失败', "none");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
const blockName = fileName + "--" + "getHistory";
|
||||||
|
ctx.app.middleware.log('../../controllerLog', blockName + ">>>>" + error);
|
||||||
|
this.setResponse(ctx, 500, '服务器错误', "none");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = TeachingController;
|
||||||
110
app/core/base_controller.js
Normal file
110
app/core/base_controller.js
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
const { Controller } = require('egg');
|
||||||
|
|
||||||
|
const sha256 = require("crypto-js/sha256");
|
||||||
|
|
||||||
|
const CryptoJS = require("crypto-js");
|
||||||
|
|
||||||
|
const KEY = CryptoJS.enc.Utf8.parse('BDQH');
|
||||||
|
|
||||||
|
class BaseController extends Controller {
|
||||||
|
shaForm = (body, salt) => {
|
||||||
|
return sha256(sha256(body).toString() + salt).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
encryptRequest = (body) => {
|
||||||
|
return CryptoJS.AES.encrypt(body, KEY, {
|
||||||
|
mode: CryptoJS.mode.ECB,
|
||||||
|
padding: CryptoJS.pad.Pkcs7
|
||||||
|
}).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
decryptRequest = (body) => {
|
||||||
|
return CryptoJS.AES.decrypt(body, KEY, {
|
||||||
|
mode: CryptoJS.mode.ECB,
|
||||||
|
padding: CryptoJS.pad.Pkcs7
|
||||||
|
}).toString(CryptoJS.enc.Utf8);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkUid = async (ctx, uid) => {
|
||||||
|
const token = ctx.request.header.authorization;
|
||||||
|
const redis = ctx.app.redis;
|
||||||
|
let rdmcode;
|
||||||
|
if (!uid) {
|
||||||
|
const [buser, cuser] = await Promise.all([
|
||||||
|
redis.get('db0').get(token),
|
||||||
|
redis.get('db1').get(token),
|
||||||
|
]);
|
||||||
|
rdmcode = buser || cuser;
|
||||||
|
} else {
|
||||||
|
const redisType = {
|
||||||
|
"B": "db0",
|
||||||
|
"C": "db1"
|
||||||
|
};
|
||||||
|
const lastCode = uid[uid.length - 1];
|
||||||
|
rdmcode = await redis.get(redisType[lastCode]).get(token);
|
||||||
|
}
|
||||||
|
if (!rdmcode) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return rdmcode;
|
||||||
|
};
|
||||||
|
|
||||||
|
setResponse = (ctx, code, msg, model, data = {}) => {
|
||||||
|
const modelType = {
|
||||||
|
"none": { code, msg },
|
||||||
|
"deconstruction": { code, msg, ...data },
|
||||||
|
"polymerization": { code, msg, data }
|
||||||
|
}
|
||||||
|
ctx.body = modelType[model];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 黑名单管理器
|
||||||
|
banManager = async (redis, token) => {
|
||||||
|
// 基本元素
|
||||||
|
const now = new Date().getTime();
|
||||||
|
let reex = 1209600;
|
||||||
|
let tokenContainer = await redis.get('db4').get('tokenContainer');
|
||||||
|
let tokenCheck = await redis.get('db4').get(token);
|
||||||
|
let ex = await redis.get('db4').ttl(token);
|
||||||
|
tokenCheck = JSON.parse(tokenCheck);
|
||||||
|
// 判断存放教学接口 token 的容器是否存在,不存在则创建并设置过期时间
|
||||||
|
if (!tokenContainer == null) {
|
||||||
|
reex = await redis.get('db4').ttl('tokenContainer');
|
||||||
|
if (reex <= 600) {
|
||||||
|
reex = 1209600;
|
||||||
|
await redis.get('db4').set('tokenContainer', JSON.stringify(JSON.parse(tokenContainer)), 'EX', reex);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let createContainer = {};
|
||||||
|
createContainer[token] = { num: 1, firstTime: now };
|
||||||
|
await redis.get('db4').set('tokenContainer', JSON.stringify(createContainer), 'EX', reex);
|
||||||
|
}
|
||||||
|
tokenContainer = JSON.parse(tokenContainer);
|
||||||
|
if (tokenContainer !== null && tokenCheck !== null) {
|
||||||
|
// 黑名单回收器
|
||||||
|
for (let item in tokenContainer) {
|
||||||
|
if (tokenContainer[item].firstTime < now - 1000) {
|
||||||
|
delete tokenContainer[item];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 黑名单释放器
|
||||||
|
if (tokenCheck.attacksMark && now - tokenCheck.banAt > 3600000) {
|
||||||
|
await redis.get('db4').set(token, JSON.stringify({ uid: tokenCheck.uid, attacksMark: false }), 'EX', ex);
|
||||||
|
}
|
||||||
|
// 黑名单检查器
|
||||||
|
if (!tokenContainer[token]) {
|
||||||
|
tokenContainer[token] = { num: 1, firstTime: now }
|
||||||
|
} else {
|
||||||
|
tokenContainer[token].num += 1;
|
||||||
|
if (tokenContainer[token].num > 10) {
|
||||||
|
delete tokenContainer[token];
|
||||||
|
// 黑名单标记器
|
||||||
|
await redis.get('db4').set(token, JSON.stringify({ uid: tokenCheck.uid, attacksMark: true, banAt: now }), 'EX', ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await redis.get('db4').set('tokenContainer', JSON.stringify(tokenContainer), 'EX', reex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = BaseController;
|
||||||
85
app/core/base_service.js
Normal file
85
app/core/base_service.js
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
const { Service } = require('egg');
|
||||||
|
|
||||||
|
const sha256 = require("crypto-js/sha256");
|
||||||
|
|
||||||
|
const CryptoJS = require("crypto-js");
|
||||||
|
|
||||||
|
const KEY = CryptoJS.enc.Utf8.parse('BDQH');
|
||||||
|
|
||||||
|
class BaseService extends Service {
|
||||||
|
shaForm = (body, salt) => {
|
||||||
|
return sha256(sha256(body).toString() + salt).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
encryptRequest = (body) => {
|
||||||
|
return CryptoJS.AES.encrypt(body, KEY, {
|
||||||
|
mode: CryptoJS.mode.ECB,
|
||||||
|
padding: CryptoJS.pad.Pkcs7
|
||||||
|
}).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
decryptRequest = (body) => {
|
||||||
|
return CryptoJS.AES.decrypt(body, KEY, {
|
||||||
|
mode: CryptoJS.mode.ECB,
|
||||||
|
padding: CryptoJS.pad.Pkcs7
|
||||||
|
}).toString(CryptoJS.enc.Utf8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 随机盐生成函数
|
||||||
|
generateRandomString = () => {
|
||||||
|
const lowerCaseLetters = 'abcdefghijklmnopqrstuvwxyz';
|
||||||
|
const upperCaseLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||||
|
const numbers = '0123456789';
|
||||||
|
|
||||||
|
let result = '';
|
||||||
|
|
||||||
|
// 生成5位随机小写字母
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
const randomIndex = Math.floor(Math.random() * lowerCaseLetters.length);
|
||||||
|
result += lowerCaseLetters[randomIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成5位随机大写字母
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
const randomIndex = Math.floor(Math.random() * upperCaseLetters.length);
|
||||||
|
result += upperCaseLetters[randomIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成2位随机数字
|
||||||
|
for (let i = 0; i < 2; i++) {
|
||||||
|
const randomIndex = Math.floor(Math.random() * numbers.length);
|
||||||
|
result += numbers[randomIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打乱整个字符串
|
||||||
|
const characters = result.split('');
|
||||||
|
for (let i = characters.length - 1; i > 0; i--) {
|
||||||
|
const j = Math.floor(Math.random() * (i + 1));
|
||||||
|
[characters[i], characters[j]] = [characters[j], characters[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return characters.join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 教学接口 token 验证,验证 token 是否存在,是否在黑名单中
|
||||||
|
Verify = async (redis, teachingToken) => {
|
||||||
|
const token = await redis.get('db4').get(teachingToken);
|
||||||
|
if (!token) {
|
||||||
|
return 401;
|
||||||
|
} else if (JSON.parse(token).attacksMark) {
|
||||||
|
return 403;
|
||||||
|
}
|
||||||
|
return JSON.parse(token).uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
shunt = (uid) => {
|
||||||
|
return uid[uid.length - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
isAllDigits = (str) => {
|
||||||
|
const regex = /^\d+$/;
|
||||||
|
return regex.test(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = BaseService;
|
||||||
72
app/middleware/log.js
Normal file
72
app/middleware/log.js
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
// 错误日志
|
||||||
|
const fs = require('fs');
|
||||||
|
const os = require('os');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const dirCheck = (dirPath) => {
|
||||||
|
// 检查文件夹是否存在
|
||||||
|
fs.access(dirPath, fs.constants.F_OK, (err) => {
|
||||||
|
if (err) {
|
||||||
|
// 文件夹不存在
|
||||||
|
console.log('文件夹不存在,正在创建...');
|
||||||
|
fs.mkdir(dirPath, { recursive: true }, (err) => {
|
||||||
|
if (err) throw err;
|
||||||
|
console.log('文件夹已创建');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 文件夹存在
|
||||||
|
console.log('文件夹已存在');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = (filePath, msg) => {
|
||||||
|
// 获取时间
|
||||||
|
let now = new Date(),
|
||||||
|
times = {
|
||||||
|
year: now.getFullYear(),
|
||||||
|
month: now.getMonth() + 1,
|
||||||
|
day: now.getDate(),
|
||||||
|
hour: now.getHours(),
|
||||||
|
minute: now.getMinutes(),
|
||||||
|
second: now.getSeconds()
|
||||||
|
};
|
||||||
|
// 获取操作系统类型
|
||||||
|
const type = os.type();
|
||||||
|
console.log(`操作系统类型: ${type}`);
|
||||||
|
filePath = path.join(__dirname, filePath);
|
||||||
|
dirCheck(filePath);
|
||||||
|
const yearPath = filePath + '/' + times.year;
|
||||||
|
dirCheck(yearPath);
|
||||||
|
const monthPath = yearPath + '/' + times.month;
|
||||||
|
dirCheck(monthPath);
|
||||||
|
const dayPath = monthPath + '/' + times.day + '.txt';
|
||||||
|
const logTime = '[' + times.year + '-' + times.month + '-' + times.day + '>>>' + times.hour + ':' + times.minute + ':' + times.second + ']' + '>>>';
|
||||||
|
let crlf;
|
||||||
|
// 判断操作系统类型,设置换行符
|
||||||
|
if (type === 'Windows_NT') {
|
||||||
|
crlf = '\n';
|
||||||
|
} else {
|
||||||
|
crlf = '\r\n';
|
||||||
|
}
|
||||||
|
// 读取文件内容
|
||||||
|
fs.readFile(dayPath, 'utf8', (err, data) => {
|
||||||
|
if (err) {
|
||||||
|
if (err.code === 'ENOENT') {
|
||||||
|
// 文件不存在,直接写入新内容(这里实际上还是使用了覆盖的方式)
|
||||||
|
fs.writeFile(dayPath, logTime + msg + crlf, (err) => {
|
||||||
|
if (err) throw err;
|
||||||
|
console.log('文件已创建并写入新内容');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 文件存在,追加新内容
|
||||||
|
fs.appendFile(dayPath, logTime + msg + crlf, (err) => {
|
||||||
|
if (err) throw err;
|
||||||
|
console.log('新内容已追加到文件');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
24
app/model/BShortMsg.js
Normal file
24
app/model/BShortMsg.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = (app) => {
|
||||||
|
const { INTEGER, CHAR, TEXT, DATE } = app.Sequelize;
|
||||||
|
|
||||||
|
const BShortMsg = app.model.define('bshort-msg', {
|
||||||
|
id: { type: INTEGER(11), primaryKey: true, autoIncrement: true },
|
||||||
|
user_uid: CHAR(15),
|
||||||
|
card_id: CHAR(8),
|
||||||
|
receiver_address: CHAR(8),
|
||||||
|
original_msg: TEXT,
|
||||||
|
send_type: INTEGER(1),
|
||||||
|
encode_type: INTEGER(1),
|
||||||
|
msg_data: TEXT,
|
||||||
|
created_at: DATE,
|
||||||
|
},{
|
||||||
|
freezeTableName: true,
|
||||||
|
timestamp: true,
|
||||||
|
createdAt: true,
|
||||||
|
updatedAt: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
return BShortMsg;
|
||||||
|
};
|
||||||
18
app/model/BuserToken.js
Normal file
18
app/model/BuserToken.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = (app) => {
|
||||||
|
const { INTEGER, CHAR } = app.Sequelize;
|
||||||
|
|
||||||
|
const BuserToken = app.model.define('buser-token', {
|
||||||
|
id: { type: INTEGER(8), primaryKey: true, autoIncrement: true },
|
||||||
|
user_uid: CHAR(15),
|
||||||
|
token: CHAR(64),
|
||||||
|
},{
|
||||||
|
freezeTableName: true,
|
||||||
|
timestamp: false,
|
||||||
|
createdAt: false,
|
||||||
|
updatedAt: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
return BuserToken;
|
||||||
|
};
|
||||||
24
app/model2/CShortMsg.js
Normal file
24
app/model2/CShortMsg.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = (app) => {
|
||||||
|
const { INTEGER, CHAR, TEXT, DATE } = app.Sequelize;
|
||||||
|
|
||||||
|
const CShortMsg = app.model2.define('cshort-msg', {
|
||||||
|
id: { type: INTEGER(11), primaryKey: true, autoIncrement: true },
|
||||||
|
user_uid: CHAR(15),
|
||||||
|
card_id: CHAR(8),
|
||||||
|
receiver_address: CHAR(8),
|
||||||
|
original_msg: TEXT,
|
||||||
|
send_type: INTEGER(1),
|
||||||
|
encode_type: INTEGER(1),
|
||||||
|
msg_data: TEXT,
|
||||||
|
created_at: DATE,
|
||||||
|
},{
|
||||||
|
freezeTableName: true,
|
||||||
|
timestamp: true,
|
||||||
|
createdAt: true,
|
||||||
|
updatedAt: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
return CShortMsg;
|
||||||
|
};
|
||||||
19
app/router.js
Normal file
19
app/router.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* @param {Egg.Application} app - egg application
|
||||||
|
*/
|
||||||
|
module.exports = async (app) => {
|
||||||
|
const { router, controller, redis } = app;
|
||||||
|
// 服务接口
|
||||||
|
// token状态查询接口
|
||||||
|
router.post('/tokenStatus', controller.home.tokenStatus);
|
||||||
|
// 用户获取短期token的接口
|
||||||
|
router.post('/getUserToken', controller.home.getUserToken);
|
||||||
|
// 用户延续短期token有效时间的接口
|
||||||
|
router.post('/lifeHold', controller.home.lifeHold);
|
||||||
|
|
||||||
|
// 教学接口
|
||||||
|
// 获取最近发送的一条信息
|
||||||
|
router.get('/getMsg', controller.teaching.getMsg)
|
||||||
|
// 获取若干条历史消息
|
||||||
|
router.get('/getHistory', controller.teaching.getHistory)
|
||||||
|
};
|
||||||
88
app/service/home.js
Normal file
88
app/service/home.js
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const BaseService = require('../core/base_service.js');
|
||||||
|
|
||||||
|
const sha256 = require("crypto-js/sha256");
|
||||||
|
|
||||||
|
const fileName = "home";
|
||||||
|
|
||||||
|
class HomeService extends BaseService {
|
||||||
|
// token 状态查询接口
|
||||||
|
async tokenStatus(uid) {
|
||||||
|
const { ctx } = this;
|
||||||
|
const redis = ctx.app.redis;
|
||||||
|
try {
|
||||||
|
let result = {};
|
||||||
|
const tokenUser = await redis.get('db4').get(uid);
|
||||||
|
if (!tokenUser) {
|
||||||
|
const where = { user_uid: uid };
|
||||||
|
const attributes = ['token'];
|
||||||
|
result.remainder = false;
|
||||||
|
result.token = await ctx.model.BuserToken.findOne({ attributes, where });
|
||||||
|
result.type = result.token == null ? 'none' : "long";
|
||||||
|
} else {
|
||||||
|
result.remainder = await redis.get('db4').ttl(uid);
|
||||||
|
result.token = JSON.parse(tokenUser).token;
|
||||||
|
result.type = JSON.parse(tokenUser).lifeHold ? "lifeHold" : "short";
|
||||||
|
}
|
||||||
|
const token = await redis.get('db4').get(result.token);
|
||||||
|
if(token) {
|
||||||
|
result.attacksMark = JSON.parse(token).attacksMark;
|
||||||
|
result.banAt = result.attacksMark ? JSON.parse(token).banAt : 0;
|
||||||
|
}
|
||||||
|
return result ? result : false;
|
||||||
|
} catch (error) {
|
||||||
|
const blockName = fileName + "--" + "tokenStatus";
|
||||||
|
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
|
||||||
|
return 'error';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用户获取短期 token 的接口
|
||||||
|
async getUserToken(uid) {
|
||||||
|
const { ctx } = this;
|
||||||
|
const redis = ctx.app.redis;
|
||||||
|
try {
|
||||||
|
const token = this.shaForm(uid, this.generateRandomString());
|
||||||
|
const checkUser = await redis.get('db4').get(uid);
|
||||||
|
let tokenUser, tokenMark;
|
||||||
|
if (!checkUser) {
|
||||||
|
const where = { user_uid: uid };
|
||||||
|
const attributes = ['token'];
|
||||||
|
const result = await ctx.model.BuserToken.findOne({ attributes, where });
|
||||||
|
if (result == null) {
|
||||||
|
// 设置过期时间为一周
|
||||||
|
tokenUser = await redis.get('db4').set(uid, JSON.stringify({ token, lifeHold: false }), 'EX', 604800);
|
||||||
|
tokenMark = await redis.get('db4').set(token, JSON.stringify({ uid, attacksMark: false }), 'EX', 604800);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tokenUser && tokenMark ? true : false;
|
||||||
|
} catch (error) {
|
||||||
|
const blockName = fileName + "--" + "getUserToken";
|
||||||
|
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
|
||||||
|
return 'error';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用户延续短期 token 有效时间的接口
|
||||||
|
async lifeHold(uid) {
|
||||||
|
const { ctx } = this;
|
||||||
|
const redis = ctx.app.redis;
|
||||||
|
try {
|
||||||
|
const user = await redis.get('db4').get(uid);
|
||||||
|
let tokenUser, tokenMark;
|
||||||
|
if (!JSON.parse(user).lifeHold) {
|
||||||
|
let ex = await redis.get('db4').ttl(uid) + 604800;
|
||||||
|
tokenUser = await redis.get('db4').set(uid, JSON.stringify({ token: JSON.parse(user).token, lifeHold: true }), 'EX', ex);
|
||||||
|
tokenMark = await redis.get('db4').expire(JSON.parse(user).token, ex);
|
||||||
|
}
|
||||||
|
return tokenUser && tokenMark ? true : false;
|
||||||
|
} catch (error) {
|
||||||
|
const blockName = fileName + "--" + "lifeHold";
|
||||||
|
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
|
||||||
|
return 'error';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = HomeService;
|
||||||
100
app/service/teaching.js
Normal file
100
app/service/teaching.js
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const BaseService = require('../core/base_service.js');
|
||||||
|
|
||||||
|
const fileName = "teaching";
|
||||||
|
|
||||||
|
class TeachingService extends BaseService {
|
||||||
|
// 获取最近发送的一条信息
|
||||||
|
async getMsg(redis, token) {
|
||||||
|
const { ctx } = this;
|
||||||
|
try {
|
||||||
|
const verifyResult = await this.Verify(redis, token);
|
||||||
|
let result = { code: verifyResult };
|
||||||
|
if (verifyResult == 401) {
|
||||||
|
const where = { token };
|
||||||
|
const attributes = ['token'];
|
||||||
|
const dbResult = await ctx.model.BuserToken.findOne({ attributes, where });
|
||||||
|
result.code = dbResult ? dbResult.dataValus.user_uid : 401;
|
||||||
|
}
|
||||||
|
if (result.code !== 401 && result.code !== 403) {
|
||||||
|
const uidLastCode = this.shunt(result.code);
|
||||||
|
const model = {
|
||||||
|
"B": ctx.model.BShortMsg,
|
||||||
|
"C": ctx.model2.CShortMsg
|
||||||
|
};
|
||||||
|
const attributes = ['card_id', 'encode_type', 'msg_data', 'created_at'];
|
||||||
|
const where = { user_uid: result.code };
|
||||||
|
const limit = 1;
|
||||||
|
const order = [['created_at', 'DESC']];
|
||||||
|
const dbOptions = { attributes, limit, order, where };
|
||||||
|
const dbResult = await model[uidLastCode].findOne(dbOptions);
|
||||||
|
if (dbResult) {
|
||||||
|
result.userData = dbResult.dataValues;
|
||||||
|
result.code = 200;
|
||||||
|
} else {
|
||||||
|
result.code = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.code ? result : false;
|
||||||
|
} catch (error) {
|
||||||
|
const blockName = fileName + "--" + "getMsg";
|
||||||
|
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
|
||||||
|
return 'error';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取若干条历史消息
|
||||||
|
async getHistory(redis, token, limit, offset) {
|
||||||
|
const { ctx } = this;
|
||||||
|
try {
|
||||||
|
const verifyResult = await this.Verify(redis, token);
|
||||||
|
let result = { code: verifyResult };
|
||||||
|
if (verifyResult == 401) {
|
||||||
|
const where = { token };
|
||||||
|
const attributes = ['token'];
|
||||||
|
const dbResult = await ctx.model.BuserToken.findOne({ attributes, where });
|
||||||
|
result.code = dbResult ? dbResult.dataValus.user_uid : 401;
|
||||||
|
}
|
||||||
|
if (result.code !== 401 && result.code !== 403) {
|
||||||
|
const uidLastCode = this.shunt(result.code);
|
||||||
|
const model = {
|
||||||
|
"B": ctx.model.BShortMsg,
|
||||||
|
"C": ctx.model2.CShortMsg
|
||||||
|
};
|
||||||
|
const attributes = ['card_id', 'encode_type', 'msg_data', 'created_at'];
|
||||||
|
const where = { user_uid: result.code };
|
||||||
|
const order = [['created_at', 'DESC']];
|
||||||
|
if (limit == undefined || !this.isAllDigits(limit)) {
|
||||||
|
limit = 10
|
||||||
|
} else {
|
||||||
|
limit = parseInt(limit);
|
||||||
|
}
|
||||||
|
if (offset == undefined || !this.isAllDigits(offset)) {
|
||||||
|
offset = 1
|
||||||
|
} else {
|
||||||
|
offset = parseInt(offset);
|
||||||
|
}
|
||||||
|
offset = (offset - 1) * limit;
|
||||||
|
const dbOptions = { attributes, limit, offset, order, where };
|
||||||
|
const dbResult = await model[uidLastCode].findAndCountAll(dbOptions);
|
||||||
|
if (dbResult.rows.length !== 0) {
|
||||||
|
result.userData = {
|
||||||
|
rows: dbResult.rows,
|
||||||
|
count: dbResult.count
|
||||||
|
};
|
||||||
|
result.code = 200;
|
||||||
|
} else {
|
||||||
|
result.code = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.code ? result : false;
|
||||||
|
} catch (error) {
|
||||||
|
const blockName = fileName + "--" + "getHistory";
|
||||||
|
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
|
||||||
|
return 'error';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = TeachingService;
|
||||||
171
config/config.default.js
Normal file
171
config/config.default.js
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
/* eslint valid-jsdoc: "off" */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Egg.EggAppInfo} appInfo app info
|
||||||
|
*/
|
||||||
|
module.exports = appInfo => {
|
||||||
|
/**
|
||||||
|
* built-in config
|
||||||
|
* @type {Egg.EggAppConfig}
|
||||||
|
**/
|
||||||
|
const config = exports = {};
|
||||||
|
|
||||||
|
// use for cookie sign key, should change to your own and keep security
|
||||||
|
config.keys = appInfo.name + '_1715070383253_5684';
|
||||||
|
|
||||||
|
// add your middleware config here
|
||||||
|
// config.middleware = [];
|
||||||
|
|
||||||
|
config.security = {
|
||||||
|
csrf:{
|
||||||
|
enable:false
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
config.redis = {
|
||||||
|
// 开发/测试环境
|
||||||
|
clients: {
|
||||||
|
db0: {
|
||||||
|
port: 6379,
|
||||||
|
host: '127.0.0.1',
|
||||||
|
password: '74191221',
|
||||||
|
db: 0,
|
||||||
|
},
|
||||||
|
db1: {
|
||||||
|
port: 6379,
|
||||||
|
host: '127.0.0.1',
|
||||||
|
password: '74191221',
|
||||||
|
db: 1,
|
||||||
|
},
|
||||||
|
db2: {
|
||||||
|
port: 6379,
|
||||||
|
host: '127.0.0.1',
|
||||||
|
password: '74191221',
|
||||||
|
db: 2,
|
||||||
|
},
|
||||||
|
db3: {
|
||||||
|
port: 6379,
|
||||||
|
host: '127.0.0.1',
|
||||||
|
password: '74191221',
|
||||||
|
db: 3,
|
||||||
|
},
|
||||||
|
db4: {
|
||||||
|
port: 6379,
|
||||||
|
host: '127.0.0.1',
|
||||||
|
password: '74191221',
|
||||||
|
db: 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生产环境
|
||||||
|
// clients: {
|
||||||
|
// db0: {
|
||||||
|
// port: 6379,
|
||||||
|
// host: '127.0.0.1',
|
||||||
|
// password: 'bd3@htcc2023',
|
||||||
|
// db: 2,
|
||||||
|
// },
|
||||||
|
// db1: {
|
||||||
|
// port: 6379,
|
||||||
|
// host: '127.0.0.1',
|
||||||
|
// password: 'bd3@htcc2023',
|
||||||
|
// db: 3,
|
||||||
|
// },
|
||||||
|
// db2: {
|
||||||
|
// port: 6379,
|
||||||
|
// host: '127.0.0.1',
|
||||||
|
// password: 'bd3@htcc2023',
|
||||||
|
// db: 4,
|
||||||
|
// },
|
||||||
|
// db3: {
|
||||||
|
// port: 6379,
|
||||||
|
// host: '127.0.0.1',
|
||||||
|
// password: 'bd3@htcc2023',
|
||||||
|
// db: 5,
|
||||||
|
// },
|
||||||
|
// db4: {
|
||||||
|
// port: 6379,
|
||||||
|
// host: '127.0.0.1',
|
||||||
|
// password: 'bd3@htcc2023',
|
||||||
|
// db: 6
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
|
||||||
|
config.sequelize = {
|
||||||
|
// 开发/测试环境
|
||||||
|
datasources: [
|
||||||
|
{
|
||||||
|
dialect: 'mariadb',
|
||||||
|
host: 'localhost',
|
||||||
|
port: 3306,
|
||||||
|
username: 'root',
|
||||||
|
password: '74191221',
|
||||||
|
database: 'bside',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dialect: 'mariadb',
|
||||||
|
host: 'localhost',
|
||||||
|
port: 3306,
|
||||||
|
username: 'root',
|
||||||
|
password: '74191221',
|
||||||
|
database: 'cside',
|
||||||
|
delegate: 'model2',
|
||||||
|
baseDir: 'model2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dialect: 'mariadb',
|
||||||
|
host: 'localhost',
|
||||||
|
port: 3306,
|
||||||
|
username: 'root',
|
||||||
|
password: '74191221',
|
||||||
|
database: 'insiders',
|
||||||
|
delegate: 'model3',
|
||||||
|
baseDir: 'model3',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// 生产环境
|
||||||
|
// datasources: [
|
||||||
|
// {
|
||||||
|
// dialect: 'mariadb',
|
||||||
|
// host: 'localhost',
|
||||||
|
// port: 3306,
|
||||||
|
// username: 'bdqh_platform',
|
||||||
|
// password: '124689@XXxx',
|
||||||
|
// database: 'bside',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// dialect: 'mariadb',
|
||||||
|
// host: 'localhost',
|
||||||
|
// port: 3306,
|
||||||
|
// username: 'bdqh_platform',
|
||||||
|
// password: '124689@XXxx',
|
||||||
|
// database: 'cside',
|
||||||
|
// delegate: 'model2',
|
||||||
|
// baseDir: 'model2',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// dialect: 'mariadb',
|
||||||
|
// host: 'localhost',
|
||||||
|
// port: 3306,
|
||||||
|
// username: 'bdqh_platform',
|
||||||
|
// password: '124689@XXxx',
|
||||||
|
// database: 'insiders',
|
||||||
|
// delegate: 'model3',
|
||||||
|
// baseDir: 'model3',
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
};
|
||||||
|
|
||||||
|
// add your user config here
|
||||||
|
const userConfig = {
|
||||||
|
// myAppName: 'egg',
|
||||||
|
salt:'teachingApi'
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
...config,
|
||||||
|
...userConfig,
|
||||||
|
};
|
||||||
|
};
|
||||||
22
config/plugin.js
Normal file
22
config/plugin.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/** @type Egg.EggPlugin */
|
||||||
|
module.exports = {
|
||||||
|
// had enabled by egg
|
||||||
|
// static: {
|
||||||
|
// enable: true,
|
||||||
|
// }
|
||||||
|
|
||||||
|
redis : {
|
||||||
|
enable: true,
|
||||||
|
package: 'egg-redis',
|
||||||
|
},
|
||||||
|
|
||||||
|
sequelize : {
|
||||||
|
enable: true,
|
||||||
|
package: 'egg-sequelize',
|
||||||
|
},
|
||||||
|
|
||||||
|
validate : {
|
||||||
|
enable: true,
|
||||||
|
package: 'egg-validate',
|
||||||
|
},
|
||||||
|
};
|
||||||
1
controllerLog/2025/2/11.txt
Normal file
1
controllerLog/2025/2/11.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[2025-2-11>>>10:34:39]>>>home--tokenStatus>>>>ReferenceError: decryptRequest is not defined
|
||||||
1
controllerLog/2025/2/12.txt
Normal file
1
controllerLog/2025/2/12.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[2025-2-12>>>14:51:56]>>>teaching--getMsg>>>>TypeError: Cannot read properties of undefined (reading 'code')
|
||||||
3
controllerLog/2025/2/13.txt
Normal file
3
controllerLog/2025/2/13.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[2025-2-13>>>10:45:5]>>>home--lifeHold>>>>TypeError: Cannot read properties of undefined (reading 'ciphertext')
|
||||||
|
[2025-2-13>>>10:45:5]>>>home--lifeHold>>>>TypeError: Cannot read properties of undefined (reading 'ciphertext')
|
||||||
|
[2025-2-13>>>17:40:44]>>>home--tokenStatus>>>>TypeError: Cannot read properties of undefined (reading 'ciphertext')
|
||||||
8
controllerLog/2025/2/14.txt
Normal file
8
controllerLog/2025/2/14.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
[2025-2-14>>>9:13:32]>>>home--tokenStatus>>>>TypeError: Cannot read properties of undefined (reading 'ciphertext')
|
||||||
|
[2025-2-14>>>9:44:31]>>>home--tokenStatus>>>>TypeError: Cannot read properties of undefined (reading 'ciphertext')
|
||||||
|
[2025-2-14>>>9:45:10]>>>home--tokenStatus>>>>ReferenceError: Cannot access 'uid' before initialization
|
||||||
|
[2025-2-14>>>9:45:28]>>>home--tokenStatus>>>>TypeError: Cannot read properties of undefined (reading 'ciphertext')
|
||||||
|
[2025-2-14>>>9:58:56]>>>home--tokenStatus>>>>TypeError: Cannot read properties of undefined (reading 'ciphertext')
|
||||||
|
[2025-2-14>>>10:2:39]>>>home--tokenStatus>>>>TypeError: Cannot read properties of undefined (reading 'ciphertext')
|
||||||
|
[2025-2-14>>>15:52:39]>>>teaching--getHistory>>>>TypeError: Cannot read properties of undefined (reading 'rows')
|
||||||
|
[2025-2-14>>>15:52:41]>>>teaching--getHistory>>>>TypeError: Cannot read properties of undefined (reading 'rows')
|
||||||
23
database/config.json
Normal file
23
database/config.json
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"development": {
|
||||||
|
"username": "root",
|
||||||
|
"password": 74191221,
|
||||||
|
"database": "vm_centos",
|
||||||
|
"host": "127.0.0.1",
|
||||||
|
"dialect": "mariadb"
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"username": "root",
|
||||||
|
"password": 74191221,
|
||||||
|
"database": "vm_centos",
|
||||||
|
"host": "127.0.0.1",
|
||||||
|
"dialect": "mariadb"
|
||||||
|
},
|
||||||
|
"production": {
|
||||||
|
"username": "root",
|
||||||
|
"password": 74191221,
|
||||||
|
"database": "vm_centos",
|
||||||
|
"host": "127.0.0.1",
|
||||||
|
"dialect": "mariadb"
|
||||||
|
}
|
||||||
|
}
|
||||||
5
jsconfig.json
Normal file
5
jsconfig.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"include": [
|
||||||
|
"**/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
48
package.json
Normal file
48
package.json
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
"name": "teaching-api",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"private": true,
|
||||||
|
"egg": {
|
||||||
|
"declarations": true
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"crypto-js": "^4.2.0",
|
||||||
|
"egg": "^3.17.5",
|
||||||
|
"egg-redis": "^2.6.0",
|
||||||
|
"egg-scripts": "2",
|
||||||
|
"egg-sequelize": "^6.0.0",
|
||||||
|
"egg-validate": "^2.0.2",
|
||||||
|
"ioredis": "^5.4.1",
|
||||||
|
"mariadb": "^3.3.0",
|
||||||
|
"mysql2": "^3.9.7",
|
||||||
|
"sequelize": "^6.37.3",
|
||||||
|
"teaching-api": "file:"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"egg-bin": "6",
|
||||||
|
"egg-mock": "5",
|
||||||
|
"eslint": "8",
|
||||||
|
"eslint-config-egg": "13",
|
||||||
|
"sequelize-cli": "^6.6.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.0.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"start": "egg-scripts start --daemon --port=8017 --title=egg-server-teaching-api",
|
||||||
|
"stop": "egg-scripts stop --title=egg-server-teaching-api",
|
||||||
|
"dev": "egg-bin dev --port=8017",
|
||||||
|
"test": "npm run lint -- --fix && npm run test:local",
|
||||||
|
"test:local": "egg-bin test",
|
||||||
|
"cov": "egg-bin cov",
|
||||||
|
"lint": "eslint .",
|
||||||
|
"ci": "npm run lint && npm run cov"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": ""
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "MIT"
|
||||||
|
}
|
||||||
2
serviceLog/2025/2/11.txt
Normal file
2
serviceLog/2025/2/11.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[2025-2-11>>>14:31:25]>>>home--lifeHold>>>>SyntaxError: Unexpected token o in JSON at position 1
|
||||||
|
[2025-2-11>>>14:39:36]>>>home--tokenStatus>>>>SyntaxError: Unexpected token o in JSON at position 1
|
||||||
19
serviceLog/2025/2/12.txt
Normal file
19
serviceLog/2025/2/12.txt
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[2025-2-12>>>14:41:26]>>>teaching--getMsg>>>>Error: WHERE parameter "token" has invalid "undefined" value
|
||||||
|
[2025-2-12>>>14:41:28]>>>teaching--getHistory>>>>Error: WHERE parameter "token" has invalid "undefined" value
|
||||||
|
[2025-2-12>>>14:48:1]>>>teaching--getMsg>>>>ReferenceError: dbOptions is not defined
|
||||||
|
[2025-2-12>>>15:13:29]>>>teaching--getHistory>>>>SequelizeDatabaseError: (conn:192, no: 1064, SQLState: 42000) You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''10'' at line 1
|
||||||
|
sql: SELECT `card_id`, `encode_type`, `msg_data`, `created_at` FROM `bshort-msg` AS `bshort-msg` WHERE `bshort-msg`.`user_uid` = '20240613698218B' ORDER BY `bshort-msg`.`created_at` DESC LIMIT 0, '10'; - parameters:[]
|
||||||
|
[2025-2-12>>>15:20:23]>>>teaching--getHistory>>>>SequelizeDatabaseError: (conn:206, no: 1064, SQLState: 42000) You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''10'' at line 1
|
||||||
|
sql: SELECT `card_id`, `encode_type`, `msg_data`, `created_at` FROM `bshort-msg` AS `bshort-msg` WHERE `bshort-msg`.`user_uid` = '20240613698218B' ORDER BY `bshort-msg`.`created_at` DESC LIMIT 0, '10'; - parameters:[]
|
||||||
|
[2025-2-12>>>15:21:54]>>>teaching--getHistory>>>>SequelizeDatabaseError: (conn:217, no: 1064, SQLState: 42000) You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''1', '10'' at line 1
|
||||||
|
sql: SELECT `card_id`, `encode_type`, `msg_data`, `created_at` FROM `bshort-msg` AS `bshort-msg` WHERE `bshort-msg`.`user_uid` = '20240613698218B' ORDER BY `bshort-msg`.`created_at` DESC LIMIT '1', '10'; - parameters:[]
|
||||||
|
[2025-2-12>>>15:23:34]>>>teaching--getHistory>>>>SequelizeDatabaseError: (conn:224, no: 1064, SQLState: 42000) You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''1', '10'' at line 1
|
||||||
|
sql: SELECT `card_id`, `encode_type`, `msg_data`, `created_at` FROM `bshort-msg` AS `bshort-msg` WHERE `bshort-msg`.`user_uid` = '20240613698218B' ORDER BY `bshort-msg`.`created_at` DESC LIMIT '1', '10'; - parameters:[]
|
||||||
|
[2025-2-12>>>15:31:9]>>>teaching--getHistory>>>>SequelizeDatabaseError: (conn:231, no: 1064, SQLState: 42000) You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''10'' at line 1
|
||||||
|
sql: SELECT `card_id`, `encode_type`, `msg_data`, `created_at` FROM `bshort-msg` AS `bshort-msg` WHERE `bshort-msg`.`user_uid` = '20240613698218B' ORDER BY `bshort-msg`.`created_at` DESC LIMIT 0, '10'; - parameters:[]
|
||||||
|
[2025-2-12>>>15:33:6]>>>teaching--getHistory>>>>SequelizeDatabaseError: (conn:252, no: 1064, SQLState: 42000) You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''10'' at line 1
|
||||||
|
sql: SELECT `card_id`, `encode_type`, `msg_data`, `created_at` FROM `bshort-msg` AS `bshort-msg` WHERE `bshort-msg`.`user_uid` = '20240613698218B' ORDER BY `bshort-msg`.`created_at` DESC LIMIT '10'; - parameters:[]
|
||||||
|
[2025-2-12>>>16:22:32]>>>home--lifeHold>>>>TypeError: Cannot read properties of null (reading 'lifeHold')
|
||||||
|
[2025-2-12>>>16:24:2]>>>home--lifeHold>>>>TypeError: Cannot read properties of null (reading 'lifeHold')
|
||||||
|
[2025-2-12>>>16:24:38]>>>home--lifeHold>>>>TypeError: Cannot read properties of null (reading 'lifeHold')
|
||||||
|
[2025-2-12>>>16:25:0]>>>home--lifeHold>>>>TypeError: Cannot read properties of null (reading 'lifeHold')
|
||||||
Reference in New Issue
Block a user