first commit

This commit is contained in:
编码猿
2024-09-27 02:06:13 +08:00
commit 852d94fbb9
36760 changed files with 3274413 additions and 0 deletions

View File

@@ -0,0 +1,292 @@
{
root: 'C:\\Users\\宝\\Desktop\\front-end-team-11\\项目开发\\学生项目\\贡婉宝\\da\\后端',
registry: 'https://registry.npmmirror.com',
pkgs: [
{
name: 'routing-controllers',
version: 'latest',
type: 'tag',
alias: undefined,
arg: [Result]
},
{
name: 'cnpm',
version: 'latest',
type: 'tag',
alias: undefined,
arg: [Result]
},
{
name: 'install',
version: 'latest',
type: 'tag',
alias: undefined,
arg: [Result]
},
{
name: 'reflect-metadata',
version: 'latest',
type: 'tag',
alias: undefined,
arg: [Result]
},
{
name: 'cnpm',
version: 'latest',
type: 'tag',
alias: undefined,
arg: [Result]
},
{
name: 'install',
version: 'latest',
type: 'tag',
alias: undefined,
arg: [Result]
},
{
name: 'koa',
version: 'latest',
type: 'tag',
alias: undefined,
arg: [Result]
},
{
name: '@koa/router',
version: 'latest',
type: 'tag',
alias: undefined,
arg: [Result]
},
{
name: 'koa-bodyparser',
version: 'latest',
type: 'tag',
alias: undefined,
arg: [Result]
},
{
name: '@koa/multer',
version: 'latest',
type: 'tag',
alias: undefined,
arg: [Result]
},
{
name: 'cnpm',
version: 'latest',
type: 'tag',
alias: undefined,
arg: [Result]
},
{
name: 'install',
version: 'latest',
type: 'tag',
alias: undefined,
arg: [Result]
},
{
name: '@types/koa',
version: 'latest',
type: 'tag',
alias: undefined,
arg: [Result]
},
{
name: '@types/koa-bodyparser',
version: 'latest',
type: 'tag',
alias: undefined,
arg: [Result]
}
],
production: false,
cacheStrict: false,
cacheDir: 'C:\\Users\\宝\\.npminstall_tarball',
env: {
npm_config_registry: 'https://registry.npmmirror.com',
npm_config_argv: '{"remain":[],"cooked":["--fix-bug-versions","--china","--userconfig=C:\\\\Users\\\\宝\\\\.cnpmrc","--disturl=https://cdn.npmmirror.com/binaries/node","--registry=https://registry.npmmirror.com","routing-controllers","cnpm","install","reflect-metadata","cnpm","install","koa","@koa/router","koa-bodyparser","@koa/multer","cnpm","install","-D","@types/koa","@types/koa-bodyparser"],"original":["--fix-bug-versions","--china","--userconfig=C:\\\\Users\\\\宝\\\\.cnpmrc","--disturl=https://cdn.npmmirror.com/binaries/node","--registry=https://registry.npmmirror.com","routing-controllers","cnpm","install","reflect-metadata","cnpm","install","koa","@koa/router","koa-bodyparser","@koa/multer","cnpm","install","-D","@types/koa","@types/koa-bodyparser"]}',
npm_config_user_agent: 'npminstall/7.8.0 npm/? node/v18.16.1 win32 x64',
npm_config_cache: 'C:\\Users\\宝\\.npminstall_tarball',
NODE: 'C:\\Program Files\\nodejs\\node.exe',
npm_node_execpath: 'C:\\Program Files\\nodejs\\node.exe',
npm_execpath: 'C:\\Users\\宝\\AppData\\Roaming\\npm\\node_modules\\cnpm\\node_modules\\npminstall\\bin\\install.js',
npm_config_userconfig: 'C:\\Users\\宝\\.cnpmrc',
npm_config_disturl: 'https://cdn.npmmirror.com/binaries/node',
npm_config_r: 'https://registry.npmmirror.com',
COREPACK_NPM_REGISTRY: 'https://registry.npmmirror.com',
NODEJS_ORG_MIRROR: 'https://cdn.npmmirror.com/binaries/node',
NVM_NODEJS_ORG_MIRROR: 'https://cdn.npmmirror.com/binaries/node',
PHANTOMJS_CDNURL: 'https://cdn.npmmirror.com/binaries/phantomjs',
CHROMEDRIVER_CDNURL: 'https://cdn.npmmirror.com/binaries/chromedriver',
OPERADRIVER_CDNURL: 'https://cdn.npmmirror.com/binaries/operadriver',
CYPRESS_DOWNLOAD_PATH_TEMPLATE: 'https://cdn.npmmirror.com/binaries/cypress/${version}/${platform}-${arch}/cypress.zip',
ELECTRON_MIRROR: 'https://cdn.npmmirror.com/binaries/electron/',
ELECTRON_BUILDER_BINARIES_MIRROR: 'https://cdn.npmmirror.com/binaries/electron-builder-binaries/',
SASS_BINARY_SITE: 'https://cdn.npmmirror.com/binaries/node-sass',
SWC_BINARY_SITE: 'https://cdn.npmmirror.com/binaries/node-swc',
NWJS_URLBASE: 'https://cdn.npmmirror.com/binaries/nwjs/v',
PUPPETEER_DOWNLOAD_HOST: 'https://cdn.npmmirror.com/binaries/chrome-for-testing',
PUPPETEER_DOWNLOAD_BASE_URL: 'https://cdn.npmmirror.com/binaries/chrome-for-testing',
PLAYWRIGHT_DOWNLOAD_HOST: 'https://cdn.npmmirror.com/binaries/playwright',
SENTRYCLI_CDNURL: 'https://cdn.npmmirror.com/binaries/sentry-cli',
SAUCECTL_INSTALL_BINARY_MIRROR: 'https://cdn.npmmirror.com/binaries/saucectl',
RE2_DOWNLOAD_MIRROR: 'https://cdn.npmmirror.com/binaries/node-re2',
RE2_DOWNLOAD_SKIP_PATH: 'true',
PRISMA_ENGINES_MIRROR: 'https://cdn.npmmirror.com/binaries/prisma',
npm_config_better_sqlite3_binary_host: 'https://cdn.npmmirror.com/binaries/better-sqlite3',
npm_config_keytar_binary_host: 'https://cdn.npmmirror.com/binaries/keytar',
npm_config_sharp_binary_host: 'https://cdn.npmmirror.com/binaries/sharp',
npm_config_sharp_libvips_binary_host: 'https://cdn.npmmirror.com/binaries/sharp-libvips',
npm_config_robotjs_binary_host: 'https://cdn.npmmirror.com/binaries/robotjs',
npm_rootpath: 'C:\\Users\\宝\\Desktop\\front-end-team-11\\项目开发\\学生项目\\贡婉宝\\da\\后端',
INIT_CWD: 'C:\\Users\\宝\\Desktop\\front-end-team-11\\项目开发\\学生项目\\贡婉宝\\da\\后端'
},
binaryMirrors: {
ENVS: {
COREPACK_NPM_REGISTRY: 'https://registry.npmmirror.com',
NODEJS_ORG_MIRROR: 'https://cdn.npmmirror.com/binaries/node',
NVM_NODEJS_ORG_MIRROR: 'https://cdn.npmmirror.com/binaries/node',
PHANTOMJS_CDNURL: 'https://cdn.npmmirror.com/binaries/phantomjs',
CHROMEDRIVER_CDNURL: 'https://cdn.npmmirror.com/binaries/chromedriver',
OPERADRIVER_CDNURL: 'https://cdn.npmmirror.com/binaries/operadriver',
CYPRESS_DOWNLOAD_PATH_TEMPLATE: 'https://cdn.npmmirror.com/binaries/cypress/${version}/${platform}-${arch}/cypress.zip',
ELECTRON_MIRROR: 'https://cdn.npmmirror.com/binaries/electron/',
ELECTRON_BUILDER_BINARIES_MIRROR: 'https://cdn.npmmirror.com/binaries/electron-builder-binaries/',
SASS_BINARY_SITE: 'https://cdn.npmmirror.com/binaries/node-sass',
SWC_BINARY_SITE: 'https://cdn.npmmirror.com/binaries/node-swc',
NWJS_URLBASE: 'https://cdn.npmmirror.com/binaries/nwjs/v',
PUPPETEER_DOWNLOAD_HOST: 'https://cdn.npmmirror.com/binaries/chrome-for-testing',
PUPPETEER_DOWNLOAD_BASE_URL: 'https://cdn.npmmirror.com/binaries/chrome-for-testing',
PLAYWRIGHT_DOWNLOAD_HOST: 'https://cdn.npmmirror.com/binaries/playwright',
SENTRYCLI_CDNURL: 'https://cdn.npmmirror.com/binaries/sentry-cli',
SAUCECTL_INSTALL_BINARY_MIRROR: 'https://cdn.npmmirror.com/binaries/saucectl',
RE2_DOWNLOAD_MIRROR: 'https://cdn.npmmirror.com/binaries/node-re2',
RE2_DOWNLOAD_SKIP_PATH: 'true',
PRISMA_ENGINES_MIRROR: 'https://cdn.npmmirror.com/binaries/prisma',
npm_config_better_sqlite3_binary_host: 'https://cdn.npmmirror.com/binaries/better-sqlite3',
npm_config_keytar_binary_host: 'https://cdn.npmmirror.com/binaries/keytar',
npm_config_sharp_binary_host: 'https://cdn.npmmirror.com/binaries/sharp',
npm_config_sharp_libvips_binary_host: 'https://cdn.npmmirror.com/binaries/sharp-libvips',
npm_config_robotjs_binary_host: 'https://cdn.npmmirror.com/binaries/robotjs'
},
'@ali/s2': { host: 'https://cdn.npmmirror.com/binaries/looksgood-s2' },
sharp: { replaceHostFiles: [Array], replaceHostMap: [Object] },
'@tensorflow/tfjs-node': {
replaceHostFiles: [Array],
replaceHostRegExpMap: [Object],
replaceHostMap: [Object]
},
cypress: {
host: 'https://cdn.npmmirror.com/binaries/cypress',
newPlatforms: [Object]
},
'utf-8-validate': {
host: 'https://cdn.npmmirror.com/binaries/utf-8-validate/v{version}'
},
xprofiler: {
remote_path: './xprofiler/v{version}/',
host: 'https://cdn.npmmirror.com/binaries'
},
leveldown: { host: 'https://cdn.npmmirror.com/binaries/leveldown/v{version}' },
couchbase: { host: 'https://cdn.npmmirror.com/binaries/couchbase/v{version}' },
gl: { host: 'https://cdn.npmmirror.com/binaries/gl/v{version}' },
sqlite3: {
host: 'https://cdn.npmmirror.com/binaries/sqlite3',
remote_path: 'v{version}'
},
'@journeyapps/sqlcipher': { host: 'https://cdn.npmmirror.com/binaries' },
grpc: {
host: 'https://cdn.npmmirror.com/binaries',
remote_path: '{name}/v{version}'
},
'grpc-tools': { host: 'https://cdn.npmmirror.com/binaries' },
wrtc: {
host: 'https://cdn.npmmirror.com/binaries',
remote_path: '{name}/v{version}'
},
fsevents: { host: 'https://cdn.npmmirror.com/binaries/fsevents' },
nodejieba: { host: 'https://cdn.npmmirror.com/binaries/nodejieba' },
canvas: { host: 'https://cdn.npmmirror.com/binaries/canvas' },
'skia-canvas': { host: 'https://cdn.npmmirror.com/binaries/skia-canvas' },
'flow-bin': {
replaceHost: 'https://github.com/facebook/flow/releases/download/v',
host: 'https://cdn.npmmirror.com/binaries/flow/v'
},
'jpegtran-bin': {
replaceHost: [Array],
host: 'https://cdn.npmmirror.com/binaries/jpegtran-bin'
},
'cwebp-bin': {
replaceHost: [Array],
host: 'https://cdn.npmmirror.com/binaries/cwebp-bin'
},
'zopflipng-bin': {
replaceHost: [Array],
host: 'https://cdn.npmmirror.com/binaries/zopflipng-bin'
},
'optipng-bin': {
replaceHost: [Array],
host: 'https://cdn.npmmirror.com/binaries/optipng-bin'
},
mozjpeg: {
replaceHost: [Array],
host: 'https://cdn.npmmirror.com/binaries/mozjpeg-bin'
},
gifsicle: {
replaceHost: [Array],
host: 'https://cdn.npmmirror.com/binaries/gifsicle-bin'
},
'pngquant-bin': {
replaceHost: [Array],
host: 'https://cdn.npmmirror.com/binaries/pngquant-bin',
replaceHostMap: [Object]
},
'pngcrush-bin': {
replaceHost: [Array],
host: 'https://cdn.npmmirror.com/binaries/pngcrush-bin'
},
'jpeg-recompress-bin': {
replaceHost: [Array],
host: 'https://cdn.npmmirror.com/binaries/jpeg-recompress-bin'
},
'advpng-bin': {
replaceHost: [Array],
host: 'https://cdn.npmmirror.com/binaries/advpng-bin'
},
'pngout-bin': {
replaceHost: [Array],
host: 'https://cdn.npmmirror.com/binaries/pngout-bin'
},
'jpegoptim-bin': {
replaceHost: [Array],
host: 'https://cdn.npmmirror.com/binaries/jpegoptim-bin'
},
argon2: { host: 'https://cdn.npmmirror.com/binaries/argon2' },
'ali-zeromq': { host: 'https://cdn.npmmirror.com/binaries/ali-zeromq' },
'ali-usb_ctl': { host: 'https://cdn.npmmirror.com/binaries/ali-usb_ctl' },
'gdal-async': { host: 'https://cdn.npmmirror.com/binaries/node-gdal-async' }
},
forbiddenLicenses: null,
flatten: false,
proxy: undefined,
prune: false,
disableFallbackStore: false,
workspacesMap: Map(0) {},
enableWorkspace: false,
workspaceRoot: 'C:\\Users\\宝\\Desktop\\front-end-team-11\\项目开发\\学生项目\\贡婉宝\\da\\后端',
isWorkspaceRoot: true,
isWorkspacePackage: false,
offline: false,
strictSSL: true,
ignoreScripts: false,
ignoreOptionalDependencies: false,
detail: false,
forceLinkLatest: false,
trace: false,
engineStrict: false,
registryOnly: false,
client: false,
autoFixVersion: [Function: autoFixVersion]
}

View File

@@ -0,0 +1,34 @@
{
"name": "后端",
"version": "0.1.0",
"private": true,
"scripts": {
"start": "node src/bin/www",
"dev": "./node_modules/.bin/nodemon bin/www",
"prd": "pm2 start bin/www",
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"@koa/multer": "^3.0.2",
"@koa/router": "^12.0.0",
"debug": "^4.1.1",
"koa": "^2.14.2",
"koa-bodyparser": "^4.4.1",
"koa-convert": "^1.2.0",
"koa-json": "^2.0.2",
"koa-logger": "^3.2.0",
"koa-onerror": "^4.1.0",
"koa-router": "^7.4.0",
"koa-static": "^5.0.0",
"koa-views": "^6.2.0",
"pug": "^2.0.3",
"reflect-metadata": "^0.1.13",
"routing-controllers": "^0.10.4"
},
"devDependencies": {
"@types/koa": "^2.13.6",
"@types/koa-bodyparser": "^4.3.10",
"@types/node": "^20.4.2",
"nodemon": "^1.19.1"
}
}

View File

@@ -0,0 +1,39 @@
const Koa = require('koa')
const app = new Koa()
const json = require('koa-json')
const onerror = require('koa-onerror')
const bodyparser = require('koa-bodyparser')
const logger = require('koa-logger')
const index = require('./routes/index')
const users = require('./routes/users')
// error handler
onerror(app)
// middlewares
app.use(bodyparser({
enableTypes:['json', 'form', 'text']
}))
app.use(json())
app.use(logger())
app.use(require('koa-static')(__dirname + '/public'))
// logger
app.use(async (ctx, next) => {
const start = new Date()
await next()
const ms = new Date() - start
console.log(`${ctx.method} ${ctx.url} - ${ms}ms`)
})
// routes
app.use(index.routes(), index.allowedMethods())
app.use(users.routes(), users.allowedMethods())
// error-handling
app.on('error', (err, ctx) => {
console.error('server error', err, ctx)
});
module.exports = app

View File

@@ -0,0 +1,90 @@
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('demo:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
// app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app.callback());
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}

View File

@@ -0,0 +1,3 @@
export default {
staticPath: '../public',
}

View File

@@ -0,0 +1,4 @@
import dev from "./dev";
import prod from "./prod";
export default process.env.NODE_ENV == "dev" ? dev : prod

View File

@@ -0,0 +1,3 @@
export default {
staticPath: '../public',
}

View File

@@ -0,0 +1,19 @@
const router = require('koa-router')()
router.get('/', async (ctx, next) => {
await ctx.render('index', {
title: 'Hello Koa 2!'
})
})
router.get('/string', async (ctx, next) => {
ctx.body = 'koa2 string'
})
router.get('/json', async (ctx, next) => {
ctx.body = {
title: 'koa2 json'
}
})
module.exports = router

View File

@@ -0,0 +1,13 @@
const router = require('koa-router')()
router.prefix('/users')
router.get('/', function (ctx, next) {
ctx.body = 'this is a users response!'
})
router.get('/bar', function (ctx, next) {
ctx.body = 'this is a users/bar response'
})
module.exports = router

View File

@@ -0,0 +1,30 @@
/**
* 插件初始滑
*/
import Application from 'koa'
import bodyparser from 'koa-bodyparser'
import json from 'koa-json'
import logger from 'koa-logger'
import config from '../config/dev'
import { join } from 'path';
import staticPublic from 'koa-static'
class Init {
// 存放我们koa框架用到的所有插件
private plugin: Array<Application.Middleware<Application.DefaultState & { }, Application.DefaultContext & {}>> = []
constructor() {
this.initPlugin()
}
initPlugin() {
this.plugin=[
bodyparser({
enableTypes:['json', 'form', 'text']
}),
json(),
staticPublic(join(__dirname,config.staticPath))
]
}
}

View File

@@ -0,0 +1,5 @@
1. koa2 脚手架 https://www.jianshu.com/p/4479dda7912a
2. npm install routing-controllers npm install reflect-metadata npm install koa @koa/router koa-bodyparser @koa/multer npm install -D @types/koa @types/koa-bodyparser
3. npm i --save-dev @types/node npm install --save-dev cross-env

View File

@@ -0,0 +1,51 @@
{
"name": "backendv2",
"version": "0.1.0",
"private": true,
"scripts": {
"start": " concurrently \"npm run tsc\" \" npm run dev \" ",
"tsc": "tsc -w",
"dev": "cross-env NODE_ENV=dev node-dev -r tsconfig-paths/register dist/src/run/app.js",
"build": "cross-env NODE_ENV=prod pm2 start src/bin/www"
},
"dependencies": {
"@koa/cors": "^4.0.0",
"@types/kcors": "^2.2.6",
"@types/koa-json": "^2.0.20",
"@types/koa-logger": "^3.1.2",
"@types/koa-static": "^4.0.2",
"apidoc": "^1.0.3",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"debug": "^4.1.1",
"jsonwebtoken": "^9.0.0",
"kcors": "^2.2.2",
"koa": "^2.7.0",
"koa-bodyparser": "^4.2.1",
"koa-convert": "^1.2.0",
"koa-json": "^2.0.2",
"koa-log4": "^2.3.2",
"koa-logger": "^3.2.0",
"koa-multer": "^1.0.2",
"koa-onerror": "^4.1.0",
"koa-router": "^7.4.0",
"koa-static": "^5.0.0",
"md5": "^2.3.0",
"moment": "^2.29.4",
"mysql": "^2.18.1",
"reflect-metadata": "^0.1.13",
"routing-controllers": "^0.10.4",
"segment": "^0.1.3",
"tsconfig-paths": "^4.2.0",
"typedi": "^0.8.0",
"typeorm": "^0.3.16"
},
"devDependencies": {
"@types/jsonwebtoken": "^9.0.2",
"@types/koa": "^2.13.6",
"@types/koa-bodyparser": "^4.3.10",
"@types/koa-log4": "^2.3.3",
"@types/md5": "^2.3.2",
"cross-env": "^7.0.3"
}
}

View File

@@ -0,0 +1,58 @@
# POST http://127.0.0.1:3000/app/user/add HTTP/1.1
# content-type: application/json
# {
# "name": "bmy2",
# "pwd": "lb714500."
# }
# POST http://127.0.0.1:3000/app/user/login HTTP/1.1
# content-type: application/json
# {
# "name": "bmy2",
# "pwd": "lb714500."
# }
# POST http://127.0.0.1:3000/app/user/info HTTP/1.1
# content-type: application/json
# token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjozLCJ1c2VyX25hbWUiOiJibXkyIiwiaWF0IjoxNjg2NzU0MzIyfQ.ULXeAjdPNDwWAOi-0LC-WmiLKgHVtn3zrFQ8hR7FeRQ
# {}
# GET http://127.0.0.1:3000/app/article/label HTTP/1.1
# content-type: application/json
# {}
# GET http://127.0.0.1:3000/app/article/label HTTP/1.1
# content-type: application/json
# {
# }
# GET http://127.0.0.1:3000/app/article/Labeldetails HTTP/1.1
# content-type: application/json
# {
# "id":1
# }
# GET http://127.0.0.1:3000/app/article/Labeldetails?id=1 HTTP/1.1
# content-type: application/json
# {
# }
GET http://127.0.0.1:3000/app/article/Search?text="3" HTTP/1.1
content-type: application/json
{
}

View File

@@ -0,0 +1,76 @@
import { join } from "path";
export default{
port:'3000',
staticPath:'/public',
cors: {
Origin: '*',
Headers: 'token',
configCors: function () {
return {
"Access-Control-Allow-Origin": this.Origin,
"Access-Control-Allow-Headers": this.Headers
}
}
},
routePrefix: {
app: '/app',
admin: '/admin',
apiPrefix: {
app: {
user: "/user",
article:"/article"
},
admin: { }
}
},
orm: null,
jwtKey: "sdfgsdgfjhjf",
mysql: {
type: "mysql",
host: "localhost",
port: 3306,
username: "root",
password: "root",
database: "myblog",
synchronize: false,
logging: true,
entities: [ join(__dirname, "../entity/**/*{.js,.ts}") ],
},
logConfig: {
appenders: {
//系统日志
access: {
type: 'dateFile',
pattern: '_yyyy-MM-dd.log',
alwaysIncludePattern: true,
encoding: "utf-8",
category: "access",
filename: join(__dirname, '../../logs/access')
},
// 应用日志
application: {
type: 'dateFile',
pattern: '_yyyy-MM-dd.log',
alwaysIncludePattern: true,
encoding: "utf-8",
category: "application",
filename: join(__dirname, '../../logs/application')
},
out: {
type: 'console'
}
},
categories: {
default: { appenders: ['out'], level: 'info' },
access: { appenders: ['access'], level: 'info' },
application: { appenders: ['application'], level: 'WARN' }
},
},
setPrefix: function(path: string): string {
let pathArr: string[] = path.split("/");
// @ts-ignore
return `${this.routePrefix[pathArr[0]]}${this.routePrefix.apiPrefix[pathArr[0]][pathArr[1]]}`
},
}

View File

@@ -0,0 +1,34 @@
import dev from "./dev";
import pord from "./pord.";
import {Configuration} from "koa-log4";
import { DataSourceOptions, DataSource } from "typeorm";
export interface ConfigType {
port:string;
staticPath: string;
orm: DataSource;
jwtKey: string;
mysql: DataSourceOptions;
routePrefix: {
app: string;
admin: string;
apiPrefix: {
app: {
[key: string]: any
};
admin: {
[key: string]: any
}
}
},
cors: {
Origin: string;
Headers: string;
configCors: () => object;
},
setPrefix: (path: string) => string;
logConfig:Configuration;
}
export default process.env.NODE_ENV=="dev"?dev:pord

View File

@@ -0,0 +1,76 @@
import { join } from "path";
export default{
port:'80',
staticPath:'/public',
orm:null,
mysql: {
type: "mysql",
host: "localhost",
port: 3306,
username: "root",
password: "root",
database: "myblog",
synchronize: false,
logging: true,
entities: [ join(__dirname, "../entity/**/*{.js,.ts}") ],
},
routePrefix: {
app: '/app',
admin: '/admin',
apiPrefix: {
app: {
user: "/user"
},
admin: { }
}
},
cors: {
Origin: '*',
Headers: 'token',
configCors: function () {
return {
"Access-Control-Allow-Origin": this.Origin,
"Access-Control-Allow-Headers": this.Headers
}
}
},
logConfig: {
appenders: {
//系统日志
access: {
type: 'dateFile',
pattern: '_yyyy-MM-dd.log',
alwaysIncludePattern: true,
encoding: "utf-8",
category: "access",
filename: join(__dirname, '../../logs/access')
},
// 应用日志
application: {
type: 'dateFile',
pattern: '_yyyy-MM-dd.log',
alwaysIncludePattern: true,
encoding: "utf-8",
category: "application",
filename: join(__dirname, '../../logs/application')
},
out: {
type: 'console'
}
},
categories: {
default: { appenders: ['out'], level: 'info' },
access: { appenders: ['access'], level: 'info' },
application: { appenders: ['application'], level: 'WARN' }
},
},
jwtKey: "sdfgsdgfjhjf",
setPrefix: function(path: string): string {
let pathArr: string[] = path.split("/");
// @ts-ignore
return `${this.routePrefix[pathArr[0]]}${this.routePrefix.apiPrefix[pathArr[0]][pathArr[1]]}`
},
}

View File

@@ -0,0 +1,49 @@
import { JsonController, Authorized, Body, HeaderParam, Get, Post, UseBefore, QueryParam} from 'routing-controllers';
import { RequestLog } from '@/middledware/requestLog'
import { Inject, Service } from 'typedi';
import { ArticleServiceImpl } from '../../service/impl/ArticleServiceImpl';
import { JsonResult, msgList, res } from '@/utils/jsonResult';
import { User } from '@/m_res/user'
import config from '@/config/init'
@Service()
@JsonController(config.setPrefix("app/article"))
export class ArticleController {
@Inject()
articleServiceImpl!: ArticleServiceImpl;
@Inject()
json!: JsonResult<any>;
@Get('/label')
@UseBefore(RequestLog) //全部标签
async Articlelabel(){
return await this.articleServiceImpl.GetArticlelabel()
}
@Get('/Labeldetails')
@UseBefore(RequestLog) //标签 详情
async ArticleLabeldetails(@QueryParam("id") id: number){
return await this.articleServiceImpl.GetArticlelabeldetails(id)
}
@Get('/categories_list')
@UseBefore(RequestLog) //分类 全部
async GetCategoriesList() {
return await this.articleServiceImpl.GetCategoriesList();
}
@Get('/categories_info')
@UseBefore(RequestLog) //分类 详情
async GetArticgoriesListinfo(@QueryParam("id") id:number) {
return await this.articleServiceImpl.GetArticgoriesListinfo(id);
}
@Get('/Search')
@UseBefore(RequestLog) //分类 详情
async GetArticSearch(@QueryParam("text") text:string) {
return await this.articleServiceImpl.GetSearch(text);
}
}

View File

@@ -0,0 +1,49 @@
import { Authorized,HeaderParam,Get,JsonController,QueryParams,UseBefore,UseInterceptor,Post,Body} from "routing-controllers";
import { getOneUser ,addUser} from "../../model/request/User";
import { RequestLog } from "../../middledware/requestLog";
import { Service,Inject, } from "typedi";
import { UserServiceimpl } from "../../service/impl/userServiceimpl";
import { User } from "../../model/response/user";
import { JsonResponse } from "../../middledware/JsonResponse"
import { JsonResult ,msgList,res} from "../../utils/jsonResult";
import config from "@/config/init";
import {Token} from "@/m_req/request_Token";
@Service()
@JsonController(config.setPrefix("app/user"))
export class indexController{
@Inject()
UserServiceimpl!:UserServiceimpl;
@Inject()
jsonResult!:JsonResult<any>
// @Post('/info')
// @UseBefore(RequestLog)
// @Authorized()
// async getOneUser(@HeaderParam("token") token: Token): Promise<res<User | null>>{
// console.log("token: ", token);
// return await this.UserServiceimpl.GetOneUser(token.user_id);
// }
//用户添加
@Post('/add')
@UseBefore(RequestLog)
async add(@Body() params: addUser):Promise<res<null>> {
console.log("params",params)
return await this.UserServiceimpl.addUser(params);
}
//登录
@Post('/login')
@UseBefore(RequestLog)
async Login(@Body() params: addUser): Promise<res<User | null>> {
return await this.UserServiceimpl.Login(params);
}
}

View File

@@ -0,0 +1,72 @@
import { Article, } from '@/entity/Article';
import { Categories } from '@/entity/Categories';
import { Tag } from '@/entity/Tag';
import { Comment } from '@/entity/Comment';
import { User } from '@/entity/User';
import { Service, Inject } from 'typedi'
import { Like } from "typeorm"
import { Entity } from '@/utils/orm'
import { Segment } from '@/utils/segment'
import { JsonResult, msgList, res } from '@/utils/jsonResult';
import { Article as ResArticle, comment as commentType, categories, Articlelabel, tag } from '@/m_res/Article';
@Service()
export class ArticleDao {
@Inject()
orm!: Entity
@Inject()
json!: JsonResult<any>;
@Inject()
segment!: Segment
//全部标签
async GetArticlelabelDao(): Promise<res<Array<tag | null>>> {
return this.json.success(await this.orm.get(Tag).find())
}
//标签 详情
async GetArticlelabeldetailsDao(id: number): Promise<res<Article[]>> {
console.log(111)
let res= await this.orm.get(Article).findBy({
tag_id: Like(`%${id}%`),
})
res.forEach(v => {
v.article_text = v.article_text.substr(0, 100)
})
return this.json.success(res)
}
// 分类 全部
async GetArticgoriesListDao(): Promise<res<Categories[]>> {
return this.json.success(await this.orm.get(Categories).find())
}
// 分类 详情
async GetArticgoriesListinfoDao(id: number): Promise<res<Article[]>> {
let ret= await this.orm.get(Article).findBy({
categories_id: Like(`%${id}%`),
})
ret.forEach(v => {
v.article_text = v.article_text.substr(0, 100)
})
return this.json.success(ret)
}
//搜索
async GetSearchDao(text:string): Promise<res<Article[]>> {
let sql: string = ""
this.segment.ik(text).forEach(v => {
sql += ` or article_title like '%${v.w}%'`
})
let res = await this.orm.repository(Article)
.where(sql.replace("or", ""))
.getMany()
return this.json.success(res)
}
}

View File

@@ -0,0 +1,97 @@
import { User ,selectUserField } from "../entity/User";
import { Entity } from "../utils/orm";
import { Service,Inject } from "typedi";
import manager, { DataSource } from "typeorm";
import config from "../config/init";
import { addUser, } from "@/m_req/User";
import { res,JsonResult ,msgList} from "@/utils/jsonResult";
import md5 from "md5";
import moment from "moment";
import { User as UserType } from "@/m_res/user";
import jsonwebtoken from "jsonwebtoken";
@Service()
export class UserDao{
@Inject()
entity!:Entity;
@Inject()
json!: JsonResult<any>;
async GetOneuser(id:number):Promise<res<UserType | null>>{
let data = <UserType> await this.entity.get(User).findOne({
select: selectUserField,
where: { user_id: id }
});
if (data) {
return this.json.success(data)
} else {
return this.json.success(null,msgList.NoFound)
}
}
async addUserDao(params: addUser): Promise<res<null>> {
let isHave = await this.entity.get(User).findOne({
where: { "user_name": params.name }
});
if (isHave != null) {
return this.json.success(null, msgList.UserNameExist)
} else {
await this.entity.source()
.insert()
.into(User)
.values([
{
user_name: params.name,
user_img: "https://c-ssl.dtstatic.com/uploads/item/202004/29/20200429154321_khaik.thumb.1000_0.jpg",
user_pwd: md5(params.pwd),
user_type: 0,
user_addtime: moment().valueOf()
},
])
.execute()
return this.json.success(null, msgList.addUserSuccess)
}
}
async LoginDao(params: addUser): Promise<res<UserType | null>> {
// const user = await this.entity.get(User).findOneBy({
// user_name: params.name,
// user_pwd: md5(params.pwd),
// })
const user = await this.entity.repository(User)
.where("user.user_name = :user_name", { user_name: params.name })
.andWhere('user.user_pwd = :user_pwd', { user_pwd: md5(params.pwd) })
.getOne()
if (user) {
var token = jsonwebtoken.sign({
user_id: user.user_id,
user_name: user.user_name
}, config.jwtKey);
return this.json.success(token)
} else {
return this.json.error(null,msgList.PasswordError)
}
}
async GetOneUser(id: number): Promise<res<UserType | null>> {
let data = <UserType>await this.entity.get(User).findOne({
select: selectUserField,
where: { user_id: id }
});
if (data) {
return this.json.success(data)
} else {
return this.json.success(null,msgList.NoFound)
}
}
}

View File

@@ -0,0 +1,33 @@
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
@Entity({
name: 'article'
})
export class Article {
@PrimaryGeneratedColumn()
article_id!: number;
@Column()
article_user!: number;
@Column()
article_title!: string;
@Column()
article_time!: number;
@Column()
article_text!: string;
@Column()
article_backimg!: string;
@Column()
article_view!: number;
@Column()
categories_id!: string;
@Column()
tag_id!: string;
}

View File

@@ -0,0 +1,12 @@
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
@Entity({
name: 'categories'
})
export class Categories {
@PrimaryGeneratedColumn()
categories_id!: number;
@Column()
categories_title!: string;
}

View File

@@ -0,0 +1,33 @@
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
@Entity({
name: 'comment'
})
export class Comment {
@PrimaryGeneratedColumn()
comment_id!: number;
@Column()
comment_text!: string;
@Column()
comment_time!: number;
@Column()
comment_father_id!: number;
@Column()
article_id!: number;
// @Column()
// comment_reply_id!: number;
@Column()
user_id!: number;
@Column()
user_reply_id!: number;
@Column()
user_reply_name!: string;
}

View File

@@ -0,0 +1,12 @@
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
@Entity({
name: 'tag'
})
export class Tag {
@PrimaryGeneratedColumn()
tag_id!: number;
@Column()
tag_title!: string;
}

View File

@@ -0,0 +1,35 @@
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
import { Service,Inject } from "typedi";
@Service()
@Entity({ //表名不同时设置
name: 'user'
})
export class User {
@PrimaryGeneratedColumn() //主键
user_id!: number;
@Column()//列
user_name!: string;
@Column()
user_pwd!: string;
@Column()
user_type!: number;
@Column()
user_img!: string;
@Column()
user_addtime!: number;
}
export let selectUserField = {
user_id: true,
user_name:true,
user_img:true,
user_type: true,
user_addtime:true
}

View File

@@ -0,0 +1,19 @@
import { Interceptor,InterceptorInterface,Action } from "routing-controllers";
export class JsonResponse implements InterceptorInterface{
intercept(action: Action, content: any) {
if(content==null||content.length==0){
}else{
}
return content;
}
}

View File

@@ -0,0 +1,24 @@
import { KoaMiddlewareInterface } from 'routing-controllers';
import { Log } from '../utils/log';
import moment from 'moment';
export class RequestLog implements KoaMiddlewareInterface {
async use(context: any, next: (err?: any) => Promise<any>): Promise<any> {
const start = new Date().valueOf()
let nextAction = await next()
const ms = new Date().valueOf() - start
let message: string = `\n1 请求基本信息: ${context.request.method} ${ms}ms ${context.request.url} ${context.request.ip} ${moment().format('YYYY-MM-DD HH:mm:ss')}\n2 请求参数: ${JSON.stringify(
context.request.method == "GET"
? context.request.querystring
: context.request.body
)} \n3 请求头: ${JSON.stringify(context.request.header)} \n\n`;
console.log(message)
Log.ApplicationLogger().warn(message)
return nextAction
}
}

View File

@@ -0,0 +1,19 @@
import { IsString,MinLength,MaxLength,IsNotEmpty ,IsInt,maxLength} from "class-validator";
export class getOneUser{
@IsNotEmpty()
id!:number;
}
export class addUser {
@IsString({ message: "用户名必须字符串" })
@MinLength(3, { message: "用户名最少3个" })
@MaxLength(10, { message: "用户名最长10个" })
name!: string;
@IsString({ message: "密码必须字符串" })
@MinLength(6, { message: "密码最少6位" })
@MaxLength(20, { message: "密码最长20位" })
@IsNotEmpty({message: "密码不为空"})
pwd!: string;
}

View File

@@ -0,0 +1,5 @@
export interface Token {
user_id: number;
user_name: string;
iat: number
}

View File

@@ -0,0 +1,50 @@
export interface categories {
categories_id: number;
categories_title: string;
}
export interface tag {
tag_id: number;
tag_title: string;
}
export interface comment {
[key: string]: any;
comment_id: number;
comment_text: string;
comment_time: number;
comment_father_id: number;
article_id: number;
comment_reply_id: number;
user_id: number;
user_name: string;
user_img: string;
user_reply_id: number;
user_reply_name: string;
comment_children: comment[]
}
export interface Article {
article_id: number;
article_user: number;
article_title: string;
article_time: number;
article_text: string;
article_backimg: string;
article_view: number;
article_comment: comment[];
categories_id: categories[];
tag_id: tag[];
}
//标签
export interface Articlelabel{
article_id: number;
article_user: number;
article_title: string;
article_time: number;
article_text: string;
article_backimg: string;
article_view: number;
categories_id: string;
tag_id: string;
}

View File

@@ -0,0 +1,8 @@
export interface User {
user_id: number;
user_name: string;
user_pwd: string;
user_type: number;
user_img: string;
user_addtime: number;
}

View File

@@ -0,0 +1,39 @@
/*启动后端项目*/
import { init } from "@/run/init";
import { Controller, useKoaServer,useContainer } from "routing-controllers";
import { Container } from "typedi";
import { join } from "path";
import "reflect-metadata";
class App extends init {
app:typeof this.koa
constructor(){
super()
useContainer(Container)
this.app= useKoaServer(this.koa,{
cors:this.config.cors.configCors,
validation:true,
classTransformer:true,
controllers: [ `${join(__dirname, '../controller/**/*{.js,.ts}')}` ]
})
this.run()
}
run(){
this.app.listen(this.config.port, ()=>{
console.log( `
👏 博客后端接口 👏
👉 1:PC官网: http://127.0.0.1:${this.config.port}/
👉 2:Admin后台: xxxxx
`);
}) //支持回调参数
this.app.on('error', (err, ctx) => {
console.error('server error', err, ctx)
});
}
}
new App();

View File

@@ -0,0 +1,53 @@
// @ts-ignore
//初始化项目插件
import Application from "koa";
import bodyparser from 'koa-bodyparser';
import json from 'koa-json';
import logger from 'koa-logger'; //请求日志
// @ts-ignore
import onerror from 'koa-onerror'
import staticPublic from 'koa-static';
import config from "../config/init";
import{ ConfigType } from '../config/init';
import { DataSource } from "typeorm";
import { MysqlConnectionOptions } from "typeorm/driver/mysql/MysqlConnectionOptions";
export class init{
private plugin: Array<Application.Middleware<Application.DefaultState & { }, Application.DefaultContext & {}>> = [];
protected koa:Application =new Application()
protected config: ConfigType =<ConfigType><unknown>config;
protected orm!:DataSource;
constructor(){
this.initPlugin()
}
initPlugin(){
onerror(this.koa);
this.config.orm = new DataSource(<MysqlConnectionOptions>this.config.mysql)
this.config.orm.initialize()
this.plugin=[
bodyparser({
enableTypes:['json', 'form', 'text']
}),
json(),
logger(),
staticPublic(__dirname + config.staticPath),
// async (ctx, next) => {
// const start = new Date().valueOf()
// await next()
// const ms = new Date().valueOf() - start
// console.log(`${ctx.method} ${ctx.url} - ${ms}ms`)
// }
]
this.usePlugin()
}
usePlugin(){
//挂载插件数组到Koa内部
this.plugin.forEach(v=>{
this.koa.use(v)
})
}
}

View File

@@ -0,0 +1,16 @@
import { Article, categories,tag } from '@/m_res/Article'
import { res } from '@/utils/jsonResult';
import { Article as Articlein } from '@/entity/Article';
import {Categories} from '@/entity/Categories';
export interface ArticleService {
//标签
GetArticlelabel():Promise<res<Array<tag|null>>>
//标签详情
GetArticlelabeldetails(id:number):Promise<res<Articlein[]>>
//分类 全部
GetCategoriesList():Promise<res<Categories[]>>
//分类 详情
GetArticgoriesListinfo(id:number):Promise<res<Articlein[]>>
}

View File

@@ -0,0 +1,40 @@
import { ArticleService } from '@/service/ArticleServiceI'
import { ArticleDao } from '@/dao/ArticleDao'
import { Service, Inject } from 'typedi';
import { res } from '@/utils/jsonResult';
import { Article, categories ,Articlelabel,tag} from '@/m_res/Article'
import { Any } from 'typeorm';
import { Article as Articlein } from '@/entity/Article';
import { Categories } from '@/entity/Categories';
@Service()
export class ArticleServiceImpl implements ArticleService {
@Inject()
articleDao!: ArticleDao
//标签全部
async GetArticlelabel():Promise<res<Array<tag|null>>>{
return await this.articleDao.GetArticlelabelDao()
}
//标签 详情
async GetArticlelabeldetails(id:number):Promise<res<Articlein[]>>{
return await this.articleDao.GetArticlelabeldetailsDao(id)
}
//分类全部
async GetCategoriesList():Promise<res<Categories[]>>{
return await this.articleDao.GetArticgoriesListDao()
}
//分类 详情
async GetArticgoriesListinfo(id:number):Promise<res<Articlein[]>>{
return await this.articleDao.GetArticgoriesListinfoDao(id)
}
//搜索
async GetSearch(text:string):Promise<res<Articlein[]>>{
return await this.articleDao.GetSearchDao(text)
}
}

View File

@@ -0,0 +1,37 @@
import { User } from "../../entity/User";
import { userService } from "../userService";
import { Service,Inject } from "typedi";
import { UserDao } from "../../dao/UserDao";
import {res} from "../../utils/jsonResult";
import { addUser } from "@/m_req/User";
import { User as UserType} from "@/m_res/user";
@Service()
export class UserServiceimpl implements userService{
@Inject()
UserDao!:UserDao;
GetAlluser(): User[] {
throw new Error("Method not implemented.");
}
async GetOneuser(id:number): Promise<res<User | null>> {
console.log("cccccc",id)
return await this.UserDao.GetOneuser(id)
}
//用户添加
async addUser(params: addUser): Promise<res<null>> {
return await this.UserDao.addUserDao(params);
}
//登录查询
async Login(params: addUser): Promise<res<UserType | null>> {
return await this.UserDao.LoginDao(params);
}
//token查询
async GetOneUser(id: number): Promise<res<UserType | null>> {
return await this.UserDao.GetOneUser(id);
}
}

View File

@@ -0,0 +1,11 @@
import { User } from "../entity/User";
import { addUser } from '@/m_req/User'
import { res } from "@/utils/jsonResult";
import { User as UserType } from "@/m_res/user";
export interface userService {
GetAlluser():Array<User>
GetOneuser(id:number):Promise<res<User | null>>
addUser(params: addUser): Promise<res<null>>;
Login(params: addUser): Promise<res<UserType | null>>;
GetOneUser(id: number): Promise<res<UserType | null>>;
}

View File

@@ -0,0 +1,27 @@
import { Action } from 'routing-controllers';
import JsonwebToken, { VerifyErrors, JwtPayload } from 'jsonwebtoken'
import config from '@/config/init'
import { JsonResult, msgList } from '@/utils/jsonResult';
/**
* Token检验的装饰器代码实现
*/
export class AuthorizationChecker {
json: JsonResult<null> = new JsonResult
async check(action: Action, roles: string[]): Promise<boolean> {
if (action.request.headers.hasOwnProperty("token")) {
const token = action.request.headers['token'];
return new Promise<boolean>((success: (value: boolean | PromiseLike<boolean>) => void) => {
JsonwebToken.verify( token, config.jwtKey, (err: VerifyErrors | null, decoded: JwtPayload | undefined | string) =>{
if(err){
throw this.json.error(null,msgList.DecodedTokenError)
}else{
action.request.headers['token'] = decoded
success(true)
}
});
})
}
throw this.json.error(null,msgList.NoFoundToken)
}
}

View File

@@ -0,0 +1,81 @@
import { Inject, Service } from 'typedi';
export enum codeList {
Success = 200,
Error = 500,
NoFound = 404
}
export enum msgList {
Success = "请求成功",
Error = "请求成功",
NoFound = "未找到用户",
SystemError = "系统错误",
DeleteSuccess = "删除成功",
NoFoundToken = "缺少token",
DecodedTokenError = "解密token失败",
PasswordError = "用户密码错误,请检查",
UserNameExist = "用户名已存在,请改名",
addUserSuccess = "注册成功",
}
export interface res<T> {
code: number;
msg: string;
data: T;
}
@Service()
export class JsonResult<T> {
// 状态码
private _code!: number;
// 错误的中文信息
private _msg!: string;
// 接口数据
private _data!: T;
public get code(): number {
return this._code;
}
public set code(value: number) {
this._code = value;
}
public get msg(): string {
return this._msg;
}
public set msg(value: string) {
this._msg = value;
}
public get data(): T {
return this._data;
}
public set data(value: T) {
this._data = value;
}
success<U extends T>(data: U, msg?: string, code?: number ) {
this.code = code || codeList.Success;
this.msg = msg || msgList.Success;
this.data = data;
return {
code: this.code,
msg: this.msg,
data: this.data,
}
}
error<U extends T>(data: U, msg?: string, code?: number) {
this.code = code || codeList.Error;
this.msg = msg || msgList.SystemError;
this.data = data;
return {
code: this.code,
msg: this.msg,
data: this.data,
}
}
}

View File

@@ -0,0 +1,20 @@
import log4 from "koa-log4";
import config from "../config/init";
log4.configure(config.logConfig)
export class Log {
/**
* 系统级日志
*/
public static AccessLogger() {
return log4.koaLogger(log4.getLogger('access'), { level: 'auto' });
}
/**
* 应用级别的日志
* @constructor
*/
public static ApplicationLogger() {
return log4.getLogger('application')
}
}

View File

@@ -0,0 +1,35 @@
import { DataSource, EntityTarget, ObjectLiteral, QueryRunner, Repository, SelectQueryBuilder } from "typeorm";
import { MysqlConnectionOptions } from "typeorm/driver/mysql/MysqlConnectionOptions";
import config from '../config/init';
import { Service } from "typedi";
@Service()
export class Entity{
getid<T extends ObjectLiteral>(entity:EntityTarget<T>):Repository<T>{
return(<DataSource><unknown>config.orm).getRepository(entity)
}
// 使用 存储库 查询
get<T extends ObjectLiteral>(entity: EntityTarget<T>): Repository<T> {
return (<DataSource><unknown>config.orm).getRepository(entity)
}
// 基于 实体管理器 创建 QueryBuilder
manager<T extends ObjectLiteral>(entity: EntityTarget<T> | any): SelectQueryBuilder<T> {
return (<DataSource><unknown>config.orm).manager.createQueryBuilder(entity,entity.name.toLowerCase())
}
// 基于 数据源 创建 QueryBuilder
source(queryRunner?: QueryRunner): SelectQueryBuilder<any> {
return (<DataSource><unknown>config.orm).createQueryBuilder(queryRunner)
}
// 基于 存储库 使用 QueryBuilder
repository<T extends ObjectLiteral>(entity: EntityTarget<T> | any): SelectQueryBuilder<ObjectLiteral> {
return (<DataSource><unknown>config.orm).getRepository(entity).createQueryBuilder(entity.name.toLowerCase())
}
}

View File

@@ -0,0 +1,16 @@
//@ts-ignore
import segment from 'segment'
import { Service, Inject } from 'typedi'
@Service()
export class Segment {
seg: segment;
constructor() {
this.seg = new segment()
this.seg.useDefault();
}
ik(text: string): { w: string, p: number }[] {
return this.seg.doSegment(text)
}
}

View File

@@ -0,0 +1,88 @@
{
"compilerOptions": {
"target": "ES2015",
"lib": [
"esnext",
"dom"
],
"module": "commonjs",
"baseUrl": "./",
"outDir": "./dist/",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"strict": true,
"skipLibCheck": true,
"paths": {
"@/*": [
"src/*",
"dist/src*",
],
"@/config/*": [
"src/config/*",
"dist/src/config/*",
],
"@/controller/*": [
"src/controller/*",
"dist/src/controller/*",
],
"@/c_admin/*": [
"src/controller/admin/*",
"dist/src/controller/admin/*",
],
"@/c_app/*": [
"src/controller/app/*",
"dist/src/controller/app/*"
],
"@/dao/*": [
"src/dao/*",
"dist/src/dao/*"
],
"@/entity/*": [
"src/entity/*",
"dist/src/entity/*"
],
"@/middledware/*": [
"src/middledware/*",
"dist/src/middledware/*"
],
"@/model/*": [
"src/model/*",
"dist/src/model/*"
],
"@/m_req/*": [
"src/model/request/*",
"dist/src/model/request/*"
],
"@/m_res/*": [
"src/model/response/*",
"dist/src/model/response/*"
],
"@/plugins/*": [
"src/plugins/*",
"dist/src/plugins/*"
],
"@/public/*": [
"src/public/*",
"dist/src/public/*"
],
"@/run/*": [
"src/run/*",
"dist/src/run/*"
],
"@/service/*": [
"src/service/*",
"dist/service/*"
],
"@/impl/*": [
"src/service/impl/*",
"dist/src/service/impl/*"
],
"@/utils/*": [
"src/utils/*",
"dist/src/utils/*"
],
}
}
}

View File

@@ -0,0 +1,44 @@
插件
cross-env 环境变量插件
routing-controllers
kcors
npm install class-validator --save 参数检查效验 需要与reflect-metadata 搭配
koa-log4 日志插件
moment 时间插件
TypeORM 数据库
typrdi 调class库
tsconfig-paths 插件 使用类型别名时使用
md5 加密插件
网址
https://blog.csdn.net/pzy_666/article/details/123369193 禁用eslint / ts相关检查
笔记
path.join() 拼接字符串需引用 path (onde.js 自带)
routing-controllers
useContainer 注入
controller 调 service 调 dao 调 entity