mirror of
https://gitee.com/niucloud-team/niucloud-admin.git
synced 2026-03-17 11:13:43 +00:00
update uniapp
This commit is contained in:
parent
3258774194
commit
c4ebd51a5c
4753
uni-app/package-lock.json
generated
4753
uni-app/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,20 +1,20 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onLaunch, onShow, onHide } from '@dcloudio/uni-app'
|
import { onLaunch, onShow, onHide } from '@dcloudio/uni-app'
|
||||||
import manifest from '@/manifest.json'
|
import { launchInterceptor } from '@/utils/interceptor'
|
||||||
import { launchInterceptor } from '@/utils/interceptor'
|
import { getToken, isWeixinBrowser } from '@/utils/common'
|
||||||
import { getToken, isWeixinBrowser } from '@/utils/common'
|
import useMemberStore from '@/stores/member'
|
||||||
import useMemberStore from '@/stores/member'
|
import useConfigStore from '@/stores/config'
|
||||||
import useConfigStore from '@/stores/config'
|
import useSystemStore from '@/stores/system'
|
||||||
import useSystemStore from '@/stores/system'
|
import { useLogin } from '@/hooks/useLogin'
|
||||||
import { useLogin } from '@/hooks/useLogin'
|
import { useShare } from '@/hooks/useShare'
|
||||||
|
|
||||||
onLaunch(async (data) => {
|
onLaunch(async(data) => {
|
||||||
|
|
||||||
// 添加初始化拦截器
|
// 添加初始化拦截器
|
||||||
launchInterceptor()
|
launchInterceptor()
|
||||||
|
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
uni.getSystemInfoSync().platform == 'ios' && (uni.setStorageSync('initUrl', location.href))
|
uni.getSystemInfoSync().platform == 'ios' && (uni.setStorageSync('initUrl', location.href))
|
||||||
|
|
||||||
// 传输给后台数据
|
// 传输给后台数据
|
||||||
window.parent.postMessage(JSON.stringify({
|
window.parent.postMessage(JSON.stringify({
|
||||||
@ -26,11 +26,11 @@
|
|||||||
window.addEventListener('message', event => {
|
window.addEventListener('message', event => {
|
||||||
try {
|
try {
|
||||||
let data = {
|
let data = {
|
||||||
type :''
|
type: ''
|
||||||
};
|
};
|
||||||
if(typeof event.data == 'string') {
|
if (typeof event.data == 'string') {
|
||||||
data = JSON.parse(event.data)
|
data = JSON.parse(event.data)
|
||||||
}else if(typeof event.data == 'object') {
|
} else if (typeof event.data == 'object') {
|
||||||
data = event.data
|
data = event.data
|
||||||
}
|
}
|
||||||
if (data.type && data.type == 'appOnReady') {
|
if (data.type && data.type == 'appOnReady') {
|
||||||
@ -44,45 +44,65 @@
|
|||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
// #endif
|
const { wechatInit } = useShare()
|
||||||
|
wechatInit()
|
||||||
|
// #endif
|
||||||
|
|
||||||
const configStore = useConfigStore()
|
const configStore = useConfigStore()
|
||||||
await configStore.getLoginConfig()
|
await configStore.getTabbarConfig()
|
||||||
|
await configStore.getLoginConfig()
|
||||||
|
|
||||||
useSystemStore().getSiteInfoFn()
|
useSystemStore().getMapFn()
|
||||||
|
useSystemStore().getSiteInfoFn()
|
||||||
|
useMemberStore().getMemberLevel()
|
||||||
|
try {
|
||||||
|
// 隐藏tabbar
|
||||||
|
uni.hideTabBar()
|
||||||
|
} catch (e) {
|
||||||
|
|
||||||
// 隐藏tabbar
|
}
|
||||||
uni.hideTabBar()
|
|
||||||
|
|
||||||
// 判断是否已登录
|
// 判断是否已登录
|
||||||
if (getToken()) {
|
if (getToken()) {
|
||||||
const memberStore = useMemberStore()
|
const memberStore = useMemberStore()
|
||||||
await memberStore.setToken(getToken())
|
await memberStore.setToken(getToken())
|
||||||
}
|
|
||||||
|
|
||||||
if (!getToken()) {
|
setTimeout(() => {
|
||||||
const login = useLogin()
|
if (!uni.getStorageSync('openid')) {
|
||||||
// 三方平台自动登录
|
const memberInfo = useMemberStore().info
|
||||||
// #ifdef MP
|
// #ifdef MP-WEIXIN
|
||||||
login.getAuthCode()
|
memberInfo && memberInfo.weapp_openid && uni.setStorageSync('openid', memberInfo.weapp_openid)
|
||||||
// #endif
|
// #endif
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
if (isWeixinBrowser()) {
|
isWeixinBrowser() && memberInfo && memberInfo.wx_openid && uni.setStorageSync('openid', memberInfo.wx_openid)
|
||||||
data.query.code ? login.authLogin(data.query.code) : login.getAuthCode('snsapi_userinfo')
|
// #endif
|
||||||
}
|
}
|
||||||
// #endif
|
}, 1000)
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
onShow(() => {
|
if (!getToken()) {
|
||||||
})
|
const login = useLogin()
|
||||||
|
// 第三方平台自动登录
|
||||||
|
// #ifdef MP
|
||||||
|
login.getAuthCode()
|
||||||
|
// #endif
|
||||||
|
// #ifdef H5
|
||||||
|
if (isWeixinBrowser()) {
|
||||||
|
data.query.code ? login.authLogin(data.query.code) : login.getAuthCode('snsapi_userinfo')
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
onHide(() => {
|
onShow(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onHide(() => {
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
uni-page-head {
|
uni-page-head {
|
||||||
display: none!important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
.draggable-element {
|
.draggable-element,.ignore-draggable-element {
|
||||||
&.decorate {
|
&.decorate {
|
||||||
&:hover:before {
|
&:hover:before {
|
||||||
content: '';
|
content: '';
|
||||||
@ -7,11 +7,10 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
border: 4rpx solid $u-primary;
|
border: 4rpx dotted $u-primary;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
cursor: move;
|
cursor: move;
|
||||||
border-style: dotted;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.selected:before {
|
&.selected:before {
|
||||||
|
|||||||
@ -1,47 +1,55 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="diy-group" id="componentList">
|
<view class="diy-group" id="componentList">
|
||||||
<view v-for="(component, index) in data.value" :key="component.id"
|
<top-tabbar :scrollTop="topTabbarScrollBool" v-if="data.global && Object.keys(data.global).length && data.global.topStatusBar && data.global.topStatusBar.isShow" ref="topTabbarRef" :data="data.global" />
|
||||||
@click="diyStore.changeCurrentIndex(index, component)"
|
<view v-for="(component, index) in data.value" :key="component.id" @click="diyStore.changeCurrentIndex(index, component)" :class="getComponentClass(index,component)" :style="component.pageStyle">
|
||||||
:class="getComponentClass(index,component)" :style="component.pageStyle">
|
<view class="relative" :style="{ marginTop : component.margin.top < 0 ? (component.margin.top * 2) + 'rpx' : '0' }">
|
||||||
<template v-if="component.componentName == 'ActiveCube'">
|
|
||||||
<diy-active-cube :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-active-cube>
|
<!-- 装修模式下,设置负上边距后超出的内容,禁止选中设置 -->
|
||||||
</template>
|
<view v-if="isShowPlaceHolder(index,component)" class="absolute w-full z-1" :style="{ height : (component.margin.top * 2 * -1) + 'rpx' }" @click.stop="placeholderEvent"></view>
|
||||||
<template v-if="component.componentName == 'CarouselSearch'">
|
|
||||||
<diy-carousel-search :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-carousel-search>
|
<template v-if="component.componentName == 'GraphicNav'">
|
||||||
</template>
|
<diy-graphic-nav :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount" />
|
||||||
<template v-if="component.componentName == 'FloatBtn'">
|
</template>
|
||||||
<diy-float-btn :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-float-btn>
|
<template v-if="component.componentName == 'HorzBlank'">
|
||||||
</template>
|
<diy-horz-blank :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount" />
|
||||||
<template v-if="component.componentName == 'GraphicNav'">
|
</template>
|
||||||
<diy-graphic-nav :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-graphic-nav>
|
<template v-if="component.componentName == 'HorzLine'">
|
||||||
</template>
|
<diy-horz-line :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount" />
|
||||||
<template v-if="component.componentName == 'HorzBlank'">
|
</template>
|
||||||
<diy-horz-blank :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-horz-blank>
|
<template v-if="component.componentName == 'HotArea'">
|
||||||
</template>
|
<diy-hot-area :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount" />
|
||||||
<template v-if="component.componentName == 'HorzLine'">
|
</template>
|
||||||
<diy-horz-line :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-horz-line>
|
<template v-if="component.componentName == 'ImageAds'">
|
||||||
</template>
|
<diy-image-ads :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount" />
|
||||||
<template v-if="component.componentName == 'HotArea'">
|
</template>
|
||||||
<diy-hot-area :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-hot-area>
|
<template v-if="component.componentName == 'MemberInfo'">
|
||||||
</template>
|
<diy-member-info :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount" />
|
||||||
<template v-if="component.componentName == 'ImageAds'">
|
</template>
|
||||||
<diy-image-ads :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-image-ads>
|
<template v-if="component.componentName == 'MemberLevel'">
|
||||||
</template>
|
<diy-member-level :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount" />
|
||||||
<template v-if="component.componentName == 'MemberInfo'">
|
</template>
|
||||||
<diy-member-info :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-member-info>
|
<template v-if="component.componentName == 'Notice'">
|
||||||
</template>
|
<diy-notice :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount" />
|
||||||
<template v-if="component.componentName == 'Notice'">
|
</template>
|
||||||
<diy-notice :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-notice>
|
<template v-if="component.componentName == 'RubikCube'">
|
||||||
</template>
|
<diy-rubik-cube :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount" />
|
||||||
<template v-if="component.componentName == 'RichText'">
|
</template>
|
||||||
<diy-rich-text :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-rich-text>
|
<template v-if="component.componentName == 'Text'">
|
||||||
</template>
|
<diy-text :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount" />
|
||||||
<template v-if="component.componentName == 'RubikCube'">
|
</template>
|
||||||
<diy-rubik-cube :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-rubik-cube>
|
<template v-if="component.componentName == 'RichText'">
|
||||||
</template>
|
<diy-rich-text :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"/>
|
||||||
<template v-if="component.componentName == 'Text'">
|
</template>
|
||||||
<diy-text :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-text>
|
<template v-if="component.componentName == 'ActiveCube'">
|
||||||
</template>
|
<diy-active-cube :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"/>
|
||||||
|
</template>
|
||||||
|
<template v-if="component.componentName == 'FloatBtn'">
|
||||||
|
<diy-float-btn :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount"/>
|
||||||
|
</template>
|
||||||
|
<template v-if="component.componentName == 'CarouselSearch'">
|
||||||
|
<diy-carousel-search ref="carouselSearchRef" :scrollTop="carouselSearchScrollBool" :component="component" :global="data.global" :index="index" :pullDownRefreshCount="props.pullDownRefreshCount" />
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<template v-if="diyStore.mode == '' && data.global.bottomTabBarSwitch">
|
<template v-if="diyStore.mode == '' && data.global.bottomTabBarSwitch">
|
||||||
<view class="pt-[20rpx]"></view>
|
<view class="pt-[20rpx]"></view>
|
||||||
@ -50,57 +58,73 @@
|
|||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import topTabbar from '@/components/top-tabbar/top-tabbar.vue'
|
||||||
|
|
||||||
import useDiyStore from '@/app/stores/diy';
|
import useDiyStore from '@/app/stores/diy';
|
||||||
import { ref, onMounted, nextTick, computed } from 'vue';
|
import { ref, onMounted, nextTick, computed, watch } from 'vue';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import { getLocation } from '@/utils/common';
|
||||||
import Sortable from 'sortablejs';
|
import Sortable from 'sortablejs';
|
||||||
import { range } from 'lodash-es';
|
import { range } from 'lodash-es';
|
||||||
|
import { onPageScroll } from '@dcloudio/uni-app'
|
||||||
import useConfigStore from '@/stores/config'
|
import useConfigStore from '@/stores/config'
|
||||||
|
|
||||||
const props = defineProps(['data','pullDownRefreshCount']);
|
const props = defineProps(['data','pullDownRefreshCount']);
|
||||||
const diyStore = useDiyStore();
|
const diyStore = useDiyStore();
|
||||||
|
const router = useRouter();
|
||||||
const data = computed(() => {
|
const data = computed(()=>{
|
||||||
if (diyStore.mode == 'decorate') {
|
if (diyStore.mode == 'decorate') {
|
||||||
return diyStore;
|
return diyStore;
|
||||||
} else {
|
} else {
|
||||||
return props.data;
|
return props.data;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let carouselSearchRef = ref(null)
|
||||||
|
let carouselSearchScrollValue = 0
|
||||||
|
let topTabbarRef = ref(null)
|
||||||
|
let topTabbarScrollValue = 0
|
||||||
|
|
||||||
|
// 兼容轮播搜索组件-切换分类时,导致个人中心白屏 - start
|
||||||
|
// #ifdef H5
|
||||||
|
watch(() => router.currentRoute.value, (newRoute) => {
|
||||||
|
if(newRoute.path != "/addon/shop/pages/index"){
|
||||||
|
diyStore.topFixedStatus = 'home'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef MP
|
||||||
|
wx.onAppRoute(function(res) {
|
||||||
|
if(res.path != "addon/shop/pages/index"){
|
||||||
|
diyStore.topFixedStatus = 'home'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
// 兼容轮播搜索组件-切换分类时,导致个人中心白屏 - end
|
||||||
|
|
||||||
const tabbarAddonName = computed(() => {
|
const tabbarAddonName = computed(() => {
|
||||||
return useConfigStore().addon;
|
return useConfigStore().addon;
|
||||||
})
|
})
|
||||||
|
|
||||||
const positionFixed = ref(['fixed', 'top_fixed','right_fixed','bottom_fixed','left_fixed'])
|
const positionFixed = ref(['fixed', 'top_fixed','right_fixed','bottom_fixed','left_fixed']);
|
||||||
|
|
||||||
const getComponentClass = (index:any,component:any) => {
|
const getComponentClass = (index:any,component:any) => {
|
||||||
|
let obj: any = {
|
||||||
|
relative: true,
|
||||||
|
selected: diyStore.currentIndex == index,
|
||||||
|
decorate: diyStore.mode == 'decorate'
|
||||||
|
}
|
||||||
|
obj['top-fixed-' + diyStore.topFixedStatus] = true;
|
||||||
|
|
||||||
let obj: any = {
|
if (component.position && positionFixed.value.indexOf(component.position) != -1) {
|
||||||
|
// 找出置顶组件,设置禁止拖动
|
||||||
relative: true,
|
obj['ignore-draggable-element'] = true;
|
||||||
|
} else {
|
||||||
selected: diyStore.currentIndex == index,
|
obj['draggable-element'] = true;
|
||||||
|
}
|
||||||
decorate: diyStore.mode == 'decorate'
|
return obj;
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
obj['top-fixed-' + diyStore.topFixedStatus] = true;
|
|
||||||
|
|
||||||
if (component.position && positionFixed.value.indexOf(component.position) != -1) {
|
|
||||||
|
|
||||||
// 找出置顶组件,设置禁止拖动
|
|
||||||
|
|
||||||
obj['ignore-draggable-element'] = true;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
obj['draggable-element'] = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@ -117,11 +141,9 @@
|
|||||||
diyStore.value.splice(event.newIndex!, 0, temp);
|
diyStore.value.splice(event.newIndex!, 0, temp);
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
sortable.sort(
|
sortable.sort(range(diyStore.value.length).map(value => {
|
||||||
range(diyStore.value.length).map(value => {
|
return value.toString();
|
||||||
return value.toString();
|
}));
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
diyStore.postMessage(event.newIndex, diyStore.value[event.newIndex]);
|
diyStore.postMessage(event.newIndex, diyStore.value[event.newIndex]);
|
||||||
});
|
});
|
||||||
@ -129,7 +151,76 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (data.value.global && data.value.global.topStatusBar && data.value.global.topStatusBar.style == 'style-4') {
|
||||||
|
// 第一次获取经纬度
|
||||||
|
getLocation()
|
||||||
|
}
|
||||||
|
// 获取轮播搜索的滚动值
|
||||||
|
carouselSearchScrollValue = carouselSearchRef.value ? carouselSearchRef.value[0].scrollValue : 0;
|
||||||
|
// 获取top-tabbar的滚动值
|
||||||
|
topTabbarScrollValue = topTabbarRef.value ? topTabbarRef.value.scrollValue : 0;
|
||||||
|
}, 500)
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 是否显示占位区域,用于禁止选中负上边距的内容
|
||||||
|
const isShowPlaceHolder = (index: any, component: any) => {
|
||||||
|
// #ifdef H5
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
let el: any = document.getElementById('componentList');
|
||||||
|
if (el && el.children.length && el.children[index]) {
|
||||||
|
let height = el.children[index].offsetHeight;
|
||||||
|
let top = 0;
|
||||||
|
if (component.margin.top < 0) {
|
||||||
|
top = component.margin.top * 2 * -1;
|
||||||
|
// 若负上边距大于组件的高度,则允许选中进行装修
|
||||||
|
if (top > height) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 空函数,禁止选中
|
||||||
|
const placeholderEvent = ()=>{}
|
||||||
|
|
||||||
|
// 页面onShow调用时,也会触发改方法
|
||||||
|
const refresh = ()=>{
|
||||||
|
nextTick(()=>{
|
||||||
|
topTabbarRef.value?.refresh();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当页面滚动值超出轮播搜索滚动值时,carouselSearchScrollBool会变成true,触发相对应变化
|
||||||
|
let carouselSearchScrollBool = ref(false)
|
||||||
|
// 当页面滚动值超出轮播搜索滚动值时,top-tabbar会变成true,触发相对应变化
|
||||||
|
let topTabbarScrollBool = ref(false)
|
||||||
|
onPageScroll((e)=>{
|
||||||
|
// 轮播搜索
|
||||||
|
if(e.scrollTop > carouselSearchScrollValue){
|
||||||
|
carouselSearchScrollBool.value = true
|
||||||
|
}else{
|
||||||
|
carouselSearchScrollBool.value = false
|
||||||
|
}
|
||||||
|
// top-tabbar
|
||||||
|
if(e.scrollTop > topTabbarScrollValue){
|
||||||
|
topTabbarScrollBool.value = true
|
||||||
|
}else{
|
||||||
|
topTabbarScrollBool.value = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
refresh
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import './index.scss';
|
@import './index.scss';
|
||||||
|
|||||||
@ -33,7 +33,9 @@ export function logout() {
|
|||||||
*/
|
*/
|
||||||
export function usernameRegister(data : AnyObject) {
|
export function usernameRegister(data : AnyObject) {
|
||||||
let url = 'register'
|
let url = 'register'
|
||||||
data.pid && (url += `?pid=${data.pid}`)
|
if(uni.getStorageSync('pid')){
|
||||||
|
data.pid = uni.getStorageSync('pid');
|
||||||
|
}
|
||||||
return request.post(url, data, { showErrorMessage: true })
|
return request.post(url, data, { showErrorMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,10 +44,26 @@ export function usernameRegister(data : AnyObject) {
|
|||||||
*/
|
*/
|
||||||
export function mobileRegister(data : AnyObject) {
|
export function mobileRegister(data : AnyObject) {
|
||||||
let url = 'register/mobile'
|
let url = 'register/mobile'
|
||||||
data.pid && (url += `?pid=${data.pid}`)
|
if(uni.getStorageSync('pid')){
|
||||||
|
data.pid = uni.getStorageSync('pid');
|
||||||
|
}
|
||||||
return request.post(url, data, { showErrorMessage: true })
|
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 })
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信公众号授权登录
|
* 微信公众号授权登录
|
||||||
*/
|
*/
|
||||||
@ -54,7 +72,7 @@ export function wechatLogin(data : AnyObject) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信公众号授权登录
|
* 微信小程序授权登录
|
||||||
*/
|
*/
|
||||||
export function weappLogin(data : AnyObject) {
|
export function weappLogin(data : AnyObject) {
|
||||||
return request.post('weapp/login', data, { showErrorMessage: false })
|
return request.post('weapp/login', data, { showErrorMessage: false })
|
||||||
@ -65,7 +83,9 @@ export function weappLogin(data : AnyObject) {
|
|||||||
*/
|
*/
|
||||||
export function bind(data : AnyObject) {
|
export function bind(data : AnyObject) {
|
||||||
let url = 'bind'
|
let url = 'bind'
|
||||||
data.pid && (url += `?pid=${data.pid}`)
|
if(uni.getStorageSync('pid')){
|
||||||
|
data.pid = uni.getStorageSync('pid');
|
||||||
|
}
|
||||||
return request.post(url, data, { showErrorMessage: true })
|
return request.post(url, data, { showErrorMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,20 +3,27 @@ import request from '@/utils/request'
|
|||||||
/**
|
/**
|
||||||
* 获取自定义页面信息
|
* 获取自定义页面信息
|
||||||
*/
|
*/
|
||||||
export function getDiyInfo(params : Record<string, any>) {
|
export function getDiyInfo(params: Record<string, any>) {
|
||||||
return request.get('diy/diy', params)
|
return request.get('diy/diy', params)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取底部导航信息
|
* 获取底部导航信息
|
||||||
*/
|
*/
|
||||||
export function getTabbarInfo(params : Record<string, any>) {
|
export function getTabbarInfo(params: Record<string, any>) {
|
||||||
return request.get('diy/tabbar', params)
|
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>) {
|
export function getShareInfo(params: Record<string, any>) {
|
||||||
return request.get('diy/share', params)
|
return request.get('diy/share', params)
|
||||||
}
|
}
|
||||||
@ -17,6 +17,12 @@ export function getPointList(data : AnyObject) {
|
|||||||
export function getBalanceList(data : AnyObject) {
|
export function getBalanceList(data : AnyObject) {
|
||||||
return request.get('member/account/balance', data)
|
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 })
|
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)
|
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
|
* @param params
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getAddressList(params: Record<string, any>) {
|
export function getAddressList(params: Record<string, any>) {
|
||||||
return request.get(`member/address`, {params})
|
return request.get(`member/address`, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -167,3 +186,59 @@ export function editAddress(params: Record<string, any>) {
|
|||||||
export function deleteAddress(id: number) {
|
export function deleteAddress(id: number) {
|
||||||
return request.delete(`member/address/${id}`, { showErrorMessage: true, showSuccessMessage: true })
|
return request.delete(`member/address/${id}`, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取会员等级
|
||||||
|
*/
|
||||||
|
export function getMemberLevel() {
|
||||||
|
return request.get(`member/level`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取成长值任务
|
||||||
|
*/
|
||||||
|
export function getTaskGrowth() {
|
||||||
|
return request.get(`task/growth`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取签到日期
|
||||||
|
*/
|
||||||
|
export function getSignInfo(data : AnyObject) {
|
||||||
|
return request.get(`member/sign/info/${data.year}/${data.month}`, {})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取日签到奖励
|
||||||
|
*/
|
||||||
|
export function getDayPack(data : AnyObject) {
|
||||||
|
return request.get(`member/sign/award/${data.year}/${data.month}/${data.day}`)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 获取签到设置
|
||||||
|
*/
|
||||||
|
export function getSignConfig() {
|
||||||
|
return request.get(`member/sign/config`)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 点击签到
|
||||||
|
* @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`)
|
||||||
|
}
|
||||||
@ -4,69 +4,69 @@ import request from '@/utils/request'
|
|||||||
* 获取验证码
|
* 获取验证码
|
||||||
*/
|
*/
|
||||||
export function getCaptcha() {
|
export function getCaptcha() {
|
||||||
return request.get('captcha', {}, { showErrorMessage: true })
|
return request.get('captcha', {}, {showErrorMessage: true})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取微信公众号授权码
|
* 获取微信公众号授权码
|
||||||
*/
|
*/
|
||||||
export function getWechatAuthCode(data : AnyObject) {
|
export function getWechatAuthCode(data: AnyObject) {
|
||||||
return request.get('wechat/codeurl', data, { showErrorMessage: false })
|
return request.get('wechat/codeurl', data, {showErrorMessage: false})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 同步微信信息
|
* 同步微信信息
|
||||||
*/
|
*/
|
||||||
export function wechatSync(data : AnyObject) {
|
export function wechatSync(data: AnyObject) {
|
||||||
return request.post('wechat/sync', data)
|
return request.post('wechat/sync', data, {showErrorMessage: false})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取协议信息
|
* 获取协议信息
|
||||||
*/
|
*/
|
||||||
export function getAgreementInfo(key : string) {
|
export function getAgreementInfo(key: string) {
|
||||||
return request.get(`agreement/${key}`)
|
return request.get(`agreement/${key}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置密码
|
* 重置密码
|
||||||
*/
|
*/
|
||||||
export function resetPassword(data : AnyObject) {
|
export function resetPassword(data: AnyObject) {
|
||||||
return request.post(`password/reset`, data, { showErrorMessage: true })
|
return request.post(`password/reset`, data, {showErrorMessage: true})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送短信验证码
|
* 发送短信验证码
|
||||||
*/
|
*/
|
||||||
export function sendSms(data : AnyObject) {
|
export function sendSms(data: AnyObject) {
|
||||||
return request.post(`send/mobile/${data.type}`, data, { showErrorMessage: true })
|
return request.post(`send/mobile/${data.type}`, data, {showErrorMessage: true})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取微信jssdk config
|
* 获取微信jssdk config
|
||||||
*/
|
*/
|
||||||
export function getWechatSkdConfig(data : AnyObject) {
|
export function getWechatSkdConfig(data: AnyObject) {
|
||||||
return request.get('wechat/jssdkconfig', data, { showErrorMessage: false })
|
return request.get('wechat/jssdkconfig', data, {showErrorMessage: false})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传图片
|
* 上传图片
|
||||||
*/
|
*/
|
||||||
export function uploadImage(data : AnyObject) {
|
export function uploadImage(data: AnyObject) {
|
||||||
return request.upload('file/image', data, { showErrorMessage: true })
|
return request.upload('file/image', data, {showErrorMessage: true})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 拉取图片
|
* 拉取图片
|
||||||
*/
|
*/
|
||||||
export function fetchImage(data : AnyObject) {
|
export function fetchImage(data: AnyObject) {
|
||||||
return request.post('file/image/fetch', data)
|
return request.post('file/image/fetch', data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 拉取base64图片
|
* 拉取base64图片
|
||||||
*/
|
*/
|
||||||
export function fetchBase64Image(data : AnyObject) {
|
export function fetchBase64Image(data: AnyObject) {
|
||||||
return request.post('file/image/base64', data)
|
return request.post('file/image/base64', data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ export function getSiteInfo() {
|
|||||||
* 获取微信小程序订阅消息模板id
|
* 获取微信小程序订阅消息模板id
|
||||||
*/
|
*/
|
||||||
export function getWeappTemplateId(keys: string) {
|
export function getWeappTemplateId(keys: string) {
|
||||||
return request.get('weapp/subscribemsg', { keys })
|
return request.get('weapp/subscribemsg', {keys})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,10 +108,18 @@ export function getAreaByCode(code: number | string) {
|
|||||||
return request.get(`area/code/${code}`)
|
return request.get(`area/code/${code}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过经纬度查询地址
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export function getAddressByLatlng(params: Record<string, any>) {
|
||||||
|
return request.get(`area/address_by_latlng`, params, {showErrorMessage: true})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取手机端首页列表
|
* 获取手机端首页列表
|
||||||
*/
|
*/
|
||||||
export function getWapIndexList(data : AnyObject) {
|
export function getWapIndexList(data: AnyObject) {
|
||||||
return request.get('wap_index', data)
|
return request.get('wap_index', data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,6 +127,21 @@ export function getWapIndexList(data : AnyObject) {
|
|||||||
* 获取海报
|
* 获取海报
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getPoster(params : Record<string, any>) {
|
export function getPoster(params: Record<string, any>) {
|
||||||
return request.get("poster", params)
|
return request.get("poster", params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取地图设置
|
||||||
|
*/
|
||||||
|
export function getMap() {
|
||||||
|
return request.get('map')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过外部交易号获取消息跳转路径
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export function getMsgJumpPath(params: Record<string, any>) {
|
||||||
|
return request.get('weapp/getMsgJumpPath', params)
|
||||||
|
}
|
||||||
|
|||||||
47
uni-app/src/app/api/verify.ts
Normal file
47
uni-app/src/app/api/verify.ts
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取核销信息
|
||||||
|
*/
|
||||||
|
export function getVerifyCode(type: string ,params: AnyObject) {
|
||||||
|
return request.get('verify', {type, data: params})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取核销记录
|
||||||
|
*/
|
||||||
|
export function getVerifyRecords(params: Record<string, any>) {
|
||||||
|
return request.get('verify_records', params)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否是核销员
|
||||||
|
*/
|
||||||
|
export function getCheckVerifier() {
|
||||||
|
return request.get('check_verifier')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取核销信息
|
||||||
|
*/
|
||||||
|
export function getVerifierInfo(code: string) {
|
||||||
|
return request.get(`get_verify_by_code/${code}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 核销
|
||||||
|
*/
|
||||||
|
export function verify(code: string) {
|
||||||
|
return request.post(`verify/${code}`,{}, { showSuccessMessage: true, showErrorMessage: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取核销详情
|
||||||
|
*/
|
||||||
|
export function getVerifyDetail(code: string) {
|
||||||
|
return request.get(`verify_detail/${code}`,{}, { showErrorMessage: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -4,32 +4,32 @@
|
|||||||
<view class="diy-active-cube relative">
|
<view class="diy-active-cube relative">
|
||||||
<view class="active-cube-wrap p-[20rpx]">
|
<view class="active-cube-wrap p-[20rpx]">
|
||||||
<view class="flex items-center" v-if="diyComponent.titleStyle.value == 'style-1'">
|
<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 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="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 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>
|
||||||
<view class="flex items-center" v-if="diyComponent.titleStyle.value == 'style-2'">
|
<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 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="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 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>
|
||||||
<view class="flex items-center" v-if="diyComponent.titleStyle.value == 'style-3'">
|
<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="mr-[20rpx] font-bold text-[32rpx]" @click="diyStore.toRedirect(diyComponent.textLink)" :style="{color: diyComponent.titleColor }">{{ diyComponent.text }}</view>
|
||||||
<view class="relative h-[44rpx]" @click="toRedirect(diyComponent.subTitle.link)">
|
<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>
|
<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 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"/>
|
<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>
|
</view>
|
||||||
<view class="flex items-center justify-between" v-if="diyComponent.titleStyle.value == 'style-4'">
|
<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 class="font-bold text-[32rpx]" @click="diyStore.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 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>{{ 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>
|
</view>
|
||||||
|
|
||||||
<view class="bd flex flex-wrap justify-between">
|
<view class="bd flex flex-wrap justify-between">
|
||||||
<template v-for="item in diyComponent.list" :key="item.id">
|
<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="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--[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>
|
<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>
|
<u-icon name="photo" color="#999" size="50"></u-icon>
|
||||||
</view>
|
</view>
|
||||||
</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="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--[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>
|
<view class="text--[24rpx] text-gray-500 pb-[20rpx]">{{ item.subTitle.text }}</view>
|
||||||
@ -64,15 +64,14 @@
|
|||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
</view>
|
</view>
|
||||||
|
<scroll-view scroll-x="true" class="whitespace-nowrap" :id="'warpStyle3-'+diyComponent.id" v-if="diyComponent.blockStyle.value == 'style-3'">
|
||||||
<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 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 :id="'item'+index+diyComponent.id" @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" :style="itemStyle3" :class="{'!mr-[0rpx]': index+1 === diyComponent.list.length}">
|
||||||
<view class="w-[140rpx] h-[140rpx]" v-if="item.imageUrl">
|
<view class="w-[141rpx] h-[141rpx]" v-if="item.imageUrl">
|
||||||
<image class="w-[140rpx] h-[140rpx]" :src="img(item.imageUrl)" mode="aspectFit" />
|
<image class="w-[141rpx] h-[141rpx]" :src="img(item.imageUrl)" mode="aspectFit" />
|
||||||
</view>
|
</view>
|
||||||
<view class="w-[140rpx] h-[140rpx] relative flex-shrink-0" v-else>
|
<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-[140rpx] h-[140rpx] bg-[#f3f4f6]">
|
<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>
|
<u-icon name="photo" color="#999" size="50"></u-icon>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -81,10 +80,10 @@
|
|||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
|
|
||||||
<scroll-view scroll-x="true" class="whitespace-nowrap" v-if="diyComponent.blockStyle.value == 'style-4'">
|
<scroll-view scroll-x="true" class="whitespace-nowrap" :id="'warpStyle4-'+diyComponent.id" v-if="diyComponent.blockStyle.value == 'style-4'">
|
||||||
<view v-for="(item,index) in diyComponent.list" :key="item.id" class="inline-flex">
|
<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 :id="'item'+index+diyComponent.id" @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-[0rpx]': index+1 === diyComponent.list.length}" :style="'background :linear-gradient('+ item.listFrame.startColor +','+ item.listFrame.endColor + ');'+itemStyle4">
|
||||||
<view class="w-[148rpx] h-[148rpx] box-border px-[18rpx] pt-[16rpx] pb-[6rpx] bg-[#fff] flex flex-col items-center rounded-[16rpx]">
|
<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">
|
<view class="w-[112rpx] h-[102rpx]" v-if="item.imageUrl">
|
||||||
<image class="w-[112rpx] h-[102rpx]" :src="img(item.imageUrl)" mode="aspectFit" />
|
<image class="w-[112rpx] h-[102rpx]" :src="img(item.imageUrl)" mode="aspectFit" />
|
||||||
</view>
|
</view>
|
||||||
@ -108,8 +107,7 @@
|
|||||||
// 活动魔方组件
|
// 活动魔方组件
|
||||||
import { ref,computed, watch, onMounted, nextTick,getCurrentInstance } from 'vue';
|
import { ref,computed, watch, onMounted, nextTick,getCurrentInstance } from 'vue';
|
||||||
import useDiyStore from '@/app/stores/diy';
|
import useDiyStore from '@/app/stores/diy';
|
||||||
import { img, redirect,diyRedirect, currRoute, getToken } from '@/utils/common';
|
import { img } from '@/utils/common';
|
||||||
import { useLogin } from '@/hooks/useLogin';
|
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
||||||
|
|
||||||
@ -161,7 +159,35 @@
|
|||||||
|
|
||||||
return style;
|
return style;
|
||||||
});
|
});
|
||||||
|
//商品样式三
|
||||||
|
const itemStyle3 = ref('');
|
||||||
|
const setItemStyle3 = ()=>{
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
uni.createSelectorQuery().in(instance).select('#warpStyle3-'+diyComponent.value.id).boundingClientRect((res:any) => {
|
||||||
|
uni.createSelectorQuery().in(instance).select('#item0'+diyComponent.value.id).boundingClientRect((data:any) => {
|
||||||
|
itemStyle3.value = `margin-right:${(res.width - data.width*4)/3}px;`
|
||||||
|
}).exec()
|
||||||
|
}).exec()
|
||||||
|
// #endif
|
||||||
|
// #ifdef H5
|
||||||
|
itemStyle3.value= 'margin-right:14rpx;'
|
||||||
|
// #endif
|
||||||
|
};
|
||||||
|
//商品样式四
|
||||||
|
const itemStyle4 = ref('');
|
||||||
|
const setItemStyle4 = ()=>{
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
uni.createSelectorQuery().in(instance).select('#warpStyle4-'+diyComponent.value.id).boundingClientRect((res:any) => {
|
||||||
|
uni.createSelectorQuery().in(instance).select('#item0'+diyComponent.value.id).boundingClientRect((data:any) => {
|
||||||
|
itemStyle4.value = `margin-right:${(res.width - data.width*4)/3}px;`
|
||||||
|
|
||||||
|
}).exec()
|
||||||
|
}).exec()
|
||||||
|
// #endif
|
||||||
|
// #ifdef H5
|
||||||
|
itemStyle4.value= 'margin-right:14rpx;'
|
||||||
|
// #endif
|
||||||
|
};
|
||||||
const btnCss = (item:any) => {
|
const btnCss = (item:any) => {
|
||||||
var style = '';
|
var style = '';
|
||||||
style += `background:linear-gradient(90deg,${item.startColor},${item.endColor});`;
|
style += `background:linear-gradient(90deg,${item.startColor},${item.endColor});`;
|
||||||
@ -199,21 +225,11 @@
|
|||||||
query.select('.diy-active-cube').boundingClientRect((data: any) => {
|
query.select('.diy-active-cube').boundingClientRect((data: any) => {
|
||||||
height.value = data.height;
|
height.value = data.height;
|
||||||
}).exec();
|
}).exec();
|
||||||
|
|
||||||
|
if(diyComponent.value.blockStyle.value == 'style-3') setItemStyle3()
|
||||||
|
if(diyComponent.value.blockStyle.value == 'style-4') setItemStyle4()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -8,13 +8,13 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="fixed-wrap" :class="[ diyStore.mode != 'decorate' ? diyComponent.positionWay : '' ]" :style="fixedStyle">
|
<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">
|
<view class="img-wrap" v-if="diyComponent.search.logo">
|
||||||
<image :src="img(diyComponent.search.logo)" mode="aspectFit"/>
|
<image :src="img(diyComponent.search.logo)" mode="aspectFit"/>
|
||||||
</view>
|
</view>
|
||||||
<view class="search-content">
|
<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"/>
|
<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 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">
|
<swiper-item class="swiper-item" v-for="(item) in diyComponent.search.hotWord.list" :key="item.id">
|
||||||
@ -36,7 +36,7 @@
|
|||||||
<view class="line" :style="{'background-color': getTabColor(index == currTabIndex)}" v-if="index == currTabIndex"></view>
|
<view class="line" :style="{'background-color': getTabColor(index == currTabIndex)}" v-if="index == currTabIndex"></view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-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>
|
||||||
|
|
||||||
<view class="bg-img" v-if="fixedStyleBg">
|
<view class="bg-img" v-if="fixedStyleBg">
|
||||||
@ -58,11 +58,11 @@
|
|||||||
'swiper-right': diyComponent.swiper.indicatorAlign == 'right',
|
'swiper-right': diyComponent.swiper.indicatorAlign == 'right',
|
||||||
'ns-indicator-dots': diyComponent.swiper.indicatorStyle == 'style-2'
|
'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"
|
:interval="diyComponent.swiper.interval * 1000" :indicator-dots="isShowDots"
|
||||||
:indicator-color="diyComponent.swiper.indicatorColor" :indicator-active-color="diyComponent.swiper.indicatorActiveColor">
|
: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">
|
<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}">
|
<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-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"/>
|
<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>
|
</view>
|
||||||
|
|
||||||
<!-- 分类展开 -->
|
<!-- 分类展开 -->
|
||||||
<u-popup :show="tabAllPopup" mode="top" @close="tabAllPopup = false">
|
<u-popup :safeAreaInsetTop="true" :show="tabAllPopup" mode="top" @close="tabAllPopup = false">
|
||||||
<view class="text-sm px-[30rpx] mt-3" :style="{'padding-top':(menuButtonInfo.top+'px')}">全部分类</view>
|
<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 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 }]">
|
<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,14 +112,14 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
// 轮播搜索
|
// 轮播搜索
|
||||||
import { ref, reactive, computed, watch, onMounted, nextTick, getCurrentInstance } from 'vue';
|
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 useDiyStore from '@/app/stores/diy';
|
||||||
import diyGroup from '@/addon/components/diy/group/index.vue'
|
import diyGroup from '@/addon/components/diy/group/index.vue'
|
||||||
import { getDiyInfo } from '@/app/api/diy';
|
import { getDiyInfo } from '@/app/api/diy';
|
||||||
import { useLogin } from '@/hooks/useLogin';
|
|
||||||
|
|
||||||
const instance = getCurrentInstance();
|
const instance = getCurrentInstance();
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount', 'global']);
|
const props = defineProps(['component', 'index', 'pullDownRefreshCount', 'global','scrollTop']);
|
||||||
|
|
||||||
const diyStore = useDiyStore();
|
const diyStore = useDiyStore();
|
||||||
|
|
||||||
const diyComponent = computed(() => {
|
const diyComponent = computed(() => {
|
||||||
@ -154,10 +154,12 @@
|
|||||||
|
|
||||||
const setModuleLocation = ()=> {
|
const setModuleLocation = ()=> {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
const query = uni.createSelectorQuery().in(instance);
|
setTimeout(()=>{
|
||||||
query.select('.fixed-wrap').boundingClientRect(data => {
|
const query = uni.createSelectorQuery().in(instance);
|
||||||
moduleHeight.value = (data.height || 0) + 'px';
|
query.select('.fixed-wrap').boundingClientRect((data:any) => {
|
||||||
}).exec();
|
moduleHeight.value = (data.height || 0) + 'px';
|
||||||
|
}).exec();
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,9 +167,21 @@
|
|||||||
const fixedStyle = computed(()=>{
|
const fixedStyle = computed(()=>{
|
||||||
if (diyStore.mode == 'decorate') return '';
|
if (diyStore.mode == 'decorate') return '';
|
||||||
var style = '';
|
var style = '';
|
||||||
|
// #ifdef H5
|
||||||
|
if(props.global.topStatusBar.isShow && props.global.topStatusBar.style == 'style-4') {
|
||||||
|
style += 'top:' + diyStore.topTabarHeight + 'px;';
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
if(diyComponent.value.positionWay == 'fixed') {
|
if(diyComponent.value.positionWay == 'fixed') {
|
||||||
|
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
|
||||||
|
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
||||||
|
if(props.global.topStatusBar.isShow) {
|
||||||
|
style += 'top:' + diyStore.topTabarHeight + 'px;';
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
|
||||||
fixedStyleBg.value = false;
|
fixedStyleBg.value = false;
|
||||||
if (diyStore.scrollTop > 20) {
|
if (props.scrollTop) {
|
||||||
let str = diyComponent.value.fixedBgColor;
|
let str = diyComponent.value.fixedBgColor;
|
||||||
let arr = str.split(',');
|
let arr = str.split(',');
|
||||||
let num = diyComponent.value.fixedBgColor ? parseInt(arr[arr.length-1]) : 0;
|
let num = diyComponent.value.fixedBgColor ? parseInt(arr[arr.length-1]) : 0;
|
||||||
@ -186,12 +200,12 @@
|
|||||||
let color = '';
|
let color = '';
|
||||||
if(flag){
|
if(flag){
|
||||||
color = diyComponent.value.tab.selectColor;
|
color = diyComponent.value.tab.selectColor;
|
||||||
if(diyComponent.value.positionWay == 'fixed' && diyStore.scrollTop > 20) {
|
if(diyComponent.value.positionWay == 'fixed' && props.scrollTop) {
|
||||||
color = diyComponent.value.tab.fixedSelectColor;
|
color = diyComponent.value.tab.fixedSelectColor;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
color = diyComponent.value.tab.noColor;
|
color = diyComponent.value.tab.noColor;
|
||||||
if(diyComponent.value.positionWay == 'fixed' && diyStore.scrollTop > 20) {
|
if(diyComponent.value.positionWay == 'fixed' && props.scrollTop) {
|
||||||
color = diyComponent.value.tab.fixedNoColor;
|
color = diyComponent.value.tab.fixedNoColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -215,9 +229,14 @@
|
|||||||
const bgImgBoxStyle = computed(()=>{
|
const bgImgBoxStyle = computed(()=>{
|
||||||
var style = '';
|
var style = '';
|
||||||
let str = props.global.pageStartBgColor ? props.global.pageStartBgColor : 'rgba(255,255,255,1)';
|
let str = props.global.pageStartBgColor ? props.global.pageStartBgColor : 'rgba(255,255,255,1)';
|
||||||
let arr = str.split('(')[1].split(')')[0].split(',');
|
if(str.indexOf('(') > -1) {
|
||||||
if(diyComponent.value.bgGradient == true)
|
let arr = str.split('(')[1].split(')')[0].split(',');
|
||||||
style += `background: linear-gradient(rgba(${arr[0]}, ${arr[1]}, ${arr[2]}, 0) 65%, rgba(${arr[0]}, ${arr[1]}, ${arr[2]}, 0.6) 70%, rgba(${arr[0]}, ${arr[1]}, ${arr[2]}, 0.85) 80%, rgba(${arr[0]}, ${arr[1]}, ${arr[2]}, 0.95) 90%, rgb(${arr[0]}, ${arr[1]}, ${arr[2]}, 1) 100%);`;
|
if (diyComponent.value.bgGradient == true) {
|
||||||
|
style += `background: linear-gradient(rgba(${arr[0]}, ${arr[1]}, ${arr[2]}, 0) 65%, rgba(${arr[0]}, ${arr[1]}, ${arr[2]}, 0.6) 70%, rgba(${arr[0]}, ${arr[1]}, ${arr[2]}, 0.85) 80%, rgba(${arr[0]}, ${arr[1]}, ${arr[2]}, 0.95) 90%, rgb(${arr[0]}, ${arr[1]}, ${arr[2]}, 1) 100%);`;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
style += `background: (${str});`;
|
||||||
|
}
|
||||||
return style;
|
return style;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -228,7 +247,6 @@
|
|||||||
return style;
|
return style;
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const imgHeight = computed(() => {
|
const imgHeight = computed(() => {
|
||||||
return (diyComponent.value.swiper.imageHeight * 2) + 'rpx';
|
return (diyComponent.value.swiper.imageHeight * 2) + 'rpx';
|
||||||
})
|
})
|
||||||
@ -270,6 +288,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let tabAllPopup = ref(false);
|
||||||
|
let menuButtonInfo:any = {};
|
||||||
|
let navbarInnerStyle = ref('')
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
refresh();
|
refresh();
|
||||||
// 装修模式下刷新
|
// 装修模式下刷新
|
||||||
@ -283,6 +305,23 @@
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API,尚未兼容)
|
||||||
|
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
|
||||||
|
if(diyComponent.value.positionWay == 'fixed') {
|
||||||
|
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
||||||
|
// 导航栏内部盒子的样式
|
||||||
|
// 导航栏宽度,如果在小程序下,导航栏宽度为胶囊的左边到屏幕左边的距离
|
||||||
|
// 如果是各家小程序,导航栏内部的宽度需要减少右边胶囊的宽度
|
||||||
|
if(props.global.topStatusBar.isShow == false) {
|
||||||
|
let rightButtonWidth = menuButtonInfo.width ? menuButtonInfo.width * 2 + 'rpx' : '70rpx';
|
||||||
|
navbarInnerStyle.value += 'padding-right:calc(' + rightButtonWidth + ' + 30rpx);';
|
||||||
|
navbarInnerStyle.value += 'padding-top:' + menuButtonInfo.top + 'px;';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const refresh = ()=> {
|
const refresh = ()=> {
|
||||||
@ -299,12 +338,18 @@
|
|||||||
const diyPageData = reactive({
|
const diyPageData = reactive({
|
||||||
pageMode: 'diy',
|
pageMode: 'diy',
|
||||||
title: '',
|
title: '',
|
||||||
global: {},
|
global: <any>{},
|
||||||
value: []
|
value: []
|
||||||
})
|
})
|
||||||
|
|
||||||
const getDiyInfoFn = (id:any) => {
|
const getDiyInfoFn = (id:any) => {
|
||||||
if(!id) return;
|
if(!id){
|
||||||
|
diyPageData.pageMode = 'diy';
|
||||||
|
diyPageData.title = '';
|
||||||
|
diyPageData.global = {};
|
||||||
|
diyPageData.value = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
getDiyInfo({
|
getDiyInfo({
|
||||||
id
|
id
|
||||||
}).then((res : any) => {
|
}).then((res : any) => {
|
||||||
@ -315,6 +360,7 @@
|
|||||||
|
|
||||||
let sources = JSON.parse(data.value);
|
let sources = JSON.parse(data.value);
|
||||||
diyPageData.global = sources.global;
|
diyPageData.global = sources.global;
|
||||||
|
diyPageData.global.topStatusBar.isShow = false; // 子页面不需要展示顶部导航栏
|
||||||
diyPageData.global.bottomTabBarSwitch = false; // 子页面不需要展示底部导航
|
diyPageData.global.bottomTabBarSwitch = false; // 子页面不需要展示底部导航
|
||||||
diyPageData.value = sources.value;
|
diyPageData.value = sources.value;
|
||||||
|
|
||||||
@ -326,7 +372,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (item.margin) {
|
if (item.margin) {
|
||||||
item.pageStyle += 'padding-top:' + item.margin.top * 2 + 'rpx' + ';';
|
if (item.margin.top > 0) {
|
||||||
|
item.pageStyle += 'padding-top:' + item.margin.top * 2 + 'rpx' + ';';
|
||||||
|
}
|
||||||
item.pageStyle += 'padding-bottom:' + item.margin.bottom * 2 + 'rpx' + ';';
|
item.pageStyle += 'padding-bottom:' + item.margin.bottom * 2 + 'rpx' + ';';
|
||||||
item.pageStyle += 'padding-right:' + item.margin.both * 2 + 'rpx' + ';';
|
item.pageStyle += 'padding-right:' + item.margin.both * 2 + 'rpx' + ';';
|
||||||
item.pageStyle += 'padding-left:' + item.margin.both * 2 + 'rpx' + ';';
|
item.pageStyle += 'padding-left:' + item.margin.both * 2 + 'rpx' + ';';
|
||||||
@ -338,36 +386,6 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
let tabAllPopup = ref(false);
|
|
||||||
|
|
||||||
|
|
||||||
let menuButtonInfo = {};
|
|
||||||
let navbarInnerStyle = ref('')
|
|
||||||
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API,尚未兼容)
|
|
||||||
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
|
|
||||||
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
|
||||||
|
|
||||||
// 导航栏内部盒子的样式
|
|
||||||
// 导航栏宽度,如果在小程序下,导航栏宽度为胶囊的左边到屏幕左边的距离
|
|
||||||
// style += 'height:' + this.navbarHeight + 'px;';
|
|
||||||
// // 如果是各家小程序,导航栏内部的宽度需要减少右边胶囊的宽度
|
|
||||||
let rightButtonWidth = menuButtonInfo.width ? menuButtonInfo.width * 2 + 'rpx' : '70rpx';
|
|
||||||
navbarInnerStyle.value += 'padding-right:calc(' + rightButtonWidth + ' + 30rpx);';
|
|
||||||
navbarInnerStyle.value += 'padding-top:' + menuButtonInfo.top + 'px;';
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
const toRedirect = (data: {}) => {
|
|
||||||
if (Object.keys(data).length) {
|
|
||||||
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)
|
let isShowDots = ref(true)
|
||||||
@ -379,6 +397,11 @@
|
|||||||
isShowDots.value = false;
|
isShowDots.value = false;
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
|
// 表示轮播搜素组件,需要判断滚动超出20时,需要做相对应反应
|
||||||
|
defineExpose({
|
||||||
|
scrollValue: 20
|
||||||
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -515,7 +538,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.tab-btn{
|
.tab-btn{
|
||||||
font-size: 32rpx;
|
font-size: 34rpx;
|
||||||
/* #ifdef H5 */
|
/* #ifdef H5 */
|
||||||
top: 22rpx;
|
top: 22rpx;
|
||||||
right: 20rpx;
|
right: 20rpx;
|
||||||
@ -524,9 +547,9 @@
|
|||||||
&::after{
|
&::after{
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 2rpx;
|
top: 6rpx;
|
||||||
bottom: 0;
|
bottom: -2rpx;
|
||||||
left: -16rpx;
|
left: -14rpx;
|
||||||
width: 4rpx;
|
width: 4rpx;
|
||||||
background: linear-gradient( 180deg, #FFFFFF 16%, rgba(255,255,255,0) 92%);
|
background: linear-gradient( 180deg, #FFFFFF 16%, rgba(255,255,255,0) 92%);
|
||||||
}
|
}
|
||||||
@ -568,6 +591,10 @@
|
|||||||
left: 80rpx;
|
left: 80rpx;
|
||||||
transform: translate(0);
|
transform: translate(0);
|
||||||
}
|
}
|
||||||
|
.swiper :deep(.uni-swiper-dot) {
|
||||||
|
width: 12rpx;
|
||||||
|
height: 12rpx;
|
||||||
|
}
|
||||||
.swiper.ns-indicator-dots :deep(.uni-swiper-dot) {
|
.swiper.ns-indicator-dots :deep(.uni-swiper-dot) {
|
||||||
width: 18rpx;
|
width: 18rpx;
|
||||||
height: 6rpx;
|
height: 6rpx;
|
||||||
@ -596,9 +623,9 @@
|
|||||||
|
|
||||||
.swiper-dot {
|
.swiper-dot {
|
||||||
background-color: #b2b2b2;
|
background-color: #b2b2b2;
|
||||||
width: 15rpx;
|
width: 12rpx;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
height: 15rpx;
|
height: 12rpx;
|
||||||
margin: 8rpx;
|
margin: 8rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -615,12 +642,3 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<style lang="scss">
|
|
||||||
.child-diy-template-wrap{
|
|
||||||
::v-deep .diy-group {
|
|
||||||
>.draggable-element {
|
|
||||||
display: block !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :style="warpCss">
|
<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 :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-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"/>
|
<image v-else :src="img('static/resource/images/diy/figure.png')" mode="aspectFit" :style="floatBtnItemCss"/>
|
||||||
</view>
|
</view>
|
||||||
@ -13,8 +13,7 @@
|
|||||||
// 浮动按钮组件
|
// 浮动按钮组件
|
||||||
import { computed, watch } from 'vue';
|
import { computed, watch } from 'vue';
|
||||||
import useDiyStore from '@/app/stores/diy';
|
import useDiyStore from '@/app/stores/diy';
|
||||||
import { img,redirect,diyRedirect, currRoute, getToken } from '@/utils/common';
|
import { img } from '@/utils/common';
|
||||||
import { useLogin } from '@/hooks/useLogin';
|
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
<view v-if="diyComponent.layout == 'vertical'" class="graphic-nav">
|
<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 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]"
|
<view class="graphic-img relative flex items-center w-10 h-10 mr-[20rpx]"
|
||||||
v-if="diyComponent.mode != 'text'"
|
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 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"
|
<view class="graphic-img relative flex items-center justify-center w-10 h-10"
|
||||||
v-if="diyComponent.mode != 'text'"
|
v-if="diyComponent.mode != 'text'"
|
||||||
@ -82,7 +82,7 @@
|
|||||||
v-for="(item, index) in diyComponent.list" :key="item.id"
|
v-for="(item, index) in diyComponent.list" :key="item.id"
|
||||||
:style="{ width: 100 / diyComponent.rowCount + '%' }">
|
: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"
|
<view class="graphic-img relative flex items-center justify-center w-10 h-10"
|
||||||
v-if="diyComponent.mode != 'text'"
|
v-if="diyComponent.mode != 'text'"
|
||||||
:style="{ width: diyComponent.imageSize * 2 + 'rpx', height: diyComponent.imageSize * 2 + 'rpx' }">
|
:style="{ width: diyComponent.imageSize * 2 + 'rpx', height: diyComponent.imageSize * 2 + 'rpx' }">
|
||||||
@ -119,9 +119,8 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
// 图文导航
|
// 图文导航
|
||||||
import { ref,computed, watch, onMounted, nextTick,getCurrentInstance } from 'vue';
|
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 useDiyStore from '@/app/stores/diy';
|
||||||
import { useLogin } from '@/hooks/useLogin';
|
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
||||||
|
|
||||||
@ -240,19 +239,6 @@
|
|||||||
}).exec();
|
}).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>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<template v-if="diyStore.mode != 'decorate'">
|
<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="{
|
:key="mapIndex" :style="{
|
||||||
width: mapItem.width + '%',
|
width: mapItem.width + '%',
|
||||||
height: mapItem.height + '%',
|
height: mapItem.height + '%',
|
||||||
@ -23,8 +23,7 @@
|
|||||||
// 热区
|
// 热区
|
||||||
import { computed, watch, onMounted } from 'vue';
|
import { computed, watch, onMounted } from 'vue';
|
||||||
import useDiyStore from '@/app/stores/diy';
|
import useDiyStore from '@/app/stores/diy';
|
||||||
import { img,redirect,diyRedirect, currRoute, getToken } from '@/utils/common';
|
import { img } from '@/utils/common';
|
||||||
import { useLogin } from '@/hooks/useLogin';
|
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
@ -3,15 +3,15 @@
|
|||||||
<view :style="maskLayer"></view>
|
<view :style="maskLayer"></view>
|
||||||
<view class="diy-image-ads">
|
<view class="diy-image-ads">
|
||||||
<view v-if="diyComponent.list.length == 1" class="leading-0 overflow-hidden" :style="swiperWarpCss">
|
<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-if="diyComponent.list[0].imageUrl" :src="img(diyComponent.list[0].imageUrl)" :style="{height: imgHeight}" mode="heightFix" class="!w-full" :show-menu-by-longpress="true"/>
|
||||||
<image v-else :src="img('static/resource/images/diy/figure.png')" :style="{height: imgHeight}" mode="heightFix" class="w-full" :show-menu-by-longpress="true"/>
|
<image v-else :src="img('static/resource/images/diy/figure.png')" :style="{height: imgHeight}" mode="heightFix" class="!w-full" :show-menu-by-longpress="true"/>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<swiper v-else class="swiper" :style="{ height: imgHeight }" autoplay="true" circular="true" @change="swiperChange">
|
<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">
|
<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}">
|
<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-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"/>
|
<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 { ref,computed, watch, onMounted, nextTick,getCurrentInstance } from 'vue';
|
||||||
import useDiyStore from '@/app/stores/diy';
|
import useDiyStore from '@/app/stores/diy';
|
||||||
import { img,redirect,diyRedirect, currRoute, getToken } from '@/utils/common';
|
import { img } from '@/utils/common';
|
||||||
import { useLogin } from '@/hooks/useLogin';
|
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
||||||
|
|
||||||
@ -135,19 +134,6 @@
|
|||||||
}).exec();
|
}).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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :style="warpCss">
|
<view :style="warpCss">
|
||||||
<view class="pt-[34rpx] member-info">
|
<view class="pt-[34rpx] member-info">
|
||||||
<!-- #ifdef MP-WEIXIN --><view :style="navbarInnerStyle" class="flex items-center justify-center fixed left-0 right-0 z-10 top-0"></view>
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
<!-- 解决fixed定位后导航栏塌陷的问题 -->
|
<!-- 解决fixed定位后导航栏塌陷的问题 -->
|
||||||
<view :style="navbarInnerStyle"></view>
|
<view :style="navbarInnerStyle"></view>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
@ -9,12 +9,14 @@
|
|||||||
<!-- 唤起获取微信 -->
|
<!-- 唤起获取微信 -->
|
||||||
<u-avatar :src="img(info.headimg)" size="55" leftIcon="none" @click="clickAvatar"></u-avatar>
|
<u-avatar :src="img(info.headimg)" size="55" leftIcon="none" @click="clickAvatar"></u-avatar>
|
||||||
<view class="ml-[22rpx]">
|
<view class="ml-[22rpx]">
|
||||||
<view class="text-[#222222] truncate w-[430rpx] font-bold text-lg" :style="{ color : diyComponent.textColor }">{{ info.nickname }}</view>
|
<view class="text-[#222222] flex pr-[50rpx] flex-wrap items-center">
|
||||||
|
<view class="text-[#222222] truncate max-w-[320rpx] font-bold text-lg mr-[16rpx]" :style="{ color : diyComponent.textColor }">{{ info.nickname }}</view>
|
||||||
|
</view>
|
||||||
<view class="text-[#696B70] text-[24rpx] mt-[10rpx]" :style="{ color : diyComponent.textColor }">UID:{{ info.member_no }}</view>
|
<view class="text-[#696B70] text-[24rpx] mt-[10rpx]" :style="{ color : diyComponent.textColor }">UID:{{ info.member_no }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="set-icon flex items-center absolute right-0 top-2">
|
<view class="set-icon flex items-center absolute right-0 top-2">
|
||||||
<view @click="redirect({ url: '/app/pages/setting/index' })">
|
<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>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -27,7 +29,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="set-icon flex items-center absolute right-0 top-2">
|
<view class="set-icon flex items-center absolute right-0 top-2">
|
||||||
<view @click="redirect({ url: '/app/pages/setting/index' })">
|
<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>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -68,7 +70,7 @@
|
|||||||
import { wechatSync } from '@/app/api/system'
|
import { wechatSync } from '@/app/api/system'
|
||||||
import useDiyStore from '@/app/stores/diy'
|
import useDiyStore from '@/app/stores/diy'
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
const props = defineProps(['component', 'index', 'pullDownRefreshCount','global']);
|
||||||
|
|
||||||
const diyStore = useDiyStore();
|
const diyStore = useDiyStore();
|
||||||
|
|
||||||
@ -159,36 +161,21 @@
|
|||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
|
let menuButtonInfo = {};
|
||||||
|
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API,尚未兼容)
|
||||||
// 获取系统状态栏的高度
|
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
|
||||||
let systemInfo = uni.getSystemInfoSync();
|
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
||||||
let platform = systemInfo.platform;
|
// #endif
|
||||||
let menuButtonInfo = {};
|
|
||||||
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API,尚未兼容)
|
|
||||||
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
|
|
||||||
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// 导航栏内部盒子的样式
|
// 导航栏内部盒子的样式
|
||||||
const navbarInnerStyle = computed(() => {
|
const navbarInnerStyle = computed(() => {
|
||||||
let style = '';
|
let style = '';
|
||||||
// 导航栏宽度,如果在小程序下,导航栏宽度为胶囊的左边到屏幕左边的距离
|
// 导航栏宽度,如果在小程序下,导航栏宽度为胶囊的左边到屏幕左边的距离
|
||||||
// #ifdef MP
|
// #ifdef MP
|
||||||
let rightButtonWidth = menuButtonInfo.width ? menuButtonInfo.width * 2 + 'rpx' : '70rpx';
|
if (props.global.topStatusBar.isShow == false) {
|
||||||
style += 'height:' + menuButtonInfo.height + 'px;';
|
style += 'height:' + menuButtonInfo.height + 'px;';
|
||||||
style += 'padding-right:calc(' + rightButtonWidth + ' + 30rpx);';
|
style += 'padding-top:' + menuButtonInfo.top + 'px;';
|
||||||
style += 'padding-left:calc(' + rightButtonWidth + ' + 30rpx);';
|
}
|
||||||
style += 'padding-top:' + (menuButtonInfo.top-15) + 'px;';
|
|
||||||
style += 'padding-bottom: 8px;';
|
|
||||||
style += 'font-size: 32rpx;';
|
|
||||||
if (platform === 'ios') {
|
|
||||||
// 苹果(iOS)设备
|
|
||||||
style += 'font-weight: 500;';
|
|
||||||
} else if (platform === 'android') {
|
|
||||||
// 安卓(Android)设备
|
|
||||||
style += 'font-size: 36rpx;';
|
|
||||||
}
|
|
||||||
// #endif
|
// #endif
|
||||||
return style;
|
return style;
|
||||||
})
|
})
|
||||||
|
|||||||
217
uni-app/src/app/components/diy/member-level/index.vue
Normal file
217
uni-app/src/app/components/diy/member-level/index.vue
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
<template>
|
||||||
|
<view :style="warpCss" class="overflow-hidden" v-if="info&&list && list.length">
|
||||||
|
<view v-if="diyComponent.style == 'style-1'" class="rounded-t-[16rpx] flex items-center justify-between style-bg-1 py-[20rpx] px-[30rpx]">
|
||||||
|
<view class="flex items-end">
|
||||||
|
<image :src="img('static/resource/images/diy/member/VIP_02.png')" mode="aspectFit" class="w-[50rpx] h-[36rpx]" />
|
||||||
|
<text class="text-[28rpx] text-[#FFDAA8] ml-[10rpx] font-bold 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>
|
||||||
|
<text class="iconfont iconxiayibu1 ml-[2rpx] !text-[20rpx] text-[#333]"></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="diyComponent.style == 'style-2'" class="rounded-[16rpx] flex items-center justify-between style-bg-2 p-[30rpx]">
|
||||||
|
<view class="flex flex-col">
|
||||||
|
<view class="flex items-center">
|
||||||
|
<image :src="img('static/resource/images/diy/member/VIP_01.png')" mode="aspectFit" class="w-[74rpx] h-[30rpx]" />
|
||||||
|
<text class="text-[32rpx] text-[#FFE3B1] leading-[normal] ml-[14rpx] font-bold max-w-[420rpx] truncate">{{info.member_level_name}}</text>
|
||||||
|
</view>
|
||||||
|
<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>
|
||||||
|
<text class="iconfont iconxiayibu1 ml-[2rpx] !text-[20rpx] text-[#333]"></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="diyComponent.style == 'style-3'" class="rounded-[16rpx] style-bg-3 p-[30rpx]">
|
||||||
|
<view class="flex items-center justify-between style-border-3 mb-[22rpx] pb-[22rpx]">
|
||||||
|
<view class="flex flex-col">
|
||||||
|
<view class="flex items-center">
|
||||||
|
<view class="flex justify-end leading-[30rpx] box-border text-[#fff] pr-[10rpx] text-[26rpx] w-[120rpx] h-[30rpx] bg-contain bg-no-repeat" :style="{'backgroundImage': 'url('+img('static/resource/images/diy/member/VIP.png')+')'}">
|
||||||
|
VIP.{{currIndex}}
|
||||||
|
</view>
|
||||||
|
<text class="text-[#733F02] ml-[8rpx] text-[30rpx] font-bold max-w-[380rpx] truncate">{{info.member_level_name}}</text>
|
||||||
|
</view>
|
||||||
|
<text class="text-[28rpx] text-[#794200] mt-[16rpx]">购物或邀请好友可以提升等级</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex items-center" @click="toLink('/app/pages/member/level')">
|
||||||
|
<view class="flex flex-col items-center justify-center">
|
||||||
|
<image :src="img('static/resource/images/diy/member/rule.png')" mode="aspectFit" class="w-[26rpx] h-[26rpx]" />
|
||||||
|
<text class="text-[24rpx] text-[#733F02] mt-[10rpx]">规则</text>
|
||||||
|
</view>
|
||||||
|
<view class="ml-[10rpx] text-[#733F02] !text-[26rpx] nc-iconfont nc-icon-youV6xx"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="flex items-center justify-between">
|
||||||
|
<view class="flex flex-col flex-1">
|
||||||
|
<view class="overflow-hidden rounded-[20rpx]">
|
||||||
|
<progress :percent="progress()" activeColor="#fff" backgroundColor="rgba(255,5,5,.1)" stroke-width="6" />
|
||||||
|
</view>
|
||||||
|
<text class="text-[24rpx] leading-[1.4] text-[#794200] mt-[16rpx]" v-if="upgradeGrowth > 0">还差{{upgradeGrowth}}成长值即可升级为{{ list[afterCurrIndex].level_name }}</text>
|
||||||
|
<text class="text-[24rpx] text-[#794200] mt-[16rpx]" v-else>恭喜您升级为最高等级</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex items-center rounded-[30rpx] bg-[rgb(245,230,185)] p-[16rpx] ml-[40rpx]" @click="toLink('/app/pages/member/level')">
|
||||||
|
<text class="text-[28rpx] text-[#733F02]">{{info.member_level ? (upgradeGrowth > 0 ? '做任务' : '点击查看') : '去解锁'}}</text>
|
||||||
|
<image :src="img('static/resource/images/diy/member/vector.png')" mode="aspectFit" class="ml-[8rpx] w-[12rpx] h-[18rpx]" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed, ref, watch } from 'vue'
|
||||||
|
import { img, redirect } from '@/utils/common'
|
||||||
|
import useMemberStore from '@/stores/member'
|
||||||
|
import { t } from '@/locale'
|
||||||
|
import { getMemberLevel } from '@/app/api/member';
|
||||||
|
import useDiyStore from '@/app/stores/diy'
|
||||||
|
|
||||||
|
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
const memberStore = useMemberStore()
|
||||||
|
|
||||||
|
const diyComponent = computed(() => {
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return diyStore.value[props.index];
|
||||||
|
} else {
|
||||||
|
return props.component;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const warpCss = computed(() => {
|
||||||
|
var style = '';
|
||||||
|
if (diyComponent.value.topRounded) style += 'border-top-left-radius:' + diyComponent.value.topRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.topRounded) style += 'border-top-right-radius:' + diyComponent.value.topRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.pullDownRefreshCount,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
// 处理下拉刷新业务
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// 获取会员等级列表
|
||||||
|
const upgradeGrowth = ref(0) // 升级下级会员所需的成长值
|
||||||
|
const currIndex = ref(0) //当前会员索引
|
||||||
|
const afterCurrIndex = ref(-1) // 下一个会员等级索引
|
||||||
|
const benefits_arr:any = ref([]) //当前会员权益
|
||||||
|
const wap_member_info = ref(uni.getStorageSync('wap_member_info'));
|
||||||
|
const info:any = computed(() => {
|
||||||
|
// 装修模式
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
upgradeGrowth.value = 0;
|
||||||
|
benefits_arr.value = [{'title': '商品包邮'}];
|
||||||
|
currIndex.value = 1;
|
||||||
|
return {
|
||||||
|
member_level_name: '会员等级',
|
||||||
|
growth: 5
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return wap_member_info.value||{};
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const list:any = computed(() => {
|
||||||
|
// 装修模式
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return [{}];
|
||||||
|
}else{
|
||||||
|
getMemberLevelFn(memberStore.levelList)
|
||||||
|
return memberStore.levelList
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
const getMemberLevelFn = (list:any)=> {
|
||||||
|
if(!list||!list.length) return false;
|
||||||
|
let isSet = false;
|
||||||
|
// 刚进来处理会员等级数据
|
||||||
|
if (info.value && list && list.length) {
|
||||||
|
list.forEach((item: any, index: any) => {
|
||||||
|
if (item.level_id == info.value.member_level) {
|
||||||
|
currIndex.value = index + 1;
|
||||||
|
// 会员权益
|
||||||
|
if (item.level_benefits) {
|
||||||
|
Object.values(item.level_benefits).forEach((bItem: any) => {
|
||||||
|
if (bItem.content) {
|
||||||
|
benefits_arr.value.push(bItem.content)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.growth > info.value.growth && !isSet) {
|
||||||
|
afterCurrIndex.value = index;
|
||||||
|
isSet = true;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.value.member_level) {
|
||||||
|
if(afterCurrIndex.value == -1){
|
||||||
|
afterCurrIndex.value = list.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list[afterCurrIndex.value] && list[afterCurrIndex.value].growth) {
|
||||||
|
upgradeGrowth.value = list[afterCurrIndex.value].growth - info.value.growth;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
// 当前会员没有会员等级,则展示会员等级中的最后一个等级
|
||||||
|
info.value.member_level_name = list[0].level_name;
|
||||||
|
upgradeGrowth.value = list[0].growth;
|
||||||
|
afterCurrIndex.value = 0;
|
||||||
|
currIndex.value = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 进度条值
|
||||||
|
let progress = () => {
|
||||||
|
let num = 100
|
||||||
|
if(list.value[afterCurrIndex.value] && list.value[afterCurrIndex.value].growth) {
|
||||||
|
if(info.value.growth) {
|
||||||
|
num = info.value.growth / list.value[afterCurrIndex.value].growth * 100
|
||||||
|
}else{
|
||||||
|
num = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跳转链接
|
||||||
|
const toLink = (link: string)=>{
|
||||||
|
if (diyStore.mode == 'decorate') return false;
|
||||||
|
redirect({ url: link })
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.style-bg-1{
|
||||||
|
background: linear-gradient(to right, #1F1313, #4D4646);
|
||||||
|
}
|
||||||
|
.style-btn{
|
||||||
|
background: linear-gradient(to right, #FFEACB, #FFD195);
|
||||||
|
}
|
||||||
|
.style-bg-2{
|
||||||
|
background: linear-gradient(to right, #484846, #222222);
|
||||||
|
border-bottom-left-radius: 320rpx 16rpx;
|
||||||
|
border-bottom-right-radius: 320rpx 16rpx;
|
||||||
|
}
|
||||||
|
.style-bg-3{
|
||||||
|
background: linear-gradient(to right, #FFE6C2, #E39F42);
|
||||||
|
}
|
||||||
|
.style-border-3{
|
||||||
|
position: relative;
|
||||||
|
&:after{
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
background: linear-gradient(to right, #F0D2A9, #DBA051);
|
||||||
|
height: 2rpx;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -5,24 +5,21 @@
|
|||||||
<view class="flex items-center pl-[28rpx] p-[22rpx]">
|
<view class="flex items-center pl-[28rpx] p-[22rpx]">
|
||||||
<template v-if="diyComponent.noticeType == 'img'">
|
<template v-if="diyComponent.noticeType == 'img'">
|
||||||
<template v-if="diyComponent.imgType == 'system'">
|
<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-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]" 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-[30rpx] flex-shrink-0" mode="heightFix" />
|
||||||
</template>
|
</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-[200rpx] h-[30rpx] mr-[20rpx] flex-shrink-0" mode="heightFix"/>
|
||||||
</template>
|
</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 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 items-center">
|
<view class="flex-1 flex overflow-hidden horizontal-body" :id="'horizontal-body-'+diyComponent.id" :class="{'items-center':diyComponent.scrollWay == 'upDown'}">
|
||||||
|
|
||||||
<!-- 横向滚动 -->
|
<!-- 横向滚动 -->
|
||||||
<view class="horizontal-wrap" v-if="diyComponent.scrollWay == 'horizontal'">
|
<view class="horizontal-wrap" :style="marqueeStyle" v-if="diyComponent.scrollWay == 'horizontal'">
|
||||||
<view class="marquee-wrap">
|
<view class="marquee marquee-one" id="marquee-one" >
|
||||||
<view class="marquee" :style="marqueeStyle">
|
<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>
|
||||||
<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="marquee">
|
||||||
<view class="marquee" :style="marqueeAgainStyle">
|
<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>
|
||||||
<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>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 上下滚动 -->
|
<!-- 上下滚动 -->
|
||||||
@ -34,7 +31,7 @@
|
|||||||
</text>
|
</text>
|
||||||
</swiper-item>
|
</swiper-item>
|
||||||
</swiper>
|
</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>
|
</template>
|
||||||
</view>
|
</view>
|
||||||
@ -42,12 +39,14 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<u-popup :show="noticeShow" @close="noticeShow = false" mode="center" :round="5" :safeAreaInsetBottom="false">
|
<u-popup :show="noticeShow" @close="noticeShow = false" mode="center" :round="5" :safeAreaInsetBottom="false">
|
||||||
<view class="py-[25rpx] text-sm leading-none border-0 border-solid border-b-[2rpx] border-[#eee] flex items-center justify-between">
|
<view @touchmove.prevent.stop>
|
||||||
<text class="ml-[30rpx]">公告</text>
|
<view class="py-[25rpx] text-sm leading-none border-0 border-solid border-b-[2rpx] border-[#eee] flex items-center justify-between">
|
||||||
<text class="mr-[20rpx] iconfont iconguanbi text-[35rpx]" @click="noticeShow = false"></text>
|
<text class="ml-[30rpx]">公告</text>
|
||||||
</view>
|
<text class="mr-[20rpx] nc-iconfont nc-icon-guanbiV6xx text-[35rpx]" @click="noticeShow = false"></text>
|
||||||
<scroll-view scroll-y="true" class="px-6 py-3 w-[480rpx] h-[500rpx] text-sm">{{ noticeContent }}</scroll-view>
|
</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>
|
<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>
|
||||||
|
</view>
|
||||||
</u-popup>
|
</u-popup>
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
@ -57,9 +56,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
// 公告组件
|
// 公告组件
|
||||||
import { ref,computed, watch, onMounted, nextTick,getCurrentInstance } from 'vue';
|
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 useDiyStore from '@/app/stores/diy';
|
||||||
import { useLogin } from '@/hooks/useLogin';
|
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
||||||
const diyStore = useDiyStore();
|
const diyStore = useDiyStore();
|
||||||
@ -118,41 +116,53 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const marqueeWrapWidth = ref(0); // 容器宽度
|
const marqueeBodyWidth = ref(0); // 容器宽度
|
||||||
const marqueeWidth = ref(0); // 公告内容累加宽度
|
|
||||||
const marqueeStyle = ref(''); // 横向滚动样式
|
const marqueeStyle = ref(''); // 横向滚动样式
|
||||||
const marqueeAgainStyle = ref(''); // 横向滚动复制样式
|
|
||||||
const time = ref(0); // 滚动完成时间
|
const time = ref(0); // 滚动完成时间
|
||||||
const delayTime = ref(1000); // 动画延迟时间
|
const delayTime = ref(800); // 动画延迟时间
|
||||||
|
// px转rpx
|
||||||
|
const pxToRpx=(px)=> {
|
||||||
|
const screenWidth = uni.getSystemInfoSync().screenWidth
|
||||||
|
return (750 * Number.parseInt(px)) / screenWidth
|
||||||
|
}
|
||||||
// 绑定横向滚动事件
|
// 绑定横向滚动事件
|
||||||
const bindCrossSlipEvent = ()=> {
|
const bindCrossSlipEvent = ()=> {
|
||||||
if (diyComponent.value.scrollWay == 'horizontal') {
|
if (diyComponent.value.scrollWay == 'horizontal') {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
uni.createSelectorQuery().in(instance).select('.marquee-wrap').boundingClientRect(res => {
|
// #ifdef MP-WEIXIN
|
||||||
marqueeWrapWidth.value = res.width;
|
uni.createSelectorQuery().in(instance).select('#horizontal-body-' + diyComponent.value.id).boundingClientRect(res => {
|
||||||
|
marqueeBodyWidth.value = res.width;
|
||||||
const query = uni.createSelectorQuery().in(instance);
|
const query = uni.createSelectorQuery().in(instance);
|
||||||
query.select('.marquee').boundingClientRect(data => {
|
query.select('#horizontal-body-' + diyComponent.value.id + ' .marquee-one').boundingClientRect((data: any) => {
|
||||||
marqueeWidth.value = data.width + 30; // 30px是间距
|
const width = data.width
|
||||||
time.value = Math.ceil(marqueeWidth.value * 10);
|
time.value = Math.ceil(width * 14);
|
||||||
|
if (marqueeBodyWidth.value > width) {
|
||||||
if (marqueeWrapWidth.value > marqueeWidth.value) {
|
|
||||||
marqueeStyle.value = `animation: none;`;
|
marqueeStyle.value = `animation: none;`;
|
||||||
marqueeAgainStyle.value = 'display:none;';
|
|
||||||
} else {
|
} else {
|
||||||
marqueeStyle.value = `
|
marqueeStyle.value = `
|
||||||
width: ${marqueeWidth.value}px;
|
animation-duration: ${ time.value }ms;
|
||||||
animation-duration: ${time.value}ms;
|
animation-delay: ${ delayTime.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();
|
||||||
}).exec();
|
}).exec();
|
||||||
|
// #endif
|
||||||
|
// #ifdef H5
|
||||||
|
let documentObj = window.document.getElementById('horizontal-body-' + diyComponent.value.id);
|
||||||
|
let marqueeOne = window.document.getElementById('marquee-one');
|
||||||
|
if(documentObj && marqueeOne) {
|
||||||
|
marqueeBodyWidth.value = documentObj.offsetWidth;
|
||||||
|
const width = marqueeOne.offsetWidth;
|
||||||
|
time.value = Math.ceil(width * 14);
|
||||||
|
if (marqueeBodyWidth.value > width) {
|
||||||
|
marqueeStyle.value = `animation: none;`;
|
||||||
|
} else {
|
||||||
|
marqueeStyle.value = `
|
||||||
|
animation-duration: ${ time.value }ms;
|
||||||
|
animation-delay: ${ delayTime.value }ms;`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -188,19 +198,13 @@ const refresh = ()=> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const toRedirect = (data: {}) => {
|
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;
|
noticeShow.value = true;
|
||||||
noticeContent.value = data.text;
|
noticeContent.value = data.text;
|
||||||
}else {
|
} else {
|
||||||
if (data.link.url) {
|
diyStore.toRedirect(data);
|
||||||
if (currRoute() == 'app/pages/member/index' && !getToken()) {
|
|
||||||
useLogin().setLoginBack({ url: data.link.url })
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
diyRedirect(data.link);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -256,45 +260,49 @@ const toRedirect = (data: {}) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.horizontal-wrap {
|
.horizontal-wrap {
|
||||||
height: 30px;
|
height: 40rpx;
|
||||||
line-height: 30px;
|
display: flex;
|
||||||
position: relative;
|
align-items: center;
|
||||||
overflow: hidden;
|
transform: translateZ(0);
|
||||||
width: 100%;
|
animation: marquee 0s 0s linear infinite;
|
||||||
|
transform-style: preserve-3d;
|
||||||
|
backface-visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.marquee-wrap {
|
|
||||||
display: inline-block;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
vertical-align: middle;
|
|
||||||
overflow: hidden;
|
|
||||||
box-sizing: border-box;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.marquee {
|
.marquee {
|
||||||
display: flex;
|
display: flex;
|
||||||
position: absolute;
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
animation: marquee 0s 0s linear infinite;
|
padding-right: 60rpx;
|
||||||
|
|
||||||
text {
|
|
||||||
margin-left: 40rpx;
|
|
||||||
|
|
||||||
&:first-child {
|
// -webkit-perspective: 1000;
|
||||||
margin-left: 0;
|
// -moz-perspective: 1000;
|
||||||
}
|
// -ms-perspective: 1000;
|
||||||
}
|
// perspective: 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes marquee {
|
@keyframes marquee {
|
||||||
0% {
|
0% {
|
||||||
transform: translateX(0);
|
transform: translateX(0);
|
||||||
}
|
}
|
||||||
|
20%{
|
||||||
|
transform: translateX(-10%);
|
||||||
|
}
|
||||||
|
40%{
|
||||||
|
transform: translateX(-20%);
|
||||||
|
}
|
||||||
|
60%{
|
||||||
|
transform: translateX(-30%);
|
||||||
|
}
|
||||||
|
80%{
|
||||||
|
transform: translateX(-40%);
|
||||||
|
}
|
||||||
100% {
|
100% {
|
||||||
transform: translateX(-100%);
|
transform: translateX(-50%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
<!-- 1左2右 -->
|
<!-- 1左2右 -->
|
||||||
<template v-if="diyComponent.mode == 'row1-lt-of2-rt'">
|
<template v-if="diyComponent.mode == 'row1-lt-of2-rt'">
|
||||||
<view class="template-left">
|
<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' }">
|
: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-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"/>
|
<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">
|
<view class="template-right">
|
||||||
<template v-for="(item, index) in diyComponent.list" :key="index">
|
<template v-for="(item, index) in diyComponent.list" :key="index">
|
||||||
<template v-if="index > 0">
|
<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' }">
|
: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-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"/>
|
<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右 -->
|
<!-- 1左3右 -->
|
||||||
<template v-else-if="diyComponent.mode == 'row1-lt-of1-tp-of2-bm'">
|
<template v-else-if="diyComponent.mode == 'row1-lt-of1-tp-of2-bm'">
|
||||||
<view class="template-left">
|
<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' }">
|
: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-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"/>
|
<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>
|
||||||
|
|
||||||
<view class="template-right">
|
<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' }">
|
: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-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"/>
|
<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">
|
<view class="template-bottom">
|
||||||
<template v-for="(item, index) in diyComponent.list" :key="index">
|
<template v-for="(item, index) in diyComponent.list" :key="index">
|
||||||
<template v-if="index > 1">
|
<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',
|
marginRight: diyComponent.imageGap * 2 + 'rpx',
|
||||||
width: item.imgWidth,
|
width: item.imgWidth,
|
||||||
height: item.imgHeight + 'px'
|
height: item.imgHeight + 'px'
|
||||||
@ -61,7 +61,7 @@
|
|||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<view :class="['item', diyComponent.mode]" v-for="(item, index) in diyComponent.list" :key="index"
|
<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' }">
|
: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-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"/>
|
<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 { ref,onMounted, computed, watch,nextTick,getCurrentInstance } from 'vue';
|
||||||
import useDiyStore from '@/app/stores/diy';
|
import useDiyStore from '@/app/stores/diy';
|
||||||
import { img, redirect, diyRedirect, currRoute, getToken } from '@/utils/common';
|
import { img } from '@/utils/common';
|
||||||
import { useLogin } from '@/hooks/useLogin';
|
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
||||||
|
|
||||||
@ -141,7 +140,7 @@
|
|||||||
if (diyComponent.value.elementAngle == 'right') {
|
if (diyComponent.value.elementAngle == 'right') {
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
var defaultData = {
|
var defaultData:any = {
|
||||||
'row1-lt-of2-rt': [
|
'row1-lt-of2-rt': [
|
||||||
['border-top-right-radius', 'border-bottom-right-radius'],
|
['border-top-right-radius', 'border-bottom-right-radius'],
|
||||||
['border-top-left-radius', 'border-bottom-left-radius', 'border-bottom-right-radius'],
|
['border-top-left-radius', 'border-bottom-left-radius', 'border-bottom-right-radius'],
|
||||||
@ -209,6 +208,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
}else{
|
||||||
|
watch(
|
||||||
|
() => diyComponent.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -235,7 +241,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleData = () => {
|
const handleData = () => {
|
||||||
var singleRow = {
|
var singleRow:any = {
|
||||||
'row1-of2': {
|
'row1-of2': {
|
||||||
ratio: 2,
|
ratio: 2,
|
||||||
width: 'calc((100% - ' + upx2px(diyComponent.value.imageGap * 2) + 'px) / 2)'
|
width: 'calc((100% - ' + upx2px(diyComponent.value.imageGap * 2) + 'px) / 2)'
|
||||||
@ -274,7 +280,7 @@
|
|||||||
* 比例:原图高/原图宽,示例:322/690=0.46
|
* 比例:原图高/原图宽,示例:322/690=0.46
|
||||||
* 高度:宽度*比例,示例:187.5*0.46=86.25
|
* 高度:宽度*比例,示例:187.5*0.46=86.25
|
||||||
*/
|
*/
|
||||||
const calcSingleRow = (params) => {
|
const calcSingleRow = (params:any) => {
|
||||||
uni.getSystemInfo({
|
uni.getSystemInfo({
|
||||||
success: res => {
|
success: res => {
|
||||||
let maxHeight = 0;
|
let maxHeight = 0;
|
||||||
@ -428,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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<view :style="maskLayer"></view>
|
<view :style="maskLayer"></view>
|
||||||
<view class="diy-text relative">
|
<view class="diy-text relative">
|
||||||
<view v-if="diyComponent.style == 'style-1'" class=" px-[20rpx]">
|
<view v-if="diyComponent.style == 'style-1'" class=" px-[20rpx]">
|
||||||
<view @click="toRedirect(diyComponent.link)">
|
<view @click="diyStore.toRedirect(diyComponent.link)">
|
||||||
<view :style="{
|
<view :style="{
|
||||||
fontSize: diyComponent.fontSize * 2 + 'rpx',
|
fontSize: diyComponent.fontSize * 2 + 'rpx',
|
||||||
color: diyComponent.textColor,
|
color: diyComponent.textColor,
|
||||||
@ -15,7 +15,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-if="diyComponent.style == 'style-2'" class=" px-[20rpx] flex items-center">
|
<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="{
|
<view class="max-w-[200rpx] truncate" :style="{
|
||||||
fontSize: diyComponent.fontSize * 2 + 'rpx',
|
fontSize: diyComponent.fontSize * 2 + 'rpx',
|
||||||
color: diyComponent.textColor,
|
color: diyComponent.textColor,
|
||||||
@ -26,9 +26,9 @@
|
|||||||
</view>
|
</view>
|
||||||
<text class="ml-[16rpx] max-w-[300rpx] truncate" :style="{ color: diyComponent.subTitle.color, fontSize: diyComponent.subTitle.fontSize * 2 + 'rpx', }">{{ diyComponent.subTitle.text }}</text>
|
<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 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">
|
<view @click="diyStore.toRedirect(diyComponent.more.link)" class="flex items-center">
|
||||||
<text class="max-w-[200rpx] truncate text-[24rpx] mr-[8rpx]">{{ diyComponent.more.text }}</text>
|
<text class="max-w-[200rpx] truncate text-[24rpx]">{{ diyComponent.more.text }}</text>
|
||||||
<u-icon name="arrow-right" size="12" :style="{ color: diyComponent.more.color }"></u-icon>
|
<text class="nc-iconfont nc-icon-youV6xx text-[26rpx]" :style="{ color: diyComponent.more.color }"></text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -40,8 +40,7 @@
|
|||||||
// 标题
|
// 标题
|
||||||
import { ref, computed, watch,onMounted,nextTick,getCurrentInstance } from 'vue';
|
import { ref, computed, watch,onMounted,nextTick,getCurrentInstance } from 'vue';
|
||||||
import useDiyStore from '@/app/stores/diy';
|
import useDiyStore from '@/app/stores/diy';
|
||||||
import { img,redirect,diyRedirect, currRoute, getToken } from '@/utils/common';
|
import { img } from '@/utils/common';
|
||||||
import { useLogin } from '@/hooks/useLogin';
|
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
||||||
const diyStore = useDiyStore();
|
const diyStore = useDiyStore();
|
||||||
@ -124,19 +123,6 @@
|
|||||||
}).exec();
|
}).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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -7,5 +7,6 @@
|
|||||||
"selectAreaPlaceholder":"请选择地区",
|
"selectAreaPlaceholder":"请选择地区",
|
||||||
"address": "详细地址",
|
"address": "详细地址",
|
||||||
"addressPlaceholder": "请填写详细地址",
|
"addressPlaceholder": "请填写详细地址",
|
||||||
"defaultAddress": "设为默认地址"
|
"defaultAddress": "设为默认地址",
|
||||||
|
"selectAddressPlaceholder":"请选择地址"
|
||||||
}
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"cashOut": "提现",
|
"cashOutNow": "立即提现",
|
||||||
"balanceDetail": "余额明细",
|
"balanceDetail": "余额明细",
|
||||||
"cashOutTo": "提现到",
|
"cashOutTo": "提现到",
|
||||||
"cashOutTypePlaceholder": "请选择提现方式",
|
"cashOutTypePlaceholder": "请选择提现方式",
|
||||||
@ -25,5 +25,6 @@
|
|||||||
"applyMoneyExceed": "提现金额超出可提现金额",
|
"applyMoneyExceed": "提现金额超出可提现金额",
|
||||||
"applyMoneyBelow": "提现金额小于最低提现金额",
|
"applyMoneyBelow": "提现金额小于最低提现金额",
|
||||||
"replace": "更换",
|
"replace": "更换",
|
||||||
"toAdd": "去添加"
|
"isOpenApply": "提现设置未开启",
|
||||||
|
"toAdd": "添加"
|
||||||
}
|
}
|
||||||
@ -3,9 +3,9 @@
|
|||||||
"recharge": "充值",
|
"recharge": "充值",
|
||||||
"cashOut":"提现",
|
"cashOut":"提现",
|
||||||
"balanceDetail": "余额明细",
|
"balanceDetail": "余额明细",
|
||||||
"accountBalance":"账户余额(元)",
|
"accountBalance":"账户余额 (元)",
|
||||||
"balance":"余额(元)",
|
"balance":"余额 (元)",
|
||||||
"money":"可提现余额(元)",
|
"money":"可提现余额 (元)",
|
||||||
"availableBalance": "可用余额",
|
"availableBalance": "可用余额",
|
||||||
"rechargeAmountError": "充值金额错误",
|
"rechargeAmountError": "充值金额错误",
|
||||||
"clickRecharge": "立即充值",
|
"clickRecharge": "立即充值",
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"recharge": "充值",
|
"recharge": "充值",
|
||||||
"cashOut":"提现",
|
"cashOut":"提现",
|
||||||
|
"transferMoney":"提现",
|
||||||
"commissionDetail": "佣金明细",
|
"commissionDetail": "佣金明细",
|
||||||
"accountCommission":"账户佣金(元)",
|
"accountCommission":"当前佣金(元)",
|
||||||
"commission":"累计佣金(元)",
|
"commission":"累计佣金(元)",
|
||||||
"money":"提现中佣金(元)",
|
"money":"提现中佣金(元)",
|
||||||
"availableCommission": "可用佣金",
|
"availableCommission": "可用佣金",
|
||||||
|
|||||||
@ -10,11 +10,11 @@
|
|||||||
<view class="px-[60rpx]">
|
<view class="px-[60rpx]">
|
||||||
<u-form labelPosition="left" :model="formData" errorType='toast' :rules="rules" ref="formRef">
|
<u-form labelPosition="left" :model="formData" errorType='toast' :rules="rules" ref="formRef">
|
||||||
<u-form-item label="" prop="mobile" :border-bottom="true">
|
<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>
|
</u-form-item>
|
||||||
<view class="mt-[40rpx]">
|
<view class="mt-[40rpx]">
|
||||||
<u-form-item label="" prop="mobile_code" :border-bottom="true">
|
<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>
|
<template #suffix>
|
||||||
<sms-code :mobile="formData.mobile" type="bind_mobile" v-model="formData.mobile_key"></sms-code>
|
<sms-code :mobile="formData.mobile" type="bind_mobile" v-model="formData.mobile_key"></sms-code>
|
||||||
</template>
|
</template>
|
||||||
@ -23,7 +23,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="flex items-start mt-[30rpx]" v-if="!info && config.agreement_show">
|
<view class="flex items-start mt-[30rpx]" v-if="!info && config.agreement_show">
|
||||||
<u-checkbox-group>
|
<u-checkbox-group>
|
||||||
<u-checkbox :checked="isAgree" shape="shape" size="14" @change="agreeChange" :customStyle="{'marginTop': '4rpx'}" />
|
<u-checkbox activeColor="var(--primary-color)" :checked="isAgree" shape="shape" size="14" @change="agreeChange" :customStyle="{'marginTop': '4rpx'}" />
|
||||||
</u-checkbox-group>
|
</u-checkbox-group>
|
||||||
<view class="text-xs text-gray-400 flex flex-wrap">
|
<view class="text-xs text-gray-400 flex flex-wrap">
|
||||||
{{ t('agreeTips') }}
|
{{ t('agreeTips') }}
|
||||||
@ -36,24 +36,27 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-[60rpx]">
|
<view class="mt-[60rpx]">
|
||||||
<u-button type="primary" :loading="loading" :loadingText="t('binding')" @click="handleBind">
|
<u-button type="primary" :text="t('bind')" :loading="loading" :loadingText="t('binding')" @click="handleBind"></u-button>
|
||||||
{{ t('bind') }}
|
|
||||||
</u-button>
|
|
||||||
</view>
|
</view>
|
||||||
<!-- #ifdef MP-WEIXIN -->
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
<view class="mt-[30rpx]">
|
<view class="mt-[30rpx]">
|
||||||
<u-button type="primary" :plain="true" :text="t('weixinUserAuth')" open-type="getPhoneNumber" @getphonenumber="mobileAuth" v-if="info || (!info || !config.agreement_show || isAgree)"></u-button>
|
<u-button type="primary" :plain="true" :text="t('weixinUserAuth')" @click="agreeTips" v-if="!info && config.agreement_show && !isAgree"></u-button>
|
||||||
<u-button type="primary" :plain="true" :text="t('weixinUserAuth')" v-else @click="agreeTips"></u-button>
|
<u-button type="primary" :plain="true" :text="t('weixinUserAuth')" open-type="getPhoneNumber" @getphonenumber="mobileAuth" v-else></u-button>
|
||||||
</view>
|
</view>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
</u-form>
|
</u-form>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
|
<!-- 小程序隐私协议 -->
|
||||||
|
<wx-privacy-popup ref="wxPrivacyPopup"></wx-privacy-popup>
|
||||||
|
<!-- #endif -->
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, computed } from 'vue'
|
import { ref, reactive, computed, onMounted } from 'vue'
|
||||||
import { t } from '@/locale'
|
import { t } from '@/locale'
|
||||||
import { bind } from '@/app/api/auth'
|
import { bind } from '@/app/api/auth'
|
||||||
import { bindMobile } from '@/app/api/member'
|
import { bindMobile } from '@/app/api/member'
|
||||||
@ -78,13 +81,21 @@
|
|||||||
mobile_key: ''
|
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('openid') && (Object.assign(formData, { openid: uni.getStorageSync('openid') }))
|
||||||
uni.getStorageSync('pid') && (Object.assign(formData, { pid: uni.getStorageSync('pid') }))
|
uni.getStorageSync('pid') && (Object.assign(formData, { pid: uni.getStorageSync('pid') }))
|
||||||
|
uni.getStorageSync('unionid') && (Object.assign(formData, { unionid: uni.getStorageSync('unionid') }))
|
||||||
|
|
||||||
const rules = {
|
const rules = {
|
||||||
'mobile': [
|
'mobile': [
|
||||||
{
|
{
|
||||||
|
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: true,
|
required: true,
|
||||||
message: t('mobilePlaceholder'),
|
message: t('mobilePlaceholder'),
|
||||||
@ -142,10 +153,12 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const mobileAuth = (e) => {
|
const mobileAuth = (e) => {
|
||||||
if (!isAgree.value && !info.value && config.value.agreement_show) {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,11 +179,27 @@
|
|||||||
memberStore.setToken(res.data.token)
|
memberStore.setToken(res.data.token)
|
||||||
useLogin().handleLoginBack()
|
useLogin().handleLoginBack()
|
||||||
}
|
}
|
||||||
}).catch(() => {
|
}).catch((res) => {
|
||||||
uni.hideLoading()
|
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' })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss">
|
||||||
|
.u-input{
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|||||||
@ -9,32 +9,29 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="px-[60rpx] text-sm flex mb-[50rpx] font-bold leading-none" v-if="loginType.length > 1">
|
<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">
|
<block v-for="(item, index) in loginType">
|
||||||
<view :class="{'text-gray-300' : item.type != type}" @click="type = item.type">{{ item.title }}
|
<view :class="{'text-gray-300' : item.type != type}" @click="type = item.type">{{ item.title }}</view>
|
||||||
</view>
|
<view class="mx-[30rpx] border-solid border-0 border-r-[2px] border-gray-300" v-show="index == 0"></view>
|
||||||
<view class="mx-[30rpx] border-solid border-0 border-r-[2px] border-gray-300" v-show="index == 0">
|
|
||||||
</view>
|
|
||||||
</block>
|
</block>
|
||||||
</view>
|
</view>
|
||||||
<view class="px-[60rpx]">
|
<view class="px-[60rpx]">
|
||||||
<u-form labelPosition="left" :model="formData" errorType='toast' :rules="rules" ref="formRef">
|
<u-form labelPosition="left" :model="formData" errorType='toast' :rules="rules" ref="formRef">
|
||||||
<view v-show="type == 'username'">
|
<view v-show="type == 'username'">
|
||||||
<u-form-item label="" prop="username" :border-bottom="true">
|
<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>
|
</u-form-item>
|
||||||
<view class="mt-[40rpx]">
|
<view class="mt-[40rpx]">
|
||||||
<u-form-item label="" prop="password" :border-bottom="true">
|
<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>
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-show="type == 'mobile'">
|
<view v-show="type == 'mobile'">
|
||||||
<u-form-item label="" prop="mobile" :border-bottom="true">
|
<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>
|
</u-form-item>
|
||||||
<view class="mt-[40rpx]">
|
<view class="mt-[40rpx]">
|
||||||
<u-form-item label="" prop="mobile_code" :border-bottom="true">
|
<u-form-item label="" prop="mobile_code" :border-bottom="true">
|
||||||
<u-input v-model="formData.mobile_code" border="none" type="password" clearable
|
<u-input v-model="formData.mobile_code" border="none" clearable class="!bg-transparent" :disabled="real_name_input" :placeholder="t('codePlaceholder')">
|
||||||
:placeholder="t('codePlaceholder')">
|
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
<sms-code :mobile="formData.mobile" type="login" v-model="formData.mobile_key"></sms-code>
|
<sms-code :mobile="formData.mobile" type="login" v-model="formData.mobile_key"></sms-code>
|
||||||
</template>
|
</template>
|
||||||
@ -49,15 +46,14 @@
|
|||||||
<view @click="redirect({ url: '/app/pages/auth/resetpwd' })">{{ t('resetpwd') }}</view>
|
<view @click="redirect({ url: '/app/pages/auth/resetpwd' })">{{ t('resetpwd') }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-[80rpx]">
|
<view class="mt-[80rpx]">
|
||||||
<u-button type="primary" :loading="loading" :loadingText="t('logining')" @click="handleLogin">
|
<u-button type="primary" :text="t('login')" :loading="loading" :loadingText="t('logining')" @click="handleLogin">
|
||||||
{{ t('login') }}
|
|
||||||
</u-button>
|
</u-button>
|
||||||
</view>
|
</view>
|
||||||
</u-form>
|
</u-form>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="text-xs py-[50rpx] flex justify-center w-full" v-if="configStore.login.agreement_show">
|
<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') }}
|
{{ t('agreeTips') }}
|
||||||
<view @click="redirect({ url: '/app/pages/auth/agreement?key=service' })">
|
<view @click="redirect({ url: '/app/pages/auth/agreement?key=service' })">
|
||||||
<text class="text-primary">{{ t('userAgreement') }}</text>
|
<text class="text-primary">{{ t('userAgreement') }}</text>
|
||||||
@ -71,7 +67,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<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 { usernameLogin, mobileLogin } from '@/app/api/auth'
|
||||||
import useMemberStore from '@/stores/member'
|
import useMemberStore from '@/stores/member'
|
||||||
import useConfigStore from '@/stores/config'
|
import useConfigStore from '@/stores/config'
|
||||||
@ -87,7 +83,18 @@
|
|||||||
mobile_key: ''
|
mobile_key: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
uni.getStorageSync('openid') && (Object.assign(formData, { openid: uni.getStorageSync('openid') }))
|
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') }))
|
uni.getStorageSync('pid') && (Object.assign(formData, { pid: uni.getStorageSync('pid') }))
|
||||||
|
|
||||||
const memberStore = useMemberStore()
|
const memberStore = useMemberStore()
|
||||||
@ -170,4 +177,8 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss">
|
||||||
|
.u-input{
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="w-screen h-screen flex flex-col" :style="themeColor()">
|
<view class="w-screen h-screen flex flex-col" :style="themeColor()" v-show="type">
|
||||||
<view class="flex-1">
|
<view class="flex-1">
|
||||||
<!-- #ifdef H5 -->
|
<!-- #ifdef H5 -->
|
||||||
<view class="h-[100rpx]"></view>
|
<view class="h-[100rpx]"></view>
|
||||||
@ -18,29 +18,29 @@
|
|||||||
<view v-show="type == 'username'">
|
<view v-show="type == 'username'">
|
||||||
<view class="mt-[30rpx]">
|
<view class="mt-[30rpx]">
|
||||||
<u-form-item label="" prop="username" :border-bottom="true">
|
<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>
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-[30rpx]">
|
<view class="mt-[30rpx]">
|
||||||
<u-form-item label="" prop="password" :border-bottom="true">
|
<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>
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-[30rpx]">
|
<view class="mt-[30rpx]">
|
||||||
<u-form-item label="" prop="confirm_password" :border-bottom="true">
|
<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>
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-show="type == 'mobile' || configStore.login.is_bind_mobile">
|
<view v-show="type == 'mobile' || configStore.login.is_bind_mobile">
|
||||||
<view class="mt-[30rpx]">
|
<view class="mt-[30rpx]">
|
||||||
<u-form-item label="" prop="mobile" :border-bottom="true">
|
<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>
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-[30rpx]">
|
<view class="mt-[30rpx]">
|
||||||
<u-form-item label="" prop="code" :border-bottom="true">
|
<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>
|
<template #suffix>
|
||||||
<sms-code :mobile="formData.mobile" type="register" v-model="formData.mobile_key"></sms-code>
|
<sms-code :mobile="formData.mobile" type="register" v-model="formData.mobile_key"></sms-code>
|
||||||
</template>
|
</template>
|
||||||
@ -51,9 +51,9 @@
|
|||||||
<view v-show="type == 'username'">
|
<view v-show="type == 'username'">
|
||||||
<view class="mt-[30rpx]">
|
<view class="mt-[30rpx]">
|
||||||
<u-form-item label="" prop="captcha_code" :border-bottom="true">
|
<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>
|
<template #suffix>
|
||||||
<image :src="captcha.image.value" class="h-[48rpx] ml-[20rpx]" mode="heightFix" @click="captcha.refresh()"></image>
|
<image :src="captcha.image.value" class="h-[48rpx] w-[60rpx] ml-[20rpx]" mode="heightFix" @click="captcha.refresh()"></image>
|
||||||
</template>
|
</template>
|
||||||
</u-input>
|
</u-input>
|
||||||
</u-form-item>
|
</u-form-item>
|
||||||
@ -63,15 +63,14 @@
|
|||||||
<view @click="redirect({ url: '/app/pages/auth/login' })">{{ t('haveAccount') }},<text class="text-primary">{{ t('toLogin') }}</text></view>
|
<view @click="redirect({ url: '/app/pages/auth/login' })">{{ t('haveAccount') }},<text class="text-primary">{{ t('toLogin') }}</text></view>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-[80rpx]">
|
<view class="mt-[80rpx]">
|
||||||
<u-button type="primary" :loading="loading" :loadingText="t('registering')" @click="handleregister">
|
<u-button type="primary" :text="t('register')" :loading="loading" :loadingText="t('registering')" @click="handleRegister">
|
||||||
{{ t('register') }}
|
|
||||||
</u-button>
|
</u-button>
|
||||||
</view>
|
</view>
|
||||||
</u-form>
|
</u-form>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="text-xs py-[50rpx] flex justify-center w-full" v-if="configStore.login.agreement_show">
|
<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') }}
|
{{ t('registerAgreeTips') }}
|
||||||
<view @click="redirect({ url: '/app/pages/auth/agreement?key=service' })">
|
<view @click="redirect({ url: '/app/pages/auth/agreement?key=service' })">
|
||||||
<text class="text-primary">{{ t('userAgreement') }}</text>
|
<text class="text-primary">{{ t('userAgreement') }}</text>
|
||||||
@ -85,7 +84,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<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 { usernameRegister, mobileRegister } from '@/app/api/auth'
|
||||||
import useMemberStore from '@/stores/member'
|
import useMemberStore from '@/stores/member'
|
||||||
import useConfigStore from '@/stores/config'
|
import useConfigStore from '@/stores/config'
|
||||||
@ -105,8 +104,19 @@
|
|||||||
captcha_code: ''
|
captcha_code: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
uni.getStorageSync('openid') && (Object.assign(formData, { openid: uni.getStorageSync('openid') }))
|
let real_name_input = ref(true);
|
||||||
uni.getStorageSync('pid') && (Object.assign(formData, { pid: uni.getStorageSync('pid') }))
|
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)
|
const captcha = useCaptcha(formData)
|
||||||
captcha.refresh()
|
captcha.refresh()
|
||||||
@ -190,7 +200,7 @@
|
|||||||
|
|
||||||
const formRef = ref(null)
|
const formRef = ref(null)
|
||||||
|
|
||||||
const handleregister = () => {
|
const handleRegister = () => {
|
||||||
formRef.value.validate().then(() => {
|
formRef.value.validate().then(() => {
|
||||||
if (configStore.login.agreement_show && !isAgree.value) {
|
if (configStore.login.agreement_show && !isAgree.value) {
|
||||||
uni.showToast({ title: t('isAgreeTips'), icon: 'none' });
|
uni.showToast({ title: t('isAgreeTips'), icon: 'none' });
|
||||||
@ -212,4 +222,8 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss">
|
||||||
|
.u-input{
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@ -12,12 +12,12 @@
|
|||||||
<u-form labelPosition="left" :model="formData" errorType='toast' :rules="rules" ref="formRef">
|
<u-form labelPosition="left" :model="formData" errorType='toast' :rules="rules" ref="formRef">
|
||||||
<view class="mt-[30rpx]">
|
<view class="mt-[30rpx]">
|
||||||
<u-form-item label="" prop="mobile" :border-bottom="true">
|
<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>
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-[30rpx]">
|
<view class="mt-[30rpx]">
|
||||||
<u-form-item label="" prop="code" :border-bottom="true">
|
<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>
|
<template #suffix>
|
||||||
<sms-code :mobile="formData.mobile" type="find_pass" v-model="formData.mobile_key"></sms-code>
|
<sms-code :mobile="formData.mobile" type="find_pass" v-model="formData.mobile_key"></sms-code>
|
||||||
</template>
|
</template>
|
||||||
@ -26,17 +26,16 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="mt-[30rpx]">
|
<view class="mt-[30rpx]">
|
||||||
<u-form-item label="" prop="password" :border-bottom="true">
|
<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>
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-[30rpx]">
|
<view class="mt-[30rpx]">
|
||||||
<u-form-item label="" prop="confirm_password" :border-bottom="true">
|
<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>
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-[80rpx]">
|
<view class="mt-[80rpx]">
|
||||||
<u-button type="primary" :loading="loading" :loadingText="t('confirm')" @click="handleConfirm">
|
<u-button type="primary" :text="t('confirm')" :loading="loading" :loadingText="t('confirm')" @click="handleConfirm">
|
||||||
{{ t('confirm') }}
|
|
||||||
</u-button>
|
</u-button>
|
||||||
</view>
|
</view>
|
||||||
</u-form>
|
</u-form>
|
||||||
@ -46,7 +45,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive } from 'vue'
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
import { t } from '@/locale'
|
import { t } from '@/locale'
|
||||||
import { resetPassword } from '@/app/api/system'
|
import { resetPassword } from '@/app/api/system'
|
||||||
import { redirect } from '@/utils/common'
|
import { redirect } from '@/utils/common'
|
||||||
@ -59,6 +58,14 @@
|
|||||||
confirm_password: ''
|
confirm_password: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let real_name_input = ref(true);
|
||||||
|
onMounted(() => {
|
||||||
|
// 防止浏览器自动填充
|
||||||
|
setTimeout(()=>{
|
||||||
|
real_name_input.value = false;
|
||||||
|
},800)
|
||||||
|
});
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const formRef = ref(null)
|
const formRef = ref(null)
|
||||||
|
|
||||||
@ -121,4 +128,8 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss">
|
||||||
|
.u-input{
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1,7 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="w-screen h-screen flex flex-col items-center justify-center" :style="themeColor()">
|
<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 :icon="img('static/resource/images/site/close.png')" :text="t('siteClose')"></u-empty>
|
||||||
</u-empty>
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@ -1,166 +1,76 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :style="themeColor()">
|
<view :style="themeColor()">
|
||||||
<u-loading-page :loading="loading" loadingText="" bg-color="#f7f7f7"></u-loading-page>
|
|
||||||
|
|
||||||
<view v-show="!loading">
|
<u-loading-page :loading="diy.getLoading()" loadingText="" bg-color="#f7f7f7" />
|
||||||
<!-- #ifdef MP-WEIXIN -->
|
|
||||||
<top-tabbar v-if="!isShowTopTabbar" :title="data.title" />
|
<view v-show="!diy.getLoading()">
|
||||||
<!-- #endif -->
|
|
||||||
|
|
||||||
<!-- 自定义模板渲染 -->
|
<!-- 自定义模板渲染 -->
|
||||||
<view class="diy-template-wrap bg-index" v-if="data.pageMode != 'fixed'" :style="pageStyle">
|
<view class="diy-template-wrap bg-index" v-if="diy.data.pageMode != 'fixed'" :style="diy.pageStyle()">
|
||||||
|
|
||||||
<diy-group :data="data" :pullDownRefreshCount="pullDownRefreshCount"></diy-group>
|
<diy-group ref="diyGroupRef" :data="diy.data" :pullDownRefreshCount="diy.pullDownRefreshCount" />
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 固定模板渲染 -->
|
<!-- 固定模板渲染 -->
|
||||||
<view class="fixed-template-wrap" v-if="data.pageMode == 'fixed'">
|
<view class="fixed-template-wrap" v-if="diy.data.pageMode == 'fixed'">
|
||||||
|
|
||||||
<fixed-group :data="data" :pullDownRefreshCount="pullDownRefreshCount"></fixed-group>
|
<fixed-group :data="diy.data" :pullDownRefreshCount="diy.pullDownRefreshCount" />
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
|
<!-- 小程序隐私协议 -->
|
||||||
|
<wx-privacy-popup ref="wxPrivacyPopup"></wx-privacy-popup>
|
||||||
|
<!-- #endif -->
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, computed } from 'vue';
|
import {ref} from 'vue';
|
||||||
import { onLoad, onShow, onPullDownRefresh, onPageScroll } from '@dcloudio/uni-app';
|
import {useDiy} from '@/hooks/useDiy'
|
||||||
import { getDiyInfo } from '@/app/api/diy';
|
import {useShare} from '@/hooks/useShare'
|
||||||
import useDiyStore from '@/app/stores/diy';
|
|
||||||
import { useShare } from '@/hooks/useShare'
|
|
||||||
import { img } from '@/utils/common';
|
|
||||||
import diyGroup from '@/addon/components/diy/group/index.vue'
|
import diyGroup from '@/addon/components/diy/group/index.vue'
|
||||||
import fixedGroup from '@/addon/components/fixed/group/index.vue'
|
import fixedGroup from '@/addon/components/fixed/group/index.vue'
|
||||||
|
|
||||||
const { setShare, onShareAppMessage, onShareTimeline } = useShare()
|
const {setShare} = useShare()
|
||||||
onShareAppMessage()
|
|
||||||
onShareTimeline()
|
|
||||||
|
|
||||||
const loading = ref(true);
|
const diy = useDiy({})
|
||||||
const diyStore = useDiyStore();
|
|
||||||
const pullDownRefreshCount = ref(0)
|
|
||||||
let isShowTopTabbar = ref(false);
|
|
||||||
|
|
||||||
const diyData = reactive({
|
const diyGroupRef = ref(null)
|
||||||
pageMode: 'diy',
|
|
||||||
title: '',
|
|
||||||
global: {},
|
|
||||||
value: []
|
|
||||||
})
|
|
||||||
|
|
||||||
const data = computed(() => {
|
// 监听页面加载
|
||||||
if (diyStore.mode == 'decorate') {
|
diy.onLoad();
|
||||||
return diyStore;
|
|
||||||
} else {
|
|
||||||
return diyData;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const id = ref(0)
|
// 监听页面显示
|
||||||
const name = ref('')
|
diy.onShow((data: any) => {
|
||||||
const template = ref('')
|
let share = data.share ? JSON.parse(data.share) : null;
|
||||||
|
setShare(share);
|
||||||
onLoad(option => {
|
diyGroupRef.value?.refresh();
|
||||||
// #ifdef H5
|
|
||||||
// 装修模式
|
|
||||||
diyStore.mode = option.mode || '';
|
|
||||||
if (diyStore.mode == 'decorate') {
|
|
||||||
loading.value = false;
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
id.value = option.id || '';
|
|
||||||
name.value = option.name || '';
|
|
||||||
template.value = option.template || '';
|
|
||||||
});
|
|
||||||
|
|
||||||
onShow(() => {
|
|
||||||
// 装修模式
|
|
||||||
if (diyStore.mode == 'decorate') {
|
|
||||||
diyStore.init();
|
|
||||||
} else {
|
|
||||||
getDiyInfo({
|
|
||||||
id: id.value,
|
|
||||||
name: name.value,
|
|
||||||
template: template.value
|
|
||||||
}).then((res : any) => {
|
|
||||||
if (res.data.value) {
|
|
||||||
let data = res.data;
|
|
||||||
diyData.pageMode = data.mode;
|
|
||||||
diyData.title = data.title;
|
|
||||||
|
|
||||||
let sources = JSON.parse(data.value);
|
|
||||||
diyData.global = sources.global;
|
|
||||||
diyData.value = sources.value;
|
|
||||||
diyData.value.forEach((item, index) => {
|
|
||||||
item.pageStyle = '';
|
|
||||||
if(item.pageStartBgColor) {
|
|
||||||
if (item.pageStartBgColor && item.pageEndBgColor) item.pageStyle += `background:linear-gradient(${item.pageGradientAngle},${item.pageStartBgColor},${item.pageEndBgColor});`;
|
|
||||||
else item.pageStyle += 'background-color:' + item.pageStartBgColor + ';';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.margin) {
|
|
||||||
item.pageStyle += 'padding-top:' + item.margin.top * 2 + 'rpx' + ';';
|
|
||||||
item.pageStyle += 'padding-bottom:' + item.margin.bottom * 2 + 'rpx' + ';';
|
|
||||||
item.pageStyle += 'padding-right:' + item.margin.both * 2 + 'rpx' + ';';
|
|
||||||
item.pageStyle += 'padding-left:' + item.margin.both * 2 + 'rpx' + ';';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// 控制自定义头部是否出现 | 微信小程序
|
|
||||||
isShowTopTabbar.value = diyData.value.some((item)=>{
|
|
||||||
return item && item.position && item.position == 'top_fixed'
|
|
||||||
})
|
|
||||||
uni.setNavigationBarTitle({
|
|
||||||
title: diyData.global.title
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
let share = res.data.share ? JSON.parse(res.data.share) : null;
|
|
||||||
setShare(share);
|
|
||||||
|
|
||||||
loading.value = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const pageStyle = computed(()=>{
|
|
||||||
var style = '';
|
|
||||||
if (data.value.global.pageStartBgColor && data.value.global.pageEndBgColor) style += `background:linear-gradient(${data.value.global.pageGradientAngle},${data.value.global.pageStartBgColor},${data.value.global.pageEndBgColor});`;
|
|
||||||
else style += 'background-color:' + data.value.global.pageStartBgColor + ';';
|
|
||||||
|
|
||||||
style += 'min-height:calc(100vh - 50px);';
|
|
||||||
if(data.value.global.bgUrl) {
|
|
||||||
style += `background-image:url('${ img(data.value.global.bgUrl) }');`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.value.global.bgHeightScale) {
|
|
||||||
style += `background-size: 100% ${data.value.global.bgHeightScale}%;`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return style;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 监听下拉刷新事件
|
// 监听下拉刷新事件
|
||||||
onPullDownRefresh(() => {
|
diy.onPullDownRefresh()
|
||||||
pullDownRefreshCount.value++;
|
|
||||||
uni.stopPullDownRefresh();
|
|
||||||
})
|
|
||||||
|
|
||||||
onPageScroll((e)=>{
|
// 监听滚动事件
|
||||||
diyStore.scrollTop = e.scrollTop;
|
diy.onPageScroll()
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '@/styles/diy.scss';
|
@import '@/styles/diy.scss';
|
||||||
</style>
|
</style>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.diy-template-wrap {
|
.diy-template-wrap {
|
||||||
::v-deep .diy-group {
|
/* #ifdef MP */
|
||||||
> .draggable-element.top-fixed-diy {
|
.child-diy-template-wrap {
|
||||||
display: none;
|
::v-deep .diy-group {
|
||||||
}
|
> .draggable-element.top-fixed-diy {
|
||||||
}
|
display: block !important;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -1,168 +1,82 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :style="themeColor()">
|
<view :style="themeColor()">
|
||||||
<u-loading-page :loading="loading" loadingText="" bg-color="#f7f7f7"></u-loading-page>
|
|
||||||
|
|
||||||
<view v-show="!loading">
|
<u-loading-page :loading="diy.getLoading()" loadingText="" bg-color="#f7f7f7" />
|
||||||
<!-- #ifdef MP-WEIXIN -->
|
|
||||||
<top-tabbar v-if="!isShowTopTabbar" :title="data.title" />
|
<view v-show="!diy.getLoading()">
|
||||||
<!-- #endif -->
|
|
||||||
|
|
||||||
<!-- 自定义模板渲染 -->
|
<!-- 自定义模板渲染 -->
|
||||||
<view class="diy-template-wrap bg-index" v-if="data.pageMode != 'fixed'" :style="pageStyle">
|
<view class="diy-template-wrap bg-index" v-if="diy.data.pageMode != 'fixed'" :style="diy.pageStyle()">
|
||||||
|
|
||||||
<diy-group :data="data" :pullDownRefreshCount="pullDownRefreshCount"></diy-group>
|
<diy-group ref="diyGroupRef" :data="diy.data" :pullDownRefreshCount="diy.pullDownRefreshCount" />
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 固定模板渲染 -->
|
<!-- 固定模板渲染 -->
|
||||||
<view class="fixed-template-wrap" v-if="data.pageMode == 'fixed'">
|
<view class="fixed-template-wrap" v-if="diy.data.pageMode == 'fixed'">
|
||||||
|
|
||||||
<fixed-group :data="data" :pullDownRefreshCount="pullDownRefreshCount"></fixed-group>
|
<fixed-group :data="diy.data" :pullDownRefreshCount="diy.pullDownRefreshCount" />
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
|
<!-- 小程序隐私协议 -->
|
||||||
|
<wx-privacy-popup ref="wxPrivacyPopup"></wx-privacy-popup>
|
||||||
|
<!-- #endif -->
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, computed } from 'vue';
|
import {ref} from 'vue';
|
||||||
import { onLoad, onShow, onPullDownRefresh, onPageScroll } from '@dcloudio/uni-app';
|
import {useDiy} from '@/hooks/useDiy'
|
||||||
import { getDiyInfo } from '@/app/api/diy';
|
import {redirect} from '@/utils/common';
|
||||||
import useDiyStore from '@/app/stores/diy';
|
|
||||||
import { useShare } from '@/hooks/useShare'
|
|
||||||
import { img,redirect } from '@/utils/common';
|
|
||||||
import diyGroup from '@/addon/components/diy/group/index.vue'
|
import diyGroup from '@/addon/components/diy/group/index.vue'
|
||||||
import fixedGroup from '@/addon/components/fixed/group/index.vue'
|
import fixedGroup from '@/addon/components/fixed/group/index.vue'
|
||||||
|
|
||||||
const { setShare, onShareAppMessage, onShareTimeline } = useShare()
|
const diy = useDiy({
|
||||||
setShare();
|
name: 'DIY_INDEX'
|
||||||
onShareAppMessage()
|
})
|
||||||
onShareTimeline()
|
|
||||||
|
|
||||||
const loading = ref(true);
|
const diyGroupRef = ref(null)
|
||||||
const diyStore = useDiyStore();
|
|
||||||
const pullDownRefreshCount = ref(0)
|
|
||||||
let isShowTopTabbar = ref(false);
|
|
||||||
|
|
||||||
const id = ref(0)
|
// 监听页面加载
|
||||||
const name = ref('DIY_INDEX')
|
diy.onLoad();
|
||||||
const template = ref('')
|
|
||||||
|
|
||||||
// 自定义页面 数据
|
// 监听页面显示
|
||||||
const diyData = reactive({
|
diy.onShow((data: any) => {
|
||||||
pageMode: 'diy',
|
if (data.value) {
|
||||||
title: '',
|
// uni.setNavigationBarTitle({
|
||||||
global: {},
|
// title: diyData.title
|
||||||
value: []
|
// })
|
||||||
})
|
} else if (data.page) {
|
||||||
|
// 跳转到设置的启动页
|
||||||
const data = computed(() => {
|
redirect({url: data.page, mode: 'reLaunch'})
|
||||||
if (diyStore.mode == 'decorate') {
|
|
||||||
return diyStore;
|
|
||||||
} else {
|
|
||||||
return diyData;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
onLoad(option => {
|
|
||||||
// #ifdef H5
|
|
||||||
// 装修模式
|
|
||||||
diyStore.mode = option.mode || '';
|
|
||||||
if (diyStore.mode == 'decorate') {
|
|
||||||
loading.value = false;
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
id.value = option.id || '';
|
|
||||||
template.value = option.template || '';
|
|
||||||
});
|
|
||||||
|
|
||||||
onShow(() => {
|
|
||||||
// 装修模式
|
|
||||||
if (diyStore.mode == 'decorate') {
|
|
||||||
diyStore.init();
|
|
||||||
} else {
|
|
||||||
getDiyInfo({
|
|
||||||
id: id.value,
|
|
||||||
name: name.value,
|
|
||||||
template: template.value
|
|
||||||
}).then((res : any) => {
|
|
||||||
let data = res.data;
|
|
||||||
if (data.value) {
|
|
||||||
diyData.pageMode = data.mode;
|
|
||||||
diyData.title = data.title;
|
|
||||||
|
|
||||||
let sources = JSON.parse(data.value);
|
|
||||||
diyData.global = sources.global;
|
|
||||||
diyData.value = sources.value;
|
|
||||||
diyData.value.forEach((item, index) => {
|
|
||||||
item.pageStyle = '';
|
|
||||||
if(item.pageStartBgColor) {
|
|
||||||
if (item.pageStartBgColor && item.pageEndBgColor) item.pageStyle += `background:linear-gradient(${item.pageGradientAngle},${item.pageStartBgColor},${item.pageEndBgColor});`;
|
|
||||||
else item.pageStyle += 'background-color:' + item.pageStartBgColor + ';';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.margin) {
|
|
||||||
item.pageStyle += 'padding-top:' + item.margin.top * 2 + 'rpx' + ';';
|
|
||||||
item.pageStyle += 'padding-bottom:' + item.margin.bottom * 2 + 'rpx' + ';';
|
|
||||||
item.pageStyle += 'padding-right:' + item.margin.both * 2 + 'rpx' + ';';
|
|
||||||
item.pageStyle += 'padding-left:' + item.margin.both * 2 + 'rpx' + ';';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// 控制自定义头部是否出现 | 微信小程序
|
|
||||||
isShowTopTabbar.value = diyData.value.some((item)=>{
|
|
||||||
return item && item.position && item.position == 'top_fixed'
|
|
||||||
})
|
|
||||||
// uni.setNavigationBarTitle({
|
|
||||||
// title: diyData.global.title
|
|
||||||
// })
|
|
||||||
} else if (data.page) {
|
|
||||||
// 跳转到设置的启动页
|
|
||||||
redirect({ url: data.page, mode : 'reLaunch' })
|
|
||||||
}
|
|
||||||
|
|
||||||
loading.value = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
const pageStyle = computed(()=>{
|
|
||||||
var style = '';
|
|
||||||
if (data.value.global.pageStartBgColor && data.value.global.pageEndBgColor) style += `background:linear-gradient(${data.value.global.pageGradientAngle},${data.value.global.pageStartBgColor},${data.value.global.pageEndBgColor});`;
|
|
||||||
else style += 'background-color:' + data.value.global.pageStartBgColor + ';';
|
|
||||||
|
|
||||||
style += 'min-height:calc(100vh - 50px);';
|
|
||||||
if(data.value.global.bgUrl) {
|
|
||||||
style += `background-image:url('${ img(data.value.global.bgUrl) }');`;
|
|
||||||
}
|
}
|
||||||
|
diyGroupRef.value?.refresh();
|
||||||
if (data.value.global.bgHeightScale) {
|
|
||||||
style += `background-size: 100% ${data.value.global.bgHeightScale}%;`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return style;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 监听下拉刷新事件
|
// 监听下拉刷新事件
|
||||||
onPullDownRefresh(() => {
|
diy.onPullDownRefresh()
|
||||||
pullDownRefreshCount.value++;
|
|
||||||
uni.stopPullDownRefresh();
|
|
||||||
})
|
|
||||||
|
|
||||||
onPageScroll((e)=>{
|
// 监听滚动事件
|
||||||
diyStore.scrollTop = e.scrollTop;
|
diy.onPageScroll()
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '@/styles/diy.scss';
|
@import '@/styles/diy.scss';
|
||||||
</style>
|
</style>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.diy-template-wrap {
|
.diy-template-wrap {
|
||||||
::v-deep .diy-group {
|
/* #ifdef MP */
|
||||||
> .draggable-element.top-fixed-diy {
|
.child-diy-template-wrap {
|
||||||
display: none;
|
::v-deep .diy-group {
|
||||||
}
|
> .draggable-element.top-fixed-diy {
|
||||||
}
|
display: block !important;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -1,13 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="w-screen h-screen flex flex-col items-center justify-center" :style="themeColor()">
|
<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 :icon="img('static/resource/images/site/close.png')" :text="t('noSite')"></u-empty>
|
||||||
</u-empty>
|
</view>
|
||||||
</view>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { img } from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import { t } from '@/locale'
|
import { t } from '@/locale'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
@ -1,25 +1,31 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="w-screen h-screen bg-page" :style="themeColor()">
|
<view class="w-screen h-screen bg-page" :style="themeColor()">
|
||||||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="getCashoutAccountListFn">
|
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="getCashoutAccountListFn">
|
||||||
<view class="h-[20rpx]"></view>
|
<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)">
|
<u-swipe-action-item :options="accountOptions" @click="swipeClick(index)" v-for="(item, index) in accountList" :key="index" class="mx-[32rpx] my-[20rpx]">
|
||||||
<view class="w-[100rpx] h-[100rpx] flex items-center justify-center mr-[10rpx]">
|
<view class="p-[30rpx] bg-white rounded flex justify-between" >
|
||||||
<image
|
<view class="flex">
|
||||||
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAACnVJREFUeF7tWXtQVNcZ/91FQQZZdhcXfKCCqFXQuKBV0YSHqWJ9AbU+qkZQG+uEyu66i0maB5jEaSetBdvG1vrCRhM1bQS1SUw6gn0kJhkDpqLNQ10jLApEHmrCuuyeznfWRZZd3L03/MOw38zOPfee8517vt/5fY9zV0AfF6GP2w8/AH4G9HEE/C7QxwngD4J+F/C7QB9HwO8CfZwA/iwgyQWuQznBBmGxAKGdwd4u41e0070Ndhtd7z2zUT+DYKN7GWzt14PDAtZOXfIjgLULYNaziuGfQ0A73QPMxtt2wdGG0H6vzwaB2kI7omyjoMZkMFgRav8MTGZFP+Eu7PZ23gaz8nGMWRHArGABVtht7QiQfY08Q2VXxosGwAzlVkDQAggR6z7bx87EjrEzcKtfkFhVIBjAcAYMZeJ1uYbwDWR4BnmG4s4TiALAjPBfAuwpKSvYFTsVBRPnSFF16ExigFKq8R2vvQmdMVwSAGYoVwHCq1IsqA4bjIXJOWgL6CdFHYhljt3vCWEsDfr8CudUPjOgFqpDArBMyhp2x07F899l96fbgQFS3uxBp/l2AAoL7aIBMEN1GUCMlGXkTsnE0agJUlSBgQCmdKxX2hz3tf4NnfER0S5QA4VGBplbBPV1NTNm58IUovR1uOu4IQC+10MACMJWaA3PigbADOV6QNgpxYKL8gg8Omu9FFWHzlg7MFS6uoumTJaOvE3vSgBAtRvAOinLeH2kBoaEBVJUHTqT7UCodHUXzf7BocjNvS0agFqoPhWAiQMy56HfpAmwXb2Gb0te5/MEps5EYMpMWMrehrXqv24r3ayZhwPRiZIsSNVEISV9mItuVUMDyi5/KX4+AR9Ba5zWVdFrFriOsBg7AigAYlBlBfprJuLb/YfQnJPL5wqvOMYBaExI9QjA7LSfgtKgFCktWIQMTSzONTZAERSEkaFyPs2a995ByYVqcVMK7DfQ5ueLBsAM5QpAOEiKQ9jXXL8p6zG0lb7F2/SMtbTiusI9QZiD5ZiSniduoZ1GN732BBTBQYjZtwum1lZUrVyNSYPU2PLhByg88764ee1sETblH5cAgIpKRy1RPbz8GNe/oRwFe3MLZwOxoq3sbTRlruJ9MkUY7yM5NiwOh9bkISU+CvvLL8BU39rtohUhjvKYrjROE6NG5W9X4eqtVkTv3cUZULliNaLlciS89iqqGurFAWBlkcjPd1Py6gJ1UL3PgKQQ3QbIi7bCeu48GjUp/OXOZ636Z/g99dtMXyEgegQH4bllzyJi41pER8iR87uT3Kh9G9P5ffMdC9Kee4MbfPSpRR3G03Plqh3QLUxE0doUvvOll75AZuwYbvz+i9WoqLmGouQ0mFpb0GyxICYsDJnHy3B0QQYHjNhB7e1VnziYwnAOeqPGE2IPBOAmlGFtEIj3AYqSVxCcvdzF/5WlBzAg44fc/wkM6r+95WUMLNjM3/WDec9gd8mT3GAy6srOdWj5xgLdngpu9PYTlRyIgmXTeTtzWixGquUQsopQYkhH9sNx3CACodnShtJLX/J2+eKlHAiS7PHxvE0xgZ6frq0BY4yDojn4Fw4QGH4PvdGjLz4QgBoo58sgnKAXOYPdne070ar7Bad6ZNNlnhHqozUdAbJOCOdxof1qDZKKTuHj4tU4XV2DklMXsG/jHGw5fIZT3NlOnRDFXSTmZ3tQ/uISKAcGQbFyB67sWYdolTvdSxdmIGPUaO4GmbGjUTAtCfp/VqC48iyY1tCxyS6BUmDLoM0/IpoBZihfAgTOb+duE7UtpW/x9EdUp4B4t+I/HAxyDwKHYsWVwyfwQn1gh6E0B+10yalqaGIiEBMph0Z/gPu5IIC3iSEEFrkLZ4vFAsWf/uCy7oofL0PKsChknSjjbtA5JjgBIBak/vXwfT1mjYH+aZMEAFRUNc0mRTI2tPBJbjiJteo87hT/kRtPwVBevJW3qRYgd3jzZCU+mzQFtMOFhz5A1ZUGlD69iO922UeX+DOif8VLS1D64SUOTPG6VM4UU30LCh9PQtXNeuhOl7usOycuHsXJaWi+a+FpsTNIzizhGiSFi9AZ4rqLmA90ATNUzQDCxIVbx+iVST9BeWSsFFWAEkKSuPqfmHBlzeM8HuS8+06n9wo7oTNsEA3ADaiSbIDIZHv/NXHzDGgOpM84EkTNgHhx53+K+mlRwxG9b5cj8DmFCWugN5SIBqAOKiMDfi1h+ahSDMG81O6PDuTflBmKj3+Cc6ZGnh61CxK4K1AmcAr5OUX+pg0/548o7WnUES5LIrpTcVQyZ67nAokFxEGvvygaADNUbwLIkgJAd5+/KOdTpKcASDGBhHyegiOlx+LjlRipDkXO3Hgog4N4AKRIT7vrzP/7Zs/l+Z0kZ3w8qhod8xA4rtTnjy9DZ3ygH3YbA8xQ1QBwPYn4iMb6qYtxYuh4t9G061QIVZy/1tF3ztTAawK6UlAk4ZXjPV8uTkmDVpPIix+qBokBlPYyRrna1XLXwoshF2HYD70x50HL9giAGeHjANYtbbzh8P30jagNdo+dBEBJXrpLaUysIPoTIwgAhTwImhFqpP3tCDeaAhulSdpd2n2HoaWIlofxe2cf+b2H8jgXOuMO0QDUQrVOAOgbgGgxhagwY/YTHvVyZsVzY8nnnf5P91T8EP0zpsZi/6fVyJgWy098ZGTlisc4EFQBUgokZjhPhalRw3nAI8OJFW4ACJgCrfGsaADqoNrLgDWirQdwZMRD0CU6avuu4qzvie4U8JwVYeeS2NTUihabhZexuoTJKEpO5UYTGFQAUdAjV6C4QFdnGUzGu0R/oBY6Y5Q3G7pxAdX/6EucN2VP/fma+TgYneBRlYoiCoL6vac5A4gRVBJn/eoYrw4pGAovb+N1ABlHtT35PFV1hdNn8DYdjQkYnSaRF0NNbW0cFA/yBnTGpd5scAPgOgZG2BF4w5tid/2pj27A56GDPHYXLk/iRtLOUzVI/p+d5ijSiBWTotW8Tf5PhQ35eFchV6A+chFyAToMdfOBxAidcZs3O9wAMCM8C2CUAkVLc/9gxM2/fyDpOgEZTP5PQiBQ0HPeUxDUJKqBkYz7fGdxRn9KdeQKTr93PvdAf8BuT8amzf/yZoQHAFSE2iZvip763xs8FtnTvbKu+6nHMGCYuArQ82RCA4beisLSwrve7HADoBaqMwLg9vHQ20TUvzV+Fl4ZM8OXoZ7H9NQXYIa/Q2/06VO0CwAM6FcHlVWqBRmPZOPj8OHS1GUAksUdgLp9kSA8D63hRV8W4gLANShSAyBzPX/6Msu9MUMzXf50EaFJHwMZoOkJ+vPXzoXOeNKXBXRlQGCd4wgs6Ri3Kmk5TkWO9uW97mOIAQ/bAbp+N9kGndHo6xSegqDkf4G2jUsG/STLODsg7S8EQIAZEP4MrWGLmPd7LIS+AIIGQJEkZqLOYwseSudfYL8KCav/R+QYs6h51BiMMAxGsKwRKjsdyHyTTv/5+6bgGOX1s7iYyXrjWD8AvXHXenLNfgb0JJq9cS4/A3rjrvXkmv0M6Ek0e+Ncfgb0xl3ryTX7GdCTaPbGufo8A/4PpckqfWjPHTQAAAAASUVORK5CYII="
|
<view class="w-[100rpx] h-[100rpx] flex items-center justify-center mr-[10rpx]" @click="handleClick(item)">
|
||||||
mode="widthFix" class="w-[80rpx]" v-if="item.account_type == 'bank'"></image>
|
<image
|
||||||
<text class="iconfont iconzhifubaoxuanzhong text-[#188dfb] text-[80rpx]" v-else></text>
|
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAACnVJREFUeF7tWXtQVNcZ/91FQQZZdhcXfKCCqFXQuKBV0YSHqWJ9AbU+qkZQG+uEyu66i0maB5jEaSetBdvG1vrCRhM1bQS1SUw6gn0kJhkDpqLNQ10jLApEHmrCuuyeznfWRZZd3L03/MOw38zOPfee8517vt/5fY9zV0AfF6GP2w8/AH4G9HEE/C7QxwngD4J+F/C7QB9HwO8CfZwA/iwgyQWuQznBBmGxAKGdwd4u41e0070Ndhtd7z2zUT+DYKN7GWzt14PDAtZOXfIjgLULYNaziuGfQ0A73QPMxtt2wdGG0H6vzwaB2kI7omyjoMZkMFgRav8MTGZFP+Eu7PZ23gaz8nGMWRHArGABVtht7QiQfY08Q2VXxosGwAzlVkDQAggR6z7bx87EjrEzcKtfkFhVIBjAcAYMZeJ1uYbwDWR4BnmG4s4TiALAjPBfAuwpKSvYFTsVBRPnSFF16ExigFKq8R2vvQmdMVwSAGYoVwHCq1IsqA4bjIXJOWgL6CdFHYhljt3vCWEsDfr8CudUPjOgFqpDArBMyhp2x07F899l96fbgQFS3uxBp/l2AAoL7aIBMEN1GUCMlGXkTsnE0agJUlSBgQCmdKxX2hz3tf4NnfER0S5QA4VGBplbBPV1NTNm58IUovR1uOu4IQC+10MACMJWaA3PigbADOV6QNgpxYKL8gg8Omu9FFWHzlg7MFS6uoumTJaOvE3vSgBAtRvAOinLeH2kBoaEBVJUHTqT7UCodHUXzf7BocjNvS0agFqoPhWAiQMy56HfpAmwXb2Gb0te5/MEps5EYMpMWMrehrXqv24r3ayZhwPRiZIsSNVEISV9mItuVUMDyi5/KX4+AR9Ba5zWVdFrFriOsBg7AigAYlBlBfprJuLb/YfQnJPL5wqvOMYBaExI9QjA7LSfgtKgFCktWIQMTSzONTZAERSEkaFyPs2a995ByYVqcVMK7DfQ5ueLBsAM5QpAOEiKQ9jXXL8p6zG0lb7F2/SMtbTiusI9QZiD5ZiSniduoZ1GN732BBTBQYjZtwum1lZUrVyNSYPU2PLhByg88764ee1sETblH5cAgIpKRy1RPbz8GNe/oRwFe3MLZwOxoq3sbTRlruJ9MkUY7yM5NiwOh9bkISU+CvvLL8BU39rtohUhjvKYrjROE6NG5W9X4eqtVkTv3cUZULliNaLlciS89iqqGurFAWBlkcjPd1Py6gJ1UL3PgKQQ3QbIi7bCeu48GjUp/OXOZ636Z/g99dtMXyEgegQH4bllzyJi41pER8iR87uT3Kh9G9P5ffMdC9Kee4MbfPSpRR3G03Plqh3QLUxE0doUvvOll75AZuwYbvz+i9WoqLmGouQ0mFpb0GyxICYsDJnHy3B0QQYHjNhB7e1VnziYwnAOeqPGE2IPBOAmlGFtEIj3AYqSVxCcvdzF/5WlBzAg44fc/wkM6r+95WUMLNjM3/WDec9gd8mT3GAy6srOdWj5xgLdngpu9PYTlRyIgmXTeTtzWixGquUQsopQYkhH9sNx3CACodnShtJLX/J2+eKlHAiS7PHxvE0xgZ6frq0BY4yDojn4Fw4QGH4PvdGjLz4QgBoo58sgnKAXOYPdne070ar7Bad6ZNNlnhHqozUdAbJOCOdxof1qDZKKTuHj4tU4XV2DklMXsG/jHGw5fIZT3NlOnRDFXSTmZ3tQ/uISKAcGQbFyB67sWYdolTvdSxdmIGPUaO4GmbGjUTAtCfp/VqC48iyY1tCxyS6BUmDLoM0/IpoBZihfAgTOb+duE7UtpW/x9EdUp4B4t+I/HAxyDwKHYsWVwyfwQn1gh6E0B+10yalqaGIiEBMph0Z/gPu5IIC3iSEEFrkLZ4vFAsWf/uCy7oofL0PKsChknSjjbtA5JjgBIBak/vXwfT1mjYH+aZMEAFRUNc0mRTI2tPBJbjiJteo87hT/kRtPwVBevJW3qRYgd3jzZCU+mzQFtMOFhz5A1ZUGlD69iO922UeX+DOif8VLS1D64SUOTPG6VM4UU30LCh9PQtXNeuhOl7usOycuHsXJaWi+a+FpsTNIzizhGiSFi9AZ4rqLmA90ATNUzQDCxIVbx+iVST9BeWSsFFWAEkKSuPqfmHBlzeM8HuS8+06n9wo7oTNsEA3ADaiSbIDIZHv/NXHzDGgOpM84EkTNgHhx53+K+mlRwxG9b5cj8DmFCWugN5SIBqAOKiMDfi1h+ahSDMG81O6PDuTflBmKj3+Cc6ZGnh61CxK4K1AmcAr5OUX+pg0/548o7WnUES5LIrpTcVQyZ67nAokFxEGvvygaADNUbwLIkgJAd5+/KOdTpKcASDGBhHyegiOlx+LjlRipDkXO3Hgog4N4AKRIT7vrzP/7Zs/l+Z0kZ3w8qhod8xA4rtTnjy9DZ3ygH3YbA8xQ1QBwPYn4iMb6qYtxYuh4t9G061QIVZy/1tF3ztTAawK6UlAk4ZXjPV8uTkmDVpPIix+qBokBlPYyRrna1XLXwoshF2HYD70x50HL9giAGeHjANYtbbzh8P30jagNdo+dBEBJXrpLaUysIPoTIwgAhTwImhFqpP3tCDeaAhulSdpd2n2HoaWIlofxe2cf+b2H8jgXOuMO0QDUQrVOAOgbgGgxhagwY/YTHvVyZsVzY8nnnf5P91T8EP0zpsZi/6fVyJgWy098ZGTlisc4EFQBUgokZjhPhalRw3nAI8OJFW4ACJgCrfGsaADqoNrLgDWirQdwZMRD0CU6avuu4qzvie4U8JwVYeeS2NTUihabhZexuoTJKEpO5UYTGFQAUdAjV6C4QFdnGUzGu0R/oBY6Y5Q3G7pxAdX/6EucN2VP/fma+TgYneBRlYoiCoL6vac5A4gRVBJn/eoYrw4pGAovb+N1ABlHtT35PFV1hdNn8DYdjQkYnSaRF0NNbW0cFA/yBnTGpd5scAPgOgZG2BF4w5tid/2pj27A56GDPHYXLk/iRtLOUzVI/p+d5ijSiBWTotW8Tf5PhQ35eFchV6A+chFyAToMdfOBxAidcZs3O9wAMCM8C2CUAkVLc/9gxM2/fyDpOgEZTP5PQiBQ0HPeUxDUJKqBkYz7fGdxRn9KdeQKTr93PvdAf8BuT8amzf/yZoQHAFSE2iZvip763xs8FtnTvbKu+6nHMGCYuArQ82RCA4beisLSwrve7HADoBaqMwLg9vHQ20TUvzV+Fl4ZM8OXoZ7H9NQXYIa/Q2/06VO0CwAM6FcHlVWqBRmPZOPj8OHS1GUAksUdgLp9kSA8D63hRV8W4gLANShSAyBzPX/6Msu9MUMzXf50EaFJHwMZoOkJ+vPXzoXOeNKXBXRlQGCd4wgs6Ri3Kmk5TkWO9uW97mOIAQ/bAbp+N9kGndHo6xSegqDkf4G2jUsG/STLODsg7S8EQIAZEP4MrWGLmPd7LIS+AIIGQJEkZqLOYwseSudfYL8KCav/R+QYs6h51BiMMAxGsKwRKjsdyHyTTv/5+6bgGOX1s7iYyXrjWD8AvXHXenLNfgb0JJq9cS4/A3rjrvXkmv0M6Ek0e+Ncfgb0xl3ryTX7GdCTaPbGufo8A/4PpckqfWjPHTQAAAAASUVORK5CYII="
|
||||||
</view>
|
mode="widthFix" class="w-[80rpx]" v-if="item.account_type == 'bank'"></image>
|
||||||
<view>
|
<text class="iconfont iconzhifubaoxuanzhong text-[#188dfb] text-[80rpx]" v-else></text>
|
||||||
<view>{{ item.account_type == 'bank' ? item.bank_name : t('alipayAccountNo') }}</view>
|
</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 @click="handleClick(item)">
|
||||||
<view v-else class="text-sm text-gray-subtitle mt-[10rpx]">{{ item.account_no }}</view>
|
<view>{{ item.account_type == 'bank' ? item.bank_name : t('alipayAccountNo') }}</view>
|
||||||
</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>
|
<view v-else class="text-sm text-gray-subtitle mt-[10rpx]">{{ item.account_no }}</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 } })">
|
</view>
|
||||||
<u-icon name="plus" color="#333" size="16"></u-icon>
|
</view>
|
||||||
<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>
|
<text class="flex items-center nc-iconfont nc-icon-xiugaiV6xx shrink-0 text-[32rpx] p-[20rpx] pr-0" @click="editAccount(item)"></text>
|
||||||
</view>
|
</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>
|
</mescroll-body>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
@ -27,7 +33,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { redirect } from '@/utils/common'
|
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 MescrollBody from '@/components/mescroll/mescroll-body/mescroll-body.vue'
|
||||||
import useMescroll from '@/components/mescroll/hooks/useMescroll.js'
|
import useMescroll from '@/components/mescroll/hooks/useMescroll.js'
|
||||||
import { onPageScroll, onReachBottom, onLoad } from '@dcloudio/uni-app'
|
import { onPageScroll, onReachBottom, onLoad } from '@dcloudio/uni-app'
|
||||||
@ -68,9 +74,30 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) => {
|
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 } })
|
if (mode.value == 'get') redirect({ url: '/app/pages/member/account_edit', param: { id: data.account_id, type: accountType.value, mode: mode.value }, mode: 'redirectTo' })
|
||||||
else redirect({ url: '/app/pages/member/apply_cash_out', param: { account_id: data.account_id, type: accountType.value } })
|
else redirect({ url: '/app/pages/member/apply_cash_out', param: { account_id: data.account_id, type: accountType.value }, mode: 'redirectTo'})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -11,17 +11,17 @@
|
|||||||
<u-form labelPosition="left" :model="formData" labelWidth="200rpx" errorType='toast' :rules="rules" ref="formRef">
|
<u-form labelPosition="left" :model="formData" labelWidth="200rpx" errorType='toast' :rules="rules" ref="formRef">
|
||||||
<view class="mt-[10rpx]">
|
<view class="mt-[10rpx]">
|
||||||
<u-form-item :label="t('bankRealname')" prop="realname" :border-bottom="true">
|
<u-form-item :label="t('bankRealname')" prop="realname" :border-bottom="true">
|
||||||
<u-input v-model.trim="formData.realname" border="none" clearable :placeholder="t('bankRealnamePlaceholder')"/>
|
<u-input v-model.trim="formData.realname" maxlength="30" border="none" clearable :placeholder="t('bankRealnamePlaceholder')"/>
|
||||||
</u-form-item>
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-[10rpx]">
|
<view class="mt-[10rpx]">
|
||||||
<u-form-item :label="t('bankName')" prop="bank_name" :border-bottom="true">
|
<u-form-item :label="t('bankName')" prop="bank_name" :border-bottom="true">
|
||||||
<u-input v-model.trim="formData.bank_name" border="none" clearable :placeholder="t('bankNamePlaceholder')"/>
|
<u-input v-model.trim="formData.bank_name" maxlength="30" border="none" clearable :placeholder="t('bankNamePlaceholder')"/>
|
||||||
</u-form-item>
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-[10rpx]">
|
<view class="mt-[10rpx]">
|
||||||
<u-form-item :label="t('bankAccountNo')" prop="account_no" :border-bottom="true">
|
<u-form-item :label="t('bankAccountNo')" prop="account_no" :border-bottom="true">
|
||||||
<u-input v-model.trim="formData.account_no" border="none" clearable :placeholder="t('bankAccountNoPlaceholder')"/>
|
<u-input v-model.trim="formData.account_no" maxlength="30" border="none" clearable :placeholder="t('bankAccountNoPlaceholder')"/>
|
||||||
</u-form-item>
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
</u-form>
|
</u-form>
|
||||||
@ -36,12 +36,12 @@
|
|||||||
<u-form labelPosition="left" :model="formData" labelWidth="200rpx" errorType='toast' :rules="rules" ref="formRef">
|
<u-form labelPosition="left" :model="formData" labelWidth="200rpx" errorType='toast' :rules="rules" ref="formRef">
|
||||||
<view class="mt-[10rpx]">
|
<view class="mt-[10rpx]">
|
||||||
<u-form-item :label="t('alipayRealname')" prop="realname" :border-bottom="true">
|
<u-form-item :label="t('alipayRealname')" prop="realname" :border-bottom="true">
|
||||||
<u-input v-model.trim="formData.realname" border="none" clearable :placeholder="t('alipayRealnamePlaceholder')"/>
|
<u-input v-model.trim="formData.realname" maxlength="30" border="none" clearable :placeholder="t('alipayRealnamePlaceholder')"/>
|
||||||
</u-form-item>
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-[10rpx]">
|
<view class="mt-[10rpx]">
|
||||||
<u-form-item :label="t('alipayAccountNo')" prop="account_no" :border-bottom="true">
|
<u-form-item :label="t('alipayAccountNo')" prop="account_no" :border-bottom="true">
|
||||||
<u-input v-model.trim="formData.account_no" border="none" clearable :placeholder="t('alipayAccountNoPlaceholder')"/>
|
<u-input v-model.trim="formData.account_no" border="none" maxlength="30" clearable :placeholder="t('alipayAccountNoPlaceholder')"/>
|
||||||
</u-form-item>
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
</u-form>
|
</u-form>
|
||||||
@ -50,9 +50,6 @@
|
|||||||
|
|
||||||
<view class="mt-[100rpx]">
|
<view class="mt-[100rpx]">
|
||||||
<u-button :text="t('save')" type="primary" shape="circle" :loading="loading" @click="handleSave"></u-button>
|
<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>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
@ -128,7 +125,7 @@
|
|||||||
|
|
||||||
save(formData).then((res) => {
|
save(formData).then((res) => {
|
||||||
if (mode.value == 'get') redirect({ url: '/app/pages/member/account', param: { type: formData.account_type, mode: mode.value } })
|
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, type: formData.account_type } })
|
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(() => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,32 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<view v-if="!loading" :style="themeColor()">
|
<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">
|
<scroll-view scroll-y="true">
|
||||||
<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 }" >
|
|
||||||
<u-swipe-action>
|
<u-swipe-action>
|
||||||
<view class="p-[30rpx]" v-show="current == 0">
|
<view class="p-[30rpx]">
|
||||||
<u-swipe-action-item :options="addressOptions" @click="swipeClick" v-for="item in addressList">
|
<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="border-0 !border-b !border-[#f5f5f5] border-solid pb-[30rpx] flex items-center">
|
||||||
<view class="flex-1 line-feed" @click="selectAddress(item)">
|
<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]">
|
|
||||||
<u-empty text="暂无收货地址" :icon="img('static/resource/images/system/empty.png')"/>
|
|
||||||
</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="font-bold my-[10rpx] text-sm line-feed">{{ item.full_address }}</view>
|
||||||
<view class="text-sm flex items-center">
|
<view class="text-sm flex items-center">
|
||||||
<view>{{ item.name }}</view>
|
<view>{{ item.name }}</view>
|
||||||
@ -34,11 +13,11 @@
|
|||||||
<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 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>
|
||||||
</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>
|
</view>
|
||||||
</u-swipe-action-item>
|
</u-swipe-action-item>
|
||||||
<view v-if="!locationAddressList.length" class="pt-[15vh]">
|
<view v-if="!addressList.length" class="pt-[20vh]">
|
||||||
<u-empty text="暂无收货地址" :icon="img('static/resource/images/system/empty.png')"/>
|
<mescroll-empty :option="{tip : '暂无收货地址'}"></mescroll-empty>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</u-swipe-action>
|
</u-swipe-action>
|
||||||
@ -57,13 +36,10 @@
|
|||||||
import { redirect, img, mobileHide } from '@/utils/common'
|
import { redirect, img, mobileHide } from '@/utils/common'
|
||||||
import { getAddressList, deleteAddress } from '@/app/api/member'
|
import { getAddressList, deleteAddress } from '@/app/api/member'
|
||||||
import { t } from '@/locale'
|
import { t } from '@/locale'
|
||||||
|
import MescrollEmpty from '@/components/mescroll/mescroll-empty/mescroll-empty.vue';
|
||||||
|
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const current = ref(0)
|
const current = ref(0)
|
||||||
const tabs = ref([
|
|
||||||
{ name: '快递地址', key: 'address' },
|
|
||||||
{ name: '同城配送地址', key: 'location_address' }
|
|
||||||
])
|
|
||||||
const addressList = ref<object[]>([])
|
const addressList = ref<object[]>([])
|
||||||
const locationAddressList = ref<object[]>([])
|
const locationAddressList = ref<object[]>([])
|
||||||
const type = ref('')
|
const type = ref('')
|
||||||
@ -73,6 +49,8 @@
|
|||||||
type.value = data.type || ''
|
type.value = data.type || ''
|
||||||
source.value = data.source || ''
|
source.value = data.source || ''
|
||||||
if (data.type) current.value = data.type == 'address' ? 0 : 1
|
if (data.type) current.value = data.type == 'address' ? 0 : 1
|
||||||
|
// 清空缓存,防止受待支付界面影响
|
||||||
|
if(uni.getStorageSync('selectAddressCallback')){uni.removeStorage({ key: 'selectAddressCallback' })}
|
||||||
})
|
})
|
||||||
|
|
||||||
getAddressList({}).then(({ data }) => {
|
getAddressList({}).then(({ data }) => {
|
||||||
@ -80,25 +58,24 @@
|
|||||||
data.forEach(item => {
|
data.forEach(item => {
|
||||||
item.type == 'address' ? address.push(item) : locationAddress.push(item)
|
item.type == 'address' ? address.push(item) : locationAddress.push(item)
|
||||||
})
|
})
|
||||||
addressList.value = address
|
if(!source.value){ //地址管理使用
|
||||||
locationAddressList.value = locationAddress
|
addressList.value = data;
|
||||||
|
}else{ // 区分同城配送地址和快递地址
|
||||||
|
addressList.value = current.value == 0 ? address : locationAddress;
|
||||||
|
}
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
|
|
||||||
const switchTab = (event)=> {
|
|
||||||
current.value = event.index
|
|
||||||
}
|
|
||||||
|
|
||||||
const addAddress = ()=> {
|
const addAddress = ()=> {
|
||||||
const url = `/app/pages/member/${tabs.value[ current.value ].key}_edit`
|
const url = `/app/pages/member/address_edit`
|
||||||
redirect({ url, param: { type: tabs.value[ current.value ].key } })
|
redirect({ url, param: { source : source.value } })
|
||||||
}
|
}
|
||||||
|
|
||||||
const editAddress = (id: number)=> {
|
const editAddress = (id: number)=> {
|
||||||
const url = `/app/pages/member/${tabs.value[ current.value ].key}_edit`
|
const url = `/app/pages/member/address_edit`
|
||||||
redirect({ url, param: { id, type: tabs.value[ current.value ].key} })
|
redirect({ url, param: { id, source : source.value} })
|
||||||
}
|
}
|
||||||
|
|
||||||
const addressOptions = ref([
|
const addressOptions = ref([
|
||||||
@ -119,25 +96,27 @@
|
|||||||
key: 'selectAddressCallback',
|
key: 'selectAddressCallback',
|
||||||
data: selectAddress,
|
data: selectAddress,
|
||||||
success() {
|
success() {
|
||||||
redirect({url: selectAddress.back,mode:'redirectTo' })
|
redirect({url: selectAddress.back, mode: 'redirectTo'})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const swipeClick = (event: any) => {
|
const swipeClick = (index: any) => {
|
||||||
const list = current.value ? locationAddressList : addressList
|
const list = current.value ? locationAddressList : addressList
|
||||||
const data = list.value[event.index]
|
const data = list.value[index]
|
||||||
|
|
||||||
deleteAddress(data.id).then(() => {
|
deleteAddress(data.id).then(() => {
|
||||||
list.value.splice(event.index, 1)
|
list.value.splice(index, 1)
|
||||||
}).catch()
|
}).catch()
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
:deep(.u-tabs__wrapper__nav__line) {
|
:deep(.u-tabs__wrapper__nav__line) {
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
background: var(--primary-color) !important;
|
||||||
}
|
}
|
||||||
.line-feed{
|
.line-feed{
|
||||||
word-wrap:break-word;
|
word-wrap:break-word;
|
||||||
|
|||||||
@ -1,39 +1,57 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="px-[30rpx]" :style="themeColor()">
|
<view class="px-[30rpx] pt-[10rpx]" :style="themeColor()">
|
||||||
<u-form labelPosition="left" :model="formData" labelWidth="200rpx" errorType='toast' :rules="rules" ref="formRef">
|
<u-form labelPosition="left" :model="formData" labelWidth="200rpx" errorType='toast' :rules="rules" ref="formRef">
|
||||||
<view class="mt-[10rpx]">
|
<view class="">
|
||||||
<u-form-item :label="t('name')" prop="name" :border-bottom="true">
|
<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>
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-[10rpx]">
|
<view class="mt-[10rpx]">
|
||||||
<u-form-item :label="t('mobile')" prop="mobile" :border-bottom="true">
|
<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>
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-[10rpx]">
|
<view class="mt-[10rpx]">
|
||||||
<u-form-item :label="t('selectArea')" prop="area" :border-bottom="true" @click="selectArea">
|
<u-form-item :label="t('selectArea')" prop="area" :border-bottom="true" >
|
||||||
<view v-if="!formData.area" class="text-gray-placeholder text-[30rpx]">{{ t('selectAreaPlaceholder') }}</view>
|
<view class="flex w-full items-center" v-if="addressType == 'address' && isSelectMap != 1" @click="selectArea">
|
||||||
<view v-else class="text-[30rpx]">{{ formData.area }}</view>
|
<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>
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-[10rpx]">
|
<view class="mt-[10rpx]">
|
||||||
<u-form-item :label="t('address')" prop="address" :border-bottom="true">
|
<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>
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-[10rpx]">
|
<view class="mt-[10rpx]">
|
||||||
<u-form-item :label="t('defaultAddress')" prop="name" :border-bottom="true">
|
<u-form-item :label="t('defaultAddress')" prop="name" :border-bottom="true">
|
||||||
<u-switch v-model="formData.is_default" size="20" :activeValue="1" :inactiveValue="0"></u-switch>
|
<u-switch v-model="formData.is_default" size="20" :activeValue="1" :inactiveValue="0" activeColor="var(--primary-color)"/>
|
||||||
</u-form-item>
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-[40rpx]">
|
<view class="mt-[40rpx]">
|
||||||
<u-button type="primary" shape="circle" :text="t('save')" @click="save" :loading="operateLoading"></u-button>
|
<u-button type="primary" shape="circle" :text="t('save')" @click="save" :disabled="btnDisabled" :loading="operateLoading"></u-button>
|
||||||
</view>
|
</view>
|
||||||
</u-form>
|
</u-form>
|
||||||
|
<area-select ref="areaRef" @complete="areaSelectComplete" :area-id="formData.district_id"/>
|
||||||
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
|
<!-- 小程序隐私协议 -->
|
||||||
|
<wx-privacy-popup ref="wxPrivacyPopup"></wx-privacy-popup>
|
||||||
|
<!-- #endif -->
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<area-select ref="areaRef" @complete="areaSelectComplete" :area-id="formData.district_id"/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@ -42,6 +60,8 @@
|
|||||||
import { redirect } from '@/utils/common'
|
import { redirect } from '@/utils/common'
|
||||||
import { t } from '@/locale'
|
import { t } from '@/locale'
|
||||||
import { addAddress, editAddress, getAddressInfo } from '@/app/api/member'
|
import { addAddress, editAddress, getAddressInfo } from '@/app/api/member'
|
||||||
|
import manifestJson from '@/manifest.json'
|
||||||
|
import { getAddressByLatlng } from '@/app/api/system'
|
||||||
|
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
id: 0,
|
id: 0,
|
||||||
@ -50,26 +70,50 @@
|
|||||||
province_id: 0,
|
province_id: 0,
|
||||||
city_id: 0,
|
city_id: 0,
|
||||||
district_id: 0,
|
district_id: 0,
|
||||||
|
lat: '',
|
||||||
|
lng: '',
|
||||||
address: '',
|
address: '',
|
||||||
|
address_name: '',
|
||||||
full_address: '',
|
full_address: '',
|
||||||
is_default: 0,
|
is_default: 0,
|
||||||
area: '',
|
area: ''
|
||||||
type: 'address'
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const areaRef = ref()
|
const areaRef = ref()
|
||||||
const formRef = ref(null)
|
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) => {
|
onLoad((data) => {
|
||||||
|
isSelectMap.value = data.isSelectMap || '';
|
||||||
|
const selectAddress = uni.getStorageSync('selectAddressCallback')
|
||||||
if (data.id) {
|
if (data.id) {
|
||||||
getAddressInfo(data.id)
|
getAddressInfo(data.id)
|
||||||
.then(({ data }) => {
|
.then(res => {
|
||||||
data && Object.assign(formData.value, data)
|
res.data && Object.assign(formData.value, res.data)
|
||||||
|
// 兼容待支付页面编辑地址
|
||||||
|
if(selectAddress){
|
||||||
|
addressType.value = selectAddress.delivery == 'express' ? 'address' : 'locationAddress';
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch()
|
.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(() => {
|
const rules = computed(() => {
|
||||||
@ -100,7 +144,11 @@
|
|||||||
],
|
],
|
||||||
'area': {
|
'area': {
|
||||||
validator() {
|
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')
|
message: t('selectAreaPlaceholder')
|
||||||
},
|
},
|
||||||
@ -114,36 +162,152 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
const selectArea = () => {
|
const selectArea = () => {
|
||||||
|
isSelectAddress.value = true
|
||||||
areaRef.value.open()
|
areaRef.value.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
const areaSelectComplete = (event) => {
|
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.province_id = event.province.id || 0
|
||||||
formData.value.city_id = event.city.id || 0
|
formData.value.city_id = event.city.id || 0
|
||||||
formData.value.district_id = event.district.id || 0
|
formData.value.district_id = event.district.id || 0
|
||||||
formData.value.area = `${event.province.name || ''}${event.city.name || ''}${event.district.name || ''}`
|
formData.value.area = `${event.province.name || ''}${event.city.name || ''}${event.district.name || ''}`
|
||||||
|
isSelectAddress.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const operateLoading = ref(false)
|
const operateLoading = ref(false)
|
||||||
const save = ()=> {
|
const save = ()=> {
|
||||||
const save = formData.value.id ? editAddress : addAddress
|
const save = formData.value.id ? editAddress : addAddress
|
||||||
|
|
||||||
formRef.value.validate().then(() => {
|
formRef.value.validate().then(() => {
|
||||||
if (operateLoading.value) return
|
if (operateLoading.value) return
|
||||||
operateLoading.value = true
|
operateLoading.value = true
|
||||||
|
|
||||||
|
btnDisabled.value = true
|
||||||
|
|
||||||
formData.value.full_address = formData.value.area + formData.value.address
|
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) => {
|
save(formData.value).then((res) => {
|
||||||
operateLoading.value = false
|
operateLoading.value = false
|
||||||
setTimeout(()=> {
|
setTimeout(() => {
|
||||||
redirect({ url: '/app/pages/member/address', param: { type: type.value } })
|
btnDisabled.value = false
|
||||||
|
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)
|
}, 1000)
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
operateLoading.value = false
|
operateLoading.value = false
|
||||||
|
btnDisabled.value = false
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 选择地址
|
||||||
|
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.province + res.data.city + res.data.district) || 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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
@ -1,110 +1,102 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :style="themeColor()">
|
<view :style="themeColor()">
|
||||||
<scroll-view scroll-y="true" class="w-screen h-screen bg-page" v-if="!pageLoading">
|
<scroll-view scroll-y="true" class="w-screen h-screen bg-page" v-if="!pageLoading && config.is_open == 1">
|
||||||
<view>
|
<view class="px-[30rpx] pt-[20rpx]">
|
||||||
<view class="p-[30rpx] bg-white">
|
<view class="p-[20rpx] bg-white rounded-[16rpx]">
|
||||||
<view>{{t('cashOutMoneyTip')}}</view>
|
<view class="font-500 text-[32rpx] text-[#333] leading-[44rpx]">{{t('cashOutMoneyTip')}}</view>
|
||||||
<view class="flex py-[20rpx] items-baseline border-0 border-b-[2rpx] border-solid border-gray-200">
|
<view class="flex pt-[30rpx] pb-[8rpx] items-center border-0 border-b-[2rpx] border-solid border-gray-200">
|
||||||
<text class="text-[60rpx] ">{{ t('currency') }}</text>
|
<text class="text-[54rpx] font-bold leading-[76rpx] ">{{ t('currency') }}</text>
|
||||||
<input type="digit" class="h-[70rpx] leading-[70rpx] pl-[10rpx] flex-1 font-bold text-[60rpx]" v-model="applyData.apply_money" />
|
<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"
|
<image @click="clearMoney" v-if="applyData.apply_money"
|
||||||
:src="img('static/resource/images/member/apply_withdrawal/close.png')" class="w-[40rpx] h-[40rpx]"
|
:src="img('static/resource/images/member/apply_withdrawal/close.png')" class="w-[40rpx] h-[40rpx]"
|
||||||
mode="widthFix" />
|
mode="widthFix" />
|
||||||
</view>
|
</view>
|
||||||
<view class="pt-[20rpx]">
|
<view class="pt-[18rpx] flex items-center justify-between mb-[20rpx]">
|
||||||
<text class="text-gray-400 text-[28rpx]">{{t('money')}}:{{ t('currency') }}{{ moneyFormat(cashOutMoney) }}</text>
|
<view class="text-[26rpx] text-[#666] leading-[36rpx]">
|
||||||
<text class="pl-[10rpx] text-[28rpx] text-primary" @click="allMoney">{{t('allTx')}}</text>
|
<text>{{t('money')}}:{{ t('currency') }}{{ moneyFormat(cashOutMoney) }}</text>
|
||||||
</view>
|
<text>,{{t('commissionTo')}}{{ config.rate + '%' }}</text>
|
||||||
<view>
|
</view>
|
||||||
<text class="text-[24rpx] text-gray-400">{{t('minWithdrawal')}}{{ t('currency') }}{{ moneyFormat(config.min) }}</text>
|
<view class="text-[26rpx] text-primary leading-[36rpx]" @click="allMoney">{{t('allTx')}}</view>
|
||||||
<text class="text-[24rpx] text-gray-400">,{{t('commissionTo')}}{{ config.rate + '%' }}</text>
|
</view>
|
||||||
</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('wechat') && 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 class="flex-1 px-[20rpx]">
|
<view>
|
||||||
<view>{{ t('cashOutToWechat') }}</view>
|
<image class="h-[60rpx] w-[60rpx]" :src="img('static/resource/images/member/apply_withdrawal/wechat.png')" mode="widthFix" />
|
||||||
<view class="text-[#bbb] text-[26rpx] mt-[16rpx]">{{ t('cashOutToWechatTips') }}</view>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="flex items-center" @click="applyData.transfer_type = 'wechat'">
|
<view class="flex-1 px-[20rpx]">
|
||||||
<text class="iconfont iconduigou text-[40rpx] text-primary" v-if="applyData.transfer_type == 'wechat'"></text>
|
<view class="text-[28rpx] text-[#333] leading-[40rpx] mb-[6rpx]">{{ t('cashOutToWechat') }}</view>
|
||||||
<text class="iconfont iconcheckbox_nol text-[40rpx] text-[#bbb]" v-else></text>
|
<view class="text-[#999] text-[24rpx] leading-[34rpx]">{{ t('cashOutToWechatTips') }}</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 提现到支付宝 -->
|
<!-- 提现到支付宝 -->
|
||||||
<view class="py-[30rpx] flex" v-if="config.transfer_type.includes('alipay')">
|
<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><text class="iconfont iconzhifubaoxuanzhong text-[#188dfb] text-[70rpx]"></text></view>
|
<view @click="transferAlipay" >
|
||||||
<view class="flex-1 px-[20rpx]">
|
<image class="h-[60rpx] w-[60rpx] align-middle" :src="img('static/resource/images/member/apply_withdrawal/alipay-icon.png')" mode="widthFix" />
|
||||||
<view>{{ t('cashOutToAlipay') }}</view>
|
|
||||||
<view class="text-[#bbb] text-[26rpx] mt-[16rpx]">
|
|
||||||
<view v-if="alipayAccountInfo">
|
|
||||||
{{ t('cashOutTo') }}{{ t('alipayAccountNo') }}{{ alipayAccountInfo.account_no }} <text class="text-black" @click="redirect({ url: '/app/pages/member/account', param: { type: 'alipay', mode: 'select' } })">{{ t('replace') }}</text>
|
|
||||||
</view>
|
|
||||||
<view v-else>
|
|
||||||
{{ t('cashOutToAlipayTips') }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="flex items-center">
|
<view class="flex-1 px-[22rpx]" @click="transferAlipay" >
|
||||||
<u-button :plain="true" type="primary" shape="circle" :custom-style="{height: '56rpx'}" v-if="!alipayAccountInfo" @click="redirect({ url: '/app/pages/member/account', param: { type: 'alipay', mode: 'select' } })">{{ t('toAdd') }}</u-button>
|
<view class="text-[28rpx] text-[#333] leading-[40rpx] mb-[6rpx]">{{ t('cashOutToAlipay') }}</view>
|
||||||
<view v-else @click="applyData.transfer_type = 'alipay'">
|
<view class="text-[#999] text-[24rpx] leading-[34rpx]">
|
||||||
<text class="iconfont iconduigou text-[40rpx] text-primary" v-if="applyData.transfer_type == 'alipay'"></text>
|
<view v-if="alipayAccountInfo" class="truncate max-w-[440rpx]">
|
||||||
<text class="iconfont iconcheckbox_nol text-[40rpx] text-[#bbb]" v-else></text>
|
<text>{{ t('cashOutTo') }}{{ t('alipayAccountNo') }}</text>
|
||||||
</view>
|
<text class="text-[#333]">{{ alipayAccountInfo.account_no }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
<view v-else>{{ t('cashOutToAlipayTips') }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="flex items-center">
|
||||||
|
<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="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 class="w-[70rpx] flex justify-center">
|
<view @click="transferBank" >
|
||||||
<image
|
<image class="h-[42rpx] w-[60rpx] align-middle" :src="img('static/resource/images/member/apply_withdrawal/bank-icon.png')" mode="widthFix" />
|
||||||
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAACnVJREFUeF7tWXtQVNcZ/91FQQZZdhcXfKCCqFXQuKBV0YSHqWJ9AbU+qkZQG+uEyu66i0maB5jEaSetBdvG1vrCRhM1bQS1SUw6gn0kJhkDpqLNQ10jLApEHmrCuuyeznfWRZZd3L03/MOw38zOPfee8517vt/5fY9zV0AfF6GP2w8/AH4G9HEE/C7QxwngD4J+F/C7QB9HwO8CfZwA/iwgyQWuQznBBmGxAKGdwd4u41e0070Ndhtd7z2zUT+DYKN7GWzt14PDAtZOXfIjgLULYNaziuGfQ0A73QPMxtt2wdGG0H6vzwaB2kI7omyjoMZkMFgRav8MTGZFP+Eu7PZ23gaz8nGMWRHArGABVtht7QiQfY08Q2VXxosGwAzlVkDQAggR6z7bx87EjrEzcKtfkFhVIBjAcAYMZeJ1uYbwDWR4BnmG4s4TiALAjPBfAuwpKSvYFTsVBRPnSFF16ExigFKq8R2vvQmdMVwSAGYoVwHCq1IsqA4bjIXJOWgL6CdFHYhljt3vCWEsDfr8CudUPjOgFqpDArBMyhp2x07F899l96fbgQFS3uxBp/l2AAoL7aIBMEN1GUCMlGXkTsnE0agJUlSBgQCmdKxX2hz3tf4NnfER0S5QA4VGBplbBPV1NTNm58IUovR1uOu4IQC+10MACMJWaA3PigbADOV6QNgpxYKL8gg8Omu9FFWHzlg7MFS6uoumTJaOvE3vSgBAtRvAOinLeH2kBoaEBVJUHTqT7UCodHUXzf7BocjNvS0agFqoPhWAiQMy56HfpAmwXb2Gb0te5/MEps5EYMpMWMrehrXqv24r3ayZhwPRiZIsSNVEISV9mItuVUMDyi5/KX4+AR9Ba5zWVdFrFriOsBg7AigAYlBlBfprJuLb/YfQnJPL5wqvOMYBaExI9QjA7LSfgtKgFCktWIQMTSzONTZAERSEkaFyPs2a995ByYVqcVMK7DfQ5ueLBsAM5QpAOEiKQ9jXXL8p6zG0lb7F2/SMtbTiusI9QZiD5ZiSniduoZ1GN732BBTBQYjZtwum1lZUrVyNSYPU2PLhByg88764ee1sETblH5cAgIpKRy1RPbz8GNe/oRwFe3MLZwOxoq3sbTRlruJ9MkUY7yM5NiwOh9bkISU+CvvLL8BU39rtohUhjvKYrjROE6NG5W9X4eqtVkTv3cUZULliNaLlciS89iqqGurFAWBlkcjPd1Py6gJ1UL3PgKQQ3QbIi7bCeu48GjUp/OXOZ636Z/g99dtMXyEgegQH4bllzyJi41pER8iR87uT3Kh9G9P5ffMdC9Kee4MbfPSpRR3G03Plqh3QLUxE0doUvvOll75AZuwYbvz+i9WoqLmGouQ0mFpb0GyxICYsDJnHy3B0QQYHjNhB7e1VnziYwnAOeqPGE2IPBOAmlGFtEIj3AYqSVxCcvdzF/5WlBzAg44fc/wkM6r+95WUMLNjM3/WDec9gd8mT3GAy6srOdWj5xgLdngpu9PYTlRyIgmXTeTtzWixGquUQsopQYkhH9sNx3CACodnShtJLX/J2+eKlHAiS7PHxvE0xgZ6frq0BY4yDojn4Fw4QGH4PvdGjLz4QgBoo58sgnKAXOYPdne070ar7Bad6ZNNlnhHqozUdAbJOCOdxof1qDZKKTuHj4tU4XV2DklMXsG/jHGw5fIZT3NlOnRDFXSTmZ3tQ/uISKAcGQbFyB67sWYdolTvdSxdmIGPUaO4GmbGjUTAtCfp/VqC48iyY1tCxyS6BUmDLoM0/IpoBZihfAgTOb+duE7UtpW/x9EdUp4B4t+I/HAxyDwKHYsWVwyfwQn1gh6E0B+10yalqaGIiEBMph0Z/gPu5IIC3iSEEFrkLZ4vFAsWf/uCy7oofL0PKsChknSjjbtA5JjgBIBak/vXwfT1mjYH+aZMEAFRUNc0mRTI2tPBJbjiJteo87hT/kRtPwVBevJW3qRYgd3jzZCU+mzQFtMOFhz5A1ZUGlD69iO922UeX+DOif8VLS1D64SUOTPG6VM4UU30LCh9PQtXNeuhOl7usOycuHsXJaWi+a+FpsTNIzizhGiSFi9AZ4rqLmA90ATNUzQDCxIVbx+iVST9BeWSsFFWAEkKSuPqfmHBlzeM8HuS8+06n9wo7oTNsEA3ADaiSbIDIZHv/NXHzDGgOpM84EkTNgHhx53+K+mlRwxG9b5cj8DmFCWugN5SIBqAOKiMDfi1h+ahSDMG81O6PDuTflBmKj3+Cc6ZGnh61CxK4K1AmcAr5OUX+pg0/548o7WnUES5LIrpTcVQyZ67nAokFxEGvvygaADNUbwLIkgJAd5+/KOdTpKcASDGBhHyegiOlx+LjlRipDkXO3Hgog4N4AKRIT7vrzP/7Zs/l+Z0kZ3w8qhod8xA4rtTnjy9DZ3ygH3YbA8xQ1QBwPYn4iMb6qYtxYuh4t9G061QIVZy/1tF3ztTAawK6UlAk4ZXjPV8uTkmDVpPIix+qBokBlPYyRrna1XLXwoshF2HYD70x50HL9giAGeHjANYtbbzh8P30jagNdo+dBEBJXrpLaUysIPoTIwgAhTwImhFqpP3tCDeaAhulSdpd2n2HoaWIlofxe2cf+b2H8jgXOuMO0QDUQrVOAOgbgGgxhagwY/YTHvVyZsVzY8nnnf5P91T8EP0zpsZi/6fVyJgWy098ZGTlisc4EFQBUgokZjhPhalRw3nAI8OJFW4ACJgCrfGsaADqoNrLgDWirQdwZMRD0CU6avuu4qzvie4U8JwVYeeS2NTUihabhZexuoTJKEpO5UYTGFQAUdAjV6C4QFdnGUzGu0R/oBY6Y5Q3G7pxAdX/6EucN2VP/fma+TgYneBRlYoiCoL6vac5A4gRVBJn/eoYrw4pGAovb+N1ABlHtT35PFV1hdNn8DYdjQkYnSaRF0NNbW0cFA/yBnTGpd5scAPgOgZG2BF4w5tid/2pj27A56GDPHYXLk/iRtLOUzVI/p+d5ijSiBWTotW8Tf5PhQ35eFchV6A+chFyAToMdfOBxAidcZs3O9wAMCM8C2CUAkVLc/9gxM2/fyDpOgEZTP5PQiBQ0HPeUxDUJKqBkYz7fGdxRn9KdeQKTr93PvdAf8BuT8amzf/yZoQHAFSE2iZvip763xs8FtnTvbKu+6nHMGCYuArQ82RCA4beisLSwrve7HADoBaqMwLg9vHQ20TUvzV+Fl4ZM8OXoZ7H9NQXYIa/Q2/06VO0CwAM6FcHlVWqBRmPZOPj8OHS1GUAksUdgLp9kSA8D63hRV8W4gLANShSAyBzPX/6Msu9MUMzXf50EaFJHwMZoOkJ+vPXzoXOeNKXBXRlQGCd4wgs6Ri3Kmk5TkWO9uW97mOIAQ/bAbp+N9kGndHo6xSegqDkf4G2jUsG/STLODsg7S8EQIAZEP4MrWGLmPd7LIS+AIIGQJEkZqLOYwseSudfYL8KCav/R+QYs6h51BiMMAxGsKwRKjsdyHyTTv/5+6bgGOX1s7iYyXrjWD8AvXHXenLNfgb0JJq9cS4/A3rjrvXkmv0M6Ek0e+Ncfgb0xl3ryTX7GdCTaPbGufo8A/4PpckqfWjPHTQAAAAASUVORK5CYII="
|
</view>
|
||||||
mode="widthFix" class="w-[60rpx]"></image>
|
<view class="flex-1 px-[20rpx]" @click="transferBank" >
|
||||||
</view>
|
<view class="text-[28rpx] text-[#333] leading-[40rpx] mb-[6rpx]">{{ t('cashOutToBank') }}</view>
|
||||||
<view class="flex-1 px-[20rpx]">
|
<view class="text-[#999] text-[24rpx] leading-[34rpx]">
|
||||||
<view>{{ t('cashOutToBank') }}</view>
|
<view v-if="bankAccountInfo" class="truncate max-w-[440rpx]">
|
||||||
<view class="text-[#bbb] text-[26rpx] mt-[16rpx]">
|
<text>{{ t('cashOutTo') }}{{ bankAccountInfo.bank_name }}{{ t('debitCard') }}</text>
|
||||||
<view v-if="bankAccountInfo">
|
<text class="text-[#333]">{{ bankAccountInfo.account_no.substring(bankAccountInfo.account_no.length - 4) }} </text>
|
||||||
{{ t('cashOutTo') }}{{ bankAccountInfo.bank_name }}{{ t('debitCard') }}{{ bankAccountInfo.account_no.substring(bankAccountInfo.account_no.length - 4) }} <text class="text-black" @click="redirect({ url: '/app/pages/member/account', param: { type: 'bank', mode: 'select' } })">{{ t('replace') }}</text>
|
</view>
|
||||||
</view>
|
<view v-else>
|
||||||
<view v-else>
|
{{ t('cashOutToBankTips') }}
|
||||||
{{ t('cashOutToBankTips') }}
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
<view class="flex items-center">
|
||||||
<view class="flex items-center">
|
<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>
|
||||||
<u-button :plain="true" type="primary" shape="circle" :custom-style="{height: '56rpx'}" v-if="!bankAccountInfo" @click="redirect({ url: '/app/pages/member/account', param: { type: 'bank', mode: 'select' } })">{{ t('toAdd') }}</u-button>
|
<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 v-else @click="applyData.transfer_type = 'bank'">
|
</view>
|
||||||
<text class="iconfont iconduigou text-[40rpx] text-primary" v-if="applyData.transfer_type == 'bank'"></text>
|
</view>
|
||||||
<text class="iconfont iconcheckbox_nol text-[40rpx] text-[#bbb]" v-else></text>
|
</view>
|
||||||
</view>
|
<view class="mt-[100rpx]">
|
||||||
</view>
|
<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>
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="px-[32rpx]">
|
<view class="mt-[40rpx] text-center text-[26rpx] text-primary" @click.stop="redirect({ url: '/app/pages/member/cash_out'})">
|
||||||
<u-button type="primary" shape="circle" :text="t('cashOut')" class="mt-[60rpx] mb-[40rpx]"
|
{{t('cashOutList')}}
|
||||||
:disabled="applyData.apply_money == '' || applyData.apply_money == 0" :loading="loading"
|
</view>
|
||||||
@click="cashOut"></u-button>
|
</view>
|
||||||
</view>
|
</scroll-view>
|
||||||
|
<block v-if="config.is_open == 0 && !pageLoading">
|
||||||
<view class="mt-[40rpx] text-center text-sm" @click="redirect({ url: '/app/pages/member/cash_out'})">
|
<u-empty :text="t('isOpenApply')" :icon="img('static/resource/images/empty.png')"/>
|
||||||
{{t('cashOutList')}}
|
</block>
|
||||||
</view>
|
<u-loading-page :loading="pageLoading" bg-color="#e8e8e8" loading-text=""></u-loading-page>
|
||||||
</view>
|
|
||||||
</scroll-view>
|
|
||||||
<u-loading-page :loading="pageLoading" bg-color="#e8e8e8" loading-text=""></u-loading-page>
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive, watch, computed } from 'vue'
|
import { ref, reactive, watch, computed } from 'vue'
|
||||||
import { t } from '@/locale'
|
import { t } from '@/locale'
|
||||||
import { moneyFormat, redirect, img } from '@/utils/common'
|
import { moneyFormat, redirect, getToken ,img, deepClone } from '@/utils/common'
|
||||||
import useMemberStore from '@/stores/member'
|
import useMemberStore from '@/stores/member'
|
||||||
import { cashOutConfig, cashOutApply, getFirstCashoutAccountInfo, getCashoutAccountInfo } from '@/app/api/member'
|
import { cashOutConfig, cashOutApply, getFirstCashoutAccountInfo, getCashoutAccountInfo } from '@/app/api/member'
|
||||||
import { onLoad } from '@dcloudio/uni-app'
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
@ -126,15 +118,14 @@
|
|||||||
return memberStore.info ? memberStore.info[ applyData.account_type ] : 0
|
return memberStore.info ? memberStore.info[ applyData.account_type ] : 0
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
watch(() => applyData.transfer_type, (nval) => {
|
watch(() => applyData.transfer_type, (nval) => {
|
||||||
switch (nval) {
|
switch (nval) {
|
||||||
case 'bank':
|
case 'bank':
|
||||||
applyData.account_id = bankAccountInfo.value ? bankAccountInfo.value.account_id : 0
|
applyData.account_id = bankAccountInfo.value ? bankAccountInfo.value.account_id : 0
|
||||||
break;
|
break;
|
||||||
case 'alipay':
|
case 'alipay':
|
||||||
applyData.account_id = alipayAccountInfo.value ? alipayAccountInfo.value.account_id : 0
|
applyData.account_id = alipayAccountInfo.value ? alipayAccountInfo.value.account_id : 0
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
applyData.account_id = 0
|
applyData.account_id = 0
|
||||||
}
|
}
|
||||||
@ -153,8 +144,13 @@
|
|||||||
|
|
||||||
onLoad(async (data) => {
|
onLoad(async (data) => {
|
||||||
query = data
|
query = data
|
||||||
|
|
||||||
uni.getStorageSync('cashOutAccountType') && (applyData.account_type = uni.getStorageSync('cashOutAccountType'))
|
uni.getStorageSync('cashOutAccountType') && (applyData.account_type = uni.getStorageSync('cashOutAccountType'))
|
||||||
|
|
||||||
|
if(getToken()){
|
||||||
|
memberStore.getMemberInfo()
|
||||||
|
}
|
||||||
|
|
||||||
if (!['money', 'commission'].includes(applyData.account_type)) {
|
if (!['money', 'commission'].includes(applyData.account_type)) {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: t('abnormalOperation'),
|
title: t('abnormalOperation'),
|
||||||
@ -168,20 +164,23 @@
|
|||||||
|
|
||||||
// 提现配置
|
// 提现配置
|
||||||
await cashOutConfig().then((res : any) => {
|
await cashOutConfig().then((res : any) => {
|
||||||
for (let key in res.data) {
|
for (let key in deepClone(res.data)) {
|
||||||
config[key] = res.data[key];
|
config[key] = deepClone(res.data[key]);
|
||||||
}
|
}
|
||||||
if (config.transfer_type.includes('wechat') && memberStore.info && (!memberStore.info.wx_openid && !memberStore.info.weapp_openid)) config.transfer_type.splice(0, 1)
|
if (config.transfer_type.includes('wechatpay') && memberStore.info && (!memberStore.info.wx_openid && !memberStore.info.weapp_openid)) config.transfer_type.splice(config.transfer_type.indexOf('wechatpay'),1)
|
||||||
config.transfer_type.includes('bank') && getBankAccountInfo()
|
config.transfer_type.includes('bank') && getBankAccountInfo()
|
||||||
config.transfer_type.includes('alipay') && getAlipayAccountInfo()
|
config.transfer_type.includes('alipay') && getAlipayAccountInfo()
|
||||||
applyData.transfer_type = config.transfer_type[0]
|
applyData.transfer_type = config.transfer_type[0]
|
||||||
|
if(query.type){
|
||||||
|
applyData.transfer_type = query.type
|
||||||
|
}
|
||||||
pageLoading.value = false
|
pageLoading.value = false
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
//全部提现
|
//全部提现
|
||||||
const allMoney = () => {
|
const allMoney = () => {
|
||||||
applyData.apply_money = moneyFormat(cashOutMoney)
|
if(parseFloat(cashOutMoney.value)) applyData.apply_money = moneyFormat(cashOutMoney.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清空提现金额
|
// 清空提现金额
|
||||||
@ -216,8 +215,9 @@
|
|||||||
/**
|
/**
|
||||||
* 获取支付宝提现账号信息
|
* 获取支付宝提现账号信息
|
||||||
*/
|
*/
|
||||||
const alipayAccountInfo = ref(null)
|
const alipayLoading = ref(false)
|
||||||
const getAlipayAccountInfo = () => {
|
const alipayAccountInfo:any = ref(null)
|
||||||
|
const getAlipayAccountInfo = () => {
|
||||||
const data = { account_type: 'alipay', account_id: 0 }
|
const data = { account_type: 'alipay', account_id: 0 }
|
||||||
let request = getFirstCashoutAccountInfo
|
let request = getFirstCashoutAccountInfo
|
||||||
|
|
||||||
@ -225,15 +225,23 @@
|
|||||||
request = getCashoutAccountInfo
|
request = getCashoutAccountInfo
|
||||||
data.account_id = query.account_id
|
data.account_id = query.account_id
|
||||||
}
|
}
|
||||||
|
alipayLoading.value = true
|
||||||
request(data).then(res => {
|
request(data).then(res => {
|
||||||
if (res.data && res.data.account_id) alipayAccountInfo.value = res.data
|
if (res.data && res.data.account_id) {
|
||||||
|
alipayAccountInfo.value = res.data
|
||||||
|
// 初始化赋值
|
||||||
|
if(applyData.transfer_type == 'alipay' && !applyData.account_id){
|
||||||
|
applyData.account_id = alipayAccountInfo.value.account_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
alipayLoading.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取银行卡提现账号信息
|
* 获取银行卡提现账号信息
|
||||||
*/
|
*/
|
||||||
|
const bankLoading = ref(false)
|
||||||
const bankAccountInfo = ref(null)
|
const bankAccountInfo = ref(null)
|
||||||
const getBankAccountInfo = () => {
|
const getBankAccountInfo = () => {
|
||||||
const data = { account_type: 'bank', account_id: 0 }
|
const data = { account_type: 'bank', account_id: 0 }
|
||||||
@ -243,8 +251,16 @@
|
|||||||
request = getCashoutAccountInfo
|
request = getCashoutAccountInfo
|
||||||
data.account_id = query.account_id
|
data.account_id = query.account_id
|
||||||
}
|
}
|
||||||
|
bankLoading.value = true
|
||||||
request(data).then(res => {
|
request(data).then(res => {
|
||||||
if (res.data && res.data.account_id) bankAccountInfo.value = res.data
|
if (res.data && res.data.account_id) {
|
||||||
|
bankAccountInfo.value = res.data
|
||||||
|
// 初始化赋值
|
||||||
|
if(applyData.transfer_type == 'bank' && !applyData.account_id){
|
||||||
|
applyData.account_id = bankAccountInfo.value.account_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bankLoading.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,16 +272,38 @@
|
|||||||
if (loading.value) return
|
if (loading.value) return
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
||||||
cashOutApply(applyData)
|
cashOutApply(applyData).then(res => {
|
||||||
.then(res => {
|
loading.value = false
|
||||||
redirect({ url: '/app/pages/member/cash_out' })
|
redirect({ url: '/app/pages/member/cash_out' })
|
||||||
})
|
}).catch(() => {
|
||||||
.catch(() => {
|
loading.value = false
|
||||||
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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
:deep(.apply-price){
|
||||||
|
color:#999;
|
||||||
|
font-size: 26rpx;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 76rpx;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,89 +1,229 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :style="themeColor()">
|
<view class="min-h-[100vh] !bg-[#F6F6F6]" :style="themeColor()" v-if="memberStore.info">
|
||||||
<u-loading-page :loading="loading" loadingText=""></u-loading-page>
|
<view class="fixed w-full z-2 !bg-[#F6F6F6]">
|
||||||
<view class="account-info-wrap" v-show="!loading">
|
<view class="pb-[203rpx] text-[#fff] w-full" :style="headerStyle">
|
||||||
<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%)'}">
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
<view class="name">{{t('balanceInfo')}}</view>
|
<top-tabbar :data="param" titleColor="#fff" class="top-header"/>
|
||||||
<view class="content">
|
<!-- #endif -->
|
||||||
<view class="money">
|
<view class="leading-[39rpx] text-[28rpx] pl-[53rpx] pt-[79rpx]">{{t('accountBalance')}}</view>
|
||||||
{{ memberStore.info ? moneyFormat((parseFloat(memberStore.info.balance) + parseFloat(memberStore.info.money)).toString()) : '0.00' }}
|
<view class="flex items-baseline pl-[53rpx]">
|
||||||
</view>
|
<text class="text-[40rpx] leading-[56rpx]">¥</text>
|
||||||
<view class="text">{{t('accountBalance')}}</view>
|
<text class="text-[70rpx] leading-[98rpx]">{{ memberStore.info ? moneyFormat((parseFloat(memberStore.info.balance) + parseFloat(memberStore.info.money)).toString()) : '0.00' }}</text>
|
||||||
<view class="money-wrap">
|
</view>
|
||||||
<view class="money-item" @click="redirect({ url: '/app/pages/member/detailed_account', param: { type : 'balance' } })">
|
</view>
|
||||||
<view class="money">
|
<view class="mx-[30rpx] py-[30rpx] bg-[#fff] rounded-[16rpx] px-[40rpx] box-border w-[calc(100% - 60rpx)] mt-[-112rpx]">
|
||||||
{{ moneyFormat(memberStore.info?.balance)|| '0.00' }}
|
<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>
|
<view class=" text-[#999] text-[24rpx] leading-[34rpx] font-400">{{t('money')}}</view>
|
||||||
<view class="text leading-none">{{ t('balance') }}</view>
|
<view class="flex items-baseline text-[#333]">
|
||||||
</view>
|
<text class="text-[26rpx] leading-[36rpx]">¥</text>
|
||||||
<view class="money-item" @click="redirect({ url: '/app/pages/member/detailed_account', param: { type : 'money' } })">
|
<text class="text-[44rpx] leading-[62rpx] font-bold">{{ moneyFormat(memberStore.info?.money)|| '0.00' }}</text>
|
||||||
<view class="money">
|
</view>
|
||||||
{{ moneyFormat(memberStore.info?.money)|| '0.00' }}
|
|
||||||
</view>
|
|
||||||
<view class="text leading-none">{{ t('money') }}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="account-info-btn">
|
</view>
|
||||||
<u-button type="primary" shape="circle" class="btn"
|
<view class="mt-[50rpx] flex justify-between" v-if="Object.keys(cashOutConfigObj).length && (systemStore.siteAddons.includes('recharge') || cashOutConfigObj.is_open == 1)">
|
||||||
:customStyle="{backgroundColor: '#FE4E50',color: '#fff', borderColor: '#FE4E50',width: 'calc(100vw - 64rpx)'}"
|
<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')"
|
||||||
v-if="systemStore.siteAddons.includes('recharge')"
|
@click="redirect({url: '/addon/recharge/pages/recharge'})">充值</button>
|
||||||
@click="redirect({url: '/addon/recharge/pages/recharge'})">
|
<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"
|
||||||
<image class="max-w-[36rpx] max-h-[36rpx] mr-1" :src="img('static/resource/images/member/reset.png')" />
|
style="background: linear-gradient( 94deg, #FB7939 0%, #FE120E 99%), #EF000C;" shape="circle" @click="applyCashOut">{{t('cashOut')}}</view>
|
||||||
<text>{{t('recharge')}}</text>
|
</view>
|
||||||
</u-button>
|
</view>
|
||||||
<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">
|
<view class=" box-border px-[30rpx] w-full mt-[20rpx]">
|
||||||
<image class="max-w-[36rpx] max-h-[36rpx] mr-1" :src="img('static/resource/images/member/withdraw_deposit.png')" />
|
<scroll-view :scroll-x="true" scroll-with-animation :scroll-into-view="'id' + (subActive>3 ? subActive - 2 : 0)" class="!h-[100%]">
|
||||||
<text>{{t('cashOut')}}</text>
|
<view class="flex whitespace-nowrap">
|
||||||
</u-button>
|
<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>
|
</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>0}">
|
||||||
|
<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>
|
||||||
|
|
||||||
<pay ref="payRef" @close="rechargeLoading = false"></pay>
|
</mescroll-body>
|
||||||
</view>
|
<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>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive } from 'vue'
|
import { ref, reactive,computed } from 'vue'
|
||||||
import { t } from '@/locale'
|
import { t } from '@/locale'
|
||||||
import { moneyFormat, redirect, img } from '@/utils/common';
|
import { moneyFormat, redirect, img } from '@/utils/common';
|
||||||
import { cashOutConfig } from '@/app/api/member';
|
import { cashOutConfig,getBalanceListAll } from '@/app/api/member';
|
||||||
import { onShow } from '@dcloudio/uni-app';
|
import MescrollBody from '@/components/mescroll/mescroll-body/mescroll-body.vue';
|
||||||
|
import MescrollEmpty from '@/components/mescroll/mescroll-empty/mescroll-empty.vue';
|
||||||
|
import useMescroll from '@/components/mescroll/hooks/useMescroll.js';
|
||||||
|
import { onLoad,onShow, onPageScroll, onReachBottom } from '@dcloudio/uni-app';
|
||||||
import useMemberStore from '@/stores/member'
|
import useMemberStore from '@/stores/member'
|
||||||
import useSystemStore from '@/stores/system'
|
import useSystemStore from '@/stores/system'
|
||||||
|
|
||||||
const memberStore = useMemberStore(),
|
const { downCallback,mescrollInit, getMescroll } = useMescroll(onPageScroll, onReachBottom);
|
||||||
systemStore = useSystemStore()
|
const memberStore = useMemberStore()
|
||||||
|
const systemStore = useSystemStore()
|
||||||
|
let param = ref({
|
||||||
const cashOutConfigObj = reactive({
|
title:'我的余额',
|
||||||
is_auto_transfer: 0, // 是否自动转账
|
topStatusBar: {
|
||||||
is_auto_verify: 0, // 是否自动审核
|
style: 'style-1',
|
||||||
is_open: 0, // 是否启用提现
|
isTransparent: true,
|
||||||
min: 0, // 最低提现金额
|
bgColor: 'transparent',
|
||||||
rate: 0, // 手续费比率
|
textColor: '#fff'
|
||||||
transfer_type: [] // 提现方式
|
}
|
||||||
})
|
})
|
||||||
|
const cashOutConfigObj = reactive({})
|
||||||
const loading = ref(true);
|
|
||||||
|
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
cashOutConfig().then((res) => {
|
cashOutConfig().then((res) => {
|
||||||
for (let key in res.data) {
|
for (let key in res.data) {
|
||||||
cashOutConfigObj[key] = res.data[key];
|
cashOutConfigObj[key] = res.data[key];
|
||||||
}
|
}
|
||||||
loading.value = false;
|
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取系统状态栏的高度
|
||||||
|
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'
|
||||||
|
})
|
||||||
|
|
||||||
|
// px转rpx
|
||||||
|
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 = () => {
|
const applyCashOut = () => {
|
||||||
uni.setStorageSync('cashOutAccountType', 'money')
|
uni.setStorageSync('cashOutAccountType', 'money')
|
||||||
redirect({ url: '/app/pages/member/apply_cash_out' })
|
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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<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>
|
</style>
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
{{ item.status_name }}
|
{{ item.status_name }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<mescroll-empty v-if="!cashOutList.length && loading" :option="{tip : (account_type == 'commission' ? t('commissemptyTip') : t('emptyTip') )}"></mescroll-empty>
|
<mescroll-empty v-if="!cashOutList.length && loading" :option="{tip : t('emptyTip')}"></mescroll-empty>
|
||||||
</mescroll-body>
|
</mescroll-body>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -1,48 +1,51 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="member-record-detail" :style="themeColor()">
|
<view class="member-record-detail" :style="themeColor()">
|
||||||
<view class="money-wrap">
|
<block v-if="!loading">
|
||||||
<text>-{{ cashOutInfo.apply_money }}</text>
|
<view class="money-wrap">
|
||||||
<text>{{ cashOutInfo.status_name }}</text>
|
<text>-{{ cashOutInfo.apply_money }}</text>
|
||||||
</view>
|
<text>{{ cashOutInfo.status_name }}</text>
|
||||||
<!-- 状态0待审核1.待转账2已转账 -1拒绝' -->
|
|
||||||
<view class="item">
|
|
||||||
<view class="line-wrap">
|
|
||||||
<text class="label">{{t('cashOutNo')}}</text>
|
|
||||||
<text class="value">{{ cashOutInfo.cash_out_no }}</text>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="line-wrap">
|
<!-- 状态0待审核1.待转账2已转账 -1拒绝' -->
|
||||||
<text class="label">{{t('serviceMoney')}}</text>
|
<view class="item">
|
||||||
<text class="value">¥{{ cashOutInfo.service_money }}</text>
|
<view class="line-wrap">
|
||||||
|
<text class="label w-[200rpx]">{{t('cashOutNo')}}</text>
|
||||||
|
<text class="value">{{ cashOutInfo.cash_out_no }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="line-wrap">
|
||||||
|
<text class="label w-[200rpx]">{{t('serviceMoney')}}</text>
|
||||||
|
<text class="value">¥{{ cashOutInfo.service_money }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="line-wrap">
|
||||||
|
<text class="label w-[200rpx]">{{t('createTime')}}</text>
|
||||||
|
<text class="value">{{ cashOutInfo.create_time }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="line-wrap" v-if="cashOutInfo.status && cashOutInfo.audit_time">
|
||||||
|
<text class="label w-[200rpx]">{{t('auditTime')}}</text>
|
||||||
|
<text class="value">{{ cashOutInfo.audit_time }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="line-wrap" v-if="cashOutInfo.transfer_bank">
|
||||||
|
<text class="label w-[200rpx]">{{t('transferBank')}}</text>
|
||||||
|
<text class="value truncate">{{ cashOutInfo.transfer_bank }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="line-wrap">
|
||||||
|
<text class="label w-[200rpx]">{{t('transferAccount')}}</text>
|
||||||
|
<text class="value truncate">{{ cashOutInfo.transfer_type == 'wechatpay' ? '微信' : cashOutInfo.transfer_account }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="line-wrap" v-if="cashOutInfo.status == -1 && cashOutInfo.refuse_reason">
|
||||||
|
<text class="label w-[200rpx]">{{t('refuseReason')}}</text>
|
||||||
|
<text class="value truncate">{{ cashOutInfo.refuse_reason }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="line-wrap" v-if="cashOutInfo.status == 2">
|
||||||
|
<text class="label w-[200rpx]">{{t('transferTypeName')}}</text>
|
||||||
|
<text class="value truncate">{{ cashOutInfo.transfer_type_name }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="line-wrap" v-if="cashOutInfo.status == 2 && cashOutInfo.transfer_time">
|
||||||
|
<text class="label w-[200rpx]">{{t('transferTime')}}</text>
|
||||||
|
<text class="value truncate">{{ cashOutInfo.transfer_time }}</text>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="line-wrap">
|
</block>
|
||||||
<text class="label">{{t('createTime')}}</text>
|
<u-loading-page bg-color="rgb(248,248,248)" :loading="loading" loadingText="" fontSize="16" color="#303133"></u-loading-page>
|
||||||
<text class="value">{{ cashOutInfo.create_time }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="line-wrap" v-if="cashOutInfo.status">
|
|
||||||
<text class="label">{{t('auditTime')}}</text>
|
|
||||||
<text class="value">{{ cashOutInfo.audit_time }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="line-wrap" v-if="cashOutInfo.transfer_bank">
|
|
||||||
<text class="label">{{t('transferBank')}}</text>
|
|
||||||
<text class="value">{{ cashOutInfo.transfer_bank }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="line-wrap">
|
|
||||||
<text class="label">{{t('transferAccount')}}</text>
|
|
||||||
<text class="value">{{ cashOutInfo.transfer_account }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="line-wrap" v-if="cashOutInfo.status == -1 && cashOutInfo.refuse_reason">
|
|
||||||
<text class="label">{{t('refuseReason')}}</text>
|
|
||||||
<text class="value">{{ cashOutInfo.refuse_reason }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="line-wrap" v-if="cashOutInfo.status == 2">
|
|
||||||
<text class="label">{{t('transferTypeName')}}</text>
|
|
||||||
<text class="value">{{ cashOutInfo.transfer_type_name }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="line-wrap" v-if="cashOutInfo.status == 2">
|
|
||||||
<text class="label">{{t('transferTime')}}</text>
|
|
||||||
<text class="value">{{ cashOutInfo.transfer_time }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -54,20 +57,20 @@ import { redirect, img } from '@/utils/common';
|
|||||||
import { getCashOutDetail } from '@/app/api/member';
|
import { getCashOutDetail } from '@/app/api/member';
|
||||||
|
|
||||||
let cashOutInfo = ref({});
|
let cashOutInfo = ref({});
|
||||||
let loading = ref<boolean>(false);
|
let loading = ref<boolean>(true);
|
||||||
onLoad((option) => {
|
onLoad((option) => {
|
||||||
let id = option.id || "";
|
let id = option.id || "";
|
||||||
getCashoutAccountListFn(id)
|
getCashoutAccountListFn(id)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getCashoutAccountListFn = (id) => {
|
const getCashoutAccountListFn = (id) => {
|
||||||
loading.value = false;
|
loading.value = true;
|
||||||
|
|
||||||
getCashOutDetail(id).then((res) => {
|
getCashOutDetail(id).then((res) => {
|
||||||
cashOutInfo.value = res.data;
|
cashOutInfo.value = res.data;
|
||||||
loading.value = true;
|
loading.value = false;
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = true;
|
loading.value = false;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,51 +1,198 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="account-info-wrap" :style="themeColor()">
|
<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="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="pb-[174rpx]" :style="headerStyle">
|
||||||
<view class="name">{{t('commissionInfo')}}</view>
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
<view class="content">
|
<top-tabbar :data="param" class="top-header"/>
|
||||||
<view class="money" @click="redirect({ url: '/app/pages/member/detailed_account', param: { type : 'commission' } })">
|
<!-- #endif -->
|
||||||
{{ memberStore.info ? moneyFormat(memberStore.info.commission) : 0.00 }}
|
<!-- <view class="pt-[18rpx] pb-[20rpx] pl-[30rpx] flex items-center" v-if="info">
|
||||||
</view>
|
<u-avatar :src="img(info.headimg)" :size="'60rpx'" leftIcon="none"></u-avatar>
|
||||||
<view class="text" @click="redirect({ url: '/app/pages/member/detailed_account', param: { type : 'commission' } })">{{t('accountCommission')}}</view>
|
<view class="ml-[12rpx] mr-[46rpx] text-[32rpx] font-bold text-[#333] leading-[38rpx]">{{info.nickname}}</view>
|
||||||
<view class="money-wrap">
|
<view class="member-level pl-[30rpx] pr-[12rpx] py-[2rpx] font-400 text-[24rpx] text-[#fff] leading-[34rpx] relative">
|
||||||
<view class="money-item">
|
<text>{{ info.member_level_name }}</text>
|
||||||
<view class="money">
|
<image class="h-[40rpx] w-[36rpx] absolute top-0 left-[-20rpx] " :src="img('static/resource/images/member/commission/level_icon.png')" mode="heightFix" />
|
||||||
{{ moneyFormat(memberStore.info?.commission_get)|| '0.00' }}
|
|
||||||
</view>
|
|
||||||
<view class="text">{{ t('commission') }}</view>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="money-item">
|
</view> -->
|
||||||
<view class="money">
|
</view>
|
||||||
{{ moneyFormat(memberStore.info?.commission_cash_outing)|| '0.00' }}
|
<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>
|
||||||
<view class="text">{{ t('money') }}</view>
|
|
||||||
</view>
|
</view>
|
||||||
</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>
|
</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">
|
</mescroll-body>
|
||||||
<u-button type="primary" :plain="true" shape="circle" class="btn" :customStyle="{backgroundColor: '#fff',color: '#FE4E50', borderColor: '#FE4E50',width: 'calc(100vw - 64rpx)'}" @click="applyCashOut">
|
<u-loading-page bg-color="rgb(248,248,248)" :loading="loading" loadingText="" fontSize="16" color="#303133"></u-loading-page>
|
||||||
<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>
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { computed, ref } from 'vue'
|
||||||
import { t } from '@/locale'
|
import { t } from '@/locale'
|
||||||
import { moneyFormat, redirect, img } from '@/utils/common';
|
import { moneyFormat, redirect, img } from '@/utils/common';
|
||||||
import useMemberStore from '@/stores/member'
|
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 memberStore = useMemberStore();
|
||||||
|
const info = computed(() => memberStore.info)
|
||||||
|
// 提现
|
||||||
const applyCashOut = ()=> {
|
const applyCashOut = ()=> {
|
||||||
uni.setStorageSync('cashOutAccountType', 'commission')
|
uni.setStorageSync('cashOutAccountType', 'commission')
|
||||||
redirect({ url: '/app/pages/member/apply_cash_out' })
|
redirect({ url: '/app/pages/member/apply_cash_out' })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let param = ref({
|
||||||
|
title:'我的佣金',
|
||||||
|
topStatusBar: {
|
||||||
|
isTransparent: true,
|
||||||
|
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',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 16为自定头部的padding-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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<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>
|
</style>
|
||||||
|
|||||||
@ -1,162 +1,90 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :style="themeColor()">
|
<view :style="themeColor()">
|
||||||
<u-loading-page :loading="loading" loadingText="" bg-color="#f7f7f7"></u-loading-page>
|
|
||||||
|
|
||||||
<view v-show="!loading">
|
<u-loading-page :loading="diy.getLoading()" loadingText="" bg-color="#f7f7f7" />
|
||||||
<!-- #ifdef MP-WEIXIN -->
|
|
||||||
<top-tabbar v-if="!isShowTopTabbar" :title="data.title" />
|
<view v-show="!diy.getLoading()">
|
||||||
<!-- #endif -->
|
|
||||||
|
|
||||||
<!-- 自定义模板渲染 -->
|
<!-- 自定义模板渲染 -->
|
||||||
<view class="diy-template-wrap bg-index" v-if="data.pageMode != 'fixed'" :style="pageStyle">
|
<view class="diy-template-wrap bg-index" v-if="diy.data.pageMode != 'fixed'" :style="diy.pageStyle()">
|
||||||
|
|
||||||
<diy-group :data="data" :pullDownRefreshCount="pullDownRefreshCount"></diy-group>
|
<diy-group ref="diyGroupRef" :data="diy.data" :pullDownRefreshCount="diy.pullDownRefreshCount" />
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 固定模板渲染 -->
|
<!-- 固定模板渲染 -->
|
||||||
<view class="fixed-template-wrap" v-if="data.pageMode == 'fixed'">
|
<view class="fixed-template-wrap" v-if="diy.data.pageMode == 'fixed'">
|
||||||
|
|
||||||
<fixed-group :data="data" :pullDownRefreshCount="pullDownRefreshCount"></fixed-group>
|
<fixed-group :data="diy.data" :pullDownRefreshCount="diy.pullDownRefreshCount" />
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
|
<!-- 小程序隐私协议 -->
|
||||||
|
<wx-privacy-popup ref="wxPrivacyPopup"></wx-privacy-popup>
|
||||||
|
<!-- #endif -->
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, computed } from 'vue'
|
import {ref, computed} from 'vue';
|
||||||
import { onLoad, onShow, onPullDownRefresh, onPageScroll } from '@dcloudio/uni-app'
|
import {useDiy} from '@/hooks/useDiy'
|
||||||
import { getDiyInfo } from '@/app/api/diy'
|
import {redirect} from '@/utils/common';
|
||||||
import useDiyStore from '@/app/stores/diy'
|
|
||||||
import useMemberStore from '@/stores/member'
|
|
||||||
import { img,redirect } from '@/utils/common';
|
|
||||||
import diyGroup from '@/addon/components/diy/group/index.vue'
|
import diyGroup from '@/addon/components/diy/group/index.vue'
|
||||||
import fixedGroup from '@/addon/components/fixed/group/index.vue'
|
import fixedGroup from '@/addon/components/fixed/group/index.vue'
|
||||||
|
import useMemberStore from '@/stores/member'
|
||||||
|
|
||||||
const loading = ref(true);
|
// 会员信息
|
||||||
const diyStore = useDiyStore();
|
const memberStore = useMemberStore()
|
||||||
const pullDownRefreshCount = ref(0)
|
const userInfo = computed(() => memberStore.info)
|
||||||
let isShowTopTabbar = ref(false);
|
|
||||||
|
|
||||||
const id = ref(0)
|
const diy = useDiy({
|
||||||
const name = ref('DIY_MEMBER_INDEX')
|
name: 'DIY_MEMBER_INDEX'
|
||||||
const template = ref('')
|
})
|
||||||
|
|
||||||
const diyData = reactive({
|
const diyGroupRef = ref(null)
|
||||||
pageMode: 'diy',
|
|
||||||
title: '',
|
|
||||||
global: {},
|
|
||||||
value: []
|
|
||||||
})
|
|
||||||
|
|
||||||
const data = computed(() => {
|
// 监听页面加载
|
||||||
if (diyStore.mode == 'decorate') {
|
diy.onLoad();
|
||||||
return diyStore;
|
|
||||||
} else {
|
|
||||||
return diyData;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
onLoad(option => {
|
// 监听页面显示
|
||||||
// #ifdef H5
|
diy.onShow((data: any) => {
|
||||||
// 装修模式
|
if (data.value) {
|
||||||
diyStore.mode = option.mode || '';
|
// uni.setNavigationBarTitle({
|
||||||
if (diyStore.mode == 'decorate') {
|
// title: diyData.title
|
||||||
loading.value = false;
|
// })
|
||||||
}
|
} else if (data.page) {
|
||||||
// #endif
|
// 跳转到设置的启动页
|
||||||
id.value = option.id || '';
|
redirect({url: data.page, mode: 'reLaunch'})
|
||||||
template.value = option.template || '';
|
|
||||||
});
|
|
||||||
|
|
||||||
onShow(() => {
|
|
||||||
// 装修模式
|
|
||||||
if (diyStore.mode == 'decorate') {
|
|
||||||
diyStore.init();
|
|
||||||
} else {
|
|
||||||
getDiyInfo({
|
|
||||||
id: id.value,
|
|
||||||
name: name.value,
|
|
||||||
template: template.value
|
|
||||||
}).then((res : any) => {
|
|
||||||
let data = res.data;
|
|
||||||
if (data.value) {
|
|
||||||
diyData.pageMode = data.mode;
|
|
||||||
diyData.title = data.title;
|
|
||||||
|
|
||||||
let sources = JSON.parse(data.value);
|
|
||||||
diyData.global = sources.global;
|
|
||||||
diyData.value = sources.value;
|
|
||||||
diyData.value.forEach((item, index) => {
|
|
||||||
item.pageStyle = '';
|
|
||||||
if(item.pageStartBgColor) {
|
|
||||||
if (item.pageStartBgColor && item.pageEndBgColor) item.pageStyle += `background:linear-gradient(${item.pageGradientAngle},${item.pageStartBgColor},${item.pageEndBgColor});`;
|
|
||||||
else item.pageStyle += 'background-color:' + item.pageStartBgColor + ';';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.margin) {
|
|
||||||
item.pageStyle += 'padding-top:' + item.margin.top * 2 + 'rpx' + ';';
|
|
||||||
item.pageStyle += 'padding-bottom:' + item.margin.bottom * 2 + 'rpx' + ';';
|
|
||||||
item.pageStyle += 'padding-right:' + item.margin.both * 2 + 'rpx' + ';';
|
|
||||||
item.pageStyle += 'padding-left:' + item.margin.both * 2 + 'rpx' + ';';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// 控制自定义头部是否出现 | 微信小程序
|
|
||||||
isShowTopTabbar.value = diyData.value.some((item)=>{
|
|
||||||
return item && item.position && item.position == 'top_fixed'
|
|
||||||
})
|
|
||||||
uni.setNavigationBarTitle({
|
|
||||||
title: diyData.global.title
|
|
||||||
})
|
|
||||||
}else if (data.page) {
|
|
||||||
// 跳转到设置的个人中心
|
|
||||||
redirect({ url: data.page })
|
|
||||||
}
|
|
||||||
loading.value = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
useMemberStore().getMemberInfo()
|
|
||||||
});
|
|
||||||
|
|
||||||
const pageStyle = computed(()=>{
|
|
||||||
var style = '';
|
|
||||||
if (data.value.global.pageStartBgColor && data.value.global.pageEndBgColor) style += `background:linear-gradient(${data.value.global.pageGradientAngle},${data.value.global.pageStartBgColor},${data.value.global.pageEndBgColor});`;
|
|
||||||
else style += 'background-color:' + data.value.global.pageStartBgColor + ';';
|
|
||||||
|
|
||||||
style += 'min-height:calc(100vh - 50px);';
|
|
||||||
if(data.value.global.bgUrl) {
|
|
||||||
style += `background-image:url('${ img(data.value.global.bgUrl) }');`;
|
|
||||||
}
|
}
|
||||||
|
diyGroupRef.value?.refresh();
|
||||||
if (data.value.global.bgHeightScale) {
|
if (userInfo.value) {
|
||||||
style += `background-size: 100% ${data.value.global.bgHeightScale}%;`;
|
useMemberStore().getMemberInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
return style;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 监听下拉刷新事件
|
// 监听下拉刷新事件
|
||||||
onPullDownRefresh(() => {
|
diy.onPullDownRefresh()
|
||||||
pullDownRefreshCount.value++;
|
|
||||||
uni.stopPullDownRefresh();
|
|
||||||
})
|
|
||||||
|
|
||||||
onPageScroll((e)=>{
|
// 监听滚动事件
|
||||||
diyStore.scrollTop = e.scrollTop;
|
diy.onPageScroll()
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '@/styles/diy.scss';
|
@import '@/styles/diy.scss';
|
||||||
</style>
|
</style>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.diy-template-wrap {
|
.diy-template-wrap {
|
||||||
::v-deep .diy-group {
|
/* #ifdef MP */
|
||||||
> .draggable-element.top-fixed-diy {
|
.child-diy-template-wrap {
|
||||||
display: none;
|
::v-deep .diy-group {
|
||||||
}
|
> .draggable-element.top-fixed-diy {
|
||||||
}
|
display: block !important;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
326
uni-app/src/app/pages/member/level.vue
Normal file
326
uni-app/src/app/pages/member/level.vue
Normal file
@ -0,0 +1,326 @@
|
|||||||
|
<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=" 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>
|
||||||
|
<view class="pt-[40rpx] mb-[20rpx]">
|
||||||
|
<!-- 轮播图 -->
|
||||||
|
<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-[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 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="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="currLevelInfo.level_style.level_color" backgroundColor="#fff" stroke-width="6" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="relatvie h-full w-full">
|
||||||
|
<image class="h-full w-full" :src="img(item.level_bg)" mode="aspectFit" :class="{'swiper-animation': swiperIndex != index}" :show-menu-by-longpress="true"/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</swiper-item>
|
||||||
|
</swiper>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<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>
|
||||||
|
<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="text-[rgba(255,255,255,0.9)] mt-[10rpx] text-[24rpx]">{{item.title}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<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-[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="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-[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 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>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<u-empty v-if="!loading && (!list || !list.length)" :icon="img('static/resource/images/empty.png')" text="暂无会员等级" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive, computed } from 'vue'
|
||||||
|
import { onLoad, onShow } from '@dcloudio/uni-app'
|
||||||
|
import { getMemberLevel, getTaskGrowth } from '@/app/api/member';
|
||||||
|
import { img,redirect, deepClone, getToken } from '@/utils/common';
|
||||||
|
import useMemberStore from '@/stores/member'
|
||||||
|
|
||||||
|
const memberStore = useMemberStore()
|
||||||
|
|
||||||
|
let loading = ref(false)
|
||||||
|
let list = ref([]) // 会员等级
|
||||||
|
let upgradeSkills = ref([]) // 升级技巧
|
||||||
|
const swiperIndex = ref(0); //当前滑块的索引
|
||||||
|
const levelIndex = ref(0); //当前等级的索引
|
||||||
|
// 自定义头部
|
||||||
|
let topTabbarData = ref({
|
||||||
|
title: '会员等级',
|
||||||
|
topStatusBar: {
|
||||||
|
isTransparent: true,
|
||||||
|
style: 'style-1',
|
||||||
|
bgColor: 'transparent',
|
||||||
|
textColor: '#fff'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
// 判断是否已登录
|
||||||
|
if (getToken()) {
|
||||||
|
getTaskGrowthFn();
|
||||||
|
getMemberLevelFn();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 会员信息
|
||||||
|
const memberInfo = computed(() => {
|
||||||
|
return memberStore.info
|
||||||
|
})
|
||||||
|
|
||||||
|
// 进度条值
|
||||||
|
let progress = (index:any) => {
|
||||||
|
let indent = index;
|
||||||
|
let num = 100
|
||||||
|
if(list.value[indent] && list.value[indent].growth) {
|
||||||
|
num = memberInfo.value.growth / list.value[indent].growth * 100
|
||||||
|
}
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
|
||||||
|
// 所需的成长值
|
||||||
|
let upgradeGrowth = (index:any) => {
|
||||||
|
let indent = index;
|
||||||
|
let num = 0;
|
||||||
|
if(list.value[indent] && list.value[indent].growth) {
|
||||||
|
num = list.value[indent].growth - memberInfo.value.growth;
|
||||||
|
}
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
const levelStyle = ref(''); // 等级样式
|
||||||
|
const maxWidth = ref(''); // 等级样式
|
||||||
|
const lineStyle = ref(''); // 线样式
|
||||||
|
const getMemberLevelFn = ()=>{
|
||||||
|
loading.value = true;
|
||||||
|
|
||||||
|
getMemberLevel().then((res) => {
|
||||||
|
list.value = res.data || [];
|
||||||
|
|
||||||
|
// 初始化会员等级数据
|
||||||
|
let bool = true;
|
||||||
|
if(memberInfo.value && list.value && list.value.length){
|
||||||
|
list.value.forEach((item,index)=>{
|
||||||
|
if(item.level_id == memberInfo.value.member_level){
|
||||||
|
bool = false;
|
||||||
|
swiperIndex.value = index;
|
||||||
|
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:460rpx;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;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getTaskGrowthFn = ()=>{
|
||||||
|
getTaskGrowth().then((res) => {
|
||||||
|
upgradeSkills.value = res.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const swiperChange = (e) => {
|
||||||
|
swiperIndex.value = e.detail.current;
|
||||||
|
levelIndex.value = swiperIndex.value
|
||||||
|
infoStructureFn(e.detail.current);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 当前的会员等级信息
|
||||||
|
let currLevelInfo = ref<any>({});
|
||||||
|
let infoStructureFn = (index:number)=>{
|
||||||
|
let data:any = deepClone(list.value[index]);
|
||||||
|
// 会员权益
|
||||||
|
if(data && data.level_benefits){
|
||||||
|
data.benefits_arr = [];
|
||||||
|
Object.values(data.level_benefits).forEach((item,index,Array)=>{
|
||||||
|
if(item.content){
|
||||||
|
data.benefits_arr.push(item.content)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 升级礼包
|
||||||
|
if(data && data.level_gifts){
|
||||||
|
data.gifts_arr = [];
|
||||||
|
for(let key in data.level_gifts){
|
||||||
|
if(data.level_gifts[key].content){
|
||||||
|
// 增加类型
|
||||||
|
data.level_gifts[key].content.forEach((item,index,Array)=>{
|
||||||
|
Array[index].type = key
|
||||||
|
})
|
||||||
|
data.gifts_arr = data.gifts_arr.concat(data.level_gifts[key].content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currLevelInfo.value = data;
|
||||||
|
}
|
||||||
|
// 改变会员等级
|
||||||
|
const changeLevel = (index : any) =>{
|
||||||
|
levelIndex.value = index;
|
||||||
|
swiperIndex.value = index;
|
||||||
|
infoStructureFn(index);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.skill-btn{
|
||||||
|
padding: 0 20rpx;
|
||||||
|
height: 54rpx;
|
||||||
|
line-height: 56rpx;
|
||||||
|
color: #333;
|
||||||
|
background: linear-gradient( 180deg, #FEE8AC 0%, #F5D36E 85%);
|
||||||
|
border-radius: 30rpx;
|
||||||
|
margin-left: auto;
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
.swiper-animation{
|
||||||
|
transform: scale(0.92, 0.92);
|
||||||
|
transition-duration: 0.3s;
|
||||||
|
transition-timing-function: ease;
|
||||||
|
}
|
||||||
|
:deep(.uni-progress) .uni-progress-bar, :deep(.uni-progress) .uni-progress-inner-bar{
|
||||||
|
border-radius: 10rpx;
|
||||||
|
}
|
||||||
|
.tab-bar {
|
||||||
|
padding-bottom: constant(safe-area-inset-bottom);
|
||||||
|
padding-bottom: env(safe-area-inset-bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.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>
|
||||||
@ -6,8 +6,7 @@
|
|||||||
</view> -->
|
</view> -->
|
||||||
<view class="h-[30rpx]"></view>
|
<view class="h-[30rpx]"></view>
|
||||||
<view class="m-[30rpx] mt-0 p-[30rpx] pt-[10rpx] rounded-md bg-white">
|
<view class="m-[30rpx] mt-0 p-[30rpx] pt-[10rpx] rounded-md bg-white">
|
||||||
<u-form labelPosition="left" :model="formData" labelWidth="200rpx" errorType='toast' :rules="rules"
|
<u-form labelPosition="left" :model="formData" labelWidth="200rpx" errorType='toast' :rules="rules" ref="formRef">
|
||||||
ref="formRef">
|
|
||||||
<view class="mt-[10rpx]">
|
<view class="mt-[10rpx]">
|
||||||
<u-form-item :label="t('name')" prop="name" :border-bottom="true">
|
<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 v-model.trim="formData.name" border="none" clearable maxlength="25" :placeholder="t('namePlaceholder')"/>
|
||||||
@ -33,15 +32,20 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="mt-[10rpx]">
|
<view class="mt-[10rpx]">
|
||||||
<u-form-item :label="t('defaultAddress')" prop="name" :border-bottom="true" >
|
<u-form-item :label="t('defaultAddress')" prop="name" :border-bottom="true" >
|
||||||
<u-switch v-model="formData.is_default" size="20" :activeValue="1" :inactiveValue="0"></u-switch>
|
<u-switch v-model="formData.is_default" size="20" :activeValue="1" :inactiveValue="0" activeColor="var(--primary-color)"/>
|
||||||
</u-form-item>
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-[40rpx]">
|
<view class="mt-[40rpx]">
|
||||||
<u-button type="primary" shape="circle" :text="t('save')" @click="save" :loading="operateLoading"></u-button>
|
<u-button type="primary" shape="circle" :text="t('save')" @click="save" :disabled="btnDisabled" :loading="operateLoading"></u-button>
|
||||||
</view>
|
</view>
|
||||||
</u-form>
|
</u-form>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
|
|
||||||
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
|
<!-- 小程序隐私协议 -->
|
||||||
|
<wx-privacy-popup ref="wxPrivacyPopup"></wx-privacy-popup>
|
||||||
|
<!-- #endif -->
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -51,34 +55,51 @@
|
|||||||
import { redirect } from '@/utils/common'
|
import { redirect } from '@/utils/common'
|
||||||
import { t } from '@/locale'
|
import { t } from '@/locale'
|
||||||
import { addAddress, editAddress, getAddressInfo } from '@/app/api/member'
|
import { addAddress, editAddress, getAddressInfo } from '@/app/api/member'
|
||||||
|
import manifestJson from '@/manifest.json'
|
||||||
|
import { getAddressByLatlng } from '@/app/api/system'
|
||||||
|
|
||||||
const type = ref('')
|
const type = ref('')
|
||||||
|
const source = ref('')
|
||||||
|
const btnDisabled = ref(false)
|
||||||
|
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
id: 0,
|
id: 0,
|
||||||
name: '',
|
name: '',
|
||||||
mobile: '',
|
mobile: '',
|
||||||
|
province_id: 0,
|
||||||
|
city_id: 0,
|
||||||
|
district_id: 0,
|
||||||
lat: '',
|
lat: '',
|
||||||
lng: '',
|
lng: '',
|
||||||
address: '',
|
address: '',
|
||||||
address_name: '学府街',
|
address_name: '',
|
||||||
full_address: '',
|
full_address: '',
|
||||||
is_default: 0,
|
is_default: 0,
|
||||||
area: '',
|
area: '',
|
||||||
type: 'location_address'
|
type: 'location_address'
|
||||||
})
|
})
|
||||||
|
|
||||||
onLoad((data) => {
|
onLoad((option) => {
|
||||||
if (data.id) {
|
if (option.id) {
|
||||||
getAddressInfo(data.id)
|
getAddressInfo(option.id).then(({data}) => {
|
||||||
.then(({ data }) => {
|
if (data) {
|
||||||
if (data) {
|
Object.assign(formData.value, data)
|
||||||
Object.assign(formData.value, data)
|
formData.value.area = formData.value.full_address.replace(formData.value.address, '').replace(formData.value.address_name, '')
|
||||||
formData.value.area = formData.value.full_address.replace(formData.value.address, '').replace(formData.value.address_name, '')
|
}
|
||||||
}
|
}).catch()
|
||||||
})
|
}else if (option.name) {
|
||||||
.catch()
|
if (uni.getStorageSync('addressInfo')) {
|
||||||
|
Object.assign(formData.value, uni.getStorageSync('addressInfo'))
|
||||||
|
}
|
||||||
|
formData.value.address = option.name;
|
||||||
|
getAddress(option.latng);
|
||||||
|
var tempArr = getQueryVariable('latng').split(',');
|
||||||
|
formData.value.lat = tempArr[0];
|
||||||
|
formData.value.lng = tempArr[1];
|
||||||
}
|
}
|
||||||
type.value = data.type || ''
|
|
||||||
|
type.value = option.type || ''
|
||||||
|
source.value = option.source || ''
|
||||||
})
|
})
|
||||||
|
|
||||||
const formRef = ref(null)
|
const formRef = ref(null)
|
||||||
@ -118,10 +139,45 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取详细地址
|
||||||
|
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 operateLoading = ref(false)
|
const operateLoading = ref(false)
|
||||||
const save = ()=> {
|
const save = ()=> {
|
||||||
if (uni.$u.test.isEmpty(formData.value.area)) {
|
if (uni.$u.test.isEmpty(formData.value.area)) {
|
||||||
uni.showToast({ title: t('selectAddressPlaceholder'), icon: 'none' })
|
uni.showToast({title: t('selectAddressPlaceholder'), icon: 'none'})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,28 +187,60 @@
|
|||||||
if (operateLoading.value) return
|
if (operateLoading.value) return
|
||||||
operateLoading.value = true
|
operateLoading.value = true
|
||||||
|
|
||||||
|
btnDisabled.value = true
|
||||||
|
|
||||||
formData.value.full_address = `${formData.value.area}${formData.value.address_name}${formData.value.address}`
|
formData.value.full_address = `${formData.value.area}${formData.value.address_name}${formData.value.address}`
|
||||||
|
|
||||||
save(formData.value).then((res) => {
|
save(formData.value).then((res) => {
|
||||||
operateLoading.value = false
|
operateLoading.value = false
|
||||||
setTimeout(()=> {
|
uni.removeStorageSync('addressInfo');
|
||||||
redirect({ url: '/app/pages/member/address', param: { type: type.value } })
|
setTimeout(() => {
|
||||||
|
btnDisabled.value = false
|
||||||
|
redirect({
|
||||||
|
url: '/app/pages/member/address',
|
||||||
|
mode: 'redirectTo',
|
||||||
|
param: {type: type.value, source: source.value}
|
||||||
|
})
|
||||||
}, 1000)
|
}, 1000)
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
operateLoading.value = false
|
operateLoading.value = false
|
||||||
|
btnDisabled.value = false
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const chooseLocation = ()=> {
|
const chooseLocation = ()=> {
|
||||||
|
// #ifdef MP
|
||||||
uni.chooseLocation({
|
uni.chooseLocation({
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
res.latitude && (formData.value.lat = res.latitude)
|
res.latitude && (formData.value.lat = res.latitude)
|
||||||
res.longitude && (formData.value.lng = res.longitude)
|
res.longitude && (formData.value.lng = res.longitude)
|
||||||
res.address && (formData.value.area = res.address)
|
res.address && (formData.value.area = res.address)
|
||||||
res.name && (formData.value.address_name = res.name)
|
res.name && (formData.value.address_name = res.name)
|
||||||
}
|
},
|
||||||
|
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 + '?type=' + type.value + '&source=' + source.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
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -21,8 +21,8 @@
|
|||||||
<u-cell :title="t('sex')" :is-link="true" :value="info.sex_name || t('unknown')" @click="sexSheetShow = true"></u-cell>
|
<u-cell :title="t('sex')" :is-link="true" :value="info.sex_name || t('unknown')" @click="sexSheetShow = true"></u-cell>
|
||||||
<u-cell :title="t('mobile')">
|
<u-cell :title="t('mobile')">
|
||||||
<template #value>
|
<template #value>
|
||||||
<view v-if="info.mobile">{{ mobileConceal(info.mobile) }}</view>
|
<view v-if="info.mobile" class="mr-[10rpx]">{{ mobileConceal(info.mobile) }}</view>
|
||||||
<view @click="redirect({ url: '/app/pages/auth/bind' })">
|
<view v-else @click="redirect({ url: '/app/pages/auth/bind' })">
|
||||||
<u-button type="primary" :plain="true" :text="t('bindMobile')" shape="circle" size="mini"></u-button>
|
<u-button type="primary" :plain="true" :text="t('bindMobile')" shape="circle" size="mini"></u-button>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
@ -48,9 +48,10 @@
|
|||||||
:safeAreaInsetBottom="true"
|
:safeAreaInsetBottom="true"
|
||||||
@close="sexSheetShow = false" @select="updateSex"></u-action-sheet>
|
@close="sexSheetShow = false" @select="updateSex"></u-action-sheet>
|
||||||
|
|
||||||
<u-datetime-picker :show="birthdayPicker" mode="date" :confirm-text="t('confirm')"
|
<u-datetime-picker v-model="info.birthday" :show="birthdayPicker" mode="date" :confirm-text="t('confirm')"
|
||||||
:maxDate="new Date().valueOf()" :minDate="0"
|
:maxDate="new Date().valueOf()" :minDate="0"
|
||||||
:cancel-text="t('cancel')" @cancel="birthdayPicker = false" @confirm="updateBirthday"></u-datetime-picker>
|
:cancel-text="t('cancel')" @cancel="birthdayPicker = false" @confirm="updateBirthday"></u-datetime-picker>
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -150,7 +151,7 @@
|
|||||||
field: 'birthday',
|
field: 'birthday',
|
||||||
value: uni.$u.date(e.value, 'yyyy-mm-dd')
|
value: uni.$u.date(e.value, 'yyyy-mm-dd')
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
memberStore.info.birthday = uni.$u.date(e.value||e.value+1, 'yyyy-mm-dd')
|
memberStore.info.birthday = uni.$u.date(e.value || e.value + 1, 'yyyy-mm-dd')
|
||||||
birthdayPicker.value = false
|
birthdayPicker.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,51 +1,177 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="bg-gray-100 min-h-[100vh]" :class="{'bg-[#fff]':!pointList.length}" :style="themeColor()">
|
<view class="bg-[#F6F6F6] min-h-[100vh]" :style="themeColor()">
|
||||||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="getPointListFn">
|
<template v-if="!loading">
|
||||||
<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="w-full bg-[#F6F6F6]">
|
||||||
<view class="text-[14px]">{{item.from_type_name}}</view>
|
<view class="pb-[210rpx] relative" :style="headerStyle">
|
||||||
<view class="text-[12px] text-gray-400 mt-[10px]">{{item.create_time}}</view>
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
<view class="text-[14px] absolute top-[50%] transform -translate-y-[50%] right-[10px]">{{item.account_data}}</view>
|
<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>
|
</view>
|
||||||
<mescroll-empty v-if="!pointList.length && loading"></mescroll-empty>
|
<view class="mx-[30rpx] flex flex-col mt-[-178rpx] relative">
|
||||||
</mescroll-body>
|
<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>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import { onLoad } from '@dcloudio/uni-app'
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
import { t } from '@/locale'
|
import { t } from '@/locale'
|
||||||
import { redirect, img } from '@/utils/common';
|
import { redirect, img } from '@/utils/common';
|
||||||
import { getPointList } from '@/app/api/member';
|
import { getMemberAccountPointcount,getTaskPoint } 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 param = ref({
|
||||||
let mescrollRef = ref(null);
|
title:'我的积分',
|
||||||
let loading = ref<boolean>(false);
|
topStatusBar: {
|
||||||
|
style: 'style-1',
|
||||||
const getPointListFn = (mescroll)=>{
|
isTransparent: true,
|
||||||
let data = ref({});
|
bgColor: 'transparent',
|
||||||
loading.value = false;
|
textColor: '#fff'
|
||||||
data.value.page = mescroll.num;
|
}
|
||||||
data.value.page_size = mescroll.size;
|
})
|
||||||
getPointList(data.value).then((res) => {
|
// 获取系统状态栏的高度
|
||||||
let newArr = res.data.data;
|
let menuButtonInfo:any = {};
|
||||||
mescroll.endSuccess(newArr.length);
|
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API,尚未兼容)
|
||||||
//设置列表数据
|
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
|
||||||
if (mescroll.num == 1){
|
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
||||||
pointList.value = []; //如果是第一页需手动制空列表
|
// #endif
|
||||||
}
|
const headerStyle = computed(()=>{
|
||||||
pointList.value = pointList.value.concat(newArr);
|
return {
|
||||||
loading.value = true;
|
backgroundImage: 'url(' + img('static/resource/images/member/point/point_bg.png') + ') ',
|
||||||
}).catch(()=>{
|
backgroundSize: 'cover',
|
||||||
loading.value = true;
|
backgroundRepeat: 'no-repeat',
|
||||||
mescroll.endErr(); // 请求失败, 结束加载
|
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
|
||||||
|
})
|
||||||
|
// px转rpx
|
||||||
|
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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped>
|
||||||
|
.bg-color{
|
||||||
|
background-color: rgba(102,102,102,0.4);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
53
uni-app/src/app/pages/member/point_detail.vue
Normal file
53
uni-app/src/app/pages/member/point_detail.vue
Normal 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>
|
||||||
@ -1,89 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="member-record-list">
|
|
||||||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="getListFn" top="">
|
|
||||||
<view v-for="(order,index) in list" :key="order.order_id" class="member-record-item"
|
|
||||||
@click="toDetailFn(order)">
|
|
||||||
<view class="name">{{order.item[0].item_name}}</view>
|
|
||||||
<view class="desc">{{order.create_time}}</view>
|
|
||||||
<view class="money text-active">+{{ order.order_money }}</view>
|
|
||||||
<view class="status" v-if="order.order_status_info">{{order.order_status_info.name}}</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<mescroll-empty v-if="!list.length && loading" :option="{tip : t('emptyTip') }"></mescroll-empty>
|
|
||||||
</mescroll-body>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref } from 'vue'
|
|
||||||
import { t } from '@/locale'
|
|
||||||
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 { getRechargeList } from '@/app/api/member';
|
|
||||||
import { redirect } from '@/utils/common'
|
|
||||||
import { onPageScroll, onReachBottom, onLoad } from '@dcloudio/uni-app';
|
|
||||||
const { mescrollInit, downCallback, getMescroll } = useMescroll(onPageScroll, onReachBottom);
|
|
||||||
|
|
||||||
const list = ref<Array<any>>([]),
|
|
||||||
loading = ref<boolean>(false),
|
|
||||||
mescrollRef = ref(null);
|
|
||||||
|
|
||||||
interface mescrollStructure {
|
|
||||||
num : number,
|
|
||||||
size : number,
|
|
||||||
endSuccess : Function,
|
|
||||||
[propName : string] : any
|
|
||||||
}
|
|
||||||
|
|
||||||
const getListFn = (mescroll : mescrollStructure) => {
|
|
||||||
loading.value = false;
|
|
||||||
let data : Object = {
|
|
||||||
page: mescroll.num,
|
|
||||||
page_size: mescroll.size
|
|
||||||
};
|
|
||||||
interface acceptingDataStructure {
|
|
||||||
data : acceptingDataItemStructure,
|
|
||||||
msg : string,
|
|
||||||
code : number
|
|
||||||
}
|
|
||||||
interface acceptingDataItemStructure {
|
|
||||||
data : object,
|
|
||||||
[propName : string] : number | string | object
|
|
||||||
}
|
|
||||||
|
|
||||||
getRechargeList(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);
|
|
||||||
loading.value = true;
|
|
||||||
}).catch(() => {
|
|
||||||
loading.value = true;
|
|
||||||
mescroll.endErr(); // 请求失败, 结束加载
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const toDetailFn = (data) => {
|
|
||||||
redirect({ url: '/app/pages/member/recharge_record_detail', param: { id: data.order_id } });
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
@import '@/styles/member_record_list.scss';
|
|
||||||
|
|
||||||
.member-record-list {
|
|
||||||
.member-record-item {
|
|
||||||
.desc {
|
|
||||||
@apply leading-8 h-8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status {
|
|
||||||
@apply absolute right-3 top-11 text-sm;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="member-record-detail" v-show="loading">
|
|
||||||
<view class="money-wrap">
|
|
||||||
<text>¥{{ rechargeInfo.order_money }}</text>
|
|
||||||
<text v-if="rechargeInfo.order_status_info">{{rechargeInfo.order_status_info.name}}</text>
|
|
||||||
</view>
|
|
||||||
<view class="item">
|
|
||||||
<view class="line-wrap" v-if="rechargeInfo.item">
|
|
||||||
<text class="label">{{ rechargeInfo.item[0].item_name }}</text>
|
|
||||||
<text class="value">¥{{ rechargeInfo.order_money }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="line-wrap">
|
|
||||||
<text class="label">{{t('orderNo')}}</text>
|
|
||||||
<text class="value">{{ rechargeInfo.order_no }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="line-wrap">
|
|
||||||
<text class="label">{{t('createTime')}}</text>
|
|
||||||
<text class="value">{{ rechargeInfo.create_time }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { reactive, ref } from 'vue'
|
|
||||||
import { onLoad } from '@dcloudio/uni-app'
|
|
||||||
import { t } from '@/locale'
|
|
||||||
import { getRechargeDetail } from '@/app/api/member';
|
|
||||||
|
|
||||||
let rechargeInfo = ref({});
|
|
||||||
let loading = ref<boolean>(false);
|
|
||||||
onLoad((option) => {
|
|
||||||
let id = option.id || "";
|
|
||||||
getRechargeDetailFn(id)
|
|
||||||
})
|
|
||||||
|
|
||||||
const getRechargeDetailFn = (id) => {
|
|
||||||
loading.value = false;
|
|
||||||
|
|
||||||
getRechargeDetail(id).then((res) => {
|
|
||||||
rechargeInfo.value = res.data;
|
|
||||||
loading.value = true;
|
|
||||||
}).catch(() => {
|
|
||||||
loading.value = true;
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
@import '@/styles/member_record_detail.scss';
|
|
||||||
</style>
|
|
||||||
484
uni-app/src/app/pages/member/sign_in.vue
Normal file
484
uni-app/src/app/pages/member/sign_in.vue
Normal file
@ -0,0 +1,484 @@
|
|||||||
|
<template>
|
||||||
|
<view :style="themeColor()">
|
||||||
|
<view class="bg-[#F6F6F6] min-h-screen overflow-hidden" v-if="Object.values(info).length">
|
||||||
|
<view v-if="info.is_use">
|
||||||
|
<view class="sigin-header">
|
||||||
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
|
<view class="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 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>
|
||||||
|
<!-- #endif -->
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
<view class="mx-[30rpx] bg-[#fff] rounded-[16rpx] -mt-[85rpx]">
|
||||||
|
<view class="px-[30rpx]">
|
||||||
|
<view class="pt-[32rpx] mb-[40rpx] flex justify-between items-center" v-if="flag" >
|
||||||
|
<view class="flex items-center">
|
||||||
|
<text class="iconfont iconshangyibu text-[#999] text-[24rpx]" @click="changeMonth('prev')"></text>
|
||||||
|
<view class="mx-[30rpx] font-bold text-[32rpx] text-[#333] leading-[38rpx]">{{ state.curYear }}年{{ state.curMonth+1 }}月</view>
|
||||||
|
<text class="iconfont iconxiayibu1 text-[#999] text-[24rpx]" @click="changeMonth('next')"></text>
|
||||||
|
</view>
|
||||||
|
<view class="flex items-center">
|
||||||
|
<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>
|
||||||
|
<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>
|
||||||
|
<view class="flex items-center justify-between text-[#666] text-[26rpx] mb-[14rpx]">
|
||||||
|
<text class="w-[14.2%] leading-[30rpx] text-center">周一</text>
|
||||||
|
<text class="w-[14.2%] leading-[30rpx] text-center">周二</text>
|
||||||
|
<text class="w-[14.2%] leading-[30rpx] text-center">周三</text>
|
||||||
|
<text class="w-[14.2%] leading-[30rpx] text-center">周四</text>
|
||||||
|
<text class="w-[14.2%] leading-[30rpx] text-center">周五</text>
|
||||||
|
<text class="w-[14.2%] leading-[30rpx] text-center">周六</text>
|
||||||
|
<text class="w-[14.2%] leading-[30rpx] text-center">周日</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex flex-wrap items-center justify-start" v-if="!flag">
|
||||||
|
<block v-for="(item,index) in state.weekCount" :key="index">
|
||||||
|
<view class="w-[14.2%] flex flex-col justify-center items-center">
|
||||||
|
<view v-if="filteredDate(item)" class="w-[74rpx] h-[92rpx] bg-[#F2F2F2] text-[#666] border-box py-[10rpx] rounded-[8rpx] flex flex-col items-center" :class="{'sigin-bg !text-[#fff]': isVerDate(item),'bg-[#FDFDFD] border-[1rpx] border-[#E0E0E0] border-solid !text-[#999]': !isVerDate(item) && item < state.curDate && (state.curMonth + 1) == (new Date().getMonth() + 1) ,'mb-[10rpx]':isCurrentDate(item),'mb-[20rpx]':!isCurrentDate(item) }" @click="getDayPackFn(item)">
|
||||||
|
<text class="text-[24rpx] leading-[34rpx] mb-[6rpx]">{{ filteredDate(item) }}</text>
|
||||||
|
<view v-if="filteredDate(item)">
|
||||||
|
<image v-if="isPackDate(item)" :src="img('static/resource/images/app/package.png')" class="w-[40rpx] h-[40rpx]"></image>
|
||||||
|
<image v-else-if="isVerDate(item)" :src="img('static/resource/images/app/hassigin.png')" class="w-[34rpx] h-[34rpx]"></image>
|
||||||
|
<image v-else :src="img('static/resource/images/app/nosigin.png')" class="w-[34rpx] h-[34rpx]"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="w-[10rpx] h-[10rpx] rounded-[50%] bg-[#FF5527]" v-if="isCurrentDate(item)"></view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
<view class="flex flex-wrap items-center justify-start" v-else>
|
||||||
|
<block v-for="(item,index) in state.dataCount" >
|
||||||
|
<view class="w-[14.2%] flex flex-col justify-center items-center mb-[10rpx]">
|
||||||
|
<view v-if="filteredDate(item)" class="w-[74rpx] h-[92rpx] bg-[#F2F2F2] text-[#666] border-box py-[10rpx] rounded-[8rpx] flex flex-col items-center" :class="{'sigin-bg !text-[#fff]': isVerDate(item) && active ,'bg-[#FDFDFD] border-[1rpx] border-[#E0E0E0] border-solid !text-[#999]': !isVerDate(item) && item < state.curDate && (state.curMonth + 1) == (new Date().getMonth() + 1) && state.curYear == new Date().getFullYear() ,'mb-[10rpx]':isCurrentDate(item),'mb-[20rpx]':!isCurrentDate(item)}" @click="getDayPackFn(item)">
|
||||||
|
<text class="text-[24rpx] leading-[34rpx] mb-[6rpx]">{{ filteredDate(item) }}</text>
|
||||||
|
<view v-if="filteredDate(item)">
|
||||||
|
<image v-if="isPackDate(item)" :src="img('static/resource/images/app/package.png')" class="w-[40rpx] h-[40rpx]"></image>
|
||||||
|
<image v-else-if="isVerDate(item) && active " :src="img('static/resource/images/app/hassigin.png')" class="w-[34rpx] h-[34rpx]"></image>
|
||||||
|
<image v-else :src="img('static/resource/images/app/nosigin.png')" class="w-[34rpx] h-[34rpx]"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="w-[10rpx] h-[10rpx] rounded-[50%] bg-[#FF5527]" v-if="isCurrentDate(item)"></view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
<view class="mt-[50rpx] mx-[20rpx] flex justify-center" v-if="state.curMonth + 1 == (new Date().getMonth() + 1) && state.curYear == new Date().getFullYear() ">
|
||||||
|
<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>
|
||||||
|
</view> -->
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="mt-[20rpx] mb-[30rpx] mx-[30rpx] p-[30rpx] bg-[#fff] rounded-[16rpx]">
|
||||||
|
<view class="mb-[30rpx] flex items-center">
|
||||||
|
<view class="font-bold text-[32rpx] text-[#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>
|
||||||
|
</view> -->
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
<view v-for="(item,index) in info.continue_award" :key="index" class="flex items-center mt-[40rpx] border-box">
|
||||||
|
<view class="w-[90rpx] h-[90rpx] rounded-[50%] bg-[#E7F6FF] flex items-center justify-center 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 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 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 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 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-[#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>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="min-h-screen flex flex-col justify-center bg-[#fff]" v-else>
|
||||||
|
<image class="rounded-[8rpx] overflow-hidden mx-auto w-[320rpx] h-[184rpx]" :src="img('static/resource/images/system/empty.png')" model="aspectFill" />
|
||||||
|
<view class="text-[#999] text-[26rpx] font-400 mt-[26rpx] text-center leading-[30rpx]">签到未开启</view>
|
||||||
|
</view>
|
||||||
|
<!-- 签到规则-->
|
||||||
|
<u-popup :show="signPopup" :round="16" mode="bottom" :closeable="true" @close="signPopup = false">
|
||||||
|
<view class="pt-[30rpx] px-[32rpx] pb-[20rpx]">
|
||||||
|
<view class="text-center text-[32rpx] font-700 text-[#323233]">签到规则</view>
|
||||||
|
<scroll-view :scroll-y="true" class="my-[20rpx] h-[360rpx] overflow-auto">
|
||||||
|
<block v-for="(item) in info.rule_explain.split('\n')">
|
||||||
|
<view class="text-[28rpx] leading-[40rpx] mb-[20rpx]">{{ item }}</view>
|
||||||
|
</block>
|
||||||
|
</scroll-view>
|
||||||
|
<view>
|
||||||
|
<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>
|
||||||
|
<!-- 签到奖励 -->
|
||||||
|
<u-popup :show="awardShow" class="award-popup" :customStyle="{backgroundColor:'transparent'}" @close="awardShow = false" mode="center" :round="5" :safeAreaInsetBottom="false" >
|
||||||
|
<view class="w-[550rpx]" v-if="Object.values(signAward).length">
|
||||||
|
<view class="flex justify-center">
|
||||||
|
<image :src="img('static/resource/images/app/award.png')" class="w-[484rpx] h-[480rpx]"></image>
|
||||||
|
</view>
|
||||||
|
<view class="-mt-[265rpx] bg-award rounded-[30rpx] pt-[100rpx] pb-[48rpx] mb-[50rpx] raleative z-10">
|
||||||
|
<view class="px-[32rpx]">
|
||||||
|
<view class="text-[48rpx] text-[#EF000C] font-bold leading-[56rpx] mb-[4rpx] text-center">{{ signAward.title }}</view>
|
||||||
|
<view class="text-[24rpx] text-[#F05F66] leading-[28rpx] text-center mb-[60rpx]">{{ signAward.info }}</view>
|
||||||
|
<view class="px-[68rpx] mb-[54rpx]">
|
||||||
|
<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>
|
||||||
|
<view class="flex justify-center">
|
||||||
|
<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="nc-iconfont nc-icon-cuohaoV6xx text-[#fff] text-[60rpx]" @click="awardShow = false"></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</u-popup>
|
||||||
|
<!-- 查看当日或连续签到奖励 -->
|
||||||
|
<u-popup :show="packShow" class="award-popup" :customStyle="{backgroundColor:'transparent'}" @close="packShow = false" mode="center" :round="5" :safeAreaInsetBottom="false">
|
||||||
|
<view class="w-[550rpx]" v-if="Object.values(packInfo).length">
|
||||||
|
<view class="flex justify-center">
|
||||||
|
<image :src="img('static/resource/images/app/award.png')" class="w-[484rpx] h-[480rpx]"></image>
|
||||||
|
</view>
|
||||||
|
<view class="-mt-[265rpx] bg-award rounded-[30rpx] pt-[100rpx] pb-[48rpx] mb-[50rpx] raleative z-10">
|
||||||
|
<view class="px-[32rpx]">
|
||||||
|
<view class="text-[48rpx] text-[#EF000C] font-bold leading-[56rpx] mb-[4rpx] text-center opacity-60">签到奖励</view>
|
||||||
|
<view class="text-[24rpx] text-[#F05F66] opacity-60 leading-[28rpx] text-center mb-[60rpx]">您将获得以下奖励</view>
|
||||||
|
<view class="px-[68rpx] mb-[54rpx]">
|
||||||
|
<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>
|
||||||
|
<view class="flex justify-center">
|
||||||
|
<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="nc-iconfont nc-icon-cuohaoV6xx text-[#fff] text-[60rpx]" @click="packShow = false"></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</u-popup>
|
||||||
|
</view>
|
||||||
|
<u-loading-page bg-color="rgb(248,248,248)" :loading="loading" loadingText="" fontSize="16" color="#303133"></u-loading-page>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, ref, toRefs, toRaw, computed } from 'vue'
|
||||||
|
import { redirect, img } from '@/utils/common'
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import { getSignInfo,getSignConfig, setSign,getDayPack } from '@/app/api/member'
|
||||||
|
import useMemberStore from '@/stores/member'
|
||||||
|
|
||||||
|
let state = reactive({
|
||||||
|
dataCount:[], //当月所有天数
|
||||||
|
weekCount:[], //如果签到周期是7天
|
||||||
|
curYear:0, // 当前年
|
||||||
|
curMonth:0, //当前月
|
||||||
|
curDate:0, //当前日
|
||||||
|
curWeek:0, //当前星期
|
||||||
|
signInList:[], // 签到列表
|
||||||
|
packList:[] //每个小周期内的礼包
|
||||||
|
})
|
||||||
|
let week = reactive({
|
||||||
|
weekDay:0, //当前天
|
||||||
|
week:0 //当前星期
|
||||||
|
})
|
||||||
|
const loading = ref(false)
|
||||||
|
let flag = ref(false)
|
||||||
|
let info = ref({}) //签到配置
|
||||||
|
let signPopup = ref(false)//签到规则弹框
|
||||||
|
let signAward = ref({}) //当日签到奖励
|
||||||
|
let awardShow = ref(false) // 每日签到弹框
|
||||||
|
let packShow = ref(false) //查看每天礼包
|
||||||
|
let packInfo = ref({}) //礼包奖励
|
||||||
|
let active = ref(false)
|
||||||
|
let currentYear=null
|
||||||
|
let currentMonth=null
|
||||||
|
onLoad(() =>{
|
||||||
|
let date=new Date()
|
||||||
|
state.curYear=date.getFullYear()
|
||||||
|
state.curMonth=date.getMonth()
|
||||||
|
state.curDate=date.getDate()
|
||||||
|
state.curWeek=date.getDay()
|
||||||
|
if(state.curWeek==0) state.curWeek = 7
|
||||||
|
|
||||||
|
currentYear=toRaw(state.curYear)
|
||||||
|
currentMonth=toRaw(state.curMonth)
|
||||||
|
|
||||||
|
//初始化执行
|
||||||
|
getDayCounts()
|
||||||
|
getWeekCounts()
|
||||||
|
getSignInfoFn({year:state.curYear,month:state.curMonth+1})
|
||||||
|
getSignConfigFn()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取签到配置
|
||||||
|
const getSignConfigFn = () =>{
|
||||||
|
loading.value = true
|
||||||
|
getSignConfig().then((res:any) =>{
|
||||||
|
info.value = res.data
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 每个周期签到日期
|
||||||
|
const getSignInfoFn = (data:any) =>{
|
||||||
|
getSignInfo(data).then((res:any) =>{
|
||||||
|
state.signInList = []
|
||||||
|
state.packList = []
|
||||||
|
state.packList = res.data.period
|
||||||
|
state.signInList = res.data.days.map((el:any) =>{
|
||||||
|
return Number(el)
|
||||||
|
})
|
||||||
|
active.value = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取当月总天数
|
||||||
|
const getDayCounts= () => {
|
||||||
|
let counts = new Date(state.curYear,state.curMonth+1,0).getDate()
|
||||||
|
//获取当前第一天是星期几
|
||||||
|
let firstWeekDay = new Date(state.curYear,state.curMonth,1).getDay()
|
||||||
|
state.dataCount = []
|
||||||
|
for(let i=1;i<counts+firstWeekDay;i++){
|
||||||
|
let val=i-firstWeekDay+ 1
|
||||||
|
state.dataCount.push(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 获取7天的日期签到
|
||||||
|
const getWeekCounts = () =>{
|
||||||
|
let now = `${state.curYear}-${state.curMonth+1 > 10 ? state.curMonth+1 : '0'+(state.curMonth+1)}-${state.curDate > 10 ? state.curDate : '0'+state.curDate }`
|
||||||
|
for (let i = state.curWeek - 1; i >= 0; i --) {
|
||||||
|
const day = new Date(now).getDate() - i
|
||||||
|
state.weekCount.push(day)
|
||||||
|
}
|
||||||
|
for (let i = 1; i <= 7 - state.curWeek; i++) {
|
||||||
|
const day = new Date(now).getDate() + i
|
||||||
|
state.weekCount.push(day)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//控制状态
|
||||||
|
const handleChange = () =>{
|
||||||
|
let nowDate = new Date().getMonth()
|
||||||
|
|
||||||
|
if(state.curMonth == nowDate){
|
||||||
|
flag.value = !flag.value
|
||||||
|
}else{
|
||||||
|
state.curMonth = new Date().getMonth()
|
||||||
|
state.curYear = new Date().getFullYear()
|
||||||
|
getSignInfoFn({year:state.curYear,month:state.curMonth+1})
|
||||||
|
flag.value = !flag.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//更改月份
|
||||||
|
const changeMonth=(type: string)=>{
|
||||||
|
state.dataCount=[]
|
||||||
|
if(type == 'prev'){
|
||||||
|
state.curMonth--
|
||||||
|
if(state.curMonth < 0){
|
||||||
|
state.curMonth = 11
|
||||||
|
state.curYear--
|
||||||
|
}
|
||||||
|
week.weekDay = 1
|
||||||
|
active.value = false
|
||||||
|
}else{
|
||||||
|
state.curMonth++
|
||||||
|
if(state.curMonth > 11){
|
||||||
|
state.curMonth = 0
|
||||||
|
state.curYear++
|
||||||
|
}
|
||||||
|
week.weekDay = 1
|
||||||
|
active.value = false
|
||||||
|
}
|
||||||
|
let data = {year:state.curYear,month:state.curMonth + 1}
|
||||||
|
getSignInfoFn(data)
|
||||||
|
getDayCounts()
|
||||||
|
}
|
||||||
|
|
||||||
|
const memberStore = useMemberStore()
|
||||||
|
|
||||||
|
// 点击签到
|
||||||
|
const setSignFn = () =>{
|
||||||
|
setSign().then(res =>{
|
||||||
|
if(Object.values(res.data).length){
|
||||||
|
signAward.value = res.data
|
||||||
|
getSignInfoFn({year:state.curYear,month:state.curMonth+1})
|
||||||
|
getSignConfigFn()
|
||||||
|
memberStore.getMemberInfo()
|
||||||
|
awardShow.value = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查看每日礼包
|
||||||
|
let curPickDay = ref(null)
|
||||||
|
const getDayPackFn = (date:number) =>{
|
||||||
|
let {curYear,curMonth}=toRefs(state)
|
||||||
|
let itemDate=`${curYear.value}-${(curMonth.value+1) < 10 ? '0' + (curMonth.value+1) : (curMonth.value+1)}-${date < 10 ? '0'+date : date}`
|
||||||
|
let flag = state.packList.some(el =>{
|
||||||
|
return el.day == itemDate
|
||||||
|
})
|
||||||
|
if(!flag) return
|
||||||
|
curPickDay.value = date
|
||||||
|
let obj = {
|
||||||
|
year: state.curYear,
|
||||||
|
month:state.curMonth + 1,
|
||||||
|
day: date
|
||||||
|
}
|
||||||
|
getDayPack(obj).then((res:any) => {
|
||||||
|
if(JSON.stringify(res.data) != '[]'){
|
||||||
|
packInfo.value = res.data
|
||||||
|
packShow.value = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断是否签到
|
||||||
|
const isVerDate = (val:any) => {
|
||||||
|
return state.signInList.includes(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
//判断是否是当前日期
|
||||||
|
const isCurrentDate=(date)=>{
|
||||||
|
if(date> 0 && date <= state.dataCount.length){
|
||||||
|
if(date == state.curDate && currentYear == state.curYear && currentMonth == state.curMonth){
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const isPackDate = (date:any) =>{
|
||||||
|
let {curYear,curMonth}=toRefs(state)
|
||||||
|
let itemDate=`${curYear.value}-${(curMonth.value+1) < 10 ? '0' + (curMonth.value+1) : (curMonth.value+1)}-${date < 10 ? '0'+date : date}`
|
||||||
|
let flag = state.packList.some((el:any) =>{
|
||||||
|
return el.day == itemDate && el.award
|
||||||
|
})
|
||||||
|
return flag
|
||||||
|
}
|
||||||
|
|
||||||
|
// 过滤日期
|
||||||
|
const filteredDate=(date :any)=>{
|
||||||
|
return date > 0 ? date : ''
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取系统状态栏的高度
|
||||||
|
let menuButtonInfo = {};
|
||||||
|
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API,尚未兼容)
|
||||||
|
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
|
||||||
|
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
||||||
|
// #endif
|
||||||
|
let topTabbarData = ref({
|
||||||
|
title:'我的签到',
|
||||||
|
topStatusBar: {
|
||||||
|
style: 'style-1',
|
||||||
|
isTransparent: true,
|
||||||
|
bgColor: 'transparent',
|
||||||
|
textColor: '#fff'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const headStyle = computed(() => {
|
||||||
|
let style = ''
|
||||||
|
style = pxToRpx(Number(menuButtonInfo.height) + menuButtonInfo.top + 8)+ 382 + 'rpx;'
|
||||||
|
return style
|
||||||
|
})
|
||||||
|
const topStyle = computed(() => {
|
||||||
|
let style = ''
|
||||||
|
style = pxToRpx(Number(menuButtonInfo.height) + menuButtonInfo.top + 8)+38 + 'rpx;'
|
||||||
|
return style
|
||||||
|
})
|
||||||
|
// rpx转px
|
||||||
|
const rpxToPx=(rpx:any)=>{
|
||||||
|
const screenWidth = uni.getSystemInfoSync().screenwidth
|
||||||
|
return(screenWidth*Number.parseInt(rpx))/750
|
||||||
|
}
|
||||||
|
// px转rpx
|
||||||
|
const pxToRpx=(px:any)=>{
|
||||||
|
const screenWidth =uni.getSystemInfoSync().screenWidth
|
||||||
|
return(750*Number.parseInt(px))/screenWidth
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.bg-color{
|
||||||
|
background-color: rgba(102,102,102,0.4);
|
||||||
|
}
|
||||||
|
.sigin-bg{
|
||||||
|
background: linear-gradient( 90deg, #FFA359 0%, #FF5426 100%), #F2F2F2;
|
||||||
|
}
|
||||||
|
:deep(.award-popup .u-popup__content){
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
.bg-award{
|
||||||
|
background: linear-gradient( 51deg, #FFFBFC 0%, #FFFCF9 59%, #FFE7E7 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-button{
|
||||||
|
background: linear-gradient( 180deg, #FFEAE1 0%, #FFCDD0 34%, #E0052C 100%);
|
||||||
|
border-radius: 40rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -45,32 +45,31 @@
|
|||||||
* 获取支付信息
|
* 获取支付信息
|
||||||
*/
|
*/
|
||||||
const getPayInfo = () => {
|
const getPayInfo = () => {
|
||||||
getPayInfoApi(tradeType, tradeId)
|
getPayInfoApi(tradeType, tradeId).then((res: responseResult) => {
|
||||||
.then((res : responseResult) => {
|
if (!uni.$u.test.isEmpty(res.data)) {
|
||||||
if (!uni.$u.test.isEmpty(res.data)) {
|
if (res.data.status == 1 && requestNum < 5) {
|
||||||
if (res.data.status == 1 && requestNum < 5) {
|
loading.value = true
|
||||||
loading.value = true
|
requestNum++
|
||||||
requestNum++
|
setTimeout(() => {
|
||||||
setTimeout(() => {
|
getPayInfo()
|
||||||
getPayInfo()
|
}, 1000)
|
||||||
}, 1000)
|
return
|
||||||
return
|
|
||||||
}
|
|
||||||
payInfo.value = res.data
|
|
||||||
loading.value = false
|
|
||||||
uni.setNavigationBarTitle({
|
|
||||||
title: payInfo.value.status == 2 ? t('pay.paySuccess') : t('pay.payFail')
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}).catch(() => {
|
payInfo.value = res.data
|
||||||
|
loading.value = false
|
||||||
|
uni.setNavigationBarTitle({
|
||||||
|
title: payInfo.value.status == 2 ? t('pay.paySuccess') : t('pay.payFail')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const complete = () => {
|
const complete = () => {
|
||||||
const payReturn = decodeURIComponent(uni.getStorageSync('payReturn'))
|
const payReturn = decodeURIComponent(uni.getStorageSync('payReturn'))
|
||||||
if (payReturn) redirect({ url: payReturn, mode: 'redirectTo' })
|
if (payReturn) redirect({ url: payReturn, mode: 'reLaunch' })
|
||||||
else redirect({ url: getFirstPage(), param: { code: payInfo.value?.out_trade_no }, mode: 'redirectTo' })
|
else redirect({ url: getFirstPage(), param: { code: payInfo.value?.out_trade_no }, mode: 'reLaunch' })
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="w-full h-screen bg-page setting-wrap" :style="themeColor()">
|
<view class="w-full h-screen box-border pt-[30rpx] bg-page setting-wrap" :style="themeColor()">
|
||||||
<view class="h-[30rpx]"></view>
|
<view class="m-[30rpx] mt-0 bg-white rounded-md overflow-hidden px-[20rpx] py-[10rpx]">
|
||||||
<view class="m-[30rpx] bg-white rounded-md overflow-hidden px-[20rpx] py-[10rpx]">
|
|
||||||
<u-cell-group :border="false">
|
<u-cell-group :border="false">
|
||||||
<u-cell :title="t('personalSettings')" :is-link="true" url="/app/pages/member/personal"></u-cell>
|
<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>
|
<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 :title="t('privacyAgreement')" :is-link="true" url="/app/pages/auth/agreement?key=privacy"></u-cell>
|
||||||
</u-cell-group>
|
</u-cell-group>
|
||||||
</view>
|
</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-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>
|
</u-cell-group>
|
||||||
</view>
|
</view>
|
||||||
<!-- #endif -->
|
|
||||||
|
|
||||||
<u-action-sheet :actions="langList" :show="langSheetShow" :closeOnClickOverlay="true"
|
<u-action-sheet :actions="langList" :show="langSheetShow" :closeOnClickOverlay="true"
|
||||||
:safeAreaInsetBottom="true"
|
:safeAreaInsetBottom="true"
|
||||||
@ -57,7 +55,7 @@
|
|||||||
* 切换语言
|
* 切换语言
|
||||||
*/
|
*/
|
||||||
const switchLang = (lang) => {
|
const switchLang = (lang) => {
|
||||||
language.loadLocaleMessages('/' + currRoute(), lang.value)
|
language.loadAllLocaleMessages('app', lang.value)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
82
uni-app/src/app/pages/verify/detail.vue
Normal file
82
uni-app/src/app/pages/verify/detail.vue
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<template>
|
||||||
|
<view :style="themeColor()" class="bg-[#f8f8f8] min-h-[100vh] overflow-hidden">
|
||||||
|
<block v-if="!loading">
|
||||||
|
<view class="mt-[30rpx] mx-[30rpx]">
|
||||||
|
<view class="py-[10rpx] px-[20rpx] flex flex-col rounded-[16rpx] bg-white">
|
||||||
|
<view class="flex h-[180rpx]" :class="{'mb-[20rpx]': verifyInfo.value.list.length-1 != index}" v-for="(item,index) in verifyInfo.value.list" :key="index">
|
||||||
|
<image class="w-[120rpx] h-[120rpx] mt-[30rpx] rounded-[8rpx]" mode="aspectFit" v-if="item.cover" :src="img(item.cover)"></image>
|
||||||
|
<image class="w-[120rpx] h-[120rpx] mt-[30rpx] rounded-[8rpx]" mode="aspectFit" v-else :src="img('addon/tourism/tourism/member/hotel.png')"></image>
|
||||||
|
<view class="flex flex-col flex-1 ml-[20rpx] mt-36rpx">
|
||||||
|
<view class="leading-[39rpx] text-[28rpx] max-w-[432rpx] multi-hidden">{{item.name}}</view>
|
||||||
|
<view class="self-end text-[28rpx]">x1</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="flex flex-col bg-[#fff] p-[20rpx] rounded-[16rpx] mt-[20rpx]">
|
||||||
|
<view class="text-[28rpx] text-[#333333] font-bold leading-[39rpx] h-[39rpx]">核销信息</view>
|
||||||
|
<view class="flex justify-between items-center mt-[30rpx] h-[39rpx]">
|
||||||
|
<text class="text-[28rpx] text-[#333]">核销类型</text>
|
||||||
|
<view class="text-[28rpx] text-[#333]">{{verifyInfo.type_name}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="flex justify-between items-center mt-[20rpx] h-[39rpx]">
|
||||||
|
<text class="text-[28rpx] text-[#333]">核销状态</text>
|
||||||
|
<view class="text-[28rpx] text-[#333]">已核销</view>
|
||||||
|
</view>
|
||||||
|
<view class="flex justify-between items-center mt-[20rpx] h-[39rpx]">
|
||||||
|
<text class="text-[28rpx]">核销时间</text>
|
||||||
|
<view class="text-[#333333] text-[28rpx]">{{verifyInfo.create_time}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="flex justify-between items-center mt-[20rpx] h-[39rpx]">
|
||||||
|
<text class="text-[28rpx]">核销人员</text>
|
||||||
|
<view class="text-[#333333] text-[28rpx]">{{verifyInfo.member ? verifyInfo.member.nickname : '--'}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="flex items-center justify-between mt-[20rpx]" v-for="(item,index) in verifyInfo.value.content.fixed">
|
||||||
|
<text class="text-[28rpx] text-[#333]">{{item.title}}</text>
|
||||||
|
<view class="text-[28rpx] text-[#333]">{{item.value}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-for="(item,index) in verifyInfo.value.content.diy" :key="index" class="text-[#838383] bg-white p-[20rpx] rounded-[16rpx] mt-[20rpx]">
|
||||||
|
<view class="text-[28rpx] text-[#333333] font-bold leading-[39rpx] h-[39rpx]">{{item.title}}</view>
|
||||||
|
<view class="flex items-center justify-between h-[39rpx] mt-[20rpx]" v-for="(subItem,subIndex) in item.list" :key="subIndex" :class="{'mt-30rpx' : subIndex == '0'}">
|
||||||
|
<text class="text-[28rpx] text-[#333]">{{subItem.title}}</text>
|
||||||
|
<view class="text-[28rpx] text-[#333]">{{subItem.value}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</block>
|
||||||
|
<u-loading-page :loading="loading" loading-text="" loadingColor="var(--primary-color)" iconSize="35"></u-loading-page>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { onLoad,onShow } from '@dcloudio/uni-app'
|
||||||
|
import { img,redirect, getToken } from '@/utils/common';
|
||||||
|
import { getVerifyDetail } from '@/app/api/verify'
|
||||||
|
import { t } from '@/locale'
|
||||||
|
|
||||||
|
const loading = ref(true)
|
||||||
|
let code = ref('');
|
||||||
|
onLoad((option)=> {
|
||||||
|
if (option.code) code.value = option.code;
|
||||||
|
})
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
if(getToken()){
|
||||||
|
getVerifyDetailFn();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
let verifyInfo = ref({})
|
||||||
|
const getVerifyDetailFn = ()=>{
|
||||||
|
loading.value = true;
|
||||||
|
getVerifyDetail(code.value).then((res:any) =>{
|
||||||
|
verifyInfo.value = res.data;
|
||||||
|
console.log("verifyInfo.value",verifyInfo.value);
|
||||||
|
loading.value = false;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
200
uni-app/src/app/pages/verify/index.vue
Normal file
200
uni-app/src/app/pages/verify/index.vue
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
<template>
|
||||||
|
<view :style="themeColor()">
|
||||||
|
<view class="w-[100vw] min-h-[100vh] bg-[#f8f8f8]" v-if="!loading">
|
||||||
|
<view class="w-full bg-[#fff] verify-box h-[760rpx]">
|
||||||
|
<view class="text-[var(--primary-color)] fixed top-[30rpx] right-[30rpx] flex items-center" @click="redirect({url:'/app/pages/verify/record'})">
|
||||||
|
<image class="w-[24rpx] h-[28rpx]" :src="img('static/resource/images/verify/history.png')"/>
|
||||||
|
<text class="text-[26rpx] ml-[10rpx]">核销记录</text>
|
||||||
|
</view>
|
||||||
|
<view v-show="operationType == 'sweepCode'" class="flex flex-col items-center justify-center">
|
||||||
|
<view class="sweep-code flex items-center justify-center" @click="scanCode">
|
||||||
|
<image class="w-[354rpx] h-[354rpx]" :src="img('static/resource/images/verify/saoma.png')"/>
|
||||||
|
</view>
|
||||||
|
<view class="mt-[40rpx] text-[32rpx]">点击扫描二维码</view>
|
||||||
|
<view class="mt-[20rpx] text-[#999] text-[26rpx] font-400 pb-[142rpx]">扫描二维码进行核销</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-show="operationType == 'manualInput'">
|
||||||
|
<view class="flex pt-[126rpx] pb-[30rpx] items-center justify-center">
|
||||||
|
<view class="flex justify-center items-center flex-col pr-[30rpx]">
|
||||||
|
<image class="w-[100rpx] h-[100rpx]" :src="img('static/resource/images/verify/shuruhexiaoma.png')"/>
|
||||||
|
<view class="text-[26rpx] h-[36rpx] leading-[36rpx] mt-[12rpx]">验证核销码</view>
|
||||||
|
</view>
|
||||||
|
<image class="w-[74rpx] h-[12rpx] mb-[50rpx]" :src="img('static/resource/images/verify/youjiantou.png')"/>
|
||||||
|
<view class="flex justify-center items-center flex-col pl-[30rpx]">
|
||||||
|
<image class="w-[100rpx] h-[100rpx]" :src="img('static/resource/images/verify/hexiao1.png')"/>
|
||||||
|
<view class="text-[26rpx] h-[36rpx] leading-[36rpx] mt-[12rpx]">核销</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="mt-[50rpx]">
|
||||||
|
<view class="h-[90rpx] border-[2rpx] border-solid border-[#eee] rounded-[12rpx] box-border p-[20rpx] mx-[60rpx] flex items-center" >
|
||||||
|
<text class="nc-iconfont nc-icon-saotiaoxingmaV6xx text-[44rpx] text-[#EF000C]"></text>
|
||||||
|
<input type="text" placeholder="请输入核销码" class="h-[90rpx] border-none text-start ml-[30rpx] text-[28rpx] flex-1" placeholder-class="_placeholder" v-model="verify_code" :focus="isFocus" ref="input"/>
|
||||||
|
</view>
|
||||||
|
<view class="h-[88rpx] min-w-[630rpx] bg-[var(--primary-color)] text-[#fff] flex items-center justify-center !text-[32rpx] rounded-[50rpx] h-[88rpx] mx-[60rpx] mt-[146rpx] relative z-1" @click="confirm">确认</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="w-[630rpx] h-[100rpx] bg-[#fff] mx-[auto] mt-[220rpx] rounded-[90rpx] flex relative action-type-wrap">
|
||||||
|
<view class="relative w-[51%] rounded-[50rpx] z-0 flex flex-col items-center justify-center" @click="changeOperationType('sweepCode')" :class="{'xuanZhong1': operationType == 'sweepCode'}">
|
||||||
|
<view class="mt-[10rpx]"><text class="nc-iconfont nc-icon-saoyisaoV6xx !text-[42rpx]"></text></view>
|
||||||
|
<view class="text-[24rpx] leading-[34rpx] h-[34rpx] mt-[-6rpx]">扫码核销</view>
|
||||||
|
</view>
|
||||||
|
<view class="flex flex-col items-center flex-col w-[120rpx] h-[120rpx] bg-[#FF7354] rounded-[50%] absolute top-[-10rpx] left-[255rpx] heXiao text-white z-10 shrink-0">
|
||||||
|
<view class="nc-iconfont nc-icon-saotiaoxingmaV6xx ns-gradient-otherpages-member-balance-balance-rechange !text-[44rpx] mt-[19rpx]"></view>
|
||||||
|
<view class="text-[24rpx] mt-[8rpx] leading-[34rpx] h-[34rpx]">核销台</view>
|
||||||
|
</view>
|
||||||
|
<view class="relative w-[51%] rounded-[50rpx] z-0 flex flex-col items-center justify-center" :class="{'xuanZhong': operationType == 'manualInput'}" @click="changeOperationType('manualInput')">
|
||||||
|
<view class="ml-[20rpx] mt-[10rpx]"><text class="iconfont iconVector-77 !text-[42rpx]"></text></view>
|
||||||
|
<view class="ml-[20rpx] text-[24rpx] leading-[34rpx] h-[34rpx] mt-[-6rpx]" @click="focus">手动输入</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
|
<!-- 小程序隐私协议 -->
|
||||||
|
<privacy-popup ref="privacyPopup"></privacy-popup>
|
||||||
|
<!-- #endif -->
|
||||||
|
</view>
|
||||||
|
<u-loading-page :loading="loading" loading-text="" loadingColor="var(--primary-color)" iconSize="35"></u-loading-page>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { img,redirect, isWeixinBrowser, getToken } from '@/utils/common';
|
||||||
|
import {onShow} from '@dcloudio/uni-app'
|
||||||
|
import { getVerifierInfo, getCheckVerifier } from '@/app/api/verify'
|
||||||
|
import { t } from '@/locale'
|
||||||
|
import wechat from '@/utils/wechat'
|
||||||
|
|
||||||
|
let operationType = ref('manualInput'); //类型
|
||||||
|
// #ifdef H5
|
||||||
|
operationType.value = 'manualInput';
|
||||||
|
// #endif
|
||||||
|
// #ifndef H5
|
||||||
|
operationType.value = 'sweepCode';
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
let isFocus = ref(false)
|
||||||
|
let verify_code = ref('');
|
||||||
|
let loading = ref(true)
|
||||||
|
onShow(() => {
|
||||||
|
if(getToken())
|
||||||
|
checkIsVerifier();
|
||||||
|
})
|
||||||
|
|
||||||
|
// 检测是否是核销员
|
||||||
|
const checkIsVerifier = () => {
|
||||||
|
getCheckVerifier().then((res:any) =>{
|
||||||
|
if(!res.data){
|
||||||
|
uni.showToast({
|
||||||
|
title: '非核销员无此权限',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.navigateBack();
|
||||||
|
}, 1000);
|
||||||
|
}else{
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const scanCode = () => {
|
||||||
|
// #ifdef MP
|
||||||
|
uni.scanCode({
|
||||||
|
onlyFromCamera: true,
|
||||||
|
success: res => {
|
||||||
|
if (res.errMsg == 'scanCode:ok') {
|
||||||
|
let code = res.result;
|
||||||
|
redirect({ url: '/app/pages/verify/verify', param: { code} })
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: res.errorMsg,
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef H5
|
||||||
|
if (isWeixinBrowser()) {
|
||||||
|
wechat.init();
|
||||||
|
wechat.scanQRCode(res => {
|
||||||
|
if (res.resultStr) {
|
||||||
|
let code = res.resultStr;
|
||||||
|
redirect({ url: '/app/pages/verify/verify', param: { code} })
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
|
||||||
|
let isLoading = false;
|
||||||
|
const confirm = () => {
|
||||||
|
if(isLoading) return false;
|
||||||
|
isLoading = true;
|
||||||
|
var reg = /[\S]+/;
|
||||||
|
if (!reg.test(verify_code.value)) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请输入核销码',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
getVerifierInfo(verify_code.value).then((res:any) =>{
|
||||||
|
isLoading = false;
|
||||||
|
redirect({ url: '/app/pages/verify/verify', param: { code: verify_code.value} })
|
||||||
|
}).catch(() => {
|
||||||
|
isLoading = false;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const focus = () => {
|
||||||
|
isFocus.value = !isFocus.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeOperationType = (type: string) => {
|
||||||
|
// #ifdef H5
|
||||||
|
if (type == 'sweepCode' && !isWeixinBrowser()) {
|
||||||
|
uni.showToast({
|
||||||
|
title: 'H5端不支持扫码核销',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
operationType.value = type;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.action-type-wrap {
|
||||||
|
box-shadow: 0 6px 6px 0 rgba(0, 0, 0, 0.03), 0 4px 2px 0 rgba(0, 0, 0, 0.04);;
|
||||||
|
}
|
||||||
|
.heXiao{
|
||||||
|
background: linear-gradient( 180deg, #FF7354 0%, #FF020F 100%), #EF000C;
|
||||||
|
}
|
||||||
|
.xuanZhong{
|
||||||
|
background: linear-gradient( 270deg, #FFD1D1 0%, rgba(255,209,209,0.2) 100%), #FFFFFF;
|
||||||
|
color:#EF000C;
|
||||||
|
}
|
||||||
|
.xuanZhong1{
|
||||||
|
background: linear-gradient( 90deg, #FFD1D1 0%, rgba(255,209,209,0.2) 100%), #FFFFFF;
|
||||||
|
color:#EF000C;
|
||||||
|
}
|
||||||
|
.sweep-code {
|
||||||
|
width: 354rpx;
|
||||||
|
height: 354rpx;
|
||||||
|
box-shadow: 0 8px 8px 0 rgba(0, 0, 0, 0.03), 0 6px 3px 0 rgba(0, 0, 0, 0.02);
|
||||||
|
border-radius: 50%;
|
||||||
|
margin: 146rpx auto 0rpx;
|
||||||
|
}
|
||||||
|
.verify-box {
|
||||||
|
border-bottom-left-radius: 400rpx 60rpx;
|
||||||
|
border-bottom-right-radius: 400rpx 60rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
74
uni-app/src/app/pages/verify/record.vue
Normal file
74
uni-app/src/app/pages/verify/record.vue
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<template>
|
||||||
|
<view class="bg-[#f8f8f8] min-h-screen overflow-hidden" :style="themeColor()">
|
||||||
|
<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="w-full flex flex-col mb-3 bg-[#fff] px-[20rpx] box-border rounded-[18rpx] " @click="toLink(item)">
|
||||||
|
<view class="flex items-center pb-[30rpx] pt-[20rpx] leading-[1]">
|
||||||
|
<view class="nc-iconfont nc-icon-hexiaotaiV6xx pr-[10rpx]"></view>
|
||||||
|
<text class="truncate max-w-[590rpx] text-[#333333] text-[26rpx]">核销码:{{ item.code }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex flex-1" v-for="(dataItem,dataIndex) in item.value.list" :key="dataIndex">
|
||||||
|
<image class="w-[100rpx] h-[100rpx] rounded-[8rpx]" mode="aspectFit" v-if="dataItem.cover" :src="img(dataItem.cover)"></image>
|
||||||
|
<image class="w-[100rpx] h-[100rpx] rounded-[8rpx]" mode="aspectFit" v-else :src="img('addon/tourism/tourism/member/hotel.png')"></image>
|
||||||
|
|
||||||
|
<view class="flex flex-col flex-1 ml-[20rpx] mt-[3rpx]">
|
||||||
|
<view class="leading-[1.4] multi-hidden text-28rpx text-[#333]">{{dataItem.name}}</view>
|
||||||
|
<view class="self-end text-[28rpx]">x1</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="flex flex-col bg-[#F6F6F6] p-[20rpx] rounded-[12rpx] mt-[20rpx] mb-[20rpx]">
|
||||||
|
<text class="text-[#333333] text-[26rpx] h-[36rpx] leading-[36rpx]">核销时间:{{ item.create_time }}</text>
|
||||||
|
<text class="text-[#333333] text-[26rpx] h-[36rpx] mt-[10rpx] truncate leading-[36rpx]">核销员:{{ item.member ? item.member.nickname : '--' }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
<mescroll-empty :option="{'icon': img('static/resource/images/empty.png')}" v-if="!list.length && loading"></mescroll-empty>
|
||||||
|
</mescroll-body>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive, computed } from 'vue'
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import MescrollBody from '@/components/mescroll/mescroll-body/mescroll-body.vue'
|
||||||
|
import MescrollEmpty from '@/components/mescroll/mescroll-empty/mescroll-empty.vue'
|
||||||
|
import useMescroll from '@/components/mescroll/hooks/useMescroll.js'
|
||||||
|
import { onPageScroll, onReachBottom } from '@dcloudio/uni-app'
|
||||||
|
import { getVerifyRecords } from '@/app/api/verify'
|
||||||
|
import { img, redirect } from '@/utils/common'
|
||||||
|
|
||||||
|
let list = ref<Array<Object>>([])
|
||||||
|
let loading = ref<boolean>(false)
|
||||||
|
const { mescrollInit, downCallback, getMescroll } = useMescroll(onPageScroll, onReachBottom)
|
||||||
|
|
||||||
|
const geVerifyRecordFn = (mescroll) => {
|
||||||
|
loading.value = false;
|
||||||
|
let data : object = {
|
||||||
|
page: mescroll.num,
|
||||||
|
limit: mescroll.size,
|
||||||
|
};
|
||||||
|
|
||||||
|
getVerifyRecords(data).then((res) => {
|
||||||
|
let newArr = (res.data.data as Array<Object>);
|
||||||
|
//设置列表数据
|
||||||
|
if (mescroll.num == 1) {
|
||||||
|
list.value = []; //如果是第一页需手动制空列表
|
||||||
|
}
|
||||||
|
list.value = list.value.concat(newArr);
|
||||||
|
mescroll.endSuccess(newArr.length);
|
||||||
|
loading.value = true;
|
||||||
|
}).catch(() => {
|
||||||
|
loading.value = true;
|
||||||
|
mescroll.endErr(); // 请求失败, 结束加载
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const toLink = (data: AnyObject)=> {
|
||||||
|
redirect({ url: '/app/pages/verify/detail', param: { code: data.code } })
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
</style>
|
||||||
145
uni-app/src/app/pages/verify/verify.vue
Normal file
145
uni-app/src/app/pages/verify/verify.vue
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
<template>
|
||||||
|
<view :style="themeColor()" class="bg-[#f8f8f8] min-h-[100vh] overflow-hidden">
|
||||||
|
<block v-if="!loading && verifyInfo && verifyInfo.value">
|
||||||
|
<view class="w-full bg-[#fff] flex justify-center">
|
||||||
|
<view class="text-[var(--primary-color)] absolute top-[30rpx] right-[30rpx] flex" @click="redirect({url:'/app/pages/verify/record'})">
|
||||||
|
<image class="w-[24rpx] h-[28rpx]" :src="img('static/resource/images/verify/history.png')"/>
|
||||||
|
<text class="text-[26rpx] leading-[30.47rpx] ml-[10rpx] h-[36rpx] leading-[36rpx]">核销记录</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex pt-[126rpx] pb-[30rpx] items-center">
|
||||||
|
<view class="flex justify-center items-center flex-col pr-[30rpx]">
|
||||||
|
<image class="w-[100rpx] h-[100rpx]" :src="img('static/resource/images/verify/yanzhenghexiaoma.png')"/>
|
||||||
|
<view class="text-[26rpx] mt-[12rpx] h-[36rpx] leading-[36rpx]">验证核销码</view>
|
||||||
|
</view>
|
||||||
|
<image class="w-[74rpx] h-[12rpx] mb-[50rpx]" :src="img('static/resource/images/verify/youjiantou.png')"/>
|
||||||
|
<view class="flex justify-center items-center flex-col pl-[30rpx]">
|
||||||
|
<image class="w-[100rpx] h-[100rpx]" :src="img('static/resource/images/verify/hexiao.png')"/>
|
||||||
|
<view class="text-[26rpx] mt-[12rpx] h-[36rpx] leading-[36rpx]">确定核销</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="bg-[#fff] rounded-[16rpx] mt-[20rpx] mx-[30rpx] h-[200rpx]">
|
||||||
|
<view class="flex" v-for="(item,index) in verifyInfo.value.list" :key="index">
|
||||||
|
<image class="w-[150rpx] h-[150rpx] ml-[20rpx] mt-[30rpx] rounded-[8rpx]" mode="aspectFit" v-if="item.cover" :src="img(item.cover)"></image>
|
||||||
|
<image class="w-[150rpx] h-[150rpx] ml-[20rpx] mt-[30rpx] rounded-[8rpx]" mode="aspectFit" v-else :src="img('addon/tourism/tourism/member/hotel.png')"></image>
|
||||||
|
<view class="flex flex-col flex-1 ml-[10rpx]">
|
||||||
|
<view class="mt-[33rpx] ml-[20rpx] max-w-[432rpx] multi-hidden">{{item.name}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="bg-[#fff] rounded-[16rpx] mx-[30rpx] mt-[20rpx]">
|
||||||
|
<view class="pt-[20rpx] pl-[20rpx] text-[28rpx] font-bold h-[39rpx] leading-[39rpx]">核销信息</view>
|
||||||
|
<view class="text-[28rpx] pb-[20rpx]">
|
||||||
|
<view class="flex pt-[30rpx] items-center justify-between px-[20rpx]">
|
||||||
|
<text class="text-[28rpx] text-[#333333] h-[39rpx] leading-[39rpx]">核销类型</text>
|
||||||
|
<view class="text-[28rpx] text-[#333333] h-[39rpx] leading-[39rpx]">{{verifyInfo.type_name}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="flex pt-[30rpx] items-center justify-between px-[20rpx]" v-for="(item,index) in verifyInfo.value.content.fixed">
|
||||||
|
<text class="text-[28rpx] text-[#333333] h-[39rpx] leading-[39rpx]">{{item.title}}</text>
|
||||||
|
<view class="text-[28rpx] text-[#333333] h-[39rpx] leading-[39rpx]">{{item.value}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-for="(item,index) in verifyInfo.value.content.diy" :key="index" class="bg-[#fff] rounded-[16rpx] mx-[30rpx] mt-[20rpx]">
|
||||||
|
<view class="pt-[20rpx] pl-[20rpx] text-[28rpx] font-bold h-[39rpx] leading-[39rpx]">{{item.title}}</view>
|
||||||
|
<view class="text-[28rpx] pb-[20rpx]">
|
||||||
|
<view class="flex pt-[30rpx] items-center justify-between px-[20rpx]" v-for="(subItem,subIndex) in item.list" :key="subIndex">
|
||||||
|
<text class="text-[28rpx] text-[#333333] h-[39rpx] leading-[39rpx]">{{subItem.title}}</text>
|
||||||
|
<div v-if="subIndex === 0" class="flex items-center">
|
||||||
|
<text class="text-[28rpx] text-[#333333] h-[39rpx] leading-[39rpx] mr-[10rpx]">{{ subItem.value }}</text>
|
||||||
|
<view class="w-[1rpx] h-[20rpx] bg-[#999999] mr-[10rpx]"></view>
|
||||||
|
<view class="text-[#EF900A]" @click="copy(subItem.value)">复制</view>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<text class="text-[28rpx] text-[#333333] h-[39rpx] leading-[39rpx]">{{ subItem.value }}</text>
|
||||||
|
</div>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<text class=" min-w-[630rpx] fixed bottom-[60rpx] confirmBtn text-[#fff] flex items-center justify-center !text-[32rpx] rounded-[50rpx] h-[88rpx] ml-[60rpx] mr-[60rpx]" @click="verifyFn">确定</text>
|
||||||
|
</block>
|
||||||
|
<u-loading-page :loading="loading" loading-text="" loadingColor="var(--primary-color)" iconSize="35"></u-loading-page>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { onLoad ,onShow} from '@dcloudio/uni-app'
|
||||||
|
import { img,redirect, isWeixinBrowser, getToken } from '@/utils/common';
|
||||||
|
import { getVerifierInfo, getCheckVerifier, verify } from '@/app/api/verify'
|
||||||
|
import { copy } from '@/utils/common';
|
||||||
|
import { t } from '@/locale'
|
||||||
|
|
||||||
|
const loading = ref(true)
|
||||||
|
const verifyDetail = ref<AnyObject | null>(null)
|
||||||
|
let code = ref('');
|
||||||
|
onLoad((option)=> {
|
||||||
|
if (option.code) code.value = option.code;
|
||||||
|
// 小程序扫码进入
|
||||||
|
if (option.scene) {
|
||||||
|
let sceneParams = decodeURIComponent(option.scene);
|
||||||
|
sceneParams = sceneParams.split('&');
|
||||||
|
if (sceneParams.length) {
|
||||||
|
sceneParams.forEach(item => {
|
||||||
|
if (item.indexOf('code') != -1) code.value = item.split('-')[1];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
if(getToken()){
|
||||||
|
checkIsVerifier();
|
||||||
|
getVerifierInfoFn();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 检测是否是核销员
|
||||||
|
const checkIsVerifier = () => {
|
||||||
|
getCheckVerifier().then((res:any) =>{
|
||||||
|
if(!res.data){
|
||||||
|
uni.showToast({
|
||||||
|
title: '非核销员无此权限',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.navigateBack();
|
||||||
|
}, 1000);
|
||||||
|
}else{
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let verifyInfo = ref({})
|
||||||
|
const getVerifierInfoFn = ()=>{
|
||||||
|
loading.value = true;
|
||||||
|
getVerifierInfo(code.value).then((res:any) =>{
|
||||||
|
verifyInfo.value = res.data;
|
||||||
|
loading.value = false;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let isLoading = false;
|
||||||
|
const verifyFn = ()=>{
|
||||||
|
if(isLoading) return false;
|
||||||
|
isLoading = true;
|
||||||
|
|
||||||
|
verify(code.value).then((res:any) =>{
|
||||||
|
isLoading = false;
|
||||||
|
setTimeout(() => {
|
||||||
|
redirect({ url: '/app/pages/verify/index', param: {}, mode: 'redirectTo' })
|
||||||
|
}, 1000);
|
||||||
|
}).catch(() => {
|
||||||
|
isLoading = false;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.confirmBtn{
|
||||||
|
background: linear-gradient( 94deg, #FB7939 0%, #FE120E 99%), #EF000C;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
37
uni-app/src/app/pages/weapp/order_shipping.vue
Normal file
37
uni-app/src/app/pages/weapp/order_shipping.vue
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<template>
|
||||||
|
<view :style="themeColor()">
|
||||||
|
<view class="error-msg">{{errorMsg}}</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {ref} from 'vue';
|
||||||
|
import {redirect} from '@/utils/common';
|
||||||
|
import {onLoad} from '@dcloudio/uni-app'
|
||||||
|
import {getMsgJumpPath} from '@/app/api/system'
|
||||||
|
|
||||||
|
const outTradeNo = ref('')
|
||||||
|
const errorMsg = ref('')
|
||||||
|
|
||||||
|
onLoad((options: any) => {
|
||||||
|
if (options.merchant_trade_no) {
|
||||||
|
outTradeNo.value = options.merchant_trade_no;
|
||||||
|
getMsgJumpPathFn();
|
||||||
|
} else {
|
||||||
|
errorMsg.value = '缺少merchant_trade_no参数';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const getMsgJumpPathFn = () => {
|
||||||
|
getMsgJumpPath({
|
||||||
|
out_trade_no: outTradeNo.value,
|
||||||
|
}).then((res: any) => {
|
||||||
|
if(res.data && res.data.path){
|
||||||
|
// 跳转到设置的页面
|
||||||
|
redirect({url: '/' + res.data.path, mode: 'reLaunch'})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
</style>
|
||||||
@ -1,5 +1,7 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { toRaw } from 'vue'
|
import { toRaw } from 'vue'
|
||||||
|
import { diyRedirect, currRoute, getToken } from '@/utils/common';
|
||||||
|
import { useLogin } from '@/hooks/useLogin';
|
||||||
|
|
||||||
interface Diy {
|
interface Diy {
|
||||||
mode: string, // 模式:decorate 装修,为空表示正常
|
mode: string, // 模式:decorate 装修,为空表示正常
|
||||||
@ -7,115 +9,130 @@ interface Diy {
|
|||||||
currentIndex: number,
|
currentIndex: number,
|
||||||
global: {
|
global: {
|
||||||
title: string,
|
title: string,
|
||||||
pageStartBgColor: string, // 页面背景颜色(开始)
|
pageStartBgColor: string, // 页面背景颜色(开始)
|
||||||
pageEndBgColor: string, // 页面背景颜色(结束)
|
pageEndBgColor: string, // 页面背景颜色(结束)
|
||||||
bottomTabBarSwitch: boolean, // 底部导航开关
|
bottomTabBarSwitch: boolean, // 底部导航开关
|
||||||
bgUrl: string
|
bgUrl: string
|
||||||
},
|
},
|
||||||
// 组件集合
|
// 组件集合
|
||||||
value: any[],
|
value: any[],
|
||||||
topFixedStatus: string, // 置顶组件的状态
|
topFixedStatus: string, // 置顶组件的状态
|
||||||
scrollTop: number
|
scrollTop: number,
|
||||||
|
topTabarHeight: number
|
||||||
}
|
}
|
||||||
|
|
||||||
const useDiyStore = defineStore('diy', {
|
const useDiyStore = defineStore('diy', {
|
||||||
state: () : Diy => {
|
state: (): Diy => {
|
||||||
return {
|
return {
|
||||||
mode: '',
|
mode: '',
|
||||||
pageMode: 'diy',
|
pageMode: 'diy',
|
||||||
currentIndex: -99,
|
currentIndex: -99,
|
||||||
global: {
|
global: {
|
||||||
title: "",
|
title: "",
|
||||||
pageStartBgColor: '', // 页面背景颜色(开始)
|
pageStartBgColor: '', // 页面背景颜色(开始)
|
||||||
pageEndBgColor: '', // 页面背景颜色(结束)
|
pageEndBgColor: '', // 页面背景颜色(结束)
|
||||||
bottomTabBarSwitch: true,
|
bottomTabBarSwitch: true,
|
||||||
bgUrl: ''
|
bgUrl: ''
|
||||||
},
|
},
|
||||||
value: [], // 组件集合
|
value: [], // 组件集合
|
||||||
topFixedStatus: 'home', // 顶部 置顶组件状态,home:展示首页数据、diy:展示置顶组件定义的子页面
|
topFixedStatus: 'home', // 顶部 置顶组件状态,home:展示首页数据、diy:展示置顶组件定义的子页面
|
||||||
scrollTop: 0 // 滚动位置
|
scrollTop: 0, // 滚动位置
|
||||||
|
topTabarHeight: 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {},
|
||||||
},
|
actions: {
|
||||||
actions: {
|
// 初始化
|
||||||
// 初始化
|
init() {
|
||||||
init() {
|
// #ifdef H5
|
||||||
// #ifdef H5
|
var data = JSON.stringify({
|
||||||
var data = JSON.stringify({
|
type: 'init',
|
||||||
type: 'init',
|
load: true
|
||||||
load: true
|
});
|
||||||
});
|
// 传输给后台数据
|
||||||
// 传输给后台数据
|
window.parent.postMessage(data, '*');
|
||||||
window.parent.postMessage(data, '*');
|
|
||||||
|
|
||||||
// 监听父页面发来的消息
|
// 监听父页面发来的消息
|
||||||
window.addEventListener('message', event => {
|
window.addEventListener('message', event => {
|
||||||
try {
|
try {
|
||||||
let data = JSON.parse(event.data);
|
let data = JSON.parse(event.data);
|
||||||
this.currentIndex = data.currentIndex;
|
this.currentIndex = data.currentIndex;
|
||||||
this.pageMode = data.pageMode;
|
this.pageMode = data.pageMode;
|
||||||
if (data.global) this.global = data.global;
|
if (data.global) this.global = data.global;
|
||||||
if (data.value) this.value = data.value;
|
if (data.value) this.value = data.value;
|
||||||
|
|
||||||
if (this.value) {
|
if (this.value) {
|
||||||
this.value.forEach((item, index) => {
|
this.value.forEach((item, index) => {
|
||||||
item.pageStyle = '';
|
item.pageStyle = '';
|
||||||
if(item.pageStartBgColor) {
|
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 + ';';
|
else item.pageStyle += 'background-color:' + item.pageStartBgColor + ';';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.margin) {
|
if (item.margin) {
|
||||||
item.pageStyle += 'padding-top:' + item.margin.top * 2 + 'rpx' + ';';
|
if (item.margin.top > 0) {
|
||||||
item.pageStyle += 'padding-bottom:' + item.margin.bottom * 2 + 'rpx' + ';';
|
item.pageStyle += 'padding-top:' + item.margin.top * 2 + 'rpx' + ';';
|
||||||
item.pageStyle += 'padding-right:' + item.margin.both * 2 + 'rpx' + ';';
|
} else {
|
||||||
item.pageStyle += 'padding-left:' + item.margin.both * 2 + 'rpx' + ';';
|
item.pageStyle += 'padding-top:2rpx' + ';'; // 装修实时预览需要设置
|
||||||
}
|
}
|
||||||
});
|
item.pageStyle += 'padding-bottom:' + item.margin.bottom * 2 + 'rpx' + ';';
|
||||||
}
|
item.pageStyle += 'padding-right:' + item.margin.both * 2 + 'rpx' + ';';
|
||||||
// console.log('uniapp 接受后台装修返回的组件数据', data);
|
item.pageStyle += 'padding-left:' + item.margin.both * 2 + 'rpx' + ';';
|
||||||
} catch (e) {
|
}
|
||||||
console.log('uni-app diy 接受数据错误', e)
|
});
|
||||||
}
|
}
|
||||||
}, false);
|
// console.log('uniapp 接受后台装修返回的组件数据', data);
|
||||||
// #endif
|
} catch (e) {
|
||||||
},
|
console.log('uni-app diy 接受数据错误', e)
|
||||||
// 将数据传输给后台
|
}
|
||||||
postMessage(index, component) {
|
}, false);
|
||||||
// #ifdef H5
|
// #endif
|
||||||
this.currentIndex = index;
|
},
|
||||||
if (component)
|
// 将数据传输给后台
|
||||||
var data = JSON.stringify({
|
postMessage(index: any, component: any) {
|
||||||
type: 'data',
|
// #ifdef H5
|
||||||
index: this.currentIndex,
|
this.currentIndex = index;
|
||||||
global: toRaw(this.global),
|
if (component)
|
||||||
value: toRaw(this.value),
|
var data: any = JSON.stringify({
|
||||||
component: toRaw(component)
|
type: 'data',
|
||||||
});
|
index: this.currentIndex,
|
||||||
// 传输给后台数据
|
global: toRaw(this.global),
|
||||||
window.parent.postMessage(data, '*');
|
value: toRaw(this.value),
|
||||||
// #endif
|
component: toRaw(component)
|
||||||
},
|
});
|
||||||
// 选中正在编辑的组件
|
// 传输给后台数据
|
||||||
changeCurrentIndex(index : number, component : any = null) {
|
window.parent.postMessage(data, '*');
|
||||||
// #ifdef H5
|
// #endif
|
||||||
|
},
|
||||||
|
// 选中正在编辑的组件
|
||||||
|
changeCurrentIndex(index: number, component: any = null) {
|
||||||
|
// #ifdef H5
|
||||||
|
|
||||||
// 实际展示禁止编辑
|
// 实际展示禁止编辑
|
||||||
if (this.mode == '') return;
|
if (this.mode == '') return;
|
||||||
|
|
||||||
// 减少重复请求
|
// 减少重复请求
|
||||||
if (this.currentIndex == index) return;
|
if (this.currentIndex == index) return;
|
||||||
this.currentIndex = index;
|
this.currentIndex = index;
|
||||||
var data = JSON.stringify({
|
var data = JSON.stringify({
|
||||||
type: 'change',
|
type: 'change',
|
||||||
index,
|
index,
|
||||||
component: toRaw(component)
|
component: toRaw(component)
|
||||||
});
|
});
|
||||||
window.parent.postMessage(data, '*');
|
window.parent.postMessage(data, '*');
|
||||||
// #endif
|
// #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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
export default useDiyStore
|
export default useDiyStore
|
||||||
@ -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>
|
|
||||||
@ -1,42 +1,44 @@
|
|||||||
<template>
|
<template>
|
||||||
<u-popup :show="show" @close="show = false" mode="bottom" :round="10" :closeable="true">
|
<u-popup :show="show" @close="show = false" mode="bottom" :round="10" :closeable="true">
|
||||||
|
<view @touchmove.prevent.stop>
|
||||||
<view class="text-center p-[30rpx]">请选择地区</view>
|
<view class="text-center p-[30rpx]">请选择地区</view>
|
||||||
|
|
||||||
<view class="flex p-[30rpx] text-sm font-semibold">
|
<view class="flex p-[30rpx] text-sm font-semibold">
|
||||||
<view v-if="areaList.province.length" class="flex-1" :class="{'text-[var(--primary-color)]': currSelect == 'province'}" @click="currSelect = 'province'">
|
<view v-if="areaList.province.length" class="flex-1" :class="{'text-[var(--primary-color)]': currSelect == 'province'}" @click="currSelect = 'province'">
|
||||||
<view v-if="selected.province">{{ selected.province.name }}</view>
|
<view v-if="selected.province">{{ selected.province.name }}</view>
|
||||||
<view v-else>请选择</view>
|
<view v-else>请选择</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-if="areaList.city.length" class="flex-1" :class="{'text-[var(--primary-color)]': currSelect == 'city' }" @click="currSelect = 'city'">
|
<view v-if="areaList.city.length" class="flex-1" :class="{'text-[var(--primary-color)]': currSelect == 'city' }" @click="currSelect = 'city'">
|
||||||
<view v-if="selected.city">{{ selected.city.name }}</view>
|
<view v-if="selected.city">{{ selected.city.name }}</view>
|
||||||
<view v-else>请选择</view>
|
<view v-else>请选择</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-if="areaList.district.length" class="flex-1" :class="{'text-[var(--primary-color)]': currSelect == 'district' }" @click="currSelect = 'district'">
|
<view v-if="areaList.district.length" class="flex-1" :class="{'text-[var(--primary-color)]': currSelect == 'district' }" @click="currSelect = 'district'">
|
||||||
<view v-if="selected.district">{{ selected.district.name }}</view>
|
<view v-if="selected.district">{{ selected.district.name }}</view>
|
||||||
<view v-else>请选择</view>
|
<view v-else>请选择</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<scroll-view scroll-y="true" class="h-[50vh]">
|
||||||
|
<view class="flex p-[30rpx] pt-0 text-sm">
|
||||||
|
<view v-if="areaList.province.length" v-show="currSelect == 'province'">
|
||||||
|
<view v-for="item in areaList.province" class="leading-loose" :class="{'text-[var(--primary-color)]': selected.province && selected.province.id == item.id }"
|
||||||
|
@click="selected.province = item" >{{ item.name }}</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="areaList.city.length" v-show="currSelect == 'city'">
|
||||||
|
<view v-for="item in areaList.city" class="leading-loose" :class="{'text-[var(--primary-color)]': selected.city && selected.city.id == item.id }"
|
||||||
|
@click="selected.city = item">{{ item.name }}</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="areaList.district.length" v-show="currSelect == 'district'">
|
||||||
|
<view v-for="item in areaList.district" class="leading-loose" :class="{'text-[var(--primary-color)]': selected.district && selected.district.id == item.id }"
|
||||||
|
@click="selected.district = item">{{ item.name }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
<scroll-view scroll-y="true" class="h-[50vh]">
|
|
||||||
<view class="flex p-[30rpx] pt-0 text-sm">
|
|
||||||
<view v-if="areaList.province.length" v-show="currSelect == 'province'">
|
|
||||||
<view v-for="item in areaList.province" class="leading-loose" :class="{'text-[var(--primary-color)]': selected.province && selected.province.id == item.id }"
|
|
||||||
@click="selected.province = item" >{{ item.name }}</view>
|
|
||||||
</view>
|
|
||||||
<view v-if="areaList.city.length" v-show="currSelect == 'city'">
|
|
||||||
<view v-for="item in areaList.city" class="leading-loose" :class="{'text-[var(--primary-color)]': selected.city && selected.city.id == item.id }"
|
|
||||||
@click="selected.city = item">{{ item.name }}</view>
|
|
||||||
</view>
|
|
||||||
<view v-if="areaList.district.length" v-show="currSelect == 'district'">
|
|
||||||
<view v-for="item in areaList.district" class="leading-loose" :class="{'text-[var(--primary-color)]': selected.district && selected.district.id == item.id }"
|
|
||||||
@click="selected.district = item">{{ item.name }}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</scroll-view>
|
|
||||||
</u-popup>
|
</u-popup>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, computed, watch } from 'vue'
|
import { ref, reactive, watch } from 'vue'
|
||||||
import { getAreaListByPid, getAreaByCode } from '@/app/api/system'
|
import { getAreaListByPid, getAreaByCode } from '@/app/api/system'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
@ -60,11 +62,9 @@
|
|||||||
district: null
|
district: null
|
||||||
})
|
})
|
||||||
|
|
||||||
getAreaListByPid(0)
|
getAreaListByPid(0).then(({ data }) => {
|
||||||
.then(({ data }) => {
|
areaList.province = data
|
||||||
areaList.province = data
|
}).catch()
|
||||||
})
|
|
||||||
.catch()
|
|
||||||
|
|
||||||
watch(() => prop.areaId, (nval, oval)=> {
|
watch(() => prop.areaId, (nval, oval)=> {
|
||||||
if (nval && !oval) {
|
if (nval && !oval) {
|
||||||
@ -75,31 +75,31 @@
|
|||||||
})
|
})
|
||||||
.catch()
|
.catch()
|
||||||
}
|
}
|
||||||
})
|
},{
|
||||||
|
immediate:true
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听省变更
|
* 监听省变更
|
||||||
*/
|
*/
|
||||||
watch(() => selected.province, ()=> {
|
watch(() => selected.province, ()=> {
|
||||||
getAreaListByPid(selected.province.id)
|
getAreaListByPid(selected.province.id).then(({ data }) => {
|
||||||
.then(({ data }) => {
|
areaList.city = data
|
||||||
areaList.city = data
|
currSelect.value = 'city'
|
||||||
currSelect.value = 'city'
|
|
||||||
|
|
||||||
if (selected.city) {
|
if (selected.city) {
|
||||||
let isExist = false
|
let isExist = false
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
if (selected.city.id == data[i].id) {
|
if (selected.city.id == data[i].id) {
|
||||||
isExist = true
|
isExist = true
|
||||||
break
|
break
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isExist) {
|
|
||||||
selected.city = null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
if (!isExist) {
|
||||||
.catch()
|
selected.city = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).catch()
|
||||||
}, { deep: true })
|
}, { deep: true })
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -107,25 +107,23 @@
|
|||||||
*/
|
*/
|
||||||
watch(() => selected.city, (nval)=> {
|
watch(() => selected.city, (nval)=> {
|
||||||
if (nval) {
|
if (nval) {
|
||||||
getAreaListByPid(selected.city.id)
|
getAreaListByPid(selected.city.id).then(({ data }) => {
|
||||||
.then(({ data }) => {
|
areaList.district = data
|
||||||
areaList.district = data
|
currSelect.value = 'district'
|
||||||
currSelect.value = 'district'
|
|
||||||
|
|
||||||
if (selected.district) {
|
if (selected.district) {
|
||||||
let isExist = false
|
let isExist = false
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
if (selected.district.id == data[i].id) {
|
if (selected.district.id == data[i].id) {
|
||||||
isExist = true
|
isExist = true
|
||||||
break
|
break
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isExist) {
|
|
||||||
selected.district = null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
if (!isExist) {
|
||||||
.catch()
|
selected.district = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).catch()
|
||||||
} else {
|
} else {
|
||||||
areaList.district = []
|
areaList.district = []
|
||||||
selected.district = null
|
selected.district = null
|
||||||
|
|||||||
@ -8,23 +8,20 @@
|
|||||||
<view class="mx-[30rpx]">
|
<view class="mx-[30rpx]">
|
||||||
<view class="mt-[20rpx]">
|
<view class="mt-[20rpx]">
|
||||||
<u-form-item :label="t('headimg')" prop="headimg" :border-bottom="true">
|
<u-form-item :label="t('headimg')" prop="headimg" :border-bottom="true">
|
||||||
<button class="m-0 my-[10rpx] p-0 w-[140rpx] h-[140rpx]" open-type="chooseAvatar"
|
<button class="m-0 my-[10rpx] p-0 w-[140rpx] h-[140rpx]" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
|
||||||
@chooseavatar="onChooseAvatar">
|
|
||||||
<view class="w-full h-full flex items-center justify-center overflow-hidden">
|
<view class="w-full h-full flex items-center justify-center overflow-hidden">
|
||||||
<u-image :src="img(formData.headimg)" width="140rpx" v-if="formData.headimg"></u-image>
|
<u-image :src="img(formData.headimg)" width="140rpx" height="140rpx" v-if="formData.headimg" mode="aspectFill"></u-image>
|
||||||
<u-icon name="plus" v-else></u-icon>
|
<u-icon name="plus" v-else></u-icon>
|
||||||
</view>
|
</view>
|
||||||
</button>
|
</button>
|
||||||
</u-form-item>
|
</u-form-item>
|
||||||
<u-form-item :label=" t('nickname')" prop="nickname" :border-bottom="true">
|
<u-form-item :label=" t('nickname')" prop="nickname" :border-bottom="true">
|
||||||
<input type="nickname" v-model="formData.nickname" :placeholder="t('nicknamePlaceholder')"
|
<input type="nickname" v-model="formData.nickname" :placeholder="t('nicknamePlaceholder')" @blur="bindNickname">
|
||||||
@blur="bindNickname">
|
|
||||||
</u-form-item>
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="p-[30rpx] mt-[20rpx]">
|
<view class="p-[30rpx] mt-[20rpx]">
|
||||||
<u-button type="primary" :loading="loading" :text="t('confirm')" shape="circle"
|
<u-button type="primary" :loading="loading" :text="t('confirm')" shape="circle" @click="confirm"></u-button>
|
||||||
@click="confirm"></u-button>
|
|
||||||
</view>
|
</view>
|
||||||
</u-form>
|
</u-form>
|
||||||
</u-popup>
|
</u-popup>
|
||||||
@ -89,32 +86,28 @@
|
|||||||
const formRef = ref(null)
|
const formRef = ref(null)
|
||||||
|
|
||||||
const confirm = async () => {
|
const confirm = async () => {
|
||||||
formRef.value.validate().then(async () => {
|
formRef.value.validate().then(async() => {
|
||||||
if (loading.value) return
|
if (loading.value) return
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
||||||
// 修改头像
|
// 修改头像
|
||||||
await modifyMember({ field: 'headimg', value: formData.headimg })
|
await modifyMember({ field: 'headimg', value: formData.headimg }).then(() => {
|
||||||
.then(() => {
|
memberStore.info.headimg = formData.headimg
|
||||||
memberStore.info.headimg = formData.headimg
|
}).catch(() => {
|
||||||
})
|
loading.value = false
|
||||||
.catch(() => {
|
})
|
||||||
loading.value = false
|
if (!loading.value) return
|
||||||
})
|
|
||||||
if (!loading.value) return
|
|
||||||
|
|
||||||
// 修改昵称
|
// 修改昵称
|
||||||
modifyMember({ field: 'nickname', value: formData.nickname })
|
modifyMember({ field: 'nickname', value: formData.nickname }).then(() => {
|
||||||
.then(() => {
|
memberStore.info.nickname = formData.nickname
|
||||||
memberStore.info.nickname = formData.nickname
|
loading.value = false
|
||||||
loading.value = false
|
show.value = false
|
||||||
show.value = false
|
}).catch(() => {
|
||||||
})
|
loading.value = false
|
||||||
.catch(() => {
|
})
|
||||||
loading.value = false
|
})
|
||||||
})
|
}
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
show
|
show
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<u-popup :show="show" :round="10" @close="handleClose" :closeable="true" bgColor="#fff" zIndex="10081"
|
<u-popup :show="show" :round="10" @close="handleClose" :closeable="true" bgColor="#fff" zIndex="10081" :closeOnClickOverlay="false">
|
||||||
:closeOnClickOverlay="false">
|
<view class="flex flex-col h-[75vh]" v-if="payInfo" @touchmove.prevent.stop>
|
||||||
<view class="flex flex-col h-[75vh]" v-if="payInfo">
|
|
||||||
<view class="head">
|
<view class="head">
|
||||||
<view class="text-center py-[26rpx]">{{ t('pay.payTitle') }}</view>
|
<view class="text-center py-[26rpx]">{{ t('pay.payTitle') }}</view>
|
||||||
<view class="flex items-end justify-center w-full text-xl font-bold py-[20rpx]">
|
<view class="flex items-end justify-center w-full text-xl font-bold py-[20rpx]">
|
||||||
@ -12,12 +11,11 @@
|
|||||||
<scroll-view scroll-y="true" class="flex-1 pt-[20rpx]">
|
<scroll-view scroll-y="true" class="flex-1 pt-[20rpx]">
|
||||||
<view class="flex text-sm px-[30rpx] py-[20rpx]">
|
<view class="flex text-sm px-[30rpx] py-[20rpx]">
|
||||||
<view class="text-gray-500">{{ t('pay.orderInfo') }}</view>
|
<view class="text-gray-500">{{ t('pay.orderInfo') }}</view>
|
||||||
<view class="text-right flex-1 pl-[30rpx] truncate">{{ payInfo.body }}</view>
|
<view class="text-right flex-1 pl-[30rpx] using-hidden">{{ payInfo.body }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="mx-[30rpx] py-[10rpx] px-[30rpx] bg-white rounded-md bg-page">
|
<view class="mx-[30rpx] py-[10rpx] px-[30rpx] bg-white rounded-md bg-page">
|
||||||
<block v-if="payInfo.pay_type_list.length">
|
<block v-if="payInfo.pay_type_list.length">
|
||||||
<view class="pay-item py-[18rpx] flex items-center border-0 border-b border-solid border-[#eee]"
|
<view class="pay-item py-[18rpx] flex items-center border-0 border-b border-solid border-[#eee]" v-for="(item, index) in payInfo.pay_type_list" :key="index" @click="type = item.key">
|
||||||
v-for="(item, index) in payInfo.pay_type_list" :key="index" @click="type = item.key">
|
|
||||||
<u-image :src="img(item.icon)" width="50rpx" height="50rpx"></u-image>
|
<u-image :src="img(item.icon)" width="50rpx" height="50rpx"></u-image>
|
||||||
<view class="flex-1 px-[20rpx] text-sm font-bold">{{ item.name }}</view>
|
<view class="flex-1 px-[20rpx] text-sm font-bold">{{ item.name }}</view>
|
||||||
<u-icon name="checkbox-mark" color="var(--primary-color)" v-if="item.key == type"></u-icon>
|
<u-icon name="checkbox-mark" color="var(--primary-color)" v-if="item.key == type"></u-icon>
|
||||||
@ -27,8 +25,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
<view class="p-[30rpx]">
|
<view class="p-[30rpx]">
|
||||||
<u-button type="primary" :loading="loading" :text="t('pay.confirmPay')" shape="circle"
|
<u-button type="primary" :loading="loading" :text="t('pay.confirmPay')" shape="circle" @click="confirmPay"></u-button>
|
||||||
@click="confirmPay"></u-button>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</u-popup>
|
</u-popup>
|
||||||
@ -65,7 +62,8 @@
|
|||||||
pay({
|
pay({
|
||||||
trade_type: payInfo.value?.trade_type,
|
trade_type: payInfo.value?.trade_type,
|
||||||
trade_id: payInfo.value?.trade_id,
|
trade_id: payInfo.value?.trade_id,
|
||||||
type: type.value
|
type: type.value,
|
||||||
|
openid: uni.getStorageSync('openid') || ''
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
switch (type.value) {
|
switch (type.value) {
|
||||||
case 'wechatpay':
|
case 'wechatpay':
|
||||||
@ -111,6 +109,16 @@
|
|||||||
// #endif
|
// #endif
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
if (res.data.url) {
|
||||||
|
redirect({
|
||||||
|
url: res.data.url,
|
||||||
|
param: res.data.param || {},
|
||||||
|
mode: 'redirectTo',
|
||||||
|
success() {
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
toPayResult()
|
toPayResult()
|
||||||
}
|
}
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
@ -137,8 +145,10 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
const repeat = ref(false)
|
||||||
const open = (tradeType : string, tradeId : number, payReturn: string = '') => {
|
const open = (tradeType : string, tradeId : number, payReturn: string = '') => {
|
||||||
|
if (repeat.value) return
|
||||||
|
repeat.value = true
|
||||||
// 设置支付后跳转页面
|
// 设置支付后跳转页面
|
||||||
uni.setStorageSync('payReturn', encodeURIComponent(payReturn))
|
uni.setStorageSync('payReturn', encodeURIComponent(payReturn))
|
||||||
|
|
||||||
@ -155,11 +165,14 @@
|
|||||||
toPayResult()
|
toPayResult()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
type.value = data.pay_type_list[0] ? data.pay_type_list[0].key : ''
|
type.value = data.pay_type_list[0] ? data.pay_type_list[0].key : ''
|
||||||
show.value = true
|
show.value = true
|
||||||
|
repeat.value = false
|
||||||
|
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
repeat.value = false
|
||||||
})
|
})
|
||||||
.catch(() => { })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const toPayResult = ()=> {
|
const toPayResult = ()=> {
|
||||||
|
|||||||
344
uni-app/src/components/share-poster/share-poster.vue
Normal file
344
uni-app/src/components/share-poster/share-poster.vue
Normal file
@ -0,0 +1,344 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 分享弹窗 -->
|
||||||
|
<view @touchmove.prevent.stop class="share-popup">
|
||||||
|
<u-popup :show="sharePopupShow" type="bottom" @close="sharePopuClose" overlayOpacity="0.8">
|
||||||
|
<view @touchmove.prevent.stop>
|
||||||
|
<view class="poster-img-wrap" :style="{'top': shareTop}">
|
||||||
|
<image v-if="isPosterAnimation" class="poster-animation" :src="img('addon/shop/poster_animation.gif')" mode="aspectFit"></image>
|
||||||
|
<image v-if="isPosterImg" class="poster-img" :src="img(poster)" mode="aspectFit"></image>
|
||||||
|
</view>
|
||||||
|
<view class="share-content">
|
||||||
|
<!-- #ifdef MP || APP-PLUS -->
|
||||||
|
<view class="share-box">
|
||||||
|
<button class="share-btn" :plain="true" open-type="share">
|
||||||
|
<view class="text-[#07c160] iconfont iconweixin11"></view>
|
||||||
|
<text>分享给好友</text>
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="share-box">
|
||||||
|
<button class="share-btn" :plain="true" @click="saveGoodsPoster()">
|
||||||
|
<view class="text-[#07c160] iconfont iconpengyouquan"></view>
|
||||||
|
<text>保存海报</text>
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
<!-- #endif -->
|
||||||
|
|
||||||
|
<!-- #ifdef H5 -->
|
||||||
|
<view class="share-box" @click="copyUrl">
|
||||||
|
<button class="share-btn" :plain="true">
|
||||||
|
<view class="text-[#07c160] iconfont iconfuzhilianjie"></view>
|
||||||
|
<text>复制链接</text>
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
<!-- #endif -->
|
||||||
|
</view>
|
||||||
|
<view class="share-footer" @click="sharePopuClose"><text>取消分享</text></view>
|
||||||
|
</view>
|
||||||
|
</u-popup>
|
||||||
|
<u-popup :show="show" mode="center" :round="10" :closeable="true" @close="show = false" :safe-area-inset-bottom="false">
|
||||||
|
<view class="dialog-popup">
|
||||||
|
<view class="title">提示</view>
|
||||||
|
<view class="message">您拒绝了保存图片到相册的授权请求,无法保存图片到相册,如需正常使用,请授权之后再进行操作。</view>
|
||||||
|
<view class="action-wrap">
|
||||||
|
<view @click="closeDialog">取消</view>
|
||||||
|
<view>
|
||||||
|
<button type="default" class="authorization-btn" open-type="openSetting" @opensetting="closeDialog" hover-class="none">立即授权</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</u-popup>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, computed } from 'vue';
|
||||||
|
import { img, copy } from '@/utils/common';
|
||||||
|
import { getPoster } from '@/app/api/system'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
posterId: {
|
||||||
|
type: String || Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
posterType: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
posterParam: {
|
||||||
|
type: Object,
|
||||||
|
default: {}
|
||||||
|
},
|
||||||
|
copyUrl: { // 例 "/wap/addon/shop_fenxiao/pages/goods"
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
copyUrlParam: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
copy(data, () => {
|
||||||
|
sharePopupShow.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const openShare = ()=>{
|
||||||
|
sharePopupShow.value = true
|
||||||
|
goodsPosterShowFn();
|
||||||
|
}
|
||||||
|
|
||||||
|
//生成海报
|
||||||
|
let isPosterAnimation = ref(false)
|
||||||
|
let isPosterImg = ref(false)
|
||||||
|
// 获取分享海报
|
||||||
|
let poster = ref('');
|
||||||
|
const goodsPosterShowFn = () => {
|
||||||
|
isPosterAnimation.value = true;
|
||||||
|
isPosterImg.value = false;
|
||||||
|
let obj = {
|
||||||
|
id: props.posterId,
|
||||||
|
type: props.posterType,
|
||||||
|
param: props.posterParam
|
||||||
|
}
|
||||||
|
let startTime = Date.parse(new Date());
|
||||||
|
getPoster(obj).then((res:any) => {
|
||||||
|
poster.value = res.data && img(res.data) || '';
|
||||||
|
|
||||||
|
let endTime = Date.parse(new Date());
|
||||||
|
let time = endTime-startTime;
|
||||||
|
let periodTime = 2200;
|
||||||
|
if(time < periodTime){
|
||||||
|
setTimeout(()=>{
|
||||||
|
isPosterAnimation.value = false;
|
||||||
|
isPosterImg.value = true;
|
||||||
|
},(periodTime-time))
|
||||||
|
}else{
|
||||||
|
isPosterAnimation.value = false;
|
||||||
|
isPosterImg.value = true;
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
sharePopuClose();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let show = ref(false);
|
||||||
|
|
||||||
|
const closeDialog = ()=> {
|
||||||
|
show.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// #ifdef MP || APP-PLUS
|
||||||
|
//小程序中保存海报
|
||||||
|
const saveGoodsPoster = () => {
|
||||||
|
let url = img(poster.value);
|
||||||
|
uni.downloadFile({
|
||||||
|
url: url,
|
||||||
|
success: (res) => {
|
||||||
|
if (res.errMsg == "downloadFile:ok") {
|
||||||
|
uni.saveImageToPhotosAlbum({
|
||||||
|
filePath: res.tempFilePath,
|
||||||
|
success: () => {
|
||||||
|
uni.showToast({
|
||||||
|
title: '保存成功',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
if(err.errno == 104){
|
||||||
|
let msg = '用户未授权隐私权限,将图像保存到相册失败';
|
||||||
|
uni.showToast({title: msg, icon: 'none'})
|
||||||
|
}else if (err.errMsg == "saveImageToPhotosAlbum:fail auth deny" ||
|
||||||
|
err.errMsg == "saveImageToPhotosAlbum:fail:auth denied") {
|
||||||
|
show.value = true;
|
||||||
|
}else if(err.errMsg == "saveImageToPhotosAlbum:fail cancel"){
|
||||||
|
let msg = '用户取消将图片保存到相册';
|
||||||
|
uni.showToast({title: msg, icon: 'none'})
|
||||||
|
}else{
|
||||||
|
uni.showToast({title: err.errMsg, icon: 'none'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
uni.showToast({
|
||||||
|
title: err.errMsg,
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
let shareTop = ref(0)
|
||||||
|
/************ 获取微信头部-start ****************/
|
||||||
|
// 获取系统状态栏的高度
|
||||||
|
let menuButtonInfo = {};
|
||||||
|
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API,尚未兼容)
|
||||||
|
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
|
||||||
|
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
||||||
|
shareTop.value = menuButtonInfo.top + menuButtonInfo.height + 'px';
|
||||||
|
// #endif
|
||||||
|
/************ 获取微信头部-end ****************/
|
||||||
|
|
||||||
|
const sharePopuClose = ()=>{
|
||||||
|
sharePopupShow.value = false;
|
||||||
|
isPosterAnimation.value = false;
|
||||||
|
isPosterImg.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
openShare
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.share-popup {
|
||||||
|
:deep(.u-transition), :deep(.u-popup__content){
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
.share-content {
|
||||||
|
border-top-left-radius: 40rpx;
|
||||||
|
border-top-right-radius: 40rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
display: -webkit-flex;
|
||||||
|
-webkit-flex-wrap: wrap;
|
||||||
|
-moz-flex-wrap: wrap;
|
||||||
|
-ms-flex-wrap: wrap;
|
||||||
|
-o-flex-wrap: wrap;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
padding: 40rpx 15rpx ;
|
||||||
|
background-color: #fff;
|
||||||
|
|
||||||
|
.share-box {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.share-btn {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: none;
|
||||||
|
line-height: 1;
|
||||||
|
height: auto;
|
||||||
|
background: none;
|
||||||
|
|
||||||
|
text {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
display: block;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
font-size: 80rpx;
|
||||||
|
line-height: initial;
|
||||||
|
}
|
||||||
|
.icon-fuzhilianjie,
|
||||||
|
.icon-pengyouquan,
|
||||||
|
.icon-haowuquan,
|
||||||
|
.icon-share-friend {
|
||||||
|
color: #07c160;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.share-footer {
|
||||||
|
background-color: #fff;
|
||||||
|
height: 90rpx;
|
||||||
|
line-height: 90rpx;
|
||||||
|
border-top: 2rpx solid #eee;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.poster-img-wrap{
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: calc(constant(safe-area-inset-bottom) + 300rpx); //300是海报弹窗下面高度的问题
|
||||||
|
bottom: calc(env(safe-area-inset-bottom) + 300rpx);
|
||||||
|
right: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
.poster-img{
|
||||||
|
width: 80%;
|
||||||
|
height: 80%;
|
||||||
|
}
|
||||||
|
.poster-animation{
|
||||||
|
width: 60%;
|
||||||
|
height: 65%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-popup {
|
||||||
|
width: 580rpx;
|
||||||
|
background: #fff;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
height: initial;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
padding: 30rpx 30rpx 0 30rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
padding: 0 30rpx;
|
||||||
|
color: #666;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1.3;
|
||||||
|
margin-top: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-wrap {
|
||||||
|
margin-top: 50rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
display: flex;
|
||||||
|
border-top: 2rpx solid #eee;
|
||||||
|
|
||||||
|
&>view {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 80rpx;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
border-right: 2rpx solid #eee;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border: none;
|
||||||
|
line-height: 80rpx;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.authorization-btn{
|
||||||
|
background-color: #07c160;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 28rpx;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1,14 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="{'text-primary': sendSms.canGetCode.value, 'text-gray-300': !sendSms.canGetCode.value}" @click="handleSend">{{ sendSms.tips.value }}</view>
|
<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-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"
|
<u-modal :show="show" :title="t('captchaTitle')" :confirm-text="t('confirm')" :cancel-text="t('cancel')" :show-cancel-button="true" @cancel="show = false" @confirm="handleConfirm">
|
||||||
@cancel="show = false" @confirm="handleConfirm">
|
|
||||||
<view class="flex mt-[20rpx]">
|
<view class="flex mt-[20rpx]">
|
||||||
<u-input
|
<u-input :placeholder="t('captchaPlaceholder')" border="surround" v-model="formData.captcha_code"></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>
|
<image :src="captcha.image.value" class="h-[76rpx] ml-[20rpx]" mode="heightFix" @click="captcha.refresh()"></image>
|
||||||
</view>
|
</view>
|
||||||
</u-modal>
|
</u-modal>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<template v-if="tabbar && Object.keys(tabbar).length">
|
<template v-if="tabbar && Object.keys(tabbar).length">
|
||||||
<u-tabbar :value="value" @change="tabbarChange" zIndex="9999" :fixed="true" :placeholder="true" :safeAreaInsetBottom="true"
|
<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">
|
<block v-for="item in tabbar.value.list">
|
||||||
<u-tabbar-item class="py-[5rpx]" :style="{'background-color': tabbar.value.backgroundColor}" :text="item.text"
|
<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"
|
:icon="img(value == item.link.url ? item.iconSelectPath : item.iconPath)" :name="item.link.url"
|
||||||
@ -18,8 +18,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
import { ref,reactive,computed,watch } from 'vue'
|
||||||
import { redirect, currRoute, img } from '@/utils/common'
|
import { redirect, currRoute,currShareRoute, img } from '@/utils/common'
|
||||||
import useConfigStore from '@/stores/config'
|
import useConfigStore from '@/stores/config'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -29,23 +29,83 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if(props.addon){
|
let addon:any = props.addon;
|
||||||
const configStore = useConfigStore()
|
|
||||||
configStore.getTabbarConfig(props.addon)
|
const configStore = useConfigStore()
|
||||||
|
if(!addon && configStore.addon){
|
||||||
|
addon = configStore.addon;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tabbar = computed(() => {
|
const tabbar:any = reactive({})
|
||||||
return useConfigStore().tabbar
|
|
||||||
})
|
|
||||||
|
|
||||||
|
const setTabbar = ()=>{
|
||||||
|
let list = useConfigStore().tabbarList;
|
||||||
|
if(list.length == 1){
|
||||||
|
Object.assign(tabbar,list[0]);
|
||||||
|
}else{
|
||||||
|
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 }
|
||||||
|
)
|
||||||
|
|
||||||
|
if(!props.addon) {
|
||||||
|
watch(
|
||||||
|
() => useConfigStore().tabbarList,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue) {
|
||||||
|
setTabbar()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
, { deep: true, immediate: true }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const value = computed(() => {
|
const value = computed(() => {
|
||||||
return '/' + currRoute()
|
let query:any = currShareRoute().params;
|
||||||
|
let str = [];
|
||||||
|
for (let key in query) {
|
||||||
|
str.push(key + '=' + query[key]);
|
||||||
|
}
|
||||||
|
return '/' + currRoute() + (str.length > 0 ? '?' + str.join('&') : '')
|
||||||
})
|
})
|
||||||
|
|
||||||
const tabbarChange = (name : string) => {
|
const tabbarChange = (url : string) => {
|
||||||
redirect({ url: `${name}`,mode: 'reLaunch' })
|
// 外部链接
|
||||||
|
if (url.indexOf('http') != -1 || url.indexOf('http') != -1) {
|
||||||
|
|
||||||
|
// #ifdef H5
|
||||||
|
window.location.href = url;
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef MP
|
||||||
|
redirect({
|
||||||
|
url: '/app/pages/webview/index',
|
||||||
|
param: { src: encodeURIComponent(url) }
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
} else {
|
||||||
|
redirect({ url,mode: 'reLaunch' })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -1,12 +1,59 @@
|
|||||||
<template>
|
<template>
|
||||||
<view>
|
<!-- diyStore.mode !='decorate' && topStatusBarData topStatusBarData.style == 'style-5 为了兼容风格五 -->
|
||||||
<!-- #ifdef MP-WEIXIN -->
|
<view class="ns-navbar-wrap" v-if="diyStore.mode !='decorate' && topStatusBarData || diyStore.mode =='decorate' && topStatusBarData && topStatusBarData.style == 'style-5' " :class="topStatusBarData.style">
|
||||||
<view class="flex items-center justify-center fixed left-0 right-0 z-10 bg-[#fff]" :style="navbarInnerStyle">
|
<view class="u-navbar" :style="{ backgroundColor: bgColor}">
|
||||||
<text v-if="props.param.isShowArrow" class="iconfont iconjiantou3 absolute" :style="navbarInnerArrowStyle" @click="goback()"></text>
|
<view class="navbar-inner" :style="{ width: '100%', height: placeholderHeight + 'px' }">
|
||||||
<text class="truncate" :style="{color:props.param.titleColor}">{{props.title}}</text>
|
<view v-if="topStatusBarData.style == 'style-1'" class="content-wrap" :class="[topStatusBarData.textAlign]" :style="navbarInnerStyle">
|
||||||
|
<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="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>
|
||||||
|
</view>
|
||||||
|
<view :style="{ color: topStatusBarData.textColor }">{{ data.title }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="topStatusBarData.style == 'style-3'" :style="navbarInnerStyle" class="content-wrap">
|
||||||
|
<view v-if="isBack && isBackShow" class="back-wrap 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="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 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="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 text-[26px] nc-iconfont nc-icon-zuoV6xx" :style="{ color: topStatusBarData.textColor || titleColor }" @tap="goBack"></view>
|
||||||
|
</view>
|
||||||
|
<!-- #endif -->
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- 风格5,填充 -->
|
||||||
|
<view v-if="topStatusBarData.style == 'style-5'" :style="style5Height"></view>
|
||||||
|
|
||||||
<!-- 解决fixed定位后导航栏塌陷的问题 -->
|
<!-- 解决fixed定位后导航栏塌陷的问题 -->
|
||||||
<view :style="navbarInnerStyle"></view>
|
<view class="u-navbar-placeholder" :style="{ width: '100%', paddingTop: placeholderHeight + 'px' }"></view>
|
||||||
|
|
||||||
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
|
<!-- 小程序隐私协议 -->
|
||||||
|
<wx-privacy-popup ref="wxPrivacyPopup"></wx-privacy-popup>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
@ -21,38 +68,79 @@ let menuButtonInfo = {};
|
|||||||
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
import { ref, reactive, computed } from 'vue';
|
import { ref, computed, watch, onMounted, getCurrentInstance, nextTick } from 'vue';
|
||||||
import { redirect } from '@/utils/common';
|
import { img, getLocation, locationStorage } from '@/utils/common';
|
||||||
|
import { getAddressByLatlng } from '@/app/api/system';
|
||||||
|
import useSystemStore from '@/stores/system';
|
||||||
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
import manifestJson from '@/manifest.json'
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
|
||||||
// param是一个对象{arrowLink => 箭头链接,isShowArrow => 箭头是否显示,tabbarBg => 背景颜色}
|
// param是一个对象{arrowLink => 箭头链接,isShowArrow => 箭头是否显示,tabbarBg => 背景颜色}
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
title: {
|
data: {
|
||||||
type: String,
|
|
||||||
default: '首页'
|
|
||||||
},
|
|
||||||
param: {
|
|
||||||
type: Object,
|
type: Object,
|
||||||
default: {
|
default: {}
|
||||||
arrowLink: '',
|
},
|
||||||
isShowArrow: false,
|
// 标题的颜色
|
||||||
arrowColor:'#000',
|
titleColor: {
|
||||||
titleColor:'#000',
|
type: String,
|
||||||
tabbarBg: '#fff'
|
default: '#606266'
|
||||||
}
|
},
|
||||||
|
// 自定义返回逻辑
|
||||||
|
customBack: {
|
||||||
|
type: Function,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
scrollTop: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: '0'
|
||||||
|
},
|
||||||
|
// 是否显示导航栏左边返回图标和辅助文字
|
||||||
|
isBack: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const data = computed(() => {
|
||||||
|
return props.data;
|
||||||
|
});
|
||||||
|
const topStatusBarData = computed(() => {
|
||||||
|
if(props.data && props.data.topStatusBar)
|
||||||
|
return props.data.topStatusBar;
|
||||||
|
});
|
||||||
|
|
||||||
// 导航栏内部盒子的样式
|
// 导航栏内部盒子的样式
|
||||||
const navbarInnerStyle = computed(() => {
|
const navbarInnerStyle = computed(() => {
|
||||||
let style = '';
|
let style = '';
|
||||||
// 导航栏宽度,如果在小程序下,导航栏宽度为胶囊的左边到屏幕左边的距离
|
|
||||||
|
if(props.isBack && isBackShow.value){
|
||||||
|
style += 'padding-left: 30rpx;';//30=>右边留边 44=>箭头宽度 10=>箭头的右maring
|
||||||
|
if(topStatusBarData.value.style == 'style-1') //样式一需要居中需要有右边padding辅助
|
||||||
|
style += 'padding-right:' + (40+30+10) + 'rpx;'; //30=>左边留边 44=>箭头宽度 10=>箭头的右maring
|
||||||
|
}else{
|
||||||
|
if(topStatusBarData.value.style == 'style-1') //样式一需要居中需要有右边padding辅助
|
||||||
|
style += 'padding-right: 30rpx;'; //右边留边
|
||||||
|
style += 'padding-left: 30rpx;'; //左边留边
|
||||||
|
}
|
||||||
// #ifdef MP
|
// #ifdef MP
|
||||||
let rightButtonWidth = menuButtonInfo.width ? menuButtonInfo.width * 2 + 'rpx' : '70rpx';
|
// 导航栏宽度,如果在小程序下,导航栏宽度为胶囊的左边到屏幕左边的距离
|
||||||
style += 'height:' + menuButtonInfo.height + 'px;';
|
style += 'height:' + menuButtonInfo.height + 'px;';
|
||||||
style += 'padding-right:calc(' + rightButtonWidth + ' + 30rpx);';
|
|
||||||
style += 'padding-left:calc(' + rightButtonWidth + ' + 30rpx);';
|
|
||||||
style += 'padding-top:' + menuButtonInfo.top + 'px;';
|
style += 'padding-top:' + menuButtonInfo.top + 'px;';
|
||||||
style += 'padding-bottom: 8px;';
|
style += 'padding-bottom: 8px;';
|
||||||
style += 'background:'+ props.param.tabbarBg +';';
|
// #endif
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 样式一的字体大小
|
||||||
|
const styleOneFontSize = computed(() => {
|
||||||
|
let style = '';
|
||||||
|
|
||||||
|
// #ifdef H5
|
||||||
|
style += 'font-size: 28rpx;';
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP
|
||||||
style += 'font-size: 32rpx;';
|
style += 'font-size: 32rpx;';
|
||||||
if (platform === 'ios') {
|
if (platform === 'ios') {
|
||||||
// 苹果(iOS)设备
|
// 苹果(iOS)设备
|
||||||
@ -62,42 +150,378 @@ const navbarInnerStyle = computed(() => {
|
|||||||
style += 'font-size: 36rpx;';
|
style += 'font-size: 36rpx;';
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
return style;
|
style += `color: ${topStatusBarData.value.textColor};`;
|
||||||
})
|
if(topStatusBarData.value.style == 'style-1'){
|
||||||
|
style += `text-align: ${topStatusBarData.value.textAlign};`;
|
||||||
// 导航栏内部盒子的样式
|
|
||||||
const navbarInnerArrowStyle = computed(() => {
|
|
||||||
let style = '';
|
|
||||||
// 导航栏宽度,如果在小程序下,导航栏宽度为胶囊的左边到屏幕左边的距离
|
|
||||||
// #ifdef MP
|
|
||||||
style += "padding-left: 10rpx;" //1、增加点击面积,2、增加间距
|
|
||||||
style += "padding-right: 10rpx;" //1、增加点击面积
|
|
||||||
style += 'left:calc( 100vw - ' + menuButtonInfo.right + 'px);';
|
|
||||||
style += 'font-size: 32rpx;';
|
|
||||||
style += 'font-weight: bold;';
|
|
||||||
style += 'color:'+ props.param.arrowColor +';';
|
|
||||||
if (platform === 'ios') {
|
|
||||||
// 苹果(iOS)设备
|
|
||||||
style += 'font-weight: 700;';
|
|
||||||
} else if (platform === 'android') {
|
|
||||||
// 安卓(Android)设备
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// #endif
|
|
||||||
return style;
|
return style;
|
||||||
})
|
})
|
||||||
|
|
||||||
// 返回上一页
|
const bgColor = computed(() => {
|
||||||
const goback=()=> {
|
var color = '';
|
||||||
if(!props.param.arrowLink){
|
if (topStatusBarData.value.isTransparent) {
|
||||||
uni.navigateBack({
|
// 顶部透明
|
||||||
delta: 1
|
color = 'transparent';
|
||||||
});
|
if (props.scrollTop) {
|
||||||
}else{
|
color = topStatusBarData.value.bgColor;
|
||||||
redirect({ url: props.param.arrowLink })
|
} else {
|
||||||
|
color = 'transparent';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
color = '#fff';
|
||||||
|
}
|
||||||
|
|
||||||
|
return color;
|
||||||
|
})
|
||||||
|
|
||||||
|
/******************************* 返回按钮-start ***********************/
|
||||||
|
let isBackShow = ref(false);
|
||||||
|
let pages = getCurrentPages();
|
||||||
|
|
||||||
|
// 返回按钮的函数
|
||||||
|
const goBack = () => {
|
||||||
|
// 如果自定义了点击返回按钮的函数,则执行,否则执行返回逻辑
|
||||||
|
if (typeof props.customBack === 'function') {
|
||||||
|
props.customBack();
|
||||||
|
} else {
|
||||||
|
uni.navigateBack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/******************************* 返回按钮-end ***********************/
|
||||||
|
|
||||||
|
// 微信胶囊宽度+right
|
||||||
|
const capsuleWidth = computed(() => {
|
||||||
|
let width = `calc(100vw - ${menuButtonInfo.right}px + ${menuButtonInfo.width}px + 10px)`;
|
||||||
|
return width;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 导航栏塌陷的高度
|
||||||
|
let placeholderHeight = ref(0);
|
||||||
|
const instance = getCurrentInstance();
|
||||||
|
const navbarPlaceholderHeight = () => {
|
||||||
|
nextTick(() => {
|
||||||
|
const query = uni.createSelectorQuery().in(instance);
|
||||||
|
query.select('.ns-navbar-wrap .u-navbar .content-wrap').boundingClientRect(data => {
|
||||||
|
placeholderHeight.value = data ? data.height : 0;
|
||||||
|
diyStore.topTabarHeight = placeholderHeight.value;
|
||||||
|
}).exec();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************* 定位-start ***********************/
|
||||||
|
// 获取地图配置
|
||||||
|
const systemStore = useSystemStore();
|
||||||
|
let currentPosition = ref('定位中...')
|
||||||
|
let mapConfig = uni.getStorageSync('mapConfig');
|
||||||
|
|
||||||
|
const initPosition = () =>{
|
||||||
|
// #ifdef H5
|
||||||
|
if (getQueryVariable('latng')) {
|
||||||
|
currentPosition.value = "定位中..."
|
||||||
|
let locationInfo = systemStore.location;
|
||||||
|
var tempArr = getQueryVariable('latng').split(',');
|
||||||
|
locationInfo.latitude = tempArr[0];
|
||||||
|
locationInfo.longitude = tempArr[1];
|
||||||
|
systemStore.setLocation(locationInfo);
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
currentPosition.value = '定位中...';
|
||||||
|
if(uni.getStorageSync('addressByLatlng')){
|
||||||
|
currentPosition.value = uni.getStorageSync('addressByLatlng').formatted_addresses.recommend;
|
||||||
|
}
|
||||||
|
// 定位信息过期后,重新获取定位
|
||||||
|
if(mapConfig.is_open == 1 && locationStorage() && locationStorage().is_expired) {
|
||||||
|
getLocation({
|
||||||
|
fail: (res) => {
|
||||||
|
// 拒绝定位,进入默认总店
|
||||||
|
currentPosition.value = "定位中..."
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(() => systemStore.location, (nval, oval)=> {
|
||||||
|
if (nval.latitude && nval.longitude) {
|
||||||
|
getAddressByLatlngFn()
|
||||||
|
}else{
|
||||||
|
currentPosition.value = "定位中..."
|
||||||
|
}
|
||||||
|
},{deep:true})
|
||||||
|
|
||||||
|
// 根据经纬度获取位置
|
||||||
|
const getAddressByLatlngFn = () => {
|
||||||
|
let data = {
|
||||||
|
latlng: ''
|
||||||
|
};
|
||||||
|
data.latlng = systemStore.location.latitude + ',' + systemStore.location.longitude ;
|
||||||
|
getAddressByLatlng(data).then((res: any) => {
|
||||||
|
if (res.data && Object.keys(res.data).length) {
|
||||||
|
currentPosition.value = res.data.formatted_addresses.recommend; // 结合知名地点形成的描述性地址,更具人性化特点
|
||||||
|
uni.setStorageSync('addressByLatlng', res.data);
|
||||||
|
} else {
|
||||||
|
currentPosition.value = '定位中...';
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开地图重新选择位置
|
||||||
|
const reposition = () => {
|
||||||
|
// #ifdef MP
|
||||||
|
uni.chooseLocation({
|
||||||
|
success: (res) => {
|
||||||
|
var urlencode = JSON.parse(JSON.stringify(systemStore.location));
|
||||||
|
urlencode = Object.assign(urlencode,res)
|
||||||
|
systemStore.setLocation(urlencode);
|
||||||
|
},
|
||||||
|
fail: (res)=>{
|
||||||
|
// 在隐私协议中没有声明chooseLocation:fail api作用域
|
||||||
|
if(res.errMsg && res.errno) {
|
||||||
|
if(res.errno == 104){
|
||||||
|
let msg = '用户未授权隐私权限,选择位置失败';
|
||||||
|
uni.showToast({title: msg, icon: 'none'})
|
||||||
|
}else if(res.errno == 112){
|
||||||
|
let msg = '隐私协议中未声明,打开地图选择位置失败';
|
||||||
|
uni.showToast({title: msg, icon: 'none'})
|
||||||
|
}else {
|
||||||
|
uni.showToast({title: res.errMsg, icon: 'none'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef H5
|
||||||
|
let backurl = location.origin + location.pathname;
|
||||||
|
window.location.href = 'https://apis.map.qq.com/tools/locpicker?search=1&type=0&backurl=' + encodeURIComponent(backurl) + '&key=' + manifestJson.h5.sdkConfigs.maps.qqmap.key + '&referer=myapp';
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
|
||||||
|
const getQueryVariable = (variable:any)=> {
|
||||||
|
var query = window.location.search.substring(1);
|
||||||
|
var vars = query.split('&');
|
||||||
|
for (var i = 0; i < vars.length; i++) {
|
||||||
|
var pair = vars[i].split('=');
|
||||||
|
if (pair[0] == variable) {
|
||||||
|
return pair[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/******************************* 定位-end ***********************/
|
||||||
|
|
||||||
|
/******************************* 风格五-start ***********************/
|
||||||
|
let style5Height = ref('')
|
||||||
|
watch(() => topStatusBarData.value.style, (nval, oval)=> {
|
||||||
|
if(topStatusBarData.value.style == 'style-5'){
|
||||||
|
style5Height.value = '';
|
||||||
|
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-bottom、padding-top]
|
||||||
|
style5Height.value += `padding-top:${ sysHeight }px;`
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},{immediate: true, deep:true})
|
||||||
|
/******************************* 风格五-end ***********************/
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
navbarPlaceholderHeight();
|
||||||
|
if (pages.length > 1) {
|
||||||
|
isBackShow.value = true;
|
||||||
|
}
|
||||||
|
if(topStatusBarData.value && topStatusBarData.value.style == 'style-4') {
|
||||||
|
initPosition();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 页面onShow调用时,也会触发改方法
|
||||||
|
const refresh = ()=>{
|
||||||
|
if(topStatusBarData.value && topStatusBarData.value.style == 'style-4') {
|
||||||
|
initPosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表示该组件,需要判断滚动超出1时,需要做相对应反应
|
||||||
|
defineExpose({
|
||||||
|
refresh,
|
||||||
|
scrollValue: 1
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
/* #ifdef H5 */
|
||||||
|
.style-1,
|
||||||
|
.style-2,
|
||||||
|
.style-3 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
.u-navbar {
|
||||||
|
width: 100%;
|
||||||
|
transition: background 0.3s;
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 991;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-inner {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
position: relative;
|
||||||
|
align-items: center;
|
||||||
|
// padding-bottom: 20rpx;
|
||||||
|
// /* #ifdef H5 */
|
||||||
|
// padding-bottom: 40rpx;
|
||||||
|
// /* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-wrap {
|
||||||
|
padding-right: 10rpx;
|
||||||
|
line-height: 1;
|
||||||
|
.iconfont {
|
||||||
|
font-size: 40rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrap {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
flex: 1;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
height: 60rpx;
|
||||||
|
text-align: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-wrap {
|
||||||
|
line-height: 1;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ns-navbar-wrap {
|
||||||
|
|
||||||
|
&.style-2 {
|
||||||
|
.content-wrap {
|
||||||
|
.title-wrap {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
>view {
|
||||||
|
height: 56rpx;
|
||||||
|
line-height: 56rpx;
|
||||||
|
max-width: 300rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
|
||||||
|
image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
max-width: 300rpx;
|
||||||
|
overflow: hidden; //超出的文本隐藏
|
||||||
|
text-overflow: ellipsis; //用省略号显示
|
||||||
|
white-space: nowrap; //不换行
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.style-3 {
|
||||||
|
.content-wrap {
|
||||||
|
.title-wrap {
|
||||||
|
height: 60rpx;
|
||||||
|
max-width: 170rpx;
|
||||||
|
flex: initial;
|
||||||
|
text-align: center;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
|
||||||
|
image {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.search {
|
||||||
|
flex: 1;
|
||||||
|
padding-right: 20rpx;
|
||||||
|
padding-left: 62rpx;
|
||||||
|
position: relative;
|
||||||
|
background-color: #fff;
|
||||||
|
text-align: left;
|
||||||
|
border-radius: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
line-height: 60rpx;
|
||||||
|
border: 1px solid #eeeeee;
|
||||||
|
color: rgb(102, 102, 102);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
text{
|
||||||
|
overflow: hidden; //超出的文本隐藏
|
||||||
|
text-overflow: ellipsis; //用省略号显示
|
||||||
|
white-space: nowrap; //不换行
|
||||||
|
}
|
||||||
|
.iconfont {
|
||||||
|
color: #909399;
|
||||||
|
font-size: 32rpx;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.style-4 {
|
||||||
|
.content-wrap {
|
||||||
|
top: 0;
|
||||||
|
text-align: left;
|
||||||
|
padding-left: 30rpx;
|
||||||
|
/* #ifdef H5 */
|
||||||
|
padding-top: 10rpx;
|
||||||
|
padding-bottom: 10rpx;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
.title-wrap {
|
||||||
|
flex: none;
|
||||||
|
margin: 0 10rpx;
|
||||||
|
max-width: 360rpx;
|
||||||
|
font-size: 27rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nearby-store-name {
|
||||||
|
margin: 0 10rpx;
|
||||||
|
background: rgba(0, 0, 0, .2);
|
||||||
|
font-size: 22rpx;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
padding: 10rpx 20rpx;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
236
uni-app/src/components/wx-privacy-popup/wx-privacy-popup.vue
Normal file
236
uni-app/src/components/wx-privacy-popup/wx-privacy-popup.vue
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
<template>
|
||||||
|
<view v-if="showPop">
|
||||||
|
<view class="privacy-mask">
|
||||||
|
<view class="privacy-wrap">
|
||||||
|
<view class="privacy-title">用户隐私保护提示</view>
|
||||||
|
<view class="privacy-desc">
|
||||||
|
感谢您使用本小程序,在使用前您应当阅读并同意
|
||||||
|
<text class="privacy-link" @tap="openPrivacyContract">{{privacyContractName}}</text>,
|
||||||
|
当点击同意并继续时,即表示您已理解并同意该条款内容,该条款将对您产生法律约束力;如您不同意,将无法继续使用小程序相关功能。
|
||||||
|
</view>
|
||||||
|
<view class="privacy-button-flex">
|
||||||
|
<button class="privacy-button-btn bg-disagree" @tap="handleDisagree">不同意</button>
|
||||||
|
<button id="agree-btn" class="privacy-button-btn bg-agree" open-type="agreePrivacyAuthorization" @agreeprivacyauthorization="handleAgree">同意并继续</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import useConfigStore from "@/stores/config";
|
||||||
|
|
||||||
|
const agree = ref(false)
|
||||||
|
const showPop = ref(false)
|
||||||
|
const privacyAuthorization = ref(null)
|
||||||
|
|
||||||
|
const privacyResolves = new Set()
|
||||||
|
const closeOtherPagePopUpHooks = new Set()
|
||||||
|
|
||||||
|
const privacyContractName = ref('用户隐私保护指引')
|
||||||
|
|
||||||
|
const emits = defineEmits(['agree','disagree'])
|
||||||
|
|
||||||
|
// 监听何时需要提示用户阅读隐私政策
|
||||||
|
const init = ()=>{
|
||||||
|
if (wx.onNeedPrivacyAuthorization) {
|
||||||
|
wx.onNeedPrivacyAuthorization((resolve) => {
|
||||||
|
if (typeof privacyAuthorization.value === 'function') {
|
||||||
|
privacyAuthorization.value(resolve)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//初始化监听程序
|
||||||
|
const curPageShow = ()=> {
|
||||||
|
privacyAuthorization.value = resolve => {
|
||||||
|
privacyResolves.add(resolve)
|
||||||
|
//打开弹窗
|
||||||
|
popUp()
|
||||||
|
// 额外逻辑:当前页面的隐私弹窗弹起的时候,关掉其他页面的隐私弹窗
|
||||||
|
closeOtherPagePopUp(disPopUp)
|
||||||
|
}
|
||||||
|
closeOtherPagePopUpHooks.add(disPopUp)
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(()=>{
|
||||||
|
//查询微信侧记录的用户是否有待同意的隐私政策信息
|
||||||
|
try {
|
||||||
|
wx.getPrivacySetting({
|
||||||
|
success(res:any) {
|
||||||
|
// console.log('隐私政策信息', res);
|
||||||
|
// console.log(res.privacyContractName);
|
||||||
|
privacyContractName.value = res.privacyContractName
|
||||||
|
}
|
||||||
|
});
|
||||||
|
init();
|
||||||
|
curPageShow()
|
||||||
|
} catch (e) {
|
||||||
|
// console.log("=========低版本基础库==========")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//打开隐私协议
|
||||||
|
const openPrivacyContract = ()=> {
|
||||||
|
wx.openPrivacyContract({
|
||||||
|
success(res) {
|
||||||
|
// console.log('打开隐私协议', res);
|
||||||
|
},
|
||||||
|
fail(err) {
|
||||||
|
// console.error('打开隐私协议失败', err)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 额外逻辑:当前页面的隐私弹窗弹起的时候,关掉其他页面的隐私弹窗
|
||||||
|
const closeOtherPagePopUp = (closePopUp:any)=> {
|
||||||
|
closeOtherPagePopUpHooks.forEach((hook:any) => {
|
||||||
|
if (closePopUp !== hook) {
|
||||||
|
hook()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不同意
|
||||||
|
const handleDisagree = ()=> {
|
||||||
|
privacyResolves.forEach(resolve => {
|
||||||
|
resolve({
|
||||||
|
event: 'disagree',
|
||||||
|
})
|
||||||
|
})
|
||||||
|
privacyResolves.clear()
|
||||||
|
//关闭弹窗
|
||||||
|
disPopUp()
|
||||||
|
//退出小程序
|
||||||
|
uni.showModal({
|
||||||
|
content: '未同意隐私协议,无法使用相关功能',
|
||||||
|
confirmColor: useConfigStore().themeColor['--primary-color'],
|
||||||
|
success: () => {
|
||||||
|
emits('disagree')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 同意并继续
|
||||||
|
const handleAgree = ()=> {
|
||||||
|
privacyResolves.forEach(resolve => {
|
||||||
|
resolve({
|
||||||
|
event: 'agree',
|
||||||
|
buttonId: 'agree-btn'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
privacyResolves.clear()
|
||||||
|
//关闭弹窗
|
||||||
|
disPopUp()
|
||||||
|
emits('agree')
|
||||||
|
}
|
||||||
|
|
||||||
|
//打开弹窗
|
||||||
|
const popUp = ()=> {
|
||||||
|
if (showPop.value === false) {
|
||||||
|
showPop.value = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//关闭弹窗
|
||||||
|
const disPopUp = ()=> {
|
||||||
|
if (showPop.value === true) {
|
||||||
|
showPop.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const proactive =()=> {
|
||||||
|
if (wx.getPrivacySetting) {
|
||||||
|
wx.getPrivacySetting({
|
||||||
|
success: (res) => {
|
||||||
|
if (res.needAuthorization) {
|
||||||
|
popUp()
|
||||||
|
// 额外逻辑:当前页面的隐私弹窗弹起的时候,关掉其他页面的隐私弹窗
|
||||||
|
closeOtherPagePopUp(disPopUp)
|
||||||
|
} else {
|
||||||
|
emits('agree')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
emits('agree')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.privacy-mask {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 20000;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.privacy-wrap {
|
||||||
|
width: 632rpx;
|
||||||
|
padding: 48rpx 30rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.privacy-title {
|
||||||
|
padding: 0rpx 30rpx 40rpx 30rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 36rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.privacy-desc {
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #555;
|
||||||
|
line-height: 2;
|
||||||
|
text-align: left;
|
||||||
|
padding: 0 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.privacy-link {
|
||||||
|
color: #2f80ed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.privacy-button-flex {
|
||||||
|
display: flex;
|
||||||
|
padding: 20rpx 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.privacy-button-btn {
|
||||||
|
color: #FFF;
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 100rpx;
|
||||||
|
text-align: center;
|
||||||
|
height: 100rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
border: none;
|
||||||
|
background: #07c160;
|
||||||
|
flex: 1;
|
||||||
|
margin-right: 30rpx;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.privacy-button-btn::after {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-disagree {
|
||||||
|
color: #07c160;
|
||||||
|
background: #f2f2f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-agree {
|
||||||
|
margin-right: 0rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
172
uni-app/src/hooks/useDiy.ts
Normal file
172
uni-app/src/hooks/useDiy.ts
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
import {ref, reactive, computed} from 'vue';
|
||||||
|
import {onLoad, onShow, onPullDownRefresh, onPageScroll} from '@dcloudio/uni-app';
|
||||||
|
import {img, handleOnloadParams} from '@/utils/common';
|
||||||
|
import {getDiyInfo} from '@/app/api/diy';
|
||||||
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
|
||||||
|
export function useDiy(params: any = {}) {
|
||||||
|
|
||||||
|
const loading = ref(true);
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
const pullDownRefreshCount = ref(0)
|
||||||
|
|
||||||
|
const id = ref(0)
|
||||||
|
const name = ref(params.name || '')
|
||||||
|
const template = ref('')
|
||||||
|
|
||||||
|
// 自定义页面 数据
|
||||||
|
const diyData = reactive({
|
||||||
|
pageMode: 'diy',
|
||||||
|
title: '',
|
||||||
|
global: {},
|
||||||
|
value: []
|
||||||
|
})
|
||||||
|
|
||||||
|
const getLoading = () => {
|
||||||
|
return loading.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = computed(() => {
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return diyStore;
|
||||||
|
} else {
|
||||||
|
return diyData;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const isShowTopTabbar = ref(false);
|
||||||
|
|
||||||
|
const pageStyle = () => {
|
||||||
|
var style = '';
|
||||||
|
if (data.value.global.pageStartBgColor) {
|
||||||
|
if (data.value.global.pageStartBgColor && data.value.global.pageEndBgColor) style += `background:linear-gradient(${data.value.global.pageGradientAngle},${data.value.global.pageStartBgColor},${data.value.global.pageEndBgColor});`;
|
||||||
|
else style += 'background-color:' + data.value.global.pageStartBgColor + ';';
|
||||||
|
}
|
||||||
|
|
||||||
|
style += 'min-height:calc(100vh - 50px);';
|
||||||
|
if (data.value.global.bgUrl) {
|
||||||
|
style += `background-image:url('${img(data.value.global.bgUrl)}');`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.value.global.bgHeightScale) {
|
||||||
|
style += `background-size: 100% ${data.value.global.bgHeightScale}%;`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// #ifdef H5
|
||||||
|
// 导航栏风格五 - 兼容
|
||||||
|
if(data.value.global && data.value.global.topStatusBar && data.value.global.topStatusBar.style == "style-5"){
|
||||||
|
style += `background-position-y: -176rpx;`;
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
return style;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 监听页面加载
|
||||||
|
const onLoadLifeCycle = () => {
|
||||||
|
onLoad((option: any) => {
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
// 处理小程序场景值参数
|
||||||
|
option = handleOnloadParams(option);
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef H5
|
||||||
|
// 装修模式
|
||||||
|
diyStore.mode = option.mode || '';
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
id.value = option.id || '';
|
||||||
|
if (name.value == '') name.value = option.name || '';
|
||||||
|
template.value = option.template || '';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听页面显示
|
||||||
|
const onShowLifeCycle = (callback: any = null) => {
|
||||||
|
onShow(() => {
|
||||||
|
// 装修模式
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
diyStore.init();
|
||||||
|
} else {
|
||||||
|
getDiyInfo({
|
||||||
|
id: id.value,
|
||||||
|
name: name.value,
|
||||||
|
template: template.value
|
||||||
|
}).then((res: any) => {
|
||||||
|
let requestData = res.data;
|
||||||
|
if (requestData.value) {
|
||||||
|
diyData.pageMode = requestData.mode;
|
||||||
|
diyData.title = requestData.title;
|
||||||
|
|
||||||
|
let sources = JSON.parse(requestData.value);
|
||||||
|
diyData.global = sources.global;
|
||||||
|
diyData.value = sources.value;
|
||||||
|
diyData.value.forEach((item: any, index) => {
|
||||||
|
item.pageStyle = '';
|
||||||
|
if (item.pageStartBgColor) {
|
||||||
|
if (item.pageStartBgColor && item.pageEndBgColor) item.pageStyle += `background:linear-gradient(${item.pageGradientAngle},${item.pageStartBgColor},${item.pageEndBgColor});`;
|
||||||
|
else item.pageStyle += 'background-color:' + item.pageStartBgColor + ';';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.margin) {
|
||||||
|
if (item.margin.top > 0) {
|
||||||
|
item.pageStyle += 'padding-top:' + item.margin.top * 2 + 'rpx' + ';';
|
||||||
|
}
|
||||||
|
item.pageStyle += 'padding-bottom:' + item.margin.bottom * 2 + 'rpx' + ';';
|
||||||
|
item.pageStyle += 'padding-right:' + item.margin.both * 2 + 'rpx' + ';';
|
||||||
|
item.pageStyle += 'padding-left:' + item.margin.both * 2 + 'rpx' + ';';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 控制自定义头部是否出现 | 微信小程序
|
||||||
|
isShowTopTabbar.value = diyData.value.some((item) => {
|
||||||
|
return item && item.position && item.position == 'top_fixed'
|
||||||
|
});
|
||||||
|
|
||||||
|
uni.setNavigationBarTitle({
|
||||||
|
title: diyData.title
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
loading.value = false;
|
||||||
|
|
||||||
|
if (callback) callback(requestData)
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听下拉刷新事件
|
||||||
|
const onPullDownRefreshLifeCycle = () => {
|
||||||
|
onPullDownRefresh(() => {
|
||||||
|
pullDownRefreshCount.value++;
|
||||||
|
uni.stopPullDownRefresh();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听滚动事件
|
||||||
|
const onPageScrollLifeCycle = () => {
|
||||||
|
onPageScroll((e) => {
|
||||||
|
if (e.scrollTop > 0) {
|
||||||
|
diyStore.scrollTop = e.scrollTop;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
getLoading,
|
||||||
|
pullDownRefreshCount,
|
||||||
|
data: data.value,
|
||||||
|
isShowTopTabbar,
|
||||||
|
pageStyle,
|
||||||
|
onLoad: onLoadLifeCycle,
|
||||||
|
onShow: onShowLifeCycle,
|
||||||
|
onPullDownRefresh: onPullDownRefreshLifeCycle,
|
||||||
|
onPageScroll: onPageScrollLifeCycle,
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
import { redirect, isWeixinBrowser, urlDeconstruction } from '@/utils/common'
|
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 { getWechatAuthCode } from '@/app/api/system'
|
||||||
import useMemberStore from '@/stores/member'
|
import useMemberStore from '@/stores/member'
|
||||||
import useConfigStore from '@/stores/config'
|
import useConfigStore from '@/stores/config'
|
||||||
@ -13,14 +13,14 @@ export function useLogin() {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const config = useConfigStore()
|
const config = useConfigStore()
|
||||||
// #ifdef MP-WEIXIN
|
// #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' })
|
redirect({ url: '/app/pages/auth/bind', mode: 'redirectTo' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// #ifdef H5
|
// #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' })
|
redirect({ url: '/app/pages/auth/bind', mode: 'redirectTo' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -33,6 +33,7 @@ export function useLogin() {
|
|||||||
* 执行登录后跳转
|
* 执行登录后跳转
|
||||||
*/
|
*/
|
||||||
const handleLoginBack = () => {
|
const handleLoginBack = () => {
|
||||||
|
uni.removeStorageSync('autoLoginLock')
|
||||||
uni.getStorage({
|
uni.getStorage({
|
||||||
key: 'loginBack',
|
key: 'loginBack',
|
||||||
success: (data : AnyObject) => {
|
success: (data : AnyObject) => {
|
||||||
@ -48,26 +49,45 @@ export function useLogin() {
|
|||||||
* 授权登录
|
* 授权登录
|
||||||
*/
|
*/
|
||||||
const authLogin = (code : string | null) => {
|
const authLogin = (code : string | null) => {
|
||||||
let login = null
|
|
||||||
let obj = {};
|
let obj = {};
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
login = weappLogin
|
// #ifdef MP-WEIXIN
|
||||||
obj.code = code;
|
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
|
// #endif
|
||||||
|
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
login = wechatLogin
|
|
||||||
obj.code = code;
|
obj.code = code;
|
||||||
uni.getStorageSync('pid') && (Object.assign(obj, { pid: uni.getStorageSync('pid') }))
|
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
|
// #endif
|
||||||
|
|
||||||
login(obj).then((res : AnyObject) => {
|
|
||||||
if (res.data.token) {
|
|
||||||
useMemberStore().setToken(res.data.token)
|
|
||||||
} else {
|
|
||||||
uni.setStorageSync('openid', res.data.openid)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -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 { onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'
|
||||||
import { getShareInfo } from '@/app/api/diy';
|
import { getShareInfo } from '@/app/api/diy';
|
||||||
import useMemberStore from '@/stores/member'
|
|
||||||
import { watch } from 'vue'
|
|
||||||
|
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
import wechat from '@/utils/wechat'
|
import wechat from '@/utils/wechat'
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
export const useShare = () => {
|
export const useShare = () => {
|
||||||
var wechatOptions : WeixinJsSdk.OnMenuShareAppMessageOptions = {
|
var wechatOptions: any = {};
|
||||||
title: '',
|
|
||||||
link: ''
|
|
||||||
};
|
|
||||||
|
|
||||||
var weappOptions = {};
|
var weappOptions:any = {};
|
||||||
|
|
||||||
// #ifdef H5
|
const wechatInit = () => {
|
||||||
const wechatInit = async () => {
|
|
||||||
if (!isWeixinBrowser()) return;
|
if (!isWeixinBrowser()) return;
|
||||||
await wechat.init();
|
// 初始化sdk
|
||||||
|
wechat.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 微信公众号分享
|
// 微信公众号分享
|
||||||
@ -27,84 +22,101 @@ export const useShare = () => {
|
|||||||
if (!isWeixinBrowser()) return;
|
if (!isWeixinBrowser()) return;
|
||||||
wechat.share(wechatOptions);
|
wechat.share(wechatOptions);
|
||||||
}
|
}
|
||||||
// #endif
|
|
||||||
|
|
||||||
const setShare = async (options : any = {}) => {
|
const getQuery = ()=>{
|
||||||
let memberStore = useMemberStore();
|
let query:any = currShareRoute().params;
|
||||||
|
let wap_member_id = uni.getStorageSync('wap_member_id');
|
||||||
|
if (wap_member_id) {
|
||||||
|
query.mid = wap_member_id;
|
||||||
|
}
|
||||||
|
|
||||||
watch(() => memberStore.info, () => {
|
let queryStr = [];
|
||||||
setShare(options)
|
for (let key in query) {
|
||||||
})
|
queryStr.push(key + '=' + query[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return queryStr
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const setShare = (options : any = {}) => {
|
||||||
|
if(currRoute() == '' || currRoute().indexOf('app/pages/index/close') != -1 || currRoute().indexOf('app/pages/index/nosite') != -1) return;
|
||||||
|
|
||||||
|
let queryStr = getQuery();
|
||||||
|
|
||||||
// #ifdef H5
|
// #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
|
// #endif
|
||||||
|
|
||||||
if (options && options.wechat && options.weapp) {
|
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
|
// #ifdef H5
|
||||||
let link = location.origin + location.pathname + (str.length > 0 ? '?' + str.join('&') : '');
|
wechatOptions.title = options.wechat.title || ''
|
||||||
wechatOptions = {
|
wechatOptions.link = options.wechat.link || h5Link
|
||||||
title: options.wechat.title || '',
|
wechatOptions.desc = options.wechat.desc || ''
|
||||||
link: options.wechat.link || link,
|
wechatOptions.imgUrl = options.wechat.url ? img(options.wechat.url) : ''
|
||||||
desc: options.wechat.desc || '',
|
|
||||||
imgUrl: options.wechat.url ? img(options.wechat.url) : ''
|
|
||||||
}
|
|
||||||
wechatShare()
|
wechatShare()
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
weappOptions = {
|
// #ifdef MP-WEIXIN
|
||||||
title: options.weapp.title || '',
|
weappOptions.title = options.weapp.title || ''
|
||||||
query: options.weapp.path || '/' + currRoute() + (str.length > 0 ? '?' + str.join('&') : ''),
|
weappOptions.query = options.weapp.path || queryStr.join('&')
|
||||||
imageUrl: options.weapp.url ? img(options.weapp.url) : ''
|
weappOptions.imageUrl = options.weapp.url ? img(options.weapp.url) : ''
|
||||||
}
|
// #endif
|
||||||
|
|
||||||
} else {
|
} 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;
|
let data = res.data;
|
||||||
|
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
let wechat = data.wechat;
|
let wechat = data.wechat;
|
||||||
if (wechat) {
|
if (wechat) {
|
||||||
let link = location.origin + location.pathname + (data.query ? '?' + data.query : '');
|
wechatOptions.title = wechat.title
|
||||||
wechatOptions = {
|
wechatOptions.desc = wechat.desc
|
||||||
link: link,
|
wechatOptions.imgUrl = wechat.url ? img(wechat.url) : ''
|
||||||
title: wechat.title,
|
}else{
|
||||||
desc: wechat.desc,
|
wechatOptions.title = document.title;
|
||||||
imgUrl: wechat.url ? img(wechat.url) : ''
|
wechatOptions.desc = ''
|
||||||
}
|
|
||||||
}
|
}
|
||||||
wechatShare()
|
wechatShare()
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
let weapp = data.weapp;
|
let weapp = data.weapp;
|
||||||
if (weapp) {
|
if (weapp) {
|
||||||
weappOptions = {
|
weappOptions.title = weapp.title
|
||||||
query: data.url,
|
weappOptions.imageUrl = weapp.url ? img(weapp.url) : ''
|
||||||
title: weapp.title,
|
|
||||||
imageUrl: weapp.url ? img(weapp.url) : ''
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// #endif
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
uni.setStorageSync('weappOptions', weappOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 小程序分享,分享给好友
|
// 小程序分享,分享给好友
|
||||||
const shareApp = (options = {}) => {
|
const shareApp = (options = {}) => {
|
||||||
onShareAppMessage(() => {
|
onShareAppMessage(() => {
|
||||||
|
let config:any= uni.getStorageSync('weappOptions')
|
||||||
|
if(!config) config = {}
|
||||||
return {
|
return {
|
||||||
...weappOptions,
|
...config,
|
||||||
...options
|
...options
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -114,14 +126,17 @@ export const useShare = () => {
|
|||||||
// 小程序分享,分享到朋友圈
|
// 小程序分享,分享到朋友圈
|
||||||
const shareTime = (options = {}) => {
|
const shareTime = (options = {}) => {
|
||||||
onShareTimeline(() => {
|
onShareTimeline(() => {
|
||||||
|
let config:any= uni.getStorageSync('weappOptions')
|
||||||
|
if(!config) config = {}
|
||||||
return {
|
return {
|
||||||
...weappOptions,
|
...config,
|
||||||
...options
|
...options
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
wechatInit:wechatInit,
|
||||||
setShare: setShare,
|
setShare: setShare,
|
||||||
onShareAppMessage: shareApp,
|
onShareAppMessage: shareApp,
|
||||||
onShareTimeline: shareTime,
|
onShareTimeline: shareTime,
|
||||||
|
|||||||
@ -9,6 +9,7 @@ let i18n = createI18n({
|
|||||||
locale: uni.getLocale(),
|
locale: uni.getLocale(),
|
||||||
globalInjection: true, //是否全局注入
|
globalInjection: true, //是否全局注入
|
||||||
silentFallbackWarn: true,
|
silentFallbackWarn: true,
|
||||||
|
silentTranslationWarn: true,
|
||||||
messages: {
|
messages: {
|
||||||
'zh-Hans': zhHans,
|
'zh-Hans': zhHans,
|
||||||
en
|
en
|
||||||
|
|||||||
@ -1,10 +1,19 @@
|
|||||||
import i18n, { language } from "./i18n"
|
import i18n, { language } from "./i18n"
|
||||||
import { currRoute } from '@/utils/common'
|
import useSystemStore from '@/stores/system'
|
||||||
|
import { getCurrentInstance } from 'vue'
|
||||||
|
|
||||||
const t = (message: string) => {
|
const t = (message: string) => {
|
||||||
const route = currRoute()
|
let route = '/' + useSystemStore().currRoute
|
||||||
const file = language.getFileKey(`/${route}`)
|
// #ifdef H5
|
||||||
const key = `${file.fileKey}.${message}`
|
route = getCurrentInstance()?.appContext.config.globalProperties.$route.path || ('/' + useSystemStore().currRoute)
|
||||||
return i18n.global.t(key) != key ? i18n.global.t(key) : i18n.global.t(message)
|
// #endif
|
||||||
|
// #ifdef MP
|
||||||
|
route = '/' + (getCurrentInstance()?.root.ctx.$scope.__route__ || useSystemStore().currRoute)
|
||||||
|
// #endif
|
||||||
|
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) : ''
|
||||||
}
|
}
|
||||||
|
|
||||||
export { language, t }
|
export { language, t }
|
||||||
@ -15,5 +24,3 @@ export default {
|
|||||||
app.use(i18n);
|
app.use(i18n);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { nextTick } from 'vue'
|
import { nextTick } from 'vue'
|
||||||
|
import { getAppPages, getSubPackagesPages} from "@/utils/pages"
|
||||||
|
|
||||||
class Language {
|
class Language {
|
||||||
private i18n: any
|
private i18n: any
|
||||||
@ -15,15 +16,19 @@ class Language {
|
|||||||
* @param locale 设置语言
|
* @param locale 设置语言
|
||||||
*/
|
*/
|
||||||
public setI18nLanguage(locale: string, path: string = '') {
|
public setI18nLanguage(locale: string, path: string = '') {
|
||||||
if (this.i18n.mode === 'legacy') {
|
if (this.i18n.global.locale == locale) return
|
||||||
this.i18n.global.locale = locale
|
this.i18n.global.locale = locale
|
||||||
} else {
|
|
||||||
this.i18n.global.locale = locale
|
|
||||||
}
|
|
||||||
path && (this.path = path)
|
path && (this.path = path)
|
||||||
uni.setLocale(locale)
|
uni.setLocale(locale)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public loadAllLocaleMessages(app: string, locale: string) {
|
||||||
|
const pages = app == 'app' ? getAppPages() : getSubPackagesPages()
|
||||||
|
pages.forEach((path: string) => {
|
||||||
|
this.loadLocaleMessages(path, locale)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载语言包
|
* 加载语言包
|
||||||
* @param path
|
* @param path
|
||||||
|
|||||||
@ -17,6 +17,10 @@
|
|||||||
"pages.member.address_edit": "编辑收货地址",
|
"pages.member.address_edit": "编辑收货地址",
|
||||||
"pages.member.apply_cash_out": "申请提现",
|
"pages.member.apply_cash_out": "申请提现",
|
||||||
"pages.member.balance": "我的余额",
|
"pages.member.balance": "我的余额",
|
||||||
|
"pages.member.point": "我的积分",
|
||||||
|
"pages.member.point_detail": "积分明细",
|
||||||
|
"pages.member.level": "会员等级",
|
||||||
|
"pages.member.sign_in": "我的签到",
|
||||||
"pages.member.cash_out": "提现记录",
|
"pages.member.cash_out": "提现记录",
|
||||||
"pages.member.cash_out_detail": "提现详情",
|
"pages.member.cash_out_detail": "提现详情",
|
||||||
"pages.member.commission": "我的佣金",
|
"pages.member.commission": "我的佣金",
|
||||||
@ -26,5 +30,9 @@
|
|||||||
"pages.pay.browser": "支付",
|
"pages.pay.browser": "支付",
|
||||||
"pages.pay.result": "支付结果",
|
"pages.pay.result": "支付结果",
|
||||||
"pages.setting.index": "设置",
|
"pages.setting.index": "设置",
|
||||||
|
"pages.verify.index": "核销台",
|
||||||
|
"pages.verify.verify": "核销",
|
||||||
|
"pages.verify.detail": "核销详情",
|
||||||
|
"pages.verify.record": "核销记录",
|
||||||
"pages.webview.index": ""
|
"pages.webview.index": ""
|
||||||
}
|
}
|
||||||
|
|||||||
@ -72,7 +72,7 @@
|
|||||||
"orderNo": "订单号",
|
"orderNo": "订单号",
|
||||||
"actualPayment": "实付款",
|
"actualPayment": "实付款",
|
||||||
"orderClose": "关闭订单",
|
"orderClose": "关闭订单",
|
||||||
"orderFinish": "订单完成",
|
"orderFinish": "确认收货",
|
||||||
"orderDetail": "详情",
|
"orderDetail": "详情",
|
||||||
"wxPrivacyPopup": {
|
"wxPrivacyPopup": {
|
||||||
"title": "用户隐私保护提示",
|
"title": "用户隐私保护提示",
|
||||||
@ -85,33 +85,9 @@
|
|||||||
},
|
},
|
||||||
"starLevel": "星级",
|
"starLevel": "星级",
|
||||||
"star": "星",
|
"star": "星",
|
||||||
"shop.orderNo": "订单号",
|
|
||||||
"shop.actualPayment": "实付款",
|
"emptyAddress":"暂无收货地址,请先创建地址",
|
||||||
"shop.orderClose": "关闭订单",
|
"addAddress":"新增收货地址",
|
||||||
"shop.orderFinish": "订单完成",
|
"selectAddress":"选择地址",
|
||||||
"tourism.orderNo": "订单号",
|
"coupon":"优惠劵"
|
||||||
"tourism.rise": "起",
|
|
||||||
"tourism.starLevel": "星级",
|
|
||||||
"tourism.star": "星",
|
|
||||||
"o2o.way": "线路",
|
|
||||||
"o2o.hotel": "酒店",
|
|
||||||
"o2o.scenic": "景点",
|
|
||||||
"o2o.reserveBtn": "去抢购",
|
|
||||||
"o2o.noHomeAddress": "没有更多内容啦~",
|
|
||||||
"o2o.soldOut": "已售",
|
|
||||||
"o2o.orderNo": "订单号",
|
|
||||||
"o2o.actualPayment": "实付款",
|
|
||||||
"o2o.orderDetail": "详情",
|
|
||||||
"recharge.orderNo": "订单号",
|
|
||||||
"vipcard.cardReserve": "项目预约",
|
|
||||||
"vipcard.card": "办理次卡",
|
|
||||||
"vipcard.reserveSuccess": "预约成功",
|
|
||||||
"vipcard.reserve": "预约",
|
|
||||||
"vipcard.cardLink": "次卡",
|
|
||||||
"vipcard.reserveBtn": "去抢购",
|
|
||||||
"vipcard.cardBtn": "办理",
|
|
||||||
"vipcard.soldOut": "已售",
|
|
||||||
"vipcard.orderNo": "订单号",
|
|
||||||
"vipcard.myLink": "我的",
|
|
||||||
"vipcard.memberCode": "会员码"
|
|
||||||
}
|
}
|
||||||
@ -1,28 +1,24 @@
|
|||||||
{
|
{
|
||||||
"name" : "",
|
"name": "",
|
||||||
"appid" : "__UNI__ED923AB",
|
"appid": "__UNI__ED923AB",
|
||||||
"description" : "",
|
"description": "",
|
||||||
"versionName" : "1.0.0",
|
"versionName": "1.0.0",
|
||||||
"versionCode" : "100",
|
"versionCode": "100",
|
||||||
"transformPx" : false,
|
"transformPx": false,
|
||||||
/* 5+App特有相关 */
|
"app-plus": {
|
||||||
"app-plus" : {
|
"usingComponents": true,
|
||||||
"usingComponents" : true,
|
"nvueStyleCompiler": "uni-app",
|
||||||
"nvueStyleCompiler" : "uni-app",
|
"compilerVersion": 3,
|
||||||
"compilerVersion" : 3,
|
"splashscreen": {
|
||||||
"splashscreen" : {
|
"alwaysShowBeforeRender": true,
|
||||||
"alwaysShowBeforeRender" : true,
|
"waiting": true,
|
||||||
"waiting" : true,
|
"autoclose": true,
|
||||||
"autoclose" : true,
|
"delay": 0
|
||||||
"delay" : 0
|
|
||||||
},
|
},
|
||||||
/* 模块配置 */
|
"modules": {},
|
||||||
"modules" : {},
|
"distribute": {
|
||||||
/* 应用发布信息 */
|
"android": {
|
||||||
"distribute" : {
|
"permissions": [
|
||||||
/* android打包配置 */
|
|
||||||
"android" : {
|
|
||||||
"permissions" : [
|
|
||||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||||
@ -40,48 +36,57 @@
|
|||||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
/* ios打包配置 */
|
"ios": {},
|
||||||
"ios" : {},
|
"sdkConfigs": {}
|
||||||
/* SDK配置 */
|
|
||||||
"sdkConfigs" : {}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/* 快应用特有相关 */
|
"quickapp": {},
|
||||||
"quickapp" : {},
|
"mp-weixin": {
|
||||||
/* 小程序特有相关 */
|
"appid": "",
|
||||||
"mp-weixin" : {
|
"setting": {
|
||||||
"appid" : "wx59e6ba6050bbe7bc",
|
"urlCheck": false
|
||||||
"setting" : {
|
|
||||||
"urlCheck" : false
|
|
||||||
},
|
},
|
||||||
"usingComponents" : true,
|
"usingComponents": true,
|
||||||
"requiredPrivateInfos" : [ "chooseLocation", "getLocation", "chooseAddress" ]
|
"permission": {
|
||||||
},
|
"scope.userLocation": {
|
||||||
"mp-alipay" : {
|
"desc": "为了更好地为您提供服务"
|
||||||
"usingComponents" : true
|
},
|
||||||
},
|
"scope.writePhotosAlbum": {
|
||||||
"mp-baidu" : {
|
"desc": "为了更好地为您提供服务"
|
||||||
"usingComponents" : true
|
|
||||||
},
|
|
||||||
"mp-toutiao" : {
|
|
||||||
"usingComponents" : true
|
|
||||||
},
|
|
||||||
"uniStatistics" : {
|
|
||||||
"enable" : false
|
|
||||||
},
|
|
||||||
"vueVersion" : "3",
|
|
||||||
"h5" : {
|
|
||||||
"sdkConfigs" : {
|
|
||||||
"maps" : {
|
|
||||||
"qqmap" : {
|
|
||||||
"key" : "6ZDBZ-CLSLX-66747-7MVM4-HLK47-XMBXU"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"router" : {
|
"requiredPrivateInfos": [
|
||||||
"mode" : "history",
|
"chooseLocation",
|
||||||
"base" : "/wap/"
|
"getLocation",
|
||||||
|
"chooseAddress"
|
||||||
|
],
|
||||||
|
"__usePrivacyCheck__": true
|
||||||
|
},
|
||||||
|
"mp-alipay": {
|
||||||
|
"usingComponents": true
|
||||||
|
},
|
||||||
|
"mp-baidu": {
|
||||||
|
"usingComponents": true
|
||||||
|
},
|
||||||
|
"mp-toutiao": {
|
||||||
|
"usingComponents": true
|
||||||
|
},
|
||||||
|
"uniStatistics": {
|
||||||
|
"enable": false
|
||||||
|
},
|
||||||
|
"vueVersion": "3",
|
||||||
|
"h5": {
|
||||||
|
"router": {
|
||||||
|
"mode": "history",
|
||||||
|
"base": "/wap/"
|
||||||
|
},
|
||||||
|
"sdkConfigs": {
|
||||||
|
"maps": {
|
||||||
|
"qqmap": {
|
||||||
|
"key": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fallbackLocale" : "zh-Hans"
|
"fallbackLocale": "zh-Hans"
|
||||||
}
|
}
|
||||||
@ -86,6 +86,9 @@
|
|||||||
{
|
{
|
||||||
"path": "app/pages/member/commission",
|
"path": "app/pages/member/commission",
|
||||||
"style": {
|
"style": {
|
||||||
|
// #ifndef H5
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
// #endif
|
||||||
"navigationBarTitleText": "%pages.member.commission%"
|
"navigationBarTitleText": "%pages.member.commission%"
|
||||||
},
|
},
|
||||||
"needLogin": true
|
"needLogin": true
|
||||||
@ -93,10 +96,23 @@
|
|||||||
{
|
{
|
||||||
"path": "app/pages/member/balance",
|
"path": "app/pages/member/balance",
|
||||||
"style": {
|
"style": {
|
||||||
|
// #ifndef H5
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
// #endif
|
||||||
"navigationBarTitleText": "%pages.member.balance%"
|
"navigationBarTitleText": "%pages.member.balance%"
|
||||||
},
|
},
|
||||||
"needLogin": true
|
"needLogin": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "app/pages/member/level",
|
||||||
|
"style": {
|
||||||
|
// #ifndef H5
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
// #endif
|
||||||
|
"navigationBarTitleText": "%pages.member.level%"
|
||||||
|
},
|
||||||
|
"needLogin": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "app/pages/member/detailed_account",
|
"path": "app/pages/member/detailed_account",
|
||||||
"style": {
|
"style": {
|
||||||
@ -118,10 +134,10 @@
|
|||||||
{
|
{
|
||||||
"path": "app/pages/member/index",
|
"path": "app/pages/member/index",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "%pages.member.index%",
|
|
||||||
// #ifndef H5
|
// #ifndef H5
|
||||||
"navigationStyle": "custom",
|
"navigationStyle": "custom",
|
||||||
// #endif
|
// #endif
|
||||||
|
"navigationBarTitleText": "%pages.member.index%",
|
||||||
"usingComponents": {
|
"usingComponents": {
|
||||||
"diy-group": "../../../../addon/components/diy/group/index",
|
"diy-group": "../../../../addon/components/diy/group/index",
|
||||||
"fixed-group": "../../../../addon/components/fixed/group/index"
|
"fixed-group": "../../../../addon/components/fixed/group/index"
|
||||||
@ -142,10 +158,20 @@
|
|||||||
{
|
{
|
||||||
"path": "app/pages/member/point",
|
"path": "app/pages/member/point",
|
||||||
"style": {
|
"style": {
|
||||||
|
// #ifndef H5
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
// #endif
|
||||||
"navigationBarTitleText": "%pages.member.point%"
|
"navigationBarTitleText": "%pages.member.point%"
|
||||||
},
|
},
|
||||||
"needLogin": true
|
"needLogin": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "app/pages/member/point_detail",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "%pages.member.point_detail%"
|
||||||
|
},
|
||||||
|
"needLogin": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "app/pages/member/account",
|
"path": "app/pages/member/account",
|
||||||
"style": {
|
"style": {
|
||||||
@ -181,6 +207,16 @@
|
|||||||
},
|
},
|
||||||
"needLogin": true
|
"needLogin": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "app/pages/member/sign_in",
|
||||||
|
"style": {
|
||||||
|
// #ifndef H5
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
// #endif
|
||||||
|
"navigationBarTitleText": "%pages.member.sign_in%"
|
||||||
|
},
|
||||||
|
"needLogin": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "app/pages/pay/browser",
|
"path": "app/pages/pay/browser",
|
||||||
"style": {
|
"style": {
|
||||||
@ -205,6 +241,40 @@
|
|||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "%pages.webview.index%"
|
"navigationBarTitleText": "%pages.webview.index%"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "app/pages/verify/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "%pages.verify.index%"
|
||||||
|
},
|
||||||
|
"needLogin": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "app/pages/verify/verify",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "%pages.verify.verify%"
|
||||||
|
},
|
||||||
|
"needLogin": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "app/pages/verify/detail",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "%pages.verify.detail%"
|
||||||
|
},
|
||||||
|
"needLogin": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "app/pages/verify/record",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "%pages.verify.record%"
|
||||||
|
},
|
||||||
|
"needLogin": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "app/pages/weapp/order_shipping",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "%pages.weapp.order_shipping%"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"subPackages": [
|
"subPackages": [
|
||||||
@ -212,7 +282,7 @@
|
|||||||
"root": "addon",
|
"root": "addon",
|
||||||
"pages": [
|
"pages": [
|
||||||
// {{ PAGE_BEGAIN }}
|
// {{ PAGE_BEGAIN }}
|
||||||
// {{ PAGE_END }}}
|
// {{ PAGE_END }}}
|
||||||
{
|
{
|
||||||
"path": "end"
|
"path": "end"
|
||||||
}
|
}
|
||||||
@ -242,6 +312,8 @@
|
|||||||
"diy-group": "@/addon/components/diy/group/index.vue",
|
"diy-group": "@/addon/components/diy/group/index.vue",
|
||||||
"fixed-group": "@/addon/components/fixed/group/index.vue",
|
"fixed-group": "@/addon/components/fixed/group/index.vue",
|
||||||
"^u-(.*)": "uview-plus/components/u-$1/u-$1.vue",
|
"^u-(.*)": "uview-plus/components/u-$1/u-$1.vue",
|
||||||
|
"^up-(.*)": "uview-plus/components/u-$1/u-$1.vue",
|
||||||
|
"^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue",
|
||||||
"diy-(\W.*)": "@/app/components/diy/$1/index.vue",
|
"diy-(\W.*)": "@/app/components/diy/$1/index.vue",
|
||||||
"fixed-(\W.*)": "@/app/components/fixed/$1/index.vue"
|
"fixed-(\W.*)": "@/app/components/fixed/$1/index.vue"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { getConfig } from '@/app/api/auth'
|
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 {
|
interface loginConfig {
|
||||||
is_username: number | boolean,
|
is_username: number | boolean,
|
||||||
@ -19,9 +20,10 @@ interface tabbarConfig {
|
|||||||
|
|
||||||
interface Config {
|
interface Config {
|
||||||
login: loginConfig,
|
login: loginConfig,
|
||||||
|
tabbarList:any,
|
||||||
tabbar: tabbarConfig | null,
|
tabbar: tabbarConfig | null,
|
||||||
addon: String,
|
addon: String,
|
||||||
themeColor:String
|
themeColor:any
|
||||||
}
|
}
|
||||||
|
|
||||||
const useConfigStore = defineStore('config', {
|
const useConfigStore = defineStore('config', {
|
||||||
@ -34,6 +36,7 @@ const useConfigStore = defineStore('config', {
|
|||||||
is_bind_mobile: 0,
|
is_bind_mobile: 0,
|
||||||
agreement_show: 0
|
agreement_show: 0
|
||||||
},
|
},
|
||||||
|
tabbarList:{},
|
||||||
tabbar: null,
|
tabbar: null,
|
||||||
addon: '',
|
addon: '',
|
||||||
themeColor:''
|
themeColor:''
|
||||||
@ -50,13 +53,10 @@ const useConfigStore = defineStore('config', {
|
|||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
async getTabbarConfig(key: any = '') {
|
async getTabbarConfig() {
|
||||||
if(key == this.addon) return; // 防重复请求
|
await getTabbarList({}).then((res:any)=>{
|
||||||
if (!key) key = this.addon;
|
this.tabbarList = res.data;
|
||||||
|
}).catch(()=>{
|
||||||
await getTabbarInfo({key}).then((res: responseResult) => {
|
|
||||||
this.tabbar = res.data
|
|
||||||
}).catch(() => {
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 获取主色调
|
// 获取主色调
|
||||||
|
|||||||
@ -1,18 +1,20 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { setToken, removeToken, redirect } from '@/utils/common'
|
import { setToken, removeToken, redirect } from '@/utils/common'
|
||||||
import { getMemberInfo } from '@/app/api/member'
|
import { getMemberInfo,getMemberLevel } from '@/app/api/member'
|
||||||
import { logout } from '@/app/api/auth'
|
import { logout } from '@/app/api/auth'
|
||||||
|
|
||||||
interface Member {
|
interface Member {
|
||||||
token : string | null
|
token : string | null
|
||||||
info : AnyObject | null
|
info : AnyObject | null
|
||||||
|
levelList : Array<any> | null
|
||||||
}
|
}
|
||||||
|
|
||||||
const useMemberStore = defineStore('member', {
|
const useMemberStore = defineStore('member', {
|
||||||
state: () : Member => {
|
state: () : Member => {
|
||||||
return {
|
return {
|
||||||
token: uni.getStorageSync(import.meta.env.VITE_REQUEST_STORAGE_TOKEN_KEY),
|
token: uni.getStorageSync(import.meta.env.VITE_REQUEST_STORAGE_TOKEN_KEY),
|
||||||
info: null
|
info: null,
|
||||||
|
levelList:null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
@ -23,26 +25,34 @@ const useMemberStore = defineStore('member', {
|
|||||||
},
|
},
|
||||||
async getMemberInfo() {
|
async getMemberInfo() {
|
||||||
if (!this.token) return
|
if (!this.token) return
|
||||||
await getMemberInfo()
|
await getMemberInfo().then((res: any) => {
|
||||||
.then((res : any) => {
|
this.info = res.data
|
||||||
this.info = res.data
|
uni.setStorageSync('wap_member_info',this.info)
|
||||||
})
|
uni.setStorageSync('wap_member_id',res.data.member_id)
|
||||||
.catch(async () => {
|
}).catch(async () => {
|
||||||
await this.logout()
|
await this.logout()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
async logout(isRedirect : boolean = false) {
|
async logout(isRedirect : boolean = false) {
|
||||||
if (!this.token) return
|
if (!this.token) return
|
||||||
this.token = ''
|
this.token = ''
|
||||||
this.info = null
|
this.info = null
|
||||||
|
uni.setStorageSync('autoLoginLock', true)
|
||||||
await logout().then(() => {
|
await logout().then(() => {
|
||||||
removeToken()
|
removeToken()
|
||||||
|
uni.removeStorageSync('wap_member_info');
|
||||||
isRedirect && redirect({ url: '/app/pages/index/index', mode: 'switchTab' })
|
isRedirect && redirect({ url: '/app/pages/index/index', mode: 'switchTab' })
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
removeToken()
|
removeToken()
|
||||||
|
uni.removeStorageSync('wap_member_info');
|
||||||
isRedirect && redirect({ url: '/app/pages/index/index', mode: 'switchTab' })
|
isRedirect && redirect({ url: '/app/pages/index/index', mode: 'switchTab' })
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
|
getMemberLevel(){
|
||||||
|
getMemberLevel().then((res:any)=>{
|
||||||
|
this.levelList = res.data
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -1,36 +1,60 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { getSiteInfo } from '@/app/api/system'
|
import { getSiteInfo, getMap } from '@/app/api/system'
|
||||||
import { redirect } from '@/utils/common'
|
import { redirect } from '@/utils/common'
|
||||||
|
|
||||||
interface System {
|
interface System {
|
||||||
site : AnyObject | null,
|
site: AnyObject | null,
|
||||||
siteApps: string[],
|
siteApps: string[],
|
||||||
siteAddons: string[]
|
siteAddons: string[],
|
||||||
|
currRoute: string,
|
||||||
|
location: Object | null, // 定位信息
|
||||||
|
mapConfig: Object
|
||||||
}
|
}
|
||||||
|
|
||||||
const useSystemStore = defineStore('system', {
|
const useSystemStore = defineStore('system', {
|
||||||
state: () : System => {
|
state: (): System => {
|
||||||
return {
|
return {
|
||||||
site: null,
|
site: null,
|
||||||
siteApps: [],
|
siteApps: [],
|
||||||
siteAddons: []
|
siteAddons: [],
|
||||||
}
|
currRoute: '',
|
||||||
},
|
location: null,
|
||||||
actions: {
|
mapConfig: {
|
||||||
async getSiteInfoFn() {
|
is_open: 1,
|
||||||
await getSiteInfo().then((res: any) => {
|
valid_time: 0
|
||||||
this.site = res.data
|
}
|
||||||
const apps = [], addons = []
|
}
|
||||||
Object.keys(res.data.site_addons).forEach((key:string) => {
|
},
|
||||||
const item = res.data.site_addons[key]
|
actions: {
|
||||||
item.type == 'app' ? apps.push(key) : addons.push(key)
|
async getSiteInfoFn() {
|
||||||
})
|
await getSiteInfo().then((res: any) => {
|
||||||
this.siteApps = apps
|
this.site = res.data
|
||||||
this.siteAddons = addons
|
const apps = [], addons = []
|
||||||
}).catch((err) => {
|
Object.keys(res.data.site_addons).forEach((key:string) => {
|
||||||
})
|
const item = res.data.site_addons[key]
|
||||||
}
|
item.type == 'app' ? apps.push(key) : addons.push(key)
|
||||||
}
|
})
|
||||||
|
this.siteApps = apps
|
||||||
|
this.siteAddons = addons
|
||||||
|
}).catch((err) => {
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async getMapFn() {
|
||||||
|
// 获取地图配置
|
||||||
|
await getMap().then((res: any) => {
|
||||||
|
this.mapConfig.is_open = res.data.is_open;
|
||||||
|
this.mapConfig.valid_time = res.data.valid_time;
|
||||||
|
uni.setStorageSync('mapConfig', this.mapConfig);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
setLocation(value: Object) {
|
||||||
|
var date = new Date();
|
||||||
|
date.setSeconds(60 * this.mapConfig.valid_time);
|
||||||
|
value.valid_time = date.getTime() / 1000; // 定位信息 5分钟内有效,过期后将重新获取定位信息
|
||||||
|
this.location = value;
|
||||||
|
uni.setStorageSync('location', value); // 初始化数据调用
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
export default useSystemStore
|
export default useSystemStore
|
||||||
|
|||||||
@ -72,3 +72,36 @@ button[type='primary'],uni-button[type='primary']{
|
|||||||
padding-bottom:constant(safe-area-inset-bottom);
|
padding-bottom:constant(safe-area-inset-bottom);
|
||||||
padding-bottom:env(safe-area-inset-bottom);
|
padding-bottom:env(safe-area-inset-bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 防止穿透
|
||||||
|
.u-popup .u-transition {
|
||||||
|
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 *********************/
|
||||||
|
|||||||
@ -1,7 +1,28 @@
|
|||||||
.bg-index {
|
.bg-index {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
background-size: 100%;
|
background-size: contain;
|
||||||
background-repeat: no-repeat !important;
|
background-repeat: no-repeat !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.u-tabbar__placeholder) {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diy-template-wrap {
|
||||||
|
::v-deep .diy-group {
|
||||||
|
> .draggable-element.top-fixed-diy {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #ifdef H5 */
|
||||||
|
:deep(.child-diy-template-wrap) {
|
||||||
|
.diy-group .draggable-element.top-fixed-diy {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #endif */
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,5 @@
|
|||||||
@import 'uview-plus/index.scss';
|
@import 'uview-plus/index.scss';
|
||||||
@import 'common.scss';
|
@import 'common.scss';
|
||||||
@import 'iconfont.css';
|
@import 'iconfont.css';
|
||||||
|
@import 'official-iconfont.css';
|
||||||
|
|
||||||
|
|||||||
1294
uni-app/src/styles/official-iconfont.css
Normal file
1294
uni-app/src/styles/official-iconfont.css
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,9 +1,7 @@
|
|||||||
import { getTabbarPages } from './pages'
|
import { getTabbarPages } from './pages'
|
||||||
import useDiyStore from '@/app/stores/diy'
|
import useDiyStore from '@/app/stores/diy'
|
||||||
import useMemberStore from '@/stores/member'
|
import useMemberStore from '@/stores/member'
|
||||||
import pagesZh from '@/locale/zh-Hans.json'
|
import useSystemStore from '@/stores/system'
|
||||||
import pagesEn from '@/locale/en.json'
|
|
||||||
import { onReady } from '@dcloudio/uni-app'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 跳转页面
|
* 跳转页面
|
||||||
@ -59,17 +57,15 @@ export const redirect = (redirect : redirectOptions) => {
|
|||||||
* 自定义跳转链接
|
* 自定义跳转链接
|
||||||
* @param {Object} link
|
* @param {Object} link
|
||||||
*/
|
*/
|
||||||
export const diyRedirect = (link : any) => {
|
export const diyRedirect = (link: any) => {
|
||||||
const diyStore = useDiyStore();
|
const diyStore = useDiyStore();
|
||||||
// 装修模式禁止跳转
|
// 装修模式禁止跳转
|
||||||
if (diyStore.mode == 'decorate') return;
|
if (diyStore.mode == 'decorate') return;
|
||||||
|
|
||||||
if (link == null || Object.keys(link).length == 1) 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
|
// #ifdef H5
|
||||||
window.location.href = link.url;
|
window.location.href = link.url;
|
||||||
@ -81,6 +77,24 @@ export const diyRedirect = (link : any) => {
|
|||||||
param: { src: encodeURIComponent(link.url) }
|
param: { src: encodeURIComponent(link.url) }
|
||||||
});
|
});
|
||||||
// #endif
|
// #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 {
|
} else {
|
||||||
redirect({ url: link.url });
|
redirect({ url: link.url });
|
||||||
}
|
}
|
||||||
@ -98,6 +112,12 @@ export const currRoute = () => {
|
|||||||
// 获取分享路由
|
// 获取分享路由
|
||||||
export const currShareRoute = () => {
|
export const currShareRoute = () => {
|
||||||
const pages = getCurrentPages()
|
const pages = getCurrentPages()
|
||||||
|
if (pages.length == 0) {
|
||||||
|
return {
|
||||||
|
path: '/',
|
||||||
|
params: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
let currentRoute = pages[pages.length - 1].route //获取当前页面路由
|
let currentRoute = pages[pages.length - 1].route //获取当前页面路由
|
||||||
|
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
@ -267,7 +287,7 @@ export function timeStampTurnTime(timeStamp, type = "") {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 复制
|
* 复制
|
||||||
* @param {Object} message
|
* @param {Object} value
|
||||||
* @param {Object} callback
|
* @param {Object} callback
|
||||||
*/
|
*/
|
||||||
export function copy(value, callback) {
|
export function copy(value, callback) {
|
||||||
@ -294,7 +314,131 @@ export function copy(value, callback) {
|
|||||||
data: value,
|
data: value,
|
||||||
success: () => {
|
success: () => {
|
||||||
typeof callback == 'function' && callback();
|
typeof callback == 'function' && callback();
|
||||||
|
},
|
||||||
|
fail: (res)=>{
|
||||||
|
// 在隐私协议中没有声明chooseLocation:fail api作用域
|
||||||
|
if(res.errMsg && res.errno) {
|
||||||
|
if(res.errno == 104){
|
||||||
|
let msg = '用户未授权隐私权限,设置剪贴板数据失败';
|
||||||
|
uni.showToast({title: msg, icon: 'none'})
|
||||||
|
}else if(res.errno == 112){
|
||||||
|
let msg = '隐私协议中未声明,设置剪贴板数据失败';
|
||||||
|
uni.showToast({title: msg, icon: 'none'})
|
||||||
|
}else {
|
||||||
|
uni.showToast({title: res.errMsg, icon: 'none'})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理onLoad传递的参数
|
||||||
|
* @param option
|
||||||
|
*/
|
||||||
|
export function handleOnloadParams(option:any) {
|
||||||
|
let params: any = {};
|
||||||
|
|
||||||
|
// 处理小程序扫码进入的场景值参数
|
||||||
|
if (option.scene) {
|
||||||
|
var sceneParams = decodeURIComponent(option.scene).split('&');
|
||||||
|
if (sceneParams.length) {
|
||||||
|
sceneParams.forEach(item => {
|
||||||
|
let arr = item.split('-');
|
||||||
|
params[arr[0]] = arr[1];
|
||||||
|
if(arr[0] == 'mid'){
|
||||||
|
uni.setStorageSync('pid', arr[1])
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
params = option;
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取定位信息
|
||||||
|
*/
|
||||||
|
export function getLocation(param = {}) {
|
||||||
|
uni.getLocation({
|
||||||
|
type: param.type ?? 'gcj02',
|
||||||
|
success: res => {
|
||||||
|
const systemStore = useSystemStore()
|
||||||
|
systemStore.setLocation(res);
|
||||||
|
typeof param.success == 'function' && param.success(res);
|
||||||
|
},
|
||||||
|
fail: res => {
|
||||||
|
typeof param.fail == 'function' && param.fail(res);
|
||||||
|
},
|
||||||
|
complete: res => {
|
||||||
|
typeof param.complete == 'function' && param.complete(res);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定位信息(缓存)
|
||||||
|
*/
|
||||||
|
export function locationStorage () {
|
||||||
|
let data = uni.getStorageSync('location');
|
||||||
|
let mapConfig = uni.getStorageSync('mapConfig');
|
||||||
|
if (data) {
|
||||||
|
var date = new Date();
|
||||||
|
if (mapConfig.valid_time > 0) {
|
||||||
|
data.is_expired = (date.getTime() / 1000) > data.valid_time; // 是否过期
|
||||||
|
} else {
|
||||||
|
data.is_expired = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 深度克隆
|
||||||
|
* @param {object} obj 需要深度克隆的对象
|
||||||
|
* @returns {*} 克隆后的对象或者原值(不是对象)
|
||||||
|
*/
|
||||||
|
export function deepClone(obj: object) {
|
||||||
|
// 对常见的“非”值,直接返回原来值
|
||||||
|
if ([null, undefined, NaN, false].includes(obj)) return obj
|
||||||
|
if (typeof obj !== 'object' && typeof obj !== 'function') {
|
||||||
|
// 原始类型直接返回
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
const o = isArray(obj) ? [] : {}
|
||||||
|
for (const i in obj) {
|
||||||
|
if (obj.hasOwnProperty(i)) {
|
||||||
|
o[i] = typeof obj[i] === 'object' ? deepClone(obj[i]) : obj[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 防抖函数
|
||||||
|
* @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]'
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,81 +1,98 @@
|
|||||||
import { language } from '@/locale'
|
import { language } from '@/locale'
|
||||||
import { checkNeedLogin } from '@/utils/auth'
|
import { checkNeedLogin } from '@/utils/auth'
|
||||||
import { redirect, getToken } from '@/utils/common'
|
import { redirect, getToken, isWeixinBrowser } from '@/utils/common'
|
||||||
import { memberLog } from '@/app/api/auth'
|
import { memberLog } from '@/app/api/auth'
|
||||||
import useConfigStore from "@/stores/config";
|
import useConfigStore from "@/stores/config";
|
||||||
|
import { useShare } from '@/hooks/useShare'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 页面跳转拦截器
|
* 页面跳转拦截器
|
||||||
*/
|
*/
|
||||||
export const redirectInterceptor = (route: { path: string, query: object }) => {
|
export const redirectInterceptor = (route: { path: string, query: object }) => {
|
||||||
route.path = `/${route.path}`
|
route.path = `/${ route.path }`
|
||||||
|
|
||||||
// 检测当前访问的是系统(app)还是插件
|
// 检测当前访问的是系统(app)还是插件
|
||||||
setAddonName(route.path)
|
setAddonName(route.path)
|
||||||
|
|
||||||
// 加载语言包
|
// #ifdef MP
|
||||||
language.loadLocaleMessages(route.path, uni.getLocale())
|
route.path.indexOf('addon') != -1 && language.loadAllLocaleMessages('addon', uni.getLocale())
|
||||||
|
// #endif
|
||||||
|
|
||||||
// 校验是否需要登录
|
// 校验是否需要登录
|
||||||
checkNeedLogin(route)
|
checkNeedLogin(route)
|
||||||
|
|
||||||
// 添加会员访问日志
|
loadShare()
|
||||||
if (getToken()) memberLog({ route: route.path, params: JSON.stringify(route.query), pre_route: getCurrentPages()[0]?.route })
|
|
||||||
|
// 添加会员访问日志
|
||||||
|
if (getToken()) memberLog({
|
||||||
|
route: route.path,
|
||||||
|
params: JSON.stringify(route.query),
|
||||||
|
pre_route: getCurrentPages()[0]?.route
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应用初始化拦截器
|
* 应用初始化拦截器
|
||||||
*/
|
*/
|
||||||
export const launchInterceptor = () => {
|
export const launchInterceptor = () => {
|
||||||
const launch = uni.getLaunchOptionsSync()
|
const launch = uni.getLaunchOptionsSync()
|
||||||
launch.path = `/${launch.path}`
|
launch.path = `/${ launch.path }`
|
||||||
|
|
||||||
// 检测当前访问的是系统(app)还是插件
|
// 检测当前访问的是系统(app)还是插件
|
||||||
setAddonName(launch.path);
|
setAddonName(launch.path);
|
||||||
|
|
||||||
// 加载语言包
|
// 加载语言包
|
||||||
language.loadLocaleMessages(launch.path, uni.getLocale())
|
language.loadAllLocaleMessages('app', uni.getLocale())
|
||||||
|
|
||||||
// 校验是否需要登录
|
// #ifdef H5
|
||||||
checkNeedLogin(launch)
|
language.loadAllLocaleMessages('addon', uni.getLocale())
|
||||||
|
// #endif
|
||||||
|
|
||||||
// 存储分享会员id
|
// 校验是否需要登录
|
||||||
if (launch.query && launch.query.mid) {
|
checkNeedLogin(launch)
|
||||||
uni.setStorageSync('pid', launch.query.mid)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加会员访问日志
|
// 存储分享会员id
|
||||||
if (getToken()) memberLog({ route: launch.path, params: JSON.stringify(launch.query || {}), pre_route: '' })
|
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)还是插件
|
* 检测当前访问的是系统(app)还是插件
|
||||||
* 设置插件的底部导航
|
* 设置插件的底部导航
|
||||||
* 设置插件应用的主色调
|
* 设置插件应用的主色调
|
||||||
* @param path
|
* @param path
|
||||||
*/
|
*/
|
||||||
const setAddonName = async (path: string) => {
|
const setAddonName = async (path: string) => {
|
||||||
let pathArr = path.split('/')
|
let pathArr = path.split('/')
|
||||||
let route = pathArr[1] == 'addon' ? pathArr[2] : 'app';
|
let route = pathArr[1] == 'addon' ? pathArr[2] : 'app';
|
||||||
|
|
||||||
// 设置底部导航
|
// 设置底部导航
|
||||||
const configStore = useConfigStore()
|
const configStore = useConfigStore()
|
||||||
if (configStore.addon != route) {
|
if (configStore.addon != route) {
|
||||||
configStore.addon = route;
|
configStore.addon = route;
|
||||||
configStore.getTabbarConfig();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 设置插件应用的主色调,排除系统
|
// 设置插件应用的主色调,排除系统
|
||||||
if (route != 'app') {
|
if (route != 'app') {
|
||||||
try {
|
try {
|
||||||
const theme = await import(`../addon/${route}/utils/theme.json`)
|
const theme = await import(`../addon/${route}/utils/theme.json`)
|
||||||
configStore.themeColor = theme.default
|
configStore.themeColor = theme.default
|
||||||
uni.setStorageSync('current_theme_color', JSON.stringify(theme.default));
|
uni.setStorageSync('current_theme_color', JSON.stringify(theme.default));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('设置插件应用的主色调', e)
|
// 设置插件应用的主色调发生错误,若不存在则使用最后有效的主色调
|
||||||
uni.removeStorageSync('current_theme_color');
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载分享
|
||||||
|
const loadShare = () => {
|
||||||
|
const { setShare } = useShare()
|
||||||
|
setShare()
|
||||||
}
|
}
|
||||||
@ -1,6 +1,8 @@
|
|||||||
import { currRoute } from './common'
|
import { currRoute } from './common'
|
||||||
import { redirectInterceptor } from './interceptor'
|
import { redirectInterceptor } from './interceptor'
|
||||||
import useConfigStore from "@/stores/config";
|
import useConfigStore from "@/stores/config";
|
||||||
|
import useSystemStore from '@/stores/system'
|
||||||
|
import {useShare} from '@/hooks/useShare'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
install(vue) {
|
install(vue) {
|
||||||
@ -11,15 +13,31 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLoad: (data: object) => {
|
onLoad: (data: object) => {
|
||||||
|
const route = currRoute() ?? ''
|
||||||
|
|
||||||
this.query = data
|
this.query = data
|
||||||
|
|
||||||
|
useSystemStore().$patch((state) => {
|
||||||
|
state.currRoute = route
|
||||||
|
})
|
||||||
},
|
},
|
||||||
onShow: () => {
|
onShow: () => {
|
||||||
const route = currRoute() ?? ''
|
const route = currRoute() ?? ''
|
||||||
|
|
||||||
redirectInterceptor({
|
useSystemStore().$patch((state) => {
|
||||||
path: route,
|
state.currRoute = route
|
||||||
query: this.query
|
})
|
||||||
})
|
|
||||||
|
redirectInterceptor({
|
||||||
|
path: route,
|
||||||
|
query: this.query
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onShareAppMessage(){
|
||||||
|
useShare().onShareAppMessage()
|
||||||
|
},
|
||||||
|
onShareTimeline(){
|
||||||
|
useShare().onShareTimeline()
|
||||||
},
|
},
|
||||||
methods:{
|
methods:{
|
||||||
themeColor(){
|
themeColor(){
|
||||||
|
|||||||
@ -20,6 +20,31 @@ export function getNeedLoginPages() {
|
|||||||
return pages
|
return pages
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有页面
|
||||||
|
*/
|
||||||
|
export function getAppPages() {
|
||||||
|
const pages = []
|
||||||
|
// 获取主包中需要登录的页面
|
||||||
|
pagesJson.pages.forEach(item => {
|
||||||
|
pages.push(`/${item.path}`)
|
||||||
|
})
|
||||||
|
return pages
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSubPackagesPages() {
|
||||||
|
const pages = []
|
||||||
|
// 获取分包中需要登录的页面
|
||||||
|
if (pagesJson.subPackages) {
|
||||||
|
pagesJson.subPackages.forEach(subPackages => {
|
||||||
|
subPackages.pages.forEach(item => {
|
||||||
|
pages.push(`/${subPackages.root}/${item.path}`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return pages
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取tabbar
|
* 获取tabbar
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import useMemberStore from '@/stores/member'
|
import useMemberStore from '@/stores/member'
|
||||||
import { t } from '@/locale'
|
import { t } from '@/locale'
|
||||||
import {getToken, getAppChannel, redirect} from './common'
|
import { getToken, getAppChannel, redirect, currRoute } from './common'
|
||||||
import qs from 'qs'
|
import qs from 'qs'
|
||||||
|
|
||||||
interface RequestConfig {
|
interface RequestConfig {
|
||||||
@ -147,8 +147,13 @@ class Request {
|
|||||||
useMemberStore().logout()
|
useMemberStore().logout()
|
||||||
break;
|
break;
|
||||||
case 402:
|
case 402:
|
||||||
|
if(currRoute().indexOf('app/pages/index/close') != -1) return;
|
||||||
redirect({url: '/app/pages/index/close', mode: 'reLaunch'})
|
redirect({url: '/app/pages/index/close', mode: 'reLaunch'})
|
||||||
break;
|
break;
|
||||||
|
case 403:
|
||||||
|
if(currRoute().indexOf('app/pages/index/nosite') != -1) return;
|
||||||
|
redirect({url: '/app/pages/index/nosite', mode: 'reLaunch'})
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
const handleKey = (key: string) : string => {
|
const handleKey = (key: string) : string => {
|
||||||
return key
|
return key
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,7 +22,7 @@ class Wechat {
|
|||||||
timestamp: data.timestamp, // 必填,生成签名的时间戳
|
timestamp: data.timestamp, // 必填,生成签名的时间戳
|
||||||
nonceStr: data.nonceStr, // 必填,生成签名的随机串
|
nonceStr: data.nonceStr, // 必填,生成签名的随机串
|
||||||
signature: data.signature,// 必填,签名
|
signature: data.signature,// 必填,签名
|
||||||
jsApiList: ['chooseWXPay', 'updateAppMessageShareData', 'updateTimelineShareData'] // 必填,需要使用的JS接口列表
|
jsApiList: ['chooseWXPay', 'updateAppMessageShareData', 'updateTimelineShareData', 'scanQRCode'] // 必填,需要使用的JS接口列表
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -47,6 +47,22 @@ class Wechat {
|
|||||||
wx.updateTimelineShareData(options)
|
wx.updateTimelineShareData(options)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扫一扫
|
||||||
|
* @param {Object} callback
|
||||||
|
*/
|
||||||
|
public scanQRCode(callback:AnyFunction){
|
||||||
|
wx.ready(()=> {
|
||||||
|
wx.scanQRCode({
|
||||||
|
needResult: 1,
|
||||||
|
scanType: ["qrCode"],
|
||||||
|
success: function (res) {
|
||||||
|
typeof callback == 'function' && callback(res);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new Wechat()
|
export default new Wechat()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user