|
|
@@ -0,0 +1,1162 @@
|
|
|
+<template>
|
|
|
+ <view class="app-content">
|
|
|
+ <!-- 门店地址管理 -->
|
|
|
+ <view class="shop-address-section">
|
|
|
+ <view class="section-header">
|
|
|
+ <text class="section-title">门店地址</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="shop-info-card" v-if="shopAddress">
|
|
|
+ <view class="shop-status success">
|
|
|
+ <text class="status-icon">✓</text>
|
|
|
+ <text class="status-text">已创建门店地址</text>
|
|
|
+ </view>
|
|
|
+ <!-- <view class="shop-details">
|
|
|
+ <view class="detail-item">
|
|
|
+ <text class="detail-label">门店名称:</text>
|
|
|
+ <text class="detail-value">{{ shopAddress.shopName || '未设置' }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="detail-item">
|
|
|
+ <text class="detail-label">门店地址:</text>
|
|
|
+ <text class="detail-value">{{ shopAddress.fullAddress || '未设置' }}</text>
|
|
|
+ </view>
|
|
|
+ </view> -->
|
|
|
+ <button class="update-btn" @click="updateShopAddressFn">
|
|
|
+ <text class="btn-text">更新门店地址</text>
|
|
|
+ </button>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="shop-info-card empty" v-else>
|
|
|
+ <view class="shop-status warning">
|
|
|
+ <text class="status-icon">!</text>
|
|
|
+ <text class="status-text">暂未创建门店地址</text>
|
|
|
+ </view>
|
|
|
+ <view class="shop-desc">
|
|
|
+ <text class="desc-text">请先创建门店地址,以便正常使用跑腿服务</text>
|
|
|
+ </view>
|
|
|
+ <button class="create-btn" @click="createShopAddress">
|
|
|
+ <text class="btn-text">创建门店</text>
|
|
|
+ </button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 余额卡片 -->
|
|
|
+ <view class="balance-card">
|
|
|
+ <view class="balance-left">
|
|
|
+ <view class="balance-header">
|
|
|
+ <text class="balance-title">账户余额</text>
|
|
|
+ </view>
|
|
|
+ <view class="balance-amount">
|
|
|
+ <text class="amount-text">{{ balance.toFixed(2) }}</text>
|
|
|
+ <text class="balance-unit">元</text>
|
|
|
+ </view>
|
|
|
+ <view class="balance-desc">
|
|
|
+ <text class="desc-text">用于支付跑腿费用</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="balance-right">
|
|
|
+ <view class="sub-balance sf">
|
|
|
+ <text class="sub-balance-label">达达</text>
|
|
|
+ <text class="sub-balance-amount">{{ dadaBalance.toFixed(2) }}元</text>
|
|
|
+ </view>
|
|
|
+ <view class="sub-balance dada">
|
|
|
+ <text class="sub-balance-label">顺丰同城</text>
|
|
|
+ <text class="sub-balance-amount">{{ sfBalance.toFixed(2) }}元</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 充值按钮 -->
|
|
|
+ <view class="recharge-section">
|
|
|
+ <button class="recharge-btn" @click="showRechargeModal">
|
|
|
+ <text class="btn-text">立即充值</text>
|
|
|
+ </button>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 充值记录 -->
|
|
|
+ <!-- <view class="record-section">
|
|
|
+ <view class="section-header">
|
|
|
+ <text class="section-title">充值记录</text>
|
|
|
+ </view>
|
|
|
+ <view class="record-list" v-if="rechargeRecords.length > 0">
|
|
|
+ <view class="record-item" v-for="(record, index) in rechargeRecords" :key="index">
|
|
|
+ <view class="record-info">
|
|
|
+ <text class="record-amount">+{{ record.amount }}元</text>
|
|
|
+ <text class="record-time">{{ record.time }}</text>
|
|
|
+ </view>
|
|
|
+ <text class="record-status" :class="record.status">{{ record.statusText }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="empty-record" v-else>
|
|
|
+ <text class="empty-text">暂无充值记录</text>
|
|
|
+ </view>
|
|
|
+ </view> -->
|
|
|
+
|
|
|
+ <!-- 充值弹窗 -->
|
|
|
+ <view class="modal-overlay" v-if="showModal" @click="hideRechargeModal">
|
|
|
+ <view class="modal-content" @click.stop>
|
|
|
+ <view class="modal-header">
|
|
|
+ <text class="modal-title">账户充值</text>
|
|
|
+ <text class="modal-close" @click="hideRechargeModal">×</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="modal-body">
|
|
|
+ <view v-if="!showPayUrl">
|
|
|
+ <!-- 配送公司选择 -->
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="form-label">选择跑腿</text>
|
|
|
+ <view class="express-company-options">
|
|
|
+ <view
|
|
|
+ class="express-option"
|
|
|
+ :class="{ active: expressCompany === 'DADA' }"
|
|
|
+ @click="selectExpressCompany('DADA')"
|
|
|
+ >
|
|
|
+ <text class="express-option-text">达达</text>
|
|
|
+ </view>
|
|
|
+ <view
|
|
|
+ class="express-option"
|
|
|
+ :class="{ active: expressCompany === 'SFTC' }"
|
|
|
+ @click="selectExpressCompany('SFTC')"
|
|
|
+ >
|
|
|
+ <text class="express-option-text">顺丰同城</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="form-label">充值金额</text>
|
|
|
+ <view class="amount-input-wrapper">
|
|
|
+ <text class="currency-symbol">¥</text>
|
|
|
+ <input
|
|
|
+ class="amount-input"
|
|
|
+ type="digit"
|
|
|
+ v-model="rechargeAmount"
|
|
|
+ placeholder="充值金额"
|
|
|
+ @input="onAmountInput"
|
|
|
+ />
|
|
|
+ </view>
|
|
|
+ <view style="color:red;margin:10upx 0 10upx 0;font-size:24upx;font-weight:bold;">充值金额不能少于50元,用不完可以退</view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 快捷金额选择 -->
|
|
|
+ <view class="quick-amounts">
|
|
|
+ <text class="quick-title">快捷选择</text>
|
|
|
+ <view class="amount-options">
|
|
|
+ <view
|
|
|
+ class="amount-option"
|
|
|
+ v-for="amount in quickAmounts"
|
|
|
+ :key="amount"
|
|
|
+ :class="{ active: rechargeAmount == amount }"
|
|
|
+ @click="selectAmount(amount)"
|
|
|
+ >
|
|
|
+ <text class="option-text">{{ amount }}元</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 支付链接展示区域 -->
|
|
|
+ <view v-if="showPayUrl" class="pay-url-section">
|
|
|
+ <view class="pay-url-title">
|
|
|
+ <text>请复制以下链接在浏览器中打开完成支付</text>
|
|
|
+ </view>
|
|
|
+ <view class="pay-url-box">
|
|
|
+ <text class="pay-url-text" user-select>{{ payUrl }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="copy-btn-wrapper">
|
|
|
+ <button class="copy-btn" @click="copyPayUrl">
|
|
|
+ <text class="copy-btn-text">复制链接</text>
|
|
|
+ </button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="modal-footer">
|
|
|
+ <button class="cancel-btn" @click="hideRechargeModal">
|
|
|
+ <text class="cancel-text">{{ showPayUrl ? '关闭' : '取消' }}</text>
|
|
|
+ </button>
|
|
|
+ <button v-if="!showPayUrl" class="confirm-btn" @click="confirmRecharge" :disabled="!canRecharge">
|
|
|
+ <text class="confirm-text">确认充值</text>
|
|
|
+ </button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import TuiListCell from "@/components/plugin/list-cell";
|
|
|
+import { createStore, updateStore, getStore, getStoreBalance, rechargeStore } from "@/api/shop/shop-express.js";
|
|
|
+export default {
|
|
|
+ name: "expressSet",
|
|
|
+ components: {
|
|
|
+ TuiListCell,
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ balance: 0.00, // 总账户余额
|
|
|
+ sfBalance: 0.00, // 顺丰余额
|
|
|
+ dadaBalance: 0.00, // 达达余额
|
|
|
+ showModal: false, // 是否显示充值弹窗
|
|
|
+ rechargeAmount: '', // 充值金额
|
|
|
+ expressCompany: 'DADA', // 跑腿公司,默认达达
|
|
|
+ quickAmounts: [50, 100, 200, 500], // 快捷金额选项
|
|
|
+ rechargeRecords: [], // 充值记录
|
|
|
+ shopAddress: null, // 门店地址信息
|
|
|
+ loading: false,
|
|
|
+ payUrl: '', // 支付链接
|
|
|
+ showPayUrl: false, // 是否显示支付链接
|
|
|
+ wxStoreId:''
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ canRecharge() {
|
|
|
+ const amount = parseFloat(this.rechargeAmount);
|
|
|
+ return amount > 0 && amount <= 1000000; // 限制最大充值金额
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onLoad() {
|
|
|
+
|
|
|
+ },
|
|
|
+ onShow() {
|
|
|
+ uni.setNavigationBarTitle({
|
|
|
+ title: `跑腿设置`,
|
|
|
+ });
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // 复制支付链接
|
|
|
+ copyPayUrl() {
|
|
|
+ uni.setClipboardData({
|
|
|
+ data: this.payUrl,
|
|
|
+ success: () => {
|
|
|
+ uni.showToast({
|
|
|
+ title: '链接已复制',
|
|
|
+ icon: 'success'
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ init() {
|
|
|
+ this.initExpress()
|
|
|
+ },
|
|
|
+ async initExpress(){
|
|
|
+ try {
|
|
|
+ this.loading = true;
|
|
|
+ // 获取门店地址信息
|
|
|
+ this.getShopAddressInfo();
|
|
|
+ // 获取账户余额和充值记录
|
|
|
+ this.getBalance();
|
|
|
+ this.getRechargeRecords();
|
|
|
+ } catch (error) {
|
|
|
+ console.error('初始化失败:', error);
|
|
|
+ uni.showToast({
|
|
|
+ title: '加载失败',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ } finally {
|
|
|
+ this.loading = false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 获取门店地址信息
|
|
|
+ async getShopAddressInfo() {
|
|
|
+ try {
|
|
|
+ const result = await getStore();
|
|
|
+
|
|
|
+ console.log(result.data);
|
|
|
+ if (result.data.id) {
|
|
|
+ this.shopAddress = result.data ? {
|
|
|
+ province: result.data.province,
|
|
|
+ city: result.data.city,
|
|
|
+ area: result.data.dist,
|
|
|
+ floor: result.data.floor,
|
|
|
+ address: result.data.address,
|
|
|
+ lat: result.data.lat,
|
|
|
+ lng: result.data.long,
|
|
|
+ wxStoreId: result.data.wx_store_id
|
|
|
+ } : null;
|
|
|
+ } else {
|
|
|
+ this.shopAddress = result.data ? {
|
|
|
+ province: result.data.address_info.province,
|
|
|
+ city: result.data.address_info.city,
|
|
|
+ area: result.data.address_info.area,
|
|
|
+ street: result.data.address_info.street,
|
|
|
+ house: result.data.address_info.house,
|
|
|
+ lat: result.data.address_info.lat,
|
|
|
+ lng: result.data.address_info.lng,
|
|
|
+ cityId: result.data.city_id,
|
|
|
+ orderPattern: result.data.order_pattern,
|
|
|
+ outStoreId: result.data.out_store_id,
|
|
|
+ serviceTransPrefer: result.data.service_trans_prefer,
|
|
|
+ wxStoreId: result.data.wx_store_id
|
|
|
+ } : null;
|
|
|
+ console.log(this.shopAddress);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ // console.error('获取门店地址失败:', error);
|
|
|
+ // 如果接口不存在或失败,设置为null
|
|
|
+ this.shopAddress = null;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 创建门店地址
|
|
|
+ async createShopAddress() {
|
|
|
+ try {
|
|
|
+ uni.showLoading({
|
|
|
+ title: '创建中...'
|
|
|
+ });
|
|
|
+
|
|
|
+ // 调用创建门店地址API
|
|
|
+ const result = await createStore({
|
|
|
+ // 这里可以传入默认的门店信息
|
|
|
+ shopName: '默认门店',
|
|
|
+ province: '',
|
|
|
+ city: '',
|
|
|
+ address: '',
|
|
|
+ lat: 0,
|
|
|
+ lng: 0
|
|
|
+ });
|
|
|
+
|
|
|
+ uni.hideLoading();
|
|
|
+
|
|
|
+ if (result.code === 1) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '创建成功',
|
|
|
+ icon: 'success'
|
|
|
+ });
|
|
|
+
|
|
|
+ // 刷新门店信息
|
|
|
+ await this.getShopAddressInfo();
|
|
|
+ } else {
|
|
|
+ if(result.msg && result.msg.includes('address_info.house is empty')){
|
|
|
+ this.$msg('门店的门牌号未填写')
|
|
|
+ } else {
|
|
|
+ console.log(result.message);
|
|
|
+ uni.showToast({
|
|
|
+ title: '创建失败',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ uni.hideLoading();
|
|
|
+ console.error('创建门店地址失败:', error);
|
|
|
+ uni.showToast({
|
|
|
+ title: '创建失败,请重试',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 更新门店地址
|
|
|
+ async updateShopAddressFn() {
|
|
|
+ try {
|
|
|
+ uni.showLoading({
|
|
|
+ title: '更新中...'
|
|
|
+ });
|
|
|
+
|
|
|
+ // 调用更新门店地址API
|
|
|
+ const result = await updateStore({
|
|
|
+ id: this.shopAddress.id,
|
|
|
+ province: this.shopAddress.province,
|
|
|
+ city: this.shopAddress.city,
|
|
|
+ address: this.shopAddress.address,
|
|
|
+ lat: this.shopAddress.lat,
|
|
|
+ lng: this.shopAddress.lng
|
|
|
+ });
|
|
|
+
|
|
|
+ uni.hideLoading();
|
|
|
+
|
|
|
+ if (result.code === 1) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '更新成功',
|
|
|
+ icon: 'success'
|
|
|
+ });
|
|
|
+
|
|
|
+ // 刷新门店信息
|
|
|
+ await this.getShopAddressInfo();
|
|
|
+ } else {
|
|
|
+ console.log(result);
|
|
|
+ if(result.msg && result.msg.includes('content.address_info.house is empty')){
|
|
|
+ this.$msg('门店的门牌号未填写')
|
|
|
+ } else {
|
|
|
+ console.log(result.msg);
|
|
|
+ uni.showToast({
|
|
|
+ title: '更新失败',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ uni.hideLoading();
|
|
|
+ console.error('更新门店地址失败:', error);
|
|
|
+ if(error.msg && error.msg.includes('content.address_info.house is empty')){
|
|
|
+ this.$msg('门店的门牌号未填写')
|
|
|
+ } else {
|
|
|
+ console.log(error.msg);
|
|
|
+ this.$msg('更新失败')
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 获取账户余额
|
|
|
+ async getBalance() {
|
|
|
+ try {
|
|
|
+ const result = await getStoreBalance();
|
|
|
+ this.balance = result.data.all_balance || 0;
|
|
|
+ // 获取顺丰和达达的余额
|
|
|
+ this.sfBalance = result.data.sf_balance || 0;
|
|
|
+ this.dadaBalance = result.data.dada_balance || 0;
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error);
|
|
|
+ // console.error('获取余额失败:', error);
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 获取充值记录
|
|
|
+ async getRechargeRecords() {
|
|
|
+ try {
|
|
|
+ // 这里调用实际的API获取充值记录
|
|
|
+ // const result = await getRechargeRecords();
|
|
|
+ // this.rechargeRecords = result.data || [];
|
|
|
+
|
|
|
+ // 模拟数据
|
|
|
+ this.rechargeRecords = [
|
|
|
+ {
|
|
|
+ amount: 100,
|
|
|
+ time: '2024-01-15 14:30:25',
|
|
|
+ status: 'success',
|
|
|
+ statusText: '充值成功'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ amount: 200,
|
|
|
+ time: '2024-01-10 09:15:30',
|
|
|
+ status: 'success',
|
|
|
+ statusText: '充值成功'
|
|
|
+ }
|
|
|
+ ];
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取充值记录失败:', error);
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 显示充值弹窗
|
|
|
+ showRechargeModal() {
|
|
|
+ this.showModal = true;
|
|
|
+ this.rechargeAmount = '';
|
|
|
+ this.expressCompany = 'DADA'; // 默认选择顺丰
|
|
|
+ },
|
|
|
+
|
|
|
+ // 隐藏充值弹窗
|
|
|
+ hideRechargeModal() {
|
|
|
+ this.showModal = false;
|
|
|
+ this.rechargeAmount = '';
|
|
|
+ this.payUrl = '';
|
|
|
+ this.showPayUrl = false;
|
|
|
+ },
|
|
|
+
|
|
|
+ // 选择跑腿公司
|
|
|
+ selectExpressCompany(company) {
|
|
|
+ this.expressCompany = company;
|
|
|
+ },
|
|
|
+
|
|
|
+ // 金额输入处理
|
|
|
+ onAmountInput(e) {
|
|
|
+ let value = e.detail.value;
|
|
|
+ // 限制只能输入数字和小数点
|
|
|
+ value = value.replace(/[^\d.]/g, '');
|
|
|
+ // 限制小数点后两位
|
|
|
+ if (value.includes('.')) {
|
|
|
+ const parts = value.split('.');
|
|
|
+ if (parts[1].length > 2) {
|
|
|
+ value = parts[0] + '.' + parts[1].substring(0, 2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.rechargeAmount = value;
|
|
|
+ },
|
|
|
+
|
|
|
+ // 选择快捷金额
|
|
|
+ selectAmount(amount) {
|
|
|
+ this.rechargeAmount = amount.toString();
|
|
|
+ },
|
|
|
+
|
|
|
+ // 确认充值
|
|
|
+ async confirmRecharge() {
|
|
|
+ if (!this.canRecharge) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请输入有效金额',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const amount = parseFloat(this.rechargeAmount);
|
|
|
+
|
|
|
+ try {
|
|
|
+ uni.showLoading({
|
|
|
+ title: '充值中...'
|
|
|
+ });
|
|
|
+
|
|
|
+ // 调用实际的充值API,传入金额和跑腿公司
|
|
|
+ const result = await rechargeStore({
|
|
|
+ amount: amount,
|
|
|
+ expressId: this.expressCompany // 添加跑腿公司参数
|
|
|
+ });
|
|
|
+
|
|
|
+ uni.hideLoading();
|
|
|
+
|
|
|
+ if (result.code === 1 && result.data && result.data.payurl) {
|
|
|
+ // 保存支付链接并显示
|
|
|
+ this.payUrl = result.data.payurl;
|
|
|
+ this.showPayUrl = true;
|
|
|
+
|
|
|
+ // 不关闭弹窗,而是显示支付链接
|
|
|
+ } else {
|
|
|
+ // 充值单生成成功但没有支付链接
|
|
|
+ uni.showToast({
|
|
|
+ title: '充值单已生成',
|
|
|
+ icon: 'success'
|
|
|
+ });
|
|
|
+
|
|
|
+ this.hideRechargeModal();
|
|
|
+
|
|
|
+ // 刷新余额和记录
|
|
|
+ await this.initExpress()
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (error) {
|
|
|
+ uni.hideLoading();
|
|
|
+ console.error('充值失败:', error);
|
|
|
+ uni.showToast({
|
|
|
+ title: '充值失败,请重试',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.app-content {
|
|
|
+ min-height: 100vh;
|
|
|
+ background-color: #f5f5f5;
|
|
|
+ padding: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+// 门店地址管理样式
|
|
|
+.shop-address-section {
|
|
|
+ background-color: #ffffff;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ padding: 30rpx;
|
|
|
+ margin-bottom: 30rpx;
|
|
|
+ box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
|
|
|
+}
|
|
|
+
|
|
|
+.section-header {
|
|
|
+ margin-bottom: 30rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.section-title {
|
|
|
+ color: #333333;
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: 600;
|
|
|
+}
|
|
|
+
|
|
|
+.shop-info-card {
|
|
|
+ &.empty {
|
|
|
+ text-align: center;
|
|
|
+ padding: 40rpx 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.shop-status {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ margin-bottom: 25rpx;
|
|
|
+
|
|
|
+ &.success {
|
|
|
+ .status-icon {
|
|
|
+ color: #52c41a;
|
|
|
+ background-color: #f6ffed;
|
|
|
+ border: 2rpx solid #b7eb8f;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &.warning {
|
|
|
+ .status-icon {
|
|
|
+ color: #faad14;
|
|
|
+ background-color: #fffbe6;
|
|
|
+ border: 2rpx solid #ffe58f;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.status-icon {
|
|
|
+ width: 40rpx;
|
|
|
+ height: 40rpx;
|
|
|
+ border-radius: 50%;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ font-size: 24rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ margin-right: 15rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.status-text {
|
|
|
+ color: #333333;
|
|
|
+ font-size: 30rpx;
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+
|
|
|
+.shop-desc {
|
|
|
+ margin-bottom: 30rpx;
|
|
|
+
|
|
|
+ .desc-text {
|
|
|
+ color: #666666;
|
|
|
+ font-size: 26rpx;
|
|
|
+ line-height: 1.5;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.shop-details {
|
|
|
+ margin-bottom: 30rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.detail-item {
|
|
|
+ display: flex;
|
|
|
+ margin-bottom: 15rpx;
|
|
|
+
|
|
|
+ &:last-child {
|
|
|
+ margin-bottom: 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.detail-label {
|
|
|
+ color: #666666;
|
|
|
+ font-size: 26rpx;
|
|
|
+ min-width: 140rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.detail-value {
|
|
|
+ color: #333333;
|
|
|
+ font-size: 26rpx;
|
|
|
+ flex: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.create-btn, .update-btn {
|
|
|
+ width: 60%;
|
|
|
+ height: 80rpx;
|
|
|
+ border-radius: 40rpx;
|
|
|
+ border: none;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ font-size: 28rpx;
|
|
|
+ font-weight: 500;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+}
|
|
|
+
|
|
|
+.create-btn {
|
|
|
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
+ box-shadow: 0 8rpx 24rpx rgba(102, 126, 234, 0.3);
|
|
|
+
|
|
|
+ .btn-text {
|
|
|
+ color: #ffffff;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:active {
|
|
|
+ transform: translateY(2rpx);
|
|
|
+ box-shadow: 0 4rpx 12rpx rgba(102, 126, 234, 0.3);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.update-btn {
|
|
|
+ background: linear-gradient(135deg, #52c41a 0%, #389e0d 100%);
|
|
|
+ box-shadow: 0 8rpx 24rpx rgba(82, 196, 26, 0.3);
|
|
|
+
|
|
|
+ .btn-text {
|
|
|
+ color: #ffffff;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:active {
|
|
|
+ transform: translateY(2rpx);
|
|
|
+ box-shadow: 0 4rpx 12rpx rgba(82, 196, 26, 0.3);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 余额卡片样式
|
|
|
+.balance-card {
|
|
|
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
+ border-radius: 20rpx;
|
|
|
+ padding: 40rpx 30rpx;
|
|
|
+ margin-bottom: 30rpx;
|
|
|
+ box-shadow: 0 8rpx 32rpx rgba(102, 126, 234, 0.3);
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+
|
|
|
+.balance-left {
|
|
|
+ flex: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.balance-right {
|
|
|
+ width: 200rpx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
+ border-left: 2rpx solid rgba(255, 255, 255, 0.2);
|
|
|
+ padding-left: 30rpx;
|
|
|
+ margin-left: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.balance-header {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.balance-title {
|
|
|
+ color: rgba(255, 255, 255, 0.9);
|
|
|
+ font-size: 28rpx;
|
|
|
+ font-weight: 400;
|
|
|
+}
|
|
|
+
|
|
|
+.balance-amount {
|
|
|
+ margin-bottom: 15rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: baseline;
|
|
|
+}
|
|
|
+
|
|
|
+.amount-text {
|
|
|
+ color: #ffffff;
|
|
|
+ font-size: 60rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ font-family: 'DIN Alternate', sans-serif;
|
|
|
+}
|
|
|
+
|
|
|
+.balance-unit {
|
|
|
+ color: rgba(255, 255, 255, 0.7);
|
|
|
+ font-size: 24rpx;
|
|
|
+ margin-left: 10rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.balance-desc {
|
|
|
+ .desc-text {
|
|
|
+ color: rgba(255, 255, 255, 0.8);
|
|
|
+ font-size: 21rpx;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.sub-balance {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ padding: 10rpx 0;
|
|
|
+
|
|
|
+ &.sf {
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+ padding-bottom: 20rpx;
|
|
|
+ border-bottom: 2rpx solid rgba(255, 255, 255, 0.2);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.sub-balance-label {
|
|
|
+ color: rgba(255, 255, 255, 0.8);
|
|
|
+ font-size: 24rpx;
|
|
|
+ margin-bottom: 8rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.sub-balance-amount {
|
|
|
+ color: #ffffff;
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ font-family: 'DIN Alternate', sans-serif;
|
|
|
+}
|
|
|
+
|
|
|
+// 充值按钮样式
|
|
|
+.recharge-section {
|
|
|
+ margin-bottom: 30rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.recharge-btn {
|
|
|
+ width: 60%;
|
|
|
+ height: 88rpx;
|
|
|
+ background: linear-gradient(135deg, #ff6b6b 0%, #ee5a24 100%);
|
|
|
+ border-radius: 44rpx;
|
|
|
+ border: none;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ box-shadow: 0 8rpx 24rpx rgba(255, 107, 107, 0.3);
|
|
|
+ transition: all 0.3s ease;
|
|
|
+}
|
|
|
+
|
|
|
+.recharge-btn:active {
|
|
|
+ transform: translateY(2rpx);
|
|
|
+ box-shadow: 0 4rpx 12rpx rgba(255, 107, 107, 0.3);
|
|
|
+}
|
|
|
+
|
|
|
+.btn-text {
|
|
|
+ color: #ffffff;
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: 600;
|
|
|
+}
|
|
|
+
|
|
|
+// 记录区域样式
|
|
|
+.record-section {
|
|
|
+ background-color: #ffffff;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ padding: 30rpx;
|
|
|
+ box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
|
|
|
+}
|
|
|
+
|
|
|
+.record-list {
|
|
|
+ .record-item {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ padding: 25rpx 0;
|
|
|
+ border-bottom: 1rpx solid #f0f0f0;
|
|
|
+
|
|
|
+ &:last-child {
|
|
|
+ border-bottom: none;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .record-info {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ }
|
|
|
+
|
|
|
+ .record-amount {
|
|
|
+ color: #333333;
|
|
|
+ font-size: 30rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ margin-bottom: 8rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .record-time {
|
|
|
+ color: #999999;
|
|
|
+ font-size: 24rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .record-status {
|
|
|
+ font-size: 26rpx;
|
|
|
+ padding: 8rpx 16rpx;
|
|
|
+ border-radius: 20rpx;
|
|
|
+
|
|
|
+ &.success {
|
|
|
+ color: #52c41a;
|
|
|
+ background-color: #f6ffed;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.pending {
|
|
|
+ color: #faad14;
|
|
|
+ background-color: #fffbe6;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.failed {
|
|
|
+ color: #ff4d4f;
|
|
|
+ background-color: #fff2f0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.empty-record {
|
|
|
+ text-align: center;
|
|
|
+ padding: 60rpx 0;
|
|
|
+
|
|
|
+ .empty-text {
|
|
|
+ color: #999999;
|
|
|
+ font-size: 28rpx;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 支付链接样式
|
|
|
+.pay-url-section {
|
|
|
+ padding: 20rpx 0;
|
|
|
+}
|
|
|
+
|
|
|
+.pay-url-title {
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+ text-align: center;
|
|
|
+
|
|
|
+ text {
|
|
|
+ color: #333333;
|
|
|
+ font-size: 28rpx;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.pay-url-box {
|
|
|
+ background-color: #f5f5f5;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ padding: 20rpx;
|
|
|
+ margin-bottom: 30rpx;
|
|
|
+ word-break: break-all;
|
|
|
+ border: 2rpx dashed #ddd;
|
|
|
+}
|
|
|
+
|
|
|
+.pay-url-text {
|
|
|
+ color: #0066cc;
|
|
|
+ font-size: 26rpx;
|
|
|
+ line-height: 1.5;
|
|
|
+}
|
|
|
+
|
|
|
+.copy-btn-wrapper {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+
|
|
|
+.copy-btn {
|
|
|
+ width: 60%;
|
|
|
+ height: 80rpx;
|
|
|
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
+ border-radius: 40rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ box-shadow: 0 8rpx 16rpx rgba(102, 126, 234, 0.3);
|
|
|
+ transition: all 0.3s ease;
|
|
|
+
|
|
|
+ &:active {
|
|
|
+ transform: translateY(2rpx);
|
|
|
+ box-shadow: 0 4rpx 8rpx rgba(102, 126, 234, 0.3);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.copy-btn-text {
|
|
|
+ color: #ffffff;
|
|
|
+ font-size: 28rpx;
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+
|
|
|
+// 弹窗样式
|
|
|
+.modal-overlay {
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ bottom: 0;
|
|
|
+ background-color: rgba(0, 0, 0, 0.5);
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ z-index: 9999;
|
|
|
+}
|
|
|
+
|
|
|
+.modal-content {
|
|
|
+ width: 600rpx;
|
|
|
+ background-color: #ffffff;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ overflow: hidden;
|
|
|
+ animation: modalSlideIn 0.3s ease;
|
|
|
+}
|
|
|
+
|
|
|
+@keyframes modalSlideIn {
|
|
|
+ from {
|
|
|
+ opacity: 0;
|
|
|
+ transform: scale(0.8) translateY(50rpx);
|
|
|
+ }
|
|
|
+ to {
|
|
|
+ opacity: 1;
|
|
|
+ transform: scale(1) translateY(0);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.modal-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ padding: 30rpx;
|
|
|
+ border-bottom: 1rpx solid #f0f0f0;
|
|
|
+}
|
|
|
+
|
|
|
+.modal-title {
|
|
|
+ color: #333333;
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: 600;
|
|
|
+}
|
|
|
+
|
|
|
+.modal-close {
|
|
|
+ color: #999999;
|
|
|
+ font-size: 40rpx;
|
|
|
+ line-height: 1;
|
|
|
+ padding: 10rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.modal-body {
|
|
|
+ padding: 30rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.form-item {
|
|
|
+ margin-bottom: 30rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.form-label {
|
|
|
+ display: block;
|
|
|
+ color: #333333;
|
|
|
+ font-size: 28rpx;
|
|
|
+ font-weight: 500;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.amount-input-wrapper {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ border: 2rpx solid #e8e8e8;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ padding: 0 20rpx;
|
|
|
+ background-color: #fafafa;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+
|
|
|
+ &:focus-within {
|
|
|
+ border-color: #667eea;
|
|
|
+ background-color: #ffffff;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.currency-symbol {
|
|
|
+ color: #333333;
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ margin-right: 15rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.amount-input {
|
|
|
+ flex: 1;
|
|
|
+ height: 80rpx;
|
|
|
+ font-size: 32rpx;
|
|
|
+ color: #333333;
|
|
|
+ background: transparent;
|
|
|
+ border: none;
|
|
|
+}
|
|
|
+
|
|
|
+.quick-amounts {
|
|
|
+ margin-top: 30rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.quick-title {
|
|
|
+ display: block;
|
|
|
+ color: #666666;
|
|
|
+ font-size: 26rpx;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.amount-options {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.amount-option {
|
|
|
+ flex: 1;
|
|
|
+ min-width: 120rpx;
|
|
|
+ height: 70rpx;
|
|
|
+ border: 2rpx solid #e8e8e8;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ background-color: #ffffff;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+
|
|
|
+ &.active {
|
|
|
+ border-color: #667eea;
|
|
|
+ background-color: #667eea;
|
|
|
+
|
|
|
+ .option-text {
|
|
|
+ color: #ffffff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &:active {
|
|
|
+ transform: scale(0.95);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.option-text {
|
|
|
+ color: #333333;
|
|
|
+ font-size: 26rpx;
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+
|
|
|
+// 跑腿公司选择样式
|
|
|
+.express-company-options {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ gap: 30rpx;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.express-option {
|
|
|
+ height: 80rpx;
|
|
|
+ border: 2rpx solid #e8e8e8;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ padding: 0 20rpx;
|
|
|
+ background-color: #ffffff;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+
|
|
|
+ &.active {
|
|
|
+ border-color: #667eea;
|
|
|
+ background-color: #f0f4ff;
|
|
|
+
|
|
|
+ .express-option-text {
|
|
|
+ color: #667eea;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &:active {
|
|
|
+ transform: scale(0.98);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.express-option-text {
|
|
|
+ color: #333333;
|
|
|
+ font-size: 28rpx;
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+
|
|
|
+.modal-footer {
|
|
|
+ display: flex;
|
|
|
+ border-top: 1rpx solid #f0f0f0;
|
|
|
+}
|
|
|
+
|
|
|
+.cancel-btn, .confirm-btn {
|
|
|
+ flex: 1;
|
|
|
+ height: 88rpx;
|
|
|
+ border: 1rpx solid #e8e8e8;
|
|
|
+ border-radius: 8rpx;
|
|
|
+ font-size: 30rpx;
|
|
|
+ font-weight: 500;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+
|
|
|
+.cancel-btn {
|
|
|
+ background-color: #f5f5f5;
|
|
|
+
|
|
|
+ .cancel-text {
|
|
|
+ color: #666666;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.confirm-btn {
|
|
|
+ background-color: #52c41a;
|
|
|
+
|
|
|
+ .confirm-text {
|
|
|
+ color: #666666;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:disabled {
|
|
|
+ background-color: #f5f5f5 !important;
|
|
|
+
|
|
|
+ .confirm-text {
|
|
|
+ color: #666666 !important;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|