完成代码路径重构

This commit is contained in:
2026-03-18 08:36:49 +08:00
parent 4041933e42
commit c2cd6dcd95
290 changed files with 866 additions and 38459 deletions

View File

@@ -0,0 +1,383 @@
<template>
<view class="marketing-recharge-quota">
<view class="content-layout">
<!-- 左侧预览 -->
<view class="preview-side">
<view class="phone-mock">
<view class="phone-header">
<text class="balance-label">我的余额</text>
<view class="balance-val">
<text class="symbol">¥</text>
<text class="num">0.00</text>
</view>
</view>
<view class="recharge-tabs">
<view class="tab active"><text class="tab-txt">账户充值</text></view>
<view class="tab"><text class="tab-txt">佣金导入</text></view>
</view>
<view class="quota-grid">
<view v-for="(item, index) in list" :key="index" class="quota-item" :class="{ active: index === 0 }">
<text class="price">{{ item.price }}元</text>
<text class="bonus">赠送{{ item.bonus }}元</text>
</view>
<view class="quota-item other">
<text class="other-txt">其他</text>
</view>
</view>
<view class="notice-section">
<text class="notice-title">注意事项:</text>
<text class="notice-content">充值后账户的金额不能提现可用于商城消费使用。佣金导入账户之后不能再次导出、不可提现。账户充值出现问题可联系商城客服也可拨打商城客服热线4008888888。</text>
</view>
<button class="recharge-btn">立即充值</button>
</view>
</view>
<!-- 右侧设置 -->
<view class="table-side border-shadow">
<view class="side-header">
<text class="side-title">充值金额设置</text>
</view>
<view class="action-row">
<button class="btn-primary" @click="showAddModal = true">添加数据</button>
</view>
<view class="table-container">
<view class="table-head">
<view class="th cell-id">编号</view>
<view class="th cell-price">售价</view>
<view class="th cell-bonus">赠送</view>
<view class="th cell-status">是否可用</view>
<view class="th cell-sort">排序</view>
<view class="th cell-op">操作</view>
</view>
<view class="table-body">
<view v-for="item in list" :key="item.id" class="table-row">
<view class="td cell-id"><text class="td-txt">{{ item.id }}</text></view>
<view class="td cell-price"><text class="td-txt">{{ item.price }}</text></view>
<view class="td cell-bonus"><text class="td-txt">{{ item.bonus }}</text></view>
<view class="td cell-status">
<view class="switch-mock" :class="{ active: item.is_open }" @click="toggleStatus(item)">
<view class="switch-dot"></view>
</view>
</view>
<view class="td cell-sort"><text class="td-txt">{{ item.sort }}</text></view>
<view class="td cell-op">
<text class="op-link" @click="handleEdit(item)">编辑</text>
<text class="op-link del ml-10" @click="handleDelete(item)">删除</text>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 添加数据弹窗 -->
<view v-if="showAddModal" class="modal-mask">
<view class="modal-content">
<view class="modal-header">
<text class="modal-title">添加数据</text>
<text class="modal-close" @click="showAddModal = false">×</text>
</view>
<view class="modal-body">
<view class="form-item">
<text class="form-label">售价:</text>
<input class="form-input" v-model="formData.price" type="number" placeholder="请输入售价" />
</view>
<view class="form-item">
<text class="form-label">赠送:</text>
<input class="form-input" v-model="formData.bonus" type="number" placeholder="请输入赠送" />
</view>
<view class="form-item">
<text class="form-label">排序:</text>
<input class="form-input" v-model="formData.sort" type="number" />
</view>
<view class="form-item">
<text class="form-label">状态:</text>
<view class="radio-group">
<view class="radio-item" @click="formData.is_open = true">
<view class="radio-circle" :class="{ checked: formData.is_open }"></view>
<text class="radio-txt">显示</text>
</view>
<view class="radio-item ml-20" @click="formData.is_open = false">
<view class="radio-circle" :class="{ checked: !formData.is_open }"></view>
<text class="radio-txt">隐藏</text>
</view>
</view>
</view>
</view>
<view class="modal-footer">
<button class="btn-cancel" @click="showAddModal = false">取消</button>
<button class="btn-submit" @click="handleSubmit">确定</button>
</view>
</view>
</view>
</view>
</template>
<script setup lang="uts">
import { ref, reactive } from 'vue'
const showAddModal = ref(false)
const formData = reactive({
price: '',
bonus: '',
sort: 1,
is_open: true
})
const list = ref([
{ id: 640, price: 10, bonus: 2, is_open: true, sort: 6 },
{ id: 641, price: 20, bonus: 8, is_open: true, sort: 5 },
{ id: 642, price: 50, bonus: 20, is_open: true, sort: 4 },
{ id: 643, price: 100, bonus: 50, is_open: true, sort: 3 },
{ id: 644, price: 200, bonus: 110, is_open: true, sort: 2 },
{ id: 645, price: 300, bonus: 200, is_open: true, sort: 1 }
])
const toggleStatus = (item: any) => {
item.is_open = !item.is_open
uni.showToast({ title: '操作成功', icon: 'success' })
}
const handleEdit = (item: any) => {
uni.showToast({ title: '编辑功能', icon: 'none' })
}
const handleDelete = (item: any) => {
uni.showModal({
title: '提示',
content: '确认删除该项吗?',
success: (res) => {
if (res.confirm) {
const index = list.value.findIndex(i => i.id === item.id)
if (index > -1) {
list.value.splice(index, 1)
uni.showToast({ title: '已删除', icon: 'success' })
}
}
}
})
}
const handleSubmit = () => {
if (!formData.price) {
uni.showToast({ title: '请输入售价', icon: 'none' })
return
}
const newItem = {
id: Math.floor(Math.random() * 1000) + 700,
price: parseFloat(formData.price),
bonus: parseFloat(formData.bonus || '0'),
sort: parseInt(formData.sort.toString()),
is_open: formData.is_open
}
list.value.push(newItem)
// 重置表单
formData.price = ''
formData.bonus = ''
formData.sort = 1
formData.is_open = true
showAddModal.value = false
uni.showToast({ title: '添加成功', icon: 'success' })
}
</script>
<style scoped lang="scss">
.marketing-recharge-quota {
padding: 0;
background: transparent;
min-height: auto;
}
.content-layout {
display: flex;
flex-direction: row;
}
/* 左侧预览 */
.preview-side {
width: 320px;
margin-right: 24px;
}
.phone-mock {
background: #fff;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 4px 16px rgba(0,0,0,0.1);
padding-bottom: 24px;
}
.phone-header {
height: 120px;
background: #e74c3c;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #fff;
}
.balance-label { font-size: 13px; opacity: 0.9; margin-bottom: 8px; }
.balance-val { display: flex; flex-direction: row; align-items: baseline; }
.symbol { font-size: 18px; margin-right: 4px; }
.num { font-size: 32px; font-weight: bold; }
.recharge-tabs {
display: flex;
flex-direction: row;
height: 44px;
border-bottom: 1px solid #f5f5f5;
}
.tab { flex: 1; display: flex; align-items: center; justify-content: center; position: relative; }
.tab.active::after { content: ''; position: absolute; bottom: 0; width: 40px; height: 2px; background: #e74c3c; }
.tab-txt { font-size: 14px; color: #666; font-weight: bold; }
.tab.active .tab-txt { color: #333; }
.quota-grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
padding: 16px;
justify-content: space-between;
}
.quota-item {
width: 90px;
height: 60px;
border: 1px solid #f0f0f0;
border-radius: 4px;
margin-bottom: 12px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: #f8f8f8;
}
.quota-item.active {
border-color: #e74c3c;
background: #fff;
position: relative;
}
.quota-item.active::after {
content: '';
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
border: 1px solid #e74c3c;
border-radius: 4px;
}
.price { font-size: 14px; color: #333; font-weight: bold; margin-bottom: 4px; }
.bonus { font-size: 11px; color: #999; }
.quota-item.active .price { color: #e74c3c; }
.quota-item.active .bonus { color: #e74c3c; opacity: 0.8; }
.other { background: #f0f0f0; border: none; }
.other-txt { font-size: 14px; color: #666; }
.notice-section {
padding: 0 16px;
margin-top: 10px;
}
.notice-title { font-size: 13px; color: #333; font-weight: bold; margin-bottom: 8px; display: block; }
.notice-content { font-size: 12px; color: #999; line-height: 1.6; }
.recharge-btn {
margin: 24px 16px 0;
height: 40px;
line-height: 40px;
background: #e74c3c;
color: #fff;
border-radius: 20px;
font-size: 15px;
border: none;
}
/* 右侧设置 */
.table-side {
flex: 1;
background: #fff;
padding: 24px;
}
.border-shadow { border-radius: 4px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05); }
.side-header { border-left: 4px solid #1890ff; padding-left: 12px; margin-bottom: 24px; }
.side-title { font-size: 16px; font-weight: bold; color: #333; }
.action-row { margin-bottom: 16px; }
.btn-primary {
background: #1890ff; color: #fff; border: none;
height: 32px; line-height: 32px; padding: 0 16px; font-size: 14px; border-radius: 4px; cursor: pointer;
}
.table-head { display: flex; flex-direction: row; background: #f8f8f9; border-bottom: 1px solid #e8eaec; }
.th { padding: 12px 8px; font-size: 13px; color: #515a6e; font-weight: bold; }
.table-row { display: flex; flex-direction: row; border-bottom: 1px solid #e8eaec; align-items: center; }
.td { padding: 16px 8px; }
.td-txt { font-size: 13px; color: #515a6e; }
.cell-id { width: 80px; }
.cell-price { width: 120px; }
.cell-bonus { width: 120px; }
.cell-status { width: 100px; text-align: center; }
.cell-sort { width: 100px; text-align: center; }
.cell-op { flex: 1; text-align: right; }
.op-link { color: #1890ff; font-size: 13px; cursor: pointer; }
.op-link.del { color: #ff4d4f; }
.ml-10 { margin-left: 10px; }
.switch-mock {
width: 44px; height: 22px; background-color: #bfbfbf; border-radius: 11px;
display: flex; align-items: center; padding: 0 4px; position: relative;
transition: background-color 0.3s; cursor: pointer;
}
.switch-mock.active { background-color: #1890ff; }
.switch-dot {
width: 14px; height: 14px; background-color: #fff; border-radius: 50%;
position: absolute; left: 4px; transition: left 0.3s;
}
.switch-mock.active .switch-dot { left: 26px; }
/* Modal */
.modal-mask {
position: fixed; top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; z-index: 1000;
}
.modal-content { width: 500px; background: #fff; border-radius: 4px; }
.modal-header { padding: 16px 24px; border-bottom: 1px solid #e8eaec; display: flex; justify-content: space-between; align-items: center; }
.modal-title { font-size: 16px; font-weight: bold; }
.modal-close { font-size: 24px; color: #999; cursor: pointer; }
.modal-body { padding: 24px; }
.modal-footer { padding: 12px 24px; border-top: 1px solid #e8eaec; display: flex; justify-content: flex-end; }
.form-item { display: flex; flex-direction: row; margin-bottom: 20px; align-items: center; }
.form-label { width: 80px; font-size: 14px; color: #606266; }
.form-input { flex: 1; height: 32px; border: 1px solid #dcdfe6; border-radius: 4px; padding: 0 12px; }
.radio-group { display: flex; flex-direction: row; flex: 1; }
.radio-item { display: flex; flex-direction: row; align-items: center; cursor: pointer; }
.radio-circle { width: 14px; height: 14px; border: 1px solid #dcdfe6; border-radius: 50%; margin-right: 6px; position: relative; }
.radio-circle.checked { border-color: #1890ff; }
.radio-circle.checked::after { content: ''; position: absolute; width: 8px; height: 8px; background: #1890ff; border-radius: 50%; top: 2px; left: 2px; }
.radio-txt { font-size: 14px; color: #606266; }
.ml-20 { margin-left: 20px; }
.btn-cancel { margin-right: 8px; height: 32px; line-height: 32px; padding: 0 16px; font-size: 14px; border-radius: 4px; border: 1px solid #dcdfe6; background: #fff; }
.btn-submit { height: 32px; line-height: 32px; padding: 0 16px; font-size: 14px; border-radius: 4px; background: #1890ff; color: #fff; border: none; }
</style>