mirror of
https://github.com/cool-team-official/cool-admin-midway.git
synced 2025-12-11 00:22:49 +00:00
整理
This commit is contained in:
parent
b8b40b4bf2
commit
a618bd70b0
252
.cursorrules
252
.cursorrules
@ -33,254 +33,4 @@
|
||||
│ │ └── service(服务,写业务逻辑)
|
||||
│ │ └── config.ts(必须,模块的配置)
|
||||
│ │ └── db.json(可选,初始化该模块的数据)
|
||||
│ │ └── menu.json(可选,初始化该模块的菜单)
|
||||
|
||||
# 核心
|
||||
|
||||
- Controller
|
||||
|
||||
```ts
|
||||
import { Get, Provide } from "@midwayjs/core";
|
||||
import { CoolController, BaseController } from "@cool-midway/core";
|
||||
import { BaseSysUserEntity } from "../../../base/entity/sys/user";
|
||||
import { DemoAppGoodsEntity } from "../../entity/goods";
|
||||
|
||||
/**
|
||||
* 商品
|
||||
*/
|
||||
@Provide()
|
||||
@CoolController({
|
||||
// 添加通用CRUD接口
|
||||
api: ["add", "delete", "update", "info", "list", "page"],
|
||||
// 设置表实体
|
||||
entity: DemoAppGoodsEntity,
|
||||
// 向表插入当前登录用户ID
|
||||
insertParam: (ctx) => {
|
||||
return {
|
||||
// 获得当前登录的后台用户ID,需要请求头传Authorization参数
|
||||
userId: ctx.admin.userId,
|
||||
};
|
||||
},
|
||||
// 操作crud之前做的事情 @cool-midway/core@3.2.14 新增
|
||||
before: (ctx) => {
|
||||
// 将前端的数据转JSON格式存数据库
|
||||
const { data } = ctx.request.body;
|
||||
ctx.request.body.data = JSON.stringify(data);
|
||||
},
|
||||
// info接口忽略价格字段
|
||||
infoIgnoreProperty: ["a.price"],
|
||||
// 分页查询配置
|
||||
pageQueryOp: {
|
||||
// 让title字段支持模糊查询
|
||||
keyWordLikeFields: ["a.title"],
|
||||
// 让type字段支持筛选,请求筛选字段与表字段一致是情况
|
||||
fieldEq: ["a.type"],
|
||||
// 多表关联,请求筛选字段与表字段不一致的情况
|
||||
fieldEq: [{ column: "a.id", requestParam: "id" }],
|
||||
// 指定返回字段,注意多表查询这个是必要的,否则会出现重复字段的问题
|
||||
select: ["a.*", "b.name", "a.name AS userName"],
|
||||
// 4.x置为过时 改用 join 关联表用户表
|
||||
leftJoin: [
|
||||
{
|
||||
entity: BaseSysUserEntity,
|
||||
alias: "b",
|
||||
condition: "a.userId = b.id",
|
||||
},
|
||||
],
|
||||
// 4.x新增
|
||||
join: [
|
||||
{
|
||||
entity: BaseSysUserEntity,
|
||||
alias: "b",
|
||||
condition: "a.userId = b.id",
|
||||
type: "innerJoin",
|
||||
},
|
||||
],
|
||||
// 4.x 新增 追加其他条件
|
||||
extend: async (find: SelectQueryBuilder<DemoGoodsEntity>) => {
|
||||
find.groupBy("a.id");
|
||||
},
|
||||
// 增加其他条件
|
||||
where: async (ctx) => {
|
||||
// 获取body参数
|
||||
const { a } = ctx.request.body;
|
||||
return [
|
||||
// 价格大于90
|
||||
["a.price > :price", { price: 90.0 }],
|
||||
// 满足条件才会执行
|
||||
["a.price > :price", { price: 90.0 }, "条件"],
|
||||
// 多个条件一起
|
||||
[
|
||||
"(a.price = :price or a.userId = :userId)",
|
||||
{ price: 90.0, userId: ctx.admin.userId },
|
||||
],
|
||||
];
|
||||
},
|
||||
// 可选,添加排序,默认按createTime Desc排序
|
||||
addOrderBy: {
|
||||
price: "desc",
|
||||
},
|
||||
},
|
||||
})
|
||||
export class DemoAppGoodsController extends BaseController {
|
||||
/**
|
||||
* 其他接口
|
||||
*/
|
||||
@Get("/other")
|
||||
async other() {
|
||||
return this.ok("hello, cool-admin!!!");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
注意:
|
||||
- CoolController的entity,alias 为 "a";
|
||||
- 如果是多表查询,必须设置 select 参数,否则会出现重复字段的错误,因为每个表都继承了 BaseEntity,至少都有 id、createTime、updateTime 三个相同的字段;
|
||||
- keyWordLikeFields、fieldEq等配置哪个字段,都需要有对应的别名;
|
||||
|
||||
- Entity
|
||||
|
||||
```ts
|
||||
// BaseEntity的路径是固定,不能修改
|
||||
import { BaseEntity } from '../../base/entity/base';
|
||||
import { Column, Entity, Index } from 'typeorm';
|
||||
|
||||
/**
|
||||
* demo模块-用户信息
|
||||
*/
|
||||
// 表名必须包含模块固定格式:模块_,
|
||||
@Entity('demo_user_info')
|
||||
// DemoUserInfoEntity是模块+表名+Entity
|
||||
export class DemoUserInfoEntity extends BaseEntity {
|
||||
@Index()
|
||||
@Column({ comment: '手机号', length: 11 })
|
||||
phone: string;
|
||||
|
||||
@Index({ unique: true })
|
||||
@Column({ comment: '身份证', length: 50 })
|
||||
idCard: string;
|
||||
|
||||
// 生日只需要精确到哪一天,所以type:'date',如果需要精确到时分秒,应为'datetime'
|
||||
@Column({ comment: '生日', type: 'date' })
|
||||
birthday: Date;
|
||||
|
||||
@Column({ comment: '状态', dict: ['禁用', '启用'], default: 1 })
|
||||
status: number;
|
||||
|
||||
@Column({ comment: '分类', dict: ['普通', '会员', '超级会员'], default: 0, type: 'tinyint' })
|
||||
type: number;
|
||||
|
||||
// 由于labels的类型是一个数组,所以Column中的type类型必须得是'json'
|
||||
@Column({ comment: '标签', nullable: true, type: 'json' })
|
||||
labels: string[];
|
||||
|
||||
@Column({
|
||||
comment: '余额',
|
||||
type: 'decimal',
|
||||
precision: 12,
|
||||
scale: 2,
|
||||
})
|
||||
balance: number;
|
||||
|
||||
@Column({ comment: '备注', nullable: true })
|
||||
remark: string;
|
||||
|
||||
@Column({ comment: '简介', type: 'text', nullable: true })
|
||||
summary: string;
|
||||
|
||||
@Column({ comment: '省', length: 50 })
|
||||
province: string;
|
||||
|
||||
@Column({ comment: '市', length: 50 })
|
||||
city: string;
|
||||
|
||||
@Column({ comment: '区', length: 50 })
|
||||
district: string;
|
||||
|
||||
@Column({ comment: '详细地址', length: 255 })
|
||||
address: string;
|
||||
}
|
||||
```
|
||||
注意:
|
||||
- 禁止使用外键,如ManyToOne、JoinColumn等;
|
||||
- comment需要简短,如班级表的名称不要叫班级名称,直接叫名称;
|
||||
- dict如果遇到可选项如:状态、类型等需要配置;
|
||||
- BaseEntity的路径是固定,不能修改;
|
||||
|
||||
- Service
|
||||
|
||||
```ts
|
||||
import { Init, Provide } from '@midwayjs/core';
|
||||
import { BaseService } from '@cool-midway/core';
|
||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
@Provide()
|
||||
export class XxxService extends BaseService {
|
||||
@InjectEntityModel(实体)
|
||||
xxxEntity: Repository<实体>;
|
||||
|
||||
// 获得ctx
|
||||
@Inject()
|
||||
ctx;
|
||||
|
||||
@Init()
|
||||
async init() {
|
||||
await super.init();
|
||||
this.setEntity(this.xxxEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 其它方法
|
||||
*/
|
||||
async xxx() {}
|
||||
}
|
||||
```
|
||||
|
||||
- 自动路由
|
||||
|
||||
规则: /controller 文件夹下的文件夹名或者文件名/模块文件夹名/方法名
|
||||
// 模块目录
|
||||
├── modules
|
||||
│ └── demo(模块名)
|
||||
│ │ └── controller(api接口)
|
||||
│ │ │ └── app(参数校验)
|
||||
│ │ │ │ └── goods.ts(商品的controller)
|
||||
│ │ │ └── pay.ts(支付的controller)
|
||||
│ │ └── config.ts(必须,模块的配置)
|
||||
│ │ └── init.sql(可选,初始化该模块的sql)
|
||||
|
||||
生成的路由前缀为: /pay/demo/xxx(具体的方法)与/app/demo/goods/xxx(具体的方法)
|
||||
|
||||
- config.ts
|
||||
|
||||
```ts
|
||||
import { ModuleConfig } from '@cool-midway/core';
|
||||
|
||||
/**
|
||||
* 模块配置
|
||||
*/
|
||||
export default () => {
|
||||
return {
|
||||
// 模块名称
|
||||
name: 'xxx',
|
||||
// 模块描述
|
||||
description: 'xxx',
|
||||
// 中间件,只对本模块有效
|
||||
middlewares: [],
|
||||
// 中间件,全局有效
|
||||
globalMiddlewares: [],
|
||||
// 模块加载顺序,默认为0,值越大越优先加载
|
||||
order: 0,
|
||||
} as ModuleConfig;
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
# 其它
|
||||
- 根据需要进行必要的关联表查询;
|
||||
- 禁止出现import 但是没有使用的情况;
|
||||
- 所有代码需有类级注释;
|
||||
│ │ └── menu.json(可选,初始化该模块的菜单)
|
||||
@ -4,7 +4,7 @@
|
||||
"description": "一个很酷的Ai快速开发框架",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@cool-midway/core": "8.0.0-beta.1",
|
||||
"@cool-midway/core": "file:///Users/ap/Documents/src/admin/midway-packages/core",
|
||||
"@cool-midway/rpc": "8.0.0-beta.2",
|
||||
"@cool-midway/task": "8.0.0-beta.2",
|
||||
"@midwayjs/bootstrap": "^3.20.0",
|
||||
|
||||
43
pnpm-lock.yaml
generated
43
pnpm-lock.yaml
generated
@ -9,8 +9,8 @@ importers:
|
||||
.:
|
||||
dependencies:
|
||||
'@cool-midway/core':
|
||||
specifier: 8.0.0-beta.1
|
||||
version: 8.0.0-beta.1(debug@4.4.0)
|
||||
specifier: file:///Users/ap/Documents/src/admin/midway-packages/core
|
||||
version: file:../midway-packages/core(debug@4.4.0)
|
||||
'@cool-midway/rpc':
|
||||
specifier: 8.0.0-beta.2
|
||||
version: 8.0.0-beta.2(debug@4.4.0)(encoding@0.1.13)
|
||||
@ -62,9 +62,6 @@ importers:
|
||||
cron:
|
||||
specifier: ^3.5.0
|
||||
version: 3.5.0
|
||||
deasync:
|
||||
specifier: ^0.1.30
|
||||
version: 0.1.30
|
||||
jsonwebtoken:
|
||||
specifier: ^9.0.2
|
||||
version: 9.0.2
|
||||
@ -321,8 +318,8 @@ packages:
|
||||
resolution: {integrity: sha512-Bl43bVCUm0V+w1wkfOicRfiHHZtaH1mQCp06baNapG86uC7OiXwMrml5+cvZD+mYSHdP07qUxtqkL8oUhrgAfg==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
|
||||
'@cool-midway/core@8.0.0-beta.1':
|
||||
resolution: {integrity: sha512-3pNmtB2f3MrkBPCJlFiizWui1FqGxti8VBaBtOWJhg66tZeNdsSQsnG4/o1R2WfLHjlMkSMsCL0Jrl7HC7/Aig==}
|
||||
'@cool-midway/core@file:../midway-packages/core':
|
||||
resolution: {directory: ../midway-packages/core, type: directory}
|
||||
hasBin: true
|
||||
|
||||
'@cool-midway/rpc@8.0.0-beta.2':
|
||||
@ -1638,10 +1635,6 @@ packages:
|
||||
dayjs@1.8.36:
|
||||
resolution: {integrity: sha512-3VmRXEtw7RZKAf+4Tv1Ym9AGeo8r8+CjDi26x+7SYQil1UqtqdaokhzoEJohqlzt0m5kacJSDhJQkG/LWhpRBw==}
|
||||
|
||||
deasync@0.1.30:
|
||||
resolution: {integrity: sha512-OaAjvEQuQ9tJsKG4oHO9nV1UHTwb2Qc2+fadB0VeVtD0Z9wiG1XPGLJ4W3aLhAoQSYTaLROFRbd5X20Dkzf7MQ==}
|
||||
engines: {node: '>=0.11.0'}
|
||||
|
||||
debug@3.2.7:
|
||||
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
|
||||
peerDependencies:
|
||||
@ -2949,8 +2942,8 @@ packages:
|
||||
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
|
||||
libphonenumber-js@1.11.18:
|
||||
resolution: {integrity: sha512-okMm/MCoFrm1vByeVFLBdkFIXLSHy/AIK2AEGgY3eoicfWZeOZqv3GfhtQgICkzs/tqorAMm3a4GBg5qNCrqzg==}
|
||||
libphonenumber-js@1.11.19:
|
||||
resolution: {integrity: sha512-bW/Yp/9dod6fmyR+XqSUL1N5JE7QRxQ3KrBIbYS1FTv32e5i3SEtQVX+71CYNv8maWNSOgnlCoNp9X78f/cKiA==}
|
||||
|
||||
lines-and-columns@1.2.4:
|
||||
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
|
||||
@ -3398,9 +3391,6 @@ packages:
|
||||
node-abort-controller@3.1.1:
|
||||
resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==}
|
||||
|
||||
node-addon-api@1.7.2:
|
||||
resolution: {integrity: sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==}
|
||||
|
||||
node-addon-api@7.1.1:
|
||||
resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
|
||||
|
||||
@ -3713,8 +3703,8 @@ packages:
|
||||
engines: {node: '>=12.0.0'}
|
||||
hasBin: true
|
||||
|
||||
possible-typed-array-names@1.0.0:
|
||||
resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
|
||||
possible-typed-array-names@1.1.0:
|
||||
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
prebuild-install@7.1.3:
|
||||
@ -4900,7 +4890,7 @@ snapshots:
|
||||
dependencies:
|
||||
lockfile: 1.0.4
|
||||
|
||||
'@cool-midway/core@8.0.0-beta.1(debug@4.4.0)':
|
||||
'@cool-midway/core@file:../midway-packages/core(debug@4.4.0)':
|
||||
dependencies:
|
||||
'@cool-midway/cache-manager-fs-hash': 7.0.0
|
||||
'@midwayjs/cache-manager': 3.20.0
|
||||
@ -5993,7 +5983,7 @@ snapshots:
|
||||
|
||||
available-typed-arrays@1.0.7:
|
||||
dependencies:
|
||||
possible-typed-array-names: 1.0.0
|
||||
possible-typed-array-names: 1.1.0
|
||||
|
||||
aws-ssl-profiles@1.1.2: {}
|
||||
|
||||
@ -6304,7 +6294,7 @@ snapshots:
|
||||
class-validator@0.14.1:
|
||||
dependencies:
|
||||
'@types/validator': 13.12.2
|
||||
libphonenumber-js: 1.11.18
|
||||
libphonenumber-js: 1.11.19
|
||||
validator: 13.12.0
|
||||
|
||||
clean-stack@2.2.0:
|
||||
@ -6504,11 +6494,6 @@ snapshots:
|
||||
|
||||
dayjs@1.8.36: {}
|
||||
|
||||
deasync@0.1.30:
|
||||
dependencies:
|
||||
bindings: 1.5.0
|
||||
node-addon-api: 1.7.2
|
||||
|
||||
debug@3.2.7:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
@ -8110,7 +8095,7 @@ snapshots:
|
||||
prelude-ls: 1.2.1
|
||||
type-check: 0.4.0
|
||||
|
||||
libphonenumber-js@1.11.18: {}
|
||||
libphonenumber-js@1.11.19: {}
|
||||
|
||||
lines-and-columns@1.2.4: {}
|
||||
|
||||
@ -8505,8 +8490,6 @@ snapshots:
|
||||
|
||||
node-abort-controller@3.1.1: {}
|
||||
|
||||
node-addon-api@1.7.2: {}
|
||||
|
||||
node-addon-api@7.1.1: {}
|
||||
|
||||
node-fetch@2.7.0(encoding@0.1.13):
|
||||
@ -8861,7 +8844,7 @@ snapshots:
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
possible-typed-array-names@1.0.0: {}
|
||||
possible-typed-array-names@1.1.0: {}
|
||||
|
||||
prebuild-install@7.1.3:
|
||||
dependencies:
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { CoolConfig } from '@cool-midway/core';
|
||||
import { MidwayConfig } from '@midwayjs/core';
|
||||
import { pSqlitePath } from '../comm/path';
|
||||
import { entities } from '../entities';
|
||||
import { TenantSubscriber } from '../modules/base/db/tenant';
|
||||
|
||||
/**
|
||||
|
||||
@ -3,6 +3,7 @@ import { MidwayConfig } from '@midwayjs/core';
|
||||
import { entities } from '../entities';
|
||||
import { pSqlitePath } from '../comm/path';
|
||||
import { TenantSubscriber } from '../modules/base/db/tenant';
|
||||
|
||||
/**
|
||||
* 本地开发 npm run prod 读取的配置文件
|
||||
*/
|
||||
|
||||
@ -1 +0,0 @@
|
||||
2025-01-21T11:32:10.104Z
|
||||
@ -1,11 +0,0 @@
|
||||
{
|
||||
"COOL": "COOL",
|
||||
"闪酷": "Flashy",
|
||||
"法师": "Mage",
|
||||
"战士": "Warrior",
|
||||
"坦克": "Tank",
|
||||
"刺客": "Assassin",
|
||||
"射手": "Shooter",
|
||||
"幻影刺客": "Phantom Assassin",
|
||||
"你好": "Hello"
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
{
|
||||
"COOL": "COOL",
|
||||
"闪酷": "闪酷",
|
||||
"法师": "法师",
|
||||
"战士": "战士",
|
||||
"坦克": "坦克",
|
||||
"刺客": "刺客",
|
||||
"射手": "射手",
|
||||
"幻影刺客": "幻影刺客",
|
||||
"你好": "你好"
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
{
|
||||
"COOL": "酷",
|
||||
"闪酷": "閃酷",
|
||||
"法师": "法師",
|
||||
"战士": "戰士",
|
||||
"坦克": "坦克",
|
||||
"刺客": "刺客",
|
||||
"射手": "射手",
|
||||
"幻影刺客": "幻影刺客",
|
||||
"你好": "你好"
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
{
|
||||
"品牌": "Brand",
|
||||
"职业": "Job"
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
{
|
||||
"品牌": "品牌",
|
||||
"职业": "职业"
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
{
|
||||
"品牌": "品牌",
|
||||
"职业": "職業"
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
2025-01-21T11:32:17.870Z
|
||||
@ -1,47 +0,0 @@
|
||||
{
|
||||
"系统管理": "System",
|
||||
"权限管理": "Auth",
|
||||
"菜单列表": "Menu",
|
||||
"新增": "Add",
|
||||
"删除": "Del",
|
||||
"查询": "Search",
|
||||
"参数": "Param",
|
||||
"编辑": "Edit",
|
||||
"角色列表": "Role",
|
||||
"修改": "Modify",
|
||||
"用户列表": "User",
|
||||
"部门列表": "Dept",
|
||||
"新增部门": "Add Dept",
|
||||
"更新部门": "Update Dept",
|
||||
"删除部门": "Del Dept",
|
||||
"部门排序": "Sort Dept",
|
||||
"用户转移": "Transfer",
|
||||
"参数配置": "Config",
|
||||
"参数列表": "Param List",
|
||||
"查看": "View",
|
||||
"监控管理": "Monitor",
|
||||
"请求日志": "Log",
|
||||
"权限": "Auth",
|
||||
"任务管理": "Task",
|
||||
"任务列表": "Task List",
|
||||
"框架教程": "Tutorial",
|
||||
"文档官网": "Docs",
|
||||
"crud 示例": "CRUD",
|
||||
"通用": "Common",
|
||||
"图片上传": "Upload",
|
||||
"首页": "Home",
|
||||
"数据管理": "Data",
|
||||
"字典管理": "Dict",
|
||||
"获得字典数据": "Get Dict",
|
||||
"单个信息": "Single",
|
||||
"列表查询": "List",
|
||||
"分页查询": "Page",
|
||||
"组权限": "Group",
|
||||
"字典类型": "Dict Type",
|
||||
"数据回收站": "Recycle",
|
||||
"恢复数据": "Restore",
|
||||
"文件管理": "File",
|
||||
"用户管理": "User",
|
||||
"扩展管理": "Extend",
|
||||
"插件列表": "Plugin"
|
||||
}
|
||||
@ -1,47 +0,0 @@
|
||||
{
|
||||
"系统管理": "系统管理",
|
||||
"权限管理": "权限管理",
|
||||
"菜单列表": "菜单列表",
|
||||
"新增": "新增",
|
||||
"删除": "删除",
|
||||
"查询": "查询",
|
||||
"参数": "参数",
|
||||
"编辑": "编辑",
|
||||
"角色列表": "角色列表",
|
||||
"修改": "修改",
|
||||
"用户列表": "用户列表",
|
||||
"部门列表": "部门列表",
|
||||
"新增部门": "新增部门",
|
||||
"更新部门": "更新部门",
|
||||
"删除部门": "删除部门",
|
||||
"部门排序": "部门排序",
|
||||
"用户转移": "用户转移",
|
||||
"参数配置": "参数配置",
|
||||
"参数列表": "参数列表",
|
||||
"查看": "查看",
|
||||
"监控管理": "监控管理",
|
||||
"请求日志": "请求日志",
|
||||
"权限": "权限",
|
||||
"任务管理": "任务管理",
|
||||
"任务列表": "任务列表",
|
||||
"框架教程": "框架教程",
|
||||
"文档官网": "文档官网",
|
||||
"crud 示例": "crud 示例",
|
||||
"通用": "通用",
|
||||
"图片上传": "图片上传",
|
||||
"首页": "首页",
|
||||
"数据管理": "数据管理",
|
||||
"字典管理": "字典管理",
|
||||
"获得字典数据": "获得字典数据",
|
||||
"单个信息": "单个信息",
|
||||
"列表查询": "列表查询",
|
||||
"分页查询": "分页查询",
|
||||
"组权限": "组权限",
|
||||
"字典类型": "字典类型",
|
||||
"数据回收站": "数据回收站",
|
||||
"恢复数据": "恢复数据",
|
||||
"文件管理": "文件管理",
|
||||
"用户管理": "用户管理",
|
||||
"扩展管理": "扩展管理",
|
||||
"插件列表": "插件列表"
|
||||
}
|
||||
@ -1,47 +0,0 @@
|
||||
{
|
||||
"系统管理": "系統管理",
|
||||
"权限管理": "權限管理",
|
||||
"菜单列表": "選單列表",
|
||||
"新增": "新增",
|
||||
"删除": "刪除",
|
||||
"查询": "查詢",
|
||||
"参数": "參數",
|
||||
"编辑": "編輯",
|
||||
"角色列表": "角色列表",
|
||||
"修改": "修改",
|
||||
"用户列表": "用戶列表",
|
||||
"部门列表": "部門列表",
|
||||
"新增部门": "新增部門",
|
||||
"更新部门": "更新部門",
|
||||
"删除部门": "刪除部門",
|
||||
"部门排序": "部門排序",
|
||||
"用户转移": "用戶轉移",
|
||||
"参数配置": "參數配置",
|
||||
"参数列表": "參數列表",
|
||||
"查看": "查看",
|
||||
"监控管理": "監控管理",
|
||||
"请求日志": "請求日誌",
|
||||
"权限": "權限",
|
||||
"任务管理": "任務管理",
|
||||
"任务列表": "任務列表",
|
||||
"框架教程": "框架教程",
|
||||
"文档官网": "文件官網",
|
||||
"crud 示例": "crud 示例",
|
||||
"通用": "通用",
|
||||
"图片上传": "圖片上傳",
|
||||
"首页": "首頁",
|
||||
"数据管理": "數據管理",
|
||||
"字典管理": "字典管理",
|
||||
"获得字典数据": "獲得字典數據",
|
||||
"单个信息": "單個信息",
|
||||
"列表查询": "列表查詢",
|
||||
"分页查询": "分頁查詢",
|
||||
"组权限": "組權限",
|
||||
"字典类型": "字典類型",
|
||||
"数据回收站": "數據回收站",
|
||||
"恢复数据": "恢復數據",
|
||||
"文件管理": "文件管理",
|
||||
"用户管理": "用戶管理",
|
||||
"扩展管理": "擴展管理",
|
||||
"插件列表": "插件列表"
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
2025-01-21T11:32:17.869Z
|
||||
@ -1,27 +0,0 @@
|
||||
{
|
||||
"登录失效~": "Login expired~",
|
||||
"登录失效或无权限访问~": "Login expired or no access~",
|
||||
"账户或密码不正确~": "Incorrect account or password~",
|
||||
"该用户未设置任何角色,无法登录~": "No role set, cannot login~",
|
||||
"验证码不正确": "Incorrect code",
|
||||
"代码结构不正确,请检查": "Invalid code structure, check",
|
||||
"存在相同的keyName": "Duplicate keyName",
|
||||
"非法操作~": "Illegal operation~",
|
||||
"用户名已经存在~": "Username exists~",
|
||||
"用户不存在": "User not found",
|
||||
"原密码错误": "Wrong old password",
|
||||
"非法的key值": "Invalid key",
|
||||
"上传文件为空": "Empty upload",
|
||||
"插件信息不完整": "Incomplete plugin info",
|
||||
"插件key不能为plugin,请更换其他key": "Plugin key cannot be 'plugin', change it",
|
||||
"更新失败,参数错误或者手机号已存在": "Update failed, wrong params or phone exists",
|
||||
"验证码错误": "Wrong code",
|
||||
"图片验证码错误": "Wrong image code",
|
||||
"获得手机号失败,请检查配置": "Failed to get phone, check config",
|
||||
"token类型非refreshToken": "Token type not refreshToken",
|
||||
"账号或密码错误": "Wrong account or password",
|
||||
"发送过于频繁,请稍后再试": "Too frequent, try later",
|
||||
"用户不存在或已被禁用": "User not found or disabled",
|
||||
"登录失败,请重试": "Login failed, retry",
|
||||
"获取手机号失败,请刷新重试": "Failed to get phone, refresh and retry"
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
{
|
||||
"登录失效~": "登录失效~",
|
||||
"登录失效或无权限访问~": "登录失效或无权限访问~",
|
||||
"账户或密码不正确~": "账户或密码不正确~",
|
||||
"该用户未设置任何角色,无法登录~": "该用户未设置任何角色,无法登录~",
|
||||
"验证码不正确": "验证码不正确",
|
||||
"代码结构不正确,请检查": "代码结构不正确,请检查",
|
||||
"存在相同的keyName": "存在相同的keyName",
|
||||
"非法操作~": "非法操作~",
|
||||
"用户名已经存在~": "用户名已经存在~",
|
||||
"用户不存在": "用户不存在",
|
||||
"原密码错误": "原密码错误",
|
||||
"非法的key值": "非法的key值",
|
||||
"上传文件为空": "上传文件为空",
|
||||
"插件信息不完整": "插件信息不完整",
|
||||
"插件key不能为plugin,请更换其他key": "插件key不能为plugin,请更换其他key",
|
||||
"更新失败,参数错误或者手机号已存在": "更新失败,参数错误或者手机号已存在",
|
||||
"验证码错误": "验证码错误",
|
||||
"图片验证码错误": "图片验证码错误",
|
||||
"获得手机号失败,请检查配置": "获得手机号失败,请检查配置",
|
||||
"token类型非refreshToken": "token类型非refreshToken",
|
||||
"账号或密码错误": "账号或密码错误",
|
||||
"发送过于频繁,请稍后再试": "发送过于频繁,请稍后再试",
|
||||
"用户不存在或已被禁用": "用户不存在或已被禁用",
|
||||
"登录失败,请重试": "登录失败,请重试",
|
||||
"获取手机号失败,请刷新重试": "获取手机号失败,请刷新重试"
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
{
|
||||
"登录失效~": "登入失效~",
|
||||
"登录失效或无权限访问~": "登入失效或無權限訪問~",
|
||||
"账户或密码不正确~": "帳號或密碼不正確~",
|
||||
"该用户未设置任何角色,无法登录~": "該用戶未設置任何角色,無法登入~",
|
||||
"验证码不正确": "驗證碼不正確",
|
||||
"代码结构不正确,请检查": "代碼結構不正確,請檢查",
|
||||
"存在相同的keyName": "存在相同的keyName",
|
||||
"非法操作~": "非法操作~",
|
||||
"用户名已经存在~": "用戶名已經存在~",
|
||||
"用户不存在": "用戶不存在",
|
||||
"原密码错误": "原密碼錯誤",
|
||||
"非法的key值": "非法的key值",
|
||||
"上传文件为空": "上傳文件為空",
|
||||
"插件信息不完整": "插件信息不完整",
|
||||
"插件key不能为plugin,请更换其他key": "插件key不能為plugin,請更換其他key",
|
||||
"更新失败,参数错误或者手机号已存在": "更新失敗,參數錯誤或手機號已存在",
|
||||
"验证码错误": "驗證碼錯誤",
|
||||
"图片验证码错误": "圖片驗證碼錯誤",
|
||||
"获得手机号失败,请检查配置": "獲取手機號失敗,請檢查配置",
|
||||
"token类型非refreshToken": "token類型非refreshToken",
|
||||
"账号或密码错误": "帳號或密碼錯誤",
|
||||
"发送过于频繁,请稍后再试": "發送過於頻繁,請稍後再試",
|
||||
"用户不存在或已被禁用": "用戶不存在或已被禁用",
|
||||
"登录失败,请重试": "登入失敗,請重試",
|
||||
"获取手机号失败,请刷新重试": "獲取手機號失敗,請刷新重試"
|
||||
}
|
||||
@ -16,7 +16,7 @@ export default () => {
|
||||
globalMiddlewares: [
|
||||
BaseTranslateMiddleware,
|
||||
BaseAuthorityMiddleware,
|
||||
// BaseLogMiddleware,
|
||||
BaseLogMiddleware,
|
||||
],
|
||||
// 模块加载顺序,默认为0,值越大越优先加载
|
||||
order: 10,
|
||||
|
||||
@ -1,12 +1,18 @@
|
||||
import {
|
||||
Index,
|
||||
UpdateDateColumn,
|
||||
CreateDateColumn,
|
||||
PrimaryGeneratedColumn,
|
||||
Column,
|
||||
} from 'typeorm';
|
||||
import { Index, PrimaryGeneratedColumn, Column } from 'typeorm';
|
||||
import * as moment from 'moment';
|
||||
import { CoolBaseEntity } from '@cool-midway/core';
|
||||
|
||||
const transformer = {
|
||||
to(value) {
|
||||
return value
|
||||
? moment(value).format('YYYY-MM-DD HH:mm:ss')
|
||||
: moment().format('YYYY-MM-DD HH:mm:ss');
|
||||
},
|
||||
from(value) {
|
||||
return value;
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 实体基类
|
||||
*/
|
||||
@ -18,11 +24,19 @@ export abstract class BaseEntity extends CoolBaseEntity {
|
||||
id: number;
|
||||
|
||||
@Index()
|
||||
@CreateDateColumn({ comment: '创建时间' })
|
||||
@Column({
|
||||
comment: '创建时间',
|
||||
type: 'varchar',
|
||||
transformer,
|
||||
})
|
||||
createTime: Date;
|
||||
|
||||
@Index()
|
||||
@UpdateDateColumn({ comment: '更新时间' })
|
||||
@Column({
|
||||
comment: '更新时间',
|
||||
type: 'varchar',
|
||||
transformer,
|
||||
})
|
||||
updateTime: Date;
|
||||
|
||||
@Index()
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
"router": "/sys",
|
||||
"perms": null,
|
||||
"type": 0,
|
||||
"icon": "icon-system",
|
||||
"icon": "icon-set",
|
||||
"orderNum": 2,
|
||||
"viewPath": null,
|
||||
"keepAlive": true,
|
||||
@ -834,20 +834,100 @@
|
||||
"isShow": true,
|
||||
"childMenus": [
|
||||
{
|
||||
"name": "后端插件",
|
||||
"router": "/helper/plugins/serve",
|
||||
"tenantId": null,
|
||||
"name": "插件列表",
|
||||
"router": "/helper/plugins",
|
||||
"perms": null,
|
||||
"type": 1,
|
||||
"icon": "icon-component",
|
||||
"orderNum": 2,
|
||||
"viewPath": "modules/helper/views/plugins/serve.vue",
|
||||
"icon": "icon-list",
|
||||
"orderNum": 1,
|
||||
"viewPath": "modules/helper/views/plugins.vue",
|
||||
"keepAlive": true,
|
||||
"isShow": true,
|
||||
"childMenus": [
|
||||
{
|
||||
"name": "权限",
|
||||
"tenantId": null,
|
||||
"name": "删除",
|
||||
"router": null,
|
||||
"perms": "plugin:info:install,plugin:info:delete,plugin:info:update,plugin:info:page,plugin:info:info",
|
||||
"perms": "plugin:info:delete",
|
||||
"type": 2,
|
||||
"icon": null,
|
||||
"orderNum": 0,
|
||||
"viewPath": null,
|
||||
"keepAlive": true,
|
||||
"isShow": true,
|
||||
"childMenus": []
|
||||
},
|
||||
{
|
||||
"tenantId": null,
|
||||
"name": "分页查询",
|
||||
"router": null,
|
||||
"perms": "plugin:info:page",
|
||||
"type": 2,
|
||||
"icon": null,
|
||||
"orderNum": 0,
|
||||
"viewPath": null,
|
||||
"keepAlive": true,
|
||||
"isShow": true,
|
||||
"childMenus": []
|
||||
},
|
||||
{
|
||||
"tenantId": null,
|
||||
"name": "单个信息",
|
||||
"router": null,
|
||||
"perms": "plugin:info:info",
|
||||
"type": 2,
|
||||
"icon": null,
|
||||
"orderNum": 0,
|
||||
"viewPath": null,
|
||||
"keepAlive": true,
|
||||
"isShow": true,
|
||||
"childMenus": []
|
||||
},
|
||||
{
|
||||
"tenantId": null,
|
||||
"name": "安装插件",
|
||||
"router": null,
|
||||
"perms": "plugin:info:install",
|
||||
"type": 2,
|
||||
"icon": null,
|
||||
"orderNum": 0,
|
||||
"viewPath": null,
|
||||
"keepAlive": true,
|
||||
"isShow": true,
|
||||
"childMenus": []
|
||||
},
|
||||
{
|
||||
"tenantId": null,
|
||||
"name": "修改",
|
||||
"router": null,
|
||||
"perms": "plugin:info:update",
|
||||
"type": 2,
|
||||
"icon": null,
|
||||
"orderNum": 0,
|
||||
"viewPath": null,
|
||||
"keepAlive": true,
|
||||
"isShow": true,
|
||||
"childMenus": []
|
||||
},
|
||||
{
|
||||
"tenantId": null,
|
||||
"name": "列表查询",
|
||||
"router": null,
|
||||
"perms": "plugin:info:list",
|
||||
"type": 2,
|
||||
"icon": null,
|
||||
"orderNum": 0,
|
||||
"viewPath": null,
|
||||
"keepAlive": true,
|
||||
"isShow": true,
|
||||
"childMenus": []
|
||||
},
|
||||
{
|
||||
"tenantId": null,
|
||||
"name": "新增",
|
||||
"router": null,
|
||||
"perms": "plugin:info:add",
|
||||
"type": 2,
|
||||
"icon": null,
|
||||
"orderNum": 0,
|
||||
@ -857,18 +937,6 @@
|
||||
"childMenus": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "前端插件",
|
||||
"router": "/helper/plugins/vue",
|
||||
"perms": null,
|
||||
"type": 1,
|
||||
"icon": "icon-vue",
|
||||
"orderNum": 1,
|
||||
"viewPath": "modules/helper/views/plugins/vue.vue",
|
||||
"keepAlive": true,
|
||||
"isShow": true,
|
||||
"childMenus": []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ export class BaseAuthorityMiddleware
|
||||
ctx.admin.tenantId = 1;
|
||||
if (ctx.admin.isRefresh) {
|
||||
ctx.status = 401;
|
||||
throw new CoolCommException('登录失效~');
|
||||
throw new CoolCommException('登录失效~', ctx.status);
|
||||
}
|
||||
} catch (error) {}
|
||||
// 使用matchUrl方法来检查URL是否应该被忽略
|
||||
@ -78,14 +78,12 @@ export class BaseAuthorityMiddleware
|
||||
`admin:passwordVersion:${ctx.admin.userId}`
|
||||
);
|
||||
if (passwordV != ctx.admin.passwordVersion) {
|
||||
ctx.status = 401;
|
||||
throw new CoolCommException('登录失效~');
|
||||
throw new CoolCommException('登录失效~', 401);
|
||||
}
|
||||
// 超管拥有所有权限
|
||||
if (ctx.admin.username == 'admin' && !ctx.admin.isRefresh) {
|
||||
if (rToken !== token && this.jwtConfig.jwt.sso) {
|
||||
ctx.status = 401;
|
||||
throw new CoolCommException('登录失效~');
|
||||
throw new CoolCommException('登录失效~', 401);
|
||||
} else {
|
||||
await next();
|
||||
return;
|
||||
@ -102,12 +100,10 @@ export class BaseAuthorityMiddleware
|
||||
}
|
||||
// 如果传的token是refreshToken则校验失败
|
||||
if (ctx.admin.isRefresh) {
|
||||
ctx.status = 401;
|
||||
throw new CoolCommException('登录失效~');
|
||||
throw new CoolCommException('登录失效~', 401);
|
||||
}
|
||||
if (!rToken) {
|
||||
ctx.status = 401;
|
||||
throw new CoolCommException('登录失效或无权限访问~');
|
||||
throw new CoolCommException('登录失效或无权限访问~', 401);
|
||||
}
|
||||
if (rToken !== token && this.jwtConfig.jwt.sso) {
|
||||
statusCode = 401;
|
||||
@ -130,8 +126,7 @@ export class BaseAuthorityMiddleware
|
||||
statusCode = 401;
|
||||
}
|
||||
if (statusCode > 200) {
|
||||
ctx.status = statusCode;
|
||||
throw new CoolCommException('登录失效或无权限访问~');
|
||||
throw new CoolCommException('登录失效或无权限访问~', statusCode);
|
||||
}
|
||||
}
|
||||
await next();
|
||||
|
||||
@ -39,7 +39,7 @@ export class BaseTranslateMiddleware
|
||||
// 处理翻译消息
|
||||
if (error.name == 'CoolCommException') {
|
||||
if (language && error.message && error.message !== 'success') {
|
||||
ctx.status = 200;
|
||||
ctx.status = error.statusCode || 200;
|
||||
ctx.body = {
|
||||
code: RESCODE.COMMFAIL,
|
||||
message: await this.baseTranslateService.translate(
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import { CoolController, BaseController } from '@cool-midway/core';
|
||||
import { DemoGoodsEntity } from '../../entity/goods';
|
||||
import { Get, Inject } from '@midwayjs/core';
|
||||
import { DemoGoodsService } from '../../service/goods';
|
||||
import { UserInfoEntity } from '../../../user/entity/info';
|
||||
import { DemoGoodsService } from '../../service/goods';
|
||||
|
||||
/**
|
||||
* 商品模块-商品信息
|
||||
@ -10,6 +9,7 @@ import { UserInfoEntity } from '../../../user/entity/info';
|
||||
@CoolController({
|
||||
api: ['add', 'delete', 'update', 'info', 'list', 'page'],
|
||||
entity: DemoGoodsEntity,
|
||||
service: DemoGoodsService,
|
||||
pageQueryOp: {
|
||||
keyWordLikeFields: ['a.description'],
|
||||
fieldEq: ['a.status'],
|
||||
@ -24,13 +24,4 @@ import { UserInfoEntity } from '../../../user/entity/info';
|
||||
],
|
||||
},
|
||||
})
|
||||
export class AdminDemoGoodsController extends BaseController {
|
||||
@Inject()
|
||||
demoGoodsService: DemoGoodsService;
|
||||
|
||||
@Get('/test', { summary: '测试' })
|
||||
async test() {
|
||||
await this.demoGoodsService.test();
|
||||
return this.ok('test');
|
||||
}
|
||||
}
|
||||
export class AdminDemoGoodsController extends BaseController {}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { DemoGoodsService } from '../../service/goods';
|
||||
import { DemoGoodsEntity } from '../../entity/goods';
|
||||
import { Body, Config, Get, Inject, Post, Provide } from '@midwayjs/core';
|
||||
import { Body, Inject, Post } from '@midwayjs/core';
|
||||
import { CoolController, BaseController } from '@cool-midway/core';
|
||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
@ -32,10 +32,4 @@ export class OpenDemoGoodsController extends BaseController {
|
||||
async entityPage(@Body() query) {
|
||||
return this.ok(await this.demoGoodsService.entityPage(query));
|
||||
}
|
||||
|
||||
@Get('/test', { summary: '测试' })
|
||||
async test() {
|
||||
await this.demoGoodsService.test();
|
||||
return this.ok('test');
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,6 @@ import { Inject, Provide } from '@midwayjs/core';
|
||||
import { BaseService } from '@cool-midway/core';
|
||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { noTenant } from '../../base/db/tenant';
|
||||
|
||||
/**
|
||||
* 商品示例
|
||||
@ -41,14 +40,4 @@ export class DemoGoodsService extends BaseService {
|
||||
const find = this.demoGoodsEntity.createQueryBuilder();
|
||||
return this.entityRenderPage(find, query);
|
||||
}
|
||||
|
||||
async test() {
|
||||
const a = await this.demoGoodsEntity.createQueryBuilder().getMany();
|
||||
await noTenant(this.ctx, async () => {
|
||||
const b = await this.demoGoodsEntity.createQueryBuilder().getMany();
|
||||
console.log('b');
|
||||
});
|
||||
const c = await this.demoGoodsEntity.createQueryBuilder().getMany();
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,6 @@ import { BaseService } from '@cool-midway/core';
|
||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { DemoGoodsEntity } from '../entity/goods';
|
||||
import { UserInfoEntity } from '../../user/entity/info';
|
||||
import { noTenant } from '../../base/db/tenant';
|
||||
|
||||
/**
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { CoolController, BaseController } from '@cool-midway/core';
|
||||
import { UserInfoEntity } from '../../entity/info';
|
||||
import { DemoGoodsEntity } from '../../../demo/entity/goods';
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
@ -10,16 +9,7 @@ import { DemoGoodsEntity } from '../../../demo/entity/goods';
|
||||
entity: UserInfoEntity,
|
||||
pageQueryOp: {
|
||||
fieldEq: ['a.status', 'a.gender', 'a.loginType'],
|
||||
fieldLike: ['b.title'],
|
||||
keyWordLikeFields: ['a.nickName', 'a.phone'],
|
||||
select: ['a.*', 'b.title as goodsName'],
|
||||
join: [
|
||||
{
|
||||
entity: DemoGoodsEntity,
|
||||
alias: 'b',
|
||||
condition: 'a.id = b.id',
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
export class AdminUserInfoController extends BaseController {}
|
||||
|
||||
@ -29,21 +29,9 @@ export class UserInfoEntity extends BaseEntity {
|
||||
@Column({ comment: '登录方式', dict: ['小程序', '公众号', 'H5'], default: 0 })
|
||||
loginType: number;
|
||||
|
||||
@Column({ comment: '来源', dict: 'sourceType', default: 0 })
|
||||
source: number;
|
||||
|
||||
@Column({ comment: '密码', nullable: true })
|
||||
password: string;
|
||||
|
||||
@Column({ comment: '介绍', type: 'text', nullable: true })
|
||||
description: string;
|
||||
|
||||
@Column({
|
||||
comment: '余额',
|
||||
type: 'decimal',
|
||||
precision: 10,
|
||||
scale: 2,
|
||||
default: 0,
|
||||
})
|
||||
balance: number;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user