Selaa lähdekoodia

🐞 fix(日报汇总): 看板

Zimo 6 päivää sitten
vanhempi
commit
11997ac032
4 muutettua tiedostoa jossa 178 lisäystä ja 25 poistoa
  1. 1 0
      package.json
  2. 58 0
      pnpm-lock.yaml
  3. 4 0
      src/api/pms/iotrhdailyreport/index.ts
  4. 115 25
      src/views/pms/iotrhdailyreport/summary.vue

+ 1 - 0
package.json

@@ -69,6 +69,7 @@
     "min-dash": "^4.1.1",
     "mitt": "^3.0.1",
     "moment": "^2.30.1",
+    "motion-v": "^1.7.4",
     "nprogress": "^0.2.0",
     "pinia": "^2.1.7",
     "pinia-plugin-persistedstate": "^3.2.1",

+ 58 - 0
pnpm-lock.yaml

@@ -140,6 +140,9 @@ importers:
       moment:
         specifier: ^2.30.1
         version: 2.30.1
+      motion-v:
+        specifier: ^1.7.4
+        version: 1.7.4(@vueuse/core@10.11.1(vue@3.5.12(typescript@5.3.3)))(vue@3.5.12(typescript@5.3.3))
       nprogress:
         specifier: ^0.2.0
         version: 0.2.0
@@ -3390,6 +3393,20 @@ packages:
   fraction.js@4.3.7:
     resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
 
+  framer-motion@12.23.12:
+    resolution: {integrity: sha512-6e78rdVtnBvlEVgu6eFEAgG9v3wLnYEboM8I5O5EXvfKC8gxGQB8wXJdhkMy10iVcn05jl6CNw7/HTsTCfwcWg==}
+    peerDependencies:
+      '@emotion/is-prop-valid': '*'
+      react: ^18.0.0 || ^19.0.0
+      react-dom: ^18.0.0 || ^19.0.0
+    peerDependenciesMeta:
+      '@emotion/is-prop-valid':
+        optional: true
+      react:
+        optional: true
+      react-dom:
+        optional: true
+
   fs-extra@10.1.0:
     resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==}
     engines: {node: '>=12'}
@@ -3524,6 +3541,9 @@ packages:
     resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
     hasBin: true
 
+  hey-listen@1.0.8:
+    resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==}
+
   highlight.js@11.10.0:
     resolution: {integrity: sha512-SYVnVFswQER+zu1laSya563s+F8VDGt7o35d4utbamowvUNLLMovFqwCLSocpZTz3MgaSRA1IbqRWZv97dtErQ==}
     engines: {node: '>=12.0.0'}
@@ -4055,6 +4075,18 @@ packages:
   moment@2.30.1:
     resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==}
 
+  motion-dom@12.23.12:
+    resolution: {integrity: sha512-RcR4fvMCTESQBD/uKQe49D5RUeDOokkGRmz4ceaJKDBgHYtZtntC/s2vLvY38gqGaytinij/yi3hMcWVcEF5Kw==}
+
+  motion-utils@12.23.6:
+    resolution: {integrity: sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==}
+
+  motion-v@1.7.4:
+    resolution: {integrity: sha512-YNDUAsany04wfI7YtHxQK3kxzNvh+OdFUk9GpA3+hMt7j6P+5WrVAAgr8kmPPoVza9EsJiAVhqoN3YYFN0Twrw==}
+    peerDependencies:
+      '@vueuse/core': '>=10.0.0'
+      vue: '>=3.0.0'
+
   mpd-parser@0.22.1:
     resolution: {integrity: sha512-fwBebvpyPUU8bOzvhX0VQZgSohncbgYwUyJJoTSNpmy7ccD2ryiCvM7oRkn/xQH5cv73/xU7rJSNCLjdGFor0Q==}
     hasBin: true
@@ -8890,6 +8922,12 @@ snapshots:
 
   fraction.js@4.3.7: {}
 
+  framer-motion@12.23.12:
+    dependencies:
+      motion-dom: 12.23.12
+      motion-utils: 12.23.6
+      tslib: 2.8.1
+
   fs-extra@10.1.0:
     dependencies:
       graceful-fs: 4.2.11
@@ -9027,6 +9065,8 @@ snapshots:
 
   he@1.2.0: {}
 
+  hey-listen@1.0.8: {}
+
   highlight.js@11.10.0: {}
 
   htm@3.1.1: {}
@@ -9521,6 +9561,24 @@ snapshots:
 
   moment@2.30.1: {}
 
+  motion-dom@12.23.12:
+    dependencies:
+      motion-utils: 12.23.6
+
+  motion-utils@12.23.6: {}
+
+  motion-v@1.7.4(@vueuse/core@10.11.1(vue@3.5.12(typescript@5.3.3)))(vue@3.5.12(typescript@5.3.3)):
+    dependencies:
+      '@vueuse/core': 10.11.1(vue@3.5.12(typescript@5.3.3))
+      framer-motion: 12.23.12
+      hey-listen: 1.0.8
+      motion-dom: 12.23.12
+      vue: 3.5.12(typescript@5.3.3)
+    transitivePeerDependencies:
+      - '@emotion/is-prop-valid'
+      - react
+      - react-dom
+
   mpd-parser@0.22.1:
     dependencies:
       '@babel/runtime': 7.26.0

+ 4 - 0
src/api/pms/iotrhdailyreport/index.ts

@@ -47,6 +47,10 @@ export const IotRhDailyReportApi = {
     return await request.get({ url: `/pms/iot-rh-daily-report/statistics`, params })
   },
 
+  getIotRhDailyReportSummaryPolyline: async (params: any) => {
+    return await request.get({ url: `/pms/iot-rh-daily-report/polylineStatistics`, params })
+  },
+
   // 累计工作量统计
   totalWorkload: async (params: any) => {
     return await request.get({ url: `/pms/iot-rh-daily-report/totalWorkload`, params })

+ 115 - 25
src/views/pms/iotrhdailyreport/summary.vue

@@ -5,6 +5,8 @@ import { IotRhDailyReportApi } from '@/api/pms/iotrhdailyreport'
 import { useDebounceFn } from '@vueuse/core'
 import CountTo from '@/components/count-to1.vue'
 
+import { Motion, AnimatePresence } from 'motion-v'
+
 import { rangeShortcuts } from '@/utils/formatTime'
 
 interface Query {
@@ -78,7 +80,8 @@ const getTotal = useDebounceFn(async () => {
     let res1: any[]
     if (query.value.createTime.length !== 0) {
       res1 = await IotRhDailyReportApi.rhDailyReportStatistics({
-        createTime: query.value.createTime
+        createTime: query.value.createTime,
+        deptId: query.value.deptId
       })
 
       totalWork.value.totalCount = res1[0].count
@@ -173,7 +176,43 @@ const getList = useDebounceFn(async () => {
   }
 }, 1000)
 
+const tab = ref<'表格' | '看板'>('表格')
+
+const currentTab = ref<'表格' | '看板'>('表格')
+
+const deptName = ref('瑞恒兴域')
+
+const direction = ref<'left' | 'right'>('right')
+
+watch(
+  () => tab.value,
+  (val) => {
+    direction.value = val === '看板' ? 'right' : 'left'
+    nextTick(() => {
+      currentTab.value = val
+    })
+  },
+  {
+    immediate: true
+  }
+)
+
+const chartRef = ref<HTMLDivElement | null>(null)
+let chart: echarts.ECharts | null = null
+
+let chartLoading = ref(false)
+
+const getChart = useDebounceFn(async () => {
+  chartLoading.value = true
+
+  // try {
+  //   const res =
+  // } finally {
+  // }
+}, 1000)
+
 const handleDeptNodeClick = (node: any) => {
+  deptName.value = node.name
   query.value.deptId = node.id
   handleQuery()
 }
@@ -213,7 +252,7 @@ onMounted(() => {
     <div class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow p-4">
       <DeptTree2 :deptId="id" @node-click="handleDeptNodeClick" />
     </div>
-    <div class="grid grid-rows-[62px_164px_1fr] h-full gap-5">
+    <div class="grid grid-rows-[62px_164px_1fr] h-full gap-4">
       <el-form
         size="default"
         class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-8 gap-8 flex items-center justify-between"
@@ -260,7 +299,7 @@ onMounted(() => {
         <div
           v-for="info in totalWorkKeys"
           :key="info[0]"
-          class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow p-4 flex flex-col items-center justify-center gap-2"
+          class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow p-1 flex flex-col items-center justify-center gap-1"
         >
           <div class="size-7.5" :class="info[3]"></div>
           <count-to class="text-2xl font-medium" :start-val="0" :end-val="totalWork[info[0]]">
@@ -270,33 +309,84 @@ onMounted(() => {
           <div class="text-sm font-medium text-[var(--el-text-color-regular)]">{{ info[2] }}</div>
         </div>
       </div>
-      <div class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow pt-4 px-8">
-        <el-table
-          v-loading="listLoading"
-          :data="list"
-          :stripe="true"
-          :style="{ width: '100%' }"
-          max-height="600"
-          class="min-h-143"
-          show-overflow-tooltip
-        >
-          <el-table-column
-            v-for="item in columns(type)"
-            :key="item.prop"
-            :label="item.label"
-            :prop="item.prop"
-            align="center"
-            :formatter="formatter"
-          />
-        </el-table>
-
-        <!-- <Pagination
+      <div
+        class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-8 py-4 grid grid-rows-[48px_1fr] gap-2"
+      >
+        <div class="flex items-center justify-between">
+          <el-button-group>
+            <el-button
+              size="default"
+              :type="tab === '表格' ? 'primary' : 'default'"
+              @click="tab = '表格'"
+              >表格
+            </el-button>
+            <el-button
+              size="default"
+              :type="tab === '看板' ? 'primary' : 'default'"
+              @click="tab = '看板'"
+              >看板
+            </el-button>
+          </el-button-group>
+          <h3 class="text-xl font-medium">{{ `${deptName}-${tab}` }}</h3>
+          <el-button size="default" type="primary">导出</el-button>
+        </div>
+        <el-auto-resizer>
+          <template #default="{ height, width }">
+            <Motion
+              as="div"
+              :style="{ position: 'relative', overflow: 'hidden' }"
+              :animate="{ height: `${height + 1}px`, width: `${width}px` }"
+              :transition="{ type: 'spring', stiffness: 200, damping: 25, duration: 0.3 }"
+            >
+              <AnimatePresence :initial="false" mode="sync">
+                <Motion
+                  :key="tab"
+                  as="div"
+                  :initial="{ x: direction === 'left' ? '-100%' : '100%', opacity: 0 }"
+                  :animate="{ x: '0%', opacity: 1 }"
+                  :exit="{ x: direction === 'left' ? '50%' : '-50%', opacity: 0 }"
+                  :transition="{ type: 'tween', stiffness: 300, damping: 30, duration: 0.3 }"
+                  :style="{ position: 'absolute', left: 0, right: 0, top: 0 }"
+                >
+                  <div :style="{ width: `${width}px`, height: `${height}px` }">
+                    <el-table
+                      v-if="currentTab === '表格'"
+                      v-loading="listLoading"
+                      :data="list"
+                      :stripe="true"
+                      :width="width"
+                      :max-height="height"
+                      show-overflow-tooltip
+                    >
+                      <el-table-column
+                        v-for="item in columns(type)"
+                        :key="item.prop"
+                        :label="item.label"
+                        :prop="item.prop"
+                        align="center"
+                        :formatter="formatter"
+                      />
+                    </el-table>
+                    <div
+                      ref="chartRef"
+                      v-else
+                      :style="{ width: `${width}px`, height: `${height}px` }"
+                    >
+                    </div>
+                  </div>
+                </Motion>
+              </AnimatePresence>
+            </Motion>
+          </template>
+
+          <!-- <Pagination
           class="mt-8"
           :total="total"
           v-model:page="query.pageNo"
           v-model:limit="query.pageSize"
           @pagination="getList"
         /> -->
+        </el-auto-resizer>
       </div>
     </div>
   </div>
@@ -312,7 +402,7 @@ onMounted(() => {
   border-top-left-radius: 8px;
 
   .el-table__cell {
-    height: 52px;
+    height: 40px;
   }
 
   .el-table__header-wrapper {