Compare commits
5 Commits
master
...
feature/co
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c36384a38 | ||
|
|
5e7284afb9 | ||
|
|
abcad3423f | ||
|
|
5e6b143a72 | ||
|
|
9925f330bd |
@ -85,8 +85,28 @@ export default [
|
||||
},
|
||||
{
|
||||
path: '/ComplaintForwardingProcess/index',
|
||||
name: '投诉转发流程',
|
||||
name: '投诉受理',
|
||||
component: "@/pages/ComplaintForwardingProcess/index",
|
||||
},
|
||||
{
|
||||
path: '/ComplaintForwardingProcess/ComplaintForwardingProcessReview',
|
||||
name: '投诉审核',
|
||||
component: "@/pages/ComplaintForwardingProcess/ComplaintForwardingProcessReview",
|
||||
},
|
||||
{
|
||||
path: '/ComplaintForwardingProcess/ComplaintForwardingProcessList',
|
||||
name: '投诉台账',
|
||||
component: "@/pages/ComplaintForwardingProcess/ComplaintForwardingProcessList",
|
||||
},
|
||||
{
|
||||
path: '/ComplaintForwardingProcess/ComplaintForwardingProcessReport',
|
||||
name: '投诉报表',
|
||||
component: "@/pages/ComplaintForwardingProcess/ComplaintForwardingProcessReport",
|
||||
},
|
||||
{
|
||||
path: '/BusinessConfiguration/index',
|
||||
name: '业务配置',
|
||||
component: "@/pages/BusinessConfiguration/index",
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
Binary file not shown.
@ -314,9 +314,33 @@ const UserModel: UserModelType = {
|
||||
{
|
||||
path: '/ComplaintForwardingProcess/index',
|
||||
redirect: '',
|
||||
name: '投诉转发流程',
|
||||
name: '投诉受理',
|
||||
component: "@/pages/ComplaintForwardingProcess/index",
|
||||
},
|
||||
{
|
||||
path: '/ComplaintForwardingProcess/ComplaintForwardingProcessReview',
|
||||
redirect: '',
|
||||
name: '投诉审核',
|
||||
component: "@/pages/ComplaintForwardingProcess/ComplaintForwardingProcessReview",
|
||||
},
|
||||
{
|
||||
path: '/ComplaintForwardingProcess/ComplaintForwardingProcessList',
|
||||
redirect: '',
|
||||
name: '投诉台账',
|
||||
component: "@/pages/ComplaintForwardingProcess/ComplaintForwardingProcessList",
|
||||
},
|
||||
{
|
||||
path: '/ComplaintForwardingProcess/ComplaintForwardingProcessReport',
|
||||
redirect: '',
|
||||
name: '投诉报表',
|
||||
component: "@/pages/ComplaintForwardingProcess/ComplaintForwardingProcessReport",
|
||||
},
|
||||
{
|
||||
path: '/BusinessConfiguration/index',
|
||||
redirect: '',
|
||||
name: '业务配置',
|
||||
component: "@/pages/BusinessConfiguration/index",
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
@ -402,6 +426,10 @@ const UserModel: UserModelType = {
|
||||
"/realEstate/index",
|
||||
"/ComplaintApproval/index",
|
||||
"/ComplaintForwardingProcess/index",
|
||||
"/ComplaintForwardingProcess/ComplaintForwardingProcessReview",
|
||||
"/ComplaintForwardingProcess/ComplaintForwardingProcessList",
|
||||
"/ComplaintForwardingProcess/ComplaintForwardingProcessReport",
|
||||
"/BusinessConfiguration/index",
|
||||
// '/examine/index',
|
||||
// '/examine/modal',
|
||||
// '/examine/question',
|
||||
|
||||
205
src/pages/BusinessConfiguration/components/ChosePlayers.tsx
Normal file
205
src/pages/BusinessConfiguration/components/ChosePlayers.tsx
Normal file
@ -0,0 +1,205 @@
|
||||
import { ActionType, ProCard, ProTable } from "@ant-design/pro-components"
|
||||
import { useEffect, useImperativeHandle, useRef, useState } from "react"
|
||||
import { getOnwer, getUserTypeTree, handleGetUserList } from "@/pages/serverpartAssets/service";
|
||||
import { Tree } from "antd";
|
||||
import './style.less'
|
||||
|
||||
const ChosePlayers = ({ actionRef, onRef, defaultPerson }: { actionRef?: any, onRef: any, defaultPerson: any }) => {
|
||||
const tableRef = useRef<ActionType>();
|
||||
// 是否显示账号分类查询树
|
||||
// 左侧业务类型数据
|
||||
const [treeView, setTreeView] = useState<any>()
|
||||
// 选择的部门
|
||||
const [selectedId, setSelectedId] = useState<any>()
|
||||
// 选择的行
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<any>()
|
||||
// 选择的行的详情
|
||||
const [selectedRowDetail, setSelectedRowDetial] = useState<any>()
|
||||
|
||||
// 表格内容
|
||||
const columns: any = [
|
||||
{
|
||||
title: '查询账号',
|
||||
dataIndex: 'searchKey',
|
||||
hideInDescriptions: true,
|
||||
hideInTable: true,
|
||||
fieldProps: {
|
||||
placeholder: '请输入账号/用户名称/业主单位/手机号/经营单位'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '账号部门',
|
||||
dataIndex: 'USERTYPE_ID',
|
||||
hideInSearch: true,
|
||||
hideInDescriptions: true,
|
||||
valueType: "treeSelect",
|
||||
fieldProps: {
|
||||
options: treeView,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '账号',
|
||||
dataIndex: 'USER_PASSPORT',
|
||||
sorter: (a, b) => {
|
||||
return (a.USER_PASSPORT || '').localeCompare((b.USER_PASSPORT || ''))
|
||||
},
|
||||
hideInSearch: true,
|
||||
},
|
||||
{
|
||||
title: '用户名称',
|
||||
dataIndex: 'USER_NAME',
|
||||
sorter: (a, b) => {
|
||||
return (a.USER_NAME || '').localeCompare((b.USER_NAME || ''))
|
||||
},
|
||||
hideInDescriptions: true,
|
||||
hideInSearch: true,
|
||||
},
|
||||
{
|
||||
title: '手机号',
|
||||
dataIndex: 'USER_MOBILEPHONE',
|
||||
hideInSearch: true
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'USER_STATUS',
|
||||
hideInSearch: true,
|
||||
filters: true,
|
||||
onFilter: true,
|
||||
valueType: 'select',
|
||||
initialValue: 1,
|
||||
valueEnum: {
|
||||
all: { text: '全部', status: 'Default' },
|
||||
0: { text: '无效', status: 'Default' },
|
||||
1: { text: '有效', status: 'Processing' },
|
||||
},
|
||||
|
||||
},
|
||||
{
|
||||
title: '业主单位',
|
||||
dataIndex: 'PROVINCE_UNIT',
|
||||
hideInSearch: true,
|
||||
ellipsis: true,
|
||||
sorter: (a, b) => {
|
||||
return (a.PROVINCE_UNIT || '').localeCompare((b.PROVINCE_UNIT || ''))
|
||||
},
|
||||
valueType: "select",
|
||||
request: async () => {
|
||||
let data = await getOnwer({ ProvinceCode: "530000", DataType: 1 })
|
||||
if (data && data.length > 0) {
|
||||
data.forEach((item: any) => {
|
||||
item.value = item.value.toString()
|
||||
})
|
||||
}
|
||||
return data
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '备注',
|
||||
dataIndex: 'USER_DESC',
|
||||
hideInSearch: true,
|
||||
render: (_, record) => {
|
||||
return record?.USER_DESC
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
useEffect(() => {
|
||||
getUserTypeTree({ UserTypePattern: 1000, ShowStatus: true }).then((res: any) => {
|
||||
console.log('fdsklfja', res);
|
||||
setTreeView(res)
|
||||
})
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
console.log('defaultPersondefaultPerson', defaultPerson);
|
||||
|
||||
if (defaultPerson && defaultPerson.length > 0) {
|
||||
setSelectedRowDetial(defaultPerson)
|
||||
let keyList: any = []
|
||||
defaultPerson.forEach((item: any) => {
|
||||
keyList.push(item.USER_ID)
|
||||
})
|
||||
setSelectedRowKeys(keyList)
|
||||
}
|
||||
}, [defaultPerson])
|
||||
|
||||
useImperativeHandle(onRef, () => ({
|
||||
selectedRowKeys,
|
||||
selectedRowDetail
|
||||
}))
|
||||
|
||||
return (
|
||||
<div className="ChosePlayersBox" style={{ backgroundColor: '#fff', display: 'flex', width: '100%', height: '700px' }}>
|
||||
<ProCard
|
||||
style={{ width: "300px" }}
|
||||
className="ChosePlayersLeft"
|
||||
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: "300px" }}
|
||||
colSpan={"300px"}
|
||||
headerBordered
|
||||
>
|
||||
{treeView && treeView.length > 0 ? <Tree
|
||||
checkable
|
||||
treeData={[{
|
||||
label: '云南省',
|
||||
value: 0,
|
||||
key: '0-0',
|
||||
children: treeView
|
||||
}]}
|
||||
fieldNames={{
|
||||
title: "label",
|
||||
key: "key"
|
||||
}}
|
||||
blockNode
|
||||
defaultExpandedKeys={['0-0']}
|
||||
onCheck={(checkedKeys: React.Key[] | any, info) => {
|
||||
const selectedIds = info.checkedNodes.filter((n: any) => n?.type === 1)
|
||||
let res: any = selectedIds.map(n => n?.value)?.toString() || ''
|
||||
console.log('reqs', res);
|
||||
setSelectedId(res)
|
||||
}}
|
||||
/> : ''}
|
||||
</ProCard>
|
||||
<div style={{
|
||||
width: 'calc(100% - 300px)',
|
||||
paddingTop: 0,
|
||||
paddingBottom: 0,
|
||||
paddingRight: 0
|
||||
}}>
|
||||
<ProTable
|
||||
rowKey="USER_ID"
|
||||
actionRef={tableRef}
|
||||
scroll={{ x: "100%", y: '430px' }}
|
||||
options={false}
|
||||
request={async (params, sorter) => {
|
||||
if (!selectedId) return []
|
||||
const req: any = {
|
||||
SearchParameter: {
|
||||
UserTypeIds: selectedId,
|
||||
USER_STATUS: 1
|
||||
},
|
||||
PageIndex: 1,
|
||||
PageSize: 999999,
|
||||
keyWord: params.searchKey ? { key: "USER_PASSPORT,USER_NAME,USER_MOBILEPHONE,PROVINCE_UNIT,BUSINESSMAN_NAME", value: params.searchKey } : null,
|
||||
}
|
||||
const data = await handleGetUserList(req)
|
||||
console.log('dsajkdjas;da', data);
|
||||
if (data && data.length > 0) {
|
||||
return { data, success: true }
|
||||
}
|
||||
return { data: [], success: true }
|
||||
}}
|
||||
columns={columns}
|
||||
rowSelection={{
|
||||
selectedRowKeys: selectedRowKeys,
|
||||
onChange: (e: any, detail: any) => {
|
||||
setSelectedRowDetial(detail)
|
||||
setSelectedRowKeys(e)
|
||||
},
|
||||
preserveSelectedRowKeys: true,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default ChosePlayers;
|
||||
7
src/pages/BusinessConfiguration/components/style.less
Normal file
7
src/pages/BusinessConfiguration/components/style.less
Normal file
@ -0,0 +1,7 @@
|
||||
.ChosePlayersBox {
|
||||
.ant-pro-card {
|
||||
.ant-pro-card-body {
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
}
|
||||
491
src/pages/BusinessConfiguration/index.tsx
Normal file
491
src/pages/BusinessConfiguration/index.tsx
Normal file
@ -0,0 +1,491 @@
|
||||
import { FileSearchOutlined, MenuFoldOutlined, PlusOutlined } from "@ant-design/icons"
|
||||
import { ActionType, ProCard, ProForm, ProFormDigit, ProFormSelect, ProFormText, ProFormTreeSelect, ProTable } from "@ant-design/pro-components"
|
||||
import { Button, FormInstance, message, Modal, Popconfirm, Space, Tree } from "antd"
|
||||
import { useEffect, useRef, useState } from "react"
|
||||
import { getFieldEnumTree, handleDeleteAPPROVALROUTE, handleGetAPPROVALROUTEList, handleGetUserList, handleSynchroAPPROVALROUTE } from "../serverpartAssets/service"
|
||||
import moment from "moment"
|
||||
import ChosePlayers from "./components/ChosePlayers"
|
||||
|
||||
const BusinessConfiguration = () => {
|
||||
const actionRef = useRef<ActionType>();
|
||||
const formRef = useRef<FormInstance>();
|
||||
const modalFormRef = useRef<FormInstance>();
|
||||
const chosePlayerRef = useRef<any>();
|
||||
|
||||
// 折叠左侧业务类型属性选择框
|
||||
const [collapsible, setCollapsible] = useState<boolean>(false)
|
||||
// 左侧业务类型数据
|
||||
const [treeView, setTreeView] = useState<any>()
|
||||
// 左侧业务类型数据对象
|
||||
const [serviceTypeObj, setServiceTypeObj] = useState<any>()
|
||||
// 树相关的属性和方法
|
||||
const [selectedId, setSelectedId] = useState<string>()
|
||||
// 存储当前数据的搜索条件
|
||||
const [searchParams, setSearchParams] = useState<any>()
|
||||
// 显示新增环节的悬浮框
|
||||
const [modalVisible, setModalVisible] = useState<boolean>(false)
|
||||
// 选中的当前行数据
|
||||
const [currentRow, setCurrentRow] = useState<any>()
|
||||
// 悬浮框的确认按钮的loading
|
||||
const [confirmLoading, setConfirmLoading] = useState<boolean>(false)
|
||||
// 参与人列表
|
||||
const [playerList, setPlayerList] = useState<any>()
|
||||
// 当前已经存在了的参与人
|
||||
const [defaultPerson, setDefaultPerson] = useState<any>()
|
||||
// 显示参与人的悬浮框
|
||||
const [showChosePlayer, setShowChosePlayer] = useState<boolean>(false)
|
||||
|
||||
const columns: any = [
|
||||
{
|
||||
title: '环节名称',
|
||||
width: 150,
|
||||
dataIndex: 'APPROVALROUTE_NAME',
|
||||
align: 'center',
|
||||
hideInSearch: true
|
||||
},
|
||||
{
|
||||
title: '业务状态',
|
||||
width: 120,
|
||||
dataIndex: 'APPROVALROUTE_STATE',
|
||||
align: 'center',
|
||||
sorter: (a, b) => a.APPROVALROUTE_STATE - b.APPROVALROUTE_STATE,
|
||||
defaultSortOrder: 'ascend',
|
||||
},
|
||||
{
|
||||
title: '业务类型',
|
||||
width: 120,
|
||||
dataIndex: 'OPERATION_TYPE',
|
||||
valueType: 'select',
|
||||
align: 'center',
|
||||
hideInSearch: true,
|
||||
valueEnum: serviceTypeObj
|
||||
},
|
||||
{
|
||||
title: '下一业务状态',
|
||||
width: 120,
|
||||
dataIndex: 'NEXT_STATE',
|
||||
align: 'center',
|
||||
// valueType: 'select',
|
||||
hideInSearch: true,
|
||||
// valueEnum:{
|
||||
// 2000:'商户确认审核',
|
||||
// 2010:'服务区经理审核',
|
||||
// 2020:'片区中心审核',
|
||||
// 2030:'经发部审核',
|
||||
// 2040:'财务部审核',
|
||||
// }
|
||||
},
|
||||
{
|
||||
title: '参与人',
|
||||
dataIndex: 'APPROVALSTAFF_NAME',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
ellipsis: true,
|
||||
hideInSearch: true,
|
||||
},
|
||||
{
|
||||
title: '生成时间',
|
||||
width: 150,
|
||||
dataIndex: 'RECORD_DATE',
|
||||
align: 'center',
|
||||
hideInSearch: true,
|
||||
render: (_, record) => {
|
||||
return record?.RECORD_DATE ? moment(record?.RECORD_DATE).format('YYYY-MM-DD') : ''
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '业主单位',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
dataIndex: 'PROVINCE_CODE',
|
||||
hideInSearch: true,
|
||||
},
|
||||
{
|
||||
dataIndex: 'option',
|
||||
title: '操作',
|
||||
width: 120,
|
||||
valueType: 'option',
|
||||
align: 'center',
|
||||
fixed: 'right',
|
||||
hideInSearch: true,
|
||||
render: (_, record) => {
|
||||
return (
|
||||
<Space>
|
||||
<a onClick={() => {
|
||||
setCurrentRow(record)
|
||||
setModalVisible(true)
|
||||
}}>编辑</a>
|
||||
<Popconfirm
|
||||
title="确认删除?"
|
||||
onConfirm={async () => {
|
||||
const req: any = {
|
||||
APPROVALROUTEId: record?.APPROVALROUTE_ID
|
||||
}
|
||||
const data = await handleDeleteAPPROVALROUTE(req)
|
||||
if (data.Result_Code === 100) {
|
||||
message.success('删除成功')
|
||||
actionRef.current?.reload()
|
||||
} else {
|
||||
message.error(data.Result_Desc)
|
||||
}
|
||||
}}
|
||||
>
|
||||
<a>删除</a>
|
||||
</Popconfirm>
|
||||
</Space>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
// 解构左侧类型
|
||||
const extractValueLabel = (list: any) => {
|
||||
const result: any = {};
|
||||
|
||||
function traverse(nodes: any) {
|
||||
if (!Array.isArray(nodes)) return;
|
||||
|
||||
nodes.forEach(item => {
|
||||
if (item.value !== undefined && item.label !== undefined) {
|
||||
result[item.value] = item.label;
|
||||
}
|
||||
if (Array.isArray(item.children)) {
|
||||
traverse(item.children);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
traverse(list);
|
||||
return result;
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getFieldEnumTree({ FieldExplainField: 'PROCESS_TYPE', sessionName: 'PROCESS_TYPE' }).then((res: any) => {
|
||||
console.log('resresresres', res);
|
||||
let obj = extractValueLabel(res)
|
||||
setServiceTypeObj(obj)
|
||||
setTreeView(res)
|
||||
})
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div style={{ height: 'calc(100vh - 100px)', background: "#fff", display: 'flex' }}>
|
||||
<div>
|
||||
<ProCard
|
||||
style={{ width: !collapsible ? "300px" : "60px" }}
|
||||
className="pageTable-leftnav"
|
||||
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "300px" : "60px" }}
|
||||
extra={<MenuFoldOutlined onClick={() => {
|
||||
setCollapsible(!collapsible)
|
||||
}} />}
|
||||
colSpan={!collapsible ? "300px" : "60px"}
|
||||
title={!collapsible ? "请选择业务类型" : ""}
|
||||
headerBordered
|
||||
collapsed={collapsible}
|
||||
>
|
||||
{treeView && treeView.length > 0 ? <Tree
|
||||
checkable
|
||||
treeData={[{
|
||||
label: '全部',
|
||||
value: 0,
|
||||
key: '0-0',
|
||||
children: treeView
|
||||
}]}
|
||||
fieldNames={{
|
||||
title: "label",
|
||||
key: "key"
|
||||
}}
|
||||
blockNode
|
||||
defaultExpandedKeys={['0-0']}
|
||||
onCheck={(checkedKeys: React.Key[] | any, info) => {
|
||||
const selectedIds = info.checkedNodes.filter(n => n?.type === 2)
|
||||
setSelectedId(selectedIds.map(n => n?.value)?.toString() || '')
|
||||
}}
|
||||
// switcherIcon={<PlusOutlined />}
|
||||
/> : ''}
|
||||
</ProCard>
|
||||
</div>
|
||||
|
||||
<div style={{
|
||||
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
|
||||
paddingTop: 0,
|
||||
paddingBottom: 0,
|
||||
paddingRight: 0
|
||||
}}>
|
||||
<ProTable
|
||||
actionRef={actionRef}
|
||||
formRef={formRef}
|
||||
columns={columns}
|
||||
bordered
|
||||
expandable={{
|
||||
expandRowByClick: true
|
||||
}}
|
||||
headerTitle={'业务配置'}
|
||||
search={{ span: 6 }}
|
||||
request={async (params) => {
|
||||
if (!selectedId) {
|
||||
return
|
||||
}
|
||||
const req: any = {
|
||||
SearchParameter: {
|
||||
PROVINCE_CODE: '530000',
|
||||
OPERATION_TYPES: selectedId || '',
|
||||
APPROVALROUTE_VALID: 1
|
||||
},
|
||||
|
||||
PageIndex: 1,
|
||||
PageSize: 999999
|
||||
}
|
||||
setSearchParams(params)
|
||||
const data = await handleGetAPPROVALROUTEList(req)
|
||||
console.log('fdsjfhsdjkfhsa', data);
|
||||
|
||||
if (data && data.length > 0) {
|
||||
return { data, success: true }
|
||||
}
|
||||
return { data: [], success: true }
|
||||
}}
|
||||
toolbar={{
|
||||
actions: [
|
||||
<Button
|
||||
key="new"
|
||||
icon={<PlusOutlined />}
|
||||
type="primary"
|
||||
onClick={(e) => {
|
||||
setModalVisible(true)
|
||||
}}
|
||||
>
|
||||
新增环节
|
||||
</Button>
|
||||
]
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
<Modal
|
||||
title={currentRow ? "编辑环节" : "新增环节"}
|
||||
width={600}
|
||||
destroyOnClose
|
||||
open={modalVisible}
|
||||
confirmLoading={confirmLoading}
|
||||
onOk={(e) => {
|
||||
setModalVisible(false)
|
||||
modalFormRef.current?.validateFields().then((res: any) => {
|
||||
modalFormRef.current?.submit()
|
||||
})
|
||||
}}
|
||||
onCancel={(e) => {
|
||||
setModalVisible(false)
|
||||
modalFormRef.current?.resetFields();
|
||||
setDefaultPerson([])
|
||||
setPlayerList([])
|
||||
setCurrentRow(undefined)
|
||||
}}
|
||||
>
|
||||
<ProForm
|
||||
formRef={modalFormRef}
|
||||
submitter={false}
|
||||
initialValues={currentRow}
|
||||
request={async () => {
|
||||
console.log('currentRowcurrentRow', currentRow);
|
||||
|
||||
if (currentRow) {
|
||||
if (currentRow?.APPROVALSTAFF_ID) {
|
||||
const req: any = {
|
||||
SearchParameter: {
|
||||
USER_IDS: currentRow?.APPROVALSTAFF_ID
|
||||
},
|
||||
PageIndex: 1,
|
||||
PageSize: 999999
|
||||
}
|
||||
const data = await handleGetUserList(req)
|
||||
console.log('datadatadata', data);
|
||||
setDefaultPerson(data)
|
||||
|
||||
if (data && data.length > 0) {
|
||||
const list: any = []
|
||||
data.forEach((item: any) => {
|
||||
list.push({ label: item.USER_NAME, value: item.USER_ID.toString() })
|
||||
})
|
||||
setPlayerList(list)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...currentRow,
|
||||
APPROVALSTAFF_ID: currentRow?.APPROVALSTAFF_ID ? currentRow?.APPROVALSTAFF_ID.split(',') : null
|
||||
}
|
||||
} else {
|
||||
return {}
|
||||
}
|
||||
}}
|
||||
onFinish={async (res) => {
|
||||
console.log('readas', res);
|
||||
let req: any = {}
|
||||
if (currentRow) {
|
||||
req = {
|
||||
APPROVALROUTE_ID: currentRow?.APPROVALROUTE_ID,
|
||||
APPROVALROUTE_NAME: res?.APPROVALROUTE_NAME || '',
|
||||
APPROVALROUTE_STATE: res?.APPROVALROUTE_STATE || '',
|
||||
OPERATION_TYPE: res?.OPERATION_TYPE || '',
|
||||
APPROVALSTAFF_ID: res?.APPROVALSTAFF_ID ? res?.APPROVALSTAFF_ID.toString() : null,
|
||||
APPROVALROUTE_VALID: 1,
|
||||
PROVINCE_CODE: '530000',
|
||||
NEXT_STATE: res?.NEXT_STATE
|
||||
}
|
||||
} else {
|
||||
req = {
|
||||
APPROVALROUTE_NAME: res?.APPROVALROUTE_NAME || '',
|
||||
APPROVALROUTE_STATE: res?.APPROVALROUTE_STATE || '',
|
||||
OPERATION_TYPE: res?.OPERATION_TYPE || '',
|
||||
APPROVALSTAFF_ID: res?.APPROVALSTAFF_ID ? res?.APPROVALSTAFF_ID.toString() : null,
|
||||
APPROVALROUTE_VALID: 1,
|
||||
PROVINCE_CODE: '530000',
|
||||
NEXT_STATE: res?.NEXT_STATE
|
||||
}
|
||||
}
|
||||
setConfirmLoading(true)
|
||||
const data = await handleSynchroAPPROVALROUTE(req)
|
||||
setConfirmLoading(false)
|
||||
if (data.Result_Code === 100) {
|
||||
message.success('新增成功')
|
||||
modalFormRef.current?.resetFields();
|
||||
setCurrentRow(undefined)
|
||||
actionRef.current?.reload()
|
||||
setModalVisible(false)
|
||||
setDefaultPerson([])
|
||||
setPlayerList([])
|
||||
return true
|
||||
}
|
||||
message.error(data.Result_Desc)
|
||||
}}
|
||||
>
|
||||
<ProFormTreeSelect
|
||||
label={"业务类型"}
|
||||
name={"OPERATION_TYPE"}
|
||||
request={async (params) => {
|
||||
let list: any = JSON.parse(JSON.stringify(treeView))
|
||||
if (list && list.length > 0) {
|
||||
list.forEach((item: any) => {
|
||||
item.disabled = true
|
||||
})
|
||||
}
|
||||
return list
|
||||
}}
|
||||
fieldProps={{
|
||||
treeDefaultExpandAll: true
|
||||
}}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: '请选择业务类型',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<ProFormText
|
||||
label={'环节名称'}
|
||||
name={'APPROVALROUTE_NAME'}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: '请输入环节名称',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<ProFormDigit
|
||||
label={"业务状态"}
|
||||
name={"APPROVALROUTE_STATE"}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: '请选择业务状态',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<ProFormDigit
|
||||
label={"下一个业务状态"}
|
||||
name={"NEXT_STATE"}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: '请选择下一个业务状态',
|
||||
},
|
||||
]}
|
||||
tooltip={'若下一状态为审结则是9000'}
|
||||
/>
|
||||
|
||||
<ProFormSelect
|
||||
label={'参与人'}
|
||||
name={'APPROVALSTAFF_ID'}
|
||||
width={'lg'}
|
||||
fieldProps={{
|
||||
options: playerList || [],
|
||||
mode: 'multiple'
|
||||
}}
|
||||
addonAfter={
|
||||
<Button type="primary" icon={<FileSearchOutlined />}
|
||||
onClick={() => {
|
||||
const res = modalFormRef.current?.getFieldValue('APPROVALSTAFF_ID')
|
||||
console.log('resres', res);
|
||||
|
||||
// if ([res] && [res].length > 0) {
|
||||
// const list: any = []
|
||||
// [res].forEach((item: any) => {
|
||||
// list.push(Number(item))
|
||||
// })
|
||||
// setDefaultPerson(list)
|
||||
// } else {
|
||||
// setDefaultPerson([])
|
||||
// setPlayerList([])
|
||||
// }
|
||||
setShowChosePlayer(true)
|
||||
}}>
|
||||
选择
|
||||
</Button>}
|
||||
/>
|
||||
|
||||
</ProForm>
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
title={'选择参与人'}
|
||||
width={'80%'}
|
||||
open={showChosePlayer}
|
||||
destroyOnClose
|
||||
bodyStyle={{
|
||||
height: '700px',
|
||||
overflowY: 'auto'
|
||||
}}
|
||||
onOk={(e) => {
|
||||
setShowChosePlayer(false)
|
||||
let detailList: any = chosePlayerRef?.current?.selectedRowDetail
|
||||
console.log('detailListdetailList', detailList);
|
||||
|
||||
let list: any = []
|
||||
if (detailList && detailList.length > 0) {
|
||||
detailList.forEach((item: any) => {
|
||||
list.push({ label: item?.USER_NAME, value: item.USER_ID })
|
||||
})
|
||||
}
|
||||
setPlayerList(list)
|
||||
modalFormRef.current?.setFieldsValue({ APPROVALSTAFF_ID: chosePlayerRef?.current?.selectedRowKeys })
|
||||
}}
|
||||
onCancel={(e) => {
|
||||
setShowChosePlayer(false)
|
||||
}}
|
||||
>
|
||||
<ChosePlayers onRef={chosePlayerRef} actionRef={actionRef} defaultPerson={defaultPerson} />
|
||||
|
||||
</Modal>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
export default BusinessConfiguration;
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,424 @@
|
||||
import LeftSelectTree from "@/components/leftSelectTree/leftSelectTree";
|
||||
import { ActionType, FormInstance, ProTable } from "@ant-design/pro-components";
|
||||
import { useRef, useState } from "react";
|
||||
import { getFieldEnumTreeNoSession, handleGetSUGGESTIONReport } from "../serverpartAssets/service";
|
||||
import { Drawer, Modal } from "antd";
|
||||
import ComplaintForwardingProcessList from "./ComplaintForwardingProcessList";
|
||||
import moment from "moment";
|
||||
|
||||
const ComplaintForwardingProcessReport = () => {
|
||||
const actionRef = useRef<ActionType>();
|
||||
const formRef = useRef<FormInstance>();
|
||||
// 树相关的属性和方法
|
||||
const [selectedId, setSelectedId] = useState<string>()
|
||||
const [collapsible, setCollapsible] = useState<boolean>(false)
|
||||
// 显示详情抽屉
|
||||
const [showDetailModal, setShowDetailModal] = useState<boolean>(false)
|
||||
// 当前行数据
|
||||
const [currentRow, setCurrentRow] = useState<any>()
|
||||
// 要查看的类型
|
||||
const [isComponentsParams, setIsComponentsParams] = useState<any>()
|
||||
// 搜索入参
|
||||
const [searchParams, setSearchParams] = useState<any>()
|
||||
|
||||
// 表格列内容
|
||||
const columns: any = [
|
||||
{
|
||||
title: "统计时间",
|
||||
dataIndex: 'search_date',
|
||||
valueType: 'dateRange',
|
||||
hideInTable: true,
|
||||
hideInDescriptions: true,
|
||||
search: {
|
||||
transform: (value) => {
|
||||
return {
|
||||
SUGGESTION_CREATEDATE_Start: value[0],
|
||||
SUGGESTION_CREATEDATE_End: value[1],
|
||||
};
|
||||
},
|
||||
},
|
||||
initialValue: [moment().subtract(1, 'M'), moment()],
|
||||
},
|
||||
{
|
||||
title: "建议类型",
|
||||
dataIndex: "SUGGESTION_TYPES",
|
||||
valueType: 'select',
|
||||
valueEnum: {
|
||||
"1000": "投诉",
|
||||
"1050": "表扬",
|
||||
"4000": "咨询/建议"
|
||||
},
|
||||
hideInTable: true
|
||||
},
|
||||
{
|
||||
title: "投诉渠道",
|
||||
width: 120,
|
||||
dataIndex: "SUGGESTION_CHANNELS",
|
||||
valueType: "select",
|
||||
align: 'center',
|
||||
request: async () => {
|
||||
const taxRateLabel: any = await getFieldEnumTreeNoSession({ FieldExplainField: 'SUGGESTION_CHANNEL', notformate: true })
|
||||
console.log('taxRateLabeltaxRateLabel', taxRateLabel);
|
||||
|
||||
return taxRateLabel
|
||||
},
|
||||
hideInTable: true
|
||||
},
|
||||
{
|
||||
title: "服务区",
|
||||
width: 200,
|
||||
align: 'center',
|
||||
dataIndex: "ServerPart_Name",
|
||||
hideInSearch: true,
|
||||
ellipsis: true,
|
||||
render: (_, record) => {
|
||||
return record?.SpregionType_Name || record?.ServerPart_Name
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "总计",
|
||||
width: 120,
|
||||
align: 'center',
|
||||
dataIndex: "TotalCount",
|
||||
hideInSearch: true,
|
||||
ellipsis: true,
|
||||
render: (_, record) => {
|
||||
return record?.TotalCount ? <a onClick={() => {
|
||||
handleGetComponentsParams(1, record)
|
||||
setCurrentRow(record)
|
||||
setShowDetailModal(true)
|
||||
}}> {record?.TotalCount}</a > : "0"
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "投诉数量",
|
||||
width: 120,
|
||||
align: 'center',
|
||||
dataIndex: "ComplaintCount",
|
||||
hideInSearch: true,
|
||||
ellipsis: true,
|
||||
render: (_, record) => {
|
||||
return record?.ComplaintCount ? <a onClick={() => {
|
||||
handleGetComponentsParams(2, record)
|
||||
setCurrentRow(record)
|
||||
setShowDetailModal(true)
|
||||
}}> {record?.ComplaintCount}</a > : "0"
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "表扬数量",
|
||||
width: 120,
|
||||
align: 'center',
|
||||
dataIndex: "PraiseCount",
|
||||
hideInSearch: true,
|
||||
ellipsis: true,
|
||||
render: (_, record) => {
|
||||
return record?.PraiseCount ? <a onClick={() => {
|
||||
handleGetComponentsParams(3, record)
|
||||
setCurrentRow(record)
|
||||
setShowDetailModal(true)
|
||||
}}> {record?.PraiseCount}</a> : "0"
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "咨询建议数量",
|
||||
width: 120,
|
||||
align: 'center',
|
||||
dataIndex: "ConsultationSuggestionCount",
|
||||
hideInSearch: true,
|
||||
ellipsis: true,
|
||||
render: (_, record) => {
|
||||
return record?.ConsultationSuggestionCount ? <a onClick={() => {
|
||||
handleGetComponentsParams(4, record)
|
||||
setCurrentRow(record)
|
||||
setShowDetailModal(true)
|
||||
}}> {record?.ConsultationSuggestionCount}</a> : "0"
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "小程序数量",
|
||||
width: 120,
|
||||
align: 'center',
|
||||
dataIndex: "MiniProgramCount",
|
||||
hideInSearch: true,
|
||||
ellipsis: true,
|
||||
render: (_, record) => {
|
||||
return record?.MiniProgramCount ? <a onClick={() => {
|
||||
handleGetComponentsParams(5, record)
|
||||
setCurrentRow(record)
|
||||
setShowDetailModal(true)
|
||||
}}> {record?.MiniProgramCount}</a> : "0"
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "12328交通运输数量",
|
||||
width: 120,
|
||||
align: 'center',
|
||||
dataIndex: "Transport12328Count",
|
||||
hideInSearch: true,
|
||||
ellipsis: true,
|
||||
render: (_, record) => {
|
||||
return record?.Transport12328Count ? <a onClick={() => {
|
||||
handleGetComponentsParams(6, record)
|
||||
setCurrentRow(record)
|
||||
setShowDetailModal(true)
|
||||
}}> {record?.Transport12328Count}</a> : "0"
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "网络舆情数量",
|
||||
width: 120,
|
||||
align: 'center',
|
||||
dataIndex: "OnlineOpinionCount",
|
||||
hideInSearch: true,
|
||||
ellipsis: true,
|
||||
render: (_, record) => {
|
||||
return record?.OnlineOpinionCount ? <a onClick={() => {
|
||||
handleGetComponentsParams(7, record)
|
||||
setCurrentRow(record)
|
||||
setShowDetailModal(true)
|
||||
}}> {record?.OnlineOpinionCount}</a> : "0"
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "监控中心值班电话数量",
|
||||
width: 120,
|
||||
align: 'center',
|
||||
dataIndex: "MonitoringCenterCount",
|
||||
hideInSearch: true,
|
||||
ellipsis: true,
|
||||
render: (_, record) => {
|
||||
return record?.MonitoringCenterCount ? <a onClick={() => {
|
||||
handleGetComponentsParams(8, record)
|
||||
setCurrentRow(record)
|
||||
setShowDetailModal(true)
|
||||
}}> {record?.MonitoringCenterCount}</a> : "0"
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "话务转办数量",
|
||||
width: 120,
|
||||
align: 'center',
|
||||
dataIndex: "TransferCount",
|
||||
hideInSearch: true,
|
||||
ellipsis: true,
|
||||
render: (_, record) => {
|
||||
return record?.TransferCount ? <a onClick={() => {
|
||||
handleGetComponentsParams(9, record)
|
||||
setCurrentRow(record)
|
||||
setShowDetailModal(true)
|
||||
}}> {record?.TransferCount}</a> : "0"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
// 处理入参的办法
|
||||
const handleGetComponentsParams = (type: number, obj: any) => {
|
||||
// type 1 总计 2 投诉数量 3 表扬数量 4 咨询建议数量 5 小程序数量 6 12328交通运输数量 7 网络舆情数量 8 监控中心值班电话数量 9 话务转办数量
|
||||
console.log('dasda', obj);
|
||||
|
||||
let req: any = {}
|
||||
let SERVERPART_IDS: string = ""
|
||||
if (obj.Type === 0) {
|
||||
if (obj.children && obj.children.length > 0) {
|
||||
obj.children.forEach((item: any) => {
|
||||
if (SERVERPART_IDS) {
|
||||
SERVERPART_IDS += `,${item.ServerPart_Id}`
|
||||
} else {
|
||||
SERVERPART_IDS = item.ServerPart_Id
|
||||
}
|
||||
})
|
||||
}
|
||||
} else if (obj.Type === 1) {
|
||||
SERVERPART_IDS = obj.ServerPart_Id
|
||||
}
|
||||
console.log('SERVERPART_IDSSERVERPART_IDS', SERVERPART_IDS);
|
||||
console.log('type123123', type);
|
||||
|
||||
if (type === 1) {
|
||||
req = {
|
||||
SearchParameter: {
|
||||
SERVERPART_IDS: SERVERPART_IDS,
|
||||
SUGGESTION_CREATEDATE_Start: searchParams?.SUGGESTION_CREATEDATE_Start || "",
|
||||
SUGGESTION_CREATEDATE_End: searchParams?.SUGGESTION_CREATEDATE_End || ""
|
||||
},
|
||||
SortStr: "SUGGESTION_CREATEDATE desc",
|
||||
PageIndex: 1,
|
||||
PageSize: "999999"
|
||||
}
|
||||
} else if (type === 2) {
|
||||
req = {
|
||||
SearchParameter: {
|
||||
SERVERPART_IDS: SERVERPART_IDS,
|
||||
SUGGESTION_TYPES: "1000,2000",
|
||||
SUGGESTION_CREATEDATE_Start: searchParams?.SUGGESTION_CREATEDATE_Start || "",
|
||||
SUGGESTION_CREATEDATE_End: searchParams?.SUGGESTION_CREATEDATE_End || ""
|
||||
},
|
||||
SortStr: "SUGGESTION_CREATEDATE desc",
|
||||
PageIndex: 1,
|
||||
PageSize: "999999"
|
||||
}
|
||||
} else if (type === 3) {
|
||||
req = {
|
||||
SearchParameter: {
|
||||
SERVERPART_IDS: SERVERPART_IDS,
|
||||
SUGGESTION_TYPES: "1050",
|
||||
SUGGESTION_CREATEDATE_Start: searchParams?.SUGGESTION_CREATEDATE_Start || "",
|
||||
SUGGESTION_CREATEDATE_End: searchParams?.SUGGESTION_CREATEDATE_End || ""
|
||||
},
|
||||
SortStr: "SUGGESTION_CREATEDATE desc",
|
||||
PageIndex: 1,
|
||||
PageSize: "999999"
|
||||
}
|
||||
} else if (type === 4) {
|
||||
req = {
|
||||
SearchParameter: {
|
||||
SERVERPART_IDS: SERVERPART_IDS,
|
||||
SUGGESTION_TYPES: "4000",
|
||||
SUGGESTION_CREATEDATE_Start: searchParams?.SUGGESTION_CREATEDATE_Start || "",
|
||||
SUGGESTION_CREATEDATE_End: searchParams?.SUGGESTION_CREATEDATE_End || ""
|
||||
},
|
||||
SortStr: "SUGGESTION_CREATEDATE desc",
|
||||
PageIndex: 1,
|
||||
PageSize: "999999"
|
||||
}
|
||||
} else if (type === 5) {
|
||||
req = {
|
||||
SearchParameter: {
|
||||
SERVERPART_IDS: SERVERPART_IDS,
|
||||
SUGGESTION_CHANNELS: "1000",
|
||||
SUGGESTION_CREATEDATE_Start: searchParams?.SUGGESTION_CREATEDATE_Start || "",
|
||||
SUGGESTION_CREATEDATE_End: searchParams?.SUGGESTION_CREATEDATE_End || ""
|
||||
},
|
||||
SortStr: "SUGGESTION_CREATEDATE desc",
|
||||
PageIndex: 1,
|
||||
PageSize: "999999"
|
||||
}
|
||||
} else if (type === 6) {
|
||||
req = {
|
||||
SearchParameter: {
|
||||
SERVERPART_IDS: SERVERPART_IDS,
|
||||
SUGGESTION_CHANNELS: "2000",
|
||||
SUGGESTION_CREATEDATE_Start: searchParams?.SUGGESTION_CREATEDATE_Start || "",
|
||||
SUGGESTION_CREATEDATE_End: searchParams?.SUGGESTION_CREATEDATE_End || ""
|
||||
},
|
||||
SortStr: "SUGGESTION_CREATEDATE desc",
|
||||
PageIndex: 1,
|
||||
PageSize: "999999"
|
||||
}
|
||||
} else if (type === 7) {
|
||||
req = {
|
||||
SearchParameter: {
|
||||
SERVERPART_IDS: SERVERPART_IDS,
|
||||
SUGGESTION_CHANNELS: "3000",
|
||||
SUGGESTION_CREATEDATE_Start: searchParams?.SUGGESTION_CREATEDATE_Start || "",
|
||||
SUGGESTION_CREATEDATE_End: searchParams?.SUGGESTION_CREATEDATE_End || ""
|
||||
},
|
||||
SortStr: "SUGGESTION_CREATEDATE desc",
|
||||
PageIndex: 1,
|
||||
PageSize: "999999"
|
||||
}
|
||||
} else if (type === 8) {
|
||||
req = {
|
||||
SearchParameter: {
|
||||
SERVERPART_IDS: SERVERPART_IDS,
|
||||
SUGGESTION_CHANNELS: "4000",
|
||||
SUGGESTION_CREATEDATE_Start: searchParams?.SUGGESTION_CREATEDATE_Start || "",
|
||||
SUGGESTION_CREATEDATE_End: searchParams?.SUGGESTION_CREATEDATE_End || ""
|
||||
},
|
||||
SortStr: "SUGGESTION_CREATEDATE desc",
|
||||
PageIndex: 1,
|
||||
PageSize: "999999"
|
||||
}
|
||||
} else if (type === 9) {
|
||||
req = {
|
||||
SearchParameter: {
|
||||
SERVERPART_IDS: SERVERPART_IDS,
|
||||
SUGGESTION_CHANNELS: "5000",
|
||||
SUGGESTION_CREATEDATE_Start: searchParams?.SUGGESTION_CREATEDATE_Start || "",
|
||||
SUGGESTION_CREATEDATE_End: searchParams?.SUGGESTION_CREATEDATE_End || ""
|
||||
},
|
||||
SortStr: "SUGGESTION_CREATEDATE desc",
|
||||
PageIndex: 1,
|
||||
PageSize: "999999"
|
||||
}
|
||||
}
|
||||
console.log('reqreq', req);
|
||||
|
||||
setIsComponentsParams(req)
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ height: 'calc(100vh - 100px)', background: "#fff", display: 'flex' }}>
|
||||
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} serverPartType={'1000'} ServerpartSiteType={'1000,1010,3000'} />
|
||||
<div style={{
|
||||
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
|
||||
paddingTop: 0,
|
||||
paddingBottom: 0,
|
||||
paddingRight: 0
|
||||
}}>
|
||||
<ProTable
|
||||
actionRef={actionRef}
|
||||
formRef={formRef}
|
||||
columns={columns}
|
||||
bordered
|
||||
rowKey={(record: any) => {
|
||||
return `${record?.SpregionType_Id}-${record?.ServerPart_Id}-${record?.Type}`
|
||||
}}
|
||||
scroll={{ x: '100%', y: 'calc(100vh - 450px)' }}
|
||||
headerTitle={'流程报表'}
|
||||
search={{ span: 6 }}
|
||||
request={async (params) => {
|
||||
if (!selectedId) {
|
||||
return []
|
||||
}
|
||||
console.log('paramsparams', params);
|
||||
|
||||
const req: any = {
|
||||
SearchParameter: {
|
||||
SERVERPART_IDS: selectedId,
|
||||
SUGGESTION_TYPES: params?.SUGGESTION_TYPES || "",
|
||||
SUGGESTION_CHANNELS: params?.SUGGESTION_CHANNELS || "",
|
||||
SUGGESTION_CREATEDATE_Start: params?.SUGGESTION_CREATEDATE_Start || "",
|
||||
SUGGESTION_CREATEDATE_End: params?.SUGGESTION_CREATEDATE_End || ""
|
||||
},
|
||||
PageIndex: 1,
|
||||
PageSize: 999999
|
||||
}
|
||||
setSearchParams(params)
|
||||
const data = await handleGetSUGGESTIONReport(req)
|
||||
console.log('datadata', data);
|
||||
|
||||
if (data && data.length > 0) {
|
||||
return { data, success: true }
|
||||
}
|
||||
return { data: [], success: true }
|
||||
}}
|
||||
toolbar={{
|
||||
actions: [
|
||||
|
||||
]
|
||||
}}
|
||||
/>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<Drawer
|
||||
width={"80%"}
|
||||
open={showDetailModal}
|
||||
onClose={() => {
|
||||
setShowDetailModal(false)
|
||||
setCurrentRow(undefined)
|
||||
setIsComponentsParams(undefined)
|
||||
}}
|
||||
destroyOnClose
|
||||
footer={false}
|
||||
>
|
||||
<ComplaintForwardingProcessList isComponents={true} isComponentsParams={isComponentsParams} />
|
||||
</Drawer>
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
export default ComplaintForwardingProcessReport;
|
||||
File diff suppressed because it is too large
Load Diff
287
src/pages/ComplaintForwardingProcess/downFile.tsx
Normal file
287
src/pages/ComplaintForwardingProcess/downFile.tsx
Normal file
@ -0,0 +1,287 @@
|
||||
import moment from 'moment';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
let SUGGESTION_TYPEOBJ: any = {
|
||||
1000: "小程序",
|
||||
2000: "12328交通运输",
|
||||
3000: "网络舆情",
|
||||
4000: "监控中心值班电话",
|
||||
5000: "话务转办",
|
||||
}
|
||||
|
||||
// 附件1 结构
|
||||
export const Attachment1 = ({ record }: { record: any }) => {
|
||||
// 根据 record 数据处理显示逻辑
|
||||
return (
|
||||
<div className="printContainer attachment1">
|
||||
<div className="printTitle">附件1:投诉受理工单</div>
|
||||
<div style={{ textAlign: 'left', marginBottom: '5px' }}>编号:{record?.SUGGESTION_CODE || ''}</div>
|
||||
<table className="printTable">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="labelCell">投诉人</td>
|
||||
<td className="contentCell">{record?.SUGGESTION_NAME || ''}</td>
|
||||
<td className="labelCell">联系电话</td>
|
||||
<td className="contentCell">{record?.PHONE_NUMBER || ''}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">受理部门</td>
|
||||
<td className="contentCell">{record?.DISPOSITION_PERSON || ''}</td>
|
||||
<td className="labelCell">受理时间</td>
|
||||
<td className="contentCell">{record?.OPERATE_DATE ? moment(record?.OPERATE_DATE).format('YYYY-MM-DD HH:mm:ss') : ''}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">转办部门</td>
|
||||
<td className="contentCell">{record?.MANAGER_NAME || ''}</td>
|
||||
<td className="labelCell">来电类别</td>
|
||||
<td className="contentCell">{record?.SUGGESTION_TYPE ? SUGGESTION_TYPEOBJ[Number(record?.SUGGESTION_TYPE)] : ''}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">来电内容</td>
|
||||
<td colSpan={3} className="contentCell">{record?.SUGGESTION_REASON || ''}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">转办要求</td>
|
||||
<td colSpan={3} className="requirement-cell">{record?.SUGGESTION_INFO || ''}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">处理反馈结果(可附页)</td>
|
||||
<td colSpan={3} className="feedback-cell">
|
||||
<div className="feedback-content-wrapper">
|
||||
<div className="feedback-text">{record?.FEEDBACK_INFO || ''}</div>
|
||||
<div className="feedback-footer">
|
||||
反馈人:{record?.LEADERSHIP_NAME || ''} 时间:{record?.FEEDBACK_DATE ? moment(record?.FEEDBACK_DATE).format('YYYY年MM月DD日 HH时mm分') : ''}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div style={{ textAlign: 'left', marginTop: '5px', marginBottom: '5px' }}>备注:投诉受理工单根据全年投诉发生的时间先后排序,并以彩云驿CYY、投诉GY、年份、工单编号(0001以此类推)。</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// 附件2 结构
|
||||
export const Attachment2 = ({ record }: { record: any }) => (
|
||||
<div className="printContainer attachment2">
|
||||
<div className="printTitle">“12328”交通运输服务监督电话话务转办单</div>
|
||||
<div style={{ textAlign: 'left', marginBottom: '5px' }}>编号:{record?.SUGGESTION_CODE || ''}</div>
|
||||
<table className="printTable">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="labelCell">来电人</td>
|
||||
<td className="contentCell">{record?.SUGGESTION_NAME || ''}</td>
|
||||
<td className="labelCell">联系电话</td>
|
||||
<td className="contentCell">{record?.PHONE_NUMBER || ''}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">受理部门</td>
|
||||
<td className="contentCell">{record?.SERVERPART_NAME || ''}</td>
|
||||
<td className="labelCell">受理时间</td>
|
||||
<td className="contentCell">{record?.SUGGESTION_CREATEDATE || ''}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">转办单位</td>
|
||||
<td className="contentCell">{record?.MANAGER_NAME || ''}</td>
|
||||
<td className="labelCell">来电类别</td>
|
||||
<td className="contentCell">{record?.SUGGESTION_TYPE ? SUGGESTION_TYPEOBJ[Number(record?.SUGGESTION_TYPE)] : ''}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">来电内容</td>
|
||||
<td colSpan={3} className="requirement-cell">
|
||||
<div className="feedback-content-wrapper">
|
||||
<div className="feedback-text">{record?.SUGGESTION_REASON || ''}</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">转办要求</td>
|
||||
<td colSpan={3} className="requirement-cell">
|
||||
<div className="feedback-content-wrapper">
|
||||
<div className="feedback-text">{record?.SUGGESTION_INFO || ''}</div>
|
||||
<div className="feedback-footer">
|
||||
转办人:{record?.DISPOSITION_PERSON || ''} 时间:{record?.OPERATE_DATE ? moment(record?.OPERATE_DATE).format('YYYY年MM月DD日 HH时mm分') : ''}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">处理反馈结果(可附页)</td>
|
||||
<td colSpan={3} className="feedback-cell">
|
||||
<div className="feedback-content-wrapper">
|
||||
<div className="feedback-text">{record?.FEEDBACK_INFO || ''}</div>
|
||||
<div className="feedback-footer">
|
||||
反馈人:{record?.LEADERSHIP_NAME || ''} 时间:{record?.FEEDBACK_DATE ? moment(record?.FEEDBACK_DATE).format('YYYY年MM月DD日 HH时mm分') : ''}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
|
||||
// 附件3 结构
|
||||
export const Attachment3 = ({ record }: { record: any }) => (
|
||||
<div className="printContainer attachment3">
|
||||
<div className="printTitle">网络舆情处置报告书</div>
|
||||
<div style={{ textAlign: 'right', marginBottom: '5px' }}>反馈时间:{record?.SUGGESTION_CREATEDATE ? moment(record?.SUGGESTION_CREATEDATE).format('YYYY年MM月DD日 HH时mm分') : ''}</div>
|
||||
<table className="printTable">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="labelCell">反馈单位(加盖公章)</td>
|
||||
<td colSpan={3} className="contentCell">{record?.MANAGER_NAME || ''}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">签发人</td>
|
||||
<td colSpan={3} className="contentCell">{record?.LEADERSHIP_NAME || ''}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">联系人</td>
|
||||
<td className="contentCell">{record?.LEADERSHIP_NAME || ''}</td>
|
||||
<td className="labelCell">手机号码</td>
|
||||
<td className="contentCell">{record?.PHONE_NUMBER || ''}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">舆情概况</td>
|
||||
<td colSpan={3} className="requirement-cell">
|
||||
<div className="feedback-content-wrapper">
|
||||
<div className="feedback-text">{record?.SUGGESTION_REASON || ''}</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">核实及处置情况(可另附页)</td>
|
||||
<td colSpan={3} className="feedback-cell">
|
||||
<div className="feedback-content-wrapper">
|
||||
<div className="feedback-text">{record?.SUGGESTION_INFO || ''}</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
|
||||
// 打印函数
|
||||
export const handlePrintByIframe = (AttachmentComponent: React.ComponentType<any>, record: any) => {
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.style.position = 'fixed';
|
||||
iframe.style.right = '0';
|
||||
iframe.style.bottom = '0';
|
||||
iframe.style.width = '0';
|
||||
iframe.style.height = '0';
|
||||
iframe.style.border = '0';
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
const iframeDoc = iframe.contentWindow?.document;
|
||||
if (!iframeDoc) return;
|
||||
|
||||
iframeDoc.open();
|
||||
iframeDoc.write(`
|
||||
<html>
|
||||
<head>
|
||||
<title>打印预览</title>
|
||||
<style>
|
||||
@page { size: A4; margin: 15mm; }
|
||||
body { margin: 0; padding: 0; font-family: SimSun, STSong, serif; }
|
||||
.printContainer {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.printTitle { text-align: center; font-size: 24px; font-weight: bold; margin-bottom: 25px; margin-top: 10px; }
|
||||
.printTable {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border: 2px solid #000;
|
||||
table-layout: fixed;
|
||||
}
|
||||
.printTable td { border: 1px solid #000; padding: 10px 12px; font-size: 15px; word-break: break-all; }
|
||||
.labelCell { background-color: #f2f2f2 !important; width: 110px; font-weight: bold; text-align: center; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
||||
.contentCell { text-align: left; }
|
||||
|
||||
/* --- 附件1 专用样式 --- */
|
||||
.attachment1 {
|
||||
min-height: 260mm;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.attachment1 .printTable { height: auto; }
|
||||
.attachment1 .requirement-cell { height: 100px; vertical-align: top; }
|
||||
.attachment1 .feedback-cell { vertical-align: top; padding: 0 !important; }
|
||||
.attachment1 .feedback-content-wrapper {
|
||||
display: flex; flex-direction: column; min-height: 550px; padding: 12px; box-sizing: border-box;
|
||||
}
|
||||
.attachment1 .feedback-text { flex: 1; }
|
||||
.attachment1 .feedback-footer { text-align: right; margin-top: 20px; }
|
||||
|
||||
/* --- 附件2 专用样式 --- */
|
||||
.attachment2 {
|
||||
min-height: 260mm;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.attachment2 .printTable { height: auto; }
|
||||
.attachment2 .requirement-cell { height: 130px; vertical-align: top; padding: 0 !important; }
|
||||
.attachment2 .feedback-cell { vertical-align: top; padding: 0 !important; }
|
||||
|
||||
.attachment2 .feedback-content-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
padding: 12px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.attachment2 .feedback-cell .feedback-content-wrapper {
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
.attachment2 .feedback-text { flex: 1; }
|
||||
.attachment2 .feedback-footer { text-align: right; margin-top: 10px; }
|
||||
|
||||
/* --- 附件3 专用样式 --- */
|
||||
.attachment3 {
|
||||
min-height: 260mm;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.attachment3 .printTable { height: auto; }
|
||||
.attachment3 .requirement-cell { height: 70px; vertical-align: top; padding: 0 !important; }
|
||||
.attachment3 .feedback-cell { vertical-align: top; padding: 0 !important; }
|
||||
|
||||
.attachment3 .feedback-content-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
padding: 12px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.attachment3 .feedback-cell .feedback-content-wrapper {
|
||||
min-height: 500px;
|
||||
}
|
||||
.attachment3 .feedback-text { flex: 1; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="print-root"></div>
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
iframeDoc.close();
|
||||
|
||||
const printRoot = iframeDoc.getElementById('print-root');
|
||||
if (printRoot) {
|
||||
ReactDOM.render(React.createElement(AttachmentComponent, { record }), printRoot);
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
iframe.contentWindow?.focus();
|
||||
iframe.contentWindow?.print();
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(iframe);
|
||||
}, 1000);
|
||||
}, 300);
|
||||
};
|
||||
@ -4,6 +4,32 @@
|
||||
此文件目前仅保留页面基础样式(如有)。
|
||||
*/
|
||||
|
||||
.print-ignore {
|
||||
/* 页面按钮展示样式 */
|
||||
.custom-steps {
|
||||
display: flex !important;
|
||||
flex-wrap: wrap !important;
|
||||
|
||||
.ant-steps-item {
|
||||
flex: none !important;
|
||||
width: 200px !important;
|
||||
/* 固定每个步骤的宽度,你可以根据需要调整 */
|
||||
margin-right: 24px !important;
|
||||
/* 每个步骤之间的固定间距 */
|
||||
margin-bottom: 24px !important;
|
||||
/* 换行后的行间距 */
|
||||
padding-inline-start: 0 !important;
|
||||
|
||||
// 隐藏连接线,因为换行后的连线轨迹会错乱
|
||||
.ant-steps-item-tail {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
// 调整标题和描述的布局,确保紧凑
|
||||
.ant-steps-item-content {
|
||||
overflow: visible;
|
||||
|
||||
.ant-steps-item-title {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
96
src/pages/ComplaintForwardingProcess/resizeImageHalf.ts
Normal file
96
src/pages/ComplaintForwardingProcess/resizeImageHalf.ts
Normal file
@ -0,0 +1,96 @@
|
||||
export interface ResizeHalfOptions {
|
||||
quality?: number;
|
||||
}
|
||||
|
||||
export const resizeImageHalf = (
|
||||
file: File,
|
||||
options: ResizeHalfOptions = {}
|
||||
): Promise<File> => {
|
||||
const {
|
||||
quality = 0.8
|
||||
} = options;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!file || !file.type.includes('image')) {
|
||||
reject(new Error('无效的图片文件'));
|
||||
return;
|
||||
}
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
resizeToHalfDimensions(img, file, quality, resolve, reject);
|
||||
};
|
||||
img.onerror = () => reject(new Error('图片加载失败'));
|
||||
img.src = e.target?.result as string;
|
||||
};
|
||||
reader.onerror = () => reject(new Error('文件读取失败'));
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 图片处理函数 - 将图片长宽分辨率精确减半
|
||||
*/
|
||||
function resizeToHalfDimensions(
|
||||
img: HTMLImageElement,
|
||||
originalFile: File,
|
||||
quality: number,
|
||||
resolve: (file: File) => void,
|
||||
reject: (error: Error) => void
|
||||
) {
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
if (!ctx) {
|
||||
reject(new Error('浏览器不支持Canvas'));
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算减半后的尺寸
|
||||
const halfWidth = Math.floor(img.width / 2);
|
||||
const halfHeight = Math.floor(img.height / 2);
|
||||
|
||||
console.log(`原图尺寸: ${img.width}x${img.height}`);
|
||||
console.log(`减半后尺寸: ${halfWidth}x${halfHeight}`);
|
||||
|
||||
// 设置canvas尺寸为原图的一半
|
||||
canvas.width = halfWidth;
|
||||
canvas.height = halfHeight;
|
||||
|
||||
// 在canvas上绘制缩小后的图片
|
||||
// 使用平滑缩放算法以获得更好的图像质量
|
||||
ctx.imageSmoothingEnabled = true;
|
||||
ctx.imageSmoothingQuality = 'high';
|
||||
ctx.drawImage(img, 0, 0, halfWidth, halfHeight);
|
||||
|
||||
// 将canvas转换为Blob并创建新的File对象
|
||||
canvas.toBlob(
|
||||
(blob) => {
|
||||
if (!blob) {
|
||||
reject(new Error('图片处理失败'));
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建新的文件名,添加_resize_half后缀
|
||||
const fileNameParts = originalFile.name.split('.');
|
||||
const extension = fileNameParts.pop();
|
||||
const fileNameWithoutExtension = fileNameParts.join('.');
|
||||
const newFileName = `${fileNameWithoutExtension}_half.${extension}`;
|
||||
|
||||
// 创建压缩后的文件对象
|
||||
const resizedFile = new File([blob], newFileName, {
|
||||
type: originalFile.type,
|
||||
lastModified: Date.now()
|
||||
});
|
||||
|
||||
console.log(`✅ 图片尺寸减半完成: ${img.width}x${img.height} → ${halfWidth}x${halfHeight}`);
|
||||
console.log(`文件大小: ${(originalFile.size / 1024).toFixed(1)}KB → ${(resizedFile.size / 1024).toFixed(1)}KB`);
|
||||
|
||||
resolve(resizedFile);
|
||||
},
|
||||
originalFile.type,
|
||||
quality
|
||||
);
|
||||
}
|
||||
304
src/pages/ComplaintForwardingProcess/test.tsx
Normal file
304
src/pages/ComplaintForwardingProcess/test.tsx
Normal file
@ -0,0 +1,304 @@
|
||||
import { Button } from "antd";
|
||||
import ReactDOM from "react-dom";
|
||||
import "./index.less";
|
||||
|
||||
const ComplaintForwardingProcess = () => {
|
||||
// 附件1 结构(已根据您的要求优化)
|
||||
const Attachment1 = () => (
|
||||
<div className="printContainer attachment1">
|
||||
<div className="printTitle">附件1:投诉受理工单</div>
|
||||
<div style={{ textAlign: 'left', marginBottom: '5px' }}>编号:</div>
|
||||
<table className="printTable">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="labelCell">投诉人</td>
|
||||
<td className="contentCell"></td>
|
||||
<td className="labelCell">联系电话</td>
|
||||
<td className="contentCell"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">受理部门</td>
|
||||
<td className="contentCell"></td>
|
||||
<td className="labelCell">受理时间</td>
|
||||
<td className="contentCell"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">转办部门</td>
|
||||
<td className="contentCell"></td>
|
||||
<td className="labelCell">来电类别</td>
|
||||
<td className="contentCell"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">来电内容</td>
|
||||
<td colSpan={3} className="contentCell"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">转办要求</td>
|
||||
<td colSpan={3} className="requirement-cell"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">处理反馈结果(可附页)</td>
|
||||
<td colSpan={3} className="feedback-cell">
|
||||
<div className="feedback-content-wrapper">
|
||||
<div className="feedback-text"></div>
|
||||
<div className="feedback-footer">
|
||||
反馈人: 时间: 年 月 日 时 分
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div style={{ textAlign: 'left', marginTop: '5px', marginBottom: '5px' }}>备注:投诉受理工单根据全年投诉发生的时间先后排序,并以彩云驿CYY、投诉GY、年份、工单编号(0001以此类推)。</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
// 附件2 结构(恢复独立,不受附件1样式影响)
|
||||
const Attachment2 = () => (
|
||||
<div className="printContainer attachment2">
|
||||
<div className="printTitle">“12328”交通运输服务监督电话话务转办单</div>
|
||||
<div style={{ textAlign: 'left', marginBottom: '5px' }}>编号:</div>
|
||||
<table className="printTable">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="labelCell">来电人</td>
|
||||
<td className="contentCell"></td>
|
||||
<td className="labelCell">联系电话</td>
|
||||
<td className="contentCell"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">受理部门</td>
|
||||
<td className="contentCell"></td>
|
||||
<td className="labelCell">受理时间</td>
|
||||
<td className="contentCell"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">转办单位</td>
|
||||
<td className="contentCell"></td>
|
||||
<td className="labelCell">来电类别</td>
|
||||
<td className="contentCell"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">来电内容</td>
|
||||
<td colSpan={3} className="requirement-cell">
|
||||
<div className="feedback-content-wrapper">
|
||||
<div className="feedback-text"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">转办要求</td>
|
||||
<td colSpan={3} className="requirement-cell">
|
||||
<div className="feedback-content-wrapper">
|
||||
<div className="feedback-text"></div>
|
||||
<div className="feedback-footer">
|
||||
转办人: 时间:
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">处理反馈结果(可附页)</td>
|
||||
<td colSpan={3} className="feedback-cell">
|
||||
<div className="feedback-content-wrapper">
|
||||
<div className="feedback-text"></div>
|
||||
<div className="feedback-footer">
|
||||
反馈人: 时间:
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
|
||||
// 附件3 结构(已加入高度优化)
|
||||
const Attachment3 = () => (
|
||||
<div className="printContainer attachment3">
|
||||
<div className="printTitle">网络舆情处置报告书</div>
|
||||
<div style={{ textAlign: 'right', marginBottom: '5px' }}>反馈时间: 年 月 日</div>
|
||||
<table className="printTable">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="labelCell">反馈单位(加盖公章)</td>
|
||||
<td colSpan={3} className="contentCell"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">签发人</td>
|
||||
<td colSpan={3} className="contentCell"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">联系人</td>
|
||||
<td className="contentCell"></td>
|
||||
<td className="labelCell">手机号码</td>
|
||||
<td className="contentCell"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">舆情概况</td>
|
||||
<td colSpan={3} className="requirement-cell">
|
||||
<div className="feedback-content-wrapper">
|
||||
<div className="feedback-text"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="labelCell">核实及处置情况(可另附页)</td>
|
||||
<td colSpan={3} className="feedback-cell">
|
||||
<div className="feedback-content-wrapper">
|
||||
<div className="feedback-text"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
|
||||
// 真正的打印函数,使用 Iframe 隔离
|
||||
const handlePrintByIframe = (AttachmentComponent: React.ComponentType) => {
|
||||
// 1. 创建隐藏的 iframe
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.style.position = 'fixed';
|
||||
iframe.style.right = '0';
|
||||
iframe.style.bottom = '0';
|
||||
iframe.style.width = '0';
|
||||
iframe.style.height = '0';
|
||||
iframe.style.border = '0';
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
const iframeDoc = iframe.contentWindow?.document;
|
||||
if (!iframeDoc) return;
|
||||
|
||||
// 2. 注入样式和容器
|
||||
iframeDoc.open();
|
||||
iframeDoc.write(`
|
||||
<html>
|
||||
<head>
|
||||
<title>打印预览</title>
|
||||
<style>
|
||||
@page { size: A4; margin: 15mm; }
|
||||
body { margin: 0; padding: 0; font-family: SimSun, STSong, serif; }
|
||||
.printContainer {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.printTitle { text-align: center; font-size: 24px; font-weight: bold; margin-bottom: 25px; margin-top: 10px; }
|
||||
.printTable {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border: 2px solid #000;
|
||||
table-layout: fixed;
|
||||
}
|
||||
.printTable td { border: 1px solid #000; padding: 10px 12px; font-size: 15px; word-break: break-all; }
|
||||
.labelCell { background-color: #f2f2f2 !important; width: 110px; font-weight: bold; text-align: center; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
||||
.contentCell { text-align: left; }
|
||||
|
||||
/* --- 附件1 专用样式 --- */
|
||||
.attachment1 {
|
||||
min-height: 260mm;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.attachment1 .printTable { height: auto; }
|
||||
.attachment1 .requirement-cell { height: 100px; vertical-align: top; }
|
||||
.attachment1 .feedback-cell { vertical-align: top; padding: 0 !important; }
|
||||
.attachment1 .feedback-content-wrapper {
|
||||
display: flex; flex-direction: column; min-height: 550px; padding: 12px; box-sizing: border-box;
|
||||
}
|
||||
.attachment1 .feedback-text { flex: 1; }
|
||||
.attachment1 .feedback-footer { text-align: right; margin-top: 20px; }
|
||||
|
||||
/* --- 附件2 专用样式 --- */
|
||||
.attachment2 {
|
||||
min-height: 260mm;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.attachment2 .printTable { height: auto; }
|
||||
/* 来电内容和转办要求:默认四行 (约 130px) */
|
||||
.attachment2 .requirement-cell { height: 130px; vertical-align: top; padding: 0 !important; }
|
||||
.attachment2 .feedback-cell { vertical-align: top; padding: 0 !important; }
|
||||
|
||||
/* 公用的内容包装器:用于签名贴底 */
|
||||
.attachment2 .feedback-content-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
padding: 12px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 关键修复:只有真正的反馈区域才需要 min-height 来撑开全页 */
|
||||
.attachment2 .feedback-cell .feedback-content-wrapper {
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
.attachment2 .feedback-text { flex: 1; }
|
||||
.attachment2 .feedback-footer { text-align: right; margin-top: 10px; }
|
||||
|
||||
/* --- 附件3 专用样式 --- */
|
||||
.attachment3 {
|
||||
min-height: 260mm;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.attachment3 .printTable { height: auto; }
|
||||
/* 舆情概况:默认两行 (约 70px) */
|
||||
.attachment3 .requirement-cell { height: 70px; vertical-align: top; padding: 0 !important; }
|
||||
.attachment3 .feedback-cell { vertical-align: top; padding: 0 !important; }
|
||||
|
||||
.attachment3 .feedback-content-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
padding: 12px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.attachment3 .feedback-cell .feedback-content-wrapper {
|
||||
min-height: 500px;
|
||||
}
|
||||
.attachment3 .feedback-text { flex: 1; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="print-root"></div>
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
iframeDoc.close();
|
||||
|
||||
// 3. 将 React 组件渲染到 iframe 中
|
||||
const printRoot = iframeDoc.getElementById('print-root');
|
||||
if (printRoot) {
|
||||
ReactDOM.render(<AttachmentComponent />, printRoot);
|
||||
}
|
||||
|
||||
// 4. 调用打印
|
||||
setTimeout(() => {
|
||||
iframe.contentWindow?.focus();
|
||||
iframe.contentWindow?.print();
|
||||
// 5. 打印完成后清理
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(iframe);
|
||||
}, 1000);
|
||||
}, 300);
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ padding: '24px' }}>
|
||||
<div style={{ display: 'flex', gap: '16px', marginBottom: '24px' }}>
|
||||
<Button type="primary" onClick={() => handlePrintByIframe(Attachment1)}>打印附件1</Button>
|
||||
<Button type="primary" onClick={() => handlePrintByIframe(Attachment2)}>打印附件2</Button>
|
||||
<Button type="primary" onClick={() => handlePrintByIframe(Attachment3)}>打印附件3</Button>
|
||||
</div>
|
||||
|
||||
<div style={{ color: '#999', fontSize: '14px' }}>
|
||||
提示:点击按钮将使用 Iframe 隔离技术打开打印预览。这能确保**只打印表格内容**,而不会包含页面上的其他元素。
|
||||
当前已优化布局:转办要求默认2行,反馈结果自动填充剩余页面高度。
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ComplaintForwardingProcess;
|
||||
@ -16,6 +16,10 @@ const authority: PageAuthority = {
|
||||
'/realEstate/index': ['/realEstate/index'],
|
||||
'/ComplaintApproval/index': ['/ComplaintApproval/index'],
|
||||
'/ComplaintForwardingProcess/index': ['/ComplaintForwardingProcess/index'],
|
||||
'/ComplaintForwardingProcess/ComplaintForwardingProcessReview': ['/ComplaintForwardingProcess/ComplaintForwardingProcessReview'],
|
||||
'/ComplaintForwardingProcess/ComplaintForwardingProcessList': ['/ComplaintForwardingProcess/ComplaintForwardingProcessList'],
|
||||
'/ComplaintForwardingProcess/ComplaintForwardingProcessReport': ['/ComplaintForwardingProcess/ComplaintForwardingProcessReport'],
|
||||
'/BusinessConfiguration/index': ['/BusinessConfiguration/index'],
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -595,3 +595,163 @@ export async function handleGetServerpartList(params?: any) {
|
||||
|
||||
}
|
||||
|
||||
// 查询业务环节配置的列表
|
||||
export async function handleGetAPPROVALROUTEList(params?: any) {
|
||||
|
||||
const data = await requestSamember(`/BusinessProcess/GetAPPROVALROUTEList`, {
|
||||
method: 'POST',
|
||||
data: params,
|
||||
});
|
||||
|
||||
if (data.Result_Code !== 100) {
|
||||
return []
|
||||
}
|
||||
|
||||
return data.Result_Data.List;
|
||||
|
||||
}
|
||||
|
||||
// 获取账号分类树
|
||||
export async function getUserTypeTree(params?: any) {
|
||||
const data = await requestSamember('/FrameWork/GetUserTypeTree', {
|
||||
method: 'GET',
|
||||
params
|
||||
})
|
||||
|
||||
if (data.Result_Code !== 100) {
|
||||
return []
|
||||
}
|
||||
|
||||
const treeTable = wrapTreeNode(data.Result_Data.List);
|
||||
return [...treeTable];
|
||||
}
|
||||
|
||||
|
||||
// 获取账号
|
||||
export async function handleGetUserList(params?: any) {
|
||||
const data = await requestSamember('/Platform/GetUserList', {
|
||||
method: 'POST',
|
||||
data: params
|
||||
})
|
||||
|
||||
if (data.Result_Code !== 100) {
|
||||
return data
|
||||
}
|
||||
|
||||
return data.Result_Data.List
|
||||
}
|
||||
|
||||
export async function getOnwer(params?: any) {
|
||||
const data = await requestSamember('/BaseInfo/BindingOwnerUnitDDL', {
|
||||
method: 'GET',
|
||||
params
|
||||
})
|
||||
|
||||
if (data.Result_Code !== 100) {
|
||||
return data
|
||||
}
|
||||
|
||||
return data.Result_Data.List
|
||||
}
|
||||
|
||||
// 配置审批环节
|
||||
export async function handleSynchroAPPROVALROUTE(params?: any) {
|
||||
const data = await requestSamember('/BusinessProcess/SynchroAPPROVALROUTE', {
|
||||
method: 'POST',
|
||||
data: params
|
||||
})
|
||||
|
||||
if (data.Result_Code !== 100) {
|
||||
return data
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
// 删除配置审批环节
|
||||
export async function handleDeleteAPPROVALROUTE(params?: any) {
|
||||
const data = await requestSamember(`/BusinessProcess/DeleteAPPROVALROUTE`, {
|
||||
method: 'GET',
|
||||
params
|
||||
});
|
||||
if (data.Result_Code !== 100) {
|
||||
return data
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
// 获取用户建议表列表
|
||||
export async function handleGetSUGGESTIONList(params?: any) {
|
||||
const data = await requestSamember('/SiteManage/GetSUGGESTIONList', {
|
||||
method: 'POST',
|
||||
data: params
|
||||
})
|
||||
|
||||
if (data.Result_Code !== 100) {
|
||||
return data
|
||||
}
|
||||
|
||||
return data.Result_Data.List
|
||||
}
|
||||
|
||||
// 同步用户建议表
|
||||
export async function handleSynchroSUGGESTION(params?: any) {
|
||||
const data = await requestSamember('/SiteManage/SynchroSUGGESTION', {
|
||||
method: 'POST',
|
||||
data: params
|
||||
})
|
||||
|
||||
if (data.Result_Code !== 100) {
|
||||
return data
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
// 删除用户建议表
|
||||
export async function handleDeleteSUGGESTION(params?: any) {
|
||||
const data = await requestSamember(`/SiteManage/DeleteSUGGESTION`, {
|
||||
method: 'GET',
|
||||
params
|
||||
});
|
||||
if (data.Result_Code !== 100) {
|
||||
return data
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
// 同步审批意见
|
||||
export async function handleSynchroAPPLYAPPROVE(params?: any) {
|
||||
const data = await requestSamember(`/BusinessProcess/SynchroAPPLYAPPROVE`, {
|
||||
method: 'POST',
|
||||
data: params
|
||||
});
|
||||
if (data.Result_Code !== 100) {
|
||||
return data
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
// 审批意见的流程过程
|
||||
export async function handleGetAPPLYAPPROVEList(params?: any) {
|
||||
const data = await requestSamember(`/BusinessProcess/GetAPPLYAPPROVEList`, {
|
||||
method: 'POST',
|
||||
data: params
|
||||
});
|
||||
if (data.Result_Code !== 100) {
|
||||
return data
|
||||
}
|
||||
return data.Result_Data.List;
|
||||
}
|
||||
|
||||
// 用户建议报表页面
|
||||
export async function handleGetSUGGESTIONReport(params?: any) {
|
||||
const data = await requestSamember(`/SiteManage/GetSUGGESTIONReport`, {
|
||||
method: 'POST',
|
||||
data: params
|
||||
});
|
||||
if (data.Result_Code !== 100) {
|
||||
return data
|
||||
}
|
||||
return wrapTreeNode(data.Result_Data);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user