mirror of
https://gitee.com/niucloud-team/niucloud.git
synced 2026-03-15 08:10:53 +00:00
update uni-app
This commit is contained in:
parent
af22537caf
commit
4aaf35ee08
@ -13,6 +13,8 @@
|
||||
// 添加初始化拦截器
|
||||
launchInterceptor()
|
||||
|
||||
uni.removeStorageSync('isWatchShare')
|
||||
|
||||
// #ifdef H5
|
||||
uni.getSystemInfoSync().platform == 'ios' && (uni.setStorageSync('initUrl', location.href))
|
||||
|
||||
@ -51,6 +53,7 @@
|
||||
const configStore = useConfigStore()
|
||||
await configStore.getLoginConfig()
|
||||
|
||||
useSystemStore().getMapFn()
|
||||
useSystemStore().getSiteInfoFn()
|
||||
|
||||
// 隐藏tabbar
|
||||
@ -64,7 +67,7 @@
|
||||
|
||||
if (!getToken()) {
|
||||
const login = useLogin()
|
||||
// 三方平台自动登录
|
||||
// 第三方平台自动登录
|
||||
// #ifdef MP
|
||||
login.getAuthCode()
|
||||
// #endif
|
||||
|
||||
@ -7,11 +7,10 @@
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border: 4rpx solid $u-primary;
|
||||
border: 4rpx dotted $u-primary;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
cursor: move;
|
||||
border-style: dotted;
|
||||
}
|
||||
|
||||
&.selected:before {
|
||||
|
||||
@ -1,42 +1,55 @@
|
||||
<template>
|
||||
<view class="diy-group" id="componentList">
|
||||
<top-tabbar :scrollTop="scrollTop" v-if="data.global && Object.keys(data.global).length && data.global.topStatusBar && data.global.topStatusBar.isShow" ref="topTabbarRef" :data="data.global" />
|
||||
<view v-for="(component, index) in data.value" :key="component.id" @click="diyStore.changeCurrentIndex(index, component)" :class="getComponentClass(index,component)" :style="component.pageStyle">
|
||||
<template v-if="component.componentName == 'GraphicNav'">
|
||||
<diy-graphic-nav :component="component" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-graphic-nav>
|
||||
</template>
|
||||
<template v-if="component.componentName == 'HorzBlank'">
|
||||
<diy-horz-blank :component="component" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-horz-blank>
|
||||
</template>
|
||||
<template v-if="component.componentName == 'HorzLine'">
|
||||
<diy-horz-line :component="component" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-horz-line>
|
||||
</template>
|
||||
<template v-if="component.componentName == 'HotArea'">
|
||||
<diy-hot-area :component="component" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-hot-area>
|
||||
</template>
|
||||
<template v-if="component.componentName == 'ImageAds'">
|
||||
<diy-image-ads :component="component" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-image-ads>
|
||||
</template>
|
||||
<template v-if="component.componentName == 'MemberInfo'">
|
||||
<diy-member-info :component="component" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-member-info>
|
||||
</template>
|
||||
<template v-if="component.componentName == 'Notice'">
|
||||
<diy-notice :component="component" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-notice>
|
||||
</template>
|
||||
<template v-if="component.componentName == 'RubikCube'">
|
||||
<diy-rubik-cube :component="component" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-rubik-cube>
|
||||
</template>
|
||||
<template v-if="component.componentName == 'Text'">
|
||||
<diy-text :component="component" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-text>
|
||||
</template>
|
||||
<template v-if="component.componentName == 'RichText'">
|
||||
<diy-rich-text :component="component" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"/>
|
||||
</template>
|
||||
<template v-if="component.componentName == 'ActiveCube'">
|
||||
<diy-active-cube :component="component" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"/>
|
||||
</template>
|
||||
<template v-if="component.componentName == 'FloatBtn'">
|
||||
<diy-float-btn :component="component" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"/>
|
||||
</template>
|
||||
<view class="relative" :style="{ marginTop : component.margin.top < 0 ? (component.margin.top * 2) + 'rpx' : '0' }">
|
||||
|
||||
<!-- 装修模式下,设置负上边距后超出的内容,禁止选中设置 -->
|
||||
<view v-if="isShowPlaceHolder(index,component)" class="absolute w-full z-1" :style="{ height : (component.margin.top * 2 * -1) + 'rpx' }" @click.stop="placeholderEvent"></view>
|
||||
|
||||
<template v-if="component.componentName == 'GraphicNav'">
|
||||
<diy-graphic-nav :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount" />
|
||||
</template>
|
||||
<template v-if="component.componentName == 'HorzBlank'">
|
||||
<diy-horz-blank :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount" />
|
||||
</template>
|
||||
<template v-if="component.componentName == 'HorzLine'">
|
||||
<diy-horz-line :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount" />
|
||||
</template>
|
||||
<template v-if="component.componentName == 'HotArea'">
|
||||
<diy-hot-area :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount" />
|
||||
</template>
|
||||
<template v-if="component.componentName == 'ImageAds'">
|
||||
<diy-image-ads :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount" />
|
||||
</template>
|
||||
<template v-if="component.componentName == 'MemberInfo'">
|
||||
<diy-member-info :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount" />
|
||||
</template>
|
||||
<template v-if="component.componentName == 'MemberLevel'">
|
||||
<diy-member-level :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount" />
|
||||
</template>
|
||||
<template v-if="component.componentName == 'Notice'">
|
||||
<diy-notice :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount" />
|
||||
</template>
|
||||
<template v-if="component.componentName == 'RubikCube'">
|
||||
<diy-rubik-cube :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount" />
|
||||
</template>
|
||||
<template v-if="component.componentName == 'Text'">
|
||||
<diy-text :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount" />
|
||||
</template>
|
||||
<template v-if="component.componentName == 'RichText'">
|
||||
<diy-rich-text :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"/>
|
||||
</template>
|
||||
<template v-if="component.componentName == 'ActiveCube'">
|
||||
<diy-active-cube :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"/>
|
||||
</template>
|
||||
<template v-if="component.componentName == 'FloatBtn'">
|
||||
<diy-float-btn :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"/>
|
||||
</template>
|
||||
<template v-if="component.componentName == 'CarouselSearch'">
|
||||
<diy-carousel-search :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount" />
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
<template v-if="diyStore.mode == '' && data.global.bottomTabBarSwitch">
|
||||
<view class="pt-[20rpx]"></view>
|
||||
@ -45,10 +58,14 @@
|
||||
</view>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import topTabbar from '@/components/top-tabbar/top-tabbar.vue'
|
||||
|
||||
import useDiyStore from '@/app/stores/diy';
|
||||
import { ref, onMounted, nextTick, computed } from 'vue';
|
||||
import { getLocation } from '@/utils/common';
|
||||
import Sortable from 'sortablejs';
|
||||
import { range } from 'lodash-es';
|
||||
import { onPageScroll } from '@dcloudio/uni-app'
|
||||
import useConfigStore from '@/stores/config'
|
||||
const props = defineProps(['data','pullDownRefreshCount']);
|
||||
const diyStore = useDiyStore();
|
||||
@ -65,7 +82,7 @@
|
||||
return useConfigStore().addon;
|
||||
})
|
||||
|
||||
const positionFixed = ref(['fixed', 'top_fixed','right_fixed','bottom_fixed','left_fixed'])
|
||||
const positionFixed = ref(['fixed', 'top_fixed','right_fixed','bottom_fixed','left_fixed']);
|
||||
|
||||
const getComponentClass = (index:any,component:any) => {
|
||||
let obj: any = {
|
||||
@ -98,11 +115,9 @@
|
||||
diyStore.value.splice(event.newIndex!, 0, temp);
|
||||
|
||||
nextTick(() => {
|
||||
sortable.sort(
|
||||
range(diyStore.value.length).map(value => {
|
||||
return value.toString();
|
||||
})
|
||||
);
|
||||
sortable.sort(range(diyStore.value.length).map(value => {
|
||||
return value.toString();
|
||||
}));
|
||||
|
||||
diyStore.postMessage(event.newIndex, diyStore.value[event.newIndex]);
|
||||
});
|
||||
@ -110,8 +125,61 @@
|
||||
});
|
||||
}
|
||||
// #endif
|
||||
|
||||
nextTick(() => {
|
||||
setTimeout(() => {
|
||||
if (data.value.global && data.value.global.topStatusBar && data.value.global.topStatusBar.style == 'style-4') {
|
||||
// 第一次获取经纬度
|
||||
getLocation()
|
||||
}
|
||||
}, 500)
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// 是否显示占位区域,用于禁止选中负上边距的内容
|
||||
const isShowPlaceHolder = (index: any, component: any) => {
|
||||
// #ifdef H5
|
||||
if (diyStore.mode == 'decorate') {
|
||||
let el: any = document.getElementById('componentList');
|
||||
if (el && el.children.length && el.children[index]) {
|
||||
let height = el.children[index].offsetHeight;
|
||||
let top = 0;
|
||||
if (component.margin.top < 0) {
|
||||
top = component.margin.top * 2 * -1;
|
||||
// 若负上边距大于组件的高度,则允许选中进行装修
|
||||
if (top > height) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// #endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// 空函数,禁止选中
|
||||
const placeholderEvent = ()=>{}
|
||||
|
||||
let topTabbarRef = ref(null)
|
||||
|
||||
// 页面onShow调用时,也会触发改方法
|
||||
const refresh = ()=>{
|
||||
nextTick(()=>{
|
||||
topTabbarRef.value?.refresh();
|
||||
})
|
||||
}
|
||||
|
||||
let scrollTop = ref(0)
|
||||
onPageScroll((e)=>{
|
||||
scrollTop.value = e.scrollTop;
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
refresh
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import './index.scss';
|
||||
</style>
|
||||
</style>
|
||||
@ -167,3 +167,46 @@ export function editAddress(params: Record<string, any>) {
|
||||
export function deleteAddress(id: number) {
|
||||
return request.delete(`member/address/${id}`, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会员等级
|
||||
*/
|
||||
export function getMemberLevel() {
|
||||
return request.get(`member/level`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取成长值任务
|
||||
*/
|
||||
export function getTaskGrowth() {
|
||||
return request.get(`task/growth`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取签到日期
|
||||
*/
|
||||
export function getSignInfo(data : AnyObject) {
|
||||
return request.get(`member/sign/info/${data.year}/${data.month}`, {})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取日签到奖励
|
||||
*/
|
||||
export function getDayPack(data : AnyObject) {
|
||||
return request.get(`member/sign/award/${data.year}/${data.month}/${data.day}`)
|
||||
}
|
||||
/**
|
||||
* 获取签到设置
|
||||
*/
|
||||
export function getSignConfig() {
|
||||
return request.get(`member/sign/config`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击签到
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function setSign() {
|
||||
return request.post('member/sign')
|
||||
}
|
||||
@ -4,69 +4,69 @@ import request from '@/utils/request'
|
||||
* 获取验证码
|
||||
*/
|
||||
export function getCaptcha() {
|
||||
return request.get('captcha', {}, { showErrorMessage: true })
|
||||
return request.get('captcha', {}, {showErrorMessage: true})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信公众号授权码
|
||||
*/
|
||||
export function getWechatAuthCode(data : AnyObject) {
|
||||
return request.get('wechat/codeurl', data, { showErrorMessage: false })
|
||||
export function getWechatAuthCode(data: AnyObject) {
|
||||
return request.get('wechat/codeurl', data, {showErrorMessage: false})
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步微信信息
|
||||
*/
|
||||
export function wechatSync(data : AnyObject) {
|
||||
return request.post('wechat/sync', data, { showErrorMessage: false })
|
||||
export function wechatSync(data: AnyObject) {
|
||||
return request.post('wechat/sync', data, {showErrorMessage: false})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取协议信息
|
||||
*/
|
||||
export function getAgreementInfo(key : string) {
|
||||
export function getAgreementInfo(key: string) {
|
||||
return request.get(`agreement/${key}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置密码
|
||||
*/
|
||||
export function resetPassword(data : AnyObject) {
|
||||
return request.post(`password/reset`, data, { showErrorMessage: true })
|
||||
export function resetPassword(data: AnyObject) {
|
||||
return request.post(`password/reset`, data, {showErrorMessage: true})
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送短信验证码
|
||||
*/
|
||||
export function sendSms(data : AnyObject) {
|
||||
return request.post(`send/mobile/${data.type}`, data, { showErrorMessage: true })
|
||||
export function sendSms(data: AnyObject) {
|
||||
return request.post(`send/mobile/${data.type}`, data, {showErrorMessage: true})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信jssdk config
|
||||
*/
|
||||
export function getWechatSkdConfig(data : AnyObject) {
|
||||
return request.get('wechat/jssdkconfig', data, { showErrorMessage: false })
|
||||
export function getWechatSkdConfig(data: AnyObject) {
|
||||
return request.get('wechat/jssdkconfig', data, {showErrorMessage: false})
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传图片
|
||||
*/
|
||||
export function uploadImage(data : AnyObject) {
|
||||
return request.upload('file/image', data, { showErrorMessage: true })
|
||||
export function uploadImage(data: AnyObject) {
|
||||
return request.upload('file/image', data, {showErrorMessage: true})
|
||||
}
|
||||
|
||||
/**
|
||||
* 拉取图片
|
||||
*/
|
||||
export function fetchImage(data : AnyObject) {
|
||||
export function fetchImage(data: AnyObject) {
|
||||
return request.post('file/image/fetch', data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 拉取base64图片
|
||||
*/
|
||||
export function fetchBase64Image(data : AnyObject) {
|
||||
export function fetchBase64Image(data: AnyObject) {
|
||||
return request.post('file/image/base64', data)
|
||||
}
|
||||
|
||||
@ -81,7 +81,7 @@ export function getSiteInfo() {
|
||||
* 获取微信小程序订阅消息模板id
|
||||
*/
|
||||
export function getWeappTemplateId(keys: string) {
|
||||
return request.get('weapp/subscribemsg', { keys })
|
||||
return request.get('weapp/subscribemsg', {keys})
|
||||
}
|
||||
|
||||
/**
|
||||
@ -112,14 +112,14 @@ export function getAreaByCode(code: number | string) {
|
||||
* 通过经纬度查询地址
|
||||
* @param params
|
||||
*/
|
||||
export function getAddressByLatlng(params : Record<string, any>) {
|
||||
return request.get(`area/address_by_latlng`,params)
|
||||
export function getAddressByLatlng(params: Record<string, any>) {
|
||||
return request.get(`area/address_by_latlng`, params)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取手机端首页列表
|
||||
*/
|
||||
export function getWapIndexList(data : AnyObject) {
|
||||
export function getWapIndexList(data: AnyObject) {
|
||||
return request.get('wap_index', data)
|
||||
}
|
||||
|
||||
@ -127,6 +127,21 @@ export function getWapIndexList(data : AnyObject) {
|
||||
* 获取海报
|
||||
* @returns
|
||||
*/
|
||||
export function getPoster(params : Record<string, any>) {
|
||||
export function getPoster(params: Record<string, any>) {
|
||||
return request.get("poster", params)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取地图设置
|
||||
*/
|
||||
export function getMap() {
|
||||
return request.get('map')
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过外部交易号获取消息跳转路径
|
||||
* @param params
|
||||
*/
|
||||
export function getMsgJumpPath(params: Record<string, any>) {
|
||||
return request.get('weapp/getMsgJumpPath', params)
|
||||
}
|
||||
|
||||
47
uni-app/src/app/api/verify.ts
Normal file
47
uni-app/src/app/api/verify.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 获取核销信息
|
||||
*/
|
||||
export function getVerifyCode(type: string ,params: AnyObject) {
|
||||
return request.get('verify', {type, data: params})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取核销记录
|
||||
*/
|
||||
export function getVerifyRecords(params: Record<string, any>) {
|
||||
return request.get('verify_records', {params})
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否是核销员
|
||||
*/
|
||||
export function getCheckVerifier() {
|
||||
return request.get('check_verifier')
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取核销信息
|
||||
*/
|
||||
export function getVerifierInfo(code: string) {
|
||||
return request.get(`get_verify_by_code/${code}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 核销
|
||||
*/
|
||||
export function verify(code: string) {
|
||||
return request.post(`verify/${code}`,{}, { showSuccessMessage: true, showErrorMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取核销详情
|
||||
*/
|
||||
export function getVerifyDetail(code: string) {
|
||||
return request.get(`verify_detail/${code}`,{}, { showErrorMessage: true })
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -154,10 +154,12 @@
|
||||
|
||||
const setModuleLocation = ()=> {
|
||||
nextTick(() => {
|
||||
const query = uni.createSelectorQuery().in(instance);
|
||||
query.select('.fixed-wrap').boundingClientRect(data => {
|
||||
moduleHeight.value = (data.height || 0) + 'px';
|
||||
}).exec();
|
||||
setTimeout(()=>{
|
||||
const query = uni.createSelectorQuery().in(instance);
|
||||
query.select('.fixed-wrap').boundingClientRect((data:any) => {
|
||||
moduleHeight.value = (data.height || 0) + 'px';
|
||||
}).exec();
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -165,7 +167,19 @@
|
||||
const fixedStyle = computed(()=>{
|
||||
if (diyStore.mode == 'decorate') return '';
|
||||
var style = '';
|
||||
// #ifdef H5
|
||||
if(props.global.topStatusBar.isShow && props.global.topStatusBar.style == 'style-4') {
|
||||
style += 'top:' + diyStore.topTabarHeight + 'px;';
|
||||
}
|
||||
// #endif
|
||||
if(diyComponent.value.positionWay == 'fixed') {
|
||||
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
|
||||
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
||||
if(props.global.topStatusBar.isShow) {
|
||||
style += 'top:' + diyStore.topTabarHeight + 'px;';
|
||||
}
|
||||
// #endif
|
||||
|
||||
fixedStyleBg.value = false;
|
||||
if (diyStore.scrollTop > 20) {
|
||||
let str = diyComponent.value.fixedBgColor;
|
||||
@ -215,9 +229,14 @@
|
||||
const bgImgBoxStyle = computed(()=>{
|
||||
var style = '';
|
||||
let str = props.global.pageStartBgColor ? props.global.pageStartBgColor : 'rgba(255,255,255,1)';
|
||||
let arr = str.split('(')[1].split(')')[0].split(',');
|
||||
if(diyComponent.value.bgGradient == true)
|
||||
style += `background: linear-gradient(rgba(${arr[0]}, ${arr[1]}, ${arr[2]}, 0) 65%, rgba(${arr[0]}, ${arr[1]}, ${arr[2]}, 0.6) 70%, rgba(${arr[0]}, ${arr[1]}, ${arr[2]}, 0.85) 80%, rgba(${arr[0]}, ${arr[1]}, ${arr[2]}, 0.95) 90%, rgb(${arr[0]}, ${arr[1]}, ${arr[2]}, 1) 100%);`;
|
||||
if(str.indexOf('(') > -1) {
|
||||
let arr = str.split('(')[1].split(')')[0].split(',');
|
||||
if (diyComponent.value.bgGradient == true) {
|
||||
style += `background: linear-gradient(rgba(${arr[0]}, ${arr[1]}, ${arr[2]}, 0) 65%, rgba(${arr[0]}, ${arr[1]}, ${arr[2]}, 0.6) 70%, rgba(${arr[0]}, ${arr[1]}, ${arr[2]}, 0.85) 80%, rgba(${arr[0]}, ${arr[1]}, ${arr[2]}, 0.95) 90%, rgb(${arr[0]}, ${arr[1]}, ${arr[2]}, 1) 100%);`;
|
||||
}
|
||||
}else{
|
||||
style += `background: (${str});`;
|
||||
}
|
||||
return style;
|
||||
});
|
||||
|
||||
@ -270,6 +289,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
let tabAllPopup = ref(false);
|
||||
let menuButtonInfo:any = {};
|
||||
let navbarInnerStyle = ref('')
|
||||
|
||||
onMounted(() => {
|
||||
refresh();
|
||||
// 装修模式下刷新
|
||||
@ -283,6 +306,23 @@
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API,尚未兼容)
|
||||
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
|
||||
if(diyComponent.value.positionWay == 'fixed') {
|
||||
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
||||
// 导航栏内部盒子的样式
|
||||
// 导航栏宽度,如果在小程序下,导航栏宽度为胶囊的左边到屏幕左边的距离
|
||||
// 如果是各家小程序,导航栏内部的宽度需要减少右边胶囊的宽度
|
||||
if(props.global.topStatusBar.isShow == false) {
|
||||
let rightButtonWidth = menuButtonInfo.width ? menuButtonInfo.width * 2 + 'rpx' : '70rpx';
|
||||
navbarInnerStyle.value += 'padding-right:calc(' + rightButtonWidth + ' + 30rpx);';
|
||||
navbarInnerStyle.value += 'padding-top:' + menuButtonInfo.top + 'px;';
|
||||
}
|
||||
|
||||
}
|
||||
// #endif
|
||||
|
||||
});
|
||||
|
||||
const refresh = ()=> {
|
||||
@ -332,7 +372,9 @@
|
||||
}
|
||||
|
||||
if (item.margin) {
|
||||
item.pageStyle += 'padding-top:' + item.margin.top * 2 + 'rpx' + ';';
|
||||
if (item.margin.top > 0) {
|
||||
item.pageStyle += 'padding-top:' + item.margin.top * 2 + 'rpx' + ';';
|
||||
}
|
||||
item.pageStyle += 'padding-bottom:' + item.margin.bottom * 2 + 'rpx' + ';';
|
||||
item.pageStyle += 'padding-right:' + item.margin.both * 2 + 'rpx' + ';';
|
||||
item.pageStyle += 'padding-left:' + item.margin.both * 2 + 'rpx' + ';';
|
||||
@ -344,23 +386,6 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
let tabAllPopup = ref(false);
|
||||
|
||||
|
||||
let menuButtonInfo = {};
|
||||
let navbarInnerStyle = ref('')
|
||||
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API,尚未兼容)
|
||||
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
|
||||
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
||||
|
||||
// 导航栏内部盒子的样式
|
||||
// 导航栏宽度,如果在小程序下,导航栏宽度为胶囊的左边到屏幕左边的距离
|
||||
// style += 'height:' + this.navbarHeight + 'px;';
|
||||
// // 如果是各家小程序,导航栏内部的宽度需要减少右边胶囊的宽度
|
||||
let rightButtonWidth = menuButtonInfo.width ? menuButtonInfo.width * 2 + 'rpx' : '70rpx';
|
||||
navbarInnerStyle.value += 'padding-right:calc(' + rightButtonWidth + ' + 30rpx);';
|
||||
navbarInnerStyle.value += 'padding-top:' + menuButtonInfo.top + 'px;';
|
||||
// #endif
|
||||
|
||||
const toRedirect = (data: {}) => {
|
||||
if (Object.keys(data).length) {
|
||||
@ -409,7 +434,7 @@
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
<view class="diy-image-ads">
|
||||
<view v-if="diyComponent.list.length == 1" class="leading-0 overflow-hidden" :style="swiperWarpCss">
|
||||
<view @click="toRedirect(diyComponent.list[0].link)">
|
||||
<image v-if="diyComponent.list[0].imageUrl" :src="img(diyComponent.list[0].imageUrl)" :style="{height: imgHeight}" mode="heightFix" class="w-full" :show-menu-by-longpress="true"/>
|
||||
<image v-else :src="img('static/resource/images/diy/figure.png')" :style="{height: imgHeight}" mode="heightFix" class="w-full" :show-menu-by-longpress="true"/>
|
||||
<image v-if="diyComponent.list[0].imageUrl" :src="img(diyComponent.list[0].imageUrl)" :style="{height: imgHeight}" mode="heightFix" class="!w-full" :show-menu-by-longpress="true"/>
|
||||
<image v-else :src="img('static/resource/images/diy/figure.png')" :style="{height: imgHeight}" mode="heightFix" class="!w-full" :show-menu-by-longpress="true"/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<view :style="warpCss">
|
||||
<view class="pt-[34rpx] member-info">
|
||||
<!-- #ifdef MP-WEIXIN --><view :style="navbarInnerStyle" class="flex items-center justify-center fixed left-0 right-0 z-10 top-0"></view>
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<!-- 解决fixed定位后导航栏塌陷的问题 -->
|
||||
<view :style="navbarInnerStyle"></view>
|
||||
<!-- #endif -->
|
||||
@ -9,7 +9,9 @@
|
||||
<!-- 唤起获取微信 -->
|
||||
<u-avatar :src="img(info.headimg)" size="55" leftIcon="none" @click="clickAvatar"></u-avatar>
|
||||
<view class="ml-[22rpx]">
|
||||
<view class="text-[#222222] truncate w-[430rpx] font-bold text-lg" :style="{ color : diyComponent.textColor }">{{ info.nickname }}</view>
|
||||
<view class="text-[#222222] flex pr-[50rpx] flex-wrap items-center">
|
||||
<view class="text-[#222222] truncate max-w-[320rpx] font-bold text-lg mr-[16rpx]" :style="{ color : diyComponent.textColor }">{{ info.nickname }}</view>
|
||||
</view>
|
||||
<view class="text-[#696B70] text-[24rpx] mt-[10rpx]" :style="{ color : diyComponent.textColor }">UID:{{ info.member_no }}</view>
|
||||
</view>
|
||||
<view class="set-icon flex items-center absolute right-0 top-2">
|
||||
@ -68,7 +70,7 @@
|
||||
import { wechatSync } from '@/app/api/system'
|
||||
import useDiyStore from '@/app/stores/diy'
|
||||
|
||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount','global']);
|
||||
|
||||
const diyStore = useDiyStore();
|
||||
|
||||
@ -159,11 +161,7 @@
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
|
||||
|
||||
// 获取系统状态栏的高度
|
||||
let systemInfo = uni.getSystemInfoSync();
|
||||
let platform = systemInfo.platform;
|
||||
|
||||
let menuButtonInfo = {};
|
||||
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API,尚未兼容)
|
||||
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
|
||||
@ -175,20 +173,10 @@
|
||||
let style = '';
|
||||
// 导航栏宽度,如果在小程序下,导航栏宽度为胶囊的左边到屏幕左边的距离
|
||||
// #ifdef MP
|
||||
let rightButtonWidth = menuButtonInfo.width ? menuButtonInfo.width * 2 + 'rpx' : '70rpx';
|
||||
style += 'height:' + menuButtonInfo.height + 'px;';
|
||||
style += 'padding-right:calc(' + rightButtonWidth + ' + 30rpx);';
|
||||
style += 'padding-left:calc(' + rightButtonWidth + ' + 30rpx);';
|
||||
style += 'padding-top:' + (menuButtonInfo.top-15) + 'px;';
|
||||
style += 'padding-bottom: 8px;';
|
||||
style += 'font-size: 32rpx;';
|
||||
if (platform === 'ios') {
|
||||
// 苹果(iOS)设备
|
||||
style += 'font-weight: 500;';
|
||||
} else if (platform === 'android') {
|
||||
// 安卓(Android)设备
|
||||
style += 'font-size: 36rpx;';
|
||||
}
|
||||
if (props.global.topStatusBar.isShow == false) {
|
||||
style += 'height:' + menuButtonInfo.height + 'px;';
|
||||
style += 'padding-top:' + menuButtonInfo.top + 'px;';
|
||||
}
|
||||
// #endif
|
||||
return style;
|
||||
})
|
||||
|
||||
218
uni-app/src/app/components/diy/member-level/index.vue
Normal file
218
uni-app/src/app/components/diy/member-level/index.vue
Normal file
@ -0,0 +1,218 @@
|
||||
<template>
|
||||
<view :style="warpCss" class="overflow-hidden" v-if="info && list && list.length">
|
||||
<view v-if="diyComponent.style == 'style-1'" class="rounded-t-[16rpx] flex items-center justify-between style-bg-1 py-[20rpx] px-[30rpx]">
|
||||
<view class="flex items-end">
|
||||
<image :src="img('static/resource/images/diy/member/VIP_02.png')" mode="aspectFit" class="w-[50rpx] h-[36rpx]" />
|
||||
<text class="text-[28rpx] text-[#FFDAA8] ml-[10rpx] font-bold">{{info.member_level_name}}</text>
|
||||
</view>
|
||||
<view class="flex items-center justify-center rounded-[30rpx] box-border style-btn w-[120rpx] h-[50rpx]" @click="toLink('/app/pages/member/level')">
|
||||
<text class="text-[24rpx] text-[#333]">{{ info.member_level ? (upgradeGrowth > 0 ? '去升级' : '去查看') : '去解锁' }}</text>
|
||||
<text class="iconfont iconxiayibu1 ml-[2rpx] !text-[20rpx] text-[#333]"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="diyComponent.style == 'style-2'" class="rounded-[16rpx] flex items-center justify-between style-bg-2 p-[30rpx]">
|
||||
<view class="flex flex-col">
|
||||
<view class="flex items-center">
|
||||
<image :src="img('static/resource/images/diy/member/VIP_01.png')" mode="aspectFit" class="w-[74rpx] h-[30rpx]" />
|
||||
<text class="text-[32rpx] text-[#FFE3B1] leading-[normal] ml-[14rpx] font-bold">{{info.member_level_name}}</text>
|
||||
</view>
|
||||
<text class="text-[#fff] text-[24rpx] mt-[10rpx]" v-if="benefits_arr && benefits_arr.length">{{info.member_level_name}}购物享{{benefits_arr[0].title}}</text>
|
||||
</view>
|
||||
<view class="flex items-center justify-center rounded-[30rpx] box-border style-btn w-[120rpx] h-[50rpx]" @click="toLink('/app/pages/member/level')">
|
||||
<text class="text-[24rpx] text-[#333]">{{ info.member_level ? (upgradeGrowth > 0 ? '去升级' : '去查看') : '去解锁' }}</text>
|
||||
<text class="iconfont iconxiayibu1 ml-[2rpx] !text-[20rpx] text-[#333]"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="diyComponent.style == 'style-3'" class="rounded-[16rpx] style-bg-3 p-[30rpx]">
|
||||
<view class="flex items-center justify-between style-border-3 mb-[22rpx] pb-[22rpx]">
|
||||
<view class="flex flex-col">
|
||||
<view class="flex items-center">
|
||||
<view class="flex justify-end leading-[30rpx] box-border text-[#fff] pr-[10rpx] text-[26rpx] w-[120rpx] h-[30rpx] bg-contain bg-no-repeat" :style="{'backgroundImage': 'url('+img('static/resource/images/diy/member/VIP.png')+')'}">
|
||||
VIP.{{currIndex}}
|
||||
</view>
|
||||
<text class="text-[#733F02] ml-[8rpx] text-[30rpx] font-bold">{{info.member_level_name}}</text>
|
||||
</view>
|
||||
<text class="text-[28rpx] text-[#794200] mt-[16rpx]">购物或邀请好友可以提升等级</text>
|
||||
</view>
|
||||
<view class="flex items-center" @click="toLink('/app/pages/member/level')">
|
||||
<view class="flex flex-col items-center justify-center">
|
||||
<image :src="img('static/resource/images/diy/member/rule.png')" mode="aspectFit" class="w-[26rpx] h-[26rpx]" />
|
||||
<text class="text-[24rpx] text-[#733F02] mt-[10rpx]">规则</text>
|
||||
</view>
|
||||
<view class="ml-[10rpx] text-[#733F02] !text-[24rpx] iconfont iconxiangyoujiantou"></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex items-center justify-between">
|
||||
<view class="flex flex-col flex-1">
|
||||
<view class="overflow-hidden rounded-[20rpx]">
|
||||
<progress :percent="progress()" activeColor="#fff" backgroundColor="rgba(255,5,5,.1)" stroke-width="6" />
|
||||
</view>
|
||||
<text class="text-[24rpx] text-[#794200] mt-[16rpx]" v-if="upgradeGrowth > 0">还差{{upgradeGrowth}}成长值即可升级为{{ list[afterCurrIndex].level_name }}</text>
|
||||
<text class="text-[24rpx] text-[#794200] mt-[16rpx]" v-else>恭喜您升级为最高等级</text>
|
||||
</view>
|
||||
<view class="flex items-center rounded-[30rpx] bg-[rgb(245,230,185)] p-[16rpx] ml-[40rpx]" @click="toLink('/app/pages/member/level')">
|
||||
<text class="text-[28rpx] text-[#733F02]">{{info.member_level ? (upgradeGrowth > 0 ? '做任务' : '点击查看') : '去解锁'}}</text>
|
||||
<image :src="img('static/resource/images/diy/member/vector.png')" mode="aspectFit" class="ml-[8rpx] w-[12rpx] h-[18rpx]" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, watch, onMounted } from 'vue'
|
||||
import { img, redirect } from '@/utils/common'
|
||||
import useMemberStore from '@/stores/member'
|
||||
import { t } from '@/locale'
|
||||
import { getMemberLevel } from '@/app/api/member';
|
||||
import useDiyStore from '@/app/stores/diy'
|
||||
|
||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
||||
const diyStore = useDiyStore();
|
||||
const memberStore = useMemberStore()
|
||||
|
||||
const diyComponent = computed(() => {
|
||||
if (diyStore.mode == 'decorate') {
|
||||
return diyStore.value[props.index];
|
||||
} else {
|
||||
return props.component;
|
||||
}
|
||||
})
|
||||
|
||||
const warpCss = computed(() => {
|
||||
var style = '';
|
||||
if (diyComponent.value.topRounded) style += 'border-top-left-radius:' + diyComponent.value.topRounded * 2 + 'rpx;';
|
||||
if (diyComponent.value.topRounded) style += 'border-top-right-radius:' + diyComponent.value.topRounded * 2 + 'rpx;';
|
||||
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||
return style;
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.pullDownRefreshCount,
|
||||
(newValue, oldValue) => {
|
||||
// 处理下拉刷新业务
|
||||
}
|
||||
)
|
||||
|
||||
const info:any = computed(() => {
|
||||
// 装修模式
|
||||
if (diyStore.mode == 'decorate') {
|
||||
upgradeGrowth.value = 10;
|
||||
benefits_arr.value = [{'title': '商品包邮'}];
|
||||
currIndex.value = 1;
|
||||
list.value = [{}];
|
||||
|
||||
return {
|
||||
member_level_name: '会员等级',
|
||||
growth: 5
|
||||
}
|
||||
} else {
|
||||
if (memberStore.info) {
|
||||
getMemberLevelFn();
|
||||
}
|
||||
return memberStore.info;
|
||||
}
|
||||
})
|
||||
|
||||
// 获取会员等级列表
|
||||
let list:any = ref([])
|
||||
let upgradeGrowth = ref(0) // 升级下级会员所需的成长值
|
||||
let currIndex = ref(0) //当前会员索引
|
||||
let afterCurrIndex = ref(-1) // 下一个会员等级索引
|
||||
let benefits_arr:any = ref([]) //当前会员权益
|
||||
|
||||
const getMemberLevelFn = ()=> {
|
||||
getMemberLevel().then((res: any) => {
|
||||
list.value = res.data;
|
||||
let isSet = false;
|
||||
|
||||
// 刚进来处理会员等级数据
|
||||
if (info.value && list.value && list.value.length) {
|
||||
list.value.forEach((item: any, index: any) => {
|
||||
if (item.level_id == info.value.member_level) {
|
||||
currIndex.value = index + 1;
|
||||
// 会员权益
|
||||
if (item.level_benefits) {
|
||||
Object.values(item.level_benefits).forEach((bItem: any) => {
|
||||
if (bItem.content) {
|
||||
benefits_arr.value.push(bItem.content)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (item.growth > info.value.growth && !isSet) {
|
||||
afterCurrIndex.value = index;
|
||||
isSet = true;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (info.value.member_level) {
|
||||
if(afterCurrIndex.value == -1){
|
||||
afterCurrIndex.value = list.value.length - 1;
|
||||
}
|
||||
|
||||
if (list.value[afterCurrIndex.value] && list.value[afterCurrIndex.value].growth) {
|
||||
upgradeGrowth.value = list.value[afterCurrIndex.value].growth - info.value.growth;
|
||||
}
|
||||
}else{
|
||||
// 当前会员没有会员等级,则展示会员等级中的最后一个等级
|
||||
info.value.member_level_name = list.value[0].level_name;
|
||||
upgradeGrowth.value = list.value[0].growth;
|
||||
afterCurrIndex.value = 0;
|
||||
currIndex.value = 1;
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
// 进度条值
|
||||
let progress = () => {
|
||||
let num = 100
|
||||
if(list.value[afterCurrIndex.value] && list.value[afterCurrIndex.value].growth) {
|
||||
if(info.value.growth) {
|
||||
num = info.value.growth / list.value[afterCurrIndex.value].growth * 100
|
||||
}else{
|
||||
num = 0
|
||||
}
|
||||
}
|
||||
return num
|
||||
}
|
||||
|
||||
// 跳转链接
|
||||
const toLink = (link: string)=>{
|
||||
if (diyStore.mode == 'decorate') return false;
|
||||
redirect({ url: link })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.style-bg-1{
|
||||
background: linear-gradient(to right, #1F1313, #4D4646);
|
||||
}
|
||||
.style-btn{
|
||||
background: linear-gradient(to right, #FFEACB, #FFD195);
|
||||
}
|
||||
.style-bg-2{
|
||||
background: linear-gradient(to right, #484846, #222222);
|
||||
border-bottom-left-radius: 320rpx 16rpx;
|
||||
border-bottom-right-radius: 320rpx 16rpx;
|
||||
}
|
||||
.style-bg-3{
|
||||
background: linear-gradient(to right, #FFE6C2, #E39F42);
|
||||
}
|
||||
.style-border-3{
|
||||
position: relative;
|
||||
&:after{
|
||||
content: "";
|
||||
position: absolute;
|
||||
background: linear-gradient(to right, #F0D2A9, #DBA051);
|
||||
height: 2rpx;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -25,5 +25,6 @@
|
||||
"applyMoneyExceed": "提现金额超出可提现金额",
|
||||
"applyMoneyBelow": "提现金额小于最低提现金额",
|
||||
"replace": "更换",
|
||||
"isOpenApply": "提现设置未开启",
|
||||
"toAdd": "去添加"
|
||||
}
|
||||
@ -85,6 +85,7 @@
|
||||
|
||||
uni.getStorageSync('openid') && (Object.assign(formData, { openid: uni.getStorageSync('openid') }))
|
||||
uni.getStorageSync('pid') && (Object.assign(formData, { pid: uni.getStorageSync('pid') }))
|
||||
uni.getStorageSync('unionid') && (Object.assign(formData, { unionid: uni.getStorageSync('unionid') }))
|
||||
|
||||
const rules = {
|
||||
'mobile': [
|
||||
@ -161,6 +162,7 @@
|
||||
|
||||
request({
|
||||
openid: formData.openid,
|
||||
unionid: formData.unionid || '',
|
||||
mobile_code: e.detail.code
|
||||
}).then((res) => {
|
||||
uni.hideLoading()
|
||||
@ -175,6 +177,15 @@
|
||||
uni.hideLoading()
|
||||
})
|
||||
}
|
||||
|
||||
if(e.detail.errno == 104){
|
||||
let msg = '用户未授权隐私权限';
|
||||
uni.showToast({title: msg, icon: 'none'})
|
||||
}
|
||||
if(e.detail.errMsg == "getPhoneNumber:fail user deny"){
|
||||
let msg = '用户拒绝获取手机号码';
|
||||
uni.showToast({title: msg, icon: 'none'})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@ -88,6 +88,7 @@
|
||||
})
|
||||
|
||||
uni.getStorageSync('openid') && (Object.assign(formData, { openid: uni.getStorageSync('openid') }))
|
||||
uni.getStorageSync('unionid') && (Object.assign(formData, { unionid: uni.getStorageSync('unionid') }))
|
||||
uni.getStorageSync('pid') && (Object.assign(formData, { pid: uni.getStorageSync('pid') }))
|
||||
|
||||
const memberStore = useMemberStore()
|
||||
|
||||
@ -107,6 +107,7 @@
|
||||
|
||||
uni.getStorageSync('openid') && (Object.assign(formData, { openid: uni.getStorageSync('openid') }))
|
||||
uni.getStorageSync('pid') && (Object.assign(formData, { pid: uni.getStorageSync('pid') }))
|
||||
uni.getStorageSync('unionid') && (Object.assign(formData, { unionid: uni.getStorageSync('unionid') }))
|
||||
|
||||
const captcha = useCaptcha(formData)
|
||||
captcha.refresh()
|
||||
|
||||
@ -1,23 +1,21 @@
|
||||
<template>
|
||||
<view :style="themeColor()">
|
||||
<u-loading-page :loading="loading" loadingText="" bg-color="#f7f7f7"></u-loading-page>
|
||||
|
||||
<view v-show="!loading">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<top-tabbar v-if="!isShowTopTabbar" :title="data.title" />
|
||||
<!-- #endif -->
|
||||
<u-loading-page :loading="diy.getLoading()" loadingText="" bg-color="#f7f7f7" />
|
||||
|
||||
<view v-show="!diy.getLoading()">
|
||||
|
||||
<!-- 自定义模板渲染 -->
|
||||
<view class="diy-template-wrap bg-index" v-if="data.pageMode != 'fixed'" :style="pageStyle">
|
||||
<view class="diy-template-wrap bg-index" v-if="diy.data.pageMode != 'fixed'" :style="diy.pageStyle()">
|
||||
|
||||
<diy-group :data="data" :pullDownRefreshCount="pullDownRefreshCount"></diy-group>
|
||||
<diy-group ref="diyGroupRef" :data="diy.data" :pullDownRefreshCount="diy.pullDownRefreshCount" />
|
||||
|
||||
</view>
|
||||
|
||||
<!-- 固定模板渲染 -->
|
||||
<view class="fixed-template-wrap" v-if="data.pageMode == 'fixed'">
|
||||
<view class="fixed-template-wrap" v-if="diy.data.pageMode == 'fixed'">
|
||||
|
||||
<fixed-group :data="data" :pullDownRefreshCount="pullDownRefreshCount"></fixed-group>
|
||||
<fixed-group :data="diy.data" :pullDownRefreshCount="diy.pullDownRefreshCount" />
|
||||
|
||||
</view>
|
||||
|
||||
@ -27,162 +25,42 @@
|
||||
<!-- 小程序隐私协议 -->
|
||||
<wx-privacy-popup ref="wxPrivacyPopup"></wx-privacy-popup>
|
||||
<!-- #endif -->
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed } from 'vue';
|
||||
import { onLoad, onShow, onPullDownRefresh, onPageScroll } from '@dcloudio/uni-app';
|
||||
import { getDiyInfo } from '@/app/api/diy';
|
||||
import useDiyStore from '@/app/stores/diy';
|
||||
import { useShare } from '@/hooks/useShare'
|
||||
import { img } from '@/utils/common';
|
||||
import {ref} from 'vue';
|
||||
import {useDiy} from '@/hooks/useDiy'
|
||||
import {useShare} from '@/hooks/useShare'
|
||||
import diyGroup from '@/addon/components/diy/group/index.vue'
|
||||
import fixedGroup from '@/addon/components/fixed/group/index.vue'
|
||||
|
||||
const { setShare, onShareAppMessage, onShareTimeline } = useShare()
|
||||
onShareAppMessage()
|
||||
onShareTimeline()
|
||||
const {setShare, onShareAppMessage, onShareTimeline} = useShare()
|
||||
|
||||
const loading = ref(true);
|
||||
const diyStore = useDiyStore();
|
||||
const pullDownRefreshCount = ref(0)
|
||||
let isShowTopTabbar = ref(false);
|
||||
const diy = useDiy({})
|
||||
|
||||
const diyData = reactive({
|
||||
pageMode: 'diy',
|
||||
title: '',
|
||||
global: {},
|
||||
value: []
|
||||
})
|
||||
const diyGroupRef = ref(null)
|
||||
|
||||
const data = computed(() => {
|
||||
if (diyStore.mode == 'decorate') {
|
||||
return diyStore;
|
||||
} else {
|
||||
return diyData;
|
||||
}
|
||||
})
|
||||
onShareAppMessage()
|
||||
onShareTimeline()
|
||||
|
||||
const id = ref(0)
|
||||
const name = ref('')
|
||||
const template = ref('')
|
||||
// 监听页面加载
|
||||
diy.onLoad();
|
||||
|
||||
onLoad(option => {
|
||||
// #ifdef H5
|
||||
// 装修模式
|
||||
diyStore.mode = option.mode || '';
|
||||
if (diyStore.mode == 'decorate') {
|
||||
loading.value = false;
|
||||
}
|
||||
// #endif
|
||||
id.value = option.id || '';
|
||||
name.value = option.name || '';
|
||||
template.value = option.template || '';
|
||||
});
|
||||
|
||||
onShow(() => {
|
||||
// 装修模式
|
||||
if (diyStore.mode == 'decorate') {
|
||||
diyStore.init();
|
||||
} else {
|
||||
getDiyInfo({
|
||||
id: id.value,
|
||||
name: name.value,
|
||||
template: template.value
|
||||
}).then((res : any) => {
|
||||
if (res.data.value) {
|
||||
let data = res.data;
|
||||
diyData.pageMode = data.mode;
|
||||
diyData.title = data.title;
|
||||
|
||||
let sources = JSON.parse(data.value);
|
||||
diyData.global = sources.global;
|
||||
diyData.value = sources.value;
|
||||
diyData.value.forEach((item, index) => {
|
||||
item.pageStyle = '';
|
||||
if(item.pageStartBgColor) {
|
||||
if (item.pageStartBgColor && item.pageEndBgColor) item.pageStyle += `background:linear-gradient(${item.pageGradientAngle},${item.pageStartBgColor},${item.pageEndBgColor});`;
|
||||
else item.pageStyle += 'background-color:' + item.pageStartBgColor + ';';
|
||||
}
|
||||
|
||||
if (item.margin) {
|
||||
item.pageStyle += 'padding-top:' + item.margin.top * 2 + 'rpx' + ';';
|
||||
item.pageStyle += 'padding-bottom:' + item.margin.bottom * 2 + 'rpx' + ';';
|
||||
item.pageStyle += 'padding-right:' + item.margin.both * 2 + 'rpx' + ';';
|
||||
item.pageStyle += 'padding-left:' + item.margin.both * 2 + 'rpx' + ';';
|
||||
}
|
||||
});
|
||||
// 控制自定义头部是否出现 | 微信小程序
|
||||
isShowTopTabbar.value = diyData.value.some((item)=>{
|
||||
return item && item.position && item.position == 'top_fixed'
|
||||
})
|
||||
uni.setNavigationBarTitle({
|
||||
title: diyData.title
|
||||
})
|
||||
}
|
||||
|
||||
let share = res.data.share ? JSON.parse(res.data.share) : null;
|
||||
setShare(share);
|
||||
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const pageStyle = computed(()=>{
|
||||
var style = '';
|
||||
if (data.value.global.pageStartBgColor && data.value.global.pageEndBgColor) style += `background:linear-gradient(${data.value.global.pageGradientAngle},${data.value.global.pageStartBgColor},${data.value.global.pageEndBgColor});`;
|
||||
else style += 'background-color:' + data.value.global.pageStartBgColor + ';';
|
||||
|
||||
style += 'min-height:calc(100vh - 50px);';
|
||||
if(data.value.global.bgUrl) {
|
||||
style += `background-image:url('${ img(data.value.global.bgUrl) }');`;
|
||||
}
|
||||
|
||||
if (data.value.global.bgHeightScale) {
|
||||
style += `background-size: 100% ${data.value.global.bgHeightScale}%;`;
|
||||
}
|
||||
|
||||
return style;
|
||||
// 监听页面显示
|
||||
diy.onShow((data: any) => {
|
||||
let share = data.share ? JSON.parse(data.share) : null;
|
||||
setShare(share);
|
||||
diyGroupRef.value?.refresh();
|
||||
});
|
||||
|
||||
// 监听下拉刷新事件
|
||||
onPullDownRefresh(() => {
|
||||
pullDownRefreshCount.value++;
|
||||
uni.stopPullDownRefresh();
|
||||
})
|
||||
diy.onPullDownRefresh()
|
||||
|
||||
onPageScroll((e)=>{
|
||||
if(e.scrollTop > 0)
|
||||
diyStore.scrollTop = e.scrollTop;
|
||||
})
|
||||
// 监听滚动事件
|
||||
diy.onPageScroll()
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '@/styles/diy.scss';
|
||||
</style>
|
||||
<style lang="scss">
|
||||
.diy-template-wrap {
|
||||
::v-deep .diy-group {
|
||||
> .draggable-element.top-fixed-diy {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
/* #ifdef MP */
|
||||
.child-diy-template-wrap {
|
||||
::v-deep .diy-group {
|
||||
> .draggable-element.top-fixed-diy {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* #endif */
|
||||
/* #ifdef H5 */
|
||||
:deep(.child-diy-template-wrap) {
|
||||
.diy-group .draggable-element.top-fixed-diy{
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
/* #endif */
|
||||
}
|
||||
</style>
|
||||
@ -1,23 +1,21 @@
|
||||
<template>
|
||||
<view :style="themeColor()">
|
||||
<u-loading-page :loading="loading" loadingText="" bg-color="#f7f7f7"></u-loading-page>
|
||||
|
||||
<view v-show="!loading">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<top-tabbar v-if="!isShowTopTabbar" :title="data.title" />
|
||||
<!-- #endif -->
|
||||
<u-loading-page :loading="diy.getLoading()" loadingText="" bg-color="#f7f7f7" />
|
||||
|
||||
<view v-show="!diy.getLoading()">
|
||||
|
||||
<!-- 自定义模板渲染 -->
|
||||
<view class="diy-template-wrap bg-index" v-if="data.pageMode != 'fixed'" :style="pageStyle">
|
||||
<view class="diy-template-wrap bg-index" v-if="diy.data.pageMode != 'fixed'" :style="diy.pageStyle()">
|
||||
|
||||
<diy-group :data="data" :pullDownRefreshCount="pullDownRefreshCount"></diy-group>
|
||||
<diy-group ref="diyGroupRef" :data="diy.data" :pullDownRefreshCount="diy.pullDownRefreshCount" />
|
||||
|
||||
</view>
|
||||
|
||||
<!-- 固定模板渲染 -->
|
||||
<view class="fixed-template-wrap" v-if="data.pageMode == 'fixed'">
|
||||
<view class="fixed-template-wrap" v-if="diy.data.pageMode == 'fixed'">
|
||||
|
||||
<fixed-group :data="data" :pullDownRefreshCount="pullDownRefreshCount"></fixed-group>
|
||||
<fixed-group :data="diy.data" :pullDownRefreshCount="diy.pullDownRefreshCount" />
|
||||
|
||||
</view>
|
||||
|
||||
@ -27,164 +25,52 @@
|
||||
<!-- 小程序隐私协议 -->
|
||||
<wx-privacy-popup ref="wxPrivacyPopup"></wx-privacy-popup>
|
||||
<!-- #endif -->
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed } from 'vue';
|
||||
import { onLoad, onShow, onPullDownRefresh, onPageScroll } from '@dcloudio/uni-app';
|
||||
import { getDiyInfo } from '@/app/api/diy';
|
||||
import useDiyStore from '@/app/stores/diy';
|
||||
import { useShare } from '@/hooks/useShare'
|
||||
import { img,redirect } from '@/utils/common';
|
||||
import {ref} from 'vue';
|
||||
import {useDiy} from '@/hooks/useDiy'
|
||||
import {useShare} from '@/hooks/useShare'
|
||||
import {redirect} from '@/utils/common';
|
||||
import diyGroup from '@/addon/components/diy/group/index.vue'
|
||||
import fixedGroup from '@/addon/components/fixed/group/index.vue'
|
||||
|
||||
const { setShare, onShareAppMessage, onShareTimeline } = useShare()
|
||||
setShare();
|
||||
onShareAppMessage()
|
||||
onShareTimeline()
|
||||
const {setShare, onShareAppMessage, onShareTimeline} = useShare()
|
||||
|
||||
const loading = ref(true);
|
||||
const diyStore = useDiyStore();
|
||||
const pullDownRefreshCount = ref(0)
|
||||
let isShowTopTabbar = ref(false);
|
||||
const diy = useDiy({
|
||||
name: 'DIY_INDEX'
|
||||
})
|
||||
|
||||
const id = ref(0)
|
||||
const name = ref('DIY_INDEX')
|
||||
const template = ref('')
|
||||
const diyGroupRef = ref(null)
|
||||
|
||||
// 自定义页面 数据
|
||||
const diyData = reactive({
|
||||
pageMode: 'diy',
|
||||
title: '',
|
||||
global: {},
|
||||
value: []
|
||||
})
|
||||
setShare();
|
||||
onShareAppMessage()
|
||||
onShareTimeline()
|
||||
|
||||
const data = computed(() => {
|
||||
if (diyStore.mode == 'decorate') {
|
||||
return diyStore;
|
||||
} else {
|
||||
return diyData;
|
||||
}
|
||||
})
|
||||
// 监听页面加载
|
||||
diy.onLoad();
|
||||
|
||||
onLoad(option => {
|
||||
// #ifdef H5
|
||||
// 装修模式
|
||||
diyStore.mode = option.mode || '';
|
||||
if (diyStore.mode == 'decorate') {
|
||||
loading.value = false;
|
||||
}
|
||||
// #endif
|
||||
id.value = option.id || '';
|
||||
template.value = option.template || '';
|
||||
});
|
||||
|
||||
onShow(() => {
|
||||
// 装修模式
|
||||
if (diyStore.mode == 'decorate') {
|
||||
diyStore.init();
|
||||
} else {
|
||||
getDiyInfo({
|
||||
id: id.value,
|
||||
name: name.value,
|
||||
template: template.value
|
||||
}).then((res : any) => {
|
||||
let data = res.data;
|
||||
if (data.value) {
|
||||
diyData.pageMode = data.mode;
|
||||
diyData.title = data.title;
|
||||
|
||||
let sources = JSON.parse(data.value);
|
||||
diyData.global = sources.global;
|
||||
diyData.value = sources.value;
|
||||
diyData.value.forEach((item, index) => {
|
||||
item.pageStyle = '';
|
||||
if(item.pageStartBgColor) {
|
||||
if (item.pageStartBgColor && item.pageEndBgColor) item.pageStyle += `background:linear-gradient(${item.pageGradientAngle},${item.pageStartBgColor},${item.pageEndBgColor});`;
|
||||
else item.pageStyle += 'background-color:' + item.pageStartBgColor + ';';
|
||||
}
|
||||
|
||||
if (item.margin) {
|
||||
item.pageStyle += 'padding-top:' + item.margin.top * 2 + 'rpx' + ';';
|
||||
item.pageStyle += 'padding-bottom:' + item.margin.bottom * 2 + 'rpx' + ';';
|
||||
item.pageStyle += 'padding-right:' + item.margin.both * 2 + 'rpx' + ';';
|
||||
item.pageStyle += 'padding-left:' + item.margin.both * 2 + 'rpx' + ';';
|
||||
}
|
||||
});
|
||||
// 控制自定义头部是否出现 | 微信小程序
|
||||
isShowTopTabbar.value = diyData.value.some((item)=>{
|
||||
return item && item.position && item.position == 'top_fixed'
|
||||
})
|
||||
// uni.setNavigationBarTitle({
|
||||
// title: diyData.title
|
||||
// })
|
||||
} else if (data.page) {
|
||||
// 跳转到设置的启动页
|
||||
redirect({ url: data.page, mode : 'reLaunch' })
|
||||
}
|
||||
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
const pageStyle = computed(()=>{
|
||||
var style = '';
|
||||
if (data.value.global.pageStartBgColor && data.value.global.pageEndBgColor) style += `background:linear-gradient(${data.value.global.pageGradientAngle},${data.value.global.pageStartBgColor},${data.value.global.pageEndBgColor});`;
|
||||
else style += 'background-color:' + data.value.global.pageStartBgColor + ';';
|
||||
|
||||
style += 'min-height:calc(100vh - 50px);';
|
||||
if(data.value.global.bgUrl) {
|
||||
style += `background-image:url('${ img(data.value.global.bgUrl) }');`;
|
||||
// 监听页面显示
|
||||
diy.onShow((data: any) => {
|
||||
if (data.value) {
|
||||
// uni.setNavigationBarTitle({
|
||||
// title: diyData.title
|
||||
// })
|
||||
} else if (data.page) {
|
||||
// 跳转到设置的启动页
|
||||
redirect({url: data.page, mode: 'reLaunch'})
|
||||
}
|
||||
|
||||
if (data.value.global.bgHeightScale) {
|
||||
style += `background-size: 100% ${data.value.global.bgHeightScale}%;`;
|
||||
}
|
||||
|
||||
return style;
|
||||
diyGroupRef.value?.refresh();
|
||||
});
|
||||
|
||||
// 监听下拉刷新事件
|
||||
onPullDownRefresh(() => {
|
||||
pullDownRefreshCount.value++;
|
||||
uni.stopPullDownRefresh();
|
||||
})
|
||||
diy.onPullDownRefresh()
|
||||
|
||||
onPageScroll((e)=>{
|
||||
if(e.scrollTop > 0)
|
||||
diyStore.scrollTop = e.scrollTop;
|
||||
})
|
||||
// 监听滚动事件
|
||||
diy.onPageScroll()
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '@/styles/diy.scss';
|
||||
</style>
|
||||
<style lang="scss">
|
||||
.diy-template-wrap {
|
||||
::v-deep .diy-group {
|
||||
> .draggable-element.top-fixed-diy {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
/* #ifdef MP */
|
||||
.child-diy-template-wrap {
|
||||
::v-deep .diy-group {
|
||||
> .draggable-element.top-fixed-diy {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* #endif */
|
||||
/* #ifdef H5 */
|
||||
:deep(.child-diy-template-wrap) {
|
||||
.diy-group .draggable-element.top-fixed-diy{
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
/* #endif */
|
||||
}
|
||||
</style>
|
||||
@ -69,9 +69,9 @@
|
||||
}
|
||||
|
||||
const handleClick = (data: AnyObject) => {
|
||||
if (mode.value == 'get') redirect({ url: '/app/pages/member/account_edit', param: { id: data.account_id, type: accountType.value, mode: mode.value } })
|
||||
else redirect({ url: '/app/pages/member/apply_cash_out', param: { account_id: data.account_id, type: accountType.value } })
|
||||
if (mode.value == 'get') redirect({ url: '/app/pages/member/account_edit', param: { id: data.account_id, type: accountType.value, mode: mode.value }, mode: 'redirectTo' })
|
||||
else redirect({ url: '/app/pages/member/apply_cash_out', param: { account_id: data.account_id, type: accountType.value }, mode: 'redirectTo'})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped></style>
|
||||
@ -128,7 +128,7 @@
|
||||
|
||||
save(formData).then((res) => {
|
||||
if (mode.value == 'get') redirect({ url: '/app/pages/member/account', param: { type: formData.account_type, mode: mode.value } })
|
||||
else redirect({ url: '/app/pages/member/apply_cash_out', param: { account_id: res.data.id, type: formData.account_type } })
|
||||
else redirect({ url: '/app/pages/member/apply_cash_out', param: { account_id: res.data.id, type: formData.account_type } , mode: 'redirectTo'})
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
@ -120,7 +120,7 @@
|
||||
key: 'selectAddressCallback',
|
||||
data: selectAddress,
|
||||
success() {
|
||||
redirect({url: selectAddress.back,mode:'redirectTo' })
|
||||
redirect({url: selectAddress.back, mode: 'redirectTo'})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
</u-form-item>
|
||||
</view>
|
||||
<view class="mt-[40rpx]">
|
||||
<u-button type="primary" shape="circle" :text="t('save')" @click="save" :loading="operateLoading"></u-button>
|
||||
<u-button type="primary" shape="circle" :text="t('save')" @click="save" :disabled="btnDisabled" :loading="operateLoading"></u-button>
|
||||
</view>
|
||||
</u-form>
|
||||
<area-select ref="areaRef" @complete="areaSelectComplete" :area-id="formData.district_id"/>
|
||||
@ -61,6 +61,7 @@
|
||||
const formRef = ref(null)
|
||||
const type = ref('')
|
||||
const source = ref('')
|
||||
const btnDisabled = ref(false)
|
||||
|
||||
onLoad((data) => {
|
||||
if (data.id) {
|
||||
@ -129,20 +130,28 @@
|
||||
const operateLoading = ref(false)
|
||||
const save = ()=> {
|
||||
const save = formData.value.id ? editAddress : addAddress
|
||||
|
||||
|
||||
formRef.value.validate().then(() => {
|
||||
if (operateLoading.value) return
|
||||
operateLoading.value = true
|
||||
|
||||
|
||||
btnDisabled.value = true
|
||||
|
||||
formData.value.full_address = formData.value.area + formData.value.address
|
||||
|
||||
|
||||
save(formData.value).then((res) => {
|
||||
operateLoading.value = false
|
||||
setTimeout(()=> {
|
||||
redirect({ url: '/app/pages/member/address', param: { type: type.value, source : source.value } })
|
||||
setTimeout(() => {
|
||||
btnDisabled.value = false
|
||||
redirect({
|
||||
url: '/app/pages/member/address',
|
||||
mode: 'redirectTo',
|
||||
param: {type: type.value, source: source.value}
|
||||
})
|
||||
}, 1000)
|
||||
}).catch(() => {
|
||||
operateLoading.value = false
|
||||
btnDisabled.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -1,110 +1,110 @@
|
||||
<template>
|
||||
<view :style="themeColor()">
|
||||
<scroll-view scroll-y="true" class="w-screen h-screen bg-page" v-if="!pageLoading">
|
||||
<view>
|
||||
<view class="p-[30rpx] bg-white">
|
||||
<view>{{t('cashOutMoneyTip')}}</view>
|
||||
<view class="flex py-[20rpx] items-baseline border-0 border-b-[2rpx] border-solid border-gray-200">
|
||||
<text class="text-[60rpx] ">{{ t('currency') }}</text>
|
||||
<input type="digit" class="h-[70rpx] leading-[70rpx] pl-[10rpx] flex-1 font-bold text-[60rpx]" v-model="applyData.apply_money" maxlength="7" />
|
||||
<image @click="clearMoney" v-if="applyData.apply_money"
|
||||
:src="img('static/resource/images/member/apply_withdrawal/close.png')" class="w-[40rpx] h-[40rpx]"
|
||||
mode="widthFix" />
|
||||
</view>
|
||||
<view class="pt-[20rpx]">
|
||||
<text class="text-gray-400 text-[28rpx]">{{t('money')}}:{{ t('currency') }}{{ moneyFormat(cashOutMoney) }}</text>
|
||||
<text class="pl-[10rpx] text-[28rpx] text-primary" @click="allMoney">{{t('allTx')}}</text>
|
||||
</view>
|
||||
<view>
|
||||
<text class="text-[24rpx] text-gray-400">{{t('minWithdrawal')}}{{ t('currency') }}{{ moneyFormat(config.min) }}</text>
|
||||
<text class="text-[24rpx] text-gray-400">,{{t('commissionTo')}}{{ config.rate + '%' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view scroll-y="true" class="w-screen h-screen bg-page" v-if="!pageLoading && config.is_open == 1">
|
||||
<view>
|
||||
<view class="p-[30rpx] bg-white">
|
||||
<view>{{t('cashOutMoneyTip')}}</view>
|
||||
<view class="flex py-[20rpx] items-baseline border-0 border-b-[2rpx] border-solid border-gray-200">
|
||||
<text class="text-[60rpx] ">{{ t('currency') }}</text>
|
||||
<input type="digit" class="h-[70rpx] leading-[70rpx] pl-[10rpx] flex-1 font-bold text-[60rpx]" v-model="applyData.apply_money" maxlength="7" />
|
||||
<image @click="clearMoney" v-if="applyData.apply_money"
|
||||
:src="img('static/resource/images/member/apply_withdrawal/close.png')" class="w-[40rpx] h-[40rpx]"
|
||||
mode="widthFix" />
|
||||
</view>
|
||||
<view class="pt-[20rpx]">
|
||||
<text class="text-gray-400 text-[28rpx]">{{t('money')}}:{{ t('currency') }}{{ moneyFormat(cashOutMoney) }}</text>
|
||||
<text class="pl-[10rpx] text-[28rpx] text-primary" @click="allMoney">{{t('allTx')}}</text>
|
||||
</view>
|
||||
<view>
|
||||
<text class="text-[24rpx] text-gray-400">{{t('minWithdrawal')}}{{ t('currency') }}{{ moneyFormat(config.min) }}</text>
|
||||
<text class="text-[24rpx] text-gray-400">,{{t('commissionTo')}}{{ config.rate + '%' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="px-[30rpx] bg-white mt-[30rpx]">
|
||||
<!-- 提现到微信 -->
|
||||
<view class="py-[30rpx] flex" v-if="config.transfer_type.includes('wechat') && memberStore.info && (memberStore.info.wx_openid || memberStore.info.weapp_openid)">
|
||||
<view><text class="iconfont iconweixin1 text-[#43c93e] text-[70rpx]"></text></view>
|
||||
<view class="flex-1 px-[20rpx]">
|
||||
<view>{{ t('cashOutToWechat') }}</view>
|
||||
<view class="text-[#bbb] text-[26rpx] mt-[16rpx]">{{ t('cashOutToWechatTips') }}</view>
|
||||
</view>
|
||||
<view class="flex items-center" @click="applyData.transfer_type = 'wechat'">
|
||||
<text class="iconfont iconduigou text-[40rpx] text-primary" v-if="applyData.transfer_type == 'wechat'"></text>
|
||||
<text class="iconfont iconcheckbox_nol text-[40rpx] text-[#bbb]" v-else></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="px-[30rpx] bg-white mt-[30rpx]">
|
||||
<!-- 提现到微信 -->
|
||||
<view class="py-[30rpx] flex" v-if="config.transfer_type.includes('wechatpay') && memberStore.info && (memberStore.info.wx_openid || memberStore.info.weapp_openid)">
|
||||
<view><text class="iconfont iconweixin1 text-[#43c93e] text-[70rpx]"></text></view>
|
||||
<view class="flex-1 px-[20rpx]">
|
||||
<view>{{ t('cashOutToWechat') }}</view>
|
||||
<view class="text-[#bbb] text-[26rpx] mt-[16rpx]">{{ t('cashOutToWechatTips') }}</view>
|
||||
</view>
|
||||
<view class="flex items-center" @click="applyData.transfer_type = 'wechatpay'">
|
||||
<text class="iconfont iconduigou text-[40rpx] text-primary" v-if="applyData.transfer_type == 'wechatpay'"></text>
|
||||
<text class="iconfont iconcheckbox_nol text-[40rpx] text-[#bbb]" v-else></text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 提现到支付宝 -->
|
||||
<view class="py-[30rpx] flex" v-if="config.transfer_type.includes('alipay')">
|
||||
<view><text class="iconfont iconzhifubaoxuanzhong text-[#188dfb] text-[70rpx]"></text></view>
|
||||
<view class="flex-1 px-[20rpx]">
|
||||
<view>{{ t('cashOutToAlipay') }}</view>
|
||||
<view class="text-[#bbb] text-[26rpx] mt-[16rpx]">
|
||||
<view v-if="alipayAccountInfo">
|
||||
{{ t('cashOutTo') }}{{ t('alipayAccountNo') }}{{ alipayAccountInfo.account_no }} <text class="text-black" @click="redirect({ url: '/app/pages/member/account', param: { type: 'alipay', mode: 'select' } })">{{ t('replace') }}</text>
|
||||
</view>
|
||||
<view v-else>
|
||||
{{ t('cashOutToAlipayTips') }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex items-center">
|
||||
<u-button :plain="true" type="primary" shape="circle" :custom-style="{height: '56rpx'}" v-if="!alipayAccountInfo" @click="redirect({ url: '/app/pages/member/account', param: { type: 'alipay', mode: 'select' } })">{{ t('toAdd') }}</u-button>
|
||||
<view v-else @click="applyData.transfer_type = 'alipay'">
|
||||
<text class="iconfont iconduigou text-[40rpx] text-primary" v-if="applyData.transfer_type == 'alipay'"></text>
|
||||
<text class="iconfont iconcheckbox_nol text-[40rpx] text-[#bbb]" v-else></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 提现到支付宝 -->
|
||||
<view class="py-[30rpx] flex" v-if="config.transfer_type.includes('alipay')">
|
||||
<view><text class="iconfont iconzhifubaoxuanzhong text-[#188dfb] text-[70rpx]"></text></view>
|
||||
<view class="flex-1 px-[20rpx]">
|
||||
<view>{{ t('cashOutToAlipay') }}</view>
|
||||
<view class="text-[#bbb] text-[26rpx] mt-[16rpx]">
|
||||
<view v-if="alipayAccountInfo">
|
||||
{{ t('cashOutTo') }}{{ t('alipayAccountNo') }}{{ alipayAccountInfo.account_no }} <text class="text-black" @click="redirect({ url: '/app/pages/member/account', param: { type: 'alipay', mode: 'select' } , mode: 'redirectTo'})">{{ t('replace') }}</text>
|
||||
</view>
|
||||
<view v-else>
|
||||
{{ t('cashOutToAlipayTips') }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex items-center">
|
||||
<u-button :plain="true" type="primary" shape="circle" :custom-style="{height: '56rpx'}" v-if="!alipayAccountInfo" @click="redirect({ url: '/app/pages/member/account', param: { type: 'alipay', mode: 'select' } , mode: 'redirectTo'})">{{ t('toAdd') }}</u-button>
|
||||
<view v-else @click="applyData.transfer_type = 'alipay'">
|
||||
<text class="iconfont iconduigou text-[40rpx] text-primary" v-if="applyData.transfer_type == 'alipay'"></text>
|
||||
<text class="iconfont iconcheckbox_nol text-[40rpx] text-[#bbb]" v-else></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 提现到银行卡 -->
|
||||
<view class="py-[30rpx] flex" v-if="config.transfer_type.includes('bank')">
|
||||
<view class="w-[70rpx] flex justify-center">
|
||||
<image
|
||||
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAACnVJREFUeF7tWXtQVNcZ/91FQQZZdhcXfKCCqFXQuKBV0YSHqWJ9AbU+qkZQG+uEyu66i0maB5jEaSetBdvG1vrCRhM1bQS1SUw6gn0kJhkDpqLNQ10jLApEHmrCuuyeznfWRZZd3L03/MOw38zOPfee8517vt/5fY9zV0AfF6GP2w8/AH4G9HEE/C7QxwngD4J+F/C7QB9HwO8CfZwA/iwgyQWuQznBBmGxAKGdwd4u41e0070Ndhtd7z2zUT+DYKN7GWzt14PDAtZOXfIjgLULYNaziuGfQ0A73QPMxtt2wdGG0H6vzwaB2kI7omyjoMZkMFgRav8MTGZFP+Eu7PZ23gaz8nGMWRHArGABVtht7QiQfY08Q2VXxosGwAzlVkDQAggR6z7bx87EjrEzcKtfkFhVIBjAcAYMZeJ1uYbwDWR4BnmG4s4TiALAjPBfAuwpKSvYFTsVBRPnSFF16ExigFKq8R2vvQmdMVwSAGYoVwHCq1IsqA4bjIXJOWgL6CdFHYhljt3vCWEsDfr8CudUPjOgFqpDArBMyhp2x07F899l96fbgQFS3uxBp/l2AAoL7aIBMEN1GUCMlGXkTsnE0agJUlSBgQCmdKxX2hz3tf4NnfER0S5QA4VGBplbBPV1NTNm58IUovR1uOu4IQC+10MACMJWaA3PigbADOV6QNgpxYKL8gg8Omu9FFWHzlg7MFS6uoumTJaOvE3vSgBAtRvAOinLeH2kBoaEBVJUHTqT7UCodHUXzf7BocjNvS0agFqoPhWAiQMy56HfpAmwXb2Gb0te5/MEps5EYMpMWMrehrXqv24r3ayZhwPRiZIsSNVEISV9mItuVUMDyi5/KX4+AR9Ba5zWVdFrFriOsBg7AigAYlBlBfprJuLb/YfQnJPL5wqvOMYBaExI9QjA7LSfgtKgFCktWIQMTSzONTZAERSEkaFyPs2a995ByYVqcVMK7DfQ5ueLBsAM5QpAOEiKQ9jXXL8p6zG0lb7F2/SMtbTiusI9QZiD5ZiSniduoZ1GN732BBTBQYjZtwum1lZUrVyNSYPU2PLhByg88764ee1sETblH5cAgIpKRy1RPbz8GNe/oRwFe3MLZwOxoq3sbTRlruJ9MkUY7yM5NiwOh9bkISU+CvvLL8BU39rtohUhjvKYrjROE6NG5W9X4eqtVkTv3cUZULliNaLlciS89iqqGurFAWBlkcjPd1Py6gJ1UL3PgKQQ3QbIi7bCeu48GjUp/OXOZ636Z/g99dtMXyEgegQH4bllzyJi41pER8iR87uT3Kh9G9P5ffMdC9Kee4MbfPSpRR3G03Plqh3QLUxE0doUvvOll75AZuwYbvz+i9WoqLmGouQ0mFpb0GyxICYsDJnHy3B0QQYHjNhB7e1VnziYwnAOeqPGE2IPBOAmlGFtEIj3AYqSVxCcvdzF/5WlBzAg44fc/wkM6r+95WUMLNjM3/WDec9gd8mT3GAy6srOdWj5xgLdngpu9PYTlRyIgmXTeTtzWixGquUQsopQYkhH9sNx3CACodnShtJLX/J2+eKlHAiS7PHxvE0xgZ6frq0BY4yDojn4Fw4QGH4PvdGjLz4QgBoo58sgnKAXOYPdne070ar7Bad6ZNNlnhHqozUdAbJOCOdxof1qDZKKTuHj4tU4XV2DklMXsG/jHGw5fIZT3NlOnRDFXSTmZ3tQ/uISKAcGQbFyB67sWYdolTvdSxdmIGPUaO4GmbGjUTAtCfp/VqC48iyY1tCxyS6BUmDLoM0/IpoBZihfAgTOb+duE7UtpW/x9EdUp4B4t+I/HAxyDwKHYsWVwyfwQn1gh6E0B+10yalqaGIiEBMph0Z/gPu5IIC3iSEEFrkLZ4vFAsWf/uCy7oofL0PKsChknSjjbtA5JjgBIBak/vXwfT1mjYH+aZMEAFRUNc0mRTI2tPBJbjiJteo87hT/kRtPwVBevJW3qRYgd3jzZCU+mzQFtMOFhz5A1ZUGlD69iO922UeX+DOif8VLS1D64SUOTPG6VM4UU30LCh9PQtXNeuhOl7usOycuHsXJaWi+a+FpsTNIzizhGiSFi9AZ4rqLmA90ATNUzQDCxIVbx+iVST9BeWSsFFWAEkKSuPqfmHBlzeM8HuS8+06n9wo7oTNsEA3ADaiSbIDIZHv/NXHzDGgOpM84EkTNgHhx53+K+mlRwxG9b5cj8DmFCWugN5SIBqAOKiMDfi1h+ahSDMG81O6PDuTflBmKj3+Cc6ZGnh61CxK4K1AmcAr5OUX+pg0/548o7WnUES5LIrpTcVQyZ67nAokFxEGvvygaADNUbwLIkgJAd5+/KOdTpKcASDGBhHyegiOlx+LjlRipDkXO3Hgog4N4AKRIT7vrzP/7Zs/l+Z0kZ3w8qhod8xA4rtTnjy9DZ3ygH3YbA8xQ1QBwPYn4iMb6qYtxYuh4t9G061QIVZy/1tF3ztTAawK6UlAk4ZXjPV8uTkmDVpPIix+qBokBlPYyRrna1XLXwoshF2HYD70x50HL9giAGeHjANYtbbzh8P30jagNdo+dBEBJXrpLaUysIPoTIwgAhTwImhFqpP3tCDeaAhulSdpd2n2HoaWIlofxe2cf+b2H8jgXOuMO0QDUQrVOAOgbgGgxhagwY/YTHvVyZsVzY8nnnf5P91T8EP0zpsZi/6fVyJgWy098ZGTlisc4EFQBUgokZjhPhalRw3nAI8OJFW4ACJgCrfGsaADqoNrLgDWirQdwZMRD0CU6avuu4qzvie4U8JwVYeeS2NTUihabhZexuoTJKEpO5UYTGFQAUdAjV6C4QFdnGUzGu0R/oBY6Y5Q3G7pxAdX/6EucN2VP/fma+TgYneBRlYoiCoL6vac5A4gRVBJn/eoYrw4pGAovb+N1ABlHtT35PFV1hdNn8DYdjQkYnSaRF0NNbW0cFA/yBnTGpd5scAPgOgZG2BF4w5tid/2pj27A56GDPHYXLk/iRtLOUzVI/p+d5ijSiBWTotW8Tf5PhQ35eFchV6A+chFyAToMdfOBxAidcZs3O9wAMCM8C2CUAkVLc/9gxM2/fyDpOgEZTP5PQiBQ0HPeUxDUJKqBkYz7fGdxRn9KdeQKTr93PvdAf8BuT8amzf/yZoQHAFSE2iZvip763xs8FtnTvbKu+6nHMGCYuArQ82RCA4beisLSwrve7HADoBaqMwLg9vHQ20TUvzV+Fl4ZM8OXoZ7H9NQXYIa/Q2/06VO0CwAM6FcHlVWqBRmPZOPj8OHS1GUAksUdgLp9kSA8D63hRV8W4gLANShSAyBzPX/6Msu9MUMzXf50EaFJHwMZoOkJ+vPXzoXOeNKXBXRlQGCd4wgs6Ri3Kmk5TkWO9uW97mOIAQ/bAbp+N9kGndHo6xSegqDkf4G2jUsG/STLODsg7S8EQIAZEP4MrWGLmPd7LIS+AIIGQJEkZqLOYwseSudfYL8KCav/R+QYs6h51BiMMAxGsKwRKjsdyHyTTv/5+6bgGOX1s7iYyXrjWD8AvXHXenLNfgb0JJq9cS4/A3rjrvXkmv0M6Ek0e+Ncfgb0xl3ryTX7GdCTaPbGufo8A/4PpckqfWjPHTQAAAAASUVORK5CYII="
|
||||
mode="widthFix" class="w-[60rpx]"></image>
|
||||
</view>
|
||||
<view class="flex-1 px-[20rpx]">
|
||||
<view>{{ t('cashOutToBank') }}</view>
|
||||
<view class="text-[#bbb] text-[26rpx] mt-[16rpx]">
|
||||
<view v-if="bankAccountInfo">
|
||||
{{ t('cashOutTo') }}{{ bankAccountInfo.bank_name }}{{ t('debitCard') }}{{ bankAccountInfo.account_no.substring(bankAccountInfo.account_no.length - 4) }} <text class="text-black" @click="redirect({ url: '/app/pages/member/account', param: { type: 'bank', mode: 'select' } })">{{ t('replace') }}</text>
|
||||
</view>
|
||||
<view v-else>
|
||||
{{ t('cashOutToBankTips') }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex items-center">
|
||||
<u-button :plain="true" type="primary" shape="circle" :custom-style="{height: '56rpx'}" v-if="!bankAccountInfo" @click="redirect({ url: '/app/pages/member/account', param: { type: 'bank', mode: 'select' } })">{{ t('toAdd') }}</u-button>
|
||||
<view v-else @click="applyData.transfer_type = 'bank'">
|
||||
<text class="iconfont iconduigou text-[40rpx] text-primary" v-if="applyData.transfer_type == 'bank'"></text>
|
||||
<text class="iconfont iconcheckbox_nol text-[40rpx] text-[#bbb]" v-else></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 提现到银行卡 -->
|
||||
<view class="py-[30rpx] flex" v-if="config.transfer_type.includes('bank')">
|
||||
<view class="w-[70rpx] flex justify-center">
|
||||
<image
|
||||
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAACnVJREFUeF7tWXtQVNcZ/91FQQZZdhcXfKCCqFXQuKBV0YSHqWJ9AbU+qkZQG+uEyu66i0maB5jEaSetBdvG1vrCRhM1bQS1SUw6gn0kJhkDpqLNQ10jLApEHmrCuuyeznfWRZZd3L03/MOw38zOPfee8517vt/5fY9zV0AfF6GP2w8/AH4G9HEE/C7QxwngD4J+F/C7QB9HwO8CfZwA/iwgyQWuQznBBmGxAKGdwd4u41e0070Ndhtd7z2zUT+DYKN7GWzt14PDAtZOXfIjgLULYNaziuGfQ0A73QPMxtt2wdGG0H6vzwaB2kI7omyjoMZkMFgRav8MTGZFP+Eu7PZ23gaz8nGMWRHArGABVtht7QiQfY08Q2VXxosGwAzlVkDQAggR6z7bx87EjrEzcKtfkFhVIBjAcAYMZeJ1uYbwDWR4BnmG4s4TiALAjPBfAuwpKSvYFTsVBRPnSFF16ExigFKq8R2vvQmdMVwSAGYoVwHCq1IsqA4bjIXJOWgL6CdFHYhljt3vCWEsDfr8CudUPjOgFqpDArBMyhp2x07F899l96fbgQFS3uxBp/l2AAoL7aIBMEN1GUCMlGXkTsnE0agJUlSBgQCmdKxX2hz3tf4NnfER0S5QA4VGBplbBPV1NTNm58IUovR1uOu4IQC+10MACMJWaA3PigbADOV6QNgpxYKL8gg8Omu9FFWHzlg7MFS6uoumTJaOvE3vSgBAtRvAOinLeH2kBoaEBVJUHTqT7UCodHUXzf7BocjNvS0agFqoPhWAiQMy56HfpAmwXb2Gb0te5/MEps5EYMpMWMrehrXqv24r3ayZhwPRiZIsSNVEISV9mItuVUMDyi5/KX4+AR9Ba5zWVdFrFriOsBg7AigAYlBlBfprJuLb/YfQnJPL5wqvOMYBaExI9QjA7LSfgtKgFCktWIQMTSzONTZAERSEkaFyPs2a995ByYVqcVMK7DfQ5ueLBsAM5QpAOEiKQ9jXXL8p6zG0lb7F2/SMtbTiusI9QZiD5ZiSniduoZ1GN732BBTBQYjZtwum1lZUrVyNSYPU2PLhByg88764ee1sETblH5cAgIpKRy1RPbz8GNe/oRwFe3MLZwOxoq3sbTRlruJ9MkUY7yM5NiwOh9bkISU+CvvLL8BU39rtohUhjvKYrjROE6NG5W9X4eqtVkTv3cUZULliNaLlciS89iqqGurFAWBlkcjPd1Py6gJ1UL3PgKQQ3QbIi7bCeu48GjUp/OXOZ636Z/g99dtMXyEgegQH4bllzyJi41pER8iR87uT3Kh9G9P5ffMdC9Kee4MbfPSpRR3G03Plqh3QLUxE0doUvvOll75AZuwYbvz+i9WoqLmGouQ0mFpb0GyxICYsDJnHy3B0QQYHjNhB7e1VnziYwnAOeqPGE2IPBOAmlGFtEIj3AYqSVxCcvdzF/5WlBzAg44fc/wkM6r+95WUMLNjM3/WDec9gd8mT3GAy6srOdWj5xgLdngpu9PYTlRyIgmXTeTtzWixGquUQsopQYkhH9sNx3CACodnShtJLX/J2+eKlHAiS7PHxvE0xgZ6frq0BY4yDojn4Fw4QGH4PvdGjLz4QgBoo58sgnKAXOYPdne070ar7Bad6ZNNlnhHqozUdAbJOCOdxof1qDZKKTuHj4tU4XV2DklMXsG/jHGw5fIZT3NlOnRDFXSTmZ3tQ/uISKAcGQbFyB67sWYdolTvdSxdmIGPUaO4GmbGjUTAtCfp/VqC48iyY1tCxyS6BUmDLoM0/IpoBZihfAgTOb+duE7UtpW/x9EdUp4B4t+I/HAxyDwKHYsWVwyfwQn1gh6E0B+10yalqaGIiEBMph0Z/gPu5IIC3iSEEFrkLZ4vFAsWf/uCy7oofL0PKsChknSjjbtA5JjgBIBak/vXwfT1mjYH+aZMEAFRUNc0mRTI2tPBJbjiJteo87hT/kRtPwVBevJW3qRYgd3jzZCU+mzQFtMOFhz5A1ZUGlD69iO922UeX+DOif8VLS1D64SUOTPG6VM4UU30LCh9PQtXNeuhOl7usOycuHsXJaWi+a+FpsTNIzizhGiSFi9AZ4rqLmA90ATNUzQDCxIVbx+iVST9BeWSsFFWAEkKSuPqfmHBlzeM8HuS8+06n9wo7oTNsEA3ADaiSbIDIZHv/NXHzDGgOpM84EkTNgHhx53+K+mlRwxG9b5cj8DmFCWugN5SIBqAOKiMDfi1h+ahSDMG81O6PDuTflBmKj3+Cc6ZGnh61CxK4K1AmcAr5OUX+pg0/548o7WnUES5LIrpTcVQyZ67nAokFxEGvvygaADNUbwLIkgJAd5+/KOdTpKcASDGBhHyegiOlx+LjlRipDkXO3Hgog4N4AKRIT7vrzP/7Zs/l+Z0kZ3w8qhod8xA4rtTnjy9DZ3ygH3YbA8xQ1QBwPYn4iMb6qYtxYuh4t9G061QIVZy/1tF3ztTAawK6UlAk4ZXjPV8uTkmDVpPIix+qBokBlPYyRrna1XLXwoshF2HYD70x50HL9giAGeHjANYtbbzh8P30jagNdo+dBEBJXrpLaUysIPoTIwgAhTwImhFqpP3tCDeaAhulSdpd2n2HoaWIlofxe2cf+b2H8jgXOuMO0QDUQrVOAOgbgGgxhagwY/YTHvVyZsVzY8nnnf5P91T8EP0zpsZi/6fVyJgWy098ZGTlisc4EFQBUgokZjhPhalRw3nAI8OJFW4ACJgCrfGsaADqoNrLgDWirQdwZMRD0CU6avuu4qzvie4U8JwVYeeS2NTUihabhZexuoTJKEpO5UYTGFQAUdAjV6C4QFdnGUzGu0R/oBY6Y5Q3G7pxAdX/6EucN2VP/fma+TgYneBRlYoiCoL6vac5A4gRVBJn/eoYrw4pGAovb+N1ABlHtT35PFV1hdNn8DYdjQkYnSaRF0NNbW0cFA/yBnTGpd5scAPgOgZG2BF4w5tid/2pj27A56GDPHYXLk/iRtLOUzVI/p+d5ijSiBWTotW8Tf5PhQ35eFchV6A+chFyAToMdfOBxAidcZs3O9wAMCM8C2CUAkVLc/9gxM2/fyDpOgEZTP5PQiBQ0HPeUxDUJKqBkYz7fGdxRn9KdeQKTr93PvdAf8BuT8amzf/yZoQHAFSE2iZvip763xs8FtnTvbKu+6nHMGCYuArQ82RCA4beisLSwrve7HADoBaqMwLg9vHQ20TUvzV+Fl4ZM8OXoZ7H9NQXYIa/Q2/06VO0CwAM6FcHlVWqBRmPZOPj8OHS1GUAksUdgLp9kSA8D63hRV8W4gLANShSAyBzPX/6Msu9MUMzXf50EaFJHwMZoOkJ+vPXzoXOeNKXBXRlQGCd4wgs6Ri3Kmk5TkWO9uW97mOIAQ/bAbp+N9kGndHo6xSegqDkf4G2jUsG/STLODsg7S8EQIAZEP4MrWGLmPd7LIS+AIIGQJEkZqLOYwseSudfYL8KCav/R+QYs6h51BiMMAxGsKwRKjsdyHyTTv/5+6bgGOX1s7iYyXrjWD8AvXHXenLNfgb0JJq9cS4/A3rjrvXkmv0M6Ek0e+Ncfgb0xl3ryTX7GdCTaPbGufo8A/4PpckqfWjPHTQAAAAASUVORK5CYII="
|
||||
mode="widthFix" class="w-[60rpx]"/>
|
||||
</view>
|
||||
<view class="flex-1 px-[20rpx]">
|
||||
<view>{{ t('cashOutToBank') }}</view>
|
||||
<view class="text-[#bbb] text-[26rpx] mt-[16rpx]">
|
||||
<view v-if="bankAccountInfo">
|
||||
{{ t('cashOutTo') }}{{ bankAccountInfo.bank_name }}{{ t('debitCard') }}{{ bankAccountInfo.account_no.substring(bankAccountInfo.account_no.length - 4) }} <text class="text-black" @click="redirect({ url: '/app/pages/member/account', param: { type: 'bank', mode: 'select' }, mode: 'redirectTo' })">{{ t('replace') }}</text>
|
||||
</view>
|
||||
<view v-else>
|
||||
{{ t('cashOutToBankTips') }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex items-center">
|
||||
<u-button :plain="true" type="primary" shape="circle" :custom-style="{height: '56rpx'}" v-if="!bankAccountInfo" @click="redirect({ url: '/app/pages/member/account', param: { type: 'bank', mode: 'select' }, mode: 'redirectTo' })">{{ t('toAdd') }}</u-button>
|
||||
<view v-else @click="applyData.transfer_type = 'bank'">
|
||||
<text class="iconfont iconduigou text-[40rpx] text-primary" v-if="applyData.transfer_type == 'bank'"></text>
|
||||
<text class="iconfont iconcheckbox_nol text-[40rpx] text-[#bbb]" v-else></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="px-[32rpx]">
|
||||
<u-button type="primary" shape="circle" :text="t('cashOut')" class="mt-[60rpx] mb-[40rpx]" :disabled="applyData.apply_money == '' || applyData.apply_money == 0" :loading="loading" @click="cashOut"></u-button>
|
||||
</view>
|
||||
|
||||
<view class="px-[32rpx]">
|
||||
<u-button type="primary" shape="circle" :text="t('cashOut')" class="mt-[60rpx] mb-[40rpx]"
|
||||
:disabled="applyData.apply_money == '' || applyData.apply_money == 0" :loading="loading"
|
||||
@click="cashOut"></u-button>
|
||||
</view>
|
||||
|
||||
<view class="mt-[40rpx] text-center text-sm" @click="redirect({ url: '/app/pages/member/cash_out'})">
|
||||
{{t('cashOutList')}}
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<u-loading-page :loading="pageLoading" bg-color="#e8e8e8" loading-text=""></u-loading-page>
|
||||
<view class="mt-[40rpx] text-center text-sm" @click="redirect({ url: '/app/pages/member/cash_out'})">
|
||||
{{t('cashOutList')}}
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<block v-if="config.is_open == 0 && !pageLoading">
|
||||
<u-empty :text="t('isOpenApply')" :icon="img('static/resource/images/empty.png')"/>
|
||||
</block>
|
||||
<u-loading-page :loading="pageLoading" bg-color="#e8e8e8" loading-text=""></u-loading-page>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, watch, computed } from 'vue'
|
||||
import { t } from '@/locale'
|
||||
import { moneyFormat, redirect, img } from '@/utils/common'
|
||||
import { moneyFormat, redirect, getToken ,img } from '@/utils/common'
|
||||
import useMemberStore from '@/stores/member'
|
||||
import { cashOutConfig, cashOutApply, getFirstCashoutAccountInfo, getCashoutAccountInfo } from '@/app/api/member'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
@ -112,7 +112,7 @@
|
||||
const pageLoading = ref(true)
|
||||
const loading = ref(false)
|
||||
const memberStore = useMemberStore()
|
||||
|
||||
|
||||
// 申请提现数据
|
||||
const applyData = reactive({
|
||||
apply_money: '',
|
||||
@ -131,10 +131,10 @@
|
||||
switch (nval) {
|
||||
case 'bank':
|
||||
applyData.account_id = bankAccountInfo.value ? bankAccountInfo.value.account_id : 0
|
||||
break;
|
||||
break;
|
||||
case 'alipay':
|
||||
applyData.account_id = alipayAccountInfo.value ? alipayAccountInfo.value.account_id : 0
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
applyData.account_id = 0
|
||||
}
|
||||
@ -154,6 +154,10 @@
|
||||
onLoad(async (data) => {
|
||||
query = data
|
||||
uni.getStorageSync('cashOutAccountType') && (applyData.account_type = uni.getStorageSync('cashOutAccountType'))
|
||||
|
||||
if(getToken()){
|
||||
memberStore.getMemberInfo()
|
||||
}
|
||||
|
||||
if (!['money', 'commission'].includes(applyData.account_type)) {
|
||||
uni.showToast({
|
||||
@ -171,7 +175,7 @@
|
||||
for (let key in res.data) {
|
||||
config[key] = res.data[key];
|
||||
}
|
||||
if (config.transfer_type.includes('wechat') && memberStore.info && (!memberStore.info.wx_openid && !memberStore.info.weapp_openid)) config.transfer_type.splice(0, 1)
|
||||
if (config.transfer_type.includes('wechatpay') && memberStore.info && (!memberStore.info.wx_openid && !memberStore.info.weapp_openid)) config.transfer_type.splice(0, 1)
|
||||
config.transfer_type.includes('bank') && getBankAccountInfo()
|
||||
config.transfer_type.includes('alipay') && getAlipayAccountInfo()
|
||||
applyData.transfer_type = config.transfer_type[0]
|
||||
@ -216,7 +220,7 @@
|
||||
/**
|
||||
* 获取支付宝提现账号信息
|
||||
*/
|
||||
const alipayAccountInfo = ref(null)
|
||||
const alipayAccountInfo:any = ref(null)
|
||||
const getAlipayAccountInfo = () => {
|
||||
const data = { account_type: 'alipay', account_id: 0 }
|
||||
let request = getFirstCashoutAccountInfo
|
||||
@ -227,7 +231,13 @@
|
||||
}
|
||||
|
||||
request(data).then(res => {
|
||||
if (res.data && res.data.account_id) alipayAccountInfo.value = res.data
|
||||
if (res.data && res.data.account_id) {
|
||||
alipayAccountInfo.value = res.data
|
||||
// 初始化赋值
|
||||
if(applyData.transfer_type == 'alipay' && !applyData.account_id){
|
||||
applyData.account_id = alipayAccountInfo.value.account_id;
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -244,7 +254,13 @@
|
||||
data.account_id = query.account_id
|
||||
}
|
||||
request(data).then(res => {
|
||||
if (res.data && res.data.account_id) bankAccountInfo.value = res.data
|
||||
if (res.data && res.data.account_id) {
|
||||
bankAccountInfo.value = res.data
|
||||
// 初始化赋值
|
||||
if(applyData.transfer_type == 'bank' && !applyData.account_id){
|
||||
applyData.account_id = alipayAccountInfo.value.account_id;
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -258,6 +274,7 @@
|
||||
|
||||
cashOutApply(applyData)
|
||||
.then(res => {
|
||||
loading.value = false
|
||||
redirect({ url: '/app/pages/member/cash_out' })
|
||||
})
|
||||
.catch(() => {
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
{{ item.status_name }}
|
||||
</view>
|
||||
</view>
|
||||
<mescroll-empty v-if="!cashOutList.length && loading" :option="{tip : (account_type == 'commission' ? t('commissemptyTip') : t('emptyTip') )}"></mescroll-empty>
|
||||
<mescroll-empty v-if="!cashOutList.length && loading" :option="{tip : t('emptyTip')}"></mescroll-empty>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@ -1,177 +1,69 @@
|
||||
<template>
|
||||
<view :style="themeColor()">
|
||||
<u-loading-page :loading="loading" loadingText="" bg-color="#f7f7f7"></u-loading-page>
|
||||
|
||||
<view v-show="!loading">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<top-tabbar v-if="!isShowTopTabbar" :title="data.title" />
|
||||
<!-- #endif -->
|
||||
<u-loading-page :loading="diy.getLoading()" loadingText="" bg-color="#f7f7f7" />
|
||||
|
||||
<view v-show="!diy.getLoading()">
|
||||
|
||||
<!-- 自定义模板渲染 -->
|
||||
<view class="diy-template-wrap bg-index" v-if="data.pageMode != 'fixed'" :style="pageStyle">
|
||||
<view class="diy-template-wrap bg-index" v-if="diy.data.pageMode != 'fixed'" :style="diy.pageStyle()">
|
||||
|
||||
<diy-group :data="data" :pullDownRefreshCount="pullDownRefreshCount"></diy-group>
|
||||
<diy-group ref="diyGroupRef" :data="diy.data" :pullDownRefreshCount="diy.pullDownRefreshCount" />
|
||||
|
||||
</view>
|
||||
|
||||
<!-- 固定模板渲染 -->
|
||||
<view class="fixed-template-wrap" v-if="data.pageMode == 'fixed'">
|
||||
<view class="fixed-template-wrap" v-if="diy.data.pageMode == 'fixed'">
|
||||
|
||||
<fixed-group :data="data" :pullDownRefreshCount="pullDownRefreshCount"></fixed-group>
|
||||
<fixed-group :data="diy.data" :pullDownRefreshCount="diy.pullDownRefreshCount" />
|
||||
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<!-- 小程序隐私协议 -->
|
||||
<wx-privacy-popup ref="wxPrivacyPopup"></wx-privacy-popup>
|
||||
<!-- #endif -->
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
import { onLoad, onShow, onPullDownRefresh, onPageScroll } from '@dcloudio/uni-app'
|
||||
import { getDiyInfo } from '@/app/api/diy'
|
||||
import useDiyStore from '@/app/stores/diy'
|
||||
import { img,redirect } from '@/utils/common';
|
||||
import {ref} from 'vue';
|
||||
import {useDiy} from '@/hooks/useDiy'
|
||||
import {redirect} from '@/utils/common';
|
||||
import diyGroup from '@/addon/components/diy/group/index.vue'
|
||||
import fixedGroup from '@/addon/components/fixed/group/index.vue'
|
||||
|
||||
const loading = ref(true);
|
||||
const diyStore = useDiyStore();
|
||||
const pullDownRefreshCount = ref(0)
|
||||
let isShowTopTabbar = ref(false);
|
||||
const diy = useDiy({
|
||||
name: 'DIY_MEMBER_INDEX'
|
||||
})
|
||||
|
||||
const id = ref(0)
|
||||
const name = ref('DIY_MEMBER_INDEX')
|
||||
const template = ref('')
|
||||
const diyGroupRef = ref(null)
|
||||
|
||||
const diyData = reactive({
|
||||
pageMode: 'diy',
|
||||
title: '',
|
||||
global: {},
|
||||
value: []
|
||||
})
|
||||
// 监听页面加载
|
||||
diy.onLoad();
|
||||
|
||||
const data = computed(() => {
|
||||
if (diyStore.mode == 'decorate') {
|
||||
return diyStore;
|
||||
} else {
|
||||
return diyData;
|
||||
}
|
||||
})
|
||||
|
||||
onLoad(option => {
|
||||
// #ifdef H5
|
||||
// 装修模式
|
||||
diyStore.mode = option.mode || '';
|
||||
if (diyStore.mode == 'decorate') {
|
||||
loading.value = false;
|
||||
}
|
||||
// #endif
|
||||
id.value = option.id || '';
|
||||
template.value = option.template || '';
|
||||
});
|
||||
|
||||
onShow(() => {
|
||||
// 装修模式
|
||||
if (diyStore.mode == 'decorate') {
|
||||
diyStore.init();
|
||||
} else {
|
||||
getDiyInfo({
|
||||
id: id.value,
|
||||
name: name.value,
|
||||
template: template.value
|
||||
}).then((res : any) => {
|
||||
let data = res.data;
|
||||
if (data.value) {
|
||||
diyData.pageMode = data.mode;
|
||||
diyData.title = data.title;
|
||||
|
||||
let sources = JSON.parse(data.value);
|
||||
diyData.global = sources.global;
|
||||
diyData.value = sources.value;
|
||||
diyData.value.forEach((item, index) => {
|
||||
item.pageStyle = '';
|
||||
if(item.pageStartBgColor) {
|
||||
if (item.pageStartBgColor && item.pageEndBgColor) item.pageStyle += `background:linear-gradient(${item.pageGradientAngle},${item.pageStartBgColor},${item.pageEndBgColor});`;
|
||||
else item.pageStyle += 'background-color:' + item.pageStartBgColor + ';';
|
||||
}
|
||||
|
||||
if (item.margin) {
|
||||
item.pageStyle += 'padding-top:' + item.margin.top * 2 + 'rpx' + ';';
|
||||
item.pageStyle += 'padding-bottom:' + item.margin.bottom * 2 + 'rpx' + ';';
|
||||
item.pageStyle += 'padding-right:' + item.margin.both * 2 + 'rpx' + ';';
|
||||
item.pageStyle += 'padding-left:' + item.margin.both * 2 + 'rpx' + ';';
|
||||
}
|
||||
});
|
||||
// 控制自定义头部是否出现 | 微信小程序
|
||||
isShowTopTabbar.value = diyData.value.some((item)=>{
|
||||
return item && item.position && item.position == 'top_fixed'
|
||||
})
|
||||
uni.setNavigationBarTitle({
|
||||
title: diyData.title
|
||||
})
|
||||
}else if (data.page) {
|
||||
// 跳转到设置的个人中心
|
||||
redirect({ url: data.page })
|
||||
}
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const pageStyle = computed(()=>{
|
||||
var style = '';
|
||||
if (data.value.global.pageStartBgColor && data.value.global.pageEndBgColor) style += `background:linear-gradient(${data.value.global.pageGradientAngle},${data.value.global.pageStartBgColor},${data.value.global.pageEndBgColor});`;
|
||||
else style += 'background-color:' + data.value.global.pageStartBgColor + ';';
|
||||
|
||||
style += 'min-height:calc(100vh - 50px);';
|
||||
if(data.value.global.bgUrl) {
|
||||
style += `background-image:url('${ img(data.value.global.bgUrl) }');`;
|
||||
// 监听页面显示
|
||||
diy.onShow((data: any) => {
|
||||
if (data.value) {
|
||||
// uni.setNavigationBarTitle({
|
||||
// title: diyData.title
|
||||
// })
|
||||
} else if (data.page) {
|
||||
// 跳转到设置的启动页
|
||||
redirect({url: data.page, mode: 'reLaunch'})
|
||||
}
|
||||
|
||||
if (data.value.global.bgHeightScale) {
|
||||
style += `background-size: 100% ${data.value.global.bgHeightScale}%;`;
|
||||
}
|
||||
|
||||
return style;
|
||||
diyGroupRef.value?.refresh();
|
||||
});
|
||||
|
||||
// 监听下拉刷新事件
|
||||
onPullDownRefresh(() => {
|
||||
pullDownRefreshCount.value++;
|
||||
uni.stopPullDownRefresh();
|
||||
})
|
||||
diy.onPullDownRefresh()
|
||||
|
||||
onPageScroll((e)=>{
|
||||
if(e.scrollTop > 0)
|
||||
diyStore.scrollTop = e.scrollTop;
|
||||
})
|
||||
// 监听滚动事件
|
||||
diy.onPageScroll()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/styles/diy.scss';
|
||||
</style>
|
||||
<style lang="scss">
|
||||
.diy-template-wrap {
|
||||
::v-deep .diy-group {
|
||||
> .draggable-element.top-fixed-diy {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
/* #ifdef MP */
|
||||
.child-diy-template-wrap {
|
||||
::v-deep .diy-group {
|
||||
> .draggable-element.top-fixed-diy {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* #endif */
|
||||
/* #ifdef H5 */
|
||||
:deep(.child-diy-template-wrap) {
|
||||
.diy-group .draggable-element.top-fixed-diy{
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
/* #endif */
|
||||
}
|
||||
</style>
|
||||
322
uni-app/src/app/pages/member/level.vue
Normal file
322
uni-app/src/app/pages/member/level.vue
Normal file
@ -0,0 +1,322 @@
|
||||
<template>
|
||||
<view :style="themeColor()">
|
||||
<u-loading-page :loading="loading && memberInfo" loadingText="" bg-color="#f7f7f7"></u-loading-page>
|
||||
<view v-if="!loading && memberInfo && list && list.length" class="bg-[#2f3a58] min-h-[100vh] overflow-hidden flex flex-col">
|
||||
<!-- #ifdef MP -->
|
||||
<top-tabbar :data="topTabbarData" titleColor="#fff"/>
|
||||
<!-- #endif -->
|
||||
<view class="pb-[36rpx]">
|
||||
<view class="pt-[40rpx] pb-[70rpx]">
|
||||
<!-- 轮播图 -->
|
||||
<view class="relative mx-[20rpx]">
|
||||
<swiper class="swiper ns-indicator-dots" :style="{ height: '340rpx' }" @change="swiperChange"
|
||||
indicator-color="rgb(139,139,139)" indicator-active-color="#fff"
|
||||
:current = "swiperIndex" :indicator-dots="isIndicatorDots"
|
||||
previous-margin="40rpx" next-margin="40rpx">
|
||||
<swiper-item class="swiper-item" v-for="(item,index) in list" :key="item.id">
|
||||
<view class="h-[340rpx] relative">
|
||||
<view v-if="memberInfo.member_level == item.level_id && swiperIndex == index" class="text-[24rpx] absolute top-[42rpx] left-0 z-10 h-[38rpx] !bg-contain w-[144rpx] text-[#fff] flex items-center justify-center" :style="{ background: 'url(' + img('addon/shop/level/carousel_bg_02.png') + ') no-repeat'}">
|
||||
当前等级
|
||||
</view>
|
||||
<view class="absolute left-0 right-0 z-10 px-[40rpx]" :class="{'pt-[108rpx]': memberInfo.member_level == item.level_id, 'pt-[90rpx]': memberInfo.member_level != item.level_id}">
|
||||
<view class="flex items-end">
|
||||
<view class="flex items-center mb-[-4rpx] mr-[6rpx]">
|
||||
<text class="text-[60rpx] skewed-text-10">V</text>
|
||||
<text class="text-[60rpx] skewed-text-10">{{index+1}}</text>
|
||||
</view>
|
||||
<text class="text-[32rpx] text-[#3C2913]">{{item.level_name}}</text>
|
||||
</view>
|
||||
<view class="text-[#977B48] text-[26rpx] mt-[20rpx]">成长值已达到 {{memberInfo.growth}}</view>
|
||||
<view class="flex justify-between items-center mt-[50rpx]">
|
||||
<view class="flex flex-col flex-1">
|
||||
<view>
|
||||
<progress :percent="progress(index)" :border-radius="100" activeColor="#DB9400" backgroundColor="#D9D9D9" stroke-width="6" />
|
||||
</view>
|
||||
<view class="text-[#977B48] mt-[10rpx] text-[24rpx]" v-if="upgradeGrowth(index) > 0">还需要{{upgradeGrowth(index)}}点成长值升级</view>
|
||||
<view class="text-[#977B48] mt-[10rpx] text-[24rpx]" v-if="upgradeGrowth(list.length-1) <= 0 && list.length-1 == index">恭喜您升级到最高等级</view>
|
||||
</view>
|
||||
<text v-if="upgradeGrowth(index) > 0" class="flex justify-center items-center ml-[90rpx] text-[30rpx] rounded-[50rpx] w-[180rpx] h-[60rpx] text-[#fff] bg-[#3A3842]">加速升级</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="relatvie h-full w-full">
|
||||
<image class="h-full w-full" :src="img(item.level_bg)" mode="aspectFit" :class="{'swiper-animation': swiperIndex != index}" :show-menu-by-longpress="true"/>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view v-if="list.length > 1" :class="['swiper-dot-box straightLine']">
|
||||
<view v-for="(numItem, numIndex) in list" :key="numIndex" :class="['swiper-dot', { active: numIndex == swiperIndex }]"></view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex px-[58rpx] items-center flex-col" v-if="currLevelInfo.benefits_arr && currLevelInfo.benefits_arr.length">
|
||||
<view class="flex items-center justify-center">
|
||||
<image class="h-[24rpx]" :src="img('addon/shop/level/arrows_left_01.png')" mode="heightFix" />
|
||||
<text class="mx-[30rpx] text-[#FACC80] text-[32rpx] font-bold">会员权益</text>
|
||||
<image class="h-[24rpx]" :src="img('addon/shop/level/arrows_right_01.png')" mode="heightFix" />
|
||||
</view>
|
||||
<view class="flex flex-wrap w-full mt-[46rpx]">
|
||||
<view class="flex flex-col w-[25%] items-center" v-for="(item,index) in currLevelInfo.benefits_arr" :key="index">
|
||||
<image class="h-[100rpx] w-[100rpx]" :src="img(item.icon)" mode="heightFix" />
|
||||
<text class="bg-[#2f3a58] -mt-[18rpx] text-[#FACC80] text-[20rpx] flex items-center h-[36rpx] px-[16rpx] rounded-full border-[2rpx] border-solid border-[#FACC80]">{{item.desc}}</text>
|
||||
<text class="text-[rgba(255,255,255,0.9)] mt-[10rpx] text-[24rpx]">{{item.title}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="bg-[#fff] flex-1 rounded-t-[16rpx] px-[30rpx] pt-[30rpx] tab-bar">
|
||||
<!-- 升级礼包 -->
|
||||
<view v-if="currLevelInfo.gifts_arr && currLevelInfo.gifts_arr.length">
|
||||
<view class="pt-[10rpx] pb-[40rpx] flex items-center justify-center">
|
||||
<image class="h-[24rpx]" :src="img('addon/shop/level/arrows_left_02.png')" mode="heightFix" />
|
||||
<text class="mx-[30rpx] text-[32rpx] text-[#3A3945] font-bold">升级礼包</text>
|
||||
<image class="h-[24rpx]" :src="img('addon/shop/level/arrows_right_02.png')" mode="heightFix" />
|
||||
</view>
|
||||
<view class="flex flex-wrap">
|
||||
<view v-for="(item,index) in currLevelInfo.gifts_arr" :key="idnex" class="relative box-border mb-[40rpx] leading-1 bg-[#FFEAD3] w-[216rpx] h-[220rpx] px-[30rpx] pb-[20rpx] pt-[46rpx] relative rounded-[16rpx] !bg-contain"
|
||||
:class="{'mr-[20rpx]': (index+1)%3!=0}"
|
||||
:style="{ background: 'url(' + img(item.background) + ') no-repeat'}"
|
||||
>
|
||||
<text class="absolute left-0 right-0 text-[rgba(58,57,69,0.8)] bottom-[34rpx] text-center text-[24rpx] font-bold z-10">{{item.text}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 升级技巧 -->
|
||||
<view v-if="upgradeSkills && upgradeSkills.length">
|
||||
<view class="pt-[10rpx] pb-[40rpx] flex items-center justify-center">
|
||||
<image class="h-[24rpx]" :src="img('addon/shop/level/arrows_left_02.png')" mode="heightFix" />
|
||||
<text class="mx-[30rpx] text-[32rpx] text-[#3A3945] font-bold">升级技巧</text>
|
||||
<image class="h-[24rpx]" :src="img('addon/shop/level/arrows_right_02.png')" mode="heightFix" />
|
||||
</view>
|
||||
<view>
|
||||
<view class="flex items-center mb-[30rpx]" v-for="(item,index) in upgradeSkills" :key="index">
|
||||
<image class="h-[100rpx] w-[100rpx] mr-[20rpx]" :src="img(item.icon)" mode="heightFix" />
|
||||
<view class="flex flex-col">
|
||||
<view class="text-[#3A3945] text-[28rpx] font-bold mb-[12rpx]">{{item.title}}</view>
|
||||
<view class="text-[24rpx] text-[#3A3945]">{{item.desc}}</view>
|
||||
</view>
|
||||
<text class="skill-btn" @click="redirect({ url: item.button.wap_redirect, param: {} , mode: 'redirectTo'})">{{item.button.text}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<u-empty v-if="!loading && (!list || !list.length)" :icon="img('static/resource/images/empty.png')" text="暂无会员等级" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app'
|
||||
import { getMemberLevel, getTaskGrowth } from '@/app/api/member';
|
||||
import { img,redirect, deepClone, getToken } from '@/utils/common';
|
||||
import useMemberStore from '@/stores/member'
|
||||
|
||||
const memberStore = useMemberStore()
|
||||
|
||||
let loading = ref(false)
|
||||
let list = ref([]) // 会员等级
|
||||
let upgradeSkills = ref([]) // 升级技巧
|
||||
const swiperIndex = ref(0); //当前滑块的索引
|
||||
|
||||
let isIndicatorDots = ref(true) // 是否展示显示面板指示点
|
||||
// #ifdef MP
|
||||
isIndicatorDots.value = false
|
||||
// #endif
|
||||
|
||||
// 自定义头部
|
||||
let topTabbarData = ref({
|
||||
title: '会员等级',
|
||||
topStatusBar: {
|
||||
style: 'style-1',
|
||||
bgColor: 'transparent',
|
||||
textColor: '#fff'
|
||||
}
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
// 判断是否已登录
|
||||
if (getToken()) {
|
||||
getTaskGrowthFn();
|
||||
getMemberLevelFn();
|
||||
}
|
||||
})
|
||||
|
||||
// 会员信息
|
||||
const memberInfo = computed(() => {
|
||||
return memberStore.info
|
||||
})
|
||||
|
||||
// 进度条值
|
||||
let progress = (index:any) => {
|
||||
let indent = index;
|
||||
let num = 100
|
||||
if(list.value[indent] && list.value[indent].growth) {
|
||||
num = memberInfo.value.growth / list.value[indent].growth * 100
|
||||
}
|
||||
return num
|
||||
}
|
||||
|
||||
// 所需的成长值
|
||||
let upgradeGrowth = (index:any) => {
|
||||
let indent = index;
|
||||
let num = 0;
|
||||
if(list.value[indent] && list.value[indent].growth) {
|
||||
num = list.value[indent].growth - memberInfo.value.growth;
|
||||
}
|
||||
return num
|
||||
}
|
||||
|
||||
const getMemberLevelFn = ()=>{
|
||||
loading.value = true;
|
||||
getMemberLevel().then((res) => {
|
||||
list.value = res.data || [];
|
||||
|
||||
// 初始化会员等级数据
|
||||
let bool = true;
|
||||
if(memberInfo.value && list.value && list.value.length){
|
||||
list.value.forEach((item,index)=>{
|
||||
if(item.level_id == memberInfo.value.member_level){
|
||||
bool = false;
|
||||
swiperIndex.value = index;
|
||||
infoStructureFn(index);
|
||||
}
|
||||
})
|
||||
}
|
||||
if(bool) infoStructureFn(0);
|
||||
|
||||
loading.value = false;
|
||||
}).catch(()=>{
|
||||
loading.value = false;
|
||||
})
|
||||
}
|
||||
|
||||
const getTaskGrowthFn = ()=>{
|
||||
getTaskGrowth().then((res) => {
|
||||
upgradeSkills.value = res.data
|
||||
})
|
||||
}
|
||||
|
||||
const swiperChange = e => {
|
||||
swiperIndex.value = e.detail.current;
|
||||
infoStructureFn(e.detail.current);
|
||||
};
|
||||
|
||||
// 当前的会员等级信息
|
||||
let currLevelInfo = ref({});
|
||||
let infoStructureFn = (index:number)=>{
|
||||
let data = {}
|
||||
data = deepClone(list.value[index]);
|
||||
// 会员权益
|
||||
if(data && data.level_benefits){
|
||||
data.benefits_arr = [];
|
||||
Object.values(data.level_benefits).forEach((item,index,Array)=>{
|
||||
if(item.content){
|
||||
data.benefits_arr.push(item.content)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 升级礼包
|
||||
if(data && data.level_gifts){
|
||||
data.gifts_arr = [];
|
||||
for(let key in data.level_gifts){
|
||||
if(data.level_gifts[key].content){
|
||||
// 增加类型
|
||||
data.level_gifts[key].content.forEach((item,index,Array)=>{
|
||||
Array[index].type = key
|
||||
})
|
||||
data.gifts_arr = data.gifts_arr.concat(data.level_gifts[key].content);
|
||||
}
|
||||
}
|
||||
}
|
||||
currLevelInfo.value = data;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.skill-btn{
|
||||
padding: 0 20rpx;
|
||||
height: 54rpx;
|
||||
line-height: 56rpx;
|
||||
color: rgba(255,255,255,0.9);
|
||||
background: linear-gradient( 180deg, #F1C28C 0%, #DB9E32 85%);
|
||||
border-radius: 50rpx;
|
||||
margin-left: auto;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.swiper-animation{
|
||||
transform: scale(0.94, 0.94);
|
||||
transition-duration: 0.3s;
|
||||
transition-timing-function: ease;
|
||||
}
|
||||
|
||||
// 轮播指示器
|
||||
/* #ifdef H5 */
|
||||
.swiper :deep(.uni-swiper-wrapper){
|
||||
overflow: initial;
|
||||
}
|
||||
/* #endif */
|
||||
.swiper :deep(.uni-swiper-dots-horizontal) {
|
||||
bottom: -30rpx;
|
||||
}
|
||||
.swiper.ns-indicator-dots :deep(.uni-swiper-dot) {
|
||||
width: 18rpx;
|
||||
height: 6rpx;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
.swiper.ns-indicator-dots :deep(.uni-swiper-dot-active) {
|
||||
width: 36rpx;
|
||||
}
|
||||
.swiper-dot-box {
|
||||
position: absolute;
|
||||
bottom: -50rpx;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 80rpx 8rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.swiper-dot {
|
||||
background-color: #b2b2b2;
|
||||
width: 15rpx;
|
||||
border-radius: 50%;
|
||||
height: 15rpx;
|
||||
margin: 8rpx;
|
||||
}
|
||||
|
||||
&.straightLine {
|
||||
.swiper-dot {
|
||||
width: 18rpx;
|
||||
height: 6rpx;
|
||||
border-radius: 4rpx;
|
||||
|
||||
&.active {
|
||||
width: 36rpx;
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
:deep(.uni-progress) .uni-progress-bar, :deep(.uni-progress) .uni-progress-inner-bar{
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
.tab-bar {
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
.skewed-text-5 {
|
||||
transform: skew(-5deg);
|
||||
font-weight: 900;
|
||||
}
|
||||
.skewed-text-10 {
|
||||
transform: skew(-10deg);
|
||||
font-weight: 900;
|
||||
}
|
||||
</style>
|
||||
@ -36,7 +36,7 @@
|
||||
</u-form-item>
|
||||
</view>
|
||||
<view class="mt-[40rpx]">
|
||||
<u-button type="primary" shape="circle" :text="t('save')" @click="save" :loading="operateLoading"></u-button>
|
||||
<u-button type="primary" shape="circle" :text="t('save')" @click="save" :disabled="btnDisabled" :loading="operateLoading"></u-button>
|
||||
</view>
|
||||
</u-form>
|
||||
</view>
|
||||
@ -60,6 +60,7 @@
|
||||
|
||||
const type = ref('')
|
||||
const source = ref('')
|
||||
const btnDisabled = ref(false)
|
||||
|
||||
const formData = ref({
|
||||
id: 0,
|
||||
@ -176,7 +177,7 @@
|
||||
const operateLoading = ref(false)
|
||||
const save = ()=> {
|
||||
if (uni.$u.test.isEmpty(formData.value.area)) {
|
||||
uni.showToast({ title: t('selectAddressPlaceholder'), icon: 'none' })
|
||||
uni.showToast({title: t('selectAddressPlaceholder'), icon: 'none'})
|
||||
return
|
||||
}
|
||||
|
||||
@ -186,16 +187,24 @@
|
||||
if (operateLoading.value) return
|
||||
operateLoading.value = true
|
||||
|
||||
btnDisabled.value = true
|
||||
|
||||
formData.value.full_address = `${formData.value.area}${formData.value.address_name}${formData.value.address}`
|
||||
|
||||
save(formData.value).then((res) => {
|
||||
operateLoading.value = false
|
||||
uni.removeStorageSync('addressInfo');
|
||||
setTimeout(()=> {
|
||||
redirect({ url: '/app/pages/member/address', param: { type: type.value } })
|
||||
setTimeout(() => {
|
||||
btnDisabled.value = false
|
||||
redirect({
|
||||
url: '/app/pages/member/address',
|
||||
mode: 'redirectTo',
|
||||
param: {type: type.value, source: source.value}
|
||||
})
|
||||
}, 1000)
|
||||
}).catch(() => {
|
||||
operateLoading.value = false
|
||||
btnDisabled.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
@ -212,7 +221,10 @@
|
||||
fail: (res)=>{
|
||||
// 在隐私协议中没有声明chooseLocation:fail api作用域
|
||||
if(res.errMsg && res.errno) {
|
||||
if(res.errno == 112){
|
||||
if(res.errno == 104){
|
||||
let msg = '用户未授权隐私权限,选择位置失败';
|
||||
uni.showToast({title: msg, icon: 'none'})
|
||||
}else if(res.errno == 112){
|
||||
let msg = '隐私协议中未声明,打开地图选择位置失败';
|
||||
uni.showToast({title: msg, icon: 'none'})
|
||||
}else {
|
||||
|
||||
@ -21,8 +21,8 @@
|
||||
<u-cell :title="t('sex')" :is-link="true" :value="info.sex_name || t('unknown')" @click="sexSheetShow = true"></u-cell>
|
||||
<u-cell :title="t('mobile')">
|
||||
<template #value>
|
||||
<view v-if="info.mobile">{{ mobileConceal(info.mobile) }}</view>
|
||||
<view @click="redirect({ url: '/app/pages/auth/bind' })">
|
||||
<view v-if="info.mobile" class="mr-[10rpx]">{{ mobileConceal(info.mobile) }}</view>
|
||||
<view v-else @click="redirect({ url: '/app/pages/auth/bind' })">
|
||||
<u-button type="primary" :plain="true" :text="t('bindMobile')" shape="circle" size="mini"></u-button>
|
||||
</view>
|
||||
</template>
|
||||
@ -48,9 +48,10 @@
|
||||
:safeAreaInsetBottom="true"
|
||||
@close="sexSheetShow = false" @select="updateSex"></u-action-sheet>
|
||||
|
||||
<u-datetime-picker :show="birthdayPicker" mode="date" :confirm-text="t('confirm')"
|
||||
<u-datetime-picker v-model="info.birthday" :show="birthdayPicker" mode="date" :confirm-text="t('confirm')"
|
||||
:maxDate="new Date().valueOf()" :minDate="0"
|
||||
:cancel-text="t('cancel')" @cancel="birthdayPicker = false" @confirm="updateBirthday"></u-datetime-picker>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@ -150,7 +151,7 @@
|
||||
field: 'birthday',
|
||||
value: uni.$u.date(e.value, 'yyyy-mm-dd')
|
||||
}).then(() => {
|
||||
memberStore.info.birthday = uni.$u.date(e.value||e.value+1, 'yyyy-mm-dd')
|
||||
memberStore.info.birthday = uni.$u.date(e.value || e.value + 1, 'yyyy-mm-dd')
|
||||
birthdayPicker.value = false
|
||||
})
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<view v-for="(item,index) in pointList" :key="item.id" :class="['bg-white relative p-[10px]',{'border-solid border-t-0 border-l-0 border-r-0 border-b-[1px] border-gray-200': pointList.length-1 != index}] ">
|
||||
<view class="text-[14px]">{{item.from_type_name}}</view>
|
||||
<view class="text-[12px] text-gray-400 mt-[10px]">{{item.create_time}}</view>
|
||||
<view class="text-[14px] absolute top-[50%] transform -translate-y-[50%] right-[10px]">{{item.account_data}}</view>
|
||||
<view class="text-[14px] absolute top-[50%] transform -translate-y-[50%] right-[10px]" :class="{ 'text-primary' : item.account_data > 0 }">{{item.account_data > 0 ? '+' + item.account_data : item.account_data}}</view>
|
||||
</view>
|
||||
<mescroll-empty v-if="!pointList.length && loading"></mescroll-empty>
|
||||
</mescroll-body>
|
||||
@ -21,30 +21,32 @@ import MescrollBody from '@/components/mescroll/mescroll-body/mescroll-body.vue'
|
||||
import MescrollEmpty from '@/components/mescroll/mescroll-empty/mescroll-empty.vue';
|
||||
import useMescroll from '@/components/mescroll/hooks/useMescroll.js';
|
||||
import { onPageScroll, onReachBottom } from '@dcloudio/uni-app';
|
||||
|
||||
const { mescrollInit, downCallback, getMescroll } = useMescroll(onPageScroll, onReachBottom);
|
||||
|
||||
let pointList = ref<Array<any>>([]);
|
||||
let mescrollRef = ref(null);
|
||||
let loading = ref<boolean>(false);
|
||||
|
||||
const getPointListFn = (mescroll)=>{
|
||||
let data = ref({});
|
||||
loading.value = false;
|
||||
data.value.page = mescroll.num;
|
||||
data.value.page_size = mescroll.size;
|
||||
getPointList(data.value).then((res) => {
|
||||
let newArr = res.data.data;
|
||||
mescroll.endSuccess(newArr.length);
|
||||
//设置列表数据
|
||||
if (mescroll.num == 1){
|
||||
pointList.value = []; //如果是第一页需手动制空列表
|
||||
}
|
||||
pointList.value = pointList.value.concat(newArr);
|
||||
loading.value = true;
|
||||
}).catch(()=>{
|
||||
loading.value = true;
|
||||
mescroll.endErr(); // 请求失败, 结束加载
|
||||
})
|
||||
const getPointListFn = (mescroll)=> {
|
||||
let data = {
|
||||
page: mescroll.num,
|
||||
page_size: mescroll.size
|
||||
};
|
||||
loading.value = false;
|
||||
getPointList(data).then((res) => {
|
||||
let newArr = res.data.data;
|
||||
mescroll.endSuccess(newArr.length);
|
||||
//设置列表数据
|
||||
if (mescroll.num == 1) {
|
||||
pointList.value = []; //如果是第一页需手动制空列表
|
||||
}
|
||||
pointList.value = pointList.value.concat(newArr);
|
||||
loading.value = true;
|
||||
}).catch(() => {
|
||||
loading.value = true;
|
||||
mescroll.endErr(); // 请求失败, 结束加载
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
502
uni-app/src/app/pages/member/sign_in.vue
Normal file
502
uni-app/src/app/pages/member/sign_in.vue
Normal file
@ -0,0 +1,502 @@
|
||||
<template>
|
||||
<view :style="themeColor()">
|
||||
<view class="bg-[#F6F6F6] min-h-screen overflow-hidden" v-if="Object.values(info).length">
|
||||
<view v-if="info.is_use">
|
||||
<view class="sigin-header">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view class="absolute right-0 py-[4rpx] px-[14rpx] bg-color rounded-l-[30rpx] text-[#fff] text-[24rpx] leading-[28rpx] z-10" :style="{top: topStyle}" @click="signPopup = true">
|
||||
<text class="iconfont iconqiandao text-[24rpx] text-[#fff] mr-[4rpx]"></text>
|
||||
签到规则</view>
|
||||
<view :style="{height: headStyle, backgroundImage: 'url(' + img('static/resource/images/app/sigin_uniapp.png') + ')',backgroundSize: '100% 100%', backgroundRepeat: 'no-repeat'}">
|
||||
<top-tabbar :data="topTabbarData" titleColor="#fff" class="top-header" />
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 -->
|
||||
<view class="absolute top-[38rpx] right-0 py-[4rpx] px-[14rpx] bg-color rounded-l-[30rpx] text-[#fff] text-[24rpx] leading-[28rpx] z-10" @click="signPopup = true">
|
||||
<text class="iconfont iconqiandao text-[24rpx] text-[#fff] mr-[4rpx]"></text>
|
||||
签到规则</view>
|
||||
<view class="h-[382rpx]" :style="{ backgroundImage: 'url(' + img('static/resource/images/app/sigin_h5.png') + ')',backgroundSize: '100%', backgroundRepeat: 'no-repeat'}">
|
||||
<top-tabbar :data="topTabbarData" class="top-header" />
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
<view>
|
||||
<view class="mx-[30rpx] bg-[#fff] rounded-[16rpx] -mt-[85rpx]">
|
||||
<view class="px-[30rpx]">
|
||||
<view class="pt-[32rpx] mb-[40rpx] flex justify-between items-center" v-if="flag" >
|
||||
<view class="flex items-center">
|
||||
<text class="iconfont iconshangyibu text-[#999] text-[24rpx]" @click="changeMonth('prev')"></text>
|
||||
<view class="mx-[30rpx] font-bold text-[32rpx] text-[#333] leading-[38rpx]">{{ state.curYear }}年{{ state.curMonth+1 }}月</view>
|
||||
<text class="iconfont iconxiayibu1 text-[#999] text-[24rpx]" @click="changeMonth('next')"></text>
|
||||
</view>
|
||||
<view class="flex items-center">
|
||||
<view class="text-[24rpx] text-[#333] leading-[28rpx]" @click="handleChange">
|
||||
<text class="iconfont iconxiangshang text-[#666] !text-[16rpx] ml-[10rpx]"></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pt-[32rpx] mb-[40rpx] flex justify-between items-center" v-else>
|
||||
<view class="flex items-center">
|
||||
<view class="font-bold text-[32rpx] text-[#333] leading-[38rpx]">已连续签到<text class="text-[#EF000C] mx-[4rpx]">{{ info.days }}</text>天</view>
|
||||
</view>
|
||||
<view class="text-[24rpx] text-[#333] leading-[28rpx]" v-if="!flag" @click="flag = !flag">
|
||||
<text class="iconfont iconxiangxia text-[#666] !text-[16rpx] ml-[10rpx]"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="relative z-9 pb-[30rpx] bg-[#fff] rounded-[18rpx]">
|
||||
<view>
|
||||
<view class="flex items-center justify-between text-[#666] text-[26rpx] mb-[14rpx]">
|
||||
<text class="w-[14.2%] leading-[30rpx] text-center">周一</text>
|
||||
<text class="w-[14.2%] leading-[30rpx] text-center">周二</text>
|
||||
<text class="w-[14.2%] leading-[30rpx] text-center">周三</text>
|
||||
<text class="w-[14.2%] leading-[30rpx] text-center">周四</text>
|
||||
<text class="w-[14.2%] leading-[30rpx] text-center">周五</text>
|
||||
<text class="w-[14.2%] leading-[30rpx] text-center">周六</text>
|
||||
<text class="w-[14.2%] leading-[30rpx] text-center">周日</text>
|
||||
</view>
|
||||
<view class="flex flex-wrap items-center justify-start" v-if="!flag">
|
||||
<block v-for="(item,index) in state.weekCount" :key="index">
|
||||
<view class="w-[14.2%] flex flex-col justify-center items-center">
|
||||
<view v-if="filteredDate(item)" class="w-[74rpx] h-[92rpx] bg-[#F2F2F2] text-[#666] border-box py-[10rpx] rounded-[8rpx] flex flex-col items-center" :class="{'sigin-bg !text-[#fff]': isVerDate(item),'bg-[#FDFDFD] border-[1rpx] border-[#E0E0E0] border-solid !text-[#999]': !isVerDate(item) && item < state.curDate && (state.curMonth + 1) == (new Date().getMonth() + 1) ,'mb-[10rpx]':isCurrentDate(item),'mb-[20rpx]':!isCurrentDate(item) }" @click="getDayPackFn(item)">
|
||||
<text class="text-[24rpx] leading-[34rpx] mb-[6rpx]">{{ filteredDate(item) }}</text>
|
||||
<view v-if="filteredDate(item)">
|
||||
<image v-if="isPackDate(item)" :src="img('static/resource/images/app/package.png')" class="w-[40rpx] h-[40rpx]"></image>
|
||||
<image v-else-if="isVerDate(item)" :src="img('static/resource/images/app/hassigin.png')" class="w-[34rpx] h-[34rpx]"></image>
|
||||
<image v-else :src="img('static/resource/images/app/nosigin.png')" class="w-[34rpx] h-[34rpx]"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="w-[10rpx] h-[10rpx] rounded-[50%] bg-[#FF5527]" v-if="isCurrentDate(item)"></view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<view class="flex flex-wrap items-center justify-start" v-else>
|
||||
<block v-for="(item,index) in state.dataCount" >
|
||||
<view class="w-[14.2%] flex flex-col justify-center items-center mb-[10rpx]">
|
||||
<view v-if="filteredDate(item)" class="w-[74rpx] h-[92rpx] bg-[#F2F2F2] text-[#666] border-box py-[10rpx] rounded-[8rpx] flex flex-col items-center" :class="{'sigin-bg !text-[#fff]': isVerDate(item) && active ,'bg-[#FDFDFD] border-[1rpx] border-[#E0E0E0] border-solid !text-[#999]': !isVerDate(item) && item < state.curDate && (state.curMonth + 1) == (new Date().getMonth() + 1) && state.curYear == new Date().getFullYear() ,'mb-[10rpx]':isCurrentDate(item),'mb-[20rpx]':!isCurrentDate(item)}" @click="getDayPackFn(item)">
|
||||
<text class="text-[24rpx] leading-[34rpx] mb-[6rpx]">{{ filteredDate(item) }}</text>
|
||||
<view v-if="filteredDate(item)">
|
||||
<image v-if="isPackDate(item)" :src="img('static/resource/images/app/package.png')" class="w-[40rpx] h-[40rpx]"></image>
|
||||
<image v-else-if="isVerDate(item) && active " :src="img('static/resource/images/app/hassigin.png')" class="w-[34rpx] h-[34rpx]"></image>
|
||||
<image v-else :src="img('static/resource/images/app/nosigin.png')" class="w-[34rpx] h-[34rpx]"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="w-[10rpx] h-[10rpx] rounded-[50%] bg-[#FF5527]" v-if="isCurrentDate(item)"></view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<view class="mt-[50rpx] mx-[20rpx] flex justify-center" v-if="state.curMonth + 1 == (new Date().getMonth() + 1) && state.curYear == new Date().getFullYear() ">
|
||||
<u-button v-if="!info.is_sign" :customStyle="{width:'450rpx',height:'62rpx',border:'none', color:'#fff', fontSize:'28rpx',lineHeight:'66rpx',backgroundImage: `url(${img('static/resource/images/app/button_bg2.png')})`,backgroundSize: '100%', backgroundRepeat: 'no-repeat'}" shape="circle" @click="setSignFn">
|
||||
<text class="iconfont iconqiandao text-[26rpx] text-[#fff] mr-[14rpx]"></text>
|
||||
立即签到</u-button>
|
||||
<u-button v-else :customStyle="{width:'450rpx',height:'62rpx',border:'none',color:'#fff', fontSize:'28rpx',lineHeight:'66rpx',backgroundImage: `url(${img('static/resource/images/app/button_bg1.png')})`,backgroundSize: '100%', backgroundRepeat: 'no-repeat'}" shape="circle">
|
||||
<text class="iconfont iconqiandao text-[26rpx] text-[#fff] mr-[14rpx]"></text>
|
||||
已签到</u-button>
|
||||
</view>
|
||||
<!-- <view class="mx-[20rpx] flex items-baseline justify-between mt-[16rpx]">
|
||||
<text class="text-[26rpx] text-[#FF9000] leading-[30rpx]">查看签到记录</text>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mt-[20rpx] mb-[30rpx] mx-[30rpx] p-[30rpx] bg-[#fff] rounded-[16rpx]">
|
||||
<view class="mb-[30rpx] flex items-center">
|
||||
<view class="font-bold text-[32rpx] text-[#000] leading-[38rpx]">签到奖励</view>
|
||||
<!-- <view class="text-[#666] text-[26rpx] leading-[30rpx]">
|
||||
<text>签到记录</text>
|
||||
<image :src="img('static/resource/images/app/more.png')" class="w-[12rpx] h-[18rpx] ml-[8rpx]"></image>
|
||||
</view> -->
|
||||
</view>
|
||||
<view>
|
||||
<view v-for="(item,index) in info.continue_award" :key="index" class="flex items-center mt-[40rpx] border-box">
|
||||
<view class="w-[90rpx] h-[90rpx] rounded-[50%] bg-[#E7F6FF] flex items-center justify-center " v-if="(index + 1) % 4 == 1">
|
||||
<image :src="img('static/resource/images/app/icon_02.png')" class="w-[40rpx] h-[40rpx]"></image>
|
||||
</view>
|
||||
<view class="w-[90rpx] h-[90rpx] rounded-[50%] bg-[#ffefef] flex items-center justify-center" v-else-if="(index + 1) % 4 == 2">
|
||||
<image :src="img('static/resource/images/app/icon_03.png')" class="w-[40rpx] h-[40rpx]"></image>
|
||||
</view>
|
||||
<view class="w-[90rpx] h-[90rpx] rounded-[50%] bg-[#d3feeb] flex items-center justify-center" v-else-if="(index + 1) % 4 == 3">
|
||||
<image :src="img('static/resource/images/app/icon_04.png')" class="w-[40rpx] h-[40rpx]"></image>
|
||||
</view>
|
||||
<view class="w-[90rpx] h-[90rpx] rounded-[50%] bg-[#ffeddd] flex items-center justify-center" v-else-if="(index + 1) % 4 == 0">
|
||||
<image :src="img('static/resource/images/app/icon_05.png')" class="w-[40rpx] h-[40rpx]"></image>
|
||||
</view>
|
||||
<view class="flex-1 mx-[20rpx]">
|
||||
<view class="font-500 text-[28rpx] text-[#333] leading-[33rpx] mb-[10rpx]">连续签到{{item.continue_sign}}天</view>
|
||||
<view class="flex">
|
||||
<view v-if="item.balance.is_use" class="flex items-center leading-normal">
|
||||
<image :src="img('static/resource/images/app/packet01.png')" class="w-[26rpx] h-[30rpx]"></image>
|
||||
<text class="text-[24rpx] ml-[3rpx] text-[#FF9000] leading-[28rx] max-w-[86rpx] truncate">{{item.balance.content}}</text>
|
||||
</view>
|
||||
<view v-if="item.point.is_use" class="flex items-center leading-normal ml-[14rpx]">
|
||||
<image :src="img('static/resource/images/app/point.png')" class="w-[28rpx] h-[28rpx]"></image>
|
||||
<text class="text-[24rpx] ml-[3rpx] text-[#FF9000] leading-[28rx] max-w-[80rpx] truncate">{{item.point.content}}</text>
|
||||
</view>
|
||||
<view v-if="item.shop_coupon.is_use" class="flex items-center leading-normal ml-[14rpx]">
|
||||
<image :src="img('static/resource/images/app/coupon.png')" class="w-[28rpx] h-[28rpx]"></image>
|
||||
<text class="text-[24rpx] ml-[3rpx] text-[#FF9000] leading-[28rx] max-w-[80rpx] truncate">{{item.shop_coupon.content}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-shrink-0">
|
||||
<view v-if="Number(info.days) < Number(item.continue_sign) " class="px-[28rpx] py-[8rpx] bg-[#fff2f0] rounded-[40rpx] font-500 text-[24rpx] text-[#EF000C] leading-[34rpx]">待完成</view>
|
||||
<view v-else class="px-[28rpx] py-[8rpx] rounded-[40rpx] font-500 text-[24rpx] text-[#fff] leading-[34rpx]" style="background:linear-gradient( 90deg, #FB7939 0%, #FE120E 100%) ;">已完成</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="min-h-screen flex flex-col justify-center bg-[#fff]" v-else>
|
||||
<image class="rounded-[8rpx] overflow-hidden mx-auto w-[320rpx] h-[184rpx]" :src="img('static/resource/images/system/empty.png')" model="aspectFill" />
|
||||
<view class="text-[#999] text-[26rpx] font-400 mt-[26rpx] text-center leading-[30rpx]">暂无内容</view>
|
||||
</view>
|
||||
<!-- 签到规则-->
|
||||
<u-popup :show="signPopup" :round="16" mode="bottom" :closeable="true" @close="signPopup = false">
|
||||
<view class="pt-[30rpx] px-[32rpx] pb-[20rpx]">
|
||||
<view class="text-center text-[32rpx] font-700 text-[#323233]">签到规则</view>
|
||||
<view class="mt-[60rpx] mx-[20rpx] mb-[120rpx]">
|
||||
<block v-for="(item) in info.rule_explain.split('\n')">
|
||||
<view class="leading-[40rpx] mb-[20rpx]">{{ item }}</view>
|
||||
</block>
|
||||
</view>
|
||||
<view>
|
||||
<u-button :customStyle="{height:'66rpx',color:'#fff', fontSize:'28rpx',lineHeight:'66rpx',background: 'linear-gradient( 90deg, #fc7035 0%, #EF000C 100%)',border:'none'}" shape="circle" @click="signPopup = false">知道了</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
<!-- 签到奖励 -->
|
||||
<u-popup :show="awardShow" class="award-popup" :customStyle="{backgroundColor:'transparent'}" @close="awardShow = false" mode="center" :round="5" :safeAreaInsetBottom="false" >
|
||||
<view class="w-[550rpx]" v-if="Object.values(signAward).length">
|
||||
<view class="flex justify-center">
|
||||
<image :src="img('static/resource/images/app/award.png')" class="w-[484rpx] h-[480rpx]"></image>
|
||||
</view>
|
||||
<view class="-mt-[265rpx] bg-award rounded-[30rpx] pt-[100rpx] pb-[48rpx] mb-[50rpx] raleative z-10">
|
||||
<view class="px-[32rpx]">
|
||||
<view class="text-[48rpx] text-[#EF000C] font-bold leading-[56rpx] mb-[4rpx] text-center">{{ signAward.title }}</view>
|
||||
<view class="text-[24rpx] text-[#F05F66] leading-[28rpx] text-center mb-[60rpx]">{{ signAward.info }}</view>
|
||||
<view class="px-[68rpx] mb-[54rpx]">
|
||||
<view class="flex items-center mb-[30rpx]" v-if="signAward.awards.point.is_use">
|
||||
<image :src="img('static/resource/images/app/point01.png')" class="w-[40rpx] h-[40rpx]"></image>
|
||||
<view class="ml-[20rpx] text-[28rpx] text-[#333] leading-[32rpx]">{{signAward.awards.point.content }}</view>
|
||||
</view>
|
||||
<block v-if="signAward.awards.shop_coupon.is_use">
|
||||
<view class="flex items-center mb-[30rpx]" v-for="(item,index) in signAward.awards.shop_coupon.content.split(',')" :key="index" >
|
||||
<image :src="img('static/resource/images/app/coupon01.png')" class="w-[40rpx] h-[34rpx]"></image>
|
||||
<view class="ml-[20rpx] text-[28rpx] text-[#333] leading-[32rpx]">{{ item }}</view>
|
||||
</view>
|
||||
</block>
|
||||
<view class="flex items-center" v-if="signAward.awards.balance.is_use">
|
||||
<image :src="img('static/resource/images/app/packet.png')" class="w-[34rpx] h-[40rpx]"></image>
|
||||
<view class="ml-[20rpx] text-[28rpx] text-[#333] leading-[32rpx]">{{signAward.awards.balance.content }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex justify-center">
|
||||
<image :src="img('static/resource/images/app/button.png')" class="w-[380rpx] h-[112rpx]" @click="awardShow = false"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex justify-center">
|
||||
<text class="iconfont iconguanbi1 text-[#fff] text-[60rpx]" @click="awardShow = false"></text>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
<!-- 查看当日或连续签到奖励 -->
|
||||
<u-popup :show="packShow" class="award-popup" :customStyle="{backgroundColor:'transparent'}" @close="packShow = false" mode="center" :round="5" :safeAreaInsetBottom="false">
|
||||
<view class="w-[550rpx]" v-if="Object.values(packInfo).length">
|
||||
<view class="flex justify-center">
|
||||
<image :src="img('static/resource/images/app/award.png')" class="w-[484rpx] h-[480rpx]"></image>
|
||||
</view>
|
||||
<view class="-mt-[265rpx] bg-award rounded-[30rpx] pt-[100rpx] pb-[48rpx] mb-[50rpx] raleative z-10">
|
||||
<view class="px-[32rpx]">
|
||||
<view class="text-[48rpx] text-[#EF000C] font-bold leading-[56rpx] mb-[4rpx] text-center opacity-60">签到奖励</view>
|
||||
<view class="text-[24rpx] text-[#F05F66] opacity-60 leading-[28rpx] text-center mb-[60rpx]">您将获得以下奖励</view>
|
||||
<view class="px-[68rpx] mb-[54rpx]">
|
||||
<view class="flex items-center mb-[32rpx]" v-if="packInfo.point.is_use">
|
||||
<image :src="img('static/resource/images/app/point01.png')" class="w-[40rpx] h-[40rpx]"></image>
|
||||
<view class="ml-[20rpx] text-[28rpx] text-[#333] leading-[32rpx]">{{packInfo.point.content }}</view>
|
||||
</view>
|
||||
<block v-if="packInfo.shop_coupon.is_use">
|
||||
<view class="flex items-center mb-[32rpx]" v-for="(item,index) in packInfo.shop_coupon.content.split(',')" :key="index">
|
||||
<image :src="img('static/resource/images/app/coupon01.png')" class="w-[40rpx] h-[34rpx]"></image>
|
||||
<view class="ml-[20rpx] text-[28rpx] text-[#333] leading-[32rpx]">{{ item }}</view>
|
||||
</view>
|
||||
</block>
|
||||
<view class="flex items-center" v-if="packInfo.balance.is_use">
|
||||
<image :src="img('static/resource/images/app/packet.png')" class="w-[34rpx] h-[40rpx]"></image>
|
||||
<view class="ml-[20rpx] text-[28rpx] text-[#333] leading-[32rpx]">{{packInfo.balance.content }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex justify-center">
|
||||
<image :src="img('static/resource/images/app/button.png')" class="w-[380rpx] h-[112rpx]" @click="packShow = false"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex justify-center">
|
||||
<text class="iconfont iconguanbi1 text-[#fff] text-[60rpx]" @click="packShow = false"></text>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</view>
|
||||
<u-loading-page bg-color="rgb(248,248,248)" :loading="loading" loadingText="" fontSize="16" color="#303133"></u-loading-page>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, toRefs, toRaw, computed } from 'vue'
|
||||
import { redirect, img } from '@/utils/common'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { getSignInfo,getSignConfig, setSign,getDayPack } from '@/app/api/member'
|
||||
import useMemberStore from '@/stores/member'
|
||||
|
||||
let state = reactive({
|
||||
dataCount:[], //当月所有天数
|
||||
weekCount:[], //如果签到周期是7天
|
||||
curYear:0, // 当前年
|
||||
curMonth:0, //当前月
|
||||
curDate:0, //当前日
|
||||
curWeek:0, //当前星期
|
||||
signInList:[], // 签到列表
|
||||
packList:[] //每个小周期内的礼包
|
||||
})
|
||||
let week = reactive({
|
||||
weekDay:0, //当前天
|
||||
week:0 //当前星期
|
||||
})
|
||||
const loading = ref(false)
|
||||
let flag = ref(false)
|
||||
let info = ref({}) //签到配置
|
||||
let signPopup = ref(false)//签到规则弹框
|
||||
let signAward = ref({}) //当日签到奖励
|
||||
let awardShow = ref(false) // 每日签到弹框
|
||||
let packShow = ref(false) //查看每天礼包
|
||||
let packInfo = ref({}) //礼包奖励
|
||||
let active = ref(false)
|
||||
let currentYear=null
|
||||
let currentMonth=null
|
||||
onLoad(() =>{
|
||||
let date=new Date()
|
||||
state.curYear=date.getFullYear()
|
||||
state.curMonth=date.getMonth()
|
||||
state.curDate=date.getDate()
|
||||
state.curWeek=date.getDay()
|
||||
if(state.curWeek==0) state.curWeek = 7
|
||||
|
||||
currentYear=toRaw(state.curYear)
|
||||
currentMonth=toRaw(state.curMonth)
|
||||
|
||||
//初始化执行
|
||||
getDayCounts()
|
||||
getWeekCounts()
|
||||
getSignInfoFn({year:state.curYear,month:state.curMonth+1})
|
||||
getSignConfigFn()
|
||||
})
|
||||
|
||||
// 获取签到配置
|
||||
const getSignConfigFn = () =>{
|
||||
loading.value = true
|
||||
getSignConfig().then((res:any) =>{
|
||||
info.value = res.data
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
// 每个周期签到日期
|
||||
const getSignInfoFn = (data:any) =>{
|
||||
getSignInfo(data).then((res:any) =>{
|
||||
state.signInList = []
|
||||
state.packList = []
|
||||
state.packList = res.data.period
|
||||
state.signInList = res.data.days.map((el:any) =>{
|
||||
return Number(el)
|
||||
})
|
||||
active.value = true
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//获取当月总天数
|
||||
const getDayCounts= () => {
|
||||
let counts = new Date(state.curYear,state.curMonth+1,0).getDate()
|
||||
//获取当前第一天是星期几
|
||||
let firstWeekDay = new Date(state.curYear,state.curMonth,1).getDay()
|
||||
state.dataCount = []
|
||||
for(let i=1;i<counts+firstWeekDay;i++){
|
||||
let val=i-firstWeekDay+ 1
|
||||
state.dataCount.push(val)
|
||||
}
|
||||
}
|
||||
// 获取7天的日期签到
|
||||
const getWeekCounts = () =>{
|
||||
let now = `${state.curYear}-${state.curMonth+1 > 10 ? state.curMonth+1 : '0'+(state.curMonth+1)}-${state.curDate > 10 ? state.curDate : '0'+state.curDate }`
|
||||
for (let i = state.curWeek - 1; i >= 0; i --) {
|
||||
const day = new Date(now).getDate() - i
|
||||
state.weekCount.push(day)
|
||||
}
|
||||
for (let i = 1; i <= 7 - state.curWeek; i++) {
|
||||
const day = new Date(now).getDate() + i
|
||||
state.weekCount.push(day)
|
||||
}
|
||||
}
|
||||
|
||||
//控制状态
|
||||
const handleChange = () =>{
|
||||
let nowDate = new Date().getMonth()
|
||||
|
||||
if(state.curMonth == nowDate){
|
||||
flag.value = !flag.value
|
||||
}else{
|
||||
state.curMonth = new Date().getMonth()
|
||||
state.curYear = new Date().getFullYear()
|
||||
getSignInfoFn({year:state.curYear,month:state.curMonth+1})
|
||||
flag.value = !flag.value
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//更改月份
|
||||
const changeMonth=(type: string)=>{
|
||||
state.dataCount=[]
|
||||
if(type == 'prev'){
|
||||
state.curMonth--
|
||||
if(state.curMonth < 0){
|
||||
state.curMonth = 11
|
||||
state.curYear--
|
||||
}
|
||||
week.weekDay = 1
|
||||
active.value = false
|
||||
}else{
|
||||
state.curMonth++
|
||||
if(state.curMonth > 11){
|
||||
state.curMonth = 0
|
||||
state.curYear++
|
||||
}
|
||||
week.weekDay = 1
|
||||
active.value = false
|
||||
}
|
||||
let data = {year:state.curYear,month:state.curMonth + 1}
|
||||
getSignInfoFn(data)
|
||||
getDayCounts()
|
||||
}
|
||||
|
||||
const memberStore = useMemberStore()
|
||||
|
||||
// 点击签到
|
||||
const setSignFn = () =>{
|
||||
setSign().then(res =>{
|
||||
if(Object.values(res.data).length){
|
||||
signAward.value = res.data
|
||||
getSignInfoFn({year:state.curYear,month:state.curMonth+1})
|
||||
getSignConfigFn()
|
||||
memberStore.getMemberInfo()
|
||||
awardShow.value = true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 查看每日礼包
|
||||
let curPickDay = ref(null)
|
||||
const getDayPackFn = (date:number) =>{
|
||||
let {curYear,curMonth}=toRefs(state)
|
||||
let itemDate=`${curYear.value}-${(curMonth.value+1) < 10 ? '0' + (curMonth.value+1) : (curMonth.value+1)}-${date < 10 ? '0'+date : date}`
|
||||
let flag = state.packList.some(el =>{
|
||||
return el.day == itemDate
|
||||
})
|
||||
if(!flag) return
|
||||
curPickDay.value = date
|
||||
let obj = {
|
||||
year: state.curYear,
|
||||
month:state.curMonth + 1,
|
||||
day: date
|
||||
}
|
||||
getDayPack(obj).then((res:any) => {
|
||||
if(JSON.stringify(res.data) != '[]'){
|
||||
packInfo.value = res.data
|
||||
packShow.value = true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 判断是否签到
|
||||
const isVerDate = (val:any) => {
|
||||
return state.signInList.includes(val)
|
||||
}
|
||||
|
||||
|
||||
//判断是否是当前日期
|
||||
|
||||
const isCurrentDate=(date)=>{
|
||||
if(date> 0 && date <= state.dataCount.length){
|
||||
if(date == state.curDate && currentYear == state.curYear && currentMonth == state.curMonth){
|
||||
return true
|
||||
}
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const isPackDate = (date:any) =>{
|
||||
let {curYear,curMonth}=toRefs(state)
|
||||
let itemDate=`${curYear.value}-${(curMonth.value+1) < 10 ? '0' + (curMonth.value+1) : (curMonth.value+1)}-${date < 10 ? '0'+date : date}`
|
||||
let flag = state.packList.some((el:any) =>{
|
||||
return el.day == itemDate && el.award
|
||||
})
|
||||
return flag
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 过滤日期
|
||||
const filteredDate=(date :any)=>{
|
||||
return date > 0 ? date : ''
|
||||
}
|
||||
|
||||
|
||||
// 获取系统状态栏的高度
|
||||
let menuButtonInfo = {};
|
||||
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API,尚未兼容)
|
||||
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
|
||||
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
||||
// #endif
|
||||
let topTabbarData = ref({
|
||||
title:'我的签到',
|
||||
topStatusBar: {
|
||||
style: 'style-1',
|
||||
bgColor: 'transparent',
|
||||
textColor: '#fff'
|
||||
}
|
||||
})
|
||||
|
||||
const headStyle = computed(() => {
|
||||
let style = ''
|
||||
style = (Number(menuButtonInfo.height) * 2 + menuButtonInfo.top * 2 + 382) + 'rpx;'
|
||||
return style
|
||||
})
|
||||
const topStyle = computed(() => {
|
||||
let style = ''
|
||||
style = (Number(menuButtonInfo.height) * 2 + menuButtonInfo.top * 2 + 38) + 'rpx;'
|
||||
return style
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.bg-color{
|
||||
background-color: rgba(102,102,102,0.4);
|
||||
}
|
||||
.sigin-bg{
|
||||
background: linear-gradient( 90deg, #FFA359 0%, #FF5426 100%), #F2F2F2;
|
||||
}
|
||||
:deep(.award-popup .u-popup__content){
|
||||
background-color: transparent;
|
||||
}
|
||||
.bg-award{
|
||||
background: linear-gradient( 51deg, #FFFBFC 0%, #FFFCF9 59%, #FFE7E7 100%);
|
||||
}
|
||||
|
||||
.bg-button{
|
||||
background: linear-gradient( 180deg, #FFEAE1 0%, #FFCDD0 34%, #E0052C 100%);
|
||||
border-radius: 40rpx;
|
||||
}
|
||||
</style>
|
||||
@ -45,32 +45,31 @@
|
||||
* 获取支付信息
|
||||
*/
|
||||
const getPayInfo = () => {
|
||||
getPayInfoApi(tradeType, tradeId)
|
||||
.then((res : responseResult) => {
|
||||
if (!uni.$u.test.isEmpty(res.data)) {
|
||||
if (res.data.status == 1 && requestNum < 5) {
|
||||
loading.value = true
|
||||
requestNum++
|
||||
setTimeout(() => {
|
||||
getPayInfo()
|
||||
}, 1000)
|
||||
return
|
||||
}
|
||||
payInfo.value = res.data
|
||||
loading.value = false
|
||||
uni.setNavigationBarTitle({
|
||||
title: payInfo.value.status == 2 ? t('pay.paySuccess') : t('pay.payFail')
|
||||
})
|
||||
getPayInfoApi(tradeType, tradeId).then((res: responseResult) => {
|
||||
if (!uni.$u.test.isEmpty(res.data)) {
|
||||
if (res.data.status == 1 && requestNum < 5) {
|
||||
loading.value = true
|
||||
requestNum++
|
||||
setTimeout(() => {
|
||||
getPayInfo()
|
||||
}, 1000)
|
||||
return
|
||||
}
|
||||
}).catch(() => {
|
||||
payInfo.value = res.data
|
||||
loading.value = false
|
||||
uni.setNavigationBarTitle({
|
||||
title: payInfo.value.status == 2 ? t('pay.paySuccess') : t('pay.payFail')
|
||||
})
|
||||
}
|
||||
}).catch(() => {
|
||||
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const complete = () => {
|
||||
const payReturn = decodeURIComponent(uni.getStorageSync('payReturn'))
|
||||
if (payReturn) redirect({ url: payReturn, mode: 'redirectTo' })
|
||||
else redirect({ url: getFirstPage(), param: { code: payInfo.value?.out_trade_no }, mode: 'redirectTo' })
|
||||
if (payReturn) redirect({ url: payReturn, mode: 'reLaunch' })
|
||||
else redirect({ url: getFirstPage(), param: { code: payInfo.value?.out_trade_no }, mode: 'reLaunch' })
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
85
uni-app/src/app/pages/verify/detail.vue
Normal file
85
uni-app/src/app/pages/verify/detail.vue
Normal file
@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<view :style="themeColor()" class="bg-[#f8f8f8] min-h-[100vh] overflow-hidden">
|
||||
<block v-if="!loading">
|
||||
<view class="bg-[#fff] rounded-[16rpx] mt-[20rpx] mx-[20rpx] px-[20rpx] py-[30rpx]">
|
||||
<view class="py-[10rpx] flex" v-for="(item,index) in verifyInfo.value.list" :key="index">
|
||||
<image class="w-[80rpx] h-[80rpx]" mode="aspectFit" v-if="item.cover" :src="img(item.cover)"></image>
|
||||
<image class="w-[80rpx] h-[80rpx]" mode="aspectFit" v-else :src="img('addon/tourism/tourism/member/hotel.png')"></image>
|
||||
<view class="flex flex-col flex-1 ml-[10rpx]">
|
||||
<view class="multi-hidden leading-[1.2]">{{item.name}}</view>
|
||||
<view class="ml-auto text-[#999]">x{{item.num}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="bg-[#fff] rounded-[16rpx] mt-[20rpx] mx-[20rpx] px-[20rpx] py-[30rpx]">
|
||||
<view class="border-0 border-b-[2rpx] leading-[1] pb-[20rpx] border-[#ccc] border-solid">核销信息</view>
|
||||
<view>
|
||||
<view class="flex items-center leading-[1] mt-[30rpx] justify-between">
|
||||
<text>核销类型</text>
|
||||
<view>{{verifyInfo.type_name}}</view>
|
||||
</view>
|
||||
<view class="flex items-center leading-[1] mt-[30rpx] justify-between">
|
||||
<text>核销状态</text>
|
||||
<view>已核销</view>
|
||||
</view>
|
||||
<view class="flex items-center leading-[1] mt-[30rpx] justify-between">
|
||||
<text>核销人员</text>
|
||||
<view>{{verifyInfo.member ? verifyInfo.member.nickname : '--'}}</view>
|
||||
</view>
|
||||
<view class="flex items-center leading-[1] mt-[30rpx] justify-between">
|
||||
<text>核销时间</text>
|
||||
<view>{{verifyInfo.create_time}}</view>
|
||||
</view>
|
||||
<view class="flex items-center leading-[1] mt-[30rpx] justify-between" v-for="(item,index) in verifyInfo.value.content.fixed">
|
||||
<text>{{item.title}}</text>
|
||||
<view>{{item.value}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-for="(item,index) in verifyInfo.value.content.diy" :key="index" class="bg-[#fff] rounded-[16rpx] mt-[20rpx] mx-[20rpx] px-[20rpx] py-[30rpx]">
|
||||
<view class="border-0 border-b-[2rpx] leading-[1] pb-[20rpx] border-[#ccc] border-solid">{{item.title}}</view>
|
||||
<view>
|
||||
<view class="flex items-center leading-[1] mt-[30rpx] justify-between" v-for="(subItem,subIndex) in item.list" :key="subIndex">
|
||||
<text>{{subItem.title}}</text>
|
||||
<view>{{subItem.value}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<u-loading-page :loading="loading" loading-text="" loadingColor="var(--primary-color)" iconSize="35"></u-loading-page>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { img,redirect, getToken } from '@/utils/common';
|
||||
import { getVerifyDetail } from '@/app/api/verify'
|
||||
import { t } from '@/locale'
|
||||
import {onShow} from '@dcloudio/uni-app'
|
||||
|
||||
const loading = ref(true)
|
||||
const verifyDetail = ref<AnyObject | null>(null)
|
||||
let code = ref('');
|
||||
onLoad((option)=> {
|
||||
if (option.code) code.value = option.code;
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
if(getToken()){
|
||||
getVerifyDetailFn();
|
||||
}
|
||||
})
|
||||
|
||||
let verifyInfo = ref({})
|
||||
const getVerifyDetailFn = ()=>{
|
||||
loading.value = true;
|
||||
getVerifyDetail(code.value).then((res:any) =>{
|
||||
verifyInfo.value = res.data;
|
||||
loading.value = false;
|
||||
console.log("verifyInfo.value",verifyInfo.value)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
306
uni-app/src/app/pages/verify/index.vue
Normal file
306
uni-app/src/app/pages/verify/index.vue
Normal file
@ -0,0 +1,306 @@
|
||||
<template>
|
||||
<view :style="themeColor()">
|
||||
<view class="container" v-if="!loading">
|
||||
<view class="action-wrap">
|
||||
<view class="record-wrap text-[var(--primary-color)]" @click="redirect({url:'/app/pages/verify/record'})">
|
||||
<text class="iconfont iconjilu color-base-text"></text>
|
||||
<text class="text-[28rpx]">核销记录</text>
|
||||
</view>
|
||||
|
||||
<view class="sweep-code ns-gradient-otherpages-member-balance-balance-rechange" @click="scanCode" v-show="operationType == 'sweepCode'">
|
||||
<text class="iconfont iconsaoma"></text>
|
||||
</view>
|
||||
<view class="manual-input" v-show="operationType == 'manualInput'">
|
||||
<view class="process-wrap">
|
||||
<view class="wrap">
|
||||
<view class="_icon"><text class="iconfont iconshurutianxiebi color-base-text"></text></view>
|
||||
<view class="_text">输入核销码</view>
|
||||
</view>
|
||||
<view>
|
||||
<view><text class="iconfont iconjiang-copy color-tip"></text></view>
|
||||
</view>
|
||||
<view class="wrap">
|
||||
<view class="_icon"><text class="iconfont iconhexiao color-base-text"></text></view>
|
||||
<view class="_text">核销</view>
|
||||
</view>
|
||||
</view>
|
||||
<input type="text" placeholder="请输入核销码" class="_input" placeholder-class="_placeholder" v-model="verify_code" :focus="isFocus" ref="input" />
|
||||
<view class="_btn" @click="confirm"><button class="h-[80rpx] flex items-center justify-center !text-[28rpx]" type="primary">确认</button></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="arc-edge"></view>
|
||||
|
||||
<view class="action-type-wrap">
|
||||
<view class="action" @click="changeOperationType('sweepCode')">
|
||||
<view class="_icon"><text class="iconfont iconsaoma"></text></view>
|
||||
<view class="_text">扫码核销</view>
|
||||
</view>
|
||||
<view class="iconfont icontiaoxingmasaomiao ns-gradient-otherpages-member-balance-balance-rechange"></view>
|
||||
<view class="action" @click="changeOperationType('manualInput')">
|
||||
<view class="_icon"><text class="iconfont iconshuru"></text></view>
|
||||
<view class="_text" @click="focus">手动输入</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<!-- 小程序隐私协议 -->
|
||||
<privacy-popup ref="privacyPopup"></privacy-popup>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
<u-loading-page :loading="loading" loading-text="" loadingColor="var(--primary-color)" iconSize="35"></u-loading-page>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { img,redirect, isWeixinBrowser, getToken } from '@/utils/common';
|
||||
import {onShow} from '@dcloudio/uni-app'
|
||||
import { getVerifierInfo, getCheckVerifier } from '@/app/api/verify'
|
||||
import { t } from '@/locale'
|
||||
import wechat from '@/utils/wechat'
|
||||
|
||||
let operationType = ref('manualInput'); //类型
|
||||
// #ifdef H5
|
||||
operationType.value = 'manualInput';
|
||||
// #endif
|
||||
// #ifndef H5
|
||||
operationType.value = 'sweepCode';
|
||||
// #endif
|
||||
|
||||
let isFocus = ref(false)
|
||||
let verify_code = ref('');
|
||||
let loading = ref(true)
|
||||
onShow(() => {
|
||||
if(getToken())
|
||||
checkIsVerifier();
|
||||
})
|
||||
|
||||
// 检测是否是核销员
|
||||
const checkIsVerifier = () => {
|
||||
getCheckVerifier().then((res:any) =>{
|
||||
if(!res.data){
|
||||
uni.showToast({
|
||||
title: '非核销员无此权限',
|
||||
icon: 'none'
|
||||
});
|
||||
setTimeout(() => {
|
||||
uni.navigateBack();
|
||||
}, 1000);
|
||||
}else{
|
||||
loading.value = false;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const scanCode = () => {
|
||||
// #ifdef MP
|
||||
uni.scanCode({
|
||||
onlyFromCamera: true,
|
||||
success: res => {
|
||||
if (res.errMsg == 'scanCode:ok') {
|
||||
let code = res.result;
|
||||
redirect({ url: '/app/pages/verify/verify', param: { code} })
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.errorMsg,
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
if (isWeixinBrowser()) {
|
||||
wechat.init();
|
||||
wechat.scanQRCode(res => {
|
||||
if (res.resultStr) {
|
||||
let code = res.resultStr;
|
||||
redirect({ url: '/app/pages/verify/verify', param: { code} })
|
||||
}
|
||||
});
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
|
||||
let isLoading = false;
|
||||
const confirm = () => {
|
||||
if(isLoading) return false;
|
||||
isLoading = true;
|
||||
var reg = /[\S]+/;
|
||||
if (!reg.test(verify_code.value)) {
|
||||
uni.showToast({
|
||||
title: '请输入核销码',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
getVerifierInfo(verify_code.value).then((res:any) =>{
|
||||
isLoading = false;
|
||||
redirect({ url: '/app/pages/verify/verify', param: { code: verify_code.value} })
|
||||
})
|
||||
}
|
||||
|
||||
const focus = () => {
|
||||
isFocus.value = !isFocus.value;
|
||||
}
|
||||
|
||||
const changeOperationType = (type: string) => {
|
||||
// #ifdef H5
|
||||
if (type == 'sweepCode' && !isWeixinBrowser()) {
|
||||
uni.showToast({
|
||||
title: 'H5端不支持扫码核销',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
// #endif
|
||||
operationType.value = type;
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.container {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: #f8f8f8;
|
||||
|
||||
.action-wrap {
|
||||
padding: 100rpx 0;
|
||||
background: #fff;
|
||||
position: relative;
|
||||
|
||||
.record-wrap {
|
||||
position: absolute;
|
||||
top: 30rpx;
|
||||
right: 30rpx;
|
||||
|
||||
.iconfont {
|
||||
font-size: 28rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.sweep-code {
|
||||
width: 400rpx;
|
||||
height: 400rpx;
|
||||
box-shadow: 0 8px 8px 0 rgba(0, 0, 0, 0.03), 0 6px 3px 0 rgba(0, 0, 0, 0.02);
|
||||
border-radius: 50%;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
line-height: 400rpx;
|
||||
background: var(--primary-color);
|
||||
|
||||
.iconfont {
|
||||
color: #fff;
|
||||
font-size: 150rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.manual-input {
|
||||
width: 70%;
|
||||
margin: auto;
|
||||
|
||||
.process-wrap {
|
||||
height: 140rpx;
|
||||
display: flex;
|
||||
padding-top: 60rpx;
|
||||
|
||||
.wrap {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
|
||||
._icon {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
background: #eee;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto;
|
||||
color: var(--primary-color);
|
||||
|
||||
.iconfont {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
|
||||
._text {
|
||||
font-size: 24rpx;
|
||||
margin-top: 10rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
._input {
|
||||
height: 80rpx;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 8rpx;
|
||||
box-sizing: border-box;
|
||||
padding: 20rpx;
|
||||
font-size: 28rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
._placeholder {
|
||||
font-size: 28rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
._btn {
|
||||
margin-top: 40rpx;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.arc-edge {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
background: #fff;
|
||||
border-radius: 400rpx/40rpx; /*上下有弧度的边*/
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.action-type-wrap {
|
||||
width: 70%;
|
||||
height: 90rpx;
|
||||
background: #fff;
|
||||
border-radius: 90rpx;
|
||||
display: flex;
|
||||
position: relative;
|
||||
box-shadow: 0 6px 6px 0 rgba(0, 0, 0, 0.03), 0 4px 2px 0 rgba(0, 0, 0, 0.04);
|
||||
margin: 100rpx auto;
|
||||
|
||||
.action {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
color: #333;
|
||||
|
||||
._icon {
|
||||
line-height: 25px;
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
._text {
|
||||
font-size: 24rpx;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.icontiaoxingmasaomiao {
|
||||
width: 110rpx;
|
||||
height: 110rpx;
|
||||
border-radius: 50%;
|
||||
transform: translateY(-10rpx);
|
||||
box-shadow: 0 8px 8px 0 rgba(0, 0, 0, 0.03), 0 6px 3px 0 rgba(0, 0, 0, 0.02);
|
||||
text-align: center;
|
||||
line-height: 110rpx;
|
||||
background: var(--primary-color);
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
168
uni-app/src/app/pages/verify/record.vue
Normal file
168
uni-app/src/app/pages/verify/record.vue
Normal file
@ -0,0 +1,168 @@
|
||||
<template>
|
||||
<view class="bg-[#f8f8f8] min-h-screen overflow-hidden" :style="themeColor()">
|
||||
<mescroll-body ref="mescrollRef" top="20rpx" @init="mescrollInit" @down="downCallback" @up="geVerifyRecordFn">
|
||||
<view class="goods-wrap">
|
||||
<block v-for="(item,index) in list" :key="item.id">
|
||||
<view class="goods-item" @click="toLink(item)">
|
||||
<view class="flex items-center justify-between border-0 border-b-[2rpx] border-[#ccc] border-solid pb-[20rpx]">
|
||||
<text class="truncate w-[460rpx] text-[#999]">核销码:{{ item.code }}</text>
|
||||
<text class="text-[#999]">核销员:{{ item.member ? item.member.nickname : '--' }}</text>
|
||||
</view>
|
||||
<view class="py-[20rpx]">
|
||||
<view class="py-[10rpx] flex" v-for="(dataItem,dataIndex) in item.value.list" :key="dataIndex">
|
||||
<image class="w-[80rpx] h-[80rpx]" mode="aspectFit" v-if="dataItem.cover" :src="img(dataItem.cover)"></image>
|
||||
<image class="w-[80rpx] h-[80rpx]" mode="aspectFit" v-else :src="img('addon/tourism/tourism/member/hotel.png')"></image>
|
||||
<view class="flex flex-col flex-1 ml-[10rpx]">
|
||||
<view class="multi-hidden leading-[1.2]">{{dataItem.name}}</view>
|
||||
<view class="ml-auto text-[#999]">x{{dataItem.num}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex items-center justify-between border-0 border-t-[2rpx] border-[#ccc] border-solid pt-[20rpx]">
|
||||
<text class="text-[#999]">核销时间:{{ item.create_time }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<mescroll-empty :option="{'icon': img('static/resource/images/empty.png')}" v-if="!list.length && loading"></mescroll-empty>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import MescrollBody from '@/components/mescroll/mescroll-body/mescroll-body.vue'
|
||||
import MescrollEmpty from '@/components/mescroll/mescroll-empty/mescroll-empty.vue'
|
||||
import useMescroll from '@/components/mescroll/hooks/useMescroll.js'
|
||||
import { onPageScroll, onReachBottom } from '@dcloudio/uni-app'
|
||||
import { getVerifyRecords } from '@/app/api/verify'
|
||||
import { img, redirect } from '@/utils/common'
|
||||
|
||||
let list = ref<Array<Object>>([])
|
||||
let loading = ref<boolean>(false)
|
||||
const { mescrollInit, downCallback, getMescroll } = useMescroll(onPageScroll, onReachBottom)
|
||||
|
||||
const geVerifyRecordFn = (mescroll) => {
|
||||
loading.value = false;
|
||||
let data : object = {
|
||||
page: mescroll.num,
|
||||
limit: mescroll.size,
|
||||
};
|
||||
|
||||
getVerifyRecords(data).then((res) => {
|
||||
let newArr = (res.data.data as Array<Object>);
|
||||
//设置列表数据
|
||||
if (mescroll.num == 1) {
|
||||
list.value = []; //如果是第一页需手动制空列表
|
||||
}
|
||||
list.value = list.value.concat(newArr);
|
||||
mescroll.endSuccess(newArr.length);
|
||||
loading.value = true;
|
||||
}).catch(() => {
|
||||
loading.value = true;
|
||||
mescroll.endErr(); // 请求失败, 结束加载
|
||||
})
|
||||
}
|
||||
|
||||
const toLink = (data: AnyObject)=> {
|
||||
redirect({ url: '/app/pages/verify/detail', param: { code: data.code } })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.font-scale{
|
||||
transform: scale(0.75);
|
||||
}
|
||||
.text-color{
|
||||
color: $u-primary;
|
||||
}
|
||||
.bg-color{
|
||||
background-color: $u-primary;
|
||||
}
|
||||
|
||||
.goods-wrap{
|
||||
margin: 20rpx 20rpx 0;
|
||||
.goods-item{
|
||||
@apply w-full flex flex-col mb-3 bg-[#fff] py-3 px-4 box-border;
|
||||
border-radius: 18rpx;
|
||||
overflow: hidden;
|
||||
.goods-head{
|
||||
@apply flex justify-between pb-3 border-0 border-b-1 border-solid border-[#F0F0F0] mb-4;
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
}
|
||||
.goods-content{
|
||||
@apply flex;
|
||||
& > image{
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
& > view{
|
||||
flex: 1;
|
||||
}
|
||||
.name-wrap{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20rpx;
|
||||
&> view{
|
||||
&:first-of-type{
|
||||
font-weight: bold;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.desc{
|
||||
color: #686868;
|
||||
font-size: 26rpx;
|
||||
margin-bottom: 14rpx;
|
||||
}
|
||||
.time-wrap{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #F6F7FB;
|
||||
border-radius: 8rpx;
|
||||
height: 62rpx;
|
||||
font-size: 26rpx;
|
||||
padding: 0 16rpx;
|
||||
text{
|
||||
&:nth-child(1){
|
||||
color: #444;
|
||||
margin-right: 14rpx;
|
||||
}
|
||||
&:nth-child(2){
|
||||
color: #686868;
|
||||
}
|
||||
&:nth-child(3){
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
.btn-wrap{
|
||||
justify-content: flex-end;
|
||||
@apply flex margin-0 mt-2 flex-wrap;
|
||||
button{
|
||||
width: 172rpx;
|
||||
height: 64rpx;
|
||||
font-size: 26rpx;
|
||||
@apply rounded-3xl;
|
||||
line-height: 64rpx;
|
||||
background-color: transparent;
|
||||
margin: 0;
|
||||
margin-left: 20rpx;
|
||||
@apply mt-2;
|
||||
border: 2rpx solid #E2E2E2;
|
||||
&[type="primary"]{
|
||||
background-color: $u-primary;
|
||||
}
|
||||
&::after{
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
115
uni-app/src/app/pages/verify/verify.vue
Normal file
115
uni-app/src/app/pages/verify/verify.vue
Normal file
@ -0,0 +1,115 @@
|
||||
<template>
|
||||
<view :style="themeColor()" class="bg-[#f8f8f8] min-h-[100vh] overflow-hidden">
|
||||
<block v-if="!loading && verifyInfo && verifyInfo.value">
|
||||
<view class="bg-[#fff] rounded-[16rpx] mt-[20rpx] mx-[20rpx] px-[20rpx] py-[30rpx]">
|
||||
<view class="py-[10rpx] flex" v-for="(item,index) in verifyInfo.value.list" :key="index">
|
||||
<image class="w-[80rpx] h-[80rpx]" mode="aspectFit" v-if="item.cover" :src="img(item.cover)"></image>
|
||||
<image class="w-[80rpx] h-[80rpx]" mode="aspectFit" v-else :src="img('addon/tourism/tourism/member/hotel.png')"></image>
|
||||
<view class="flex flex-col flex-1 ml-[10rpx]">
|
||||
<view class="multi-hidden leading-[1.2]">{{item.name}}</view>
|
||||
<view class="ml-auto text-[#999]">x{{item.num}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="bg-[#fff] rounded-[16rpx] mt-[20rpx] mx-[20rpx] px-[20rpx] py-[30rpx]">
|
||||
<view class="border-0 border-b-[2rpx] leading-[1] pb-[20rpx] border-[#ccc] border-solid">核销信息</view>
|
||||
<view class="text-[28rpx]">
|
||||
<view class="flex items-center leading-[1] mt-[30rpx] justify-between">
|
||||
<text>核销类型</text>
|
||||
<view>{{verifyInfo.type_name}}</view>
|
||||
</view>
|
||||
<view class="flex items-center leading-[1] mt-[30rpx] justify-between" v-for="(item,index) in verifyInfo.value.content.fixed">
|
||||
<text>{{item.title}}</text>
|
||||
<view>{{item.value}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-for="(item,index) in verifyInfo.value.content.diy" :key="index" class="bg-[#fff] rounded-[16rpx] mt-[20rpx] mx-[20rpx] px-[20rpx] py-[30rpx]">
|
||||
<view class="border-0 border-b-[2rpx] leading-[1] pb-[20rpx] border-[#ccc] border-solid">{{item.title}}</view>
|
||||
<view class="text-[28rpx]">
|
||||
<view class="flex items-center leading-[1] mt-[30rpx] justify-between" v-for="(subItem,subIndex) in item.list" :key="subIndex">
|
||||
<text>{{subItem.title}}</text>
|
||||
<view>{{subItem.value}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<text class="bg-[var(--primary-color)] text-[#fff] mx-[20rpx] mt-[60rpx] h-[80rpx] flex items-center justify-center !text-[28rpx] rounded-[10rpx]" @click="verifyFn">核销</text>
|
||||
</block>
|
||||
<u-loading-page :loading="loading" loading-text="" loadingColor="var(--primary-color)" iconSize="35"></u-loading-page>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { img,redirect, isWeixinBrowser, getToken } from '@/utils/common';
|
||||
import { getVerifierInfo, getCheckVerifier, verify } from '@/app/api/verify'
|
||||
import { t } from '@/locale'
|
||||
import {onShow} from '@dcloudio/uni-app'
|
||||
|
||||
const loading = ref(true)
|
||||
const verifyDetail = ref<AnyObject | null>(null)
|
||||
let code = ref('');
|
||||
onLoad((option)=> {
|
||||
if (option.code) code.value = option.code;
|
||||
// 小程序扫码进入
|
||||
if (option.scene) {
|
||||
let sceneParams = decodeURIComponent(option.scene);
|
||||
sceneParams = sceneParams.split('&');
|
||||
if (sceneParams.length) {
|
||||
sceneParams.forEach(item => {
|
||||
if (item.indexOf('code') != -1) code.value = item.split('-')[1];
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
if(getToken()){
|
||||
checkIsVerifier();
|
||||
getVerifierInfoFn();
|
||||
}
|
||||
})
|
||||
|
||||
// 检测是否是核销员
|
||||
const checkIsVerifier = () => {
|
||||
getCheckVerifier().then((res:any) =>{
|
||||
if(!res.data){
|
||||
uni.showToast({
|
||||
title: '非核销员无此权限',
|
||||
icon: 'none'
|
||||
});
|
||||
setTimeout(() => {
|
||||
uni.navigateBack();
|
||||
}, 1000);
|
||||
}else{
|
||||
loading.value = false;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
let verifyInfo = ref({})
|
||||
const getVerifierInfoFn = ()=>{
|
||||
loading.value = true;
|
||||
getVerifierInfo(code.value).then((res:any) =>{
|
||||
verifyInfo.value = res.data;
|
||||
loading.value = false;
|
||||
console.log("verifyInfo.value",verifyInfo.value)
|
||||
})
|
||||
}
|
||||
let isLoading = false;
|
||||
const verifyFn = ()=>{
|
||||
if(isLoading) return false;
|
||||
isLoading = true;
|
||||
|
||||
verify(code.value).then((res:any) =>{
|
||||
isLoading = false;
|
||||
setTimeout(() => {
|
||||
redirect({ url: '/app/pages/verify/index', param: {}, mode: 'redirectTo' })
|
||||
}, 1000);
|
||||
})
|
||||
}
|
||||
</script>
|
||||
38
uni-app/src/app/pages/weapp/order_shipping.vue
Normal file
38
uni-app/src/app/pages/weapp/order_shipping.vue
Normal file
@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<view :style="themeColor()">
|
||||
<view class="error-msg">{{errorMsg}}</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {ref} from 'vue';
|
||||
import {redirect} from '@/utils/common';
|
||||
import {onLoad} from '@dcloudio/uni-app'
|
||||
import {getMsgJumpPath} from '@/app/api/system'
|
||||
|
||||
const outTradeNo = ref('')
|
||||
const errorMsg = ref('')
|
||||
|
||||
onLoad((options: any) => {
|
||||
console.log('onload',options)
|
||||
if (options.merchant_trade_no) {
|
||||
outTradeNo.value = options.merchant_trade_no;
|
||||
getMsgJumpPathFn();
|
||||
} else {
|
||||
errorMsg.value = '缺少merchant_trade_no参数';
|
||||
}
|
||||
});
|
||||
|
||||
const getMsgJumpPathFn = () => {
|
||||
getMsgJumpPath({
|
||||
out_trade_no: outTradeNo.value,
|
||||
}).then((res: any) => {
|
||||
if(res.data && res.data.path){
|
||||
// 跳转到设置的页面
|
||||
redirect({url: '/' + res.data.path, mode: 'reLaunch'})
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@ -1,5 +1,5 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { toRaw } from 'vue'
|
||||
import {defineStore} from 'pinia'
|
||||
import {toRaw} from 'vue'
|
||||
|
||||
interface Diy {
|
||||
mode: string, // 模式:decorate 装修,为空表示正常
|
||||
@ -7,115 +7,120 @@ interface Diy {
|
||||
currentIndex: number,
|
||||
global: {
|
||||
title: string,
|
||||
pageStartBgColor: string, // 页面背景颜色(开始)
|
||||
pageEndBgColor: string, // 页面背景颜色(结束)
|
||||
pageStartBgColor: string, // 页面背景颜色(开始)
|
||||
pageEndBgColor: string, // 页面背景颜色(结束)
|
||||
bottomTabBarSwitch: boolean, // 底部导航开关
|
||||
bgUrl: string
|
||||
},
|
||||
// 组件集合
|
||||
value: any[],
|
||||
topFixedStatus: string, // 置顶组件的状态
|
||||
scrollTop: number
|
||||
scrollTop: number,
|
||||
topTabarHeight: number
|
||||
}
|
||||
|
||||
const useDiyStore = defineStore('diy', {
|
||||
state: () : Diy => {
|
||||
state: (): Diy => {
|
||||
return {
|
||||
mode: '',
|
||||
pageMode: 'diy',
|
||||
currentIndex: -99,
|
||||
global: {
|
||||
title: "",
|
||||
pageStartBgColor: '', // 页面背景颜色(开始)
|
||||
pageEndBgColor: '', // 页面背景颜色(结束)
|
||||
pageStartBgColor: '', // 页面背景颜色(开始)
|
||||
pageEndBgColor: '', // 页面背景颜色(结束)
|
||||
bottomTabBarSwitch: true,
|
||||
bgUrl: ''
|
||||
},
|
||||
value: [], // 组件集合
|
||||
topFixedStatus: 'home', // 顶部 置顶组件状态,home:展示首页数据、diy:展示置顶组件定义的子页面
|
||||
scrollTop: 0 // 滚动位置
|
||||
scrollTop: 0, // 滚动位置
|
||||
topTabarHeight: 0
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
},
|
||||
actions: {
|
||||
// 初始化
|
||||
init() {
|
||||
// #ifdef H5
|
||||
var data = JSON.stringify({
|
||||
type: 'init',
|
||||
load: true
|
||||
});
|
||||
// 传输给后台数据
|
||||
window.parent.postMessage(data, '*');
|
||||
getters: {},
|
||||
actions: {
|
||||
// 初始化
|
||||
init() {
|
||||
// #ifdef H5
|
||||
var data = JSON.stringify({
|
||||
type: 'init',
|
||||
load: true
|
||||
});
|
||||
// 传输给后台数据
|
||||
window.parent.postMessage(data, '*');
|
||||
|
||||
// 监听父页面发来的消息
|
||||
window.addEventListener('message', event => {
|
||||
try {
|
||||
let data = JSON.parse(event.data);
|
||||
this.currentIndex = data.currentIndex;
|
||||
this.pageMode = data.pageMode;
|
||||
if (data.global) this.global = data.global;
|
||||
if (data.value) this.value = data.value;
|
||||
// 监听父页面发来的消息
|
||||
window.addEventListener('message', event => {
|
||||
try {
|
||||
let data = JSON.parse(event.data);
|
||||
this.currentIndex = data.currentIndex;
|
||||
this.pageMode = data.pageMode;
|
||||
if (data.global) this.global = data.global;
|
||||
if (data.value) this.value = data.value;
|
||||
|
||||
if (this.value) {
|
||||
this.value.forEach((item, index) => {
|
||||
item.pageStyle = '';
|
||||
if(item.pageStartBgColor) {
|
||||
if (item.pageStartBgColor && item.pageEndBgColor) item.pageStyle += `background:linear-gradient(${item.pageGradientAngle},${item.pageStartBgColor},${item.pageEndBgColor});`;
|
||||
else item.pageStyle += 'background-color:' + item.pageStartBgColor + ';';
|
||||
}
|
||||
if (this.value) {
|
||||
this.value.forEach((item, index) => {
|
||||
item.pageStyle = '';
|
||||
if (item.pageStartBgColor) {
|
||||
if (item.pageStartBgColor && item.pageEndBgColor) item.pageStyle += `background:linear-gradient(${item.pageGradientAngle},${item.pageStartBgColor},${item.pageEndBgColor});`;
|
||||
else item.pageStyle += 'background-color:' + item.pageStartBgColor + ';';
|
||||
}
|
||||
|
||||
if (item.margin) {
|
||||
item.pageStyle += 'padding-top:' + item.margin.top * 2 + 'rpx' + ';';
|
||||
item.pageStyle += 'padding-bottom:' + item.margin.bottom * 2 + 'rpx' + ';';
|
||||
item.pageStyle += 'padding-right:' + item.margin.both * 2 + 'rpx' + ';';
|
||||
item.pageStyle += 'padding-left:' + item.margin.both * 2 + 'rpx' + ';';
|
||||
}
|
||||
});
|
||||
}
|
||||
// console.log('uniapp 接受后台装修返回的组件数据', data);
|
||||
} catch (e) {
|
||||
console.log('uni-app diy 接受数据错误', e)
|
||||
}
|
||||
}, false);
|
||||
// #endif
|
||||
},
|
||||
// 将数据传输给后台
|
||||
postMessage(index, component) {
|
||||
// #ifdef H5
|
||||
this.currentIndex = index;
|
||||
if (component)
|
||||
var data = JSON.stringify({
|
||||
type: 'data',
|
||||
index: this.currentIndex,
|
||||
global: toRaw(this.global),
|
||||
value: toRaw(this.value),
|
||||
component: toRaw(component)
|
||||
});
|
||||
// 传输给后台数据
|
||||
window.parent.postMessage(data, '*');
|
||||
// #endif
|
||||
},
|
||||
// 选中正在编辑的组件
|
||||
changeCurrentIndex(index : number, component : any = null) {
|
||||
// #ifdef H5
|
||||
if (item.margin) {
|
||||
if (item.margin.top > 0) {
|
||||
item.pageStyle += 'padding-top:' + item.margin.top * 2 + 'rpx' + ';';
|
||||
} else {
|
||||
item.pageStyle += 'padding-top:2rpx' + ';'; // 装修实时预览需要设置
|
||||
}
|
||||
item.pageStyle += 'padding-bottom:' + item.margin.bottom * 2 + 'rpx' + ';';
|
||||
item.pageStyle += 'padding-right:' + item.margin.both * 2 + 'rpx' + ';';
|
||||
item.pageStyle += 'padding-left:' + item.margin.both * 2 + 'rpx' + ';';
|
||||
}
|
||||
});
|
||||
}
|
||||
// console.log('uniapp 接受后台装修返回的组件数据', data);
|
||||
} catch (e) {
|
||||
console.log('uni-app diy 接受数据错误', e)
|
||||
}
|
||||
}, false);
|
||||
// #endif
|
||||
},
|
||||
// 将数据传输给后台
|
||||
postMessage(index, component) {
|
||||
// #ifdef H5
|
||||
this.currentIndex = index;
|
||||
if (component)
|
||||
var data = JSON.stringify({
|
||||
type: 'data',
|
||||
index: this.currentIndex,
|
||||
global: toRaw(this.global),
|
||||
value: toRaw(this.value),
|
||||
component: toRaw(component)
|
||||
});
|
||||
// 传输给后台数据
|
||||
window.parent.postMessage(data, '*');
|
||||
// #endif
|
||||
},
|
||||
// 选中正在编辑的组件
|
||||
changeCurrentIndex(index: number, component: any = null) {
|
||||
// #ifdef H5
|
||||
|
||||
// 实际展示禁止编辑
|
||||
if (this.mode == '') return;
|
||||
// 实际展示禁止编辑
|
||||
if (this.mode == '') return;
|
||||
|
||||
// 减少重复请求
|
||||
if (this.currentIndex == index) return;
|
||||
this.currentIndex = index;
|
||||
var data = JSON.stringify({
|
||||
type: 'change',
|
||||
index,
|
||||
component: toRaw(component)
|
||||
});
|
||||
window.parent.postMessage(data, '*');
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
// 减少重复请求
|
||||
if (this.currentIndex == index) return;
|
||||
this.currentIndex = index;
|
||||
var data = JSON.stringify({
|
||||
type: 'change',
|
||||
index,
|
||||
component: toRaw(component)
|
||||
});
|
||||
window.parent.postMessage(data, '*');
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default useDiyStore
|
||||
@ -8,23 +8,20 @@
|
||||
<view class="mx-[30rpx]">
|
||||
<view class="mt-[20rpx]">
|
||||
<u-form-item :label="t('headimg')" prop="headimg" :border-bottom="true">
|
||||
<button class="m-0 my-[10rpx] p-0 w-[140rpx] h-[140rpx]" open-type="chooseAvatar"
|
||||
@chooseavatar="onChooseAvatar">
|
||||
<button class="m-0 my-[10rpx] p-0 w-[140rpx] h-[140rpx]" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
|
||||
<view class="w-full h-full flex items-center justify-center overflow-hidden">
|
||||
<u-image :src="img(formData.headimg)" width="140rpx" v-if="formData.headimg"></u-image>
|
||||
<u-image :src="img(formData.headimg)" width="140rpx" height="140rpx" v-if="formData.headimg" mode="aspectFill"></u-image>
|
||||
<u-icon name="plus" v-else></u-icon>
|
||||
</view>
|
||||
</button>
|
||||
</u-form-item>
|
||||
<u-form-item :label=" t('nickname')" prop="nickname" :border-bottom="true">
|
||||
<input type="nickname" v-model="formData.nickname" :placeholder="t('nicknamePlaceholder')"
|
||||
@blur="bindNickname">
|
||||
<input type="nickname" v-model="formData.nickname" :placeholder="t('nicknamePlaceholder')" @blur="bindNickname">
|
||||
</u-form-item>
|
||||
</view>
|
||||
</view>
|
||||
<view class="p-[30rpx] mt-[20rpx]">
|
||||
<u-button type="primary" :loading="loading" :text="t('confirm')" shape="circle"
|
||||
@click="confirm"></u-button>
|
||||
<u-button type="primary" :loading="loading" :text="t('confirm')" shape="circle" @click="confirm"></u-button>
|
||||
</view>
|
||||
</u-form>
|
||||
</u-popup>
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<u-popup :show="show" :round="10" @close="handleClose" :closeable="true" bgColor="#fff" zIndex="10081"
|
||||
:closeOnClickOverlay="false">
|
||||
<u-popup :show="show" :round="10" @close="handleClose" :closeable="true" bgColor="#fff" zIndex="10081" :closeOnClickOverlay="false">
|
||||
<view class="flex flex-col h-[75vh]" v-if="payInfo" @touchmove.prevent.stop>
|
||||
<view class="head">
|
||||
<view class="text-center py-[26rpx]">{{ t('pay.payTitle') }}</view>
|
||||
@ -12,12 +11,11 @@
|
||||
<scroll-view scroll-y="true" class="flex-1 pt-[20rpx]">
|
||||
<view class="flex text-sm px-[30rpx] py-[20rpx]">
|
||||
<view class="text-gray-500">{{ t('pay.orderInfo') }}</view>
|
||||
<view class="text-right flex-1 pl-[30rpx] truncate">{{ payInfo.body }}</view>
|
||||
<view class="text-right flex-1 pl-[30rpx] using-hidden">{{ payInfo.body }}</view>
|
||||
</view>
|
||||
<view class="mx-[30rpx] py-[10rpx] px-[30rpx] bg-white rounded-md bg-page">
|
||||
<block v-if="payInfo.pay_type_list.length">
|
||||
<view class="pay-item py-[18rpx] flex items-center border-0 border-b border-solid border-[#eee]"
|
||||
v-for="(item, index) in payInfo.pay_type_list" :key="index" @click="type = item.key">
|
||||
<view class="pay-item py-[18rpx] flex items-center border-0 border-b border-solid border-[#eee]" v-for="(item, index) in payInfo.pay_type_list" :key="index" @click="type = item.key">
|
||||
<u-image :src="img(item.icon)" width="50rpx" height="50rpx"></u-image>
|
||||
<view class="flex-1 px-[20rpx] text-sm font-bold">{{ item.name }}</view>
|
||||
<u-icon name="checkbox-mark" color="var(--primary-color)" v-if="item.key == type"></u-icon>
|
||||
@ -27,8 +25,7 @@
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="p-[30rpx]">
|
||||
<u-button type="primary" :loading="loading" :text="t('pay.confirmPay')" shape="circle"
|
||||
@click="confirmPay"></u-button>
|
||||
<u-button type="primary" :loading="loading" :text="t('pay.confirmPay')" shape="circle" @click="confirmPay"></u-button>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
|
||||
@ -3,9 +3,9 @@
|
||||
<view @touchmove.prevent.stop class="share-popup">
|
||||
<u-popup :show="sharePopupShow" type="bottom" @close="sharePopuClose" overlayOpacity="0.8">
|
||||
<view @touchmove.prevent.stop>
|
||||
<image v-if="isPosterAnimation" class="poster-animation" :src="img('addon/shop/poster_animation.gif')" mode=""></image>
|
||||
<view v-if="isPosterImg" class="poster-img">
|
||||
<image :src="img(poster)" mode="aspectFit"></image>
|
||||
<view class="poster-img-wrap" :style="{'top': shareTop}">
|
||||
<image v-if="isPosterAnimation" class="poster-animation" :src="img('addon/shop/poster_animation.gif')" mode="aspectFit"></image>
|
||||
<image v-if="isPosterImg" class="poster-img" :src="img(poster)" mode="aspectFit"></image>
|
||||
</view>
|
||||
<view class="share-content">
|
||||
<!-- #ifdef MP || APP-PLUS -->
|
||||
@ -36,6 +36,18 @@
|
||||
<view class="share-footer" @click="sharePopuClose"><text>取消分享</text></view>
|
||||
</view>
|
||||
</u-popup>
|
||||
<u-popup :show="show" mode="center" :round="10" :closeable="true" @close="show = false" :safe-area-inset-bottom="false">
|
||||
<view class="dialog-popup">
|
||||
<view class="title">提示</view>
|
||||
<view class="message">您拒绝了保存图片到相册的授权请求,无法保存图片到相册,如需正常使用,请授权之后再进行操作。</view>
|
||||
<view class="action-wrap">
|
||||
<view @click="closeDialog">取消</view>
|
||||
<view>
|
||||
<button type="default" class="authorization-btn" open-type="openSetting" @opensetting="closeDialog" hover-class="none">立即授权</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@ -45,6 +57,10 @@ import { img, copy } from '@/utils/common';
|
||||
import { getPoster } from '@/app/api/system'
|
||||
|
||||
const props = defineProps({
|
||||
posterId: {
|
||||
type: String || Number,
|
||||
default: 0
|
||||
},
|
||||
posterType: {
|
||||
type: String,
|
||||
default: ''
|
||||
@ -53,6 +69,10 @@ const props = defineProps({
|
||||
type: Object,
|
||||
default: {}
|
||||
},
|
||||
copyUrl: { // 例 "/wap/addon/shop_fenxiao/pages/goods"
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
copyUrlParam: {
|
||||
type: String,
|
||||
default: ''
|
||||
@ -60,11 +80,14 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
let sharePopupShow = ref(false);
|
||||
/************** 分享海报-start *******************/
|
||||
|
||||
// 复制
|
||||
const copyUrl = () => {
|
||||
let data = ''
|
||||
data = location.origin + location.pathname + props.copyUrlParam;
|
||||
if(props.copyUrl)
|
||||
data = location.origin + props.copyUrl + props.copyUrlParam;
|
||||
else
|
||||
data = location.origin + location.pathname + props.copyUrlParam;
|
||||
copy(data, () => {
|
||||
sharePopupShow.value = false;
|
||||
});
|
||||
@ -84,9 +107,10 @@ const goodsPosterShowFn = () => {
|
||||
isPosterAnimation.value = true;
|
||||
isPosterImg.value = false;
|
||||
let obj = {
|
||||
type: props.posterType,
|
||||
param: props.posterParam
|
||||
}
|
||||
id: props.posterId,
|
||||
type: props.posterType,
|
||||
param: props.posterParam
|
||||
}
|
||||
let startTime = Date.parse(new Date());
|
||||
getPoster(obj).then((res:any) => {
|
||||
poster.value = res.data && img(res.data) || '';
|
||||
@ -107,6 +131,11 @@ const goodsPosterShowFn = () => {
|
||||
sharePopuClose();
|
||||
})
|
||||
}
|
||||
let show = ref(false);
|
||||
|
||||
const closeDialog = ()=> {
|
||||
show.value = false;
|
||||
}
|
||||
|
||||
// #ifdef MP || APP-PLUS
|
||||
//小程序中保存海报
|
||||
@ -125,17 +154,25 @@ const saveGoodsPoster = () => {
|
||||
});
|
||||
},
|
||||
fail: (err) => {
|
||||
uni.showToast({
|
||||
title: '保存失败,请稍后重试',
|
||||
icon: 'none'
|
||||
});
|
||||
if(err.errno == 104){
|
||||
let msg = '用户未授权隐私权限,将图像保存到相册失败';
|
||||
uni.showToast({title: msg, icon: 'none'})
|
||||
}else if (err.errMsg == "saveImageToPhotosAlbum:fail auth deny" ||
|
||||
err.errMsg == "saveImageToPhotosAlbum:fail:auth denied") {
|
||||
show.value = true;
|
||||
}else if(err.errMsg == "saveImageToPhotosAlbum:fail cancel"){
|
||||
let msg = '用户取消将图片保存到相册';
|
||||
uni.showToast({title: msg, icon: 'none'})
|
||||
}else{
|
||||
uni.showToast({title: err.errMsg, icon: 'none'})
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
uni.showToast({
|
||||
title: '保存失败,请稍后重试',
|
||||
title: err.errMsg,
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
@ -144,6 +181,17 @@ const saveGoodsPoster = () => {
|
||||
// #endif
|
||||
|
||||
|
||||
let shareTop = ref(0)
|
||||
/************ 获取微信头部-start ****************/
|
||||
// 获取系统状态栏的高度
|
||||
let menuButtonInfo = {};
|
||||
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API,尚未兼容)
|
||||
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
|
||||
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
||||
shareTop.value = menuButtonInfo.top + menuButtonInfo.height + 'px';
|
||||
// #endif
|
||||
/************ 获取微信头部-end ****************/
|
||||
|
||||
const sharePopuClose = ()=>{
|
||||
sharePopupShow.value = false;
|
||||
isPosterAnimation.value = false;
|
||||
@ -154,18 +202,16 @@ const sharePopuClose = ()=>{
|
||||
defineExpose({
|
||||
openShare
|
||||
})
|
||||
/************** 分享海报-end *******************/
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.share-popup {
|
||||
:deep(.u-transition), :deep(.u-popup__content){
|
||||
background-color: transparent;
|
||||
}
|
||||
.share-content {
|
||||
border-top-left-radius: 20rpx;
|
||||
border-top-right-radius: 20rpx;
|
||||
border-top-left-radius: 40rpx;
|
||||
border-top-right-radius: 40rpx;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
display: -webkit-flex;
|
||||
@ -191,7 +237,7 @@ defineExpose({
|
||||
|
||||
text {
|
||||
margin-top: 20rpx;
|
||||
font-size: 28rpx;
|
||||
font-size: 24rpx;
|
||||
display: block;
|
||||
color: #333;
|
||||
}
|
||||
@ -216,37 +262,85 @@ defineExpose({
|
||||
line-height: 90rpx;
|
||||
border-top: 2rpx solid #eee;
|
||||
text-align: center;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
}
|
||||
.poster-animation{
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
top: -74vh;
|
||||
width: 542rpx;
|
||||
height: 960rpx;
|
||||
}
|
||||
.poster-img{
|
||||
position: absolute;
|
||||
top: -74vh;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
|
||||
.poster-img-wrap{
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: calc(constant(safe-area-inset-bottom) + 300rpx); //300是海报弹窗下面高度的问题
|
||||
bottom: calc(env(safe-area-inset-bottom) + 300rpx);
|
||||
right: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
image{
|
||||
width: 600rpx;
|
||||
height: 960rpx;
|
||||
.poster-img{
|
||||
width: 80%;
|
||||
height: 80%;
|
||||
}
|
||||
.save-btn{
|
||||
.poster-animation{
|
||||
width: 60%;
|
||||
height: 65%;
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-popup {
|
||||
width: 580rpx;
|
||||
background: #fff;
|
||||
box-sizing: border-box;
|
||||
border-radius: 10rpx;
|
||||
overflow: hidden;
|
||||
height: initial;
|
||||
|
||||
.title {
|
||||
padding: 30rpx 30rpx 0 30rpx;
|
||||
text-align: center;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
background-color: var(--primary-color);
|
||||
border-radius: 10rpx;
|
||||
width: 90%;
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.message {
|
||||
padding: 0 30rpx;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
line-height: 1.3;
|
||||
margin-top: 30rpx;
|
||||
}
|
||||
|
||||
.action-wrap {
|
||||
margin-top: 50rpx;
|
||||
height: 80rpx;
|
||||
display: flex;
|
||||
border-top: 2rpx solid #eee;
|
||||
|
||||
&>view {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
line-height: 80rpx;
|
||||
|
||||
&:first-child {
|
||||
border-right: 2rpx solid #eee;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
button {
|
||||
border: none;
|
||||
line-height: 80rpx;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.authorization-btn{
|
||||
background-color: #07c160;
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -19,7 +19,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { redirect, currRoute, img } from '@/utils/common'
|
||||
import { redirect, currRoute,currShareRoute, img } from '@/utils/common'
|
||||
import useConfigStore from '@/stores/config'
|
||||
|
||||
const props = defineProps({
|
||||
@ -35,11 +35,16 @@
|
||||
}
|
||||
|
||||
const tabbar = computed(() => {
|
||||
return useConfigStore().tabbar
|
||||
return useConfigStore().tabbar
|
||||
})
|
||||
|
||||
const value = computed(() => {
|
||||
return '/' + currRoute()
|
||||
let query:any = currShareRoute().params;
|
||||
let str = [];
|
||||
for (let key in query) {
|
||||
str.push(key + '=' + query[key]);
|
||||
}
|
||||
return '/' + currRoute() + (str.length > 0 ? '?' + str.join('&') : '')
|
||||
})
|
||||
|
||||
const tabbarChange = (url : string) => {
|
||||
@ -60,6 +65,15 @@
|
||||
redirect({ url,mode: 'reLaunch' })
|
||||
}
|
||||
}
|
||||
|
||||
const setAddon = (addon:any)=> {
|
||||
const configStore = useConfigStore()
|
||||
configStore.getTabbarConfig(addon)
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
setAddon
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@ -1,12 +1,59 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view class="flex items-center justify-center fixed left-0 right-0 z-10 bg-[#fff]" :style="navbarInnerStyle">
|
||||
<text v-if="props.param.isShowArrow" class="iconfont iconjiantou3 absolute" :style="navbarInnerArrowStyle" @click="goback()"></text>
|
||||
<text class="truncate" :style="{color:props.param.titleColor}">{{props.title}}</text>
|
||||
<!-- diyStore.mode !='decorate' && topStatusBarData topStatusBarData.style == 'style-5 为了兼容风格五 -->
|
||||
<view class="ns-navbar-wrap" v-if="diyStore.mode !='decorate' && topStatusBarData || diyStore.mode =='decorate' && topStatusBarData && topStatusBarData.style == 'style-5' " :class="topStatusBarData.style">
|
||||
<view class="u-navbar" :style="{ backgroundColor: bgColor}">
|
||||
<view class="navbar-inner" :style="{ width: '100%', height: placeholderHeight + 'px' }">
|
||||
<view v-if="topStatusBarData.style == 'style-1'" class="content-wrap" :class="[topStatusBarData.textAlign]" :style="navbarInnerStyle">
|
||||
<view v-if="isBack && isBackShow" class="back-wrap iconfont iconjiantou3" :style="{ color: topStatusBarData.textColor || titleColor }" @tap="goBack"></view>
|
||||
<view class="title-wrap" :style="styleOneFontSize">
|
||||
{{ data.title }}
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="topStatusBarData.style == 'style-2'" class="content-wrap" :style="navbarInnerStyle" @click="toRedirect(topStatusBarData.link)">
|
||||
<view v-if="isBack && isBackShow" class="back-wrap iconfont iconjiantou3" :style="{ color: topStatusBarData.textColor || titleColor }" @tap="goBack"></view>
|
||||
<view class="title-wrap" :style="{ color: topStatusBarData.textColor }">
|
||||
<view>
|
||||
<image :src="img(topStatusBarData.imgUrl)" mode="heightFix"></image>
|
||||
</view>
|
||||
<view :style="{ color: topStatusBarData.textColor }">{{ data.title }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="topStatusBarData.style == 'style-3'" :style="navbarInnerStyle" class="content-wrap">
|
||||
<view v-if="isBack && isBackShow" class="back-wrap iconfont iconjiantou3" :style="{ color: topStatusBarData.textColor || titleColor }" @tap="goBack"></view>
|
||||
<view class="title-wrap" @click="toRedirect(topStatusBarData.link)">
|
||||
<image :src="img(topStatusBarData.imgUrl)" mode="heightFix"></image>
|
||||
</view>
|
||||
<view class="search" @click="toRedirect(topStatusBarData.link)" :style="{ height: menuButtonInfo.height - 2 + 'px', lineHeight: menuButtonInfo.height - 2 + 'px' }">
|
||||
<text class="iconfont iconsousuo absolute left-[20rpx]"></text>
|
||||
<text class="text-[28rpx]">{{topStatusBarData.inputPlaceholder}}</text>
|
||||
</view>
|
||||
<view :style="{ 'width': capsuleWidth }"></view>
|
||||
</view>
|
||||
|
||||
<view v-if="topStatusBarData.style == 'style-4'" :style="navbarInnerStyle" class="content-wrap">
|
||||
<view v-if="isBack && isBackShow" class="back-wrap iconfont iconjiantou3" :style="{ color: topStatusBarData.textColor || titleColor }" @tap="goBack"></view>
|
||||
<text class="iconfont iconxiazai19 text-[28rpx]" :style="{ color: topStatusBarData.textColor }"></text>
|
||||
<view class="title-wrap" @click="reposition()" :style="{ color: topStatusBarData.textColor }">{{ currentPosition }}</view>
|
||||
<text class="iconfont iconxiangyoujiantou text-[24rpx]" @click="reposition()" :style="{ color: topStatusBarData.textColor }"></text>
|
||||
</view>
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view v-if="topStatusBarData.style == 'style-5'" class="content-wrap" :style="navbarInnerStyle">
|
||||
<view v-if="isBack && isBackShow" class="back-wrap iconfont iconjiantou3" :style="{ color: topStatusBarData.textColor || titleColor }" @tap="goBack"></view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 风格5,填充 -->
|
||||
<view v-if="topStatusBarData.style == 'style-5'" :style="style5Height"></view>
|
||||
|
||||
<!-- 解决fixed定位后导航栏塌陷的问题 -->
|
||||
<view :style="navbarInnerStyle"></view>
|
||||
<view class="u-navbar-placeholder" :style="{ width: '100%', paddingTop: placeholderHeight + 'px' }"></view>
|
||||
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<!-- 小程序隐私协议 -->
|
||||
<wx-privacy-popup ref="wxPrivacyPopup"></wx-privacy-popup>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</template>
|
||||
@ -21,38 +68,80 @@ let menuButtonInfo = {};
|
||||
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
||||
// #endif
|
||||
|
||||
import { ref, reactive, computed } from 'vue';
|
||||
import { redirect } from '@/utils/common';
|
||||
import { ref, computed, watch, onMounted, getCurrentInstance, nextTick } from 'vue';
|
||||
import { img, redirect, getLocation, locationStorage, getToken, currRoute, diyRedirect } from '@/utils/common';
|
||||
import { getAddressByLatlng } from '@/app/api/system';
|
||||
import useSystemStore from '@/stores/system';
|
||||
import { useLogin } from '@/hooks/useLogin';
|
||||
import useDiyStore from '@/app/stores/diy';
|
||||
import manifestJson from '@/manifest.json'
|
||||
const diyStore = useDiyStore();
|
||||
|
||||
// param是一个对象{arrowLink => 箭头链接,isShowArrow => 箭头是否显示,tabbarBg => 背景颜色}
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: '首页'
|
||||
},
|
||||
param: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: {
|
||||
arrowLink: '',
|
||||
isShowArrow: false,
|
||||
arrowColor:'#000',
|
||||
titleColor:'#000',
|
||||
tabbarBg: '#fff'
|
||||
}
|
||||
default: {}
|
||||
},
|
||||
// 标题的颜色
|
||||
titleColor: {
|
||||
type: String,
|
||||
default: '#606266'
|
||||
},
|
||||
// 自定义返回逻辑
|
||||
customBack: {
|
||||
type: Function,
|
||||
default: null
|
||||
},
|
||||
scrollTop: {
|
||||
type: [String, Number],
|
||||
default: '0'
|
||||
},
|
||||
// 是否显示导航栏左边返回图标和辅助文字
|
||||
isBack: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
})
|
||||
|
||||
const data = computed(() => {
|
||||
return props.data;
|
||||
});
|
||||
const topStatusBarData = computed(() => {
|
||||
if(props.data && props.data.topStatusBar)
|
||||
return props.data.topStatusBar;
|
||||
});
|
||||
|
||||
// 导航栏内部盒子的样式
|
||||
const navbarInnerStyle = computed(() => {
|
||||
let style = '';
|
||||
// 导航栏宽度,如果在小程序下,导航栏宽度为胶囊的左边到屏幕左边的距离
|
||||
|
||||
if(props.isBack && isBackShow.value){
|
||||
style += 'padding-left: 30rpx;';//30=>右边留边 44=>箭头宽度 10=>箭头的右maring
|
||||
if(topStatusBarData.value.style == 'style-1') //样式一需要居中需要有右边padding辅助
|
||||
style += 'padding-right:' + (40+30+10) + 'rpx;'; //30=>左边留边 44=>箭头宽度 10=>箭头的右maring
|
||||
}else{
|
||||
if(topStatusBarData.value.style == 'style-1') //样式一需要居中需要有右边padding辅助
|
||||
style += 'padding-right: 30rpx;'; //右边留边
|
||||
style += 'padding-left: 30rpx;'; //左边留边
|
||||
}
|
||||
// #ifdef MP
|
||||
let rightButtonWidth = menuButtonInfo.width ? menuButtonInfo.width * 2 + 'rpx' : '70rpx';
|
||||
// 导航栏宽度,如果在小程序下,导航栏宽度为胶囊的左边到屏幕左边的距离
|
||||
style += 'height:' + menuButtonInfo.height + 'px;';
|
||||
style += 'padding-right:calc(' + rightButtonWidth + ' + 30rpx);';
|
||||
style += 'padding-left:calc(' + rightButtonWidth + ' + 30rpx);';
|
||||
style += 'padding-top:' + menuButtonInfo.top + 'px;';
|
||||
style += 'padding-bottom: 8px;';
|
||||
style += 'background:'+ props.param.tabbarBg +';';
|
||||
// #endif
|
||||
return style;
|
||||
})
|
||||
|
||||
// 样式一的字体大小
|
||||
const styleOneFontSize = computed(() => {
|
||||
let style = '';
|
||||
|
||||
// #ifdef H5
|
||||
style += 'font-size: 28rpx;';
|
||||
// #endif
|
||||
// #ifdef MP
|
||||
style += 'font-size: 32rpx;';
|
||||
if (platform === 'ios') {
|
||||
// 苹果(iOS)设备
|
||||
@ -62,42 +151,389 @@ const navbarInnerStyle = computed(() => {
|
||||
style += 'font-size: 36rpx;';
|
||||
}
|
||||
// #endif
|
||||
return style;
|
||||
})
|
||||
|
||||
// 导航栏内部盒子的样式
|
||||
const navbarInnerArrowStyle = computed(() => {
|
||||
let style = '';
|
||||
// 导航栏宽度,如果在小程序下,导航栏宽度为胶囊的左边到屏幕左边的距离
|
||||
// #ifdef MP
|
||||
style += "padding-left: 10rpx;" //1、增加点击面积,2、增加间距
|
||||
style += "padding-right: 10rpx;" //1、增加点击面积
|
||||
style += 'left:calc( 100vw - ' + menuButtonInfo.right + 'px);';
|
||||
style += 'font-size: 32rpx;';
|
||||
style += 'font-weight: bold;';
|
||||
style += 'color:'+ props.param.arrowColor +';';
|
||||
if (platform === 'ios') {
|
||||
// 苹果(iOS)设备
|
||||
style += 'font-weight: 700;';
|
||||
} else if (platform === 'android') {
|
||||
// 安卓(Android)设备
|
||||
|
||||
style += `color: ${topStatusBarData.value.textColor};`;
|
||||
if(topStatusBarData.value.style == 'style-1'){
|
||||
style += `text-align: ${topStatusBarData.value.textAlign};`;
|
||||
}
|
||||
// #endif
|
||||
return style;
|
||||
})
|
||||
|
||||
// 返回上一页
|
||||
const goback=()=> {
|
||||
if(!props.param.arrowLink){
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
});
|
||||
}else{
|
||||
redirect({ url: props.param.arrowLink, mode : 'redirectTo' })
|
||||
const bgColor = computed(() => {
|
||||
var color = '';
|
||||
if (topStatusBarData.value.isTransparent) {
|
||||
// 顶部透明
|
||||
color = 'transparent';
|
||||
let top = 1;
|
||||
if (props.scrollTop > top) {
|
||||
color = topStatusBarData.value.bgColor;
|
||||
} else {
|
||||
color = 'transparent';
|
||||
}
|
||||
} else {
|
||||
color = topStatusBarData.value.bgColor;
|
||||
}
|
||||
|
||||
return color;
|
||||
})
|
||||
|
||||
/******************************* 返回按钮-start ***********************/
|
||||
let isBackShow = ref(false);
|
||||
let pages = getCurrentPages();
|
||||
|
||||
// 返回按钮的函数
|
||||
const goBack = () => {
|
||||
// 如果自定义了点击返回按钮的函数,则执行,否则执行返回逻辑
|
||||
if (typeof props.customBack === 'function') {
|
||||
props.customBack();
|
||||
} else {
|
||||
uni.navigateBack();
|
||||
}
|
||||
}
|
||||
/******************************* 返回按钮-end ***********************/
|
||||
|
||||
// 微信胶囊宽度+right
|
||||
const capsuleWidth = computed(() => {
|
||||
let width = `calc(100vw - ${menuButtonInfo.right}px + ${menuButtonInfo.width}px + 10px)`;
|
||||
return width;
|
||||
})
|
||||
|
||||
// 导航栏塌陷的高度
|
||||
let placeholderHeight = ref(0);
|
||||
const instance = getCurrentInstance();
|
||||
const navbarPlaceholderHeight = () => {
|
||||
nextTick(() => {
|
||||
const query = uni.createSelectorQuery().in(instance);
|
||||
query.select('.ns-navbar-wrap .u-navbar .content-wrap').boundingClientRect(data => {
|
||||
placeholderHeight.value = data ? data.height : 0;
|
||||
diyStore.topTabarHeight = placeholderHeight.value;
|
||||
}).exec();
|
||||
})
|
||||
}
|
||||
|
||||
// 跳转链接
|
||||
const toRedirect = (data: {}) => {
|
||||
if (Object.keys(data).length) {
|
||||
if (!data.url) return;
|
||||
if (currRoute() == 'app/pages/member/index' && !getToken()) {
|
||||
useLogin().setLoginBack({ url: data.url })
|
||||
return;
|
||||
}
|
||||
diyRedirect(data);
|
||||
} else {
|
||||
redirect(data)
|
||||
}
|
||||
}
|
||||
|
||||
/******************************* 定位-start ***********************/
|
||||
// 获取地图配置
|
||||
const systemStore = useSystemStore();
|
||||
let currentPosition = ref('定位中...')
|
||||
let mapConfig = uni.getStorageSync('mapConfig');
|
||||
|
||||
const initPosition = () =>{
|
||||
// #ifdef H5
|
||||
if (getQueryVariable('latng')) {
|
||||
currentPosition.value = "定位中..."
|
||||
let locationInfo = systemStore.location;
|
||||
var tempArr = getQueryVariable('latng').split(',');
|
||||
locationInfo.latitude = tempArr[0];
|
||||
locationInfo.longitude = tempArr[1];
|
||||
systemStore.setLocation(locationInfo);
|
||||
}
|
||||
// #endif
|
||||
currentPosition.value = '定位中...';
|
||||
if(uni.getStorageSync('addressByLatlng')){
|
||||
currentPosition.value = uni.getStorageSync('addressByLatlng').formatted_addresses.recommend;
|
||||
}
|
||||
// 定位信息过期后,重新获取定位
|
||||
if(mapConfig.is_open == 1 && locationStorage() && locationStorage().is_expired) {
|
||||
getLocation({
|
||||
fail: (res) => {
|
||||
// 拒绝定位,进入默认总店
|
||||
currentPosition.value = "定位中..."
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
watch(() => systemStore.location, (nval, oval)=> {
|
||||
if (nval.latitude && nval.longitude) {
|
||||
getAddressByLatlngFn()
|
||||
}else{
|
||||
currentPosition.value = "定位中..."
|
||||
}
|
||||
},{deep:true})
|
||||
|
||||
// 根据经纬度获取位置
|
||||
const getAddressByLatlngFn = () => {
|
||||
let data = {
|
||||
latlng: ''
|
||||
};
|
||||
data.latlng = systemStore.location.latitude + ',' + systemStore.location.longitude ;
|
||||
getAddressByLatlng(data).then((res: any) => {
|
||||
if (res.data && Object.keys(res.data).length) {
|
||||
currentPosition.value = res.data.formatted_addresses.recommend; // 结合知名地点形成的描述性地址,更具人性化特点
|
||||
uni.setStorageSync('addressByLatlng', res.data);
|
||||
} else {
|
||||
currentPosition.value = '定位中...';
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 打开地图重新选择位置
|
||||
const reposition = () => {
|
||||
// #ifdef MP
|
||||
uni.chooseLocation({
|
||||
success: (res) => {
|
||||
var urlencode = JSON.parse(JSON.stringify(systemStore.location));
|
||||
urlencode = Object.assign(urlencode,res)
|
||||
systemStore.setLocation(urlencode);
|
||||
},
|
||||
fail: (res)=>{
|
||||
// 在隐私协议中没有声明chooseLocation:fail api作用域
|
||||
if(res.errMsg && res.errno) {
|
||||
if(res.errno == 104){
|
||||
let msg = '用户未授权隐私权限,选择位置失败';
|
||||
uni.showToast({title: msg, icon: 'none'})
|
||||
}else if(res.errno == 112){
|
||||
let msg = '隐私协议中未声明,打开地图选择位置失败';
|
||||
uni.showToast({title: msg, icon: 'none'})
|
||||
}else {
|
||||
uni.showToast({title: res.errMsg, icon: 'none'})
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
let backurl = location.origin + location.pathname;
|
||||
window.location.href = 'https://apis.map.qq.com/tools/locpicker?search=1&type=0&backurl=' + encodeURIComponent(backurl) + '&key=' + manifestJson.h5.sdkConfigs.maps.qqmap.key + '&referer=myapp';
|
||||
// #endif
|
||||
}
|
||||
|
||||
const getQueryVariable = (variable:any)=> {
|
||||
var query = window.location.search.substring(1);
|
||||
var vars = query.split('&');
|
||||
for (var i = 0; i < vars.length; i++) {
|
||||
var pair = vars[i].split('=');
|
||||
if (pair[0] == variable) {
|
||||
return pair[1];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/******************************* 定位-end ***********************/
|
||||
|
||||
/******************************* 风格五-start ***********************/
|
||||
let style5Height = ref('')
|
||||
watch(() => topStatusBarData.value.style, (nval, oval)=> {
|
||||
if(topStatusBarData.value.style == 'style-5'){
|
||||
style5Height.value = '';
|
||||
let sysWidth = systemInfo.windowWidth
|
||||
let sysHeight =sysWidth / data.value.imgWidth * data.value.imgHeight
|
||||
style5Height.value += `width:100%;`
|
||||
// #ifdef H5
|
||||
sysHeight = sysHeight - 88; //使用图片高度减去88
|
||||
style5Height.value += `padding-top:${sysHeight}px;`
|
||||
style5Height.value += `height:0;` //h5需要去掉兼容微信胶囊的高度
|
||||
// #endif
|
||||
// #ifdef MP
|
||||
sysHeight = sysHeight - menuButtonInfo.top - menuButtonInfo.height - 5; //图片高度减去兼容小程序头部的高度[胶囊高度、padding-bottom、padding-top]
|
||||
style5Height.value += `padding-top:${sysHeight}px;`
|
||||
// #endif
|
||||
}
|
||||
},{immediate: true, deep:true})
|
||||
/******************************* 风格五-end ***********************/
|
||||
|
||||
onMounted(() => {
|
||||
navbarPlaceholderHeight();
|
||||
if (pages.length > 1) {
|
||||
isBackShow.value = true;
|
||||
}
|
||||
if(topStatusBarData.value && topStatusBarData.value.style == 'style-4') {
|
||||
initPosition();
|
||||
}
|
||||
});
|
||||
|
||||
// 页面onShow调用时,也会触发改方法
|
||||
const refresh = ()=>{
|
||||
if(topStatusBarData.value && topStatusBarData.value.style == 'style-4') {
|
||||
initPosition();
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
refresh
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
/* #ifdef H5 */
|
||||
.style-1,
|
||||
.style-2,
|
||||
.style-3 {
|
||||
display: none;
|
||||
}
|
||||
/* #endif */
|
||||
|
||||
.u-navbar {
|
||||
width: 100%;
|
||||
transition: background 0.3s;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
z-index: 991;
|
||||
}
|
||||
|
||||
.navbar-inner {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
// padding-bottom: 20rpx;
|
||||
// /* #ifdef H5 */
|
||||
// padding-bottom: 40rpx;
|
||||
// /* #endif */
|
||||
}
|
||||
|
||||
.back-wrap {
|
||||
padding-right: 10rpx;
|
||||
line-height: 1;
|
||||
.iconfont {
|
||||
font-size: 40rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.content-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
flex: 1;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: 60rpx;
|
||||
text-align: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.title-wrap {
|
||||
line-height: 1;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 32rpx;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.ns-navbar-wrap {
|
||||
|
||||
&.style-2 {
|
||||
.content-wrap {
|
||||
.title-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-align: left;
|
||||
|
||||
>view {
|
||||
height: 56rpx;
|
||||
line-height: 56rpx;
|
||||
max-width: 300rpx;
|
||||
font-size: 28rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
max-width: 300rpx;
|
||||
overflow: hidden; //超出的文本隐藏
|
||||
text-overflow: ellipsis; //用省略号显示
|
||||
white-space: nowrap; //不换行
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.style-3 {
|
||||
.content-wrap {
|
||||
.title-wrap {
|
||||
height: 60rpx;
|
||||
max-width: 170rpx;
|
||||
flex: initial;
|
||||
text-align: center;
|
||||
margin-right: 10rpx;
|
||||
|
||||
image {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.search {
|
||||
flex: 1;
|
||||
padding-right: 20rpx;
|
||||
padding-left: 62rpx;
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
text-align: left;
|
||||
border-radius: 60rpx;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
border: 1px solid #eeeeee;
|
||||
color: rgb(102, 102, 102);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 10rpx;
|
||||
overflow: hidden;
|
||||
text{
|
||||
overflow: hidden; //超出的文本隐藏
|
||||
text-overflow: ellipsis; //用省略号显示
|
||||
white-space: nowrap; //不换行
|
||||
}
|
||||
.iconfont {
|
||||
color: #909399;
|
||||
font-size: 32rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.style-4 {
|
||||
.content-wrap {
|
||||
top: 0;
|
||||
text-align: left;
|
||||
padding-left: 30rpx;
|
||||
/* #ifdef H5 */
|
||||
padding-top: 10rpx;
|
||||
padding-bottom: 10rpx;
|
||||
/* #endif */
|
||||
|
||||
.title-wrap {
|
||||
flex: none;
|
||||
margin: 0 10rpx;
|
||||
max-width: 360rpx;
|
||||
font-size: 27rpx;
|
||||
}
|
||||
|
||||
.nearby-store-name {
|
||||
margin: 0 10rpx;
|
||||
background: rgba(0, 0, 0, .2);
|
||||
font-size: 22rpx;
|
||||
border-radius: 40rpx;
|
||||
padding: 10rpx 20rpx;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,14 +1,19 @@
|
||||
import { ref, reactive, computed } from 'vue';
|
||||
import { onLoad, onShow, onPullDownRefresh, onPageScroll } from '@dcloudio/uni-app';
|
||||
import { getDiyInfo } from '@/app/api/diy';
|
||||
import {ref, reactive, computed} from 'vue';
|
||||
import {onLoad, onShow, onPullDownRefresh, onPageScroll} from '@dcloudio/uni-app';
|
||||
import {img, handleOnloadParams} from '@/utils/common';
|
||||
import {getDiyInfo} from '@/app/api/diy';
|
||||
import useDiyStore from '@/app/stores/diy';
|
||||
import { useShare } from '@/hooks/useShare'
|
||||
|
||||
export function useDiy() {
|
||||
export function useDiy(params: any = {}) {
|
||||
|
||||
const loading = ref(true);
|
||||
const diyStore = useDiyStore();
|
||||
const pullDownRefreshCount = ref(0)
|
||||
|
||||
const id = ref(0)
|
||||
const name = ref(params.name || '')
|
||||
const template = ref('')
|
||||
|
||||
// 自定义页面 数据
|
||||
const diyData = reactive({
|
||||
pageMode: 'diy',
|
||||
@ -17,69 +22,151 @@ export function useDiy() {
|
||||
value: []
|
||||
})
|
||||
|
||||
const diyStore = useDiyStore();
|
||||
const getLoading = () => {
|
||||
return loading.value;
|
||||
}
|
||||
|
||||
const { setShare } = useShare()
|
||||
|
||||
const id = ref(0)
|
||||
const name = ref('')
|
||||
|
||||
const onShowLifeCycle = async () => {
|
||||
|
||||
console.log('on show life cycle',{
|
||||
id: id.value,
|
||||
name: name.value
|
||||
})
|
||||
|
||||
// 装修模式
|
||||
const data = computed(() => {
|
||||
if (diyStore.mode == 'decorate') {
|
||||
diyStore.init();
|
||||
return diyStore;
|
||||
} else {
|
||||
getDiyInfo({
|
||||
id: id.value,
|
||||
name: name.value
|
||||
}).then((res : any) => {
|
||||
if (res.data.value) {
|
||||
let data = res.data;
|
||||
diyData.pageMode = data.mode;
|
||||
diyData.title = data.title;
|
||||
|
||||
let sources = JSON.parse(data.value);
|
||||
diyData.global = sources.global;
|
||||
diyData.value = sources.value;
|
||||
diyData.value.forEach((item, index) => {
|
||||
item.pageStyle = '';
|
||||
if(item.pageStartBgColor) {
|
||||
if (item.pageStartBgColor && item.pageEndBgColor) item.pageStyle += `background:linear-gradient(${item.pageGradientAngle},${item.pageStartBgColor},${item.pageEndBgColor});`;
|
||||
else item.pageStyle += 'background-color:' + item.pageStartBgColor + ';';
|
||||
}
|
||||
|
||||
if (item.margin) {
|
||||
item.pageStyle += 'padding-top:' + item.margin.top * 2 + 'rpx' + ';';
|
||||
item.pageStyle += 'padding-bottom:' + item.margin.bottom * 2 + 'rpx' + ';';
|
||||
item.pageStyle += 'padding-right:' + item.margin.both * 2 + 'rpx' + ';';
|
||||
item.pageStyle += 'padding-left:' + item.margin.both * 2 + 'rpx' + ';';
|
||||
}
|
||||
});
|
||||
uni.setNavigationBarTitle({
|
||||
title: diyData.title
|
||||
})
|
||||
}
|
||||
|
||||
let share = res.data.share ? JSON.parse(res.data.share) : null;
|
||||
setShare(share);
|
||||
|
||||
loading.value = false;
|
||||
});
|
||||
return diyData;
|
||||
}
|
||||
})
|
||||
|
||||
const isShowTopTabbar = ref(false);
|
||||
|
||||
const pageStyle = () => {
|
||||
var style = '';
|
||||
if (data.value.global.pageStartBgColor) {
|
||||
if (data.value.global.pageStartBgColor && data.value.global.pageEndBgColor) style += `background:linear-gradient(${data.value.global.pageGradientAngle},${data.value.global.pageStartBgColor},${data.value.global.pageEndBgColor});`;
|
||||
else style += 'background-color:' + data.value.global.pageStartBgColor + ';';
|
||||
}
|
||||
|
||||
style += 'min-height:calc(100vh - 50px);';
|
||||
if (data.value.global.bgUrl) {
|
||||
style += `background-image:url('${img(data.value.global.bgUrl)}');`;
|
||||
}
|
||||
|
||||
if (data.value.global.bgHeightScale) {
|
||||
style += `background-size: 100% ${data.value.global.bgHeightScale}%;`;
|
||||
}
|
||||
|
||||
// #ifdef H5
|
||||
// 导航栏风格五 - 兼容
|
||||
if(data.value.global && data.value.global.topStatusBar && data.value.global.topStatusBar.style == "style-5"){
|
||||
style += `background-position-y: -176rpx;`;
|
||||
}
|
||||
// #endif
|
||||
return style;
|
||||
};
|
||||
|
||||
// 监听页面加载
|
||||
const onLoadLifeCycle = () => {
|
||||
onLoad((option: any) => {
|
||||
// #ifdef MP-WEIXIN
|
||||
// 处理小程序场景值参数
|
||||
option = handleOnloadParams(option);
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
// 装修模式
|
||||
diyStore.mode = option.mode || '';
|
||||
if (diyStore.mode == 'decorate') {
|
||||
loading.value = false;
|
||||
}
|
||||
// #endif
|
||||
|
||||
id.value = option.id || '';
|
||||
if (name.value == '') name.value = option.name || '';
|
||||
template.value = option.template || '';
|
||||
});
|
||||
}
|
||||
|
||||
// 监听页面显示
|
||||
const onShowLifeCycle = (callback: any = null) => {
|
||||
onShow(() => {
|
||||
// 装修模式
|
||||
if (diyStore.mode == 'decorate') {
|
||||
diyStore.init();
|
||||
} else {
|
||||
getDiyInfo({
|
||||
id: id.value,
|
||||
name: name.value,
|
||||
template: template.value
|
||||
}).then((res: any) => {
|
||||
let requestData = res.data;
|
||||
if (requestData.value) {
|
||||
diyData.pageMode = requestData.mode;
|
||||
diyData.title = requestData.title;
|
||||
|
||||
let sources = JSON.parse(requestData.value);
|
||||
diyData.global = sources.global;
|
||||
diyData.value = sources.value;
|
||||
diyData.value.forEach((item: any, index) => {
|
||||
item.pageStyle = '';
|
||||
if (item.pageStartBgColor) {
|
||||
if (item.pageStartBgColor && item.pageEndBgColor) item.pageStyle += `background:linear-gradient(${item.pageGradientAngle},${item.pageStartBgColor},${item.pageEndBgColor});`;
|
||||
else item.pageStyle += 'background-color:' + item.pageStartBgColor + ';';
|
||||
}
|
||||
|
||||
if (item.margin) {
|
||||
if (item.margin.top > 0) {
|
||||
item.pageStyle += 'padding-top:' + item.margin.top * 2 + 'rpx' + ';';
|
||||
}
|
||||
item.pageStyle += 'padding-bottom:' + item.margin.bottom * 2 + 'rpx' + ';';
|
||||
item.pageStyle += 'padding-right:' + item.margin.both * 2 + 'rpx' + ';';
|
||||
item.pageStyle += 'padding-left:' + item.margin.both * 2 + 'rpx' + ';';
|
||||
}
|
||||
});
|
||||
|
||||
// 控制自定义头部是否出现 | 微信小程序
|
||||
isShowTopTabbar.value = diyData.value.some((item) => {
|
||||
return item && item.position && item.position == 'top_fixed'
|
||||
});
|
||||
|
||||
uni.setNavigationBarTitle({
|
||||
title: diyData.title
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
loading.value = false;
|
||||
|
||||
if (callback) callback(requestData)
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
// 监听下拉刷新事件
|
||||
const onPullDownRefreshLifeCycle = () => {
|
||||
onPullDownRefresh(() => {
|
||||
pullDownRefreshCount.value++;
|
||||
uni.stopPullDownRefresh();
|
||||
})
|
||||
}
|
||||
|
||||
// 监听滚动事件
|
||||
const onPageScrollLifeCycle = () => {
|
||||
onPageScroll((e) => {
|
||||
if (e.scrollTop > 0) {
|
||||
diyStore.scrollTop = e.scrollTop;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
id,
|
||||
name,
|
||||
loading,
|
||||
getLoading,
|
||||
pullDownRefreshCount,
|
||||
diyData,
|
||||
onShowLifeCycle
|
||||
data: data.value,
|
||||
isShowTopTabbar,
|
||||
pageStyle,
|
||||
onLoad: onLoadLifeCycle,
|
||||
onShow: onShowLifeCycle,
|
||||
onPullDownRefresh: onPullDownRefreshLifeCycle,
|
||||
onPageScroll: onPageScrollLifeCycle,
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,6 +67,7 @@ export function useLogin() {
|
||||
useMemberStore().setToken(res.data.token)
|
||||
} else {
|
||||
uni.setStorageSync('openid', res.data.openid)
|
||||
uni.setStorageSync('unionid', res.data.unionid)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -92,7 +93,7 @@ export function useLogin() {
|
||||
let query = urlDeconstruction(location.href).query
|
||||
query.code && (delete query.code)
|
||||
Object.keys(query).length && (url += uni.$u.queryParams(query))
|
||||
|
||||
|
||||
getWechatAuthCode({
|
||||
url,
|
||||
scopes
|
||||
|
||||
@ -2,7 +2,7 @@ import { img, isWeixinBrowser, currRoute, currShareRoute, getToken } from '@/uti
|
||||
import { onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'
|
||||
import { getShareInfo } from '@/app/api/diy';
|
||||
import useMemberStore from '@/stores/member'
|
||||
import { watch } from 'vue'
|
||||
import { watch,computed } from 'vue'
|
||||
|
||||
// #ifdef H5
|
||||
import wechat from '@/utils/wechat'
|
||||
@ -31,10 +31,18 @@ export const useShare = () => {
|
||||
|
||||
const setShare = async (options : any = {}) => {
|
||||
let memberStore = useMemberStore();
|
||||
let isWatch = uni.getStorageSync('isWatchShare');
|
||||
|
||||
watch(() => memberStore.info, () => {
|
||||
setShare(options)
|
||||
})
|
||||
// 防重复监听
|
||||
if(!isWatch) {
|
||||
watch(() => memberStore.info, (newValue: any, oldValue: any) => {
|
||||
// 如果会员发生变化,则请求分享接口
|
||||
if (newValue && oldValue && newValue.member_id != oldValue.member_id) {
|
||||
setShare(options)
|
||||
}
|
||||
})
|
||||
uni.setStorageSync('isWatchShare', true);
|
||||
}
|
||||
|
||||
// #ifdef H5
|
||||
// 初始化sdk
|
||||
@ -61,6 +69,11 @@ export const useShare = () => {
|
||||
desc: options.wechat.desc || '',
|
||||
imgUrl: options.wechat.url ? img(options.wechat.url) : ''
|
||||
}
|
||||
const userInfo = computed(() => memberStore.info)
|
||||
if(wechatOptions.link == ''){
|
||||
//分享首页拼接参数
|
||||
wechatOptions.link = location.href + '?mid=' + userInfo.value.member_id
|
||||
}
|
||||
wechatShare()
|
||||
// #endif
|
||||
|
||||
|
||||
@ -6,7 +6,8 @@ const t = (message: string) => {
|
||||
const route = currRoute()
|
||||
const file = language.getFileKey(`/${route}`)
|
||||
const key = `${file.fileKey}.${message}`
|
||||
return i18n.global.t(key) != key ? i18n.global.t(key) : i18n.global.t(message)
|
||||
if (i18n.global.t(message) != message) return i18n.global.t(message)
|
||||
return i18n.global.t(key) != key ? i18n.global.t(key) : ''
|
||||
}
|
||||
|
||||
export { language, t }
|
||||
|
||||
@ -17,6 +17,9 @@
|
||||
"pages.member.address_edit": "编辑收货地址",
|
||||
"pages.member.apply_cash_out": "申请提现",
|
||||
"pages.member.balance": "我的余额",
|
||||
"pages.member.point": "我的积分",
|
||||
"pages.member.level": "会员等级",
|
||||
"pages.member.sign_in": "我的签到",
|
||||
"pages.member.cash_out": "提现记录",
|
||||
"pages.member.cash_out_detail": "提现详情",
|
||||
"pages.member.commission": "我的佣金",
|
||||
@ -26,5 +29,9 @@
|
||||
"pages.pay.browser": "支付",
|
||||
"pages.pay.result": "支付结果",
|
||||
"pages.setting.index": "设置",
|
||||
"pages.verify.index": "核销台",
|
||||
"pages.verify.verify": "核销",
|
||||
"pages.verify.detail": "核销详情",
|
||||
"pages.verify.record": "核销记录",
|
||||
"pages.webview.index": ""
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name" : "",
|
||||
"appid" : "__UNI__FB0C409",
|
||||
"name" : "wx59e6ba6050bbe7bc",
|
||||
"appid" : "__UNI__ED923AB",
|
||||
"description" : "",
|
||||
"versionName" : "1.0.0",
|
||||
"versionCode" : "100",
|
||||
@ -84,10 +84,10 @@
|
||||
"mode" : "history",
|
||||
"base" : "/wap/"
|
||||
},
|
||||
"sdkConfigs": {
|
||||
"maps": {
|
||||
"qqmap": {
|
||||
"key": "IZQBZ-3UHEU-WTCVD-2464U-I5N4V-ZFFU3"
|
||||
"sdkConfigs" : {
|
||||
"maps" : {
|
||||
"qqmap" : {
|
||||
"key" : ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,6 +97,16 @@
|
||||
},
|
||||
"needLogin": true
|
||||
},
|
||||
{
|
||||
"path": "app/pages/member/level",
|
||||
"style": {
|
||||
// #ifndef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.member.level%"
|
||||
},
|
||||
"needLogin": true
|
||||
},
|
||||
{
|
||||
"path": "app/pages/member/detailed_account",
|
||||
"style": {
|
||||
@ -181,6 +191,16 @@
|
||||
},
|
||||
"needLogin": true
|
||||
},
|
||||
{
|
||||
"path": "app/pages/member/sign_in",
|
||||
"style": {
|
||||
// #ifndef H5
|
||||
"navigationStyle": "custom",
|
||||
// #endif
|
||||
"navigationBarTitleText": "%pages.member.sign_in%"
|
||||
},
|
||||
"needLogin": true
|
||||
},
|
||||
{
|
||||
"path": "app/pages/pay/browser",
|
||||
"style": {
|
||||
@ -211,6 +231,40 @@
|
||||
"style": {
|
||||
"navigationBarTitleText": "%pages.index.develop%"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "app/pages/verify/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "%pages.verify.index%"
|
||||
},
|
||||
"needLogin": true
|
||||
},
|
||||
{
|
||||
"path": "app/pages/verify/verify",
|
||||
"style": {
|
||||
"navigationBarTitleText": "%pages.verify.verify%"
|
||||
},
|
||||
"needLogin": true
|
||||
},
|
||||
{
|
||||
"path": "app/pages/verify/detail",
|
||||
"style": {
|
||||
"navigationBarTitleText": "%pages.verify.detail%"
|
||||
},
|
||||
"needLogin": true
|
||||
},
|
||||
{
|
||||
"path": "app/pages/verify/record",
|
||||
"style": {
|
||||
"navigationBarTitleText": "%pages.verify.record%"
|
||||
},
|
||||
"needLogin": true
|
||||
},
|
||||
{
|
||||
"path": "app/pages/weapp/order_shipping",
|
||||
"style": {
|
||||
"navigationBarTitleText": "%pages.weapp.order_shipping%"
|
||||
}
|
||||
}
|
||||
],
|
||||
"subPackages": [
|
||||
@ -218,7 +272,7 @@
|
||||
"root": "addon",
|
||||
"pages": [
|
||||
// {{ PAGE_BEGAIN }}
|
||||
// {{ PAGE_END }}}
|
||||
// {{ PAGE_END }}}
|
||||
{
|
||||
"path": "end"
|
||||
}
|
||||
@ -248,6 +302,8 @@
|
||||
"diy-group": "@/addon/components/diy/group/index.vue",
|
||||
"fixed-group": "@/addon/components/fixed/group/index.vue",
|
||||
"^u-(.*)": "uview-plus/components/u-$1/u-$1.vue",
|
||||
"^up-(.*)": "uview-plus/components/u-$1/u-$1.vue",
|
||||
"^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue",
|
||||
"diy-(\W.*)": "@/app/components/diy/$1/index.vue",
|
||||
"fixed-(\W.*)": "@/app/components/fixed/$1/index.vue"
|
||||
}
|
||||
|
||||
@ -1,37 +1,61 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { getSiteInfo } from '@/app/api/system'
|
||||
import { redirect } from '@/utils/common'
|
||||
import {defineStore} from 'pinia'
|
||||
import {getSiteInfo, getMap} from '@/app/api/system'
|
||||
import {redirect} from '@/utils/common'
|
||||
|
||||
interface System {
|
||||
site : AnyObject | null,
|
||||
siteApps: string[],
|
||||
siteAddons: string[],
|
||||
currRoute: string
|
||||
site: AnyObject | null,
|
||||
siteApps: string[],
|
||||
siteAddons: string[],
|
||||
currRoute: string,
|
||||
location: Object | null, // 定位信息
|
||||
mapConfig: Object,
|
||||
installAddonList: string[]
|
||||
}
|
||||
|
||||
const useSystemStore = defineStore('system', {
|
||||
state: () : System => {
|
||||
return {
|
||||
site: null,
|
||||
siteApps: [],
|
||||
siteAddons: [],
|
||||
currRoute: ''
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
async getSiteInfoFn() {
|
||||
await getSiteInfo().then((res: any) => {
|
||||
this.site = res.data
|
||||
this.siteApps = res.data.app
|
||||
this.siteAddons = res.data.site_addons.map((item: AnyObject) => {
|
||||
return item.key
|
||||
})
|
||||
if (!this.site || this.site.status == 3) redirect({url: '/app/pages/index/close', mode: 'reLaunch'})
|
||||
}).catch((err) => {
|
||||
redirect({url: '/app/pages/index/nosite', mode: 'reLaunch'})
|
||||
})
|
||||
}
|
||||
}
|
||||
state: (): System => {
|
||||
return {
|
||||
site: null,
|
||||
siteApps: [],
|
||||
siteAddons: [],
|
||||
currRoute: '',
|
||||
location: null,
|
||||
mapConfig: {
|
||||
is_open: 1,
|
||||
valid_time: 0
|
||||
},
|
||||
installAddonList: []
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
async getSiteInfoFn() {
|
||||
await getSiteInfo().then((res: any) => {
|
||||
this.site = res.data
|
||||
this.siteApps = res.data.app
|
||||
this.siteAddons = res.data.site_addons.map((item: AnyObject) => {
|
||||
return item.key
|
||||
})
|
||||
if (!this.site || this.site.status == 3) redirect({url: '/app/pages/index/close', mode: 'reLaunch'})
|
||||
}).catch((err) => {
|
||||
redirect({url: '/app/pages/index/nosite', mode: 'reLaunch'})
|
||||
})
|
||||
},
|
||||
async getMapFn() {
|
||||
// 获取地图配置
|
||||
await getMap().then((res: any) => {
|
||||
this.mapConfig.is_open = res.data.is_open;
|
||||
this.mapConfig.valid_time = res.data.valid_time;
|
||||
uni.setStorageSync('mapConfig', this.mapConfig);
|
||||
})
|
||||
},
|
||||
setLocation(value: Object) {
|
||||
var date = new Date();
|
||||
date.setSeconds(60 * this.mapConfig.valid_time);
|
||||
value.valid_time = date.getTime() / 1000; // 定位信息 5分钟内有效,过期后将重新获取定位信息
|
||||
this.location = value;
|
||||
uni.setStorageSync('location', value); // 初始化数据调用
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default useSystemStore
|
||||
|
||||
@ -81,5 +81,5 @@ button[type='primary'],uni-button[type='primary']{
|
||||
|
||||
// 去掉uveiew 点击时变灰【针对于微信小程序处理,官方提供的方法,在小程序中不起作用】
|
||||
.u-button.u-button--active:before{
|
||||
opacity: 0 !important;
|
||||
opacity: 0 !important;
|
||||
}
|
||||
@ -1,7 +1,39 @@
|
||||
.bg-index {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
background-size: 100%;
|
||||
background-repeat: no-repeat !important;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
background-size: contain !important;
|
||||
background-repeat: no-repeat !important;
|
||||
}
|
||||
|
||||
:deep(.u-tabbar__placeholder) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.diy-template-wrap {
|
||||
::v-deep .diy-group {
|
||||
> .draggable-element.top-fixed-diy {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* #ifdef MP */
|
||||
.child-diy-template-wrap {
|
||||
::v-deep .diy-group {
|
||||
> .draggable-element.top-fixed-diy {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
|
||||
/* #ifdef H5 */
|
||||
:deep(.child-diy-template-wrap) {
|
||||
.diy-group .draggable-element.top-fixed-diy {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
}
|
||||
@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 3952239 */
|
||||
src: url('//at.alicdn.com/t/c/font_3952239_3tsf1efqgog.woff2?t=1712802722864') format('woff2'),
|
||||
url('//at.alicdn.com/t/c/font_3952239_3tsf1efqgog.woff?t=1712802722864') format('woff'),
|
||||
url('//at.alicdn.com/t/c/font_3952239_3tsf1efqgog.ttf?t=1712802722864') format('truetype');
|
||||
src: url('//at.alicdn.com/t/c/font_3952239_w46a4i1qd3b.woff2?t=1715765166832') format('woff2'),
|
||||
url('//at.alicdn.com/t/c/font_3952239_w46a4i1qd3b.woff?t=1715765166832') format('woff'),
|
||||
url('//at.alicdn.com/t/c/font_3952239_w46a4i1qd3b.ttf?t=1715765166832') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
@ -13,6 +13,82 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.iconqiandao:before {
|
||||
content: "\e636";
|
||||
}
|
||||
|
||||
.iconguanbi1:before {
|
||||
content: "\e634";
|
||||
}
|
||||
|
||||
.iconxiangxia:before {
|
||||
content: "\e62f";
|
||||
}
|
||||
|
||||
.iconxiangshang:before {
|
||||
content: "\e630";
|
||||
}
|
||||
|
||||
.iconshangyibu:before {
|
||||
content: "\e62a";
|
||||
}
|
||||
|
||||
.iconzhankai:before {
|
||||
content: "\e62c";
|
||||
}
|
||||
|
||||
.iconshouqi:before {
|
||||
content: "\e62d";
|
||||
}
|
||||
|
||||
.iconxiayibu1:before {
|
||||
content: "\e628";
|
||||
}
|
||||
|
||||
.iconhexiao:before {
|
||||
content: "\e64f";
|
||||
}
|
||||
|
||||
.iconjiang-copy:before {
|
||||
content: "\e624";
|
||||
}
|
||||
|
||||
.iconshuru:before {
|
||||
content: "\e625";
|
||||
}
|
||||
|
||||
.iconshurutianxiebi:before {
|
||||
content: "\e69f";
|
||||
}
|
||||
|
||||
.icontiaoxingmasaomiao:before {
|
||||
content: "\e63a";
|
||||
}
|
||||
|
||||
.iconsaoma:before {
|
||||
content: "\e69a";
|
||||
}
|
||||
|
||||
.iconjilu:before {
|
||||
content: "\e627";
|
||||
}
|
||||
|
||||
.iconshangjiadingdan:before {
|
||||
content: "\ee00";
|
||||
}
|
||||
|
||||
.iconzhekou:before {
|
||||
content: "\e623";
|
||||
}
|
||||
|
||||
.iconxiayibu:before {
|
||||
content: "\e60e";
|
||||
}
|
||||
|
||||
.iconsousuo:before {
|
||||
content: "\e8b9";
|
||||
}
|
||||
|
||||
.iconweixin11:before {
|
||||
content: "\e63b";
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import useMemberStore from '@/stores/member'
|
||||
import pagesZh from '@/locale/zh-Hans.json'
|
||||
import pagesEn from '@/locale/en.json'
|
||||
import { onReady } from '@dcloudio/uni-app'
|
||||
import useSystemStore from '@/stores/system'
|
||||
|
||||
/**
|
||||
* 跳转页面
|
||||
@ -310,6 +311,20 @@ export function copy(value, callback) {
|
||||
data: value,
|
||||
success: () => {
|
||||
typeof callback == 'function' && callback();
|
||||
},
|
||||
fail: (res)=>{
|
||||
// 在隐私协议中没有声明chooseLocation:fail api作用域
|
||||
if(res.errMsg && res.errno) {
|
||||
if(res.errno == 104){
|
||||
let msg = '用户未授权隐私权限,设置剪贴板数据失败';
|
||||
uni.showToast({title: msg, icon: 'none'})
|
||||
}else if(res.errno == 112){
|
||||
let msg = '隐私协议中未声明,设置剪贴板数据失败';
|
||||
uni.showToast({title: msg, icon: 'none'})
|
||||
}else {
|
||||
uni.showToast({title: res.errMsg, icon: 'none'})
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
@ -338,4 +353,69 @@ export function handleOnloadParams(option:any) {
|
||||
params = option;
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取定位信息
|
||||
*/
|
||||
export function getLocation(param = {}) {
|
||||
uni.getLocation({
|
||||
type: param.type ?? 'gcj02',
|
||||
success: res => {
|
||||
const systemStore = useSystemStore()
|
||||
systemStore.setLocation(res);
|
||||
typeof param.success == 'function' && param.success(res);
|
||||
},
|
||||
fail: res => {
|
||||
typeof param.fail == 'function' && param.fail(res);
|
||||
},
|
||||
complete: res => {
|
||||
typeof param.complete == 'function' && param.complete(res);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 定位信息(缓存)
|
||||
*/
|
||||
export function locationStorage () {
|
||||
let data = uni.getStorageSync('location');
|
||||
let mapConfig = uni.getStorageSync('mapConfig');
|
||||
if (data) {
|
||||
var date = new Date();
|
||||
if (mapConfig.valid_time > 0) {
|
||||
data.is_expired = (date.getTime() / 1000) > data.valid_time; // 是否过期
|
||||
} else {
|
||||
data.is_expired = false;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 深度克隆
|
||||
* @param {object} obj 需要深度克隆的对象
|
||||
* @returns {*} 克隆后的对象或者原值(不是对象)
|
||||
*/
|
||||
export function deepClone(obj: object) {
|
||||
// 对常见的“非”值,直接返回原来值
|
||||
if ([null, undefined, NaN, false].includes(obj)) return obj
|
||||
if (typeof obj !== 'object' && typeof obj !== 'function') {
|
||||
// 原始类型直接返回
|
||||
return obj
|
||||
}
|
||||
const o = isArray(obj) ? [] : {}
|
||||
for (const i in obj) {
|
||||
if (obj.hasOwnProperty(i)) {
|
||||
o[i] = typeof obj[i] === 'object' ? deepClone(obj[i]) : obj[i]
|
||||
}
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
const isArray = (value: any) => {
|
||||
if (typeof Array.isArray === 'function') {
|
||||
return Array.isArray(value)
|
||||
}
|
||||
return Object.prototype.toString.call(value) === '[object Array]'
|
||||
}
|
||||
@ -22,7 +22,7 @@ class Wechat {
|
||||
timestamp: data.timestamp, // 必填,生成签名的时间戳
|
||||
nonceStr: data.nonceStr, // 必填,生成签名的随机串
|
||||
signature: data.signature,// 必填,签名
|
||||
jsApiList: ['chooseWXPay', 'updateAppMessageShareData', 'updateTimelineShareData'] // 必填,需要使用的JS接口列表
|
||||
jsApiList: ['chooseWXPay', 'updateAppMessageShareData', 'updateTimelineShareData', 'scanQRCode'] // 必填,需要使用的JS接口列表
|
||||
});
|
||||
})
|
||||
}
|
||||
@ -47,6 +47,22 @@ class Wechat {
|
||||
wx.updateTimelineShareData(options)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫一扫
|
||||
* @param {Object} callback
|
||||
*/
|
||||
public scanQRCode(callback:AnyFunction){
|
||||
wx.ready(()=> {
|
||||
wx.scanQRCode({
|
||||
needResult: 1,
|
||||
scanType: ["qrCode"],
|
||||
success: function (res) {
|
||||
typeof callback == 'function' && callback(res);
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default new Wechat()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user