Files
medical-mall/pages/mall/admin/setting/interface/storage.uvue
2026-02-13 00:54:33 +08:00

482 lines
13 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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>