Compare commits
10 Commits
1d35b458fa
...
e94956b778
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e94956b778 | ||
| b021eff28f | |||
| f3966ac2c9 | |||
| bf17f9f44b | |||
| c6da1f9557 | |||
| f4d966168e | |||
| a96e829ac4 | |||
| 70d4f4cb3d | |||
| 2a2a116a7e | |||
| 637f0cd1c8 |
@ -44,10 +44,26 @@ export default [
|
|||||||
path: '/examine/record',
|
path: '/examine/record',
|
||||||
name: '考核记录管理',
|
name: '考核记录管理',
|
||||||
component: "@/pages/examine/record/index",
|
component: "@/pages/examine/record/index",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/examine/recordSummary',
|
||||||
|
name: '考核记录汇总',
|
||||||
|
component: "@/pages/examine/recordSummary/index",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/setting",
|
||||||
|
redirect: '',
|
||||||
|
name: '系统设置',
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
path: '/setting/menu',
|
||||||
|
name: '菜单管理',
|
||||||
|
component: "@/pages/setting/menu/index",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
height: 30.9px;
|
height: 30.9px;
|
||||||
}
|
}
|
||||||
.username{
|
.username{
|
||||||
color: #fff;
|
color: #000;
|
||||||
}
|
}
|
||||||
&:hover {
|
&:hover {
|
||||||
// background: #252a3d;
|
// background: #252a3d;
|
||||||
|
|||||||
@ -1,14 +1,18 @@
|
|||||||
|
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import { connect } from 'umi';
|
import { connect } from 'umi';
|
||||||
import { Dropdown, Space } from 'antd';
|
import { Dropdown, Space } from 'antd';
|
||||||
import { LogoutOutlined } from '@ant-design/icons';
|
import { LogoutOutlined } from '@ant-design/icons';
|
||||||
import type { UserConnectedProps } from '@/models/user';
|
import type { UserConnectedProps } from '@/models/user';
|
||||||
import './index.less';
|
import './index.less';
|
||||||
|
import IconFont from '../IconFont';
|
||||||
|
|
||||||
const Avatar: FC<UserConnectedProps> = (props) => {
|
const Avatar: FC<UserConnectedProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
user: { data }, dispatch,
|
user: { data }, dispatch,
|
||||||
} = props;
|
} = props;
|
||||||
|
console.log('user32323', data);
|
||||||
|
|
||||||
|
|
||||||
const handleLogout = () => {
|
const handleLogout = () => {
|
||||||
dispatch?.({
|
dispatch?.({
|
||||||
@ -41,12 +45,16 @@ const Avatar: FC<UserConnectedProps> = (props) => {
|
|||||||
menu={{ items }}
|
menu={{ items }}
|
||||||
>
|
>
|
||||||
<Space className="avatar-container">
|
<Space className="avatar-container">
|
||||||
<img
|
{
|
||||||
alt="avatar"
|
data.avatarUrl ? <img
|
||||||
src={data.avatar}
|
alt="avatar"
|
||||||
className="avatar"
|
src={data.avatarUrl}
|
||||||
/>
|
className="avatar"
|
||||||
<span className="username">{data.name}</span>
|
/> :
|
||||||
|
<IconFont name='icon-touxiang' size="36" ></IconFont>
|
||||||
|
}
|
||||||
|
|
||||||
|
<span className="username">{data.adminName}</span>
|
||||||
</Space>
|
</Space>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
);
|
);
|
||||||
|
|||||||
21
src/components/IconFont/index.tsx
Normal file
21
src/components/IconFont/index.tsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* @Author: cclu 1106109051@qq.com
|
||||||
|
* @Date: 2025-03-26 16:52:53
|
||||||
|
* @LastEditors: cclu 1106109051@qq.com
|
||||||
|
* @LastEditTime: 2025-03-26 16:55:11
|
||||||
|
* @FilePath: \cloudNew\src\components\IconFont\index.tsx
|
||||||
|
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
*/
|
||||||
|
import { createFromIconfontCN } from '@ant-design/icons'
|
||||||
|
|
||||||
|
const IconEle = createFromIconfontCN({
|
||||||
|
// 该地址为iconfont中的项目地址,根据实际进行修改
|
||||||
|
scriptUrl: '//at.alicdn.com/t/font_2794551_586f2xpreyu.js'
|
||||||
|
});
|
||||||
|
|
||||||
|
const IconFont = ({ name, style, size, className }: { name: string, style?: any, size: string | number, className?: any }) => {
|
||||||
|
// const newStyle = size ? { ...{ fontSize: `${size}px`,lineHeight:`${size}px` }, ...style } : {...style}
|
||||||
|
return <IconEle type={name} style={{ ...style, fontSize: `${size}px`, display: 'flex', alignItems: 'center' }} className={className} />
|
||||||
|
}
|
||||||
|
|
||||||
|
export default IconFont;
|
||||||
@ -8,7 +8,7 @@ import ProForm, { ProFormText } from "@ant-design/pro-form";
|
|||||||
import { Button, Col, FormInstance, Row, Tree } from "antd";
|
import { Button, Col, FormInstance, Row, Tree } from "antd";
|
||||||
// import { getServerpartTree } from "@/services/options";
|
// import { getServerpartTree } from "@/services/options";
|
||||||
import useRequest from "@ahooksjs/use-request";
|
import useRequest from "@ahooksjs/use-request";
|
||||||
import { getMerchantShopTree, getServerpartTree } from "./service";
|
import { getMerchantShopTree, getServerpartTree, handleGetAllServicePart } from "./service";
|
||||||
// import './style.less'
|
// import './style.less'
|
||||||
// import { getMerchantShopTree } from "@/pages/Setting/Users/service";
|
// import { getMerchantShopTree } from "@/pages/Setting/Users/service";
|
||||||
|
|
||||||
@ -39,9 +39,19 @@ const LeftSelectTree = ({ setSelectedId, reload, actionRef, currentUser, width,
|
|||||||
const { loading: treeLoading, data: treeViews } = useRequest(async () => {
|
const { loading: treeLoading, data: treeViews } = useRequest(async () => {
|
||||||
let data: any = []
|
let data: any = []
|
||||||
if (currentUser?.UserPattern === 2000) {
|
if (currentUser?.UserPattern === 2000) {
|
||||||
data = await getMerchantShopTree({ BusinessManId: currentUser?.BusinessManID, ShowShop: false });
|
// data = await getMerchantShopTree({ BusinessManId: currentUser?.BusinessManID, ShowShop: false });
|
||||||
} else {
|
} else {
|
||||||
data = await getServerpartTree(currentUser?.provinceCode, currentUser?.CityAuthority, true, true, true, false, 1000)
|
// 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
|
||||||
}
|
}
|
||||||
console.log('datatree', data);
|
console.log('datatree', data);
|
||||||
|
|
||||||
@ -60,11 +70,11 @@ const LeftSelectTree = ({ setSelectedId, reload, actionRef, currentUser, width,
|
|||||||
list.push(item.children[0])
|
list.push(item.children[0])
|
||||||
} else {
|
} else {
|
||||||
if (haveTest) {
|
if (haveTest) {
|
||||||
if (item.value !== 424) {
|
if (item.id !== 424) {
|
||||||
list.push(item)
|
list.push(item)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (item.value !== 424 && item.value !== 586) {
|
if (item.id !== 424 && item.id !== 586) {
|
||||||
list.push(item)
|
list.push(item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,7 +147,7 @@ const LeftSelectTree = ({ setSelectedId, reload, actionRef, currentUser, width,
|
|||||||
const handleFilterList = (list: any, id: any) => {
|
const handleFilterList = (list: any, id: any) => {
|
||||||
let res: any = []
|
let res: any = []
|
||||||
list.forEach((item: any) => {
|
list.forEach((item: any) => {
|
||||||
if (item.value === id) {
|
if (item.id === id) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
res.push(item)
|
res.push(item)
|
||||||
@ -207,22 +217,17 @@ const LeftSelectTree = ({ setSelectedId, reload, actionRef, currentUser, width,
|
|||||||
>
|
>
|
||||||
{treeView && treeView.length > 0 ? <Tree
|
{treeView && treeView.length > 0 ? <Tree
|
||||||
checkable
|
checkable
|
||||||
treeData={isShowAllInTree ? [{
|
treeData={treeView}
|
||||||
label: '全部',
|
|
||||||
value: 0,
|
|
||||||
key: '0-0',
|
|
||||||
children: treeView
|
|
||||||
}] : treeView}
|
|
||||||
fieldNames={{
|
fieldNames={{
|
||||||
title: "label",
|
title: "name",
|
||||||
key: "key"
|
key: "id"
|
||||||
}}
|
}}
|
||||||
blockNode
|
blockNode
|
||||||
defaultExpandAll={isShowAllInTree ? false : true}
|
defaultExpandAll={isShowAllInTree ? true : false}
|
||||||
defaultExpandedKeys={isShowAllInTree ? treeShowRow && treeShowRow.length > 0 ? treeShowRow : ['0-0'] : []}
|
defaultExpandedKeys={isShowAllInTree ? [] : [510000]}
|
||||||
onCheck={(checkedKeys: React.Key[] | any, info) => {
|
onCheck={(checkedKeys: React.Key[] | any, info) => {
|
||||||
const selectedIds = info.checkedNodes.filter((n: any) => n?.type === 1)
|
const selectedIds = info.checkedNodes.filter((n: any) => n?.districtId > 0)
|
||||||
setSelectedId(selectedIds.map(n => n?.value)?.toString() || '')
|
setSelectedId(selectedIds.map(n => n?.id) || '')
|
||||||
if (reload) {
|
if (reload) {
|
||||||
actionRef?.current?.reload()
|
actionRef?.current?.reload()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -59,3 +59,14 @@ export async function handleGetServerpartDDL(params: any) {
|
|||||||
return data.Result_Data.List
|
return data.Result_Data.List
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
import requestNew from "@/utils/request"
|
||||||
|
// 新的拿到服务区的树的接口
|
||||||
|
|
||||||
|
export async function handleGetAllServicePart(params?: any) {
|
||||||
|
const data = await requestNew.get('/server-part/provinces', params)
|
||||||
|
if (data.code === 200) {
|
||||||
|
return data.data
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}
|
||||||
@ -1,11 +1,4 @@
|
|||||||
/*
|
|
||||||
* @Author: cclu 1106109051@qq.com
|
|
||||||
* @Date: 2025-02-27 15:55:46
|
|
||||||
* @LastEditors: cclu 1106109051@qq.com
|
|
||||||
* @LastEditTime: 2025-03-10 17:46:55
|
|
||||||
* @FilePath: \umi4-admin-main\src\layouts\index.tsx
|
|
||||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
|
||||||
*/
|
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { Dropdown, Layout, Menu, Tabs, Tooltip } from 'antd';
|
import { Dropdown, Layout, Menu, Tabs, Tooltip } from 'antd';
|
||||||
@ -110,6 +103,8 @@ const BasicLayout: FC<{ user: UserModelState, global: ProfileModelState, dispatc
|
|||||||
: item.name,
|
: item.name,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
console.log('consumableMenuconsumableMenuconsumableMenu', consumableMenu);
|
||||||
|
|
||||||
// const consumableMenu: MenuDataItem[] = [
|
// const consumableMenu: MenuDataItem[] = [
|
||||||
// {
|
// {
|
||||||
// path: '/',
|
// path: '/',
|
||||||
@ -200,12 +195,28 @@ const BasicLayout: FC<{ user: UserModelState, global: ProfileModelState, dispatc
|
|||||||
hideInMenu: false,
|
hideInMenu: false,
|
||||||
name: "考核记录管理",
|
name: "考核记录管理",
|
||||||
path: "/examine/record",
|
path: "/examine/record",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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('tabsRoutes', tabsRoutes);
|
||||||
console.log('location', location);
|
console.log('location', location);
|
||||||
console.log('consumableMenu', consumableMenu);
|
console.log('consumableMenu', consumableMenu);
|
||||||
|
console.log('oneFloorListoneFloorListoneFloorListoneFloorList', oneFloorList);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -273,10 +284,9 @@ const BasicLayout: FC<{ user: UserModelState, global: ProfileModelState, dispatc
|
|||||||
actionsRender={() => <nav />}
|
actionsRender={() => <nav />}
|
||||||
onPageChange={(location) => {
|
onPageChange={(location) => {
|
||||||
console.log('location', location);
|
console.log('location', location);
|
||||||
|
|
||||||
if (location?.pathname && location?.pathname !== '/') {
|
if (location?.pathname && location?.pathname !== '/') {
|
||||||
|
|
||||||
const nextModule: any = oneFloorList.filter(n => location?.pathname === n?.path)
|
const nextModule: any = oneFloorList.filter(n => location?.pathname === n?.path)
|
||||||
|
|
||||||
let title = ''
|
let title = ''
|
||||||
if (nextModule && nextModule.length > 0) {
|
if (nextModule && nextModule.length > 0) {
|
||||||
title = nextModule[0].name
|
title = nextModule[0].name
|
||||||
|
|||||||
@ -242,10 +242,27 @@ const UserModel: UserModelType = {
|
|||||||
path: '/examine/record',
|
path: '/examine/record',
|
||||||
name: '考核记录管理',
|
name: '考核记录管理',
|
||||||
component: "@/pages/examine/record",
|
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 indexAllMenuItemByPath: any = []
|
||||||
let indexValidMenuItemByPath: any = []
|
let indexValidMenuItemByPath: any = []
|
||||||
@ -278,6 +295,8 @@ const UserModel: UserModelType = {
|
|||||||
'/examine/modal',
|
'/examine/modal',
|
||||||
'/examine/question',
|
'/examine/question',
|
||||||
'/examine/record',
|
'/examine/record',
|
||||||
|
'/setting/menu',
|
||||||
|
'/examine/recordSummary'
|
||||||
],
|
],
|
||||||
rootSubmenuKeys: handleGetRootSubmenuKeys(menuRes.data),
|
rootSubmenuKeys: handleGetRootSubmenuKeys(menuRes.data),
|
||||||
indexAllMenuItemById: handleGetEachDatumFromNestedDataByKey(menuRes.data, 'id'),
|
indexAllMenuItemById: handleGetEachDatumFromNestedDataByKey(menuRes.data, 'id'),
|
||||||
|
|||||||
@ -14,6 +14,10 @@ const authority: PageAuthority = {
|
|||||||
'/examine/record': [
|
'/examine/record': [
|
||||||
'/examine/record',
|
'/examine/record',
|
||||||
],
|
],
|
||||||
|
'/examine/recordSummary': [
|
||||||
|
'/examine/recordSummary',
|
||||||
|
],
|
||||||
|
'/setting/menu': ['/setting/menu']
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
147
src/pages/examine/index/components/addBigType.tsx
Normal file
147
src/pages/examine/index/components/addBigType.tsx
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
import { ConnectState } from "@/models/global";
|
||||||
|
import { FormInstance, ProForm, ProFormSwitch, ProFormText, ProFormTextArea, ProFormTreeSelect } from "@ant-design/pro-components";
|
||||||
|
import { useImperativeHandle, useRef } from "react";
|
||||||
|
import { connect } from "umi";
|
||||||
|
import { handleGetAddExamineType, handleGetEditExamineType, handleGetExamineTypeTreeList } from "../service";
|
||||||
|
import { message, Modal } from "antd";
|
||||||
|
|
||||||
|
|
||||||
|
type DetailProps = {
|
||||||
|
parentRow: any
|
||||||
|
onRef: any
|
||||||
|
openAddModal: boolean
|
||||||
|
currentUser?: any
|
||||||
|
setOpenAddModal?: any
|
||||||
|
parentActionRef?: any
|
||||||
|
setParentRow?: any
|
||||||
|
afterAdd?: any // 新增完之后 需要调用的方法
|
||||||
|
}
|
||||||
|
const AddBigType = ({ parentRow, onRef, openAddModal, currentUser, setOpenAddModal, parentActionRef, setParentRow, afterAdd }: DetailProps) => {
|
||||||
|
|
||||||
|
// 弹出框的表单实例
|
||||||
|
const modalRef = useRef<FormInstance>()
|
||||||
|
|
||||||
|
|
||||||
|
useImperativeHandle(onRef, () => ({
|
||||||
|
modalRef
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Modal
|
||||||
|
title={`${parentRow?.id ? '编辑' : '创建'}分类`}
|
||||||
|
open={openAddModal}
|
||||||
|
destroyOnClose
|
||||||
|
onOk={() => {
|
||||||
|
modalRef.current?.validateFields().then(async (res) => {
|
||||||
|
let req = {}
|
||||||
|
let data = {}
|
||||||
|
if (parentRow?.id) {
|
||||||
|
req = {
|
||||||
|
...parentRow,
|
||||||
|
parentId: res.parentId,
|
||||||
|
name: res.name,
|
||||||
|
description: res.description,
|
||||||
|
status: res.status,
|
||||||
|
operator: currentUser?.operator
|
||||||
|
}
|
||||||
|
data = await handleGetEditExamineType(req)
|
||||||
|
} else {
|
||||||
|
req = {
|
||||||
|
parentId: res.parentId,
|
||||||
|
name: res.name,
|
||||||
|
description: res.description,
|
||||||
|
sortOrder: "1",
|
||||||
|
status: res.status,
|
||||||
|
operator: currentUser?.operator
|
||||||
|
}
|
||||||
|
data = await handleGetAddExamineType(req)
|
||||||
|
}
|
||||||
|
console.log('req', req);
|
||||||
|
console.log('data', data);
|
||||||
|
if (data.Result_Code === 100) {
|
||||||
|
modalRef.current?.resetFields()
|
||||||
|
message.success(`${parentRow?.id ? '编辑' : '新增'}成功!`)
|
||||||
|
setOpenAddModal(false)
|
||||||
|
if (parentActionRef) {
|
||||||
|
parentActionRef.current?.reload()
|
||||||
|
}
|
||||||
|
if (setParentRow) {
|
||||||
|
setParentRow(undefined)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (afterAdd) {
|
||||||
|
afterAdd()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
message.error(data.Result_Desc)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
onCancel={() => {
|
||||||
|
modalRef.current?.setFieldsValue({})
|
||||||
|
if (setParentRow) {
|
||||||
|
setParentRow(undefined)
|
||||||
|
}
|
||||||
|
setOpenAddModal(false)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProForm formRef={modalRef} submitter={false} request={() => {
|
||||||
|
console.log('parentRow', parentRow);
|
||||||
|
return { ...parentRow }
|
||||||
|
}}>
|
||||||
|
<ProFormTreeSelect
|
||||||
|
label={"类别层级"}
|
||||||
|
name={"parentId"}
|
||||||
|
request={async () => {
|
||||||
|
const req = {}
|
||||||
|
const data = await handleGetExamineTypeTreeList(req)
|
||||||
|
console.log('dsadas', data);
|
||||||
|
let res = [
|
||||||
|
{
|
||||||
|
name: '/',
|
||||||
|
id: 0,
|
||||||
|
children: data
|
||||||
|
}
|
||||||
|
]
|
||||||
|
return res
|
||||||
|
}}
|
||||||
|
fieldProps={{
|
||||||
|
treeDefaultExpandedKeys: [0],
|
||||||
|
fieldNames: {
|
||||||
|
label: "name",
|
||||||
|
value: "id"
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: '请选择类别层级!' }
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ProFormText
|
||||||
|
label={"类别名称"}
|
||||||
|
name={"name"}
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: '请输入类别名称!' }
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<ProFormTextArea
|
||||||
|
label={"类别注释"}
|
||||||
|
name={"description"}
|
||||||
|
/>
|
||||||
|
<ProFormSwitch
|
||||||
|
label={"有效状态"}
|
||||||
|
name={"status"}
|
||||||
|
initialValue={parentRow?.id ? parentRow.status : true}
|
||||||
|
/>
|
||||||
|
</ProForm>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(({ user }: ConnectState) => ({
|
||||||
|
currentUser: user.data
|
||||||
|
}))(AddBigType);
|
||||||
@ -7,6 +7,7 @@ import moment from "moment";
|
|||||||
import LeftSelectTree from "@/components/leftSelectTree/leftSelectTree";
|
import LeftSelectTree from "@/components/leftSelectTree/leftSelectTree";
|
||||||
import { handleGetAddExamineType, handleGetDeleteExamineType, handleGetEditExamineType, handleGetExamineTypeList, handleGetExamineTypeTreeList } from "./service";
|
import { handleGetAddExamineType, handleGetDeleteExamineType, handleGetEditExamineType, handleGetExamineTypeList, handleGetExamineTypeTreeList } from "./service";
|
||||||
import { ProForm, ProFormSwitch, ProFormText, ProFormTextArea, ProFormTreeSelect } from "@ant-design/pro-components";
|
import { ProForm, ProFormSwitch, ProFormText, ProFormTextArea, ProFormTreeSelect } from "@ant-design/pro-components";
|
||||||
|
import AddBigType from "./components/addBigType";
|
||||||
|
|
||||||
|
|
||||||
const examineIndex: React.FC<{ currentUser: any }> = (props) => {
|
const examineIndex: React.FC<{ currentUser: any }> = (props) => {
|
||||||
@ -118,10 +119,16 @@ const examineIndex: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
|
|
||||||
// 删除分类
|
// 删除分类
|
||||||
const handleDeleteType = async (id: number) => {
|
const handleDeleteType = async (id: number) => {
|
||||||
const data = await handleGetDeleteExamineType(id)
|
let req: any = {
|
||||||
if (data.code === 200) {
|
id: id
|
||||||
message.success(data.message)
|
}
|
||||||
|
console.log('req', req);
|
||||||
|
const data = await handleGetDeleteExamineType(req)
|
||||||
|
if (data.Result_Code === 100) {
|
||||||
|
message.success('删除成功!')
|
||||||
actionRef.current?.reload()
|
actionRef.current?.reload()
|
||||||
|
} else {
|
||||||
|
message.error(data.Result_Desc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,104 +197,13 @@ const examineIndex: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Modal
|
|
||||||
title={`${currentRow?.id ? '编辑' : '创建'}分类`}
|
|
||||||
open={openAddModal}
|
|
||||||
destroyOnClose
|
|
||||||
onOk={() => {
|
|
||||||
modalRef.current?.validateFields().then(async (res) => {
|
|
||||||
let req = {}
|
|
||||||
let data = {}
|
|
||||||
if (currentRow?.id) {
|
|
||||||
req = {
|
|
||||||
...currentRow,
|
|
||||||
parentId: res.parentId,
|
|
||||||
name: res.name,
|
|
||||||
description: res.description,
|
|
||||||
status: res.status,
|
|
||||||
operator: currentUser?.operator
|
|
||||||
}
|
|
||||||
data = await handleGetEditExamineType(req)
|
|
||||||
} else {
|
|
||||||
req = {
|
|
||||||
parentId: res.parentId,
|
|
||||||
name: res.name,
|
|
||||||
description: res.description,
|
|
||||||
sortOrder: "1",
|
|
||||||
status: res.status,
|
|
||||||
operator: currentUser?.operator
|
|
||||||
}
|
|
||||||
data = await handleGetAddExamineType(req)
|
|
||||||
}
|
|
||||||
console.log('req', req);
|
|
||||||
console.log('data', data);
|
|
||||||
if (data.code === 200) {
|
|
||||||
modalRef.current?.resetFields()
|
|
||||||
message.success(data.message)
|
|
||||||
setOpenAddModal(false)
|
|
||||||
actionRef.current?.reload()
|
|
||||||
setCurrentRow(undefined)
|
|
||||||
} else {
|
|
||||||
message.error(data.message)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
onCancel={() => {
|
|
||||||
modalRef.current?.setFieldsValue({})
|
|
||||||
setCurrentRow(undefined)
|
|
||||||
setOpenAddModal(false)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ProForm formRef={modalRef} submitter={false} request={() => {
|
|
||||||
console.log('currentRow', currentRow);
|
|
||||||
return { ...currentRow }
|
|
||||||
}}>
|
|
||||||
<ProFormTreeSelect
|
|
||||||
label={"类别层级"}
|
|
||||||
name={"parentId"}
|
|
||||||
request={async () => {
|
|
||||||
const req = {}
|
|
||||||
const data = await handleGetExamineTypeList(req)
|
|
||||||
console.log('dsadas', data);
|
|
||||||
let res = [
|
|
||||||
{
|
|
||||||
name: '/',
|
|
||||||
id: 0,
|
|
||||||
children: data
|
|
||||||
}
|
|
||||||
]
|
|
||||||
return res
|
|
||||||
}}
|
|
||||||
fieldProps={{
|
|
||||||
treeDefaultExpandedKeys: [0],
|
|
||||||
fieldNames: {
|
|
||||||
label: "name",
|
|
||||||
value: "id"
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
rules={[
|
|
||||||
{ required: true, message: '请选择类别层级!' }
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ProFormText
|
|
||||||
label={"类别名称"}
|
<AddBigType parentRow={currentRow} openAddModal={openAddModal}
|
||||||
name={"name"}
|
setOpenAddModal={setOpenAddModal}
|
||||||
rules={[
|
parentActionRef={actionRef}
|
||||||
{ required: true, message: '请输入类别名称!' }
|
setParentRow={setCurrentRow} />
|
||||||
]}
|
|
||||||
/>
|
|
||||||
<ProFormTextArea
|
|
||||||
label={"类别注释"}
|
|
||||||
name={"description"}
|
|
||||||
/>
|
|
||||||
<ProFormSwitch
|
|
||||||
label={"有效状态"}
|
|
||||||
name={"status"}
|
|
||||||
initialValue={currentRow?.id ? currentRow.status : true}
|
|
||||||
/>
|
|
||||||
</ProForm>
|
|
||||||
</Modal>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,13 @@
|
|||||||
import request from "@/utils/request"
|
|
||||||
|
// import request from "@/utils/request"
|
||||||
|
import request from "@/utils/requestJava"
|
||||||
|
|
||||||
|
|
||||||
// 拿到类别列表接口
|
// 拿到类别列表接口
|
||||||
export async function handleGetExamineTypeList(params?: any) {
|
export async function handleGetExamineTypeList(params?: any) {
|
||||||
const data = await request.get('/question-categories', {params})
|
const data = await request.get('/question-categories/getList', { params })
|
||||||
if (data.code === 200) {
|
if (data.Result_Code === 100) {
|
||||||
return data.data
|
return data.Result_Data.List
|
||||||
}
|
}
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
@ -12,26 +15,26 @@ export async function handleGetExamineTypeList(params?: any) {
|
|||||||
// 拿树形的
|
// 拿树形的
|
||||||
export async function handleGetExamineTypeTreeList(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.code === 200) {
|
if (data.Result_Code === 100) {
|
||||||
return data.data
|
return data.Result_Data.List
|
||||||
}
|
}
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增类别列表接口
|
// 新增类别列表接口
|
||||||
export async function handleGetAddExamineType(params: any) {
|
export async function handleGetAddExamineType(params: any) {
|
||||||
const data = await request.post('/question-categories', params)
|
const data = await request.post('/question-categories/save', params)
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除类别接口
|
// 删除类别接口
|
||||||
export async function handleGetDeleteExamineType(params: any) {
|
export async function handleGetDeleteExamineType(params: any) {
|
||||||
const data = await request.get(`/question-categories/delete/${params}`)
|
const data = await request.get(`/question-categories/delete`, { params })
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
// 编辑分类接口
|
// 编辑分类接口
|
||||||
export async function handleGetEditExamineType(params: any) {
|
export async function handleGetEditExamineType(params: any) {
|
||||||
const data = await request.post(`/question-categories/${params.id}`, params)
|
const data = await request.post(`/question-categories/update`, params)
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
@ -1,31 +1,37 @@
|
|||||||
import LeftSelectTree from "@/components/leftSelectTree/leftSelectTree";
|
import LeftSelectTree from "@/components/leftSelectTree/leftSelectTree";
|
||||||
import { handleGetServerpartDDL } from "@/components/leftSelectTree/service";
|
import { handleGetServerpartDDL } from "@/components/leftSelectTree/service";
|
||||||
import { ActionType, FormInstance, ProCard, ProForm, ProFormList, ProFormSelect, ProFormSwitch, ProFormText, ProFormTextArea, ProTable } from "@ant-design/pro-components";
|
import { ActionType, FormInstance, ProCard, ProForm, ProFormDigit, ProFormList, ProFormSelect, ProFormSwitch, ProFormText, ProFormTextArea, ProTable } from "@ant-design/pro-components";
|
||||||
import { Button, Col, message, Modal, Popconfirm, Row, Space, Image, Drawer } from "antd";
|
import { Button, Col, message, Modal, Popconfirm, Row, Space, Image, Drawer } from "antd";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { connect } from "umi";
|
import { connect } from "umi";
|
||||||
import { handleAddTemplates, handleDeleteTemplates, handleGetQuestionList, handleGetTemplatesList, handleUpdateTemplates, handleUploadFile } from "./service";
|
import { handleAddTemplates, handleBatchService, handleDeleteTemplates, handleGetQuestionList, handleGetTemplatesList, handleSearchModalTree, handleUpdateTemplates, handleUploadFile } from "./service";
|
||||||
import { handleGetExamineTypeTreeList } from "../index/service";
|
import { handleGetExamineTypeTreeList } from "../index/service";
|
||||||
import QRCode from 'qrcode';
|
import QRCode from 'qrcode';
|
||||||
import { base64ToFile } from "@/utils/publicMethods";
|
import { base64ToFile } from "@/utils/publicMethods";
|
||||||
import RecordDetail from "../record/components/recordDetail";
|
import RecordDetail from "../record/components/recordDetail";
|
||||||
|
import AddBigType from "../index/components/addBigType";
|
||||||
|
import AddQuestion from "../question/components/addQuestion";
|
||||||
|
import { ArrowDownOutlined, ArrowUpOutlined } from "@ant-design/icons";
|
||||||
|
|
||||||
|
|
||||||
const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
||||||
const { currentUser } = props
|
const { currentUser } = props
|
||||||
|
|
||||||
const actionRef = useRef<ActionType>();
|
const actionRef = useRef<ActionType>();
|
||||||
|
const cloneActionRef = useRef<ActionType>();
|
||||||
const formRef = useRef<FormInstance>();
|
const formRef = useRef<FormInstance>();
|
||||||
const modalActionRef = useRef<ActionType>();
|
const modalActionRef = useRef<ActionType>();
|
||||||
const modalFormRef = useRef<FormInstance>();
|
const modalFormRef = useRef<FormInstance>();
|
||||||
|
|
||||||
|
const cloneFormRef = useRef<FormInstance>();
|
||||||
|
const batchCloneForm = useRef<FormInstance>();
|
||||||
|
|
||||||
|
|
||||||
// 弹出框的表单实例
|
// 弹出框的表单实例
|
||||||
const modalRef = useRef<FormInstance>()
|
const modalRef = useRef<any>()
|
||||||
// 树相关的属性和方法
|
// 树相关的属性和方法
|
||||||
const [selectedId, setSelectedId] = useState<string>()
|
const [selectedId, setSelectedId] = useState<string[]>()
|
||||||
const [collapsible, setCollapsible] = useState<boolean>(false)
|
const [collapsible, setCollapsible] = useState<boolean>(false)
|
||||||
|
|
||||||
// 显示新增点位的悬浮框
|
// 显示新增点位的悬浮框
|
||||||
@ -36,6 +42,8 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
const [currentRow, setCurrentRow] = useState<any>()
|
const [currentRow, setCurrentRow] = useState<any>()
|
||||||
// 服务区的枚举
|
// 服务区的枚举
|
||||||
const [serviceObj, setServiceObj] = useState<any>()
|
const [serviceObj, setServiceObj] = useState<any>()
|
||||||
|
// 服务区的全部数据
|
||||||
|
const [allServiceList, setAllServiceList] = useState<any>()
|
||||||
// 生成的二维码的初始
|
// 生成的二维码的初始
|
||||||
const [qrCodeUrl, setQrCodeUrl] = useState<string>()
|
const [qrCodeUrl, setQrCodeUrl] = useState<string>()
|
||||||
// 选择问题的悬浮框
|
// 选择问题的悬浮框
|
||||||
@ -53,25 +61,64 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
const [previewIndex, setPreviewIndex] = useState<number>(0)
|
const [previewIndex, setPreviewIndex] = useState<number>(0)
|
||||||
const [columnsStateMap, setColumnsStateMap] = useState<any>({
|
const [columnsStateMap, setColumnsStateMap] = useState<any>({
|
||||||
updatedAt: { show: false },
|
updatedAt: { show: false },
|
||||||
createdAt: { show: false },
|
// createdAt: { show: false },
|
||||||
operator: { show: false },
|
operator: { show: false },
|
||||||
})
|
})
|
||||||
|
// 显示新增大类的抽屉
|
||||||
|
const [openAddBigType, setOpenAddBigType] = useState<boolean>(false)
|
||||||
|
// 显示 新增问题的抽屉
|
||||||
|
const [openAddQuestion, setOpenAddQuestion] = useState<boolean>(false)
|
||||||
|
// 拿到protable的问题分类
|
||||||
|
const [bigTypeList, setBigTypeList] = useState<any>()
|
||||||
|
// 显示克隆悬浮框
|
||||||
|
const [showCloneModal, handleShowCloneModal] = useState<boolean>(false)
|
||||||
|
// 克隆的选择内容
|
||||||
|
const [selectedCloneId, setSelectedCloneId] = useState<any>()
|
||||||
|
const [selectedCloneDetail, setSelectedCloneDetail] = useState<any>()
|
||||||
|
// 默认展开行的id
|
||||||
|
const [defaultExpandRow, setDefaultExpandRow] = useState<any>()
|
||||||
|
// 点位克隆的悬浮框
|
||||||
|
const [showBatchCloneModal, setshowBatchCloneModal] = useState<boolean>(false)
|
||||||
|
// 批量克隆的loading效果
|
||||||
|
const [batchLoading, setBatchLoading] = useState<boolean>(false)
|
||||||
|
|
||||||
const columns: any = [
|
const columns: any = [
|
||||||
|
// {
|
||||||
|
// title: "巡查类型",
|
||||||
|
// dataIndex: "status",
|
||||||
|
// hideInTable: true,
|
||||||
|
// valueType: "select",
|
||||||
|
// valueEnum: {
|
||||||
|
// "1": '异常',
|
||||||
|
// "0": "正常"
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// title: "搜索内容",
|
||||||
|
// dataIndex: "anySearchParams",
|
||||||
|
// hideInTable: true,
|
||||||
|
// fieldProps: {
|
||||||
|
|
||||||
|
// }
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
title: <div style={{ textAlign: 'center' }}>服务区名称</div>,
|
title: <div style={{ textAlign: 'center' }}>服务区名称</div>,
|
||||||
dataIndex: "serverPartName",
|
dataIndex: "serverPartName",
|
||||||
hideInSearch: true,
|
hideInSearch: true,
|
||||||
width: 150,
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: <div style={{ textAlign: 'center' }}>点位名称</div>,
|
|
||||||
dataIndex: "title",
|
|
||||||
hideInSearch: true,
|
|
||||||
width: 200,
|
width: 200,
|
||||||
ellipsis: true
|
ellipsis: true,
|
||||||
|
render: (_, record) => {
|
||||||
|
return record?.type === 'district' || record?.type === 'servicePart' ? record?.name :
|
||||||
|
record?.title
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// title: <div style={{ textAlign: 'center' }}>点位名称</div>,
|
||||||
|
// dataIndex: "title",
|
||||||
|
// hideInSearch: true,
|
||||||
|
// width: 200,
|
||||||
|
// ellipsis: true
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
title: <div style={{ textAlign: 'center' }}>问题列表</div>,
|
title: <div style={{ textAlign: 'center' }}>问题列表</div>,
|
||||||
dataIndex: "questions",
|
dataIndex: "questions",
|
||||||
@ -85,10 +132,12 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
let options: string = ''
|
let options: string = ''
|
||||||
if (item.question.options && item.question.options.length > 0) {
|
if (item.question.options && item.question.options.length > 0) {
|
||||||
item.question.options.forEach((subItem: any, subIndex: number) => {
|
item.question.options.forEach((subItem: any, subIndex: number) => {
|
||||||
options += `${subIndex > 0 ? ',' : ''}选项${subIndex + 1}:${subItem.text}`
|
options += `${subItem.text};`
|
||||||
|
// ${subIndex > 0 ? ',' : ''} 选项${subIndex + 1}:
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
questionStr += `${index > 0 ? ',' : ''}问题${index + 1}:${item.question.title},${options}`
|
questionStr += `${index > 0 ? ',' : ''}问题:${item.question.title}。${options}`
|
||||||
|
// ${index + 1}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return questionStr || ''
|
return questionStr || ''
|
||||||
@ -117,7 +166,7 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
width: 100,
|
width: 100,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
return record?.status ? '有效' : '无效'
|
return record?.type === 'district' || record?.type === 'servicePart' ? '' : record?.status ? '有效' : '无效'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -163,18 +212,18 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
align: 'center',
|
align: 'center',
|
||||||
hideInSearch: true,
|
hideInSearch: true,
|
||||||
fixed: "right",
|
fixed: "right",
|
||||||
width: 120,
|
width: 150,
|
||||||
render: (_: any, record: any) => {
|
render: (_: any, record: any) => {
|
||||||
return <Space>
|
return record?.type === 'district' || record?.type === 'servicePart' ? '' : <Space>
|
||||||
<a onClick={() => {
|
<a onClick={() => {
|
||||||
console.log('record', record);
|
console.log('currentRow', record);
|
||||||
setCurrentRow(record)
|
setCurrentRow(record)
|
||||||
setShowPlaceModal(true)
|
setShowPlaceModal(true)
|
||||||
}}>编辑</a>
|
}}>编辑</a>
|
||||||
<a onClick={() => {
|
{/* <a onClick={() => {
|
||||||
setCurrentRow(record)
|
setCurrentRow(record)
|
||||||
handleShowDetail(true)
|
handleShowDetail(true)
|
||||||
}}>详情</a>
|
}}>详情</a> */}
|
||||||
<Popconfirm
|
<Popconfirm
|
||||||
title={"确认删除?"}
|
title={"确认删除?"}
|
||||||
onConfirm={async () => {
|
onConfirm={async () => {
|
||||||
@ -183,6 +232,13 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
>
|
>
|
||||||
<a>删除</a>
|
<a>删除</a>
|
||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
|
<a onClick={() => {
|
||||||
|
console.log('currentRow', record);
|
||||||
|
setCurrentRow(record)
|
||||||
|
setshowBatchCloneModal(true)
|
||||||
|
}}>
|
||||||
|
点位克隆
|
||||||
|
</a>
|
||||||
|
|
||||||
</Space>
|
</Space>
|
||||||
}
|
}
|
||||||
@ -196,25 +252,26 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
dataIndex: "id",
|
dataIndex: "id",
|
||||||
hideInTable: true,
|
hideInTable: true,
|
||||||
valueType: 'treeSelect',
|
valueType: 'treeSelect',
|
||||||
request: async () => {
|
// request: async () => {
|
||||||
const data = await handleGetExamineTypeTreeList()
|
// const data = await handleGetExamineTypeTreeList()
|
||||||
console.log('data', data);
|
// console.log('data', data);
|
||||||
return data && data.length > 0 ? data.map(item => ({
|
// return data && data.length > 0 ? data.map(item => ({
|
||||||
title: item.name,
|
// title: item.name,
|
||||||
value: item.id,
|
// value: item.id,
|
||||||
children: item.children?.map((child: any) => ({
|
// children: item.children?.map((child: any) => ({
|
||||||
title: child.name,
|
// title: child.name,
|
||||||
value: child.id,
|
// value: child.id,
|
||||||
children: child.children || []
|
// children: child.children || []
|
||||||
})) || []
|
// })) || []
|
||||||
})) : []
|
// })) : []
|
||||||
},
|
// },
|
||||||
fieldProps: {
|
fieldProps: {
|
||||||
multiple: false,
|
multiple: false,
|
||||||
treeDefaultExpandAll: true,
|
treeDefaultExpandAll: true,
|
||||||
showSearch: true,
|
showSearch: true,
|
||||||
treeNodeFilterProp: 'title',
|
treeNodeFilterProp: 'title',
|
||||||
placeholder: '请选择问题分类'
|
placeholder: '请选择问题分类',
|
||||||
|
options: bigTypeList
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -246,19 +303,45 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
// 删除模版
|
// 删除模版
|
||||||
const deleteQuestion = async (id: number) => {
|
const deleteQuestion = async (id: number) => {
|
||||||
const data = await handleDeleteTemplates({ id: id })
|
const data = await handleDeleteTemplates({ id: id })
|
||||||
if (data.code === 200) {
|
if (data.Result_Code === 100) {
|
||||||
message.success(data.message)
|
message.success(data.Result_Desc)
|
||||||
actionRef.current?.reload()
|
actionRef.current?.reload()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 新增完类型之后的刷新
|
||||||
|
const handleReloadSearchList = async () => {
|
||||||
|
modalActionRef.current?.reload();
|
||||||
|
fetchTreeData()
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchTreeData = async () => {
|
||||||
|
const data = await handleGetExamineTypeTreeList();
|
||||||
|
const formattedData = data?.length ? data.map(item => ({
|
||||||
|
title: item.name,
|
||||||
|
value: item.id,
|
||||||
|
children: item.children?.map(child => ({
|
||||||
|
title: child.name,
|
||||||
|
value: child.id,
|
||||||
|
children: child.children || []
|
||||||
|
})) || []
|
||||||
|
})) : [];
|
||||||
|
console.log('formattedData', formattedData);
|
||||||
|
|
||||||
|
setBigTypeList(formattedData);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchTreeData()
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
|
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
|
||||||
{/* <LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} currentUser={currentUser} /> */}
|
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} currentUser={currentUser} />
|
||||||
|
|
||||||
<div style={{
|
<div style={{
|
||||||
// width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
|
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
|
||||||
width: "100%",
|
// width: "100%",
|
||||||
paddingTop: 0,
|
paddingTop: 0,
|
||||||
paddingBottom: 0,
|
paddingBottom: 0,
|
||||||
paddingRight: 0
|
paddingRight: 0
|
||||||
@ -271,14 +354,24 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
expandable={{
|
expandable={{
|
||||||
expandRowByClick: true
|
expandRowByClick: true
|
||||||
}}
|
}}
|
||||||
|
rowKey={(record) => {
|
||||||
|
return `${record?.id}`
|
||||||
|
}}
|
||||||
scroll={{ x: "100%", y: 'calc(100vh - 400px)' }}
|
scroll={{ x: "100%", y: 'calc(100vh - 400px)' }}
|
||||||
headerTitle={<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}>走动式点位管理</span>}
|
headerTitle={<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}>走动式点位管理</span>}
|
||||||
search={{ span: 6 }}
|
search={{ span: 6 }}
|
||||||
request={async () => {
|
request={async () => {
|
||||||
const req: any = {
|
console.log('selectedId', selectedId);
|
||||||
|
|
||||||
|
if (!(selectedId && selectedId.length > 0)) {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
const data = await handleGetTemplatesList()
|
|
||||||
|
|
||||||
|
const req: any = {
|
||||||
|
serverPartIds: selectedId && selectedId.length > 0 ? selectedId : [],
|
||||||
|
}
|
||||||
|
const data = await handleSearchModalTree(req)
|
||||||
if (data && data.length > 0) {
|
if (data && data.length > 0) {
|
||||||
return { data, success: true }
|
return { data, success: true }
|
||||||
}
|
}
|
||||||
@ -332,6 +425,7 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
modalRef.current?.validateFields().then(async (res) => {
|
modalRef.current?.validateFields().then(async (res) => {
|
||||||
console.log('res', res);
|
console.log('res', res);
|
||||||
console.log('currentRow', currentRow);
|
console.log('currentRow', currentRow);
|
||||||
|
console.log('selectedQuestionDetail', selectedQuestionDetail);
|
||||||
let req = {}
|
let req = {}
|
||||||
let data = {}
|
let data = {}
|
||||||
if (currentRow?.id) {
|
if (currentRow?.id) {
|
||||||
@ -346,32 +440,43 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// 判断是否有改动 一样 说明没改动 那么把老的拿进去就行
|
// 判断是否有改动 一样 说明没改动 那么把老的拿进去就行
|
||||||
if (currentRow?.questionnaireTemplateQuestions.length === res.questions.length) {
|
// if (currentRow?.questionnaireTemplateQuestions.length === res.questions.length) {
|
||||||
if (currentRow?.questionnaireTemplateQuestions && currentRow?.questionnaireTemplateQuestions.length > 0) {
|
// if (currentRow?.questionnaireTemplateQuestions && currentRow?.questionnaireTemplateQuestions.length > 0) {
|
||||||
currentRow?.questionnaireTemplateQuestions.forEach((item) => {
|
// currentRow?.questionnaireTemplateQuestions.forEach((item) => {
|
||||||
questions.push({
|
// questions.push({
|
||||||
questionId: item.question.id,
|
// questionId: item.question.id,
|
||||||
isRequired: item.question.required,
|
// isRequired: item.question.required,
|
||||||
sortOrder: item.question.sortOrder
|
// sortOrder: item.question.sortOrder
|
||||||
})
|
// })
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// // 不一样 说明有删除 不然走的是第一个
|
||||||
|
// if (res.questions && res.questions.length > 0) {
|
||||||
|
// res.questions.forEach((item) => {
|
||||||
|
// questions.push({
|
||||||
|
// questionId: item.id,
|
||||||
|
// isRequired: item.required,
|
||||||
|
// sortOrder: item.sortOrder
|
||||||
|
// })
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
if (res.questions && res.questions.length > 0) {
|
||||||
|
res.questions.forEach((item: any) => {
|
||||||
|
questions.push({
|
||||||
|
questionId: item.questionId,
|
||||||
|
isRequired: item.isRequired,
|
||||||
|
sortOrder: item.sortOrder
|
||||||
})
|
})
|
||||||
}
|
})
|
||||||
} else {
|
|
||||||
// 不一样 说明有删除 不然走的是第一个
|
|
||||||
if (res.questions && res.questions.length > 0) {
|
|
||||||
res.questions.forEach((item) => {
|
|
||||||
questions.push({
|
|
||||||
questionId: item.id,
|
|
||||||
isRequired: item.required,
|
|
||||||
sortOrder: item.sortOrder
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
req = {
|
req = {
|
||||||
...currentRow,
|
...currentRow,
|
||||||
|
deadlineType: res.deadlineType,
|
||||||
|
deadlineFrequency: res.deadlineFrequency,
|
||||||
title: res.title,
|
title: res.title,
|
||||||
serverPartName: serviceObj ? serviceObj[res.serverPartId] : "",
|
serverPartName: serviceObj ? serviceObj[res.serverPartId] : "",
|
||||||
serverPartId: res.serverPartId,
|
serverPartId: res.serverPartId,
|
||||||
@ -380,58 +485,64 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
status: res.status,
|
status: res.status,
|
||||||
description: res.description
|
description: res.description
|
||||||
}
|
}
|
||||||
|
console.log('req', req);
|
||||||
data = await handleUpdateTemplates(req)
|
data = await handleUpdateTemplates(req)
|
||||||
} else {
|
} else {
|
||||||
let questions: any = []
|
let questions: any = []
|
||||||
if (selectedQuestionDetail && selectedQuestionDetail.length > 0) {
|
if (selectedQuestionDetail && selectedQuestionDetail.length > 0) {
|
||||||
selectedQuestionDetail.forEach((item) => {
|
selectedQuestionDetail.forEach((item: any, index: number) => {
|
||||||
questions.push({
|
questions.push({
|
||||||
questionId: item.id,
|
questionId: item.id,
|
||||||
isRequired: item.required,
|
isRequired: item.required,
|
||||||
sortOrder: item.sortOrder
|
sortOrder: index + 1
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
req = {
|
req = {
|
||||||
title: res.title,
|
title: res.title,
|
||||||
|
deadlineType: res.deadlineType,
|
||||||
|
deadlineFrequency: res.deadlineFrequency,
|
||||||
placeName: "",
|
placeName: "",
|
||||||
placeId: 0,
|
placeId: 0,
|
||||||
serverPartName: serviceObj ? serviceObj[res.serverPartId] : "",
|
serverPartName: serviceObj ? serviceObj[res.serverPartId] : "",
|
||||||
serverPartId: res.serverPartId,
|
serverPartId: res.serverPartId,
|
||||||
// qrUrl: "",
|
// qrUrl: "",
|
||||||
questions: questions && questions.length > 0 ? questions : "",
|
questions: questions && questions.length > 0 ? questions : [],
|
||||||
operator: currentUser?.operator,
|
operator: currentUser?.operator,
|
||||||
status: res.status,
|
status: res.status,
|
||||||
description: res.description
|
description: res.description
|
||||||
}
|
}
|
||||||
|
console.log('reqreqreqreqreq', req);
|
||||||
data = await handleAddTemplates(req)
|
data = await handleAddTemplates(req)
|
||||||
console.log('datadsadsa1', data.data);
|
console.log('datadsadsa1', data);
|
||||||
const myQRCodeDataUrl = await QRCode.toDataURL(`pages/walkAroundManager/index?id=${data.data.id}`);
|
|
||||||
const file = base64ToFile(myQRCodeDataUrl, `wenjuan${data.data.id}.png`);
|
const myQRCodeDataUrl = await QRCode.toDataURL(`pages/walkAroundManager/index?id=${data.Result_Data.id}`);
|
||||||
|
const file = base64ToFile(myQRCodeDataUrl, `wenjuan${data.Result_Data.id}.png`);
|
||||||
console.log('file', file);
|
console.log('file', file);
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("file", file, `wenjuan${data.data.id}.png`); // 确保文件名也传递
|
formData.append("file", file, `wenjuan${data.Result_Data.id}.png`); // 确保文件名也传递
|
||||||
|
|
||||||
const fileData = await handleUploadFile(formData)
|
const fileData = await handleUploadFile(formData)
|
||||||
console.log('fileData', fileData);
|
console.log('fileData', fileData);
|
||||||
let imgUrl: string = `https://es.robot-z.cn/${fileData.data.path}`
|
let imgUrl: string = `https://es.eshangtech.com/${fileData.data.path}`
|
||||||
await handleUpdateTemplates({
|
await handleUpdateTemplates({
|
||||||
...data.data,
|
...data.Result_Data,
|
||||||
qrUrl: imgUrl
|
qrUrl: imgUrl
|
||||||
})
|
})
|
||||||
setQrCodeUrl(imgUrl)
|
setQrCodeUrl(imgUrl)
|
||||||
|
|
||||||
// setQrCodeUrl(myQRCodeDataUrl)
|
// setQrCodeUrl(myQRCodeDataUrl)
|
||||||
}
|
}
|
||||||
console.log('datadsadsa', data);
|
console.log('datadsadsa', data);
|
||||||
if (data.code === 200) {
|
if (data.Result_Code === 100) {
|
||||||
modalRef.current?.resetFields()
|
modalRef.current?.resetFields()
|
||||||
message.success(data.message)
|
message.success('新增成功!')
|
||||||
setShowPlaceModal(false)
|
setShowPlaceModal(false)
|
||||||
actionRef.current?.reload()
|
actionRef.current?.reload()
|
||||||
setCurrentRow(undefined)
|
setCurrentRow(undefined)
|
||||||
} else {
|
} else {
|
||||||
message.error(data.message)
|
message.error(data.Result_Desc)
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
@ -443,37 +554,58 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
setQrCodeUrl(undefined)
|
setQrCodeUrl(undefined)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ProForm formRef={modalRef} submitter={false} request={() => {
|
<ProForm formRef={modalRef} submitter={false} request={async () => {
|
||||||
console.log('currentRow', currentRow);
|
console.log('currentRow', currentRow);
|
||||||
|
|
||||||
let questionsList: any = []
|
let questionsList: any = []
|
||||||
let keyList: any = []
|
let keyList: any = []
|
||||||
if (currentRow?.questionnaireTemplateQuestions && currentRow?.questionnaireTemplateQuestions.length > 0) {
|
if (currentRow?.questionnaireTemplateQuestions && currentRow?.questionnaireTemplateQuestions.length > 0) {
|
||||||
console.log('1');
|
currentRow?.questionnaireTemplateQuestions.forEach((item: any) => {
|
||||||
|
|
||||||
currentRow?.questionnaireTemplateQuestions.forEach((item) => {
|
|
||||||
console.log('2');
|
|
||||||
if (item.question) {
|
if (item.question) {
|
||||||
let obj = JSON.parse(JSON.stringify(item.question))
|
let obj = JSON.parse(JSON.stringify(item.question))
|
||||||
|
|
||||||
let str: string = ''
|
// let str: string = ''
|
||||||
if (obj.options && obj?.options.length > 0) {
|
// if (obj.options && obj?.options.length > 0) {
|
||||||
obj.options.forEach((subItem: any, index: number) => {
|
// obj.options.forEach((subItem: any, index: number) => {
|
||||||
str += `${index > 0 ? ',' : ''}选项${index + 1}:${subItem.text}`
|
// str += `${index > 0 ? ',' : ''}选项${index + 1}:${subItem.text}`
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
|
// obj.text = obj.title
|
||||||
|
// obj.mark = JSON.stringify(obj.options)
|
||||||
|
// obj.showText = str
|
||||||
|
keyList.push(obj.id)
|
||||||
|
// questionsList.push(obj)
|
||||||
|
|
||||||
|
|
||||||
|
let markStr: string = JSON.stringify(item.question.options)
|
||||||
|
let showText: string = ''
|
||||||
|
if (item.question.options && item.question.options.length > 0) {
|
||||||
|
item.question.options.forEach((subItem: any, subIndex: number) => {
|
||||||
|
if (showText) {
|
||||||
|
showText += `,选项${subIndex + 1}:${subItem.text}`
|
||||||
|
} else {
|
||||||
|
showText = `选项${subIndex + 1}:${subItem.text}`
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.text = obj.title
|
questionsList.push({
|
||||||
obj.mark = JSON.stringify(obj.options)
|
questionId: item.questionId,
|
||||||
obj.showText = str
|
isRequired: item.isRequired,
|
||||||
keyList.push(obj.id)
|
sortOrder: item.sortOrder,
|
||||||
questionsList.push(obj)
|
text: item.question.title,
|
||||||
|
mark: markStr,
|
||||||
|
showText: showText
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// setSelectedQuestionDetail
|
|
||||||
setSelectedQuestionId(keyList)
|
setSelectedQuestionId(keyList)
|
||||||
|
console.log('questionsList', questionsList);
|
||||||
return {
|
return {
|
||||||
...currentRow,
|
...currentRow,
|
||||||
serverPartId: currentRow.serverPartId.toString(),
|
serverPartId: currentRow.serverPartId.toString(),
|
||||||
@ -497,6 +629,7 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
obj[item.value] = item.label
|
obj[item.value] = item.label
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
setAllServiceList(data)
|
||||||
setServiceObj(obj)
|
setServiceObj(obj)
|
||||||
return data
|
return data
|
||||||
}}
|
}}
|
||||||
@ -520,13 +653,38 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
}]}
|
}]}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={8}>
|
<Col span={4}>
|
||||||
<ProFormSwitch
|
<ProFormSwitch
|
||||||
label={"有效状态"}
|
label={"有效状态"}
|
||||||
name={"status"}
|
name={"status"}
|
||||||
initialValue={currentRow?.id ? currentRow.status : true}
|
initialValue={currentRow?.id ? currentRow.status : true}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
|
<Col span={4}>
|
||||||
|
<Button type="primary" onClick={() => {
|
||||||
|
handleShowCloneModal(true)
|
||||||
|
}}>克隆点位</Button>
|
||||||
|
</Col>
|
||||||
|
|
||||||
|
<Col span={8}>
|
||||||
|
<ProFormSelect
|
||||||
|
label={"任务时限类型"}
|
||||||
|
name={"deadlineType"}
|
||||||
|
options={[
|
||||||
|
{ label: "每日任务", value: 1 },
|
||||||
|
{ label: "每月任务", value: 2 }
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<ProFormDigit
|
||||||
|
label={"巡查频次"}
|
||||||
|
name={"deadlineFrequency"}
|
||||||
|
initialValue={1}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
<Col span={8}></Col>
|
||||||
|
|
||||||
<Col span={20}>
|
<Col span={20}>
|
||||||
<ProFormList
|
<ProFormList
|
||||||
name="questions"
|
name="questions"
|
||||||
@ -535,20 +693,90 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
creatorButtonProps={{
|
creatorButtonProps={{
|
||||||
position: 'bottom',
|
position: 'bottom',
|
||||||
creatorButtonText: '添加选项',
|
creatorButtonText: '添加选项',
|
||||||
style: { display: 'none' },
|
style: { display: 'none' }
|
||||||
onClick: (e) => {
|
|
||||||
console.log('e', e);
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
copyIconProps={false}
|
copyIconProps={false}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
itemContainerStyle={{ width: '100%' }}
|
itemContainerStyle={{ width: '100%' }}
|
||||||
itemRender={({ listDom, action }, { record, index }) => (
|
itemRender={({ listDom, action }, { record, index, move }) => {
|
||||||
<div style={{ width: '100%', display: 'flex', alignItems: 'flex-start', marginBottom: '10px' }}>
|
// console.log('modalRef', modalRef);
|
||||||
<div style={{ flex: 1, width: '100%' }}>{listDom}</div>
|
// let list: any = modalRef?.current?.getFieldValue("questions") || []
|
||||||
<div style={{ marginLeft: '8px', marginTop: '30px' }}>{action}</div>
|
// console.log('newidas2', list);
|
||||||
</div>
|
return (
|
||||||
)}
|
<div style={{
|
||||||
|
width: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'flex-start',
|
||||||
|
marginBottom: '10px',
|
||||||
|
padding: '12px',
|
||||||
|
backgroundColor: '#fafafa',
|
||||||
|
borderRadius: '4px'
|
||||||
|
}}>
|
||||||
|
<div style={{ flex: 1, width: '100%' }}>{listDom}</div>
|
||||||
|
<div style={{
|
||||||
|
marginLeft: '8px',
|
||||||
|
display: 'flex',
|
||||||
|
gap: '8px'
|
||||||
|
}}>
|
||||||
|
{/* 上移按钮 */}
|
||||||
|
<Button
|
||||||
|
icon={<ArrowUpOutlined />}
|
||||||
|
disabled={index === 0}
|
||||||
|
onClick={() => {
|
||||||
|
const currentList = modalRef?.current?.getFieldValue("questions") || []
|
||||||
|
console.log('currentList', currentList);
|
||||||
|
|
||||||
|
if (index > 0) {
|
||||||
|
// 交换位置
|
||||||
|
[currentList[index], currentList[index - 1]] =
|
||||||
|
[currentList[index - 1], currentList[index]];
|
||||||
|
// 更新 sortOrder
|
||||||
|
currentList.forEach((item, i) => {
|
||||||
|
item.sortOrder = i + 1;
|
||||||
|
});
|
||||||
|
console.log('currentList', currentList);
|
||||||
|
|
||||||
|
modalRef.current?.setFieldsValue({
|
||||||
|
questions: currentList
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* 下移按钮 */}
|
||||||
|
<Button
|
||||||
|
icon={<ArrowDownOutlined />}
|
||||||
|
disabled={index === currentRow?.questionnaireTemplateQuestions.length - 1}
|
||||||
|
onClick={() => {
|
||||||
|
const currentList = modalRef?.current?.getFieldValue("questions") || []
|
||||||
|
if (index < currentList.length - 1) {
|
||||||
|
// 交换位置
|
||||||
|
[currentList[index], currentList[index + 1]] =
|
||||||
|
[currentList[index + 1], currentList[index]];
|
||||||
|
// 更新 sortOrder
|
||||||
|
currentList.forEach((item, i) => {
|
||||||
|
item.sortOrder = i + 1;
|
||||||
|
});
|
||||||
|
modalRef.current?.setFieldsValue({
|
||||||
|
questions: currentList
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* 删除按钮(保留原有) */}
|
||||||
|
{action}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
|
||||||
|
// itemRender={({ listDom, action }, { record, index }) => (
|
||||||
|
// <div style={{ width: '100%', display: 'flex', alignItems: 'flex-start', marginBottom: '10px' }}>
|
||||||
|
// <div style={{ flex: 1, width: '100%' }}>{listDom}</div>
|
||||||
|
// <div style={{ marginLeft: '8px', marginTop: '30px' }}>{action}</div>
|
||||||
|
// </div>
|
||||||
|
// )}
|
||||||
>
|
>
|
||||||
<Row gutter={6} style={{ width: '100%', margin: 0 }}>
|
<Row gutter={6} style={{ width: '100%', margin: 0 }}>
|
||||||
<Col span={8}>
|
<Col span={8}>
|
||||||
@ -603,6 +831,7 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
width={1400}
|
width={1400}
|
||||||
title={`点位`}
|
title={`点位`}
|
||||||
open={selectQuestionModal}
|
open={selectQuestionModal}
|
||||||
|
|
||||||
destroyOnClose
|
destroyOnClose
|
||||||
onOk={() => {
|
onOk={() => {
|
||||||
console.log('selectedQuestionDetail', selectedQuestionDetail);
|
console.log('selectedQuestionDetail', selectedQuestionDetail);
|
||||||
@ -619,6 +848,8 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
showQuestion.push({ text: item.title, showText: str, mark: item.options ? JSON.stringify(item.options) : "" })
|
showQuestion.push({ text: item.title, showText: str, mark: item.options ? JSON.stringify(item.options) : "" })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
console.log('showQuestion', showQuestion);
|
||||||
|
|
||||||
modalRef.current?.setFieldsValue({
|
modalRef.current?.setFieldsValue({
|
||||||
questions: showQuestion
|
questions: showQuestion
|
||||||
})
|
})
|
||||||
@ -632,7 +863,9 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
actionRef={modalActionRef}
|
actionRef={modalActionRef}
|
||||||
formRef={modalFormRef}
|
formRef={modalFormRef}
|
||||||
columns={modalColumns}
|
columns={modalColumns}
|
||||||
rowKey={"id"}
|
rowKey={(record) => {
|
||||||
|
return `${record?.id}`
|
||||||
|
}}
|
||||||
scroll={{ y: 'calc(100vh - 500px)' }}
|
scroll={{ y: 'calc(100vh - 500px)' }}
|
||||||
request={async (params) => {
|
request={async (params) => {
|
||||||
console.log('查询参数:', params);
|
console.log('查询参数:', params);
|
||||||
@ -654,11 +887,184 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
setSelectedQuestionId(selectedRowKeys)
|
setSelectedQuestionId(selectedRowKeys)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
toolbar={{
|
||||||
|
actions: [
|
||||||
|
<Button type="primary" onClick={(e) => {
|
||||||
|
setOpenAddBigType(true)
|
||||||
|
}}>
|
||||||
|
新增分类
|
||||||
|
</Button>,
|
||||||
|
<Button type="primary" onClick={(e) => {
|
||||||
|
setOpenAddQuestion(true)
|
||||||
|
}}>
|
||||||
|
新增问题
|
||||||
|
</Button>
|
||||||
|
]
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
width={1500}
|
||||||
|
title={'克隆点位'}
|
||||||
|
open={showCloneModal}
|
||||||
|
destroyOnClose
|
||||||
|
onOk={() => {
|
||||||
|
console.log('selectedCloneId', selectedCloneId);
|
||||||
|
console.log('selectedCloneDetail', selectedCloneDetail);
|
||||||
|
if (selectedCloneDetail && selectedCloneDetail.length > 0) {
|
||||||
|
let res: any = []
|
||||||
|
let detailList: any = []
|
||||||
|
let idList: any = []
|
||||||
|
let list: any = selectedCloneDetail[0].questionnaireTemplateQuestions
|
||||||
|
if (list && list.length > 0) {
|
||||||
|
list.forEach((item: any) => {
|
||||||
|
detailList.push(item)
|
||||||
|
idList.push(item.question.id.toString())
|
||||||
|
if (item.question) {
|
||||||
|
let obj = JSON.parse(JSON.stringify(item.question))
|
||||||
|
|
||||||
|
let str: string = ''
|
||||||
|
if (obj.options && obj?.options.length > 0) {
|
||||||
|
obj.options.forEach((subItem: any, index: number) => {
|
||||||
|
str += `${index > 0 ? ',' : ''}选项${index + 1}:${subItem.text}`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.text = obj.title
|
||||||
|
obj.mark = JSON.stringify(obj.options)
|
||||||
|
obj.showText = str
|
||||||
|
res.push(obj)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
setSelectedQuestionDetail(detailList)
|
||||||
|
console.log('idList', idList);
|
||||||
|
|
||||||
|
setSelectedQuestionId(idList)
|
||||||
|
|
||||||
|
modalRef.current?.setFieldsValue({
|
||||||
|
questions: res
|
||||||
|
})
|
||||||
|
handleShowCloneModal(false)
|
||||||
|
} else {
|
||||||
|
handleShowCloneModal(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
}}
|
||||||
|
onCancel={() => {
|
||||||
|
handleShowCloneModal(false)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
|
||||||
|
<ProTable
|
||||||
|
actionRef={cloneActionRef}
|
||||||
|
formRef={cloneFormRef}
|
||||||
|
rowKey={(record) => {
|
||||||
|
return `${record?.id}`
|
||||||
|
}}
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
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?.title
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: <div style={{ textAlign: 'center' }}>问题列表</div>,
|
||||||
|
dataIndex: "questions",
|
||||||
|
hideInSearch: true,
|
||||||
|
width: 400,
|
||||||
|
ellipsis: true,
|
||||||
|
render: (_, record) => {
|
||||||
|
let questionStr: string = ""
|
||||||
|
if (record?.questionnaireTemplateQuestions && record?.questionnaireTemplateQuestions.length > 0) {
|
||||||
|
record?.questionnaireTemplateQuestions.forEach((item: any, index: number) => {
|
||||||
|
let options: string = ''
|
||||||
|
if (item.question.options && item.question.options.length > 0) {
|
||||||
|
item.question.options.forEach((subItem: any, subIndex: number) => {
|
||||||
|
options += `${subItem.text};`
|
||||||
|
// ${subIndex > 0 ? ',' : ''} 选项${subIndex + 1}:
|
||||||
|
})
|
||||||
|
}
|
||||||
|
questionStr += `${index > 0 ? ',' : ''}问题:${item.question.title}。${options}`
|
||||||
|
// ${index + 1}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return questionStr || ''
|
||||||
|
// return record?.questions && record?.questions.length > 0 ? JSON.stringify(record?.questions) : ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
request={async (params) => {
|
||||||
|
let selectId: string[] = []
|
||||||
|
console.log('cloneFormRef', cloneFormRef);
|
||||||
|
console.log('params', params);
|
||||||
|
|
||||||
|
if (allServiceList && allServiceList.length > 0) {
|
||||||
|
allServiceList.forEach((item: any) => {
|
||||||
|
selectId.push(item.value)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
console.log('selectId', selectId);
|
||||||
|
const req: any = {
|
||||||
|
serverPartIds: selectId,
|
||||||
|
any: params?.serverPartName ? [
|
||||||
|
{
|
||||||
|
key: "serverPartName",
|
||||||
|
value: params?.serverPartName
|
||||||
|
}
|
||||||
|
] : undefined
|
||||||
|
}
|
||||||
|
const data = await handleSearchModalTree(req)
|
||||||
|
console.log('dasdsa', data);
|
||||||
|
let defaultRow: any = []
|
||||||
|
|
||||||
|
if (data && data.length > 0) {
|
||||||
|
data.forEach((item: any) => {
|
||||||
|
defaultRow.push(item.id.toString())
|
||||||
|
if (item.children && item.children.length > 0) {
|
||||||
|
item.children.forEach((subItem: any) => {
|
||||||
|
defaultRow.push(subItem.id.toString())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
console.log('defaultRow', defaultRow);
|
||||||
|
|
||||||
|
setDefaultExpandRow(defaultRow)
|
||||||
|
return { data, success: true }
|
||||||
|
}
|
||||||
|
setDefaultExpandRow(defaultRow)
|
||||||
|
return { data: [], success: true }
|
||||||
|
}}
|
||||||
|
expandable={{
|
||||||
|
expandedRowKeys: defaultExpandRow,
|
||||||
|
defaultExpandAllRows: true
|
||||||
|
}}
|
||||||
|
scroll={{ x: '100%', y: '500px' }}
|
||||||
|
rowSelection={{
|
||||||
|
type: "radio",
|
||||||
|
defaultSelectedRowKeys: selectedCloneId,
|
||||||
|
getCheckboxProps: (record) => ({
|
||||||
|
disabled: record.type === "district" || record.type === "servicePart",
|
||||||
|
}),
|
||||||
|
onChange: (selectedRowKeys, selectedRows) => {
|
||||||
|
setSelectedCloneDetail(selectedRows)
|
||||||
|
setSelectedCloneId(selectedRowKeys)
|
||||||
|
}
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<Drawer
|
<Drawer
|
||||||
title={false}
|
title={false}
|
||||||
closeIcon={false}
|
closeIcon={false}
|
||||||
@ -671,6 +1077,121 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
>
|
>
|
||||||
<RecordDetail parentRow={currentRow} show={showDetail} detailType={'modal'} />
|
<RecordDetail parentRow={currentRow} show={showDetail} detailType={'modal'} />
|
||||||
</Drawer>
|
</Drawer>
|
||||||
|
|
||||||
|
|
||||||
|
<AddBigType openAddModal={openAddBigType} setOpenAddModal={setOpenAddBigType} afterAdd={handleReloadSearchList} />
|
||||||
|
|
||||||
|
<AddQuestion showQuestionModal={openAddQuestion} setShowQuestionModal={setOpenAddQuestion} afterAdd={handleReloadSearchList} />
|
||||||
|
|
||||||
|
{/* 批量克隆点位 */}
|
||||||
|
<Modal
|
||||||
|
width={400}
|
||||||
|
title={"批量克隆"}
|
||||||
|
open={showBatchCloneModal}
|
||||||
|
confirmLoading={batchLoading}
|
||||||
|
onOk={() => {
|
||||||
|
batchCloneForm.current?.validateFields().then(async (res: any) => {
|
||||||
|
console.log('res', res);
|
||||||
|
console.log('currentRow', currentRow);
|
||||||
|
console.log('currentUser', currentUser);
|
||||||
|
console.log('serviceObj', serviceObj);
|
||||||
|
|
||||||
|
|
||||||
|
let list: any = res.serviceList
|
||||||
|
let serverParts: any = []
|
||||||
|
if (list && list.length > 0) {
|
||||||
|
list.forEach((item: any) => {
|
||||||
|
serverParts.push({
|
||||||
|
serverPartName: serviceObj[item],
|
||||||
|
serverPartId: item
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let question: any = []
|
||||||
|
if (currentRow?.questionnaireTemplateQuestions && currentRow?.questionnaireTemplateQuestions.length > 0) {
|
||||||
|
currentRow.questionnaireTemplateQuestions.forEach((item: any) => {
|
||||||
|
question.push({
|
||||||
|
questionId: item.questionId,
|
||||||
|
isRequired: item.isRequired,
|
||||||
|
sortOrder: item.sortOrder
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let req: any = {
|
||||||
|
title: currentRow?.title,
|
||||||
|
placeName: currentRow?.placeName,
|
||||||
|
placeId: currentRow?.placeId,
|
||||||
|
serverParts: serverParts,
|
||||||
|
questions: question,
|
||||||
|
operator: currentUser?.operator,
|
||||||
|
status: currentRow?.status,
|
||||||
|
description: currentRow?.description
|
||||||
|
}
|
||||||
|
console.log('req', req);
|
||||||
|
const data = await handleBatchService(req)
|
||||||
|
console.log('datadatadatadata', data);
|
||||||
|
if (data.Result_Code === 100) {
|
||||||
|
message.success('批量克隆成功!')
|
||||||
|
actionRef.current?.reload()
|
||||||
|
batchCloneForm.current?.resetFields()
|
||||||
|
setshowBatchCloneModal(false)
|
||||||
|
setCurrentRow(undefined)
|
||||||
|
} else {
|
||||||
|
message.error(data.Result_Desc)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// setshowBatchCloneModal(false)
|
||||||
|
}}
|
||||||
|
onCancel={() => {
|
||||||
|
setshowBatchCloneModal(false)
|
||||||
|
batchCloneForm.current?.resetFields()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProForm
|
||||||
|
formRef={batchCloneForm}
|
||||||
|
submitter={false}
|
||||||
|
>
|
||||||
|
<Row>
|
||||||
|
<Col span={24}>
|
||||||
|
<ProFormSelect
|
||||||
|
label={"服务区"}
|
||||||
|
name={"serviceList"}
|
||||||
|
fieldProps={{
|
||||||
|
mode: "multiple",
|
||||||
|
showSearch: true,
|
||||||
|
filterOption: (input, option) => {
|
||||||
|
return (option?.label ?? '').toLowerCase().includes(input.toLowerCase());
|
||||||
|
},
|
||||||
|
optionFilterProp: "label"
|
||||||
|
}}
|
||||||
|
request={async () => {
|
||||||
|
const req = {
|
||||||
|
ProvinceCode: currentUser?.provinceCode,
|
||||||
|
StatisticsType: 1000
|
||||||
|
}
|
||||||
|
const data = await handleGetServerpartDDL(req)
|
||||||
|
let obj: any = {}
|
||||||
|
if (data && data.length > 0) {
|
||||||
|
data.forEach((item: any) => {
|
||||||
|
obj[item.value] = item.label
|
||||||
|
})
|
||||||
|
}
|
||||||
|
setAllServiceList(data)
|
||||||
|
setServiceObj(obj)
|
||||||
|
return data
|
||||||
|
}}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: "请选择目标服务区"
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</ProForm>
|
||||||
|
</Modal>
|
||||||
</div >
|
</div >
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,45 +1,61 @@
|
|||||||
import requestOld from "@/utils/requestOld"
|
import requestOld from "@/utils/requestOld"
|
||||||
import request from "@/utils/request"
|
// import request from "@/utils/request"
|
||||||
|
import requestNode from "@/utils/request"
|
||||||
|
import request from "@/utils/requestJava"
|
||||||
|
|
||||||
// 拿到模版id列表 去绑定服务区的多个站点信息 的列表接口
|
// 拿到模版id列表 去绑定服务区的多个站点信息 的列表接口
|
||||||
export async function handleGetTemplatesList(params?: any) {
|
export async function handleGetTemplatesList(params?: any) {
|
||||||
const data = await request.get('/questionnaire-templates', {params})
|
const data = await request.get('/questionnaire-templates', { params })
|
||||||
if (data.code === 200) {
|
if (data.Result_Code === 200) {
|
||||||
return data.data
|
return data.Result_Data.List
|
||||||
}
|
}
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新建模版
|
// 新建模版
|
||||||
export async function handleAddTemplates(params?: any) {
|
export async function handleAddTemplates(params?: any) {
|
||||||
const data = await request.post('/questionnaire-templates', params)
|
const data = await request.post('/questionnaire-templates/save', params)
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新模版
|
// 更新模版
|
||||||
export async function handleUpdateTemplates(params?: any) {
|
export async function handleUpdateTemplates(params?: any) {
|
||||||
const data = await request.post(`/questionnaire-templates/${params.id}`, params)
|
const data = await request.post(`/questionnaire-templates/update`, params)
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除模版
|
// 删除模版
|
||||||
export async function handleDeleteTemplates(params?: any) {
|
export async function handleDeleteTemplates(params?: any) {
|
||||||
const data = await request.get(`/questionnaire-templates/delete/${params.id}`)
|
const data = await request.get(`/questionnaire-templates/delete`, { params })
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export async function handleGetQuestionList(params?: any) {
|
export async function handleGetQuestionList(params?: any) {
|
||||||
const data = await request.get(`/questions?categoryId=${params.categoryId}`,)
|
const data = await request.get('/questions/getList', params)
|
||||||
if (data.code === 200) {
|
if (data.Result_Code === 100) {
|
||||||
return data.data
|
return data.Result_Data.List
|
||||||
}
|
}
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
// 上传图片的oss接口
|
// 上传图片的oss接口
|
||||||
export async function handleUploadFile(params?: any) {
|
export async function handleUploadFile(params?: any) {
|
||||||
const data = await request.post(`/oss/upload`, params)
|
const data = await requestNode.post(`/oss/upload`, params)
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模版树的查询
|
||||||
|
export async function handleSearchModalTree(params?: any) {
|
||||||
|
const data = await request.post(`/questionnaire-templates/search/tree`, params)
|
||||||
|
if (data.Result_Code === 100) {
|
||||||
|
return data.Result_Data.List
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量克隆服务区
|
||||||
|
export async function handleBatchService(params?: any) {
|
||||||
|
const data = await request.post(`/questionnaire-templates/batchSave`, params)
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
252
src/pages/examine/question/components/addQuestion.tsx
Normal file
252
src/pages/examine/question/components/addQuestion.tsx
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
import { ConnectState } from "@/models/global";
|
||||||
|
import { FormInstance, ProForm, ProFormDigit, ProFormList, ProFormRadio, ProFormSwitch, ProFormText, ProFormTextArea, ProFormTreeSelect } from "@ant-design/pro-components";
|
||||||
|
import { useImperativeHandle, useRef, useState } from "react";
|
||||||
|
import { connect } from "umi";
|
||||||
|
import { Col, message, Modal, Row } from "antd";
|
||||||
|
import { handleGetExamineTypeList, handleGetExamineTypeTreeList } from "../../index/service";
|
||||||
|
import { handleAddQuestion, handleEditQuestion } from "../service";
|
||||||
|
|
||||||
|
|
||||||
|
type DetailProps = {
|
||||||
|
parentRow: any
|
||||||
|
onRef: any
|
||||||
|
currentUser?: any
|
||||||
|
showQuestionModal: boolean
|
||||||
|
setShowQuestionModal?: any
|
||||||
|
parentActionRef?: any
|
||||||
|
setCurrentRow?: any
|
||||||
|
afterAdd?: any
|
||||||
|
}
|
||||||
|
const addQuestion = ({ parentRow, onRef, currentUser, showQuestionModal, setShowQuestionModal, parentActionRef, setCurrentRow, afterAdd }: DetailProps) => {
|
||||||
|
|
||||||
|
// 弹出框的表单实例
|
||||||
|
const modalRef = useRef<FormInstance>()
|
||||||
|
const [categoryIdObj, setCategoryIdObj] = useState<any>()
|
||||||
|
|
||||||
|
|
||||||
|
useImperativeHandle(onRef, () => ({
|
||||||
|
modalRef,
|
||||||
|
categoryIdObj
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Modal
|
||||||
|
width={800}
|
||||||
|
title={`${parentRow?.id ? '编辑' : '创建'}问题`}
|
||||||
|
open={showQuestionModal}
|
||||||
|
destroyOnClose
|
||||||
|
onOk={() => {
|
||||||
|
modalRef.current?.validateFields().then(async (res) => {
|
||||||
|
let req = {}
|
||||||
|
let data = {}
|
||||||
|
if (parentRow?.id) {
|
||||||
|
req = {
|
||||||
|
...parentRow,
|
||||||
|
categoryId: res.categoryId,// 题目id
|
||||||
|
type: `${res.selectType === 1 ? 'radio' : 'checked'}_choice`,// 题目类型
|
||||||
|
title: res.title,// 问题内容
|
||||||
|
required: res.required,// 是否必填
|
||||||
|
options: res.options,
|
||||||
|
status: res.status,
|
||||||
|
operator: currentUser?.operator,
|
||||||
|
description: `${res.categoryId && categoryIdObj ? categoryIdObj[res.categoryId] : ''}`,
|
||||||
|
category: undefined
|
||||||
|
}
|
||||||
|
console.log('req', req);
|
||||||
|
|
||||||
|
data = await handleEditQuestion(req)
|
||||||
|
} else {
|
||||||
|
req = {
|
||||||
|
categoryId: res.categoryId,// 题目id
|
||||||
|
type: `${res.selectType === 1 ? 'radio' : 'checked'}_choice`,// 题目类型
|
||||||
|
title: res.title,// 问题内容
|
||||||
|
required: res.required,// 是否必填
|
||||||
|
options: res.options,
|
||||||
|
sortOrder: 1,
|
||||||
|
status: res.status,
|
||||||
|
operator: currentUser?.operator,
|
||||||
|
defaultScore: 0,
|
||||||
|
images: [],
|
||||||
|
description: `${res.categoryId && categoryIdObj ? categoryIdObj[res.categoryId] : ''}`
|
||||||
|
}
|
||||||
|
data = await handleAddQuestion(req)
|
||||||
|
}
|
||||||
|
console.log('datadsadsa', data);
|
||||||
|
if (data.Result_Code === 100) {
|
||||||
|
if (modalRef) {
|
||||||
|
modalRef.current?.resetFields()
|
||||||
|
}
|
||||||
|
message.success(data.Result_Desc)
|
||||||
|
setShowQuestionModal(false)
|
||||||
|
if (parentActionRef) {
|
||||||
|
parentActionRef.current?.reload()
|
||||||
|
}
|
||||||
|
if (setCurrentRow) {
|
||||||
|
setCurrentRow(undefined)
|
||||||
|
}
|
||||||
|
if (afterAdd) {
|
||||||
|
afterAdd()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
message.error(data.Result_Desc)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
}}
|
||||||
|
onCancel={() => {
|
||||||
|
if (modalRef) {
|
||||||
|
modalRef.current?.resetFields()
|
||||||
|
}
|
||||||
|
setShowQuestionModal(false)
|
||||||
|
if (setCurrentRow) {
|
||||||
|
setCurrentRow(undefined)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProForm formRef={modalRef} submitter={false} request={() => {
|
||||||
|
console.log('currentRow', parentRow);
|
||||||
|
return {
|
||||||
|
...parentRow,
|
||||||
|
selectType: parentRow.type.split('_')[0] === 'checked' ? 2 : 1
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
<Row gutter={8}>
|
||||||
|
<Col span={12}>
|
||||||
|
<ProFormTreeSelect
|
||||||
|
label={"问题分类"}
|
||||||
|
name={"categoryId"}
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: '请选择问题分类!' }
|
||||||
|
]}
|
||||||
|
request={async () => {
|
||||||
|
|
||||||
|
|
||||||
|
const req = {}
|
||||||
|
const data = await handleGetExamineTypeTreeList(req)
|
||||||
|
console.log('dsadas', data);
|
||||||
|
let res = [
|
||||||
|
{
|
||||||
|
name: '/',
|
||||||
|
id: 0,
|
||||||
|
children: data
|
||||||
|
}
|
||||||
|
]
|
||||||
|
let obj: any = {}
|
||||||
|
const labelList = await handleGetExamineTypeList()
|
||||||
|
if (labelList && labelList.length > 0) {
|
||||||
|
labelList.forEach((item: any) => {
|
||||||
|
obj[item.id] = item.name
|
||||||
|
})
|
||||||
|
}
|
||||||
|
console.log('objobjobjobj', obj);
|
||||||
|
|
||||||
|
setCategoryIdObj(obj)
|
||||||
|
return data
|
||||||
|
}}
|
||||||
|
fieldProps={{
|
||||||
|
treeDefaultExpandAll: true,
|
||||||
|
// treeDefaultExpandedKeys: [0],
|
||||||
|
fieldNames: {
|
||||||
|
label: "name",
|
||||||
|
value: "id"
|
||||||
|
},
|
||||||
|
showSearch: true,
|
||||||
|
filterTreeNode: (input, treeNode) => {
|
||||||
|
return (treeNode?.name ?? '').toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
||||||
|
},
|
||||||
|
treeNodeFilterProp: 'name'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<ProFormText
|
||||||
|
label={"问题内容"}
|
||||||
|
name={"title"}
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: '请输入问题!' }
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
|
||||||
|
<Col span={6}>
|
||||||
|
<ProFormSwitch
|
||||||
|
label={"是否必填"}
|
||||||
|
name={"required"}
|
||||||
|
initialValue={parentRow?.id ? parentRow.required : true}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
<Col span={6}>
|
||||||
|
<ProFormSwitch
|
||||||
|
label={"有效状态"}
|
||||||
|
name={"status"}
|
||||||
|
initialValue={parentRow?.id ? parentRow.status : true}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
<Col span={6}>
|
||||||
|
<ProFormRadio.Group
|
||||||
|
label={"题目类型"}
|
||||||
|
name={"selectType"}
|
||||||
|
fieldProps={{
|
||||||
|
options: [{ label: "单选", value: 1 }, { label: "多选", value: 2 }],
|
||||||
|
}}
|
||||||
|
initialValue={1}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
<Col span={24}>
|
||||||
|
<ProFormList
|
||||||
|
name="options"
|
||||||
|
label="选项内容"
|
||||||
|
initialValue={[]}
|
||||||
|
creatorButtonProps={{
|
||||||
|
position: 'bottom',
|
||||||
|
creatorButtonText: '添加选项'
|
||||||
|
}}
|
||||||
|
copyIconProps={false}
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
itemContainerStyle={{ width: '100%' }}
|
||||||
|
itemRender={({ listDom, action }, { record, index }) => (
|
||||||
|
<div style={{ width: '100%', display: 'flex', alignItems: 'flex-start', marginBottom: '10px' }}>
|
||||||
|
<div style={{ flex: 1, width: '100%' }}>{listDom}</div>
|
||||||
|
<div style={{ marginLeft: '8px', marginTop: '30px' }}>{action}</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Row gutter={6} style={{ width: '100%', margin: 0 }}>
|
||||||
|
<Col span={16}>
|
||||||
|
<ProFormTextArea
|
||||||
|
name="text"
|
||||||
|
label="选项"
|
||||||
|
fieldProps={{
|
||||||
|
style: { width: '100%' }
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<ProFormDigit
|
||||||
|
name="mark"
|
||||||
|
label="分值"
|
||||||
|
fieldProps={{
|
||||||
|
style: { width: '100%' },
|
||||||
|
defaultValue: 0
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</ProFormList>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</ProForm>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(({ user }: ConnectState) => ({
|
||||||
|
currentUser: user.data
|
||||||
|
}))(addQuestion);
|
||||||
@ -4,14 +4,17 @@ import { Button, Col, message, Modal, Popconfirm, Row, Space } from "antd";
|
|||||||
import { useRef, useState } from "react";
|
import { useRef, useState } from "react";
|
||||||
import { connect } from "umi";
|
import { connect } from "umi";
|
||||||
import { handleAddQuestion, handleDeleteQuestion, handleEditQuestion, handleGetQuestionList } from "./service";
|
import { handleAddQuestion, handleDeleteQuestion, handleEditQuestion, handleGetQuestionList } from "./service";
|
||||||
import { handleGetExamineTypeList, handleGetExamineTypeTreeList } from "../index/service";
|
import { handleGetAddExamineType, handleGetExamineTypeList, handleGetExamineTypeTreeList } from "../index/service";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
|
import AddQuestion from "./components/addQuestion";
|
||||||
|
|
||||||
const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
|
const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
|
||||||
const { currentUser } = props
|
const { currentUser } = props
|
||||||
|
|
||||||
const actionRef = useRef<ActionType>();
|
const actionRef = useRef<ActionType>();
|
||||||
const formRef = useRef<FormInstance>();
|
const formRef = useRef<FormInstance>();
|
||||||
|
|
||||||
|
const addQuestionRef = useRef<any>()
|
||||||
// 显示新增问题的悬浮框
|
// 显示新增问题的悬浮框
|
||||||
const [showQuestionModal, setShowQuestionModal] = useState<boolean>(false)
|
const [showQuestionModal, setShowQuestionModal] = useState<boolean>(false)
|
||||||
// 当前点击选中的问题行
|
// 当前点击选中的问题行
|
||||||
@ -23,10 +26,35 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
const [columnsStateMap, setColumnsStateMap] = useState<any>({
|
const [columnsStateMap, setColumnsStateMap] = useState<any>({
|
||||||
createdAt: { show: false }
|
createdAt: { show: false }
|
||||||
})
|
})
|
||||||
|
// 拿到protable的问题分类
|
||||||
|
const [bigTypeList, setBigTypeList] = useState<any>()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const columns: any = [
|
const columns: any = [
|
||||||
|
{
|
||||||
|
title: "问题内容",
|
||||||
|
dataIndex: "title",
|
||||||
|
hideInTable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "问题分类",
|
||||||
|
dataIndex: "id",
|
||||||
|
hideInTable: true,
|
||||||
|
valueType: 'treeSelect',
|
||||||
|
fieldProps: {
|
||||||
|
multiple: false,
|
||||||
|
treeDefaultExpandAll: true,
|
||||||
|
showSearch: true,
|
||||||
|
treeNodeFilterProp: 'title',
|
||||||
|
placeholder: '请选择问题分类',
|
||||||
|
fieldNames: {
|
||||||
|
label: "name",
|
||||||
|
value: "id"
|
||||||
|
},
|
||||||
|
options: bigTypeList || []
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: <div style={{ textAlign: 'center' }}>问题分类</div>,
|
title: <div style={{ textAlign: 'center' }}>问题分类</div>,
|
||||||
dataIndex: "description",
|
dataIndex: "description",
|
||||||
@ -50,7 +78,7 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
let questionType: string = record?.type && record?.type.split('_') && record?.type.split('_').length > 0 ? record?.type.split('_')[0] : ''
|
let questionType: string = record?.type && record?.type.split('_') && record?.type.split('_').length > 0 ? record?.type.split('_')[0] : ''
|
||||||
return questionType === 'radio' ? '单选' : "多选"
|
return questionType === 'radio' ? '单选' : questionType === 'checked' ? "多选" : ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -61,7 +89,7 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
align: 'center',
|
align: 'center',
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
return record?.required ? '是' : "否"
|
return record?.isNoChildren ? record?.required ? '是' : "否" : ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -74,7 +102,7 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
let str: string = ''
|
let str: string = ''
|
||||||
if (record.options && record?.options.length > 0) {
|
if (record.options && record?.options.length > 0) {
|
||||||
record.options.forEach((item: any, index: number) => {
|
record.options.forEach((item: any, index: number) => {
|
||||||
str += `${index > 0 ? ',' : ''}选项${index + 1}:${item.text}`
|
str += `${item.text};`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return str || ''
|
return str || ''
|
||||||
@ -118,7 +146,7 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
hideInSearch: true,
|
hideInSearch: true,
|
||||||
width: 100,
|
width: 100,
|
||||||
render: (_: any, record: any) => {
|
render: (_: any, record: any) => {
|
||||||
return <Space>
|
return record?.isNoChildren ? <Space>
|
||||||
<a onClick={() => {
|
<a onClick={() => {
|
||||||
console.log('record', record);
|
console.log('record', record);
|
||||||
setCurrentRow(record)
|
setCurrentRow(record)
|
||||||
@ -132,8 +160,7 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
>
|
>
|
||||||
<a>删除</a>
|
<a>删除</a>
|
||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
|
</Space> : ""
|
||||||
</Space>
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -141,12 +168,87 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
// 删除分类
|
// 删除分类
|
||||||
const deleteQuestion = async (id: number) => {
|
const deleteQuestion = async (id: number) => {
|
||||||
const data = await handleDeleteQuestion({ id: id })
|
const data = await handleDeleteQuestion({ id: id })
|
||||||
if (data.code === 200) {
|
if (data.Result_Code === 100) {
|
||||||
message.success(data.message)
|
message.success('删除成功!')
|
||||||
actionRef.current?.reload()
|
actionRef.current?.reload()
|
||||||
|
} else {
|
||||||
|
message.error(data.Result_Desc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 递归 处理 将问题拼在列表的对应层 不一定是第二层
|
||||||
|
const handleGetNewQuestion = (typeList: any, list: any) => {
|
||||||
|
console.log('typeList', typeList);
|
||||||
|
console.log('list', list);
|
||||||
|
if (list && list.length > 0) {
|
||||||
|
list.forEach((item: any) => {
|
||||||
|
item.isNoChildren = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 递归查找并插入匹配项的函数
|
||||||
|
const findAndInsert = (nodes: any[], itemsToInsert: any[]) => {
|
||||||
|
for (const node of nodes) {
|
||||||
|
// 在当前节点的子节点中查找匹配
|
||||||
|
if (node.children) {
|
||||||
|
findAndInsert(node.children, itemsToInsert);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查当前节点是否匹配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) {
|
||||||
|
node.children = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将匹配到的项添加到children中
|
||||||
|
node.children.push(...matchedItems);
|
||||||
|
|
||||||
|
// 从待插入列表中移除已处理的项
|
||||||
|
itemsToInsert = itemsToInsert.filter(item => !matchedItems.includes(item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 创建list的副本以避免修改原数组
|
||||||
|
const itemsToInsert = [...list];
|
||||||
|
|
||||||
|
// 开始递归处理
|
||||||
|
findAndInsert(typeList, itemsToInsert);
|
||||||
|
return typeList
|
||||||
|
|
||||||
|
// let res: any = []
|
||||||
|
// if (typeList && typeList.length > 0) {
|
||||||
|
// typeList.forEach((item: any) => {
|
||||||
|
// if (item.children && item.children.length > 0) {
|
||||||
|
// let newRes = handleGetNewQuestion(item.children, list)
|
||||||
|
// item.children = newRes
|
||||||
|
// res.push(item)
|
||||||
|
// } else {
|
||||||
|
// if (list && list.length > 0) {
|
||||||
|
// list.forEach((subItem: any) => {
|
||||||
|
// if (subItem.categoryId === item.id) {
|
||||||
|
// if (item.children && item.children.length > 0) {
|
||||||
|
// subItem.isNoChildren = true
|
||||||
|
// item.children.push(subItem)
|
||||||
|
// } else {
|
||||||
|
// subItem.isNoChildren = true
|
||||||
|
// item.children = [subItem]
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// res.push(item)
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// return res
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div style={{
|
<div style={{
|
||||||
@ -165,13 +267,35 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
}}
|
}}
|
||||||
headerTitle={<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}>考核问题管理</span>}
|
headerTitle={<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}>考核问题管理</span>}
|
||||||
search={{ span: 6 }}
|
search={{ span: 6 }}
|
||||||
|
rowKey={(record: any) => {
|
||||||
|
return `${record?.id}-${record?.categoryId}`
|
||||||
|
}}
|
||||||
scroll={{ x: "100%", y: 'calc(100vh - 400px)' }}
|
scroll={{ x: "100%", y: 'calc(100vh - 400px)' }}
|
||||||
request={async (params) => {
|
request={async (params) => {
|
||||||
const data = await handleGetQuestionList()
|
console.log('params', params);
|
||||||
console.log('data', data);
|
|
||||||
|
|
||||||
if (data && data.length > 0) {
|
// 拿到分类数据 将 问题数据 拼到对应的分类下面去
|
||||||
return { data, success: true }
|
const typeReq = {
|
||||||
|
any: [{
|
||||||
|
"key": ""
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
|
let res = await handleGetNewQuestion(typeData, data)
|
||||||
|
console.log('res432423', res);
|
||||||
|
if (res && res.length > 0) {
|
||||||
|
return { data: res, success: true }
|
||||||
}
|
}
|
||||||
return { data: [], success: true }
|
return { data: [], success: true }
|
||||||
}}
|
}}
|
||||||
@ -191,196 +315,14 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<AddQuestion onRef={addQuestionRef} parentRow={currentRow}
|
||||||
<Modal
|
showQuestionModal={showQuestionModal}
|
||||||
width={800}
|
setShowQuestionModal={setShowQuestionModal}
|
||||||
title={`${currentRow?.id ? '编辑' : '创建'}问题`}
|
parentActionRef={actionRef}
|
||||||
open={showQuestionModal}
|
setCurrentRow={setCurrentRow}
|
||||||
destroyOnClose
|
/>
|
||||||
onOk={() => {
|
|
||||||
modalRef.current?.validateFields().then(async (res) => {
|
|
||||||
let req = {}
|
|
||||||
let data = {}
|
|
||||||
if (currentRow?.id) {
|
|
||||||
req = {
|
|
||||||
...currentRow,
|
|
||||||
categoryId: res.categoryId,// 题目id
|
|
||||||
type: `${res.selectType === 1 ? 'radio' : 'checked'}_choice`,// 题目类型
|
|
||||||
title: res.title,// 问题内容
|
|
||||||
required: res.required,// 是否必填
|
|
||||||
options: res.options,
|
|
||||||
status: res.status,
|
|
||||||
operator: currentUser?.operator,
|
|
||||||
description: `${res.categoryId ? categoryIdObj[res.categoryId] : ''}`
|
|
||||||
}
|
|
||||||
data = await handleEditQuestion(req)
|
|
||||||
} else {
|
|
||||||
req = {
|
|
||||||
categoryId: res.categoryId,// 题目id
|
|
||||||
type: `${res.selectType === 1 ? 'radio' : 'checked'}_choice`,// 题目类型
|
|
||||||
title: res.title,// 问题内容
|
|
||||||
required: res.required,// 是否必填
|
|
||||||
options: res.options,
|
|
||||||
sortOrder: 1,
|
|
||||||
status: res.status,
|
|
||||||
operator: currentUser?.operator,
|
|
||||||
defaultScore: 0,
|
|
||||||
images: [],
|
|
||||||
description: `${res.categoryId ? categoryIdObj[res.categoryId] : ''}`
|
|
||||||
}
|
|
||||||
data = await handleAddQuestion(req)
|
|
||||||
}
|
|
||||||
console.log('datadsadsa', data);
|
|
||||||
if (data.code === 200) {
|
|
||||||
modalRef.current?.resetFields()
|
|
||||||
message.success(data.message)
|
|
||||||
setShowQuestionModal(false)
|
|
||||||
actionRef.current?.reload()
|
|
||||||
setCurrentRow(undefined)
|
|
||||||
} else {
|
|
||||||
message.error(data.message)
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
}}
|
|
||||||
onCancel={() => {
|
|
||||||
modalRef.current?.resetFields()
|
|
||||||
setShowQuestionModal(false)
|
|
||||||
setCurrentRow(undefined)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ProForm formRef={modalRef} submitter={false} request={() => {
|
|
||||||
console.log('currentRow', currentRow);
|
|
||||||
return {
|
|
||||||
...currentRow,
|
|
||||||
selectType: currentRow.type.split('_')[0] === 'checked' ? 2 : 1
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
<Row gutter={8}>
|
|
||||||
<Col span={12}>
|
|
||||||
<ProFormTreeSelect
|
|
||||||
label={"问题分类"}
|
|
||||||
name={"categoryId"}
|
|
||||||
rules={[
|
|
||||||
{ required: true, message: '请选择问题分类!' }
|
|
||||||
]}
|
|
||||||
request={async () => {
|
|
||||||
|
|
||||||
|
|
||||||
const req = {}
|
|
||||||
const data = await handleGetExamineTypeTreeList(req)
|
|
||||||
console.log('dsadas', data);
|
|
||||||
let res = [
|
|
||||||
{
|
|
||||||
name: '/',
|
|
||||||
id: 0,
|
|
||||||
children: data
|
|
||||||
}
|
|
||||||
]
|
|
||||||
let obj: any = {}
|
|
||||||
const labelList = await handleGetExamineTypeList()
|
|
||||||
if (labelList && labelList.length > 0) {
|
|
||||||
labelList.forEach((item) => {
|
|
||||||
obj[item.id] = item.name
|
|
||||||
})
|
|
||||||
}
|
|
||||||
setCategoryIdObj(obj)
|
|
||||||
return res
|
|
||||||
}}
|
|
||||||
fieldProps={{
|
|
||||||
treeDefaultExpandedKeys: [0],
|
|
||||||
fieldNames: {
|
|
||||||
label: "name",
|
|
||||||
value: "id"
|
|
||||||
},
|
|
||||||
showSearch: true,
|
|
||||||
filterTreeNode: (input, treeNode) => {
|
|
||||||
return (treeNode?.name ?? '').toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
|
||||||
},
|
|
||||||
treeNodeFilterProp: 'name'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
<Col span={12}>
|
|
||||||
<ProFormText
|
|
||||||
label={"问题内容"}
|
|
||||||
name={"title"}
|
|
||||||
rules={[
|
|
||||||
{ required: true, message: '请输入问题!' }
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
|
|
||||||
<Col span={6}>
|
|
||||||
<ProFormSwitch
|
|
||||||
label={"是否必填"}
|
|
||||||
name={"required"}
|
|
||||||
initialValue={currentRow?.id ? currentRow.required : true}
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
<Col span={6}>
|
|
||||||
<ProFormSwitch
|
|
||||||
label={"有效状态"}
|
|
||||||
name={"status"}
|
|
||||||
initialValue={currentRow?.id ? currentRow.status : true}
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
<Col span={6}>
|
|
||||||
<ProFormRadio.Group
|
|
||||||
label={"题目类型"}
|
|
||||||
name={"selectType"}
|
|
||||||
fieldProps={{
|
|
||||||
options: [{ label: "单选", value: 1 }, { label: "多选", value: 2 }],
|
|
||||||
}}
|
|
||||||
initialValue={1}
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
<Col span={24}>
|
|
||||||
<ProFormList
|
|
||||||
name="options"
|
|
||||||
label="选项内容"
|
|
||||||
initialValue={[]}
|
|
||||||
creatorButtonProps={{
|
|
||||||
position: 'bottom',
|
|
||||||
creatorButtonText: '添加选项'
|
|
||||||
}}
|
|
||||||
copyIconProps={false}
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
itemContainerStyle={{ width: '100%' }}
|
|
||||||
itemRender={({ listDom, action }, { record, index }) => (
|
|
||||||
<div style={{ width: '100%', display: 'flex', alignItems: 'flex-start', marginBottom: '10px' }}>
|
|
||||||
<div style={{ flex: 1, width: '100%' }}>{listDom}</div>
|
|
||||||
<div style={{ marginLeft: '8px', marginTop: '30px' }}>{action}</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<Row gutter={6} style={{ width: '100%', margin: 0 }}>
|
|
||||||
<Col span={16}>
|
|
||||||
<ProFormTextArea
|
|
||||||
name="text"
|
|
||||||
label="选项"
|
|
||||||
fieldProps={{
|
|
||||||
style: { width: '100%' }
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
<Col span={8}>
|
|
||||||
<ProFormDigit
|
|
||||||
name="mark"
|
|
||||||
label="分值"
|
|
||||||
fieldProps={{
|
|
||||||
style: { width: '100%' },
|
|
||||||
defaultValue: 0
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</ProFormList>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</ProForm>
|
|
||||||
</Modal>
|
|
||||||
</div >
|
</div >
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,29 +1,30 @@
|
|||||||
import request from "@/utils/request"
|
// import request from "@/utils/request"
|
||||||
|
import request from "@/utils/requestJava"
|
||||||
|
|
||||||
// 拿到问题列表接口
|
// 拿到问题列表接口
|
||||||
export async function handleGetQuestionList(params?: any) {
|
export async function handleGetQuestionList(params?: any) {
|
||||||
const data = await request.get('/questions', {params})
|
const data = await request.post('/questions/search/many', params)
|
||||||
if (data.code === 200) {
|
if (data.Result_Code === 100) {
|
||||||
return data.data
|
return data.Result_Data.List
|
||||||
}
|
}
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增问题接口
|
// 新增问题接口
|
||||||
export async function handleAddQuestion(params?: any) {
|
export async function handleAddQuestion(params?: any) {
|
||||||
const data = await request.post('/questions', params)
|
const data = await request.post('/questions/save', params)
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
// 编辑问题接口
|
// 编辑问题接口
|
||||||
export async function handleEditQuestion(params?: any) {
|
export async function handleEditQuestion(params?: any) {
|
||||||
const data = await request.post(`/questions/${params.id}`, params)
|
const data = await request.post(`/questions/update`, params)
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除问题
|
// 删除问题
|
||||||
export async function handleDeleteQuestion(params?: any) {
|
export async function handleDeleteQuestion(params?: any) {
|
||||||
const data = await request.get(`/questions/delete/${params.id}`)
|
const data = await request.get(`/questions/delete`, { params })
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
26
src/pages/examine/record/1.js
Normal file
26
src/pages/examine/record/1.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
// 第一层 片区
|
||||||
|
value: 81, // (id 变成value),
|
||||||
|
... // 别的一样没事
|
||||||
|
childnre: [{
|
||||||
|
// 第二层 服务区
|
||||||
|
value: 528, // (id变value)
|
||||||
|
SPRegionTypeName: "", // 片区名称
|
||||||
|
SPRegionTypeId: "", // 片区id
|
||||||
|
... // 别的一样
|
||||||
|
childnre: [{
|
||||||
|
// 第三层 实际业务
|
||||||
|
serverPartName: "", // 服务区名称
|
||||||
|
serverPartId: "", // 服务区id
|
||||||
|
SPRegionTypeName: "", // 片区名称
|
||||||
|
SPRegionTypeId: "", // 片区id
|
||||||
|
serverPartShopName:"" ,// 门店名称(可能会有)
|
||||||
|
serverPartShopId:"",// 门店id (可能会有)
|
||||||
|
... // 实际业务内容
|
||||||
|
}
|
||||||
|
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,6 +1,5 @@
|
|||||||
/* 打印样式 */
|
/* 打印样式 */
|
||||||
@media print {
|
@media print {
|
||||||
|
|
||||||
/* 隐藏不需要打印的元素 */
|
/* 隐藏不需要打印的元素 */
|
||||||
.ant-pro-card-header,
|
.ant-pro-card-header,
|
||||||
.ant-pro-table-search,
|
.ant-pro-table-search,
|
||||||
@ -21,7 +20,7 @@
|
|||||||
td {
|
td {
|
||||||
border: 1px solid #000;
|
border: 1px solid #000;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
text-align: left;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 页面设置 */
|
/* 页面设置 */
|
||||||
@ -53,4 +52,21 @@
|
|||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 确保iframe内的打印内容可见 */
|
||||||
|
iframe {
|
||||||
|
display: block !important;
|
||||||
|
visibility: visible !important;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 确保打印内容可见 */
|
||||||
|
.print-content, .print-content * {
|
||||||
|
visibility: visible !important;
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,27 +1,36 @@
|
|||||||
import { ConnectState } from "@/models/global";
|
import { ConnectState } from "@/models/global";
|
||||||
import { ActionType, ProTable } from "@ant-design/pro-components";
|
import { ActionType, ProTable } from "@ant-design/pro-components";
|
||||||
import ProForm, { FormInstance, ProFormList, ProFormText } from "@ant-design/pro-form";
|
import ProForm, { FormInstance, ProFormList, ProFormSelect, ProFormText, ProFormTextArea, ProFormUploadButton } from "@ant-design/pro-form";
|
||||||
import { Col, Row, Image, Button, Input, Modal } from "antd";
|
import { Col, Row, Image, Button, Input, Modal } from "antd";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useImperativeHandle, useRef, useState } from "react";
|
||||||
import { connect } from "umi";
|
import { connect } from "umi";
|
||||||
import { handleGetExamineTypeTreeList } from "../../index/service";
|
import { handleGetExamineTypeTreeList } from "../../index/service";
|
||||||
import session from "@/utils/session";
|
import session from "@/utils/session";
|
||||||
import { TextAreaRef } from "antd/lib/input/TextArea";
|
import { TextAreaRef } from "antd/lib/input/TextArea";
|
||||||
import './printStyle.css';
|
import './printStyle.css';
|
||||||
|
import { handleGetDealerList, handleUploadFile } from "../service";
|
||||||
|
|
||||||
|
|
||||||
type DetailProps = {
|
type DetailProps = {
|
||||||
parentRow: any; // 父级数据
|
parentRow: any; // 父级数据
|
||||||
show: boolean;// 抽屉是否显示
|
show: boolean;// 抽屉是否显示
|
||||||
detailType: string; // 详情的类型
|
detailType: string; // 详情的类型
|
||||||
|
currentUser: any
|
||||||
|
onRef?: any
|
||||||
|
showError: boolean;// 是不是处理异常
|
||||||
}
|
}
|
||||||
const RecordDetail = ({ parentRow, show, detailType }: DetailProps) => {
|
const RecordDetail = ({ parentRow, show, detailType, currentUser, onRef, showError }: DetailProps) => {
|
||||||
|
|
||||||
const formRef = useRef<FormInstance>();
|
const formRef = useRef<FormInstance>();
|
||||||
|
console.log('currentUser', currentUser);
|
||||||
|
|
||||||
|
|
||||||
const actionRef = useRef<ActionType>();
|
const actionRef = useRef<ActionType>();
|
||||||
const tableFormRef = useRef<FormInstance>();
|
const tableFormRef = useRef<FormInstance>();
|
||||||
|
|
||||||
|
const errorStatusFormRef = useRef<FormInstance>();
|
||||||
|
const errorStatusFormReflast = useRef<FormInstance>();
|
||||||
// 表格数据
|
// 表格数据
|
||||||
const [proTableData, setTableData] = useState<any>([])
|
const [proTableData, setTableData] = useState<any>([])
|
||||||
|
|
||||||
@ -34,11 +43,15 @@ const RecordDetail = ({ parentRow, show, detailType }: DetailProps) => {
|
|||||||
const footerRef = useRef<TextAreaRef>(null)
|
const footerRef = useRef<TextAreaRef>(null)
|
||||||
// 考核分类的对象格式
|
// 考核分类的对象格式
|
||||||
const [examineObj, setExamineObj] = useState<any>()
|
const [examineObj, setExamineObj] = useState<any>()
|
||||||
|
// 文件列表
|
||||||
|
const [fileList, setFileList] = useState<any>()
|
||||||
|
// 选人的列表数据
|
||||||
|
const [selectPersonList, setSelectPersonList] = useState<any>()
|
||||||
|
|
||||||
const columns: any = [
|
const columns: any = [
|
||||||
{
|
{
|
||||||
title: "考核分类",
|
title: "考核分类",
|
||||||
dataIndex: "name"
|
dataIndex: "parentName"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "考核子类",
|
title: "考核子类",
|
||||||
@ -52,10 +65,11 @@ const RecordDetail = ({ parentRow, show, detailType }: DetailProps) => {
|
|||||||
dataIndex: "title",
|
dataIndex: "title",
|
||||||
hideInTable: detailType === 'modal',
|
hideInTable: detailType === 'modal',
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
|
let questionType: string = record?.question.type.split('_')[0]
|
||||||
let str: string = ''
|
let str: string = ''
|
||||||
if (record.choiceResponse && record?.choiceResponse.length > 0) {
|
if (record.choiceResponse && record?.choiceResponse.length > 0) {
|
||||||
record.choiceResponse.forEach((item: any, index: number) => {
|
record.choiceResponse.forEach((item: any, index: number) => {
|
||||||
str += `${index > 0 ? ',' : ''}答案${index + 1}:${item}`
|
str += `${item.text ? item.text : item};`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return str || ""
|
return str || ""
|
||||||
@ -90,6 +104,8 @@ const RecordDetail = ({ parentRow, show, detailType }: DetailProps) => {
|
|||||||
placeName: parentRow.template?.title || '',
|
placeName: parentRow.template?.title || '',
|
||||||
submittedAt: moment(parentRow?.submittedAt).format('YYYY-MM-DD HH:mm:ss')
|
submittedAt: moment(parentRow?.submittedAt).format('YYYY-MM-DD HH:mm:ss')
|
||||||
}
|
}
|
||||||
|
console.log('formRes', obj);
|
||||||
|
|
||||||
setFormRes(obj)
|
setFormRes(obj)
|
||||||
formRef.current?.setFieldsValue(obj)
|
formRef.current?.setFieldsValue(obj)
|
||||||
}
|
}
|
||||||
@ -121,7 +137,7 @@ const RecordDetail = ({ parentRow, show, detailType }: DetailProps) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 把需要打印的数组拿到一层中来
|
// 把需要打印的数组拿到一层中来
|
||||||
const handleGetTableRes = (list: any) => {
|
const handleGetTableRes = (list: any, fieldObj?: any) => {
|
||||||
console.log('list', list);
|
console.log('list', list);
|
||||||
|
|
||||||
let res: any = [];
|
let res: any = [];
|
||||||
@ -132,13 +148,14 @@ const RecordDetail = ({ parentRow, show, detailType }: DetailProps) => {
|
|||||||
item.question.forEach((questionItem: any) => {
|
item.question.forEach((questionItem: any) => {
|
||||||
res.push({
|
res.push({
|
||||||
...questionItem,
|
...questionItem,
|
||||||
parentId: item.parentId ? item.parentId : "-"
|
parentId: item.parentId ? item.parentId : "-",
|
||||||
|
parentName: fieldObj && item.parentId ? fieldObj[item.parentId] : "-"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (item.children && item.children.length > 0) {
|
if (item.children && item.children.length > 0) {
|
||||||
// 如果有子项,递归处理子项并合并结果
|
// 如果有子项,递归处理子项并合并结果
|
||||||
const childResults = handleGetTableRes(item.children);
|
const childResults = handleGetTableRes(item.children, fieldObj);
|
||||||
if (childResults && childResults.length > 0) {
|
if (childResults && childResults.length > 0) {
|
||||||
res = [...res, ...childResults];
|
res = [...res, ...childResults];
|
||||||
}
|
}
|
||||||
@ -161,61 +178,100 @@ const RecordDetail = ({ parentRow, show, detailType }: DetailProps) => {
|
|||||||
// 从categoryId获取分类名称
|
// 从categoryId获取分类名称
|
||||||
if (item.question && item.question.categoryId) {
|
if (item.question && item.question.categoryId) {
|
||||||
// 这里需要根据实际情况获取分类名称
|
// 这里需要根据实际情况获取分类名称
|
||||||
// 可以从缓存或其他地方获取
|
|
||||||
// const categoryInfo = getCategoryInfo(item.question.categoryId);
|
|
||||||
item.name = examineObj && item.parentId ? examineObj[item.parentId] : ""
|
item.name = examineObj && item.parentId ? examineObj[item.parentId] : ""
|
||||||
item.categoryName = item?.question.title || '';
|
item.categoryName = item?.question.title || '';
|
||||||
item.parentCategoryName = item?.name || '';
|
item.parentCategoryName = item?.name || '';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 按照考核分类和考核子类排序,确保相同的分类和子类相邻
|
||||||
|
processedData.sort((a, b) => {
|
||||||
|
// 先按考核分类排序
|
||||||
|
if (a.parentCategoryName !== b.parentCategoryName) {
|
||||||
|
return a.parentCategoryName.localeCompare(b.parentCategoryName);
|
||||||
|
}
|
||||||
|
// 再按考核子类排序
|
||||||
|
return a.categoryName.localeCompare(b.categoryName);
|
||||||
|
});
|
||||||
|
|
||||||
// 计算合并信息
|
// 计算合并信息
|
||||||
let currentCategory = '';
|
let currentCategory = '';
|
||||||
let currentSubCategory = '';
|
let currentSubCategory = '';
|
||||||
let categorySpan = 0;
|
let categoryStartIndex = 0;
|
||||||
let subCategorySpan = 0;
|
let subCategoryStartIndex = 0;
|
||||||
|
|
||||||
processedData.forEach((item: any, index: number) => {
|
processedData.forEach((item: any, index: number) => {
|
||||||
|
// 初始化合并标记
|
||||||
|
item._categoryMerged = false;
|
||||||
|
item._subCategoryMerged = false;
|
||||||
|
|
||||||
// 处理考核分类合并
|
// 处理考核分类合并
|
||||||
if (item.parentCategoryName === currentCategory) {
|
if (index === 0 || item.parentCategoryName !== currentCategory) {
|
||||||
categorySpan++;
|
// 如果是新的分类,更新前一个分类的合并信息
|
||||||
item._categoryMerged = true; // 标记为已合并
|
if (index > 0) {
|
||||||
} else {
|
const span = index - categoryStartIndex;
|
||||||
// 更新前一个分类的合并信息
|
if (span > 1) { // 只有当跨度大于1时才需要合并
|
||||||
if (categorySpan > 0 && index > 0) {
|
processedData[categoryStartIndex]._categoryRowSpan = span;
|
||||||
processedData[index - categorySpan]._categoryRowSpan = categorySpan + 1;
|
// 标记除第一行外的其他行为已合并
|
||||||
|
for (let i = categoryStartIndex + 1; i < index; i++) {
|
||||||
|
processedData[i]._categoryMerged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// 记录新分类的开始位置
|
||||||
|
categoryStartIndex = index;
|
||||||
currentCategory = item.parentCategoryName;
|
currentCategory = item.parentCategoryName;
|
||||||
categorySpan = 0;
|
// 重置子类信息,因为新的分类开始了
|
||||||
item._categoryRowSpan = 1; // 默认占一行
|
currentSubCategory = '';
|
||||||
|
subCategoryStartIndex = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理考核子类合并
|
// 处理考核子类合并
|
||||||
if (item.categoryName === currentSubCategory) {
|
if (index === 0 || item.categoryName !== currentSubCategory || item.parentCategoryName !== currentCategory) {
|
||||||
subCategorySpan++;
|
// 如果是新的子类或新的分类,更新前一个子类的合并信息
|
||||||
item._subCategoryMerged = true; // 标记为已合并
|
if (index > 0 && currentSubCategory) {
|
||||||
} else {
|
const span = index - subCategoryStartIndex;
|
||||||
// 更新前一个子类的合并信息
|
if (span > 1) { // 只有当跨度大于1时才需要合并
|
||||||
if (subCategorySpan > 0 && index > 0) {
|
processedData[subCategoryStartIndex]._subCategoryRowSpan = span;
|
||||||
processedData[index - subCategorySpan]._subCategoryRowSpan = subCategorySpan + 1;
|
// 标记除第一行外的其他行为已合并
|
||||||
|
for (let i = subCategoryStartIndex + 1; i < index; i++) {
|
||||||
|
processedData[i]._subCategoryMerged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// 记录新子类的开始位置
|
||||||
|
subCategoryStartIndex = index;
|
||||||
currentSubCategory = item.categoryName;
|
currentSubCategory = item.categoryName;
|
||||||
subCategorySpan = 0;
|
|
||||||
item._subCategoryRowSpan = 1; // 默认占一行
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 处理最后一组数据的合并信息
|
// 处理最后一组数据的合并信息
|
||||||
if (categorySpan > 0 && processedData.length > 0) {
|
const lastIndex = processedData.length - 1;
|
||||||
const targetIndex = processedData.length - categorySpan - 1;
|
if (lastIndex >= 0) {
|
||||||
if (targetIndex >= 0 && targetIndex < processedData.length && processedData[targetIndex]) {
|
// 处理最后一个分类的合并
|
||||||
processedData[targetIndex]._categoryRowSpan = categorySpan + 1;
|
const categorySpan = lastIndex - categoryStartIndex + 1;
|
||||||
|
if (categorySpan > 1) {
|
||||||
|
processedData[categoryStartIndex]._categoryRowSpan = categorySpan;
|
||||||
|
for (let i = categoryStartIndex + 1; i <= lastIndex; i++) {
|
||||||
|
processedData[i]._categoryMerged = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果只有一行,不需要合并
|
||||||
|
processedData[categoryStartIndex]._categoryRowSpan = 1;
|
||||||
|
processedData[categoryStartIndex]._categoryMerged = false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (subCategorySpan > 0 && processedData.length > 0) {
|
// 处理最后一个子类的合并
|
||||||
const targetIndex = processedData.length - subCategorySpan - 1;
|
const subCategorySpan = lastIndex - subCategoryStartIndex + 1;
|
||||||
if (targetIndex >= 0 && targetIndex < processedData.length && processedData[targetIndex]) {
|
if (subCategorySpan > 1) {
|
||||||
processedData[targetIndex]._subCategoryRowSpan = subCategorySpan + 1;
|
processedData[subCategoryStartIndex]._subCategoryRowSpan = subCategorySpan;
|
||||||
|
for (let i = subCategoryStartIndex + 1; i <= lastIndex; i++) {
|
||||||
|
processedData[i]._subCategoryMerged = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果只有一行,不需要合并
|
||||||
|
processedData[subCategoryStartIndex]._subCategoryRowSpan = 1;
|
||||||
|
processedData[subCategoryStartIndex]._subCategoryMerged = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,73 +306,58 @@ const RecordDetail = ({ parentRow, show, detailType }: DetailProps) => {
|
|||||||
|
|
||||||
// 打印表格方法
|
// 打印表格方法
|
||||||
const handlePrintTable = () => {
|
const handlePrintTable = () => {
|
||||||
// 创建打印内容
|
|
||||||
const printWindow = window.open('', '_blank');
|
|
||||||
if (!printWindow) {
|
|
||||||
Modal.error({ title: '打印失败', content: '无法创建打印窗口,请检查浏览器设置。' });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取表格数据
|
// 获取表格数据
|
||||||
const tableData = proTableData || [];
|
const tableData = proTableData || [];
|
||||||
|
|
||||||
// 构建HTML内容
|
// 创建一个iframe用于打印,这样可以避免CSS冲突
|
||||||
|
const printIframe = document.createElement('iframe');
|
||||||
|
printIframe.style.position = 'absolute';
|
||||||
|
printIframe.style.width = '0';
|
||||||
|
printIframe.style.height = '0';
|
||||||
|
printIframe.style.border = '0';
|
||||||
|
document.body.appendChild(printIframe);
|
||||||
|
|
||||||
|
// 构建打印内容
|
||||||
let printContent = `
|
let printContent = `
|
||||||
<html>
|
<!DOCTYPE html>
|
||||||
<head>
|
<html>
|
||||||
<title>考核记录打印</title>
|
<head>
|
||||||
<style>
|
<title>打印页面</title>
|
||||||
body { font-family: Arial, sans-serif; margin: 20px; }
|
<style>
|
||||||
.print-header, .print-footer { margin: 20px 0; white-space: pre-wrap; }
|
/* 重置样式 */
|
||||||
table { width: 100%; border-collapse: collapse; margin: 20px 0; }
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||||
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
body { font-family: Arial, sans-serif; padding: 32px; }
|
||||||
th { background-color: #f2f2f2; }
|
|
||||||
.info-section { margin-bottom: 20px; }
|
/* 表格样式 */
|
||||||
.info-item { margin-bottom: 10px; }
|
table { width: 100%; border-collapse: collapse; margin: 8px 0; }
|
||||||
.info-label { font-weight: bold; display: inline-block; width: 100px; }
|
th, td { border: 1px solid #000; padding: 8px; text-align: center; }
|
||||||
.image-container { display: flex; flex-wrap: wrap; margin-top: 10px; }
|
th { background-color: #f2f2f2; font-weight: bold; }
|
||||||
.image-item { margin-right: 10px; margin-bottom: 10px; }
|
|
||||||
@media print {
|
/* 打印设置 */
|
||||||
button { display: none; }
|
@page { margin: 1cm; }
|
||||||
}
|
|
||||||
</style>
|
/* 确保所有内容可见 */
|
||||||
</head>
|
.print-content { visibility: visible !important; }
|
||||||
<body>
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="print-content">
|
||||||
`;
|
`;
|
||||||
|
// 加一下页眉
|
||||||
// 添加自定义页眉
|
|
||||||
if (headerContent) {
|
|
||||||
printContent += `<div class="print-header">${headerContent}</div>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加基本信息
|
|
||||||
printContent += `
|
printContent += `
|
||||||
<div class="info-section">
|
<div style="width:100%;text-align:center;font-size: 32px;font-weight: bold;margin-bottom: 20px">
|
||||||
<div class="info-item"><span class="info-label">服务区名称:</span> ${formRes?.serverPartName || ''}</div>
|
<div>${parentRow?.serverPartName || '-'}</div>
|
||||||
<div class="info-item"><span class="info-label">站点名称:</span> ${formRes?.placeName || ''}</div>
|
<div>走动式管理巡查记录</div>
|
||||||
<div class="info-item"><span class="info-label">巡查内容:</span> ${formRes?.uploadResult || ''}</div>
|
|
||||||
<div class="info-item"><span class="info-label">巡查人员:</span> ${formRes?.userName || ''}</div>
|
|
||||||
<div class="info-item"><span class="info-label">巡查时间:</span> ${formRes?.submittedAt || ''}</div>
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
<div style="width:100%;display:flex;align-items: center;justify-content: space-between;">
|
||||||
|
<div>巡查内容:${formRes?.uploadResult || '-'}</div>
|
||||||
// 添加图片信息
|
<div>服务区区域:${formRes?.placeName || '-'}</div>
|
||||||
if (formRes?.imgsList && formRes.imgsList.length > 0) {
|
</div>
|
||||||
printContent += `
|
<div style="width:100%;display:flex;align-items: center;justify-content: space-between;">
|
||||||
<div class="info-section">
|
<div>巡检人员:${parentRow?.userName || '-'}</div>
|
||||||
<div class="info-label">附件列表:</div>
|
<div>巡检时间:${parentRow?.createdAt ? moment(parentRow?.createdAt).format('YYYY-MM-DD HH:mm:ss') : '-'}</div>
|
||||||
<div class="image-container">
|
</div>
|
||||||
`;
|
`
|
||||||
|
|
||||||
formRes.imgsList.forEach((item: string) => {
|
|
||||||
printContent += `<div class="image-item"><img src="${item}" style="width: 150px; height: 150px;" /></div>`;
|
|
||||||
});
|
|
||||||
|
|
||||||
printContent += `
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加表格
|
// 添加表格
|
||||||
printContent += `
|
printContent += `
|
||||||
@ -325,12 +366,14 @@ const RecordDetail = ({ parentRow, show, detailType }: DetailProps) => {
|
|||||||
<tr>
|
<tr>
|
||||||
<th>考核分类</th>
|
<th>考核分类</th>
|
||||||
<th>考核子类</th>
|
<th>考核子类</th>
|
||||||
<th>考核结果</th>
|
<th>${detailType !== 'modal' ? '考核结果' : '考核选项'}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
console.log('tableData', tableData);
|
||||||
|
|
||||||
// 添加表格数据行
|
// 添加表格数据行
|
||||||
tableData.forEach((record: any) => {
|
tableData.forEach((record: any) => {
|
||||||
printContent += '<tr>';
|
printContent += '<tr>';
|
||||||
@ -339,65 +382,114 @@ const RecordDetail = ({ parentRow, show, detailType }: DetailProps) => {
|
|||||||
if (record._categoryMerged) {
|
if (record._categoryMerged) {
|
||||||
// 如果已合并,不显示单元格
|
// 如果已合并,不显示单元格
|
||||||
} else {
|
} else {
|
||||||
printContent += `<td ${record._categoryRowSpan && record._categoryRowSpan > 1 ? `rowspan="${record._categoryRowSpan}"` : ''}>${record.parentCategoryName || ''}</td>`;
|
printContent += `<td style="width: 100px" ${record._categoryRowSpan && record._categoryRowSpan > 1 ? `rowspan="${record._categoryRowSpan}"` : ''}>${record.parentName || ''}</td>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 考核子类列 - 处理合并单元格
|
// 考核子类列 - 处理合并单元格
|
||||||
if (record._subCategoryMerged) {
|
if (record._subCategoryMerged) {
|
||||||
// 如果已合并,不显示单元格
|
// 如果已合并,不显示单元格
|
||||||
} else {
|
} else {
|
||||||
printContent += `<td ${record._subCategoryRowSpan && record._subCategoryRowSpan > 1 ? `rowspan="${record._subCategoryRowSpan}"` : ''}>${record.question?.title || ''}</td>`;
|
printContent += `<td style="width: 100px" ${record._subCategoryRowSpan && record._subCategoryRowSpan > 1 ? `rowspan="${record._subCategoryRowSpan}"` : ''}>${record.question?.title || ''}</td>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 考核结果列
|
// 考核结果列
|
||||||
let resultStr = '';
|
let resultStr = '';
|
||||||
if (record.choiceResponse && record.choiceResponse.length > 0) {
|
if (record.choiceResponse && record.choiceResponse.length > 0) {
|
||||||
record.choiceResponse.forEach((item: any, index: number) => {
|
record.choiceResponse.forEach((item: any, index: number) => {
|
||||||
resultStr += `${index > 0 ? ',' : ''}答案${index + 1}:${item}`;
|
resultStr += `${item.text ? item.text : item}`;
|
||||||
|
// ${index > 0 ? ',' : ''}结果${index + 1}:
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
printContent += `<td>${resultStr || ''}</td>`;
|
printContent += `<td style="text-align:left">${resultStr || ''}</td>`;
|
||||||
|
|
||||||
printContent += '</tr>';
|
printContent += '</tr>';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// if (parentRow?.situation !== 1) {
|
||||||
|
// 加一个页脚
|
||||||
|
printContent += `
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
${formRes.errorStatus >= 1 ? `<tr>
|
||||||
|
<td style="width: 100px">值班经理</td>
|
||||||
|
<td>${formRes.suggestPerson.STAFF_NAME || '-'}</td>
|
||||||
|
<td style="width: 100px">确认时间</td>
|
||||||
|
<td>${formRes.suggestTime || '-'}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 100px">经理意见</td>
|
||||||
|
<td colspan="3">${formRes.suggestion || '-'}</td>
|
||||||
|
</tr>`: ""
|
||||||
|
}
|
||||||
|
${formRes.errorStatus === 2 ? `
|
||||||
|
<tr>
|
||||||
|
<td style="width: 100px">处理人员</td>
|
||||||
|
<td>${formRes.person.STAFF_NAME || '-'}</td>
|
||||||
|
<td style="width: 100px">反馈时间</td>
|
||||||
|
<td>${formRes.feedbackTime || '-'}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 100px">反馈内容</td>
|
||||||
|
<td colspan="3">${formRes.feedbackContent || '-'}</td>
|
||||||
|
</tr>
|
||||||
|
`:
|
||||||
|
""
|
||||||
|
}
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
`
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
printContent += `
|
printContent += `
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
`;
|
|
||||||
|
|
||||||
// 添加自定义页脚
|
|
||||||
if (footerContent) {
|
|
||||||
printContent += `<div class="print-footer">${footerContent}</div>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加打印按钮
|
|
||||||
printContent += `
|
|
||||||
<div style="text-align: center; margin-top: 20px;">
|
|
||||||
<button onclick="window.print();" style="padding: 8px 16px;">打印</button>
|
|
||||||
<button onclick="window.close();" style="padding: 8px 16px; margin-left: 10px;">关闭</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
printContent += `
|
console.log('printContent', printContent);
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`;
|
|
||||||
|
|
||||||
// 写入打印窗口并打印
|
// 获取iframe的文档对象
|
||||||
printWindow.document.open();
|
const iframeDocument = printIframe.contentWindow?.document;
|
||||||
printWindow.document.write(printContent);
|
if (iframeDocument) {
|
||||||
printWindow.document.close();
|
// 打开文档进行写入
|
||||||
|
iframeDocument.open();
|
||||||
// 等待图片加载完成后打印
|
iframeDocument.write(printContent);
|
||||||
setTimeout(() => {
|
iframeDocument.close();
|
||||||
printWindow.focus();
|
|
||||||
// 自动打印可以取消注释下面的代码
|
|
||||||
// printWindow.print();
|
|
||||||
}, 500);
|
|
||||||
|
|
||||||
|
// 等待内容渲染完成后打印
|
||||||
|
setTimeout(() => {
|
||||||
|
try {
|
||||||
|
// 使用iframe的打印功能
|
||||||
|
printIframe.contentWindow?.print();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('打印失败:', error);
|
||||||
|
} finally {
|
||||||
|
// 打印完成后移除iframe
|
||||||
|
setTimeout(() => {
|
||||||
|
document.body.removeChild(printIframe);
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
}, 500); // 增加等待时间确保内容完全渲染
|
||||||
|
} else {
|
||||||
|
console.error('无法获取iframe文档对象');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useImperativeHandle(onRef, () => ({
|
||||||
|
errorStatusFormRef,
|
||||||
|
errorStatusFormReflast,
|
||||||
|
formRes,
|
||||||
|
selectPersonList,
|
||||||
|
fileList
|
||||||
|
}));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ProForm
|
<ProForm
|
||||||
@ -444,58 +536,216 @@ const RecordDetail = ({ parentRow, show, detailType }: DetailProps) => {
|
|||||||
readonly
|
readonly
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={16}>
|
|
||||||
<ProFormList
|
{
|
||||||
label={"附件列表"}
|
formRes?.imgsList && formRes?.imgsList.length > 0 ?
|
||||||
name={"imgsList"}
|
<Col span={24}>
|
||||||
copyIconProps={false}
|
<div style={{ width: "100%", height: '170px', overflowX: "auto", display: 'flex', alignItems: 'center' }}>
|
||||||
deleteIconProps={false}
|
{
|
||||||
readonly
|
formRes?.imgsList && formRes?.imgsList.length > 0 ?
|
||||||
style={{ width: '100%' }}
|
formRes?.imgsList.map((item: string) => {
|
||||||
itemContainerStyle={{ width: '100%' }}
|
return <Image key={item} style={{ width: "150px", height: "150px", marginRight: "12px" }} src={item} />
|
||||||
itemRender={({ listDom, action }, { record, index }) => (
|
})
|
||||||
<div style={{ width: '100%', display: 'flex', alignItems: 'flex-start', marginBottom: '10px' }}>
|
: ''
|
||||||
<div style={{ flex: 1, width: '100%' }}>{listDom}</div>
|
}
|
||||||
<div style={{ marginLeft: '8px', marginTop: '30px' }}>{action}</div>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
</Col>
|
||||||
>
|
|
||||||
<div style={{ width: "300px", height: '170px', overflowX: "auto", display: 'flex', alignItems: 'center' }}>
|
// <Col span={16}>
|
||||||
{
|
// <ProFormList
|
||||||
formRes?.imgsList && formRes?.imgsList.length > 0 ?
|
// label={"附件列表"}
|
||||||
formRes?.imgsList.map((item: string) => {
|
// name={"imgsList"}
|
||||||
return <Image style={{ width: "150px", height: "150px", marginRight: "12px" }} src={item} />
|
// copyIconProps={false}
|
||||||
})
|
// deleteIconProps={false}
|
||||||
: ''
|
// readonly
|
||||||
}
|
// alwaysShowItemLabel
|
||||||
</div>
|
// style={{ width: '100%' }}
|
||||||
</ProFormList>
|
// itemContainerStyle={{ width: '100%' }}
|
||||||
</Col>
|
// itemRender={({ listDom, action }, { record, index }) => (
|
||||||
|
// <div style={{ width: '100%', display: 'flex', alignItems: 'flex-start', marginBottom: '10px' }}>
|
||||||
|
// <div style={{ flex: 1, width: '100%' }}>{listDom}</div>
|
||||||
|
// <div style={{ marginLeft: '8px', marginTop: '30px' }}>{action}</div>
|
||||||
|
// </div>
|
||||||
|
// )}
|
||||||
|
// >
|
||||||
|
// <div style={{ width: "300px", height: '170px', overflowX: "auto", display: 'flex', alignItems: 'center' }}>
|
||||||
|
// {
|
||||||
|
// formRes?.imgsList && formRes?.imgsList.length > 0 ?
|
||||||
|
// formRes?.imgsList.map((item: string) => {
|
||||||
|
// return <Image key={item} style={{ width: "150px", height: "150px", marginRight: "12px" }} src={item} />
|
||||||
|
// })
|
||||||
|
// : ''
|
||||||
|
// }
|
||||||
|
// </div>
|
||||||
|
// </ProFormList>
|
||||||
|
// </Col>
|
||||||
|
: ""
|
||||||
|
}
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
</Row>
|
</Row>
|
||||||
</ProForm>
|
</ProForm>
|
||||||
|
|
||||||
|
{
|
||||||
|
showError && formRes && formRes.errorStatus >= 0 ?
|
||||||
|
<ProForm
|
||||||
|
formRef={errorStatusFormRef}
|
||||||
|
submitter={false}
|
||||||
|
layout={'horizontal'}
|
||||||
|
request={() => {
|
||||||
|
console.log('formRes', formRes);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...formRes,
|
||||||
|
personIndex: formRes.person.STAFF_ID
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Row gutter={8}>
|
||||||
|
<Col span={8}>
|
||||||
|
<ProFormSelect
|
||||||
|
label={"异常处理人"}
|
||||||
|
name={"personIndex"}
|
||||||
|
request={async () => {
|
||||||
|
const req = {
|
||||||
|
SERVERPART_ID: formRes.serverPartId,
|
||||||
|
PROVINCE_CODE: currentUser.provinceCode,
|
||||||
|
}
|
||||||
|
const data = await handleGetDealerList(req)
|
||||||
|
console.log('data', data)
|
||||||
|
let res = data.Data.List
|
||||||
|
setSelectPersonList(res)
|
||||||
|
return res
|
||||||
|
}}
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: "请选择处理人" }
|
||||||
|
]}
|
||||||
|
fieldProps={{
|
||||||
|
fieldNames: {
|
||||||
|
"label": "STAFF_NAME",
|
||||||
|
"value": "STAFF_ID"
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
disabled={formRes.errorStatus > 0}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
|
||||||
|
<Col span={8}>
|
||||||
|
<ProFormTextArea
|
||||||
|
label={"整改意见"}
|
||||||
|
name={"suggestion"}
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: "请输入整改意见" }
|
||||||
|
]}
|
||||||
|
disabled={formRes.errorStatus > 0}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
</ProForm> : ""
|
||||||
|
}
|
||||||
|
{
|
||||||
|
showError && formRes && formRes.errorStatus >= 1 ?
|
||||||
|
<ProForm
|
||||||
|
formRef={errorStatusFormReflast}
|
||||||
|
submitter={false}
|
||||||
|
layout={'horizontal'}
|
||||||
|
request={() => {
|
||||||
|
console.log('formRes', formRes);
|
||||||
|
let list: any = []
|
||||||
|
if (formRes.feedbackImgList && formRes.feedbackImgList.length > 0) {
|
||||||
|
formRes.feedbackImgList.forEach((item: string, index: number) => {
|
||||||
|
list.push({
|
||||||
|
uid: '',
|
||||||
|
name: `image${index}.png`,
|
||||||
|
status: 'done',
|
||||||
|
url: item,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
setFileList(list)
|
||||||
|
return {
|
||||||
|
...formRes,
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Row gutter={8}>
|
||||||
|
<Col span={8}>
|
||||||
|
<ProFormUploadButton
|
||||||
|
label={"反馈图片"}
|
||||||
|
listType="picture-card"
|
||||||
|
name={"feedbackImgList"}
|
||||||
|
fileList={fileList}
|
||||||
|
rules={[{
|
||||||
|
required: true,
|
||||||
|
message: "请上传反馈图片"
|
||||||
|
}]}
|
||||||
|
disabled={formRes.errorStatus > 1}
|
||||||
|
fieldProps={{
|
||||||
|
customRequest: async (info: any) => {
|
||||||
|
console.log('info', info);
|
||||||
|
const formData = new FormData();
|
||||||
|
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 file = JSON.parse(JSON.stringify(fileList))
|
||||||
|
file.push({
|
||||||
|
uid: '',
|
||||||
|
// name: `${data.data.filename}.png`,
|
||||||
|
name: `${info.file.name}.png`,
|
||||||
|
status: 'done',
|
||||||
|
url: url,
|
||||||
|
})
|
||||||
|
setFileList(file)
|
||||||
|
},
|
||||||
|
onChange: (info: any) => {
|
||||||
|
if (info.file.status === 'removed') {
|
||||||
|
console.log('info', info);
|
||||||
|
setFileList(info.fileList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
|
||||||
|
|
||||||
|
<Col span={8}>
|
||||||
|
<ProFormTextArea
|
||||||
|
label={"反馈内容"}
|
||||||
|
name={"feedbackContent"}
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: "请输入反馈内容" }
|
||||||
|
]}
|
||||||
|
disabled={formRes.errorStatus > 1}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</ProForm> : ""
|
||||||
|
}
|
||||||
|
|
||||||
<ProTable
|
<ProTable
|
||||||
actionRef={actionRef}
|
actionRef={actionRef}
|
||||||
formRef={tableFormRef}
|
formRef={tableFormRef}
|
||||||
search={false}
|
search={false}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
|
bordered
|
||||||
toolbar={{
|
toolbar={{
|
||||||
actions: [
|
actions: [
|
||||||
<Button type="primary" onClick={(e) => {
|
<Button type="primary" onClick={(e) => {
|
||||||
setPrintModalVisible(true)
|
handlePrintTable()
|
||||||
}}>
|
}}>
|
||||||
打印
|
打印
|
||||||
</Button>
|
</Button>
|
||||||
]
|
]
|
||||||
}}
|
}}
|
||||||
scroll={{ x: "100%", y: 'calc(100vh - 400px)' }}
|
scroll={{ x: "100%", y: 'calc(100vh - 300px)' }}
|
||||||
pagination={false}
|
pagination={false}
|
||||||
options={false}
|
options={false}
|
||||||
request={async () => {
|
request={async () => {
|
||||||
let res = detailType === 'modal' ? parentRow?.questionnaireTemplateQuestions
|
let res = detailType === 'modal' ? parentRow?.questionnaireTemplateQuestions
|
||||||
|| [] : parentRow?.questionResponses || []
|
|| [] : parentRow?.questionResponses || []
|
||||||
|
console.log('parentRow', parentRow);
|
||||||
console.log('res', res);
|
console.log('res', res);
|
||||||
|
|
||||||
let obj: any = {}
|
let obj: any = {}
|
||||||
@ -513,14 +763,21 @@ const RecordDetail = ({ parentRow, show, detailType }: DetailProps) => {
|
|||||||
}
|
}
|
||||||
setExamineObj(obj)
|
setExamineObj(obj)
|
||||||
|
|
||||||
|
console.log('resresres', res);
|
||||||
|
|
||||||
|
|
||||||
let tableData = await handeGetTableData(typeData, res)
|
let tableData = await handeGetTableData(typeData, res)
|
||||||
console.log('tableData', tableData);
|
console.log('tableData', tableData);
|
||||||
// 拿到整个数据之后 递归取出tableData中有 question 数据的那一层数据变为一个数组
|
// 拿到整个数据之后 递归取出tableData中有 question 数据的那一层数据变为一个数组
|
||||||
let tableRes = await handleGetTableRes(tableData)
|
let tableRes = await handleGetTableRes(tableData, obj)
|
||||||
console.log('tableRes', tableRes);
|
console.log('tableRes', tableRes);
|
||||||
|
|
||||||
// 处理表格数据,为合并单元格做准备
|
// 处理表格数据,为合并单元格做准备
|
||||||
let processedData = processTableDataForMerge(tableRes);
|
let processedData = processTableDataForMerge(tableRes);
|
||||||
|
|
||||||
|
|
||||||
|
console.log('processedData', processedData);
|
||||||
|
|
||||||
setTableData(processedData)
|
setTableData(processedData)
|
||||||
|
|
||||||
if (processedData && processedData.length > 0) {
|
if (processedData && processedData.length > 0) {
|
||||||
@ -582,39 +839,9 @@ const RecordDetail = ({ parentRow, show, detailType }: DetailProps) => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Modal
|
{/* 移除打印设置弹窗 */}
|
||||||
title="打印设置"
|
|
||||||
open={printModalVisible}
|
|
||||||
onOk={() => {
|
|
||||||
handlePrintTable();
|
|
||||||
setPrintModalVisible(false);
|
|
||||||
}}
|
|
||||||
onCancel={() => setPrintModalVisible(false)}
|
|
||||||
width={600}
|
|
||||||
>
|
|
||||||
<div style={{ marginBottom: 16 }}>
|
|
||||||
<div style={{ marginBottom: 8 }}>页眉内容(可选):</div>
|
|
||||||
<Input.TextArea
|
|
||||||
ref={headerRef}
|
|
||||||
rows={4}
|
|
||||||
value={headerContent}
|
|
||||||
onChange={(e) => setHeaderContent(e.target.value)}
|
|
||||||
placeholder="请输入要在打印页面顶部显示的内容"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div style={{ marginBottom: 8 }}>页脚内容(可选):</div>
|
|
||||||
<Input.TextArea
|
|
||||||
ref={footerRef}
|
|
||||||
rows={4}
|
|
||||||
value={footerContent}
|
|
||||||
onChange={(e) => setFooterContent(e.target.value)}
|
|
||||||
placeholder="请输入要在打印页面底部显示的内容"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
|
|
||||||
</div>
|
</div >
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,17 +2,19 @@ import { ConnectState } from "@/models/global";
|
|||||||
import { ActionType, FormInstance, ProTable } from "@ant-design/pro-components";
|
import { ActionType, FormInstance, ProTable } from "@ant-design/pro-components";
|
||||||
import { useRef, useState } from "react";
|
import { useRef, useState } from "react";
|
||||||
import { connect } from "umi";
|
import { connect } from "umi";
|
||||||
import { handleDeleteRecord, handleGetRecordList } from "./service";
|
import { handleDeleteRecord, handleGetRecordList, handleGetRecordTreeList, handleUpdateExtend } from "./service";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { Button, Drawer, Image, message, Popconfirm, Space } from "antd";
|
import { Button, Drawer, Image, message, Popconfirm, Space } from "antd";
|
||||||
import { handleGetServerpartDDL } from "@/components/leftSelectTree/service";
|
import { handleGetServerpartDDL } from "@/components/leftSelectTree/service";
|
||||||
import RecordDetail from "./components/recordDetail";
|
import RecordDetail from "./components/recordDetail";
|
||||||
|
import LeftSelectTree from "@/components/leftSelectTree/leftSelectTree";
|
||||||
|
|
||||||
const examineRecord: React.FC<{ currentUser: any }> = (props) => {
|
const examineRecord: React.FC<{ currentUser: any }> = (props) => {
|
||||||
const { currentUser } = props
|
const { currentUser } = props
|
||||||
|
|
||||||
const actionRef = useRef<ActionType>();
|
const actionRef = useRef<ActionType>();
|
||||||
const formRef = useRef<FormInstance>();
|
const formRef = useRef<FormInstance>();
|
||||||
|
const recordDetailRef = useRef<any>()
|
||||||
// 显示的附件数据
|
// 显示的附件数据
|
||||||
const [showImgList, setShowImgList] = useState<string[]>([])
|
const [showImgList, setShowImgList] = useState<string[]>([])
|
||||||
// 预览图片
|
// 预览图片
|
||||||
@ -23,59 +25,101 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
const [currentRow, setCurrentRow] = useState<any>()
|
const [currentRow, setCurrentRow] = useState<any>()
|
||||||
// 显示详情抽屉
|
// 显示详情抽屉
|
||||||
const [showDetail, setShowDetail] = useState<boolean>(false)
|
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 = [
|
const columns: any = [
|
||||||
{
|
{
|
||||||
title: "统计日期",
|
title: "统计日期",
|
||||||
dataIndex: "staticDate",
|
dataIndex: "staticDate",
|
||||||
hideInTable: true,
|
hideInTable: true,
|
||||||
valueType: "dateRange",
|
valueType: "date",
|
||||||
initialValue: [moment().startOf('M'), moment()],
|
initialValue: moment().subtract('1', 'd'),
|
||||||
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: "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: "服务区",
|
title: "巡查类型",
|
||||||
dataIndex: "serverPartId",
|
dataIndex: "inspectionType",
|
||||||
hideInTable: true,
|
hideInTable: true,
|
||||||
valueType: "select",
|
valueType: "select",
|
||||||
request: async () => {
|
valueEnum: {
|
||||||
const req = {
|
"1": '异常',
|
||||||
ProvinceCode: currentUser?.provinceCode,
|
"0": "正常"
|
||||||
StatisticsType: 1000
|
|
||||||
}
|
|
||||||
const data = await handleGetServerpartDDL(req)
|
|
||||||
return data
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: <div style={{ textAlign: 'center' }}>服务区名称</div>,
|
title: <div style={{ textAlign: 'center' }}>服务区名称</div>,
|
||||||
dataIndex: "serverPartName",
|
dataIndex: "serverPartName",
|
||||||
hideInSearch: true,
|
hideInSearch: true,
|
||||||
width: 150,
|
width: 200,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
return record?.template.serverPartName ? record?.template.serverPartName : "-"
|
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>,
|
title: <div style={{ textAlign: 'center' }}>巡查类型</div>,
|
||||||
dataIndex: "placeName",
|
dataIndex: "placeName",
|
||||||
hideInSearch: true,
|
hideInSearch: true,
|
||||||
width: 150,
|
width: 100,
|
||||||
|
align: 'center',
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
return record?.template.title ? record?.template.title : "-"
|
let res: any = record.extend ? JSON.parse(record.extend) : "-"
|
||||||
|
return <span style={{ color: res.situation === 1 ? "red" : "" }}>{res.situation === 1 ? '异常' : res.situation === 0 ? '正常' : ''}</span>
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -111,6 +155,14 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
return str || ''
|
return str || ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: <div style={{ textAlign: 'center' }}>巡查总分</div>,
|
||||||
|
dataIndex: "score",
|
||||||
|
hideInSearch: true,
|
||||||
|
valueType: 'digit',
|
||||||
|
width: 100,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: <div style={{ textAlign: 'center' }}>巡查时间</div>,
|
title: <div style={{ textAlign: 'center' }}>巡查时间</div>,
|
||||||
dataIndex: "createdAt",
|
dataIndex: "createdAt",
|
||||||
@ -130,6 +182,26 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
align: 'center',
|
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>,
|
title: <div style={{ textAlign: 'center' }}>现场图片</div>,
|
||||||
dataIndex: "placeName",
|
dataIndex: "placeName",
|
||||||
@ -153,15 +225,33 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
align: 'center',
|
align: 'center',
|
||||||
fixed: "right",
|
fixed: "right",
|
||||||
hideInSearch: true,
|
hideInSearch: true,
|
||||||
width: 100,
|
width: 150,
|
||||||
render: (_: any, record: any) => {
|
render: (_: any, record: any) => {
|
||||||
return <Space>
|
let res: any = record.extend ? JSON.parse(record.extend) : "-"
|
||||||
<a onClick={() => {
|
|
||||||
setCurrentRow(record)
|
return record?.type === 'district' || record?.type === 'servicePart' ? '' : <Space>
|
||||||
|
{
|
||||||
|
res.situation === 1 ?
|
||||||
|
<a onClick={
|
||||||
|
() => {
|
||||||
|
setCurrentRow({
|
||||||
|
...record,
|
||||||
|
...res
|
||||||
|
})
|
||||||
|
setShowAbnormal(true)
|
||||||
|
setShowDetail(true)
|
||||||
|
}
|
||||||
|
}>异常处理</a> : ""
|
||||||
|
}
|
||||||
|
< a onClick={() => {
|
||||||
|
setCurrentRow({
|
||||||
|
...record,
|
||||||
|
...res
|
||||||
|
})
|
||||||
setShowDetail(true)
|
setShowDetail(true)
|
||||||
}}>
|
}}>
|
||||||
详情
|
详情
|
||||||
</a>
|
</a >
|
||||||
<Popconfirm
|
<Popconfirm
|
||||||
title={"确认删除?"}
|
title={"确认删除?"}
|
||||||
onConfirm={async () => {
|
onConfirm={async () => {
|
||||||
@ -171,7 +261,7 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
<a>删除</a>
|
<a>删除</a>
|
||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
|
|
||||||
</Space>
|
</Space >
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -179,17 +269,20 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
// 删除记录
|
// 删除记录
|
||||||
const deleteRecord = async (id: any) => {
|
const deleteRecord = async (id: any) => {
|
||||||
const data = await handleDeleteRecord({ id: id })
|
const data = await handleDeleteRecord({ id: id })
|
||||||
if (data.code === 200) {
|
if (data.Result_Code === 100) {
|
||||||
message.success(data.message)
|
message.success(data.Result_Desc)
|
||||||
actionRef.current?.reload()
|
actionRef.current?.reload()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
|
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
|
||||||
|
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} currentUser={currentUser} />
|
||||||
|
|
||||||
|
|
||||||
<div style={{
|
<div style={{
|
||||||
// width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
|
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
|
||||||
width: "100%",
|
// width: "100%",
|
||||||
paddingTop: 0,
|
paddingTop: 0,
|
||||||
paddingBottom: 0,
|
paddingBottom: 0,
|
||||||
paddingRight: 0
|
paddingRight: 0
|
||||||
@ -202,19 +295,33 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
expandable={{
|
expandable={{
|
||||||
expandRowByClick: true
|
expandRowByClick: true
|
||||||
}}
|
}}
|
||||||
|
rowKey={(record) => {
|
||||||
|
return `${record?.id}-${record?.code}`
|
||||||
|
}}
|
||||||
scroll={{ x: "100%", y: 'calc(100vh - 400px)' }}
|
scroll={{ x: "100%", y: 'calc(100vh - 400px)' }}
|
||||||
headerTitle={<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}>考核记录管理</span>}
|
headerTitle={<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}>考核记录管理</span>}
|
||||||
search={{ span: 6 }}
|
search={{ span: 6 }}
|
||||||
request={async (params) => {
|
request={async (params) => {
|
||||||
|
// selectedId
|
||||||
console.log('params', params);
|
console.log('params', params);
|
||||||
|
console.log('selectedId', selectedId);
|
||||||
|
if (!(selectedId && selectedId.length > 0)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const req: any = {
|
const req: any = {
|
||||||
startTime: params?.startTime ? `${params?.startTime}T00:00:00` : "",
|
serverPartIds: selectedId && selectedId.length > 0 ? selectedId : [],
|
||||||
endTime: params?.endTime ? `${params?.endTime}T23:59:59` : "",
|
startTime: params?.staticDate ? `${params?.staticDate}` : "",
|
||||||
serverPartId: params?.serverPartId ? params?.serverPartId : ""
|
endTime: params?.staticDate ? `${params?.staticDate}` : "",
|
||||||
|
// serverPartId: params?.serverPartId ? params?.serverPartId : undefined,
|
||||||
|
extend: params?.inspectionType ? [{
|
||||||
|
key: "situation",
|
||||||
|
value: params?.inspectionType
|
||||||
|
}] : undefined
|
||||||
|
|
||||||
}
|
}
|
||||||
console.log('req', req);
|
console.log('req', req);
|
||||||
const data = await handleGetRecordList(req)
|
const data = await handleGetRecordTreeList(req)
|
||||||
console.log('data', data);
|
console.log('data', data);
|
||||||
|
|
||||||
if (data && data.length > 0) {
|
if (data && data.length > 0) {
|
||||||
@ -225,6 +332,10 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
toolbar={{
|
toolbar={{
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
columnsState={{
|
||||||
|
value: columnsStateMap,
|
||||||
|
onChange: setColumnsStateMap,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
</ProTable>
|
</ProTable>
|
||||||
</div>
|
</div>
|
||||||
@ -258,12 +369,92 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
closeIcon={false}
|
closeIcon={false}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
setShowDetail(false)
|
setShowDetail(false)
|
||||||
|
setShowAbnormal(false)
|
||||||
}}
|
}}
|
||||||
open={showDetail}
|
open={showDetail}
|
||||||
destroyOnClose
|
destroyOnClose
|
||||||
width={'60%'}
|
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={() => {
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const req = {
|
||||||
|
...extendObj,
|
||||||
|
person: personObj,
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const data = await handleUpdateExtend(recordDetailRef.current?.formRes.id, { extend: JSON.stringify(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)
|
||||||
|
|
||||||
|
let fileList: any = []
|
||||||
|
if (recordDetailRef.current?.fileList && recordDetailRef.current?.fileList.length > 0) {
|
||||||
|
recordDetailRef.current?.fileList.forEach((item: any) => {
|
||||||
|
fileList.push(item.url)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const req = {
|
||||||
|
...extendObj,
|
||||||
|
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) })
|
||||||
|
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 parentRow={currentRow} show={showDetail} />
|
<RecordDetail onRef={recordDetailRef} parentRow={currentRow} show={showDetail} showError={showAbnormal} />
|
||||||
</Drawer>
|
</Drawer>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,10 +1,21 @@
|
|||||||
import request from "@/utils/request"
|
// import request from "@/utils/request"
|
||||||
|
import request from "@/utils/requestJava"
|
||||||
|
import requestMap from '@/utils/requestMap'
|
||||||
|
|
||||||
// 拿到记录
|
// 拿到记录
|
||||||
export async function handleGetRecordList(params?: any) {
|
export async function handleGetRecordList(params?: any) {
|
||||||
const data = await request.post('/questionnaire-templates/search', params)
|
const data = await request.post('/questionnaire-responses/search/many', params)
|
||||||
if (data.code === 200) {
|
if (data.Result_Code === 100) {
|
||||||
return data.data
|
return data.Result_Data.List
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拿到记录的树型结构
|
||||||
|
export async function handleGetRecordTreeList(params?: any) {
|
||||||
|
const data = await request.post('/questionnaire-responses/tree', params)
|
||||||
|
if (data.Result_Code === 100) {
|
||||||
|
return data.Result_Data.List
|
||||||
}
|
}
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
@ -17,5 +28,33 @@ export async function handleDeleteRecord(params?: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 拿到处理人列表
|
||||||
|
export async function handleGetDealerList(params?: any) {
|
||||||
|
const data = await requestMap.get(`handler_ajax.ashx?SERVERPART_ID=${params?.SERVERPART_ID}&PROVINCE_CODE=${params?.PROVINCE_CODE}&action_type=GetDealerList`)
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除记录
|
||||||
|
export async function handleUpdateExtend(id: any, params?: any) {
|
||||||
|
const data = await request.post(`questionnaire-responses/${id}/extend`, params)
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 上传图片
|
||||||
|
export async function handleUploadFile(params?: any) {
|
||||||
|
const data = await request.post(`/oss/upload`, params)
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拿到考核记录的汇总数据
|
||||||
|
export async function handleGetResponsesSummary(params?: any) {
|
||||||
|
const data = await request.post(`/questionnaire-responses/statistic`, params)
|
||||||
|
if (data.Result_Code === 100) {
|
||||||
|
return data.Result_Data.List
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
674
src/pages/examine/recordSummary/index.tsx
Normal file
674
src/pages/examine/recordSummary/index.tsx
Normal file
@ -0,0 +1,674 @@
|
|||||||
|
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 LeftSelectTree from "@/components/leftSelectTree/leftSelectTree";
|
||||||
|
import { handleGetRecordTreeList, handleGetResponsesSummary } from "../record/service";
|
||||||
|
|
||||||
|
const recordSummary: React.FC<{ currentUser: any }> = (props) => {
|
||||||
|
const { currentUser } = props
|
||||||
|
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
const formRef = useRef<FormInstance>();
|
||||||
|
|
||||||
|
const drawerActionRef = useRef<ActionType>();
|
||||||
|
const drawerFormRef = 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)
|
||||||
|
// 显示类型 1 巡查次数 2 正常 3 异常 4 待处理 5 处理中 6 已处理
|
||||||
|
const [showType, setShowType] = useState<number>(0)
|
||||||
|
// 外侧表格的搜索条件
|
||||||
|
const [searchParams, setSearchParams] = useState<any>()
|
||||||
|
|
||||||
|
// 判断是否点了出现的是异常处理的抽屉
|
||||||
|
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: "staticDate",
|
||||||
|
hideInTable: true,
|
||||||
|
valueType: "dateRange",
|
||||||
|
initialValue: [moment().startOf('M'), moment()],
|
||||||
|
search: {
|
||||||
|
transform: (value: any) => {
|
||||||
|
return {
|
||||||
|
startTime: moment(value[0]).startOf('m').format('YYYY-MM-DD'),
|
||||||
|
endTime: moment(value[1]).format('YYYY-MM-DD')
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fieldProps: {
|
||||||
|
picker: "day",
|
||||||
|
format: 'YYYY-MM-DD',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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 : "-"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: <div style={{ textAlign: 'center' }}>巡查天数</div>,
|
||||||
|
dataIndex: "inspectionNumber",
|
||||||
|
align: 'center',
|
||||||
|
hideInSearch: true,
|
||||||
|
width: 150,
|
||||||
|
ellipsis: true,
|
||||||
|
render: (_, record) => {
|
||||||
|
return record?.template?.id && record?.inspectionNumber > 0 ? <span>
|
||||||
|
<a style={{ color: record?.inspectionNumber === record?.allDay ? '' : 'red' }} onClick={() => {
|
||||||
|
setCurrentRow(record)
|
||||||
|
setShowType(1)
|
||||||
|
setShowDetail(true)
|
||||||
|
}}>
|
||||||
|
{record?.inspectionNumber || '-'}
|
||||||
|
</a> / {record?.allDay}
|
||||||
|
</span > : <span><span style={{ color: record?.inspectionNumber === record?.allDay ? '' : 'red' }}>{record?.inspectionNumber || '-'} </span><span>/ {record?.allDay}</span></span>
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: <div style={{ textAlign: 'center' }}>巡查完成率</div>,
|
||||||
|
dataIndex: "inspectionRate",
|
||||||
|
align: 'center',
|
||||||
|
hideInSearch: true,
|
||||||
|
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> : ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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={() => {
|
||||||
|
setCurrentRow(record)
|
||||||
|
setShowType(2)
|
||||||
|
setShowDetail(true)
|
||||||
|
}}>
|
||||||
|
{record?.normalNumber || '-'}
|
||||||
|
</a> : <span>{record?.normalNumber || '-'}</span>
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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={() => {
|
||||||
|
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>
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: <div style={{ textAlign: 'center' }}>处理中</div>,
|
||||||
|
dataIndex: "processingNumber",
|
||||||
|
align: 'center',
|
||||||
|
hideInSearch: true,
|
||||||
|
width: 150,
|
||||||
|
ellipsis: true,
|
||||||
|
render: (_, record) => {
|
||||||
|
return record?.template?.id && record?.processingNumber > 0 ? <a onClick={() => {
|
||||||
|
setCurrentRow(record)
|
||||||
|
setShowType(5)
|
||||||
|
setShowDetail(true)
|
||||||
|
}}>
|
||||||
|
{record?.processingNumber || '-'}
|
||||||
|
</a> : <span>{record?.processingNumber || '-'}</span>
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: <div style={{ textAlign: 'center' }}>已处理</div>,
|
||||||
|
dataIndex: "processedNumber",
|
||||||
|
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> : ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const drawerColumns: any = [
|
||||||
|
// {
|
||||||
|
// title: "巡查类型",
|
||||||
|
// dataIndex: "inspectionType",
|
||||||
|
// hideInTable: true,
|
||||||
|
// valueType: "select",
|
||||||
|
// valueEnum: {
|
||||||
|
// "1": '异常',
|
||||||
|
// "0": "正常"
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
title: <div style={{ textAlign: 'center' }}>巡查时间</div>,
|
||||||
|
dataIndex: "createdAt",
|
||||||
|
hideInSearch: true,
|
||||||
|
width: 150,
|
||||||
|
ellipsis: true,
|
||||||
|
fixed: 'left',
|
||||||
|
align: 'center',
|
||||||
|
render: (_, record) => {
|
||||||
|
return record?.createdAt ? moment(record?.createdAt).format('YYYY-MM-DD HH:mm:ss') : '-'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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 : "-"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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: res.situation === 1 ? "red" : "" }}>{res.situation === 1 ? '异常' : res.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 extendObj?.uploadResult ? extendObj?.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: "userName",
|
||||||
|
hideInSearch: true,
|
||||||
|
width: 100,
|
||||||
|
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",
|
||||||
|
hideInSearch: true,
|
||||||
|
width: 150,
|
||||||
|
ellipsis: true,
|
||||||
|
align: 'center',
|
||||||
|
render: (_, record) => {
|
||||||
|
let extendObj = record?.extend ? JSON.parse(record?.extend) : ""
|
||||||
|
let imgList = extendObj.imgsList
|
||||||
|
return imgList && imgList.length > 0 ?
|
||||||
|
<Button type="primary" onClick={() => {
|
||||||
|
setShowImgList(imgList)
|
||||||
|
setImagePreviewVisible(true)
|
||||||
|
}}>查看附件</Button> : "-"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
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,
|
||||||
|
defaultExpandAllRows: true
|
||||||
|
}}
|
||||||
|
rowKey={(record) => {
|
||||||
|
return `${record?.id}-${record?.code}`
|
||||||
|
}}
|
||||||
|
scroll={{ x: "100%", y: 'calc(100vh - 400px)' }}
|
||||||
|
headerTitle={<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}>考核记录汇总</span>}
|
||||||
|
search={{ span: 6 }}
|
||||||
|
request={async (params) => {
|
||||||
|
if (!(selectedId && selectedId.length > 0)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const req: any = {
|
||||||
|
serverPartIds: selectedId && selectedId.length > 0 ? selectedId : [],
|
||||||
|
startTime: params?.startTime ? `${params?.startTime}` : "",
|
||||||
|
endTime: params?.endTime ? `${params?.endTime}` : "",
|
||||||
|
// serverPartId: params?.serverPartId ? params?.serverPartId : undefined,
|
||||||
|
extend: params?.inspectionType ? [{
|
||||||
|
key: "situation",
|
||||||
|
value: params?.inspectionType
|
||||||
|
}] : undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
let allDay: number = moment(params?.endTime).diff(params?.startTime, 'd') + 1
|
||||||
|
console.log('allDay', allDay);
|
||||||
|
|
||||||
|
|
||||||
|
setSearchParams(params)
|
||||||
|
|
||||||
|
console.log('req', req);
|
||||||
|
// const data = await handleGetRecordTreeList(req)
|
||||||
|
const data = await handleGetResponsesSummary(req)
|
||||||
|
console.log('dat3a333', data);
|
||||||
|
|
||||||
|
// 处理一下 根据第三层的实际巡查记录 汇总到第二层来
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
|
||||||
|
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 (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);
|
||||||
|
|
||||||
|
})
|
||||||
|
subItem.children = newChildren
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
data.forEach((item: any) => {
|
||||||
|
let inspectionNumberItemSum: number = 0
|
||||||
|
let normalNumberItemSum: number = 0
|
||||||
|
let errorNumberItemSum: number = 0
|
||||||
|
let pendingProcessNumberItemSum: number = 0
|
||||||
|
let processingNumberItemSum: number = 0
|
||||||
|
let processedNumberItemSum: number = 0
|
||||||
|
// 这一次时间段应该查询的次数(天数)
|
||||||
|
let allItemDaySum: number = 0
|
||||||
|
if (item.children && item.children.length > 0) {
|
||||||
|
item.children.forEach((subItem: any) => {
|
||||||
|
let inspectionNumberSum: number = 0
|
||||||
|
let normalNumberSum: number = 0
|
||||||
|
let errorNumberSum: number = 0
|
||||||
|
let pendingProcessNumberSum: number = 0
|
||||||
|
let processingNumberSum: number = 0
|
||||||
|
let processedNumberSum: number = 0
|
||||||
|
// 这一次时间段应该查询的次数(天数)
|
||||||
|
let allSubItemDaySum: number = 0
|
||||||
|
if (subItem.children && subItem.children.length > 0) {
|
||||||
|
subItem.children.forEach((thirdItem: any) => {
|
||||||
|
thirdItem.allDay = allDay
|
||||||
|
allSubItemDaySum += thirdItem.allDay
|
||||||
|
inspectionNumberSum += thirdItem.inspectionNumber
|
||||||
|
normalNumberSum += thirdItem.normalNumber
|
||||||
|
errorNumberSum += thirdItem.errorNumber
|
||||||
|
pendingProcessNumberSum += thirdItem.pendingProcessNumber
|
||||||
|
processingNumberSum += thirdItem.processingNumber
|
||||||
|
processedNumberSum += thirdItem.processedNumber
|
||||||
|
})
|
||||||
|
}
|
||||||
|
subItem.allDay = allSubItemDaySum
|
||||||
|
subItem.inspectionNumber = inspectionNumberSum
|
||||||
|
subItem.normalNumber = normalNumberSum
|
||||||
|
subItem.errorNumber = errorNumberSum
|
||||||
|
subItem.pendingProcessNumber = pendingProcessNumberSum
|
||||||
|
subItem.processingNumber = processingNumberSum
|
||||||
|
subItem.processedNumber = processedNumberSum
|
||||||
|
|
||||||
|
inspectionNumberItemSum += subItem.inspectionNumber
|
||||||
|
normalNumberItemSum += subItem.normalNumber
|
||||||
|
errorNumberItemSum += subItem.errorNumber
|
||||||
|
pendingProcessNumberItemSum += subItem.pendingProcessNumber
|
||||||
|
processingNumberItemSum += subItem.processingNumber
|
||||||
|
processedNumberItemSum += subItem.processedNumber
|
||||||
|
allItemDaySum += subItem.allDay
|
||||||
|
})
|
||||||
|
item.allDay = allItemDaySum
|
||||||
|
item.inspectionNumber = inspectionNumberItemSum
|
||||||
|
item.normalNumber = normalNumberItemSum
|
||||||
|
item.errorNumber = errorNumberItemSum
|
||||||
|
item.pendingProcessNumber = pendingProcessNumberItemSum
|
||||||
|
item.processingNumber = processingNumberItemSum
|
||||||
|
item.processedNumber = processedNumberItemSum
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
console.log('resresres', 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={() => {
|
||||||
|
setCurrentRow(undefined)
|
||||||
|
setShowType(0)
|
||||||
|
setShowDetail(false)
|
||||||
|
setShowImgList([])
|
||||||
|
setImagePreviewVisible(false)
|
||||||
|
}}
|
||||||
|
open={showDetail}
|
||||||
|
destroyOnClose
|
||||||
|
width={'60%'}
|
||||||
|
>
|
||||||
|
<ProTable
|
||||||
|
actionRef={drawerActionRef}
|
||||||
|
formRef={drawerFormRef}
|
||||||
|
columns={drawerColumns}
|
||||||
|
bordered
|
||||||
|
expandable={{
|
||||||
|
expandRowByClick: true,
|
||||||
|
defaultExpandAllRows: true
|
||||||
|
}}
|
||||||
|
rowKey={(record) => {
|
||||||
|
return `${record?.id}-${record?.code}`
|
||||||
|
}}
|
||||||
|
scroll={{ x: "100%", y: 'calc(100vh - 400px)' }}
|
||||||
|
headerTitle={<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}>考核记录管理</span>}
|
||||||
|
search={{ span: 6 }}
|
||||||
|
request={async (params) => {
|
||||||
|
|
||||||
|
console.log('searchParams', searchParams);
|
||||||
|
console.log('currentRow', currentRow);
|
||||||
|
if (!currentRow?.template?.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 ? [
|
||||||
|
{
|
||||||
|
key: "situation",
|
||||||
|
value: 0,
|
||||||
|
},
|
||||||
|
] : showType === 3 ? [
|
||||||
|
{
|
||||||
|
key: "situation",
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
] : showType === 4 ? [
|
||||||
|
{
|
||||||
|
key: "errorStatus",
|
||||||
|
value: 0,
|
||||||
|
}
|
||||||
|
] :
|
||||||
|
showType === 5 ? [
|
||||||
|
{
|
||||||
|
key: "errorStatus",
|
||||||
|
value: 1,
|
||||||
|
}
|
||||||
|
] :
|
||||||
|
showType === 6 ? [
|
||||||
|
{
|
||||||
|
key: "errorStatus",
|
||||||
|
value: 2,
|
||||||
|
}
|
||||||
|
] : undefined
|
||||||
|
}
|
||||||
|
console.log('req', req);
|
||||||
|
const data = await handleGetRecordTreeList(req)
|
||||||
|
console.log('data', data);
|
||||||
|
|
||||||
|
if (data && data.length > 0) {
|
||||||
|
|
||||||
|
// 最后结果直接输出第三层的数据 好看点
|
||||||
|
let res: any = []
|
||||||
|
data.forEach((item: any) => {
|
||||||
|
if (item.children && item.children.length > 0) {
|
||||||
|
item.children.forEach((subItem: any) => {
|
||||||
|
if (subItem.children && subItem.children.length > 0) {
|
||||||
|
subItem.children.forEach((thirdItem: any) => {
|
||||||
|
res.push(thirdItem)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return { data: res, success: true }
|
||||||
|
}
|
||||||
|
return { data: [], success: true }
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
</ProTable>
|
||||||
|
</Drawer>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(({ user }: ConnectState) => ({
|
||||||
|
currentUser: user.data
|
||||||
|
}))(recordSummary);
|
||||||
213
src/pages/setting/menu/components/addMenu.tsx
Normal file
213
src/pages/setting/menu/components/addMenu.tsx
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
import { ProForm, ProFormDigit, ProFormRadio, ProFormText, ProFormTextArea, ProFormTreeSelect } from "@ant-design/pro-components";
|
||||||
|
import { Col, FormInstance, message, Modal, Row } from "antd";
|
||||||
|
import { useRef, useState } from "react";
|
||||||
|
import { connect } from "umi";
|
||||||
|
import { ConnectState } from "@/models/global";
|
||||||
|
import { handleAddMenus, handleGetMenuList } from "../service";
|
||||||
|
|
||||||
|
type DetailProps = {
|
||||||
|
currentUser?: any // 用户详情的公参
|
||||||
|
showDrawer: boolean // 显示悬浮框的判断
|
||||||
|
parentRow?: any // 点击的行 编辑的时候有用
|
||||||
|
setShowDrawer: any // 改变悬浮框现实状态
|
||||||
|
parentTableRef?: any // 父级表格实例
|
||||||
|
}
|
||||||
|
const AddMenu = ({ currentUser, showDrawer, parentRow, setShowDrawer, parentTableRef }: DetailProps) => {
|
||||||
|
console.log('showDrawer', showDrawer);
|
||||||
|
// 表单实例
|
||||||
|
const formRef = useRef<FormInstance>();
|
||||||
|
// 当前的菜单类型
|
||||||
|
const [currentMenuType, setCurrentMenuType] = useState<number>(1)
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
title={parentRow?.id ? '更新菜单' : '新建菜单'}
|
||||||
|
width={600}
|
||||||
|
open={showDrawer}
|
||||||
|
destroyOnClose
|
||||||
|
onOk={() => {
|
||||||
|
formRef.current?.validateFields().then(async (res: any) => {
|
||||||
|
console.log('res', res);
|
||||||
|
const req: any = {
|
||||||
|
parentId: res.parentId || 1,
|
||||||
|
menuCode: res.menuCode,
|
||||||
|
menuName: res.menuName,
|
||||||
|
menuIcon: res.menuIcon || "",
|
||||||
|
menuPath: res.menuPath || "",
|
||||||
|
component: "",
|
||||||
|
permission: "",
|
||||||
|
menuType: res.menuType,
|
||||||
|
sortOrder: res.sortOrder,
|
||||||
|
hidden: res.hidden === 1 ? false : res.hidden === 2 ? true : '',
|
||||||
|
operator: currentUser.adminName
|
||||||
|
}
|
||||||
|
const data = await handleAddMenus(req)
|
||||||
|
console.log('datadsa', data);
|
||||||
|
if (data.code === 200) {
|
||||||
|
message.success(data.message)
|
||||||
|
if (parentTableRef) {
|
||||||
|
parentTableRef.current.reload()
|
||||||
|
}
|
||||||
|
|
||||||
|
formRef.current?.resetFields()
|
||||||
|
setShowDrawer(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
onCancel={() => {
|
||||||
|
setShowDrawer(false)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProForm
|
||||||
|
formRef={formRef}
|
||||||
|
submitter={false}
|
||||||
|
layout="horizontal"
|
||||||
|
labelCol={{ span: 6 }}
|
||||||
|
>
|
||||||
|
<Row>
|
||||||
|
<Col span={24}>
|
||||||
|
<ProFormText
|
||||||
|
label={currentMenuType === 1 ? "菜单名称" : "模块名称"}
|
||||||
|
name={"menuName"}
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: `请输入${currentMenuType === 1 ? '菜单' : '模块'}名称` }
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
|
||||||
|
<Col span={24}>
|
||||||
|
<ProFormText
|
||||||
|
label={currentMenuType === 1 ? "菜单编码" : "模块编码"}
|
||||||
|
name={"menuCode"}
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: `请输入${currentMenuType === 1 ? '菜单' : '模块'}编码` }
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
|
||||||
|
<Col span={24}>
|
||||||
|
<ProFormTreeSelect
|
||||||
|
label={"上级菜单"}
|
||||||
|
name={"parentId"}
|
||||||
|
request={async () => {
|
||||||
|
const req: any = {
|
||||||
|
|
||||||
|
}
|
||||||
|
const data = await handleGetMenuList()
|
||||||
|
let res: any = []
|
||||||
|
if (data && data.length > 0) {
|
||||||
|
res = data
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}}
|
||||||
|
fieldProps={{
|
||||||
|
fieldNames: {
|
||||||
|
label: "menuName",
|
||||||
|
value: "id"
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
|
||||||
|
{
|
||||||
|
currentMenuType === 1 ?
|
||||||
|
<Col span={24}>
|
||||||
|
<ProFormText
|
||||||
|
name="menuIcon"
|
||||||
|
label="菜单图标"
|
||||||
|
placeholder="请输入菜单图标字段"
|
||||||
|
initialValue={"<ProfileOutlined />"}
|
||||||
|
fieldProps={
|
||||||
|
{
|
||||||
|
addonAfter: <a href='https://ant.design/components/icon-cn/' target='_blank'>去复制</a>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/>
|
||||||
|
</Col> : ""
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
currentMenuType === 2 ?
|
||||||
|
<Col span={24}>
|
||||||
|
<ProFormText
|
||||||
|
name="menuPath"
|
||||||
|
label="模块地址"
|
||||||
|
placeholder="请输入模块地址"
|
||||||
|
/>
|
||||||
|
</Col> : ''
|
||||||
|
}
|
||||||
|
|
||||||
|
<Col span={24}>
|
||||||
|
<ProFormDigit
|
||||||
|
name="sortOrder"
|
||||||
|
label="索引"
|
||||||
|
placeholder="请输入索引"
|
||||||
|
|
||||||
|
min={0}
|
||||||
|
max={9999}
|
||||||
|
fieldProps={{ precision: 0 }}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
|
||||||
|
<Col span={24}>
|
||||||
|
<ProFormRadio.Group
|
||||||
|
name="hidden"
|
||||||
|
label="状态"
|
||||||
|
initialValue={1}
|
||||||
|
|
||||||
|
options={[
|
||||||
|
{
|
||||||
|
label: '有效',
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '隐藏',
|
||||||
|
value: 2,
|
||||||
|
}]}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
|
||||||
|
<Col span={24}>
|
||||||
|
<ProFormRadio.Group
|
||||||
|
name="menuType"
|
||||||
|
label="菜单类型"
|
||||||
|
initialValue={1}
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: "请选择菜单类型" }
|
||||||
|
]}
|
||||||
|
options={[
|
||||||
|
{
|
||||||
|
label: '菜单',
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '模块',
|
||||||
|
value: 2,
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
fieldProps={{
|
||||||
|
onChange: (e: any) => {
|
||||||
|
console.log('e', e);
|
||||||
|
setCurrentMenuType(Number(e.target.value))
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
|
||||||
|
{/* <Col span={24}>
|
||||||
|
<ProFormTextArea
|
||||||
|
name="DESC"
|
||||||
|
label="备注说明"
|
||||||
|
placeholder="请输入说明"
|
||||||
|
/>
|
||||||
|
</Col> */}
|
||||||
|
</Row>
|
||||||
|
</ProForm>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default connect(({ user }: ConnectState) => ({
|
||||||
|
currentUser: user.data
|
||||||
|
}))(AddMenu);
|
||||||
191
src/pages/setting/menu/index.tsx
Normal file
191
src/pages/setting/menu/index.tsx
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
|
||||||
|
import { ActionType, FormInstance, ProTable } from "@ant-design/pro-components";
|
||||||
|
import { Button, Space } from "antd";
|
||||||
|
import { useRef, useState } from "react";
|
||||||
|
import { connect } from "umi";
|
||||||
|
import { handleGetMenuList } from "./service";
|
||||||
|
import AddMenu from "./components/addMenu";
|
||||||
|
import moment from "moment";
|
||||||
|
|
||||||
|
const menuIndex: React.FC<{ currentUser: any }> = (props) => {
|
||||||
|
const { currentUser } = props
|
||||||
|
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
const formRef = useRef<FormInstance>();
|
||||||
|
// 打开新增的悬浮框
|
||||||
|
const [openAddModal, setOpenAddModal] = useState<boolean>(false)
|
||||||
|
// 行数据
|
||||||
|
const [currentRow, setCurrentRow] = useState<any>()
|
||||||
|
// 表格默认隐藏字段
|
||||||
|
const [columnsStateMap, setColumnsStateMap] = useState<any>({
|
||||||
|
menuCode: { show: false },
|
||||||
|
createdAt: { show: false },
|
||||||
|
})
|
||||||
|
// 表格组件
|
||||||
|
const columns: any = [
|
||||||
|
{
|
||||||
|
title: <div style={{ textAlign: 'center' }}>菜单名称</div>,
|
||||||
|
dataIndex: "menuName",
|
||||||
|
width: 300,
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: <div style={{ textAlign: 'center' }}>菜单编号</div>,
|
||||||
|
dataIndex: "menuCode",
|
||||||
|
width: 300,
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: <div style={{ textAlign: 'center' }}>菜单图标</div>,
|
||||||
|
dataIndex: "menuIcon",
|
||||||
|
width: 120,
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: <div style={{ textAlign: 'center' }}>菜单索引</div>,
|
||||||
|
dataIndex: "sortOrder",
|
||||||
|
align: 'center',
|
||||||
|
width: 100,
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: <div style={{ textAlign: 'center' }}>状态</div>,
|
||||||
|
dataIndex: 'hidden',
|
||||||
|
hideInSearch: true,
|
||||||
|
width: 100,
|
||||||
|
render: (_, record) => {
|
||||||
|
return record?.hidden ? '隐藏' : '显示'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: <div style={{ textAlign: 'center' }}>创建时间</div>,
|
||||||
|
dataIndex: 'createdAt',
|
||||||
|
width: 200,
|
||||||
|
hideInSearch: true,
|
||||||
|
render: (_, record) => {
|
||||||
|
return record?.createdAt ? moment(record?.createdAt).format('YYYY-MM-DD HH:mm:ss') : ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: <div style={{ textAlign: 'center' }}>操作</div>,
|
||||||
|
dataIndex: 'option',
|
||||||
|
valueType: 'option',
|
||||||
|
hideInDescriptions: true,
|
||||||
|
width: 100,
|
||||||
|
render: (_, record) => {
|
||||||
|
return <Space>
|
||||||
|
|
||||||
|
</Space>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
// 表格子集的columns
|
||||||
|
const childrenColumns: any = [
|
||||||
|
{
|
||||||
|
title: "模块名称",
|
||||||
|
dataIndex: "menuName",
|
||||||
|
width: 300,
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "模块地址",
|
||||||
|
dataIndex: "",
|
||||||
|
width: 120,
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "模块索引",
|
||||||
|
dataIndex: "id",
|
||||||
|
width: 180,
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '状态',
|
||||||
|
dataIndex: 'hidden',
|
||||||
|
hideInSearch: true,
|
||||||
|
width: 180,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '说明',
|
||||||
|
dataIndex: 'desc',
|
||||||
|
width: 200,
|
||||||
|
hideInSearch: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'option',
|
||||||
|
valueType: 'option',
|
||||||
|
hideInDescriptions: true,
|
||||||
|
width: 260,
|
||||||
|
render: (_, record) => { }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// 模块列表
|
||||||
|
const expandedRowRender = (data: any) => {
|
||||||
|
console.log('data', data);
|
||||||
|
|
||||||
|
return (data && data.length > 0 ?
|
||||||
|
<ProTable
|
||||||
|
rowKey="id"
|
||||||
|
columns={childrenColumns}
|
||||||
|
search={false}
|
||||||
|
headerTitle={false}
|
||||||
|
options={false}
|
||||||
|
dataSource={data}
|
||||||
|
pagination={false}
|
||||||
|
/>
|
||||||
|
: [])
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<ProTable
|
||||||
|
actionRef={actionRef}
|
||||||
|
formRef={formRef}
|
||||||
|
columns={columns}
|
||||||
|
bordered
|
||||||
|
rowKey={(record) => {
|
||||||
|
return `${record?.id}`
|
||||||
|
}}
|
||||||
|
scroll={{ x: "100%", y: 'calc(100vh - 400px)' }}
|
||||||
|
headerTitle={<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}>菜单管理</span>}
|
||||||
|
request={async (params) => {
|
||||||
|
const req: any = {
|
||||||
|
|
||||||
|
}
|
||||||
|
const data = await handleGetMenuList()
|
||||||
|
console.log('data', data);
|
||||||
|
if (data && data.length > 0) {
|
||||||
|
return { data, success: true }
|
||||||
|
}
|
||||||
|
return { data: [], success: true }
|
||||||
|
}}
|
||||||
|
toolbar={{
|
||||||
|
actions: [
|
||||||
|
<Button type="primary" onClick={(e) => {
|
||||||
|
setOpenAddModal(true)
|
||||||
|
}}>
|
||||||
|
新增分类
|
||||||
|
</Button>
|
||||||
|
]
|
||||||
|
}}
|
||||||
|
expandable={{
|
||||||
|
expandRowByClick: true,
|
||||||
|
// expandedRowRender
|
||||||
|
}}
|
||||||
|
columnsState={{
|
||||||
|
value: columnsStateMap,
|
||||||
|
onChange: setColumnsStateMap,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
<AddMenu currentUser={currentUser} showDrawer={openAddModal} parentRow={currentRow} setShowDrawer={setOpenAddModal} parentTableRef={actionRef} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(({ user }: ConnectState) => ({
|
||||||
|
currentUser: user.data
|
||||||
|
}))(menuIndex);
|
||||||
16
src/pages/setting/menu/service.ts
Normal file
16
src/pages/setting/menu/service.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import request from "@/utils/request"
|
||||||
|
|
||||||
|
// 拿到菜单列表数据
|
||||||
|
export async function handleGetMenuList(params?: any) {
|
||||||
|
const data = await request.get('/menus/getAll', { params })
|
||||||
|
if (data.code === 200) {
|
||||||
|
return data.data
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增菜单
|
||||||
|
export async function handleAddMenus(params?: any) {
|
||||||
|
const data = await request.post('/menus', params)
|
||||||
|
return data
|
||||||
|
}
|
||||||
@ -12,7 +12,9 @@ const { UMI_APP_BASEURL } = process.env;
|
|||||||
|
|
||||||
// const instance = axios.create({ baseURL: 'http://home.robot-z.cn:7001/' });
|
// const instance = axios.create({ baseURL: 'http://home.robot-z.cn:7001/' });
|
||||||
// 修改baseURL为完整的API地址,确保在生产环境中正确访问
|
// 修改baseURL为完整的API地址,确保在生产环境中正确访问
|
||||||
const instance = axios.create({ baseURL: 'https://es.robot-z.cn' });
|
// const instance = axios.create({ baseURL: 'https://es.robot-z.cn' });
|
||||||
|
|
||||||
|
const instance = axios.create({ baseURL: 'https://es.eshangtech.com' });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
159
src/utils/requestJava.ts
Normal file
159
src/utils/requestJava.ts
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import { getDvaApp } from 'umi';
|
||||||
|
import { notification } from 'antd';
|
||||||
|
import type { AxiosRequestHeaders } from 'axios/index';
|
||||||
|
import CryptoJS from "crypto-js";
|
||||||
|
|
||||||
|
const { UMI_APP_BASEURL } = process.env;
|
||||||
|
|
||||||
|
// const instance = axios.create({ baseURL: UMI_APP_BASEURL });
|
||||||
|
// const instance = axios.create({ baseURL: 'https://api.eshangtech.com/EShangApiMain' });
|
||||||
|
|
||||||
|
|
||||||
|
// const instance = axios.create({ baseURL: 'http://home.robot-z.cn:7001/' });
|
||||||
|
// 修改baseURL为完整的API地址,确保在生产环境中正确访问
|
||||||
|
// const instance = axios.create({ baseURL: 'https://es.robot-z.cn' });
|
||||||
|
|
||||||
|
const instance = axios.create({ baseURL: 'http://10.104.1.161:8070/platform' });
|
||||||
|
|
||||||
|
instance.interceptors.request.use(
|
||||||
|
(config) => {
|
||||||
|
// 对data数据进行加密
|
||||||
|
// if (config.data) {
|
||||||
|
// config.data = preprocessData(JSON.stringify(config.data)); // 调用预处理函数
|
||||||
|
//
|
||||||
|
|
||||||
|
const isUpload = config.url?.includes("/oss/upload");
|
||||||
|
|
||||||
|
let token = localStorage.getItem('Authorization') || ''
|
||||||
|
|
||||||
|
config.headers = {
|
||||||
|
...config.headers,
|
||||||
|
Authorization: token ? `Bearer ${token}` : "",
|
||||||
|
"Content-Type": isUpload ? "multipart/form-data" : "application/json;charset=utf-8",
|
||||||
|
} as AxiosRequestHeaders;
|
||||||
|
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
(error) => Promise.reject(error),
|
||||||
|
);
|
||||||
|
|
||||||
|
instance.interceptors.response.use(
|
||||||
|
//状态码为2xx的时候执行
|
||||||
|
(response) => {
|
||||||
|
const { data } = response;
|
||||||
|
|
||||||
|
if (data.Result_Code !== 100) {
|
||||||
|
notification.error({
|
||||||
|
message: data.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const timestamp = getFormattedDate()
|
||||||
|
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
//状态码不是2xx的时候执行
|
||||||
|
(error) => {
|
||||||
|
const { response } = error;
|
||||||
|
|
||||||
|
if (response && response.status === 401) {
|
||||||
|
// // 清除本地存储的token
|
||||||
|
// localStorage.removeItem('Authorization');
|
||||||
|
// // 重定向到登录页
|
||||||
|
// window.location.href = '/user/login';
|
||||||
|
// notification.error({
|
||||||
|
// message: response?.data?.message || '请求失败',
|
||||||
|
// description: error.message
|
||||||
|
// });
|
||||||
|
} else {
|
||||||
|
notification.error({
|
||||||
|
message: response?.data?.message || '请求失败',
|
||||||
|
description: error.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.reject({
|
||||||
|
Result_Code: response?.status || 500,
|
||||||
|
Result_Desc: response?.data?.message || '请求失败'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// 加密
|
||||||
|
const encryptAESECB = (data: string, key: string) => {
|
||||||
|
// const cipher = CryptoJS.createCipheriv('aes-128-ecb', key, null); // ECB 模式不需要 IV
|
||||||
|
const newKey = CryptoJS.enc.Utf8.parse(key); // 密钥必须是 16 字节
|
||||||
|
const cipher = CryptoJS.AES.encrypt(data, newKey, {
|
||||||
|
mode: CryptoJS.mode.ECB,
|
||||||
|
padding: CryptoJS.pad.Pkcs7
|
||||||
|
});
|
||||||
|
let encrypted = cipher.ciphertext.toString(CryptoJS.enc.Hex);
|
||||||
|
// let encrypted = cipher.update(data, 'utf8', 'hex');
|
||||||
|
// encrypted += cipher.final('hex');
|
||||||
|
return encrypted;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解密
|
||||||
|
const decryptAESECB = (data: string, key: string) => {
|
||||||
|
// const decipher = CryptoJS.createDecipheriv('aes-128-ecb', key, null);
|
||||||
|
// let decrypted = decipher.update(data, 'hex', 'utf8');
|
||||||
|
// decrypted += decipher.final('utf8');
|
||||||
|
const newKey = CryptoJS.enc.Utf8.parse(key);
|
||||||
|
|
||||||
|
const encryptedData = CryptoJS.enc.Hex.parse(data);
|
||||||
|
|
||||||
|
// 解密操作
|
||||||
|
const decrypted = CryptoJS.AES.decrypt({ ciphertext: encryptedData }, newKey, {
|
||||||
|
mode: CryptoJS.mode.ECB, // ECB 模式
|
||||||
|
padding: CryptoJS.pad.Pkcs7 // PKCS7 填充方式
|
||||||
|
});
|
||||||
|
// 将解密后的结果转为 UTF-8 字符串
|
||||||
|
const decryptedText = decrypted.toString(CryptoJS.enc.Utf8);
|
||||||
|
return decryptedText;
|
||||||
|
}
|
||||||
|
|
||||||
|
// md5 签名
|
||||||
|
const md5 = (key: string, data: string, timestamp: string) => {
|
||||||
|
const text = "s" + key + data + timestamp;
|
||||||
|
return CryptoJS.MD5(text).toString(CryptoJS.enc.Hex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成签名戳
|
||||||
|
const getFormattedDate = () => {
|
||||||
|
const date = new Date();
|
||||||
|
const year = date.getFullYear(); // 获取年份 (yyyy)
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, '0'); // 获取月份 (MM)
|
||||||
|
const day = String(date.getDate()).padStart(2, '0'); // 获取日期 (dd)
|
||||||
|
const hours = String(date.getHours()).padStart(2, '0'); // 获取小时 (HH)
|
||||||
|
return `es0${year}${month}${day}${hours}0es`; // 拼接成 yyyyMMddHH 格式
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加密方法
|
||||||
|
const preprocessData = (data: string) => {
|
||||||
|
console.log('data', data);
|
||||||
|
// YYYYMMDD
|
||||||
|
let timestamp = getFormattedDate()
|
||||||
|
console.log('timestamp', timestamp);
|
||||||
|
// 秒为单位的时间戳
|
||||||
|
let timeSecond = parseInt((new Date().getTime() / 1000).toString())
|
||||||
|
console.log('timeSecond', timeSecond);
|
||||||
|
// 数据的加密
|
||||||
|
let encryptionData = encryptAESECB(data, timestamp)
|
||||||
|
console.log('encryptionData', encryptionData);
|
||||||
|
// md5签名方法
|
||||||
|
let md5Data = md5(timestamp, encryptionData, timestamp)
|
||||||
|
console.log('md5Data', md5Data);
|
||||||
|
|
||||||
|
let res = {
|
||||||
|
data: encryptionData,
|
||||||
|
timestamp: timeSecond,
|
||||||
|
sign: md5Data
|
||||||
|
}
|
||||||
|
console.log('res', res);
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
export default instance;
|
||||||
158
src/utils/requestMap.ts
Normal file
158
src/utils/requestMap.ts
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import { getDvaApp } from 'umi';
|
||||||
|
import { notification } from 'antd';
|
||||||
|
import type { AxiosRequestHeaders } from 'axios/index';
|
||||||
|
import CryptoJS from "crypto-js";
|
||||||
|
|
||||||
|
const { UMI_APP_BASEURL } = process.env;
|
||||||
|
|
||||||
|
// const instance = axios.create({ baseURL: UMI_APP_BASEURL });
|
||||||
|
// const instance = axios.create({ baseURL: 'https://api.eshangtech.com/EShangApiMain' });
|
||||||
|
|
||||||
|
|
||||||
|
// const instance = axios.create({ baseURL: 'http://home.robot-z.cn:7001/' });
|
||||||
|
// 修改baseURL为完整的API地址,确保在生产环境中正确访问
|
||||||
|
const instance = axios.create({ baseURL: 'https://mp.eshangtech.com/Coop.Merchant/Handler/' });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
instance.interceptors.request.use(
|
||||||
|
(config) => {
|
||||||
|
// 对data数据进行加密
|
||||||
|
// if (config.data) {
|
||||||
|
// config.data = preprocessData(JSON.stringify(config.data)); // 调用预处理函数
|
||||||
|
// }
|
||||||
|
console.log('config', config);
|
||||||
|
|
||||||
|
const isUpload = config.url?.includes("/oss/upload");
|
||||||
|
|
||||||
|
config.headers = {
|
||||||
|
...config.headers,
|
||||||
|
Authorization: `Bearer ${localStorage.getItem('Authorization') || ''}`,
|
||||||
|
"Content-Type": "text/plain; charset=utf-8",
|
||||||
|
} as AxiosRequestHeaders;
|
||||||
|
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
(error) => Promise.reject(error),
|
||||||
|
);
|
||||||
|
|
||||||
|
instance.interceptors.response.use(
|
||||||
|
//状态码为2xx的时候执行
|
||||||
|
(response) => {
|
||||||
|
const { data } = response;
|
||||||
|
|
||||||
|
if (data.code !== 200) {
|
||||||
|
// notification.error({
|
||||||
|
// message: data.message,
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
const timestamp = getFormattedDate()
|
||||||
|
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
//状态码不是2xx的时候执行
|
||||||
|
(error) => {
|
||||||
|
const { response } = error;
|
||||||
|
|
||||||
|
if (response && response.status === 401) {
|
||||||
|
// // 清除本地存储的token
|
||||||
|
// localStorage.removeItem('Authorization');
|
||||||
|
// // 重定向到登录页
|
||||||
|
// window.location.href = '/user/login';
|
||||||
|
// notification.error({
|
||||||
|
// message: response?.data?.message || '请求失败',
|
||||||
|
// description: error.message
|
||||||
|
// });
|
||||||
|
} else {
|
||||||
|
// notification.error({
|
||||||
|
// message: response?.data?.message || '请求失败',
|
||||||
|
// description: error.message
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.reject({
|
||||||
|
code: response?.status || 500,
|
||||||
|
message: response?.data?.message || '请求失败'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// 加密
|
||||||
|
const encryptAESECB = (data: string, key: string) => {
|
||||||
|
// const cipher = CryptoJS.createCipheriv('aes-128-ecb', key, null); // ECB 模式不需要 IV
|
||||||
|
const newKey = CryptoJS.enc.Utf8.parse(key); // 密钥必须是 16 字节
|
||||||
|
const cipher = CryptoJS.AES.encrypt(data, newKey, {
|
||||||
|
mode: CryptoJS.mode.ECB,
|
||||||
|
padding: CryptoJS.pad.Pkcs7
|
||||||
|
});
|
||||||
|
let encrypted = cipher.ciphertext.toString(CryptoJS.enc.Hex);
|
||||||
|
// let encrypted = cipher.update(data, 'utf8', 'hex');
|
||||||
|
// encrypted += cipher.final('hex');
|
||||||
|
return encrypted;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解密
|
||||||
|
const decryptAESECB = (data: string, key: string) => {
|
||||||
|
// const decipher = CryptoJS.createDecipheriv('aes-128-ecb', key, null);
|
||||||
|
// let decrypted = decipher.update(data, 'hex', 'utf8');
|
||||||
|
// decrypted += decipher.final('utf8');
|
||||||
|
const newKey = CryptoJS.enc.Utf8.parse(key);
|
||||||
|
|
||||||
|
const encryptedData = CryptoJS.enc.Hex.parse(data);
|
||||||
|
|
||||||
|
// 解密操作
|
||||||
|
const decrypted = CryptoJS.AES.decrypt({ ciphertext: encryptedData }, newKey, {
|
||||||
|
mode: CryptoJS.mode.ECB, // ECB 模式
|
||||||
|
padding: CryptoJS.pad.Pkcs7 // PKCS7 填充方式
|
||||||
|
});
|
||||||
|
// 将解密后的结果转为 UTF-8 字符串
|
||||||
|
const decryptedText = decrypted.toString(CryptoJS.enc.Utf8);
|
||||||
|
return decryptedText;
|
||||||
|
}
|
||||||
|
|
||||||
|
// md5 签名
|
||||||
|
const md5 = (key: string, data: string, timestamp: string) => {
|
||||||
|
const text = "s" + key + data + timestamp;
|
||||||
|
return CryptoJS.MD5(text).toString(CryptoJS.enc.Hex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成签名戳
|
||||||
|
const getFormattedDate = () => {
|
||||||
|
const date = new Date();
|
||||||
|
const year = date.getFullYear(); // 获取年份 (yyyy)
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, '0'); // 获取月份 (MM)
|
||||||
|
const day = String(date.getDate()).padStart(2, '0'); // 获取日期 (dd)
|
||||||
|
const hours = String(date.getHours()).padStart(2, '0'); // 获取小时 (HH)
|
||||||
|
return `es0${year}${month}${day}${hours}0es`; // 拼接成 yyyyMMddHH 格式
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加密方法
|
||||||
|
const preprocessData = (data: string) => {
|
||||||
|
console.log('data', data);
|
||||||
|
// YYYYMMDD
|
||||||
|
let timestamp = getFormattedDate()
|
||||||
|
console.log('timestamp', timestamp);
|
||||||
|
// 秒为单位的时间戳
|
||||||
|
let timeSecond = parseInt((new Date().getTime() / 1000).toString())
|
||||||
|
console.log('timeSecond', timeSecond);
|
||||||
|
// 数据的加密
|
||||||
|
let encryptionData = encryptAESECB(data, timestamp)
|
||||||
|
console.log('encryptionData', encryptionData);
|
||||||
|
// md5签名方法
|
||||||
|
let md5Data = md5(timestamp, encryptionData, timestamp)
|
||||||
|
console.log('md5Data', md5Data);
|
||||||
|
|
||||||
|
let res = {
|
||||||
|
data: encryptionData,
|
||||||
|
timestamp: timeSecond,
|
||||||
|
sign: md5Data
|
||||||
|
}
|
||||||
|
console.log('res', res);
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
export default instance;
|
||||||
Loading…
x
Reference in New Issue
Block a user