385 lines
8.5 KiB
Vue
385 lines
8.5 KiB
Vue
|
|
<template>
|
|||
|
|
<view class="admin-container">
|
|||
|
|
<view class="header">
|
|||
|
|
<view class="back-btn" @click="goBack">← 返回</view>
|
|||
|
|
<text class="title">模型状态管理</text>
|
|||
|
|
<view class="placeholder"></view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<scroll-view scroll-y class="content">
|
|||
|
|
<view class="intro-card">
|
|||
|
|
<text class="intro-text">💡 在此管理各个模型的可用状态。当第三方接口更新时,可以临时禁用模型并显示维护信息。</text>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- Veo 模型配置 -->
|
|||
|
|
<view class="model-card">
|
|||
|
|
<view class="model-header">
|
|||
|
|
<text class="model-name">Veo 模型</text>
|
|||
|
|
<switch :checked="!veoDisabled" @change="onVeoStatusChange" color="#8B7355" />
|
|||
|
|
</view>
|
|||
|
|
<view class="model-status">
|
|||
|
|
<text class="status-label">状态:</text>
|
|||
|
|
<text :class="['status-value', veoDisabled ? 'disabled' : 'enabled']">
|
|||
|
|
{{ veoDisabled ? '已禁用' : '正常' }}
|
|||
|
|
</text>
|
|||
|
|
</view>
|
|||
|
|
<view class="form-group">
|
|||
|
|
<text class="form-label">维护提示信息</text>
|
|||
|
|
<textarea
|
|||
|
|
class="form-textarea"
|
|||
|
|
v-model="veoMessage"
|
|||
|
|
placeholder="请输入维护提示信息,例如:官方接口参数更新,正在处理中,暂不可用"
|
|||
|
|
maxlength="200"
|
|||
|
|
/>
|
|||
|
|
<view class="char-count">{{ veoMessage.length }} / 200</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 火山引擎模型配置 -->
|
|||
|
|
<view class="model-card">
|
|||
|
|
<view class="model-header">
|
|||
|
|
<text class="model-name">火山引擎模型</text>
|
|||
|
|
<switch :checked="!volcengineDisabled" @change="onVolcengineStatusChange" color="#8B7355" />
|
|||
|
|
</view>
|
|||
|
|
<view class="model-status">
|
|||
|
|
<text class="status-label">状态:</text>
|
|||
|
|
<text :class="['status-value', volcengineDisabled ? 'disabled' : 'enabled']">
|
|||
|
|
{{ volcengineDisabled ? '已禁用' : '正常' }}
|
|||
|
|
</text>
|
|||
|
|
</view>
|
|||
|
|
<view class="form-group">
|
|||
|
|
<text class="form-label">维护提示信息</text>
|
|||
|
|
<textarea
|
|||
|
|
class="form-textarea"
|
|||
|
|
v-model="volcengineMessage"
|
|||
|
|
placeholder="请输入维护提示信息,例如:官方接口参数更新,正在处理中,暂不可用"
|
|||
|
|
maxlength="200"
|
|||
|
|
/>
|
|||
|
|
<view class="char-count">{{ volcengineMessage.length }} / 200</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 保存按钮 -->
|
|||
|
|
<button class="save-btn" @click="saveConfig" :disabled="saving">
|
|||
|
|
<text v-if="saving">保存中...</text>
|
|||
|
|
<text v-else>💾 保存配置</text>
|
|||
|
|
</button>
|
|||
|
|
</scroll-view>
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
import { API_BASE } from '@/config/api.js';
|
|||
|
|
|
|||
|
|
export default {
|
|||
|
|
data() {
|
|||
|
|
return {
|
|||
|
|
API_BASE,
|
|||
|
|
veoDisabled: false,
|
|||
|
|
veoMessage: '',
|
|||
|
|
volcengineDisabled: false,
|
|||
|
|
volcengineMessage: '',
|
|||
|
|
saving: false
|
|||
|
|
};
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onLoad() {
|
|||
|
|
this.loadConfig();
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
methods: {
|
|||
|
|
goBack() {
|
|||
|
|
uni.navigateBack();
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 加载配置
|
|||
|
|
loadConfig() {
|
|||
|
|
console.log('[Admin] 加载模型状态配置...');
|
|||
|
|
uni.showLoading({ title: '加载中...' });
|
|||
|
|
|
|||
|
|
uni.request({
|
|||
|
|
url: `${this.API_BASE}/api/admin/system/model-status-config`,
|
|||
|
|
method: 'GET',
|
|||
|
|
success: (res) => {
|
|||
|
|
console.log('[Admin] 配置响应:', res);
|
|||
|
|
if (res.statusCode === 200 && res.data && res.data.success) {
|
|||
|
|
const config = res.data.data;
|
|||
|
|
|
|||
|
|
// 设置Veo状态
|
|||
|
|
this.veoDisabled = config.veo_disabled === 'true';
|
|||
|
|
this.veoMessage = config.veo_message || '';
|
|||
|
|
|
|||
|
|
// 设置火山引擎状态
|
|||
|
|
this.volcengineDisabled = config.volcengine_disabled === 'true';
|
|||
|
|
this.volcengineMessage = config.volcengine_message || '';
|
|||
|
|
|
|||
|
|
console.log('[Admin] 配置加载成功');
|
|||
|
|
} else {
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '加载配置失败',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
fail: (error) => {
|
|||
|
|
console.error('[Admin] 加载配置失败:', error);
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '网络错误',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
complete: () => {
|
|||
|
|
uni.hideLoading();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// Veo状态切换
|
|||
|
|
onVeoStatusChange(e) {
|
|||
|
|
this.veoDisabled = !e.detail.value;
|
|||
|
|
console.log('[Admin] Veo状态:', this.veoDisabled ? '禁用' : '启用');
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 火山引擎状态切换
|
|||
|
|
onVolcengineStatusChange(e) {
|
|||
|
|
this.volcengineDisabled = !e.detail.value;
|
|||
|
|
console.log('[Admin] 火山引擎状态:', this.volcengineDisabled ? '禁用' : '启用');
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 保存配置
|
|||
|
|
saveConfig() {
|
|||
|
|
console.log('[Admin] 保存配置...');
|
|||
|
|
|
|||
|
|
// 验证:如果禁用了模型,必须填写维护信息
|
|||
|
|
if (this.veoDisabled && !this.veoMessage.trim()) {
|
|||
|
|
uni.showToast({
|
|||
|
|
title: 'Veo模型已禁用,请填写维护提示信息',
|
|||
|
|
icon: 'none',
|
|||
|
|
duration: 2000
|
|||
|
|
});
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (this.volcengineDisabled && !this.volcengineMessage.trim()) {
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '火山引擎模型已禁用,请填写维护提示信息',
|
|||
|
|
icon: 'none',
|
|||
|
|
duration: 2000
|
|||
|
|
});
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.saving = true;
|
|||
|
|
uni.showLoading({ title: '保存中...' });
|
|||
|
|
|
|||
|
|
const config = {
|
|||
|
|
veo_disabled: this.veoDisabled ? 'true' : 'false',
|
|||
|
|
veo_message: this.veoMessage,
|
|||
|
|
volcengine_disabled: this.volcengineDisabled ? 'true' : 'false',
|
|||
|
|
volcengine_message: this.volcengineMessage
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
uni.request({
|
|||
|
|
url: `${this.API_BASE}/api/admin/system/model-status-config`,
|
|||
|
|
method: 'POST',
|
|||
|
|
header: {
|
|||
|
|
'Content-Type': 'application/json'
|
|||
|
|
},
|
|||
|
|
data: config,
|
|||
|
|
success: (res) => {
|
|||
|
|
console.log('[Admin] 保存响应:', res);
|
|||
|
|
if (res.statusCode === 200 && res.data && res.data.success) {
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '保存成功',
|
|||
|
|
icon: 'success'
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 延迟返回
|
|||
|
|
setTimeout(() => {
|
|||
|
|
uni.navigateBack();
|
|||
|
|
}, 1500);
|
|||
|
|
} else {
|
|||
|
|
uni.showToast({
|
|||
|
|
title: res.data?.message || '保存失败',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
fail: (error) => {
|
|||
|
|
console.error('[Admin] 保存失败:', error);
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '网络错误',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
complete: () => {
|
|||
|
|
this.saving = false;
|
|||
|
|
uni.hideLoading();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style lang="scss" scoped>
|
|||
|
|
.admin-container {
|
|||
|
|
width: 100%;
|
|||
|
|
min-height: 100vh;
|
|||
|
|
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.header {
|
|||
|
|
background: white;
|
|||
|
|
padding: 60rpx 40rpx 20rpx;
|
|||
|
|
padding-top: calc(60rpx + constant(safe-area-inset-top));
|
|||
|
|
padding-top: calc(60rpx + env(safe-area-inset-top));
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
align-items: center;
|
|||
|
|
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.back-btn {
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
color: #666;
|
|||
|
|
padding: 16rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.title {
|
|||
|
|
font-size: 36rpx;
|
|||
|
|
font-weight: bold;
|
|||
|
|
color: #333;
|
|||
|
|
flex: 1;
|
|||
|
|
text-align: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.placeholder {
|
|||
|
|
width: 80rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.content {
|
|||
|
|
flex: 1;
|
|||
|
|
padding: 40rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.intro-card {
|
|||
|
|
background: rgba(139, 115, 85, 0.1);
|
|||
|
|
border-radius: 16rpx;
|
|||
|
|
padding: 32rpx;
|
|||
|
|
margin-bottom: 40rpx;
|
|||
|
|
border: 2rpx solid rgba(139, 115, 85, 0.2);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.intro-text {
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
color: #666;
|
|||
|
|
line-height: 1.6;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.model-card {
|
|||
|
|
background: white;
|
|||
|
|
border-radius: 16rpx;
|
|||
|
|
padding: 32rpx;
|
|||
|
|
margin-bottom: 32rpx;
|
|||
|
|
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.model-header {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
align-items: center;
|
|||
|
|
margin-bottom: 24rpx;
|
|||
|
|
padding-bottom: 24rpx;
|
|||
|
|
border-bottom: 2rpx solid #f0f0f0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.model-name {
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
font-weight: bold;
|
|||
|
|
color: #333;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.model-status {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
margin-bottom: 24rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.status-label {
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
color: #666;
|
|||
|
|
margin-right: 16rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.status-value {
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
font-weight: bold;
|
|||
|
|
padding: 8rpx 24rpx;
|
|||
|
|
border-radius: 24rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.status-value.enabled {
|
|||
|
|
color: #52c41a;
|
|||
|
|
background: rgba(82, 196, 26, 0.1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.status-value.disabled {
|
|||
|
|
color: #ff4d4f;
|
|||
|
|
background: rgba(255, 77, 79, 0.1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.form-group {
|
|||
|
|
margin-top: 24rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.form-label {
|
|||
|
|
display: block;
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
color: #666;
|
|||
|
|
margin-bottom: 16rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.form-textarea {
|
|||
|
|
width: 100%;
|
|||
|
|
min-height: 200rpx;
|
|||
|
|
padding: 24rpx;
|
|||
|
|
border: 2rpx solid #e0e0e0;
|
|||
|
|
border-radius: 12rpx;
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
background: #f8f9fa;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.char-count {
|
|||
|
|
text-align: right;
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
color: #999;
|
|||
|
|
margin-top: 8rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.save-btn {
|
|||
|
|
width: 100%;
|
|||
|
|
padding: 32rpx;
|
|||
|
|
background: linear-gradient(135deg, #8B7355 0%, #6D8B8B 100%);
|
|||
|
|
color: white;
|
|||
|
|
border: none;
|
|||
|
|
border-radius: 16rpx;
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
font-weight: bold;
|
|||
|
|
box-shadow: 0 8rpx 24rpx rgba(139, 115, 85, 0.3);
|
|||
|
|
margin-top: 40rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.save-btn:disabled {
|
|||
|
|
opacity: 0.6;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.save-btn:active:not(:disabled) {
|
|||
|
|
transform: translateY(2rpx);
|
|||
|
|
box-shadow: 0 4rpx 12rpx rgba(139, 115, 85, 0.3);
|
|||
|
|
}
|
|||
|
|
</style>
|