From 92b4c8e1bc2c68a3ea387c7ea78d535565c4f06d Mon Sep 17 00:00:00 2001 From: lishenfeng Date: Wed, 12 Feb 2025 17:49:39 +0800 Subject: [PATCH] =?UTF-8?q?feat():=20=E6=97=A5=E5=88=B0=E6=8A=A5=E7=8E=87?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 + src/views/Ptjs/Czdbl/dblOption.js | 96 ++++++++++ src/views/Ptjs/Czdbl/index.js | 276 ++++++++++++++++++----------- src/views/Ptjs/Czdbl/qsOption.js | 153 ++++++++++++++++ src/views/Ptjs/Czdbl/toolBottom.js | 64 ++++--- src/views/Ptjs/Czdbl/toolbar.js | 4 +- 6 files changed, 460 insertions(+), 135 deletions(-) create mode 100644 src/views/Ptjs/Czdbl/dblOption.js create mode 100644 src/views/Ptjs/Czdbl/qsOption.js diff --git a/package.json b/package.json index 33d725b..9e65b84 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,8 @@ "craco-less": "^3.0.1", "crypto-js": "^4.2.0", "dayjs": "^1.11.12", + "echarts": "^5.6.0", + "echarts-for-react": "^3.0.2", "http-proxy-middleware": "^2.0.6", "moment": "^2.30.1", "ol": "^9.1.0", diff --git a/src/views/Ptjs/Czdbl/dblOption.js b/src/views/Ptjs/Czdbl/dblOption.js new file mode 100644 index 0000000..afaebab --- /dev/null +++ b/src/views/Ptjs/Czdbl/dblOption.js @@ -0,0 +1,96 @@ +export default function dblOption(sellist,selday) { + let itemStyle = { + normal: { + label: { + show: true, + formatter: '{c}%' + }, + labelLine: { + show: true + } + } + } + const seriesData = []; + const serdata = { + type: 'bar', + itemStyle: itemStyle, + data: [] + }; + + const yAxisData = []; + for (let si = 0; si < sellist.length; si++) { + let obj = sellist[si]; + yAxisData.push(obj.adnm); + serdata.data.push(parseFloat((obj[selday]?.rate * 100).toFixed(2))); + } + if (serdata.data.length > 0) { + seriesData.push(serdata); + } + + return { + title: { + text: '日到报率详情', + textStyle: { + fontSize: 16 + }, + left: 'center' + }, + color: ['#1fbcd2', '#a23746'], + tooltip: { + formatter: '{b}, {c}%' + }, + grid: { + left:'12%' + }, + legend: { data: [] }, + toolbox: { + show: true, + orient: 'vertical', + feature: { + dataZoom: { + show: true, + title: { + zoom: '区域缩放', + back: '区域缩放还原', + } + }, + magicType: { + show: true, + title: { + line: '切换为折线图', + bar: '切换为柱状图', + }, + type: ['line', 'bar'] + }, + restore: { + show: true, + title: '还原' + }, + saveAsImage: { + show: true, + title: '保存为图片' + } + } + }, + xAxis: { + type: 'value', + axisLabel: { + formatter: '{value}%' + }, + axisLine: { + show: true, + }, + axisTick: { + show: true, + } + }, + yAxis: { + type: 'category', + data: yAxisData, + axisLabel: { + interval: 0 + } + }, + series: seriesData + } +} \ No newline at end of file diff --git a/src/views/Ptjs/Czdbl/index.js b/src/views/Ptjs/Czdbl/index.js index 11df331..f9a9997 100644 --- a/src/views/Ptjs/Czdbl/index.js +++ b/src/views/Ptjs/Czdbl/index.js @@ -5,6 +5,9 @@ import ToolBottom from './toolBottom.js'; import apiurl from '../../../models/apiurl' import { xyt_httpget2 } from "../../../utils/request" import { resJson } from './res.js'; +import ReactEcharts from 'echarts-for-react'; +import qsOption from './qsOption.js' +import dblOption from './dblOption.js' import moment from 'moment'; export default function Czrz() { const [newColumns, setNewColumns] = useState([]) @@ -15,6 +18,25 @@ export default function Czrz() { const [loading, setLoading] = useState(false) const [SearchBottom, setSearchBottom] = useState(false) const [adcdList, setAdcdList] = useState([]) + const [dayArr, setDayArr] = useState([]) + const [hbobj, setHbobj] = useState() + const [selectedObject, setSelectObject] = useState() + const [subTableData, setSubTableData] = useState([]) + const qsoptions = useMemo(() => { + if (dayArr.length > 0 && selectedObject) { + return qsOption(dayArr, selectedObject, hbobj) + } else { + return {} + } + }, [dayArr, selectedObject, hbobj]) + + const dblOptions = useMemo(() => { + if (subTableData.length > 0 && SearchBottom) { + return dblOption(subTableData, SearchBottom.operTime) + } else { + return {} + } + }, [subTableData, SearchBottom]) const columns = [ { title: '序号', @@ -47,6 +69,16 @@ export default function Czrz() { }, ] const detailsColumns = [ + { + title: '序号', + dataIndex: 'inx', + key: 'inx', + width: 80, + align: "center", + render: (text, record, index) => { + return {index + 1} + } + }, { title: '行政区划', dataIndex: 'adnm', @@ -64,10 +96,10 @@ export default function Czrz() { width: 100, align: "center", render: (text, record) => ( - - {record[SearchBottom?.operTime]?.ontpcnt?.pp} - - ) + + {record[SearchBottom?.operTime]?.ontpcnt?.pp} + + ) }, { title: '离线', @@ -76,10 +108,10 @@ export default function Czrz() { width: 100, align: "center", render: (text, record) => ( - - {record[SearchBottom?.operTime]?.offtpcnt?.pp} - - ) + + {record[SearchBottom?.operTime]?.offtpcnt?.pp} + + ) }, ] }, @@ -93,10 +125,10 @@ export default function Czrz() { width: 100, align: "center", render: (text, record) => ( - - {record[SearchBottom?.operTime]?.ontpcnt?.zz} - - ) + + {record[SearchBottom?.operTime]?.ontpcnt?.zz} + + ) }, { title: '离线', @@ -105,10 +137,10 @@ export default function Czrz() { width: 100, align: "center", render: (text, record) => ( - - {record[SearchBottom?.operTime]?.offtpcnt?.zz} - - ) + + {record[SearchBottom?.operTime]?.offtpcnt?.zz} + + ) }, ] }, @@ -122,10 +154,10 @@ export default function Czrz() { width: 100, align: "center", render: (text, record) => ( - - {record[SearchBottom?.operTime]?.ontpcnt?.wf} - - ) + + {record[SearchBottom?.operTime]?.ontpcnt?.wf} + + ) }, { title: '离线', @@ -134,10 +166,10 @@ export default function Czrz() { width: 100, align: "center", render: (text, record) => ( - - {record[SearchBottom?.operTime]?.offtpcnt?.wf} - - ) + + {record[SearchBottom?.operTime]?.offtpcnt?.wf} + + ) }, ] }, @@ -148,10 +180,10 @@ export default function Czrz() { width: 100, align: "center", render: (text, record) => ( - - {(record[SearchBottom?.operTime].rate * 100).toFixed(2)}% - - ) + + {(record[SearchBottom?.operTime]?.rate * 100).toFixed(2)}% + + ) }, { title: '总在线率', @@ -160,12 +192,12 @@ export default function Czrz() { width: 150, align: "center", render: (text, record) => { - return - { record.ratelen > 0 ? ( record.ratesum * 100 / record.ratelen ).toFixed(2) : '-'}% - + return + {record.ratelen > 0 ? (record.ratesum * 100 / record.ratelen).toFixed(2) : '-'}% + } - + }, ] const newDetailsColumns = useMemo(() => { @@ -178,9 +210,9 @@ export default function Czrz() { align: "center", render: (v, r, i) => {i + 1} } - return [tmObj,...detailsColumns] + return [tmObj, ...detailsColumns] } - },[SearchBottom]) + }, [SearchBottom]) const [searchVal, setSearchVal] = useState(false) const width = useMemo(() => newColumns.reduce((total, cur) => total + (cur.width), 0), [newColumns]); @@ -189,14 +221,15 @@ export default function Czrz() { try { const res = await xyt_httpget2(apiurl.ptjs.czdbl, params) if (res.code == 200) { + res.data['429000000000'] = { ...res.data["429021000000"], adcd: '429000000000' } proccess(res.data) - + } } catch (error) { console.log(error); } } - const [hbobj, setHbobj] = useState() + const proccess = (results) => { const dayarr = []; const adlist = []; @@ -216,7 +249,7 @@ export default function Czrz() { adlist.push(adobj); - if (/00000000$/.test(adcd) || adcd === '429021000000') { + if (/00000000$/.test(adcd)) { for (let k in adobj) { if (!/^[0-9]{4}/.test(k)) { continue; @@ -290,6 +323,7 @@ export default function Czrz() { } }); console.log("dayarr", dayarr); + setDayArr(dayarr) const dayarrColumns = dayarr.map(it => ({ title: it, dataIndex: it, @@ -328,14 +362,15 @@ export default function Czrz() { obj.ratesum += obj[day].rate; obj.ratelen += 1; } - if (reg.test(adcd) || adcd === '429021000000') { + if (reg.test(adcd)) { list.push(obj); } } - if (list.length > 0) { + if (list.length > 0) { setLoading(false) } console.log("list", list); + console.log("newhbobj", newhbobj); setTableList([newhbobj, ...list]); } @@ -389,51 +424,52 @@ export default function Czrz() { console.log(error); } } - const onSelect = (keys,arr) => { - console.log(keys,arr); + const onSelect = (keys, arr) => { + console.log(keys, arr); setSelectedKeys(keys) setAdcd(keys[0]) } - - // 子表格数据 - const [subTableData, setSubTableData] = useState([]) - const filterSondata = (selectedObj, type, adlist, selday) => { + // 子表格数据 + + const filterSondata = (selectedObj, type, adlist, selday) => { const sellist = []; if (selectedObj && type != 'province') { let adreg = new RegExp('^' + selectedObj.adcd.substring(0, 4)); - for (let si = 0; si < adlist.length; si++) { - let obj = adlist[si]; - if ((adreg.test(obj.adcd) && obj.adcd != selectedObj.adcd) || - (selectedObj.adcd === '429021000000' && obj.adcd === '429021000000')) { - sellist.push(obj); + let obj = adlist[si]; + if (selectedObj.isBl) { + if ((adreg.test(obj.adcd) && obj.adcd == selectedObj.adcd)) { + sellist.push(obj); + } + } else if ((adreg.test(obj.adcd) && obj.adcd != selectedObj.adcd)) { + sellist.push(obj); } - } - } - if (selectedObj && type == 'province') { - let adreg = /00000000$/; + } + } - for (let si = 0; si < adlist.length; si++) { - let obj = adlist[si]; + if (selectedObj && type == 'province') { + let adreg = /00000000$/; - if ((adreg.test(obj.adcd) || obj.adcd === '429021000000') && obj.adcd != selectedObj.adcd) { - sellist.push(obj); - } - } - } + for (let si = 0; si < adlist.length; si++) { + let obj = adlist[si]; - sellist.sort(function (o1, o2) { - if (o1[selday].rate > o2[selday].rate) { - return 1; - } else { - return -1; - } + if ((adreg.test(obj.adcd)) && obj.adcd != selectedObj.adcd) { + sellist.push(obj); + } + } + } + sellist.sort(function (o1, o2) { + if (o1[selday]?.rate > o2[selday]?.rate) { + return 1; + } else { + return -1; + } }); - console.log("sellist",sellist); - + console.log("sellist", sellist); + setSubTableData(sellist) - } + } useEffect(() => { if (searchVal) { const params = { @@ -456,64 +492,88 @@ export default function Czrz() { return item } }) - const type = selectObj?.adcd == '420000000000' ? 'province':'city' + selectObj.isBl = selectObj?.adcd.substring(4) != '00000000' ? true : false + const type = selectObj?.adcd == '420000000000' ? 'province' : 'city' // const type = 'province'; - console.log("adcd",subStrAdcd); - - filterSondata(selectObj,type,adcdList,SearchBottom.operTime) + console.log("adcd", subStrAdcd); + setSelectObject(selectObj) + filterSondata(selectObj, type, adcdList, SearchBottom.operTime) } - }, [adcd,SearchBottom,adcdList,hbobj]) - - + }, [adcd, SearchBottom, adcdList, hbobj]) + + return (
{ treeList.length > 0 ? - : - + /> : + }
+ +
+ + 测站到报率 +
-
- { - !loading ? - : } - -
- -
- { - newDetailsColumns && -
} - +
+
+ { + !loading ? + <> +
+ +
+
+ + : null} + +
+ {!loading &&
+ +
} +
+ { + !loading ? + <> +
+ +
+
+ : + + } + + + diff --git a/src/views/Ptjs/Czdbl/qsOption.js b/src/views/Ptjs/Czdbl/qsOption.js new file mode 100644 index 0000000..4aab4c4 --- /dev/null +++ b/src/views/Ptjs/Czdbl/qsOption.js @@ -0,0 +1,153 @@ + +import moment from "moment" +export default function qsOption(timeList, listObj, hbobj) { + const chartTimeList = JSON.parse(JSON.stringify(timeList)); + let itemStyle = { + normal: { + label: { + show: true, + formatter: '{c}%' + }, + labelLine: { + show: true + } + } + } + let minY = 100; + let hbSeriseData = []; + const totalSerise = [ + { + name: "湖北省", + type: 'line', + itemStyle: itemStyle, + data: hbSeriseData + } + ] + const legendName = ['湖北省']; + let addSerise = { + name: "", + type: 'line', + itemStyle: itemStyle, + data: [] + } + // 湖北省 + for (let d = chartTimeList.length - 1; d > -1; d--) { + let yval = parseFloat((hbobj[chartTimeList[d]]?.rate * 100).toFixed(2)); + hbSeriseData.push(yval); + } + // 市 + for (let d = chartTimeList.length - 1; d > -1; d--) { + let yval = parseFloat((listObj[chartTimeList[d]]?.rate * 100).toFixed(2)); + addSerise.name = listObj?.adnm; + addSerise.data.push(yval); + + if (yval < minY) { + minY = yval; + } + minY = Math.ceil(minY) - 5; + minY = minY < 0 ? 0 : minY; + + } + if (addSerise.name && addSerise.name != '湖北省') { + totalSerise.push(addSerise) + legendName.push(addSerise.name); + } + + chartTimeList.sort(function (o1, o2) { + if (moment(o1).isBefore(moment(o2))) { + return -1; + } else { + return 1; + } + }); + chartTimeList.forEach(function (str, idx) { + chartTimeList[idx] = str.substring(5, 10); + }); + + + + return { + title: { + text: '到报率变化趋势', + textStyle: { + fontSize: 16 + }, + left: 'center' + }, + tooltip: { + trigger: 'axis', + formatter: '{a}, {b}, {c}%' + }, + legend: { + data: legendName, + top:30 + }, + toolbox: { + show: true, + orient: 'vertical', + feature: { + dataZoom: { + show: true, + title: { + zoom: '区域缩放', + back: '区域缩放还原', + } + }, + magicType: { + show: true, + title: { + line: '切换为折线图', + bar: '切换为柱状图', + }, + type: ['line', 'bar'] + }, + restore: { + show: true, + title: '还原' + }, + saveAsImage: { + show: true, + title: '保存为图片' + } + } + }, + // dataZoom: [{ + // type: 'inside', + // start: 0, + // end: 100 + // }, { + // start: 0, + // end: 10, + // handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z', + // handleSize: '80%', + // handleStyle: { + // color: '#fff', + // shadowBlur: 3, + // shadowColor: 'rgba(0, 0, 0, 0.6)', + // shadowOffsetX: 2, + // shadowOffsetY: 2 + // } + // }], + xAxis: { + type: 'category', + data: chartTimeList, + axisLabel: { + interval: 0 + } + }, + yAxis: { + type: 'value', + axisLabel: { + formatter: '{value}%' + }, + min: minY, + axisLine: { + show: true, + }, + axisTick: { + show: true, + } + }, + series:totalSerise + } +} \ No newline at end of file diff --git a/src/views/Ptjs/Czdbl/toolBottom.js b/src/views/Ptjs/Czdbl/toolBottom.js index 234af8a..7474edd 100644 --- a/src/views/Ptjs/Czdbl/toolBottom.js +++ b/src/views/Ptjs/Czdbl/toolBottom.js @@ -2,35 +2,49 @@ import React, { useEffect,useState } from 'react'; import { Form, Input, Button, DatePicker } from 'antd'; import NormalSelect from '../../../components/Form/NormalSelect'; import dayjs from 'dayjs'; -const ToolBottom = ({ setToolVal }) => { - const [form] = Form.useForm(); - const onFinish = (values) => { - if (values.operTime) { - values.operTime = values.operTime ? dayjs(values.operTime).format('YYYY-MM-DD') : ""; +import moment from 'moment'; +const ToolBottom = ({ setToolVal, searchVal }) => { + console.log("searchVal",searchVal); + + const [form] = Form.useForm(); + const [timeOptions, setTimeOptions] = useState([]) + const onValuesChange = (changedValues, allValues) => { + setToolVal(changedValues) + } + const generateDateRange = (startDate, endDate) => { + let dates = []; + let currentDate = moment(startDate); + let end = moment(endDate); + + while (currentDate.isSameOrBefore(end)) { + dates.push(currentDate.format('YYYY-MM-DD')); + currentDate.add(1, 'days'); } - setToolVal(values); - } - - useEffect(() => { - const defaultValue = dayjs() - form.setFieldsValue({ operTime: defaultValue }) - setToolVal({operTime:defaultValue.format('YYYY-MM-DD')}) - }, []); + return dates.map(item => ({ + label: item, + value: item, + })); +} +// useEffect(() => { +// const defaultValue = dayjs().subtract(1,'days').format('YYYY-MM-DD') +// form.setFieldsValue({ operTime: defaultValue }) +// setToolVal({operTime:defaultValue}) +// }, []); + useEffect(() => { + if (searchVal) { + const timeOptions = generateDateRange(searchVal.stm, searchVal.etm) + setTimeOptions(timeOptions) + form.setFieldsValue({ operTime: searchVal.etm }) + setToolVal({operTime:searchVal.etm}) + } + }, [searchVal]) + return (
-
- - - - - - - - + + + diff --git a/src/views/Ptjs/Czdbl/toolbar.js b/src/views/Ptjs/Czdbl/toolbar.js index ccfbbfe..484ac4b 100644 --- a/src/views/Ptjs/Czdbl/toolbar.js +++ b/src/views/Ptjs/Czdbl/toolbar.js @@ -19,8 +19,8 @@ const ToolBar = ({ setToolVal }) => { useEffect(() => { const defaultValue = [ - dayjs().subtract(7, 'days'), - dayjs() + dayjs().subtract(10, 'days'), + dayjs().subtract(1,'days') ] form.setFieldsValue({ operTime: defaultValue }) setToolVal({stm:defaultValue[0].format('YYYY-MM-DD'), etm:defaultValue[1].format('YYYY-MM-DD')})