zhang_li
12 months ago
13 changed files with 1249 additions and 401 deletions
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 6.2 KiB |
After Width: | Height: | Size: 5.3 KiB |
@ -0,0 +1,381 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<el-card shadow="never"> |
||||
|
<el-skeleton :loading="loading" animated> |
||||
|
<el-row :gutter="20" justify="space-between"> |
||||
|
<el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24"> |
||||
|
<div class="flex items-center"> |
||||
|
<img :src="avatar" alt="" class="mr-20px h-70px w-70px rounded-[50%]" /> |
||||
|
<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-20px 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-20px 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-20px 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> |
||||
|
</div> |
||||
|
|
||||
|
<el-row class="mt-5px" :gutter="20" justify="space-between"> |
||||
|
<el-col :xl="16" :lg="16" :md="24" :sm="24" :xs="24" class="mb-10px"> |
||||
|
<el-card shadow="never"> |
||||
|
<template #header> |
||||
|
<div class="h-3 flex justify-between"> |
||||
|
<span>{{ t('workplace.project') }}</span> |
||||
|
<el-link type="primary" :underline="false">{{ 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"> |
||||
|
<div class="flex items-center"> |
||||
|
<Icon :icon="item.icon" :size="25" class="mr-10px" /> |
||||
|
<span class="text-16px">{{ item.name }}</span> |
||||
|
</div> |
||||
|
<div class="mt-15px text-14px text-gray-400">{{ t(item.message) }}</div> |
||||
|
<div class="mt-20px 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-5px"> |
||||
|
<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-10px"> |
||||
|
<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-10px"> |
||||
|
<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-10px"> |
||||
|
<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-10px"> |
||||
|
<div class="flex items-center"> |
||||
|
<Icon :icon="item.icon" class="mr-10px" /> |
||||
|
<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-10px"> |
||||
|
<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"> |
||||
|
<img :src="avatar" alt="" class="mr-20px h-35px w-35px rounded-[50%]" /> |
||||
|
<div> |
||||
|
<div class="text-14px"> |
||||
|
<Highlight :keys="item.keys.map((v) => t(v))"> |
||||
|
{{ item.type }} : {{ item.title }} |
||||
|
</Highlight> |
||||
|
</div> |
||||
|
<div class="mt-15px 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 avatarImg from '@/assets/imgs/avatar.gif' |
||||
|
import type { WorkplaceTotal, Project, Notice, Shortcut } from './types' |
||||
|
import { pieOptions, barOptions } from './echarts-data' |
||||
|
|
||||
|
defineOptions({ name: 'Home' }) |
||||
|
|
||||
|
const { t } = useI18n() |
||||
|
const userStore = useUserStore() |
||||
|
const { setWatermark } = useWatermark() |
||||
|
const loading = ref(true) |
||||
|
const avatar = userStore.getUser.avatar ? userStore.getUser.avatar : avatarImg |
||||
|
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 projects = reactive<Project[]>([]) |
||||
|
const getProject = async () => { |
||||
|
const data = [ |
||||
|
{ |
||||
|
name: 'Github', |
||||
|
icon: 'akar-icons:github-fill', |
||||
|
message: 'workplace.introduction', |
||||
|
personal: 'Archer', |
||||
|
time: new Date() |
||||
|
}, |
||||
|
{ |
||||
|
name: 'Vue', |
||||
|
icon: 'logos:vue', |
||||
|
message: 'workplace.introduction', |
||||
|
personal: 'Archer', |
||||
|
time: new Date() |
||||
|
}, |
||||
|
{ |
||||
|
name: 'Angular', |
||||
|
icon: 'logos:angular-icon', |
||||
|
message: 'workplace.introduction', |
||||
|
personal: 'Archer', |
||||
|
time: new Date() |
||||
|
}, |
||||
|
{ |
||||
|
name: 'React', |
||||
|
icon: 'logos:react', |
||||
|
message: 'workplace.introduction', |
||||
|
personal: 'Archer', |
||||
|
time: new Date() |
||||
|
}, |
||||
|
{ |
||||
|
name: 'Webpack', |
||||
|
icon: 'logos:webpack', |
||||
|
message: 'workplace.introduction', |
||||
|
personal: 'Archer', |
||||
|
time: new Date() |
||||
|
}, |
||||
|
{ |
||||
|
name: 'Vite', |
||||
|
icon: 'vscode-icons:file-type-vite', |
||||
|
message: 'workplace.introduction', |
||||
|
personal: 'Archer', |
||||
|
time: new Date() |
||||
|
} |
||||
|
] |
||||
|
projects = Object.assign(projects, data) |
||||
|
} |
||||
|
|
||||
|
// 获取通知公告 |
||||
|
let notice = reactive<Notice[]>([]) |
||||
|
const getNotice = async () => { |
||||
|
const data = [ |
||||
|
{ |
||||
|
title: '系统升级版本', |
||||
|
type: '通知', |
||||
|
keys: ['通知', '升级'], |
||||
|
date: new Date() |
||||
|
}, |
||||
|
{ |
||||
|
title: '系统凌晨维护', |
||||
|
type: '公告', |
||||
|
keys: ['公告', '维护'], |
||||
|
date: new Date() |
||||
|
}, |
||||
|
{ |
||||
|
title: '系统升级版本', |
||||
|
type: '通知', |
||||
|
keys: ['通知', '升级'], |
||||
|
date: new Date() |
||||
|
}, |
||||
|
{ |
||||
|
title: '系统凌晨维护', |
||||
|
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 getAllApi = async () => { |
||||
|
await Promise.all([ |
||||
|
getCount(), |
||||
|
getProject(), |
||||
|
getNotice(), |
||||
|
getShortcut(), |
||||
|
getUserAccessSource(), |
||||
|
getWeeklyUserActivity() |
||||
|
]) |
||||
|
loading.value = false |
||||
|
} |
||||
|
|
||||
|
getAllApi() |
||||
|
</script> |
@ -1,381 +1,14 @@ |
|||||
<template> |
<template> |
||||
<div> |
<div> |
||||
<el-card shadow="never"> |
<supplierIndex/> |
||||
<el-skeleton :loading="loading" animated> |
<warehouseKeeper v-hasRole="['role2']"/> |
||||
<el-row :gutter="20" justify="space-between"> |
<productWarehouseKeeper v-hasRole="['role3']"/> |
||||
<el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24"> |
<productionManager v-hasRole="['role4']"/> |
||||
<div class="flex items-center"> |
|
||||
<img :src="avatar" alt="" class="mr-20px h-70px w-70px rounded-[50%]" /> |
|
||||
<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-20px 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-20px 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-20px 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> |
|
||||
</div> |
|
||||
|
|
||||
<el-row class="mt-5px" :gutter="20" justify="space-between"> |
|
||||
<el-col :xl="16" :lg="16" :md="24" :sm="24" :xs="24" class="mb-10px"> |
|
||||
<el-card shadow="never"> |
|
||||
<template #header> |
|
||||
<div class="h-3 flex justify-between"> |
|
||||
<span>{{ t('workplace.project') }}</span> |
|
||||
<el-link type="primary" :underline="false">{{ 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"> |
|
||||
<div class="flex items-center"> |
|
||||
<Icon :icon="item.icon" :size="25" class="mr-10px" /> |
|
||||
<span class="text-16px">{{ item.name }}</span> |
|
||||
</div> |
|
||||
<div class="mt-15px text-14px text-gray-400">{{ t(item.message) }}</div> |
|
||||
<div class="mt-20px 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-5px"> |
|
||||
<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-10px"> |
|
||||
<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-10px"> |
|
||||
<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-10px"> |
|
||||
<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-10px"> |
|
||||
<div class="flex items-center"> |
|
||||
<Icon :icon="item.icon" class="mr-10px" /> |
|
||||
<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-10px"> |
|
||||
<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"> |
|
||||
<img :src="avatar" alt="" class="mr-20px h-35px w-35px rounded-[50%]" /> |
|
||||
<div> |
|
||||
<div class="text-14px"> |
|
||||
<Highlight :keys="item.keys.map((v) => t(v))"> |
|
||||
{{ item.type }} : {{ item.title }} |
|
||||
</Highlight> |
|
||||
</div> |
|
||||
<div class="mt-15px text-12px text-gray-400"> |
|
||||
{{ formatTime(item.date, 'yyyy-MM-dd') }} |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
<el-divider /> |
|
||||
</div> |
</div> |
||||
</el-skeleton> |
|
||||
</el-card> |
|
||||
</el-col> |
|
||||
</el-row> |
|
||||
</template> |
</template> |
||||
<script lang="ts" setup> |
<script lang="ts" setup> |
||||
import { set } from 'lodash-es' |
import supplierIndex from './components/supplierIndex.vue' |
||||
import { EChartsOption } from 'echarts' |
import warehouseKeeper from './components/warehouseKeeper.vue' |
||||
import { formatTime } from '@/utils' |
import productWarehouseKeeper from './components/productWarehouseKeeper.vue' |
||||
|
import productionManager from './components/productionManager.vue' |
||||
import { useUserStore } from '@/store/modules/user' |
|
||||
import { useWatermark } from '@/hooks/web/useWatermark' |
|
||||
import avatarImg from '@/assets/imgs/avatar.gif' |
|
||||
import type { WorkplaceTotal, Project, Notice, Shortcut } from './types' |
|
||||
import { pieOptions, barOptions } from './echarts-data' |
|
||||
|
|
||||
defineOptions({ name: 'Home' }) |
|
||||
|
|
||||
const { t } = useI18n() |
|
||||
const userStore = useUserStore() |
|
||||
const { setWatermark } = useWatermark() |
|
||||
const loading = ref(true) |
|
||||
const avatar = userStore.getUser.avatar ? userStore.getUser.avatar : avatarImg |
|
||||
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 projects = reactive<Project[]>([]) |
|
||||
const getProject = async () => { |
|
||||
const data = [ |
|
||||
{ |
|
||||
name: 'Github', |
|
||||
icon: 'akar-icons:github-fill', |
|
||||
message: 'workplace.introduction', |
|
||||
personal: 'Archer', |
|
||||
time: new Date() |
|
||||
}, |
|
||||
{ |
|
||||
name: 'Vue', |
|
||||
icon: 'logos:vue', |
|
||||
message: 'workplace.introduction', |
|
||||
personal: 'Archer', |
|
||||
time: new Date() |
|
||||
}, |
|
||||
{ |
|
||||
name: 'Angular', |
|
||||
icon: 'logos:angular-icon', |
|
||||
message: 'workplace.introduction', |
|
||||
personal: 'Archer', |
|
||||
time: new Date() |
|
||||
}, |
|
||||
{ |
|
||||
name: 'React', |
|
||||
icon: 'logos:react', |
|
||||
message: 'workplace.introduction', |
|
||||
personal: 'Archer', |
|
||||
time: new Date() |
|
||||
}, |
|
||||
{ |
|
||||
name: 'Webpack', |
|
||||
icon: 'logos:webpack', |
|
||||
message: 'workplace.introduction', |
|
||||
personal: 'Archer', |
|
||||
time: new Date() |
|
||||
}, |
|
||||
{ |
|
||||
name: 'Vite', |
|
||||
icon: 'vscode-icons:file-type-vite', |
|
||||
message: 'workplace.introduction', |
|
||||
personal: 'Archer', |
|
||||
time: new Date() |
|
||||
} |
|
||||
] |
|
||||
projects = Object.assign(projects, data) |
|
||||
} |
|
||||
|
|
||||
// 获取通知公告 |
|
||||
let notice = reactive<Notice[]>([]) |
|
||||
const getNotice = async () => { |
|
||||
const data = [ |
|
||||
{ |
|
||||
title: '系统升级版本', |
|
||||
type: '通知', |
|
||||
keys: ['通知', '升级'], |
|
||||
date: new Date() |
|
||||
}, |
|
||||
{ |
|
||||
title: '系统凌晨维护', |
|
||||
type: '公告', |
|
||||
keys: ['公告', '维护'], |
|
||||
date: new Date() |
|
||||
}, |
|
||||
{ |
|
||||
title: '系统升级版本', |
|
||||
type: '通知', |
|
||||
keys: ['通知', '升级'], |
|
||||
date: new Date() |
|
||||
}, |
|
||||
{ |
|
||||
title: '系统凌晨维护', |
|
||||
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 getAllApi = async () => { |
|
||||
await Promise.all([ |
|
||||
getCount(), |
|
||||
getProject(), |
|
||||
getNotice(), |
|
||||
getShortcut(), |
|
||||
getUserAccessSource(), |
|
||||
getWeeklyUserActivity() |
|
||||
]) |
|
||||
loading.value = false |
|
||||
} |
|
||||
|
|
||||
getAllApi() |
|
||||
</script> |
</script> |
||||
|
@ -0,0 +1,172 @@ |
|||||
|
<template> |
||||
|
<div class="row"> |
||||
|
<div class="data"> |
||||
|
<div class="small-data-item small-data-item1"> |
||||
|
<div class="small-data-item-txt"> |
||||
|
<div>今日到货计划(已发货)</div> |
||||
|
<div>22<span>单</span></div> |
||||
|
</div> |
||||
|
<img src="../../../assets/imgs/icon1.png" alt="" class="img" /> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
<div class="two-row mt-14px"> |
||||
|
<div class="data1 w-[50%]"> |
||||
|
<div class="title">呆滞库存预警</div> |
||||
|
<el-table :data="tableData" style="width: 100%" stripe height="240px"> |
||||
|
<el-table-column prop="title" label="标题" /> |
||||
|
<el-table-column prop="name" label="发布人" /> |
||||
|
<el-table-column prop="date" label="发布日期" /> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
<div class="data1 w-[50%] ml-14px"> |
||||
|
<div class="title">超期库存预警</div> |
||||
|
<el-table :data="tableData" style="width: 100%" stripe height="240px"> |
||||
|
<el-table-column prop="title" label="标题" /> |
||||
|
<el-table-column prop="name" label="发布人" /> |
||||
|
<el-table-column prop="date" label="发布日期" /> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="two-row mt-14px"> |
||||
|
<div class="data1 w-[50%]"> |
||||
|
<div class="title">高低储预警</div> |
||||
|
<el-table :data="tableData" style="width: 100%" stripe height="240px"> |
||||
|
<el-table-column prop="title" label="标题" /> |
||||
|
<el-table-column prop="name" label="发布人" /> |
||||
|
<el-table-column prop="date" label="发布日期" /> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
<div class="data1 w-[50%] ml-14px"> |
||||
|
<div class="title">待处理任务</div> |
||||
|
<el-table :data="tableData" style="width: 100%" stripe height="240px"> |
||||
|
<el-table-column prop="title" label="标题" /> |
||||
|
<el-table-column prop="name" label="发布人" /> |
||||
|
<el-table-column prop="date" label="发布日期" /> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script lang="ts" setup> |
||||
|
const tableData = [ |
||||
|
{ |
||||
|
date: '2016-05-03', |
||||
|
name: 'Tom', |
||||
|
title: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
}, |
||||
|
{ |
||||
|
date: '2016-05-02', |
||||
|
title: 'Tom', |
||||
|
name: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
}, |
||||
|
{ |
||||
|
date: '2016-05-04', |
||||
|
title: 'Tom', |
||||
|
name: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
}, |
||||
|
{ |
||||
|
date: '2016-05-01', |
||||
|
title: 'Tom', |
||||
|
name: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
}, |
||||
|
{ |
||||
|
date: '2016-05-01', |
||||
|
title: 'Tom', |
||||
|
name: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
}, |
||||
|
{ |
||||
|
date: '2016-05-01', |
||||
|
title: 'Tom', |
||||
|
name: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
} |
||||
|
] |
||||
|
|
||||
|
</script> |
||||
|
<style scoped lang="scss"> |
||||
|
.title { |
||||
|
padding-bottom: 10px; |
||||
|
border-bottom: 1px solid #dedede; |
||||
|
position: relative; |
||||
|
padding-left: 10px; |
||||
|
&::after { |
||||
|
content: ''; |
||||
|
position: absolute; |
||||
|
width: 4px; |
||||
|
height: 16px; |
||||
|
background: #3c7adf; |
||||
|
left: 0px; |
||||
|
top: 3px; |
||||
|
border-radius: 8px; |
||||
|
} |
||||
|
} |
||||
|
.data { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: space-between; |
||||
|
.small-data-item { |
||||
|
width:25%; |
||||
|
height: 90px; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
border-radius: 6px; |
||||
|
color: white; |
||||
|
padding: 0px 20px; |
||||
|
.small-data-item-txt { |
||||
|
flex: 1; |
||||
|
div { |
||||
|
&:nth-child(1) { |
||||
|
font-size: 14px; |
||||
|
|
||||
|
} |
||||
|
&:nth-child(2) { |
||||
|
font-size: 26px; |
||||
|
margin-top: 4px; |
||||
|
font-weight: bold; |
||||
|
span { |
||||
|
font-size: 14px; |
||||
|
padding-left: 6px; |
||||
|
font-weight: normal; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.img { |
||||
|
width: 40px; |
||||
|
opacity: 0.5; |
||||
|
} |
||||
|
} |
||||
|
.small-data-item1 { |
||||
|
background: linear-gradient(to left, #fd817d, #fcad80); |
||||
|
} |
||||
|
.small-data-item2 { |
||||
|
background: linear-gradient(to left, #46c6fa, #336bfe); |
||||
|
} |
||||
|
.small-data-item3 { |
||||
|
background: linear-gradient(to left, #96a6cc, #595f82); |
||||
|
} |
||||
|
.small-data-item4 { |
||||
|
background: linear-gradient(to left, #08dcd5, #46e2bb); |
||||
|
} |
||||
|
.small-data-item5 { |
||||
|
background: linear-gradient(to left, #f4c46b, #ffb313); |
||||
|
} |
||||
|
.small-data-item6 { |
||||
|
background: linear-gradient(to left, #6eccf8, #02acfd); |
||||
|
} |
||||
|
} |
||||
|
.two-row { |
||||
|
display: flex; |
||||
|
align-content: center; |
||||
|
.data1 { |
||||
|
background: white; |
||||
|
padding: 14px; |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,162 @@ |
|||||
|
<template> |
||||
|
<div class="row"> |
||||
|
<div class="two-row"> |
||||
|
<div class="data1 w-[50%]"> |
||||
|
<div class="title">今日生产计划</div> |
||||
|
<el-table :data="tableData" style="width: 100%" stripe height="240px"> |
||||
|
<el-table-column prop="title" label="标题" /> |
||||
|
<el-table-column prop="name" label="发布人" /> |
||||
|
<el-table-column prop="date" label="发布日期" /> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
<div class="data1 w-[50%] ml-14px"> |
||||
|
<div class="title">线边安全库存</div> |
||||
|
<el-table :data="tableData" style="width: 100%" stripe height="240px"> |
||||
|
<el-table-column prop="title" label="标题" /> |
||||
|
<el-table-column prop="name" label="发布人" /> |
||||
|
<el-table-column prop="date" label="发布日期" /> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="two-row mt-14px"> |
||||
|
<div class="data1 w-[50%]"> |
||||
|
<div class="title">待上架成品库存</div> |
||||
|
<el-table :data="tableData" style="width: 100%" stripe height="240px"> |
||||
|
<el-table-column prop="title" label="标题" /> |
||||
|
<el-table-column prop="name" label="发布人" /> |
||||
|
<el-table-column prop="date" label="发布日期" /> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
<div class="data1 w-[50%] ml-14px"> |
||||
|
<div class="title">待处理任务</div> |
||||
|
<el-table :data="tableData" style="width: 100%" stripe height="240px"> |
||||
|
<el-table-column prop="title" label="标题" /> |
||||
|
<el-table-column prop="name" label="发布人" /> |
||||
|
<el-table-column prop="date" label="发布日期" /> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script lang="ts" setup> |
||||
|
const tableData = [ |
||||
|
{ |
||||
|
date: '2016-05-03', |
||||
|
name: 'Tom', |
||||
|
title: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
}, |
||||
|
{ |
||||
|
date: '2016-05-02', |
||||
|
title: 'Tom', |
||||
|
name: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
}, |
||||
|
{ |
||||
|
date: '2016-05-04', |
||||
|
title: 'Tom', |
||||
|
name: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
}, |
||||
|
{ |
||||
|
date: '2016-05-01', |
||||
|
title: 'Tom', |
||||
|
name: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
}, |
||||
|
{ |
||||
|
date: '2016-05-01', |
||||
|
title: 'Tom', |
||||
|
name: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
}, |
||||
|
{ |
||||
|
date: '2016-05-01', |
||||
|
title: 'Tom', |
||||
|
name: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
} |
||||
|
] |
||||
|
|
||||
|
</script> |
||||
|
<style scoped lang="scss"> |
||||
|
.title { |
||||
|
padding-bottom: 10px; |
||||
|
border-bottom: 1px solid #dedede; |
||||
|
position: relative; |
||||
|
padding-left: 10px; |
||||
|
&::after { |
||||
|
content: ''; |
||||
|
position: absolute; |
||||
|
width: 4px; |
||||
|
height: 16px; |
||||
|
background: #3c7adf; |
||||
|
left: 0px; |
||||
|
top: 3px; |
||||
|
border-radius: 8px; |
||||
|
} |
||||
|
} |
||||
|
.data { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: space-between; |
||||
|
.small-data-item { |
||||
|
width:25%; |
||||
|
height: 90px; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
border-radius: 6px; |
||||
|
color: white; |
||||
|
padding: 0px 20px; |
||||
|
.small-data-item-txt { |
||||
|
flex: 1; |
||||
|
div { |
||||
|
&:nth-child(1) { |
||||
|
font-size: 14px; |
||||
|
|
||||
|
} |
||||
|
&:nth-child(2) { |
||||
|
font-size: 26px; |
||||
|
margin-top: 4px; |
||||
|
font-weight: bold; |
||||
|
span { |
||||
|
font-size: 14px; |
||||
|
padding-left: 6px; |
||||
|
font-weight: normal; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.img { |
||||
|
width: 40px; |
||||
|
opacity: 0.5; |
||||
|
} |
||||
|
} |
||||
|
.small-data-item1 { |
||||
|
background: linear-gradient(to left, #fd817d, #fcad80); |
||||
|
} |
||||
|
.small-data-item2 { |
||||
|
background: linear-gradient(to left, #46c6fa, #336bfe); |
||||
|
} |
||||
|
.small-data-item3 { |
||||
|
background: linear-gradient(to left, #96a6cc, #595f82); |
||||
|
} |
||||
|
.small-data-item4 { |
||||
|
background: linear-gradient(to left, #08dcd5, #46e2bb); |
||||
|
} |
||||
|
.small-data-item5 { |
||||
|
background: linear-gradient(to left, #f4c46b, #ffb313); |
||||
|
} |
||||
|
.small-data-item6 { |
||||
|
background: linear-gradient(to left, #6eccf8, #02acfd); |
||||
|
} |
||||
|
} |
||||
|
.two-row { |
||||
|
display: flex; |
||||
|
align-content: center; |
||||
|
.data1 { |
||||
|
background: white; |
||||
|
padding: 14px; |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,322 @@ |
|||||
|
<template> |
||||
|
<div class="one-row"> |
||||
|
<div class="data"> |
||||
|
<div class="data-item"> |
||||
|
<div class="small-title">订单数</div> |
||||
|
<div class="small-data"> |
||||
|
<div class="small-data-item small-data-item1"> |
||||
|
<div class="small-data-item-txt"> |
||||
|
<div>22<span>单</span></div> |
||||
|
<div>开发订单数</div> |
||||
|
</div> |
||||
|
<img src="../../../assets/imgs/icon1.png" alt="" class="img" /> |
||||
|
</div> |
||||
|
<div class="small-data-item small-data-item2 ml-14px"> |
||||
|
<div class="small-data-item-txt"> |
||||
|
<div>2456<span>单</span></div> |
||||
|
<div>全部订单数</div> |
||||
|
</div> |
||||
|
<img src="../../../assets/imgs/icon5.png" alt="" class="img" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="data-item ml-14px"> |
||||
|
<div class="small-title">要货计划数</div> |
||||
|
<div class="small-data"> |
||||
|
<div class="small-data-item small-data-item3"> |
||||
|
<div class="small-data-item-txt"> |
||||
|
<div>255<span>单</span></div> |
||||
|
<div>开放计划数</div> |
||||
|
</div> |
||||
|
<img src="../../../assets/imgs/icon6.png" alt="" class="img" /> |
||||
|
</div> |
||||
|
<div class="small-data-item small-data-item4 ml-14px"> |
||||
|
<div class="small-data-item-txt"> |
||||
|
<div>2555<span>单</span></div> |
||||
|
<div>全部计划数</div> |
||||
|
</div> |
||||
|
<img src="../../../assets/imgs/icon3.png" alt="" class="img" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="data-item ml-14px"> |
||||
|
<div class="small-title">发货单数</div> |
||||
|
<div class="small-data"> |
||||
|
<div class="small-data-item small-data-item5"> |
||||
|
<div class="small-data-item-txt"> |
||||
|
<div>255<span>单</span></div> |
||||
|
<div>未收货订单数</div> |
||||
|
</div> |
||||
|
<img src="../../../assets/imgs/icon4.png" alt="" class="img" /> |
||||
|
</div> |
||||
|
<div class="small-data-item small-data-item6 ml-14px"> |
||||
|
<div class="small-data-item-txt"> |
||||
|
<div>2555<span>单</span></div> |
||||
|
<div>已收货订单数</div> |
||||
|
</div> |
||||
|
<img src="../../../assets/imgs/icon2.png" alt="" class="img" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="two-row mt-14px"> |
||||
|
<div class="data1 w-[65%]"> |
||||
|
<div class="title">本月发货单趋势</div> |
||||
|
<Echart :options="lineOptions" :height="280" /> |
||||
|
</div> |
||||
|
<div class="data1 w-[35%] ml-14px"> |
||||
|
<div class="title">本月发货零件TOP10</div> |
||||
|
<Echart :options="pieOptions" :height="280" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="two-row mt-14px"> |
||||
|
<div class="data1 w-[50%]"> |
||||
|
<div class="title">最新消息</div> |
||||
|
<el-table :data="tableData" style="width: 100%" stripe height="240px"> |
||||
|
<el-table-column prop="title" label="标题" /> |
||||
|
<el-table-column prop="name" label="发布人" /> |
||||
|
<el-table-column prop="date" label="发布日期" /> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
<div class="data1 w-[50%] ml-14px"> |
||||
|
<div class="title">最新扣分明细</div> |
||||
|
<el-table :data="tableData" style="width: 100%" stripe height="240px"> |
||||
|
<el-table-column prop="title" label="标题" /> |
||||
|
<el-table-column prop="name" label="发布人" /> |
||||
|
<el-table-column prop="date" label="发布日期" /> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="two-row mt-14px"> |
||||
|
<div class="data1 w-[50%]"> |
||||
|
<div class="title">本月退货明细</div> |
||||
|
<el-table :data="tableData" style="width: 100%" stripe height="240px"> |
||||
|
<el-table-column prop="title" label="标题" /> |
||||
|
<el-table-column prop="name" label="发布人" /> |
||||
|
<el-table-column prop="date" label="发布日期" /> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
<div class="data1 w-[50%] ml-14px"> |
||||
|
<div class="title">本月索赔明细</div> |
||||
|
<el-table :data="tableData" style="width: 100%" stripe height="240px"> |
||||
|
<el-table-column prop="title" label="标题" /> |
||||
|
<el-table-column prop="name" label="发布人" /> |
||||
|
<el-table-column prop="date" label="发布日期" /> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script lang="ts" setup> |
||||
|
import { set } from 'lodash-es' |
||||
|
import { EChartsOption } from 'echarts' |
||||
|
import { lineOptions, pieOptions } from '../echarts-data' |
||||
|
const { t } = useI18n() |
||||
|
const tableData = [ |
||||
|
{ |
||||
|
date: '2016-05-03', |
||||
|
name: 'Tom', |
||||
|
title: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
}, |
||||
|
{ |
||||
|
date: '2016-05-02', |
||||
|
title: 'Tom', |
||||
|
name: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
}, |
||||
|
{ |
||||
|
date: '2016-05-04', |
||||
|
title: 'Tom', |
||||
|
name: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
}, |
||||
|
{ |
||||
|
date: '2016-05-01', |
||||
|
title: 'Tom', |
||||
|
name: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
}, |
||||
|
{ |
||||
|
date: '2016-05-01', |
||||
|
title: 'Tom', |
||||
|
name: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
}, |
||||
|
{ |
||||
|
date: '2016-05-01', |
||||
|
title: 'Tom', |
||||
|
name: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
} |
||||
|
] |
||||
|
// 本月发货单趋势 |
||||
|
const lineOptionsData = reactive<EChartsOption>(lineOptions) as EChartsOption |
||||
|
const getInvoiceCharts = async () => { |
||||
|
const data = [ |
||||
|
{ value: 20, name: '1日' }, |
||||
|
{ value: 50, name: '2日' }, |
||||
|
{ value: 250, name: '3日' }, |
||||
|
{ value: 220, name: '4日' }, |
||||
|
{ value: 230, name: '5日' }, |
||||
|
{ value: 160, name: '6日' }, |
||||
|
{ value: 120, name: '7日' }, |
||||
|
{ value: 160, name: '8日' }, |
||||
|
{ value: 130, name: '9日' }, |
||||
|
{ value: 240, name: '10日' }, |
||||
|
{ value: 230, name: '11日' }, |
||||
|
{ value: 100, name: '12日' }, |
||||
|
{ value: 40, name: '13日' }, |
||||
|
{ value: 80, name: '14日' }, |
||||
|
{ value: 30, name: '15日' }, |
||||
|
{ value: 88, name: '16日' }, |
||||
|
{ value: 134, name: '17日' }, |
||||
|
{ value: 156, name: '18日' }, |
||||
|
{ value: 143, name: '19日' }, |
||||
|
{ value: 240, name: '20日' }, |
||||
|
{ value: 160, name: '21日' }, |
||||
|
{ value: 160, name: '22日' }, |
||||
|
{ value: 160, name: '23日' }, |
||||
|
{ value: 160, name: '24日' }, |
||||
|
{ value: 160, name: '25日' }, |
||||
|
{ value: 160, name: '26日' }, |
||||
|
{ value: 160, name: '27日' }, |
||||
|
{ value: 160, name: '28日' }, |
||||
|
{ value: 160, name: '29日' }, |
||||
|
{ value: 160, name: '30日' } |
||||
|
] |
||||
|
set( |
||||
|
lineOptionsData, |
||||
|
'xAxis.data', |
||||
|
data.map((v) => t(v.name)) |
||||
|
) |
||||
|
set(lineOptionsData, 'series', [ |
||||
|
{ |
||||
|
name: '哈哈', |
||||
|
smooth: true, |
||||
|
type: 'line', |
||||
|
itemStyle: {}, |
||||
|
animationDuration: 2800, |
||||
|
animationEasing: 'quadraticOut', |
||||
|
data: data.map((v) => v.value) |
||||
|
} |
||||
|
]) |
||||
|
} |
||||
|
//本月发货零件TOP10 |
||||
|
|
||||
|
const pieOptionsData = reactive<EChartsOption>(pieOptions) as EChartsOption |
||||
|
const getPartTOPCharts = 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 |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
getInvoiceCharts() |
||||
|
getPartTOPCharts() |
||||
|
</script> |
||||
|
<style scoped lang="scss"> |
||||
|
.title { |
||||
|
padding-bottom: 10px; |
||||
|
border-bottom: 1px solid #dedede; |
||||
|
position: relative; |
||||
|
padding-left: 10px; |
||||
|
&::after { |
||||
|
content: ''; |
||||
|
position: absolute; |
||||
|
width: 4px; |
||||
|
height: 16px; |
||||
|
background: #3c7adf; |
||||
|
left: 0px; |
||||
|
top: 3px; |
||||
|
border-radius: 8px; |
||||
|
} |
||||
|
} |
||||
|
.data { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: space-between; |
||||
|
.data-item { |
||||
|
width: calc(100% / 3); |
||||
|
padding: 10px 0px; |
||||
|
background: white; |
||||
|
.small-title { |
||||
|
padding: 0px 14px 10px; |
||||
|
} |
||||
|
.small-data { |
||||
|
display: flex; |
||||
|
align-content: center; |
||||
|
justify-content: space-between; |
||||
|
padding: 0px 14px; |
||||
|
.small-data-item { |
||||
|
width: 50%; |
||||
|
height: 70px; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
border-radius: 6px; |
||||
|
color: white; |
||||
|
padding: 0px 20px; |
||||
|
.small-data-item-txt { |
||||
|
flex: 1; |
||||
|
div { |
||||
|
&:nth-child(1) { |
||||
|
font-size: 20px; |
||||
|
span { |
||||
|
font-size: 12px; |
||||
|
padding-left: 6px; |
||||
|
} |
||||
|
} |
||||
|
&:nth-child(2) { |
||||
|
font-size: 12px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.img { |
||||
|
width: 30px; |
||||
|
opacity: 0.5; |
||||
|
} |
||||
|
} |
||||
|
.small-data-item1 { |
||||
|
background: linear-gradient(to left, #fd817d, #fcad80); |
||||
|
} |
||||
|
.small-data-item2 { |
||||
|
background: linear-gradient(to left, #46c6fa, #336bfe); |
||||
|
} |
||||
|
.small-data-item3 { |
||||
|
background: linear-gradient(to left, #96a6cc, #595f82); |
||||
|
} |
||||
|
.small-data-item4 { |
||||
|
background: linear-gradient(to left, #08dcd5, #46e2bb); |
||||
|
} |
||||
|
.small-data-item5 { |
||||
|
background: linear-gradient(to left, #f4c46b, #ffb313); |
||||
|
} |
||||
|
.small-data-item6 { |
||||
|
background: linear-gradient(to left, #6eccf8, #02acfd); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.two-row { |
||||
|
display: flex; |
||||
|
align-content: center; |
||||
|
.data1 { |
||||
|
background: white; |
||||
|
padding: 14px; |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,192 @@ |
|||||
|
<template> |
||||
|
<div class="row"> |
||||
|
<div class="data"> |
||||
|
<div class="small-data-item small-data-item1"> |
||||
|
<div class="small-data-item-txt"> |
||||
|
<div>今日到货计划(已发货)</div> |
||||
|
<div>22<span>单</span></div> |
||||
|
</div> |
||||
|
<img src="../../../assets/imgs/icon1.png" alt="" class="img" /> |
||||
|
</div> |
||||
|
<div class="small-data-item small-data-item2 ml-14px"> |
||||
|
<div class="small-data-item-txt"> |
||||
|
<div>今日备料计划(已发料)</div> |
||||
|
<div>2456<span>单</span></div> |
||||
|
</div> |
||||
|
<img src="../../../assets/imgs/icon5.png" alt="" class="img" /> |
||||
|
</div> |
||||
|
<div class="small-data-item small-data-item3 ml-14px"> |
||||
|
<div class="small-data-item-txt"> |
||||
|
<div>今日叫料请求(已发料)</div> |
||||
|
<div>255<span>单</span></div> |
||||
|
</div> |
||||
|
<img src="../../../assets/imgs/icon6.png" alt="" class="img" /> |
||||
|
</div> |
||||
|
<div class="small-data-item small-data-item4 ml-14px"> |
||||
|
<div class="small-data-item-txt"> |
||||
|
<div>空闲库位数/总库位数</div> |
||||
|
<div style="font-size: 20px;">2555<span>个</span>/65555<span>个</span></div> |
||||
|
</div> |
||||
|
<img src="../../../assets/imgs/icon3.png" alt="" class="img" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="two-row mt-14px"> |
||||
|
<div class="data1 w-[50%]"> |
||||
|
<div class="title">呆滞库存预警</div> |
||||
|
<el-table :data="tableData" style="width: 100%" stripe height="240px"> |
||||
|
<el-table-column prop="title" label="标题" /> |
||||
|
<el-table-column prop="name" label="发布人" /> |
||||
|
<el-table-column prop="date" label="发布日期" /> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
<div class="data1 w-[50%] ml-14px"> |
||||
|
<div class="title">超期库存预警</div> |
||||
|
<el-table :data="tableData" style="width: 100%" stripe height="240px"> |
||||
|
<el-table-column prop="title" label="标题" /> |
||||
|
<el-table-column prop="name" label="发布人" /> |
||||
|
<el-table-column prop="date" label="发布日期" /> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="two-row mt-14px"> |
||||
|
<div class="data1 w-[50%]"> |
||||
|
<div class="title">高低储预警</div> |
||||
|
<el-table :data="tableData" style="width: 100%" stripe height="240px"> |
||||
|
<el-table-column prop="title" label="标题" /> |
||||
|
<el-table-column prop="name" label="发布人" /> |
||||
|
<el-table-column prop="date" label="发布日期" /> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
<div class="data1 w-[50%] ml-14px"> |
||||
|
<div class="title">待处理任务</div> |
||||
|
<el-table :data="tableData" style="width: 100%" stripe height="240px"> |
||||
|
<el-table-column prop="title" label="标题" /> |
||||
|
<el-table-column prop="name" label="发布人" /> |
||||
|
<el-table-column prop="date" label="发布日期" /> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script lang="ts" setup> |
||||
|
const tableData = [ |
||||
|
{ |
||||
|
date: '2016-05-03', |
||||
|
name: 'Tom', |
||||
|
title: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
}, |
||||
|
{ |
||||
|
date: '2016-05-02', |
||||
|
title: 'Tom', |
||||
|
name: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
}, |
||||
|
{ |
||||
|
date: '2016-05-04', |
||||
|
title: 'Tom', |
||||
|
name: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
}, |
||||
|
{ |
||||
|
date: '2016-05-01', |
||||
|
title: 'Tom', |
||||
|
name: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
}, |
||||
|
{ |
||||
|
date: '2016-05-01', |
||||
|
title: 'Tom', |
||||
|
name: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
}, |
||||
|
{ |
||||
|
date: '2016-05-01', |
||||
|
title: 'Tom', |
||||
|
name: 'Tom', |
||||
|
text: 'No. 189, Grove St, Los Angeles' |
||||
|
} |
||||
|
] |
||||
|
|
||||
|
</script> |
||||
|
<style scoped lang="scss"> |
||||
|
.title { |
||||
|
padding-bottom: 10px; |
||||
|
border-bottom: 1px solid #dedede; |
||||
|
position: relative; |
||||
|
padding-left: 10px; |
||||
|
&::after { |
||||
|
content: ''; |
||||
|
position: absolute; |
||||
|
width: 4px; |
||||
|
height: 16px; |
||||
|
background: #3c7adf; |
||||
|
left: 0px; |
||||
|
top: 3px; |
||||
|
border-radius: 8px; |
||||
|
} |
||||
|
} |
||||
|
.data { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: space-between; |
||||
|
.small-data-item { |
||||
|
width:25%; |
||||
|
height: 90px; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
border-radius: 6px; |
||||
|
color: white; |
||||
|
padding: 0px 20px; |
||||
|
.small-data-item-txt { |
||||
|
flex: 1; |
||||
|
div { |
||||
|
&:nth-child(1) { |
||||
|
font-size: 14px; |
||||
|
|
||||
|
} |
||||
|
&:nth-child(2) { |
||||
|
font-size: 26px; |
||||
|
margin-top: 4px; |
||||
|
font-weight: bold; |
||||
|
span { |
||||
|
font-size: 14px; |
||||
|
padding-left: 6px; |
||||
|
font-weight: normal; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.img { |
||||
|
width: 40px; |
||||
|
opacity: 0.5; |
||||
|
} |
||||
|
} |
||||
|
.small-data-item1 { |
||||
|
background: linear-gradient(to left, #fd817d, #fcad80); |
||||
|
} |
||||
|
.small-data-item2 { |
||||
|
background: linear-gradient(to left, #46c6fa, #336bfe); |
||||
|
} |
||||
|
.small-data-item3 { |
||||
|
background: linear-gradient(to left, #96a6cc, #595f82); |
||||
|
} |
||||
|
.small-data-item4 { |
||||
|
background: linear-gradient(to left, #08dcd5, #46e2bb); |
||||
|
} |
||||
|
.small-data-item5 { |
||||
|
background: linear-gradient(to left, #f4c46b, #ffb313); |
||||
|
} |
||||
|
.small-data-item6 { |
||||
|
background: linear-gradient(to left, #6eccf8, #02acfd); |
||||
|
} |
||||
|
} |
||||
|
.two-row { |
||||
|
display: flex; |
||||
|
align-content: center; |
||||
|
.data1 { |
||||
|
background: white; |
||||
|
padding: 14px; |
||||
|
} |
||||
|
} |
||||
|
</style> |
Loading…
Reference in new issue