update uniapp

This commit is contained in:
全栈小学生 2024-06-15 15:44:03 +08:00
parent 8a1dea9ea9
commit 57f185994f
75 changed files with 4176 additions and 1722 deletions

View File

@ -50,6 +50,20 @@ export function mobileRegister(data : AnyObject) {
return request.post(url, data, { showErrorMessage: true })
}
/**
*
*/
export function wechatUser(data : AnyObject) {
return request.get('wechat/user', data, { showErrorMessage: false })
}
/**
* openid
*/
export function wechatUserLogin(data : AnyObject) {
return request.post('wechat/userlogin', data, { showErrorMessage: true })
}
/**
*
*/
@ -58,7 +72,7 @@ export function wechatLogin(data : AnyObject) {
}
/**
*
*
*/
export function weappLogin(data : AnyObject) {
return request.post('weapp/login', data, { showErrorMessage: false })

View File

@ -3,20 +3,27 @@ import request from '@/utils/request'
/**
*
*/
export function getDiyInfo(params : Record<string, any>) {
return request.get('diy/diy', params)
export function getDiyInfo(params: Record<string, any>) {
return request.get('diy/diy', params)
}
/**
*
*/
export function getTabbarInfo(params : Record<string, any>) {
return request.get('diy/tabbar', params)
export function getTabbarInfo(params: Record<string, any>) {
return request.get('diy/tabbar', params)
}
/**
*
*/
export function getTabbarList(params: Record<string, any>) {
return request.get('diy/tabbar/list', params)
}
/**
*
*/
export function getShareInfo(params : Record<string, any>) {
return request.get('diy/share', params)
export function getShareInfo(params: Record<string, any>) {
return request.get('diy/share', params)
}

View File

@ -17,6 +17,12 @@ export function getPointList(data : AnyObject) {
export function getBalanceList(data : AnyObject) {
return request.get('member/account/balance', data)
}
/**
* ,
*/
export function getBalanceListAll(data : AnyObject) {
return request.get('member/account/balance_list', data)
}
/**
*
@ -116,6 +122,12 @@ export function deleteCashoutAccount(accountId: number) {
return request.delete(`member/cashout_account/${accountId}`, { showSuccessMessage: true, showErrorMessage: true })
}
/**
*
*/
export function getMemberCommission(data : AnyObject) {
return request.get(`member/account/commission`,data)
}
/**
*
*/
@ -123,13 +135,20 @@ export function getCommissionList(data : AnyObject) {
return request.get(`member/account/commission`, data)
}
/**
*
*/
export function getAccountType(params: Record<string, any>) {
return request.get(`member/account/fromtype/${params.account_type}`)
}
/**
*
* @param params
* @returns
*/
export function getAddressList(params: Record<string, any>) {
return request.get(`member/address`, {params})
return request.get(`member/address`, params)
}
/**
@ -204,9 +223,22 @@ export function getSignConfig() {
/**
*
* @param params
* @returns
*/
export function setSign() {
return request.post('member/sign')
}
/**
*
*/
export function getMemberAccountPointcount() {
return request.get(`member/account/pointcount`)
}
/**
*
*/
export function getTaskPoint() {
return request.get(`task/point`)
}

View File

@ -113,7 +113,7 @@ export function getAreaByCode(code: number | string) {
* @param params
*/
export function getAddressByLatlng(params: Record<string, any>) {
return request.get(`area/address_by_latlng`, params)
return request.get(`area/address_by_latlng`, params, {showErrorMessage: true})
}
/**

View File

@ -11,7 +11,7 @@ export function getVerifyCode(type: string ,params: AnyObject) {
*
*/
export function getVerifyRecords(params: Record<string, any>) {
return request.get('verify_records', {params})
return request.get('verify_records', params)
}
/**

View File

@ -4,32 +4,32 @@
<view class="diy-active-cube relative">
<view class="active-cube-wrap p-[20rpx]">
<view class="flex items-center" v-if="diyComponent.titleStyle.value == 'style-1'">
<view class="mr-[20rpx] font-bold text-[32rpx]" :style="{color: diyComponent.titleColor }" @click="toRedirect(diyComponent.textLink)">{{ diyComponent.text }}</view>
<view v-if="diyComponent.subTitle.text" @click="toRedirect(diyComponent.subTitle.link)" class="text-center text-[24rpx] rounded-[40rpx] rounded-tl-none py-[10rpx] px-[20rpx]" :style="{'color': diyComponent.subTitle.textColor, background: 'linear-gradient(90deg, '+ diyComponent.subTitle.startColor + ', '+ diyComponent.subTitle.endColor + ')'}">{{ diyComponent.subTitle.text }}</view>
<view class="mr-[20rpx] font-bold text-[32rpx]" :style="{color: diyComponent.titleColor }" @click="diyStore.toRedirect(diyComponent.textLink)">{{ diyComponent.text }}</view>
<view v-if="diyComponent.subTitle.text" @click="diyStore.toRedirect(diyComponent.subTitle.link)" class="text-center text-[24rpx] rounded-[40rpx] rounded-tl-none py-[10rpx] px-[20rpx]" :style="{'color': diyComponent.subTitle.textColor, background: 'linear-gradient(90deg, '+ diyComponent.subTitle.startColor + ', '+ diyComponent.subTitle.endColor + ')'}">{{ diyComponent.subTitle.text }}</view>
</view>
<view class="flex items-center" v-if="diyComponent.titleStyle.value == 'style-2'">
<view class="mr-[20rpx] font-bold text-[32rpx]" :style="{color: diyComponent.titleColor }" @click="toRedirect(diyComponent.textLink)">{{ diyComponent.text }}</view>
<view v-if="diyComponent.subTitle.text" @click="toRedirect(diyComponent.subTitle.link)" class="text-center text-[24rpx] rounded-[10rpx] py-[10rpx] px-[20rpx]" :style="{'color': diyComponent.subTitle.textColor, background: 'linear-gradient(90deg, '+ diyComponent.subTitle.startColor + ', '+ diyComponent.subTitle.endColor + ')'}">{{ diyComponent.subTitle.text }}</view>
<view class="mr-[20rpx] font-bold text-[32rpx]" :style="{color: diyComponent.titleColor }" @click="diyStore.toRedirect(diyComponent.textLink)">{{ diyComponent.text }}</view>
<view v-if="diyComponent.subTitle.text" @click="diyStore.toRedirect(diyComponent.subTitle.link)" class="text-center text-[24rpx] rounded-[10rpx] py-[10rpx] px-[20rpx]" :style="{'color': diyComponent.subTitle.textColor, background: 'linear-gradient(90deg, '+ diyComponent.subTitle.startColor + ', '+ diyComponent.subTitle.endColor + ')'}">{{ diyComponent.subTitle.text }}</view>
</view>
<view class="flex items-center" v-if="diyComponent.titleStyle.value == 'style-3'">
<view class="mr-[20rpx] font-bold text-[32rpx]" @click="toRedirect(diyComponent.textLink)" :style="{color: diyComponent.titleColor }">{{ diyComponent.text }}</view>
<view class="relative h-[44rpx]" @click="toRedirect(diyComponent.subTitle.link)">
<view class="mr-[20rpx] font-bold text-[32rpx]" @click="diyStore.toRedirect(diyComponent.textLink)" :style="{color: diyComponent.titleColor }">{{ diyComponent.text }}</view>
<view class="relative h-[44rpx]" @click="diyStore.toRedirect(diyComponent.subTitle.link)">
<view v-if="diyComponent.subTitle.text" class="text-center text-[24rpx] py-[10rpx] pl-[16rpx] pr-[36rpx]" :style="{'color': diyComponent.subTitle.textColor, background: 'linear-gradient(90deg, '+ diyComponent.subTitle.startColor + ', '+ diyComponent.subTitle.endColor + ')'}">{{ diyComponent.subTitle.text }}</view>
<image class="absolute left-0 top-0 bottom-0 !w-[16rpx] !h-[44rpx]" :src="img('static/resource/images/diy/active_cube/block_style2_1.png')" mode="scaleToFill"/>
<image class="absolute right-0 top-0 bottom-0 !w-[28rpx] !h-[44rpx]" :src="img('static/resource/images/diy/active_cube/block_style2_2.png')" mode="scaleToFill"/>
</view>
</view>
<view class="flex items-center justify-between" v-if="diyComponent.titleStyle.value == 'style-4'">
<view class="font-bold text-[32rpx]" @click="toRedirect(diyComponent.textLink)" :style="{color: diyComponent.titleColor }">{{ diyComponent.text }}</view>
<view v-if="diyComponent.subTitle.text" @click="toRedirect(diyComponent.subTitle.link)" class="text-[24rpx] rounded-[40rpx] py-[10rpx] pl-[16rpx] pr-[12rpx] flex items-center" :style="{'color': diyComponent.subTitle.textColor, background: 'linear-gradient(90deg, '+ diyComponent.subTitle.startColor + ', '+ diyComponent.subTitle.endColor + ')'}">
<view class="font-bold text-[32rpx]" @click="diyStore.toRedirect(diyComponent.textLink)" :style="{color: diyComponent.titleColor }">{{ diyComponent.text }}</view>
<view v-if="diyComponent.subTitle.text" @click="diyStore.toRedirect(diyComponent.subTitle.link)" class="text-[24rpx] rounded-[40rpx] py-[10rpx] pl-[16rpx] pr-[12rpx] flex items-center" :style="{'color': diyComponent.subTitle.textColor, background: 'linear-gradient(90deg, '+ diyComponent.subTitle.startColor + ', '+ diyComponent.subTitle.endColor + ')'}">
<text>{{ diyComponent.subTitle.text }}</text>
<text class="iconfont iconxiangyoujiantou ml-[4rpx] !text-[20rpx]"></text>
<text class="nc-iconfont nc-icon-youV6xx !text-[26rpx]"></text>
</view>
</view>
<view class="bd flex flex-wrap justify-between">
<template v-for="item in diyComponent.list" :key="item.id">
<view v-if="diyComponent.blockStyle.value == 'style-1'" @click="toRedirect(item.link)" class="item flex justify-between p-[20rpx] bg-white mt-[20rpx] rounded-[16rpx]" :style="{ backgroundColor : diyComponent.elementBgColor }">
<view v-if="diyComponent.blockStyle.value == 'style-1'" @click="diyStore.toRedirect(item.link)" class="item flex justify-between p-[20rpx] bg-white mt-[20rpx] rounded-[16rpx]" :style="{ backgroundColor : diyComponent.elementBgColor }">
<view class="flex-1 flex items-baseline flex-col">
<view class="text--[28rpx] pb-[20rpx]" :style="{ fontWeight : diyComponent.blockStyle.fontWeight }">{{ item.title.text }}</view>
<view class="text--[24rpx] text-gray-500 pb-[20rpx]">{{ item.subTitle.text }}</view>
@ -46,7 +46,7 @@
<u-icon name="photo" color="#999" size="50"></u-icon>
</view>
</view>
<view v-if="diyComponent.blockStyle.value == 'style-2'" @click="toRedirect(item.link)" class="item flex justify-between p-[20rpx] bg-white mt-[20rpx] rounded-[16rpx]" :style="{ backgroundColor : diyComponent.elementBgColor }">
<view v-if="diyComponent.blockStyle.value == 'style-2'" @click="diyStore.toRedirect(item.link)" class="item flex justify-between p-[20rpx] bg-white mt-[20rpx] rounded-[16rpx]" :style="{ backgroundColor : diyComponent.elementBgColor }">
<view class="flex-1 flex items-baseline flex-col">
<view class="text--[28rpx] pb-[20rpx]" :style="{ fontWeight : diyComponent.blockStyle.fontWeight }">{{ item.title.text }}</view>
<view class="text--[24rpx] text-gray-500 pb-[20rpx]">{{ item.subTitle.text }}</view>
@ -67,12 +67,12 @@
<scroll-view scroll-x="true" class="whitespace-nowrap" v-if="diyComponent.blockStyle.value == 'style-3'">
<view v-for="(item,index) in diyComponent.list" :key="item.id" class="inline-flex">
<view @click="toRedirect(item.link)" class="flex flex-col items-center justify-between p-[10rpx] bg-white mt-[20rpx] w-[156rpx] h-[200rpx] rounded-[10rpx] box-border" :class="{'mr-[14rpx]': (index+1 != diyComponent.list.length)}">
<view class="w-[140rpx] h-[140rpx]" v-if="item.imageUrl">
<image class="w-[140rpx] h-[140rpx]" :src="img(item.imageUrl)" mode="aspectFit" />
<view @click="diyStore.toRedirect(item.link)" class="flex flex-col items-center justify-between p-[10rpx] bg-white mt-[20rpx] w-[157rpx] h-[200rpx] rounded-[10rpx] box-border" :class="{'mr-[14rpx]': (index+1 != diyComponent.list.length)}">
<view class="w-[141rpx] h-[141rpx]" v-if="item.imageUrl">
<image class="w-[141rpx] h-[141rpx]" :src="img(item.imageUrl)" mode="aspectFit" />
</view>
<view class="w-[140rpx] h-[140rpx] relative flex-shrink-0" v-else>
<view class="absolute left-0 top-0 flex items-center justify-center w-[140rpx] h-[140rpx] bg-[#f3f4f6]">
<view class="w-[141rpx] h-[141rpx] relative flex-shrink-0" v-else>
<view class="absolute left-0 top-0 flex items-center justify-center w-[141rpx] h-[141rpx] bg-[#f3f4f6]">
<u-icon name="photo" color="#999" size="50"></u-icon>
</view>
</view>
@ -83,8 +83,8 @@
<scroll-view scroll-x="true" class="whitespace-nowrap" v-if="diyComponent.blockStyle.value == 'style-4'">
<view v-for="(item,index) in diyComponent.list" :key="item.id" class="inline-flex">
<view @click="toRedirect(item.link)" class="flex flex-col items-center justify-between p-[4rpx] bg-[#F93D02] mt-[20rpx] rounded-[20rpx] box-border" :class="{'mr-[14rpx]': index+1 != diyComponent.list.length}" :style="{ background : 'linear-gradient('+ item.listFrame.startColor +','+ item.listFrame.endColor + ')' }">
<view class="w-[148rpx] h-[148rpx] box-border px-[18rpx] pt-[16rpx] pb-[6rpx] bg-[#fff] flex flex-col items-center rounded-[16rpx]">
<view @click="diyStore.toRedirect(item.link)" class="flex flex-col items-center justify-between p-[4rpx] bg-[#F93D02] mt-[20rpx] rounded-[20rpx] box-border" :class="{'mr-[14rpx]': index+1 != diyComponent.list.length}" :style="{ background : 'linear-gradient('+ item.listFrame.startColor +','+ item.listFrame.endColor + ')' }">
<view class="w-[149rpx] h-[149rpx] box-border px-[18rpx] pt-[16rpx] pb-[6rpx] bg-[#fff] flex flex-col items-center rounded-[16rpx]">
<view class="w-[112rpx] h-[102rpx]" v-if="item.imageUrl">
<image class="w-[112rpx] h-[102rpx]" :src="img(item.imageUrl)" mode="aspectFit" />
</view>
@ -108,8 +108,7 @@
//
import { ref,computed, watch, onMounted, nextTick,getCurrentInstance } from 'vue';
import useDiyStore from '@/app/stores/diy';
import { img, redirect,diyRedirect, currRoute, getToken } from '@/utils/common';
import { useLogin } from '@/hooks/useLogin';
import { img } from '@/utils/common';
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
@ -201,19 +200,6 @@
}).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)
}
}
</script>
<style lang="scss" scoped>

View File

@ -8,13 +8,13 @@
</view>
<view class="fixed-wrap" :class="[ diyStore.mode != 'decorate' ? diyComponent.positionWay : '' ]" :style="fixedStyle">
<view class="diy-search-wrap relative z-10" @click="toRedirect(diyComponent.search.link)" :style="navbarInnerStyle">
<view class="diy-search-wrap relative z-10" @click="diyStore.toRedirect(diyComponent.search.link)" :style="navbarInnerStyle">
<view class="img-wrap" v-if="diyComponent.search.logo">
<image :src="img(diyComponent.search.logo)" mode="aspectFit"/>
</view>
<view class="search-content">
<input type="text" class="uni-input" placeholder-style="color:#fff" placeholder-class="!text-[#fff] text-[24rpx] leading-[68rpx]" :placeholder="isShowSearchPlaceholder ? diyComponent.search.text : ''" disabled="true"/>
<text class="iconfont iconxiazai17"></text>
<text class="nc-iconfont nc-icon-sousuo-duanV6xx1"></text>
<swiper class="swiper-wrap" :interval="diyComponent.search.hotWord.interval * 1000" autoplay="true" vertical="true" circular="true" v-if="!isShowSearchPlaceholder">
<swiper-item class="swiper-item" v-for="(item) in diyComponent.search.hotWord.list" :key="item.id">
@ -24,7 +24,7 @@
</view>
</view>
<view class="tab-list-wrap relative z-10" v-if="diyComponent.tab.control">
<scroll-view scroll-x="true" class="scroll-wrap" :scroll-into-view="'a' + currTabIndex">
<view @click="changeData({ source : 'home' },-1)" class="scroll-item" :class="[{ active: currTabIndex == -1 }]">
@ -36,7 +36,7 @@
<view class="line" :style="{'background-color': getTabColor(index == currTabIndex)}" v-if="index == currTabIndex"></view>
</view>
</scroll-view>
<view v-if="diyComponent.tab.list.length" class="absolute tab-btn iconfont iconliebiaoxingshi" @click="tabAllPopup = true"></view>
<view v-if="diyComponent.tab.list.length" class="absolute tab-btn nc-iconfont nc-icon-yingyongliebiaoV6xx" @click="tabAllPopup = true"></view>
</view>
<view class="bg-img" v-if="fixedStyleBg">
@ -58,11 +58,11 @@
'swiper-right': diyComponent.swiper.indicatorAlign == 'right',
'ns-indicator-dots': diyComponent.swiper.indicatorStyle == 'style-2'
}"
:previous-margin="swiperStyle2 ? 0 : '60rpx'" :next-margin="swiperStyle2 ? 0 : '60rpx'"
:previous-margin="swiperStyle2 ? 0 : '36rpx'" :next-margin="swiperStyle2 ? 0 : '36rpx'"
:interval="diyComponent.swiper.interval * 1000" :indicator-dots="isShowDots"
:indicator-color="diyComponent.swiper.indicatorColor" :indicator-active-color="diyComponent.swiper.indicatorActiveColor">
<swiper-item class="swiper-item" v-for="(item,index) in diyComponent.swiper.list" :key="item.id" :style="swiperWarpCss">
<view @click="toRedirect(item.link)">
<view @click="diyStore.toRedirect(item.link)">
<view class="item" :style="{height: imgHeight}">
<image v-if="item.imageUrl" :src="img(item.imageUrl)" mode="scaleToFill" :style="swiperWarpCss" :class="['w-full h-full',{'swiper-animation': swiperIndex != index}]" :show-menu-by-longpress="true"/>
<image v-else :src="img('static/resource/images/diy/figure.png')" :style="swiperWarpCss" mode="scaleToFill" :class="['w-full h-full',{'swiper-animation': swiperIndex != index}]" :show-menu-by-longpress="true"/>
@ -83,8 +83,8 @@
</view>
<!-- 分类展开 -->
<u-popup :show="tabAllPopup" mode="top" @close="tabAllPopup = false">
<view class="text-sm px-[30rpx] mt-3" :style="{'padding-top':(menuButtonInfo.top+'px')}">全部分类</view>
<u-popup :safeAreaInsetTop="true" :show="tabAllPopup" mode="top" @close="tabAllPopup = false">
<view class="text-sm px-[30rpx] pt-3" :style="{'padding-top':(menuButtonInfo.top+'px')}">全部分类</view>
<view class="flex flex-wrap pl-[30rpx] pt-[30rpx]">
<view @click="changeData({ source : 'home' },-1)" :class="['px-[26rpx] border-[2rpx] border-solid border-transparent h-[60rpx] mr-[30rpx] mb-[30rpx] flex items-center justify-center bg-[#F4F4F4] rounded-[8rpx] text-xs', { 'tab-select-popup': currTabIndex == -1 }]">
首页
@ -112,12 +112,11 @@
<script setup lang="ts">
//
import { ref, reactive, computed, watch, onMounted, nextTick, getCurrentInstance } from 'vue';
import { img, redirect,diyRedirect, currRoute, getToken } from '@/utils/common';
import { img } from '@/utils/common';
import useDiyStore from '@/app/stores/diy';
import diyGroup from '@/addon/components/diy/group/index.vue'
import { getDiyInfo } from '@/app/api/diy';
import { useLogin } from '@/hooks/useLogin';
const instance = getCurrentInstance();
const props = defineProps(['component', 'index', 'pullDownRefreshCount', 'global']);
const diyStore = useDiyStore();
@ -246,7 +245,6 @@
style = diyComponent.value.swiper.swiperStyle == 'style-2' ? true : false;
return style;
})
const imgHeight = computed(() => {
return (diyComponent.value.swiper.imageHeight * 2) + 'rpx';
@ -339,7 +337,7 @@
const diyPageData = reactive({
pageMode: 'diy',
title: '',
global: {},
global: <any>{},
value: []
})
@ -361,6 +359,7 @@
let sources = JSON.parse(data.value);
diyPageData.global = sources.global;
diyPageData.global.topStatusBar.isShow = false; //
diyPageData.global.bottomTabBarSwitch = false; //
diyPageData.value = sources.value;
@ -386,19 +385,6 @@
}
});
}
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)
}
}
//
let isShowDots = ref(true)
@ -546,7 +532,7 @@
}
}
.tab-btn{
font-size: 32rpx;
font-size: 34rpx;
/* #ifdef H5 */
top: 22rpx;
right: 20rpx;
@ -555,9 +541,9 @@
&::after{
content: "";
position: absolute;
top: 2rpx;
bottom: 0;
left: -16rpx;
top: 6rpx;
bottom: -2rpx;
left: -14rpx;
width: 4rpx;
background: linear-gradient( 180deg, #FFFFFF 16%, rgba(255,255,255,0) 92%);
}

View File

@ -1,7 +1,7 @@
<template>
<view :style="warpCss">
<view :class="['float-btn flex flex-col z-1000 items-center px-[24rpx] fixed', diyComponent.bottomPosition, diyStore.mode == 'decorate' ? 'float-btn-border' : '']" :style="floatBtnWrapCss">
<view v-for="(item,index) in diyComponent.list" :key="index" @click="toRedirect(item.link)" :class="{'flex items-center justify-center' : true, 'mb-[20rpx]': diyComponent.list.length != index+1 }" :style="floatBtnItemCss">
<view v-for="(item,index) in diyComponent.list" :key="index" @click="diyStore.toRedirect(item.link)" :class="{'flex items-center justify-center' : true, 'mb-[20rpx]': diyComponent.list.length != index+1 }" :style="floatBtnItemCss">
<image v-if="item && item.imageUrl" :style="floatBtnItemCss" :src="img(item.imageUrl)" mode="aspectFit"></image>
<image v-else :src="img('static/resource/images/diy/figure.png')" mode="aspectFit" :style="floatBtnItemCss"/>
</view>
@ -13,8 +13,7 @@
//
import { computed, watch } from 'vue';
import useDiyStore from '@/app/stores/diy';
import { img,redirect,diyRedirect, currRoute, getToken } from '@/utils/common';
import { useLogin } from '@/hooks/useLogin';
import { img } from '@/utils/common';
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
@ -67,19 +66,6 @@
//
}
)
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)
}
}
</script>
<style lang="scss" scoped>

View File

@ -5,7 +5,7 @@
<view v-if="diyComponent.layout == 'vertical'" class="graphic-nav">
<view class="graphic-nav-item" v-for="(item, index) in diyComponent.list" :key="item.id">
<view @click="toRedirect(item.link)" :class="['flex items-center justify-between py-3 px-4', index == 0 ? 'border-t-0':'border-t']">
<view @click="diyStore.toRedirect(item.link)" :class="['flex items-center justify-between py-3 px-4', index == 0 ? 'border-t-0':'border-t']">
<view class="graphic-img relative flex items-center w-10 h-10 mr-[20rpx]"
v-if="diyComponent.mode != 'text'"
@ -42,7 +42,7 @@
<view class="graphic-nav-item" :class="[diyComponent.mode]" :key="item.id" v-if="swiperCondition(index,numItem)" :style="{ width: 100 / diyComponent.rowCount + '%' }">
<view @click="toRedirect(item.link)" class="flex flex-col items-center box-border py-2">
<view @click="diyStore.toRedirect(item.link)" class="flex flex-col items-center box-border py-2">
<view class="graphic-img relative flex items-center justify-center w-10 h-10"
v-if="diyComponent.mode != 'text'"
@ -82,7 +82,7 @@
v-for="(item, index) in diyComponent.list" :key="item.id"
:style="{ width: 100 / diyComponent.rowCount + '%' }">
<view @click="toRedirect(item.link)" class="flex flex-col items-center box-border py-2">
<view @click="diyStore.toRedirect(item.link)" class="flex flex-col items-center box-border py-2">
<view class="graphic-img relative flex items-center justify-center w-10 h-10"
v-if="diyComponent.mode != 'text'"
:style="{ width: diyComponent.imageSize * 2 + 'rpx', height: diyComponent.imageSize * 2 + 'rpx' }">
@ -119,9 +119,8 @@
<script lang="ts" setup>
//
import { ref,computed, watch, onMounted, nextTick,getCurrentInstance } from 'vue';
import { img,redirect,diyRedirect, currRoute, getToken } from '@/utils/common';
import { img } from '@/utils/common';
import useDiyStore from '@/app/stores/diy';
import { useLogin } from '@/hooks/useLogin';
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
@ -240,19 +239,6 @@
}).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)
}
}
</script>
<style>

View File

@ -6,7 +6,7 @@
<template v-if="diyStore.mode != 'decorate'">
<!-- 热区功能 -->
<view @click="toRedirect(mapItem.link)" class="absolute" v-for="(mapItem, mapIndex) in diyComponent.heatMapData"
<view @click="diyStore.toRedirect(mapItem.link)" class="absolute" v-for="(mapItem, mapIndex) in diyComponent.heatMapData"
:key="mapIndex" :style="{
width: mapItem.width + '%',
height: mapItem.height + '%',
@ -23,8 +23,7 @@
//
import { computed, watch, onMounted } from 'vue';
import useDiyStore from '@/app/stores/diy';
import { img,redirect,diyRedirect, currRoute, getToken } from '@/utils/common';
import { useLogin } from '@/hooks/useLogin';
import { img } from '@/utils/common';
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
@ -86,19 +85,6 @@
//
}
)
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)
}
}
</script>
<style lang="scss">

View File

@ -3,7 +3,7 @@
<view :style="maskLayer"></view>
<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)">
<view @click="diyStore.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"/>
</view>
@ -11,7 +11,7 @@
<swiper v-else class="swiper" :style="{ height: imgHeight }" autoplay="true" circular="true" @change="swiperChange">
<swiper-item class="swiper-item" v-for="(item) in diyComponent.list" :key="item.id" :style="swiperWarpCss">
<view @click="toRedirect(item.link)">
<view @click="diyStore.toRedirect(item.link)">
<view class="item" :style="{height: imgHeight}">
<image v-if="item.imageUrl" :src="img(item.imageUrl)" mode="scaleToFill" class="w-full h-full" :show-menu-by-longpress="true"/>
<image v-else :src="img('static/resource/images/diy/figure.png')" mode="scaleToFill" class="w-full h-full" :show-menu-by-longpress="true"/>
@ -27,8 +27,7 @@
// 广
import { ref,computed, watch, onMounted, nextTick,getCurrentInstance } from 'vue';
import useDiyStore from '@/app/stores/diy';
import { img,redirect,diyRedirect, currRoute, getToken } from '@/utils/common';
import { useLogin } from '@/hooks/useLogin';
import { img } from '@/utils/common';
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
@ -135,19 +134,6 @@
}).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)
}
}
</script>
<style lang="scss" scoped>

View File

@ -16,7 +16,7 @@
</view>
<view class="set-icon flex items-center absolute right-0 top-2">
<view @click="redirect({ url: '/app/pages/setting/index' })">
<text class="iconfont iconshezhi text-[1.6rem] ml-[10rpx]" :style="{ color : diyComponent.textColor }"></text>
<text class="nc-iconfont nc-icon-shezhiV6xx-1 text-[40rpx] ml-[10rpx]" :style="{ color : diyComponent.textColor }"></text>
</view>
</view>
</view>
@ -29,7 +29,7 @@
</view>
<view class="set-icon flex items-center absolute right-0 top-2">
<view @click="redirect({ url: '/app/pages/setting/index' })">
<text class="iconfont iconshezhi text-[1.6rem] ml-[10rpx]" :style="{ color : diyComponent.textColor }"></text>
<text class="nc-iconfont nc-icon-shezhiV6xx-1 text-[40rpx] ml-[10rpx]" :style="{ color : diyComponent.textColor }"></text>
</view>
</view>
</view>
@ -161,12 +161,11 @@
}
// #endif
}
let menuButtonInfo = {};
// (API)
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
// #endif
let menuButtonInfo = {};
// (API)
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
// #endif
//
const navbarInnerStyle = computed(() => {

View File

@ -3,7 +3,7 @@
<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>
<text class="text-[28rpx] text-[#FFDAA8] ml-[10rpx] font-bold max-w-[440rpx] truncate">{{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>
@ -14,9 +14,9 @@
<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>
<text class="text-[32rpx] text-[#FFE3B1] leading-[normal] ml-[14rpx] font-bold max-w-[420rpx] truncate">{{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>
<text class="text-[#fff] text-[24rpx] mt-[10rpx] leading-[32rpx]" 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>
@ -30,7 +30,7 @@
<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>
<text class="text-[#733F02] ml-[8rpx] text-[30rpx] font-bold max-w-[380rpx] truncate">{{info.member_level_name}}</text>
</view>
<text class="text-[28rpx] text-[#794200] mt-[16rpx]">购物或邀请好友可以提升等级</text>
</view>
@ -39,7 +39,7 @@
<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 class="ml-[10rpx] text-[#733F02] !text-[26rpx] nc-iconfont nc-icon-youV6xx"></view>
</view>
</view>
<view class="flex items-center justify-between">
@ -60,7 +60,7 @@
</template>
<script lang="ts" setup>
import { computed, ref, watch, onMounted } from 'vue'
import { computed, ref, watch } from 'vue'
import { img, redirect } from '@/utils/common'
import useMemberStore from '@/stores/member'
import { t } from '@/locale'
@ -95,10 +95,17 @@
}
)
//
let list:any = ref([])
let upgradeGrowth = ref(0) //
let currIndex = ref(0) //
let afterCurrIndex = ref(-1) //
let benefits_arr:any = ref([]) //
const info:any = computed(() => {
//
if (diyStore.mode == 'decorate') {
upgradeGrowth.value = 10;
upgradeGrowth.value = 0;
benefits_arr.value = [{'title': '商品包邮'}];
currIndex.value = 1;
list.value = [{}];
@ -115,16 +122,11 @@
}
})
//
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;
if(!list.value.length) return false;
let isSet = false;
//

View File

@ -5,24 +5,21 @@
<view class="flex items-center pl-[28rpx] p-[22rpx]">
<template v-if="diyComponent.noticeType == 'img'">
<template v-if="diyComponent.imgType == 'system'">
<image v-if="diyComponent.systemUrl == 'style_1'" :src="img(`static/resource/images/diy/notice/${diyComponent.systemUrl}.png`)" class="h-[40rpx] max-w-[130rpx] mr-[20rpx]" mode="heightFix"/>
<image v-else-if="diyComponent.systemUrl == 'style_2'" :src="img(`static/resource/images/diy/notice/${diyComponent.systemUrl}.png`)" class="w-[200rpx] mr-[20rpx] h-[40rpx]" mode="heightFix" />
<image v-if="diyComponent.systemUrl == 'style_1'" :src="img(`static/resource/images/diy/notice/${diyComponent.systemUrl}.png`)" class="h-[40rpx] max-w-[130rpx] mr-[20rpx] flex-shrink-0" mode="heightFix"/>
<image v-else-if="diyComponent.systemUrl == 'style_2'" :src="img(`static/resource/images/diy/notice/${diyComponent.systemUrl}.png`)" class="w-[200rpx] mr-[20rpx] h-[40rpx] flex-shrink-0" mode="heightFix" />
</template>
<image v-else-if="diyComponent.imgType == 'diy'" :src="img(diyComponent.imageUrl || '')" class="h-[50rpx] mr-[20rpx]" mode="heightFix"/>
<image v-else-if="diyComponent.imgType == 'diy'" :src="img(diyComponent.imageUrl || '')" class="w-[50rpx] h-[50rpx] mr-[20rpx] flex-shrink-0" mode="heightFix"/>
</template>
<view v-if="diyComponent.noticeType == 'text' && diyComponent.noticeTitle" class="max-w-[128rpx] px-[12rpx] text-[26rpx] h-[40rpx] leading-[40rpx] text-[var(--primary-color)] bg-[var(--primary-color-light)] truncate rounded-[8rpx] mr-[20rpx]">{{ diyComponent.noticeTitle }}</view>
<view class="flex-1 flex items-center">
<view v-if="diyComponent.noticeType == 'text' && diyComponent.noticeTitle" class="max-w-[128rpx] px-[12rpx] text-[26rpx] h-[40rpx] leading-[40rpx] text-[var(--primary-color)] bg-[var(--primary-color-light)] truncate rounded-[8rpx] mr-[20rpx] flex-shrink-0">{{ diyComponent.noticeTitle }}</view>
<view class="flex-1 flex overflow-hidden horizontal-body" id="horizontal-body" :class="{'items-center':diyComponent.scrollWay == 'upDown'}">
<!-- 横向滚动 -->
<view class="horizontal-wrap" v-if="diyComponent.scrollWay == 'horizontal'">
<view class="marquee-wrap">
<view class="marquee" :style="marqueeStyle">
<text v-for="(item, index) in diyComponent.list" :key="index" @click="toRedirect(item)" :style="{ color: diyComponent.textColor, fontSize: diyComponent.fontSize * 2 + 'rpx', fontWeight: diyComponent.fontWeight }">{{ item.text }}</text>
</view>
<view class="marquee" :style="marqueeAgainStyle">
<text v-for="(item, index) in diyComponent.list" :key="index" @click="toRedirect(item)" :style="{ color: diyComponent.textColor, fontSize: diyComponent.fontSize * 2 + 'rpx', fontWeight: diyComponent.fontWeight }">{{ item.text }}</text>
</view>
</view>
<view class="horizontal-wrap" :style="marqueeStyle" v-if="diyComponent.scrollWay == 'horizontal'">
<view class="marquee marquee-one" id="marquee-one" >
<view class="item flex-shrink-0 !leading-[40rpx] h-[40rpx]" :class="{'ml-[80rpx]':index}" v-for="(item, index) in diyComponent.list" :key="index" @click="toRedirect(item)" :style="{ color: diyComponent.textColor, fontSize: diyComponent.fontSize * 2 + 'rpx', fontWeight: diyComponent.fontWeight }">{{ item.text }}</view>
</view>
<view class="marquee">
<view class="item flex-shrink-0 !leading-[40rpx] h-[40rpx]" :class="{'ml-[80rpx]':index}" v-for="(item, index) in diyComponent.list" :key="index" @click="toRedirect(item)" :style="{ color: diyComponent.textColor, fontSize: diyComponent.fontSize * 2 + 'rpx', fontWeight: diyComponent.fontWeight }">{{ item.text }}</view>
</view>
</view>
<!-- 上下滚动 -->
@ -34,7 +31,7 @@
</text>
</swiper-item>
</swiper>
<text class="iconfont iconxiangyoujiantou -ml-[8rpx] pl-[30rpx]" :style="{'color': '#999','fontSize': (12 * 2 + 'rpx'), 'fontWeight': diyComponent.fontWeight}"></text>
<text class="nc-iconfont nc-icon-youV6xx text-[26rpx] -ml-[8rpx] pl-[30rpx]" :style="{'color': '#999', 'fontWeight': diyComponent.fontWeight}"></text>
</template>
</view>
@ -45,7 +42,7 @@
<view @touchmove.prevent.stop>
<view class="py-[25rpx] text-sm leading-none border-0 border-solid border-b-[2rpx] border-[#eee] flex items-center justify-between">
<text class="ml-[30rpx]">公告</text>
<text class="mr-[20rpx] iconfont iconguanbi text-[35rpx]" @click="noticeShow = false"></text>
<text class="mr-[20rpx] nc-iconfont nc-icon-guanbiV6xx text-[35rpx]" @click="noticeShow = false"></text>
</view>
<scroll-view scroll-y="true" class="px-6 py-3 w-[480rpx] h-[500rpx] text-sm">{{ noticeContent }}</scroll-view>
<button @click="noticeShow = false" class="!mx-[30rpx] !mb-[40rpx] !w-auto !h-[70rpx] text-[24rpx] leading-[70rpx] rounded-full text-white !bg-[#ff4500] !text-[#fff]">我知道了</button>
@ -59,9 +56,8 @@
<script setup lang="ts">
//
import { ref,computed, watch, onMounted, nextTick,getCurrentInstance } from 'vue';
import { img, redirect,diyRedirect,currRoute, getToken } from '@/utils/common';
import { img } from '@/utils/common';
import useDiyStore from '@/app/stores/diy';
import { useLogin } from '@/hooks/useLogin';
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
const diyStore = useDiyStore();
@ -120,41 +116,50 @@ watch(
}
)
const marqueeWrapWidth = ref(0); //
const marqueeWidth = ref(0); //
const marqueeBodyWidth = ref(0); //
const marqueeStyle = ref(''); //
const marqueeAgainStyle = ref(''); //
const time = ref(0); //
const delayTime = ref(1000); //
const delayTime = ref(800); //
// pxrpx
const pxToRpx=(px)=> {
const screenWidth = uni.getSystemInfoSync().screenWidth
return (750 * Number.parseInt(px)) / screenWidth
}
//
const bindCrossSlipEvent = ()=> {
if (diyComponent.value.scrollWay == 'horizontal') {
setTimeout(() => {
nextTick(() => {
uni.createSelectorQuery().in(instance).select('.marquee-wrap').boundingClientRect(res => {
marqueeWrapWidth.value = res.width;
// #ifdef MP-WEIXIN
uni.createSelectorQuery().in(instance).select('.horizontal-body').boundingClientRect(res => {
marqueeBodyWidth.value = res.width;
console.log(pxToRpx(res.width))
const query = uni.createSelectorQuery().in(instance);
query.select('.marquee').boundingClientRect(data => {
marqueeWidth.value = data.width + 30; // 30px
time.value = Math.ceil(marqueeWidth.value * 10);
if (marqueeWrapWidth.value > marqueeWidth.value) {
query.selectAll('.marquee-one').boundingClientRect((data:any) => {
let width = data[0].width
time.value = pxToRpx(width) * 10;
if (marqueeBodyWidth.value > width) {
marqueeStyle.value = `animation: none;`;
marqueeAgainStyle.value = 'display:none;';
} else {
marqueeStyle.value = `
width: ${marqueeWidth.value}px;
animation-duration: ${time.value}ms;
animation-delay: ${delayTime.value}ms;`;
marqueeAgainStyle.value = `
width: ${marqueeWidth.value}px;
left: ${marqueeWidth.value}px;
animation-duration: ${time.value}ms;
animation-delay: ${delayTime.value}ms;`;
}
}).exec();
}).exec();
// #endif
// #ifdef H5
marqueeBodyWidth.value = window.document.getElementById('horizontal-body').offsetWidth;
const width = window.document.getElementById('marquee-one').offsetWidth;
time.value = pxToRpx(width) * 10;
if (marqueeBodyWidth.value > width) {
marqueeStyle.value = `animation: none;`;
} else {
marqueeStyle.value = `
animation-duration: ${time.value}ms;
animation-delay: ${delayTime.value}ms;`;
}
// #endif
});
});
}
@ -190,19 +195,13 @@ const refresh = ()=> {
}
const toRedirect = (data: {}) => {
if(diyStore.mode == 'decorate') return false;
if (diyStore.mode == 'decorate') return false;
if(diyComponent.value.showType == 'popup'){
if (diyComponent.value.showType == 'popup') {
noticeShow.value = true;
noticeContent.value = data.text;
}else {
if (data.link.url) {
if (currRoute() == 'app/pages/member/index' && !getToken()) {
useLogin().setLoginBack({ url: data.link.url })
return;
}
diyRedirect(data.link);
}
} else {
diyStore.toRedirect(data);
}
}
</script>
@ -258,36 +257,26 @@ const toRedirect = (data: {}) => {
}
.horizontal-wrap {
height: 30px;
line-height: 30px;
position: relative;
overflow: hidden;
width: 100%;
height: 40rpx;
display: flex;
align-items: center;
transform: translateZ(0);
animation: marquee 0s 0s linear infinite;
}
.marquee-wrap {
display: inline-block;
width: 100%;
height: 100%;
vertical-align: middle;
overflow: hidden;
box-sizing: border-box;
position: relative;
}
.marquee {
display: flex;
position: absolute;
align-items: center;
height: 100%;
white-space: nowrap;
animation: marquee 0s 0s linear infinite;
text {
margin-left: 40rpx;
&:first-child {
margin-left: 0;
}
}
padding-right: 60rpx;
// backface-visibility: hidden;
// -webkit-perspective: 1000;
// -moz-perspective: 1000;
// -ms-perspective: 1000;
// perspective: 1000;
}
@keyframes marquee {
@ -296,7 +285,7 @@ const toRedirect = (data: {}) => {
}
100% {
transform: translateX(-100%);
transform: translateX(-50%);
}
}
</style>

View File

@ -6,7 +6,7 @@
<!-- 1左2右 -->
<template v-if="diyComponent.mode == 'row1-lt-of2-rt'">
<view class="template-left">
<view @click="toRedirect(diyComponent.list[0].link)" :class="['item', diyComponent.mode]"
<view @click="diyStore.toRedirect(diyComponent.list[0].link)" :class="['item', diyComponent.mode]"
:style="{ marginRight: diyComponent.imageGap * 2 + 'rpx', width: diyComponent.list[0].imgWidth, height: diyComponent.list[0].imgHeight + 'px' }">
<image v-if="diyComponent.list[0].imageUrl" :src="img(diyComponent.list[0].imageUrl)" mode="scaleToFill" :style="diyComponent.list[0].pageItemStyle" :show-menu-by-longpress="true"/>
<image v-else :src="img('static/resource/images/diy/figure.png')" mode="scaleToFill" :style="diyComponent.list[0].pageItemStyle" :show-menu-by-longpress="true"/>
@ -16,7 +16,7 @@
<view class="template-right">
<template v-for="(item, index) in diyComponent.list" :key="index">
<template v-if="index > 0">
<view @click="toRedirect(item.link)" :class="['item', diyComponent.mode]"
<view @click="diyStore.toRedirect(item.link)" :class="['item', diyComponent.mode]"
:style="{ marginBottom: diyComponent.imageGap * 2 + 'rpx', width: item.imgWidth, height: item.imgHeight + 'px' }">
<image v-if="item.imageUrl" :src="img(item.imageUrl)" mode="scaleToFill" :style="item.pageItemStyle" :show-menu-by-longpress="true"/>
<image v-else :src="img('static/resource/images/diy/figure.png')" mode="scaleToFill" :style="item.pageItemStyle" :show-menu-by-longpress="true"/>
@ -29,7 +29,7 @@
<!-- 1左3右 -->
<template v-else-if="diyComponent.mode == 'row1-lt-of1-tp-of2-bm'">
<view class="template-left">
<view @click="toRedirect(diyComponent.list[0].link)" :class="['item', diyComponent.mode]"
<view @click="diyStore.toRedirect(diyComponent.list[0].link)" :class="['item', diyComponent.mode]"
:style="{ marginRight: diyComponent.imageGap * 2 + 'rpx', width: diyComponent.list[0].imgWidth, height: diyComponent.list[0].imgHeight + 'px' }">
<image v-if="diyComponent.list[0].imageUrl" :src="img(diyComponent.list[0].imageUrl)" mode="scaleToFill" :style="diyComponent.list[0].pageItemStyle" :show-menu-by-longpress="true"/>
<image v-else :src="img('static/resource/images/diy/figure.png')" mode="scaleToFill" :style="diyComponent.list[0].pageItemStyle" :show-menu-by-longpress="true"/>
@ -37,7 +37,7 @@
</view>
<view class="template-right">
<view @click="toRedirect(diyComponent.list[1].link)" :class="['item', diyComponent.mode]"
<view @click="diyStore.toRedirect(diyComponent.list[1].link)" :class="['item', diyComponent.mode]"
:style="{ marginBottom: diyComponent.imageGap * 2 + 'rpx', width: diyComponent.list[1].imgWidth, height: diyComponent.list[1].imgHeight + 'px' }">
<image v-if="diyComponent.list[1].imageUrl" :src="img(diyComponent.list[1].imageUrl)" mode="scaleToFill" :style="diyComponent.list[1].pageItemStyle" :show-menu-by-longpress="true"/>
<image v-else :src="img('static/resource/images/diy/figure.png')" mode="scaleToFill" :style="diyComponent.list[1].pageItemStyle" :show-menu-by-longpress="true"/>
@ -45,7 +45,7 @@
<view class="template-bottom">
<template v-for="(item, index) in diyComponent.list" :key="index">
<template v-if="index > 1">
<view @click="toRedirect(item.link)" :class="['item', diyComponent.mode]" :style="{
<view @click="diyStore.toRedirect(item.link)" :class="['item', diyComponent.mode]" :style="{
marginRight: diyComponent.imageGap * 2 + 'rpx',
width: item.imgWidth,
height: item.imgHeight + 'px'
@ -61,7 +61,7 @@
<template v-else>
<view :class="['item', diyComponent.mode]" v-for="(item, index) in diyComponent.list" :key="index"
@click="toRedirect(item.link)"
@click="diyStore.toRedirect(item.link)"
:style="{ marginRight: diyComponent.imageGap * 2 + 'rpx', marginBottom: diyComponent.imageGap * 2 + 'rpx', width: item.widthStyle, height: item.imgHeight + 'px' }">
<image v-if="item.imageUrl" :src="img(item.imageUrl)" :mode="'scaleToFill'" :style="item.pageItemStyle" :show-menu-by-longpress="true"/>
<image v-else :src="img('static/resource/images/diy/figure.png')" :mode="'scaleToFill'" :style="item.pageItemStyle" :show-menu-by-longpress="true"/>
@ -76,8 +76,7 @@
//
import { ref,onMounted, computed, watch,nextTick,getCurrentInstance } from 'vue';
import useDiyStore from '@/app/stores/diy';
import { img, redirect, diyRedirect, currRoute, getToken } from '@/utils/common';
import { useLogin } from '@/hooks/useLogin';
import { img } from '@/utils/common';
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
@ -141,7 +140,7 @@
if (diyComponent.value.elementAngle == 'right') {
return obj;
}
var defaultData = {
var defaultData:any = {
'row1-lt-of2-rt': [
['border-top-right-radius', 'border-bottom-right-radius'],
['border-top-left-radius', 'border-bottom-left-radius', 'border-bottom-right-radius'],
@ -242,7 +241,7 @@
}
const handleData = () => {
var singleRow = {
var singleRow:any = {
'row1-of2': {
ratio: 2,
width: 'calc((100% - ' + upx2px(diyComponent.value.imageGap * 2) + 'px) / 2)'
@ -281,7 +280,7 @@
* 比例原图高/原图宽示例322/690=0.46
* 高度宽度*比例示例187.5*0.46=86.25
*/
const calcSingleRow = (params) => {
const calcSingleRow = (params:any) => {
uni.getSystemInfo({
success: res => {
let maxHeight = 0;
@ -435,19 +434,6 @@
}
});
}
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)
}
}
</script>
<style lang="scss">

View File

@ -3,7 +3,7 @@
<view :style="maskLayer"></view>
<view class="diy-text relative">
<view v-if="diyComponent.style == 'style-1'" class=" px-[20rpx]">
<view @click="toRedirect(diyComponent.link)">
<view @click="diyStore.toRedirect(diyComponent.link)">
<view :style="{
fontSize: diyComponent.fontSize * 2 + 'rpx',
color: diyComponent.textColor,
@ -15,7 +15,7 @@
</view>
</view>
<view v-if="diyComponent.style == 'style-2'" class=" px-[20rpx] flex items-center">
<view @click="toRedirect(diyComponent.link)">
<view @click="diyStore.toRedirect(diyComponent.link)">
<view class="max-w-[200rpx] truncate" :style="{
fontSize: diyComponent.fontSize * 2 + 'rpx',
color: diyComponent.textColor,
@ -26,9 +26,9 @@
</view>
<text class="ml-[16rpx] max-w-[300rpx] truncate" :style="{ color: diyComponent.subTitle.color, fontSize: diyComponent.subTitle.fontSize * 2 + 'rpx', }">{{ diyComponent.subTitle.text }}</text>
<view class="ml-auto text-right " v-if="diyComponent.more.isShow" :style="{ color: diyComponent.more.color }">
<view @click="toRedirect(diyComponent.more.link)" class="flex items-center">
<text class="max-w-[200rpx] truncate text-[24rpx] mr-[8rpx]">{{ diyComponent.more.text }}</text>
<u-icon name="arrow-right" size="12" :style="{ color: diyComponent.more.color }"></u-icon>
<view @click="diyStore.toRedirect(diyComponent.more.link)" class="flex items-center">
<text class="max-w-[200rpx] truncate text-[24rpx]">{{ diyComponent.more.text }}</text>
<text class="nc-iconfont nc-icon-youV6xx text-[26rpx]" :style="{ color: diyComponent.more.color }"></text>
</view>
</view>
</view>
@ -40,8 +40,7 @@
//
import { ref, computed, watch,onMounted,nextTick,getCurrentInstance } from 'vue';
import useDiyStore from '@/app/stores/diy';
import { img,redirect,diyRedirect, currRoute, getToken } from '@/utils/common';
import { useLogin } from '@/hooks/useLogin';
import { img } from '@/utils/common';
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
const diyStore = useDiyStore();
@ -124,19 +123,6 @@
}).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)
}
}
</script>
<style lang="scss" scoped>

View File

@ -7,5 +7,6 @@
"selectAreaPlaceholder":"请选择地区",
"address": "详细地址",
"addressPlaceholder": "请填写详细地址",
"defaultAddress": "设为默认地址"
"defaultAddress": "设为默认地址",
"selectAddressPlaceholder":"请选择地址"
}

View File

@ -1,5 +1,5 @@
{
"cashOut": "提现",
"cashOutNow": "立即提现",
"balanceDetail": "余额明细",
"cashOutTo": "提现到",
"cashOutTypePlaceholder": "请选择提现方式",
@ -26,5 +26,5 @@
"applyMoneyBelow": "提现金额小于最低提现金额",
"replace": "更换",
"isOpenApply": "提现设置未开启",
"toAdd": "添加"
"toAdd": "添加"
}

View File

@ -3,9 +3,9 @@
"recharge": "充值",
"cashOut":"提现",
"balanceDetail": "余额明细",
"accountBalance":"账户余额(元)",
"balance":"余额(元)",
"money":"可提现余额(元)",
"accountBalance":"账户余额 (元)",
"balance":"余额 (元)",
"money":"可提现余额 (元)",
"availableBalance": "可用余额",
"rechargeAmountError": "充值金额错误",
"clickRecharge": "立即充值",

View File

@ -1,8 +1,9 @@
{
"recharge": "充值",
"cashOut":"提现",
"transferMoney":"提现",
"commissionDetail": "佣金明细",
"accountCommission":"账户佣金(元)",
"accountCommission":"当前佣金(元)",
"commission":"累计佣金(元)",
"money":"提现中佣金(元)",
"availableCommission": "可用佣金",

View File

@ -10,11 +10,11 @@
<view class="px-[60rpx]">
<u-form labelPosition="left" :model="formData" errorType='toast' :rules="rules" ref="formRef">
<u-form-item label="" prop="mobile" :border-bottom="true">
<u-input v-model="formData.mobile" border="none" clearable :placeholder="t('mobilePlaceholder')"/>
<u-input v-model="formData.mobile" border="none" clearable :placeholder="t('mobilePlaceholder')" class="!bg-transparent" :disabled="real_name_input"/>
</u-form-item>
<view class="mt-[40rpx]">
<u-form-item label="" prop="mobile_code" :border-bottom="true">
<u-input v-model="formData.mobile_code" border="none" type="password" clearable :placeholder="t('codePlaceholder')">
<u-input v-model="formData.mobile_code" border="none" clearable :placeholder="t('codePlaceholder')" class="!bg-transparent" :disabled="real_name_input">
<template #suffix>
<sms-code :mobile="formData.mobile" type="bind_mobile" v-model="formData.mobile_key"></sms-code>
</template>
@ -36,9 +36,7 @@
</view>
</view>
<view class="mt-[60rpx]">
<u-button type="primary" :loading="loading" :loadingText="t('binding')" @click="handleBind">
{{ t('bind') }}
</u-button>
<u-button type="primary" :text="t('bind')" :loading="loading" :loadingText="t('binding')" @click="handleBind"></u-button>
</view>
<!-- #ifdef MP-WEIXIN -->
<view class="mt-[30rpx]">
@ -58,7 +56,7 @@
</template>
<script setup lang="ts">
import { ref, reactive, computed } from 'vue'
import { ref, reactive, computed, onMounted } from 'vue'
import { t } from '@/locale'
import { bind } from '@/app/api/auth'
import { bindMobile } from '@/app/api/member'
@ -83,6 +81,14 @@
mobile_key: ''
})
let real_name_input = ref(true);
onMounted(() => {
//
setTimeout(()=>{
real_name_input.value = false;
},800)
});
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') }))
@ -90,7 +96,6 @@
const rules = {
'mobile': [
{
type: 'string',
required: true,
message: t('mobilePlaceholder'),
@ -148,10 +153,12 @@
})
}
const mobileAuth = (e) => {
if (!isAgree.value && !info.value && config.value.agreement_show) {
uni.showToast({ title: `${t('pleaceAgree')}${t('userAgreement')}》《${t('privacyAgreement')}`, icon: 'none' })
uni.showToast({
title: `${ t('pleaceAgree') }${ t('userAgreement') }》《${ t('privacyAgreement') }`,
icon: 'none'
})
return
}
@ -162,7 +169,6 @@
request({
openid: formData.openid,
unionid: formData.unionid || '',
mobile_code: e.detail.code
}).then((res) => {
uni.hideLoading()
@ -173,20 +179,27 @@
memberStore.setToken(res.data.token)
useLogin().handleLoginBack()
}
}).catch(() => {
uni.hideLoading()
}).catch((res) => {
setTimeout(() => {
uni.hideLoading()
}, 2000);
})
}
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'})
}
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>
<style lang="scss" scoped></style>
<style lang="scss">
.u-input{
background-color: transparent !important;
}
</style>

View File

@ -9,32 +9,29 @@
</view>
<view class="px-[60rpx] text-sm flex mb-[50rpx] font-bold leading-none" v-if="loginType.length > 1">
<block v-for="(item, index) in loginType">
<view :class="{'text-gray-300' : item.type != type}" @click="type = item.type">{{ item.title }}
</view>
<view class="mx-[30rpx] border-solid border-0 border-r-[2px] border-gray-300" v-show="index == 0">
</view>
<view :class="{'text-gray-300' : item.type != type}" @click="type = item.type">{{ item.title }}</view>
<view class="mx-[30rpx] border-solid border-0 border-r-[2px] border-gray-300" v-show="index == 0"></view>
</block>
</view>
<view class="px-[60rpx]">
<u-form labelPosition="left" :model="formData" errorType='toast' :rules="rules" ref="formRef">
<view v-show="type == 'username'">
<u-form-item label="" prop="username" :border-bottom="true">
<u-input v-model="formData.username" border="none" clearable :placeholder="t('usernamePlaceholder')"/>
<u-input v-model="formData.username" border="none" clearable :placeholder="t('usernamePlaceholder')" autocomplete="off" class="!bg-transparent" :disabled="real_name_input"/>
</u-form-item>
<view class="mt-[40rpx]">
<u-form-item label="" prop="password" :border-bottom="true">
<u-input v-model="formData.password" border="none" type="password" clearable :placeholder="t('passwordPlaceholder')"/>
<u-input v-model="formData.password" border="none" type="password" clearable :placeholder="t('passwordPlaceholder')" autocomplete="new-password" class="!bg-transparent" :disabled="real_name_input"/>
</u-form-item>
</view>
</view>
<view v-show="type == 'mobile'">
<u-form-item label="" prop="mobile" :border-bottom="true">
<u-input v-model="formData.mobile" border="none" clearable :placeholder="t('mobilePlaceholder')"/>
<u-input v-model="formData.mobile" border="none" clearable :placeholder="t('mobilePlaceholder')" autocomplete="off" class="!bg-transparent" :disabled="real_name_input"/>
</u-form-item>
<view class="mt-[40rpx]">
<u-form-item label="" prop="mobile_code" :border-bottom="true">
<u-input v-model="formData.mobile_code" border="none" type="password" clearable
:placeholder="t('codePlaceholder')">
<u-input v-model="formData.mobile_code" border="none" clearable class="!bg-transparent" :disabled="real_name_input" :placeholder="t('codePlaceholder')">
<template #suffix>
<sms-code :mobile="formData.mobile" type="login" v-model="formData.mobile_key"></sms-code>
</template>
@ -49,15 +46,14 @@
<view @click="redirect({ url: '/app/pages/auth/resetpwd' })">{{ t('resetpwd') }}</view>
</view>
<view class="mt-[80rpx]">
<u-button type="primary" :loading="loading" :loadingText="t('logining')" @click="handleLogin">
{{ t('login') }}
<u-button type="primary" :text="t('login')" :loading="loading" :loadingText="t('logining')" @click="handleLogin">
</u-button>
</view>
</u-form>
</view>
</view>
<view class="text-xs py-[50rpx] flex justify-center w-full" v-if="configStore.login.agreement_show">
<text class="iconfont text-[var(--primary-color)] text-[34rpx] mr-[12rpx]" :class="isAgree ? 'iconxuanze1' : 'iconcheckbox_nol'" @click="isAgree = !isAgree"></text>
<text class="iconfont text-[var(--primary-color)] text-[34rpx] mr-[12rpx]" :class="isAgree ? 'iconxuanze1' : 'nc-iconfont nc-icon-yuanquanV6xx'" @click="isAgree = !isAgree"></text>
{{ t('agreeTips') }}
<view @click="redirect({ url: '/app/pages/auth/agreement?key=service' })">
<text class="text-primary">{{ t('userAgreement') }}</text>
@ -71,7 +67,7 @@
</template>
<script setup lang="ts">
import { ref, reactive, computed } from 'vue'
import { ref, reactive, computed, onMounted } from 'vue'
import { usernameLogin, mobileLogin } from '@/app/api/auth'
import useMemberStore from '@/stores/member'
import useConfigStore from '@/stores/config'
@ -87,8 +83,18 @@
mobile_key: ''
})
uni.getStorageSync('openid') && (Object.assign(formData, { openid: uni.getStorageSync('openid') }))
uni.getStorageSync('unionid') && (Object.assign(formData, { unionid: uni.getStorageSync('unionid') }))
let real_name_input = ref(true);
onMounted(() => {
//
setTimeout(()=>{
real_name_input.value = false;
},800)
});
if (!uni.getStorageSync('autoLoginLock')) {
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()
@ -163,7 +169,6 @@
login(formData).then((res) => {
memberStore.setToken(res.data.token)
uni.removeStorageSync('pid');
useLogin().handleLoginBack()
}).catch(() => {
loading.value = false
@ -172,4 +177,8 @@
}
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.u-input{
background-color: transparent !important;
}
</style>

View File

@ -18,29 +18,29 @@
<view v-show="type == 'username'">
<view class="mt-[30rpx]">
<u-form-item label="" prop="username" :border-bottom="true">
<u-input v-model="formData.username" border="none" clearable :placeholder="t('usernamePlaceholder')"/>
<u-input v-model="formData.username" border="none" clearable :placeholder="t('usernamePlaceholder')" class="!bg-transparent" :disabled="real_name_input"/>
</u-form-item>
</view>
<view class="mt-[30rpx]">
<u-form-item label="" prop="password" :border-bottom="true">
<u-input v-model="formData.password" border="none" type="password" clearable :placeholder="t('passwordPlaceholder')"/>
<u-input v-model="formData.password" border="none" type="password" clearable :placeholder="t('passwordPlaceholder')" class="!bg-transparent" :disabled="real_name_input"/>
</u-form-item>
</view>
<view class="mt-[30rpx]">
<u-form-item label="" prop="confirm_password" :border-bottom="true">
<u-input v-model="formData.confirm_password" border="none" type="password" clearable :placeholder="t('confirmPasswordPlaceholder')"/>
<u-input v-model="formData.confirm_password" border="none" type="password" clearable :placeholder="t('confirmPasswordPlaceholder')" class="!bg-transparent" :disabled="real_name_input"/>
</u-form-item>
</view>
</view>
<view v-show="type == 'mobile' || configStore.login.is_bind_mobile">
<view class="mt-[30rpx]">
<u-form-item label="" prop="mobile" :border-bottom="true">
<u-input v-model="formData.mobile" border="none" clearable :placeholder="t('mobilePlaceholder')"/>
<u-input v-model="formData.mobile" border="none" clearable :placeholder="t('mobilePlaceholder')" class="!bg-transparent" :disabled="real_name_input"/>
</u-form-item>
</view>
<view class="mt-[30rpx]">
<u-form-item label="" prop="code" :border-bottom="true">
<u-input v-model="formData.mobile_code" border="none" type="password" clearable :placeholder="t('codePlaceholder')">
<u-input v-model="formData.mobile_code" border="none" clearable :placeholder="t('codePlaceholder')" class="!bg-transparent" :disabled="real_name_input">
<template #suffix>
<sms-code :mobile="formData.mobile" type="register" v-model="formData.mobile_key"></sms-code>
</template>
@ -51,7 +51,7 @@
<view v-show="type == 'username'">
<view class="mt-[30rpx]">
<u-form-item label="" prop="captcha_code" :border-bottom="true">
<u-input v-model="formData.captcha_code" border="none" clearable :placeholder="t('captchaPlaceholder')">
<u-input v-model="formData.captcha_code" border="none" clearable :placeholder="t('captchaPlaceholder')" class="!bg-transparent" :disabled="real_name_input">
<template #suffix>
<image :src="captcha.image.value" class="h-[48rpx] ml-[20rpx]" mode="heightFix" @click="captcha.refresh()"></image>
</template>
@ -63,15 +63,14 @@
<view @click="redirect({ url: '/app/pages/auth/login' })">{{ t('haveAccount') }}<text class="text-primary">{{ t('toLogin') }}</text></view>
</view>
<view class="mt-[80rpx]">
<u-button type="primary" :loading="loading" :loadingText="t('registering')" @click="handleregister">
{{ t('register') }}
<u-button type="primary" :text="t('register')" :loading="loading" :loadingText="t('registering')" @click="handleRegister">
</u-button>
</view>
</u-form>
</view>
</view>
<view class="text-xs py-[50rpx] flex justify-center w-full" v-if="configStore.login.agreement_show">
<text class="iconfont text-[var(--primary-color)] text-[34rpx] mr-[12rpx]" :class="isAgree ? 'iconxuanze1' : 'iconcheckbox_nol'" @click="isAgree = !isAgree"></text>
<text class="iconfont text-[var(--primary-color)] text-[34rpx] mr-[12rpx]" :class="isAgree ? 'iconxuanze1' : 'nc-iconfont nc-icon-yuanquanV6xx'" @click="isAgree = !isAgree"></text>
{{ t('registerAgreeTips') }}
<view @click="redirect({ url: '/app/pages/auth/agreement?key=service' })">
<text class="text-primary">{{ t('userAgreement') }}</text>
@ -85,7 +84,7 @@
</template>
<script setup lang="ts">
import { ref, reactive, computed } from 'vue'
import { ref, reactive, computed, onMounted } from 'vue'
import { usernameRegister, mobileRegister } from '@/app/api/auth'
import useMemberStore from '@/stores/member'
import useConfigStore from '@/stores/config'
@ -105,8 +104,18 @@
captcha_code: ''
})
uni.getStorageSync('openid') && (Object.assign(formData, { openid: uni.getStorageSync('openid') }))
uni.getStorageSync('pid') && (Object.assign(formData, { pid: uni.getStorageSync('pid') }))
let real_name_input = ref(true);
onMounted(() => {
//
setTimeout(()=>{
real_name_input.value = false;
},800)
});
if (!uni.getStorageSync('autoLoginLock')) {
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)
@ -191,7 +200,7 @@
const formRef = ref(null)
const handleregister = () => {
const handleRegister = () => {
formRef.value.validate().then(() => {
if (configStore.login.agreement_show && !isAgree.value) {
uni.showToast({ title: t('isAgreeTips'), icon: 'none' });
@ -204,7 +213,6 @@
register(formData).then((res: responseResult) => {
memberStore.setToken(res.data.token)
uni.removeStorageSync('pid');
useLogin().handleLoginBack()
}).catch(() => {
loading.value = false
@ -214,4 +222,8 @@
}
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.u-input{
background-color: transparent !important;
}
</style>

View File

@ -12,12 +12,12 @@
<u-form labelPosition="left" :model="formData" errorType='toast' :rules="rules" ref="formRef">
<view class="mt-[30rpx]">
<u-form-item label="" prop="mobile" :border-bottom="true">
<u-input v-model="formData.mobile" border="none" clearable :placeholder="t('mobilePlaceholder')"/>
<u-input v-model="formData.mobile" border="none" clearable :placeholder="t('mobilePlaceholder')" class="!bg-transparent" :disabled="real_name_input"/>
</u-form-item>
</view>
<view class="mt-[30rpx]">
<u-form-item label="" prop="code" :border-bottom="true">
<u-input v-model="formData.mobile_code" border="none" type="password" clearable :placeholder="t('codePlaceholder')">
<u-input v-model="formData.mobile_code" border="none" clearable :placeholder="t('codePlaceholder')" class="!bg-transparent" :disabled="real_name_input">
<template #suffix>
<sms-code :mobile="formData.mobile" type="find_pass" v-model="formData.mobile_key"></sms-code>
</template>
@ -26,17 +26,16 @@
</view>
<view class="mt-[30rpx]">
<u-form-item label="" prop="password" :border-bottom="true">
<u-input v-model="formData.password" border="none" type="password" clearable :placeholder="t('passwordPlaceholder')"/>
<u-input v-model="formData.password" border="none" type="password" clearable :placeholder="t('passwordPlaceholder')" class="!bg-transparent" :disabled="real_name_input"/>
</u-form-item>
</view>
<view class="mt-[30rpx]">
<u-form-item label="" prop="confirm_password" :border-bottom="true">
<u-input v-model="formData.confirm_password" border="none" type="password" clearable :placeholder="t('confirmPasswordPlaceholder')"/>
<u-input v-model="formData.confirm_password" border="none" type="password" clearable :placeholder="t('confirmPasswordPlaceholder')" class="!bg-transparent" :disabled="real_name_input"/>
</u-form-item>
</view>
<view class="mt-[80rpx]">
<u-button type="primary" :loading="loading" :loadingText="t('confirm')" @click="handleConfirm">
{{ t('confirm') }}
<u-button type="primary" :text="t('confirm')" :loading="loading" :loadingText="t('confirm')" @click="handleConfirm">
</u-button>
</view>
</u-form>
@ -46,7 +45,7 @@
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { ref, reactive, onMounted } from 'vue'
import { t } from '@/locale'
import { resetPassword } from '@/app/api/system'
import { redirect } from '@/utils/common'
@ -59,6 +58,14 @@
confirm_password: ''
})
let real_name_input = ref(true);
onMounted(() => {
//
setTimeout(()=>{
real_name_input.value = false;
},800)
});
const loading = ref(false)
const formRef = ref(null)
@ -121,4 +128,8 @@
}
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.u-input{
background-color: transparent !important;
}
</style>

View File

@ -1,7 +1,6 @@
<template>
<view class="w-screen h-screen flex flex-col items-center justify-center" :style="themeColor()">
<u-empty :icon="img('static/resource/images/site/close.png')" :text="t('siteClose')">
</u-empty>
<u-empty :icon="img('static/resource/images/site/close.png')" :text="t('siteClose')"></u-empty>
</view>
</template>

View File

@ -13,8 +13,7 @@
<text class="mb-[20rpx]">{{ t('siteId') }}</text>
<u-input v-model="formData.siteId" clearable :placeholder="t('siteIdPlaceholder')" />
</view>
<u-button type="primary" @click="save" class="mt-[80rpx]">
{{ t('confirm') }}
<u-button type="primary" :text="t('confirm') " @click="save" class="mt-[80rpx]">
</u-button>
</view>
</template>
@ -35,11 +34,13 @@
uni.showToast({ title: t('siteIdPlaceholder'), icon: 'none' });
return;
}
var reg = /^[0-9]+$/;
if (!reg.test(formData.siteId)) {
uni.showToast({ title: t('pleaseEnterNumber'), icon: 'none' });
return;
}
// if (formData.siteId > 9999999) {
// uni.showToast({ title: t('maximumCannotExceed') + '9999999', icon: 'none' });
// return;

View File

@ -36,15 +36,12 @@
import diyGroup from '@/addon/components/diy/group/index.vue'
import fixedGroup from '@/addon/components/fixed/group/index.vue'
const {setShare, onShareAppMessage, onShareTimeline} = useShare()
const {setShare} = useShare()
const diy = useDiy({})
const diyGroupRef = ref(null)
onShareAppMessage()
onShareTimeline()
//
diy.onLoad();
@ -63,4 +60,17 @@
</script>
<style lang="scss" scoped>
@import '@/styles/diy.scss';
</style>
<style lang="scss">
.diy-template-wrap {
/* #ifdef MP */
.child-diy-template-wrap {
::v-deep .diy-group {
> .draggable-element.top-fixed-diy {
display: block !important;
}
}
}
/* #endif */
}
</style>

View File

@ -32,23 +32,16 @@
<script setup lang="ts">
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()
const diy = useDiy({
name: 'DIY_INDEX'
})
const diyGroupRef = ref(null)
setShare();
onShareAppMessage()
onShareTimeline()
//
diy.onLoad();
@ -73,4 +66,17 @@
</script>
<style lang="scss" scoped>
@import '@/styles/diy.scss';
</style>
<style lang="scss">
.diy-template-wrap {
/* #ifdef MP */
.child-diy-template-wrap {
::v-deep .diy-group {
> .draggable-element.top-fixed-diy {
display: block !important;
}
}
}
/* #endif */
}
</style>

View File

@ -1,13 +1,12 @@
<template>
<view class="w-screen h-screen flex flex-col items-center justify-center" :style="themeColor()">
<u-empty :icon="img('static/resource/images/site/close.png')" :text="t('noSite')">
</u-empty>
</view>
<view class="w-screen h-screen flex flex-col items-center justify-center" :style="themeColor()">
<u-empty :icon="img('static/resource/images/site/close.png')" :text="t('noSite')"></u-empty>
</view>
</template>
<script setup lang="ts">
import { img } from '@/utils/common'
import { t } from '@/locale'
import { img } from '@/utils/common'
import { t } from '@/locale'
</script>
<style lang="scss" scoped></style>

View File

@ -1,25 +1,31 @@
<template>
<view class="w-screen h-screen bg-page" :style="themeColor()">
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="getCashoutAccountListFn">
<view class="h-[20rpx]"></view>
<view class="p-[30rpx] bg-white mx-[32rpx] my-[20rpx] rounded flex" v-for="(item, index) in accountList" :key="index" @click="handleClick(item)">
<view class="w-[100rpx] h-[100rpx] flex items-center justify-center mr-[10rpx]">
<image
src="data:image/png;base64,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"
mode="widthFix" class="w-[80rpx]" v-if="item.account_type == 'bank'"></image>
<text class="iconfont iconzhifubaoxuanzhong text-[#188dfb] text-[80rpx]" v-else></text>
</view>
<view>
<view>{{ item.account_type == 'bank' ? item.bank_name : t('alipayAccountNo') }}</view>
<view v-if="item.account_type == 'bank'" class="text-sm text-gray-subtitle mt-[10rpx]">{{ t('endNumber') }} {{ item.account_no.substring(item.account_no.length - 4) }}{{ t('bankCard') }}</view>
<view v-else class="text-sm text-gray-subtitle mt-[10rpx]">{{ item.account_no }}</view>
</view>
</view>
<view class="p-[30rpx] bg-white mx-[32rpx] my-[20rpx] rounded flex" @click="redirect({ url: '/app/pages/member/account_edit', param: { type: accountType, mode } })">
<u-icon name="plus" color="#333" size="16"></u-icon>
<text class="text-sm ml-[10rpx] flex-1">{{ accountType == 'bank' ? t('addBankCard') : t('addAlipayAccount') }}</text>
<u-icon name="arrow-right" color="#333" size="14"></u-icon>
</view>
<view class="h-[20rpx]"></view>
<u-swipe-action-item :options="accountOptions" @click="swipeClick(index)" v-for="(item, index) in accountList" :key="index" class="mx-[32rpx] my-[20rpx]">
<view class="p-[30rpx] bg-white rounded flex justify-between" >
<view class="flex">
<view class="w-[100rpx] h-[100rpx] flex items-center justify-center mr-[10rpx]" @click="handleClick(item)">
<image
src="data:image/png;base64,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"
mode="widthFix" class="w-[80rpx]" v-if="item.account_type == 'bank'"></image>
<text class="iconfont iconzhifubaoxuanzhong text-[#188dfb] text-[80rpx]" v-else></text>
</view>
<view @click="handleClick(item)">
<view>{{ item.account_type == 'bank' ? item.bank_name : t('alipayAccountNo') }}</view>
<view v-if="item.account_type == 'bank'" class="text-sm text-gray-subtitle mt-[10rpx]">{{ t('endNumber') }} {{ item.account_no.substring(item.account_no.length - 4) }}{{ t('bankCard') }}</view>
<view v-else class="text-sm text-gray-subtitle mt-[10rpx]">{{ item.account_no }}</view>
</view>
</view>
<text class="flex items-center nc-iconfont nc-icon-xiugaiV6xx shrink-0 text-[32rpx] p-[20rpx] pr-0" @click="editAccount(item)"></text>
</view>
</u-swipe-action-item>
<view class="p-[30rpx] bg-white mx-[32rpx] my-[20rpx] rounded flex" @click="redirect({ url: '/app/pages/member/account_edit', param: { type: accountType, mode } })">
<u-icon name="plus" color="#333" size="16"></u-icon>
<text class="text-sm ml-[10rpx] flex-1">{{ accountType == 'bank' ? t('addBankCard') : t('addAlipayAccount') }}</text>
<u-icon name="arrow-right" color="#333" size="14"></u-icon>
</view>
</mescroll-body>
</view>
</template>
@ -27,7 +33,7 @@
<script setup lang="ts">
import { ref } from 'vue'
import { redirect } from '@/utils/common'
import { getCashoutAccountList } from '@/app/api/member'
import { getCashoutAccountList, deleteCashoutAccount } from '@/app/api/member'
import MescrollBody from '@/components/mescroll/mescroll-body/mescroll-body.vue'
import useMescroll from '@/components/mescroll/hooks/useMescroll.js'
import { onPageScroll, onReachBottom, onLoad } from '@dcloudio/uni-app'
@ -67,6 +73,27 @@
mescroll.endErr(); // ,
})
}
const editAccount = (item: any)=> {
const url = `/app/pages/member/account_edit`
redirect({ url, param: { id : item.account_id, type : item.account_type, mode:mode.value} })
}
const accountOptions = ref([
{
text: t('delete'),
style: {
backgroundColor: '#F56C6C'
}
}
])
const swipeClick = (index: any) => {
const data = accountList.value[index]
deleteCashoutAccount(data.account_id).then(() => {
accountList.value.splice(index, 1)
}).catch()
}
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 }, mode: 'redirectTo' })

View File

@ -50,9 +50,6 @@
<view class="mt-[100rpx]">
<u-button :text="t('save')" type="primary" shape="circle" :loading="loading" @click="handleSave"></u-button>
<view class="mt-[30rpx]" v-if="formData.account_id">
<u-button :text="t('delete')" type="primary" shape="circle" :plain="true" :loading="loading" @click="deleteConfirm = true"></u-button>
</view>
</view>
</view>
</scroll-view>
@ -128,7 +125,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 } , mode: 'redirectTo'})
else redirect({ url: '/app/pages/member/apply_cash_out', param: { account_id: formData.account_id ? formData.account_id : res.data.id, type: formData.account_type } , mode: 'redirectTo'})
}).catch(() => {
loading.value = false
})

View File

@ -1,32 +1,11 @@
<template>
<view v-if="!loading" :style="themeColor()">
<view class="border-0 !border-b !border-[#eee] border-solid fixed top-0 left-0 right-0 z-99 bg-[#fff]" v-if="!source">
<u-tabs :list="tabs" @click="switchTab" :current="current" itemStyle="width:50%;height:88rpx;box-sizing: border-box;"></u-tabs>
</view>
<scroll-view scroll-y="true" :class="{ 'pt-[88rpx]' : !source }" >
<scroll-view scroll-y="true">
<u-swipe-action>
<view class="p-[30rpx]" v-show="current == 0">
<u-swipe-action-item :options="addressOptions" @click="swipeClick" v-for="item in addressList">
<view class="p-[30rpx]">
<u-swipe-action-item :options="addressOptions" @click="swipeClick(key)" v-for="(item, key) in addressList">
<view class="border-0 !border-b !border-[#f5f5f5] border-solid pb-[30rpx] flex items-center">
<view class="flex-1 line-feed" @click="selectAddress(item)">
<view class="font-bold my-[10rpx] text-sm line-feed">{{ item.full_address }}</view>
<view class="text-sm flex items-center">
<view>{{ item.name }}</view>
<text class="text-[26rpx] text-gray-subtitle">{{ mobileHide(item.mobile) }}</text>
<view class="bg-primary text-white text-xs px-[10rpx] leading-none flex items-center h-[32rpx] ml-[10rpx] rounded min-w-[50rpx]" v-if="item.is_default == 1">{{ t('default') }}</view>
</view>
</view>
<text class="iconfont iconbianji shrink-0 text-[40rpx] p-[20rpx] pr-0" @click="editAddress(item.id)"></text>
</view>
</u-swipe-action-item>
<view v-if="!addressList.length" class="pt-[20vh]">
<mescroll-empty :option="{tip : '暂无收货地址'}"></mescroll-empty>
</view>
</view>
<view class="p-[30rpx]" v-show="current == 1">
<u-swipe-action-item :options="addressOptions" @click="swipeClick" v-for="item in locationAddressList">
<view class="border-0 !border-b !border-[#f5f5f5] border-solid pb-[30rpx] flex items-center">
<view class="flex-1" @click="selectAddress(item)">
<view class="font-bold my-[10rpx] text-sm line-feed">{{ item.full_address }}</view>
<view class="text-sm flex items-center">
<view>{{ item.name }}</view>
@ -34,10 +13,10 @@
<view class="bg-primary text-white text-xs px-[10rpx] leading-none flex items-center h-[32rpx] ml-[10rpx] rounded min-w-[50rpx]" v-if="item.is_default == 1">{{ t('default') }}</view>
</view>
</view>
<text class="iconfont iconbianji shrink-0 text-[40rpx] p-[20rpx] pr-0" @click="editAddress(item.id)"></text>
<text class="nc-iconfont nc-icon-xiugaiV6xx shrink-0 text-[32rpx] p-[20rpx] pr-0" @click="editAddress(item.id)"></text>
</view>
</u-swipe-action-item>
<view v-if="!locationAddressList.length" class="pt-[20vh]">
<view v-if="!addressList.length" class="pt-[20vh]">
<mescroll-empty :option="{tip : '暂无收货地址'}"></mescroll-empty>
</view>
</view>
@ -61,10 +40,6 @@
const loading = ref(true)
const current = ref(0)
const tabs = ref([
{ name: '快递地址', key: 'address' },
{ name: '同城配送地址', key: 'location_address' }
])
const addressList = ref<object[]>([])
const locationAddressList = ref<object[]>([])
const type = ref('')
@ -81,25 +56,24 @@
data.forEach(item => {
item.type == 'address' ? address.push(item) : locationAddress.push(item)
})
addressList.value = address
locationAddressList.value = locationAddress
if(!source.value){ //使
addressList.value = data;
}else{ //
addressList.value = current.value == 0 ? address : locationAddress;
}
loading.value = false
}).catch(() => {
loading.value = false
})
const switchTab = (event)=> {
current.value = event.index
}
const addAddress = ()=> {
const url = `/app/pages/member/${tabs.value[ current.value ].key}_edit`
redirect({ url, param: { type: tabs.value[ current.value ].key, source : source.value } })
const url = `/app/pages/member/address_edit`
redirect({ url, param: { source : source.value } })
}
const editAddress = (id: number)=> {
const url = `/app/pages/member/${tabs.value[ current.value ].key}_edit`
redirect({ url, param: { id, type: tabs.value[ current.value ].key, source : source.value} })
const url = `/app/pages/member/address_edit`
redirect({ url, param: { id, source : source.value} })
}
const addressOptions = ref([
@ -126,14 +100,15 @@
}
}
const swipeClick = (event: any) => {
const swipeClick = (index: any) => {
const list = current.value ? locationAddressList : addressList
const data = list.value[event.index]
const data = list.value[index]
deleteAddress(data.id).then(() => {
list.value.splice(event.index, 1)
list.value.splice(index, 1)
}).catch()
}
</script>
<style lang="scss" scoped>

View File

@ -3,23 +3,37 @@
<u-form labelPosition="left" :model="formData" labelWidth="200rpx" errorType='toast' :rules="rules" ref="formRef">
<view class="mt-[10rpx]">
<u-form-item :label="t('name')" prop="name" :border-bottom="true">
<u-input v-model.trim="formData.name" border="none" clearable maxlength="25" :placeholder="t('namePlaceholder')"/>
<u-input fontSize="30rpx" v-model.trim="formData.name" border="none" clearable maxlength="25" :placeholder="t('namePlaceholder')"/>
</u-form-item>
</view>
<view class="mt-[10rpx]">
<u-form-item :label="t('mobile')" prop="mobile" :border-bottom="true">
<u-input v-model="formData.mobile" border="none" clearable :placeholder="t('mobilePlaceholder')"/>
<u-input fontSize="30rpx" v-model.trim="formData.mobile" border="none" clearable :placeholder="t('mobilePlaceholder')"/>
</u-form-item>
</view>
<view class="mt-[10rpx]">
<u-form-item :label="t('selectArea')" prop="area" :border-bottom="true" @click="selectArea">
<view v-if="!formData.area" class="text-gray-placeholder text-[30rpx]">{{ t('selectAreaPlaceholder') }}</view>
<view v-else class="text-[30rpx]">{{ formData.area }}</view>
<u-form-item :label="t('selectArea')" prop="area" :border-bottom="true" >
<view class="flex w-full items-center" v-if="addressType == 'address' && isSelectMap != 1" @click="selectArea">
<view v-if="!formData.area" class="text-gray-placeholder text-[30rpx] flex-1">{{ t('selectAreaPlaceholder') }}</view>
<view v-else class="text-[30rpx] flex-1">{{ formData.area }}</view>
<view @click.stop="chooseLocation" class="flex items-center">
<text class="nc-iconfont nc-icon-dizhiguanliV6xx mr-[4rpx] text-[32rpx] text-[#e93323]"></text>
<text class="text-[24rpx] whitespace-nowrap">定位</text>
</view>
</view>
<view v-else class="flex justify-between items-center flex-1" @click="chooseLocation">
<view class="text-[30rpx] text-[#303133]" v-if="formData.area || formData.address_name">{{formData.area || formData.address_name}}</view>
<view class="text-[#c3c4d5] text-[30rpx]" v-else>{{t('selectAddressPlaceholder')}}</view>
<view class="flex items-center">
<text class="nc-iconfont nc-icon-dizhiguanliV6xx text-[32rpx] mr-[4rpx] text-[#e93323]"></text>
<text class="text-[24rpx] whitespace-nowrap">定位</text>
</view>
</view>
</u-form-item>
</view>
<view class="mt-[10rpx]">
<u-form-item :label="t('address')" prop="address" :border-bottom="true">
<u-input v-model.trim="formData.address" border="none" clearable maxlength="120" :placeholder="t('addressPlaceholder')"/>
<u-input fontSize="30rpx" v-model.trim="formData.address" border="none" clearable maxlength="120" :placeholder="t('addressPlaceholder')"/>
</u-form-item>
</view>
<view class="mt-[10rpx]">
@ -31,7 +45,11 @@
<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"/>
<area-select ref="areaRef" @complete="areaSelectComplete" :area-id="formData.district_id" v-if="addressType == 'address'"/>
<!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 -->
<wx-privacy-popup ref="wxPrivacyPopup"></wx-privacy-popup>
<!-- #endif -->
</view>
</template>
@ -42,6 +60,8 @@
import { redirect } from '@/utils/common'
import { t } from '@/locale'
import { addAddress, editAddress, getAddressInfo } from '@/app/api/member'
import manifestJson from '@/manifest.json'
import { getAddressByLatlng } from '@/app/api/system'
const formData = ref({
id: 0,
@ -50,29 +70,52 @@
province_id: 0,
city_id: 0,
district_id: 0,
lat: '',
lng: '',
address: '',
address_name: '',
full_address: '',
is_default: 0,
area: '',
type: 'address'
area: ''
})
const areaRef = ref()
const formRef = ref(null)
const type = ref('')
const source = ref('')
const btnDisabled = ref(false)
let isSelectAddress = ref(false)
let addressType = ref('address');
let isSelectMap = ref(2) // 1
onLoad((data) => {
isSelectMap.value = data.isSelectMap || '';
const selectAddress = uni.getStorageSync('selectAddressCallback')
if (data.id) {
getAddressInfo(data.id)
.then(({ data }) => {
data && Object.assign(formData.value, data)
.then(res => {
res.data && Object.assign(formData.value, res.data)
//
addressType.value = res.data.lat&&res.data.lng ? 'locationAddress' : 'address';
//
if(selectAddress){
addressType.value = selectAddress.delivery == 'express' ? 'address' : 'locationAddress';
}
})
.catch()
}else if (data.name) {
if (uni.getStorageSync('addressInfo')) {
Object.assign(formData.value, uni.getStorageSync('addressInfo'))
}
formData.value.address = data.name;
getAddress(data.latng);
var tempArr = getQueryVariable('latng').split(',');
formData.value.lat = tempArr[0];
formData.value.lng = tempArr[1];
}
type.value = data.type || ''
source.value = data.source || ''
if(selectAddress){
addressType.value = selectAddress.delivery == 'express' ? 'address' : 'locationAddress';
}
})
const rules = computed(() => {
@ -103,7 +146,11 @@
],
'area': {
validator() {
return !uni.$u.test.isEmpty(formData.value.area)
let bool = true;
if(uni.$u.test.isEmpty(formData.value.area) && uni.$u.test.isEmpty(formData.value.address_name)){
bool = false;
}
return bool
},
message: t('selectAreaPlaceholder')
},
@ -115,22 +162,27 @@
}
}
})
const selectArea = () => {
isSelectAddress.value = true
areaRef.value.open()
}
const areaSelectComplete = (event) => {
if(isSelectAddress.value && (formData.value.province_id == event.province.id || formData.value.city_id != event.city.id || formData.value.district_id != event.district.id)){
formData.value.lat = '';
formData.value.lng = '';
}
formData.value.province_id = event.province.id || 0
formData.value.city_id = event.city.id || 0
formData.value.district_id = event.district.id || 0
formData.value.area = `${event.province.name || ''}${event.city.name || ''}${event.district.name || ''}`
isSelectAddress.value = false;
}
const operateLoading = ref(false)
const save = ()=> {
const save = formData.value.id ? editAddress : addAddress
formRef.value.validate().then(() => {
if (operateLoading.value) return
operateLoading.value = true
@ -138,16 +190,41 @@
btnDisabled.value = true
formData.value.full_address = formData.value.area + formData.value.address
if(isSelectMap.value == 1 && !formData.value.lat && !formData.value.lng){
uni.showToast({
title: '缺少经纬度,请在地图上重新选点',
icon: 'none'
});
operateLoading.value = false;
btnDisabled.value = false
return false;
}
save(formData.value).then((res) => {
operateLoading.value = false
setTimeout(() => {
btnDisabled.value = false
redirect({
url: '/app/pages/member/address',
mode: 'redirectTo',
param: {type: type.value, source: source.value}
})
if(source.value == 'shop_order_payment'){
const selectAddress = uni.getStorageSync('selectAddressCallback')
if (selectAddress) {
selectAddress.address_id = res.data.id || formData.value.id
uni.setStorage({
key: 'selectAddressCallback',
data: selectAddress,
success() {
redirect({url: selectAddress.back, mode: 'redirectTo'})
}
})
}
}else{
redirect({
url: '/app/pages/member/address',
mode: 'redirectTo',
param: {source: source.value}
})
}
}, 1000)
}).catch(() => {
operateLoading.value = false
@ -155,6 +232,84 @@
})
})
}
//
const chooseLocation = (data:Object = {})=> {
// #ifdef MP
uni.chooseLocation({
success: (res) => {
res.latitude && (formData.value.lat = res.latitude)
res.longitude && (formData.value.lng = res.longitude)
res.address && (formData.value.area = res.address)
res.name && (formData.value.address_name = res.address)
res.name && (formData.value.address = res.name)
if(res.latitude && res.longitude){
let latng = res.latitude+','+res.longitude;
getAddress(latng);
}
},
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
var urlencode = formData.value;
uni.setStorageSync('addressInfo', urlencode);
let backurl = location.origin + location.pathname + '?source=' + source.value;
if(isSelectMap.value){
backurl = backurl + '&isSelectMap=' + isSelectMap.value
}
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 getAddress = (latlng:any)=> {
getAddressByLatlng({latlng}).then((res: any) => {
if (res.data) {
formData.value.full_address = '';
formData.value.full_address += res.data.province != undefined ? res.data.province : '';
formData.value.full_address += res.data.city != undefined ? '' + res.data.city : '';
formData.value.full_address += res.data.district != undefined ? '' + res.data.district : '';
formData.value.address_name = formData.value.full_address.replace(/-/g,'');
formData.value.area = res.data.full_address;
formData.value.province_id = res.data.province_id != undefined ? res.data.province_id : 0;
formData.value.city_id = res.data.city_id != undefined ? res.data.city_id : 0;
formData.value.district_id = res.data.district_id != undefined ? res.data.district_id : 0;
} else {
uni.showToast({title: res.msg, icon: 'none'})
}
})
}
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;
}
</script>
<style lang="scss" scoped></style>

View File

@ -1,75 +1,69 @@
<template>
<view :style="themeColor()">
<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" />
<view class="px-[30rpx] pt-[20rpx]">
<view class="p-[20rpx] bg-white rounded-[16rpx]">
<view class="font-500 text-[32rpx] text-[#333] leading-[44rpx]">{{t('cashOutMoneyTip')}}</view>
<view class="flex pt-[30rpx] pb-[8rpx] items-center border-0 border-b-[2rpx] border-solid border-gray-200">
<text class="text-[54rpx] font-bold leading-[76rpx] ">{{ t('currency') }}</text>
<input type="digit" class="h-[76rpx] leading-[76rpx] pl-[10rpx] flex-1 font-bold text-[54rpx] bg-[#fff]" v-model="applyData.apply_money" maxlength="7" :placeholder="applyData.apply_money?'':(t('minWithdrawal') + t('currency') + moneyFormat(config.min))" placeholder-class="apply-price" :adjust-position="false"/>
<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 class="pt-[18rpx] flex items-center justify-between mb-[20rpx]">
<view class="text-[26rpx] text-[#666] leading-[36rpx]">
<text>{{t('money')}}{{ t('currency') }}{{ moneyFormat(cashOutMoney) }}</text>
<text>{{t('commissionTo')}}{{ config.rate + '%' }}</text>
</view>
<view class="text-[26rpx] text-primary leading-[36rpx]" @click="allMoney">{{t('allTx')}}</view>
</view>
</view>
<view class="px-[30rpx] bg-white mt-[30rpx]">
<view class="px-[20rpx] pt-[20rpx] pb-[30rpx] bg-white mt-[20rpx] rounded-[16rpx]">
<view class="font-500 text-[32rpx] text-[#333] leading-[44rpx] mb-[20rpx]">到账方式</view>
<!-- 提现到微信 -->
<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="p-[20rpx] mb-[20rpx] flex items-center rounded-[16rpx] border-[2rpx] border-solid border-[#eee]" v-if="config.transfer_type.includes('wechatpay') && memberStore.info && (memberStore.info.wx_openid || memberStore.info.weapp_openid)" @click="applyData.transfer_type = 'wechatpay'" :class="{'border-[#089C98] bg-[#F6FFFF]': applyData.transfer_type == 'wechatpay'}">
<view>
<image class="h-[60rpx] w-[60rpx]" :src="img('static/resource/images/member/apply_withdrawal/wechat.png')" mode="widthFix" />
</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 class="text-[28rpx] text-[#333] leading-[40rpx] mb-[6rpx]">{{ t('cashOutToWechat') }}</view>
<view class="text-[#999] text-[24rpx] leading-[34rpx]">{{ t('cashOutToWechatTips') }}</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 class="p-[20rpx] mb-[20rpx] flex items-center rounded-[16rpx] border-[2rpx] border-solid border-[#eee]" v-if="config.transfer_type.includes('alipay')" :class="{'border-[#089C98] bg-[#F6FFFF]': applyData.transfer_type == 'alipay' && alipayAccountInfo}" >
<view @click="transferAlipay" >
<image class="h-[60rpx] w-[60rpx] align-middle" :src="img('static/resource/images/member/apply_withdrawal/alipay-icon.png')" mode="widthFix" />
</view>
<view class="flex-1 px-[22rpx]" @click="transferAlipay" >
<view class="text-[28rpx] text-[#333] leading-[40rpx] mb-[6rpx]">{{ t('cashOutToAlipay') }}</view>
<view class="text-[#999] text-[24rpx] leading-[34rpx]">
<view v-if="alipayAccountInfo">
<text>{{ t('cashOutTo') }}{{ t('alipayAccountNo') }}</text>
<text class="text-[#333]">{{ alipayAccountInfo.account_no }}</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>
<u-button :plain="true" :text="t('toAdd')" type="primary" shape="circle" :custom-style="{height: '54rpx'}" v-if="!alipayAccountInfo && !alipayLoading" @click="redirect({ url: '/app/pages/member/account', param: { type: 'alipay', mode: 'select' } , mode: 'redirectTo'})"></u-button>
<text v-else class="nc-iconfont nc-icon-youV6xx text-[40rpx] text-[#999] p-[10rpx]" @click.stop="redirect({ url: '/app/pages/member/account', param: { type: 'alipay', mode: 'select' } , mode: 'redirectTo'})"></text>
</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,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"
mode="widthFix" class="w-[60rpx]"/>
<view class="p-[20rpx] flex items-center rounded-[16rpx] border-[2rpx] border-solid border-[#eee]" v-if="config.transfer_type.includes('bank')" :class="{'border-[#089C98] bg-[#F6FFFF]': applyData.transfer_type == 'bank' && bankAccountInfo}">
<view @click="transferBank" >
<image class="h-[42rpx] w-[60rpx] align-middle" :src="img('static/resource/images/member/apply_withdrawal/bank-icon.png')" mode="widthFix" />
</view>
<view class="flex-1 px-[20rpx]">
<view>{{ t('cashOutToBank') }}</view>
<view class="text-[#bbb] text-[26rpx] mt-[16rpx]">
<view class="flex-1 px-[20rpx]" @click="transferBank" >
<view class="text-[28rpx] text-[#333] leading-[40rpx] mb-[6rpx]">{{ t('cashOutToBank') }}</view>
<view class="text-[#999] text-[24rpx] leading-[34rpx]">
<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>
<text>{{ t('cashOutTo') }}{{ bankAccountInfo.bank_name }}{{ t('debitCard') }}</text>
<text class="text-[#333]">{{ bankAccountInfo.account_no.substring(bankAccountInfo.account_no.length - 4) }} </text>
</view>
<view v-else>
{{ t('cashOutToBankTips') }}
@ -77,19 +71,16 @@
</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>
<u-button :plain="true" :text="t('toAdd')" type="primary" shape="circle" :custom-style="{height: '56rpx'}" v-if="!bankAccountInfo && !bankLoading" @click="redirect({ url: '/app/pages/member/account', param: { type: 'bank', mode: 'select' }, mode: 'redirectTo' })"></u-button>
<text v-else class="nc-iconfont nc-icon-youV6xx text-[40rpx] text-[#999] p-[10rpx]" @click.stop="redirect({ url: '/app/pages/member/account', param: { type: 'bank', mode: 'select' }, mode: 'redirectTo' })"></text>
</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 class="mt-[100rpx]">
<u-button type="primary" shape="circle" :text="t('cashOutNow')" class="mb-[40rpx]" :disabled="applyData.apply_money == '' || applyData.apply_money == 0" :loading="loading" @click="cashOut" :customStyle="{background: 'linear-gradient( 94deg, #FB7939 0%, #FE120E 99%), #EF000C',fontSize:'32rpx'}"></u-button>
</view>
<view class="mt-[40rpx] text-center text-sm" @click="redirect({ url: '/app/pages/member/cash_out'})">
<view class="mt-[40rpx] text-center text-[26rpx] text-primary" @click.stop="redirect({ url: '/app/pages/member/cash_out'})">
{{t('cashOutList')}}
</view>
</view>
@ -126,7 +117,6 @@
return memberStore.info ? memberStore.info[ applyData.account_type ] : 0
})
watch(() => applyData.transfer_type, (nval) => {
switch (nval) {
case 'bank':
@ -153,6 +143,7 @@
onLoad(async (data) => {
query = data
uni.getStorageSync('cashOutAccountType') && (applyData.account_type = uni.getStorageSync('cashOutAccountType'))
if(getToken()){
@ -179,13 +170,16 @@
config.transfer_type.includes('bank') && getBankAccountInfo()
config.transfer_type.includes('alipay') && getAlipayAccountInfo()
applyData.transfer_type = config.transfer_type[0]
if(query.type){
applyData.transfer_type = query.type
}
pageLoading.value = false
})
})
//
const allMoney = () => {
applyData.apply_money = moneyFormat(cashOutMoney)
if(parseFloat(cashOutMoney.value)) applyData.apply_money = moneyFormat(cashOutMoney.value)
}
//
@ -220,8 +214,9 @@
/**
* 获取支付宝提现账号信息
*/
const alipayLoading = ref(false)
const alipayAccountInfo:any = ref(null)
const getAlipayAccountInfo = () => {
const getAlipayAccountInfo = () => {
const data = { account_type: 'alipay', account_id: 0 }
let request = getFirstCashoutAccountInfo
@ -229,7 +224,7 @@
request = getCashoutAccountInfo
data.account_id = query.account_id
}
alipayLoading.value = true
request(data).then(res => {
if (res.data && res.data.account_id) {
alipayAccountInfo.value = res.data
@ -238,12 +233,14 @@
applyData.account_id = alipayAccountInfo.value.account_id;
}
}
alipayLoading.value = false
})
}
/**
* 获取银行卡提现账号信息
*/
const bankLoading = ref(false)
const bankAccountInfo = ref(null)
const getBankAccountInfo = () => {
const data = { account_type: 'bank', account_id: 0 }
@ -253,14 +250,16 @@
request = getCashoutAccountInfo
data.account_id = query.account_id
}
bankLoading.value = true
request(data).then(res => {
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;
applyData.account_id = bankAccountInfo.value.account_id;
}
}
bankLoading.value = false
})
}
@ -272,17 +271,38 @@
if (loading.value) return
loading.value = true
cashOutApply(applyData)
.then(res => {
loading.value = false
redirect({ url: '/app/pages/member/cash_out' })
})
.catch(() => {
loading.value = false
})
cashOutApply(applyData).then(res => {
loading.value = false
redirect({ url: '/app/pages/member/cash_out' })
}).catch(() => {
loading.value = false
})
}
}
//
const transferAlipay = () => {
if(!alipayAccountInfo.value){
uni.showToast({ title: t('cashOutToAlipayTips'), icon: 'none' })
return false
}
applyData.transfer_type = 'alipay'
}
//
const transferBank = () => {
if(!bankAccountInfo.value){
uni.showToast({ title: t('cashOutToBankTips'), icon: 'none' })
return false
}
applyData.transfer_type = 'bank'
}
</script>
<style lang="scss" scoped>
:deep(.apply-price){
color:#999;
font-size: 26rpx;
font-weight: normal;
line-height: 76rpx;
}
</style>

View File

@ -1,88 +1,228 @@
<template>
<view :style="themeColor()">
<u-loading-page :loading="loading" loadingText=""></u-loading-page>
<view class="account-info-wrap" v-show="!loading">
<view class="account-info-head" :style="{ background: 'url(' + img('static/resource/images/member/balance_bg.png') + ') no-repeat 95% 30% / auto 250rpx, linear-gradient(314deg, #FE7849 0%, #FF1959 100%)'}">
<view class="name">{{t('balanceInfo')}}</view>
<view class="content">
<view class="money">
{{ memberStore.info ? moneyFormat((parseFloat(memberStore.info.balance) + parseFloat(memberStore.info.money)).toString()) : '0.00' }}
</view>
<view class="text">{{t('accountBalance')}}</view>
<view class="money-wrap">
<view class="money-item" @click="redirect({ url: '/app/pages/member/detailed_account', param: { type : 'balance' } })">
<view class="money">
{{ moneyFormat(memberStore.info?.balance)|| '0.00' }}
</view>
<view class="text leading-none">{{ t('balance') }}</view>
</view>
<view class="money-item" @click="redirect({ url: '/app/pages/member/detailed_account', param: { type : 'money' } })">
<view class="money">
{{ moneyFormat(memberStore.info?.money)|| '0.00' }}
</view>
<view class="text leading-none">{{ t('money') }}</view>
</view>
</view>
</view>
</view>
<view class="min-h-[100vh] !bg-[#F6F6F6]" :style="themeColor()" v-if="memberStore.info">
<view class="fixed w-full z-2 !bg-[#F6F6F6]">
<view class="pb-[203rpx] text-[#fff] w-full" :style="headerStyle">
<!-- #ifdef MP-WEIXIN -->
<top-tabbar :data="param" titleColor="#fff" class="top-header"/>
<!-- #endif -->
<view class="leading-[39rpx] text-[28rpx] pl-[53rpx] pt-[79rpx]">{{t('accountBalance')}}</view>
<view class="flex items-baseline pl-[53rpx]">
<text class="text-[40rpx] leading-[56rpx]"></text>
<text class="text-[70rpx] leading-[98rpx]">{{ memberStore.info ? moneyFormat((parseFloat(memberStore.info.balance) + parseFloat(memberStore.info.money)).toString()) : '0.00' }}</text>
</view>
</view>
<view class="mx-[30rpx] py-[30rpx] bg-[#fff] rounded-[16rpx] px-[40rpx] box-border w-[calc(100% - 60rpx)] mt-[-112rpx]">
<view class="flex flex-col items-center w-full" @click="redirect({ url: '/app/pages/member/detailed_account', param: { type : 'money' } })" :class="{'pt-[12rpx]': !Object.keys(cashOutConfigObj).length || (Object.keys(cashOutConfigObj).length && !systemStore.siteAddons.includes('recharge') && cashOutConfigObj.is_open != 1)}">
<view class=" text-[#999] text-[24rpx] leading-[34rpx] font-400">{{t('money')}}</view>
<view class="flex items-baseline text-[#333]">
<text class="text-[26rpx] leading-[36rpx]"></text>
<text class="text-[44rpx] leading-[62rpx] font-bold">{{ moneyFormat(memberStore.info?.money)|| '0.00' }}</text>
</view>
</view>
<view class="mt-[50rpx] flex justify-between" v-if="Object.keys(cashOutConfigObj).length && (systemStore.siteAddons.includes('recharge') || cashOutConfigObj.is_open == 1)">
<button :class="{'!w-[610rpx]': cashOutConfigObj.is_open != 1}" class="w-[280rpx] h-[66rpx] rounded-[40rpx] text-[30rpx] !bg-[#fff] !text-[var(--primary-color)] leading-[64rpx] !m-0 border-[2rpx] border-[var(--primary-color)] border-solid box-border" shape="circle" v-if="systemStore.siteAddons.includes('recharge')"
@click="redirect({url: '/addon/recharge/pages/recharge'})">充值</button>
<view v-if="cashOutConfigObj.is_open == 1" :class="{'!w-[610rpx]': !systemStore.siteAddons.includes('recharge')}" class="text-center w-[280rpx] h-[66rpx] rounded-[40rpx] text-[30rpx] !text-[#fff] leading-[66rpx] !m-0"
style="background: linear-gradient( 94deg, #FB7939 0%, #FE120E 99%), #EF000C;" shape="circle" @click="applyCashOut">{{t('cashOut')}}</view>
</view>
</view>
<view class=" box-border px-[30rpx] w-full mt-[20rpx]">
<scroll-view :scroll-x="true" scroll-with-animation :scroll-into-view="'id' + (subActive>3 ? subActive - 2 : 0)" class="!h-[100%]">
<view class="flex whitespace-nowrap">
<view :id="'id' + index" class="text-[26rpx] leading-[70rpx] text-[#666] font-400" :class="{ 'class-select': fromType === item.key,'ml-30rpx':index}" @click="fromTypeFn(item.key,index)" v-for="(item, index) in accountTypeList">{{ item.name }}</view>
</view>
</scroll-view>
</view>
</view>
<mescroll-body ref="mescrollRef" @init="mescrollInit" :down="{ use: false }" @up="getListFn" :top="mescrollTop">
<view class="px-[30rpx] pt-[20rpx] body-bottom" v-if="list.length">
<view v-for="(item,index) in list" :key="item.id" class="w-full h-[120rpx] flex justify-between items-center bg-[#fff] box-border p-[20rpx] rounded-[16rpx]" :class="{'mt-[20rpx]':index}">
<view class="flex items-center">
<view class="w-[80rpx] h-[80rpx] text-center rounded-[40rpx] text-[40rpx] font-bold leading-[80rpx] text-[#fff]"
:class="{'bg-[#EF000C]' :item.account_data > 0&&item.account_type!='money', 'bg-[#03B521]':item.account_data <= 0&&item.account_type!='money','bg-[#1379FF]':item.account_type=='money'}">
{{item.account_type=='money'?'提':item.account_data > 0?'收':'支'}}
</view>
<view class="flex flex-col ml-[20rpx]">
<view class="text-[#000] text-[26rpx] leading-[36rpx]">{{item.from_type_name}}</view>
<view class="text-[#999] text-[24rpx] leading-[34rpx] mt-[4rpx] font-400">{{item.create_time}}</view>
</view>
</view>
<view class="text-right">
<view class="text-[36rpx] leading-[50rpx]"
:class="{'text-[#EF000C]' :item.account_data > 0&&item.account_type!='money', 'text-[#03B521]':item.account_data <= 0&&item.account_type!='money'}">{{ item.account_data > 0 ? '+' + item.account_data : item.account_data }}</view>
<view class="text-[#999] text-[24rpx] leading-[34rpx] mt-[4rpx] font-400">
<text class="mr-[15rpx]">剩余余额</text>
<text>{{item.account_sum}}</text>
</view>
</view>
</view>
</view>
<view class="box-border pt-[20rpx] px-[30rpx] body-bottom" :style="{'height':'calc(100vh - '+mescrollTop +')'}" v-if="!list.length && !loading &&!listLoading">
<view class="h-full bg-[#fff] rounded-[16rpx] flex items-center justify-center">
<mescroll-empty></mescroll-empty>
</view>
</view>
<view class="account-info-btn">
<u-button type="primary" shape="circle" class="btn"
:customStyle="{backgroundColor: '#FE4E50',color: '#fff', borderColor: '#FE4E50',width: 'calc(100vw - 64rpx)'}"
v-if="systemStore.siteAddons.includes('recharge')"
@click="redirect({url: '/addon/recharge/pages/recharge'})">
<image class="max-w-[36rpx] max-h-[36rpx] mr-1" :src="img('static/resource/images/member/reset.png')" />
<text>{{t('recharge')}}</text>
</u-button>
<u-button v-if="cashOutConfigObj.is_open == 1" type="primary" :plain="true" shape="circle" class="btn" :customStyle="{backgroundColor: '#fff',color: '#FE4E50', borderColor: '#FE4E50',width: 'calc(100vw - 64rpx)'}" @click="applyCashOut">
<image class="max-w-[36rpx] max-h-[36rpx] mr-1" :src="img('static/resource/images/member/withdraw_deposit.png')" />
<text>{{t('cashOut')}}</text>
</u-button>
</view>
<pay ref="payRef" @close="rechargeLoading = false"></pay>
</view>
</mescroll-body>
<u-loading-page bg-color="rgb(248,248,248)" :loading="loading" loadingText="" fontSize="16" color="#303133"></u-loading-page>
<!-- <pay ref="payRef" @close="rechargeLoading = false"></pay> -->
</view>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { ref, reactive,computed } from 'vue'
import { t } from '@/locale'
import { moneyFormat, redirect, img } from '@/utils/common';
import { cashOutConfig } from '@/app/api/member';
import { onShow } from '@dcloudio/uni-app';
import { cashOutConfig,getBalanceListAll } from '@/app/api/member';
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 { onLoad,onShow, onPageScroll, onReachBottom } from '@dcloudio/uni-app';
import useMemberStore from '@/stores/member'
import useSystemStore from '@/stores/system'
const memberStore = useMemberStore(),
systemStore = useSystemStore()
const cashOutConfigObj = reactive({
is_auto_transfer: 0, //
is_auto_verify: 0, //
is_open: 0, //
min: 0, //
rate: 0, //
transfer_type: [] //
const { downCallback,mescrollInit, getMescroll } = useMescroll(onPageScroll, onReachBottom);
const memberStore = useMemberStore()
const systemStore = useSystemStore()
let param = ref({
title:'我的余额',
topStatusBar: {
style: 'style-1',
bgColor: 'transparent',
textColor: '#fff'
}
})
const loading = ref(true);
const cashOutConfigObj = reactive({})
onShow(() => {
cashOutConfig().then((res) => {
for (let key in res.data) {
cashOutConfigObj[key] = res.data[key];
}
loading.value = false;
})
cashOutConfig().then((res) => {
for (let key in res.data) {
cashOutConfigObj[key] = res.data[key];
}
})
})
//
let menuButtonInfo:any = {};
// (API)
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
// #endif
const headerStyle = computed(()=>{
return {
backgroundImage: 'url(' + img('static/resource/images/member/balance_bg.png') + ') ',
backgroundSize: 'cover',
backgroundRepeat: 'no-repeat',
backgroundPosition: 'bottom',
// paddingTop:Object.keys(menuButtonInfo).length?(Number(menuButtonInfo.height) * 2 + menuButtonInfo.top * 2 + 99)+'rpx':'99rpx',
}
})
const mescrollTop = computed(()=>{
return Object.keys(menuButtonInfo).length?(pxToRpx(Number(menuButtonInfo.height)) + pxToRpx(menuButtonInfo.top) +pxToRpx(8)+669)+'rpx':'669rpx'
})
// pxrpx
const pxToRpx=(px)=> {
const screenWidth = uni.getSystemInfoSync().screenWidth
return (750 * Number.parseInt(px)) / screenWidth
}
//
const accountTypeList = ref([
{name:'全部',key:''},
{name:'收入',key:'income'},
{name:'支出',key:'disburse'},
{name:'提现',key:'cash_out'},
])
const fromType = ref('')
//
const subActive = ref(0)
const fromTypeFn = (key,index)=>{
fromType.value = key
subActive.value = index
getMescroll().resetUpScroll();
}
const applyCashOut = () => {
uni.setStorageSync('cashOutAccountType', 'money')
redirect({ url: '/app/pages/member/apply_cash_out' })
}
const list = ref<Array<any>>([]),
loading = ref<boolean>(true),
listLoading = ref<boolean>(true),
mescrollRef = ref(null);
interface mescrollStructure {
num : number,
size : number,
endSuccess : Function,
[propName : string] : any
}
const getListFn = (mescroll : mescrollStructure) => {
listLoading.value = true;
let data : Object = {
page: mescroll.num,
limit: mescroll.size,
from_type:fromType.value
};
interface acceptingDataStructure {
data : acceptingDataItemStructure,
msg : string,
code : number
}
interface acceptingDataItemStructure {
data : object,
[propName : string] : number | string | object
}
getBalanceListAll(data).then((res : acceptingDataStructure) => {
let newArr = res.data.data;-
mescroll.endSuccess(newArr.length);
//
if (mescroll.num == 1) {
list.value = []; //
}
list.value = list.value.concat(newArr);
listLoading.value = false;
loading.value = false;
}).catch(() => {
listLoading.value = false;
loading.value = false;
mescroll.endErr(); // ,
})
}
</script>
<style lang="scss" scoped>
@import '@/styles/account_info.scss';
.class-select {
position: relative;
font-weight: 500;
color: var(--primary-color);
&::before {
content: "";
position: absolute;
bottom: 0;
height: 4rpx;
border-radius: 4rpx;
background-color: var(--primary-color);
width: 40rpx;
left: 50%;
transform: translateX(-50%);
}
}
:deep(.uni-scroll-view){
overflow: auto hidden !important;
}
.body-bottom{
padding-bottom: calc(20rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
}
.pl-20rpx{
padding-left: 20rpx;
}
</style>

View File

@ -18,9 +18,9 @@
<text class="label">{{t('createTime')}}</text>
<text class="value">{{ cashOutInfo.create_time }}</text>
</view>
<view class="line-wrap" v-if="cashOutInfo.status">
<view class="line-wrap" v-if="cashOutInfo.status && cashOutInfo.audit_time">
<text class="label">{{t('auditTime')}}</text>
<text class="value">{{ cashOutInfo.audit_time }}</text>
<text class="value">{{ cashOutInfo.audit_time }}</text>
</view>
<view class="line-wrap" v-if="cashOutInfo.transfer_bank">
<text class="label">{{t('transferBank')}}</text>
@ -38,7 +38,7 @@
<text class="label">{{t('transferTypeName')}}</text>
<text class="value">{{ cashOutInfo.transfer_type_name }}</text>
</view>
<view class="line-wrap" v-if="cashOutInfo.status == 2">
<view class="line-wrap" v-if="cashOutInfo.status == 2 && cashOutInfo.transfer_time">
<text class="label">{{t('transferTime')}}</text>
<text class="value">{{ cashOutInfo.transfer_time }}</text>
</view>

View File

@ -1,51 +1,197 @@
<template>
<view class="account-info-wrap" :style="themeColor()">
<view class="account-info-head" :style="{ background: 'url(' + img('static/resource/images/member/balance_bg.png') + ') no-repeat 95% 30% / auto 250rpx, linear-gradient(314deg, #FE7849 0%, #FF1959 100%)'}">
<view class="name">{{t('commissionInfo')}}</view>
<view class="content">
<view class="money" @click="redirect({ url: '/app/pages/member/detailed_account', param: { type : 'commission' } })">
{{ memberStore.info ? moneyFormat(memberStore.info.commission) : 0.00 }}
</view>
<view class="text" @click="redirect({ url: '/app/pages/member/detailed_account', param: { type : 'commission' } })">{{t('accountCommission')}}</view>
<view class="money-wrap">
<view class="money-item">
<view class="money">
{{ moneyFormat(memberStore.info?.commission_get)|| '0.00' }}
</view>
<view class="text">{{ t('commission') }}</view>
<view class="bg-[#F6F6F6] min-h-[100vh] w-full" :style="themeColor()" v-if="memberStore.info">
<view class="fixed w-full z-2 !bg-[#F6F6F6]">
<view class="pb-[174rpx]" :style="headerStyle">
<!-- #ifdef MP-WEIXIN -->
<top-tabbar :data="param" class="top-header"/>
<!-- #endif -->
<!-- <view class="pt-[18rpx] pb-[20rpx] pl-[30rpx] flex items-center" v-if="info">
<u-avatar :src="img(info.headimg)" :size="'60rpx'" leftIcon="none"></u-avatar>
<view class="ml-[12rpx] mr-[46rpx] text-[32rpx] font-bold text-[#333] leading-[38rpx]">{{info.nickname}}</view>
<view class="member-level pl-[30rpx] pr-[12rpx] py-[2rpx] font-400 text-[24rpx] text-[#fff] leading-[34rpx] relative">
<text>{{ info.member_level_name }}</text>
<image class="h-[40rpx] w-[36rpx] absolute top-0 left-[-20rpx] " :src="img('static/resource/images/member/commission/level_icon.png')" mode="heightFix" />
</view>
<view class="money-item">
<view class="money">
{{ moneyFormat(memberStore.info?.commission_cash_outing)|| '0.00' }}
</view> -->
</view>
<view class=" mt-[-114rpx] mx-[30rpx]" :style="{ backgroundImage: 'url(' + img('static/resource/images/member/commission/account_bg.png') + ')',backgroundRepeat:'no-repeat',backgroundSize:'100% 100%'}">
<view class="pt-[40rpx] pb-[20rpx]">
<view class="flex items-center justify-between px-[30rpx]">
<view>
<view class="text-[26rpx] font-500 text-[#fff] leading-[36rpx] mb-[8rpx]">{{t('accountCommission')}}</view>
<view class="text-[56rpx] font-bold text-[#fff] leading-[68rpx]">{{ memberStore.info ? moneyFormat(memberStore.info.commission) : 0.00 }}</view>
</view>
<u-button type="primary" :text="t('transferMoney')" :plain="true" shape="circle" :customStyle="{backgroundColor: '#fff',color: '#EF000C',width: '150rpx', height:'66rpx', lineHeight:'66rpx', margin:'0rpx',border:'none'}" @click="applyCashOut"></u-button>
</view>
<view class="h-[1rpx] bg-[#fff] opacity-30 mt-[80rpx] mb-[20rpx]"></view>
<view class="flex items-center px-[30rpx]">
<view class="flex-1">
<view class="font-bold text-[#fff] text-[36rpx] leading-[44rpx] mb-[6rpx]">
{{ moneyFormat(memberStore.info?.commission_get)|| '0.00' }}
</view>
<view class="text-[26rpx] text-[#fff] leading-[36rpx]">{{ t('commission') }}</view>
</view>
<view class="flex-1">
<view class="font-bold text-[#fff] text-[36rpx] leading-[44rpx] mb-[6rpx]">
{{ moneyFormat(memberStore.info?.commission_cash_outing)|| '0.00' }}
</view>
<view class="text-[26rpx] text-[#fff] leading-[36rpx]">{{ t('money') }}</view>
</view>
<view class="text">{{ t('money') }}</view>
</view>
</view>
</view>
<view class="mt-[40rpx] box-border px-[15rpx]">
<view class="flex whitespace-nowrap">
<view class="text-[26rpx] leading-[70rpx] text-[#666] font-400 px-[15rpx]" :class="{ 'class-select': fromType.from_type === item.from_type && fromType.account_data_gt === item.account_data_gt }" @click="fromTypeFn(item,index)" v-for="(item, index) in accountTypeList">{{ item.name }}</view>
</view>
</view>
</view>
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="geCommissiontListFn" :top="mescrollTop">
<view class="px-[30rpx] pt-[20rpx] body-bottom" v-if="list.length">
<view v-for="(item,index) in list" :key="item.id" class="w-full h-[120rpx] flex justify-between items-center bg-[#fff] box-border p-[20rpx] rounded-[16rpx]" :class="{'mt-[20rpx]':index}">
<view class="flex items-center">
<view class="w-[80rpx] h-[80rpx] text-center rounded-[40rpx] text-[40rpx] font-bold leading-[80rpx] text-[#fff]"
:class="{'bg-[#EF000C]' :item.account_data > 0, 'bg-[#1379FF]':item.account_data <= 0 }">
{{item.account_data > 0?'收':'提'}}
</view>
<view class="flex flex-col ml-[20rpx]">
<view class="text-[#333] text-[26rpx] leading-[36rpx]">{{item.from_type_name}}</view>
<view class="text-[#999] text-[24rpx] leading-[34rpx] mt-[4rpx] font-400">{{item.create_time}}</view>
</view>
</view>
<view class="text-[36rpx] leading-[50rpx]" :class="{'text-[#EF000C]' :item.account_data > 0, 'text-[#333]':item.account_data <= 0 }">{{ item.account_data > 0 ? '+' + item.account_data : item.account_data }}</view>
</view>
</view>
<view class="box-border pt-[20rpx] px-[30rpx] body-bottom" :style="{'height':'calc(100vh - '+mescrollTop +')'}" v-if="!list.length && !loading &&!listLoading">
<view class="h-full bg-[#fff] rounded-[16rpx] flex items-center justify-center">
<mescroll-empty></mescroll-empty>
</view>
</view>
<view class="account-info-btn">
<u-button type="primary" :plain="true" shape="circle" class="btn" :customStyle="{backgroundColor: '#fff',color: '#FE4E50', borderColor: '#FE4E50',width: 'calc(100vw - 64rpx)'}" @click="applyCashOut">
<image class="max-w-[36rpx] max-h-[36rpx] mr-1" :src="img('static/resource/images/member/withdraw_deposit.png')" />
<text>{{t('cashOut')}}</text>
</u-button>
</view>
</mescroll-body>
<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 { computed, ref } from 'vue'
import { t } from '@/locale'
import { moneyFormat, redirect, img } from '@/utils/common';
import useMemberStore from '@/stores/member'
import { getMemberCommission } from '@/app/api/member';
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 { onLoad, onPageScroll, onReachBottom } from '@dcloudio/uni-app';
const { downCallback,mescrollInit, getMescroll } = useMescroll(onPageScroll, onReachBottom);
const memberStore = useMemberStore();
const info = computed(() => memberStore.info)
//
const applyCashOut = ()=> {
uni.setStorageSync('cashOutAccountType', 'commission')
redirect({ url: '/app/pages/member/apply_cash_out' })
}
let param = ref({
title:'我的佣金',
topStatusBar: {
style: 'style-1',
bgColor: 'transparent',
textColor: '#333'
}
})
//
let menuButtonInfo:any = {};
// (API)
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
// #endif
const headerStyle = computed(()=>{
return {
backgroundImage: 'url(' + img('static/resource/images/member/commission/commission_bg.png') + ') ',
backgroundSize: 'cover',
backgroundRepeat: 'no-repeat',
backgroundPosition: 'center',
}
})
// 16padding-bottom
const mescrollTop = computed(()=>{
return Object.keys(menuButtonInfo).length?(Number(menuButtonInfo.height) * 2 + menuButtonInfo.top * 2 + 530 + 16)+'rpx':'530rpx'
})
//
const fromType = ref({
from_type:'',
account_data_gt:''
})
const accountTypeList = ref([
{name:'全部',from_type:'',account_data_gt: ''},
{name:'佣金',from_type:'',account_data_gt: 0},
{name:'提现',from_type:'cash_out',account_data_gt: ''},
])
const list = ref<Array<any>>([])
const loading = ref<boolean>(true)
const listLoading = ref<boolean>(true)
const mescrollRef = ref(null);
const fromTypeFn = (data : any ,index : number)=>{
fromType.value.from_type = data.from_type
fromType.value.account_data_gt = data.account_data_gt
getMescroll().resetUpScroll();
}
const geCommissiontListFn = (mescroll) => {
listLoading.value = true;
let data : Object = {
page: mescroll.num,
limit: mescroll.size,
from_type:fromType.value.from_type,
account_data_gt: fromType.value.account_data_gt
}
getMemberCommission(data).then((res:any) => {
let newArr = res.data.data;-
mescroll.endSuccess(newArr.length);
//
if (mescroll.num == 1) {
list.value = []; //
}
list.value = list.value.concat(newArr);
listLoading.value = false;
loading.value = false;
}).catch(() => {
listLoading.value = false;
loading.value = false;
mescroll.endErr(); // ,
})
}
</script>
<style lang="scss">
@import '@/styles/account_info.scss';
.member-level{
background: linear-gradient( 360deg, #F23621 11%, #FF7F71 100%), #D9D9D9;
border-radius: 0rpx 20rpx 20rpx 0rpx;
}
.class-select {
position: relative;
font-weight: 500;
color: var(--primary-color);
&::before {
content: "";
position: absolute;
bottom: 0;
height: 4rpx;
border-radius: 4rpx;
background-color: var(--primary-color);
width: 40rpx;
left: 50%;
transform: translateX(-50%);
}
}
:deep(.uni-scroll-view){
overflow: auto hidden !important;
}
.body-bottom{
padding-bottom: calc(20rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
}
</style>

View File

@ -30,11 +30,16 @@
</template>
<script setup lang="ts">
import {ref} from 'vue';
import {ref, computed} 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'
import useMemberStore from '@/stores/member'
//
const memberStore = useMemberStore()
const userInfo = computed(() => memberStore.info)
const diy = useDiy({
name: 'DIY_MEMBER_INDEX'
@ -56,6 +61,9 @@
redirect({url: data.page, mode: 'reLaunch'})
}
diyGroupRef.value?.refresh();
if (userInfo.value) {
useMemberStore().getMemberInfo()
}
});
//
@ -66,4 +74,17 @@
</script>
<style lang="scss" scoped>
@import '@/styles/diy.scss';
</style>
<style lang="scss">
.diy-template-wrap {
/* #ifdef MP */
.child-diy-template-wrap {
::v-deep .diy-group {
> .draggable-element.top-fixed-diy {
display: block !important;
}
}
}
/* #endif */
}
</style>

View File

@ -1,41 +1,39 @@
<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">
<view v-if="!loading && memberInfo && list && list.length" class=" min-h-[100vh] overflow-hidden flex flex-col" :style="{backgroundColor: currLevelInfo.level_style.bg_color }">
<!-- #ifdef MP -->
<top-tabbar :data="topTabbarData" titleColor="#fff"/>
<!-- #endif -->
<view class="pb-[36rpx]">
<view class="pt-[40rpx] pb-[70rpx]">
<view>
<view class="pt-[40rpx] mb-[20rpx]">
<!-- 轮播图 -->
<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">
<view class="relative">
<swiper class="swiper ns-indicator-dots relative" :style="{ height: '300rpx' }" @change="swiperChange" :current = "swiperIndex"
previous-margin="48rpx" next-margin="48rpx">
<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 class="h-[300rpx] relative">
<view v-if="memberInfo.member_level == item.level_id && swiperIndex == index" class="text-[24rpx] absolute top-0 left-0 z-10 h-[66rpx] !bg-contain w-[150rpx] flex pt-[12rpx] pl-[16rpx] leadinig-[34rpx] box-border" :style="{ background: 'url(' + img(currLevelInfo.level_tag) + ') no-repeat',color: currLevelInfo.level_style.level_color}">
当前等级
</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 v-else-if="Number(memberInfo.growth) < Number(currLevelInfo.growth) && swiperIndex == index" class="text-[24rpx] absolute top-0 left-0 z-10 h-[66rpx] !bg-contain w-[150rpx] text-[#999] flex pt-[12rpx] pl-[16rpx] leadinig-[34rpx] box-border" :style="{ background: 'url(' + img('static/resource/images/member/level/not_reach.png') + ') no-repeat'}" >
未达标
</view>
<view class="absolute top-0 left-0 right-0 bottom-0 z-20 px-[30rpx] pt-[76rpx] box-border" :class="{'px-[50rpx]': swiperIndex != index}">
<view class="flex items-center leading-[50rpx] mb-[70rpx]">
<image class="h-[32rpx] w-[34rpx] align-middle" :src="img(item.level_icon ? item.level_icon : '')" mode="aspectFill" />
<view class="text-[36rpx] font-bold ml-[10rpx] max-w-[340rpx] truncate" :style="{color:currLevelInfo.level_style.level_color}">{{item.level_name}}</view>
</view>
<view class="text-[#977B48] text-[26rpx] mt-[20rpx]">成长值已达到 {{memberInfo.growth}}</view>
<view class="flex justify-between items-center mt-[50rpx]">
<view class="flex items-center" :style="{color: currLevelInfo.level_style.level_color}">
<view class="text-[28rpx] font-bold leading-[38rpx]">{{ memberInfo.growth }}</view>
<view class="text-[24rpx] leading-[34rpx]">/{{list[index].growth}}成长值</view>
</view>
<view class="flex justify-between items-center mt-[10rpx]">
<view class="flex flex-col flex-1">
<view>
<progress :percent="progress(index)" :border-radius="100" activeColor="#DB9400" backgroundColor="#D9D9D9" stroke-width="6" />
<progress :percent="progress(index)" :border-radius="100" :activeColor="currLevelInfo.level_style.level_color" backgroundColor="#fff" 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">
@ -44,60 +42,63 @@
</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 class="mb-[30rpx] relative">
<view class="bg-[#fff] opacity-15 h-[2rpx] w-full absolute top-[15rpx]"></view>
<view :style="lineStyle" class="bg-[#fff] opacity-60 h-[2rpx] absolute top-[15rpx] z-4 left-[50%]"></view>
<view class="mx-[86rpx]">
<scroll-view :scroll-x="true" scroll-with-animation :scroll-into-view="'id' + ( levelIndex ? levelIndex - 1 : 0)">
<view class="flex flex-nowrap py-[10rpx]">
<block v-for="(item,index) in list" :key="item.id">
<view :style="levelStyle" class=" flex-shrink-0 flex flex-col items-center justify-center" @click="changeLevel(index)" :id="'id' + index">
<view class="w-[14rpx] h-[14rpx] level-class" :class="{'level-select': levelIndex == (index)}"></view>
<view :style="maxWidth" class="text-[24rpx] text-[#aaa] mt-[10rpx] truncate">{{item.level_name}}</view>
</view>
</block>
</view>
</scroll-view>
</view>
<view class="flex flex-wrap w-full mt-[46rpx]">
</view>
<view class="flex mx-[30rpx] px-[38rpx] pt-[30rpx] pb-[46rpx] items-center flex-col level_benefits" v-if="currLevelInfo.benefits_arr && currLevelInfo.benefits_arr.length" :style="{ backgroundImage: 'url(' + img(currLevelInfo.member_bg) + ')'}">
<view class="flex items-center justify-center">
<text class="text-[#fff] text-[32rpx] font-bold leading-[44rpx]">会员权益</text>
</view>
<view class="flex flex-wrap w-[690rpx] mt-[40rpx] justify-between">
<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 class="flex-1 rounded-t-[40rpx] px-[30rpx] pt-[30rpx] mt-[-16rpx] relative tab-bar" :style="{background: `linear-gradient( 180deg, ${currLevelInfo.level_style.gift} 0%, #FFFFFF 20%)`}">
<!-- 升级礼包 -->
<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 class="pt-[10rpx] pb-[30rpx] flex items-center">
<text class="text-[32rpx] text-[#3A3945] font-bold leading-[44rpx]">升级礼包</text>
</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 v-for="(item,index) in currLevelInfo.gifts_arr" :key="index" class="mb-[20rpx]" :class="{'mr-[20rpx]': (index+1) % 3 != 0}">
<view class="relative box-border mb-[12rpx] w-[216rpx] h-[180rpx] !bg-contain" :style="{ background: 'url(' + img(item.background) + ') no-repeat'}">
</view>
<view class="text-center text-[#333] text-[28rpx] font-500 truncate leading-[40rpx] max-w-[216rpx]">{{item.text}}</view>
</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 class="pt-[10rpx] pb-[30rpx] flex items-center">
<text class="text-[32rpx] text-[#333] font-bold leading-[44rpx]">升级技巧</text>
</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 class="text-[#3A3945] text-[28rpx] font-bold leading-[38rpx] mb-[8rpx]">{{item.title}}</view>
<view class="text-[24rpx] text-[#3A3945] leading-[34rpx]">{{item.desc}}</view>
</view>
<text class="skill-btn" @click="redirect({ url: item.button.wap_redirect, param: {} , mode: 'redirectTo'})">{{item.button.text}}</text>
</view>
@ -105,7 +106,7 @@
</view>
</view>
</view>
<u-empty v-if="!loading && (!list || !list.length)" :icon="img('static/resource/images/empty.png')" text="暂无会员等级" />
<u-empty v-if="!loading && !list && !list.length " :icon="img('static/resource/images/empty.png')" text="暂无会员等级" />
</view>
</template>
@ -122,12 +123,7 @@
let list = ref([]) //
let upgradeSkills = ref([]) //
const swiperIndex = ref(0); //
let isIndicatorDots = ref(true) //
// #ifdef MP
isIndicatorDots.value = false
// #endif
const levelIndex = ref(0); //
//
let topTabbarData = ref({
title: '会员等级',
@ -170,9 +166,12 @@
}
return num
}
const levelStyle = ref(''); //
const maxWidth = ref(''); //
const lineStyle = ref(''); // 线
const getMemberLevelFn = ()=>{
loading.value = true;
getMemberLevel().then((res) => {
list.value = res.data || [];
@ -183,12 +182,32 @@
if(item.level_id == memberInfo.value.member_level){
bool = false;
swiperIndex.value = index;
levelIndex.value = swiperIndex.value;
infoStructureFn(index);
}
})
}
if(bool) infoStructureFn(0);
if(list.value && list.value.length >= 5){
levelStyle.value ='width:115rpx;'
maxWidth.value = 'max-width:115rpx;'
lineStyle.value = `width:470rpx;transform: translateX(-235rpx);`
}else if(list.value && list.value.length == 4){
levelStyle.value ='width:144rpx;'
maxWidth.value = 'max-width:144rpx;'
lineStyle.value = `width:436rpx;transform: translateX(-218rpx);`
}else if(list.value && list.value.length == 3){
levelStyle.value ='width:192rpx;'
maxWidth.value = 'max-width:192rpx;'
lineStyle.value = `width:388rpx;transform: translateX(-194rpx);`
}else if(list.value && list.value.length == 2){
levelStyle.value ='width:289rpx;'
maxWidth.value = 'max-width:289rpx;'
lineStyle.value = `width:289rpx;transform: translateX(-144rpx);`
}else{
maxWidth.value = 'max-width:578rpx;'
levelStyle.value ='width:100%;'
}
loading.value = false;
}).catch(()=>{
loading.value = false;
@ -201,16 +220,16 @@
})
}
const swiperChange = e => {
const swiperChange = (e) => {
swiperIndex.value = e.detail.current;
levelIndex.value = swiperIndex.value
infoStructureFn(e.detail.current);
};
//
let currLevelInfo = ref({});
let currLevelInfo = ref<any>({});
let infoStructureFn = (index:number)=>{
let data = {}
data = deepClone(list.value[index]);
let data:any = deepClone(list.value[index]);
//
if(data && data.level_benefits){
data.benefits_arr = [];
@ -236,6 +255,12 @@
}
currLevelInfo.value = data;
}
//
const changeLevel = (index : any) =>{
levelIndex.value = index;
swiperIndex.value = index;
infoStructureFn(index);
}
</script>
<style lang="scss" scoped>
@ -243,66 +268,17 @@
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;
color: #333;
background: linear-gradient( 180deg, #FEE8AC 0%, #F5D36E 85%);
border-radius: 30rpx;
margin-left: auto;
font-size: 24rpx;
}
.swiper-animation{
transform: scale(0.94, 0.94);
transform: scale(0.92, 0.92);
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;
}
@ -311,12 +287,39 @@
padding-bottom: env(safe-area-inset-bottom);
}
.skewed-text-5 {
transform: skew(-5deg);
font-weight: 900;
.level-class{
position: relative;
&::before {
content: "";
position: absolute;
width: 14rpx;
height: 14rpx;
background-color: #aaa;
border-radius: 14rpx;
top:50%;
left: 50%;
transform: translate(-50%,-50%);
z-index: 10;
}
}
.skewed-text-10 {
transform: skew(-10deg);
font-weight: 900;
.level-select{
position: relative;
&::after {
content: "";
position: absolute;
width: 26rpx;
height: 26rpx;
background-color: #F6F6F6;
opacity: 0.4;
border-radius: 26rpx;
top:50%;
left: 50%;
transform: translate(-50%,-50%);
z-index: 1;
}
}
.level_benefits{
background-repeat: no-repeat;
background-size: 100% 100%;
}
</style>

View File

@ -239,7 +239,6 @@
var urlencode = formData.value;
uni.setStorageSync('addressInfo', urlencode);
let backurl = location.origin + location.pathname + '?type=' + type.value + '&source=' + source.value;
console.log('backurl',backurl)
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
}

View File

@ -1,53 +1,176 @@
<template>
<view class="bg-gray-100 min-h-[100vh]" :class="{'bg-[#fff]':!pointList.length}" :style="themeColor()">
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="getPointListFn">
<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]" :class="{ 'text-primary' : item.account_data > 0 }">{{item.account_data > 0 ? '+' + item.account_data : item.account_data}}</view>
<view class="bg-[#F6F6F6] min-h-[100vh]" :style="themeColor()">
<template v-if="!loading">
<view class="w-full bg-[#F6F6F6]">
<view class="pb-[210rpx] relative" :style="headerStyle">
<!-- #ifdef MP-WEIXIN -->
<top-tabbar :data="param" titleColor="#fff" class="top-header"/>
<!-- #endif -->
<view class="text-[70rpx] leading-[98rpx] text-[#fff] pl-[60rpx] font-600 pt-[77rpx]">{{pointInfo.point||0}}</view>
<view class="flex items-center pl-[60rpx]">
<image class="h-[36rpx] w-[36rpx]" :src="img('static/resource/images/member/point/icon.png')" mode="heightFix" />
<view class="text-[26rpx] leading-[36rpx] text-[#fff] ml-[10rpx]">我的积分</view>
</view>
<view class="flex items-center absolute right-0 px-[14rpx] bg-color rounded-l-[35rpx] text-[#fff] text-[24rpx] h-[50rpx] z-10" :style="{top: topStyle}" @click="toLink('/app/pages/member/point_detail')">
<text class="nc-iconfont nc-icon-meiriqiandaoV6xx text-[28rpx] text-[#fff] mr-[4rpx]"></text>
<text class="text-[24rpx]">积分明细</text>
</view>
</view>
<mescroll-empty v-if="!pointList.length && loading"></mescroll-empty>
</mescroll-body>
<view class="mx-[30rpx] flex flex-col mt-[-178rpx] relative">
<view class="w-[322rpx] h-[80rpx] leading-[80rpx] text-[26rpx] text-[#333] font-bold box-border pl-[30rpx]"
:style="{backgroundImage: 'url(' + img('static/resource/images/member/point/top_bg.png') + ') ',backgroundSize: '100% 100%',backgroundRepeat: 'no-repeat'}">
积分详情
</view>
<view class="flex items-center w-[690rpx] px-[30rpx] rounded-[16rpx] !rounded-tl-none bg-[#fff] h-[173rpx] box-border">
<view class="w-[196rpx] flex-shrink-0 text-center">
<view class="text-[#333] text-[42rpx] leading-[59rpx] font-bold">{{pointInfo.point_get||0}}</view>
<view class="mt-[8rpx] text-[#666] text-[26rpx] leading-[36rpx] font-400">累计积分</view>
</view>
<view class="w-[1rpx] h-[50rpx] flex-shrink-0 bg-[#EBEBEB] mx-[10rpx]"></view>
<view class="w-[196rpx] flex-shrink-0 text-center">
<view class="text-[#333] text-[42rpx] leading-[59rpx] font-bold">{{pointInfo.use||0}}</view>
<view class="mt-[8rpx] text-[#666] text-[26rpx] leading-[36rpx] font-400">累计消费</view>
</view>
<view class="w-[1rpx] h-[50rpx] flex-shrink-0 bg-[#EBEBEB] mx-[10rpx]"></view>
<view class="w-[196rpx] min-w-[209.33rpx] flex-shrink-0 text-center">
<view class="text-[#333] text-[42rpx] leading-[59rpx] font-bold">{{pointInfo.point||0}}</view>
<view class="mt-[8rpx] text-[#666] text-[26rpx] leading-[36rpx] font-400">可用积分</view>
</view>
</view>
</view>
</view>
<view class="mt-[20rpx] mx-[30rpx] p-[30rpx] pb-[70rpx] box-border rounded-[16rpx] bg-[#fff]">
<view class="text-[32rpx] leading-[45rpx] font-bold">热门活动</view>
<view class="mt-[50rpx] flex justify-between">
<view class="w-[200rpx] h-[253rpx] box-border pt-[69rpx] relative text-center"
:style="{backgroundImage: 'url(' + img('static/resource/images/member/point/activity_1.png') + ') ',
backgroundSize: '100% 100%',
backgroundRepeat: 'no-repeat'}">
<image class="h-[78rpx] w-[78rpx] absolute left-[65rpx] top-[-21rpx]" :src="img('static/resource/images/member/point/activity_icon_1.png')" mode="heightFix" />
<view class="text-[28rpx] leading-[39rpx] text-[#333]">每日赚积分</view>
<view class="mt-[10rpx] text-[24rpx] leading-[34rpx] text-[#999] font-500">每日签到</view>
<view class="w-full flex justify-center mt-[20rpx]">
<button class="h-[40rpx] !m-0 rounded-[40rpx] text-[26rpx] leading-[40rpx] !text-[#fff] !" shape="circle"
:style="{background: 'linear-gradient( 94deg, #FB7939 0%, #FE120E 99%), #EF000C'}" @click="toLink('/app/pages/member/sign_in')">去签到</button>
</view>
</view>
<view class="w-[200rpx] h-[253rpx] box-border pt-[69rpx] relative text-center"
:style="{backgroundImage: 'url(' + img('static/resource/images/member/point/activity_2.png') + ') ',
backgroundSize: '100% 100%',
backgroundRepeat: 'no-repeat'}">
<image class="h-[78rpx] w-[78rpx] absolute left-[65rpx] top-[-21rpx]" :src="img('static/resource/images/member/point/activity_icon_2.png')" mode="heightFix" />
<view class="text-[28rpx] leading-[39rpx] text-[#333]">积分当钱花</view>
<view class="mt-[10rpx] text-[24rpx] leading-[34rpx] text-[#999] font-500">抵扣部分费用</view>
<view class="w-full flex justify-center mt-[20rpx]">
<button class="h-[40rpx] !m-0 rounded-[40rpx] text-[26rpx] leading-[40rpx] !text-[#fff] !" shape="circle"
:style="{background: 'linear-gradient( 94deg, #FB7939 0%, #FE120E 99%), #EF000C'}" @click="toLink('/addon/shop/pages/point/index')">去兑换</button>
</view>
</view>
<view class="w-[200rpx] h-[253rpx] box-border pt-[69rpx] relative text-center"
:style="{backgroundImage: 'url(' + img('static/resource/images/member/point/activity_3.png') + ') ',
backgroundSize: '100% 100%',
backgroundRepeat: 'no-repeat'}">
<image class="h-[78rpx] w-[78rpx] absolute left-[65rpx] top-[-21rpx]" :src="img('static/resource/images/member/point/icon.png')" mode="heightFix" />
<view class="text-[28rpx] leading-[39rpx] text-[#333]">购物返积分</view>
<view class="mt-[10rpx] text-[24rpx] leading-[34rpx] text-[#999] font-500">下单得积分</view>
<view class="w-full flex justify-center mt-[20rpx]">
<button class="h-[40rpx] !m-0 rounded-[40rpx] text-[26rpx] leading-[40rpx] !text-[#fff] !" shape="circle"
:style="{background: 'linear-gradient( 94deg, #FB7939 0%, #FE120E 99%), #EF000C'}" @click="toLink('/addon/shop/pages/goods/list')">去逛逛</button>
</view>
</view>
</view>
</view>
<view class="mt-[20rpx] mx-[30rpx] p-[30rpx] box-border rounded-[16rpx] bg-[#fff]" v-if="pointList.length">
<view class="flex justify-between items-center">
<view class="text-[32rpx] leading-[45rpx] font-bold">做任务领积分</view>
<!-- <view class="flex items-center text-[#666]">
<text class=" text-[26rpx] leading-[36rpx] mr-[10rpx]">更多</text>
<text class=" text-[18rpx] leading-[36rpx] iconfont iconxiayibu1 text-[#999]"></text>
</view> -->
</view>
<block v-for="(item,index) in pointList">
<view class="flex items-center justify-between mt-[30rpx]">
<view class="flex items-center flex-1">
<image class="h-[62rpx] w-[62rpx]" :src="img(item.icon||'')" mode="heightFix" />
<view class="flex flex-col ml-[20rpx]">
<view class="flex">
<text class="text-[28rpx] leading-[39rpx]">{{item.title}}</text>
<!-- <image class="h-[28rpx] w-[28rpx] ml-[10rpx] mr-[6rpx]" :src="img('static/resource/images/member/point/icon.png')" mode="heightFix" /> -->
<!-- <text class="text-[#EF000C] text-[28rpx] leading-[39rpx]">+10</text> -->
</view>
<view class="mt-[10rpx] text-[#999] text-[24rpx] leading-[34rpx] font-400">{{item.desc}}</view>
</view>
</view>
<button v-if="item.button" class="h-[56rpx] !m-0 rounded-[40rpx] text-[26rpx] leading-[56rpx] !text-[#fff] !" shape="circle"
:style="{background: 'linear-gradient( 94deg, #FB7939 0%, #FE120E 99%), #EF000C'}" @click="toLink(item.button.wap_redirect)">{{item.button.text}}</button>
</view>
</block>
</view>
</template>
<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 } from 'vue'
import { computed, ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { t } from '@/locale'
import { redirect, img } from '@/utils/common';
import { getPointList } from '@/app/api/member';
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 { getMemberAccountPointcount,getTaskPoint } from '@/app/api/member';
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 = {
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(); // ,
})
let param = ref({
title:'我的积分',
topStatusBar: {
style: 'style-1',
bgColor: 'transparent',
textColor: '#fff'
}
})
//
let menuButtonInfo:any = {};
// (API)
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
// #endif
const headerStyle = computed(()=>{
return {
backgroundImage: 'url(' + img('static/resource/images/member/point/point_bg.png') + ') ',
backgroundSize: 'cover',
backgroundRepeat: 'no-repeat',
backgroundPosition: 'bottom',
// paddingTop:Object.keys(menuButtonInfo).length?(Number(menuButtonInfo.height) * 2 + menuButtonInfo.top * 2 + 77)+'rpx':'77rpx',
}
})
const topStyle = computed(() => {
let style = ''
style = Object.keys(menuButtonInfo).length?(pxToRpx(Number(menuButtonInfo.height)) + pxToRpx(menuButtonInfo.top) + 38) + 'rpx;':'38rpx'
return style
})
// pxrpx
const pxToRpx=(px)=> {
const screenWidth = uni.getSystemInfoSync().screenWidth
return (750 * Number.parseInt(px)) / screenWidth
}
//
const pointInfo = ref({});
//
const pointList = ref([]);
const loading = ref(true)
onLoad(async()=>{
let pointInfoRes :any = await getMemberAccountPointcount()
let pointListRes :any = await getTaskPoint()
pointInfo.value = pointInfoRes.data
pointList.value = pointListRes.data
loading.value = false
})
const toLink=(url='',param={})=>{
redirect({ url, param })
}
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
.bg-color{
background-color: rgba(102,102,102,0.4);
}
</style>

View File

@ -0,0 +1,53 @@
<template>
<view class="bg-gray-100 min-h-[100vh]" :class="{'bg-[#fff]':!pointList.length}" :style="themeColor()">
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="getPointListFn">
<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]" :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" :option="{tip : '暂无积分明细'}"></mescroll-empty>
</mescroll-body>
</view>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { t } from '@/locale'
import { redirect, img } from '@/utils/common';
import { getPointList } from '@/app/api/member';
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 = {
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>
<style lang="scss" scoped></style>

View File

@ -4,17 +4,19 @@
<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 class="flex items-center absolute right-0 px-[14rpx] bg-color rounded-l-[35rpx] text-[#fff] text-[24rpx] h-[50rpx] z-10" :style="{top: topStyle}" @click="signPopup = true">
<text class="nc-iconfont nc-icon-meiriqiandaoV6xx text-[28rpx] text-[#fff] mr-[4rpx]"></text>
<text class="text-[24rpx]">签到规则</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 v-if="info.rule_explain" class="flex items-center absolute top-[38rpx] right-0 px-[14rpx] bg-color rounded-l-[35rpx] text-[#fff] text-[24rpx] h-[50rpx] z-10" @click="signPopup = true">
<text class="nc-iconfont nc-icon-meiriqiandaoV6xx text-[28rpx] text-[#fff] mr-[4rpx]"></text>
<text class="text-[24rpx]">签到规则</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>
@ -30,18 +32,14 @@
<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>
<text class="nc-iconfont nc-icon-shangV6xx-1 text-[#666] text-[30rpx] transform scale-80" @click="handleChange"></text>
</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>
<text class="nc-iconfont nc-icon-xiaV6xx text-[#666] text-[30rpx] transform scale-80" v-if="!flag" @click="flag = !flag"></text>
</view>
<view class="relative z-9 pb-[30rpx] bg-[#fff] rounded-[18rpx]">
<view>
@ -85,12 +83,14 @@
</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>
<button v-if="!info.is_sign" class="rounded-[40rpx] !bg-transparent" :style="{width:'470rpx',height:'80rpx',border:'none', color:'#fff', fontSize:'28rpx',lineHeight:'76rpx',backgroundImage: `url(${img('static/resource/images/app/button_bg2.png')})`,backgroundSize: '100%', backgroundRepeat: 'no-repeat'}" shape="circle" @click="setSignFn">
<text class="nc-iconfont nc-icon-meiriqiandaoV6xx text-[30rpx] text-[#fff] mr-[8rpx]"></text>
<text>立即签到</text>
</button>
<button v-else class="rounded-[40rpx] !bg-transparent" :style="{width:'470rpx',height:'80rpx',border:'none',color:'#fff', fontSize:'28rpx',lineHeight:'76rpx',backgroundImage: `url(${img('static/resource/images/app/button_bg1.png')})`,backgroundSize: '100%', backgroundRepeat: 'no-repeat'}" shape="circle">
<text class="nc-iconfont nc-icon-meiriqiandaoV6xx text-[30rpx] text-[#fff] mr-[8rpx]"></text>
<text>已签到</text>
</button>
</view>
<!-- <view class="mx-[20rpx] flex items-baseline justify-between mt-[16rpx]">
<text class="text-[26rpx] text-[#FF9000] leading-[30rpx]">查看签到记录</text>
@ -101,7 +101,7 @@
</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="font-bold text-[32rpx] text-[#333] 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>
@ -109,37 +109,29 @@
</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">
<view class="w-[90rpx] h-[90rpx] rounded-[50%] bg-[#E7F6FF] flex items-center justify-center flex-shrink-0" 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">
<view class="w-[90rpx] h-[90rpx] rounded-[50%] bg-[#ffefef] flex items-center justify-center flex-shrink-0" 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">
<view class="w-[90rpx] h-[90rpx] rounded-[50%] bg-[#d3feeb] flex items-center justify-center flex-shrink-0" 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">
<view class="w-[90rpx] h-[90rpx] rounded-[50%] bg-[#ffeddd] flex items-center justify-center flex-shrink-0" 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 class="flex flex-wrap" v-if="item.gift">
<view class="flex mb-[10rpx] ">
<image :src="img(item.gift.total.icon)" class="w-[30rpx] h-[30rpx] flex-shrink-0"></image>
<view class="text-[24rpx] ml-[6rpx] text-[#FF9000] leading-[30rpx] max-w-[330rpx]">{{item.gift.total.text}}</view>
</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-if="Number(info.days) < Number(item.continue_sign) " class="px-[28rpx] py-[8rpx] bg-[#FFECE9] rounded-[40rpx] font-500 text-[24rpx] text-[rgba(239,0,12,.8)] 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>
@ -149,19 +141,19 @@
</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 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]">
<view class="mt-[60rpx] mx-[20rpx] mb-[120rpx] h-[260rpx] overflow-auto">
<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>
<u-button text="知道了" :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>
@ -176,28 +168,22 @@
<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 v-for="(item,index) in signAward.awards">
<template v-if="item.content" v-for="(subItem,subIndex) in item.content">
<view class="flex items-center mb-[30rpx]" >
<image :src="img(subItem.icon)" class="w-[42rpx] h-[42rpx]"></image>
<view class="ml-[20rpx] text-[28rpx] text-[#333] leading-[32rpx]">{{subItem.text }}</view>
</view>
</template>
</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 class="w-[380rpx] h-[80rpx] bg-gradient-to-r from-[#FB7939] to-[#FE120E] rounded-[50rpx] text-[#ffffff] text-center leading-[80rpx] text-[30rpx]" @click="awardShow = false">我知道了</view>
</view>
</view>
</view>
<view class="flex justify-center">
<text class="iconfont iconguanbi1 text-[#fff] text-[60rpx]" @click="awardShow = false"></text>
<text class="nc-iconfont nc-icon-cuohaoV6xx text-[#fff] text-[60rpx]" @click="awardShow = false"></text>
</view>
</view>
</u-popup>
@ -212,28 +198,22 @@
<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 v-for="(item,index) in packInfo">
<template v-if="item.content">
<view class="flex items-center mb-[32rpx]" v-for="(subItem,subIndex) in item.content" :key="subIndex">
<image :src="img(subItem.icon)" class="w-[42rpx] h-[42rpx]"></image>
<view class="ml-[20rpx] text-[28rpx] text-[#333] leading-[32rpx]">{{ subItem.text }}</view>
</view>
</template>
</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 class="w-[380rpx] h-[80rpx] bg-gradient-to-r from-[#FB7939] to-[#FE120E] rounded-[50rpx] text-[#ffffff] text-center leading-[80rpx] text-[30rpx]" @click="packShow = false">我知道了</view>
</view>
</view>
</view>
<view class="flex justify-center">
<text class="iconfont iconguanbi1 text-[#fff] text-[60rpx]" @click="packShow = false"></text>
<text class="nc-iconfont nc-icon-cuohaoV6xx text-[#fff] text-[60rpx]" @click="packShow = false"></text>
</view>
</view>
</u-popup>
@ -314,7 +294,6 @@ const getSignInfoFn = (data:any) =>{
})
}
//
const getDayCounts= () => {
let counts = new Date(state.curYear,state.curMonth+1,0).getDate()
@ -353,7 +332,6 @@ const handleChange = () =>{
}
}
//
const changeMonth=(type: string)=>{
state.dataCount=[]
@ -417,15 +395,12 @@ const getDayPackFn = (date:number) =>{
})
}
//
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){
@ -445,14 +420,11 @@ const isPackDate = (date:any) =>{
return flag
}
//
const filteredDate=(date :any)=>{
return date > 0 ? date : ''
}
//
let menuButtonInfo = {};
// (API)

View File

@ -1,7 +1,6 @@
<template>
<view class="w-full h-screen bg-page setting-wrap" :style="themeColor()">
<view class="h-[30rpx]"></view>
<view class="m-[30rpx] bg-white rounded-md overflow-hidden px-[20rpx] py-[10rpx]">
<view class="w-full h-screen box-border pt-[30rpx] bg-page setting-wrap" :style="themeColor()">
<view class="m-[30rpx] mt-0 bg-white rounded-md overflow-hidden px-[20rpx] py-[10rpx]">
<u-cell-group :border="false">
<u-cell :title="t('personalSettings')" :is-link="true" url="/app/pages/member/personal"></u-cell>
<u-cell :title="t('switchLang')" :is-link="true" :value="lang" @click="langSheetShow = true"></u-cell>
@ -14,13 +13,12 @@
<u-cell :title="t('privacyAgreement')" :is-link="true" url="/app/pages/auth/agreement?key=privacy"></u-cell>
</u-cell-group>
</view>
<!-- #ifdef H5 -->
<view class="m-[30rpx] bg-white rounded-md overflow-hidden px-[20rpx]" v-if="!isWeixinBrowser()">
<view class="m-[30rpx] bg-white rounded-md overflow-hidden px-[20rpx]">
<u-cell-group :border="false">
<u-cell :title="t('logout')" class="text-center" @click="memberStore.logout(true)"></u-cell>
<view class="text-center py-[20rpx] text-sm" @click="memberStore.logout(true)">{{ t('logout') }}</view>
</u-cell-group>
</view>
<!-- #endif -->
<u-action-sheet :actions="langList" :show="langSheetShow" :closeOnClickOverlay="true"
:safeAreaInsetBottom="true"

View File

@ -1,49 +1,62 @@
<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 class="bg-[#fff] rounded-[16rpx] mt-[30rpx] mx-[30rpx]">
<view class="py-[10rpx] flex flex-col" v-for="(item,index) in verifyInfo.value.list" :key="index">
<view class="mb-[20rpx]">
<text class="px-[10rpx] text-sm flex items-center mt-[10rpx] ml-[16rpx]">订单明细</text>
</view>
<span class="xian border-[#e7e7e7] border-solid border-0 border-b-[4rpx] w-[690rpx]"></span>
<view class="flex mt-[40rpx] px-[20rpx]">
<image class="w-[120rpx] h-[120rpx]" mode="aspectFit" v-if="item.cover" :src="img(item.cover)"></image>
<image class="w-[120rpx] h-[120rpx]" 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="multi-hidden leading-[1.2] mt-[50rpx] text-xs flex">
<view class="ml-auto text-[#909399] mr-[30rpx] font-normal" >×1</view>
</view>
</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">
<view class="border-0 border-b-[4rpx] leading-[1] border-[#e7e7e7] border-solid mx-[20rpx] mt-[20rpx] "></view>
<view v-for="(item,index) in verifyInfo.value.content.diy" :key="index" class="ml-[40rpx] mr-[30rpx] text-[#838383] text-sm ">
<view class="flex items-center leading-[1] mt-[40rpx] justify-between" v-for="(subItem,subIndex) in item.list" :key="subIndex">
<text>{{subItem.title}}</text>
<view>{{subItem.value}}</view>
<view class="ml-[60rpx]">{{subItem.value}}</view>
</view>
<view class="flex items-center leading-[1] mt-[40rpx] justify-between pb-[30rpx]">
<text>创建时间</text>
<view class="ml-[60rpx]">2024-05-28 10:11:03</view>
</view>
</view>
</view>
<view class="bg-[#fff] rounded-[16rpx] mt-[20rpx] mx-[30rpx]">
<view class="py-[10rpx] flex flex-col" v-for="(item,index) in verifyInfo.value.list" :key="index">
<view class="mb-[20rpx]">
<text class="px-[10rpx] text-sm flex items-center mt-[10rpx] ml-[17rpx]">核销信息</text>
</view>
<span class="xian border-[#e7e7e7] border-solid border-0 border-b-[4rpx] w-[690rpx]"></span>
<view class="ml-[10rpx] mr-[30rpx] text-[#838383] text-sm pb-[30rpx]">
<view class="flex items-center leading-[1] mt-[50rpx] justify-between">
<text class="ml-[30rpx]">核销类型</text>
<view>{{verifyInfo.type_name}}</view>
</view>
<view class="flex items-center leading-[1] mt-[50rpx] justify-between">
<text class="ml-[30rpx]">核销状态</text>
<view>已核销</view>
</view>
<view class="flex items-center leading-[1] mt-[50rpx] justify-between">
<text class="ml-[30rpx]">核销人员</text>
<view>{{verifyInfo.member ? verifyInfo.member.nickname : '--'}}</view>
</view>
<view class="flex items-center leading-[1] mt-[50rpx] justify-between">
<text class="ml-[30rpx]">核销时间</text>
<view>{{verifyInfo.create_time}}</view>
</view>
<view class="flex items-center leading-[1] mt-[50rpx]" v-for="(item,index) in verifyInfo.value.content.fixed">
<text>{{item.title}}</text>
<view>{{item.value}}</view>
</view>
</view>
</view>
</view>
@ -54,14 +67,12 @@
<script setup lang="ts">
import { ref } from 'vue';
import { onLoad } from '@dcloudio/uni-app'
import { onLoad,onShow } 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;
@ -79,7 +90,6 @@
getVerifyDetail(code.value).then((res:any) =>{
verifyInfo.value = res.data;
loading.value = false;
console.log("verifyInfo.value",verifyInfo.value)
})
}
</script>

View File

@ -6,18 +6,17 @@
<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 class="sweep-code flex items-center justify-center ns-gradient-otherpages-member-balance-balance-rechange" @click="scanCode" v-show="operationType == 'sweepCode'">
<text class="nc-iconfont nc-icon-saoyisaoV6xx text-[130rpx] text-[#fff]"></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="_icon"><text class="iconfont iconVector-77 color-base-text"></text></view>
<view class="_text">输入核销码</view>
</view>
<view>
<view><text class="iconfont iconjiang-copy color-tip"></text></view>
<view><text class="nc-iconfont nc-icon-changjiantouV6xx color-tip"></text></view>
</view>
<view class="wrap">
<view class="_icon"><text class="iconfont iconhexiao color-base-text"></text></view>
@ -32,12 +31,12 @@
<view class="action-type-wrap">
<view class="action" @click="changeOperationType('sweepCode')">
<view class="_icon"><text class="iconfont iconsaoma"></text></view>
<view class="_icon"><text class="nc-iconfont nc-icon-saoyisaoV6xx"></text></view>
<view class="_text">扫码核销</view>
</view>
<view class="iconfont icontiaoxingmasaomiao ns-gradient-otherpages-member-balance-balance-rechange"></view>
<view class="nc-iconfont nc-icon-saotiaoxingmaV6xx 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="_icon"><text class="iconfont iconVector-77"></text></view>
<view class="_text" @click="focus">手动输入</view>
</view>
</view>
@ -140,7 +139,9 @@
getVerifierInfo(verify_code.value).then((res:any) =>{
isLoading = false;
redirect({ url: '/app/pages/verify/verify', param: { code: verify_code.value} })
})
}).catch(() => {
isLoading = false;
})
}
const focus = () => {
@ -218,6 +219,9 @@
border-radius: 50%;
margin: 0 auto;
color: var(--primary-color);
display: flex;
align-items: center;
justify-content: center;
.iconfont {
font-size: 36rpx;
@ -289,7 +293,7 @@
}
}
.icontiaoxingmasaomiao {
.nc-icon-saotiaoxingmaV6xx {
width: 110rpx;
height: 110rpx;
border-radius: 50%;
@ -299,7 +303,7 @@
line-height: 110rpx;
background: var(--primary-color);
color: #fff;
font-size: 32rpx;
font-size: 40rpx;
}
}
}

View File

@ -1,25 +1,22 @@
<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">
<mescroll-body ref="mescrollRef" top="30rpx" @init="mescrollInit" @down="downCallback" @up="geVerifyRecordFn">
<view class="ml-[30rpx] mr-[30rpx]">
<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 class="w-full flex flex-col mb-3 bg-[#fff] py-3 px-4 box-border rounded-[18rpx] " @click="toLink(item)">
<view class="flex items-center justify-between border-0 border-b-[4rpx] border-[#eee] border-solid pb-[20rpx]">
<text class="truncate w-[460rpx] text-[#999] text-xs">核销码{{ item.code }}</text>
<text class="text-[#999] text-xs ">核销员{{ 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>
<view class="py-[30rpx] flex" v-for="(dataItem,dataIndex) in item.value.list" :key="dataIndex">
<image class="w-[120rpx] h-[120rpx]" 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 class="flex flex-col justify-between ml-[20rpx]" >
<view class="multi-hidden leading-[1.2] text-xs">{{dataItem.name}}</view>
<text class="text-[#999] text-xs mt-[20rpx]">核销时间{{ item.create_time }}</text>
<view class="text-[#999] mt-[6rpx]">x1</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>
@ -71,98 +68,4 @@
</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>

View File

@ -7,7 +7,7 @@
<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 class="ml-auto text-[#999]">x1</view>
</view>
</view>
</view>
@ -44,11 +44,10 @@
<script setup lang="ts">
import { ref } from 'vue';
import { onLoad } from '@dcloudio/uni-app'
import { onLoad ,onShow} 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)
@ -97,7 +96,6 @@
getVerifierInfo(code.value).then((res:any) =>{
verifyInfo.value = res.data;
loading.value = false;
console.log("verifyInfo.value",verifyInfo.value)
})
}
let isLoading = false;
@ -110,6 +108,8 @@
setTimeout(() => {
redirect({ url: '/app/pages/verify/index', param: {}, mode: 'redirectTo' })
}, 1000);
})
}).catch(() => {
isLoading = false;
})
}
</script>

View File

@ -14,7 +14,6 @@
const errorMsg = ref('')
onLoad((options: any) => {
console.log('onload',options)
if (options.merchant_trade_no) {
outTradeNo.value = options.merchant_trade_no;
getMsgJumpPathFn();

View File

@ -1,5 +1,7 @@
import {defineStore} from 'pinia'
import {toRaw} from 'vue'
import { defineStore } from 'pinia'
import { toRaw } from 'vue'
import { diyRedirect, currRoute, getToken } from '@/utils/common';
import { useLogin } from '@/hooks/useLogin';
interface Diy {
mode: string, // 模式decorate 装修,为空表示正常
@ -63,7 +65,7 @@ const useDiyStore = defineStore('diy', {
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});`;
if (item.pageStartBgColor && item.pageEndBgColor) item.pageStyle += `background:linear-gradient(${ item.pageGradientAngle },${ item.pageStartBgColor },${ item.pageEndBgColor });`;
else item.pageStyle += 'background-color:' + item.pageStartBgColor + ';';
}
@ -87,11 +89,11 @@ const useDiyStore = defineStore('diy', {
// #endif
},
// 将数据传输给后台
postMessage(index, component) {
postMessage(index: any, component: any) {
// #ifdef H5
this.currentIndex = index;
if (component)
var data = JSON.stringify({
var data: any = JSON.stringify({
type: 'data',
index: this.currentIndex,
global: toRaw(this.global),
@ -119,6 +121,16 @@ const useDiyStore = defineStore('diy', {
});
window.parent.postMessage(data, '*');
// #endif
},
toRedirect(data: any) {
if (Object.keys(data).length) {
if (!data.name) return;
if (currRoute() == 'app/pages/member/index' && !getToken()) {
useLogin().setLoginBack({ url: data.url })
return;
}
diyRedirect(data);
}
}
}
})

View File

@ -1,47 +0,0 @@
<template>
<view @click="toRedirect" :class="prop.customClass" :style="prop.customStyle">
<slot></slot>
</view>
</template>
<script setup lang="ts">
import { redirect, diyRedirect, currRoute, getToken } from '@/utils/common'
import { useLogin } from '@/hooks/useLogin';
const prop = defineProps({
url: String,
data: {
type: Object,
default: () => {
return {}
}
},
mode: {
type: String,
default: 'navigateTo'
},
customClass: {
type: [String, Object, Array],
default: ''
},
customStyle: {
type: [String, Object, Array],
default: ''
}
})
const toRedirect = () => {
if (Object.keys(prop.data).length) {
if (!prop.data.url) return;
if (currRoute() == 'app/pages/member/index' && !getToken()) {
useLogin().setLoginBack({ url: prop.data.url })
return;
}
diyRedirect(prop.data);
} else {
redirect(prop)
}
}
</script>
<style lang="scss" scoped></style>

View File

@ -36,7 +36,7 @@
</template>
<script setup lang="ts">
import { ref, reactive, computed, watch } from 'vue'
import { ref, reactive, watch } from 'vue'
import { getAreaListByPid, getAreaByCode } from '@/app/api/system'
const prop = defineProps({
@ -60,11 +60,9 @@
district: null
})
getAreaListByPid(0)
.then(({ data }) => {
areaList.province = data
})
.catch()
getAreaListByPid(0).then(({ data }) => {
areaList.province = data
}).catch()
watch(() => prop.areaId, (nval, oval)=> {
if (nval && !oval) {
@ -75,31 +73,31 @@
})
.catch()
}
})
},{
immediate:true
})
/**
* 监听省变更
*/
watch(() => selected.province, ()=> {
getAreaListByPid(selected.province.id)
.then(({ data }) => {
areaList.city = data
currSelect.value = 'city'
if (selected.city) {
let isExist = false
for (let i = 0; i < data.length; i++) {
if (selected.city.id == data[i].id) {
isExist = true
break
}
}
if (!isExist) {
selected.city = null
getAreaListByPid(selected.province.id).then(({ data }) => {
areaList.city = data
currSelect.value = 'city'
if (selected.city) {
let isExist = false
for (let i = 0; i < data.length; i++) {
if (selected.city.id == data[i].id) {
isExist = true
break
}
}
})
.catch()
if (!isExist) {
selected.city = null
}
}
}).catch()
}, { deep: true })
/**
@ -107,30 +105,28 @@
*/
watch(() => selected.city, (nval)=> {
if (nval) {
getAreaListByPid(selected.city.id)
.then(({ data }) => {
areaList.district = data
currSelect.value = 'district'
if (selected.district) {
let isExist = false
for (let i = 0; i < data.length; i++) {
if (selected.district.id == data[i].id) {
isExist = true
break
}
}
if (!isExist) {
selected.district = null
getAreaListByPid(selected.city.id).then(({ data }) => {
areaList.district = data
currSelect.value = 'district'
if (selected.district) {
let isExist = false
for (let i = 0; i < data.length; i++) {
if (selected.district.id == data[i].id) {
isExist = true
break
}
}
})
.catch()
if (!isExist) {
selected.district = null
}
}
}).catch()
} else {
areaList.district = []
selected.district = null
}
}, { deep: true })
const emits = defineEmits(['complete'])

View File

@ -86,32 +86,28 @@
const formRef = ref(null)
const confirm = async () => {
formRef.value.validate().then(async () => {
if (loading.value) return
loading.value = true
formRef.value.validate().then(async() => {
if (loading.value) return
loading.value = true
//
await modifyMember({ field: 'headimg', value: formData.headimg })
.then(() => {
memberStore.info.headimg = formData.headimg
})
.catch(() => {
loading.value = false
})
if (!loading.value) return
//
await modifyMember({ field: 'headimg', value: formData.headimg }).then(() => {
memberStore.info.headimg = formData.headimg
}).catch(() => {
loading.value = false
})
if (!loading.value) return
//
modifyMember({ field: 'nickname', value: formData.nickname })
.then(() => {
memberStore.info.nickname = formData.nickname
loading.value = false
show.value = false
})
.catch(() => {
loading.value = false
})
})
}
//
modifyMember({ field: 'nickname', value: formData.nickname }).then(() => {
memberStore.info.nickname = formData.nickname
loading.value = false
show.value = false
}).catch(() => {
loading.value = false
})
})
}
defineExpose({
show

View File

@ -62,7 +62,8 @@
pay({
trade_type: payInfo.value?.trade_type,
trade_id: payInfo.value?.trade_id,
type: type.value
type: type.value,
openid: uni.getStorageSync('openid') || ''
}).then(res => {
switch (type.value) {
case 'wechatpay':

View File

@ -84,10 +84,11 @@ let sharePopupShow = ref(false);
//
const copyUrl = () => {
let data = ''
if(props.copyUrl)
data = location.origin + props.copyUrl + props.copyUrlParam;
else
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;
});
@ -180,7 +181,6 @@ const saveGoodsPoster = () => {
}
// #endif
let shareTop = ref(0)
/************ 获取微信头部-start ****************/
//
@ -198,11 +198,9 @@ const sharePopuClose = ()=>{
isPosterImg.value = false;
}
defineExpose({
openShare
})
</script>
<style lang="scss" scoped>
.share-popup {

View File

@ -1,14 +1,9 @@
<template>
<view :class="{'text-primary': sendSms.canGetCode.value, 'text-gray-300': !sendSms.canGetCode.value}" @click="handleSend">{{ sendSms.tips.value }}</view>
<u-code :seconds="sendSms.seconds" :change-text="sendSms.changeText" ref="smsRef" @change="sendSms.codeChange"></u-code>
<u-modal :show="show" :title="t('captchaTitle')" :confirm-text="t('confirm')" :cancel-text="t('cancel')" :show-cancel-button="true"
@cancel="show = false" @confirm="handleConfirm">
<u-modal :show="show" :title="t('captchaTitle')" :confirm-text="t('confirm')" :cancel-text="t('cancel')" :show-cancel-button="true" @cancel="show = false" @confirm="handleConfirm">
<view class="flex mt-[20rpx]">
<u-input
:placeholder="t('captchaPlaceholder')"
border="surround"
v-model="formData.captcha_code"
></u-input>
<u-input :placeholder="t('captchaPlaceholder')" border="surround" v-model="formData.captcha_code"></u-input>
<image :src="captcha.image.value" class="h-[76rpx] ml-[20rpx]" mode="heightFix" @click="captcha.refresh()"></image>
</view>
</u-modal>

View File

@ -1,7 +1,7 @@
<template>
<template v-if="tabbar && Object.keys(tabbar).length">
<u-tabbar :value="value" @change="tabbarChange" zIndex="9999" :fixed="true" :placeholder="true" :safeAreaInsetBottom="true"
:inactive-color="tabbar.value.textColor" :active-color="tabbar.value.textHoverColor" v-if="tabbar">
:inactive-color="tabbar.value.textColor" :active-color="tabbar.value.textHoverColor">
<block v-for="item in tabbar.value.list">
<u-tabbar-item class="py-[5rpx]" :style="{'background-color': tabbar.value.backgroundColor}" :text="item.text"
:icon="img(value == item.link.url ? item.iconSelectPath : item.iconPath)" :name="item.link.url"
@ -18,7 +18,7 @@
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { ref,reactive,computed,watch } from 'vue'
import { redirect, currRoute,currShareRoute, img } from '@/utils/common'
import useConfigStore from '@/stores/config'
@ -29,14 +29,36 @@
}
})
if(props.addon){
const configStore = useConfigStore()
configStore.getTabbarConfig(props.addon)
let addon:any = props.addon;
const configStore = useConfigStore()
if(!addon && configStore.addon){
addon = configStore.addon;
}
const tabbar = computed(() => {
return useConfigStore().tabbar
})
const tabbar:any = reactive({})
const setTabbar = ()=>{
let list = useConfigStore().tabbarList;
for(let i=0;i<list.length;i++){
if(list[i].key == addon){
Object.assign(tabbar,list[i]);
break;
}
}
}
setTabbar()
watch(
() => props.addon,
(newValue, oldValue) => {
if(newValue && oldValue && newValue != oldValue) {
setTabbar()
}
}
, { immediate: true }
)
const value = computed(() => {
let query:any = currShareRoute().params;
@ -66,13 +88,7 @@
}
}
const setAddon = (addon:any)=> {
const configStore = useConfigStore()
configStore.getTabbarConfig(addon)
}
defineExpose({
setAddon
})
</script>

View File

@ -4,13 +4,13 @@
<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 v-if="isBack && isBackShow" class="back-wrap text-[26px] nc-iconfont nc-icon-zuoV6xx" :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 v-if="topStatusBarData.style == 'style-2'" class="content-wrap" :style="navbarInnerStyle" @click="diyStore.toRedirect(topStatusBarData.link)">
<view v-if="isBack && isBackShow" class="back-wrap text-[26px] nc-iconfont nc-icon-zuoV6xx" :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>
@ -20,26 +20,26 @@
</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)">
<view v-if="isBack && isBackShow" class="back-wrap text-[26px] nc-iconfont nc-icon-zuoV6xx" :style="{ color: topStatusBarData.textColor || titleColor }" @tap="goBack"></view>
<view class="title-wrap" @click="diyStore.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>
<view class="search" @click="diyStore.toRedirect(topStatusBarData.link)" :style="{ height: menuButtonInfo.height - 2 + 'px', lineHeight: menuButtonInfo.height - 2 + 'px' }">
<text class="nc-iconfont nc-icon-sousuoV6xx 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 v-if="isBack && isBackShow" class="back-wrap text-[26px] nc-iconfont nc-icon-zuoV6xx" :style="{ color: topStatusBarData.textColor || titleColor }" @tap="goBack"></view>
<text class="nc-iconfont nc-icon-dizhiguanliV6xx 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>
<text class="nc-iconfont nc-icon-youV6xx text-[26rpx]" @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 v-if="isBack && isBackShow" class="back-wrap text-[26px] nc-iconfont nc-icon-zuoV6xx" :style="{ color: topStatusBarData.textColor || titleColor }" @tap="goBack"></view>
</view>
<!-- #endif -->
</view>
@ -69,10 +69,9 @@ menuButtonInfo = uni.getMenuButtonBoundingClientRect();
// #endif
import { ref, computed, watch, onMounted, getCurrentInstance, nextTick } from 'vue';
import { img, redirect, getLocation, locationStorage, getToken, currRoute, diyRedirect } from '@/utils/common';
import { img, getLocation, locationStorage } 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();
@ -210,20 +209,6 @@ const navbarPlaceholderHeight = () => {
})
}
//
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();
@ -330,18 +315,20 @@ 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-bottompadding-top]
style5Height.value += `padding-top:${sysHeight}px;`
// #endif
if(data.value.imgWidth && data.value.imgHeight) {
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-bottompadding-top]
style5Height.value += `padding-top:${ sysHeight }px;`
// #endif
}
}
},{immediate: true, deep:true})
/******************************* 风格五-end ***********************/

View File

@ -1,5 +1,5 @@
import { redirect, isWeixinBrowser, urlDeconstruction } from '@/utils/common'
import { weappLogin, wechatLogin } from '@/app/api/auth'
import { weappLogin, wechatLogin, wechatUser, wechatUserLogin } from '@/app/api/auth'
import { getWechatAuthCode } from '@/app/api/system'
import useMemberStore from '@/stores/member'
import useConfigStore from '@/stores/config'
@ -13,14 +13,14 @@ export function useLogin() {
setTimeout(() => {
const config = useConfigStore()
// #ifdef MP-WEIXIN
if (uni.getStorageSync('openid') && config.login.is_bind_mobile) {
if (!uni.getStorageSync('autoLoginLock') && uni.getStorageSync('openid') && config.login.is_bind_mobile) {
redirect({ url: '/app/pages/auth/bind', mode: 'redirectTo' })
return
}
// #endif
// #ifdef H5
if (isWeixinBrowser() && uni.getStorageSync('openid') && config.login.is_bind_mobile) {
if (!uni.getStorageSync('autoLoginLock') && isWeixinBrowser() && uni.getStorageSync('openid') && config.login.is_bind_mobile) {
redirect({ url: '/app/pages/auth/bind', mode: 'redirectTo' })
return
}
@ -33,6 +33,7 @@ export function useLogin() {
*
*/
const handleLoginBack = () => {
uni.removeStorageSync('autoLoginLock')
uni.getStorage({
key: 'loginBack',
success: (data : AnyObject) => {
@ -48,28 +49,45 @@ export function useLogin() {
*
*/
const authLogin = (code : string | null) => {
let login = null
let obj = {};
// #ifdef MP-WEIXIN
login = weappLogin
// #ifdef MP-WEIXIN
obj.code = code;
uni.getStorageSync('pid') && (Object.assign(obj, { pid: uni.getStorageSync('pid') }))
weappLogin(obj).then((res : AnyObject) => {
if (res.data.token) {
useMemberStore().setToken(res.data.token)
setTimeout(() => {
const memberInfo = useMemberStore().info
memberInfo && memberInfo.weapp_openid && uni.setStorageSync('openid', memberInfo.weapp_openid)
}, 1000)
} else {
uni.setStorageSync('openid', res.data.openid)
uni.setStorageSync('unionid', res.data.unionid)
}
})
// #endif
// #ifdef H5
login = wechatLogin
obj.code = code;
uni.getStorageSync('pid') && (Object.assign(obj, { pid: uni.getStorageSync('pid') }))
wechatUser(obj).then((user_res : AnyObject) => {
if(user_res.data){
wechatUserLogin(user_res.data).then((res : AnyObject) => {
if (res.data.token) {
useMemberStore().setToken(res.data.token)
setTimeout(() => {
const memberInfo = useMemberStore().info
memberInfo && memberInfo.wx_openid && uni.setStorageSync('openid', memberInfo.wx_openid)
}, 1000)
} else {
uni.setStorageSync('openid', res.data.openid)
uni.setStorageSync('unionid', res.data.unionid)
}
})
}
})
// #endif
login(obj).then((res : AnyObject) => {
if (res.data.token) {
useMemberStore().setToken(res.data.token)
} else {
uni.setStorageSync('openid', res.data.openid)
uni.setStorageSync('unionid', res.data.unionid)
}
})
}
/**

View File

@ -1,25 +1,20 @@
import { img, isWeixinBrowser, currRoute, currShareRoute, getToken } from '@/utils/common'
import { img, isWeixinBrowser, currRoute, currShareRoute } from '@/utils/common'
import { onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'
import { getShareInfo } from '@/app/api/diy';
import useMemberStore from '@/stores/member'
import { watch,computed } from 'vue'
// #ifdef H5
import wechat from '@/utils/wechat'
// #endif
export const useShare = () => {
var wechatOptions : WeixinJsSdk.OnMenuShareAppMessageOptions = {
title: '',
link: ''
};
var wechatOptions: any = {};
var weappOptions = {};
var weappOptions:any = {};
// #ifdef H5
const wechatInit = async () => {
const wechatInit = () => {
if (!isWeixinBrowser()) return;
await wechat.init();
// 初始化sdk
wechat.init();
}
// 微信公众号分享
@ -27,97 +22,101 @@ export const useShare = () => {
if (!isWeixinBrowser()) return;
wechat.share(wechatOptions);
}
// #endif
const setShare = async (options : any = {}) => {
let memberStore = useMemberStore();
let isWatch = uni.getStorageSync('isWatchShare');
// 防重复监听
if(!isWatch) {
watch(() => memberStore.info, (newValue: any, oldValue: any) => {
// 如果会员发生变化,则请求分享接口
if (newValue && oldValue && newValue.member_id != oldValue.member_id) {
setShare(options)
}
})
uni.setStorageSync('isWatchShare', true);
const getQuery = ()=>{
let query:any = currShareRoute().params;
let wap_member_id = uni.getStorageSync('wap_member_id');
if (wap_member_id) {
query.mid = wap_member_id;
}
let queryStr = [];
for (let key in query) {
queryStr.push(key + '=' + query[key]);
}
return queryStr
}
const setShare = (options : any = {}) => {
if(currRoute() == '') return;
let queryStr = getQuery();
// #ifdef H5
// 初始化sdk
await wechatInit();
let h5Link = location.origin + location.pathname + (queryStr.length > 0 ? '?' + queryStr.join('&') : '');
wechatOptions = {
link: h5Link
}
// #endif
// #ifdef MP-WEIXIN
weappOptions = {
path: '/' + currRoute() + (queryStr.length > 0 ? '?' + queryStr.join('&') : ''),
query: queryStr.join('&'),
}
// #endif
if (options && options.wechat && options.weapp) {
let query = currShareRoute().params;
if (memberStore.info) {
query.mid = memberStore.info.member_id;
}
let str = [];
for (let key in query) {
str.push(key + '=' + query[key]);
}
// #ifdef H5
let link = location.origin + location.pathname + (str.length > 0 ? '?' + str.join('&') : '');
wechatOptions = {
title: options.wechat.title || '',
link: options.wechat.link || link,
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
}
wechatOptions.title = options.wechat.title || ''
wechatOptions.link = options.wechat.link || h5Link
wechatOptions.desc = options.wechat.desc || ''
wechatOptions.imgUrl = options.wechat.url ? img(options.wechat.url) : ''
wechatShare()
// #endif
weappOptions = {
title: options.weapp.title || '',
query: options.weapp.path || '/' + currRoute() + (str.length > 0 ? '?' + str.join('&') : ''),
imageUrl: options.weapp.url ? img(options.weapp.url) : ''
}
// #ifdef MP-WEIXIN
weappOptions.title = options.weapp.title || ''
weappOptions.query = options.weapp.path || queryStr.join('&')
weappOptions.imageUrl = options.weapp.url ? img(options.weapp.url) : ''
// #endif
} else {
getShareInfo({ route: '/' + currRoute(), params: JSON.stringify(currShareRoute().params) }).then((res : any) => {
getShareInfo({
route: '/' + currRoute(),
params: JSON.stringify(currShareRoute().params)
}).then((res: any) => {
let data = res.data;
// #ifdef H5
let wechat = data.wechat;
if (wechat) {
let link = location.origin + location.pathname + (data.query ? '?' + data.query : '');
wechatOptions = {
link: link,
title: wechat.title,
desc: wechat.desc,
imgUrl: wechat.url ? img(wechat.url) : ''
}
wechatOptions.title = wechat.title
wechatOptions.desc = wechat.desc
wechatOptions.imgUrl = wechat.url ? img(wechat.url) : ''
}else{
wechatOptions.title = document.title;
wechatOptions.desc = ''
}
wechatShare()
// #endif
// #ifdef MP-WEIXIN
let weapp = data.weapp;
if (weapp) {
weappOptions = {
query: data.url,
title: weapp.title,
imageUrl: weapp.url ? img(weapp.url) : ''
}
weappOptions.title = weapp.title
weappOptions.imageUrl = weapp.url ? img(weapp.url) : ''
}
// #endif
})
}
uni.setStorageSync('weappOptions', weappOptions)
}
// 小程序分享,分享给好友
const shareApp = (options = {}) => {
onShareAppMessage(() => {
let config:any= uni.getStorageSync('weappOptions')
if(!config) config = {}
return {
...weappOptions,
...config,
...options
}
})
@ -127,14 +126,17 @@ export const useShare = () => {
// 小程序分享,分享到朋友圈
const shareTime = (options = {}) => {
onShareTimeline(() => {
let config:any= uni.getStorageSync('weappOptions')
if(!config) config = {}
return {
...weappOptions,
...config,
...options
}
})
}
return {
wechatInit:wechatInit,
setShare: setShare,
onShareAppMessage: shareApp,
onShareTimeline: shareTime,

View File

@ -1,11 +1,10 @@
import i18n, { language } from "./i18n"
import useSystemStore from '@/stores/system'
import { currRoute } from '@/utils/common'
const t = (message: string) => {
const route = currRoute()
const file = language.getFileKey(`/${route}`)
const key = `${file.fileKey}.${message}`
const route = useSystemStore().currRoute
const file = language.getFileKey(`/${ route }`)
const key = `${ file.fileKey }.${ message }`
if (i18n.global.t(message) != message) return i18n.global.t(message)
return i18n.global.t(key) != key ? i18n.global.t(key) : ''
}

View File

@ -18,6 +18,7 @@
"pages.member.apply_cash_out": "申请提现",
"pages.member.balance": "我的余额",
"pages.member.point": "我的积分",
"pages.member.point_detail": "积分明细",
"pages.member.level": "会员等级",
"pages.member.sign_in": "我的签到",
"pages.member.cash_out": "提现记录",
@ -33,5 +34,83 @@
"pages.verify.verify": "核销",
"pages.verify.detail": "核销详情",
"pages.verify.record": "核销记录",
"pages.webview.index": ""
"pages.webview.index": "",
"tourism.pages.way.list": "线路列表",
"tourism.pages.way.detail": "线路详情",
"tourism.pages.way.order": "线路订单",
"tourism.pages.hotel.list": "酒店列表",
"tourism.pages.hotel.detail": "酒店详情",
"tourism.pages.hotel.order": "酒店订单",
"tourism.pages.scenic.list": "景点列表",
"tourism.pages.scenic.detail": "景点详情",
"tourism.pages.scenic.order": "景点订单",
"tourism.pages.order.list": "旅游订单",
"tourism.pages.order.detail": "订单详情",
"tourism.pages.verify.index": "核销",
"tourism.pages.verify.record": "核销记录",
"tourism.pages.verify.detail": "核销详情",
"vipcard.pages.verify.index": "核销",
"vipcard.pages.verify.record": "核销记录",
"vipcard.pages.verify.detail": "核销详情",
"vipcard.pages.order.payment": "订单结算",
"vipcard.pages.order.list": "订单列表",
"vipcard.pages.order.my_reserved": "我的预约",
"vipcard.pages.order.my_reserved_detail": "我的预约详情",
"vipcard.pages.order.my_card": "我的卡项",
"vipcard.pages.order.detail": "订单详情",
"vipcard.pages.service.list": "项目列表",
"vipcard.pages.card.list": "卡项列表",
"vipcard.pages.card.detail": "卡项详情",
"recharge.pages.recharge": "充值",
"recharge.pages.recharge_record": "充值记录",
"recharge.pages.recharge_record_detail": "充值记录详情",
"shop.pages.goods.search": "搜索",
"shop.pages.goods.cart": "购物车",
"shop.pages.goods.category": "商品分类",
"shop.pages.goods.detail": "商品详情",
"shop.pages.goods.list": "商品列表",
"shop.pages.member.index": "个人中心",
"shop.pages.member.my_coupon": "我的优惠券",
"shop.pages.order.list": "订单列表",
"shop.pages.order.detail": "订单详情",
"shop.pages.order.payment": "待付款订单",
"shop.pages.pay.index": "待支付",
"shop.pages.pay.result": "支付成功",
"shop.pages.evaluate.order_evaluate": "商品评价",
"shop.pages.evaluate.order_evaluate_view": "商品评价",
"shop.pages.evaluate.list": "评价列表",
"shop.pages.coupon.list": "优惠券列表",
"shop.pages.coupon.detail": "优惠券详情",
"shop.pages.discount.list": "限时折扣",
"shop.pages.refund.list": "退款列表",
"shop.pages.refund.detail": "退款详情",
"shop.pages.refund.apply": "申请退款",
"shop.pages.refund.edit_apply": "编辑退款信息",
"shop.pages.refund.log": "协商记录",
"shop.pages.point.index":"积分商城",
"shop.pages.point.list":"积分商品列表",
"shop.pages.point.detail":"积分商品详情",
"shop.pages.point.payment":"待付款订单",
"shop.pages.point.order_list":"积分兑换记录",
"cms.pages.list": "资讯中心",
"cms.pages.detail": "文章详情",
"shop_fenxiao.pages.index": "分销中心",
"shop_fenxiao.pages.zone": "分销专区",
"shop_fenxiao.pages.level": "分销商等级",
"shop_fenxiao.pages.child_fenxiao": "分销商",
"shop_fenxiao.pages.goods": "分销商品",
"shop_fenxiao.pages.team": "团队",
"shop_fenxiao.pages.ranking_list": "排行榜",
"shop_fenxiao.pages.agent_list": "渠道代理",
"shop_fenxiao.pages.bill": "账单",
"shop_fenxiao.pages.order": "分销订单",
"shop_fenxiao.pages.order_detail": "订单详情",
"shop_fenxiao.pages.apply": "分销商申请",
"shop_fenxiao.pages.task_rewards": "任务奖励",
"shop_fenxiao.pages.task_detail": "任务奖励详情",
"shop_fenxiao.pages.task_rewards_detail": "任务奖励明细",
"shop_fenxiao.pages.sale": "销售奖励",
"shop_fenxiao.pages.sale_detail": "销售奖励详情",
"shop_fenxiao.pages.sale_ranking": "销售排行榜",
"shop_fenxiao.pages.promote_code": "分销推广"
}

View File

@ -72,7 +72,7 @@
"orderNo": "订单号",
"actualPayment": "实付款",
"orderClose": "关闭订单",
"orderFinish": "订单完成",
"orderFinish": "确认收货",
"orderDetail": "详情",
"wxPrivacyPopup": {
"title": "用户隐私保护提示",
@ -84,5 +84,10 @@
"disagreeDesc": "未同意隐私协议,无法使用相关功能"
},
"starLevel": "星级",
"star": "星"
"star": "星",
"emptyAddress":"暂无收货地址,请先创建地址",
"addAddress":"新增收货地址",
"selectAddress":"选择地址",
"coupon":"优惠劵"
}

View File

@ -1,6 +1,7 @@
import { defineStore } from 'pinia'
import { getConfig } from '@/app/api/auth'
import { getTabbarInfo } from '@/app/api/diy'
import { getTabbarList } from '@/app/api/diy'
import { cloneDeep } from 'lodash-es'
interface loginConfig {
is_username: number | boolean,
@ -19,6 +20,7 @@ interface tabbarConfig {
interface Config {
login: loginConfig,
tabbarList:any,
tabbar: tabbarConfig | null,
addon: String,
themeColor:String
@ -34,6 +36,7 @@ const useConfigStore = defineStore('config', {
is_bind_mobile: 0,
agreement_show: 0
},
tabbarList:{},
tabbar: null,
addon: '',
themeColor:''
@ -50,13 +53,10 @@ const useConfigStore = defineStore('config', {
}).catch(() => {
})
},
async getTabbarConfig(key: any = '') {
if(key == this.addon) return; // 防重复请求
if (!key) key = this.addon;
await getTabbarInfo({key}).then((res: responseResult) => {
this.tabbar = res.data
}).catch(() => {
async getTabbarConfig() {
await getTabbarList({}).then((res:any)=>{
this.tabbarList = res.data;
}).catch(()=>{
})
},
// 获取主色调

View File

@ -25,6 +25,7 @@ const useMemberStore = defineStore('member', {
if (!this.token) return
await getMemberInfo().then((res: any) => {
this.info = res.data
uni.setStorageSync('wap_member_id',res.data.member_id)
}).catch(async () => {
await this.logout()
})
@ -33,12 +34,11 @@ const useMemberStore = defineStore('member', {
if (!this.token) return
this.token = ''
this.info = null
uni.setStorageSync('autoLoginLock', true)
await logout().then(() => {
uni.removeStorageSync('pid');
removeToken()
isRedirect && redirect({ url: '/app/pages/index/index', mode: 'switchTab' })
}).catch(() => {
uni.removeStorageSync('pid');
removeToken()
isRedirect && redirect({ url: '/app/pages/index/index', mode: 'switchTab' })
})

View File

@ -8,8 +8,7 @@ interface System {
siteAddons: string[],
currRoute: string,
location: Object | null, // 定位信息
mapConfig: Object,
installAddonList: string[]
mapConfig: Object
}
const useSystemStore = defineStore('system', {
@ -23,8 +22,7 @@ const useSystemStore = defineStore('system', {
mapConfig: {
is_open: 1,
valid_time: 0
},
installAddonList: []
}
}
},
actions: {
@ -35,9 +33,7 @@ const useSystemStore = defineStore('system', {
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() {

View File

@ -78,8 +78,30 @@ button[type='primary'],uni-button[type='primary']{
touch-action: none;
}
// 去掉uveiew 点击时变灰针对于微信小程序处理官方提供的方法在小程序中不起作用
.u-button.u-button--active:before{
opacity: 0 !important;
}
}
/****************** 弹窗-start *********************/
// 弹窗圆角[从下往上弹窗]
.u-popup[type="bottom"] .u-popup__content, .u-popup .u-slide-up-enter-to .u-popup__content{
border-top-left-radius: 16rpx;
border-top-right-radius: 16rpx;
overflow: hidden;
}
// 防止覆盖住图片放大
.u-popup :deep(.u-transition){
z-index: 999 !important;
}
/****************** 弹窗-end *********************/
/****************** u-cell-start *********************/
.u-cell-group .u-cell__body__content{
line-height: 1;
}
.u-cell-group .u-cell__right-icon-wrap .uicon-arrow-right{
font-size: 28rpx !important;
color: #999;
}
/****************** u-cell-end *********************/

View File

@ -2,7 +2,7 @@
width: 100%;
height: 100%;
box-sizing: border-box;
background-size: contain !important;
background-size: contain;
background-repeat: no-repeat !important;
}
@ -17,17 +17,6 @@
}
}
/* #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 {

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,5 @@
@import 'uview-plus/index.scss';
@import 'common.scss';
@import 'iconfont.css';
@import 'official-iconfont.css';

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,6 @@
import { getTabbarPages } from './pages'
import useDiyStore from '@/app/stores/diy'
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'
/**
@ -60,17 +57,15 @@ export const redirect = (redirect : redirectOptions) => {
*
* @param {Object} link
*/
export const diyRedirect = (link : any) => {
export const diyRedirect = (link: any) => {
const diyStore = useDiyStore();
// 装修模式禁止跳转
if (diyStore.mode == 'decorate') return;
if (link == null || Object.keys(link).length == 1) return;
if (!link.url) return;
// 外部链接
if (link.url.indexOf('http') != -1 || link.url.indexOf('http') != -1) {
if (link.url && (link.url.indexOf('https') != -1 || link.url.indexOf('http') != -1)) {
// #ifdef H5
window.location.href = link.url;
@ -82,6 +77,24 @@ export const diyRedirect = (link : any) => {
param: { src: encodeURIComponent(link.url) }
});
// #endif
} else if (link.appid) {
// 跳转其他小程序
// #ifdef MP
uni.navigateToMiniProgram({
appId: link.appid,
path: link.page
})
// #endif
} else if (link.name == 'DIY_MAKE_PHONE_CALL' && link.mobile) {
// 拨打电话
uni.makePhoneCall({
phoneNumber: link.mobile,
success: (res) => {},
fail: (res) => {}
});
} else {
redirect({ url: link.url });
}
@ -99,6 +112,12 @@ export const currRoute = () => {
// 获取分享路由
export const currShareRoute = () => {
const pages = getCurrentPages()
if (pages.length == 0) {
return {
path: '/',
params: {}
}
}
let currentRoute = pages[pages.length - 1].route //获取当前页面路由
// #ifdef H5
@ -236,19 +255,22 @@ export function mobileConceal(mobile : string) : string {
/**
* id
*/
export function getSiteId(siteid : number) {
export function getSiteId(siteId : number | string) {
// #ifdef H5
const match = location.href.match(/\/wap\/(\d*)\//);
if (match) return match[1]
else return siteid
match && (siteId = match[1])
// #endif
// #ifndef H5
return siteid
// #endif
// #ifdef MP-WEIXIN
if (uni.getExtConfigSync) {
const extConfig = uni.getExtConfigSync()
extConfig.site_id && (siteId = extConfig.site_id)
}
// #endif
return siteId
}
/**
*
* @param {Object} timeStamp
@ -284,7 +306,7 @@ export function timeStampTurnTime(timeStamp, type = "") {
/**
*
* @param {Object} message
* @param {Object} value
* @param {Object} callback
*/
export function copy(value, callback) {
@ -413,9 +435,29 @@ export function deepClone(obj: object) {
return o
}
/**
*
* @param fn
* @param delay
* @returns
*/
export function debounce(fn: (args?: any) => any, delay: number = 300) {
let timer: null | number = null
return function (...args) {
if (timer != null) {
clearTimeout(timer)
timer = null
}
timer = setTimeout(() => {
fn.call(this, ...args)
}, delay);
}
}
const isArray = (value: any) => {
if (typeof Array.isArray === 'function') {
return Array.isArray(value)
}
return Object.prototype.toString.call(value) === '[object Array]'
}
}

View File

@ -1,111 +1,127 @@
import { language } from '@/locale'
import { checkNeedLogin } from '@/utils/auth'
import { redirect, getToken, getSiteId } from '@/utils/common'
import { redirect, getToken, getSiteId, isWeixinBrowser } from '@/utils/common'
import { memberLog } from '@/app/api/auth'
import useConfigStore from "@/stores/config";
import { useShare } from '@/hooks/useShare'
/**
*
*/
export const redirectInterceptor = (route: { path: string, query: object }) => {
route.path = `/${route.path}`
route.path = `/${ route.path }`
// 检测当前访问的是系统app还是插件
setAddonName(route.path)
// 检测当前访问的是系统app还是插件
setAddonName(route.path)
// 开发模式下如果未配置站点ID则跳转到开发环境配置页面
// #ifdef H5
if (process.env.NODE_ENV == 'development') {
if ((getSiteId(import.meta.env.VITE_SITE_ID || uni.getStorageSync('wap_site_id')) === '') && route.path != '/app/pages/index/develop') {
redirect({ url: '/app/pages/index/develop', mode: 'reLaunch' })
}
}
// #endif
// 开发模式下如果未配置站点ID则跳转到开发环境配置页面
// #ifdef H5
if (process.env.NODE_ENV == 'development') {
if ((getSiteId(import.meta.env.VITE_SITE_ID || uni.getStorageSync('wap_site_id')) === '') && route.path != '/app/pages/index/develop') {
redirect({ url: '/app/pages/index/develop', mode: 'reLaunch' })
}
}
// #ifdef MP
route.path.indexOf('addon') != -1 && language.loadAllLocaleMessages('addon', uni.getLocale())
// #endif
// #endif
// 校验是否需要登录
checkNeedLogin(route)
// #ifdef MP
route.path.indexOf('addon') != -1 && language.loadAllLocaleMessages('addon', uni.getLocale())
// #endif
// 添加会员访问日志
if (getToken()) memberLog({ route: route.path, params: JSON.stringify(route.query), pre_route: getCurrentPages()[0]?.route })
// 校验是否需要登录
checkNeedLogin(route)
loadShare()
// 添加会员访问日志
if (getToken()) memberLog({
route: route.path,
params: JSON.stringify(route.query),
pre_route: getCurrentPages()[0]?.route
})
}
/**
*
*/
export const launchInterceptor = () => {
const launch = uni.getLaunchOptionsSync()
launch.path = `/${launch.path}`
const launch = uni.getLaunchOptionsSync()
launch.path = `/${ launch.path }`
// 开发模式下如果未配置站点ID则跳转到开发环境配置页面
// #ifdef H5
if (process.env.NODE_ENV == 'development') {
// 后台DIY装修页面时获取站点ID
// 开发模式下如果未配置站点ID则跳转到开发环境配置页面
// #ifdef H5
if (process.env.NODE_ENV == 'development') {
// 后台DIY装修页面时获取站点ID
if (location.search.indexOf('site_id=') != -1) {
let site_id = location.search.substr(location.search.indexOf('site_id=')+8);
uni.setStorageSync('wap_site_id', site_id);
}
if (getSiteId(import.meta.env.VITE_SITE_ID || uni.getStorageSync('wap_site_id')) === '') {
launch.path = '/app/pages/index/develop';
uni.setStorageSync('develop_before_path', launch.path);
redirect({ url: '/app/pages/index/develop', mode: 'reLaunch' })
}
}
// #endif
if (location.search.indexOf('site_id=') != -1) {
let site_id = location.search.substr(location.search.indexOf('site_id=') + 8);
uni.setStorageSync('wap_site_id', site_id);
}
if (getSiteId(import.meta.env.VITE_SITE_ID || uni.getStorageSync('wap_site_id')) === '') {
launch.path = '/app/pages/index/develop';
uni.setStorageSync('develop_before_path', launch.path);
redirect({ url: '/app/pages/index/develop', mode: 'reLaunch' })
}
}
// 检测当前访问的是系统app还是插件
setAddonName(launch.path);
// #endif
// 加载语言包
language.loadAllLocaleMessages('app', uni.getLocale())
// #ifdef H5
language.loadAllLocaleMessages('addon', uni.getLocale())
// #endif
// 检测当前访问的是系统app还是插件
setAddonName(launch.path);
// 校验是否需要登录
checkNeedLogin(launch)
// 加载语言包
language.loadAllLocaleMessages('app', uni.getLocale())
// 存储分享会员id
if (launch.query && launch.query.mid) {
uni.setStorageSync('pid', launch.query.mid)
}
// #ifdef H5
language.loadAllLocaleMessages('addon', uni.getLocale())
// #endif
// 添加会员访问日志
if (getToken()) memberLog({ route: launch.path, params: JSON.stringify(launch.query || {}), pre_route: '' })
// 校验是否需要登录
checkNeedLogin(launch)
// 存储分享会员id
if (launch.query && launch.query.mid) {
uni.setStorageSync('pid', launch.query.mid)
}
loadShare()
// 添加会员访问日志
if (getToken()) memberLog({ route: launch.path, params: JSON.stringify(launch.query || {}), pre_route: '' })
}
/**
* 访app
*
*
* @param path
* @param path
*/
const setAddonName = async (path: string) => {
let pathArr = path.split('/')
let route = pathArr[1] == 'addon' ? pathArr[2] : 'app';
const setAddonName = async(path: string) => {
let pathArr = path.split('/')
let route = pathArr[1] == 'addon' ? pathArr[2] : 'app';
// 设置底部导航
const configStore = useConfigStore()
if (configStore.addon != route) {
configStore.addon = route;
configStore.getTabbarConfig();
}
// 设置底部导航
const configStore = useConfigStore()
if (configStore.addon != route) {
configStore.addon = route;
}
// 设置插件应用的主色调,排除系统
if (route != 'app') {
try {
const theme = await import(`../addon/${route}/utils/theme.json`)
configStore.themeColor = theme.default
uni.setStorageSync('current_theme_color', JSON.stringify(theme.default));
} catch (e) {
console.log('设置插件应用的主色调', e)
uni.removeStorageSync('current_theme_color');
}
// 设置插件应用的主色调,排除系统
if (route != 'app') {
try {
const theme = await import(`../addon/${ route }/utils/theme.json`)
configStore.themeColor = theme.default
uni.setStorageSync('current_theme_color', JSON.stringify(theme.default));
} catch (e) {
// 设置插件应用的主色调发生错误,若不存在则使用最后有效的主色调
}
}
}
}
// 加载分享
const loadShare = () => {
const { setShare } = useShare()
setShare()
}

View File

@ -2,6 +2,7 @@ import { currRoute } from './common'
import { redirectInterceptor } from './interceptor'
import useConfigStore from "@/stores/config";
import useSystemStore from '@/stores/system'
import {useShare} from '@/hooks/useShare'
export default {
install(vue) {
@ -32,6 +33,12 @@ export default {
query: this.query
})
},
onShareAppMessage(){
useShare().onShareAppMessage()
},
onShareTimeline(){
useShare().onShareTimeline()
},
methods:{
themeColor(){
const configStore = useConfigStore()

View File

@ -159,6 +159,9 @@ class Request {
case 402:
redirect({url: '/app/pages/index/close', mode: 'reLaunch'})
break;
case 403:
redirect({url: '/app/pages/index/nosite', mode: 'reLaunch'})
break;
}
}