ylj20011123 a05dd915f3 update
2025-08-29 19:14:40 +08:00

742 lines
34 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 服务区人员管理
import { connect } from "umi";
import type { CurrentUser } from "umi";
import type { ConnectState } from "@/models/connect";
import React, { useRef, useState } from "react";
import ProCard from "@ant-design/pro-card";
import { MenuFoldOutlined, PlusOutlined } from "@ant-design/icons";
import { Col, Divider, FormInstance, Modal, Row } from "antd";
import { Button, message, Space, Spin, Tree } from "antd";
import useRequest from "@ahooksjs/use-request";
import { getFieldEnum, getServerpartTree } from "@/services/options";
import type { ActionType } from "@ant-design/pro-table";
import ProTable from "@ant-design/pro-table";
import ReactHTMLTableToExcel from "react-html-table-to-excel";
import LeftSelectTree from "@/pages/reports/settlementAccount/component/leftSelectTree";
import ProForm, { ProFormCheckbox, ProFormRadio, ProFormSelect, ProFormText } from "@ant-design/pro-form";
import { handleGetCASHWORKERDetail, handleGetCASHWORKERList, handleGetServerpartShopList, handleSynchroCASHWORKER } from "./service";
import PageTitleBox from "@/components/PageTitleBox";
import session from "@/utils/session";
import { handleNewGetSERVERPARTDetail } from "../service";
const serviceAreaPersonnel: React.FC<{ currentUser: CurrentUser }> = (props) => {
const { currentUser } = props
const downloadBtnRef = useRef<any>()
const actionRef = useRef<ActionType>();
const realteActionRef = useRef<ActionType>();
const formRef = useRef<FormInstance>();
const editFormRef = useRef<FormInstance>();
const [reqDetailList, setReqDetailList] = useState<any>(); // 合计项数据源
const [printOut, setPrintOut] = useState<any>(); // 打印数据的内容
const [collapsible, setCollapsible] = useState<boolean>(false)
const [treeView, setTreeView] = useState<any>()
const [printIndex, setPrintIndex] = useState<number>(new Date().getTime())
// 树相关的属性和方法
const [selectedId, setSelectedId] = useState<string>()
// 导出的加载效果
const [showLoading, setShowLoading] = useState<boolean>(false)
// 是否显示打印的表格
const [showExportTable, setShowExportTable] = useState<boolean>(false)
// 查询的条件
const [searchParams, setSearchParams] = useState<any>()
// 编辑悬浮框
const [editModal, setEditModal] = useState<boolean>(false)
// 点击行的数据
const [currentRow, setCurrentRow] = useState<any>()
// 员工详情
const [personDetail, setPersonDetail] = useState<any>()
// 关联门店悬浮框
const [relatedShop, setRelatedShop] = useState<any>()
// 选择的门店id数组
const [selectShop, setSelectShop] = useState<any>()
// 显示的人员权限可以选择的内容
const [showPROWERSETList, setShowPROWERSETList] = useState<any>()
const { loading: PROWERSETLoading, data: PROWERSET } = useRequest(async () => {
const data = await getFieldEnum({ FieldExplainField: 'PROWERSET' })
console.log('data', data);
return data
})
const addQuotesToNumbers = (value: any) => {
return /^-?\d+(\.\d+)?$/.test(value) ? `'${value}` : value;
};
const columns: any = [
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: 'ServerPart_Name',
align: 'center',
hideInSearch: true,
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: 'CASHWORKER_TYPE',
valueType: 'select',
align: 'center',
fieldProps: {
options: [
{ label: "全部", value: '0' },
{ label: "收银员", value: '1' },
{ label: "管理员", value: '2' },
{ label: "店长", value: '20' },
{ label: "稽核人员", value: '25' },
]
},
// valueEnum: {
// '0': '全部',
// '1': '收银员',
// '2': '管理员',
// '20': '店长',
// '25': "稽核人员"
// },
initialValue: '0'
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: 'CASHWORKER_NAME',
align: 'center',
hideInSearch: true,
render: (_, record) => {
return <a onClick={() => {
setCurrentRow(record)
setEditModal(true)
}}>
{record?.CASHWORKER_NAME || ''}
</a>
}
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: 'CASHWORKER_LOGINNAME',
align: 'center',
valueType: 'text',
hideInSearch: true
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: 'CASHWORKER_LOGINPWD',
align: 'center',
valueType: 'text',
hideInSearch: true,
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: 'WORKER_VALID',
align: 'center',
valueType: 'select',
fieldProps: {
options: [
{ label: "全部", value: 'all' },
{ label: "有效", value: '1' },
{ label: "无效", value: '0' },
]
},
// valueEnum: {
// 'all': '全部',
// '1': '有效',
// '0': '无效'
// },
initialValue: '1'
},
{
title: '查询内容',
dataIndex: 'searchValue',
hideInTable: true,
fieldProps: {
placeholder: '请输入人员名称'
}
}
]
const relateColumns: any = [
{
title: '门店名称',
dataIndex: 'SHOPNAME',
hideInSearch: true
},
{
title: '服务区',
dataIndex: 'SERVERPART_NAME',
hideInSearch: true
},
{
title: '经营状态',
dataIndex: 'ISVALID',
hideInSearch: true,
valueType: 'select',
valueEnum: {
'1': { text: '有效', status: 'processing' },
'0': { text: '无效', status: 'error' }
}
}
]
const exportTable = (e) => {
e.stopPropagation(); // 防止Collapse组件收起
const main = document.getElementsByClassName(`saleReportHideBox${printIndex}`)[0]
const thead = main.querySelector('thead').cloneNode(true); // 深克隆DOM节点
const tbody = main.querySelector('tbody').cloneNode(true); // 深克隆DOM节点
const container = document.querySelector('#hiddenBox');
const tempTable = document.createElement('table');
tempTable.appendChild(thead);
tempTable.appendChild(tbody);
tempTable.setAttribute('id', 'table-to-xls-serviceAreaPersonnel'); // 给table添加id值与按钮上的table字段对应
container.appendChild(tempTable); // 把创建的节点添加到页面容器中
setShowLoading(false)
downloadBtnRef.current.handleDownload();
setShowExportTable(false)
tempTable.remove() // 防止重复打印一个内容
}
return (
<div ref={(el) => {
// 打印报表
if (!reqDetailList || reqDetailList.length === 0) return;
setPrintOut(el);
}} >
{
showLoading ?
<div
style={{
width: '100%',
height: '100%',
background: 'rgba(0,0,0,0.1)',
position: 'fixed',
zIndex: 5,
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}
>
<div style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
padding: '15px 20px 10px',
background: '#fff',
borderRadius: '8px',
width: '200px'
}}>
<Spin />
<span style={{ marginLeft: '5px' }}>...</span>
</div>
</div> : ''
}
<div className={`saleReportHideBox${printIndex}`} style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }}>
{
showExportTable && reqDetailList && reqDetailList.length > 0 ?
<ProTable
columns={columns}
dataSource={reqDetailList}
pagination={false}
expandable={{
defaultExpandAllRows: true
}}
/> : ''
}
</div>
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
<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}
bordered
expandable={{
expandRowByClick: true
}}
scroll={{ y: 500 }}
headerTitle={<PageTitleBox props={props} />}
search={{ span: 6 }}
request={async (params) => {
if (!selectedId) {
return
}
setSearchParams(params)
const req: any = {
SearchParameter: {
SERVERPART_IDS: selectedId,
Worker_ValId: params?.Worker_ValId === '1' ? 1 : params?.Worker_ValId === '0' ? 0 : '',// 有效状态
// Post: params?.CASHWORKER_TYPE === '0' ? '' : Number(params?.CASHWORKER_TYPE),// 人员类别
CASHWORKER_TYPE: params?.CASHWORKER_TYPE === '0' ? '' : params.CASHWORKER_TYPE || ""
},
keyWord: {
Key: 'CASHWORKER_NAME',
Value: params?.searchValue || ''
},
PageIndex: 1,
PageSize: 999999
}
const data = await handleGetCASHWORKERList(req)
if (data && data.length > 0) {
console.log('data', data);
let res = JSON.parse(JSON.stringify(data))
let list: any = []
data.forEach((item: any) => {
item.CASHWORKER_LOGINNAME = `"${item.CASHWORKER_LOGINNAME}"`
item.CASHWORKER_LOGINPWD = `"${item.CASHWORKER_LOGINPWD}"`
list.push(item)
})
setReqDetailList(list)
return { data: res, success: true }
}
setReqDetailList([])
return { data: [], success: true }
}}
toolbar={{
actions: [
<span style={{ visibility: 'hidden' }}>
<ReactHTMLTableToExcel
buttonText={'导出excel'}
ref={downloadBtnRef}
table="table-to-xls-serviceAreaPersonnel"
filename={`服务区人员管理统计`}
sheet="sheet1"
/>
</span>,
<Button
key="new"
type="primary"
onClick={(e) => {
if (reqDetailList && reqDetailList.length > 0) {
setShowLoading(true)
setTimeout(() => {
setShowExportTable(true)
setTimeout(() => {
exportTable(e)
}, 100)
}, 100)
} else {
message.error('暂无数据可导出!')
}
}}
>
excel
</Button>,
<Button icon={<PlusOutlined />} type={"primary"} onClick={() => {
setEditModal(true)
}}></Button>
]
}}
/>
</div>
</div>
{/* 编辑悬浮框 */}
<Modal
title="拆分明细"
width={1200}
bodyStyle={{ padding: 16 }}
open={editModal}
footer={null}
destroyOnClose={true}
onCancel={() => {
setEditModal(false)
setCurrentRow(undefined)
setPersonDetail(undefined)
}}
footer={<div style={{ width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
<div>
{/* <Button type='primary' onClick={() => {
setRelatedShop(true)
}}>关联门店</Button> */}
</div>
<div>
<Button type='primary' style={{ marginRight: '16px' }} onClick={() => {
editFormRef.current?.validateFields().then(async (res) => {
// 根据当前的服务区 去拿个code
const code = await handleNewGetSERVERPARTDetail({ SERVERPARTId: res.SERVERPART_ID })
console.log('codecodecodecode', code);
let SERVERPART_CODE = code.SERVERPART_CODE
// 255个0
let defaultAuthor: string = "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
console.log('personDetail', personDetail);
console.log('res', res);
if (res.WORKER_OTHER && res.WORKER_OTHER.length > 0) {
res.WORKER_OTHER.forEach((item: string) => {
let start: string = defaultAuthor.substring(0, Number(item) - 1)
let end: string = defaultAuthor.substring(Number(item))
let test: string = `${start}1${end}`
defaultAuthor = test
console.log('defaultAuthor', defaultAuthor);
actionRef.current?.reload()
})
}
let req: any = {}
if (currentRow?.CASHWORKER_ID) {
req = {
...personDetail,
...res,
WORKER_OTHER: defaultAuthor,
SERVERPART_CODE: SERVERPART_CODE
}
} else {
req = {
...res,
WORKER_OTHER: defaultAuthor,
SERVERPART_CODE: SERVERPART_CODE
}
}
const data = await handleSynchroCASHWORKER(req)
console.log('data', data);
if (data.Result_Code === 100) {
message.success(data.Result_Desc)
setEditModal(false)
setCurrentRow(undefined)
setPersonDetail(undefined)
actionRef.current?.reload()
} else {
message.error(data.Result_Desc)
}
})
}}></Button>
<Button onClick={() => {
setEditModal(false)
setCurrentRow(undefined)
setPersonDetail(undefined)
}}></Button>
</div>
</div>}
>
<ProForm
formRef={editFormRef}
request={async () => {
console.log('currentRow', currentRow);
if (currentRow?.CASHWORKER_ID) {
const req: any = {
CASHWORKERId: currentRow?.CASHWORKER_ID
}
const data = await handleGetCASHWORKERDetail(req)
console.log('data', data);
let author: string[] = []
if (PROWERSET && PROWERSET.length > 0) {
let str: string = data.WORKER_OTHER.toString()
PROWERSET.forEach((item: any) => {
if (str[item.value - 1] === '1') {
if (author) {
author.push(item.value.toString())
}
}
})
}
console.log('author', author);
setPersonDetail({
...data,
WORKER_OTHER: author
})
return {
...data,
WORKER_OTHER: author
}
} else {
return {
WORKER_VALID: 1
}
}
}}
submitter={{
render: (props, doms) => {
return []
}
}}
>
<Row gutter={18}>
<Col span={12}>
<ProFormText
label='人员名称'
name="CASHWORKER_NAME"
rules={[
{
required: true,
message: '请输入人员名称',
},
]}
/>
</Col>
<Col span={12}>
<ProFormSelect
label='人员类别'
name="CASHWORKER_TYPE"
request={() => {
const list: any = [
{ label: '收银员', value: 1 },
{ label: '管理员', value: 2 },
{ label: '店长', value: 20 },
]
return list
}}
rules={[
{
required: true,
message: '请选择人员类别',
},
]}
fieldProps={{
onChange: (e: any) => {
console.log('e', e);
// WORKER_OTHER: ['']
let list: any = []
let nowValueList: any = []
if (e === 1) {
editFormRef.current?.setFieldsValue({ WORKER_OTHER: ['1', '5', '8', '13', '15', '47', '52', '53'] })
nowValueList = ['1', '2', '4', '5', '6', '8', '9', '10', '13', '15', '35', '47', '52', '53']
} else if (e === 2) {
editFormRef.current?.setFieldsValue({ WORKER_OTHER: ['2', '3', '4', '6', '18', '35', '36', '51'] })
nowValueList = ['1', '2', '3', '4', '5', '6', '8', '9', '10', '13', '15', '18', '35', '36', '47', '50', '51', '52', '53', '120']
} else if (e === 20) {
editFormRef.current?.setFieldsValue({ WORKER_OTHER: ['2', '3', '4', '6', '8', '18', '35', '47', '51'] })
nowValueList = ['2', '3', '4', '6', '8', '9', '10', '18', '35', '47', '51']
}
if (PROWERSET && PROWERSET.length > 0) {
PROWERSET.forEach((item: any) => {
if (nowValueList.indexOf(item.value.toString()) !== -1) {
list.push(item)
}
})
}
console.log('PROWERSETPROWERSETPROWERSETPROWERSET', PROWERSET);
console.log('listlistlistlistlist', list);
setShowPROWERSETList(list)
}
}}
/>
</Col>
<Col span={12}>
<ProFormText
disabled={currentRow?.CASHWORKER_ID}
label="人员账号"
name="CASHWORKER_LOGINNAME"
/>
</Col>
<Col span={12}>
<ProFormText
label="人员密码"
name="CASHWORKER_LOGINPWD"
rules={[
{
required: true,
message: '请输入人员密码',
},
]}
/>
</Col>
<Col span={12}>
<ProFormSelect
label='服务区'
name="SERVERPART_ID"
request={() => {
let serverpartList = session.get('ServerpartIdsTree')
return serverpartList
}}
rules={[
{
required: true,
message: '请选择服务区',
},
]}
/>
</Col>
<Col span={12}>
<ProFormSelect
label='人员状态'
name="WORKER_VALID"
request={() => {
const list: any = [
{ label: '有效', value: 1 },
{ label: '无效', value: 0 },
]
return list
}}
rules={[
{
required: true,
message: '请选择人员状态',
},
]}
/>
</Col>
<Col span={12}>
<ProFormText
label="联系方式"
name="LINKTEL"
/>
</Col>
</Row>
<Divider orientation="left" plain></Divider>
<ProFormCheckbox.Group
name="WORKER_OTHER"
options={showPROWERSETList}
// request={() => {
// if (PROWERSET && PROWERSET.length > 0) {
// PROWERSET.forEach((item: any) => {
// item.value = item.value.toString()
// })
// }
// console.log('PROWERSET', PROWERSET);
// return PROWERSET
// }}
// options={[
// { label: '销售', value: 1 },
// { label: '退货', value: 2 },
// { label: '优惠', value: 4 },
// { label: '单清', value: 5 },
// { label: '改价', value: 6 },
// { label: '开钱箱', value: 8 },
// { label: '支付通道切换', value: 9 },
// { label: '套餐销售配置', value: 10 },
// { label: '挂单取单', value: 13 },
// { label: '修改数量', value: 15 },
// { label: '小票复制', value: 35 },
// { label: '开箱口令', value: 47 },
// { label: '总清', value: 52 },
// { label: '拼音码销售', value: 53 },
// ]}
>
</ProFormCheckbox.Group>
<Row>
<Button style={{ marginRight: '16px' }} onClick={() => {
let res: any = []
if (PROWERSET && PROWERSET.length > 0) {
PROWERSET.forEach((item: any) => {
res.push(item.value.toString())
})
}
editFormRef.current?.setFieldsValue({ WORKER_OTHER: res })
}}></Button>
<Button onClick={() => {
let res = editFormRef.current?.getFieldValue('WORKER_OTHER')
console.log('res', res);
// 原本已经悬赏了的 如果没有就等于全选
if (res && res.length > 0) {
let list: any = []
if (PROWERSET && PROWERSET.length > 0) {
let resList: any = JSON.parse(JSON.stringify(PROWERSET))
res.forEach((item: any) => {
resList.forEach((subItem: any) => {
if (subItem.value.toString() === item) {
subItem.show = true
}
})
})
console.log('resList', resList);
resList.forEach((item: any) => {
if (item.show) {
} else {
list.push(item.value.toString())
}
})
}
editFormRef.current?.setFieldsValue({ WORKER_OTHER: list })
} else {
let list: any = []
if (PROWERSET && PROWERSET.length > 0) {
PROWERSET.forEach((item: any) => {
list.push(item.value.toString())
})
}
editFormRef.current?.setFieldsValue({ WORKER_OTHER: list })
}
}}></Button>
</Row>
</ProForm>
</Modal>
{/* 关联门店悬浮框 */}
<Modal
title="关联门店"
width={1200}
bodyStyle={{ padding: 16 }}
open={relatedShop}
footer={null}
destroyOnClose={true}
onCancel={() => {
setRelatedShop(false)
setSelectShop(undefined)
}}
footer={
<div style={{ width: '100%', display: 'flex', justifyContent: 'flex-end' }}>
<Button type={'primary'}></Button>
</div>
}
>
<ProTable
actionRef={realteActionRef}
columns={relateColumns}
rowKey={(record) => {
return `${record?.SERVERPARTSHOP_ID}`
}}
request={async () => {
let id: string = ''
if (!currentRow?.CASHWORKER_ID) {
let formRef: any = editFormRef.current?.getFieldsValue()
console.log('formRefformRefformRef', formRef);
id = formRef.SERVERPART_ID
}
const req: any = {
SearchParameter: {
ISVALID: 1,
SERVERPART_IDS: id || currentRow?.SERVERPART_ID,
SortStr: "BUSINESS_STATE,SHOPTRADE,SHOPSHORTNAME,SHOPREGION"
},
SortStr: "BUSINESS_STATE,SHOPTRADE,SHOPSHORTNAME,SHOPREGION",
pagesize: 999999
}
const data = await handleGetServerpartShopList(req)
if (data && data.length > 0) {
return { data, success: true }
}
return { data: [], success: true }
}}
headerTitle={`当前收银员为【${currentRow?.CASHWORKER_NAME || ""}`}
pagination={false}
scroll={{ y: 400 }}
rowSelection={{
onChange: (selectedRowKeys, selectedRows) => { // 选中行时 存储选中的行数据
console.log('selectedRowKeys', selectedRowKeys);
console.log('selectedRows', selectedRows);
setSelectShop(selectedRowKeys)
},
defaultSelectedRowKeys: selectShop
}}
/>
</Modal>
</div>
)
}
export default connect(({ user }: ConnectState) => ({
currentUser: user.currentUser
}))(serviceAreaPersonnel);