lsf-dev
xielei 2024-09-23 15:52:06 +08:00
parent 65449e77a2
commit 8d6f15bcbe
14 changed files with 1368 additions and 17 deletions

View File

@ -226,7 +226,10 @@ export async function loadMenu(): Promise<MenuItem[]> {
id: id(), title: '考核模板管理', path: '/mgr/sz/jdkh/khmbgl',
}
]
}
},
{ id: id(), title: '法律法规', path: '/mgr/sz/flfg' },
{ id: id(), title: '制度管理', path: '/mgr/sz/zdgl' },
]
},
{ id: id(), title: '四预', redirect: '/mgr/sy/fhxzfx', icon: 'fxzb',

View File

@ -86,7 +86,7 @@ import Kqys from './sq/qys/kqys/index.js'
import Xyys from './sq/qys/xyys/index.js'
import Gcys from './sq/qys/gcys/index.js'
import Gcdsj from './sq/qzq/gcdsj'
import Qzqda from './sq/qzq/qzqda'
// import Zcdjxx from './sq/qys/'
// import Zcdjxx from './sq/qfg/zcdjxx'
// import Zcdjxx from './sq/qfg/zcdjxx'
@ -94,6 +94,10 @@ import Gcdsj from './sq/qzq/gcdsj'
// 四制 - 组织机构查看
import Zzjgck from './sz/zzjgck'
import Flfg from './sz/flfg'
import Zdgl from './sz/zdgl'
const HomePage = lazy(() => import('./Home'))
@ -231,9 +235,13 @@ const AppRouters: React.FC = () => {
{ path: 'sq/qys/kqys', element: <Kqys /> },
{ path: 'sq/qys/xyys', element: <Xyys /> },
{ path: 'sq/qys/gcys', element: <Gcys /> },
{ path: 'sq/qzq/Gcdsj', element: <Gcdsj /> },
{ path: 'sq/qzq/gcdsj', element: <Gcdsj /> },
{ path: 'sq/qys/qzqda', element: <Qzqda /> },
// 四制-组织机构查看
{ path: 'sz/gltx/zzjgck', element: <Zzjgck /> },
{ path: 'sz/flfg', element: <Flfg /> },
{ path: 'sz/zdgl', element: <Zdgl /> },
],
},
{ path: '/login', element: <LoginPage /> },

View File

@ -5,7 +5,8 @@ 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 { useState } from "react"
import { Rnd } from "react-rnd"
import { useState, useEffect } from "react"
const list = [
{ name: '水库地理位置图', key: 1, img: qys1 },
{ name: '水库平面布置图', key: 2, img: qys2 },
@ -17,14 +18,57 @@ const Page = () => {
const tabClick = (item) => {
setUrl(item.img)
}
useEffect(() => {
let scale = 1
const img = document.getElementById("img");
const fun = (e) => {
console.log(1111)
// 大于0:滚轮向上滚动 小于0:滚轮向下滚动
if (e.wheelDelta > 0) {
scale += 0.05;
img.style.transform = `scale(${scale})`;
} else {
if (scale == 1) {
img.style.left = 0 + "px";
img.style.top = 0 + "px";
}
// 缩放值大于1时,可以缩小,反之亦然
if (scale > 1) {
scale -= 0.05;
img.style.transform = `scale(${scale})`;
}
}
}
img.addEventListener("wheel", fun)
// getSyData()
// getSlData()
// getWyData()
// getDmData()
return () => {
img.removeEventListener("wheel", fun)
}
}, [])
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>)}
</div>
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center',overflow:'auto',height:'calc(100% - 100px)' }}>
<Image src={url} width='80%' preview={false} />
<Rnd
default={{
x: 10,
y: 60,
width: '80%',
height: 'calc(100% - 100px)'
}}
>
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', width:'72%',height:'98%',}}>
<Image src={url} id="img" preview={false} />
</div>
</Rnd>
</div>
)
}

View File

@ -6,7 +6,7 @@ import './index.less'
const Page = () => {
return (
<div style={{ display: 'flex',height:'100%' }}>
<div style={{ backgroundColor: '#ffffff',width:390,height:'100%',marginRight:10 }}>
<div style={{ backgroundColor: '#ffffff',width:390,height:'100%',marginRight:10,padding:10 }}>
<div className="title">
<Image src={title} />保护对象
</div>
@ -16,7 +16,7 @@ const Page = () => {
</div>
</div>
<div style={{ backgroundColor: '#ffffff',flex:1}}>
<div style={{ backgroundColor: '#ffffff',flex:1,padding:10}}>
<div className="title">
<Image src={title} />转移路线示意图
</div>

View File

@ -44,7 +44,7 @@ const ToolBar = ({ setSearchVal, onSave, storeData,role }) => {
<Button onClick={() => form.resetFields()}>重置</Button>
</Form.Item>
{
(onSave && addBtn) ?
(onSave) ?
<Form.Item>
<Button onClick={onSave}>新增</Button>
</Form.Item>

View File

@ -0,0 +1,152 @@
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 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 [isFetch, setIsFetch] = useState(false)
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 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();
}
const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.rcgl.gcdsj.page).find_noCode);
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" }}>
<div className='time-line'>
<Timeline>
{tableProps.dataSource.map((item, index) => (
<Timeline.Item key={index}>
<div className='time-line-item'>
<span style={{width:100}}>{item.eventsDate}</span>
<div className='item-right'>
<span>{item.eventsDesc}</span>
<div style={{ display: "flex"}}>
<span>附件</span>
<Row gutter={[16]} style={{flex:1}}>
{
item.files.length > 0 && item.files.map(file => {
return (
<Col span={12}>
<div className="file-item" style={{width:"100%"}}>
<div className='file-description'>
{file.fileName.indexOf('.docx') > -1 ?
<div
onClick={() => { download(file.fileId) }}
style={{ cursor: 'pointer' }}
>
<FileWordOutlined
style={{ fontSize: 40 }}
/>
</div>
:
file.fileName.indexOf('.pdf') > -1 ?
<div
onClick={() => { viewPdf(file?.fileId) }}
style={{ cursor: 'pointer' }}
>
<FilePdfOutlined style={{ fontSize: 40 }} />
</div>
:
file.fileName.indexOf('.zip') > -1 ?
<div
onClick={() => { download(file?.fileId) }}
style={{ cursor: 'pointer' }}
>
<FileZipOutlined style={{ fontSize: 40 }} />
</div>
:
file.fileName.indexOf('.xlsx') > -1 ?
<div
onClick={() => { download(file?.fileId) }}
style={{ cursor: 'pointer' }}
>
<FileExcelOutlined style={{ fontSize: 40 }} />
</div>
:
<Image width={60} src={url +file?.filePath} alt='' />
}
<span>{file.fileName}</span>
</div>
</div>
</Col>
)
})
}
</Row>
</div>
</div>
</div>
</Timeline.Item>
))}
</Timeline>
</div>
</div>
</div>
</div>
</>
);
}
export default Page;

View File

@ -0,0 +1,30 @@
.basic-info{
position: relative;
font-size: 16px;
margin-bottom: 20px;
padding:5px 25px;
border-bottom: 1px solid #eee;
&::before{
position: absolute;
top:8px;
left:0;
content: "";
display: block;
width: 5px;
height: 20px;
background-color: #0079fe;
}
}
.time-line{
width: 50%;
margin-left: 6%;
margin-top: 1%;
.time-line-item{
display: flex;
// align-items: center;
column-gap: 20px;
.item-right{
flex:1
}
}
}

View File

@ -0,0 +1,59 @@
import React, { useEffect,useState } from 'react';
import { Form, Input, Button, DatePicker } from 'antd';
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 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});
}
return (
<>
<div style={{display:'flex',justifyContent:'space-between'}}>
<Form form={form} className='toolbarBox' layout="inline" onFinish={onFinish}>
<Form.Item label="名称" name="name">
<Input allowClear style={{width:'150px'}}/>
</Form.Item>
<Form.Item label="发生日期" name="tm">
<RangePicker
allowClear
showTime
style={{ width: "300px" }}
format="YYYY-MM-DD HH:mm:ss"
/>
</Form.Item>
{searchBtn ? <Form.Item>
<Button type="primary" htmlType="submit">查询</Button>
</Form.Item> : null }
<Form.Item>
<Button onClick={() => form.resetFields()}>重置</Button>
</Form.Item>
{
(onSave) ?
<Form.Item>
<Button onClick={onSave}>新增</Button>
</Form.Item>
:null
}
</Form>
</div>
</>
);
}
export default ToolBar;

308
src/views/sz/flfg/form.js Normal file
View File

@ -0,0 +1,308 @@
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 NormalSelect from '../../../components/Form/NormalSelect';
// 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;

150
src/views/sz/flfg/index.js Normal file
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;

287
src/views/sz/zdgl/form.js Normal file
View File

@ -0,0 +1,287 @@
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 NormalSelect from '../../../components/Form/NormalSelect';
// 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">
<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="name"
rules={[{ required: true }]}
>
<Input disabled={mode === 'view'} 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;

143
src/views/sz/zdgl/index.js Normal file
View File

@ -0,0 +1,143 @@
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: '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,76 @@
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}>
<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 label="发布日期" name="name">
<RangePicker allowClear />
</Form.Item>
<Form.Item label="发布单位" name="name">
<Input allowClear style={{ width: '150px' }} />
</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>
</div>
</>
);
}
export default ToolBar;