This commit is contained in:
ylj20011123 2025-10-17 18:27:20 +08:00
parent 651263dec0
commit e90dabf9fa
5 changed files with 102171 additions and 99496 deletions

View File

@ -1290,6 +1290,11 @@ export default [
name: 'setting',
icon: 'setting',
routes: [
{
path: 'batchAuthorization',
name: 'batchAuthorization',
component: './Setting/batchAuthorization/index',
},
{
path: 'OperationLog',
name: 'OperationLog',

View File

@ -0,0 +1,521 @@
import { connect } from "umi";
import type { CurrentUser } from "umi";
import type { ConnectState } from "@/models/connect";
import React, { useEffect, useRef, useState } from "react";
import ProCard from "@ant-design/pro-card";
import { EllipsisOutlined, MenuFoldOutlined } from "@ant-design/icons";
import type { FormInstance } from "antd";
import { Button, message, Modal, Popconfirm, Row, Space, Spin, Tree } from "antd";
import useRequest from "@ahooksjs/use-request";
import { getServerpartTree } from "@/services/options";
import type { ActionType } from "@ant-design/pro-table";
import ProTable from "@ant-design/pro-table";
import LeftSelectTree from "@/pages/reports/settlementAccount/component/leftSelectTree";
import PageTitleBox from "@/components/PageTitleBox";
import Draggable from "react-draggable";
import { getUserList, getUserTypeTree } from "../Users/service";
import { handleGetSERVERPARTList, handleModifyUserCityAuthority } from "./service";
import ProForm, { ProFormCheckbox } from "@ant-design/pro-form";
const BatchAuthorization: React.FC<{ currentUser: CurrentUser }> = (props) => {
const { currentUser } = props
const actionRef = useRef<ActionType>();
const modalTableRef = useRef<ActionType>();
const formRef = useRef<FormInstance>();
const confirmModalFormRef = useRef<FormInstance>();
const [reqDetailList, setReqDetailList] = useState<any>(); // 合计项数据源
const [printOut, setPrintOut] = useState<any>(); // 打印数据的内容
const [collapsible, setCollapsible] = useState<boolean>(false)
const { confirm } = Modal;
// 弹出框拖动效果
const [bounds, setBounds] = useState<{ left: number, right: number, top: number, bottom: number }>() // 移动的位置
const [disabled, setDraggleDisabled] = useState<boolean>() // 是否拖动
const draggleRef = React.createRef<any>()
const onDraggaleStart = (event, uiData) => {
const { clientWidth, clientHeight } = window.document.documentElement;
const targetRect = draggleRef.current?.getBoundingClientRect();
if (!targetRect) {
return;
}
setBounds({
left: -targetRect.left + uiData.x,
right: clientWidth - (targetRect.right - uiData.x),
top: -targetRect.top + uiData.y,
bottom: clientHeight - (targetRect.bottom - uiData.y),
});
};
const { run: getUserTypeMenu, loading: typeLoading, data: userTypeTree } = useRequest((type) => getUserTypeTree({ UserTypePattern: tableTab, ShowStatus: true }))
const leftTab = [{ key: `1000`, name: '业主' }, { key: `4000`, name: '供应商' }, { key: `2000`, name: '商户' }, { key: `3000`, name: '游客' }, { key: `9000`, name: '内部' }]
const ueserCloudTab = currentUser?.UserPattern === 9000 ? leftTab : currentUser?.UserPattern === 1000 ? [{ key: `1000`, name: '业主' }, { key: `4000`, name: '供应商' }] : leftTab.filter(n => n.key === `${currentUser?.UserPattern}`)
// 树相关的属性和方法
const [selectedId, setSelectedId] = useState<string>()
// 查询的条件
const [searchParams, setSearchParams] = useState<any>()
// 添加人员
const [showModal, setShowModal] = useState<any>()
// 点击确认的加载效果
const [confirmLoading, setConfirmLoading] = useState<boolean>(false)
// 选择行的数据
const [currentRow, setCurrentRow] = useState<any>()
// 商户还是业主
const [tableTab, setTableTab] = useState<string>('1000')
const [userTypeId, setUserTypeId] = useState<Record<number, []>>();
// 拿到服务区对应的 code 自己搞个枚举
const [serverpartCodeObj, setServerPartCodeObj] = useState<any>()
// 确认要同步服务区的悬浮框
const [confirmModal, setConfirmModal] = useState<boolean>(false)
// 判断是批量删除还是批量同步
const [updateType, setUpdateType] = useState<number>(0)
// 选择的用户id列表
const [selectedRowKeysList, setSelectedRowKeysList] = useState<any>()
// 选择的用户信息列表
const [selectedRowsInfoList, setSelectedRowsInfoList] = useState<any>()
// 这次显示的全部服务区code
const [allServerPartCodeList, setAllServerPartCodeList] = useState<any>()
// 选择的要移除用户id列表
const [selectedDeleteRowKeysList, setSelectedDeleteRowKeysList] = useState<any>()
// 选择的要移除用户信息列表
const [selectedDeleteRowsInfoList, setSelectedDeleteRowsInfoList] = useState<any>()
const columns: any = [
{
title: "查询内容",
dataIndex: "searchValue",
hideInTable: true
},
{
title: '账号部门',
dataIndex: 'USERTYPE_ID',
width: 150,
hideInSearch: true,
hideInDescriptions: true,
valueType: "treeSelect",
fieldProps: {
options: userTypeTree,
},
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "USER_NAME",
width: 150,
hideInSearch: true,
ellipsis: true
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "USER_PASSPORT",
width: 150,
hideInSearch: true,
ellipsis: true
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "USER_MOBILEPHONE",
width: 150,
hideInSearch: true,
ellipsis: true
}
// {
// title: <div style={{ textAlign: 'center' }}>服务区权限</div>,
// dataIndex: "ServerpartShopList",
// width: 150,
// hideInSearch: true,
// ellipsis: true
// }
]
useEffect(async () => {
// const req: any = {
// SearchParameter:{
// },
// PageIndex: 1,
// PageSize: 999999,
// Province_Code: currentUser?.ProvinceCode
// }
// const data = await handleGetSERVERPARTList(req)
// console.log('handleGetSERVERPARTListhandleGetSERVERPARTList', data);
}, [])
return (
<div ref={(el) => {
// 打印报表
if (!reqDetailList || reqDetailList.length === 0) return;
setPrintOut(el);
}} >
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,
paddingBottom: 0,
paddingRight: 0
}}>
<ProTable
actionRef={actionRef}
formRef={formRef}
columns={columns}
rowKey="USER_ID"
bordered
expandable={{
expandRowByClick: true
}}
scroll={{ x: "100%", y: "calc(100vh - 430px)" }}
headerTitle={<PageTitleBox props={props} />} // 列表表头
search={{ span: 6 }}
request={async (params) => {
if (!selectedId) {
return
}
console.log('selectedIdselectedIdselectedId', selectedId);
setSearchParams(params)
const req: any = {
USER_STATUS: 1,
current: 1,
pageSize: 999999,
USER_PROVINCE: currentUser?.ProvinceCode,
keyWord: {
Key: "USER_NAME",
Value: params?.searchValue
}
}
const data = await getUserList(req)
console.log('datadatadatadatadata', data);
if (data.data && data.data.length > 0) {
return { data: data.data, success: true }
}
return { data: [], success: true }
}}
toolbar={{
actions: [
<Button type={'primary'} danger onClick={() => {
if (selectedDeleteRowKeysList && selectedDeleteRowKeysList.length > 0) {
setUpdateType(2)
setConfirmModal(true)
} else {
message.error('请选择要移除服务区权限的用户!')
}
}}></Button>,
<Button type={"primary"} onClick={() => {
if (!selectedId) {
message.error('请先选择服务区!')
return
}
setShowModal(true)
}}></Button>
]
}}
rowSelection={{
onChange: (selectedRowKeys, selectedRows) => {
console.log('selectedRowKeysselectedRowKeys', selectedRowKeys);
setSelectedDeleteRowKeysList(selectedRowKeys)
setSelectedDeleteRowsInfoList(selectedRows)
},
}}
/>
</div>
</div>
<Modal
title={<div className="batchAuthorization"></div>}
destroyOnClose={true}
width={1400}
bodyStyle={{
height: '700px', // 你可以根据需要调整高度
overflowY: 'auto',
}}
open={showModal}
confirmLoading={confirmLoading}
afterClose={() => {
formRef.current?.resetFields();
setCurrentRow(undefined);
}}
onCancel={() => {
setShowModal(false)
setUpdateType(0)
}}
footer={<div style={{ width: '100%', display: 'flex', boxSizing: 'border-box', padding: '0 8px', justifyContent: 'flex-end' }}>
<Button onClick={() => {
formRef.current?.resetFields();
setCurrentRow(undefined);
setShowModal(false)
setSelectedRowKeysList([])
setSelectedRowsInfoList([])
}}></Button>
<Button type={"primary"} style={{ marginLeft: '8px' }} onClick={() => {
if (selectedRowKeysList && selectedRowKeysList.length > 0) {
setUpdateType(1)
setConfirmModal(true)
} else {
message.error('请选择变更人员!')
}
}}></Button>
{/* <Popconfirm
title="?"
onConfirm={async (e: any) => {
}}
onCancel={(e: any) => {
}}
>
<Button type={"primary"} style={{ marginLeft: '8px' }}></Button>
</Popconfirm> */}
</div>}
modalRender={(modal) => {
return <Draggable
disabled={disabled}
bounds={bounds}
onStart={(event, uiData) => onDraggaleStart(event, uiData)}
handle={'.batchAuthorization'}
>
<div ref={draggleRef}>{modal}</div>
</Draggable>
}}
>
<ProCard split="vertical" style={{ backgroundColor: '#fff' }}>
{/* 左侧树筛选 */}
<ProCard
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20 }}
// extra={<MenuFoldOutlined onClick={() => { setCollapsible(!collapsible) }} />}
colSpan={!collapsible ? "360px" : "60px"}
// title={!collapsible ? "请选择账号部门" : ""}
// headerBordered
// collapsed={collapsible}
tabs={{
activeKey: tableTab,
onChange: (key) => {
console.log('key', key)
setTableTab(key as string);
getUserTypeMenu(key)
},
}}
>
{ueserCloudTab.map(n => {
return <ProCard.TabPane key={n.key} tab={n.name}>
<Tree
checkable
style={{ padding: '20px' }}
// eslint-disable-next-line no-nested-ternary
treeData={!typeLoading ? (currentUser?.UserPattern === 9000 ? userTypeTree : userTypeTree[0]?.children) : []}
fieldNames={{
title: "label",
// key: "USERTYPE_ID"
}}
blockNode
// onSelect={onSelect}
onCheck={(checkedKeys: React.Key[] | any) => {
setUserTypeId({ [n.key]: checkedKeys })
if (actionRef.current) {
// actionRef.current?.reset()
actionRef.current?.reload()
}
}}
>
</Tree>
</ProCard.TabPane>
})}
</ProCard>
{/* 右侧表格主体 */}
<ProCard bodyStyle={{ paddingTop: 0, paddingBottom: 0, paddingRight: 0 }}>
<ProTable
headerTitle="账号管理"
rowKey="USER_ID"
actionRef={actionRef}
request={async (params, sorter) => {
console.log('params', params);
const sortstr = Object.keys(sorter).map(n => {
const value = sorter[n]
return value ? `${n} ${value.replace('end', '')}` : ''
})
const data = await getUserList({
...params,
USER_STATUS: 1,
USER_PATTERN: tableTab,
UserTypeIds: userTypeId && userTypeId[tableTab] ? userTypeId[tableTab].toString() : '',
SortStr: sortstr ? sortstr.toString() : 'USER_INDEX',
keyWord: { key: "USER_PASSPORT,USER_NAME,USER_MOBILEPHONE,PROVINCE_UNIT,BUSINESSMAN_NAME", value: params.searchValue }, // 关键词查询
})
return data
}}
onReset={() => {
actionRef.current?.reload()
}}
params={{ USER_PATTERN: tableTab }}
columns={columns}
pagination={{ defaultPageSize: 10 }}
rowSelection={{
onChange: (selectedRowKeys, selectedRows) => {
setSelectedRowKeysList(selectedRowKeys)
setSelectedRowsInfoList(selectedRows)
},
}}
/>
</ProCard>
</ProCard>
</Modal>
<Modal
title={<div className="batchAuthorization"></div>}
destroyOnClose={true}
width={500}
// bodyStyle={{
// height: '700px', // 你可以根据需要调整高度
// overflowY: 'auto',
// }}
open={confirmModal}
confirmLoading={confirmLoading}
onCancel={() => {
setConfirmLoading(false)
setConfirmModal(false)
setUpdateType(0)
}}
onOk={() => {
confirmModalFormRef?.current?.validateFields().then(() => {
confirmModalFormRef?.current?.submit();
})
}}
>
<ProForm
formRef={confirmModalFormRef}
submitter={false}
onFinish={async (values) => {
console.log('valuesvalues', values);
console.log('selectedRowKeysListselectedRowKeysListselectedRowKeysList', selectedRowKeysList);
console.log('selectedRowsInfoListselectedRowsInfoListselectedRowsInfoList', selectedRowsInfoList);
let personList: string = ''
if (updateType === 1) {
if (selectedRowsInfoList && selectedRowsInfoList.length > 0) {
selectedRowsInfoList.forEach((item: any) => {
if (personList) {
personList += `,${item.USER_NAME}`
} else {
personList = item.USER_NAME
}
})
}
} else if (updateType === 2) {
if (selectedDeleteRowsInfoList && selectedDeleteRowsInfoList.length > 0) {
selectedDeleteRowsInfoList.forEach((item: any) => {
if (personList) {
personList += `,${item.USER_NAME}`
} else {
personList = item.USER_NAME
}
})
}
}
let serverPartStr: string = ''
if (allServerPartCodeList && allServerPartCodeList.length > 0) {
allServerPartCodeList.forEach((item: any) => {
if (values.selectServerPartCode.indexOf(item.value) !== -1) {
if (serverPartStr) {
serverPartStr += `,${item.label}`
} else {
serverPartStr = item.label
}
}
})
}
console.log('personListpersonListpersonList', personList);
console.log('serverPartStrserverPartStrserverPartStr', serverPartStr);
confirm({
title: `确认给【${personList}${updateType === 1 ? '同步' : updateType === 2 ? '移除' : ''}${serverPartStr}】权限吗?`,
async onOk() {
const req: any = {
AddAuthority: updateType === 1 ? true : updateType === 2 ? false : '',
UserIdList: updateType === 1 ? selectedRowKeysList : updateType === 2 ? selectedDeleteRowKeysList : '',
CityAuthorityList: values.selectServerPartCode
}
const data = await handleModifyUserCityAuthority(req)
console.log('datadatadatadata', data);
if (data.Result_Code === 100) {
message.success(data.Result_Desc)
confirmModalFormRef.current?.resetFields();
setConfirmLoading(false)
setConfirmModal(false)
setUpdateType(0)
setCurrentRow(undefined);
setShowModal(false)
setSelectedRowKeysList([])
setSelectedRowsInfoList([])
actionRef.current?.reload()
} else {
message.error(data.Result_Desc)
}
}
});
}}
>
<ProFormCheckbox.Group
label={`选择需要${updateType === 1 ? '同步' : updateType === 2 ? '移除' : ''}的服务区`}
name={'selectServerPartCode'}
rules={[
{
required: true,
message: `请选择需要${updateType === 1 ? '同步' : updateType === 2 ? '移除' : ''}的服务区`
}
]}
request={async () => {
const req: any = {
SearchParameter: {
SERVERPART_IDS: selectedId
},
PageIndex: 1,
PageSize: 999999,
}
const data = await handleGetSERVERPARTList(req)
if (data && data.length > 0) {
let list: any = []
data.forEach((item: any) => {
list.push({ label: item.SERVERPART_NAME, value: item.SERVERPART_CODE })
})
console.log('listlistlistlist', list);
setAllServerPartCodeList(list)
return list
} else {
return []
}
}}
>
</ProFormCheckbox.Group>
<Row>
<Button style={{ marginRight: '16px' }} onClick={() => {
let res: any = []
if (allServerPartCodeList && allServerPartCodeList.length > 0) {
allServerPartCodeList.forEach((item: any) => {
res.push(item.value)
})
}
confirmModalFormRef.current?.setFieldsValue({ selectServerPartCode: res })
}}></Button>
</Row>
</ProForm>
</Modal>
</div >
)
}
export default connect(({ user }: ConnectState) => ({
currentUser: user.currentUser
}))(BatchAuthorization);

View File

@ -0,0 +1,34 @@
import requestEncryption from "@/utils/requestEncryption"
import request from "@/utils/request"
// 批量更新用户服务区权限
export async function handleModifyUserCityAuthority(params?: any) {
const data = await request('/FrameWork/ModifyUserCityAuthority', {
method: 'POST',
data: {
...params,
requestEncryption: true
},
})
if (data.Result_Code !== 100) {
return data
}
return data
}
// 获取服务区站点列表
export async function handleGetSERVERPARTList(params?: any) {
const data = await request('/BaseInfo/GetSERVERPARTList', {
method: 'POST',
data: {
...params
},
})
if (data.Result_Code !== 100) {
return data
}
return data.Result_Data.List
}

File diff suppressed because it is too large Load Diff

View File

@ -422,11 +422,12 @@ const scenicSpotConfig: React.FC<{ currentUser: CurrentUser | undefined }> = (pr
})
let obj: any = {
status0,
status1,
status2,
status3,
status255
"离线": status0,
"空闲": status1,
"未充电": status2,
"充电中": status3,
"故障": status255,
"总数": status0 + status1 + status2 + status3 + status255
}
console.log('objobjobjobjobj', obj);