调整文件结构;跑通admin端;初步设计页面结构
This commit is contained in:
64
pages/mall/admin/activity-log.uvue
Normal file
64
pages/mall/admin/activity-log.uvue
Normal file
@@ -0,0 +1,64 @@
|
||||
<!-- 活动日志页面 -->
|
||||
<template>
|
||||
<view class="activity-log">
|
||||
<view class="page-header">
|
||||
<text class="page-title">活动日志</text>
|
||||
<text class="page-subtitle">查看系统活动和操作日志</text>
|
||||
</view>
|
||||
|
||||
<view class="log-content">
|
||||
<text class="coming-soon">活动日志功能正在开发中...</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
// 统一的导航方法
|
||||
const go = (url: string) => {
|
||||
// 1) 目标页面必须是非 tabBar 页面
|
||||
// 2) 必须在 pages.json / subPackages 注册
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.activity-log {
|
||||
padding: 30rpx;
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
background-color: #fff;
|
||||
padding: 40rpx;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.page-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #212529;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
font-size: 26rpx;
|
||||
color: #6c757d;
|
||||
}
|
||||
}
|
||||
|
||||
.log-content {
|
||||
background-color: #fff;
|
||||
padding: 60rpx 40rpx;
|
||||
border-radius: 16rpx;
|
||||
text-align: center;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.coming-soon {
|
||||
font-size: 28rpx;
|
||||
color: #6c757d;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
64
pages/mall/admin/complaints.uvue
Normal file
64
pages/mall/admin/complaints.uvue
Normal file
@@ -0,0 +1,64 @@
|
||||
<!-- 投诉处理页面 -->
|
||||
<template>
|
||||
<view class="complaints">
|
||||
<view class="page-header">
|
||||
<text class="page-title">投诉处理</text>
|
||||
<text class="page-subtitle">处理用户投诉和反馈</text>
|
||||
</view>
|
||||
|
||||
<view class="complaints-content">
|
||||
<text class="coming-soon">投诉处理功能正在开发中...</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
// 统一的导航方法
|
||||
const go = (url: string) => {
|
||||
// 1) 目标页面必须是非 tabBar 页面
|
||||
// 2) 必须在 pages.json / subPackages 注册
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.complaints {
|
||||
padding: 30rpx;
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
background-color: #fff;
|
||||
padding: 40rpx;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.page-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #212529;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
font-size: 26rpx;
|
||||
color: #6c757d;
|
||||
}
|
||||
}
|
||||
|
||||
.complaints-content {
|
||||
background-color: #fff;
|
||||
padding: 60rpx 40rpx;
|
||||
border-radius: 16rpx;
|
||||
text-align: center;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.coming-soon {
|
||||
font-size: 28rpx;
|
||||
color: #6c757d;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
11
pages/mall/admin/coupon-management.uvue
Normal file
11
pages/mall/admin/coupon-management.uvue
Normal file
@@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<text>优惠券管理 - 占位页</text>
|
||||
</view>
|
||||
</template>
|
||||
<script lang="uts">
|
||||
export default {}
|
||||
</script>
|
||||
<style>
|
||||
.page { padding: 30rpx; }
|
||||
</style>
|
||||
11
pages/mall/admin/delivery-management.uvue
Normal file
11
pages/mall/admin/delivery-management.uvue
Normal file
@@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<text>配送管理 - 占位页</text>
|
||||
</view>
|
||||
</template>
|
||||
<script lang="uts">
|
||||
export default {}
|
||||
</script>
|
||||
<style>
|
||||
.page { padding: 30rpx; }
|
||||
</style>
|
||||
607
pages/mall/admin/finance-management.uvue
Normal file
607
pages/mall/admin/finance-management.uvue
Normal file
@@ -0,0 +1,607 @@
|
||||
<!-- 财务管理页面 - 基于CRMEB设计 -->
|
||||
<template>
|
||||
<view class="finance-management">
|
||||
<!-- 财务概览 -->
|
||||
<view class="finance-overview">
|
||||
<view class="overview-grid">
|
||||
<view class="overview-card">
|
||||
<text class="card-title">今日收入</text>
|
||||
<text class="card-amount">¥{{ overview.today_income }}</text>
|
||||
<text class="card-change positive">+{{ overview.income_growth }}%</text>
|
||||
</view>
|
||||
<view class="overview-card">
|
||||
<text class="card-title">本月收入</text>
|
||||
<text class="card-amount">¥{{ overview.month_income }}</text>
|
||||
<text class="card-change positive">+{{ overview.month_growth }}%</text>
|
||||
</view>
|
||||
<view class="overview-card">
|
||||
<text class="card-title">账户余额</text>
|
||||
<text class="card-amount">¥{{ overview.account_balance }}</text>
|
||||
<text class="card-change neutral">--</text>
|
||||
</view>
|
||||
<view class="overview-card">
|
||||
<text class="card-title">待结算</text>
|
||||
<text class="card-amount">¥{{ overview.pending_settlement }}</text>
|
||||
<text class="card-change neutral">--</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 财务明细 -->
|
||||
<view class="finance-details">
|
||||
<view class="section-header">
|
||||
<text class="section-title">财务明细</text>
|
||||
<view class="header-actions">
|
||||
<button class="btn btn-primary" @click="exportRecords">导出记录</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="filter-bar">
|
||||
<view class="filter-item">
|
||||
<text class="label">交易类型:</text>
|
||||
<picker mode="selector" :range="transactionTypes" range-key="label" @change="onTypeChange">
|
||||
<view class="picker-text">{{ selectedType || '全部' }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="filter-item">
|
||||
<text class="label">时间范围:</text>
|
||||
<view class="date-range">
|
||||
<picker mode="date" @change="onStartDateChange">
|
||||
<view class="date-picker">{{ startDate || '开始日期' }}</view>
|
||||
</picker>
|
||||
<text class="separator">至</text>
|
||||
<picker mode="date" @change="onEndDateChange">
|
||||
<view class="date-picker">{{ endDate || '结束日期' }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
<view class="filter-actions">
|
||||
<button class="btn btn-default" @click="resetFilters">重置</button>
|
||||
<button class="btn btn-primary" @click="applyFilters">筛选</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="records-table">
|
||||
<view class="table-header">
|
||||
<view class="table-row">
|
||||
<view class="table-cell">交易时间</view>
|
||||
<view class="table-cell">交易类型</view>
|
||||
<view class="table-cell">订单号</view>
|
||||
<view class="table-cell">金额</view>
|
||||
<view class="table-cell">余额</view>
|
||||
<view class="table-cell">备注</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="table-body">
|
||||
<view v-for="record in records" :key="record.id" class="table-row data-row">
|
||||
<view class="table-cell">{{ formatDateTime(record.created_at) }}</view>
|
||||
<view class="table-cell">
|
||||
<text class="type-tag" :class="'type-' + record.type">{{ getTypeText(record.type) }}</text>
|
||||
</view>
|
||||
<view class="table-cell">{{ record.order_sn || '--' }}</view>
|
||||
<view class="table-cell">
|
||||
<text :class="record.amount > 0 ? 'income' : 'expense'">
|
||||
{{ record.amount > 0 ? '+' : '' }}¥{{ record.amount }}
|
||||
</text>
|
||||
</view>
|
||||
<view class="table-cell">¥{{ record.balance_after }}</view>
|
||||
<view class="table-cell">{{ record.remark || '--' }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 分页 -->
|
||||
<view class="pagination">
|
||||
<view class="page-info">共 {{ totalRecords }} 条记录,第 {{ currentPage }}/{{ totalPages }} 页</view>
|
||||
<view class="page-buttons">
|
||||
<button class="page-btn" :disabled="currentPage === 1" @click="goToPage(currentPage - 1)">上一页</button>
|
||||
<view class="page-numbers">
|
||||
<button
|
||||
v-for="page in visiblePages"
|
||||
:key="page"
|
||||
class="page-number"
|
||||
:class="{ active: page === currentPage }"
|
||||
@click="goToPage(page)"
|
||||
>{{ page }}</button>
|
||||
</view>
|
||||
<button class="page-btn" :disabled="currentPage === totalPages" @click="goToPage(currentPage + 1)">下一页</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import { ref, onMounted, computed } from 'vue'
|
||||
import supa from '@/components/supadb/aksupainstance.uts'
|
||||
|
||||
// 响应式数据
|
||||
const overview = ref({
|
||||
today_income: '0.00',
|
||||
income_growth: '0.00',
|
||||
month_income: '0.00',
|
||||
month_growth: '0.00',
|
||||
account_balance: '0.00',
|
||||
pending_settlement: '0.00'
|
||||
})
|
||||
|
||||
const records = ref([])
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(20)
|
||||
const totalRecords = ref(0)
|
||||
const totalPages = ref(0)
|
||||
|
||||
const transactionTypes = ref([
|
||||
{ value: '', label: '全部' },
|
||||
{ value: '1', label: '订单收入' },
|
||||
{ value: '2', label: '退款支出' },
|
||||
{ value: '3', label: '提现支出' },
|
||||
{ value: '4', label: '充值收入' },
|
||||
{ value: '5', label: '系统调整' }
|
||||
])
|
||||
|
||||
const selectedType = ref('')
|
||||
const startDate = ref('')
|
||||
const endDate = ref('')
|
||||
|
||||
// 计算属性
|
||||
const visiblePages = computed(() => {
|
||||
const pages = []
|
||||
const start = Math.max(1, currentPage.value - 2)
|
||||
const end = Math.min(totalPages.value, currentPage.value + 2)
|
||||
|
||||
for (let i = start; i <= end; i++) {
|
||||
pages.push(i)
|
||||
}
|
||||
return pages
|
||||
})
|
||||
|
||||
// 方法
|
||||
const onTypeChange = (e: any) => {
|
||||
selectedType.value = transactionTypes.value[e.detail.value].label
|
||||
}
|
||||
|
||||
const onStartDateChange = (e: any) => {
|
||||
startDate.value = e.detail.value
|
||||
}
|
||||
|
||||
const onEndDateChange = (e: any) => {
|
||||
endDate.value = e.detail.value
|
||||
}
|
||||
|
||||
const applyFilters = () => {
|
||||
loadRecords()
|
||||
}
|
||||
|
||||
const resetFilters = () => {
|
||||
selectedType.value = ''
|
||||
startDate.value = ''
|
||||
endDate.value = ''
|
||||
loadRecords()
|
||||
}
|
||||
|
||||
const exportRecords = () => {
|
||||
uni.showToast({
|
||||
title: '导出功能开发中',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
|
||||
const goToPage = (page: number) => {
|
||||
if (page >= 1 && page <= totalPages.value) {
|
||||
currentPage.value = page
|
||||
loadRecords()
|
||||
}
|
||||
}
|
||||
|
||||
const getTypeText = (type: number) => {
|
||||
const typeMap = {
|
||||
1: '订单收入',
|
||||
2: '退款支出',
|
||||
3: '提现支出',
|
||||
4: '充值收入',
|
||||
5: '系统调整'
|
||||
}
|
||||
return typeMap[type] || '未知'
|
||||
}
|
||||
|
||||
const formatDateTime = (dateStr: string) => {
|
||||
if (!dateStr) return ''
|
||||
const date = new Date(dateStr)
|
||||
return date.toLocaleString()
|
||||
}
|
||||
|
||||
// 数据加载方法
|
||||
const loadOverview = async () => {
|
||||
try {
|
||||
const { data } = await supa.rpc('get_finance_overview')
|
||||
if (data) {
|
||||
overview.value = data
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载财务概览失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const loadRecords = async () => {
|
||||
try {
|
||||
let query = supa.from('finance_records').select('*').order('created_at', { ascending: false })
|
||||
|
||||
// 筛选条件
|
||||
if (selectedType.value && selectedType.value !== '全部') {
|
||||
const typeObj = transactionTypes.value.find((t: any) => t.label === selectedType.value)
|
||||
if (typeObj) {
|
||||
query = query.eq('type', parseInt(typeObj.value))
|
||||
}
|
||||
}
|
||||
|
||||
if (startDate.value && endDate.value) {
|
||||
query = query.gte('created_at', startDate.value + ' 00:00:00')
|
||||
.lte('created_at', endDate.value + ' 23:59:59')
|
||||
}
|
||||
|
||||
// 分页
|
||||
const from = (currentPage.value - 1) * pageSize.value
|
||||
const to = from + pageSize.value - 1
|
||||
|
||||
const { data, count } = await query.range(from, to)
|
||||
records.value = data || []
|
||||
totalRecords.value = count || 0
|
||||
totalPages.value = Math.ceil(totalRecords.value / pageSize.value)
|
||||
|
||||
} catch (error) {
|
||||
console.error('加载财务记录失败:', error)
|
||||
uni.showToast({
|
||||
title: '加载失败',
|
||||
icon: 'error'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 页面初始化
|
||||
onMounted(async () => {
|
||||
await Promise.all([
|
||||
loadOverview(),
|
||||
loadRecords()
|
||||
])
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.finance-management {
|
||||
padding: 30rpx;
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
// 财务概览样式
|
||||
.finance-overview {
|
||||
background-color: #fff;
|
||||
border-radius: 12rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.overview-grid {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.overview-card {
|
||||
flex: 1;
|
||||
padding: 20rpx;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 8rpx;
|
||||
text-align: center;
|
||||
|
||||
.card-title {
|
||||
font-size: 24rpx;
|
||||
color: #6c757d;
|
||||
margin-bottom: 10rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.card-amount {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #28a745;
|
||||
margin-bottom: 5rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.card-change {
|
||||
font-size: 20rpx;
|
||||
|
||||
&.positive {
|
||||
color: #28a745;
|
||||
}
|
||||
|
||||
&.negative {
|
||||
color: #dc3545;
|
||||
}
|
||||
|
||||
&.neutral {
|
||||
color: #6c757d;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 财务明细样式
|
||||
.finance-details {
|
||||
background-color: #fff;
|
||||
border-radius: 12rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 30rpx 30rpx 0;
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #212529;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 12rpx 24rpx;
|
||||
border-radius: 6rpx;
|
||||
font-size: 26rpx;
|
||||
border: none;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.filter-bar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20rpx;
|
||||
padding: 30rpx;
|
||||
border-bottom: 1rpx solid #e9ecef;
|
||||
|
||||
.filter-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.label {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
margin-right: 10rpx;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.picker-text {
|
||||
padding: 0 20rpx;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
border: 1rpx solid #ddd;
|
||||
border-radius: 6rpx;
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
min-width: 150rpx;
|
||||
}
|
||||
|
||||
.date-range {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
|
||||
.date-picker {
|
||||
padding: 0 20rpx;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
border: 1rpx solid #ddd;
|
||||
border-radius: 6rpx;
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.separator {
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.filter-actions {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
margin-left: auto;
|
||||
|
||||
.btn {
|
||||
padding: 12rpx 24rpx;
|
||||
border-radius: 6rpx;
|
||||
font-size: 26rpx;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
|
||||
&.btn-primary {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.btn-default {
|
||||
background-color: #f5f5f5;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.records-table {
|
||||
.table-header {
|
||||
background-color: #f8f9fa;
|
||||
border-bottom: 1rpx solid #e9ecef;
|
||||
|
||||
.table-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx 30rpx;
|
||||
font-weight: bold;
|
||||
font-size: 26rpx;
|
||||
color: #495057;
|
||||
}
|
||||
}
|
||||
|
||||
.table-body {
|
||||
.data-row {
|
||||
border-bottom: 1rpx solid #e9ecef;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx 30rpx;
|
||||
min-height: 80rpx;
|
||||
|
||||
.table-cell {
|
||||
flex: 1;
|
||||
font-size: 26rpx;
|
||||
color: #495057;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.type-tag {
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 12rpx;
|
||||
font-size: 24rpx;
|
||||
font-weight: bold;
|
||||
|
||||
&.type-1 {
|
||||
background-color: #d4edda;
|
||||
color: #155724;
|
||||
}
|
||||
|
||||
&.type-2,
|
||||
&.type-3 {
|
||||
background-color: #f8d7da;
|
||||
color: #721c24;
|
||||
}
|
||||
|
||||
&.type-4 {
|
||||
background-color: #cce5ff;
|
||||
color: #0066cc;
|
||||
}
|
||||
|
||||
&.type-5 {
|
||||
background-color: #fff3cd;
|
||||
color: #856404;
|
||||
}
|
||||
}
|
||||
|
||||
.income {
|
||||
color: #28a745;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.expense {
|
||||
color: #dc3545;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
// 分页样式
|
||||
.pagination {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 30rpx;
|
||||
border-top: 1rpx solid #e9ecef;
|
||||
|
||||
.page-info {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.page-buttons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
.page-btn,
|
||||
.page-number {
|
||||
padding: 12rpx 20rpx;
|
||||
border: 1rpx solid #ddd;
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
border-radius: 6rpx;
|
||||
font-size: 26rpx;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:disabled {
|
||||
background-color: #f5f5f5;
|
||||
color: #999;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border-color: #007bff;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border-color: #007bff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式设计
|
||||
@media (max-width: 750rpx) {
|
||||
.overview-grid {
|
||||
flex-direction: column;
|
||||
gap: 15rpx;
|
||||
}
|
||||
|
||||
.filter-bar {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
|
||||
.filter-actions {
|
||||
margin-left: 0;
|
||||
margin-top: 15rpx;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.table-row {
|
||||
flex-wrap: wrap;
|
||||
padding: 15rpx;
|
||||
|
||||
.table-cell {
|
||||
min-width: 150rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.pagination {
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
align-items: center;
|
||||
|
||||
.page-info {
|
||||
order: 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,64 +1,68 @@
|
||||
<!-- 后台管理端首页 - UTS Android 兼容 -->
|
||||
<!-- 后台管理端首页 - 基于CRMEB设计 -->
|
||||
<template>
|
||||
<view class="admin-container">
|
||||
<!-- 头部导航 -->
|
||||
<view class="header">
|
||||
<view class="header-left">
|
||||
<text class="app-title">商城管理后台</text>
|
||||
<text class="welcome-text">欢迎回来,{{ adminInfo.nickname }}</text>
|
||||
</view>
|
||||
<view class="header-right">
|
||||
<text class="notification-btn" @click="goToNotifications">🔔</text>
|
||||
<text class="profile-btn" @click="goToProfile">👤</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 核心指标概览 -->
|
||||
<view class="metrics-section">
|
||||
<text class="section-title">核心指标</text>
|
||||
<view class="metrics-grid">
|
||||
<view class="metric-card">
|
||||
<text class="metric-value">¥{{ platformStats.total_gmv }}</text>
|
||||
<text class="metric-label">总GMV</text>
|
||||
<text class="metric-change positive">+{{ platformStats.gmv_growth }}%</text>
|
||||
</view>
|
||||
<view class="metric-card">
|
||||
<text class="metric-value">{{ platformStats.total_orders }}</text>
|
||||
<text class="metric-label">总订单数</text>
|
||||
<text class="metric-change positive">+{{ platformStats.order_growth }}%</text>
|
||||
</view>
|
||||
<view class="metric-card">
|
||||
<text class="metric-value">{{ platformStats.total_users }}</text>
|
||||
<text class="metric-label">注册用户</text>
|
||||
<text class="metric-change positive">+{{ platformStats.user_growth }}%</text>
|
||||
</view>
|
||||
<view class="metric-card">
|
||||
<text class="metric-value">{{ platformStats.total_merchants }}</text>
|
||||
<text class="metric-label">入驻商家</text>
|
||||
<text class="metric-change positive">+{{ platformStats.merchant_growth }}%</text>
|
||||
<view class="admin-dashboard">
|
||||
<!-- 基础信息统计卡片 -->
|
||||
<view class="base-info-section">
|
||||
<view class="info-grid">
|
||||
<view class="info-card" v-for="(item, index) in infoList" :key="index">
|
||||
<view class="card-header">
|
||||
<text class="card-title">{{ item.title }}</text>
|
||||
<text class="card-date">{{ item.date }}</text>
|
||||
</view>
|
||||
<view class="card-content">
|
||||
<text class="today-number">{{ item.today }}</text>
|
||||
<view class="comparison-info">
|
||||
<text class="yesterday-text">昨日 {{ item.yesterday }}</text>
|
||||
<text class="ratio-text" :class="{ positive: item.today_ratio >= 0, negative: item.today_ratio < 0 }">
|
||||
日环比 {{ item.today_ratio }}%
|
||||
<text class="ratio-icon">{{ item.today_ratio >= 0 ? '↑' : '↓' }}</text>
|
||||
</text>
|
||||
</view>
|
||||
<view class="divider"></view>
|
||||
<view class="total-info">
|
||||
<text class="total-label">{{ item.total_name }}</text>
|
||||
<text class="total-value">{{ item.total }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 今日数据 -->
|
||||
<view class="today-section">
|
||||
<text class="section-title">今日数据</text>
|
||||
<view class="today-grid">
|
||||
<view class="today-item">
|
||||
<text class="today-value">¥{{ todayStats.sales }}</text>
|
||||
<text class="today-label">销售额</text>
|
||||
<!-- 功能导航网格 -->
|
||||
<view class="grid-menu-section">
|
||||
<text class="section-title">功能导航</text>
|
||||
<view class="menu-grid">
|
||||
<view class="menu-item" @click="go('/pages/mall/admin/user-management')">
|
||||
<view class="menu-icon user-icon">👥</view>
|
||||
<text class="menu-text">用户管理</text>
|
||||
</view>
|
||||
<view class="today-item">
|
||||
<text class="today-value">{{ todayStats.orders }}</text>
|
||||
<text class="today-label">订单数</text>
|
||||
<view class="menu-item" @click="go('/pages/mall/admin/product-management')">
|
||||
<view class="menu-icon product-icon">📦</view>
|
||||
<text class="menu-text">商品管理</text>
|
||||
</view>
|
||||
<view class="today-item">
|
||||
<text class="today-value">{{ todayStats.new_users }}</text>
|
||||
<text class="today-label">新增用户</text>
|
||||
<view class="menu-item" @click="go('/pages/mall/admin/order-management')">
|
||||
<view class="menu-icon order-icon">📋</view>
|
||||
<text class="menu-text">订单管理</text>
|
||||
</view>
|
||||
<view class="today-item">
|
||||
<text class="today-value">{{ todayStats.active_users }}</text>
|
||||
<text class="today-label">活跃用户</text>
|
||||
<view class="menu-item" @click="go('/pages/mall/admin/finance-management')">
|
||||
<view class="menu-icon finance-icon">💰</view>
|
||||
<text class="menu-text">财务管理</text>
|
||||
</view>
|
||||
<view class="menu-item" @click="go('/pages/mall/admin/marketing-management')">
|
||||
<view class="menu-icon marketing-icon">📢</view>
|
||||
<text class="menu-text">营销管理</text>
|
||||
</view>
|
||||
<view class="menu-item" @click="go('/pages/mall/admin/system-settings')">
|
||||
<view class="menu-icon settings-icon">⚙️</view>
|
||||
<text class="menu-text">系统设置</text>
|
||||
</view>
|
||||
<view class="menu-item" @click="go('/pages/mall/admin/coupon-management')">
|
||||
<view class="menu-icon coupon-icon">🎫</view>
|
||||
<text class="menu-text">优惠券管理</text>
|
||||
</view>
|
||||
<view class="menu-item" @click="go('/pages/mall/admin/activity-log')">
|
||||
<view class="menu-icon log-icon">📊</view>
|
||||
<text class="menu-text">活动日志</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -67,7 +71,7 @@
|
||||
<view class="pending-section">
|
||||
<text class="section-title">待处理事项</text>
|
||||
<view class="pending-list">
|
||||
<view class="pending-item urgent" @click="goToMerchantReview">
|
||||
<view class="pending-item urgent" @click="go('/pages/mall/admin/merchant-review')">
|
||||
<text class="pending-icon">🏪</text>
|
||||
<view class="pending-content">
|
||||
<text class="pending-title">商家入驻审核</text>
|
||||
@@ -75,8 +79,8 @@
|
||||
</view>
|
||||
<text class="pending-count">{{ pendingCounts.merchant_review }}</text>
|
||||
</view>
|
||||
|
||||
<view class="pending-item" @click="goToProductReview">
|
||||
|
||||
<view class="pending-item" @click="go('/pages/mall/admin/product-review')">
|
||||
<text class="pending-icon">📦</text>
|
||||
<view class="pending-content">
|
||||
<text class="pending-title">商品审核</text>
|
||||
@@ -84,8 +88,8 @@
|
||||
</view>
|
||||
<text class="pending-count">{{ pendingCounts.product_review }}</text>
|
||||
</view>
|
||||
|
||||
<view class="pending-item" @click="goToRefundReview">
|
||||
|
||||
<view class="pending-item" @click="go('/pages/mall/admin/refund-review')">
|
||||
<text class="pending-icon">💰</text>
|
||||
<view class="pending-content">
|
||||
<text class="pending-title">退款处理</text>
|
||||
@@ -93,8 +97,8 @@
|
||||
</view>
|
||||
<text class="pending-count">{{ pendingCounts.refund_review }}</text>
|
||||
</view>
|
||||
|
||||
<view class="pending-item" @click="goToComplaints">
|
||||
|
||||
<view class="pending-item" @click="go('/pages/mall/admin/complaints')">
|
||||
<text class="pending-icon">⚠️</text>
|
||||
<view class="pending-content">
|
||||
<text class="pending-title">投诉处理</text>
|
||||
@@ -136,43 +140,43 @@
|
||||
<view class="shortcuts-section">
|
||||
<text class="section-title">快捷管理</text>
|
||||
<view class="shortcuts-grid">
|
||||
<view class="shortcut-item" @click="goToUserManagement">
|
||||
<view class="shortcut-item" @click="go('/pages/mall/admin/user-management')">
|
||||
<text class="shortcut-icon">👥</text>
|
||||
<text class="shortcut-text">用户管理</text>
|
||||
</view>
|
||||
<view class="shortcut-item" @click="goToMerchantManagement">
|
||||
<view class="shortcut-item" @click="go('/pages/mall/admin/merchant-management')">
|
||||
<text class="shortcut-icon">🏪</text>
|
||||
<text class="shortcut-text">商家管理</text>
|
||||
</view>
|
||||
<view class="shortcut-item" @click="goToProductManagement">
|
||||
<view class="shortcut-item" @click="go('/pages/mall/admin/product-management')">
|
||||
<text class="shortcut-icon">📦</text>
|
||||
<text class="shortcut-text">商品管理</text>
|
||||
</view>
|
||||
<view class="shortcut-item" @click="goToOrderManagement">
|
||||
<view class="shortcut-item" @click="go('/pages/mall/admin/order-management')">
|
||||
<text class="shortcut-icon">📋</text>
|
||||
<text class="shortcut-text">订单管理</text>
|
||||
</view>
|
||||
<view class="shortcut-item" @click="goToCouponManagement">
|
||||
<view class="shortcut-item" @click="go('/pages/mall/admin/coupon-management')">
|
||||
<text class="shortcut-icon">🎫</text>
|
||||
<text class="shortcut-text">优惠券管理</text>
|
||||
</view>
|
||||
<view class="shortcut-item" @click="goToDeliveryManagement">
|
||||
<view class="shortcut-item" @click="go('/pages/mall/admin/delivery-management')">
|
||||
<text class="shortcut-icon">🚚</text>
|
||||
<text class="shortcut-text">配送管理</text>
|
||||
</view>
|
||||
<view class="shortcut-item" @click="goToFinanceManagement">
|
||||
<view class="shortcut-item" @click="go('/pages/mall/admin/finance-management')">
|
||||
<text class="shortcut-icon">💳</text>
|
||||
<text class="shortcut-text">财务管理</text>
|
||||
</view>
|
||||
<view class="shortcut-item" @click="goToSystemSettings">
|
||||
<view class="shortcut-item" @click="go('/pages/mall/admin/system-settings')">
|
||||
<text class="shortcut-icon">⚙️</text>
|
||||
<text class="shortcut-text">系统设置</text>
|
||||
</view>
|
||||
<view class="shortcut-item" @click="goToAdminUserSubscriptions">
|
||||
<view class="shortcut-item" @click="go('/pages/mall/admin/subscription/user-subscriptions')">
|
||||
<text class="shortcut-icon">📑</text>
|
||||
<text class="shortcut-text">用户订阅</text>
|
||||
</view>
|
||||
<view class="shortcut-item" @click="goToSubscriptionPlans">
|
||||
<view class="shortcut-item" @click="go('/pages/mall/admin/subscription/plan-management')">
|
||||
<text class="shortcut-icon">🧾</text>
|
||||
<text class="shortcut-text">订阅方案</text>
|
||||
</view>
|
||||
@@ -183,7 +187,7 @@
|
||||
<view class="activities-section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">最新动态</text>
|
||||
<text class="section-more" @click="goToActivityLog">查看全部</text>
|
||||
<text class="section-more" @click="go('/pages/mall/admin/activity-log')">查看全部</text>
|
||||
</view>
|
||||
<view class="activities-list">
|
||||
<view v-for="activity in recentActivities" :key="activity.id" class="activity-item">
|
||||
@@ -284,6 +288,16 @@
|
||||
delivering_orders: 0,
|
||||
system_load: 0
|
||||
} as RealTimeStatsType,
|
||||
|
||||
infoList:{
|
||||
title: '总用户数',
|
||||
date: '2025-01-08',
|
||||
today: '1000',
|
||||
yesterday: '900',
|
||||
today_ratio: 10,
|
||||
total_name: '总用户数',
|
||||
total: '10000'
|
||||
} as Array<InfoListType>,
|
||||
|
||||
recentActivities: [] as Array<ActivityType>
|
||||
}
|
||||
@@ -402,6 +416,7 @@
|
||||
default: return '📝'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// 格式化时间
|
||||
formatTime(timeStr: string): string {
|
||||
@@ -418,108 +433,12 @@
|
||||
return `${Math.floor(minutes / 1440)}天前`
|
||||
}
|
||||
},
|
||||
|
||||
// 导航方法
|
||||
goToNotifications() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/mall/admin/notifications'
|
||||
})
|
||||
},
|
||||
|
||||
goToProfile() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/mall/admin/profile'
|
||||
})
|
||||
},
|
||||
|
||||
goToMerchantReview() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/mall/admin/merchant-review'
|
||||
})
|
||||
},
|
||||
|
||||
goToProductReview() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/mall/admin/product-review'
|
||||
})
|
||||
},
|
||||
|
||||
goToRefundReview() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/mall/admin/refund-review'
|
||||
})
|
||||
},
|
||||
|
||||
goToComplaints() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/mall/admin/complaints'
|
||||
})
|
||||
},
|
||||
|
||||
goToUserManagement() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/mall/admin/user-management'
|
||||
})
|
||||
},
|
||||
|
||||
goToMerchantManagement() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/mall/admin/merchant-management'
|
||||
})
|
||||
},
|
||||
|
||||
goToProductManagement() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/mall/admin/product-management'
|
||||
})
|
||||
},
|
||||
|
||||
goToOrderManagement() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/mall/admin/order-management'
|
||||
})
|
||||
},
|
||||
|
||||
goToCouponManagement() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/mall/admin/coupon-management'
|
||||
})
|
||||
},
|
||||
|
||||
goToDeliveryManagement() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/mall/admin/delivery-management'
|
||||
})
|
||||
},
|
||||
|
||||
goToFinanceManagement() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/mall/admin/finance-management'
|
||||
})
|
||||
},
|
||||
|
||||
goToSystemSettings() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/mall/admin/system-settings'
|
||||
})
|
||||
},
|
||||
|
||||
goToActivityLog() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/mall/admin/activity-log'
|
||||
})
|
||||
},
|
||||
|
||||
goToSubscriptionPlans() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/mall/admin/subscription/plan-management'
|
||||
})
|
||||
},
|
||||
|
||||
goToAdminUserSubscriptions() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/mall/admin/subscription/user-subscriptions'
|
||||
})
|
||||
|
||||
// 统一的导航方法
|
||||
go(url: string) {
|
||||
// 1) 目标页面必须是非 tabBar 页面
|
||||
// 2) 必须在 pages.json / subPackages 注册
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
366
pages/mall/admin/marketing-management.uvue
Normal file
366
pages/mall/admin/marketing-management.uvue
Normal file
@@ -0,0 +1,366 @@
|
||||
<!-- 营销管理页面 -->
|
||||
<template>
|
||||
<view class="marketing-management">
|
||||
<!-- 页面标题 -->
|
||||
<view class="page-header">
|
||||
<text class="page-title">营销管理</text>
|
||||
<text class="page-subtitle">管理营销活动、优惠券、直播等营销工具</text>
|
||||
</view>
|
||||
|
||||
<!-- 营销工具导航 -->
|
||||
<view class="marketing-tools">
|
||||
<view class="tool-grid">
|
||||
<view class="tool-item" @click="go('/pages/mall/admin/store-coupon')">
|
||||
<view class="tool-icon">🎫</view>
|
||||
<text class="tool-name">优惠券管理</text>
|
||||
<text class="tool-desc">创建和管理优惠券活动</text>
|
||||
</view>
|
||||
<view class="tool-item" @click="go('/pages/mall/admin/store-seckill')">
|
||||
<view class="tool-icon">⚡</view>
|
||||
<text class="tool-name">秒杀活动</text>
|
||||
<text class="tool-desc">管理限时秒杀活动</text>
|
||||
</view>
|
||||
<view class="tool-item" @click="go('/pages/mall/admin/store-bargain')">
|
||||
<view class="tool-icon">🪓</view>
|
||||
<text class="tool-name">砍价活动</text>
|
||||
<text class="tool-desc">管理砍价促销活动</text>
|
||||
</view>
|
||||
<view class="tool-item" @click="go('/pages/mall/admin/store-combination')">
|
||||
<view class="tool-icon">👥</view>
|
||||
<text class="tool-name">拼团活动</text>
|
||||
<text class="tool-desc">管理拼团购买活动</text>
|
||||
</view>
|
||||
<view class="tool-item" @click="go('/pages/mall/admin/live-broadcast')">
|
||||
<view class="tool-icon">📺</view>
|
||||
<text class="tool-name">直播管理</text>
|
||||
<text class="tool-desc">管理直播带货活动</text>
|
||||
</view>
|
||||
<view class="tool-item" @click="go('/pages/mall/admin/channel-code')">
|
||||
<view class="tool-icon">📱</view>
|
||||
<text class="tool-name">渠道码</text>
|
||||
<text class="tool-desc">生成和管理推广渠道码</text>
|
||||
</view>
|
||||
<view class="tool-item" @click="go('/pages/mall/admin/store-integral')">
|
||||
<view class="tool-icon">💎</view>
|
||||
<text class="tool-name">积分商品</text>
|
||||
<text class="tool-desc">管理积分兑换商品</text>
|
||||
</view>
|
||||
<view class="tool-item" @click="go('/pages/mall/admin/sign-in')">
|
||||
<view class="tool-icon">📅</view>
|
||||
<text class="tool-name">签到活动</text>
|
||||
<text class="tool-desc">管理用户签到奖励</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 营销数据统计 -->
|
||||
<view class="marketing-stats">
|
||||
<text class="section-title">营销数据概览</text>
|
||||
<view class="stats-grid">
|
||||
<view class="stat-card">
|
||||
<text class="stat-value">{{ stats.totalCoupons }}</text>
|
||||
<text class="stat-label">优惠券发放</text>
|
||||
</view>
|
||||
<view class="stat-card">
|
||||
<text class="stat-value">{{ stats.activeActivities }}</text>
|
||||
<text class="stat-label">进行中活动</text>
|
||||
</view>
|
||||
<view class="stat-card">
|
||||
<text class="stat-value">{{ stats.totalParticipants }}</text>
|
||||
<text class="stat-label">活动参与人数</text>
|
||||
</view>
|
||||
<view class="stat-card">
|
||||
<text class="stat-value">¥{{ stats.marketingRevenue }}</text>
|
||||
<text class="stat-label">营销收入</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 快捷操作 -->
|
||||
<view class="quick-actions">
|
||||
<text class="section-title">快捷操作</text>
|
||||
<view class="action-buttons">
|
||||
<button class="action-btn primary" @click="createActivity">创建新活动</button>
|
||||
<button class="action-btn secondary" @click="viewReports">查看营销报表</button>
|
||||
<button class="action-btn info" @click="manageCoupons">批量管理优惠券</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
|
||||
// 响应式数据
|
||||
const stats = ref({
|
||||
totalCoupons: 0,
|
||||
activeActivities: 0,
|
||||
totalParticipants: 0,
|
||||
marketingRevenue: '0.00'
|
||||
})
|
||||
|
||||
// 统一的导航方法
|
||||
const go = (url: string) => {
|
||||
// 1) 目标页面必须是非 tabBar 页面
|
||||
// 2) 必须在 pages.json / subPackages 注册
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
|
||||
// 快捷操作方法
|
||||
const createActivity = () => {
|
||||
uni.showActionSheet({
|
||||
itemList: ['优惠券活动', '秒杀活动', '砍价活动', '拼团活动', '直播活动'],
|
||||
success: (res) => {
|
||||
const activities = [
|
||||
'/pages/mall/admin/store-coupon',
|
||||
'/pages/mall/admin/store-seckill',
|
||||
'/pages/mall/admin/store-bargain',
|
||||
'/pages/mall/admin/store-combination',
|
||||
'/pages/mall/admin/live-broadcast'
|
||||
]
|
||||
if (activities[res.tapIndex]) {
|
||||
go(activities[res.tapIndex])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const viewReports = () => {
|
||||
uni.showToast({
|
||||
title: '营销报表功能开发中',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
|
||||
const manageCoupons = () => {
|
||||
go('/pages/mall/admin/store-coupon')
|
||||
}
|
||||
|
||||
// 页面初始化
|
||||
onMounted(() => {
|
||||
loadMarketingStats()
|
||||
})
|
||||
|
||||
// 加载营销统计数据
|
||||
const loadMarketingStats = async () => {
|
||||
try {
|
||||
// 这里应该调用实际的API
|
||||
// 暂时使用模拟数据
|
||||
stats.value = {
|
||||
totalCoupons: 12580,
|
||||
activeActivities: 8,
|
||||
totalParticipants: 45620,
|
||||
marketingRevenue: '128500.00'
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载营销统计失败:', error)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.marketing-management {
|
||||
padding: 30rpx;
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
// 页面头部
|
||||
.page-header {
|
||||
background-color: #fff;
|
||||
padding: 40rpx;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.page-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #212529;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
font-size: 26rpx;
|
||||
color: #6c757d;
|
||||
}
|
||||
}
|
||||
|
||||
// 营销工具网格
|
||||
.marketing-tools {
|
||||
background-color: #fff;
|
||||
padding: 30rpx;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.tool-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.tool-item {
|
||||
width: calc(50% - 10rpx);
|
||||
background-color: #f8f9fa;
|
||||
padding: 30rpx 20rpx;
|
||||
border-radius: 12rpx;
|
||||
text-align: center;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
background-color: #e3f2fd;
|
||||
transform: translateY(-2rpx);
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.tool-icon {
|
||||
font-size: 48rpx;
|
||||
margin-bottom: 15rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tool-name {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #212529;
|
||||
margin-bottom: 8rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tool-desc {
|
||||
font-size: 22rpx;
|
||||
color: #6c757d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 营销数据统计
|
||||
.marketing-stats {
|
||||
background-color: #fff;
|
||||
padding: 30rpx;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #212529;
|
||||
margin-bottom: 30rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
flex: 1;
|
||||
min-width: 200rpx;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
padding: 30rpx 20rpx;
|
||||
border-radius: 12rpx;
|
||||
text-align: center;
|
||||
color: white;
|
||||
|
||||
.stat-value {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 24rpx;
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 快捷操作
|
||||
.quick-actions {
|
||||
background-color: #fff;
|
||||
padding: 30rpx;
|
||||
border-radius: 16rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #212529;
|
||||
margin-bottom: 30rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
flex: 1;
|
||||
min-width: 200rpx;
|
||||
padding: 20rpx;
|
||||
border-radius: 12rpx;
|
||||
font-size: 26rpx;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
|
||||
&.primary {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
|
||||
&:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
}
|
||||
|
||||
&.secondary {
|
||||
background-color: #6c757d;
|
||||
color: white;
|
||||
|
||||
&:hover {
|
||||
background-color: #545b62;
|
||||
}
|
||||
}
|
||||
|
||||
&.info {
|
||||
background-color: #17a2b8;
|
||||
color: white;
|
||||
|
||||
&:hover {
|
||||
background-color: #138496;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式设计
|
||||
@media (max-width: 750rpx) {
|
||||
.tool-grid {
|
||||
flex-direction: column;
|
||||
|
||||
.tool-item {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
flex-direction: column;
|
||||
|
||||
.action-btn {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
13
pages/mall/admin/merchant-management.uvue
Normal file
13
pages/mall/admin/merchant-management.uvue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<text>商家管理 - 占位页</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="uts">
|
||||
export default {}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.page { padding: 30rpx; }
|
||||
</style>
|
||||
64
pages/mall/admin/merchant-review.uvue
Normal file
64
pages/mall/admin/merchant-review.uvue
Normal file
@@ -0,0 +1,64 @@
|
||||
<!-- 商家审核页面 -->
|
||||
<template>
|
||||
<view class="merchant-review">
|
||||
<view class="page-header">
|
||||
<text class="page-title">商家入驻审核</text>
|
||||
<text class="page-subtitle">审核商家入驻申请</text>
|
||||
</view>
|
||||
|
||||
<view class="review-content">
|
||||
<text class="coming-soon">商家审核功能正在开发中...</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
// 统一的导航方法
|
||||
const go = (url: string) => {
|
||||
// 1) 目标页面必须是非 tabBar 页面
|
||||
// 2) 必须在 pages.json / subPackages 注册
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.merchant-review {
|
||||
padding: 30rpx;
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
background-color: #fff;
|
||||
padding: 40rpx;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.page-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #212529;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
font-size: 26rpx;
|
||||
color: #6c757d;
|
||||
}
|
||||
}
|
||||
|
||||
.review-content {
|
||||
background-color: #fff;
|
||||
padding: 60rpx 40rpx;
|
||||
border-radius: 16rpx;
|
||||
text-align: center;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.coming-soon {
|
||||
font-size: 28rpx;
|
||||
color: #6c757d;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
11
pages/mall/admin/notifications.uvue
Normal file
11
pages/mall/admin/notifications.uvue
Normal file
@@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<text>通知中心 - 占位页</text>
|
||||
</view>
|
||||
</template>
|
||||
<script lang="uts">
|
||||
export default {}
|
||||
</script>
|
||||
<style>
|
||||
.page { padding: 30rpx; }
|
||||
</style>
|
||||
1380
pages/mall/admin/order-management.uvue
Normal file
1380
pages/mall/admin/order-management.uvue
Normal file
File diff suppressed because it is too large
Load Diff
1154
pages/mall/admin/product-management.uvue
Normal file
1154
pages/mall/admin/product-management.uvue
Normal file
File diff suppressed because it is too large
Load Diff
64
pages/mall/admin/product-review.uvue
Normal file
64
pages/mall/admin/product-review.uvue
Normal file
@@ -0,0 +1,64 @@
|
||||
<!-- 商品审核页面 -->
|
||||
<template>
|
||||
<view class="product-review">
|
||||
<view class="page-header">
|
||||
<text class="page-title">商品审核</text>
|
||||
<text class="page-subtitle">审核商品上架申请</text>
|
||||
</view>
|
||||
|
||||
<view class="review-content">
|
||||
<text class="coming-soon">商品审核功能正在开发中...</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
// 统一的导航方法
|
||||
const go = (url: string) => {
|
||||
// 1) 目标页面必须是非 tabBar 页面
|
||||
// 2) 必须在 pages.json / subPackages 注册
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.product-review {
|
||||
padding: 30rpx;
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
background-color: #fff;
|
||||
padding: 40rpx;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.page-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #212529;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
font-size: 26rpx;
|
||||
color: #6c757d;
|
||||
}
|
||||
}
|
||||
|
||||
.review-content {
|
||||
background-color: #fff;
|
||||
padding: 60rpx 40rpx;
|
||||
border-radius: 16rpx;
|
||||
text-align: center;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.coming-soon {
|
||||
font-size: 28rpx;
|
||||
color: #6c757d;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
64
pages/mall/admin/refund-review.uvue
Normal file
64
pages/mall/admin/refund-review.uvue
Normal file
@@ -0,0 +1,64 @@
|
||||
<!-- 退款审核页面 -->
|
||||
<template>
|
||||
<view class="refund-review">
|
||||
<view class="page-header">
|
||||
<text class="page-title">退款审核</text>
|
||||
<text class="page-subtitle">审核用户退款申请</text>
|
||||
</view>
|
||||
|
||||
<view class="review-content">
|
||||
<text class="coming-soon">退款审核功能正在开发中...</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
// 统一的导航方法
|
||||
const go = (url: string) => {
|
||||
// 1) 目标页面必须是非 tabBar 页面
|
||||
// 2) 必须在 pages.json / subPackages 注册
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.refund-review {
|
||||
padding: 30rpx;
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
background-color: #fff;
|
||||
padding: 40rpx;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.page-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #212529;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
font-size: 26rpx;
|
||||
color: #6c757d;
|
||||
}
|
||||
}
|
||||
|
||||
.review-content {
|
||||
background-color: #fff;
|
||||
padding: 60rpx 40rpx;
|
||||
border-radius: 16rpx;
|
||||
text-align: center;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.coming-soon {
|
||||
font-size: 28rpx;
|
||||
color: #6c757d;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
528
pages/mall/admin/system-settings.uvue
Normal file
528
pages/mall/admin/system-settings.uvue
Normal file
@@ -0,0 +1,528 @@
|
||||
<!-- 系统设置页面 - 基于CRMEB设计 -->
|
||||
<template>
|
||||
<view class="system-settings">
|
||||
<!-- 设置选项卡 -->
|
||||
<view class="settings-tabs">
|
||||
<view class="tab-list">
|
||||
<view
|
||||
v-for="tab in settingTabs"
|
||||
:key="tab.key"
|
||||
class="tab-item"
|
||||
:class="{ active: activeTab === tab.key }"
|
||||
@click="switchTab(tab.key)"
|
||||
>
|
||||
<text class="tab-text">{{ tab.label }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 基础设置 -->
|
||||
<view v-if="activeTab === 'basic'" class="setting-section">
|
||||
<view class="section-title">基础设置</view>
|
||||
<view class="setting-form">
|
||||
<view class="form-item">
|
||||
<text class="label">网站名称:</text>
|
||||
<input v-model="settings.site_name" placeholder="请输入网站名称" class="input-field" />
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label">网站域名:</text>
|
||||
<input v-model="settings.site_domain" placeholder="请输入网站域名" class="input-field" />
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label">网站Logo:</text>
|
||||
<view class="upload-area">
|
||||
<image v-if="settings.site_logo" :src="settings.site_logo" class="logo-preview" />
|
||||
<button class="upload-btn" @click="chooseLogo">选择图片</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label">客服电话:</text>
|
||||
<input v-model="settings.service_phone" placeholder="请输入客服电话" class="input-field" />
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label">网站描述:</text>
|
||||
<textarea v-model="settings.site_description" placeholder="请输入网站描述" class="textarea-field" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付设置 -->
|
||||
<view v-if="activeTab === 'payment'" class="setting-section">
|
||||
<view class="section-title">支付设置</view>
|
||||
<view class="setting-form">
|
||||
<view class="form-item">
|
||||
<text class="label">微信支付:</text>
|
||||
<view class="switch-item">
|
||||
<switch :checked="settings.wechat_pay_enabled" @change="onWechatPayChange" />
|
||||
<text class="switch-label">{{ settings.wechat_pay_enabled ? '已开启' : '已关闭' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="settings.wechat_pay_enabled" class="form-item">
|
||||
<text class="label">微信商户号:</text>
|
||||
<input v-model="settings.wechat_mch_id" placeholder="请输入微信商户号" class="input-field" />
|
||||
</view>
|
||||
<view v-if="settings.wechat_pay_enabled" class="form-item">
|
||||
<text class="label">微信支付密钥:</text>
|
||||
<input v-model="settings.wechat_pay_key" type="password" placeholder="请输入微信支付密钥" class="input-field" />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label">支付宝支付:</text>
|
||||
<view class="switch-item">
|
||||
<switch :checked="settings.alipay_enabled" @change="onAlipayChange" />
|
||||
<text class="switch-label">{{ settings.alipay_enabled ? '已开启' : '已关闭' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="settings.alipay_enabled" class="form-item">
|
||||
<text class="label">支付宝应用ID:</text>
|
||||
<input v-model="settings.alipay_app_id" placeholder="请输入支付宝应用ID" class="input-field" />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label">余额支付:</text>
|
||||
<view class="switch-item">
|
||||
<switch :checked="settings.balance_pay_enabled" @change="onBalancePayChange" />
|
||||
<text class="switch-label">{{ settings.balance_pay_enabled ? '已开启' : '已关闭' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 物流设置 -->
|
||||
<view v-if="activeTab === 'shipping'" class="setting-section">
|
||||
<view class="section-title">物流设置</view>
|
||||
<view class="setting-form">
|
||||
<view class="form-item">
|
||||
<text class="label">默认物流公司:</text>
|
||||
<picker mode="selector" :range="expressCompanies" range-key="name" @change="onDefaultExpressChange">
|
||||
<view class="picker-text">{{ selectedExpress || '选择物流公司' }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label">运费计算方式:</text>
|
||||
<picker mode="selector" :range="shippingMethods" range-key="label" @change="onShippingMethodChange">
|
||||
<view class="picker-text">{{ selectedShippingMethod || '选择计算方式' }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label">包邮金额:</text>
|
||||
<input v-model="settings.free_shipping_amount" type="number" placeholder="请输入包邮金额" class="input-field" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 消息设置 -->
|
||||
<view v-if="activeTab === 'notification'" class="setting-section">
|
||||
<view class="section-title">消息设置</view>
|
||||
<view class="setting-form">
|
||||
<view class="form-item">
|
||||
<text class="label">短信通知:</text>
|
||||
<view class="switch-item">
|
||||
<switch :checked="settings.sms_enabled" @change="onSmsChange" />
|
||||
<text class="switch-label">{{ settings.sms_enabled ? '已开启' : '已关闭' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="settings.sms_enabled" class="form-item">
|
||||
<text class="label">短信服务商:</text>
|
||||
<picker mode="selector" :range="smsProviders" range-key="label" @change="onSmsProviderChange">
|
||||
<view class="picker-text">{{ selectedSmsProvider || '选择服务商' }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label">邮件通知:</text>
|
||||
<view class="switch-item">
|
||||
<switch :checked="settings.email_enabled" @change="onEmailChange" />
|
||||
<text class="switch-label">{{ settings.email_enabled ? '已开启' : '已关闭' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="settings.email_enabled" class="form-item">
|
||||
<text class="label">SMTP服务器:</text>
|
||||
<input v-model="settings.smtp_host" placeholder="请输入SMTP服务器" class="input-field" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 保存按钮 -->
|
||||
<view class="save-section">
|
||||
<button class="btn btn-primary" @click="saveSettings">保存设置</button>
|
||||
<button class="btn btn-default" @click="resetSettings">重置</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import supa from '@/components/supadb/aksupainstance.uts'
|
||||
|
||||
// 响应式数据
|
||||
const activeTab = ref('basic')
|
||||
|
||||
const settingTabs = ref([
|
||||
{ key: 'basic', label: '基础设置' },
|
||||
{ key: 'payment', label: '支付设置' },
|
||||
{ key: 'shipping', label: '物流设置' },
|
||||
{ key: 'notification', label: '消息设置' }
|
||||
])
|
||||
|
||||
const settings = ref({
|
||||
// 基础设置
|
||||
site_name: '',
|
||||
site_domain: '',
|
||||
site_logo: '',
|
||||
service_phone: '',
|
||||
site_description: '',
|
||||
|
||||
// 支付设置
|
||||
wechat_pay_enabled: false,
|
||||
wechat_mch_id: '',
|
||||
wechat_pay_key: '',
|
||||
alipay_enabled: false,
|
||||
alipay_app_id: '',
|
||||
balance_pay_enabled: true,
|
||||
|
||||
// 物流设置
|
||||
default_express: '',
|
||||
shipping_method: '',
|
||||
free_shipping_amount: '',
|
||||
|
||||
// 消息设置
|
||||
sms_enabled: false,
|
||||
sms_provider: '',
|
||||
email_enabled: false,
|
||||
smtp_host: ''
|
||||
})
|
||||
|
||||
// 选项数据
|
||||
const expressCompanies = ref([])
|
||||
const shippingMethods = ref([
|
||||
{ value: 'fixed', label: '固定运费' },
|
||||
{ value: 'weight', label: '按重量计算' },
|
||||
{ value: 'pieces', label: '按件数计算' }
|
||||
])
|
||||
const smsProviders = ref([
|
||||
{ value: 'aliyun', label: '阿里云短信' },
|
||||
{ value: 'tencent', label: '腾讯云短信' },
|
||||
{ value: 'qiniu', label: '七牛云短信' }
|
||||
])
|
||||
|
||||
const selectedExpress = ref('')
|
||||
const selectedShippingMethod = ref('')
|
||||
const selectedSmsProvider = ref('')
|
||||
|
||||
// 方法
|
||||
const switchTab = (tabKey: string) => {
|
||||
activeTab.value = tabKey
|
||||
}
|
||||
|
||||
const onWechatPayChange = (e: any) => {
|
||||
settings.value.wechat_pay_enabled = e.detail.value
|
||||
}
|
||||
|
||||
const onAlipayChange = (e: any) => {
|
||||
settings.value.alipay_enabled = e.detail.value
|
||||
}
|
||||
|
||||
const onBalancePayChange = (e: any) => {
|
||||
settings.value.balance_pay_enabled = e.detail.value
|
||||
}
|
||||
|
||||
const onSmsChange = (e: any) => {
|
||||
settings.value.sms_enabled = e.detail.value
|
||||
}
|
||||
|
||||
const onEmailChange = (e: any) => {
|
||||
settings.value.email_enabled = e.detail.value
|
||||
}
|
||||
|
||||
const onDefaultExpressChange = (e: any) => {
|
||||
selectedExpress.value = expressCompanies.value[e.detail.value].name
|
||||
settings.value.default_express = expressCompanies.value[e.detail.value].code
|
||||
}
|
||||
|
||||
const onShippingMethodChange = (e: any) => {
|
||||
selectedShippingMethod.value = shippingMethods.value[e.detail.value].label
|
||||
settings.value.shipping_method = shippingMethods.value[e.detail.value].value
|
||||
}
|
||||
|
||||
const onSmsProviderChange = (e: any) => {
|
||||
selectedSmsProvider.value = smsProviders.value[e.detail.value].label
|
||||
settings.value.sms_provider = smsProviders.value[e.detail.value].value
|
||||
}
|
||||
|
||||
const chooseLogo = () => {
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
sizeType: ['compressed'],
|
||||
sourceType: ['album', 'camera'],
|
||||
success: (res) => {
|
||||
const tempFilePath = res.tempFilePaths[0]
|
||||
// 这里应该上传图片到服务器
|
||||
settings.value.site_logo = tempFilePath // 临时显示
|
||||
uni.showToast({
|
||||
title: '图片选择成功',
|
||||
icon: 'success'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const saveSettings = async () => {
|
||||
try {
|
||||
await supa.from('system_settings').upsert(settings.value)
|
||||
uni.showToast({
|
||||
title: '保存成功',
|
||||
icon: 'success'
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('保存设置失败:', error)
|
||||
uni.showToast({
|
||||
title: '保存失败',
|
||||
icon: 'error'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const resetSettings = () => {
|
||||
loadSettings()
|
||||
}
|
||||
|
||||
// 数据加载方法
|
||||
const loadSettings = async () => {
|
||||
try {
|
||||
const { data } = await supa.from('system_settings').select('*').single()
|
||||
if (data) {
|
||||
settings.value = { ...settings.value, ...data }
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载设置失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const loadExpressCompanies = async () => {
|
||||
try {
|
||||
const { data } = await supa.from('express_companies').select('*')
|
||||
expressCompanies.value = data || []
|
||||
} catch (error) {
|
||||
console.error('加载物流公司失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 页面初始化
|
||||
onMounted(async () => {
|
||||
await Promise.all([
|
||||
loadSettings(),
|
||||
loadExpressCompanies()
|
||||
])
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.system-settings {
|
||||
padding: 30rpx;
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
// 设置选项卡样式
|
||||
.settings-tabs {
|
||||
background-color: #fff;
|
||||
border-radius: 12rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.tab-list {
|
||||
display: flex;
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
.tab-item {
|
||||
flex: 1;
|
||||
padding: 30rpx 20rpx;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
|
||||
&.active {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.tab-text {
|
||||
font-size: 28rpx;
|
||||
color: #495057;
|
||||
}
|
||||
|
||||
&.active .tab-text {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 设置表单样式
|
||||
.setting-section {
|
||||
background-color: #fff;
|
||||
border-radius: 12rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #212529;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.setting-form {
|
||||
.form-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-right: 20rpx;
|
||||
white-space: nowrap;
|
||||
min-width: 150rpx;
|
||||
}
|
||||
|
||||
.input-field {
|
||||
flex: 1;
|
||||
height: 60rpx;
|
||||
border: 1rpx solid #ddd;
|
||||
border-radius: 6rpx;
|
||||
padding: 0 20rpx;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.textarea-field {
|
||||
flex: 1;
|
||||
min-height: 120rpx;
|
||||
border: 1rpx solid #ddd;
|
||||
border-radius: 6rpx;
|
||||
padding: 20rpx;
|
||||
font-size: 26rpx;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.switch-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
|
||||
.switch-label {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
.picker-text {
|
||||
padding: 0 20rpx;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
border: 1rpx solid #ddd;
|
||||
border-radius: 6rpx;
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
min-width: 200rpx;
|
||||
}
|
||||
|
||||
.upload-area {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
|
||||
.logo-preview {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 8rpx;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.upload-btn {
|
||||
padding: 12rpx 24rpx;
|
||||
border: 1rpx solid #ddd;
|
||||
border-radius: 6rpx;
|
||||
background-color: #f5f5f5;
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 保存按钮区域
|
||||
.save-section {
|
||||
background-color: #fff;
|
||||
border-radius: 12rpx;
|
||||
padding: 30rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
justify-content: center;
|
||||
|
||||
.btn {
|
||||
padding: 15rpx 40rpx;
|
||||
border-radius: 8rpx;
|
||||
font-size: 28rpx;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
|
||||
&.btn-primary {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.btn-default {
|
||||
background-color: #f5f5f5;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式设计
|
||||
@media (max-width: 750rpx) {
|
||||
.settings-tabs {
|
||||
.tab-list {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.tab-item {
|
||||
padding: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.form-item {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
|
||||
.label {
|
||||
margin-bottom: 10rpx;
|
||||
min-width: auto;
|
||||
}
|
||||
|
||||
.input-field,
|
||||
.textarea-field,
|
||||
.picker-text {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.switch-item {
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
.save-section {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
|
||||
.btn {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
1117
pages/mall/admin/user-management.uvue
Normal file
1117
pages/mall/admin/user-management.uvue
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user