瀏覽代碼

feat: 前台功能角色权限新增业务列表+数据权限相关内容

feat: 编号规则绑定主体列表不完整版

fix: 111

fix: 加上menu的children

feat: 编号规则未完成

fix: 编号规则同key
outaozhen 2 年之前
父節點
當前提交
9b614f3d65

+ 21 - 1
src/enums/access.ts

@@ -35,7 +35,27 @@ export enum FrontPermission {
   /** 指标库-编辑 */
   ZBK_EDIT = 'zbkEdit',
   /** 财价库-启用 */
-  CJK_ENABLE = 'cjkEnable'
+  CJK_ENABLE = 'cjkEnable',
+  /** 我的业务-启用 */
+  ENABLE_BUSINESS = 'enableBusiness',
+  /** 我的业务-新建业务 */
+  ADD_BUSINESS = 'addBusiness',
+  /** 我的业务-编辑业务 */
+  EDIT_BUSINESS = 'editBusiness',
+  /** 我的业务-删除业务 */
+  DEL_BUSINESS = 'delBusiness'
+}
+
+/** 前台-角色数据权限枚举 */
+export enum DataPermission {
+  /** 全部 */
+  ALL = 'all',
+  /** 仅本人 */
+  ONES = 'ones',
+  /** 本部门 */
+  DEPARTMENT = 'department',
+  /** 本部门及下属部门 */
+  DEPARTMENTALL = 'departmentAll'
 }
 
 /** 后台-角色权限枚举 */

+ 32 - 0
src/pages/Business/RuleCode/components/LeftMenu/index.tsx

@@ -0,0 +1,32 @@
+import { Menu } from 'antd'
+import React from 'react'
+import '@/pages/Schema/Base/components/LeftMenu/index.less'
+
+type LeftMenuProps = {
+  title?: string
+  options: { label: string; value: string }[]
+  onChange: (key: string) => void
+  value: string
+}
+
+const itemsChild = [
+  { label: '预算审核', key: 'yuS' },
+  { label: '结算审核', key: 'jieS' },
+  { label: '决算审核', key: 'jueS' }
+]
+
+const LeftMenu: React.FC<LeftMenuProps> = ({ title = '业务主体列表', options, onChange, value }) => {
+  return (
+    <div className="w-216px rounded-20px" style={{ height: 'calc(100vh - 122px)', background: '#ffffff' }}>
+      <div className="p-5 text-16px text-opacity-85 menu-title">{title}</div>
+      <Menu
+        defaultSelectedKeys={[value]}
+        onSelect={({ key }) => onChange(key)}
+        mode="inline"
+        items={options.map(item => ({ label: item.name, key: item.ID, type: 'group', children: itemsChild }))}
+      />
+    </div>
+  )
+}
+
+export default LeftMenu

+ 177 - 149
src/pages/Business/RuleCode/index.tsx

@@ -5,6 +5,8 @@ import { TweenOneGroup } from 'rc-tween-one'
 import { createUid, dayjsFormat } from '@/utils/util'
 import { queryRuleCodeList, updateRuleCode } from '@/services/api/business'
 import { useRequest } from '@umijs/max'
+import LeftMenu from './components/LeftMenu'
+import { querySubject } from '@/services/api/subject'
 
 const { TabPane } = Tabs
 const contentHeight = document.body.clientHeight - 122
@@ -90,8 +92,11 @@ const RulesCode = () => {
     approvalTypeValue: '01',
     digits: '5',
     autoCode: '00001',
-    fixedText: ''
+    fixedText: '',
+    subjectList: '',
+    subjectID: ''
   })
+  console.log(state.subjectID)
 
   const [ruleArr, setRuleArr] = useState<ruleOption[]>([])
 
@@ -121,13 +126,16 @@ const RulesCode = () => {
     }
   }
 
-  const { run: tryRuleCode } = useRequest(() => queryRuleCodeList({ tab: state.tabId }), {
-    manual: true,
-    onSuccess: result => {
-      setRuleArr(result.rules)
-      setState({ ...state, connector: result.connector })
+  const { run: tryRuleCode } = useRequest(
+    () => queryRuleCodeList({ tab: state.tabId, subjectID: state.subjectID }),
+    {
+      manual: true,
+      onSuccess: result => {
+        setRuleArr(result.rules)
+        setState({ ...state, connector: result.connector })
+      }
     }
-  })
+  )
 
   const { run: tryUpdateRuleCode } = useRequest(updateRuleCode, {
     manual: true,
@@ -137,14 +145,16 @@ const RulesCode = () => {
     }
   })
 
+  const { run: trySubjectList } = useRequest(() => querySubject(), {
+    manual: true,
+    onSuccess: result => {
+      setState({ ...state, subjectList: result.items })
+    }
+  })
+
   // 只需首次加载执行一次
   useEffect(() => {
-    function fectTryRuleCode() {
-      if (state.tabId === 'yuS') {
-        tryRuleCode()
-      }
-    }
-    fectTryRuleCode()
+    trySubjectList()
   }, [])
 
   // 添加规则
@@ -176,150 +186,168 @@ const RulesCode = () => {
     setRuleArr([...ruleArr, rule])
   }
 
-  const renderExtraTabContent = () => (
-    <Button
-      type="primary"
-      onClick={() => {
-        tryUpdateRuleCode({
-          tab: state.tabId,
-          rules: ruleArr.map(item => ({
-            type: item.type,
-            value: item.value,
-            label: item.label,
-            id: item.id
-          })),
-          connector: state.connector
-        })
-      }}>
-      保存
-    </Button>
-  )
+  const renderExtraTabContent = () =>
+    state.subjectID ? (
+      <Button
+        type="primary"
+        onClick={() => {
+          tryUpdateRuleCode({
+            tab: state.tabId,
+            rules: ruleArr.map(item => ({
+              type: item.type,
+              value: item.value,
+              label: item.label,
+              id: item.id
+            })),
+            connector: state.connector
+          })
+        }}>
+        保存
+      </Button>
+    ) : null
   return (
     <PageContainer title={false}>
-      <div className="p-4 bg-white" style={{ height: `${contentHeight}px` }}>
-        <Tabs
-          defaultActiveKey="yuS"
-          tabBarExtraContent={renderExtraTabContent()}
-          onChange={key => {
-            setState({
-              ...state,
-              tabId: key
-            })
-          }}>
-          <TabPane key="yuS" tab="预算编号规则">
-            <div className="flex items-center mb-3">
-              <div className="w-100px text-right mr-1">编号预览:</div>
-              <div className="min-h-32px leading-32px">
-                {ruleArr?.map(item => item?.value).join(state.connector)}
-              </div>
-            </div>
-            <div className="flex items-center mb-3">
-              <div className="w-100px text-right mr-1">编号规则:</div>
-              <div className="w-2/5 min-h-32px border-1 border-[#d9d9d9] border-solid rounded-2px pt-1 px-1">
-                <RenderTags ruleArr={ruleArr} setRuleArr={setRuleArr} />
-              </div>
-            </div>
-            <div className="flex items-center mb-3">
-              <div className="w-100px text-right mr-1">连接符:</div>
-              <div>
-                <Select
-                  style={{ width: 160 }}
-                  options={connectorOption}
-                  defaultValue={state.connector}
-                  onSelect={value =>
-                    setState({
-                      ...state,
-                      connector: value
-                    })
-                  }
-                />
-              </div>
-            </div>
-            <div className="flex items-center mb-3">
-              <div className="w-100px text-right mr-1">规则:</div>
-              <div>
-                <Select
-                  style={{ width: 160 }}
-                  options={ruleOption}
-                  defaultValue={state.ruleTypeValue}
-                  onSelect={value =>
-                    setState({
-                      ...state,
-                      ruleTypeValue: value
-                    })
-                  }
-                />
-              </div>
-              {state.ruleTypeValue === RuleOptionEunm.APPROVALTYPE ? (
-                <div className="flex items-center">
-                  <div className="w-100px text-right mr-1">类型:</div>
-                  <div>
-                    <Select
-                      style={{ width: 160 }}
-                      options={approvalTypeOption}
-                      defaultValue={state.approvalTypeValue}
-                      onSelect={value =>
-                        setState({
-                          ...state,
-                          approvalTypeValue: value
-                        })
-                      }
-                    />
+      <div className="h-full w-full flex flex-row">
+        {state.subjectList.length ? (
+          <LeftMenu
+            title="业务主体列表"
+            options={state.subjectList}
+            value={state.subjectID}
+            onChange={key => setState({ ...state, subjectID: key })}
+          />
+        ) : null}
+
+        <div className="w-6/7 ml-8 p-4 bg-white">
+          <Tabs
+            defaultActiveKey="yuS"
+            tabBarExtraContent={renderExtraTabContent()}
+            onChange={key => {
+              setState({
+                ...state,
+                tabId: key
+              })
+            }}>
+            <TabPane key="yuS" tab="预算编号规则">
+              {state.subjectID ? (
+                <>
+                  <div className="flex items-center mb-3">
+                    <div className="w-100px text-right mr-1">编号预览:</div>
+                    <div className="min-h-32px leading-32px">
+                      {ruleArr?.map(item => item?.value).join(state.connector)}
+                    </div>
                   </div>
-                </div>
-              ) : null}
-              {state.ruleTypeValue === RuleOptionEunm.AUTOCODE ? (
-                <div className="flex items-center">
-                  <div className="w-100px text-right mr-1">数位:</div>
-                  <div>
-                    <InputNumber
-                      style={{ width: 160 }}
-                      defaultValue={state.digits}
-                      min={1}
-                      onChange={value => digitHandler(value)}
-                    />
+                  <div className="flex items-center mb-3">
+                    <div className="w-100px text-right mr-1">编号规则:</div>
+                    <div className="w-2/5 min-h-32px border-1 border-[#d9d9d9] border-solid rounded-2px pt-1 px-1">
+                      <RenderTags ruleArr={ruleArr} setRuleArr={setRuleArr} />
+                    </div>
                   </div>
-                </div>
-              ) : null}
-              {state.ruleTypeValue === RuleOptionEunm.FIXEDTEXT ? (
-                <div className="flex items-center">
-                  <div className="w-100px text-right mr-1">规则:</div>
-                  <div>
-                    <Input
-                      style={{ width: 160 }}
-                      onChange={e =>
-                        setState({
-                          ...state,
-                          fixedText: e.target.value
-                        })
-                      }
-                    />
+                  <div className="flex items-center mb-3">
+                    <div className="w-100px text-right mr-1">连接符:</div>
+                    <div>
+                      <Select
+                        style={{ width: 160 }}
+                        options={connectorOption}
+                        defaultValue={state.connector}
+                        onSelect={value =>
+                          setState({
+                            ...state,
+                            connector: value
+                          })
+                        }
+                      />
+                    </div>
                   </div>
-                </div>
-              ) : null}
-              {state.ruleTypeValue === RuleOptionEunm.AUTOCODE ? (
-                <div className="flex items-center">
-                  <div className="w-100px text-right mr-1">起始编号:</div>
-                  <div>
-                    <Input
-                      type="number"
-                      value={state.autoCode}
-                      onChange={e => autoCodeHandler(e)}
-                      defaultValue={state.autoCode}
-                      style={{ width: 160 }}
-                    />
+                  <div className="flex items-center mb-3">
+                    <div className="w-100px text-right mr-1">规则:</div>
+                    <div>
+                      <Select
+                        style={{ width: 160 }}
+                        options={ruleOption}
+                        defaultValue={state.ruleTypeValue}
+                        onSelect={value =>
+                          setState({
+                            ...state,
+                            ruleTypeValue: value
+                          })
+                        }
+                      />
+                    </div>
+                    {state.ruleTypeValue === RuleOptionEunm.APPROVALTYPE ? (
+                      <div className="flex items-center">
+                        <div className="w-100px text-right mr-1">类型:</div>
+                        <div>
+                          <Select
+                            style={{ width: 160 }}
+                            options={approvalTypeOption}
+                            defaultValue={state.approvalTypeValue}
+                            onSelect={value =>
+                              setState({
+                                ...state,
+                                approvalTypeValue: value
+                              })
+                            }
+                          />
+                        </div>
+                      </div>
+                    ) : null}
+                    {state.ruleTypeValue === RuleOptionEunm.AUTOCODE ? (
+                      <div className="flex items-center">
+                        <div className="w-100px text-right mr-1">数位:</div>
+                        <div>
+                          <InputNumber
+                            style={{ width: 160 }}
+                            defaultValue={state.digits}
+                            min={1}
+                            onChange={value => digitHandler(value)}
+                          />
+                        </div>
+                      </div>
+                    ) : null}
+                    {state.ruleTypeValue === RuleOptionEunm.FIXEDTEXT ? (
+                      <div className="flex items-center">
+                        <div className="w-100px text-right mr-1">规则:</div>
+                        <div>
+                          <Input
+                            style={{ width: 160 }}
+                            onChange={e =>
+                              setState({
+                                ...state,
+                                fixedText: e.target.value
+                              })
+                            }
+                          />
+                        </div>
+                      </div>
+                    ) : null}
+                    {state.ruleTypeValue === RuleOptionEunm.AUTOCODE ? (
+                      <div className="flex items-center">
+                        <div className="w-100px text-right mr-1">起始编号:</div>
+                        <div>
+                          <Input
+                            type="number"
+                            value={state.autoCode}
+                            onChange={e => autoCodeHandler(e)}
+                            defaultValue={state.autoCode}
+                            style={{ width: 160 }}
+                          />
+                        </div>
+                      </div>
+                    ) : null}
+                    <div className="ml-4">
+                      <Button type="primary" ghost onClick={() => addRule()}>
+                        添加
+                      </Button>
+                    </div>
                   </div>
-                </div>
+                </>
               ) : null}
-              <div className="ml-4">
-                <Button type="primary" ghost onClick={() => addRule()}>
-                  添加
-                </Button>
-              </div>
-            </div>
-          </TabPane>
-        </Tabs>
+            </TabPane>
+          </Tabs>
+        </div>
       </div>
+
+      <div className="p-4 bg-white" style={{ height: `${contentHeight}px` }} />
     </PageContainer>
   )
 }

+ 69 - 0
src/pages/Permission/FrontRole/components/DataTabs/index.tsx

@@ -0,0 +1,69 @@
+import { queryRoleDetailByID, setRolePermission } from '@/services/permission'
+import { useRequest } from '@umijs/max'
+import { Affix, Button, message, Radio, Space, Spin } from 'antd'
+import React, { useState } from 'react'
+import type { RadioChangeEvent } from 'antd'
+import { DataPermission } from '@/enums/access'
+import { operationType } from '../PermTabs'
+
+const DataTabs = ({ currentPermData: { ID } }) => {
+  const [state, setState] = useState({
+    value: DataPermission.ONES
+  })
+
+  const { loading } = useRequest(() => queryRoleDetailByID({ ID }), {
+    refreshDeps: [ID],
+    onSuccess: result => {
+      setState({ ...state, value: result.dataPermission })
+    }
+  })
+
+  const { run: trySetRolePermission, loading: submitStauts } = useRequest(
+    (params: API.RolePermissionParams) => setRolePermission(params),
+    {
+      manual: true,
+      onSuccess: () => {
+        message.success('设置成功')
+      }
+    }
+  )
+
+  const handleSubmit = () => {
+    const params = {
+      ID,
+      operation: operationType.DATA,
+      dataPermission: state.value
+    }
+    trySetRolePermission(params)
+  }
+
+  const onChange = (e: RadioChangeEvent) => {
+    setState({ ...state, value: e.target.value })
+  }
+
+  return (
+    <>
+      <div style={{ height: 'calc(100vh - 250px)' }} className="overflow-y-auto">
+        <Spin spinning={loading}>
+          <div className="my-2">
+            <Radio.Group onChange={onChange} value={state.value} defaultChecked={state.value}>
+              <Space direction="vertical">
+                <Radio value={DataPermission.ALL}>全部</Radio>
+                <Radio value={DataPermission.DEPARTMENT}>本部门</Radio>
+                <Radio value={DataPermission.DEPARTMENTALL}>本部门及下属部门</Radio>
+                <Radio value={DataPermission.ONES}>仅本人</Radio>
+              </Space>
+            </Radio.Group>
+          </div>
+        </Spin>
+      </div>
+      <Affix offsetBottom={10}>
+        <Button type="primary" onClick={handleSubmit} loading={submitStauts}>
+          提交
+        </Button>
+      </Affix>
+    </>
+  )
+}
+
+export default DataTabs

+ 38 - 1
src/pages/Permission/FrontRole/components/PermTabs/index.tsx

@@ -4,6 +4,14 @@ import { Card, Checkbox, Button, message, Spin, Affix } from 'antd'
 import { queryRoleDetailByID, setRolePermission } from '@/services/permission'
 import { FrontPermission } from '@/enums/access'
 
+/** 权限参数枚举 */
+export enum operationType {
+  /** 功能权限 */
+  FRONT = 'front',
+  /** 数据权限 */
+  DATA = 'data'
+}
+
 type PermTabsProps = {
   currentPermData: {
     ID: string
@@ -49,7 +57,7 @@ const PermTabs: React.FC<PermTabsProps> = ({ currentPermData: { ID } }) => {
   const handleSubmit = () => {
     const params = {
       ID,
-      operation: state.activeTab,
+      operation: operationType.FRONT,
       frontPermission: filterPermission(permission)
     }
     trySetRolePermission(params)
@@ -70,6 +78,35 @@ const PermTabs: React.FC<PermTabsProps> = ({ currentPermData: { ID } }) => {
             </Card>
           </div>
           <div className="shadow-md mb-4">
+            <Card size="small" type="inner" title="业务列表">
+              <div>
+                <h4>我的业务</h4>
+                <div className="my-2">
+                  <Checkbox
+                    onChange={e => handleFrontOnchange(e.target.checked, FrontPermission.ENABLE_BUSINESS)}
+                    checked={permission.includes(FrontPermission.ENABLE_BUSINESS)}>
+                    启用
+                  </Checkbox>
+                  <Checkbox
+                    onChange={e => handleFrontOnchange(e.target.checked, FrontPermission.ADD_BUSINESS)}
+                    checked={permission.includes(FrontPermission.ADD_BUSINESS)}>
+                    新建业务
+                  </Checkbox>
+                  <Checkbox
+                    onChange={e => handleFrontOnchange(e.target.checked, FrontPermission.EDIT_BUSINESS)}
+                    checked={permission.includes(FrontPermission.EDIT_BUSINESS)}>
+                    编辑业务
+                  </Checkbox>
+                  <Checkbox
+                    onChange={e => handleFrontOnchange(e.target.checked, FrontPermission.DEL_BUSINESS)}
+                    checked={permission.includes(FrontPermission.DEL_BUSINESS)}>
+                    删除业务
+                  </Checkbox>
+                </div>
+              </div>
+            </Card>
+          </div>
+          <div className="shadow-md mb-4">
             <Card size="small" type="inner" title="项目列表">
               <div>
                 <h4>我的项目</h4>

+ 8 - 0
src/pages/Permission/FrontRole/index.tsx

@@ -8,6 +8,7 @@ import ConnectModal from './components/ConnectModal'
 import RoleLeftMenu, { RoleType } from './components/RoleLeftMenu'
 import PermTabs from './components/PermTabs'
 import type { ColumnsType } from 'antd/lib/table'
+import DataTabs from './components/DataTabs'
 const { TabPane } = Tabs
 
 const Role = () => {
@@ -156,6 +157,13 @@ const Role = () => {
                 }}
               />
             </TabPane>
+            <TabPane tab="数据权限" key="3">
+              <DataTabs
+                currentPermData={{
+                  ID: state.currentRoleID
+                }}
+              />
+            </TabPane>
           </Tabs>
         </div>
       </div>

+ 5 - 4
src/pages/Schema/Base/components/LeftMenu/index.tsx

@@ -11,15 +11,16 @@ type LeftMenuProps = {
 
 const LeftMenu: React.FC<LeftMenuProps> = ({ title = '栏目/功能', options, onChange, value }) => {
   return (
-    <div
-      className="w-216px rounded-20px"
-      style={{ height: 'calc(100vh - 122px)', background: '#ffffff' }}>
+    <div className="w-216px rounded-20px" style={{ height: 'calc(100vh - 122px)', background: '#ffffff' }}>
       <div className="p-5 text-16px text-opacity-85 menu-title">{title}</div>
       <Menu
         defaultSelectedKeys={[value]}
         onSelect={({ key }) => onChange(key)}
         mode="inline"
-        items={options.map(item => ({ label: item.label, key: item.value }))}
+        items={options.map(item => ({
+          label: item.label,
+          key: item.value
+        }))}
       />
     </div>
   )

+ 9 - 1
src/pages/System/Account/index.tsx

@@ -22,7 +22,9 @@ const Account: React.FC = () => {
   const tRef = useRef<ActionType>(null)
   const formRef = useRef<ProFormInstance>(null)
   const [state, setState] = useState({
-    params: {},
+    params: {
+      search: null
+    },
     visible: false,
     modalType: 'add',
     modalVisible: false
@@ -137,6 +139,7 @@ const Account: React.FC = () => {
           <ProTable
             rowKey="ID"
             actionRef={tRef}
+            params={state.params}
             columns={columns}
             search={false}
             scroll={{ y: document.body.clientHeight - 315 }}
@@ -151,6 +154,11 @@ const Account: React.FC = () => {
               }
             }}
             toolbar={{
+              search: {
+                onSearch: val => setState({ ...state, params: { ...state.params, search: val } }),
+                style: { width: '250px' },
+                placeholder: '请输入姓名'
+              },
               actions: [
                 <>
                   <Button