index.tsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. import { useModel, useRequest } from 'umi'
  2. import { Delete } from '@icon-park/react'
  3. import ProForm, { ProFormDependency, ProFormSwitch, ProFormCheckbox } from '@ant-design/pro-form'
  4. import type { FormInstance } from 'antd'
  5. import { message, Table, Tabs, Radio, Space, Popconfirm } from 'antd'
  6. import React, { useRef, useMemo, useState, useEffect } from 'react'
  7. import styles from '@/pages/Role/index.less'
  8. import classNames from 'classnames'
  9. import {
  10. fetchRoleStaffListByRoleId,
  11. updateRolePermission,
  12. getRolePermissions,
  13. updatePermDataByRoleId,
  14. deleteStaff
  15. } from '@/services/user/api'
  16. import type { ColumnsType } from 'antd/lib/table'
  17. import { formatPermission } from '@/utils/utils'
  18. import RoleMenu from '../System/components/RoleMenu'
  19. import ConnectModal from '../System/components/ConnectModal'
  20. import FormItem from 'antd/lib/form/FormItem'
  21. import { permData } from '../Customer'
  22. import { PieChartOutlined } from '@ant-design/icons'
  23. import { PageContainer } from '@ant-design/pro-layout'
  24. const Statistic = () => {
  25. const { TabPane } = Tabs
  26. const formRef = useRef<FormInstance>(null)
  27. const formRef2 = useRef<FormInstance>(null)
  28. const { initialState } = useModel('@@initialState')
  29. const menuId = useMemo(() => {
  30. return initialState?.menuList?.find(item => item.name === '统计')?.id
  31. }, initialState.menuList)
  32. const [state, setState] = useState({
  33. id: '',
  34. roleStaff: [],
  35. rolePermission: {},
  36. dataPermission: {},
  37. activeKey: ''
  38. })
  39. const onSelect = (id: string) => {
  40. setState({ ...state, id })
  41. }
  42. const { run: tryGetRoleStaffList } = useRequest(
  43. (id: string) => fetchRoleStaffListByRoleId({ id }),
  44. {
  45. manual: true,
  46. onSuccess: result => {
  47. setState({ ...state, roleStaff: result })
  48. }
  49. }
  50. )
  51. const { run: tryGetRolePermissions } = useRequest((id: string) => getRolePermissions({ id }), {
  52. manual: true,
  53. onSuccess: (result: API.GetRolePermissionResultModel) => {
  54. const values = {
  55. client: [],
  56. company: [],
  57. business: [],
  58. ...formatPermission('init', result.permission)
  59. }
  60. if (
  61. values['showSoftware-usage'] ||
  62. values['showInvoice-aggregate'] ||
  63. values['showInvoice-trends'] ||
  64. values['showInvoice-receivables']
  65. ) {
  66. values.showProduct = true
  67. delete values['showSoftware-usage']
  68. delete values['showInvoice-aggregate']
  69. delete values['showInvoice-trends']
  70. delete values['showInvoice-receivables']
  71. }
  72. if (values['showCustomer-additions']) {
  73. values.showCustomer = true
  74. delete values['showCustomer-additions']
  75. }
  76. setState({
  77. ...state,
  78. rolePermission: values,
  79. dataPermission: result.dataPermission ? JSON.parse(result.dataPermission) : null
  80. })
  81. formRef.current?.setFieldsValue({ ...values })
  82. formRef2.current?.setFieldsValue(
  83. result.dataPermission ? JSON.parse(result.dataPermission) : null
  84. )
  85. }
  86. })
  87. const { run: tryDeleteStaff } = useRequest(
  88. (params: API.DeleteStaff) => {
  89. return deleteStaff(params)
  90. },
  91. {
  92. manual: true,
  93. onSuccess: () => {
  94. message.success('移除员工成功')
  95. tryGetRoleStaffList(state.id)
  96. }
  97. }
  98. )
  99. useEffect(() => {
  100. if (state.id) {
  101. tryGetRoleStaffList(state.id)
  102. tryGetRolePermissions(state.id)
  103. }
  104. if (state.activeKey === '2') {
  105. formRef.current?.setFieldsValue({ ...state.rolePermission })
  106. }
  107. if (state.activeKey === '3') {
  108. formRef2.current?.setFieldsValue({ ...state.dataPermission })
  109. }
  110. }, [state.id, state.activeKey])
  111. const columns: ColumnsType<API.RoleStaffListItem> = [
  112. {
  113. title: '用户',
  114. dataIndex: 'username',
  115. width: '15%'
  116. },
  117. {
  118. title: '手机',
  119. dataIndex: 'phone',
  120. width: '20%'
  121. },
  122. {
  123. title: '部门',
  124. dataIndex: 'departmentName',
  125. width: '20%'
  126. },
  127. {
  128. title: '岗位',
  129. dataIndex: 'position',
  130. width: '15%'
  131. },
  132. {
  133. title: '角色',
  134. dataIndex: 'age',
  135. width: '20%'
  136. },
  137. {
  138. title: '操作',
  139. dataIndex: 'opreate',
  140. width: '20%',
  141. render: (_, record) => (
  142. <Popconfirm
  143. title="确认删除吗?"
  144. okText="确认"
  145. cancelText="取消"
  146. onConfirm={() => tryDeleteStaff({ id: state.id, staffId: record.staffId })}>
  147. <div className="pl-2 text-hex-fd3995 cursor-pointer hover:text-hex-e7026e">
  148. <Delete />
  149. </div>
  150. </Popconfirm>
  151. )
  152. }
  153. ]
  154. return (
  155. <PageContainer title={false} breadcrumb={false}>
  156. <div className="h-full w-full flex flex-row">
  157. <RoleMenu menuId={menuId} onSelect={onSelect} itemCount={state.roleStaff?.length || 0} />
  158. <div className={classNames('w-max-3/4', styles.formItemWrap)}>
  159. <div className="ml-8 bg-white p-4 shadow-md shadow-hex-3e2c5a relative">
  160. <div className="absolute right-4 top-4 z-100">
  161. {state.id && (
  162. <ConnectModal
  163. title="关联员工"
  164. dataId={state.id}
  165. postUrl="/role/staff/add"
  166. closeAfterSelect={false}
  167. onReload={() => tryGetRoleStaffList(state.id)}
  168. />
  169. )}
  170. </div>
  171. <Tabs
  172. defaultActiveKey="1"
  173. type="card"
  174. onChange={key => setState({ ...state, activeKey: key })}>
  175. <TabPane tab="员工列表" key="1">
  176. <Table<API.RoleStaffListItem>
  177. dataSource={state.roleStaff}
  178. columns={columns}
  179. rowKey={row => row.staffId}
  180. />
  181. </TabPane>
  182. <TabPane tab="角色权限" key="2">
  183. <div className="ml-4">
  184. {state.id && (
  185. <ProForm
  186. formRef={formRef}
  187. layout="horizontal"
  188. onFinish={async values => {
  189. const newValues = formatPermission('submit', values)
  190. await updateRolePermission({
  191. permission: JSON.stringify(newValues),
  192. id: state.id
  193. })
  194. message.success('设置成功')
  195. }}>
  196. <ProFormSwitch
  197. fieldProps={{
  198. onChange(checked) {
  199. if (!checked) {
  200. formRef.current?.setFieldsValue({
  201. usage: [],
  202. aggregate: [],
  203. trends: [],
  204. additions: [],
  205. receivables: []
  206. })
  207. }
  208. }
  209. }}
  210. name="showProduct"
  211. label={
  212. <span className="flex items-center">
  213. <PieChartOutlined
  214. theme="outline"
  215. className="flex items-baseline mr-1"
  216. />
  217. 产品销售
  218. </span>
  219. }
  220. />
  221. <div className="ml-25px">
  222. <ProFormDependency name={['showProduct']}>
  223. {({ showProduct }) => (
  224. <>
  225. <ProFormCheckbox.Group
  226. name="usage"
  227. label="软件锁用量"
  228. options={[
  229. { value: 'access', label: '查看', disabled: !showProduct }
  230. ]}
  231. />
  232. <ProFormCheckbox.Group
  233. name="aggregate"
  234. label="发票收款入账汇总"
  235. options={[
  236. { value: 'access', label: '查看', disabled: !showProduct }
  237. ]}
  238. />
  239. <ProFormCheckbox.Group
  240. name="trends"
  241. label="发票收款入账趋势"
  242. options={[
  243. { value: 'access', label: '查看', disabled: !showProduct }
  244. ]}
  245. />
  246. <ProFormCheckbox.Group
  247. name="receivables"
  248. label="应收款统计"
  249. options={[
  250. { value: 'access', label: '查看', disabled: !showProduct }
  251. ]}
  252. />
  253. </>
  254. )}
  255. </ProFormDependency>
  256. </div>
  257. <ProFormSwitch
  258. fieldProps={{
  259. onChange(checked) {
  260. if (!checked) {
  261. formRef.current?.setFieldsValue({
  262. additions: []
  263. })
  264. }
  265. }
  266. }}
  267. name="showCustomer"
  268. label={
  269. <span className="flex items-center">
  270. <PieChartOutlined
  271. theme="outline"
  272. className="flex items-baseline mr-1"
  273. />
  274. 客户数据
  275. </span>
  276. }
  277. />
  278. <div className="ml-25px">
  279. <ProFormDependency name={['showCustomer']}>
  280. {({ showCustomer }) => (
  281. <ProFormCheckbox.Group
  282. name="additions"
  283. label="客户新增"
  284. options={[
  285. { value: 'access', label: '查看', disabled: !showCustomer }
  286. ]}
  287. />
  288. )}
  289. </ProFormDependency>
  290. </div>
  291. </ProForm>
  292. )}
  293. </div>
  294. </TabPane>
  295. <TabPane tab="数据权限" key="3">
  296. {state.id && (
  297. <ProForm
  298. formRef={formRef2}
  299. layout="vertical"
  300. onFinish={async values => {
  301. try {
  302. await updatePermDataByRoleId({
  303. id: state.id,
  304. dataPermission: JSON.stringify(values)
  305. })
  306. } catch (error) {
  307. return message.error(error.toString())
  308. }
  309. message.success('设置成功')
  310. return true
  311. }}>
  312. <FormItem name="access" label="产品销售模块可见" required>
  313. <Radio.Group>
  314. <Space direction="vertical">
  315. {permData.map(item => (
  316. <Radio key={item.value} value={item.value}>
  317. {item.label}
  318. </Radio>
  319. ))}
  320. </Space>
  321. </Radio.Group>
  322. </FormItem>
  323. </ProForm>
  324. )}
  325. </TabPane>
  326. </Tabs>
  327. </div>
  328. </div>
  329. </div>
  330. </PageContainer>
  331. )
  332. }
  333. export default Statistic