This commit is contained in:
2026-09-29 15:17:13 +08:00
commit 69e6ed8c59
113 changed files with 36564 additions and 0 deletions
+996
View File
@@ -0,0 +1,996 @@
<template>
<view class="performance-page">
<view class="perf-hero">
<AppNavbar title="业绩统计"/>
<view class="stats-card">
<view class="flex justify-between items-center w-100p">
<view class="stat-item">
<view class="stat-value">{{ stats.doneNum }}/{{ stats.taskNum }}</view>
<view class="stat-label">我的完成进度</view>
</view>
<!-- <view class="stat-item" @click="toBonus">-->
<!-- <view class="stat-value">{{ stats.income }}元</view>-->
<!-- <view class="stat-label">我的活动奖励</view>-->
<!-- </view>-->
<view class="stat-item">
<view class="stat-value">{{ stats.doneRate }}%</view>
<view class="stat-label">我的完成率</view>
</view>
</view>
<view class="flex justify-between items-center w-100p pt-20 border-top" v-if="isLoggedIn && user.canAuth === 1">
<view class="stat-item">
<view class="stat-value text-main">{{ stats.totalDoneNum }}/{{ stats.totalTaskNum }}</view>
<view class="stat-label">总完成进度</view>
</view>
<!-- <view class="stat-item" @click="toBonus">-->
<!-- <view class="stat-value text-main">{{ stats.totalIncome }}元</view>-->
<!-- <view class="stat-label">总活动奖励</view>-->
<!-- </view>-->
<view class="stat-item">
<view class="stat-value text-main">{{ stats.totalDoneRate }}%</view>
<view class="stat-label">总完成率</view>
</view>
</view>
</view>
</view>
<view class="section-head">
<view class="head-left" @tap="openAreaPicker">
<u-icon name="map" size="26" color="#27c7a4"/>
<text>{{ currentCity }}</text>
</view>
<view class="head-center">
<image class="head-icon" mode="heightFix"
src="https://yaodongxiao.oss-cn-guangzhou.aliyuncs.com/20260126/6a639dcbe30e9c503d50f391272a066a.png"
alt=""/>
<!-- <text class="head-dot">✦</text>-->
<!-- <text class="section-title">任务完成详情</text>-->
</view>
<view class="section-more"></view>
</view>
<view class="filter-chips">
<view class="filter-chip" @tap="openMerchantPicker">{{ merchantLabel }}</view>
<view class="filter-chip" @tap="openManufacturerPicker">{{ manufacturerLabel }}</view>
</view>
<view class="task-list">
<template v-if="details.length">
<view class="task-card" v-for="(item, index) in visibleDetails" :key="index" @tap="showDetails(item)">
<view class="task-top">
<text class="task-label">匹配门店:</text>
<text class="task-value">{{ item.merchant.name || '-' }}</text>
</view>
<view class="task-divider"></view>
<view class="task-row">
<text class="task-label">任务名称:</text>
<text class="task-value">{{ item.title }}</text>
</view>
<view class="task-row">
<text class="task-label">当前状态:</text>
<text :class="['task-status', taskStatusClass(item)]">{{ resolveTaskStatusLabel(item) }}</text>
</view>
<view class="task-row task-row-space">
<text class="task-time">任务时间:{{ item.date || '-' }}</text>
<view class="task-distance">
<u-icon name="map" size="24" color="#ff9f43"/>
<text>距离{{ item.distance || '100米' }}</text>
</view>
</view>
<view class="task-progress">
<view class="progress-line">
<view class="progress-fill"
:style="{ width: `${item.num ? (item.doneNum / item.num) * 100 : 0}%` }"></view>
</view>
<view class="progress-right">
<u-icon name="close-circle" color="#2fc6a7" size="30rpx"/>
<!-- <view class="progress-icon">×</view>-->
<view class="progress-count">{{ item.doneNum }}/{{ item.num }}</view>
</view>
</view>
</view>
<view v-if="showMoreTaskBtn" class="task-more-btn" @tap="expandTaskList">查看更多</view>
</template>
<u-empty v-else
icon="https://yaodongxiao.oss-cn-guangzhou.aliyuncs.com/20260126/ddcc1bbd561d97128ed19407b07e299b.png"
text="暂无数据"/>
</view>
<view class="person-section">
<view class="section-banner">
<view class="banner-center">
<!-- <text class="head-dot">✦</text>-->
<!-- <text class="section-title section-title-light">按人员筛选</text>-->
<image class="head-icon" mode="aspectFit"
src="https://yaodongxiao.oss-cn-guangzhou.aliyuncs.com/20260126/10fe8406037bab94adf5045216feb74a.png"
alt=""/>
</view>
<view class="section-more section-more-light"></view>
</view>
<!-- <view class="person-search">-->
<!-- <u-icon name="search" size="26" color="#9ca3af"/>-->
<!-- <input type="text" placeholder="输入姓名搜索" v-model="personKeyword"/>-->
<!-- <view class="search-btn" @tap="searchPerson">搜索</view>-->
<!-- </view>-->
<view class="p-20">
<u-search showAction animation v-model="personKeyword" bgColor="white"
searchIcon="https://yaodongxiao.oss-cn-guangzhou.aliyuncs.com/20260126/16f54dd102cacccfb5085533009b70fc.png"/>
</view>
<view class="person-list">
<template v-if="filteredPersons.length">
<view class="person-item" v-for="(person, idx) in filteredPersons" :key="idx">
<view class="person-left">
<u-icon v-if="idx === 0"
name="https://yaodongxiao.oss-cn-guangzhou.aliyuncs.com/20260126/99b7a70575473d52e38c765a8635428c.png"
size="50rpx"/>
<u-icon v-else-if="idx === 1"
name="https://yaodongxiao.oss-cn-guangzhou.aliyuncs.com/20260126/3a984885c03dbd31f1bd998f98c41493.png"
size="50rpx"/>
<u-icon v-else-if="idx === 2"
name="https://yaodongxiao.oss-cn-guangzhou.aliyuncs.com/20260126/722383e4ed2ba2e98cd04ce3ee5c4b8f.png"
size="50rpx"/>
<text v-else class="person-index">{{ idx + 1 }}</text>
<text class="person-name">{{ person.nickname || person.name || '-' }}</text>
</view>
<!-- <view class="person-right">奖励 ¥{{ person.incomeAmount }} 完成 {{-->
<!-- person.taskCompleteNum-->
<!-- }}/{{ person.totalTaskNum }}-->
<!-- </view>-->
</view>
</template>
<u-empty v-else
icon="https://yaodongxiao.oss-cn-guangzhou.aliyuncs.com/20260126/ddcc1bbd561d97128ed19407b07e299b.png"
text="暂无数据"/>
</view>
</view>
<Login ref="Login" @done="getUserData"/>
<AreaPicker
:show="showAreaPicker"
:default-province="currentProvince"
:default-city="currentCity"
@close="showAreaPicker = false"
@confirm="onAreaConfirm"
/>
<u-popup :show="showMerchantPicker" mode="bottom" round="24rpx" @close="closeMerchantPicker">
<view class="merchant-picker">
<view class="merchant-picker-head">
<view class="picker-action" @tap="closeMerchantPicker">取消</view>
<text class="picker-title">药店筛选</text>
<view class="picker-action primary" @tap="confirmMerchantPicker">确定</view>
</view>
<view class="merchant-picker-search">
<u-search
v-model="merchantSearchKeyword"
bgColor="white"
showAction
animation
actionText="搜索"
searchIcon="https://yaodongxiao.oss-cn-guangzhou.aliyuncs.com/20260126/16f54dd102cacccfb5085533009b70fc.png"
/>
</view>
<view v-if="merchantLoading" class="merchant-picker-loading">
<u-loading-icon mode="circle"></u-loading-icon>
</view>
<picker-view
v-else
class="merchant-picker-view"
:value="merchantPickerValue"
:indicator-style="merchantIndicatorStyle"
@change="onMerchantPickerChange"
>
<picker-view-column>
<view
v-for="(item, idx) in merchantFilteredOptions"
:key="idx"
class="merchant-picker-item"
>{{ item.text }}
</view>
</picker-view-column>
</picker-view>
</view>
</u-popup>
<u-popup :show="showManufacturerPicker" mode="bottom" round="24rpx" @close="closeManufacturerPicker">
<view class="merchant-picker">
<view class="merchant-picker-head">
<view class="picker-action" @tap="closeManufacturerPicker">取消</view>
<text class="picker-title">厂家筛选</text>
<view class="picker-action primary" @tap="confirmManufacturerPicker">确定</view>
</view>
<view v-if="manufacturerLoading" class="merchant-picker-loading">
<u-loading-icon mode="circle"></u-loading-icon>
</view>
<picker-view
v-else
class="merchant-picker-view"
:value="manufacturerPickerValue"
:indicator-style="merchantIndicatorStyle"
@change="onManufacturerPickerChange"
>
<picker-view-column>
<view
v-for="(item, idx) in manufacturerOptions"
:key="idx"
class="merchant-picker-item"
>{{ item.text }}
</view>
</picker-view-column>
</picker-view>
</view>
</u-popup>
</view>
</template>
<script>
import {taskDataReq, taskListForDataReq, taskUserRankReq} from "@/api/task";
import AppNavbar from "@/components/AppNavbar.vue";
import {calcDistanceMeters, formatDistance, getLocationAction} from "@/util";
import AreaPicker from "@/components/AreaPicker.vue";
import Login from "@/components/Login.vue";
import {userInfoReq} from "@/api/user";
import {getUserInfo} from "@/util/user";
import {merchantListReq} from "@/api/shop";
import {productGroupReq} from "@/api/product";
export default {
components: {Login, AppNavbar, AreaPicker},
data() {
return {
customerOptions: ['全部客户', '大参林', '老百姓', '海王星辰'],
industryOptions: ['自身产品', '大参林联营', '老百姓联营'],
roleOptions: ['管理员视角', '店长视角', '本人视角'],
customerIndex: 0,
industryIndex: 0,
roleIndex: 0,
stats: {
taskNum: 0,
doneNum: 0,
income: 0,
doneRate: 0,
totalDoneNum: 0,
totalTaskNum: 0,
totalIncome: 0,
totalDoneRate: 0,
},
details: [],
taskDisplayLimit: 10,
taskListExpanded: false,
lat: null,
lng: null,
currentCity: '定位中',
currentProvince: '',
showAreaPicker: false,
isLoggedIn: false,
personKeyword: '',
persons: [],
showMerchantPicker: false,
merchantLoading: false,
merchantOptions: [
{id: '', text: '全部门店'}
],
merchantId: '',
merchantText: '药店筛选',
merchantSearchKeyword: '',
merchantPickerValue: [0],
showManufacturerPicker: false,
manufacturerLoading: false,
manufacturerOptions: [
{markAbb: '', text: '全部厂家'}
],
manufacturerMarkAbb: '',
manufacturerText: '厂家筛选',
manufacturerPickerValue: [0],
user: {
canAuth: 0
}
}
},
computed: {
filteredPersons() {
const kw = this.personKeyword.trim()
const list = Array.isArray(this.persons) ? this.persons : []
const filtered = kw ? list.filter(p => (p.nickname || '').includes(kw)) : list
return filtered.slice().sort((a, b) => {
const aAmount = Number(a.incomeAmount) || 0
const bAmount = Number(b.incomeAmount) || 0
return bAmount - aAmount
})
},
merchantLabel() {
return this.merchantText || '药店筛选'
},
manufacturerLabel() {
return this.manufacturerText || '厂家筛选'
},
merchantFilteredOptions() {
const kw = this.merchantSearchKeyword.trim()
const list = Array.isArray(this.merchantOptions) ? this.merchantOptions : []
const filtered = kw ? list.filter(item => (item.text || '').includes(kw)) : list
return filtered.length ? filtered : [{id: '', text: '无匹配门店'}]
},
merchantIndicatorStyle() {
return 'height: 44px;'
},
visibleDetails() {
const list = Array.isArray(this.details) ? this.details : []
if (this.taskListExpanded) return list
return list.slice(0, this.taskDisplayLimit)
},
showMoreTaskBtn() {
const list = Array.isArray(this.details) ? this.details : []
return !this.taskListExpanded && list.length > this.taskDisplayLimit
}
},
watch: {
merchantSearchKeyword() {
this.merchantPickerValue = [0]
}
},
async onShow() {
await this.refreshPageData()
},
async onPullDownRefresh() {
try {
await this.refreshPageData()
} finally {
uni.stopPullDownRefresh()
}
},
methods: {
async refreshPageData() {
await this.getLocation()
await this.getTaskList()
await this.getUserRank()
if (getUserInfo().token) await this.getUserData()
},
async getUserData() {
const {data} = await userInfoReq()
this.isLoggedIn = true
this.user = data
await this.getTaskData()
},
async getLocation() {
const res = await getLocationAction().catch(() => {
uni.showToast({
title: '请允许位置授权',
icon: 'none'
})
})
if (res) {
this.lat = Number(res.latitude)
this.lng = Number(res.longitude)
this.currentCity = res.city_str || this.currentCity
this.currentProvince = res.province_str || this.currentProvince
this.updateTaskDistances()
}
},
async getTaskData() {
const {data} = await taskDataReq()
this.stats = data
},
async getTaskList() {
const params = {
province: this.currentProvince,
city: this.currentCity,
}
if (this.merchantId !== '' && this.merchantId !== null && this.merchantId !== undefined) {
params.merchantId = this.merchantId
}
if (this.manufacturerMarkAbb) {
params.markAbb = this.manufacturerMarkAbb
}
const {data} = await taskListForDataReq(params)
this.details = data
this.taskListExpanded = false
this.updateTaskDistances()
},
expandTaskList() {
this.taskListExpanded = true
},
async getUserRank() {
const {data} = await taskUserRankReq()
this.persons = data
},
changeCustomer(e) {
this.customerIndex = Number(e.detail.value)
},
changeIndustry(e) {
this.industryIndex = Number(e.detail.value)
},
changeRole(e) {
this.roleIndex = Number(e.detail.value)
},
openAreaPicker() {
this.showAreaPicker = true
},
onAreaConfirm({provinceName, cityName}) {
this.currentProvince = provinceName
this.currentCity = cityName
this.showAreaPicker = false
this.getTaskList()
},
async getMerchantList() {
this.merchantLoading = true
try {
const params = {}
if (this.currentProvince) params.province = this.currentProvince
if (this.currentCity && this.currentCity !== '定位中') params.city = this.currentCity
const {data} = await merchantListReq(params)
const list = Array.isArray(data)
? data
: (Array.isArray(data && data.records) ? data.records : (Array.isArray(data && data.list) ? data.list : []))
const options = list.map(item => ({
id: item.id ?? item.merchantId ?? item.merchant_id,
text: item.name || item.merchantName || item.merchant_name || item.title || '未命名门店'
})).filter(item => item.id !== undefined && item.id !== null)
this.merchantOptions = [{id: '', text: '全部门店'}].concat(options)
} catch (error) {
uni.showToast({
title: '门店列表获取失败',
icon: 'none'
})
} finally {
this.merchantLoading = false
}
},
async openMerchantPicker() {
// if (!this.merchantOptions || this.merchantOptions.length <= 1) {
await this.getMerchantList()
// }
this.merchantSearchKeyword = ''
const idx = this.merchantOptions.findIndex(item => item.id === this.merchantId)
this.merchantPickerValue = [idx > -1 ? idx : 0]
this.showMerchantPicker = true
},
closeMerchantPicker() {
this.showMerchantPicker = false
},
onMerchantPickerChange(e) {
const value = Array.isArray(e.detail && e.detail.value) ? e.detail.value : [0]
this.merchantPickerValue = value
},
confirmMerchantPicker() {
const selected = this.merchantFilteredOptions[this.merchantPickerValue[0]] || null
if (selected) {
this.merchantId = selected.id ?? ''
this.merchantText = selected.text || '药店筛选'
} else {
this.merchantId = ''
this.merchantText = '药店筛选'
}
this.showMerchantPicker = false
this.getTaskList()
},
async getManufacturerList() {
this.manufacturerLoading = true
try {
const {data} = await productGroupReq()
console.log(data)
const options = data.map(item => ({
makerAbb: item.makerAbb,
text: item.makerAbb || ''
})).filter(item => item.text)
console.log(options)
this.manufacturerOptions = [{makerAbb: '', text: '全部厂家'}].concat(options)
} catch (error) {
uni.showToast({
title: '厂家列表获取失败',
icon: 'none'
})
} finally {
this.manufacturerLoading = false
}
},
async openManufacturerPicker() {
if (!this.manufacturerOptions || this.manufacturerOptions.length <= 1) {
await this.getManufacturerList()
}
const idx = this.manufacturerOptions.findIndex(item => item.markAbb === this.manufacturerMarkAbb)
this.manufacturerPickerValue = [idx > -1 ? idx : 0]
this.showManufacturerPicker = true
},
closeManufacturerPicker() {
this.showManufacturerPicker = false
},
onManufacturerPickerChange(e) {
const value = Array.isArray(e.detail && e.detail.value) ? e.detail.value : [0]
this.manufacturerPickerValue = value
},
confirmManufacturerPicker() {
const selected = this.manufacturerOptions[this.manufacturerPickerValue[0]] || null
if (selected) {
this.manufacturerMarkAbb = selected.markAbb ?? ''
this.manufacturerText = selected.text || '厂家筛选'
} else {
this.manufacturerMarkAbb = ''
this.manufacturerText = '厂家筛选'
}
this.showManufacturerPicker = false
this.getTaskList()
},
updateTaskDistances() {
if (!Number.isFinite(this.lat) || !Number.isFinite(this.lng)) return
this.details = this.details.map(item => {
const merchant = item.merchant || {}
const lat = Number(merchant.lat || merchant.latitude || item.lat || item.latitude)
const lng = Number(merchant.lng || merchant.longitude || item.lng || item.longitude)
if (!Number.isFinite(lat) || !Number.isFinite(lng)) return item
const meters = calcDistanceMeters(this.lat, this.lng, lat, lng)
return Object.assign({}, item, {
distance: formatDistance(meters)
})
})
},
pickFirstTaskText(values = []) {
for (let i = 0; i < values.length; i++) {
const value = values[i]
if (value === undefined || value === null) continue
const text = String(value).trim()
if (text) return text
}
return ''
},
pickFirstTaskNumber(values = []) {
for (let i = 0; i < values.length; i++) {
const raw = values[i]
if (raw === '' || raw === undefined || raw === null) continue
const num = Number(raw)
if (Number.isFinite(num)) return num
}
return null
},
resolveTaskStatusLabel(item = {}) {
const userTask = item.userTask || {}
const textLabel = this.pickFirstTaskText([
item.statusText,
item.taskStatusText,
item.stateText,
item.statusName,
item.taskStatusName,
userTask.statusText
])
if (textLabel) return textLabel
const userStatus = this.pickFirstTaskNumber([item.userTaskStatus, userTask.status, item.auditStatus])
if (userStatus !== null) {
if (userStatus === 2) return '已完成'
if (userStatus === 1) return '审核中'
if (userStatus === 3) return '审核驳回'
if (userStatus === 0) return '待提交'
}
const taskStatus = this.pickFirstTaskNumber([item.taskStatus, item.status, item.state])
if (taskStatus !== null) {
if (taskStatus === 2) return '已完成'
if (taskStatus === 1) return '进行中'
if (taskStatus === 0) return '未开始'
}
const doneNum = Number(item.doneNum) || 0
const totalNum = Number(item.num) || 0
if (totalNum > 0 && doneNum >= totalNum) return '已完成'
if (doneNum > 0) return '进行中'
return '未开始'
},
taskStatusClass(item = {}) {
const label = this.resolveTaskStatusLabel(item)
if (label.includes('驳回') || label.includes('失败')) return 'task-status-danger'
if (label.includes('完成') || label.includes('通过')) return 'task-status-success'
if (label.includes('审核中') || label.includes('进行') || label.includes('待')) return 'task-status-pending'
return 'task-status-default'
},
searchPerson() {
if (!this.personKeyword.trim()) {
uni.showToast({
title: '请输入姓名',
icon: 'none'
})
}
},
showDetails(task) {
uni.navigateTo({
url: `/pages/task/detail?title=${encodeURIComponent(task.merchant.name)}&reward=${task.reward}&target=${task.cate.title}&id=${task.id}`
})
},
toBonus() {
if (!this.isLoggedIn) {
return this.$refs.Login.open()
}
uni.navigateTo({
url: '/pages/bonus/index'
})
}
}
}
</script>
<style lang="scss" scoped>
.performance-page {
min-height: 100vh;
padding: 0 0 40rpx;
background: #e9fbf6;
}
.perf-hero {
padding: 0 0 20rpx;
background: url('https://yaodongxiao.oss-cn-guangzhou.aliyuncs.com/20260126/462bfa04cf0eff8698884c38b9d17519.png') no-repeat top center / 100% auto;
}
.perf-navbar {
padding: 0 6rpx;
}
.stats-card {
margin: 0 20rpx 0;
padding: 18rpx 18rpx;
background: #ffffff;
border-radius: 20rpx;
border: 1rpx solid #2fc6a7;
border-top: 20rpx solid #2fc6a7;
//display: grid;
//grid-template-columns: repeat(3, 1fr);
//gap: 10rpx;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.stat-item {
text-align: center;
width: 30%;
}
.stat-value {
font-size: 30rpx;
font-weight: 700;
color: #ff3b30;
}
.stat-label {
margin-top: 6rpx;
font-size: 22rpx;
color: #6b7280;
}
.section-head {
margin: 14rpx 20rpx 0 20rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 6rpx;
}
.head-left {
display: flex;
align-items: center;
gap: 6rpx;
font-size: 24rpx;
color: #2fc6a7;
font-weight: 700;
}
.head-center {
display: flex;
align-items: center;
gap: 6rpx;
color: #2fc6a7;
font-weight: 700;
}
.head-dot {
font-size: 20rpx;
}
.section-title {
font-size: 26rpx;
font-weight: 700;
color: #2fc6a7;
}
.section-more {
font-size: 22rpx;
color: #6b7280;
width: 50rpx;
}
.filter-chips {
margin: 12rpx 20rpx 0;
display: flex;
justify-content: flex-end;
gap: 10rpx;
}
.filter-chip {
padding: 6rpx 14rpx;
border-radius: 999rpx;
border: 1rpx solid #2fc6a7;
color: #2fc6a7;
font-size: 22rpx;
}
.task-list {
margin: 12rpx 20rpx 0;
display: flex;
flex-direction: column;
gap: 14rpx;
}
.task-more-btn {
margin: 6rpx auto 0;
padding: 10rpx 30rpx;
border-radius: 999rpx;
border: 1rpx solid #2fc6a7;
color: #2fc6a7;
font-size: 24rpx;
background: #ffffff;
}
.task-card {
background: #ffffff;
border-radius: 18rpx;
padding: 14rpx 16rpx;
border: 1rpx solid #2fc6a7;
box-shadow: 0 8rpx 16rpx rgba(39, 199, 164, 0.12);
}
.task-top {
display: flex;
align-items: center;
gap: 6rpx;
font-size: 24rpx;
color: #374151;
}
.task-label {
color: #6b7280;
}
.task-divider {
height: 1rpx;
background: #d7f4eb;
margin: 10rpx 0;
}
.task-row {
display: flex;
align-items: center;
gap: 6rpx;
font-size: 24rpx;
color: #374151;
margin-top: 6rpx;
}
.task-row-space {
justify-content: space-between;
}
.task-time {
color: #6b7280;
font-size: 22rpx;
}
.task-distance {
display: flex;
align-items: center;
gap: 4rpx;
font-size: 22rpx;
color: #ff8a00;
}
.task-status {
font-size: 22rpx;
font-weight: 700;
}
.task-status-default {
color: #6b7280;
}
.task-status-pending {
color: #ff9f43;
}
.task-status-success {
color: #22c55e;
}
.task-status-danger {
color: #ef4444;
}
.task-progress {
margin-top: 12rpx;
display: flex;
align-items: center;
justify-content: space-between;
gap: 12rpx;
}
.progress-line {
flex: 1;
height: 6rpx;
background: #e5f7f1;
border-radius: 999rpx;
overflow: hidden;
}
.progress-fill {
height: 100%;
background: #37c977;
}
.progress-right {
display: flex;
align-items: center;
gap: 6rpx;
font-size: 22rpx;
color: #2fc6a7;
}
.progress-icon {
width: 28rpx;
height: 28rpx;
border-radius: 50%;
border: 1rpx solid #2fc6a7;
display: flex;
align-items: center;
justify-content: center;
font-size: 20rpx;
}
.person-section {
margin-top: 18rpx;
overflow: hidden;
background-image: url("https://yaodongxiao.oss-cn-guangzhou.aliyuncs.com/20260126/09dd8e6519b44d71410fc82a7e255540.jpg");
background-size: cover;
}
.section-banner {
padding: 12rpx 14rpx;
//background: linear-gradient(135deg, #33d0b3, #22c3a1);
display: flex;
align-items: center;
justify-content: center;
}
.banner-center {
display: flex;
align-items: center;
gap: 6rpx;
}
.section-title-light {
color: #ffffff;
}
.section-more-light {
color: #ffffff;
}
.person-search {
padding: 12rpx 14rpx;
display: flex;
align-items: center;
gap: 10rpx;
background: #ffffff;
border-bottom: 1rpx dashed #d7f4eb;
}
.person-search input {
flex: 1;
font-size: 24rpx;
color: #1f2937;
}
.search-btn {
padding: 6rpx 16rpx;
border-radius: 999rpx;
background: #2fc6a7;
color: #ffffff;
font-size: 24rpx;
font-weight: 700;
}
.person-list {
padding: 10rpx;
margin: 20rpx;
background-color: white;
border-radius: 10rpx;
min-height: 200rpx;
}
.person-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12rpx 0;
border-bottom: 1rpx dashed #d7f4eb;
font-size: 24rpx;
}
.person-item:last-child {
border-bottom: none;
}
.person-left {
display: flex;
align-items: center;
gap: 10rpx;
flex: 1;
}
.person-index {
font-size: 24rpx;
font-weight: 700;
color: #2fc6a7;
width: 36rpx;
text-align: center;
}
.person-name {
color: #1f2937;
}
.person-right {
color: #ef4444;
font-size: 22rpx;
}
.head-icon {
height: 60rpx;
}
.merchant-picker {
background: #ffffff;
border-radius: 24rpx 24rpx 0 0;
padding-bottom: 24rpx;
}
.merchant-picker-head {
display: flex;
align-items: center;
justify-content: space-between;
padding: 18rpx 20rpx;
border-bottom: 1rpx solid #eef2f7;
}
.picker-title {
font-size: 28rpx;
font-weight: 700;
color: #111827;
}
.picker-action {
font-size: 24rpx;
color: #6b7280;
}
.picker-action.primary {
color: #2fc6a7;
font-weight: 700;
}
.merchant-picker-search {
padding: 12rpx 20rpx 0;
}
.merchant-picker-loading {
height: 320rpx;
display: flex;
align-items: center;
justify-content: center;
}
.merchant-picker-view {
height: 360rpx;
}
.merchant-picker-item {
height: 44px;
line-height: 44px;
text-align: center;
font-size: 26rpx;
color: #111827;
}
</style>