up uniapp

This commit is contained in:
全栈小学生 2025-05-23 14:59:15 +08:00
parent 4a6197b4fe
commit 7ce04c3f16
37 changed files with 1268 additions and 543 deletions

View File

@ -29,7 +29,9 @@
<view v-if="diyComponent.search.style == 'style-2'" class="diy-search-wrap style-2 relative z-10" @click="diyStore.toRedirect(diyComponent.search.link)">
<view class="flex items-center" :style="navbarInnerStyle">
<view class="img-wrap" v-if="diyComponent.search.logo"><image :src="img(diyComponent.search.logo)" mode="aspectFit" /></view>
<view :style="searchSubTitleCss" class="text-[24rpx] h-[38rpx] flex items-center px-[12rpx] rounded-r-[20rpx] rounded-t-[20rpx] rounded-bl-[2rpx]" v-if="diyComponent.search.subTitle.text">{{ diyComponent.search.subTitle.text }}</view>
<view :style="searchSubTitleCss" class="max-w-[360rpx] text-[24rpx] h-[38rpx] rounded-r-[20rpx] rounded-t-[20rpx] rounded-bl-[2rpx]" v-if="diyComponent.search.subTitle.text">
<view class="truncate leading-[38rpx] h-[38rpx] px-[12rpx]">{{ diyComponent.search.subTitle.text }}</view>
</view>
</view>
<view class="flex items-center w-full mt-[16rpx]">
<view @click.stop="locationVal.reposition()" v-if="systemStore.diyAddressInfo" :style="{color: diyComponent.search.positionColor}" class="mr-[30rpx]">

View File

@ -1,15 +1,66 @@
<template>
<view :style="warpCss">
表单 地址组件
<view class="relative">
<view class="p-[10rpx] flex items-center ">
<view class="w-[27%] mr-[10rpx] flex items-center">
<text class="text-overflow-ellipsis" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx' ,'font-weight': diyComponent.fontWeight}">{{ diyComponent.field.name }}</text>
<text class="text-[#ec0003]">{{ diyComponent.field.required ? '*' : '' }}</text>
</view>
</view>
</view>
<view v-if="diyComponent.viewFormDetail" class="form-item-frame">
<view class="base-layout-one" v-if="diyGlobal.completeLayout == 'style-1'">
<view class="detail-one-content">
<text class="detail-one-content-label">{{ diyComponent.field.name }}</text>
<text class="detail-one-content-value">{{ diyComponent.field.value }}</text>
</view>
</view>
<view class="base-layout-two" v-if="diyGlobal.completeLayout == 'style-2'">
<view class="detail-two-content">
<view>{{ diyComponent.field.name }}</view>
<view class="detail-two-content-value w-[80%]">{{ diyComponent.field.value }}</view>
</view>
</view>
</view>
<view v-else :style="warpCss" class="form-item-frame">
<view class="base-layout-one" v-if="diyGlobal.completeLayout == 'style-1'">
<view class="layout-one-label">
<text class="text-overflow-ellipsis" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx' ,'font-weight': diyComponent.fontWeight}">{{ diyComponent.field.name }}</text>
<text class="required">{{ diyComponent.field.required ? '*' : '' }}</text>
<text v-if="diyStore.mode == 'decorate' && diyComponent.isHidden" class="is-hidden">{{ t('diyForm.hidden') }}</text>
</view>
<view v-if="diyComponent.field.remark.text" class="layout-one-remark" :style="{ color: diyComponent.field.remark.color, fontSize: (diyComponent.field.remark.fontSize * 2 ) + 'rpx' }">{{ diyComponent.field.remark.text }}</view>
<view class="layout-one-error-message" v-if="errorInfo && !errorInfo.code">{{ errorInfo.message }}</view>
<view class="flex layout-one-content justify-between items-center">
<input type="text" class="flex-1" :placeholder="inputPlaceholder"
placeholderClass="layout-one-input-placeholder"
:placeholder-style="{'font-size': (diyComponent.fontSize * 2) + 'rpx' }"
:style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}"
v-model="diyComponent.field.value" :disabled="isDisabled" @click="selectArea" />
<view class="text-[var(--primary-color)]" v-if="diyComponent.field.value" @click="reset">
清除
</view>
</view>
<textarea v-if="diyComponent.addressFormat=='province/city/district/address'" type="textarea" class="layout-one-content mt-2 w-full" placeholderClass="layout-one-input-placeholder" :placeholder-style="{'font-size': (diyComponent.fontSize * 2) + 'rpx' }" placeholder="详细地址(如小区门牌号)" :disabled="isDisabled"></textarea>
<view class="layout-one-attribute-wrap" v-if="inputAttribute().length">
<view v-for="(item,index) in inputAttribute()" :key="index" @click="eventFn(item.type)" class="layout-one-attribute-item">{{ item.title }}</view>
</view>
</view>
<view class="base-layout-two" v-if="diyGlobal.completeLayout == 'style-2'">
<text v-if="diyStore.mode == 'decorate' && diyComponent.isHidden" class="layout-two-is-hidden">{{ t('diyForm.hidden') }}</text>
<view class="layout-two-wrap" :class="{'no-border': !diyGlobal.borderControl}">
<view class="layout-two-label" :class="{'justify-start': diyGlobal.completeAlign == 'left', 'justify-end': diyGlobal.completeAlign == 'right'}">
<text class="required" v-if="diyComponent.field.required">{{ diyComponent.field.required ? '*' : '' }}</text>
<text class="name" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx' ,'font-weight': diyComponent.fontWeight}">{{ diyComponent.field.name }}</text>
</view>
<input type="text" class="layout-two-content no-flex" :placeholder="inputPlaceholder"
placeholderClass="layout-two-input-placeholder" @click="selectArea"
:placeholder-style="{'font-size': (diyComponent.fontSize * 2) + 'rpx'}"
:style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}"
v-model="diyComponent.field.value" :disabled="isDisabled" />
</view>
<textarea v-if="diyComponent.addressFormat=='province/city/district/address'" type="textarea" class="layout-one-content p-2 mt-2 w-full" placeholderClass="layout-one-input-placeholder" :placeholder-style="{'font-size': (diyComponent.fontSize * 2) + 'rpx' }" placeholder="详细地址(如小区门牌号)" :disabled="isDisabled"></textarea>
<view class="layout-two-error-message" v-if="errorInfo && !errorInfo.code">{{ errorInfo.message }}</view>
<view v-if="diyComponent.field.remark.text" class="layout-two-remark" :style="{ color: diyComponent.field.remark.color, fontSize: (diyComponent.field.remark.fontSize * 2 ) + 'rpx' }">{{ diyComponent.field.remark.text }}</view>
<view class="layout-two-attribute-wrap" v-if="inputAttribute().length">
<view v-for="(item,index) in inputAttribute()" :key="index" @click="eventFn(item.type)" class="layout-two-attribute-item">{{ item.title }}</view>
</view>
</view>
<view v-if="diyStore.mode == 'decorate'" class="form-item-mask"></view>
</view>
<area-select ref="areaRef" @complete="areaSelectComplete" :area-id="formData.district_id" />
</template>
<script setup lang="ts">
@ -17,10 +68,12 @@
import { ref, computed, watch,onMounted } from 'vue';
import { img } from '@/utils/common';
import useDiyStore from '@/app/stores/diy';
import { t } from '@/locale'
const props = defineProps(['component', 'index','global']);
const diyStore = useDiyStore();
const areaRef = ref()
const errorInfo: any = ref(null);
const isSelectAddress = ref(false)
const diyComponent = computed(() => {
if (diyStore.mode == 'decorate') {
return diyStore.value[props.index];
@ -28,6 +81,39 @@
return props.component;
}
})
const diyGlobal = computed(() => {
return props.global;
})
const formData: any = ref({
id: 0,
name: '',
mobile: '',
province_id: 0,
city_id: 0,
district_id: 0,
lat: '',
lng: '',
address: '',
address_name: '',
full_address: '',
is_default: 0,
area: ''
})
const inputPlaceholder = computed(() => {
let str = '请选择';
if(diyComponent.value.addressFormat=="province/city/district/address"){
str += '省/市/区/街道'
}else if(diyComponent.value.addressFormat=="province/city/district/street"){
str += '省/市/区/街道(镇)'
}else if(diyComponent.value.addressFormat=="province/city/district"){
str += '省/市/区(县)'
}else if(diyComponent.value.addressFormat=="province/city"){
str += '省/市'
}else{
str += '省份'
}
return str;
})
const warpCss = computed(() => {
var style = '';
@ -48,7 +134,18 @@
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
return style;
})
const areaSelectComplete = (event: any) => {
if (isSelectAddress.value && (formData.value.province_id == event.province.id || formData.value.city_id != event.city.id || formData.value.district_id != event.district.id)) {
formData.value.lat = '';
formData.value.lng = '';
}
formData.value.province_id = event.province.id || 0
formData.value.city_id = event.city.id || 0
formData.value.district_id = event.district.id || 0
formData.value.area = `${ event.province.name || '' }${ event.city.name || '' }${ event.district.name || '' }`
diyComponent.value.field.value = formData.value.area
isSelectAddress.value = false;
}
onMounted(() => {
refresh();
//
@ -67,18 +164,57 @@
const refresh = ()=> {
}
const selectArea = () => {
isSelectAddress.value = true
areaRef.value.open()
}
// input
const inputAttribute = () => {
let arr = [];
if (diyComponent.value.autofill) {
let obj = {
title: '已自动填充'
};
arr.push(obj);
}
if (diyComponent.value.field.privacyProtection) {
let obj = {
title: '已开启隐私保护',
type: 'privacy'
};
arr.push(obj);
}
arr.forEach((item, index, arr) => {
if (index != (arr.length - 1)) {
let obj = {
title: '|'
};
arr.push(obj);
}
})
return arr;
}
//
const verify = () => {
const res = { code: true, message: '' }
// todo diyComponent.value.field.value
return res;
const res = { code: true, message: '' }
if (diyComponent.value.field.required && diyComponent.value.field.value == '' && diyStore.mode != 'decorate') {
res.code = false
res.message ='111';
}
errorInfo.value = res;
return res;
}
//
const reset = () => {
// todo diyComponent.value.field.value = '';
diyComponent.value.field.value = '';
}
const isDisabled = computed(() => {
return diyStore.mode == 'decorate';
});
defineExpose({
verify,

View File

@ -1,13 +1,39 @@
<template>
<view :style="warpCss">
<view class="relative">
<view class="p-[10rpx] flex items-center ">
<view class="w-[27%] mr-[10rpx] flex items-center">
<text class="text-overflow-ellipsis" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx' ,'font-weight': diyComponent.fontWeight}">{{ diyComponent.field.name }}</text>
<text class="text-[#ec0003]">{{ diyComponent.field.required ? '*' : '' }}</text>
</view>
<view :style="warpCss" class="form-item-frame">
<view class="base-layout-one" v-if="diyGlobal.completeLayout == 'style-1'">
<view class="layout-one-label">
<text class="text-overflow-ellipsis" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx' ,'font-weight': diyComponent.fontWeight}">{{ diyComponent.field.name }}</text>
<text class="required">{{ diyComponent.field.required ? '*' : '' }}</text>
<text v-if="diyStore.mode == 'decorate' && diyComponent.isHidden" class="is-hidden">{{ t('diyForm.hidden') }}</text>
</view>
<view v-if="diyComponent.field.remark.text" class="layout-one-remark" :style="{ color: diyComponent.field.remark.color, fontSize: (diyComponent.field.remark.fontSize * 2 ) + 'rpx' }">{{ diyComponent.field.remark.text }}</view>
<view class="layout-one-error-message" v-if="errorInfo && !errorInfo.code">{{ errorInfo.message }}</view>
<view class="flex flex-wrap">
<view class="relative w-[180rpx] !h-[180rpx] mr-[16rpx] mb-[16rpx] layout-one-content" v-for="(item,index) in diyComponent.field.value" :key="index">
<image class="w-[100%] h-[100%]" :src="img(item)" mode="aspectFill" />
<view class="absolute top-0 right-[0] bg-[#373737] flex justify-end h-[28rpx] w-[28rpx] rounded-bl-[40rpx]" @click="deleteImage(index)">
<text class="nc-iconfont nc-icon-guanbiV6xx !text-[20rpx] mt-[2rpx] mr-[2rpx] text-[#fff]"></text>
</view>
</view>
<view class="flex items-center flex-1">
<view class="layout-one-content !p-[0] flex-1 !items-stretch !h-[100rpx]">
<view class="flex items-center h-[100%] w-[100%] pl-[30rpx] box-border" @click="selectWeChatFile">
<text class="nc-iconfont nc-icon-weixinV6mm"></text>
<text class="text-[28rpx] ml-[10rpx]">选择微信聊天文件</text>
</view>
</view>
<view class="layout-one-content !p-[0] ml-[20rpx] !items-stretch flex-1 !h-[100rpx]">
<u-upload accept="file " @afterRead="afterRead" multiple :maxCount="9">
<view class="flex items-center h-[100%] w-[100%] pl-[30rpx] box-border">
<text class="nc-iconfont nc-icon-tupiandaohangpc"></text>
<text class="text-[28rpx] ml-[10rpx]">选择本地文件</text>
</view>
</u-upload>
</view>
</view>
</view>
</view>
<view v-if="diyStore.mode == 'decorate'" class="form-item-mask"></view>
</view>
</template>
@ -16,11 +42,11 @@
import { ref, computed, watch,onMounted } from 'vue';
import { img } from '@/utils/common';
import useDiyStore from '@/app/stores/diy';
import { t } from '@/locale'
import { uploadImage } from '@/app/api/system'
const errorInfo: any = ref(null);
const props = defineProps(['component', 'index','global']);
const diyStore = useDiyStore();
const selectValue = ref([])
const diyComponent = computed(() => {
if (diyStore.mode == 'decorate') {
@ -29,6 +55,11 @@
return props.component;
}
})
const diyGlobal = computed(() => {
return props.global;
})
const warpCss = computed(() => {
var style = '';
style += 'position:relative;';
@ -64,28 +95,57 @@
}
});
const imgListPreview = computed(() => {
return selectValue.value.map(item => {
return {url: img(item)}
})
})
// const imgListPreview = computed(() => {
// return selectValue.value.map(item => {
// return {url: img(item)}
// })
// })
//
const selectWeChatFile = () => {
uni.chooseMessageFile({
count: 9, // 9
type: 'all', // 'image', 'video', 'file', 'all'
success: (res) => {
console.log('选择的微信聊天文件:', res.tempFiles);
res.tempFiles.forEach(file => {
uploadImage({
filePath: file.path,
name: 'file'
}).then(uploadRes => {
if (diyComponent.value.field.value.length < Number(diyComponent.value.limit)) {
diyComponent.value.field.value.push(uploadRes.data.url);
}
}).catch(() => {
console.error('上传失败');
});
});
},
fail: (err) => {
console.error('选择文件失败', err);
}
});
};
// &
const afterRead = (event) => {
event.file.forEach(item => {
uploadImage({
filePath: item.url,
name: 'file'
}).then(res => {
if (selectValue.value.length < diyComponent.value.limit ) {
selectValue.value.push(res.data.url)
}
}).catch(() => {
})
})
}
event.file.forEach(item => {
uploadImage({
filePath: item.url,
name: 'file'
}).then(res => {
if (diyComponent.value.field.value.length < Number(diyComponent.value.limit)) {
diyComponent.value.field.value.push(res.data.url);
}
}).catch(() => {
console.error('上传失败');
});
});
};
const deletePic = (event)=> {
selectValue.value.splice(event.index, 1)
const deleteImage = (event) => {
diyComponent.value.field.value.splice(event.index, 1)
}
const refresh = ()=> {

View File

@ -1,24 +1,87 @@
<template>
<view :style="warpCss">
form-location
<view class="relative">
<view class="p-[10rpx] flex items-center ">
<view class="w-[27%] mr-[10rpx] flex items-center">
<text class="text-overflow-ellipsis" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx' ,'font-weight': diyComponent.fontWeight}">{{ diyComponent.field.name }}</text>
<text class="text-[#ec0003]">{{ diyComponent.field.required ? '*' : '' }}</text>
<view :style="warpCss" class="form-item-frame">
<view class="base-layout-one" v-if="diyGlobal.completeLayout == 'style-1'">
<view class="layout-one-label">
<text class="text-overflow-ellipsis"
:style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx' ,'font-weight': diyComponent.fontWeight}">{{ diyComponent.field.name }}</text>
<text class="required">{{ diyComponent.field.required ? '*' : '' }}</text>
<text v-if="diyStore.mode == 'decorate' && diyComponent.isHidden"
class="is-hidden">{{ t('diyForm.hidden') }}</text>
</view>
<view v-if="diyComponent.field.remark.text" class="layout-one-remark"
:style="{ color: diyComponent.field.remark.color, fontSize: (diyComponent.field.remark.fontSize * 2 ) + 'rpx' }">
{{ diyComponent.field.remark.text }}</view>
<view class="layout-one-error-message" v-if="errorInfo && !errorInfo.code">{{ errorInfo.message }}</view>
<view v-if="diyComponent.mode== 'authorized_wechat_location'">
<view @click.stop="locationVal.reposition()" v-if="systemStore.diyAddressInfo" class="layout-one-content">
<!-- <view class="flex items-baseline font-500">
<text class="text-[24rpx] mr-[2rpx]">{{ systemStore.diyAddressInfo.city }}</text>
<text class="iconfont iconxiaV6xx !text-[24rpx]"></text>
</view> -->
<text class="iconfont iconzuobiaofill !text-[28rpx]"></text>
<view
v-if="systemStore.diyAddressInfo.community">{{ systemStore.diyAddressInfo.community }}</view>
</view>
<view @click.stop="locationVal.reposition()" class="layout-one-content"
v-else>
<text class="iconfont iconzuobiaofill !text-[28rpx]"></text>
<text class="ml-1 text-[#999]">点击获取位置信息</text>
</view>
</view>
<view v-else>
<view @click.stop="locationVal.reposition()" v-if="systemStore.diyAddressInfo" class="layout-one-content">
<view class="flex items-baseline font-500">
<text class="text-[24rpx] mr-[2rpx]">{{ systemStore.diyAddressInfo.city }}</text>
<text class="iconfont iconxiaV6xx !text-[24rpx]"></text>
</view>
<view class="layout-one-content"
v-if="systemStore.diyAddressInfo.community">{{ systemStore.diyAddressInfo.community }}</view>
</view>
<view @click.stop="locationVal.reposition()" class="layout-one-content"
v-else>
<text class="iconfont iconzuobiaofill !text-[28rpx]"></text>
<text class="ml-1 text-[#999]">选择位置</text>
</view>
<view class="text-[var(--primary-color)] mt-1">
当前定位
</view>
</view>
<!-- <input type="text" class="layout-one-content" :placeholder=""
placeholderClass="layout-one-input-placeholder"
:placeholder-style="{'font-size': (diyComponent.fontSize * 2) + 'rpx' }"
:style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}"
v-model="diyComponent.field.value" :disabled="isDisabled" /> -->
<!-- <view class="layout-one-attribute-wrap" v-if="inputAttribute().length">
<view v-for="(item,index) in inputAttribute()" :key="index" @click="eventFn(item.type)"
class="layout-one-attribute-item">{{ item.title }}</view>
</view> -->
</view>
<!-- <view class="relative">
<view class="p-[10rpx] flex items-center ">
<view class="w-[27%] mr-[10rpx] flex items-center">
<text class="text-overflow-ellipsis"
:style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx' ,'font-weight': diyComponent.fontWeight}">{{ diyComponent.field.name}}</text>
<text class="text-[#ec0003]">{{ diyComponent.field.required ? '*' : '' }}</text>
</view>
</view>
</view> -->
</view>
</template>
<script setup lang="ts">
//
import { ref, computed, watch,onMounted } from 'vue';
import { img } from '@/utils/common';
import { ref, computed, watch, onMounted } from 'vue';
import { img } from '@/utils/common';
import useDiyStore from '@/app/stores/diy';
const props = defineProps(['component', 'index','global']);
import { useLocation } from '@/hooks/useLocation'
import useSystemStore from '@/stores/system';
const errorInfo: any = ref(null);
const systemStore = useSystemStore();
const systemInfo = uni.getSystemInfoSync();
const props = defineProps(['component', 'index', 'global']);
const diyStore = useDiyStore();
const diyComponent = computed(() => {
@ -28,19 +91,34 @@
return props.component;
}
})
const diyGlobal = computed(() => {
return props.global;
})
/************** 定位-start ****************/
let isOpenLocation = false;
if (diyComponent.value && diyStore.mode != 'decorate') {
isOpenLocation = true;
}
const locationVal = useLocation(isOpenLocation);
locationVal.onLoad();
locationVal.init();
/************** 定位-end ****************/
const warpCss = computed(() => {
var style = '';
style += 'position:relative;';
if(diyComponent.value.componentStartBgColor) {
if (diyComponent.value.componentStartBgColor && diyComponent.value.componentEndBgColor) style += `background:linear-gradient(${diyComponent.value.componentGradientAngle},${diyComponent.value.componentStartBgColor},${diyComponent.value.componentEndBgColor});`;
else style += 'background-color:' + diyComponent.value.componentStartBgColor + ';';
}
style += 'position:relative;';
if (diyComponent.value.componentStartBgColor) {
if (diyComponent.value.componentStartBgColor && diyComponent.value.componentEndBgColor) style += `background:linear-gradient(${diyComponent.value.componentGradientAngle},${diyComponent.value.componentStartBgColor},${diyComponent.value.componentEndBgColor});`;
else style += 'background-color:' + diyComponent.value.componentStartBgColor + ';';
}
if(diyComponent.value.componentBgUrl) {
style += `background-image:url('${ img(diyComponent.value.componentBgUrl) }');`;
style += 'background-size: cover;background-repeat: no-repeat;';
}
if (diyComponent.value.componentBgUrl) {
style += `background-image:url('${img(diyComponent.value.componentBgUrl)}');`;
style += 'background-size: cover;background-repeat: no-repeat;';
}
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;';
@ -49,24 +127,24 @@
return style;
})
onMounted(() => {
refresh();
//
if (diyStore.mode == 'decorate') {
watch(
() => diyComponent.value,
(newValue, oldValue) => {
if (newValue && newValue.componentName == 'FormLocation') {
refresh();
}
}
)
}else{
onMounted(() => {
refresh();
//
if (diyStore.mode == 'decorate') {
watch(
() => diyComponent.value,
(newValue, oldValue) => {
if (newValue && newValue.componentName == 'FormLocation') {
refresh();
}
}
)
} else {
}
});
});
const refresh = ()=> {
}
const refresh = () => {
}
//
const verify = () => {
@ -88,9 +166,10 @@
<style lang="scss" scoped>
@import '@/styles/diy_form.scss';
.text-overflow-ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
</style>

View File

@ -1,26 +1,32 @@
<template>
<view :style="warpCss">
//
<view class="relative">
<view class="p-[10rpx] flex items-center ">
<view class="w-[27%] mr-[10rpx] flex items-center">
<text class="text-overflow-ellipsis" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx' ,'font-weight': diyComponent.fontWeight}">{{ diyComponent.field.name }}</text>
<text class="text-[#ec0003]">{{ diyComponent.field.required ? '*' : '' }}</text>
</view>
</view>
</view>
<view :style="warpCss" class="form-item-frame">
</view>
</template>
<script setup lang="ts">
//
import { ref, computed, watch,onMounted } from 'vue';
import { ref, computed, watch, onMounted } from 'vue';
import useDiyStore from '@/app/stores/diy';
import { img } from '@/utils/common';
const props = defineProps(['component', 'index','global']);
import { img, timeStampTurnTime, timeTurnTimeStamp } from '@/utils/common';
const props = defineProps(['component', 'index', 'global']);
const diyStore = useDiyStore();
const formData: any = ref({
id: 0,
name: '',
mobile: '',
province_id: 0,
city_id: 0,
district_id: 0,
lat: '',
lng: '',
address: '',
address_name: '',
full_address: '',
is_default: 0,
area: ''
})
const selectShow = ref<Array<boolean>>(Array(10).fill(false)); //
const diyComponent = computed(() => {
if (diyStore.mode == 'decorate') {
return diyStore.value[props.index];
@ -29,18 +35,190 @@
}
})
const isDisabled = computed(() => {
return diyStore.mode === 'decorate';
});
//
const openPicker = (columnIndex : number) => {
if (isDisabled.value) return;
selectShow.value[columnIndex] = true;
};
//
const getSelectRadioName = (columnIndex : number) => {
const column = diyComponent.value.columnList[columnIndex];
if (!column || !column.value) return '';
const selectedOption = column.options.find(opt => opt.id === column.value);
return selectedOption ? selectedOption.label : '';
};
//
const pullDownConfirmFn = (columnIndex : number, option : any) => {
diyComponent.value.columnList[columnIndex].value = option.id;
selectShow.value[columnIndex] = false;
};
//
const groupChange = (columnIndex : number) => {
const column = diyComponent.value.columnList[columnIndex];
if (!column || !column.value) return;
selectShow.value[columnIndex] = false;
};
const currentColumn = ref(null); //
/**
* 性别
*/
const sexSheetShow = ref(false); //
//
const sexList = computed(() => [
{ name: '男', value: 1 },
{ name: '女', value: 2 }
]);
//
const getSexName = (column : any) => {
if (!column || !column.value) return '请选择';
return column.value === 1 ? '男' : column.value === 2 ? '女' : '请选择';
};
//
const openSex = (column : any) => {
if (isDisabled.value) return;
currentColumn.value = column;
sexSheetShow.value = true;
};
//
const updateSex = (e : any) => {
if (currentColumn.value) {
currentColumn.value.value = e.value; // value
}
sexSheetShow.value = false; //
};
//
let currentDate = new Date();
currentDate.setFullYear(currentDate.getFullYear() + 1);
const maxDate = ref(currentDate.getTime());
let currentDateTime = new Date();
const minDate = ref(currentDateTime.getTime());
const calendarShow = ref(false);
const show = ref(false);
//
const startDate = computed(() => {
if (!currentColumn.value || !currentColumn.value.value) {
return diyComponent.value.placeholder || '请选择日期';
}
return getDateFn(currentColumn.value.value, currentColumn.value.dateFormat);
});
const openCalendar = (column : any) => {
if (diyStore.mode === 'decorate') return;
currentColumn.value = column;
if (column.dateFormat == 'YYYY-MM-DD HH:mm') {
show.value = true;
} else {
calendarShow.value = true;
}
};
const confirm = (e : any) => {
if (currentColumn.value) {
currentColumn.value.value = e[0]; // column
}
calendarShow.value = false;
};
const calendarConfirm = (e : any) => {
if (currentColumn.value) {
currentColumn.value.value = e.value; // column
}
show.value = false;
};
const formatter = (day) => {
const time = timeStampTurnTime(Date.parse(day.date) / 1000, "year_month_day");
return day
}
const getDateFn = (data : any = '', type : any) => {
console.log(data,type)
let timestamp = type == 'YYYY-MM-DD HH:mm' ? data : timeTurnTimeStamp(data);
let date = timestamp > 9999999999 ? new Date(timestamp) : new Date(timestamp * 1000);
let year = date.getFullYear();
let month = String(date.getMonth() + 1).padStart(2, '0');
let day = String(date.getDate()).padStart(2, '0');
console.log(year)
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
let str = '';
if (type == 'YYYY年M月D日') {
str = `${year}${month}${day}`;
} else if (type == 'YYYY-MM-DD') {
str = `${year}-${month}-${day}`;
} else if (type == 'YYYY/MM/DD') {
str = `${year}/${month}/${day}`;
} else if (type == 'YYYY-MM-DD HH:mm') {
str = `${year}-${month}-${day} ${hours}:${minutes}`;
}
return str;
}
const areaRef = ref()
const isSelectAddress = ref(false)
const selectArea = (column : any) => {
currentColumn.value = column;
isSelectAddress.value = true
areaRef.value.open()
}
const areaSelectComplete = (event: any) => {
if (isSelectAddress.value && (formData.value.province_id == event.province.id || formData.value.city_id != event.city.id || formData.value.district_id != event.district.id)) {
formData.value.lat = '';
formData.value.lng = '';
}
formData.value.province_id = event.province.id || 0
formData.value.city_id = event.city.id || 0
formData.value.district_id = event.district.id || 0
formData.value.area = `${ event.province.name || '' }${ event.city.name || '' }${ event.district.name || '' }`
currentColumn.value.value = formData.value.area
isSelectAddress.value = false;
}
const inputPlaceholder = (column: any) => {
if (!column) return "请选择";
const format = column.addressFormat || "province/city/district";
if (format === "province/city/district/address") return "请选择省/市/区/街道";
if (format === "province/city/district/street") return "请选择省/市/区/街道(镇)";
if (format === "province/city/district") return "请选择省/市/区(县)";
if (format === "province/city") return "请选择省/市";
return "请选择省份";
};
const warpCss = computed(() => {
var style = '';
style += 'position:relative;';
if(diyComponent.value.componentStartBgColor) {
if (diyComponent.value.componentStartBgColor && diyComponent.value.componentEndBgColor) style += `background:linear-gradient(${diyComponent.value.componentGradientAngle},${diyComponent.value.componentStartBgColor},${diyComponent.value.componentEndBgColor});`;
else style += 'background-color:' + diyComponent.value.componentStartBgColor + ';';
}
style += 'position:relative;';
if (diyComponent.value.componentStartBgColor) {
if (diyComponent.value.componentStartBgColor && diyComponent.value.componentEndBgColor) style += `background:linear-gradient(${diyComponent.value.componentGradientAngle},${diyComponent.value.componentStartBgColor},${diyComponent.value.componentEndBgColor});`;
else style += 'background-color:' + diyComponent.value.componentStartBgColor + ';';
}
if(diyComponent.value.componentBgUrl) {
style += `background-image:url('${ img(diyComponent.value.componentBgUrl) }');`;
style += 'background-size: cover;background-repeat: no-repeat;';
}
if (diyComponent.value.componentBgUrl) {
style += `background-image:url('${img(diyComponent.value.componentBgUrl)}');`;
style += 'background-size: cover;background-repeat: no-repeat;';
}
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;';
@ -49,24 +227,26 @@
return style;
})
onMounted(() => {
refresh();
//
if (diyStore.mode == 'decorate') {
watch(
() => diyComponent.value,
(newValue, oldValue) => {
if (newValue && newValue.componentName == 'FormTable') {
refresh();
}
}
)
}else{
onMounted(() => {
refresh();
//
if (diyStore.mode == 'decorate') {
watch(
() => diyComponent.value,
(newValue, oldValue) => {
if (newValue && newValue.componentName == 'FormTable') {
refresh();
}
}
)
} else {
}
});
const refresh = ()=> {
}
console.log(diyComponent.value)
});
const refresh = () => {
}
//
const verify = () => {
@ -88,9 +268,10 @@
<style lang="scss" scoped>
@import '@/styles/diy_form.scss';
.text-overflow-ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
</style>

View File

@ -1,32 +1,173 @@
<template>
<view :style="warpCss">
form-video
<view class="relative">
<view v-if="diyComponent.viewFormDetail" class="form-item-frame">
<view class="base-layout-one" v-if="diyGlobal.completeLayout == 'style-1'">
<view class="detail-one-content">
<text class="detail-one-content-label">{{ diyComponent.field.name }}</text>
<view class="flex flex-wrap detail-one-content-value pt-[6rpx]">
<view class="relative w-[180rpx] !h-[180rpx] mr-[16rpx] mb-[16rpx] "
v-for="(item,index) in diyComponent.field.value" :key="index">
<image class="w-[100%] h-[100%]" :src="img(item)" @click="handleImg(item,index)"
mode="aspectFill" />
</view>
</view>
</view>
</view>
<view class="base-layout-two" v-if="diyGlobal.completeLayout == 'style-2'">
<view class="detail-two-content">
<text class="detail-two-content-label">{{ diyComponent.field.name }}</text>
<view class="flex flex-wrap w-[80%] justify-end">
<view class="relative w-[180rpx] !h-[180rpx] mr-[16rpx] mb-[16rpx] "
v-for="(item,index) in diyComponent.field.value" :key="index">
<image class="w-[100%] h-[100%]" :src="img(item)" @click="handleImg(item,index)"
mode="aspectFill" />
</view>
</view>
</view>
</view>
</view>
<view v-else :style="warpCss" class="form-item-frame">
<view class="base-layout-one" v-if="diyGlobal.completeLayout == 'style-1'">
<view class="layout-one-label">
<text class="text-overflow-ellipsis"
:style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx' ,'font-weight': diyComponent.fontWeight}">{{ diyComponent.field.name }}</text>
<text class="required">{{ diyComponent.field.required ? '*' : '' }}</text>
<text v-if="diyStore.mode == 'decorate' && diyComponent.isHidden"
class="is-hidden">{{ t('diyForm.hidden') }}</text>
</view>
<view v-if="diyComponent.field.remark.text" class="layout-one-remark"
:style="{ color: diyComponent.field.remark.color, fontSize: (diyComponent.field.remark.fontSize * 2 ) + 'rpx' }">
{{ diyComponent.field.remark.text }}</view>
<view class="layout-one-error-message" v-if="errorInfo && !errorInfo.code">{{ errorInfo.message }}</view>
<view class="flex flex-wrap">
<view class="relative w-[180rpx] !h-[180rpx] mr-[16rpx] mb-[16rpx] layout-one-content"
v-for="(item,index) in diyComponent.field.value" :key="index">
<image class="w-[100%] h-[100%]" :src="img(item)" mode="aspectFill" />
<view
class="absolute top-0 right-[0] bg-[#373737] flex justify-end h-[28rpx] w-[28rpx] rounded-bl-[40rpx]"
@click="deleteImage(index)">
<text
class="nc-iconfont nc-icon-guanbiV6xx !text-[20rpx] mt-[2rpx] mr-[2rpx] text-[#fff]"></text>
</view>
</view>
<!-- <view class="flex items-center flex-1"
v-if="diyComponent.uploadMode.length > 1 && diyComponent.field.value.length <= 0">
<view class="layout-one-content !p-[0] flex-1 !items-stretch !h-[100rpx]">
<u-upload accept="image" @afterRead="afterRead" multiple :maxCount="9" capture="camera">
<view class="flex items-center h-[100%] w-[100%] pl-[30rpx] box-border">
<text class="nc-iconfont nc-icon-xiangjiV6xx"></text>
<text class="text-[28rpx] ml-[10rpx]">拍照上传</text>
</view>
</u-upload>
</view>
<view class="layout-one-content !p-[0] ml-[20rpx] !items-stretch flex-1 !h-[100rpx]">
<u-upload accept="image" @afterRead="afterRead" multiple :maxCount="9" capture="album">
<view class="flex items-center h-[100%] w-[100%] pl-[30rpx] box-border">
<text class="nc-iconfont nc-icon-tupiandaohangpc"></text>
<text class="text-[28rpx] ml-[10rpx]">从相册中选择</text>
</view>
</u-upload>
</view>
</view> -->
<view class="layout-one-content h-[180rpx] w-[180rpx] !px-[0]">
<u-upload accept="image" v-if="diyComponent.uploadMode=='shoot_and_album'" @afterRead="afterRead"
capture="album" :maxCount="1">
<view class="flex flex-col items-center justify-center w-[180rpx] h-[180rpx] ">
<text class="nc-iconfont !text-[36rpx] nc-icon-jiahaoV6xx mb-[16rpx]"></text>
<text class="text-[28rpx] ml-[10rpx] text-[24rpx]">添加视频</text>
</view>
</u-upload>
<u-upload accept="image" v-else @afterRead="afterRead" :maxCount="1" :maxDuration="60" capture="camera">
<view class="flex flex-col items-center justify-center w-[180rpx] h-[180rpx] ">
<text class="nc-iconfont !text-[36rpx] nc-icon-jiahaoV6xx mb-[16rpx]"></text>
<text class="text-[28rpx] ml-[10rpx] text-[24rpx]">拍摄上传</text>
</view>
</u-upload>
</view>
</view>
<view class="layout-one-attribute-wrap" v-if="inputAttribute().length">
<view v-for="(item,index) in inputAttribute()" :key="index" @click="eventFn(item.type)"
class="layout-one-attribute-item">{{ item.title }}</view>
</view>
</view>
<view class="base-layout-two" v-if="diyGlobal.completeLayout == 'style-2'">
<text v-if="diyStore.mode == 'decorate' && diyComponent.isHidden"
class="layout-two-is-hidden">{{ t('diyForm.hidden') }}</text>
<view class="layout-two-wrap" :class="{'no-border': !diyGlobal.borderControl}">
<view class="layout-two-label"
:class="{'justify-start': diyGlobal.completeAlign == 'left', 'justify-end': diyGlobal.completeAlign == 'right'}">
<text class="required"
v-if="diyComponent.field.required">{{ diyComponent.field.required ? '*' : '' }}</text>
<text class="name"
:style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx' ,'font-weight': diyComponent.fontWeight}">{{ diyComponent.field.name }}</text>
</view>
<view class="layout-two-content flex-wrap">
<view
class="relative border-box w-[180rpx] !h-[180rpx] ml-[16rpx] mb-[16rpx] border-box border-[2rpx] border-solid border-[#e6e6e6] rounded-[10rpx] flex items-center"
v-for="(item,index) in diyComponent.field.value" :key="index">
<image class="w-[100%] h-[100%]" :src="img(item)" mode="aspectFill" />
<view
class="absolute top-0 right-[0] bg-[#373737] flex justify-end h-[28rpx] w-[28rpx] rounded-bl-[40rpx]"
@click="deleteImage(index)">
<text
class="nc-iconfont nc-icon-guanbiV6xx !text-[20rpx] mt-[2rpx] mr-[2rpx] text-[#fff]"></text>
</view>
</view>
<view
class="items-start border-box border-[2rpx] ml-[16rpx] mb-[16rpx] border-solid border-[#e6e6e6] rounded-[10rpx]">
<u-upload accept="video" v-if="diyComponent.uploadMode=='shoot_and_album'" @afterRead="afterRead" :maxCount="1"
capture="album" >
<view class="flex flex-col items-center justify-center w-[180rpx] h-[180rpx] ">
<text class="nc-iconfont !text-[36rpx] nc-icon-jiahaoV6xx mb-[16rpx]"></text>
<text class="text-[28rpx] ml-[10rpx] text-[24rpx]">添加视频</text>
</view>
</u-upload>
<u-upload accept="video" v-else @afterRead="afterRead" :maxCount="1" :maxDuration="60" capture="camera">
<view class="flex flex-col items-center justify-center w-[180rpx] h-[180rpx] ">
<text class="nc-iconfont !text-[36rpx] nc-icon-jiahaoV6xx mb-[16rpx]"></text>
<text class="text-[28rpx] ml-[10rpx] text-[24rpx]">拍摄上传</text>
</view>
</u-upload>
</view>
</view>
</view>
<view class="layout-two-error-message" v-if="errorInfo && !errorInfo.code">{{ errorInfo.message }}</view>
<view v-if="diyComponent.field.remark.text" class="layout-two-remark"
:style="{ color: diyComponent.field.remark.color, fontSize: (diyComponent.field.remark.fontSize * 2 ) + 'rpx' }">
{{ diyComponent.field.remark.text }}</view>
<view class="layout-two-attribute-wrap" v-if="inputAttribute().length">
<view v-for="(item,index) in inputAttribute()" :key="index" @click="eventFn(item.type)"
class="layout-two-attribute-item">{{ item.title }}</view>
</view>
</view>
<view v-if="diyStore.mode == 'decorate'" class="form-item-mask"></view>
<!-- <view class="relative">
<view class="p-[10rpx] flex items-center ">
<view class="w-[25%] flex items-center">
<text class="text-overflow-ellipsis" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx' ,'font-weight': diyComponent.fontWeight}">{{ diyComponent.field.name }}</text>
<text class="text-overflow-ellipsis"
:style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx' ,'font-weight': diyComponent.fontWeight}">{{ diyComponent.field.name }}</text>
<text class="text-[#ec0003]">{{ diyComponent.field.required ? '*' : '' }}</text>
</view>
<view class="w-[75%] flex justify-center items-center">
<u-upload :fileList="imgListPreview" :disabled="isDisabled" @afterRead="afterRead" @delete="deletePic" multiple :maxCount="diyComponent.limit"/>
<u-upload :fileList="imgListPreview" :disabled="isDisabled" @afterRead="afterRead"
@delete="deletePic" multiple :maxCount="diyComponent.limit" />
</view>
</view>
</view>
</view> -->
</view>
</template>
<script setup lang="ts">
//
import { ref, computed, watch,onMounted } from 'vue';
import { ref, computed, watch, onMounted } from 'vue';
import useDiyStore from '@/app/stores/diy';
import { img } from '@/utils/common';
import { uploadImage } from '@/app/api/system'
const props = defineProps(['component', 'index','global']);
import { img } from '@/utils/common';
import { uploadVideo } from '@/app/api/system'
import { t } from '@/locale'
const props = defineProps(['component', 'index', 'global']);
const diyStore = useDiyStore();
const selectValue = ref([])
const errorInfo: any = ref(null);
const diyComponent = computed(() => {
if (diyStore.mode == 'decorate') {
return diyStore.value[props.index];
@ -34,18 +175,33 @@
return props.component;
}
})
//
const uploadType = computed(() => {
let type = '';
if (diyComponent.value && diyComponent.value.uploadMode) {
if(diyComponent.value.uploadMode=='shoot_and_album'){
type = 'album'
}else if(diyComponent.value.uploadMode=='shoot_only'){
type = 'camera'
}
}
return type;
});
const diyGlobal = computed(() => {
return props.global;
})
const warpCss = computed(() => {
var style = '';
style += 'position:relative;';
if(diyComponent.value.componentStartBgColor) {
if (diyComponent.value.componentStartBgColor && diyComponent.value.componentEndBgColor) style += `background:linear-gradient(${diyComponent.value.componentGradientAngle},${diyComponent.value.componentStartBgColor},${diyComponent.value.componentEndBgColor});`;
else style += 'background-color:' + diyComponent.value.componentStartBgColor + ';';
}
style += 'position:relative;';
if (diyComponent.value.componentStartBgColor) {
if (diyComponent.value.componentStartBgColor && diyComponent.value.componentEndBgColor) style += `background:linear-gradient(${diyComponent.value.componentGradientAngle},${diyComponent.value.componentStartBgColor},${diyComponent.value.componentEndBgColor});`;
else style += 'background-color:' + diyComponent.value.componentStartBgColor + ';';
}
if(diyComponent.value.componentBgUrl) {
style += `background-image:url('${ img(diyComponent.value.componentBgUrl) }');`;
style += 'background-size: cover;background-repeat: no-repeat;';
}
if (diyComponent.value.componentBgUrl) {
style += `background-image:url('${img(diyComponent.value.componentBgUrl)}');`;
style += 'background-size: cover;background-repeat: no-repeat;';
}
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;';
@ -54,20 +210,20 @@
return style;
})
onMounted(() => {
refresh();
//
if (diyStore.mode == 'decorate') {
watch(
() => diyComponent.value,
(newValue, oldValue) => {
if (newValue && newValue.componentName == 'FormVideo') {
refresh();
}
}
)
}
});
onMounted(() => {
refresh();
//
if (diyStore.mode == 'decorate') {
watch(
() => diyComponent.value,
(newValue, oldValue) => {
if (newValue && newValue.componentName == 'FormVideo') {
refresh();
}
}
)
}
});
const isDisabled = computed(() => {
@ -76,41 +232,76 @@
const imgListPreview = computed(() => {
return selectValue.value.map(item => {
return {url: img(item)}
return { url: img(item) }
})
})
const afterRead = (event) => {
event.file.forEach(item => {
uploadImage({
filePath: item.url,
name: 'file'
}).then(res => {
if (selectValue.value.length < diyComponent.value.limit ) {
selectValue.value.push(res.data.url)
}
}).catch(() => {
})
})
// uni.setStorageSync('sku_form_refresh', true);
event.file.forEach(item => {
upload(item);
})
}
const upload = (data: any) => {
// if (diyComponent.value.field.value.length > Number(diyComponent.value.limit)) {
// uni.showToast({ title: `${ diyComponent.value.limit }`, icon: 'none' })
// return false
// }
uploadVideo({
filePath: data.url,
name: 'file'
}).then(res => {
// if (diyComponent.value.field.value.length < Number(diyComponent.value.limit)) {
diyComponent.value.field.value.push(res.data.url)
// }
}).catch(() => {
})
}
const deleteImage = (event) => {
diyComponent.value.field.value.splice(event.index, 1)
}
// input
const inputAttribute = () => {
let arr = [];
if (diyComponent.value.autofill) {
let obj = {
title: '已自动填充'
};
arr.push(obj);
}
arr.forEach((item, index, arr) => {
if (index != (arr.length - 1)) {
let obj = {
title: '|'
};
arr.push(obj);
}
})
return arr;
}
const deletePic = (event)=> {
selectValue.value.splice(event.index, 1)
const refresh = () => {
}
const refresh = ()=> {
}
//
const verify = () => {
const res = { code: true, message: '' }
// todo diyComponent.value.field.value
return res;
const res = { code: true, message: '' }
// todo diyComponent.value.field.value
if (diyComponent.value.field.required && (!diyComponent.value.field.value || diyComponent.value.field.value && !diyComponent.value.field.value.length)) {
res.code = false
res.message = `请上传视频`;
}
errorInfo.value = res;
return res;
}
//
const reset = () => {
// todo diyComponent.value.field.value = '';
// todo
diyComponent.value.field.value = [];
}
defineExpose({
@ -121,4 +312,4 @@
<style lang="scss" scoped>
@import '@/styles/diy_form.scss';
</style>
</style>

View File

@ -1,26 +1,76 @@
<template>
<view :style="warpCss">
form-wechat-name
<view class="relative">
<view class="p-[10rpx] flex items-center ">
<view class="w-[27%] mr-[10rpx] flex items-center">
<text class="text-overflow-ellipsis" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx' ,'font-weight': diyComponent.fontWeight}">{{ diyComponent.field.name }}</text>
<text class="text-[#ec0003]">{{ diyComponent.field.required ? '*' : '' }}</text>
</view>
</view>
</view>
<view v-if="diyComponent.viewFormDetail" class="form-item-frame">
<view class="base-layout-one" v-if="diyGlobal.completeLayout == 'style-1'">
<view class="detail-one-content">
<text class="detail-one-content-label">{{ diyComponent.field.name }}</text>
<text class="detail-one-content-value">{{ diyComponent.field.value }}</text>
</view>
</view>
<view class="base-layout-two" v-if="diyGlobal.completeLayout == 'style-2'">
<view class="detail-two-content">
<view>{{ diyComponent.field.name }}</view>
<view class="detail-two-content-value w-[80%]">{{ diyComponent.field.value }}</view>
</view>
</view>
</view>
<view v-else :style="warpCss" class="form-item-frame">
<view class="base-layout-one" v-if="diyGlobal.completeLayout == 'style-1'">
<view class="layout-one-label">
<text class="text-overflow-ellipsis" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx' ,'font-weight': diyComponent.fontWeight}">{{ diyComponent.field.name }}</text>
<text class="required">{{ diyComponent.field.required ? '*' : '' }}</text>
<text v-if="diyStore.mode == 'decorate' && diyComponent.isHidden" class="is-hidden">{{ t('diyForm.hidden') }}</text>
</view>
<view v-if="diyComponent.field.remark.text" class="layout-one-remark" :style="{ color: diyComponent.field.remark.color, fontSize: (diyComponent.field.remark.fontSize * 2 ) + 'rpx' }">{{ diyComponent.field.remark.text }}</view>
<view class="layout-one-error-message" v-if="errorInfo && !errorInfo.code">{{ errorInfo.message }}</view>
<input type="nickname" class="layout-one-content" placeholder="获取填表人的微信名"
placeholderClass="layout-one-input-placeholder"
:placeholder-style="{'font-size': (diyComponent.fontSize * 2) + 'rpx' }"
:style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}"
v-model="diyComponent.field.value" :disabled="isDisabled" @click="openInfo" />
<!-- <view class="layout-one-attribute-wrap" v-if="inputAttribute().length">
<view v-for="(item,index) in inputAttribute()" :key="index" @click="eventFn(item.type)" class="layout-one-attribute-item">{{ item.title }}</view>
</view> -->
</view>
<view class="base-layout-two" v-if="diyGlobal.completeLayout == 'style-2'">
<text v-if="diyStore.mode == 'decorate' && diyComponent.isHidden" class="layout-two-is-hidden">{{ t('diyForm.hidden') }}</text>
<view class="layout-two-wrap" :class="{'no-border': !diyGlobal.borderControl}">
<view class="layout-two-label" :class="{'justify-start': diyGlobal.completeAlign == 'left', 'justify-end': diyGlobal.completeAlign == 'right'}">
<text class="required" v-if="diyComponent.field.required">{{ diyComponent.field.required ? '*' : '' }}</text>
<text class="name" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx' ,'font-weight': diyComponent.fontWeight}">{{ diyComponent.field.name }}</text>
</view>
<input type="nickname" class="layout-two-content no-flex" placeholder="获取填表人的微信名"
placeholderClass="layout-two-input-placeholder" @click="openInfo"
:placeholder-style="{'font-size': (diyComponent.fontSize * 2) + 'rpx'}"
:style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}"
v-model="diyComponent.field.value" :disabled="isDisabled" />
</view>
<view class="layout-two-error-message" v-if="errorInfo && !errorInfo.code">{{ errorInfo.message }}</view>
<view v-if="diyComponent.field.remark.text" class="layout-two-remark" :style="{ color: diyComponent.field.remark.color, fontSize: (diyComponent.field.remark.fontSize * 2 ) + 'rpx' }">{{ diyComponent.field.remark.text }}</view>
<!-- <view class="layout-two-attribute-wrap" v-if="inputAttribute().length">
<view v-for="(item,index) in inputAttribute()" :key="index" @click="eventFn(item.type)" class="layout-two-attribute-item">{{ item.title }}</view>
</view> -->
</view>
<view v-if="diyStore.mode == 'decorate'" class="form-item-mask"></view>
</view>
<!-- #ifdef MP-WEIXIN -->
<!-- <information-filling ref="infoFill"></information-filling> -->
<!-- #endif -->
</template>
<script setup lang="ts">
//
import { ref, computed, watch,onMounted } from 'vue';
import useDiyStore from '@/app/stores/diy';
import { img } from '@/utils/common';
import { img, isWeixinBrowser } from '@/utils/common'
import { useLogin } from '@/hooks/useLogin'
import { t } from '@/locale'
import useMemberStore from '@/stores/member'
const memberStore = useMemberStore()
const login = useLogin()
const props = defineProps(['component', 'index','global']);
const diyStore = useDiyStore();
const infoFill: any = ref(false)
const errorInfo: any = ref(null);
const diyComponent = computed(() => {
if (diyStore.mode == 'decorate') {
return diyStore.value[props.index];
@ -28,6 +78,68 @@
return props.component;
}
})
const diyGlobal = computed(() => {
return props.global;
})
const inputAttribute = () => {
let arr = [];
if (diyComponent.value.autofill) {
let obj = {
title: '已自动填充'
};
arr.push(obj);
}
if (diyComponent.value.field.privacyProtection) {
let obj = {
title: '已开启隐私保护',
type: 'privacy'
};
arr.push(obj);
}
arr.forEach((item, index, arr) => {
if (index != (arr.length - 1)) {
let obj = {
title: '|'
};
arr.push(obj);
}
})
return arr;
}
const openInfo = ()=>{
// #ifdef H5
wechatGetInfo();
// #endif
// #ifdef MP
weappGetInfo()
// #endif
}
const wechatGetInfo = async () => {
// if (isWeixinBrowser()) {
// const userInfo = await login.getAuthCode({ scopes: 'snsapi_userinfo' });
if (memberStore) {
console.log(memberStore)
diyComponent.value.field.value = memberStore.info.nickname;
}
// }
};
const weappGetInfo = async () => {
// #ifdef MP-WEIXIN
wx.getUserInfo({
success: function(res) {
},
fail: function(res) {}
});
// #endif
};
const warpCss = computed(() => {
var style = '';
@ -70,15 +182,23 @@
//
const verify = () => {
const res = { code: true, message: '' }
// todo diyComponent.value.field.value
return res;
const res = { code: true, message: '' }
if (diyComponent.value.field.required && diyComponent.value.field.value == '' && diyStore.mode != 'decorate') {
res.code = false
res.message ='111';
}
errorInfo.value = res;
return res;
}
//
const reset = () => {
// todo diyComponent.value.field.value = '';
diyComponent.value.field.value = '';
}
const isDisabled = computed(() => {
return diyStore.mode == 'decorate';
});
defineExpose({
verify,

View File

@ -57,11 +57,11 @@
</swiper-item>
</swiper>
<view class="graphic-nav-indicator-dot" v-if="shouldShowIndicator && swiperHeight">
<div class="dots-wrap" :class="[diyComponent.swiper.indicatorAlign]">
<div v-for="(item,index) in Math.ceil(diyComponent.list.length / (diyComponent.pageCount * diyComponent.rowCount))"
<view class="dots-wrap" :class="[diyComponent.swiper.indicatorAlign]">
<view v-for="(item,index) in Math.ceil(diyComponent.list.length / (diyComponent.pageCount * diyComponent.rowCount))"
:class="['dot',index == swiperIndex ? 'dot-active' : '',diyComponent.swiper.indicatorStyle]"
:style="{ background : index == swiperIndex ? diyComponent.swiper.indicatorActiveColor : diyComponent.swiper.indicatorColor}"></div>
</div>
:style="{ background : index == swiperIndex ? diyComponent.swiper.indicatorActiveColor : diyComponent.swiper.indicatorColor}"></view>
</view>
</view>
</view>
@ -254,7 +254,7 @@ const refresh = () => {
handleData()
const query = uni.createSelectorQuery().in(instance);
query.select('.diy-graphic-nav').boundingClientRect((data: any) => {
height.value = data.height;
if(data) height.value = data.height;
}).exec();
})
}

View File

@ -44,9 +44,9 @@
<view class="w-[570rpx] px-[32rpx] popup-common center">
<view class="title">公告</view>
<scroll-view :scroll-y="true" class="px-[30rpx] box-border h-[260rpx]">
<block v-for="(item) in noticeContent.split('\n')">
<template v-for="(item) in noticeContent.split('\n')">
<view class="text-[28rpx] leading-[40rpx] mb-[20rpx]">{{ item }}</view>
</block>
</template>
</scroll-view>
<view class="btn-wrap !pt-[40rpx]">
<button class="primary-btn-bg w-[480rpx] h-[70rpx] text-[26rpx] leading-[70rpx] rounded-[35rpx] !text-[#fff] font-500" @click="noticeShow = false">我知道了</button>

View File

@ -4,12 +4,12 @@
<view class="diy-text relative">
<view v-if="diyComponent.style == 'style-1'" class="px-[var(--pad-sidebar-m)]">
<view @click="diyStore.toRedirect(diyComponent.link)">
<view class="leading-[1]" :style="{ fontSize: diyComponent.fontSize * 2 + 'rpx', color: diyComponent.textColor, fontWeight: (diyComponent.fontWeight == 'normal' ? 500 : diyComponent.fontWeight), textAlign : diyComponent.textAlign }">{{ diyComponent.text }}</view>
<view class="leading-[1]" :style="textStyle1">{{ diyComponent.text }}</view>
</view>
</view>
<view v-if="diyComponent.style == 'style-2'" class=" px-[20rpx] flex items-center">
<view @click="diyStore.toRedirect(diyComponent.link)">
<view class="max-w-[200rpx] truncate leading-[1]" :style="{ fontSize: diyComponent.fontSize * 2 + 'rpx', color: diyComponent.textColor, fontWeight: (diyComponent.fontWeight == 'normal' ? 500 : diyComponent.fontWeight) }">{{ diyComponent.text }}</view>
<view class="max-w-[200rpx] truncate leading-[1]" :style="textStyle2">{{ diyComponent.text }}</view>
</view>
<text v-if="diyComponent.subTitle.text" :style="{background: diyComponent.subTitle.color}" class="mx-[10rpx] w-[2rpx] h-[24rpx] opacity-70"></text>
<text class="max-w-[300rpx] truncate" :style="{ color: diyComponent.subTitle.color, fontSize: diyComponent.subTitle.fontSize * 2 + 'rpx', }">{{ diyComponent.subTitle.text }}</text>
@ -41,6 +41,25 @@ const diyComponent = computed(() => {
}
})
//
const textStyle1 = computed(() => {
return {
fontSize: diyComponent.value.fontSize * 2 + 'rpx',
color: diyComponent.value.textColor,
fontWeight: diyComponent.value.fontWeight === 'normal' ? 500 : diyComponent.value.fontWeight,
textAlign: diyComponent.value.textAlign
};
});
//
const textStyle2 = computed(() => {
return {
fontSize: diyComponent.value.fontSize * 2 + 'rpx',
color: diyComponent.value.textColor,
fontWeight: diyComponent.value.fontWeight === 'normal' ? 500 : diyComponent.value.fontWeight
};
});
const warpCss = computed(() => {
var style = '';
style += 'position:relative;';

View File

@ -1,33 +1,33 @@
{
"cashOutNow": "立即提现",
"balanceDetail": "余额明细",
"cashOutTo": "提现到",
"cashOutTypePlaceholder": "请选择提现方式",
"wechatpay": "微信默认钱包",
"cashOutMoneyTip": "提现金额",
"money": "可提现余额",
"allTx": "全部提现",
"minWithdrawal": "最小提现金额为",
"commissionTo": "手续费为",
"cashOutList": "提现记录",
"cashOutToWechat": "提现至微信零钱",
"cashOutToWechatTips": "提现至微信零钱",
"cashOutToAlipay": "提现至支付宝",
"cashOutToAlipayTips": "请先添加支付宝账号",
"cashOutToBank": "提现至银行卡",
"cashOutToBankTips": "请先添加银行卡",
"cashOutToWechatCode": "提现至微信",
"cashOutToWechatCodeTips": "请先添加微信号",
"alipayAccountNo": "支付宝账号",
"wechatCodeAccountNo": "微信号",
"debitCard": "储蓄卡",
"abnormalOperation": "异常操作",
"noAvailableCashOutType": "没有可用的提现方式",
"applyMoneyPlaceholder": "请输入提现金额",
"moneyformatError": "提现金额格式错误",
"applyMoneyExceed": "提现金额超出可提现金额",
"applyMoneyBelow": "提现金额小于最低提现金额",
"replace": "更换",
"isOpenApply": "提现设置未开启",
"toAdd": "添加"
"cashOutNow": "立即提现",
"balanceDetail": "余额明细",
"cashOutTo": "提现到",
"cashOutTypePlaceholder": "请选择提现方式",
"wechatpay": "微信默认钱包",
"cashOutMoneyTip": "提现金额",
"money": "可提现余额",
"allTx": "全部提现",
"minWithdrawal": "最小提现金额为",
"commissionTo": "手续费为",
"cashOutList": "提现记录",
"cashOutToWechat": "提现至微信零钱",
"cashOutToWechatTips": "提现至微信零钱",
"cashOutToAlipay": "提现至支付宝",
"cashOutToAlipayTips": "请先添加支付宝账号",
"cashOutToBank": "提现至银行卡",
"cashOutToBankTips": "请先添加银行卡",
"cashOutToWechatCode": "提现至微信",
"cashOutToWechatCodeTips": "请先添加微信号",
"alipayAccountNo": "支付宝账号",
"wechatCodeAccountNo": "微信号",
"debitCard": "储蓄卡",
"abnormalOperation": "异常操作",
"noAvailableCashOutType": "没有可用的提现方式",
"applyMoneyPlaceholder": "请输入提现金额",
"moneyformatError": "提现金额格式错误",
"applyMoneyExceed": "提现金额超出可提现金额",
"applyMoneyBelow": "提现金额小于最低提现金额",
"replace": "更换",
"isOpenApply": "提现设置未开启",
"toAdd": "添加"
}

View File

@ -182,7 +182,7 @@ onLoad(async(option: any) => {
//
// #ifdef MP-WEIXIN
if (configStore.login.is_username && !configStore.login.is_mobile && !configStore.login.is_auth_register) {
if (!configStore.login.is_auth_register) {
isShowQuickLogin.value = false;
} else {
isShowQuickLogin.value = true;
@ -192,18 +192,14 @@ onLoad(async(option: any) => {
// #ifdef H5
if (isWeixinBrowser()) {
//
if (configStore.login.is_username && !configStore.login.is_mobile && !configStore.login.is_auth_register) {
if (!configStore.login.is_auth_register) {
isShowQuickLogin.value = false;
} else {
isShowQuickLogin.value = true;
}
} else {
//
if (configStore.login.is_username && !configStore.login.is_mobile) {
isShowQuickLogin.value = false;
} else {
isShowQuickLogin.value = true;
}
isShowQuickLogin.value = false;
}
// #endif
})

View File

@ -4,9 +4,9 @@
<view class="w-[570rpx] px-[32rpx] popup-common center" v-if="Object.keys(configInfo).length">
<view class="title">{{ configInfo.pay_explain_title }}</view>
<scroll-view :scroll-y="true" class="px-[30rpx] box-border max-h-[260rpx]" v-if="configInfo.pay_explain_content">
<block v-for="(item) in configInfo.pay_explain_content.split('\n')">
<template v-for="(item) in configInfo.pay_explain_content.split('\n')">
<view class="text-[28rpx] leading-[40rpx] mb-[20rpx]">{{ item }}</view>
</block>
</template>
</scroll-view>
<view class="btn-wrap !pt-[40rpx]">
<button class="primary-btn-bg w-[480rpx] h-[70rpx] text-[26rpx] leading-[70rpx] rounded-[35rpx] !text-[#fff] font-500" @click="closeFn">我知道了</button>

View File

@ -26,7 +26,10 @@
import { ref, nextTick } from 'vue';
import { useDiy } from '@/hooks/useDiy'
import { redirect } from '@/utils/common';
import { useShare } from '@/hooks/useShare'
import diyGroup from '@/addon/components/diy/group/index.vue'
const { setShare } = useShare()
uni.hideTabBar() // tabbar
@ -51,6 +54,8 @@ diy.onShow((data: any) => {
//
redirect({ url: data.page, mode: 'reLaunch' })
}
let share = data.share ? JSON.parse(data.share) : null;
setShare(share);
diyGroupRef.value?.refresh();
// #ifdef MP
nextTick(() => {

View File

@ -2,7 +2,7 @@
<view class="w-screen h-screen bg-[var(--page-bg-color)] overflow-hidden" :style="themeColor()">
<scroll-view scroll-y="true">
<view class="sidebar-margin card-template top-mar account pb-[20rpx]">
<block v-if="formData.account_type == 'bank'">
<template v-if="formData.account_type == 'bank'">
<view class="text-center text-[32rpx] font-500 mt-[10rpx] text-[#333] leading-[42rpx]">{{ formData.account_id ? t('editBankCard') : t('addBankCard') }}</view>
<view class="text-center text-[24rpx] mt-[16rpx] text-[var(--text-color-light9)]">{{ formData.account_id ? t('editBankCardTips') : t('addBankCardTips') }}</view>
<view class="mt-[70rpx] px-[10rpx]">
@ -24,9 +24,9 @@
</view>
</u-form>
</view>
</block>
</template>
<block v-if="formData.account_type == 'alipay'">
<template v-if="formData.account_type == 'alipay'">
<view class="text-center text-[32rpx] font-500 mt-[20rpx] text-[#333] leading-[42rpx]">{{ formData.account_id ? t('editAlipayAccount') : t('addAlipayAccount') }}</view>
<!-- <view class="text-center text-[28rpx] mt-[16rpx] text-[var(--text-color-light9)] leading-[36rpx]">{{ formData.account_id ? t('editAlipayAccountTips') : t('addAlipayAccountTips') }}</view> -->
@ -55,9 +55,9 @@
</view>
</u-form>
</view>
</block>
</template>
<block v-if="formData.account_type == 'wechat_code'">
<template v-if="formData.account_type == 'wechat_code'">
<view class="text-center text-[32rpx] font-500 mt-[20rpx] text-[#333] leading-[42rpx]">{{ formData.account_id ? t('editWechatCodeAccount') : t('addWechatCodeAccount') }}</view>
<!-- <view class="text-center text-[28rpx] mt-[16rpx] text-[var(--text-color-light9)] leading-[36rpx]">{{ formData.account_id ? t('editWechatCodeAccountTips') : t('addWechatCodeAccountTips') }}</view> -->
@ -86,7 +86,7 @@
</view>
</u-form>
</view>
</block>
</template>
</view>
<view class="common-tab-bar-placeholder"></view>
<view class="common-tab-bar fixed left-[var(--sidebar-m)] right-[var(--sidebar-m)] bottom-[0]">

View File

@ -3,12 +3,12 @@
<scroll-view :scroll-y="true" class="w-screen h-screen bg-[var(--page-bg-color)]" v-if="!pageLoading && config.is_open == 1">
<view class="sidebar-margin pt-[var(--top-m)]">
<view class="card-template">
<view class="font-500 text-[30rpx] text-[#333] leading-[42rpx]">{{ t('cashOutMoneyTip') }}</view>
<view class="font-500 text-[30rpx] text-[#333] leading-[42rpx]">最小提现金额为</view>
<view class="flex pt-[30rpx] pb-[8rpx] items-center border-0 border-b-[2rpx] border-solid border-[#F1F2F5]">
<text class="pt-[4rpx] text-[44rpx] text-[#333] iconfont iconrenminbiV6xx price-font "></text>
<input type="digit" class="h-[76rpx] leading-[76rpx] pl-[10rpx] flex-1 font-500 text-[54rpx] bg-[#fff]"
v-model="applyData.apply_money" maxlength="7"
:placeholder="applyData.apply_money?'':(t('minWithdrawal') + t('currency') + moneyFormat(config.min))"
:placeholder="applyData.apply_money?'':('最小提现金额为' + t('currency') + moneyFormat(config.min))"
placeholder-class="apply-price" :adjust-position="false" />
<text v-if="Number(serviceMoney)" class="text-[24rpx] text-[var(--text-color-light6)] mr-[20rpx]">手续费{{ serviceMoney }}
</text>
@ -16,10 +16,10 @@
</view>
<view class="pt-[16rpx] flex items-center justify-between px-[4rpx]">
<view class="text-[24rpx] text-[var(--text-color-light6)] leading-[36rpx]">
<text>{{ t('money') }}{{ t('currency') }}{{ moneyFormat(cashOutMoney) }}</text>
<text>{{ t('commissionTo') }}{{ config.rate + '%' }}</text>
<text>可提现余额{{ t('currency') }}{{ moneyFormat(cashOutMoney) }}</text>
<text>手续费为{{ config.rate + '%' }}</text>
</view>
<view class="text-[24rpx] text-primary leading-[36rpx]" @click="allMoney">{{ t('allTx') }}</view>
<view class="text-[24rpx] text-primary leading-[36rpx]" @click="allMoney">全部提现</view>
</view>
</view>
@ -34,8 +34,8 @@
<image class="h-[60rpx] w-[60rpx] align-middle" :src="img('static/resource/images/member/apply_withdrawal/wechat.png')" mode="widthFix" />
</view>
<view class="flex-1 px-[20rpx]">
<view class="text-[28rpx] text-[#333] leading-[40rpx] mb-[6rpx]">{{ t('cashOutToWechat') }}</view>
<view class="text-[var(--text-color-light9)] text-[24rpx] leading-[34rpx]">{{ t('cashOutToWechatTips') }}</view>
<view class="text-[28rpx] text-[#333] leading-[40rpx] mb-[6rpx]">提现至微信零钱</view>
<view class="text-[var(--text-color-light9)] text-[24rpx] leading-[34rpx]">提现至微信零钱</view>
</view>
</view>
@ -47,19 +47,19 @@
<image class="h-[60rpx] w-[60rpx] align-middle" :src="img('static/resource/images/member/apply_withdrawal/wechat_code.png')" mode="widthFix" />
</view>
<view class="flex-1 px-[22rpx]" @click="transferWechatCode">
<view class="text-[28rpx] text-[#333] leading-[40rpx] mb-[6rpx]">{{ t('cashOutToWechatCode') }}</view>
<view class="text-[28rpx] text-[#333] leading-[40rpx] mb-[6rpx]">提现至微信</view>
<view class="text-[var(--text-color-light9)] text-[24rpx] leading-[34rpx]">
<view v-if="wechatCodeInfo" class="truncate max-w-[440rpx]">
<text>{{ t('cashOutTo') }}{{ t('wechatCodeAccountNo') }}</text>
<text>提现到微信号</text>
<text class="text-[#333]">{{ wechatCodeInfo.account_no }}</text>
</view>
<view v-else>{{ t('cashOutToWechatCodeTips') }}</view>
<view v-else>请先添加微信号</view>
</view>
</view>
<view class="flex items-center">
<button v-if="!wechatCodeInfo && !wechatCodeLoading" hover-class="none"
class="w-[110rpx] h-[54rpx] flex-center rounded-full p-[0] text-[var(--primary-color)] bg-transparent border-[2rpx] border-solid border-[var(--primary-color)] text-[22rpx]"
@click="redirect({ url: '/app/pages/member/account', param: { type: 'wechat_code', mode: 'select' } , mode: 'redirectTo'})">{{ t('toAdd') }}</button>
@click="redirect({ url: '/app/pages/member/account', param: { type: 'wechat_code', mode: 'select' } , mode: 'redirectTo'})">添加</button>
<text v-else class="nc-iconfont nc-icon-youV6xx text-[28rpx] text-[var(--text-color-light9)] p-[10rpx]"
@click.stop="redirect({ url: '/app/pages/member/account', param: { type: 'wechat_code', mode: 'select' } , mode: 'redirectTo'})"></text>
</view>
@ -73,19 +73,19 @@
<image class="h-[60rpx] w-[60rpx] align-middle" :src="img('static/resource/images/member/apply_withdrawal/alipay-icon.png')" mode="widthFix" />
</view>
<view class="flex-1 px-[22rpx]" @click="transferAlipay">
<view class="text-[28rpx] text-[#333] leading-[40rpx] mb-[6rpx]">{{ t('cashOutToAlipay') }}</view>
<view class="text-[28rpx] text-[#333] leading-[40rpx] mb-[6rpx]">提现至支付宝</view>
<view class="text-[var(--text-color-light9)] text-[24rpx] leading-[34rpx]">
<view v-if="alipayAccountInfo" class="truncate max-w-[440rpx]">
<text>{{ t('cashOutTo') }}{{ t('alipayAccountNo') }}</text>
<text>提现到支付宝账号</text>
<text class="text-[#333]">{{ alipayAccountInfo.account_no }}</text>
</view>
<view v-else>{{ t('cashOutToAlipayTips') }}</view>
<view v-else>请先添加支付宝账号</view>
</view>
</view>
<view class="flex items-center">
<button v-if="!alipayAccountInfo && !alipayLoading" hover-class="none"
class="w-[110rpx] h-[54rpx] flex-center rounded-full p-[0] text-[var(--primary-color)] bg-transparent border-[2rpx] border-solid border-[var(--primary-color)] text-[22rpx]"
@click="redirect({ url: '/app/pages/member/account', param: { type: 'alipay', mode: 'select' } , mode: 'redirectTo'})">{{ t('toAdd') }}</button>
@click="redirect({ url: '/app/pages/member/account', param: { type: 'alipay', mode: 'select' } , mode: 'redirectTo'})">添加</button>
<text v-else class="nc-iconfont nc-icon-youV6xx text-[28rpx] text-[var(--text-color-light9)] p-[10rpx]"
@click.stop="redirect({ url: '/app/pages/member/account', param: { type: 'alipay', mode: 'select' } , mode: 'redirectTo'})"></text>
</view>
@ -99,19 +99,19 @@
<image class="h-[42rpx] w-[60rpx] align-middle" :src="img('static/resource/images/member/apply_withdrawal/bank-icon.png')" mode="widthFix" />
</view>
<view class="flex-1 px-[20rpx]" @click="transferBank">
<view class="text-[28rpx] text-[#333] leading-[40rpx] mb-[6rpx]">{{ t('cashOutToBank') }}</view>
<view class="text-[28rpx] text-[#333] leading-[40rpx] mb-[6rpx]">提现至银行卡</view>
<view class="text-[var(--text-color-light9)] text-[24rpx] leading-[34rpx]">
<view v-if="bankAccountInfo" class="truncate max-w-[440rpx]">
<text>{{ t('cashOutTo') }}{{ bankAccountInfo.bank_name }}{{ t('debitCard') }}</text>
<text>提现到{{ bankAccountInfo.bank_name }}储蓄卡</text>
<text class="text-[#333]">{{ bankAccountInfo.account_no.substring(bankAccountInfo.account_no.length - 4) }}</text>
</view>
<view v-else>{{ t('cashOutToBankTips') }}</view>
<view v-else>请先添加银行卡</view>
</view>
</view>
<view class="flex items-center">
<button hover-class="none" class="h-[54rpx] flex-center rounded-full p-[0] w-[110rpx] text-[var(--primary-color)] bg-transparent border-[2rpx] border-solid border-[var(--primary-color)] text-[22rpx]"
v-if="!bankAccountInfo && !bankLoading"
@click="redirect({ url: '/app/pages/member/account', param: { type: 'bank', mode: 'select' }, mode: 'redirectTo' })">{{ t('toAdd') }}</button>
@click="redirect({ url: '/app/pages/member/account', param: { type: 'bank', mode: 'select' }, mode: 'redirectTo' })">添加</button>
<text v-else class="nc-iconfont nc-icon-youV6xx text-[28rpx] text-[var(--text-color-light9)] p-[10rpx]"
@click.stop="redirect({ url: '/app/pages/member/account', param: { type: 'bank', mode: 'select' }, mode: 'redirectTo' })"></text>
</view>
@ -120,9 +120,9 @@
<view class="tab-bar-placeholder"></view>
<view class="fixed bottom-[0] tab-bar left-0 right-0 px-[var(--sidebar-m)] bg-[var(--page-bg-color)]">
<button class="h-[80rpx] !text-[#fff] leading-[80rpx] primary-btn-bg rounded-[50rpx] text-[26rpx]" :disabled="applyData.apply_money == '' || applyData.apply_money == 0" :loading="loading" @click="cashOut">{{ t('cashOutNow') }}</button>
<button class="h-[80rpx] !text-[#fff] leading-[80rpx] primary-btn-bg rounded-[50rpx] text-[26rpx]" :disabled="applyData.apply_money == '' || applyData.apply_money == 0" :loading="loading" @click="cashOut">立即提现</button>
<view class="mt-[30rpx] text-center text-[26rpx] text-primary"
@click.stop="redirect({ url: '/app/pages/member/cash_out'})">{{ t('cashOutList') }}</view>
@click.stop="redirect({ url: '/app/pages/member/cash_out'})">提现记录</view>
</view>
</view>
@ -130,7 +130,7 @@
<view class="h-[100vh] w-[100vw] bg-[var(--page-bg-color)] overflow-hidden" v-if="config.is_open == 0 && !pageLoading">
<view class="empty-page">
<image class="img" :src="img('addon/shop/cart-empty.png')" model="aspectFit" />
<view class="desc">{{ t('isOpenApply') }}</view>
<view class="desc">提现设置未开启</view>
</view>
</view>
<loading-page :loading="pageLoading"></loading-page>
@ -200,7 +200,7 @@ onLoad(async(data) => {
if (!['money', 'commission'].includes(applyData.account_type)) {
uni.showToast({
title: t('abnormalOperation'),
title: '异常操作',
icon: 'none',
success() {
setTimeout(() => {
@ -267,23 +267,23 @@ const clearMoney = () => {
const verify = () => {
if (!applyData.transfer_type) {
uni.showToast({ title: t('noAvailableCashOutType'), icon: 'none' })
uni.showToast({ title: '没有可用的提现方式', icon: 'none' })
return false
}
if (uni.$u.test.isEmpty(applyData.apply_money)) {
uni.showToast({ title: t('applyMoneyPlaceholder'), icon: 'none' })
uni.showToast({ title: '请输入提现金额', icon: 'none' })
return false
}
if (!uni.$u.test.amount(applyData.apply_money)) {
uni.showToast({ title: t('moneyformatError'), icon: 'none' })
uni.showToast({ title: '提现金额格式错误', icon: 'none' })
return false
}
if (parseFloat(applyData.apply_money) > parseFloat(cashOutMoney.value)) {
uni.showToast({ title: t('applyMoneyExceed'), icon: 'none' })
uni.showToast({ title: '提现金额超出可提现金额', icon: 'none' })
return false
}
if (parseFloat(applyData.apply_money) < parseFloat(config.min)) {
uni.showToast({ title: t('applyMoneyBelow'), icon: 'none' })
uni.showToast({ title: '提现金额小于最低提现金额', icon: 'none' })
return false
}
return true;
@ -391,7 +391,7 @@ const cashOut = () => {
//
const transferAlipay = () => {
if (!alipayAccountInfo.value) {
uni.showToast({ title: t('cashOutToAlipayTips'), icon: 'none' })
uni.showToast({ title: '请先添加支付宝账号', icon: 'none' })
return false
}
applyData.transfer_type = 'alipay'
@ -399,7 +399,7 @@ const transferAlipay = () => {
//
const transferBank = () => {
if (!bankAccountInfo.value) {
uni.showToast({ title: t('cashOutToBankTips'), icon: 'none' })
uni.showToast({ title: '请先添加银行卡', icon: 'none' })
return false
}
applyData.transfer_type = 'bank'
@ -417,7 +417,7 @@ const transferWeixin = () => {
//
const transferWechatCode = () => {
if (!wechatCodeInfo.value) {
uni.showToast({ title: t('cashOutToWechatCodeTips'), icon: 'none' })
uni.showToast({ title: '请先添加微信号', icon: 'none' })
return false
}
applyData.transfer_type = 'wechat_code'

View File

@ -25,17 +25,17 @@
</view>
</view>
<view class="mt-[60rpx] flex justify-around" v-if="Object.keys(cashOutConfigObj).length && (systemStore.siteAddons.includes('recharge') || cashOutConfigObj.is_open == 1 || rechargeConfigObj.is_use == 1)">
<block v-if="systemStore.siteAddons.includes('recharge')">
<template v-if="systemStore.siteAddons.includes('recharge')">
<button v-if="rechargeConfigObj.is_use == 1"
class="w-[250rpx] h-[70rpx] rounded-[40rpx] text-[26rpx] font-500 !bg-[#fff] !text-[var(--primary-color)] flex-center !m-0 border-[2rpx] border-[var(--primary-color)] border-solid box-border"
hover-class="none" shape="circle"
@click="redirect({url: '/addon/recharge/pages/recharge'})">充值</button>
</block>
</template>
<view v-if="cashOutConfigObj.is_open == 1"
:class="{'!w-[340rpx]': !systemStore.siteAddons.includes('recharge')}"
class="text-center w-[250rpx] h-[70rpx] rounded-[40rpx] text-[26rpx] !text-[#fff] flex-center font-500 !m-0"
style="background: linear-gradient( 94deg, #FB7939 0%, #FE120E 99%), #EF000C;"
@click="applyCashOut">{{ t('cashOut') }}</view>
@click="applyCashOut">提现</view>
</view>
</view>
<view class="mt-[30rpx] bg-[var(--page-bg-color)] tab-style-1">

View File

@ -1,6 +1,6 @@
<template>
<view class="min-h-[100vh] bg-[var(--page-bg-color)] overflow-hidden" :style="themeColor()">
<block v-if="!loading">
<template v-if="!loading">
<view class="sidebar-margin card-template mt-[20rpx] !pt-[60rpx] !pb-[40rpx]">
<!-- <view class="flex flex-col justify-center items-center mb-[44rpx]" v-if="cashOutInfo.status == 4 && cashOutInfo.transfer_type == 'wechatpay'">
<image class="h-[70rpx] w-[70rpx] mb-[24rpx]" :src="img('static/resource/images/member/apply_withdrawal/transfer.png')" mode="widthFix" />
@ -111,7 +111,7 @@
:loading="operateLoading" @click="cashTransfer"
v-else-if="cashOutInfo.transfer_type == 'wechatpay' && cashOutInfo.status == 4">{{ t('cashOutNow') }}</button>
</view>
</block>
</template>
<loading-page :loading="loading"></loading-page>
</view>
</template>
@ -201,7 +201,9 @@ const cashOut = () => {
clearTimeout(timer)
}, 6000)
})
})
}).catch((err:any)=>{
operateLoading.value = false;
})
}
const cashTransfer = () => {

View File

@ -24,6 +24,8 @@
<script setup lang="ts">
import { ref, computed, nextTick } from 'vue';
import { useDiy } from '@/hooks/useDiy'
import { useShare } from '@/hooks/useShare'
import { redirect } from '@/utils/common';
import diyGroup from '@/addon/components/diy/group/index.vue'
import useMemberStore from '@/stores/member'
@ -31,6 +33,7 @@ import useMemberStore from '@/stores/member'
//
const memberStore = useMemberStore()
const userInfo = computed(() => memberStore.info)
const { setShare } = useShare()
const diy = useDiy({
name: 'DIY_MEMBER_INDEX'
@ -53,6 +56,8 @@ diy.onShow((data: any) => {
//
redirect({ url: data.page, mode: 'reLaunch' })
}
let share = data.share ? JSON.parse(data.share) : null;
setShare(share);
diyGroupRef.value?.refresh();
if (userInfo.value) {
useMemberStore().getMemberInfo()

View File

@ -52,13 +52,13 @@
<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">
<template 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-[22rpx] text-[#aaa] mt-[16rpx] truncate" :class="{'!text-[#fff]': levelIndex == (index)}">{{ item.level_name }}</view>
</view>
</block>
</template>
</view>
</scroll-view>
</view>

View File

@ -80,7 +80,7 @@
<view class="mt-[var(--top-m)] sidebar-margin card-template" v-if="pointList.length">
<view class="title">做任务领积分</view>
<block v-for="(item,index) in pointList">
<template 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-[80rpx] w-[80rpx]" :src="img(item.icon||'')" mode="heightFix" />
@ -92,7 +92,7 @@
<button v-if="item.button" class="h-[54rpx] !m-0 rounded-[40rpx] text-[24rpx] flex-center !text-[#fff] primary-btn-bg"
shape="circle" @click="toLink(item.button.wap_redirect)">{{ item.button.text }}</button>
</view>
</block>
</template>
</view>
</template>
<loading-page :loading="loading"></loading-page>

View File

@ -46,7 +46,7 @@
</view>
</view>
<view v-show="item.flag">
<block v-for="(subItem,subIndex) in item.month_data" :key="subItem.id">
<template v-for="(subItem,subIndex) in item.month_data" :key="subItem.id">
<view class="flex items-center ">
<view class="w-[60rpx] h-[60rpx]">
<image v-if="subItem.account_data > 0" :src="img('static/resource/images/member/point/detail/point_add.png')" class="w-[60rpx] h-[60rpx]"/>
@ -60,7 +60,7 @@
<view class="text-[36rpx] font-500 text-[#03B521] price-font" :class="{ '!text-primary' : subItem.account_data > 0 }">{{ subItem.account_data > 0 ? '+' + subItem.account_data : subItem.account_data }}</view>
</view>
</view>
</block>
</template>
</view>
</view>
<mescroll-empty :option="{tip : '暂无积分明细'}" v-if="!pointList.length && loading"></mescroll-empty>

View File

@ -49,7 +49,7 @@
<text class="w-[14.28%] leading-[36rpx] 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">
<template v-for="(item,index) in state.weekCount" :key="index">
<view class="w-[14.28%] flex flex-col justify-center items-center">
<view v-if="filteredDate(item)"
class="w-[74rpx] h-[92rpx] bg-[#f4f4f4] text-[var(--text-color-light6)] box-border py-[10rpx] rounded-[8rpx] flex flex-col items-center"
@ -69,10 +69,10 @@
</view>
<view class="w-[10rpx] h-[10rpx] rounded-[50%] bg-[var(--primary-color)]" v-if="isCurrentDate(item)"></view>
</view>
</block>
</template>
</view>
<view class="flex flex-wrap items-center justify-start" v-else>
<block v-for="(item,index) in state.dataCount">
<template v-for="(item,index) in state.dataCount">
<view class="w-[14.28%] flex flex-col justify-center items-center mb-[30rpx]">
<view v-if="filteredDate(item)"
class="w-[74rpx] h-[92rpx] bg-[#F6FAFF] text-[var(--text-color-light6)] box-border py-[10rpx] rounded-[8rpx] flex flex-col items-center"
@ -91,7 +91,7 @@
</view>
<view class="w-[10rpx] h-[10rpx] rounded-[50%] bg-[var(--primary-color)]" v-if="isCurrentDate(item)"></view>
</view>
</block>
</template>
</view>
<view class="mt-[40rpx] flex justify-center" v-if="state.curMonth + 1 == (new Date().getMonth() + 1) && state.curYear == new Date().getFullYear() ">
<button v-if="!info.is_sign"
@ -137,7 +137,7 @@
</view>
<view class="flex-1 mx-[20rpx]">
<view class="font-400 text-[28rpx] text-[#303133] leading-[38rpx] mb-[10rpx]">连续签到{{ item.continue_sign }}</view>
<view class="flex flex-wrap" v-if="item.gift">
<view class="flex flex-wrap" v-if="item.gift && item.gift.total">
<view class="flex">
<image :src="img(item.gift.total.icon)" class="w-[30rpx] h-[30rpx] flex-shrink-0"/>
<view class="text-[24rpx] ml-[8rpx] text-[#FF9000] leading-[34rpx] max-w-[330rpx]">{{ item.gift.total.text }}</view>
@ -164,9 +164,9 @@
<view class="popup-common">
<view class="title">签到规则</view>
<scroll-view :scroll-y="true" class="px-[30rpx] box-border h-[360rpx] overflow-auto">
<block v-for="(item) in info.rule_explain.split('\n')">
<template v-for="(item) in info.rule_explain.split('\n')">
<view class="text-[28rpx] leading-[40rpx] mb-[20rpx]">{{ item }}</view>
</block>
</template>
</scroll-view>
<view class="btn-wrap">
<button class="primary-btn-bg btn" @click="signPopup = false">知道了</button>
@ -186,14 +186,14 @@
<view class="text-[36rpx] text-[#EF000C] font-500 mb-[10rpx] text-center">{{ signAward.title }}</view>
<view class="text-[24rpx] text-[#333] leading-[34rpx] text-center mb-[60rpx]" v-if="signAward.info">{{ signAward.info }}</view>
<view class="px-[68rpx] mb-[100rpx]">
<block v-for="(item,index) in signAward.awards">
<template 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]" />
<view class="ml-[20rpx] text-[28rpx] text-[#303133] leading-[38rpx]">{{ subItem.text }}</view>
</view>
</template>
</block>
</template>
</view>
<view class="flex justify-center relative z-30">
<view class="w-[370rpx] h-[80rpx] primary-btn-bg font-500 rounded-[100rpx] text-[#ffffff] text-center leading-[80rpx] text-[26rpx]" @click="awardShow = false">我知道了</view>
@ -216,14 +216,14 @@
<view class="text-[36rpx] text-[#303133] font-500 mb-[10rpx] text-center relative z-20">{{ packInfo.title }}</view>
<view class="text-[24rpx] text-[#333] leading-[34rpx] text-center mb-[60rpx]">{{ packInfo.info }}</view>
<view class="px-[68rpx] mb-[100rpx]">
<block v-for="(item,index) in packInfo.awards">
<template v-for="(item,index) in packInfo.awards">
<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]" />
<view class="ml-[20rpx] text-[28rpx] text-[#303133] leading-[38rpx]">{{ subItem.text }}</view>
</view>
</template>
</block>
</template>
</view>
<view class="flex justify-center relative z-30">
<view class="w-[370rpx] h-[80rpx] border-[2rpx] text-[var(--primary-color)] border-solid rounded-[40rpx] border-[var(--primary-color)] text-center flex-center text-[26rpx] box-border" @click="packShow = false">我知道了</view>

View File

@ -1,6 +1,6 @@
<template>
<view :style="themeColor()" class="bg-[var(--page-bg-color)] min-h-[100vh] overflow-hidden">
<block v-if="!loading">
<template v-if="!loading">
<view class="pt-[20rpx] sidebar-margin">
<view class="flex flex-col card-template">
<view class="flex" :class="{'mb-[20rpx]': verifyInfo.value.list.length-1 != index}" v-for="(item,index) in verifyInfo.value.list" :key="index">
@ -9,7 +9,7 @@
<view class="flex flex-col flex-1 ml-[20rpx] py-[4rpx]">
<view class="leading-[40rpx] truncate max-w-[490rpx] text-[28rpx]">{{ item.name }}</view>
<view class="mt-[14rpx] truncate text-[24rpx] text-[var(--text-color-light9)] leading-[28rpx] max-w-[490rpx] " v-if="item.sub_name">{{ item.sub_name }}</view>
<view class="text-[var(--text-color-light6)] text-[26rpx] mt-[20rpx]">x1</view>
<view class="text-[var(--text-color-light6)] text-[26rpx] mt-[20rpx]">x{{item.verify_num}}</view>
</view>
</view>
</view>
@ -47,7 +47,7 @@
</view>
</view>
</block>
</template>
<loading-page :loading="loading"></loading-page>
</view>
</template>

View File

@ -12,7 +12,7 @@
</view>
<mescroll-body ref="mescrollRef" top="88rpx" @init="mescrollInit" :down="{ use: false }" @up="geVerifyRecordFn">
<view class="sidebar-margin pt-[var(--top-m)]" v-if="list.length">
<block v-for="(item,index) in list" :key="item.id">
<template v-for="(item,index) in list" :key="item.id">
<view class="w-full flex flex-col mb-[var(--top-m)] card-template" @click="toLink(item)">
<view class="flex items-center mb-[30rpx] leading-[1] text-[26rpx]">
<view class="nc-iconfont nc-icon-hexiaotaiV6xx !text-[26rpx] pr-[10rpx]"></view>
@ -20,7 +20,7 @@
<text class="ml-[10rpx] max-w-[494rpx]">{{ item.code }}</text>
<text class="text-[#303133] text-[26rpx] font-400 nc-iconfont nc-icon-fuzhiV6xx1 ml-[11rpx]" @click.stop="copy(item.code)"></text>
</view>
<view class="flex flex-1" v-for="(dataItem,dataIndex) in item.value.list" :key="dataIndex">
<view class="flex flex-1 mb-2" v-for="(dataItem,dataIndex) in item.value.list" :key="dataIndex">
<u--image width="130rpx" height="130rpx" :radius="'var(--goods-rounded-big)'" :src="img(dataItem.cover ? dataItem.cover : '')" mode="aspectFill">
<template #error>
<image class="w-[130rpx] h-[130rpx] rounded-[var(--goods-rounded-big)] overflow-hidden" :src="img('static/resource/images/diy/shop_default.jpg')" mode="aspectFill"/>
@ -29,7 +29,7 @@
<view class="flex flex-col flex-1 ml-[20rpx] py-[4rpx]">
<view class="max-w-[490rpx] leading-[1.3] truncate text-[28rpx] text-[#303133]">{{ dataItem.name }}</view>
<view class="mt-[14rpx] truncate text-[24rpx] text-[var(--text-color-light9)] max-w-[490rpx] " v-if="item.sub_name">{{ item.sub_name }}</view>
<view class="text-[24rpx] mt-[10rpx] text-[var(--text-color-light9)]">x1</view>
<view class="text-[24rpx] mt-[10rpx] text-[var(--text-color-light9)]">x{{dataItem.verify_num}}</view>
</view>
</view>
<view class="flex bg-[var(--temp-bg)] py-[20rpx] px-[20rpx] rounded-[12rpx] mt-[20rpx]">
@ -43,7 +43,7 @@
</view>
</view>
</view>
</block>
</template>
</view>
<mescroll-empty v-if="!list.length && loading" :option="{tip : '暂无核销记录'}"></mescroll-empty>
</mescroll-body>

View File

@ -1,6 +1,6 @@
<template>
<view :style="themeColor()" class="bg-[var(--page-bg-color)] min-h-[100vh] overflow-hidden">
<block v-if="!loading && verifyInfo && verifyInfo.value">
<template v-if="!loading && verifyInfo && verifyInfo.value">
<view class="p-[30rpx] bg-[#fff]">
<view class="text-[var(--primary-color)] fixed top-[40rpx] right-[30rpx] flex items-center" @click="redirect({url:'/app/pages/verify/record'})">
<text class="nc-iconfont nc-icon-lishijiluV6xx !text-[28rpx] -mb-[2rpx]"></text>
@ -23,11 +23,17 @@
<image class="w-[150rpx] h-[150rpx] rounded-[var(--goods-rounded-big)]" mode="aspectFill" v-if="item.cover" :src="img(item.cover)"/>
<image class="w-[150rpx] h-[150rpx] rounded-[var(--goods-rounded-big)]" mode="aspectFill" v-else :src="img('addon/tourism/tourism/member/hotel.png')"/>
<view class="flex flex-col flex-1 ml-[20rpx] py-[4rpx]">
<view class="leading-[1]">
<view class="leading-[40rpx] truncate max-w-[490rpx] text-[28rpx]">{{ item.name }}</view>
<view class="mt-[14rpx] truncate text-[24rpx] text-[var(--text-color-light9)] leading-[28rpx] max-w-[490rpx]" v-if="item.sub_name">{{ item.sub_name }}</view>
</view>
<view class="text-[var(--text-color-light6)] text-[28rpx] mt-[20rpx]">x1</view>
<view class="leading-[1]">
<view class="leading-[40rpx] truncate max-w-[490rpx] text-[28rpx]">{{ item.name }}</view>
<view class="mt-[14rpx] truncate text-[24rpx] text-[var(--text-color-light9)] leading-[28rpx] max-w-[490rpx]" v-if="item.sub_name">{{ item.sub_name }}</view>
</view>
<view class="flex items-center mt-[20rpx]">
<view class="text-[var(--text-color-light6)] text-[28rpx] ">x{{item.verify_num }}</view>
<view class="leading-[1] ml-3 text-[var(--price-text-color)] text-[28rpx]">
{{item.un_use_msg}}
</view>
</view>
</view>
</view>
</view>
@ -52,9 +58,10 @@
<text class="text-[28rpx] text-[#333]">{{ subItem.value }}</text>
</view>
</view>
<view class="common-tab-bar w-[100%]"></view>
<view class="verify-tab-bar fixed flex-center !text-[26rpx] rounded-[50rpx] h-[80rpx] left-[20rpx] right-[20rpx] text-[#fff] font-500" :class="verifyInfo.is_can_use ? 'primary-btn-bg' : 'bg-[#ccc]'" @click="verifyFn">确定</view>
<view class="fixed bottom-[30rpx] primary-btn-bg text-[#fff] flex-center !text-[26rpx] rounded-[50rpx] h-[80rpx] left-[20rpx] right-[20rpx] font-500" @click="verifyFn">确定</view>
</block>
</template>
<loading-page :loading="loading"></loading-page>
</view>
</template>
@ -129,6 +136,7 @@ const getVerifierInfoFn = () => {
}
let isLoading = false;
const verifyFn = () => {
if (!verifyInfo.value.is_can_use) return;
if (isLoading) return false;
isLoading = true;
@ -148,4 +156,8 @@ const verifyFn = () => {
</script>
<style lang="scss" scoped>
.verify-tab-bar{
bottom: calc(constant(safe-area-inset-bottom) + 30rpx);
bottom: calc(env(safe-area-inset-bottom) + 30rpx);
}
</style>

View File

@ -154,46 +154,48 @@ const getPhoneNumber = (e: any) => {
}
}
const confirm = async() => {
formRef.value.validate().then(async() => {
if (loading.value) return
loading.value = true
const confirm = async () => {
formRef.value.validate().then(async () => {
if (loading.value) return;
loading.value = true;
if (info.value) {
//
await modifyMember({ field: 'headimg', value: formData.headimg }).then(() => {
memberStore.info.headimg = formData.headimg
}).catch(() => {
loading.value = false
})
if (!loading.value) return
try {
if (info.value) {
//
await modifyMember({ field: 'headimg', value: formData.headimg });
memberStore.info.headimg = formData.headimg;
//
modifyMember({ field: 'nickname', value: formData.nickname }).then(() => {
memberStore.info.nickname = formData.nickname
loading.value = false
show.value = false
}).catch(() => {
loading.value = false
})
//
await modifyMember({ field: 'nickname', value: formData.nickname });
memberStore.info.nickname = formData.nickname;
// #ifdef MP-WEIXIN
const login = useLogin()
if (info.value && !info.value.weapp_openid) {
login.getAuthCode({ updateFlag: true }) // openid
// openid
if (info.value && !info.value.weapp_openid) {
const login = useLogin();
await login.getAuthCode({ updateFlag: true }); // openid
}
//
show.value = false;
} else {
// todo
// #ifdef MP-WEIXIN
const login = useLogin();
await login.getAuthCode({ backFlag: true, ...formData }); //
show.value = false;
// #endif
}
// #endif
} else {
// todo
// #ifdef MP-WEIXIN
const login = useLogin()
login.getAuthCode({ backFlag: true, ...formData }) //
// #endif
} catch (error) {
//
console.error("发生错误:", error);
} finally {
loading.value = false; // loading
}
})
}
const checkAuth = (e, type) => {
// #ifdef MP-WEIXIN
wx.getUserInfo({

View File

@ -1,5 +1,6 @@
<template>
<view
v-if="wxsProp"
class="mescroll-body mescroll-render-touch"
:class="{'mescorll-sticky': sticky}"
:style="{'minHeight':minHeight, 'padding-top': padTop, 'padding-bottom': padBottom}"

View File

@ -14,13 +14,13 @@
<view class="text-right flex-1 pl-[30rpx] truncate">{{ payInfo.body }}</view>
</view>
<view class="mx-[var(--popup-sidebar-m)] px-[30rpx] bg-white rounded-[20rpx] bg-[var(--temp-bg)]">
<block v-if="payInfo.pay_type_list.length">
<template v-if="payInfo.pay_type_list.length">
<view class="pay-item py-[30rpx] flex items-center border-0 border-b border-solid border-[#eee]" v-for="(item, index) in payInfo.pay_type_list" :key="index" @click="type = item.key">
<u-image :src="img(item.icon)" width="50rpx" height="50rpx"></u-image>
<view class="flex-1 px-[20rpx] text-[28rpx] font-500">{{ item.name }}</view>
<u-icon name="checkbox-mark" color="var(--primary-color)" v-if="item.key == type"></u-icon>
</view>
</block>
</template>
<view class="py-[30rpx] text-center text-[24rpx] text-gray-subtitle" v-else>{{ t('pay.notHavePayType') }}</view>
</view>
</scroll-view>

View File

@ -1,11 +1,11 @@
<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" :border="props.border" class="custom-tabbar">
<block v-for="item in tabbar.value.list">
<template v-for="item in tabbar.value.list">
<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]" :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]" :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>
</template>
</u-tabbar>
<view class="tab-bar-placeholder"></view>
</template>

View File

@ -1,15 +1,17 @@
<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 @touchmove.prevent.stop>
<u-popup :show="showPop" type="bottom" @close="disPopUp">
<view>
<view class="p-[30rpx]">
<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>
</u-popup>
</view>
</template>
@ -183,18 +185,18 @@ defineExpose({
}
.privacy-title {
padding: 0rpx 30rpx 40rpx 30rpx;
padding: 10rpx 40rpx;
font-weight: 700;
font-size: 36rpx;
text-align: center;
font-size: 30rpx;
// text-align: center;
}
.privacy-desc {
font-size: 30rpx;
font-size: 28rpx;
color: #555;
line-height: 2;
line-height: 1.5;
text-align: left;
padding: 0 40rpx;
padding: 15rpx 40rpx;
}
.privacy-link {
@ -203,17 +205,17 @@ defineExpose({
.privacy-button-flex {
display: flex;
padding: 20rpx 40rpx;
padding: 20rpx 100rpx;
}
.privacy-button-btn {
color: #FFF;
font-size: 30rpx;
font-weight: 500;
line-height: 100rpx;
line-height: 80rpx;
text-align: center;
height: 100rpx;
border-radius: 20rpx;
height: 80rpx;
border-radius: 10rpx;
border: none;
background: #07c160;
flex: 1;

View File

@ -144,7 +144,7 @@ export function useDiyForm(params: any = {}) {
let diyFormStorage = uni.getStorageSync('diyFormStorage_' + diyStore.id)
if (diyFormStorage) {
var date = new Date();
let currentTime: any = parseInt(date.getTime() / 1000); // 定位信息 5分钟内有效过期后将重新获取定位信息
let currentTime: any = parseInt(date.getTime() / 1000); // 存储信息 5分钟内有效过期后将重新获取定位信息
if (diyFormStorage.validTime > currentTime) {
if (diyFormStorage.components) {
diyFormStorage.components.forEach((item: any) => {

View File

@ -323,7 +323,8 @@ export function useLogin() {
scopes: params.scopes
}).then((res: any) => {
uni.setStorageSync('wechat_login_back', true) // 微信公众号手动授权登录回调标识
location.href = res.data.url
location.replace(res.data.url);
// location.href = res.data.url
})
// #endif

View File

@ -8,10 +8,21 @@ const t = (message: string) => {
route = getCurrentInstance()?.appContext.config.globalProperties.$route.path || ('/' + useSystemStore().currRoute)
// #endif
// #ifdef MP
route = '/' + (getCurrentInstance()?.root.ctx.$scope.__route__ || useSystemStore().currRoute)
let _route = getCurrentInstance()?.root.ctx.$scope.__route__;
if(_route == 'app/pages/index/tabbar'){
route = useSystemStore().currRoute
}else{
route = '/' + getCurrentInstance()?.root.ctx.$scope.__route__
}
// #endif
// console.log('vgetCurrentInstance()?.root.ctx.$scope.__route__',getCurrentInstance()?.root.ctx.$scope.__route__,useSystemStore().currRoute)
// console.log('route',route)
const file = language.getFileKey(route)
// console.log('file',file)
const key = `${ file.fileKey }.${ message }`
// console.log('key',key)
// console.log('i18n.global.t(key)',i18n.global.t(key))
// console.log('i18n.global.t(message)',i18n.global.t(message))
if (i18n.global.t(message) != message) return i18n.global.t(message)
return i18n.global.t(key) != key ? i18n.global.t(key) : ''
}

View File

@ -41,139 +41,5 @@
"pages.verify.record": "核销记录",
"pages.friendspay.share": "找朋友帮忙付",
"pages.friendspay.money": "",
"pages.webview.index": "",
"tourism.pages.way.list": "线路列表",
"tourism.pages.way.detail": "线路详情",
"tourism.pages.way.order": "线路订单",
"tourism.pages.hotel.list": "酒店列表",
"tourism.pages.hotel.detail": "酒店详情",
"tourism.pages.hotel.order": "酒店订单",
"tourism.pages.scenic.list": "景点列表",
"tourism.pages.scenic.detail": "景点详情",
"tourism.pages.scenic.order": "景点订单",
"tourism.pages.order.list": "旅游订单",
"tourism.pages.order.detail": "订单详情",
"tourism.pages.verify.index": "核销",
"tourism.pages.verify.record": "核销记录",
"tourism.pages.verify.detail": "核销详情",
"vipcard.pages.verify.index": "核销",
"vipcard.pages.verify.record": "核销记录",
"vipcard.pages.verify.detail": "核销详情",
"vipcard.pages.order.payment": "订单结算",
"vipcard.pages.order.list": "订单列表",
"vipcard.pages.order.my_reserved": "我的预约",
"vipcard.pages.order.my_reserved_detail": "我的预约详情",
"vipcard.pages.order.my_card": "我的卡项",
"vipcard.pages.order.detail": "订单详情",
"vipcard.pages.service.list": "项目列表",
"vipcard.pages.card.list": "卡项列表",
"vipcard.pages.card.detail": "卡项详情",
"recharge.pages.recharge": "充值",
"recharge.pages.recharge_record": "充值记录",
"recharge.pages.recharge_record_detail": "充值记录详情",
"shop.pages.goods.search": "搜索",
"shop.pages.goods.cart": "购物车",
"shop.pages.goods.collect": "商品收藏",
"shop.pages.goods.browse": "我的足迹",
"shop.pages.goods.category": "商品分类",
"shop.pages.goods.detail": "商品详情",
"shop.pages.goods.list": "商品列表",
"shop.pages.goods.rank": "排行榜",
"shop.pages.member.index": "个人中心",
"shop.pages.member.my_coupon": "我的优惠券",
"shop.pages.order.list": "订单列表",
"shop.pages.order.detail": "订单详情",
"shop.pages.order.payment": "待付款订单",
"shop.pages.evaluate.order_evaluate": "商品评价",
"shop.pages.evaluate.order_evaluate_view": "商品评价",
"shop.pages.evaluate.list": "评价列表",
"shop.pages.coupon.list": "优惠券列表",
"shop.pages.coupon.detail": "优惠券详情",
"shop.pages.discount.list": "限时折扣",
"shop.pages.refund.list": "退款列表",
"shop.pages.refund.detail": "退款详情",
"shop.pages.refund.apply": "申请退款",
"shop.pages.refund.edit_apply": "编辑退款信息",
"shop.pages.refund.log": "协商记录",
"shop.pages.point.index": "积分商城",
"shop.pages.point.list": "积分商品列表",
"shop.pages.point.detail": "积分商品详情",
"shop.pages.point.payment": "待付款订单",
"shop.pages.point.order_list": "积分兑换记录",
"shop.pages.newcomer.list": "新人专享",
"cms.pages.list": "资讯中心",
"cms.pages.detail": "文章详情",
"shop_fenxiao.pages.index": "分销中心",
"shop_fenxiao.pages.zone": "分销专区",
"shop_fenxiao.pages.level": "分销商等级",
"shop_fenxiao.pages.child_fenxiao": "分销商",
"shop_fenxiao.pages.goods": "分销商品",
"shop_fenxiao.pages.team": "我的团队",
"shop_fenxiao.pages.ranking_list": "排行榜",
"shop_fenxiao.pages.agent_list": "渠道代理",
"shop_fenxiao.pages.bill": "账单",
"shop_fenxiao.pages.order": "分销订单",
"shop_fenxiao.pages.order_detail": "订单详情",
"shop_fenxiao.pages.apply": "分销商申请",
"shop_fenxiao.pages.task_rewards": "任务奖励",
"shop_fenxiao.pages.task_detail": "任务奖励详情",
"shop_fenxiao.pages.task_rewards_detail": "任务奖励明细",
"shop_fenxiao.pages.sale": "销售奖励",
"shop_fenxiao.pages.sale_detail": "销售奖励详情",
"shop_fenxiao.pages.sale_ranking": "销售奖励排行榜",
"shop_fenxiao.pages.promote_code": "分享海报",
"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.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":"话题列表"
"pages.webview.index": ""
}

View File

@ -289,12 +289,17 @@ export function isUrl(str: string): boolean {
*/
export function img(path: string): string {
// #ifdef H5
return isUrl(path) ? path : `${ import.meta.env.VITE_IMG_DOMAIN || location.origin }/${ path }`
let imgDomain = import.meta.env.VITE_IMG_DOMAIN || location.origin
// #endif
// #ifndef H5
return isUrl(path) ? path : `${ import.meta.env.VITE_IMG_DOMAIN }/${ path }`
let imgDomain = import.meta.env.VITE_IMG_DOMAIN
// #endif
if (typeof path == 'string' && path.startsWith('/')) path = path.replace(/^\//, '')
if (typeof imgDomain == 'string' && imgDomain.endsWith('/')) imgDomain = imgDomain.slice(0, -1)
return isUrl(path) ? path : `${imgDomain}/${path}`
}
/**
@ -628,21 +633,20 @@ export function setThemeColor (path: string) {
let currTheme = {};
if (route != 'app') {
try {
currTheme = theme_color_list[route];
if (currTheme && currTheme.theme) {
configStore.themeColor = themeColorToHex(currTheme.theme)
uni.setStorageSync("current_theme_color", JSON.stringify(themeColorToHex(currTheme.theme)))
} else if (!currTheme && current_theme_color) {
configStore.themeColor = ""
} else {
currTheme = theme_color_list.app || Object.values(theme_color_list)[0]
configStore.themeColor = themeColorToHex(currTheme.theme)
uni.setStorageSync("current_theme_color", JSON.stringify(themeColorToHex(currTheme.theme)))
}
currTheme = theme_color_list[route];
if(currTheme && currTheme.theme){
configStore.themeColor = themeColorToHex(currTheme.theme)
uni.setStorageSync('current_theme_color', JSON.stringify(themeColorToHex(currTheme.theme)));
}else if( !currTheme && current_theme_color){
configStore.themeColor = ''
}else{
currTheme = theme_color_list.app || Object.values(theme_color_list)[0];
configStore.themeColor = themeColorToHex(currTheme.theme)
uni.setStorageSync('current_theme_color', JSON.stringify(themeColorToHex(currTheme.theme)));
}
} catch (e) {
// 设置插件应用的主色调发生错误,若不存在则使用最后有效的主色调
if(!current_theme_color && theme_color_list && theme_color_list.length>0){
if(!current_theme_color && theme_color_list && theme_color_list.length>0){
currTheme = theme_color_list.app || Object.values(theme_color_list)[0];
configStore.themeColor = themeColorToHex(currTheme.theme)
uni.setStorageSync('current_theme_color', JSON.stringify(themeColorToHex(currTheme.theme)));
@ -651,7 +655,7 @@ export function setThemeColor (path: string) {
}
}
}else if (!current_theme_color && theme_color_list && theme_color_list.length > 0) {
}else if (!current_theme_color && theme_color_list && theme_color_list.length>0) {
currTheme = theme_color_list.app || Object.values(theme_color_list)[0]
configStore.themeColor = themeColorToHex(currTheme.theme)
uni.setStorageSync("current_theme_color", JSON.stringify(themeColorToHex(currTheme.theme)))

View File

@ -12,9 +12,11 @@ export function getNeedLoginPages() {
// 获取分包中需要登录的页面
if (pagesJson.subPackages) {
pagesJson.subPackages.forEach(subPackages => {
subPackages.pages.forEach(item => {
if (item.needLogin) pages.push(`/${ subPackages.root }/${ item.path }`)
})
if(subPackages.pages) {
subPackages.pages.forEach(item => {
if (item.needLogin) pages.push(`/${ subPackages.root }/${ item.path }`)
})
}
})
}
return pages
@ -37,9 +39,11 @@ export function getSubPackagesPages() {
// 获取分包中需要登录的页面
if (pagesJson.subPackages) {
pagesJson.subPackages.forEach(subPackages => {
subPackages.pages.forEach(item => {
pages.push(`/${ subPackages.root }/${ item.path }`)
})
if(subPackages.pages) {
subPackages.pages.forEach(item => {
pages.push(`/${ subPackages.root }/${ item.path }`)
})
}
})
}
return pages
@ -60,3 +64,29 @@ export function getTabbarPages() {
export function getFirstPage() {
return '/' + pagesJson.pages[0].path
}
/**
* navbar的页面
*/
export function getCustomNavigationPages() {
const pages: any = {}
// 获取主包中的
pagesJson.pages.forEach(item => {
if (item.style && item.style.navigationStyle && item.style.navigationStyle == 'custom') {
pages[`/${ item.path }`] = item
}
})
// 获取分包中的
if (pagesJson.subPackages) {
pagesJson.subPackages.forEach(subPackages => {
if(subPackages.pages) {
subPackages.pages.forEach(item => {
if (item.style && item.style.navigationStyle && item.style.navigationStyle == 'custom') {
pages[`/${ subPackages.root }/${ item.path }`] = item
}
})
}
})
}
return pages
}