384 lines
13 KiB
Plaintext
384 lines
13 KiB
Plaintext
<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>
|
||
|
||
|
||
|