Browse Source

首页修改 及 加入ai

master
赵鹏 2 months ago
parent
commit
939631c863
  1. 1
      src/layout/Layout.vue
  2. 302
      src/layout/components/Setting/src/Setting copy.vue
  3. 89
      src/layout/components/Setting/src/Setting.vue
  4. 643
      src/views/Home/Index.vue
  5. 282
      src/views/Home/echarts-data.ts
  6. 7
      src/views/Home/types.ts
  7. 2
      src/views/system/policy/index.vue

1
src/layout/Layout.vue

@ -65,6 +65,7 @@ export default defineComponent({
}) })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
$prefix-cls: #{$namespace}-layout; $prefix-cls: #{$namespace}-layout;

302
src/layout/components/Setting/src/Setting copy.vue

@ -0,0 +1,302 @@
<script lang="ts" setup>
import { ElMessage } from 'element-plus'
import { useClipboard, useCssVar } from '@vueuse/core'
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
import { useDesign } from '@/hooks/web/useDesign'
import { setCssVar, trim } from '@/utils'
import { colorIsDark, hexToRGB, lighten } from '@/utils/color'
import { useAppStore } from '@/store/modules/app'
import { ThemeSwitch } from '@/layout/components/ThemeSwitch'
import ColorRadioPicker from './components/ColorRadioPicker.vue'
import InterfaceDisplay from './components/InterfaceDisplay.vue'
import LayoutRadioPicker from './components/LayoutRadioPicker.vue'
defineOptions({ name: 'Setting' })
const { t } = useI18n()
const appStore = useAppStore()
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('setting')
const layout = computed(() => appStore.getLayout)
const drawer = ref(false)
//
const systemTheme = ref(appStore.getTheme.elColorPrimary)
const setSystemTheme = (color: string) => {
setCssVar('--el-color-primary', color)
appStore.setTheme({ elColorPrimary: color })
const leftMenuBgColor = useCssVar('--left-menu-bg-color', document.documentElement)
setMenuTheme(trim(unref(leftMenuBgColor)))
}
//
const headerTheme = ref(appStore.getTheme.topHeaderBgColor || '')
const setHeaderTheme = (color: string) => {
const isDarkColor = colorIsDark(color)
const textColor = isDarkColor ? '#fff' : 'inherit'
const textHoverColor = isDarkColor ? lighten(color!, 6) : '#f6f6f6'
const topToolBorderColor = isDarkColor ? color : '#eee'
setCssVar('--top-header-bg-color', color)
setCssVar('--top-header-text-color', textColor)
setCssVar('--top-header-hover-color', textHoverColor)
appStore.setTheme({
topHeaderBgColor: color,
topHeaderTextColor: textColor,
topHeaderHoverColor: textHoverColor,
topToolBorderColor
})
if (unref(layout) === 'top') {
setMenuTheme(color)
}
}
//
const menuTheme = ref(appStore.getTheme.leftMenuBgColor || '')
const setMenuTheme = (color: string) => {
const primaryColor = useCssVar('--el-color-primary', document.documentElement)
const isDarkColor = colorIsDark(color)
const theme: Recordable = {
//
leftMenuBorderColor: isDarkColor ? 'inherit' : '#eee',
//
leftMenuBgColor: color,
//
leftMenuBgLightColor: isDarkColor ? lighten(color!, 6) : color,
//
leftMenuBgActiveColor: isDarkColor
? 'var(--el-color-primary)'
: hexToRGB(unref(primaryColor), 0.1),
//
leftMenuCollapseBgActiveColor: isDarkColor
? 'var(--el-color-primary)'
: hexToRGB(unref(primaryColor), 0.1),
//
leftMenuTextColor: isDarkColor ? '#bfcbd9' : '#333',
//
leftMenuTextActiveColor: isDarkColor ? '#fff' : 'var(--el-color-primary)',
// logo
logoTitleTextColor: isDarkColor ? '#fff' : 'inherit',
// logo
logoBorderColor: isDarkColor ? color : '#eee'
}
appStore.setTheme(theme)
appStore.setCssVarTheme()
}
if (layout.value === 'top' && !appStore.getIsDark) {
headerTheme.value = '#fff'
setHeaderTheme('#fff')
}
// layout
watch(
() => layout.value,
(n) => {
if (n === 'top' && !appStore.getIsDark) {
headerTheme.value = '#fff'
setHeaderTheme('#fff')
} else {
setMenuTheme(unref(menuTheme))
}
}
)
//
const copyConfig = async () => {
const { copy, copied, isSupported } = useClipboard({
source: `
//
breadcrumb: ${appStore.getBreadcrumb},
//
breadcrumbIcon: ${appStore.getBreadcrumbIcon},
//
hamburger: ${appStore.getHamburger},
//
screenfull: ${appStore.getScreenfull},
//
size: ${appStore.getSize},
//
locale: ${appStore.getLocale},
//
message: ${appStore.getMessage},
//
tagsView: ${appStore.getTagsView},
//
tagsViewImmerse: ${appStore.getTagsViewImmerse},
//
tagsViewIcon: ${appStore.getTagsViewIcon},
// logo
logo: ${appStore.getLogo},
//
uniqueOpened: ${appStore.getUniqueOpened},
// header
fixedHeader: ${appStore.getFixedHeader},
//
footer: ${appStore.getFooter},
//
greyMode: ${appStore.getGreyMode},
// layout
layout: '${appStore.getLayout}',
//
isDark: ${appStore.getIsDark},
//
currentSize: '${appStore.getCurrentSize}',
//
theme: {
//
elColorPrimary: '${appStore.getTheme.elColorPrimary}',
//
leftMenuBorderColor: '${appStore.getTheme.leftMenuBorderColor}',
//
leftMenuBgColor: '${appStore.getTheme.leftMenuBgColor}',
//
leftMenuBgLightColor: '${appStore.getTheme.leftMenuBgLightColor}',
//
leftMenuBgActiveColor: '${appStore.getTheme.leftMenuBgActiveColor}',
//
leftMenuCollapseBgActiveColor: '${appStore.getTheme.leftMenuCollapseBgActiveColor}',
//
leftMenuTextColor: '${appStore.getTheme.leftMenuTextColor}',
//
leftMenuTextActiveColor: '${appStore.getTheme.leftMenuTextActiveColor}',
// logo
logoTitleTextColor: '${appStore.getTheme.logoTitleTextColor}',
// logo
logoBorderColor: '${appStore.getTheme.logoBorderColor}',
//
topHeaderBgColor: '${appStore.getTheme.topHeaderBgColor}',
//
topHeaderTextColor: '${appStore.getTheme.topHeaderTextColor}',
//
topHeaderHoverColor: '${appStore.getTheme.topHeaderHoverColor}',
//
topToolBorderColor: '${appStore.getTheme.topToolBorderColor}'
}
`
})
if (!isSupported) {
ElMessage.error(t('setting.copyFailed'))
} else {
await copy()
if (unref(copied)) {
ElMessage.success(t('setting.copySuccess'))
}
}
}
//
const clear = () => {
const { wsCache } = useCache()
wsCache.delete(CACHE_KEY.LAYOUT)
wsCache.delete(CACHE_KEY.THEME)
wsCache.delete(CACHE_KEY.IS_DARK)
window.location.reload()
}
</script>
<template>
<div
:class="prefixCls"
class="fixed right-0 top-[45%] h-40px w-40px cursor-pointer bg-[var(--el-color-primary)] text-center leading-40px"
@click="drawer = true"
>
<Icon color="#fff" icon="ep:setting" />
</div>
<ElDrawer v-model="drawer" :z-index="4000" direction="rtl" size="350px">
<template #header>
<span class="text-16px font-700">{{ t('setting.projectSetting') }}</span>
</template>
<div class="text-center">
<!-- 主题 -->
<ElDivider>{{ t('setting.theme') }}</ElDivider>
<ThemeSwitch />
<!-- 布局 -->
<ElDivider>{{ t('setting.layout') }}</ElDivider>
<LayoutRadioPicker />
<!-- 系统主题 -->
<ElDivider>{{ t('setting.systemTheme') }}</ElDivider>
<ColorRadioPicker
v-model="systemTheme"
:schema="[
'#409eff',
'#009688',
'#536dfe',
'#ff5c93',
'#ee4f12',
'#0096c7',
'#9c27b0',
'#ff9800'
]"
@change="setSystemTheme"
/>
<!-- 头部主题 -->
<ElDivider>{{ t('setting.headerTheme') }}</ElDivider>
<ColorRadioPicker
v-model="headerTheme"
:schema="[
'#fff',
'#151515',
'#5172dc',
'#e74c3c',
'#24292e',
'#394664',
'#009688',
'#383f45'
]"
@change="setHeaderTheme"
/>
<!-- 菜单主题 -->
<template v-if="layout !== 'top'">
<ElDivider>{{ t('setting.menuTheme') }}</ElDivider>
<ColorRadioPicker
v-model="menuTheme"
:schema="[
'#fff',
'#001529',
'#212121',
'#273352',
'#191b24',
'#383f45',
'#001628',
'#344058'
]"
@change="setMenuTheme"
/>
</template>
</div>
<!-- 界面显示 -->
<ElDivider>{{ t('setting.interfaceDisplay') }}</ElDivider>
<InterfaceDisplay />
<ElDivider />
<div>
<ElButton class="w-full" type="primary" @click="copyConfig">{{ t('setting.copy') }}</ElButton>
</div>
<div class="mt-5px">
<ElButton class="w-full" type="danger" @click="clear">
{{ t('setting.clearAndReset') }}
</ElButton>
</div>
</ElDrawer>
</template>
<style lang="scss" scoped>
$prefix-cls: #{$namespace}-setting;
.#{$prefix-cls} {
border-radius: 6px 0 0 6px;
z-index: 1200;/*修正没有z-index会被表格层覆盖,值不要超过4000*/
}
</style>

89
src/layout/components/Setting/src/Setting.vue

@ -202,93 +202,20 @@ const clear = () => {
<template> <template>
<div <div
:class="prefixCls" :class="prefixCls"
class="fixed right-0 top-[45%] h-40px w-40px cursor-pointer bg-[var(--el-color-primary)] text-center leading-40px" class="fixed right-0 top-[90%] h-40px w-40px cursor-pointer bg-[var(--el-color-primary)] text-center leading-40px"
@click="drawer = true" @click="drawer = true"
> >
<Icon color="#fff" icon="ep:setting" /> <Icon color="#fff" icon="ep:setting" />
</div> </div>
<ElDrawer v-model="drawer" :z-index="4000" direction="rtl" size="350px"> <ElDrawer v-model="drawer" :z-index="4000" direction="rtl" size="550px">
<template #header> <iframe
<span class="text-16px font-700">{{ t('setting.projectSetting') }}</span> src="https://mb.jzce.com/chat/313cf9e35628923a"
</template> style="width: 100%; height: 100%;"
frameborder="0"
allow="microphone">
</iframe>
<div class="text-center">
<!-- 主题 -->
<ElDivider>{{ t('setting.theme') }}</ElDivider>
<ThemeSwitch />
<!-- 布局 -->
<ElDivider>{{ t('setting.layout') }}</ElDivider>
<LayoutRadioPicker />
<!-- 系统主题 -->
<ElDivider>{{ t('setting.systemTheme') }}</ElDivider>
<ColorRadioPicker
v-model="systemTheme"
:schema="[
'#409eff',
'#009688',
'#536dfe',
'#ff5c93',
'#ee4f12',
'#0096c7',
'#9c27b0',
'#ff9800'
]"
@change="setSystemTheme"
/>
<!-- 头部主题 -->
<ElDivider>{{ t('setting.headerTheme') }}</ElDivider>
<ColorRadioPicker
v-model="headerTheme"
:schema="[
'#fff',
'#151515',
'#5172dc',
'#e74c3c',
'#24292e',
'#394664',
'#009688',
'#383f45'
]"
@change="setHeaderTheme"
/>
<!-- 菜单主题 -->
<template v-if="layout !== 'top'">
<ElDivider>{{ t('setting.menuTheme') }}</ElDivider>
<ColorRadioPicker
v-model="menuTheme"
:schema="[
'#fff',
'#001529',
'#212121',
'#273352',
'#191b24',
'#383f45',
'#001628',
'#344058'
]"
@change="setMenuTheme"
/>
</template>
</div>
<!-- 界面显示 -->
<ElDivider>{{ t('setting.interfaceDisplay') }}</ElDivider>
<InterfaceDisplay />
<ElDivider />
<div>
<ElButton class="w-full" type="primary" @click="copyConfig">{{ t('setting.copy') }}</ElButton>
</div>
<div class="mt-5px">
<ElButton class="w-full" type="danger" @click="clear">
{{ t('setting.clearAndReset') }}
</ElButton>
</div>
</ElDrawer> </ElDrawer>
</template> </template>

643
src/views/Home/Index.vue

@ -1,340 +1,349 @@
<template> <template>
<div> <el-row :gutter="8" justify="space-between">
<!-- <el-card shadow="never">--> <el-col :xl="16" :lg="16" :md="24" :sm="24" :xs="24" class="mb-8px">
<!-- <el-skeleton :loading="loading" animated>--> <el-card ref="taskInfoCard" shadow="never">
<!-- <el-row :gutter="16" justify="space-between">--> <template #header>任务信息</template>
<!-- <el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">--> <el-skeleton :loading="loading" animated>
<!-- <div class="flex items-center">--> <el-row :gutter="20" justify="space-between">
<!-- <el-avatar :src="avatar" :size="70" class="mr-16px">--> <el-col :xl="10" :lg="10" :md="24" :sm="24" :xs="24">
<!-- <img src="@/assets/imgs/avatar.gif" alt="" />--> <el-card shadow="hover" class="mb-8px">
<!-- </el-avatar>--> <el-skeleton :loading="loading" animated>
<!-- <div>--> <Echart :options="pieOptionsData" :height="280" />
<!-- <div class="text-20px">--> </el-skeleton>
<!-- {{ t('workplace.welcome') }} {{ username }} {{ t('workplace.happyDay') }}--> </el-card>
<!-- </div>--> </el-col>
<!-- <div class="mt-10px text-14px text-gray-500">--> <el-col :xl="14" :lg="14" :md="24" :sm="24" :xs="24">
<!-- {{ t('workplace.toady') }}20 - 32--> <el-card shadow="hover" class="mb-8px">
<!-- </div>--> <el-skeleton :loading="loading" animated>
<!-- </div>--> <Echart :options="barOptionsData" :height="280" />
<!-- </div>--> </el-skeleton>
<!-- </el-col>--> </el-card>
<!-- <el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">--> </el-col>
<!-- <div class="h-70px flex items-center justify-end lt-sm:mt-10px">--> </el-row>
<!-- <div class="px-8px text-right">--> </el-skeleton>
<!-- <div class="mb-16px text-14px text-gray-400">{{ t('workplace.project') }}</div>--> </el-card>
<!-- <CountTo--> </el-col>
<!-- class="text-20px"--> <el-col :xl="8" :lg="8" :md="24" :sm="24" :xs="24" class="mb-8px">
<!-- :start-val="0"--> <el-card ref="taskNewCard" shadow="never" >
<!-- :end-val="totalSate.project"--> <template #header>
<!-- :duration="2600"--> 最新任务
<!-- />--> </template>
<!-- </div>--> <el-skeleton :loading="loading" animated>
<!-- <el-divider direction="vertical" />--> <div v-for="(item, index) in tasks" :key="`dynamics-${index}`">
<!-- <div class="px-8px text-right">--> <div>
<!-- <div class="mb-16px text-14px text-gray-400">{{ t('workplace.toDo') }}</div>--> <div class="text-12px flex justify-between">
<!-- <CountTo--> <span>{{ item.title }}</span>
<!-- class="text-20px"--> <span class="mr-10">{{ item.user }}</span>
<!-- :start-val="0"--> <span class="mr-10">{{ item.date }}</span>
<!-- :end-val="totalSate.todo"--> </div>
<!-- :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>-->
</div>
<el-row class="mt-8px" :gutter="8" justify="space-between"> </div>
<el-divider height="10px" class="m-4 p-0" style="margin:8px 0" />
</div>
</el-skeleton>
</el-card>
</el-col>
</el-row>
<el-row :gutter="8">
<el-col :xl="16" :lg="16" :md="24" :sm="24" :xs="24" class="mb-8px"> <el-col :xl="16" :lg="16" :md="24" :sm="24" :xs="24" class="mb-8px">
<!-- <el-card shadow="never">--> <el-card shadow="never">
<!-- <template #header>--> <template #header>企业信息</template>
<!-- <div class="h-3 flex justify-between">-->
<!-- <span>{{ t('workplace.project') }}</span>--> <el-skeleton :loading="loading" animated>
<!-- <el-link--> <el-row :gutter="20" justify="space-between">
<!-- type="primary"--> <el-col :xl="10" :lg="10" :md="24" :sm="24" :xs="24">
<!-- :underline="false"--> <el-card shadow="hover" class="mb-8px">
<!-- href="https://github.com/yudaocode"--> <el-skeleton :loading="loading" animated>
<!-- target="_blank"--> <Echart :options="pieOptionsData" :height="280" />
<!-- >--> </el-skeleton>
<!-- {{ t('action.more') }}--> </el-card>
<!-- </el-link>--> </el-col>
<!-- </div>--> <el-col :xl="14" :lg="14" :md="24" :sm="24" :xs="24">
<!-- </template>--> <el-card shadow="hover" class="mb-8px">
<!-- <el-skeleton :loading="loading" animated>--> <el-skeleton :loading="loading" animated>
<!-- <el-row>--> <Echart :options="barOptionsData" :height="280" />
<!-- <el-col--> </el-skeleton>
<!-- v-for="(item, index) in projects"--> </el-card>
<!-- :key="`card-${index}`"--> </el-col>
<!-- :xl="8"--> </el-row>
<!-- :lg="8"--> </el-skeleton>
<!-- :md="8"--> </el-card>
<!-- :sm="24"--> </el-col>
<!-- :xs="24"--> <el-col :xl="8" :lg="8" :md="24" :sm="24" :xs="24" class="mb-8px">
<!-- >-->
<!-- <el-card shadow="hover" class="mr-5px mt-5px">--> <el-card shadow="never">
<!-- <div class="flex items-center">--> <template #header>
<!-- <Icon :icon="item.icon" :size="25" class="mr-8px" />--> <div class="h-3 flex justify-between">
<!-- <span class="text-16px">{{ item.name }}</span>--> <el-radio-group v-model="radio2" @change="rdiType">
<!-- </div>--> <el-radio-button label="资质逾期" value="资质逾期" />
<!-- <div class="mt-12px text-9px text-gray-400">{{ t(item.message) }}</div>--> <el-radio-button label="整改次数" value="整改次数" />
<!-- <div class="mt-12px flex justify-between text-12px text-gray-400">--> </el-radio-group>
<!-- <span>{{ item.personal }}</span>--> </div>
<!-- <span>{{ formatTime(item.time, 'yyyy-MM-dd') }}</span>--> </template>
<!-- </div>--> <el-skeleton :loading="loading" animated>
<!-- </el-card>--> <div v-for="(item, index) in notice" :key="`dynamics-${index}`">
<!-- </el-col>--> <div>
<!-- </el-row>--> <div class="text-12px flex justify-between">
<!-- </el-skeleton>--> <span>{{ item.title }}</span>
<!-- </el-card>--> <span class="mr-10">{{ item.days }}</span>
</div>
<!-- <el-card shadow="never" class="mt-8px">--> </div>
<!-- <el-skeleton :loading="loading" animated>--> <el-divider height="10px" class="m-4 p-0" style="margin:8px 0" />
<!-- <el-row :gutter="20" justify="space-between">-->
<!-- <el-col :xl="10" :lg="10" :md="24" :sm="24" :xs="24">--> </div>
<!-- <el-card shadow="hover" class="mb-8px">--> </el-skeleton>
<!-- <el-skeleton :loading="loading" animated>--> </el-card>
<!-- <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-col>
</el-row> </el-row>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { set } from 'lodash-es' import { set } from 'lodash-es'
import { EChartsOption } from 'echarts' import { EChartsOption } from 'echarts'
import { formatTime } from '@/utils'
import { useUserStore } from '@/store/modules/user' 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 { pieOptions, barOptions } from './echarts-data'
defineOptions({ name: 'Home' }) defineOptions({ name: 'Home' })
const { t } = useI18n() const { t } = useI18n()
const userStore = useUserStore() const userStore = useUserStore()
const { setWatermark } = useWatermark()
const loading = ref(true) const loading = ref(true)
const avatar = userStore.getUser.avatar
const username = userStore.getUser.nickname
const pieOptionsData = reactive<EChartsOption>(pieOptions) as EChartsOption const pieOptionsData = reactive<EChartsOption>(pieOptions) as EChartsOption
//
let totalSate = reactive<WorkplaceTotal>({
project: 0,
access: 0,
todo: 0
})
const getCount = async () => { const radio2 = ref('资质逾期')
const data = {
project: 40,
access: 2340,
todo: 10
}
totalSate = Object.assign(totalSate, data)
}
// //
let projects = reactive<Project[]>([]) const taskInfoCard = ref()
const getProject = async () => { const taskNewCard = ref()
const data = [
{
name: 'ruoyi-vue-pro',
icon: 'akar-icons:github-fill',
message: 'https://github.com/YunaiV/ruoyi-vue-pro',
personal: 'Spring Boot 单体架构',
time: new Date()
},
{
name: 'yudao-ui-admin-vue3',
icon: 'logos:vue',
message: 'https://github.com/yudaocode/yudao-ui-admin-vue3',
personal: 'Vue3 + element-plus',
time: new Date()
},
{
name: 'yudao-ui-admin-vben',
icon: 'logos:vue',
message: 'https://github.com/yudaocode/yudao-ui-admin-vben',
personal: 'Vue3 + vben(antd)',
time: new Date()
},
{
name: 'yudao-cloud',
icon: 'akar-icons:github',
message: 'https://github.com/YunaiV/yudao-cloud',
personal: 'Spring Cloud 微服务架构',
time: new Date()
},
{
name: 'yudao-ui-mall-uniapp',
icon: 'logos:vue',
message: 'https://github.com/yudaocode/yudao-ui-admin-uniapp',
personal: 'Vue3 + uniapp',
time: new Date()
},
{
name: 'yudao-ui-admin-vue2',
icon: 'logos:vue',
message: 'https://github.com/yudaocode/yudao-ui-admin-vue2',
personal: 'Vue2 + element-ui',
time: new Date()
}
]
projects = Object.assign(projects, data)
}
// // 使ResizeObserver
let notice = reactive<Notice[]>([]) onMounted(() => {
const getNotice = async () => { const resizeObserver = new ResizeObserver((entries) => {
const data = [ for (const entry of entries) {
{ const height = entry.contentRect.height
title: '系统支持 JDK 8/17/21,Vue 2/3', // taskInfoCardtaskNewCard
type: '通知', if (entry.target === taskInfoCard.value.$el) {
keys: ['通知', '8', '17', '21', '2', '3'], taskNewCard.value.$el.style.height = height + 'px'
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[]>([]) resizeObserver.observe(taskInfoCard.value.$el)
resizeObserver.observe(taskNewCard.value.$el)
rdiType(radio2.value)
//
onUnmounted(() => {
resizeObserver.disconnect()
})
})
const getShortcut = async () => {
const data = [ const tasks = reactive<any>([
{ {
name: 'Github', title: '义县一公司环保信息',
icon: 'akar-icons:github-fill', date: '2023-01-01',
url: 'github.io' user: '张三',
}, status: 1
{ },
name: 'Vue', {
icon: 'logos:vue', title: '锦州二公司安全检查',
url: 'vuejs.org' date: '2023-01-02',
}, user: '李四',
{ status: 2
name: 'Vite', },
icon: 'vscode-icons:file-type-vite', {
url: 'https://vitejs.dev/' title: '北镇三公司环评整改',
}, date: '2023-01-03',
{ user: '王五',
name: 'Angular', status: 1
icon: 'logos:angular-icon', },
url: 'github.io' {
}, title: '凌海四公司排污监测',
{ date: '2023-01-04',
name: 'React', user: '赵六',
icon: 'logos:react', status: 3
url: 'github.io' },
}, {
{ title: '黑山五公司设备巡检',
name: 'Webpack', date: '2023-01-05',
icon: 'logos:webpack', user: '孙七',
url: 'github.io' status: 2
} },
] {
shortcut = Object.assign(shortcut, data) title: '义县六公司安全培训',
date: '2023-01-06',
user: '周八',
status: 1
},
{
title: '大石桥七公司隐患排查',
date: '2023-01-07',
user: '吴九',
status: 3
},
{
title: '盘锦八公司应急演练',
date: '2023-01-08',
user: '郑十',
status: 2
},
{
title: '营口九公司废水处理',
date: '2023-01-09',
user: '钱十一',
status: 1
},
{
title: '阜新十公司空气监测',
date: '2023-01-10',
user: '刘十二',
status: 2
}
])
const notice2 = reactive<any>([
{
type: '资质逾期',
title: '义县一公司环保信息',
date: '2023-01-01 12:00:00',
days: '逾期1天'
},
{
type: '整改次数',
title: '义县一公司环保信息',
date: '2023-01-01 12:00:00',
days: '整改1次'
},
{
type: '资质逾期',
title: '义县一公司环保信息',
date: '2023-01-01 12:00:00',
days: '逾期1天'
},
{
type: '整改次数',
title: '义县一公司环保信息',
date: '2023-01-01 12:00:00',
days: '整改1次'
},
{
type: '资质逾期',
title: '义县一公司环保信息',
date: '2023-01-01 12:00:00',
days: '逾期1天'
},
{
type: '整改次数',
title: '义县一公司环保信息',
date: '2023-01-01 12:00:00',
days: '整改1次'
},
{
type: '资质逾期',
title: '锦州二公司安全检查',
date: '2023-01-02 12:00:00',
days: '逾期2天'
},
{
type: '整改次数',
title: '锦州二公司安全检查',
date: '2023-01-02 12:00:00',
days: '整改2次'
},
{
type: '资质逾期',
title: '北镇三公司环评整改',
date: '2023-01-03 12:00:00',
days: '逾期3天'
},
{
type: '整改次数',
title: '北镇三公司环评整改',
date: '2023-01-03 12:00:00',
days: '整改3次'
},
{
type: '资质逾期',
title: '凌海四公司排污监测',
date: '2023-01-04 12:00:00',
days: '逾期4天'
},
{
type: '整改次数',
title: '凌海四公司排污监测',
date: '2023-01-04 12:00:00',
days: '整改4次'
},
{
type: '资质逾期',
title: '黑山五公司设备巡检',
date: '2023-01-05 12:00:00',
days: '逾期5天'
},
{
type: '整改次数',
title: '黑山五公司设备巡检',
date: '2023-01-05 12:00:00',
days: '整改5次'
},
{
type: '资质逾期',
title: '义县六公司安全培训',
date: '2023-01-06 12:00:00',
days: '逾期6天'
},
{
type: '整改次数',
title: '义县六公司安全培训',
date: '2023-01-06 12:00:00',
days: '整改6次'
},
{
type: '资质逾期',
title: '大石桥七公司隐患排查',
date: '2023-01-07 12:00:00',
days: '逾期7天'
},
{
type: '整改次数',
title: '大石桥七公司隐患排查',
date: '2023-01-07 12:00:00',
days: '整改7次'
},
{
type: '资质逾期',
title: '盘锦八公司应急演练',
date: '2023-01-08 12:00:00',
days: '逾期8天'
},
{
type: '整改次数',
title: '盘锦八公司应急演练',
date: '2023-01-08 12:00:00',
days: '整改8次'
}
])
const notice = ref([])
const rdiType = (val: any) => {
//notice2typeradio2
if (val === '资质逾期') {
notice.value = notice2.filter((v: any) => v.type === '资质逾期')
} else {
notice.value = notice2.filter((v: any) => v.type === '整改次数')
}
} }
// //
const getUserAccessSource = async () => { const getUserAccessSource = async () => {
const data = [ const data = [
{ value: 335, name: 'analysis.directAccess' }, { value: 335, name: '执法一队' },
{ value: 310, name: 'analysis.mailMarketing' }, { value: 310, name: '执法二队' },
{ value: 234, name: 'analysis.allianceAdvertising' }, { value: 234, name: '执法三队' },
{ value: 135, name: 'analysis.videoAdvertising' }, { value: 135, name: '执法四队' },
{ value: 1548, name: 'analysis.searchEngines' } { value: 1548, name: '执法五队' }
] ]
set( set(
pieOptionsData, pieOptionsData,
@ -353,13 +362,13 @@ const barOptionsData = reactive<EChartsOption>(barOptions) as EChartsOption
// //
const getWeeklyUserActivity = async () => { const getWeeklyUserActivity = async () => {
const data = [ const data = [
{ value: 13253, name: 'analysis.monday' }, { value: 325, name: '一月' },
{ value: 34235, name: 'analysis.tuesday' }, { value: 423, name: '二月' },
{ value: 26321, name: 'analysis.wednesday' }, { value: 632, name: '三月' },
{ value: 12340, name: 'analysis.thursday' }, { value: 234, name: '四月' },
{ value: 24643, name: 'analysis.friday' }, { value: 464, name: '五月' },
{ value: 1322, name: 'analysis.saturday' }, { value: 322, name: '六月' },
{ value: 1324, name: 'analysis.sunday' } { value: 324, name: '七月' }
] ]
set( set(
barOptionsData, barOptionsData,
@ -368,7 +377,7 @@ const getWeeklyUserActivity = async () => {
) )
set(barOptionsData, 'series', [ set(barOptionsData, 'series', [
{ {
name: t('analysis.activeQuantity'), name: '任务数',
data: data.map((v) => v.value), data: data.map((v) => v.value),
type: 'bar' type: 'bar'
} }
@ -377,10 +386,6 @@ const getWeeklyUserActivity = async () => {
const getAllApi = async () => { const getAllApi = async () => {
await Promise.all([ await Promise.all([
getCount(),
getProject(),
getNotice(),
getShortcut(),
getUserAccessSource(), getUserAccessSource(),
getWeeklyUserActivity() getWeeklyUserActivity()
]) ])

282
src/views/Home/echarts-data.ts

@ -2,107 +2,51 @@ import { EChartsOption } from 'echarts'
const { t } = useI18n() const { t } = useI18n()
export const lineOptions: EChartsOption = {
title: {
text: t('analysis.monthlySales'),
left: 'center'
},
xAxis: {
data: [
t('analysis.january'),
t('analysis.february'),
t('analysis.march'),
t('analysis.april'),
t('analysis.may'),
t('analysis.june'),
t('analysis.july'),
t('analysis.august'),
t('analysis.september'),
t('analysis.october'),
t('analysis.november'),
t('analysis.december')
],
boundaryGap: false,
axisTick: {
show: false
}
},
grid: {
left: 20,
right: 20,
bottom: 20,
top: 80,
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
},
padding: [5, 10]
},
yAxis: {
axisTick: {
show: false
}
},
legend: {
data: [t('analysis.estimate'), t('analysis.actual')],
top: 50
},
series: [
{
name: t('analysis.estimate'),
smooth: true,
type: 'line',
data: [100, 120, 161, 134, 105, 160, 165, 114, 163, 185, 118, 123],
animationDuration: 2800,
animationEasing: 'cubicInOut'
},
{
name: t('analysis.actual'),
smooth: true,
type: 'line',
itemStyle: {},
data: [120, 82, 91, 154, 162, 140, 145, 250, 134, 56, 99, 123],
animationDuration: 2800,
animationEasing: 'quadraticOut'
}
]
}
export const pieOptions: EChartsOption = { export const pieOptions: EChartsOption = {
title: { title: {
text: t('analysis.userAccessSource'), text: '完成率90%',
left: 'center' left: 'center',
top: '35%',
textStyle: {
fontSize: 16,
fontWeight: 'bold'
}
}, },
tooltip: { tooltip: {
trigger: 'item', trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)' formatter: '{a} <br/>{b} : {c} ({d}%)'
}, },
legend: { legend: {
orient: 'vertical', orient: 'horizontal',
left: 'left', bottom: 10,
left: 'center',
data: [ data: [
t('analysis.directAccess'), '执法一队',
t('analysis.mailMarketing'), '执法二队',
t('analysis.allianceAdvertising'), '执法三队',
t('analysis.videoAdvertising'), '执法四队',
t('analysis.searchEngines') '执法五队',
] ]
}, },
series: [ series: [
{ {
name: t('analysis.userAccessSource'), name: t('analysis.userAccessSource'),
type: 'pie', type: 'pie',
radius: '55%', radius: ['40%', '70%'],
center: ['50%', '60%'], center: ['50%', '40%'],
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2
},
data: [ data: [
{ value: 335, name: t('analysis.directAccess') }, { value: 335, name: '执法一队' },
{ value: 310, name: t('analysis.mailMarketing') }, { value: 310, name: '执法二队' },
{ value: 234, name: t('analysis.allianceAdvertising') }, { value: 234, name:'执法三队' },
{ value: 135, name: t('analysis.videoAdvertising') }, { value: 135, name: '执法四队' },
{ value: 1548, name: t('analysis.searchEngines') } { value: 1548, name: '执法五队' }
] ]
} }
] ]
@ -110,7 +54,7 @@ export const pieOptions: EChartsOption = {
export const barOptions: EChartsOption = { export const barOptions: EChartsOption = {
title: { title: {
text: t('analysis.weeklyUserActivity'), text: '月均执法任务数',
left: 'center' left: 'center'
}, },
tooltip: { tooltip: {
@ -127,13 +71,13 @@ export const barOptions: EChartsOption = {
xAxis: { xAxis: {
type: 'category', type: 'category',
data: [ data: [
t('analysis.monday'), '一月',
t('analysis.tuesday'), '二月',
t('analysis.wednesday'), '三月',
t('analysis.thursday'), '四月',
t('analysis.friday'), '五月',
t('analysis.saturday'), '六月',
t('analysis.sunday')
], ],
axisTick: { axisTick: {
alignWithLabel: true alignWithLabel: true
@ -151,158 +95,4 @@ export const barOptions: EChartsOption = {
] ]
} }
export const radarOption: EChartsOption = {
legend: {
data: [t('workplace.personal'), t('workplace.team')]
},
radar: {
// shape: 'circle',
indicator: [
{ name: t('workplace.quote'), max: 65 },
{ name: t('workplace.contribution'), max: 160 },
{ name: t('workplace.hot'), max: 300 },
{ name: t('workplace.yield'), max: 130 },
{ name: t('workplace.follow'), max: 100 }
]
},
series: [
{
name: `xxx${t('workplace.index')}`,
type: 'radar',
data: [
{
value: [42, 30, 20, 35, 80],
name: t('workplace.personal')
},
{
value: [50, 140, 290, 100, 90],
name: t('workplace.team')
}
]
}
]
}
export const wordOptions = {
series: [
{
type: 'wordCloud',
gridSize: 2,
sizeRange: [12, 50],
rotationRange: [-90, 90],
shape: 'pentagon',
width: 600,
height: 400,
drawOutOfBound: true,
textStyle: {
color: function () {
return (
'rgb(' +
[
Math.round(Math.random() * 160),
Math.round(Math.random() * 160),
Math.round(Math.random() * 160)
].join(',') +
')'
)
}
},
emphasis: {
textStyle: {
shadowBlur: 10,
shadowColor: '#333'
}
},
data: [
{
name: 'Sam S Club',
value: 10000,
textStyle: {
color: 'black'
},
emphasis: {
textStyle: {
color: 'red'
}
}
},
{
name: 'Macys',
value: 6181
},
{
name: 'Amy Schumer',
value: 4386
},
{
name: 'Jurassic World',
value: 4055
},
{
name: 'Charter Communications',
value: 2467
},
{
name: 'Chick Fil A',
value: 2244
},
{
name: 'Planet Fitness',
value: 1898
},
{
name: 'Pitch Perfect',
value: 1484
},
{
name: 'Express',
value: 1112
},
{
name: 'Home',
value: 965
},
{
name: 'Johnny Depp',
value: 847
},
{
name: 'Lena Dunham',
value: 582
},
{
name: 'Lewis Hamilton',
value: 555
},
{
name: 'KXAN',
value: 550
},
{
name: 'Mary Ellen Mark',
value: 462
},
{
name: 'Farrah Abraham',
value: 366
},
{
name: 'Rita Ora',
value: 360
},
{
name: 'Serena Williams',
value: 282
},
{
name: 'NCAA baseball tournament',
value: 273
},
{
name: 'Point Break',
value: 265
}
]
}
]
}

7
src/views/Home/types.ts

@ -12,12 +12,7 @@ export type Project = {
time: Date | number | string time: Date | number | string
} }
export type Notice = {
title: string
type: string
keys: string[]
date: Date | number | string
}
export type Shortcut = { export type Shortcut = {
name: string name: string

2
src/views/system/policy/index.vue

@ -55,7 +55,7 @@
<!-- 列表 --> <!-- 列表 -->
<ContentWrap> <ContentWrap>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"> <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column label="id" align="center" prop="id" /> <!-- <el-table-column label="id" align="center" prop="id" /> -->
<el-table-column label="名称" align="center" prop="name" /> <el-table-column label="名称" align="center" prop="name" />
<el-table-column <el-table-column
label="创建时间" label="创建时间"

Loading…
Cancel
Save