perf:工作台页面展示优化
This commit is contained in:
parent
c02c6eab68
commit
8e986bfa5a
@ -1,9 +1,5 @@
|
||||
import request from '@/config/axios'
|
||||
import type { WorkplaceTotal, Project, Dynamic, Team, RadarData, Shortcuts } from './types'
|
||||
|
||||
export const getCountApi = (): Promise<IResponse<WorkplaceTotal>> => {
|
||||
return request.get({ url: '/vadmin/workplace/total' })
|
||||
}
|
||||
import type { Project, Dynamic, Team, RadarData, Shortcuts } from './types'
|
||||
|
||||
export const getProjectApi = (): Promise<IResponse<Project>> => {
|
||||
return request.get({ url: '/vadmin/workplace/project' })
|
||||
|
@ -1,9 +1,3 @@
|
||||
export type WorkplaceTotal = {
|
||||
project: number
|
||||
access: number
|
||||
todo: number
|
||||
}
|
||||
|
||||
export type Project = {
|
||||
name: string
|
||||
icon: string
|
||||
|
@ -22,6 +22,9 @@ export interface UserState {
|
||||
gender?: string
|
||||
roles?: Recordable[]
|
||||
create_datetime?: string
|
||||
is_reset_password?: boolean
|
||||
last_login?: string
|
||||
last_ip?: string
|
||||
}
|
||||
|
||||
export interface AuthState {
|
||||
|
@ -108,3 +108,128 @@ export function toAnyString() {
|
||||
})
|
||||
return str
|
||||
}
|
||||
|
||||
/**
|
||||
* 小数转折扣
|
||||
* 例子:0.85 -> 8.5折
|
||||
* 例子:0.5 -> 5折
|
||||
*/
|
||||
export const convertToDiscount = (decimal: number | undefined): string => {
|
||||
if (decimal === undefined) {
|
||||
return ''
|
||||
}
|
||||
const discount = decimal * 10
|
||||
if (discount === 10) {
|
||||
return '无折扣'
|
||||
}
|
||||
return discount % 1 === 0 ? `${discount}折` : `${discount.toFixed(1)}折`
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前时间
|
||||
* 返回:yyyy-MM-dd HH:mm:ss
|
||||
*/
|
||||
export const getCurrentDateTime = (): string => {
|
||||
const now: Date = new Date()
|
||||
|
||||
const year: number = now.getFullYear()
|
||||
const month: number = now.getMonth() + 1
|
||||
const day: number = now.getDate()
|
||||
const hours: number = now.getHours()
|
||||
const minutes: number = now.getMinutes()
|
||||
const seconds: number = now.getSeconds()
|
||||
|
||||
// 格式化为字符串
|
||||
const formattedDateTime = `${year}-${padZero(month)}-${padZero(day)} ${padZero(hours)}:${padZero(
|
||||
minutes
|
||||
)}:${padZero(seconds)}`
|
||||
|
||||
return formattedDateTime
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前日期
|
||||
* 返回:yyyy-MM-dd HH:mm:ss
|
||||
*/
|
||||
export const getCurrentDate = (): string => {
|
||||
const now: Date = new Date()
|
||||
|
||||
const year: number = now.getFullYear()
|
||||
const month: number = now.getMonth() + 1
|
||||
const day: number = now.getDate()
|
||||
|
||||
// 格式化为字符串
|
||||
const formattedDate = `${year}-${padZero(month)}-${padZero(day)}`
|
||||
|
||||
return formattedDate
|
||||
}
|
||||
|
||||
// 辅助函数:在数字小于10时,在前面补零
|
||||
export const padZero = (num: number): string => {
|
||||
return num < 10 ? `0${num}` : `${num}`
|
||||
}
|
||||
|
||||
// 将base64编码的字符串转换为文件
|
||||
export const base64ToFile = (dataURI, filename): File => {
|
||||
const arr = dataURI.split(',')
|
||||
const mime = arr[0].match(/:(.*?);/)[1]
|
||||
const bstr = atob(arr[1])
|
||||
let n = bstr.length
|
||||
const u8arr = new Uint8Array(n)
|
||||
while (n--) {
|
||||
u8arr[n] = bstr.charCodeAt(n)
|
||||
}
|
||||
return new File([u8arr], filename, { type: mime })
|
||||
}
|
||||
|
||||
// 根据当前时间获取祝福语
|
||||
export const getGreeting = (): string => {
|
||||
const now = new Date()
|
||||
const hour = now.getHours()
|
||||
|
||||
if (hour >= 6 && hour < 10) {
|
||||
return '早上好'
|
||||
} else if (hour >= 10 && hour < 13) {
|
||||
return '中午好'
|
||||
} else if (hour >= 13 && hour < 18) {
|
||||
return '下午好'
|
||||
} else {
|
||||
return '晚上好'
|
||||
}
|
||||
}
|
||||
|
||||
// 获取当前星期几
|
||||
export const getDayOfWeek = (): string => {
|
||||
const daysOfWeek: string[] = [
|
||||
'星期日',
|
||||
'星期一',
|
||||
'星期二',
|
||||
'星期三',
|
||||
'星期四',
|
||||
'星期五',
|
||||
'星期六'
|
||||
]
|
||||
const date: Date = new Date()
|
||||
const dayOfWeekIndex: number = date.getDay()
|
||||
return daysOfWeek[dayOfWeekIndex]
|
||||
}
|
||||
|
||||
// 数字转金额
|
||||
// 作者:时光足迹
|
||||
// 链接:https://juejin.cn/post/7028086399601475591
|
||||
// 来源:稀土掘金
|
||||
export const formatMoney = (amount, currency = true): string => {
|
||||
const formatter = new Intl.NumberFormat('zh-CN', {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
useGrouping: true
|
||||
})
|
||||
|
||||
const formattedAmount = formatter.format(amount)
|
||||
|
||||
if (currency) {
|
||||
return `¥${formattedAmount}`
|
||||
}
|
||||
|
||||
return formattedAmount
|
||||
}
|
||||
|
@ -3,27 +3,19 @@ import { useTimeAgo } from '@/hooks/web/useTimeAgo'
|
||||
import { ElRow, ElCol, ElSkeleton, ElCard, ElDivider, ElLink } from 'element-plus'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
import { CountTo } from '@/components/CountTo'
|
||||
import { formatTime } from '@/utils'
|
||||
import { formatTime, getGreeting, getCurrentDate, getDayOfWeek } from '@/utils'
|
||||
import { Highlight } from '@/components/Highlight'
|
||||
import {
|
||||
getCountApi,
|
||||
getProjectApi,
|
||||
getDynamicApi,
|
||||
getTeamApi,
|
||||
getShortcutsApi
|
||||
} from '@/api/dashboard/workplace'
|
||||
import type {
|
||||
WorkplaceTotal,
|
||||
Project,
|
||||
Dynamic,
|
||||
Team,
|
||||
Shortcuts
|
||||
} from '@/api/dashboard/workplace/types'
|
||||
import type { Project, Dynamic, Team, Shortcuts } from '@/api/dashboard/workplace/types'
|
||||
import avatar from '@/assets/imgs/avatar.jpg'
|
||||
import { useAuthStoreWithOut } from '@/store/modules/auth'
|
||||
import { useAuthStore } from '@/store/modules/auth'
|
||||
|
||||
const authStore = useAuthStoreWithOut()
|
||||
const authStore = useAuthStore()
|
||||
|
||||
const loading = ref(true)
|
||||
|
||||
@ -31,20 +23,6 @@ const toLink = (link: string) => {
|
||||
window.open(link)
|
||||
}
|
||||
|
||||
// 获取统计数
|
||||
let totalSate = reactive<WorkplaceTotal>({
|
||||
project: 0,
|
||||
access: 0,
|
||||
todo: 0
|
||||
})
|
||||
|
||||
const getCount = async () => {
|
||||
const res = await getCountApi().catch(() => {})
|
||||
if (res) {
|
||||
totalSate = Object.assign(totalSate, res.data)
|
||||
}
|
||||
}
|
||||
|
||||
let projects = reactive<Project[]>([])
|
||||
|
||||
// 获取项目数
|
||||
@ -88,7 +66,7 @@ const getTeam = async () => {
|
||||
}
|
||||
|
||||
const getAllApi = async () => {
|
||||
await Promise.all([getCount(), getProject(), getDynamic(), getTeam()])
|
||||
await Promise.all([getProject(), getDynamic(), getTeam()])
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
@ -113,10 +91,10 @@ const user = computed(() => authStore.getUser)
|
||||
/>
|
||||
<div class="truncate">
|
||||
<div class="text-20px text-700 truncate">
|
||||
{{ t('workplace.goodMorning') }},{{ user.name }},{{ t('workplace.happyDay') }}
|
||||
{{ getGreeting() }},{{ user.name }},{{ t('workplace.happyDay') }}
|
||||
</div>
|
||||
<div class="mt-10px text-14px text-gray-500">
|
||||
{{ t('workplace.toady') }},20℃ - 32℃!
|
||||
{{ getCurrentDate() }},{{ getDayOfWeek() }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -124,33 +102,8 @@ const user = computed(() => authStore.getUser)
|
||||
<ElCol :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
|
||||
<div class="flex h-70px items-center justify-end <sm:mt-20px">
|
||||
<div class="px-8px text-right">
|
||||
<div class="text-14px text-gray-400 mb-20px">{{ t('workplace.project') }}</div>
|
||||
<CountTo
|
||||
class="text-20px"
|
||||
:start-val="0"
|
||||
:end-val="totalSate.project"
|
||||
:duration="2600"
|
||||
/>
|
||||
</div>
|
||||
<ElDivider direction="vertical" />
|
||||
<div class="px-8px text-right">
|
||||
<div class="text-14px text-gray-400 mb-20px">{{ t('workplace.toDo') }}</div>
|
||||
<CountTo
|
||||
class="text-20px"
|
||||
:start-val="0"
|
||||
:end-val="totalSate.todo"
|
||||
:duration="2600"
|
||||
/>
|
||||
</div>
|
||||
<ElDivider direction="vertical" border-style="dashed" />
|
||||
<div class="px-8px text-right">
|
||||
<div class="text-14px text-gray-400 mb-20px">{{ t('workplace.access') }}</div>
|
||||
<CountTo
|
||||
class="text-20px"
|
||||
:start-val="0"
|
||||
:end-val="totalSate.access"
|
||||
:duration="2600"
|
||||
/>
|
||||
<div class="text-14px text-gray-400 mb-20px">最近登录时间</div>
|
||||
<span class="text-20px">{{ user.last_login?.split(' ')[0] }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</ElCol>
|
||||
|
@ -19,23 +19,13 @@ app = APIRouter()
|
||||
###########################################################
|
||||
# 工作区管理
|
||||
###########################################################
|
||||
@app.get("/total", summary="获取统计")
|
||||
async def get_total(auth: Auth = Depends(AllUserAuth())):
|
||||
data = {
|
||||
"project": 40,
|
||||
"access": await LoginRecordDal(auth.db).get_count(),
|
||||
"todo": 10
|
||||
}
|
||||
return SuccessResponse(data)
|
||||
|
||||
|
||||
@app.get("/project", summary="获取项目")
|
||||
async def get_project():
|
||||
data = [
|
||||
{
|
||||
"name": 'Mysql',
|
||||
"icon": 'vscode-icons:file-type-mysql',
|
||||
"message": 'MySQL 是最流行的关系型数据库管理系统',
|
||||
"message": '最流行的关系型数据库管理系统',
|
||||
"personal": 'kinit',
|
||||
"link": "https://www.mysql.com/",
|
||||
"time": datetime.datetime.now().strftime("%Y-%m-%d")
|
||||
@ -59,7 +49,7 @@ async def get_project():
|
||||
{
|
||||
"name": 'Element-plus',
|
||||
"icon": 'logos:element',
|
||||
"message": '基于 Vue3,面向设计师和开发者的组件库',
|
||||
"message": '面向设计师和开发者的组件库',
|
||||
"personal": 'kinit',
|
||||
"link": "https://element-plus.org/zh-CN/",
|
||||
"time": datetime.datetime.now().strftime("%Y-%m-%d")
|
||||
|
Loading…
x
Reference in New Issue
Block a user