This commit is contained in:
不做码农 2023-04-20 07:14:19 +08:00
parent a900d30a03
commit 5e0cacb556
13 changed files with 167 additions and 187 deletions

View File

@ -23,7 +23,6 @@
"axios": "^0.27.2",
"countup.js": "^2.1.0",
"echarts": "5.2.2",
"echarts-wordcloud": "^2.0.0",
"element-plus": "^2.3.2",
"file-saver": "2.0.5",
"fuse.js": "6.4.6",
@ -39,8 +38,7 @@
"vue-clipboard3": "^2.0.0",
"vue-cropper": "1.0.2",
"vue-i18n": "^9.2.2",
"vue-router": "^4.1.6",
"vue3-seamless-scroll": "^1.2.0"
"vue-router": "^4.1.6"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.1.0",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1682510872430" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1825" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M512 1024C229.222 1024 0 794.778 0 512S229.222 0 512 0s512 229.222 512 512-229.222 512-512 512z m259.149-568.883h-290.74a25.293 25.293 0 0 0-25.292 25.293l-0.026 63.206c0 13.952 11.315 25.293 25.267 25.293h177.024c13.978 0 25.293 11.315 25.293 25.267v12.646a75.853 75.853 0 0 1-75.853 75.853h-240.23a25.293 25.293 0 0 1-25.267-25.293V417.203a75.853 75.853 0 0 1 75.827-75.853h353.946a25.293 25.293 0 0 0 25.267-25.292l0.077-63.207a25.293 25.293 0 0 0-25.268-25.293H417.152a189.62 189.62 0 0 0-189.62 189.645V771.15c0 13.977 11.316 25.293 25.294 25.293h372.94a170.65 170.65 0 0 0 170.65-170.65V480.384a25.293 25.293 0 0 0-25.293-25.267z" fill="#C71D23" p-id="1826"></path></svg>

After

Width:  |  Height:  |  Size: 1010 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

View File

@ -11,21 +11,20 @@
</div>
</template>
<script setup>
import { getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance()
const menuList = ref([
{ path: '/dashboard', title: '控制台', color: '#40c9c6', name: 'dashboard' },
{ path: '/tool/gen', title: '代码生成', color: '#40c9c6', name: 'code', perms: ['tool:gen:list'] },
{ path: '/tool/file', title: '文件存储', color: '#6A5ACD', name: 'upload', perms: ['tool:file:list'] },
// // { path: '/system/user', title: '', color: '#7FFF00', name: 'peoples' },
{ path: '/system/dict', title: '字典管理', color: '#B0E0E6', name: 'dict', perms: ['system:dict:list'] },
{ path: '/monitor/job', title: '定时任务', color: '#D2691E', name: 'job', perms: ['monitor:job:list'] },
{ path: '/system/log/operlog', title: '操作日志', color: '#D2691E', name: 'form', perms: ['monitor:operlog:list'] },
{ path: '/system/log/operlog', title: '操作日志', color: '#D2691E', name: 'form', perms: ['monitor:operlog:list'] }
// { path: '/system/log/logininfor', title: '', color: '#D2691E', name: 'logininfor' }
])
function checkPermi(v) {
if (v && v.permi) {
if (v && v.perms) {
return proxy.$auth.hasPermiOr(v.perms)
}
return true
@ -34,12 +33,13 @@ function checkPermi(v) {
<style lang="scss" scoped>
.tool-wrap {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
.tool-item {
display: flex;
flex-direction: column;
text-align: center;
width: 110px;
width: 100px;
margin-bottom: 30px;
.card-panel-icon {
width: 30px;

View File

@ -32,7 +32,7 @@
<div class="card-panel-description">
<!-- <div class="card-panel-text" v-waves>{{ $t('layout.amount') }}</div>
<div id="amount" class="card-panel-num">{{ state.amount }}</div> -->
<el-statistic :value="state.order" v-waves :title="$t('layout.amount')">
<el-statistic :value="state.order" :title="$t('layout.amount')">
<template #title>
<div style="display: inline-flex; align-items: center">{{ $t('layout.amount') }}</div>
</template>
@ -55,13 +55,21 @@
</el-statistic>
<div class="statistic-footer">
<div class="footer-item">
<span>than yesterday</span>
<span>环比</span>
<span style="color: green">
16%
<el-icon>
<CaretTop />
</el-icon>
</span>
<span>同比</span>
<span style="color: red">
-16%
<el-icon>
<CaretBottom />
</el-icon>
</span>
</div>
</div>
</div>
@ -104,15 +112,18 @@ function handleSetLineChartData(type) {
}
.card-panel {
height: 108px;
height: 90px;
cursor: pointer;
font-size: 12px;
position: relative;
overflow: hidden;
color: #666;
background: var(--base-bg-main);
// background: var(--base-bg-main);
box-shadow: 4px 4px 40px rgba(0, 0, 0, 0.05);
border-color: rgba(0, 0, 0, 0.05);
display: flex;
justify-content: space-between;
align-items: center;
&:hover {
.card-panel-icon-wrapper {
@ -153,8 +164,8 @@ function handleSetLineChartData(type) {
}
.card-panel-icon-wrapper {
float: left;
margin: 14px 0 0 14px;
// float: left;
margin: 0px 0 0 14px;
padding: 16px;
transition: all 0.38s ease-out;
border-radius: 6px;
@ -162,13 +173,13 @@ function handleSetLineChartData(type) {
.card-panel-icon {
float: left;
font-size: 48px;
font-size: 28px;
}
.card-panel-description {
float: right;
// float: right;
font-weight: bold;
margin: 26px;
margin-right: 20px;
margin-left: 0px;
.card-panel-text {

View File

@ -6,7 +6,7 @@
import * as echarts from 'echarts'
import { useDebounceFn } from '@vueuse/core'
import 'echarts-wordcloud'
// import 'echarts-wordcloud'
const { proxy } = getCurrentInstance()

View File

@ -1,98 +1,60 @@
<template>
<div class="dashboard-editor-container home">
<div class="home">
<!-- 用户信息 -->
<el-row :gutter="15">
<el-col :md="24" :lg="12" :xl="12" class="mb10">
<el-col :md="24" :lg="24" :xl="24" class="mb10">
<el-card shadow="hover">
<template #header>
<span>{{ $t('layout.myWorkbench') }}</span>
</template>
<div class="user-item">
<div class="user-item-left">
<img :src="userInfo.avatar" />
</div>
<div class="user-item-right overflow">
<div class="user-item-right">
<el-row>
<el-col :xs="24" :md="24" class="right-title mb20 one-text-overflow">
{{ userInfo.welcomeMessage + ',' + userInfo.nickName + ' ,' + userInfo.welcomeContent }}
</el-col>
<el-col :xs="24" :sm="24" :md="24">
<el-row>
<el-col :xs="24" :lg="8" class="right-l-v">
<div class="right-label">{{ $t('common.nickName') }}</div>
<div class="right-value">{{ userInfo.nickName }}</div>
</el-col>
<el-col :xs="24" :lg="16" class="right-l-v">
<div class="right-label">{{ $t('layout.identity') }}</div>
<div class="right-value">
<span v-for="item in userInfo.roles" :key="item.roleId">
{{ item.roleName }}
</span>
</div>
{{ userInfo.welcomeMessage }} <strong>{{ userInfo.nickName }}</strong> {{ userInfo.welcomeContent }}
</el-col>
</el-row>
</el-col>
<el-col :md="24" class="mt10">
<el-row>
<el-col :xs="24" :sm="12" :md="8" class="right-l-v">
<div class="right-label one-text-overflow">IP</div>
<div class="right-value one-text-overflow">
{{ userInfo.loginIP }}
</div>
</el-col>
<el-col :xs="24" :sm="12" :md="16" class="right-l-v">
<div class="right-label one-text-overflow">{{ $t('common.time') }}</div>
<div class="right-value one-text-overflow">
{{ currentTime }}
</div>
</el-col>
</el-row>
</el-col>
<el-col :lg="24" class="mt10">
<el-button icon="edit">
<router-link to="/user/profile">{{ $t('layout.modifyInformation') }}</router-link>
</el-button>
</el-col>
</el-row>
</div>
</div>
</el-card>
</el-col>
<el-col :md="24" :lg="12" :xl="12" class="mb10">
<el-card shadow="hover">
<template #header>
<div>
<span>{{ $t('layout.onlineUsers') }}</span>
<el-button class="home-card-more" text @click="onOpenGitee">{{ $t('btn.more') }}</el-button>
</div>
</template>
<div class="info">
<el-scrollbar wrap-class="scrollbar-wrapper">
<div class="info-scroll">
<ul class="info-ul">
<li v-for="(v, k) in onlineUsers" :key="k" class="info-item">
<div class="info-item-left" v-text="v.name"></div>
<div>{{ v.userIP }}({{ v.location }})</div>
<div class="info-item-right" v-text="dayjs(v.loginTime).format('MM/DD日HH:mm:ss')"></div>
<el-button text @click="onChat(v)" icon="bell" v-hasRole="['admin']">通知</el-button>
</li>
</ul>
</div>
</el-scrollbar>
</div>
</el-card>
</el-col>
</el-row>
<el-row :gutter="15">
<el-col :md="24" :lg="24" :xl="24" class="mb10">
<el-col :md="12" :lg="12" :xl="12" class="mb10">
<el-card shadow="hover">
<template #header>
<span>常用功能</span>
<div>
<span><svg-icon name="peoples" />{{ $t('layout.onlineUsers') }}</span>
<el-button class="home-card-more" text @click="onOpenGitee">{{ $t('btn.more') }}</el-button>
</div>
</template>
<CommonMenu></CommonMenu>
<div class="info">
<el-scrollbar wrap-class="scrollbar-wrapper">
<div v-for="(v, k) in onlineUsers" :key="k" class="info-item">
<div class="info-item-left" v-text="v.name"></div>
<div>{{ v.userIP }}({{ v.location }})</div>
<div class="info-item-right" v-text="dayjs(v.loginTime).format('MM/DD日HH:mm:ss')"></div>
<el-button text @click="onChat(v)" icon="bell" v-hasRole="['admin']">通知</el-button>
</div>
</el-scrollbar>
</div>
</el-card>
</el-col>
<el-col :md="12" :lg="12" :xl="12" class="mb10">
<el-card shadow="hover">
<template #header>
<span><svg-icon name="tool" /> 常用功能</span>
</template>
<div class="info">
<el-scrollbar wrap-class="scrollbar-wrapper"> <CommonMenu></CommonMenu></el-scrollbar>
</div>
</el-card>
</el-col>
</el-row>
@ -123,13 +85,13 @@
</div>
</el-col>
</el-row>
<el-row :gutter="32">
<!-- <el-row :gutter="32">
<el-col :xs="24" :sm="24" :lg="24">
<div class="chart-wrapper">
<WordCloudChat :data="data.wordCloud" />
</div>
</el-col>
</el-row>
</el-row> -->
</div>
</template>
@ -139,7 +101,7 @@ import LineChart from './dashboard/LineChart'
import RaddarChart from './dashboard/RaddarChart'
import PieChart from './dashboard/PieChart'
import BarChart from './dashboard/BarChart'
import WordCloudChat from './dashboard/WordCloud.vue'
// import WordCloudChat from './dashboard/WordCloud.vue'
import CommonMenu from './components/CommonMenu'
import dayjs from 'dayjs'
@ -253,7 +215,6 @@ function onChat(item) {
<style lang="scss" scoped>
.home {
overflow: hidden;
.home-card-more {
float: right;
padding: 3px 0;
@ -261,7 +222,7 @@ function onChat(item) {
}
.user-item {
height: 198px;
// height: 198px;
display: flex;
align-items: center;
.user-item-left {
@ -269,6 +230,7 @@ function onChat(item) {
height: 60px;
border-radius: 50%;
overflow: hidden;
margin-right: 10px;
img {
width: 100%;
height: 100%;
@ -276,32 +238,15 @@ function onChat(item) {
}
.user-item-right {
flex: 1;
padding: 15px;
.right-title {
font-size: 20px;
}
.right-l-v {
font-size: 13px;
display: flex;
.right-label {
color: gray;
width: 75px;
}
.right-value {
flex: 1;
}
}
}
}
.info {
height: 189px;
height: 200px;
// overflow-y: scroll;
.info-scroll {
height: 100%;
overflow: auto;
.info-ul {
list-style: none;
padding: 0;
.info-item {
display: flex;
font-size: 13px;
@ -319,6 +264,7 @@ function onChat(item) {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
margin-right: 10px;
}
.info-item-right {
width: 140px;
@ -327,18 +273,11 @@ function onChat(item) {
}
}
}
}
}
}
.dashboard-editor-container {
background-color: var(--base-bg-main);
position: relative;
.chart-wrapper {
.chart-wrapper {
background: var(--base-bg-main);
padding: 16px 16px 0;
margin-bottom: 32px;
}
}
@media (max-width: 1024px) {

View File

@ -55,9 +55,9 @@
</el-form-item>
<div class="other-login" v-if="defaultSettings.showOtherLogin">
<el-divider>{{ $t('login.otherLoginWay') }}</el-divider>
<img src="../assets/icons/gitee-fill-round.png" alt="" class="login-icon" @click="onAuth('GITEE')" />
<img src="../assets/icons/github-fill.png" alt="" class="login-icon" @click="onAuth('GITHUB')" />
<img src="../assets/icons/wechat-fill.png" alt="" class="login-icon" />
<span @click="onAuth('GITHUB')" title="github"><svg-icon name="github" className="login-icon"></svg-icon></span>
<span @click="onAuth('GITEE')" title="gitee"><svg-icon name="gitee" className="login-icon"></svg-icon></span>
</div>
</el-form>

View File

@ -122,16 +122,6 @@
<dict-tag :options="options.businessTypeOptions" :value="form.businessType" />
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="请求参数:">
<el-input type="textarea" disabled rows="5" v-model="form.operParam"> </el-input>
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="返回结果:">
<el-input type="textarea" disabled rows="5" v-model="form.jsonResult"> </el-input>
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="操作状态:">
<dict-tag :options="options.statusOptions" :value="form.status"></dict-tag>
@ -140,6 +130,16 @@
<el-col :lg="12">
<el-form-item label="操作时间:">{{ parseTime(form.operTime) }}</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="请求参数:">
<el-input type="textarea" rows="5" v-model="form.operParam"> </el-input>
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="返回结果:">
<el-input type="textarea" rows="10" v-model="form.jsonResult"> </el-input>
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="异常信息:" v-if="form.status === 1">{{ form.errorMsg }}</el-form-item>
</el-col>

View File

@ -4,7 +4,10 @@
<el-col :lg="24" class="card-box" v-if="server.cpu">
<el-card class="box-card">
<template #header>
<Cpu style="width: 1em; height: 1em; vertical-align: middle" /> <span style="vertical-align: middle">CPU/内存</span>
<div class="card-header">
<div><Cpu style="width: 1em; height: 1em; vertical-align: middle" /> <span style="vertical-align: middle">CPU/内存</span></div>
<el-button text @click="getList()">刷新</el-button>
</div>
</template>
<div class="col-item">
@ -32,6 +35,14 @@
</el-tooltip>
<div class="footer">{{ server.cpu.usedRam }} / {{ server.cpu.totalRAM }}</div>
</div>
<div class="col-item">
<div class="title">.NETCore服务</div>
<div class="content">
<el-progress type="dashboard" :percentage="parseFloat(appPercent)" />
</div>
<div class="footer" v-if="server.app">{{ server.app.appRAM }}</div>
</div>
</el-card>
</el-col>
@ -130,13 +141,13 @@
<div class="cell">环境变量</div>
</td>
<td>
<div class="cell" v-if="server.app">{{ server.app.name }}</div>
<div v-if="server.app">{{ server.app.name }}</div>
</td>
<td>
<div class="cell">.Net版本</div>
</td>
<td>
<div class="cell" v-if="server.app">{{ server.app.version }}</div>
<div v-if="server.app">{{ server.app.version }}</div>
</td>
</tr>
<tr>
@ -144,13 +155,13 @@
<div class="cell">启动时间</div>
</td>
<td>
<div class="cell" v-if="server.app">{{ server.app.startTime }}</div>
<div v-if="server.app">{{ server.app.startTime }}</div>
</td>
<td>
<div class="cell">运行时长</div>
</td>
<td>
<div class="cell" v-if="server.app">{{ server.app.runTime }}</div>
<div v-if="server.app">{{ server.app.runTime }}</div>
</td>
</tr>
<tr>
@ -158,13 +169,13 @@
<div class="cell">占用内存</div>
</td>
<td>
<div class="cell" v-if="server.app">{{ server.app.appRAM }}</div>
<div v-if="server.app">{{ server.app.appRAM }}</div>
</td>
<td>
<div class="cell">启动地址</div>
</td>
<td>
<div class="cell" v-if="server.app">{{ server.app.host }}</div>
<div v-if="server.app">{{ server.app.host }}</div>
</td>
</tr>
<tr>
@ -172,13 +183,13 @@
<div class="cell">ContentRootPath</div>
</td>
<td>
<div class="cell" v-if="server.app">{{ server.app.rootPath }}</div>
<div v-if="server.app">{{ server.app.rootPath }}</div>
</td>
<td>
<div class="cell">webPath</div>
</td>
<td>
<div class="cell" v-if="server.app">{{ server.app.webRootPath }}</div>
<div v-if="server.app">{{ server.app.webRootPath }}</div>
</td>
</tr>
</tbody>
@ -196,6 +207,7 @@ import { onBeforeRouteLeave } from 'vue-router'
onBeforeRouteLeave((to) => {
clear()
})
const appPercent = ref(0)
//
const server = ref([])
const intervalId = ref(null)
@ -230,7 +242,19 @@ function clear() {
clearInterval(intervalId.value)
intervalId.value = null
}
watch(
() => server.value,
(val) => {
if (val && val.app) {
const appRam = val.app.appRAM.replace(' MB', '')
const totalRam = val.cpu.totalRAM.replace('GB', '') * 1024
const p = appRam / totalRam
appPercent.value = p.toFixed(2)
}
},
{ immediate: true }
)
getList()
openLoading()
dataRefreh()
@ -267,4 +291,9 @@ table tr {
width: 200px;
display: inline-block;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View File

@ -136,11 +136,13 @@
<el-col :lg="24">
<el-form-item prop="langKey">
<template #label>
<span>
<el-tooltip content="翻译keyegmessage.title" placement="top">
<el-icon :size="15">
<questionFilled />
</el-icon>
</el-tooltip>
</span>
{{ $t('languageKey') }}
</template>
<el-input v-model="form.langKey" placeholder="请输入语言key" />
@ -194,7 +196,7 @@ const queryParams = reactive({
langCode: undefined,
langKey: undefined,
addtime: undefined,
showMode: 2, // 1table 2
showMode: 2 // 1table 2
})
//
const title = ref('')
@ -209,9 +211,9 @@ const state = reactive({
id: [{ required: true, message: 'id不能为空', trigger: 'blur', type: 'number' }],
// langCode: [{ required: true, message: 'code', trigger: 'change' }],
langKey: [{ required: true, pattern: /^[A-Za-z].+$/, message: '语言key不能为空', trigger: 'change' }],
langName: [{ required: true, message: '内容不能为空', trigger: 'blur' }],
langName: [{ required: true, message: '内容不能为空', trigger: 'blur' }]
},
options: {},
options: {}
})
var dictParams = [{ dictType: 'sys_lang_type' }]
@ -236,7 +238,7 @@ watch(
() => {
getList()
},
{ immediate: true },
{ immediate: true }
)
function getList() {
proxy.addDateRange(queryParams, proxy.dateRangeAddtime, 'Addtime')
@ -264,19 +266,19 @@ function reset() {
{
langCode: 'zh-cn',
label: proxy.$t('common.chinese'),
langName: undefined,
langName: undefined
},
{
langCode: 'zh-tw',
label: proxy.$t('common.traditionalChinese'),
langName: undefined,
langName: undefined
},
{
langCode: 'en',
label: proxy.$t('common.english'),
langName: undefined,
},
],
langName: undefined
}
]
}
proxy.resetForm('formRef')
}
@ -323,7 +325,7 @@ function handleUpdate(row) {
opertype.value = 2
form.value = {
...data,
...data
}
}
})
@ -338,7 +340,7 @@ function handleUpdateP(row) {
opertype.value = 2
form.value = {
...data,
...data
}
}
})
@ -382,7 +384,7 @@ function handleExport() {
.$confirm('是否确认导出所有多语言配置数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
type: 'warning'
})
.then(function () {
return exportCommonLang(queryParams)