|
|
@@ -1,26 +1,70 @@
|
|
|
+<!-- 客户充值记录页:承接会员详情和统计页入口,展示可按日期、客户、渠道、金额类型筛选的充值明细。 -->
|
|
|
<template>
|
|
|
<view class="app-content">
|
|
|
+ <view class="control-panel">
|
|
|
+ <view class="filter-row">
|
|
|
+ <view class="filter-chip date-chip">
|
|
|
+ <image class="filter-icon" :src="iconSrc('order-calendar')" mode="aspectFit" />
|
|
|
+ <DateSelect class="date-select" top="0" @selectDateFn="selectDateFn" :defaultShowName="currentDateName" :showAllOption="true" />
|
|
|
+ </view>
|
|
|
+ <view class="search-box">
|
|
|
+ <AppSearchModule
|
|
|
+ ref="searchRef"
|
|
|
+ :height="72"
|
|
|
+ :fontSize="26"
|
|
|
+ placeholder="客户姓名 / 手机尾号4位"
|
|
|
+ placeholderColor="#8b9098"
|
|
|
+ backColor="#f2f4f7"
|
|
|
+ @input="searchFn"
|
|
|
+ />
|
|
|
+ <view v-if="customId != 0 || searchText" class="search-clear" @click.stop="clearSearch">清空</view>
|
|
|
+ </view>
|
|
|
+ <view class="filter-btn" @click.stop="openFilterPanel">
|
|
|
+ <image class="filter-icon filter-icon-lg" :src="iconSrc('order-filter')" mode="aspectFit" />
|
|
|
+ <view v-if="hasActiveFilters" class="filter-dot"></view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view v-if="showSearch" class="search-suggest">
|
|
|
+ <block v-if="!$util.isEmpty(searchList)">
|
|
|
+ <view class="suggest-item" v-for="(item, index) in searchList" :key="index" @click="getCustom(index)">
|
|
|
+ <view class="suggest-name">{{ item.name }}</view>
|
|
|
+ <view class="suggest-meta">
|
|
|
+ <text>{{ item.visitTime ? item.visitTime.substr(5, 11) : '' }}</text>
|
|
|
+ <text v-if="item.mobile" class="suggest-tag">{{ item.mobile }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </block>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
<block v-if="!$util.isEmpty(list.data)">
|
|
|
<view class="recharge-table">
|
|
|
<view class="table-header table-row">
|
|
|
<view class="table-cell cell-date">日期</view>
|
|
|
- <view class="table-cell cell-scene">场景</view>
|
|
|
- <view class="table-cell cell-staff">人员</view>
|
|
|
- <view class="table-cell cell-status">状态</view>
|
|
|
- <view class="table-cell cell-amount">充值</view>
|
|
|
- <view class="table-cell cell-give">赠送</view>
|
|
|
+ <view class="table-cell cell-scene">充值渠道</view>
|
|
|
+ <view class="table-cell cell-staff">操作人</view>
|
|
|
+ <view class="table-cell cell-status">客户姓名</view>
|
|
|
+ <view class="table-cell cell-amount">金额</view>
|
|
|
</view>
|
|
|
<view v-for="(item, index) in list.data" :key="index" class="table-body">
|
|
|
<view class="table-row table-row-data">
|
|
|
<view class="table-cell cell-date">{{ item.addTime.substr(5,11) }}</view>
|
|
|
<view class="table-cell cell-scene">
|
|
|
- <view>{{ item.onlinePay == 2 ? '线上' : '线下'}}</view>
|
|
|
- <view>{{ item.payWay==0?'微信':item.payWay == 1 ?'支付宝':item.payWay == 4 ?'现金':item.payWay == 5 ?'银行卡':'其它'}}</view>
|
|
|
+ <view>{{ getChannelLine(item, 0) }}</view>
|
|
|
+ <view v-if="getChannelLine(item, 1)">{{ getChannelLine(item, 1) }}</view>
|
|
|
+ <view v-if="isRefunded(item)" class="refund-tag">已退款</view>
|
|
|
</view>
|
|
|
<view class="table-cell cell-staff">{{ item.staffName }}</view>
|
|
|
- <view class="table-cell cell-status">{{ item.payStatus == 1 ? '已付款' : '待付款' }}</view>
|
|
|
- <view class="table-cell cell-amount">{{ item.amount }}</view>
|
|
|
- <view class="table-cell cell-give">{{ item.giveAmount>0 ? parseFloat(item.giveAmount) : '-' }}</view>
|
|
|
+ <view class="table-cell cell-status">{{ item.customName }}</view>
|
|
|
+ <view class="table-cell cell-amount">
|
|
|
+ <view class="amount-line">{{ item.amount }}{{ getGiveAmountText(item) }}</view>
|
|
|
+ <view
|
|
|
+ v-if="canRefund(item)"
|
|
|
+ class="refund-btn"
|
|
|
+ :class="{ disabled: refundingId == item.id }"
|
|
|
+ @click.stop="confirmRefund(item)"
|
|
|
+ >退款</view>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
<view class="table-row table-row-extra" v-if="!$util.isEmpty(item.remark)">
|
|
|
<view class="table-cell cell-extra">
|
|
|
@@ -34,37 +78,365 @@
|
|
|
<block v-else>
|
|
|
<AppWrapperEmpty title="暂无数据" :is-empty="$util.isEmpty(list.data)" />
|
|
|
</block>
|
|
|
+
|
|
|
+ <view v-if="showFilterPanel" class="filter-overlay" @click="closeFilterPanel">
|
|
|
+ <view class="filter-panel" @click.stop>
|
|
|
+ <view class="filter-header">筛选充值记录</view>
|
|
|
+ <view class="filter-section">
|
|
|
+ <view class="filter-title">充值渠道</view>
|
|
|
+ <view class="filter-options">
|
|
|
+ <view
|
|
|
+ v-for="(item, index) in channelOptions"
|
|
|
+ :key="index"
|
|
|
+ class="filter-option"
|
|
|
+ :class="{ active: channelKey === item.value }"
|
|
|
+ @click="selectChannel(item.value)"
|
|
|
+ >
|
|
|
+ {{ item.label }}
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="filter-section">
|
|
|
+ <view class="filter-title">金额类型</view>
|
|
|
+ <view class="filter-options">
|
|
|
+ <view
|
|
|
+ v-for="(item, index) in ioOptions"
|
|
|
+ :key="index"
|
|
|
+ class="filter-option"
|
|
|
+ :class="{ active: io === item.value }"
|
|
|
+ @click="selectIo(item.value)"
|
|
|
+ >
|
|
|
+ {{ item.label }}
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="filter-actions">
|
|
|
+ <button class="filter-action-btn clear-btn" @click="clearFilters">重置</button>
|
|
|
+ <button class="filter-action-btn confirm-btn" @click="confirmFilters">确定</button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
</template>
|
|
|
<script>
|
|
|
import AppWrapperEmpty from "@/components/app-wrapper-empty";
|
|
|
- import { rechargeList } from '@/api/recharge'
|
|
|
+ import { rechargeList, refundRecharge } from '@/api/recharge'
|
|
|
+ import { getList } from "@/api/member";
|
|
|
+ import { getStaffInfo } from '@/api/shop-admin'
|
|
|
import list from '@/mixins/list'
|
|
|
+ import AppSearchModule from "@/components/module/app-search";
|
|
|
+ import DateSelect from "@/components/module/dateSelect";
|
|
|
+ import { iconSrc } from "@/utils/iconSrc";
|
|
|
export default {
|
|
|
name: "rechargeBalance",
|
|
|
components: {
|
|
|
- AppWrapperEmpty
|
|
|
+ AppWrapperEmpty,
|
|
|
+ AppSearchModule,
|
|
|
+ DateSelect
|
|
|
},
|
|
|
mixins:[list],
|
|
|
+ computed: {
|
|
|
+ hasActiveFilters() {
|
|
|
+ return this.channelKey !== 'all' || this.io !== '';
|
|
|
+ }
|
|
|
+ },
|
|
|
data() {
|
|
|
return {
|
|
|
+ initialCustomId: 0,
|
|
|
+ initialCustomName: '',
|
|
|
+ initialCustomCleared: false,
|
|
|
+ customId: 0,
|
|
|
+ searchTime: '',
|
|
|
+ startTime: '',
|
|
|
+ endTime: '',
|
|
|
+ currentDateName: '全部',
|
|
|
+ queryFiltersHydrated: false,
|
|
|
+ io: '',
|
|
|
+ searchText: '',
|
|
|
+ lastSearchText: '',
|
|
|
+ showSearch: false,
|
|
|
+ searchList: [],
|
|
|
+ showFilterPanel: false,
|
|
|
+ channelKey: 'all',
|
|
|
+ channelOptions: [
|
|
|
+ { label: '全部', value: 'all' },
|
|
|
+ { label: '线上微信', value: 'online_0' },
|
|
|
+ { label: '线上支付宝', value: 'online_1' },
|
|
|
+ { label: '线下微信', value: 'pay_0' },
|
|
|
+ { label: '线下支付宝', value: 'pay_1' },
|
|
|
+ { label: '现金', value: 'pay_4' },
|
|
|
+ { label: '银行卡', value: 'pay_5' },
|
|
|
+ { label: '其它', value: 'other' }
|
|
|
+ ],
|
|
|
+ ioOptions: [
|
|
|
+ { label: '全部金额', value: '' },
|
|
|
+ { label: '充值金额', value: '1' },
|
|
|
+ { label: '减少金额', value: '0' }
|
|
|
+ ],
|
|
|
+ hasFinance: 0,
|
|
|
+ refundingId: 0
|
|
|
};
|
|
|
},
|
|
|
+ onLoad(option) {
|
|
|
+ this.option = option || {};
|
|
|
+ this.hydrateQueryFilters();
|
|
|
+ },
|
|
|
+ onReady() {
|
|
|
+ this.syncSearchInput();
|
|
|
+ },
|
|
|
methods: {
|
|
|
+ iconSrc,
|
|
|
+ loadFinancePermission() {
|
|
|
+ getStaffInfo().then(res => {
|
|
|
+ if (res.code == 1 && res.data && res.data.staff) {
|
|
|
+ this.hasFinance = res.data.staff.finance ? 1 : 0;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ decodeQueryText(text) {
|
|
|
+ try {
|
|
|
+ return decodeURIComponent(text || '');
|
|
|
+ } catch (e) {
|
|
|
+ return text || '';
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 从统计页或会员详情入口恢复初始筛选,保证首次加载明细数据与来源页面一致。
|
|
|
+ hydrateQueryFilters() {
|
|
|
+ if (this.queryFiltersHydrated) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const option = this.option || {};
|
|
|
+ if (Object.prototype.hasOwnProperty.call(option, 'searchTime')) {
|
|
|
+ this.searchTime = option.searchTime || '';
|
|
|
+ }
|
|
|
+ if (Object.prototype.hasOwnProperty.call(option, 'startTime')) {
|
|
|
+ this.startTime = option.startTime || '';
|
|
|
+ }
|
|
|
+ if (Object.prototype.hasOwnProperty.call(option, 'endTime')) {
|
|
|
+ this.endTime = option.endTime || '';
|
|
|
+ }
|
|
|
+ if (option.dateName) {
|
|
|
+ this.currentDateName = this.decodeQueryText(option.dateName);
|
|
|
+ } else {
|
|
|
+ this.currentDateName = this.getDateName();
|
|
|
+ }
|
|
|
+ if (option.channelKey) {
|
|
|
+ this.channelKey = option.channelKey;
|
|
|
+ }
|
|
|
+ if (Object.prototype.hasOwnProperty.call(option, 'io')) {
|
|
|
+ this.io = String(option.io);
|
|
|
+ }
|
|
|
+ this.hydrateInitialCustom();
|
|
|
+ this.queryFiltersHydrated = true;
|
|
|
+ },
|
|
|
+ syncSearchInput() {
|
|
|
+ if (this.$refs && this.$refs.searchRef) {
|
|
|
+ this.$refs.searchRef.search = this.searchText;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 初始化入口客户筛选,会员详情和统计页客户行都会带入客户身份。
|
|
|
+ hydrateInitialCustom() {
|
|
|
+ if (this.initialCustomCleared) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const option = this.option || {};
|
|
|
+ const optionCustomId = option.customId || option.id || 0;
|
|
|
+ const optionCustomName = this.decodeQueryText(option.customName || '');
|
|
|
+ if (optionCustomId && !this.initialCustomId) {
|
|
|
+ this.initialCustomId = optionCustomId;
|
|
|
+ }
|
|
|
+ if (optionCustomName && !this.initialCustomName) {
|
|
|
+ this.initialCustomName = optionCustomName;
|
|
|
+ }
|
|
|
+ if (this.initialCustomId && !this.customId) {
|
|
|
+ this.customId = this.initialCustomId;
|
|
|
+ }
|
|
|
+ if (this.initialCustomName && !this.searchText) {
|
|
|
+ this.searchText = this.initialCustomName;
|
|
|
+ this.lastSearchText = this.initialCustomName;
|
|
|
+ this.syncSearchInput();
|
|
|
+ }
|
|
|
+ },
|
|
|
async init(){
|
|
|
- let id = this.option.id ? this.option.id : 0
|
|
|
- const res = await rechargeList({ page:this.list.page,customId:id })
|
|
|
+ this.hydrateQueryFilters();
|
|
|
+ this.loadFinancePermission();
|
|
|
+ const res = await rechargeList({
|
|
|
+ page: this.list.page,
|
|
|
+ customId: this.customId,
|
|
|
+ searchTime: this.searchTime,
|
|
|
+ startTime: this.startTime,
|
|
|
+ endTime: this.endTime,
|
|
|
+ channelKey: this.channelKey,
|
|
|
+ io: this.io
|
|
|
+ })
|
|
|
if (this.$util.isEmpty(res.data.list)){
|
|
|
this.completes(res)
|
|
|
return
|
|
|
}
|
|
|
let currentList = res.data.list
|
|
|
currentList.forEach(function(item,index,array){
|
|
|
- array[index].amount = item.io == 0 ? '-'+parseFloat(item.amount) : '+'+parseFloat(item.amount)
|
|
|
+ const prefix = Number(item.isRefund) === 1 ? '-' : '+';
|
|
|
+ array[index].amount = prefix + parseFloat(item.amount)
|
|
|
});
|
|
|
res.data.list = currentList
|
|
|
this.completes(res)
|
|
|
},
|
|
|
+ getPayWayName(payWay) {
|
|
|
+ return payWay == 0 ? '微信' : payWay == 1 ? '支付宝' : payWay == 4 ? '现金' : payWay == 5 ? '银行卡' : '其它';
|
|
|
+ },
|
|
|
+ getChannelLine(item, line) {
|
|
|
+ if (item.onlinePay == 2) {
|
|
|
+ return line === 0 ? '线上' : this.getPayWayName(item.payWay);
|
|
|
+ }
|
|
|
+ return line === 0 ? '线下' : this.getPayWayName(item.payWay);
|
|
|
+ },
|
|
|
+ isRefunded(item) {
|
|
|
+ return Number(item && item.isRefund) === 1;
|
|
|
+ },
|
|
|
+ canRefund(item) {
|
|
|
+ return this.hasFinance == 1
|
|
|
+ && item
|
|
|
+ && Number(item.payStatus) === 1
|
|
|
+ && !this.isRefunded(item)
|
|
|
+ && Number(item.amount) > 0;
|
|
|
+ },
|
|
|
+ // 格式化金额列的赠送补充文案,只有存在正向赠送金额时才跟随主金额展示。
|
|
|
+ getGiveAmountText(item) {
|
|
|
+ const giveAmount = Number(item && item.giveAmount);
|
|
|
+ if (!giveAmount || giveAmount <= 0) {
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+ return '(赠送' + parseFloat(item.giveAmount) + ')';
|
|
|
+ },
|
|
|
+ confirmRefund(item) {
|
|
|
+ const amount = Math.abs(parseFloat(item.amount)) || 0;
|
|
|
+ let content = '确认对该笔充值退款 ¥' + amount + ' ?';
|
|
|
+ if (Number(item.onlinePay) === 2) {
|
|
|
+ content = '此单为线上付款,提交后钱会原路退回给客户,确认退款 ¥' + amount + ' ?';
|
|
|
+ }
|
|
|
+ uni.showModal({
|
|
|
+ title: '确认退款',
|
|
|
+ content,
|
|
|
+ success: (res) => {
|
|
|
+ if (res.confirm) {
|
|
|
+ this.submitRefund(item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ submitRefund(item) {
|
|
|
+ if (this.refundingId) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.refundingId = item.id;
|
|
|
+ refundRecharge({ id: item.id }).then(res => {
|
|
|
+ if (res.code == 1) {
|
|
|
+ this.$msg('退款成功');
|
|
|
+ this.resetList();
|
|
|
+ this.init();
|
|
|
+ }
|
|
|
+ this.refundingId = 0;
|
|
|
+ }).catch(() => {
|
|
|
+ this.refundingId = 0;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ openFilterPanel() {
|
|
|
+ this.showFilterPanel = true;
|
|
|
+ },
|
|
|
+ closeFilterPanel() {
|
|
|
+ this.showFilterPanel = false;
|
|
|
+ },
|
|
|
+ selectChannel(value) {
|
|
|
+ this.channelKey = value;
|
|
|
+ },
|
|
|
+ // 选择金额类型后由确认按钮统一触发列表刷新。
|
|
|
+ selectIo(value) {
|
|
|
+ this.io = value;
|
|
|
+ },
|
|
|
+ clearFilters() {
|
|
|
+ this.channelKey = 'all';
|
|
|
+ this.io = '';
|
|
|
+ this.closeFilterPanel();
|
|
|
+ this.resetList();
|
|
|
+ this.init();
|
|
|
+ },
|
|
|
+ confirmFilters() {
|
|
|
+ this.closeFilterPanel();
|
|
|
+ this.resetList();
|
|
|
+ this.init();
|
|
|
+ },
|
|
|
+ // 切换日期后刷新列表,保留展示文案供当前页筛选器显示。
|
|
|
+ selectDateFn(val) {
|
|
|
+ this.searchTime = val.searchTime || '';
|
|
|
+ this.startTime = val.startTime || '';
|
|
|
+ this.endTime = val.endTime || '';
|
|
|
+ this.currentDateName = val.showName || this.getDateName();
|
|
|
+ this.resetList();
|
|
|
+ this.init();
|
|
|
+ },
|
|
|
+ // 根据当前日期筛选补全 DateSelect 展示文案。
|
|
|
+ getDateName() {
|
|
|
+ if (!this.searchTime) {
|
|
|
+ return '全部';
|
|
|
+ }
|
|
|
+ if (this.searchTime === 'byMonth') {
|
|
|
+ return this.startTime || '选月份';
|
|
|
+ }
|
|
|
+ if (this.searchTime === 'custom') {
|
|
|
+ return this.startTime === this.endTime ? this.startTime : '选时段';
|
|
|
+ }
|
|
|
+ return '今天';
|
|
|
+ },
|
|
|
+ searchFn(e) {
|
|
|
+ this.searchText = e;
|
|
|
+ if (this.$util.isEmpty(this.searchText) && this.$util.isEmpty(this.lastSearchText)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (this.$util.isEmpty(e)) {
|
|
|
+ this.lastSearchText = '';
|
|
|
+ this.showSearch = false;
|
|
|
+ this.searchList = [];
|
|
|
+ this.customId = this.initialCustomId || 0;
|
|
|
+ this.resetList();
|
|
|
+ this.init();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.lastSearchText = this.searchText;
|
|
|
+ getList({ page: 1, name: e, type: 0 }).then(res => {
|
|
|
+ if (!this.$util.isEmpty(res.data) && !this.$util.isEmpty(res.data.list)) {
|
|
|
+ this.showSearch = true;
|
|
|
+ this.searchList = res.data.list;
|
|
|
+ } else {
|
|
|
+ this.showSearch = false;
|
|
|
+ this.searchList = [];
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ getCustom(index) {
|
|
|
+ const item = this.searchList[index];
|
|
|
+ if (!item) return;
|
|
|
+ this.showSearch = false;
|
|
|
+ this.initialCustomCleared = false;
|
|
|
+ this.customId = item.id;
|
|
|
+ this.searchText = item.name || this.searchText;
|
|
|
+ this.lastSearchText = this.searchText;
|
|
|
+ this.syncSearchInput();
|
|
|
+ this.resetList();
|
|
|
+ this.init();
|
|
|
+ },
|
|
|
+ clearSearch() {
|
|
|
+ this.searchText = '';
|
|
|
+ this.lastSearchText = '';
|
|
|
+ this.showSearch = false;
|
|
|
+ this.searchList = [];
|
|
|
+ this.initialCustomCleared = true;
|
|
|
+ this.initialCustomId = 0;
|
|
|
+ this.initialCustomName = '';
|
|
|
+ this.customId = 0;
|
|
|
+ this.syncSearchInput();
|
|
|
+ this.resetList();
|
|
|
+ this.init();
|
|
|
+ },
|
|
|
goShOrder(item){
|
|
|
this.$util.pageTo({ url: '/admin/order/detail?id='+item.shOrderId})
|
|
|
}
|
|
|
@@ -85,13 +457,134 @@
|
|
|
};
|
|
|
</script>
|
|
|
<style lang="scss" scoped>
|
|
|
+ .control-panel {
|
|
|
+ position: sticky;
|
|
|
+ top: 0;
|
|
|
+ z-index: 30;
|
|
|
+ width: 100%;
|
|
|
+ padding: 22upx 22upx 18upx;
|
|
|
+ background: #fff;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+ .filter-row {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+ .filter-chip,
|
|
|
+ .filter-btn {
|
|
|
+ height: 72upx;
|
|
|
+ border-radius: 16upx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ flex-shrink: 0;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+ .filter-chip {
|
|
|
+ padding: 0 8upx;
|
|
|
+ color: #60666d;
|
|
|
+ font-size: 28upx;
|
|
|
+ }
|
|
|
+ .date-chip {
|
|
|
+ min-width: 92upx;
|
|
|
+ }
|
|
|
+ .date-select {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+ .date-chip .filter-icon {
|
|
|
+ margin-right: 4upx;
|
|
|
+ }
|
|
|
+ .filter-icon {
|
|
|
+ width: 32upx;
|
|
|
+ height: 32upx;
|
|
|
+ flex-shrink: 0;
|
|
|
+ }
|
|
|
+ .filter-icon-lg {
|
|
|
+ width: 38upx;
|
|
|
+ height: 38upx;
|
|
|
+ }
|
|
|
+ .search-box {
|
|
|
+ position: relative;
|
|
|
+ flex: 1;
|
|
|
+ min-width: 0;
|
|
|
+ margin-left: 14upx;
|
|
|
+ margin-right: 14upx;
|
|
|
+ }
|
|
|
+ .search-box ::v-deep .app-search-module .map-search {
|
|
|
+ height: 72upx !important;
|
|
|
+ border-radius: 28upx;
|
|
|
+ }
|
|
|
+ .search-box ::v-deep .app-search-module .map-search .input-wrap {
|
|
|
+ height: 72upx;
|
|
|
+ }
|
|
|
+ .filter-btn {
|
|
|
+ position: relative;
|
|
|
+ min-width: 72upx;
|
|
|
+ border: 1upx solid #e3e8e6;
|
|
|
+ background: #fff;
|
|
|
+ }
|
|
|
+ .filter-dot {
|
|
|
+ position: absolute;
|
|
|
+ right: 10upx;
|
|
|
+ top: 8upx;
|
|
|
+ width: 14upx;
|
|
|
+ height: 14upx;
|
|
|
+ border-radius: 50%;
|
|
|
+ background: #ff3b30;
|
|
|
+ border: 2upx solid #fff;
|
|
|
+ }
|
|
|
+ .search-clear {
|
|
|
+ position: absolute;
|
|
|
+ right: 12upx;
|
|
|
+ top: 50%;
|
|
|
+ transform: translateY(-50%);
|
|
|
+ padding: 7upx 14upx;
|
|
|
+ border: 1upx solid #09c567;
|
|
|
+ border-radius: 22upx;
|
|
|
+ background: rgba(255, 255, 255, 0.94);
|
|
|
+ color: #09c567;
|
|
|
+ font-size: 22upx;
|
|
|
+ z-index: 2;
|
|
|
+ }
|
|
|
+ .search-suggest {
|
|
|
+ position: absolute;
|
|
|
+ left: 22upx;
|
|
|
+ right: 22upx;
|
|
|
+ top: 108upx;
|
|
|
+ z-index: 40;
|
|
|
+ max-height: 420upx;
|
|
|
+ padding: 20upx 24upx 0;
|
|
|
+ border-radius: 18upx;
|
|
|
+ background: #fff;
|
|
|
+ box-shadow: 0 18upx 38upx rgba(22, 33, 28, 0.14);
|
|
|
+ overflow-y: auto;
|
|
|
+ }
|
|
|
+ .suggest-item {
|
|
|
+ padding-bottom: 22upx;
|
|
|
+ margin-bottom: 22upx;
|
|
|
+ border-bottom: 1upx solid #eff2f0;
|
|
|
+ }
|
|
|
+ .suggest-name {
|
|
|
+ color: #1f2328;
|
|
|
+ font-size: 32upx;
|
|
|
+ font-weight: 700;
|
|
|
+ }
|
|
|
+ .suggest-meta {
|
|
|
+ margin-top: 8upx;
|
|
|
+ color: #9298a0;
|
|
|
+ font-size: 25upx;
|
|
|
+ }
|
|
|
+ .suggest-tag {
|
|
|
+ margin-left: 18upx;
|
|
|
+ color: #09c567;
|
|
|
+ }
|
|
|
.recharge-table {
|
|
|
width: 100%;
|
|
|
border-radius: 16upx;
|
|
|
overflow: hidden;
|
|
|
background: #fff;
|
|
|
box-shadow: 0 4upx 24upx rgba(0,0,0,0.06);
|
|
|
- margin: 20upx 0;
|
|
|
.table-row {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
@@ -119,7 +612,9 @@
|
|
|
padding: 16upx 20upx;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
- gap: 2upx;
|
|
|
+ view:not(:last-child) {
|
|
|
+ margin-bottom: 2upx;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -152,15 +647,133 @@
|
|
|
}
|
|
|
&.cell-amount {
|
|
|
text-align: right;
|
|
|
- min-width: 100upx;
|
|
|
- flex: 1;
|
|
|
- }
|
|
|
- &.cell-give {
|
|
|
- text-align: right;
|
|
|
- min-width: 80upx;
|
|
|
- padding-right: 32upx;
|
|
|
- flex: 1;
|
|
|
+ min-width: 152upx;
|
|
|
+ padding-right: 18upx;
|
|
|
+ flex: 1.45;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- </style>
|
|
|
+ .refund-tag {
|
|
|
+ display: inline-flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ min-width: 64upx;
|
|
|
+ height: 30upx;
|
|
|
+ margin-top: 6upx;
|
|
|
+ padding: 0 8upx;
|
|
|
+ border-radius: 6upx;
|
|
|
+ background: #fff1f0;
|
|
|
+ color: #e5484d;
|
|
|
+ font-size: 20upx;
|
|
|
+ line-height: 30upx;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+ .amount-line {
|
|
|
+ line-height: 34upx;
|
|
|
+ word-break: break-all;
|
|
|
+ }
|
|
|
+ .refund-btn {
|
|
|
+ display: inline-flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ min-width: 70upx;
|
|
|
+ height: 44upx;
|
|
|
+ margin-top: 8upx;
|
|
|
+ padding: 0 12upx;
|
|
|
+ border-radius: 8upx;
|
|
|
+ background: #e5484d;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 24upx;
|
|
|
+ line-height: 44upx;
|
|
|
+ box-sizing: border-box;
|
|
|
+ &.disabled {
|
|
|
+ opacity: 0.55;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .filter-overlay {
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ bottom: 0;
|
|
|
+ z-index: 9999;
|
|
|
+ display: flex;
|
|
|
+ align-items: flex-start;
|
|
|
+ justify-content: center;
|
|
|
+ background-color: rgba(0, 0, 0, 0.5);
|
|
|
+ }
|
|
|
+ .filter-panel {
|
|
|
+ width: 100%;
|
|
|
+ max-height: 90vh;
|
|
|
+ overflow-y: auto;
|
|
|
+ border-radius: 0 0 24upx 24upx;
|
|
|
+ background: #fff;
|
|
|
+ }
|
|
|
+ .filter-header {
|
|
|
+ padding: 24upx 0;
|
|
|
+ text-align: center;
|
|
|
+ color: #202329;
|
|
|
+ font-size: 32upx;
|
|
|
+ font-weight: 800;
|
|
|
+ border-bottom: 1upx solid #f0f0f0;
|
|
|
+ }
|
|
|
+ .filter-section {
|
|
|
+ padding: 30upx 40upx;
|
|
|
+ border-bottom: 1upx solid #f0f0f0;
|
|
|
+ }
|
|
|
+ .filter-title {
|
|
|
+ margin-bottom: 20upx;
|
|
|
+ color: #202329;
|
|
|
+ font-size: 28upx;
|
|
|
+ font-weight: 700;
|
|
|
+ }
|
|
|
+ .filter-options {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ margin-right: -18upx;
|
|
|
+ margin-bottom: -18upx;
|
|
|
+ }
|
|
|
+ .filter-option {
|
|
|
+ min-width: 120upx;
|
|
|
+ padding: 15upx 28upx;
|
|
|
+ margin-right: 18upx;
|
|
|
+ margin-bottom: 18upx;
|
|
|
+ border: 1upx solid #dce2e0;
|
|
|
+ border-radius: 28upx;
|
|
|
+ color: #60666d;
|
|
|
+ background: #fff;
|
|
|
+ font-size: 26upx;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+ .filter-option.active {
|
|
|
+ color: #09c567;
|
|
|
+ border-color: #09c567;
|
|
|
+ background: #effbf4;
|
|
|
+ font-weight: 700;
|
|
|
+ }
|
|
|
+ .filter-actions {
|
|
|
+ display: flex;
|
|
|
+ padding: 30upx 40upx;
|
|
|
+ }
|
|
|
+ .filter-action-btn {
|
|
|
+ flex: 1;
|
|
|
+ height: 76upx;
|
|
|
+ border-radius: 14upx;
|
|
|
+ font-size: 28upx;
|
|
|
+ font-weight: 700;
|
|
|
+ }
|
|
|
+ .filter-action-btn:not(:last-child) {
|
|
|
+ margin-right: 20upx;
|
|
|
+ }
|
|
|
+ .filter-action-btn::after {
|
|
|
+ border: 0;
|
|
|
+ }
|
|
|
+ .clear-btn {
|
|
|
+ color: #626970;
|
|
|
+ background: #f3f5f4;
|
|
|
+ }
|
|
|
+ .confirm-btn {
|
|
|
+ color: #fff;
|
|
|
+ background: #09c567;
|
|
|
+ }
|
|
|
+ </style>
|