ylj20011123 385c285601 update
2025-11-10 09:36:04 +08:00

660 lines
31 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 { ConnectState } from "@/models/global";
import moment from 'moment'
import { useEffect, useRef, useState } from "react";
import { ActionType, FormInstance, ProTable } from "@ant-design/pro-components";
import React from "react";
import session from "@/utils/session";
import { Button, message, Popconfirm, Spin, Image, Modal, Drawer } from "antd";
import { PlusOutlined } from "@ant-design/icons";
import { getFieldEnumTree, handleDeletePROPERTYASSETS, handleGetBatchPROPERTYSHOP, handleGetPROPERTYASSETSTreeList, handleGetServerpartList } from "./service";
import LeftSelectTree from "@/components/leftSelectTree/leftSelectTree";
import AssetsEditor from "./components/assetsEditor";
import RelatedShop from "./components/relatedShop";
import AssetsDetail from "./components/assetsDetail";
import HistoryTable from "./components/historyTable";
import { handleGetPassportInfoById } from "../DigitalElectronics/service";
const ServerpartAssets = () => {
const downloadBtnRef = useRef<any>()
const relatedShopRef = useRef<any>()
const historyTableRef = useRef<any>()
const actionRef = useRef<ActionType>();
const formRef = useRef<FormInstance>();
const formAssetsRef = useRef<any>();
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 [assetsDrawer, setAssetsDrawer] = useState<any>(false)
// 点击行的数据
const [currentRow, setCurrentRow] = useState<any>()
// 是否正在提交
const [isSubmit, setIsSubmit] = useState<boolean>(false)
// 点击的资产详情
const [assetsDetail, setAssetsDetail] = useState<any>()
// 判断是否是查看详情
const [isSearchDetail, setIsSearchDetail] = useState<boolean>(false)
// 判断资产编码是否必填 资产类型是商铺的时候必填
const [assetsCodeRequired, setAssetsCodeRequired] = useState<boolean>(false)
// 关联门店抽屉
const [relatedShopModal, setRelatedShopModal] = useState<boolean>(false)
// 关联门店的id
const [selectShopId, setSelectShopId] = useState<any>()
// 资产详情抽屉
const [assetsDetailDrawer, setAssetsDetailDrawer] = useState<boolean>(false)
// 上传平面图的图片列表
const [fileList, setFileList] = useState<any>()
// 预览的文件地址
const [priviewImage, setPriviewImage] = useState<string>();
// 服务区方位根据服务区动态变化的选择数据
const [selectRegionList, setSelectRegionList] = useState<any>()
// 用户信息
const [currentUser, setCurrentUser] = useState<any>()
// 树相关的属性和方法
const [selectedId, setSelectedId] = useState<string>()
// 导出的加载效果
const [showLoading, setShowLoading] = useState<boolean>(false)
// 是否显示打印的表格
const [showExportTable, setShowExportTable] = useState<boolean>(false)
// 查询的条件
const [searchParams, setSearchParams] = useState<any>()
// 预览图片
const [imagePreviewVisible, setImagePreviewVisible] = useState<boolean>(false)
// 关联历史门店的抽屉
const [showHistory, setShowHistory] = useState<boolean>(false)
// 默认选中门店的行号列表
const [defaultSelectList, setDefaultSelectList] = useState<any>()
// 资产类型
const [PROPERTYASSETSTYPE, setPROPERTYASSETSTYPE] = useState<any>()
// 资产类型的对象
const [PROPERTYASSETS_TYPEOBJ, setPROPERTYASSETS_TYPEOBJ] = useState<any>()
const [columnsStateMap, setColumnsStateMap] = useState<any>({
STAFF_NAME: { show: false },
});
const shopregionObj = {
"10": "A区",
"11": "上行",
"12": "上线",
"15": "东区",
"20": "南区",
"30": "B区",
"31": "下行",
"32": "下线",
"35": "西区",
"40": "北区"
}
// const serverpartObj = session.get('serverpartObj')
const [serverpartObj, setServerpartObj] = useState<any>()
const columns: any = [
{
title: '服务区名称',
dataIndex: 'SERVERPART_ID',
hideInSearch: true,
width: 180,
ipsis: true,
valueType: 'select',
align: 'center',
render: (_, record) => {
return record?.level === 1 ? record?.SPREGIONTYPE_NAME ? record?.SPREGIONTYPE_NAME : '' :
record?.level === 2 ? record?.SERVERPART_ID && serverpartObj ? serverpartObj[record?.SERVERPART_ID] : '' :
record?.level === 3 ? record?.PROPERTYASSETS_REGION && shopregionObj ?
shopregionObj[record?.PROPERTYASSETS_REGION] + `${record?.PROPERTYASSETS_TYPE && PROPERTYASSETS_TYPEOBJ ? PROPERTYASSETS_TYPEOBJ[record?.PROPERTYASSETS_TYPE] : ''}`
: '' :
record?.level === 4 ? record?.PROPERTYASSETS_CODE ?
<a onClick={() => {
console.log('record', record);
setCurrentRow(record)
setAssetsDrawer(true)
}}>
{record?.PROPERTYASSETS_CODE}
</a>
: '-' : '-'
}
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: 'PROPERTYASSETS_NAME',
width: 250,
ellipsis: true,
hideInSearch: true,
render: (_, record) => {
return record?.PROPERTYASSETS_ID ?
record?.SHOPNAME
:
record?.SHOPNAME ?
<view style={{ display: 'flex', alignItems: 'center' }}>
<span>{record?.SHOPNAME}</span>
{
record?.BUSINESS_STATE === 1000 ?
<span style={{ margin: '0 4px' }} className="ant-badge-status-dot ant-badge-status-processing"></span> :
record?.BUSINESS_STATE === 1010 ?
<span style={{ margin: '0 4px' }} className="ant-badge-status-dot ant-badge-status-default"></span> :
record?.BUSINESS_STATE === 2000 ?
<span style={{ margin: '0 4px' }} className="ant-badge-status-dot ant-badge-status-warning"></span> :
record?.BUSINESS_STATE === 3000 ?
<span style={{ margin: '0 4px' }} className="ant-badge-status-dot ant-badge-status-error"></span> : ''
}
</view>
:
''
}
},
{
title: '资产类型',
dataIndex: 'PROPERTYASSETS_TYPE',
ellipsis: true,
width: 120,
align: 'center',
valueType: 'treeSelect',
request: async () => {
const list = await getFieldEnumTree({ FieldExplainField: 'PROPERTYASSETS_TYPE', notformate: true })
console.log('list2222', list);
let obj: any = []
if (list && list.length > 0) {
list.forEach((item: any) => {
obj[item.value] = item.label
})
}
setPROPERTYASSETS_TYPEOBJ(obj)
return list
},
fieldProps: {
treeDefaultExpandAll: true,
},
},
{
title: '商铺面积',
dataIndex: 'PROPERTYASSETS_AREA',
align: 'center',
width: 140,
valueType: 'digit',
hideInSearch: true
},
{
title: '服务区面积',
dataIndex: 'TOTAL_AREA',
align: 'center',
width: 160,
valueType: 'digit',
hideInSearch: true
},
{
dataIndex: 'BUSINESS_STATE',
title: '门店状态',
width: 120,
valueType: 'select',
align: 'center',
hideInSearch: true,
ellipsis: true,
valueEnum: {
3000: { text: '关闭', status: 'error' },
2000: { text: '暂停', status: 'warning' },
1000: { text: '运营中', status: 'processing' },
1010: { text: '待运营', status: 'default' }
}
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: 'PROPERTYASSETS_DESC',
width: 180,
hideInSearch: true,
ellipsis: true,
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: 'STAFF_NAME',
align: 'center',
width: 150,
hideInSearch: true
},
{
title: '操作',
dataIndex: 'option',
width: 120,
align: 'center',
valueType: 'option',
hideInDescriptions: true,
hideInSearch: true,
width: 120,
render: (_, record) => {
return [
<>
{
record?.PROPERTYASSETS_CODE ?
<>
<a onClick={() => {
console.log('record', record);
setCurrentRow(record)
setAssetsDrawer(true)
}}></a>
<Popconfirm
title="确认删除该资产?"
onConfirm={async () => {
console.log('record', record);
const req: any = {
Id: record?.PROPERTYASSETS_ID,
OperateId: currentUser?.ID,
OperateName: currentUser?.Name,
}
const data = await handleDeletePROPERTYASSETS(req)
if (data.Result_Code === 100) {
message.success(data.Result_Desc)
actionRef.current?.reload()
} else {
message.error(data.Result_Desc)
}
}}
>
<a onClick={() => {
}}></a>
</Popconfirm>
</>
: <>
{
record?.SHOPNAME ?
<a onClick={() => {
console.log('record', record);
setCurrentRow(record)
setAssetsDrawer(true)
}}></a> : ''
}
</>
}
</>
]
}
}
]
// 导出的表格
const exportColumns: any = [
{
title: '服务区名称',
dataIndex: 'SERVERPART_ID',
hideInSearch: true,
valueType: 'select',
align: 'center',
render: (_, record) => {
return record?.SERVERPART_ID ? serverpartObj[record?.SERVERPART_ID] : ''
}
},
{
title: '区域方位',
dataIndex: 'PROPERTYASSETS_REGION',
hideInSearch: true,
align: 'center',
valueType: 'select',
request: () => {
let list: any = session.get('shopregionList')
return list
}
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: 'PROPERTYASSETS_CODE',
hideInSearch: true,
},
]
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-serverpartAssets'); // 给table添加id值与按钮上的table字段对应
container.appendChild(tempTable); // 把创建的节点添加到页面容器中
setShowLoading(false)
downloadBtnRef.current.handleDownload();
setShowExportTable(false)
tempTable.remove() // 防止重复打印一个内容
}
// 历史表格的提交
const handleSubHistoryTableData = async () => {
let list: any = historyTableRef.current?.selectModalRowList
console.log('list', list);
let reqList: any = []
list.forEach((item: any) => {
reqList.push({
SERVERPART_ID: currentRow.SERVERPART_ID,
PROPERTYASSETS_ID: currentRow.PROPERTYASSETS_ID,
SERVERPARTSHOP_ID: item.SERVERPARTSHOP_ID,
STAFF_ID: currentUser?.ID,
STAFF_NAME: currentUser?.Name,
PROPERTYSHOP_STATE: 1,
CREATE_DATE: moment().format('YYYY-MM-DD HH:mm:ss'),
OPERATOR_ID: currentUser?.ID,
OPERATOR_NAME: currentUser?.Name,
OPERATE_DATE: moment().format('YYYY-MM-DD HH:mm:ss'),
})
})
const data = await handleGetBatchPROPERTYSHOP(reqList)
if (data.Result_Code === 100) {
message.success(data.Result_Desc)
setShowHistory(false);
} else {
message.error(data.Result_Desc)
}
}
// 获取当前用户信息
const handleGetUserInfo = async (id: string) => {
const req: any = {
UserIdEncrypted: id
}
const data = await handleGetPassportInfoById(req)
console.log('datae2e12e1', data);
setCurrentUser(data)
return data
}
// 拿到当前的服务区列表
const handleGetServerList = async () => {
const data = await handleGetServerpartList({ Province_Code: '530000' })
let obj: any = {}
if (data && data.length > 0) {
data.forEach((item: any) => {
obj[item.SERVERPART_ID] = item.SERVERPART_NAME
})
}
setServerpartObj(obj)
}
useEffect(() => {
const search = window.location.search;
const addressParams = Object.fromEntries(new URLSearchParams(search).entries());
console.log('addressParamsaddressParamsaddressParams', addressParams);
handleGetUserInfo(addressParams.UserIdEncrypted)
handleGetServerList()
}, [])
return (
<div>
{
currentUser ?
<div>
{
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={[...exportColumns, ...columns.slice(1, columns.length - 1)]}
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', height: 'calc(100vh - 80px)' }}>
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} currentUser={currentUser} />
<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
}}
rowKey={(record: any) => {
return `${record?.SERVERPART_ID}-${record?.PROPERTYASSETS_REGION}-${record?.SERVERPARTSHOP_ID}-${record?.level}-${record?.indexNumber}`
}}
headerTitle={<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}></span>}
search={{ span: 6 }}
scroll={{ x: '100%', y: 'calc(100vh - 400px)' }}
request={async (params) => {
if (!selectedId) {
return
}
const req: any = {
SearchParameter: {
SERVERPART_IDS: selectedId,
PROPERTYASSETS_STATE: 1,
PROPERTYASSETS_TYPES: params?.PROPERTYASSETS_TYPE || ''
},
PageIndex: 1,
PageSize: 999999
}
setSearchParams(params)
const data = await handleGetPROPERTYASSETSTreeList(req)
console.log('data', data);
if (data && data.length > 0) {
// 每层都加上level 第一层显示片区 第二层显示服务区 第三层显示方位 第四层显示资产编码
data.forEach((item: any, index: number) => {
item.level = 1
item.indexNumber = index + 1
if (item.children && item.children.length > 0) {
item.children.forEach((subItem: any, subIndex: number) => {
subItem.level = 2
subItem.indexNumber = `${index + 1}-${subIndex + 1}`
if (subItem.children && subItem.children.length > 0) {
subItem.children.forEach((thirdItem: any, thirdIndex: number) => {
thirdItem.level = 3
thirdItem.indexNumber = `${index + 1}-${subIndex + 1}-${thirdIndex + 1}`
if (thirdItem.children && thirdItem.children.length > 0) {
thirdItem.children.forEach((fourthItem: any, fourthIndex: number) => {
fourthItem.level = 4
fourthItem.indexNumber = `${index + 1}-${subIndex + 1}-${thirdIndex + 1}-${fourthIndex + 1}`
})
}
})
}
})
}
})
setReqDetailList(data)
return { data, success: true }
}
return { data: [], success: true }
}}
toolbar={{
actions: [
<Button
type='primary'
icon={<PlusOutlined />}
onClick={() => {
setAssetsDrawer(true)
}}>
</Button>,
<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>
]
}}
pagination={{
pageSize: 10
}}
columnsState={{
value: columnsStateMap,
onChange: setColumnsStateMap,
}}
/>
</div>
</div>
{fileList && fileList.length > 0 && <div style={{ display: 'none' }}>
<Image.PreviewGroup
preview={{
visible: imagePreviewVisible,
onVisibleChange: vis => {
setImagePreviewVisible(vis)
}
}}>
{
fileList.map((n) =>
<Image src={n.url} key={n.url} />
)
}
</Image.PreviewGroup>
</div>}
<AssetsEditor onShow={assetsDrawer} currentUser={currentUser} handleClose={() => {
setAssetsDrawer(false);
setCurrentRow(undefined);
setAssetsDetail(undefined);
setDefaultSelectList([])
setIsSearchDetail(false)
setAssetsCodeRequired(false)
setSelectShopId(undefined)
setIsSubmit(false)
setPROPERTYASSETSTYPE(undefined)
setFileList([])
setSelectRegionList([])
}} id={currentRow?.PROPERTYASSETS_ID} shopId={currentRow?.SERVERPARTSHOP_ID} SERVERPARTID={currentRow?.SERVERPART_ID} parentRef={actionRef} setOnShow={setAssetsDrawer} />
{/* 关联门店的悬浮框 */}
<Modal
width={1000}
open={relatedShopModal}
title={'请选择门店进行关联'}
onOk={() => {
let shopIdList: any = relatedShopRef.current?.selectModalRowList
console.log('shopIdList', shopIdList);
let shopId: any = {}
if (shopIdList && shopIdList.length > 0) {
shopId = shopIdList[0]
console.log('shopId', shopId);
}
// 选中的整行对象 因为要回显关联的门店
setSelectShopId(shopId)
setRelatedShopModal(false)
}}
destroyOnClose={!assetsDrawer}
onCancel={() => {
setRelatedShopModal(false)
}}
>
<RelatedShop currentRow={currentRow} defaultId={assetsDetail?.PropertyShop?.SERVERPARTSHOP_ID} detailFormRef={formAssetsRef} onRef={relatedShopRef} show={relatedShopModal} />
</Modal>
{/* 资产详情抽屉 */}
<Drawer
width={'80%'}
visible={assetsDetailDrawer}
className={"assetsDetailDrawer"}
onClose={() => {
setAssetsDetailDrawer(false);
}}
bodyStyle={{ backgroundColor: "#fff", padding: 16 }}
closable={false}
destroyOnClose
>
<AssetsDetail currentRow={currentRow} />
</Drawer>
{/* 关联历史门店 */}
<Drawer
width={'60%'}
visible={showHistory}
className={"assetsDetailDrawer"}
onClose={() => {
setShowHistory(false);
}}
bodyStyle={{ backgroundColor: "#fff", padding: 16 }}
closable={false}
destroyOnClose
footer={
<div style={{ width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'flex-end' }}>
<Button type={"primary"} onClick={() => {
handleSubHistoryTableData()
}}>
</Button>
</div>
}
>
<HistoryTable onRef={historyTableRef} currentRow={currentRow} defaultId={defaultSelectList} />
</Drawer>
</div> :
<Spin />
}
</div>
)
}
export default connect(({ user }: ConnectState) => ({
currentUser: user.data
}))(ServerpartAssets);