Skip to content

Commit 505eee1

Browse files
author
pedro
committed
init:完成ts和js双版本
0 parents  commit 505eee1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+5371
-0
lines changed

.editorconfig

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
root = true
2+
3+
[*]
4+
indent_style = space
5+
indent_size = 2
6+
charset = utf-8
7+
trim_trailing_whitespace = false
8+
insert_final_newline = false

.eslintignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
dist

.eslintrc.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module.exports = {
2+
"extends": "standard",
3+
"rules": {
4+
"semi": ["warn", "always"],
5+
"quotes": ["warn", "double"],
6+
"eol-last": 0
7+
}
8+
};

.gitignore

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
logs/
2+
npm-debug.log
3+
yarn-error.log
4+
node_modules/
5+
package-lock.json
6+
yarn.lock
7+
coverage/
8+
.idea/
9+
run/
10+
suspect/
11+
.DS_Store
12+
*.sw*
13+
*.un~
14+
.vscode/
15+
dist
16+
learn

README.md

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# lin-cms-koa
2+
3+
> 以 koa 实现的 lin-cms 后台部分,支持 javasript 和 typescript 双语言版本
4+
5+
## 提示
6+
7+
**lin-cms-koa 目前仅作为个人项目进行开发,强烈不建议用于实际项目**
8+
9+
lin-cms 的[前端仓库](https://github.com/TaleLin/lin-cms-vue)
10+
11+
## 开始
12+
13+
**以 typescript 的方式运行**
14+
15+
```bash
16+
npm run start:dev
17+
```
18+
19+
**将 typescript 编译成 javascript 的方式运行**
20+
21+
```bash
22+
npm run tsc:prod && npm run start:prod
23+
```
24+
25+
**通过 javascript 的方式直接运行**
26+
27+
```bash
28+
node js/app/starter.js
29+
```
30+
31+
## TODO LIST
32+
33+
- [x] 全局异常处理
34+
- [x] 参数检验
35+
- [x] 多级路由,路由分层,路由前缀
36+
- [x] JWT 支持
37+
- [x] json 数据返回扩展
38+
- [x] 日志记录中间件
39+
- [x] ORM(typeorm)框架集成
40+
- [x] 配置文件驱动
41+
- [x] 业务
42+
- [x] 插件(推送)
43+
- [x] 将数据库操作抽象成 dto 层
44+
- [ ] 细节优化

jest.config.js

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = {
2+
preset: "ts-jest",
3+
testEnvironment: "node"
4+
};

js/app/api/cms/admin.js

+265
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
"use strict";
2+
3+
const {
4+
Redprint,
5+
paginate,
6+
routeMetaInfo,
7+
adminRequired,
8+
Success,
9+
ParametersException,
10+
NotFound,
11+
Failed
12+
} = require("lin-cms-test");
13+
14+
const {
15+
has,
16+
set,
17+
get,
18+
toSafeInteger,
19+
isInteger
20+
} = require("lodash");
21+
const {
22+
ResetPasswordForm,
23+
UpdateUserInfoForm,
24+
NewGroupForm,
25+
UpdateGroupForm,
26+
DispatchAuthForm,
27+
DispatchAuthsForm,
28+
RemoveAuthsForm
29+
} = require("../../validators/forms");
30+
const {
31+
AdminDao
32+
} = require("../../dao/cms/admin");
33+
const {
34+
getSafeParamId
35+
} = require("../../libs/util");
36+
37+
const admin = new Redprint({
38+
prefix: "/admin"
39+
});
40+
41+
exports.admin = admin;
42+
const adminDao = new AdminDao();
43+
44+
admin.redGet("getAuthority", "/authority", {
45+
auth: "查询所有可分配的权限",
46+
module: "管理员",
47+
mount: false
48+
}, adminRequired, ctx => {
49+
const res = {};
50+
routeMetaInfo.forEach((v, k) => {
51+
const au = v["auth"];
52+
if (!has(res, `${v["module"]}.${au}`)) {
53+
set(res, `${v["module"]}.${au}`, [k]);
54+
} else {
55+
res[v["module"]][au].push(k);
56+
}
57+
});
58+
ctx.json(res);
59+
});
60+
61+
admin.redGet("getAdminUsers", "/users", {
62+
auth: "查询所有用户",
63+
module: "管理员",
64+
mount: false
65+
}, adminRequired, async (ctx) => {
66+
const groupId = get(ctx.request.query, "group_id");
67+
const {
68+
start,
69+
count
70+
} = paginate(ctx);
71+
const {
72+
users,
73+
total
74+
} = await adminDao.getUsers(ctx, groupId, start, count);
75+
ctx.json({
76+
collection: users,
77+
// 超级管理员不算入总数
78+
total_nums: total
79+
});
80+
});
81+
82+
admin.redPut("changeUserPassword", "/password/:id", {
83+
auth: "修改用户密码",
84+
module: "管理员",
85+
mount: false
86+
}, adminRequired, async (ctx) => {
87+
const form = new ResetPasswordForm(ctx).validate();
88+
const id = toSafeInteger(get(ctx.params, "id"));
89+
if (!isInteger(id)) {
90+
throw new ParametersException({
91+
msg: "路由参数错误"
92+
});
93+
}
94+
await adminDao.changeUserPassword(ctx, form, id);
95+
ctx.json(new Success({
96+
msg: "密码修改成功"
97+
}));
98+
});
99+
100+
admin.redDelete("deleteUser", "/:id", {
101+
auth: "删除用户",
102+
module: "管理员",
103+
mount: false
104+
}, adminRequired, async (ctx) => {
105+
const id = toSafeInteger(get(ctx.params, "id"));
106+
if (!isInteger(id)) {
107+
throw new ParametersException({
108+
msg: "路由参数错误"
109+
});
110+
}
111+
await adminDao.deleteUser(ctx, id);
112+
ctx.json(new Success({
113+
msg: "操作成功"
114+
}));
115+
});
116+
117+
admin.redPut("updateUser", "/:id", {
118+
auth: "管理员更新用户信息",
119+
module: "管理员",
120+
mount: false
121+
}, adminRequired, async (ctx) => {
122+
const form = new UpdateUserInfoForm(ctx).validate();
123+
const id = toSafeInteger(get(ctx.params, "id"));
124+
if (!isInteger(id)) {
125+
throw new ParametersException({
126+
msg: "路由参数错误"
127+
});
128+
}
129+
await adminDao.updateUserInfo(ctx, form, id);
130+
ctx.json(new Success({
131+
msg: "操作成功"
132+
}));
133+
});
134+
135+
admin.redGet("getAdminGroups", "/groups", {
136+
auth: "查询所有权限组及其权限",
137+
module: "管理员",
138+
mount: false
139+
}, adminRequired, async (ctx) => {
140+
const {
141+
start,
142+
count
143+
} = paginate(ctx);
144+
const {
145+
groups,
146+
total
147+
} = await adminDao.getGroups(ctx, start, count);
148+
if (total < 1) {
149+
throw new NotFound({
150+
msg: "未找到任何权限组"
151+
});
152+
}
153+
ctx.json({
154+
collection: groups,
155+
total_nums: total
156+
});
157+
});
158+
159+
admin.redGet("getAllGroup", "/group/all", {
160+
auth: "查询所有权限组",
161+
module: "管理员",
162+
mount: false
163+
}, adminRequired, async (ctx) => {
164+
const groups = await ctx.manager.groupModel.find();
165+
if (!groups || groups.length < 1) {
166+
throw new NotFound({
167+
msg: "未找到任何权限组"
168+
});
169+
}
170+
ctx.json(groups);
171+
});
172+
173+
admin.redGet("getGroup", "/group/:id", {
174+
auth: "查询一个权限组及其权限",
175+
module: "管理员",
176+
mount: false
177+
}, adminRequired, async (ctx) => {
178+
const id = toSafeInteger(get(ctx.params, "id"));
179+
if (!isInteger(id)) {
180+
throw new ParametersException({
181+
msg: "路由参数错误"
182+
});
183+
}
184+
const group = await adminDao.getGroup(ctx, id);
185+
ctx.json(group);
186+
});
187+
188+
admin.redPost("createGroup", "/group", {
189+
auth: "新建权限组",
190+
module: "管理员",
191+
mount: false
192+
}, adminRequired, async (ctx) => {
193+
const form = new NewGroupForm(ctx).validate();
194+
const ok = await adminDao.createGroup(ctx, form);
195+
if (ok) {
196+
ctx.json(new Failed({
197+
msg: "新建分组失败"
198+
}));
199+
} else {
200+
ctx.json(new Success({
201+
msg: "新建分组成功"
202+
}));
203+
}
204+
});
205+
206+
admin.redPut("updateGroup", "/group/:id", {
207+
auth: "更新一个权限组",
208+
module: "管理员",
209+
mount: false
210+
}, adminRequired, async (ctx) => {
211+
const id = getSafeParamId(ctx);
212+
const form = new UpdateGroupForm(ctx).validate();
213+
await adminDao.updateGroup(ctx, form, id);
214+
ctx.json(new Success({
215+
msg: "更新分组成功"
216+
}));
217+
});
218+
219+
admin.redDelete("deleteGroup", "/group/:id", {
220+
auth: "删除一个权限组",
221+
module: "管理员",
222+
mount: false
223+
}, adminRequired, async (ctx) => {
224+
const id = getSafeParamId(ctx);
225+
await adminDao.deleteGroup(ctx, id);
226+
ctx.json(new Success({
227+
msg: "删除分组成功"
228+
}));
229+
});
230+
231+
admin.redPost("dispatchAuth", "/dispatch", {
232+
auth: "分配单个权限",
233+
module: "管理员",
234+
mount: false
235+
}, adminRequired, async (ctx) => {
236+
const form = new DispatchAuthForm(ctx).validate();
237+
await adminDao.dispatchAuth(ctx, form);
238+
ctx.json(new Success({
239+
msg: "添加权限成功"
240+
}));
241+
});
242+
243+
admin.redPost("dispatchAuths", "/dispatch/patch", {
244+
auth: "分配多个权限",
245+
module: "管理员",
246+
mount: false
247+
}, adminRequired, async (ctx) => {
248+
const form = new DispatchAuthsForm(ctx).validate();
249+
await adminDao.dispatchAuths(ctx, form);
250+
ctx.json(new Success({
251+
msg: "添加权限成功"
252+
}));
253+
});
254+
255+
admin.redPost("removeAuths", "/remove", {
256+
auth: "删除多个权限",
257+
module: "管理员",
258+
mount: false
259+
}, adminRequired, async (ctx) => {
260+
const form = new RemoveAuthsForm(ctx).validate();
261+
await adminDao.removeAuths(ctx, form);
262+
ctx.json(new Success({
263+
msg: "删除权限成功"
264+
}));
265+
});

js/app/api/cms/index.js

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"use strict";
2+
3+
const {
4+
user
5+
} = require("./user");
6+
const {
7+
test
8+
} = require("./test");
9+
const {
10+
log
11+
} = require("./log");
12+
const {
13+
admin
14+
} = require("./admin");
15+
const {
16+
Redprint
17+
} = require("lin-cms-test");
18+
19+
const cms = new Redprint({
20+
prefix: "/cms"
21+
});
22+
23+
exports.cms = cms;
24+
25+
cms.use(user.routes()).use(user.allowedMethods());
26+
cms.use(test.routes()).use(test.allowedMethods());
27+
cms.use(log.routes()).use(log.allowedMethods());
28+
cms.use(admin.routes()).use(admin.allowedMethods());

0 commit comments

Comments
 (0)