完善页面5

This commit is contained in:
2026-02-13 00:54:33 +08:00
parent 194dd19174
commit 1b558e3117
2 changed files with 659 additions and 53 deletions

View File

@@ -1,28 +1,215 @@
<template> <template>
<view class="admin-page-container"> <view class="admin-page-container">
<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="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="content-card">
<view class="tabs-header"><view class="tab-item active"><text class="tab-text">基础配置</text></view></view> <view class="tabs-header">
<view class="config-view"> <view :class="['tab-item', activeTab == 0 ? 'active' : '']" @click="activeTab = 0">
<text class="tab-text">基础配置</text>
</view>
<view :class="['tab-item', activeTab == 1 ? 'active' : '']" @click="activeTab = 1">
<text class="tab-text">99api配置</text>
</view>
</view>
<!-- 基础配置 -->
<view class="form-section" v-if="activeTab == 0">
<view class="form-content"> <view class="form-content">
<view class="form-row"> <view class="form-row">
<view class="form-label">接口选择:</view> <view class="form-label">接口选择:</view>
<view class="form-input-box"> <view class="form-input-box">
<radio-group @change="onInterfaceChange"> <radio-group class="form-radio-group" @change="onBaseChange('type', $event)">
<label><radio value="onepass" checked color="#2d8cf0" /><text>一号通</text></label> <label class="radio-label">
<label><radio value="99api" color="#2d8cf0" /><text>99Api</text></label> <radio value="onepass" :checked="form.base.type == 'onepass'" color="#2d8cf0" />
<text class="radio-text">一号通</text>
</label>
<label class="radio-label">
<radio value="99api" :checked="form.base.type == '99api'" color="#2d8cf0" />
<text class="radio-text">99Api</text>
</label>
</radio-group> </radio-group>
<text class="form-tips highlight">采集商品接口选择一号通快速注册开通使用不用配置apikey或者去99api网址https://www.99api.com/注册账号。推荐一号通方便快捷</text>
</view> </view>
</view> </view>
<view class="form-actions"><button class="submit-btn" type="primary" @click="handleSubmit">提交</button></view> <view class="form-actions" style="margin-top: 20px;">
<button class="submit-btn" type="primary" @click="handleSave">提交</button>
</view>
</view>
</view>
<!-- 99api配置 -->
<view class="form-section" v-if="activeTab == 1">
<view class="form-content">
<view class="form-row">
<view class="form-label">99Api apiKey:</view>
<view class="form-input-box">
<input class="form-input max-width-input" v-model="form.api99.apiKey" placeholder="请输入99Api apiKey" />
<text class="form-tips highlight">注册99api采集接口在个人中心复制key</text>
</view>
</view>
<view class="form-actions" style="margin-top: 20px;">
<button class="submit-btn" type="primary" @click="handleSave">提交</button>
</view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</template> </template>
<script setup lang="uts"> <script setup lang="uts">
import { ref } from 'vue' import { ref, reactive } from 'vue'
const onInterfaceChange = (e : any) => { console.log(e.detail.value) }
const handleSubmit = () => { uni.showToast({ title: '提交成功' }) } const activeTab = ref(0)
const form = reactive({
base: {
type: 'onepass'
},
api99: {
apiKey: ''
}
})
const onBaseChange = (key : string, e : any) => {
form.base[key] = e.detail.value
}
const handleSave = () => {
uni.showToast({
title: '提交成功',
icon: 'success'
})
}
</script> </script>
<style scoped> .admin-page-container { padding: 20px; background-color: #f5f7f9; } .content-card { background: #fff; padding: 20px; } .breadcrumb { margin-bottom: 20px; display: flex; flex-direction: row; } </style>
<style scoped>
.admin-page-container {
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: #fff;
border-radius: 4px;
box-shadow: 0 1px 4px rgba(0,21,41,.08);
}
.tabs-header {
display: flex;
flex-direction: row;
border-bottom: 1px solid #f0f0f0;
padding: 0 30px;
}
.tab-item {
padding: 16px 20px;
margin-right: 32px;
cursor: pointer;
border-bottom: 2px solid transparent;
}
.tab-text {
font-size: 14px;
color: #666;
}
.tab-item.active {
border-bottom-color: #2d8cf0;
}
.tab-item.active .tab-text {
color: #2d8cf0;
font-weight: bold;
}
.form-section {
padding: 30px;
}
.form-content {
max-width: 900px;
}
.form-row {
display: flex;
flex-direction: row;
margin-bottom: 24px;
}
.form-label {
width: 140px;
font-size: 14px;
color: #333;
text-align: right;
margin-right: 24px;
padding-top: 8px;
}
.form-input-box {
flex: 1;
}
.form-input {
width: 100%;
border: 1px solid #dcdfe6;
border-radius: 4px;
height: 34px;
padding: 0 12px;
font-size: 14px;
}
.max-width-input {
max-width: 450px;
}
.form-tips {
display: block;
font-size: 12px;
color: #999;
margin-top: 10px;
line-height: 1.6;
}
.highlight {
color: #c0c4cc;
}
.form-radio-group {
display: flex;
flex-direction: row;
align-items: center;
height: 34px;
}
.radio-label {
display: flex;
flex-direction: row;
align-items: center;
margin-right: 24px;
}
.radio-text {
font-size: 14px;
margin-left: 6px;
color: #606266;
}
.form-actions {
padding-left: 164px;
}
.submit-btn {
width: 65px;
height: 32px;
background-color: #2d8cf0;
color: #fff;
border-radius: 4px;
font-size: 14px;
line-height: 32px;
text-align: center;
border: none;
}
</style>

View File

@@ -1,62 +1,481 @@
<template> <template>
<view class="admin-page-container"> <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="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="content-card">
<view class="tabs-header"> <view class="tabs-header">
<scroll-view class="tabs-scroll" scroll-x="true" show-scrollbar="false"> <scroll-view class="tabs-scroll" scroll-x="true" show-scrollbar="false">
<view class="tabs-list"> <view class="tabs-list">
<view class="tab-item active"><text class="tab-text">储存配置</text></view> <view
<view class="tab-item"><text class="tab-text">七牛云储存</text></view> v-for="(item, index) in tabs"
<view class="tab-item"><text class="tab-text">阿里云储存</text></view> :key="index"
class="tab-item"
:class="{ active: activeTab === index }"
@click="activeTab = index"
>
<text class="tab-text">{{ item }}</text>
</view>
</view> </view>
</scroll-view> </scroll-view>
</view> </view>
<view class="config-view">
<view class="notice-box"> <view class="tab-body">
<text class="notice-text">上传图片时会生成缩略图\nx</text> <!-- Tab 0: 储存配置 -->
</view> <view v-if="activeTab === 0" class="config-view">
<view class="form-content"> <view class="notice-box">
<view class="form-row"> <view class="notice-content">
<view class="form-label">存储方式:</view> <text class="notice-line">上传图片时会生成缩略图</text>
<view class="form-input-box"> <text class="notice-line">未设置按照系统默认生成系统默认大图800*800中图300*300小图150*150</text>
<radio-group class="form-radio-group" @change="onStorageTypeChange"> <text class="notice-line">水印只在上传图片时生成,原图,大中小缩略图都会按照比例存在。</text>
<label class="radio-label"><radio value="local" :checked="form.storageType == 'local'" color="#2d8cf0" /><text class="radio-text">本地存储</text></label> <text class="notice-line">若上传图片时未开启水印,则该图在开启水印之后依旧无水印效果。</text>
<label class="radio-label"><radio value="qiniu" :checked="form.storageType == 'qiniu'" color="#2d8cf0" /><text class="radio-text">七牛云存储</text></label> </view>
</radio-group> <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 class="form-actions"><button class="save-btn" type="primary" @click="handleSave">保存</button></view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</template> </template>
<script setup lang="uts"> <script setup lang="uts">
import { ref, reactive } from 'vue' import { ref, reactive } from 'vue'
const form = reactive({ storageType: 'local' })
const onStorageTypeChange = (e : any) => { form.storageType = e.detail.value } const tabs = ['储存配置', '七牛云储存', '阿里云储存', '腾讯云储存', '京东云储存', '华为云储存', '天翼云储存']
const handleSave = () => { uni.showToast({ title: '保存成功' }) } 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> </script>
<style scoped> <style scoped>
.admin-page-container { min-height: 100vh; background-color: #f5f7f9; padding: 20px; } .admin-page {
.breadcrumb { display: flex; flex-direction: row; margin-bottom: 20px; } min-height: 100vh;
.bc-item { font-size: 14px; color: #999; } background-color: #f5f7f9;
.bc-item.active { color: #333; } padding: 20px;
.bc-sep { margin: 0 8px; color: #ccc; } }
.content-card { background-color: #fff; border-radius: 4px; }
.tabs-header { border-bottom: 1px solid #f0f0f0; } .breadcrumb {
.tabs-scroll { white-space: nowrap; width: 100%; } display: flex;
.tabs-list { display: flex; flex-direction: row; padding: 0 20px; } flex-direction: row;
.tab-item { padding: 15px 20px; cursor: pointer; } margin-bottom: 20px;
.tab-text { font-size: 14px; color: #666; } }
.tab-item.active { border-bottom: 2px solid #2d8cf0; }
.tab-item.active .tab-text { color: #2d8cf0; font-weight: bold; } .bc-item {
.config-view { padding: 24px; } font-size: 14px;
.notice-box { background-color: #fffbe6; border: 1px solid #ffe58f; border-radius: 4px; padding: 16px; margin-bottom: 30px; } color: #999;
.notice-text { font-size: 13px; color: #faad14; line-height: 1.8; } }
.form-content { padding-left: 20px; }
.form-row { display: flex; flex-direction: row; margin-bottom: 30px; align-items: center; } .bc-item.active {
.form-label { width: 140px; font-size: 14px; color: #333; text-align: right; margin-right: 20px; } color: #333;
.form-actions { margin-top: 40px; padding-left: 160px; } }
.save-btn { width: 80px; height: 36px; background-color: #2d8cf0; color: #fff; border-radius: 4px; font-size: 14px; line-height: 36px; text-align: center; }
.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> </style>