优化细节

This commit is contained in:
xh
2025-12-17 09:19:54 +08:00
parent 5acfe8501c
commit d6a344d910
14 changed files with 190 additions and 179 deletions
+8 -8
View File
@@ -17,14 +17,14 @@
<link rel="stylesheet" preload href="/loading.css" />
<script src="/XErr.umd.js"></script>
<script>
// const xErr = new XErr.Base(
// {
// Dns: `${location.origin}/api`,
// Pid: 'e19e3be20de94f49b68fafb4c30668bc',
// Uid: ''
// },
// new XErr.Web({})
// )
const xErr = new XErr.Base(
{
Dns: `${location.origin}/api`,
Pid: 'e19e3be20de94f49b68fafb4c30668bc',
Uid: ''
},
new XErr.Web({})
)
// xErr.SetUid(2) //设置用户ID
</script>
</head>
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -13,7 +13,7 @@ export type type_flow_apply = {
flowProcessData?: string
flowProcessDataList?: string
formValue?: string
status?: number
status?: number // 状态:1待提交,2审批中,3审批完成,4审批失败
isDelete?: number
createTime?: string
updateTime?: string
+17 -13
View File
@@ -155,9 +155,12 @@
<el-table-column label="格式" prop="ext" min-width="80"></el-table-column>
<el-table-column prop="createTime" label="上传时间" min-width="160" />
<el-table-column label="操作" width="150" fixed="right">
<el-table-column label="操作" width="190" fixed="right">
<template #default="{ row }">
<div class="inline-block" v-perms="['admin:common:album:albumRename']">
<div
class="inline-block mr-2"
v-perms="['admin:common:album:albumRename']"
>
<popover-input
@confirm="handleFileRename($event, row.id)"
size="default"
@@ -167,28 +170,29 @@
show-limit
teleported
>
<el-button type="primary" link> 重命名 </el-button>
<el-link type="primary" link> 重命名 </el-link>
</popover-input>
</div>
<div class="inline-block">
<el-button type="primary" link @click.stop="handlePreview(row.uri)">
<div class="inline-block mr-2">
<el-link type="primary" link @click.stop="handlePreview(row.uri)">
查看
</el-button>
</el-link>
</div>
<div class="inline-block" v-perms="['admin:common:album:albumDel']">
<el-button
<div
class="inline-block mr-2"
v-perms="['admin:common:album:albumDel']"
>
<el-link
type="primary"
link
@click.stop="batchFileDelete([row.id])"
>
删除
</el-button>
</el-link>
</div>
<div class="inline-block">
<el-button type="primary" link @click.stop="handlePreview(row.uri)">
下载(待开发)
</el-button>
<div class="inline-block mr-2">
<el-link type="primary" :href="row.uri" download>下载</el-link>
</div>
</template>
</el-table-column>
@@ -14,7 +14,7 @@
</div>
<el-dropdown @command="handleCommand">
<span class="flex items-center px-3">
<icon :size="16" name="el-icon-arrow-down" />
<icon :size="16" name="el-icon-ArrowDown" />
</span>
<template #dropdown>
<el-dropdown-menu>
@@ -1,6 +1,9 @@
<template>
<template v-if="!route.meta?.hidden">
<app-link v-if="!hasShowChild" :to="`${routePath}?${queryStr}`">
<app-link
v-if="!hasShowChild"
:to="`${routePath}${queryStr?.length ? `?${queryStr}` : ''}`"
>
<el-menu-item :index="routePath">
<Icon :size="16" v-if="routeMeta?.icon" :name="routeMeta?.icon" />
<template #title>
+3 -1
View File
@@ -29,7 +29,8 @@ export type ECOption = ComposeOption<
import {
BarChart,
LineChart,
PieChart
PieChart,
GaugeChart
// MapChart,//地图
// PictorialBarChart,//象形柱状图
// RadarChart,//雷达图
@@ -71,6 +72,7 @@ echarts.use([
BarChart,
LineChart,
PieChart,
GaugeChart,
// MapChart,
// RadarChart,
// PictorialBarChart,
+2 -1
View File
@@ -44,6 +44,7 @@ import Popup from '@/components/popup/index.vue'
import feedback from '@/utils/feedback'
import { shallowRef, ref, computed, reactive } from 'vue'
import type { PropType } from 'vue'
import dayjs from 'dayjs'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
@@ -152,7 +153,7 @@ function handleTemplateChange(id: number) {
console.log(id)
flow_template.value.find((item: any) => {
if (item.id == id) {
formData.flowName = item.flowName
formData.flowName = item.flowName + '_' + dayjs().format('YYYY-MM-DD-HHmm')
// formData.flowGroup = item.flowGroup
// formData.flowRemark = item.flowRemark
// formData.flowFormData = item.flowFormData
+21 -15
View File
@@ -1,7 +1,13 @@
<template>
<div class="index-lists">
<el-card class="!border-none" shadow="never">
<el-form ref="formRef" class="mb-[-16px]" :model="queryParams" :inline="true">
<el-form
ref="formRef"
class="mb-[-16px]"
label-width="80px"
:model="queryParams"
:inline="true"
>
<!-- <el-form-item label="模板" prop="templateId">
<el-input v-model="queryParams.templateId" />
</el-form-item> -->
@@ -68,7 +74,7 @@
</div>
<el-table class="mt-4" size="large" v-loading="pager.loading" :data="pager.lists">
<el-table-column label="申请人昵称" prop="applyUserNickname" min-width="100" />
<el-table-column label="流程名称" prop="flowName" min-width="100" />
<el-table-column label="流程名称" prop="flowName" min-width="160" />
<el-table-column label="流程分类" prop="flowGroup" min-width="100">
<template #default="{ row }">
<dict-value :options="dictData.flow_group" :value="row.flowGroup" />
@@ -77,13 +83,13 @@
<el-table-column label="流程描述" prop="flowRemark" min-width="100" />
<!-- <el-table-column label="formValue" prop="formValue" min-width="100" /> -->
<el-table-column label="状态" prop="status" min-width="100">
<el-table-column label="状态" prop="status" width="100">
<template #default="{ row }">
<dict-value :options="dictData.flow_apply_status" :value="row.status" />
</template>
</el-table-column>
<el-table-column label="更新时间" prop="updateTime" min-width="130" />
<el-table-column label="创建时间" prop="createTime" min-width="130" />
<el-table-column label="更新时间" prop="updateTime" width="180" />
<el-table-column label="创建时间" prop="createTime" width="180" />
<el-table-column label="操作" width="180" fixed="right">
<template #default="{ row }">
<el-button
@@ -152,7 +158,7 @@ import {
flow_apply_detail
} from '@/api/flow/flow_apply'
import type { type_flow_apply } from '@/api/flow/flow_apply'
import type { type_flow_apply, type_flow_apply_query } from '@/api/flow/flow_apply'
import { useDictData } from '@/hooks/useDictOptions'
import type { type_dict } from '@/hooks/useDictOptions'
@@ -174,16 +180,16 @@ const viewFormRef = shallowRef<InstanceType<typeof ViewForm>>()
const ApplySubmitRef = shallowRef<InstanceType<typeof ApplySubmit>>()
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
const showEdit = ref(false)
const queryParams = reactive({
templateId: '',
const queryParams = reactive<type_flow_apply_query>({
templateId: undefined,
applyUserId: userStore.userInfo?.id,
applyUserNickname: '',
flowName: '',
flowGroup: '',
flowRemark: '',
flowFormData: '',
flowProcessData: '',
status: ''
applyUserNickname: undefined,
flowName: undefined,
flowGroup: undefined,
flowRemark: undefined,
flowFormData: undefined,
flowProcessData: undefined,
status: undefined
})
const { pager, getLists, resetPage, resetParams } = usePaging<type_flow_apply>({
+4 -1
View File
@@ -80,7 +80,9 @@ import useUserStore from '@/stores/modules/user'
import ApplySubmit from './components/apply_submit.vue'
// import ViewForm from './components/ViewForm.vue'
const ViewForm = defineAsyncComponent(() => import('./components/ViewForm.vue'))
import Back from './components/Back.vue'
// import Back from './components/Back.vue'
const Back = defineAsyncComponent(() => import('./components/Back.vue'))
const userStore = useUserStore()
defineOptions({
@@ -162,6 +164,7 @@ const closeBack = () => {
console.log('closeBack')
viewFormRef.value?.closeFn()
getLists()
}
getLists()
+76 -105
View File
@@ -4,111 +4,65 @@
<el-card class="!border-none" shadow="never">
<div>
<div class="mb-4 lg">基本信息</div>
<div class="el-table--enable-row-transition el-table--large el-table">
<el-scrollbar>
<table class="el-table__body" cellspacing="0">
<tbody>
<tr class="el-table__row">
<td class="el-table__cell">
<div class="cell">Redis版本</div>
</td>
<td class="el-table__cell">
<div class="cell">{{ baseInfo.redis_version }}</div>
</td>
<td class="el-table__cell">
<div class="cell">运行模式</div>
</td>
<td class="el-table__cell">
<div class="cell">
{{
baseInfo.redis_mode == 'standalone'
? '单机'
: '集群'
}}
</div>
</td>
<td class="el-table__cell">
<div class="cell">端口</div>
</td>
<td class="el-table__cell">
<div class="cell">{{ baseInfo.tcp_port }}</div>
</td>
<td class="el-table__cell">
<div class="cell">客户端数</div>
</td>
<td class="el-table__cell">
<div class="cell">{{ baseInfo.connected_clients }}</div>
</td>
</tr>
<tr class="el-table__row">
<td class="el-table__cell">
<div class="cell">运行时间()</div>
</td>
<td class="el-table__cell">
<div class="cell">{{ baseInfo.uptime_in_days }}</div>
</td>
<td class="el-table__cell">
<div class="cell">使用内存</div>
</td>
<td class="el-table__cell">
<div class="cell">
{{ baseInfo.used_memory_human }}
</div>
</td>
<td class="el-table__cell">
<div class="cell">使用CPU</div>
</td>
<td class="el-table__cell">
<div class="cell">
{{ baseInfo.used_cpu_user_children }}
</div>
</td>
<td class="el-table__cell">
<div class="cell">内存配置</div>
</td>
<td class="el-table__cell">
<div class="cell">{{ baseInfo.maxmemory_human }}</div>
</td>
</tr>
<tr class="el-table__row">
<td class="el-table__cell">
<div class="cell">AOF是否开启</div>
</td>
<td class="el-table__cell">
<div class="cell">
{{ baseInfo.aof_enabled == 0 ? '开启' : '关闭' }}
</div>
</td>
<td class="el-table__cell">
<div class="cell">RDB是否成功</div>
</td>
<td class="el-table__cell">
<div class="cell">
{{ baseInfo.aof_enabled == 'ok' ? '成功' : '失败' }}
</div>
</td>
<td class="el-table__cell">
<div class="cell">Key数量</div>
</td>
<td class="el-table__cell">
<div class="cell">{{ baseInfo.dbSize }}</div>
</td>
<td class="el-table__cell">
<div class="cell">网络入口/出口</div>
</td>
<td class="el-table__cell">
<div class="cell">
{{ baseInfo.instantaneous_input_kbps }}
/
{{ baseInfo.instantaneous_output_kbps }}
</div>
</td>
</tr>
</tbody>
</table>
</el-scrollbar>
</div>
<el-row :gutter="20">
<el-col :xl="4" :lg="6" :md="8" :sm="12" class="info-item">
<div class="info-label">Redis版本</div>
<div class="info-value">{{ baseInfo.redis_version }}</div>
</el-col>
<el-col :xl="4" :lg="6" :md="8" :sm="12" class="info-item">
<div class="info-label">运行模式</div>
<div class="info-value">
{{ baseInfo.redis_mode == 'standalone' ? '单机' : '集群' }}
</div>
</el-col>
<el-col :xl="4" :lg="6" :md="8" :sm="12" class="info-item">
<div class="info-label">端口</div>
<div class="info-value">{{ baseInfo.tcp_port }}</div>
</el-col>
<el-col :xl="4" :lg="6" :md="8" :sm="12" class="info-item">
<div class="info-label">客户端数</div>
<div class="info-value">{{ baseInfo.connected_clients }}</div>
</el-col>
<el-col :xl="4" :lg="6" :md="8" :sm="12" class="info-item">
<div class="info-label">运行时间()</div>
<div class="info-value">{{ baseInfo.uptime_in_days }}</div>
</el-col>
<el-col :xl="4" :lg="6" :md="8" :sm="12" class="info-item">
<div class="info-label">使用内存</div>
<div class="info-value">{{ baseInfo.used_memory_human }}</div>
</el-col>
<el-col :xl="4" :lg="6" :md="8" :sm="12" class="info-item">
<div class="info-label">使用CPU</div>
<div class="info-value">{{ baseInfo.used_cpu_user_children }}</div>
</el-col>
<el-col :xl="4" :lg="6" :md="8" :sm="12" class="info-item">
<div class="info-label">内存配置</div>
<div class="info-value">{{ baseInfo.maxmemory_human }}</div>
</el-col>
<el-col :xl="4" :lg="6" :md="8" :sm="12" class="info-item">
<div class="info-label">AOF是否开启</div>
<div class="info-value">
{{ baseInfo.aof_enabled == 0 ? '开启' : '关闭' }}
</div>
</el-col>
<el-col :xl="4" :lg="6" :md="8" :sm="12" class="info-item">
<div class="info-label">RDB是否成功</div>
<div class="info-value">
{{ baseInfo.aof_enabled == 'ok' ? '成功' : '失败' }}
</div>
</el-col>
<el-col :xl="4" :lg="6" :md="8" :sm="12" class="info-item">
<div class="info-label">Key数量</div>
<div class="info-value">{{ baseInfo.dbSize }}</div>
</el-col>
<el-col :xl="4" :lg="6" :md="8" :sm="12" class="info-item">
<div class="info-label">网络入/出口</div>
<div class="info-value">
{{ baseInfo.instantaneous_input_kbps }} /
{{ baseInfo.instantaneous_output_kbps }}
</div>
</el-col>
</el-row>
</div>
</el-card>
@@ -131,6 +85,7 @@
<div>
<div class="mb-10">内存信息</div>
<div class="flex h-[300px] items-center">
<!-- {{ chartOptions.memoryChartOption }} -->
<echart-component
:option="chartOptions.memoryChartOption"
:autoresize="true"
@@ -265,4 +220,20 @@ getSystemCache()
.el-table .el-table__cell {
min-width: 120px;
}
.info-item {
display: flex;
padding: 12px 0;
border-bottom: 1px solid #ebeef5;
}
.info-label {
font-weight: 500;
margin-bottom: 4px;
color: #303133;
width: 110px;
}
.info-value {
color: #949597;
}
</style>
+38 -29
View File
@@ -97,7 +97,8 @@
import { reactive, onDeactivated, onActivated, onMounted, useTemplateRef, onUnmounted } from 'vue'
import { getWorkbench } from '@/api/app'
import feedback from '@/utils/feedback'
// import feedback from '@/utils/feedback'
import { useWebSocket } from '@vueuse/core'
import useUserStore from '@/stores/modules/user'
import type { ECOption } from '@/utils/echart'
@@ -164,7 +165,7 @@ const getData = async () => {
visitorOption.series[0].data = res.visitor.list
visitorChartRef.value?.setOption(visitorOption as ECOption)
}
const timer: any = null
function updateChart(val) {
visitorOption.xAxis.data.push(new Date().toLocaleTimeString())
visitorOption.series[0].data.push(val)
@@ -176,49 +177,57 @@ function updateChart(val) {
}
visitorChartRef.value?.setOption(visitorOption as ECOption)
}
// // 用户 A,加入 room1
const wsA = new WebSocket(`ws://localhost:8080/api/ws?token=${userStore.token}&room=room1`)
// // 用户 B,加入 room1
// const wsB = new WebSocket('ws://localhost:8080/api/ws?uid=userB&room=room1')
// // 用户 C,不加入房间
// const wsC = new WebSocket('ws://localhost:8080/api/ws?uid=userC')
wsA.onmessage = (event) => {
console.log('用户 A 收到消息:', event.data)
// {"onlineCount":9}
feedback.msgSuccess(event.data)
updateChart(JSON.parse(event.data).onlineCount)
}
wsA.onerror = (error) => {
console.error('用户 A 连接错误:', error)
// 定义你的消息类型
interface ChatMessage {
onlineCount: number
}
const ws = useWebSocket(`ws://localhost:8080/api/ws?token=${userStore.token}&room=room1`, {
heartbeat: {
message: 'ping',
interval: 10000,
pongTimeout: 1000
},
autoReconnect: true,
// // 用户 B,加入 room1
// wsB.onmessage = (event) => {
// console.log('用户 B 收到消息:', event.data)
// }
// wsC.onmessage = (event) => {
// console.log('用户 C 收到消息:', event.data)
// wsC.send('ping')
// }
onMessage(ws, e) {
if (e.data === 'pong') {
console.log('Received pong message')
return
}
try {
const data = JSON.parse(e.data) as ChatMessage
updateChart(data.onlineCount)
} catch (error) {
console.error('JSON parse error:', error)
return
}
},
onError: (ws, event) => {
console.error('WebSocket error:', event)
},
onDisconnected: (ws, event) => {
console.log('WebSocket closed:', event)
}
})
// setInterval(() => {
// ws.send('ping')
// }, 1000)
onActivated(() => {
// updateChart()
console.log('onActivated')
})
onDeactivated(() => {
clearInterval(timer)
// ws.close()
})
onMounted(() => {
console.log('onMounted')
// ws.connect()
getData()
// updateChart()
})
onUnmounted(() => {
console.log('onUnmounted')
wsA.close()
})
</script>
+9 -2
View File
@@ -51,7 +51,7 @@ func (c *Client) Read() {
})
for {
_, _, err := c.conn.ReadMessage()
messageType, data, err := c.conn.ReadMessage()
if err != nil {
// 处理浏览器主动关闭的情况
if websocket.IsCloseError(err,
@@ -63,6 +63,13 @@ func (c *Client) Read() {
}
break
}
msg := string(data)
if msg == "ping" {
// 回复客户端的 Ping 消息
c.conn.WriteMessage(websocket.TextMessage, []byte("pong"))
continue
}
log.Printf("WebSocket message:%d, %s", messageType, msg)
// 可在此处理客户端发来的消息(如聊天内容)
}
}
@@ -83,7 +90,7 @@ func (c *Client) Write() {
c.conn.WriteMessage(websocket.CloseMessage, []byte{})
return
}
// ✅ 关键:每次只写一条消息,不合并
// 消息,不合并
err := c.conn.WriteMessage(websocket.TextMessage, message)
if err != nil {
return
+5
View File
@@ -64,6 +64,11 @@ class Web implements IErrorEvent {
}
private callback(err: LogWithError): void {}
private listenError = (err: any) => {
// 过滤ResizeObserver相关错误
if (err&&err.message && err.message.includes("ResizeObserver")) {
return;
}
console.error([err]);
let target = err.target;
if (target?.localName) {