mirror of
https://gitee.com/niucloud-team/niucloud-admin.git
synced 2025-12-11 18:32:49 +00:00
1.5.0
This commit is contained in:
parent
dd8b697d12
commit
fa7e637363
@ -2,7 +2,6 @@
|
||||
<u-popup :show="show" @close="show = false" mode="bottom" :round="10">
|
||||
<view @touchmove.prevent.stop class="popup-common">
|
||||
<view class="title">请选择地区</view>
|
||||
|
||||
<view class="flex p-[30rpx] pt-[0] text-sm font-500">
|
||||
<view v-if="areaList.province.length" class="flex-1 pr-[10rpx]" :class="{'text-[var(--primary-color)]': currSelect == 'province'}" @click="currSelect = 'province'">
|
||||
<view v-if="selected.province">{{ selected.province.name }}</view>
|
||||
@ -40,14 +39,14 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, watch } from 'vue'
|
||||
import { getAreaListByPid, getAreaByCode } from '@/app/api/system'
|
||||
|
||||
|
||||
const prop = defineProps({
|
||||
areaId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const show = ref(false)
|
||||
const areaList = reactive({
|
||||
province: [],
|
||||
@ -55,17 +54,17 @@
|
||||
district: []
|
||||
})
|
||||
const currSelect = ref('province')
|
||||
|
||||
|
||||
const selected = reactive({
|
||||
province: null,
|
||||
city: null,
|
||||
district: null
|
||||
})
|
||||
|
||||
|
||||
getAreaListByPid(0).then(({ data }) => {
|
||||
areaList.province = data
|
||||
}).catch()
|
||||
|
||||
|
||||
watch(() => prop.areaId, (nval, oval)=> {
|
||||
if (nval && !oval) {
|
||||
getAreaByCode(nval).then(({ data }) => {
|
||||
@ -77,7 +76,7 @@
|
||||
},{
|
||||
immediate:true
|
||||
})
|
||||
|
||||
|
||||
/**
|
||||
* 监听省变更
|
||||
*/
|
||||
@ -100,7 +99,7 @@
|
||||
}
|
||||
}).catch()
|
||||
}, { deep: true })
|
||||
|
||||
|
||||
/**
|
||||
* 监听市变更
|
||||
*/
|
||||
@ -129,9 +128,9 @@
|
||||
}
|
||||
|
||||
}, { deep: true })
|
||||
|
||||
|
||||
const emits = defineEmits(['complete'])
|
||||
|
||||
|
||||
/**
|
||||
* 监听区县变更
|
||||
*/
|
||||
@ -140,16 +139,16 @@
|
||||
currSelect.value = 'district'
|
||||
emits('complete', selected)
|
||||
show.value = false
|
||||
}
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
|
||||
const open = ()=> {
|
||||
show.value = true
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
open
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
<template #right>
|
||||
<sms-code v-if="config.agreement_show" :mobile="formData.mobile" type="login" v-model="formData.mobile_key" :isAgree="isAgree"></sms-code>
|
||||
<sms-code v-else :mobile="formData.mobile" type="login" v-model="formData.mobile_key"></sms-code>
|
||||
</template>
|
||||
</template>
|
||||
</u-form-item>
|
||||
</view>
|
||||
<view v-if="config.agreement_show" class="flex items-center mt-[30rpx] pl-[10rpx] py-[10rpx]" @click.stop="agreeChange">
|
||||
@ -41,9 +41,11 @@
|
||||
import { ref, reactive, computed, onMounted } from 'vue'
|
||||
import { t } from '@/locale'
|
||||
import { bindMobile } from '@/app/api/member'
|
||||
import { mobileLogin } from '@/app/api/auth'
|
||||
import useMemberStore from '@/stores/member'
|
||||
import useConfigStore from '@/stores/config'
|
||||
import { redirect } from '@/utils/common'
|
||||
import { useLogin } from '@/hooks/useLogin'
|
||||
|
||||
const show = ref(false)
|
||||
const memberStore = useMemberStore()
|
||||
@ -64,15 +66,17 @@
|
||||
|
||||
const real_name_input = ref(true);
|
||||
onMounted(() => {
|
||||
// 防止浏览器自动填充
|
||||
setTimeout(()=>{
|
||||
real_name_input.value = false;
|
||||
},800)
|
||||
// 防止浏览器自动填充
|
||||
setTimeout(() => {
|
||||
real_name_input.value = false;
|
||||
}, 800)
|
||||
|
||||
uni.getStorageSync('openid') && (Object.assign(formData, { openid: uni.getStorageSync('openid') }))
|
||||
uni.getStorageSync('pid') && (Object.assign(formData, { pid: uni.getStorageSync('pid') }))
|
||||
uni.getStorageSync('openid') && (Object.assign(formData, { openid: uni.getStorageSync('openid') }))
|
||||
uni.getStorageSync('unionid') && (Object.assign(formData, { unionid: uni.getStorageSync('unionid') }))
|
||||
});
|
||||
uni.getStorageSync('nickname') && (Object.assign(formData, { nickname: uni.getStorageSync('nickname') }))
|
||||
uni.getStorageSync('avatar') && (Object.assign(formData, { headimg: uni.getStorageSync('avatar') }))
|
||||
});
|
||||
|
||||
const rules = {
|
||||
'mobile': [
|
||||
@ -84,8 +88,7 @@
|
||||
},
|
||||
{
|
||||
validator(rule: any, value: any, callback: any) {
|
||||
let mobile = /^1[3-9]\d{9}$/;
|
||||
if (!mobile.test(value)){
|
||||
if (!uni.$u.test.mobile(value)){
|
||||
callback(new Error('请输入正确的手机号'))
|
||||
} else {
|
||||
callback()
|
||||
@ -115,14 +118,21 @@
|
||||
uni.showToast({ title: t('isAgreeTips'), icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if (loading.value) return
|
||||
loading.value = true
|
||||
|
||||
bindMobile(formData).then((res) => {
|
||||
memberStore.getMemberInfo()
|
||||
if(info.value.mobile){
|
||||
uni.removeStorageSync('isbindmobile');
|
||||
const request = info.value ? bindMobile : mobileLogin;
|
||||
|
||||
request(formData).then((res: any) => {
|
||||
if (info.value) {
|
||||
memberStore.getMemberInfo()
|
||||
if (info.value.mobile) {
|
||||
uni.removeStorageSync('isbindmobile');
|
||||
}
|
||||
} else {
|
||||
memberStore.setToken(res.data.token)
|
||||
useLogin().handleLoginBack()
|
||||
}
|
||||
show.value = false
|
||||
}).catch(() => {
|
||||
@ -134,7 +144,7 @@
|
||||
const open = ()=> {
|
||||
show.value = true
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
open
|
||||
})
|
||||
@ -148,4 +158,4 @@
|
||||
:deep(.u-checkbox){
|
||||
margin:0 !important;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@ -1,33 +1,41 @@
|
||||
<template>
|
||||
<u-popup :show="show" :round="10" @close="show = false" :closeable="true">
|
||||
<view class="mx-[30rpx] pb-[20rpx] pt-[40rpx] border-t">
|
||||
<view class="text-base">{{ t('getAvatarNickname') }}</view>
|
||||
<view class="text-sm mt-[18rpx] text-gray-400">{{ t('getAvatarNicknameTips') }}</view>
|
||||
</view>
|
||||
<u-form labelPosition="left" :model="formData" errorType='toast' :rules="rules" ref="formRef" labelWidth="65">
|
||||
<view class="mx-[30rpx]">
|
||||
<view class="mt-[20rpx]">
|
||||
<u-form-item :label="t('headimg')" prop="headimg" :border-bottom="true">
|
||||
<button class="m-0 my-[10rpx] p-0 w-[140rpx] h-[140rpx]" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
|
||||
<view class="w-full h-full flex items-center justify-center overflow-hidden">
|
||||
<u-image :src="img(formData.headimg)" width="140rpx" height="140rpx" v-if="formData.headimg" mode="aspectFill"></u-image>
|
||||
<u-icon name="plus" v-else></u-icon>
|
||||
</view>
|
||||
</button>
|
||||
</u-form-item>
|
||||
<u-form-item :label=" t('nickname')" prop="nickname" :border-bottom="true">
|
||||
<input type="nickname" v-model="formData.nickname" :placeholder="t('nicknamePlaceholder')" @blur="bindNickname">
|
||||
</u-form-item>
|
||||
<u-form-item :label="t('mobile')" prop="mobile" :border-bottom="true" v-if="isBindMobile">
|
||||
<input type="mobile" v-model="formData.mobile" :disabled="true" v-if="formData.mobile">
|
||||
<u-button :customStyle="{border:'none',color: 'var(--primary-color)',width:'140rpx', textAlign:'left',margin:'0rpx'}" :text="t('getMobile')" open-type="getPhoneNumber" @getphonenumber="memberStore.bindMobile" v-else></u-button>
|
||||
</u-form-item>
|
||||
</view>
|
||||
</view>
|
||||
<view class="p-[30rpx] mt-[20rpx]">
|
||||
<button :loading="loading" class="bg-[var(--primary-color)] text-[#fff] h-[80rpx] leading-[80rpx] rounded-[100rpx] text-[28rpx]" @click="confirm">{{t('confirm')}}</button>
|
||||
</view>
|
||||
</u-form>
|
||||
<u-popup :show="show" :round="10" @close="show = false">
|
||||
<view class="information-filling">
|
||||
<view class="relative">
|
||||
<view class="mx-[30rpx] pb-[20rpx] pt-[36rpx] border-t">
|
||||
<view class="text-[30rpx]">{{ t('getAvatarNickname') }}</view>
|
||||
<view class="text-[24rpx] mt-[18rpx] leading-[1.4] text-gray-400">{{ t('getAvatarNicknameTips') }}</view>
|
||||
</view>
|
||||
<text class="nc-iconfont nc-icon-guanbiV6xx2 !text-[40rpx] absolute top-[28rpx] right-[30rpx]" @click="show = false"></text>
|
||||
</view>
|
||||
<u-form labelPosition="left" :model="formData" errorType='toast' :rules="rules" ref="formRef" labelWidth="65">
|
||||
<view class="mx-[30rpx]">
|
||||
<view class="mt-[20rpx]">
|
||||
<u-form-item :label="t('headimg')" prop="headimg" :border-bottom="true">
|
||||
<button class="m-0 p-0 w-[120rpx] h-[120rpx]" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
|
||||
<view class="w-full h-full flex items-center justify-center overflow-hidden">
|
||||
<u-image :src="img(formData.headimg)" width="120rpx" height="120rpx" v-if="formData.headimg" mode="aspectFill"></u-image>
|
||||
<u-icon name="plus" v-else></u-icon>
|
||||
</view>
|
||||
</button>
|
||||
</u-form-item>
|
||||
<u-form-item :label=" t('nickname')" prop="nickname" :border-bottom="true">
|
||||
<input type="nickname" v-model="formData.nickname" :placeholder="t('nicknamePlaceholder')" placeholderClass="text-[28rpx]" class="text-[28rpx]" @blur="bindNickname">
|
||||
</u-form-item>
|
||||
<u-form-item :label="t('mobile')" prop="mobile" :border-bottom="true" v-if="isBindMobile">
|
||||
<input type="mobile" v-model="formData.mobile" :disabled="true" v-if="formData.mobile">
|
||||
<template v-else>
|
||||
<u-button v-if="info" :customStyle="{border:'none',color: 'var(--primary-color)',width:'140rpx', textAlign:'left',margin:'0rpx'}" :text="t('getMobile')" open-type="getPhoneNumber" @getphonenumber="memberStore.bindMobile"></u-button>
|
||||
<u-button v-else :customStyle="{border:'none',color: 'var(--primary-color)',width:'140rpx', textAlign:'left',margin:'0rpx'}" :text="t('getMobile')" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber"></u-button>
|
||||
</template>
|
||||
</u-form-item>
|
||||
</view>
|
||||
</view>
|
||||
<view class="p-[30rpx] mt-[20rpx]">
|
||||
<button :loading="loading" class="bg-[var(--primary-color)] text-[#fff] h-[80rpx] leading-[80rpx] rounded-[100rpx] text-[28rpx]" @click="confirm">{{t('confirm')}}</button>
|
||||
</view>
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<!-- 小程序隐私协议 -->
|
||||
<wx-privacy-popup ref="wxPrivacyPopupRef"></wx-privacy-popup>
|
||||
@ -40,14 +48,16 @@
|
||||
import { t } from '@/locale'
|
||||
import useMemberStore from '@/stores/member'
|
||||
import { img } from '@/utils/common'
|
||||
import { modifyMember } from '@/app/api/member'
|
||||
import { modifyMember,getMobile } from '@/app/api/member'
|
||||
import { fetchBase64Image } from '@/app/api/system'
|
||||
import { useLogin } from '@/hooks/useLogin'
|
||||
import useConfigStore from '@/stores/config'
|
||||
|
||||
const show = ref(false)
|
||||
const loading = ref(false)
|
||||
const memberStore = useMemberStore()
|
||||
const info = computed(() => memberStore.info)
|
||||
const config = useConfigStore()
|
||||
|
||||
const formData = reactive({
|
||||
nickname: '',
|
||||
@ -110,7 +120,7 @@
|
||||
},
|
||||
'mobile': {
|
||||
type: 'string',
|
||||
required: isBindMobile.value ? true : false,
|
||||
required: config.login.is_bind_mobile ? true : false,
|
||||
message: t('mobileTips'),
|
||||
trigger: ['blur', 'change'],
|
||||
}
|
||||
@ -118,33 +128,68 @@
|
||||
|
||||
const formRef: any = ref(null)
|
||||
|
||||
// 获取手机号
|
||||
const getPhoneNumber = (e:any)=> {
|
||||
if (e.detail.errMsg == 'getPhoneNumber:ok') {
|
||||
uni.showLoading({ title: '' })
|
||||
getMobile({
|
||||
mobile_code: e.detail.code
|
||||
}).then((res: any) => {
|
||||
formData.mobile = res.data.mobile
|
||||
uni.hideLoading()
|
||||
}).catch(() => {
|
||||
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' })
|
||||
}
|
||||
}
|
||||
|
||||
const confirm = async () => {
|
||||
formRef.value.validate().then(async() => {
|
||||
if (loading.value) return
|
||||
loading.value = true
|
||||
|
||||
// 修改头像
|
||||
await modifyMember({ field: 'headimg', value: formData.headimg }).then(() => {
|
||||
memberStore.info.headimg = formData.headimg
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
if (!loading.value) return
|
||||
if (info.value) {
|
||||
// 修改头像
|
||||
await modifyMember({ field: 'headimg', value: formData.headimg }).then(() => {
|
||||
memberStore.info.headimg = formData.headimg
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
if (!loading.value) return
|
||||
|
||||
// 修改昵称
|
||||
modifyMember({ field: 'nickname', value: formData.nickname }).then(() => {
|
||||
memberStore.info.nickname = formData.nickname
|
||||
loading.value = false
|
||||
show.value = false
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
// #ifdef MP-WEIXIN
|
||||
const login = useLogin()
|
||||
if (info.value && !info.value.weapp_openid) {
|
||||
login.getAuthCode({ updateFlag: true }) // 更新oppenid
|
||||
// 修改昵称
|
||||
modifyMember({ field: 'nickname', value: formData.nickname }).then(() => {
|
||||
memberStore.info.nickname = formData.nickname
|
||||
loading.value = false
|
||||
show.value = false
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
const login = useLogin()
|
||||
if (info.value && !info.value.weapp_openid) {
|
||||
login.getAuthCode({ updateFlag: true }) // 更新oppenid
|
||||
}
|
||||
// #endif
|
||||
} else {
|
||||
// todo 如果没有登录过,则注册
|
||||
// #ifdef MP-WEIXIN
|
||||
const login = useLogin()
|
||||
login.getAuthCode({ backFlag: true, ...formData }) // 注册
|
||||
// #endif
|
||||
}
|
||||
// #endif
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@ -1,47 +0,0 @@
|
||||
<!-- 下拉刷新区域 -->
|
||||
<template>
|
||||
<view v-if="mOption.use" class="mescroll-downwarp" :style="{'background-color':mOption.bgColor,'color':mOption.textColor}">
|
||||
<view class="downwarp-content">
|
||||
<view class="downwarp-progress" :class="{'mescroll-rotate': isDownLoading}" :style="{'border-color':mOption.textColor, 'transform':downRotate}"></view>
|
||||
<view class="downwarp-tip">{{downText}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
option: Object , // down的配置项
|
||||
type: Number, // 下拉状态(inOffset:1, outOffset:2, showLoading:3, endDownScroll:4)
|
||||
rate: Number // 下拉比率 (inOffset: rate<1; outOffset: rate>=1)
|
||||
},
|
||||
computed: {
|
||||
// 支付宝小程序需写成计算属性,prop定义default仍报错
|
||||
mOption(){
|
||||
return this.option || {}
|
||||
},
|
||||
// 是否在加载中
|
||||
isDownLoading(){
|
||||
return this.type === 3
|
||||
},
|
||||
// 旋转的角度
|
||||
downRotate(){
|
||||
return 'rotate(' + 360 * this.rate + 'deg)'
|
||||
},
|
||||
// 文本提示
|
||||
downText(){
|
||||
switch (this.type){
|
||||
case 1: return this.mOption.textInOffset;
|
||||
case 2: return this.mOption.textOutOffset;
|
||||
case 3: return this.mOption.textLoading;
|
||||
case 4: return this.mOption.textLoading;
|
||||
default: return this.mOption.textInOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@import "./mescroll-down.css";
|
||||
</style>
|
||||
@ -1,39 +0,0 @@
|
||||
<!-- 上拉加载区域 -->
|
||||
<template>
|
||||
<view class="mescroll-upwarp" :style="{'background-color':mOption.bgColor,'color':mOption.textColor}">
|
||||
<!-- 加载中 (此处不能用v-if,否则android小程序快速上拉可能会不断触发上拉回调) -->
|
||||
<view v-show="isUpLoading">
|
||||
<view class="upwarp-progress mescroll-rotate" :style="{'border-color':mOption.textColor}"></view>
|
||||
<view class="upwarp-tip">{{ mOption.textLoading }}</view>
|
||||
</view>
|
||||
<!-- 无数据 -->
|
||||
<view v-if="isUpNoMore" class="upwarp-nodata">{{ mOption.textNoMore }}</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
option: Object, // up的配置项
|
||||
type: Number // 上拉加载的状态:0(loading前),1(loading中),2(没有更多了)
|
||||
},
|
||||
computed: {
|
||||
// 支付宝小程序需写成计算属性,prop定义default仍报错
|
||||
mOption() {
|
||||
return this.option || {};
|
||||
},
|
||||
// 加载中
|
||||
isUpLoading() {
|
||||
return this.type === 1;
|
||||
},
|
||||
// 没有更多了
|
||||
isUpNoMore() {
|
||||
return this.type === 2;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@import './mescroll-up.css';
|
||||
</style>
|
||||
@ -1,47 +0,0 @@
|
||||
/**
|
||||
* mescroll-body写在子组件时,需通过mescroll的mixins补充子组件缺少的生命周期
|
||||
*/
|
||||
const MescrollCompMixin = {
|
||||
// 因为子组件无onPageScroll和onReachBottom的页面生命周期,需在页面传递进到子组件 (一级)
|
||||
onPageScroll(e) {
|
||||
this.handlePageScroll(e)
|
||||
},
|
||||
onReachBottom() {
|
||||
this.handleReachBottom()
|
||||
},
|
||||
// 当down的native: true时, 还需传递此方法进到子组件
|
||||
onPullDownRefresh(){
|
||||
this.handlePullDownRefresh()
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
mescroll: { // mescroll-body写在子子子...组件的情况 (多级)
|
||||
onPageScroll: e=>{
|
||||
this.handlePageScroll(e)
|
||||
},
|
||||
onReachBottom: ()=>{
|
||||
this.handleReachBottom()
|
||||
},
|
||||
onPullDownRefresh: ()=>{
|
||||
this.handlePullDownRefresh()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
handlePageScroll(e){
|
||||
let item = this.$refs["mescrollItem"];
|
||||
if(item && item.mescroll) item.mescroll.onPageScroll(e);
|
||||
},
|
||||
handleReachBottom(){
|
||||
let item = this.$refs["mescrollItem"];
|
||||
if(item && item.mescroll) item.mescroll.onReachBottom();
|
||||
},
|
||||
handlePullDownRefresh(){
|
||||
let item = this.$refs["mescrollItem"];
|
||||
if(item && item.mescroll) item.mescroll.onPullDownRefresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default MescrollCompMixin;
|
||||
@ -1,66 +0,0 @@
|
||||
/**
|
||||
* mescroll-more-item的mixins, 仅在多个 mescroll-body 写在子组件时使用 (参考 mescroll-more 案例)
|
||||
*/
|
||||
const MescrollMoreItemMixin = {
|
||||
// 支付宝小程序不支持props的mixin,需写在具体的页面中
|
||||
// #ifndef MP-ALIPAY || MP-DINGTALK
|
||||
props:{
|
||||
i: Number, // 每个tab页的专属下标
|
||||
index: { // 当前tab的下标
|
||||
type: Number,
|
||||
default(){
|
||||
return 0
|
||||
}
|
||||
}
|
||||
},
|
||||
// #endif
|
||||
data() {
|
||||
return {
|
||||
downOption:{
|
||||
auto:false // 不自动加载
|
||||
},
|
||||
upOption:{
|
||||
auto:false // 不自动加载
|
||||
},
|
||||
isInit: false // 当前tab是否已初始化
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
// 监听下标的变化
|
||||
index(val){
|
||||
if (this.i === val && !this.isInit) this.mescrollTrigger()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 以ref的方式初始化mescroll对象 (兼容字节跳动小程序)
|
||||
mescrollInitByRef() {
|
||||
if(!this.mescroll || !this.mescroll.resetUpScroll){
|
||||
// 字节跳动小程序编辑器不支持一个页面存在相同的ref, 多mescroll的ref需动态生成, 格式为'mescrollRef下标'
|
||||
let mescrollRef = this.$refs.mescrollRef || this.$refs['mescrollRef'+this.i];
|
||||
if(mescrollRef) this.mescroll = mescrollRef.mescroll
|
||||
}
|
||||
},
|
||||
// mescroll组件初始化的回调,可获取到mescroll对象 (覆盖mescroll-mixins.js的mescrollInit, 为了标记isInit)
|
||||
mescrollInit(mescroll) {
|
||||
this.mescroll = mescroll;
|
||||
this.mescrollInitByRef && this.mescrollInitByRef(); // 兼容字节跳动小程序
|
||||
// 自动加载当前tab的数据
|
||||
if(this.i === this.index){
|
||||
this.mescrollTrigger()
|
||||
}
|
||||
},
|
||||
// 主动触发加载
|
||||
mescrollTrigger(){
|
||||
this.isInit = true; // 标记为true
|
||||
if (this.mescroll) {
|
||||
if (this.mescroll.optDown.use) {
|
||||
this.mescroll.triggerDownScroll();
|
||||
} else{
|
||||
this.mescroll.triggerUpScroll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default MescrollMoreItemMixin;
|
||||
@ -1,74 +0,0 @@
|
||||
/**
|
||||
* mescroll-body写在子组件时, 需通过mescroll的mixins补充子组件缺少的生命周期
|
||||
*/
|
||||
const MescrollMoreMixin = {
|
||||
data() {
|
||||
return {
|
||||
tabIndex: 0, // 当前tab下标
|
||||
mescroll: { // mescroll-body写在子子子...组件的情况 (多级)
|
||||
onPageScroll: e=>{
|
||||
this.handlePageScroll(e)
|
||||
},
|
||||
onReachBottom: ()=>{
|
||||
this.handleReachBottom()
|
||||
},
|
||||
onPullDownRefresh: ()=>{
|
||||
this.handlePullDownRefresh()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// 因为子组件无onPageScroll和onReachBottom的页面生命周期,需在页面传递进到子组件
|
||||
onPageScroll(e) {
|
||||
this.handlePageScroll(e)
|
||||
},
|
||||
onReachBottom() {
|
||||
this.handleReachBottom()
|
||||
},
|
||||
// 当down的native: true时, 还需传递此方法进到子组件
|
||||
onPullDownRefresh(){
|
||||
this.handlePullDownRefresh()
|
||||
},
|
||||
methods:{
|
||||
handlePageScroll(e){
|
||||
let mescroll = this.getMescroll(this.tabIndex);
|
||||
mescroll && mescroll.onPageScroll(e);
|
||||
},
|
||||
handleReachBottom(){
|
||||
let mescroll = this.getMescroll(this.tabIndex);
|
||||
mescroll && mescroll.onReachBottom();
|
||||
},
|
||||
handlePullDownRefresh(){
|
||||
let mescroll = this.getMescroll(this.tabIndex);
|
||||
mescroll && mescroll.onPullDownRefresh();
|
||||
},
|
||||
// 根据下标获取对应子组件的mescroll
|
||||
getMescroll(i){
|
||||
if(!this.mescrollItems) this.mescrollItems = [];
|
||||
if(!this.mescrollItems[i]) {
|
||||
// v-for中的refs
|
||||
let vForItem = this.$refs["mescrollItem"];
|
||||
if(vForItem){
|
||||
this.mescrollItems[i] = vForItem[i]
|
||||
}else{
|
||||
// 普通的refs,不可重复
|
||||
this.mescrollItems[i] = this.$refs["mescrollItem"+i];
|
||||
}
|
||||
}
|
||||
let item = this.mescrollItems[i]
|
||||
return item ? item.mescroll : null
|
||||
},
|
||||
// 切换tab,恢复滚动条位置
|
||||
tabChange(i){
|
||||
let mescroll = this.getMescroll(i);
|
||||
if(mescroll){
|
||||
// 延时(比$nextTick靠谱一些),确保元素已渲染
|
||||
setTimeout(()=>{
|
||||
mescroll.scrollTo(mescroll.getScrollTop(),0)
|
||||
},30)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default MescrollMoreMixin;
|
||||
@ -94,5 +94,4 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<view class="absolute top-[36rpx] right-[36rpx] text-[24rpx] text-[var(--text-color-light6)] leading-[30rpx] z-10" @click="clearDate">清除</view>
|
||||
<view class="px-[var(--popup-sidebar-m)] mb-[20rpx] mt-[10rpx]">
|
||||
<view class="flex items-center justify-between mb-[30rpx]">
|
||||
<view class="w-[160rpx] h-[66rpx] box-border flex-center rounded-[33rpx] bg-[var(--temp-bg)] text-center text-[26rpx] text-[var(--text-color-light6)] border-[2rpx] border-solid border-[var(--temp-bg)]" v-for="(item,index) in curselectDate" :key="'a'+index" :class="{'text-primary !border-[var(--primary-color)] !bg-[rgba(239,0,12,0.04)]': currentValue.type == item.type}" @click="loadDateFn(item)">{{item.name}}</view>
|
||||
<view class="w-[160rpx] h-[66rpx] box-border flex-center rounded-[33rpx] bg-[var(--temp-bg)] text-center text-[26rpx] text-[var(--text-color-light6)] border-[2rpx] border-solid border-[var(--temp-bg)]" v-for="(item,index) in curselectDate" :key="'a'+index" :class="{'text-primary !border-[var(--primary-color)] !bg-[var(--primary-color-light)]': currentValue.type == item.type}" @click="loadDateFn(item)">{{item.name}}</view>
|
||||
</view>
|
||||
<view class="flex items-center justify-between">
|
||||
<view class="w-[316rpx] h-[66rpx] box-border leading-[62rpx] rounded-[33rpx] bg-[var(--temp-bg)] text-center text-[26rpx] text-[var(--text-color-light6)] border-[2rpx] border-solid border-[var(--temp-bg)]" :class="{'text-primary !border-[var(--primary-color)] !bg-[var(--primary-color-light)]': currentValue.type == 'first'}" @click="currentValue.type = 'first'">{{dateList.nowDate[0].substr(0,10)}}</view>
|
||||
|
||||
237
uni-app/src/components/share-popup/share-popup.vue
Normal file
237
uni-app/src/components/share-popup/share-popup.vue
Normal file
@ -0,0 +1,237 @@
|
||||
<template>
|
||||
<!-- 分享弹窗 -->
|
||||
<view @touchmove.prevent.stop class="share-popup">
|
||||
<u-popup :show="sharePopupShow" type="bottom" @close="sharePopupClose" overlayOpacity="0.8">
|
||||
<view @touchmove.prevent.stop>
|
||||
<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>
|
||||
<!-- #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="sharePopupClose"><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 } from 'vue';
|
||||
import { img, copy } from '@/utils/common';
|
||||
|
||||
const props = defineProps({
|
||||
copyUrl: { // 例 "/wap/addon/shop_fenxiao/pages/goods"
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
copyUrlParam: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const emits = defineEmits(['close'])
|
||||
|
||||
const sharePopupShow = ref(false);
|
||||
|
||||
// 复制
|
||||
const copyUrl = () => {
|
||||
let data = ''
|
||||
if (props.copyUrl) {
|
||||
let pathName = location.pathname;
|
||||
let packageArr: any = ['/app/', '/addon/'];
|
||||
for (let i = 0; i < packageArr.length; i++) {
|
||||
if (pathName.indexOf(packageArr[i]) != -1) {
|
||||
pathName = pathName.substr(0, pathName.indexOf(packageArr[i]));
|
||||
}
|
||||
}
|
||||
data = location.origin + pathName + props.copyUrl + props.copyUrlParam;
|
||||
} else {
|
||||
data = location.origin + location.pathname + props.copyUrlParam;
|
||||
}
|
||||
copy(data, () => {
|
||||
sharePopupShow.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
const openShare = ()=>{
|
||||
sharePopupShow.value = true
|
||||
|
||||
}
|
||||
|
||||
|
||||
const show = ref(false);
|
||||
|
||||
const closeDialog = ()=> {
|
||||
show.value = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const shareTop: any = ref(0)
|
||||
/************ 获取微信头部-start ****************/
|
||||
// 获取系统状态栏的高度
|
||||
let menuButtonInfo: any = {};
|
||||
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API,尚未兼容)
|
||||
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
|
||||
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
||||
shareTop.value = menuButtonInfo.top + menuButtonInfo.height + 'px';
|
||||
// #endif
|
||||
/************ 获取微信头部-end ****************/
|
||||
|
||||
const sharePopupClose = ()=>{
|
||||
sharePopupShow.value = false;
|
||||
emits('close');
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
.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>
|
||||
59
uni-app/src/components/sow-show/sow-show.vue
Normal file
59
uni-app/src/components/sow-show/sow-show.vue
Normal file
@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<view class="card-template mt-[var(--top-m)]" v-if="items.list && items.list.length>0">
|
||||
<view class="flex justify-between items-center" @click="toLink">
|
||||
<view class="text-[30rpx]">
|
||||
<text>种草秀</text>
|
||||
<text class="ml-[6rpx] text-[24rpx] text-[var(--text-color-light9)]" v-if="items.count">({{items.count}})</text>
|
||||
</view>
|
||||
<text class="nc-iconfont nc-icon-youV6xx text-[26rpx] text-[var(--text-color-light6)] ml-[8rpx]"></text>
|
||||
</view>
|
||||
|
||||
<view class="grid grid-cols-3 gap-2 mt-[20rpx]">
|
||||
<view class="w-[210rpx] h-[210rpx]" v-for="(item, index) in items.list" :key="index" @click="handleClick(item)">
|
||||
<image :src="img(item.content_cover)" mode="aspectFill" class="w-[210rpx] h-[210rpx] rounded-[20rpx]" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref,onMounted} from 'vue';
|
||||
import { img,redirect } from '@/utils/common';
|
||||
|
||||
const props = defineProps({
|
||||
items: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({}),
|
||||
}
|
||||
});
|
||||
|
||||
const treasureId = ref(null);
|
||||
|
||||
function extractTreasureId(url) {
|
||||
const match = url.match(/treasure_id=(\d+)/);
|
||||
return match ? match[1] : null;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (props.items && props.items.url) {
|
||||
treasureId.value = extractTreasureId(props.items.url);
|
||||
}
|
||||
});
|
||||
|
||||
const toLink = () => {
|
||||
redirect({ url: '/addon/sow_community/pages/sow_show', param: { treasure_id: treasureId.value }})
|
||||
}
|
||||
|
||||
const handleClick = (item:any) => {
|
||||
if(item.content_type == 1){
|
||||
redirect({url: '/addon/sow_community/pages/image/detail', param: { content_id: item.content_id }})
|
||||
}else{
|
||||
redirect({url: '/addon/sow_community/pages/video/detail', param: { content_id: item.content_id }})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
@ -1,15 +1,14 @@
|
||||
<template>
|
||||
<template v-if="tabbar && Object.keys(tabbar).length">
|
||||
<u-tabbar :value="value" zIndex="9999" :fixed="true" :placeholder="true" :safeAreaInsetBottom="true"
|
||||
:inactive-color="tabbar.value.textColor" :active-color="tabbar.value.textHoverColor">
|
||||
<u-tabbar :value="value" zIndex="9999" :fixed="true" :placeholder="true" :safeAreaInsetBottom="true" :inactive-color="tabbar.value.textColor" :active-color="tabbar.value.textHoverColor" :border="props.border">
|
||||
<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]" :custom-style="{'background-color': tabbar.value.backgroundColor}" :text="item.text"
|
||||
:icon="img(value == item.link.url ? item.iconSelectPath : item.iconPath)" :name="item.link.url"
|
||||
v-if="tabbar.value.type == 1" @click="itemBtn(item.link.url)"></u-tabbar-item>
|
||||
<u-tabbar-item class="py-[5rpx]" :style="{'background-color': tabbar.value.backgroundColor}"
|
||||
<u-tabbar-item class="py-[5rpx]" :custom-style="{'background-color': tabbar.value.backgroundColor}"
|
||||
:icon="img(value == item.link.url ? item.iconSelectPath : item.iconPath)" :name="item.link.url"
|
||||
v-if="tabbar.value.type == 2" @click="itemBtn(item.link.url)"></u-tabbar-item>
|
||||
<u-tabbar-item class="py-[5rpx]" :style="{'background-color': tabbar.value.backgroundColor}" :text="item.text" :name="item.link.url"
|
||||
<u-tabbar-item class="py-[5rpx]" :custom-style="{'background-color': tabbar.value.backgroundColor}" :text="item.text" :name="item.link.url"
|
||||
v-if="tabbar.value.type == 3" @click="itemBtn(item.link.url)"></u-tabbar-item>
|
||||
</block>
|
||||
</u-tabbar>
|
||||
@ -18,26 +17,40 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref,reactive,computed,watch } from 'vue'
|
||||
import { reactive, computed, watch, nextTick, getCurrentInstance } from 'vue'
|
||||
import { redirect, currRoute,currShareRoute, img } from '@/utils/common'
|
||||
import useConfigStore from '@/stores/config'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
|
||||
const props = defineProps({
|
||||
addon: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
addon: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
color: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
backgroundColor: '', // 背景色
|
||||
textColor: '', // 文字颜色
|
||||
textHoverColor: '', // 文字选中颜色
|
||||
};
|
||||
}
|
||||
},
|
||||
border: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
})
|
||||
|
||||
let addon:any = props.addon;
|
||||
let addon: any = props.addon;
|
||||
|
||||
const configStore = useConfigStore()
|
||||
if(!addon && configStore.addon){
|
||||
addon = configStore.addon;
|
||||
if(!addon && configStore.addon) {
|
||||
addon = configStore.addon;
|
||||
}
|
||||
|
||||
const tabbar:any = reactive({})
|
||||
const tabbar: any = reactive({})
|
||||
|
||||
const setTabbar = ()=> {
|
||||
let list = cloneDeep(useConfigStore().tabbarList);
|
||||
@ -73,11 +86,17 @@
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (props.color) {
|
||||
for (let key in props.color) {
|
||||
if (props.color[key] && tabbar.value[key]) {
|
||||
tabbar.value[key] = props.color[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setTabbar()
|
||||
@ -92,6 +111,16 @@
|
||||
, { immediate: true }
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.color,
|
||||
(newValue, oldValue) => {
|
||||
if(newValue && oldValue && newValue != oldValue) {
|
||||
setTabbar()
|
||||
}
|
||||
}
|
||||
, { immediate: true,deep: true }
|
||||
)
|
||||
|
||||
if(!props.addon) {
|
||||
watch(
|
||||
() => useConfigStore().tabbarList,
|
||||
@ -113,40 +142,46 @@
|
||||
return '/' + currRoute() + (str.length > 0 ? '?' + str.join('&') : '')
|
||||
})
|
||||
|
||||
// const tabbarChange = (url : string) => {
|
||||
// 外部链接
|
||||
// }
|
||||
|
||||
const itemBtn = (url)=>{
|
||||
const itemBtn = (url: any)=> {
|
||||
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
|
||||
|
||||
// #ifdef H5
|
||||
window.location.href = url;
|
||||
// #endif
|
||||
|
||||
// #ifdef MP
|
||||
redirect({
|
||||
url: '/app/pages/webview/index',
|
||||
param: { src: encodeURIComponent(url) }
|
||||
});
|
||||
// #endif
|
||||
} else {
|
||||
let query:any = currShareRoute().params;
|
||||
let query: any = currShareRoute().params;
|
||||
let str = [];
|
||||
for (let key in query) {
|
||||
str.push(key + '=' + query[key]);
|
||||
}
|
||||
if(url == ('/' + currRoute()) && !str.length) return
|
||||
redirect({ url,mode: 'reLaunch' })
|
||||
if (url == ('/' + currRoute()) && !str.length) return
|
||||
redirect({ url, mode: 'reLaunch' })
|
||||
}
|
||||
}
|
||||
defineExpose({
|
||||
})
|
||||
|
||||
const instance = getCurrentInstance();
|
||||
nextTick(() => {
|
||||
const query = uni.createSelectorQuery().in(instance);
|
||||
query.select('.tab-bar-placeholder').boundingClientRect((data: any) => {
|
||||
let height = data ? data.height : 0;
|
||||
let tabbarInfo = {
|
||||
height: height
|
||||
};
|
||||
uni.setStorageSync('tabbarInfo', tabbarInfo);
|
||||
}).exec();
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tab-bar-placeholder {
|
||||
padding-bottom: calc(constant(safe-area-inset-bottom) + 112rpx);
|
||||
padding-bottom: calc(env(safe-area-inset-bottom) + 112rpx);
|
||||
padding-bottom: calc(constant(safe-area-inset-bottom) + 50px);
|
||||
padding-bottom: calc(env(safe-area-inset-bottom) + 50px);
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -3,13 +3,13 @@
|
||||
<view class="u-navbar" :class="{'fixed': props.scrollBool != -1, 'absolute': props.scrollBool == -1}" :style="{ backgroundColor: bgColor}">
|
||||
<view class="navbar-inner" :style="{ width: '100%', height: placeholderHeight + 'px' }">
|
||||
<view v-if="topStatusBarData.style == 'style-1'" class="content-wrap" :class="[topStatusBarData.textAlign]" :style="navbarInnerStyle">
|
||||
<view v-if="isBack && isBackShow" class="back-wrap -ml-[16rpx] text-[27px] nc-iconfont nc-icon-zuoV6xx" :style="{ color: titleTextColor }" @tap="goBack"></view>
|
||||
<view v-if="isBack" class="back-wrap -ml-[16rpx] text-[26px] nc-iconfont nc-icon-zuoV6xx" :style="{ color: titleTextColor }" @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 -ml-[16rpx] text-[27px] nc-iconfont nc-icon-zuoV6xx" :style="{ color: titleTextColor }" @tap="goBack"></view>
|
||||
<view v-if="isBack" class="back-wrap -ml-[16rpx] text-[26px] nc-iconfont nc-icon-zuoV6xx" :style="{ color: titleTextColor }" @tap="goBack"></view>
|
||||
<view class="title-wrap" :style="{ color: topStatusBarData.textColor }">
|
||||
<view>
|
||||
<image :src="img(topStatusBarData.imgUrl)" mode="heightFix"></image>
|
||||
@ -19,7 +19,7 @@
|
||||
</view>
|
||||
|
||||
<view v-if="topStatusBarData.style == 'style-3'" :style="navbarInnerStyle" class="content-wrap">
|
||||
<view v-if="isBack && isBackShow" class="back-wrap -ml-[16rpx] text-[27px] nc-iconfont nc-icon-zuoV6xx" :style="{ color: titleTextColor }" @tap="goBack"></view>
|
||||
<view v-if="isBack" class="back-wrap -ml-[16rpx] text-[26px] nc-iconfont nc-icon-zuoV6xx" :style="{ color: titleTextColor }" @tap="goBack"></view>
|
||||
<view class="title-wrap" @click="diyStore.toRedirect(topStatusBarData.link)">
|
||||
<image :src="img(topStatusBarData.imgUrl)" mode="heightFix"></image>
|
||||
</view>
|
||||
@ -31,7 +31,7 @@
|
||||
</view>
|
||||
|
||||
<view v-if="topStatusBarData.style == 'style-4'" :style="navbarInnerStyle" class="content-wrap">
|
||||
<view v-if="isBack && isBackShow" class="back-wrap -ml-[16rpx] text-[27px] nc-iconfont nc-icon-zuoV6xx" :style="{ color: titleTextColor }" @tap="goBack"></view>
|
||||
<view v-if="isBack" class="back-wrap -ml-[16rpx] text-[26px] nc-iconfont nc-icon-zuoV6xx" :style="{ color: titleTextColor }" @tap="goBack"></view>
|
||||
<text class="nc-iconfont nc-icon-dizhiguanliV6xx text-[28rpx]" :style="{ color: topStatusBarData.textColor }"></text>
|
||||
<view class="title-wrap" @click.stop="locationVal.reposition()" :style="{ color: topStatusBarData.textColor }" v-if="systemStore.diyAddressInfo">{{ systemStore.diyAddressInfo.community }}</view>
|
||||
<view class="title-wrap" @click.stop="locationVal.reposition()" :style="{ color: topStatusBarData.textColor }" v-else>{{ systemStore.defaultPositionAddress }}</view>
|
||||
@ -113,7 +113,7 @@ const topStatusBarData = computed(() => {
|
||||
const navbarInnerStyle = computed(() => {
|
||||
let style = '';
|
||||
|
||||
if(props.isBack && isBackShow.value){
|
||||
if(props.isBack){
|
||||
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
|
||||
@ -191,27 +191,33 @@ if(componentsScrollVal){
|
||||
/******************************* 存储滚动值-end ***********************/
|
||||
|
||||
/******************************* 返回按钮-start ***********************/
|
||||
const isBackShow = ref(false);
|
||||
// const isBackShow = ref(false);
|
||||
let pages = getCurrentPages();
|
||||
|
||||
// 返回按钮的函数
|
||||
const goBack = () => {
|
||||
// 兼容小程序,未登录状态下点击某个功能跳转到登录页,不登录无法返回的情况
|
||||
if(pages.length == 1 && pages[0].route == 'app/pages/auth/index'){
|
||||
uni.getStorage({
|
||||
key: 'loginBack',
|
||||
success: (res: any) => {
|
||||
res ? redirect(
|
||||
{
|
||||
...res.data,
|
||||
mode: 'redirectTo'
|
||||
}
|
||||
) : redirect({ url: '/app/pages/index/index', mode: 'switchTab' })
|
||||
},
|
||||
fail: (res) => {
|
||||
redirect({ url: '/app/pages/index/index', mode: 'switchTab' })
|
||||
}
|
||||
})
|
||||
if (pages.length === 1) {
|
||||
if (pages[0].route === 'app/pages/auth/index') {
|
||||
uni.getStorage({
|
||||
key: 'loginBack',
|
||||
success: (res: any) => {
|
||||
res ? redirect(
|
||||
{
|
||||
...res.data,
|
||||
mode: 'redirectTo'
|
||||
}
|
||||
) : redirect({ url: '/app/pages/index/index', mode: 'switchTab' })
|
||||
},
|
||||
fail: (res) => {
|
||||
redirect({ url: '/app/pages/index/index', mode: 'switchTab' })
|
||||
}
|
||||
});
|
||||
} else if (typeof props.customBack === 'function') {
|
||||
props.customBack();
|
||||
}else{
|
||||
redirect({ url: '/app/pages/index/index', mode: 'switchTab' });
|
||||
}
|
||||
}else{
|
||||
// 如果自定义了点击返回按钮的函数,则执行,否则执行返回逻辑
|
||||
if (typeof props.customBack === 'function') {
|
||||
@ -259,12 +265,12 @@ const navbarPlaceholderHeight = () => {
|
||||
let imageAdsSameScreen = ref(false);
|
||||
onMounted(() => {
|
||||
navbarPlaceholderHeight();
|
||||
if (pages.length > 1) {
|
||||
isBackShow.value = true;
|
||||
// 兼容小程序,未登录状态下点击某个功能跳转到登录页,不登录无法返回的情况
|
||||
}else if(pages.length == 1 && pages[0].route == 'app/pages/auth/index'){
|
||||
isBackShow.value = true;
|
||||
}
|
||||
// if (pages.length > 1) {
|
||||
// isBackShow.value = true;
|
||||
// // 兼容小程序,未登录状态下点击某个功能跳转到登录页,不登录无法返回的情况
|
||||
// }else if(pages.length == 1 && pages[0].route == 'app/pages/auth/index'){
|
||||
// isBackShow.value = true;
|
||||
// }
|
||||
// 刷新定位
|
||||
locationVal.refresh();
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { ref, reactive, computed } from 'vue';
|
||||
import { onLoad, onShow, onHide, onPullDownRefresh, onPageScroll, onUnload } from '@dcloudio/uni-app';
|
||||
import { onLoad, onShow, onHide, onPageScroll, onUnload } from '@dcloudio/uni-app';
|
||||
import { img, handleOnloadParams } from '@/utils/common';
|
||||
import { getDiyInfo } from '@/app/api/diy';
|
||||
import useDiyStore from '@/app/stores/diy';
|
||||
@ -8,12 +8,12 @@ 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('')
|
||||
let currRoute = "" //当前路由
|
||||
const currRoute = ref('') //当前路由
|
||||
const requestData: any = reactive({});
|
||||
|
||||
// 自定义页面 数据
|
||||
const diyData = reactive({
|
||||
@ -43,11 +43,11 @@ export function useDiy(params: any = {}) {
|
||||
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 + ';';
|
||||
}
|
||||
if(data.value.global.bottomTabBarSwitch){
|
||||
style += 'min-height:calc(100vh - 50px);';
|
||||
}else{
|
||||
style += 'min-height:calc(100vh);';
|
||||
}
|
||||
if (data.value.global.bottomTabBarSwitch) {
|
||||
style += 'min-height:calc(100vh - 50px);';
|
||||
} else {
|
||||
style += 'min-height:calc(100vh);';
|
||||
}
|
||||
if (data.value.global.bgUrl) {
|
||||
style += `background-image:url('${ img(data.value.global.bgUrl) }');`;
|
||||
}
|
||||
@ -86,14 +86,14 @@ export function useDiy(params: any = {}) {
|
||||
onShow(() => {
|
||||
/******** 解决跳转自定义页面空白问题-第二步-start **********/
|
||||
let curPage: any = getCurrentPages();
|
||||
currRoute = curPage[curPage.length - 1] ? curPage[curPage.length - 1].route : ''; //获取当前页面的路由
|
||||
currRoute.value = curPage[curPage.length - 1] ? curPage[curPage.length - 1].route : ''; //获取当前页面的路由
|
||||
let urlArr = []
|
||||
if (uni.getStorageSync('diyPageBlank')) {
|
||||
urlArr = uni.getStorageSync('diyPageBlank');
|
||||
}
|
||||
if (!urlArr.length || urlArr.length && urlArr.indexOf(currRoute) == -1) {
|
||||
if (!urlArr.length || urlArr.length && urlArr.indexOf(currRoute.value) == -1) {
|
||||
diyStore.topFixedStatus = 'home'
|
||||
} else if (urlArr.length && urlArr.indexOf(currRoute) != -1) {
|
||||
} else if (urlArr.length && urlArr.indexOf(currRoute.value) != -1) {
|
||||
diyStore.topFixedStatus = 'diy'
|
||||
}
|
||||
/******** 解决跳转自定义页面空白问题-第二步-end **********/
|
||||
@ -107,12 +107,13 @@ export function useDiy(params: any = {}) {
|
||||
name: name.value,
|
||||
template: template.value
|
||||
}).then((res: any) => {
|
||||
let requestData = res.data;
|
||||
Object.assign(requestData, res.data);
|
||||
if (requestData.value) {
|
||||
diyData.pageMode = requestData.mode;
|
||||
diyData.title = requestData.title;
|
||||
|
||||
let sources = JSON.parse(requestData.value);
|
||||
let sources = JSON.parse(requestData.value); // todo diy的结构应该后台处理好,前端就不需要再转换了
|
||||
|
||||
diyData.global = sources.global;
|
||||
diyData.value = sources.value;
|
||||
diyData.value.forEach((item: any, index) => {
|
||||
@ -149,7 +150,6 @@ export function useDiy(params: any = {}) {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@ -166,7 +166,7 @@ export function useDiy(params: any = {}) {
|
||||
if (url.length) {
|
||||
url = Array.from(new Set(url))
|
||||
url.forEach((item, index, arr) => {
|
||||
if (item == currRoute) {
|
||||
if (item == currRoute.value) {
|
||||
arr.splice(index, 1);
|
||||
}
|
||||
})
|
||||
@ -174,7 +174,7 @@ export function useDiy(params: any = {}) {
|
||||
|
||||
// 当diyStore.topFixedStatus == "diy"时,存储到diyPageBlank缓存中
|
||||
if (diyStore.topFixedStatus == "diy") {
|
||||
url.push(currRoute);
|
||||
url.push(currRoute.value);
|
||||
}
|
||||
uni.setStorageSync('diyPageBlank', url);
|
||||
/******** 解决跳转自定义页面空白问题-第一步 -end **********/
|
||||
@ -190,14 +190,6 @@ export function useDiy(params: any = {}) {
|
||||
})
|
||||
}
|
||||
|
||||
// 监听下拉刷新事件
|
||||
const onPullDownRefreshLifeCycle = () => {
|
||||
onPullDownRefresh(() => {
|
||||
pullDownRefreshCount.value++;
|
||||
uni.stopPullDownRefresh();
|
||||
})
|
||||
}
|
||||
|
||||
// 监听滚动事件
|
||||
const onPageScrollLifeCycle = () => {
|
||||
onPageScroll((e) => {
|
||||
@ -209,7 +201,6 @@ export function useDiy(params: any = {}) {
|
||||
|
||||
return {
|
||||
getLoading,
|
||||
pullDownRefreshCount,
|
||||
data: data.value,
|
||||
isShowTopTabbar,
|
||||
pageStyle,
|
||||
@ -217,7 +208,6 @@ export function useDiy(params: any = {}) {
|
||||
onShow: onShowLifeCycle,
|
||||
onHide: onHideLifeCycle,
|
||||
onUnload: onUnloadLifeCycle,
|
||||
onPullDownRefresh: onPullDownRefreshLifeCycle,
|
||||
onPageScroll: onPageScrollLifeCycle,
|
||||
}
|
||||
}
|
||||
|
||||
277
uni-app/src/hooks/useDiyForm.ts
Normal file
277
uni-app/src/hooks/useDiyForm.ts
Normal file
@ -0,0 +1,277 @@
|
||||
import { ref, reactive, computed } from 'vue';
|
||||
import { onLoad, onShow, onHide, onPageScroll, onUnload } from '@dcloudio/uni-app';
|
||||
import { img, handleOnloadParams, getToken, deepClone } from '@/utils/common';
|
||||
import { getDiyFormInfo } from '@/app/api/diy_form';
|
||||
import useDiyStore from '@/app/stores/diy';
|
||||
import { useLogin } from '@/hooks/useLogin';
|
||||
|
||||
export function useDiyForm(params: any = {}) {
|
||||
|
||||
const loading = ref(true);
|
||||
const diyStore = useDiyStore();
|
||||
|
||||
const form_id = ref(params.form_id || 0)
|
||||
const name = ref(params.name || '')
|
||||
const template = ref('')
|
||||
const currRoute = ref('') //当前路由
|
||||
const requestData: any = reactive({});
|
||||
const needLogin = ref(params.needLogin || false) // 是否检测登录
|
||||
|
||||
// 自定义页面 数据
|
||||
const diyData = reactive({
|
||||
pageMode: 'diy',
|
||||
title: '',
|
||||
global: {},
|
||||
value: [],
|
||||
status: 0
|
||||
})
|
||||
|
||||
const getLoading = () => {
|
||||
return loading.value;
|
||||
}
|
||||
|
||||
const data: any = 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 + ';';
|
||||
}
|
||||
if (data.value.global.bottomTabBarSwitch) {
|
||||
style += 'min-height:calc(100vh - 50px);';
|
||||
} else {
|
||||
style += 'min-height:calc(100vh);';
|
||||
}
|
||||
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;
|
||||
};
|
||||
|
||||
// 监听页面加载
|
||||
const onLoadLifeCycle = (callback: any = null) => {
|
||||
onLoad((option: any) => {
|
||||
// #ifdef MP-WEIXIN
|
||||
// 处理小程序场景值参数
|
||||
option = handleOnloadParams(option);
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
// 装修模式
|
||||
diyStore.mode = option.mode || '';
|
||||
if (diyStore.mode == 'decorate') {
|
||||
requestData.status = 1;
|
||||
requestData.error = [];
|
||||
loading.value = false;
|
||||
}
|
||||
// #endif
|
||||
|
||||
form_id.value = option.form_id || '';
|
||||
// if (name.value == '') name.value = option.name || '';
|
||||
// template.value = option.template || '';
|
||||
getData(callback)
|
||||
});
|
||||
}
|
||||
|
||||
// 监听页面显示
|
||||
const onShowLifeCycle = (callback: any = null) => {
|
||||
onShow(() => {
|
||||
if (callback) callback(requestData)
|
||||
})
|
||||
}
|
||||
|
||||
const getData = (callback: any = null) => {
|
||||
/******** 解决跳转自定义页面空白问题-第二步-start **********/
|
||||
let curPage: any = getCurrentPages();
|
||||
currRoute.value = curPage[curPage.length - 1] ? curPage[curPage.length - 1].route : ''; //获取当前页面的路由
|
||||
let urlArr = []
|
||||
if (uni.getStorageSync('diyPageBlank')) {
|
||||
urlArr = uni.getStorageSync('diyPageBlank');
|
||||
}
|
||||
if (!urlArr.length || urlArr.length && urlArr.indexOf(currRoute.value) == -1) {
|
||||
diyStore.topFixedStatus = 'home'
|
||||
} else if (urlArr.length && urlArr.indexOf(currRoute.value) != -1) {
|
||||
diyStore.topFixedStatus = 'diy'
|
||||
}
|
||||
/******** 解决跳转自定义页面空白问题-第二步-end **********/
|
||||
|
||||
// 装修模式
|
||||
if (diyStore.mode == 'decorate') {
|
||||
diyStore.init();
|
||||
} else {
|
||||
|
||||
if (!form_id.value) return; // 空值情况下不调用接口
|
||||
|
||||
// 填写万能表单需要检测登录
|
||||
if (needLogin.value && !getToken()) {
|
||||
useLogin().setLoginBack({
|
||||
url: '/app/pages/index/diy_form',
|
||||
param: {
|
||||
form_id: form_id.value
|
||||
}
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
getDiyFormInfo({
|
||||
form_id: form_id.value,
|
||||
// name: name.value, todo 暂时没用
|
||||
// template: template.value // todo 暂时没用
|
||||
}).then((res: any) => {
|
||||
Object.assign(requestData, res.data);
|
||||
diyData.status = res.data.status;
|
||||
if (requestData.value) {
|
||||
diyData.pageMode = requestData.mode;
|
||||
diyData.title = requestData.title;
|
||||
|
||||
diyStore.id = requestData.form_id;
|
||||
let sources = requestData.value;
|
||||
// 匹配缓存,赋值
|
||||
let diyFormStorage = uni.getStorageSync('diyFormStorage_' + diyStore.id)
|
||||
if (diyFormStorage) {
|
||||
var date = new Date();
|
||||
let currentTime: any = parseInt(date.getTime() / 1000); // 定位信息 5分钟内有效,过期后将重新获取定位信息
|
||||
if (diyFormStorage.validTime > currentTime) {
|
||||
if (diyFormStorage.components) {
|
||||
diyFormStorage.components.forEach((item: any) => {
|
||||
for (let i = 0; i < sources.value.length; i++) {
|
||||
if (sources.value[i].componentType == 'diy_form' && item.id == sources.value[i].id) {
|
||||
let comp = deepClone(item);
|
||||
let field = deepClone(comp.field);
|
||||
delete comp.field;
|
||||
// 移除不需要的数据
|
||||
delete field.required; // 是否必填
|
||||
delete field.unique; // 内容不可重复提交
|
||||
delete field.autofill; // 自动填充上次填写的内容
|
||||
delete field.privacyProtection; // 隐私保护
|
||||
Object.assign(sources.value[i], comp)
|
||||
Object.assign(sources.value[i].field, field)
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
uni.removeStorageSync('diyFormStorage_' + diyStore.id) // 清除过期的表单缓存数据
|
||||
}
|
||||
}
|
||||
diyStore.value = sources.value; // 用于 万能表单 收集数据,组件之间的数据通讯
|
||||
diyData.global = sources.global;
|
||||
diyData.value = sources.value;
|
||||
diyData.value.forEach((item: any, index) => {
|
||||
if (item.isHidden) {
|
||||
// 隐藏组件
|
||||
diyData.value.splice(index, 1)
|
||||
// 过滤表单-提交组件且按钮悬空的情况下不设置样式
|
||||
} else {
|
||||
item.pageStyle = '';
|
||||
if (item.componentName != 'FormSubmit' || item.componentName == 'FormSubmit' && item.btnPosition != 'hover_screen_bottom') {
|
||||
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: any) => {
|
||||
return item && item.position && item.position == 'top_fixed'
|
||||
});
|
||||
|
||||
uni.setNavigationBarTitle({
|
||||
title: diyData.title
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
loading.value = false;
|
||||
|
||||
if (callback) callback(requestData)
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 监听页面隐藏
|
||||
const onHideLifeCycle = (callback: any = null) => {
|
||||
onHide(() => {
|
||||
/******** 解决跳转自定义页面空白问题-第一步 -start **********/
|
||||
let url = [];
|
||||
if (uni.getStorageSync('diyPageBlank')) {
|
||||
url = uni.getStorageSync('diyPageBlank');
|
||||
}
|
||||
|
||||
// 清空重复、与当前页面路径一致的url
|
||||
if (url.length) {
|
||||
url = Array.from(new Set(url))
|
||||
url.forEach((item, index, arr) => {
|
||||
if (item == currRoute.value) {
|
||||
arr.splice(index, 1);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 当diyStore.topFixedStatus == "diy"时,存储到diyPageBlank缓存中
|
||||
if (diyStore.topFixedStatus == "diy") {
|
||||
url.push(currRoute.value);
|
||||
}
|
||||
uni.setStorageSync('diyPageBlank', url);
|
||||
/******** 解决跳转自定义页面空白问题-第一步 -end **********/
|
||||
|
||||
if (callback) callback()
|
||||
})
|
||||
}
|
||||
|
||||
// 监听页面卸载
|
||||
const onUnloadLifeCycle = () => {
|
||||
onUnload(() => {
|
||||
})
|
||||
}
|
||||
|
||||
// 监听滚动事件
|
||||
const onPageScrollLifeCycle = () => {
|
||||
onPageScroll((e) => {
|
||||
if (e.scrollTop > 0) {
|
||||
diyStore.scrollTop = e.scrollTop;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
getLoading,
|
||||
requestData,
|
||||
data: data.value,
|
||||
isShowTopTabbar,
|
||||
pageStyle,
|
||||
onLoad: onLoadLifeCycle,
|
||||
onShow: onShowLifeCycle,
|
||||
onHide: onHideLifeCycle,
|
||||
onUnload: onUnloadLifeCycle,
|
||||
onPageScroll: onPageScrollLifeCycle,
|
||||
getData
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
import { redirect, isWeixinBrowser, urlDeconstruction } from '@/utils/common'
|
||||
import { redirect, isWeixinBrowser, urlDeconstruction, currRoute } from '@/utils/common'
|
||||
import {
|
||||
weappLogin,
|
||||
updateWeappOpenid,
|
||||
@ -23,15 +23,13 @@ export function useLogin() {
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
if (!uni.getStorageSync('autoLoginLock') && uni.getStorageSync('openid') && config.login.is_bind_mobile) {
|
||||
uni.setStorageSync('isbindmobile', true)
|
||||
return
|
||||
uni.setStorageSync('isbindmobile', true) // 强制绑定手机号标识
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
if (!uni.getStorageSync('autoLoginLock') && isWeixinBrowser() && uni.getStorageSync('openid') && config.login.is_bind_mobile) {
|
||||
uni.setStorageSync('isbindmobile', true)
|
||||
return
|
||||
uni.setStorageSync('isbindmobile', true) // 强制绑定手机号标识
|
||||
}
|
||||
// #endif
|
||||
|
||||
@ -70,6 +68,7 @@ export function useLogin() {
|
||||
// #endif
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行登录后跳转
|
||||
*/
|
||||
@ -97,7 +96,11 @@ export function useLogin() {
|
||||
*/
|
||||
const authLogin = (params: any) => {
|
||||
let obj: any = {
|
||||
code: params.code
|
||||
code: params.code,
|
||||
nickname: params.nickname,
|
||||
headimg: params.headimg,
|
||||
mobile: params.mobile,
|
||||
mobile_code: params.mobile_code
|
||||
};
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
@ -126,7 +129,7 @@ export function useLogin() {
|
||||
if (params.backFlag) handleLoginBack() // 一键登录返回
|
||||
})
|
||||
} else {
|
||||
// 目前业务不会执行到这里
|
||||
// 强制获取昵称和头像,先存储起来
|
||||
uni.setStorageSync('openid', res.data.openid)
|
||||
uni.setStorageSync('unionid', res.data.unionid)
|
||||
}
|
||||
@ -153,11 +156,18 @@ export function useLogin() {
|
||||
if (config.login.is_bind_mobile && memberInfo && !memberInfo.mobile) {
|
||||
uni.setStorageSync('isbindmobile', true)
|
||||
}
|
||||
|
||||
let loginBack = uni.getStorageSync('loginBack');
|
||||
if (loginBack && loginBack.url && currRoute() == 'app/pages/auth/index') {
|
||||
handleLoginBack(); // 跳转到上一个页面
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// 目前业务不会执行到这里
|
||||
// 强制获取昵称和头像,先存储起来
|
||||
uni.setStorageSync('openid', res.data.openid)
|
||||
uni.setStorageSync('unionid', res.data.unionid)
|
||||
if(res.data.nickname) uni.setStorageSync('nickname', res.data.nickname)
|
||||
if(res.data.avatar) uni.setStorageSync('avatar', res.data.avatar)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -210,6 +220,10 @@ export function useLogin() {
|
||||
params.updateFlag = params.updateFlag || false; // updateFlag:更新oppenid
|
||||
params.backFlag = params.backFlag || false; // backFlag 控制一键登录返回
|
||||
params.successCallback = params.successCallback || null;
|
||||
params.nickname = params.nickname || '';
|
||||
params.headimg = params.headimg || '';
|
||||
params.mobile = params.mobile || '';
|
||||
params.mobile_code = params.mobile_code || '';
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
wx.login({
|
||||
@ -217,6 +231,10 @@ export function useLogin() {
|
||||
if (res.code) {
|
||||
params.updateFlag ? updateOpenid(res.code) : authLogin({
|
||||
code: res.code,
|
||||
nickname: params.nickname,
|
||||
headimg: params.headimg,
|
||||
mobile: params.mobile,
|
||||
mobile_code: params.mobile_code,
|
||||
backFlag: params.backFlag,
|
||||
successCallback: params.successCallback
|
||||
})
|
||||
|
||||
@ -4,6 +4,9 @@
|
||||
"pages.index.nosite": "站点不存在",
|
||||
"pages.index.develop": "开发环境配置",
|
||||
"pages.index.diy": "",
|
||||
"pages.index.diy_form": "",
|
||||
"pages.index.diy_form_result": "",
|
||||
"pages.index.diy_form_detail": "表单详情",
|
||||
"pages.article.list": "资讯中心",
|
||||
"pages.article.detail": "文章详情",
|
||||
"pages.auth.index": "登录",
|
||||
@ -32,12 +35,12 @@
|
||||
"pages.pay.browser": "支付",
|
||||
"pages.pay.result": "",
|
||||
"pages.setting.index": "设置",
|
||||
"pages.verify.index": "核销台",
|
||||
"pages.verify.verify": "核销",
|
||||
"pages.verify.detail": "核销详情",
|
||||
"pages.verify.record": "核销记录",
|
||||
"pages.verify.index": "核销台",
|
||||
"pages.verify.verify": "核销",
|
||||
"pages.verify.detail": "核销详情",
|
||||
"pages.verify.record": "核销记录",
|
||||
"pages.friendspay.share": "找朋友帮忙付",
|
||||
"pages.friendspay.money":"",
|
||||
"pages.friendspay.money": "",
|
||||
"pages.webview.index": "",
|
||||
"tourism.pages.way.list": "线路列表",
|
||||
"tourism.pages.way.detail": "线路详情",
|
||||
@ -75,7 +78,7 @@
|
||||
"shop.pages.goods.category": "商品分类",
|
||||
"shop.pages.goods.detail": "商品详情",
|
||||
"shop.pages.goods.list": "商品列表",
|
||||
"shop.pages.goods.rank": "排行榜",
|
||||
"shop.pages.goods.rank": "排行榜",
|
||||
"shop.pages.member.index": "个人中心",
|
||||
"shop.pages.member.my_coupon": "我的优惠券",
|
||||
"shop.pages.order.list": "订单列表",
|
||||
@ -92,12 +95,12 @@
|
||||
"shop.pages.refund.apply": "申请退款",
|
||||
"shop.pages.refund.edit_apply": "编辑退款信息",
|
||||
"shop.pages.refund.log": "协商记录",
|
||||
"shop.pages.point.index":"积分商城",
|
||||
"shop.pages.point.list":"积分商品列表",
|
||||
"shop.pages.point.detail":"积分商品详情",
|
||||
"shop.pages.point.payment":"待付款订单",
|
||||
"shop.pages.point.order_list":"积分兑换记录",
|
||||
"shop.pages.newcomer.list":"新人专享列表",
|
||||
"shop.pages.point.index": "积分商城",
|
||||
"shop.pages.point.list": "积分商品列表",
|
||||
"shop.pages.point.detail": "积分商品详情",
|
||||
"shop.pages.point.payment": "待付款订单",
|
||||
"shop.pages.point.order_list": "积分兑换记录",
|
||||
"shop.pages.newcomer.list": "新人专享",
|
||||
"cms.pages.list": "资讯中心",
|
||||
"cms.pages.detail": "文章详情",
|
||||
"shop_fenxiao.pages.index": "分销中心",
|
||||
@ -105,7 +108,7 @@
|
||||
"shop_fenxiao.pages.level": "分销商等级",
|
||||
"shop_fenxiao.pages.child_fenxiao": "分销商",
|
||||
"shop_fenxiao.pages.goods": "分销商品",
|
||||
"shop_fenxiao.pages.team": "团队",
|
||||
"shop_fenxiao.pages.team": "我的团队",
|
||||
"shop_fenxiao.pages.ranking_list": "排行榜",
|
||||
"shop_fenxiao.pages.agent_list": "渠道代理",
|
||||
"shop_fenxiao.pages.bill": "账单",
|
||||
@ -117,23 +120,60 @@
|
||||
"shop_fenxiao.pages.task_rewards_detail": "任务奖励明细",
|
||||
"shop_fenxiao.pages.sale": "销售奖励",
|
||||
"shop_fenxiao.pages.sale_detail": "销售奖励详情",
|
||||
"shop_fenxiao.pages.sale_ranking": "销售排行榜",
|
||||
"shop_fenxiao.pages.promote_code": "分销推广",
|
||||
"shop_giftcard.pages.index": "礼品卡首页",
|
||||
"shop_giftcard.pages.list": "礼品卡列表",
|
||||
"shop_giftcard.pages.detail": "加载中",
|
||||
"shop_giftcard.pages.order_list": "礼品卡订单列表",
|
||||
"shop_giftcard.pages.order_detail": "礼品卡订单详情",
|
||||
"shop_giftcard.pages.member": "我的",
|
||||
"shop_giftcard.pages.my_card_list": "我的卡包",
|
||||
"shop_giftcard.pages.card_bag": "我的卡包",
|
||||
"shop_giftcard.pages.activate": "卡密激活",
|
||||
"shop_giftcard.pages.receive_list": "收到的礼品卡",
|
||||
"shop_giftcard.pages.give_list": "送出的礼品卡",
|
||||
"shop_giftcard.pages.give_detail": "送出礼品卡详情",
|
||||
"shop_giftcard.pages.give": "礼品卡赠送",
|
||||
"shop_giftcard.pages.receive_info": "领取礼品卡",
|
||||
"shop_fenxiao.pages.sale_ranking": "销售奖励排行榜",
|
||||
"shop_fenxiao.pages.promote_code": "分享海报",
|
||||
"shop_giftcard.pages.index": "礼品卡首页",
|
||||
"shop_giftcard.pages.list": "礼品卡列表",
|
||||
"shop_giftcard.pages.detail": "加载中",
|
||||
"shop_giftcard.pages.order_list": "礼品卡订单列表",
|
||||
"shop_giftcard.pages.order_detail": "礼品卡订单详情",
|
||||
"shop_giftcard.pages.member": "我的",
|
||||
"shop_giftcard.pages.my_card_list": "我的卡包",
|
||||
"shop_giftcard.pages.card_bag": "我的卡包",
|
||||
"shop_giftcard.pages.activate": "卡密激活",
|
||||
"shop_giftcard.pages.receive_list": "收到的礼品卡",
|
||||
"shop_giftcard.pages.give_list": "送出的礼品卡",
|
||||
"shop_giftcard.pages.give_detail": "送出礼品卡详情",
|
||||
"shop_giftcard.pages.give": "礼品卡赠送",
|
||||
"shop_giftcard.pages.receive_info": "领取礼品卡",
|
||||
"shop_giftcard.pages.use_card": "礼品卡使用",
|
||||
"shop_giftcard.pages.use_goods_select": "选择兑换商品",
|
||||
"shop_giftcard.pages.payment": "待付款订单"
|
||||
"shop_giftcard.pages.use_goods_select": "选择兑换商品",
|
||||
"shop_giftcard.pages.payment": "待付款订单",
|
||||
"shop.pages.pay.index": "待支付",
|
||||
"shop.pages.pay.result": "",
|
||||
"shop_fenxiao.pages.promote": "邀请好友",
|
||||
"shop_fenxiao.pages.team_dividend": "团队分红",
|
||||
"o2o.pages.address.edit": "编辑地址",
|
||||
"o2o.pages.address.index": "地址",
|
||||
"o2o.pages.goods.category": "项目分类",
|
||||
"o2o.pages.goods.detail": "项目详情",
|
||||
"o2o.pages.goods.list": "项目列表",
|
||||
"o2o.pages.index": "首页",
|
||||
"o2o.pages.master.statistics.index": "技师中心",
|
||||
"o2o.pages.master.task.add": "师傅报单",
|
||||
"o2o.pages.master.task.detail": "任务详情",
|
||||
"o2o.pages.master.task.list": "任务列表",
|
||||
"o2o.pages.master.task.refund": "查看退款",
|
||||
"o2o.pages.master.task.show": "报单详情",
|
||||
"o2o.pages.member.index": "个人中心",
|
||||
"o2o.pages.order.detail": "订单详情",
|
||||
"o2o.pages.order.list": "订单列表",
|
||||
"o2o.pages.order.payment": "订单结算",
|
||||
"o2o.pages.refund.apply": "申请退款",
|
||||
"o2o.pages.refund.detail": "退款详情",
|
||||
"o2o.pages.refund.list": "退款列表",
|
||||
"o2o.pages.refund.log": "协商记录",
|
||||
"o2o.pages.technician.detail": "技师详情",
|
||||
"o2o.pages.technician.list": "技师列表",
|
||||
"shop_giftcard.pages.member_give_info": "送出礼品卡详情",
|
||||
"shop_giftcard.pages.give_info": "领取礼品卡",
|
||||
"sow_community.pages.index":"种草社区",
|
||||
"sow_community.pages.search":"搜索结果",
|
||||
"sow_community.pages.image.detail":"内容详情",
|
||||
"sow_community.pages.video.detail":"内容详情",
|
||||
"sow_community.pages.member":"个人主页",
|
||||
"sow_community.pages.create":"发布内容",
|
||||
"sow_community.pages.follow":"关注列表",
|
||||
"sow_community.pages.sow_show":"种草秀",
|
||||
"sow_community.pages.topic_list":"话题列表"
|
||||
}
|
||||
|
||||
@ -1,103 +1,144 @@
|
||||
{
|
||||
"requestFail": "请求失败",
|
||||
"notInDomainList": "不在request 合法域名列表中",
|
||||
"baseUrlError": " 接口请求错误,请检查VITE_APP_BASE_URL参数配置或者伪静态配置",
|
||||
"currency": "¥",
|
||||
"getSmsCode": "获取验证码",
|
||||
"smsCodeChangeText": "秒后重新获取",
|
||||
"captchaTitle": "请完成验证",
|
||||
"confirm": "确认",
|
||||
"cancel": "取消",
|
||||
"save": "保存",
|
||||
"delete": "删除",
|
||||
"captchaPlaceholder": "请输入验证码",
|
||||
"mobilePlaceholder": "请输入手机号码",
|
||||
"mobileError": "请输入正确的手机号",
|
||||
"codePlaceholder": "请输入手机验证码",
|
||||
"memberCenter": "个人中心",
|
||||
"userAgreement": "用户协议",
|
||||
"and": "和",
|
||||
"privacyAgreement": "隐私协议",
|
||||
"isAgreeTips": "请先阅读并同意协议",
|
||||
"nickname": "昵称",
|
||||
"nicknamePlaceholder": "请输入昵称",
|
||||
"headimg": "头像",
|
||||
"headimgPlaceholder": "请设置头像",
|
||||
"getAvatarNickname": "获取您的昵称头像",
|
||||
"getAvatarNicknameTips": "获取用户头像、昵称完善个人资料,主要用于向用户提供具有辨识度的用户中心界面",
|
||||
"mobile": "手机号",
|
||||
"getMobile": "获取手机号",
|
||||
"mobileTips": "请获取手机号",
|
||||
"point": "积分",
|
||||
"balance": "余额",
|
||||
"login": "登录",
|
||||
"bind": "绑定",
|
||||
"binding": "绑定中",
|
||||
"bindMobile": "绑定手机号",
|
||||
"agreeTips": "我已阅读并同意",
|
||||
"pleaseAgree": "请勾选已阅读并同意",
|
||||
"weixinUserAuth": "一键绑定",
|
||||
"mobileQuickLogin": "手机号快捷登录",
|
||||
"register": "注册",
|
||||
"complete": "完成",
|
||||
"close": "关闭",
|
||||
"pay": {
|
||||
"orderInfo": "订单信息",
|
||||
"confirmPay": "确认支付",
|
||||
"payTitle": "确认付款",
|
||||
"notHavePayType": "没有可用的支付方式",
|
||||
"notObtainedInfo": "未获取到支付信息",
|
||||
"paymentDocuments": "该支付单据",
|
||||
"paySuccess": "支付成功",
|
||||
"payFail": "支付失败",
|
||||
"completePay": "已完成支付",
|
||||
"incompletePay": "未完成支付",
|
||||
"getting": "获取支付结果中"
|
||||
},
|
||||
"myBalance": "我的余额",
|
||||
"myPoint": "我的积分",
|
||||
"customerService": "联系客服",
|
||||
"siteClose": "站点已关闭",
|
||||
"noSite": "站点不存在",
|
||||
"scenic": "景点",
|
||||
"seeMore": "查看更多",
|
||||
"way": "线路",
|
||||
"hotel": "酒店",
|
||||
"rise": "起",
|
||||
"cardReserve": "项目预约",
|
||||
"card": "办理次卡",
|
||||
"memberName": "会员名称",
|
||||
"memberCode": "会员码",
|
||||
"reserve": "预约",
|
||||
"reserveSuccess": "预约成功",
|
||||
"cardLink": "次卡",
|
||||
"myLink": "我的",
|
||||
"reserveBtn": "去抢购",
|
||||
"cardBtn": "办理",
|
||||
"soldOut": "已售",
|
||||
"unpaidOrder": "待支付",
|
||||
"waitingOrder": "待使用",
|
||||
"remainOrder": "已完成",
|
||||
"allOrder": "全部订单",
|
||||
"myOrder": "我的订单",
|
||||
"orderNo": "订单号",
|
||||
"actualPayment": "实付款",
|
||||
"orderClose": "关闭订单",
|
||||
"orderFinish": "确认收货",
|
||||
"orderDetail": "详情",
|
||||
"wxPrivacyPopup": {
|
||||
"title": "用户隐私保护提示",
|
||||
"descBefore": "感谢您使用本小程序,在使用前您应当阅读并同意",
|
||||
"descAfter": "当点击同意并继续时,即表示您已理解并同意该条款内容,该条款将对您产生法律约束力;如您不同意,将无法继续使用小程序相关功能。",
|
||||
"disagree": "不同意",
|
||||
"agree": "同意并继续",
|
||||
"contractName": "用户隐私保护指引",
|
||||
"disagreeDesc": "未同意隐私协议,无法使用相关功能"
|
||||
},
|
||||
"starLevel": "星级",
|
||||
"star": "星",
|
||||
"emptyAddress": "暂无收货地址,请先创建地址",
|
||||
"addAddress": "新增收货地址",
|
||||
"selectAddress": "选择地址",
|
||||
"coupon": "优惠劵"
|
||||
"requestFail": "请求失败",
|
||||
"notInDomainList": "不在request 合法域名列表中",
|
||||
"baseUrlError": " 接口请求错误,请检查VITE_APP_BASE_URL参数配置或者伪静态配置",
|
||||
"currency": "¥",
|
||||
"getSmsCode": "获取验证码",
|
||||
"smsCodeChangeText": "秒后重新获取",
|
||||
"captchaTitle": "请完成验证",
|
||||
"confirm": "确认",
|
||||
"cancel": "取消",
|
||||
"save": "保存",
|
||||
"delete": "删除",
|
||||
"captchaPlaceholder": "请输入验证码",
|
||||
"mobilePlaceholder": "请输入手机号码",
|
||||
"mobileError": "请输入正确的手机号",
|
||||
"codePlaceholder": "请输入手机验证码",
|
||||
"memberCenter": "个人中心",
|
||||
"userAgreement": "用户协议",
|
||||
"and": "和",
|
||||
"privacyAgreement": "隐私协议",
|
||||
"isAgreeTips": "请先阅读并同意协议",
|
||||
"nickname": "昵称",
|
||||
"nicknamePlaceholder": "请输入昵称",
|
||||
"headimg": "头像",
|
||||
"headimgPlaceholder": "请设置头像",
|
||||
"getAvatarNickname": "获取您的昵称头像",
|
||||
"getAvatarNicknameTips": "获取用户头像、昵称完善个人资料,主要用于向用户提供具有辨识度的用户中心界面",
|
||||
"mobile": "手机号",
|
||||
"getMobile": "获取手机号",
|
||||
"mobileTips": "请获取手机号",
|
||||
"point": "积分",
|
||||
"balance": "余额",
|
||||
"login": "登录",
|
||||
"bind": "绑定",
|
||||
"binding": "绑定中",
|
||||
"bindMobile": "绑定手机号",
|
||||
"agreeTips": "我已阅读并同意",
|
||||
"pleaseAgree": "请勾选已阅读并同意",
|
||||
"weixinUserAuth": "一键绑定",
|
||||
"mobileQuickLogin": "手机号快捷登录",
|
||||
"register": "注册",
|
||||
"complete": "完成",
|
||||
"close": "关闭",
|
||||
"back":"返回",
|
||||
"hidden":"已隐藏",
|
||||
"view":"查看",
|
||||
"know":"我知道了",
|
||||
"prompt":"提示",
|
||||
"call":"拨打",
|
||||
"copy":"复制号码",
|
||||
"uploadTips":"请上传图片",
|
||||
"tips":"仅限本人和管理员能查看完整号码:",
|
||||
"viewFillingDetails":"查看填写详情",
|
||||
"detailInformation":"详细信息",
|
||||
"pay": {
|
||||
"orderInfo": "订单信息",
|
||||
"confirmPay": "确认支付",
|
||||
"payTitle": "确认付款",
|
||||
"notHavePayType": "没有可用的支付方式",
|
||||
"notObtainedInfo": "未获取到支付信息",
|
||||
"paymentDocuments": "该支付单据",
|
||||
"paySuccess": "支付成功",
|
||||
"payFail": "支付失败",
|
||||
"completePay": "已完成支付",
|
||||
"incompletePay": "未完成支付",
|
||||
"getting": "获取支付结果中"
|
||||
},
|
||||
"myBalance": "我的余额",
|
||||
"myPoint": "我的积分",
|
||||
"customerService": "联系客服",
|
||||
"siteClose": "站点已关闭",
|
||||
"noSite": "站点不存在",
|
||||
"scenic": "景点",
|
||||
"seeMore": "查看更多",
|
||||
"way": "线路",
|
||||
"hotel": "酒店",
|
||||
"rise": "起",
|
||||
"cardReserve": "项目预约",
|
||||
"card": "办理次卡",
|
||||
"memberName": "会员名称",
|
||||
"memberCode": "会员码",
|
||||
"reserve": "预约",
|
||||
"reserveSuccess": "预约成功",
|
||||
"cardLink": "次卡",
|
||||
"myLink": "我的",
|
||||
"reserveBtn": "去抢购",
|
||||
"cardBtn": "办理",
|
||||
"soldOut": "已售",
|
||||
"unpaidOrder": "待支付",
|
||||
"waitingOrder": "待使用",
|
||||
"remainOrder": "已完成",
|
||||
"allOrder": "全部订单",
|
||||
"myOrder": "我的订单",
|
||||
"orderNo": "订单号",
|
||||
"actualPayment": "实付款",
|
||||
"orderClose": "关闭订单",
|
||||
"orderFinish": "确认收货",
|
||||
"orderDetail": "详情",
|
||||
"wxPrivacyPopup": {
|
||||
"title": "用户隐私保护提示",
|
||||
"descBefore": "感谢您使用本小程序,在使用前您应当阅读并同意",
|
||||
"descAfter": "当点击同意并继续时,即表示您已理解并同意该条款内容,该条款将对您产生法律约束力;如您不同意,将无法继续使用小程序相关功能。",
|
||||
"disagree": "不同意",
|
||||
"agree": "同意并继续",
|
||||
"contractName": "用户隐私保护指引",
|
||||
"disagreeDesc": "未同意隐私协议,无法使用相关功能"
|
||||
},
|
||||
"starLevel": "星级",
|
||||
"star": "星",
|
||||
"emptyAddress": "暂无收货地址,请先创建地址",
|
||||
"addAddress": "新增收货地址",
|
||||
"selectAddress": "选择地址",
|
||||
"coupon": "优惠劵",
|
||||
"tourism.orderNo": "订单号",
|
||||
"tourism.rise": "起",
|
||||
"tourism.starLevel": "星级",
|
||||
"tourism.star": "星",
|
||||
"vipcard.cardReserve": "项目预约",
|
||||
"vipcard.card": "办理次卡",
|
||||
"vipcard.reserveSuccess": "预约成功",
|
||||
"vipcard.reserve": "预约",
|
||||
"vipcard.cardLink": "次卡",
|
||||
"vipcard.reserveBtn": "去抢购",
|
||||
"vipcard.cardBtn": "办理",
|
||||
"vipcard.soldOut": "已售",
|
||||
"vipcard.orderNo": "订单号",
|
||||
"vipcard.myLink": "我的",
|
||||
"vipcard.memberCode": "会员码",
|
||||
"recharge.orderNo": "订单号",
|
||||
"shop.orderNo": "订单号",
|
||||
"shop.actualPayment": "实付款",
|
||||
"shop.orderClose": "关闭订单",
|
||||
"shop.orderFinish": "确认收货",
|
||||
"shop.coupon": "优惠劵",
|
||||
"o2o.way": "线路",
|
||||
"o2o.hotel": "酒店",
|
||||
"o2o.scenic": "景点",
|
||||
"o2o.reserveBtn": "去抢购",
|
||||
"o2o.noHomeAddress": "没有更多内容啦~",
|
||||
"o2o.soldOut": "已售",
|
||||
"o2o.orderNo": "订单号",
|
||||
"o2o.actualPayment": "实付款",
|
||||
"o2o.orderDetail": "详情"
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user