代码更新

This commit is contained in:
GaoHao
2025-02-26 19:46:20 +08:00
parent 7519ffced3
commit b4a0393d2d
413 changed files with 7483 additions and 60762 deletions

View File

@@ -1,192 +0,0 @@
<template>
<JeepayCustomNavbar bgDefaultColor="#fff" title="关于我们" backCtrl="back" />
<view class="content">
<view class="logo-box">
<view class="app-logo"><image :src="vdata.siteInfos.siteInfo.iconUrl"></image></view>
<view class="app-name">
<text>{{ vdata.siteInfos.siteInfo.companyName }}特约商家</text>
</view>
<view class="app-version">
<!-- #ifdef APP-PLUS -->
<text>{{ vdata.versionName }}</text>
<!-- #endif -->
</view>
</view>
<view class="company-item">
<view class="item">
<view class="title"><text>公司名称</text></view>
<view class="describe">
<text>{{ vdata.siteInfos.siteInfo.companyName }}</text>
</view>
</view>
<view class="item" @tap="call">
<view class="title"><text>联系电话</text></view>
<view class="describe">
<text style="color: #3981ff">{{ vdata.siteInfos.siteInfo.companyTel }}</text>
</view>
</view>
<view class="item">
<view class="title"><text>电子邮箱</text></view>
<view class="describe">
<text>{{ vdata.siteInfos.siteInfo.companyEmail }}</text>
</view>
</view>
<view class="item" @tap="go.to('/pages/login/serviceAgreement')">
<view class="title"><text>服务协议</text></view>
<view class="describe"><image src="@/static/iconImg/icon-arrow-small.svg" class="arrow"></image></view>
</view>
<view class="item" @tap="go.to('/pages/login/privacyPolicy')">
<view class="title"><text>隐私政策</text></view>
<view class="describe"><image src="@/static/iconImg/icon-arrow-small.svg" class="arrow"></image></view>
</view>
<!-- #ifdef APP-PLUS -->
<view class="item" @tap="checkCurrVersion('checked')">
<view class="title"><text>检查新版本</text></view>
<view class="describe">
<text>{{ vdata.versionName }}</text>
</view>
</view>
<!-- #endif -->
</view>
<!-- 拨打电话对话框 -->
<uni-popup ref="phonePopup" type="dialog" @maskClick="closePopup">
<uni-popup-dialog ref="phonePopup" type="dialog" mode="base" @close="close" title="提示" @confirm="confirm">
<view class="tip-content">是否联系客服?</view>
</uni-popup-dialog>
</uni-popup>
</view>
</template>
<script setup>
import { ref, reactive } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import go from '@/commons/utils/go.js';
import storageManage from '@/commons/utils/storageManage.js';
import { checkCurrVersion, getCurrentVersionPromise } from '@/commons/utils/versionManage.js';
let phonePopup = ref();
const vdata = reactive({
siteInfos: storageManage.siteInfos(),
versionName: 'v1.0.0'
});
onLoad(() => {
getCurrentVersionPromise()
.then((res) => {
vdata.versionName = res.version;
})
.catch((error) => {});
});
function close() {
phonePopup.value.close();
}
function confirm() {
phonePopup.value.close();
uni.makePhoneCall({
phoneNumber: vdata.siteInfos.siteInfo.companyTel
});
}
// 拨打电话弹窗
function call() {
phonePopup.value.open();
}
// 关闭电话弹窗
function closePopup() {
phonePopup.value.close();
}
</script>
<style lang="scss" scoped>
page {
background: #fff;
}
.content {
.logo-box {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
height: 373rpx;
overflow: hidden;
.app-logo {
margin: 70rpx 0 50rpx 0;
image {
width: 100rpx;
height: 100rpx;
}
}
.app-name {
margin-bottom: 10rpx;
text {
font-size: 33rpx;
font-weight: 700;
}
}
.app-version {
text {
font-size: 25rpx;
}
}
}
.company-item {
padding: 0 85rpx;
.item {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
height: 110rpx;
.title {
text {
font-size: 28rpx;
color: #666f80;
}
}
.describe {
display: flex;
align-items: center;
text {
font-size: 28rpx;
}
image {
width: 120rpx;
height: 120rpx;
}
}
}
.item:last-child {
border-bottom: 1rpx solid #ededed;
}
.item:first-child {
border-top: 1rpx solid #ededed;
}
}
.tip-content-title {
display: flex;
justify-content: center;
align-items: center;
// height: 80rpx;
padding-top: 20rpx;
font-weight: bold;
font-size: 34rpx;
text-align: left;
color: #0041c4;
letter-spacing: 0.05em;
}
.tip-content {
@extend .tip-content-title;
height: 0;
font-size: 32rpx;
font-weight: 500;
text-align: left;
color: #000;
}
}
.arrow {
transform: translateX(50rpx);
}
</style>

View File

@@ -1,15 +0,0 @@
<template>
<web-view :src="src" />
</template>
<script setup>
import { onLoad } from '@dcloudio/uni-app'
import { ref } from 'vue'
const src = ref('')
onLoad((options) => {
console.log('options.url', options.url)
src.value = options.url
})
</script>
<style lang="scss" scoped></style>

View File

@@ -1,64 +0,0 @@
<template>
<!-- #ifdef MP-WEIXIN -->
<StartPage :flag="!!vdata.list.length" />
<!-- #endif -->
<JeepayAdStart ref="refAdStart" :list="vdata.list" :time="6" :url="vdata.url" @openInt="openInt" />
</template>
<script setup>
import { $adList } from '@/http/apiManager.js';
import storageManage from '@/commons/utils/storageManage.js';
import { reactive } from 'vue';
import appConfig from '@/config/appConfig.js';
import { onShow } from '@dcloudio/uni-app';
import StartPage from './components/StartPage';
onShow(() => {
if (vdata.list.length > 0 && timeStartFlag && opneInterval) {
opneInterval();
}
});
let opneInterval = undefined;
const vdata = reactive({
list: [],
url: ''
});
let timeStartFlag = false;
const params = {
appPlace: 1
};
const isLogin = (flag) => {
// vdata.url = storageManage.token() ? '/pages/index/index' : '/pages/index/indexCopy'
vdata.url = storageManage.token() ? '/pages/index/index' : '/pages/login/index';
if (flag) {
console.log(vdata.url);
if (vdata.url == '/pages/index/index')
return uni.switchTab({
url: vdata.url
});
uni.redirectTo({
url: vdata.url
});
}
};
isLogin();
$adList(params)
.then(({ bizData }) => {
const adDate = bizData.map((v) => JSON.parse(v.appContent));
vdata.list = [...adDate.flat()];
if (!vdata.list.length) {
isLogin(true);
} else {
opneInterval();
timeStartFlag = true;
}
})
.catch((err) => {
opneInterval();
});
const openInt = (fun) => {
opneInterval = fun;
};
</script>
<style lang="scss" scoped></style>

View File

@@ -1,58 +0,0 @@
<template>
<view class="start-wrapper" :class="{ 'start-wrapper-hiddren': flag }">
<view class="iamge-box">
<!-- <image class="start-logo" src="/static/logo.svg" mode="scaleToFill" /> -->
<image class="mch-name" src="/static/startImg/mch-name.svg" mode="scaleToFill" />
</view>
</view>
</template>
<script setup>
import { ref } from "vue"
const props = defineProps({
flag: { type: Boolean, default: false }
})
</script>
<style lang="scss" scoped>
.start-wrapper {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 9999999999;
min-height: 100vh;
background: url("/static/startImg/start-bg.svg") no-repeat top;
background-size: 100%;
// background: #fff;
.iamge-box {
transform: translateY(300rpx);
display: flex;
flex-direction: column;
align-items: center;
.start-logo {
width: 150rpx;
height: 150rpx;
border-radius: 12rpx;
}
.mch-name {
margin-top: 80rpx;
width: 300rpx;
height: 150rpx;
}
}
}
.start-wrapper-hiddren {
transition: 1s cubic-bezier(0.785, 0.135, 0.15, 0.86);
bottom: auto;
top: -100vh;
overflow: hidden;
}
</style>

View File

@@ -1,275 +0,0 @@
<template>
<JeepayCustomNavbar backCtrl="back" bgDefaultColor="#fff" title="支付宝代运营授权" />
<view class="ali-wrapper">
<view class="ali-top">
<image class="ali-image" :src="calcStyleOrImg()" mode="scaleToFill" />
<view class="ali-status" :style="{ color: calcStyleOrImg('color') }">{{ calcAliStatus() }}</view>
<view class="ali-reset" @tap="upDateAliStatus">
<image src="/static/iconImg/ali-resete.svg" mode="scaleToFill" /> 刷新授权状态
</view>
<view class="edit-input flex-center" style="margin-top: 30rpx">
<view class="input-title">支付宝账号</view>
<uni-easyinput :inputBorder="false" v-model="vdata.aliAccount" placeholderStyle=" font-size: 30rpx;color:#ADADAD"
placeholder="请输入支付宝账号以授权" :styles="styles" clearable />
</view>
</view>
<view class="ali-bottom">
<view>
<Button @tap="openPopup">{{ vdata.original?.handleStatus == 'SUCCESS' ? '重新' : '发起' }}授权</Button>
</view>
</view>
</view>
<JSinglePopup :list="list" ref="refSingle" />
<uni-popup type="center" ref="refPopup">
<view class="ali-img-wrapper">
<view class="ali-tips">
请使用支付宝账号{{ vdata.aliAccount }}绑定的支付宝扫码根据页面指引完成授权
</view>
<image class="ali-image" :src="vdata.qrImg" mode="scaleToFill" />
<view class="save-img">
<Button @tap="saveImage(vdata.qrImg)">保存图片</Button>
</view>
</view>
</uni-popup>
</template>
<script setup>
import { $aliPayQrCodeOrApply, $aliAccountInfo } from "@/http/apiManager"
import infoBox from '@/commons/utils/infoBox.js';
import { ref, reactive, onMounted } from "vue"
const vdata = reactive({
aliAccount: '',
original: {},//存储原始数据
})
const styles = {
backgroundColor: 'transparent',
color: '#000',
fontSize: '32rpx',
}
const refSingle = ref(null)
const refPopup = ref(null)
const list = [
{ label: '发送支付宝授权消息', value: 'phone', fun: () => { getAliQrCode('phone') } },
{ label: '使用支付宝扫授权码', value: 'scan', fun: () => { getAliQrCode('scan') } },
]
const getAliQrCode = (v) => {
if (validate()) return
$aliPayQrCodeOrApply(vdata.aliAccount, v == 'phone' ? 'apply' : 'queryQrcode').then(({ bizData }) => {
vdata.qrImg = decodeURIComponent(bizData.qrCodeUrl)
upDateAliStatus()
if (v == 'phone') {
infoBox.showToast('授权消息发送成功 请在支付宝 服务消息点击确认授权')
return
}
refPopup.value.open()
})
}
const getAliInfo = () => {
$aliAccountInfo().then(({ bizData }) => {
if (!bizData) return
vdata.original = bizData
vdata.aliAccount = bizData.alipayAccount
})
}
getAliInfo()
const validate = () => {
// 正则表达式 判断是否包含中文 和 中文符号
const REG = /[\u4e00-\u9fa5|\u3002|\uff1f|\uff01|\uff0c|\u3001|\uff1b|\uff1a|\u201c|\u201d|\u2018|\u2019|\uff08|\uff09|\u300a|\u300b|\u3008|\u3009|\u3010|\u3011|\u300e|\u300f|\u300c|\u300d|\ufe43|\ufe44|\u3014|\u3015|\u2026|\u2014|\uff5e|\ufe4f|\uffe5]/
if (vdata.aliAccount == vdata.original.alipayAccount && vdata.original.handleStatus == 'SUCCESS') return infoBox.showToast('当前支付宝账号已授权通过,无需再次授权。')
if (REG.test(vdata.aliAccount)) return infoBox.showToast('账号格式错误 不能包含中文和中文标点符号')
return false
}
const calcAliStatus = () => {
if (!vdata.original.handleStatus) return '暂未授权'
if (vdata.original.handleStatus == 'SUCCESS') return '已授权'
if (vdata.original.handleStatus == 'PROCESS') return '授权中'
return '暂未授权'
}
const calcStyleOrImg = (v = 'img') => {
if (v == 'img') return vdata.original.handleStatus == 'SUCCESS' ? '/static/iconImg/ali-success.svg' : '/static/iconImg/ali-none.svg'
if (v == 'color') return vdata.original.handleStatus == 'SUCCESS' ? '#000000ff' : '#afbbcbff'
}
// 更新授权状态
const upDateAliStatus = () => {
$aliPayQrCodeOrApply().then(({ bizData }) => {
infoBox.showToast('授权状态更新成功')
if (bizData) vdata.original.handleStatus = bizData.handleStatus
})
}
const saveImage = (key) => {
// #ifdef APP-PLUS
uni.downloadFile({
url: key,
success: (res) => {
if (res.statusCode == 200) {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: (r) => {
infoBox.showSuccessToast('保存成功')
uni.vibrateShort()
},
fail: (er) => {
infoBox.showErrorToast('保存失败')
}
})
}
},
fail: (err) => {
infoBox.showErrorToast('保存失败')
}
})
// #endif
//#ifdef MP-WEIXIN
downloadQR(key)
//#endif
}
//#ifdef MP-WEIXIN
function downloadQR (key) {
console.log('执行');
wx.getSetting({
//获取权限
success (res) {
if (res.authSetting['scope.writePhotosAlbum']) {
if (key == 'authQr') return saveWxQrcodeImg(vdata.authQr)
download(key)
} else {
wx.authorize({
scope: 'scope.writePhotosAlbum',
success () {
if (key == 'authQr') return saveWxQrcodeImg(vdata.authQr)
download(key)
},
})
}
},
})
}
function download (data) {
uni.downloadFile({
url: data,
success: (res) => {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: function () {
infoBox.showSuccessToast('保存成功')
uni.vibrateShort()
},
fail: function (err) {
infoBox.showErrorToast('保存失败')
},
})
},
})
}
//#endif
const openPopup = () =>{
if(!vdata.aliAccount) return infoBox.showToast('请输入支付宝账号。')
refSingle.value.open()
}
</script>
<style lang="scss" scoped>
.ali-wrapper {
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: calc(100vh - 170rpx);
overflow: hidden;
.ali-top {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
.ali-image {
margin-top: 50rpx;
width: 350rpx;
height: 280rpx;
}
.ali-status {
margin: 20rpx 0 50rpx 0;
color: #afbbcbff;
font-size: 36rpx;
font-weight: 500;
}
.ali-reset {
display: flex;
align-items: center;
margin-bottom: 130rpx;
color: #1f7bfeff;
font-size: 26rpx;
image {
margin-right: 15rpx;
width: 28rpx;
height: 28rpx;
}
}
}
.ali-bottom {
display: flex;
justify-content: center;
height: 180rpx;
view {
width: 400rpx;
}
}
}
.edit-input {
padding: 0 20rpx;
width: calc(100% - 100rpx);
flex: 1;
min-height: 120rpx;
border-radius: 32rpx;
background-color: #f7f7f7;
}
.input-title {
margin-left: 40rpx;
font-size: 30rpx;
color: #000;
}
:deep .content-clear-icon {
color: rgb(192, 196, 204) !important;
}
.ali-img-wrapper {
display: flex;
flex-direction: column;
align-items: center;
margin: 0 auto;
width: calc(100% - 60rpx);
min-height: 500rpx;
background-color: #fff;
border-radius: 22rpx;
image {
margin-top: 15rpx;
width: 350rpx;
height: 350rpx;
}
}
.ali-tips {
margin: 30rpx;
margin-bottom: 0;
text-align: center;
color: #808080ff;
font-size: 26rpx;
line-height: 2;
}
.save-img {
margin: 30rpx 0;
width: 80%;
}</style>

View File

@@ -1,17 +0,0 @@
<template>
<view class="">
<uni-forms :modelValue="formData">
</uni-forms>
</view>
</template>
<script setup>
import { ref, reactive } from 'vue';
const formData = reactive({
})
</script>
<style scoped lang="scss"></style>

View File

@@ -1,320 +0,0 @@
<template>
<view class="page-wrapper">
<!-- 搜索栏头部 -->
<view class="search-title">
<view class="search-input">
<!-- <view class="search-input" @tap="go.toSearchPage('mchApplyment')"> -->
<image src="/static/iconImg/icon-search.svg" mode="scaleToFill" class="search-img" />
<input placeholder="搜索商户号/名称" v-model="searchValue" placeholder-class="input-placeholder" @confirm="searchHandle" />
<view class="close" v-if="searchValue" @click="clearHandle">
<image src="/static/iconImg/icon-x.svg" mode="scaleToFill" class="del-img" />
</view>
</view>
<view class="search-state" :class="{ active: searchValue }">
<div class="btn-wrap">
<view class="s-wrap flex-center" @tap="statePopup.open(vdata.searchData.state)" v-if="!searchValue">
{{ vdata.selected.label || '全部状态' }}
<image class="arrow" src="/static/iconImg/icon-arrow-black.svg" mode="scaleToFill" />
</view>
<view class="s-wrap flex-center" @click="searchHandle" v-else>搜索</view>
</div>
</view>
</view>
<JeepayTableList ref="jeepayTableListRef" :reqTableDataFunc="reqTableDataFunc" :searchData="vdata.searchData">
<template #tableBody="{ record }">
<MchApplymentRender :record="record" />
</template>
</JeepayTableList>
<!-- 底部固定按钮 -->
<view class="list-footer">
<view class="button-wrapper">
<Button @tap="toSelectIfCodePage">发起进件</Button>
</view>
</view>
<JSinglePopup :list="stateList" title="按状态筛选" ref="statePopup" @confirm="confirmState" />
<!-- 选择支付 接口 -->
<JeepayPopupListSelect
ref="selectIfcodeRef"
title="请选择渠道"
:reqTableDataFunc="reqTableDataByIfcodeFunc"
:fields="{ key: 'ifCode', left: 'ifName', right: 'ifCode' }"
@confirm="confirmIfCode"
>
<!-- 小程序 插槽不生效 待排查 TODO -->
<!-- 详见 https://ask.dcloud.net.cn/question/158765 -->
<!-- JeepayPopupListSelect.js 修改 "content-" + i0, 改为 content 即可 -->
<!-- #ifdef APP-PLUS || H5 -->
<template #content="{ record }">
<view class="pay-wrapper">
<view class="pay-info">
<view class="pay-logo flex-center" :style="{ backgroundColor: record.bgColor }">
<image :src="record.icon" mode="scaleToFill" />
</view>
<view>
<view class="pay-title">{{ record.ifName }}</view>
</view>
</view>
</view>
</template>
<!-- #endif -->
</JeepayPopupListSelect>
<!-- 选择支付 接口 -->
<JeepayPopupListSelect
ref="selectIncomingRef"
title="请选择场景类型"
:reqTableDataFunc="reqTableIncomingDataByIfcodeFunc"
:fields="{ key: 'range', left: 'name' }"
@confirm="confirmIncoming"
></JeepayPopupListSelect>
</view>
</template>
<script setup>
import { reactive, ref, computed, provide } from 'vue';
import { onReachBottom, onUnload } from '@dcloudio/uni-app';
import go from '@/commons/utils/go.js';
import ak from '@/commons/utils/ak.js';
import { reqLoad, API_URL_MCH_APPLYMENT_LIST, $getAllAllowApplymentIfCodeList } from '@/http/apiManager.js';
import MchApplymentRender from '@/pages/list/render/MchApplymentRender.vue';
onReachBottom(() => {});
const statePopup = ref(null);
const jeepayTableListRef = ref();
const selectIfcodeRef = ref();
const selectIncomingRef = ref();
const searchValue = ref('');
// // 监听 更新事件
onUnload(() => uni.$off(ak.emit.ENAME_REF_APPLYMENT_LIST));
uni.$on(ak.emit.ENAME_REF_APPLYMENT_LIST, function (data) {
jeepayTableListRef.value.refTable(true);
});
const vdata = reactive({
searchData: {
mchApplyName: ''
},
selected: {}, // 当前选择对象
addIfCodeList: [] // 可以选择的接口集合
});
const stateList = reactive([
{ label: '全部', value: '' },
// { label: '草稿', value: '0' },
// { label: '审核中', value: '1' },
{ label: '进件成功', value: '2' },
// { label: '驳回待修改', value: '3' },
// { label: '待验证', value: '4' },
// { label: '待签约', value: '5' },
// { label: '等待预审', value: '7' },
// { label: '预审拒绝', value: '8' },
{ label: '已风控', value: '20' },
{ label: '已冻结', value: '21' },
{ label: '已注销', value: '22' }
]);
// 清空搜索
function clearHandle() {
searchValue.value = '';
vdata.searchData.mchApplyName = searchValue.value;
jeepayTableListRef.value.refTable(true);
}
// 搜索
function searchHandle() {
// reqTableDataFunc({ mchApplyName: searchValue });
vdata.searchData.mchApplyName = searchValue.value;
jeepayTableListRef.value.refTable(true);
}
// 请求
function reqTableDataFunc(params) {
if (!params.state) {
params.state = 99;
}
return reqLoad.list(API_URL_MCH_APPLYMENT_LIST, params);
}
//按状态筛选
function confirmState(r) {
vdata.selected = r || {};
vdata.searchData.state = r.value;
jeepayTableListRef.value.refTable(true);
}
// 打开选择渠道页面
function toAddPage() {
$getAllAllowApplymentIfCodeList().then(({ bizData }) => {
vdata.addIfCodeList = bizData.filter((v) => {
return v.isOpenApplyment == 1;
});
selectIfcodeRef.value.open();
});
}
// 请求可以选择的支付渠道
function reqTableDataByIfcodeFunc() {
// 模拟请求数据
return Promise.resolve({ bizData: { records: vdata.addIfCodeList, hasNext: false } });
}
function confirmIfCode(selected) {
if (!selected) {
ak.infoBox.showToast('请选择进件渠道');
return false;
}
selectIfcodeRef.value.close();
ak.go.to('PAGES_APPLYMENT_H5_DETAIL', { isView: 0, ifCode: selected.ifCode });
}
// 页面跳转 选择 应用渠道
function toSelectIfCodePage() {
selectIncomingRef.value.open();
// ak.go.to('PAGES_APPLYMENT_SELECETDPAY')
}
function confirmIncoming(selected) {
console.log(selected, 'selectedselected');
if (!selected) {
ak.infoBox.showToast('请选择场景类型');
return false;
}
selectIncomingRef.value.close();
ak.go.to('PAGES_APPLYMENT_SELECETDPAY', { range: selected.range });
}
function reqTableIncomingDataByIfcodeFunc() {
const incomingList = [
{ range: 0, name: '线下场景' },
{ range: 1, name: '线上场景' }
];
console.log(incomingList, 'incomingList');
return Promise.resolve({ bizData: { records: incomingList, hasNext: false } });
}
</script>
<style lang="scss" scoped>
.page-wrapper {
min-height: calc(100vh - 80rpx);
// 搜索栏样式
.search-title {
display: flex;
align-items: center;
padding: 0 30rpx;
height: 110rpx;
.search-input {
flex: 1;
display: flex;
align-items: center;
height: 70rpx;
background-color: #fff;
border-radius: 12rpx;
position: relative;
padding-right: 70upx;
.search-img {
padding: 22rpx;
width: 26rpx;
height: 26rpx;
}
.close {
$closeSize: 70upx;
width: $closeSize;
height: $closeSize;
position: absolute;
top: 50;
right: 0;
display: flex;
align-items: center;
justify-content: center;
.del-img {
$size: 34upx;
width: $size;
height: $size;
}
}
}
.search-state {
$height: 40upx;
width: 200upx;
height: $height;
margin-left: 40rpx;
font-size: 30rpx;
color: #222425;
position: relative;
overflow: hidden;
transition: all 0.1s ease-in-out;
&.active {
width: 80upx;
}
.arrow {
margin-left: 10rpx;
width: 40rpx;
height: 40rpx;
transform: rotate(180deg);
}
.btn-wrap {
width: 100%;
position: absolute;
top: 0;
left: 0;
transition: all 0.1s ease-in-out;
.s-wrap {
height: $height;
}
}
}
}
}
.pay-wrapper {
display: flex;
align-items: center;
height: 170rpx;
.dot {
position: relative;
width: 36rpx;
height: 36rpx;
border-radius: 50%;
background-color: #d7d8d9;
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 50%;
height: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
background-color: #fff;
}
}
.dot-active {
background-color: #2980fd;
}
.pay-info {
display: flex;
.pay-logo {
margin: 0 20rpx 0 0rpx;
width: 90rpx;
height: 90rpx;
border-radius: $v-b-r20;
background-color: #07112d;
image {
width: 50rpx;
height: 50rpx;
}
}
.pay-title {
font-size: 30rpx;
font-weight: 400;
}
}
}
</style>

View File

@@ -1,92 +0,0 @@
<template>
<view class="page">
<!-- 注意 App 网页向应用 postMessage 为实时消息 -->
<web-view v-if="vdata.url" :src="vdata.url" @message="onMessageFunc"></web-view>
</view>
</template>
<script setup>
import { ref, reactive } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import appConfig from '@/config/appConfig.js';
import ak from '@/commons/utils/ak.js';
import storageManage from '@/commons/utils/storageManage.js';
import env from '@/env/env.development.js';
const vdata = reactive({
url: null,
isAdd: false // 是否新增, 新增将返回两个页面, 修改返回一个。
});
onLoad((option) => {
// console.log(option);
let jeepayToken = storageManage.token();
let mchNo = storageManage.userInfo().mchNo;
let uploadImgSize = storageManage.uploadImgSize() || '';
let isView = option.isView == 1 ? true : false; // 是否预览模式
let isvNo = option.isvNo || ''; // 渠道号
let range = option.range || 0; // 渠道号
let autoConfigMchAppId = option.autoConfigMchAppId || ''; // 应用号
let baseUrl = `${env.JEEPAY_BASE_URL_H5}`;
let url = '';
// 包含 记录ID
if (option.applyId) {
url = `${baseUrl}/h5MchApplyment?isView=${isView ? 1 : 0}&jeepayToken=${jeepayToken}&applyId=${
option.applyId
}&uploadImgSize=${uploadImgSize}&autoConfigMchAppId=${autoConfigMchAppId}&isvNo=${isvNo}&range=${range}`;
} else {
vdata.isAdd = true;
// 副本。
let copyInfoSourceApplyIdParam = option.copyInfoSourceApplyId || '';
url = `${baseUrl}/h5MchApplyment?isView=0&jeepayToken=${jeepayToken}&mchNo=${mchNo}&ifCode=${option.ifCode}&copyInfoSourceApplyId=${copyInfoSourceApplyIdParam}&isvNo=${isvNo}&range=${range}&autoConfigMchAppId=${autoConfigMchAppId}`;
// url = `${baseUrl}/h5MchApplyment?isView=0&jeepayToken=${jeepayToken}&mchNo=${mchNo}&ifCode=${option.ifCode}&copyInfoSourceApplyId=${copyInfoSourceApplyIdParam}&uploadImgSize=${uploadImgSize}&autoConfigMchAppId=${option.appId || ''}&isvNo=${isvNo}&range=${range}`
}
console.log(url, 'urlurlurl');
vdata.url = url;
});
// App 网页向应用 postMessage 为实时消息
// 接收到 web-view事件 ,
// 注意:放置数据, 必须在data字段下 比如: uni.postMessage({data: {ctrl: 'TOTOTOTOTOT'}})
function onMessageFunc(msg) {
// 接收到响应的数据 [数组格式, 比如接收到 web-view的返回等特定事件 将数据入栈全部返回 ]
let postDataArray = msg.detail.data;
// 无数据
if (!postDataArray || !Array.isArray(postDataArray)) {
return false;
}
for (var i = 0; i < postDataArray.length; i++) {
if (postDataArray[i].ctrl == 'toApplymentListAndRef') {
// 跳转到进件列表 && 刷新
// APP 可以实时接收到消息, 微信小程序需要在返回事件 (会关闭当前页面)时再接收到消息。
// #ifdef APP-PLUS
ak.go.back(1, ak.emit.ENAME_REF_APPLYMENT_LIST); //返回上一页
// #endif
// #ifdef MP-WEIXIN
ak.emit.pageEmit(ak.emit.ENAME_REF_APPLYMENT_LIST); // 刷新页面。
// #endif
break;
}
}
}
</script>
<style lang="scss" scoped>
.page {
padding: 30rpx;
box-sizing: border-box;
padding-bottom: 150rpx;
background-color: #f5f6fd;
min-height: calc(100vh - 0px);
}
</style>

View File

@@ -1,50 +0,0 @@
<template>
<view class="page">
<!-- 注意 App 网页向应用 postMessage 为实时消息 -->
<web-view v-if="vdata.url" :src="vdata.url" @message="onMessageFunc"></web-view>
</view>
</template>
<script setup>
import { ref, reactive } from "vue"
import { onLoad } from "@dcloudio/uni-app"
import appConfig from "@/config/appConfig.js"
import storageManage from '@/commons/utils/storageManage.js'
const vdata = reactive({
url: null,
})
onLoad((option) => {
let jeepayToken = storageManage.token()
let isView = false // 是否预览模式
let uploadImgSize = storageManage.uploadImgSize() || ''
let baseUrl = `${appConfig.env.JEEPAY_BASE_URL_H5}`
vdata.url = `${baseUrl}/h5MchApplymentOption?configPage=${option.configPage}&jeepayToken=${jeepayToken}&applyId=${option.applyId}&uploadImgSize=${uploadImgSize}`
})
// App 网页向应用 postMessage 为实时消息
// 接收到 web-view事件 ,
// 注意:放置数据, 必须在data字段下 比如: uni.postMessage({data: {ctrl: 'TOTOTOTOTOT'}})
function onMessageFunc(msg) {
// 接收到响应的数据 [数组格式, 比如接收到 web-view的返回等特定事件 将数据入栈全部返回 ]
let postDataArray = msg.detail.data
// 无数据
if (!postDataArray || !Array.isArray(postDataArray)) {
return false
}
}
</script>
<style lang="scss" scoped>
.page {
padding: 30rpx;
box-sizing: border-box;
padding-bottom: 150rpx;
background-color: #f5f6fd;
min-height: calc(100vh - 0px);
}
</style>

View File

@@ -1,338 +0,0 @@
<template>
<view class="page-wrapper">
<!-- 搜索栏头部 -->
<view class="search-title">
<view class="search-input">
<!-- <view class="search-input" @tap="go.toSearchPage('mchApplyment')"> -->
<image src="/static/iconImg/icon-search.svg" mode="scaleToFill" class="search-img" />
<input placeholder="搜索商户号/名称" v-model="searchValue" placeholder-class="input-placeholder" @confirm="searchHandle" />
<view class="close" v-if="searchValue" @click="clearHandle">
<image src="/static/iconImg/icon-x.svg" mode="scaleToFill" class="del-img" />
</view>
</view>
<view class="search-state" :class="{ active: searchValue }">
<div class="btn-wrap">
<view class="s-wrap flex-center" @tap="statePopup.open(vdata.searchData.state)" v-if="!searchValue">
{{ vdata.selected.label || '全部状态' }}
<image class="arrow" src="/static/iconImg/icon-arrow-black.svg" mode="scaleToFill" />
</view>
<view class="s-wrap flex-center" @click="searchHandle" v-else>搜索</view>
</div>
</view>
</view>
<JeepayTableList ref="jeepayTableListRef" :reqTableDataFunc="reqTableDataFunc" :searchData="vdata.searchData">
<template #tableBody="{ record }">
<MchApplymentRender :record="record" @refresh="jeepayTableListRef.refTable(true)" />
</template>
</JeepayTableList>
<!-- 底部固定按钮 -->
<view class="list-footer">
<view class="button-wrapper">
<Button @tap="toSelectIfCodePage">发起进件</Button>
</view>
</view>
<JSinglePopup :list="stateList" title="按状态筛选" ref="statePopup" @confirm="confirmState" />
<!-- 选择支付 接口 -->
<JeepayPopupListSelect
ref="selectIfcodeRef"
title="请选择渠道"
:reqTableDataFunc="reqTableDataByIfcodeFunc"
:fields="{ key: 'ifCode', left: 'ifName', right: 'ifCode' }"
@confirm="confirmIfCode"
>
<!-- 小程序 插槽不生效 待排查 TODO -->
<!-- 详见 https://ask.dcloud.net.cn/question/158765 -->
<!-- JeepayPopupListSelect.js 修改 "content-" + i0, 改为 content 即可 -->
<!-- #ifdef APP-PLUS || H5 -->
<template #content="{ record }">
<view class="pay-wrapper">
<view class="pay-info">
<view class="pay-logo flex-center" :style="{ backgroundColor: record.bgColor }">
<image :src="record.icon" mode="scaleToFill" />
</view>
<view>
<view class="pay-title">{{ record.ifName }}</view>
</view>
</view>
</view>
</template>
<!-- #endif -->
</JeepayPopupListSelect>
<!-- :fields="{ key: 'range', left: 'name', right: 'range' }" -->
<!-- 选择支付 接口 -->
<!-- <JeepayIncomingPopupListSelect
ref="selectIncomingRef"
title='请选择场景类型'
:reqTableDataFunc="reqTableIncomingDataByIfcodeFunc"
:fields="{ key: 'ifCode', left: 'ifName', right: 'ifCode' }"
@confirm="confirmIfCode"
>
</JeepayIncomingPopupListSelect> -->
<!-- 选择支付 接口 -->
<JeepayPopupListSelect
ref="selectIncomingRef"
title="请选择场景类型"
:reqTableDataFunc="reqTableIncomingDataByIfcodeFunc"
:fields="{ key: 'range', left: 'name' }"
@confirm="confirmIncoming"
></JeepayPopupListSelect>
</view>
</template>
<script setup>
import { reactive, ref, computed, provide } from 'vue';
import { onReachBottom, onUnload } from '@dcloudio/uni-app';
import go from '@/commons/utils/go.js';
import ak from '@/commons/utils/ak.js';
import { reqLoad, API_URL_MCH_APPLYMENT_LIST, $getAllAllowApplymentIfCodeList } from '@/http/apiManager.js';
import MchApplymentRender from '@/pages/list/render/MchApplymentRender.vue';
onReachBottom(() => {});
const statePopup = ref(null);
const jeepayTableListRef = ref();
const selectIfcodeRef = ref();
const selectIncomingRef = ref();
// // 监听 更新事件
onUnload(() => uni.$off(ak.emit.ENAME_REF_APPLYMENT_LIST));
uni.$on(ak.emit.ENAME_REF_APPLYMENT_LIST, function (data) {
jeepayTableListRef.value.refTable(true);
});
// 清空搜索
function clearHandle() {
searchValue.value = '';
vdata.searchData.mchApplyName = searchValue.value;
jeepayTableListRef.value.refTable(true);
}
// 搜索
function searchHandle() {
// reqTableDataFunc({ mchApplyName: searchValue });
vdata.searchData.mchApplyName = searchValue.value;
jeepayTableListRef.value.refTable(true);
}
const vdata = reactive({
incomingStatus: true,
searchData: {
mchApplyName: ''
},
selected: {}, // 当前选择对象
addIfCodeList: [] // 可以选择的接口集合
});
const stateList = reactive([
{ label: '全部', value: '' },
{ label: '草稿', value: '0' },
{ label: '审核中', value: '1' },
{ label: '进件成功', value: '2' },
{ label: '驳回待修改', value: '3' },
{ label: '待验证', value: '4' },
{ label: '待签约', value: '5' },
{ label: '等待预审', value: '7' },
{ label: '预审拒绝', value: '8' },
{ label: '已风控', value: '20' },
{ label: '已冻结', value: '21' },
{ label: '进件请求中', value: '100' }
]);
const searchValue = ref('');
// 请求
function reqTableDataFunc(params) {
return reqLoad.list(API_URL_MCH_APPLYMENT_LIST, params);
}
//按状态筛选
function confirmState(r) {
vdata.selected = r || {};
vdata.searchData.state = r.value;
jeepayTableListRef.value.refTable(true);
}
// 打开选择渠道页面
function toAddPage() {
$getAllAllowApplymentIfCodeList().then(({ bizData }) => {
vdata.addIfCodeList = bizData.filter((v) => {
return v.isOpenApplyment == 1;
});
selectIfcodeRef.value.open();
});
}
// 请求可以选择的支付渠道
function reqTableDataByIfcodeFunc() {
// 模拟请求数据
console.log(vdata.addIfCodeList, 'incomingList');
return Promise.resolve({ bizData: { records: vdata.addIfCodeList, hasNext: false } });
}
function confirmIfCode(selected) {
if (!selected) {
ak.infoBox.showToast('请选择进件渠道');
return false;
}
selectIfcodeRef.value.close();
ak.go.to('PAGES_APPLYMENT_H5_DETAIL', { isView: 0, ifCode: selected.ifCode });
}
// 页面跳转 选择 应用渠道
function toSelectIfCodePage() {
selectIncomingRef.value.open();
// ak.go.to('PAGES_APPLYMENT_SELECETDPAY')
}
function confirmIncoming(selected) {
console.log(selected, 'selectedselected');
if (!selected) {
ak.infoBox.showToast('请选择场景类型');
return false;
}
selectIncomingRef.value.close();
ak.go.to('PAGES_APPLYMENT_SELECETDPAY', { range: selected.range });
}
function reqTableIncomingDataByIfcodeFunc() {
const incomingList = [
{ range: 0, name: '线下场所', intro: '接入线下支付服务获得微信、支付宝、银联二维码、POS刷卡等基础支付能力。以及多方分账、手动现取、分时结算、资金快速到账等增值服务。' },
{
range: 1,
name: '线上平台',
intro: '接入线上支付能力获取微信、支付宝、银联二维码等在线支付能力。以及快捷支付、APP支付、H5支付、订单分账、代收代付、远程收款单等增值服务。'
}
];
console.log(incomingList, 'incomingList');
return Promise.resolve({ bizData: { records: incomingList, hasNext: false } });
}
</script>
<style lang="scss" scoped>
.page-wrapper {
min-height: calc(100vh - 80rpx);
// 搜索栏样式
.search-title {
display: flex;
align-items: center;
padding: 0 30rpx;
height: 110rpx;
.search-input {
flex: 1;
display: flex;
align-items: center;
height: 70rpx;
background-color: #fff;
border-radius: 12rpx;
position: relative;
padding-right: 70upx;
.search-img {
padding: 22rpx;
width: 26rpx;
height: 26rpx;
}
.close {
$closeSize: 70upx;
width: $closeSize;
height: $closeSize;
position: absolute;
top: 50;
right: 0;
display: flex;
align-items: center;
justify-content: center;
.del-img {
$size: 34upx;
width: $size;
height: $size;
}
}
}
.search-state {
$height: 40upx;
width: 200upx;
height: $height;
margin-left: 40rpx;
font-size: 30rpx;
color: #222425;
position: relative;
overflow: hidden;
transition: all 0.1s ease-in-out;
&.active {
width: 80upx;
}
.arrow {
margin-left: 10rpx;
width: 40rpx;
height: 40rpx;
transform: rotate(180deg);
}
.btn-wrap {
width: 100%;
position: absolute;
top: 0;
left: 0;
transition: all 0.1s ease-in-out;
.s-wrap {
height: $height;
}
}
}
}
}
.pay-wrapper {
display: flex;
align-items: center;
height: 170rpx;
.dot {
position: relative;
width: 36rpx;
height: 36rpx;
border-radius: 50%;
background-color: #d7d8d9;
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 50%;
height: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
background-color: #fff;
}
}
.dot-active {
background-color: #2980fd;
}
.pay-info {
display: flex;
.pay-logo {
margin: 0 20rpx 0 0rpx;
width: 90rpx;
height: 90rpx;
border-radius: $v-b-r20;
background-color: #07112d;
image {
width: 50rpx;
height: 50rpx;
}
}
.pay-title {
font-size: 30rpx;
font-weight: 400;
}
}
}
</style>

View File

@@ -1,309 +0,0 @@
<template>
<view class="page-wrapper">
<view class="title-wrapper flex-column" v-if="vdata.isIsvShow">
<view class="title">选择线上应用</view>
<view class="tips" @click="ak.go.to('PAGES_WEBVIEW', { url: 'https://shouyinbei.yuque.com/rv7pt7/xczlxt/dgxuxxgl17vsvwvl?singleDoc#' })">
(线上场景需要通过应用获取各种能力并进行开发对接如APP支付分账代付等当前进件商户需要与应用进行关联
<text class="t">了解应用</text>
)
</view>
<!-- <JSwitch :bol="vdata.isIsvShow" :confirmTips="false" @confirm="changeShow" /> -->
</view>
<!-- <view class="selected-wrapper selected-appId" :class="{ 'hide-appId': !vdata.isShow }"> -->
<view class="selected-wrapper selected-appId" v-if="vdata.isIsvShow">
<JeepayBizsPopupView :hasTitle="false" bizType="mchApp" v-model:value="vdata.appId" :showName="vdata.bindAppName" :isIcon="false" :addUse="true" />
<image src="/static/iconImg/icon-arrow-right.svg" class="arrow" />
</view>
<view class="title-wrapper">
<view class="title">选择支付通道</view>
</view>
<view class="selected-wrapper" @tap="toAddPage">
<text v-if="!vdata.ifCode">请选择支付通道</text>
<view class="ifcode-info" v-else>
<view class="ifcode-title">{{ vdata.ifName }}</view>
<view class="ifcode-code">{{ vdata.ifCode }}</view>
</view>
<image src="/static/iconImg/icon-arrow-right.svg" class="arrow" />
</view>
<view class="title-wrapper" v-if="vdata.ifCode">
<view class="title">选择支付渠道号</view>
</view>
<view class="selected-wrapper selected-appId" v-if="vdata.ifCode">
<JeepayBizsPopupView
:hasTitle="false"
bizType="isvApp"
v-model:value="vdata.isvNo"
:range="vdata.range"
:ifCode="vdata.ifCode"
:showName="vdata.isvName"
:isIcon="false"
/>
<image src="/static/iconImg/icon-arrow-right.svg" class="arrow" />
</view>
<view class="next-but">
<Button @tap="queryMchAppPayPassage">下一步</Button>
</view>
</view>
<!-- 选择支付 接口 -->
<JeepayPopupListSelect
ref="selectIfcodeRef"
title="请选择通道"
:isCheckbox="false"
:reqTableDataFunc="reqTableDataByIfcodeFunc"
:fields="{ key: 'ifCode', left: 'ifName', right: 'ifCode' }"
@confirm="confirmIfCode"
>
<!-- 小程序 插槽不生效 待排查 TODO -->
<!-- 详见 https://ask.dcloud.net.cn/question/158765 -->
<!-- JeepayPopupListSelect.js 修改 "content-" + i0, 改为 content 即可 -->
<!-- #ifdef APP-PLUS || H5 -->
<template #content="{ record }">
<view class="pay-wrapper">
<view class="pay-info">
<view class="pay-logo flex-center" :style="{ backgroundColor: record.bgColor }">
<image :src="record.icon" mode="scaleToFill" />
</view>
<view>
<view class="pay-title">{{ record.ifName }}</view>
</view>
</view>
</view>
</template>
<!-- #endif -->
</JeepayPopupListSelect>
</template>
<script setup>
import { reactive, ref } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import ak from '@/commons/utils/ak.js';
import { reqLoad, $getMchPayPassage, $getAllAllowApplymentIfCodeList, API_URL_MCH_APP_LIST, $getAllIsvInfoList } from '@/http/apiManager.js';
onLoad((options) => {
console.log(options, 'options');
if (options.applyId) vdata.applyId = options.applyId;
if (options.range) vdata.range = options.range;
if (vdata.range != 1) {
vdata.isShow = false;
vdata.isIsvShow = false;
}
});
const vdata = reactive({
range: 0,
isShow: true,
isIsvShow: true,
appId: ''
});
const statePopup = ref(null);
const jeepayTableListRef = ref();
const selectIfcodeRef = ref();
const selectIsvRef = ref();
// 打开选择通道页面
function toAddPage() {
$getAllAllowApplymentIfCodeList().then(({ bizData }) => {
vdata.addIfCodeList = bizData.filter((v) => {
return v.isOpenApplyment == 1;
});
selectIfcodeRef.value.open();
});
}
// 查询默认 应用
const findDefaultMchApp = () => {
reqLoad.list(API_URL_MCH_APP_LIST, { defaultFlag: 1 }).then(({ bizData }) => {
vdata.bindAppName = bizData.records[0].appName;
vdata.appId = bizData.records[0].appId;
});
};
findDefaultMchApp();
// 请求可以选择的支付通道
function reqTableDataByIfcodeFunc() {
// 模拟请求数据
return Promise.resolve({ bizData: { records: vdata.addIfCodeList, hasNext: false } });
}
// 查询商户支付应用参数是否配置
function queryMchAppPayPassage() {
if (vdata.appId == undefined && vdata.range == 1) {
ak.infoBox.showToast('请选择进件应用');
return false;
}
if (vdata.ifCode == undefined) {
ak.infoBox.showToast('请选择进件通道');
return false;
}
if (vdata.isvNo == undefined) {
ak.infoBox.showToast('请选择所属渠道');
return false;
}
$getMchPayPassage(vdata.appId, vdata.ifCode).then(({ bizData }) => {
if (bizData && bizData.existMchParams && vdata.isShow) {
uni.showModal({
title: '注意',
content: `当前所选应用已在通道【${vdata.ifName}】配置参数、费率,该笔进件成功后将自动覆盖原有配置,或将导致原有支付功能失效,请谨慎提交。`,
success: (res) => {
if (res.confirm) {
ak.go.to('PAGES_APPLYMENT_H5_DETAIL', {
range: vdata.range,
isvNo: vdata.isvNo,
isView: 0,
ifCode: vdata.ifCode,
appId: vdata.isShow ? vdata.appId : '',
copyInfoSourceApplyId: vdata.applyId ? vdata.applyId : '',
autoConfigMchAppId: vdata.appId
});
}
}
});
} else {
ak.go.to('PAGES_APPLYMENT_H5_DETAIL', {
range: vdata.range,
isvNo: vdata.isvNo,
isView: 0,
ifCode: vdata.ifCode,
appId: vdata.isShow ? vdata.appId : '',
copyInfoSourceApplyId: vdata.applyId ? vdata.applyId : '',
autoConfigMchAppId: vdata.appId
});
}
});
}
const changeShow = (e) => {
console.log(e);
vdata.isShow = e;
};
const changeIsvShow = (e) => {
console.log(e);
vdata.isIsvShow = e;
};
// 选择支付通道
function confirmIfCode(selected) {
Object.assign(vdata, selected);
selectIfcodeRef.value.close();
}
// 打开选择渠道页面
function toIsvAddPage() {
if (vdata.ifCode == undefined) {
ak.infoBox.showToast('请选择进件通道');
return false;
}
console.log(vdata.ifCode, 'vdata.ifCode');
$getAllIsvInfoList(vdata.ifCode).then(({ bizData }) => {
vdata.addIsvList = bizData.filter((v) => {
return v.isOpenApplyment == 1;
});
selectIsvRef.value.open();
});
}
// 请求可以选择的支付渠道
function reqTableDataByIsvFunc() {
// 模拟请求数据
return Promise.resolve({ bizData: { records: vdata.addIsvList, hasNext: false } });
}
// 选择支付渠道
function confirmIsv(selected) {
Object.assign(vdata, selected);
selectIfcodeRef.value.close();
}
</script>
<style lang="scss" scoped>
.page-wrapper {
padding-top: 60rpx;
min-height: 100vh;
.title-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
margin: 0 auto 20rpx;
padding: 0 30rpx;
box-sizing: border-box;
width: 670rpx;
&.flex-column {
padding: 0;
align-items: flex-start;
flex-direction: column;
.title {
padding: 0 30upx;
}
}
.title {
font-size: 32rpx;
}
.tips {
$bg: #ffeed8;
color: #c57000;
font-size: 20upx;
margin-top: 20upx;
background-color: #ffeed8;
padding: 12upx 16upx;
border-radius: 10upx;
position: relative;
&::after {
$size: 20upx;
content: '';
width: $size;
height: $size;
border-radius: 8upx;
background-color: $bg;
position: absolute;
top: $size * 0.5 * -1;
left: 60upx;
transform: rotate(-45deg);
}
.t {
color: $uni-primary;
font-weight: bold;
}
}
}
.selected-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
margin: 0 auto 120rpx;
padding: 0 0 0 30rpx;
box-sizing: border-box;
width: 670rpx;
min-height: 120rpx;
border-radius: 20rpx;
background-color: #fff;
.arrow {
width: 100rpx;
height: 100rpx;
}
.ifcode-info {
padding-top: 20rpx;
.ifcode-code {
padding: 15rpx 0 20rpx;
font-size: 30rpx;
color: #a1a1a1;
}
}
}
.selected-appId {
padding-bottom: 25rpx;
}
.next-but {
padding-top: 80rpx;
width: 670rpx;
margin: 0 auto;
}
}
.hide-appId {
margin-bottom: 110rpx;
padding: 0 !important;
min-height: 0 !important;
height: 0 !important;
overflow: hidden;
}
</style>

View File

@@ -49,7 +49,6 @@
<view>
<!-- <text class="money-title">展开全部</text> -->
</view>
<!-- <button v-if="ak.ent.has('ENT_C_QUICKCASHIER')" class="quick-money flex-center" @tap.stop="go.to('PAGES_QUICK_PAY')">快捷收银</button> -->
</view>
</template>
@@ -65,7 +64,6 @@
} from '@/http/apiManager.js';
import cal from '@/commons/utils/cal.js';
import go from '@/commons/utils/go.js';
import ak from '@/commons/utils/ak.js';
import ent from '@/commons/utils/ent.js';
import unionScan from '@/commons/utils/unionScan.js';
import storageManage from '@/commons/utils/storageManage.js';

View File

@@ -83,7 +83,7 @@
]
const currentInstance = getCurrentInstance()
onShow((options) => {
let iToken = uni.getStorageSync('iToken')
let iToken = uni.getStorageSync('iToken').tokenValue
if (iToken) {
getlist()
} else {

View File

@@ -1,37 +1,49 @@
<!-- 首页 -->
<template>
<JeepayBackground :bgColorStyle="{}">
<!-- 导航条 -->
<up-navbar title="首页" bg-color="#318AFE" titleStyle="color:#fff;font-size:16px;" @leftClick="toSetting">
<template #left>
<up-icon name="/static/indexImg/icon-menu.svg" color="#fff" :size="16"></up-icon>
</template>
</up-navbar>
<!-- <JeepayCustomNavbar title="首页" textColor="#fff" bgDefaultColor="#318AFE" /> -->
<view class="income">
<view class="u-flex u-row-center u-relative">
<view class="u-flex u-col-center">
<view class="u-m-r-12">总收入</view>
<up-icon name="/static/indexImg/icon-help.svg" color="#fff" :size="12"
@click="toggleTips"></up-icon>
</view>
<view class="tips u-absolute color-666 u-font-20 u-text-left " :class="{'showTips':showTips}">
<view class="sanjiao u-flex"><up-icon name="play-left-fill" size="12" color="#fff"></up-icon></view>
总收入为除会员余额
支付外所有收入
</view>
<view class="page-wrapper" style="overflow:visible;height:auto">
<!-- 背景图片view -->
<view class="bg-img-view" >
<!-- 背景颜色view -->
<view class="bg-color-view" style="position: absolute;top: 0;left: 0;right: 0;height: 550rpx;border-radius:0 0 32rpx 32rpx;background-color: #318AFE!important;">
<view class="bgbottomStyle">
</view>
</view>
<view class="u-flex u-row-center">
<view class="">{{((totalRevenuedata||0)*1).toFixed(2)}}</view>
</view>
<view>{{shopName||''}}</view>
</view>
<!-- 统计 or 快捷扫码 -->
<!-- <Stats ref="statsRef" /> -->
<statistics @totalRevenue="totalRevenue"></statistics>
<!-- 导航栅格 -->
<JeepayNavigation :navList="navList" type="grid" />
</JeepayBackground>
<!-- 解决定位层级问题 -->
<view class="bg-main">
<!-- 导航条 -->
<up-navbar title="首页" bg-color="#318AFE" titleStyle="color:#fff;font-size:16px;" @leftClick="toSetting">
<template #left>
<up-icon name="/static/indexImg/icon-menu.svg" color="#fff" :size="16"></up-icon>
</template>
</up-navbar>
<view class="income">
<view class="u-flex u-row-center u-relative">
<view class="u-flex u-col-center">
<view class="u-m-r-12">总收入</view>
<up-icon name="/static/indexImg/icon-help.svg" color="#fff" :size="12"
@click="toggleTips"></up-icon>
</view>
<view class="tips u-absolute color-666 u-font-20 u-text-left " :class="{'showTips':showTips}">
<view class="sanjiao u-flex"><up-icon name="play-left-fill" size="12" color="#fff"></up-icon></view>
总收入为除会员余额
支付外所有收入
</view>
</view>
<view class="u-flex u-row-center">
<view class="">{{((totalRevenuedata||0)*1).toFixed(2)}}</view>
</view>
<view>{{shopName||''}}</view>
</view>
<!-- 统计 or 快捷扫码 -->
<!-- <Stats ref="statsRef" /> -->
<statistics @totalRevenue="totalRevenue"></statistics>
<!-- 导航栅格 -->
<JeepayNavigation :navList="navList" type="grid" />
</view>
</view>
</template>
<script setup>
@@ -83,11 +95,6 @@
}
// 导航列表
const navList = [
// {
// title: '收银',
// icon: '/static/indexImg/icon-cashier.svg',
// pageUrl: 'PAGES_QUICK_PAY',
// },
{
title: '销售汇总',
icon: '/static/indexImg/PAGE_SALES_SUMMARY.svg',
@@ -154,11 +161,6 @@
icon: '/static/indexImg/icon-work.svg',
pageUrl: 'PAGES_WORK_INDEX',
},
// {
// title: '极速开票',
// icon: '/static/indexImg/red-envelope.svg',
// pageUrl: 'PAGES_INVOICE'
// },
{
title: '排队',
icon: '/static/indexImg/icon-line-up.svg',
@@ -169,21 +171,6 @@
icon: '/static/indexImg/icon-bwc.svg',
pageUrl: 'PAGES_BWC'
},
// {
// title: '成员管理',
// icon: '/static/indexImg/icon-staff.svg',
// pageUrl: 'PAGES_USER'
// },
// {
// title: '订阅通知',
// icon: '/static/indexImg/icon-notification.svg',
// pageUrl: 'PAGES_NOTIFICATION_INDEX',
// },
// {
// title: '设置中心',
// icon: '/static/indexImg/icon-cashier.svg',
// pageUrl: 'PAGES_SHOP_SETUP',
// },
{
title: '优惠券',
icon: '/static/coupon/icon_coupon.svg',
@@ -199,57 +186,75 @@
icon: '/static/indexImg/icon_credit.svg',
pageUrl: 'PAGES_CREDIT_BUYER_INDEX',
},
// // // {
// // // title: '进销存',
// // // icon: '/static/indexImg/icon-invoicing.svg',
// // // pageUrl: 'PAGES_INVOICING_INDEX',
// // // },
// // // {
// // // title: '预定座位',
// // // icon: '/static/indexImg/icon-yuyue-zuo.svg',
// // // pageUrl: 'PAGES_RESERVE_SEAT_INDEX',
// // // },
// // // {
// // // title: '预约管理',
// // // icon: '/static/indexImg/icon-yuyue.svg',
// // // pageUrl: 'PAGES_BOOKING_INDEX',
// // // },
// // // {
// // // title: '充值管理',
// // // icon: '/static/indexImg/icon-recharge.svg',
// // // pageUrl: 'PAGES_RECHARGE_INDEX',
// // // },
// // // {
// // // title: '存酒管理',
// // // icon: '/static/indexImg/icon-wine.svg',
// // // pageUrl: 'PAGES_STORING_WINE_INDEX',
// // // },
// // // {
// // // title: '进件管理',
// // // icon: '/static/indexImg/icon-passage.svg',
// // // pageUrl: 'PAGES_APPLYMENT',
// // // entId: 'ENT_MCH_APPLYMENT_LIST'
// // // },
// // // {
// // // title: '商户管理',
// // // icon: '/static/indexImg/business.svg',
// // // pageUrl: 'PAGES_APPLYMENT_BUSINESS',
// // // entId: 'ENT_MCH_APPLYMENT_LIST'
// // // },
// // // {
// // // title: '门店管理',
// // // icon: '/static/indexImg/icon-store.svg',
// // // pageUrl: 'PAGES_STORE',
// // // entId: 'ENT_MCH_STORE'
// // // },
// // {
// // title: '设备管理',
// // icon: '/static/indexImg/icon-calc.svg',
// // pageUrl: 'PAGES_DEVICE_MAIN',
// // entId: 'ENT_DEVICE'
// // },
{
title: '核销管理',
icon: '/static/indexImg/pagewriteoff.svg',
pageUrl: 'PAGES_WEITEOFF'
},
{
title: '退出登录',
icon: '/static/indexImg/icon-login-out.svg',
pageUrl: 'PAGES_LOGIN',
clickFunc: () => {
storageManage.cleanByLogout()
go.to('PAGES_LOGIN', {}, 'redirect')
}
}
// {
// title: '成员管理',
// icon: '/static/indexImg/icon-staff.svg',
// pageUrl: 'PAGES_USER'
// },
// {
// title: '订阅通知',
// icon: '/static/indexImg/icon-notification.svg',
// pageUrl: 'PAGES_NOTIFICATION_INDEX',
// },
// {
// title: '进销存',
// icon: '/static/indexImg/icon-invoicing.svg',
// pageUrl: 'PAGES_INVOICING_INDEX',
// },
// {
// title: '预定座位',
// icon: '/static/indexImg/icon-yuyue-zuo.svg',
// pageUrl: 'PAGES_RESERVE_SEAT_INDEX',
// },
// {
// title: '预约管理',
// icon: '/static/indexImg/icon-yuyue.svg',
// pageUrl: 'PAGES_BOOKING_INDEX',
// },
// {
// title: '充值管理',
// icon: '/static/indexImg/icon-recharge.svg',
// pageUrl: 'PAGES_RECHARGE_INDEX',
// },
// {
// title: '进件管理',
// icon: '/static/indexImg/icon-passage.svg',
// pageUrl: 'PAGES_APPLYMENT',
// entId: 'ENT_MCH_APPLYMENT_LIST'
// },
// {
// title: '商户管理',
// icon: '/static/indexImg/business.svg',
// pageUrl: 'PAGES_APPLYMENT_BUSINESS',
// entId: 'ENT_MCH_APPLYMENT_LIST'
// },
// {
// title: '门店管理',
// icon: '/static/indexImg/icon-store.svg',
// pageUrl: 'PAGES_STORE',
// entId: 'ENT_MCH_STORE'
// },
// {
// title: '设备管理',
// icon: '/static/indexImg/icon-calc.svg',
// pageUrl: 'PAGES_DEVICE_MAIN',
// entId: 'ENT_DEVICE'
// },
// {
// title: '数据中心',
// icon: '/static/indexImg/icon-pro.svg',
@@ -274,30 +279,7 @@
// pageUrl: 'PAGES_AD_LIST',
// entId: 'ENT_ADVERT_CONTROL'
// },
// {
// title: '营销红包',
// icon: '/static/indexImg/red-envelope.svg',
// pageUrl: 'PAGES_RED_INDEX',
// entId: 'ENT_MCH_MEMBER'
// },
{
title: '核销管理',
icon: '/static/indexImg/pagewriteoff.svg',
pageUrl: 'PAGES_WEITEOFF'
},
{
title: '退出登录',
icon: '/static/indexImg/icon-login-out.svg',
pageUrl: 'PAGES_LOGIN',
clickFunc: () => {
storageManage.cleanByLogout()
go.to('PAGES_LOGIN', {}, 'redirect')
}
}
];
// 如果不是超管 删除 刷脸广告菜单
@@ -314,16 +296,6 @@
shareImgUrl: '' //分享图片
});
// 公告的点击事件。
const listviewClickFunc = (isClickMore, record) => {
if (isClickMore) {
return go.to('PAGES_NOTICE_LIST');
}
return go.to('PAGES_NOTICE_DETAIL', {
id: record.articleId
});
};
// 刷新数据 async 异步函数, 每个查询需要返回promise对象并标识await
async function refData() {
@@ -370,6 +342,19 @@
</script>
<style lang="scss" scoped>
.bg-main{
position: relative;
z-index: 10;
}
.bgbottomStyle{
position: absolute;
bottom: -2rpx;
left: 0;
width: 750rpx;
height: 74rpx;
background: linear-gradient( 180deg, rgba(195,215,235,0) 0%, #F9F9F9 100%);
}
.income {
/* #ifdef H5 */
padding-top: calc(84rpx);

View File

@@ -1,191 +0,0 @@
<!-- 首页 -->
<template>
<view class="" @click="tologin">
<JeepayBackground :bgColorStyle="{}">
<!-- 导航条 -->
<JeepayCustomNavbar title="首页" textColor="#fff" bgDefaultColor="linear-gradient(270deg, rgba(72, 192, 255, 1) 0%, rgba(51, 157, 255, 1) 100%)" />
<!-- 统计 or 快捷扫码 -->
<view class="code-box">
<view class="today-box">
<view class="today">
<view class="today-title">今天</view>
<view class="jing-box">
<text>昨天</text>
<text>近7天</text>
<text>近30天</text>
</view>
</view>
<view class="saoma">扫码</view>
</view>
<view class="" style="display: flex; flex-direction: column; justify-content: space-around; align-items: center; height: 400rpx; color: #fff; font-size: 28rpx">
<view class="" style="display: flex; flex-direction: column; align-items: center">
<view class="">成交金额()</view>
<view class="">0.00</view>
</view>
<view class="" style="display: flex; justify-content: space-around; width: 100%; align-items: center">
<view class="" style="display: flex; flex-direction: column; align-items: center">
<view class="">成交笔数</view>
<view class="">0</view>
</view>
<view class="" style="display: flex; flex-direction: column; align-items: center">
<view class="">退款金额()</view>
<view class="" style="font-size: 60rpx">0.00</view>
</view>
<view class="" style="display: flex; flex-direction: column; align-items: center">
<view class="">退款笔数</view>
<view class="">0</view>
</view>
</view>
<view class="" style="width: 100%">
<button>快捷收银</button>
</view>
</view>
</view>
<!-- 导航栅格 -->
<view class="" style="margin-top: 85%; display: flex; flex-wrap: wrap; padding: 0 40rpx; justify-content: space-around">
<view class="" v-for="item in navList" style="width: 30%; margin: 10rpx 0; background: #fff; padding: 10rpx 0; border-radius: 30rpx">
<view class="" style="display: flex; flex-direction: column; justify-content: center; align-items: center">
<image :src="item.icon" mode="" style="width: 100rpx; height: 100rpx"></image>
{{ item.title }}
</view>
</view>
</view>
</JeepayBackground>
</view>
</template>
<script setup>
import storageManage from '@/commons/utils/storageManage.js';
// 导航列表
const navList = [
{
title: '商户进件',
icon: '/static/indexImg/icon-passage.svg',
pageUrl: 'PAGES_APPLYMENT',
entId: 'ENT_MCH_APPLYMENT_LIST'
},
{
title: '商户管理',
icon: '/static/indexImg/business.svg',
pageUrl: 'PAGES_APPLYMENT_BUSINESS',
entId: 'ENT_MCH_APPLYMENT_LIST'
},
{
title: '我的门店',
icon: '/static/indexImg/icon-store.svg',
pageUrl: 'PAGES_STORE',
entId: 'ENT_MCH_STORE'
},
{
title: '我的设备',
icon: '/static/indexImg/icon-calc.svg',
pageUrl: 'PAGES_DEVICE_MAIN',
entId: 'ENT_DEVICE'
},
{
title: '员工管理',
icon: '/static/indexImg/icon-staff.svg',
pageUrl: 'PAGES_USER',
entId: 'ENT_UR_USER_LIST'
},
{
title: '统计报表',
icon: '/static/indexImg/icon-pro.svg',
pageUrl: 'PAGES_STAT',
entId: 'ENT_ORDER_STATISTIC'
},
{
title: '商户应用',
icon: '/static/indexImg/icon-app.svg',
pageUrl: 'PAGES_APP',
entId: 'ENT_MCH_APP_LIST'
},
{
title: '会员中心',
icon: '/static/indexImg/icon-member.svg',
pageUrl: 'PAGES_MEMBER_CENTER',
entId: 'ENT_MCH_MEMBER'
},
{
title: '广告管理',
icon: '/static/indexImg/icon-ad.svg',
pageUrl: 'PAGES_AD_LIST',
entId: 'ENT_ADVERT_CONTROL'
},
{
title: '营销红包',
icon: '/static/indexImg/red-envelope.svg',
pageUrl: 'PAGES_RED_INDEX',
entId: 'ENT_MCH_MEMBER'
}
];
// 如果不是超管 删除 刷脸广告菜单
if (storageManage.userInfo().userType != 1) {
const index = navList.findIndex((v) => v.entId == 'ENT_ADVERT_CONTROL');
if (index != -1) {
navList.splice(index, 1);
}
}
const tologin = () => {
uni.redirectTo({
url: '/pages/login/index'
});
};
</script>
<style lang="scss" scoped>
.code-box {
background: #1c72fe;
position: fixed;
width: 90%;
right: 5%;
height: 500rpx;
border-radius: 20rpx;
padding: 20rpx;
box-sizing: border-box;
top: 15%;
.today-box {
display: flex;
color: #fff;
.today {
display: flex;
flex: 1;
margin-right: 10rpx;
background: #368bfd;
padding: 10rpx;
border-radius: 10rpx;
}
.today-title {
height: 70rpx;
background: #fff;
width: 100rpx;
display: flex;
justify-content: center;
align-items: center;
border-radius: 10rpx;
color: #1b6dfe;
}
.saoma {
width: 100rpx;
display: flex;
justify-content: center;
align-items: center;
border-radius: 10rpx;
color: #fff;
background: #368bfd;
}
.jing-box {
display: flex;
flex: 1;
justify-content: space-around;
align-items: center;
}
}
}
</style>

View File

@@ -1,93 +0,0 @@
<template>
<JeepayCustomNavbar backIcon="closeempty" title="登录取认" backCtrl="back" />
<view class="scan-content">
<view class="computer">
<image src="/static/iconImg/computer.svg" mode=""></image>
<text>您正在登录商户管理系统网站</text>
</view>
<view class="btn confirm" @tap="codeOk('confirmed')" hover-class="touch-button ">确认登录</view>
<view class="btn cancel" @tap="codeOk('canceled')" hover-class="touch-hover">取消登录</view>
</view>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { $scanCodeLogin } from '@/http/apiManager.js'
import { onLoad } from '@dcloudio/uni-app'
import infoBox from '@/commons/utils/infoBox.js'
import go from '@/commons/utils/go.js'
const vdata = reactive({
qrcodeNo : ''
})
onLoad((option) => {
vdata.qrcodeNo = option.qrcodeNo
// 已扫
$scanCodeLogin(vdata.qrcodeNo, "scaned")
})
const codeOk = (val) => {
$scanCodeLogin(vdata.qrcodeNo, val).then((res) => {
if(val == 'confirmed'){
return infoBox.showSuccessToast('登录成功')
}else{
return infoBox.showToast("已取消")
}
}).then(() => {
go.back()
})
}
</script>
<style scoped lang="scss">
.scan-content {
height: 100%;
width: 100%;
display: flex;
align-items: center;
flex-direction: column;
.computer {
margin-top: 260rpx;
margin-bottom: 150rpx;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
image {
width: 200rpx;
height: 200rpx;
}
text {
line-height: 46px;
font-size: 33rpx;
color: #000000;
}
}
.btn {
display: flex;
align-items: center;
justify-content: center;
width: 360rpx;
height: 110rpx;
border-radius: 20rpx;
background: #4dab68;
font-size: 33rpx;
}
.confirm {
color: #fff;
background: $jeepay-bg-primary;
}
.cancel {
margin-top: 35rpx;
color: #666;
background: transparent;
}
}
.canceled {
width: 50rpx;
height: 50rpx;
}
</style>

View File

@@ -1,22 +0,0 @@
<template>
<web-view class="view" :src="webUrl"></web-view>
</template>
<script setup>
import { ref } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
const webUrl = ref(`https://h5-invoice.sxczgkj.cn/?userId=${uni.getStorageSync('currentUserInfo').sysUserId}&type=cashier`);
onLoad((options) => {
// webUrl.value = options.url;
console.log(webUrl.value);
});
</script>
<style scoped lang="scss">
.view {
width: 100vw;
height: 100vh;
}
</style>

View File

@@ -1,14 +0,0 @@
pages/list/search.vue 通用搜索显示卡片
pages/list/render/ : 定义了列表数据渲染样式。
PayOrderRender.vue 支付订单
RefundOrderRender.vue 退款订单
...

View File

@@ -1,187 +0,0 @@
<!--
订单列表页面 数据渲染
业务 应用配置信息
@author terrfly
@site https://www.jeequan.com
@date 2022/12/02 16:57
-->
<template>
<JeepayTableListItem :title="props.record.wayName" :subtitle="props.record.wayCode" @tap="openConfig">
<template #titleRight>
<view v-if="props.record.isConfig" class="state-dot state-dot-enable">已配置</view>
<view v-else class="state-dot state-dot-disable">未配置</view>
</template>
</JeepayTableListItem>
<!-- 选择支付 接口 -->
<JeepayPopupListSelect
ref="selectIfcodeRef"
title='请选择支付渠道'
:reqTableDataFunc="reqTableDataByIfcodeFunc"
:fields="{ key: 'ifCode', left: 'ifName', right: 'ifCode' }"
@confirm="confirmFunc"
>
<!-- 小程序 插槽不生效 待排查 TODO -->
<!-- 详见 https://ask.dcloud.net.cn/question/158765 -->
<!-- JeepayPopupListSelect.js 修改 "content-" + i0, 改为 content 即可 -->
<!-- #ifdef APP-PLUS || H5 -->
<template #content="{record}">
<view class="pay-wrapper">
<view class="pay-info">
<view class="pay-logo flex-center" :style="{ backgroundColor: record.bgColor }">
<image :src="record.icon" mode="scaleToFill" />
</view>
<view>
<view class="pay-title">{{ record.ifName }}</view>
<view class="pay-rate">{{getRateStr(record.paywayFee)}}</view>
</view>
</view>
</view>
</template>
<!-- #endif -->
</JeepayPopupListSelect>
</template>
<script setup>
import { reactive, ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { reqLoad, API_URL_PAY_PASSAGE_LIST, $getAvailablePayInterface, $wayCodeConfigIfCode } from '@/http/apiManager.js'
import go from '@/commons/utils/go.js'
import emit from '@/commons/utils/emit.js'
import infoBox from '@/commons/utils/infoBox.js'
import cal from '@/commons/utils/cal.js'
const selectIfcodeRef = ref()
// 定义传入属性
const props = defineProps({
record: {type:Object, default: () => {}}, // 渲染对象
configAppId: { type: String }, // 配置的appId
})
const vdata = reactive({
configedIfCode: '', // 已配置的ifCode
apiRes: { }, //接口返回数据缓存
})
// 请求
function reqTableDataByIfcodeFunc (params) {
return Promise.resolve(vdata.apiRes)
}
// 打开面板 ( 先查询过滤下。 )
function openConfig(wayCode){
vdata.configedIfCode = '';
$getAvailablePayInterface(props.configAppId, props.record.wayCode).then(res => {
vdata.apiRes = res
if(!res.bizData.records.length) return infoBox.showToast('暂无可配置的渠道')
res.bizData.records.forEach(r => {
if(r.configState == 1){
vdata.configedIfCode = r.ifCode
}
})
if(vdata.configedIfCode){
selectIfcodeRef.value.open({ifCode: vdata.configedIfCode})
}else{
selectIfcodeRef.value.open()
}
})
}
function confirmFunc(v){
if(!v){
return infoBox.showToast('请选择接口')
}
$wayCodeConfigIfCode(props.configAppId, props.record.wayCode, v.ifCode).then(() => {
infoBox.showSuccessToast("配置完成")
emit.refPageAndSearchEmit(emit.ENAME_REF_PAY_PASSAGE_LIST)
selectIfcodeRef.value.close();
})
}
function getRateStr(paywayFee){
if(paywayFee.feeType == 'SINGLE'){
return '单笔费率:' + cal.cert2Dollar(paywayFee.feeRate * 10000) + "%"
}else{
return '阶梯费率'
}
}
</script>
<style lang="scss" scoped>
.pay-wrapper {
display: flex;
align-items: center;
height: 170rpx;
.dot {
position: relative;
width: 36rpx;
height: 36rpx;
border-radius: 50%;
background-color: #d7d8d9;
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 50%;
height: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
background-color: #fff;
}
}
.dot-active {
background-color: #2980fd;
}
.pay-info {
display: flex;
.pay-logo {
margin: 0 20rpx 0 0rpx;
width: 90rpx;
height: 90rpx;
border-radius: $v-b-r20;
background-color: #07112d;
image {
width: 50rpx;
height: 50rpx;
}
}
.pay-title {
font-size: 30rpx;
font-weight: 400;
}
.pay-rate {
margin-top: 16rpx;
font-size: 26rpx;
font-weight: 400;
color: $J-color-t99;
}
}
}
</style>

View File

@@ -1,99 +0,0 @@
<!--
组件功能 设备通用渲染页面
@author terrfly
@site https://www.jeequan.com
@date 2022/12/06 13:25
-->
<template>
<!-- 码牌 -->
<template v-if="props.type == 'qrc'">
<JeepayTableListItem :logo="codeImgListByQrc[record.qrcState]" :title="record.qrcAlias || '未命名'" :subtitle="record.qrcId" :state="record.qrcState" @tap="toDetailPage" />
</template>
<!-- 辅助终端 -->
<template v-if="props.type == 'storeTerminal'">
<JeepayTableListItem :logo="codeImgListByTerm[record.state]" :title="record.trmName" :subtitle="record.trmNo" :state="record.state" @tap="toDetailPage" />
</template>
<!-- 通用设备 -->
<template v-if="props.type == 'device'">
<JeepayTableListItem
:logo="vdata[`imgListByType${props.record.deviceType}`][props.record.state]"
:title="record.deviceName"
:subtitle="record.deviceNo"
:state="record.state"
@tap="toDetailPage"
/>
</template>
<template v-if="props.type == 'face'">
<JeepayTableListItem :logo="faceImgListByFace[record.state]" :subtitle="record.deviceNo" :state="record.qrcState" @tap="toDetailPage">
<template #title>
{{ record.deviceName }}
<JeepayTag :type="record.provider == 'wxpayQWPro' ? 'green-rgba' : 'blue'">{{ record.provider == 'wxpayQWPro' ? '青蛙刷脸Pro' : '蜻蜓F4' }}</JeepayTag>
</template>
</JeepayTableListItem>
</template>
</template>
<script setup>
import { reactive, ref } from 'vue'
import go from '@/commons/utils/go.js'
const codeImgListByQrc = ['/pageDevice/static/detailsLislImg/code-none.svg', '/pageDevice/static/devIconImg/icon-code.svg']
const codeImgListByTerm = ['/pageDevice/static/detailsLislImg/trm-none.svg', '/pageDevice/static/devIconImg/icon-term.svg']
const faceImgListByFace = ['/pageDevice/static/devIconImg/icon-face-0.svg', '/pageDevice/static/devIconImg/icon-face-1.svg']
// 定义传入属性
const props = defineProps({
type: { type: String, default: 'device' }, // 类型
record: { type: Object, default: () => {} }, // 渲染对象
})
const vdata = reactive({
imgListByType1: ['/pageDevice/static/detailsLislImg/horn-none.svg', '/pageDevice/static/devIconImg/icon-horn.svg'],
imgListByType2: ['/pageDevice/static/detailsLislImg/print-none.svg', '/pageDevice/static/devIconImg/icon-print.svg'],
imgListByType3: ['/pageDevice/static/detailsLislImg/scanPos-none.svg', '/pageDevice/static/devIconImg/icon-scanPos.svg'],
imgListByType4: ['/pageDevice/static/detailsLislImg/pos-none.svg', '/pageDevice/static/devIconImg/icon-pos.svg'],
imgListByType5: ['/pageDevice/static/detailsLislImg/horn-none.svg', '/pageDevice/static/devIconImg/icon-horn.svg'],
imgListByType7: ['/pageDevice/static/detailsLislImg/lite-none.svg', '/pageDevice/static/detailsLislImg/icon-lite.svg'],
})
function toDetailPage() {
if (props.type == 'qrc') {
return go.to('PAGES_APP_CODE_DETAILS', { codeId: props.record.qrcId })
}
if (props.type == 'storeTerminal') {
return go.to('PAGES_APP_TERMINAL_DETAILS', { trmId: props.record.trmId })
}
// 通用设备 1-喇叭 2-打印机 3-扫码POS 4-智能POS
if (props.record.deviceType) {
const deviceId = props.record.deviceId
switch (props.record.deviceType) {
case 1:
go.to('PAGES_APP_HORN_DETAILS', { deviceId })
break
case 2:
go.to('PAGES_APP_PRINT_DETAILS', { deviceId })
break
case 3:
go.to('PAGES_APP_SCANPOS_DETAILS', { deviceId })
break
case 4:
go.to('PAGES_APP_POS_DETAILS', { deviceId })
break
case 6:
go.to('PAGES_APP_FACE_DETAILS', { deviceId })
break
case 7:
go.to('PAGES_LITE_DETAILS', { deviceId })
break
}
}
}
</script>
<style lang="scss" scoped></style>

View File

@@ -1,26 +0,0 @@
<!--
订单列表页面 数据渲染
业务 示例模板
@author terrfly
@site https://www.jeequan.com
@date 2022/11/23 16:57
-->
<template>
<view>{{ props.record }}</view>
</template>
<script setup>
import { reactive, ref } from "vue"
// 定义传入属性
const props = defineProps({
record: {type:Object, default: () => {}}, // 渲染对象
})
</script>
<style lang="scss" scoped>
</style>

View File

@@ -1,33 +0,0 @@
<template>
<JeepayTableListItem :logo="imgUrl" :subtitle="advertId" logoStyle="border-radius:20rpx" @tap="toAdDetails">
<template #title>
{{ title }}
<JeepayTag type="green-rgba" v-if="releaseState">已发布</JeepayTag>
</template>
</JeepayTableListItem>
</template>
<script setup>
import {
unix
} from 'dayjs';
import go from '@/commons/utils/go.js'
const props = defineProps({
title: {
type: String
},
advertId: {
type: String
},
imgUrl: {
type: String
},
releaseState: {
type: [String, Number]
}
})
const toAdDetails = () => go.to('/pageDevice/adManager/view', { id: props.advertId })
</script>
<style lang="scss" scoped></style>

View File

@@ -1,36 +0,0 @@
<!--
订单列表页面 数据渲染
业务 示例模板
@author terrfly
@site https://www.jeequan.com
@date 2022/11/23 16:57
-->
<template>
<JeepayTableListItem :subtitle="props.record.appId" @tap="toDetailPage" :state="props.record.state">
<template #title>
{{ props.record.appName }}
<JeepayTag v-if="props.record.defaultFlag == 1" type="green-rgba">默认</JeepayTag>
</template>
</JeepayTableListItem>
</template>
<script setup>
import { reactive, ref } from 'vue'
import go from '@/commons/utils/go.js'
import ak from '@/commons/utils/ak.js'
// 定义传入属性
const props = defineProps({
record: { type: Object, default: () => {} }, // 渲染对象
})
function toDetailPage() {
if(ak.ent.has('ENT_MCH_APP_VIEW')){
go.to('PAGES_APP_DETAIL', { appId: props.record.appId })
}
}
</script>
<style lang="scss" scoped></style>

View File

@@ -1,413 +0,0 @@
<!--
订单列表页面 数据渲染
业务 进件
@author terrfly
@site https://www.jeequan.com
@date 2022/11/29 09:17
-->
<template>
<!-- 草稿 灰色 失败红色 审核中 黄色 -->
<!-- 列表卡片 -->
<view class="apply-card">
<view class="apply-title" @tap="toViewPage">
<view class="pay-img-wrapper flex-center" :style="{ backgroundColor: record.bgColor }">
<image :src="props.record.icon" mode="scaleToFill" />
</view>
<view class="apply-title-wrapper">
<view class="apply-title-info">
<text class="single-text-beyond">{{ props.record.mchShortName }}</text>
<view class="apply-state" @tap.stop="showErrorModal(props.record)">
<div class="err_icon">
<uni-icons type="info" v-if="record.state == 3" size="20"></uni-icons>
</div>
<text>{{ stateList[record.state]?.text }}</text>
<!-- <text v-if="record.state == 3" class="err_tips">{{ props.record.applyErrorInfo }}</text> -->
<view class="apply-dot" :style="{ backgroundColor: stateList[record.state]?.bgColor }"></view>
</view>
</view>
<view class="apply-time">{{ props.record.createdAt }}</view>
</view>
</view>
<view class="apply-info-title" @tap="toViewPage">
<view class="title">商户类型&emsp;</view>
<view class="info">{{ merchantTypeFilter(props.record.merchantType) }}</view>
</view>
<view class="apply-info-title" @tap="toViewPage">
<view class="title">支付通道&emsp;</view>
<view class="info">{{ props.record.ifName }}</view>
</view>
<view class="apply-info-title" @tap="toViewPage">
<view class="title">商户号&emsp;&emsp;</view>
<view class="info">{{ props.record.applyId }}</view>
</view>
<view class="apply-info-title" @tap="toViewPage">
<view class="title">所属渠道&emsp;</view>
<view class="info">{{ props.record.isvNo }}</view>
</view>
<view class="apply-info-title" @tap="toViewPage">
<view class="title">支付宝认证</view>
<view class="info">{{ props.record.zfbAuthenticationState ? '已认证' : '未认证' }}</view>
</view>
<view class="apply-info-title" @tap="toViewPage">
<view class="title">微信认证&emsp;</view>
<view class="info">{{ props.record.wxAuthenticationState ? '已认证' : '未认证' }}</view>
</view>
<view class="apply-button">
<view
v-if="
ent.has('ENT_MCH_APPLYMENT_SIGN') &&
(props.record.state == 1 || props.record.state == 2 || props.record.state == 4 || props.record.state == 5 || props.record.state == 6)
"
class="sign flex-center"
hover-class="touch-hover"
@tap="toSignPage"
>
签约开通
</view>
<template v-if="props.record.state == 5 || props.record.state == 1">
<view class="sign flex-center" hover-class="touch-hover" @tap="refresh">刷新</view>
<view v-if="ent.has('ENT_MCH_APPLYMENT_ADD')" class="new-state flex-center" hover-class="touch-button" @tap="toShowSelectIfCode()">复用信息</view>
</template>
<template v-if="ent.has('ENT_MCH_APPLYMENT_SIGN') && props.record.state == 2">
<!-- <view class="new-state flex-center" hover-class="touch-button" @tap="ak.go.to('PAGES_APPLYMENT_BUSINESS')">商户管理</view> -->
<view class="new-state flex-center" hover-class="touch-button" @tap="ak.go.to('PAGES_STORE')">门店管理</view>
<view class="new-state flex-center" hover-class="touch-button" @tap="toShowSelectIfCode()">复用信息</view>
</template>
<template v-if="props.record.state == 3">
<view class="new-state flex-center" hover-class="touch-button" @tap="toShowSelectIfCode()">修改信息</view>
</template>
<template v-if="props.record.state == 0">
<view class="sign flex-center" hover-class="touch-hover" @tap="toShowSelectIfCode()">继续填写</view>
<view class="new-state flex-center" hover-class="touch-button" @tap="toShowSelectIfCode()">复用信息</view>
</template>
<!-- <template v-if="props.record.state == 1">
<view class="sign flex-center" hover-class="touch-hover" @tap="ak.go.to('PAGES_APPLYMENT')">进件管理</view>
<view
v-if="ent.has('ENT_MCH_APPLYMENT_GET_INFO') && (props.record.state == 1 || props.record.state == 4 || props.record.state == 5)"
class="new-state flex-center"
hover-class="touch-button"
>
获取最新状态
</view>
<view v-if="ent.has('ENT_MCH_APPLYMENT_ADD')" class="new-state flex-center" hover-class="touch-button" @tap="ak.go.to('PAGES_STORE')">门店管理</view>
</template> -->
</view>
<!-- 选择支付 接口 -->
<JeepayPopupListSelect
ref="selectIfcodeRef"
title="请选择渠道"
:reqTableDataFunc="reqTableDataByIfcodeFunc"
:fields="{ key: 'ifCode', left: 'ifName', right: 'ifCode' }"
@confirm="confirmIfCode"
>
<!-- 小程序, 插槽不生效, 待排查! TODO -->
<!-- 详见: https://ask.dcloud.net.cn/question/158765 -->
<!-- JeepayPopupListSelect.js 修改 "content-" + i0, 改为: content 即可。 -->
<!-- #ifdef APP-PLUS || H5 -->
<template #content="{ record }">
<view class="pay-wrapper">
<view class="pay-info">
<view class="pay-logo flex-center" :style="{ backgroundColor: record.bgColor }">
<image :src="record.icon" mode="scaleToFill" />
</view>
<view>
<view class="pay-title">{{ record.ifName }}</view>
</view>
</view>
</view>
</template>
<!-- #endif -->
</JeepayPopupListSelect>
</view>
</template>
<script setup>
import { reactive, ref } from 'vue';
import cal from '@/commons/utils/cal.js';
import go from '@/commons/utils/go.js';
import datamap from '@/commons/utils/datamap.js';
import ent from '@/commons/utils/ent.js';
import ak from '@/commons/utils/ak.js';
import { $getAllAllowApplymentIfCodeList } from '@/http/apiManager.js';
const emit = defineEmits(['refresh']);
const selectIfcodeRef = ref();
const vdata = reactive({
addIfCodeList: [] // 可以选择的接口集合
});
// 刷新
function refresh() {
emit('refresh');
}
// 根据type返回商户类型
function merchantTypeFilter(type) {
const m = {
1: '个人',
2: '个体工商户',
3: '企业',
4: '党政、机关级事业单位',
5: '其他组织'
};
return m[type];
}
function toH5ApplyOptionPage(applyId, configPage) {
uni.navigateTo({ url: `/pageApply/applyDetailH5ApplyOption?applyId=${applyId}&configPage=${configPage}` });
}
// 去进件详情 / 修改页
function toViewPage() {
let isView = 1;
if ([0, 3, 8].indexOf(props.record.state) >= 0) {
isView = 0;
}
go.to('PAGES_APPLYMENT_H5_DETAIL', { autoConfigMchAppId: props.record.autoConfigMchAppId, isvNo: props.record.isvNo, applyId: props.record.applyId, isView: isView });
}
// 签约开通
function toSignPage() {
go.to('PAGES_APPLYMENT_H5_OPTION', { applyId: props.record.applyId, configPage: 'NEXT_BIZS' });
}
// 定义传入属性
const props = defineProps({
record: { type: Object, default: () => {} } // 渲染对象
});
const stateList = reactive([
{
text: '草稿', //0
bgColor: '#D9D9D9'
},
{
text: '审核中', //1
bgColor: '#FFCC66'
},
{
text: '已开通', //2
bgColor: '#18BC73'
},
{
text: '申请被驳回', //3
bgColor: '#FF4D5B'
},
{
text: '待验证', //4
bgColor: '#FFCC66'
},
{
text: '待签约', //5
bgColor: '#2980FD'
},
{
text: '', //6 占位
bgColor: ''
},
{
text: '等待预审', //7
bgColor: '#FFCC66'
},
{
text: '预审拒绝', //8
bgColor: '#FF4D5B'
}
]);
// 打开选择渠道页面
function toShowSelectIfCode() {
ak.go.to('PAGES_APPLYMENT_SELECETDPAY', { applyId: props.record.applyId, ifCode: props.record.ifCode, range: props.record.range });
return;
$getAllAllowApplymentIfCodeList().then(({ bizData }) => {
vdata.addIfCodeList = bizData;
selectIfcodeRef.value.open();
});
}
// 请求可以选择的支付渠道
function reqTableDataByIfcodeFunc() {
// 模拟请求数据
return Promise.resolve({ bizData: { records: vdata.addIfCodeList, hasNext: false } });
}
function confirmIfCode(selected) {
if (!selected) {
ak.infoBox.showToast('请选择进件渠道');
return false;
}
selectIfcodeRef.value.close();
ak.go.to('PAGES_APPLYMENT_H5_DETAIL', { isView: 0, ifCode: selected.ifCode, copyInfoSourceApplyId: props.record.applyId });
}
function showErrorModal(record) {
if (record.state == 3) {
uni.showModal({
title: stateList[record.state].text,
content: record.applyErrorInfo,
showCancel: false,
confirmText: '知道了'
});
}
}
function toCopyPage() {}
</script>
<style lang="scss" scoped>
.single-text-beyond {
width: 300rpx;
}
.err_icon {
margin-right: 12upx;
position: relative;
top: 2upx;
}
// 列表卡片样式
.apply-card {
padding: 0.1rpx 30rpx;
padding-bottom: 10rpx;
margin: 20rpx;
background-color: #fff;
border-radius: $J-b-r32;
.apply-title {
display: flex;
margin-top: 30rpx;
margin-bottom: 40rpx;
font-size: 30rpx;
.pay-img-wrapper {
flex-shrink: 0;
margin-right: 20rpx;
width: 90rpx;
height: 90rpx;
border-radius: 20rpx;
image {
width: 100%;
height: 100%;
}
}
.apply-title-wrapper {
flex: 1;
.apply-title-info {
display: flex;
justify-content: space-between;
height: 40rpx;
.apply-state {
display: flex;
justify-content: flex-end;
align-items: center;
font-size: 26rpx;
color: #999;
white-space: nowrap;
text {
transform: translateX(-10rpx);
}
.err_tips {
overflow: hidden;
text-overflow: ellipsis;
}
.apply-dot {
flex-shrink: 0;
width: 20rpx;
height: 20rpx;
border-radius: 50%;
background-color: #2980fd;
}
}
}
.apply-time {
color: #999;
margin-top: 10rpx;
font-size: 26rpx;
}
}
}
.apply-info-title {
margin: 20rpx 0;
display: flex;
font-size: 26rpx;
.title {
color: #808080;
}
.info {
text-indent: 56rpx;
}
}
.apply-button {
display: flex;
justify-content: flex-end;
margin-bottom: 20rpx;
view {
font-size: 26rpx;
font-weight: 500;
height: 62rpx;
border-radius: 12rpx;
}
.sign {
width: 164rpx;
border: 1rpx solid #d3d3d4;
}
.new-state {
margin-left: 20rpx;
width: 216rpx;
color: #fff;
background: $jeepay-bg-primary;
}
}
}
.pay-wrapper {
display: flex;
align-items: center;
height: 170rpx;
.dot {
position: relative;
width: 36rpx;
height: 36rpx;
border-radius: 50%;
background-color: #d7d8d9;
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 50%;
height: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
background-color: #fff;
}
}
.dot-active {
background-color: #2980fd;
}
.pay-info {
display: flex;
.pay-logo {
margin: 0 20rpx 0 0rpx;
width: 90rpx;
height: 90rpx;
border-radius: $v-b-r20;
background-color: #07112d;
image {
width: 50rpx;
height: 50rpx;
}
}
.pay-title {
font-size: 30rpx;
font-weight: 400;
}
}
}
</style>

View File

@@ -1,334 +0,0 @@
<!--
订单列表页面 数据渲染
业务 进件
@author terrfly
@site https://www.jeequan.com
@date 2022/11/29 09:17
-->
<template>
<!-- 草稿 灰色 失败红色 审核中 黄色 -->
<!-- 列表卡片 -->
<view class="apply-card">
<view class="apply-title" @tap="toDetailPage">
<view class="pay-img-wrapper flex-center" :style="{ backgroundColor: record.bgColor }">
<image :src="props.record.storeLogo" mode="aspectFill" />
</view>
<view class="apply-title-wrapper">
<view class="apply-title-info">
<text class="single-text-beyond" style="width: 340rpx">{{ props.record.storeName }}</text>
<!-- <view class="apply-state">
<text>{{ stateList[record.state]?.text }}</text>
<view class="apply-dot" :style="{ backgroundColor: stateList[record.state]?.bgColor }"></view>
</view> -->
</view>
<view class="apply-time">{{ props.record.createdAt }}</view>
</view>
</view>
<view class="apply-info-title" @tap="toDetailPage">
<view class="title">门店编号</view>
<view class="info">{{ props.record.storeId }}</view>
</view>
<view class="apply-info-title" @tap="toDetailPage">
<view class="title">所属商户</view>
<view class="info">{{ props.record.isvName }}</view>
</view>
<view class="apply-button">
<!-- <view
v-if="
ent.has('ENT_MCH_APPLYMENT_SIGN') &&
(props.record.state == 1 || props.record.state == 2 || props.record.state == 4 || props.record.state == 5 || props.record.state == 6)
"
class="sign flex-center"
hover-class="touch-hover"
@tap="toSignPage"
>
签约开通
</view>
<view
v-if="ent.has('ENT_MCH_APPLYMENT_GET_INFO') && (props.record.state == 1 || props.record.state == 4 || props.record.state == 5)"
class="new-state flex-center"
hover-class="touch-button"
>
获取最新状态
</view> -->
<view class="new-state flex-center" hover-class="touch-button" @tap="ak.go.to('PAGES_DEVICE_MAIN')">设备管理</view>
<!-- <view v-if="ent.has('ENT_MCH_APPLYMENT_ADD')" class="new-state flex-center" hover-class="touch-button" @tap.stop="toShowSelectIfCode()">设备管理</view> -->
</view>
<!-- 选择支付 接口 -->
<JeepayPopupListSelect
ref="selectIfcodeRef"
title="请选择渠道"
:reqTableDataFunc="reqTableDataByIfcodeFunc"
:fields="{ key: 'ifCode', left: 'ifName', right: 'ifCode' }"
@confirm="confirmIfCode"
>
<!-- 小程序, 插槽不生效, 待排查! TODO -->
<!-- 详见: https://ask.dcloud.net.cn/question/158765 -->
<!-- JeepayPopupListSelect.js 修改 "content-" + i0, 改为: content 即可。 -->
<!-- #ifdef APP-PLUS || H5 -->
<template #content="{ record }">
<view class="pay-wrapper">
<view class="pay-info">
<view class="pay-logo flex-center" :style="{ backgroundColor: record.bgColor }">
<image :src="record.icon" mode="scaleToFill" />
</view>
<view>
<view class="pay-title">{{ record.ifName }}</view>
</view>
</view>
</view>
</template>
<!-- #endif -->
</JeepayPopupListSelect>
</view>
</template>
<script setup>
import { reactive, ref } from 'vue';
import cal from '@/commons/utils/cal.js';
import go from '@/commons/utils/go.js';
import datamap from '@/commons/utils/datamap.js';
import ent from '@/commons/utils/ent.js';
import ak from '@/commons/utils/ak.js';
import { $getAllAllowApplymentIfCodeList } from '@/http/apiManager.js';
const selectIfcodeRef = ref();
const vdata = reactive({
addIfCodeList: [] // 可以选择的接口集合
});
function toDetailPage() {
go.to('PAGES_APP_STORE_DETAIL', { storeId: props.record.storeId });
}
function toH5ApplyOptionPage(applyId, configPage) {
uni.navigateTo({ url: `/pageApply/applyDetailH5ApplyOption?applyId=${applyId}&configPage=${configPage}` });
}
// 去进件详情 / 修改页
function toViewPage() {
let isView = 1;
if ([0, 3, 8].indexOf(props.record.state) >= 0) {
isView = 0;
}
go.to('PAGES_APPLYMENT_H5_DETAIL', { autoConfigMchAppId: props.record.autoConfigMchAppId, isvNo: props.record.isvNo, applyId: props.record.applyId, isView: isView });
}
// 签约开通
function toSignPage() {
go.to('PAGES_APPLYMENT_H5_OPTION', { applyId: props.record.applyId, configPage: 'NEXT_BIZS' });
}
// 定义传入属性
const props = defineProps({
record: { type: Object, default: () => {} } // 渲染对象
});
const stateList = reactive([
{
text: '草稿', //0
bgColor: '#D9D9D9'
},
{
text: '审核中', //1
bgColor: '#FFCC66'
},
{
text: '已开通', //2
bgColor: '#18BC73'
},
{
text: '申请被驳回', //3
bgColor: '#FF4D5B'
},
{
text: '待验证', //4
bgColor: '#FFCC66'
},
{
text: '待签约', //5
bgColor: '#2980FD'
},
{
text: '', //6 占位
bgColor: ''
},
{
text: '等待预审', //7
bgColor: '#FFCC66'
},
{
text: '预审拒绝', //8
bgColor: '#FF4D5B'
}
]);
// 打开选择渠道页面
function toShowSelectIfCode() {
ak.go.to('PAGES_DEVICE_MAIN');
// ak.go.to('PAGES_APPLYMENT_SELECETDPAY', { applyId: props.record.applyId, ifCode: props.record.ifCode, range: props.record.range });
return;
$getAllAllowApplymentIfCodeList().then(({ bizData }) => {
vdata.addIfCodeList = bizData;
selectIfcodeRef.value.open();
});
}
// 请求可以选择的支付渠道
function reqTableDataByIfcodeFunc() {
// 模拟请求数据
return Promise.resolve({ bizData: { records: vdata.addIfCodeList, hasNext: false } });
}
function confirmIfCode(selected) {
if (!selected) {
ak.infoBox.showToast('请选择进件渠道');
return false;
}
selectIfcodeRef.value.close();
ak.go.to('PAGES_APPLYMENT_H5_DETAIL', { isView: 0, ifCode: selected.ifCode, copyInfoSourceApplyId: props.record.applyId });
}
function toCopyPage() {}
</script>
<style lang="scss" scoped>
// 列表卡片样式
.apply-card {
padding: 0.1rpx 30rpx;
padding-bottom: 10rpx;
margin: 20rpx;
background-color: #fff;
border-radius: $J-b-r32;
.apply-title {
display: flex;
margin-top: 30rpx;
margin-bottom: 40rpx;
font-size: 30rpx;
.pay-img-wrapper {
margin-right: 20rpx;
width: 90rpx;
height: 90rpx;
border-radius: 20rpx;
image {
width: 100%;
height: 100%;
}
}
.apply-title-wrapper {
flex: 1;
.apply-title-info {
display: flex;
justify-content: space-between;
height: 40rpx;
.apply-state {
display: flex;
align-items: center;
font-size: 26rpx;
color: #999;
white-space: nowrap;
text {
transform: translateX(-10rpx);
}
.apply-dot {
width: 20rpx;
height: 20rpx;
border-radius: 50%;
background-color: #2980fd;
}
}
}
.apply-time {
color: #999;
margin-top: 10rpx;
font-size: 26rpx;
}
}
}
.apply-info-title {
margin: 20rpx 0;
display: flex;
font-size: 26rpx;
.title {
color: #808080;
}
.info {
text-indent: 56rpx;
}
}
.apply-button {
display: flex;
justify-content: flex-end;
margin-bottom: 20rpx;
view {
font-size: 26rpx;
font-weight: 500;
height: 62rpx;
border-radius: 12rpx;
}
.sign {
width: 164rpx;
border: 1rpx solid #d3d3d4;
}
.new-state {
margin-left: 20rpx;
width: 216rpx;
color: #fff;
background: $jeepay-bg-primary;
}
}
}
.pay-wrapper {
display: flex;
align-items: center;
height: 170rpx;
.dot {
position: relative;
width: 36rpx;
height: 36rpx;
border-radius: 50%;
background-color: #d7d8d9;
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 50%;
height: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
background-color: #fff;
}
}
.dot-active {
background-color: #2980fd;
}
.pay-info {
display: flex;
.pay-logo {
margin: 0 20rpx 0 0rpx;
width: 90rpx;
height: 90rpx;
border-radius: $v-b-r20;
background-color: #07112d;
image {
width: 50rpx;
height: 50rpx;
}
}
.pay-title {
font-size: 30rpx;
font-weight: 400;
}
}
}
</style>

View File

@@ -1,38 +0,0 @@
<!--
订单列表页面 数据渲染
业务 门店
@author terrfly
@site https://www.jeequan.com
@date 2022/11/23 16:57
-->
<template>
<JeepayTableListItem :subtitle="props.record.storeId" @tap="toDetailPage" :logo="props.record.storeLogo||'/static/indexImg/icon-store.svg'">
<template #title>
{{ props.record.storeName }}
<JeepayTag v-if="props.record.defaultFlag == 1" type="green-rgba">默认</JeepayTag>
<JeepayTag v-if="props.record.alipayShopStatus == 99" type="blue">蚂蚁店铺</JeepayTag>
</template>
</JeepayTableListItem>
</template>
<script setup>
import { reactive, ref } from "vue"
import go from '@/commons/utils/go.js'
// 定义传入属性
const props = defineProps({
record: {type:Object, default: () => {}}, // 渲染对象
})
function toDetailPage(){
go.to("PAGES_APP_STORE_DETAIL", {storeId: props.record.storeId})
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -1,141 +0,0 @@
<!--
会员账户流水列表页面 数据渲染
业务 会员账户流水
@author terrfly
@site https://www.jeequan.com
@date 2022/11/30 07:07
-->
<template>
<view class="card">
<view class="card-content" @tap="toDetails">
<view class="card-content-title">
<view class="card-content-title-left">
<image :src="props.record.avatarUrl" />
<text>{{ props.record.mbrName }}</text>
</view>
<view class="card-content-title-right">
<text>{{ props.record.changeAmount < 0? '-' : '+'}}{{cal.cert2Dollar(Math.abs(props.record.changeAmount))}}</text>
</view>
</view>
<view class="card-content-line"></view>
<view class="card-content-body">
<view class="card-content-body-row">
<text>变动时间</text>
<text>{{ props.record.createdAt }}</text>
</view>
<view class="card-content-body-row">
<text>业务类型</text>
<text>{{ props.record.bizType==1?'支付充值':props.record.bizType==2?'现金充值':props.record.bizType==3?'会员消费':props.record.bizType==4?'消费退款':props.record.bizType==5?'人工调账':'其他' }}</text>
</view>
<view class="card-content-body-row">
<text>变动后余额</text>
<text>{{ cal.cert2Dollar(props.record.afterAmount) }}</text>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { reactive, ref } from 'vue'
import cal from '@/commons/utils/cal.js'
import go from '@/commons/utils/go.js'
// 定义传入属性
const props = defineProps({
record: { type: Object, default: () => {} }, // 渲染对象
})
//前往会员详情
const toDetails = () => {
go.to('PAGES_MEMBER_ACCOUNT_HISTORY_DETAIL', { hid: props.record.hid })
}
</script>
<style lang="scss" scoped>
.card {
width: 690rpx;
margin: 30rpx auto;
}
.card-content {
border-radius: 20rpx;
background-color: $J-bg-ff;
margin: 10rpx 0;
}
.card-content-title {
height: 100rpx;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 0 30rpx;
.card-content-title-left {
height: 100rpx;
display: flex;
color: #000000ff;
font-size: 30rpx;
flex-direction: row;
align-items: center;
image {
width: 40rpx;
height: 40rpx;
border-radius: 50%;
}
text {
padding-left: 10rpx;
}
}
.card-content-title-right {
font-weight: 600;
color: #000000ff;
text {
font-size: 30rpx;
}
}
}
.card-content-line {
border-bottom: 2rpx solid rgba(0, 0, 0, 0.06);
}
.card-content-body {
padding: 20rpx;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: space-evenly;
box-sizing: border-box;
.card-content-body-row {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
padding-left: 50rpx;
height: 60rpx;
text:first-child {
width: 170rpx;
color: #999999ff;
font-size: 26rpx;
font-weight: 400;
}
text:last-child {
color: #000000ff;
font-size: 26rpx;
font-weight: 400;
}
}
}
</style>

View File

@@ -1,165 +0,0 @@
<!--
会员充值记录列表页面 数据渲染
业务 会员充值记录
@author terrfly
@site https://www.jeequan.com
@date 2022/11/30 07:07
-->
<template>
<view class="card">
<view class="card-content" @tap="toDetails">
<view class="card-content-title">
<view class="card-content-title-left">
<image :src="props.record.avatarUrl" />
<text>{{ props.record.mbrName }}</text>
</view>
<view class="card-content-title-right">
<text></text>
<text>{{ cal.cert2Dollar(props.record.entryAmount) }}</text>
</view>
</view>
<view class="card-content-line"></view>
<view class="card-content-body">
<view class="card-content-body-row">
<text>充值时间</text>
<text>{{ props.record.createdAt }}</text>
</view>
<view class="card-content-body-row">
<text>充值状态</text>
<view class="order">
<view class="order-spot" :style="{ backgroundColor: datamap.rechargeRecordImage(props.record.state).color }"></view>
<text class="order-text">{{ datamap.rechargeRecordImage(props.record.state).text }}</text>
</view>
</view>
<view v-if="props.record.state==2" class="card-content-body-row">
<text>充值后余额</text>
<text>{{ cal.cert2Dollar(props.record.afterBalance) }}</text>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { reactive, ref } from 'vue'
import cal from '@/commons/utils/cal.js'
import go from '@/commons/utils/go.js'
import datamap from '@/commons/utils/datamap.js'
// 定义传入属性
const props = defineProps({
record: { type: Object, default: () => {} }, // 渲染对象
})
//前往会员详情
const toDetails = () => {
go.to('PAGES_MEMBER_RECHARGE_RECORD_DETAIL', { rechargeRecordId: props.record.rechargeRecordId })
}
</script>
<style lang="scss" scoped>
.card {
width: 690rpx;
margin: 30rpx auto;
}
.card-content {
border-radius: 20rpx;
background-color: $J-bg-ff;
margin: 10rpx 0;
}
.card-content-title {
height: 100rpx;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 0 30rpx;
.card-content-title-left {
height: 100rpx;
display: flex;
color: #000000ff;
font-size: 30rpx;
flex-direction: row;
align-items: center;
image {
width: 40rpx;
height: 40rpx;
border-radius: 50%;
}
text {
padding-left: 10rpx;
}
}
.card-content-title-right {
font-weight: 600;
color: #000000ff;
text:first-child {
font-size: 20rpx;
}
text:last-child {
font-size: 30rpx;
}
}
}
.card-content-line {
border-bottom: 2rpx solid rgba(0, 0, 0, 0.06);
}
.card-content-body {
padding: 20rpx;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: space-evenly;
box-sizing: border-box;
.card-content-body-row {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
opacity: 1;
padding-left: 50rpx;
height: 60rpx;
text:first-child {
width: 160rpx;
color: #999999ff;
font-size: 26rpx;
font-weight: 400;
}
text:last-child {
color: #000000ff;
font-size: 26rpx;
font-weight: 400;
}
.order {
display: flex;
flex-direction: row;
align-items: center;
.order-spot {
width: 10rpx;
height: 10rpx;
border-radius: 50%;
}
.order-text {
padding-left: 10rpx;
color: #000000ff;
font-size: 26rpx;
font-weight: 400;
}
}
}
}
</style>

View File

@@ -1,148 +0,0 @@
<!--
充值规则列表页面 数据渲染
业务 充值规则
@author terrfly
@site https://www.jeequan.com
@date 2022/11/30 07:07
-->
<template>
<view class="card">
<view class="card-content">
<view class="card-content-left">
<view class="rule">
<view class="rule-amount">
<text></text>
<text class="rule-amount-recharge">{{ cal.cert2Dollar(props.record.rechargeAmount) }}</text>
</view>
<view class="rule-amount">
<text></text>
<text class="rule-amount-give">{{ cal.cert2Dollar(props.record.giveAmount) }}</text>
</view>
</view>
<view class="rule-state">
<view class="order-spot" :style="{ backgroundColor: props.record.state ? '#09BB07' : '#CB2972' }"></view>
<text>{{ props.record.state ? '启用' : '禁用' }}</text>
</view>
</view>
<view class="card-content-right">
<image src="/static/member/edit.svg" @tap="editFunc(props.record.ruleId)"></image>
<view class="right-line"></view>
<image src="/static/member/delete.svg" @tap="deleteFunc(props.record.ruleId)"></image>
</view>
</view>
<JeepayPopupConfirm ref="jeepayPopupConfirmRef" />
</view>
</template>
<script setup>
import { reactive, ref } from 'vue'
import cal from '@/commons/utils/cal.js'
import go from '@/commons/utils/go.js'
import emit from '@/commons/utils/emit.js'
import infoBox from '@/commons/utils/infoBox.js'
import { reqLoad, API_URL_MEMBER_RECHARGE_RULES } from "@/http/apiManager.js"
const jeepayPopupConfirmRef = ref()
// 定义传入属性
const props = defineProps({
record: { type: Object, default: () => {} }, // 渲染对象
})
const editFunc = (ruleId) => {
go.to("PAGES_RECHARGE_RULE_EDIT", { ruleId: ruleId })
}
const deleteFunc = (ruleId) => {
jeepayPopupConfirmRef.value.open('确定删除规则?', { confirmColor: 'red' }).then(() => {
return reqLoad.delById(API_URL_MEMBER_RECHARGE_RULES, ruleId).then(() => {
infoBox.showSuccessToast("删除成功");
emit.pageEmit(emit.ENAME_REF_RECHARGE_RULE_LIST) // 更新列表
})
}).catch(() => {
})
}
</script>
<style lang="scss" scoped>
.card {
width: 711rpx;
margin: 0 auto;
}
.card-content {
height: 180rpx;
display: flex;
flex-direction: row;
border-radius: 20rpx;
background-color: $J-bg-ff;
margin: 20rpx 0;
}
.card-content-left {
width: 590rpx;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 0 40rpx;
.rule {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: flex-start;
.rule-amount {
color: #808080ff;
font-size: 30rpx;
padding: 8rpx 0;
}
.rule-amount-recharge {
color: #000000ff;
font-size: 30rpx;
}
.rule-amount-give {
color: #3d8affff;
font-size: 30rpx;
}
}
.rule-state {
color: #000000ff;
font-size: 26rpx;
display: flex;
flex-direction: row;
align-items: center;
.order-spot {
width: 10rpx;
height: 10rpx;
border-radius: 50%;
}
text {
margin-left: 8rpx;
}
}
}
.card-content-right {
width: 120rpx;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
border-left: 2rpx solid rgba(0, 0, 0, 0.06);
image {
width: 40rpx;
height: 40rpx;
}
.right-line {
width: 100%;
border-bottom: 2rpx solid rgba(0, 0, 0, 0.06);
}
}
</style>

View File

@@ -1,118 +0,0 @@
<!--
会员列表页面 数据渲染
业务 会员管理
@author terrfly
@site https://www.jeequan.com
@date 2022/11/30 07:07
-->
<template>
<view class="card-wrapper">
<view class="card-main" hover-class="touch-hover" :style="{ right: right + 'rpx' }">
<view class="card-item" @tap="toDetails">
<view class="img-wrapper">
<image :src="props.record.avatarUrl" mode="scaleToFill" />
</view>
<view class="card-info">
<view class="info-text">
<view class="text-main single-text-beyond">{{ props.record.mbrName }}</view>
</view>
<view class="info-phone">
{{props.record.mbrTel}}
<text class="info-balance">余额{{ cal.cert2Dollar(props.record.balance) }}</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { reactive, ref } from 'vue'
import go from '@/commons/utils/go.js'
import cal from '@/commons/utils/cal.js'
// 定义传入属性
const props = defineProps({
record: { type: Object, default: () => {} }, // 渲染对象
})
//前往会员详情
const toDetails = () => {
go.to('PAGES_MEMBER_DETAIL', { mbrId: props.record.mbrId })
}
</script>
<style lang="scss" scoped>
.card-wrapper {
overflow: hidden;
.card-main {
position: relative;
padding: 0 30rpx;
height: 170rpx;
background-color: $J-bg-ff;
transition: 0.2s ease-in;
.card-item {
display: flex;
align-items: center;
width: 100%;
height: 100%;
.img-wrapper {
position: relative;
flex-shrink: 0;
width: 100rpx;
height: 100rpx;
background-color: skyblue;
border-radius: 50%;
image {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.card-info {
margin-left: 30rpx;
.info-text {
display: flex;
.text-main {
max-width: 446rpx;
font-size: 30rpx;
font-weight: 400;
color: #000000ff;
opacity: 1;
}
.info-state {
display: flex;
align-items: center;
margin-left: 30rpx;
padding: 0 15rpx;
height: 40rpx;
font-size: 23rpx;
font-weight: 400;
color: #fff;
white-space: nowrap;
background: linear-gradient(270deg, rgba(61, 220, 68, 1) 0%, rgba(23, 187, 118, 1) 100%);
border-radius: 6rpx;
}
}
.info-phone {
margin-top: 16rpx;
font-size: 25rpx;
font-weight: 400;
color: $J-color-t99;
.info-balance {
padding-left: 30rpx;
color: #000000ff;
font-size: 26rpx;
}
}
}
}
}
}
</style>

View File

@@ -1,142 +0,0 @@
<!--
订单列表页面 数据渲染
业务 支付订单列表页
@author terrfly
@site https://www.jeequan.com
@date 2022/11/23 16:57
-->
<template>
<!-- 列表卡片循环渲染start -->
<view class="order-card" hover-class="touch-hover" hover-stay-time="150" @tap="toDetail()">
<view class="img-wrapper flex-center" :style="{ backgroundColor: datamap.payOrderImage(record?.wayCodeType)?.bgColor }">
<image :src="datamap.payOrderImage(record?.wayCodeType)?.imgUrl" mode="scaleToFill"></image>
</view>
<view class="order-info">
<view class="order-num">
<view> <text class="icon-money"></text> {{ cal.cert2Dollar(props.record.amount) }} </view>
<view class="order-state">
{{ datamap.payOrderState(props.record.state).text }}
<text class="order-spot" :style="{ backgroundColor: datamap.payOrderState(props.record.state).color }"></text>
</view>
</view>
<view class="order-time">{{ props.record.createdAt }}</view>
</view>
</view>
</template>
<script setup>
import { reactive, ref } from 'vue'
import cal from '@/commons/utils/cal.js'
import go from '@/commons/utils/go.js'
import datamap from '@/commons/utils/datamap.js'
// 跳转详情页
function toDetail() {
go.to('PAGES_PAY_ORDER_DETAIL', { payOrderId: props.record.payOrderId })
}
// 定义传入属性
const props = defineProps({
record: { type: Object, default: () => {} }, // 渲染对象
})
</script>
<style lang="scss" scoped>
.store-name {
display: flex;
align-items: center;
font-size: 33rpx;
font-weight: 500;
image {
width: 44rpx;
height: 44rpx;
margin-left: 5rpx;
transform: rotate(180deg);
}
}
.input-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 30rpx;
padding-top: 22rpx;
height: 110rpx;
background-color: $J-bg-ff;
.input-main {
flex: 1;
display: flex;
align-items: center;
height: 70rpx;
background: $J-bg-f5;
border-radius: $J-b-r12;
image {
padding: 22rpx;
width: 26rpx;
height: 26rpx;
}
input {
flex: 1;
font-size: 27rpx;
}
}
.screen-wrapper {
margin: 0 12rpx 0 20rpx;
font-size: 32rpx;
color: $J-color-t99;
image {
width: 28rpx;
height: 26rpx;
padding: 0 21rpx;
}
}
}
.order-card {
display: flex;
align-items: center;
padding: 0 30rpx;
height: 170rpx;
background-color: $J-bg-ff;
.img-wrapper {
margin-right: 30rpx;
width: 100rpx;
height: 100rpx;
border-radius: 50%;
overflow: hidden;
image {
width: 100%;
height: 100%;
}
}
.order-info {
flex: 1;
.order-num {
display: flex;
justify-content: space-between;
font-size: 30rpx;
font-weight: 500;
.icon-money {
font-size: 23rpx;
}
.order-state {
display: flex;
align-items: center;
color: $J-color-t80;
.order-spot {
display: block;
margin: 0 10rpx 0 20rpx;
width: 20rpx;
height: 20rpx;
border-radius: 50%;
}
}
}
.order-time {
margin-top: 16rpx;
font-size: 26rpx;
color: $J-color-t99;
}
}
}
</style>

View File

@@ -1,197 +0,0 @@
<!--
订单列表页面 数据渲染
业务 用户管理 迁移自 JFeftCard
@author terrfly
@site https://www.jeequan.com
@date 2022/11/30 07:07
-->
<template>
<view class="card-wrapper">
<view class="card-main" hover-class="touch-hover" :style="{ right: right + 'rpx' }">
<view class="card-item" @tap="toDetails">
<view class="img-wrapper" :class="{ 'open-state': props.record.state == 1, 'close-state': props.record.state == 0 }">
<image :src="props.record.avatarUrl" mode="scaleToFill" />
</view>
<view class="card-info">
<view class="info-text">
<view class="text-main single-text-beyond">{{ props.record.realname }}</view>
<JeepayTag :type="datamap.userType(props.record.userType).type">{{ datamap.userType(props.record.userType).text }}</JeepayTag>
</view>
<view class="info-phone">{{props.record.telphone}}</view>
</view>
</view>
<view class="card-delete" hover-class="u-cell-delete" hover-stay-time="150" @tap="deleteStaff"> 删除 </view>
</view>
</view>
</template>
<script setup>
import { reactive, ref } from 'vue'
import cal from '@/commons/utils/cal.js'
import go from '@/commons/utils/go.js'
import datamap from '@/commons/utils/datamap.js'
// 定义传入属性
const props = defineProps({
record: { type: Object, default: () => {} }, // 渲染对象
})
// 删除确认弹窗
const deleteStaff = (v) => {
// jeepayPopupConfirmRef.value.open(`确认删除 ${v.name} 员工吗?`).then(() => {
// console.log('确认')
// });
}
//前往员工详情
const toDetails = () => {
go.to('PAGES_USER_DETAIL', { sysUserId: props.record.sysUserId })
}
// 该部分 为左滑右滑功能部分
const right = ref(0)
let startX = 0
const touchStart = (e) => {
startX = e.touches[0].clientX
}
const touchMove = (e) => {
const endX = e.changedTouches[0].clientX
const deviationX = startX - endX
if (deviationX > 0) {
leftTouch(deviationX)
} else if (deviationX < 0) {
rightTouch(deviationX)
}
}
const touchEnd = (e) => {
const endX = e.changedTouches[0].clientX
const deviationX = startX - endX
if (deviationX == 0) {
emits('touchDown')
}
}
const leftTouch = (x) => {
if (x <= 50) return
right.value += x
if (right.value > 232) {
right.value = 232
}
}
const rightTouch = (x) => {
if (right.value > 0) {
right.value += x
right.value = right.value > 0 ? 0 : right.value
} else {
right.value = 0
}
}
// 左滑右滑 end
</script>
<style lang="scss" scoped>
.card-wrapper {
overflow: hidden;
.card-main {
position: relative;
padding: 0 30rpx;
height: 170rpx;
background-color: #fff;
transition: 0.2s ease-in;
.card-item {
display: flex;
align-items: center;
width: 100%;
height: 100%;
.img-wrapper {
position: relative;
flex-shrink: 0;
width: 100rpx;
height: 100rpx;
background-color: skyblue;
border-radius: 50%;
image {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.close-state::after {
content: '';
position: absolute;
right: -10rpx;
bottom: -5rpx;
width: 25rpx;
height: 25rpx;
border: 6rpx solid #fff;
border-radius: 50%;
background-color: #d9d9d9;
}
.open-state::after {
content: '';
position: absolute;
right: -10rpx;
bottom: -5rpx;
width: 25rpx;
height: 25rpx;
border: 6rpx solid #fff;
border-radius: 50%;
background-color: #168fff;
}
.card-info {
margin-left: 30rpx;
.info-text {
display: flex;
.text-main {
max-width: 446rpx;
font-size: 30rpx;
font-weight: 400;
}
.info-state {
display: flex;
align-items: center;
margin-left: 30rpx;
padding: 0 15rpx;
height: 40rpx;
font-size: 23rpx;
font-weight: 400;
color: #fff;
white-space: nowrap;
background: linear-gradient(270deg, rgba(61, 220, 68, 1) 0%, rgba(23, 187, 118, 1) 100%);
border-radius: 6rpx;
}
}
.info-phone {
margin-top: 16rpx;
font-size: 25rpx;
font-weight: 400;
color: $J-color-t99;
}
}
}
.card-delete {
position: absolute;
top: 0;
right: -232rpx;
display: flex;
justify-content: center;
align-items: center;
width: 232rpx;
height: 170rpx;
color: #fff;
background-color: #ff5b4c;
}
}
}
.u-cell-hover {
background-color: #f8f9fa;
}
.u-cell-delete {
opacity: 0.5;
}
</style>

View File

@@ -1,64 +0,0 @@
<!--
订单列表页面 数据渲染
业务 通知人管理
@author terrfly
@site https://www.jeequan.com
@date 2022/11/28 17:44
-->
<template>
<view class="notice-main">
<view class="notice-title">
<view class="notice-name single-text-beyond">{{ props.record.nickname }}</view>
<JeepayStateSwitch v-model:state="props.record.sendStatus" :showSwitchType="true" :updateStateFunc="updateStateFunc" />
</view>
<view class="notice-info">{{ props.record.wxOpenId }}</view>
</view>
</template>
<script setup>
import { reactive, ref } from "vue"
import cal from '@/commons/utils/cal.js'
import go from '@/commons/utils/go.js'
import datamap from '@/commons/utils/datamap.js'
import { reqLoad, API_URL_WXMP_USER_LIST } from "@/http/apiManager.js"
import infoBox from '@/commons/utils/infoBox.js'
// 定义传入属性
const props = defineProps({
record: {type:Object, default: () => {}}, // 渲染对象
})
function updateStateFunc (sendStatus) {
return reqLoad.updateById(API_URL_WXMP_USER_LIST, props.record.userId, { sendStatus : sendStatus }).then(({bizData}) => {
infoBox.showSuccessToast('更新成功')
})
}
</script>
<style lang="scss" scoped>
.notice-main {
display: flex;
flex-direction: column;
justify-content: center;
padding: 0 40rpx;
height: 175rpx;
background-color: $J-bg-ff;
.notice-title {
display: flex;
align-items: center;
justify-content: space-between;
.notice-name {
width: 480rpx;
font-size: 30rpx;
}
}
.notice-info {
margin-top: 16rpx;
font-size: 26rpx;
color: $J-color-t99;
}
}
</style>

View File

@@ -1,315 +0,0 @@
<template>
<JeepayBackground>
<view class="input-wrapper">
<view class="input-main">
<uni-easyinput class='jeepay-search' :inputBorder="false" :placeholder="vdata.pageObject.searchPlaceholder"
v-model="vdata.searchVal" @focus="focus" @confirm="searchFunc">
<template #prefixIcon><image src="@/static/iconImg/icon-search.svg" class="input-icon" @tap="vdata.searchVal=''" /></template>
</uni-easyinput>
<button type="text" @click="searchFunc()">搜索</button>
<!-- <button v-show="!vdata.isSearch" type="text" @click="searchFunc">取消</button> -->
</view>
</view>
<JeepayTableList ref="tableRef" :reqTableDataFunc="reqTableDataFunc" :searchData="vdata.searchData" :initData="false">
<template #tableBody="{ record }">
<PayOrderRender v-if="vdata.pageType == 'payOrder'" :record="record" />
<MchAppRender v-if="vdata.pageType == 'mchApp'" :record="record" />
<WxmpUserRender v-if="vdata.pageType == 'wxmpUser'" :record="record" />
<MchApplymentRender v-if="vdata.pageType == 'mchApplyment'" :record="record" />
<MchStoreRender v-if="vdata.pageType == 'mchStore'" :record="record" />
<SysUserRender v-if="vdata.pageType == 'sysUser'" :record="record" />
<AppConfigRender v-if="vdata.pageType == 'payPassage'" :record="record" :configAppId="vdata.pageOptions.appId" />
<MemberRender v-if="vdata.pageType == 'member'" :record="record" />
<MemberRechargeRecordRender v-if="vdata.pageType == 'memberRechargeRecord'" :record="record" />
<MemberAccountHistoryRender v-if="vdata.pageType == 'memberAccountHistory'" :record="record" />
<!-- 设备的三个类型的搜索 -->
<DeviceCommonsRender v-if="vdata.pageType == 'qrc'" type="qrc" :record="record" />
<DeviceCommonsRender v-if="vdata.pageType == 'storeTerminal'" type="storeTerminal" :record="record" />
<DeviceCommonsRender v-if="vdata.pageType == 'device'" type="device" :record="record" />
<DeviceCommonsRender v-if="vdata.pageType == 'face'" type="face" :record="record" />
<FaceCardRender v-if="vdata.pageType == 'faceImgAd'" v-bind="record" />
<!-- 数据渲染: 动态组件 微信小程序不支持 -->
<!-- <component ref="recordRenderComponentRef" :is="vdata.pageObject.component" :record="record" /> -->
</template>
</JeepayTableList>
</JeepayBackground>
</template>
<script setup>
import { reactive, ref, onMounted, nextTick } from 'vue';
import emit from '@/commons/utils/emit.js';
import go from '@/commons/utils/go.js';
import {
reqLoad,
API_URL_PAY_ORDER_LIST,
API_URL_MCH_APP_LIST,
API_URL_WXMP_USER_LIST,
API_URL_MCH_APPLYMENT_LIST,
API_URL_MCH_STORE_LIST,
API_URL_SYS_USER_LIST,
API_URL_PAY_PASSAGE_LIST,
API_URL_SYS_CODE_LIST,
API_URL_SYS_DEVICE_LIST,
API_URL_SYS_TERMINALS,
API_URI_PAY_AD_LIST,
API_URL_MEMBERS,
API_URL_MEMBER_RECHARGE_RECORDS,
API_URL_MEMBER_ACCOUNT_HISTORY
} from '@/http/apiManager.js';
import { onLoad, onUnload, onReachBottom } from '@dcloudio/uni-app';
import PayOrderRender from './render/PayOrderRender.vue';
import MchAppRender from './render/MchAppRender.vue';
import WxmpUserRender from './render/WxmpUserRender.vue';
import MchApplymentRender from './render/MchApplymentRender.vue';
import MchStoreRender from './render/MchStoreRender.vue';
import SysUserRender from './render/SysUserRender.vue';
import AppConfigRender from './render/AppConfigRender.vue';
import DeviceCommonsRender from './render/DeviceCommonsRender.vue';
import FaceCardRender from './render/FaceCardRender.vue';
import MemberRender from './render/MemberRender.vue';
import MemberRechargeRecordRender from './render/MemberRechargeRecordRender.vue';
import MemberAccountHistoryRender from './render/MemberAccountHistoryRender.vue';
onReachBottom(() => {});
const tableRef = ref();
const recordRenderComponentRef = ref(); // 数据渲染组件
// 定义所有的页面类型
const pageTypeMap = {
payOrder: {
// 支付订单列表
component: PayOrderRender, // 渲染组件
searchUrl: API_URL_PAY_ORDER_LIST,
searchField: 'unionOrderId', // 搜索字段
searchPlaceholder: '支付订单号、商户单号' // 显示名称
},
mchApp: {
// 商户应用
component: MchAppRender, // 渲染组件
searchUrl: API_URL_MCH_APP_LIST,
searchField: 'unionSearchId', // 搜索字段
searchPlaceholder: '应用APPID、名称' // 显示名称
},
wxmpUser: {
// 通知人管理
component: WxmpUserRender, // 渲染组件
searchUrl: API_URL_WXMP_USER_LIST,
searchField: 'nickname', // 搜索字段
searchPlaceholder: '昵称' // 显示名称
},
mchApplyment: {
// 进件
component: MchApplymentRender, // 渲染组件
searchUrl: API_URL_MCH_APPLYMENT_LIST,
searchField: 'unionSearchId', // 搜索字段
searchPlaceholder: '进件单号' // 显示名称
},
mchStore: {
// 门店
component: MchStoreRender, // 渲染组件
searchUrl: API_URL_MCH_STORE_LIST,
searchField: 'unionStoreInfo', // 搜索字段
searchPlaceholder: '门店名称、ID' // 显示名称
},
sysUser: {
// 用户管理
component: SysUserRender, // 渲染组件
searchUrl: API_URL_SYS_USER_LIST,
searchField: 'realname', // 搜索字段
searchPlaceholder: '姓名' // 显示名称
},
payPassage: {
// 支付通道配置
component: AppConfigRender, // 渲染组件
searchUrl: API_URL_PAY_PASSAGE_LIST,
searchField: 'wayCode', // 搜索字段
searchPlaceholder: '支付方式代码' // 显示名称
},
qrc: {
searchUrl: API_URL_SYS_CODE_LIST,
searchField: 'appSearchData',
searchPlaceholder: '搜索码牌名称,编号'
},
device: {
searchUrl: API_URL_SYS_DEVICE_LIST,
searchField: 'appSearchData',
searchPlaceholder: '搜索设备名称、编号'
},
storeTerminal: {
searchUrl: API_URL_SYS_TERMINALS,
searchField: 'trmName',
searchPlaceholder: '搜索辅助终端名称'
},
face: {
searchUrl: API_URL_SYS_DEVICE_LIST,
searchField: 'appSearchData',
searchPlaceholder: '搜索设备名称、编号'
},
faceImgAd:{
searchUrl: API_URI_PAY_AD_LIST,
searchField: 'title',
searchPlaceholder: '搜索广告标题'
},
// 会员管理
member: {
component: MemberRender, // 渲染组件
searchUrl: API_URL_MEMBERS,
searchField: 'unionQueryParam',
searchPlaceholder: '搜索手机号、会员名称'
},
// 会员充值记录
memberRechargeRecord: {
component: MemberRechargeRecordRender, // 渲染组件
searchUrl: API_URL_MEMBER_RECHARGE_RECORDS,
searchField: 'unionQueryParam',
searchPlaceholder: '搜索订单号、手机号、会员名称'
},
// 会员账户流水
memberAccountHistory: {
component: MemberAccountHistoryRender, // 渲染组件
searchUrl: API_URL_MEMBER_ACCOUNT_HISTORY,
searchField: 'unionQueryParam',
searchPlaceholder: '搜索充值单号、手机号、会员名称'
}
};
onLoad(option => {
vdata.pageOptions = option;
vdata.pageType = option.type;
vdata.pageObject = pageTypeMap[option.type];
// 特殊处理
if (vdata.pageType == 'payPassage') {
vdata.searchData.appId = option.appId;
}
// 特殊处理
if (vdata.pageType == 'device') {
vdata.searchData.deviceType = option.deviceType;
}
// 特殊处理
if (vdata.pageType == 'sysUser') { // 不查询普通用户。
vdata.searchData.isNotHasType2 = 1;
}
});
// 监听 更新事件
onUnload(() => uni.$off(emit.ENAME_REF_SEARCH_PAGE));
uni.$on(emit.ENAME_REF_SEARCH_PAGE, function(data) {
searchFunc();
});
const vdata = reactive({
pageOptions: {}, // 页面参数
pageType: '', // 页面类型
pageObject: {}, // 页面对象
searchVal: '', // 搜索值
searchData: {} ,// 搜索内容
});
// 请求
function reqTableDataFunc(params) {
return reqLoad.list(vdata.pageObject.searchUrl, params);
}
// 点击搜索事件
async function searchFunc(val) {
if(!vdata.searchVal.trim()) return;
vdata.searchData[vdata.pageObject.searchField] = vdata.searchVal;
tableRef.value.refTable(true); // 刷新列表页
}
const focus = () => {
vdata.isSearch = false
}
</script>
<style lang="scss" scoped>
.input-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 30rpx;
padding-top: 22rpx;
height: 110rpx;
background-color: $J-bg-ff;
.input-main {
flex: 1;
display: flex;
align-items: center;
height: 70rpx;
image {
padding: 22rpx;
width: 26rpx;
height: 26rpx;
}
input {
flex: 1;
font-size: 27rpx;
}
::v-deep uni-button {
font-size: 32rpx;
color: rgba(29,121,253,1);
background: rgba(255,255,255,1);
}
::v-deep.uni-easyinput {
.uni-easyinput__content {
background-color: $J-bg-f5 !important;
border-radius: $J-b-r12;
.uni-easyinput__content-input {
padding-left: 0 !important;
.uni-input-input {
border-radius: $J-b-r12 !important;
overflow: hidden !important;
}
}
.uni-input-placeholder {
font-size: 27rpx;
}
.uni-icons {
color: rgba(230,230,230,1) !important;
}
}
}
}
}
.input-icon{
position: relative;
z-index: 10;
}
.search-button{
position: absolute;
right: 0;
background-color: transparent !important;
color: transparent !important;
}
</style>

View File

@@ -1,158 +0,0 @@
<!--
环境变量切换组件
@author terrfly
@site https://www.jeequan.com
@date 2022/04/12 10:14
-->
<template>
<view>
<!-- 当包含环境变量 && 不是生产环境时 -->
<view
class="login-test"
v-if="
vdata.currentEnvEnum &&
vdata.currentEnvEnum != appConfig.ENV_ENUM.PRODUCTION
"
><text>{{ vdata.currentEnvEnum }}</text></view
>
<!-- 切换环境提示 -->
<uni-popup ref="uniPopupRef" :mask-click="false" :open="true">
<view class="uni-popup-dialog">
<image
@tap="uniClose"
class="uni-dialog-close"
src="/static/indexImg/del.svg"
mode="scaleToFill"
/>
<view class="uni-dialog-button-box">
<view
class="uni-dialog-button"
style="border-bottom: 2rpx solid #e1e1e1"
@click="changeEnvFunc(appConfig.ENV_ENUM.DEVELOPMENT)"
><text>开发环境</text></view
>
<view
class="uni-dialog-button"
style="border-bottom: 2rpx solid #e1e1e1"
@click="changeEnvFunc(appConfig.ENV_ENUM.TEST)"
><text>测试环境</text></view
>
<view
class="uni-dialog-button"
style="border-bottom: 2rpx solid #e1e1e1"
@click="changeEnvFunc(appConfig.ENV_ENUM.DEMO)"
><text>演示环境</text></view
>
<view
class="uni-dialog-button"
@click="changeEnvFunc(appConfig.ENV_ENUM.PRODUCTION)"
><text>生产环境</text></view
>
</view>
</view>
</uni-popup>
</view>
</template>
<script setup>
import { reactive, ref, onMounted } from 'vue'
import appConfig from '@/config/appConfig.js'
import envConfig from '@/env/config.js'
import storageManage from '@/commons/utils/storageManage.js'
import { $getSiteInfos } from '@/http/apiManager.js';
const uniPopupRef = ref()
// emit
const emit = defineEmits(['change'])
const vdata = reactive({
currentEnvEnum: '', // 当前环境变量
count: 0, // 当前点击次数
})
onMounted(() => {
vdata.currentEnvEnum = storageManage.env()
})
// 父组件的点击事件
function tapFunc() {
vdata.count++
if (vdata.count >= 10) {
vdata.count = 0
uniPopupRef.value.open()
}
}
// 改变环境函数
function changeEnvFunc(envMode) {
vdata.currentEnvEnum = envMode //显示信息
envConfig.changeEnv(envMode) //更改请求包
storageManage.env(envMode) // 改变存储
// 更改公司信息
$getSiteInfos().then( ( { bizData } ) => {
storageManage.siteInfos(bizData)
// 调起外层页面
emit("change")
})
uniPopupRef.value.close() //弹层关闭
}
// 关闭弹窗
function uniClose() {
uniPopupRef.value.close()
}
defineExpose({ tapFunc })
</script>
<style lang="scss" scoped>
.uni-popup-dialog {
position: relative;
box-sizing: border-box;
width: 500rpx;
height: 600rpx;
overflow: hidden;
border-radius: 30rpx;
background-color: #ffffff;
display: flex;
flex-direction: column;
justify-content: space-around;
.uni-dialog-close {
position: absolute;
top: 20rpx;
right: 20rpx;
width: 50rpx;
height: 50rpx;
}
.uni-dialog-button-box {
width: 100%;
box-sizing: border-box;
display: flex;
justify-content: space-around;
flex-direction: column;
text-align: center;
padding: 0 40rpx;
.uni-dialog-button {
width: 100%;
height: 150rpx;
line-height: 150rpx;
text {
font-size: 40rpx;
}
}
}
}
.login-test {
position: absolute;
bottom: 70rpx;
width: 100%;
text-align: center;
text {
color: #666f80;
}
}
</style>

View File

@@ -1,169 +0,0 @@
<template>
<view class="forget-password">
<view v-if="vdata.isRetrieve" class="tips">
<text>我们已将短信验证码发送至您的手机</text>
<text style="margin-top: 30rpx; font-size: 46rpx; font-weight: 500; color: rgba(0,0,0,1);">{{ vdata.userInfo.telphone }}</text>
</view>
<view v-else class="tips">
<text>您正在尝试找回密码</text>
<text>请在下方输入注册手机号并填写短信验证码</text>
</view>
<view class="jeepay-form">
<uni-forms ref="formRef" label-width="0" :model="vdata.formData" :rules="rules">
<uni-forms-item v-if="vdata.isRetrieve !== '1'" name="phone">
<uni-easyinput class='jeepay-easyinput' v-model="vdata.formData.phone" type="number" :maxlength="11" :disabled="!vdata.allowSendMsgFlag" placeholder="请输入手机号" :clearable="false">
<template #prefixIcon><image src="@/static/login/icon-phone.svg" class="input-icon" /></template>
<template #suffixIcon> <view class='show-tips' style="color: rgba(88,132,204,1);font-weight: 400;font-size: 32rpx;" @tap="sendSmscodeFunc">{{ vdata.sendMsgText }}</view> </template>
</uni-easyinput>
</uni-forms-item>
<uni-forms-item>
<!-- 手机验证码 不限制数字还是本文 如果发送为文本则无需app升级 -->
<view style="display: flex;">
<uni-easyinput class='jeepay-easyinput' :maxlength="6" placeholder="请输入验证码" v-model="vdata.formData.vercode" :clearable="false">
<template #prefixIcon><image src="@/static/login/icon-sms-code.svg" class="input-icon" /></template>
</uni-easyinput>
<image :src="vdata.formData.imgCodeUrl" style="width: 200rpx; height: 110rpx;margin-left: 10rpx;" @click="getCode" mode=""></image>
</view>
</uni-forms-item>
<uni-forms-item name="code">
<!-- 手机验证码 不限制数字还是本文 如果发送为文本则无需app升级 -->
<uni-easyinput class='jeepay-easyinput' :maxlength="6" placeholder="请输入手机验证码" v-model="vdata.formData.code" :clearable="false">
<template #prefixIcon><image src="@/static/login/icon-sms-code.svg" class="input-icon" /></template>
</uni-easyinput>
</uni-forms-item>
<view v-if="vdata.isRetrieve" style="font-size: 29rpx; text-align: center; color: rgba(128,128,128,1);" @tap="sendSmscodeFunc">{{ vdata.sendMsgText }}</view>
<Button @tap="nextRetrieve">下一步</Button>
</uni-forms>
</view>
</view>
</template>
<script setup>
import { ref, reactive, getCurrentInstance } from 'vue';
import { onLoad } from '@dcloudio/uni-app'
import { $sendSms, $retrieve,$isCode } from '@/http/apiManager.js';
import storageManage from '@/commons/utils/storageManage.js'
import infoBox from '@/commons/utils/infoBox.js';
import go from '@/commons/utils/go.js'
import timer from '@/commons/utils/timer.js'
import formUtil from '@/commons/utils/formUtil.js'
const rules = {
phone: {
rules:[ formUtil.rules.requiredInputShowToast('手机号') ],
},
code: {
rules:[ formUtil.rules.requiredInputShowToast('短信验证码') ],
},
}
const formRef = ref()
const vdata = reactive({
formData: {
phone: '', // 手机号
code: '' // 短信验证码
},
sendMsgText : '发送验证码',
allowSendMsgFlag : true, // 是否可发送短信验证码
isRetrieve: '' ,// 是否在设置中找回密码跳转
userInfo: storageManage.userInfo()
})
// const instance = getCurrentInstance()
// console.log('instance', instance)
onLoad((options) => {
Object.assign(vdata, options)
console.log(vdata)
if (vdata.isRetrieve) {
vdata.formData.phone = vdata.userInfo.telphone
sendSmscodeFunc()
}
})
const getCode=()=>{
$isCode().then(res=>
{
console.log(res);
vdata.formData.imgCodeUrl=res.bizData.imageBase64Data
vdata.formData.vercodeToken=res.bizData.vercodeToken
})
}
getCode()
// 验证验证码是否正确进行下一步
const nextRetrieve = () => {
let phone = vdata.formData.phone;
if(phone && !formUtil.regexp.mobile.test(phone)){
return infoBox.showToast("请输入正确的手机号")
}
formUtil.validate(formRef.value).then(() => {
$retrieve(vdata.formData).then(() => {
go.to('PAGES_SET_NEW_PASSWORD', vdata.formData)
})
})
}
// 点击发送验证码的函数
const sendSmscodeFunc = () => {
// 按钮禁用
if(!vdata.allowSendMsgFlag){
return false ;
}
if(!vdata.formData.vercode){
return infoBox.showToast("请输入图像验证码");
}
// 验证失败
if(!formUtil.regexp.mobile.test(vdata.formData.phone)){
return infoBox.showToast("请输入正确的手机号")
}
vdata.allowSendMsgFlag = false; // 按钮禁用
let data= {
phone:vdata.formData.phone,
vercode:vdata.formData.vercode,
vercodeToken:vdata.formData.vercodeToken,
}
// 发送短信验证码
$sendSms(data, 'retrieve').then(({bizData}) => {
infoBox.showSuccessToast('验证码发送成功')
timer.startTimeoutTask(1, 60, (subTime) => {
if(subTime <= 0){ // 任务结束
vdata.sendMsgText = '发送验证码'
vdata.allowSendMsgFlag = true;
return false;
}
vdata.sendMsgText = `${subTime}s后可重新发送`
})
}).catch(() => {
vdata.allowSendMsgFlag = true
})
}
</script>
<style lang="scss">
.forget-password {
padding: 142rpx 50rpx 0;
.tips {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 56rpx;
font-size: 32rpx;
font-weight: 400;
color: rgba(128,128,128,1);
}
.jeepay-form {
.jeepay-btn {
width: 400rpx;
margin-top: 120rpx;
}
}
}
</style>

View File

@@ -1,13 +1,8 @@
<template>
<view class="login-wrapper">
<!-- 切换环境提示 -->
<EnvChangeTips ref="envChangeTipsRef" @change="vdata.siteInfos = storageManage.siteInfos()" />
<view class="login-top">
<text>欢迎回来请登录</text>
<image @tap="envChangeTipsRef.tapFunc()" style="width: 320rpx; height: 76rpx"
:src="vdata.siteInfos.appTopImgUrl" />
</view>
<view class="login-bottom jeepay-form">
@@ -111,47 +106,20 @@
</uni-forms>
<view class="agreement-policy">
<JeepayCheckbox v-model:checked="vdata.isSelectedAgreement" />
<up-checkbox label="" name="agree" usedAlone v-model:checked="vdata.isSelectedAgreement" />
同意
<text class="agreement" @click="toPrivacy">用户服务协议</text>
<text></text>
<text class="policy" @click="toPrivacy">隐私政策</text>
</view>
<!-- <view class="agreement-policy">
<JeepayCheckbox v-model:checked="vdata.isSelectedAgreement" />
同意
<text class="agreement" @click="go.to('PAGES_STATIC_AGREEMENT')">用户服务协议</text>
<text></text>
<text class="policy" @click="toPrivacy">隐私政策</text>
<text class="policy" @click="go.to('PAGES_STATIC_POLICY')">隐私政策</text>
</view> -->
<Button @tap="loginFunc">登录</Button>
<!-- <view class="register-box">
<view class="register">
<text>还没有账号</text> <text @tap="go.to('PAGES_REGISTER')">去注册></text>
</view>
<view class="forget" @tap="go.to('PAGES_FORGET_PASSWORD')">忘记密码</view>
</view>
<view class="swidth-login" @click="changeLoginType">
{{ vdata.loginType == 'pwd' ? '短信验证码登录' : '账号密码登录' }}
<image src="@/static/login/icon-arrow-left.svg"></image>
</view> -->
<button class="btn" hover-class="hover-button" @tap="loginFunc">登录</button>
</view>
</view>
<JAgree service="PAGES_STATIC_AGREEMENT" privacy="PAGES_FORGET_PASSWORD" ref="refAgr"
@agree="vdata.isSelectedAgreement = true" />
</template>
<script setup>
import {
encrypt
} from '@/commons/utils/rsaEncrypt.js'
import { encrypt } from '@/commons/utils/rsaEncrypt.js'
import {
ref,
reactive,
@@ -159,48 +127,34 @@
watch
} from 'vue';
import {
$loginByPwd,
$phoneCodeLogin,
$userInfo,
$sendSms,
$getSiteInfos,
$getUploadImgSize,
$isCode
$sendSms
} from '@/http/apiManager.js';
import { login, authCaptcha } from '@/api/login.js';
import storageManage from '@/commons/utils/storageManage.js'
import infoBox from '@/commons/utils/infoBox.js';
import go from '@/commons/utils/go.js'
import timer from '@/commons/utils/timer.js'
import formUtil from '@/commons/utils/formUtil.js'
import EnvChangeTips from './components/EnvChangeTips.vue'
import dayjs from 'dayjs' //时间格式库
import {
getExtStoreId
} from "@/commons/utils/versionManage.js"
import {
$login
} from '@/http/newApi/login.js';
import {
login,
getCodeImg
} from '@/http/yskApi/login.js';
const accountType = reactive({
list: [{
label: '商户',
value: 'merchant'
value: 0
},
{
label: '员工',
value: 'staff'
value: 1
},
],
sel: 0
})
const loginFormRef = ref()
const envChangeTipsRef = ref()
const refAgr = ref()
const rules = {
merchantName: {
rules: [formUtil.rules.requiredInputShowToast('商户号')],
@@ -227,7 +181,6 @@
}
const vdata = reactive({
isShowPwd: false, // 是否显示密码
loginType: 'pwd', // 类型切换: pwd or sms
isShowSafetyCode: false, // 是否显示安全码输入框
@@ -235,16 +188,13 @@
sendMsgText: '发送验证码',
isSelectedAgreement: false, // 勾选隐私协议
siteInfos: storageManage.siteInfos() || {},
formData: {
username: '', // 账密登录: 用户名
pwd: '', // 账密登录: 密码
rememberMe: false,
code: '',
uuid: '',
merchantName: '',
loginType: 'merchant'
loginType: 1
},
})
@@ -268,26 +218,15 @@
}
// #endif
}
const getCode = () => {
getCodeImg().then(res => {
vdata.formData.img = res.img
vdata.formData.uuid = res.uuid
})
}
getCode()
watch(() => accountType.sel, (newval) => {
if (newval == 1) {
vdata.formData.merchantName = uni.getStorageSync('merchantName') || ''
} else {
vdata.formData.username = ''
}
})
onMounted(() => {
// getExtStoreId()
// 查询是否包含网站信息, 否则更新
// if(!vdata.siteInfos || Object.keys(vdata.siteInfos) <= 0){
// $getSiteInfos().then( ( { bizData } ) => {
// vdata.siteInfos = storageManage.siteInfos(bizData)
// })
// }
getCode()
// 获取商户信息,有就回显
let info = uni.getStorageSync('MerchantId')
if (info.merchantName) {
@@ -295,12 +234,21 @@
vdata.formData.username = info.username
}
})
// 切换登录方式
function changeLoginType() {
vdata.loginType = vdata.loginType == 'pwd' ? 'sms' : 'pwd';
/**
* 获取验证码
*/
const getCode = () => {
authCaptcha().then(res => {
console.log(res)
vdata.formData.img = res.code
vdata.formData.uuid = res.uuid
})
}
/**
* 登录
*/
function loginFunc() {
// 表单验证
@@ -311,17 +259,20 @@
}
let loginPromise = null;
if (vdata.loginType == 'pwd') { // 用户名密码登录
// loginPromise = $loginByPwd(vdata.formData.username, vdata.formData.pwd, vdata.formData.safetyCode)
loginPromise = login({
let params = {
username: vdata.formData.username,
password: encrypt(vdata.formData.pwd),
rememberMe: false,
password: vdata.formData.pwd,
// password: encrypt(vdata.formData.pwd),
code: vdata.formData.code,
uuid: vdata.formData.uuid,
merchantName: vdata.formData.merchantName,
loginType: accountType.list[accountType.sel].value
})
}
//商户号参数
if ( accountType.sel == 1 ) {
params.merchantName = vdata.formData.merchantName
}
loginPromise = login(params)
} else if (vdata.loginType == 'sms') { // 短信验证码登录
loginPromise = $phoneCodeLogin(vdata.formData.loginPhone, vdata.formData.smsCode)
}
@@ -333,6 +284,7 @@
// 请求后的操作
loginPromise.then(res => {
console.log(res)
// 登录成功
loginFinishFunc(res)
// 保存商户号
@@ -362,28 +314,23 @@
})
// #endif
}
watch(() => accountType.sel, (newval) => {
if (newval == 1) {
vdata.formData.merchantName = uni.getStorageSync('merchantName') || ''
} else {
vdata.formData.username = ''
}
})
// 封装登录成功后的操作
/**
* 封装登录成功后的操作
* @param {Object} loginBizData
*/
async function loginFinishFunc(loginBizData) {
// 保存 token
storageManage.setLogin(loginBizData)
storageManage.token(loginBizData.token)
storageManage.shopId(loginBizData.shopId)
storageManage.shopUserId(loginBizData.user.user.id)
storageManage.userInfo(loginBizData)
var time1 = new Date();
var time2 = new Date(loginBizData.expireDate);
let les = (time1.getTime() - time2.getTime()) / 86400000;
uni.showToast({
title: '店铺账号有限期至' + loginBizData.expireDate + ',店铺账号到期剩余' + Math.abs(les.toFixed(0)) + '天!',
icon: 'none'
});
storageManage.token(loginBizData.tokenInfo)
// var time1 = new Date();
// var time2 = new Date(loginBizData.expireDate);
// let les = (time1.getTime() - time2.getTime()) / 86400000;
// uni.showToast({
// title: '店铺账号有限期至' + loginBizData.expireDate + ',店铺账号到期剩余' + Math.abs(les.toFixed(0)) + '天!',
// icon: 'none'
// });
setTimeout(() => {
// 跳转到首页
@@ -394,7 +341,9 @@
}
// 点击发送验证码的函数
/**
* 点击发送验证码的函数
*/
function sendSmscodeFunc() {
// 按钮禁用
if (!vdata.allowSendMsgFlag) {
@@ -455,18 +404,12 @@
background: url("/static/indexImg/user-bg.svg") center center no-repeat;
background-size: cover;
text:first-child {
text{
margin-bottom: 30rpx;
font-size: 38rpx;
font-weight: 500;
color: rgba(0, 0, 0, 0.8);
}
text:last-child {
font-size: 50rpx;
font-weight: 600;
color: #48C0FF;
}
}
.login-bottom {
@@ -542,5 +485,20 @@
}
}
}
.btn {
display: flex;
justify-content: center;
align-items: center;
height: 110rpx;
font-size: 33rpx;
font-weight: 500;
color: $J-color-tff;
border-radius: 20rpx;
background: $jeepay-bg-primary;
box-shadow: 0 20rpx 60rpx -20rpx rgba(0,84,210,0.5);
&.hover-button {
opacity: 0.5;
}
}
}
</style>

View File

@@ -1,317 +0,0 @@
<template>
<view class="login-wrapper">
<view class="login-top">
<text>欢迎注册</text>
<image style="width: 320rpx; height: 76rpx" :src="vdata.siteInfos.appTopImgUrl" />
</view>
<view class="login-bottom jeepay-form">
<uni-forms ref="formRef" label-width="0" :model="vdata.formData" :rules="rules">
<!-- <uni-forms-item name="mchName">
<uni-easyinput class="jeepay-easyinput" placeholder="请输入商户名称" v-model="vdata.formData.mchName" :clearable="false">
<template #prefixIcon><image src="@/static/login/icon-merchantuser.svg" class="input-icon" /></template>
</uni-easyinput>
</uni-forms-item> -->
<uni-forms-item name="phone">
<uni-easyinput
class="jeepay-easyinput"
v-model="vdata.formData.phone"
type="number"
:maxlength="11"
:disabled="!vdata.allowSendMsgFlag"
placeholder="请输入手机号"
:clearable="false"
>
<template #prefixIcon><image src="@/static/login/icon-phone.svg" class="input-icon" /></template>
</uni-easyinput>
</uni-forms-item>
<uni-forms-item>
<!-- 手机验证码 不限制数字还是本文 如果发送为文本则无需app升级 -->
<view style="display: flex">
<uni-easyinput class="jeepay-easyinput" :maxlength="6" placeholder="请输入验证码" v-model="vdata.formData.vercode" :clearable="false">
<template #prefixIcon><image src="@/static/login/icon-sms-code.svg" class="input-icon" /></template>
</uni-easyinput>
<image :src="vdata.formData.imgCodeUrl" style="width: 200rpx; height: 110rpx; margin-left: 10rpx" @click="getCode" mode=""></image>
</view>
</uni-forms-item>
<uni-forms-item name="code">
<!-- 手机验证码 不限制数字还是本文 如果发送为文本则无需app升级 -->
<uni-easyinput class="jeepay-easyinput" :maxlength="6" placeholder="请输入手机验证码" v-model="vdata.formData.code" :clearable="false">
<template #prefixIcon><image src="@/static/login/icon-sms-code.svg" class="input-icon" /></template>
<template #suffixIcon>
<view style="color: rgba(88, 132, 204, 1); font-weight: 400; font-size: 32rpx" @tap="sendSmscodeFunc">{{ vdata.sendMsgText }}</view>
</template>
</uni-easyinput>
</uni-forms-item>
<uni-forms-item name="pwd">
<uni-easyinput
class="jeepay-easyinput"
:type="vdata.isShowPwd ? 'text' : 'password'"
v-model="vdata.formData.pwd"
:clearable="false"
placeholder="请输入登录密码"
>
<template #prefixIcon><image src="@/static/login/icon-pw.svg" class="input-icon" /></template>
<template #suffixIcon>
<view class="show-tips" style="color: rgba(88, 132, 204, 1); font-weight: 400; font-size: 32rpx" @tap="vdata.isShowPwd = !vdata.isShowPwd">
<!-- {{ vdata.isShowPwd ? '隐藏' : '显示' }} -->
<uni-icons type="eye" size="24" v-if="vdata.isShowPwd"></uni-icons>
<uni-icons type="eye-slash" size="24" v-else></uni-icons>
</view>
</template>
</uni-easyinput>
</uni-forms-item>
<uni-forms-item name="confirmPwd">
<uni-easyinput
class="jeepay-easyinput"
:type="vdata.isShowConfirmPwd ? 'text' : 'password'"
placeholder="请确认登录密码"
v-model="vdata.formData.confirmPwd"
:clearable="false"
:passwordIcon="false"
>
<template #prefixIcon><image src="@/static/login/icon-confirm-pw.svg" class="input-icon" /></template>
<template #suffixIcon>
<view
class="show-tips"
style="color: rgba(88, 132, 204, 1); font-weight: 400; font-size: 32rpx"
@tap="vdata.isShowConfirmPwd = !vdata.isShowConfirmPwd"
>
<!-- {{ vdata.isShowConfirmPwd ? '隐藏' : '显示' }} -->
<uni-icons type="eye" size="24" v-if="vdata.isShowConfirmPwd"></uni-icons>
<uni-icons type="eye-slash" size="24" v-else></uni-icons>
</view>
</template>
</uni-easyinput>
</uni-forms-item>
<uni-forms-item>
<uni-easyinput class="jeepay-easyinput" placeholder="请输入邀请码(选填)" v-model="vdata.formData.inviteCode" :clearable="false">
<template #prefixIcon><image src="@/static/login/icon-invite-code.svg" class="input-icon" /></template>
</uni-easyinput>
</uni-forms-item>
</uni-forms>
<view class="agreement-policy">
<view class="select-box">
<JeepayCheckbox v-model:checked="vdata.isSelectedAgreement" />
同意商户通
</view>
<text class="agreement" @click="go.to('PAGES_STATIC_AGREEMENT')">用户服务协议</text>
<text></text>
<text class="policy" @click="go.to('PAGES_STATIC_POLICY')">隐私政策</text>
</view>
<Button @tap="mchRegister">注册</Button>
<view class="register-box">
<view class="register">
<text>已有账号</text>
<text @tap="go.back()">去登录></text>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue';
import { $mchRegister, $sendSms, $getPasswordRules, $isCode } from '@/http/apiManager.js';
import storageManage from '@/commons/utils/storageManage.js';
import infoBox from '@/commons/utils/infoBox.js';
import go from '@/commons/utils/go.js';
import timer from '@/commons/utils/timer.js';
import formUtil from '@/commons/utils/formUtil.js';
const rules = {
mchName: {
rules: [formUtil.rules.requiredInputShowToast('用户名称')]
},
pwd: {
rules: [formUtil.rules.requiredInputShowToast('登录密码')]
},
confirmPwd: {
rules: [formUtil.rules.requiredInputShowToast('确认密码')]
},
inviteCode: {
rules: [formUtil.rules.requiredInputShowToast('邀请码')]
},
phone: {
rules: [formUtil.rules.requiredInputShowToast('手机号')]
},
code: {
rules: [formUtil.rules.requiredInputShowToast('短信验证码')]
}
};
const formRef = ref();
const vdata = reactive({
formData: {
mchName: '', // 用户名称
pwd: '', // 登录密码
confirmPwd: '', // 确认密码
inviteCode: '', // 邀请码
phone: '', // 手机号
code: '', // 短信验证码
imgCodeUrl: ''
},
siteInfos: storageManage.siteInfos() || {},
isSelectedAgreement: false, //是否勾选同意协议
sendMsgText: '发送验证码',
allowSendMsgFlag: true, // 是否可发送短信验证码
passwordRules: /^$/, //密码规则
passwordRulesText: '' //密码规则提示文字
});
const getCode = () => {
$isCode().then((res) => {
console.log(res);
vdata.formData.imgCodeUrl = res.bizData.imageBase64Data;
vdata.formData.vercodeToken = res.bizData.vercodeToken;
});
};
getCode();
onMounted(() => {
getPasswordRules();
});
const getPasswordRules = () => {
$getPasswordRules().then(({ bizData }) => {
vdata.passwordRules = new RegExp(bizData.regexpRules);
vdata.passwordRulesText = bizData.errTips;
});
};
const mchRegister = () => {
if (!vdata.isSelectedAgreement) {
return infoBox.showToast('请勾选用户隐私政策');
}
// 表单验证
formUtil.validate(formRef.value).then(() => {
let { pwd, confirmPwd } = vdata.formData;
if (!vdata.passwordRules.test(pwd) || !vdata.passwordRules.test(confirmPwd)) {
return infoBox.showToast(vdata.passwordRulesText);
}
if (pwd !== confirmPwd) {
return infoBox.showToast('两次密码输入不一致');
}
vdata.formData.mchName = vdata.formData.phone
$mchRegister(vdata.formData).then(() => {
infoBox.showToast('注册成功').then(() => {
go.back();
});
});
});
};
// 点击发送验证码的函数
function sendSmscodeFunc() {
// 按钮禁用
if (!vdata.allowSendMsgFlag) {
return false;
}
if (!vdata.formData.vercode) {
return infoBox.showToast('请输入图像验证码');
}
// 验证失败
if (!formUtil.regexp.mobile.test(vdata.formData.phone)) {
return infoBox.showToast('请输入正确的手机号');
}
vdata.allowSendMsgFlag = false; // 按钮禁用
let data = {
phone: vdata.formData.phone,
vercode: vdata.formData.vercode,
vercodeToken: vdata.formData.vercodeToken
};
// 发送短信验证码
$sendSms(data, 'register')
.then(({ bizData }) => {
infoBox.showSuccessToast('验证码发送成功');
timer.startTimeoutTask(1, 60, (subTime) => {
if (subTime <= 0) {
// 任务结束
vdata.sendMsgText = '发送验证码';
vdata.allowSendMsgFlag = true;
return false;
}
vdata.sendMsgText = `${subTime}s后可重新发送`;
});
})
.catch(() => {
vdata.allowSendMsgFlag = true;
});
}
</script>
<style lang="scss">
.login-wrapper {
min-height: 100vh;
background-color: $v-color-bgrey;
.login-top {
display: flex;
flex-direction: column;
height: 376rpx;
padding: 176rpx 70rpx 0;
box-sizing: border-box;
background: url('/static/indexImg/user-bg.svg') no-repeat;
background-size: cover;
text:first-child {
margin-bottom: 30rpx;
font-size: 38rpx;
font-weight: 500;
color: rgba(0, 0, 0, 0.8);
}
text:last-child {
font-size: 50rpx;
font-weight: 600;
color: #48c0ff;
}
}
.login-bottom {
height: calc(100vh - 376rpx);
padding: 50rpx;
box-sizing: border-box;
border-radius: 60rpx 60rpx 0 0;
background-color: #fff;
.agreement-policy {
display: flex;
align-items: center;
padding: 0 30rpx;
margin-top: 10rpx;
margin-bottom: 50rpx;
font-size: 26rpx;
color: #8c8c8c;
.select-box {
display: flex;
align-items: center;
.select-img {
width: 46rpx;
height: 46rpx;
}
}
.agreement,
.policy {
color: #1d79fd;
}
}
.register-box {
display: flex;
justify-content: space-between;
padding: 0 30rpx;
padding-bottom: 100rpx;
margin-top: 50rpx;
font-size: 26rpx;
font-weight: 400;
.register {
text:last-child {
color: #1d79fd;
}
}
.forget {
color: #1d79fd;
}
}
}
}
</style>

View File

@@ -1,119 +0,0 @@
<template>
<view class="new-password">
<uni-forms ref="formRef" label-align="left" :model="vdata.formData" :rules="rules">
<uni-forms-item label="新密码" name="pwd">
<uni-easyinput class='jeepay-easyinput' :inputBorder="false" :type="vdata.isShowPwd ? 'text' : 'password'" v-model="vdata.formData.pwd" :clearable="false" placeholder="请输入登录密码" >
<template #suffixIcon> <view class='show-tips' style="color: rgba(88,132,204,1);font-weight: 400;font-size: 32rpx;" @tap="vdata.isShowPwd = !vdata.isShowPwd ">{{ vdata.isShowPwd ? '隐藏' : '显示' }}</view> </template>
</uni-easyinput>
</uni-forms-item>
<uni-forms-item label="确认新密码" name="newPwd">
<uni-easyinput class='jeepay-easyinput' :inputBorder="false" :type="vdata.isShowNewPwd ? 'text' : 'password'" v-model="vdata.formData.newPwd" :clearable="false" placeholder="请输入登录密码" >
<template #suffixIcon> <view class='show-tips' style="color: rgba(88,132,204,1);font-weight: 400;font-size: 32rpx;" @tap="vdata.isShowNewPwd = !vdata.isShowNewPwd ">{{ vdata.isShowNewPwd ? '隐藏' : '显示' }}</view> </template>
</uni-easyinput>
</uni-forms-item>
</uni-forms>
<view class="btn-box">
<Button @tap="confirmRetrieve">确认修改</Button>
</view>
</view>
</template>
<script setup>
import { ref, reactive } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import { $retrieve, $getPasswordRules } from '@/http/apiManager.js';
import storageManage from '@/commons/utils/storageManage.js'
import infoBox from '@/commons/utils/infoBox.js';
import go from '@/commons/utils/go.js'
import timer from '@/commons/utils/timer.js'
import formUtil from '@/commons/utils/formUtil.js'
const rules = {
pwd: {
rules:[ formUtil.rules.requiredInputShowToast('新密码') ],
},
newPwd: {
rules:[ formUtil.rules.requiredInputShowToast('确认密码') ],
},
}
const formRef = ref()
const vdata = reactive({
formData: {
pwd: '', // 新密码
newPwd: '' // 确认新密码
},
isShowPwd: false, // 是否显示新密码
isShowNewPwd: false, // 是否显示确认新密码
params: null,
passwordRules: /^$/, //密码规则
passwordRulesText: '',//密码规则提示文字
})
onLoad(options => {
vdata.params = options
getPasswordRules()
});
const getPasswordRules = () => {
$getPasswordRules().then(({bizData}) => {
vdata.passwordRules = new RegExp(bizData.regexpRules)
vdata.passwordRulesText = bizData.errTips
})
}
const confirmRetrieve = () => {
formUtil.validate(formRef.value).then(() => {
let { pwd, newPwd } = vdata.formData;
if(!vdata.passwordRules.test(pwd) || !vdata.passwordRules.test(newPwd)) {
return infoBox.showToast(vdata.passwordRulesText)
}
if (pwd !== newPwd) {
return infoBox.showToast('两次密码输入不一致')
}
$retrieve({
...vdata.params,
newPwd
}).then(() => {
storageManage.token() && storageManage.token(null, true)
infoBox.showToast('设置成功').then(() => {
go.to('PAGES_LOGIN', {}, go.GO_TYPE_RELAUNCH)
})
})
})
}
</script>
<style lang="scss">
.new-password {
min-height: 100vh;
background-color: $v-color-bgrey;
::v-deep.uni-forms-item.is-direction-left {
padding: 0 40rpx;
.uni-forms-item__label {
width: 190rpx !important;
font-size: 32rpx !important;
font-weight: 400;
white-space: nowrap;
color: rgba(102,102,102,1);
text-indent: 0 !important;
}
.uni-easyinput__placeholder-class {
font-size: 32rpx !important;
font-weight: 400 !important;
}
}
.btn-box {
position: fixed;
left: 0;
right: 0;
bottom: 0;
height: 200rpx;
border: 1rpx solid rgba(237,237,237,1);
background: rgba(255,255,255,0.85);
.jeepay-btn {
margin: 30rpx;
}
}
}
</style>

View File

@@ -1,106 +0,0 @@
<template>
<view class="page-wrapper">
<view class="info-wrapper">
<block v-for="(v, i) in vdata.mchInfoList" :key="i">
<view class="info-main">
<view class="info-title">{{ v.title }}</view>
<view class="info-text">
<view v-if="v.clsName" class="flex-center" :class="[v.clsName]">{{ v.text }}</view>
<text v-else>{{ v.text }}</text>
</view>
<view class="info-copy" v-if="v.copy" @tap="copyInfo(v.text)">复制</view>
</view>
</block>
<view class="info-button flex-center" @tap="allCopyInfo"> 全部复制 </view>
</view>
</view>
</template>
<script setup>
import { reactive, ref } from "vue"
import { onLoad } from '@dcloudio/uni-app'
import { $getMchInfo } from "@/http/apiManager.js"
import infoBox from '@/commons/utils/infoBox.js'
const vdata = reactive({
mchInfoList: [ ]
})
onLoad((options) => {
$getMchInfo().then(({bizData}) => {
let mchTye = bizData.type == 1 ? '普通用户': '特约用户'
vdata.mchInfoList.push({ title: "用户名称", text: bizData.mchName, copy: true })
vdata.mchInfoList.push({ title: "用户简称", text: bizData.mchShortName, copy: true })
vdata.mchInfoList.push({ title: "用户号", text: bizData.mchNo, copy: true })
// vdata.mchInfoList.push({ title: "用户类型", text: mchTye, clsName: "info-tag", copy: false })
if(bizData.isvNo){
vdata.mchInfoList.push({ title: "服务商号", text: bizData.isvNo, copy: true })
}
vdata.mchInfoList.push({ title: "注册时间", text: bizData.createdAt, copy: false })
})
})
const copyInfo = (val) => {
uni.setClipboardData({ data: val}).then(() => {
infoBox.showSuccessToast('复制成功')
})
}
// 全部复制 格式化数据
const allCopyInfo = () => {
const infoStr = []
vdata.mchInfoList.forEach((v) => {
infoStr.push(v.title + "" + v.text)
})
copyInfo(infoStr.join("\n"))
}
</script>
<style lang="scss" scoped>
.page-wrapper {
min-height: 100vh;
background-color: $v-color-bgrey;
.info-wrapper {
padding-top: 20rpx;
background-color: $J-bg-ff;
.info-main {
display: flex;
align-items: center;
padding: 0 40rpx;
height: 120rpx;
.info-title {
width: 198rpx;
font-size: 32rpx;
color: $J-color-t4d;
}
.info-text {
flex: 1;
font-size: 32rpx;
}
.info-copy {
font-size: 32rpx;
color: #5884cc;
}
.info-tag {
width: 122rpx;
height: 42rpx;
font-size: 23rpx;
color: #fff;
border-radius: 6rpx;
background: linear-gradient(270deg, rgba(255, 162, 22, 1) 0%, rgba(241, 112, 18, 1) 100%);
}
}
.info-button {
height: 110rpx;
border-top: 1rpx solid #ededed;
border-bottom: 1rpx solid #ededed;
font-size: 32rpx;
color: #5884cc;
}
}
}
</style>

View File

@@ -1,139 +0,0 @@
<template>
<view class="content">
<view class="mbr-info">
<image :src="vdata.record.avatarUrl" />
<text class="mbr-info-name">{{ vdata.record.mbrName }}</text>
<text class="mbr-info-amount">{{ vdata.record.changeAmount > 0 ? '+'+cal.cert2Dollar(vdata.record.changeAmount) : cal.cert2Dollar(vdata.record.changeAmount) }}</text>
</view>
<view class="account-line"></view>
<view class="account-history">
<view class="account-history-item"><text>业务类型</text>
<text>{{ vdata.record.bizType==1?'支付充值':vdata.record.bizType==2?'现金充值':vdata.record.bizType==3?'会员消费':vdata.record.bizType==4?'消费退款':vdata.record.bizType==5?'人工调账':'其他' }}</text>
</view>
<view class="account-history-item"><text>流水ID</text><text>{{ vdata.record.hid }}</text></view>
<view class="account-history-item"><text>会员ID</text><text>{{ vdata.record.mbrId }}</text></view>
<view class="account-history-item"><text>会员手机号</text><text>{{ vdata.record.mbrTel }}</text></view>
<view class="account-history-item"><text>变动前余额</text><text>{{ cal.cert2Dollar(vdata.record.beforeAmount) }}</text></view>
<view class="account-history-item"><text>变动金额</text><text>{{ cal.cert2Dollar(vdata.record.changeAmount) }}</text></view>
<view class="account-history-item"><text>变动后余额</text><text>{{ cal.cert2Dollar(vdata.record.afterAmount) }}</text></view>
<view v-if="vdata.record.relaBizOrderId && vdata.record.bizType == 1" class="account-history-item">
<text>充值订单号</text>
<text>{{ vdata.record.relaBizOrderId }}
<text class="info-copy" @tap="copyInfo(vdata.record.relaBizOrderId)">复制</text>
</text>
</view>
<view class="account-history-item"><text>变动时间</text><text>{{ vdata.record.createdAt }}</text></view>
</view>
</view>
</template>
<script setup>
import { reactive, ref } from 'vue'
import { onLoad, onUnload } from '@dcloudio/uni-app'
import { reqLoad, API_URL_MEMBER_ACCOUNT_HISTORY } from '@/http/apiManager.js'
import infoBox from '@/commons/utils/infoBox.js';
import cal from '@/commons/utils/cal.js'
import go from '@/commons/utils/go.js'
import emit from '@/commons/utils/emit.js'
import ent from '@/commons/utils/ent.js'
onLoad((options) => {
refData(options.hid)
})
const vdata = reactive({
record : { }
})
// 监听 更新事件
onUnload(() => uni.$off(emit.ENAME_REF_MEMBER_ACCOUNT_HISTORY_DETAIL))
uni.$on(emit.ENAME_REF_MEMBER_ACCOUNT_HISTORY_DETAIL, function(data){
refData(vdata.record.hid)
})
function refData(hid){
reqLoad.getById(API_URL_MEMBER_ACCOUNT_HISTORY, hid).then(({bizData}) => {
vdata.record = bizData
})
}
const copyInfo = (val) => {
uni.setClipboardData({ data: val}).then(() => {
infoBox.showSuccessToast('复制成功')
})
}
</script>
<style lang="scss" scoped>
.content {
width: 630rpx;
margin: 0 auto;
}
.mbr-info {
height: 376rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
image {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
}
.mbr-info-name {
padding-top: 10rpx;
color: #828282ff;
font-size: 30rpx;
}
.mbr-info-amount {
padding-top: 10rpx;
color: #000000ff;
font-size: 50rpx;
font-weight: 500;
}
}
.account-line {
border-bottom: 1rpx solid #0000001a;
}
.account-history {
padding-top: 60rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
.account-history-item {
display: flex;
flex-direction: row;
justify-content: flex-start;
opacity: 1;
padding: 13rpx 0 12rpx;
text:first-child {
width: 180rpx;
color: #999999;
font-size: 26rpx;
font-weight: 400;
}
text:nth-child(2) {
width: 450rpx;
color: #000000;
font-size: 26rpx;
font-weight: 400;
word-break: break-all;
.info-copy {
padding-left: 20rpx;
opacity: 1;
color: #2d6dccff;
font-size: 26rpx;
}
}
}
}
</style>

View File

@@ -1,116 +0,0 @@
<template>
<view class="page-wrapper">
<JeepayCustomNavbar title="账户流水" backCtrl="back" />
<!-- 搜索 -->
<JSearchTitle place="搜索" @click="go.toSearchPage('memberAccountHistory')">
<template #right>
<JeepaySearchSelect v-model:bizType="vdata.searchData.bizType" :list="vdata.bizTypeList" title="按业务类型筛选" @change="refTable"/>
</template>
</JSearchTitle>
<JeepayTableList ref="jeepayTableListRef" :searchData="vdata.searchData" :reqTableDataFunc="reqTableDataFunc">
<template #tableBody="{ record }">
<MemberAccountHistoryRender :record="record" />
</template>
</JeepayTableList>
</view>
</template>
<script setup>
import { nextTick, reactive, ref } from "vue"
import { onReachBottom, onShow, onUnload } from '@dcloudio/uni-app'
import go from '@/commons/utils/go.js'
import emit from '@/commons/utils/emit.js'
import { reqLoad, API_URL_MEMBER_ACCOUNT_HISTORY } from "@/http/apiManager.js"
import MemberAccountHistoryRender from '@/pages/list/render/MemberAccountHistoryRender.vue'
const jeepayTableListRef = ref()
const vdata = reactive({
searchData: { bizType: '' },
bizTypeList: [
{ label: '全部业务类型', value: '' },
{ label: '支付充值', value: '1' },
{ label: '现金充值', value: '2' },
{ label: '会员消费', value: '3' },
{ label: '消费退款', value: '4' },
{ label: '人工调账', value: '5' },
]
})
onReachBottom(() => { })
// // 监听 更新事件
onUnload(() => uni.$off(emit.ENAME_REF_MEMBER_ACCOUNT_HISTORY_LIST))
uni.$on(emit.ENAME_REF_MEMBER_ACCOUNT_HISTORY_LIST, function(data){
jeepayTableListRef.value.refTable(true)
})
function refTable (e) {
jeepayTableListRef.value.refTable(true)
}
// 请求
function reqTableDataFunc (params) {
return reqLoad.list(API_URL_MEMBER_ACCOUNT_HISTORY, params)
}
</script>
<style lang="scss" scoped>
.sta-input {
display: flex;
align-items: center;
padding: 0 30rpx;
height: 110rpx;
background-color: $J-bg-ff;
.input-main {
flex: 1;
display: flex;
align-items: center;
height: 70rpx;
background-color: $J-bg-f5;
border-radius: $J-b-r12;
color: rgba(0, 0, 0, 0.35);
font-size: 27rpx;
font-weight: 400;
image {
padding: 22rpx;
width: 26rpx;
height: 26rpx;
}
}
.icon-more {
margin-left: 30rpx;
width: 70rpx;
height: 70rpx;
}
}
.footer-wrapper {
height: 170rpx;
background-color: transparent;
.footer-button {
position: fixed;
left: 0;
right: 0;
bottom: 0;
padding: 30rpx;
button {
height: 110rpx;
font-size: 33rpx;
font-weight: 500;
color: $J-color-tff;
border-radius: 20rpx;
background: $jeepay-bg-primary;
}
.hover-button {
opacity: 0.5;
}
}
}
</style>

View File

@@ -1,490 +0,0 @@
<template>
<JeepayBackground :bgColorStyle="{ background: '#f7f7f7' }">
<JeepayCustomNavbar title="会员中心" backCtrl="back" textColor="#fff"
bgDefaultColor="linear-gradient(270deg, rgb(35, 143, 252) 0%, rgb(26, 102, 255) 100%)" />
<view class="header-info">
<view class="member-info">
<view class="info-main">
<text class="num">{{ vdata.mbrTotalCount }}</text>
<text class="sub-title">会员总数</text>
</view>
<view class="info-main">
<view class="num">{{ cal.cert2Dollar(vdata.mbrTotalBalance) }}<text class="unit"></text></view>
<text class="sub-title">会员总余额</text>
</view>
</view>
<view class="nav-list-wrapper">
<block v-for="(v, i) in navList" :key="i">
<view class="nav-item" @tap="toPage(v.pageUrl)">
<image :src="v.icon"></image>
<text>{{ v.title }}</text>
</view>
</block>
</view>
</view>
<view class="stat-card">
<view class="time-wrapper">
<block v-for="(v, i) in timeList" :key="i">
<view class="time-item" @tap="changeTime(v.value)"
:class="{ 'time-selected': v.value == vdata.selected }">{{
v.label }}</view>
</block>
</view>
<view v-show="vdata.selected == 'custom'">
<view class="time-selection time-custom">
<image src="/static/iconImg/custom-time-icon.svg" mode="scaleToFill" />
<view class="selection-main" @tap="startTimeRef.show()">{{ vdata.startTime || '请选择开始时间' }} </view>
<view>---</view>
<view class="selection-main" @tap="endTimeRef.show()">{{ vdata.endTime || '请选择结束时间' }}</view>
<image src="/static/iconImg/icon-nav-left.svg" style="transform: rotate(-90deg);" mode="scaleToFill" />
</view>
</view>
<view class="member-consume">
<text class="num">{{ cal.cert2Dollar(Math.abs(vdata.mbrCount.changeAmount)) }}</text>
<text class="sub-title">会员消费金额 ()</text>
</view>
<view class="stat-card-info">
<view class="stat-item">
<view class="stat-num">{{ cal.cert2Dollar(vdata.rechargeRecordCount.entryAmount) }}</view>
<view class="stat-title">充值入账 ()</view>
</view>
<view class="stat-item">
<view class="stat-num">{{ cal.cert2Dollar(vdata.rechargeRecordCount.giveAmount) }}</view>
<view class="stat-title">充值赠送 ()</view>
</view>
<view class="stat-item">
<view class="stat-num">{{ cal.cert2Dollar(vdata.rechargeRecordCount.payAmount) }}</view>
<view class="stat-title">充值支付 ()</view>
</view>
<view class="stat-item">
<view class="stat-num">{{ cal.cert2Dollar(Math.abs(vdata.accountHistoryCount.changeAmount)) }}</view>
<view class="stat-title">余额变动 ()</view>
</view>
<view class="stat-item">
<view class="stat-num">{{ vdata.accountHistoryCount.countNum }}</view>
<view class="stat-title">余额变动条数</view>
</view>
<view class="stat-item">
<view class="stat-num">{{ vdata.mbrCount.changeCount }}</view>
<view class="stat-title">会员消费笔数</view>
</view>
</view>
</view>
<view class="switch-wrapper">
<block v-for="v in vdata.memberConfig" :key="v.configKey">
<view class="switch-item" v-if="v.configKey != 'memberModelState'">
<text class="switch-text">{{ v.phoneTips.title }}</text>
<JeepayStateSwitch v-if="v.configKey != 'mbrMaxBalance'" :confirmTitle="v.phoneTips.tips"
:state="v.configVal" showSwitchType @update:state="changeState($event, v)" />
<text class="max-amount" v-else>{{ !v.phoneTips.maxAmount ? '不限制充值余额' : cal.cert2Dollar(v.phoneTips?.maxAmount) }}</text>
</view>
</block>
</view>
</JeepayBackground>
<view v-show="vdata.selected == 'custom'">
<xp-picker ref="startTimeRef" mode="ymd" @confirm="customTime($event, 'startTime')" />
<xp-picker ref="endTimeRef" mode="ymd" @confirm="customTime($event, 'endTime')" />
</view>
</template>
<script setup>
import { reactive, ref, onMounted, nextTick } from 'vue'
import { req, API_URL_MEMBERS, API_URL_MEMBER_RECHARGE_RECORDS, API_URL_MEMBER_ACCOUNT_HISTORY, $findOrEditMemberConfig } from '@/http/apiManager.js'
import go from '@/commons/utils/go.js'
import cal from '@/commons/utils/cal.js'
import dayjs from 'dayjs'
import infoBox from '@/commons/utils/infoBox.js'
import { onPullDownRefresh, onShow } from '@dcloudio/uni-app'
const startTimeRef = ref()
const endTimeRef = ref()
const vdata = reactive({
mbrTotalCount: '', // 会员总数,不随时间条件变化
mbrTotalBalance: '', // 会员总余额,不随时间条件变化
mbrCount: {}, // 会员统计
accountHistoryCount: {}, // 流水统计
rechargeRecordCount: {}, // 充值统计
selected: 'today',
startTime: '',
endTime: '',
memberConfig: [] //会员配置项
})
const toPage = (url) => {
go.to(url)
}
onShow(() => {
vdata.selected = 'today'
getMbrCount()
getMbrStats(vdata.selected)
})
// 导航列表
const navList = [
{
title: '会员管理',
icon: '/static/indexImg/icon-member.svg',
pageUrl: 'PAGES_MEMBER',
entId: 'ENT_MCH_MEMBER'
},
{
title: '充值规则',
icon: '/static/member/recharge-rule.svg',
pageUrl: 'PAGES_RECHARGE_RULE',
entId: 'ENT_MEMBER_RECHARGE_RULE'
},
{
title: '账户流水',
icon: '/static/member/account-history.svg',
pageUrl: 'PAGES_MEMBER_ACCOUNT_HISTORY',
entId: 'ENT_MEMBER_ACCOUNT_HISTORY'
},
{
title: '充值记录',
icon: '/static/member/recharge-record.svg',
pageUrl: 'PAGES_MEMBER_RECHARGE_RECORD',
entId: 'ENT_MEMBER_RECHARGE_RECORD'
},
]
const timeList = [
{ label: '今天', value: 'today' },
{ label: '昨天', value: 'yesterday' },
{ label: '近30天', value: 'near2now_30' },
{ label: '自定义', value: 'custom' }
]
// 下拉刷新
onPullDownRefresh(() => {
getMbrCount()
changeTime(vdata.selected)
})
function getMbrCount () {
// 请求会员统计,不随时间变化
req.list(API_URL_MEMBERS + '/count', undefined).then(({ bizData }) => {
uni.stopPullDownRefresh()
vdata.mbrTotalCount = bizData.memberNum
vdata.mbrTotalBalance = bizData.balance
}).catch((err) => uni.stopPullDownRefresh())
}
function getMbrStats (queryDate) {
const reqParams = {}
if (queryDate) {
reqParams.queryDateRange = queryDate
}
// 请求会员统计
req.list(API_URL_MEMBERS + '/count', reqParams).then(({ bizData }) => {
vdata.mbrCount = bizData
})
// 请求记录统计
req.list(API_URL_MEMBER_RECHARGE_RECORDS + '/count', Object.assign({ state: 2 }, reqParams)).then(({ bizData }) => {
vdata.rechargeRecordCount = bizData
})
// 请求会员流水统计
req.list(API_URL_MEMBER_ACCOUNT_HISTORY + '/count', reqParams).then(({ bizData }) => {
vdata.accountHistoryCount = bizData
})
}
// 切换日期选项,当选自定义时,赋予默认时间
function changeTime (e) {
if (e != 'custom') {
vdata.selected = e
getMbrStats(e)
} else {
if (vdata.selected == 'today') {
vdata.startTime = dayjs().format('YYYY-MM-DD')
vdata.endTime = dayjs().format('YYYY-MM-DD')
} else if (vdata.selected == 'yesterday') {
vdata.startTime = dayjs().subtract(1, 'day').format('YYYY-MM-DD')
vdata.endTime = dayjs().subtract(1, 'day').format('YYYY-MM-DD')
} else if (vdata.selected == 'near2now_30') {
vdata.startTime = dayjs().subtract(30, 'day').format('YYYY-MM-DD')
vdata.endTime = dayjs().format('YYYY-MM-DD')
}
vdata.selected = e
}
}
function customTime ({ value }, type) {
if ((type == 'startTime' && dayjs(value).isAfter(dayjs(vdata.endTime)))
|| (type == 'endTime' && (dayjs(vdata.startTime).isAfter(dayjs(value)) || dayjs(value).isAfter(dayjs())))) {
return infoBox.showToast('时间选择有误')
}
vdata[type] = value
const queryDateRange = `customDateTime_
${dayjs(vdata.startTime).startOf('date').format('YYYY-MM-DD HH:mm:ss')}_
${dayjs(vdata.endTime).endOf('date').format('YYYY-MM-DD HH:mm:ss')}`
getMbrStats(queryDateRange)
}
//移动端自定义提示语
const mebConfig = {
memberCustomAmountState: {
title: '是否开启自定义金额充值',
tips: '是否修改自定义充值金额状态',
weight: 1
},
memberPayState: {
title: '是否开启会员支付',
tips: '是否修改会员支付状态',
weight: 0
},
mbrMaxBalance: {
title: '会员最大储值余额(单位元)',
tips: '是否修改会员支付状态',
weight: 2,
maxAmount: ''
}
}
// 获取会员支付配置项
const findOrEditMemberConfig = (data, mode, uri) => {
$findOrEditMemberConfig(data, mode, uri).then(({ bizData }) => {
if (mode) return infoBox.showToast('修改成功')
//不需要会员模块
const index = bizData.findIndex(v => v.configKey == 'memberModelState')
if (index != '-1') {
bizData.splice(index, 1)
}
bizData.forEach(v => {
v.phoneTips = mebConfig[v.configKey] || {}
})
bizData.sort((a, b) => a.phoneTips.weight - b.phoneTips.weight)
Object.assign(vdata.memberConfig, bizData)
findMemberMaxAmount()
})
}
findOrEditMemberConfig({ groupKey: 'memberConfig' })
function changeState (e, v) {
v.configVal = e
findOrEditMemberConfig({ configData: vdata.memberConfig }, 'PUT', '/memberConfig')
}
//查询 会员最大储值金额
function findMemberMaxAmount () {
$findOrEditMemberConfig(undefined, undefined, '/mbrMaxBalance').then(({ bizData }) => {
vdata.memberConfig.find(v => v.configKey == 'mbrMaxBalance').phoneTips.maxAmount = bizData
})
}
</script>
<style lang="scss" scoped>
.time-item {
display: flex;
justify-content: center;
align-items: center;
}
.header-info {
height: 290rpx;
background: linear-gradient(270deg, rgb(35, 143, 252) 0%, rgb(26, 102, 255) 100%);
border: 1rpx solid transparent;
border-radius: 0 0 32rpx 32rpx;
.member-info {
display: flex;
justify-content: center;
margin-top: 50rpx;
.info-main {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 335rpx;
height: 106rpx;
.num {
margin-bottom: 10rpx;
color: #ffffff;
font-size: 50rpx;
font-weight: 500;
.unit {
margin-left: 10rpx;
font-size: 22rpx;
}
}
.sub-title {
color: rgba(255, 255, 255, 0.6);
font-size: 23rpx;
}
}
view:nth-child(1) {
border-right: 1rpx solid rgba(255, 255, 255, 0.1);
}
}
.nav-list-wrapper {
display: flex;
justify-content: space-between;
margin: 50rpx auto 40rpx;
width: 680rpx;
height: 170rpx;
border-radius: 32rpx;
background-color: #fff;
view {
width: 170rpx;
height: 170rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
image {
margin-bottom: 10rpx;
width: 70rpx;
height: 70rpx;
}
text {
color: rgba(63, 63, 63, 1);
font-size: 22rpx;
}
}
}
}
.stat-card {
margin: 40rpx auto;
margin-top: 120rpx;
width: 680rpx;
min-height: 656rpx;
border-radius: 32rpx;
background-color: #fff;
border: .1rpx solid transparent;
.time-wrapper {
display: flex;
justify-content: space-between;
margin: 30rpx auto;
width: 620rpx;
height: 100rpx;
border-radius: 20rpx;
background: linear-gradient(270deg, rgba(35, 143, 252, 0.1) 0%, rgba(26, 102, 255, 0.1) 100%);
.time-item {
width: 153.5rpx;
height: 100rpx;
border-radius: 20rpx;
color: rgb(89, 134, 179);
}
.time-selected {
background: linear-gradient(270deg, rgb(35, 143, 252) 0%, rgb(26, 102, 255) 100%);
color: #fff;
}
}
}
.time-selection {
height: 100rpx;
white-space: nowrap;
image {
width: 40rpx;
height: 40rpx;
}
.selection-main {
height: auto;
margin: 0 10rpx 0 20rpx;
font-size: 30rpx;
color: rgb(0, 0, 0);
}
}
.time-custom {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 60rpx;
}
.member-consume {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding-bottom: 50rpx;
box-shadow: 0 50rpx 70rpx -60rpx rgba(107, 130, 153, 0.2);
.num {
margin-top: 50rpx;
color: rgb(41, 128, 253);
font-size: 60rpx;
font-weight: 600;
}
.sub-title {
margin-top: 10rpx;
color: rgb(166, 166, 166);
font-size: 24rpx;
}
}
.stat-card-info {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
padding: 25rpx;
.stat-item {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin: 25rpx 0;
width: 210rpx;
height: 82rpx;
.stat-num {
margin-bottom: 10rpx;
color: rgb(0, 0, 0);
font-size: 30rpx;
font-weight: 600;
}
.stat-title {
color: rgb(166, 166, 166);
font-size: 24rpx;
}
}
}
.switch-wrapper {
margin: 40rpx auto 0;
width: 680rpx;
height: 330rpx;
border-radius: 32rpx;
background: #ffffffff;
.switch-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 10rpx 0 30rpx;
height: 110rpx;
}
.switch-item:nth-child(2) {
border-bottom: 1rpx solid rgba(0, 0, 0, 0.06);
border-top: 1rpx solid rgba(0, 0, 0, 0.06);
}
}
.max-amount {
margin-right: 15rpx;
}
</style>

View File

@@ -1,108 +0,0 @@
<template>
<uni-popup ref="popup" type="center" mask-background-color="rgba(0,0,0,.5)">
<view class="psw-wrapper">
<view class="psw-top">
<view class="close-wrapper">
<view class="psw-close" @tap="close">
<image src="/static/iconImg/icon-x.svg"></image>
</view>
</view>
<view class="psw-title">请输入支付密码</view>
<view class="sub-tips">会员调账</view>
<view class="amount">{{ vdata.amount }}</view>
</view>
<view class="psw-input">
<JPasswordInput ref="refPswInput" margin="0 20px" @inputChange="inputChange" />
</view>
</view>
</uni-popup>
</template>
<script setup>
import { ref, reactive, onMounted } from "vue"
import infoBox from '@/commons/utils/infoBox.js';
import { $memberManual } from "@/http/apiManager"
import emit from '@/commons/utils/emit.js'
import go from '@/commons/utils/go.js'
import { Base64 } from "js-base64";
const refPswInput = ref(null)
const popup = ref(null)
const vdata = reactive({})
const open = (val) => {
val.addOrRedUce
vdata.amount = val.addOrRedUce == 'add' ? '+' + val.num : '-' + val.num
vdata.memberId = val.mbrId
popup.value.open()
}
const close = () => popup.value.close()
const inputChange = (e) => {
if (e.length >= 6) return manual(e)
}
const manual = (pswd) => {
$memberManual({ memberId: vdata.memberId, changeAmount: vdata.amount, currentPassword: Base64.encode(pswd) }).then(res => {
infoBox.showToast('调账成功').then(r => {
close()
emit.pageEmit(emit.ENAME_REF_MEMBER_LIST) // 更新列表
go.back(1, emit.ENAME_REF_MEMBER_DETAIL) // 返回详情 && 更新详情
})
}).catch(err => {
refPswInput.value.clearInput()
})
}
defineExpose({ open })
</script>
<style lang="scss" scoped>
.psw-wrapper {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 650rpx;
height: 496rpx;
border-radius: 32rpx;
background-color: #fff;
.psw-title {
text-align: center;
color: #000000ff;
font-size: 30rpx;
font-weight: 500;
}
.close-wrapper {
.psw-close {
display: flex;
align-items: center;
justify-content: center;
width: 106rpx;
height: 106rpx;
image {
width: 80rpx;
height: 80rpx;
}
}
}
.psw-input {
margin-bottom: 50rpx;
width: 650rpx;
}
.sub-tips {
margin: 30rpx 0 20rpx 0;
color: #808080ff;
font-size: 30rpx;
text-align: center;
}
.amount {
text-align: center;
color: #000000ff;
font-size: 50rpx;
font-weight: 500;
}
}
</style>

View File

@@ -1,180 +0,0 @@
<template>
<JeepayBackground :bgColorStyle="{}">
<JeepayCustomNavbar textColor="#fff"
bgDefaultColor="linear-gradient(270deg, rgba(72, 192, 255, 1) 0%, rgba(51, 157, 255, 1) 100%)" title="会员详情"
backCtrl="back" />
<JeepayTableListItem viewClass="list-item-by-detail" :logo="vdata.record.avatarUrl" :title="vdata.record.mbrName"
:subtitle="vdata.record.mbrTel" :moreBtnList="list" :logoStyle="{ borderRadius: '50%' }" />
<!-- 账户金额 -->
<JeepayCard :viewStyle="{ marginTop: '50rpx' }">
<view class="pay-wrapper">
<view>
<JeepayDescviewItem title="账户余额 (元)" />
<view class="pay-amount">{{ (vdata.record.balance / 100).toFixed(2) }}</view>
</view>
<view class="pay-shift" @tap="toManual">调账
<image src="/static/member/member-arrow.svg"></image>
</view>
</view>
</JeepayCard>
<JeepayCard viewStyle="margin-top: 50rpx" editText="编辑信息"
@editTap="go.to('PAGES_MEMBER_EDIT', { mbrId: vdata.record.mbrId })">
<JeepayDescview>
<JeepayDescviewItem title="会员编号" :desc="vdata.record.mbrId" />
<JeepayDescviewItem title="会员备注" :desc="vdata.record.remark ? vdata.record.remark : '-'" />
<JeepayDescviewItem title="创建时间" :desc="vdata.record.createdAt" />
</JeepayDescview>
</JeepayCard>
<JeepayCard viewStyle="margin-top: 40rpx">
<JeepayTableListItem v-if="ent.has('ENT_MEMBER_EDIT')" title="会员状态" subtitle="状态禁用后,该会员将无法使用">
<template #titleRight>
<JeepayStateSwitch v-model:state="vdata.record.state" :showSwitchType="true"
:updateStateFunc="updateStateFunc" />
</template>
</JeepayTableListItem>
</JeepayCard>
<JSinglePopup ref="single" :list="list" activeColor="#FF5B4C" />
<JeepayPopupConfirm ref="jeepayPopupConfirmRef" />
</JeepayBackground>
</template>
<script setup>
import { reactive, ref } from 'vue'
import { onLoad, onUnload } from '@dcloudio/uni-app'
import { reqLoad, API_URL_MEMBERS } from '@/http/apiManager.js'
import infoBox from '@/commons/utils/infoBox.js';
import go from '@/commons/utils/go.js'
import emit from '@/commons/utils/emit.js'
import ent from '@/commons/utils/ent.js'
const single = ref()
const jeepayPopupConfirmRef = ref()
const list = reactive([
{ label: '调账', value: 'delete', fun: toManual },
])
onLoad((options) => {
refData(options.mbrId)
})
const vdata = reactive({
record: {}
})
// 监听 更新事件
onUnload(() => uni.$off(emit.ENAME_REF_MEMBER_DETAIL))
uni.$on(emit.ENAME_REF_MEMBER_DETAIL, function (data) {
refData(vdata.record.mbrId)
})
function refData (mbrId) {
reqLoad.getById(API_URL_MEMBERS, mbrId).then(({ bizData }) => {
vdata.record = bizData
})
}
function updateStateFunc (state) {
return reqLoad.updateById(API_URL_MEMBERS, vdata.record.mbrId, { state: state }).then(() => {
emit.pageEmit(emit.ENAME_REF_MEMBER_LIST)
infoBox.showSuccessToast("修改成功");
})
}
function toManual () {
go.to('PAGES_MEMBER_RECHARGE_MEMBERMANUAL', { mbrId: vdata.record.mbrId })
}
function deleteFunc () {
return reqLoad.delById(API_URL_MEMBERS, vdata.record.mbrId).then(() => {
infoBox.showSuccessToast("删除成功");
go.back(1, emit.ENAME_REF_MEMBER_LIST) // 返回页面 && 更新
})
}
</script>
<style lang="scss" scoped>
.sex-info-text {
image {
width: 30rpx;
height: 30rpx;
margin-right: 10rpx;
}
}
.sta-info {
display: flex;
margin-top: 50rpx;
padding: 0 50rpx;
.sta-photo {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
image {
width: 100%;
height: 100%;
}
}
.info-main {
flex: 1;
margin-left: 30rpx;
color: #fff;
.info-name {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 33rpx;
font-weight: 400;
image {
width: 70rpx;
height: 70rpx;
}
}
.info-phone {
margin-top: 16rpx;
color: rgba(251, 252, 253, 0.7);
font-size: 25rpx;
font-weight: 400;
}
}
}
.pay-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
.pay-amount {
margin: 40rpx;
color: #000000ff;
font-size: 50rpx;
font-weight: 500;
}
.pay-shift {
display: flex;
align-items: center;
color: #2980fdff;
font-size: 33rpx;
image {
margin-right: 40rpx;
width: 44rpx;
height: 44rpx;
}
}
}
</style>

View File

@@ -1,129 +0,0 @@
<template>
<JeepayBackground>
<view class="page-wrapper jeepay-edit-form">
<JeepayCustomNavbar :title="vdata.mbrId ? '修改会员信息' : '创建会员' " backCtrl="back" />
<uni-forms ref="formRef" :rules="rules" :model="vdata.formData" :label-width="140">
<uni-forms-item required label="会员名称" name="mbrName">
<uni-easyinput v-model="vdata.formData.mbrName" placeholder="请输入会员名称" :inputBorder="false"></uni-easyinput>
</uni-forms-item>
<uni-forms-item required label="手机号" name="mbrTel">
<text v-if="vdata.mbrId">{{ vdata.formData.mbrTel }}</text>
<uni-easyinput v-else v-model="vdata.formData.mbrTel" placeholder="请输入手机号" :inputBorder="false"></uni-easyinput>
</uni-forms-item>
<JeepayTableListItem v-if="vdata.mbrId" title="状态" subtitle="状态禁用后,会员将无法支付">
<template #titleRight>
<JeepayStateSwitch v-model:state="vdata.formData.state" :showSwitchType="true" :confirm='false' />
</template>
</JeepayTableListItem>
<uni-forms-item required label="备注" name="remark">
<uni-easyinput v-model="vdata.formData.remark" placeholder="请输入备注" :inputBorder="false"></uni-easyinput>
</uni-forms-item>
</uni-forms>
<view class="confirm-wrapper">
<view class="confirm-button flex-center" hover-class="touch-button" @tap="confirmFunc"> {{ vdata.mbrId ? '确认修改' : '确认创建' }}</view>
</view>
</view>
</JeepayBackground>
</template>
<script setup>
import { reactive, ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { reqLoad, API_URL_MEMBERS } from '@/http/apiManager.js'
import infoBox from '@/commons/utils/infoBox.js';
import go from '@/commons/utils/go.js'
import formUtil from '@/commons/utils/formUtil.js'
import emit from '@/commons/utils/emit.js'
const formRef = ref()
onLoad((options) => {
// 修改页面
if(options.mbrId){
vdata.mbrId = options.mbrId
reqLoad.getById(API_URL_MEMBERS, vdata.mbrId).then(({bizData}) => {
vdata.formData = bizData
})
}
})
const rules = {
mbrName: {
rules:[ formUtil.rules.requiredInput() ],
},
mbrTel: {
rules:[ formUtil.rules.requiredInput(), formUtil.rules.patternRule('联系人电话', formUtil.regexp.mobile) ],
},
}
const vdata = reactive({
mbrId: null, // 新建 or 修改
// 表单数据
formData: {
state: 1
}
})
function confirmFunc(){
formUtil.validate(formRef.value).then(() => {
return reqLoad.addOrUpdate(vdata.mbrId, API_URL_MEMBERS, vdata.formData)
})
.then(( {bizData} ) => {
emit.pageEmit(emit.ENAME_REF_MEMBER_LIST) // 更新列表
go.back(1, emit.ENAME_REF_MEMBER_DETAIL) // 返回详情 && 更新详情
})
}
</script>
<style lang="scss" scoped>
input {
font-size: 32rpx;
}
.f-label {
width: 240rpx;
}
.selected-sex {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-top: 45rpx;
margin-bottom: 10rpx;
font-size: 32rpx;
color: #b3b3b3;
image {
width: 120rpx;
height: 120rpx;
margin-top: -40rpx;
}
.selected-box {
color: #000;
}
}
.confirm-wrapper {
padding: 50rpx 30rpx;
.confirm-button {
height: 110rpx;
color: #fff;
border-radius: 20rpx;
background: $jeepay-bg-primary;
}
}
</style>

View File

@@ -1,116 +0,0 @@
<template>
<view class="page-wrapper">
<JeepayCustomNavbar title="会员管理" backCtrl="back" />
<view class="sta-input" @tap="go.toSearchPage('member')">
<view class="input-main">
<image src="/static/iconImg/icon-search.svg" mode="scaleToFill" />
搜索会员名称手机号
</view>
<!-- <image class="icon-more" src="/static/iconImg/icon-more.svg" mode="scaleToFill" /> -->
</view>
<JeepayTableList ref="jeepayTableListRef" :reqTableDataFunc="reqTableDataFunc">
<template #tableBody="{ record }">
<MemberRender :record="record" />
</template>
</JeepayTableList>
<view class="footer-wrapper">
<view class="footer-button footer-button-style">
<button hover-class="hover-button" hover-stay-time="150" class="flex-center" @tap="createMember">创建会员</button>
</view>
</view>
</view>
<JeepayPopupConfirm ref="jeepayPopupConfirmRef" />
</template>
<script setup>
import { nextTick, reactive, ref } from "vue"
import { onReachBottom, onShow, onUnload } from '@dcloudio/uni-app'
import go from '@/commons/utils/go.js'
import emit from '@/commons/utils/emit.js'
import { reqLoad, API_URL_MEMBERS } from "@/http/apiManager.js"
import MemberRender from '@/pages/list/render/MemberRender.vue'
const jeepayTableListRef = ref()
const jeepayPopupConfirmRef = ref()
onReachBottom(() => { })
// // 监听 更新事件
onUnload(() => uni.$off(emit.ENAME_REF_MEMBER_LIST))
uni.$on(emit.ENAME_REF_MEMBER_LIST, function(data){
jeepayTableListRef.value.refTable(true)
})
// 请求
function reqTableDataFunc (params) {
return reqLoad.list(API_URL_MEMBERS, params)
}
// 创建会员
const createMember = () => {
go.to("PAGES_MEMBER_EDIT")
}
</script>
<style lang="scss" scoped>
.sta-input {
display: flex;
align-items: center;
padding: 0 30rpx;
height: 110rpx;
background-color: $J-bg-ff;
.input-main {
flex: 1;
display: flex;
align-items: center;
height: 70rpx;
background-color: $J-bg-f5;
border-radius: $J-b-r12;
color: rgba(0, 0, 0, 0.35);
font-size: 27rpx;
font-weight: 400;
image {
padding: 22rpx;
width: 26rpx;
height: 26rpx;
}
}
.icon-more {
margin-left: 30rpx;
width: 70rpx;
height: 70rpx;
}
}
.footer-wrapper {
height: 170rpx;
background-color: transparent;
.footer-button {
position: fixed;
left: 0;
right: 0;
bottom: 0;
padding: 30rpx;
button {
height: 110rpx;
font-size: 33rpx;
font-weight: 500;
color: $J-color-tff;
border-radius: 20rpx;
background: $jeepay-bg-primary;
}
.hover-button {
opacity: 0.5;
}
}
}
</style>

View File

@@ -1,195 +0,0 @@
<template>
<view class="page-wrapper">
<view class="member-header">
<view class="left">
<view class="top-title">会员当前余额 ()</view>
<view class="member-amount">{{ (vdata.balance / 100).toFixed(2) }}</view>
</view>
<image :src="vdata.avatarUrl" class="member-photo"></image>
</view>
<view class="m-wrapper" @tap="openAddOrRed">
<view class="left">
<view class="sub-title">调账方式</view>
<view class="m-type">{{ vdata.addOrRedUce == 'add' ? '加款' : '减款' }} </view>
</view>
<view class="right">
<image src="/static/iconImg/icon-arrow-right.svg" class="member-photo"></image>
</view>
</view>
<view class="m-wrapper m-amout">
<view class="left">
<view class="sub-title">调账金额</view>
<input class="m-input" type="digit" v-model="vdata.num" placeholder="请输入调账金额" @input="inputChange">
</view>
<view class="right">
</view>
</view>
<view class="ba-wrapper">
<view class="sub-title">调账后金额</view>
<view class="m-balance">{{ (vdata.manualAmount / 100).toFixed(2) }}</view>
</view>
<view class="but-wrapper">
<Button @tap="openManual">确认调账</Button>
</view>
</view>
<ConfirmManual ref="refManual" />
<JSinglePopup :list="list" ref="refSingle" />
</template>
<script setup>
import { ref, reactive } from "vue"
import { onLoad } from '@dcloudio/uni-app'
import ConfirmManual from "./conponents/ConfirmManual.vue"
import { $memberManual, reqLoad, API_URL_MEMBERS } from "@/http/apiManager"
import infoBox from '@/commons/utils/infoBox.js';
onLoad((options) => {
getMemberInfos(options.mbrId)
})
const vdata = reactive({})
const refSingle = ref(null)
const refManual = ref(null)
const list = [
{
label: '加款', value: 'add', fun: () => {
vdata.addOrRedUce = 'add'
if (vdata.num) return vdata.manualAmount = (vdata.balance * 1 + vdata.num * 100)// 隐式转换后 在进行加法运算
}
},
{
label: '减款', value: 'reduce', fun: () => {
vdata.addOrRedUce = 'reduce'
if (vdata.num) return vdata.manualAmount = (vdata.balance - vdata.num * 100)
}
},
]
const styles = {
backgroundColor: 'transparent',
color: '#000',
fontSize: '32rpx',
}
function getMemberInfos (mbrId) {
reqLoad.getById(API_URL_MEMBERS, mbrId).then(({ bizData }) => {
Object.assign(vdata, bizData)
vdata.manualAmount = bizData.balance
vdata.addOrRedUce = 'add' //赋值初始值 加款
})
}
const openAddOrRed = () => {
refSingle.value.open()
}
const inputChange = (e) => {
if (vdata.addOrRedUce == 'add') {
vdata.manualAmount = (vdata.balance * 1 + vdata.num * 100)// 隐式转换后 在进行加法运算
return
}
return vdata.manualAmount = (vdata.balance - vdata.num * 100)
}
const REG_AMOUNT = /^([0-9]{1}|^[1-9]{1}\d{1,15})(\.\d{1,2})?$/
const openManual = () => {
if (vdata.num <= 0) return infoBox.showToast('调账金额 不能为零')
if (!REG_AMOUNT.test(vdata.num)) return infoBox.showToast('请输入正数金额 保留两位小数')
refManual.value.open(vdata)
}
</script>
<style lang="scss" scoped>
.page-wrapper {
background-color: #fff !important;
min-height: 100vh;
.sub-title {
color: #4c4c4cff;
font-size: 30rpx;
text-align: center;
white-space: nowrap;
}
.member-header {
display: flex;
justify-content: space-between;
margin: 35rpx;
padding-bottom: 50rpx;
border-bottom: 1rpx solid #0000000f;
.top-title {
color: #808080ff;
font-size: 26rpx;
}
.member-amount {
margin-top: 20rpx;
color: #000000ff;
font-size: 50rpx;
font-weight: 500;
}
image {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
}
}
}
.m-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
margin: 0 auto;
width: 680rpx;
height: 120rpx;
border-radius: 32rpx;
opacity: 1;
background: #f7f7f7ff;
.left {
display: flex;
margin-left: 40rpx;
.m-type {
margin-left: 78rpx;
}
}
.right {
image {
width: 108rpx;
height: 120rpx;
}
}
}
.m-amout {
margin-top: 30rpx;
.m-input {
margin-left: 78rpx;
}
.right {
margin-right: 40rpx;
color: #00000080;
font-size: 32rpx;
}
}
.ba-wrapper {
display: flex;
justify-content: space-between;
margin: 50rpx auto;
width: 600rpx;
.m-balance {
color: #000000ff;
font-size: 30rpx;
font-weight: 500;
}
}
.but-wrapper {
margin: 105rpx auto;
width: 400rpx;
}
</style>

View File

@@ -1,147 +0,0 @@
<template>
<view class="content">
<view class="mbr-info">
<image :src="vdata.record.avatarUrl" />
<text class="mbr-info-name">{{ vdata.record.mbrName }}</text>
<text class="mbr-info-amount">{{ '+' + cal.cert2Dollar(vdata.record.entryAmount) }}</text>
</view>
<view class="account-line"></view>
<view class="account-history">
<view class="account-history-item"><text>充值状态</text>
<text class="order-text">{{ datamap.rechargeRecordImage(vdata.record.state).text }}</text>
</view>
<view class="account-history-item">
<text>充值订单号</text>
<text>{{ vdata.record.rechargeRecordId }}
<text class="info-copy" @tap="copyInfo(vdata.record.rechargeRecordId)">复制</text>
</text>
</view>
<view class="account-history-item"><text>会员ID</text><text>{{ vdata.record.mbrId }}</text></view>
<view class="account-history-item"><text>会员手机号</text><text>{{ vdata.record.mbrTel }}</text></view>
<view class="account-history-item"><text>支付金额</text><text>{{ cal.cert2Dollar(vdata.record.payAmount) }}</text></view>
<view class="account-history-item"><text>赠送金额</text><text>{{ cal.cert2Dollar(vdata.record.giveAmount) }}</text></view>
<view class="account-history-item"><text>到账金额</text><text>{{ cal.cert2Dollar(vdata.record.entryAmount) }}</text></view>
<view v-if="vdata.record.payOrderId" class="account-history-item">
<text>支付订单号</text>
<text>{{ vdata.record.payOrderId }}
<text class="info-copy" @tap="copyInfo(vdata.record.payOrderId)">复制</text>
</text>
</view>
<view class="account-history-item"><text>异步通知地址</text><text>{{ vdata.record.notifyUrl }}</text></view>
<view class="account-history-item"><text>创建时间</text><text>{{ vdata.record.createdAt }}</text></view>
<view class="account-history-item"><text>支付成功时间</text><text>{{ vdata.record.successTime }}</text></view>
</view>
</view>
</template>
<script setup>
import { reactive, ref } from 'vue'
import { onLoad, onUnload } from '@dcloudio/uni-app'
import { reqLoad, API_URL_MEMBER_RECHARGE_RECORDS } from '@/http/apiManager.js'
import infoBox from '@/commons/utils/infoBox.js';
import cal from '@/commons/utils/cal.js'
import go from '@/commons/utils/go.js'
import emit from '@/commons/utils/emit.js'
import ent from '@/commons/utils/ent.js'
import datamap from '@/commons/utils/datamap.js'
onLoad((options) => {
refData(options.rechargeRecordId)
})
const vdata = reactive({
record : { }
})
// 监听 更新事件
onUnload(() => uni.$off(emit.ENAME_REF_MEMBER_RECHARGE_RECORD_DETAIL))
uni.$on(emit.ENAME_REF_MEMBER_RECHARGE_RECORD_DETAIL, function(data){
refData(vdata.record.rechargeRecordId)
})
function refData(rechargeRecordId){
reqLoad.getById(API_URL_MEMBER_RECHARGE_RECORDS, rechargeRecordId).then(({bizData}) => {
vdata.record = bizData
})
}
const copyInfo = (val) => {
uni.setClipboardData({ data: val}).then(() => {
infoBox.showSuccessToast('复制成功')
})
}
</script>
<style lang="scss" scoped>
.content {
width: 630rpx;
margin: 0 auto;
}
.mbr-info {
height: 376rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
image {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
}
.mbr-info-name {
padding-top: 10rpx;
color: #828282ff;
font-size: 30rpx;
}
.mbr-info-amount {
padding-top: 10rpx;
color: #000000ff;
font-size: 50rpx;
font-weight: 500;
}
}
.account-line {
border-bottom: 1rpx solid #0000001a;
}
.account-history {
padding-top: 60rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
.account-history-item {
display: flex;
flex-direction: row;
justify-content: flex-start;
opacity: 1;
padding: 13rpx 0 12rpx;
text:first-child {
width: 180rpx;
color: #999999;
font-size: 26rpx;
font-weight: 400;
}
text:nth-child(2) {
width: 450rpx;
word-break: break-all;
color: #000000;
font-size: 26rpx;
font-weight: 400;
.info-copy {
padding-left: 20rpx;
color: #2d6dccff;
font-size: 26rpx;
}
}
}
}
</style>

View File

@@ -1,116 +0,0 @@
<template>
<view class="page-wrapper">
<JeepayCustomNavbar title="红包记录" backCtrl="back" />
<!-- 搜索 -->
<JSearchTitle place="搜索手机号、会员名称" @click="go.toSearchPage('memberRechargeRecord')">
<template #right>
<JeepaySearchSelect v-model:bizType="vdata.searchData.state" :list="vdata.searchParamsList" title="按充值状态筛选" @change="refTable"/>
</template>
</JSearchTitle>
<!-- 数据列表 -->
<JeepayTableList ref="jeepayTableListRef" :searchData="vdata.searchData" :reqTableDataFunc="reqTableDataFunc">
<template #tableBody="{ record }">
<MemberRechargeRecordRender :record="record" />
</template>
</JeepayTableList>
</view>
</template>
<script setup>
import { nextTick, reactive, ref } from "vue"
import { onReachBottom, onShow, onUnload } from '@dcloudio/uni-app'
import go from '@/commons/utils/go.js'
import emit from '@/commons/utils/emit.js'
import { reqLoad, API_URL_MEMBER_RECHARGE_RECORDS } from "@/http/apiManager.js"
import MemberRechargeRecordRender from '@/pages/list/render/MemberRechargeRecordRender.vue'
const jeepayTableListRef = ref()
onReachBottom(() => { })
const vdata = reactive({
searchData: { state: '' },
searchParamsList: [
{ label: '全部充值状态', value: '' },
{ label: '初始化', value: '0' },
{ label: '充值中', value: '1' },
{ label: '充值成功', value: '2' },
{ label: '充值失败', value: '3' }
]
})
// // 监听 更新事件
onUnload(() => uni.$off(emit.ENAME_REF_MEMBER_RECHARGE_RECORD_LIST))
uni.$on(emit.ENAME_REF_MEMBER_RECHARGE_RECORD_LIST, function(data){
jeepayTableListRef.value.refTable(true)
})
function refTable (e) {
jeepayTableListRef.value.refTable(true)
}
// 请求
function reqTableDataFunc (params) {
return reqLoad.list(API_URL_MEMBER_RECHARGE_RECORDS, params)
}
</script>
<style lang="scss" scoped>
.sta-input {
display: flex;
align-items: center;
padding: 0 30rpx;
height: 110rpx;
background-color: $J-bg-ff;
.input-main {
flex: 1;
display: flex;
align-items: center;
height: 70rpx;
background-color: $J-bg-f5;
border-radius: $J-b-r12;
color: rgba(0, 0, 0, 0.35);
font-size: 27rpx;
font-weight: 400;
image {
padding: 22rpx;
width: 26rpx;
height: 26rpx;
}
}
.icon-more {
margin-left: 30rpx;
width: 70rpx;
height: 70rpx;
}
}
.footer-wrapper {
height: 170rpx;
background-color: transparent;
.footer-button {
position: fixed;
left: 0;
right: 0;
bottom: 0;
padding: 30rpx;
button {
height: 110rpx;
font-size: 33rpx;
font-weight: 500;
color: $J-color-tff;
border-radius: 20rpx;
background: $jeepay-bg-primary;
}
.hover-button {
opacity: 0.5;
}
}
}
</style>

View File

@@ -1,139 +0,0 @@
<template>
<JeepayBackground>
<view class="page-wrapper jeepay-edit-form">
<JeepayCustomNavbar :title="vdata.ruleId ? '修改充值规则' : '创建充值规则' " backCtrl="back" />
<uni-forms ref="formRef" :rules="rules" :model="vdata.formData" :label-width="140">
<uni-forms-item required label="充值金额" name="rechargeAmount">
<uni-easyinput type="digit" v-model="vdata.formData.rechargeAmount" placeholder="请输入充值金额" :inputBorder="false"></uni-easyinput>
</uni-forms-item>
<uni-forms-item required label="赠送金额" name="giveAmount">
<uni-easyinput type="digit" v-model="vdata.formData.giveAmount" placeholder="请输入赠送金额" :inputBorder="false"></uni-easyinput>
</uni-forms-item>
<uni-forms-item required label="排序" name="sort">
<uni-easyinput type="number" v-model="vdata.formData.sort" placeholder="请输入排序" :inputBorder="false"></uni-easyinput>
</uni-forms-item>
<JeepayTableListItem v-if="vdata.ruleId" title="状态" subtitle="状态禁用后,规则将无法使用">
<template #titleRight>
<JeepayStateSwitch v-model:state="vdata.formData.state" :showSwitchType="true" :confirm='false' />
</template>
</JeepayTableListItem>
<uni-forms-item required label="备注" name="remark">
<uni-easyinput v-model="vdata.formData.remark" placeholder="请输入备注" :inputBorder="false"></uni-easyinput>
</uni-forms-item>
</uni-forms>
<view class="confirm-wrapper">
<view class="confirm-button flex-center" hover-class="touch-button" @tap="confirmFunc"> {{ vdata.ruleId ? '确认修改' : '确认创建' }}</view>
</view>
</view>
</JeepayBackground>
</template>
<script setup>
import { reactive, ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { reqLoad, API_URL_MEMBER_RECHARGE_RULES } from '@/http/apiManager.js'
import infoBox from '@/commons/utils/infoBox.js';
import go from '@/commons/utils/go.js'
import formUtil from '@/commons/utils/formUtil.js'
import cal from '@/commons/utils/cal.js'
import emit from '@/commons/utils/emit.js'
const formRef = ref()
onLoad((options) => {
// 修改页面
if(options.ruleId){
vdata.ruleId = options.ruleId
reqLoad.getById(API_URL_MEMBER_RECHARGE_RULES, vdata.ruleId).then(({bizData}) => {
vdata.formData = bizData
vdata.formData.rechargeAmount = cal.cert2Dollar(vdata.formData.rechargeAmount)
vdata.formData.giveAmount = cal.cert2Dollar(vdata.formData.giveAmount)
})
}
})
const rules = {
rechargeAmount: {
rules:[ formUtil.rules.requiredInput('充值金额') ]
}
}
const vdata = reactive({
ruleId: null, // 新建 or 修改
// 表单数据
formData: {
state: 1
}
})
function confirmFunc(){
if(vdata.formData.rechargeAmount<=0) return infoBox.showToast('充值金额 不能小于0')
const REG_AMOUNT = /^([0-9]{1}|^[1-9]{1}\d{1,15})(\.\d{1,2})?$/
if (!REG_AMOUNT.test(vdata.formData.rechargeAmount)) {
return infoBox.showToast('请输入正确的充值金额,最多两位小数')
}
if (vdata.formData.giveAmount && !REG_AMOUNT.test(vdata.formData.giveAmount)) {
return infoBox.showToast('请输入正确的赠送金额不能小于0 最多保留两位小数')
}
formUtil.validate(formRef.value).then(() => {
return reqLoad.addOrUpdate(vdata.ruleId, API_URL_MEMBER_RECHARGE_RULES, vdata.formData)
})
.then(( {bizData} ) => {
go.back(1, emit.ENAME_REF_RECHARGE_RULE_LIST) // 返回页面 && 更新
})
}
</script>
<style lang="scss" scoped>
input {
font-size: 32rpx;
}
.f-label {
width: 240rpx;
}
.selected-sex {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-top: 45rpx;
margin-bottom: 10rpx;
font-size: 32rpx;
color: #b3b3b3;
image {
width: 120rpx;
height: 120rpx;
margin-top: -40rpx;
}
.selected-box {
color: #000;
}
}
.confirm-wrapper {
padding: 50rpx 30rpx;
.confirm-button {
height: 110rpx;
color: #fff;
border-radius: 20rpx;
background: $jeepay-bg-primary;
}
}
</style>

View File

@@ -1,108 +0,0 @@
<template>
<view class="page-wrapper">
<JeepayCustomNavbar title="充值规则" backCtrl="back" />
<JeepayTableList ref="jeepayTableListRef" :reqTableDataFunc="reqTableDataFunc">
<template #tableBody="{ record }">
<MemberRechargeRuleRender :record="record" />
</template>
</JeepayTableList>
<view class="footer-wrapper">
<view class="footer-button footer-button-style">
<button hover-class="hover-button" hover-stay-time="150" class="flex-center" @tap="create">创建充值规则</button>
</view>
</view>
</view>
<JeepayPopupConfirm ref="jeepayPopupConfirmRef" />
</template>
<script setup>
import { nextTick, reactive, ref } from "vue"
import { onReachBottom, onShow, onUnload } from '@dcloudio/uni-app'
import go from '@/commons/utils/go.js'
import emit from '@/commons/utils/emit.js'
import { reqLoad, API_URL_MEMBER_RECHARGE_RULES } from "@/http/apiManager.js"
import MemberRechargeRuleRender from '@/pages/list/render/MemberRechargeRuleRender.vue'
const jeepayTableListRef = ref()
const jeepayPopupConfirmRef = ref()
onReachBottom(() => { })
// // 监听 更新事件
onUnload(() => uni.$off(emit.ENAME_REF_RECHARGE_RULE_LIST))
uni.$on(emit.ENAME_REF_RECHARGE_RULE_LIST, function(data){
jeepayTableListRef.value.refTable(true)
})
// 请求
function reqTableDataFunc (params) {
return reqLoad.list(API_URL_MEMBER_RECHARGE_RULES, params)
}
// 创建充值规则
const create = () => {
go.to("PAGES_RECHARGE_RULE_EDIT")
}
</script>
<style lang="scss" scoped>
.sta-input {
display: flex;
align-items: center;
padding: 0 30rpx;
height: 110rpx;
background-color: $J-bg-ff;
.input-main {
flex: 1;
display: flex;
align-items: center;
height: 70rpx;
background-color: $J-bg-f5;
border-radius: $J-b-r12;
color: rgba(0, 0, 0, 0.35);
font-size: 27rpx;
font-weight: 400;
image {
padding: 22rpx;
width: 26rpx;
height: 26rpx;
}
}
.icon-more {
margin-left: 30rpx;
width: 70rpx;
height: 70rpx;
}
}
.footer-wrapper {
height: 170rpx;
background-color: transparent;
.footer-button {
position: fixed;
left: 0;
right: 0;
bottom: 0;
padding: 30rpx;
button {
height: 110rpx;
font-size: 33rpx;
font-weight: 500;
color: $J-color-tff;
border-radius: 20rpx;
background: $jeepay-bg-primary;
}
.hover-button {
opacity: 0.5;
}
}
}
</style>

View File

@@ -1,204 +0,0 @@
<template>
<view class="n-title">第一步</view>
<view class="sub-title">使用微信扫一扫扫描下方二维码并点击确认授权按钮</view>
<view class="image-wrapper">
<view class="image-content" @touchstart="handleStart('authQr')" @touchend="handleEnd">
<image :src="vdata.authQr" mode="scaleToFill" />
</view>
<view class="image-tips">长按可将图片保存至相册</view>
</view>
<view class="n-title">第二步</view>
<view class="sub-title">页面提示授权成功按照手机端的提示关注公众号开启消息推送功能</view>
<view class="image-wrapper footer-image">
<view class="image-content" @touchstart="handleStart('wxmpQr')" @touchend="handleEnd">
<image :src="vdata.wxmpQr" mode="scaleToFill" />
</view>
<view class="image-tips">长按可将图片保存至相册</view>
</view>
<view class="list-footer">
<view class="button-wrapper">
<button class="jeepay-btn" hover-class="hover-button" @tap="goBack">返回列表页</button>
</view>
</view>
<JeepayPopupConfirm ref="confirmSave" />
</template>
<script setup>
import { reactive, ref } from 'vue'
import { $getWxMpInfo } from '@/http/apiManager.js'
import infoBox from '@/commons/utils/infoBox.js'
import qrCode from '@/commons/utils/qrCode.js'
import { saveHeadImgFile } from '@/commons/utils/saveImg.js'
const confirmSave = ref(null)
const vdata = reactive({
timeOut: null,
})
$getWxMpInfo().then(({ bizData }) => {
bizData.authQr = qrCode.drawImg(bizData.authUrl)
Object.assign(vdata, bizData)
})
const handleStart = (key) => {
vdata.timeOut = setTimeout(() => {
saveImage(key)
clearTimeout(vdata.timeOut)
}, 800)
}
const handleEnd = () => clearTimeout(vdata.timeOut)
const saveImage = (key) => {
// #ifdef APP-PLUS
confirmSave.value.open('确认保存图片?').then((res) => {
if (key == 'authQr') return saveQrcodeImg()
uni.downloadFile({
url: vdata[key],
success: (res) => {
console.log(res)
if (res.statusCode == 200) {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: (r) => {
infoBox.showSuccessToast('保存成功')
uni.vibrateShort()
},
fail: (er) => {
console.log(er)
infoBox.showErrorToast('保存失败')
}
})
}
},
fail: (err) => {
console.log(err)
infoBox.showErrorToast('保存失败')
}
})
})
// #endif
//#ifdef MP-WEIXIN
confirmSave.value.open('确认保存图片?').then((res) => {
downloadQR(key)
})
//#endif
}
//#ifdef MP-WEIXIN
function downloadQR(key) {
wx.getSetting({
//获取权限
success(res) {
if (res.authSetting['scope.writePhotosAlbum']) {
if (key == 'authQr') return saveWxQrcodeImg(vdata.authQr)
download(vdata[key])
} else {
wx.authorize({
scope: 'scope.writePhotosAlbum',
success() {
if (key == 'authQr') return saveWxQrcodeImg(vdata.authQr)
download(vdata[key])
},
})
}
},
})
}
function download(data) {
uni.downloadFile({
url: data,
success: (res) => {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: function () {
console.log('res', res)
infoBox.showSuccessToast('保存成功')
uni.vibrateShort()
},
fail: function (err) {
infoBox.showErrorToast('保存失败')
},
})
},
})
}
//#endif
const saveQrcodeImg = () => {
saveHeadImgFile(vdata.authQr, 80)
.then((success) => {
infoBox.showSuccessToast('保存成功')
})
.catch((err) => {
console.log(err)
infoBox.showErrorToast('保存失败')
})
}
const saveWxQrcodeImg = (data) => {
const fileManager = wx.getFileSystemManager()
const filePath = wx.env.USER_DATA_PATH + '/res.png'
//这块是定义图片的名称,可自定义其他
fileManager.writeFile({
filePath: filePath,
data: data.slice(22),
encoding: 'base64',
success: (res) => {
wx.saveImageToPhotosAlbum({
filePath: filePath,
success: function (res) {
//保存成功
infoBox.showSuccessToast('保存成功')
},
fail: function (err) {
console.log(err)
//保存失败
infoBox.showErrorToast('保存失败')
},
})
},
fail: (err) => {
infoBox.showErrorToast('保存失败')
},
})
}
const goBack = () => uni.navigateBack()
</script>
<style lang="scss" scoped>
.n-title {
margin: 50rpx 0 20rpx 0;
text-align: center;
font-size: 38rpx;
}
.sub-title {
margin: 0 50rpx;
color: #666666;
font-size: 28rpx;
text-align: center;
}
.image-wrapper {
display: flex;
flex-direction: column;
align-items: center;
border-bottom: 1rpx solid #ededed;
.image-content {
margin: 50rpx 0 30rpx 0;
width: 300rpx;
height: 300rpx;
overflow: hidden;
image {
width: 100%;
height: 100%;
}
}
.image-tips {
margin-bottom: 50rpx;
font-size: 26rpx;
color: #a6a6a6;
}
}
.footer-image {
padding-bottom: 50rpx;
}
</style>

View File

@@ -1,89 +0,0 @@
<template>
<view class="page-wrapper" @tap="dbTap">
<JeepayCustomNavbar title="通知接收人管理" backCtrl="back" />
<JSearchTitle :pTop="22" place="搜索微信昵称" @tap="go.toSearchPage('wxmpUser')"/>
<JeepayTableList ref="jeepayTableListRef" :reqTableDataFunc="reqTableDataFunc" >
<template #tableBody="{ record }">
<WxmpUserRender :record="record" />
</template>
</JeepayTableList>
<view class="footer-wrapper">
<view class="footer-button footer-button-style">
<button hover-class="hover-button" class="flex-center" @tap="go.to('PAGES_NOTICE_BING_USER')">绑定新的接收人</button>
</view>
</view>
</view>
</template>
<script setup>
import { reactive, ref, computed, provide } from "vue"
import { onReachBottom } from '@dcloudio/uni-app'
import go from '@/commons/utils/go.js'
import { reqLoad, API_URL_WXMP_USER_LIST } from "@/http/apiManager.js"
import WxmpUserRender from '@/pages/list/render/WxmpUserRender.vue'
onReachBottom(() => { })
// 请求
function reqTableDataFunc (params) {
return reqLoad.list(API_URL_WXMP_USER_LIST, params)
}
const confirm = (e, val) => {
console.log("e", e)
console.log("val", val)
val.state = Number(e)
}
let tapLastTime = 0
const dbTap = () => {
const timestamp = Date.parse(new Date())
const result = timestamp - tapLastTime
if (result <= 300) {
uni.pageScrollTo({
scrollTop: 0,
})
}
tapLastTime = timestamp
}
const navBack = () => uni.navigateBack()
</script>
<style lang="scss" scoped>
.page-wrapper {
.header-title {
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
font-size: 33rpx;
}
.footer-wrapper {
height: 170rpx;
.footer-button {
position: fixed;
left: 0;
right: 0;
bottom: 0;
padding: 30rpx;
background-color: transparent;
button {
height: 110rpx;
font-size: 33rpx;
font-weight: 500;
color: $J-color-tff;
border-radius: 20rpx;
background: $jeepay-bg-primary;
}
.hover-button {
opacity: 0.5;
}
}
}
}
</style>

View File

@@ -1,57 +0,0 @@
<template>
<view class="content">
<view class="title">
<span>{{ vdata.record.title }}</span>
</view>
<view class="updatedAt">
<span class="author">作者{{ vdata.record.publisher }}</span>
<span>时间{{ vdata.record.updatedAt }}</span>
</view>
<!-- mp-html 会有横向滚动条问题 所以采用v-html -->
<!-- <mp-html :content="record.content" /> -->
<view v-html="vdata.record.content"></view>
</view>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { reqLoad, API_URL_SYS_ARTICLES } from '@/http/apiManager.js'
import { onLoad } from '@dcloudio/uni-app'
onLoad((options) => {
reqLoad.getById(API_URL_SYS_ARTICLES, options.id).then( ({bizData}) => {
vdata.record = bizData
})
})
const vdata = reactive({
record : { }
})
</script>
<style lang="scss" scoped>
.content {
box-sizing: border-box;
padding: 0 50rpx 40rpx 50rpx;
.title {
// height: 60rpx;
width: 100%;
display: flex;
align-items: center;
justify-content: flex-start;
font-size: 35rpx;
padding: 20rpx 0;
font-weight: 700;
color: rgba(0, 0, 0, 0.8);
}
.updatedAt {
padding: 0rpx 0 40rpx 0;
color: #969696;
font-size: 20rpx;
.author {
margin-right: 30rpx;
}
}
}
</style>

View File

@@ -1,64 +0,0 @@
<template>
<JeepayTableList :reqTableDataFunc="reqTableDataFunc" :searchData="vdata.searchData" :pageSize="10">
<template #tableBody="{ record }">
<view class="post-list" @tap="toDetail(record.articleId)">
<text>{{ record.title }}</text>
<text>{{ record.createdAt ? record.createdAt.slice(0, 10) : '' }}</text>
</view>
</template>
</JeepayTableList>
</template>
<script setup>
import { ref, reactive, watch } from 'vue'
import { reqLoad, API_URL_SYS_ARTICLES } from "@/http/apiManager.js"
import go from '@/commons/utils/go.js'
import { onReachBottom } from '@dcloudio/uni-app'
onReachBottom(() => {} )
const vdata = reactive({
searchData: { articleType : 1 } // 搜索条件
})
// 请求
function reqTableDataFunc (params) {
return reqLoad.list(API_URL_SYS_ARTICLES, params)
}
// 跳转
function toDetail (articleId) {
go.to("PAGES_NOTICE_DETAIL", {id: articleId})
}
</script>
<style scoped lang="scss">
page {
background: #f5f6fc;
}
.post-list {
box-sizing: border-box;
width: 750rpx;
height: 150rpx;
background: #fff;
margin-top: 2rpx;
padding: 30rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
text {
&:nth-child(1) {
font-weight: bold;
font-size: 30rpx;
color: #000;
overflow: hidden;
text-overflow: ellipsis; //溢出用省略号显示
white-space: nowrap;
}
&:nth-child(2) {
font-weight: 500;
font-size: 23rpx;
color: #a6a6a6;
}
}
}
</style>

View File

@@ -1,314 +0,0 @@
<template>
<uni-drawer ref="drawer" mode="right" @change="change" :width="650">
<view class="screen-wrapper">
<JeepayCustomNavbar>
<view class="screen-title">订单筛选</view>
</JeepayCustomNavbar>
<scroll-view scroll-y class="screen-main">
<view class="time-wrapper">
<view class="time-title" style="margin-top: 42rpx">时间</view>
<view class="time-main">
<block v-for="v in timeList" :key="v.value">
<view class="time-item flex-center" :class="{ 'screen-active': v.value == vdata.selected }" @tap="vdata.selected = v.value">{{ v.text }}</view>
</block>
</view>
</view>
<view class="custom-wrapper" :class="{ 'custom-active': vdata.selected == 'custom' }">
<view class="custom-time custom-top-time">
<view class="custom-title">开始时间</view>
<view class="custom-tips" :style="{ color: vdata.startTime ? '#000' : '' }" @tap="startTime.show()">{{ vdata.startTime?.slice(0, -3) || '请选择开始时间' }}</view>
<image src="/static/iconImg/icon-arrow-right.svg" mode="scaleToFill" />
</view>
<view class="custom-time">
<view class="custom-title">结束时间</view>
<view class="custom-tips" :style="{ color: vdata.endTime ? '#000' : '' }" @tap="endTime.show()">{{ vdata.endTime?.slice(0, -3) || '请选择结束时间' }}</view>
<image src="/static/iconImg/icon-arrow-right.svg" mode="scaleToFill" />
</view>
</view>
<view class="screen-line" :class="{ 'custom-active-line': vdata.selected != 'custom' }"></view>
<view class="state-wrapper">
<view class="time-title">订单状态</view>
<view class="state-main">
<block v-for="(v, i) in stateList" :key="i">
<view class="state-item flex-center" :class="{ 'screen-active': vdata.stateArray.includes(v.value) }" @tap="orderStateOrWayCode(v.value, 'stateArray')">{{
v.text
}}</view>
</block>
</view>
</view>
<view class="screen-line" style="margin-top: 30rpx"></view>
<view class="pay-wrapper">
<view class="time-title">支付方式</view>
<view class="time-main">
<block v-for="(v, i) in payList" :key="i">
<view class="time-item flex-center" :class="{ 'screen-active': vdata.wayCodeArray.includes(v.value) }" @tap="orderStateOrWayCode(v.value, 'wayCodeArray')">{{
v.text
}}</view>
</block>
</view>
</view>
</scroll-view>
<!-- 按钮部分 -->
<view class="screen-button footer-button-style">
<view class="button-rest" hover-class="touch-button" hover-stay-time="150" @tap="reset">重置</view>
<view class="button-confirm" hover-class="touch-button" hover-stay-time="150" @tap="confirm">确认</view>
</view>
</view>
</uni-drawer>
<!-- 时间选择器 放在抽屉外面 否则选择器 大小受限 抽屉大小 -->
<template v-if="vdata.flag">
<xp-picker ref="endTime" mode="ymdhi" :history="true" @confirm="timeClick($event, 'endTime')"> <view></view></xp-picker>
<xp-picker ref="startTime" mode="ymdhi" :history="true" @confirm="timeClick($event, 'startTime')"> <view></view> </xp-picker>
</template>
</template>
<script setup>
import { reactive, ref, inject } from 'vue'
import { startAndEndTime } from '@/commons/utils/timeInspect'
import dayJs from 'dayjs'
// 搜索条件
let searchDataInject = inject('searchData')
let searchData = searchDataInject.value
let changePageMetaOverflowFunc = inject('changePageMetaOverflowFunc')
// 搜索 函数
let refTableFunc = inject('refTableFunc')
// 选择开始时间
const startTime = ref(null)
// 选择结束时间
const endTime = ref(null)
const drawer = ref(null) //获取抽屉实例
const vdata = reactive({
selected: 'today',
stateArray: [2, 5],
wayCodeArray: ['WECHAT', 'ALIPAY', 'YSFPAY', 'UNIONPAY', 'OTHER'],
flag: false,
})
const timeList = reactive([
{ text: '全部', value: '' },
{ text: '今天', value: 'today' },
{ text: '昨天', value: 'yesterday' },
{ text: '近7天', value: 'near2now_7' },
{ text: '近30天', value: 'near2yesterday_30' },
{ text: '自定义', value: 'custom' },
])
const stateList = reactive([
{ text: '支付成功', value: 2 },
{ text: '已退款', value: 5 },
{ text: '支付失败', value: 3 },
{ text: '订单生成', value: 0 },
{ text: '支付中', value: 1 },
{ text: '已撤销', value: 4 },
{ text: '订单关闭', value: 6 },
])
const payList = reactive([
{ text: '微信支付', value: 'WECHAT' },
{ text: '支付宝', value: 'ALIPAY' },
{ text: '云闪付', value: 'YSFPAY' },
{ text: '银联', value: 'UNIONPAY' },
{ text: '其他', value: 'OTHER' },
])
const selected = reactive({
time: 'custom',
})
const open = () => {
drawer.value.open()
}
// e 抽屉打开为true 关闭为 false
const change = (e) => {
if (changePageMetaOverflowFunc) {
changePageMetaOverflowFunc(!e)
}
vdata.flag = true
if (e) return uni.hideTabBar()
uni.showTabBar()
vdata.flag = false
}
// 时间选择器确认
const timeClick = (e, val) => {
vdata[val] = dayJs(e.timestamp).format('YYYY-MM-DD HH:mm:ss')
}
// 数组通用处理 有则删除 否则添加
const orderStateOrWayCode = (value, key) => {
// 如果存在值 删除
if (vdata[key].includes(value))
return vdata[key].splice(
vdata[key].findIndex((v) => v == value),
1
)
// 否则添加
vdata[key].push(value)
}
// 重置
const reset = () => {
vdata.selected = 'today'
vdata.stateArray = [2, 5]
vdata.wayCodeArray = payList.map((v) => v.value)
vdata.endTime = ''
vdata.startTime = ''
}
function confirm() {
// 自定义 筛选时间校验
if (vdata.selected == 'custom') {
if (!startAndEndTime(vdata.startTime, vdata.endTime)) return
}
// 模拟修改搜索 条件。
searchData.unionOrderState = vdata.stateArray.join(',')
searchData.queryDateRange = vdata.selected == 'custom' ? `customDateTime_${vdata.startTime}_${vdata.endTime || ''}` : vdata.selected
searchData.unionWayCodeType = vdata.wayCodeArray.join(',')
// 刷新父页面
refTableFunc()
// 关闭 弹层
drawer.value.close()
}
defineExpose({ open })
</script>
<style lang="scss" scoped>
.screen-wrapper {
display: flex;
flex-direction: column;
height: 100vh;
background-color: $J-bg-ff;
.screen-main {
height: calc(100vh - 88rpx - 260rpx);
}
}
.screen-title {
margin-left: 15rpx;
margin-right: 40rpx;
white-space: nowrap;
font-size: 33rpx;
font-weight: 500;
}
.time-title {
margin-left: 10rpx;
margin-bottom: 20rpx;
font-size: 30rpx;
font-weight: 500;
}
.time-wrapper {
padding: 0 30rpx;
margin-bottom: 10rpx;
}
.time-main {
display: grid;
grid-template-columns: repeat(3, 182rpx);
grid-template-rows: repeat(2, 90rpx);
grid-gap: 22rpx 22rpx;
border: 3rpx solid transparent;
.time-item {
color: rgba(0, 0, 0, 0.75);
font-size: 28rpx;
background-color: $J-bg-f5;
border-radius: $J-b-r10;
}
}
.state-wrapper {
padding: 0 30rpx;
.state-main {
display: grid;
grid-template-columns: repeat(3, 182rpx);
grid-template-rows: repeat(3, 90rpx);
grid-gap: 22rpx 22rpx;
border: 3rpx solid transparent;
.state-item {
height: 90rpx;
color: rgba(0, 0, 0, 0.75);
font-size: 28rpx;
background-color: $J-bg-f5;
border-radius: $J-b-r10;
}
}
}
.custom-wrapper {
padding-left: 30rpx;
height: 0;
transition: 0.2s ease-in;
overflow: hidden;
.custom-time {
display: flex;
align-items: center;
height: 110rpx;
.custom-title {
margin-right: 40rpx;
color: rgba(0, 0, 0, 0.75);
font-size: 28rpx;
}
.custom-tips {
flex: 1;
color: rgba(166, 166, 166, 1);
font-size: 28rpx;
}
image {
width: 110rpx;
height: 110rpx;
}
}
.custom-top-time {
border-bottom: 1rpx solid #ededed;
}
}
.custom-active {
height: 220rpx;
transition: 0.2s ease-in;
}
.pay-wrapper {
padding: 0 30rpx;
margin-bottom: 60rpx;
}
.screen-button {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx;
padding-bottom: 60rpx;
height: 110rpx;
view {
display: flex;
justify-content: center;
align-items: center;
height: 110rpx;
border-radius: 20rpx;
font-size: 33rpx;
font-weight: 500;
}
.button-rest {
width: 260rpx;
color: rgba(0, 0, 0, 0.5);
background-color: #f7f7f7;
}
.button-confirm {
flex: 1;
margin: 0 60rpx 0 20rpx;
color: #fff;
background: $jeepay-bg-primary;
}
}
.screen-active {
color: $J-color-t29 !important;
border: 3rpx solid #1a66ff !important;
background: linear-gradient(270deg, rgba(35, 143, 252, 0.1) 0%, rgba(26, 102, 255, 0.1) 100%) !important;
}
.screen-line {
height: 20rpx;
margin-bottom: 30rpx;
background-color: #f5f5f5;
}
.custom-active-line {
margin-top: 20rpx;
}
.touch-button {
opacity: 0.5;
}
</style>

View File

@@ -1,113 +0,0 @@
<template>
<view class="refund-wrapper" v-if="vdata.list.length > 0">
<view class="refund-title">退款记录</view>
<!-- 列表循环部分 start border-none 去掉边框类名 -->
<block v-for="(item, i) in vdata.list" :key="i">
<view class="refund-item border-none">
<view class="refund-money">
<view>退{{ cal.cert2Dollar(item.refundAmount) }}</view>
<view>{{ calSubAmount(i) }}</view>
</view>
<view class="refund-time">{{ item.createdAt }}</view>
</view>
</block>
<!-- 列表循环部分end -->
<view v-if="props.refundBtn" class="refund-button flex-center" hover-class="touch-button" hover-stay-time="150" @tap="emits('refund')">发起退款</view>
</view>
</template>
<script setup>
import { reactive, ref } from 'vue';
import { reqLoad, API_URL_REFUND_LIST } from '@/http/apiManager.js';
import { onPageScroll, onLoad } from '@dcloudio/uni-app';
import cal from '@/commons/utils/cal.js';
import datamap from '@/commons/utils/datamap.js';
import infoBox from '@/commons/utils/infoBox.js';
import ent from '@/commons/utils/ent.js';
import go from '@/commons/utils/go.js';
import emit from '@/commons/utils/emit.js';
const props = defineProps({
refundBtn: { type: Boolean, default: false },
orderInfo: {
type: Object,
default: () => {
return {};
}
}
});
const vdata = reactive({
list: []
});
// 刷新列表
function refList(payOrderId) {
reqLoad.list(API_URL_REFUND_LIST, { payOrderId: payOrderId, state: 2, pageSize: -1 }).then(({ bizData }) => {
vdata.list = bizData.records;
emits('refRefundCountFunc', bizData.total);
});
}
function calSubAmount(index) {
let allRefundAmount = 0;
for (var i = index; i < vdata.list.length; i++) {
allRefundAmount += vdata.list[i].refundAmount;
}
return cal.cert2Dollar(props.orderInfo.amount - allRefundAmount);
}
const emits = defineEmits(['refund', 'refRefundCountFunc']);
defineExpose({ refList });
</script>
<style lang="scss" scoped>
.refund-wrapper {
padding: 0 75rpx;
padding-bottom: 70rpx;
box-sizing: border-box;
.refund-title {
margin: 70rpx 0 30rpx 0;
font-size: 32rpx;
font-weight: 500;
color: #fff;
}
.refund-item {
height: 160rpx;
border-bottom: 1rpx solid rgba(255, 255, 255, 0.2);
.refund-money {
display: flex;
justify-content: space-between;
margin: 30rpx 0 20rpx 0;
color: #fff;
font-size: 30rpx;
font-weight: 400;
}
.refund-time {
margin-bottom: 30rpx;
color: rgba(255, 255, 255, 0.65);
font-size: 30rpx;
font-weight: 400;
}
}
.border-none {
border: none;
}
.refund-button {
margin-top: 70rpx;
height: 110rpx;
font-size: 33rpx;
font-weight: 500;
color: #ff5b4c;
background-color: $J-bg-ff;
border-radius: $v-b-r20;
}
}
.touch-button {
opacity: 0.5;
}
</style>

View File

@@ -1,77 +0,0 @@
<template>
<uni-popup ref="popup" type="top" mask-background-color="rgba(0,0,0,.5)" :safe-area="false">
<view class="card-wrapper">
<image class="icon-close" src="/static/iconImg/icon-x.svg" mode="scaleToFill" @tap="close" />
<view class="title">请输入支付密码</view>
<view class="sub-title">退款</view>
<view class="refund-money">{{ vdata.refundAmount }}</view>
<JPasswordInput v-if="vdata.isShowPwdInput" margin="0 50rpx" :focus="true" ref="pwdInput" @inputChange="inputChange" />
</view>
</uni-popup>
</template>
<script setup>
import { onMounted, reactive, ref, nextTick } from 'vue'
const vdata = reactive({
refundAmount: 0,
isShowPwdInput: false,
})
const proms = {}
const popup = ref(null)
const pwdInput = ref(null)
const open = (money, callBack) => {
vdata.refundAmount = money
vdata.callBack = callBack
popup.value.open()
vdata.isShowPwdInput = false
nextTick(() => {
vdata.isShowPwdInput = true
})
}
const close = () => {
popup.value.close()
vdata.isShowPwdInput = false
}
// 输入框 e 输入的数字
const inputChange = (e) => {
if (e.length >= 6) return vdata.callBack(e)
}
const clearInput = () => pwdInput.value.clearInput()
defineExpose({ open, clearInput, close })
</script>
<style lang="scss" scoped>
.card-wrapper {
margin: 0 50rpx;
padding-bottom: 50rpx;
margin-top: 162rpx;
background-color: $J-bg-ff;
border-radius: $J-b-r32;
.icon-close {
padding: 30rpx;
width: 60rpx;
height: 60rpx;
}
.title {
text-align: center;
font-size: 30rpx;
font-weight: 500;
}
.sub-title {
margin-top: 40rpx;
margin-bottom: 20rpx;
text-align: center;
font-size: 30rpx;
color: #808080;
}
.refund-money {
margin-bottom: 70rpx;
text-align: center;
font-size: 50rpx;
font-weight: 500;
}
}
</style>

View File

@@ -1,12 +0,0 @@
import { reactive, ref } from "vue"
export const stateList = reactive([
{ text: "支付成功", color: "#09BB07" },
{ text: "支付失败", color: "#CB2972" },
{ text: "订单生成", color: "#2980FD" },
{ text: "支付中", color: "#FFAA33" },
{ text: "部分退款", color: "#FF5B4C" },
{ text: "全额退款", color: "#FF5B4C" },
{ text: "全额退款", color: "#FF5B4C" },
{ text: "已撤销", color: "#808080" },
{ text: "订单关闭", color: "#D9D9D9" },
])

View File

@@ -1,140 +0,0 @@
<template>
<JeepayBackground>
<JeepayCustomNavbar>
<view class="store-name" @tap="selectedStore">{{ vdata.store.storeName }}<image src="/static/iconImg/icon-arrow-black.svg" mode="scaleToFill" /></view>
</JeepayCustomNavbar>
<view class="input-wrapper">
<view class="input-main" @tap="go.toSearchPage('payOrder')">
<image src="/static/iconImg/icon-search.svg" mode="scaleToFill" />
<input type="text" placeholder="搜索订单号" disabled placeholder-style="color:rgba(0, 0, 0, 0.35)" />
</view>
<view class="screen-wrapper flex-center" @tap="screen.open()">
<image src="/static/iconImg/icon-screen.svg" mode="scaleToFill" />
筛选
</view>
</view>
<JeepayTableList ref="jeepayTableListRef" :reqTableDataFunc="reqTableDataFunc" :searchData="vdata.searchData">
<template #tableBody="{ record }">
<PayOrderRender :record="record" />
</template>
</JeepayTableList>
<OrderScreen ref="screen" />
</JeepayBackground>
<!-- 选择门店 -->
<JeepayBizinfoSelect :isShowAllBiz="true" ref="jeepayPopupListSelect" />
</template>
<script setup>
import { reactive, ref, computed, provide } from 'vue'
import { onReachBottom, onUnload } from '@dcloudio/uni-app'
import go from '@/commons/utils/go.js'
import { stateList } from './components/stateList.js'
import OrderScreen from './components/OrderScreen.vue'
import PayOrderRender from '@/pages/list/render/PayOrderRender.vue'
import { req, reqLoad, API_URL_PAY_ORDER_LIST, API_URL_MCH_STORE_LIST } from '@/http/apiManager.js'
import emit from '@/commons/utils/emit.js'
onReachBottom(() => {})
// 监听 更新事件
onUnload(() => uni.$off(emit.ENAME_REF_PAY_ORDER))
uni.$on(emit.ENAME_REF_PAY_ORDER, function (data) {
jeepayTableListRef.value.refTable(true)
})
const screen = ref(null) //获取抽屉实例
const jeepayTableListRef = ref()
// 获取门店选择弹窗实例
const jeepayPopupListSelect = ref(null)
const vdata = reactive({
// 搜索对象 默认查询条件 今天 成功和已退款
searchData: {
queryDateRange: 'today',
unionOrderState: '2,5',
},
store: {
storeId: '',
storeName: '全部门店',
},
})
// 向子组件注入: 搜索条件
provide(
'searchData',
computed(() => vdata.searchData)
)
provide('refTableFunc', refTableFunc)
const toDetail = () => uni.navigateTo({ url: '/pages/order/orderDetail' })
// 请求
function reqTableDataFunc(params) {
return reqLoad.list(API_URL_PAY_ORDER_LIST, params)
}
// 选择门店
const selectedStore = () => {
jeepayPopupListSelect.value.open(vdata.store).then((selected) => {
if (selected) {
vdata.store = selected
vdata.searchData.storeId = selected.storeId
refTableFunc()
}
})
}
// 点击筛选条件的确定按钮
function refTableFunc() {
jeepayTableListRef.value.refTable(true)
}
</script>
<style lang="scss" scoped>
.store-name {
display: flex;
align-items: center;
font-size: 33rpx;
font-weight: 500;
image {
width: 44rpx;
height: 44rpx;
margin-left: 5rpx;
transform: rotate(180deg);
}
}
.input-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 30rpx;
padding-top: 22rpx;
height: 110rpx;
background-color: $J-bg-ff;
.input-main {
flex: 1;
display: flex;
align-items: center;
height: 70rpx;
background: $J-bg-f5;
border-radius: $J-b-r12;
image {
padding: 22rpx;
width: 26rpx;
height: 26rpx;
}
input {
flex: 1;
font-size: 27rpx;
}
}
.screen-wrapper {
margin: 0 12rpx 0 20rpx;
font-size: 32rpx;
color: $J-color-t99;
image {
width: 28rpx;
height: 26rpx;
padding: 0 21rpx;
}
}
}
</style>

View File

@@ -1,447 +0,0 @@
<template>
<!-- 如果有退款 使用渐变色背景色 如果没有退款 使用 f7背景色 -->
<view class="detail-wrapper" :style="{ background: vdata.refundCount > 0 ? '' : '#f7f7f7' }">
<view class="detail-main">
<view class="detail-header">
<JeepayCustomNavbar :transparent="true" title="订单详情" backCtrl="back" />
<view style="height: 30rpx"></view>
<view class="detail-title">
<view class="title-img" :style="{ backgroundColor: datamap.payOrderImage(vdata.orderInfo?.wayCodeType)?.bgColor }">
<image :src="datamap.payOrderImage(vdata.orderInfo?.wayCodeType)?.imgUrl" mode="scaleToFill" />
</view>
<view class="money-wrapper">
<view class="detail-money">
<view>
<text class="icon-money"></text>
{{ cal.cert2Dollar(vdata.orderInfo.amount) }}
</view>
<image src="/static/iconImg/icon-more.svg" mode="scaleToFill" @tap="singlePopupRef.open('refund')" />
</view>
<view class="detail-number">{{ vdata.orderInfo.payOrderId }}</view>
</view>
</view>
</view>
<br />
<view class="detail-info bdr-after bdr-before border-f2">
<view class="detail-item">
<view class="item-title">交易状态</view>
<view class="item-info">
<text class="detail-dot" :style="{ backgroundColor: datamap.payOrderState(vdata.orderInfo.state).color }" />
{{ datamap.payOrderState(vdata.orderInfo.state).text }}
</view>
</view>
<view class="detail-item">
<view class="item-title">交易门店</view>
<view class="item-info">{{ vdata.orderInfo.storeName }}</view>
</view>
<view class="detail-item">
<view class="item-title">支付方式</view>
<view class="item-info">{{ datamap.payOrderImage(vdata.orderInfo.wayCodeType).title }}</view>
</view>
<view class="detail-item">
<view class="item-title">下单应用</view>
<view class="item-info">{{ vdata.orderInfo.appId }}</view>
</view>
<view class="detail-item">
<view class="item-title">商户订单号</view>
<view class="item-info">{{ vdata.orderInfo.mchOrderNo }}</view>
</view>
<view class="detail-item">
<view class="item-title">支付订单号</view>
<view class="item-info">{{ vdata.orderInfo.payOrderId }}</view>
</view>
<view class="detail-item">
<view class="item-title">渠道订单号</view>
<view class="item-info">{{ vdata.orderInfo.channelOrderNo }}</view>
</view>
<view class="detail-item">
<view class="item-title">分账状态</view>
<view class="item-info">
<text v-if="vdata.orderInfo.divisionState == 0" color="blue">未发生分账</text>
<text v-else-if="vdata.orderInfo.divisionState == 1" color="orange">待分账</text>
<text v-else-if="vdata.orderInfo.divisionState == 2" color="red">分账处理中</text>
<text v-else-if="vdata.orderInfo.divisionState == 3" color="green">任务已结束</text>
<text v-else color="#f50">未知</text>
</view>
</view>
<view class="detail-item">
<view class="item-title">顾客备注</view>
<view class="item-info">{{ vdata.orderInfo.buyerRemark }}</view>
</view>
<view class="detail-item">
<view class="item-title">下单时间</view>
<view class="item-info">{{ vdata.orderInfo.createdAt }}</view>
</view>
</view>
<view class="detail-info">
<view class="detail-item">
<view class="item-title">支付金额</view>
<view class="item-info"> {{ cal.cert2Dollar(vdata.orderInfo.amount) }}</view>
</view>
<view class="detail-item">
<view class="item-title">收单费率</view>
<view class="item-info">{{ (vdata.orderInfo.mchFeeRateNum && (vdata.orderInfo.mchFeeRateNum.replace('%', '') * 1).toFixed(2)) || '--' }}%</view>
</view>
<view class="detail-item">
<view class="item-title">收单手续费</view>
<view class="item-info">
{{ vdata.orderInfo.mchFeeRateNum && cal.cert2Dollar(vdata.orderInfo.amount * (vdata.orderInfo.mchFeeRateNum.replace('%', '') / 100)) }}
</view>
</view>
<view class="detail-item">
<view class="item-title">垫资费率</view>
<view class="item-info">{{ vdata.orderInfo.cashRate }}%</view>
</view>
<view class="detail-item">
<view class="item-title">垫资手续费</view>
<view class="item-info"> {{ cal.cert2Dollar(vdata.orderInfo.amount * vdata.orderInfo.cashRate) }}</view>
</view>
<view class="detail-item">
<view class="item-title">退款总额</view>
<view class="item-info">{{ cal.cert2Dollar(vdata.orderInfo.refundAmount) }}</view>
</view>
<view class="detail-item">
<view class="item-title">退款次数</view>
<view class="item-info">{{ vdata.orderInfo.refundTimes }}</view>
</view>
<view class="detail-item">
<view class="item-title">优惠金额</view>
<view class="item-info">{{ cal.cert2Dollar(vdata.orderInfo.discountAmt) }}</view>
</view>
<view class="detail-item">
<view class="item-title">补贴金额</view>
<view class="item-info">{{ cal.cert2Dollar(vdata.orderInfo.marketAmt) }}</view>
</view>
<view class="detail-item">
<view class="item-title">预计入账金额</view>
<view class="item-info" v-if="vdata.orderInfo.state == 5">
<template v-if="vdata.orderInfo.refundState == 1">
{{
vdata.orderInfo.mchFeeRateNum &&
cal.cert2Dollar(
vdata.orderInfo.amount - vdata.orderInfo.amount * (vdata.orderInfo.mchFeeRateNum.replace('%', '') / 100) - vdata.orderInfo.refundAmount
)
}}
</template>
<template v-else>
{{
vdata.orderInfo.mchFeeRateNum &&
cal.cert2Dollar(vdata.orderInfo.amount * (vdata.orderInfo.mchFeeRateNum.replace('%', '') / 100) - vdata.orderInfo.amount)
}}
</template>
</view>
<view class="item-info" v-else>
{{
vdata.orderInfo.mchFeeRateNum &&
cal.cert2Dollar(
vdata.orderInfo.amount -
vdata.orderInfo.amount * (vdata.orderInfo.mchFeeRateNum.replace('%', '') / 100) -
vdata.orderInfo.amount * vdata.orderInfo.cashRate -
vdata.orderInfo.refundAmount
)
}}
</view>
</view>
<view class="detail-item" @tap.stop="tips.open()">
<view class="item-title">
<text class="t">入账结算类型</text>
<uni-icons type="help-filled" size="20" color="#c6c6c6" class="icon" />
</view>
<view class="item-info">
{{ vdata.orderInfo.settleType }}
</view>
</view>
<!-- <view class="detail-item">
<view class="item-title">实收金额</view>
<view class="item-info">{{ cal.cert2Dollar(vdata.orderInfo.amount - vdata.orderInfo.refundAmount - vdata.orderInfo.mchFeeAmount) }}</view>
</view> -->
<view class="detail-button flex-center" hover-class="touch-button" hover-stay-time="150" @tap="printOrder">打印小票</view>
<!-- 不包含退款记录 && 支持退款 -->
<!-- 包含退款记录时在列表内显示 -->
<!-- <view v-if="isShowRefund() && vdata.refundCount <= 0" class="refund-button flex-center" hover-class="touch-button" hover-stay-time="150" @tap="toRefundPage">
发起退款
</view> -->
<view v-if="vdata.orderInfo.refundState != 2" class="refund-button flex-center" hover-class="touch-button" hover-stay-time="150" @tap="toRefundPage">发起退款</view>
</view>
</view>
<!-- 包含退款记录时 需要展示退款记录 -->
<RefundCard
v-show="vdata.refundCount > 0"
:orderInfo="vdata.orderInfo"
ref="refundCardRef"
@refund="toRefundPage"
:refundBtn="isShowRefund()"
@refRefundCountFunc="refRefundCountFunc"
/>
</view>
<JTipsPopupContent ref="tips" title="入账结算类型" buttonText="我知道了">
<block v-for="(v, i) in tipsList" :key="i">
<view class="tips-wrapper">
<view class="tips-title">{{ v.title }}</view>
<view class="tips-info">{{ v.info }}</view>
</view>
</block>
</JTipsPopupContent>
<JSinglePopup ref="singlePopupRef" activeColor="#FF5B4C" :list="vdata.singleList" />
</template>
<script setup>
import { nextTick, onMounted, reactive, ref } from 'vue';
import { req, reqLoad, API_URL_PAY_ORDER_LIST, $payOrderPrint } from '@/http/apiManager.js';
import RefundCard from './components/RefundCard.vue';
import { onPageScroll, onLoad, onUnload } from '@dcloudio/uni-app';
import cal from '@/commons/utils/cal.js';
import datamap from '@/commons/utils/datamap.js';
import infoBox from '@/commons/utils/infoBox.js';
import ent from '@/commons/utils/ent.js';
import go from '@/commons/utils/go.js';
import emit from '@/commons/utils/emit.js';
onPageScroll(() => {});
const refundCardRef = ref();
const tips = ref(null);
const tipsList = ref([
{
title: 'T1',
info: '工作日次日到账交易资金于周末和法定节假日次日的6点-12点自动结算至银行卡'
},
{
title: 'D1',
info: '自然日次日到账全年365天不分节假日的交易资金于自然日的次日6点-12点自动结算至银行卡'
},
{
title: 'D0',
info: '实时到账全年365天24小时不分节假日的交易资金笔笔实时秒到至银行卡更放心更快捷定时结算在一天24个整点时辰根据入账需求选择结算范围可任意指定一个或多个结算时间点'
}
]);
// 监听 更新事件
onUnload(() => uni.$off(emit.ENAME_REF_PAY_ORDER));
uni.$on(emit.ENAME_REF_PAY_ORDER, function (data) {
refData(vdata.orderInfo.payOrderId);
});
function refData(payOrderId) {
vdata.singleList = [{ label: '打印小票', value: 'print', fun: printOrder }];
reqLoad.getById(API_URL_PAY_ORDER_LIST, payOrderId).then(({ bizData }) => {
vdata.orderInfo = bizData;
// 追加退款
if (isShowRefund()) {
vdata.singleList.push({ label: '订单退款', value: 'refund', fun: toRefundPage });
}
// 当不同状态, 可能没有此组件
nextTick(() => {
if (refundCardRef && refundCardRef.value) {
refundCardRef.value.refList(vdata.orderInfo.payOrderId);
}
});
});
}
onLoad((options) => {
refData(options.payOrderId);
});
const vdata = reactive({
singleList: [],
orderInfo: {},
refundCount: 0 // 退款记录 0条。
});
const singlePopupRef = ref();
function isShowRefund() {
return ent.has('ENT_PAY_ORDER_REFUND') && vdata.orderInfo.state === 2 && vdata.orderInfo.refundState !== 2;
}
// 去退款详情页
function toRefundPage() {
go.to('PAGES_REFUND_ORDER', { payOrderId: vdata.orderInfo.payOrderId });
}
// 订单打印
function printOrder() {
$payOrderPrint(vdata.orderInfo.payOrderId).then((bizData) => {
infoBox.showToast('打印指令已发送');
});
}
function refRefundCountFunc(count) {
vdata.refundCount = count;
}
</script>
<style lang="scss" scoped>
.tips-wrapper {
display: flex;
flex-direction: column;
justify-content: center;
padding: 0 50rpx;
height: 170rpx;
.tips-title {
margin-bottom: 12rpx;
font-size: 30rpx;
}
.tips-info {
font-size: 26rpx;
color: #808080;
}
}
.detail-wrapper {
background: linear-gradient(135deg, rgba(255, 91, 76, 1) 60%, rgba(203, 41, 114, 1) 100%);
.detail-main {
// min-height: calc(100vh - 35rpx);
min-height: 100vh;
padding-bottom: 35rpx;
border-radius: 0 0 60rpx 60rpx;
background-color: $v-color-bgrey;
}
}
.detail-header {
background: url('/static/indexImg/user-bg.svg');
padding-bottom: 32rpx;
.detail-title {
display: flex;
padding: 0 50rpx;
min-height: 160rpx;
.title-img {
flex-shrink: 0;
margin-right: 30rpx;
width: 160rpx;
height: 160rpx;
border-radius: 50%;
overflow: hidden;
image {
width: 100%;
height: 100%;
}
}
.money-wrapper {
flex: 1;
}
.detail-money {
display: flex;
justify-content: space-between;
align-items: center;
.icon-money {
font-size: 26rpx;
}
image {
width: 70rpx;
height: 70rpx;
}
}
.detail-number {
margin-top: 20rpx;
color: rgba(0, 0, 0, 0.5);
font-size: 30rpx;
}
}
}
.detail-info {
position: relative;
padding: 20rpx 40rpx;
margin: 0 auto;
width: 680rpx;
box-sizing: border-box;
border-radius: $J-b-r32;
background-color: $J-bg-ff;
.detail-button,
.refund-button {
margin: 20rpx 0 10rpx 0;
height: 110rpx;
font-size: 33rpx;
font-weight: 500;
color: #fff;
border-radius: $v-b-r20;
background: $jeepay-bg-primary;
}
.refund-button {
margin-top: 30rpx;
color: #ff5b4c;
background: rgba(255, 91, 76, 0.1);
}
}
.border-f2 {
border-bottom: 2px dashed #f2f2f2;
}
.bdr-after::after,
.bdr-before::before {
content: '';
display: block;
position: absolute;
bottom: -25rpx;
z-index: 99;
width: 50rpx;
height: 50rpx;
background-color: $v-color-bgrey;
border-radius: 50%;
}
.bdr-after::after {
left: -25rpx;
}
.bdr-before::before {
right: -25rpx;
}
.touch-button {
opacity: 0.5;
}
.detail-item {
display: flex;
justify-content: space-between;
padding: 20rpx 0;
.item-title {
flex-shrink: 0;
font-size: $J-f-size30;
font-weight: 400;
color: $J-color-t8c;
display: flex;
align-items: center;
.icon {
margin-left: 8upx;
position: relative;
top: 3upx;
}
}
.item-info {
flex: 1;
display: flex;
align-items: center;
justify-content: flex-end;
text-align: right;
font-size: $J-f-size30;
font-weight: 400;
word-break: break-all;
padding-left: 32upx;
.detail-dot {
align-self: center;
display: block;
margin-right: 15rpx;
width: 20rpx;
height: 20rpx;
border-radius: 50%;
background-color: #ff5b4c;
}
}
}
</style>

View File

@@ -1,188 +0,0 @@
<template>
<view class="refund-wrapper">
<JeepayCustomNavbar textColor="#fff" :transparent="true" title="订单退款" backCtrl="back" />
<view class="refund-main">
<view class="refund-title">退款金额</view>
<view class="refund-money">
<input type="digit" v-model="vdata.refundAmount" :maxlength="vdata.maxLength" id="" @input="inputChange" />
<view class="icon-unit">()</view>
</view>
<view class="sure-refund">
<text>可退 {{ cal.cert2Dollar(vdata.orderInfo.amount - vdata.orderInfo.refundAmount) }}</text>
<view class="all-refund" @tap="vdata.refundAmount = cal.cert2Dollar(vdata.orderInfo.amount - vdata.orderInfo.refundAmount, true)">全部退款</view>
</view>
<view class="refund-title">退款原因</view>
<view class="refund-reason">
<input type="text" placeholder="请输入退款原因" placeholder-style=" color: rgba(255,255,255,0.35)" v-model="vdata.refundRemark" />
</view>
<view class="refund-info">
<view class="info-title">订单金额</view>
<view class="info-text">{{ cal.cert2Dollar(vdata.orderInfo.amount) }}</view>
</view>
<view class="refund-info">
<view class="info-title">已退金额</view>
<view class="info-text">{{ cal.cert2Dollar(vdata.orderInfo.refundAmount) }}</view>
</view>
<view class="refund-info">
<view class="info-title">剩余金额</view>
<view class="info-text">{{ cal.cert2Dollar(vdata.orderInfo.amount - vdata.orderInfo.refundAmount) }}</view>
</view>
<view class="confirm-refund flex-center" hover-class="touch-button" hover-stay-time="150" @tap="confirmRefund">确认退款</view>
</view>
</view>
<confirmRefundPopup ref="refundPopup" />
</template>
<script setup>
import { reactive, ref } from 'vue';
import { reqLoad, API_URL_PAY_ORDER_LIST, $payOrderRefund } from '@/http/apiManager.js';
import confirmRefundPopup from './components/confirmRefundPopup.vue';
import { onLoad } from '@dcloudio/uni-app';
import cal from '@/commons/utils/cal.js';
import datamap from '@/commons/utils/datamap.js';
import infoBox from '@/commons/utils/infoBox.js';
import ent from '@/commons/utils/ent.js';
import go from '@/commons/utils/go.js';
import emit from '@/commons/utils/emit.js';
onLoad((options) => {
reqLoad.getById(API_URL_PAY_ORDER_LIST, options.payOrderId).then(({ bizData }) => {
vdata.orderInfo = bizData;
});
});
const refundPopup = ref(null);
const vdata = reactive({
orderInfo: {},
refundModel: 1,
refundAmount: 0,
refundRemark: '', // 退款原因
maxLength: 15
});
// 确认退款
function confirmRefund() {
if (isNaN(vdata.refundAmount) || vdata.refundAmount <= 0) {
return infoBox.showToast('请输入退款金额');
}
if (parseFloat(vdata.refundAmount) > cal.cert2Dollar(vdata.orderInfo.amount - vdata.orderInfo.refundAmount, true)) {
return infoBox.showToast('退款金额超限');
}
if (!vdata.refundRemark) {
return infoBox.showToast('请输入退款原因');
}
// TODO 调起 支付密码弹层 发起请求。
refundPopup.value.open(vdata.refundAmount, refundPost);
}
// 只能输入小数点后两位
const inputChange = (e) => {
const value = e.detail.value;
if (!value.includes('.')) return (vdata.maxLength = 15); //不包含小数点
vdata.maxLength = value.split('.')[0].length + 3;
};
const refundPost = (payPassword) => {
console.log('payPassword', payPassword);
$payOrderRefund(vdata.orderInfo.payOrderId, vdata.refundAmount, vdata.refundRemark, payPassword, vdata.refundModel)
.then(({ bizData }) => {
console.log('bizData', bizData);
if (bizData.state == 0 || bizData.state == 1 || bizData.state == 2) {
infoBox.showSuccessToast('退款已申请').then(() => {
// 刷新订单数据
emit.pageEmit(emit.ENAME_REF_PAY_ORDER);
refundPopup.value.close();
go.back();
});
} else {
infoBox.showErrorToast(bizData.errMsg);
}
})
.catch((err) => {
refundPopup.value.clearInput();
});
};
</script>
<style lang="scss" scoped>
.refund-wrapper {
min-height: 100vh;
background: linear-gradient(135deg, rgba(255, 91, 76, 1) 0%, rgba(203, 41, 114, 1) 100%);
.refund-main {
padding: 0 60rpx;
.refund-title {
margin: 50rpx 0 10rpx 0;
font-size: 30rpx;
color: rgba(255, 255, 255, 0.7);
}
.refund-money {
display: flex;
justify-content: space-between;
align-items: flex-end;
min-height: 130rpx;
color: #fff;
border-bottom: 1rpx solid rgba(255, 255, 255, 0.25);
input {
height: 100rpx;
font-size: 60rpx;
font-weight: 500;
}
.icon-unit {
transform: translateY(-33rpx);
font-size: 30rpx;
font-weight: 500;
}
}
.sure-refund {
display: flex;
margin: 30rpx 0 20rpx 0;
color: rgba(255, 255, 255, 0.6);
font-size: 30rpx;
font-weight: 400;
.all-refund {
margin-left: 30rpx;
color: rgba(255, 255, 255, 1);
}
}
.refund-reason {
display: flex;
align-items: center;
margin-bottom: 66rpx;
height: 120rpx;
border-bottom: 1rpx solid rgba(255, 255, 255, 0.25);
input {
font-size: 30rpx;
font-weight: 400;
color: #fff;
}
}
.refund-info {
display: flex;
justify-content: space-between;
margin: 44rpx 0;
font-size: 30rpx;
font-weight: 400;
.info-title {
color: rgba(255, 255, 255, 0.7);
}
.info-text {
color: #fff;
font-weight: 500;
}
}
.confirm-refund {
margin-top: 74rpx;
height: 110rpx;
border-radius: $v-b-r20;
background-color: #fff;
color: #dd3b65;
font-size: 33rpx;
font-weight: 500;
}
}
}
</style>

View File

@@ -1,135 +0,0 @@
<template>
<uni-popup ref="popup" type="bottom" mask-background-color="rgba(0,0,0,0.5)" :safe-area="false">
<view class="pay-wrapper">
<view class="pay-header-wrapper">
<view class="pay-img">
<image src="/static/iconImg/icon-success.svg" mode="scaleToFill" />
<view class="pay-tips">支付成功</view>
</view>
<view class="pay-number">{{ cal.cert2Dollar(vdata.orderInfo.amount) }}</view>
</view>
<view class="time-out flex-center">
<text>{{ vdata.subTime }}S</text> 后自动返回
</view>
<view class="list-footer">
<view class="button-wrapper" style="border: none; background-color: transparent; backdrop-filter: none;">
<Button @tap="close">确认</Button>
</view>
</view>
</view>
</uni-popup>
</template>
<script setup>
import { nextTick, onMounted, reactive, ref } from 'vue'
import timer from '@/commons/utils/timer.js'
import cal from '@/commons/utils/cal.js'
const emit = defineEmits(['close'])
const vdata = reactive({
orderInfo: { }, // 订单信息
subTime: 5,
isClosed: false, // 是否已经明确关闭, 避免点击按钮与定时同时触发。
})
const popup = ref(null)
// 打开弹窗 val 收款金额
const open = (orderInfo) => {
// 订单信息
vdata.orderInfo = orderInfo
// 剩余时间重置
vdata.subTime = 5
vdata.isClosed = false
popup.value.open()
// nextTick 用作, 显示页面后再倒计时, 否则直接显示了 4s .
nextTick(() => {
// 执行递归函数 1秒 一次
timer.startTimeoutTask(1, 5, (subTime) => {
// 第一个判断是task任务结束 第二个判断是 手动关闭的判断。
if (subTime <= 0 || vdata.subTime <= 0) {
close()
return false;
}
vdata.subTime = subTime
return true;
})
})
}
const close = () => {
if(vdata.isClosed){
return false;
}
emit('close') //回调函数 close
vdata.isClosed = true
popup.value.close()
vdata.subTime = 0 ; // 避免进入下一次task
}
defineExpose({ open, close })
</script>
<style lang="scss" scoped>
.pay-wrapper {
padding: 0.1rpx;
height: 100vh;
.pay-header-wrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin: 0 auto;
margin-top: 108rpx;
width: 670rpx;
height: 500rpx;
border-radius: $J-b-r32;
background-image: url('/static/bgImg/quik-bg-img.svg');
.pay-img {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
image {
width: 100rpx;
height: 100rpx;
}
.pay-tips {
margin-top: 10rpx;
margin-bottom: 50rpx;
color: #1abb51;
font-size: 36rpx;
font-weight: 500;
}
}
.pay-number {
font-size: 50rpx;
font-weight: 500;
}
}
.time-out {
margin-top: 30rpx;
color: rgba(255, 255, 255, 0.7);
font-size: 30rpx;
text {
margin-right: 15rpx;
color: #fff;
}
}
}
</style>

View File

@@ -1,231 +0,0 @@
<template>
<view>
<view style="height:50rpx"></view>
<view class="collection-code">
<view style="font-size: 36rpx;margin-bottom: 30rpx;">扫码付款</view>
<view style="font-size: 50rpx;color: #0041c4;margin-bottom: 50rpx;">{{vdata.payAmount}}</view>
<view class="img-box">
<image v-if='vdata.qrImgUrl' :src="vdata.qrImgUrl" style="width:100%;height: 100%" mode=""></image>
</view>
<view class="text">
<view>支付方式</view>
</view>
<view class="pay-methods">
<view v-for="(item, index) in payMethods" :key="index">
<image :src="item.url" mode=""></image>
<view>{{ item.name }}</view>
</view>
</view>
</view>
<view class="scan" @click="changeScan">
<image src="@/static/pay/scancode.svg" mode=""></image>
<view>切换至扫一扫收款</view>
</view>
<PaymentSuccess ref="paymentSuccessRef" @close="go.back(1,emit.ENAME_RESET_PAY_AMOUNT)"/>
</view>
</template>
<script setup>
import { onLoad, onUnload } from '@dcloudio/uni-app'
import { reactive, ref, onUnmounted, nextTick} from 'vue'
import PaymentSuccess from './components/PaymentSuccess.vue'
import { req, reqLoad, API_URL_MCH_STORE_LIST, $appPay, API_URL_PAY_ORDER_LIST } from "@/http/apiManager.js"
import infoBox from '@/commons/utils/infoBox.js'
import timer from '@/commons/utils/timer.js'
import go from '@/commons/utils/go.js'
import emit from '@/commons/utils/emit.js'
let payMethods = [
{name: '微信支付', url: '/static/pay/type-wx.svg'},
{name: '支付宝支付', url: '/static/pay/type-zfb.svg'},
{name: '银联云闪付', url: '/static/pay/type-ysf.svg'},
]
const paymentSuccessRef = ref()
const vdata = reactive({
qrImgUrl: '',
payAmount: 0,
payOrderId: '',
isUnload: false, // 是否已经销毁当前组件。
})
onLoad((options) => {
vdata.payAmount = options.payAmount
vdata.payOrderId = options.payOrderId
vdata.qrImgUrl = options.qrImgUrl
// 订单轮询
orderPollingByQR(vdata.payOrderId)
})
// 页面销毁需要将 定时任务结束。
onUnload(() => vdata.isUnload = true)
// 轮询查单 (聚合收款码)
function orderPollingByQR(payOrderId) {
// 总共查询几次
let allCount = 15
timer.startTimeoutTask(2, allCount, (subTime) => {
// 页面已销毁。
if(vdata.isUnload){
return false;
}
// 任务结束
if(subTime <= 0){
return infoBox.showToast('请于订单列表查询结果').then(() => {
emit.pageEmit(emit.ENAME_REF_PAY_ORDER) // 刷新订单数据
go.to('PAGES_PAY_ORDER', {}, go.GO_TYPE_SWITCHTAB)
})
}
return req.getById(API_URL_PAY_ORDER_LIST, payOrderId).then(( { bizData } ) => {
switch (bizData.state) {
case 2:
infoBox.showSuccessToast("支付成功")
paymentSuccessRef.value.open(bizData)
return Promise.reject()
break;
case 3:
infoBox.showToast('支付失败:' + bizData.errMsg, 3)
return Promise.reject()
break;
case 4:
infoBox.showErrorToast("订单撤销")
return Promise.reject()
break;
default:
return Promise.resolve()
break;
}
})
})
}
// 切换到扫一扫
const changeScan = () => {
// 先发射事件, 提示调起相机 。
emit.pageEmit(emit.ENAME_E_PAY_SCAN)
// 返回上一页, onShow调起。
nextTick(() => {
go.back();
})
}
</script>
<style scoped lang="scss">
.collection-code {
margin: 0 70rpx;
padding: 50rpx 0;
background-color: #eff2f7;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.img-box {
width: 370rpx;
height: 370rpx;
display: flex;
justify-content: center;
align-items: center;
background: #fff;
image {
width: 340rpx;
height: 340rpx;
}
}
.text {
width: 100%;
text-align: center;
padding: 50rpx 0;
margin: 50rpx 0;
color: #adb8cc;
position: relative;
view {
position: absolute;
width: 30%;
top: 30%;
left:35%;
background-color: #eff2f7;
z-index: 10;
}
&::before {
position: absolute;
top: 50%;
left:10%;
content: '';
height: 1px;
z-index: 1;
width: 80%;
background-color: #d5dbe6;
}
}
.pay-methods {
display: flex;
flex-direction: row;
justify-content: space-around;
width: 80%;
&>view {
width: 30%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-size: 22rpx;
color: #666F80;
image {
margin-bottom: 20rpx;
width: 50rpx;
height: 50rpx;
}
}
}
}
.scan {
position: fixed;
left: 0;
bottom: 60rpx;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
image {
width :60rpx;
height: 60rpx;
margin-bottom: 20rpx;
}
view {
font-size: 20rpx;
color: #666f80;
}
}
</style>

View File

@@ -1,258 +0,0 @@
<template>
<view class="quick-wrapper">
<view>
<view class="quick-money">
<text class="quick-title">收款金额</text>
<view class="quick-input">
<view class="quick-number">{{ vdata.payAmount }}</view>
<text></text>
</view>
</view>
<view class="quick-remarks-wrapper"><text class="quick-remarks" @tap="jeepayPopupInputRef.open()">添加备注</text></view>
</view>
<!-- 键盘页面 -->
<JKeyboard @selectedStore="selectedStore" @boardDown="boardDown" v-model:value="vdata.payAmount" :storeName="vdata.store.storeName" />
</view>
<!-- 备注弹层 -->
<JeepayPopupInput ref="jeepayPopupInputRef" label="备注" :maxLength="12" v-model:value="vdata.payRemark" />
<PaymentSuccess ref="paymentSuccessRef" @close="resetData" />
<JeepayBizinfoSelect ref="jeepayBizinfoSelect" />
</template>
<script setup>
import { ref, reactive } from 'vue'
import { onUnload, onShow } from '@dcloudio/uni-app'
import PaymentSuccess from './components/PaymentSuccess.vue'
import { req, reqLoad, API_URL_MCH_STORE_LIST, $appPay, API_URL_PAY_ORDER_LIST } from '@/http/apiManager.js'
import infoBox from '@/commons/utils/infoBox.js'
import timer from '@/commons/utils/timer.js'
import go from '@/commons/utils/go.js'
import emit from '@/commons/utils/emit.js'
const jeepayPopupInputRef = ref()
const paymentSuccessRef = ref()
const jeepayBizinfoSelect = ref()
const vdata = reactive({
payRemark: '', // 支付备注
payAmount: 0, // 支付金额
store: {}, //选择的门店
isUnload: false, // 页面是否已销毁。
isOpenScan: false, // 是否直接打开相机
})
// 页面销毁需要将 定时任务结束。
onUnload(() => {
vdata.isUnload = true
uni.$off(emit.ENAME_E_PAY_SCAN)
uni.$off(emit.ENAME_RESET_PAY_AMOUNT)
})
onShow(() => {
if (vdata.isOpenScan) {
// 打开相机
funObj.scan()
vdata.isOpenScan = false
} else {
// 其他页面进入, 需要金额初始化。
// 调起扫一扫, 会重新 onShow 暂时不重置金额。
// vdata.payAmount = 0; // 金额初始化
}
})
// 监听扫一扫, 之后需要在 onShow中调用。
uni.$on(emit.ENAME_E_PAY_SCAN, function (data) {
vdata.isOpenScan = true
})
uni.$on(emit.ENAME_RESET_PAY_AMOUNT, function (data) {
vdata.payAmount = 0
vdata.payRemark = ''
})
function reqTableDataByStoreFunc(params) {
return reqLoad.list(API_URL_MCH_STORE_LIST, params)
}
// 预先检查
function preCheckFunc(callbackFunc) {
if (isNaN(vdata.payAmount) || vdata.payAmount <= 0) {
infoBox.showToast('请输入金额')
return false
}
if (!vdata.store.storeId) {
infoBox.showToast('请选择门店')
selectedStore().then(() => {
if (callbackFunc) {
callbackFunc()
}
})
return false
}
return true
}
const funObj = {
scan: () => {
if (!preCheckFunc(funObj.scan)) {
return false
}
uni.scanCode().then(({ result }) => {
// 调起支付
$appPay(vdata.store.storeId, vdata.payAmount, vdata.payRemark, 'AUTO_BAR', result).then(({ bizData }) => {
processPayData(bizData, true)
})
})
},
code: () => {
if (!preCheckFunc(funObj.code)) {
return false
}
// 调起支付
$appPay(vdata.store.storeId, vdata.payAmount, vdata.payRemark, 'QR_CASHIER').then(({ bizData }) => {
// 处理支付结果
processPayData(bizData, false)
})
},
}
// 选择门店
const selectedStore = () => {
return jeepayBizinfoSelect.value.open(vdata.store).then((selected) => {
if (selected) {
vdata.store = selected
return Promise.resolve()
} else {
vdata.store = {}
return Promise.reject()
}
})
}
// 处理调起下单接口的返回数据
function processPayData(bizData, isScan) {
if (bizData.orderState == 2) {
// 成功
// 跳转到支付成功页面, 兼容payOrderInfo没有数据的情况。
let payOrderInfo = Object.assign(bizData, { state: bizData.orderState, amount: vdata.payAmount * 100 })
if (bizData.payOrderInfo) {
payOrderInfo = JSON.parse(bizData.payOrderInfo)
}
vdata.payAmount = 0
return paymentSuccessRef.value.open(payOrderInfo)
} else if (bizData.orderState == 3) {
// 成功
// 失败
return infoBox.showToast('失败:' + bizData.errMsg, 3)
} else {
// 聚合二维码方式 - 显示弹层
if (!isScan) {
return go.to('PAGES_QR_CASHIER', { qrImgUrl: bizData.payData, payOrderId: bizData.payOrderId, payAmount: vdata.payAmount })
}
// 仅scan 需要 轮询查单
return orderPollingByScan(bizData.payOrderId)
}
}
// 轮询查单 ( 扫一扫方式 )
function orderPollingByScan(payOrderId) {
// 总共查询几次
let allCount = 10
timer.startTimeoutTask(2, allCount, (subTime) => {
// 页面已销毁。
if (vdata.isUnload) {
return false
}
infoBox.showLoading(`等待付款, 第[${allCount - subTime}/${allCount}]次查单中...`)
// 任务结束
if (subTime <= 0) {
return infoBox.showToast('请于订单列表查询结果').then(() => {
emit.pageEmit(emit.ENAME_REF_PAY_ORDER) // 刷新订单数据
go.to('PAGES_PAY_ORDER', {}, go.GO_TYPE_SWITCHTAB)
})
}
return req.getById(API_URL_PAY_ORDER_LIST, payOrderId).then(({ bizData }) => {
switch (bizData.state) {
case 2:
infoBox.showSuccessToast('支付成功')
paymentSuccessRef.value.open(bizData)
return Promise.reject()
break
case 3:
infoBox.showToast('支付失败')
return Promise.reject()
break
case 4:
infoBox.showErrorToast('订单撤销')
return Promise.reject()
break
default:
return Promise.resolve()
break
}
})
})
}
const boardDown = (key) => {
if (['scan', 'code'].includes(key)) return funObj[key]()
}
// 成功清除数据
const resetData = () => {
vdata.payAmount = 0
vdata.payRemark = ''
}
</script>
<style lang="scss" scoped>
.quick-wrapper {
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: calc(100vh - 90rpx);
.quick-money {
margin: 0 auto;
margin-top: 50rpx;
width: 630rpx;
border-bottom: 1rpx solid rgba(0, 0, 0, 0.2);
.quick-title {
color: rgba(0, 0, 0, 0.5);
font-size: 30rpx;
}
.quick-input {
display: flex;
justify-content: space-between;
align-items: center;
height: 130rpx;
margin-top: 10rpx;
.quick-number {
flex: 1;
font-size: 60rpx;
font-weight: 500;
}
text {
align-self: flex-end;
transform: translateY(-30rpx);
font-weight: 700;
}
}
}
.quick-remarks-wrapper {
margin-top: 58rpx;
text-align: center;
font-size: 30rpx;
color: $J-color-t29;
}
}
</style>

View File

@@ -1,362 +0,0 @@
<template>
<view class="rekeaseMain">
<view class="main-title">
营销内容
</view>
<view class="banner-mian">
<view class="banner-list" v-for="(img,index) in imgList" :key="img">
<view class="banner-list-title">
{{index+1}}屏广告
</view>
<image :src="img.url" mode="" @click="previewImage(img.url)"></image>
<view class="del-box">
<view class="del-tip" @click="delImg(index)">
<image style="height: 30rpx;width: 30rpx;margin-top:0rpx;" src="../../static/img/del.svg"
mode=""></image>
<text>删除</text>
</view>
</view>
</view>
<view class="addimg-box" v-if="imgList.length<5">
<view class="addimg-title" @click="cjimg">
<image src="../../static/img/add.svg" mode=""></image>
<view class="">
加一屏广告
</view>
</view>
</view>
</view>
<view class="">
<button
style="background: linear-gradient(45deg, #17c5c6, #15ccb0);color: #fff;border: 0; margin-top: 20rpx; margin-bottom: 60rpx;"
@click="beforeUploadImg">发布营销内容</button>
</view>
<view class="main-title">
跑马灯内容
</view>
<view class="PMDtextarea-box" v-show="!changeImgFlag">
<textarea v-model="PMDtextarea" name="" id="" maxlength="20"
style="background:#f4f4f4; width:100%;height:150rpx; box-sizing: border-box; border-radius: 10rpx; padding: 20rpx;"></textarea>
<view class="PMDtextarea-num">
{{PMDtextarea.length}}/20
</view>
</view>
<view class="fontColor-select">
<text>选择字体颜色</text>
<view @click="changeFontColor('font')"
style="width: 50rpx;height: 50rpx;border-radius: 10rpx; margin-left: 50rpx;"
:style="{background:fontColor}"></view>
</view>
<view class="fontColor-select">
<text>选择背景颜色</text>
<view @click="changeFontColor('background')"
style="width: 50rpx;height: 50rpx;border-radius: 10rpx; margin-left: 50rpx;"
:style="{background:BackgroundColor}"></view>
</view>
<view class="">
<button
style="background: linear-gradient(45deg, #17c5c6, #15ccb0);color: #fff;border: 0; margin-top: 20rpx; margin-bottom: 60rpx;"
@click="releaseLamp">发布跑马灯</button>
</view>
<view class="">
<button
style="background:#d1f3f5;color: #4ac3c3;border: 1px solid #15ccb0; margin-top: 20rpx; margin-bottom: 60rpx;">查看效果</button>
</view>
<picker-color :isShow="showPickerColor" :bottom="0" @callback='getPickerColor' />
<view class="">
<l-clipper v-if="show" @success="successImg" @cancel="show = false" :width="800" :height="960"
:is-lock-width="true" :is-lock-height="true" />
<!-- <button @tap="show = true">裁剪</button> -->
</view>
</view>
</template>
<script>
import {
$pmdfb,
$getImgWH,
$initializeImg,
$NewOssFilesForm,
$uploadImg
} from "@/http/apiManager.js"
import pickerColor from "@/components/helang-pickerColor/helang-pickerColor.vue"
import storageManage from '@/commons/utils/storageManage.js'
export default {
components: {
"picker-color": pickerColor,
},
data() {
return {
imgList: [],
changeImgFlag: false,
PMDtextarea: '',
showPickerColor: false,
fontColor: '#000',
BackgroundColor: '#000',
colorType: '',
selectImgData: {},
imageUrl: 'https://img12.360buyimg.com/pop/s1180x940_jfs/t1/97205/26/1142/87801/5dbac55aEf795d962/48a4d7a63ff80b8b.jpg',
show: false,
url: '',
formParams: '',
isOss: '',
ossImgUrl: [],
OSSurl: '',
}
},
onLoad(options) {
this.picUrl = ''; // 初始化图片
this.getImgWH()
this.getInitializeIMG() //回显图片
},
methods: {
cjimg() {
this.show = true
},
successImg(e) {
console.log(e);
this.show = false
this.imgList.push({
url: e.url
})
},
async getImgWH() {
let res = await $getImgWH('QR939200003565')
console.log(res);
if (res.code === 0) {
this.picSizeH = res.bizData.picHeight
this.picSizeW = res.bizData.picWidth
}
},
async getInitializeIMG() {
let res = await $initializeImg('QR939200003565')
console.log(res);
if (res.code === 0) {
if (res.bizData.length > 1) {
res.bizData.map(item => {
this.imgList.push({
url: item.picName
})
})
}
}
},
async releaseLamp() {
let data = {
deviceNo: 'QR939200003565',
inputText: this.PMDtextarea,
fontColor: this.fontColor,
bgColor: this.BackgroundColor,
}
let res = await $pmdfb(data)
console.log(res);
},
getPickerColor(color) {
if (color) {
if (this.colorType === 'font') {
this.fontColor = color
} else {
this.BackgroundColor = color
}
}
this.showPickerColor = false
},
changeFontColor(type) {
this.colorType = type
this.showPickerColor = true
},
previewImage(url) {
console.log(url);
let data = {
urls: []
}
data.urls.push(url)
uni.previewImage(data)
},
changeImg() {
this.changeImgFlag = true
},
delImg(index) {
this.imgList.splice(index, 1)
},
beforeUploadImg() {
this.ossImgUrl = []
let that = this
this.imgList.map(img => {
uni.getFileInfo({
filePath: img.url,
async success(imgs) {
let res = await $NewOssFilesForm({
bizType: "applyment",
sourceFileName: img.url,
sourceFileSize: imgs.size,
})
that.OSSurl = res.bizData.formActionUrl
that.formParams = res.bizData.formParams
that.ossImgUrl.push(res.bizData.ossFileUrl)
that.isOss = true
}
})
})
setTimeout(()=>{
console.log(that.ossImgUrl);
that.uploadImg(that.imgList, that.OSSurl, that.formParams, that.isOss, that.ossImgUrl)
},1000)
},
uploadImg(tempFilePaths, url, formParams, isOss, ossImgUrl) {
console.log(tempFilePaths, url, formParams, isOss, ossImgUrl);
const token = storageManage.token()
var successCount = 0 //多图时,上传成功数量
var qualification = [] //多图存储
let carouselPicInfo = []
ossImgUrl.forEach((item)=>{
carouselPicInfo.push({
picName: item
})
})
console.log(carouselPicInfo);
uni.uploadFile({
url: url,
filePath: this.imgList[0],
name: "file",
header: {
itoken: token,
},
formData: this.formParams,
// 代表完成的函数 注:此处可以传入三个函数 success (成功)/ fail失败 / complete (完成)
// complete(res) {
// console.log(res,'resresres');
// $uploadImg({
// deviceNo: 'QR939200003565',
// carouselPicInfo: carouselPicInfo,
// }).then(({
// bizData
// }) => {
// console.log(bizData);
// })
// }
})
}
}
}
</script>
<style lang="scss" scoped>
.rekeaseMain {
padding: 20rpx;
.main-title {
line-height: 60rpx;
position: relative;
padding-left: 20rpx;
}
.main-title::after {
content: '';
display: block;
width: 8rpx;
background: #16c3c3;
height: 30rpx;
position: absolute;
left: 0;
top: 17rpx;
}
.banner-mian {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.banner-list {
width: 48%;
text-align: center;
height: 470rpx;
margin-top: 20rpx;
.banner-list-title {
background: #e7f9f9;
padding: 15rpx;
font-size: 24rpx;
color: #1ac3c7;
border-radius: 10rpx 10rpx 0 0;
height: 40rpx;
}
image {
width: 100%;
border-radius: 10rpx;
margin-top: -10rpx;
height: 340rpx;
}
.del-box {
display: flex;
justify-content: center;
margin-top: 16rpx;
.del-tip {
width: 40%;
background: #fce3df;
color: #f00;
border-radius: 30rpx;
border: 1px solid #f00;
font-size: 26rpx;
display: flex;
align-items: center;
justify-content: center;
padding: 4rpx;
}
}
}
.addimg-box {
width: 48%;
background: #f4f4f4;
border-radius: 10rpx;
display: flex;
align-items: center;
justify-content: center;
height: 400rpx;
margin-top: 20rpx;
.addimg-title {
display: flex;
flex-direction: column;
align-items: center;
image {
width: 50rpx;
height: 50rpx;
}
}
}
}
.PMDtextarea-box {
position: relative;
.PMDtextarea-num {
position: absolute;
right: 5rpx;
bottom: 10rpx;
}
}
.fontColor-select {
display: flex;
margin: 30rpx 0;
}
}
</style>

View File

@@ -1,377 +0,0 @@
<template>
<view class="rekeaseMain">
<view class="main-title">
营销内容
</view>
<view class="banner-mian">
<view class="banner-list" v-for="(img,index) in imgList" :key="img">
<view class="banner-list-title">
{{index+1}}屏广告
</view>
<image :src="img.url" mode="" @click="previewImage(img.url)"></image>
<view class="del-box">
<view class="del-tip" @click="delImg(index)">
<image style="height: 30rpx;width: 30rpx;margin-top:0rpx;" src="../../static/img/del.svg"
mode=""></image>
<text>删除</text>
</view>
</view>
</view>
<view class="addimg-box" v-if="imgList.length<5">
<view class="addimg-title" @click="cjimg">
<image src="../../static/img/add.svg" mode=""></image>
<view class="">
加一屏广告
</view>
</view>
</view>
</view>
<view class="">
<button
style="background: linear-gradient(45deg, #17c5c6, #15ccb0);color: #fff;border: 0; margin-top: 20rpx; margin-bottom: 60rpx;"
@click="uploadImg">发布营销内容</button>
</view>
<view class="main-title">
跑马灯内容
</view>
<view class="PMDtextarea-box" v-show="!changeImgFlag">
<textarea v-model="PMDtextarea" name="" id="" maxlength="20"
style="background:#f4f4f4; width:100%;height:150rpx; box-sizing: border-box; border-radius: 10rpx; padding: 20rpx;"></textarea>
<view class="PMDtextarea-num">
{{PMDtextarea.length}}/20
</view>
</view>
<view class="fontColor-select">
<text>选择字体颜色</text>
<view @click="changeFontColor('font')"
style="width: 50rpx;height: 50rpx;border-radius: 10rpx; margin-left: 50rpx;"
:style="{background:fontColor}"></view>
</view>
<view class="fontColor-select">
<text>选择背景颜色</text>
<view @click="changeFontColor('background')"
style="width: 50rpx;height: 50rpx;border-radius: 10rpx; margin-left: 50rpx;"
:style="{background:BackgroundColor}"></view>
</view>
<view class="">
<button
style="background: linear-gradient(45deg, #17c5c6, #15ccb0);color: #fff;border: 0; margin-top: 20rpx; margin-bottom: 60rpx;"
@click="releaseLamp">发布跑马灯</button>
</view>
<view class="">
<button
style="background:#d1f3f5;color: #4ac3c3;border: 1px solid #15ccb0; margin-top: 20rpx; margin-bottom: 60rpx;">查看效果</button>
</view>
<picker-color :isShow="showPickerColor" :bottom="0" @callback='getPickerColor' />
<view class="">
<l-clipper v-if="show" @success="successImg" @cancel="show = false"
:width="800" :height="960"/>
<!-- <button @tap="show = true">裁剪</button> -->
</view>
</view>
</template>
<script>
import {
$pmdfb,
$getImgWH,
$initializeImg,
$NewOssFilesForm,
$uploadImg
} from "@/http/apiManager.js"
import pickerColor from "@/components/helang-pickerColor/helang-pickerColor.vue"
import storageManage from '@/commons/utils/storageManage.js'
export default {
components: {
"picker-color": pickerColor,
},
data() {
return {
imgList: [],
changeImgFlag: false,
PMDtextarea: '',
showPickerColor: false,
fontColor: '#000',
BackgroundColor: '#000',
colorType: '',
selectImgData: {},
imageUrl: 'https://img12.360buyimg.com/pop/s1180x940_jfs/t1/97205/26/1142/87801/5dbac55aEf795d962/48a4d7a63ff80b8b.jpg',
show: false,
url: '',
formParams: '',
isOss: '',
ossImgUrl: [],
OSSurl: '',
UploadImgList:[],
deviceNo:null,
}
},
onLoad(options) {
console.log(options,'deviceNodeviceNodeviceNodeviceNo');
if(options.deviceNo){
this.deviceNo=options.deviceNo
}
this.picUrl = ''; // 初始化图片
this.getImgWH()
this.getInitializeIMG() //回显图片
},
methods: {
cjimg() {
this.show = true
},
successImg(e) {
console.log(e);
this.show = false
this.imgList.push({
url: e.url
})
this.beforeUploadImg(e.url)
},
async getImgWH() {
let res = await $getImgWH(this.deviceNo)
console.log(res);
if (res.code === 0) {
this.picSizeH = res.bizData.picHeight
this.picSizeW = res.bizData.picWidth
}
},
async getInitializeIMG() {
let res = await $initializeImg(this.deviceNo)
console.log(res);
if (res.code === 0) {
if (res.bizData) {
res.bizData.map(item => {
this.imgList.push({
url: item.picName
})
})
}
}
},
async releaseLamp() {
let data = {
deviceNo: this.deviceNo,
inputText: this.PMDtextarea,
fontColor: this.fontColor,
bgColor: this.BackgroundColor,
}
let res = await $pmdfb(data)
console.log(res);
},
getPickerColor(color) {
if (color) {
if (this.colorType === 'font') {
this.fontColor = color
} else {
this.BackgroundColor = color
}
}
this.showPickerColor = false
},
changeFontColor(type) {
this.colorType = type
this.showPickerColor = true
},
previewImage(url) {
console.log(url);
let data = {
urls: []
}
data.urls.push(url)
uni.previewImage(data)
},
changeImg() {
this.changeImgFlag = true
},
delImg(index) {
this.imgList.splice(index, 1)
this.UploadImgList.splice(index,1)
},
beforeUploadImg(urls) {
let that=this
uni.getFileInfo({
filePath: urls,
success: (imgs) => {
console.log(imgs,'sourceFileNamesourceFileName');
$NewOssFilesForm({
bizType: "applyment",
// bizType: "material",
sourceFileName: urls,
sourceFileSize: imgs.size,
}).then(({
bizData
}) => {
console.log(bizData);
const token = storageManage.token()
let url=bizData.formActionUrl
let ossFileUrl=bizData.ossFileUrl
//调用图片上传方法
uni.uploadFile({
url: url,
filePath: urls,
name: "file",
header: {
itoken: token,
},
formData: bizData.formParams,
// 代表完成的函数 注:此处可以传入三个函数 success (成功)/ fail失败 / complete (完成)
complete(res) {
console.log(res);
if(res.statusCode===200){
that.UploadImgList.push(ossFileUrl)
}
}
})
})
}
})
},
uploadImg() {
let carouselPicInfo=[]
this.imgList.forEach(item=>{
if(item.url.indexOf('aliyuncs')!==-1){
carouselPicInfo.push({
picName:item.url
})
}
})
this.UploadImgList.forEach(item=>{
carouselPicInfo.push({
picName:item
})
})
$uploadImg({
deviceNo:this.deviceNo,
carouselPicInfo:carouselPicInfo,
}).then(res=>{
uni.showToast({
title: '发布成功',
//将值设置为 success 或者直接不用写icon这个参数
icon: 'success',
//显示持续时间为 2秒
duration: 1000
})
})
}
}
}
</script>
<style lang="scss" scoped>
.rekeaseMain {
padding: 20rpx;
.main-title {
line-height: 60rpx;
position: relative;
padding-left: 20rpx;
}
.main-title::after {
content: '';
display: block;
width: 8rpx;
background: #16c3c3;
height: 30rpx;
position: absolute;
left: 0;
top: 17rpx;
}
.banner-mian {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.banner-list {
width: 48%;
text-align: center;
height: 470rpx;
margin-top: 20rpx;
.banner-list-title {
background: #e7f9f9;
padding: 15rpx;
font-size: 24rpx;
color: #1ac3c7;
border-radius: 10rpx 10rpx 0 0;
height: 40rpx;
}
image {
width: 100%;
border-radius: 10rpx;
margin-top: -10rpx;
height: 340rpx;
}
.del-box {
display: flex;
justify-content: center;
margin-top: 16rpx;
.del-tip {
width: 40%;
background: #fce3df;
color: #f00;
border-radius: 30rpx;
border: 1px solid #f00;
font-size: 26rpx;
display: flex;
align-items: center;
justify-content: center;
padding: 4rpx;
}
}
}
.addimg-box {
width: 48%;
background: #f4f4f4;
border-radius: 10rpx;
display: flex;
align-items: center;
justify-content: center;
height: 400rpx;
margin-top: 20rpx;
.addimg-title {
display: flex;
flex-direction: column;
align-items: center;
image {
width: 50rpx;
height: 50rpx;
}
}
}
}
.PMDtextarea-box {
position: relative;
.PMDtextarea-num {
position: absolute;
right: 5rpx;
bottom: 10rpx;
}
}
.fontColor-select {
display: flex;
margin: 30rpx 0;
}
}
</style>

View File

@@ -2,7 +2,7 @@
<view class="page-wrapper">
<view class="page-cell">
<view class="label">头像</view>
<view class="right" @tap="uploadImg.preview()">
<view class="right">
<up-avatar class="fileImg" :src="vdata.shopInfo.coverImg?vdata.shopInfo.coverImg:''" mode="aspectFill"></up-avatar>
<view class="file" @tap="chooseAndUploadAvatar('coverImg')"></view>
</view>
@@ -34,11 +34,11 @@
</view> -->
<view class="page-cell">
<view class="label">允许打包</view>
<view class="right"><up-switch v-model="vdata.takeout" size="20"activeColor="#0FC161" @change="switchChange('eatModel')"></up-switch></view>
<view class="right"><up-switch v-model="vdata.takeout" size="20" activeColor="#0FC161" @change="switchChange('eatModel')"></up-switch></view>
</view>
<view class="page-cell m">
<view class="label">是否开启会员支付</view>
<view class="right"><up-switch v-model="vdata.shopInfo.isUseVip" size="20" :inactiveValue="0" :activeValue="1" activeColor="#0FC161" @change="switchChange('isUseVip')"></up-switch></view>
<view class="right"><up-switch v-model="vdata.shopInfo.isAccountPay" size="20" :inactiveValue="0" :activeValue="1" activeColor="#0FC161" @change="switchChange('isAccountPay')"></up-switch></view>
</view>
<view class="page-cell">
@@ -62,6 +62,7 @@
:key="index"
:label="item.name"
:name="item.value"
activeColor="#0FC161"
@change="radioChange"
>
</up-radio>
@@ -112,24 +113,25 @@
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { onShow } from '@dcloudio/uni-app';
import { getShopInfo , editShopInfo, getShopExtend, editShopExtend } from '@/http/yskApi/shop.js'
// import { getShopInfo , editShopInfo, getShopExtend, editShopExtend } from '@/http/yskApi/shop.js'
import storageManage from '@/commons/utils/storageManage.js'
import go from '@/commons/utils/go.js'
import infoBox from '@/commons/utils/infoBox.js'
import { $uploadFile } from '@/http/yskApi/file.js'
import { uploadFile } from '@/api/index.js'
import { getShopInfo, editShopInfo } from '@/api/shop.js'
import { forIn } from 'lodash';
const uploadImg = ref()
const phone = ref(null)
const vdata = reactive({
shopInfo: {
status: 2,
isUseVip: 0,
isAccountPay: 0,
},
extendList: [],
registerTypeList: [
{name: "先付费", value: "munchies"},
{name: "后付费", value: "restaurant"}
{name: "先付费", value: "before"},
{name: "后付费", value: "after"}
],
extendIndex: 0,
extendInfo: {},
@@ -144,7 +146,7 @@ const vdata = reactive({
})
onMounted(() => {
shopExtend();
// shopExtend();
})
onShow(() => {
@@ -173,15 +175,16 @@ let refreshData = (e) => {
* 获取店铺信息
*/
const shopInfo = () => {
getShopInfo(storageManage.shopId()).then((res) => {
getShopInfo({id:uni.getStorageSync('shopInfo').id}).then((res) => {
vdata.isTableFee = res.isTableFee == 1 ? true: false;
if (res.eatModel.join(",").indexOf("dine-in") != -1) {
if (res.eatModel.split(",").indexOf("dine-in") != -1) {
vdata.dineIn = true
}
if (res.eatModel.join(",").indexOf("take-out") != -1) {
if (res.eatModel.split(",").indexOf("take-out") != -1) {
vdata.takeout = true
}
vdata.shopInfo = res;
console.log(vdata.shopInfo)
})
}
@@ -246,10 +249,10 @@ let chooseAndUploadAvatar = ( type ) => {
success: (res) => {
let file = res.tempFiles[0];
console.log(res)
$uploadFile(file).then(res => {
uploadFile(file).then(res => {
console.log(res);
if ( type == "coverImg") {
vdata.shopInfo.coverImg = res.data[0];
vdata.shopInfo.coverImg = res;
let params = {
id : vdata.shopInfo.id,
coverImg : vdata.shopInfo.coverImg,
@@ -257,7 +260,7 @@ let chooseAndUploadAvatar = ( type ) => {
updateShopInfo(params)
}
if ( type == "extendUp") {
vdata.extendInfo.value = res.data[0];
vdata.extendInfo.value = res;
updateShopExtend()
}
@@ -306,6 +309,7 @@ let switchChange = ( type ) => {
let params = {
id : vdata.shopInfo.id,
}
console.log(vdata.shopInfo)
switch ( type ){
case "address":
params.lng = vdata.shopInfo.lng;
@@ -323,9 +327,10 @@ let switchChange = ( type ) => {
if ( vdata.takeout ) {
params.eatModel.push('take-out');
}
params.eatModel = params.eatModel.join(',')
break;
case "isUseVip":
params.isUseVip = vdata.shopInfo.isUseVip;
case "isAccountPay":
params.isAccountPay = vdata.shopInfo.isAccountPay;
break;
case "isTableFee":
if ( vdata.isTableFee ) {

View File

@@ -39,7 +39,7 @@
<script setup>
import { nextTick, reactive, ref } from 'vue';
import { onReachBottom, onShow, onUnload } from '@dcloudio/uni-app';
import ak from '@/commons/utils/ak.js';
import go from '@/commons/utils/go.js';
import { getShopList } from '@/http/yskApi/shop.js'
const vdata = reactive({
@@ -62,7 +62,7 @@ let getshopList = () => {
let createStore = () => {
ak.go.back(1)
go.back(1)
};
</script>
<style lang="scss" scoped>

View File

@@ -1,150 +0,0 @@
<template>
<view class="info-wrapper">
<view class="dev-title" v-if="dev" @tap="devType.open(vdata.devTitle.value)">
{{ vdata.devTitle.label }}
<image src="/static/iconImg/icon-arrow-black.svg" mode="scaleToFill" />
</view>
<view class="info-title" :class="{ 'fixed-header': fixed }">
<block v-for="(v, i) in vdata.titleList" :key="i">
<view class="info-item" :class="{ 'active-title': vdata.selected == v.value }" @tap="selectedTitle(v)">
{{ v.title }}
<view class="stat-sort" :class="[calcClassName(v)]"></view>
</view>
</block>
</view>
<!-- 默认插槽位置 -->
<slot />
</view>
<JSinglePopup :list="devTypeList" ref="devType" @confirm="confirmType" />
</template>
<script setup>
import { reactive, ref } from 'vue';
const props = defineProps({
dev: { type: Boolean, default: false }, //是否展示设备类型切换标题
fixed: { type: Boolean, default: false } //是否固定头部 默认 false
});
const emits = defineEmits(['device', 'sortClick']);
const vdata = reactive({
selected: 'totalSuccAmt',
devTitle: {
label: '全部设备类型',
value: ''
},
titleList: [
{ title: '成交金额', value: 'totalSuccAmt', sort: 'ascend' },
{ title: '退款金额', value: 'totalRefundAmt', sort: 'ascend' },
{ title: '成交笔数', value: 'totalSuccNum', sort: 'ascend' },
{ title: '成功率', value: 'succRate', sort: 'ascend' }
]
});
const devType = ref(null);
const selectedTitle = (val) => {
if (vdata.selected != val.value) {
vdata.selected = val.value;
emits('sortClick', val);
return;
}
val.sort = val.sort == 'ascend' ? 'descend' : 'ascend';
emits('sortClick', val);
};
const devTypeList = reactive([
{ label: '全部', value: '' },
{ label: '电子码牌', value: '0' },
{ label: '实体码牌', value: '1' },
{ label: '实体立牌', value: '2' },
{ label: '云音响码牌', value: '3' },
{ label: '扫码POS', value: 'scan_pos"' },
{ label: '智能POS', value: 'auto_pos"' },
{ label: '收银插件', value: 'cash_plugin' }
]);
// 计算需要展示的上下箭头
const calcClassName = (val) => {
// 判断 选中 与 集合中的 value 值是否相等 不相等 则不添加类名
if (vdata.selected == val.value) {
// 返回上箭头 下箭头类名
return val.sort == 'descend' ? 'asc-sort' : 'des-sort';
}
return '';
};
const confirmType = (val) => {
vdata.devTitle = val;
emits('device', val.value);
};
</script>
<style lang="scss" scoped>
.info-wrapper {
margin: 0 35rpx 40rpx 35rpx;
border-radius: $J-b-r32;
background-color: $J-bg-ff;
.dev-title {
display: flex;
align-items: center;
padding: 0 30rpx;
height: 100rpx;
font-size: 30rpx;
background-color: #fff;
border-bottom: 1rpx solid #ededed;
image {
margin-left: 10rpx;
width: 40rpx;
height: 40rpx;
transform: rotate(180deg);
}
}
.info-title {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 40rpx;
height: 102rpx;
font-size: 24rpx;
color: $J-color-t80;
background-color: #fff;
border-bottom: 1rpx solid #ededed;
.active-title {
font-weight: 500;
color: #2980fd;
border-bottom: 5rpx solid #2980fd;
}
.info-item {
display: flex;
align-items: center;
height: 100%;
.stat-sort {
display: flex;
flex-direction: column;
align-items: center;
margin-left: 10rpx;
&::before,
&::after {
content: '';
display: block;
width: 0px;
height: 0px;
border: 8rpx solid;
border-color: #d9d9d9 transparent transparent transparent;
}
&::before {
margin-bottom: 4rpx;
transform: rotate(180deg);
}
}
.asc-sort::before {
border-color: #2980fd transparent transparent transparent;
}
.des-sort::after {
border-color: #2980fd transparent transparent transparent;
}
}
}
}
.fixed-header {
position: sticky;
top: 112rpx;
z-index: 10;
left: 0;
right: 0;
}
</style>

View File

@@ -1,50 +0,0 @@
<template>
<view class="store-wrapper">
<view class="store-left">
<image :src="storeImg" mode="scaleToFill" />
{{ storeName }}
</view>
<view class="store-right">
<text>{{ storeNum }}</text>
<slot />
</view>
</view>
</template>
<script setup>
const props = defineProps({
storeName: { type: String }, //门店名称
storeImg: { type: String }, //门店照片
storeNum: { type: Number }, //收款金额
})
</script>
<style lang="scss" scoped>
.store-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 30rpx;
height: 100rpx;
.store-left {
display: flex;
align-items: center;
font-size: 26rpx;
color: #666;
image {
margin-right: 10rpx;
width: 40rpx;
height: 40rpx;
}
}
.store-right {
display: flex;
align-items: center;
font-size: 30rpx;
font-weight: 500;
text {
margin-right: 10rpx;
}
}
}
</style>

View File

@@ -1,113 +0,0 @@
<template>
<uni-popup ref="popup" type="bottom" mask-background-color="rgba(0,0,0,.5)" @change="change" :safe-area="false">
<view class="info-wrapper">
<view class="info-title">
<text>支付方式统计明细</text>
<view class="icon-close" @tap="popup.close()"><image src="/static/iconImg/icon-x.svg" mode="scaleToFill" /></view>
</view>
<StatInfoCard @sortClick="switchField" :fixed="true">
<JTableList ref="refTable" :reqTableDataFunc="reqTableDataFunc" :initData="false" height="220rpx" :searchData="vdata.params">
<template #tableBody="{ record }">
<statCell
:imgNone="false"
:title="record.wayCode"
:money="calcData(record[vdata.cardSelected])"
:reality="calcReality(record.totalSuccNum, record.totalNum)"
:round="vdata.cardSelected == 'round'"
:iconPre="vdata.cardSelected == 'totalFinalAmt' || vdata.cardSelected == 'totalRefundAmt '"
:iconNext="vdata.cardSelected == 'round'"
/>
</template>
</JTableList>
</StatInfoCard>
</view>
</uni-popup>
</template>
<script setup>
import { nextTick, onMounted, reactive, ref, inject } from 'vue';
import { onReachBottom } from '@dcloudio/uni-app';
import { $getStatistic } from '@/http/apiManager.js';
import StatInfoCard from './StatInfoCard.vue';
import statCell from './statCell.vue';
import cal from '@/commons/utils/cal.js';
// 获取弹窗实例
const popup = ref(null);
const refTable = ref(null);
const vdata = reactive({
cardSelected: 'totalFinalAmt',
record: {},
params: {}
});
const open = (params, record) => {
const obj = JSON.parse(JSON.stringify(params));
vdata.record = record;
obj.wayCodeType = record.wayType;
obj.method = 'wayCode';
vdata.params = obj;
popup.value.open();
nextTick(() => {
refTable.value.refTable(true);
});
};
const reqTableDataFunc = (params) => {
return $getStatistic(params);
};
//切换字段 切换排序
const switchField = (val) => {
vdata.cardSelected = val.value;
vdata.params.sortOrder = val.sort;
vdata.params.sortField = val.value;
refTable.value.refTable(true);
};
// 计算数据需不需要除以 100
const calcData = (val) => {
if (vdata.cardSelected == 'totalFinalAmt' || vdata.cardSelected == 'totalRefundAmt') return cal.cert2Dollar(val);
return val;
};
// 计算进度条
const calcReality = (val, totalNum) => {
return (val / totalNum) * 100;
};
let changePageMetaOverflowFunc = inject('changePageMetaOverflowFunc');
const change = (e) => {
if (changePageMetaOverflowFunc) {
changePageMetaOverflowFunc(!e.show);
}
};
onReachBottom(() => {});
defineExpose({ open });
</script>
<style lang="scss" scoped>
.info-wrapper {
height: 70vh;
overflow-y: scroll;
border-radius: 32rpx 32rpx 0 0;
background-color: #fff;
}
.info-title {
position: sticky;
top: 0;
left: 0;
right: 0;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 40rpx;
height: 110rpx;
font-size: 30rpx;
font-weight: 500;
border-bottom: 1rpx solid #ededed;
.icon-close {
width: 50rpx;
height: 50rpx;
border-radius: 10rpx;
background-color: #f2f2f2;
image {
width: 100%;
height: 100%;
}
}
}
</style>

View File

@@ -1,98 +0,0 @@
<template>
<view class="pay-wrapper">
<view class="pay-left">
<template v-if="imgNone">
<image v-if="devImage" :src="imgObj[devImage]" mode="scaleToFill" />
<image v-else :src="imgUrl" mode="scaleToFill" />
</template>
<view>{{ imgUrl }}</view>
<view class="pay-title single-text-beyond">{{ title }}</view>
</view>
<view class="pro-bar" :style="{ '--bar-width': reality + '%' }" v-if="round"></view>
<view class="pay-right">
<text v-show="iconPre"></text>
{{ money }}
<text v-show="iconNext">%</text>
</view>
</view>
</template>
<script setup>
import { reactive } from 'vue';
const props = defineProps({
reality: [String, Number], //实际进度
imgUrl: { type: String }, //左侧图片
title: { type: String }, //左侧标题
money: [String, Number], //右侧金额
round: { type: Boolean, default: false }, //是否展示进度条
iconPre: { type: Boolean, default: false }, //金钱
iconNext: { type: Boolean, default: false }, // 百分比
devImage: { type: String }, //如果设备
imgNone: { type: Boolean, default: true } //不需要图片
});
const imgObj = reactive({
store: '/static/indexImg/icon-store.svg', //门店
qr_code: '/static/devIconImg/icon-code.svg',
scan_pos: '/static/devIconImg/icon-pos.svg',
auto_pos: '/static/devIconImg/icon-scanPos.svg',
cash_plugin: '/static/devIconImg/icon-horn.svg',
face_app: '/static/devIconImg/icon-face-1.svg', //刷脸设备
ALIPAY: '/static/payImg/icon-zfb.svg', //支付宝
OTHER: '/static/payImg/icon-qt.svg', //其他
DCEPPAY: '/static/payImg/icon-qt.svg', //数字人民币
UNIONPAY: '/static/payImg/icon-yl.svg', //银联
WECHAT: '/static/payImg/icon-wx.svg', //微信
YSFPAY: '/static/payImg/icon-ysf.svg' //云闪付
});
</script>
<style lang="scss" scoped>
.pay-wrapper {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 30rpx;
height: 100rpx;
.pay-left {
flex: 1;
display: flex;
align-items: center;
font-size: 26rpx;
color: #666;
image {
margin-right: 10rpx;
width: 40rpx;
height: 40rpx;
}
.pay-title {
width: 178rpx;
}
}
.pro-bar {
flex-grow: 0;
flex-shrink: 0;
position: relative;
width: 100rpx;
height: 6rpx;
background-color: rgba(0, 0, 0, 0.1);
border-radius: 6rpx;
&::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: var(--bar-width);
height: 100%;
border-radius: 6rpx;
background: $jeepay-bg-primary;
}
}
.pay-right {
flex: 1;
text-align: right;
font-size: 30rpx;
font-weight: 500;
}
}
</style>

View File

@@ -1,203 +0,0 @@
<template>
<uni-popup ref="popup" type="bottom" mask-background-color="rgba(0,0,0,.5)" @change="change" :safe-area="false">
<view class="info-wrapper">
<view class="info-title">
<!-- <image :src="imgObj[vdata.record.deviceType]" mode="scaleToFill" /> -->
<view class="info-content">
<view class="info-name">
<text>{{ vdata.record?.storeName || vdata.record?.deviceName }}</text>
<view class="icon-close" @tap="popup.close()">
<image src="/static/iconImg/icon-x.svg" mode="scaleToFill" />
</view>
</view>
<view class="sub-name">{{ vdata.record?.storeId || vdata.record?.deviceNo }}</view>
</view>
</view>
<view class="stat-card">
<view class="stat-money">
<view class="stat-title">入账金额 ()</view>
<view class="stat-num-title">{{ cal.cert2Dollar(vdata.totalSuccAmt - vdata.totalFeeAmt - vdata.totalRefundAmt) }}</view>
</view>
<view class="stat-card-info">
<view class="stat-item">
<view class="stat-title">成交订单金额 ()</view>
<view class="stat-num">{{ cal.cert2Dollar(vdata.totalSuccAmt) }}</view>
</view>
<view class="stat-item">
<view class="stat-title">成交订单笔数</view>
<view class="stat-num">{{ vdata.totalSuccNum }}</view>
</view>
<view class="stat-item">
<view class="stat-title">交易成功率</view>
<view class="stat-num">{{ vdata.succRate }}%</view>
</view>
<view class="stat-item">
<view class="stat-title">交易手续费</view>
<view class="stat-num">{{ cal.cert2Dollar(vdata.totalFeeAmt) }}</view>
</view>
<!-- <view class="stat-item">
<view class="stat-title">垫资手续费</view>
<view class="stat-num">---</view>
</view> -->
<!-- <view class="stat-item">
<view class="stat-title">优惠金额</view>
<view class="stat-num">{{ cal.cert2Dollar(vdata.totalDiscountAmt) }}%</view>
</view> -->
<view class="stat-item">
<view class="stat-title">退款金额 ()</view>
<view class="stat-num">{{ cal.cert2Dollar(vdata.totalRefundAmt) }}</view>
</view>
<view class="stat-item">
<view class="stat-title">退款笔数</view>
<view class="stat-num">{{ vdata.totalRefundNum }}</view>
</view>
<!-- <view class="stat-item">
<view class="stat-title">补贴金额</view>
<view class="stat-num">---</view>
</view> -->
<!-- <view class="stat-item">
<view class="stat-title">交易成功笔数</view>
<view class="stat-num">{{ vdata.totalSuccNum }}</view>
</view>
<view class="stat-item">
<view class="stat-title">成功交易金额 ()</view>
<view class="stat-num">{{ cal.cert2Dollar(vdata.totalSuccAmt) }}</view>
</view>
<view class="stat-item">
<view class="stat-title">总交易笔数</view>
<view class="stat-num">{{ vdata.totalNum }}</view>
</view> -->
</view>
</view>
</view>
</uni-popup>
</template>
<script setup>
import { onMounted, reactive, ref, inject } from 'vue';
import { $getStatInfo, $getStatistic } from '@/http/apiManager.js';
import cal from '@/commons/utils/cal.js';
// 获取弹窗实例
const popup = ref(null);
const vdata = reactive({
record: {}
});
const imgObj = reactive({
store: '/static/indexImg/icon-store.svg',
qr_code: '/pageDevice/static/devIconImg/icon-code.svg',
scan_pos: '/pageDevice/static/devIconImg/icon-pos.svg',
auto_pos: '/pageDevice/static/devIconImg/icon-scanPos.svg',
cash_plugin: '/pageDevice/static/devIconImg/icon-horn.svg'
});
const getInfo = (params) => {
$getStatInfo(params).then(({ bizData }) => {
Object.assign(vdata, bizData);
});
};
const open = (params, record) => {
const obj = JSON.parse(JSON.stringify(params));
vdata.record = record;
if (!vdata.record.deviceType) vdata.record.deviceType = 'store';
obj.deviceNo = record.deviceNo ? record.deviceNo : '';
obj.storeId = record.storeId ? record.storeId : '';
getInfo(obj);
popup.value.open();
};
let changePageMetaOverflowFunc = inject('changePageMetaOverflowFunc');
const change = (e) => {
if (changePageMetaOverflowFunc) {
changePageMetaOverflowFunc(!e.show);
}
};
defineExpose({ open });
</script>
<style lang="scss" scoped>
.info-wrapper {
// height: 777rpx;
border-radius: 32rpx 32rpx 0 0;
background-color: #fff;
padding-bottom: 32upx;
}
.info-title {
display: flex;
align-items: center;
padding: 0 40rpx;
height: 160rpx;
border-bottom: 1rpx solid #ededed;
image {
margin-right: 20rpx;
width: 100rpx;
height: 100rpx;
}
.info-content {
flex: 1;
.info-name {
display: flex;
justify-content: space-between;
font-size: 30rpx;
font-weight: 500;
.icon-close {
width: 50rpx;
height: 50rpx;
border-radius: 10rpx;
background-color: #f2f2f2;
image {
width: 100%;
height: 100%;
}
}
}
.sub-name {
font-size: 26rpx;
color: #808080;
}
}
}
.stat-card {
position: relative;
margin: 0 30rpx;
background-color: $J-bg-ff;
border-radius: $J-b-r32;
.stat-title {
white-space: nowrap;
margin-bottom: 10rpx;
font-size: 24rpx;
color: #a6a6a6;
}
.stat-money {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 202rpx;
box-shadow: 0 50rpx 70rpx -60rpx rgba(107, 130, 153, 0.2);
.stat-num-title {
font-size: 60rpx;
font-weight: 700;
color: #2980fd;
}
}
.stat-card-info {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
padding: 0 68rpx 50rpx 68rpx;
.stat-item {
width: 175rpx;
margin-top: 50rpx;
text-align: center;
.stat-num {
font-size: 30rpx;
font-weight: 700;
}
}
}
.stat-tips {
position: absolute;
top: 30rpx;
right: 30rpx;
}
}
</style>

View File

@@ -1,522 +0,0 @@
<template>
<JeepayBackground :bgColorStyle="{ background: 'linear-gradient(270deg,#238FFC 0%, #1A66FF 100%)' }">
<view>
<JeepayCustomNavbar title="统计报表" textColor="#fff" bgDefaultColor="linear-gradient(270deg,#238FFC 0%, #1A66FF 100%)" backCtrl="back" />
<!-- 统计时间选择部分 -->
<view class="screen-time">
<block v-for="(v, i) in screenList" :key="i">
<view class="time-main" :class="{ 'active-screen': vdata.selected == v.value }" @tap="selectedTime(v)">{{ v.title }}</view>
</block>
</view>
<template v-if="vdata.selected == 'custom'">
<view class="time-selection time-custom">
<image src="/static/iconImg/icon-calendar.svg" mode="scaleToFill" />
<view class="selection-main" @tap="startTime.show()">{{ vdata.startTime || '请选择开始时间' }}</view>
<view style="color: #fff">---</view>
<view class="selection-main" @tap="endTime.show()">{{ vdata.endTime || '请选择结束时间' }}</view>
<image src="/static/iconImg/icon-arrow-downWhite.svg" mode="scaleToFill" />
</view>
</template>
<view class="time-selection flex-center" v-else @tap="timeSelected.show()">
<image src="/static/iconImg/icon-calendar.svg" mode="scaleToFill" />
<view class="selection-main">
{{ vdata.time }}
<text v-if="isToDay()">今天</text>
</view>
<image src="/static/iconImg/icon-arrow-downWhite.svg" mode="scaleToFill" />
</view>
<!-- 统计卡片部分 -->
<view class="stat-card" @click="go.to('PAGES_PAY_ORDER', {}, 'switchTab')">
<view class="stat-money">
<view class="stat-title">入账金额 ()</view>
<view class="stat-num-title">{{ vdata.totalFinalAmt }}</view>
<view class="stat-tips"><uni-icons type="help-filled" size="20" color="#c6c6c6" @tap.stop="openTips()" /></view>
</view>
<view class="stat-card-info">
<block v-for="(v, i) in vdata.infoList" :key="i">
<view class="stat-item">
<view class="stat-title">{{ v.title }}</view>
<view class="stat-num" v-if="v.value == 'totalSuccAmt' || v.value == 'totalFeeAmt' || v.value == 'totalRefundAmt'">
{{ cal.cert2Dollar(v.text) }}
</view>
<view class="stat-num" v-else>
<template v-if="v.value == 'succRate'">{{ v.text }}%</template>
<template v-else>{{ v.text }}</template>
</view>
</view>
</block>
</view>
</view>
<!-- 统计选择门店等方式部分 -->
<view class="stat-selection">
<block v-for="v in vdata.statList" :key="v.value">
<view class="stat-item" :class="{ 'active-stat': vdata.statSelected == v.value }" @tap="switchStatType(v.value)">{{ v.title }}</view>
</block>
</view>
<StatInfoCard :dev="vdata.statSelected == 'device'" @sortClick="switchField" @device="switchDevType">
<JeepayTableList ref="refTable" :reqTableDataFunc="reqTableDataFunc" :searchData="params" :showListNull="false">
<template #tableBody="{ record }">
<statCell
:reality="record.succRate"
:title="record[vdata.namObj[vdata.statSelected]]"
:money="money(record)"
round
:iconPre="vdata.cardSelected == 'totalSuccAmt' || vdata.cardSelected == 'totalRefundAmt'"
:iconNext="vdata.cardSelected == 'succRate'"
:devImage="vdata.statSelected == 'wayCodeType' ? record.wayType : vdata.statSelected == 'store' ? 'store' : record.deviceType"
@tap="showDetail(params, record)"
></statCell>
</template>
</JeepayTableList>
</StatInfoCard>
<!-- 占位 -->
<view class="store-block"></view>
<!-- 选择门店按钮 -->
<view class="store-name" @tap="selectedStore">
{{ vdata.store?.storeName }}
<image src="/static/iconImg/icon-arrow-black.svg" mode="scaleToFill" />
</view>
<JeepayBizinfoSelect :isShowAllBiz="true" ref="jeepayPopupListSelect" />
<JTipsPopupContent ref="tips" title="统计释义" buttonText="我知道了" @cancel="vdata.flag = true">
<block v-for="(v, i) in tipsList" :key="i">
<view class="tips-wrapper">
<view class="tips-title">{{ v.title }}</view>
<view class="tips-info">{{ v.info }}</view>
</view>
</block>
</JTipsPopupContent>
<xp-picker @confirm="dayConfirm" ref="timeSelected" mode="ymd" v-if="vdata.selected == 'date'" />
<xp-picker @confirm="dayConfirm" ref="timeSelected" mode="ym" v-if="vdata.selected == 'month'" />
<xp-picker @confirm="dayConfirm" ref="timeSelected" mode="y" v-if="vdata.selected == 'year'" />
<xp-picker ref="startTime" mode="ymd" @confirm="customTime($event, 'startTime')" />
<xp-picker ref="endTime" mode="ymd" @confirm="customTime($event, 'endTime')" />
<!-- 选择门店 -->
<!-- 详情弹窗 -->
<statInfoPopup ref="infoPopup" />
<payInfoPopup ref="payInfo" />
</view>
</JeepayBackground>
</template>
<script setup>
import { onMounted, reactive, ref, getCurrentInstance, nextTick, computed } from 'vue';
import { onLoad, onReachBottom } from '@dcloudio/uni-app';
import { startAndEndTime } from '@/commons/utils/timeInspect';
import dayjs from 'dayjs';
import { req, reqLoad, $getStatInfo, $getStatistic, API_URL_MCH_STORE_LIST } from '@/http/apiManager.js';
import StatInfoCard from './components/StatInfoCard.vue';
import statInfoPopup from './components/statInfoPopup.vue';
import payInfoPopup from './components/payInfoPopup.vue';
// import StoreCell from './components/StoreCell.vue'
import statCell from './components/statCell.vue';
import cal from '@/commons/utils/cal.js';
import go from '@/commons/utils/go.js';
// 提示框
const tips = ref(null);
// 时间选怎器
const timeSelected = ref(null);
const startTime = ref(null);
const endTime = ref(null);
// 获取表格实例
const refTable = ref(null);
// 获取门店实例
const jeepayPopupListSelect = ref(null);
const infoPopup = ref(null);
const payInfo = ref(null);
const vdata = reactive({
selected: 'date',
statSelected: 'store',
totalSuccNum: '0.00',
originalData: {}, //原始数据 计算进度条
infoList: [
{ title: '退款金额 (元)', money: '13.15', value: 'totalRefundAmt' },
{ title: '退款笔数', money: '13.15', value: 'totalRefundNum' },
{ title: '成交订单笔数', money: '13.15', value: 'totalSuccNum' },
{ title: '成交订单金额 (元)', money: '6365876.15', value: 'totalSuccAmt' },
{ title: '手续费(元)', money: '13.15', value: 'totalFeeAmt' },
{ title: '交易成功率', money: '98.25%', value: 'succRate' }
],
statList: [
{ title: '门店统计', value: 'store' },
{ title: '支付类型统计', value: 'wayCodeType' },
{ title: '设备统计', value: 'device' }
],
namObj: {
store: 'storeName',
device: 'deviceName',
wayCodeType: 'name'
},
cardSelected: 'totalSuccAmt',
store: {
storeId: '',
storeName: '全部门店'
}
});
const screenList = reactive([
{ title: '日报', value: 'date' },
{ title: '月报', value: 'month' },
{ title: '年报', value: 'year' },
{ title: '自定义', value: 'custom' }
]);
const timeFormat = {
date: 'YYYY/MM/DD',
month: 'YYYY/MM',
year: 'YYYY'
};
const tipsList = reactive([
{ title: '入账金额:', info: '扣除已退款金额及手续费,入账金额为商户实际到账金额。' },
{ title: '退款笔数:', info: '实际退款订单笔数,若一笔已成交订单退款多次,则计多次。' },
{ title: '成交订单金额:', info: '支付成功的订单金额,包含部分退款及全额退款的订单。' },
{ title: '成交订单笔数:', info: '支付成功的订单笔数,包含已全额退款的订单。' },
{ title: '交易成功率:', info: '成交笔数与全部订单笔数除得的百分比。' }
]);
// 选择年月日
let orgSelectedTime = undefined;
const selectedTime = (val) => {
vdata.selected = val.value;
if (val.value != 'custom') orgSelectedTime = val.value;
if (val.value == 'custom') {
vdata.startTime = dayjs(vdata.time).startOf(orgSelectedTime).format(timeFormat['date']);
vdata.endTime = dayjs(vdata.time).endOf(orgSelectedTime).format(timeFormat['date']);
return;
}
dayConfirm({ value: dayjs(new Date()).format(timeFormat[vdata.selected]) });
};
const params = {
method: 'store',
queryDateRange: '',
sortOrder: 'ascend', //排序默认正序
sortField: 'totalSuccAmt' //默认字段
};
// 日报时间选择器确认
const dayConfirm = (e) => {
vdata.time = dayjs(e.value).format(timeFormat[vdata.selected]);
params.queryDateRange = `customDateTime_${dayjs(e.value).startOf('date').format('YYYY-MM-DD HH:mm:ss')}_${dayjs(e.value).endOf(vdata.selected).format('YYYY-MM-DD HH:mm:ss')}`;
nextTick(() => {
getStatList();
refTable.value.refTable(true);
// refTable.value.refTable(true);
});
};
// 自定义时间选择器
const customTime = (e, val) => {
vdata[val] = dayjs(e.value).format('YYYY/MM/DD');
if (vdata.endTime) {
if (!startAndEndTime(vdata.startTime, vdata.endTime)) return;
params.queryDateRange = `customDateTime_${dayjs(vdata.startTime).startOf('date').format('YYYY-MM-DD HH:mm:ss')}_${dayjs(vdata.endTime)
.endOf('date')
.format('YYYY-MM-DD HH:mm:ss')}`;
getStatList();
refTable.value.refTable(true);
// refTable.value.refTable(true);
}
};
const getStatList = () => {
$getStatInfo(params).then(({ bizData }) => {
vdata.originalData = JSON.parse(JSON.stringify(bizData)); //储存原始数据
// bizData.totalRefundAmt = cal.cert2Dollar(bizData.totalRefundAmt);
bizData.allAmount = cal.cert2Dollar(bizData.allAmount);
bizData.fee = cal.cert2Dollar(bizData.fee);
vdata.totalFinalAmt =
cal.cert2Dollar(bizData.totalSuccAmt - bizData.totalFeeAmt - bizData.totalRefundAmt) < 0
? '0.00'
: cal.cert2Dollar(bizData.totalSuccAmt - bizData.totalFeeAmt - bizData.totalRefundAmt);
bizData.round = bizData.round + '%';
vdata.infoList.forEach((v) => {
v.text = bizData[v.value];
});
});
};
//切换字段 切换排序
const switchField = (val) => {
vdata.cardSelected = val.value;
params.sortOrder = val.sort;
params.sortField = val.value;
refTable.value.refTable(true);
// refTable.value.refTable(true);
};
const reqTableDataFunc = (params) => {
return $getStatistic(params);
};
const openTips = () => {
tips.value.open();
};
// 判断是不是当天
const isToDay = () => {
return dayjs(vdata.time).format('YYYY/MM/DD') == dayjs(new Date()).format('YYYY/MM/DD');
};
// 计算进度条
const calcReality = (val, totalNum) => {
return (val / totalNum) * 100;
};
// 计算数据需不需要除以 100
const calcData = (val) => {
if (vdata.cardSelected == 'totalSuccNum' || vdata.cardSelected == 'totalRefundAmt') return cal.cert2Dollar(val);
return val;
};
const switchStatType = (val) => {
vdata.statSelected = val;
params.method = val;
nextTick(() => {
refTable.value.refTable(true);
// refTable.value.refTable(true);
// getStatList();
});
};
// 显示列表明细
function showDetail(params, record) {
if (vdata.statSelected == 'store') {
// payInfo.value.open(params, record);
infoPopup.value.open(params, record);
} else if (vdata.statSelected == 'device') {
infoPopup.value.open(params, record);
}
}
// 切换设备类型
const switchDevType = (val) => {
params.deviceType = val;
refTable.value.refTable(true);
refTable.value.refTable(true);
};
// 获取门店数据
function reqTableDataByStoreFunc(params) {
return reqLoad.list(API_URL_MCH_STORE_LIST, params);
}
// 选择门店
const selectedStore = () => {
jeepayPopupListSelect.value.open(vdata.store).then((selected) => {
if (selected) {
vdata.store = selected;
params.storeId = selected.storeId;
getStatList();
refTable.value.refTable(true);
}
});
};
// 根据类型计算值
const money = (record) => {
if (vdata.cardSelected == 'totalSuccAmt') {
return cal.cert2Dollar(record.totalSuccAmt);
} else if (vdata.cardSelected == 'totalSuccNum') {
return record.totalSuccNum;
} else if (vdata.cardSelected == 'totalRefundAmt') {
return cal.cert2Dollar(record.totalRefundAmt);
} else {
return record.succRate;
}
};
// 进入页面初始化数据
onLoad(() => {
params.queryDateRange = `customDateTime_${dayjs(new Date()).startOf('date').format('YYYY-MM-DD HH:mm:ss')}_${dayjs(new Date()).endOf('date').format('YYYY-MM-DD HH:mm:ss')}`;
vdata.time = dayjs().format('YYYY/MM/DD');
getStatList();
});
onReachBottom(() => {});
</script>
<style lang="scss" scoped>
.screen-time {
display: flex;
justify-content: space-around;
align-items: center;
margin: 10rpx 30rpx;
margin-top: 20rpx;
height: 100rpx;
border-radius: 20rpx;
background-color: rgba(255, 255, 255, 0.1);
.time-main {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
border-radius: 20rpx;
color: rgba(255, 255, 255, 0.75);
font-size: 32rpx;
font-weight: 500;
}
.active-screen {
width: 171rpx;
background-color: #fff;
color: $J-color-t21;
}
}
.time-selection {
margin-bottom: 10rpx;
height: 100rpx;
image {
width: 40rpx;
height: 40rpx;
}
.selection-main {
height: auto;
margin: 0 10rpx 0 20rpx;
font-size: 30rpx;
color: #fff;
}
}
.stat-card {
position: relative;
margin: 0 30rpx;
background-color: $J-bg-ff;
border-radius: $J-b-r32;
.stat-title {
white-space: nowrap;
margin-bottom: 10rpx;
font-size: 24rpx;
color: #a6a6a6;
}
.stat-money {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 202rpx;
box-shadow: 0 50rpx 70rpx -60rpx rgba(107, 130, 153, 0.2);
.stat-num-title {
font-size: 60rpx;
font-weight: 700;
color: #2980fd;
}
}
.stat-card-info {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
padding: 0 68rpx 50rpx 68rpx;
.stat-item {
width: 175rpx;
margin-top: 50rpx;
text-align: center;
.stat-num {
font-size: 30rpx;
font-weight: 700;
}
}
}
.stat-tips {
position: absolute;
top: 30rpx;
right: 30rpx;
}
}
.stat-selection {
position: sticky;
top: 88rpx;
left: 0;
right: 0;
z-index: 99;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 46rpx;
height: 110rpx;
background-color: #f7f7f7;
.stat-item {
flex-grow: 0;
display: flex;
align-items: center;
height: 100%;
font-size: 27rpx;
color: $J-color-t80;
background-color: #f7f7f7;
}
.active-stat {
font-weight: 500;
color: #2980fd;
}
}
.tips-wrapper {
display: flex;
flex-direction: column;
justify-content: center;
padding: 0 50rpx;
height: 170rpx;
.tips-title {
margin-bottom: 12rpx;
font-size: 30rpx;
}
.tips-info {
font-size: 26rpx;
color: #808080;
}
}
.store-name {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding-bottom: 60rpx;
text-align: center;
line-height: 100rpx;
height: 100rpx;
border-top: 1rpx solid #ededed;
font-size: 30rpx;
backdrop-filter: blur(20rpx);
background-color: rgba(252, 252, 252, 0.85);
}
.store-block {
height: 90rpx;
}
.time-custom {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 60rpx;
}
.store-name {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding-bottom: 60rpx;
text-align: center;
line-height: 100rpx;
height: 100rpx;
border-top: 1rpx solid #ededed;
font-size: 30rpx;
background-color: rgba(252, 252, 252, 0.85);
image {
margin-left: 10rpx;
width: 40rpx;
height: 40rpx;
}
}
</style>

View File

@@ -1,113 +1,11 @@
<template>
<JeepayBackground :bgImgView="true">
<JeepayCustomNavbar :transparent="true" bgDefaultColor="#eff5ff" title="我的" />
<!-- 业务操作 -->
<view class="my-wrapper">
<view class="user-info">
<image :src="vdata.userInfo.avatarUrl" mode="scaleToFill" />
<view class="user-main">
<view class="user-name">{{ vdata.userInfo.realname }}</view>
<view class="user-phone">{{ vdata.userInfo.telphone }}</view>
</view>
</view>
</view>
<JeepayNavigation :navList="navList1" />
<view class="line"></view>
<JeepayNavigation :navList="navList2" />
<!-- 广告部分组件 -->
<blcok v-for="v in vdata.adList" :key="v.adverId">
<JeepayBanner :list="v.appContent" :interval='v.changeTime' v-if="v.appPlaceType == 2" />
<JeepayAdCard :list='v.appContent' v-if="v.appPlaceType == 1" />
</blcok>
</JeepayBackground>
</template>
<script setup>
import { reactive, ref, onMounted } from 'vue'
import go from '@/commons/utils/go.js'
import { onPageScroll, onShow } from '@dcloudio/uni-app'
import storageManage from '@/commons/utils/storageManage.js'
import { $userInfo, $adList } from '@/http/apiManager.js'
onPageScroll(() => { })
const vdata = reactive({
userInfo: storageManage.userInfo(),
adList: []
})
const navList1 = [
{ title: '商户信息', icon: '/static/indexImg/mch-info.svg', pageUrl: '/pages/mchInfo/mchInfo', entId: 'ENT_MCH_INFO' },
{ title: '通知接收人', icon: '/static/indexImg/user-contact.svg', pageUrl: '/pages/noticeManage/noticeManage', entId: 'ENT_MCH_WXMP_USER_LIST' },
{ title: '支付宝代运营授权', icon: '/static/indexImg/icon-ali-pay.svg', pageUrl: 'PAGES_AD_ALIOPERATION',entId:'ENT_MCH_ALIPAY_SP_OPERATION' },
{ title: '关于我们', icon: '/static/indexImg/icon-about.svg', pageUrl: '/pages/aboutMch/aboutMch' },
]
const navList2 = [{ title: '设置', icon: '/static/indexImg/icon-setup.svg', pageUrl: '/pages/userSetUp/userSetUp' }]
onShow(() => {
// userInfo()
})
const userInfo = () => {
$userInfo().then(({ bizData }) => {
vdata.userInfo = bizData
// 保存用户数据
storageManage.userInfo(bizData)
})
}
const jumpPage = (url) => uni.navigateTo({ url })
const toLogin = () => uni.navigateTo({ url: '/pages/login/index' })
</script>
<style scoped>
/deep/ .bg-img-view {
background: url('/static/indexImg/user-bg.svg');
}
</style>
<style lang="scss" scoped>
.my-wrapper {
width: 100%;
height: 268rpx;
margin-top: 40rpx;
.user-info {
display: flex;
align-items: center;
padding: 0 50rpx;
height: 160rpx;
image {
width: 160rpx;
height: 160rpx;
border-radius: 32rpx;
background-color: tomato;
}
.user-main {
margin-left: 30rpx;
.user-name {
font-size: 36rpx;
}
.user-phone {
margin-top: 20rpx;
color: rgba(0, 0, 0, 0.5);
font-size: 30rpx;
}
}
}
}
.line {
height: 30rpx;
}
.to-login {
margin-top: 50rpx;
text-align: center;
background-color: #fff;
padding: 20rpx;
}
</style>

View File

@@ -1,137 +0,0 @@
<template>
<view class="account-pwd">
<uni-forms ref="formRef" label-align="left" :model="vdata.formData" :rules="rules">
<uni-forms-item label="原密码" name="originalPwd">
<uni-easyinput class='jeepay-easyinput' :inputBorder="false" :type="vdata.isShowOriginalPwd ? 'text' : 'password'" v-model="vdata.formData.originalPwd" :clearable="false" placeholder="请输入登录密码" >
<template #suffixIcon> <view class='show-tips' style="color: rgba(88,132,204,1);font-weight: 400;font-size: 32rpx;" @tap="vdata.isShowOriginalPwd = !vdata.isShowOriginalPwd ">{{ vdata.isShowOriginalPwd ? '隐藏' : '显示' }}</view> </template>
</uni-easyinput>
</uni-forms-item>
<view class="forget-pwd" @tap="phone.open({
tips: '为了您的账户安全,您需要使用短信验证码重置密码,是否发送验证码到:',
phone: vdata.userInfo.telphone,
confirmText: '发送短信验证码'
})">
<text>忘记原密码去找回 ></text>
</view>
<uni-forms-item label="新密码" name="newPwd">
<uni-easyinput class='jeepay-easyinput' :inputBorder="false" :type="vdata.isShowNewPwd ? 'text' : 'password'" v-model="vdata.formData.newPwd" :clearable="false" placeholder="请输入登录密码" >
<template #suffixIcon> <view class='show-tips' style="color: rgba(88,132,204,1);font-weight: 400;font-size: 32rpx;" @tap="vdata.isShowNewPwd = !vdata.isShowNewPwd ">{{ vdata.isShowNewPwd ? '隐藏' : '显示' }}</view> </template>
</uni-easyinput>
</uni-forms-item>
<uni-forms-item label="确认新密码" name="confirmPwd">
<uni-easyinput class='jeepay-easyinput' :inputBorder="false" :type="vdata.isShowConfirmPwd ? 'text' : 'password'" v-model="vdata.formData.confirmPwd" :clearable="false" placeholder="请输入登录密码" >
<template #suffixIcon> <view class='show-tips' style="color: rgba(88,132,204,1);font-weight: 400;font-size: 32rpx;" @tap="vdata.isShowConfirmPwd = !vdata.isShowConfirmPwd ">{{ vdata.isShowConfirmPwd ? '隐藏' : '显示' }}</view> </template>
</uni-easyinput>
</uni-forms-item>
</uni-forms>
<button class="confirm flex-center" hover-class="touch-button" @click="modifyPwd">确认修改</button>
</view>
<CallPhone ref="phone" @callPhone="callPhone" />
</template>
<script setup>
import { reactive, ref, onMounted } from 'vue'
import { $modifyPwd, $getPasswordRules } from "@/http/apiManager.js"
import storageManage from '@/commons/utils/storageManage.js'
import go from '@/commons/utils/go.js'
import infoBox from "@/commons/utils/infoBox.js"
import formUtil from '@/commons/utils/formUtil.js'
import CallPhone from './components/CallPhone.vue'
const rules = {
originalPwd: {
rules:[ formUtil.rules.requiredInputShowToast('原密码') ],
},
newPwd: {
rules:[ formUtil.rules.requiredInputShowToast('新密码') ],
},
confirmPwd: {
rules:[ formUtil.rules.requiredInputShowToast('确认新密码') ],
}
}
const formRef = ref()
const phone = ref()
const vdata = reactive({
formData: {
originalPwd: '',
newPwd: '',
confirmPwd: ''
},
userInfo: storageManage.userInfo(),
passwordRules: /^$/, //密码规则
passwordRulesText: '',//密码规则提示文字
})
onMounted(() => {
getPasswordRules()
})
const getPasswordRules = () => {
$getPasswordRules().then(({bizData}) => {
vdata.passwordRules = new RegExp(bizData.regexpRules)
vdata.passwordRulesText = bizData.errTips
})
}
const modifyPwd = () => {
formUtil.validate(formRef.value).then(() => {
let { newPwd, confirmPwd } = vdata.formData;
if(!vdata.passwordRules.test(newPwd) || !vdata.passwordRules.test(confirmPwd)) {
return infoBox.showToast(vdata.passwordRulesText)
}
if (newPwd !== confirmPwd) {
return infoBox.showToast('两次密码输入不一致')
}
$modifyPwd(vdata.formData).then(() => {
infoBox.showToast('修改成功')
storageManage.token() && storageManage.token(null, true)
go.to('PAGES_LOGIN', {}, 'redirect')
})
})
}
const callPhone = () => {
go.to('PAGES_FORGET_PASSWORD', {isRetrieve: 1 })
}
</script>
<style lang="scss" scoped>
.account-pwd {
min-height: 100vh;
background-color: $v-color-bgrey;
::v-deep.uni-forms-item.is-direction-left {
padding: 0 40rpx;
.uni-forms-item__label {
width: 190rpx !important;
font-size: 32rpx !important;
font-weight: 400;
white-space: nowrap;
color: rgba(102,102,102,1);
text-indent: 0 !important;
}
.uni-easyinput__placeholder-class {
font-size: 32rpx !important;
font-weight: 400 !important;
}
}
.forget-pwd {
display: flex;
align-items: center;
height: 90rpx;
text-indent: 30rpx;
color: #2980fd;
font-size: 30rpx;
font-weight: 400;
}
.confirm {
margin: 30rpx;
height: 110rpx;
border-radius: 20rpx;
color: #fff;
background: $jeepay-bg-primary;
}
}
</style>

View File

@@ -1,116 +0,0 @@
<template>
<view class="page-wrapper">
<JeepayCustomNavbar bgDefaultColor="#fff" title="账号设置" backCtrl="back" />
<view class="user-photo">
<view class="title">用户头像</view>
<view class="right" @tap="uploadImg.preview()">
<JeepayUploadImg ref="uploadImg" v-model:src="vdata.userInfo.avatarUrl" bizType="applyment" mode="viewbtn" @change="modifyUser" />
<!-- <image class="user-img" src="/static/orderImg/ysf.svg" mode="scaleToFill" /> -->
<image style="width: 100rpx; height: 120rpx" src="/static/iconImg/icon-arrow-small.svg" mode="scaleToFill" />
</view>
</view>
<view class="user-name-wrapper" @tap="go.to('PAGES_EDIT_FORM', { realname: vdata.userInfo.realname })">
<view class="title">用户姓名</view>
<view class="right">
<view>{{ vdata.userInfo.realname }}</view>
<image style="width: 100rpx; height: 120rpx" src="/static/iconImg/icon-arrow-small.svg" mode="scaleToFill" />
</view>
</view>
<view class="user-name-wrapper remover" @tap="phone.open(vdata.callPhone)">
<view class="title">注销账号</view>
<view class="right">
<image style="width: 100rpx; height: 120rpx" src="/static/iconImg/icon-arrow-small.svg" mode="scaleToFill" />
</view>
</view>
</view>
<CallPhone ref="phone" @callPhone="callPhone" />
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { onShow } from '@dcloudio/uni-app';
import { $modifyUser, $userInfo } from '@/http/apiManager.js'
import storageManage from '@/commons/utils/storageManage.js'
import go from '@/commons/utils/go.js'
import infoBox from '@/commons/utils/infoBox.js'
import CallPhone from './components/CallPhone.vue'
const uploadImg = ref()
const phone = ref(null)
const vdata = reactive({
userInfo: storageManage.userInfo(),
siteInfos: storageManage.siteInfos(),
callPhone: {
}
})
onMounted(() => {
vdata.callPhone = {
tips: '为了您的账户安全,请联系客服进行账号注销处理,客服电话:',
phone: vdata.siteInfos.siteInfo.companyTel,
confirmText: '拨打电话'
}
})
onShow(() => {
userInfo()
})
const userInfo = () => {
$userInfo().then(({bizData}) => {
vdata.userInfo = bizData
// 保存用户数据
storageManage.userInfo(bizData)
})
}
const modifyUser = (ossFileUrl) => {
$modifyUser({
avatarUrl: ossFileUrl
}).then(() => {
return infoBox.showToast("保存成功")
})
}
const callPhone = () => {
uni.makePhoneCall({
phoneNumber: vdata.siteInfos.companyTel
})
}
</script>
<style lang="scss" scoped>
.title {
margin-left: 40rpx;
color: #666666;
}
.right {
display: flex;
align-items: center;
}
.user-photo {
display: flex;
justify-content: space-between;
align-items: center;
height: 240rpx;
background-color: #fff;
font-size: 32rpx;
.user-img {
width: 160rpx;
height: 160rpx;
border-radius: 26rpx;
}
}
.user-name-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 20rpx;
background-color: #fff;
}
.remover {
margin-top: 30rpx;
padding: 0;
}
</style>

View File

@@ -1,81 +0,0 @@
<template>
<uni-popup ref="popup" type="bottom" mask-background-color="rgba(0,0,0,.5)" :safe-area="false">
<view class="tips-wrapper">
<view class="tips-text call-phone">
{{ vdata.tips }}
<view class="phone-number">{{ vdata.phone }}</view>
</view>
<view class="single-text flex-center" hover-class="u-cell-hover" hover-stay-time="150" style="color: #2980fd" @tap="emits('callPhone')">{{ vdata.confirmText }}</view>
<view class="line"></view>
<view class="tips-text tips-cancel flex-center" hover-class="u-cell-hover" hover-stay-time="150" @tap="popup.close()"> 取消 </view>
</view>
</uni-popup>
</template>
<script setup>
import { reactive, ref } from 'vue'
const vdata = reactive({
phone: '',
tips: '',
confirmText: ''
})
const emits = defineEmits(['callPhone'])
const selected = ref(undefined)
const popup = ref(null)
// 打开弹窗 val 选中数据的key
const open = (val) => {
console.log(val)
Object.assign(vdata, val)
popup.value.open()
}
const close = () => popup.value.close()
defineExpose({ open, close })
</script>
<style lang="scss" scoped>
.tips-wrapper {
// overflow: hidden;
border-radius: 32rpx 32rpx 0 0;
padding-top: 20rpx;
padding-bottom: 60rpx;
background-color: #fff;
.tips-text {
text-align: center;
min-height: 90rpx;
font-size: 30rpx;
border-bottom: 1rpx solid rgba(0, 0, 0, 0.07);
}
.single-text {
height: 120rpx;
}
.line {
height: 20rpx;
background-color: rgba(0, 0, 0, 0.07);
}
.tips-cancel {
height: 110rpx;
color: $J-color-t80;
font-size: 33rpx;
border: none;
}
.u-cell-hover {
background-color: #f8f9fa;
}
}
.call-phone {
padding: 0 60rpx;
padding-top: 40rpx;
font-size: 30rpx;
color: #808080;
.phone-number {
margin-top: 25rpx;
margin-bottom: 40rpx;
font-size: 36rpx;
font-weight: 500;
color: #000;
}
}
</style>

View File

@@ -1,66 +0,0 @@
<template>
<view class="edit-wrapper">
<view class="edit-input flex-center">
<uni-easyinput :inputBorder="false" clearable maxlength="12" v-model="vdata.formData.realname" type="text" :styles="styles" />
</view>
<view class="confirm-button flex-center" hover-class="touch-button" @tap="updateState">确认修改</view>
</view>
</template>
<script setup>
import { reactive } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { $modifyUser } from '@/http/apiManager.js'
import infoBox from '@/commons/utils/infoBox.js'
import go from '@/commons/utils/go.js'
onLoad((options) => {
Object.assign(vdata.formData, options)
})
const styles = reactive({
backgroundColor: 'transparent',
color: '#000',
fontSize: '32rpx',
})
const vdata = reactive({
formData: {}
})
function updateState() {
if (!vdata.formData.realname) {
return infoBox.showToast("请输入用户姓名")
}
$modifyUser(vdata.formData).then(() => {
infoBox.showToast("保存成功").then(() => {
go.back()
})
})
}
</script>
<style lang="scss" scoped>
.edit-input {
padding: 0 20rpx;
margin: 0 35rpx;
margin-top: 150rpx;
height: 120rpx;
border-radius: 32rpx;
background-color: #f7f7f7;
}
.tips {
margin-top: 30rpx;
text-align: center;
font-size: 27rpx;
color: #808080;
}
.confirm-button {
margin: 0 auto;
margin-top: 90rpx;
width: 400rpx;
height: 110rpx;
border-radius: 20rpx;
font-size: 33rpx;
font-weight: 500;
color: #fff;
background: $jeepay-bg-primary;
}
</style>

View File

@@ -1,160 +0,0 @@
<template>
<view class="pay-wrapper">
<view class="title">{{ vdata.steps[vdata.current].title }}</view>
<view class="tips">{{ vdata.steps[vdata.current].subTitle }}</view>
<JPasswordInput focus @inputChange="inputChange" ref="input" />
<view class="confirm flex-center">
<button
v-if="vdata.current == 2"
class="confirm-button flex-center"
hover-class="touch-button"
:style="{
background: vdata.allowChange && (vdata.steps[vdata.current].pwd.length >= 6) ? 'linear-gradient(270deg, rgba(35,143,252,1) 0%, rgba(26,102,255,1) 100%)' : '',
}"
@click="confirm"
>
确认修改
</button>
</view>
<view v-if="vdata.current != 0" class="back" @click="back">
<image src="@/static/iconImg/icon-arrow-left.svg" class="arrow"></image>
<text style="margin-left: 10rpx">返回上一步</text>
</view>
</view>
</template>
<script setup>
import { reactive, ref } from 'vue'
import { onLoad, onBackPress } from "@dcloudio/uni-app"
import { $isSipw, $isMchSipw, $updateMchSipw } from "@/http/apiManager.js"
import infoBox from "@/commons/utils/infoBox.js"
import go from '@/commons/utils/go.js'
const input = ref(null) //输入框实例
const vdata = reactive({
allowChange: false,
current: 0,
steps: [
{
title: '验证身份',
subTitle: '请输入原支付密码以验证您的身份',
pwd: ''
},
{
title: '设置密码',
subTitle: '请设置新的支付密码,用于退款验证',
pwd: ''
},
{
title: '确认密码',
subTitle: '请再次输入支付密码确认',
pwd: ''
}
]
})
onLoad(() => {
$isSipw().then(({ bizData }) => {
!bizData && (vdata.current = 1)
})
})
const getInputVerification1 = (originalPwd) => {
$isMchSipw(originalPwd).then(({ bizData }) => {
if (bizData) {
vdata.current = 1
clearInput()
} else {
return infoBox.showToast('密码验证错误')
}
})
}
const getInputVerification2 = () => {
vdata.current = 2
clearInput()
}
const getInputVerification3 = (pwd, confirmPwd) => {
if (pwd != confirmPwd) {
vdata.allowChange = false
return infoBox.showToast('两次输入的密码不一致')
} else {
vdata.allowChange = true;
}
}
const inputChange = (e) => {
let currentStep = vdata.steps[vdata.current];
currentStep.pwd = e
if (vdata.current === 0 && currentStep.pwd.length == 6) {
getInputVerification1(currentStep.pwd)
}
if (vdata.current === 1 && currentStep.pwd.length == 6) {
getInputVerification2(currentStep.pwd)
}
if (vdata.current === 2 && currentStep.pwd.length == 6) {
getInputVerification3(vdata.steps[1].pwd, currentStep.pwd)
}
}
const confirm = () => {
if (vdata.allowChange) {
let steps = vdata.steps;
$updateMchSipw({
originalPwd: steps[0].pwd,
confirmPwd: steps[2].pwd
}).then(() => {
infoBox.showSuccessToast('修改成功')
return go.back()
})
}
}
const back = () => {
vdata.current = vdata.current - 1
}
// 清空输入框事件
const clearInput = () => input.value.clearInput()
</script>
<style lang="scss" scoped>
.title {
margin-top: 200rpx;
text-align: center;
font-size: 50rpx;
font-weight: 500;
}
.tips {
margin: 30rpx 0 90rpx 0;
text-align: center;
font-size: 32rpx;
font-weight: 400;
color: $J-color-t80;
}
.back {
display: flex;
justify-content: center;
align-items: center;
color: #808080;
font-size: 30rpx;
margin-top: 53rpx;
.arrow {
width: 50rpx;
height: 50rpx;
}
}
.confirm {
margin-top: 90rpx;
height: 110rpx;
.confirm-button {
width: 400rpx;
height: 110rpx;
border-radius: 20rpx;
font-size: 33rpx;
font-weight: 500;
color: #fff;
background-color: #d9d9d9;
}
}
</style>

View File

@@ -1,12 +0,0 @@
<template>
<view class="page-wrapper">
<JCell title="账号密码" :mT="20" @tap="jumpPage('accountPwd')" />
<JCell title="支付密码" @tap="jumpPage('payPassword')" />
</view>
</template>
<script setup>
const jumpPage = (url) => uni.navigateTo({ url: `/pages/userSetUp/${url}` })
</script>
<style lang="scss" scoped></style>

View File

@@ -1,95 +0,0 @@
<template>
<view class="page-wrapper">
<JCell v-for="(item, index) in vdata.defaultConfig" :key="item.configKey" :title="item.configName" color="#4D4D4D" borderWidth="40rpx" :isTouch="false">
<template #right>
<JSwitch
:bol="item.configVal === '1' ? true : false"
:tips="item.tips || `是否${item.configVal === '1' ? '关闭' : '开启'}${item.configName}`"
margin="0 35rpx 0 0"
@confirm="confirm($event, item)"
/>
</template>
</JCell>
</view>
</template>
<script setup>
import { reactive, computed } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import { $mchConfig, $orderConfig } from '@/http/apiManager.js';
import infoBox from '@/commons/utils/infoBox.js';
import storageManage from '@/commons/utils/storageManage.js';
// #ifdef MP-WEIXIN
// 控制 音乐播放 和暂停
import { startOrEndMusice } from '@/commons/utils/pushmsg/wxTextToSpeach.js';
// #endif
onLoad((options) => {
mchConfig();
});
const vdata = reactive({
defaultConfig: [
{
configKey: 'appVoice',
configName: 'app订单语音播报',
configVal: '0',
type: 'radio'
},
{
configKey: 'qrcEscaping',
configName: '码牌防逃单功能',
configVal: '0',
type: 'radio'
},
{
configKey: 'weChatVoice',
configName: '小程序语音推送',
configVal: '0',
type: 'radio'
}
] // 默认配置项
});
// 计算属性 用于计算 开关状态 提供不同提示语
const pushTips = computed(() => {
return vdata.isPush ? '是否确认关闭小程序语音推送?' : '注意“小程序语音推送功能会占用音乐播放器请勿关闭播放器, 请开启小程序浮窗以保证小程序正常播放订单消息”。';
});
const mchConfig = () => {
$mchConfig('orderConfig').then(({ bizData = [] }) => {
Object.assign(vdata.defaultConfig, bizData);
// 如果是app 则删除 微信推送开关
// #ifdef APP-PLUS
const index = vdata.defaultConfig.findIndex((v) => v.configKey == 'weChatVoice');
spliceIndex(index);
// #endif
// 如果是微信则删除 app 推送开关
// #ifdef MP-WEIXIN
const index = vdata.defaultConfig.findIndex((v) => v.configKey == 'appVoice');
const weChat = vdata.defaultConfig.find((v) => v.configKey == 'weChatVoice'); //获取 小程序数据实例
calcTips(weChat);
spliceIndex(index);
// #endif
});
};
const confirm = (e, item) => {
item.configVal = e ? 1 : 0;
$orderConfig(JSON.stringify(vdata.defaultConfig), vdata.defaultConfig[0].mchNo).then(() => {
if (item.configKey == 'weChatVoice') calcTips(item);
infoBox.showToast('设置成功');
// #ifdef MP-WEIXIN
if (item.configKey == 'weChatVoice') {
// 添加语音播报的消息推送
startOrEndMusice(item.configVal);
}
// #endif
});
};
function spliceIndex(i) {
if (i != '-1') vdata.defaultConfig.splice(i, 1);
}
// 用于计算 合适的提示用语
function calcTips(v) {
if (v != '-1')
v.tips = v.configVal == 1 ? '是否确认关闭小程序语音推送?' : '注意“小程序语音推送功能会占用音乐播放器请勿关闭播放器, 请开启小程序浮窗以保证小程序正常播放订单消息”。';
}
</script>
<style lang="scss" scoped></style>

View File

@@ -1,48 +0,0 @@
<template>
<view class="page-wrapper">
<JCell title="安全设置" :mT="20" @tap="jumpPage('safeSetUp')" />
<JCell title="账号设置" :mT="20" @tap="jumpPage('accountSetUp')" />
<JCell v-if="ak.ent.has('ENT_MCH_CONFIG_EDIT')" title="系统设置" @tap="jumpPage('systemSetUp')" />
<button hover-class="touch-hover" class="login-out flex-center u-m-t-30" @tap="logout">退出登录</button>
</view>
<!-- 通用提示 -->
<JeepayPopupConfirm ref="jeepayPopupConfirm" />
</template>
<script setup>
import { ref, reactive } from 'vue'
import go from '@/commons/utils/go.js'
import infoBox from '@/commons/utils/infoBox.js'
import storageManage from '@/commons/utils/storageManage.js'
import ak from '@/commons/utils/ak.js'
// #ifdef MP-WEIXIN
// 控制 音乐播放 和暂停
import { startOrEndMusice } from "@/commons/utils/pushmsg/wxTextToSpeach.js"
// #endif
const jeepayPopupConfirm = ref()
function logout() {
jeepayPopupConfirm.value.open('确认退出?').then(() => {
storageManage.cleanByLogout()
// #ifdef MP-WEIXIN
startOrEndMusice(false)
// #endif
go.to('PAGES_LOGIN', {}, go.GO_TYPE_RELAUNCH)
})
}
const jumpPage = (url) => uni.navigateTo({ url: `/pages/userSetUp/${url}` })
</script>
<style lang="scss" scoped>
.login-out {
margin-top: 20rpx;
height: 120rpx;
background-color: #fff;
font-size: 32rpx;
font-weight: 400;
color: #ff5b4c;
}
</style>