ljy121 1 рік тому
батько
коміт
876241bef9

+ 8 - 4
client/src/views/OaSystem/home/components/CardItemFour.vue

@@ -6,13 +6,13 @@
 import * as echarts from 'echarts'
 
 const category: number[] = []
-const barData: number[] = []
+const barData: number[] = [13173.72, 16577.82, 15467.92, 16753.91, 20601.69]
 const dottedBase: Date = new Date()
 
-for (var i = 0; i < 10; i++) {
+for (var i = 0; i < 5; i++) {
   category.push(dottedBase.getFullYear() - 1)
-  var b = Math.random() * 200
-  barData.push(b)
+  // var b =
+  // barData.push(b)
 }
 const echartOption: echarts.EChartsOption = {
   title: [
@@ -60,6 +60,10 @@ const echartOption: echarts.EChartsOption = {
       name: 'bar',
       type: 'bar',
       barWidth: 20,
+      label: {
+        show: true,
+        position: 'top'
+      },
       itemStyle: {
         normal: {
           barBorderRadius: 10,

+ 92 - 0
client/src/views/OaSystem/home/components/CardItemFour2.vue

@@ -0,0 +1,92 @@
+<template>
+  <div class="FourDetailBox" ref="echartRef"> </div>
+</template>
+
+<script setup lang="ts">
+import * as echarts from 'echarts'
+
+const category: number[] = []
+const barData: number[] = [0, 0, 678.2, 1052.74, 515.02]
+const dottedBase: Date = new Date()
+
+for (var i = 0; i < 5; i++) {
+  category.push(dottedBase.getFullYear() - 1)
+  // var b =
+  // barData.push(b)
+}
+const echartOption: echarts.EChartsOption = {
+  title: [
+    {
+      show: true,
+      subtext: '单位:万元',
+      subtextStyle: {
+        color: '#8B969C',
+        lineHeight: 20
+      },
+      right: 20,
+      top: 5
+    }
+  ],
+  grid: {
+    left: '10%',
+    right: '5%',
+    bottom: '16%'
+  },
+  xAxis: {
+    data: category,
+    axisLine: {
+      show: false
+    },
+    axisTick: {
+      show: false
+    }
+  },
+  yAxis: {
+    splitLine: {
+      show: true,
+      lineStyle: {
+        type: 'dashed',
+        color: '#E3E3E3'
+      }
+    },
+    axisLine: {
+      lineStyle: {
+        color: '#666'
+      }
+    }
+  },
+  series: [
+    {
+      name: 'bar',
+      type: 'bar',
+      barWidth: 20,
+      label: {
+        show: true,
+        position: 'top'
+      },
+      itemStyle: {
+        normal: {
+          barBorderRadius: 10,
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+            { offset: 0, color: '#7BB5FA' },
+            { offset: 1, color: '#448ADC' }
+          ])
+        }
+      },
+      data: barData
+    }
+  ]
+}
+const echartRef = ref(null)
+onMounted(() => {
+  const myChart = echarts.init(echartRef.value)
+  myChart.setOption(echartOption)
+})
+</script>
+
+<style lang="scss" scoped>
+@import '../common.scss';
+.FourDetailBox {
+  height: 100%;
+}
+</style>

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

@@ -28,12 +28,12 @@ interface SignInterface {
   unit: string
 }
 const signs = ref<SignInterface[]>([
-  { icon: '签', title: '2023年度签约', value: 15005.65, unit: '万元' },
-  { icon: '回', title: '2023年度回款', value: 15005.65, unit: '万元' },
-  { icon: '净', title: '2023年度净合同额', value: 15005.65, unit: '万元' },
-  { icon: '拓', title: '2023年度新开拓', value: 15005.65, unit: '万元' },
-  { icon: '应', title: '总应收款', value: 15005.65, unit: '万元' },
-  { icon: '余', title: '总合同余额', value: 15005.65, unit: '万元' }
+  { 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: '万元' }
 ])
 const currentIndex = ref<number>(0)
 const $emit = defineEmits<{

+ 127 - 0
client/src/views/OaSystem/home/components/CardItemThree2.vue

@@ -0,0 +1,127 @@
+<template>
+  <div class="ThreeDetailBox">
+    <ul>
+      <li
+        v-for="(item, index) in signs"
+        :class="{ active: currentIndex === index }"
+        :key="index"
+        @click="clickHandle(item, index)"
+      >
+        <span class="circle">{{ item['icon'] }}</span>
+        <div>
+          <p class="title">{{ item['title'] }}</p>
+          <div class="numberBox">
+            <span class="number">{{ item['value'] }}</span>
+            <span class="unit">{{ item['unit'] }}</span>
+          </div>
+        </div>
+      </li>
+    </ul>
+  </div>
+</template>
+
+<script setup lang="ts">
+interface SignInterface {
+  icon: string
+  title: string
+  value: number
+  unit: string
+}
+const signs = ref<SignInterface[]>([
+  { icon: '签', title: '2023年度签约', value: 515.02, unit: '万元' },
+  { icon: '回', title: '2023年度回款', value: 758.438, unit: '万元' },
+  { icon: '净', title: '2023年度净合同额', value: 507.563, unit: '万元' },
+  { icon: '拓', title: '2023年度新开拓', value: 515.02, unit: '万元' },
+  { icon: '应', title: '总应收款', value: 87.83, unit: '万元' },
+  { icon: '余', title: '总合同余额', value: 622.4, unit: '万元' }
+])
+const currentIndex = ref<number>(0)
+const $emit = defineEmits<{
+  (e: 'click', v: SignInterface): void
+}>()
+const clickHandle = (item: SignInterface, index: number): void => {
+  currentIndex.value = index
+  $emit('click', item)
+}
+</script>
+
+<style lang="scss" scoped>
+.ThreeDetailBox {
+  padding: 35px 20px;
+  height: 100%;
+  > ul {
+    height: 100%;
+    display: grid;
+    grid-template-columns: repeat(2, 50%);
+    justify-content: space-between;
+    align-content: space-between;
+    > li {
+      padding: 10px 20px;
+      border-radius: 8px;
+      border: 2px solid transparent;
+      &:nth-child(2n + 1) {
+        margin-right: 15px;
+      }
+      display: flex;
+      > .circle {
+        display: block;
+        width: 66px;
+        height: 66px;
+        line-height: 66px;
+        border-radius: 50%;
+        background-color: #498bef;
+        color: #fff;
+        font-size: 22px;
+        text-align: center;
+        margin-right: 5px;
+      }
+      &:nth-child(1),
+      &:nth-child(2) {
+        cursor: pointer;
+        &.active,
+        &:hover {
+          border-color: #498bef;
+          background: linear-gradient(270deg, #eaf4ff 0%, #f9fcff 100%);
+        }
+      }
+      &:nth-child(3),
+      &:nth-child(4) {
+        > .circle {
+          background-color: #05ce9e;
+        }
+        &.active,
+        &:hover {
+          cursor: pointer;
+          border-color: #498bef;
+          background: linear-gradient(270deg, #eaf4ff 0%, #f9fcff 100%);
+        }
+      }
+
+      &:nth-child(5),
+      &:nth-child(6) {
+        > .circle {
+          background-color: #f9a527;
+        }
+        &.active,
+        &:hover {
+          cursor: pointer;
+          border-color: #498bef;
+          background: linear-gradient(270deg, #eaf4ff 0%, #f9fcff 100%);
+        }
+      }
+    }
+  }
+  .numberBox {
+    > .number {
+      font-size: 26px;
+      font-weight: bold;
+    }
+    > .unit {
+      font-size: 16px;
+      margin-left: 3px;
+      font-weight: 500;
+      color: #2d333c;
+    }
+  }
+}
+</style>

+ 1 - 0
client/src/views/OaSystem/home/index.vue

@@ -41,6 +41,7 @@ const IndexThree = defineAsyncComponent({
     return import('@/views/OaSystem/home/indexThree.vue')
   }
 })
+debugger
 const roles = userStore.getRoles
 if (roles) {
   if (roles.indexOf('test_leader') != -1) {

+ 2 - 2
client/src/views/OaSystem/home/indexTwo.vue

@@ -71,8 +71,8 @@
 import { useRouter } from 'vue-router'
 import CardItemOne from './components/CardItemOne.vue'
 import CardItemTwo from './components/CardItemTwo.vue'
-import CardItemThree from './components/CardItemThree.vue'
-import CardItemFour from './components/CardItemFour.vue'
+import CardItemThree from './components/CardItemThree2.vue'
+import CardItemFour from './components/CardItemFour2.vue'
 import CardItemFive from './components/CardItemFive2.vue'
 import CardItemSix from './components/CardItemSix.vue'
 import CardItemSeven from './components/CardItemSeven.vue'

+ 98 - 0
client/src/views/OaSystem/mineCenter/rightChild/loan.scss

@@ -0,0 +1,98 @@
+._LoanBox {
+  width: calc(100% - 30px);
+  height: calc(100% - 30px);
+  background: #FFFFFF;
+  border-radius: 4px 4px 4px 4px;
+  border: 1px solid #DEE0E3;
+  margin: 15px;
+
+  .searchBox {
+    width: 100%;
+    height: 125px;
+    background: #F7F8FA;
+    border-radius: 4px 4px 0 0;
+    display: flex;
+    align-items: center;
+    flex-wrap: wrap;
+    padding: 0 20px;
+    box-sizing: border-box;
+
+    .form {
+      display: flex;
+      align-items: center;
+      margin-right: 20px;
+
+      .formSpan {
+        font-size: 16px;
+      }
+
+      .btnBox {
+        display: flex;
+        align-items: center;
+      }
+    }
+  }
+
+  .infoBox {
+    width: 100%;
+    height: 55px;
+    background: #EDF2FB;
+
+    ul {
+      width: 100%;
+      height: 100%;
+      display: flex;
+      align-items: center;
+      padding: 0 20px;
+
+      li {
+        list-style: none;
+        display: flex;
+        align-items: center;
+      }
+    }
+  }
+
+  .tableBox {
+    width: 100%;
+    height: 480px;
+    padding: 15px 20px;
+    position: relative;
+
+    .table {
+      width: 100%;
+      height: calc(100% - 40px);
+
+      .operateBtn {
+        width: 54px;
+        height: 24px;
+        background: #EBF2FF;
+        border-radius: 16px 16px 16px 16px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        cursor: pointer;
+
+        span {
+          color: #2E77E6;
+        }
+      }
+    }
+
+    .pageBox {
+      position: absolute;
+      right: 20px;
+      bottom: 10px;
+      text-align: right;
+    }
+  }
+  :deep(.el-radio__label),
+  :deep(.el-checkbox__label){
+      font-size: 16px;
+  }
+  :deep(.el-radio-group){
+    label {
+      margin-right: 10px;
+    }
+  }
+}

+ 252 - 0
client/src/views/OaSystem/mineCenter/rightChild/myLoan.vue

@@ -0,0 +1,252 @@
+<template>
+  <div class="_LoanBox">
+    <div class="searchBox">
+      <div class="form">
+        <span class="formSpan">借款单号:</span>
+        <el-input
+          v-model="queryParams.loanNumber"
+          placeholder="请输入借款单号"
+          style="width: 210px"
+        />
+      </div>
+      <div class="form">
+        <span class="formSpan">核销状态:</span>
+        <el-select
+          width="160px"
+          v-model="queryParams.isVerify"
+          class="m-2"
+          placeholder="请选择核销状态"
+          size="large"
+        >
+          <el-option :key="''" label="全部" :value="''" />
+          <el-option :key="1" label="已核销" :value="1" />
+          <el-option :key="0" label="未核销" :value="0" />
+        </el-select>
+      </div>
+      <div class="form">
+        <span class="formSpan">状态:</span>
+        <el-select
+          width="160px"
+          v-model="queryParams.flowStatus"
+          class="m-2"
+          placeholder=""
+          size="large"
+        >
+          <el-option :key="''" label="全部" :value="''" />
+          <el-option :key="1" label="办理中" :value="1" />
+          <el-option :key="90" label="已借" :value="90" />
+        </el-select>
+      </div>
+      <div class="form">
+        <span class="formSpan">申请时间:</span>
+        <el-date-picker
+          v-model="applyDate"
+          type="daterange"
+          unlink-panels
+          range-separator="To"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+        />
+      </div>
+      <div class="from">
+        <div class="btnBox">
+          <el-button type="primary" style="background: #3485ff" @click="searchHandle">
+            <img src="@/assets/imgs/OA/search.png" class="mr-8px" alt="" />
+            查询</el-button
+          >
+        </div>
+      </div>
+    </div>
+    <div class="infoBox">
+      <ul>
+        <li v-for="(item, index) in infoList" :key="index" class="mr-40px">
+          <img class="mr-8px" :src="getAssetURL(item.icon)" alt="" />
+          <p>{{ item.name }}:</p>
+          <h4 class="font-size-18px">{{ item.num }}</h4>
+        </li>
+      </ul>
+    </div>
+    <div class="tableBox">
+      <div class="table" ref="tableRef">
+        <el-table
+          :data="tableData"
+          style="width: 100%; height: 100%"
+          :style="{ height: tableHeight + 'px' }"
+          :header-cell-style="{
+            background: '#F7F8FA',
+            color: '#121518',
+            height: '50px'
+          }"
+        >
+          <el-table-column label="序号" width="60">
+            <template #default="scope">{{ scope.$index + 1 }}</template>
+          </el-table-column>
+          <el-table-column prop="loanNumber" label="借款单号" width="180" />
+          <el-table-column prop="applyDate" label="申请时间" width="120" />
+          <el-table-column prop="workerDept" label="借款人部门" width="100" />
+          <el-table-column prop="worker" label="借款人" width="120" />
+          <el-table-column prop="loanAmount" label="借款总金额" width="120" />
+          <el-table-column prop="verifyAmount" label="已核销金额" width="120" />
+          <el-table-column prop="loanBalance" label="借款余额" width="120" />
+          <el-table-column prop="agreedPayTime" label="约定付款期限" width="120" />
+          <el-table-column prop="isVerify" label="核销状态" width="80">
+            <template #default="scope">
+              {{ verifyMap[scope.row.isVerify] }}
+            </template>
+          </el-table-column>
+          <el-table-column prop="verifyDate" label="核销时间" width="120" />
+          <el-table-column
+            show-overflow-tooltip="true"
+            prop="description"
+            label="借款说明"
+            width="360"
+          />
+          <el-table-column prop="flowStatus" label="状态" width="80">
+            <template #default="scope">
+              {{ flowStatusMap[scope.row.flowStatus] }}
+            </template>
+          </el-table-column>
+          <el-table-column label="操作" width="80">
+            <template #default="scope">
+              <div class="operateBtn" @click="operateClick(scope.row)">
+                <span>查看</span>
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+      <div class="pageBox">
+        <el-pagination
+          v-model:current-page="queryParams.pageNo"
+          :page-size="10"
+          background
+          layout="total, prev, pager, next, jumper"
+          :total="total"
+          @current-change="handleCurrentChange"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+<script setup lang="ts">
+import moment from 'moment'
+import { useRouter } from 'vue-router'
+import request from '@/config/axios'
+import { getAssetURL } from '@/utils/auth'
+import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
+
+defineOptions({ name: 'LoanList' })
+const verifyMap: any = { 1: '已核销', 0: '未核销' }
+const flowStatusMap: any = { 1: '办理中', 90: '已借' }
+
+const router = useRouter()
+const { wsCache } = useCache()
+const user = wsCache.get(CACHE_KEY.USER)
+const userId = user.user.id ? user.user.id : ''
+const deptId = user.user.deptId ? user.user.deptId : ''
+const tableRef: any = ref(null)
+const tableHeight: any = ref(0)
+const queryParams = reactive<{
+  loanNumber: string
+  appyDate: string
+  workerDept: string
+  worker: string
+  loanAmount: number | string
+  verifyAmount: number | string
+  loanBalance: number | string
+  agreedPayTime: string
+  isVerify: any
+  verifyDate: string
+  description: string
+  flowStatus: any
+  pageNo: number
+  applyOn: string
+  applyOff: string
+  workerId: string
+}>({
+  loanNumber: '',
+  appyDate: '',
+  workerDept: '',
+  worker: '',
+  loanAmount: '',
+  verifyAmount: '',
+  loanBalance: '',
+  agreedPayTime: '',
+  isVerify: '',
+  verifyDate: '',
+  description: '',
+  flowStatus: '',
+  pageNo: 1,
+  applyOn: '',
+  applyOff: '',
+  workerId: userId
+})
+const applyDate = ref()
+const infoList: any = ref([
+  {
+    icon: 'xmzx/xmzcz',
+    name: '已借款总金额(元)',
+    num: '0'
+  },
+  {
+    icon: 'xmzx/xmzcb',
+    name: '已核销总金额(元)',
+    num: '0'
+  },
+  {
+    icon: 'xmzx/xmzlr',
+    name: '借款总余额(元)',
+    num: '-100000.57'
+  }
+])
+
+const handleCurrentChange = (pageNo: number) => {
+  queryParams.pageNo = pageNo
+  queryLoanListAjax()
+}
+const operateClick = (row: any) => {
+  router.push({
+    path: '/projectDetail',
+    query: { id: row.projectId, contractId: row.id }
+  })
+}
+const tableData = ref<Array<any>>([])
+const total = ref<number>()
+const searchHandle: () => void = () => {
+  queryLoanListAjax()
+}
+const queryLoanListAjax = async (): Promise<void> => {
+  const urlApi = `/loan/page`
+  if (applyDate.value && applyDate.value.length > 0) {
+    queryParams.applyOn = moment(applyDate.value[0]).format('YYYY-MM-DD')
+    queryParams.applyOff = moment(applyDate.value[1]).format('YYYY-MM-DD')
+  }
+  const sendData = {
+    ...queryParams,
+    pageSize: 10
+  }
+  const result = await request.get({ url: urlApi, params: sendData }, '/business')
+  tableData.value = result['records']
+  total.value = result['total']
+}
+queryLoanListAjax()
+
+const filterNodeMethod = (value, data) => {
+  return data.name.includes(value)
+}
+onMounted(() => {
+  tableHeight.value = tableRef.value.clientHeight
+})
+</script>
+<style lang="scss" scoped>
+@import url(./loan.scss);
+@import url(./book.scss);
+._LoanBox {
+  width: calc(100% - 30px);
+  height: calc(100% - 30px);
+  background: #ffffff;
+  border-radius: 4px 4px 4px 4px;
+  border: 1px solid #dee0e3;
+  margin: 15px;
+}
+</style>