From ec175159cf1354c44c8fc458209280acfc79c4b2 Mon Sep 17 00:00:00 2001 From: liuyiliang Date: Sun, 23 Mar 2025 23:22:40 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/examination/craco.config.js | 5 +- packages/examination/public/index.html | 2 +- packages/examination/src/App.tsx | 24 +- packages/examination/src/api/axios.js | 9 + .../src/api/configuration/announcement.tsx | 58 -- .../src/api/configuration/gold.tsx | 21 - packages/examination/src/api/login/index.tsx | 2 +- .../examination/src/api/statistical/index.tsx | 26 +- .../examination/src/assets/profilePicture.svg | 6 + .../src/components/contentMain/index.js | 25 +- packages/examination/src/style/common.css | 54 +- packages/examination/src/utils/exportPdf.js | 74 ++ .../configuration_manage/announcement.tsx | 181 ----- .../compoents/announceCreate.tsx | 101 --- .../src/views/configuration_manage/gold.tsx | 73 -- .../compoents/ExamDetailAnalysisPage.tsx | 2 + .../exam-online/compoents/ExamDetailPage.tsx | 4 + .../exam-online/compoents/ExamListPage.tsx | 2 + .../compoents/ExamPaperAnalysisPage.tsx | 2 + .../compoents/ExamStatisticsPage.tsx | 2 +- .../src/views/examPaper/examPaperAdd.tsx | 4 + .../src/views/examPaper/examPaperList.tsx | 2 + .../examination/src/views/header/index.tsx | 17 +- .../examination/src/views/login/index.tsx | 51 +- .../src/views/orderManage/coupon.tsx | 6 +- .../src/views/orderManage/promotion.tsx | 6 +- .../src/views/question/questionAdd.tsx | 1 + .../src/views/question/questionList.tsx | 2 + .../examination/src/views/slider/index.js | 24 - .../examination/src/views/slider/menu.tsx | 111 +-- .../views/statistical/customerRetention.tsx | 19 +- .../src/views/statistical/detail.tsx | 4 +- .../src/views/statistical/enterpriseFile.tsx | 711 +++++++++++++++--- .../src/views/statistical/list.tsx | 113 +-- .../views/statistical/serviceStatistics.tsx | 252 +++++++ .../src/views/store_manage/index.tsx | 6 +- 36 files changed, 1204 insertions(+), 798 deletions(-) delete mode 100644 packages/examination/src/api/configuration/announcement.tsx delete mode 100644 packages/examination/src/api/configuration/gold.tsx create mode 100644 packages/examination/src/assets/profilePicture.svg create mode 100644 packages/examination/src/utils/exportPdf.js delete mode 100644 packages/examination/src/views/configuration_manage/announcement.tsx delete mode 100644 packages/examination/src/views/configuration_manage/compoents/announceCreate.tsx delete mode 100644 packages/examination/src/views/configuration_manage/gold.tsx create mode 100644 packages/examination/src/views/statistical/serviceStatistics.tsx diff --git a/packages/examination/craco.config.js b/packages/examination/craco.config.js index c39d847..02fda97 100644 --- a/packages/examination/craco.config.js +++ b/packages/examination/craco.config.js @@ -7,7 +7,10 @@ module.exports = { options: { lessLoaderOptions: { lessOptions: { - modifyVars: { '@primary-color': '#B5DBFF' }, + modifyVars: { + '@primary-color': '#6789E2', + '@border-radius-base': '4px', + }, javascriptEnabled: true, }, }, diff --git a/packages/examination/public/index.html b/packages/examination/public/index.html index 8cad91a..401d731 100644 --- a/packages/examination/public/index.html +++ b/packages/examination/public/index.html @@ -24,7 +24,7 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> - 重构项目 + 安责险系统 diff --git a/packages/examination/src/App.tsx b/packages/examination/src/App.tsx index 39b0574..5f58ed2 100644 --- a/packages/examination/src/App.tsx +++ b/packages/examination/src/App.tsx @@ -1,5 +1,5 @@ import React from 'react' -import {Layout, Breadcrumb, Select} from 'antd'; +import {Layout, Breadcrumb} from 'antd'; import Header from 'views/header'; import Slider from 'views/slider'; import ContentMain from 'components/contentMain'; @@ -25,6 +25,7 @@ class App extends React.Component { } componentDidMount() { + let stat = false; // @ts-ignore this.props.history.listen(path=>{ console.log("全局路由监听" + path.pathname) @@ -32,8 +33,18 @@ class App extends React.Component { console.log(tag) if (tag && tag.length > 0) { this.setState({ breadcrumb: tag }); + stat = true; } - }) + }); + if (!stat) { + // @ts-ignore + const location = this.props.location; + const tag = findTitleByKey(location.pathname.slice(1)); + console.log(tag) + if (tag && tag.length > 0) { + this.setState({ breadcrumb: tag }); + } + } } render() { @@ -46,14 +57,17 @@ class App extends React.Component {
- + {breadcrumb.map((item, index) => ( - {item} + + + {item} + + ))} -
) diff --git a/packages/examination/src/api/axios.js b/packages/examination/src/api/axios.js index ee4accf..eab0b30 100644 --- a/packages/examination/src/api/axios.js +++ b/packages/examination/src/api/axios.js @@ -7,6 +7,7 @@ import { } from 'react-router-dom' import { getToken, + setToken, removeToken } from './token' @@ -17,11 +18,19 @@ const instance = axios.create({ }) export const serverUrl = 'http://localhost:8187/'; + +const token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJjY2ljLXVzZXIiLCJpYXQiOjE3NDI1NDI4MTIsImV4cCI6MTc0MjYyOTIxMiwiaWQiOiI0MjY1NjA4NTc2MDI4MjYyNCIsInVzZXJOYW1lIjoi5rWL6K-VNjI2ODg1Iiwib3JnYW5JZCI6MzEwMTAwMDAsIm9yZ2FuTmFtZSI6IuS4iua1t-WIhuWFrOWPuCIsIm9yZ2FuQ29kZSI6IjMxMDEwMDAwIiwidXNlck5vIjoiODAwMDYyNjg4NSIsIm9yZ2FuVHlwZSI6IjMiLCJncmlkQ29kZSI6IjMxMDAwMCJ9.C8a04P9zSCaN388EMmCqlhcTen2H6GV4TmNQaA1qDac' +if (token) { + setToken(token); + localStorage.setItem('si', JSON.stringify({ eName: 'admin' })); +} + instance.interceptors.request.use( config => { let token = getToken(); if (token && token !== undefined && token !== "" && token !== "undefined") { config.headers['Authorization'] = "Bearer " + token; + config.headers['token'] = token; } return config; }, diff --git a/packages/examination/src/api/configuration/announcement.tsx b/packages/examination/src/api/configuration/announcement.tsx deleted file mode 100644 index fe5007b..0000000 --- a/packages/examination/src/api/configuration/announcement.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import axios from '../axios'; - -/* -* 公告列表 -*/ -export function getNoticeList(targetId: number | string, type: number) { - return axios({ - url: '/seller/na/wx/setting/notice/' + targetId + '/' + type, - method: 'get' - }); -} - -/* -* 公告添加 -*/ -export function addNotice(targetId: number | string, type: number, obj: any) { - return axios({ - url: '/seller/na/wx/setting/notice/' + targetId + '/' + type, - method: 'post', - data: obj - }); -} - -/* -* 公告启用 -*/ -export function enable(targetId: number | string, type: number, id: number | string, status: number) { - return axios({ - url: '/seller/na/wx/setting/notice/' + targetId + '/' + type + '/' + id, - method: 'put', - params: { - status: status - } - }); -} - -/* -* 公告禁用 -*/ -export function disable(targetId: number | string, type: number, id: number | string, status: number) { - return axios({ - url: '/seller/na/wx/setting/notice/' + targetId + '/' + type + '/' + id, - method: 'put', - params: { - status: status - } - }); -} - -/* -* 公告删除 -*/ -export function delNotice(targetId: number | string, type: number, id: number | string) { - return axios({ - url: '/seller/na/wx/setting/notice/' + targetId + '/' + type + '/' + id, - method: 'delete', - }); -} \ No newline at end of file diff --git a/packages/examination/src/api/configuration/gold.tsx b/packages/examination/src/api/configuration/gold.tsx deleted file mode 100644 index 9486e9a..0000000 --- a/packages/examination/src/api/configuration/gold.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import axios from '../axios'; - -/* -* 金币回显 -*/ -export function getCoin(targetId: number|string) { - return axios({ - url: '/seller/na/member/gold/coin/gold/coin/' + targetId, - method: 'get' - }); -} - -/* -* 金币添加 -*/ -export function addCoin(targetId: number|string, count: number) { - return axios({ - url: '/seller/na/member/gold/coin/gold/coin/' + targetId + '/' + count, - method: 'post', - }); -} \ No newline at end of file diff --git a/packages/examination/src/api/login/index.tsx b/packages/examination/src/api/login/index.tsx index 2f72be2..b2f62bb 100644 --- a/packages/examination/src/api/login/index.tsx +++ b/packages/examination/src/api/login/index.tsx @@ -2,7 +2,7 @@ import axios from '../axios' export function loginName(obj: any) { return axios({ - url: "/user/noa/auth/seller/login", + url: "/testLogin", method: "post", data: obj }) diff --git a/packages/examination/src/api/statistical/index.tsx b/packages/examination/src/api/statistical/index.tsx index ce64f0b..615bcc1 100644 --- a/packages/examination/src/api/statistical/index.tsx +++ b/packages/examination/src/api/statistical/index.tsx @@ -22,4 +22,28 @@ export function saveCustomerRet(obj: any){ method: "post", data: obj }) -} \ No newline at end of file +} + +export function getServiceStatPage(obj: any, page: number, num: number){ + return axios({ + url: "/ex/statistics/serviceStatPage?page=" + page + "&num=" + num, + method: "post", + data: obj + }) +} + +export function getOrganTree(obj: any){ + return axios({ + url: "/ex/statistics/getOrganByOrganId", + method: "get", + params: obj + }) +} + +export function getEnterpriseArchives(obj: any){ + return axios({ + url: "/ex/statistics/enterpriseArchives", + method: "get", + params: obj + }) +} diff --git a/packages/examination/src/assets/profilePicture.svg b/packages/examination/src/assets/profilePicture.svg new file mode 100644 index 0000000..a32b6db --- /dev/null +++ b/packages/examination/src/assets/profilePicture.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/packages/examination/src/components/contentMain/index.js b/packages/examination/src/components/contentMain/index.js index adf5027..2bdd234 100644 --- a/packages/examination/src/components/contentMain/index.js +++ b/packages/examination/src/components/contentMain/index.js @@ -4,28 +4,14 @@ import { withRouter, Switch, Route, Redirect } from 'react-router-dom'; import Home from 'views/home'; import Modify from 'views/modify_password'; -/* 订单管理 */ -import Promotion from 'views/orderManage/promotion'; // 股东活动订单 -import CouponOrder from 'views/orderManage/coupon'; // 优惠券订单 - -/* 配置管理 */ -import Gold from 'views/configuration_manage/gold'; // 金币配置 -import Announcement from 'views/configuration_manage/announcement'; // 公告管理 - -/* 积分与会员配置 */ -import IntegralRule from 'views/integralmember_manage'; // 积分规则 - -/* 小店管理 */ -import Store from 'views/store_manage'; // 店铺管理 - - -import DemoList from 'views/demo/demoList'; +import DemoList from 'views/demo/demoList';// demo list import ExamSchedule from "views/exam-online/exam-schedule"; import ExamAdd from "../../views/exam-online/exam-add"; import ExamEdit from "../../views/exam-online/exam-edit"; import ExamStatistics from "../../views/exam-online/exam-statistics"; import Customer from 'views/statistical/list'; import CustomerDetail from 'views/statistical/detail'; +import ServiceStatistics from 'views/statistical/serviceStatistics'; import ExamDetail from "../../views/exam-online/exam-detail"; import QuestionList from 'views/question/questionList'; @@ -45,18 +31,13 @@ class ContentMain extends Component { - - - - - - + diff --git a/packages/examination/src/style/common.css b/packages/examination/src/style/common.css index 49e7d11..6273901 100644 --- a/packages/examination/src/style/common.css +++ b/packages/examination/src/style/common.css @@ -87,6 +87,11 @@ body { padding: 30px; } +.special-class .ant-table-body{ + max-height: max-content !important; + overflow-y: hidden !important; +} + .left{ left: 200px; -webkit-transition: left .1s ease-in-out; @@ -105,9 +110,9 @@ body { .content{ width: auto; - padding: 15px 15px 20px 15px; - height: 100%; - overflow-y: scroll; + padding: 0 15px 20px 15px; + /*height: 100%;*/ + /*overflow-y: scroll;*/ -webkit-box-sizing: border-box; box-sizing: border-box; } @@ -125,9 +130,10 @@ body { .list-filter { position: relative; - margin: 20px 0; - background: #f8f8f8; - padding: 20px 10px; + margin: 0; + /*background: #f8f8f8;*/ + /*padding: 20px 10px;*/ + padding-bottom: 20px; } .filter .ant-form-item{ @@ -161,9 +167,10 @@ body { .logo p{ color: rgba(16, 16, 16, 1); - font-size: larger; + font-size: 20px; text-align: center; font-family: PingFangSC-regular; + font-weight: 400; } .logo img { @@ -217,4 +224,37 @@ table.ikd-input-table { table.ikd-input-table tbody tr:nth-child(2n) { background-color: #f7fbfe; + } + + .ant-table-thead > tr > th { + border-top: 1px solid #000000; + border-left: 1px solid #000000; + border-bottom: 1px solid #000000; + background: #B5DBFF; + } + .ant-table-tbody > tr > td { + transition: background 0.3s; + border-bottom: 1px solid #000000; + border-left: 1px solid #000000; + } + .ant-table-tbody > tr:last-child > td { + border-bottom: 1px solid transparent; + } + .ant-table-tbody .ant-table-cell-fix-right { + border-left: 2px solid #000000 !important; + } + .ant-table-container table > thead > tr:first-child th:first-child { + border-top-left-radius: 2px; + } + .ant-table-thead .ant-table-cell-fix-right { + border-left: 2px solid #000000 !important; + } + .ant-table-thead .ant-table-cell-scrollbar { + border-left: 1px solid #000000 !important; + } + .container .ant-table-body { + border-bottom: 1px solid #000000; + } + .ant-table-content { + border-bottom: 1px solid #000000; } \ No newline at end of file diff --git a/packages/examination/src/utils/exportPdf.js b/packages/examination/src/utils/exportPdf.js new file mode 100644 index 0000000..11ef571 --- /dev/null +++ b/packages/examination/src/utils/exportPdf.js @@ -0,0 +1,74 @@ +import html2canvas from 'html2canvas'; +import { jsPDF } from 'jspdf'; +export const downPdf = (title,className) => { + return new Promise((resolve, reject) => { + window.scrollTo(0,1); + // 要导出pdf的节点 + var elements = document.getElementsByClassName(className); // 需要转换的页面节点 + var imgMap = new Map(); + for (var index = 0; index < elements.length; index++) { + var mapIndex = index; + html2canvas(elements[index], { + useCORS: true, // 是否允许网页中img元素跨域,这个设置需要img元素支持及服务器支持 + scale: 1, // 这个影响生成图片的清晰度 + // background: "#F5F5F5" //背景 + }).then((canvas) => { + var img = new Image(); + img.setAttribute("crossOrigin", "anonymous"); + img.width = canvas.width; + img.height = canvas.height; + img.src = canvas.toDataURL('image/jpeg', 1.0); + imgMap.set(mapIndex, img); // 按照顺序保存图片 + if(imgMap.size == elements.length) { // 当所有图片都转化完毕,则进行保存操作 + var pdf = new jsPDF('', 'pt', 'a4'); + for(var i = 0; i < imgMap.size; i++) { + // canvas尺寸 + var canvasWidth = imgMap.get(i).width; + var canvasHeight = imgMap.get(i).height; + var pageData = imgMap.get(i).src; + addOneImg(pdf, pageData, canvasWidth, canvasHeight); + if(i < imgMap.size-1) { + pdf.addPage(); // 如果还有图片未添加到pdf,则增加一个页面 + } + } + // 所有图片添加完毕,保存 + pdf.save(title+".pdf"); + } + }); + }; + return true; + }); +} + +// 递归的方式对页面进行截取并添加到pdf中 +var addPages = function (pdf, pageData, position, imgWidth, imgHeight, canvasHeight, pageHeight, a4Height, margin) { + // pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight) + pdf.addImage(pageData, 'JPEG', margin + 10, position + margin, imgWidth - 2 * margin, imgHeight - 2 * margin); // **改动标注 2** + // 减去已经绘制的区域 + canvasHeight -= pageHeight; + position -= a4Height; + // 当还有内容未生成pdf,则新加页面,并添加图片 + if (canvasHeight > 0) { + pdf.addPage(); + addPages(pdf, pageData, position, imgWidth, imgHeight, canvasHeight, pageHeight, a4Height, margin); + } +} +// img转化为pdf并保存 +var addOneImg = function (pdf, pageData, canvasWidth, canvasHeight) { + + // a4纸的尺寸[595.28,841.89] + var a4Width = 595.28; + var a4Height = 841.89; + + // 设置页面四周的间距,单位是毫米,10mm是默认间距 // **改动标注 4** + var margin = 10; + + //html页面生成的canvas在pdf中图片的宽高 + var imgWidth = a4Width - 2 * margin; // 减去左右的间距 // **改动标注 5** + var imgHeight = a4Width / canvasWidth * canvasHeight; + + //一页pdf显示html页面生成的canvas高度; + var pageHeight = canvasWidth / a4Width * a4Height; + + addPages(pdf, pageData, 0, imgWidth, imgHeight, canvasHeight, pageHeight, a4Height, margin); // **改动标注 6** +} diff --git a/packages/examination/src/views/configuration_manage/announcement.tsx b/packages/examination/src/views/configuration_manage/announcement.tsx deleted file mode 100644 index 085da76..0000000 --- a/packages/examination/src/views/configuration_manage/announcement.tsx +++ /dev/null @@ -1,181 +0,0 @@ -import React, { Component } from "react"; -import { Button, Empty, Modal, notification, Popconfirm } from "antd"; -import { getSellerId } from 'utils/storage'; -import { delNotice, disable, enable, getNoticeList } from "api/configuration/announcement"; -import AnnounceCreate from "./compoents/announceCreate"; - -interface States { - noticeData: any - visible: boolean - title: string - current: any -} - -class Announcement extends Component { - type = 1; // 单店 - constructor(props: any) { - super(props); - this.state = { - noticeData: undefined, - visible: false, - title: '新增公告', - current: {} - } - } - - componentDidMount() { - this.getList() - } - - getList() { - getNoticeList(getSellerId(), this.type).then((res) => { - if(res.data){ - this.setState({ noticeData: res.data[0] }) - }else{ - this.setState({ noticeData: undefined }) - } - }).catch(() => { }) - } - - getStatusText(status: number): string { - if (status === 1) { - return "启用"; - } else if (status === 0) { - return "禁用"; - } else { - return ''; - } - } - - handelCreate() { - this.setState({ visible: true }) - } - - handelUpdate(item: any) { - this.setState({ - visible: true, - title: '编辑公告', - current: item - }) - } - - handleEnable(item: any) { - enable(getSellerId(), this.type, item.id, 1).then((res) => { - notification.success({ - message: '成功', - description: '启用成功' - }) - this.getList() - }).catch(() => { }) - } - - handleDisable(item: any) { - disable(getSellerId(), this.type, item.id, 0).then((res) => { - notification.success({ - message: '成功', - description: '禁用成功' - }); - this.getList() - }).catch(() => { }) - } - - handleDel(item: any) { - delNotice(getSellerId(), this.type, item.id).then(res => { - notification.success({ - message: '成功', - description: '删除公告成功', - }); - this.getList() - }).catch(() => { }) - } - - render() { - const { noticeData, visible, title, current } = this.state; - const handleCancel = () => { - this.setState({ visible: false }) - }; - - return ( -
-
公告管理
- { - noticeData ? null : - - } - - - - - - - - - - { - noticeData ? - - - - - - - : - - - - } - -
公司标题名称内容发布时间状态操作
{noticeData.name}{noticeData.statusAt ? new Date(noticeData.statusAt * 1000).toLocaleString() : '-----'}{this.getStatusText(noticeData.status)} - { - noticeData.status === 0 ? - this.handleEnable(noticeData)} - okText="确定" - cancelText="取消"> - - : null - } - { - noticeData.status === 1 ? - this.handleDisable(noticeData)} - okText="确定" - cancelText="取消"> - - : null - } - { - noticeData.status === 0 ? - : null - } - this.handleDel(noticeData)} - okText="确定" - cancelText="取消"> - - -
- -
- - - handleCancel()} - onData={() => this.getList()} /> - -
- ) - } -} - -export default Announcement; \ No newline at end of file diff --git a/packages/examination/src/views/configuration_manage/compoents/announceCreate.tsx b/packages/examination/src/views/configuration_manage/compoents/announceCreate.tsx deleted file mode 100644 index 7ee2624..0000000 --- a/packages/examination/src/views/configuration_manage/compoents/announceCreate.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import React, { Component } from "react"; -import { Button, Form, Input, notification } from "antd"; -import { getSellerId } from 'utils/storage'; -import { addNotice } from "api/configuration/announcement"; -import { FormInstance } from "antd/lib/form"; -import ReactQillWrap from 'components/reactQuill'; - -interface Props { - current?: any - onCancel: () => void - onData: () => void -} -interface States { - content: string -} - -class AnnounceCreate extends Component{ - type = 1; - reactQuillRef: any = null; - form = React.createRef() - constructor(props: Props) { - super(props); - this.state = { - content: '' - } - } - - componentDidMount() { - const currentItem = this.props.current; - if (currentItem) { - this.form.current?.setFieldsValue({ - name: currentItem.name, - content: currentItem.content - }) - } - } - - handleChange(value: string) { - this.setState({ content: value }) - } - - render() { - const layout = { - labelCol: { span: 3 }, - wrapperCol: { span: 21 }, - }; - const tailLayout = { - wrapperCol: { offset: 20, span: 4 }, - }; - - const onFinish = (values: any) => { - let msg: string; - const obj = { targetId: getSellerId(), type: this.type, ...values } - if (this.props.current) { - msg = '更新公告成功' - } else { - msg = '添加公告成功' - } - addNotice(getSellerId(), this.type, obj).then(res => { - notification.success({ - message:'成功', - description: msg - }) - this.props.onCancel(); - this.props.onData(); - }).catch(() => { }) - } - - return ( -
- - - - - - - - - { - this.props.current ? - : - - } - -
- ) - } -} - -export default AnnounceCreate; \ No newline at end of file diff --git a/packages/examination/src/views/configuration_manage/gold.tsx b/packages/examination/src/views/configuration_manage/gold.tsx deleted file mode 100644 index 004240c..0000000 --- a/packages/examination/src/views/configuration_manage/gold.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React, { Component } from 'react'; -import { Form, Input, Button, notification } from 'antd'; -import { getSellerId } from 'utils/storage'; -import { getCoin, addCoin } from 'api/configuration/gold'; -class Gold extends Component { - componentDidMount() { - this.getCoin() - } - //金币配置回显 - getCoin() { - getCoin(getSellerId()).then(res => { - const [form] = Form.useForm(); - const { coinCredit, coinMoney } = res.data; - form.setFieldsValue({ - coinCredit, - coinMoney - }) - }) - } - render() { - const layout = { - labelCol: { span: 3 }, - wrapperCol: { span: 21 }, - }; - const onFinish = (values: object) => { - console.log(JSON.parse(JSON.stringify(values))) - const { coinCredit } = JSON.parse(JSON.stringify(values)) - addCoin(getSellerId(), coinCredit).then((res: any) => { - notification.open({ - message: '成功', - description: '登录成功', - type: 'success' - }) - }).catch(() => { }) - }; - const onFinishFailed = (errorInfo: object) => { - console.log('Failed:', errorInfo); - }; - return ( -
-
金币规则配置
-
-

1、金币兑换积分规则

- - - -

2、金币提现规则

- - - - - - -
-
- ) - } -} - -export default Gold; diff --git a/packages/examination/src/views/exam-online/compoents/ExamDetailAnalysisPage.tsx b/packages/examination/src/views/exam-online/compoents/ExamDetailAnalysisPage.tsx index c9c05eb..1e3a12a 100644 --- a/packages/examination/src/views/exam-online/compoents/ExamDetailAnalysisPage.tsx +++ b/packages/examination/src/views/exam-online/compoents/ExamDetailAnalysisPage.tsx @@ -224,6 +224,8 @@ const ExamDetailAnalysisPage: React.FC = () => { = ({ history }) => {
@@ -140,6 +142,8 @@ const ExamStatisticsPage: React.FC = ({ history }) => {
diff --git a/packages/examination/src/views/exam-online/compoents/ExamListPage.tsx b/packages/examination/src/views/exam-online/compoents/ExamListPage.tsx index c710931..f21dc6f 100644 --- a/packages/examination/src/views/exam-online/compoents/ExamListPage.tsx +++ b/packages/examination/src/views/exam-online/compoents/ExamListPage.tsx @@ -442,6 +442,8 @@ const ExamListPage = ({ history }: { history: any }) => { dataSource={currentPageExamList} rowKey="examId" pagination={pagination} + bordered={true} + size={'small'} onChange={handleTableChange} /> = ({history}) => { columns={columns} dataSource={tableData} pagination={pagination} + bordered={true} + size={'small'} onChange={handleTableChange} /> diff --git a/packages/examination/src/views/exam-online/compoents/ExamStatisticsPage.tsx b/packages/examination/src/views/exam-online/compoents/ExamStatisticsPage.tsx index 6d3ef80..8389071 100644 --- a/packages/examination/src/views/exam-online/compoents/ExamStatisticsPage.tsx +++ b/packages/examination/src/views/exam-online/compoents/ExamStatisticsPage.tsx @@ -264,7 +264,7 @@ const Dashboard: React.FC = () => { )} > {/* 考试情况表格 */} -
+
{/* 试卷情况环状图 */} diff --git a/packages/examination/src/views/examPaper/examPaperAdd.tsx b/packages/examination/src/views/examPaper/examPaperAdd.tsx index d3944e9..bdf6602 100644 --- a/packages/examination/src/views/examPaper/examPaperAdd.tsx +++ b/packages/examination/src/views/examPaper/examPaperAdd.tsx @@ -542,6 +542,8 @@ class ExamPaperAdd extends Component {
@@ -589,6 +591,8 @@ class ExamPaperAdd extends Component {
{ dataSource={list} columns={columns} rowKey="id" + bordered={true} + size={'small'} loading={loading} rowSelection={{ selectedRowKeys: selectedRowKeys, diff --git a/packages/examination/src/views/header/index.tsx b/packages/examination/src/views/header/index.tsx index 735ded9..4f3d0e0 100644 --- a/packages/examination/src/views/header/index.tsx +++ b/packages/examination/src/views/header/index.tsx @@ -47,21 +47,14 @@ class Header extends React.Component { return (
-
- { - React.createElement(this.state.collapsed ? MenuUnfoldOutlined : MenuFoldOutlined, { - className: 'trigger', - onClick: this.toggle, - }) - } -
+
- ) diff --git a/packages/examination/src/views/login/index.tsx b/packages/examination/src/views/login/index.tsx index 7f95a03..7b8d388 100644 --- a/packages/examination/src/views/login/index.tsx +++ b/packages/examination/src/views/login/index.tsx @@ -1,5 +1,5 @@ import React from 'react' -import { Form, Input, Button, notification } from 'antd'; +import {Form, Input, Button, notification, Checkbox} from 'antd'; import { UserOutlined, LockFilled } from '@ant-design/icons'; import { loginName } from 'api/login'; import { setToken } from 'api/token'; @@ -21,29 +21,10 @@ class Login extends React.Component { // 表单提交 const onFinish = (values: any) => { - // console.log('Success:', values); loginName(values).then((res) => { let status = res.data.status; if (res.data.token) { - // 结算主体 - let lb = res.data.lb; - if (!lb) { - lb = ""; - } - //商户信息 - let si = res.data.si; - if (!si) { - si = ""; - } - let bs = res.data.bs; - if (!bs) { - bs = ""; - } setToken(res.data.token); - localStorage.setItem("role", res.data.role); - localStorage.setItem("lb", lb); - localStorage.setItem("si", si); - localStorage.setItem("bs", bs); notification.open({ message: '成功', description: '登录成功', @@ -69,46 +50,38 @@ class Login extends React.Component { return (
- {/* */} 某某某 - 商户中心 + 商户平台
-

Hi,欢迎登录商户管理平台!

+

测试登录

- - } /> - - - } /> + rules={[{ required: true, message: 'userName不能为空' }]}> + } /> - } /> + rules={[{ required: true, message: '8000626885不能为空' }]}> + } /> - {/* - 记住 - */} + { + 记住 + } @@ -118,8 +91,8 @@ class Login extends React.Component {
- Copyright © 1994-2022 南京xxxx有限公司 All Rights Reserved.
- 备案号:苏ICP备199xxxx号 联系方式:025-xxxxxx + Copyright © 1994-2022 xxxx有限公司 All Rights Reserved.
+ 备案号:*ICP备199xxxx号 联系方式:025-xxxxxx
) diff --git a/packages/examination/src/views/orderManage/coupon.tsx b/packages/examination/src/views/orderManage/coupon.tsx index c012bbb..aca2a60 100644 --- a/packages/examination/src/views/orderManage/coupon.tsx +++ b/packages/examination/src/views/orderManage/coupon.tsx @@ -191,8 +191,10 @@ class Coupon extends Component{
{
{ dataSource={list} columns={columns} rowKey="id" + bordered={true} + size={'small'} loading={loading} rowSelection={{ selectedRowKeys: selectedRowKeys, diff --git a/packages/examination/src/views/slider/index.js b/packages/examination/src/views/slider/index.js index f1767ff..19445bd 100644 --- a/packages/examination/src/views/slider/index.js +++ b/packages/examination/src/views/slider/index.js @@ -28,14 +28,12 @@ export const findTitleByKey = (key) => { class Slider extends React.Component { constructor(props) { super(props); - console.log('props=====', props) this.state = { openKeys: [], selectedKeys: [] } } componentDidMount() { - // console.log(this.props) const { pathname } = this.props.location if (pathname) { @@ -81,29 +79,8 @@ class Slider extends React.Component { handleMenu = (e) => { this.setState({ selectedKeys: [e.key] }) - // console.log('menu======', e) } - // onOpenChange = (openKeys) => { - // // console.log('change=====', openKeys) - // if (openKeys.length === 0 || openKeys.length === 1) { - // this.setState({ - // openKeys - // }) - // return - // } - // - // //最新展开的菜单 - // const latestOpenKey = openKeys[openKeys.length - 1] - // if (latestOpenKey.includes(openKeys[0])) { - // this.setState({ openKeys }) - // } else { - // this.setState({ - // openKeys: [latestOpenKey] - // }) - // } - // } - onOpenChange = (openKeys) => { // 这里只控制展开的菜单项 const latestOpenKey = openKeys[openKeys.length - 1]; @@ -124,7 +101,6 @@ class Slider extends React.Component { const defaultProps = this.props.collapsed ? {} : { openKeys }; // 代替openKeys 解决切换菜单时二级菜单收缩时不跟随问题 return (
- {/*

{openKeys} - {selectedKeys}

*/} { this.props.collapsed ? diff --git a/packages/examination/src/views/slider/menu.tsx b/packages/examination/src/views/slider/menu.tsx index 92c0943..60225c9 100644 --- a/packages/examination/src/views/slider/menu.tsx +++ b/packages/examination/src/views/slider/menu.tsx @@ -16,28 +16,13 @@ const menuList = [ }, { title: '服务统计', - key: 'demoList2', + key: 'serviceStatistics', icon: 'icon', } ] } ] }, - { - title: '线上考试', - key: 'exam-online', - icon: 'icon-peizhi', - subs: [ - { - title: '考试安排', - key: 'exam-schedule', - }, - { - title: '考试统计', - key: 'exam-statistics', - } - ] - }, { title: '题库管理', key: 'question', @@ -59,86 +44,22 @@ const menuList = [ key: 'examPaperList', } ] + }, + { + title: '线上考试', + key: 'exam-online', + icon: 'icon-peizhi', + subs: [ + { + title: '考试安排', + key: 'exam-schedule', + }, + { + title: '考试统计', + key: 'exam-statistics', + } + ] } - // { - // title: 'demo', - // key: 'demo', - // icon: 'icon-peizhi', - // subs: [ - // { - // title: 'list', - // key: 'demoList', - // } - // ] - // }, - // { - // title: '订单管理', - // key: 'order_mag', - // icon: 'icon-gouwucheman', - // subs: [ - // { - // title: '股东活动订单', - // key: 'promotion', - // }, - // { - // title: '优惠券订单', - // key: 'couponOrder', - // } - // ] - // }, - // { - // title: '配置管理', - // key: 'configuration_mag', - // icon: 'icon-peizhi', - // subs: [ - // { - // title: '金币配置', - // key: 'gold', - // }, - // { - // title: '公告管理', - // key: 'announcement', - // } - // ] - // }, - // { - // title: '积分会员管理', - // key: 'integralmember_manage', - // icon: 'icon-jifen', - // subs: [ - // { - // title: '积分规则', - // key: 'integralRule', - // } - // ] - // }, - // { - // title: '小店管理', - // key: 'shop_manage', - // icon: 'icon-shop', - // subs: [ - // { - // title: '店铺管理', - // key: 'store', - // } - // ] - // }, - // { - // title: '提现管理', - // key: 'withdrawal_manage', - // icon: 'icon-withdrawal', - // subs: [ - // { - // title: '提现规则', - // key: 'store', - // } - // ] - // }, - // { - // title: '首页', - // key: 'home', - // icon: 'icon-home' - // } ] export default menuList; \ No newline at end of file diff --git a/packages/examination/src/views/statistical/customerRetention.tsx b/packages/examination/src/views/statistical/customerRetention.tsx index cae2abb..bd6973c 100644 --- a/packages/examination/src/views/statistical/customerRetention.tsx +++ b/packages/examination/src/views/statistical/customerRetention.tsx @@ -3,6 +3,9 @@ import {Table, Button, Spin, Space, Modal, Form, Upload, Image, notification} fr import TextArea from "antd/es/input/TextArea"; import {getCustomerRetPage, saveCustomerRet} from "../../api/statistical"; import {serverUrl} from "../../api/axios"; +import { + getToken, +} from '../../api/token' type NotificationPlacement = 'top' | 'bottom' | 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight'; type NotificationType = 'success' | 'info' | 'warning' | 'error'; @@ -132,16 +135,14 @@ const CustomerRetention: React.FC = ({ customer }) => { const showModal2 = (fileUid: string) => { console.log(fileUid) - setFileUrl('./ex/file/download?fileName=' + fileUid); + setFileUrl('./ex/file/download?fileName=' + fileUid + '&token=' + getToken()); setIsModalOpen2(true); }; const handleOk2 = () => { - debugger const url = serverUrl + fileUrl; const link = document.createElement('a'); link.href = url; - // link.download = 'file.png'; link.click(); setFileUrl(null); setIsModalOpen2(false); @@ -161,7 +162,6 @@ const CustomerRetention: React.FC = ({ customer }) => { // 条数切换 const changePage = (current: number, pageSize?: number) => { - debugger const query = { page: current, num: pageSize || 20 } setTimeout(() => { setQuery(query); @@ -223,6 +223,9 @@ const CustomerRetention: React.FC = ({ customer }) => { const response = await fetch('/ex/file/upload', { method: 'POST', body: formData, + headers: { + 'token': getToken(), + }, }); if (response.ok) { const res = await response.json(); @@ -240,7 +243,7 @@ const CustomerRetention: React.FC = ({ customer }) => { }; return ( -
+
{contextHolder}
@@ -255,16 +258,20 @@ const CustomerRetention: React.FC = ({ customer }) => { columns={columns} rowKey="key" loading={loading} + bordered={true} + size={'small'} pagination={{ total: total || 0, current: query?.page || 1, - pageSize: query?.num || 10, + pageSize: query?.num || 20, showQuickJumper: true, showSizeChanger: true, showTotal: total => `共 ${total} 条`, onShowSizeChange: selectChange, onChange: changePage }} + scroll={{ y: 500 }} + sticky /> )}
diff --git a/packages/examination/src/views/statistical/detail.tsx b/packages/examination/src/views/statistical/detail.tsx index 192c4b1..28448cf 100644 --- a/packages/examination/src/views/statistical/detail.tsx +++ b/packages/examination/src/views/statistical/detail.tsx @@ -52,7 +52,7 @@ const App: React.FC = () => { { key: '7', label: '一企一档', - children: , + children: , }, { key: '8', @@ -61,7 +61,7 @@ const App: React.FC = () => { }, ]; - return ; + return ; }; export default App; diff --git a/packages/examination/src/views/statistical/enterpriseFile.tsx b/packages/examination/src/views/statistical/enterpriseFile.tsx index 2ce2e01..78c52a5 100644 --- a/packages/examination/src/views/statistical/enterpriseFile.tsx +++ b/packages/examination/src/views/statistical/enterpriseFile.tsx @@ -1,7 +1,8 @@ import React, {useState, useEffect} from 'react'; -import {Table, Button, Spin, Descriptions} from 'antd'; -import html2canvas from 'html2canvas'; -import { jsPDF } from 'jspdf'; +import {Table, Button, Spin, Descriptions, Divider, message, Input} from 'antd'; +import {getEnterpriseArchives} from 'api/statistical' + +import {downPdf} from 'utils/exportPdf'; interface Enterprise { key: string; @@ -12,142 +13,656 @@ interface Enterprise { phone: string; } -const EnterpriseFile: React.FC = () => { +interface CustomerRetentionProps { + customer: any; +} + +interface Item { + key: string; + label: string; + children: any; + span?: number; + policyCoverageData?: any; +} + +interface PolicyItem { + baseData: any, + policyCoverageList: any, + hivePolicyInnerCoInsurerList: any +} + +interface HiveClaimStatistics { + key: string; + title: string; + children: any; + span?: number; +} + +interface PolicyServiceItem { + policyNumber: string, + accidentPreventionList: any, + riskList: any, + hazardInvestigationList: any, +} + + +const EnterpriseFile: React.FC = ({ customer }) => { // State to store data and loading state const [data, setData] = useState([]); const [loading, setLoading] = useState(false); + const [items, setItems] = useState([]); + const [items2, setItems2] = useState([]); + const [items3, setItems3] = useState([]); + const [items4, setItems4] = useState([]); + const [downloadStat, setDownloadStat] = useState(false); + + const [testVal, setTestVal] = useState(0); // Simulate data fetching on component mount useEffect(() => { setLoading(true); - setTimeout(() => { - // Simulated response data - const fetchedData: Enterprise[] = [ - { key: '1', customerNo: '001', customerName: 'Company A', industry: 'Technology', contacts: 'John Doe', phone: '123-456-789' }, - { key: '2', customerNo: '002', customerName: 'Company B', industry: 'Finance', contacts: 'Jane Smith', phone: '987-654-321' }, - // Add more data as needed - ]; - setData(fetchedData); + message.open({ + type: 'loading', + content: '数据加载中..', + duration: 0, + }); + getEnterpriseArchives({ customerId: '90020242601'}).then(res => { + // getEnterpriseArchives({ customerId: customer.customerId}).then(res => { + var baseData = [ + { + key: 'customerNo', + label: '客户编号', + children: res.data.customerNo + }, + { + key: 'type', + label: '企业类型', + children: res.data.typeName + }, + { + key: 'socialCreditCode', + label: '统一社会信用代码', + children: res.data.socialCreditCode + }, + { + key: 'legalPerson', + label: '法定代表人', + span: 2, + children: res.data.legalPerson + }, + { + key: 'contacts', + label: '联系人', + children: res.data.contacts + }, + { + key: 'email', + label: '电子邮箱', + children: res.data.email + }, + { + key: 'contactsPhone', + label: '联系电话', + children: res.data.contactsPhone + }, + { + key: 'typePname', + label: '行业分类', + children: res.data.typePname + }, + { + key: 'businessScope', + label: '许可范围', + span: 2, + children: res.data.businessScope + }, + { + key: 'orgRegistrationAddress', + label: '注册地址', + children: res.data.orgRegistrationAddress + }]; + setItems(baseData); + debugger + let policyArr = []; + for (var index = 0; index < res.data.policyList.length; index ++) { + let policyCoverageList = []; + for (var cIndex = 0; cIndex < res.data.policyList[index].policyCoverageList.length; cIndex ++) { + policyCoverageList.push(res.data.policyList[index].policyCoverageList[cIndex]) + } + let hivePolicyInnerCoInsurerList = []; + for (var hIndex = 0; hIndex < res.data.policyList[index].hivePolicyInnerCoInsurerList.length; hIndex ++) { + hivePolicyInnerCoInsurerList.push(res.data.policyList[index].hivePolicyInnerCoInsurerList[hIndex]) + } + policyArr.push({ + baseData:[{ + key: 'policyNumber', + label: '保单号', + children: res.data.policyList[index].policyNumber + }, + { + key: 'insurCustomerName', + label: '投保人', + children: res.data.policyList[index].insurCustomerName + }, + { + key: 'customerName', + label: '被保人', + children: res.data.policyList[index].customerName + }, + { + key: 'duePremium', + label: '保费', + span: 2, + children: res.data.policyList[index].duePremium + }, + { + key: 'startDate', + label: '起保日期', + children: res.data.policyList[index].startDate + }, + { + key: 'doneDate', + label: '终保日期', + children: res.data.policyList[index].doneDate + }, + { + key: 'policyStatusName', + label: '保单状态', + children: res.data.policyList[index].policyStatusName + }, + { + key: 'premiumRate', + label: '保单费率', + children: res.data.policyList[index].premiumRate + }, + { + key: 'sumInsured', + label: '累计责任限额', + children:res.data.policyList[index].sumInsured + }], + policyCoverageList: policyCoverageList, + hivePolicyInnerCoInsurerList: hivePolicyInnerCoInsurerList + }); + } + setItems2(policyArr); + + let hiveClaimArr = []; + for (var index2 = 0; index2 < res.data.hiveClaimStatisticsList.length; index2 ++) { + const hiveClaim = [ + { + title: '保单号', + key: 'policyno', + children: res.data.hiveClaimStatisticsList[index2].policyno + }, + { + title: '报案时间', + key: 'reporttime', + children: res.data.hiveClaimStatisticsList[index2].reporttime + }, + { + title: '立案时间', + key: 'claimtime', + children: res.data.hiveClaimStatisticsList[index2].claimtime + }, + { + title: '任务节点', + key: 'tasktype', + children: res.data.hiveClaimStatisticsList[index2].tasktype + }, + { + title: '估损金额', + key: 'claimloss', + children: res.data.hiveClaimStatisticsList[index2].claimloss + }, + { + title: '定损总金额', + key: 'sumlossapproval', + children: res.data.hiveClaimStatisticsList[index2].sumlossapproval + }, + { + title: '从业人员人身伤亡定损金额', + key: 'peoplelossapproval', + children: res.data.hiveClaimStatisticsList[index2].peoplelossapproval + }, + { + title: '医疗救护费用定损金额', + key: 'medicsumapprv', + children: res.data.hiveClaimStatisticsList[index2].medicsumapprv + }, + { + title: '第三者人身伤亡定损金额', + key: 'ossapproval', + children: res.data.hiveClaimStatisticsList[index2].ossapproval + }, + { + title: '事故鉴定费用定损金额', + key: 'accidentsumaprv', + children: res.data.hiveClaimStatisticsList[index2].accidentsumaprv + }, + { + title: '第三者财产损失定损金额', + key: 'lossapproval', + children: res.data.hiveClaimStatisticsList[index2].lossapproval + }, + { + title: '法律诉讼费用定损金额', + key: 'lawsumapprv', + children: res.data.hiveClaimStatisticsList[index2].lawsumapprv + }, + { + title: '事故抢险救援费用定损金额', + key: 'accidentrssumapprv', + children: res.data.hiveClaimStatisticsList[index2].accidentrssumapprv + }, + { + title: '其他费用定损金额', + key: 'othersumapprv', + children: res.data.hiveClaimStatisticsList[index2].othersumapprv + }, + { + title: '赔付总金额', + key: 'totalamtcharg', + children: res.data.hiveClaimStatisticsList[index2].totalamtcharg + }, + { + title: '赔付时间', + key: 'bankpaytime', + children: res.data.hiveClaimStatisticsList[index2].bankpaytime + }, + { + title: '决案时间', + key: 'endcasedate', + children: res.data.hiveClaimStatisticsList[index2].endcasedate + }, + { + title: '从业人员人身伤亡赔付金额', + key: 'peoplemdiesumcharg', + children: res.data.hiveClaimStatisticsList[index2].peoplemdiesumcharg + }, + { + title: '医疗救护费用赔付金额', + key: 'medicsumcharg', + children: res.data.hiveClaimStatisticsList[index2].medicsumcharg + }, + { + title: '第三者人身伤亡赔付金额', + key: 'tempcharg', + children: res.data.hiveClaimStatisticsList[index2].lossinjurycharg + }, + { + title: '事故鉴定费用赔付金额', + key: 'accidentrssumcharg', + children: res.data.hiveClaimStatisticsList[index2].accidentrssumcharg + }, + { + title: '第三者财产损失赔付金额', + key: 'losscharg', + children: res.data.hiveClaimStatisticsList[index2].losscharg + }, + { + title: '法律诉讼费用赔付金额', + key: 'lawsumcharg', + children: res.data.hiveClaimStatisticsList[index2].lawsumcharg + }, + { + title: '事故抢险救援费用赔付金额', + key: 'hiveClaim', + children: res.data.hiveClaimStatisticsList[index2].hiveClaim + }, + { + title: '其他费用赔付金额', + key: 'othersumcharg', + children: res.data.hiveClaimStatisticsList[index2].othersumcharg + } + ]; + hiveClaimArr.push(hiveClaim); + } + setItems3(hiveClaimArr); + + let policyServiceArr = []; + for (var index3 = 0; index3 < res.data.serviceStatisticsList.length; index3 ++) { + let accidentPreventionList = []; + for (var aIndex = 0; aIndex < res.data.serviceStatisticsList[index3].accidentPreventionList.length; aIndex ++) { + accidentPreventionList.push(res.data.serviceStatisticsList[index3].accidentPreventionList[aIndex]) + } + let riskList = []; + for (var rIndex = 0; rIndex < res.data.serviceStatisticsList[index3].riskList.length; rIndex ++) { + riskList.push(res.data.serviceStatisticsList[index3].riskList[rIndex]) + } + let hazardInvestigationList = []; + for (var sIndex = 0; sIndex < res.data.serviceStatisticsList[index3].hazardInvestigationList.length; sIndex ++) { + hazardInvestigationList.push(res.data.serviceStatisticsList[index3].hazardInvestigationList[sIndex]) + } + policyServiceArr.push({ + policyNumber: res.data.hiveClaimStatisticsList[index3].policyNumber, + accidentPreventionList: accidentPreventionList, + riskList: riskList, + hazardInvestigationList: hazardInvestigationList + }) + } + setItems4(policyServiceArr); + + message.destroy(); setLoading(false); - }, 1000); // Simulate a delay of 2 seconds + }).catch(() => {}) }, []); - const columns = [ + const columnsPolicyCoverage = [ { - title: '客户编号', - dataIndex: 'customerNo', - key: 'customerNo', + title: '条款代码', + dataIndex: 'clausecode', + key: 'clausecode', }, { - title: '企业名称', - dataIndex: 'customerName', - key: 'customerName', + title: '条款类型', + dataIndex: 'coverageType', + key: 'coverageType', }, { - title: '行业分类', - dataIndex: 'industry', - key: 'industry', + title: '条款名称', + dataIndex: 'productElementName', + key: 'productElementName', }, { - title: '企业联系人', - dataIndex: 'contacts', - key: 'contacts', + title: '责任限额(元)', + dataIndex: 'sumInsured', + key: 'sumInsured', + } + ]; + + const columnsHivePolicyInnerCoInsurer = [ + { + title: '联保机构', + dataIndex: 'innerCoOrgCode', + key: 'innerCoOrgCode', }, { - title: '联系电话', - dataIndex: 'phone', - key: 'phone', + title: '联保份额', + dataIndex: 'shareRate', + key: 'shareRate', }, ]; - const items = [ + const columnsAccidentPrevention = [ + { + title: '服务时间', + dataIndex: 'completedAt', + key: 'completedAt', + }, { - key: '1', - label: 'UserName', - children: 'Zhou Maomao', + title: '服务名称', + dataIndex: 'serviceName', + key: 'serviceName', }, { - key: '2', - label: 'Telephone', - children: '1810000000', + title: '被服务对象', + dataIndex: 'serviceObjectName', + key: 'serviceObjectName', }, { - key: '3', - label: 'Live', - children: 'Hangzhou, Zhejiang', + title: '服务分类', + dataIndex: 'serviceRange', + key: 'serviceRange', }, { - key: '4', - label: 'Address', - span: 2, - children: 'No. 18, Wantang Road, Xihu District, Hangzhou, Zhejiang, China', + title: '服务机构', + dataIndex: 'executedOrganName', + key: 'executedOrganName', }, { - key: '5', - label: 'Remark', - children: 'empty', + title: '服务报告', + dataIndex: 'uploadStatus', + key: 'uploadStatus', }, ]; + const columnsRisk = [ + { + title: '风险编号', + dataIndex: 'riskNumber', + key: 'riskNumber', + }, + { + title: '风险名称', + dataIndex: 'riskName', + key: 'riskName', + }, + { + title: '风险描述', + dataIndex: 'riskontent', + key: 'riskontent', + }, + { + title: '场所/部位', + dataIndex: 'discoveredAddress', + key: 'discoveredAddress', + }, + { + title: '风险等级', + dataIndex: 'riskGrade', + key: 'riskGrade', + }, + { + title: '管控状态', + dataIndex: 'status', + key: 'status', + }, + { + title: '发现时间', + dataIndex: 'discoveredAt', + key: 'discoveredAt', + }, + ]; + + const columnsHazardInvestigation = [ + { + title: '隐患编号', + dataIndex: 'hiddenNumber', + key: 'hiddenNumber', + }, + { + title: '隐患描述', + dataIndex: 'description', + key: 'description', + }, + { + title: '隐患类型', + dataIndex: 'hiddenDangerType', + key: 'hiddenDangerType', + }, + { + title: '隐患分类', + dataIndex: 'dangerTypeName', + key: 'dangerTypeName', + }, + { + title: '隐患等级', + dataIndex: 'riskGrade', + key: 'riskGrade', + }, + { + title: '发现时间', + dataIndex: 'discoveredAt', + key: 'discoveredAt', + }, + { + title: '整改状态', + dataIndex: 'correctionStatus', + key: 'correctionStatus', + }, + ]; const handleCapture = () => { - const element = document.querySelector('.main-customer-htm'); - if (element) { - html2canvas(element as HTMLElement, { - useCORS: true, // Allow CORS for cross-origin resources - }).then((canvas) => { - // Convert the canvas to image data - const imgData = canvas.toDataURL('image/png'); - - // Create a new jsPDF instance - const pdf = new jsPDF(); - - // Add the image to the PDF (at position (10, 10) with size (pdf width - 20, auto)) - pdf.addImage(imgData, 'PNG', 10, 10, pdf.internal.pageSize.width - 20, canvas.height * (pdf.internal.pageSize.width - 20) / canvas.width); - - // Save the PDF - pdf.save('企业档案.pdf'); + setLoading(true); + setDownloadStat(true); + setTimeout(function () { + downPdf("企业档案", "main-customer-htm").then(() => { + console.log("PDF已经生成并保存!"); + }).catch((error: any) => { + console.error("生成PDF时发生错误: ", error); }); - } + setLoading(false); + setDownloadStat(false); + }, 7000); } - return ( -
-
- +
+
+
- - {items.map(item => ( - - {item.children} - +
+
企业档案
+
+ + {items.map(item => ( + + {item.children} + + ))} + +
+
+
保单信息
+
+ {items2.map(pItem => ( +
+
基本信息
+ + {pItem.baseData.map((item: { label: string, key: string, children: string }) => ( + + {item.children} + + ))} + +
责任条款
+
+
+
联保信息
+
+
+ + ))} +
+
+
理赔记录
+
+ {items3.map((item3, index) => ( +
+ {(index === 0 || item3[0].children !== items3[index - 1][0].children) && ( +
+ 保单号: {item3[0].children} +
+ )} +
基本信息
+ + {item3.slice(1, 4).map(tim => ( + + {tim.children} + + ))} + +
定损信息
+ + {item3.slice(5, 13).map(tim => ( + + {tim.children} + + ))} + +
赔付信息
+ + {item3.slice(14, 24).map(tim => ( + + {tim.children} + + ))} + +
+ ))} +
+
+
服务记录
+
+ {items4.map((item4, index) => ( +
+
保单号: {item4.policyNumber}
+
事故预防服务
+
+
+
风险辨识
+
+
+
隐患排查
+
+ ))} - -
- {loading ? ( - - ) : ( -
- )} -
-
-
-
+ ); diff --git a/packages/examination/src/views/statistical/list.tsx b/packages/examination/src/views/statistical/list.tsx index 187d0e6..c85940d 100644 --- a/packages/examination/src/views/statistical/list.tsx +++ b/packages/examination/src/views/statistical/list.tsx @@ -1,8 +1,8 @@ -import React from 'react' -import { Form, Input, Button, DatePicker, Table, Select} from 'antd' -import { getList } from 'api/statistical' +import React, {useState} from 'react' +import { Form, Input, Button, DatePicker, Table, Select, TreeSelect , TreeSelectProps, message} from 'antd' +import { getList, getOrganTree } from 'api/statistical' -import { dictionary } from "api/dict/index"; +import {getIndustryList} from "api/exam-online/index"; const { Option } = Select @@ -15,11 +15,8 @@ interface State { keyword: string, page: number, num: number, - affiliation?: string, - memberName?: string, - mobile?: number | string, - start?: number, - end?: number + insuranceId?: number | string, + typePid?: number | string, }, order_time?: string[], list: object[], @@ -27,8 +24,8 @@ interface State { loading: boolean, detailVisible: boolean, currentId: number, - affiliationDict: any, - manageTypeDict: any, + industryOptions: any, + organMap: any, showDetail: boolean } @@ -40,22 +37,23 @@ class Customer extends React.Component{ listQuery: { keyword: '', page: 1, - num: 20 + num: 20, + insuranceId: '', + typePid: '', }, list: [], total: 0, loading: false, detailVisible: false, currentId: 0, - affiliationDict: undefined, - manageTypeDict: undefined, + industryOptions: undefined, + organMap: undefined, showDetail: false } - // this.getListApi = this.getListApi.bind(this) } componentDidMount() { this.getListApi(this.state.listQuery) - this.getDict() + this.getInitData() } // 列表接口 getListApi(listQuery: object) { @@ -68,17 +66,24 @@ class Customer extends React.Component{ }) }).catch(() => { }) } - getDict() { - dictionary('affiliation').then((res) => { + getInitData() { + getOrganTree({}).then((res) => { if(res.data){ - this.setState({ affiliationDict: res.data }) + let options = (res.data.map((item: any) => ( { id: item.organId, pId: item.parentId, value: item.organId, title: item.organName }))); + this.setState({ organMap: options }) } - }) - dictionary('manage_type').then((res) => { - if(res.data){ - this.setState({ manageTypeDict: res.data }) + }); + const fetchData = async () => { + try { + // 获取监管行业列表 + const industryResponse = await getIndustryList(); + let industryOptions = (industryResponse.map((item: any) => ({ value: item.industry_id, label: item.industry_name }))); + this.setState({ industryOptions: industryOptions }) + } catch (error) { + console.error('数据加载失败:', error); } - }) + }; + fetchData(); } handleDetail(record: any) { @@ -93,9 +98,13 @@ class Customer extends React.Component{ render() { const onFinish = (values: object) => { + const form = this.formRef.current; + this.state.listQuery.keyword = form.getFieldValue('keyword'); + this.state.listQuery.insuranceId = form.getFieldValue('insuranceId'); + this.state.listQuery.typePid = form.getFieldValue('typePid'); const { customerNo, customerName, typePname, contacts, contactsPhone } = JSON.parse(JSON.stringify(values)) const _listQuery = { ...this.state.listQuery, customerNo, customerName, typePname, contacts, contactsPhone } - this.setState({ listQuery: _listQuery }) + this.setState({ listQuery: _listQuery }); this.getListApi(this.state.listQuery) } const onFinishFailed = (errorInfo: object) => { @@ -135,17 +144,29 @@ class Customer extends React.Component{ const onReset = () => { const form = this.formRef.current; - // const keyword = form.getFieldValue('keyword'); - // const affiliation = form.getFieldValue('affiliation'); - // const manageType = form.getFieldValue('manageType'); - // 清空字段值 form.resetFields(); }; - const { list, loading, affiliationDict, manageTypeDict } = this.state; + const onLoadData: TreeSelectProps['loadData'] = ({ id }) => + new Promise((resolve) => { + getOrganTree({organId: id}).then((res) => { + if(res.data){ + let options = (res.data.map((item: any) => ( { id: item.organId, pId: item.parentId, value: item.organId, title: item.organName }))); + let overOptions = this.state.organMap.concat(options); + this.setState({ organMap: overOptions }) + }else { + message.open({ + type: 'warning', + content: '暂无数据', + }); + } + resolve(undefined); + }); + }); + + const { list, loading, industryOptions, organMap } = this.state; return (
- {/* {JSON.stringify(this.state.listQuery)} */}
查询条件
{ - + name="insuranceId"> + + name="typePid"> @@ -193,10 +215,15 @@ class Customer extends React.Component{
`共 ${total} 条`, diff --git a/packages/examination/src/views/statistical/serviceStatistics.tsx b/packages/examination/src/views/statistical/serviceStatistics.tsx new file mode 100644 index 0000000..c34013d --- /dev/null +++ b/packages/examination/src/views/statistical/serviceStatistics.tsx @@ -0,0 +1,252 @@ +import React, { useState, useEffect } from 'react'; +import {Table, Button, Spin, Radio, DatePicker, Select, Form, Modal} from 'antd'; +import {getServiceStatPage} from "../../api/statistical"; +import type { RadioChangeEvent } from 'antd'; +import {dictionary} from "../../api/dict"; +import {serverUrl} from "../../api/axios"; + +interface Enterprise { + key: string; + policyNumber: string; + insuranceName: string; + serviceStatusName: string; + remarks: string; +} + +interface FormData { + num: number; + page: number; +} + +const App: React.FC = () => { + + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [query, setQuery] = useState(null); + const [total, setTotal] = useState(0); + const [dictData, setDictData] = useState([]); + const [form] = Form.useForm(); + + useEffect(() => { + const query = {page: 1, num: 20}; + setQuery(query); + getListApi({}, query.page, query.num) + dictionary('service_status').then((res) => { + if(res.data){ + const formattedData = res.data.map((item: { dictValue: any; dictKey: any; }) => ({ + label: item.dictValue, + value: item.dictKey + })); + setDictData(formattedData) + } + }) + }, []); + + const columns: any = [ + { + title: '序号', + dataIndex: 'key', + width: 50, + align: 'center', + render: (text: string, record: any, index: number) => index + 1 + }, + { + title: '保单号', + dataIndex: 'policyNumber', + align: 'center', + key: 'policyNumber', + }, + { + title: '归属中支', + dataIndex: 'insuranceName', + align: 'center', + key: 'insuranceName', + }, + { + title: '事故预防状态', + dataIndex: 'serviceStatusName', + align: 'center', + key: 'serviceStatusName', + }, + { + title: '备注', + dataIndex: 'remarks', + align: 'center', + key: 'remarks', + } + ]; + + // 多少每页 + const selectChange = (page: number, num: number) => { + const query = { page, num } + setQuery(query); + getListApi({}, query.page, query.num) + } + + // 条数切换 + const changePage = (current: number, pageSize?: number) => { + const query = { page: current, num: pageSize || 20 } + setTimeout(() => { + setQuery(query); + getListApi({}, query.page, query.num) + }, 0) + } + + // 列表接口 + const getListApi = (formData: object, page: number, num: number) => { + setLoading(true); + var formObj = JSON.parse(JSON.stringify(formData)); + getServiceStatPage(formObj, page, num).then(res => { + setData(res.data.records); + setTotal(res.data.total); + setLoading(false); + }).catch(() => { }) + } + + const onChange = (e: RadioChangeEvent) => { + console.log(`radio checked:${e.target.value}`); + }; + + const onReset = () => { + const form = formRef.current; + form.resetFields(); + }; + + const formRef = React.createRef(); + + const { RangePicker } = DatePicker; + + const onFinish = (values: object) => { + const form = formRef.current; + const safeQuery = query ?? {page: 1, num: 20}; + getListApi({ + dateFilter: form.getFieldValue('dateFilter'), + startDate: form.getFieldValue('selectDateTime') ? formatDate(form.getFieldValue('selectDateTime')[0]) : null, + doneDate: form.getFieldValue('selectDateTime') ? formatDate(form.getFieldValue('selectDateTime')[1]) : null, + serviceStatus: form.getFieldValue('serviceStatus') + }, safeQuery.page, safeQuery.num) + } + + const goExport = () => { + showModal(); + } + + const [isModalOpen, setIsModalOpen] = useState(false); + + const showModal = () => { + setIsModalOpen(true); + }; + + const formatDate = (dateString: string | number | Date) => { + const date = new Date(dateString); + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + const hours = String(date.getHours()).padStart(2, '0'); + const minutes = String(date.getMinutes()).padStart(2, '0'); + const seconds = String(date.getSeconds()).padStart(2, '0'); + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; + } + + + const handleOk = () => { + const params = {}; + const dateFilter = form.getFieldValue('dateFilter'); + if (dateFilter) { + params['dateFilter'] = dateFilter; + } + const selectDateTime = form.getFieldValue('selectDateTime'); + if (selectDateTime && selectDateTime[0]) { + console.log(selectDateTime) + params['startDate'] = formatDate(selectDateTime[0]); + } + if (selectDateTime && selectDateTime[1]) { + params['doneDate'] = formatDate(selectDateTime[1]); + } + const serviceStatus = form.getFieldValue('serviceStatus'); + if (serviceStatus) { + params['serviceStatus'] = serviceStatus; + } + const urlParams = new URLSearchParams(params).toString(); + window.open(serverUrl + `./ex/statistics/exportServiceStatList?` + urlParams); + setIsModalOpen(false); + }; + + const handleCancel = () => { + setIsModalOpen(false); + }; + + return ( +
+
+
+
+ + + 近一周 + 近一月 + 近三月 + + + + {}}/> + + +
`共 ${total} 条`, + onShowSizeChange: selectChange, + onChange: changePage + }} + scroll={{ y: 500 }} + sticky + /> + )} + + +

确定要导出文件?

+
+ + ); +}; + +export default App; diff --git a/packages/examination/src/views/store_manage/index.tsx b/packages/examination/src/views/store_manage/index.tsx index 63b7665..eab5535 100644 --- a/packages/examination/src/views/store_manage/index.tsx +++ b/packages/examination/src/views/store_manage/index.tsx @@ -197,8 +197,10 @@ class Store extends Component {