update
This commit is contained in:
parent
3357d03316
commit
9925f330bd
@ -87,6 +87,11 @@ export default [
|
|||||||
path: '/ComplaintForwardingProcess/index',
|
path: '/ComplaintForwardingProcess/index',
|
||||||
name: '投诉转发流程',
|
name: '投诉转发流程',
|
||||||
component: "@/pages/ComplaintForwardingProcess/index",
|
component: "@/pages/ComplaintForwardingProcess/index",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/BusinessConfiguration/index',
|
||||||
|
name: '业务配置',
|
||||||
|
component: "@/pages/BusinessConfiguration/index",
|
||||||
}
|
}
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|||||||
@ -317,6 +317,12 @@ const UserModel: UserModelType = {
|
|||||||
name: '投诉转发流程',
|
name: '投诉转发流程',
|
||||||
component: "@/pages/ComplaintForwardingProcess/index",
|
component: "@/pages/ComplaintForwardingProcess/index",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/BusinessConfiguration/index',
|
||||||
|
redirect: '',
|
||||||
|
name: '业务配置',
|
||||||
|
component: "@/pages/BusinessConfiguration/index",
|
||||||
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,6 +408,7 @@ const UserModel: UserModelType = {
|
|||||||
"/realEstate/index",
|
"/realEstate/index",
|
||||||
"/ComplaintApproval/index",
|
"/ComplaintApproval/index",
|
||||||
"/ComplaintForwardingProcess/index",
|
"/ComplaintForwardingProcess/index",
|
||||||
|
"/BusinessConfiguration/index",
|
||||||
// '/examine/index',
|
// '/examine/index',
|
||||||
// '/examine/modal',
|
// '/examine/modal',
|
||||||
// '/examine/question',
|
// '/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[0].children)
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
489
src/pages/BusinessConfiguration/index.tsx
Normal file
489
src/pages/BusinessConfiguration/index.tsx
Normal file
@ -0,0 +1,489 @@
|
|||||||
|
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
|
||||||
|
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
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,7 @@ const authority: PageAuthority = {
|
|||||||
'/realEstate/index': ['/realEstate/index'],
|
'/realEstate/index': ['/realEstate/index'],
|
||||||
'/ComplaintApproval/index': ['/ComplaintApproval/index'],
|
'/ComplaintApproval/index': ['/ComplaintApproval/index'],
|
||||||
'/ComplaintForwardingProcess/index': ['/ComplaintForwardingProcess/index'],
|
'/ComplaintForwardingProcess/index': ['/ComplaintForwardingProcess/index'],
|
||||||
|
'/BusinessConfiguration/index': ['/BusinessConfiguration/index'],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -595,3 +595,152 @@ 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user