This commit is contained in:
ylj20011123 2025-11-10 09:36:04 +08:00
parent 4c9e3c16d3
commit 385c285601
31 changed files with 5090 additions and 66 deletions

View File

@ -32,7 +32,12 @@ export default [
path: '/InvoiceSearch/index',
name: '开票查询',
component: "@/pages/InvoiceSearch/index",
}
},
{
path: '/serverpartAssets/index',
name: '服务区资产管理',
component: "@/pages/serverpartAssets/index",
},
]
}

View File

@ -16,6 +16,7 @@
"crypto-js": "^4.2.0",
"dva": "^3.0.0-alpha.1",
"moment": "^2.30.1",
"numeral": "^2.0.6",
"qrcode": "^1.5.4",
"umi": "^4.3.24",
"xlsx": "^0.18.5",

BIN
src/assets/ai/close.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -1,7 +1,8 @@
import { connect } from "umi";
// import type { ConnectState } from "@/models/connect";
import ProCard from "@ant-design/pro-card";
// import searchIcon from '@/assets/ai/searchIcon.png'
import searchIcon from '@/assets/ai/searchIcon.png'
import close from '@/assets/ai/close.png'
import { useRef, useState } from "react";
import { MenuFoldOutlined } from "@ant-design/icons";
import ProForm, { ProFormText } from "@ant-design/pro-form";
@ -9,7 +10,8 @@ import { Button, Col, FormInstance, Row, Tree } from "antd";
// import { getServerpartTree } from "@/services/options";
import useRequest from "@ahooksjs/use-request";
import { getMerchantShopTree, getServerpartTree } from "./service";
// import './style.less'
import { handleGetPassportInfoById } from "@/pages/DigitalElectronics/service";
import './style.less'
// import { getMerchantShopTree } from "@/pages/Setting/Users/service";
@ -27,9 +29,6 @@ type DetailProps = {
noWj?: any // 把万佳商贸隐藏
}
const LeftSelectTree = ({ setSelectedId, reload, actionRef, currentUser, width, otherFun, setCollapsible, collapsible, haveTest, handleGetLeftTreeData, noWj }: DetailProps) => {
console.log('currentUser', currentUser);
const searchTreeRef = useRef<FormInstance>();
// 默认的服务区树
const [allTreeViews, setAllTreeViews] = useState<any>()
@ -37,11 +36,20 @@ const LeftSelectTree = ({ setSelectedId, reload, actionRef, currentUser, width,
const [isShowAllInTree, setIsShowAllInTree] = useState<boolean>(false)
// 加载服务区树
const { loading: treeLoading, data: treeViews } = useRequest(async () => {
const search = window.location.search;
const addressParams = Object.fromEntries(new URLSearchParams(search).entries());
console.log('addressParamsaddressParamsaddressParams', addressParams);
const req: any = {
UserIdEncrypted: addressParams.UserIdEncrypted
}
const userInfo = await handleGetPassportInfoById(req)
console.log('userInfouserInfouserInfo', userInfo);
let data: any = []
if (currentUser?.UserPattern === 2000) {
data = await getMerchantShopTree({ BusinessManId: currentUser?.BusinessManID, ShowShop: false });
if (userInfo?.UserPattern === 2000) {
data = await getMerchantShopTree({ BusinessManId: userInfo?.BusinessManID, ShowShop: false });
} else {
data = await getServerpartTree(currentUser?.provinceCode, currentUser?.CityAuthority, true, true, true, false, 1000)
data = await getServerpartTree(userInfo?.ProvinceCode, userInfo?.CityAuthority, true, true, true, false, 1000)
}
console.log('datatree', data);
@ -153,10 +161,10 @@ const LeftSelectTree = ({ setSelectedId, reload, actionRef, currentUser, width,
<ProCard
style={{ width: !collapsible ? width ? `${width}px` : "300px" : "60px" }}
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? width ? `${width}px` : "300px" : "60px" }}
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? width ? `${width}px` : "300px" : "60px", overflowY: 'auto' }}
extra={<div className="leftSelectBox">
{/* src={searchIcon} */}
<img className="searchIcon" onClick={() => {
{/* */}
<img className="searchIcon" src={searchIcon} onClick={() => {
setShowServiceSearchBox(true)
}} />
<MenuFoldOutlined onClick={() => {

View File

@ -0,0 +1,34 @@
.pageTable-leftnav {
height: 100%;
.leftSelectBox {
position: relative;
.searchIcon {
width: 20px;
height: 20px;
cursor: pointer;
margin-right: 15px;
}
.fixedBox {
position: absolute;
width: 275px;
background: #fff;
right: -10px;
box-shadow: 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
border-radius: 8px;
box-sizing: border-box;
padding: 12px;
z-index: 2;
display: flex;
align-items: center;
.noBottom {
.ant-form-item {
margin-bottom: 0 !important;
}
}
}
}
}

View File

@ -251,6 +251,12 @@ const UserModel: UserModelType = {
name: '开票查询',
component: "@/pages/InvoiceSearch/index",
},
{
path: '/serverpartAssets/index',
redirect: '',
name: '服务区资产管理',
component: "@/pages/serverpartAssets/index",
},
]
}
@ -324,7 +330,8 @@ const UserModel: UserModelType = {
"/DigitalElectronics/index",
"/InvoiceInquiry/index",
"/redReversal/index",
"/InvoiceSearch/index"
"/InvoiceSearch/index",
"/serverpartAssets/index"
// '/examine/index',
// '/examine/modal',
// '/examine/question',

View File

@ -292,11 +292,17 @@ const DigitalElectronics: React.FC<{ currentUser: any }> = (props) => {
requestId: Date.now().toString(),
data: encryptedDataOld
};
let responseOld = await handleGetForwardJDPJInterface({
ReqUrl: `https://cosmic.piaozone.com/ynjtjtjykf/kapi/app/sim/openApi?access_token=${accessToken}`,
Access_token: accessToken,
data: JSON.stringify(requestParams)
})
let newreq2: any = {
name: "",
value: encryptAES(JSON.stringify({
ReqUrl: `https://cosmic.piaozone.com/ynjtjtjykf/kapi/app/sim/openApi?access_token=${accessToken}`,
Access_token: accessToken,
data: JSON.stringify(requestParams)
}))
}
let responseOld = await handleGetForwardJDPJInterface(newreq2)
responseOld = JSON.parse(responseOld as any)
// console.log('最终请求参数:', requestParams);
// // 调用查询接口 (这里需要传入正确的code参数)
@ -385,11 +391,16 @@ const DigitalElectronics: React.FC<{ currentUser: any }> = (props) => {
console.log('访问令牌:', accessToken);
// const response = await handleGetKaiPiao(invoiceData, accessToken);
let response = await handleGetForwardJDPJInterface({
ReqUrl: `https://cosmic.piaozone.com/ynjtjtjykf/kapi/app/sim/openApi?access_token=${accessToken}`,
Access_token: accessToken,
data: JSON.stringify(invoiceData)
})
let newreq: any = {
name: "",
value: encryptAES(JSON.stringify({
ReqUrl: `https://cosmic.piaozone.com/ynjtjtjykf/kapi/app/sim/openApi?access_token=${accessToken}`,
Access_token: accessToken,
data: JSON.stringify(invoiceData)
}))
}
let response = await handleGetForwardJDPJInterface(newreq)
response = JSON.parse(response as any)
console.log('开票响应:', response);
@ -533,12 +544,15 @@ const DigitalElectronics: React.FC<{ currentUser: any }> = (props) => {
console.log('访问令牌:', accessToken);
// const response = await handleGetKaiPiao(invoiceData, accessToken);
let response = await handleGetForwardJDPJInterface({
ReqUrl: `https://cosmic.piaozone.com/ynjtjtjykf/kapi/app/sim/openApi?access_token=${accessToken}`,
Access_token: accessToken,
data: JSON.stringify(invoiceData)
})
let newreq: any = {
name: "",
value: encryptAES(JSON.stringify({
ReqUrl: `https://cosmic.piaozone.com/ynjtjtjykf/kapi/app/sim/openApi?access_token=${accessToken}`,
Access_token: accessToken,
data: JSON.stringify(invoiceData)
}))
}
let response = await handleGetForwardJDPJInterface(newreq)
response = JSON.parse(response as any)
console.log('开票响应:', response);

View File

@ -229,11 +229,16 @@ const InvoiceInquiry: React.FC<{ currentUser: any }> = (props) => {
requestId: Date.now().toString(),
data: encryptedDataOld
};
let responseOld = await handleGetForwardJDPJInterface({
ReqUrl: `https://cosmic.piaozone.com/ynjtjtjykf/kapi/app/sim/openApi?access_token=${accessToken}`,
Access_token: accessToken,
data: JSON.stringify(requestParams)
})
let newreq2: any = {
name: "",
value: encryptAES(JSON.stringify({
ReqUrl: `https://cosmic.piaozone.com/ynjtjtjykf/kapi/app/sim/openApi?access_token=${accessToken}`,
Access_token: accessToken,
data: JSON.stringify(requestParams)
}))
}
let responseOld = await handleGetForwardJDPJInterface(newreq2)
responseOld = JSON.parse(responseOld as any)
// console.log('最终请求参数:', requestParams);
// // 调用查询接口 (这里需要传入正确的code参数)
@ -321,12 +326,15 @@ const InvoiceInquiry: React.FC<{ currentUser: any }> = (props) => {
console.log('最终请求数据:', invoiceData);
console.log('访问令牌:', accessToken);
// const response = await handleGetKaiPiao(invoiceData, accessToken);
let response = await handleGetForwardJDPJInterface({
ReqUrl: `https://cosmic.piaozone.com/ynjtjtjykf/kapi/app/sim/openApi?access_token=${accessToken}`,
Access_token: accessToken,
data: JSON.stringify(invoiceData)
})
let newreq: any = {
name: "",
value: encryptAES(JSON.stringify({
ReqUrl: `https://cosmic.piaozone.com/ynjtjtjykf/kapi/app/sim/openApi?access_token=${accessToken}`,
Access_token: accessToken,
data: JSON.stringify(invoiceData)
}))
}
let response = await handleGetForwardJDPJInterface(newreq)
response = JSON.parse(response as any)
console.log('开票响应:', response);
@ -470,11 +478,15 @@ const InvoiceInquiry: React.FC<{ currentUser: any }> = (props) => {
// const response = await handleGetKaiPiao(invoiceData, accessToken);
let response = await handleGetForwardJDPJInterface({
ReqUrl: `https://cosmic.piaozone.com/ynjtjtjykf/kapi/app/sim/openApi?access_token=${accessToken}`,
Access_token: accessToken,
data: JSON.stringify(invoiceData)
})
let newreq: any = {
name: "",
value: encryptAES(JSON.stringify({
ReqUrl: `https://cosmic.piaozone.com/ynjtjtjykf/kapi/app/sim/openApi?access_token=${accessToken}`,
Access_token: accessToken,
data: JSON.stringify(invoiceData)
}))
}
let response = await handleGetForwardJDPJInterface(newreq)
response = JSON.parse(response as any)
console.log('开票响应:', response);

View File

@ -5,6 +5,7 @@ const authority: PageAuthority = {
'/InvoiceInquiry/index': ['/InvoiceInquiry/index'],
'/redReversal/index': ['/redReversal/index'],
'/InvoiceSearch/index': ['/InvoiceSearch/index'],
'/serverpartAssets/index': ['/serverpartAssets/index'],
};

View File

@ -292,11 +292,15 @@ const RedReversal: React.FC<{ currentUser: any }> = (props) => {
requestId: Date.now().toString(),
data: encryptedDataOld
};
let responseOld = await handleGetForwardJDPJInterface({
ReqUrl: `https://cosmic.piaozone.com/ynjtjtjykf/kapi/app/sim/openApi?access_token=${accessToken}`,
Access_token: accessToken,
data: JSON.stringify(requestParams)
})
let newTokenReq2: any = {
name: "",
value: encryptAES(JSON.stringify({
ReqUrl: `https://cosmic.piaozone.com/ynjtjtjykf/kapi/app/sim/openApi?access_token=${accessToken}`,
Access_token: accessToken,
data: JSON.stringify(requestParams)
}))
}
let responseOld = await handleGetForwardJDPJInterface(newTokenReq2)
responseOld = JSON.parse(responseOld as any)
// console.log('最终请求参数:', requestParams);
// // 调用查询接口 (这里需要传入正确的code参数)
@ -384,12 +388,15 @@ const RedReversal: React.FC<{ currentUser: any }> = (props) => {
console.log('最终请求数据:', invoiceData);
console.log('访问令牌:', accessToken);
// const response = await handleGetKaiPiao(invoiceData, accessToken);
let response = await handleGetForwardJDPJInterface({
ReqUrl: `https://cosmic.piaozone.com/ynjtjtjykf/kapi/app/sim/openApi?access_token=${accessToken}`,
Access_token: accessToken,
data: JSON.stringify(invoiceData)
})
let newTokenReq: any = {
name: "",
value: encryptAES(JSON.stringify({
ReqUrl: `https://cosmic.piaozone.com/ynjtjtjykf/kapi/app/sim/openApi?access_token=${accessToken}`,
Access_token: accessToken,
data: JSON.stringify(invoiceData)
}))
}
let response = await handleGetForwardJDPJInterface(newTokenReq)
response = JSON.parse(response as any)
console.log('开票响应:', response);
@ -532,12 +539,15 @@ const RedReversal: React.FC<{ currentUser: any }> = (props) => {
console.log('访问令牌:', accessToken);
// const response = await handleGetKaiPiao(invoiceData, accessToken);
let response = await handleGetForwardJDPJInterface({
ReqUrl: `https://cosmic.piaozone.com/ynjtjtjykf/kapi/app/sim/openApi?access_token=${accessToken}`,
Access_token: accessToken,
data: JSON.stringify(invoiceData)
})
let newTokenReq: any = {
name: "",
value: encryptAES(JSON.stringify({
ReqUrl: `https://cosmic.piaozone.com/ynjtjtjykf/kapi/app/sim/openApi?access_token=${accessToken}`,
Access_token: accessToken,
data: JSON.stringify(invoiceData)
}))
}
let response = await handleGetForwardJDPJInterface(newTokenReq)
response = JSON.parse(response as any)
console.log('开票响应:', response);

View File

@ -0,0 +1,58 @@
.subsidiaryBox{
.ant-form-item{
margin-bottom: 0;
}
}
.card-title {
// position: relative;
// padding-left: 11px;
font-size: 16px;
font-family: Microsoft YaHei Bold, Microsoft YaHei Bold-Bold;
text-align: left;
display: flex;
align-items: center;
&::before {
// position: absolute;
// top: 3px;
// left: 0;
display: block;
width: 3px;
// vertical-align: middle;
height: 14px;
margin-right: 8px;
content: '';
}
}
.from-group-title {
margin-bottom: 16px;
font-weight: 700;
font-size: 15px;
}
.contract-static-card .amount {
color: #FFA74F;
font-size: 36px;
font-family: Bahnschrift Regular;
// line-height: 1;
letter-spacing: 1px;
}
.ant-drawer-body .ant-pro-page-container-warp {
padding-top: 24px;
}
.ant-drawer-body2 .ant-pro-page-container-warp {
padding-top: 0px!important;
}
.contract-drawer .ant-drawer-body .ant-pro-grid-content {
height: calc(100vh - 225px );
overflow-y: auto;
}
.contract-detail-drawer .ant-drawer-body .ant-pro-grid-content {
height: calc(100vh - 102px);
overflow-y: auto;
}

View File

@ -0,0 +1,889 @@
/*
* @Author: cclu
* @Date: 2021-12-13 11:01:23
* @LastEditTime: 2024-10-29 15:38:57
* @LastEditors: cclu 1106109051@qq.com
* @Description:
* @FilePath: \cloud-platform\src\pages\contract\components\detail.tsx
*/
import useRequest from "@ahooksjs/use-request";
import './ContractDetailDrawer.less';
import { Card, Col, Descriptions, Drawer, Modal, Row, Statistic, Typography, Upload } from "antd";
import numeral from 'numeral'
import { useRef, useState } from "react";
import { getDetail, getPictureList, getProjectList, getSubDetail, handleGetRelatedList } from "../service";
import session from "@/utils/session";
import moment from "moment";
import { PageContainer, ProDescriptions } from "@ant-design/pro-components";
const { Text } = Typography;
// 标题金额拆分小数点前后显示大小
const amountDom = (value: any) => {
const stringValue = `${value}`
const [intValue, floatValue] = stringValue.split(".")
return floatValue ?
<><Text type="warning" style={{
fontSize: 36, lineHeight: 1,
fontFamily: "Bahnschrift Regular"
}}>{numeral(intValue || 0).format("0,0")}</Text><Text type="warning" style={{
fontSize: 18,
fontFamily: "Bahnschrift Regular"
}}>.{floatValue}</Text>
<Text type="warning" style={{ fontSize: 14 }}>()</Text></>
:
<><Text type="warning" style={{
fontSize: 36, lineHeight: 1,
fontFamily: "Bahnschrift Regular"
}}>{intValue}</Text><Text type="warning" style={{ fontSize: 14 }}>()</Text></>
}
const ContractDetailDrawer = ({ contractId, currentRow, clickedId }: { contractId: number, currentRow?: any, clickedId?: any }) => {
// clickedId已经点击过的合同id 防止循环跳转
const [shopName, setShopName] = useState<[]>()
// const [fileList, setFileList] = useState<UploadFile[]>([]) // 需要附件图片列表
// 获取合同主表信息
const { loading: detailLoading, data: contractDetail } = useRequest(async () => {
const data = await getDetail(contractId)
if (data && data.REGISTERCOMPACT_ID) {
if (data.COMPACT_DETAILS === 1000) {
handleGetRelatedContracts(data.COMPACT_DETAILS, data.REGISTERCOMPACT_ID)
} else {
handleGetRelatedContracts(data.COMPACT_DETAILS, data.REGISTERCOMPACT_HOSTID)
}
}
return data
})
// const { loading: serverpartLoading, data: serverpartDetail } = useRequest(() => { return getContractServerpartList(contractId) })
// 获取合同附属表信息
const { loading, data: subDetail } = useRequest(async () => {
const data = await getSubDetail(contractId)
return { ...data, SERVERPARTREGION: data?.SERVERPARTREGION ? data?.SERVERPARTREGION.split(',') : [] }
})
// 切换后的结算模式
const [afterChangeSwitch, setAfterChangeSwitch] = useState<any>()
// 获取合同经营项目
const { loading: projectLoading, data: projectData } = useRequest(async () => {
const data = await getProjectList({ REGISTERCOMPACT_ID: contractId, PROJECT_VALID: 1, pagesize: 20, pageindex: 1 })
if (data.data && data.data.length > 0) {
setAfterChangeSwitch(data.data[0].SWITCH_MODES)
}
return data
})
// 获取合同附属类型
const compactType = session.get("COMPACT_CHILDTYPEList")
const [associationDrawer, setAssociationDrawer] = useState<boolean>(false)
const [associationRow, setAssociationRow] = useState<any>()
const [COMPACTLIST, setCOMPACTLIST] = useState<any>([])
// 显示关联合同的附件
const [showChildrenFile, setShowChildrenFile] = useState<boolean>(false)
// 关联合同的附件
const [childrenFile, setChildrenFile] = useState<any>()
// 关联合同列表
const [relatedContractsList, setRelatedContractsList] = useState<any>()
// 显示关联合同的抽屉
const [showChildDetailDrawer, setShowChildDetailDrawer] = useState<boolean>(false)
// 选中的关联合同
const [childrenRow, setChildrenRow] = useState<any>()
// 获取合同附件
const { loading: compactFileLoading, data: fileList } = useRequest(async () => {
const data = await getPictureList(contractId, '1115')
const files = data && data?.total > 0 ? data?.data.map((n: any) => {
return {
uid: n.ImageId,
name: n.ImageName,
status: 'done',
url: n.ImageUrl,
deletepath: n.ImagePath
}
}) : []
// setFileList(files)
return files
})
// 已经查看过的子合同
// const [historyList, setHistoryList] = useState<any>()
const historyList = useRef<any>()
// 获取合同类型子项
const { loading: COMPACTLoading, data: COMPACTLISTS } = useRequest(async () => {
const options = session.get("COMPACT_DETAILSList")
setCOMPACTLIST(options)
const obj: any = session.get("COMPACT_DETAILSObj")
return obj;
})
// 显示日志抽屉
const [showLogDrawer, setShowLogDrawer] = useState<boolean>(false)
if (!projectLoading && projectData?.data && !shopName) {
// const shopname = projectData.data.map((n: any) => n.SERVERPARTSHOP_NAME)
// if (shopname) {
// setShopName(shopname.toString().split(','))
// }
setShopName(projectData.data.map((n: any) => n.SERVERPARTSHOP_NAME))
}
// const colors = ['blue', 'geekblue', 'volcano', 'orange',]
// 拿到关联合同列表
const handleGetRelatedContracts = async (type: number, id: number) => {
let req = {}
if (type === 1000) {
req = {
SearchParameter: {
REGISTERCOMPACT_HOSTID: id,
COMPACT_STATE: 1000
},
PageIndex: 1,
PageSize: 999999
}
} else {
req = {
SearchParameter: {
REGISTERCOMPACT_ID: id,
},
PageIndex: 1,
PageSize: 999999
}
}
const data = await handleGetRelatedList(req)
if (data && data.data && data.data.length > 0) {
const list: any = []
data.data.forEach((item: any) => {
if (type !== 1000 || (type === 1000 && item.COMPACT_DETAILS !== 1000)) {
list.push(item)
}
})
setRelatedContractsList(list)
}
}
const settlementModeObj = session.get("SETTLEMENT_MODESObj")
const settlementCycleObj = session.get("SETTLEMENT_CYCLEObj")
const headerColumns: any = [
{
title: '经营模式',
key: 'BUSINESS_TYPE',
dataIndex: 'BUSINESS_TYPE',
valueType: 'select',
valueEnum: {
1000: '合作经营',
2000: '固定租金',
3000: '保底采购',
4000: '业主自营',
},
},
{
title: '结算模式',
key: 'SETTLEMENT_MODES',
dataIndex: 'SETTLEMENT_MODES',
valueType: 'select',
request: async () => {
const options = session.get("SETTLEMENT_MODESList");
return options;
}
},
{
title: '结算周期',
key: 'SETTLEMENT_CYCLE',
dataIndex: 'SETTLEMENT_CYCLE',
valueType: 'select',
request: async () => {
const options = session.get("SETTLEMENT_CYCLEList");
return options
}
}
]
const contractType: any = {
// 经营模式【ISFORMAT】1000【合作经营】、2000【固定租金】
1000: '合作经营',
2000: '固定租金',
// 3000: '自营提成',
3000: '保底采购',
4000: '业主自营',
};
const descirption = (
<>
<Descriptions column={4}>
<Descriptions.Item label="开始日期">{moment(contractDetail?.COMPACT_STARTDATE).format('YYYY-MM-DD')}</Descriptions.Item>
<Descriptions.Item label="截止日期">{moment(contractDetail?.COMPACT_ENDDATE).format('YYYY-MM-DD')}</Descriptions.Item>
<Descriptions.Item label="合同编号">{contractDetail?.COMPACT_CODE}</Descriptions.Item>
{/* <Descriptions.Item label="">{contractDetail?.STAFF_NAME}</Descriptions.Item>
<Descriptions.Item label="更新时间">{moment(contractDetail?.OPERATE_DATE).format('YYYY-MM-DD HH:mm:ss')}</Descriptions.Item>
<Descriptions.Item label="承办人">{contractDetail?.ORGANIZER_LINKMAN}</Descriptions.Item>
<Descriptions.Item label="承办部门">{contractDetail?.ORGANIZER}</Descriptions.Item> */}
</Descriptions>
<Descriptions column={4}>
<Descriptions.Item label="经营模式" labelStyle={{ fontWeight: 'bold' }} contentStyle={{ color: '#ff4d4f' }}>{contractType[subDetail?.BUSINESS_TYPE]}</Descriptions.Item>
<Descriptions.Item label="结算模式" labelStyle={{ fontWeight: 'bold' }} contentStyle={{ color: '#ff4d4f' }}>
{settlementModeObj[subDetail?.SETTLEMENT_MODES]}
{
afterChangeSwitch ? `->${settlementModeObj[afterChangeSwitch]}` : ''
}
</Descriptions.Item>
<Descriptions.Item label="结算周期" labelStyle={{ fontWeight: 'bold' }} contentStyle={{ color: '#ff4d4f' }}>{settlementCycleObj[subDetail?.SETTLEMENT_CYCLE]}</Descriptions.Item>
</Descriptions>
{/* <ProDescriptions */}
{/* dataSource={subDetail} */}
{/* columns={headerColumns} */}
{/* labelStyle={{ fontWeight: 'bold' }} */}
{/* contentStyle={{ color: '#ff4d4f' }} */}
{/* column={4} */}
{/* /> */}
<Descriptions column={1}>
<Descriptions.Item label="经营门店">
{/* {shopName && shopName.length > 0 ? shopName?.map((n, i) => (n ? <Tag color={colors[i]} key={i}>{n}</Tag> : '')) : '-'} */}
{shopName ? shopName.toString() : ''}
</Descriptions.Item>
</Descriptions>
{/* <Descriptions column={2}> */}
{/* <Descriptions.Item label="附件信息"> */}
{/* { */}
{/* fileList ? */}
{/* <Upload */}
{/* defaultFileList={fileList || []} */}
{/* showUploadList={{ */}
{/* showDownloadIcon: false, */}
{/* showRemoveIcon: false, */}
{/* }} */}
{/* /> : '-' */}
{/* } */}
{/* </Descriptions.Item> */}
{/* { */}
{/* relatedContractsList && relatedContractsList.length>0? */}
{/* <Descriptions.Item label="关联合同列表"> */}
{/* { */}
{/* relatedContractsList.map((item: any)=>{ */}
{/* return <span>{`${item.COMPACT_NAME}(${COMPACTLISTS[item.COMPACT_DETAILS]})`}</span> */}
{/* }) */}
{/* } */}
{/* </Descriptions.Item>:'' */}
{/* } */}
{/* </Descriptions> */}
</>
)
const columns: any = [
{
title: '合同类型',
dataIndex: 'COMPACT_TYPE',
key: 'COMPACT_TYPE',
valueType: 'select',
request: async () => {
const options = session.get("COMPACT_CHARACTERList")
return options;
}
},
{
title: '合同类型子项',
dataIndex: 'COMPACT_DETAILS',
key: 'COMPACT_DETAILS',
valueType: 'select',
valueEnum: COMPACTLISTS,
render: (_, record) => {
return <>
{/* style={{ */}
{/* cursor: record?.REGISTERCOMPACT_HOSTID ? 'pointer' : '', */}
{/* color: record?.REGISTERCOMPACT_HOSTID ? '#1890ff' : '' */}
{/* }} */}
{
record.COMPACT_DETAILS === 1000 ? <span>{COMPACTLISTS[record.COMPACT_DETAILS]}</span> :
<span onClick={() => {
// if (record?.REGISTERCOMPACT_HOSTID) {
// setAssociationRow(record)
// setAssociationDrawer(true)
// }
}}>
{COMPACTLISTS[record.COMPACT_DETAILS]}
{/* {COMPACTLISTS && COMPACTLISTS.length>0?COMPACTLISTS.filter(item=> item.value===record.COMPACT_DETAILS)[0].label:''} */}
</span>
}
</>
}
},
{
title: '签订程序',
dataIndex: 'ORGANIZER_TEL',
valueType: 'select',
request: async () => {
const options = session.get('COMPACTREGPROINSTList')
return options;
}
},
{
title: '合同附属类型',
dataIndex: '',
render: () => {
return subDetail?.COMPACT_CHILDTYPE ?
compactType?.find(n => n.value === subDetail?.COMPACT_CHILDTYPE)?.label : '-'
}
},
];
const severpartType: any = {
// 服务区类型
1000: 'A类',
2000: 'B类',
3000: 'C类',
4000: '其他',
};
const businessType: any = {
// 经营业态
1: '主餐饮类',
2: '面馆小吃类',
3: '轻饮食、食品类',
4: '特产、工艺品等其他类',
5: '汽修类',
};
const subClumns: any = [
{
title: '服务区类型',
key: 'SERVERPART_TYPE',
dataIndex: 'SERVERPART_TYPE',
valueType: 'select',
valueEnum: severpartType
},
{
title: '经营业态',
key: 'BUSINESS_TRADE',
dataIndex: 'BUSINESS_TRADE',
valueType: 'select',
valueEnum: businessType
},
{
title: '经营品牌',
key: 'BRAND_NAME',
dataIndex: 'BRAND_NAME',
valueType: 'text',
},
{
title: '经营面积',
key: 'OPERATING_AREA',
dataIndex: 'OPERATING_AREA',
valueType: 'text',
render: (value) => {
return value ? `${value}` : '-'
}
},
// {
// title: '结算周期',
// key: 'SETTLEMENT_CYCLE',
// dataIndex: 'SETTLEMENT_CYCLE',
// valueType: 'select',
// request: async () => {
// const options = session.get("SETTLEMENT_CYCLEList");
// return options
// }
// },
{
title: '所属区域',
key: 'SERVERPARTREGION',
dataIndex: 'SERVERPARTREGION',
valueType: 'select',
request: async () => {
const options = session.get("shopregionList")
return options;
},
fieldProps: {
mode: 'multiple'
}
},
{
title: '物业费',
key: 'PROPERTY_FEE',
dataIndex: 'PROPERTY_FEE',
valueType: 'digit',
render: (value) => {
return value ? `${value}元/月` : '-'
}
},
// {
// title: '结算模式',
// key: 'SETTLEMENT_MODES',
// dataIndex: 'SETTLEMENT_MODES',
// valueType: 'select',
// request: async () => {
// const options = session.get("SETTLEMENT_MODESList");
// return options;
// }
// },
{
title: '免租开始时间',
key: 'RENTFREE_STARTDATE',
dataIndex: 'RENTFREE_STARTDATE',
valueType: 'date',
fieldProps: {
format: 'YYYY/MM/DD',
},
},
{
title: '免租结束时间',
key: 'RENTFREE_ENDDATE',
dataIndex: 'RENTFREE_ENDDATE',
valueType: 'date',
fieldProps: {
format: 'YYYY/MM/DD',
},
},
{
title: '装修开始时间',
key: 'DECORATE_STARTDATE',
dataIndex: 'DECORATE_STARTDATE',
valueType: 'date',
fieldProps: {
format: 'YYYY/MM/DD',
},
},
{
title: '装修结束时间',
key: 'DECORATE_ENDDATE',
dataIndex: 'DECORATE_ENDDATE',
valueType: 'date',
fieldProps: {
format: 'YYYY/MM/DD',
},
},
{
title: '工程保修期限',
key: 'REPAIR_TIME',
dataIndex: 'REPAIR_TIME',
valueType: 'text',
render: (value) => {
return value ? `${value}` : '-'
}
},
]
return (
<PageContainer // header={{ title: contractDetail?.COMPACT_NAME }}
loading={detailLoading}
header={{
title: contractDetail?.COMPACT_NAME,
breadcrumb: {},
}}
content={
<Row gutter={14}>
<Col span={16}>
{descirption}
</Col>
{/* <Col span={4}>
<Statistic className="contract-static-card" title="合同主体"
value={contractDetail?.SERVERPART_NAME}
valueStyle={{ fontSize: 24, lineHeight: 2.5, color: "#595959" }} />
</Col>
<Col span={4}>
<Statistic className="contract-static-card" title="合同金额" valueStyle={{
color: "#FFA74F",
fontSize: 14,
}}
valueRender={() => {
return <Space align="baseline">
<span className="amount">{contractDetail?.COMPACT_AMOUNT}</span><span>()</span>
</Space>
}} />
</Col> */}
<Col span={4}>
<Statistic className="contract-static-card"
title={contractDetail?.COMPACT_AMOUNT ? amountDom(contractDetail?.COMPACT_AMOUNT) : ""}
valueStyle={{ color: "#00000075", fontSize: 14 }}
value={'合同金额'}
/>
</Col>
<Col span={4}>
<Statistic className="contract-static-card"
title={<span style={{ fontSize: 20, color: "#262626" }}>{contractDetail?.SERVERPART_NAME}</span>}
valueStyle={{ color: "#00000075", fontSize: 14, marginTop: 10 }}
value={"合同主体"}
/>
</Col>
<Col span={24}>
<Descriptions column={2}>
<Descriptions.Item label="附件信息">
{
fileList ?
<Upload
defaultFileList={fileList || []}
showUploadList={{
showDownloadIcon: false,
showRemoveIcon: false,
}}
/> : '-'
}
</Descriptions.Item>
{
relatedContractsList && relatedContractsList.length > 0 ?
<Descriptions.Item label="关联合同列表" style={{ position: 'relative' }}>
<div style={{ display: "block" }}>
{
relatedContractsList.map((item: any) => {
return <div style={{ display: 'flex', alignItems: 'center' }}>
<span style={{
color: '#1890ff',
cursor: 'pointer'
}} onClick={() => {
console.log('item', item);
console.log('historyList.current', historyList.current);
console.log('clickedId', clickedId);
if (clickedId && clickedId.indexOf(item.REGISTERCOMPACT_ID) === -1) {
let list: any = JSON.parse(JSON.stringify(clickedId))
list.push(item.REGISTERCOMPACT_ID)
historyList.current = list
console.log('historyList.current', historyList.current);
setChildrenRow(item)
setShowChildDetailDrawer(true)
}
}}>{`${item.COMPACT_NAME}(${COMPACTLISTS[item.COMPACT_DETAILS]})`}</span>
{
item.ATTACHMENT_STATE === 1000 ?
<img
style={{ width: '15px', height: '15px', marginLeft: '15px', cursor: 'pointer' }}
src={fileIcon}
onClick={async () => {
const data = await getPictureList(item.REGISTERCOMPACT_ID, '1115')
const files = data && data?.total > 0 ? data?.data.map((n: PictureModel) => {
return {
uid: n.ImageId,
name: n.ImageName,
status: 'done',
url: n.ImageUrl,
deletepath: n.ImagePath
}
}) : []
setChildrenFile(files)
setShowChildrenFile(true)
}}
/> : ''
}
</div>
})
}
</div>
{
contractDetail && contractDetail.LogList && contractDetail.LogList.length > 0 ?
<img style={{
cursor: 'pointer',
width: '20px',
height: '20px',
position: 'absolute',
right: 0,
top: 0
}} onClick={(e) => {
setShowLogDrawer(true)
}} src={'https://eshangtech.com/ShopICO/ahyd-BID/newIndex3/noticeIcon.svg'} /> : ''
}
</Descriptions.Item> : ''
}
</Descriptions>
</Col>
</Row>
}
>
<>
<Card title={<div className="card-title"></div>} bordered={false}>
<ProDescriptions
dataSource={contractDetail}
columns={columns}
column={4}
/>
<ProDescriptions
title="甲方信息"
dataSource={contractDetail}
columns={[{
title: '名称',
key: 'FIRSTPART_NAME',
dataIndex: 'FIRSTPART_NAME',
span: 2
}, {
title: '联系人',
key: 'FIRSTPART_LINKMAN',
dataIndex: 'FIRSTPART_LINKMAN',
}, {
title: '联系电话',
key: 'FIRSTPART_MOBILE',
dataIndex: 'FIRSTPART_MOBILE',
},]} column={4} />
<ProDescriptions
title="乙方信息"
dataSource={contractDetail}
columns={[{
title: '名称',
key: 'SECONDPART_NAME',
dataIndex: 'SECONDPART_NAME',
span: 2
}, {
title: '联系人',
key: 'SECONDPART_LINKMAN',
dataIndex: 'SECONDPART_LINKMAN',
}, {
title: '联系电话',
key: 'SECONDPART_MOBILE',
dataIndex: 'SECONDPART_MOBILE',
},
]} column={4} />
{(contractDetail?.THREEPART_LINKMAN || contractDetail?.THREEPART_MOBILE || contractDetail?.THREEPART_NAME) && <ProDescriptions title="丙方信息" column={4}
dataSource={contractDetail}
columns={[{
title: '名称',
key: 'THREEPART_NAME',
dataIndex: 'THREEPART_NAME',
span: 2
}, {
title: '联系人',
key: 'THREEPART_LINKMAN',
dataIndex: 'THREEPART_LINKMAN',
}, {
title: '联系电话',
key: 'THREEPART_MOBILE',
dataIndex: 'THREEPART_MOBILE',
}]}
/>}
</Card>
<Card title={<div className="card-title"></div>} bordered={false} style={{ marginTop: 24 }}>
<ProDescriptions dataSource={contractDetail} columns={[
{
title: '合同开始日期',
key: 'COMPACT_STARTDATE',
dataIndex: 'COMPACT_STARTDATE',
valueType: 'date',
fieldProps: {
format: 'YYYY/MM/DD',
},
},
{
title: '合同截止日期',
key: 'COMPACT_ENDDATE',
dataIndex: 'COMPACT_ENDDATE',
valueType: 'date',
fieldProps: {
format: 'YYYY/MM/DD',
},
},
{
title: '合同期限',
key: 'DURATIONDAY',
dataIndex: 'DURATIONDAY',
render: (value) => {
return value ? `${value}` : '-'
}
},
{
title: '合同年限',
key: 'DURATION',
dataIndex: 'DURATION',
render: (value, record) => {
return record?.RENEWAL_YEARS ? `${value}+${record?.RENEWAL_YEARS}` : value ? `${value}` : '-'
}
},
]} column={4}>
</ProDescriptions >
<ProDescriptions dataSource={contractDetail} columns={[
// {
// title: '应到账日期',
// key: 'COMPACT_ACCOUNTDATE',
// dataIndex: 'COMPACT_ACCOUNTDATE',
// valueType: 'date',
// fieldProps: {
// format: 'YYYY/MM/DD',
// },
// span: 1.5
// },
{
title: '履约保证金',
key: 'SECURITYDEPOSIT',
dataIndex: 'SECURITYDEPOSIT',
valueType: 'text',
render: (value) => {
return value ? `${value}万元` : '-'
}
},
// {
// title: '到账日期',
// key: 'SECURITYDEPOSIT_STARTDATE',
// dataIndex: 'SECURITYDEPOSIT_STARTDATE',
// valueType: 'date',
// fieldProps: {
// format: 'YYYY/MM/DD',
// },
// },
// {
// title: '退款日期',
// key: 'SECURITYDEPOSIT_ENDDATE',
// dataIndex: 'SECURITYDEPOSIT_ENDDATE',
// valueType: 'date',
// fieldProps: {
// format: 'YYYY/MM/DD',
// },
// }
// ]} column={4}>
// </ProDescriptions >
// <ProDescriptions dataSource={contractDetail} columns={[
// {
// title: '安全风险抵押金',
// key: 'SAFETYRISKMORTGAGE',
// dataIndex: 'SAFETYRISKMORTGAGE',
// valueType: 'text',
// render: (value) => {
// return value ? `${value}万元` : '-'
// }
// },
// {
// title: '到账日期',
// key: 'SAFETYRISKMORTGAGE_STARTDATE',
// dataIndex: 'SAFETYRISKMORTGAGE_STARTDATE',
// valueType: 'date',
// fieldProps: {
// format: 'YYYY/MM/DD',
// },
// },
// {
// title: '退款日期',
// key: 'SAFETYRISKMORTGAGE_ENDDATE',
// dataIndex: 'SAFETYRISKMORTGAGE_ENDDATE',
// valueType: 'date',
// fieldProps: {
// format: 'YYYY/MM/DD',
// },
// }
]} column={4}>
</ProDescriptions>
</Card>
<Card title={<div className="card-title"></div>} bordered={false} style={{ padding: 0, marginTop: 24 }}>
<ProDescriptions dataSource={subDetail} loading={loading} columns={subClumns} column={4} />
<ProDescriptions dataSource={subDetail} loading={loading} columns={[
{
title: '经营范围',
key: 'OPERATING_SCOPE',
dataIndex: 'OPERATING_SCOPE',
span: 2
},
{
title: '经营场地',
key: 'OPERATING_SITE',
dataIndex: 'OPERATING_SITE',
span: 2
},
]} column={4} />
</Card>
<Card title={<div className="card-title"></div>} bordered={false} style={{ padding: 0, marginTop: 24, marginBottom: 24 }}>
<ProDescriptions dataSource={subDetail} loading={loading} columns={[
{
title: '设备押金',
key: 'EQUIPMENT_DEPOSIT',
dataIndex: 'EQUIPMENT_DEPOSIT',
valueType: 'digit',
render: (value) => {
return value ? `${value}` : '-'
}
},
{
title: '水费',
key: 'WATER_CHARGE',
dataIndex: 'WATER_CHARGE',
render: (value) => {
return value ? `${value}元/吨` : '-'
}
},
{
title: '电费',
key: 'ELECTRICITY_FEES',
dataIndex: 'ELECTRICITY_FEES',
render: (value) => {
return value ? `${value}元/度` : '-'
}
},
{
title: '其他费用',
key: 'OTHER_SCHARGE',
dataIndex: 'OTHER_SCHARGE',
},
{
title: '合同注意事项',
key: 'COMPACT_DPDESC',
dataIndex: 'COMPACT_DPDESC',
span: 2,
render: (value) => {
return <span style={{ whiteSpace: 'pre-wrap' }}>{value || '-'}</span>
}
},
{
title: '招商依据',
key: 'COMPACT_BASIS',
dataIndex: 'COMPACT_BASIS',
span: 2
},
]} column={4} />
</Card>
</>
<Drawer
width="73%"
visible={associationDrawer}
onClose={() => {
setAssociationRow(undefined);
setAssociationDrawer(false);
}}
closable={false}
destroyOnClose
bodyStyle={{ backgroundColor: "#f9f9f9", padding: 0 }}
>
<ContractDetailDrawer contractId={associationRow?.REGISTERCOMPACT_HOSTID} ></ContractDetailDrawer>
</Drawer>
{/* 关联合同的详情抽屉 */}
<Drawer
width="73%"
visible={showChildDetailDrawer}
onClose={() => {
setShowChildDetailDrawer(false)
setChildrenRow(undefined)
}}
destroyOnClose
title={'关联合同详情'}
closable={false}
bodyStyle={{ backgroundColor: "#f9f9f9", padding: 0 }}
>
<ContractDetailDrawer contractId={childrenRow?.REGISTERCOMPACT_ID} clickedId={historyList.current} />
</Drawer>
{/* 日志抽屉 */}
<Drawer
width="30%"
visible={showLogDrawer}
onClose={() => {
setShowLogDrawer(false)
}}
destroyOnClose
title={'日志详情'}
closable={false}
bodyStyle={{ backgroundColor: "#f9f9f9", padding: 16 }}
>
{
contractDetail && contractDetail.LogList && contractDetail.LogList.length > 0 ?
contractDetail.LogList.map((item: any, index: number) => {
return <div style={{ marginBottom: '16px' }}>
{`${index + 1}${item.BUSINESSLOG_CONTENT}`}
</div>
}) : ''
}
</Drawer>
{/* 显示关联合同附件 */}
<Modal
title={'关联合同附件'}
open={showChildrenFile}
onCancel={() => {
setShowChildrenFile(false)
}}
footer={false}
>
<Upload
defaultFileList={childrenFile || []}
showUploadList={{
showDownloadIcon: false,
showRemoveIcon: false,
}}
/>
</Modal>
</PageContainer>
);
}
export default ContractDetailDrawer;

View File

@ -0,0 +1,11 @@
.assetsDetailDrawer{
.AssetsDetail{
.drawerTitle{
font-size: 20px;
font-weight: 600;
}
}
}
.ant-drawer-header{
border-bottom: 0px;
}

View File

@ -0,0 +1,243 @@
/*
* @Author: cclu 1106109051@qq.com
* @Date: 2024-07-31 15:19:37
* @LastEditors: cclu 1106109051@qq.com
* @LastEditTime: 2024-08-30 14:38:09
* @FilePath: \cloud-platform\src\pages\basicManage\serverpartAssets\component\assetsDetail.tsx
* @Description: ,`customMade`, koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { useState } from "react";
import { connect } from "umi";
import { getFieldEnum, handleGetPictureList, handleGetPROPERTYASSETSDetail, handleGetServerpartTree } from "../service";
import { Button, Divider, Tabs, Image } from "antd";
import { ProDescriptions } from "@ant-design/pro-components";
import StoreInfor from "./storeInfor";
import LogList from "./logList";
import ContractDetail from "./contractDetail";
type DetailProps = {
currentRow: any;
currentUser?: any
}
const AssetsDetail = ({ currentRow, currentUser }: DetailProps) => {
// 资产详情
const [assetsDetail, setAssetsDetail] = useState<any>()
// 选择的tab
const [selectTab, setSelectTab] = useState<string>('1')
// 与资产关联的门店数据
const [relatedShopData, setRelatedShopData] = useState<any>()
// 上传平面图的图片列表
const [fileList, setFileList] = useState<any>()
// 预览图片
const [imagePreviewVisible, setImagePreviewVisible] = useState<boolean>(false)
// 已经请求完详情 可以将数据给下面的几个tab了
const [detailIsOK, setDetailIsOk] = useState<boolean>(false)
// 项目和合同的数据
const [projectCOMPACTDataList, setProjectCOMPACTDataList] = useState<any>()
// 资产详情显示的内容
const columns: any = [
{
title: '服务区名称',
dataIndex: 'SERVERPART_ID',
valueType: 'select',
request: async () => {
const req: any = {
ProvinceCode: currentUser?.ProvinceCode,
ServerpartType: 1000,
StatisticsType: 1000,
ShowWholePower: false,
ShowSPRegion: false,
ShowRoyalty: false,
ShowCompactCount: false,
}
const data = await handleGetServerpartTree(req)
return data
}
},
{
title: '资产名称',
dataIndex: 'PROPERTYASSETS_NAME'
},
{
title: '资产编码',
dataIndex: 'PROPERTYASSETS_CODE'
},
{
title: '资产类型',
dataIndex: 'PROPERTYASSETS_TYPE',
valueType: 'select',
request: async () => {
const list = await getFieldEnum({ FieldExplainField: 'PROPERTYASSETS_TYPE', notformate: true })
return list
}
},
{
title: '面积',
dataIndex: 'PROPERTYASSETS_AREA'
},
{
title: '有效状态',
dataIndex: 'PROPERTYASSETS_STATE',
valueType: 'select',
valueEnum: {
1: '有效',
0: '无效',
}
},
{
title: '说明信息',
dataIndex: 'PROPERTYASSETS_INFO',
span: 24
},
{
title: '备注',
dataIndex: 'PROPERTYASSETS_DESC',
span: 24
},
{
title: '',
dataIndex: '',
span: 24,
render: (_, record) => {
return <>
{
fileList && fileList.length > 0 ?
<Button type={"primary"} onClick={() => {
handlePreview()
}}></Button> : ''
}
</>
}
},
]
// tab的列表
const tabList: any = [
{
key: '1',
label: '门店信息',
},
// {
// key: '2',
// label: '项目合同',
// },
// {
// key: '3',
// label: '经营项目',
// },
{
key: '3',
label: '修改日志',
},
]
// 预览上传后的图片
const handlePreview = async () => {
setFileList(fileList)
setImagePreviewVisible(true)
};
return (
<div className={"AssetsDetail"}>
<div className={"drawerTitle"}>{currentRow?.PROPERTYASSETS_NAME ? `${assetsDetail?.PropertyShop?.SERVERPART_NAME}${currentRow?.PROPERTYASSETS_NAME}详情` : ''}</div>
{/* 资产详情部分 */}
<div>
<Divider orientation="left"></Divider>
<ProDescriptions
request={async () => {
console.log('currentRow', currentRow);
const data = await handleGetPROPERTYASSETSDetail({ PROPERTYASSETSId: currentRow?.PROPERTYASSETS_ID })
console.log('detail', data);
setAssetsDetail(data)
setRelatedShopData(data.PropertyShop)
setProjectCOMPACTDataList(data.BusinessProjectList)
setDetailIsOk(true)
// 去拿图片列表
const imgReq: any = {
TableId: data.SERVERPART_ID,
TableType: 1201,
ImageIndex: data.PROPERTYASSETS_REGION
}
const imgData = await handleGetPictureList(imgReq)
console.log('imgData', imgData);
let imgList: any = imgData.List
let realImgList: any = []
if (imgList && imgList.length > 0) {
imgList.forEach((item: any) => {
realImgList.push({
uid: item.ImageId,
name: item.ImageName,
status: 'done',
url: item.ImageUrl,
imgUrl: item.ImagePath,
})
})
}
setFileList(realImgList)
console.log('data', data);
return { data: data, success: true }
}}
columns={columns}
>
</ProDescriptions>
</div>
<div style={{ marginTop: '16px' }}>
<Tabs
activeKey={selectTab}
items={tabList}
onChange={(e: any) => {
setSelectTab(e)
}}
>
</Tabs>
{/* 门店信息 */}
{
selectTab === '1' ? <StoreInfor detailData={relatedShopData} onShow={detailIsOK} /> : ''
}
{/* 合同详情 */}
{
selectTab === '2' ? <ContractDetail detail={currentRow} tableData={projectCOMPACTDataList} /> : ''
}
{/*
{
selectTab === '3'? <BusinessProject/>:''
} */}
{/* 修改日志 */}
{
selectTab === '3' ? <LogList detail={assetsDetail} /> : ''
}
</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>}
</div >
)
}
export default connect(({ user, }: ConnectState) => ({
}))(AssetsDetail);

View File

@ -0,0 +1,927 @@
import { Button, Col, Divider, Drawer, message, Row, Image } from "antd";
import { useEffect, useRef, useState } from "react";
import { connect } from "umi";
import { getFieldEnumTreeNoSession, handleDeletePicture, handleGetBatchPROPERTYSHOP, handleGetBusinessProjectList, handleGetPictureList, handleGetPROPERTYASSETSDetail, handleGetProvinceVehicleDetail, handleGetServerpartInfo, handleGetServerpartTree, handleGetSynchroPROPERTYSHOP, handleSynchroPROPERTYASSETS, uploadAHYDPicture } from "../service";
import moment from "moment";
import { ProForm, ProFormSelect, ProFormText, ProFormTreeSelect, ProFormUploadButton } from "@ant-design/pro-components";
import RelatedShop from "./relatedShop";
import AssetsDetail from "./assetsDetail";
import HistoryTable from "./historyTable";
type DetailProps = {
onShow: any // 控制组件是否显示
setOnShow: any // 关闭抽屉
handleClose?: any // 组件的关闭事件
currentUser?: any
id: any
parentRef?: any // 上一级 可能需要刷新表格的
onlyRead?: boolean // 抽屉底部不显示任何关于编辑新增的按钮
serverPartShopId?: any // 有id 或者门店id和服务区id同时存在
SERVERPARTID?: any
}
const LeftSelectTree = ({ onShow, handleClose, setOnShow, currentUser, id, parentRef, onlyRead, serverPartShopId, SERVERPARTID }: DetailProps) => {
const formAssetsRef = useRef<any>();
const relatedShopRef = useRef<any>()
const historyTableRef = useRef<any>()
// 点击的资产详情
const [assetsDetail, setAssetsDetail] = useState<any>()
// 点击行的数据
const [currentRow, setCurrentRow] = useState<any>()
// 是否正在提交
const [isSubmit, setIsSubmit] = useState<boolean>(false)
// 关联门店的id
const [selectShopId, setSelectShopId] = useState<any>()
// 资产详情抽屉
const [assetsDetailDrawer, setAssetsDetailDrawer] = useState<boolean>(false)
// 关联历史门店的抽屉
const [showHistory, setShowHistory] = useState<boolean>(false)
// 默认选中门店的行号列表
const [defaultSelectList, setDefaultSelectList] = useState<any>()
// 上传平面图的图片列表
const [fileList, setFileList] = useState<any>()
// 服务区方位根据服务区动态变化的选择数据
const [selectRegionList, setSelectRegionList] = useState<any>()
// 判断资产编码是否必填 资产类型是商铺的时候必填
const [assetsCodeRequired, setAssetsCodeRequired] = useState<boolean>(false)
// 资产类型
const [PROPERTYASSETSTYPE, setPROPERTYASSETSTYPE] = useState<any>()
// 预览图片
const [imagePreviewVisible, setImagePreviewVisible] = useState<boolean>(false)
// 关联门店抽屉
const [relatedShopModal, setRelatedShopModal] = useState<boolean>(false)
// 校验图片大小
const beforeUpload = (file: any) => {
formAssetsRef.current?.validateFields(['SERVERPART_ID', 'PROPERTYASSETS_REGION']).then(async (res) => {
console.log('file', file);
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
message.error('你只能上传 JPG或PNG 格式的图片文件!');
setFileList([])
return isJpgOrPng;
}
console.log('2');
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
message.error('图片大小不超过 2MB!');
}
return isJpgOrPng && isLt2M;
}).catch(() => {
setFileList([])
return false
})
}
// 预览上传后的图片
const handlePreview = async () => {
setFileList(fileList)
setImagePreviewVisible(true)
};
// 保存和新增的方法
const handleCreateAssets = async (type: string) => {
// type add的时候是新增 type 是save的时候是保存
// 新增不会关闭抽屉 表格会刷新 只会清空资产类型、资产编码、资产名称、面积。。。。 即不是方位和服务区的内容清空掉
// 保存是会关闭整个抽屉 跟老的走一样的
// 新增在编辑的时候不会出现
console.log('assetsDetail', assetsDetail);
// if (!selectShopId?.SERVERPARTSHOP_ID && !assetsDetail?.PropertyShop?.SERVERPARTSHOP_ID) {
// message.error('请先选择关联门店!')
// return
// }
formAssetsRef.current?.validateFields().then(async (res) => {
// 因为现在有连续新增 所以在每一次的新增前都要去判断一下 这一次新增的编码 在这个服务区的这个方位是否已经有了
// 编辑不用判断
if (!currentRow?.PROPERTYASSETS_ID) {
const req: any = {
SearchParameter: {
SERVERPART_IDS: res?.SERVERPART_ID,
// PROPERTYASSETS_REGION: res?.PROPERTYASSETS_REGION,
PROPERTYASSETS_STATE: 1
},
PageIndex: 1,
PageSize: 999999
}
const data = await handleGetProvinceVehicleDetail(req)
console.log('32131231', data);
// 默认设置为没有一样的 有一样的就变true
let isSame: boolean = false
let sameObj: any = {}
if (data && data.length > 0) {
data.forEach((item: any) => {
if (item.PROPERTYASSETS_CODE === res.PROPERTYASSETS_CODE) {
isSame = true
sameObj = item
}
})
}
console.log('sameObj', sameObj);
if (isSame) {
message.error(`${sameObj?.PROPERTYASSETS_CODE}已与${sameObj?.SHOPNAME}关联,如需修改,请先删除关联!`)
return
}
}
console.log('res', res);
let req: any = {}
setIsSubmit(true)
// if (type === 'save') {
// setIsSubmit(true)
// }
if (currentRow?.PROPERTYASSETS_ID) {
// 编辑
req = {
...assetsDetail,
...res,
OPERATOR_ID: currentUser?.ID,
OPERATOR_NAME: currentUser?.Name,
OPERATE_DATE: moment().format('YYYY-MM-DD HH:mm:ss')
}
} else {
// 新增
req = {
...res,
STAFF_ID: currentUser?.ID,
STAFF_NAME: currentUser?.Name,
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')
}
}
console.log('req', req);
const data = await handleSynchroPROPERTYASSETS(req)
console.log('data', data);
if (data.Result_Code === 100) {
console.log('relatedShopRef', relatedShopRef);
console.log('currentRow', currentRow);
message.success(data.Result_Desc)
// 拿到关联门店的id
let shopIdList: any = relatedShopRef.current?.selectModalRowList
let shopIdObj: any = {}
if (shopIdList && shopIdList.length > 0) {
shopIdObj = shopIdList[0]
console.log('shopIdObj', shopIdObj);
}
setSelectShopId(shopIdObj)
if (shopIdList && shopIdList.length > 0 && PROPERTYASSETSTYPE !== 1) {
await handleGetShopRelateAssets(data.Result_Data, shopIdObj)
}
if (parentRef) {
parentRef.current?.reload()
}
} else {
message.error(data.Result_Desc)
}
console.log('typetype', type);
if (type === 'save') {
// 现在要求保存的时候也不关闭 抽屉 但是点了保存 整个抽屉的内容要重新刷新
// setAssetsDrawer(false);
// setCurrentRow(undefined);
// setIsSearchDetail(false)
// setAssetsCodeRequired(false)
// setSelectShopId(undefined)
// setSelectRegionList([])
// setFileList([])
setIsSubmit(false)
setAssetsDetail(undefined);
setDefaultSelectList([])
// 重新拿一下详情
if (id) {
const req: any = {
PROPERTYASSETSId: id
}
const detailData = await handleGetPROPERTYASSETSDetail(req)
console.log('detail', detailData);
setDefaultSelectList([`${detailData?.PROPERTYASSETS_CODE}-${detailData?.PropertyShop?.SERVERPARTSHOP_ID}`])
setAssetsDetail(detailData)
// 详情表单刷新
// formAssetsRef.current?.reload()
// 选择门店的列表刷新
relatedShopRef.current?.setSelectedModalOrderRowKeys([`${detailData?.PROPERTYASSETS_CODE}-${detailData?.PropertyShop?.SERVERPARTSHOP_ID}`])
}
relatedShopRef.current?.handleReloadTable()
} else {
// 老表单保存的内容
let oldObj: any = {
SERVERPART_ID: res.SERVERPART_ID,
PROPERTYASSETS_REGION: res.PROPERTYASSETS_REGION
}
// 清空关联门店
setSelectShopId(undefined)
formAssetsRef.current?.resetFields()
formAssetsRef.current?.setFieldsValue(oldObj)
if (data.Result_Data && data) {
// 重新拿一下详情
const req: any = {
PROPERTYASSETSId: data.Result_Data.PROPERTYASSETS_ID
}
const detailData = await handleGetPROPERTYASSETSDetail(req)
console.log('detail', detailData);
setDefaultSelectList([`${detailData?.PROPERTYASSETS_CODE}-${detailData?.PropertyShop?.SERVERPARTSHOP_ID}`])
console.log('[`${detailData?.PROPERTYASSETS_CODE}-${detailData?.PropertyShop?.SERVERPARTSHOP_ID}`]', [`${detailData?.PROPERTYASSETS_CODE}-${detailData?.PropertyShop?.SERVERPARTSHOP_ID}`]);
setAssetsDetail(detailData)
setIsSubmit(false)
}
relatedShopRef.current?.setSelectedModalOrderRowKeys([])
relatedShopRef.current?.handleReloadTable()
}
})
}
// 将资产跟门店关联
const handleGetShopRelateAssets = async (obj: any, shopId: any) => {
console.log('obj', obj);
console.log('详情', assetsDetail);
console.log('选择的', shopId);
if (assetsDetail) {
if (assetsDetail?.PropertyShop?.PROPERTYSHOP_ID === shopId) {
return
}
}
// 没有选择的话就不调了
if (!shopId) {
return
}
// PROPERTYSHOP_ID 表示已经关联过了 这一次是修改 所以只能从详情里面拿到
// SERVERPART_ID PROPERTYASSETS_ID 虽然详情里面也有 但是如果是新增的话 详情是没有值的 所以只能取接口返回的回参
// SERVERPARTSHOP_ID 进到这一步 说明要么是第一次关联 要么是修改过的 所以用选择的数据 合适
// 要判断是不是新增 新增要传创建人 编辑就操作人
let req: any = {}
let reqList: any = []
// 去拿当前项目的开始结束时间
let projectReq: any = {
SearchParameter: {
SERVERPARTSHOP_ID: shopId?.SERVERPARTSHOP_ID,
PROJECT_VALID: 1
},
PageIndex: 1,
PageSize: 999999
}
const projectData = await handleGetBusinessProjectList(projectReq)
console.log('projectData', projectData);
let projectStart: any = ''
let projectEnd: any = ''
if (projectData && projectData.length > 0) {
projectStart = projectData[0].PROJECT_STARTDATE
projectEnd = projectData[0].PROJECT_ENDDATE
}
if (assetsDetail?.PropertyShop?.PROPERTYSHOP_ID) {
// 编辑
req = {
PROPERTYSHOP_ID: assetsDetail?.PropertyShop?.PROPERTYSHOP_ID,
SERVERPART_ID: obj.SERVERPART_ID,
PROPERTYASSETS_ID: obj.PROPERTYASSETS_ID,
SERVERPARTSHOP_ID: shopId.SERVERPARTSHOP_ID,
OPERATOR_ID: currentUser?.ID,
PROPERTYSHOP_STATE: 1,
OPERATOR_NAME: currentUser?.Name,
OPERATE_DATE: moment().format('YYYY-MM-DD HH:mm:ss'),
}
} else {
// 新增
req = {
SERVERPART_ID: obj.SERVERPART_ID,
PROPERTYASSETS_ID: obj.PROPERTYASSETS_ID,
SERVERPARTSHOP_ID: shopId.SERVERPARTSHOP_ID,
STAFF_ID: currentUser?.ID,
STAFF_NAME: currentUser?.Name,
PROPERTYSHOP_STATE: 1,
STARTDATE_Start: projectStart ? moment(projectStart).format('YYYY-MM-DD') : '',
STARTDATE_End: projectEnd ? moment(projectEnd).format('YYYY-MM-DD') : '',
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'),
}
}
console.log('req', req);
const data = await handleGetSynchroPROPERTYSHOP(req)
// handleGetSynchroPROPERTYSHOP 单个
// handleGetBatchPROPERTYSHOP 批量
console.log('data222222', data);
if (data.Result_Code === 100) {
// message.success(data.Result_Desc)
} else {
message.error(data.Result_Desc)
}
}
// 历史表格的提交
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 handleGetServicePic = async () => {
let res: any = formAssetsRef.current?.getFieldsValue()
console.log('res', res);
if (res?.PROPERTYASSETS_REGION && res?.SERVERPART_ID) {
const imgReq: any = {
TableId: res?.SERVERPART_ID,
TableType: 1201,
ImageIndex: res?.PROPERTYASSETS_REGION
}
const imgData = await handleGetPictureList(imgReq)
console.log('imgData', imgData);
let imgList: any = imgData.List
let realImgList: any = []
if (imgList && imgList.length > 0) {
imgList.forEach((item: any) => {
realImgList.push({
uid: item.ImageId,
name: item.ImageName,
status: 'done',
url: item.ImageUrl,
imgUrl: item.ImagePath,
})
})
}
setFileList(realImgList)
relatedShopRef.current?.handleReloadTable()
if (PROPERTYASSETSTYPE === 1) {
formAssetsRef.current?.setFieldsValue({ PROPERTYASSETS_CODE: `${res?.SERVERPART_ID}-${res?.PROPERTYASSETS_REGION}` })
}
} else {
setFileList([])
}
}
return (
<div>
{/* 编辑资产和新增资产的抽屉 */}
<Drawer
width={'80%'}
visible={onShow}
destroyOnClose
title={false}
closeIcon={false}
onClose={() => {
setOnShow(false)
setCurrentRow(undefined);
setAssetsDetail(undefined);
setDefaultSelectList([])
setAssetsCodeRequired(false)
setSelectShopId(undefined)
setIsSubmit(false)
setPROPERTYASSETSTYPE(undefined)
setFileList([])
setSelectRegionList([])
if (handleClose) {
handleClose()
}
}}
bodyStyle={{ backgroundColor: "#fff", padding: 16, paddingTop: 0 }}
footer={
<div style={{ width: '100%' }}>
{
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', boxSizing: 'border-box', paddingLeft: '16px' }}>
{/* <Button type={'primary'} onClick={() => {
formAssetsRef.current?.validateFields(['SERVERPART_ID', 'PROPERTYASSETS_REGION']).then(async (res) => {
setRelatedShopModal(true)
if (relatedShopRef.current?.handleReloadTable) {
relatedShopRef.current?.handleReloadTable()
}
})
}}>
</Button> */}
{/* 占位的div 如果上面的Button重新要显示 div就注释 */}
<div>
{
currentRow?.PROPERTYASSETS_ID ? <Button type={"primary"} onClick={() => {
setAssetsDetailDrawer(true)
}}></Button> : ''
}
</div>
<div>
{/* {
currentRow?.PROJECT_ENDDATE && new Date(moment(currentRow?.PROJECT_ENDDATE).format('YYYY-MM-DD')).getTime() > new Date('2024-01-01').getTime() ?
<Button type={"primary"} style={{ marginRight: '8px' }} onClick={() => {
setShowHistory(true)
}}></Button> : ''
} */}
{
onlyRead ? '' :
<>
<Button type={"primary"} style={{ marginRight: '8px' }} onClick={() => {
setShowHistory(true)
}}></Button>
{
currentRow?.PROPERTYASSETS_ID ? '' :
<Button loading={isSubmit} type={"primary"} style={{ marginRight: '8px' }} onClick={() => {
handleCreateAssets('add')
}}></Button>
}
<Button loading={isSubmit} type={"primary"} onClick={() => {
handleCreateAssets('save')
}}>
</Button>
</>
}
</div>
</div>
}
</div>
}
>
<Divider orientation="left">{currentRow?.PROPERTYASSETS_ID ? '编辑资产' : '新增资产'}</Divider>
<ProForm
layout={'horizontal'}
formRef={formAssetsRef}
labelCol={{ span: 5 }}
submitter={{
render: (_, record) => {
return []
}
}}
request={async () => {
console.log('serverPartShopId', serverPartShopId);
console.log('idid', id);
// 有 说明是编辑 默认去请求数据
if (id) {
const req: any = {
PROPERTYASSETSId: id
}
const data = await handleGetPROPERTYASSETSDetail(req)
console.log('detail', data);
setDefaultSelectList([`${data?.PROPERTYASSETS_CODE}-${data?.PropertyShop?.SERVERPARTSHOP_ID}`])
setAssetsDetail(data)
setCurrentRow(data)
// 去拿图片列表
const imgReq: any = {
TableId: data.SERVERPART_ID,
TableType: 1201,
ImageIndex: data.PROPERTYASSETS_REGION
}
const imgData = await handleGetPictureList(imgReq)
console.log('imgData', imgData);
let imgList: any = imgData.List
let realImgList: any = []
if (imgList && imgList.length > 0) {
imgList.forEach((item: any) => {
realImgList.push({
uid: item.ImageId,
name: item.ImageName,
status: 'done',
url: item.ImageUrl,
imgUrl: item.ImagePath,
})
})
}
setFileList(realImgList)
// 拿服务区方位列表
const regReq: any = {
ServerpartId: data.SERVERPART_ID
}
const regData = await handleGetServerpartInfo(regReq)
let list: any = regData.RegionInfo
if (list && list.length > 0) {
let res: any = []
list.forEach((item: any) => {
res.push({ label: item.SERVERPART_REGIONNAME, value: item.SERVERPART_REGION })
})
console.log('res', res);
setSelectRegionList(res)
// formAssetsRef.current?.setFieldsValue({ PROPERTYASSETS_REGION: res[0].value })
}
if (data.PROPERTYASSETS_TYPE === 1000) {
setAssetsCodeRequired(true)
}
setPROPERTYASSETSTYPE(data.PROPERTYASSETS_TYPE)
console.log('dajkdjasd', data);
return data
} else if (serverPartShopId) {
// 有门店但是没资产的点编辑进来
// 去拿图片列表
const imgReq: any = {
TableId: SERVERPARTID,
TableType: 1201,
ImageIndex: currentRow?.PROPERTYASSETS_REGION
}
const imgData = await handleGetPictureList(imgReq)
console.log('imgData', imgData);
let imgList: any = imgData.List
let realImgList: any = []
if (imgList && imgList.length > 0) {
imgList.forEach((item: any) => {
realImgList.push({
uid: item.ImageId,
name: item.ImageName,
status: 'done',
url: item.ImageUrl,
imgUrl: item.ImagePath,
})
})
}
setFileList(realImgList)
// 拿服务区方位列表
const regReq: any = {
ServerpartId: currentRow?.SERVERPART_ID || SERVERPARTID
}
const regData = await handleGetServerpartInfo(regReq)
let list: any = regData.RegionInfo
if (list && list.length > 0) {
let res: any = []
list.forEach((item: any) => {
res.push({ label: item.SERVERPART_REGIONNAME, value: item.SERVERPART_REGION })
})
console.log('res', res);
setSelectRegionList(res)
formAssetsRef.current?.setFieldsValue({
SERVERPART_ID: currentRow?.SERVERPART_ID || Number(SERVERPARTID),
PROPERTYASSETS_REGION: currentRow?.PROPERTYASSETS_REGION
})
}
return {
SERVERPART_ID: currentRow?.SERVERPART_ID || Number(SERVERPARTID),
PROPERTYASSETS_REGION: currentRow?.PROPERTYASSETS_REGION
}
}
return {}
}}
>
<Row gutter={16}>
<Col span={8}>
<ProFormSelect
label={'服务区名称'}
name={"SERVERPART_ID"}
disabled={id || (serverPartShopId && SERVERPARTID)}
request={async () => {
const req: any = {
ProvinceCode: currentUser?.ProvinceCode,
ServerpartType: 1000,
StatisticsType: 1000,
ShowWholePower: false,
ShowSPRegion: false,
ShowRoyalty: false,
ShowCompactCount: false,
}
const data = await handleGetServerpartTree(req)
// 去除安徽驿达
let list: any = []
if (data && data.length > 0) {
data.forEach((item: any) => {
if (item.value !== 424) {
list.push(item)
}
})
}
console.log('listlistlistlist', list);
return list
}}
rules={[
{
required: true,
message: '请选择服务区名称!',
},
]}
labelAlign={'right'}
fieldProps={{
showSearch: true,
onChange: async (e: any) => {
if (e) {
// 根据服务区去请求服务区方位列表 然后给方位列表显示
// 默认帮忙选第一个
setSelectRegionList([])
console.log('e', e);
const req: any = {
ServerpartId: e
}
const data = await handleGetServerpartInfo(req)
let list: any = data.RegionInfo
if (list && list.length > 0) {
let res: any = []
list.forEach((item: any) => {
res.push({ label: item.SERVERPART_REGIONNAME, value: item.SERVERPART_REGION })
})
console.log('res', res);
setSelectRegionList(res)
formAssetsRef.current?.setFieldsValue({ PROPERTYASSETS_REGION: res[0].value })
}
handleGetServicePic()
} else {
setSelectRegionList([])
relatedShopRef.current?.handleReloadTable()
}
}
}}
/>
</Col>
<Col span={8}>
<ProFormSelect
label={"服务区方位"}
labelAlign={'right'}
name={"PROPERTYASSETS_REGION"}
disabled={id}
rules={[
{
required: true,
message: '请选择服务区方位!',
},
]}
fieldProps={{
options: selectRegionList,
onChange: (e: any) => {
handleGetServicePic()
}
}}
/>
</Col>
<Col span={8}>
<ProFormTreeSelect
label={"资产类型"}
labelAlign={'right'}
name={"PROPERTYASSETS_TYPE"}
rules={[
{
required: true,
message: '请选择资产类型!',
},
]}
request={async () => {
const list = await getFieldEnumTreeNoSession({ FieldExplainField: 'PROPERTYASSETS_TYPE' })
if (list && list.length > 0 && !currentRow?.PROPERTYASSETS_ID) {
formAssetsRef.current?.setFieldsValue({ PROPERTYASSETS_TYPE: list[0].children[0].value })
}
return list
}}
fieldProps={{
onChange: (e: any) => {
console.log('e', e);
setPROPERTYASSETSTYPE(e)
if (e === 1000 || e === 1) {
if (e === 1) {
let res: any = formAssetsRef.current?.getFieldsValue()
if (res?.PROPERTYASSETS_REGION && res?.SERVERPART_ID) {
formAssetsRef.current?.setFieldsValue({ PROPERTYASSETS_CODE: `${res?.SERVERPART_ID}-${res?.PROPERTYASSETS_REGION}` })
}
}
setAssetsCodeRequired(true)
} else {
setAssetsCodeRequired(false)
}
},
treeDefaultExpandAll: true
}}
/>
</Col>
</Row>
<Row gutter={16}>
<Col span={16}>
<Row>
<Col span={12}>
<ProFormText
label={"资产编码"}
labelAlign={'right'}
name={"PROPERTYASSETS_CODE"}
rules={[
{
required: true,
message: '请输入资产编码!',
},
]}
/>
</Col>
<Col span={12}>
<ProFormText
label={"面积"}
labelAlign={'right'}
name={"PROPERTYASSETS_AREA"}
fieldProps={{
addonAfter: "m²"
}}
rules={[
{
required: true,
message: '请输入资产面积!',
},
]}
/>
</Col>
<Col span={12}>
<ProFormText
label={"备注说明"}
labelAlign={'right'}
name={"PROPERTYASSETS_DESC"}
/>
</Col>
<Col span={12}>
<ProFormSelect
label={"有效状态"}
labelAlign={'right'}
name={"PROPERTYASSETS_STATE"}
rules={[
{
required: true,
message: '请选择有效状态!',
},
]}
initialValue={1}
request={() => {
// let list: any = [{ label: '有效', value: 1 }, { label: '无效', value: 0 }]
let list: any = [{ label: '正常', value: 1 }, { label: '关闭', value: 0 }]
return list
}}
/>
</Col>
</Row>
</Col>
<Col span={8}>
<ProFormUploadButton
label={"上传平面图"}
fieldProps={{
name: 'files',
maxCount: 1,
fileList: fileList,
beforeUpload: beforeUpload,
onPreview: handlePreview,
customRequest: async (info) => {
const isOk: any = await formAssetsRef.current?.validateFields(['SERVERPART_ID', 'PROPERTYASSETS_REGION'])
console.log('isOk', isOk);
if (isOk?.PROPERTYASSETS_REGION && isOk?.SERVERPART_ID) {
let res: any = formAssetsRef.current?.getFieldsValue()
console.log('res', res);
console.log('info', info);
const formData = new FormData();
formData.append('files', info.file);
formData.append('TableId', res?.SERVERPART_ID);
formData.append('TableType', '1201');
formData.append('ImageIndex', res?.PROPERTYASSETS_REGION);
formData.append('ImageName', typeof info.file !== 'string' ? info.file?.name : '');
console.log('formData', formData);
console.log('info.fileinfo.file', info.file);
if (info.filename) {
const success = await uploadAHYDPicture(formData)
console.log('success', success);
if (success.Result_Code === 100) {
const list = [{
uid: `${success.Result_Data.ImageId}`, // 注意这个uid一定不能少否则上传失败
name: success.Result_Data.ImageName,
status: 'done',
url: success.Result_Data.ImageUrl, // url 是展示在页面上的绝对链接
imgUrl: success.Result_Data.ImagePath // + success.ImageUrl,
}]
setFileList(list)
message.success("上传成功!")
console.log('listlistlist', list);
}
} else {
message.error("您上传的图片不存在.")
}
}
},
onRemove: async (info: any) => {
console.log('info', info);
// ImageId === uid imgUrl === ImagePath
const req: any = {
imageid: info.uid,
ImagePath: info.imgUrl,
TableName: 'SERVERPART',
TableType: '1010',
}
const data = await handleDeletePicture(req)
if (data) {
message.success('删除成功!')
setFileList([])
}
}
}}
/>
</Col>
</Row>
<Row gutter={16}>
</Row>
<Row>
<Col span={8}>
{
PROPERTYASSETSTYPE === 1 ? '' :
<RelatedShop currentUser={currentUser} parentRef={parentRef} currentRow={currentRow} defaultId={defaultSelectList} detailFormRef={formAssetsRef} onRef={relatedShopRef} show={relatedShopModal} />
}
</Col>
<Col span={16}>
{fileList && fileList.length > 0 ? <div>
{
fileList.map((n) =>
<Image src={n.url} key={n.url} />
)
}
</div> : ''}
</Col>
</Row>
</ProForm>
</Drawer>
{/* 资产详情抽屉 */}
<Drawer
width={'80%'}
visible={assetsDetailDrawer}
className={"assetsDetailDrawer"}
onClose={() => {
setAssetsDetailDrawer(false);
}}
bodyStyle={{ backgroundColor: "#fff", padding: 16 }}
closable={false}
destroyOnClose
>
<AssetsDetail currentRow={currentRow} currentUser={currentUser} />
</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>
)
}
export default connect(({ user }: ConnectState) => ({
}))(LeftSelectTree);

View File

@ -0,0 +1,132 @@
import { ActionType, FormInstance, ProTable } from "@ant-design/pro-components";
import moment from "moment";
import { useRef, useState } from "react";
import { connect } from "umi";
import { handleGetBusinessProjectList } from "../service";
import { Drawer } from "antd";
import ContractDetailDrawer from "./ContractDetailDrawer";
type DetailProps = {
tableData: any
detail: any
}
const ContractDetail = ({ tableData, detail }: DetailProps) => {
const actionRef = useRef<ActionType>();
const tableFormRef = useRef<FormInstance>();
// 合同详情抽屉
const [contractDrawer, setContractDrawer] = useState<boolean>(false)
// 项目详情抽屉
const [projectDrawer, setProjectDrawer] = useState<boolean>(false)
// 点击行的数据详情
const [currentRow, setCurrentRow] = useState<any>()
const columns: any = [
{
title: '项目名称',
dataIndex: 'BUSINESSPROJECT_NAME',
width: 300,
ellipsis: true,
render: (_, record) => {
return <a style={{ display: 'inline-block', width: '270px', whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }} onClick={() => {
setCurrentRow(record)
setProjectDrawer(true)
}}>
{record?.BUSINESSPROJECT_NAME || ''}
</a>
}
},
{
title: '合同名称',
dataIndex: 'COMPACT_NAME',
width: 300,
render: (_, record) => {
return <a style={{ display: 'inline-block', width: '270px', whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }} onClick={() => {
setCurrentRow(record)
setContractDrawer(true)
}}>
{record?.COMPACT_NAME || ''}
</a>
}
},
{
title: '项目开始时间',
width: 120,
dataIndex: 'PROJECT_STARTDATE',
render: (_, record) => {
return record?.PROJECT_STARTDATE ? moment(record?.PROJECT_STARTDATE).format('YYYY-MM-DD') : ''
}
},
{
title: '项目结束时间',
width: 120,
dataIndex: 'PROJECT_ENDDATE',
render: (_, record) => {
return record?.PROJECT_ENDDATE ? moment(record?.PROJECT_ENDDATE).format('YYYY-MM-DD') : ''
}
},
// {
// title: '有效状态',
// dataIndex: 'PROJECT_VALID',
// valueType: 'select',
// valueEnum: {
// 1: '有效',
// 0: '无效',
// }
// }
]
return (
<div>
<ProTable
actionRef={actionRef}
formRef={tableFormRef}
columns={columns}
search={false}
request={async () => {
console.log('detail', detail);
let req: any = {
SearchParameter: {
SERVERPARTSHOP_ID: detail?.SERVERPARTSHOP_ID || detail?.PropertyShop.SERVERPARTSHOP_ID,
PROJECT_VALID: 1
},
PageIndex: 1,
PageSize: 999999
}
const data = await handleGetBusinessProjectList(req)
console.log('data', data);
if (data && data.length > 0) {
return { data, success: true }
}
return { data: [], success: true }
}}
// dataSource={tableData}
/>
{/* 跳转到合同详情 */}
<Drawer
width={'80%'}
visible={contractDrawer}
onClose={() => {
setCurrentRow(undefined);
setContractDrawer(false);
}}
bodyStyle={{ backgroundColor: "#f9f9f9", padding: 16 }}
closable={false}
destroyOnClose
>
<ContractDetailDrawer contractId={currentRow?.REGISTERCOMPACT_ID} currentRow={currentRow}></ContractDetailDrawer>
</Drawer>
</div>
)
}
export default connect(({ user, }: ConnectState) => ({
currentUser: user.currentUser,
}))(ContractDetail);

View File

@ -0,0 +1,7 @@
.historyTable{
.ant-pro-card{
.ant-pro-table-alert{
display: none;
}
}
}

View File

@ -0,0 +1,246 @@
import { connect } from "umi";
import moment from 'moment'
import './historyTable.less'
import { useImperativeHandle, useRef, useState } from "react";
import { ActionType, FormInstance, ProTable } from "@ant-design/pro-components";
import { message, Popconfirm } from "antd";
import { handleDeletePROPERTYSHOP, handleGetBusinessProjectList, handleGetPROPERTYSHOPList, handleGetServerpartShopList } from "../service";
type DetailProps = {
currentRow: any
onRef: any
currentUser?: any
defaultId?: any // 可能存在的外部默认绑定的门店
}
const HistoryTable = ({ currentRow, onRef, currentUser, defaultId }: DetailProps) => {
const actionRef = useRef<ActionType>();
const formRef = useRef<FormInstance>();
const columns: any = [
{
title: '门店名称',
dataIndex: 'SHOPNAME',
ellipsis: true,
hideInSearch: true,
},
{
title: '项目名称',
dataIndex: 'BUSINESSPROJECT_NAME',
ellipsis: true,
hideInSearch: true,
},
{
title: '项目开始时间',
dataIndex: 'PROJECT_STARTDATE',
hideInSearch: true,
render: (_, record) => {
return record?.PROJECT_STARTDATE ? moment(record?.PROJECT_STARTDATE).format('YYYY-MM-DD') : ''
}
},
{
title: '项目结束时间',
dataIndex: 'PROJECT_STARTDATE',
hideInSearch: true,
render: (_, record) => {
return record?.PROJECT_ENDDATE ? moment(record?.PROJECT_ENDDATE).format('YYYY-MM-DD') : ''
}
},
{
title: '门店状态',
dataIndex: 'BUSINESS_STATE',
valueType: 'select',
hideInSearch: true,
valueEnum: {
1000: { text: '运营中', status: 'processing' },
2000: { text: '已暂停', status: 'warning' },
3000: { text: '已关闭', status: 'error' },
1010: { text: '待运营', status: 'default' }
}
},
{
title: '操作',
dataIndex: 'option',
hideInSearch: true,
render: (_, record) => {
return record?.showDelete ? <Popconfirm
title={'确认删除关联?'}
onConfirm={() => {
console.log('record', record);
deleteAssociation(record)
}}
>
<a ></a>
</Popconfirm> : ''
}
}
]
const deleteAssociation = async (obj: any) => {
const req: any = {
Id: obj?.PROPERTYASSETS_ID,
RelatedId: obj?.PROPERTYSHOP_ID,
OperateId: currentUser?.ID,
OperateName: currentUser?.Name
}
console.log('req', req);
const data = await handleDeletePROPERTYSHOP(req)
if (data.Result_Code === 100) {
message.success(data.Result_Desc)
actionRef.current?.reload()
} else {
message.error(data.Result_Desc)
}
}
// 选中的行
const [selectedModalOrderRowKeys, setSelectedModalOrderRowKeys] = useState<any>()
// 选中的行数据
const [selectModalRowList, setSelectModalRowList] = useState<any>()
const modalRowSelection: any = {
defaultSelectedRowKeys: selectedModalOrderRowKeys,
selectedRowKeys: selectedModalOrderRowKeys,
preserveSelectedRowKeys: true,
onChange: (selectedRowKeys: any, selectedRows: any) => {
console.log('selectedRowKeys', selectedRowKeys);
console.log('selectedRows', selectedRows);
setSelectModalRowList(selectedRows)
setSelectedModalOrderRowKeys(selectedRowKeys)
},
getCheckboxProps: (record: any) => ({
disabled: record.disable,
}),
};
useImperativeHandle(onRef, () => ({
selectModalRowList,
setSelectedModalOrderRowKeys
}));
return (
<div>
<ProTable
actionRef={actionRef}
formRef={formRef}
columns={columns}
bordered
className="historyTable"
rowKey={(record) => {
return `${record?.SERVERPARTSHOP_ID}`
}}
scroll={{ y: 'calc(100vh - 320px)' }}
pagination={false}
request={async () => {
console.log('defaultId', defaultId);
console.log('currentRow', currentRow);
let req: any = {
SearchParameter: {
SERVERPART_IDS: currentRow?.SERVERPART_ID,
SHOPREGION: currentRow?.PROPERTYASSETS_REGION,
ISVALID: 1
},
PageIndex: 1,
PageSize: 999999
}
const data = await handleGetServerpartShopList(req)
console.log('shopData', data);
let projectReq: any = {
SearchParameter: {
SERVERPART_IDS: currentRow?.SERVERPART_ID,
PROJECT_VALID: 1
},
PageIndex: 1,
PageSize: 999999
}
const projectData = await handleGetBusinessProjectList(projectReq)
// 拿到之前的勾选数据
const historySelect = await handleGetPROPERTYSHOPList({
SearchParameter: {
PROPERTYASSETS_ID: currentRow?.PROPERTYASSETS_ID
},
PageIndex: 1,
PageSize: 999999
})
let select: any = []
let selectDetail: any = []
// 当前绑定的门店
let nowSelect: any = ''
if (historySelect && historySelect.length > 0) {
historySelect.forEach((item: any) => {
// 这里只默认勾选历史的 当前的勾选
if (item.PROPERTYSHOP_STATE !== 1) {
select.push(item.SERVERPARTSHOP_ID.toString())
selectDetail.push(item)
} else {
nowSelect = item.SERVERPARTSHOP_ID.toString()
}
})
console.log('select', select);
setSelectedModalOrderRowKeys(select)
}
console.log('projectData', projectData);
if (data && data.length > 0 && projectData && projectData.length > 0) {
let newData = JSON.parse(JSON.stringify(data))
newData.forEach((item: any) => {
projectData.forEach((subItem: any) => {
if (subItem.SERVERPARTSHOP_ID.indexOf(item.SERVERPARTSHOP_ID.toString()) !== -1) {
item.BUSINESSPROJECT_NAME = subItem.BUSINESSPROJECT_NAME
item.PROJECT_ENDDATE = subItem.PROJECT_ENDDATE
item.PROJECT_STARTDATE = subItem.PROJECT_STARTDATE
item.BUSINESSPROJECT_ID = subItem.BUSINESSPROJECT_ID
}
})
})
console.log('res', newData);
console.log('selectDetail', selectDetail);
if (newData && newData.length > 0) {
let rowList: any = []
newData.forEach((item: any) => {
if (select && select.length > 0) {
if (select.indexOf(item.SERVERPARTSHOP_ID.toString()) !== -1) {
let index: number = select.indexOf(item.SERVERPARTSHOP_ID.toString())
console.log('index', index);
item.PROPERTYASSETS_ID = selectDetail[index].PROPERTYASSETS_ID
item.PROPERTYSHOP_ID = selectDetail[index].PROPERTYSHOP_ID
rowList.push(item)
item.showDelete = true
}
}
})
console.log('rowList', rowList);
setSelectModalRowList(rowList)
}
newData = newData.filter((item: any) => item.SERVERPARTSHOP_ID.toString().indexOf(nowSelect) === -1)
console.log('res', newData);
return { data: newData, success: true }
}
return { data: [], success: true }
}}
rowSelection={{
type: 'checkbox',
...modalRowSelection,
}}
/>
</div>
)
}
export default connect(({ user, }: ConnectState) => ({
currentUser: user.currentUser,
}))(HistoryTable);

View File

@ -0,0 +1,91 @@
import { connect } from "umi";
import moment from 'moment/moment'
import { useRef } from "react";
import { ActionType, FormInstance, ProTable } from "@ant-design/pro-components";
import { handleGetPROPERTYASSETSLOGList } from "../service";
type DetailProps = {
detail: any;
}
const LogList = ({ detail }: DetailProps) => {
const actionRef = useRef<ActionType>();
const tableFormRef = useRef<FormInstance>();
const columns: any = [
{
title:'操作类型',
width: 120,
ellipsis:true,
hideInSearch: true,
dataIndex:'OPERATE_TYPE'
},
{
title:'操作原值',
width: 250,
ellipsis:true,
hideInSearch: true,
dataIndex:'OPERATE_VALUE'
},
{
title:'操作新值',
width: 250,
ellipsis:true,
hideInSearch: true,
dataIndex:'OPERATE_NEWVALUE'
},
{
title:'操作描述',
width: 250,
ellipsis:true,
hideInSearch: true,
dataIndex:'OPERATE_DESC'
},
{
title:'操作人',
width: 120,
ellipsis:true,
hideInSearch: true,
dataIndex:'OPERATE_NAME'
},
{
title:'操作时间',
width: 150,
ellipsis:true,
hideInSearch: true,
dataIndex:'OPERATE_DATE',
render:(_,record)=>{
return moment(record?.OPERATE_DATE).format('YYYY-MM-DD HH:mm:ss')
}
},
]
return (
<div>
<ProTable
actionRef={actionRef}
formRef={tableFormRef}
request={async () => {
const req: any = {
SearchParameter: {
TABLE_ID: detail?.PROPERTYASSETS_ID,
TABLE_NAME: "T_PROPERTYASSETS"
}
}
const data = await handleGetPROPERTYASSETSLOGList(req)
if (data && data.length > 0) {
return { data, success: true }
}
return { data: [], success: true }
}}
columns={columns}
/>
</div>
)
}
export default connect(({ user, }: ConnectState) => ({
currentUser: user.currentUser,
}))(LogList);

View File

@ -0,0 +1,9 @@
.relateShopTable{
.ant-pro-card{
.ant-pro-card-body{
.ant-pro-table-alert{
display: none;
}
}
}
}

View File

@ -0,0 +1,391 @@
import { connect } from "umi";
import './relatedShop.less'
import { useImperativeHandle, useRef, useState } from "react";
import { ActionType, FormInstance, ProTable } from "@ant-design/pro-components";
import { message, Popconfirm, Radio } from "antd";
import { handleDeletePROPERTYSHOP, handleGetPROPERTYSHOPList, handleGetProvinceVehicleDetail, handleGetServerpartShopList } from "../service";
type DetailProps = {
currentRow: any;
detailFormRef?: any;
onRef?: any;
show: boolean;
defaultId?: any
currentUser?: any
parentRef?: any
}
const relatedShop = ({ currentRow, detailFormRef, onRef, show, defaultId, currentUser, parentRef }: DetailProps) => {
const actionRef = useRef<ActionType>();
const formRef = useRef<FormInstance>();
const [noSelect, setNoSelect] = useState<boolean>(false)
const columns: any = [
{
title: '门店名称',
width: 120,
ellipsis: true,
dataIndex: 'SHOPNAME',
render: (_, record) => {
return <div style={{ display: 'flex', alignItems: 'center' }}>
<span className={record?.BUSINESS_STATE === 1000 ? "ant-badge-status-dot ant-badge-status-processing" :
record?.BUSINESS_STATE === 1010 ? "ant-badge-status-dot ant-badge-status-default" : record?.BUSINESS_STATE === 2000 ? "ant-badge-status-dot ant-badge-status-warning" :
record?.BUSINESS_STATE === 3000 ? "ant-badge-status-dot ant-badge-status-error" : ""}></span>
<span style={{ marginLeft: '4px' }}>{record?.SHOPNAME || ''}</span>
</div>
}
},
{
title: '资产编码',
width: 120,
ellipsis: true,
dataIndex: 'PROPERTYASSETS_CODE',
},
{
title: '操作',
width: 60,
render: (_, record) => {
return record?.isShowDelete ?
<Popconfirm
title={'确认删除关联?'}
onConfirm={() => {
console.log('record', record);
setNoSelect(true)
deleteAssociation(record)
}}
>
<a ></a>
</Popconfirm> : ''
}
}
// {
// title: '服务区',
// dataIndex: 'SERVERPART_NAME',
// hideInSearch: true
// },
// {
// title: '经营状态',
// dataIndex: 'BUSINESS_STATE',
// valueType: 'select',
// hideInSearch: false,
// valueEnum: {
// 3000: { text: '关闭', status: 'error' },
// 2000: { text: '暂停', status: 'warning' },
// 1000: { text: '运营中', status: 'processing' },
// 1010: { text: '待运营', status: 'default' }
// }
// },
]
// 选中的行
const [selectedModalOrderRowKeys, setSelectedModalOrderRowKeys] = useState<any>()
// 选中的行数据
const [selectModalRowList, setSelectModalRowList] = useState<any>()
// 表格的状态
const [tableStatue, setTableStateue] = useState<any>(0)
const modalRowSelection: any = {
defaultSelectedRowKeys: noSelect ? [] : defaultId ? [`${defaultId}`] : [],
selectedRowKeys: selectedModalOrderRowKeys,
preserveSelectedRowKeys: true,
onChange: (selectedRowKeys: any, selectedRows: any) => {
console.log('defaultId', defaultId);
console.log('selectedRowKeys', selectedRowKeys);
console.log('selectedRows', selectedRows);
if (selectedRows && selectedRows.length > 0) {
// 门店状态不是正常的
let shopStateNoNormalList: any = []
let shopStateNoNormalRowList: any = []
// 门店状态是正常的
let shopIsNormalList: any = []
let shopIsNormalRowList: any = []
selectedRows.forEach((item: any) => {
if (item.BUSINESS_STATE === 1000) {
shopIsNormalList.push(item)
shopIsNormalRowList.push(`${item?.PROPERTYASSETS_CODE}-${item?.SERVERPARTSHOP_ID}`)
} else {
shopStateNoNormalList.push(item)
shopStateNoNormalRowList.push(`${item?.PROPERTYASSETS_CODE}-${item?.SERVERPARTSHOP_ID}`)
}
})
// 实际保留的这一次点击的新的 1000的数据
let realNormalList: any = []
let realNormalRowList: any = []
// 如果当前的点击行里面 1000的数量大于1 那么就要去掉之前的 留下新点击的
if (shopIsNormalList && shopIsNormalList.length > 1) {
shopIsNormalList.forEach((item: any) => {
if (`${item?.PROPERTYASSETS_CODE}-${item?.SERVERPARTSHOP_ID}` === selectedRowKeys[selectedRowKeys.length - 1]) {
realNormalList.push(item)
realNormalRowList.push(`${item?.PROPERTYASSETS_CODE}-${item?.SERVERPARTSHOP_ID}`)
}
})
} else {
realNormalList = shopIsNormalList
realNormalRowList = shopIsNormalRowList
}
setSelectModalRowList([...realNormalList, ...shopStateNoNormalList])
setSelectedModalOrderRowKeys([...realNormalRowList, ...shopStateNoNormalRowList])
} else {
setSelectModalRowList(selectedRows)
setSelectedModalOrderRowKeys(selectedRowKeys)
}
},
getCheckboxProps: (record: any) => ({
disabled: record.disable,
}),
};
useImperativeHandle(onRef, () => ({
selectModalRowList,
handleReloadTable,
setSelectedModalOrderRowKeys
}));
const handleReloadTable = () => {
actionRef.current?.reload()
}
const deleteAssociation = async (obj: any) => {
const req: any = {
Id: obj?.PROPERTYASSETS_ID,
ShopId: obj?.SERVERPARTSHOP_ID,
OperateId: currentUser?.ID,
OperateName: currentUser?.Name
}
console.log('req', req);
const data = await handleDeletePROPERTYSHOP(req)
if (data.Result_Code === 100) {
message.success(data.Result_Desc)
setSelectModalRowList([])
setSelectedModalOrderRowKeys([])
actionRef.current?.reload()
if (parentRef) {
parentRef.current?.reload()
}
} else {
message.error(data.Result_Desc)
}
}
return (
<div>
<div style={{ width: '100%', boxSizing: 'border-box', paddingLeft: '24px', marginBottom: '16px' }}>
<Radio.Group onChange={(e: any) => {
setTableStateue(Number(e.target.value))
actionRef.current?.reload()
}} value={tableStatue}>
<Radio value={0}></Radio>
<Radio value={1000}>
<span style={{ margin: '0 4px' }} className="ant-badge-status-dot ant-badge-status-processing"></span>
</Radio>
<Radio value={1010}>
<span style={{ margin: '0 4px' }} className="ant-badge-status-dot ant-badge-status-default"></span>
</Radio>
<Radio value={2000}>
<span style={{ margin: '0 4px' }} className="ant-badge-status-dot ant-badge-status-warning"></span>
</Radio>
<Radio value={3000}>
<span style={{ margin: '0 4px' }} className="ant-badge-status-dot ant-badge-status-error"></span>
</Radio>
</Radio.Group>
</div>
<ProTable
actionRef={actionRef}
formRef={formRef}
columns={columns}
bordered
className="relateShopTable"
search={false}
style={{ marginTop: '4px' }}
rowKey={(record) => {
return `${record?.PROPERTYASSETS_CODE}-${record?.SERVERPARTSHOP_ID}`
}}
options={false}
scroll={{ y: 630 }}
pagination={false}
request={async (params: any) => {
let req: any = {}
let formRes = detailFormRef.current?.getFieldsValue()
let nowShopRegion: any = '' // 当前的方位
// 先判断是新增还是编辑 这样取数据不同的
if (currentRow?.PROPERTYASSETS_ID) {
req = {
SearchParameter: {
SERVERPART_IDS: currentRow?.SERVERPART_ID,
ISVALID: 1,
BUSINESS_STATE: tableStatue ? tableStatue : '',
SHOPREGION: currentRow?.PROPERTYASSETS_REGION
},
SortStr: 'BUSINESS_STATE,SHOPTRADE,SHOPSHORTNAME,SHOPREGION',
PageIndex: 1,
PageSize: 999999
}
nowShopRegion = currentRow?.PROPERTYASSETS_REGION
} else {
// 没有服务区就不查了
if (!formRes?.SERVERPART_ID) {
return { data: [], success: true }
}
req = {
SearchParameter: {
SERVERPART_IDS: formRes?.SERVERPART_ID,
ISVALID: 1,
BUSINESS_STATE: tableStatue ? tableStatue : '',
SHOPREGION: formRes?.PROPERTYASSETS_REGION,
},
SortStr: 'BUSINESS_STATE,SHOPTRADE,SHOPSHORTNAME,SHOPREGION',
PageIndex: 1,
PageSize: 999999
}
nowShopRegion = formRes?.PROPERTYASSETS_REGION
}
// 现在要门店拼上资产内码
let data = await handleGetServerpartShopList(req)
const secondReq: any = {
SearchParameter: {
SERVERPART_IDS: formRes?.SERVERPART_ID,
// PROPERTYASSETS_REGION: formRes?.PROPERTYASSETS_REGION,
PROPERTYASSETS_STATE: 1
},
PageIndex: 1,
PageSize: 999999
}
const secondData = await handleGetProvinceVehicleDetail(secondReq)
console.log('门店数据', data);
console.log('资产数据', secondData);
// 拿到相同方位 且有资产的门店
// 和其他方位 的全部资产数据
let sameShopList: any = []
let otherShopList: any = []
// 拿到同方位 有资产 但没门店的数据
let sameNoShopList: any = []
console.log('nowShopRegion', nowShopRegion);
if (secondData && secondData.length > 0) {
secondData.forEach((item: any) => {
if (item.BUSINESS_STATE === tableStatue || !tableStatue) {
if (nowShopRegion === item.PROPERTYASSETS_REGION) {
sameShopList.push(item)
} else {
otherShopList.push(item)
}
if (item.PROPERTYASSETS_CODE && !item.SERVERPARTSHOP_ID) {
item.disable = true
sameNoShopList.push(item)
}
}
})
}
console.log('sameShopList', sameShopList);
console.log('otherShopList', otherShopList);
// 相同方位没有匹配上的数据
let sameOther: any = []
// 相同方位 且有资产的门店 把门店资产全部拼在 对应区的门店上面
// 给已经找到了门店的 做个标记 没有找到的全部列出来拼在后面
if (sameShopList && sameShopList.length > 0 && data && data.length > 0) {
sameShopList.forEach((item: any) => {
data.forEach((subItem: any) => {
if (Number(item.SERVERPARTSHOP_ID || 0) === Number(subItem.SERVERPARTSHOP_ID)) {
subItem.PROPERTYASSETS_CODE = item.PROPERTYASSETS_CODE
subItem.PROPERTYASSETS_ID = item.PROPERTYASSETS_ID
item.haveCode = true
}
})
})
console.log('sameShopList2222', sameShopList);
console.log('data222', data);
sameShopList.forEach((item: any) => {
if (item.haveCode) {
} else {
item.disable = true
sameOther.push(item)
}
})
}
// 其他方位的内容不可选
if (otherShopList && otherShopList.length > 0) {
otherShopList.forEach((item: any) => {
item.disable = true
})
}
console.log('当前方位拼上的数据', data);
console.log('想通方位的其他数据', sameOther);
console.log('有资产 没门店 同方位', sameNoShopList);
console.log('其他方位的资产数据', otherShopList);
let res = [...data, ...sameOther]
// , ...otherShopList
// 编辑的时候可以出现可以出现删除关联
let result: any = []
let firstObj: any = {}
const historySelect = await handleGetPROPERTYSHOPList({
SearchParameter: {
PROPERTYASSETS_ID: currentRow?.PROPERTYASSETS_ID
},
PageIndex: 1,
PageSize: 999999
})
// 外部绑定的
let outId: any = ''
if (historySelect && historySelect.length > 0) {
historySelect.forEach((item: any) => {
if (item.PROPERTYSHOP_STATE === 1) {
outId = item.SERVERPARTSHOP_ID
}
})
}
if (res && res.length > 0) {
res.forEach((item: any) => {
if (item.PROPERTYASSETS_CODE === currentRow?.PROPERTYASSETS_CODE && item.SERVERPARTSHOP_ID && item.SERVERPARTSHOP_ID === outId && currentRow?.PROPERTYASSETS_CODE) {
item.isShowDelete = true
firstObj = item
} else {
result.push(item)
}
})
}
if (firstObj && firstObj.PROPERTYASSETS_CODE) {
result.unshift(firstObj)
}
console.log('result', result);
return { data: result, success: true }
}}
rowSelection={{
type: 'radio',
...modalRowSelection,
}}
/>
</div>
)
}
export default connect(({ user, }: ConnectState) => ({
}))(relatedShop);

View File

@ -0,0 +1,5 @@
.shopMessageTable{
.ant-pro-card-body{
padding: 0;
}
}

View File

@ -0,0 +1,187 @@
import { connect } from "umi";
import moment from 'moment/moment'
import { useEffect, useRef } from "react";
import { ActionType, FormInstance, ProDescriptions, ProTable } from "@ant-design/pro-components";
import session from "@/utils/session";
import { handleGetServerPartShopNewDetail } from "../service";
type DetailProps = {
detailData: any;
onShow: boolean
}
const StoreInfor = ({ detailData,onShow }: DetailProps) => {
const actionRef = useRef<ActionType>();
const tableFormRef = useRef<FormInstance>();
const businessStateObj: any = session.get('businessStateObj')
const BUSINESSTYPEObj: any = session.get('BUSINESSTYPEObj')
const SHOPTRADEObj: any = session.get('SHOPTRADEObj')
const BUSINESSBRANDObj: any = session.get('BUSINESSBRANDObj')
const SHOPREGIONObj: any = session.get('shopregionObj')
const columns: any = [
{
title: '经营单位',
dataIndex: 'BUSINESS_UNIT',
},
{
title: '服务区名称',
dataIndex: 'SERVERPART_NAME'
},
{
title: '商品业态',
dataIndex: 'SHOPTRADE',
valueType: 'select',
valueEnum: SHOPTRADEObj
},
{
title: '经营业态',
dataIndex: 'BUSINESS_TRADENAME',
},
{
title: '经营品牌',
dataIndex: 'BUSINESS_BRAND',
valueType: 'select',
valueEnum: BUSINESSBRANDObj
},
{
title: '门店简称',
dataIndex: 'SHOPSHORTNAME',
},
{
title: '销售数量上限',
valueType: 'digit',
dataIndex: 'SALECOUNT_LIMIT',
},
{
title: '金额上限',
valueType: 'digit',
dataIndex: 'SALEAMOUNT_LIMIT',
},
{
title: '优惠折扣',
dataIndex: 'SALEAMOUNT_LIMIT',
valueType: 'select',
valueEnum: {
0: '不记异常稽核',
1: '记录异常稽核'
}
},
{
title: '门店方位',
dataIndex: 'SHOPREGION',
valueType: 'select',
valueEnum: SHOPREGIONObj
},
{
title: '门店名称',
dataIndex: 'SHOPNAME'
},
{
title: '经营模式',
dataIndex: 'BUSINESS_TYPE',
valueType: 'select',
valueEnum: BUSINESSTYPEObj
},
{
title: '经营状态',
dataIndex: 'BUSINESS_STATE',
valueType: 'select',
valueEnum: businessStateObj
},
{
title: '开业时间',
dataIndex: 'BUSINESS_DATE',
render:(_,record)=>{
return record?.BUSINESS_DATE ? moment(record?.BUSINESS_DATE).format('YYYY-MM-DD HH:mm:ss'):''
}
},
{
title: '停业时间',
dataIndex: 'BUSINESS_ENDDATE',
render:(_,record)=>{
return record?.BUSINESS_DATE ? moment(record?.BUSINESS_DATE).format('YYYY-MM-DD HH:mm:ss'):''
}
},
]
const tableColumns: any = [
{
title: '序号',
dataIndex: "index",
valueType: 'index',
hideInSearch: true
},
{
title: '门店名称',
dataIndex: 'ShopName',
hideInSearch: true
},
{
title: '开业时间',
dataIndex: 'BusinessDate',
hideInSearch: true,
render: (_, record) => {
return record?.BusinessDate || ''
}
},
{
title: '停业时间',
dataIndex: 'BusinessEndDate',
hideInSearch: true,
render: (_, record) => {
return record?.BusinessEndDate || ''
}
},
{
title: '操作人员',
dataIndex: 'StaffName',
hideInSearch: true
},
{
title: '操作时间',
dataIndex: 'OperateDate',
hideInSearch: true,
render: (_, record) => {
return record?.OperateDate ? moment(record?.OperateDate).format('YYYY-MM-DD') : ''
}
},
]
return (
<div>
<ProDescriptions
columns={columns}
dataSource={detailData}
></ProDescriptions>
<ProTable
actionRef={actionRef}
formRef={tableFormRef}
className={"shopMessageTable"}
headerTitle={"门店经营信息"}
columns={tableColumns}
request={async () => {
if (detailData?.SERVERPARTSHOP_ID) {
console.log('detailData2', detailData);
const req: any = {
serverPartShopId: detailData?.SERVERPARTSHOP_ID
}
const data = await handleGetServerPartShopNewDetail(req)
console.log('data2', data);
let res = data.RtServerPartShopList
if (res && res.length > 0) {
return { data: res, success: true }
}
}
return { data: [], success: true }
}}
search={false}
/>
</div>
)
}
export default connect(({ user, }: ConnectState) => ({
currentUser: user.currentUser,
}))(StoreInfor);

View File

@ -0,0 +1,660 @@
// 服务区资产页面
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);

View File

@ -0,0 +1,577 @@
import { wrapTreeNode } from "@/components/leftSelectTree/service";
import requestAHYD from "@/utils/requestAHYD";
import requestCode from "@/utils/requestCode";
import request from "@/utils/requestMain";
import session from "@/utils/session";
import numeral from 'numeral'
/* 获取枚举列表 */
export async function getFieldEnumTree(params: any) {
const sessionName = `${params.sessionName ? params.sessionName : params.FieldExplainField}Tree`;
const FieldExplain = session.get(sessionName);
const data = await request(`/FrameWork/GetFieldEnumTree`, {
method: 'GET',
params,
});
if (data.Result_Code !== 100) {
return [];
}
const options = params.notformate ? formateTreeField(data.Result_Data.List) : wrapTreeNode(data.Result_Data.List);
session.set(sessionName, options);
return [...options];
}
// 转换树节点的value类型为string
export function formateTreeField(list: any[]) {
const valueNumber: any[] = list.map((item: any) => {
const node = { label: item.node.label, value: item.node.value.toString(), type: item.node.type, ico: item.node.ico };
if (item.children && item.children.length > 0) {
node.children = formateTreeField(item.children);
}
return node
});
return valueNumber.length > 0 ? valueNumber : list;
}
// 删除服务区资产表
export async function handleDeletePROPERTYASSETS(params?: any) {
const data = await request(`/BaseInfo/DeletePROPERTYASSETS`, {
method: 'POST',
data: params
});
if (data.Result_Code !== 100) {
return {
data: [],
current: 1,
pageSize: 10,
total: 0,
success: false
}
}
return data
}
// 将门店批量与资产关联
export async function handleGetBatchPROPERTYSHOP(params?: any) {
const data = await request(`/BaseInfo/BatchPROPERTYSHOP`, {
method: 'POST',
data: params
});
if (data.Result_Code !== 100) {
return {
data: [],
current: 1,
pageSize: 10,
total: 0,
success: false
}
}
return data
}
// 获取服务区资产表树形列表
export async function handleGetPROPERTYASSETSTreeList(params?: any) {
const data = await request(`/BaseInfo/GetPROPERTYASSETSTreeList`, {
method: 'POST',
data: params
});
if (data.Result_Code !== 100) {
return {
data: [],
current: 1,
pageSize: 10,
total: 0,
success: false
}
}
return wrapTreeNode(data.Result_Data.List);
}
// 获取服务区资产表列表
export async function handleGetProvinceVehicleDetail(params?: any) {
const data = await request(`/BaseInfo/GetPROPERTYASSETSList`, {
method: 'POST',
data: params
});
if (data.Result_Code !== 100) {
return {
data: [],
current: 1,
pageSize: 10,
total: 0,
success: false
}
}
return data.Result_Data.List;
}
// 同步服务区资产表
export async function handleSynchroPROPERTYASSETS(params?: any) {
const data = await request(`/BaseInfo/SynchroPROPERTYASSETS`, {
method: 'POST',
data: params
});
if (data.Result_Code !== 100) {
return data
}
return data
}
// 获取服务区资产表明细
export async function handleGetPROPERTYASSETSDetail(params?: any) {
const data = await request(`/BaseInfo/GetPROPERTYASSETSDetail`, {
method: 'GET',
params
});
if (data.Result_Code !== 100) {
return {
data: [],
current: 1,
pageSize: 10,
total: 0,
success: false
}
}
return data.Result_Data
}
// 拿到经营项目列表
export async function handleGetBusinessProjectList(params?: any) {
const data = await request(`/BusinessProject/GetBusinessProjectList`, {
method: 'POST',
data: params
});
if (data.Result_Code !== 100) {
return data
}
return data.Result_Data.List
}
// 将资产和门店相关联
export async function handleGetSynchroPROPERTYSHOP(params?: any) {
const data = await request(`/BaseInfo/SynchroPROPERTYSHOP`, {
method: 'POST',
data: params
});
if (data.Result_Code !== 100) {
return {
data: [],
current: 1,
pageSize: 10,
total: 0,
success: false
}
}
return data
}
// 拿到图片列表
export async function handleGetPictureList(params: any) {
const data = await request(`/Picture/GetPictureList`, {
method: 'GET',
params
})
if (data.Result_Code === 500) {
return []
}
return data.Result_Data
}
// 拿到服务区的方位详情
export async function handleGetServerpartInfo(params: any) {
const data = await requestCode(`/BaseInfo/GetServerpartInfo`, {
method: 'GET',
params
})
if (data.Result_Code !== 100) {
return false
}
return data.Result_Data
}
// 拿到服务区列表
export async function handleGetServerpartTree(params?: any) {
const data = await request(`/BaseInfo/GetServerpartTree`, {
method: 'GET',
params
});
if (data.Result_Code !== 100) {
return {
data: [],
current: 1,
pageSize: 10,
total: 0,
success: false
}
}
return data.Result_Data.List;
}
export async function getFieldEnumTreeNoSession(params: any) {
const data = await request(`/FrameWork/GetFieldEnumTree`, {
method: 'GET',
params,
});
if (data.Result_Code !== 100) {
return [];
}
const options = wrapTreeNode(data.Result_Data.List);
return [...options];
}
export async function uploadAHYDPicture(uploadFilds?: any) {
return await request(`/Picture/UploadPicture`, {
method: 'POST',
data: uploadFilds
})
}
// 删除图片
export async function handleDeletePicture(params: any) {
const data = await request(`/Picture/DeletePicture`, {
method: 'GET',
params
})
if (data.Result_Code !== 100) {
return false
}
return data
}
/* 获取枚举列表 */
export async function getFieldEnum(params: any): Promise<{ label: string; value: string | number }[]> {
// const FieldExplain = session.get(params.sessionName ? params.sessionName : params.FieldExplainField);
// if (FieldExplain) {
// return [...FieldExplain];
// }
const data = await request(`/FrameWork/GetFieldEnumByField`, {
method: 'GET',
params,
});
if (data.Result_Code !== 100) {
return [];
}
const options = params.notformate ? data.Result_Data.List : formateField(data.Result_Data.List);
// session.set(params.sessionName ? params.sessionName : params.FieldExplainField, options);
return options;
}
// 转换options数据value类型为 number
export function formateField(list: { label: string; value: string | number }[]) {
const valueNumber: { label: string; value: number }[] = [];
list.map((n: any) => {
if (!isNaN(Number(n.value))) {
valueNumber.push({
label: n.label,
value: numeral(n.value).value(),
});
}
});
return valueNumber.length > 0 ? valueNumber : list;
}
// 获取详细数据
export async function getDetail(RegisterCompactId: any) {
const data = await request(
`/Contract/GetRegisterCompactDetail?RegisterCompactId=${RegisterCompactId}`, {
method: 'GET',
},
);
if (data.Result_Code !== 100) {
return data.Result_Desc;
}
return data.Result_Data;
}
// 查询附属合同详细信息
export async function getSubDetail(RegisterCompactId: any) {
const data = await request(
`/Contract/GetRegisterCompactSubDetail?RegisterCompactId=${RegisterCompactId}`, {
method: 'GET',
},
);
if (data.Result_Code !== 100) {
return {};
}
return data.Result_Data;
}
// 获取列表数据
export async function getProjectList(params?: any) {
const search = params ? {
searchParameter: { ...params }, keyWord: params.keyWord || null,
PageIndex: params.current, sortstr: params.sortstr, pagesize: params.pageSize
} : {};
const data = await request(`/BusinessProject/GetBusinessProjectList`, {
method: 'POST',
data: search,
});
if (data.Result_Code !== 100) {
return {
data: [],
otherData: null,
current: 1,
pageSize: 10,
total: 0,
success: false
};
}
return tableList(data.Result_Data);
}
export function tableList(list: any) {
return {
data: list.List || [],
current: list.PageIndex || 1,
pageSize: list.pageSize || 10,
total: list.TotalCount || 0,
otherData: list?.OtherData || '',
success: true,
};
}
// 获取附件图片
export async function getPictureList(id: number, TableType?: string) {
const data = await request(`/Picture/GetPictureList?TableId=${id}&TableType=${TableType || ''}`, {
method: 'GET'
})
if (data.Result_Code !== 100) {
return {
data: [],
current: 1,
pageSize: 10,
total: 0,
success: false
}
}
return tableList(data.Result_Data);
}
// 获得关联合同列表
export async function handleGetRelatedList(params: any) {
const data = await request(`/Contract/GetRegisterCompactList`, {
method: 'POST',
data: params,
});
if (data.Result_Code !== 100) {
return []
}
return tableList(data.Result_Data);
}
// 删除门店关联
export async function handleDeletePROPERTYSHOP(params?: any) {
const data = await request(`/BaseInfo/DeletePROPERTYSHOP`, {
method: 'POST',
data: params
});
if (data.Result_Code !== 100) {
return data
}
return data
}
// 拿到门店列表
export async function handleGetServerpartShopList(params?: any) {
const data = await request(`/BaseInfo/GetServerpartShopList`, {
method: 'POST',
data: params
});
if (data.Result_Code !== 100) {
return {
data: [],
current: 1,
pageSize: 10,
total: 0,
success: false
}
}
return data.Result_Data.List
}
// 历史经营项目的勾选数据
export async function handleGetPROPERTYSHOPList(params?: any) {
const data = await request(`/BaseInfo/GetPROPERTYSHOPList`, {
method: 'POST',
data: params
});
if (data.Result_Code !== 100) {
return data
}
return data.Result_Data.List
}
// 资产变更记录
export async function handleGetPROPERTYASSETSLOGList(params?: any) {
const data = await request(`/BaseInfo/GetPROPERTYASSETSLOGList`, {
method: 'POST',
data: params
});
if (data.Result_Code !== 100) {
return {
data: [],
current: 1,
pageSize: 10,
total: 0,
success: false
}
}
return data.Result_Data.List
}
// 获取详细数据
export async function getProjectDetail(businessProjectId: any) {
const data = await request(
`/BusinessProject/GetBusinessProjectDetail?businessProjectId=${businessProjectId}`, {
method: 'GET',
},
);
if (data.Result_Code !== 100) {
return {};
}
return data.Result_Data;
}
// 获取详细数据
export async function getCOMPACTDetail(RegisterCompactId: any) {
const data = await request(
`/Contract/GetRegisterCompactDetail?RegisterCompactId=${RegisterCompactId}`, {
method: 'GET',
},
);
if (data.Result_Code !== 100) {
return data.Result_Desc;
}
return data.Result_Data;
}
// 获取列表数据
export async function getServerpartShopList(params?: any) {
const data = await request(`/BaseInfo/GetServerpartShopList`, {
method: 'POST',
data: {
SearchParameter: { ...params }, keyWord: params?.keyWord,
PageIndex: params?.current, pagesize: params?.pageSize,
SortStr: params?.SortStr, ShowWholePower: params?.ShowWholePower
},
});
if (data.Result_Code !== 100) {
return {};
}
return tableList(data.Result_Data);
}
// 获取列表【门店应收拆分明细表】
export async function getList(params?: any) {
const search = params ? { ...params, SortStr: params?.SortStr, keyWord: params?.keyWord, PageIndex: params?.searchParameter?.current } : {};
const data = await request(`/BusinessProject/GetSHOPROYALTYDETAILList`, {
method: 'POST',
data: search,
});
if (data.Result_Code !== 100) {
return {
data: [],
current: 1,
pageSize: 10,
total: 0,
success: false
}
}
return tableList(data.Result_Data);
}
export async function handleGetBusinessDate(params: any) {
const data = await request('/Revenue/GetBusinessDate', {
method: 'GET',
params
})
if (data.Result_Code !== 100) {
return {
data: [],
otherData: '',
current: 1,
pageSize: 20,
total: 0,
success: true,
};
}
return data.Result_Data
}
// 获取门店详情
export async function handleGetServerPartShopNewDetail(params?: any) {
const data = await request(`/BaseInfo/GetServerPartShopNewDetail`, {
method: 'GET',
params,
});
if (data.Result_Code !== 100) {
return []
}
return data.Result_Data;
}
// 获取门店详情
export async function handleGetServerpartList(params?: any) {
const data = await requestCode(`/BaseInfo/GetServerpartList`, {
method: 'GET',
params,
});
if (data.Result_Code !== 100) {
return []
}
return data.Result_Data.List;
}

158
src/utils/requestAHYD.ts Normal file
View File

@ -0,0 +1,158 @@
import axios from 'axios';
import { getDvaApp } from 'umi';
import { notification } from 'antd';
import type { AxiosRequestHeaders } from 'axios/index';
import CryptoJS from "crypto-js";
const { UMI_APP_BASEURL } = process.env;
// const instance = axios.create({ baseURL: UMI_APP_BASEURL });
// const instance = axios.create({ baseURL: 'https://api.eshangtech.com/EShangApiMain' });
// const instance = axios.create({ baseURL: 'http://home.robot-z.cn:7001/' });
// 修改baseURL为完整的API地址确保在生产环境中正确访问
const instance = axios.create({ baseURL: 'https://ahyd.eshangtech.com/EShangApiMain' });
instance.interceptors.request.use(
(config) => {
// 对data数据进行加密
// if (config.data) {
// config.data = preprocessData(JSON.stringify(config.data)); // 调用预处理函数
// }
console.log('config', config);
const isUpload = config.url?.includes("/oss/upload");
config.headers = {
...config.headers,
Authorization: `Bearer ${localStorage.getItem('Authorization') || ''}`,
"Content-Type": isUpload ? "multipart/form-data" : "application/json;charset=utf-8",
} as AxiosRequestHeaders;
return config;
},
(error) => Promise.reject(error),
);
instance.interceptors.response.use(
//状态码为2xx的时候执行
(response) => {
const { data } = response;
if (data.Result_Code !== 100) {
notification.error({
message: data.message,
});
}
const timestamp = getFormattedDate()
return data
},
//状态码不是2xx的时候执行
(error) => {
const { response } = error;
if (response && response.status === 401) {
// // 清除本地存储的token
// localStorage.removeItem('Authorization');
// // 重定向到登录页
// window.location.href = '/user/login';
// notification.error({
// message: response?.data?.message || '请求失败',
// description: error.message
// });
} else {
notification.error({
message: response?.data?.message || '请求失败',
description: error.message
});
}
return Promise.reject({
code: response?.status || 500,
message: response?.data?.message || '请求失败'
});
},
);
// 加密
const encryptAESECB = (data: string, key: string) => {
// const cipher = CryptoJS.createCipheriv('aes-128-ecb', key, null); // ECB 模式不需要 IV
const newKey = CryptoJS.enc.Utf8.parse(key); // 密钥必须是 16 字节
const cipher = CryptoJS.AES.encrypt(data, newKey, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
let encrypted = cipher.ciphertext.toString(CryptoJS.enc.Hex);
// let encrypted = cipher.update(data, 'utf8', 'hex');
// encrypted += cipher.final('hex');
return encrypted;
}
// 解密
const decryptAESECB = (data: string, key: string) => {
// const decipher = CryptoJS.createDecipheriv('aes-128-ecb', key, null);
// let decrypted = decipher.update(data, 'hex', 'utf8');
// decrypted += decipher.final('utf8');
const newKey = CryptoJS.enc.Utf8.parse(key);
const encryptedData = CryptoJS.enc.Hex.parse(data);
// 解密操作
const decrypted = CryptoJS.AES.decrypt({ ciphertext: encryptedData }, newKey, {
mode: CryptoJS.mode.ECB, // ECB 模式
padding: CryptoJS.pad.Pkcs7 // PKCS7 填充方式
});
// 将解密后的结果转为 UTF-8 字符串
const decryptedText = decrypted.toString(CryptoJS.enc.Utf8);
return decryptedText;
}
// md5 签名
const md5 = (key: string, data: string, timestamp: string) => {
const text = "s" + key + data + timestamp;
return CryptoJS.MD5(text).toString(CryptoJS.enc.Hex);
}
// 生成签名戳
const getFormattedDate = () => {
const date = new Date();
const year = date.getFullYear(); // 获取年份 (yyyy)
const month = String(date.getMonth() + 1).padStart(2, '0'); // 获取月份 (MM)
const day = String(date.getDate()).padStart(2, '0'); // 获取日期 (dd)
const hours = String(date.getHours()).padStart(2, '0'); // 获取小时 (HH)
return `es0${year}${month}${day}${hours}0es`; // 拼接成 yyyyMMddHH 格式
}
// 加密方法
const preprocessData = (data: string) => {
console.log('data', data);
// YYYYMMDD
let timestamp = getFormattedDate()
console.log('timestamp', timestamp);
// 秒为单位的时间戳
let timeSecond = parseInt((new Date().getTime() / 1000).toString())
console.log('timeSecond', timeSecond);
// 数据的加密
let encryptionData = encryptAESECB(data, timestamp)
console.log('encryptionData', encryptionData);
// md5签名方法
let md5Data = md5(timestamp, encryptionData, timestamp)
console.log('md5Data', md5Data);
let res = {
data: encryptionData,
timestamp: timeSecond,
sign: md5Data
}
console.log('res', res);
return res
}
export default instance;

158
src/utils/requestCode.ts Normal file
View File

@ -0,0 +1,158 @@
import axios from 'axios';
import { getDvaApp } from 'umi';
import { notification } from 'antd';
import type { AxiosRequestHeaders } from 'axios/index';
import CryptoJS from "crypto-js";
const { UMI_APP_BASEURL } = process.env;
// const instance = axios.create({ baseURL: UMI_APP_BASEURL });
// const instance = axios.create({ baseURL: 'https://api.eshangtech.com/EShangApiMain' });
// const instance = axios.create({ baseURL: 'http://home.robot-z.cn:7001/' });
// 修改baseURL为完整的API地址确保在生产环境中正确访问
const instance = axios.create({ baseURL: 'https://api.eshangtech.com/CommercialApi' });
instance.interceptors.request.use(
(config) => {
// 对data数据进行加密
// if (config.data) {
// config.data = preprocessData(JSON.stringify(config.data)); // 调用预处理函数
// }
console.log('config', config);
const isUpload = config.url?.includes("/oss/upload");
config.headers = {
...config.headers,
Authorization: `Bearer ${localStorage.getItem('Authorization') || ''}`,
"Content-Type": isUpload ? "multipart/form-data" : "application/json;charset=utf-8",
} as AxiosRequestHeaders;
return config;
},
(error) => Promise.reject(error),
);
instance.interceptors.response.use(
//状态码为2xx的时候执行
(response) => {
const { data } = response;
if (data.Result_Code !== 100) {
notification.error({
message: data.message,
});
}
const timestamp = getFormattedDate()
return data
},
//状态码不是2xx的时候执行
(error) => {
const { response } = error;
if (response && response.status === 401) {
// // 清除本地存储的token
// localStorage.removeItem('Authorization');
// // 重定向到登录页
// window.location.href = '/user/login';
// notification.error({
// message: response?.data?.message || '请求失败',
// description: error.message
// });
} else {
notification.error({
message: response?.data?.message || '请求失败',
description: error.message
});
}
return Promise.reject({
code: response?.status || 500,
message: response?.data?.message || '请求失败'
});
},
);
// 加密
const encryptAESECB = (data: string, key: string) => {
// const cipher = CryptoJS.createCipheriv('aes-128-ecb', key, null); // ECB 模式不需要 IV
const newKey = CryptoJS.enc.Utf8.parse(key); // 密钥必须是 16 字节
const cipher = CryptoJS.AES.encrypt(data, newKey, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
let encrypted = cipher.ciphertext.toString(CryptoJS.enc.Hex);
// let encrypted = cipher.update(data, 'utf8', 'hex');
// encrypted += cipher.final('hex');
return encrypted;
}
// 解密
const decryptAESECB = (data: string, key: string) => {
// const decipher = CryptoJS.createDecipheriv('aes-128-ecb', key, null);
// let decrypted = decipher.update(data, 'hex', 'utf8');
// decrypted += decipher.final('utf8');
const newKey = CryptoJS.enc.Utf8.parse(key);
const encryptedData = CryptoJS.enc.Hex.parse(data);
// 解密操作
const decrypted = CryptoJS.AES.decrypt({ ciphertext: encryptedData }, newKey, {
mode: CryptoJS.mode.ECB, // ECB 模式
padding: CryptoJS.pad.Pkcs7 // PKCS7 填充方式
});
// 将解密后的结果转为 UTF-8 字符串
const decryptedText = decrypted.toString(CryptoJS.enc.Utf8);
return decryptedText;
}
// md5 签名
const md5 = (key: string, data: string, timestamp: string) => {
const text = "s" + key + data + timestamp;
return CryptoJS.MD5(text).toString(CryptoJS.enc.Hex);
}
// 生成签名戳
const getFormattedDate = () => {
const date = new Date();
const year = date.getFullYear(); // 获取年份 (yyyy)
const month = String(date.getMonth() + 1).padStart(2, '0'); // 获取月份 (MM)
const day = String(date.getDate()).padStart(2, '0'); // 获取日期 (dd)
const hours = String(date.getHours()).padStart(2, '0'); // 获取小时 (HH)
return `es0${year}${month}${day}${hours}0es`; // 拼接成 yyyyMMddHH 格式
}
// 加密方法
const preprocessData = (data: string) => {
console.log('data', data);
// YYYYMMDD
let timestamp = getFormattedDate()
console.log('timestamp', timestamp);
// 秒为单位的时间戳
let timeSecond = parseInt((new Date().getTime() / 1000).toString())
console.log('timeSecond', timeSecond);
// 数据的加密
let encryptionData = encryptAESECB(data, timestamp)
console.log('encryptionData', encryptionData);
// md5签名方法
let md5Data = md5(timestamp, encryptionData, timestamp)
console.log('md5Data', md5Data);
let res = {
data: encryptionData,
timestamp: timeSecond,
sign: md5Data
}
console.log('res', res);
return res
}
export default instance;

153
src/utils/requestMain.ts Normal file
View File

@ -0,0 +1,153 @@
import axios from 'axios';
import { getDvaApp } from 'umi';
import { notification } from 'antd';
import type { AxiosRequestHeaders } from 'axios/index';
import CryptoJS from "crypto-js";
const { UMI_APP_BASEURL } = process.env;
// const instance = axios.create({ baseURL: UMI_APP_BASEURL });
// const instance = axios.create({ baseURL: 'https://api.eshangtech.com/EShangApiMain' });
// const instance = axios.create({ baseURL: 'http://home.robot-z.cn:7001/' });
// 修改baseURL为完整的API地址确保在生产环境中正确访问
const instance = axios.create({ baseURL: 'https://api.eshangtech.com/EShangApiMain' });
instance.interceptors.request.use(
(config) => {
// 对data数据进行加密
// if (config.data) {
// config.data = preprocessData(JSON.stringify(config.data)); // 调用预处理函数
// }
config.headers = {
...config.headers,
} as AxiosRequestHeaders;
return config;
},
(error) => Promise.reject(error),
);
instance.interceptors.response.use(
//状态码为2xx的时候执行
(response) => {
const { data } = response;
// if (data.code !== 200) {
// notification.error({
// message: data.message,
// });
// }
const timestamp = getFormattedDate()
return data
},
//状态码不是2xx的时候执行
(error) => {
const { response } = error;
if (response && response.status === 401) {
// // 清除本地存储的token
// localStorage.removeItem('Authorization');
// // 重定向到登录页
// window.location.href = '/user/login';
// notification.error({
// message: response?.data?.message || '请求失败',
// description: error.message
// });
} else {
notification.error({
message: response?.data?.message || '请求失败',
description: error.message
});
}
return Promise.reject({
code: response?.status || 500,
message: response?.data?.message || '请求失败'
});
},
);
// 加密
const encryptAESECB = (data: string, key: string) => {
// const cipher = CryptoJS.createCipheriv('aes-128-ecb', key, null); // ECB 模式不需要 IV
const newKey = CryptoJS.enc.Utf8.parse(key); // 密钥必须是 16 字节
const cipher = CryptoJS.AES.encrypt(data, newKey, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
let encrypted = cipher.ciphertext.toString(CryptoJS.enc.Hex);
// let encrypted = cipher.update(data, 'utf8', 'hex');
// encrypted += cipher.final('hex');
return encrypted;
}
// 解密
const decryptAESECB = (data: string, key: string) => {
// const decipher = CryptoJS.createDecipheriv('aes-128-ecb', key, null);
// let decrypted = decipher.update(data, 'hex', 'utf8');
// decrypted += decipher.final('utf8');
const newKey = CryptoJS.enc.Utf8.parse(key);
const encryptedData = CryptoJS.enc.Hex.parse(data);
// 解密操作
const decrypted = CryptoJS.AES.decrypt({ ciphertext: encryptedData }, newKey, {
mode: CryptoJS.mode.ECB, // ECB 模式
padding: CryptoJS.pad.Pkcs7 // PKCS7 填充方式
});
// 将解密后的结果转为 UTF-8 字符串
const decryptedText = decrypted.toString(CryptoJS.enc.Utf8);
return decryptedText;
}
// md5 签名
const md5 = (key: string, data: string, timestamp: string) => {
const text = "s" + key + data + timestamp;
return CryptoJS.MD5(text).toString(CryptoJS.enc.Hex);
}
// 生成签名戳
const getFormattedDate = () => {
const date = new Date();
const year = date.getFullYear(); // 获取年份 (yyyy)
const month = String(date.getMonth() + 1).padStart(2, '0'); // 获取月份 (MM)
const day = String(date.getDate()).padStart(2, '0'); // 获取日期 (dd)
const hours = String(date.getHours()).padStart(2, '0'); // 获取小时 (HH)
return `es0${year}${month}${day}${hours}0es`; // 拼接成 yyyyMMddHH 格式
}
// 加密方法
const preprocessData = (data: string) => {
console.log('data', data);
// YYYYMMDD
let timestamp = getFormattedDate()
console.log('timestamp', timestamp);
// 秒为单位的时间戳
let timeSecond = parseInt((new Date().getTime() / 1000).toString())
console.log('timeSecond', timeSecond);
// 数据的加密
let encryptionData = encryptAESECB(data, timestamp)
console.log('encryptionData', encryptionData);
// md5签名方法
let md5Data = md5(timestamp, encryptionData, timestamp)
console.log('md5Data', md5Data);
let res = {
data: encryptionData,
timestamp: timeSecond,
sign: md5Data
}
console.log('res', res);
return res
}
export default instance;

View File

@ -25,7 +25,7 @@ instance.interceptors.request.use(
Authorization: `Bearer ${localStorage.getItem('Authorization') || ''}`,
"Content-Type": "application/json;charset=utf-8"
} as AxiosRequestHeaders;
return config;
},
(error) => Promise.reject(error),

View File

@ -8123,6 +8123,11 @@ nth-check@^2.0.1:
dependencies:
boolbase "^1.0.0"
numeral@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/numeral/-/numeral-2.0.6.tgz#4ad080936d443c2561aed9f2197efffe25f4e506"
integrity sha512-qaKRmtYPZ5qdw4jWJD6bxEf1FJEqllJrwxCLIm0sQU/A7v2/czigzOb+C2uSiFsa9lBUzeH7M1oK+Q+OLxL3kA==
object-assign@4.x, object-assign@^4, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
@ -10480,7 +10485,16 @@ string-convert@^0.2.0:
resolved "https://registry.npmmirror.com/string-convert/-/string-convert-0.2.1.tgz#6982cc3049fbb4cd85f8b24568b9d9bf39eeff97"
integrity sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
"string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@ -10578,7 +10592,14 @@ string_decoder@~1.1.1:
dependencies:
safe-buffer "~5.1.0"
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
version "6.0.1"
resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@ -11431,7 +11452,7 @@ word@~0.3.0:
resolved "https://registry.npmmirror.com/word/-/word-0.3.0.tgz#8542157e4f8e849f4a363a288992d47612db9961"
integrity sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
version "7.0.0"
resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@ -11449,6 +11470,15 @@ wrap-ansi@^6.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"
wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"
wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"