sc
This commit is contained in:
54
src/api/distribution/distributor.js
Normal file
54
src/api/distribution/distributor.js
Normal file
@@ -0,0 +1,54 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
// 查询分页
|
||||
export const getDistributorPage = params => {
|
||||
return request({
|
||||
url: '/applet/xunjia/distributor/page',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
};
|
||||
|
||||
// 新增
|
||||
export const addDistributor = data => {
|
||||
return request({
|
||||
url: '/applet/xunjia/distributor/create',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
// 修改
|
||||
export const updateDistributor = data => {
|
||||
return request({
|
||||
url: '/applet/xunjia/distributor/update',
|
||||
method: 'put',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
// 删除
|
||||
export const deleteDistributor = id => {
|
||||
return request({
|
||||
url: '/applet/xunjia/distributor/delete',
|
||||
method: 'delete',
|
||||
params: { id }
|
||||
});
|
||||
};
|
||||
|
||||
// 修改状态
|
||||
export const updateDistributorStatus = data => {
|
||||
return request({
|
||||
url: '/applet/xunjia/distributor/tatus/update',
|
||||
method: 'put',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
// 获取详情
|
||||
export const getDistributorDetail = id => {
|
||||
return request({
|
||||
url: '/applet/xunjia/distributor/get/' + id,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
9
src/api/distribution/index.js
Normal file
9
src/api/distribution/index.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
export const getRulesInfo = params => {
|
||||
return request({
|
||||
url: '/applet/xunjia/tenant/get',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
};
|
||||
@@ -30,48 +30,6 @@
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/mine/avatar/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/mine/info/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/mine/info/edit",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/mine/pwd/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/mine/setting/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/mine/help/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/mine/about/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/common/webview/index",
|
||||
"style": {
|
||||
@@ -102,12 +60,6 @@
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/distributor/rule",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/distribution/data",
|
||||
"style": {
|
||||
|
||||
@@ -16,35 +16,48 @@
|
||||
<view class="section-title">规则说明</view>
|
||||
<view class="info-card">
|
||||
<view class="info-item">• 分润规则适用于所有分销员</view>
|
||||
<view class="info-item">• 扫码注册分润:学员通过推广码扫码注册后,分销员可获得的分润</view>
|
||||
<view class="info-item">• 购买会员分润:学员通过推广码购买会员后,分销员可获得的分润</view>
|
||||
<view class="info-item">• 分润比例:按会员价格的百分比计算,最高不超过50%</view>
|
||||
<view class="info-item">• 注册分润:学员通过推广码扫码注册后,分销员可获得的分润</view>
|
||||
<view class="info-item">• 消费分润:学员通过推广码购买会员后,分销员可获得的分润</view>
|
||||
<view class="info-item">• 分润比例:按会员价格的百分比计算</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 分润规则配置 -->
|
||||
<view class="rule-config-section">
|
||||
<view class="section-title">分润规则配置</view>
|
||||
<view class="rule-hint">
|
||||
<view class="info-item">• 固定金额:直接设置具体金额</view>
|
||||
<view class="info-item">• 比例分润:按预设基准金额的百分比计算</view>
|
||||
</view>
|
||||
<view class="rule-card">
|
||||
<!-- 扫码注册分润 -->
|
||||
<view class="rule-item">
|
||||
<!-- 注册分润 -->
|
||||
<view class="rule-item" v-for="(rule, idx) in profitRules" :key="rule.id || idx">
|
||||
<view class="rule-header">
|
||||
<view class="rule-title">扫码注册分润</view>
|
||||
<view class="rule-title">
|
||||
{{ rule.type === 'register' ? '注册分润' : '消费分润' }}
|
||||
<view v-if="rule.type === 'consume'" class="rule-actions">
|
||||
<view class="delete-btn" @click="deleteConsumeRule(idx)">
|
||||
<text style="color: #f56c6c; font-size: 24rpx;">删除</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="rule-toggle">
|
||||
<switch
|
||||
:checked="scanRegisterRule.enabled"
|
||||
@change="onScanRegisterToggle"
|
||||
class="toggle-switch"
|
||||
active-color="#409eff"
|
||||
/>
|
||||
<view class="rule-control">
|
||||
<radio-group @change="e => onProfitTypeChange(idx, e.detail.value)">
|
||||
<label v-for="(option, index) in profitTypeOptions" :key="index" class="radio-item">
|
||||
<radio :value="option.value" :checked="rule.profitType === option.value" />
|
||||
<text class="radio-label">{{ option.label }}</text>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="scanRegisterRule.enabled" class="rule-content">
|
||||
<view class="rule-row">
|
||||
<view class="rule-content">
|
||||
<view class="rule-row" v-if="rule.profitType == '1'">
|
||||
<view class="rule-label">分润金额</view>
|
||||
<view class="rule-control">
|
||||
<input
|
||||
v-model="scanRegisterRule.amount"
|
||||
v-model="rule.amount"
|
||||
type="number"
|
||||
class="rule-input"
|
||||
placeholder="请输入分润金额"
|
||||
@@ -55,32 +68,11 @@
|
||||
<view class="rule-unit">元</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="rule-hint">
|
||||
• 固定金额分润,学员扫码注册后立即发放
|
||||
• 建议设置为5-20元
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 购买会员分润 -->
|
||||
<view class="rule-item">
|
||||
<view class="rule-header">
|
||||
<view class="rule-title">购买会员分润</view>
|
||||
<view class="rule-toggle">
|
||||
<switch
|
||||
:checked="memberPurchaseRule.enabled"
|
||||
@change="onMemberPurchaseToggle"
|
||||
class="toggle-switch"
|
||||
active-color="#409eff"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="memberPurchaseRule.enabled" class="rule-content">
|
||||
<view class="rule-row">
|
||||
<view class="rule-row" v-else-if="rule.profitType == '2'">
|
||||
<view class="rule-label">分润比例</view>
|
||||
<view class="rule-control">
|
||||
<input
|
||||
v-model="memberPurchaseRule.percentage"
|
||||
v-model="rule.percentage"
|
||||
type="number"
|
||||
class="rule-input"
|
||||
placeholder="请输入分润比例"
|
||||
@@ -91,144 +83,75 @@
|
||||
<view class="rule-unit">%</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="rule-row">
|
||||
<view class="rule-label">会员类型</view>
|
||||
|
||||
<!-- 消费分润VIP选择 -->
|
||||
<view v-if="rule.type === 'consume'">
|
||||
<view class="rule-label" style="margin-bottom: 10rpx;">选择会员类型</view>
|
||||
<view class="rule-control">
|
||||
<picker
|
||||
:range="memberTypes"
|
||||
:value="memberTypeIndex"
|
||||
@change="onMemberTypeChange"
|
||||
class="picker"
|
||||
>
|
||||
<view class="picker-text">{{ memberTypes[memberTypeIndex] }}</view>
|
||||
</picker>
|
||||
<view class="vip-list">
|
||||
<label v-for="vip in vipList" :key="vip.memberId" class="vip-item checkbox-item"
|
||||
@click="onVipChange(idx, vip.memberId)">
|
||||
<checkbox
|
||||
:value="vip.memberId"
|
||||
:checked="rule.selectedVips.includes(vip.memberId)"
|
||||
:disabled="isVipSelectedInOtherRules(idx, vip.memberId)"
|
||||
/>
|
||||
<view class="checkbox-label" :class="{ 'disabled': isVipSelectedInOtherRules(idx, vip.memberId) }">
|
||||
<text>{{ vip.carName || '' }}</text>
|
||||
<text>{{ vip.memberName || '' }}</text>
|
||||
<text>{{ vip.discount ? ' ' + vip.discount : '' }}</text>
|
||||
</view>
|
||||
</label>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="rule-hint">
|
||||
• 按会员价格的百分比计算分润
|
||||
• 最高分润比例为50%
|
||||
• 建议设置为10%-30%
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 新增消费分润规则按钮 -->
|
||||
<view class="add-rule-btn" @click="addConsumeRule">
|
||||
<text style="color: #409eff; font-size: 28rpx;">+ 新增消费分润规则</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 会员价格设置 -->
|
||||
<view class="price-section">
|
||||
<view class="section-title">会员价格设置</view>
|
||||
<view class="price-card">
|
||||
<view class="price-item">
|
||||
<view class="price-label">月度会员价格</view>
|
||||
<view class="price-control">
|
||||
<input
|
||||
v-model="memberPrices.monthly"
|
||||
type="number"
|
||||
class="price-input"
|
||||
placeholder="请输入月度会员价格"
|
||||
min="0"
|
||||
max="1000"
|
||||
step="0.1"
|
||||
/>
|
||||
<view class="price-unit">元</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="price-item">
|
||||
<view class="price-label">季度会员价格</view>
|
||||
<view class="price-control">
|
||||
<input
|
||||
v-model="memberPrices.quarterly"
|
||||
type="number"
|
||||
class="price-input"
|
||||
placeholder="请输入季度会员价格"
|
||||
min="0"
|
||||
max="3000"
|
||||
step="0.1"
|
||||
/>
|
||||
<view class="price-unit">元</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="price-item">
|
||||
<view class="price-label">年度会员价格</view>
|
||||
<view class="price-control">
|
||||
<input
|
||||
v-model="memberPrices.yearly"
|
||||
type="number"
|
||||
class="price-input"
|
||||
placeholder="请输入年度会员价格"
|
||||
min="0"
|
||||
max="10000"
|
||||
step="0.1"
|
||||
/>
|
||||
<view class="price-unit">元</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 分润预览 -->
|
||||
<view class="preview-section">
|
||||
<view class="section-title">分润预览</view>
|
||||
<view class="preview-card">
|
||||
<view class="preview-item">
|
||||
<view class="preview-label">月度会员分润</view>
|
||||
<view class="preview-value">{{ calculatePreview('monthly') }}</view>
|
||||
</view>
|
||||
<view class="preview-item">
|
||||
<view class="preview-label">季度会员分润</view>
|
||||
<view class="preview-value">{{ calculatePreview('quarterly') }}</view>
|
||||
</view>
|
||||
<view class="preview-item">
|
||||
<view class="preview-label">年度会员分润</view>
|
||||
<view class="preview-value">{{ calculatePreview('yearly') }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from "vue"
|
||||
import { ref, onMounted } from "vue"
|
||||
import { getVipTypeList } from "@/api/member"
|
||||
|
||||
// 扫码注册分润规则
|
||||
const scanRegisterRule = ref({
|
||||
enabled: true,
|
||||
amount: 10
|
||||
})
|
||||
|
||||
// 购买会员分润规则
|
||||
const memberPurchaseRule = ref({
|
||||
enabled: true,
|
||||
percentage: 20
|
||||
})
|
||||
|
||||
// 会员类型选项
|
||||
const memberTypes = ['全部会员类型', '月度会员', '季度会员', '年度会员']
|
||||
const memberTypeIndex = ref(0)
|
||||
|
||||
// 会员价格
|
||||
const memberPrices = ref({
|
||||
monthly: 39.9,
|
||||
quarterly: 99.9,
|
||||
yearly: 299.9
|
||||
})
|
||||
|
||||
// 计算分润预览
|
||||
function calculatePreview(type) {
|
||||
if (!memberPurchaseRule.value.enabled) {
|
||||
return '¥0.00'
|
||||
// 分润规则数组
|
||||
const profitRules = ref([
|
||||
{
|
||||
type: 'register', // 注册分润
|
||||
profitType: '1', // 固定金额
|
||||
amount: 10,
|
||||
percentage: 0
|
||||
},
|
||||
{
|
||||
id: Date.now(), // 唯一标识
|
||||
type: 'consume', // 消费分润
|
||||
profitType: '2', // 比例分润
|
||||
amount: 0,
|
||||
percentage: 20,
|
||||
selectedVips: [] // 选中的VIP
|
||||
}
|
||||
|
||||
const price = memberPrices.value[type]
|
||||
const percentage = memberPurchaseRule.value.percentage
|
||||
const amount = (price * percentage) / 100
|
||||
|
||||
return `¥${amount.toFixed(2)}`
|
||||
}
|
||||
])
|
||||
|
||||
const vipList = ref([])
|
||||
|
||||
// 分润方式选项
|
||||
const profitTypeOptions = [{ label: '固定金额', value: '1' }, { label: '比例分润', value: '2' }]
|
||||
|
||||
onMounted(() => {
|
||||
// 实际项目中应从接口获取分润规则配置
|
||||
// loadProfitRules()
|
||||
|
||||
getVipTypeList().then(res => {
|
||||
vipList.value = res.data?.list?.filter(item => item.useTypes.includes(1)) || []
|
||||
})
|
||||
})
|
||||
|
||||
// 返回上一页
|
||||
@@ -259,19 +182,71 @@
|
||||
})
|
||||
}
|
||||
|
||||
// 扫码注册分润开关
|
||||
function onScanRegisterToggle(e) {
|
||||
scanRegisterRule.value.enabled = e.detail.value
|
||||
// 分润方式变更
|
||||
function onProfitTypeChange(idx, profitType) {
|
||||
const rule = profitRules.value[idx]
|
||||
if (rule) {
|
||||
rule.profitType = profitType
|
||||
// 重置对应的值
|
||||
if (profitType === '1') {
|
||||
rule.percentage = 0
|
||||
} else if (profitType === '2') {
|
||||
rule.amount = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 购买会员分润开关
|
||||
function onMemberPurchaseToggle(e) {
|
||||
memberPurchaseRule.value.enabled = e.detail.value
|
||||
// 新增消费分润规则
|
||||
function addConsumeRule() {
|
||||
profitRules.value.push({
|
||||
id: Date.now(), // 唯一标识
|
||||
type: 'consume', // 消费分润
|
||||
profitType: '2', // 比例分润
|
||||
amount: 0,
|
||||
percentage: 20,
|
||||
selectedVips: [] // 选中的VIP
|
||||
})
|
||||
}
|
||||
|
||||
// 会员类型变更
|
||||
function onMemberTypeChange(e) {
|
||||
memberTypeIndex.value = e.detail.value
|
||||
// 删除消费分润规则
|
||||
function deleteConsumeRule(idx) {
|
||||
if (profitRules.value[idx].type === 'consume') {
|
||||
profitRules.value.splice(idx, 1)
|
||||
}
|
||||
}
|
||||
|
||||
// 检查会员类型是否在其他消费分润规则中被选中
|
||||
function isVipSelectedInOtherRules(currentIdx, vipId) {
|
||||
return profitRules.value.some((otherRule, otherIdx) => {
|
||||
return otherIdx !== currentIdx &&
|
||||
otherRule.type === 'consume' &&
|
||||
otherRule.selectedVips.includes(vipId)
|
||||
})
|
||||
}
|
||||
|
||||
// VIP选择变更(确保会员类型不重复)
|
||||
function onVipChange(idx, vipId) {
|
||||
if (profitRules.value[idx]) {
|
||||
const vipIndex = profitRules.value[idx].selectedVips.indexOf(vipId)
|
||||
if (vipIndex > -1) {
|
||||
// 取消选择
|
||||
profitRules.value[idx].selectedVips.splice(vipIndex, 1)
|
||||
console.log('取消选择',idx+1, profitRules.value[idx].selectedVips.length)
|
||||
} else {
|
||||
// 检查是否在其他消费分润规则中已选中
|
||||
const isDuplicate = isVipSelectedInOtherRules(idx, vipId)
|
||||
|
||||
if (!isDuplicate) {
|
||||
profitRules.value[idx].selectedVips.push(vipId)
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '该会员类型已在其他规则中选中',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -306,6 +281,7 @@
|
||||
height: 120rpx;
|
||||
background-color: #fff;
|
||||
padding: 0 32rpx;
|
||||
margin-bottom: 16rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
@@ -317,6 +293,11 @@
|
||||
font-size: 40rpx;
|
||||
color: #303133;
|
||||
cursor: pointer;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.back-icon:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
@@ -335,18 +316,29 @@
|
||||
color: #409eff;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
padding: 8rpx 16rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.save-btn:hover {
|
||||
background-color: rgba(64, 158, 255, 0.1);
|
||||
}
|
||||
|
||||
/* 通用部分样式 */
|
||||
.rule-info-section,
|
||||
.rule-config-section,
|
||||
.price-section,
|
||||
.preview-section {
|
||||
.rule-config-section {
|
||||
padding: 32rpx;
|
||||
background-color: #fff;
|
||||
margin: 0 16rpx 16rpx;
|
||||
border-radius: 16rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
|
||||
transition: box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
.rule-info-section:hover,
|
||||
.rule-config-section:hover {
|
||||
box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.section-title {
|
||||
@@ -364,6 +356,7 @@
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 12rpx;
|
||||
padding: 24rpx;
|
||||
border: 1rpx solid #e4e7ed;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
@@ -384,6 +377,13 @@
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 12rpx;
|
||||
padding: 24rpx;
|
||||
border: 1rpx solid #e4e7ed;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.rule-item:hover {
|
||||
background-color: #f0f2f5;
|
||||
border-color: #dcdfe6;
|
||||
}
|
||||
|
||||
.rule-header {
|
||||
@@ -399,6 +399,41 @@
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.rule-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
margin-top: 8rpx;
|
||||
padding: 8rpx 16rpx;
|
||||
border-radius: 8rpx;
|
||||
background-color: rgba(245, 108, 108, 0.1);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.delete-btn:hover {
|
||||
background-color: rgba(245, 108, 108, 0.2);
|
||||
}
|
||||
|
||||
.add-rule-btn {
|
||||
margin-top: 24rpx;
|
||||
padding: 20rpx;
|
||||
background-color: #ecf5ff;
|
||||
border: 1rpx dashed #409eff;
|
||||
border-radius: 12rpx;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.add-rule-btn:hover {
|
||||
background-color: #ebefff;
|
||||
border-color: #66b1ff;
|
||||
}
|
||||
|
||||
.rule-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -419,7 +454,25 @@
|
||||
.rule-control {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
.radio-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
transition: color 0.3s ease;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.radio-item:hover .radio-label {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.radio-label {
|
||||
margin-left: 8rpx;
|
||||
font-size: 24rpx;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.rule-input {
|
||||
@@ -431,6 +484,13 @@
|
||||
padding: 0 16rpx;
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.rule-input:focus {
|
||||
outline: none;
|
||||
border-color: #409eff;
|
||||
box-shadow: 0 0 0 2rpx rgba(64, 158, 255, 0.2);
|
||||
}
|
||||
|
||||
.rule-unit {
|
||||
@@ -445,89 +505,59 @@
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.picker {
|
||||
/* VIP列表样式 */
|
||||
.vip-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.vip-item {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
border: 1rpx solid #dcdfe6;
|
||||
border-radius: 8rpx;
|
||||
padding: 16rpx;
|
||||
min-width: 200rpx;
|
||||
padding: 12rpx 16rpx;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.picker-text {
|
||||
font-size: 24rpx;
|
||||
.vip-item:hover {
|
||||
border-color: #409eff;
|
||||
box-shadow: 0 2rpx 8rpx rgba(64, 158, 255, 0.1);
|
||||
}
|
||||
|
||||
.vip-label {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 15rpx;
|
||||
font-size: 20rpx;
|
||||
color: #303133;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 会员价格设置 */
|
||||
.price-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16rpx;
|
||||
/* 禁用状态样式 */
|
||||
.checkbox-label.disabled {
|
||||
color: #c0c4cc !important;
|
||||
opacity: 0.5 !important;
|
||||
}
|
||||
|
||||
.price-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 24rpx;
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 12rpx;
|
||||
/* 禁用的checkbox样式 */
|
||||
checkbox[disabled] {
|
||||
opacity: 0.5 !important;
|
||||
}
|
||||
|
||||
.price-label {
|
||||
font-size: 24rpx;
|
||||
color: #606266;
|
||||
checkbox[disabled] .uni-checkbox-input {
|
||||
border-color: #dcdfe6 !important;
|
||||
background-color: #f5f7fa !important;
|
||||
}
|
||||
|
||||
.price-control {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.price-input {
|
||||
width: 160rpx;
|
||||
height: 60rpx;
|
||||
background-color: #fff;
|
||||
border: 1rpx solid #dcdfe6;
|
||||
border-radius: 8rpx;
|
||||
padding: 0 16rpx;
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.price-unit {
|
||||
font-size: 24rpx;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
/* 分润预览 */
|
||||
.preview-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.preview-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 24rpx;
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.preview-label {
|
||||
font-size: 24rpx;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.preview-value {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #f56c6c;
|
||||
checkbox[disabled] .uni-checkbox-input.uni-checkbox-input-checked {
|
||||
border-color: #dcdfe6 !important;
|
||||
background-color: #dcdfe6 !important;
|
||||
}
|
||||
</style>
|
||||
@@ -41,26 +41,16 @@
|
||||
<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>
|
||||
<radio-group @change="onStatusChange">
|
||||
<label
|
||||
v-for="(option, index) in statusOptions"
|
||||
:key="index"
|
||||
class="radio-item"
|
||||
>
|
||||
<radio :value="index.toString()" :checked="distributorForm.status == index.toString()" />
|
||||
<text class="radio-label">{{ option }}</text>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -70,22 +60,20 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from "vue"
|
||||
import {
|
||||
addDistributor,
|
||||
} from "@/api/distribution/distributor";
|
||||
|
||||
// 分销员表单数据
|
||||
const distributorForm = ref({
|
||||
name: '',
|
||||
phone: '',
|
||||
status: '启用',
|
||||
remark: ''
|
||||
status: '0',
|
||||
})
|
||||
|
||||
// 状态选项
|
||||
const statusOptions = ['启用', '禁用']
|
||||
const statusIndex = ref(0)
|
||||
|
||||
onMounted(() => {
|
||||
// 初始化表单数据
|
||||
})
|
||||
|
||||
// 返回上一页
|
||||
function goBack() {
|
||||
@@ -112,29 +100,30 @@
|
||||
|
||||
uni.showLoading({ title: '保存中...' })
|
||||
|
||||
setTimeout(() => {
|
||||
addDistributor(distributorForm.value).then(res => {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: '添加成功',
|
||||
icon: 'success'
|
||||
})
|
||||
// 实际项目中应调用接口保存分销员
|
||||
// saveDistributorData()
|
||||
|
||||
// 保存成功后返回上一页
|
||||
setTimeout(() => {
|
||||
goBack()
|
||||
}, 1000)
|
||||
}, 1500)
|
||||
}).catch(err => {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: err.message || '添加失败',
|
||||
icon: 'none'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 状态变更
|
||||
function onStatusChange(e) {
|
||||
const value = e.detail.value
|
||||
statusIndex.value = value
|
||||
distributorForm.value.status = statusOptions[value]
|
||||
distributorForm.value.status = e.detail.value.toString()
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -328,68 +317,24 @@
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
/* 平板和大屏响应式 */
|
||||
@media screen and (min-width: 768px) {
|
||||
.distributor-add-container {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form-section {
|
||||
margin: 0 32rpx 24rpx;
|
||||
padding: 40rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 36rpx;
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.form-card {
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.form-row {
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.form-input,
|
||||
.picker {
|
||||
padding: 24rpx 28rpx;
|
||||
font-size: 26rpx;
|
||||
border-radius: 14rpx;
|
||||
}
|
||||
|
||||
.picker-text {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.form-textarea {
|
||||
height: 200rpx;
|
||||
padding: 24rpx 28rpx;
|
||||
font-size: 26rpx;
|
||||
border-radius: 14rpx;
|
||||
}
|
||||
|
||||
.form-input::placeholder,
|
||||
.form-textarea::placeholder {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.textarea-count {
|
||||
font-size: 20rpx;
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
/* Radio样式 */
|
||||
radio-group {
|
||||
display: flex;
|
||||
gap: 32rpx;
|
||||
}
|
||||
|
||||
.radio-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.radio-label {
|
||||
font-size: 24rpx;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
|
||||
/* 大屏设备响应式 */
|
||||
@media screen and (min-width: 1024px) {
|
||||
.distributor-add-container {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<view class="distributor-edit-container">
|
||||
<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-title">添加分销员</view>
|
||||
<view class="header-right" @click="saveDistributor">
|
||||
<view class="save-btn">保存</view>
|
||||
</view>
|
||||
@@ -41,61 +41,64 @@
|
||||
<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>
|
||||
<radio-group @change="onStatusChange">
|
||||
<label
|
||||
v-for="(option, index) in statusOptions"
|
||||
:key="index"
|
||||
class="radio-item"
|
||||
>
|
||||
<radio :value="index.toString()" :checked="distributorForm.status == index.toString()" />
|
||||
<text class="radio-label">{{ option }}</text>
|
||||
</label>
|
||||
</radio-group>
|
||||
</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="action-section">
|
||||
<view class="action-btn delete-btn" @click="deleteDistributor">
|
||||
删除分销员
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from "vue"
|
||||
import { ref } from "vue"
|
||||
import { onLoad } from "@dcloudio/uni-app";
|
||||
import {
|
||||
updateDistributor,
|
||||
getDistributorDetail
|
||||
} from "@/api/distribution/distributor";
|
||||
|
||||
// 分销员表单数据
|
||||
const distributorForm = ref({
|
||||
id: '',
|
||||
name: '张三',
|
||||
phone: '13800138001',
|
||||
status: '启用',
|
||||
remark: '默认分销员'
|
||||
name: '',
|
||||
phone: '',
|
||||
status: '0',
|
||||
remark: ''
|
||||
})
|
||||
|
||||
// 状态选项
|
||||
const statusOptions = ['启用', '禁用']
|
||||
const statusIndex = ref(0)
|
||||
|
||||
onMounted(() => {
|
||||
// 实际项目中应从接口获取分销员详情
|
||||
// loadDistributorDetail()
|
||||
onLoad((options) => {
|
||||
// 获取分销员信息
|
||||
getDistributorInfo(options.id)
|
||||
})
|
||||
|
||||
|
||||
// 获取分销员信息
|
||||
function getDistributorInfo(id) {
|
||||
getDistributorDetail(id).then(res => {
|
||||
distributorForm.value = {
|
||||
...res.data,
|
||||
status: res.data.status.toString()
|
||||
}
|
||||
}).catch(err => {
|
||||
uni.showToast({
|
||||
title: err.message || '获取失败',
|
||||
icon: 'none'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 返回上一页
|
||||
function goBack() {
|
||||
uni.navigateBack({ delta: 1 })
|
||||
@@ -121,47 +124,22 @@
|
||||
|
||||
uni.showLoading({ title: '保存中...' })
|
||||
|
||||
setTimeout(() => {
|
||||
updateDistributor(distributorForm.value).then(res => {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}).catch(err => {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: err.message || '添加失败',
|
||||
icon: 'none'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -169,9 +147,7 @@
|
||||
|
||||
// 状态变更
|
||||
function onStatusChange(e) {
|
||||
const value = e.detail.value
|
||||
statusIndex.value = value
|
||||
distributorForm.value.status = statusOptions[value]
|
||||
distributorForm.value.status = e.detail.value.toString()
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -192,7 +168,7 @@
|
||||
}
|
||||
/* #endif */
|
||||
|
||||
.distributor-edit-container {
|
||||
.distributor-add-container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -241,7 +217,7 @@
|
||||
.form-section {
|
||||
padding: 32rpx;
|
||||
background-color: #fff;
|
||||
margin: 0 16rpx 16rpx;
|
||||
margin: 16rpx;
|
||||
border-radius: 16rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
@@ -284,22 +260,47 @@
|
||||
|
||||
.form-input {
|
||||
width: 100%;
|
||||
height: 70rpx;
|
||||
background-color: #fff;
|
||||
border: 1rpx solid #dcdfe6;
|
||||
border-radius: 8rpx;
|
||||
padding: 16rpx;
|
||||
border-radius: 12rpx;
|
||||
padding: 20rpx 24rpx;
|
||||
font-size: 24rpx;
|
||||
color: #303133;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.02);
|
||||
}
|
||||
|
||||
.form-input:focus {
|
||||
border-color: #409eff;
|
||||
box-shadow: 0 0 0 4rpx rgba(64, 158, 255, 0.1);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.form-input::placeholder {
|
||||
color: #909399;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.picker {
|
||||
background-color: #fff;
|
||||
border: 1rpx solid #dcdfe6;
|
||||
border-radius: 8rpx;
|
||||
padding: 16rpx;
|
||||
border-radius: 12rpx;
|
||||
padding: 20rpx 24rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.picker:hover {
|
||||
border-color: #c6e2ff;
|
||||
box-shadow: 0 2rpx 8rpx rgba(64, 158, 255, 0.1);
|
||||
}
|
||||
|
||||
.picker:active {
|
||||
background-color: #f5faff;
|
||||
}
|
||||
|
||||
.picker-text {
|
||||
@@ -312,11 +313,24 @@
|
||||
height: 160rpx;
|
||||
background-color: #fff;
|
||||
border: 1rpx solid #dcdfe6;
|
||||
border-radius: 8rpx;
|
||||
padding: 16rpx;
|
||||
border-radius: 12rpx;
|
||||
padding: 20rpx 24rpx;
|
||||
font-size: 24rpx;
|
||||
color: #303133;
|
||||
resize: none;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.02);
|
||||
}
|
||||
|
||||
.form-textarea:focus {
|
||||
border-color: #409eff;
|
||||
box-shadow: 0 0 0 4rpx rgba(64, 158, 255, 0.1);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.form-textarea::placeholder {
|
||||
color: #909399;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.textarea-count {
|
||||
@@ -327,94 +341,27 @@
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
/* 操作按钮 */
|
||||
.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);
|
||||
/* Radio样式 */
|
||||
radio-group {
|
||||
display: flex;
|
||||
gap: 32rpx;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
padding: 20rpx;
|
||||
border-radius: 8rpx;
|
||||
.radio-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.radio-label {
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
background-color: #fef0f0;
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
/* 平板和大屏响应式 */
|
||||
@media screen and (min-width: 768px) {
|
||||
.distributor-edit-container {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form-section,
|
||||
.action-section {
|
||||
margin: 0 32rpx 24rpx;
|
||||
padding: 40rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 36rpx;
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.form-card {
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.form-row {
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.form-input,
|
||||
.picker {
|
||||
padding: 20rpx;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.picker-text {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.form-textarea {
|
||||
height: 200rpx;
|
||||
padding: 20rpx;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.textarea-count {
|
||||
font-size: 20rpx;
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
font-size: 26rpx;
|
||||
padding: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 大屏设备响应式 */
|
||||
@media screen and (min-width: 1024px) {
|
||||
.distributor-edit-container {
|
||||
.distributor-add-container {
|
||||
max-width: 1000px;
|
||||
}
|
||||
|
||||
@@ -428,7 +375,9 @@
|
||||
|
||||
.form-input,
|
||||
.picker {
|
||||
padding: 28rpx 32rpx;
|
||||
font-size: 28rpx;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.picker-text {
|
||||
@@ -436,11 +385,14 @@
|
||||
}
|
||||
|
||||
.form-textarea {
|
||||
padding: 28rpx 32rpx;
|
||||
font-size: 28rpx;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
font-size: 28rpx;
|
||||
.form-input::placeholder,
|
||||
.form-textarea::placeholder {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -15,25 +15,23 @@
|
||||
<view class="filter-section">
|
||||
<view class="filter-row">
|
||||
<view class="filter-item">
|
||||
<view class="filter-label">状态</view>
|
||||
<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>
|
||||
<input
|
||||
v-model="searchName"
|
||||
class="search-input"
|
||||
placeholder="请输入姓名"
|
||||
@input="onSearch"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="filter-item">
|
||||
<view class="filter-label">搜索</view>
|
||||
<view class="filter-label">手机号</view>
|
||||
<view class="filter-control">
|
||||
<input
|
||||
v-model="searchKeyword"
|
||||
v-model="searchPhone"
|
||||
class="search-input"
|
||||
placeholder="请输入姓名或手机号"
|
||||
placeholder="请输入手机号"
|
||||
@input="onSearch"
|
||||
/>
|
||||
</view>
|
||||
@@ -57,15 +55,22 @@
|
||||
<view class="distributor-name">{{ distributor.name }}</view>
|
||||
<view class="distributor-meta">
|
||||
<view class="meta-item">{{ distributor.phone }}</view>
|
||||
<view class="meta-item status-{{ distributor.statusClass }}">{{ distributor.status }}</view>
|
||||
<view class="meta-item" :class="{'status-active': distributor.status == 0, 'status-inactive': distributor.status == 1}">{{ statusOptions[distributor.status] }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="distributor-actions">
|
||||
<view class="action-btn edit-btn" @click="editDistributor(distributor.id)">
|
||||
编辑
|
||||
<view class="action-row">
|
||||
<view class="action-btn edit-btn" @click="editDistributor(distributor.id)">
|
||||
编辑
|
||||
</view>
|
||||
<view class="action-btn delete-btn" @click="confirmDelete(distributor.id)">
|
||||
删除
|
||||
</view>
|
||||
</view>
|
||||
<view class="action-btn delete-btn" @click="deleteDistributor(distributor.id)">
|
||||
删除
|
||||
<view class="action-row">
|
||||
<view class="action-btn rule-btn" @click="viewDistributorRules(distributor.id)">
|
||||
分销规则
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -104,37 +109,19 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from "vue"
|
||||
import { ref, computed } from "vue"
|
||||
import { getDistributorPage, deleteDistributor } from '@/api/distribution/distributor'
|
||||
import { onShow } from "@dcloudio/uni-app"
|
||||
|
||||
// 筛选条件
|
||||
const statusOptions = ['全部状态', '启用', '禁用']
|
||||
const statusIndex = ref(0)
|
||||
const searchKeyword = ref('')
|
||||
const searchName = ref('')
|
||||
const searchPhone = ref('')
|
||||
|
||||
// 分销员列表数据
|
||||
const distributorList = ref([
|
||||
{
|
||||
id: 1,
|
||||
name: '张三',
|
||||
phone: '13800138001',
|
||||
status: '启用',
|
||||
statusClass: 'active'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '李四',
|
||||
phone: '13800138002',
|
||||
status: '启用',
|
||||
statusClass: 'active'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '王五',
|
||||
phone: '13800138003',
|
||||
status: '禁用',
|
||||
statusClass: 'inactive'
|
||||
}
|
||||
])
|
||||
const distributorList = ref([])
|
||||
|
||||
// 状态选项
|
||||
const statusOptions = ['启用', '禁用']
|
||||
|
||||
// 分页信息
|
||||
const currentPage = ref(1)
|
||||
@@ -146,9 +133,9 @@
|
||||
return Math.ceil(totalDistributors.value / pageSize.value)
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
onShow(() => {
|
||||
// 实际项目中应从接口获取分销员列表
|
||||
// loadDistributorList()
|
||||
loadDistributorList()
|
||||
})
|
||||
|
||||
// 返回上一页
|
||||
@@ -156,6 +143,21 @@
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}
|
||||
|
||||
const loadDistributorList = async () => {
|
||||
const params = {
|
||||
page: currentPage.value,
|
||||
pageSize: pageSize.value,
|
||||
name: searchName.value,
|
||||
phone: searchPhone.value
|
||||
}
|
||||
const res = await getDistributorPage(params)
|
||||
if (res.code == '0000') {
|
||||
distributorList.value = res.data.list
|
||||
totalDistributors.value = res.data.total
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 添加分销员
|
||||
function addDistributor() {
|
||||
// 跳转至添加分销员页面
|
||||
@@ -172,39 +174,35 @@
|
||||
})
|
||||
}
|
||||
|
||||
// 查看分销规则
|
||||
function viewDistributorRules(id) {
|
||||
// 跳转至分销规则页面
|
||||
uni.navigateTo({
|
||||
url: '/pages/distribution/profit-rule?id=' + id
|
||||
})
|
||||
}
|
||||
|
||||
// 删除分销员
|
||||
function deleteDistributor(id) {
|
||||
function confirmDelete(id) {
|
||||
uni.showModal({
|
||||
title: '删除分销员',
|
||||
content: '确定要删除该分销员吗?',
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
// 实际项目中应调用接口删除分销员
|
||||
const index = distributorList.value.findIndex(item => item.id === id)
|
||||
if (index !== -1) {
|
||||
distributorList.value.splice(index, 1)
|
||||
}
|
||||
uni.showToast({
|
||||
title: '删除成功',
|
||||
icon: 'success'
|
||||
deleteDistributor(id).then(() => {
|
||||
uni.showToast({
|
||||
title: '删除成功'
|
||||
})
|
||||
loadDistributorList()
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 状态变更
|
||||
function onStatusChange(e) {
|
||||
const value = e.detail.value
|
||||
statusIndex.value = value
|
||||
// 实际项目中应根据状态筛选分销员
|
||||
// filterDistributorList()
|
||||
}
|
||||
|
||||
// 搜索
|
||||
function onSearch() {
|
||||
// 实际项目中应根据关键词搜索分销员
|
||||
// searchDistributorList()
|
||||
loadDistributorList()
|
||||
}
|
||||
|
||||
// 跳转到指定页码
|
||||
@@ -214,7 +212,7 @@
|
||||
}
|
||||
currentPage.value = page
|
||||
// 实际项目中应加载指定页码的分销员
|
||||
// loadDistributorPage(page)
|
||||
loadDistributorList()
|
||||
}
|
||||
|
||||
// 获取姓名首字母
|
||||
@@ -316,17 +314,6 @@
|
||||
padding: 16rpx;
|
||||
}
|
||||
|
||||
.picker {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.picker-text {
|
||||
font-size: 24rpx;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
font-size: 24rpx;
|
||||
color: #303133;
|
||||
@@ -397,6 +384,7 @@
|
||||
display: flex;
|
||||
gap: 16rpx;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.meta-item {
|
||||
@@ -413,16 +401,25 @@
|
||||
}
|
||||
|
||||
.distributor-actions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12rpx;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.action-row {
|
||||
display: flex;
|
||||
gap: 16rpx;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
padding: 8rpx 16rpx;
|
||||
padding: 12rpx 24rpx;
|
||||
border-radius: 8rpx;
|
||||
font-size: 16rpx;
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.edit-btn {
|
||||
@@ -430,6 +427,11 @@
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.rule-btn {
|
||||
background-color: #f0f9eb;
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
background-color: #fef0f0;
|
||||
color: #f56c6c;
|
||||
@@ -490,91 +492,6 @@
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* 平板和大屏响应式 */
|
||||
@media screen and (min-width: 768px) {
|
||||
.distributor-list-container {
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.filter-section {
|
||||
margin: 0 32rpx 24rpx;
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.distributor-list-section {
|
||||
padding: 0 32rpx;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin: 0 32rpx 32rpx;
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 36rpx;
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.filter-label {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.picker-text,
|
||||
.search-input {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.filter-control {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.distributor-item {
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.distributor-avatar {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 50rpx;
|
||||
margin-right: 32rpx;
|
||||
}
|
||||
|
||||
.avatar-placeholder {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
|
||||
.distributor-name {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.distributor-meta {
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
.meta-item {
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
font-size: 18rpx;
|
||||
padding: 12rpx 24rpx;
|
||||
}
|
||||
|
||||
.page-info {
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.page-btn {
|
||||
font-size: 22rpx;
|
||||
padding: 12rpx 24rpx;
|
||||
}
|
||||
|
||||
.add-btn {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 大屏设备响应式 */
|
||||
@media screen and (min-width: 1024px) {
|
||||
|
||||
@@ -1,596 +0,0 @@
|
||||
<template>
|
||||
<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="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="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>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from "vue"
|
||||
|
||||
// 规则表单数据
|
||||
const ruleForm = ref({
|
||||
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(() => {
|
||||
// 实际项目中应从接口获取规则配置
|
||||
// loadRuleConfig()
|
||||
})
|
||||
|
||||
// 返回上一页
|
||||
function goBack() {
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}
|
||||
|
||||
// 保存规则
|
||||
function saveRule() {
|
||||
uni.showLoading({ title: '保存中...' })
|
||||
|
||||
setTimeout(() => {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: '保存成功',
|
||||
icon: 'success'
|
||||
})
|
||||
// 实际项目中应调用接口保存规则配置
|
||||
// saveRuleConfig()
|
||||
}, 1500)
|
||||
}
|
||||
|
||||
// 审核开关变更
|
||||
function onAuditChange(e) {
|
||||
const value = e.detail.value
|
||||
ruleForm.value.needAudit = value
|
||||
}
|
||||
|
||||
// 等级制度开关变更
|
||||
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>
|
||||
/* #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;
|
||||
}
|
||||
|
||||
/* 页面头部 */
|
||||
.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;
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
font-size: 24rpx;
|
||||
color: #409eff;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* 规则配置 */
|
||||
.rule-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;
|
||||
}
|
||||
|
||||
.rule-card {
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 12rpx;
|
||||
padding: 24rpx;
|
||||
}
|
||||
|
||||
.rule-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.rule-row:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
/* 平板和大屏响应式 */
|
||||
@media screen and (min-width: 768px) {
|
||||
.distributor-rule-container {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.rule-section {
|
||||
margin: 0 32rpx 24rpx;
|
||||
padding: 40rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 36rpx;
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.rule-card {
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.rule-row {
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.rule-label {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.switch {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.picker {
|
||||
min-width: 250rpx;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.picker-text {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.form-input {
|
||||
min-width: 200rpx;
|
||||
padding: 20rpx;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.input-suffix {
|
||||
font-size: 26rpx;
|
||||
right: 40rpx;
|
||||
}
|
||||
|
||||
.level-item {
|
||||
padding: 24rpx;
|
||||
}
|
||||
|
||||
.level-title {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.condition-label,
|
||||
.benefit-label {
|
||||
font-size: 20rpx;
|
||||
}
|
||||
|
||||
.condition-value,
|
||||
.benefit-value {
|
||||
font-size: 20rpx;
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 大屏设备响应式 */
|
||||
@media screen and (min-width: 1024px) {
|
||||
.distributor-rule-container {
|
||||
max-width: 1000px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 40rpx;
|
||||
}
|
||||
|
||||
.rule-label {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.picker {
|
||||
min-width: 300rpx;
|
||||
}
|
||||
|
||||
.picker-text {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.form-input {
|
||||
min-width: 250rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.input-suffix {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.level-title {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.condition-label,
|
||||
.benefit-label {
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.condition-value,
|
||||
.benefit-value {
|
||||
font-size: 22rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -149,7 +149,7 @@
|
||||
const unitIndex = ref(0)
|
||||
|
||||
// 包含权益
|
||||
const rights = ref(useTenantStore().tenantInfo?.memberBenefits || [])
|
||||
const rights = ref(useTenantStore().tenantInfo?.memberBenefitList || [])
|
||||
const loading = ref(false)
|
||||
|
||||
// 编辑模式
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
{ value: '1002', label: '摩托车' }
|
||||
]
|
||||
|
||||
const rights = useTenantStore().tenantInfo?.memberBenefits || []
|
||||
const rights = useTenantStore().tenantInfo?.memberBenefitList || []
|
||||
// 生命周期
|
||||
onShow(() => {
|
||||
getMemberList()
|
||||
|
||||
@@ -1,716 +0,0 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="page-body uni-content-info">
|
||||
<view class='cropper-content'>
|
||||
<view v-if="isShowImg" class="uni-corpper" :style="'width:'+cropperInitW+'px;height:'+cropperInitH+'px;background:#000'">
|
||||
<view class="uni-corpper-content" :style="'width:'+cropperW+'px;height:'+cropperH+'px;left:'+cropperL+'px;top:'+cropperT+'px'">
|
||||
<image :src="imageSrc" :style="'width:'+cropperW+'px;height:'+cropperH+'px'"></image>
|
||||
<view class="uni-corpper-crop-box" @touchstart.stop="contentStartMove" @touchmove.stop="contentMoveing" @touchend.stop="contentTouchEnd"
|
||||
:style="'left:'+cutL+'px;top:'+cutT+'px;right:'+cutR+'px;bottom:'+cutB+'px'">
|
||||
<view class="uni-cropper-view-box">
|
||||
<view class="uni-cropper-dashed-h"></view>
|
||||
<view class="uni-cropper-dashed-v"></view>
|
||||
<view class="uni-cropper-line-t" data-drag="top" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
|
||||
<view class="uni-cropper-line-r" data-drag="right" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
|
||||
<view class="uni-cropper-line-b" data-drag="bottom" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
|
||||
<view class="uni-cropper-line-l" data-drag="left" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
|
||||
<view class="uni-cropper-point point-t" data-drag="top" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
|
||||
<view class="uni-cropper-point point-tr" data-drag="topTight"></view>
|
||||
<view class="uni-cropper-point point-r" data-drag="right" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
|
||||
<view class="uni-cropper-point point-rb" data-drag="rightBottom" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
|
||||
<view class="uni-cropper-point point-b" data-drag="bottom" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
|
||||
<view class="uni-cropper-point point-bl" data-drag="bottomLeft"></view>
|
||||
<view class="uni-cropper-point point-l" data-drag="left" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
|
||||
<view class="uni-cropper-point point-lt" data-drag="leftTop"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class='cropper-config'>
|
||||
<button type="primary reverse" @click="getImage" style='margin-top: 30rpx;'> 选择头像 </button>
|
||||
<button type="warn" @click="getImageInfo" style='margin-top: 30rpx;'> 提交 </button>
|
||||
</view>
|
||||
<canvas canvas-id="myCanvas" :style="'position:absolute;border: 1px solid red; width:'+imageW+'px;height:'+imageH+'px;top:-9999px;left:-9999px;'"></canvas>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import config from '@/config'
|
||||
import { useUserStore } from '@/store'
|
||||
import { uploadAvatar } from "@/api/system/user"
|
||||
|
||||
const baseUrl = config.baseUrl
|
||||
let sysInfo = uni.getSystemInfoSync()
|
||||
let SCREEN_WIDTH = sysInfo.screenWidth
|
||||
let PAGE_X, // 手按下的x位置
|
||||
PAGE_Y, // 手按下y的位置
|
||||
PR = sysInfo.pixelRatio, // dpi
|
||||
T_PAGE_X, // 手移动的时候x的位置
|
||||
T_PAGE_Y, // 手移动的时候Y的位置
|
||||
CUT_L, // 初始化拖拽元素的left值
|
||||
CUT_T, // 初始化拖拽元素的top值
|
||||
CUT_R, // 初始化拖拽元素的
|
||||
CUT_B, // 初始化拖拽元素的
|
||||
CUT_W, // 初始化拖拽元素的宽度
|
||||
CUT_H, // 初始化拖拽元素的高度
|
||||
IMG_RATIO, // 图片比例
|
||||
IMG_REAL_W, // 图片实际的宽度
|
||||
IMG_REAL_H, // 图片实际的高度
|
||||
DRAFG_MOVE_RATIO = 1, //移动时候的比例,
|
||||
INIT_DRAG_POSITION = 100, // 初始化屏幕宽度和裁剪区域的宽度之差,用于设置初始化裁剪的宽度
|
||||
DRAW_IMAGE_W = sysInfo.screenWidth // 设置生成的图片宽度
|
||||
|
||||
export default {
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data() {
|
||||
return {
|
||||
imageSrc: useUserStore().avatar,
|
||||
isShowImg: false,
|
||||
// 初始化的宽高
|
||||
cropperInitW: SCREEN_WIDTH,
|
||||
cropperInitH: SCREEN_WIDTH,
|
||||
// 动态的宽高
|
||||
cropperW: SCREEN_WIDTH,
|
||||
cropperH: SCREEN_WIDTH,
|
||||
// 动态的left top值
|
||||
cropperL: 0,
|
||||
cropperT: 0,
|
||||
|
||||
transL: 0,
|
||||
transT: 0,
|
||||
|
||||
// 图片缩放值
|
||||
scaleP: 0,
|
||||
imageW: 0,
|
||||
imageH: 0,
|
||||
|
||||
// 裁剪框 宽高
|
||||
cutL: 0,
|
||||
cutT: 0,
|
||||
cutB: SCREEN_WIDTH,
|
||||
cutR: '100%',
|
||||
qualityWidth: DRAW_IMAGE_W,
|
||||
innerAspectRadio: DRAFG_MOVE_RATIO
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady: function () {
|
||||
this.loadImage()
|
||||
},
|
||||
methods: {
|
||||
setData: function (obj) {
|
||||
let that = this
|
||||
Object.keys(obj).forEach(function (key) {
|
||||
that.$set(that.$data, key, obj[key])
|
||||
})
|
||||
},
|
||||
getImage: function () {
|
||||
var _this = this
|
||||
uni.chooseImage({
|
||||
success: function (res) {
|
||||
_this.setData({
|
||||
imageSrc: res.tempFilePaths[0],
|
||||
})
|
||||
_this.loadImage()
|
||||
},
|
||||
})
|
||||
},
|
||||
loadImage: function () {
|
||||
var _this = this
|
||||
|
||||
uni.getImageInfo({
|
||||
src: _this.imageSrc,
|
||||
success: function success(res) {
|
||||
IMG_RATIO = 1 / 1
|
||||
if (IMG_RATIO >= 1) {
|
||||
IMG_REAL_W = SCREEN_WIDTH
|
||||
IMG_REAL_H = SCREEN_WIDTH / IMG_RATIO
|
||||
} else {
|
||||
IMG_REAL_W = SCREEN_WIDTH * IMG_RATIO
|
||||
IMG_REAL_H = SCREEN_WIDTH
|
||||
}
|
||||
let minRange = IMG_REAL_W > IMG_REAL_H ? IMG_REAL_W : IMG_REAL_H
|
||||
INIT_DRAG_POSITION = minRange > INIT_DRAG_POSITION ? INIT_DRAG_POSITION : minRange
|
||||
// 根据图片的宽高显示不同的效果 保证图片可以正常显示
|
||||
if (IMG_RATIO >= 1) {
|
||||
let cutT = Math.ceil((SCREEN_WIDTH / IMG_RATIO - (SCREEN_WIDTH / IMG_RATIO - INIT_DRAG_POSITION)) / 2)
|
||||
let cutB = cutT
|
||||
let cutL = Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH + INIT_DRAG_POSITION) / 2)
|
||||
let cutR = cutL
|
||||
_this.setData({
|
||||
cropperW: SCREEN_WIDTH,
|
||||
cropperH: SCREEN_WIDTH / IMG_RATIO,
|
||||
// 初始化left right
|
||||
cropperL: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH) / 2),
|
||||
cropperT: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH / IMG_RATIO) / 2),
|
||||
cutL: cutL,
|
||||
cutT: cutT,
|
||||
cutR: cutR,
|
||||
cutB: cutB,
|
||||
// 图片缩放值
|
||||
imageW: IMG_REAL_W,
|
||||
imageH: IMG_REAL_H,
|
||||
scaleP: IMG_REAL_W / SCREEN_WIDTH,
|
||||
qualityWidth: DRAW_IMAGE_W,
|
||||
innerAspectRadio: IMG_RATIO
|
||||
})
|
||||
} else {
|
||||
let cutL = Math.ceil((SCREEN_WIDTH * IMG_RATIO - (SCREEN_WIDTH * IMG_RATIO)) / 2)
|
||||
let cutR = cutL
|
||||
let cutT = Math.ceil((SCREEN_WIDTH - INIT_DRAG_POSITION) / 2)
|
||||
let cutB = cutT
|
||||
_this.setData({
|
||||
cropperW: SCREEN_WIDTH * IMG_RATIO,
|
||||
cropperH: SCREEN_WIDTH,
|
||||
// 初始化left right
|
||||
cropperL: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH * IMG_RATIO) / 2),
|
||||
cropperT: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH) / 2),
|
||||
|
||||
cutL: cutL,
|
||||
cutT: cutT,
|
||||
cutR: cutR,
|
||||
cutB: cutB,
|
||||
// 图片缩放值
|
||||
imageW: IMG_REAL_W,
|
||||
imageH: IMG_REAL_H,
|
||||
scaleP: IMG_REAL_W / SCREEN_WIDTH,
|
||||
qualityWidth: DRAW_IMAGE_W,
|
||||
innerAspectRadio: IMG_RATIO
|
||||
})
|
||||
}
|
||||
_this.setData({
|
||||
isShowImg: true
|
||||
})
|
||||
uni.hideLoading()
|
||||
}
|
||||
})
|
||||
},
|
||||
// 拖动时候触发的touchStart事件
|
||||
contentStartMove(e) {
|
||||
PAGE_X = e.touches[0].pageX
|
||||
PAGE_Y = e.touches[0].pageY
|
||||
},
|
||||
|
||||
// 拖动时候触发的touchMove事件
|
||||
contentMoveing(e) {
|
||||
var _this = this
|
||||
var dragLengthX = (PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
|
||||
var dragLengthY = (PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
|
||||
// 左移
|
||||
if (dragLengthX > 0) {
|
||||
if (this.cutL - dragLengthX < 0) dragLengthX = this.cutL
|
||||
} else {
|
||||
if (this.cutR + dragLengthX < 0) dragLengthX = -this.cutR
|
||||
}
|
||||
|
||||
if (dragLengthY > 0) {
|
||||
if (this.cutT - dragLengthY < 0) dragLengthY = this.cutT
|
||||
} else {
|
||||
if (this.cutB + dragLengthY < 0) dragLengthY = -this.cutB
|
||||
}
|
||||
this.setData({
|
||||
cutL: this.cutL - dragLengthX,
|
||||
cutT: this.cutT - dragLengthY,
|
||||
cutR: this.cutR + dragLengthX,
|
||||
cutB: this.cutB + dragLengthY
|
||||
})
|
||||
|
||||
PAGE_X = e.touches[0].pageX
|
||||
PAGE_Y = e.touches[0].pageY
|
||||
},
|
||||
|
||||
contentTouchEnd() {
|
||||
|
||||
},
|
||||
|
||||
// 获取图片
|
||||
getImageInfo() {
|
||||
var _this = this
|
||||
uni.showLoading({
|
||||
title: '图片生成中...',
|
||||
})
|
||||
// 将图片写入画布
|
||||
const ctx = uni.createCanvasContext('myCanvas')
|
||||
ctx.drawImage(_this.imageSrc, 0, 0, IMG_REAL_W, IMG_REAL_H)
|
||||
ctx.draw(true, () => {
|
||||
// 获取画布要裁剪的位置和宽度 均为百分比 * 画布中图片的宽度 保证了在微信小程序中裁剪的图片模糊 位置不对的问题 canvasT = (_this.cutT / _this.cropperH) * (_this.imageH / pixelRatio)
|
||||
var canvasW = ((_this.cropperW - _this.cutL - _this.cutR) / _this.cropperW) * IMG_REAL_W
|
||||
var canvasH = ((_this.cropperH - _this.cutT - _this.cutB) / _this.cropperH) * IMG_REAL_H
|
||||
var canvasL = (_this.cutL / _this.cropperW) * IMG_REAL_W
|
||||
var canvasT = (_this.cutT / _this.cropperH) * IMG_REAL_H
|
||||
uni.canvasToTempFilePath({
|
||||
x: canvasL,
|
||||
y: canvasT,
|
||||
width: canvasW,
|
||||
height: canvasH,
|
||||
destWidth: canvasW,
|
||||
destHeight: canvasH,
|
||||
quality: 0.5,
|
||||
canvasId: 'myCanvas',
|
||||
success: function (res) {
|
||||
uni.hideLoading()
|
||||
let data = {name: 'avatarfile', filePath: res.tempFilePath}
|
||||
uploadAvatar(data).then(response => {
|
||||
useUserStore().SET_AVATAR(baseUrl + response.imgUrl)
|
||||
uni.showToast({ title: "修改成功", icon: 'success' })
|
||||
uni.navigateBack()
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
// 设置大小的时候触发的touchStart事件
|
||||
dragStart(e) {
|
||||
T_PAGE_X = e.touches[0].pageX
|
||||
T_PAGE_Y = e.touches[0].pageY
|
||||
CUT_L = this.cutL
|
||||
CUT_R = this.cutR
|
||||
CUT_B = this.cutB
|
||||
CUT_T = this.cutT
|
||||
},
|
||||
|
||||
// 设置大小的时候触发的touchMove事件
|
||||
dragMove(e) {
|
||||
var _this = this
|
||||
var dragType = e.target.dataset.drag
|
||||
switch (dragType) {
|
||||
case 'right':
|
||||
var dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
|
||||
if (CUT_R + dragLength < 0) dragLength = -CUT_R
|
||||
this.setData({
|
||||
cutR: CUT_R + dragLength
|
||||
})
|
||||
break
|
||||
case 'left':
|
||||
var dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
|
||||
if (CUT_L - dragLength < 0) dragLength = CUT_L
|
||||
if ((CUT_L - dragLength) > (this.cropperW - this.cutR)) dragLength = CUT_L - (this.cropperW - this.cutR)
|
||||
this.setData({
|
||||
cutL: CUT_L - dragLength
|
||||
})
|
||||
break
|
||||
case 'top':
|
||||
var dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
|
||||
if (CUT_T - dragLength < 0) dragLength = CUT_T
|
||||
if ((CUT_T - dragLength) > (this.cropperH - this.cutB)) dragLength = CUT_T - (this.cropperH - this.cutB)
|
||||
this.setData({
|
||||
cutT: CUT_T - dragLength
|
||||
})
|
||||
break
|
||||
case 'bottom':
|
||||
var dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
|
||||
if (CUT_B + dragLength < 0) dragLength = -CUT_B
|
||||
this.setData({
|
||||
cutB: CUT_B + dragLength
|
||||
})
|
||||
break
|
||||
case 'rightBottom':
|
||||
var dragLengthX = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
|
||||
var dragLengthY = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
|
||||
|
||||
if (CUT_B + dragLengthY < 0) dragLengthY = -CUT_B
|
||||
if (CUT_R + dragLengthX < 0) dragLengthX = -CUT_R
|
||||
let cutB = CUT_B + dragLengthY
|
||||
let cutR = CUT_R + dragLengthX
|
||||
|
||||
this.setData({
|
||||
cutB: cutB,
|
||||
cutR: cutR
|
||||
})
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.page-body {
|
||||
padding: 24rpx;
|
||||
}
|
||||
|
||||
.cropper-content {
|
||||
min-height: 750rpx;
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.cropper-config {
|
||||
padding: 20rpx 40rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.cropper-config button {
|
||||
font-size: 28rpx;
|
||||
height: 88rpx;
|
||||
margin-top: 30rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.uni-corpper {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
-webkit-touch-callout: none;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.uni-corpper-content {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.uni-corpper-content image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-width: 0 !important;
|
||||
max-width: none !important;
|
||||
height: 100%;
|
||||
min-height: 0 !important;
|
||||
max-height: none !important;
|
||||
image-orientation: 0deg !important;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* 移动图片效果 */
|
||||
.uni-cropper-drag-box {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
cursor: move;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* 内部的信息 */
|
||||
.uni-corpper-crop-box {
|
||||
position: absolute;
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.uni-corpper-crop-box .uni-cropper-view-box {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: visible;
|
||||
outline: 1rpx solid #69f;
|
||||
outline-color: rgba(102, 153, 255, .75)
|
||||
}
|
||||
|
||||
/* 横向虚线 */
|
||||
.uni-cropper-dashed-h {
|
||||
position: absolute;
|
||||
top: 33.33333333%;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 33.33333333%;
|
||||
border-top: 1rpx dashed rgba(255, 255, 255, 0.5);
|
||||
border-bottom: 1rpx dashed rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
/* 纵向虚线 */
|
||||
.uni-cropper-dashed-v {
|
||||
position: absolute;
|
||||
left: 33.33333333%;
|
||||
top: 0;
|
||||
width: 33.33333333%;
|
||||
height: 100%;
|
||||
border-left: 1rpx dashed rgba(255, 255, 255, 0.5);
|
||||
border-right: 1rpx dashed rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
/* 四个方向的线 为了之后的拖动事件*/
|
||||
.uni-cropper-line-t {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 100%;
|
||||
background-color: #69f;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 1rpx;
|
||||
opacity: 0.1;
|
||||
cursor: n-resize;
|
||||
}
|
||||
|
||||
.uni-cropper-line-t::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0rpx;
|
||||
width: 100%;
|
||||
-webkit-transform: translate3d(0, -50%, 0);
|
||||
transform: translate3d(0, -50%, 0);
|
||||
bottom: 0;
|
||||
height: 41rpx;
|
||||
background: transparent;
|
||||
z-index: 11;
|
||||
}
|
||||
|
||||
.uni-cropper-line-r {
|
||||
position: absolute;
|
||||
display: block;
|
||||
background-color: #69f;
|
||||
top: 0;
|
||||
right: 0rpx;
|
||||
width: 1rpx;
|
||||
opacity: 0.1;
|
||||
height: 100%;
|
||||
cursor: e-resize;
|
||||
}
|
||||
|
||||
.uni-cropper-line-r::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
width: 41rpx;
|
||||
-webkit-transform: translate3d(-50%, 0, 0);
|
||||
transform: translate3d(-50%, 0, 0);
|
||||
bottom: 0;
|
||||
height: 100%;
|
||||
background: transparent;
|
||||
z-index: 11;
|
||||
}
|
||||
|
||||
.uni-cropper-line-b {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 100%;
|
||||
background-color: #69f;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 1rpx;
|
||||
opacity: 0.1;
|
||||
cursor: s-resize;
|
||||
}
|
||||
|
||||
.uni-cropper-line-b::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0rpx;
|
||||
width: 100%;
|
||||
-webkit-transform: translate3d(0, -50%, 0);
|
||||
transform: translate3d(0, -50%, 0);
|
||||
bottom: 0;
|
||||
height: 41rpx;
|
||||
background: transparent;
|
||||
z-index: 11;
|
||||
}
|
||||
|
||||
.uni-cropper-line-l {
|
||||
position: absolute;
|
||||
display: block;
|
||||
background-color: #69f;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 1rpx;
|
||||
opacity: 0.1;
|
||||
height: 100%;
|
||||
cursor: w-resize;
|
||||
}
|
||||
|
||||
.uni-cropper-line-l::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
width: 41rpx;
|
||||
-webkit-transform: translate3d(-50%, 0, 0);
|
||||
transform: translate3d(-50%, 0, 0);
|
||||
bottom: 0;
|
||||
height: 100%;
|
||||
background: transparent;
|
||||
z-index: 11;
|
||||
}
|
||||
|
||||
.uni-cropper-point {
|
||||
width: 5rpx;
|
||||
height: 5rpx;
|
||||
background-color: #69f;
|
||||
opacity: .75;
|
||||
position: absolute;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.point-t {
|
||||
top: -3rpx;
|
||||
left: 50%;
|
||||
margin-left: -3rpx;
|
||||
cursor: n-resize;
|
||||
}
|
||||
|
||||
.point-tr {
|
||||
top: -3rpx;
|
||||
left: 100%;
|
||||
margin-left: -3rpx;
|
||||
cursor: n-resize;
|
||||
}
|
||||
|
||||
.point-r {
|
||||
top: 50%;
|
||||
left: 100%;
|
||||
margin-left: -3rpx;
|
||||
margin-top: -3rpx;
|
||||
cursor: n-resize;
|
||||
}
|
||||
|
||||
.point-rb {
|
||||
left: 100%;
|
||||
top: 100%;
|
||||
-webkit-transform: translate3d(-50%, -50%, 0);
|
||||
transform: translate3d(-50%, -50%, 0);
|
||||
cursor: n-resize;
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
background-color: #69f;
|
||||
position: absolute;
|
||||
z-index: 1112;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.point-b {
|
||||
left: 50%;
|
||||
top: 100%;
|
||||
margin-left: -3rpx;
|
||||
margin-top: -3rpx;
|
||||
cursor: n-resize;
|
||||
}
|
||||
|
||||
.point-bl {
|
||||
left: 0%;
|
||||
top: 100%;
|
||||
margin-left: -3rpx;
|
||||
margin-top: -3rpx;
|
||||
cursor: n-resize;
|
||||
}
|
||||
|
||||
.point-l {
|
||||
left: 0%;
|
||||
top: 50%;
|
||||
margin-left: -3rpx;
|
||||
margin-top: -3rpx;
|
||||
cursor: n-resize;
|
||||
}
|
||||
|
||||
.point-lt {
|
||||
left: 0%;
|
||||
top: 0%;
|
||||
margin-left: -3rpx;
|
||||
margin-top: -3rpx;
|
||||
cursor: n-resize;
|
||||
}
|
||||
|
||||
/* 裁剪框预览内容 */
|
||||
.uni-cropper-viewer {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.uni-cropper-viewer image {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* 平板响应式 */
|
||||
@media screen and (min-width: 768px) {
|
||||
.container {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.page-body {
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.cropper-content {
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 6rpx 24rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.cropper-config {
|
||||
padding: 40rpx;
|
||||
}
|
||||
|
||||
.cropper-config button {
|
||||
font-size: 32rpx;
|
||||
height: 96rpx;
|
||||
margin-top: 40rpx;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.uni-cropper-point {
|
||||
width: 8rpx;
|
||||
height: 8rpx;
|
||||
}
|
||||
|
||||
.point-rb {
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 大屏设备响应式 */
|
||||
@media screen and (min-width: 1024px) {
|
||||
.container {
|
||||
max-width: 1000px;
|
||||
}
|
||||
|
||||
.page-body {
|
||||
padding: 48rpx;
|
||||
}
|
||||
|
||||
.cropper-content {
|
||||
border-radius: 24rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.cropper-config {
|
||||
padding: 60rpx;
|
||||
}
|
||||
|
||||
.cropper-config button {
|
||||
font-size: 36rpx;
|
||||
height: 112rpx;
|
||||
margin-top: 50rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.uni-cropper-point {
|
||||
width: 10rpx;
|
||||
height: 10rpx;
|
||||
}
|
||||
|
||||
.point-rb {
|
||||
width: 52rpx;
|
||||
height: 52rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,198 +0,0 @@
|
||||
<template>
|
||||
<view class="help-container">
|
||||
<view v-for="(item, findex) in list" :key="findex" :title="item.title" class="list-title">
|
||||
<view class="text-title">
|
||||
<view :class="item.icon"></view>{{ item.title }}
|
||||
</view>
|
||||
<view class="childList">
|
||||
<view v-for="(child, zindex) in item.childList" :key="zindex" class="question" hover-class="hover"
|
||||
@click="handleText(child)">
|
||||
<view class="text-item">{{ child.title }}</view>
|
||||
<view class="line" v-if="zindex !== item.childList.length - 1"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, getCurrentInstance } from "vue"
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const list = ref([{
|
||||
icon: 'iconfont icon-github',
|
||||
title: '若依问题',
|
||||
childList: [{
|
||||
title: '若依开源吗?',
|
||||
content: '开源'
|
||||
}, {
|
||||
title: '若依可以商用吗?',
|
||||
content: '可以'
|
||||
}, {
|
||||
title: '若依官网地址多少?',
|
||||
content: 'http://ruoyi.vip'
|
||||
}, {
|
||||
title: '若依文档地址多少?',
|
||||
content: 'http://doc.ruoyi.vip'
|
||||
}]
|
||||
},
|
||||
{
|
||||
icon: 'iconfont icon-help',
|
||||
title: '其他问题',
|
||||
childList: [{
|
||||
title: '如何退出登录?',
|
||||
content: '请点击[我的] - [应用设置] - [退出登录]即可退出登录',
|
||||
}, {
|
||||
title: '如何修改用户头像?',
|
||||
content: '请点击[我的] - [选择头像] - [点击提交]即可更换用户头像',
|
||||
}, {
|
||||
title: '如何修改登录密码?',
|
||||
content: '请点击[我的] - [应用设置] - [修改密码]即可修改登录密码',
|
||||
}]
|
||||
}])
|
||||
|
||||
function handleText(item) {
|
||||
proxy.$tab.navigateTo(`/pages/common/textview/index?title=${item.title}&content=${item.content}`)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.help-container {
|
||||
min-height: 100vh;
|
||||
margin-bottom: 100rpx;
|
||||
padding: 24rpx;
|
||||
}
|
||||
|
||||
.list-title {
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.text-title {
|
||||
color: #303133;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
margin-left: 10rpx;
|
||||
line-height: 1.4;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.iconfont {
|
||||
font-size: 16px;
|
||||
margin-right: 10rpx;
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
|
||||
.childList {
|
||||
background: #ffffff;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
|
||||
border-radius: 16rpx;
|
||||
margin-top: 16rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.question {
|
||||
color: #606266;
|
||||
font-size: 28rpx;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.question:hover {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.text-item {
|
||||
font-size: 28rpx;
|
||||
padding: 24rpx;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
height: 1rpx;
|
||||
background-color: #F5F5F5;
|
||||
}
|
||||
|
||||
/* 平板响应式 */
|
||||
@media screen and (min-width: 768px) {
|
||||
.help-container {
|
||||
max-width: 900px;
|
||||
margin: 0 auto 100rpx;
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
padding: 40rpx;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.list-title {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.text-title {
|
||||
font-size: 36rpx;
|
||||
margin-left: 16rpx;
|
||||
|
||||
.iconfont {
|
||||
font-size: 20px;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.childList {
|
||||
margin-top: 20rpx;
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 6rpx 24rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.question {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.text-item {
|
||||
font-size: 32rpx;
|
||||
padding: 32rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 大屏设备响应式 */
|
||||
@media screen and (min-width: 1024px) {
|
||||
.help-container {
|
||||
max-width: 1000px;
|
||||
padding: 60rpx;
|
||||
}
|
||||
|
||||
.list-title {
|
||||
margin-bottom: 50rpx;
|
||||
}
|
||||
|
||||
.text-title {
|
||||
font-size: 40rpx;
|
||||
margin-left: 20rpx;
|
||||
|
||||
.iconfont {
|
||||
font-size: 24px;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.childList {
|
||||
margin-top: 24rpx;
|
||||
border-radius: 24rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.question {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
|
||||
.text-item {
|
||||
font-size: 36rpx;
|
||||
padding: 40rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,292 +0,0 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="example">
|
||||
<uni-forms ref="form" :model="user" labelWidth="80px">
|
||||
<uni-forms-item label="用户昵称" name="nickName">
|
||||
<uni-easyinput v-model="user.nickName" placeholder="请输入昵称" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="手机号码" name="phonenumber">
|
||||
<uni-easyinput v-model="user.phonenumber" placeholder="请输入手机号码" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="邮箱" name="email">
|
||||
<uni-easyinput v-model="user.email" placeholder="请输入邮箱" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="性别" name="sex" required>
|
||||
<uni-data-checkbox v-model="user.sex" :localdata="sexs" />
|
||||
</uni-forms-item>
|
||||
</uni-forms>
|
||||
<button type="primary" @click="submit">提交</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getUserProfile } from "@/api/system/user"
|
||||
import { updateUserProfile } from "@/api/system/user"
|
||||
import { ref , getCurrentInstance } from "vue"
|
||||
import { onReady } from "@dcloudio/uni-app"
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const user = ref({
|
||||
nickName: "",
|
||||
phonenumber: "",
|
||||
email: "",
|
||||
sex: ""
|
||||
})
|
||||
const sexs = [{
|
||||
text: '男',
|
||||
value: "0"
|
||||
}, {
|
||||
text: '女',
|
||||
value: "1"
|
||||
}]
|
||||
const rules = ref({
|
||||
nickName: {
|
||||
rules: [{
|
||||
required: true,
|
||||
errorMessage: '用户昵称不能为空'
|
||||
}]
|
||||
},
|
||||
phonenumber: {
|
||||
rules: [{
|
||||
required: true,
|
||||
errorMessage: '手机号码不能为空'
|
||||
}, {
|
||||
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
|
||||
errorMessage: '请输入正确的手机号码'
|
||||
}]
|
||||
},
|
||||
email: {
|
||||
rules: [{
|
||||
required: true,
|
||||
errorMessage: '邮箱地址不能为空'
|
||||
}, {
|
||||
format: 'email',
|
||||
errorMessage: '请输入正确的邮箱地址'
|
||||
}]
|
||||
}
|
||||
})
|
||||
|
||||
function getUser() {
|
||||
getUserProfile().then(response => {
|
||||
user.value = response.data
|
||||
})
|
||||
}
|
||||
|
||||
function submit(ref) {
|
||||
proxy.$refs.form.validate().then(res => {
|
||||
updateUserProfile(user.value).then(response => {
|
||||
proxy.$modal.msgSuccess("修改成功")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
onReady(() => {
|
||||
proxy.$refs.form.setRules(rules.value)
|
||||
})
|
||||
|
||||
getUser()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.example {
|
||||
background-color: #fff;
|
||||
padding: 24rpx;
|
||||
margin: 16rpx;
|
||||
border-radius: 16rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
/* 表单样式 */
|
||||
:deep(.uni-forms) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.uni-forms-item) {
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-forms-label) {
|
||||
font-size: 28rpx;
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
:deep(.uni-easyinput__input) {
|
||||
font-size: 28rpx;
|
||||
height: 88rpx;
|
||||
padding: 0 24rpx;
|
||||
border: 1rpx solid #dcdfe6;
|
||||
border-radius: 8rpx;
|
||||
color: #303133;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
:deep(.uni-easyinput__input:focus) {
|
||||
border-color: #409eff;
|
||||
box-shadow: 0 0 0 2rpx rgba(64, 158, 255, 0.2);
|
||||
}
|
||||
|
||||
:deep(.uni-data-checkbox) {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-data-checkbox__list) {
|
||||
margin-top: 12rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-data-checkbox__item) {
|
||||
margin-right: 32rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
:deep(.uni-data-checkbox__input) {
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
button {
|
||||
font-size: 28rpx;
|
||||
height: 88rpx;
|
||||
margin-top: 40rpx;
|
||||
border-radius: 12rpx;
|
||||
background-color: #409eff;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #66b1ff;
|
||||
}
|
||||
|
||||
button:active {
|
||||
background-color: #3a8ee6;
|
||||
}
|
||||
|
||||
/* 平板响应式 */
|
||||
@media screen and (min-width: 768px) {
|
||||
.container {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.example {
|
||||
margin: 24rpx;
|
||||
padding: 40rpx;
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 6rpx 24rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 表单样式 */
|
||||
:deep(.uni-forms-item) {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-forms-label) {
|
||||
font-size: 32rpx;
|
||||
width: 140px;
|
||||
}
|
||||
|
||||
:deep(.uni-easyinput__input) {
|
||||
font-size: 32rpx;
|
||||
height: 96rpx;
|
||||
padding: 0 32rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-data-checkbox) {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-data-checkbox__list) {
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-data-checkbox__item) {
|
||||
margin-right: 40rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-data-checkbox__input) {
|
||||
width: 28rpx;
|
||||
height: 28rpx;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
button {
|
||||
font-size: 32rpx;
|
||||
height: 96rpx;
|
||||
margin-top: 50rpx;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 大屏设备响应式 */
|
||||
@media screen and (min-width: 1024px) {
|
||||
.container {
|
||||
max-width: 1000px;
|
||||
}
|
||||
|
||||
.example {
|
||||
margin: 32rpx;
|
||||
padding: 48rpx;
|
||||
border-radius: 24rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
/* 表单样式 */
|
||||
:deep(.uni-forms-item) {
|
||||
margin-bottom: 48rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-forms-label) {
|
||||
font-size: 36rpx;
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
:deep(.uni-easyinput__input) {
|
||||
font-size: 36rpx;
|
||||
height: 112rpx;
|
||||
padding: 0 40rpx;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-data-checkbox) {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-data-checkbox__list) {
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-data-checkbox__item) {
|
||||
margin-right: 50rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-data-checkbox__input) {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
button {
|
||||
font-size: 36rpx;
|
||||
height: 112rpx;
|
||||
margin-top: 60rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,146 +0,0 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<uni-list>
|
||||
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'person-filled'}" title="昵称" :rightText="user.nickName" />
|
||||
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'phone-filled'}" title="手机号码" :rightText="user.phonenumber" />
|
||||
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'email-filled'}" title="邮箱" :rightText="user.email" />
|
||||
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'auth-filled'}" title="岗位" :rightText="postGroup" />
|
||||
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'staff-filled'}" title="角色" :rightText="roleGroup" />
|
||||
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'calendar-filled'}" title="创建日期" :rightText="user.createTime" />
|
||||
</uni-list>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getUserProfile } from "@/api/system/user"
|
||||
import { ref, reactive } from "vue"
|
||||
|
||||
const user = ref({})
|
||||
const roleGroup = ref("")
|
||||
const postGroup = ref("")
|
||||
|
||||
function getUser() {
|
||||
getUserProfile().then(response => {
|
||||
user.value = response.data
|
||||
roleGroup.value = response.roleGroup
|
||||
postGroup.value = response.postGroup
|
||||
})
|
||||
}
|
||||
|
||||
getUser()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* 列表样式 */
|
||||
:deep(.uni-list) {
|
||||
background-color: #fff;
|
||||
margin: 16rpx;
|
||||
border-radius: 16rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:deep(.uni-list-item) {
|
||||
padding: 28rpx;
|
||||
font-size: 28rpx;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
:deep(.uni-list-item:last-child) {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
:deep(.uni-list-item__content) {
|
||||
font-size: 28rpx;
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
:deep(.uni-list-item__extra) {
|
||||
font-size: 26rpx;
|
||||
color: #606266;
|
||||
text-align: right;
|
||||
flex: 1;
|
||||
margin-left: 24rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-list-item__icon) {
|
||||
font-size: 32rpx;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
/* 平板响应式 */
|
||||
@media screen and (min-width: 768px) {
|
||||
.container {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 列表样式 */
|
||||
:deep(.uni-list) {
|
||||
margin: 24rpx;
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 6rpx 24rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
:deep(.uni-list-item) {
|
||||
padding: 32rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-list-item__content) {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-list-item__extra) {
|
||||
font-size: 30rpx;
|
||||
margin-left: 32rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-list-item__icon) {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 大屏设备响应式 */
|
||||
@media screen and (min-width: 1024px) {
|
||||
.container {
|
||||
max-width: 1000px;
|
||||
}
|
||||
|
||||
/* 列表样式 */
|
||||
:deep(.uni-list) {
|
||||
margin: 32rpx;
|
||||
border-radius: 24rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
:deep(.uni-list-item) {
|
||||
padding: 40rpx;
|
||||
font-size: 36rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-list-item__content) {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-list-item__extra) {
|
||||
font-size: 34rpx;
|
||||
margin-left: 40rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-list-item__icon) {
|
||||
font-size: 40rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -105,17 +105,6 @@
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}
|
||||
|
||||
// 获取性别索引
|
||||
function getGenderIndex() {
|
||||
return genders.indexOf(userInfo.value.gender)
|
||||
}
|
||||
|
||||
// 处理性别变更
|
||||
function onGenderChange(e) {
|
||||
const index = e.detail.value
|
||||
userInfo.value.gender = genders[index]
|
||||
}
|
||||
|
||||
// 选择头像
|
||||
function chooseAvatar() {
|
||||
uni.chooseImage({
|
||||
|
||||
@@ -1,211 +0,0 @@
|
||||
<template>
|
||||
<view class="pwd-retrieve-container">
|
||||
<uni-forms ref="form" :value="user" labelWidth="80px">
|
||||
<uni-forms-item name="oldPassword" label="旧密码">
|
||||
<uni-easyinput type="password" v-model="user.oldPassword" placeholder="请输入旧密码" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item name="newPassword" label="新密码">
|
||||
<uni-easyinput type="password" v-model="user.newPassword" placeholder="请输入新密码" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item name="confirmPassword" label="确认密码">
|
||||
<uni-easyinput type="password" v-model="user.confirmPassword" placeholder="请确认新密码" />
|
||||
</uni-forms-item>
|
||||
<button type="primary" @click="submit">提交</button>
|
||||
</uni-forms>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { updateUserPwd } from "@/api/system/user"
|
||||
import { ref, reactive , getCurrentInstance } from "vue"
|
||||
import { onReady } from "@dcloudio/uni-app"
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const user = reactive({
|
||||
oldPassword: undefined,
|
||||
newPassword: undefined,
|
||||
confirmPassword: undefined
|
||||
})
|
||||
const rules = ref({
|
||||
oldPassword: {
|
||||
rules: [{
|
||||
required: true,
|
||||
errorMessage: '旧密码不能为空'
|
||||
}]
|
||||
},
|
||||
newPassword: {
|
||||
rules: [{
|
||||
required: true,
|
||||
errorMessage: '新密码不能为空',
|
||||
}, {
|
||||
minLength: 6,
|
||||
maxLength: 20,
|
||||
errorMessage: '长度在 6 到 20 个字符'
|
||||
}]
|
||||
},
|
||||
confirmPassword: {
|
||||
rules: [{
|
||||
required: true,
|
||||
errorMessage: '确认密码不能为空'
|
||||
}, {
|
||||
validateFunction: (rule, value, data) => user.newPassword === value,
|
||||
errorMessage: '两次输入的密码不一致'
|
||||
}]
|
||||
}
|
||||
})
|
||||
|
||||
onReady(() => {
|
||||
proxy.$refs.form.setRules(rules.value)
|
||||
})
|
||||
|
||||
function submit() {
|
||||
proxy.$refs.form.validate().then(res => {
|
||||
updateUserPwd(user.oldPassword, user.newPassword).then(response => {
|
||||
proxy.$modal.msgSuccess("修改成功")
|
||||
})
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.pwd-retrieve-container {
|
||||
min-height: 100vh;
|
||||
padding: 24rpx;
|
||||
}
|
||||
|
||||
/* 表单样式 */
|
||||
:deep(.uni-forms) {
|
||||
background-color: #fff;
|
||||
padding: 32rpx;
|
||||
border-radius: 16rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
:deep(.uni-forms-item) {
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-forms-label) {
|
||||
font-size: 28rpx;
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
:deep(.uni-easyinput__input) {
|
||||
font-size: 28rpx;
|
||||
height: 88rpx;
|
||||
padding: 0 24rpx;
|
||||
border: 1rpx solid #dcdfe6;
|
||||
border-radius: 8rpx;
|
||||
color: #303133;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
:deep(.uni-easyinput__input:focus) {
|
||||
border-color: #409eff;
|
||||
box-shadow: 0 0 0 2rpx rgba(64, 158, 255, 0.2);
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
button {
|
||||
font-size: 28rpx;
|
||||
height: 88rpx;
|
||||
margin-top: 40rpx;
|
||||
border-radius: 12rpx;
|
||||
background-color: #409eff;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #66b1ff;
|
||||
}
|
||||
|
||||
button:active {
|
||||
background-color: #3a8ee6;
|
||||
}
|
||||
|
||||
/* 平板响应式 */
|
||||
@media screen and (min-width: 768px) {
|
||||
.pwd-retrieve-container {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
padding: 40rpx;
|
||||
}
|
||||
|
||||
/* 表单样式 */
|
||||
:deep(.uni-forms) {
|
||||
padding: 40rpx;
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 6rpx 24rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
:deep(.uni-forms-item) {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-forms-label) {
|
||||
font-size: 32rpx;
|
||||
width: 140px;
|
||||
}
|
||||
|
||||
:deep(.uni-easyinput__input) {
|
||||
font-size: 32rpx;
|
||||
height: 96rpx;
|
||||
padding: 0 32rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
button {
|
||||
font-size: 32rpx;
|
||||
height: 96rpx;
|
||||
margin-top: 50rpx;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 大屏设备响应式 */
|
||||
@media screen and (min-width: 1024px) {
|
||||
.pwd-retrieve-container {
|
||||
max-width: 1000px;
|
||||
padding: 60rpx;
|
||||
}
|
||||
|
||||
/* 表单样式 */
|
||||
:deep(.uni-forms) {
|
||||
padding: 48rpx;
|
||||
border-radius: 24rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
:deep(.uni-forms-item) {
|
||||
margin-bottom: 48rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-forms-label) {
|
||||
font-size: 36rpx;
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
:deep(.uni-easyinput__input) {
|
||||
font-size: 36rpx;
|
||||
height: 112rpx;
|
||||
padding: 0 40rpx;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
button {
|
||||
font-size: 36rpx;
|
||||
height: 112rpx;
|
||||
margin-top: 60rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,218 +0,0 @@
|
||||
<template>
|
||||
<view class="setting-container" :style="{height: `${windowHeight}px`}">
|
||||
<view class="menu-list">
|
||||
<view class="list-cell list-cell-arrow" @click="handleToPwd">
|
||||
<view class="menu-item-box">
|
||||
<view class="iconfont icon-password menu-icon"></view>
|
||||
<view>修改密码</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="list-cell list-cell-arrow" @click="handleToUpgrade">
|
||||
<view class="menu-item-box">
|
||||
<view class="iconfont icon-refresh menu-icon"></view>
|
||||
<view>检查更新</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="list-cell list-cell-arrow" @click="handleCleanTmp">
|
||||
<view class="menu-item-box">
|
||||
<view class="iconfont icon-clean menu-icon"></view>
|
||||
<view>清理缓存</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-list menu">
|
||||
<view class="cu-item item-box">
|
||||
<view class="content text-center" @click="handleLogout">
|
||||
<text class="text-black">退出登录</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useUserStore } from '@/store'
|
||||
import { ref, computed , getCurrentInstance } from "vue"
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const windowHeight = computed(() => uni.getSystemInfoSync().windowHeight - 50)
|
||||
|
||||
function handleToPwd() {
|
||||
proxy.$tab.navigateTo('/pages/mine/pwd/index')
|
||||
}
|
||||
|
||||
function handleToUpgrade() {
|
||||
proxy.$modal.showToast('模块建设中~')
|
||||
}
|
||||
|
||||
function handleCleanTmp() {
|
||||
proxy.$modal.showToast('模块建设中~')
|
||||
}
|
||||
|
||||
function handleLogout() {
|
||||
proxy.$modal.confirm('确定注销并退出系统吗?').then(() => {
|
||||
useUserStore().logOut().then(() => {}).finally(()=>{
|
||||
proxy.$tab.reLaunch('/pages/index')
|
||||
})
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.setting-container {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* 菜单列表样式 */
|
||||
.menu-list {
|
||||
background-color: #fff;
|
||||
margin: 16rpx;
|
||||
border-radius: 16rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.list-cell {
|
||||
padding: 28rpx;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.list-cell:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.list-cell:active {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.menu-item-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 28rpx;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.menu-icon {
|
||||
font-size: 32rpx;
|
||||
margin-right: 24rpx;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
/* 退出登录按钮样式 */
|
||||
.cu-list {
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
|
||||
.item-box {
|
||||
background-color: #fff;
|
||||
margin: 16rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 28rpx;
|
||||
border-radius: 16rpx;
|
||||
color: #303133;
|
||||
font-size: 28rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.item-box:active {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.content {
|
||||
font-size: 28rpx;
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 平板响应式 */
|
||||
@media screen and (min-width: 768px) {
|
||||
.setting-container {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 菜单列表样式 */
|
||||
.menu-list {
|
||||
margin: 24rpx;
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 6rpx 24rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.list-cell {
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.menu-item-box {
|
||||
font-size: 32rpx;
|
||||
|
||||
.menu-icon {
|
||||
font-size: 36rpx;
|
||||
margin-right: 32rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 退出登录按钮样式 */
|
||||
.item-box {
|
||||
margin: 24rpx;
|
||||
padding: 32rpx;
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 6rpx 24rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.content {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 大屏设备响应式 */
|
||||
@media screen and (min-width: 1024px) {
|
||||
.setting-container {
|
||||
max-width: 1000px;
|
||||
}
|
||||
|
||||
/* 菜单列表样式 */
|
||||
.menu-list {
|
||||
margin: 32rpx;
|
||||
border-radius: 24rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.list-cell {
|
||||
padding: 40rpx;
|
||||
}
|
||||
|
||||
.menu-item-box {
|
||||
font-size: 36rpx;
|
||||
|
||||
.menu-icon {
|
||||
font-size: 40rpx;
|
||||
margin-right: 40rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 退出登录按钮样式 */
|
||||
.item-box {
|
||||
margin: 32rpx;
|
||||
padding: 40rpx;
|
||||
border-radius: 24rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.content {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
241
src/static/scss/global.css
Normal file
241
src/static/scss/global.css
Normal file
@@ -0,0 +1,241 @@
|
||||
@charset "UTF-8";
|
||||
.list-cell-arrow::before {
|
||||
content: ' ';
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
border-width: 2px 2px 0 0;
|
||||
border-color: #c0c0c0;
|
||||
border-style: solid;
|
||||
-webkit-transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
|
||||
transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
margin-top: -6px;
|
||||
right: 30rpx;
|
||||
}
|
||||
|
||||
.list-cell {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
padding: 26rpx 30rpx;
|
||||
}
|
||||
|
||||
.list-cell:first-child {
|
||||
border-radius: 8rpx 8rpx 0 0;
|
||||
}
|
||||
|
||||
.list-cell:last-child {
|
||||
border-radius: 0 0 8rpx 8rpx;
|
||||
}
|
||||
|
||||
.list-cell::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
border-bottom: 1px solid #eaeef1;
|
||||
-webkit-transform: scaleY(0.5) translateZ(0);
|
||||
transform: scaleY(0.5) translateZ(0);
|
||||
transform-origin: 0 100%;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.menu-list {
|
||||
margin: 15px 15px;
|
||||
}
|
||||
|
||||
.menu-list .menu-item-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.menu-list .menu-item-box .menu-icon {
|
||||
color: #007aff;
|
||||
font-size: 16px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.menu-list .menu-item-box .text-right {
|
||||
margin-left: auto;
|
||||
margin-right: 34rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 全局Radio样式美化 */
|
||||
radio {
|
||||
transform: scale(0.8);
|
||||
}
|
||||
|
||||
radio[checked] .wx-radio-input {
|
||||
border-color: #409eff !important;
|
||||
background-color: #409eff !important;
|
||||
}
|
||||
|
||||
/* 全局Checkbox样式美化 */
|
||||
/* 基础样式重置 */
|
||||
checkbox {
|
||||
width: 40rpx !important;
|
||||
height: 40rpx !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/* Uni-app核心样式覆盖 */
|
||||
.uni-checkbox-input {
|
||||
width: 40rpx !important;
|
||||
height: 40rpx !important;
|
||||
border: 2rpx solid #dcdfe6 !important;
|
||||
border-radius: 8rpx !important;
|
||||
background-color: #ffffff !important;
|
||||
transition: all 0.3s ease-in-out !important;
|
||||
position: relative !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
.uni-checkbox-input:hover {
|
||||
border-color: #409eff !important;
|
||||
box-shadow: 0 0 12rpx rgba(64, 158, 255, 0.2) !important;
|
||||
}
|
||||
|
||||
/* 选中状态 */
|
||||
.uni-checkbox-input.uni-checkbox-input-checked {
|
||||
border-color: #409eff !important;
|
||||
background-color: #409eff !important;
|
||||
animation: checkboxPulse 0.3s ease-in-out !important;
|
||||
}
|
||||
|
||||
/* 选中状态的对勾 - 使用SVG路径实现 */
|
||||
.uni-checkbox-input.uni-checkbox-input-checked::after {
|
||||
content: '' !important;
|
||||
position: absolute !important;
|
||||
top: 8rpx !important;
|
||||
left: 13rpx !important;
|
||||
width: 12rpx !important;
|
||||
height: 20rpx !important;
|
||||
border: 3rpx solid #ffffff !important;
|
||||
border-top: none !important;
|
||||
border-left: none !important;
|
||||
transform: rotate(45deg) !important;
|
||||
transform-origin: center !important;
|
||||
animation: checkboxTick 0.3s ease-in-out !important;
|
||||
}
|
||||
|
||||
/* 清除默认对勾 */
|
||||
.uni-checkbox-input.uni-checkbox-input-checked::before {
|
||||
display: none !important;
|
||||
content: none !important;
|
||||
}
|
||||
|
||||
/* 微信小程序兼容 */
|
||||
checkbox .wx-checkbox-input {
|
||||
width: 40rpx !important;
|
||||
height: 40rpx !important;
|
||||
border: 2rpx solid #dcdfe6 !important;
|
||||
border-radius: 8rpx !important;
|
||||
background-color: #ffffff !important;
|
||||
}
|
||||
|
||||
checkbox[checked] .wx-checkbox-input {
|
||||
border-color: #409eff !important;
|
||||
background-color: #409eff !important;
|
||||
}
|
||||
|
||||
checkbox[checked] .wx-checkbox-input::before {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* 禁用状态样式 */
|
||||
checkbox[disabled] {
|
||||
opacity: 0.5 !important;
|
||||
}
|
||||
|
||||
checkbox[disabled] .uni-checkbox-input {
|
||||
border-color: #dcdfe6 !important;
|
||||
background-color: #f5f7fa !important;
|
||||
cursor: not-allowed !important;
|
||||
}
|
||||
|
||||
checkbox[disabled] .uni-checkbox-input:hover {
|
||||
border-color: #dcdfe6 !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
checkbox[disabled] .uni-checkbox-input.uni-checkbox-input-checked {
|
||||
border-color: #dcdfe6 !important;
|
||||
background-color: #dcdfe6 !important;
|
||||
}
|
||||
|
||||
/* 微信小程序禁用状态 */
|
||||
checkbox[disabled] .wx-checkbox-input {
|
||||
border-color: #dcdfe6 !important;
|
||||
background-color: #f5f7fa !important;
|
||||
}
|
||||
|
||||
checkbox[disabled][checked] .wx-checkbox-input {
|
||||
border-color: #dcdfe6 !important;
|
||||
background-color: #dcdfe6 !important;
|
||||
}
|
||||
|
||||
checkbox[checked] .wx-checkbox-input::after {
|
||||
content: '' !important;
|
||||
position: absolute !important;
|
||||
top: 8rpx !important;
|
||||
left: 13rpx !important;
|
||||
width: 12rpx !important;
|
||||
height: 20rpx !important;
|
||||
border: 3rpx solid #ffffff !important;
|
||||
border-top: none !important;
|
||||
border-left: none !important;
|
||||
transform: rotate(45deg) !important;
|
||||
}
|
||||
|
||||
/* 动画效果 */
|
||||
@keyframes checkboxPulse {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes checkboxTick {
|
||||
0% {
|
||||
transform: rotate(45deg) scale(0);
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
transform: rotate(45deg) scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 通用选择器样式 */
|
||||
.radio-item,
|
||||
.checkbox-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.radio-item:hover .radio-label,
|
||||
.checkbox-item:hover .checkbox-label {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.radio-label,
|
||||
.checkbox-label {
|
||||
margin-left: 8rpx;
|
||||
font-size: 24rpx;
|
||||
color: #303133;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
1
src/static/scss/global.min.css
vendored
Normal file
1
src/static/scss/global.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.list-cell-arrow::before{content:' ';height:10px;width:10px;border-width:2px 2px 0 0;border-color:#c0c0c0;border-style:solid;-webkit-transform:matrix(0.5, 0.5, -0.5, 0.5, 0, 0);transform:matrix(0.5, 0.5, -0.5, 0.5, 0, 0);position:absolute;top:50%;margin-top:-6px;right:30rpx}.list-cell{position:relative;width:100%;box-sizing:border-box;background-color:#fff;color:#333;padding:26rpx 30rpx}.list-cell:first-child{border-radius:8rpx 8rpx 0 0}.list-cell:last-child{border-radius:0 0 8rpx 8rpx}.list-cell::after{content:'';position:absolute;border-bottom:1px solid #eaeef1;-webkit-transform:scaleY(0.5) translateZ(0);transform:scaleY(0.5) translateZ(0);transform-origin:0 100%;bottom:0;right:0;left:0;pointer-events:none}.menu-list{margin:15px 15px}.menu-list .menu-item-box{width:100%;display:flex;align-items:center}.menu-list .menu-item-box .menu-icon{color:#007aff;font-size:16px;margin-right:5px}.menu-list .menu-item-box .text-right{margin-left:auto;margin-right:34rpx;color:#999}radio{transform:scale(0.8)}radio[checked] .wx-radio-input{border-color:#409eff !important;background-color:#409eff !important}checkbox{width:40rpx !important;height:40rpx !important;margin:0 !important;padding:0 !important}.uni-checkbox-input{width:40rpx !important;height:40rpx !important;border:2rpx solid #dcdfe6 !important;border-radius:8rpx !important;background-color:#ffffff !important;transition:all 0.3s ease-in-out !important;position:relative !important;overflow:hidden !important}.uni-checkbox-input:hover{border-color:#409eff !important;box-shadow:0 0 12rpx rgba(64,158,255,0.2) !important}.uni-checkbox-input.uni-checkbox-input-checked{border-color:#409eff !important;background-color:#409eff !important;animation:checkboxPulse 0.3s ease-in-out !important}.uni-checkbox-input.uni-checkbox-input-checked::after{content:'' !important;position:absolute !important;top:8rpx !important;left:13rpx !important;width:12rpx !important;height:20rpx !important;border:3rpx solid #ffffff !important;border-top:none !important;border-left:none !important;transform:rotate(45deg) !important;transform-origin:center !important;animation:checkboxTick 0.3s ease-in-out !important}.uni-checkbox-input.uni-checkbox-input-checked::before{display:none !important;content:none !important}checkbox .wx-checkbox-input{width:40rpx !important;height:40rpx !important;border:2rpx solid #dcdfe6 !important;border-radius:8rpx !important;background-color:#ffffff !important}checkbox[checked] .wx-checkbox-input{border-color:#409eff !important;background-color:#409eff !important}checkbox[checked] .wx-checkbox-input::before{display:none !important}checkbox[disabled]{opacity:0.5 !important}checkbox[disabled] .uni-checkbox-input{border-color:#dcdfe6 !important;background-color:#f5f7fa !important;cursor:not-allowed !important}checkbox[disabled] .uni-checkbox-input:hover{border-color:#dcdfe6 !important;box-shadow:none !important}checkbox[disabled] .uni-checkbox-input.uni-checkbox-input-checked{border-color:#dcdfe6 !important;background-color:#dcdfe6 !important}checkbox[disabled] .wx-checkbox-input{border-color:#dcdfe6 !important;background-color:#f5f7fa !important}checkbox[disabled][checked] .wx-checkbox-input{border-color:#dcdfe6 !important;background-color:#dcdfe6 !important}checkbox[checked] .wx-checkbox-input::after{content:'' !important;position:absolute !important;top:8rpx !important;left:13rpx !important;width:12rpx !important;height:20rpx !important;border:3rpx solid #ffffff !important;border-top:none !important;border-left:none !important;transform:rotate(45deg) !important}@keyframes checkboxPulse{0%{transform:scale(1)}50%{transform:scale(1.1)}100%{transform:scale(1)}}@keyframes checkboxTick{0%{transform:rotate(45deg) scale(0);opacity:0}100%{transform:rotate(45deg) scale(1);opacity:1}}.radio-item,.checkbox-item{display:flex;align-items:center;cursor:pointer;transition:color 0.3s ease}.radio-item:hover .radio-label,.checkbox-item:hover .checkbox-label{color:#409eff}.radio-label,.checkbox-label{margin-left:8rpx;font-size:24rpx;color:#303133;transition:color 0.3s ease}
|
||||
@@ -1,90 +1,240 @@
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.font-13 {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.font-12 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.font-11 {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.text-grey1 {
|
||||
color: #888;
|
||||
}
|
||||
.text-grey2 {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.list-cell-arrow::before {
|
||||
content: ' ';
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
border-width: 2px 2px 0 0;
|
||||
border-color: #c0c0c0;
|
||||
border-style: solid;
|
||||
-webkit-transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
|
||||
transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
margin-top: -6px;
|
||||
right: 30rpx;
|
||||
}
|
||||
|
||||
.list-cell {
|
||||
position: relative;
|
||||
content: ' ';
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
border-width: 2px 2px 0 0;
|
||||
border-color: #c0c0c0;
|
||||
border-style: solid;
|
||||
-webkit-transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
|
||||
transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
margin-top: -6px;
|
||||
right: 30rpx;
|
||||
}
|
||||
|
||||
.list-cell {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
padding: 26rpx 30rpx;
|
||||
}
|
||||
|
||||
.list-cell:first-child {
|
||||
border-radius: 8rpx 8rpx 0 0;
|
||||
}
|
||||
|
||||
.list-cell:last-child {
|
||||
border-radius: 0 0 8rpx 8rpx;
|
||||
}
|
||||
|
||||
.list-cell::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
border-bottom: 1px solid #eaeef1;
|
||||
-webkit-transform: scaleY(0.5) translateZ(0);
|
||||
transform: scaleY(0.5) translateZ(0);
|
||||
transform-origin: 0 100%;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.menu-list {
|
||||
margin: 15px 15px;
|
||||
|
||||
.menu-item-box {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
padding: 26rpx 30rpx;
|
||||
}
|
||||
|
||||
.list-cell:first-child {
|
||||
border-radius: 8rpx 8rpx 0 0;
|
||||
}
|
||||
|
||||
.list-cell:last-child {
|
||||
border-radius: 0 0 8rpx 8rpx;
|
||||
}
|
||||
|
||||
.list-cell::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
border-bottom: 1px solid #eaeef1;
|
||||
-webkit-transform: scaleY(0.5) translateZ(0);
|
||||
transform: scaleY(0.5) translateZ(0);
|
||||
transform-origin: 0 100%;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
.menu-list {
|
||||
margin: 15px 15px;
|
||||
|
||||
.menu-item-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.menu-icon {
|
||||
color: #007AFF;
|
||||
font-size: 16px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
margin-left: auto;
|
||||
margin-right: 34rpx;
|
||||
color: #999;
|
||||
}
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.menu-icon {
|
||||
color: #007aff;
|
||||
font-size: 16px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
margin-left: auto;
|
||||
margin-right: 34rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 全局Radio样式美化 */
|
||||
radio {
|
||||
transform: scale(0.8);
|
||||
}
|
||||
|
||||
radio[checked] .wx-radio-input {
|
||||
border-color: #409eff !important;
|
||||
background-color: #409eff !important;
|
||||
}
|
||||
|
||||
/* 全局Checkbox样式美化 */
|
||||
/* 基础样式重置 */
|
||||
checkbox {
|
||||
width: 40rpx !important;
|
||||
height: 40rpx !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/* Uni-app核心样式覆盖 */
|
||||
.uni-checkbox-input {
|
||||
width: 40rpx !important;
|
||||
height: 40rpx !important;
|
||||
border: 2rpx solid #dcdfe6 !important;
|
||||
border-radius: 8rpx !important;
|
||||
background-color: #ffffff !important;
|
||||
transition: all 0.3s ease-in-out !important;
|
||||
position: relative !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
.uni-checkbox-input:hover {
|
||||
border-color: #409eff !important;
|
||||
box-shadow: 0 0 12rpx rgba(64, 158, 255, 0.2) !important;
|
||||
}
|
||||
|
||||
/* 选中状态 */
|
||||
.uni-checkbox-input.uni-checkbox-input-checked {
|
||||
border-color: #409eff !important;
|
||||
background-color: #409eff !important;
|
||||
animation: checkboxPulse 0.3s ease-in-out !important;
|
||||
}
|
||||
|
||||
/* 选中状态的对勾 - 使用SVG路径实现 */
|
||||
.uni-checkbox-input.uni-checkbox-input-checked::after {
|
||||
content: '' !important;
|
||||
position: absolute !important;
|
||||
top: 8rpx !important;
|
||||
left: 13rpx !important;
|
||||
width: 12rpx !important;
|
||||
height: 20rpx !important;
|
||||
border: 3rpx solid #ffffff !important;
|
||||
border-top: none !important;
|
||||
border-left: none !important;
|
||||
transform: rotate(45deg) !important;
|
||||
transform-origin: center !important;
|
||||
animation: checkboxTick 0.3s ease-in-out !important;
|
||||
}
|
||||
|
||||
/* 清除默认对勾 */
|
||||
.uni-checkbox-input.uni-checkbox-input-checked::before {
|
||||
display: none !important;
|
||||
content: none !important;
|
||||
}
|
||||
|
||||
/* 微信小程序兼容 */
|
||||
checkbox .wx-checkbox-input {
|
||||
width: 40rpx !important;
|
||||
height: 40rpx !important;
|
||||
border: 2rpx solid #dcdfe6 !important;
|
||||
border-radius: 8rpx !important;
|
||||
background-color: #ffffff !important;
|
||||
}
|
||||
|
||||
checkbox[checked] .wx-checkbox-input {
|
||||
border-color: #409eff !important;
|
||||
background-color: #409eff !important;
|
||||
}
|
||||
|
||||
checkbox[checked] .wx-checkbox-input::before {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* 禁用状态样式 */
|
||||
checkbox[disabled] {
|
||||
opacity: 0.5 !important;
|
||||
}
|
||||
|
||||
checkbox[disabled] .uni-checkbox-input {
|
||||
border-color: #dcdfe6 !important;
|
||||
background-color: #f5f7fa !important;
|
||||
cursor: not-allowed !important;
|
||||
}
|
||||
|
||||
checkbox[disabled] .uni-checkbox-input:hover {
|
||||
border-color: #dcdfe6 !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
checkbox[disabled] .uni-checkbox-input.uni-checkbox-input-checked {
|
||||
border-color: #dcdfe6 !important;
|
||||
background-color: #dcdfe6 !important;
|
||||
}
|
||||
|
||||
/* 微信小程序禁用状态 */
|
||||
checkbox[disabled] .wx-checkbox-input {
|
||||
border-color: #dcdfe6 !important;
|
||||
background-color: #f5f7fa !important;
|
||||
}
|
||||
|
||||
checkbox[disabled][checked] .wx-checkbox-input {
|
||||
border-color: #dcdfe6 !important;
|
||||
background-color: #dcdfe6 !important;
|
||||
}
|
||||
|
||||
checkbox[checked] .wx-checkbox-input::after {
|
||||
content: '' !important;
|
||||
position: absolute !important;
|
||||
top: 8rpx !important;
|
||||
left: 13rpx !important;
|
||||
width: 12rpx !important;
|
||||
height: 20rpx !important;
|
||||
border: 3rpx solid #ffffff !important;
|
||||
border-top: none !important;
|
||||
border-left: none !important;
|
||||
transform: rotate(45deg) !important;
|
||||
}
|
||||
|
||||
/* 动画效果 */
|
||||
@keyframes checkboxPulse {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes checkboxTick {
|
||||
0% {
|
||||
transform: rotate(45deg) scale(0);
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
transform: rotate(45deg) scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 通用选择器样式 */
|
||||
.radio-item,
|
||||
.checkbox-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.radio-item:hover .radio-label,
|
||||
.checkbox-item:hover .checkbox-label {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.radio-label,
|
||||
.checkbox-label {
|
||||
margin-left: 8rpx;
|
||||
font-size: 24rpx;
|
||||
color: #303133;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user