mirror of
https://github.com/chillzhuang/Sword
synced 2024-11-22 02:09:26 +08:00
🎉 2.7.0.RELEASE,内核全面升级,增加岗位管理,用户导入导出
This commit is contained in:
parent
471c659f38
commit
50cbbe6524
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2019 bladex.vip
|
Copyright (c) 2020 BladeX (https://bladex.vip)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="https://img.shields.io/badge/Release-V2.6.2-green.svg" alt="Downloads">
|
<img src="https://img.shields.io/badge/Release-V2.7.0-green.svg" alt="Downloads">
|
||||||
<img src="https://img.shields.io/badge/JDK-1.8+-green.svg" alt="Build Status">
|
<img src="https://img.shields.io/badge/JDK-1.8+-green.svg" alt="Build Status">
|
||||||
<img src="https://img.shields.io/badge/license-Apache%202-blue.svg" alt="Build Status">
|
<img src="https://img.shields.io/badge/license-Apache%202-blue.svg" alt="Build Status">
|
||||||
<img src="https://img.shields.io/badge/Spring%20Cloud-Hoxton.SR2-blue.svg" alt="Coverage Status">
|
<img src="https://img.shields.io/badge/Spring%20Cloud-Hoxton.SR3-blue.svg" alt="Coverage Status">
|
||||||
<img src="https://img.shields.io/badge/Spring%20Boot-2.2.5.RELEASE-blue.svg" alt="Downloads">
|
<img src="https://img.shields.io/badge/Spring%20Boot-2.2.6.RELEASE-blue.svg" alt="Downloads">
|
||||||
<a target="_blank" href="https://bladex.vip">
|
<a target="_blank" href="https://bladex.vip">
|
||||||
<img src="https://img.shields.io/badge/Author-Small%20Chill-ff69b4.svg" alt="Downloads">
|
<img src="https://img.shields.io/badge/Author-Small%20Chill-ff69b4.svg" alt="Downloads">
|
||||||
</a>
|
</a>
|
||||||
@ -64,6 +64,7 @@ SpringBlade
|
|||||||
* Saber-基于Vue:[https://saber.bladex.vip](https://saber.bladex.vip)
|
* Saber-基于Vue:[https://saber.bladex.vip](https://saber.bladex.vip)
|
||||||
* Sword-基于React:[https://sword.bladex.vip](https://sword.bladex.vip)
|
* Sword-基于React:[https://sword.bladex.vip](https://sword.bladex.vip)
|
||||||
* Archer-全能代码生成系统:[https://archer.bladex.vip](https://archer.bladex.vip)
|
* Archer-全能代码生成系统:[https://archer.bladex.vip](https://archer.bladex.vip)
|
||||||
|
* Caster-数据大屏展示系统:[https://data.avuejs.com](https://data.avuejs.com)
|
||||||
|
|
||||||
## 技术文档
|
## 技术文档
|
||||||
* [开发手册一览](https://gitee.com/smallc/SpringBlade/wikis/SpringBlade开发手册)
|
* [开发手册一览](https://gitee.com/smallc/SpringBlade/wikis/SpringBlade开发手册)
|
||||||
|
@ -125,6 +125,17 @@ export default [
|
|||||||
{ path: '/system/dept/view/:id', component: './System/Dept/DeptView' },
|
{ path: '/system/dept/view/:id', component: './System/Dept/DeptView' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/system/post',
|
||||||
|
routes: [
|
||||||
|
{ path: '/system/post', redirect: '/system/post/list' },
|
||||||
|
{ path: '/system/post/list', component: './System/Post/Post' },
|
||||||
|
{ path: '/system/post/add', component: './System/Post/PostAdd' },
|
||||||
|
{ path: '/system/post/add/:id', component: './System/Post/PostAdd' },
|
||||||
|
{ path: '/system/post/edit/:id', component: './System/Post/PostEdit' },
|
||||||
|
{ path: '/system/post/view/:id', component: './System/Post/PostView' },
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/system/role',
|
path: '/system/role',
|
||||||
routes: [
|
routes: [
|
||||||
|
@ -46,6 +46,7 @@ function getFakeDetail(req, res) {
|
|||||||
id: '1',
|
id: '1',
|
||||||
tenantId: '000000',
|
tenantId: '000000',
|
||||||
account: 'admin',
|
account: 'admin',
|
||||||
|
code: 'admin',
|
||||||
name: '超级管理员',
|
name: '超级管理员',
|
||||||
realName: '管理员',
|
realName: '管理员',
|
||||||
phone: '13888888888',
|
phone: '13888888888',
|
||||||
@ -54,6 +55,8 @@ function getFakeDetail(req, res) {
|
|||||||
roleName: '超级管理员',
|
roleName: '超级管理员',
|
||||||
deptId: 1,
|
deptId: 1,
|
||||||
deptName: '刀锋科技',
|
deptName: '刀锋科技',
|
||||||
|
postId: 1,
|
||||||
|
postName: '首席执行官',
|
||||||
sex: 1,
|
sex: 1,
|
||||||
sexName: '男',
|
sexName: '男',
|
||||||
birthday: '2018-12-31 23:33:33',
|
birthday: '2018-12-31 23:33:33',
|
||||||
@ -61,7 +64,6 @@ function getFakeDetail(req, res) {
|
|||||||
};
|
};
|
||||||
return res.json(json);
|
return res.json(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
function fakeSuccess(req, res) {
|
function fakeSuccess(req, res) {
|
||||||
const json = { code: 200, success: true, msg: '操作成功' };
|
const json = { code: 200, success: true, msg: '操作成功' };
|
||||||
return res.json(json);
|
return res.json(json);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "sword",
|
"name": "sword",
|
||||||
"version": "2.6.2",
|
"version": "2.7.0",
|
||||||
"description": "An out-of-box UI solution for enterprise applications",
|
"description": "An out-of-box UI solution for enterprise applications",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
43
src/actions/post.js
Normal file
43
src/actions/post.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
export const POST_NAMESPACE = 'post';
|
||||||
|
|
||||||
|
export function POST_INIT() {
|
||||||
|
return {
|
||||||
|
type: `${POST_NAMESPACE}/fetchInit`,
|
||||||
|
payload: { code: 'post_category' },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function POST_LIST(payload) {
|
||||||
|
return {
|
||||||
|
type: `${POST_NAMESPACE}/fetchList`,
|
||||||
|
payload,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function POST_DETAIL(id) {
|
||||||
|
return {
|
||||||
|
type: `${POST_NAMESPACE}/fetchDetail`,
|
||||||
|
payload: { id },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function POST_CLEAR_DETAIL() {
|
||||||
|
return {
|
||||||
|
type: `${POST_NAMESPACE}/clearDetail`,
|
||||||
|
payload: {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function POST_SUBMIT(payload) {
|
||||||
|
return {
|
||||||
|
type: `${POST_NAMESPACE}/submit`,
|
||||||
|
payload,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function POST_REMOVE(payload) {
|
||||||
|
return {
|
||||||
|
type: `${POST_NAMESPACE}/remove`,
|
||||||
|
payload,
|
||||||
|
};
|
||||||
|
}
|
@ -30,9 +30,7 @@ export default class ToolBar extends PureComponent {
|
|||||||
</Button>
|
</Button>
|
||||||
))}
|
))}
|
||||||
{renderLeftButton ? renderLeftButton() : null}
|
{renderLeftButton ? renderLeftButton() : null}
|
||||||
{renderRightButton ? (
|
{renderRightButton ? <div style={{ float: 'right' }}>{renderRightButton()}</div> : null}
|
||||||
<div style={{ float: 'right', marginRight: '20px' }}>{renderRightButton()}</div>
|
|
||||||
) : null}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -3,6 +3,7 @@ module.exports = {
|
|||||||
clientId: 'sword', // 客户端id
|
clientId: 'sword', // 客户端id
|
||||||
clientSecret: 'sword_secret', // 客户端密钥
|
clientSecret: 'sword_secret', // 客户端密钥
|
||||||
tenantMode: true, // 开启租户模式
|
tenantMode: true, // 开启租户模式
|
||||||
|
captchaMode: true, // 开启验证码模式
|
||||||
navTheme: 'dark', // theme for nav menu
|
navTheme: 'dark', // theme for nav menu
|
||||||
primaryColor: '#1890FF', // primary color of ant design
|
primaryColor: '#1890FF', // primary color of ant design
|
||||||
layout: 'sidemenu', // nav menu position: sidemenu or topmenu
|
layout: 'sidemenu', // nav menu position: sidemenu or topmenu
|
||||||
|
@ -8,7 +8,7 @@ const FooterView = () => (
|
|||||||
<GlobalFooter
|
<GlobalFooter
|
||||||
copyright={
|
copyright={
|
||||||
<Fragment>
|
<Fragment>
|
||||||
Copyright <Icon type="copyright" /> 2019 SpringBlade{' '}
|
Copyright <Icon type="copyright" /> 2020 SpringBlade{' '}
|
||||||
<a
|
<a
|
||||||
key="github"
|
key="github"
|
||||||
title="git"
|
title="git"
|
||||||
|
@ -27,7 +27,7 @@ const links = [
|
|||||||
|
|
||||||
const copyright = (
|
const copyright = (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
Copyright <Icon type="copyright" /> 2019 SpringBlade{' '}
|
Copyright <Icon type="copyright" /> 2020 SpringBlade{' '}
|
||||||
<a
|
<a
|
||||||
key="github"
|
key="github"
|
||||||
title="git"
|
title="git"
|
||||||
|
@ -9,6 +9,7 @@ export default {
|
|||||||
'menu.system': 'system',
|
'menu.system': 'system',
|
||||||
'menu.system.user': 'user',
|
'menu.system.user': 'user',
|
||||||
'menu.system.dept': 'department',
|
'menu.system.dept': 'department',
|
||||||
|
'menu.system.post': 'post',
|
||||||
'menu.system.dict': 'dictionary',
|
'menu.system.dict': 'dictionary',
|
||||||
'menu.system.menu': 'menu',
|
'menu.system.menu': 'menu',
|
||||||
'menu.system.role': 'role',
|
'menu.system.role': 'role',
|
||||||
|
@ -9,6 +9,7 @@ export default {
|
|||||||
'menu.system': '系统管理',
|
'menu.system': '系统管理',
|
||||||
'menu.system.user': '用户管理',
|
'menu.system.user': '用户管理',
|
||||||
'menu.system.dept': '部门管理',
|
'menu.system.dept': '部门管理',
|
||||||
|
'menu.system.post': '岗位管理',
|
||||||
'menu.system.dict': '字典管理',
|
'menu.system.dict': '字典管理',
|
||||||
'menu.system.menu': '菜单管理',
|
'menu.system.menu': '菜单管理',
|
||||||
'menu.system.role': '角色管理',
|
'menu.system.role': '角色管理',
|
||||||
|
@ -9,6 +9,7 @@ export default {
|
|||||||
'menu.system': '系統管理',
|
'menu.system': '系統管理',
|
||||||
'menu.system.user': '用戶管理',
|
'menu.system.user': '用戶管理',
|
||||||
'menu.system.dept': '部門管理',
|
'menu.system.dept': '部門管理',
|
||||||
|
'menu.system.post': '崗位管理',
|
||||||
'menu.system.dict': '字典管理',
|
'menu.system.dict': '字典管理',
|
||||||
'menu.system.menu': '菜單管理',
|
'menu.system.menu': '菜單管理',
|
||||||
'menu.system.role': '角色管理',
|
'menu.system.role': '角色管理',
|
||||||
|
@ -5,6 +5,7 @@ import { accountLogin } from '../services/user';
|
|||||||
import { dynamicRoutes, dynamicButtons } from '../services/menu';
|
import { dynamicRoutes, dynamicButtons } from '../services/menu';
|
||||||
import {
|
import {
|
||||||
setAuthority,
|
setAuthority,
|
||||||
|
setAccessToken,
|
||||||
setToken,
|
setToken,
|
||||||
setCurrentUser,
|
setCurrentUser,
|
||||||
setRoutes,
|
setRoutes,
|
||||||
@ -101,6 +102,7 @@ export default {
|
|||||||
} = payload;
|
} = payload;
|
||||||
const token = `${tokenType} ${accessToken}`;
|
const token = `${tokenType} ${accessToken}`;
|
||||||
setToken(token);
|
setToken(token);
|
||||||
|
setAccessToken(accessToken);
|
||||||
setAuthority(authority);
|
setAuthority(authority);
|
||||||
setCurrentUser({ avatar, account, name: userName, authority });
|
setCurrentUser({ avatar, account, name: userName, authority });
|
||||||
} else {
|
} else {
|
||||||
|
108
src/models/post.js
Normal file
108
src/models/post.js
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
import { message } from 'antd';
|
||||||
|
import router from 'umi/router';
|
||||||
|
import { POST_NAMESPACE } from '../actions/post';
|
||||||
|
import { dict } from '../services/dict';
|
||||||
|
import { list, submit, detail, remove } from '../services/post';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
namespace: POST_NAMESPACE,
|
||||||
|
state: {
|
||||||
|
data: {
|
||||||
|
list: [],
|
||||||
|
pagination: false,
|
||||||
|
},
|
||||||
|
init: {
|
||||||
|
category: [],
|
||||||
|
},
|
||||||
|
detail: {},
|
||||||
|
},
|
||||||
|
effects: {
|
||||||
|
*fetchList({ payload }, { call, put }) {
|
||||||
|
const response = yield call(list, payload);
|
||||||
|
if (response.success) {
|
||||||
|
yield put({
|
||||||
|
type: 'saveList',
|
||||||
|
payload: {
|
||||||
|
list: response.data.records,
|
||||||
|
pagination: {
|
||||||
|
total: response.data.total,
|
||||||
|
current: response.data.current,
|
||||||
|
pageSize: response.data.size,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
*fetchInit({ payload }, { call, put }) {
|
||||||
|
const response = yield call(dict, payload);
|
||||||
|
if (response.success) {
|
||||||
|
yield put({
|
||||||
|
type: 'saveInit',
|
||||||
|
payload: {
|
||||||
|
category: response.data,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
*fetchDetail({ payload }, { call, put }) {
|
||||||
|
const response = yield call(detail, payload);
|
||||||
|
if (response.success) {
|
||||||
|
yield put({
|
||||||
|
type: 'saveDetail',
|
||||||
|
payload: {
|
||||||
|
detail: response.data,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
*clearDetail({ payload }, { put }) {
|
||||||
|
yield put({
|
||||||
|
type: 'removeDetail',
|
||||||
|
payload: { payload },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
*submit({ payload }, { call }) {
|
||||||
|
const response = yield call(submit, payload);
|
||||||
|
if (response.success) {
|
||||||
|
message.success('提交成功');
|
||||||
|
router.push('/system/post');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
*remove({ payload }, { call }) {
|
||||||
|
const {
|
||||||
|
data: { keys },
|
||||||
|
success,
|
||||||
|
} = payload;
|
||||||
|
const response = yield call(remove, { ids: keys });
|
||||||
|
if (response.success) {
|
||||||
|
success();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
reducers: {
|
||||||
|
saveList(state, action) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
data: action.payload,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
saveInit(state, action) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
init: action.payload,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
saveDetail(state, action) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
detail: action.payload.detail,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
removeDetail(state) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
detail: {},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
@ -5,6 +5,7 @@ import { query as queryUsers, list, submit, update, detail, remove, grant } from
|
|||||||
import { select as tenants } from '../services/tenant';
|
import { select as tenants } from '../services/tenant';
|
||||||
import { tree as roles } from '../services/role';
|
import { tree as roles } from '../services/role';
|
||||||
import { tree as depts } from '../services/dept';
|
import { tree as depts } from '../services/dept';
|
||||||
|
import { select as posts } from '../services/post';
|
||||||
import { getCurrentUser } from '../utils/authority';
|
import { getCurrentUser } from '../utils/authority';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -20,6 +21,7 @@ export default {
|
|||||||
init: {
|
init: {
|
||||||
roleTree: [],
|
roleTree: [],
|
||||||
deptTree: [],
|
deptTree: [],
|
||||||
|
postList: [],
|
||||||
tenantList: [],
|
tenantList: [],
|
||||||
},
|
},
|
||||||
detail: {},
|
detail: {},
|
||||||
@ -59,13 +61,20 @@ export default {
|
|||||||
*fetchInit({ payload }, { call, put }) {
|
*fetchInit({ payload }, { call, put }) {
|
||||||
const responseRole = yield call(roles, payload);
|
const responseRole = yield call(roles, payload);
|
||||||
const responseDept = yield call(depts, payload);
|
const responseDept = yield call(depts, payload);
|
||||||
|
const responsePost = yield call(posts, payload);
|
||||||
const responseTenant = yield call(tenants, payload);
|
const responseTenant = yield call(tenants, payload);
|
||||||
if (responseRole.success && responseDept.success && responseTenant.success) {
|
if (
|
||||||
|
responseRole.success &&
|
||||||
|
responseDept.success &&
|
||||||
|
responsePost.success &&
|
||||||
|
responseTenant.success
|
||||||
|
) {
|
||||||
yield put({
|
yield put({
|
||||||
type: 'saveInit',
|
type: 'saveInit',
|
||||||
payload: {
|
payload: {
|
||||||
roleTree: responseRole.data,
|
roleTree: responseRole.data,
|
||||||
deptTree: responseDept.data,
|
deptTree: responseDept.data,
|
||||||
|
postList: responsePost.data,
|
||||||
tenantList: responseTenant.data,
|
tenantList: responseTenant.data,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -74,12 +83,14 @@ export default {
|
|||||||
*fetchChangeInit({ payload }, { call, put }) {
|
*fetchChangeInit({ payload }, { call, put }) {
|
||||||
const responseRole = yield call(roles, payload);
|
const responseRole = yield call(roles, payload);
|
||||||
const responseDept = yield call(depts, payload);
|
const responseDept = yield call(depts, payload);
|
||||||
if (responseRole.success && responseDept.success) {
|
const responsePost = yield call(posts, payload);
|
||||||
|
if (responseRole.success && responseDept.success && responsePost.success) {
|
||||||
yield put({
|
yield put({
|
||||||
type: 'saveChangeInit',
|
type: 'saveChangeInit',
|
||||||
payload: {
|
payload: {
|
||||||
roleTree: responseRole.data,
|
roleTree: responseRole.data,
|
||||||
deptTree: responseDept.data,
|
deptTree: responseDept.data,
|
||||||
|
postList: responsePost.data,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -174,6 +185,7 @@ export default {
|
|||||||
const newState = state;
|
const newState = state;
|
||||||
newState.init.roleTree = action.payload.roleTree;
|
newState.init.roleTree = action.payload.roleTree;
|
||||||
newState.init.deptTree = action.payload.deptTree;
|
newState.init.deptTree = action.payload.deptTree;
|
||||||
|
newState.init.postList = action.payload.postList;
|
||||||
return {
|
return {
|
||||||
...newState,
|
...newState,
|
||||||
};
|
};
|
||||||
|
@ -14,14 +14,14 @@ class Workplace extends PureComponent {
|
|||||||
<Row gutter={24}>
|
<Row gutter={24}>
|
||||||
<Col span={24}>
|
<Col span={24}>
|
||||||
<div style={{ textAlign: 'center' }}>
|
<div style={{ textAlign: 'center' }}>
|
||||||
<img src="https://img.shields.io/badge/Release-V2.6.2-green.svg" alt="Downloads" />
|
<img src="https://img.shields.io/badge/Release-V2.7.0-green.svg" alt="Downloads" />
|
||||||
<img src="https://img.shields.io/badge/JDK-1.8+-green.svg" alt="Build Status" />
|
<img src="https://img.shields.io/badge/JDK-1.8+-green.svg" alt="Build Status" />
|
||||||
<img
|
<img
|
||||||
src="https://img.shields.io/badge/Spring%20Cloud-Hoxton.SR2-blue.svg"
|
src="https://img.shields.io/badge/Spring%20Cloud-Hoxton.SR3-blue.svg"
|
||||||
alt="Coverage Status"
|
alt="Coverage Status"
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
src="https://img.shields.io/badge/Spring%20Boot-2.2.5.RELEASE-blue.svg"
|
src="https://img.shields.io/badge/Spring%20Boot-2.2.6.RELEASE-blue.svg"
|
||||||
alt="Downloads"
|
alt="Downloads"
|
||||||
/>
|
/>
|
||||||
<a href="https://bladex.vip">
|
<a href="https://bladex.vip">
|
||||||
@ -147,7 +147,7 @@ class Workplace extends PureComponent {
|
|||||||
<div>
|
<div>
|
||||||
2.接3个月以内工期的react、vue、springboot、springcloud、app、小程序等软件定制服务
|
2.接3个月以内工期的react、vue、springboot、springcloud、app、小程序等软件定制服务
|
||||||
</div>
|
</div>
|
||||||
<div>3.有意向请联系唯一指定QQ:85088620</div>
|
<div>3.有意向请联系唯一指定QQ:1272154962</div>
|
||||||
</Panel>
|
</Panel>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
</Card>
|
</Card>
|
||||||
@ -206,7 +206,19 @@ class Workplace extends PureComponent {
|
|||||||
</Row>
|
</Row>
|
||||||
<Row gutter={24}>
|
<Row gutter={24}>
|
||||||
<Card className={styles.card} bordered={false}>
|
<Card className={styles.card} bordered={false}>
|
||||||
<Collapse bordered={false} defaultActiveKey={['16']}>
|
<Collapse bordered={false} defaultActiveKey={['17']}>
|
||||||
|
<Panel header="2.7.0发布 内核全面升级,增加岗位管理,用户导入导出" key="17">
|
||||||
|
<div>1.升级至 SpringCloud Hoxton.SR3</div>
|
||||||
|
<div>2.升级至 SpringBoot 2.2.6.RELEASE</div>
|
||||||
|
<div>3.升级至 Avue 2.5.0</div>
|
||||||
|
<div>4.升级Saber内核,采用最新版本API,优化交互体验</div>
|
||||||
|
<div>5.新增岗位管理模块</div>
|
||||||
|
<div>6.新增用户导入导出模块</div>
|
||||||
|
<div>7.数据库主键统一改成bigint并采用snowflake算法</div>
|
||||||
|
<div>8.优化INode类,主键跟随修改为Long类型</div>
|
||||||
|
<div>9.优化鉴权逻辑,支持header以及parameter两种方式</div>
|
||||||
|
<div>10.优化代码生成模板以支持最新版API</div>
|
||||||
|
</Panel>
|
||||||
<Panel header="2.6.1发布 增加登陆验证码,支持seata1.0" key="16">
|
<Panel header="2.6.1发布 增加登陆验证码,支持seata1.0" key="16">
|
||||||
<div>1.升级SpringBoot 2.2.5.RELEASE</div>
|
<div>1.升级SpringBoot 2.2.5.RELEASE</div>
|
||||||
<div>2.升级SpringCloud Hoxton.SR2</div>
|
<div>2.升级SpringCloud Hoxton.SR2</div>
|
||||||
|
@ -4,7 +4,7 @@ import { formatMessage, FormattedMessage } from 'umi/locale';
|
|||||||
import { Checkbox, Alert } from 'antd';
|
import { Checkbox, Alert } from 'antd';
|
||||||
import Login from '../../components/Login';
|
import Login from '../../components/Login';
|
||||||
import styles from './Login.less';
|
import styles from './Login.less';
|
||||||
import { tenantMode } from '../../defaultSettings';
|
import { tenantMode, captchaMode } from '../../defaultSettings';
|
||||||
|
|
||||||
const { Tab, TenantId, UserName, Password, Captcha, Submit } = Login;
|
const { Tab, TenantId, UserName, Password, Captcha, Submit } = Login;
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ class LoginPage extends Component {
|
|||||||
]}
|
]}
|
||||||
onPressEnter={() => this.loginForm.validateFields(this.handleSubmit)}
|
onPressEnter={() => this.loginForm.validateFields(this.handleSubmit)}
|
||||||
/>
|
/>
|
||||||
<Captcha name="code" mode="image" />
|
{captchaMode ? <Captcha name="code" mode="image" /> : null}
|
||||||
</Tab>
|
</Tab>
|
||||||
<div>
|
<div>
|
||||||
<Checkbox checked={autoLogin} onChange={this.changeAutoLogin}>
|
<Checkbox checked={autoLogin} onChange={this.changeAutoLogin}>
|
||||||
|
102
src/pages/System/Post/Post.js
Normal file
102
src/pages/System/Post/Post.js
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
import React, { PureComponent } from 'react';
|
||||||
|
import { connect } from 'dva';
|
||||||
|
import { Button, Col, Form, Input, Row, Tag } from 'antd';
|
||||||
|
import Panel from '../../../components/Panel';
|
||||||
|
import { POST_LIST } from '../../../actions/post';
|
||||||
|
import Grid from '../../../components/Sword/Grid';
|
||||||
|
|
||||||
|
const FormItem = Form.Item;
|
||||||
|
|
||||||
|
@connect(({ post, loading }) => ({
|
||||||
|
post,
|
||||||
|
loading: loading.models.post,
|
||||||
|
}))
|
||||||
|
@Form.create()
|
||||||
|
class Post extends PureComponent {
|
||||||
|
// ============ 查询 ===============
|
||||||
|
handleSearch = params => {
|
||||||
|
const { dispatch } = this.props;
|
||||||
|
dispatch(POST_LIST(params));
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============ 查询表单 ===============
|
||||||
|
renderSearchForm = onReset => {
|
||||||
|
const { form } = this.props;
|
||||||
|
const { getFieldDecorator } = form;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
|
||||||
|
<Col md={6} sm={24}>
|
||||||
|
<FormItem label="查询名称">
|
||||||
|
{getFieldDecorator('name')(<Input placeholder="查询名称" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<div style={{ float: 'right' }}>
|
||||||
|
<Button type="primary" htmlType="submit">
|
||||||
|
查询
|
||||||
|
</Button>
|
||||||
|
<Button style={{ marginLeft: 8 }} onClick={onReset}>
|
||||||
|
重置
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const code = 'post';
|
||||||
|
|
||||||
|
const {
|
||||||
|
form,
|
||||||
|
loading,
|
||||||
|
post: { data },
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: '租户ID',
|
||||||
|
dataIndex: 'tenantId',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '岗位类型',
|
||||||
|
dataIndex: 'categoryName',
|
||||||
|
render: categoryName => (
|
||||||
|
<span>
|
||||||
|
<Tag color="geekblue" key={categoryName}>
|
||||||
|
{categoryName}
|
||||||
|
</Tag>
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '岗位编号',
|
||||||
|
dataIndex: 'postCode',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '岗位名称',
|
||||||
|
dataIndex: 'postName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '岗位排序',
|
||||||
|
dataIndex: 'sort',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Panel>
|
||||||
|
<Grid
|
||||||
|
code={code}
|
||||||
|
form={form}
|
||||||
|
onSearch={this.handleSearch}
|
||||||
|
renderSearchForm={this.renderSearchForm}
|
||||||
|
loading={loading}
|
||||||
|
data={data}
|
||||||
|
columns={columns}
|
||||||
|
/>
|
||||||
|
</Panel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default Post;
|
152
src/pages/System/Post/PostAdd.js
Normal file
152
src/pages/System/Post/PostAdd.js
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
import React, { PureComponent } from 'react';
|
||||||
|
import { Form, Input, Card, Button, InputNumber, Col, Row, Select } from 'antd';
|
||||||
|
import { connect } from 'dva';
|
||||||
|
import Panel from '../../../components/Panel';
|
||||||
|
import styles from '../../../layouts/Sword.less';
|
||||||
|
import { POST_INIT, POST_SUBMIT } from '../../../actions/post';
|
||||||
|
|
||||||
|
const FormItem = Form.Item;
|
||||||
|
const { TextArea } = Input;
|
||||||
|
|
||||||
|
@connect(({ post, loading }) => ({
|
||||||
|
post,
|
||||||
|
submitting: loading.effects['post/submit'],
|
||||||
|
}))
|
||||||
|
@Form.create()
|
||||||
|
class PostAdd extends PureComponent {
|
||||||
|
componentWillMount() {
|
||||||
|
const { dispatch } = this.props;
|
||||||
|
dispatch(POST_INIT());
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSubmit = e => {
|
||||||
|
e.preventDefault();
|
||||||
|
const { dispatch, form } = this.props;
|
||||||
|
form.validateFieldsAndScroll((err, values) => {
|
||||||
|
if (!err) {
|
||||||
|
dispatch(POST_SUBMIT(values));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
form: { getFieldDecorator },
|
||||||
|
post: { init },
|
||||||
|
submitting,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
const { category } = init;
|
||||||
|
|
||||||
|
const formItemLayout = {
|
||||||
|
labelCol: {
|
||||||
|
span: 8,
|
||||||
|
},
|
||||||
|
wrapperCol: {
|
||||||
|
span: 16,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const formAllItemLayout = {
|
||||||
|
labelCol: {
|
||||||
|
span: 4,
|
||||||
|
},
|
||||||
|
wrapperCol: {
|
||||||
|
span: 20,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const action = (
|
||||||
|
<Button type="primary" onClick={this.handleSubmit} loading={submitting}>
|
||||||
|
提交
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Panel title="新增" back="/system/post" action={action}>
|
||||||
|
<Form hideRequiredMark style={{ marginTop: 8 }}>
|
||||||
|
<Card title="基本信息" className={styles.card} bordered={false}>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="岗位类型">
|
||||||
|
{getFieldDecorator('category', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择岗位类型',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(
|
||||||
|
<Select placeholder="请选择机构类型">
|
||||||
|
{category.map(d => (
|
||||||
|
<Select.Option key={d.dictKey} value={d.dictKey}>
|
||||||
|
{d.dictValue}
|
||||||
|
</Select.Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="岗位编号">
|
||||||
|
{getFieldDecorator('postCode', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入岗位编号',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(<Input placeholder="请输入岗位编号" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="岗位名称">
|
||||||
|
{getFieldDecorator('postName', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入岗位名称',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(<Input placeholder="请输入岗位名称" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} className={styles.inputItem} label="岗位排序">
|
||||||
|
{getFieldDecorator('sort', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入岗位排序',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(<InputNumber placeholder="请输入岗位排序" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Card>
|
||||||
|
<Card title="其他信息" className={styles.card} bordered={false}>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={20}>
|
||||||
|
<FormItem {...formAllItemLayout} label="岗位描述">
|
||||||
|
{getFieldDecorator('remark', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入岗位描述',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(<TextArea rows={4} placeholder="请输入岗位描述" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Card>
|
||||||
|
</Form>
|
||||||
|
</Panel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PostAdd;
|
174
src/pages/System/Post/PostEdit.js
Normal file
174
src/pages/System/Post/PostEdit.js
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
import React, { PureComponent } from 'react';
|
||||||
|
import { Form, Input, Card, Button, InputNumber, Row, Col, Select } from 'antd';
|
||||||
|
import { connect } from 'dva';
|
||||||
|
import Panel from '../../../components/Panel';
|
||||||
|
import styles from '../../../layouts/Sword.less';
|
||||||
|
import { POST_DETAIL, POST_INIT, POST_SUBMIT } from '../../../actions/post';
|
||||||
|
|
||||||
|
const FormItem = Form.Item;
|
||||||
|
const { TextArea } = Input;
|
||||||
|
|
||||||
|
@connect(({ post, loading }) => ({
|
||||||
|
post,
|
||||||
|
submitting: loading.effects['post/submit'],
|
||||||
|
}))
|
||||||
|
@Form.create()
|
||||||
|
class PostEdit extends PureComponent {
|
||||||
|
componentWillMount() {
|
||||||
|
const {
|
||||||
|
dispatch,
|
||||||
|
match: {
|
||||||
|
params: { id },
|
||||||
|
},
|
||||||
|
} = this.props;
|
||||||
|
dispatch(POST_DETAIL(id));
|
||||||
|
dispatch(POST_INIT());
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSubmit = e => {
|
||||||
|
e.preventDefault();
|
||||||
|
const {
|
||||||
|
dispatch,
|
||||||
|
match: {
|
||||||
|
params: { id },
|
||||||
|
},
|
||||||
|
form,
|
||||||
|
} = this.props;
|
||||||
|
form.validateFieldsAndScroll((err, values) => {
|
||||||
|
if (!err) {
|
||||||
|
const params = {
|
||||||
|
id,
|
||||||
|
...values,
|
||||||
|
};
|
||||||
|
console.log(params);
|
||||||
|
dispatch(POST_SUBMIT(params));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
form: { getFieldDecorator },
|
||||||
|
post: { detail, init },
|
||||||
|
submitting,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
const { category } = init;
|
||||||
|
|
||||||
|
const formItemLayout = {
|
||||||
|
labelCol: {
|
||||||
|
span: 8,
|
||||||
|
},
|
||||||
|
wrapperCol: {
|
||||||
|
span: 16,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const formAllItemLayout = {
|
||||||
|
labelCol: {
|
||||||
|
span: 4,
|
||||||
|
},
|
||||||
|
wrapperCol: {
|
||||||
|
span: 20,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const action = (
|
||||||
|
<Button type="primary" onClick={this.handleSubmit} loading={submitting}>
|
||||||
|
提交
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Panel title="修改" back="/system/post" action={action}>
|
||||||
|
<Form hideRequiredMark style={{ marginTop: 8 }}>
|
||||||
|
<Card title="基本信息" className={styles.card} bordered={false}>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="岗位类型">
|
||||||
|
{getFieldDecorator('category', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择岗位类型',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: detail.category,
|
||||||
|
})(
|
||||||
|
<Select placeholder="请选择岗位类型">
|
||||||
|
{category.map(d => (
|
||||||
|
<Select.Option key={d.dictKey} value={d.dictKey}>
|
||||||
|
{d.dictValue}
|
||||||
|
</Select.Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="岗位编号">
|
||||||
|
{getFieldDecorator('postCode', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入岗位编号',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: detail.postCode,
|
||||||
|
})(<Input placeholder="请输入岗位编号" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="岗位名称">
|
||||||
|
{getFieldDecorator('postName', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入岗位名称',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: detail.postName,
|
||||||
|
})(<Input placeholder="请输入岗位名称" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} className={styles.inputItem} label="岗位排序">
|
||||||
|
{getFieldDecorator('sort', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入岗位排序',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: detail.sort,
|
||||||
|
})(<InputNumber placeholder="请输入岗位排序" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Card>
|
||||||
|
<Card title="其他信息" className={styles.card} bordered={false}>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={20}>
|
||||||
|
<FormItem {...formAllItemLayout} label="岗位描述">
|
||||||
|
{getFieldDecorator('remark', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入岗位描述',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: detail.remark,
|
||||||
|
})(<TextArea rows={4} placeholder="请输入岗位描述" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Card>
|
||||||
|
</Form>
|
||||||
|
</Panel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PostEdit;
|
85
src/pages/System/Post/PostView.js
Normal file
85
src/pages/System/Post/PostView.js
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import React, { PureComponent } from 'react';
|
||||||
|
import router from 'umi/router';
|
||||||
|
import { Form, Card, Button } from 'antd';
|
||||||
|
import { connect } from 'dva';
|
||||||
|
import Panel from '../../../components/Panel';
|
||||||
|
import styles from '../../../layouts/Sword.less';
|
||||||
|
import { POST_DETAIL } from '../../../actions/post';
|
||||||
|
|
||||||
|
const FormItem = Form.Item;
|
||||||
|
|
||||||
|
@connect(({ post }) => ({
|
||||||
|
post,
|
||||||
|
}))
|
||||||
|
@Form.create()
|
||||||
|
class PostView extends PureComponent {
|
||||||
|
componentWillMount() {
|
||||||
|
const {
|
||||||
|
dispatch,
|
||||||
|
match: {
|
||||||
|
params: { id },
|
||||||
|
},
|
||||||
|
} = this.props;
|
||||||
|
dispatch(POST_DETAIL(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
handleEdit = () => {
|
||||||
|
const {
|
||||||
|
match: {
|
||||||
|
params: { id },
|
||||||
|
},
|
||||||
|
} = this.props;
|
||||||
|
router.push(`/system/post/edit/${id}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
post: { detail },
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
const formItemLayout = {
|
||||||
|
labelCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 7 },
|
||||||
|
},
|
||||||
|
wrapperCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 12 },
|
||||||
|
md: { span: 10 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const action = (
|
||||||
|
<Button type="primary" onClick={this.handleEdit}>
|
||||||
|
修改
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Panel title="查看" back="/system/post" action={action}>
|
||||||
|
<Form hideRequiredMark style={{ marginTop: 8 }}>
|
||||||
|
<Card title="基本信息" className={styles.card} bordered={false}>
|
||||||
|
<FormItem {...formItemLayout} label="岗位类型">
|
||||||
|
<span>{detail.categoryName}</span>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="岗位编号">
|
||||||
|
<span>{detail.postCode}</span>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="岗位名称">
|
||||||
|
<span>{detail.postName}</span>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="岗位排序">
|
||||||
|
<span>{detail.sort}</span>
|
||||||
|
</FormItem>
|
||||||
|
</Card>
|
||||||
|
<Card title="其他信息" className={styles.card} bordered={false}>
|
||||||
|
<FormItem {...formItemLayout} label="岗位描述">
|
||||||
|
<span>{detail.remark}</span>
|
||||||
|
</FormItem>
|
||||||
|
</Card>
|
||||||
|
</Form>
|
||||||
|
</Panel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default PostView;
|
@ -1,14 +1,27 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { connect } from 'dva';
|
import { connect } from 'dva';
|
||||||
import { Button, Col, Form, Input, message, Modal, Row, Tree } from 'antd';
|
import {
|
||||||
|
Upload,
|
||||||
|
Icon,
|
||||||
|
Button,
|
||||||
|
Col,
|
||||||
|
Form,
|
||||||
|
Input,
|
||||||
|
message,
|
||||||
|
Modal,
|
||||||
|
Row,
|
||||||
|
Tree,
|
||||||
|
} from 'antd';
|
||||||
import Panel from '../../../components/Panel';
|
import Panel from '../../../components/Panel';
|
||||||
import Grid from '../../../components/Sword/Grid';
|
import Grid from '../../../components/Sword/Grid';
|
||||||
import { USER_INIT, USER_LIST, USER_ROLE_GRANT } from '../../../actions/user';
|
import { USER_INIT, USER_LIST, USER_ROLE_GRANT } from '../../../actions/user';
|
||||||
import { resetPassword } from '../../../services/user';
|
import { resetPassword } from '../../../services/user';
|
||||||
import { tenantMode } from '../../../defaultSettings';
|
import { tenantMode } from '../../../defaultSettings';
|
||||||
|
import { getAccessToken, getToken } from '../../../utils/authority';
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
const { TreeNode } = Tree;
|
const { TreeNode } = Tree;
|
||||||
|
const { Dragger } = Upload;
|
||||||
|
|
||||||
@connect(({ user, loading }) => ({
|
@connect(({ user, loading }) => ({
|
||||||
user,
|
user,
|
||||||
@ -18,9 +31,12 @@ const { TreeNode } = Tree;
|
|||||||
class User extends PureComponent {
|
class User extends PureComponent {
|
||||||
state = {
|
state = {
|
||||||
visible: false,
|
visible: false,
|
||||||
|
excelVisible: false,
|
||||||
confirmLoading: false,
|
confirmLoading: false,
|
||||||
selectedRows: [],
|
selectedRows: [],
|
||||||
checkedTreeKeys: [],
|
checkedTreeKeys: [],
|
||||||
|
params: {},
|
||||||
|
onReset: () => {},
|
||||||
};
|
};
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
@ -41,6 +57,7 @@ class User extends PureComponent {
|
|||||||
|
|
||||||
// ============ 查询 ===============
|
// ============ 查询 ===============
|
||||||
handleSearch = params => {
|
handleSearch = params => {
|
||||||
|
this.setState({ params });
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
dispatch(USER_LIST(params));
|
dispatch(USER_LIST(params));
|
||||||
};
|
};
|
||||||
@ -133,6 +150,10 @@ class User extends PureComponent {
|
|||||||
const { form } = this.props;
|
const { form } = this.props;
|
||||||
const { getFieldDecorator } = form;
|
const { getFieldDecorator } = form;
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
onReset,
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
|
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
|
||||||
<Col md={6} sm={24}>
|
<Col md={6} sm={24}>
|
||||||
@ -159,10 +180,80 @@ class User extends PureComponent {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onClickReset = () => {
|
||||||
|
const { onReset } = this.state;
|
||||||
|
onReset();
|
||||||
|
};
|
||||||
|
|
||||||
|
handleImport = () => {
|
||||||
|
this.setState({
|
||||||
|
excelVisible: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
handleExcelImport = () =>
|
||||||
|
this.setState({
|
||||||
|
excelVisible: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
handleExcelCancel = () =>
|
||||||
|
this.setState({
|
||||||
|
excelVisible: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
handleExport = () => {
|
||||||
|
const { params } = this.state;
|
||||||
|
Modal.confirm({
|
||||||
|
title: '用户导出确认',
|
||||||
|
content: '是否导出用户数据?',
|
||||||
|
okText: '确定',
|
||||||
|
okType: 'danger',
|
||||||
|
cancelText: '取消',
|
||||||
|
onOk() {
|
||||||
|
const account = params.account || '';
|
||||||
|
const realName = params.realName || '';
|
||||||
|
window.open(
|
||||||
|
`/api/blade-user/export-user?blade-auth=${getAccessToken()}&account=${account}&realName=${realName}`
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onCancel() {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
handleTemplate = () => {
|
||||||
|
window.open(`/api/blade-user/export-template?blade-auth=${getAccessToken()}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
onUpload = info => {
|
||||||
|
const { status } = info.file;
|
||||||
|
if (status !== 'uploading') {
|
||||||
|
window.console.log(info.file, info.fileList);
|
||||||
|
}
|
||||||
|
if (status === 'done') {
|
||||||
|
message.success(`${info.file.name} 数据导入成功!`);
|
||||||
|
this.handleExcelCancel();
|
||||||
|
this.onClickReset();
|
||||||
|
} else if (status === 'error') {
|
||||||
|
message.error(`${info.file.response.msg}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
renderRightButton = () => (
|
||||||
|
<div>
|
||||||
|
<Button icon="vertical-align-bottom" onClick={this.handleImport}>
|
||||||
|
导入
|
||||||
|
</Button>
|
||||||
|
<Button icon="vertical-align-top" onClick={this.handleExport} style={{ marginRight: 0 }}>
|
||||||
|
导出
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const code = 'user';
|
const code = 'user';
|
||||||
|
|
||||||
const { visible, confirmLoading, checkedTreeKeys } = this.state;
|
const { visible, excelVisible, confirmLoading, checkedTreeKeys } = this.state;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
form,
|
form,
|
||||||
@ -173,6 +264,26 @@ class User extends PureComponent {
|
|||||||
},
|
},
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
const uploadProps = {
|
||||||
|
name: 'file',
|
||||||
|
headers: {
|
||||||
|
'Blade-Auth': getToken(),
|
||||||
|
},
|
||||||
|
action: "/api/blade-user/import-user",
|
||||||
|
};
|
||||||
|
|
||||||
|
const formItemLayout = {
|
||||||
|
labelCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 5 },
|
||||||
|
},
|
||||||
|
wrapperCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 12 },
|
||||||
|
md: { span: 16 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: '租户ID',
|
title: '租户ID',
|
||||||
@ -220,6 +331,7 @@ class User extends PureComponent {
|
|||||||
onSearch={this.handleSearch}
|
onSearch={this.handleSearch}
|
||||||
onSelectRow={this.onSelectRow}
|
onSelectRow={this.onSelectRow}
|
||||||
renderSearchForm={this.renderSearchForm}
|
renderSearchForm={this.renderSearchForm}
|
||||||
|
renderRightButton={this.renderRightButton}
|
||||||
btnCallBack={this.handleBtnCallBack}
|
btnCallBack={this.handleBtnCallBack}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
data={data}
|
data={data}
|
||||||
@ -239,6 +351,33 @@ class User extends PureComponent {
|
|||||||
{this.renderTreeNodes(roleTree)}
|
{this.renderTreeNodes(roleTree)}
|
||||||
</Tree>
|
</Tree>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
<Modal
|
||||||
|
title="用户数据导入"
|
||||||
|
width={500}
|
||||||
|
visible={excelVisible}
|
||||||
|
confirmLoading={confirmLoading}
|
||||||
|
onOk={this.handleExcelImport}
|
||||||
|
onCancel={this.handleExcelCancel}
|
||||||
|
okText="确认"
|
||||||
|
cancelText="取消"
|
||||||
|
>
|
||||||
|
<Form style={{ marginTop: 8 }} hideRequiredMark>
|
||||||
|
<FormItem {...formItemLayout} label="模板上传">
|
||||||
|
<Dragger {...uploadProps} onChange={this.onUpload}>
|
||||||
|
<p className="ant-upload-drag-icon">
|
||||||
|
<Icon type="inbox" />
|
||||||
|
</p>
|
||||||
|
<p className="ant-upload-text">将文件拖到此处,或点击上传</p>
|
||||||
|
<p className="ant-upload-hint">请上传 .xls,.xlsx 格式的文件</p>
|
||||||
|
</Dragger>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem {...formItemLayout} label="模板下载">
|
||||||
|
<Button type="primary" icon="download" size="small" onClick={this.handleTemplate}>
|
||||||
|
点击下载
|
||||||
|
</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
</Panel>
|
</Panel>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ class UserAdd extends PureComponent {
|
|||||||
...values,
|
...values,
|
||||||
roleId: func.join(values.roleId),
|
roleId: func.join(values.roleId),
|
||||||
deptId: func.join(values.deptId),
|
deptId: func.join(values.deptId),
|
||||||
|
postId: func.join(values.postId),
|
||||||
birthday: func.format(values.birthday),
|
birthday: func.format(values.birthday),
|
||||||
};
|
};
|
||||||
dispatch(USER_SUBMIT(params));
|
dispatch(USER_SUBMIT(params));
|
||||||
@ -45,7 +46,7 @@ class UserAdd extends PureComponent {
|
|||||||
|
|
||||||
handleChange = value => {
|
handleChange = value => {
|
||||||
const { dispatch, form } = this.props;
|
const { dispatch, form } = this.props;
|
||||||
form.resetFields(['roleId', 'deptId']);
|
form.resetFields(['roleId', 'deptId', 'postId']);
|
||||||
dispatch(USER_CHANGE_INIT({ tenantId: value }));
|
dispatch(USER_CHANGE_INIT({ tenantId: value }));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -53,7 +54,7 @@ class UserAdd extends PureComponent {
|
|||||||
const {
|
const {
|
||||||
form: { getFieldDecorator },
|
form: { getFieldDecorator },
|
||||||
user: {
|
user: {
|
||||||
init: { roleTree, deptTree, tenantList },
|
init: { roleTree, deptTree, postList, tenantList },
|
||||||
},
|
},
|
||||||
submitting,
|
submitting,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
@ -230,6 +231,41 @@ class UserAdd extends PureComponent {
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="用户编号">
|
||||||
|
{getFieldDecorator('code', {})(<Input placeholder="请输入用户编号" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="所属岗位">
|
||||||
|
{getFieldDecorator('postId', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择所属岗位',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(
|
||||||
|
<Select
|
||||||
|
mode="multiple"
|
||||||
|
showSearch
|
||||||
|
filterOption={(input, option) =>
|
||||||
|
option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||||
|
}
|
||||||
|
allowClear
|
||||||
|
placeholder="请选择所属岗位"
|
||||||
|
>
|
||||||
|
{postList.map(d => (
|
||||||
|
<Select.Option key={d.id} value={d.id}>
|
||||||
|
{d.postName}
|
||||||
|
</Select.Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
<Row gutter={24}>
|
<Row gutter={24}>
|
||||||
<Col span={10}>
|
<Col span={10}>
|
||||||
<FormItem {...formItemLayout} label="手机号码">
|
<FormItem {...formItemLayout} label="手机号码">
|
||||||
|
@ -5,7 +5,7 @@ import { connect } from 'dva';
|
|||||||
import Panel from '../../../components/Panel';
|
import Panel from '../../../components/Panel';
|
||||||
import func from '../../../utils/Func';
|
import func from '../../../utils/Func';
|
||||||
import styles from '../../../layouts/Sword.less';
|
import styles from '../../../layouts/Sword.less';
|
||||||
import { USER_CHANGE_INIT, USER_DETAIL, USER_INIT, USER_UPDATE } from '../../../actions/user';
|
import { USER_CHANGE_INIT, USER_DETAIL, USER_UPDATE } from '../../../actions/user';
|
||||||
import { tenantMode } from '../../../defaultSettings';
|
import { tenantMode } from '../../../defaultSettings';
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
@ -23,8 +23,12 @@ class UserEdit extends PureComponent {
|
|||||||
params: { id },
|
params: { id },
|
||||||
},
|
},
|
||||||
} = this.props;
|
} = this.props;
|
||||||
dispatch(USER_DETAIL(id));
|
dispatch(USER_DETAIL(id)).then(()=>{
|
||||||
dispatch(USER_INIT());
|
const {
|
||||||
|
user: { detail },
|
||||||
|
} = this.props;
|
||||||
|
dispatch(USER_CHANGE_INIT({ tenantId: detail.tenantId }));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSubmit = e => {
|
handleSubmit = e => {
|
||||||
@ -43,6 +47,7 @@ class UserEdit extends PureComponent {
|
|||||||
...values,
|
...values,
|
||||||
roleId: func.join(values.roleId),
|
roleId: func.join(values.roleId),
|
||||||
deptId: func.join(values.deptId),
|
deptId: func.join(values.deptId),
|
||||||
|
postId: func.join(values.postId),
|
||||||
birthday: func.format(values.birthday),
|
birthday: func.format(values.birthday),
|
||||||
};
|
};
|
||||||
dispatch(USER_UPDATE(params));
|
dispatch(USER_UPDATE(params));
|
||||||
@ -52,7 +57,7 @@ class UserEdit extends PureComponent {
|
|||||||
|
|
||||||
handleChange = value => {
|
handleChange = value => {
|
||||||
const { dispatch, form } = this.props;
|
const { dispatch, form } = this.props;
|
||||||
form.resetFields(['roleId', 'deptId']);
|
form.resetFields(['roleId', 'deptId', 'postId']);
|
||||||
dispatch(USER_CHANGE_INIT({ tenantId: value }));
|
dispatch(USER_CHANGE_INIT({ tenantId: value }));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -61,7 +66,7 @@ class UserEdit extends PureComponent {
|
|||||||
form: { getFieldDecorator },
|
form: { getFieldDecorator },
|
||||||
user: {
|
user: {
|
||||||
detail,
|
detail,
|
||||||
init: { roleTree, deptTree, tenantList },
|
init: { roleTree, deptTree, postList, tenantList },
|
||||||
},
|
},
|
||||||
submitting,
|
submitting,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
@ -218,6 +223,44 @@ class UserEdit extends PureComponent {
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="用户编号">
|
||||||
|
{getFieldDecorator('code', {
|
||||||
|
initialValue: detail.code
|
||||||
|
})(<Input placeholder="请输入用户编号" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="所属岗位">
|
||||||
|
{getFieldDecorator('postId', {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择所属岗位',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
initialValue: func.split(detail.postId),
|
||||||
|
})(
|
||||||
|
<Select
|
||||||
|
mode="multiple"
|
||||||
|
showSearch
|
||||||
|
filterOption={(input, option) =>
|
||||||
|
option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||||
|
}
|
||||||
|
allowClear
|
||||||
|
placeholder="请选择所属岗位"
|
||||||
|
>
|
||||||
|
{postList.map(d => (
|
||||||
|
<Select.Option key={d.id} value={d.id}>
|
||||||
|
{d.postName}
|
||||||
|
</Select.Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
<Row gutter={24}>
|
<Row gutter={24}>
|
||||||
<Col span={10}>
|
<Col span={10}>
|
||||||
<FormItem {...formItemLayout} label="手机号码">
|
<FormItem {...formItemLayout} label="手机号码">
|
||||||
|
@ -106,6 +106,18 @@ class UserView extends PureComponent {
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="用户编号">
|
||||||
|
<span>{detail.code}</span>
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col span={10}>
|
||||||
|
<FormItem {...formItemLayout} label="所属岗位">
|
||||||
|
<span>{detail.postName}</span>
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
<Row gutter={24}>
|
<Row gutter={24}>
|
||||||
<Col span={10}>
|
<Col span={10}>
|
||||||
<FormItem {...formItemLayout} label="手机号码">
|
<FormItem {...formItemLayout} label="手机号码">
|
||||||
|
29
src/services/post.js
Normal file
29
src/services/post.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { stringify } from 'qs';
|
||||||
|
import func from '../utils/Func';
|
||||||
|
import request from '../utils/request';
|
||||||
|
|
||||||
|
export async function list(params) {
|
||||||
|
return request(`/api/blade-system/post/list?${stringify(params)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function select(params) {
|
||||||
|
return request(`/api/blade-system/post/select?${stringify(params)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function submit(params) {
|
||||||
|
return request('/api/blade-system/post/submit', {
|
||||||
|
method: 'POST',
|
||||||
|
body: params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function detail(params) {
|
||||||
|
return request(`/api/blade-system/post/detail?${stringify(params)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function remove(params) {
|
||||||
|
return request('/api/blade-system/post/remove', {
|
||||||
|
method: 'POST',
|
||||||
|
body: func.toFormData(params),
|
||||||
|
});
|
||||||
|
}
|
@ -2,12 +2,13 @@ import { stringify } from 'qs';
|
|||||||
import request from '../utils/request';
|
import request from '../utils/request';
|
||||||
import func from '../utils/Func';
|
import func from '../utils/Func';
|
||||||
import { getCaptchaKey } from '../utils/authority';
|
import { getCaptchaKey } from '../utils/authority';
|
||||||
|
import { captchaMode } from '../defaultSettings';
|
||||||
|
|
||||||
// =====================用户===========================
|
// =====================用户===========================
|
||||||
|
|
||||||
export async function accountLogin(params) {
|
export async function accountLogin(params) {
|
||||||
const values = params;
|
const values = params;
|
||||||
values.grantType = 'captcha';
|
values.grantType = captchaMode ? 'captcha' : 'password';
|
||||||
values.scope = 'all';
|
values.scope = 'all';
|
||||||
return request('/api/blade-auth/token', {
|
return request('/api/blade-auth/token', {
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -34,6 +34,14 @@ export function setToken(token) {
|
|||||||
localStorage.setItem('sword-token', token);
|
localStorage.setItem('sword-token', token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getAccessToken() {
|
||||||
|
return localStorage.getItem('sword-access-token') || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setAccessToken(accessToken) {
|
||||||
|
localStorage.setItem('sword-access-token', accessToken);
|
||||||
|
}
|
||||||
|
|
||||||
export function getRoutes() {
|
export function getRoutes() {
|
||||||
return JSON.parse(localStorage.getItem('sword-routes')) || [];
|
return JSON.parse(localStorage.getItem('sword-routes')) || [];
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user