页面初始化

This commit is contained in:
qsh
2026-01-29 18:29:34 +08:00
parent db42252b6c
commit 35f5621d7e
30 changed files with 13297 additions and 813 deletions

View File

@@ -1,224 +1,314 @@
<template>
<view class="add-container">
<!-- 头部 -->
<view class="header">
<uni-icons type="back" size="28" color="#303133" @click="handleCancel" />
<text class="title">新增分销员</text>
<view class="header-right"></view>
<view class="distributor-add-container">
<!-- 页面标题 -->
<view class="page-header">
<view class="header-left" @click="goBack">
<view class="back-icon"></view>
</view>
<view class="header-title">添加分销员</view>
<view class="header-right" @click="saveDistributor">
<view class="save-btn">保存</view>
</view>
</view>
<!-- 表单容 -->
<view class="form-container">
<uni-forms :model="formData" ref="formRef" labelWidth="100rpx">
<uni-forms-item label="姓名" required name="name">
<uni-easyinput
v-model="formData.name"
placeholder="请输入姓名"
class="form-input"
:focus="true"
/>
</uni-forms-item>
<uni-forms-item label="手机号" required name="phone">
<uni-easyinput
v-model="formData.phone"
placeholder="请输入手机号"
class="form-input"
/>
</uni-forms-item>
<uni-forms-item label="OpenID" required name="openid">
<uni-easyinput
v-model="formData.openid"
placeholder="请输入OpenID"
class="form-input"
/>
</uni-forms-item>
<uni-forms-item label="父ID" required name="parent_id">
<uni-easyinput
v-model="formData.parent_id"
placeholder="请输入父ID"
type="number"
class="form-input"
/>
</uni-forms-item>
<uni-forms-item label="租户ID" required name="tenant_id">
<uni-easyinput
v-model="formData.tenant_id"
placeholder="请输入租户ID"
type="number"
class="form-input"
/>
</uni-forms-item>
<uni-forms-item label="苹果URL" name="applet_url">
<uni-easyinput
v-model="formData.applet_url"
placeholder="请输入苹果URL"
class="form-input"
/>
</uni-forms-item>
<uni-forms-item label="状态" name="is_active">
<uni-data-checkbox
v-model="formData.is_active"
:localdata="statusOptions"
style="width: 100%"
/>
</uni-forms-item>
</uni-forms>
</view>
<!-- 按钮容器 -->
<view class="btn-container">
<button class="cancel-btn" @click="handleCancel">
<uni-icons type="close" size="20" color="#fff" />
<text class="btn-text">取消</text>
</button>
<button class="submit-btn" @click="handleSubmit">
<uni-icons type="checkmark" size="20" color="#fff" />
<text class="btn-text">提交</text>
</button>
<!-- 表单 -->
<view class="form-section">
<view class="section-title">基本信息</view>
<view class="form-card">
<view class="form-row">
<view class="form-label">姓名</view>
<view class="form-control">
<input
v-model="distributorForm.name"
class="form-input"
placeholder="请输入姓名"
/>
</view>
</view>
<view class="form-row">
<view class="form-label">手机号</view>
<view class="form-control">
<input
v-model="distributorForm.phone"
type="number"
class="form-input"
placeholder="请输入手机号"
maxlength="11"
/>
</view>
</view>
<view class="form-row">
<view class="form-label">角色</view>
<view class="form-control">
<picker
:range="roleOptions"
:value="roleIndex"
@change="onRoleChange"
class="picker"
>
<view class="picker-text">{{ roleOptions[roleIndex] }}</view>
</picker>
</view>
</view>
<view class="form-row">
<view class="form-label">状态</view>
<view class="form-control">
<picker
:range="statusOptions"
:value="statusIndex"
@change="onStatusChange"
class="picker"
>
<view class="picker-text">{{ statusOptions[statusIndex] }}</view>
</picker>
</view>
</view>
<view class="form-row">
<view class="form-label">备注</view>
<view class="form-control">
<textarea
v-model="distributorForm.remark"
class="form-textarea"
placeholder="请输入备注信息"
maxlength="200"
></textarea>
<view class="textarea-count">{{ distributorForm.remark.length }}/200</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from "vue"
import { ref, onMounted } from "vue"
const formRef = ref(null)
const formData = ref({
// 分销员表单数据
const distributorForm = ref({
name: '',
phone: '',
openid: '',
parent_id: '',
tenant_id: '',
applet_url: '',
is_active: 'Y'
role: '初级分销员',
status: '启用',
remark: ''
})
const statusOptions = [
{ text: '激活', value: 'Y' },
{ text: '未激活', value: 'N' }
]
// 取消
function handleCancel() {
uni.navigateBack()
// 角色选项
const roleOptions = ['初级分销员', '中级分销员', '高级分销员']
const roleIndex = ref(0)
// 状态选项
const statusOptions = ['启用', '禁用']
const statusIndex = ref(0)
onMounted(() => {
// 初始化表单数据
})
// 返回上一页
function goBack() {
uni.navigateBack({ delta: 1 })
}
// 提交
function handleSubmit() {
formRef.value.validate().then(() => {
// 这里应该调用后端API提交数据
uni.showToast({ title: '新增成功' })
uni.navigateTo({ url: '/pages/distributor/index' })
}).catch(err => {
console.log('表单验证失败', err)
})
// 保存分销员
function saveDistributor() {
if (!distributorForm.value.name) {
uni.showToast({
title: '请输入姓名',
icon: 'none'
})
return
}
if (!distributorForm.value.phone || distributorForm.value.phone.length !== 11) {
uni.showToast({
title: '请输入有效的手机号',
icon: 'none'
})
return
}
uni.showLoading({ title: '保存中...' })
setTimeout(() => {
uni.hideLoading()
uni.showToast({
title: '添加成功',
icon: 'success'
})
// 实际项目中应调用接口保存分销员
// saveDistributorData()
// 保存成功后返回上一页
setTimeout(() => {
goBack()
}, 1000)
}, 1500)
}
// 角色变更
function onRoleChange(e) {
const value = e.detail.value
roleIndex.value = value
distributorForm.value.role = roleOptions[value]
}
// 状态变更
function onStatusChange(e) {
const value = e.detail.value
statusIndex.value = value
distributorForm.value.status = statusOptions[value]
}
</script>
<style lang="scss" scoped>
.add-container {
padding: 20rpx;
/* #ifndef APP-NVUE */
page {
display: flex;
flex-direction: column;
box-sizing: border-box;
background-color: #f5f7fa;
min-height: 100vh;
min-height: 100%;
height: auto;
}
view {
font-size: 14px;
line-height: inherit;
}
/* #endif */
.distributor-add-container {
flex: 1;
display: flex;
flex-direction: column;
}
/* 头部样式 */
.header {
/* 页面头部 */
.page-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 24rpx;
padding-bottom: 16rpx;
border-bottom: 2rpx solid #ecf5ff;
height: 120rpx;
background-color: #fff;
padding: 0 32rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}
.title {
.header-left {
width: 60rpx;
}
.back-icon {
font-size: 40rpx;
color: #303133;
cursor: pointer;
}
.header-title {
font-size: 32rpx;
font-weight: 600;
font-weight: bold;
color: #303133;
}
.header-right {
width: 28px;
width: 60rpx;
text-align: right;
}
/* 表单容器样式 */
.form-container {
.save-btn {
font-size: 24rpx;
color: #409eff;
font-weight: 600;
cursor: pointer;
}
/* 表单内容 */
.form-section {
padding: 32rpx;
background-color: #fff;
margin: 0 16rpx 16rpx;
border-radius: 16rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
}
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #303133;
margin-bottom: 24rpx;
padding-left: 12rpx;
border-left: 8rpx solid #409eff;
line-height: 1.2;
}
.form-card {
background-color: #f9f9f9;
border-radius: 12rpx;
padding: 24rpx;
}
.form-row {
display: flex;
flex-direction: column;
margin-bottom: 24rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
}
/* 表单输入框样式 */
.form-row:last-child {
margin-bottom: 0;
}
.form-label {
font-size: 24rpx;
color: #606266;
margin-bottom: 8rpx;
}
.form-control {
position: relative;
}
.form-input {
border-radius: 8rpx !important;
border: 1rpx solid #dcdfe6 !important;
transition: all 0.3s ease !important;
}
.form-input:focus {
border-color: #409eff !important;
box-shadow: 0 0 0 2rpx rgba(64, 158, 255, 0.2) !important;
}
/* 按钮容器样式 */
.btn-container {
display: flex;
gap: 16rpx;
margin-top: 32rpx;
}
.cancel-btn,
.submit-btn {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
border: none;
padding: 16rpx 0;
width: 100%;
background-color: #fff;
border: 1rpx solid #dcdfe6;
border-radius: 8rpx;
font-size: 28rpx;
transition: all 0.3s ease;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
padding: 16rpx;
font-size: 24rpx;
color: #303133;
}
.cancel-btn:active,
.submit-btn:active {
transform: translateY(2rpx);
box-shadow: 0 1rpx 4rpx rgba(0, 0, 0, 0.1);
.picker {
background-color: #fff;
border: 1rpx solid #dcdfe6;
border-radius: 8rpx;
padding: 16rpx;
display: flex;
justify-content: space-between;
align-items: center;
}
.cancel-btn {
background-color: #909399;
color: #fff;
.picker-text {
font-size: 24rpx;
color: #303133;
}
.submit-btn {
background-color: #409eff;
color: #fff;
.form-textarea {
width: 100%;
height: 160rpx;
background-color: #fff;
border: 1rpx solid #dcdfe6;
border-radius: 8rpx;
padding: 16rpx;
font-size: 24rpx;
color: #303133;
resize: none;
}
.btn-text {
margin-left: 8rpx;
}
/* 响应式设计 */
@media screen and (max-width: 750rpx) {
.form-container {
padding: 20rpx;
}
.btn-container {
margin-top: 24rpx;
}
.textarea-count {
position: absolute;
bottom: 8rpx;
right: 16rpx;
font-size: 18rpx;
color: #909399;
}
</style>

View File

@@ -1,85 +1,88 @@
<template>
<view class="edit-container">
<!-- 头部 -->
<view class="header">
<uni-icons type="back" size="28" color="#303133" @click="handleCancel" />
<text class="title">修改分销员</text>
<view class="header-right"></view>
<view class="distributor-edit-container">
<!-- 页面标题 -->
<view class="page-header">
<view class="header-left" @click="goBack">
<view class="back-icon"></view>
</view>
<view class="header-title">编辑分销员</view>
<view class="header-right" @click="saveDistributor">
<view class="save-btn">保存</view>
</view>
</view>
<!-- 表单容 -->
<view class="form-container">
<uni-forms :model="formData" ref="formRef" labelWidth="100rpx">
<uni-forms-item label="姓名" required name="name">
<uni-easyinput
v-model="formData.name"
placeholder="请输入姓名"
class="form-input"
/>
</uni-forms-item>
<uni-forms-item label="手机号" required name="phone">
<uni-easyinput
v-model="formData.phone"
placeholder="请输入手机号"
class="form-input"
/>
</uni-forms-item>
<uni-forms-item label="OpenID" required name="openid">
<uni-easyinput
v-model="formData.openid"
placeholder="请输入OpenID"
class="form-input"
/>
</uni-forms-item>
<uni-forms-item label="父ID" required name="parent_id">
<uni-easyinput
v-model="formData.parent_id"
placeholder="请输入父ID"
type="number"
class="form-input"
/>
</uni-forms-item>
<uni-forms-item label="租户ID" required name="tenant_id">
<uni-easyinput
v-model="formData.tenant_id"
placeholder="请输入租户ID"
type="number"
class="form-input"
/>
</uni-forms-item>
<uni-forms-item label="苹果URL" name="applet_url">
<uni-easyinput
v-model="formData.applet_url"
placeholder="请输入苹果URL"
class="form-input"
/>
</uni-forms-item>
<uni-forms-item label="状态" name="is_active">
<uni-data-checkbox
v-model="formData.is_active"
:localdata="statusOptions"
style="width: 100%"
/>
</uni-forms-item>
</uni-forms>
<!-- 表单 -->
<view class="form-section">
<view class="section-title">基本信息</view>
<view class="form-card">
<view class="form-row">
<view class="form-label">姓名</view>
<view class="form-control">
<input
v-model="distributorForm.name"
class="form-input"
placeholder="请输入姓名"
/>
</view>
</view>
<view class="form-row">
<view class="form-label">手机号</view>
<view class="form-control">
<input
v-model="distributorForm.phone"
type="number"
class="form-input"
placeholder="请输入手机号"
maxlength="11"
/>
</view>
</view>
<view class="form-row">
<view class="form-label">角色</view>
<view class="form-control">
<picker
:range="roleOptions"
:value="roleIndex"
@change="onRoleChange"
class="picker"
>
<view class="picker-text">{{ roleOptions[roleIndex] }}</view>
</picker>
</view>
</view>
<view class="form-row">
<view class="form-label">状态</view>
<view class="form-control">
<picker
:range="statusOptions"
:value="statusIndex"
@change="onStatusChange"
class="picker"
>
<view class="picker-text">{{ statusOptions[statusIndex] }}</view>
</picker>
</view>
</view>
<view class="form-row">
<view class="form-label">备注</view>
<view class="form-control">
<textarea
v-model="distributorForm.remark"
class="form-textarea"
placeholder="请输入备注信息"
maxlength="200"
></textarea>
<view class="textarea-count">{{ distributorForm.remark.length }}/200</view>
</view>
</view>
</view>
</view>
<!-- 按钮容器 -->
<view class="btn-container">
<button class="cancel-btn" @click="handleCancel">
<uni-icons type="close" size="20" color="#fff" />
<text class="btn-text">取消</text>
</button>
<button class="submit-btn" @click="handleSubmit">
<uni-icons type="checkmark" size="20" color="#fff" />
<text class="btn-text">提交</text>
</button>
<!-- 操作按钮 -->
<view class="action-section">
<view class="action-btn delete-btn" @click="deleteDistributor">
删除分销员
</view>
</view>
</view>
</template>
@@ -87,162 +90,286 @@
<script setup>
import { ref, onMounted } from "vue"
const formRef = ref(null)
const distributorId = ref(uni.getStorageSync('__uni_route_query')?.id || '')
const formData = ref({
// 分销员表单数据
const distributorForm = ref({
id: '',
name: '',
phone: '',
openid: '',
parent_id: '',
tenant_id: '',
applet_url: '',
is_active: 'Y'
name: '张三',
phone: '13800138001',
role: '初级分销员',
status: '启用',
remark: '默认分销员'
})
const statusOptions = [
{ text: '激活', value: 'Y' },
{ text: '未激活', value: 'N' }
]
// 初始化加载数据
// 角色选项
const roleOptions = ['初级分销员', '中级分销员', '高级分销员']
const roleIndex = ref(0)
// 状态选项
const statusOptions = ['启用', '禁用']
const statusIndex = ref(0)
onMounted(() => {
fetchDistributorDetail()
// 实际项目中应从接口获取分销员详情
// loadDistributorDetail()
})
// 获取分销员详情
function fetchDistributorDetail() {
// 这里应该调用后端API获取数据
// 模拟数据
// 返回上一页
function goBack() {
uni.navigateBack({ delta: 1 })
}
// 保存分销员
function saveDistributor() {
if (!distributorForm.value.name) {
uni.showToast({
title: '请输入姓名',
icon: 'none'
})
return
}
if (!distributorForm.value.phone || distributorForm.value.phone.length !== 11) {
uni.showToast({
title: '请输入有效的手机号',
icon: 'none'
})
return
}
uni.showLoading({ title: '保存中...' })
setTimeout(() => {
formData.value = {
id: distributorId.value,
name: '张三',
phone: '13800138001',
openid: 'openid123456',
parent_id: '0',
tenant_id: '1',
applet_url: 'https://example.com',
is_active: 'Y'
uni.hideLoading()
uni.showToast({
title: '保存成功',
icon: 'success'
})
// 实际项目中应调用接口保存分销员
// updateDistributorData()
// 保存成功后返回上一页
setTimeout(() => {
goBack()
}, 1000)
}, 1500)
}
// 删除分销员
function deleteDistributor() {
uni.showModal({
title: '删除分销员',
content: '确定要删除该分销员吗?',
success: function(res) {
if (res.confirm) {
uni.showLoading({ title: '删除中...' })
setTimeout(() => {
uni.hideLoading()
uni.showToast({
title: '删除成功',
icon: 'success'
})
// 实际项目中应调用接口删除分销员
// deleteDistributorData()
// 删除成功后返回上一页
setTimeout(() => {
goBack()
}, 1000)
}, 1500)
}
}
}, 500)
}
// 取消
function handleCancel() {
uni.navigateBack()
}
// 提交
function handleSubmit() {
formRef.value.validate().then(() => {
// 这里应该调用后端API提交数据
uni.showToast({ title: '修改成功' })
uni.navigateTo({ url: '/pages/distributor/index' })
}).catch(err => {
console.log('表单验证失败', err)
})
}
// 角色变更
function onRoleChange(e) {
const value = e.detail.value
roleIndex.value = value
distributorForm.value.role = roleOptions[value]
}
// 状态变更
function onStatusChange(e) {
const value = e.detail.value
statusIndex.value = value
distributorForm.value.status = statusOptions[value]
}
</script>
<style lang="scss" scoped>
.edit-container {
padding: 20rpx;
/* #ifndef APP-NVUE */
page {
display: flex;
flex-direction: column;
box-sizing: border-box;
background-color: #f5f7fa;
min-height: 100vh;
min-height: 100%;
height: auto;
}
view {
font-size: 14px;
line-height: inherit;
}
/* #endif */
.distributor-edit-container {
flex: 1;
display: flex;
flex-direction: column;
}
/* 头部样式 */
.header {
/* 页面头部 */
.page-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 24rpx;
padding-bottom: 16rpx;
border-bottom: 2rpx solid #ecf5ff;
height: 120rpx;
background-color: #fff;
padding: 0 32rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}
.title {
.header-left {
width: 60rpx;
}
.back-icon {
font-size: 40rpx;
color: #303133;
cursor: pointer;
}
.header-title {
font-size: 32rpx;
font-weight: 600;
font-weight: bold;
color: #303133;
}
.header-right {
width: 28px;
width: 60rpx;
text-align: right;
}
/* 表单容器样式 */
.form-container {
.save-btn {
font-size: 24rpx;
color: #409eff;
font-weight: 600;
cursor: pointer;
}
/* 表单内容 */
.form-section {
padding: 32rpx;
background-color: #fff;
margin: 0 16rpx 16rpx;
border-radius: 16rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
}
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #303133;
margin-bottom: 24rpx;
padding-left: 12rpx;
border-left: 8rpx solid #409eff;
line-height: 1.2;
}
.form-card {
background-color: #f9f9f9;
border-radius: 12rpx;
padding: 24rpx;
}
.form-row {
display: flex;
flex-direction: column;
margin-bottom: 24rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
}
/* 表单输入框样式 */
.form-row:last-child {
margin-bottom: 0;
}
.form-label {
font-size: 24rpx;
color: #606266;
margin-bottom: 8rpx;
}
.form-control {
position: relative;
}
.form-input {
border-radius: 8rpx !important;
border: 1rpx solid #dcdfe6 !important;
transition: all 0.3s ease !important;
}
.form-input:focus {
border-color: #409eff !important;
box-shadow: 0 0 0 2rpx rgba(64, 158, 255, 0.2) !important;
}
/* 按钮容器样式 */
.btn-container {
display: flex;
gap: 16rpx;
margin-top: 32rpx;
}
.cancel-btn,
.submit-btn {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
border: none;
padding: 16rpx 0;
width: 100%;
background-color: #fff;
border: 1rpx solid #dcdfe6;
border-radius: 8rpx;
font-size: 28rpx;
transition: all 0.3s ease;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
padding: 16rpx;
font-size: 24rpx;
color: #303133;
}
.cancel-btn:active,
.submit-btn:active {
transform: translateY(2rpx);
box-shadow: 0 1rpx 4rpx rgba(0, 0, 0, 0.1);
.picker {
background-color: #fff;
border: 1rpx solid #dcdfe6;
border-radius: 8rpx;
padding: 16rpx;
display: flex;
justify-content: space-between;
align-items: center;
}
.cancel-btn {
background-color: #909399;
color: #fff;
.picker-text {
font-size: 24rpx;
color: #303133;
}
.submit-btn {
background-color: #409eff;
color: #fff;
.form-textarea {
width: 100%;
height: 160rpx;
background-color: #fff;
border: 1rpx solid #dcdfe6;
border-radius: 8rpx;
padding: 16rpx;
font-size: 24rpx;
color: #303133;
resize: none;
}
.btn-text {
margin-left: 8rpx;
.textarea-count {
position: absolute;
bottom: 8rpx;
right: 16rpx;
font-size: 18rpx;
color: #909399;
}
/* 响应式设计 */
@media screen and (max-width: 750rpx) {
.form-container {
padding: 20rpx;
}
.btn-container {
margin-top: 24rpx;
}
/* 操作按钮 */
.action-section {
padding: 32rpx;
background-color: #fff;
margin: 0 16rpx 16rpx;
border-radius: 16rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
}
.action-btn {
width: 100%;
text-align: center;
padding: 20rpx;
border-radius: 8rpx;
font-size: 24rpx;
font-weight: 600;
cursor: pointer;
}
.delete-btn {
background-color: #fef0f0;
color: #f56c6c;
}
</style>

View File

@@ -1,398 +1,495 @@
<template>
<view class="distributor-container">
<!-- 头部 -->
<view class="header">
<text class="title">分销员管理</text>
<button class="add-btn" @click="handleAdd">
<uni-icons type="plus" size="20" color="#fff" />
<text class="add-btn-text">新增分销员</text>
</button>
<view class="distributor-list-container">
<!-- 页面标题 -->
<view class="page-header">
<view class="header-left" @click="goBack">
<view class="back-icon"></view>
</view>
<view class="header-title">分销员管理</view>
<view class="header-right" @click="addDistributor">
<view class="add-btn">添加</view>
</view>
</view>
<!-- 搜索框 -->
<view class="search-box">
<view class="search-input-wrapper">
<uni-icons type="search" size="20" color="#909399" class="search-icon" />
<input
v-model="searchForm.name"
type="text"
placeholder="请输入分销员姓名"
class="search-input"
/>
<!-- 筛选条件 -->
<view class="filter-section">
<view class="filter-row">
<view class="filter-item">
<view class="filter-label">状态</view>
<view class="filter-control">
<picker
:range="statusOptions"
:value="statusIndex"
@change="onStatusChange"
class="picker"
>
<view class="picker-text">{{ statusOptions[statusIndex] }}</view>
</picker>
</view>
</view>
<view class="filter-item">
<view class="filter-label">搜索</view>
<view class="filter-control">
<input
v-model="searchKeyword"
class="search-input"
placeholder="请输入姓名或手机号"
@input="onSearch"
/>
</view>
</view>
</view>
<view class="search-input-wrapper">
<uni-icons type="phone" size="20" color="#909399" class="search-icon" />
<input
v-model="searchForm.phone"
type="text"
placeholder="请输入手机号"
class="search-input"
/>
</view>
<button class="search-btn" @click="handleSearch">
<uni-icons type="search" size="20" color="#fff" />
<text class="search-btn-text">查询</text>
</button>
</view>
<!-- 格容器 -->
<view class="table-container">
<uni-table :loading="loading" border stripe emptyText="暂无数据">
<uni-tr>
<uni-th width="120">姓名</uni-th>
<uni-th width="150">手机号</uni-th>
<uni-th width="100">总收益</uni-th>
<uni-th width="100">可用收益</uni-th>
<uni-th width="80">状态</uni-th>
<uni-th width="180">操作</uni-th>
</uni-tr>
<uni-tr v-for="item in distributorList" :key="item.id" hover>
<uni-td>{{ item.name }}</uni-td>
<uni-td>{{ item.phone }}</uni-td>
<uni-td>{{ item.total_income }}</uni-td>
<uni-td>{{ item.available_income }}</uni-td>
<uni-td>
<view class="status-badge" :class="item.is_active === 'Y' ? 'active' : 'inactive'">
{{ item.is_active === 'Y' ? '激活' : '未激活' }}
<!-- 分销员列 -->
<view class="distributor-list-section">
<view class="section-title">分销员列表</view>
<view class="distributor-list">
<view
v-for="(distributor, index) in distributorList"
:key="index"
class="distributor-item"
>
<view class="distributor-avatar">
<view class="avatar-placeholder">{{ getInitials(distributor.name) }}</view>
</view>
<view class="distributor-info">
<view class="distributor-name">{{ distributor.name }}</view>
<view class="distributor-meta">
<view class="meta-item">{{ distributor.phone }}</view>
<view class="meta-item">{{ distributor.role }}</view>
<view class="meta-item status-{{ distributor.statusClass }}">{{ distributor.status }}</view>
</view>
</uni-td>
<uni-td>
<view class="action-buttons">
<button class="action-btn edit" @click="handleEdit(item)">
<uni-icons type="compose" size="18" color="#409eff" />
<text>修改</text>
</button>
<button class="action-btn delete" @click="handleDelete(item.id)">
<uni-icons type="trash" size="18" color="#f56c6c" />
<text>删除</text>
</button>
<button class="action-btn rule" @click="handleRule(item.id)">
<uni-icons type="settings" size="18" color="#e6a23c" />
<text>分润</text>
</button>
</view>
<view class="distributor-actions">
<view class="action-btn edit-btn" @click="editDistributor(distributor.id)">
编辑
</view>
</uni-td>
</uni-tr>
</uni-table>
<view class="action-btn delete-btn" @click="deleteDistributor(distributor.id)">
删除
</view>
</view>
</view>
</view>
</view>
<!-- 空状态 -->
<view v-if="distributorList.length === 0" class="empty-state">
<view class="empty-icon">👥</view>
<view class="empty-text">暂无分销员数据</view>
</view>
<!-- 分页 -->
<view class="pagination-container">
<uni-pagination
:current="currentPage"
:pageSize="pageSize"
:total="total"
@change="handlePageChange"
show-icon
prev-text="上一页"
next-text="下一页"
/>
<view v-if="distributorList.length > 0" class="pagination">
<view class="page-info">
{{ totalDistributors }} 当前第 {{ currentPage }}
</view>
<view class="page-controls">
<view
class="page-btn"
:class="{ disabled: currentPage === 1 }"
@click="goToPage(currentPage - 1)"
>
上一页
</view>
<view
class="page-btn"
:class="{ disabled: currentPage === totalPages }"
@click="goToPage(currentPage + 1)"
>
下一页
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, onMounted } from "vue"
import { ref, computed, onMounted } from "vue"
const loading = ref(false)
const distributorList = ref([])
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(0)
// 筛选条件
const statusOptions = ['全部状态', '启用', '禁用']
const statusIndex = ref(0)
const searchKeyword = ref('')
const searchForm = ref({
name: '',
phone: ''
// 分销员列表数据
const distributorList = ref([
{
id: 1,
name: '张三',
phone: '13800138001',
role: '初级分销员',
status: '启用',
statusClass: 'active'
},
{
id: 2,
name: '李四',
phone: '13800138002',
role: '中级分销员',
status: '启用',
statusClass: 'active'
},
{
id: 3,
name: '王五',
phone: '13800138003',
role: '高级分销员',
status: '禁用',
statusClass: 'inactive'
}
])
// 分页信息
const currentPage = ref(1)
const totalDistributors = ref(50)
const pageSize = ref(10)
// 计算总页数
const totalPages = computed(() => {
return Math.ceil(totalDistributors.value / pageSize.value)
})
// 初始化加载数据
onMounted(() => {
fetchDistributorList()
// 实际项目中应从接口获取分销员列表
// loadDistributorList()
})
// 获取分销员列表
function fetchDistributorList() {
loading.value = true
// 这里应该调用后端API获取数据
// 模拟数据
setTimeout(() => {
distributorList.value = [
{
id: 1,
name: '张三',
phone: '13800138001',
total_income: 1000.00,
available_income: 800.00,
is_active: 'Y'
},
{
id: 2,
name: '李四',
phone: '13900139002',
total_income: 2000.00,
available_income: 1500.00,
is_active: 'Y'
}
]
total.value = 2
loading.value = false
}, 500)
// 返回上一页
function goBack() {
uni.navigateBack({ delta: 1 })
}
// 搜索
function handleSearch() {
currentPage.value = 1
fetchDistributorList()
}
// 分页
function handlePageChange(e) {
currentPage.value = e.current
fetchDistributorList()
}
// 新增分销员
function handleAdd() {
// 跳转到新增页面
uni.navigateTo({ url: '/pages/distributor/add' })
}
// 修改分销员
function handleEdit(item) {
// 跳转到修改页面,并传递参数
uni.navigateTo({
url: `/pages/distributor/edit?id=${item.id}`
// 添加分销员
function addDistributor() {
uni.showToast({
title: '添加分销员功能开发中',
icon: 'none'
})
}
// 编辑分销员
function editDistributor(id) {
uni.showToast({
title: '编辑分销员功能开发中',
icon: 'none'
})
}
// 删除分销员
function handleDelete(id) {
function deleteDistributor(id) {
uni.showModal({
title: '提示',
title: '删除分销员',
content: '确定要删除该分销员吗?',
success: (res) => {
success: function(res) {
if (res.confirm) {
// 这里应该调用后端API删除数据
fetchDistributorList()
uni.showToast({ title: '删除成功' })
// 实际项目中应调用接口删除分销员
const index = distributorList.value.findIndex(item => item.id === id)
if (index !== -1) {
distributorList.value.splice(index, 1)
}
uni.showToast({
title: '删除成功',
icon: 'success'
})
}
}
})
}
// 配置分润规则
function handleRule(id) {
// 跳转到分润规则配置页面
uni.navigateTo({
url: `/pages/distributor/rule?id=${id}`
})
// 状态变更
function onStatusChange(e) {
const value = e.detail.value
statusIndex.value = value
// 实际项目中应根据状态筛选分销员
// filterDistributorList()
}
// 搜索
function onSearch() {
// 实际项目中应根据关键词搜索分销员
// searchDistributorList()
}
// 跳转到指定页码
function goToPage(page) {
if (page < 1 || page > totalPages.value) {
return
}
currentPage.value = page
// 实际项目中应加载指定页码的分销员
// loadDistributorPage(page)
}
// 获取姓名首字母
function getInitials(name) {
return name.charAt(0).toUpperCase()
}
</script>
<style lang="scss" scoped>
.distributor-container {
padding: 20rpx;
background-color: #f5f7fa;
min-height: 100vh;
}
/* 头部样式 */
.header {
/* #ifndef APP-NVUE */
page {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
padding-bottom: 16rpx;
border-bottom: 2rpx solid #ecf5ff;
flex-direction: column;
box-sizing: border-box;
background-color: #f5f7fa;
min-height: 100%;
height: auto;
}
view {
font-size: 14px;
line-height: inherit;
}
/* #endif */
.distributor-list-container {
flex: 1;
display: flex;
flex-direction: column;
}
.title {
font-size: 32rpx;
font-weight: 600;
/* 页面头部 */
.page-header {
display: flex;
align-items: center;
justify-content: space-between;
height: 120rpx;
background-color: #fff;
padding: 0 32rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}
.header-left {
width: 60rpx;
}
.back-icon {
font-size: 40rpx;
color: #303133;
cursor: pointer;
}
.header-title {
font-size: 32rpx;
font-weight: bold;
color: #303133;
}
.header-right {
width: 60rpx;
text-align: right;
}
.add-btn {
display: flex;
align-items: center;
background-color: #409eff;
color: #fff;
border: none;
padding: 12rpx 24rpx;
border-radius: 8rpx;
font-size: 24rpx;
transition: all 0.3s ease;
box-shadow: 0 2rpx 8rpx rgba(64, 158, 255, 0.3);
color: #409eff;
font-weight: 600;
cursor: pointer;
}
.add-btn:active {
transform: translateY(2rpx);
box-shadow: 0 1rpx 4rpx rgba(64, 158, 255, 0.3);
}
.add-btn-text {
margin-left: 8rpx;
}
/* 搜索框样式 */
.search-box {
display: flex;
margin-bottom: 24rpx;
gap: 16rpx;
align-items: center;
}
.search-input-wrapper {
flex: 1;
display: flex;
align-items: center;
/* 筛选条件 */
.filter-section {
padding: 24rpx 32rpx;
background-color: #fff;
margin: 16rpx;
border-radius: 16rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
}
.filter-row {
display: flex;
gap: 16rpx;
}
.filter-item {
flex: 1;
}
.filter-label {
font-size: 24rpx;
color: #606266;
margin-bottom: 8rpx;
}
.filter-control {
background-color: #f9f9f9;
border: 1rpx solid #dcdfe6;
border-radius: 8rpx;
padding: 0 16rpx;
transition: all 0.3s ease;
padding: 16rpx;
}
.search-input-wrapper:focus-within {
border-color: #409eff;
box-shadow: 0 0 0 2rpx rgba(64, 158, 255, 0.2);
.picker {
display: flex;
justify-content: space-between;
align-items: center;
}
.search-icon {
margin-right: 12rpx;
}
.search-input {
flex: 1;
padding: 16rpx 0;
border: none;
.picker-text {
font-size: 24rpx;
color: #303133;
}
.search-input::placeholder {
color: #909399;
}
.search-btn {
display: flex;
align-items: center;
background-color: #67c23a;
color: #fff;
border: none;
padding: 16rpx 24rpx;
border-radius: 8rpx;
.search-input {
font-size: 24rpx;
transition: all 0.3s ease;
box-shadow: 0 2rpx 8rpx rgba(103, 194, 58, 0.3);
color: #303133;
width: 100%;
}
.search-btn:active {
transform: translateY(2rpx);
box-shadow: 0 1rpx 4rpx rgba(103, 194, 58, 0.3);
/* 分销员列表 */
.distributor-list-section {
flex: 1;
padding: 0 16rpx;
}
.search-btn-text {
margin-left: 8rpx;
}
/* 表格容器样式 */
.table-container {
background-color: #fff;
border-radius: 12rpx;
overflow: hidden;
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #303133;
margin-bottom: 24rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
padding-left: 12rpx;
border-left: 8rpx solid #409eff;
line-height: 1.2;
}
/* 状态标签样式 */
.status-badge {
display: inline-block;
padding: 4rpx 12rpx;
border-radius: 12rpx;
font-size: 20rpx;
font-weight: 500;
}
.status-badge.active {
background-color: #f0f9eb;
color: #67c23a;
}
.status-badge.inactive {
background-color: #fef0f0;
color: #f56c6c;
}
/* 操作按钮样式 */
.action-buttons {
.distributor-list {
display: flex;
gap: 8rpx;
align-items: center;
flex-direction: column;
gap: 16rpx;
}
.action-btn {
.distributor-item {
display: flex;
align-items: center;
background-color: #fff;
border-radius: 16rpx;
padding: 24rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
}
.distributor-avatar {
width: 80rpx;
height: 80rpx;
border-radius: 40rpx;
background-color: #409eff;
display: flex;
align-items: center;
justify-content: center;
border: none;
padding: 8rpx 12rpx;
border-radius: 6rpx;
margin-right: 24rpx;
}
.avatar-placeholder {
font-size: 32rpx;
font-weight: bold;
color: #fff;
}
.distributor-info {
flex: 1;
}
.distributor-name {
font-size: 28rpx;
font-weight: 600;
color: #303133;
margin-bottom: 8rpx;
}
.distributor-meta {
display: flex;
gap: 16rpx;
flex-wrap: wrap;
}
.meta-item {
font-size: 20rpx;
transition: all 0.3s ease;
color: #606266;
}
.action-btn:active {
transform: translateY(1rpx);
.meta-item.status-active {
color: #67c23a;
}
.action-btn.edit {
.meta-item.status-inactive {
color: #909399;
}
.distributor-actions {
display: flex;
gap: 16rpx;
}
.action-btn {
padding: 8rpx 16rpx;
border-radius: 8rpx;
font-size: 16rpx;
font-weight: 600;
cursor: pointer;
}
.edit-btn {
background-color: #ecf5ff;
color: #409eff;
}
.action-btn.delete {
.delete-btn {
background-color: #fef0f0;
color: #f56c6c;
}
.action-btn.rule {
background-color: #fdf6ec;
color: #e6a23c;
}
.action-btn text {
margin-left: 4rpx;
}
/* 分页样式 */
.pagination-container {
/* 空状态 */
.empty-state {
flex: 1;
display: flex;
justify-content: flex-end;
padding: 16rpx 0;
background-color: #fff;
border-radius: 12rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 0;
}
/* 响应式设计 */
@media screen and (max-width: 750rpx) {
.search-box {
flex-direction: column;
align-items: stretch;
}
.search-input-wrapper {
width: 100%;
}
.action-buttons {
flex-wrap: wrap;
}
.action-btn {
flex: 1;
min-width: 80rpx;
}
.empty-icon {
font-size: 80rpx;
margin-bottom: 24rpx;
}
.empty-text {
font-size: 24rpx;
color: #909399;
}
/* 分页 */
.pagination {
display: flex;
justify-content: space-between;
align-items: center;
padding: 24rpx;
background-color: #fff;
margin: 16rpx;
border-radius: 16rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
}
.page-info {
font-size: 20rpx;
color: #606266;
}
.page-controls {
display: flex;
gap: 16rpx;
}
.page-btn {
padding: 8rpx 16rpx;
border-radius: 8rpx;
font-size: 20rpx;
color: #409eff;
cursor: pointer;
}
.page-btn.disabled {
color: #909399;
cursor: not-allowed;
}
</style>

View File

@@ -1,40 +1,153 @@
<template>
<view class="rule-container">
<view class="header">
<text class="title">分润规则配置</text>
<view class="distributor-rule-container">
<!-- 页面标题 -->
<view class="page-header">
<view class="header-left" @click="goBack">
<view class="back-icon"></view>
</view>
<view class="header-title">分销规则配置</view>
<view class="header-right" @click="saveRule">
<view class="save-btn">保存</view>
</view>
</view>
<view class="form-container">
<uni-forms :model="ruleForm" ref="formRef">
<uni-forms-item label="分销员ID" required>
<uni-easyinput v-model="ruleForm.distributor_id" placeholder="请输入分销员ID" type="number" />
</uni-forms-item>
<uni-forms-item label="分润比例" required>
<uni-easyinput v-model="ruleForm.profit_ratio" placeholder="请输入分润比例(%" type="number" />
</uni-forms-item>
<uni-forms-item label="规则名称" required>
<uni-easyinput v-model="ruleForm.rule_name" placeholder="请输入规则名称" />
</uni-forms-item>
<uni-forms-item label="规则描述">
<uni-easyinput v-model="ruleForm.rule_desc" placeholder="请输入规则描述" type="textarea" />
</uni-forms-item>
<uni-forms-item label="生效时间">
<uni-datetime-picker v-model="ruleForm.effective_time" type="datetime" placeholder="请选择生效时间" />
</uni-forms-item>
<uni-forms-item label="失效时间">
<uni-datetime-picker v-model="ruleForm.expire_time" type="datetime" placeholder="请选择失效时间" />
</uni-forms-item>
</uni-forms>
<!-- 规则配置 -->
<view class="rule-section">
<view class="section-title">基本规则</view>
<view class="rule-card">
<view class="rule-row">
<view class="rule-label">分销员申请审核</view>
<view class="rule-control">
<switch
:checked="ruleForm.needAudit"
@change="onAuditChange"
class="switch"
/>
</view>
</view>
<view class="rule-row">
<view class="rule-label">分销员等级制度</view>
<view class="rule-control">
<switch
:checked="ruleForm.enableLevel"
@change="onLevelChange"
class="switch"
/>
</view>
</view>
<view class="rule-row">
<view class="rule-label">分销员自购优惠</view>
<view class="rule-control">
<switch
:checked="ruleForm.enableSelfBuy"
@change="onSelfBuyChange"
class="switch"
/>
</view>
</view>
<view class="rule-row">
<view class="rule-label">分销员邀请奖励</view>
<view class="rule-control">
<switch
:checked="ruleForm.enableInviteReward"
@change="onInviteRewardChange"
class="switch"
/>
</view>
</view>
</view>
</view>
<view class="btn-container">
<button class="cancel-btn" @click="handleCancel">取消</button>
<button class="submit-btn" @click="handleSubmit">提交</button>
<!-- 等级配置 -->
<view class="rule-section" v-if="ruleForm.enableLevel">
<view class="section-title">等级配置</view>
<view class="rule-card">
<view class="level-config">
<view
v-for="(level, index) in levelList"
:key="index"
class="level-item"
>
<view class="level-header">
<view class="level-title">{{ level.name }}</view>
<view class="level-condition">
<view class="condition-label">升级条件</view>
<view class="condition-value">{{ level.condition }}</view>
</view>
</view>
<view class="level-benefit">
<view class="benefit-item">
<view class="benefit-label">分销佣金比例</view>
<view class="benefit-value">{{ level.commissionRate }}%</view>
</view>
<view class="benefit-item">
<view class="benefit-label">自购优惠比例</view>
<view class="benefit-value">{{ level.selfBuyRate }}%</view>
</view>
<view class="benefit-item">
<view class="benefit-label">邀请奖励</view>
<view class="benefit-value">¥{{ level.inviteReward.toFixed(2) }}</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 佣金规则 -->
<view class="rule-section">
<view class="section-title">佣金规则</view>
<view class="rule-card">
<view class="rule-row">
<view class="rule-label">佣金计算方式</view>
<view class="rule-control">
<picker
:range="commissionTypeOptions"
:value="commissionTypeIndex"
@change="onCommissionTypeChange"
class="picker"
>
<view class="picker-text">{{ commissionTypeOptions[commissionTypeIndex] }}</view>
</picker>
</view>
</view>
<view class="rule-row">
<view class="rule-label">佣金结算周期</view>
<view class="rule-control">
<picker
:range="settlementCycleOptions"
:value="settlementCycleIndex"
@change="onSettlementCycleChange"
class="picker"
>
<view class="picker-text">{{ settlementCycleOptions[settlementCycleIndex] }}</view>
</picker>
</view>
</view>
<view class="rule-row">
<view class="rule-label">最低提现金额</view>
<view class="rule-control">
<input
v-model="ruleForm.minWithdrawAmount"
type="number"
class="form-input"
placeholder="请输入最低提现金额"
/>
</view>
</view>
<view class="rule-row">
<view class="rule-label">提现手续费</view>
<view class="rule-control">
<input
v-model="ruleForm.withdrawFee"
type="number"
class="form-input"
placeholder="请输入提现手续费比例"
/>
<view class="input-suffix">%</view>
</view>
</view>
</view>
</view>
</view>
</template>
@@ -42,104 +155,319 @@
<script setup>
import { ref, onMounted } from "vue"
const formRef = ref(null)
const distributorId = ref(uni.getStorageSync('__uni_route_query')?.id || '')
// 规则表单数据
const ruleForm = ref({
distributor_id: distributorId.value,
profit_ratio: '',
rule_name: '',
rule_desc: '',
effective_time: '',
expire_time: ''
needAudit: true,
enableLevel: true,
enableSelfBuy: true,
enableInviteReward: true,
minWithdrawAmount: 100,
withdrawFee: 0.5
})
// 初始化加载数据
// 佣金计算方式选项
const commissionTypeOptions = ['按比例', '固定金额']
const commissionTypeIndex = ref(0)
// 结算周期选项
const settlementCycleOptions = ['实时结算', '每日结算', '每周结算', '每月结算']
const settlementCycleIndex = ref(3)
// 等级配置
const levelList = ref([
{
name: '初级分销员',
condition: '邀请1人注册',
commissionRate: 10,
selfBuyRate: 5,
inviteReward: 5
},
{
name: '中级分销员',
condition: '邀请5人注册',
commissionRate: 15,
selfBuyRate: 8,
inviteReward: 8
},
{
name: '高级分销员',
condition: '邀请10人注册',
commissionRate: 20,
selfBuyRate: 10,
inviteReward: 10
}
])
onMounted(() => {
fetchRuleDetail()
// 实际项目中应从接口获取规则配置
// loadRuleConfig()
})
// 获取分润规则详情
function fetchRuleDetail() {
// 这里应该调用后端API获取数据
// 模拟数据
// 返回上一页
function goBack() {
uni.navigateBack({ delta: 1 })
}
// 保存规则
function saveRule() {
uni.showLoading({ title: '保存中...' })
setTimeout(() => {
ruleForm.value = {
distributor_id: distributorId.value,
profit_ratio: '10',
rule_name: '默认分润规则',
rule_desc: '基础分润规则',
effective_time: new Date().toISOString(),
expire_time: ''
}
}, 500)
uni.hideLoading()
uni.showToast({
title: '保存成功',
icon: 'success'
})
// 实际项目中应调用接口保存规则配置
// saveRuleConfig()
}, 1500)
}
// 取消
function handleCancel() {
uni.navigateBack()
// 审核开关变更
function onAuditChange(e) {
const value = e.detail.value
ruleForm.value.needAudit = value
}
// 提交
function handleSubmit() {
formRef.value.validate().then(() => {
// 这里应该调用后端API提交数据
uni.showToast({ title: '配置成功' })
uni.navigateTo({ url: '/pages/distributor/index' })
}).catch(err => {
console.log('表单验证失败', err)
})
// 等级制度开关变更
function onLevelChange(e) {
const value = e.detail.value
ruleForm.value.enableLevel = value
}
// 自购优惠开关变更
function onSelfBuyChange(e) {
const value = e.detail.value
ruleForm.value.enableSelfBuy = value
}
// 邀请奖励开关变更
function onInviteRewardChange(e) {
const value = e.detail.value
ruleForm.value.enableInviteReward = value
}
// 佣金计算方式变更
function onCommissionTypeChange(e) {
const value = e.detail.value
commissionTypeIndex.value = value
}
// 结算周期变更
function onSettlementCycleChange(e) {
const value = e.detail.value
settlementCycleIndex.value = value
}
</script>
<style lang="scss" scoped>
.rule-container {
padding: 20rpx;
background-color: #f5f5f5;
min-height: 100vh;
/* #ifndef APP-NVUE */
page {
display: flex;
flex-direction: column;
box-sizing: border-box;
background-color: #f5f7fa;
min-height: 100%;
height: auto;
}
view {
font-size: 14px;
line-height: inherit;
}
/* #endif */
.distributor-rule-container {
flex: 1;
display: flex;
flex-direction: column;
}
.header {
margin-bottom: 20rpx;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #e5e5e5;
/* 页面头部 */
.page-header {
display: flex;
align-items: center;
justify-content: space-between;
height: 120rpx;
background-color: #fff;
padding: 0 32rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}
.title {
.header-left {
width: 60rpx;
}
.back-icon {
font-size: 40rpx;
color: #303133;
cursor: pointer;
}
.header-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
color: #303133;
}
.form-container {
.header-right {
width: 60rpx;
text-align: right;
}
.save-btn {
font-size: 24rpx;
color: #409eff;
font-weight: 600;
cursor: pointer;
}
/* 规则配置 */
.rule-section {
padding: 32rpx;
background-color: #fff;
border-radius: 8rpx;
padding: 20rpx;
margin-bottom: 20rpx;
margin: 0 16rpx 16rpx;
border-radius: 16rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
}
.btn-container {
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #303133;
margin-bottom: 24rpx;
padding-left: 12rpx;
border-left: 8rpx solid #409eff;
line-height: 1.2;
}
.rule-card {
background-color: #f9f9f9;
border-radius: 12rpx;
padding: 24rpx;
}
.rule-row {
display: flex;
gap: 20rpx;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
}
.cancel-btn {
flex: 1;
background-color: #909399;
color: #fff;
border: none;
padding: 20rpx;
border-radius: 4rpx;
font-size: 28rpx;
.rule-row:last-child {
margin-bottom: 0;
}
.submit-btn {
flex: 1;
background-color: #409eff;
color: #fff;
border: none;
padding: 20rpx;
border-radius: 4rpx;
font-size: 28rpx;
.rule-label {
font-size: 24rpx;
color: #606266;
}
.rule-control {
position: relative;
}
.switch {
transform: scale(0.8);
}
.picker {
background-color: #fff;
border: 1rpx solid #dcdfe6;
border-radius: 8rpx;
padding: 16rpx;
display: flex;
justify-content: space-between;
align-items: center;
min-width: 200rpx;
}
.picker-text {
font-size: 24rpx;
color: #303133;
}
.form-input {
background-color: #fff;
border: 1rpx solid #dcdfe6;
border-radius: 8rpx;
padding: 16rpx;
font-size: 24rpx;
color: #303133;
min-width: 150rpx;
}
.input-suffix {
position: absolute;
right: 32rpx;
top: 50%;
transform: translateY(-50%);
font-size: 24rpx;
color: #606266;
}
/* 等级配置 */
.level-config {
display: flex;
flex-direction: column;
gap: 16rpx;
}
.level-item {
background-color: #fff;
border: 1rpx solid #dcdfe6;
border-radius: 8rpx;
padding: 16rpx;
}
.level-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12rpx;
}
.level-title {
font-size: 24rpx;
font-weight: 600;
color: #303133;
}
.level-condition {
display: flex;
align-items: center;
}
.condition-label {
font-size: 18rpx;
color: #606266;
}
.condition-value {
font-size: 18rpx;
color: #409eff;
margin-left: 4rpx;
}
.level-benefit {
display: flex;
flex-direction: column;
gap: 8rpx;
}
.benefit-item {
display: flex;
align-items: center;
}
.benefit-label {
font-size: 18rpx;
color: #606266;
}
.benefit-value {
font-size: 18rpx;
color: #303133;
margin-left: 4rpx;
}
</style>