Pārlūkot izejas kodu

feat: 新增经营看板页面

qiny 1 gadu atpakaļ
vecāks
revīzija
ef970dbddd

+ 8 - 0
client/src/router/modules/remaining.ts

@@ -383,6 +383,14 @@ const remainingRouter: AppRouteRecordRaw[] = [
         meta: {
           title: '部门周报统计'
         }
+      },
+      {
+        path: 'businessBoard',
+        component: () => import('@/views/OaSystem/financialManagement/businessBoard/index.vue'),
+        name: 'BusinessBoard',
+        meta: {
+          title: '经营看板'
+        }
       }
     ]
   },

+ 150 - 0
client/src/views/OaSystem/financialManagement/businessBoard/api.ts

@@ -0,0 +1,150 @@
+import request from '@/config/axios'
+
+const apiUrl = {
+  segment: '/manage/segment', // 按板块统计数据
+  dept: '/manage/dept', // 按部门统计数据
+  person: '/manage/person' // 按人员统计数据
+}
+
+export interface ISegment {
+  /**
+   * 合同余额
+   */
+  contractBalance: number
+  /**
+   * 本年开拓
+   */
+  newAmount: number
+  /**
+   * 应收款
+   */
+  receivableAmount: number
+  /**
+   * 本年回款
+   */
+  returnAmount: number
+  /**
+   * 板块
+   */
+  segment: string
+  /**
+   * 本年签约
+   */
+  signAmount: number
+  /**
+   * 分包额
+   */
+  subAmount: number | null
+  /**
+   * 分包已支付
+   */
+  subPayed: number | null
+  /**
+   * 分包待支付
+   */
+  subToPay: number | null
+}
+
+export interface IDept {
+  // 合同余额
+  contractBalance: number
+  deptId: string
+  // 部门
+  deptName: string
+  // 部门人数
+  memberCount: number
+  // 本年开拓
+  newAmount: number
+  // 应收款
+  receivableAmount: number
+  // 本年回款
+  returnAmount: number | null
+  // 本年签约
+  signAmount: number
+}
+
+export interface IPerson {
+  /**
+   * 本年开拓
+   */
+  newAmount: number | null
+  /**
+   * 名字
+   */
+  nickname: string
+  /**
+   * 本年回款
+   */
+  returnAmount: number | null
+  /**
+   * 本年签约
+   */
+  signAmount: number | null
+  /**
+   * 用户id
+   */
+  userId: string
+}
+
+const segmentName = ['', '空间信息研究院', '空间规划研究院', '江苏分公司', '北京分公司']
+export const getSegmentData = async () => {
+  const result: any = await request.get(
+    {
+      url: apiUrl.segment
+    },
+    '/business'
+  )
+  return result.map((item) => ({
+    ...item,
+    segment: segmentName[item.segment]
+  }))
+}
+export const getDeptData = async () => {
+  const result: any = await request.get(
+    {
+      url: apiUrl.dept
+    },
+    '/business'
+  )
+  return result
+
+  return result.map((item) => ({
+    ...item,
+    signAmount: unitConversion(item.signAmount),
+    returnAmount: unitConversion(item.returnAmount),
+    newAmount: unitConversion(item.newAmount),
+    receivableAmount: unitConversion(item.receivableAmount),
+    contractBalance: unitConversion(item.contractBalance)
+  }))
+}
+export const getPersonData = async () => {
+  const result: any = await request.get(
+    {
+      url: apiUrl.person
+    },
+    '/business'
+  )
+  return result
+
+  return result.map((item) => ({
+    ...item,
+    signAmount: unitConversion(item.signAmount),
+    returnAmount: unitConversion(item.returnAmount),
+    newAmount: unitConversion(item.newAmount)
+  }))
+}
+
+// 处理一下数据单位
+export const unitConversion = (valueInTenThousand: number | null): string => {
+  if (!valueInTenThousand) return ''
+  // 判断值是否大于等于 1 万
+  if (valueInTenThousand >= 10000) {
+    // 将以万为单位的数字除以 10,000 来得到以万为单位的数字,并保留两位小数
+    const valueInBillion = valueInTenThousand / 10000
+    // 使用 toFixed 方法保留两位小数
+    return valueInBillion.toFixed(2) + ' 万'
+  } else {
+    // 小于 1 亿的情况,以万为单位返回
+    return `${valueInTenThousand} 元`
+  }
+}

+ 154 - 0
client/src/views/OaSystem/financialManagement/businessBoard/index.vue

@@ -0,0 +1,154 @@
+<template>
+  <div class="oa-sys-list-view">
+    <el-row class="up-box">
+      <el-col :span="24">
+        <div class="title">板块经营情况</div>
+        <el-table class="detail-table" :data="segmentData" style="width: 100%" max-height="400">
+          <el-table-column prop="segment" label="板块" />
+          <el-table-column prop="signAmount" label="本年签约" sortable>
+            <template #default="scope">
+              <span>{{ unitConversion(scope.row.signAmount) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="returnAmount" label="本年回款" sortable>
+            <template #default="scope">
+              <span>{{ unitConversion(scope.row.returnAmount) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="newAmount" label="本年开拓" sortable>
+            <template #default="scope">
+              <span>{{ unitConversion(scope.row.newAmount) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="receivableAmount" label="应收款" sortable>
+            <template #default="scope">
+              <span>{{ unitConversion(scope.row.receivableAmount) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="contractBalance" label="合同余额" sortable>
+            <template #default="scope">
+              <span>{{ unitConversion(scope.row.contractBalance) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="subAmount" label="分包额" sortable>
+            <template #default="scope">
+              <span>{{ unitConversion(scope.row.subAmount) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="subPayed" label="分包已支付" sortable>
+            <template #default="scope">
+              <span>{{ unitConversion(scope.row.subPayed) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="subToPay" label="分包待支付" sortable>
+            <template #default="scope">
+              <span>{{ unitConversion(scope.row.subToPay) }}</span>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-col>
+    </el-row>
+    <el-row class="down-box" justify="space-between">
+      <el-col :span="15">
+        <div class="title">部门经营情况</div>
+        <el-table class="detail-table" :data="deptData" style="width: 100%" max-height="400">
+          <el-table-column prop="deptName" label="部门" />
+          <el-table-column prop="signAmount" label="本年签约" sortable>
+            <template #default="scope">
+              <span>{{ unitConversion(scope.row.signAmount) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="returnAmount" label="本年回款" sortable>
+            <template #default="scope">
+              <span>{{ unitConversion(scope.row.returnAmount) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="newAmount" label="本年开拓" sortable>
+            <template #default="scope">
+              <span>{{ unitConversion(scope.row.newAmount) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="receivableAmount" label="应收款" sortable>
+            <template #default="scope">
+              <span>{{ unitConversion(scope.row.receivableAmount) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="contractBalance" label="合同余额" sortable>
+            <template #default="scope">
+              <span>{{ unitConversion(scope.row.contractBalance) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="memberCount" label="部门人数" />
+        </el-table>
+      </el-col>
+      <el-col :span="8">
+        <div class="title">人员经营情况</div>
+        <el-table class="detail-table" :data="personData" style="width: 100%" max-height="400">
+          <el-table-column prop="nickname" label="人员" />
+          <el-table-column prop="signAmount" label="本年签约" sortable>
+            <template #default="scope">
+              <span>{{ unitConversion(scope.row.signAmount) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="returnAmount" label="本年回款" sortable>
+            <template #default="scope">
+              <span>{{ unitConversion(scope.row.returnAmount) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="newAmount" label="本年开拓" sortable>
+            <template #default="scope">
+              <span>{{ unitConversion(scope.row.newAmount) }}</span>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+<script lang="ts" setup>
+/**
+ * @description 经营看板
+ */
+
+defineOptions({ name: 'BusinessBoard' })
+
+import {
+  ISegment,
+  IDept,
+  IPerson,
+  getSegmentData,
+  getDeptData,
+  getPersonData,
+  unitConversion
+} from './api'
+
+const segmentData = ref<ISegment[]>([])
+const deptData = ref<IDept[]>([])
+const personData = ref<IPerson[]>([])
+
+onMounted(async () => {
+  segmentData.value = await getSegmentData()
+  deptData.value = await getDeptData()
+  personData.value = await getPersonData()
+})
+</script>
+<style scoped lang="scss">
+.oa-sys-list-view {
+  .title {
+    height: 50px;
+    line-height: 50px;
+    font-weight: bold;
+    font-size: 20px;
+    color: #121518;
+  }
+  .down-box {
+    margin-top: 30px;
+  }
+  :deep(.el-table__header) {
+    .el-table__cell {
+      color: #233755;
+      background-color: #e5f0fb !important;
+    }
+  }
+}
+</style>

+ 2 - 2
client/src/views/OaSystem/marketCenter/khglPage/CustomerTable.vue

@@ -142,8 +142,8 @@ const newCustomer = (isAdd: boolean, row?) => {
   const params = !isAdd
     ? `/editCustomer?id=${row.id}&edit=true`
     : row
-    ? `/newCustomer?id=${row.id}`
-    : '/newCustomer'
+      ? `/newCustomer?id=${row.id}`
+      : '/newCustomer'
   push(params)
 }
 // 查看客户详情

+ 60 - 5
client/src/views/OaSystem/personnelManagement/ygdaPage/WorkTable.vue

@@ -3,12 +3,9 @@
     class="detail-table"
     :header-cell-style="{
       background: '#F2F4F8',
-      color: '#000000',
-      height: '46px'
+      color: '#000000'
     }"
-    style="width: 100%; height: 100%"
     :data="tableData"
-    height="150px"
   >
     <el-table-column prop="workLocation" label="工作单位" />
     <el-table-column prop="post" label="职位" />
@@ -23,7 +20,65 @@
 /**
  * @description 工作经历
  */
-const tableData = []
+interface ITable {
+  id?: string
+  userId?: string
+  workLocation: string
+  post: string
+  startTime: string
+  endTime: string
+  resignReason: string
+  jyxy: string
+  competitionDetail: string
+}
+const tableData = ref<ITable[]>([])
+const tableData2 = ref<ITable[]>([
+  {
+    workLocation: '',
+    post: '',
+    startTime: '',
+    endTime: '',
+    resignReason: '',
+    jyxy: '',
+    competitionDetail: ''
+  },
+  {
+    workLocation: '',
+    post: '',
+    startTime: '',
+    endTime: '',
+    resignReason: '',
+    jyxy: '',
+    competitionDetail: ''
+  },
+  {
+    workLocation: '',
+    post: '',
+    startTime: '',
+    endTime: '',
+    resignReason: '',
+    jyxy: '',
+    competitionDetail: ''
+  },
+  {
+    workLocation: '',
+    post: '',
+    startTime: '',
+    endTime: '',
+    resignReason: '',
+    jyxy: '',
+    competitionDetail: ''
+  },
+  {
+    workLocation: '',
+    post: '',
+    startTime: '',
+    endTime: '',
+    resignReason: '',
+    jyxy: '',
+    competitionDetail: ''
+  }
+])
 </script>
 <style scoped lang="scss">
 .detail-table {

+ 2 - 2
client/src/views/OaSystem/personnelManagement/ygdaPage/staffDetail.vue

@@ -9,7 +9,7 @@ import { useQuery, useMutation } from '@tanstack/vue-query'
 import { getRecordsDetail, editRecordsDetail, generateStaffNum } from '@/api/oa/staffRecords'
 import { getConfigDict } from './index'
 import { ElRow, FormInstance } from 'element-plus'
-// import TechCertificate from './TechCertificate.vue'
+import TechCertificate from './TechCertificate.vue'
 import avatarImg from '@/assets/imgs/avatar.jpg'
 import DeptSelect from '@/components/DeptSelect/index.vue'
 import { createImageViewer } from '@/components/ImageViewer'
@@ -188,7 +188,7 @@ const isEdit = computed(() => {
             <i></i>
             <span>工作经历</span>
           </div>
-          <WorkTable />
+          <TechCertificate />
         </div>
         <el-row justify="end">
           <el-form-item v-if="isEdit">