From bbb68ef7ae4c64e14824d00bc87119cdd8202766 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=87=AA=E5=B8=A6=E5=A4=A7=E4=BD=AC=E6=B0=94=E5=9C=BA?=
<188633308@qq.com>
Date: Sun, 20 Jun 2021 15:07:31 +0800
Subject: [PATCH] =?UTF-8?q?add=20=E6=9F=A5=E8=AF=A2=E8=A1=A8=E6=A0=BC?=
=?UTF-8?q?=E7=A7=8D=E5=AD=90=E6=96=87=E4=BB=B6=E5=8F=8A=E7=B3=BB=E7=BB=9F?=
=?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../public/seed/query-table-form/form.jsx | 77 +++++
web-react/public/seed/query-table/index.jsx | 237 ++++++++++++++++
web-react/src/pages/system/config/form.jsx | 134 +++++++++
web-react/src/pages/system/config/index.jsx | 263 ++++++++++++++++++
4 files changed, 711 insertions(+)
create mode 100644 web-react/public/seed/query-table-form/form.jsx
create mode 100644 web-react/public/seed/query-table/index.jsx
create mode 100644 web-react/src/pages/system/config/form.jsx
create mode 100644 web-react/src/pages/system/config/index.jsx
diff --git a/web-react/public/seed/query-table-form/form.jsx b/web-react/public/seed/query-table-form/form.jsx
new file mode 100644
index 0000000..0c83022
--- /dev/null
+++ b/web-react/public/seed/query-table-form/form.jsx
@@ -0,0 +1,77 @@
+import React, { Component } from 'react'
+import { Form, Spin } from 'antd'
+import { AntIcon } from 'components'
+import { cloneDeep } from 'lodash'
+
+const initialValues = {}
+
+export default class form extends Component {
+ state = {
+ // 加载状态
+ loading: true,
+ }
+
+ // 表单实例
+ form = React.createRef()
+
+ // 初始化数据
+ record = {}
+
+ /**
+ * mount后回调
+ */
+ componentDidMount() {
+ this.props.created && this.props.created(this)
+ }
+
+ /**
+ * 填充数据
+ * 可以在设置this.record之后对其作出数据结构调整
+ * [异步,必要]
+ * @param {*} params
+ */
+ async fillData(params) {
+ this.record = cloneDeep(params.record)
+ //#region 从后端转换成前段所需格式,也可以在此处调用获取详细数据接口
+ //#endregion
+ this.form.current.setFieldsValue(this.record)
+
+ this.setState({
+ loading: false,
+ })
+ }
+
+ /**
+ * 获取数据
+ * 可以对postData进行数据结构调整
+ * [异步,必要]
+ * @returns
+ */
+ async getData() {
+ const form = this.form.current
+
+ const valid = await form.validateFields()
+ if (valid) {
+ const postData = form.getFieldsValue()
+ if (this.record) {
+ postData.id = this.record.id
+ }
+ //#region 从前段转换后端所需格式
+ //#endregion
+ return postData
+ }
+ }
+
+ //#region 自定义方法
+ //#endregion
+
+ render() {
+ return (
+
+ )
+ }
+}
diff --git a/web-react/public/seed/query-table/index.jsx b/web-react/public/seed/query-table/index.jsx
new file mode 100644
index 0000000..26773b8
--- /dev/null
+++ b/web-react/public/seed/query-table/index.jsx
@@ -0,0 +1,237 @@
+import React, { Component } from 'react'
+import { Button, Card, Form, Input, message as Message, Popconfirm } from 'antd'
+import { AntIcon, Auth, Container, ModalForm, QueryTable, QueryTableActions } from 'components'
+import { api } from 'common/api'
+import auth from 'components/authorized/handler'
+import { isEqual } from 'lodash'
+import getDictData from 'util/dic'
+import { toCamelCase } from 'util/format'
+import FormBody from './form'
+
+/**
+ * 注释段[\/**\/]为必须要改
+ */
+
+/**
+ * 配置页面所需接口函数
+ */
+const apiAction = {
+ page: api /**/,
+ add: api /**/,
+ edit: api /**/,
+ delete: api /**/,
+}
+
+/**
+ * 用于弹窗标题
+ * [必要]
+ */
+const name = '/**/'
+
+/**
+ * 统一配置权限标识
+ * [必要]
+ */
+const authName = '/**/'
+
+export default class index extends Component {
+ state = {
+ codes: {},
+ }
+
+ // 表格实例
+ table = React.createRef()
+
+ // 新增窗口实例
+ addForm = React.createRef()
+ // 编辑窗口实例
+ editForm = React.createRef()
+
+ columns = []
+
+ /**
+ * 构造函数,在渲染前动态添加操作字段等
+ * @param {*} props
+ */
+ constructor(props) {
+ super(props)
+
+ const flag = auth({ [authName]: [['edit'], ['delete']] })
+
+ if (flag) {
+ this.columns.push({
+ title: '操作',
+ width: 150,
+ dataIndex: 'actions',
+ render: (text, record) => (
+
+
+ this.onOpen(this.editForm, record)}>编辑
+
+
+ this.onDelete(record)}
+ >
+ 删除
+
+
+
+ ),
+ })
+ }
+ }
+
+ /**
+ * 阻止外部组件引发的渲染,提升性能
+ * 可自行添加渲染条件
+ * [必要]
+ * @param {*} props
+ * @param {*} state
+ * @returns
+ */
+ shouldComponentUpdate(props, state) {
+ return !isEqual(this.state, state)
+ }
+
+ /**
+ * 加载字典数据,之后开始加载表格数据
+ * 如果必须要加载字典数据,可直接对表格设置autoLoad=true
+ */
+ componentDidMount() {
+ const { onLoading, onLoadData } = this.table.current
+ onLoading()
+ getDictData(/**/).then(codes => {
+ this.setState({ codes }, () => {
+ onLoadData()
+ })
+ })
+ }
+
+ /**
+ * 调用加载数据接口,可在调用前对query进行处理
+ * [异步,必要]
+ * @param {*} params
+ * @param {*} query
+ * @returns
+ */
+ loadData = async (params, query) => {
+ const { data } = await apiAction.page({
+ ...params,
+ ...query,
+ })
+ return data
+ }
+
+ /**
+ * 绑定字典数据
+ * @param {*} code
+ * @param {*} name
+ * @returns
+ */
+ bindCodeValue(code, name) {
+ name = toCamelCase(name)
+ const codes = this.state.codes[name]
+ if (codes) {
+ const c = codes.find(p => p.code === code)
+ if (c) {
+ return c.value
+ }
+ }
+ return null
+ }
+
+ /**
+ * 打开新增/编辑弹窗
+ * @param {*} modal
+ * @param {*} record
+ */
+ onOpen(modal, record) {
+ modal.current.open({
+ record,
+ })
+ }
+
+ /**
+ * 对表格上的操作进行统一处理
+ * [异步]
+ * @param {*} action
+ * @param {*} successMessage
+ */
+ async onAction(action, successMessage) {
+ const { onLoading, onLoaded, onReloadData } = this.table.current
+ onLoading()
+ try {
+ if (action) {
+ await action
+ }
+ if (successMessage) {
+ Message.success(successMessage)
+ }
+ onReloadData()
+ } catch {
+ onLoaded()
+ }
+ }
+
+ /**
+ * 删除
+ * @param {*} record
+ */
+ onDelete(record) {
+ this.onAction(apiAction.delete(record), '删除成功')
+ }
+
+ //#region 自定义方法
+ //#endregion
+
+ render() {
+ return (
+
+
+
+ }
+ operator={
+
+ }
+ onClick={() => this.onOpen(this.addForm)}
+ >
+ 新增{name}
+
+
+ }
+ />
+
+
+
+ this.table.current.onReloadData()}
+ >
+
+
+
+
+
+ this.table.current.onReloadData()}
+ >
+
+
+
+
+ )
+ }
+}
diff --git a/web-react/src/pages/system/config/form.jsx b/web-react/src/pages/system/config/form.jsx
new file mode 100644
index 0000000..0321461
--- /dev/null
+++ b/web-react/src/pages/system/config/form.jsx
@@ -0,0 +1,134 @@
+import React, { Component } from 'react'
+import { Form, Input, Radio, Select, Spin } from 'antd'
+import { AntIcon } from 'components'
+import { cloneDeep } from 'lodash'
+import getDictData from 'util/dic'
+
+const initialValues = {}
+
+export default class form extends Component {
+ state = {
+ // 加载状态
+ loading: true,
+
+ codes: {
+ constsType: [],
+ },
+ }
+
+ // 表单实例
+ form = React.createRef()
+
+ // 初始化数据
+ record = {}
+
+ /**
+ * mount后回调
+ */
+ componentDidMount() {
+ this.props.created && this.props.created(this)
+ }
+
+ /**
+ * 填充数据
+ * 可以在设置this.record之后对其作出数据结构调整
+ * [异步,必要]
+ * @param {*} params
+ */
+ async fillData(params) {
+ this.record = cloneDeep(params.record)
+ //#region 从后端转换成前段所需格式,也可以在此处调用获取详细数据接口
+ const codes = await getDictData('consts_type')
+ this.setState({ codes })
+ //#endregion
+ this.form.current.setFieldsValue(this.record)
+
+ this.setState({
+ loading: false,
+ })
+ }
+
+ /**
+ * 获取数据
+ * 可以对postData进行数据结构调整
+ * [异步,必要]
+ * @returns
+ */
+ async getData() {
+ const form = this.form.current
+
+ const valid = await form.validateFields()
+ if (valid) {
+ const postData = form.getFieldsValue()
+ if (this.record) {
+ postData.id = this.record.id
+ }
+ //#region 从前段转换后端所需格式
+ //#endregion
+ return postData
+ }
+ }
+
+ //#region 自定义方法
+ //#endregion
+
+ render() {
+ const { codes } = this.state
+
+ return (
+
+ )
+ }
+}
diff --git a/web-react/src/pages/system/config/index.jsx b/web-react/src/pages/system/config/index.jsx
new file mode 100644
index 0000000..9668b4f
--- /dev/null
+++ b/web-react/src/pages/system/config/index.jsx
@@ -0,0 +1,263 @@
+import React, { Component } from 'react'
+import { Button, Card, Form, Input, message as Message, Popconfirm } from 'antd'
+import { AntIcon, Auth, Container, ModalForm, QueryTable, QueryTableActions } from 'components'
+import { api } from 'common/api'
+import auth from 'components/authorized/handler'
+import { isEqual } from 'lodash'
+import getDictData from 'util/dic'
+import { toCamelCase } from 'util/format'
+import FormBody from './form'
+
+// 配置页面所需接口函数
+const apiAction = {
+ page: api.sysConfigPage,
+ add: api.sysConfigAdd,
+ edit: api.sysConfigEdit,
+ delete: api.sysConfigDelete,
+}
+
+// 用于弹窗标题
+const name = '应用'
+
+// 统一配置权限标识
+const authName = 'sysConfig'
+
+export default class index extends Component {
+ state = {
+ codes: {
+ constsType: [],
+ },
+ }
+
+ // 表格实例
+ table = React.createRef()
+
+ // 新增窗口实例
+ addForm = React.createRef()
+ // 编辑窗口实例
+ editForm = React.createRef()
+
+ columns = [
+ {
+ title: '参数名称',
+ dataIndex: 'name',
+ sorter: true,
+ },
+ {
+ title: '唯一编码',
+ dataIndex: 'code',
+ sorter: true,
+ },
+ {
+ title: '参数值',
+ dataIndex: 'value',
+ sorter: true,
+ },
+ {
+ title: '所属分类',
+ dataIndex: 'groupCode',
+ sorter: true,
+ render: text => this.bindCodeValue(text, 'consts_type'),
+ },
+ {
+ title: '备注',
+ dataIndex: 'remark',
+ sorter: true,
+ },
+ ]
+
+ /**
+ * 构造函数,在渲染前动态添加操作字段等
+ * @param {*} props
+ */
+ constructor(props) {
+ super(props)
+
+ const flag = auth({ [authName]: [['edit'], ['delete']] })
+
+ if (flag) {
+ this.columns.push({
+ title: '操作',
+ width: 150,
+ dataIndex: 'actions',
+ render: (text, record) => (
+
+
+ this.onOpen(this.editForm, record)}>编辑
+
+
+ this.onDelete(record)}
+ >
+ 删除
+
+
+
+ ),
+ })
+ }
+ }
+
+ /**
+ * 阻止外部组件引发的渲染,提升性能
+ * 可自行添加渲染条件
+ * [必要]
+ * @param {*} props
+ * @param {*} state
+ * @returns
+ */
+ shouldComponentUpdate(props, state) {
+ return !isEqual(this.state, state)
+ }
+
+ /**
+ * 加载字典数据,之后开始加载表格数据
+ * 如果必须要加载字典数据,可直接对表格设置autoLoad=true
+ */
+ componentDidMount() {
+ const { onLoading, onLoadData } = this.table.current
+ onLoading()
+ getDictData('consts_type').then(codes => {
+ this.setState({ codes }, () => {
+ onLoadData()
+ })
+ })
+ }
+
+ /**
+ * 调用加载数据接口,可在调用前对query进行处理
+ * [异步,必要]
+ * @param {*} params
+ * @param {*} query
+ * @returns
+ */
+ loadData = async (params, query) => {
+ const { data } = await apiAction.page({
+ ...params,
+ ...query,
+ })
+ return data
+ }
+
+ /**
+ * 绑定字典数据
+ * @param {*} code
+ * @param {*} name
+ * @returns
+ */
+ bindCodeValue(code, name) {
+ name = toCamelCase(name)
+ const codes = this.state.codes[name]
+ if (codes) {
+ const c = codes.find(p => p.code === code)
+ if (c) {
+ return c.value
+ }
+ }
+ return null
+ }
+
+ /**
+ * 打开新增/编辑弹窗
+ * @param {*} modal
+ * @param {*} record
+ */
+ onOpen(modal, record) {
+ modal.current.open({
+ record,
+ })
+ }
+
+ /**
+ * 对表格上的操作进行统一处理
+ * [异步]
+ * @param {*} action
+ * @param {*} successMessage
+ */
+ async onAction(action, successMessage) {
+ const { onLoading, onLoaded, onReloadData } = this.table.current
+ onLoading()
+ try {
+ if (action) {
+ await action
+ }
+ if (successMessage) {
+ Message.success(successMessage)
+ }
+ onReloadData()
+ } catch {
+ onLoaded()
+ }
+ }
+
+ /**
+ * 删除
+ * @param {*} record
+ */
+ onDelete(record) {
+ this.onAction(apiAction.delete(record), '删除成功')
+ }
+
+ //#region 自定义方法
+ //#endregion
+
+ render() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ }
+ operator={
+
+ }
+ onClick={() => this.onOpen(this.addForm)}
+ >
+ 新增{name}
+
+
+ }
+ />
+
+
+
+ this.table.current.onReloadData()}
+ >
+
+
+
+
+
+ this.table.current.onReloadData()}
+ >
+
+
+
+
+ )
+ }
+}