Forráskód Böngészése

feat: 新增环形饼状图

lanjianrong 4 éve
szülő
commit
f157c62bbb

+ 3 - 1
package.json

@@ -174,9 +174,11 @@
     "webpack": "4.42.0",
     "webpack-dev-server": "3.11.0",
     "webpack-manifest-plugin": "2.2.0",
-    "workbox-webpack-plugin": "4.3.1"
+    "workbox-webpack-plugin": "4.3.1",
+    "@types/echarts": "^4.9.3"
   },
   "dependencies": {
+    "@ant-design/charts": "^1.0.13",
     "@ant-design/icons": "^4.2.2",
     "antd": "^4.6.4",
     "axios": "^0.21.1",

+ 19 - 0
src/assets/css/common.scss

@@ -516,3 +516,22 @@
   background-color: #fff3cd;
   border-color: #ffeeba;
 }
+
+.pi-badge {
+  display: inline-block;
+  padding-right: .6em;
+  padding-left: .6em;
+  border-radius: 10rem;
+  font-size: 100%;
+  font-weight: 700;
+  padding: 0.25em 0.4em;
+  line-height: 1;
+  text-align: center;
+  white-space: nowrap;
+  vertical-align: baseline;
+  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+  &.danger {
+    color: #fff;
+    background-color: #dc3545;
+  }
+}

+ 7 - 3
src/pages/Safe/Content/Info/Detail/index.tsx

@@ -150,6 +150,10 @@ const Detail: React.FC<RouteComponentProps> = props => {
   const onModalConfirm = (values?: object) => {
     let payload: any = { safe_id: detail.id, bidsection_id: detail.bidsectionId, ...values }
     if (visible.auditType === 'start') {
+      payload.inspection = detail.inspection
+      payload.inspectionDetail = detail.inspectionDetail
+      payload.demand = detail.demand
+      payload.createTime = detail.createTime
       payload.auditors = detail.auditors.filter(item => item.progress === '0').map(item => item.audit_id)
       payload.reAuditors = detail.auditors.filter(item => item.progress === '2').map(item => item.audit_id)
       payload.times = detail.times
@@ -241,7 +245,7 @@ const Detail: React.FC<RouteComponentProps> = props => {
                 <th style={{ width: '150px' }}>检查项目</th>
                 <td>
                   {
-                    isEdited ? <span>{detail.inspection}</span> : <TextArea value={detail.inspection} ></TextArea>
+                    isEdited ? <span>{detail.inspection}</span> : <TextArea value={detail.inspection} onChange={(e) => {setDetail({ ...detail, inspection: e.currentTarget.value })}}></TextArea>
                   }
                 </td>
               </tr>
@@ -249,7 +253,7 @@ const Detail: React.FC<RouteComponentProps> = props => {
                 <th style={{ width: '150px' }}>现场检查情况</th>
                 <td>
                   {
-                    isEdited ? <span>{detail.inspectionDetail}</span> : <TextArea value={detail.inspectionDetail} ></TextArea>
+                    isEdited ? <span>{detail.inspectionDetail}</span> : <TextArea value={detail.inspectionDetail} onChange={(e) => {setDetail({ ...detail, inspectionDetail: e.currentTarget.value })}}></TextArea>
                   }
                 </td>
               </tr>
@@ -257,7 +261,7 @@ const Detail: React.FC<RouteComponentProps> = props => {
                 <th style={{ width: '150px' }}>处理要求及措施</th>
                 <td>
                   {
-                    isEdited ? <span>{detail.demand}</span> : <TextArea value={detail.demand}></TextArea>
+                    isEdited ? <span>{detail.demand}</span> : <TextArea value={detail.demand} onChange={(e) => {setDetail({ ...detail, demand: e.currentTarget.value })}}></TextArea>
                   }
                 </td>
               </tr>

+ 10 - 0
src/pages/Safe/Content/Info/Summary/api.ts

@@ -0,0 +1,10 @@
+import request from "@/utils/common/request"
+
+/**
+ * 获取安全概述
+ * @param bid 标段id
+ */
+export async function apiGetSafeSurvey(bid: string) {
+  const { data } = await request.get('/api/safe/survey', { bidsectionId: bid })
+  return data
+}

+ 5 - 0
src/pages/Safe/Content/Info/Summary/index.scss

@@ -15,3 +15,8 @@
 .card.h400 {
   height: 400px;
 }
+
+.echarts-pie {
+  width: 100%;
+  height: 300px;
+}

+ 63 - 26
src/pages/Safe/Content/Info/Summary/index.tsx

@@ -1,42 +1,79 @@
 import Header from '@/components/Header'
-import React from 'react'
-import { RouteProps } from 'react-router'
+import { tenderStore } from '@/store/mobx'
+import consts from '@/utils/consts'
+import dayjs from 'dayjs'
+import React, { useEffect, useState } from 'react'
+import { useActivate } from 'react-activation'
+import { Link } from 'react-router-dom'
+import { apiGetSafeSurvey } from './api'
 import './index.scss'
+import PieChart from './pieChart'
+interface charListType {
+  [key: string]: number
+}
 
+interface iRectifyData {
+  auditName: string
+  createTime: string
+  id: string
+  inspectionDetail: string
+  status: number
+}
+interface iSummaryState {
+  approvalTotal: number
+  rectifyTotal: number
+  rectifyedData: charListType
+  rectifyedTotal: number
+  rectifylist: iRectifyData[]
+  submitData: charListType
+}
+const Summary: React.FC<{}> = () => {
+  useEffect(() => {
+    initData()
+  }, [])
+  const [ state, setState ] = useState<iSummaryState>({
+    approvalTotal: 0,
+    rectifyTotal: 0,
+    rectifyedTotal: 0,
+    rectifyedData: {},
+    rectifylist: [],
+    submitData: {}
+  })
+  useActivate(() => initData())
+  const initData = async () => {
+    const { data, code = -1 } = await apiGetSafeSurvey(tenderStore.bid)
+    if (code === consts.RET_CODE.SUCCESS) {
+      setState({ ...state, ...data })
+    }
+  }
 
-const Summary:React.FC<RouteProps> = (props) => {
-  // console.log(props.location?.state)
-
-  // useActivate(() => {
-  //   BidHander()
-  // })
-  // useEffect(() => {
-  //   BidHander()
-  // }, [])
-  // const BidHander = () => {
-  //   if (Object.keys(props.location?.state as object).length) {
-  //     // console.log(props.location?.state)
-
-  //     const { id = '', name = '' } = props.location?.state as {id: string;name: string}
-  //     id && (tenderStore.saveBidsectionId(id))
-  //     name && (tenderStore.saveName(name))
-  //   }
-  // }
+  const handleDate = (createTime: string) => {
+    return dayjs(new Date()).diff(dayjs(createTime), 'day') + '天'
+  }
   return (
     <div className="wrap-contaniner">
       <Header title="巡检概况"></Header>
       <div className="wrap-content m-3 pi-flex-column pi-justify-start">
         <div className="pi-justify-start">
           <div className="pi-flex-twice card pi-flex-column">
-            <header className="card-title">整改中 (23) </header>
+            <header className="card-title">整改中 ({state.rectifyTotal}) </header>
             <div>
-              <p>检查路面清洗,路面污染严重</p>
-              <p>检查路面清洗,路面污染严重</p>
-              <p>检查路面清洗,路面污染严重</p>
-              <p>检查路面清洗,路面污染严重</p>
+              {state.rectifylist.map(item => {
+                return (
+                  <div key={item.id} className="pi-justify-between pi-lh-18 pi-height-18">
+                    <Link to={{ pathname: '/console/safe/content/detail/info', state: { saveId: item.id } }}>{item.inspectionDetail}</Link>
+                    <div className="pi-align-center">
+                      <span className="pi-mg-right-5">{item.auditName}</span>
+                      <span className="pi-badge danger">{handleDate(item.createTime)}</span>
+                    </div>
+                  </div>
+                )
+              })}
             </div>
           </div>
-          <div className="pi-flex-treble pi-mg-left-30 card"></div>
+          <div className="pi-flex-treble pi-mg-left-30 card">
+              <PieChart></PieChart>
+          </div>
         </div>
         <div className="card h-400 mt-3"></div>
       </div>

+ 63 - 0
src/pages/Safe/Content/Info/Summary/pieChart.tsx

@@ -0,0 +1,63 @@
+import React from 'react'
+import { Pie, G2  } from '@ant-design/charts'
+import { PieConfig } from '@ant-design/charts/es/pie'
+import './index.scss'
+const G = G2.getEngine('canvas')
+G2.registerTheme('custom-pie', {
+  colors10: [ '#C7B8A1', '#9CA8B8', '#7B8B6F' ],
+  colors29: [ '#DACAB1', '#ABB8CA', '#87987A' ]
+})
+const DemoPie: React.FC = () => {
+
+  const data = [
+    {
+      type: '审批中',
+      value: 27
+    },
+    {
+      type: '整改中',
+      value: 25
+    },
+    {
+      type: '已整改',
+      value: 18
+    }
+  ]
+  const config:PieConfig = {
+
+    appendPadding: 10,
+    data: data,
+    padding: 'auto',
+    angleField: 'value',
+    colorField: 'type',
+    radius: 1,
+    renderer: 'svg',
+    innerRadius: 0.7,
+    className: 'echarts-pie',
+    // meta: {
+    //   value: {
+    //     formatter: function formatter(v) {
+    //       return ''.concat(v, ' \xA5')
+    //     }
+    //   }
+    // },
+    label: {
+      type: 'outer',
+      autoRotate: false,
+      content: '{name}: {value} - {percentage}'
+    },
+    interactions: [
+      { type: 'element-selected' },
+      { type: 'pie-legend-active' },
+      { type: 'element-active' }
+      // { type: 'pie-statistic-active' }
+    ],
+    legend: {
+      layout: 'horizontal',
+      position: 'top-left'
+    },
+    theme: 'custom-pie'
+  }
+  return <Pie {...config} />
+}
+export default DemoPie