小程序配置页:微信密钥与排行榜/商家端背景图后台管理
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -218,6 +218,16 @@ const routes = [
|
|||||||
component: () => import('@/views/miniapp/PopupNotice.vue'),
|
component: () => import('@/views/miniapp/PopupNotice.vue'),
|
||||||
meta: { title: '弹窗公告管理' }
|
meta: { title: '弹窗公告管理' }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'miniapp/script-config',
|
||||||
|
component: () => import('@/views/miniapp/ScriptConfig.vue'),
|
||||||
|
meta: { title: '自动弹窗及话术配置' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'miniapp/sys-config',
|
||||||
|
component: () => import('@/views/miniapp/MiniappConfig.vue'),
|
||||||
|
meta: { title: '微信与页面资源配置' }
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
// ========== 🔥 新增:客服会话管理 ==========
|
// ========== 🔥 新增:客服会话管理 ==========
|
||||||
|
|||||||
@@ -135,6 +135,8 @@
|
|||||||
<span>小程序配置</span>
|
<span>小程序配置</span>
|
||||||
</template>
|
</template>
|
||||||
<el-menu-item index="/miniapp/popup-notice">弹窗公告管理</el-menu-item>
|
<el-menu-item index="/miniapp/popup-notice">弹窗公告管理</el-menu-item>
|
||||||
|
<el-menu-item index="/miniapp/script-config">自动弹窗及话术配置</el-menu-item>
|
||||||
|
<el-menu-item index="/miniapp/sys-config">微信与页面资源配置</el-menu-item>
|
||||||
</el-sub-menu>
|
</el-sub-menu>
|
||||||
|
|
||||||
|
|
||||||
@@ -187,18 +189,21 @@
|
|||||||
</router-view>
|
</router-view>
|
||||||
</el-main>
|
</el-main>
|
||||||
</el-container>
|
</el-container>
|
||||||
|
<KefuConnect v-if="hasAnyChatPerm" />
|
||||||
</el-container>
|
</el-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, ref, onMounted, onUnmounted, getCurrentInstance, provide } from 'vue'
|
import { computed, ref, onMounted, onUnmounted, getCurrentInstance, provide } from 'vue'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage, ElNotification } from 'element-plus'
|
||||||
import {
|
import {
|
||||||
List, User, Warning, Money, Fold, Expand, Connection, Setting,
|
List, User, Warning, Money, Fold, Expand, Connection, Setting,
|
||||||
Goods, UserFilled, Comment,DataAnalysis, Medal // 新增
|
Goods, UserFilled, Comment,DataAnalysis, Medal // 新增
|
||||||
} from '@element-plus/icons-vue'
|
} from '@element-plus/icons-vue'
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
|
import KefuConnect from '@/components/KefuConnect.vue'
|
||||||
|
import { disconnectKefuChat } from '@/utils/kefuChat'
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
@@ -247,6 +252,7 @@ const fetchStats = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleLogout = () => {
|
const handleLogout = () => {
|
||||||
|
disconnectKefuChat()
|
||||||
localStorage.clear()
|
localStorage.clear()
|
||||||
router.push('/login')
|
router.push('/login')
|
||||||
ElMessage.success('已退出登录')
|
ElMessage.success('已退出登录')
|
||||||
@@ -277,63 +283,63 @@ const fetchKefuPermission = async () => {
|
|||||||
const { permissions, goeasy_appkey } = res.data
|
const { permissions, goeasy_appkey } = res.data
|
||||||
kefuPermissions.value = permissions || []
|
kefuPermissions.value = permissions || []
|
||||||
goeasyAppkey.value = goeasy_appkey || ''
|
goeasyAppkey.value = goeasy_appkey || ''
|
||||||
|
|
||||||
// 如果有权限且有appkey,初始化GoEasy(仅一次)
|
|
||||||
if (hasAnyChatPerm.value && goeasyAppkey.value) {
|
|
||||||
initGoEasy()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取客服权限失败:', error)
|
console.error('获取客服权限失败:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化GoEasy实例并连接
|
// 监听子组件传来的未读消息更新(由 KefuConnect + kefuChat 统一推送)
|
||||||
const initGoEasy = () => {
|
|
||||||
// 防止重复初始化
|
|
||||||
if (window.goeasy) return
|
|
||||||
|
|
||||||
// 1. 初始化实例
|
|
||||||
window.goeasy = GoEasy.getInstance({
|
|
||||||
host: 'hangzhou.goeasy.io', // 根据实际区域调整
|
|
||||||
appkey: goeasyAppkey.value,
|
|
||||||
modules: ['im']
|
|
||||||
})
|
|
||||||
|
|
||||||
// 2. 构建客服自己的userId = KF + 账号
|
|
||||||
const agentId = 'KF' + userPhone.value
|
|
||||||
const agentData = {
|
|
||||||
name: userPhone.value, // 客服名称
|
|
||||||
avatar: '' // 可后续加上头像
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 建立连接
|
|
||||||
window.goeasy.connect({
|
|
||||||
id: agentId,
|
|
||||||
data: agentData,
|
|
||||||
onSuccess: () => {
|
|
||||||
console.log('客服GoEasy连接成功')
|
|
||||||
// 连接成功后,通知Agent页面(通过provide)
|
|
||||||
proxy.$emitter.emit('goeasy-connected')
|
|
||||||
},
|
|
||||||
onFailed: (error) => {
|
|
||||||
console.error('GoEasy连接失败', error)
|
|
||||||
ElMessage.error('消息服务连接失败,请刷新重试')
|
|
||||||
},
|
|
||||||
onProgress: (attempts) => {
|
|
||||||
console.log('GoEasy正在重连,第' + attempts + '次')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 4. 保存客服标识到全局
|
|
||||||
window.__kefuAgentId = agentId
|
|
||||||
}
|
|
||||||
|
|
||||||
// 监听子组件传来的未读消息更新
|
|
||||||
const onAgentUnread = (count) => {
|
const onAgentUnread = (count) => {
|
||||||
agentUnread.value = count
|
agentUnread.value = count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let lastUnreadForNotify = 0
|
||||||
|
let unreadBaselineReady = false
|
||||||
|
|
||||||
|
const showMessageNotification = (title, message) => {
|
||||||
|
ElNotification({
|
||||||
|
title,
|
||||||
|
message,
|
||||||
|
type: 'info',
|
||||||
|
duration: 0,
|
||||||
|
showClose: true,
|
||||||
|
position: 'top-right',
|
||||||
|
customClass: 'kefu-msg-notify',
|
||||||
|
onClick: () => {
|
||||||
|
ElNotification.closeAll()
|
||||||
|
router.push('/chat/agent')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const onMessageNotify = (payload) => {
|
||||||
|
if (route.path === '/chat/agent') return
|
||||||
|
const customerId = payload?.customerId || '用户'
|
||||||
|
const preview = payload?.preview || '收到新消息'
|
||||||
|
showMessageNotification('新会话消息', `${customerId}: ${preview}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onUnreadBumpNotify = (count) => {
|
||||||
|
if (!unreadBaselineReady) {
|
||||||
|
lastUnreadForNotify = count
|
||||||
|
unreadBaselineReady = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (route.path === '/chat/agent') {
|
||||||
|
lastUnreadForNotify = count
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (count <= 0) {
|
||||||
|
lastUnreadForNotify = 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (count > lastUnreadForNotify) {
|
||||||
|
showMessageNotification('会话未读提醒', `您有 ${count} 条未读消息,点击查看`)
|
||||||
|
}
|
||||||
|
lastUnreadForNotify = count
|
||||||
|
}
|
||||||
|
|
||||||
// 向子组件提供客服相关数据
|
// 向子组件提供客服相关数据
|
||||||
provide('kefuPermissions', kefuPermissions)
|
provide('kefuPermissions', kefuPermissions)
|
||||||
provide('permPrefixMap', permPrefixMap)
|
provide('permPrefixMap', permPrefixMap)
|
||||||
@@ -342,15 +348,19 @@ provide('hasAnyChatPerm', hasAnyChatPerm)
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchStats()
|
fetchStats()
|
||||||
fetchKefuPermission() // 登录后先获取权限
|
fetchKefuPermission()
|
||||||
proxy.$emitter?.on('refresh-stats', fetchStats)
|
proxy.$emitter?.on('refresh-stats', fetchStats)
|
||||||
proxy.$emitter?.on('agent-unread', onAgentUnread)
|
proxy.$emitter?.on('agent-unread', onAgentUnread)
|
||||||
|
proxy.$emitter?.on('agent-unread', onUnreadBumpNotify)
|
||||||
|
proxy.$emitter?.on('kefu-message-notify', onMessageNotify)
|
||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
if (abortController) abortController.abort()
|
if (abortController) abortController.abort()
|
||||||
proxy.$emitter?.off('refresh-stats', fetchStats)
|
proxy.$emitter?.off('refresh-stats', fetchStats)
|
||||||
proxy.$emitter?.off('agent-unread', onAgentUnread)
|
proxy.$emitter?.off('agent-unread', onAgentUnread)
|
||||||
|
proxy.$emitter?.off('agent-unread', onUnreadBumpNotify)
|
||||||
|
proxy.$emitter?.off('kefu-message-notify', onMessageNotify)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
311
src/views/miniapp/MiniappConfig.vue
Normal file
311
src/views/miniapp/MiniappConfig.vue
Normal file
@@ -0,0 +1,311 @@
|
|||||||
|
<template>
|
||||||
|
<div class="miniapp-config">
|
||||||
|
<div v-if="!hasPermission" class="no-permission">
|
||||||
|
<div class="no-permission-icon">🔒</div>
|
||||||
|
<div class="no-permission-text">您无权访问此页面</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-else>
|
||||||
|
<div class="header-bar">
|
||||||
|
<h2>文赫电竞 · 小程序配置</h2>
|
||||||
|
<el-text type="info">AppID/服务号/支付密钥、排行榜与商家端背景图均可在此配置</el-text>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-tabs v-model="activeTab" class="config-tabs">
|
||||||
|
<el-tab-pane label="微信与支付配置" name="sys">
|
||||||
|
<el-form :model="sysForm" label-width="160px" class="sys-form" v-loading="sysLoading">
|
||||||
|
<el-form-item label="小程序 AppID">
|
||||||
|
<el-input v-model="sysForm.weixin_appid" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="小程序 Secret">
|
||||||
|
<el-input v-model="sysForm.weixin_secret" type="password" show-password placeholder="留空则不修改" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="服务号 AppID">
|
||||||
|
<el-input v-model="sysForm.weixin_official_appid" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="服务号 Secret">
|
||||||
|
<el-input v-model="sysForm.weixin_official_secret" type="password" show-password placeholder="留空则不修改" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="服务号 Token">
|
||||||
|
<el-input v-model="sysForm.weixin_official_token" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="模板消息 ID">
|
||||||
|
<el-input v-model="sysForm.weixin_template_id" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="服务号广播">
|
||||||
|
<el-switch v-model="sysForm.weixin_broadcast_enabled" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="微信支付商户号">
|
||||||
|
<el-input v-model="sysForm.weixin_mchid" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="商户密钥">
|
||||||
|
<el-input v-model="sysForm.weixin_shanghu_miyao" type="password" show-password placeholder="留空则不修改" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="支付回调 URL">
|
||||||
|
<el-input v-model="sysForm.weixin_notify_url" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="业务回调根 URL">
|
||||||
|
<el-input v-model="sysForm.notify_base_url" placeholder="https://wenhe.nmslb.com/hqhd" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" :loading="sysSaving" @click="saveSysConfig">保存微信配置</el-button>
|
||||||
|
<el-button @click="loadSysConfig">刷新</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="页面背景与图标" name="assets">
|
||||||
|
<div class="asset-toolbar">
|
||||||
|
<el-select v-model="assetGroup" placeholder="资源组" style="width: 200px" @change="loadAssets">
|
||||||
|
<el-option label="排行榜" value="paihangbang" />
|
||||||
|
<el-option label="商家端" value="shangjiaduan" />
|
||||||
|
</el-select>
|
||||||
|
<el-button type="primary" :loading="assetSaving" @click="saveAssets">保存路径</el-button>
|
||||||
|
<el-button @click="loadAssets">刷新</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table :data="assetList" v-loading="assetLoading" border class="asset-table">
|
||||||
|
<el-table-column prop="ziyuan_key" label="键名" width="160" />
|
||||||
|
<el-table-column prop="miaoshu" label="说明" min-width="120" />
|
||||||
|
<el-table-column label="预览" width="100">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-image v-if="row.ziyuan_path" :src="fullUrl(row.ziyuan_path)" fit="cover" class="thumb" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="OSS 相对路径" min-width="280">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-input v-model="row.ziyuan_path" size="small" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="上传" width="120" fixed="right">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-upload
|
||||||
|
:show-file-list="false"
|
||||||
|
accept="image/*"
|
||||||
|
:http-request="(opt) => uploadAsset(opt, row)"
|
||||||
|
>
|
||||||
|
<el-button type="primary" link>上传替换</el-button>
|
||||||
|
</el-upload>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
const zhanghao = ref(localStorage.getItem('username') || '')
|
||||||
|
const hasPermission = ref(true)
|
||||||
|
const activeTab = ref('sys')
|
||||||
|
const ossBaseUrl = ref(window.$ossURL || '')
|
||||||
|
|
||||||
|
const sysLoading = ref(false)
|
||||||
|
const sysSaving = ref(false)
|
||||||
|
const sysForm = reactive({
|
||||||
|
weixin_appid: '',
|
||||||
|
weixin_secret: '',
|
||||||
|
weixin_official_appid: '',
|
||||||
|
weixin_official_secret: '',
|
||||||
|
weixin_official_token: '',
|
||||||
|
weixin_template_id: '',
|
||||||
|
weixin_broadcast_enabled: true,
|
||||||
|
weixin_mchid: '',
|
||||||
|
weixin_shanghu_miyao: '',
|
||||||
|
weixin_notify_url: '',
|
||||||
|
notify_base_url: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
const assetGroup = ref('paihangbang')
|
||||||
|
const assetList = ref([])
|
||||||
|
const assetLoading = ref(false)
|
||||||
|
const assetSaving = ref(false)
|
||||||
|
|
||||||
|
const fullUrl = (path) => {
|
||||||
|
if (!path) return ''
|
||||||
|
if (path.startsWith('http')) return path
|
||||||
|
const base = ossBaseUrl.value.replace(/\/$/, '')
|
||||||
|
return `${base}/${String(path).replace(/^\//, '')}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadSysConfig = async () => {
|
||||||
|
sysLoading.value = true
|
||||||
|
try {
|
||||||
|
const res = await request.post('/peizhi/xcxsyshq', { zhanghao: zhanghao.value })
|
||||||
|
if (res.code === 403 || res.code === 1 && res.msg?.includes('权限')) {
|
||||||
|
hasPermission.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (res.code === 0 && res.data) {
|
||||||
|
Object.assign(sysForm, {
|
||||||
|
weixin_appid: res.data.weixin_appid || '',
|
||||||
|
weixin_secret: '',
|
||||||
|
weixin_official_appid: res.data.weixin_official_appid || '',
|
||||||
|
weixin_official_secret: '',
|
||||||
|
weixin_official_token: res.data.weixin_official_token || '',
|
||||||
|
weixin_template_id: res.data.weixin_template_id || '',
|
||||||
|
weixin_broadcast_enabled: res.data.weixin_broadcast_enabled ?? true,
|
||||||
|
weixin_mchid: res.data.weixin_mchid || '',
|
||||||
|
weixin_shanghu_miyao: '',
|
||||||
|
weixin_notify_url: res.data.weixin_notify_url || '',
|
||||||
|
notify_base_url: res.data.notify_base_url || '',
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.msg || '加载失败')
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
ElMessage.error('网络错误')
|
||||||
|
} finally {
|
||||||
|
sysLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const saveSysConfig = async () => {
|
||||||
|
sysSaving.value = true
|
||||||
|
try {
|
||||||
|
const payload = { ...sysForm }
|
||||||
|
if (!payload.weixin_secret) delete payload.weixin_secret
|
||||||
|
if (!payload.weixin_official_secret) delete payload.weixin_official_secret
|
||||||
|
if (!payload.weixin_shanghu_miyao) delete payload.weixin_shanghu_miyao
|
||||||
|
const res = await request.post('/peizhi/xcxsysgx', {
|
||||||
|
zhanghao: zhanghao.value,
|
||||||
|
config: payload,
|
||||||
|
})
|
||||||
|
if (res.code === 0) {
|
||||||
|
ElMessage.success('微信配置已保存')
|
||||||
|
loadSysConfig()
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.msg || '保存失败')
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
ElMessage.error('网络错误')
|
||||||
|
} finally {
|
||||||
|
sysSaving.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadAssets = async () => {
|
||||||
|
assetLoading.value = true
|
||||||
|
try {
|
||||||
|
const res = await request.post('/peizhi/xcxyzycx', {
|
||||||
|
zhanghao: zhanghao.value,
|
||||||
|
ziyuan_zu: assetGroup.value,
|
||||||
|
})
|
||||||
|
if (res.code === 403) {
|
||||||
|
hasPermission.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (res.code === 0) {
|
||||||
|
const group = res.data?.groups?.[assetGroup.value] || {}
|
||||||
|
assetList.value = Object.keys(group).map((key) => ({
|
||||||
|
ziyuan_zu: assetGroup.value,
|
||||||
|
ziyuan_key: key,
|
||||||
|
ziyuan_path: group[key],
|
||||||
|
miaoshu: key,
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.msg || '加载资源失败')
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
ElMessage.error('网络错误')
|
||||||
|
} finally {
|
||||||
|
assetLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const saveAssets = async () => {
|
||||||
|
assetSaving.value = true
|
||||||
|
try {
|
||||||
|
const items = assetList.value.map((row) => ({
|
||||||
|
ziyuan_zu: row.ziyuan_zu,
|
||||||
|
ziyuan_key: row.ziyuan_key,
|
||||||
|
ziyuan_path: row.ziyuan_path,
|
||||||
|
}))
|
||||||
|
const res = await request.post('/peizhi/xcxyzgx', {
|
||||||
|
zhanghao: zhanghao.value,
|
||||||
|
items,
|
||||||
|
})
|
||||||
|
if (res.code === 0) {
|
||||||
|
ElMessage.success('资源路径已保存')
|
||||||
|
loadAssets()
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.msg || '保存失败')
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
ElMessage.error('网络错误')
|
||||||
|
} finally {
|
||||||
|
assetSaving.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const uploadAsset = async ({ file }, row) => {
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('zhanghao', zhanghao.value)
|
||||||
|
formData.append('ziyuan_zu', row.ziyuan_zu)
|
||||||
|
formData.append('ziyuan_key', row.ziyuan_key)
|
||||||
|
formData.append('image', file)
|
||||||
|
try {
|
||||||
|
const res = await request.post('/peizhi/xcxyzsc', formData, {
|
||||||
|
headers: { 'Content-Type': 'multipart/form-data' },
|
||||||
|
})
|
||||||
|
if (res.code === 0) {
|
||||||
|
ElMessage.success('上传成功')
|
||||||
|
row.ziyuan_path = res.data?.ziyuan_path || row.ziyuan_path
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.msg || '上传失败')
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
ElMessage.error('上传失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
loadSysConfig()
|
||||||
|
loadAssets()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.miniapp-config {
|
||||||
|
padding: 8px 4px;
|
||||||
|
}
|
||||||
|
.header-bar {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
.header-bar h2 {
|
||||||
|
margin: 0 0 8px;
|
||||||
|
color: #00f2ff;
|
||||||
|
}
|
||||||
|
.no-permission {
|
||||||
|
text-align: center;
|
||||||
|
padding: 80px 20px;
|
||||||
|
color: rgba(255, 255, 255, 0.6);
|
||||||
|
}
|
||||||
|
.no-permission-icon {
|
||||||
|
font-size: 48px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
.sys-form {
|
||||||
|
max-width: 720px;
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
.asset-toolbar {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
.asset-table {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
.thumb {
|
||||||
|
width: 56px;
|
||||||
|
height: 56px;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user