mirror of
https://github.com/chillzhuang/Sword
synced 2024-11-23 10:49:27 +08:00
🎉 2.7.1.RELEASE,增加行政区划管理,支持seata1.2
This commit is contained in:
parent
50cbbe6524
commit
43a49063e2
@ -1,9 +1,9 @@
|
||||
<p align="center">
|
||||
<img src="https://img.shields.io/badge/Release-V2.7.0-green.svg" alt="Downloads">
|
||||
<img src="https://img.shields.io/badge/Release-V2.7.1-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/license-Apache%202-blue.svg" alt="Build 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.6.RELEASE-blue.svg" alt="Downloads">
|
||||
<img src="https://img.shields.io/badge/Spring%20Cloud-Hoxton.SR5-blue.svg" alt="Coverage Status">
|
||||
<img src="https://img.shields.io/badge/Spring%20Boot-2.2.7.RELEASE-blue.svg" alt="Downloads">
|
||||
<a target="_blank" href="https://bladex.vip">
|
||||
<img src="https://img.shields.io/badge/Author-Small%20Chill-ff69b4.svg" alt="Downloads">
|
||||
</a>
|
||||
@ -58,7 +58,8 @@ SpringBlade
|
||||
* 会员计划:[SpringBlade会员计划](https://gitee.com/smallc/SpringBlade/wikis/SpringBlade会员计划)
|
||||
* 交流一群:`477853168`(满)
|
||||
* 交流二群:`751253339`(满)
|
||||
* 交流三群:`784729540`
|
||||
* 交流三群:`784729540`(满)
|
||||
* 交流四群:`1034621754`
|
||||
|
||||
## 在线演示
|
||||
* Saber-基于Vue:[https://saber.bladex.vip](https://saber.bladex.vip)
|
||||
|
@ -90,6 +90,18 @@ export default [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/base',
|
||||
routes: [
|
||||
{
|
||||
path: '/base/region',
|
||||
routes: [
|
||||
{ path: '/base/region', redirect: '/base/region/detail' },
|
||||
{ path: '/base/region/detail', component: './Base/Region/Region' },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/system',
|
||||
routes: [
|
||||
|
@ -6,6 +6,8 @@ export default {
|
||||
'menu.dashboard.workplace': 'Workplace',
|
||||
'menu.desk': 'desktop',
|
||||
'menu.desk.notice': 'notice',
|
||||
'menu.base': 'base',
|
||||
'menu.base.region': 'region',
|
||||
'menu.system': 'system',
|
||||
'menu.system.user': 'user',
|
||||
'menu.system.dept': 'department',
|
||||
|
@ -6,6 +6,8 @@ export default {
|
||||
'menu.dashboard.workplace': '工作台',
|
||||
'menu.desk': '工作台',
|
||||
'menu.desk.notice': '通知公告',
|
||||
'menu.base': '基础配置',
|
||||
'menu.base.region': '行政区划',
|
||||
'menu.system': '系统管理',
|
||||
'menu.system.user': '用户管理',
|
||||
'menu.system.dept': '部门管理',
|
||||
|
@ -6,6 +6,8 @@ export default {
|
||||
'menu.dashboard.workplace': '工作台',
|
||||
'menu.desk': '工作台',
|
||||
'menu.desk.notice': '通知公告',
|
||||
'menu.base': '基礎配置',
|
||||
'menu.base.region': '行政區劃',
|
||||
'menu.system': '系統管理',
|
||||
'menu.system.user': '用戶管理',
|
||||
'menu.system.dept': '部門管理',
|
||||
|
399
src/pages/Base/Region/Region.js
Normal file
399
src/pages/Base/Region/Region.js
Normal file
@ -0,0 +1,399 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
Col,
|
||||
Form,
|
||||
Input,
|
||||
InputNumber,
|
||||
Row,
|
||||
Tree,
|
||||
Cascader,
|
||||
Radio,
|
||||
message,
|
||||
Modal,
|
||||
} from 'antd';
|
||||
import Panel from '../../../components/Panel';
|
||||
import styles from '@/layouts/Sword.less';
|
||||
import { getLazyTree, detail, submit, remove } from '../../../services/region';
|
||||
import { getButton, hasButton } from '../../../utils/authority';
|
||||
import Func from '../../../utils/Func';
|
||||
|
||||
const FormItem = Form.Item;
|
||||
const { TreeNode } = Tree;
|
||||
const { TextArea } = Input;
|
||||
const ButtonGroup = Button.Group;
|
||||
|
||||
@Form.create()
|
||||
class Region extends PureComponent {
|
||||
state = {
|
||||
topCode: '00',
|
||||
treeData: [],
|
||||
treeCascader: [],
|
||||
debugVisible: false,
|
||||
};
|
||||
|
||||
// ============ 初始化数据 ===============
|
||||
componentWillMount() {
|
||||
this.initTree();
|
||||
this.initCascader('00');
|
||||
}
|
||||
|
||||
initTree = () => {
|
||||
const { topCode } = this.state;
|
||||
getLazyTree({ parentCode: topCode }).then(resp => {
|
||||
if (resp.success) {
|
||||
this.setState({
|
||||
treeData: resp.data.map(item => {
|
||||
return { ...item, isLeaf: !item.hasChildren };
|
||||
}),
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
initCascader = code => {
|
||||
getLazyTree({ parentCode: code }).then(resp => {
|
||||
if (resp.success) {
|
||||
this.setState({
|
||||
treeCascader: resp.data.map(item => {
|
||||
return {
|
||||
label: item.title,
|
||||
value: item.value,
|
||||
isLeaf: !item.hasChildren,
|
||||
};
|
||||
}),
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
onSelect = checkedTreeKeys => {
|
||||
const code = checkedTreeKeys[0];
|
||||
if (Func.isEmpty(code)) {
|
||||
return;
|
||||
}
|
||||
detail({ code }).then(resp => {
|
||||
if (resp.success) {
|
||||
const { form } = this.props;
|
||||
const { data } = resp;
|
||||
form.setFieldsValue({
|
||||
parentCode: data.parentCode,
|
||||
parentName: data.parentName,
|
||||
code: data.code,
|
||||
name: data.name,
|
||||
level: data.level,
|
||||
sort: data.sort,
|
||||
remark: data.remark,
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
onLoadData = treeNode =>
|
||||
new Promise(resolve => {
|
||||
if (treeNode.props.children) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
getLazyTree({ parentCode: treeNode.props.id }).then(resp => {
|
||||
if (resp.success) {
|
||||
const { treeData } = this.state;
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
treeNode.props.dataRef.children = resp.data.map(item => {
|
||||
return { ...item, isLeaf: !item.hasChildren };
|
||||
});
|
||||
this.setState({
|
||||
treeData: [...treeData],
|
||||
});
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
onCascaderChange = (value, selectedOptions) => {
|
||||
window.console.log(value, selectedOptions);
|
||||
};
|
||||
|
||||
onLoadCascaderData = selectedOptions => {
|
||||
const targetOption = selectedOptions[selectedOptions.length - 1];
|
||||
targetOption.loading = true;
|
||||
|
||||
getLazyTree({ parentCode: targetOption.value }).then(resp => {
|
||||
if (resp.success) {
|
||||
targetOption.loading = false;
|
||||
targetOption.children = resp.data.map(item => {
|
||||
return {
|
||||
label: item.title,
|
||||
value: item.value,
|
||||
isLeaf: !item.hasChildren,
|
||||
};
|
||||
});
|
||||
const { treeCascader } = this.state;
|
||||
this.setState({
|
||||
treeCascader: [...treeCascader],
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
handleAdd = () => {
|
||||
const { form } = this.props;
|
||||
const region = form.getFieldsValue();
|
||||
if (!region.code || !region.name) {
|
||||
message.warn('请先选择一项区划!');
|
||||
return;
|
||||
}
|
||||
form.setFieldsValue({
|
||||
parentCode: region.code,
|
||||
parentName: region.name,
|
||||
code: region.code,
|
||||
name: '',
|
||||
level: region.level < 5 ? region.level + 1 : region.level,
|
||||
remark: region.remark,
|
||||
});
|
||||
};
|
||||
|
||||
handleDelete = () => {
|
||||
const { form } = this.props;
|
||||
const code = form.getFieldValue('code');
|
||||
Modal.confirm({
|
||||
title: '删除确认',
|
||||
content: '确定删除该条记录?',
|
||||
okText: '确定',
|
||||
okType: 'danger',
|
||||
cancelText: '取消',
|
||||
onOk() {
|
||||
remove({ id: code }).then(resp => {
|
||||
if (resp.success) {
|
||||
message.success(resp.msg);
|
||||
form.resetFields();
|
||||
} else {
|
||||
message.error(resp.msg || '删除失败');
|
||||
}
|
||||
});
|
||||
},
|
||||
onCancel() {},
|
||||
});
|
||||
};
|
||||
|
||||
handleDebug = () => {
|
||||
this.setState({ debugVisible: true });
|
||||
};
|
||||
|
||||
handleDebugCancel = () => {
|
||||
this.setState({ debugVisible: false });
|
||||
};
|
||||
|
||||
handleSubmit = e => {
|
||||
e.preventDefault();
|
||||
const { form } = this.props;
|
||||
const { topCode } = this.state;
|
||||
form.validateFieldsAndScroll((err, values) => {
|
||||
if (err) return;
|
||||
const parentCode = form.getFieldValue('parentCode');
|
||||
const code = form.getFieldValue('code');
|
||||
if (parentCode === code) {
|
||||
message.warn('请输入正确的区划子编号!');
|
||||
return;
|
||||
}
|
||||
const params = {
|
||||
...values,
|
||||
parentCode: parentCode === topCode ? '' : parentCode,
|
||||
};
|
||||
submit(params).then(resp => {
|
||||
if (resp.success) {
|
||||
message.success(resp.msg);
|
||||
form.resetFields();
|
||||
} else {
|
||||
message.error(resp.msg || '提交失败');
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
handleReset = () => {
|
||||
const { form } = this.props;
|
||||
form.resetFields();
|
||||
};
|
||||
|
||||
renderTreeNodes = data =>
|
||||
data.map(item => {
|
||||
if (item.children) {
|
||||
return (
|
||||
<TreeNode title={item.title} key={item.key} dataRef={item}>
|
||||
{this.renderTreeNodes(item.children)}
|
||||
</TreeNode>
|
||||
);
|
||||
}
|
||||
return <TreeNode {...item} title={item.title} key={item.key} dataRef={item} />;
|
||||
});
|
||||
|
||||
render() {
|
||||
const {
|
||||
form: { getFieldDecorator },
|
||||
} = this.props;
|
||||
|
||||
const buttons = getButton('region');
|
||||
|
||||
const {
|
||||
treeData,
|
||||
treeCascader,
|
||||
debugVisible,
|
||||
} = this.state;
|
||||
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 5 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 12 },
|
||||
md: { span: 16 },
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<Panel>
|
||||
<Row gutter={24}>
|
||||
<Col span={8}>
|
||||
<Card className={styles.card} bordered={false} style={{ marginRight: '10px' }}>
|
||||
<Tree onSelect={this.onSelect} loadData={this.onLoadData}>
|
||||
{this.renderTreeNodes(treeData)}
|
||||
</Tree>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={16}>
|
||||
<Row gutter={24}>
|
||||
<Card className={styles.card} bordered={false}>
|
||||
<Col span={18}>
|
||||
<ButtonGroup>
|
||||
{hasButton(buttons, 'region_add') ? (
|
||||
<Button type="primary" icon="plus" onClick={this.handleAdd}>
|
||||
新增下级
|
||||
</Button>
|
||||
) : null}
|
||||
{hasButton(buttons, 'region_delete') ? (
|
||||
<Button type="danger" icon="delete" onClick={this.handleDelete}>
|
||||
删除
|
||||
</Button>
|
||||
) : null}
|
||||
{hasButton(buttons, 'region_debug') ? (
|
||||
<Button icon="right-circle" onClick={this.handleDebug}>
|
||||
调试
|
||||
</Button>
|
||||
) : null}
|
||||
</ButtonGroup>
|
||||
</Col>
|
||||
<Col span={6} style={{ textAlign: 'right' }}>
|
||||
<ButtonGroup>
|
||||
<Button type="primary" htmlType="submit" onClick={this.handleSubmit}>
|
||||
提 交
|
||||
</Button>
|
||||
<Button onClick={this.handleReset}>重 置</Button>
|
||||
</ButtonGroup>
|
||||
</Col>
|
||||
</Card>
|
||||
</Row>
|
||||
<Row gutter={24}>
|
||||
<Card className={styles.card} bordered={false}>
|
||||
<Form>
|
||||
<FormItem {...formItemLayout} label="父区划编号">
|
||||
{getFieldDecorator('parentCode', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入父区划编号',
|
||||
},
|
||||
],
|
||||
})(<Input disabled placeholder="请输入父区划编号" />)}
|
||||
</FormItem>
|
||||
<FormItem {...formItemLayout} label="父区划名称">
|
||||
{getFieldDecorator('parentName', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入父区划名称',
|
||||
},
|
||||
],
|
||||
})(<Input disabled placeholder="请输入父区划名称" />)}
|
||||
</FormItem>
|
||||
<FormItem {...formItemLayout} label="区划编号">
|
||||
{getFieldDecorator('code', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入区划编号',
|
||||
},
|
||||
],
|
||||
})(<Input placeholder="请输入区划编号" />)}
|
||||
</FormItem>
|
||||
<FormItem {...formItemLayout} label="区划名称">
|
||||
{getFieldDecorator('name', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入区划名称',
|
||||
},
|
||||
],
|
||||
})(<Input placeholder="请输入区划名称" />)}
|
||||
</FormItem>
|
||||
<FormItem {...formItemLayout} label="区划等级">
|
||||
{getFieldDecorator('level', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入区划等级',
|
||||
},
|
||||
],
|
||||
})(
|
||||
<Radio.Group>
|
||||
<Radio value={0}>国家</Radio>
|
||||
<Radio value={1}>省份/直辖市</Radio>
|
||||
<Radio value={2}>地市</Radio>
|
||||
<Radio value={3}>区县</Radio>
|
||||
<Radio value={4}>乡镇</Radio>
|
||||
<Radio value={5}>村委</Radio>
|
||||
</Radio.Group>
|
||||
)}
|
||||
</FormItem>
|
||||
<FormItem {...formItemLayout} className={styles.inputItem} label="区划排序">
|
||||
{getFieldDecorator('sort', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入区划排序',
|
||||
},
|
||||
],
|
||||
})(<InputNumber placeholder="请输入区划排序" />)}
|
||||
</FormItem>
|
||||
<FormItem {...formItemLayout} label="区划备注">
|
||||
{getFieldDecorator('remark', {})(<TextArea placeholder="请输入区划备注" />)}
|
||||
</FormItem>
|
||||
</Form>
|
||||
</Card>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
<Modal
|
||||
title="行政区划数据调试"
|
||||
width={500}
|
||||
visible={debugVisible}
|
||||
onOk={this.handleDebugCancel}
|
||||
onCancel={this.handleDebugCancel}
|
||||
footer={null}
|
||||
>
|
||||
<Cascader
|
||||
style={{ width: '100%' }}
|
||||
options={treeCascader}
|
||||
loadData={this.onLoadCascaderData}
|
||||
onChange={this.onCascaderChange}
|
||||
changeOnSelect
|
||||
/>
|
||||
</Modal>
|
||||
</Panel>
|
||||
);
|
||||
}
|
||||
}
|
||||
export default Region;
|
@ -14,14 +14,14 @@ class Workplace extends PureComponent {
|
||||
<Row gutter={24}>
|
||||
<Col span={24}>
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<img src="https://img.shields.io/badge/Release-V2.7.0-green.svg" alt="Downloads" />
|
||||
<img src="https://img.shields.io/badge/Release-V2.7.1-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/Spring%20Cloud-Hoxton.SR3-blue.svg"
|
||||
src="https://img.shields.io/badge/Spring%20Cloud-Hoxton.SR5-blue.svg"
|
||||
alt="Coverage Status"
|
||||
/>
|
||||
<img
|
||||
src="https://img.shields.io/badge/Spring%20Boot-2.2.6.RELEASE-blue.svg"
|
||||
src="https://img.shields.io/badge/Spring%20Boot-2.2.7.RELEASE-blue.svg"
|
||||
alt="Downloads"
|
||||
/>
|
||||
<a href="https://bladex.vip">
|
||||
@ -206,7 +206,19 @@ class Workplace extends PureComponent {
|
||||
</Row>
|
||||
<Row gutter={24}>
|
||||
<Card className={styles.card} bordered={false}>
|
||||
<Collapse bordered={false} defaultActiveKey={['17']}>
|
||||
<Collapse bordered={false} defaultActiveKey={['18']}>
|
||||
<Panel header="2.7.1发布 增加行政区划管理,支持seata1.2" key="18">
|
||||
<div>1.升级至 SpringCloud Hoxton.SR5</div>
|
||||
<div>2.升级至 SpringBoot 2.2.7.RELEASE</div>
|
||||
<div>3.升级至 Seata 1.2.0</div>
|
||||
<div>4.升级至 FastJson 1.2.70</div>
|
||||
<div>5.升级至 Avue 2.5.3</div>
|
||||
<div>6.新增行政区划管理模块</div>
|
||||
<div>7.优化用户导入的密码配置逻辑</div>
|
||||
<div>8.优化INode结构支持懒加载数据格式</div>
|
||||
<div>9.优化代码生成模板,支持最新版Saber结构</div>
|
||||
<div>10.修复Log模块在多线程、异步场景下报错的问题</div>
|
||||
</Panel>
|
||||
<Panel header="2.7.0发布 内核全面升级,增加岗位管理,用户导入导出" key="17">
|
||||
<div>1.升级至 SpringCloud Hoxton.SR3</div>
|
||||
<div>2.升级至 SpringBoot 2.2.6.RELEASE</div>
|
||||
|
25
src/services/region.js
Normal file
25
src/services/region.js
Normal file
@ -0,0 +1,25 @@
|
||||
import { stringify } from 'qs';
|
||||
import request from '../utils/request';
|
||||
import func from '../utils/Func';
|
||||
|
||||
export async function getLazyTree(params) {
|
||||
return request(`/api/blade-system/region/lazy-tree?${stringify(params)}`);
|
||||
}
|
||||
|
||||
export async function remove(params) {
|
||||
return request('/api/blade-system/region/remove', {
|
||||
method: 'POST',
|
||||
body: func.toFormData(params),
|
||||
});
|
||||
}
|
||||
|
||||
export async function submit(params) {
|
||||
return request('/api/blade-system/region/submit', {
|
||||
method: 'POST',
|
||||
body: params,
|
||||
});
|
||||
}
|
||||
|
||||
export async function detail(params) {
|
||||
return request(`/api/blade-system/region/detail?${stringify(params)}`);
|
||||
}
|
@ -51,6 +51,10 @@ export function setRoutes(routes) {
|
||||
localStorage.setItem('sword-routes', JSON.stringify(routes));
|
||||
}
|
||||
|
||||
export function hasButton(buttons, code) {
|
||||
return buttons.filter(button => button.code === code).length > 0;
|
||||
}
|
||||
|
||||
export function getButtons() {
|
||||
return JSON.parse(localStorage.getItem('sword-buttons')) || [];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user