From da47a3349dcfd87db23ab8e64fbf35fe1aea5685 Mon Sep 17 00:00:00 2001 From: 潘志宝 <979469083@qq.com> Date: 星期四, 14 十一月 2024 16:52:21 +0800 Subject: [PATCH] 预测项数据 --- src/views/Home/Index.vue | 418 ++++++++++------------------------------------------------- 1 files changed, 72 insertions(+), 346 deletions(-) diff --git a/src/views/Home/Index.vue b/src/views/Home/Index.vue index 18d701c..aa64a85 100644 --- a/src/views/Home/Index.vue +++ b/src/views/Home/Index.vue @@ -1,370 +1,96 @@ <template> <div> - <el-card shadow="never"> - <el-skeleton :loading="loading" animated> - <el-row :gutter="16" justify="space-between"> - <el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24"> - <div class="flex items-center"> - <el-avatar :src="avatar" :size="70" class="mr-16px"> - <img src="@/assets/imgs/avatar.gif" alt="" /> - </el-avatar> - <div> - <div class="text-20px"> - {{ t('workplace.welcome') }} {{ username }} {{ t('workplace.happyDay') }} - </div> - <div class="mt-10px text-14px text-gray-500"> - {{ t('workplace.toady') }},20℃ - 32℃! - </div> - </div> - </div> - </el-col> - <el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24"> - <div class="h-70px flex items-center justify-end lt-sm:mt-10px"> - <div class="px-8px text-right"> - <div class="mb-16px text-14px text-gray-400">{{ t('workplace.project') }}</div> - <CountTo - class="text-20px" - :start-val="0" - :end-val="totalSate.project" - :duration="2600" - /> - </div> - <el-divider direction="vertical" /> - <div class="px-8px text-right"> - <div class="mb-16px text-14px text-gray-400">{{ t('workplace.toDo') }}</div> - <CountTo - class="text-20px" - :start-val="0" - :end-val="totalSate.todo" - :duration="2600" - /> - </div> - <el-divider direction="vertical" border-style="dashed" /> - <div class="px-8px text-right"> - <div class="mb-16px text-14px text-gray-400">{{ t('workplace.access') }}</div> - <CountTo - class="text-20px" - :start-val="0" - :end-val="totalSate.access" - :duration="2600" - /> - </div> - </div> - </el-col> - </el-row> - </el-skeleton> - </el-card> + <h1>IAILAB 平台主页</h1> </div> + <el-skeleton :loading="loading" animated> + <div id="app" v-for="(item, index) in appList" :key="`dynamics-${index}`"> + <div class="card" @click="gotoApp(item)"> + <img :src="item.icon" style="width: 100px; height: 100px" /> + <div> + {{item.appName}} + </div> + </div> + </div> + </el-skeleton> - <el-row class="mt-8px" :gutter="8" justify="space-between"> - <el-col :xl="16" :lg="16" :md="24" :sm="24" :xs="24" class="mb-8px"> - <el-card shadow="never"> - <template #header> - <div class="h-3 flex justify-between"> - <span>{{ t('workplace.project') }}</span> - <el-link - type="primary" - :underline="false" - href="https://xxxx" - target="_blank" - > - {{ t('action.more') }} - </el-link> - </div> - </template> - <el-skeleton :loading="loading" animated> - <el-row> - <el-col - v-for="(item, index) in projects" - :key="`card-${index}`" - :xl="8" - :lg="8" - :md="8" - :sm="24" - :xs="24" - > - <el-card shadow="hover" class="mr-5px mt-5px"> - <div class="flex items-center"> - <Icon :icon="item.icon" :size="25" class="mr-8px" /> - <span class="text-16px">{{ item.name }}</span> - </div> - <div class="mt-12px text-9px text-gray-400">{{ t(item.message) }}</div> - <div class="mt-12px flex justify-between text-12px text-gray-400"> - <span>{{ item.personal }}</span> - <span>{{ formatTime(item.time, 'yyyy-MM-dd') }}</span> - </div> - </el-card> - </el-col> - </el-row> - </el-skeleton> - </el-card> - - <el-card shadow="never" class="mt-8px"> - <el-skeleton :loading="loading" animated> - <el-row :gutter="20" justify="space-between"> - <el-col :xl="10" :lg="10" :md="24" :sm="24" :xs="24"> - <el-card shadow="hover" class="mb-8px"> - <el-skeleton :loading="loading" animated> - <Echart :options="pieOptionsData" :height="280" /> - </el-skeleton> - </el-card> - </el-col> - <el-col :xl="14" :lg="14" :md="24" :sm="24" :xs="24"> - <el-card shadow="hover" class="mb-8px"> - <el-skeleton :loading="loading" animated> - <Echart :options="barOptionsData" :height="280" /> - </el-skeleton> - </el-card> - </el-col> - </el-row> - </el-skeleton> - </el-card> - </el-col> - <el-col :xl="8" :lg="8" :md="24" :sm="24" :xs="24" class="mb-8px"> - <el-card shadow="never"> - <template #header> - <div class="h-3 flex justify-between"> - <span>{{ t('workplace.shortcutOperation') }}</span> - </div> - </template> - <el-skeleton :loading="loading" animated> - <el-row> - <el-col v-for="item in shortcut" :key="`team-${item.name}`" :span="8" class="mb-8px"> - <div class="flex items-center"> - <Icon :icon="item.icon" class="mr-8px" /> - <el-link type="default" :underline="false" @click="setWatermark(item.name)"> - {{ item.name }} - </el-link> - </div> - </el-col> - </el-row> - </el-skeleton> - </el-card> - <el-card shadow="never" class="mt-8px"> - <template #header> - <div class="h-3 flex justify-between"> - <span>{{ t('workplace.notice') }}</span> - <el-link type="primary" :underline="false">{{ t('action.more') }}</el-link> - </div> - </template> - <el-skeleton :loading="loading" animated> - <div v-for="(item, index) in notice" :key="`dynamics-${index}`"> - <div class="flex items-center"> - <el-avatar :src="avatar" :size="35" class="mr-16px"> - <img src="@/assets/imgs/avatar.gif" alt="" /> - </el-avatar> - <div> - <div class="text-14px"> - <Highlight :keys="item.keys.map((v) => t(v))"> - {{ item.type }} : {{ item.title }} - </Highlight> - </div> - <div class="mt-16px text-12px text-gray-400"> - {{ formatTime(item.date, 'yyyy-MM-dd') }} - </div> - </div> - </div> - <el-divider /> - </div> - </el-skeleton> - </el-card> - </el-col> - </el-row> </template> <script lang="ts" setup> -import { set } from 'lodash-es' -import { EChartsOption } from 'echarts' -import { formatTime } from '@/utils' -import { useUserStore } from '@/store/modules/user' -import { useWatermark } from '@/hooks/web/useWatermark' -import type { WorkplaceTotal, Project, Notice, Shortcut } from './types' -import { pieOptions, barOptions } from './echarts-data' +import * as AppApi from '@/api/system/app' +import {Apps} from "@/views/Home/types"; +import {CACHE_KEY, useCache} from "@/hooks/web/useCache"; +import * as authUtil from "@/utils/auth"; + defineOptions({ name: 'Home' }) -const { t } = useI18n() -const userStore = useUserStore() -const { setWatermark } = useWatermark() +const { wsCache } = useCache() + const loading = ref(true) -const avatar = userStore.getUser.avatar -const username = userStore.getUser.nickname -const pieOptionsData = reactive<EChartsOption>(pieOptions) as EChartsOption -// 获取统计数 -let totalSate = reactive<WorkplaceTotal>({ - project: 0, - access: 0, - todo: 0 -}) -const getCount = async () => { - const data = { - project: 40, - access: 2340, - todo: 10 - } - totalSate = Object.assign(totalSate, data) +let appList = reactive<Apps[]>([]) + +const getAppList = async () => { + const data = await AppApi.getAppList() + appList = Object.assign(appList, data) } -// 获取项目数 -let projects = reactive<Project[]>([]) -const getProject = async () => { - const data = [ - { - name: 'iailab-plat', - icon: 'akar-icons:github-fill', - message: 'https://xxxx/iailab-plat', - personal: 'Spring Boot 单体架构', - time: new Date() - }, - { - name: 'iailab-plat-ui-vue3', - icon: 'logos:vue', - message: 'https://xxxx/iailab-plat-ui-vue3', - personal: 'Vue3 + element-plus', - time: new Date() - }, - { - name: 'iailab-plat-ui-vue2', - icon: 'logos:vue', - message: 'https://xxxx/iailab-plat-ui-vue2', - personal: 'Vue2 + element-ui', - time: new Date() - } - ] - projects = Object.assign(projects, data) -} - -// 获取通知公告 -let notice = reactive<Notice[]>([]) -const getNotice = async () => { - const data = [ - { - title: '系统支持 JDK 8/17/21,Vue 2/3', - type: '通知', - keys: ['通知', '8', '17', '21', '2', '3'], - date: new Date() - }, - { - title: '后端提供 Spring Boot 2.7/3.2 + Cloud 双架构', - type: '公告', - keys: ['公告', 'Boot', 'Cloud'], - date: new Date() - }, - { - title: '全部开源,个人与企业可 100% 直接使用,无需授权', - type: '通知', - keys: ['通知', '无需授权'], - date: new Date() - }, - { - title: '国内使用最广泛的快速开发平台,超 300+ 人贡献', - type: '公告', - keys: ['公告', '最广泛'], - date: new Date() - } - ] - notice = Object.assign(notice, data) -} - -// 获取快捷入口 -let shortcut = reactive<Shortcut[]>([]) - -const getShortcut = async () => { - const data = [ - { - name: 'Github', - icon: 'akar-icons:github-fill', - url: 'github.io' - }, - { - name: 'Vue', - icon: 'logos:vue', - url: 'vuejs.org' - }, - { - name: 'Vite', - icon: 'vscode-icons:file-type-vite', - url: 'https://vitejs.dev/' - }, - { - name: 'Angular', - icon: 'logos:angular-icon', - url: 'github.io' - }, - { - name: 'React', - icon: 'logos:react', - url: 'github.io' - }, - { - name: 'Webpack', - icon: 'logos:webpack', - url: 'github.io' - } - ] - shortcut = Object.assign(shortcut, data) -} - -// 用户来源 -const getUserAccessSource = async () => { - const data = [ - { value: 335, name: 'analysis.directAccess' }, - { value: 310, name: 'analysis.mailMarketing' }, - { value: 234, name: 'analysis.allianceAdvertising' }, - { value: 135, name: 'analysis.videoAdvertising' }, - { value: 1548, name: 'analysis.searchEngines' } - ] - set( - pieOptionsData, - 'legend.data', - data.map((v) => t(v.name)) - ) - pieOptionsData!.series![0].data = data.map((v) => { - return { - name: t(v.name), - value: v.value - } - }) -} -const barOptionsData = reactive<EChartsOption>(barOptions) as EChartsOption - -// 周活跃量 -const getWeeklyUserActivity = async () => { - const data = [ - { value: 13253, name: 'analysis.monday' }, - { value: 34235, name: 'analysis.tuesday' }, - { value: 26321, name: 'analysis.wednesday' }, - { value: 12340, name: 'analysis.thursday' }, - { value: 24643, name: 'analysis.friday' }, - { value: 1322, name: 'analysis.saturday' }, - { value: 1324, name: 'analysis.sunday' } - ] - set( - barOptionsData, - 'xAxis.data', - data.map((v) => t(v.name)) - ) - set(barOptionsData, 'series', [ - { - name: t('analysis.activeQuantity'), - data: data.map((v) => v.value), - type: 'bar' - } - ]) +const getAppMenuList = async (id) => { + const data = await AppApi.getAppMenuList(id) + let userInfo = wsCache.get(CACHE_KEY.USER) + userInfo.menus = data + wsCache.set(CACHE_KEY.USER, userInfo) + wsCache.set(CACHE_KEY.ROLE_ROUTERS, data) + window.location.href = '/plat/index' } const getAllApi = async () => { await Promise.all([ - getCount(), - getProject(), - getNotice(), - getShortcut(), - getUserAccessSource(), - getWeeklyUserActivity() + getAppList() ]) loading.value = false } getAllApi() + +// 进入应用 +const gotoApp = async (item) => { + let id = item.id + let type = item.type + if(type === 0) { + getAppMenuList(id) + } else { + const data = await AppApi.getAppMenuList(id) + let userInfo = wsCache.get(CACHE_KEY.USER) + userInfo.menus = data + wsCache.set(CACHE_KEY.USER, userInfo) + wsCache.set(CACHE_KEY.ROLE_ROUTERS, data) + // await OAuth2Login(formData.value) + // window.open(item.appDomain + '/login?appid=' + item.id + "&username=" + authUtil.getLoginForm().username, '_blank') + window.open(item.appDomain + '/index', '_blank') + } +} + </script> + +<style lang="scss" scoped> +#app{ + width: 300px; + height: 200px; + display: inline-block; + background: transparent; +} +.card{ + border: thin dashed gainsboro; + width: 150px; + height: 120px; + padding: 30px; + text-align: center; + justify-content: center; + font-size: 15px; + font-weight: bolder; + color: blue; + background: aliceblue; + border-radius: 10px; +} +</style> -- Gitblit v1.9.3