482 lines
13 KiB
Plaintext
482 lines
13 KiB
Plaintext
<template>
|
||
<view class="admin-page">
|
||
<view class="page-header">
|
||
<view class="breadcrumb">
|
||
<text class="bc-item">设置</text>
|
||
<text class="bc-sep">/</text>
|
||
<text class="bc-item">接口配置</text>
|
||
<text class="bc-sep">/</text>
|
||
<text class="bc-item active">系统存储配置</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="content-card">
|
||
<view class="tabs-header">
|
||
<scroll-view class="tabs-scroll" scroll-x="true" show-scrollbar="false">
|
||
<view class="tabs-list">
|
||
<view
|
||
v-for="(item, index) in tabs"
|
||
:key="index"
|
||
class="tab-item"
|
||
:class="{ active: activeTab === index }"
|
||
@click="activeTab = index"
|
||
>
|
||
<text class="tab-text">{{ item }}</text>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
|
||
<view class="tab-body">
|
||
<!-- Tab 0: 储存配置 -->
|
||
<view v-if="activeTab === 0" class="config-view">
|
||
<view class="notice-box">
|
||
<view class="notice-content">
|
||
<text class="notice-line">上传图片时会生成缩略图</text>
|
||
<text class="notice-line">未设置按照系统默认生成,系统默认:大图800*800,中图300*300,小图150*150</text>
|
||
<text class="notice-line">水印只在上传图片时生成,原图,大中小缩略图都会按照比例存在。</text>
|
||
<text class="notice-line">若上传图片时未开启水印,则该图在开启水印之后依旧无水印效果。</text>
|
||
</view>
|
||
<text class="notice-close">×</text>
|
||
</view>
|
||
|
||
<view class="form-body">
|
||
<view class="form-row">
|
||
<text class="form-label">存储方式:</text>
|
||
<view class="form-control">
|
||
<radio-group class="storage-radio-group" @change="onStorageTypeChange">
|
||
<label class="radio-label" v-for="st in storageOptions" :key="st.value">
|
||
<radio :value="st.value" :checked="form.storageType === st.value" color="#2d8cf0" style="transform:scale(0.8)" />
|
||
<text class="radio-text">{{ st.label }}</text>
|
||
</label>
|
||
</radio-group>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-row mt-30">
|
||
<text class="form-label">是否开启缩略图:</text>
|
||
<view class="form-control">
|
||
<switch :checked="form.enableThumb" @change="onToggleThumb" color="#2d8cf0" style="transform:scale(0.8)" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-row mt-30">
|
||
<text class="form-label">是否开启水印:</text>
|
||
<view class="form-control">
|
||
<switch :checked="form.enableWatermark" @change="onToggleWatermark" color="#2d8cf0" style="transform:scale(0.8)" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-footer mt-40">
|
||
<button class="save-btn" type="primary" @click="handleSave">保存</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- Tab 1-6: Cloud Storage -->
|
||
<view v-else class="cloud-view">
|
||
<view class="cloud-notice">
|
||
<view class="notice-title">
|
||
<text class="blue-title">{{ tabs[activeTab] }}开通方法:</text>
|
||
<text class="link-text">点击查看</text>
|
||
</view>
|
||
<text class="notice-step">第一步:添加【存储空间】(空间名称不能重复)</text>
|
||
<text class="notice-step">第二步:开启【使用状态】</text>
|
||
<text class="notice-step">第三步(可选):选择云存储空间列表上的修改【空间域名操作】</text>
|
||
<text class="notice-step">第四步(可选):选择云存储空间列表上的修改【CNAME配置】,打开后复制记录值到对应的平台解析</text>
|
||
<text class="notice-close">×</text>
|
||
</view>
|
||
|
||
<view class="action-bar mt-20">
|
||
<view class="left-actions">
|
||
<button class="action-btn primary-btn">添加存储空间</button>
|
||
<button class="action-btn success-btn ml-10">同步存储空间</button>
|
||
</view>
|
||
<button class="action-btn outline-btn">修改配置信息</button>
|
||
</view>
|
||
|
||
<view class="table-container mt-20">
|
||
<view class="table-header">
|
||
<text class="th flex-2">储存空间名称</text>
|
||
<text class="th flex-1">区域</text>
|
||
<text class="th flex-3">空间域名</text>
|
||
<text class="th flex-1">使用状态</text>
|
||
<text class="th flex-2">创建时间</text>
|
||
<text class="th flex-2">更新时间</text>
|
||
<text class="th flex-2 center">操作</text>
|
||
</view>
|
||
<view class="table-body">
|
||
<view v-if="getCloudData().length > 0">
|
||
<view
|
||
class="table-row"
|
||
v-for="(row, rIndex) in getCloudData()"
|
||
:key="rIndex"
|
||
>
|
||
<text class="td flex-2">{{ row.name }}</text>
|
||
<text class="td flex-1">{{ row.region }}</text>
|
||
<text class="td flex-3 link">{{ row.domain }}</text>
|
||
<view class="td flex-1">
|
||
<switch :checked="row.status" scale="0.6" color="#2d8cf0" />
|
||
</view>
|
||
<text class="td flex-2 small-text muted">{{ row.createTime }}</text>
|
||
<text class="td flex-2 small-text muted">{{ row.updateTime }}</text>
|
||
<view class="td flex-2 center-row">
|
||
<text class="op-link">CNAME配置</text>
|
||
<text class="op-link ml-10">修改空间域名</text>
|
||
<text class="op-link danger ml-10">删除</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view v-else class="empty-state">
|
||
<text class="empty-text">暂无数据</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="uts">
|
||
import { ref, reactive } from 'vue'
|
||
|
||
const tabs = ['储存配置', '七牛云储存', '阿里云储存', '腾讯云储存', '京东云储存', '华为云储存', '天翼云储存']
|
||
const activeTab = ref(0)
|
||
|
||
const storageOptions = [
|
||
{ label: '本地存储', value: 'local' },
|
||
{ label: '七牛云存储', value: 'qiniu' },
|
||
{ label: '阿里云存储', value: 'aliyun' },
|
||
{ label: '腾讯云存储', value: 'tencent' },
|
||
{ label: '京东云存储', value: 'jd' },
|
||
{ label: '华为云存储', value: 'huawei' },
|
||
{ label: '天翼云存储', value: 'tianyi' }
|
||
]
|
||
|
||
const form = reactive({
|
||
storageType: 'local',
|
||
enableThumb: false,
|
||
enableWatermark: false
|
||
})
|
||
|
||
const onStorageTypeChange = (e : any) => {
|
||
form.storageType = e.detail.value as string
|
||
}
|
||
|
||
const onToggleThumb = (e : any) => {
|
||
form.enableThumb = e.detail.value as boolean
|
||
}
|
||
|
||
const onToggleWatermark = (e : any) => {
|
||
form.enableWatermark = e.detail.value as boolean
|
||
}
|
||
|
||
const handleSave = () => {
|
||
uni.showToast({
|
||
title: '保存成功',
|
||
icon: 'success'
|
||
})
|
||
}
|
||
|
||
// Simulated data for Aliyun Storage (based on screenshot)
|
||
const aliyunData = [
|
||
{ name: 'crmebdoc', region: '华北2 (北京)', domain: 'https://crmebdoc.oss-cn-beijing.aliyuncs.com', status: false, createTime: '2024-07-30 12:10:42', updateTime: '2025-01-22 10:58:20' },
|
||
{ name: 'crmebjavasingle', region: '华北2 (北京)', domain: 'https://crmebjavasingl...oss-cn-beijing.aliyunc...s.com', status: false, createTime: '2024-07-29 17:22:24', updateTime: '2025-01-22 10:58:20' },
|
||
{ name: 'crmebjavamer', region: '华北2 (北京)', domain: 'https://crmebjavamer.o...ss-cn-beijing.aliyuncs.c...om', status: false, createTime: '2024-07-22 14:43:42', updateTime: '2025-01-22 10:58:20' },
|
||
{ name: 'crmebmer', region: '华北2 (北京)', domain: 'https://crmebmer.oss-c...n-beijing.aliyuncs.com', status: false, createTime: '2024-07-22 14:42:53', updateTime: '2025-01-22 10:58:20' },
|
||
{ name: 'crmebmulti', region: '华北2 (北京)', domain: 'https://crmebmulti.oss-...cn-beijing.aliyuncs.com', status: false, createTime: '2024-07-22 14:42:08', updateTime: '2025-01-22 10:58:20' },
|
||
{ name: 'crmebpros', region: '华北2 (北京)', domain: 'https://crmebpros.oss-c...n-beijing.aliyuncs.com', status: false, createTime: '2024-07-22 14:41:17', updateTime: '2025-01-22 10:58:20' },
|
||
{ name: 'crmebbz', region: '华东1 (杭州)', domain: 'https://crmebbz.oss-cn-...hangzhou.aliyuncs.com', status: true, createTime: '2022-08-18 17:30:33', updateTime: '2025-01-22 10:58:20' }
|
||
]
|
||
|
||
const getCloudData = () : any[] => {
|
||
if (activeTab.value === 2) { // 阿里云
|
||
return aliyunData
|
||
}
|
||
return [] as any[]
|
||
}
|
||
|
||
</script>
|
||
|
||
<style scoped>
|
||
.admin-page {
|
||
min-height: 100vh;
|
||
background-color: #f5f7f9;
|
||
padding: 20px;
|
||
}
|
||
|
||
.breadcrumb {
|
||
display: flex;
|
||
flex-direction: row;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.bc-item {
|
||
font-size: 14px;
|
||
color: #999;
|
||
}
|
||
|
||
.bc-item.active {
|
||
color: #333;
|
||
}
|
||
|
||
.bc-sep {
|
||
margin: 0 8px;
|
||
color: #ccc;
|
||
}
|
||
|
||
.content-card {
|
||
background-color: #ffffff;
|
||
border-radius: 4px;
|
||
box-shadow: 0 1px 4px rgba(0,21,41,.08);
|
||
}
|
||
|
||
.tabs-header {
|
||
border-bottom: 1px solid #f0f0f0;
|
||
}
|
||
|
||
.tabs-scroll {
|
||
white-space: nowrap;
|
||
width: 100%;
|
||
}
|
||
|
||
.tabs-list {
|
||
display: flex;
|
||
flex-direction: row;
|
||
padding: 0 15px;
|
||
}
|
||
|
||
.tab-item {
|
||
padding: 15px 15px;
|
||
cursor: pointer;
|
||
position: relative;
|
||
}
|
||
|
||
.tab-text {
|
||
font-size: 14px;
|
||
color: #666;
|
||
}
|
||
|
||
.tab-item.active .tab-text {
|
||
color: #2d8cf0;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.tab-item.active::after {
|
||
content: "";
|
||
position: absolute;
|
||
bottom: 0;
|
||
left: 15px;
|
||
right: 15px;
|
||
height: 2px;
|
||
background-color: #2d8cf0;
|
||
}
|
||
|
||
.tab-body {
|
||
padding: 20px;
|
||
}
|
||
|
||
/* Notice Box Styles */
|
||
.notice-box {
|
||
background-color: #fffaf3;
|
||
border: 1px solid #ffebcc;
|
||
padding: 15px 20px;
|
||
border-radius: 4px;
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: space-between;
|
||
margin-bottom: 30px;
|
||
}
|
||
|
||
.notice-line {
|
||
font-size: 13px;
|
||
color: #666;
|
||
line-height: 1.8;
|
||
display: block;
|
||
}
|
||
|
||
.notice-close {
|
||
color: #ccc;
|
||
font-size: 18px;
|
||
cursor: pointer;
|
||
}
|
||
|
||
/* Form Styles */
|
||
.form-body {
|
||
max-width: 800px;
|
||
}
|
||
|
||
.form-row {
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
}
|
||
|
||
.form-label {
|
||
width: 140px;
|
||
font-size: 13px;
|
||
color: #333;
|
||
}
|
||
|
||
.storage-radio-group {
|
||
display: flex;
|
||
flex-direction: row;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.radio-label {
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
margin-right: 20px;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.radio-text {
|
||
font-size: 13px;
|
||
margin-left: 4px;
|
||
color: #666;
|
||
}
|
||
|
||
.save-btn {
|
||
width: 80px;
|
||
height: 32px;
|
||
line-height: 32px;
|
||
background-color: #2d8cf0;
|
||
color: white;
|
||
font-size: 13px;
|
||
padding: 0;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.mt-20 { margin-top: 20px; }
|
||
.mt-30 { margin-top: 30px; }
|
||
.mt-40 { margin-top: 40px; }
|
||
.ml-10 { margin-left: 10px; }
|
||
|
||
/* Cloud View Styles */
|
||
.cloud-notice {
|
||
background-color: #f0faff;
|
||
border: 1px solid #d5e8fc;
|
||
border-radius: 4px;
|
||
padding: 15px 20px;
|
||
position: relative;
|
||
}
|
||
|
||
.blue-title {
|
||
color: #2db7f5;
|
||
font-size: 14px;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.link-text {
|
||
color: #2d8cf0;
|
||
font-size: 14px;
|
||
margin-left: 10px;
|
||
cursor: pointer;
|
||
text-decoration: underline;
|
||
}
|
||
|
||
.notice-step {
|
||
display: block;
|
||
font-size: 13px;
|
||
color: #666;
|
||
line-height: 1.8;
|
||
}
|
||
|
||
.action-bar {
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.left-actions {
|
||
display: flex;
|
||
flex-direction: row;
|
||
}
|
||
|
||
.action-btn {
|
||
font-size: 12px;
|
||
height: 30px;
|
||
line-height: 30px;
|
||
padding: 0 12px;
|
||
border-radius: 3px;
|
||
}
|
||
|
||
.primary-btn { background-color: #2d8cf0; color: white; border: none; }
|
||
.success-btn { background-color: #19be6b; color: white; border: none; }
|
||
.outline-btn { background-color: white; color: #666; border: 1px solid #dcdee2; }
|
||
|
||
/* Table Styles */
|
||
.table-container {
|
||
border: 1px solid #f0f0f0;
|
||
}
|
||
|
||
.table-header {
|
||
display: flex;
|
||
flex-direction: row;
|
||
background-color: #f8f8f9;
|
||
border-bottom: 1px solid #f0f0f0;
|
||
}
|
||
|
||
.th {
|
||
padding: 12px 10px;
|
||
font-size: 13px;
|
||
font-weight: bold;
|
||
color: #333;
|
||
}
|
||
|
||
.table-row {
|
||
display: flex;
|
||
flex-direction: row;
|
||
border-bottom: 1px solid #f0f0f0;
|
||
align-items: center;
|
||
}
|
||
|
||
.td {
|
||
padding: 12px 10px;
|
||
font-size: 13px;
|
||
color: #666;
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
}
|
||
|
||
.flex-1 { flex: 1; }
|
||
.flex-2 { flex: 2; }
|
||
.flex-3 { flex: 3; }
|
||
.center { justify-content: center; }
|
||
.center-row { justify-content: center; }
|
||
|
||
.link {
|
||
color: #2d8cf0;
|
||
text-decoration: underline;
|
||
}
|
||
|
||
.small-text { font-size: 11px; }
|
||
.muted { color: #999; }
|
||
|
||
.op-link {
|
||
color: #2d8cf0;
|
||
font-size: 12px;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.op-link.danger {
|
||
color: #ed4014;
|
||
}
|
||
|
||
.empty-state {
|
||
padding: 40px;
|
||
display: flex;
|
||
justify-content: center;
|
||
}
|
||
|
||
.empty-text {
|
||
color: #ccc;
|
||
font-size: 14px;
|
||
}
|
||
</style>
|
||
|