💥 feat(模块): 添加了个很棒的功能

This commit is contained in:
ylj20011123 2025-05-06 14:51:00 +08:00
parent c3e2c371bb
commit 3dfe0c92c8
27 changed files with 2267 additions and 518 deletions

View File

@ -1,3 +1,4 @@
// 路由配置文件
export default [
{
@ -11,6 +12,17 @@ export default [
}
]
},
{
path: '/',
routes: [
{
path: '/standard/index',
redirect: '',
name: '生成标准页面',
component: "@/pages/standard/index",
}
]
},
{
path: '/',
routes: [
@ -45,6 +57,11 @@ export default [
name: '考核记录管理',
component: "@/pages/examine/record/index",
},
{
path: '/examine/errorRecord',
name: '考核记录管理',
component: "@/pages/examine/errorRecord/index",
},
{
path: '/examine/recordSummary',
name: '考核记录汇总',
@ -52,18 +69,18 @@ export default [
}
]
},
{
path: "/setting",
redirect: '',
name: '系统设置',
routes: [
{
path: '/setting/menu',
name: '菜单管理',
component: "@/pages/setting/menu/index",
},
]
}
// {
// path: "/setting",
// redirect: '',
// name: '系统设置',
// routes: [
// {
// path: '/setting/menu',
// name: '菜单管理',
// component: "@/pages/setting/menu/index",
// },
// ]
// }
]
}

View File

@ -16,7 +16,9 @@
"crypto-js": "^4.2.0",
"dva": "^3.0.0-alpha.1",
"moment": "^2.30.1",
"numeral": "^2.0.6",
"qrcode": "^1.5.4",
"qs": "^6.14.0",
"umi": "^4.3.24",
"xlsx": "^0.18.5",
"xlsx-style-fixed": "^0.0.4"

View File

@ -11,7 +11,6 @@ const Avatar: FC<UserConnectedProps> = (props) => {
const {
user: { data }, dispatch,
} = props;
console.log('user32323', data);
const handleLogout = () => {
@ -46,15 +45,15 @@ const Avatar: FC<UserConnectedProps> = (props) => {
>
<Space className="avatar-container">
{
data.avatarUrl ? <img
data?.USER_HEADIMGURL ? <img
alt="avatar"
src={data.avatarUrl}
src={data.USER_HEADIMGURL}
className="avatar"
/> :
<IconFont name='icon-touxiang' size="36" ></IconFont>
}
<span className="username">{data.adminName}</span>
<span className="username">{data?.Name}</span>
</Space>
</Dropdown>
);

View File

@ -39,17 +39,19 @@ const LeftSelectTree = ({ setSelectedId, reload, actionRef, currentUser, width,
const { loading: treeLoading, data: treeViews } = useRequest(async () => {
let data: any = []
if (currentUser?.UserPattern === 2000) {
// data = await getMerchantShopTree({ BusinessManId: currentUser?.BusinessManID, ShowShop: false });
data = await getMerchantShopTree({ BusinessManId: currentUser?.BusinessManID, ShowShop: false });
} else {
// data = await getServerpartTree(currentUser?.provinceCode, currentUser?.CityAuthority, true, true, true, false, 1000)
let req: any = {
page: 1,
limit: 999,
sortBy: 'sort',
sortOrder: 'ASC',
code: '510000'
}
data = await handleGetAllServicePart(req)
data = await getServerpartTree(currentUser?.ProvinceCode, currentUser?.CityAuthority, true, true, true, false, 1000)
// let req: any = {
// page: 1,
// limit: 999,
// sortBy: 'sort',
// sortOrder: 'ASC',
// code: '510000'
// }
// data = await handleGetAllServicePart(req)
// data.data.list[0].key = data.data.list[0].id
// data = data.data.list
}
@ -217,23 +219,41 @@ const LeftSelectTree = ({ setSelectedId, reload, actionRef, currentUser, width,
>
{treeView && treeView.length > 0 ? <Tree
checkable
treeData={treeView}
treeData={[{
label: '全部',
value: 0,
key: '0-0',
children: treeView
}]}
fieldNames={{
title: "name",
key: "id"
title: "label",
key: "key"
}}
// fieldNames={{
// title: "name",
// key: "id"
// }}
blockNode
defaultExpandAll={isShowAllInTree ? true : false}
defaultExpandedKeys={isShowAllInTree ? [] : [510000]}
// defaultExpandAll={isShowAllInTree ? true : false}
defaultExpandedKeys={['0-0']}
onCheck={(checkedKeys: React.Key[] | any, info) => {
const selectedIds = info.checkedNodes.filter((n: any) => n?.districtId > 0)
setSelectedId(selectedIds.map(n => n?.id) || '')
const selectedIds = info.checkedNodes.filter((n: any) => n?.type === 1)
let id: string = selectedIds.map(n => n?.value)?.toString() || ''
setSelectedId(id.split(','))
if (reload) {
actionRef?.current?.reload()
}
if (otherFun) {
otherFun(info)
}
// const selectedIds = info.checkedNodes.filter((n: any) => n?.districtId > 0)
// setSelectedId(selectedIds.map(n => n?.id) || '')
// if (reload) {
// actionRef?.current?.reload()
// }
// if (otherFun) {
// otherFun(info)
// }
}}
/> : ''}
</ProCard>

View File

@ -34,6 +34,15 @@
}
}
}
.ant-menu{
.ant-menu-submenu{
ul{
.ant-menu-item-selected{
background-color: #1890ff !important;
}
}
}
}
}
}
}
@ -50,10 +59,6 @@
.ant-pro-menu-item-title {
color: #fff !important;
}
&:hover {
background-color: #1890ff !important;
}
}
}
@ -61,12 +66,12 @@
background-color: #1890ff !important;
color: #fff !important;
&:hover {
background-color: #1890ff !important;
a {
color: #fff !important;
}
a {
&:hover {
background-color: #1890ff !important;
color: #fff !important;
}
}

View File

@ -17,6 +17,7 @@ import upMenu from '@/assets/upMenu.svg'
import Icon, { DoubleRightOutlined, SmileOutlined } from '@ant-design/icons';
import { ProfileModelState } from '@/models/global';
import React from 'react';
import { handleChangeCildrenName } from '@/utils/format';
const { Header, Content } = Layout;
const { TabPane } = Tabs;
@ -88,22 +89,24 @@ const BasicLayout: FC<{ user: UserModelState, global: ProfileModelState, dispatc
//所有MenuItem:
//有children的: 一定都有path, lable不动, children下的label修改为<Link to={path} />
//无children的: 有path的label修改为<Link to={path} />, 没path的label不动
const consumableMenu = handleRecursiveNestedData(
menu,
(item: API.MenuItem) => ({
...item,
name: item.path
? (
<Link
to={item.path}
style={{ color: pathname === item.path ? '#1890ff' : 'inherit' }}
className={pathname === item.path ? 'ant-menu-item-selected' : ''}
>{item.name}</Link>
)
: item.name,
}),
);
console.log('consumableMenuconsumableMenuconsumableMenu', consumableMenu);
const consumableMenu = handleChangeCildrenName(menu)
// const consumableMenu = handleRecursiveNestedData(
// menu,
// (item: API.MenuItem) => ({
// ...item,
// name: item.path
// ? (
// <Link
// to={item.path}
// style={{ color: pathname === item.path ? '#1890ff' : 'inherit' }}
// className={pathname === item.path ? 'ant-menu-item-selected' : ''}
// >{item.name}</Link>
// )
// : item.name,
// }),
// );
// console.log('consumableMenuconsumableMenuconsumableMenu', consumableMenu);
// const consumableMenu: MenuDataItem[] = [
// {
@ -159,58 +162,95 @@ const BasicLayout: FC<{ user: UserModelState, global: ProfileModelState, dispatc
}
}
// 全部菜单一层的数组
const oneFloorList = [
{
SYSTEMMODULE_DESC: "",
guid: "1",
hideInMenu: false,
name: "生成标准页面",
path: "/standard/index",
},
{
SYSTEMMODULE_DESC: "",
guid: "2",
hideInMenu: false,
name: "考评分类管理",
path: "/examine/index",
},
{
SYSTEMMODULE_DESC: "",
guid: "3",
hideInMenu: false,
name: "考核问题管理",
path: "/examine/question",
},
{
SYSTEMMODULE_DESC: "",
guid: "4",
hideInMenu: false,
name: "考核点位管理",
path: "/examine/modal",
},
{
SYSTEMMODULE_DESC: "",
guid: "5",
hideInMenu: false,
name: "考核记录管理",
path: "/examine/record",
},
{
SYSTEMMODULE_DESC: "",
guid: "7",
hideInMenu: false,
name: "考核记录汇总",
path: "/examine/recordSummary",
},
{
SYSTEMMODULE_DESC: "",
guid: "6",
hideInMenu: false,
name: "菜单管理",
path: "/setting/menu",
// 拿到一层菜单的数据
const flattenSystemModules = (menus: any) => {
const result: any = [];
function traverse(node: any) {
if (node.systemModuleList && node.systemModuleList.length > 0) {
// 如果当前节点有 systemModuleList继续递归
node.systemModuleList.forEach(traverse);
} else {
// 如果没有 systemModuleList说明是最内层数据添加到结果
result.push({
...node,
name: node.systemmoduleName,
path: node.systemmoduleUrl,
});
}
}
]
menus.forEach(traverse);
return result;
}
console.log('menus', menu);
// 全部菜单一层的数组
const oneFloorList = flattenSystemModules(menu)
console.log('oneFloorListoneFloorList', oneFloorList);
// // 全部菜单一层的数组
// const oneFloorList = [
// {
// SYSTEMMODULE_DESC: "",
// guid: "1",
// hideInMenu: false,
// name: "生成标准页面",
// path: "/standard/index",
// },
// {
// SYSTEMMODULE_DESC: "",
// guid: "2",
// hideInMenu: false,
// name: "考评分类管理",
// path: "/examine/index",
// },
// {
// SYSTEMMODULE_DESC: "",
// guid: "3",
// hideInMenu: false,
// name: "考核问题管理",
// path: "/examine/question",
// },
// {
// SYSTEMMODULE_DESC: "",
// guid: "4",
// hideInMenu: false,
// name: "考核点位管理",
// path: "/examine/modal",
// },
// {
// SYSTEMMODULE_DESC: "",
// guid: "5",
// hideInMenu: false,
// name: "考核记录管理",
// path: "/examine/record",
// },
// {
// SYSTEMMODULE_DESC: "",
// guid: "8",
// hideInMenu: false,
// name: "考核异常管理",
// path: "/examine/errorRecord",
// },
// {
// SYSTEMMODULE_DESC: "",
// guid: "7",
// hideInMenu: false,
// name: "考核记录汇总",
// path: "/examine/recordSummary",
// },
// {
// SYSTEMMODULE_DESC: "",
// guid: "6",
// hideInMenu: false,
// name: "菜单管理",
// path: "/setting/menu",
// }
// ]
console.log('tabsRoutes', tabsRoutes);
console.log('location', location);
@ -247,16 +287,31 @@ const BasicLayout: FC<{ user: UserModelState, global: ProfileModelState, dispatc
);
}}
subMenuItemRender={(menuItemProps) => {
// 父级菜单不应该有跳转功能,只需要渲染显示内容
if (menuItemProps.icon && typeof menuItemProps.icon === 'string') {
const ele = React.createElement(Icon[menuItemProps.icon])
console.log('menuItemProps.icon', menuItemProps.icon);
// const iconString = "<SettingOutlined />";
const iconName = menuItemProps.icon.replace(/[<>/]/g, "").toString(); // 得到 "SettingOutlined"
return <div className="ant-pro-menu-item">
<span style={{ marginRight: 10 }} className="ant-pro-menu-item">{ele}</span>
<span className='ant-pro-menu-item-title'>{menuItemProps.name}</span>
{/* {<IconDynamic iconName={`${iconName}`} />} */}
<span className='ant-pro-menu-item-title'> {!collapsed && menuItemProps.name}</span>
</div>;
}
return <div>
{menuItemProps.name}
{!collapsed && menuItemProps.name}
</div>;
// if (menuItemProps.icon && typeof menuItemProps.icon === 'string') {
// const ele = React.createElement(Icon[menuItemProps.icon])
// return <div className="ant-pro-menu-item">
// <span style={{ marginRight: 10 }} className="ant-pro-menu-item">{ele}</span>
// <span className='ant-pro-menu-item-title'>{menuItemProps.name}</span>
// </div>;
// }
// return <div>
// {menuItemProps.name}
// </div>;
}}
menuItemRender={(menuItemProps, defaultDom) => {
if (

View File

@ -9,6 +9,8 @@ import handleGetRootSubmenuKeys from '@/utils/handleGetRootSubmenuKeys';
import handleGetEachDatumFromNestedDataByKey from '@/utils/handleGetEachDatumFromNestedDataByKey';
import handleGetIndexValidMenuItemByPath from '@/utils/handleGetIndexValidMenuItemByPath';
import { notification } from 'antd';
import { extractInnermostNodesAsMap, handleAllUserPermission } from '@/utils/format';
import { extractDeepestRoutes } from '@/utils/extractDeepestRoutes';
/**
*
@ -107,8 +109,11 @@ const UserModel: UserModelType = {
const res: API.LoginResponse = yield call(userLogin, payload);
console.log('res', res);
if (res.code === 200) {
localStorage.setItem('Authorization', res.data.accessToken);
if (res.Result_Code === 100) {
// localStorage.setItem('Authorization', res.Result_Data.token);
console.log('AuthorizationAuthorizationAuthorizationAuthorization', res);
localStorage.setItem('Authorization', res.Result_Data.UserToken);
yield put({
type: 'getUserInfoAuthorityMenu',
@ -124,7 +129,7 @@ const UserModel: UserModelType = {
loginBtnLoading: false,
},
});
return { code: res.code, message: res.message };
return res;
}
} catch (error) {
yield put({
@ -152,24 +157,24 @@ const UserModel: UserModelType = {
return false;
}
let userInfoRes: API.UserInfoResponse = {
data: {},
code: 0,
message: '',
let userInfoRes: any = {
Result_Data: {},
Result_Code: 0,
Result_Desc: '',
};
let userAuthorityRes: API.UserAuthorityResponse = {
data: {
let userAuthorityRes: any = {
Result_Data: {
authority: [],
},
code: 0,
message: '',
Result_Code: 0,
Result_Desc: '',
};
let menuRes: API.MenuDataResponse = {
data: [],
code: 0,
message: '',
let menuRes: any = {
Result_Data: [],
Result_Code: 0,
Result_Desc: '',
};
console.log('type', type);
@ -178,12 +183,32 @@ const UserModel: UserModelType = {
const res: API.UserInfoAuthMenuResponse = yield call(retrieveUserInfoAuthorityMenu);
console.log('res', res);
userInfoRes = res[0] as API.UserInfoResponse;
// userAuthorityRes = res[1] as API.UserAuthorityResponse;
menuRes = res[1] as API.MenuDataResponse;
userAuthorityRes = res[1] as API.UserAuthorityResponse;
menuRes = res[2] as API.MenuDataResponse;
} else {
//其他情形首先查询用户的登录状态, 未登录则不继续操作
try {
userInfoRes = yield call(retrieveUserInfo);
console.log('userInfoResuserInfoResuserInfoResuserInfoRes', userInfoRes);
if (userInfoRes && userInfoRes.ID) {
} else {
yield put({
type: 'save',
payload: {
layoutWrapperLoading: false,
},
});
// 只有在非登录页面时才执行重定向
if (window.location.pathname !== '/user/login') {
yield put({
type: 'resetLoginStatus',
});
}
return false;
}
} catch (error) {
//接口报错了, 比如返回了401
yield put({
@ -204,73 +229,92 @@ const UserModel: UserModelType = {
}
const res: API.UserAuthMenuResponse = yield call(retrieveUserAuthorityMenu);
// userAuthorityRes = res[0] as API.UserAuthorityResponse;
menuRes = res[0] as API.MenuDataResponse;
userAuthorityRes = res[0] as API.UserAuthorityResponse;
menuRes = res[1] as API.MenuDataResponse;
}
console.log('userInfoRes', userInfoRes);
let userAuthorityList: any = []
if (userAuthorityRes && userAuthorityRes.length > 0) {
userAuthorityList = handleAllUserPermission(userAuthorityRes)
}
console.log('userAuthorityList', userAuthorityList);
// menuRes.data = [
// {
// path: '/standard/index',
// redirect: '',
// name: '生成标准页面',
// component: "@/pages/standard/index",
// },
// {
// path: '/examine',
// redirect: '',
// name: '走动式管理',
// children: [
// {
// path: '/examine/index',
// name: '考评分类管理',
// component: "@/pages/examine/index",
// },
// {
// path: '/examine/question',
// name: '考核问题管理',
// component: "@/pages/examine/question",
// },
// {
// path: '/examine/modal',
// name: '考核模版管理',
// component: "@/pages/examine/modal",
// },
// {
// path: '/examine/errorRecord',
// name: '考核异常管理',
// component: "@/pages/examine/errorRecord",
// },
// {
// path: '/examine/record',
// name: '考核记录管理',
// component: "@/pages/examine/record",
// },
// {
// path: '/examine/recordSummary',
// name: '考核记录汇总',
// component: "@/pages/examine/recordSummary",
// },
// ]
// },
// {
// path: "/setting",
// redirect: '',
// name: '系统设置',
// children: [
// {
// path: '/setting/menu',
// name: '菜单管理',
// component: "@/pages/setting/menu/index",
// },
// ]
// }
// ]
console.log('1', menuRes);
let allUserAuthority: any = extractInnermostNodesAsMap(menuRes) || []
console.log('allUserAuthority', allUserAuthority);
menuRes.data = [
{
path: '/standard/index',
redirect: '',
name: '生成标准页面',
component: "@/pages/standard/index",
},
{
path: '/examine',
redirect: '',
name: '走动式管理',
children: [
{
path: '/examine/index',
name: '考评分类管理',
component: "@/pages/examine/index",
},
{
path: '/examine/question',
name: '考核问题管理',
component: "@/pages/examine/question",
},
{
path: '/examine/modal',
name: '考核模版管理',
component: "@/pages/examine/modal",
},
{
path: '/examine/record',
name: '考核记录管理',
component: "@/pages/examine/record",
},
{
path: '/examine/recordSummary',
name: '考核记录汇总',
component: "@/pages/examine/recordSummary",
},
]
},
{
path: "/setting",
redirect: '',
name: '系统设置',
children: [
{
path: '/setting/menu',
name: '菜单管理',
component: "@/pages/setting/menu/index",
},
]
}
]
let indexAllMenuItemByPath: any = []
let indexValidMenuItemByPath: any = []
if (menuRes.data && menuRes.data.length > 0) {
indexAllMenuItemByPath = handleGetEachDatumFromNestedDataByKey(menuRes.data, 'path');
indexValidMenuItemByPath = handleGetIndexValidMenuItemByPath(menuRes.data);
if (menuRes && menuRes.length > 0) {
indexAllMenuItemByPath = extractDeepestRoutes(menuRes);
// indexValidMenuItemByPath = handleGetIndexValidMenuItemByPath(menuRes);
indexValidMenuItemByPath = extractDeepestRoutes(menuRes)
}
console.log('indexAllMenuItemByPath', indexAllMenuItemByPath);
console.log('indexValidMenuItemByPath', indexValidMenuItemByPath);
//在登录完获取菜单数据之后做是否需要重定向的操作
yield call(
handleRedirect,
@ -282,24 +326,30 @@ const UserModel: UserModelType = {
type: 'save',
payload: {
isLogin: true,
menu: menuRes.data,
data: userInfoRes.data,
// menu: menuRes.data,
// data: userInfoRes.data,
menu: menuRes || [],
data: userInfoRes || [],
loginBtnLoading: false,
indexAllMenuItemByPath,
indexValidMenuItemByPath,
allUserAuthority: allUserAuthority,
layoutWrapperLoading: false,
// authority: userAuthorityRes.data.authority,
authority: [
'/standard/index',
'/examine/index',
'/examine/modal',
'/examine/question',
'/examine/record',
'/setting/menu',
'/examine/recordSummary'
],
rootSubmenuKeys: handleGetRootSubmenuKeys(menuRes.data),
indexAllMenuItemById: handleGetEachDatumFromNestedDataByKey(menuRes.data, 'id'),
authority: userAuthorityList,
// authority: [
// '/standard/index',
// '/examine/index',
// '/examine/modal',
// '/examine/question',
// '/examine/record',
// '/setting/menu',
// '/examine/recordSummary',
// "/examine/errorRecord"
// ],
// rootSubmenuKeys: handleGetRootSubmenuKeys(menuRes.data),
// indexAllMenuItemById: handleGetEachDatumFromNestedDataByKey(menuRes.data, 'id'),
rootSubmenuKeys: menuRes && menuRes.length > 0 ? handleGetRootSubmenuKeys(menuRes) : "",
indexAllMenuItemById: menuRes && menuRes.length > 0 ? handleGetEachDatumFromNestedDataByKey(menuRes, 'id') : "",
},
});
//为保证所有语句都return, 因此这里加一句这个

View File

@ -17,6 +17,9 @@ const authority: PageAuthority = {
'/examine/recordSummary': [
'/examine/recordSummary',
],
'/examine/errorRecord': [
'/examine/errorRecord'
],
'/setting/menu': ['/setting/menu']
};

View File

@ -0,0 +1,505 @@
import { ConnectState } from "@/models/global";
import { ActionType, FormInstance, ProTable } from "@ant-design/pro-components";
import { useRef, useState } from "react";
import { connect } from "umi";
import moment from "moment";
import { Button, Drawer, Image, message, Popconfirm, Space } from "antd";
import { handleGetServerpartDDL } from "@/components/leftSelectTree/service";
import LeftSelectTree from "@/components/leftSelectTree/leftSelectTree";
import RecordDetail from "../record/components/recordDetail";
import { handleDeleteRecord, handleGetRecordTreeList, handleUpdateExtend } from "../record/service";
const ErrorRecord: React.FC<{ currentUser: any }> = (props) => {
const { currentUser } = props
const actionRef = useRef<ActionType>();
const formRef = useRef<FormInstance>();
const recordDetailRef = useRef<any>()
// 显示的附件数据
const [showImgList, setShowImgList] = useState<string[]>([])
// 预览图片
const [imagePreviewVisible, setImagePreviewVisible] = useState<boolean>(false)
// 预览的索引
const [previewIndex, setPreviewIndex] = useState<number>(0)
// 当行数据
const [currentRow, setCurrentRow] = useState<any>()
// 显示详情抽屉
const [showDetail, setShowDetail] = useState<boolean>(false)
// 判断是否点了出现的是异常处理的抽屉
const [showAbnormal, setShowAbnormal] = useState<boolean>(false)
// 树相关的属性和方法
const [selectedId, setSelectedId] = useState<string[]>()
const [columnsStateMap, setColumnsStateMap] = useState<any>({
score: { show: false }
})
const [collapsible, setCollapsible] = useState<boolean>(false)
const columns: any = [
// {
// title: "统计月份",
// dataIndex: "search_months",
// hideInTable: true,
// valueType: "date",
// initialValue: moment().subtract('1', 'd'),
// fieldProps: {
// picker: "month",
// format: 'YYYY-MM',
// }
// },
// {
// title: "统计日期",
// dataIndex: "staticDate",
// hideInTable: true,
// valueType: "dateRange",
// initialValue: [moment().startOf('M'), moment()],
// search: {
// transform: (value: any) => {
// return {
// startTime: moment(value[0]).format('YYYY-MM-DD'),
// endTime: moment(value[1]).format('YYYY-MM-DD')
// };
// },
// },
// fieldProps: {
// picker: "day",
// format: 'YYYY-MM-DD',
// }
// },
// {
// title: "服务区",
// dataIndex: "serverPartId",
// hideInTable: true,
// valueType: "select",
// request: async () => {
// const req = {
// ProvinceCode: currentUser?.provinceCode,
// StatisticsType: 1000
// }
// const data = await handleGetServerpartDDL(req)
// return data
// }
// },
// {
// title: "巡查类型",
// dataIndex: "inspectionType",
// hideInTable: true,
// valueType: "select",
// valueEnum: {
// "1": '异常',
// "0": "正常"
// }
// },
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "serverPartName",
hideInSearch: true,
width: 200,
ellipsis: true,
render: (_, record) => {
return record?.type === 'district' || record?.type === 'servicePart' ? record?.name :
record?.template ? record?.template.title : "-"
// return record?.name ? record?.name : record?.template && record?.serverPartName ? record?.serverPartName : "-"
}
},
// {
// title: <div style={{ textAlign: 'center' }}>站点名称</div>,
// dataIndex: "placeName",
// hideInSearch: true,
// width: 150,
// ellipsis: true,
// render: (_, record) => {
// return record?.template && record?.template.title ? record?.template.title : "-"
// }
// },
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "placeName",
hideInSearch: true,
width: 100,
align: 'center',
ellipsis: true,
render: (_, record) => {
// let res: any = record.extend ? JSON.parse(record.extend) : "-"
return <span style={{ color: record.situation === 1 ? "red" : "" }}>{record.situation === 1 ? '异常' : record.situation === 0 ? '正常' : ''}</span>
}
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "uploadResult",
hideInSearch: true,
width: 200,
ellipsis: true,
render: (_, record) => {
// let extendObj = record?.extend ? JSON.parse(record?.extend) : ""
return record?.uploadResult ? record?.uploadResult : "-"
}
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "uploadResult",
hideInSearch: true,
width: 350,
ellipsis: true,
render: (_, record) => {
let str: string = ''
if (record?.questionResponses && record?.questionResponses.length > 0) {
record?.questionResponses.forEach((item: any, index: number) => {
let anwers: string = ''
if (item.choiceResponse && item.choiceResponse.length > 0) {
item.choiceResponse.forEach((subItem: string, subIndex: number) => {
anwers += `${subIndex > 0 ? '' : ''}${subItem}`
})
}
str += `${index > 0 ? '' : ''}考核内容:${item.question.title},考核结果:${anwers}`
})
}
return str || ''
}
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "score",
hideInSearch: true,
valueType: 'digit',
width: 100,
align: 'center',
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "errorStatus",
// hideInSearch: true,
width: 100,
valueType: 'select',
valueEnum: {
"0": "待处理",
"1": "处理中",
"2": "已处理",
},
ellipsis: true,
align: 'center',
render: (_, record) => {
// let res: any = record.extend ? JSON.parse(record.extend) : "-"
return record?.situation !== 0 ? <span style={{ color: record.errorStatus === 0 ? "red" : record.errorStatus === 1 ? "#1677ff" : "" }}>{
record.errorStatus === 0
? "待处理"
: record.errorStatus === 1
? "处理中"
: record.errorStatus === 2
? "已处理"
: "-"
}</span> : ""
}
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "createdAt",
hideInSearch: true,
width: 150,
ellipsis: true,
align: 'center',
render: (_, record) => {
return record?.createdAt ? moment(record?.createdAt).format('YYYY-MM-DD HH:mm:ss') : '-'
}
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "userName",
hideInSearch: true,
width: 100,
ellipsis: true,
align: 'center',
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "placeName",
hideInSearch: true,
width: 150,
ellipsis: true,
align: 'center',
render: (_, record) => {
// let extendObj = record?.extend ? JSON.parse(record?.extend) : ""
let imgList = record.imgsList
return imgList && imgList.length > 0 ?
<Button type="primary" onClick={() => {
setShowImgList(imgList)
setImagePreviewVisible(true)
}}></Button> : "-"
}
},
{
title: '操作',
dataIndex: 'option',
align: 'center',
fixed: "right",
hideInSearch: true,
width: 150,
render: (_: any, record: any) => {
// let res: any = record.extend ? JSON.parse(record.extend) : "-"
return record?.type === 'district' || record?.type === 'servicePart' ? '' : <Space>
{
record.situation === 1 ?
<a onClick={
() => {
setCurrentRow({
...record,
})
setShowAbnormal(true)
setShowDetail(true)
}
}></a> : < a onClick={() => {
setCurrentRow({
...record,
})
setShowDetail(true)
}}>
</a >
}
<Popconfirm
title={"确认删除?"}
onConfirm={async () => {
deleteRecord(record?.id)
}}
>
<a></a>
</Popconfirm>
</Space >
}
}
]
// 删除记录
const deleteRecord = async (id: any) => {
const data = await handleDeleteRecord({ id: id })
if (data.Result_Code === 100) {
message.success(data.Result_Desc)
actionRef.current?.reload()
}
}
return (
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} currentUser={currentUser} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
// width: "100%",
paddingTop: 0,
paddingBottom: 0,
paddingRight: 0
}}>
<ProTable
actionRef={actionRef}
formRef={formRef}
columns={columns}
bordered
expandable={{
expandRowByClick: true
}}
rowKey={(record) => {
return `${record?.id}-${record?.code}-${record?.templateId}`
}}
scroll={{ x: "100%", y: 'calc(100vh - 400px)' }}
headerTitle={<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}></span>}
search={{ span: 6 }}
request={async (params) => {
// selectedId
console.log('params', params);
console.log('selectedId', selectedId);
if (!(selectedId && selectedId.length > 0)) {
return
}
const req: any = {
serverPartIds: selectedId && selectedId.length > 0 ? selectedId : [],
// startTime: params?.search_months ? `${moment(params?.search_months).startOf('M').format('YYYY-MM-DD')}` : "",
// endTime: params?.search_months ? `${moment(params?.search_months).endOf('M').format('YYYY-MM-DD')}` : "",
// serverPartId: params?.serverPartId ? params?.serverPartId : undefined,
extend: params?.errorStatus ? [{
key: "situation",
value: '1'
},
{
key: "errorStatus",
value: params?.errorStatus
}
] : [{
key: "situation",
value: '1'
}]
}
console.log('req', req);
const data = await handleGetRecordTreeList(req)
console.log('data', data);
if (data && data.length > 0) {
return { data, success: true }
}
return { data: [], success: true }
}}
toolbar={{
}}
columnsState={{
value: columnsStateMap,
onChange: setColumnsStateMap,
}}
>
</ProTable>
</div>
{
showImgList && showImgList.length > 0 && <div style={{ display: 'none' }}>
<Image.PreviewGroup
preview={{
visible: imagePreviewVisible,
onVisibleChange: vis => {
setImagePreviewVisible(vis)
},
current: previewIndex
}}>
{
showImgList.map((n) =>
<Image src={n} key={n} />
)
}
</Image.PreviewGroup>
</div>
}
<Drawer
title={false}
closeIcon={false}
onClose={() => {
setShowDetail(false)
setShowAbnormal(false)
}}
open={showDetail}
destroyOnClose
width={'60%'}
footer={showAbnormal && currentRow?.errorStatus !== 2 ? <div style={{ width: "100%", boxSizing: 'border-box', padding: "0 24px", display: 'flex', justifyContent: 'flex-end' }}>
<Button type="primary" onClick={() => {
console.log('recordDetailRef.current?.formRes.errorStatus', recordDetailRef.current?.formRes.errorStatus);
if (recordDetailRef.current?.formRes.errorStatus === 0) {
recordDetailRef.current?.errorStatusFormRef.current?.validateFields().then(async (res: any) => {
console.log('res', res);
let extendObj = JSON.parse(recordDetailRef.current?.formRes.extend)
let personObj: any = {}
let personList: any = recordDetailRef.current?.selectPersonList
if (personList && personList.length > 0) {
personList.forEach((item: any) => {
if (item.STAFF_ID === res.personIndex) {
personObj = item
}
})
}
console.log('personObj', personObj);
const req = {
...extendObj,
// person: personObj,
questionnaireResponsesId: recordDetailRef.current?.formRes.id,
personId: personObj.STAFF_ID,
personMemberShipId: personObj.MEMBERSHIP_ID,
personMemberShipName: personObj.MEMBERSHIP_NAME,
personName: personObj.STAFF_NAME,
errorStatus: 1,
suggestion: res.suggestion,
suggestTime: moment().format('YYYY-MM-DD HH:mm:ss'), // 选处理人的时间
// suggestPerson: {
// STAFF_NAME: currentUser.adminName,
// STAFF_ID: currentUser.id,
// MEMBERSHIP_NAME: currentUser.adminName,
// MEMBERSHIP_ID: currentUser.id,
// },
suggestMemberShipId: currentUser.id,
suggestMemberShipName: currentUser.adminName,
suggestPersonId: currentUser.id,
suggestPersonName: currentUser.adminName,
};
const data = await handleUpdateExtend(req)
if (data.Result_Code === 100) {
message.success('提交成功')
setShowDetail(false)
setShowAbnormal(false)
actionRef.current?.reload()
setCurrentRow(undefined)
} else {
message.error(data.Result_Desc)
}
})
}
if (recordDetailRef.current?.formRes.errorStatus === 1) {
recordDetailRef.current?.errorStatusFormReflast.current?.validateFields().then(async (res: any) => {
console.log('res', res);
let extendObj = JSON.parse(recordDetailRef.current?.formRes.extend)
console.log('recordDetailRef.current?.fileList', recordDetailRef.current?.fileList);
let fileList: any = []
if (recordDetailRef.current?.fileList && recordDetailRef.current?.fileList.length > 0) {
recordDetailRef.current?.fileList.forEach((item: any) => {
// fileList.push(item.url)
fileList.push({
keyName: item.id,
imageUrl: item.url
})
// keyName: item.id,
// imageUrl: subItem
})
}
console.log('fileList', fileList);
const req = {
...extendObj,
questionnaireResponsesId: recordDetailRef.current?.formRes.id,
feedbackImgList: fileList,
feedbackContent: res.feedbackContent,
feedbackTime: moment().format('YYYY-MM-DD HH:mm:ss'), // 反馈时间
errorStatus: 2,
};
const data = await handleUpdateExtend(req)
if (data.Result_Code === 100) {
message.success('提交成功')
setShowDetail(false)
setShowAbnormal(false)
actionRef.current?.reload()
setCurrentRow(undefined)
} else {
message.error(data.Result_Desc)
}
})
}
}}></Button>
</div> : false
}
>
<RecordDetail onRef={recordDetailRef} parentRow={currentRow} show={showDetail} showError={showAbnormal} />
</Drawer >
</div >
)
}
export default connect(({ user }: ConnectState) => ({
currentUser: user.data
}))(ErrorRecord);

View File

@ -50,7 +50,12 @@ const examineIndex: React.FC<{ currentUser: any }> = (props) => {
ellipsis: true,
align: 'center',
width: 150,
hideInSearch: true,
valueType: "select",
valueEnum: {
"1": "有效",
"0": "无效"
},
initialValue: "1",
render: (_: any, record: { status: any; }) => {
return record?.status ? '有效' : '无效'
}
@ -170,7 +175,12 @@ const examineIndex: React.FC<{ currentUser: any }> = (props) => {
headerTitle={<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}></span>}
search={{ span: 6 }}
request={async (params) => {
const req = {}
console.log('params', params);
const req = {
status: params?.status === '1' ? true : params?.status === '0' ? false : ""
}
let data = await handleGetExamineTypeTreeList(req)
console.log('table', data);
if (data && data.length > 0) {

View File

@ -14,7 +14,16 @@ export async function handleGetExamineTypeList(params?: any) {
// 拿树形的
export async function handleGetExamineTypeTreeList(params?: any) {
const data = await request.get('/question-categories/tree', params)
const data = await request.get('/question-categories/tree', { params })
if (data.Result_Code === 100) {
return data.Result_Data.List
}
return []
}
// 拿树形的 有分类 有问题的
export async function handleGetAllTypeQuestion(params?: any) {
const data = await request.post('/questions/search/tree', params)
if (data.Result_Code === 100) {
return data.Result_Data.List
}

View File

@ -1175,6 +1175,8 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
batchCloneForm.current?.resetFields()
setshowBatchCloneModal(false)
setCurrentRow(undefined)
setSelectCloneServiceDetail(undefined)
setSelectCloneServiceList(undefined)
} else {
message.error(data.Result_Desc)
}
@ -1234,6 +1236,8 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
onCancel={() => {
setshowBatchCloneModal(false)
batchCloneForm.current?.resetFields()
setSelectCloneServiceDetail(undefined)
setSelectCloneServiceList(undefined)
}}
>
@ -1267,7 +1271,7 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
}
]}
rowSelection={{
type: "radio",
type: "checked",
defaultSelectedRowKeys: selectCloneServiceList,
getCheckboxProps: (record) => ({
disabled: record.type === "district",

View File

@ -70,7 +70,7 @@ const addQuestion = ({ parentRow, onRef, currentUser, showQuestionModal, setShow
description: `${res.categoryId && categoryIdObj ? categoryIdObj[res.categoryId] : ''}`,
category: undefined
}
console.log('req', req);
console.log('reqreqreqreqreq', req);
data = await handleEditQuestion(req)
} else {

View File

@ -4,9 +4,10 @@ import { Button, Col, message, Modal, Popconfirm, Row, Space } from "antd";
import { useRef, useState } from "react";
import { connect } from "umi";
import { handleAddQuestion, handleDeleteQuestion, handleEditQuestion, handleGetQuestionList } from "./service";
import { handleGetAddExamineType, handleGetExamineTypeList, handleGetExamineTypeTreeList } from "../index/service";
import { handleGetAddExamineType, handleGetAllTypeQuestion, handleGetExamineTypeList, handleGetExamineTypeTreeList } from "../index/service";
import moment from "moment";
import AddQuestion from "./components/addQuestion";
import { request } from "express";
const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
const { currentUser } = props
@ -42,6 +43,16 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
dataIndex: "id",
hideInTable: true,
valueType: 'treeSelect',
request: async () => {
const typeReq = {
// any: [{
// "key": ""
// }]
}
let typeData = await handleGetExamineTypeTreeList(typeReq)
console.log('typeData', typeData);
return typeData
},
fieldProps: {
multiple: false,
treeDefaultExpandAll: true,
@ -52,7 +63,7 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
label: "name",
value: "id"
},
options: bigTypeList || []
// options: bigTypeList || []
}
},
{
@ -81,6 +92,23 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
return questionType === 'radio' ? '单选' : questionType === 'checked' ? "多选" : ""
}
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "status",
width: 100,
// hideInSearch: true,
align: 'center',
valueType: "select",
ellipsis: true,
valueEnum: {
"1": "有效",
"0": "无效"
},
initialValue: "1",
render: (_, record) => {
return record?.type ? record?.status ? '有效' : '无效' : ""
}
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "required",
@ -146,7 +174,7 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
hideInSearch: true,
width: 100,
render: (_: any, record: any) => {
return record?.isNoChildren ? <Space>
return record?.type ? <Space>
<a onClick={() => {
console.log('record', record);
setCurrentRow(record)
@ -195,10 +223,6 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
// 检查当前节点是否匹配list中的categoryId
const matchedItems = itemsToInsert.filter(item => item.categoryId === node.id);
console.log('node', node);
console.log('matchedItems', matchedItems);
if (matchedItems.length > 0) {
// 如果匹配到初始化children数组如果不存在
if (!node.children) {
@ -274,30 +298,53 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
request={async (params) => {
console.log('params', params);
// 拿到分类数据 将 问题数据 拼到对应的分类下面去
const typeReq = {
any: [{
"key": ""
const req: any = {
any: params?.id ? [{
key: "title",
value: params?.title || ""
},
{
key: "categoryId",
value: params?.id
}] : [{
key: "title",
value: params?.title || ""
}]
}
params?.id
let typeData = await handleGetExamineTypeTreeList(typeReq)
let bigType = JSON.parse(JSON.stringify(typeData))
console.log('bigType', bigType);
setBigTypeList(bigType)
const req = {
any: params?.title ? [{ key: "title", value: params?.title }] : undefined
}
const data = await handleGetQuestionList(req)
console.log('data3231231231', data);
const data = await handleGetAllTypeQuestion(req)
let res = await handleGetNewQuestion(typeData, data)
console.log('res432423', res);
if (res && res.length > 0) {
return { data: res, success: true }
console.log('data', data);
if (data && data.length > 0) {
return { data: data, success: true }
}
return { data: [], success: true }
// // 拿到分类数据 将 问题数据 拼到对应的分类下面去
// const typeReq = {
// any: [{
// "key": ""
// }]
// }
// let typeData = await handleGetExamineTypeTreeList(typeReq)
// let bigType = JSON.parse(JSON.stringify(typeData))
// console.log('bigType', bigType);
// setBigTypeList(bigType)
// const req = {
// any: params?.title ? [{ key: "title", value: params?.title }] : undefined
// }
// const data = await handleGetQuestionList(req)
// console.log('data3231231231', data);
// let res = await handleGetNewQuestion(typeData, data)
// console.log('res432423', res);
// if (res && res.length > 0) {
// return { data: res, success: true }
// }
// return { data: [], success: true }
}}
toolbar={{
actions: [

View File

@ -33,6 +33,8 @@ const RecordDetail = ({ parentRow, show, detailType, currentUser, onRef, showErr
const errorStatusFormReflast = useRef<FormInstance>();
// 表格数据
const [proTableData, setTableData] = useState<any>([])
// 打印的数据
const [printlnTableData, setPrintTableData] = useState<any>([])
const [formRes, setFormRes] = useState<any>()
// 打印相关状态
@ -88,7 +90,7 @@ const RecordDetail = ({ parentRow, show, detailType, currentUser, onRef, showErr
}
return str || ""
}
}
},
]
useEffect(() => {
@ -308,7 +310,7 @@ const RecordDetail = ({ parentRow, show, detailType, currentUser, onRef, showErr
// 打印表格方法
const handlePrintTable = () => {
// 获取表格数据
const tableData = proTableData || [];
const tableData = printlnTableData || [];
// 创建一个iframe用于打印这样可以避免CSS冲突
const printIframe = document.createElement('iframe');
@ -413,7 +415,7 @@ const RecordDetail = ({ parentRow, show, detailType, currentUser, onRef, showErr
<tbody>
${formRes.errorStatus >= 1 ? `<tr>
<td style="width: 100px"></td>
<td>${formRes.suggestPerson.STAFF_NAME || '-'}</td>
<td>${formRes.personMemberShipName || '-'}</td>
<td style="width: 100px"></td>
<td>${formRes.suggestTime || '-'}</td>
</tr>
@ -425,7 +427,7 @@ const RecordDetail = ({ parentRow, show, detailType, currentUser, onRef, showErr
${formRes.errorStatus === 2 ? `
<tr>
<td style="width: 100px"></td>
<td>${formRes.person.STAFF_NAME || '-'}</td>
<td>${formRes.personName || '-'}</td>
<td style="width: 100px"></td>
<td>${formRes.feedbackTime || '-'}</td>
</tr>
@ -598,7 +600,7 @@ const RecordDetail = ({ parentRow, show, detailType, currentUser, onRef, showErr
return {
...formRes,
personIndex: formRes.person.STAFF_ID
personIndex: formRes.personId
}
}}
>
@ -646,7 +648,7 @@ const RecordDetail = ({ parentRow, show, detailType, currentUser, onRef, showErr
</ProForm> : ""
}
{
showError && formRes && formRes.errorStatus >= 1 ?
showError && formRes && formRes.errorStatus >= 2 ?
<ProForm
formRef={errorStatusFormReflast}
submitter={false}
@ -689,7 +691,7 @@ const RecordDetail = ({ parentRow, show, detailType, currentUser, onRef, showErr
formData.append('file', info.file, typeof info.file !== 'string' ? info.file?.name : '');
const data = await handleUploadFile(formData)
console.log('data', data);
let url = `https://es.robot-z.cn/${data.data.path}`
let url = `https://es.eshangtech.com/${data.data.path}`
let file = JSON.parse(JSON.stringify(fileList))
file.push({
uid: '',
@ -763,23 +765,30 @@ const RecordDetail = ({ parentRow, show, detailType, currentUser, onRef, showErr
})
}
setExamineObj(obj)
console.log('resresres', res);
let tableData = await handeGetTableData(typeData, res)
console.log('tableData', tableData);
// 拿到整个数据之后 递归取出tableData中有 question 数据的那一层数据变为一个数组
let tableRes = await handleGetTableRes(tableData, obj)
console.log('tableRes', tableRes);
let newTableRes: any = []
if (tableRes && tableRes.length > 0) {
tableRes.forEach((item: any) => {
if (item.score === 0) {
newTableRes.push(item)
}
})
}
// 显示的
// 处理表格数据,为合并单元格做准备
let processedData = processTableDataForMerge(tableRes);
let processedData = processTableDataForMerge(newTableRes);
// 打印的
let printData = processTableDataForMerge(tableRes)
console.log('processedData', processedData);
setTableData(processedData)
setPrintTableData(printData)
if (processedData && processedData.length > 0) {
return { data: processedData, success: true }

View File

@ -2,7 +2,7 @@ import { ConnectState } from "@/models/global";
import { ActionType, FormInstance, ProTable } from "@ant-design/pro-components";
import { useRef, useState } from "react";
import { connect } from "umi";
import { handleDeleteRecord, handleGetRecordList, handleGetRecordTreeList, handleUpdateExtend } from "./service";
import { handleDeleteRecord, handleGetNoTimeRecordTreeList, handleGetRecordList, handleGetRecordTreeList, handleUpdateExtend } from "./service";
import moment from "moment";
import { Button, Drawer, Image, message, Popconfirm, Space } from "antd";
import { handleGetServerpartDDL } from "@/components/leftSelectTree/service";
@ -35,32 +35,32 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
const [collapsible, setCollapsible] = useState<boolean>(false)
const columns: any = [
{
title: "统计日期",
dataIndex: "staticDate",
hideInTable: true,
valueType: "date",
initialValue: moment().subtract('1', 'd'),
},
// {
// title: "统计日期",
// dataIndex: "staticDate",
// hideInTable: true,
// valueType: "dateRange",
// initialValue: [moment().startOf('M'), moment()],
// search: {
// transform: (value: any) => {
// return {
// startTime: moment(value[0]).format('YYYY-MM-DD'),
// endTime: moment(value[1]).format('YYYY-MM-DD')
// };
// },
// },
// fieldProps: {
// picker: "day",
// format: 'YYYY-MM-DD',
// }
// valueType: "date",
// initialValue: moment().subtract('1', 'd'),
// },
{
title: "统计日期",
dataIndex: "staticDate",
hideInTable: true,
valueType: "dateRange",
initialValue: [moment().startOf('M'), moment()],
search: {
transform: (value: any) => {
return {
startTime: moment(value[0]).format('YYYY-MM-DD'),
endTime: moment(value[1]).format('YYYY-MM-DD')
};
},
},
fieldProps: {
picker: "day",
format: 'YYYY-MM-DD',
}
},
// {
// title: "服务区",
// dataIndex: "serverPartId",
@ -191,7 +191,7 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
align: 'center',
render: (_, record) => {
// let res: any = record.extend ? JSON.parse(record.extend) : "-"
return <span style={{ color: record.errorStatus === 0 ? "red" : record.errorStatus === 1 ? "#1677ff" : "" }}>{
return record?.situation !== 0 ? <span style={{ color: record.errorStatus === 0 ? "red" : record.errorStatus === 1 ? "#1677ff" : "" }}>{
record.errorStatus === 0
? "待处理"
: record.errorStatus === 1
@ -199,7 +199,7 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
: record.errorStatus === 2
? "已处理"
: "-"
}</span>
}</span> : ""
}
},
{
@ -309,8 +309,8 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
const req: any = {
serverPartIds: selectedId && selectedId.length > 0 ? selectedId : [],
startTime: params?.staticDate ? `${params?.staticDate}` : "",
endTime: params?.staticDate ? `${params?.staticDate}` : "",
startTime: params?.startTime ? `${params?.startTime}` : "",
endTime: params?.endTime ? `${params?.endTime}` : "",
// serverPartId: params?.serverPartId ? params?.serverPartId : undefined,
extend: params?.inspectionType ? [{
key: "situation",
@ -319,7 +319,7 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
}
console.log('req', req);
const data = await handleGetRecordTreeList(req)
const data = await handleGetNoTimeRecordTreeList(req)
console.log('data', data);
if (data && data.length > 0) {
@ -374,6 +374,8 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
width={'60%'}
footer={showAbnormal && currentRow?.errorStatus !== 2 ? <div style={{ width: "100%", boxSizing: 'border-box', padding: "0 24px", display: 'flex', justifyContent: 'flex-end' }}>
<Button type="primary" onClick={() => {
console.log('recordDetailRef.current?.formRes.errorStatus', recordDetailRef.current?.formRes.errorStatus);
if (recordDetailRef.current?.formRes.errorStatus === 0) {
recordDetailRef.current?.errorStatusFormRef.current?.validateFields().then(async (res: any) => {
@ -389,21 +391,33 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
})
}
console.log('personObj', personObj);
const req = {
...extendObj,
person: personObj,
// person: personObj,
questionnaireResponsesId: recordDetailRef.current?.formRes.id,
personId: personObj.STAFF_ID,
personMemberShipId: personObj.MEMBERSHIP_ID,
personMemberShipName: personObj.MEMBERSHIP_NAME,
personName: personObj.STAFF_NAME,
errorStatus: 1,
suggestion: res.suggestion,
suggestTime: moment().format('YYYY-MM-DD'), // 选处理人的时间
suggestPerson: {
STAFF_NAME: currentUser.adminName,
STAFF_ID: currentUser.id,
MEMBERSHIP_NAME: currentUser.adminName,
MEMBERSHIP_ID: currentUser.id,
},
suggestTime: moment().format('YYYY-MM-DD HH:mm:ss'), // 选处理人的时间
// suggestPerson: {
// STAFF_NAME: currentUser.adminName,
// STAFF_ID: currentUser.id,
// MEMBERSHIP_NAME: currentUser.adminName,
// MEMBERSHIP_ID: currentUser.id,
// },
suggestMemberShipId: currentUser.id,
suggestMemberShipName: currentUser.adminName,
suggestPersonId: currentUser.id,
suggestPersonName: currentUser.adminName,
};
const data = await handleUpdateExtend(recordDetailRef.current?.formRes.id, { extend: JSON.stringify(req) })
const data = await handleUpdateExtend(req)
if (data.Result_Code === 100) {
message.success('提交成功')
setShowDetail(false)
@ -421,22 +435,31 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
console.log('res', res);
let extendObj = JSON.parse(recordDetailRef.current?.formRes.extend)
console.log('recordDetailRef.current?.fileList', recordDetailRef.current?.fileList);
let fileList: any = []
if (recordDetailRef.current?.fileList && recordDetailRef.current?.fileList.length > 0) {
recordDetailRef.current?.fileList.forEach((item: any) => {
fileList.push(item.url)
// fileList.push(item.url)
fileList.push({
keyName: item.id,
imageUrl: item.url
})
// keyName: item.id,
// imageUrl: subItem
})
}
console.log('fileList', fileList);
const req = {
...extendObj,
questionnaireResponsesId: recordDetailRef.current?.formRes.id,
feedbackImgList: fileList,
feedbackContent: res.feedbackContent,
feedbackTime: moment().format('YYYY-MM-DD HH:mm:ss'), // 反馈时间
errorStatus: 2,
};
const data = await handleUpdateExtend(recordDetailRef.current?.formRes.id, { extend: JSON.stringify(req) })
const data = await handleUpdateExtend(req)
if (data.Result_Code === 100) {
message.success('提交成功')
setShowDetail(false)
@ -450,11 +473,12 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
}
}}></Button>
</div> : false}
</div> : false
}
>
<RecordDetail onRef={recordDetailRef} parentRow={currentRow} show={showDetail} showError={showAbnormal} />
</Drawer>
</div>
</Drawer >
</div >
)
}

View File

@ -1,4 +1,4 @@
// import request from "@/utils/request"
import requestNormal from "@/utils/request"
import request from "@/utils/requestJava"
import requestMap from '@/utils/requestMap'
@ -20,6 +20,23 @@ export async function handleGetRecordTreeList(params?: any) {
return []
}
// 不走区间 拿到树型数据
export async function handleGetNoTimeRecordTreeList(params?: any) {
const data = await request.post('/questionnaire-responses/tree/list', params)
if (data.Result_Code === 100) {
return data.Result_Data.List
}
return []
}
// 汇总的抽屉里面的数据
export async function handleNewSummaryList(params?: any) {
const data = await request.post('/questionnaire-responses/tree/list', params)
if (data.Result_Code === 100) {
return data.Result_Data.List
}
return []
}
// 删除记录
export async function handleDeleteRecord(params?: any) {
@ -34,16 +51,16 @@ export async function handleGetDealerList(params?: any) {
return data
}
// 删除记录
export async function handleUpdateExtend(id: any, params?: any) {
const data = await request.post(`questionnaire-responses/${id}/extend`, params)
// 更新
export async function handleUpdateExtend(params?: any) {
const data = await request.post(`/questionnaire-responses/extend/update`, params)
return data
}
// 上传图片
export async function handleUploadFile(params?: any) {
const data = await request.post(`/oss/upload`, params)
const data = await requestNormal.post(`/oss/upload`, params)
return data
}

View File

@ -5,7 +5,10 @@ import { connect } from "umi";
import moment from "moment";
import { Button, Drawer, Image, message, Popconfirm, Space } from "antd";
import LeftSelectTree from "@/components/leftSelectTree/leftSelectTree";
import { handleGetRecordTreeList, handleGetResponsesSummary } from "../record/service";
import { handleGetRecordTreeList, handleGetResponsesSummary, handleNewSummaryList } from "../record/service";
import login from "@/pages/user/login";
import { LeftOutlined, RightOutlined } from "@ant-design/icons";
import RecordDetail from "../record/components/recordDetail";
const recordSummary: React.FC<{ currentUser: any }> = (props) => {
const { currentUser } = props
@ -39,6 +42,10 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
score: { show: false }
})
const [collapsible, setCollapsible] = useState<boolean>(false)
// 显示详情抽屉
const [showDetailStatus, setShowDetailStatus] = useState<boolean>(false)
// 详情抽屉的点击行数据
const [currentStatusRow, setCurrentStatusRow] = useState<any>()
const columns: any = [
{
@ -68,7 +75,7 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
ellipsis: true,
render: (_, record) => {
return record?.type === 'district' || record?.type === 'servicePart' ? record?.name :
record?.template ? record?.template.title : "-"
record.template.title || '-'
}
},
{
@ -79,7 +86,7 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
width: 150,
ellipsis: true,
render: (_, record) => {
return record?.template?.id && record?.inspectionNumber > 0 ? <span>
return record?.id && record?.inspectionNumber > 0 ? <span>
<a style={{ color: record?.inspectionNumber === record?.allDay ? '' : 'red' }} onClick={() => {
setCurrentRow(record)
setShowType(1)
@ -87,7 +94,10 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
}}>
{record?.inspectionNumber || '-'}
</a> / {record?.allDay}
</span > : <span><span style={{ color: record?.inspectionNumber === record?.allDay ? '' : 'red' }}>{record?.inspectionNumber || '-'} </span><span>/ {record?.allDay}</span></span>
</span > : record?.allDay ? <span>
<span style={{ color: record?.inspectionNumber === record?.allDay ? '' : 'red' }}>{record?.inspectionNumber || '-'} </span>
<span>/ {record?.allDay}</span>
</span> : ""
}
},
{
@ -98,21 +108,18 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
width: 150,
ellipsis: true,
render: (_, record) => {
return record?.allDay ?
<span style={{ color: record?.inspectionNumber === record?.allDay ? '' : 'red' }}>
{((record?.inspectionNumber / record?.allDay) * 100).toFixed(2) + '%'}
</span> : ''
return record?.inspectionRate ? record?.inspectionRate * 100 + '%' : ""
}
},
{
title: <div style={{ textAlign: 'center' }}></div>,
title: <div style={{ textAlign: 'center' }}>()</div>,
dataIndex: "normalNumber",
align: 'center',
hideInSearch: true,
width: 150,
ellipsis: true,
render: (_, record) => {
return record?.template?.id && record?.normalNumber > 0 ? <a onClick={() => {
return record?.template && record?.template.id && record?.normalNumber > 0 ? <a onClick={() => {
setCurrentRow(record)
setShowType(2)
setShowDetail(true)
@ -122,39 +129,40 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
}
},
{
title: <div style={{ textAlign: 'center' }}></div>,
title: <div style={{ textAlign: 'center' }}>()</div>,
dataIndex: "errorNumber",
align: 'center',
hideInSearch: true,
width: 150,
ellipsis: true,
render: (_, record) => {
return record?.template?.id && record?.errorNumber > 0 ? <a onClick={() => {
return record?.template && record?.template.id && record?.errorNumber > 0 ? <a onClick={() => {
setCurrentRow(record)
setShowType(3)
setShowDetail(true)
}}>
{record?.errorNumber || '-'}
</a> : <span>{record?.errorNumber || '-'}</span>
}
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "pendingProcessNumber",
align: 'center',
hideInSearch: true,
width: 150,
ellipsis: true,
render: (_, record) => {
return record?.template?.id && record?.pendingProcessNumber > 0 ? <a onClick={() => {
setCurrentRow(record)
setShowType(4)
setShowDetail(true)
}}>
{record?.pendingProcessNumber || '-'}
</a> : <span>{record?.pendingProcessNumber || '-'}</span>
</a> : ""
// <span>{record?.errorNumber || '-'}</span>
}
},
// {
// title: <div style={{ textAlign: 'center' }}>待处理</div>,
// dataIndex: "pendingProcessNumber",
// align: 'center',
// hideInSearch: true,
// width: 150,
// ellipsis: true,
// render: (_, record) => {
// return record?.template && record?.template.id && record?.pendingProcessNumber > 0 ? <a onClick={() => {
// setCurrentRow(record)
// setShowType(4)
// setShowDetail(true)
// }}>
// {record?.pendingProcessNumber || '-'}
// </a> : <span>{record?.pendingProcessNumber || '-'}</span>
// }
// },
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "processingNumber",
@ -163,43 +171,54 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
width: 150,
ellipsis: true,
render: (_, record) => {
return record?.template?.id && record?.processingNumber > 0 ? <a onClick={() => {
return record?.template ? record?.template.errorStatus01 > 0 ? <a onClick={() => {
setCurrentRow(record)
setShowType(5)
setShowDetail(true)
}}>
{record?.processingNumber || '-'}
</a> : <span>{record?.processingNumber || '-'}</span>
{record?.template.errorStatus01 || '-'}
</a> : <span>{record?.template.errorStatus01 || '-'}</span> : ""
}
},
// {
// title: <div style={{ textAlign: 'center' }}>已处理</div>,
// dataIndex: "processedNumber",
// align: 'center',
// hideInSearch: true,
// width: 150,
// ellipsis: true,
// render: (_, record) => {
// return record?.template && record?.template.id && record?.processedNumber > 0 ? <a onClick={() => {
// setCurrentRow(record)
// setShowType(6)
// setShowDetail(true)
// }}>
// {record?.processedNumber || '-'}
// </a> : <span>{record?.processedNumber || '-'}</span>
// }
// },
// {
// title: <div style={{ textAlign: 'center' }}>处理完成率</div>,
// dataIndex: "processedRate",
// align: 'center',
// hideInSearch: true,
// width: 150,
// ellipsis: true,
// render: (_, record) => {
// return record?.errorNumber ? <span style={{ color: record?.processedNumber === record?.errorNumber ? '' : 'red' }}>
// {record?.processedNumber / record?.errorNumber === 1 ? '100%' : ((record?.processedNumber / record?.errorNumber) * 100).toFixed(2) + '%'}
// </span> : ""
// }
// }
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "processedNumber",
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "unfinishedRate",
align: 'center',
hideInSearch: true,
width: 150,
ellipsis: true,
render: (_, record) => {
return record?.template?.id && record?.processedNumber > 0 ? <a onClick={() => {
setCurrentRow(record)
setShowType(6)
setShowDetail(true)
}}>
{record?.processedNumber || '-'}
</a> : <span>{record?.processedNumber || '-'}</span>
}
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "processedRate",
align: 'center',
hideInSearch: true,
width: 150,
ellipsis: true,
render: (_, record) => {
return record?.errorNumber ? <span style={{ color: record?.processedNumber === record?.errorNumber ? '' : 'red' }}>
{((record?.processedNumber / record?.errorNumber) * 100).toFixed(2)}%
</span> : ""
return record?.template && record?.template.unfinishedRate ? <span>{record?.template.unfinishedRate * 100}%</span> : "-"
}
}
]
@ -228,14 +247,14 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
}
},
{
title: <div style={{ textAlign: 'center' }}></div>,
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "serverPartName",
hideInSearch: true,
width: 200,
ellipsis: true,
render: (_, record) => {
return record?.type === 'district' || record?.type === 'servicePart' ? record?.name :
record?.template ? record?.template.title : "-"
record.template.title || "-"
}
},
{
@ -246,8 +265,30 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
align: 'center',
ellipsis: true,
render: (_, record) => {
let res: any = record.extend ? JSON.parse(record.extend) : "-"
return <span style={{ color: res.situation === 1 ? "red" : "" }}>{res.situation === 1 ? '异常' : res.situation === 0 ? '正常' : ''}</span>
// let res: any = record.extend ? JSON.parse(record.extend) : "-"
return <span style={{ color: record.situation === 1 ? "red" : "" }}>{record.situation === 1 ? '异常' : record.situation === 0 ? '正常' : ''}</span>
}
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "errorStatus",
hideInSearch: true,
width: 100,
ellipsis: true,
align: 'center',
render: (_, record) => {
return record.situation === 1 ? <a style={{ color: record.errorStatus === 0 ? "red" : record.errorStatus === 1 ? "#1677ff" : "" }} onClick={() => {
setCurrentStatusRow(record)
setShowDetailStatus(true)
}}>{
record.errorStatus === 0
? "待处理"
: record.errorStatus === 1
? "处理中"
: record.errorStatus === 2
? "已处理"
: "-"
}</a> : ""
}
},
{
@ -257,8 +298,8 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
width: 200,
ellipsis: true,
render: (_, record) => {
let extendObj = record?.extend ? JSON.parse(record?.extend) : ""
return extendObj?.uploadResult ? extendObj?.uploadResult : "-"
// let extendObj = record?.extend ? JSON.parse(record?.extend) : ""
return record?.uploadResult ? record?.uploadResult : "-"
}
},
{
@ -271,13 +312,15 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
let str: string = ''
if (record?.questionResponses && record?.questionResponses.length > 0) {
record?.questionResponses.forEach((item: any, index: number) => {
let anwers: string = ''
if (item.choiceResponse && item.choiceResponse.length > 0) {
item.choiceResponse.forEach((subItem: string, subIndex: number) => {
anwers += `${subIndex > 0 ? '' : ''}${subItem}`
})
if (item.score === 0) {
let anwers: string = ''
if (item.choiceResponse && item.choiceResponse.length > 0) {
item.choiceResponse.forEach((subItem: string, subIndex: number) => {
anwers += `${str ? '' : ''}${subItem}`
})
}
str += `${index > 0 ? '' : ''}考核内容:${item.question.title},考核结果:${anwers}`
}
str += `${index > 0 ? '' : ''}考核内容:${item.question.title},考核结果:${anwers}`
})
}
return str || ''
@ -300,26 +343,6 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
ellipsis: true,
align: 'center',
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "errorStatus",
hideInSearch: true,
width: 100,
ellipsis: true,
align: 'center',
render: (_, record) => {
let res: any = record.extend ? JSON.parse(record.extend) : "-"
return <span style={{ color: res.errorStatus === 0 ? "red" : res.errorStatus === 1 ? "#1677ff" : "" }}>{
res.errorStatus === 0
? "待处理"
: res.errorStatus === 1
? "处理中"
: res.errorStatus === 2
? "已处理"
: "-"
}</span>
}
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "placeName",
@ -328,11 +351,9 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
ellipsis: true,
align: 'center',
render: (_, record) => {
let extendObj = record?.extend ? JSON.parse(record?.extend) : ""
let imgList = extendObj.imgsList
return imgList && imgList.length > 0 ?
return record.imgsList && record.imgsList.length > 0 ?
<Button type="primary" onClick={() => {
setShowImgList(imgList)
setShowImgList(record.imgsList)
setImagePreviewVisible(true)
}}></Button> : "-"
}
@ -361,7 +382,7 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
defaultExpandAllRows: true
}}
rowKey={(record) => {
return `${record?.id}-${record?.code}-${record?.template.id}`
return `${record?.id}-${record?.code}-${record?.templateId}`
}}
scroll={{ x: "100%", y: 'calc(100vh - 400px)' }}
headerTitle={<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}></span>}
@ -370,6 +391,8 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
if (!(selectedId && selectedId.length > 0)) {
return
}
console.log('params', params);
const req: any = {
serverPartIds: selectedId && selectedId.length > 0 ? selectedId : [],
@ -395,74 +418,74 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
// 处理一下 根据第三层的实际巡查记录 汇总到第二层来
if (data && data.length > 0) {
data.forEach((item: any) => {
if (item.children && item.children.length > 0) {
item.children.forEach((subItem: any) => {
if (subItem.children && subItem.children.length > 0) {
// 点位的id数据 肯定要求不重复的
let templateIdList: number[] = []
// 遍历完之后 要替换的
let newChildren: any = []
// 因为一天时间内 多条记录 需要被计算为一条 那么这里就要加上时间的对象来筛选
let dateObj: any = {}
subItem.children.forEach((thirdItem: any) => {
let extendObj: any = {}
if (thirdItem.extend) {
extendObj = JSON.parse(thirdItem.extend)
}
// data.forEach((item: any) => {
// if (item.children && item.children.length > 0) {
// item.children.forEach((subItem: any) => {
// if (subItem.children && subItem.children.length > 0) {
// // 点位的id数据 肯定要求不重复的
// let templateIdList: number[] = []
// // 遍历完之后 要替换的
// let newChildren: any = []
// // 因为一天时间内 多条记录 需要被计算为一条 那么这里就要加上时间的对象来筛选
// let dateObj: any = {}
// subItem.children.forEach((thirdItem: any) => {
// let extendObj: any = {}
// if (thirdItem.extend) {
// extendObj = JSON.parse(thirdItem.extend)
// }
let oldDateList = dateObj[moment(thirdItem.createdAt).format('YYYY-MM-DD')]
// let oldDateList = dateObj[moment(thirdItem.createdAt).format('YYYY-MM-DD')]
if (!oldDateList || (oldDateList && oldDateList.indexOf(thirdItem.template.id) === -1)) {
// templateIdList 是判断 newChildren 里面已经有几个点位id了
if (templateIdList.indexOf(thirdItem.template.id) === -1) {
templateIdList.push(thirdItem.template.id)
newChildren.push({
template: thirdItem.template,
templateId: thirdItem.template.Id,
inspectionNumber: 1,
normalNumber: extendObj?.situation === 0 ? 1 : 0,
errorNumber: extendObj?.situation === 1 ? 1 : 0,
pendingProcessNumber: extendObj?.errorStatus === 0 ? 1 : 0,
processingNumber: extendObj?.errorStatus === 1 ? 1 : 0,
processedNumber: extendObj?.errorStatus === 2 ? 1 : 0,
})
} else {
newChildren.forEach((fourthItem: any) => {
if (fourthItem.template.id === thirdItem.template.id) {
// if (!oldDateList || (oldDateList && oldDateList.indexOf(thirdItem.id) === -1)) {
// // templateIdList 是判断 newChildren 里面已经有几个点位id了
// if (templateIdList.indexOf(thirdItem.id) === -1) {
// templateIdList.push(thirdItem.id)
// newChildren.push({
// // template: thirdItem.template,
// templateId: thirdItem.Id,
// inspectionNumber: 1,
// normalNumber: extendObj?.situation === 0 ? 1 : 0,
// errorNumber: extendObj?.situation === 1 ? 1 : 0,
// pendingProcessNumber: extendObj?.errorStatus === 0 ? 1 : 0,
// processingNumber: extendObj?.errorStatus === 1 ? 1 : 0,
// processedNumber: extendObj?.errorStatus === 2 ? 1 : 0,
// })
// } else {
// newChildren.forEach((fourthItem: any) => {
// if (fourthItem.id === thirdItem.id) {
fourthItem.inspectionNumber += 1
if (extendObj?.situation === 0) {
fourthItem.normalNumber += 1
} else if (extendObj?.situation === 1) {
fourthItem.errorNumber += 1
}
// fourthItem.inspectionNumber += 1
// if (extendObj?.situation === 0) {
// fourthItem.normalNumber += 1
// } else if (extendObj?.situation === 1) {
// fourthItem.errorNumber += 1
// }
if (extendObj?.errorStatus === 0) {
fourthItem.pendingProcessNumber += 1
} else if (extendObj?.errorStatus === 1) {
fourthItem.processingNumber += 1
} else if (extendObj?.errorStatus === 2) {
fourthItem.processedNumber += 1
}
}
})
}
// if (extendObj?.errorStatus === 0) {
// fourthItem.pendingProcessNumber += 1
// } else if (extendObj?.errorStatus === 1) {
// fourthItem.processingNumber += 1
// } else if (extendObj?.errorStatus === 2) {
// fourthItem.processedNumber += 1
// }
// }
// })
// }
if (oldDateList && oldDateList.length > 0) {
oldDateList.push(thirdItem.template.id)
} else {
dateObj[moment(thirdItem.createdAt).format('YYYY-MM-DD')] = [thirdItem.template.id]
}
}
console.log('dateObj', dateObj);
// if (oldDateList && oldDateList.length > 0) {
// oldDateList.push(thirdItem.id)
// } else {
// dateObj[moment(thirdItem.createdAt).format('YYYY-MM-DD')] = [thirdItem.id]
// }
// }
// console.log('dateObj', dateObj);
})
subItem.children = newChildren
}
})
}
})
// })
// subItem.children = newChildren
// }
// })
// }
// })
data.forEach((item: any) => {
@ -472,6 +495,8 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
let pendingProcessNumberItemSum: number = 0
let processingNumberItemSum: number = 0
let processedNumberItemSum: number = 0
let bigSuccessSum: number = 0
// 这一次时间段应该查询的次数(天数)
let allItemDaySum: number = 0
if (item.children && item.children.length > 0) {
@ -482,26 +507,49 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
let pendingProcessNumberSum: number = 0
let processingNumberSum: number = 0
let processedNumberSum: number = 0
// 巡查完成率合计
let successSum: number = 0
// 这一次时间段应该查询的次数(天数)
let allSubItemDaySum: number = 0
if (subItem.children && subItem.children.length > 0) {
subItem.children.forEach((thirdItem: any) => {
// thirdItem.allDay = allDay
// allSubItemDaySum += thirdItem.allDay
thirdItem.allDay = thirdItem.template.patrolTotal
allSubItemDaySum += thirdItem.template.patrolTotal
// allSubItemDaySum += thirdItem.allDay
// thirdItem.allDay = thirdItem.patrolTotal
// allSubItemDaySum += thirdItem.template.patrolTotal
allSubItemDaySum = thirdItem.template.patrolTotal
// inspectionNumberSum += thirdItem.inspectionNumber
inspectionNumberSum += thirdItem.template.patrolNumber
thirdItem.inspectionNumber = thirdItem.template.patrolNumber
if (thirdItem.template.patrolNumber > inspectionNumberSum) {
inspectionNumberSum = thirdItem.template.patrolNumber
}
// inspectionNumberSum += thirdItem.template.patrolNumber
// thirdItem.inspectionNumber = thirdItem.patrolNumber
normalNumberSum += thirdItem.normalNumber
errorNumberSum += thirdItem.errorNumber
thirdItem.inspectionNumber = thirdItem.template.patrolNumber
thirdItem.inspectionRate = thirdItem.template.patrolRate
successSum += thirdItem.inspectionRate
thirdItem.normalNumber = thirdItem.template.situation0
thirdItem.errorNumber = thirdItem.template.situation1
thirdItem.pendingProcessNumber = thirdItem.template.errorStatus0
thirdItem.processingNumber = thirdItem.template.errorStatus1
thirdItem.processedNumber = thirdItem.template.errorStatus2
normalNumberSum += thirdItem.template.situation0
errorNumberSum += thirdItem.template.situation1
pendingProcessNumberSum += thirdItem.pendingProcessNumber
processingNumberSum += thirdItem.processingNumber
processedNumberSum += thirdItem.processedNumber
})
}
subItem.inspectionRate = (successSum / subItem.children.length).toFixed(4)
subItem.allDay = allSubItemDaySum
subItem.inspectionNumber = inspectionNumberSum
subItem.normalNumber = normalNumberSum
@ -510,6 +558,7 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
subItem.processingNumber = processingNumberSum
subItem.processedNumber = processedNumberSum
bigSuccessSum += Number(subItem.inspectionRate)
inspectionNumberItemSum += subItem.inspectionNumber
normalNumberItemSum += subItem.normalNumber
errorNumberItemSum += subItem.errorNumber
@ -518,13 +567,14 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
processedNumberItemSum += subItem.processedNumber
allItemDaySum += subItem.allDay
})
item.allDay = allItemDaySum
item.inspectionNumber = inspectionNumberItemSum
// item.allDay = allItemDaySum
// item.inspectionNumber = inspectionNumberItemSum
item.normalNumber = normalNumberItemSum
item.errorNumber = errorNumberItemSum
item.pendingProcessNumber = pendingProcessNumberItemSum
item.processingNumber = processingNumberItemSum
item.processedNumber = processedNumberItemSum
item.inspectionRate = (bigSuccessSum / item.children.length).toFixed(4)
}
})
}
@ -552,13 +602,13 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
showImgList && showImgList.length > 0 && <div style={{ display: 'none' }}>
<Image.PreviewGroup
preview={{
visible: imagePreviewVisible,
onVisibleChange: vis => {
console.log('vis', vis);
setImagePreviewVisible(vis)
},
current: previewIndex
}
}}>
{
showImgList.map((n) =>
@ -604,49 +654,73 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
console.log('searchParams', searchParams);
console.log('currentRow', currentRow);
if (!currentRow?.template?.serverPartId) {
if (!currentRow?.serverPartId) {
return
}
// showType 1 巡查次数 2 正常 3 异常 4 待处理 5 处理中 6 已处理
const req: any = {
serverPartIds: [currentRow?.template?.serverPartId],
startTime: searchParams?.startTime ? `${searchParams?.startTime}T00:00:00` : "",
endTime: searchParams?.endTime ? `${searchParams?.endTime}T23:59:59` : "",
extend: showType === 1 ? undefined : showType === 2 ? [
serverPartIds: [currentRow?.serverPartId],
startTime: searchParams?.startTime ? `${searchParams?.startTime}` : "",
endTime: searchParams?.endTime ? `${searchParams?.endTime}` : "",
extend: showType === 1 ? [
{
key: "templateId",
value: currentRow?.template.id,
}
] : showType === 2 ? [
{
key: "situation",
value: 0,
},
{
key: "templateId",
value: currentRow?.template.id,
}
] : showType === 3 ? [
{
key: "situation",
value: 1,
},
{
key: "templateId",
value: currentRow?.template.id,
}
] : showType === 4 ? [
{
key: "errorStatus",
value: 0,
},
{
key: "templateId",
value: currentRow?.template.id,
}
] :
showType === 5 ? [
{
key: "errorStatus",
key: "errorStatus01",
value: 1,
},
{
key: "templateId",
value: currentRow?.template.id,
}
] :
showType === 6 ? [
{
key: "errorStatus",
value: 2,
},
{
key: "templateId",
value: currentRow?.template.id,
}
] : undefined
}
console.log('req', req);
const data = await handleGetRecordTreeList(req)
const data = await handleNewSummaryList(req)
console.log('data', data);
if (data && data.length > 0) {
@ -671,6 +745,21 @@ const recordSummary: React.FC<{ currentUser: any }> = (props) => {
>
</ProTable>
</Drawer>
<Drawer
title={false}
closeIcon={false}
onClose={() => {
setCurrentStatusRow(undefined)
setShowDetailStatus(false)
}}
open={showDetailStatus}
destroyOnClose
width={'80%'}
>
<RecordDetail onRef={recordDetailRef} parentRow={currentStatusRow} show={showDetailStatus} />
</Drawer>
</div>
)
}

View File

@ -10,19 +10,36 @@ import type { UserConnectedProps } from '@/models/user';
import styles from './index.less';
import logo from '@/assets/logo.svg';
import loginBg from '@/assets/login-bg.png';
import { md5 } from '@/utils/format';
import CryptoJs from 'crypto-js';
const Index: FC<UserConnectedProps> = (props) => {
const [type, setType] = useState<string>('account');
const { user, dispatch } = props;
const handleSubmit = async (values: API.LoginParams) => {
// values.password = md5(values.password!)
values.UserPassport = values.username
values.UserPassWord = values.password
values.UserPassWord = CryptoJs.MD5(values.UserPassWord + values.UserPassport).toString();
let newObj: any = {
UserPassport: values.username,
UserPassWord: values.UserPassWord
}
try {
const response = await dispatch?.({
type: 'user/login',
payload: values,
// payload: values,
payload: newObj
});
if (response?.code === 200) {
console.log('response', response);
if (response?.Result_Code === 100) {
message.success('登录成功');
return true;
} else {

View File

@ -1,3 +1,4 @@
import { wrapTreeNode } from '@/utils/format';
import request from '@/utils/request';
//登录
@ -7,15 +8,33 @@ import request from '@/utils/request';
// 登录
export async function userLogin(params: any) {
const data = await request.post('/auth/admin/login', params)
// const data = await request.post('/auth/admin/login', params)
// java的 暂时注释 用老的云平台的
// const data = await request.post('/auth/login', params)
// return data
// 云平台
const data = await request('/Logging/UserLogin', {
method: "POST",
data: params,
requestType: 'form',
})
return data
}
//获取用户信息
export async function retrieveUserInfo(params: any) {
const data = await request.get('/auth/admin/profile', params)
return data
// const data = await request.get('/auth/admin/profile', params)
// 新java的
// const data = await request.get('/info/getInfo')
// return data.Result_Data
// 云平台的
const data = await request.get('/Logging/GetPassportInfoByToken')
return data.Result_Data
}
// export const retrieveUserInfo = (): Promise<API.UserInfoResponse> => (
// request.get('/api/user/info')
@ -23,8 +42,131 @@ export async function retrieveUserInfo(params: any) {
//获取用户权限
export async function retrieveUserAuthority(params: any) {
const data = await request.get('/api/user/authority', params)
return data
// const data = await request.get('/api/user/authority', params)
// const data = await request.get('/info/getRolePermission')
// if (data.Result_Code === 100) {
// let list: any = wrapTreeNode(data.Result_Data.List)
// console.log('listlistlistlistlistlist3231', list);
// return list
// }
// return []
return [
{
"systemmenuId": "67",
"systemmenuPid": -1,
"systemmenuName": "走动式管理",
"systemmenuIndex": 3,
"systemmenuLevel": null,
"systemmenuIco": "<ProfileOutlined />",
"systemmenuStatus": 1,
"staffId": 1,
"staffName": "系统开发者",
"operateDate": "2025-04-29 18:43:02",
"systemmenuDesc": null,
"systemModuleList": [
{
"systemmoduleId": "400",
"systemmenuId": 67,
"systemmoduleType": null,
"systemmoduleName": "考评分类管理",
"systemmoduleIndex": 1,
"systemmoduleGuid": "WC3i3mN8P8IBLVJPHsEiN",
"systemmoduleUrl": "/examine/index",
"systemmoduleIco": null,
"systemmoduleStatus": 1,
"staffId": 1,
"staffName": "系统开发者",
"operateDate": "2025-04-29 18:43:40",
"systemmoduleDesc": null,
"systemmoduleAiDesc": null
},
{
"systemmoduleId": "401",
"systemmenuId": 67,
"systemmoduleType": null,
"systemmoduleName": "考核问题管理",
"systemmoduleIndex": 2,
"systemmoduleGuid": "d4ZGsS1VhmIINoI3S9sOS",
"systemmoduleUrl": "/examine/question",
"systemmoduleIco": null,
"systemmoduleStatus": 1,
"staffId": 1,
"staffName": "系统开发者",
"operateDate": "2025-04-29 18:43:53",
"systemmoduleDesc": null,
"systemmoduleAiDesc": null
},
{
"systemmoduleId": "402",
"systemmenuId": 67,
"systemmoduleType": null,
"systemmoduleName": "考核点位管理",
"systemmoduleIndex": 3,
"systemmoduleGuid": "7CWs9B9SuW1sfu453uQ8f",
"systemmoduleUrl": "/examine/modal",
"systemmoduleIco": null,
"systemmoduleStatus": 1,
"staffId": 1,
"staffName": "系统开发者",
"operateDate": "2025-04-29 18:44:02",
"systemmoduleDesc": null,
"systemmoduleAiDesc": null
},
{
"systemmoduleId": "403",
"systemmenuId": 67,
"systemmoduleType": null,
"systemmoduleName": "考核记录管理",
"systemmoduleIndex": 4,
"systemmoduleGuid": "ZzwgDzWpMW31RJE87T72W",
"systemmoduleUrl": "/examine/record",
"systemmoduleIco": null,
"systemmoduleStatus": 1,
"staffId": 1,
"staffName": "系统开发者",
"operateDate": "2025-04-29 18:44:13",
"systemmoduleDesc": null,
"systemmoduleAiDesc": null
},
{
"systemmoduleId": "404",
"systemmenuId": 67,
"systemmoduleType": null,
"systemmoduleName": "异常记录管理",
"systemmoduleIndex": 5,
"systemmoduleGuid": "AlN9inzu7T52fihnnkJXW",
"systemmoduleUrl": "/examine/errorRecord",
"systemmoduleIco": null,
"systemmoduleStatus": 1,
"staffId": 1,
"staffName": "系统开发者",
"operateDate": "2025-04-29 18:44:29",
"systemmoduleDesc": null,
"systemmoduleAiDesc": null
},
{
"systemmoduleId": "405",
"systemmenuId": 67,
"systemmoduleType": null,
"systemmoduleName": "考核记录汇总",
"systemmoduleIndex": 6,
"systemmoduleGuid": "6A4CmfBQViWvSE4iup3TG",
"systemmoduleUrl": "/examine/recordSummary",
"systemmoduleIco": null,
"systemmoduleStatus": 1,
"staffId": 1,
"staffName": "系统开发者",
"operateDate": "2025-04-29 18:44:48",
"systemmoduleDesc": null,
"systemmoduleAiDesc": null
}
]
}
]
}
// export const retrieveUserAuthority = (): Promise<API.UserAuthorityResponse> => (
// request.get('/api/user/authority')
@ -32,43 +174,127 @@ export async function retrieveUserAuthority(params: any) {
//获取菜单数据
export async function retrieveMenuData(params: any) {
// const data = await request.get('/menu/getList', { params })
// let res = wrapTreeNode(data.Result_Data.List)
// console.log('resresresresresresres', res);
// return res
// const data = await request.get('/menus', params)
// return data
return [
{
path: '/standard/index',
redirect: '',
name: '生成标准页面',
component: "@/pages/standard/index",
},
{
path: '/examine',
redirect: '',
name: '走动式管理',
children: [
"systemmenuId": "67",
"systemmenuPid": -1,
"systemmenuName": "走动式管理",
"systemmenuIndex": 3,
"systemmenuLevel": null,
"systemmenuIco": "<ProfileOutlined />",
"systemmenuStatus": 1,
"staffId": 1,
"staffName": "系统开发者",
"operateDate": "2025-04-29 18:43:02",
"systemmenuDesc": null,
"systemModuleList": [
{
path: '/examine/index',
name: '考评分类管理',
component: "@/pages/examine/index",
"systemmoduleId": "400",
"systemmenuId": 67,
"systemmoduleType": null,
"systemmoduleName": "考评分类管理",
"systemmoduleIndex": 1,
"systemmoduleGuid": "WC3i3mN8P8IBLVJPHsEiN",
"systemmoduleUrl": "/examine/index",
"systemmoduleIco": null,
"systemmoduleStatus": 1,
"staffId": 1,
"staffName": "系统开发者",
"operateDate": "2025-04-29 18:43:40",
"systemmoduleDesc": null,
"systemmoduleAiDesc": null
},
{
path: '/examine/question',
name: '考核问题管理',
component: "@/pages/examine/question",
"systemmoduleId": "401",
"systemmenuId": 67,
"systemmoduleType": null,
"systemmoduleName": "考核问题管理",
"systemmoduleIndex": 2,
"systemmoduleGuid": "d4ZGsS1VhmIINoI3S9sOS",
"systemmoduleUrl": "/examine/question",
"systemmoduleIco": null,
"systemmoduleStatus": 1,
"staffId": 1,
"staffName": "系统开发者",
"operateDate": "2025-04-29 18:43:53",
"systemmoduleDesc": null,
"systemmoduleAiDesc": null
},
{
path: '/examine/modal',
name: '考核模版管理',
component: "@/pages/examine/modal",
"systemmoduleId": "402",
"systemmenuId": 67,
"systemmoduleType": null,
"systemmoduleName": "考核点位管理",
"systemmoduleIndex": 3,
"systemmoduleGuid": "7CWs9B9SuW1sfu453uQ8f",
"systemmoduleUrl": "/examine/modal",
"systemmoduleIco": null,
"systemmoduleStatus": 1,
"staffId": 1,
"staffName": "系统开发者",
"operateDate": "2025-04-29 18:44:02",
"systemmoduleDesc": null,
"systemmoduleAiDesc": null
},
{
path: '/examine/record',
name: '考核记录管理',
component: "@/pages/examine/record",
"systemmoduleId": "403",
"systemmenuId": 67,
"systemmoduleType": null,
"systemmoduleName": "考核记录管理",
"systemmoduleIndex": 4,
"systemmoduleGuid": "ZzwgDzWpMW31RJE87T72W",
"systemmoduleUrl": "/examine/record",
"systemmoduleIco": null,
"systemmoduleStatus": 1,
"staffId": 1,
"staffName": "系统开发者",
"operateDate": "2025-04-29 18:44:13",
"systemmoduleDesc": null,
"systemmoduleAiDesc": null
},
{
"systemmoduleId": "404",
"systemmenuId": 67,
"systemmoduleType": null,
"systemmoduleName": "异常记录管理",
"systemmoduleIndex": 5,
"systemmoduleGuid": "AlN9inzu7T52fihnnkJXW",
"systemmoduleUrl": "/examine/errorRecord",
"systemmoduleIco": null,
"systemmoduleStatus": 1,
"staffId": 1,
"staffName": "系统开发者",
"operateDate": "2025-04-29 18:44:29",
"systemmoduleDesc": null,
"systemmoduleAiDesc": null
},
{
"systemmoduleId": "405",
"systemmenuId": 67,
"systemmoduleType": null,
"systemmoduleName": "考核记录汇总",
"systemmoduleIndex": 6,
"systemmoduleGuid": "6A4CmfBQViWvSE4iup3TG",
"systemmoduleUrl": "/examine/recordSummary",
"systemmoduleIco": null,
"systemmoduleStatus": 1,
"staffId": 1,
"staffName": "系统开发者",
"operateDate": "2025-04-29 18:44:48",
"systemmoduleDesc": null,
"systemmoduleAiDesc": null
}
]
},
}
]
}
// export const retrieveMenuData = (): Promise<API.MenuDataResponse> => (
@ -81,7 +307,7 @@ export async function retrieveMenuData(params: any) {
export const retrieveUserInfoAuthorityMenu = (): Promise<API.UserInfoAuthMenuResponse> => (
Promise.all([
retrieveUserInfo(),
// retrieveUserAuthority(),
retrieveUserAuthority(),
retrieveMenuData(),
])
);
@ -89,17 +315,25 @@ export const retrieveUserInfoAuthorityMenu = (): Promise<API.UserInfoAuthMenuRes
//获取用户权限以及菜单
export const retrieveUserAuthorityMenu = (): Promise<API.UserAuthMenuResponse> => (
Promise.all([
// retrieveUserAuthority(),
retrieveUserAuthority(),
retrieveMenuData(),
])
);
//登出
export const userLogout = (): Promise<API.LogoutResponse> => (
request.post('/auth/logout')
);
export const userLogout = (): any => {
// request.post('/auth/logout')
localStorage.removeItem('Authorization')
return {
code: 200
}
}
// export const userLogout = (): Promise<API.LogoutResponse> => (
// request.post('/auth/logout')
// );
//获取验证码
export const retrieveCaptcha = (params: Record<string, string>): Promise<API.CaptchaResponse> => (
request.get('/api/user/captcha', { params })
);
// export const retrieveCaptcha = (params: Record<string, string>): Promise<API.CaptchaResponse> => (
// request.get('/api/user/captcha', { params })
// );

16
src/utils/Authorized.ts Normal file
View File

@ -0,0 +1,16 @@
import RenderAuthorize from '@/components/Authorized';
import { getAuthority } from './authority';
/* eslint-disable eslint-comments/disable-enable-pair */
/* eslint-disable import/no-mutable-exports */
let Authorized = RenderAuthorize(getAuthority());
// Reload the rights component
const reloadAuthorized = (): void => {
Authorized = RenderAuthorize(getAuthority());
};
/** Hard code block need it。 */
window.reloadAuthorized = reloadAuthorized;
export { reloadAuthorized };
export default Authorized;

View File

@ -0,0 +1,17 @@
export function extractDeepestRoutes(routes: any, result = {}) {
routes.forEach((route: any) => {
if (route.systemModuleList && route.systemModuleList.length > 0) {
// 递归处理子路由
extractDeepestRoutes(route.systemModuleList, result);
} else {
// 没有子路由时,添加到结果
result[route.systemmoduleUrl] = {
path: '/cloudNew' + route.systemmoduleUrl,
name: route.systemmoduleName
// ,
// component: route.component
};
}
});
return result;
}

532
src/utils/format.ts Normal file
View File

@ -0,0 +1,532 @@
import ProTable from '@ant-design/pro-table'
import numeral from 'numeral'
import './printBox.less'
import CryptoJS from 'crypto-js';
export type TreeSelectModel = {
value: number | string,
id: number | string,
title: string,
pId: number | string,
disabled?: boolean
}
export type TreeNodeDto = {
node: any;
children: TreeNodeDto[];
}
/**
* @description: [{node:{},chidlren:[]}] => [{...node,children}]
* @param {any} node
* @param {any} chidlren
* @return {*} [node:{...,children:[]}]
*/
export function wrapTreeNode(data: TreeNodeDto[]) {
const wrapData: any = data.map((item: TreeNodeDto) => {
const node = { ...item.node };
if (item.children && item.children.length > 0) {
node.children = wrapTreeNode(item.children);
}
return node
});
return wrapData;
}
export function formatTreeForProTable(data: TreeNodeDto[]) {
const wrapData = wrapTreeNode(data);
return {
data: wrapData,
current: 1,
pageSize: 100,
total: 100,
success: true,
};
}
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,
};
}
/**
* @description: treeSelect组件treeDataSimpleMode模式使用的
* @param fields
* @param treeKeys fields TreeSelectModel fields as EnumItem ,treeKeys: { title: 'fieldEnumName', value: 'id', id:'id', pId:'parentId' }
* @returns TreeSelectModel[]
*/
export const getTreeSelectOption = async (treeKeys: TreeSelectModel, fields: any[]) => {
const option: TreeSelectModel[] = []
const { value, title, pId, id } = treeKeys
fields.forEach(async (item: any) => {
option.push({ value: item[value], title: item[title], pId: item[pId], id: item[id] })
if (item.children) {
const children: TreeSelectModel[] = await getTreeSelectOption(treeKeys, item.children)
option.push(...children)
}
})
return option
}
// 转换数据为option格式数据
export function formateOptions(list: [], rules: { name: string; value: string; other?: string }) {
// let options: { label: string; value: number | string; other?: string | number }[] = [];
const { name, value, other } = rules;
if (list && other) {
return list.map((n) => {
return {
label: n[name],
value: n[value],
other: n[other],
};
});
} if (list) {
return list.map((n) => {
return {
label: n[name],
value: n[value],
};
});
}
return [];
}
// 转换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;
}
// 转换树节点的value类型为string
export function formateTreeField(list: TreeNodeDto[]) {
const valueNumber: any[] = list.map((item: TreeNodeDto) => {
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;
}
// 把图片格式转化为 ui框架需要的数据格式
export const transferImg = (orgIamges: any[]) => {
const newImages = orgIamges.map((n: any) => {
if (typeof n === 'object') {
return {
uid: n.ImageId, // 注意这个uid一定不能少否则上传失败
name: n.ImageName,
status: 'done',
url: n.ImageUrl, // url 是展示在页面上的绝对链接
imgUrl: n.ImagePath,
}
}
const [name] = [...n.split("/")].reverse()
return {
uid: new Date().getTime(), // 注意这个uid一定不能少否则上传失败
name,
status: 'done',
url: n, // url 是展示在页面上的绝对链接
imgUrl: n,
}
})
return newImages
}
// 合计方法
export const handleGetSumRow = (data: any[], fieldList: string[], sumTitle: string, avgFiled?: string) => {
// data 表格数据 fieldList 要算合计的字段 sumTitle 显示合计两个字的字段 avgFiled 要算均值的字段(这个字段也必须在算合计的字段里面)
if (data && data.length > 0) {
if (data.length >= 2) {
const res: any = {}
if (fieldList && fieldList.length > 0) {
fieldList.forEach((item: any) => {
res[item] = 0
})
}
data.forEach((item: any) => {
if (res) {
for (const key in res) {
if (item[key]) {
res[key] += item[key]
}
}
}
})
if (avgFiled) {
res[avgFiled] = Number((res[avgFiled] / data.length).toFixed(2))
}
console.log('res', res);
res[sumTitle] = "合计"
data.unshift(res)
return data
}
// 一个片区的时候 判断是不是一个服务区 一个服务区的话 就单单显示一个服务区就好
if (data && data.length === 1) {
const obj: any = data[0]
if (obj.children && obj.children.length === 1) {
return obj.children
}
return data
}
return data
}
return []
}
// 自定义打印的内容的打印方法
export const handleNewPrint = (printName: string, title: string, neckBox?: any, styles?: any, tableDom?: any, footer?: any) => {
// printName 打印出来文件的名称
// title 打印内容的标题
// neckBox 标题下面可能会要求的打印的内容 数组 {label,value}格式 样式已写死
// styles 获取页面的样式
// tableDom 要打印显示的表格 直接dom元素拿进来(处理好的)
// footer 打印内容底部的自定义样式 需求不一样 样式也不一样 外面写好样式和标签直接传入
const printWindow = window.open('', '_blank', 'width=1400,height=800');
if (printWindow) {
printWindow.document.open();
printWindow.document.write(`
<html>
<head>
<title>${printName || ''}</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
position: relative;
overflow: hidden;
}
${styles}
.handlePrintBox{
width: 100%;
height: 100%;
position: relative;
z-index: 0;
box-sizing: border-box;
padding: 20px 0 0 0;
}
.handlePrintBox .custom-header {
font-size: 24px;
text-align: center;
margin-bottom: 20px;
font-weight: 600;
}
.handlePrintBox .neckBox{
width: 100%;
box-sizing: border-box;
padding: 12px 12px 12px 20px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.handlePrintBox .neckBox .neckBoxItem{
width: calc(100% / 3);
display: flex;
align-items: center;
box-sizing: border-box;
padding-left: 5%;
}
.handlePrintBox .neckBox .bigNeckBoxItem{
width: calc((100% / 3) * 2);
display: flex;
align-items: center;
box-sizing: border-box;
padding-left: 5%;
}
.handlePrintBox .neckBox .bigNeckBoxItem .itemLabel{
font-size: 14px;
font-weight: 600;
margin-right: 2px;
}
.handlePrintBox .neckBox .bigNeckBoxItem .itemValue{
font-size: 12px;
}
.handlePrintBox .neckBox .neckBoxItem .itemLabel{
font-size: 14px;
font-weight: 600;
margin-right: 2px;
}
.handlePrintBox .neckBox .neckBoxItem .itemValue{
font-size: 12px;
}
.handlePrintBox .tableBox{
width: 100%;
box-sizing: border-box;
padding: 12px;
display: flex;
justify-content: center;
border-collapse: separate;
border-spacing: 0;
}
.handlePrintBox .tableBox .ant-table-thead tr th{
border: 2px solid #000;
}
.handlePrintBox .tableBox .ant-table-tbody tr td{
border: 2px solid #000;
}
.handlePrintBox .tableBox .ant-table-summary tr td{
border: 2px solid #000;
}
.handlePrintBox .tableUnit{
width: 100%;
display: flex;
justify-content: flex-end;
box-sizing: border-box;
font-size: 14px;
}
.handlePrintBox .tableUnit .tableRight{
width: calc(100% / 3);
font-size: 14px;
box-sizing: border-box;
padding-left: 5%;
}
.pro-table {
width: 100%;
border-collapse: collapse;
}
.pro-table th, .pro-table td {
border: 1px solid #ddd;
padding: 8px;
}
.pro-table th {
background-color: #f2f2f2;
text-align: left;
}
/* 水印样式 */
.watermark {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: grid;
grid-template-rows: repeat(4, 1fr); /* 水平行数 */
grid-template-columns: repeat(4, 1fr); /* 垂直列数 */
opacity: 0.2;
pointer-events: none;
z-index: 1;
overflow: hidden;
}
.watermark span {
display: flex;
justify-content: center;
align-items: center;
transform: rotate(-45deg); /* 水印旋转 */
font-size: 14px;
color: rgba(0, 0, 0); /* 半透明水印 */
user-select: none;
}
</style>
</head>
<body>
<div class="handlePrintBox">
<div class="custom-header">${title}</div>
<div class="neckBox">
${neckBox && neckBox.length > 0
? neckBox
.map((item: any) => {
return `<div class="${item.label === '门店名称' ? 'bigNeckBoxItem' : 'neckBoxItem'}">
<span class="itemLabel">${item.label ? item.label + '' : ''}</span>
<span class="itemValue">${item.value}</span>
</div>`;
})
.join('') // 连接成单一字符串,避免逗号
: ''}
</div>
<div class="tableUnit">
<div class="tableRight"></div>
</div>
<div class="tableBox">
${tableDom}
</div>
<div>
${footer}
</div>
</div>
<div class="watermark">
${Array(16) // 5x5 网格的水印内容
.fill('<span>安徽省驿达高速公路服务区经营管理有限公司</span>')
.join('')}
</div>
</body>
</html>
`)
printWindow.document.close();
printWindow.print();
// 使用定时器检测打印窗口是否关闭
const closeCheckInterval = setInterval(() => {
if (printWindow.closed) {
clearInterval(closeCheckInterval);
}
}, 500);
// 监听窗口焦点事件,若打印窗口失去焦点,关闭窗口
printWindow.onfocus = () => {
printWindow.close();
clearInterval(closeCheckInterval);
};
printWindow.onafterprint = () => printWindow.close();
}
}
// 打印图片
export const handlePrintImg = (url: any) => {
const printWindow = window.open('', '_blank', 'width=1400,height=800');
if (printWindow) {
printWindow.document.open();
printWindow.document.close();
printWindow.document.write(`
<html>
<head>
<style>
</style>
<body>
<div style="width:100%;height:100%;display:flex;justify-content: center;">
<img style="max-width:100%;max-height:100%" src=${url}>
</div>
</body>
</head>
</html>
`)
printWindow.print();
// 使用定时器检测打印窗口是否关闭
const closeCheckInterval = setInterval(() => {
if (printWindow.closed) {
clearInterval(closeCheckInterval);
}
}, 500);
printWindow.onfocus = () => {
printWindow.close();
clearInterval(closeCheckInterval);
};
printWindow.onafterprint = () => printWindow.close();
}
}
// 传入秒 返回时分
export const secondsToHuman = (seconds: number) => {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const parts = [];
if (hours > 0) parts.push(`${hours}小时`);
if (minutes > 0) parts.push(`${minutes}分钟`);
return parts.join('') || '0分钟';
}
// MD5加密
export const md5 = (value: string) => {
return CryptoJS.MD5(value).toString();
}
// 一组数据 无限层级 把自己的字段变为 children
export const handleChangeCildrenName = (menus: any) => {
if (Array.isArray(menus)) {
return menus.map((item) => transformNode(item));
}
// 如果是单个对象,直接处理
return transformNode(menus);
}
const transformNode = (node: any) => {
const newNode: any = {};
newNode.name = node.systemmenuName || node.systemmoduleName;
newNode.path = node.systemmoduleUrl || '/';
newNode.icon = node.systemmenuIco || ''
// 如果有 systemModuleList递归处理并改为 children
if (node.systemModuleList && node.systemModuleList.length > 0) {
newNode.children = handleChangeCildrenName(node.systemModuleList);
}
return newNode;
}
// 返回全部的权限内容
export const extractInnermostNodesAsMap = (data: any) => {
const result: Record<string, string[]> = {};
const nodes = Array.isArray(data) ? data : [data];
console.log('nodes', nodes);
for (const node of nodes) {
if (!node.systemModuleList || node.systemModuleList.length === 0) {
const path = node.systemmoduleUrl || '/';
if (!result[path]) {
result[path] = []; // 初始化数组
}
result[path].push(path); // 允许重复路径
} else {
const childResults = extractInnermostNodesAsMap(node.systemModuleList);
for (const [key, values] of Object.entries(childResults)) {
if (!result[key]) {
result[key] = [];
}
result[key].push(...values);
}
}
}
return result;
}
// 吧全部有权限的路径 放在一个数组里面
export const handleAllUserPermission = (data: any) => {
let result: string[] = [];
const nodes = Array.isArray(data) ? data : [data];
for (const node of nodes) {
if (!node.systemModuleList || node.systemModuleList.length === 0) {
const path = node.systemmoduleUrl || '/';
if (!(result && result.length > 0)) {
result = []; // 初始化数组
}
result.push(path); // 允许重复路径
} else {
const childResults = extractInnermostNodesAsMap(node.systemModuleList);
for (const [key, values] of Object.entries(childResults)) {
if (!(result && result.length > 0)) {
result = []; // 初始化数组
}
result.push(...values);
}
}
}
return result;
}

3
src/utils/printBox.less Normal file
View File

@ -0,0 +1,3 @@
.andkad{
justify-content: space-between;
}

View File

@ -3,18 +3,25 @@ import { getDvaApp } from 'umi';
import { notification } from 'antd';
import type { AxiosRequestHeaders } from 'axios/index';
import CryptoJS from "crypto-js";
import qs from 'qs';
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: 'https://api.eshangtech.com/EShangApiMain' });
// const instance = axios.create({ baseURL: 'http://home.robot-z.cn:7001/' });
// 修改baseURL为完整的API地址确保在生产环境中正确访问
// const instance = axios.create({ baseURL: 'https://es.robot-z.cn' });
const instance = axios.create({ baseURL: 'https://es.eshangtech.com' });
// const instance = axios.create({ baseURL: 'https://es.eshangtech.com' });
// const instance = axios.create({ baseURL: 'https://admin.es.eshangtech.com/platform' });
// const instance = axios.create({ baseURL: 'http://10.104.1.175:8070/platform' });
@ -24,15 +31,36 @@ instance.interceptors.request.use(
// if (config.data) {
// config.data = preprocessData(JSON.stringify(config.data)); // 调用预处理函数
// }
console.log('config', config);
const isUpload = config.url?.includes("/oss/upload");
const isFormData = config.data instanceof FormData;
config.headers = {
...config.headers,
Authorization: `Bearer ${localStorage.getItem('Authorization') || ''}`,
"Content-Type": isUpload ? "multipart/form-data" : "application/json;charset=utf-8",
} as AxiosRequestHeaders;
let token = localStorage.getItem('Authorization')
if (!isUpload && !isFormData && config.data && typeof config.data === 'object') {
config.data = qs.stringify(config.data);
config.headers = {
...config.headers,
Authorization: token ? `Bearer ${localStorage.getItem('Authorization') || ''}` : "",
token: token ? `${localStorage.getItem('Authorization') || ''}` : "",
'Content-Type': 'application/x-www-form-urlencoded'
};
} else {
config.headers = {
...config.headers,
Authorization: token ? `Bearer ${localStorage.getItem('Authorization') || ''}` : "",
token: token ? `${localStorage.getItem('Authorization') || ''}` : "",
"Content-Type": isUpload
? "multipart/form-data"
: "application/json;charset=utf-8",
};
}
// config.headers = {
// ...config.headers,
// Authorization: token ? `Bearer ${localStorage.getItem('Authorization') || ''}` : "",
// "Content-Type": isUpload ? "multipart/form-data" : "application/json;charset=utf-8",
// } as AxiosRequestHeaders;
return config;
},
@ -44,7 +72,7 @@ instance.interceptors.response.use(
(response) => {
const { data } = response;
if (data.Result_Code !== 200) {
if (data.Result_Code !== 100) {
// notification.error({
// message: data.message,
// });

View File

@ -14,10 +14,10 @@ const { UMI_APP_BASEURL } = process.env;
// 修改baseURL为完整的API地址确保在生产环境中正确访问
// const instance = axios.create({ baseURL: 'https://es.robot-z.cn' });
// const instance = axios.create({ baseURL: 'http://10.104.1.161:8070/platform' });
const instance = axios.create({ baseURL: 'https://admin.es.eshangtech.com/platform' });
const instance = axios.create({ baseURL: 'http://10.104.1.175:8070/platform' });
// const instance = axios.create({ baseURL: 'http://10.104.1.175:8070/platform' });
instance.interceptors.request.use(
(config) => {

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"
@ -9082,6 +9087,13 @@ qs@^6.11.0, qs@^6.12.3:
dependencies:
side-channel "^1.1.0"
qs@^6.14.0:
version "6.14.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.0.tgz#c63fa40680d2c5c941412a0e899c89af60c0a930"
integrity sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==
dependencies:
side-channel "^1.1.0"
query-string@^6.13.6:
version "6.14.1"
resolved "https://registry.npmmirror.com/query-string/-/query-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a"
@ -10480,7 +10492,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 +10599,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 +11459,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 +11477,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"