Compare commits

...

2 Commits

Author SHA1 Message Date
xielei 155aca0416 Merge branch 'master' of http://10.0.41.100:3000/lishenfeng/tsg-web 2024-09-23 18:03:36 +08:00
xielei e6a7298010 caidan 2024-09-23 18:03:30 +08:00
20 changed files with 2350 additions and 68 deletions

View File

@ -202,4 +202,10 @@ code {
.ant-table-title{
padding: 0 !important;
padding-right: 10px !important;
}
.flex{
display: flex;
}
.flex-end{
justify-content: flex-end;
}

View File

@ -32,17 +32,17 @@ export function removeLoginInfo() {
let keysToKeep = ["checked", "loginNamePwd"];
let keysToRemove = [];
// 遍历 localStorage
for (let i = 0; i < localStorage.length; i++) {
let key: any = localStorage.key(i);
if (!keysToKeep.includes(key)) {
keysToRemove.push(key);
}
for (let i = 0; i < localStorage.length; i++) {
let key: any = localStorage.key(i);
if (!keysToKeep.includes(key)) {
keysToRemove.push(key);
}
}
for (let i = 0; i < keysToRemove.length; i++) {
localStorage.removeItem(keysToRemove[i]);
}
/*localStorage.removeItem(USER_SESSION_KEY);
localStorage.removeItem('TOKEN');*/
@ -67,7 +67,7 @@ export function getUserFromSession(): LoginUser | null {
if (obj.id && obj.tokenInfo.tokenValue) {
return obj
}
} catch (e) {}
} catch (e) { }
return null
}
@ -114,55 +114,55 @@ function idgen() {
return () => `${id++}`
}
const handelTreeData = (data:any,id:any)=>{
const handelTreeData = (data: any, id: any) => {
if (data.length > 0) {
data.forEach((item:any) => {
item.id = id()
item.title = item.menuName;
item.icon = item.icon;
data.forEach((item: any) => {
item.id = id()
item.title = item.menuName;
item.icon = item.icon;
if(item.menuType==='M'&&item.children && item.children.length > 0){//目录
item.redirect = item.path;
delete item.path
handelTreeData(item.children,id);
}
if(item.menuType==='C'){//菜单
item.rule = item.children;
delete item.children
}
});
if (item.menuType === 'M' && item.children && item.children.length > 0) {//目录
item.redirect = item.path;
delete item.path
handelTreeData(item.children, id);
}
if (item.menuType === 'C') {//菜单
item.rule = item.children;
delete item.children
}
});
}
}
const buildTree = (data:any, parentId:any)=> {
let tree:any = [];
data.forEach((node:any) => {
if (node.parentId === parentId) {
const buildTree = (data: any, parentId: any) => {
let tree: any = [];
data.forEach((node: any) => {
if (node.parentId === parentId) {
let children = buildTree(data, node.menuId);
if (children.length) {
node.children = children;
node.children = children;
}
tree.push(node);
}
}
});
return tree;
}
export function loadRole(data:any) {
const roleObj:any = {}
const handelTreeData2 = (data:any)=>{
export function loadRole(data: any) {
const roleObj: any = {}
const handelTreeData2 = (data: any) => {
if (data.length > 0) {
data.forEach((item:any) => {
if (item.children && item.children.length > 0) {
//是目录
handelTreeData2(item.children);
}else{
//是菜单
roleObj[item.path] = item
}
});
data.forEach((item: any) => {
if (item.children && item.children.length > 0) {
//是目录
handelTreeData2(item.children);
} else {
//是菜单
roleObj[item.path] = item
}
});
}
}
@ -207,6 +207,20 @@ export async function loadMenu(): Promise<MenuItem[]> {
}
]
},
{
id: id(), title: '水政执法', redirect: '/mgr/sz/szzf/ajdj',
children: [
{
id: id(), title: '案件登记', path: '/mgr/sz/szzf/ajdj',
},
{
id: id(), title: '案件统计', path: '/mgr/sz/szzf/ajtj',
},
{
id: id(), title: '处理依据', path: '/mgr/sz/szzf/clyj',
}
]
},
{
id: id(), title: '监督考核', redirect: '/mgr/sz/jdkh/khtj',
children: [
@ -231,11 +245,12 @@ export async function loadMenu(): Promise<MenuItem[]> {
{ id: id(), title: '制度管理', path: '/mgr/sz/zdgl' },
]
},
{ id: id(), title: '四预', redirect: '/mgr/sy/fhxzfx', icon: 'fxzb',
},
{
id: id(), title: '四预', redirect: '/mgr/sy/fhxzfx', icon: 'fxzb',
children: [
{ id: id(), title: '防洪形势', path: '/mgr/sy/fhxzfx'},
{ id: id(), title: '天气预报', path: '/mgr/fxzb/tqyb'},
{ id: id(), title: '防洪形势', path: '/mgr/sy/fhxzfx' },
{ id: id(), title: '天气预报', path: '/mgr/fxzb/tqyb' },
{
id: id(), title: '洪水预报', redirect: '/mgr/fxzb/hsyb/hyybjs',
children: [
@ -244,8 +259,8 @@ export async function loadMenu(): Promise<MenuItem[]> {
{ id: id(), title: '参数管理', path: '/mgr/fxzb/hsyb/csgl' },
]
},
{ id: id(), title: '防汛预案', path: '/mgr/sy/fxya'},
{ id: id(), title: '调度规程', path: '/mgr/sy/ddgc'},
{ id: id(), title: '防汛预案', path: '/mgr/sy/fxya' },
{ id: id(), title: '调度规程', path: '/mgr/sy/ddgc' },
{
id: id(),
title: '抢险物料',
@ -258,7 +273,8 @@ export async function loadMenu(): Promise<MenuItem[]> {
},
],
},
{ id: id(), title: '四管', redirect: '/mgr/sg/xcxj/xcrw', icon: 'fxzb',
{
id: id(), title: '四管', redirect: '/mgr/sg/xcxj/xcrw', icon: 'fxzb',
children: [
{
id: id(), title: '巡查巡检', redirect: '/mgr/sg/xcxj/xcrw',
@ -314,7 +330,8 @@ export async function loadMenu(): Promise<MenuItem[]> {
},
],
},
{ id: id(), title: '工程安全监测', redirect: '/mgr/gcaqjc/gcaqyj/bzt', icon: 'fxzb',
{
id: id(), title: '工程安全监测', redirect: '/mgr/gcaqjc/gcaqyj/bzt', icon: 'fxzb',
children: [
{
id: id(), title: '布置图', path: '/mgr/gcaqjc/gcaqyj/bzt',
@ -322,7 +339,7 @@ export async function loadMenu(): Promise<MenuItem[]> {
{
id: id(), title: '工程安全分析', redirect: '/mgr/gcaqjc/gcaqfx/jrx',
children: [
{ id: id(), title: '浸润线', path: '/mgr/gcaqjc/gcaqfx/jrx'},
{ id: id(), title: '浸润线', path: '/mgr/gcaqjc/gcaqfx/jrx' },
]
},
{
@ -345,31 +362,35 @@ export async function loadMenu(): Promise<MenuItem[]> {
},
],
},
{ id:id(),title:'四全',redirect:'/mgr/sq/qfg/zcdjxx',
{
id: id(), title: '四全', redirect: '/mgr/sq/qfg/zcdjxx',
children: [
{ id: id(), title: '全覆盖', redirect: '/mgr/sq/qfg/zcdjxx',
{
id: id(), title: '全覆盖', redirect: '/mgr/sq/qfg/zcdjxx',
children: [
{ id: id(), title: '注册登记信息', path: '/mgr/sq/qfg/zcdjxx'},
{ id: id(), title: '注册登记信息', path: '/mgr/sq/qfg/zcdjxx' },
]
},
{ id: id(), title: '全要素', redirect: '/mgr/sq/qys/kqys',
{
id: id(), title: '全要素', redirect: '/mgr/sq/qys/kqys',
children: [
{ id: id(), title: '库区要素', path: '/mgr/sq/qys/kqys'},
{ id: id(), title: '工程要素', path: '/mgr/sq/qys/gcys'},
{ id: id(), title: '下游要素', path: '/mgr/sq/qys/xyys'},
{ id: id(), title: '库区要素', path: '/mgr/sq/qys/kqys' },
{ id: id(), title: '工程要素', path: '/mgr/sq/qys/gcys' },
{ id: id(), title: '下游要素', path: '/mgr/sq/qys/xyys' },
]
},
{ id: id(), title: '全周期', redirect: '/mgr/sq/qzq/gcdsj',
{
id: id(), title: '全周期', redirect: '/mgr/sq/qzq/gcdsj',
children: [
{ id: id(), title: '工程大事记', path: '/mgr/sq/qzq/gcdsj'},
{ id: id(), title: '全周期档案', path: '/mgr/sq/qys/qzqda'},
{ id: id(), title: '工程大事记', path: '/mgr/sq/qzq/gcdsj' },
{ id: id(), title: '全周期档案', path: '/mgr/sq/qys/qzqda' },
]
},
]
},
// { id: id(), title: '基本情况', path: '/mgr/home', icon: 'jbqk' },
// {
// id: id(),
@ -413,14 +434,14 @@ export async function loadMenu(): Promise<MenuItem[]> {
// children: [
// { id: id(), title: '隐患预警', path: '/mgr/gcaqjc/gcaqyj/yhyj' },
// { id: id(), title: '预警规则配置', path: '/mgr/gcaqjc/gcaqyj/yjgzpz' },
// ]
// },
// {
// id: id(), title: '工程安全分析', redirect: '/mgr/gcaqjc/gcaqfx/jrx',
// children: [
// { id: id(), title: '浸润线', path: '/mgr/gcaqjc/gcaqfx/jrx' },
// ]
// },
// {
@ -433,10 +454,10 @@ export async function loadMenu(): Promise<MenuItem[]> {
// { id: id(), title: '年度渗压统计表', path: '/mgr/gcaqjc/sjtjcx/ndsytjb' },
// { id: id(), title: '年度渗流统计表', path: '/mgr/gcaqjc/sjtjcx/ndsltjb' },
// { id: id(), title: '年度位移统计表', path: '/mgr/gcaqjc/sjtjcx/ndwytjb' },
// ]
// },
// ],
// },
// {
@ -455,7 +476,7 @@ export async function loadMenu(): Promise<MenuItem[]> {
// children: [
// { id: id(), title: '值班表', path: '/mgr/rcgl/zbgl/zbb' },
// { id: id(), title: '值班日志', path: '/mgr/rcgl/zbgl/zbrz' },
// ]
// },
// {

View File

@ -96,7 +96,9 @@ import Qzqda from './sq/qzq/qzqda'
import Zzjgck from './sz/zzjgck'
import Flfg from './sz/flfg'
import Zdgl from './sz/zdgl'
import Ajdj from './sz/szzf/ajdj'
import Ajtj from './sz/szzf/ajtj'
import Clyj from './sz/szzf/clyj'
const HomePage = lazy(() => import('./Home'))
@ -242,6 +244,10 @@ const AppRouters: React.FC = () => {
{ path: 'sz/gltx/zzjgck', element: <Zzjgck /> },
{ path: 'sz/flfg', element: <Flfg /> },
{ path: 'sz/zdgl', element: <Zdgl /> },
{ path: 'sz/szzf/ajdj', element: <Ajdj /> },
{ path: 'sz/szzf/ajtj', element: <Ajtj /> },
{ path: 'sz/szzf/clyj', element: <Clyj /> },
],
},
{ path: '/login', element: <LoginPage /> },

View File

@ -4,7 +4,8 @@ import qys1 from '../../../../assets/img/qys1.png'
import qys2 from '../../../../assets/img/qys2.jpg'
import qys3 from '../../../../assets/img/qys3.jpg'
import qys4 from '../../../../assets/img/qys4.png'
import './index.less'
import stylesCss from './index.module.less'
import { Rnd } from "react-rnd"
import { useState, useEffect } from "react"
const list = [
@ -53,7 +54,7 @@ const Page = () => {
return (
<div style={{ backgroundColor: '#fff', height: '100%' }}>
<div style={{ display: 'flex', justifyContent: 'start', alignItems: 'center', }}>
{list.map(item => <div className={url == item.img ? "active" : "tabCheck"} onClick={() => tabClick(item)}>{item.name}</div>)}
{list.map(item => <div className={url == item.img ? stylesCss.active : stylesCss.tabCheck} onClick={() => tabClick(item)}>{item.name}</div>)}
</div>
<Rnd
default={{

View File

@ -0,0 +1,75 @@
import { Space, Table, Radio, DatePicker, Form, Select, Button, message, Upload, Input, Row, Col, Switch, Image } from 'antd';
import { InboxOutlined, LinkOutlined, DeleteOutlined, LoadingOutlined,VerticalAlignBottomOutlined } from '@ant-design/icons'
import { useForm } from 'antd/lib/form/Form';
import { useState } from 'react';
const { Dragger } = Upload;
const Page = () => {
const form =useForm()
const [fileList ,setFileList] =useState()
const props = {
name: 'file',
multiple: true,
fileList: fileList,
showUploadList: false,
beforeUpload: (file, fileList) => {
// if (fileType == "pic" &&
// (file.type != "image/jpeg" || file.type != "image/png" || file.type != "image/jpg")) {
// message.error('仅支持上传jpg/png/jpeg格式的图片');
// return false;
// } else {
// return true;
// }
},
onChange(e) {
// httpPostFile(apiUrl.service.uploadFile.uploadUrl + "?group=" + typeUpload, e).then(res => {
// setFileList([...fileList, res.data])
// })
}
};
const onFinish = () =>{
}
return (
<Form form={form} name="searchTabel" onFinish={onFinish} >
<Row>
<div>案卷存档</div>
<Col>
<Form.Item
label='保管人员'
name='name'
>
<Input />
</Form.Item>
</Col>
<Col>
<Form.Item
label='保管地点'
name='adress'
>
<Input />
</Form.Item>
</Col>
</Row>
<Row>
<div>案卷存档</div>
<Col>
<Form.Item
label='附件'
name='name'
>
<Dragger {...props}>
<p className="ant-upload-drag-icon">
<InboxOutlined />
</p>
<p className="ant-upload-text">点击或将文件拖拽到这里上传 支持扩展名jpegpng</p>
</Dragger>
</Form.Item>
</Col>
</Row>
</Form >
)
}
export default Page

View File

@ -0,0 +1,243 @@
const basicData = [
{
label: '填报人',
key: 'name',
type: 'input',
span: 12,
disabled: true
},
{
label: '填报时间',
key: 'name',
type: 'input',
span: 12,
disabled: true
},
{
label: '案件编号',
key: 'name',
type: 'input',
span: 12
},
{
label: '案件名称',
key: 'name',
type: 'input',
span: 12,
required: true
},
{
label: '案件类型',
key: 'name',
type: 'Select',
span: 12
},
{
label: '案发地点',
key: 'name',
type: 'input',
span: 12
},
{
label: '案件来源',
key: 'name',
type: 'Radio',
span: 12,
options: [
{ label: '自然人', value: 'Apple' },
{ label: '法人或其他组织', value: 'Pear' },
{ label: '待定', value: 'Orange' },
]
},
{
label: '违法时间',
key: 'name',
type: 'input',
span: 24
},
{
label: '案件来源',
key: 'name',
type: 'input',
span: 24
},
{
label: '姓名',
key: 'name',
type: 'input',
span: 12
},
{
label: '身份证号',
key: 'name',
type: 'input',
span: 12
},
{
label: '住址',
key: 'name',
type: 'input',
span: 12
},
{
label: '联系方式',
key: 'name',
type: 'input',
span: 12
},
{
label: '简要案情',
key: 'name',
type: 'TextArea',
span: 24
},
{
label: '附件',
key: 'name',
type: 'upload',
span: 24
},
]
const clqkData = [
{
label: '处理程序',
key: 'name',
type: 'Select',
span: 12,
disabled: true
},
{
label: '处理依据',
key: 'name',
type: 'Select',
span: 12,
disabled: true
},
{
label: '处理措施',
key: 'name',
type: 'Select',
span: 12
},
{
label: '移送处理情况',
key: 'name',
type: 'Radio',
span: 24,
options: [
{ label: '移送单位', value: 'Apple' },
{ label: '不移送', value: 'Pear' },
],
required: true
},
{
label: '案件执行情况',
key: 'name',
type: 'Radio',
options: [
{ label: '当事人自动履行', value: 'Apple' },
{ label: '行政强制执行', value: 'Pear' },
],
span: 24
},
{
label: '自动履行情况',
key: 'name',
type: 'TextArea',
span: 24
},
{
label: '伤亡人数(人)',
key: 'name',
type: 'input',
span: 12
},
{
label: '直接损失金额(万元)',
key: 'name',
type: 'input',
span: 12
},
{
label: '结案情况',
key: 'name',
type: 'Select',
span: 12
},
{
label: '结案时间',
key: 'name',
type: 'input',
span: 12
},
{
label: '文件编号及名称',
key: 'name',
type: 'input',
span: 24
},
{
label: '督办单位类型',
key: 'name',
type: 'Select',
span: 12
},
{
label: '督办单位名称',
key: 'name',
type: 'input',
span: 24
},
{
label: '附件',
key: 'name',
type: 'upload',
span: 24
},
]
const xzfy = [
{
label: '处理程序',
key: 'name',
type: 'Select',
span: 12,
options:[
{
label:'维护'
},
{label:'变更'},
{label:'撤销'},
{label:'和解'},
{label:'调解'},
],
disabled: true
},
{
label: '处理依据',
key: 'name',
type: 'Select',
span: 12,
disabled: true,
options:[
{
label:'驳回原告诉讼'
},
{label:'变更'},
{label:'撤销'},
{label:'确认违法'},
{label:'确认无效'},
{label:'其他'},
],
},
]
export {
basicData,
clqkData,
xzfy
}

View File

@ -0,0 +1,50 @@
import React, { useState } from 'react';
import { Tabs } from 'antd';
import BascForm from '../form/index'
import { basicData,clqkData,xzfy} from './config'
import Bajz from './bajz'
const items = [
{
key: '1',
label: '基本情况',
},
{
key: '2',
label: '处理情况',
},
{
key: '3',
label: '行政复议、行政应诉情况',
},
{
key: '4',
label: '办案宗卷',
},
{
key: '5',
label: '历史影像及图片',
},
];
const Page = () => {
const [key , setKeys] = useState('1')
const onChange = (key) => {
console.log(key);
setKeys(key)
};
return (
<>
<Tabs defaultActiveKey="1" items={items} onChange={onChange} />
<>
{key==1&& <BascForm formJson={basicData}></BascForm>}
{key==2&& <BascForm formJson={clqkData}></BascForm>}
{key==3&& <BascForm formJson={xzfy}></BascForm>}
{key==4&& <Bajz formJson={basicData}></Bajz>}
{/* {key==5&& <BascForm formJson={basicData}></BascForm>} */}
</>
</>
)
}
export default Page

View File

@ -0,0 +1,305 @@
import React, { useEffect, useState, useMemo, useRef } from 'react';
import { Form, Button, Input, Row, Upload, Col, Table, DatePicker, InputNumber, message, Image, Modal, Typography, Select } from 'antd';
import { DeleteOutlined, FileWordOutlined, FilePdfOutlined, FileZipOutlined, FileExcelOutlined } from '@ant-design/icons';
import { formItemLayout, btnItemLayout } from '../../../../components/crud/FormLayoutProps';
import apiurl from '../../../../service/apiurl';
// import "./index.less"
import moment from 'moment';
const { RangePicker } = DatePicker
const { Dragger } = Upload;
const url = "http://223.75.53.141:9102/test.by-lyf.tmp"
const opntios=[
{label:'宪法',value:'宪法'},
{label:'法律',value:'法律'},
{label:'行政法规',value:'行政法规'},
{label:'督察法规',value:'督察法规'},
{label:'司法解释',value:'司法解释'},
{label:'地方性法规',value:'地方性法规'},
]
const ModalForm = ({ mode, record, onEdit, onSave, onSimilarSave }) => {
const [form] = Form.useForm();
const [fileList, setFileList] = useState([]) //上传文件列表
const [fileIds, setFileIds] = useState([])
const [iframeSrc, setIframeSrc] = useState('')
const [pdfViewOPen, setPdfViewOPen] = useState(false)
const [loading, setLoading] = useState(false)
/**
* @description 文件下载
* @param {String} params 文件fileId
*/
const download = (params) => {
let downloadLink = document.createElement("a");
downloadLink.href = `http://local.gunshiiot.com:18083/gunshiApp/xyt/projectEvents/file/download/${params}`;
downloadLink.download = `${params.fileName}`;
downloadLink.style.display = "none";
// 将链接添加到页面中
document.body.appendChild(downloadLink);
// 模拟点击事件,开始下载
downloadLink.click();
}
/**
* @description 上传图片
* @param {string} file 上传的文件
*/
const fileChange = (info) => {
if (info.file.status === "done") {
setLoading(false);
}
if (info.file.status === "uploading") {
setLoading(true);
}
if (info.file.status === "error") {
message.error("文件上传失败")
setLoading(false);
}
let fileIds = info.fileList.map(file => {
return file.response?.data?.fileId
})
setFileIds(fileIds)
setFileList(info.fileList)
}
/**
* @description pdf文件预览
* @param {String} params 文件预览url
*/
const viewPdf = (params) => {
setIframeSrc(params)
setPdfViewOPen(true)
}
const onfinish = (values) => {
values.eventsDate = values.eventsDate ? moment(values.eventsDate).format("YYYY-MM-DD 00:00:00") : ''
let oldFiles = fileList.map(item => ({ fileId: item.response?.data?.fileId }))
if (mode === 'edit') {
values.files = oldFiles;
values.id = record.id;
onEdit(apiurl.rcgl.gcdsj.edit, values)
}
if (mode === 'save') {
values.files = oldFiles
onSave(apiurl.rcgl.gcdsj.save, values)
}
}
/**
* @description 删除上传的图片
* @param {string} id 删除的id
*/
const deleteFile = (fileId) => {
console.log(fileId);
let filterFile = fileList.filter(item => item.response?.data?.fileId !== fileId);
setFileList(filterFile)
}
useEffect(() => {
if (mode != 'save') {
const imgFile = record?.files?.map(o => ({
name: o.fileName,
response: {
data: {
filePath: o.filePath,
fileId: o.fileId
}
},
}))
setFileList(imgFile)
}
}, [record, mode])
return (
<>
<Form
form={form}
{...formItemLayout}
onFinish={onfinish}
initialValues={record}
>
<Row>
<Col span={12}>
<Form.Item
label="标题"
name="name"
rules={[{ required: true }]}
>
<Input disabled={mode === 'view'} style={{ width: '100%' }} allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="制定机关"
name="name"
rules={[{ required: true }]}
>
<Input disabled={mode === 'view'} style={{ width: '100%' }} allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="制定机关" name="name">
<Select allowClear style={{ width: '150px' }} options={opntios} />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="失效性" name="name">
<Select allowClear style={{ width: '150px' }} options={opntios} />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="公布日期"
name="eventsDate"
getValueFromEvent={(e, dateString) => dateString}
getValueProps={(value) => ({ value: value ? moment(value) : undefined })}
rules={[
{
required: true,
},
]}
>
<DatePicker disabled={mode === 'view'} format={'YYYY-MM-DD'} style={{ width: '100%' }} allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="施行日期"
name="eventsDate"
getValueFromEvent={(e, dateString) => dateString}
getValueProps={(value) => ({ value: value ? moment(value) : undefined })}
rules={[
{
required: true,
},
]}
>
<DatePicker disabled={mode === 'view'} format={'YYYY-MM-DD'} style={{ width: '100%' }} allowClear />
</Form.Item>
</Col>
</Row>
<Row>
<Col span={24}>
<Form.Item
label="附件"
name="fieldId"
labelCol={{ span: 3 }}
wrapperCol={{ span: 19 }}
>
{mode !== "view" &&
<Dragger
name='file'
// multiple
action="/gunshiApp/xyt/projectEvents/file/upload/singleSimple"
onChange={fileChange}
onDrop={(info) => { console.log(info.dataTransfer.files); }}
fileList={fileList}
disabled={loading}
// onSuccess={handleSuccess}
>
<p className="ant-upload-text">点击或拖拽文件到此区域上传</p>
<p className="ant-upload-hint">
支持扩展名.doc .docx .pdf .jpg .png .ppt
</p>
</Dragger>
}
<Row gutter={[16]}>
{
fileList.length > 0 && fileList.map(file => {
return (
<Col span={12}>
<div className="file-item" style={{ width: "75%" }}>
<div className='file-description'>
{file.name.indexOf('.docx') > -1 ?
<div
onClick={() => { download(file.response?.data?.fileId) }}
style={{ cursor: 'pointer' }}
>
<FileWordOutlined
style={{ fontSize: 40 }}
/>
</div>
:
file.name.indexOf('.pdf') > -1 ?
<div
onClick={() => { viewPdf(file.response?.data?.fileId) }}
style={{ cursor: 'pointer' }}
>
<FilePdfOutlined style={{ fontSize: 40 }} />
</div>
:
file.name.indexOf('.zip') > -1 ?
<div
onClick={() => { download(file.response?.data?.fileId) }}
style={{ cursor: 'pointer' }}
>
<FileZipOutlined style={{ fontSize: 40 }} />
</div>
:
file.name.indexOf('.xlsx') > -1 ?
<div
onClick={() => { download(file.response?.data?.fileId) }}
style={{ cursor: 'pointer' }}
>
<FileExcelOutlined style={{ fontSize: 40 }} />
</div>
:
<Image width={60} src={url + file.response?.data?.filePath} alt='' />
}
<span>{file.name}</span>
</div>
<div className={mode == "view" ? 'delete-icon disable-icon' : 'delete-icon'} onClick={() => deleteFile(file.response?.data?.fileId)}>
<DeleteOutlined />
</div>
</div>
</Col>
)
})
}
</Row>
</Form.Item>
</Col>
</Row>
{
mode === 'view' ? null : (
<>
<Form.Item {...btnItemLayout}>
<Button type="primary" htmlType="submit">
{mode === 'save' ? '提交' : '修改'}
</Button>
</Form.Item>
</>
)
}
</Form>
<Modal
open={pdfViewOPen}
width={1000}
title=""
footer={null}
style={{ marginTop: "-5%" }}
onCancel={() => {
setPdfViewOPen(false)
}}
>
<iframe
style={{
height: '80vh',
width: '100%',
border: 0,
marginTop: 20,
}}
src={`${process.env.PUBLIC_URL}/static/pdf/web/viewer.html?file=${encodeURIComponent(`/gunshiApp/xyt/projectEvents/file/download/${iframeSrc}`)}`}
/>
</Modal>
</>
);
}
export default ModalForm;

View File

@ -0,0 +1,150 @@
import React, { Fragment, useRef, useMemo, useEffect, useState } from 'react';
import BasicCrudModal from '../../../../components/crud/BasicCrudModal';
import { Table, Card, Modal, Form, Input, Button, Row, Col, Timeline, message, Tabs, Image } from 'antd';
import { FileWordOutlined, FilePdfOutlined, FileZipOutlined, FileExcelOutlined } from '@ant-design/icons';
import { useSelector } from 'react-redux';
import ToolBar from './toolbar';
import ModalForm from './editTabs';
import apiurl from '../../../../service/apiurl';
import usePageTable from '../../../../components/crud/usePageTable2';
import { createCrudService } from '../../../../components/crud/_';
import { CrudOpRender_text } from '../../../../components/crud/CrudOpRender';
const url = "http://223.75.53.141:9102/test.by-lyf.tmp"
const Page = () => {
const role = useSelector(state => state.auth.role);
const editBtn = role?.rule?.find(item => item.menuName == "编辑");
const viewBtn = role?.rule?.find(item => item.menuName == "查看");
const delBtn = role?.rule?.find(item => item.menuName == "删除");
const refModal = useRef();
const [searchVal, setSearchVal] = useState(false)
const [iframeSrc, setIframeSrc] = useState('')
const [pdfViewOPen, setPdfViewOPen] = useState(false)
const [isFetch, setIsFetch] = useState(false)
const columns = [
{ title: '序号', key: 'inx', dataIndex: 'inx', width: 60, align: "center" },
{ title: '标题', key: 'name', dataIndex: 'name', width: 250, ellipsis: true },
{
title: '制定机关', key: 'eventsDate', dataIndex: 'eventsDate', width: 140,
},
{
title: '法律性质', key: 'eventsType', dataIndex: 'eventsType', width: 140,
render: (value) => <span>{value == 1 ? "综合大事记" : value == 2 ? "专题大事记" : ''}</span>,
},
{
title: '时效性', key: 'eventsDesc', dataIndex: 'eventsDesc', width: 300
},
{
title: '公布日期', key: 'eventsDesc', dataIndex: 'eventsDesc', width: 300
},
{
title: '施行日期', key: 'eventsDesc', dataIndex: 'eventsDesc', width: 300
},
{
title: '上传时间', key: 'eventsDesc', dataIndex: 'eventsDesc', width: 300
},
{
title: '附件', key: 'fileName', dataIndex: 'fileName', width: 300,render:(v,r)=><a onClick={()=>viewPdf(r.fileId)}>{v}</a>
},
{
title: '操作', key: 'operation', width: 240, fixed: 'right', align: 'center',
render: (value, row, index) => (
<CrudOpRender_text
edit={true}
del={true}
view={true}
command={(cmd) => () => command(cmd)(row)} />)
},
];
const width = useMemo(() => columns.reduce((total, cur) => total + (cur.width), 0), [columns]);
const command = (type) => (params) => {
if (type === 'save') {
refModal.current.showSave();
} else if (type === 'edit') {
refModal.current.showEdit({ ...params });
} else if (type === 'view') {
refModal.current.showView(params);
} else if (type === 'del') {
refModal.current.onDeleteGet(apiurl.rcgl.gcdsj.delete + `/${params.id}`);
}
}
const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.rcgl.gcdsj.page).find_noCode);
/**
* @description 处理成功的回调
*/
const successCallback = () => {
refresh()
setIsFetch(!isFetch)
}
const viewPdf = (params) => {
setIframeSrc(params)
setPdfViewOPen(true)
}
useEffect(() => {
const params = {
search: {
...searchVal,
}
};
search(params)
}, [searchVal])
return (
<>
<div className='content-root clearFloat xybm' style={{ paddingRight: "0", paddingBottom: "0" }}>
<div className='lf CrudAdcdTreeTableBox' style={{ width: "100%", overflowY: "auto" }}>
<Card className='nonebox'>
<ToolBar
setSearchVal={setSearchVal}
onSave={command('save')}
role={role}
/>
</Card>
<div className="ant-card-body" style={{ padding: "20px 0 0 0" }}>
<Table columns={columns} rowKey="inx" {...tableProps} scroll={{ x: width, y: "calc( 100vh - 400px )" }} />
</div>
</div>
<BasicCrudModal
width={1000}
ref={refModal}
title=""
component={ModalForm}
onCrudSuccess={successCallback}
// onCrudSuccess={()=>{refresh({addvcd:localStorage.getItem('ADCD6')})}}
/>
</div>
<Modal
open={pdfViewOPen}
width={1000}
title=""
footer={null}
style={{ marginTop: "-5%" }}
onCancel={() => {
setPdfViewOPen(false)
}}
>
<iframe
style={{
height: '80vh',
width: '100%',
border: 0,
marginTop: 20,
}}
src={`${process.env.PUBLIC_URL}/static/pdf/web/viewer.html?file=${encodeURIComponent(`/gunshiApp/xyt/projectEvents/file/download/${iframeSrc}`)}`}
/>
</Modal>
</>
);
}
export default Page;

View File

@ -0,0 +1,91 @@
import React, { useEffect,useState } from 'react';
import { Form, Input, Button, DatePicker, Select } from 'antd';
import { DownOutlined, UpOutlined } from '@ant-design/icons'
import moment from 'moment';
const { RangePicker } = DatePicker;
const ToolBar = ({ setSearchVal, onSave, storeData,role }) => {
const addBtn = role?.rule?.find(item => item.menuName == "新增");
const searchBtn = role?.rule?.find(item => item.menuName == "查询");
const [form] = Form.useForm();
const [showGj , setShowGj] =useState(false)
const onFinish = (values) => {
let dataSo;
if (values.tm) {
dataSo = {
start: moment(values.tm[0]).format('YYYY-MM-DD HH:mm:ss'),
end: moment(values.tm[1]).format('YYYY-MM-DD HH:mm:ss')
}
}
delete values.tm
setSearchVal({...values, dataSo});
}
const opntios=[
{label:'宪法',value:'宪法'},
{label:'法律',value:'法律'},
{label:'行政法规',value:'行政法规'},
{label:'督察法规',value:'督察法规'},
{label:'司法解释',value:'司法解释'},
{label:'地方性法规',value:'地方性法规'},
]
const styles={
fontFamily: '微软雅黑 Bold", "微软雅黑 Regular", 微软雅黑, sans-serif',
fontWeight: '700',
fontStyle: 'normal',
fontSize: '16px'
}
return (
<>
<div style={{display:'flex',justifyContent:'space-between'}}>
<Form form={form} className='toolbarBox' layout="inline" onFinish={onFinish}>
<div style={{display:'flex'}}>
<Form.Item label="标题" name="name">
<Input allowClear style={{width:'150px'}}/>
</Form.Item>
<Form.Item label="制定机关" name="name">
<Input allowClear style={{width:'150px'}}/>
</Form.Item>
<Form.Item label="制定机关" name="name">
<Select allowClear style={{width:'150px'}} options={opntios}/>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">查询</Button>
</Form.Item>
<Form.Item>
<Button onClick={() => form.resetFields()}>重置</Button>
</Form.Item>
{
(onSave) ?
<Form.Item>
<Button onClick={onSave}>新增</Button>
</Form.Item>
:null
}
<Form.Item>
<div style={styles} onClick={()=>setShowGj(!showGj)}>高级搜索 {!showGj&&<DownOutlined />} {showGj&&<UpOutlined />}</div>
</Form.Item>
</div>
{showGj&&<div style={{display:'flex'}}>
<Form.Item label="时效性" name="name">
<Select allowClear style={{width:'150px'}} options={opntios}/>
</Form.Item>
<Form.Item label="公布日期" name="name">
<RangePicker allowClear />
</Form.Item>
<Form.Item label="施行日期" name="name">
<RangePicker allowClear />
</Form.Item>
<Form.Item label="上传时间" name="name">
<RangePicker allowClear />
</Form.Item>
</div>}
</Form>
</div>
</>
);
}
export default ToolBar;

View File

@ -0,0 +1,307 @@
import React, { useEffect, useState, useMemo, useRef } from 'react';
import { Form, Button, Input, Row, Upload, Col, Table, DatePicker, InputNumber, message, Image, Modal, Typography, Select } from 'antd';
import { DeleteOutlined, FileWordOutlined, FilePdfOutlined, FileZipOutlined, FileExcelOutlined } from '@ant-design/icons';
import { formItemLayout, btnItemLayout } from '../../../../components/crud/FormLayoutProps';
import apiurl from '../../../../service/apiurl';
// import "./index.less"
import moment from 'moment';
const { RangePicker } = DatePicker
const { Dragger } = Upload;
const url = "http://223.75.53.141:9102/test.by-lyf.tmp"
const opntios=[
{label:'宪法',value:'宪法'},
{label:'法律',value:'法律'},
{label:'行政法规',value:'行政法规'},
{label:'督察法规',value:'督察法规'},
{label:'司法解释',value:'司法解释'},
{label:'地方性法规',value:'地方性法规'},
]
const ModalForm = ({ mode, record, onEdit, onSave, onSimilarSave }) => {
const [form] = Form.useForm();
const [fileList, setFileList] = useState([]) //上传文件列表
const [fileIds, setFileIds] = useState([])
const [iframeSrc, setIframeSrc] = useState('')
const [pdfViewOPen, setPdfViewOPen] = useState(false)
const [loading, setLoading] = useState(false)
/**
* @description 文件下载
* @param {String} params 文件fileId
*/
const download = (params) => {
let downloadLink = document.createElement("a");
downloadLink.href = `http://local.gunshiiot.com:18083/gunshiApp/xyt/projectEvents/file/download/${params}`;
downloadLink.download = `${params.fileName}`;
downloadLink.style.display = "none";
// 将链接添加到页面中
document.body.appendChild(downloadLink);
// 模拟点击事件,开始下载
downloadLink.click();
}
/**
* @description 上传图片
* @param {string} file 上传的文件
*/
const fileChange = (info) => {
if (info.file.status === "done") {
setLoading(false);
}
if (info.file.status === "uploading") {
setLoading(true);
}
if (info.file.status === "error") {
message.error("文件上传失败")
setLoading(false);
}
let fileIds = info.fileList.map(file => {
return file.response?.data?.fileId
})
setFileIds(fileIds)
setFileList(info.fileList)
}
/**
* @description pdf文件预览
* @param {String} params 文件预览url
*/
const viewPdf = (params) => {
setIframeSrc(params)
setPdfViewOPen(true)
}
const onfinish = (values) => {
values.eventsDate = values.eventsDate ? moment(values.eventsDate).format("YYYY-MM-DD 00:00:00") : ''
let oldFiles = fileList.map(item => ({ fileId: item.response?.data?.fileId }))
if (mode === 'edit') {
values.files = oldFiles;
values.id = record.id;
onEdit(apiurl.rcgl.gcdsj.edit, values)
}
if (mode === 'save') {
values.files = oldFiles
onSave(apiurl.rcgl.gcdsj.save, values)
}
}
/**
* @description 删除上传的图片
* @param {string} id 删除的id
*/
const deleteFile = (fileId) => {
console.log(fileId);
let filterFile = fileList.filter(item => item.response?.data?.fileId !== fileId);
setFileList(filterFile)
}
useEffect(() => {
if (mode != 'save') {
const imgFile = record?.files?.map(o => ({
name: o.fileName,
response: {
data: {
filePath: o.filePath,
fileId: o.fileId
}
},
}))
setFileList(imgFile)
}
}, [record, mode])
return (
<>
<Form
form={form}
{...formItemLayout}
onFinish={onfinish}
initialValues={record}
>
<Row>
<Col span={12}>
<Form.Item
label="标题"
name="name"
rules={[{ required: true }]}
>
<Input disabled={mode === 'view'} style={{ width: '100%' }} allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="制定机关"
name="name"
rules={[{ required: true }]}
>
<Input disabled={mode === 'view'} style={{ width: '100%' }} allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="制定机关" name="name">
<Select allowClear style={{ width: '150px' }} options={opntios} />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="失效性" name="name">
<Select allowClear style={{ width: '150px' }} options={opntios} />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="公布日期"
name="eventsDate"
getValueFromEvent={(e, dateString) => dateString}
getValueProps={(value) => ({ value: value ? moment(value) : undefined })}
rules={[
{
required: true,
},
]}
>
<DatePicker disabled={mode === 'view'} format={'YYYY-MM-DD'} style={{ width: '100%' }} allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="施行日期"
name="eventsDate"
getValueFromEvent={(e, dateString) => dateString}
getValueProps={(value) => ({ value: value ? moment(value) : undefined })}
rules={[
{
required: true,
},
]}
>
<DatePicker disabled={mode === 'view'} format={'YYYY-MM-DD'} style={{ width: '100%' }} allowClear />
</Form.Item>
</Col>
</Row>
<Row>
<Col span={24}>
<Form.Item
label="附件"
name="fieldId"
labelCol={{ span: 3 }}
wrapperCol={{ span: 19 }}
>
{mode !== "view" &&
<Dragger
name='file'
// multiple
action="/gunshiApp/xyt/projectEvents/file/upload/singleSimple"
onChange={fileChange}
onDrop={(info) => { console.log(info.dataTransfer.files); }}
fileList={fileList}
disabled={loading}
// onSuccess={handleSuccess}
>
<p className="ant-upload-text">点击或拖拽文件到此区域上传</p>
<p className="ant-upload-hint">
支持扩展名.doc .docx .pdf .jpg .png .ppt
</p>
</Dragger>
}
<Row gutter={[16]}>
{
fileList.length > 0 && fileList.map(file => {
return (
<Col span={12}>
<div className="file-item" style={{ width: "75%" }}>
<div className='file-description'>
{file.name.indexOf('.docx') > -1 ?
<div
onClick={() => { download(file.response?.data?.fileId) }}
style={{ cursor: 'pointer' }}
>
<FileWordOutlined
style={{ fontSize: 40 }}
/>
</div>
:
file.name.indexOf('.pdf') > -1 ?
<div
onClick={() => { viewPdf(file.response?.data?.fileId) }}
style={{ cursor: 'pointer' }}
>
<FilePdfOutlined style={{ fontSize: 40 }} />
</div>
:
file.name.indexOf('.zip') > -1 ?
<div
onClick={() => { download(file.response?.data?.fileId) }}
style={{ cursor: 'pointer' }}
>
<FileZipOutlined style={{ fontSize: 40 }} />
</div>
:
file.name.indexOf('.xlsx') > -1 ?
<div
onClick={() => { download(file.response?.data?.fileId) }}
style={{ cursor: 'pointer' }}
>
<FileExcelOutlined style={{ fontSize: 40 }} />
</div>
:
<Image width={60} src={url + file.response?.data?.filePath} alt='' />
}
<span>{file.name}</span>
</div>
<div className={mode == "view" ? 'delete-icon disable-icon' : 'delete-icon'} onClick={() => deleteFile(file.response?.data?.fileId)}>
<DeleteOutlined />
</div>
</div>
</Col>
)
})
}
</Row>
</Form.Item>
</Col>
</Row>
{
mode === 'view' ? null : (
<>
<Form.Item {...btnItemLayout}>
<Button type="primary" htmlType="submit">
{mode === 'save' ? '提交' : '修改'}
</Button>
</Form.Item>
</>
)
}
</Form>
<Modal
open={pdfViewOPen}
width={1000}
title=""
footer={null}
style={{ marginTop: "-5%" }}
onCancel={() => {
setPdfViewOPen(false)
}}
>
<iframe
style={{
height: '80vh',
width: '100%',
border: 0,
marginTop: 20,
}}
src={`${process.env.PUBLIC_URL}/static/pdf/web/viewer.html?file=${encodeURIComponent(`/gunshiApp/xyt/projectEvents/file/download/${iframeSrc}`)}`}
/>
</Modal>
</>
);
}
export default ModalForm;

View File

@ -0,0 +1,150 @@
import React, { Fragment, useRef, useMemo, useEffect, useState } from 'react';
import BasicCrudModal from '../../../../components/crud/BasicCrudModal';
import { Table, Card, Modal, Form, Input, Button, Row, Col, Timeline, message, Tabs, Image } from 'antd';
import { FileWordOutlined, FilePdfOutlined, FileZipOutlined, FileExcelOutlined } from '@ant-design/icons';
import { useSelector } from 'react-redux';
import ToolBar from './toolbar';
import ModalForm from './form';
import apiurl from '../../../../service/apiurl';
import usePageTable from '../../../../components/crud/usePageTable2';
import { createCrudService } from '../../../../components/crud/_';
import { CrudOpRender_text } from '../../../../components/crud/CrudOpRender';
const url = "http://223.75.53.141:9102/test.by-lyf.tmp"
const Page = () => {
const role = useSelector(state => state.auth.role);
const editBtn = role?.rule?.find(item => item.menuName == "编辑");
const viewBtn = role?.rule?.find(item => item.menuName == "查看");
const delBtn = role?.rule?.find(item => item.menuName == "删除");
const refModal = useRef();
const [searchVal, setSearchVal] = useState(false)
const [iframeSrc, setIframeSrc] = useState('')
const [pdfViewOPen, setPdfViewOPen] = useState(false)
const [isFetch, setIsFetch] = useState(false)
const columns = [
{ title: '序号', key: 'inx', dataIndex: 'inx', width: 60, align: "center" },
{ title: '标题', key: 'name', dataIndex: 'name', width: 250, ellipsis: true },
{
title: '制定机关', key: 'eventsDate', dataIndex: 'eventsDate', width: 140,
},
{
title: '法律性质', key: 'eventsType', dataIndex: 'eventsType', width: 140,
render: (value) => <span>{value == 1 ? "综合大事记" : value == 2 ? "专题大事记" : ''}</span>,
},
{
title: '时效性', key: 'eventsDesc', dataIndex: 'eventsDesc', width: 300
},
{
title: '公布日期', key: 'eventsDesc', dataIndex: 'eventsDesc', width: 300
},
{
title: '施行日期', key: 'eventsDesc', dataIndex: 'eventsDesc', width: 300
},
{
title: '上传时间', key: 'eventsDesc', dataIndex: 'eventsDesc', width: 300
},
{
title: '附件', key: 'fileName', dataIndex: 'fileName', width: 300,render:(v,r)=><a onClick={()=>viewPdf(r.fileId)}>{v}</a>
},
{
title: '操作', key: 'operation', width: 240, fixed: 'right', align: 'center',
render: (value, row, index) => (
<CrudOpRender_text
edit={true}
del={true}
view={true}
command={(cmd) => () => command(cmd)(row)} />)
},
];
const width = useMemo(() => columns.reduce((total, cur) => total + (cur.width), 0), [columns]);
const command = (type) => (params) => {
if (type === 'save') {
refModal.current.showSave();
} else if (type === 'edit') {
refModal.current.showEdit({ ...params });
} else if (type === 'view') {
refModal.current.showView(params);
} else if (type === 'del') {
refModal.current.onDeleteGet(apiurl.rcgl.gcdsj.delete + `/${params.id}`);
}
}
const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.rcgl.gcdsj.page).find_noCode);
/**
* @description 处理成功的回调
*/
const successCallback = () => {
refresh()
setIsFetch(!isFetch)
}
const viewPdf = (params) => {
setIframeSrc(params)
setPdfViewOPen(true)
}
useEffect(() => {
const params = {
search: {
...searchVal,
}
};
search(params)
}, [searchVal])
return (
<>
<div className='content-root clearFloat xybm' style={{ paddingRight: "0", paddingBottom: "0" }}>
<div className='lf CrudAdcdTreeTableBox' style={{ width: "100%", overflowY: "auto" }}>
<Card className='nonebox'>
<ToolBar
setSearchVal={setSearchVal}
onSave={command('save')}
role={role}
/>
</Card>
<div className="ant-card-body" style={{ padding: "20px 0 0 0" }}>
<Table columns={columns} rowKey="inx" {...tableProps} scroll={{ x: width, y: "calc( 100vh - 400px )" }} />
</div>
</div>
<BasicCrudModal
width={1000}
ref={refModal}
title=""
component={ModalForm}
onCrudSuccess={successCallback}
// onCrudSuccess={()=>{refresh({addvcd:localStorage.getItem('ADCD6')})}}
/>
</div>
<Modal
open={pdfViewOPen}
width={1000}
title=""
footer={null}
style={{ marginTop: "-5%" }}
onCancel={() => {
setPdfViewOPen(false)
}}
>
<iframe
style={{
height: '80vh',
width: '100%',
border: 0,
marginTop: 20,
}}
src={`${process.env.PUBLIC_URL}/static/pdf/web/viewer.html?file=${encodeURIComponent(`/gunshiApp/xyt/projectEvents/file/download/${iframeSrc}`)}`}
/>
</Modal>
</>
);
}
export default Page;

View File

@ -0,0 +1,91 @@
import React, { useEffect,useState } from 'react';
import { Form, Input, Button, DatePicker, Select } from 'antd';
import { DownOutlined, UpOutlined } from '@ant-design/icons'
import moment from 'moment';
const { RangePicker } = DatePicker;
const ToolBar = ({ setSearchVal, onSave, storeData,role }) => {
const addBtn = role?.rule?.find(item => item.menuName == "新增");
const searchBtn = role?.rule?.find(item => item.menuName == "查询");
const [form] = Form.useForm();
const [showGj , setShowGj] =useState(false)
const onFinish = (values) => {
let dataSo;
if (values.tm) {
dataSo = {
start: moment(values.tm[0]).format('YYYY-MM-DD HH:mm:ss'),
end: moment(values.tm[1]).format('YYYY-MM-DD HH:mm:ss')
}
}
delete values.tm
setSearchVal({...values, dataSo});
}
const opntios=[
{label:'宪法',value:'宪法'},
{label:'法律',value:'法律'},
{label:'行政法规',value:'行政法规'},
{label:'督察法规',value:'督察法规'},
{label:'司法解释',value:'司法解释'},
{label:'地方性法规',value:'地方性法规'},
]
const styles={
fontFamily: '微软雅黑 Bold", "微软雅黑 Regular", 微软雅黑, sans-serif',
fontWeight: '700',
fontStyle: 'normal',
fontSize: '16px'
}
return (
<>
<div style={{display:'flex',justifyContent:'space-between'}}>
<Form form={form} className='toolbarBox' layout="inline" onFinish={onFinish}>
<div style={{display:'flex'}}>
<Form.Item label="标题" name="name">
<Input allowClear style={{width:'150px'}}/>
</Form.Item>
<Form.Item label="制定机关" name="name">
<Input allowClear style={{width:'150px'}}/>
</Form.Item>
<Form.Item label="制定机关" name="name">
<Select allowClear style={{width:'150px'}} options={opntios}/>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">查询</Button>
</Form.Item>
<Form.Item>
<Button onClick={() => form.resetFields()}>重置</Button>
</Form.Item>
{
(onSave) ?
<Form.Item>
<Button onClick={onSave}>新增</Button>
</Form.Item>
:null
}
<Form.Item>
<div style={styles} onClick={()=>setShowGj(!showGj)}>高级搜索 {!showGj&&<DownOutlined />} {showGj&&<UpOutlined />}</div>
</Form.Item>
</div>
{showGj&&<div style={{display:'flex'}}>
<Form.Item label="时效性" name="name">
<Select allowClear style={{width:'150px'}} options={opntios}/>
</Form.Item>
<Form.Item label="公布日期" name="name">
<RangePicker allowClear />
</Form.Item>
<Form.Item label="施行日期" name="name">
<RangePicker allowClear />
</Form.Item>
<Form.Item label="上传时间" name="name">
<RangePicker allowClear />
</Form.Item>
</div>}
</Form>
</div>
</>
);
}
export default ToolBar;

View File

@ -0,0 +1,306 @@
import React, { useEffect, useState, useMemo, useRef } from 'react';
import { Form, Button, Input, Row, Upload, Col, Table, DatePicker, InputNumber, message, Image, Modal, Typography, Select } from 'antd';
import { DeleteOutlined, FileWordOutlined, FilePdfOutlined, FileZipOutlined, FileExcelOutlined } from '@ant-design/icons';
import { formItemLayout, btnItemLayout } from '../../../../components/crud/FormLayoutProps';
import apiurl from '../../../../service/apiurl';
// import "./index.less"
import moment from 'moment';
const { RangePicker } = DatePicker
const { Dragger } = Upload;
const url = "http://223.75.53.141:9102/test.by-lyf.tmp"
const opntios=[
{label:'宪法',value:'宪法'},
{label:'法律',value:'法律'},
{label:'行政法规',value:'行政法规'},
{label:'督察法规',value:'督察法规'},
{label:'司法解释',value:'司法解释'},
{label:'地方性法规',value:'地方性法规'},
]
const ModalForm = ({ mode, record, onEdit, onSave, onSimilarSave }) => {
const [form] = Form.useForm();
const [fileList, setFileList] = useState([]) //上传文件列表
const [fileIds, setFileIds] = useState([])
const [iframeSrc, setIframeSrc] = useState('')
const [pdfViewOPen, setPdfViewOPen] = useState(false)
const [loading, setLoading] = useState(false)
/**
* @description 文件下载
* @param {String} params 文件fileId
*/
const download = (params) => {
let downloadLink = document.createElement("a");
downloadLink.href = `http://local.gunshiiot.com:18083/gunshiApp/xyt/projectEvents/file/download/${params}`;
downloadLink.download = `${params.fileName}`;
downloadLink.style.display = "none";
// 将链接添加到页面中
document.body.appendChild(downloadLink);
// 模拟点击事件,开始下载
downloadLink.click();
}
/**
* @description 上传图片
* @param {string} file 上传的文件
*/
const fileChange = (info) => {
if (info.file.status === "done") {
setLoading(false);
}
if (info.file.status === "uploading") {
setLoading(true);
}
if (info.file.status === "error") {
message.error("文件上传失败")
setLoading(false);
}
let fileIds = info.fileList.map(file => {
return file.response?.data?.fileId
})
setFileIds(fileIds)
setFileList(info.fileList)
}
/**
* @description pdf文件预览
* @param {String} params 文件预览url
*/
const viewPdf = (params) => {
setIframeSrc(params)
setPdfViewOPen(true)
}
const onfinish = (values) => {
values.eventsDate = values.eventsDate ? moment(values.eventsDate).format("YYYY-MM-DD 00:00:00") : ''
let oldFiles = fileList.map(item => ({ fileId: item.response?.data?.fileId }))
if (mode === 'edit') {
values.files = oldFiles;
values.id = record.id;
onEdit(apiurl.rcgl.gcdsj.edit, values)
}
if (mode === 'save') {
values.files = oldFiles
onSave(apiurl.rcgl.gcdsj.save, values)
}
}
/**
* @description 删除上传的图片
* @param {string} id 删除的id
*/
const deleteFile = (fileId) => {
console.log(fileId);
let filterFile = fileList.filter(item => item.response?.data?.fileId !== fileId);
setFileList(filterFile)
}
useEffect(() => {
if (mode != 'save') {
const imgFile = record?.files?.map(o => ({
name: o.fileName,
response: {
data: {
filePath: o.filePath,
fileId: o.fileId
}
},
}))
setFileList(imgFile)
}
}, [record, mode])
return (
<>
<Form
form={form}
{...formItemLayout}
onFinish={onfinish}
initialValues={record}
>
<Row>
<Col span={12}>
<Form.Item
label="标题"
name="name"
rules={[{ required: true }]}
>
<Input disabled={mode === 'view'} style={{ width: '100%' }} allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="制定机关"
name="name"
rules={[{ required: true }]}
>
<Input disabled={mode === 'view'} style={{ width: '100%' }} allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="制定机关" name="name">
<Select allowClear style={{ width: '150px' }} options={opntios} />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="失效性" name="name">
<Select allowClear style={{ width: '150px' }} options={opntios} />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="公布日期"
name="eventsDate"
getValueFromEvent={(e, dateString) => dateString}
getValueProps={(value) => ({ value: value ? moment(value) : undefined })}
rules={[
{
required: true,
},
]}
>
<DatePicker disabled={mode === 'view'} format={'YYYY-MM-DD'} style={{ width: '100%' }} allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="施行日期"
name="eventsDate"
getValueFromEvent={(e, dateString) => dateString}
getValueProps={(value) => ({ value: value ? moment(value) : undefined })}
rules={[
{
required: true,
},
]}
>
<DatePicker disabled={mode === 'view'} format={'YYYY-MM-DD'} style={{ width: '100%' }} allowClear />
</Form.Item>
</Col>
</Row>
<Row>
<Col span={24}>
<Form.Item
label="附件"
name="fieldId"
labelCol={{ span: 3 }}
wrapperCol={{ span: 19 }}
>
{mode !== "view" &&
<Dragger
name='file'
// multiple
action="/gunshiApp/xyt/projectEvents/file/upload/singleSimple"
onChange={fileChange}
onDrop={(info) => { console.log(info.dataTransfer.files); }}
fileList={fileList}
disabled={loading}
// onSuccess={handleSuccess}
>
<p className="ant-upload-text">点击或拖拽文件到此区域上传</p>
<p className="ant-upload-hint">
支持扩展名.doc .docx .pdf .jpg .png .ppt
</p>
</Dragger>
}
<Row gutter={[16]}>
{
fileList.length > 0 && fileList.map(file => {
return (
<Col span={12}>
<div className="file-item" style={{ width: "75%" }}>
<div className='file-description'>
{file.name.indexOf('.docx') > -1 ?
<div
onClick={() => { download(file.response?.data?.fileId) }}
style={{ cursor: 'pointer' }}
>
<FileWordOutlined
style={{ fontSize: 40 }}
/>
</div>
:
file.name.indexOf('.pdf') > -1 ?
<div
onClick={() => { viewPdf(file.response?.data?.fileId) }}
style={{ cursor: 'pointer' }}
>
<FilePdfOutlined style={{ fontSize: 40 }} />
</div>
:
file.name.indexOf('.zip') > -1 ?
<div
onClick={() => { download(file.response?.data?.fileId) }}
style={{ cursor: 'pointer' }}
>
<FileZipOutlined style={{ fontSize: 40 }} />
</div>
:
file.name.indexOf('.xlsx') > -1 ?
<div
onClick={() => { download(file.response?.data?.fileId) }}
style={{ cursor: 'pointer' }}
>
<FileExcelOutlined style={{ fontSize: 40 }} />
</div>
:
<Image width={60} src={url + file.response?.data?.filePath} alt='' />
}
<span>{file.name}</span>
</div>
<div className={mode == "view" ? 'delete-icon disable-icon' : 'delete-icon'} onClick={() => deleteFile(file.response?.data?.fileId)}>
<DeleteOutlined />
</div>
</div>
</Col>
)
})
}
</Row>
</Form.Item>
</Col>
</Row>
{
mode === 'view' ? null : (
<>
<Form.Item {...btnItemLayout}>
<Button type="primary" htmlType="submit">
{mode === 'save' ? '提交' : '修改'}
</Button>
</Form.Item>
</>
)
}
</Form>
<Modal
open={pdfViewOPen}
width={1000}
title=""
footer={null}
style={{ marginTop: "-5%" }}
onCancel={() => {
setPdfViewOPen(false)
}}
>
<iframe
style={{
height: '80vh',
width: '100%',
border: 0,
marginTop: 20,
}}
src={`${process.env.PUBLIC_URL}/static/pdf/web/viewer.html?file=${encodeURIComponent(`/gunshiApp/xyt/projectEvents/file/download/${iframeSrc}`)}`}
/>
</Modal>
</>
);
}
export default ModalForm;

View File

@ -0,0 +1,136 @@
import React, { Fragment, useRef, useMemo, useEffect, useState } from 'react';
import BasicCrudModal from '../../../../components/crud/BasicCrudModal';
import { Table, Card, Modal, Form, Input, Button, Row, Col, Timeline, message, Tabs, Image } from 'antd';
import { FileWordOutlined, FilePdfOutlined, FileZipOutlined, FileExcelOutlined } from '@ant-design/icons';
import { useSelector } from 'react-redux';
import ModalForm from './form';
import apiurl from '../../../../service/apiurl';
import usePageTable from '../../../../components/crud/usePageTable2';
import { createCrudService } from '../../../../components/crud/_';
import { CrudOpRender_text } from '../../../../components/crud/CrudOpRender';
const url = "http://223.75.53.141:9102/test.by-lyf.tmp"
const Page = () => {
const role = useSelector(state => state.auth.role);
const editBtn = role?.rule?.find(item => item.menuName == "编辑");
const viewBtn = role?.rule?.find(item => item.menuName == "查看");
const delBtn = role?.rule?.find(item => item.menuName == "删除");
const refModal = useRef();
const [searchVal, setSearchVal] = useState(false)
const [iframeSrc, setIframeSrc] = useState('')
const [pdfViewOPen, setPdfViewOPen] = useState(false)
const [isFetch, setIsFetch] = useState(false)
const columns = [
{ title: '序号', key: 'inx', dataIndex: 'inx', width: 60, align: "center" },
{ title: '标题', key: 'name', dataIndex: 'name', width: 250, ellipsis: true },
{
title: '制度类型', key: 'eventsDate', dataIndex: 'eventsDate', width: 140,
},
{
title: '发布日期', key: 'eventsDesc', dataIndex: 'eventsDesc', width: 300
},
{
title: '发布单位', key: 'eventsDesc', dataIndex: 'eventsDesc', width: 300
},
{
title: '上传时间', key: 'eventsDesc', dataIndex: 'eventsDesc', width: 300
},
{
title: '附件', key: 'fileName', dataIndex: 'fileName', width: 300,render:(v,r)=><a onClick={()=>viewPdf(r.fileId)}>{v}</a>
},
{
title: '操作', key: 'operation', width: 240, fixed: 'right', align: 'center',
render: (value, row, index) => (
<CrudOpRender_text
edit={true}
del={true}
view={true}
command={(cmd) => () => command(cmd)(row)} />)
},
];
const width = useMemo(() => columns.reduce((total, cur) => total + (cur.width), 0), [columns]);
const command = (type) => (params) => {
if (type === 'save') {
refModal.current.showSave();
} else if (type === 'edit') {
refModal.current.showEdit({ ...params });
} else if (type === 'view') {
refModal.current.showView(params);
} else if (type === 'del') {
refModal.current.onDeleteGet(apiurl.rcgl.gcdsj.delete + `/${params.id}`);
}
}
const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.rcgl.gcdsj.page).find_noCode);
/**
* @description 处理成功的回调
*/
const successCallback = () => {
refresh()
setIsFetch(!isFetch)
}
const viewPdf = (params) => {
setIframeSrc(params)
setPdfViewOPen(true)
}
useEffect(() => {
const params = {
search: {
...searchVal,
}
};
search(params)
}, [searchVal])
return (
<>
<div className='content-root clearFloat xybm' style={{ paddingRight: "0", paddingBottom: "0" }}>
<div className='lf CrudAdcdTreeTableBox' style={{ width: "100%", overflowY: "auto" }}>
<div className="ant-card-body" style={{ padding: "20px 0 0 0" }}>
<Table columns={columns} rowKey="inx" {...tableProps} scroll={{ x: width, y: "calc( 100vh - 400px )" }} />
</div>
</div>
<BasicCrudModal
width={1000}
ref={refModal}
title=""
component={ModalForm}
onCrudSuccess={successCallback}
// onCrudSuccess={()=>{refresh({addvcd:localStorage.getItem('ADCD6')})}}
/>
</div>
<Modal
open={pdfViewOPen}
width={1000}
title=""
footer={null}
style={{ marginTop: "-5%" }}
onCancel={() => {
setPdfViewOPen(false)
}}
>
<iframe
style={{
height: '80vh',
width: '100%',
border: 0,
marginTop: 20,
}}
src={`${process.env.PUBLIC_URL}/static/pdf/web/viewer.html?file=${encodeURIComponent(`/gunshiApp/xyt/projectEvents/file/download/${iframeSrc}`)}`}
/>
</Modal>
</>
);
}
export default Page;

View File

@ -0,0 +1,27 @@
.ddForm .ant-form-item-label {
width: 110px;
}
.zxform .ant-form-item-control {
border: 1px solid;
height: 50px;
}
.zxform .ant-form-item-label {
border: 1px solid;
width: 110px;
height: 50px;
display: flex;
align-items: center;
justify-content: flex-end;
}
.zxform .ant-input-outlined {
border: none;
}
.zxform .ant-form-item {
margin-bottom: 0;
}
.zxform .ant-input {
height: 48px;
}
.zxform .ant-input-disabled {
background-color: #fff;
}

View File

@ -0,0 +1,50 @@
.ddForm{
.ant-form-item-label{
width: 110px;
}
}
.zxform{
.ant-form-item{
margin-bottom: 0;
}
.ant-form-item-control{
border: 1px solid;
height: 50px;
display: flex;
justify-content: center;
}
.ant-form-item-label{
border: 1px solid;
// border-right:none;
width: 110px;
height: 50px;
display: flex;
align-items: center;
justify-content: flex-end;
}
// .ant-input-outlined {
// border:none
// }
.ant-input{
height: 40px;
width: 90%;
}
.empty{
.ant-input-disabled{
background-color: #fff;
}
}
.ant-select-single{
height: 40px;
width: 90%;
}
}

View File

@ -0,0 +1,221 @@
import React, { useEffect, useState, useRef } from 'react';
import { Space, Table, Radio, DatePicker, Form, Select, Button, message, Upload, Input, Row, Col, Switch, Image } from 'antd';
import './ddForm.less'
import dayjs from 'dayjs'
import { InboxOutlined, LinkOutlined, DeleteOutlined, LoadingOutlined,VerticalAlignBottomOutlined } from '@ant-design/icons'
import { httpPostFile } from '../../../../utils/request';
import apiUrl from '../../../../service/apiurl'
import PdfView from './pdfView'
const { RangePicker } = DatePicker;
const { TextArea } = Input;
const baseUrl = "http://local.gunshiiot.com:18083/gunshiApp/xintankou"
const FormZdy = ({ typeName = "ddForm", formJson, getFormInfo, type, formJsonData, typeUpload = 'dispatch', isModalOpen,fileType,footer=true }) => {
const [fileList, setFileList] = useState([])
const [fileListUp, setFileLisUp] = useState([])
const [url, setUrl] = useState('')
const [isModal, setIsModal] = useState(false)
// debugger;
const [form] = Form.useForm();
// function onDocumentLoadSuccess({ numPages }) {
// setRenderNumPages(numPages);
// }
const onFinish = (e) => {
}
const getInfo = () => {
form.validateFields().then((values) => {
getFormInfo({ ...values, files: fileList, fileIds: fileList.map(item => item.id) })
form.resetFields()
setFileList([])
}).catch((errorInfo) => {
console.log(errorInfo, 'error');
})
//
}
const cancel = () => {
getFormInfo(false)
form.resetFields()
setFileList([])
}
const { Dragger } = Upload;
// const preView = (e) => {
// window.open('http://local.gunshiiot.com:18083/xintankou/api/file/preview/104')
// }
const deleteFile = (e) => {
let arr = fileList.filter(item => item.id !== e)
setFileList(arr)
}
const props = {
name: 'file',
multiple: true,
fileList: fileList,
showUploadList: false,
beforeUpload: (file, fileList) => {
if (fileType == "pic" &&
(file.type != "image/jpeg" || file.type != "image/png" || file.type != "image/jpg")) {
message.error('仅支持上传jpg/png/jpeg格式的图片');
return false;
} else {
return true;
}
},
onChange(e) {
setFileLisUp([...fileListUp, e.file])
httpPostFile(apiUrl.service.uploadFile.uploadUrl + "?group=" + typeUpload, e).then(res => {
setFileList([...fileList, res.data])
})
}
};
const onChange = () => { }
function checkMediaType(url) {
// 创建URL对象
var link = url;
// 获取路径的最后一个点之后的内容作为文件扩展名
var extension = link.split('.').pop().toLowerCase();
// 声明支持的图片和视频文件扩展名
var imageExtensions = ['jpg', 'jpeg', 'gif', 'png'];
var file = ['pdf', 'word', 'xslx', 'xsl', 'txt',"pptx"];
// 判断文件扩展名是否在图片扩展名数组中
if (imageExtensions.includes(extension)) {
return 'image';
}
// 判断文件扩展名是否在视频扩展名数组中
if (file.includes(extension)) {
return extension;
}
// 扩展名不在图片或视频数组中返回null表示无法确定媒体类型
return null;
}
const preView = (item) => {
if (checkMediaType(item.name) == 'pdf') {
// window.open(baseUrl + item.previewUrl)
setUrl(`${`http://local.gunshiiot.com:18083/xintankou`}/static/pdf/web/viewer.html?file=${encodeURIComponent(`http://local.gunshiiot.com:18083/gunshiApp/xintankou/${item.previewUrl}`)}`)
setIsModal(true)
}
}
/**
* @description 文件下载
* @param {String} params 文件fileId
*/
const download = (id,name) => {
let downloadLink = document.createElement("a");
downloadLink.href = `http://local.gunshiiot.com:18083/gunshiApp/xintankou/api/file/download/${id}`;
downloadLink.download = `${name}`;
downloadLink.style.display = "none";
// 将链接添加到页面中
document.body.appendChild(downloadLink);
// 模拟点击事件,开始下载
downloadLink.click();
}
useEffect(() => {
form.resetFields()
let formType = type
if(type='edit'){
formType=2
}
if(type == 'view'){
formType =1
}
if(type=='save'){
formType =0
}
if (formType == 1 || formType == 2 || formType == 3) {
form.setFieldsValue(formJsonData)
if (formJsonData?.files) {
setFileList(formJsonData.files)
}
}
return () => {
setFileList([])
}
}, [type, formJsonData, isModalOpen])
return (
<div style={{ backgroundColor: '#fff' }}>
<Form form={form} name="searchTabel" onFinish={onFinish} className={typeName}>
<Row>
{formJson.map(item => {
return (
<Col span={item.span} >
<Form.Item
label={item.label}
name={item.key}
rules={[{ required: item.required, message: '请输入' + item.label }]}
className={item.type == 'empty'?'empty':'noempty'}
>
{item.type == "input" && <Input disabled={type == 1 || item.disabled} placeholder={item.placeholder} />}
{item.type == "Select" && <Select disabled={type == 1} options={item.options} />}
{item.type == "empty" && <Input disabled={item.type == "empty" ? true : false} />}
{item.type == "Switch" && <Switch defaultChecked onChange={onChange} disabled={type == 1} />}
{item.type == "DatePicker" && <DatePicker disabled={type == 1} style={{width:"100%"}} />}
{item.type == "TextArea" && <TextArea rows={4} disabled={type == 1} />}
{item.type == "Radio" &&<Radio.Group options={item.options} />}
{item.type == "RangePicker" &&
<RangePicker disabled={type=='view'} />}
{item.type == "upload" &&
<>
{type !== 1 && <Dragger {...props}>
<p className="ant-upload-drag-icon">
<InboxOutlined />
</p>
{fileType == "pic" ? <p className="ant-upload-text">点击或将文件拖拽到这里上传 支持扩展名jpegpng</p>: <p className="ant-upload-text"></p>}
</Dragger>}
<div>
{fileList?.map((item) => {
return <div className='flex align-center' style={{ minHeight: "50px", fontSize: 14,columnGap:10, cursor: checkMediaType(item.name) == 'image' || checkMediaType(item.name) == 'pdf'?'pointer':"not-allowed" }}>
<div style={{width:40,height:40,display:"flex",alignItems:'center'}}>
{checkMediaType(item.name) == 'image' && <Image
height={40}
src={baseUrl + item.previewUrl}
/>}
{
checkMediaType(item.name) !== 'image' &&
<span >{checkMediaType(item.name)?.toUpperCase()}</span>
}
</div>
<span onClick={() => preView(item)}>{item.name}</span>
{type==2&&<DeleteOutlined onClick={() => deleteFile(item.id)} />}
<VerticalAlignBottomOutlined onClick={() => download(item.id,item.name)} />
</div>
})}
</div>
</>}
</Form.Item>
</Col>
)
})}
</Row>
</Form >
{type !== 1 &&<div className="flex flex-end" style={{ marginTop: 10 }}>
<Button type="" style={{ marginRight: 10 }} onClick={cancel}>取消</Button>
<Button type="primary" onClick={getInfo}>确定</Button>
</div>}
<PdfView url={url} isModal={isModal} setModalN={(e)=>setIsModal(e)}/>
</div>
);
}
export default FormZdy;

View File

@ -0,0 +1,46 @@
import React, { Component, useEffect, useState } from 'react';
import { Document, Page, pdfjs } from 'react-pdf';
import { Modal } from 'antd';
const Pdf = ({ url,isModal,setModalN }) => {
const [isModalOpen, setIsModalOpen] = useState(false);
const handleOk = () => {
setIsModalOpen(false);
setModalN(false)
};
const handleCancel = () => {
setIsModalOpen(false);
setModalN(false)
};
useEffect(()=>{
setIsModalOpen(isModal)
},[isModal])
return (
<div>
<Modal
title={<div style={{ backgroundColor: '#259dff', padding: 10, color: "#fff" }}>pdf</div>}
open={isModalOpen}
width={1000}
onOk={handleOk}
footer={false}
onCancel={handleCancel}
destroyOnClose>
<div style={{ padding: "0 10px" }}>
<iframe
style={{
height: '80vh',
width: '100%',
border: 0,
marginTop: 20,
}}
src={url}
/>
</div>
</Modal>
</div>
);
}
export default Pdf