1、合作商余额查询

2、分油账户司机可用额度
This commit is contained in:
2026-10-20 23:21:10 +08:00
parent 45452c1799
commit fafd3e2c16
134 changed files with 2344 additions and 352 deletions
+4 -47
View File
@@ -2,7 +2,6 @@
<view class="container">
<!-- 搜索框 -->
<search class="search" tips="搜索商品" @event="$navTo('pages/search/index')" />
<select-province class='province' ref="choiceProvince" :provinces="provinceList" :value="province" @change="onProvinceChange" v-model="province" />
<!-- 一级分类 -->
<primary v-if="setting.style == PageCategoryStyleEnum.ONE_LEVEL_BIG.value || setting.style == PageCategoryStyleEnum.ONE_LEVEL_SMALL.value"
:display="setting.style" :list="list" />
@@ -16,7 +15,6 @@
</template>
<script>
import SelectProvince from '@/components/select-province/select-province'
import MescrollCompMixin from '@/components/mescroll-uni/mixins/mescroll-comp'
import { setCartTabBadge } from '@/core/app'
import SettingKeyEnum from '@/common/enum/setting/Key'
@@ -38,8 +36,7 @@
Empty,
Primary,
Secondary,
Commodity,
SelectProvince
Commodity
},
mixins: [MescrollCompMixin],
data() {
@@ -53,9 +50,6 @@
trade: {},
// 正在加载中
isLoading: true,
// 地区
provinceList: [],
province: '',
}
},
@@ -77,26 +71,9 @@
}
},
methods: {
async initPage(){
try {
// 第一步:获取商城设置(等待返回)
const setting = await SettingModel.data(false) // 如果你不传参数,默认根据配置决定是否用缓存
console.log('商城设置:', setting)
const trade = setting[SettingKeyEnum.TRADE.value]
this.provinceList = trade.province_list.split(',')
// 第二步:获取本地已选择的省份
const savedProvince = uni.getStorageSync('province')
if (savedProvince) {
this.province = savedProvince
this.onRefreshPage()
} else {
this.$refs.choiceProvince.open()
}
} catch (e) {
console.error('获取商城设置失败:', e)
}
// 分类不再按省份过滤,进页面直接加载
initPage(){
this.onRefreshPage()
},
// 刷新页面
@@ -136,7 +113,6 @@
initSetting(setting) {
this.setting = setting[SettingKeyEnum.PAGE_CATEGORY_TEMPLATE.value]
this.trade = setting[SettingKeyEnum.TRADE.value]
this.provinceList = this.trade.province_list.split(',')
},
/**
@@ -146,15 +122,6 @@
initCategory(result) {
this.list = result.data.list
},
onProvinceChange(val) {
this.province = val
// 存储省份
uni.setStorageSync('province', val)
// 加载页面数据
this.onRefreshPage()
}
},
/**
@@ -197,15 +164,5 @@
left: var(--window-left);
right: var(--window-right);
z-index: 9;
width: 78%;
}
.province {
position: fixed;
top: var(--window-top);
right: var(--window-right);
width: 20%;
height: 40px;
z-index: 9;
line-height: 40px;
}
</style>
+35
View File
@@ -30,6 +30,24 @@
</view>
</view>
<!-- 实名信息(油券发放实名制:上游分油前核验姓名+身份证号) -->
<view v-if="personal.hasOilGoods" class="flow-realname b-f" @click="onNavRealname">
<view class="flow-realname__hd dis-flex flex-x-between flex-y-center">
<text class="f-28">实名信息</text>
<view class="dis-flex flex-y-center">
<text v-if="personal.isRealnameReady" class="f-26 col-9">已完善</text>
<text v-else class="f-26 col-m">请完善</text>
<text class="right-arrow iconfont icon-arrow-right"></text>
</view>
</view>
<view v-if="personal.isRealnameReady" class="flow-realname__bd">
<text class="f-26 col-6">{{ personal.real_name }}&nbsp;&nbsp;{{ maskIdCard(personal.id_card) }}&nbsp;&nbsp;{{ personal.plate_no }}</text>
</view>
<view v-else class="flow-realname__bd">
<text class="f-24 col-9">油券为实名发放,下单前请先填写姓名、身份证号和车牌号</text>
</view>
</view>
<!-- 商品列表 -->
<view class="m-top20">
<view class="checkout_list" v-for="(item, index) in order.goodsList" :key="index">
@@ -435,6 +453,17 @@
this.$navTo('pages/goods/detail', { goodsId })
},
// 跳转到实名信息页(back=1 表示保存后返回本页)
onNavRealname() {
this.$navTo('pages/user/realname/index', { back: 1 })
},
// 身份证号脱敏展示
maskIdCard(value) {
const str = String(value || '')
return str.length < 8 ? str : `${str.substr(0, 4)}**********${str.substr(-4)}`
},
// 订单提交
onSubmitOrder() {
const app = this
@@ -445,6 +474,12 @@
if (!app.onVerifyFrom()) {
return false
}
// 油券实名制:缺信息先去补全,补完返回本页继续下单
if (app.personal.needRealname) {
app.$toast('请先完善姓名、身份证号和车牌号')
app.onNavRealname()
return false
}
// 按钮禁用
app.disabled = true
// 请求api
+21
View File
@@ -443,3 +443,24 @@
}
}
// 实名信息(油券发放实名制)
.flow-realname {
margin-top: 20rpx;
padding: 24rpx 30rpx;
&__hd {
line-height: 44rpx;
}
&__bd {
margin-top: 10rpx;
line-height: 36rpx;
}
.right-arrow {
margin-left: 8rpx;
color: #999;
font-size: 24rpx;
}
}
+22 -4
View File
@@ -106,12 +106,13 @@
</view>
<!-- 申请支付码 -->
<view class="goods-refund">
<text v-if="goods.use_status" class="stata-text">已加油</text>
<text v-if="goods.refund_status == 2" class="stata-text">已退款</text>
<text v-else-if="goods.oil_status && oilRemain(goods) <= 0" class="stata-text">已加完</text>
<!-- #ifdef MP-WEIXIN -->
<view v-else-if="order.order_status === 10 && goods.oil_status" class="action-btn" @click.stop="layerPayQrcode(goods.order_goods_id)">核销码</view>
<view v-else-if="order.order_status === 10 && goods.oil_status" class="action-btn" @click.stop="layerPayQrcode(goods.order_goods_id)">去加油</view>
<!-- #endif -->
<!-- #ifdef !MP-WEIXIN -->
<view v-else-if="order.order_status === 10 && goods.oil_status" class="action-btn" @click.stop="handlePayQrcode(goods.order_goods_id)">核销码</view>
<view v-else-if="order.order_status === 10 && goods.oil_status" class="action-btn" @click.stop="handlePayQrcode(goods.order_goods_id)">去加油</view>
<!-- #endif -->
</view>
<!-- 商品售后 -->
@@ -119,8 +120,17 @@
<text v-if="goods.refund" class="stata-text">已申请售后</text>
<view v-else-if="order.isAllowRefund" class="action-btn" @click.stop="handleApplyRefund(goods.order_goods_id)">申请售后</view>
</view> -->
<!-- 发放进度:7.7 运单油费下发是异步的,受理后要等上游发放结果 -->
<view v-if="goods.oilCardType === 'zsy_ticket' && goods.oilCardNo && !goods.oil_status" class="order-countdown">
<text v-if="goods.oil_status_zsy == 3" class="f-24 col-m">发放失败:{{ goods.oil_text || '请联系客服' }}</text>
<text v-else class="f-24 col-9">油费发放中,请稍候…</text>
</view>
<!-- 加油进度:一张订单可以分多次加油 -->
<view v-if="goods.used_num > 0" class="order-countdown">
<text class="f-24 col-9">已加油¥{{ goods.used_amount }}({{ goods.used_num }}次),剩余¥{{ oilRemain(goods).toFixed(2) }}</text>
</view>
<!-- 过期剩余时间 -->
<view v-if="order.order_status === 10 && goods.oil_status && !goods.use_status" class="order-countdown">
<view v-if="order.order_status === 10 && goods.oil_status && !goods.use_status && goods.expiration_time > 0" class="order-countdown">
<text class="m-r-6">剩余时间</text>
<count-down :date="goods.expiration_time" separator="zh" theme="text" />
</view>
@@ -342,6 +352,14 @@
canReset && uni.$emit('syncRefresh', true, true)
},
// 剩余可加油金额 = 发放金额 - 已加油 - 已退款(一单可分多次加油)
oilRemain(goods) {
const total = Number(goods.total_price || 0)
const used = Number(goods.used_amount || 0)
const refund = Number(goods.refund_amount || 0)
return Math.max(0, Math.round((total - used - refund) * 100) / 100)
},
// 获取核销码,弹窗展示二维码
layerPayQrcode(orderGoodsId) {
uni.navigateTo({
+22 -4
View File
@@ -44,18 +44,28 @@
</view>
<!-- 申请支付码 -->
<view class="goods-refund">
<text v-if="goods.use_status" class="stata-text">已加油</text>
<text v-if="goods.refund_status == 2" class="stata-text">已退款</text>
<text v-else-if="goods.oil_status && oilRemain(goods) <= 0" class="stata-text">已加完</text>
<!-- #ifdef MP-WEIXIN -->
<view v-else-if="item.order_status === 10 && goods.oil_status" class="action-btn" @click.stop="layerPayQrcode(goods.order_goods_id)">核销码</view>
<view v-else-if="item.order_status === 10 && goods.oil_status" class="action-btn" @click.stop="layerPayQrcode(goods.order_goods_id)">去加油</view>
<!-- #endif -->
<!-- #ifdef !MP-WEIXIN -->
<view v-else-if="item.order_status === 10 && goods.oil_status" class="action-btn" @click.stop="handlePayQrcode(goods.order_goods_id)">核销码</view>
<view v-else-if="item.order_status === 10 && goods.oil_status" class="action-btn" @click.stop="handlePayQrcode(goods.order_goods_id)">去加油</view>
<!-- #endif -->
</view>
</view>
</view>
<!-- 发放进度:7.7 运单油费下发是异步的,受理后要等上游发放结果 -->
<view v-if="goods.oilCardType === 'zsy_ticket' && goods.oilCardNo && !goods.oil_status" class="order-countdown">
<text v-if="goods.oil_status_zsy == 3" class="f-24 col-m">发放失败:{{ goods.oil_text || '请联系客服' }}</text>
<text v-else class="f-24 col-9">油费发放中,请稍候…</text>
</view>
<!-- 加油进度:一张订单可以分多次加油 -->
<view v-if="goods.used_num > 0" class="order-countdown">
<text class="f-24 col-9">已加油¥{{ goods.used_amount }}({{ goods.used_num }}次),剩余¥{{ oilRemain(goods).toFixed(2) }}</text>
</view>
<!-- 过期剩余时间 -->
<view v-if="item.order_status === 10 && goods.oil_status && !goods.use_status" class="order-countdown">
<view v-if="item.order_status === 10 && goods.oil_status && !goods.use_status && goods.expiration_time > 0" class="order-countdown">
<text class="m-r-6">剩余时间</text>
<count-down :date="goods.expiration_time" separator="zh" theme="text" />
</view>
@@ -352,6 +362,14 @@
});
},
// 剩余可加油金额 = 发放金额 - 已加油 - 已退款(一单可分多次加油)
oilRemain(goods) {
const total = Number(goods.total_price || 0)
const used = Number(goods.used_amount || 0)
const refund = Number(goods.refund_amount || 0)
return Math.max(0, Math.round((total - used - refund) * 100) / 100)
},
// 获取核销码,弹窗展示二维码
layerPayQrcode(orderGoodsId) {
uni.navigateTo({
+1
View File
@@ -168,6 +168,7 @@
* id: 标识; name: 标题名称; icon: 图标; type 类型(link和button); url: 跳转的链接
*/
const service = [
{ id: 'realname', name: '实名信息', icon: 'profile', type: 'link', url: 'pages/user/realname/index' },
{ id: 'address', name: '收货地址', icon: 'shouhuodizhi', type: 'link', url: 'pages/address/index' },
{ id: 'coupon', name: '领券中心', icon: 'lingquan', type: 'link', url: 'pages/coupon/index' },
// { id: 'myCoupon', name: '优惠券', icon: 'youhuiquan', type: 'link', url: 'pages/my-coupon/index' },
+221
View File
@@ -0,0 +1,221 @@
<template>
<view class="container">
<!-- 页面头部 -->
<view class="header">
<view class="title">
<text>完善实名信息</text>
</view>
<view class="sub-title">
<text>油券发放为实名制,需核验姓名与身份证号;车牌号仅用于您的加油记录。</text>
</view>
</view>
<!-- 表单 -->
<view class="submit-form">
<!-- 姓名 -->
<view class="form-item">
<text class="form-item--label">姓&emsp;&emsp;名</text>
<input class="form-item--input" type="text" v-model="realName" maxlength="20" placeholder="请输入身份证上的姓名" />
</view>
<!-- 身份证号 -->
<view class="form-item">
<text class="form-item--label">身份证号</text>
<input
class="form-item--input"
type="idcard"
v-model="idCard"
maxlength="18"
:disabled="idCardLocked"
:placeholder="idCardLocked ? '已核验,不可修改' : '请输入18位身份证号'"
/>
</view>
<!-- 车牌号 -->
<view class="form-item">
<text class="form-item--label">车&ensp;牌&ensp;号</text>
<input class="form-item--input" type="text" v-model="plateNo" maxlength="8" placeholder="如 闽A12345" />
</view>
<view v-if="idCardLocked" class="tips">
<text>身份证号已用于油券发放,如需变更请联系客服。</text>
</view>
<!-- 保存 -->
<view class="submit-button" :class="{ disabled: isLoading }" @click="handleSubmit()">
<text>保存</text>
</view>
</view>
</view>
</template>
<script>
import * as UserApi from '@/api/user'
export default {
data() {
return {
// 正在加载
isLoading: false,
// 姓名
realName: '',
// 身份证号
idCard: '',
// 车牌号
plateNo: '',
// 身份证号是否已锁定(已用于分油,不允许再改)
idCardLocked: false,
// 保存成功后是否返回上一页(从结算台跳过来时为 1)
back: 0
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.back = Number(options.back || 0)
this.getDetail()
},
methods: {
// 获取已保存的实名信息
getDetail() {
const app = this
app.isLoading = true
UserApi.realname()
.then(result => {
const { realname } = result.data
app.realName = realname.realName
app.idCard = realname.idCard
app.plateNo = realname.plateNo
app.idCardLocked = realname.idCardLocked
})
.finally(() => app.isLoading = false)
},
// 点击保存
handleSubmit() {
const app = this
if (app.isLoading || !app.formValidation()) {
return false
}
app.isLoading = true
UserApi.saveRealname({
form: {
realName: app.realName,
idCard: app.idCard,
plateNo: app.plateNo
}
})
.then(result => {
app.$toast(result.message)
// 从结算台跳过来的:保存完回到结算台继续下单
setTimeout(() => {
app.back ? uni.navigateBack({ delta: 1 }) : app.getDetail()
}, 1200)
})
.finally(() => app.isLoading = false)
},
// 表单验证
formValidation() {
const app = this
const realName = (app.realName || '').trim()
const idCard = (app.idCard || '').trim().toUpperCase()
const plateNo = (app.plateNo || '').trim().toUpperCase()
if (!/^[一-龥][一-龥·]{1,19}$/.test(realName)) {
app.$toast('请填写身份证上的中文姓名')
return false
}
if (!/^\d{17}[\dX]$/.test(idCard)) {
app.$toast('身份证号格式不正确(18位)')
return false
}
// 省份简称 + 城市字母(不含 I/O) + 5~7 位序号(含新能源 8 位车牌)
if (!/^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z][A-HJ-NP-Z0-9]{4,6}$/.test(plateNo)) {
app.$toast('车牌号格式不正确')
return false
}
app.realName = realName
app.idCard = idCard
app.plateNo = plateNo
return true
}
}
}
</script>
<style lang="scss" scoped>
.container {
padding: 80rpx 60rpx;
min-height: 100vh;
background-color: #fff;
}
// 页面头部
.header {
margin-bottom: 50rpx;
.title {
color: #191919;
font-size: 50rpx;
}
.sub-title {
margin-top: 20rpx;
color: #b3b3b3;
font-size: 25rpx;
line-height: 38rpx;
}
}
// 输入框元素
.form-item {
display: flex;
align-items: center;
padding: 18rpx;
border-bottom: 1rpx solid #f3f1f2;
margin-bottom: 25rpx;
height: 96rpx;
&--label {
width: 180rpx;
font-size: 28rpx;
color: #555;
}
&--input {
font-size: 28rpx;
letter-spacing: 1rpx;
flex: 1;
height: 100%;
}
}
.tips {
margin-top: 10rpx;
font-size: 24rpx;
color: #f37b1d;
line-height: 36rpx;
}
// 提交按钮
.submit-button {
margin-top: 70rpx;
height: 88rpx;
line-height: 88rpx;
text-align: center;
color: #fff;
font-size: 30rpx;
border-radius: 44rpx;
background: linear-gradient(to right, #f9211c, #ff6335);
&.disabled {
opacity: 0.6;
}
}
</style>