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,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