🐛 fix(模块): 修复了一些 bug

This commit is contained in:
cclu 2025-03-14 18:58:30 +08:00
parent facf50c0ae
commit e1d57f300a
20 changed files with 699 additions and 92 deletions

View File

@ -9,9 +9,15 @@ export default {
], ],
proxy, proxy,
dva: {}, dva: {},
title: 'UMI4 Admin', base: '/cloudNew/',
publicPath: '/cloudNew/',
outputPath: 'dist', // 打包输出目录默认是dist
title: '驿商云平台',
favicons: [ favicons: [
'/favicon.svg' '/favicon.ico'
], ],
routes: router routes: router,
history: {
type: 'browser' // 使用browser history模式配合IIS的URL重写规则
}
}; };

View File

@ -37,7 +37,7 @@ export default [
}, },
{ {
path: '/examine/modal', path: '/examine/modal',
name: '考核模版管理', name: '考核点位管理',
component: "@/pages/examine/modal/index", component: "@/pages/examine/modal/index",
}, },
{ {

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

37
public/web.config Normal file
View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Handle History Mode and custom 404/500" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="./" />
</rule>
</rules>
</rewrite>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="2147483647" maxQueryString="2147483647"/>
</requestFiltering>
</security>
<httpProtocol>
<customHeaders>
<add name="X-UA-Compatible" value="IE=Edge"/>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE" />
</customHeaders>
</httpProtocol>
<modules runAllManagedModulesForAllRequests="true" />
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
</configuration>

View File

@ -191,7 +191,7 @@ const BasicLayout: FC<{ user: UserModelState, global: ProfileModelState, dispatc
SYSTEMMODULE_DESC: "", SYSTEMMODULE_DESC: "",
guid: "4", guid: "4",
hideInMenu: false, hideInMenu: false,
name: "考核模版管理", name: "考核点位管理",
path: "/examine/modal", path: "/examine/modal",
}, },
{ {

View File

@ -211,12 +211,14 @@ const UserModel: UserModelType = {
console.log('userInfoRes', userInfoRes); console.log('userInfoRes', userInfoRes);
menuRes.data = [{ menuRes.data = [
{
path: '/standard/index', path: '/standard/index',
redirect: '', redirect: '',
name: '生成标准页面', name: '生成标准页面',
component: "@/pages/standard/index", component: "@/pages/standard/index",
}, { },
{
path: '/examine', path: '/examine',
redirect: '', redirect: '',
name: '走动式管理', name: '走动式管理',
@ -243,7 +245,8 @@ const UserModel: UserModelType = {
} }
] ]
},] },
]
let indexAllMenuItemByPath: any = [] let indexAllMenuItemByPath: any = []
let indexValidMenuItemByPath: any = [] let indexValidMenuItemByPath: any = []
if (menuRes.data && menuRes.data.length > 0) { if (menuRes.data && menuRes.data.length > 0) {
@ -254,7 +257,7 @@ const UserModel: UserModelType = {
//在登录完获取菜单数据之后做是否需要重定向的操作 //在登录完获取菜单数据之后做是否需要重定向的操作
yield call( yield call(
handleRedirect, handleRedirect,
window.location.pathname === '/user/login', window.location.pathname === '/cloudNew/user/login',
indexAllMenuItemByPath, indexAllMenuItemByPath,
indexValidMenuItemByPath, indexValidMenuItemByPath,
); );
@ -307,7 +310,19 @@ const UserModel: UserModelType = {
//当前页面不是登录页时,才进行重定向 //当前页面不是登录页时,才进行重定向
if (window.location.pathname !== '/user/login') { if (window.location.pathname !== '/user/login') {
const redirectValue = `${window.location.pathname}${window.location.search}`; // 只获取路径部分不包含查询参数避免redirect参数累积
let redirectValue = window.location.pathname;
// 检查是否有base路径重复问题
if (redirectValue.startsWith('/') && redirectValue.indexOf('/', 1) !== -1) {
const firstSlashAfterRoot = redirectValue.indexOf('/', 1);
const possiblePrefix = redirectValue.substring(0, firstSlashAfterRoot);
// 检查是否有重复的路径前缀
if (redirectValue.indexOf(possiblePrefix, firstSlashAfterRoot) === firstSlashAfterRoot) {
redirectValue = redirectValue.substring(firstSlashAfterRoot);
}
}
history.push(`/user/login?redirect=${encodeURIComponent(redirectValue)}`); history.push(`/user/login?redirect=${encodeURIComponent(redirectValue)}`);
} }
}, },

View File

@ -22,6 +22,9 @@ const examineIndex: React.FC<{ currentUser: any }> = (props) => {
const [openAddModal, setOpenAddModal] = useState<boolean>(false) const [openAddModal, setOpenAddModal] = useState<boolean>(false)
// 当前行数据 // 当前行数据
const [currentRow, setCurrentRow] = useState<any>() const [currentRow, setCurrentRow] = useState<any>()
const [columnsStateMap, setColumnsStateMap] = useState<any>({
operator: { show: false }
})
const columns: any = [ const columns: any = [
{ {
@ -73,10 +76,22 @@ const examineIndex: React.FC<{ currentUser: any }> = (props) => {
return record?.updatedAt ? moment(record?.updatedAt).format('YYYY-MM-DD HH:mm:ss') : '-' return record?.updatedAt ? moment(record?.updatedAt).format('YYYY-MM-DD HH:mm:ss') : '-'
} }
}, },
{
title: "操作人",
dataIndex: "operator",
ellipsis: true,
align: 'center',
width: 200,
hideInSearch: true,
render: (_: any, record: { status: any; }) => {
return record?.operator ? record?.operator : '-'
}
},
{ {
title: '操作', title: '操作',
dataIndex: 'option', dataIndex: 'option',
align: 'center', align: 'center',
fixed: "right",
hideInSearch: true, hideInSearch: true,
width: 150, width: 150,
render: (_: any, record: any) => { render: (_: any, record: any) => {
@ -144,7 +159,7 @@ const examineIndex: React.FC<{ currentUser: any }> = (props) => {
rowKey={(record) => { rowKey={(record) => {
return `${record?.id}` return `${record?.id}`
}} }}
scroll={{ 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) => {
@ -167,6 +182,10 @@ const examineIndex: React.FC<{ currentUser: any }> = (props) => {
</Button> </Button>
] ]
}} }}
columnsState={{
value: columnsStateMap,
onChange: setColumnsStateMap,
}}
/> />
</div> </div>
</div> </div>

View File

@ -2,7 +2,7 @@ import request from "@/utils/request"
// 拿到类别列表接口 // 拿到类别列表接口
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', {params})
if (data.code === 200) { if (data.code === 200) {
return data.data return data.data
} }

View File

@ -1,7 +1,7 @@
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, ProFormList, ProFormSelect, ProFormSwitch, ProFormText, ProFormTextArea, ProTable } from "@ant-design/pro-components";
import { Button, Col, message, Modal, Popconfirm, Row, Space } from "antd"; import { Button, Col, message, Modal, Popconfirm, Row, Space, Image } from "antd";
import moment from "moment"; import moment from "moment";
import { useRef, useState } from "react"; import { useRef, useState } from "react";
import { connect } from "umi"; import { connect } from "umi";
@ -10,6 +10,7 @@ import { handleGetExamineTypeTreeList } from "../index/service";
import QRCode from 'qrcode'; import QRCode from 'qrcode';
import { base64ToFile } from "@/utils/publicMethods"; import { base64ToFile } from "@/utils/publicMethods";
const examineModal: React.FC<{ currentUser: any }> = (props) => { const examineModal: React.FC<{ currentUser: any }> = (props) => {
const { currentUser } = props const { currentUser } = props
@ -41,13 +42,24 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
// 选择的问题列表的id // 选择的问题列表的id
const [selectedQuestionId, setSelectedQuestionId] = useState<any>() const [selectedQuestionId, setSelectedQuestionId] = useState<any>()
// 显示的附件数据
const [showImgList, setShowImgList] = useState<string[]>([])
// 预览图片
const [imagePreviewVisible, setImagePreviewVisible] = useState<boolean>(false)
// 预览的索引
const [previewIndex, setPreviewIndex] = useState<number>(0)
const [columnsStateMap, setColumnsStateMap] = useState<any>({
updatedAt: { show: false },
createdAt: { show: false },
operator: { show: false },
})
const columns: any = [ const columns: any = [
{ {
title: <div style={{ textAlign: 'center' }}></div>, title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "serverPartName", dataIndex: "serverPartName",
hideInSearch: true, hideInSearch: true,
width: 200, width: 150,
ellipsis: true ellipsis: true
}, },
{ {
@ -57,6 +69,43 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
width: 200, width: 200,
ellipsis: true ellipsis: true
}, },
{
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 += `${subIndex > 0 ? '' : ''}选项${subIndex + 1}${subItem.text}`
})
}
questionStr += `${index > 0 ? '' : ''}问题${index + 1}${item.question.title}${options}`
})
}
return questionStr || ''
// return record?.questions && record?.questions.length > 0 ? JSON.stringify(record?.questions) : ''
}
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "qrUrl",
hideInSearch: true,
align: 'center',
width: 150,
ellipsis: true,
render: (_, record) => {
return record?.qrUrl ? <Button type="primary" onClick={() => {
setShowImgList([record?.qrUrl])
setImagePreviewVisible(true)
}}></Button> : "-"
}
},
{ {
title: <div style={{ textAlign: 'center' }}></div>, title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "status", dataIndex: "status",
@ -68,6 +117,13 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
return record?.status ? '有效' : '无效' return record?.status ? '有效' : '无效'
} }
}, },
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "description",
hideInSearch: true,
width: 200,
ellipsis: true
},
{ {
title: <div style={{ textAlign: 'center' }}></div>, title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "updatedAt", dataIndex: "updatedAt",
@ -80,28 +136,31 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
} }
}, },
{ {
title: <div style={{ textAlign: 'center' }}></div>, title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "description", dataIndex: "createdAt",
hideInSearch: true, hideInSearch: true,
width: 200, align: 'center',
ellipsis: true width: 150,
},
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "questions",
hideInSearch: true,
width: 200,
ellipsis: true, ellipsis: true,
render: (_, record) => { render: (_, record) => {
return record?.questions && record?.questions.length > 0 ? JSON.stringify(record?.questions) : '' return record?.createdAt ? moment(record?.createdAt).format('YYYY-MM-DD HH:mm:ss') : ''
} }
}, },
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "operator",
hideInSearch: true,
align: 'center',
width: 100,
ellipsis: true,
},
{ {
title: '操作', title: '操作',
dataIndex: 'option', dataIndex: 'option',
align: 'center', align: 'center',
hideInSearch: true, hideInSearch: true,
width: 150, fixed: "right",
width: 100,
render: (_: any, record: any) => { render: (_: any, record: any) => {
return <Space> return <Space>
<a onClick={() => { <a onClick={() => {
@ -165,7 +224,14 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
ellipsis: true, ellipsis: true,
hideInSearch: true, hideInSearch: true,
render: (_, record) => { render: (_, record) => {
return record?.options && record?.options.length > 0 ? JSON.stringify(record?.options) : "" let str: string = ''
if (record.options && record?.options.length > 0) {
record.options.forEach((item: any, index: number) => {
str += `${index > 0 ? '' : ''}选项${index + 1}${item.text}`
})
}
return str || ''
// return record?.options && record?.options.length > 0 ? JSON.stringify(record?.options) : ""
} }
} }
] ]
@ -198,6 +264,7 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
expandable={{ expandable={{
expandRowByClick: true expandRowByClick: true
}} }}
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 () => {
@ -219,9 +286,36 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
</Button> </Button>
] ]
}} }}
columnsState={{
value: columnsStateMap,
onChange: setColumnsStateMap,
}}
> >
</ProTable> </ProTable>
{
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>
}
<Modal <Modal
width={1200} width={1200}
title={`${currentRow?.id ? '编辑' : '创建'}点位`} title={`${currentRow?.id ? '编辑' : '创建'}点位`}
@ -229,10 +323,8 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
destroyOnClose destroyOnClose
onOk={() => { onOk={() => {
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);
let req = {} let req = {}
let data = {} let data = {}
if (currentRow?.id) { if (currentRow?.id) {
@ -326,11 +418,11 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
} }
console.log('datadsadsa', data); console.log('datadsadsa', data);
if (data.code === 200) { if (data.code === 200) {
// modalRef.current?.resetFields() modalRef.current?.resetFields()
message.success(data.message) message.success(data.message)
// setShowPlaceModal(false) setShowPlaceModal(false)
actionRef.current?.reload() actionRef.current?.reload()
// setCurrentRow(undefined) setCurrentRow(undefined)
} else { } else {
message.error(data.message) message.error(data.message)
} }
@ -356,8 +448,17 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
console.log('2'); 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 = ''
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.text = obj.title
obj.mark = JSON.stringify(obj.options) obj.mark = JSON.stringify(obj.options)
obj.showText = str
keyList.push(obj.id) keyList.push(obj.id)
questionsList.push(obj) questionsList.push(obj)
} }
@ -454,7 +555,7 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
</Col> </Col>
<Col span={16}> <Col span={16}>
<ProFormTextArea <ProFormTextArea
name="mark" name="showText"
label="考核标准" label="考核标准"
/> />
</Col> </Col>
@ -502,7 +603,13 @@ const examineModal: React.FC<{ currentUser: any }> = (props) => {
let showQuestion: any = [] let showQuestion: any = []
if (selectedQuestionDetail && selectedQuestionDetail.length > 0) { if (selectedQuestionDetail && selectedQuestionDetail.length > 0) {
selectedQuestionDetail.forEach((item) => { selectedQuestionDetail.forEach((item) => {
showQuestion.push({ text: item.title, mark: item.options ? JSON.stringify(item.options) : "" }) let str: string = ''
if (item.options && item?.options.length > 0) {
item.options.forEach((item: any, index: number) => {
str += `${index > 0 ? '' : ''}选项${index + 1}${item.text}`
})
}
showQuestion.push({ text: item.title, showText: str, mark: item.options ? JSON.stringify(item.options) : "" })
}) })
} }
modalRef.current?.setFieldsValue({ modalRef.current?.setFieldsValue({

View File

@ -4,7 +4,7 @@ import request from "@/utils/request"
// 拿到模版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.code === 200) {
return data.data return data.data
} }

View File

@ -20,12 +20,17 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
const modalRef = useRef<FormInstance>() const modalRef = useRef<FormInstance>()
// 问题分类的枚举 // 问题分类的枚举
const [categoryIdObj, setCategoryIdObj] = useState<any>() const [categoryIdObj, setCategoryIdObj] = useState<any>()
const [columnsStateMap, setColumnsStateMap] = useState<any>({
createdAt: { show: false }
})
const columns: any = [ const columns: any = [
{ {
title: <div style={{ textAlign: 'center' }}></div>, title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "description", dataIndex: "description",
width: 200, width: 150,
hideInSearch: true, hideInSearch: true,
ellipsis: true ellipsis: true
}, },
@ -39,8 +44,9 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
{ {
title: <div style={{ textAlign: 'center' }}></div>, title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "type", dataIndex: "type",
width: 200, width: 100,
hideInSearch: true, hideInSearch: true,
align: 'center',
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] : ''
@ -52,6 +58,7 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
dataIndex: "required", dataIndex: "required",
width: 100, width: 100,
hideInSearch: true, hideInSearch: true,
align: 'center',
ellipsis: true, ellipsis: true,
render: (_, record) => { render: (_, record) => {
return record?.required ? '是' : "否" return record?.required ? '是' : "否"
@ -60,27 +67,46 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
{ {
title: <div style={{ textAlign: 'center' }}></div>, title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "options", dataIndex: "options",
width: 150, width: 300,
hideInSearch: true, hideInSearch: true,
ellipsis: true, ellipsis: true,
render: (_, record) => { render: (_, record) => {
return record?.options && record?.options.length > 0 ? JSON.stringify(record?.options) : '' let str: string = ''
if (record.options && record?.options.length > 0) {
record.options.forEach((item: any, index: number) => {
str += `${index > 0 ? '' : ''}选项${index + 1}${item.text}`
})
}
return str || ''
} }
}, },
{ {
title: <div style={{ textAlign: 'center' }}></div>, title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "updatedAt", dataIndex: "updatedAt",
width: 150, width: 150,
align: 'center',
hideInSearch: true, hideInSearch: true,
ellipsis: true, ellipsis: true,
render: (_, record) => { render: (_, record) => {
return record?.updatedAt ? moment(record?.updatedAt).format('YYYY-MM-DD HH:mm:ss') : '' return record?.updatedAt ? moment(record?.updatedAt).format('YYYY-MM-DD HH:mm:ss') : ''
} }
}, },
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "createdAt",
width: 150,
align: 'center',
hideInSearch: true,
ellipsis: true,
render: (_, record) => {
return record?.createdAt ? moment(record?.createdAt).format('YYYY-MM-DD HH:mm:ss') : ''
}
},
{ {
title: <div style={{ textAlign: 'center' }}></div>, title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "operator", dataIndex: "operator",
width: 150, width: 100,
align: 'center',
hideInSearch: true, hideInSearch: true,
ellipsis: true ellipsis: true
}, },
@ -88,8 +114,9 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
title: '操作', title: '操作',
dataIndex: 'option', dataIndex: 'option',
align: 'center', align: 'center',
fixed: "right",
hideInSearch: true, hideInSearch: true,
width: 150, width: 100,
render: (_: any, record: any) => { render: (_: any, record: any) => {
return <Space> return <Space>
<a onClick={() => { <a onClick={() => {
@ -138,6 +165,7 @@ 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 }}
scroll={{ x: "100%", y: 'calc(100vh - 400px)' }}
request={async (params) => { request={async (params) => {
const data = await handleGetQuestionList() const data = await handleGetQuestionList()
console.log('data', data); console.log('data', data);
@ -156,6 +184,10 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
</Button> </Button>
] ]
}} }}
columnsState={{
value: columnsStateMap,
onChange: setColumnsStateMap,
}}
/> />
</div> </div>

View File

@ -2,7 +2,7 @@ import request from "@/utils/request"
// 拿到问题列表接口 // 拿到问题列表接口
export async function handleGetQuestionList(params?: any) { export async function handleGetQuestionList(params?: any) {
const data = await request.get('/questions', params) const data = await request.get('/questions', {params})
if (data.code === 200) { if (data.code === 200) {
return data.data return data.data
} }

View File

@ -0,0 +1,208 @@
import { ConnectState } from "@/models/global";
import { ActionType, ProTable } from "@ant-design/pro-components";
import ProForm, { FormInstance, ProFormList, ProFormText } from "@ant-design/pro-form";
import { Col, Row, Image, Button } from "antd";
import moment from "moment";
import { useEffect, useRef, useState } from "react";
import { connect } from "umi";
import { handleGetExamineTypeTreeList } from "../../index/service";
import session from "@/utils/session";
type DetailProps = {
parentRow: any; // 父级数据
show: boolean;// 抽屉是否显示
}
const RecordDetail = ({ parentRow, show }: DetailProps) => {
const formRef = useRef<FormInstance>();
const actionRef = useRef<ActionType>();
const tableFormRef = useRef<FormInstance>();
const [formRes, setFormRes] = useState<any>()
useEffect(() => {
if (show) {
console.log('parentRow', parentRow);
let extendObj = {}
if (parentRow?.extend) {
extendObj = JSON.parse(parentRow?.extend)
}
let obj = {
...parentRow,
...extendObj,
placeName: parentRow.template.title,
submittedAt: moment(parentRow?.submittedAt).format('YYYY-MM-DD HH:mm:ss')
}
setFormRes(obj)
formRef.current?.setFieldsValue(obj)
}
}, [show])
return (
<div>
<ProForm
formRef={formRef}
submitter={false}
layout={'horizontal'}
>
<Row gutter={8}>
<Col span={8}>
<ProFormText
label={"服务区名称"}
name={"serverPartName"}
readonly
/>
</Col>
<Col span={8}>
<ProFormText
label={"站点名称"}
name={"placeName"}
readonly
/>
</Col>
<Col span={8}>
<ProFormText
label={"巡查内容"}
name={"uploadResult"}
readonly
/>
</Col>
<Col span={8}>
<ProFormText
label={"巡查人员"}
name={"userName"}
readonly
/>
</Col>
<Col span={8}>
<ProFormText
label={"巡查时间"}
name={"submittedAt"}
readonly
/>
</Col>
<Col span={16}>
<ProFormList
label={"附件列表"}
name={"imgsList"}
copyIconProps={false}
deleteIconProps={false}
readonly
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>
)}
>
<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 style={{ width: "150px", height: "150px", marginRight: "12px" }} src={item} />
})
: ''
}
</div>
</ProFormList>
</Col>
</Row>
</ProForm>
<ProTable
actionRef={actionRef}
formRef={tableFormRef}
search={false}
toolbar={{
actions: [
<Button type="primary" onClick={(e) => {
}}>
</Button>
]
}}
options={false}
request={async () => {
let res = parentRow?.questionResponses || []
console.log('res', res);
let typeData = await handleGetExamineTypeTreeList({})
console.log('typeData', typeData);
if (typeData && typeData.length > 0) {
typeData.forEach((item: any) => {
if (item.children && item.children.length > 0) {
item.children.forEach((subItem: any) => {
})
}
})
}
// let categoriesObj: any = {} // 子父级关系的缓存对象
// let categoriesTypeObj: any = {} // 类型的对象
// let categoriesIdObj = session.get('categoriesIdObj')
// let categoriesTypeSessionObj = session.get('categoriesTypeObj')
// if (categoriesIdObj) {
// categoriesObj = categoriesIdObj
// categoriesTypeObj = categoriesTypeSessionObj
// } else {
// let typeData = await handleGetExamineTypeTreeList({})
// // 走动式的大类包括小类的缓存 categoriesIdObj
// if (typeData && typeData.length > 0) {
// typeData.forEach((item: any) => {
// let list: any = []
// categoriesTypeObj[item.id] = item.name
// if (item.children && item.children.length > 0) {
// item.children.forEach((subItem: any) => {
// list.push(subItem.id)
// categoriesTypeObj[subItem.id] = item.name
// })
// }
// categoriesObj[item.id] = list
// })
// }
// session.set('categoriesIdObj', categoriesObj)
// session.set('categoriesTypeObj', categoriesTypeObj)
// }
// console.log('categoriesObj', categoriesObj);
// console.log('categoriesTypeObj', categoriesTypeObj);
// let res = parentRow?.questionResponses || []
// // 在res的数组里面拿到最大一个类型的数据
// if (res && res.length > 0) {
// res.forEach((item: any) => {
// for (let key in categoriesObj) {
// let list = categoriesObj[key]
// if (list && list.length > 0) {
// if (list.indexOf(Number(item.question.categoryId)) !== -1) {
// item.parentCategoryId = key
// }
// }
// }
// })
// }
// console.log('table', res);
}}
/>
</div>
)
}
export default connect(({ user }: ConnectState) => ({
currentUser: user.data
}))(RecordDetail);

View File

@ -2,9 +2,11 @@ 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 { handleGetRecordList } from "./service"; import { handleDeleteRecord, handleGetRecordList } from "./service";
import moment from "moment"; import moment from "moment";
import { Button, Image } from "antd"; import { Button, Drawer, Image, message, Popconfirm, Space } from "antd";
import { handleGetServerpartDDL } from "@/components/leftSelectTree/service";
import RecordDetail from "./components/recordDetail";
const examineRecord: React.FC<{ currentUser: any }> = (props) => { const examineRecord: React.FC<{ currentUser: any }> = (props) => {
const { currentUser } = props const { currentUser } = props
@ -17,8 +19,45 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
const [imagePreviewVisible, setImagePreviewVisible] = useState<boolean>(false) const [imagePreviewVisible, setImagePreviewVisible] = useState<boolean>(false)
// 预览的索引 // 预览的索引
const [previewIndex, setPreviewIndex] = useState<number>(0) const [previewIndex, setPreviewIndex] = useState<number>(0)
// 当行数据
const [currentRow, setCurrentRow] = useState<any>()
// 显示详情抽屉
const [showDetail, setShowDetail] = useState<boolean>(false)
const columns: any = [ const columns: any = [
{
title: "统计日期",
dataIndex: "staticDate",
hideInTable: true,
valueType: "date",
initialValue: [moment().format('YYYY-MM-DD')],
search: {
transform: (value: any) => {
return {
startTime: value,
endTime: value
};
},
},
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: <div style={{ textAlign: 'center' }}></div>, title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "serverPartName", dataIndex: "serverPartName",
@ -57,13 +96,19 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
width: 350, width: 350,
ellipsis: true, ellipsis: true,
render: (_, record) => { render: (_, record) => {
let obj: any = {} let str: string = ''
if (record?.questionResponses && record?.questionResponses.length > 0) { if (record?.questionResponses && record?.questionResponses.length > 0) {
record?.questionResponses.forEach((item) => { record?.questionResponses.forEach((item: any, index: number) => {
obj[item.question.title] = JSON.stringify(item.choiceResponse) let anwers: string = ''
if (item.choiceResponse && item.choiceResponse.length > 0) {
item.choiceResponse.forEach((subItem: string, subIndex: number) => {
anwers += `${subIndex > 0 ? '' : ''}${subItem}`
}) })
} }
return obj ? JSON.stringify(obj) : "-" str += `${index > 0 ? '' : ''}考核内容:${item.question.title},考核结果:${anwers}`
})
}
return str || ''
} }
}, },
{ {
@ -77,6 +122,14 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
return record?.createdAt ? moment(record?.createdAt).format('YYYY-MM-DD HH:mm:ss') : '-' return record?.createdAt ? moment(record?.createdAt).format('YYYY-MM-DD HH:mm:ss') : '-'
} }
}, },
{
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "userName",
hideInSearch: true,
width: 100,
ellipsis: true,
align: 'center',
},
{ {
title: <div style={{ textAlign: 'center' }}></div>, title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: "placeName", dataIndex: "placeName",
@ -93,9 +146,45 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
setImagePreviewVisible(true) setImagePreviewVisible(true)
}}></Button> : "-" }}></Button> : "-"
} }
},
{
title: '操作',
dataIndex: 'option',
align: 'center',
fixed: "right",
hideInSearch: true,
width: 100,
render: (_: any, record: any) => {
return <Space>
<a onClick={() => {
setCurrentRow(record)
setShowDetail(true)
}}>
</a>
<Popconfirm
title={"确认删除?"}
onConfirm={async () => {
deleteRecord(record?.id)
}}
>
<a></a>
</Popconfirm>
</Space>
}
} }
] ]
// 删除记录
const deleteRecord = async (id: any) => {
const data = await handleDeleteRecord({ id: id })
if (data.code === 200) {
message.success(data.message)
actionRef.current?.reload()
}
}
return ( return (
<div style={{ backgroundColor: '#fff', display: 'flex' }}> <div style={{ backgroundColor: '#fff', display: 'flex' }}>
<div style={{ <div style={{
@ -113,13 +202,19 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
expandable={{ expandable={{
expandRowByClick: true expandRowByClick: true
}} }}
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 (params) => {
const req: any = { console.log('params', params);
const req: any = {
startTime: params?.startTime ? `${params?.startTime}T00:00:00` : "",
endTime: params?.endTime ? `${params?.endTime}T23:59:59` : "",
serverPartId: params?.serverPartId ? params?.serverPartId : ""
} }
const data = await handleGetRecordList() console.log('req', req);
const data = await handleGetRecordList(req)
console.log('data', data); console.log('data', data);
if (data && data.length > 0) { if (data && data.length > 0) {
@ -156,6 +251,20 @@ const examineRecord: React.FC<{ currentUser: any }> = (props) => {
</div> </div>
} }
<Drawer
title={false}
closeIcon={false}
onClose={() => {
setShowDetail(false)
}}
open={showDetail}
destroyOnClose
width={'60%'}
>
<RecordDetail parentRow={currentRow} show={showDetail} />
</Drawer>
</div> </div>
) )
} }

View File

@ -1,8 +1,8 @@
import request from "@/utils/request" import request from "@/utils/request"
// 拿到问题列表接口 // 拿到记录
export async function handleGetRecordList(params?: any) { export async function handleGetRecordList(params?: any) {
const data = await request.get('/questionnaire-responses', params) const data = await request.get('/questionnaire-responses', { params })
if (data.code === 200) { if (data.code === 200) {
return data.data return data.data
} }
@ -10,4 +10,12 @@ export async function handleGetRecordList(params?: any) {
} }
// 删除记录
export async function handleDeleteRecord(params?: any) {
const data = await request.get(`/questionnaire-responses/delete/${params.id}`)
return data
}

View File

@ -33,7 +33,43 @@ export async function retrieveUserAuthority(params: any) {
//获取菜单数据 //获取菜单数据
export async function retrieveMenuData(params: any) { export async function retrieveMenuData(params: any) {
const data = await request.get('/menus', params) const data = await request.get('/menus', params)
return data // return data
return [
{
path: '/standard/index',
redirect: '',
name: '生成标准页面',
component: "@/pages/standard/index",
},
{
path: '/examine',
redirect: '',
name: '走动式管理',
children: [
{
path: '/examine/index',
name: '考评分类管理',
component: "@/pages/examine/index",
},
{
path: '/examine/question',
name: '考核问题管理',
component: "@/pages/examine/question",
},
{
path: '/examine/modal',
name: '考核模版管理',
component: "@/pages/examine/modal",
},
{
path: '/examine/record',
name: '考核记录管理',
component: "@/pages/examine/record",
}
]
},
]
} }
// export const retrieveMenuData = (): Promise<API.MenuDataResponse> => ( // export const retrieveMenuData = (): Promise<API.MenuDataResponse> => (
// request.get('/api/user/menu') // request.get('/api/user/menu')

View File

@ -17,34 +17,62 @@ const handleRedirect = (
indexValidMenuItemByPath: IndexValidMenuItemByPath, indexValidMenuItemByPath: IndexValidMenuItemByPath,
): Promise<boolean> => ( ): Promise<boolean> => (
new Promise((resolve) => { new Promise((resolve) => {
let routePath = Object.keys(indexValidMenuItemByPath)[0]; let routePath = ''
// Object.keys(indexValidMenuItemByPath)[0];
if (isLoginPage) { if (isLoginPage) {
const queryString = window.location.search; const queryString = window.location.search;
if (queryString) { if (queryString) {
const matchedRes = queryString.match(/redirect=(.*)/); const matchedRes = queryString.match(/redirect=(.*)/);
if (matchedRes) { if (matchedRes) {
//还要考虑redirect参数是否有效 //还要考虑redirect参数是否有效
const decodeRedirect = decodeURIComponent(matchedRes[1]); let decodeRedirect = decodeURIComponent(matchedRes[1]);
if (decodeRedirect.indexOf('/cloudNew') !== -1) {
decodeRedirect = decodeRedirect.split('/cloudNew')[1]
}
// 处理可能存在的路径问题,确保路径格式正确
// 移除可能的重复前缀
if (decodeRedirect.startsWith('/') && decodeRedirect.indexOf('/', 1) !== -1) {
const firstSlashAfterRoot = decodeRedirect.indexOf('/', 1);
const possiblePrefix = decodeRedirect.substring(0, firstSlashAfterRoot);
// 检查是否有重复的路径前缀
if (decodeRedirect.indexOf(possiblePrefix, firstSlashAfterRoot) === firstSlashAfterRoot) {
decodeRedirect = decodeRedirect.substring(firstSlashAfterRoot);
}
}
// 避免重定向到登录页面本身
if (decodeRedirect === '/user/login' || decodeRedirect.startsWith('/user/login?')) {
// 如果重定向目标是登录页面,则使用默认路由
routePath = Object.keys(indexValidMenuItemByPath)[0];
}
//有效: 跳转 //有效: 跳转
if (indexValidMenuItemByPath[decodeRedirect]) { else if (indexValidMenuItemByPath[decodeRedirect]) {
routePath = decodeRedirect; routePath = decodeRedirect;
} else if (indexAllMenuItemByPath[decodeRedirect]) { } else if (indexAllMenuItemByPath[decodeRedirect]) {
//无效 //无效
//有子路由: 跳子路由 //有子路由: 跳子路由
routePath = indexAllMenuItemByPath[decodeRedirect].redirect; routePath = indexAllMenuItemByPath[decodeRedirect].redirect;
} else { } else {
//无子路由: 还是要跳, 此时就是交由umi处理404的情况了 //无子路由: 还是要跳, 此时就是交由umi处理404的情况了
if (decodeRedirect === '/cloudNew/') {
routePath = ''
} else {
routePath = decodeRedirect; routePath = decodeRedirect;
} }
} }
} }
}
} else { } else {
const { let {
location: { search, pathname }, location: { search, pathname },
} = window; } = window;
if (pathname.indexOf('/cloudNew') !== -1) {
pathname = pathname.split('/cloudNew')[1]
}
//考虑url上有查询字符串参数的情况 //考虑url上有查询字符串参数的情况
//有效 //有效

View File

@ -8,7 +8,8 @@ const { UMI_APP_BASEURL } = process.env;
// const instance = axios.create({ baseURL: UMI_APP_BASEURL }); // const instance = axios.create({ baseURL: UMI_APP_BASEURL });
// const instance = axios.create({ baseURL: 'https://api.eshangtech.com/EShangApiMain' }); // const instance = axios.create({ baseURL: 'https://api.eshangtech.com/EShangApiMain' });
const instance = axios.create({ baseURL: '/auth' }); // 修改baseURL为完整的API地址确保在生产环境中正确访问
const instance = axios.create({ baseURL: 'https://es.robot-z.cn' });
@ -18,6 +19,7 @@ instance.interceptors.request.use(
// if (config.data) { // if (config.data) {
// config.data = preprocessData(JSON.stringify(config.data)); // 调用预处理函数 // config.data = preprocessData(JSON.stringify(config.data)); // 调用预处理函数
// } // }
console.log('config', config);
const isUpload = config.url?.includes("/oss/upload"); const isUpload = config.url?.includes("/oss/upload");

Binary file not shown.