songxy 1 год назад
Родитель
Сommit
0f1bbe0ef1

+ 27 - 7
client/src/views/OaSystem/home/components/CardItemThree.vue

@@ -11,7 +11,7 @@
         <div>
           <p class="title">{{ item['title'] }}</p>
           <div class="numberBox">
-            <span class="number">{{ item['value'] }}</span>
+            <span class="number">{{ (item['value'] / 10000).toFixed(2) }}</span>
             <span class="unit">{{ item['unit'] }}</span>
           </div>
         </div>
@@ -21,6 +21,7 @@
 </template>
 
 <script setup lang="ts">
+import request from '@/config/axios'
 interface SignInterface {
   icon: string
   title: string
@@ -28,12 +29,12 @@ interface SignInterface {
   unit: string
 }
 const signs = ref<SignInterface[]>([
-  { icon: '签', title: '2023年度签约', value: 20601.6937, unit: '万元' },
-  { icon: '回', title: '2023年度回款', value: 15631.576, unit: '万元' },
-  { icon: '净', title: '2023年度净合同额', value: 17667.32, unit: '万元' },
-  { icon: '拓', title: '2023年度新开拓', value: 21124.023, unit: '万元' },
-  { icon: '分包', title: '待支付', value: 3990.6554, unit: '万元' },
-  { icon: '外包', title: '待支付', value: 30476.618, unit: '万元' }
+  { icon: '签', title: '2023年度签约', value: 0, unit: '万元' },
+  { icon: '回', title: '2023年度回款', value: 0, unit: '万元' },
+  { icon: '净', title: '2023年度净合同额', value: 0, unit: '万元' },
+  { icon: '拓', title: '2023年度新开拓', value: 0, unit: '万元' },
+  { icon: '分包', title: '待支付', value: 0, unit: '万元' },
+  { icon: '外包', title: '待支付', value: 0, unit: '万元' }
 ])
 const currentIndex = ref<number>(0)
 const $emit = defineEmits<{
@@ -43,6 +44,25 @@ const clickHandle = (item: SignInterface, index: number): void => {
   currentIndex.value = index
   $emit('click', item)
 }
+const queryContractInfo = async (): Promise<void> => {
+  const urlApi = `/contract/info`
+  const result = await request.post(
+    {
+      url: urlApi,
+      data: {
+        year: 2023
+      }
+    },
+    'business'
+  )
+  signs.value[0].value = result.signAmount ?? 0
+  signs.value[1].value = result.returnAmount ?? 0
+  signs.value[2].value = result.netAmount ?? 0
+  signs.value[3].value = result.newAmount ?? 0
+  signs.value[4].value = result.subToPay ?? 0
+  signs.value[5].value = result.outToPay ?? 0
+}
+queryContractInfo()
 </script>
 
 <style lang="scss" scoped>

+ 157 - 33
client/src/views/OaSystem/home/components/PersonInfo.vue

@@ -1,30 +1,123 @@
 <script setup lang="ts">
+import request from '@/config/axios'
 import BarList from './BarList.vue'
 /**
  * 板块领导-人员情况
  */
-const personList = [
-  {
-    name: '博士',
-    value: '1'
-  },
-  {
-    name: '硕士',
-    value: '32'
-  },
-  {
-    name: '本科',
-    value: '214'
-  },
-  {
-    name: '大专',
-    value: '27'
-  },
-  {
-    name: '大专以下',
-    value: '5'
+interface ChartValueType {
+  name: string
+  value: number
+}
+const barList = ref<ChartValueType[]>([])
+const staffNum = ref<number>()
+const boyStaffNum = ref<number>(0)
+const girlStaffNum = ref<number>(0)
+const degreeStatistic = reactive<{
+  ordinaryCollegeStaffNum: number
+  firstClassCollegeStaffNum: number
+  list: ChartValueType[]
+}>({
+  ordinaryCollegeStaffNum: 0,
+  firstClassCollegeStaffNum: 0,
+  list: [
+    {
+      name: '博士',
+      value: 0
+    },
+    {
+      name: '硕士',
+      value: 0
+    },
+    {
+      name: '本科',
+      value: 0
+    },
+    {
+      name: '大专',
+      value: 0
+    },
+    {
+      name: '大专以下',
+      value: 0
+    }
+  ]
+})
+const staffStatistic = reactive<{
+  formalStaffNum: number
+  traineeStaffNum: number
+  probationaryStaffNum: number
+  temporaryStaffNum: number
+  list: ChartValueType[]
+}>({
+  formalStaffNum: 0,
+  traineeStaffNum: 0,
+  probationaryStaffNum: 0,
+  temporaryStaffNum: 0,
+  list: [
+    {
+      name: '小于25',
+      value: 0
+    },
+    {
+      name: '25-30',
+      value: 0
+    },
+    {
+      name: '30-35',
+      value: 0
+    },
+    {
+      name: '35-40',
+      value: 0
+    },
+    {
+      name: '大于40',
+      value: 0
+    }
+  ]
+})
+const queryStaffStatistic = async (): Promise<void> => {
+  const urlApi = `/adm/staff-records/statistic/get`
+  const result = await request.get({ url: urlApi })
+  staffNum.value = result.staffNum ?? 0
+  if (result.sexStatistic) {
+    boyStaffNum.value = result.sexStatistic.boyStaffNum ?? 0
+    girlStaffNum.value = result.sexStatistic.girlStaffNum ?? 0
+  }
+  if (result.degreeStatistic) {
+    degreeStatistic.ordinaryCollegeStaffNum = result.ordinaryCollegeStaffNum ?? 0
+    degreeStatistic.firstClassCollegeStaffNum = result.firstClassCollegeStaffNum ?? 0
+    degreeStatistic.list[0].value = result.degreeStatistic.doctorStaffNum
+    degreeStatistic.list[1].value = result.degreeStatistic.masterStaffNum
+    degreeStatistic.list[2].value = result.degreeStatistic.undergraduateStaffNum
+    degreeStatistic.list[3].value = result.degreeStatistic.juniorCollegeStaffNum
+    degreeStatistic.list[4].value = result.degreeStatistic.belowJuniorCollegeStaffNum
+  }
+  if (result.typeStatistic) {
+    staffStatistic.formalStaffNum = result.typeStatistic.formalStaffNum ?? 0
+    staffStatistic.traineeStaffNum = result.typeStatistic.traineeStaffNum ?? 0
+    staffStatistic.probationaryStaffNum = result.typeStatistic.probationaryStaffNum ?? 0
+    staffStatistic.probationaryStaffNum = result.typeStatistic.probationaryStaffNum ?? 0
   }
-]
+  if (result.ageStatistic) {
+    staffStatistic.list[0].value = result.ageStatistic.underTwentyFiveStaffNum
+    staffStatistic.list[1].value = result.ageStatistic.twentyFiveToThirtyStaffNum
+    staffStatistic.list[2].value = result.ageStatistic.thirtyToThirtyFiveStaffNum
+    staffStatistic.list[3].value = result.ageStatistic.thirtyFiveToFortyStaffNum
+    staffStatistic.list[4].value = result.ageStatistic.overFortyStaffNum
+  }
+  switchListData(0)
+}
+queryStaffStatistic()
+
+const currentIndex = ref<number>(0)
+const clickHandle = (index: number): void => {
+  currentIndex.value = index
+  switchListData()
+}
+const switchListData = (): void => {
+  barList.value = currentIndex.value === 0 ? degreeStatistic.list : staffStatistic.list
+}
 </script>
 <template>
   <div class="card-person">
@@ -32,37 +125,62 @@ const personList = [
       <li>
         <i></i>
         <span>总计</span>
-        <span><b>279</b>人</span>
+        <span
+          ><b>{{ staffNum }}</b
+          >人</span
+        >
       </li>
       <li>
         <i></i>
         <span>男生</span>
-        <span><b>163</b>人</span>
+        <span
+          ><b> {{ boyStaffNum }} </b>人</span
+        >
       </li>
       <li>
         <i></i>
         <span>女生</span>
-        <span><b>116</b>人</span>
+        <span
+          ><b> {{ girlStaffNum }} </b>人</span
+        >
       </li>
     </ul>
   </div>
   <div class="card-person-chart">
     <div class="card-person-chart-l card-flex-col-center">
-      <span>学历构成</span>
-      <span>工龄司龄</span>
+      <span @click="clickHandle(0)" :class="{ active: currentIndex === 0 }">学历构成</span>
+      <span @click="clickHandle(1)" :class="{ active: currentIndex === 1 }">工龄司龄</span>
     </div>
-    <div class="card-person-chart-m card-flex-col-center">
+    <div class="card-person-chart-m card-flex-col-center" v-if="currentIndex === 0">
       <div class="school">
         <span><i></i>普通院校</span>
-        <span><b>198</b>人</span>
+        <span>
+          <b> {{ degreeStatistic.ordinaryCollegeStaffNum }} </b>人
+        </span>
       </div>
       <div class="school">
         <span><i></i>双一流院校</span>
-        <span><b>81</b>人</span>
+        <span>
+          <b> {{ degreeStatistic.firstClassCollegeStaffNum }} </b>人
+        </span>
+      </div>
+    </div>
+    <div class="card-person-chart-m card-flex-col-center" v-else>
+      <div class="school">
+        <span><i></i>正式员工</span>
+        <span>
+          <b> {{ staffStatistic.formalStaffNum }} </b>人
+        </span>
+      </div>
+      <div class="school">
+        <span><i></i>实习员工</span>
+        <span>
+          <b> {{ staffStatistic.traineeStaffNum }} </b>人
+        </span>
       </div>
     </div>
     <div style="width: 60%">
-      <BarList :list="personList" unit="人" />
+      <BarList :list="barList" unit="人" />
     </div>
   </div>
 </template>
@@ -151,11 +269,17 @@ const personList = [
       color: #fff;
       border: solid 1px rgb(46 119 230 / 100%);
       border-radius: 4px;
-
-      &:nth-child(1) {
-        background: linear-gradient(0deg, rgb(46 119 230 / 100%) 0%, rgb(149 191 255 / 100%) 100%);
+      cursor: pointer;
+      &.active {
+        background: linear-gradient(
+          0deg,
+          rgb(46 119 230 / 100%) 0%,
+          rgb(149 191 255 / 100%) 100%
+        ) !important;
+        color: #fff !important;
       }
 
+      &:nth-child(1),
       &:nth-child(2) {
         margin-top: 8px;
         color: #000000;

+ 40 - 56
client/src/views/OaSystem/home/components/ProcessChart.vue

@@ -5,71 +5,55 @@ import { EChartsOption } from 'echarts'
 /**
  * 普通员工-进度统计
  */
-
-const projectList = [
-  {
-    name: '75%-100%',
-    unit: '个',
-    value: '1165'
-  },
-  {
-    name: '50%-75%',
-    unit: '个',
-    value: '926'
-  },
-  {
-    name: '25%-50%',
-    percent: '1.3',
-    unit: '个',
-    value: '1798'
-  },
-  {
-    name: '10%-25%',
-    unit: '个',
-    value: '1798'
-  },
-  {
-    name: '0%-10%',
-    percent: '0.5',
-    unit: '个',
-    value: '439'
-  }
-]
+const $props = defineProps<{
+  data: {
+    name: string
+    value: number
+    unit: string
+  }[]
+}>()
 const colorPalette = ['#5FA5F8', '#45CCF6', '#F9A527', '#05CE9E', '#828DF1']
-const options = {
-  series: [
-    {
-      name: '进度统计',
-      type: 'pie',
-      radius: ['60%', '90%'],
-      color: colorPalette,
-      avoidLabelOverlap: false,
-      label: {
-        show: false,
-        position: 'center'
-      },
-      emphasis: {
-        label: {
-          show: false,
-          fontSize: 40,
-          fontWeight: 'bold'
+const options = ref<EChartsOption>({})
+watch(
+  () => $props.data,
+  () => {
+    options.value = {
+      series: [
+        {
+          name: '进度统计',
+          type: 'pie',
+          radius: ['60%', '90%'],
+          color: colorPalette,
+          avoidLabelOverlap: false,
+          label: {
+            show: false,
+            position: 'center'
+          },
+          emphasis: {
+            label: {
+              show: false,
+              fontSize: 40,
+              fontWeight: 'bold'
+            }
+          },
+          labelLine: {
+            show: false
+          },
+          data: $props.data
         }
-      },
-      labelLine: {
-        show: false
-      },
-      data: projectList
+      ]
     }
-  ]
-} as EChartsOption
+    console.log('初始化')
+  }
+)
 </script>
 <template>
   <div style="display: flex; height: 100%">
     <div style="width: 50%; height: 100%">
-      <MyEchart :options="options" style="height: 100%" />
+      <MyEchart :options="options as EChartsOption" style="height: 100%" />
     </div>
     <ul class="time-list">
-      <li v-for="(item, index) in projectList" :key="index">
+      <li v-for="(item, index) in $props.data" :key="index">
         <span><i :style="`background: ${colorPalette[index]};`"></i>{{ item.name }}</span>
         <span>{{ item.value }}个</span>
       </li>

+ 98 - 23
client/src/views/OaSystem/home/components/ProjectInfo.vue

@@ -1,4 +1,5 @@
 <script setup lang="ts">
+import request from '@/config/axios'
 import CardTitle from './CardTitle.vue'
 import ProcessChart from './ProcessChart.vue'
 
@@ -6,38 +7,110 @@ import ProcessChart from './ProcessChart.vue'
  * 板块领导-项目情况
  */
 
-const projectList = [
+const amountInfoList = ref([
   {
     name: '<100万',
-    percent: '94.1',
+    percent: 0,
     unit: '个',
-    value: '4415'
+    value: 0
   },
   {
     name: '100-200万',
-    percent: '3.4',
+    percent: 0,
     unit: '个',
-    value: '159'
+    value: 0
   },
   {
     name: '200-300万',
-    percent: '1.3',
+    percent: 0,
     unit: '个',
-    value: '60'
+    value: 0
   },
   {
     name: '300-400万',
-    percent: '0.5',
+    percent: 0,
     unit: '个',
-    value: '25'
+    value: 0
   },
   {
     name: '>400万',
-    percent: '0.7',
+    percent: 0,
     unit: '个',
-    value: '32'
+    value: 0
   }
-]
+])
+const projectInfo = ref({
+  xl: 0,
+  jz: 0,
+  haveContract: 0,
+  noContract: 0,
+  accepted: 0,
+  unaccepted: 0
+})
+const amountTotal = ref<number>(0)
+const projectChartDatas = ref<
+  {
+    name: string
+    value: number
+    unit: string
+  }[]
+>([])
+const queryProjectInfo = async (): Promise<void> => {
+  const urlApi = `/project/info`
+  const result = await request.get({ url: urlApi }, 'business')
+  if (result.countInfo) {
+    projectInfo.value.xl = result.countInfo.xl ?? 0
+    projectInfo.value.jz = result.countInfo.jz ?? 0
+    projectInfo.value.haveContract = result.countInfo.haveContract ?? 0
+    projectInfo.value.noContract = result.countInfo.noContract ?? 0
+    projectInfo.value.accepted = result.countInfo.accepted ?? 0
+    projectInfo.value.unaccepted = result.countInfo.unaccepted ?? 0
+  }
+  if (result.amountInfo) {
+    amountInfoList.value[0].value = result.amountInfo.lt100
+    amountInfoList.value[1].value = result.amountInfo.lt200
+    amountInfoList.value[2].value = result.amountInfo.lt300
+    amountInfoList.value[3].value = result.amountInfo.lt400
+    amountInfoList.value[4].value = result.amountInfo.gte400
+    amountTotal.value = result.amountInfo.total
+  }
+  if (result.processInfo) {
+    const projectList = [
+      {
+        name: '75%-100%',
+        unit: '个',
+        value: 0
+      },
+      {
+        name: '50%-75%',
+        unit: '个',
+        value: 0
+      },
+      {
+        name: '25%-50%',
+        unit: '个',
+        value: 0
+      },
+      {
+        name: '10%-25%',
+        unit: '个',
+        value: 0
+      },
+      {
+        name: '0%-10%',
+        unit: '个',
+        value: 0
+      }
+    ]
+    projectList[0].value = result.processInfo.gt75 ?? 0
+    projectList[1].value = result.processInfo.gt50 ?? 0
+    projectList[2].value = result.processInfo.gt25 ?? 0
+    projectList[3].value = result.processInfo.gt20 ?? 0
+    projectList[4].value = result.processInfo.gt10 ?? 0
+    projectChartDatas.value = projectList
+  }
+}
+queryProjectInfo()
 </script>
 <template>
   <CardTitle title="项目情况">
@@ -51,35 +124,35 @@ const projectList = [
   <ul class="project-list">
     <li>
       <span>
-        <b>507</b>
+        <b>{{ projectInfo.xl }}</b>
         新立
       </span>
 
       <span>
-        <b>1194</b>
+        <b>{{ projectInfo.jz }}</b>
         结转
       </span>
     </li>
     <li>
       <span>
-        <b>2796</b>
+        <b>{{ projectInfo.haveContract }}</b>
         有合同
       </span>
       <i></i>
       <span>
-        <b>1731</b>
+        <b>{{ projectInfo.noContract }}</b>
         无合同
       </span>
     </li>
 
     <li>
       <span>
-        <b>801</b>
+        <b>{{ projectInfo.accepted }}</b>
         已验收
       </span>
       <i></i>
       <span>
-        <b style="color: #f23c3c">6</b>
+        <b style="color: #f23c3c">{{ projectInfo.unaccepted }}</b>
         待验收
       </span>
     </li>
@@ -98,11 +171,13 @@ const projectList = [
         </template>
       </CardTitle>
       <ul class="money-list">
-        <li v-for="(item, index) in projectList" :key="index">
+        <li v-for="(item, index) in amountInfoList" :key="index">
           <span style="width: 70px">{{ item.name }}</span>
-          <span></span>
-          <span style="width: 50px; text-align: right">{{ item.value }}个</span>
-          <span style="width: 50px; text-align: right">{{ item.percent }}%</span>
+          <span :style="{ width: 70 * (item.value / amountTotal) + 'px' }"></span>
+          <span style="width: 50px; text-align: right">{{ item.value ?? 0 }}个</span>
+          <span style="width: 50px; text-align: right"
+            >{{ ((item.value / amountTotal) * 100).toFixed(2) }}%</span
+          >
         </li>
       </ul>
     </div>
@@ -112,7 +187,7 @@ const projectList = [
           <span class="my-chart-title"> <i></i> <b>进度统计</b></span>
         </template>
       </CardTitle>
-      <div style="height: calc(100% - 30px)"> <ProcessChart /> </div>
+      <div style="height: calc(100% - 30px)"> <ProcessChart :data="projectChartDatas" /> </div>
     </div>
   </div>
 </template>