mirror of
https://gitee.com/niucloud-team/niucloud.git
synced 2026-03-17 11:13:42 +00:00
up
This commit is contained in:
parent
982213b49a
commit
f65e2d1ff8
@ -1,7 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onLaunch, onShow, onHide } from '@dcloudio/uni-app'
|
import { onLaunch, onShow, onHide } from '@dcloudio/uni-app'
|
||||||
import { launchInterceptor } from '@/utils/interceptor'
|
import { launchInterceptor } from '@/utils/interceptor'
|
||||||
import { getToken, isWeixinBrowser, getSiteId, currRoute, deepClone } from '@/utils/common'
|
import { getToken, isWeixinBrowser, getSiteId, currRoute, deepClone, setThemeColor } from '@/utils/common'
|
||||||
import useMemberStore from '@/stores/member'
|
import useMemberStore from '@/stores/member'
|
||||||
import useConfigStore from '@/stores/config'
|
import useConfigStore from '@/stores/config'
|
||||||
import useSystemStore from '@/stores/system'
|
import useSystemStore from '@/stores/system'
|
||||||
@ -47,6 +47,12 @@
|
|||||||
// 缺少站点id,拦截
|
// 缺少站点id,拦截
|
||||||
if (process.env.NODE_ENV == 'development' && (getSiteId(uni.getStorageSync('wap_site_id') || import.meta.env.VITE_SITE_ID) === '')) return;
|
if (process.env.NODE_ENV == 'development' && (getSiteId(uni.getStorageSync('wap_site_id') || import.meta.env.VITE_SITE_ID) === '')) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
uni.hideTabBar() // 隐藏tabbar
|
||||||
|
} catch (e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
const { wechatInit } = useShare()
|
const { wechatInit } = useShare()
|
||||||
wechatInit()
|
wechatInit()
|
||||||
// #endif
|
// #endif
|
||||||
@ -85,8 +91,11 @@
|
|||||||
loginConfig = deepClone(configStore.login)
|
loginConfig = deepClone(configStore.login)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断在登录注册页面账号锁定后不进行请求三方登录注册
|
|
||||||
let url: any = currRoute()
|
let url: any = currRoute()
|
||||||
|
// 设置主色调
|
||||||
|
setThemeColor(url)
|
||||||
|
|
||||||
|
// 判断在登录注册页面账号锁定后不进行请求三方登录注册
|
||||||
if ((['app/pages/auth/index', 'app/pages/auth/login', 'app/pages/auth/register', 'app/pages/auth/resetpwd'].indexOf(url) != -1) &&
|
if ((['app/pages/auth/index', 'app/pages/auth/login', 'app/pages/auth/register', 'app/pages/auth/resetpwd'].indexOf(url) != -1) &&
|
||||||
(loginConfig.is_username || loginConfig.is_mobile || loginConfig.is_bind_mobile)) {
|
(loginConfig.is_username || loginConfig.is_mobile || loginConfig.is_bind_mobile)) {
|
||||||
return false
|
return false
|
||||||
@ -168,6 +177,7 @@
|
|||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
if (isWeixinBrowser()) {
|
if (isWeixinBrowser()) {
|
||||||
if (uni.getStorageSync('autoLoginLock') && !uni.getStorageSync('wechat_login_back')) return;
|
if (uni.getStorageSync('autoLoginLock') && !uni.getStorageSync('wechat_login_back')) return;
|
||||||
|
// 开启自动注册的情况下才能执行
|
||||||
if (loginConfig.is_auth_register || uni.getStorageSync('wechat_login_back')) {
|
if (loginConfig.is_auth_register || uni.getStorageSync('wechat_login_back')) {
|
||||||
uni.removeStorageSync('wechat_login_back') // 删除微信公众号手动授权登录回调标识
|
uni.removeStorageSync('wechat_login_back') // 删除微信公众号手动授权登录回调标识
|
||||||
if (data.query.code) {
|
if (data.query.code) {
|
||||||
|
|||||||
@ -82,6 +82,7 @@ export function wechatLogin(data : AnyObject) {
|
|||||||
}
|
}
|
||||||
return request.post('wechat/login', data, { showErrorMessage: false })
|
return request.post('wechat/login', data, { showErrorMessage: false })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信公众号号修改openid
|
* 微信公众号号修改openid
|
||||||
*/
|
*/
|
||||||
@ -105,6 +106,7 @@ export function weappLogin(data : AnyObject) {
|
|||||||
export function updateWeappOpenid(data: AnyObject) {
|
export function updateWeappOpenid(data: AnyObject) {
|
||||||
return request.put('weapp/update_openid', data, { showErrorMessage: false })
|
return request.put('weapp/update_openid', data, { showErrorMessage: false })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绑定手机号
|
* 绑定手机号
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -7,13 +7,6 @@ export function getDiyInfo(params: Record<string, any>) {
|
|||||||
return request.get('diy/diy', params)
|
return request.get('diy/diy', params)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取自定义表单信息
|
|
||||||
*/
|
|
||||||
export function getDiyFormInfo(form_id:number) {
|
|
||||||
return request.get(`diy/form/${form_id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取底部导航列表
|
* 获取底部导航列表
|
||||||
*/
|
*/
|
||||||
@ -27,10 +20,3 @@ export function getTabbarList(params: Record<string, any>) {
|
|||||||
export function getShareInfo(params: Record<string, any>) {
|
export function getShareInfo(params: Record<string, any>) {
|
||||||
return request.get('diy/share', params)
|
return request.get('diy/share', params)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 提交表单数据
|
|
||||||
*/
|
|
||||||
export function recordsForm(params: Record<string, any>) {
|
|
||||||
return request.post('diy/form/records', params)
|
|
||||||
}
|
|
||||||
29
uni-app/src/app/api/diy_form.ts
Normal file
29
uni-app/src/app/api/diy_form.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取自定义表单信息
|
||||||
|
*/
|
||||||
|
export function getDiyFormInfo(params: Record<string, any>) {
|
||||||
|
return request.get(`diy/form`,params)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提交表单数据
|
||||||
|
*/
|
||||||
|
export function addFormRecord(params: Record<string, any>) {
|
||||||
|
return request.post('diy/form/record', params)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取表单填写结果信息
|
||||||
|
*/
|
||||||
|
export function getFormResultInfo(params: Record<string, any>) {
|
||||||
|
return request.get('diy/form/result', params)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取表单填写记录
|
||||||
|
*/
|
||||||
|
export function getFormRecord(params: Record<string, any>) {
|
||||||
|
return request.get(`diy/form/record`,params)
|
||||||
|
}
|
||||||
@ -56,6 +56,16 @@ export function bindMobile(data: AnyObject) {
|
|||||||
return request.put('member/mobile', data, { showErrorMessage: true })
|
return request.put('member/mobile', data, { showErrorMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取手机号
|
||||||
|
*/
|
||||||
|
export function getMobile(data: AnyObject) {
|
||||||
|
if (uni.getStorageSync('pid')) {
|
||||||
|
data.pid = uni.getStorageSync('pid');
|
||||||
|
}
|
||||||
|
return request.put('member/getmobile', data, { showErrorMessage: true })
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提现转账方式
|
* 提现转账方式
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -70,6 +70,12 @@ export function fetchBase64Image(data: AnyObject) {
|
|||||||
return request.post('file/image/base64', data)
|
return request.post('file/image/base64', data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传视频
|
||||||
|
*/
|
||||||
|
export function uploadVideo(data: AnyObject) {
|
||||||
|
return request.upload('file/video', data, { showErrorMessage: true })
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 获取站点信息
|
* 获取站点信息
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -118,7 +118,7 @@
|
|||||||
import useDiyStore from '@/app/stores/diy';
|
import useDiyStore from '@/app/stores/diy';
|
||||||
import { img } from '@/utils/common';
|
import { img } from '@/utils/common';
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
const props = defineProps(['component', 'index']);
|
||||||
|
|
||||||
const diyStore = useDiyStore();
|
const diyStore = useDiyStore();
|
||||||
|
|
||||||
@ -209,7 +209,7 @@
|
|||||||
if (diyComponent.value.topElementRounded) style += 'border-top-right-radius:' + diyComponent.value.topElementRounded * 2 + 'rpx;';
|
if (diyComponent.value.topElementRounded) style += 'border-top-right-radius:' + diyComponent.value.topElementRounded * 2 + 'rpx;';
|
||||||
if (diyComponent.value.bottomElementRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomElementRounded * 2 + 'rpx;';
|
if (diyComponent.value.bottomElementRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomElementRounded * 2 + 'rpx;';
|
||||||
if (diyComponent.value.bottomElementRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomElementRounded * 2 + 'rpx;';
|
if (diyComponent.value.bottomElementRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomElementRounded * 2 + 'rpx;';
|
||||||
style += 'overflow: hidden';
|
style += 'overflow: hidden;';
|
||||||
return style;
|
return style;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,13 +219,6 @@
|
|||||||
return style;
|
return style;
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.pullDownRefreshCount,
|
|
||||||
(newValue, oldValue) => {
|
|
||||||
// 处理下拉刷新业务
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
refresh();
|
refresh();
|
||||||
// 装修模式下刷新
|
// 装修模式下刷新
|
||||||
|
|||||||
@ -149,7 +149,7 @@
|
|||||||
const systemInfo = uni.getSystemInfoSync();
|
const systemInfo = uni.getSystemInfoSync();
|
||||||
|
|
||||||
const instance = getCurrentInstance();
|
const instance = getCurrentInstance();
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount', 'global', 'scrollBool']);
|
const props = defineProps(['component', 'index', 'global', 'scrollBool']);
|
||||||
const diyStore = useDiyStore();
|
const diyStore = useDiyStore();
|
||||||
const diyComponent = computed(() => {
|
const diyComponent = computed(() => {
|
||||||
if (diyStore.mode == 'decorate') {
|
if (diyStore.mode == 'decorate') {
|
||||||
@ -183,14 +183,6 @@
|
|||||||
return style;
|
return style;
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.pullDownRefreshCount,
|
|
||||||
(newValue, oldValue) => {
|
|
||||||
// 处理下拉刷新业务
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const moduleHeight:any = ref('')
|
const moduleHeight:any = ref('')
|
||||||
const setModuleLocation = ()=> {
|
const setModuleLocation = ()=> {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
|
|||||||
@ -32,7 +32,7 @@
|
|||||||
import useDiyStore from '@/app/stores/diy';
|
import useDiyStore from '@/app/stores/diy';
|
||||||
import { img } from '@/utils/common';
|
import { img } from '@/utils/common';
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
const props = defineProps(['component', 'index']);
|
||||||
|
|
||||||
const diyStore = useDiyStore();
|
const diyStore = useDiyStore();
|
||||||
|
|
||||||
@ -113,12 +113,6 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.pullDownRefreshCount,
|
|
||||||
(newValue, oldValue) => {
|
|
||||||
// 处理下拉刷新业务
|
|
||||||
}
|
|
||||||
)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
96
uni-app/src/app/components/diy/form-address/index.vue
Normal file
96
uni-app/src/app/components/diy/form-address/index.vue
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<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>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// 表单 地址组件
|
||||||
|
import { ref, computed, watch,onMounted } from 'vue';
|
||||||
|
import { img } from '@/utils/common';
|
||||||
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
|
||||||
|
const props = defineProps(['component', 'index','global']);
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
|
||||||
|
const diyComponent = computed(() => {
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return diyStore.value[props.index];
|
||||||
|
} else {
|
||||||
|
return props.component;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
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 + ';';
|
||||||
|
}
|
||||||
|
|
||||||
|
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;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
refresh();
|
||||||
|
// 装修模式下刷新
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
watch(
|
||||||
|
() => diyComponent.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue && newValue.componentName == 'FormAddress') {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}else{
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const refresh = ()=> {
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单组件验证
|
||||||
|
const verify = () => {
|
||||||
|
const res = { code: true, message: '' }
|
||||||
|
// todo 验证组件,diyComponent.value.field.value
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单组件数据
|
||||||
|
const reset = () => {
|
||||||
|
// todo 清空组件数据,diyComponent.value.field.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
verify,
|
||||||
|
reset
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
.text-overflow-ellipsis {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
324
uni-app/src/app/components/diy/form-checkbox/index.vue
Normal file
324
uni-app/src/app/components/diy/form-checkbox/index.vue
Normal file
@ -0,0 +1,324 @@
|
|||||||
|
<template>
|
||||||
|
<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">
|
||||||
|
<view class="detail-one-content-label">{{ diyComponent.field.name }}</view>
|
||||||
|
<view class="flex detail-one-content-value">
|
||||||
|
<view class="" v-for="(item,index) in diyComponent.field.value" :key="index" >{{ item.text}}<text v-if="index !== diyComponent.field.value.length - 1">、</text></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="base-layout-two" v-if="diyGlobal.completeLayout == 'style-2'">
|
||||||
|
<view class="detail-two-content">
|
||||||
|
<view class="detail-two-content-label">{{ diyComponent.field.name }}</view>
|
||||||
|
<view class="detail-two-content-value flex w-[80%] justify-end">
|
||||||
|
<view class="" v-for="(item,index) in diyComponent.field.value" :key="index" >{{ item.text}}<text v-if="index !== diyComponent.field.value.length - 1">、</text></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="name" :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">已隐藏</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="layout-one-content" v-if="diyComponent.style == 'style-1'">
|
||||||
|
<u-checkbox-group v-model="selectValue" @change="checkboxChange" iconPlacement="left">
|
||||||
|
<view v-for="(item, index) in diyComponent.options" :key="index" class="mr-[40rpx]">
|
||||||
|
<u-checkbox activeColor="var(--primary-color)" :labelSize="(diyComponent.fontSize * 2) + 'rpx'" :labelColor="diyComponent.textColor" :label="item.text" :name="item.id"></u-checkbox>
|
||||||
|
</view>
|
||||||
|
</u-checkbox-group>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<u-checkbox-group v-if="diyComponent.style == 'style-2'" v-model="selectValue" @change="checkboxChange" iconPlacement="left" placement="column">
|
||||||
|
<view v-for="(item, index) in diyComponent.options" :key="index" @click="selectRadio(item)" class="layout-one-content mb-[16rpx]" :class="{'!mb-[0]': (diyComponent.options.length-1) == index}">
|
||||||
|
<u-checkbox class="!m-[0]" activeColor="var(--primary-color)" :labelSize="(diyComponent.fontSize * 2) + 'rpx'" :labelColor="diyComponent.textColor" :label="item.text" :name="item.id"></u-checkbox>
|
||||||
|
</view>
|
||||||
|
</u-checkbox-group>
|
||||||
|
|
||||||
|
<view v-if="diyComponent.style == 'style-3'" @click="openPicker" class="layout-one-content justify-between">
|
||||||
|
<view v-if="diyComponent.field.value && diyComponent.field.value.length">
|
||||||
|
<text class="mr-[10rpx] text-[28rpx]" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}" v-for="(item,index) in diyComponent.field.value">{{item.text}}<text v-if="index !== diyComponent.field.value.length - 1">,</text></text>
|
||||||
|
</view>
|
||||||
|
<text v-else class="text-[28rpx] text-[#999]" :style="{'font-size': (diyComponent.fontSize * 2) + 'rpx'}">{{checkboxPlaceholder}}</text>
|
||||||
|
<text class="nc-iconfont nc-icon-xiaV6xx pull-down-arrow text-[#666]" :class="{'selected': selectShow}" :style="{'font-size': (diyComponent.fontSize * 2+2) + 'rpx !important'}"></text>
|
||||||
|
</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">已隐藏</text>
|
||||||
|
<view class="layout-two-wrap" :class="{'!pb-[20rpx]': ((diyComponent.style == 'style-2' || diyComponent.style == 'style-3') && diyGlobal.borderControl),'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" v-if= "diyComponent.style == 'style-1'">
|
||||||
|
<u-checkbox-group v-model="selectValue" @change="checkboxChange" iconPlacement="left" class="justify-end">
|
||||||
|
<view v-for="(item, index) in diyComponent.options" class="ml-[30rpx]">
|
||||||
|
<u-checkbox activeColor="var(--primary-color)" :labelSize="(diyComponent.fontSize * 2) + 'rpx'" :labelColor="diyComponent.textColor" :key="index" :label="item.text" :name="item.id"></u-checkbox>
|
||||||
|
</view>
|
||||||
|
</u-checkbox-group>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="layout-two-content" v-if="diyComponent.style == 'style-2'">
|
||||||
|
<view class="justify-end w-full">
|
||||||
|
<u-checkbox-group v-model="selectValue" placement="column" @change="checkboxChange" iconPlacement="left">
|
||||||
|
<view v-for="(item, index) in diyComponent.options" :key="index" @click="selectRadio(item)" class="border-solid border-[2rpx] border-[#e6e6e6] rounded-[10rpx] flex items-center h-[80rpx] mb-[16rpx] px-[16rpx] box-border" :class="{'mb-[0]': diyComponent.options.length == (index+1)}">
|
||||||
|
<u-checkbox activeColor="var(--primary-color)" :labelSize="(diyComponent.fontSize * 2) + 'rpx'" :labelColor="diyComponent.textColor" class="!m-[0]" :label="item.text" :name="item.id"></u-checkbox>
|
||||||
|
</view>
|
||||||
|
</u-checkbox-group>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="layout-two-content" v-if= "diyComponent.style == 'style-3'">
|
||||||
|
<view @click="openPicker" class="px-[16rpx] box-border h-[80rpx] flex items-center justify-between border-solid border-[2rpx] border-[#e6e6e6] rounded-[10rpx] w-[100%]">
|
||||||
|
<view v-if="diyComponent.field.value && diyComponent.field.value.length">
|
||||||
|
<text class="mr-[10rpx] text-[28rpx]" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}" v-for="(item,index) in diyComponent.field.value">{{item.text}}<text v-if="index !== diyComponent.field.value.length - 1">,</text></text>
|
||||||
|
</view>
|
||||||
|
<text v-else class="text-[28rpx] text-[#999]" :style="{'font-size': (diyComponent.fontSize * 2) + 'rpx'}">{{checkboxPlaceholder}}</text>
|
||||||
|
<text class="nc-iconfont nc-icon-xiaV6xx pull-down-arrow text-[#666]" :class="{'selected': selectShow}" :style="{'font-size': (diyComponent.fontSize * 2+2) + 'rpx !important'}"></text>
|
||||||
|
</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>
|
||||||
|
<!-- 样式三,下拉弹窗 -->
|
||||||
|
<u-popup :show="selectShow" mode="bottom" @close="selectShow=false" >
|
||||||
|
<view class="p-[15rpx]">
|
||||||
|
<scroll-view scroll-y="true" class="max-h-[450rpx] px-[14rpx] box-border">
|
||||||
|
<u-checkbox-group v-model="pullDownVal" placement="column" iconPlacement="right">
|
||||||
|
<view v-for="(item, index) in diyComponent.options" :key="index" class="border-solid border-[0] border-b-[2rpx] border-[#e6e6e6] py-[20rpx]">
|
||||||
|
<u-checkbox activeColor="var(--primary-color)" :labelSize="'30rpx'" labelColor="#333" :style="{'width': '100%'}" :label="item.text" :name="item.id"></u-checkbox>
|
||||||
|
</view>
|
||||||
|
</u-checkbox-group>
|
||||||
|
</scroll-view>
|
||||||
|
|
||||||
|
<view class="flex items-center pt-[20rpx]">
|
||||||
|
<view @click="pullDownCancelFn" class="flex-1 flex justify-center h-[70rpx] leading-[70rpx] text-[#333] bg-[#eee] text-[26rpx] border-[0] font-500 rounded-[10rpx] mr-[20rpx]">取消</view>
|
||||||
|
<view @click="pullDownConfirmFn" class="flex-1 flex justify-center bg-[var(--primary-color)] h-[70rpx] leading-[70rpx] text-[#fff] text-[26rpx] border-[0] rounded-[10rpx]">确定</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</u-popup>
|
||||||
|
<view v-if="diyStore.mode == 'decorate'" class="form-item-mask"></view>
|
||||||
|
<!-- 隐私弹窗 -->
|
||||||
|
<form-privacy-pop ref="formPrivacyRef" :data="formPrivacyData" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// 表单 多选项组件
|
||||||
|
import { ref, computed, watch,onMounted } from 'vue';
|
||||||
|
import { img } from '@/utils/common';
|
||||||
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
import formPrivacyPop from './../form-privacy-pop/index.vue';
|
||||||
|
|
||||||
|
const props = defineProps(['component', 'index','global']);
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
const selectValue = ref([])
|
||||||
|
const selectShow = ref(false);
|
||||||
|
const pullDownVal = ref([])
|
||||||
|
|
||||||
|
const errorInfo:any = ref(null);
|
||||||
|
const formPrivacyRef: any = ref(null);
|
||||||
|
|
||||||
|
const diyComponent = computed(() => {
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return diyStore.value[props.index];
|
||||||
|
} else {
|
||||||
|
return props.component;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const diyGlobal = computed(() => {
|
||||||
|
return props.global;
|
||||||
|
})
|
||||||
|
|
||||||
|
const formPrivacyData = computed(() => {
|
||||||
|
let str = `${diyComponent.value.field.name}已开启隐私保护,提交后会部分打码,只有你自己和管理员才能查看完整信息`;
|
||||||
|
return str;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 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 eventFn = (type:any)=>{
|
||||||
|
if(type == 'privacy'){
|
||||||
|
// 查看隐私
|
||||||
|
formPrivacyRef.value.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const warpCss = computed(() => {
|
||||||
|
var style = '';
|
||||||
|
style += 'position:relative;';
|
||||||
|
if (diyComponent.value.componentStartBgColor && diyComponent.value.componentEndBgColor) style += `background:linear-gradient(${diyComponent.value.componentGradientAngle},${diyComponent.value.componentStartBgColor},${diyComponent.value.componentEndBgColor});`;
|
||||||
|
else if (diyComponent.value.componentStartBgColor) style += 'background-color:' + diyComponent.value.componentStartBgColor + ';';
|
||||||
|
else if (diyComponent.value.componentEndBgColor) style += 'background-color:' + diyComponent.value.componentEndBgColor + ';';
|
||||||
|
|
||||||
|
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;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
refresh();
|
||||||
|
// 装修模式下刷新
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
watch(
|
||||||
|
() => diyComponent.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue && newValue.componentName == 'FormCheckbox') {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}else{
|
||||||
|
}
|
||||||
|
if(diyComponent.value.style == 'style-3'){
|
||||||
|
pullDownVal.value = diyComponent.value.field.value.map(item => item.id);
|
||||||
|
}
|
||||||
|
if(diyComponent.value.field.value.length>0){
|
||||||
|
selectValue.value = diyComponent.value.field.value.map(item => item.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const refresh = ()=> {
|
||||||
|
// console.log('diyComponent.value.field.value',diyComponent.value.field.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkboxPlaceholder = computed(() => {
|
||||||
|
let str = '';
|
||||||
|
str += `请选择${ diyComponent.value.field.name }`
|
||||||
|
return str;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单组件验证
|
||||||
|
const verify = () => {
|
||||||
|
const res = { code: true, message: '' }
|
||||||
|
if (diyComponent.value.field.required && diyComponent.value.field.value.length == '' && diyStore.mode != 'decorate') {
|
||||||
|
res.code = false
|
||||||
|
res.message = checkboxPlaceholder.value;
|
||||||
|
}
|
||||||
|
errorInfo.value = res;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
const backupValue = ref([]);
|
||||||
|
|
||||||
|
// 重置表单组件数据
|
||||||
|
const reset = () => {
|
||||||
|
pullDownVal.value = [];
|
||||||
|
selectValue.value = [];
|
||||||
|
diyComponent.value.field.value = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const pullDownCancelFn = ()=>{
|
||||||
|
selectShow.value = false;
|
||||||
|
pullDownVal.value = backupValue.value.map(item => item.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
const pullDownConfirmFn = () => {
|
||||||
|
selectShow.value = false;
|
||||||
|
const selectedItems = diyComponent.value.options.filter(item => pullDownVal.value.includes(item.id));
|
||||||
|
diyComponent.value.field.value = selectedItems.map(item => ({ id: item.id, text: item.text }));
|
||||||
|
}
|
||||||
|
|
||||||
|
const isDisabled = computed(() => {
|
||||||
|
return diyStore.mode === 'decorate';
|
||||||
|
});
|
||||||
|
|
||||||
|
const openPicker = () => {
|
||||||
|
if(isDisabled.value){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
backupValue.value = [...diyComponent.value.field.value]; // 保存当前的值
|
||||||
|
selectShow.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存数据到 store
|
||||||
|
const checkboxChange = (value: any) => {
|
||||||
|
const selectedItems = diyComponent.value.options.filter(item => value.includes(item.id));
|
||||||
|
diyComponent.value.field.value = selectedItems.map(item => ({ id: item.id, text: item.text }));
|
||||||
|
};
|
||||||
|
const selectRadio = (item) => {
|
||||||
|
if (isDisabled.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const itemId = item.id;
|
||||||
|
const index = selectValue.value.indexOf(itemId);
|
||||||
|
if (index > -1) {
|
||||||
|
selectValue.value.splice(index, 1);
|
||||||
|
} else {
|
||||||
|
selectValue.value.push(itemId);
|
||||||
|
}
|
||||||
|
const selectedItems = diyComponent.value.options.filter(item => selectValue.value.includes(item.id));
|
||||||
|
|
||||||
|
diyComponent.value.field.value = selectedItems.map(item => ({ id: item.id, text: item.text }));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
verify,
|
||||||
|
reset
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
.pull-down-arrow{
|
||||||
|
transition: all .3s;
|
||||||
|
transform: rotate(0);
|
||||||
|
&.selected{
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.form-item-frame :deep(.u-checkbox .u-checkbox__icon-wrap){
|
||||||
|
width: 30rpx !important;
|
||||||
|
height: 30rpx !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
304
uni-app/src/app/components/diy/form-date-scope/index.vue
Normal file
304
uni-app/src/app/components/diy/form-date-scope/index.vue
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
<template>
|
||||||
|
<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.start.date }} - {{ diyComponent.field.value.end.date }}</text>
|
||||||
|
</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="detail-two-content-value w-[80%]">{{ diyComponent.field.value.start.date }} - {{ diyComponent.field.value.end.date }}</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="name" :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">已隐藏</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 items-center">
|
||||||
|
<view class="layout-one-content flex-1" @click="openCalendar">
|
||||||
|
<view class="nc-iconfont nc-icon-a-riliV6xx-36 !text-[32rpx] text-[#999] mr-[16rpx]"></view>
|
||||||
|
<view class="flex-1 text-overflow-ellipsis" :class="{'!text-[#999]' : !diyComponent.field.value.start.timestamp && !diyComponent.defaultControl}" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx' }">
|
||||||
|
{{ startDate }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="mx-[10rpx]" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}">-</view>
|
||||||
|
<view class="layout-one-content flex-1" @click="openCalendar">
|
||||||
|
<view class="nc-iconfont nc-icon-a-riliV6xx-36 !text-[32rpx] text-[#999] mr-[16rpx]"></view>
|
||||||
|
<view class="flex-1 text-overflow-ellipsis" :class="{'!text-[#999]' : !diyComponent.field.value.end.timestamp && !diyComponent.defaultControl}" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}">
|
||||||
|
{{ endDate }}
|
||||||
|
</view>
|
||||||
|
</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">已隐藏</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" @click="openCalendar">
|
||||||
|
<view class="text-overflow-ellipsis flex justify-center" :class="{'!text-[#999]' : !diyComponent.field.value.start.timestamp && !diyComponent.defaultControl}" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}">
|
||||||
|
{{ startDate }}
|
||||||
|
</view>
|
||||||
|
<view class="mx-[10rpx]" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}">-</view>
|
||||||
|
<view class="text-overflow-ellipsis flex justify-center" :class="{'!text-[#999]' : !diyComponent.field.value.end.timestamp && !diyComponent.defaultControl}" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}">
|
||||||
|
{{ endDate }}
|
||||||
|
</view>
|
||||||
|
<text class="nc-iconfont !text-[#666] !text-[36rpx] nc-icon-youV6xx -mr-[8rpx]"></text>
|
||||||
|
</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 class="calendar-wrap">
|
||||||
|
<u-calendar :show="calendarShow" mode="range" @confirm="confirm" @close="calendarShow=false" closeOnClickOverlay="true"
|
||||||
|
:defaultDate="defaultDate" startText="开始" endText="结束" confirmDisabledText="禁止选择" color="var(--primary-color)" ref="calendar" monthNum="2"></u-calendar>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 遮罩层,装修使用 -->
|
||||||
|
<view v-if="diyStore.mode == 'decorate'" class="form-item-mask"></view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// 表单 日期范围组件
|
||||||
|
import { ref, computed, watch,onMounted } from 'vue';
|
||||||
|
import { img,timeTurnTimeStamp } from '@/utils/common';
|
||||||
|
import { t } from '@/locale'
|
||||||
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
|
||||||
|
const props = defineProps(['component', 'index','global']);
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
const calendarShow = ref(false);
|
||||||
|
|
||||||
|
const errorInfo:any = ref(null);
|
||||||
|
|
||||||
|
const diyComponent = computed(() => {
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return diyStore.value[props.index];
|
||||||
|
} else {
|
||||||
|
return props.component;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const diyGlobal = computed(() => {
|
||||||
|
return props.global;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 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 eventFn = (type:any)=>{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始日期
|
||||||
|
const startDate = computed(() => {
|
||||||
|
let returnDate = '';
|
||||||
|
let date = '';
|
||||||
|
if(diyComponent.value.field.value.start.date){
|
||||||
|
let timestamp = diyComponent.value.field.value.start.timestamp;
|
||||||
|
returnDate = getDateFn(timestamp);
|
||||||
|
date = returnDate;
|
||||||
|
}else{
|
||||||
|
if(diyComponent.value.start.defaultControl){
|
||||||
|
if(diyComponent.value.start.dateWay == 'current'){
|
||||||
|
returnDate = getDateFn();
|
||||||
|
}else if(diyComponent.value.start.dateWay == 'diy'){
|
||||||
|
let timestamp = diyComponent.value.field.default.start.timestamp ? diyComponent.value.field.default.start.timestamp : '';
|
||||||
|
returnDate = getDateFn(timestamp);
|
||||||
|
}
|
||||||
|
date = returnDate;
|
||||||
|
}else{
|
||||||
|
returnDate = diyComponent.value.start.placeholder;
|
||||||
|
date = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diyComponent.value.field.value.start.date = date;
|
||||||
|
diyComponent.value.field.value.start.timestamp = date ? timeTurnTimeStamp(date) : 0;
|
||||||
|
return returnDate;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 结束日期
|
||||||
|
const endDate = computed(() => {
|
||||||
|
let returnDate = '';
|
||||||
|
let date = '';
|
||||||
|
if (diyComponent.value.field.value.end.date) {
|
||||||
|
let timestamp = diyComponent.value.field.value.end.timestamp;
|
||||||
|
returnDate = getDateFn(timestamp);
|
||||||
|
date = returnDate;
|
||||||
|
|
||||||
|
diyComponent.value.field.value.end.date = date;
|
||||||
|
diyComponent.value.field.value.end.timestamp = timeTurnTimeStamp(date);
|
||||||
|
} else {
|
||||||
|
if (diyComponent.value.end.defaultControl) {
|
||||||
|
if (diyComponent.value.end.dateWay == 'current') {
|
||||||
|
returnDate = getDateFn();
|
||||||
|
} else if (diyComponent.value.end.dateWay == 'diy') {
|
||||||
|
returnDate = getDateFn(diyComponent.value.field.default.end.timestamp);
|
||||||
|
}
|
||||||
|
date = returnDate;
|
||||||
|
diyComponent.value.field.value.end.date = date;
|
||||||
|
diyComponent.value.field.value.end.timestamp = timeTurnTimeStamp(date);
|
||||||
|
} else {
|
||||||
|
returnDate = diyComponent.value.end.placeholder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return returnDate;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 默认数据
|
||||||
|
const defaultDate = computed(()=>{
|
||||||
|
let arr = [];
|
||||||
|
arr[0] = getDateFn(timeTurnTimeStamp(startDate.value), 'YYYY-MM-DD');
|
||||||
|
arr[1] = getDateFn(timeTurnTimeStamp(endDate.value), 'YYYY-MM-DD');
|
||||||
|
return arr;
|
||||||
|
})
|
||||||
|
|
||||||
|
const warpCss = computed(() => {
|
||||||
|
var style = '';
|
||||||
|
style += 'position:relative;';
|
||||||
|
if (diyComponent.value.componentStartBgColor && diyComponent.value.componentEndBgColor) style += `background:linear-gradient(${diyComponent.value.componentGradientAngle},${diyComponent.value.componentStartBgColor},${diyComponent.value.componentEndBgColor});`;
|
||||||
|
else if (diyComponent.value.componentStartBgColor) style += 'background-color:' + diyComponent.value.componentStartBgColor + ';';
|
||||||
|
else if (diyComponent.value.componentEndBgColor) style += 'background-color:' + diyComponent.value.componentEndBgColor + ';';
|
||||||
|
|
||||||
|
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;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
refresh();
|
||||||
|
// 装修模式下刷新
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
watch(
|
||||||
|
() => diyComponent.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue && newValue.componentName == 'FormDateScope') {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const refresh = ()=> {
|
||||||
|
// todo 开始、结束时间给予默认值
|
||||||
|
// {{ diyComponent.start.defaultControl ? diyComponent.field.value.start.date : diyComponent.start.placeholder }}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单组件验证
|
||||||
|
const verify = () => {
|
||||||
|
const res = { code: true, message: '' }
|
||||||
|
if(diyComponent.value.field.required){
|
||||||
|
if (diyComponent.value.field.value.start.date == '' || !diyComponent.value.field.value.start.timestamp) {
|
||||||
|
res.code = false
|
||||||
|
res.message = `请选择${ diyComponent.value.start.placeholder }`;
|
||||||
|
}else if (diyComponent.value.field.value.end.date == '' || !diyComponent.value.field.value.end.timestamp) {
|
||||||
|
res.code = false
|
||||||
|
res.message = `请选择${ diyComponent.value.end.placeholder }`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errorInfo.value = res;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单组件数据
|
||||||
|
const reset = () => {
|
||||||
|
diyComponent.value.field.value.start.date = '';
|
||||||
|
diyComponent.value.field.value.start.timestamp = 0;
|
||||||
|
diyComponent.value.field.value.end.date = '';
|
||||||
|
diyComponent.value.field.value.end.timestamp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const openCalendar = () =>{
|
||||||
|
if(diyStore.mode === 'decorate') return;
|
||||||
|
calendarShow.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirm = (e)=> {
|
||||||
|
diyComponent.value.field.value.start.date = e[0];
|
||||||
|
diyComponent.value.field.value.start.timestamp = timeTurnTimeStamp(e[0]); // todo 需要赋值
|
||||||
|
diyComponent.value.field.value.end.date = e[e.length - 1];
|
||||||
|
diyComponent.value.field.value.end.timestamp = timeTurnTimeStamp(e[e.length - 1]); // todo 需要赋值
|
||||||
|
calendarShow.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getDateFn = (res:any='', type:any=diyComponent.value.dateFormat)=>{
|
||||||
|
let date = res ? new Date(res*1000) : new Date();
|
||||||
|
let year = date.getFullYear();
|
||||||
|
let month = String(date.getMonth() + 1).padStart(2, '0');
|
||||||
|
let day = String(date.getDate()).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}`;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
verify,
|
||||||
|
reset
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
.text-overflow-ellipsis {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style lang="scss">
|
||||||
|
.calendar-wrap .u-calendar .u-calendar-header__title, .u-calendar-header__subtitle, .u-calendar-month__title{
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
272
uni-app/src/app/components/diy/form-date/index.vue
Normal file
272
uni-app/src/app/components/diy/form-date/index.vue
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
<template>
|
||||||
|
<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.date}}</text>
|
||||||
|
</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="detail-two-content-value w-[80%]">{{ diyComponent.field.value.date}}</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="name" :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">已隐藏</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="layout-one-content" @click="openCalendar">
|
||||||
|
<view class="nc-iconfont nc-icon-a-riliV6xx-36 !text-[32rpx] text-[#999] mr-[16rpx]"></view>
|
||||||
|
<view class="flex-1 text-overflow-ellipsis flex" :class="{'!text-[#999]' : !diyComponent.field.value.date && !diyComponent.defaultControl}" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx' }">
|
||||||
|
{{ startDate }}
|
||||||
|
</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">已隐藏</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" @click="openCalendar">
|
||||||
|
<view class="flex-1 text-overflow-ellipsis flex justify-end" :class="{'!text-[#999]' : !diyComponent.field.value.date && !diyComponent.defaultControl}" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}">
|
||||||
|
{{ startDate }}
|
||||||
|
</view>
|
||||||
|
<text class="nc-iconfont !text-[#666] !text-[36rpx] nc-icon-youV6xx -mr-[8rpx]"></text>
|
||||||
|
</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 class="calendar-wrap">
|
||||||
|
<u-calendar :show="calendarShow" mode="single" @confirm="confirm" @close="calendarShow=false" closeOnClickOverlay="true"
|
||||||
|
:formatter="formatter" confirmDisabledText="禁止选择" color="var(--primary-color)" ref="calendar" :maxDate="maxDate"></u-calendar>
|
||||||
|
<u-datetime-picker :show="show" v-model="diyComponent.field.value.date" mode="datetime" @cancel="show=false" closeOnClickOverlay="true" @confirm="calendarConfirm" @close="show=false" :minDate="minDate"></u-datetime-picker>
|
||||||
|
</view>
|
||||||
|
<!-- 遮罩层,装修使用 -->
|
||||||
|
<view v-if="diyStore.mode == 'decorate'" class="form-item-mask"></view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// 表单 日期组件
|
||||||
|
import { ref, computed, watch, onMounted } from 'vue';
|
||||||
|
import { img, timeStampTurnTime, timeTurnTimeStamp } from '@/utils/common';
|
||||||
|
import { t } from '@/locale'
|
||||||
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
let currentDate = new Date();
|
||||||
|
currentDate.setFullYear(currentDate.getFullYear() + 1);
|
||||||
|
const maxDate = ref(currentDate.getTime());
|
||||||
|
|
||||||
|
let currentDateTime = new Date();
|
||||||
|
const minDate = ref(currentDateTime.getTime());
|
||||||
|
|
||||||
|
const props = defineProps(['component', 'index','global']);
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
const calendarShow = ref(false);
|
||||||
|
const show = ref(false);
|
||||||
|
|
||||||
|
const errorInfo:any = ref(null);
|
||||||
|
|
||||||
|
const diyComponent = computed(() => {
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return diyStore.value[props.index];
|
||||||
|
} else {
|
||||||
|
return props.component;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const diyGlobal = computed(() => {
|
||||||
|
return props.global;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 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 eventFn = (type:any)=>{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 日期
|
||||||
|
const startDate = computed(() => {
|
||||||
|
var date = '';
|
||||||
|
if(diyComponent.value.field.value.date){
|
||||||
|
let timestamp = diyComponent.value.field.value.timestamp;
|
||||||
|
date = getDateFn(timestamp);
|
||||||
|
|
||||||
|
diyComponent.value.field.value.date = date;
|
||||||
|
diyComponent.value.field.value.timestamp = timeTurnTimeStamp(date);
|
||||||
|
}else{
|
||||||
|
if(diyComponent.value.defaultControl){
|
||||||
|
if(diyComponent.value.dateWay == 'current'){
|
||||||
|
date = getDateFn();
|
||||||
|
}else if(diyComponent.value.dateWay == 'diy'){
|
||||||
|
let timestamp = diyComponent.value.field.default.timestamp || '';
|
||||||
|
date = getDateFn(timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
diyComponent.value.field.value.date = date;
|
||||||
|
diyComponent.value.field.value.timestamp = timeTurnTimeStamp(date);
|
||||||
|
}else{
|
||||||
|
date = diyComponent.value.placeholder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return date;
|
||||||
|
})
|
||||||
|
|
||||||
|
const warpCss = computed(() => {
|
||||||
|
var style = '';
|
||||||
|
style += 'position:relative;';
|
||||||
|
if (diyComponent.value.componentStartBgColor && diyComponent.value.componentEndBgColor) style += `background:linear-gradient(${diyComponent.value.componentGradientAngle},${diyComponent.value.componentStartBgColor},${diyComponent.value.componentEndBgColor});`;
|
||||||
|
else if (diyComponent.value.componentStartBgColor) style += 'background-color:' + diyComponent.value.componentStartBgColor + ';';
|
||||||
|
else if (diyComponent.value.componentEndBgColor) style += 'background-color:' + diyComponent.value.componentEndBgColor + ';';
|
||||||
|
|
||||||
|
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;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
refresh();
|
||||||
|
// 装修模式下刷新
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
watch(
|
||||||
|
() => diyComponent.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue && newValue.componentName == 'FormDate') {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const refresh = ()=> {
|
||||||
|
// todo 开始、结束时间给予默认值
|
||||||
|
// {{ diyComponent.defaultControl ? diyComponent.value.field.value.date : diyComponent.placeholder }}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单组件验证
|
||||||
|
const verify = () => {
|
||||||
|
const res = { code: true, message: '' }
|
||||||
|
if (diyComponent.value.field.required && (!diyComponent.value.field.value || !diyComponent.value.field.value.timestamp)) {
|
||||||
|
res.code = false
|
||||||
|
res.message = `请选择${ diyComponent.value.placeholder }`;
|
||||||
|
}
|
||||||
|
errorInfo.value = res;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单组件数据
|
||||||
|
const reset = () => {
|
||||||
|
diyComponent.value.field.value.date = '';
|
||||||
|
diyComponent.value.field.value.timestamp = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const openCalendar = () =>{
|
||||||
|
if(diyStore.mode === 'decorate') return;
|
||||||
|
if(diyComponent.value.dateFormat=='YYYY-MM-DD HH:mm'){
|
||||||
|
show.value = true
|
||||||
|
}else{
|
||||||
|
calendarShow.value = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirm = (e)=> {
|
||||||
|
diyComponent.value.field.value.date = e[0];
|
||||||
|
diyComponent.value.field.value.timestamp = timeTurnTimeStamp(e[0]); // todo 需要赋值
|
||||||
|
calendarShow.value = false;
|
||||||
|
}
|
||||||
|
const calendarConfirm = (e)=>{
|
||||||
|
diyComponent.value.field.value.date = e.value;
|
||||||
|
diyComponent.value.field.value.timestamp = timeTurnTimeStamp(e.value); // todo 需要赋值
|
||||||
|
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=diyComponent.value.dateFormat)=>{
|
||||||
|
let date = data ? new Date(data*1000) : new Date();
|
||||||
|
let year = date.getFullYear();
|
||||||
|
let month = String(date.getMonth() + 1).padStart(2, '0');
|
||||||
|
let day = String(date.getDate()).padStart(2, '0');
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
verify,
|
||||||
|
reset
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.form-item-frame .calendar-wrap .u-calendar{
|
||||||
|
:deep(.u-calendar-header__title), :deep(.u-calendar-header__subtitle), :deep(.u-calendar-month__title){
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.form-item-frame :deep(.u-picker .u-toolbar__wrapper__cancel), .form-item-frame :deep(.u-picker .u-toolbar__wrapper__confirm){
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
199
uni-app/src/app/components/diy/form-email/index.vue
Normal file
199
uni-app/src/app/components/diy/form-email/index.vue
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
<template>
|
||||||
|
<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 class="">{{ 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">已隐藏</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="email" class="layout-one-content" :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"/>
|
||||||
|
<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">已隐藏</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="email" class="layout-two-content no-flex" :placeholder="inputPlaceholder" placeholderClass="layout-two-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>
|
||||||
|
<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>
|
||||||
|
<form-privacy-pop ref="formPrivacyRef" :data="formPrivacyData" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// 表单 邮箱组件
|
||||||
|
import { ref, computed, watch,onMounted } from 'vue';
|
||||||
|
import { img } from '@/utils/common';
|
||||||
|
import formPrivacyPop from './../form-privacy-pop/index.vue';
|
||||||
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
|
||||||
|
const props = defineProps(['component', 'index', 'global']);
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
const errorInfo:any = ref(null);
|
||||||
|
const formPrivacyRef: any = ref(null);
|
||||||
|
|
||||||
|
const diyComponent = computed(() => {
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return diyStore.value[props.index];
|
||||||
|
} else {
|
||||||
|
return props.component;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const diyGlobal = computed(() => {
|
||||||
|
return props.global;
|
||||||
|
})
|
||||||
|
|
||||||
|
const inputPlaceholder = computed(() => {
|
||||||
|
let str = '';
|
||||||
|
str += diyComponent.value.placeholder
|
||||||
|
return str;
|
||||||
|
})
|
||||||
|
|
||||||
|
const formPrivacyData = computed(() => {
|
||||||
|
let str = `${diyComponent.value.field.name}已开启隐私保护,提交后会部分打码,只有你自己和管理员才能查看完整信息`;
|
||||||
|
return str;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 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 eventFn = (type:any)=>{
|
||||||
|
if(type == 'privacy'){
|
||||||
|
// 查看隐私
|
||||||
|
formPrivacyRef.value.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const warpCss = computed(() => {
|
||||||
|
var style = '';
|
||||||
|
style += 'position:relative;';
|
||||||
|
if (diyComponent.value.componentStartBgColor && diyComponent.value.componentEndBgColor) style += `background:linear-gradient(${diyComponent.value.componentGradientAngle},${diyComponent.value.componentStartBgColor},${diyComponent.value.componentEndBgColor});`;
|
||||||
|
else if (diyComponent.value.componentStartBgColor) style += 'background-color:' + diyComponent.value.componentStartBgColor + ';';
|
||||||
|
else if (diyComponent.value.componentEndBgColor) style += 'background-color:' + diyComponent.value.componentEndBgColor + ';';
|
||||||
|
|
||||||
|
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;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
refresh();
|
||||||
|
// 装修模式下刷新
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
watch(
|
||||||
|
() => diyComponent.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue && newValue.componentName == 'FormEmail') {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}else{
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const refresh = ()=> {
|
||||||
|
// 装修模式下,展示默认值
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
diyComponent.value.field.value = diyComponent.value.field.default;
|
||||||
|
}else {
|
||||||
|
// 实际展示,优先缓存,其次默认值
|
||||||
|
if (diyComponent.value.field.value == '' && diyComponent.value.field.default) {
|
||||||
|
diyComponent.value.field.value = diyComponent.value.field.default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单组件验证
|
||||||
|
const verify = () => {
|
||||||
|
let emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
||||||
|
const res = { code: true, message: '' }
|
||||||
|
if (diyComponent.value.field.required && diyComponent.value.field.value == '' && diyStore.mode != 'decorate') {
|
||||||
|
res.code = false
|
||||||
|
res.message = `${ inputPlaceholder.value }`;
|
||||||
|
}else if (!emailRegex.test(diyComponent.value.field.value) && diyStore.mode != 'decorate') {
|
||||||
|
res.code = false
|
||||||
|
res.message = `邮箱格式不正确,请重新输入`;
|
||||||
|
}
|
||||||
|
errorInfo.value = res;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单组件数据
|
||||||
|
const reset = () => {
|
||||||
|
diyComponent.value.field.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const isDisabled = computed(() => {
|
||||||
|
return diyStore.mode == 'decorate';
|
||||||
|
});
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
verify,
|
||||||
|
reset
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
</style>
|
||||||
119
uni-app/src/app/components/diy/form-file/index.vue
Normal file
119
uni-app/src/app/components/diy/form-file/index.vue
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
<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>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// 表单 文件组件
|
||||||
|
import { ref, computed, watch,onMounted } from 'vue';
|
||||||
|
import { img } from '@/utils/common';
|
||||||
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
import { uploadImage } from '@/app/api/system'
|
||||||
|
|
||||||
|
const props = defineProps(['component', 'index','global']);
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
const selectValue = ref([])
|
||||||
|
|
||||||
|
const diyComponent = computed(() => {
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return diyStore.value[props.index];
|
||||||
|
} else {
|
||||||
|
return props.component;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
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 + ';';
|
||||||
|
}
|
||||||
|
|
||||||
|
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;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
refresh();
|
||||||
|
// 装修模式下刷新
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
watch(
|
||||||
|
() => diyComponent.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue && newValue.componentName == 'FormFile') {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const imgListPreview = computed(() => {
|
||||||
|
return selectValue.value.map(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(() => {
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const deletePic = (event)=> {
|
||||||
|
selectValue.value.splice(event.index, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
const refresh = ()=> {
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单组件验证
|
||||||
|
const verify = () => {
|
||||||
|
const res = { code: true, message: '' }
|
||||||
|
// todo 验证组件,diyComponent.value.field.value
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单组件数据
|
||||||
|
const reset = () => {
|
||||||
|
// todo 清空组件数据,diyComponent.value.field.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
verify,
|
||||||
|
reset
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
.text-overflow-ellipsis {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
<template>
|
||||||
|
<view @touchmove.prevent.stop>
|
||||||
|
<u-popup :show="formDetailPrivacyPop" @close="closeFn" zIndex="500" mode="center" :round="8">
|
||||||
|
<view class="w-[570rpx] popup-common center">
|
||||||
|
<view class="text-center my-5">
|
||||||
|
仅限本人和管理员能查看完整号码:<br />
|
||||||
|
{{data}}
|
||||||
|
</view>
|
||||||
|
<view class="flex justify-between">
|
||||||
|
<button class="w-[50%] h-[100rpx] rounded-[0rpx] leading-[100rpx] !bg-[transform] border-solid border-[0] border-t-[2rpx] border-[#e6e6e6] !text-[#333]" @click="copy(data)">
|
||||||
|
复制号码
|
||||||
|
</button>
|
||||||
|
<button class="w-[50%] h-[100rpx] rounded-[0rpx] border-solid border-[0] border-t-[2rpx] border-l-[2rpx] bo border-[#e6e6e6] leading-[100rpx] !bg-[transform] !text-[var(--primary-color)]" @click="closeFn">我知道了</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</u-popup>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, computed } from 'vue';
|
||||||
|
import { t } from '@/locale'
|
||||||
|
import { copy } from '@/utils/common';
|
||||||
|
|
||||||
|
const props = defineProps(['data']);
|
||||||
|
|
||||||
|
const data = computed(() => {
|
||||||
|
let str = props.data || '已开启隐私保护,提交后会部分打码,只有你自己和管理员才能查看完整信息';
|
||||||
|
return str;
|
||||||
|
})
|
||||||
|
|
||||||
|
const formDetailPrivacyPop = ref(false);
|
||||||
|
const open = ()=>{
|
||||||
|
formDetailPrivacyPop.value = true
|
||||||
|
}
|
||||||
|
const closeFn = ()=>{
|
||||||
|
formDetailPrivacyPop.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
</style>
|
||||||
227
uni-app/src/app/components/diy/form-identity/index.vue
Normal file
227
uni-app/src/app/components/diy/form-identity/index.vue
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
<template>
|
||||||
|
<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="detail-one-content-value">
|
||||||
|
<text>{{ formattedIdentity }}</text>
|
||||||
|
<text v-if="diyComponent.field.privacyProtection" class="ml-[20rpx] text-[var(--primary-color)]" @click="viewPrivacy">查看</text>
|
||||||
|
</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="detail-one-content-value">
|
||||||
|
<text>{{ formattedIdentity }}</text>
|
||||||
|
<text v-if="diyComponent.field.privacyProtection" class="ml-[20rpx] text-[var(--primary-color)]" @click="viewPrivacy">查看</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<form-identity-privacy ref="formDetailPrivacyRef" :data="diyComponent.field.value" />
|
||||||
|
</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">已隐藏</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="idcard" class="layout-one-content" :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" maxlength="18"/>
|
||||||
|
<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">已隐藏</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="idcard" class="layout-two-content no-flex" :placeholder="inputPlaceholder" placeholderClass="layout-two-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" maxlength="18" />
|
||||||
|
</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>
|
||||||
|
<form-privacy-pop ref="formPrivacyRef" :data="formPrivacyData" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// 表单 身份证组件
|
||||||
|
import { ref, computed, watch,onMounted,nextTick } from 'vue';
|
||||||
|
import { img } from '@/utils/common';
|
||||||
|
import formPrivacyPop from './../form-privacy-pop/index.vue';
|
||||||
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
import formIdentityPrivacy from './../form-identity-privacy/index.vue'
|
||||||
|
|
||||||
|
const props = defineProps(['component', 'index', 'global']);
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
const errorInfo:any = ref(null);
|
||||||
|
const formPrivacyRef: any = ref(null);
|
||||||
|
const formDetailPrivacyRef: any = ref(null);
|
||||||
|
|
||||||
|
const diyComponent = computed(() => {
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return diyStore.value[props.index];
|
||||||
|
} else {
|
||||||
|
return props.component;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const diyGlobal = computed(() => {
|
||||||
|
return props.global;
|
||||||
|
})
|
||||||
|
|
||||||
|
const formattedIdentity = computed(() => {
|
||||||
|
const identity = String(diyComponent.value.field.value);
|
||||||
|
if (diyComponent.value.field.privacyProtection) {
|
||||||
|
return identity.replace(/(\d{3})\d*(\d{4})/, '$1****$2');
|
||||||
|
}
|
||||||
|
return identity;
|
||||||
|
});
|
||||||
|
|
||||||
|
const inputPlaceholder = computed(() => {
|
||||||
|
let str = '';
|
||||||
|
str += diyComponent.value.placeholder
|
||||||
|
return str;
|
||||||
|
})
|
||||||
|
|
||||||
|
const formPrivacyData = computed(() => {
|
||||||
|
let str = `${diyComponent.value.field.name}已开启隐私保护,提交后会部分打码,只有你自己和管理员才能查看完整信息`;
|
||||||
|
return str;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 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 eventFn = (type:any)=>{
|
||||||
|
if(type == 'privacy'){
|
||||||
|
// 查看隐私
|
||||||
|
formPrivacyRef.value.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const viewPrivacy = () => {
|
||||||
|
nextTick(() => {
|
||||||
|
if (formDetailPrivacyRef.value) {
|
||||||
|
formDetailPrivacyRef.value.open();
|
||||||
|
} else {
|
||||||
|
console.warn('formDetailPrivacyRef is not defined');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const warpCss = computed(() => {
|
||||||
|
var style = '';
|
||||||
|
style += 'position:relative;';
|
||||||
|
if (diyComponent.value.componentStartBgColor && diyComponent.value.componentEndBgColor) style += `background:linear-gradient(${diyComponent.value.componentGradientAngle},${diyComponent.value.componentStartBgColor},${diyComponent.value.componentEndBgColor});`;
|
||||||
|
else if (diyComponent.value.componentStartBgColor) style += 'background-color:' + diyComponent.value.componentStartBgColor + ';';
|
||||||
|
else if (diyComponent.value.componentEndBgColor) style += 'background-color:' + diyComponent.value.componentEndBgColor + ';';
|
||||||
|
|
||||||
|
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;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
refresh();
|
||||||
|
// 装修模式下刷新
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
watch(
|
||||||
|
() => diyComponent.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue && newValue.componentName == 'FormIdentity') {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}else{
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const refresh = ()=> {
|
||||||
|
// 装修模式下,展示默认值
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
diyComponent.value.field.value = diyComponent.value.field.default;
|
||||||
|
}else {
|
||||||
|
// 实际展示,优先缓存,其次默认值
|
||||||
|
if (diyComponent.value.field.value == '' && diyComponent.value.field.default) {
|
||||||
|
diyComponent.value.field.value = diyComponent.value.field.default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单组件验证
|
||||||
|
const verify = () => {
|
||||||
|
const res = { code: true, message: '' }
|
||||||
|
// 18位身份证号正则表达式
|
||||||
|
let idCardReg = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))\d{3}[0-9Xx]$/;
|
||||||
|
if (diyComponent.value.field.required && diyComponent.value.field.value == '' && diyStore.mode != 'decorate') {
|
||||||
|
res.code = false
|
||||||
|
res.message = `${ inputPlaceholder.value }`;
|
||||||
|
}else if (!idCardReg.test(diyComponent.value.field.value) && diyStore.mode != 'decorate') {
|
||||||
|
res.code = false
|
||||||
|
res.message = `身份证格式不正确,请重新输入`;
|
||||||
|
}
|
||||||
|
errorInfo.value = res;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单组件数据
|
||||||
|
const reset = () => {
|
||||||
|
diyComponent.value.field.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const isDisabled = computed(() => {
|
||||||
|
return diyStore.mode == 'decorate';
|
||||||
|
});
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
verify,
|
||||||
|
reset
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
</style>
|
||||||
316
uni-app/src/app/components/diy/form-image/index.vue
Normal file
316
uni-app/src/app/components/diy/form-image/index.vue
Normal file
@ -0,0 +1,316 @@
|
|||||||
|
<template>
|
||||||
|
<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">
|
||||||
|
<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"></image>
|
||||||
|
</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"></image>
|
||||||
|
</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">已隐藏</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"></image>
|
||||||
|
<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 @afterRead="afterRead" multiple :maxCount="1" 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 @afterRead="afterRead" multiple :maxCount="1" 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> -->
|
||||||
|
<!-- v-else-if -->
|
||||||
|
<view v-if="diyComponent.field.value.length < Number(diyComponent.limit)" class="layout-one-content h-[180rpx] w-[180rpx] !px-[0]">
|
||||||
|
<!-- <u-upload v-if="diyComponent.uploadMode.length == 1" @afterRead="afterRead" multiple :capture="uploadType" :maxCount="Number(diyComponent.limit)">
|
||||||
|
<view class="flex flex-col items-center justify-center w-[180rpx] h-[180rpx] ">
|
||||||
|
<text class="nc-iconfont !text-[36rpx] mb-[16rpx]" :class="{'nc-icon-xiangjiV6xx':diyComponent.uploadMode.indexOf('take_pictures') > -1, 'nc-icon-tupiandaohangpc':diyComponent.uploadMode.indexOf('take_pictures') == -1}"></text>
|
||||||
|
<text class="text-[28rpx] ml-[10rpx] text-[24rpx]">{{diyComponent.uploadMode.indexOf('take_pictures') > -1 ? '拍照上传' : '从相册选择'}}</text>
|
||||||
|
</view>
|
||||||
|
</u-upload> -->
|
||||||
|
<!-- v-else -->
|
||||||
|
<u-upload @afterRead="afterRead" multiple :capture="uploadType" :maxCount="Number(diyComponent.limit)">
|
||||||
|
<view class="flex flex-col items-center justify-center w-[180rpx] h-[180rpx] ">
|
||||||
|
<text class="nc-iconfont !text-[40rpx] mb-[16rpx] nc-icon-jiahaoV6xx"></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">已隐藏</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"></image>
|
||||||
|
<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 v-if="diyComponent.field.value.length < Number(diyComponent.limit)" @afterRead="afterRead" multiple :capture="uploadType" :maxCount="Number(diyComponent.limit)">
|
||||||
|
<view class="flex flex-col items-center justify-center min-w-[180rpx] min-h-[180rpx]">
|
||||||
|
<text class="nc-iconfont !text-[40rpx] mb-[16rpx] nc-icon-jiahaoV6xx"></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>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// 表单 图片组件
|
||||||
|
import { ref, computed, watch,onMounted } from 'vue';
|
||||||
|
import { img } from '@/utils/common';
|
||||||
|
import { onLoad,onShow,onUnload} from '@dcloudio/uni-app';
|
||||||
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
import { uploadImage } from '@/app/api/system'
|
||||||
|
|
||||||
|
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];
|
||||||
|
} else {
|
||||||
|
return props.component;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const diyGlobal = computed(() => {
|
||||||
|
return props.global;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 上传方式
|
||||||
|
const uploadType = computed(()=>{
|
||||||
|
let type = [];
|
||||||
|
if(diyComponent.value && diyComponent.value.uploadMode){
|
||||||
|
diyComponent.value.uploadMode.forEach((item,index)=>{
|
||||||
|
if(item == 'take_pictures' && diyComponent.value.uploadMode.indexOf('camera') == -1){
|
||||||
|
type.push('camera');
|
||||||
|
}else if(item == 'select_from_album' && diyComponent.value.uploadMode.indexOf('album') == -1){
|
||||||
|
type.push('album');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 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 eventFn = (type:any)=>{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleImg = (url: any,index: number) => {
|
||||||
|
let tmp = [];
|
||||||
|
if(diyComponent.value.field.value){
|
||||||
|
tmp = Object.values(diyComponent.value.field.value).map((item: any) => {
|
||||||
|
return img(item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
uni.previewImage({
|
||||||
|
current: index,
|
||||||
|
urls: tmp,
|
||||||
|
indicator: "number",
|
||||||
|
loop: true
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭预览图片
|
||||||
|
onUnload(()=>{
|
||||||
|
// #ifdef H5 || APP
|
||||||
|
try {
|
||||||
|
uni.closePreviewImage()
|
||||||
|
}catch (e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
})
|
||||||
|
|
||||||
|
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 + ';';
|
||||||
|
}
|
||||||
|
|
||||||
|
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;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
refresh();
|
||||||
|
// 装修模式下刷新
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
watch(
|
||||||
|
() => diyComponent.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue && newValue.componentName == 'FormImage') {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const isDisabled = computed(() => {
|
||||||
|
return diyStore.mode === 'decorate';
|
||||||
|
});
|
||||||
|
|
||||||
|
const imgListPreview = computed(() => {
|
||||||
|
return diyComponent.value.field.value.map(item => {
|
||||||
|
return {url: img(item)}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const afterRead = (event) => {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
uploadImage({
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
const refresh = ()=> {
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单组件验证
|
||||||
|
const verify = () => {
|
||||||
|
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 = `请上传图片`;
|
||||||
|
}else if (diyComponent.value.field.value && diyComponent.value.field.value.length > Number(diyComponent.value.limit)) {
|
||||||
|
res.code = false
|
||||||
|
res.message = `图片上传数量已超出限制数量`;
|
||||||
|
}
|
||||||
|
errorInfo.value = res;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单组件数据
|
||||||
|
const reset = () => {
|
||||||
|
// todo 清空组件数据,diyComponent.value.field.value = '';
|
||||||
|
diyComponent.value.field.value = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
verify,
|
||||||
|
reset
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.layout-one-content .u-upload .u-upload__wrap > uni-view, .layout-one-content .u-upload .u-upload__wrap > view, .layout-one-content .u-upload .u-upload__wrap > div{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
</style>
|
||||||
195
uni-app/src/app/components/diy/form-input/index.vue
Normal file
195
uni-app/src/app/components/diy/form-input/index.vue
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
<template>
|
||||||
|
<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 class="">{{ 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">已隐藏</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="text" class="layout-one-content" :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" />
|
||||||
|
<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">已隐藏</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" :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>
|
||||||
|
<form-privacy-pop ref="formPrivacyRef" :data="formPrivacyData" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// 表单 单行文本组件
|
||||||
|
import { ref, computed, watch,onMounted } from 'vue';
|
||||||
|
import { img } from '@/utils/common';
|
||||||
|
import formPrivacyPop from './../form-privacy-pop/index.vue';
|
||||||
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
|
||||||
|
const props = defineProps(['component', 'index', 'global']);
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
const errorInfo:any = ref(null);
|
||||||
|
const formPrivacyRef: any = ref(null);
|
||||||
|
|
||||||
|
const diyComponent = computed(() => {
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return diyStore.value[props.index];
|
||||||
|
} else {
|
||||||
|
return props.component;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const diyGlobal = computed(() => {
|
||||||
|
return props.global;
|
||||||
|
})
|
||||||
|
|
||||||
|
const inputPlaceholder = computed(() => {
|
||||||
|
let str = '';
|
||||||
|
str += diyComponent.value.placeholder
|
||||||
|
return str;
|
||||||
|
})
|
||||||
|
|
||||||
|
const formPrivacyData = computed(() => {
|
||||||
|
let str = `${diyComponent.value.field.name}已开启隐私保护,提交后会部分打码,只有你自己和管理员才能查看完整信息`;
|
||||||
|
return str;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 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 eventFn = (type:any)=>{
|
||||||
|
if(type == 'privacy'){
|
||||||
|
// 查看隐私
|
||||||
|
formPrivacyRef.value.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const warpCss = computed(() => {
|
||||||
|
var style = '';
|
||||||
|
style += 'position:relative;';
|
||||||
|
if (diyComponent.value.componentStartBgColor && diyComponent.value.componentEndBgColor) style += `background:linear-gradient(${diyComponent.value.componentGradientAngle},${diyComponent.value.componentStartBgColor},${diyComponent.value.componentEndBgColor});`;
|
||||||
|
else if (diyComponent.value.componentStartBgColor) style += 'background-color:' + diyComponent.value.componentStartBgColor + ';';
|
||||||
|
else if (diyComponent.value.componentEndBgColor) style += 'background-color:' + diyComponent.value.componentEndBgColor + ';';
|
||||||
|
|
||||||
|
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;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
refresh();
|
||||||
|
// 装修模式下刷新
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
watch(
|
||||||
|
() => diyComponent.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue && newValue.componentName == 'FormInput') {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}else{
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const refresh = ()=> {
|
||||||
|
// 装修模式下,展示默认值
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
diyComponent.value.field.value = diyComponent.value.field.default;
|
||||||
|
}else {
|
||||||
|
// 实际展示,优先缓存,其次默认值
|
||||||
|
if (diyComponent.value.field.value == '' && diyComponent.value.field.default) {
|
||||||
|
diyComponent.value.field.value = diyComponent.value.field.default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单组件验证
|
||||||
|
const verify = () => {
|
||||||
|
const res = { code: true, message: '' }
|
||||||
|
if (diyComponent.value.field.required && diyComponent.value.field.value == '' && diyStore.mode != 'decorate') {
|
||||||
|
res.code = false
|
||||||
|
res.message = `${ inputPlaceholder.value }`;
|
||||||
|
}
|
||||||
|
errorInfo.value = res;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单组件数据
|
||||||
|
const reset = () => {
|
||||||
|
diyComponent.value.field.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const isDisabled = computed(() => {
|
||||||
|
return diyStore.mode == 'decorate';
|
||||||
|
});
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
verify,
|
||||||
|
reset
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
</style>
|
||||||
96
uni-app/src/app/components/diy/form-location/index.vue
Normal file
96
uni-app/src/app/components/diy/form-location/index.vue
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<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>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// 表单 定位组件
|
||||||
|
import { ref, computed, watch,onMounted } from 'vue';
|
||||||
|
import { img } from '@/utils/common';
|
||||||
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
|
||||||
|
const props = defineProps(['component', 'index','global']);
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
|
||||||
|
const diyComponent = computed(() => {
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return diyStore.value[props.index];
|
||||||
|
} else {
|
||||||
|
return props.component;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
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 + ';';
|
||||||
|
}
|
||||||
|
|
||||||
|
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;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
refresh();
|
||||||
|
// 装修模式下刷新
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
watch(
|
||||||
|
() => diyComponent.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue && newValue.componentName == 'FormLocation') {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}else{
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const refresh = ()=> {
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单组件验证
|
||||||
|
const verify = () => {
|
||||||
|
const res = { code: true, message: '' }
|
||||||
|
// todo 验证组件,diyComponent.value.field.value
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单组件数据
|
||||||
|
const reset = () => {
|
||||||
|
// todo 清空组件数据,diyComponent.value.field.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
verify,
|
||||||
|
reset
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
.text-overflow-ellipsis {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
226
uni-app/src/app/components/diy/form-mobile/index.vue
Normal file
226
uni-app/src/app/components/diy/form-mobile/index.vue
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
<template>
|
||||||
|
<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="detail-one-content-value">
|
||||||
|
<text>{{ formattedPhoneNumber }}</text>
|
||||||
|
<text v-if="diyComponent.field.privacyProtection" class="ml-[20rpx] text-[var(--primary-color)]" @click="viewPrivacy">查看</text>
|
||||||
|
</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="detail-two-content-value">
|
||||||
|
<text>{{ formattedPhoneNumber }}</text>
|
||||||
|
<text v-if="diyComponent.field.privacyProtection" class="ml-[20rpx] text-[var(--primary-color)]" @click="viewPrivacy">查看</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<form-privacy ref="formDeatilPrivacyRef" :data="diyComponent.field.value" />
|
||||||
|
</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">已隐藏</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="number" class="layout-one-content" :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" maxlength="11"/>
|
||||||
|
<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">已隐藏</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="number" class="layout-two-content no-flex" :placeholder="inputPlaceholder" placeholderClass="layout-two-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" maxlength="11" />
|
||||||
|
</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>
|
||||||
|
<form-privacy-pop ref="formPrivacyRef" :data="formPrivacyData" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// 表单 手机号组件
|
||||||
|
import { ref, computed, watch,onMounted,nextTick } from 'vue';
|
||||||
|
import { img } from '@/utils/common';
|
||||||
|
import formPrivacyPop from './../form-privacy-pop/index.vue';
|
||||||
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
import formPrivacy from './../form-privacy/index.vue'
|
||||||
|
const props = defineProps(['component', 'index', 'global']);
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
const errorInfo:any = ref(null);
|
||||||
|
const formPrivacyRef: any = ref(null);
|
||||||
|
const formDeatilPrivacyRef: any = ref(null);
|
||||||
|
|
||||||
|
const diyComponent = computed(() => {
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return diyStore.value[props.index];
|
||||||
|
} else {
|
||||||
|
return props.component;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const diyGlobal = computed(() => {
|
||||||
|
return props.global;
|
||||||
|
})
|
||||||
|
|
||||||
|
const formattedPhoneNumber = computed(() => {
|
||||||
|
const phone = String(diyComponent.value.field.value);
|
||||||
|
if (diyComponent.value.field.privacyProtection) {
|
||||||
|
return phone.replace(/(\d{3})\d{4}(\d{3})/, '$1****$2');
|
||||||
|
}
|
||||||
|
return phone;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const inputPlaceholder = computed(() => {
|
||||||
|
let str = '';
|
||||||
|
str += diyComponent.value.placeholder
|
||||||
|
return str;
|
||||||
|
})
|
||||||
|
|
||||||
|
const formPrivacyData = computed(() => {
|
||||||
|
let str = `${diyComponent.value.field.name}已开启隐私保护,提交后会部分打码,只有你自己和管理员才能查看完整信息`;
|
||||||
|
return str;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 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 eventFn = (type:any)=>{
|
||||||
|
if(type == 'privacy'){
|
||||||
|
// 查看隐私
|
||||||
|
formPrivacyRef.value.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const viewPrivacy = () => {
|
||||||
|
nextTick(() => {
|
||||||
|
if (formDeatilPrivacyRef.value) {
|
||||||
|
formDeatilPrivacyRef.value.open();
|
||||||
|
} else {
|
||||||
|
console.warn('formDeatilPrivacyRef is not defined');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const warpCss = computed(() => {
|
||||||
|
var style = '';
|
||||||
|
style += 'position:relative;';
|
||||||
|
if (diyComponent.value.componentStartBgColor && diyComponent.value.componentEndBgColor) style += `background:linear-gradient(${diyComponent.value.componentGradientAngle},${diyComponent.value.componentStartBgColor},${diyComponent.value.componentEndBgColor});`;
|
||||||
|
else if (diyComponent.value.componentStartBgColor) style += 'background-color:' + diyComponent.value.componentStartBgColor + ';';
|
||||||
|
else if (diyComponent.value.componentEndBgColor) style += 'background-color:' + diyComponent.value.componentEndBgColor + ';';
|
||||||
|
|
||||||
|
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;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
refresh();
|
||||||
|
// 装修模式下刷新
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
watch(
|
||||||
|
() => diyComponent.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue && newValue.componentName == 'FormMobile') {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}else{
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const refresh = ()=> {
|
||||||
|
// 装修模式下,展示默认值
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
diyComponent.value.field.value = diyComponent.value.field.default;
|
||||||
|
}else {
|
||||||
|
// 实际展示,优先缓存,其次默认值
|
||||||
|
if (diyComponent.value.field.value == '' && diyComponent.value.field.default) {
|
||||||
|
diyComponent.value.field.value = diyComponent.value.field.default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单组件验证
|
||||||
|
const verify = () => {
|
||||||
|
const res = { code: true, message: '' }
|
||||||
|
if (diyComponent.value.field.required && diyComponent.value.field.value == '' && diyStore.mode != 'decorate') {
|
||||||
|
res.code = false
|
||||||
|
res.message = `${ inputPlaceholder.value }`;
|
||||||
|
}else if (!/^1[3-9]\d{9}$/.test(diyComponent.value.field.value) && diyStore.mode != 'decorate') {
|
||||||
|
res.code = false
|
||||||
|
res.message = `手机号格式不正确,请重新输入`;
|
||||||
|
}
|
||||||
|
errorInfo.value = res;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单组件数据
|
||||||
|
const reset = () => {
|
||||||
|
diyComponent.value.field.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const isDisabled = computed(() => {
|
||||||
|
return diyStore.mode == 'decorate';
|
||||||
|
});
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
verify,
|
||||||
|
reset
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
</style>
|
||||||
201
uni-app/src/app/components/diy/form-number/index.vue
Normal file
201
uni-app/src/app/components/diy/form-number/index.vue
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
<template>
|
||||||
|
<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">
|
||||||
|
<text class="detail-two-content-label">{{ diyComponent.field.name }}</text>
|
||||||
|
<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">已隐藏</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="layout-one-content flex items-center">
|
||||||
|
<input type="number" 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" />
|
||||||
|
<text class="text-[#999] text-[28rpx]" v-if="diyComponent.unit">{{diyComponent.unit}}</text>
|
||||||
|
</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">已隐藏</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">
|
||||||
|
<input type="number" :placeholder="inputPlaceholder" placeholderClass="layout-two-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" />
|
||||||
|
<text class="text-[#999] ml-[10rpx] pt-[2rpx] text-[28rpx]" v-if="diyComponent.unit">{{diyComponent.unit}}</text>
|
||||||
|
</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>
|
||||||
|
<form-privacy-pop ref="formPrivacyRef" :data="formPrivacyData" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// 表单 数字组件
|
||||||
|
import { ref, computed, watch,onMounted } from 'vue';
|
||||||
|
import { img } from '@/utils/common';
|
||||||
|
import formPrivacyPop from './../form-privacy-pop/index.vue';
|
||||||
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
|
||||||
|
const props = defineProps(['component', 'index', 'global']);
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
const errorInfo:any = ref(null);
|
||||||
|
const formPrivacyRef: any = ref(null);
|
||||||
|
|
||||||
|
const diyComponent = computed(() => {
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return diyStore.value[props.index];
|
||||||
|
} else {
|
||||||
|
return props.component;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const diyGlobal = computed(() => {
|
||||||
|
return props.global;
|
||||||
|
})
|
||||||
|
|
||||||
|
const inputPlaceholder = computed(() => {
|
||||||
|
let str = '';
|
||||||
|
str += diyComponent.value.placeholder
|
||||||
|
return str;
|
||||||
|
})
|
||||||
|
|
||||||
|
const formPrivacyData = computed(() => {
|
||||||
|
let str = `${diyComponent.value.field.name}已开启隐私保护,提交后会部分打码,只有你自己和管理员才能查看完整信息`;
|
||||||
|
return str;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 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 eventFn = (type:any)=>{
|
||||||
|
if(type == 'privacy'){
|
||||||
|
// 查看隐私
|
||||||
|
formPrivacyRef.value.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const warpCss = computed(() => {
|
||||||
|
var style = '';
|
||||||
|
style += 'position:relative;';
|
||||||
|
if (diyComponent.value.componentStartBgColor && diyComponent.value.componentEndBgColor) style += `background:linear-gradient(${diyComponent.value.componentGradientAngle},${diyComponent.value.componentStartBgColor},${diyComponent.value.componentEndBgColor});`;
|
||||||
|
else if (diyComponent.value.componentStartBgColor) style += 'background-color:' + diyComponent.value.componentStartBgColor + ';';
|
||||||
|
else if (diyComponent.value.componentEndBgColor) style += 'background-color:' + diyComponent.value.componentEndBgColor + ';';
|
||||||
|
|
||||||
|
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;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
refresh();
|
||||||
|
// 装修模式下刷新
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
watch(
|
||||||
|
() => diyComponent.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue && newValue.componentName == 'FormNumber') {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}else{
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const refresh = ()=> {
|
||||||
|
// 装修模式下,展示默认值
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
diyComponent.value.field.value = diyComponent.value.field.default;
|
||||||
|
}else {
|
||||||
|
// 实际展示,优先缓存,其次默认值
|
||||||
|
if (diyComponent.value.field.value == '' && diyComponent.value.field.default) {
|
||||||
|
diyComponent.value.field.value = diyComponent.value.field.default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单组件验证
|
||||||
|
const verify = () => {
|
||||||
|
const res = { code: true, message: '' }
|
||||||
|
if (diyComponent.value.field.required && diyComponent.value.field.value == '' && diyStore.mode != 'decorate') {
|
||||||
|
res.code = false
|
||||||
|
res.message = `${ inputPlaceholder.value }`;
|
||||||
|
}
|
||||||
|
errorInfo.value = res;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单组件数据
|
||||||
|
const reset = () => {
|
||||||
|
diyComponent.value.field.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const isDisabled = computed(() => {
|
||||||
|
return diyStore.mode == 'decorate';
|
||||||
|
});
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
verify,
|
||||||
|
reset
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
</style>
|
||||||
43
uni-app/src/app/components/diy/form-privacy-pop/index.vue
Normal file
43
uni-app/src/app/components/diy/form-privacy-pop/index.vue
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<template>
|
||||||
|
<view @touchmove.prevent.stop>
|
||||||
|
<u-popup :show="formPrivacyPop" @close="closeFn" zIndex="500" mode="center" :round="8">
|
||||||
|
<view class="flex flex-col items-center w-[640rpx] pt-[50rpx]">
|
||||||
|
<view class="text-[32rpx] font-bold">提示</view>
|
||||||
|
<view class="text-center px-[40rpx] py-[30rpx] leading-[1.5] min-h-[90rpx]">
|
||||||
|
{{data}}
|
||||||
|
</view>
|
||||||
|
<view class="flex items-center justify-center border-solid border-[0] border-t-[2rpx] border-[#e6e6e6] w-[100%] h-[90rpx] text-[28rpx]">
|
||||||
|
<text @click="closeFn">我知道了</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</u-popup>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, computed } from 'vue';
|
||||||
|
import { t } from '@/locale'
|
||||||
|
|
||||||
|
const props = defineProps(['data']);
|
||||||
|
|
||||||
|
const data = computed(() => {
|
||||||
|
let str = props.data || '已开启隐私保护,提交后会部分打码,只有你自己和管理员才能查看完整信息';
|
||||||
|
return str;
|
||||||
|
})
|
||||||
|
|
||||||
|
const formPrivacyPop = ref(false);
|
||||||
|
const open = ()=>{
|
||||||
|
formPrivacyPop.value = true
|
||||||
|
}
|
||||||
|
const closeFn = ()=>{
|
||||||
|
formPrivacyPop.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
</style>
|
||||||
52
uni-app/src/app/components/diy/form-privacy/index.vue
Normal file
52
uni-app/src/app/components/diy/form-privacy/index.vue
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<template>
|
||||||
|
<view @touchmove.prevent.stop>
|
||||||
|
<u-popup :show="formDetailPrivacyPop" @close="closeFn" zIndex="500" mode="center" :round="8">
|
||||||
|
<view class="w-[570rpx] popup-common center">
|
||||||
|
<view class="text-center my-5">
|
||||||
|
仅限本人和管理员能查看完整号码:<br />
|
||||||
|
{{data}}
|
||||||
|
</view>
|
||||||
|
<view class="flex justify-between">
|
||||||
|
<button class="w-[50%] h-[100rpx] rounded-[0rpx] leading-[100rpx] !bg-[transform] border-solid border-[0] border-t-[2rpx] border-[#e6e6e6] !text-[#333]" @click="call">
|
||||||
|
拨打
|
||||||
|
</button>
|
||||||
|
<button class="w-[50%] h-[100rpx] rounded-[0rpx] border-solid border-[0] border-t-[2rpx] border-l-[2rpx] bo border-[#e6e6e6] leading-[100rpx] !bg-[transform] !text-[var(--primary-color)]" @click="closeFn">我知道了</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</u-popup>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, computed } from 'vue';
|
||||||
|
import { t } from '@/locale'
|
||||||
|
|
||||||
|
const props = defineProps(['data']);
|
||||||
|
|
||||||
|
const data = computed(() => {
|
||||||
|
let str = props.data || '已开启隐私保护,提交后会部分打码,只有你自己和管理员才能查看完整信息';
|
||||||
|
return str;
|
||||||
|
})
|
||||||
|
|
||||||
|
const formDetailPrivacyPop = ref(false);
|
||||||
|
const open = ()=>{
|
||||||
|
formDetailPrivacyPop.value = true
|
||||||
|
}
|
||||||
|
const closeFn = ()=>{
|
||||||
|
formDetailPrivacyPop.value = false
|
||||||
|
}
|
||||||
|
const call = ()=>{
|
||||||
|
uni.makePhoneCall({
|
||||||
|
phoneNumber: props.data
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
</style>
|
||||||
330
uni-app/src/app/components/diy/form-radio/index.vue
Normal file
330
uni-app/src/app/components/diy/form-radio/index.vue
Normal file
@ -0,0 +1,330 @@
|
|||||||
|
<template>
|
||||||
|
<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 v-for="(item,index) in diyComponent.field.value" :key="index" >{{ item.text}}</text>
|
||||||
|
</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="detail-two-content-value w-[80%]" v-for="(item,index) in diyComponent.field.value" :key="index" >{{ item.text}}</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="name" :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">已隐藏</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.style == 'style-1'" class="layout-one-content !flex-initial">
|
||||||
|
<u-radio-group v-model="selectedRadioId" @change="groupChange" iconPlacement="left">
|
||||||
|
<view v-for="(item, index) in diyComponent.options" :key="index" class="mr-[40rpx]">
|
||||||
|
<u-radio activeColor="var(--primary-color)" :labelSize="(diyComponent.fontSize * 2) + 'rpx'" :labelColor="diyComponent.textColor" :label="item.text" :name="item.id"></u-radio>
|
||||||
|
</view>
|
||||||
|
</u-radio-group>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<u-radio-group v-if="diyComponent.style == 'style-2'" v-model="selectedRadioId" @change="groupChange" iconPlacement="left" placement="column">
|
||||||
|
<view v-for="(item, index) in diyComponent.options" :key="index" @click="selectRadio(item)" class="layout-one-content mb-[16rpx]" :class="{'!mb-[0]': (diyComponent.options.length-1) == index}">
|
||||||
|
<u-radio activeColor="var(--primary-color)" :labelSize="(diyComponent.fontSize * 2) + 'rpx'" :labelColor="diyComponent.textColor" class="mr-[20rpx]" :label="item.text" :name="item.id"></u-radio>
|
||||||
|
</view>
|
||||||
|
</u-radio-group>
|
||||||
|
|
||||||
|
<view v-if="diyComponent.style == 'style-3'" @click="openPicker" class="layout-one-content justify-between">
|
||||||
|
<view v-if="diyComponent.field.value.length>0">
|
||||||
|
<text class="mr-[10rpx] text-[28rpx]" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}">{{getSelectRadioName}}</text>
|
||||||
|
</view>
|
||||||
|
<text v-else class="text-[28rpx] text-[#999]" :style="{'font-size': (diyComponent.fontSize * 2) + 'rpx'}">{{radioPlaceholder}}</text>
|
||||||
|
<text class="nc-iconfont nc-icon-xiaV6xx pull-down-arrow text-[#666]" :class="{'selected': selectShow}" :style="{'font-size': (diyComponent.fontSize * 2+2) + 'rpx !important'}"></text>
|
||||||
|
</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">已隐藏</text>
|
||||||
|
<view class="layout-two-wrap" :class="{'!pb-[20rpx]': ((diyComponent.style == 'style-2' || diyComponent.style == 'style-3') && diyGlobal.borderControl),'no-border': !diyGlobal.borderControl}">
|
||||||
|
<view class="layout-two-label" :class="{'justify-start': diyGlobal.completeAlign == 'left', 'justify-end': diyGlobal.completeAlign == 'right'}">
|
||||||
|
<text class="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" v-if= "diyComponent.style == 'style-1'">
|
||||||
|
<view class="justify-end">
|
||||||
|
<u-radio-group v-model="selectedRadioId" @change="groupChange" iconPlacement="left">
|
||||||
|
<view v-for="(item, index) in diyComponent.options" :key="index" class="ml-[30rpx]">
|
||||||
|
<u-radio activeColor="var(--primary-color)" :labelSize="(diyComponent.fontSize * 2) + 'rpx'" :labelColor="diyComponent.textColor" :label="item.text" :name="item.id"></u-radio>
|
||||||
|
</view>
|
||||||
|
</u-radio-group>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="layout-two-content" v-if="diyComponent.style == 'style-2'">
|
||||||
|
<view class="justify-end w-full">
|
||||||
|
<u-radio-group v-model="selectedRadioId" @change="groupChange" placement="column" iconPlacement="left">
|
||||||
|
<view v-for="(item, index) in diyComponent.options" :key="index" @click="selectRadio(item)" class="border-solid border-[2rpx] border-[#e6e6e6] rounded-[10rpx] flex items-center h-[80rpx] mb-[16rpx] px-[16rpx] box-border" :class="{'mb-[0]': diyComponent.options.length == (index+1)}" >
|
||||||
|
<u-radio activeColor="var(--primary-color)" :labelSize="(diyComponent.fontSize * 2) + 'rpx'" :labelColor="diyComponent.textColor" class="!m-[0]" :label="item.text" :name="item.id"></u-radio>
|
||||||
|
</view>
|
||||||
|
</u-radio-group>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="layout-two-content" v-if= "diyComponent.style == 'style-3'">
|
||||||
|
<view @click="openPicker" class="px-[16rpx] box-border h-[80rpx] flex items-center justify-between border-solid border-[2rpx] border-[#e6e6e6] rounded-[10rpx] w-[100%]">
|
||||||
|
<view v-if="diyComponent.field.value.length>0">
|
||||||
|
<text class="mr-[10rpx] text-[28rpx]" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}">{{getSelectRadioName}}</text>
|
||||||
|
</view>
|
||||||
|
<text v-else class="text-[28rpx] text-[#999]" :style="{'font-size': (diyComponent.fontSize * 2) + 'rpx'}">{{radioPlaceholder}}</text>
|
||||||
|
<text class="nc-iconfont nc-icon-xiaV6xx pull-down-arrow text-[#666]" :class="{'selected': selectShow}" :style="{'font-size': (diyComponent.fontSize * 2+2) + 'rpx !important'}"></text>
|
||||||
|
</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>
|
||||||
|
<!-- 样式三,下拉弹窗 -->
|
||||||
|
<u-popup :show="selectShow" mode="bottom" @close="selectShow=false" >
|
||||||
|
<view class="p-[15rpx]">
|
||||||
|
<scroll-view scroll-y="true" class="max-h-[450rpx] px-[14rpx] box-border">
|
||||||
|
<u-radio-group v-model="pullDownVal" placement="column" @change="groupChange" iconPlacement="right">
|
||||||
|
<view class="border-solid border-[0] border-b-[2rpx] border-[#e6e6e6] py-[20rpx]" @click.stop="pullDownConfirmFn(item)" v-for="(item, index) in diyComponent.options" :key="index">
|
||||||
|
<u-radio activeColor="var(--primary-color)" :labelSize="(diyComponent.fontSize * 2) + 'rpx'" :labelColor="diyComponent.textColor" :style="{'width': '100%'}" :label="item.text" :name="item.id"></u-radio>
|
||||||
|
</view>
|
||||||
|
</u-radio-group>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</u-popup>
|
||||||
|
<view v-if="diyStore.mode == 'decorate'" class="form-item-mask"></view>
|
||||||
|
<!-- 隐私弹窗 -->
|
||||||
|
<form-privacy-pop ref="formPrivacyRef" :data="formPrivacyData" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// 表单 单选项组件
|
||||||
|
import { ref, computed, watch,onMounted } from 'vue';
|
||||||
|
import { img } from '@/utils/common';
|
||||||
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
import formPrivacyPop from './../form-privacy-pop/index.vue';
|
||||||
|
|
||||||
|
const props = defineProps(['component', 'index','global']);
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
const selectValue = ref([])
|
||||||
|
const selectShow = ref(false);
|
||||||
|
const pullDownVal = ref([])
|
||||||
|
const selectedRadioId = ref(''); // 存储选中的 id
|
||||||
|
|
||||||
|
const errorInfo:any = ref(null);
|
||||||
|
const formPrivacyRef: any = ref(null);
|
||||||
|
|
||||||
|
const diyComponent = computed(() => {
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return diyStore.value[props.index];
|
||||||
|
} else {
|
||||||
|
return props.component;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const diyGlobal = computed(() => {
|
||||||
|
return props.global;
|
||||||
|
})
|
||||||
|
|
||||||
|
const formPrivacyData = computed(() => {
|
||||||
|
let str = `${diyComponent.value.field.name}已开启隐私保护,提交后会部分打码,只有你自己和管理员才能查看完整信息`;
|
||||||
|
return str;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 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 eventFn = (type:any)=>{
|
||||||
|
if(type == 'privacy'){
|
||||||
|
// 查看隐私
|
||||||
|
formPrivacyRef.value.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const warpCss = computed(() => {
|
||||||
|
var style = '';
|
||||||
|
style += 'position:relative;';
|
||||||
|
if (diyComponent.value.componentStartBgColor && diyComponent.value.componentEndBgColor) style += `background:linear-gradient(${diyComponent.value.componentGradientAngle},${diyComponent.value.componentStartBgColor},${diyComponent.value.componentEndBgColor});`;
|
||||||
|
else if (diyComponent.value.componentStartBgColor) style += 'background-color:' + diyComponent.value.componentStartBgColor + ';';
|
||||||
|
else if (diyComponent.value.componentEndBgColor) style += 'background-color:' + diyComponent.value.componentEndBgColor + ';';
|
||||||
|
|
||||||
|
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;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
refresh();
|
||||||
|
// 装修模式下刷新
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
watch(
|
||||||
|
() => diyComponent.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue && newValue.componentName == 'FormRadio') {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 样式三,初始化下拉数据
|
||||||
|
if(diyComponent.value.style == 'style-3' && diyComponent.value.field.value.length>0){
|
||||||
|
pullDownVal.value = diyComponent.value.field.value[0].id;
|
||||||
|
}
|
||||||
|
if(diyComponent.value.field.value.length>0){
|
||||||
|
selectedRadioId.value = diyComponent.value.field.value[0].id;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
const refresh = ()=> {
|
||||||
|
// console.log('diyComponent.value.field.value',diyComponent.value.field.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const radioPlaceholder = computed(() => {
|
||||||
|
let str = '';
|
||||||
|
str += `请选择${ diyComponent.value.field.name }`
|
||||||
|
return str;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单组件验证
|
||||||
|
const verify = () => {
|
||||||
|
const res = { code: true, message: '' }
|
||||||
|
if (diyComponent.value.field.required && diyComponent.value.field.value.length == '' && diyStore.mode != 'decorate') {
|
||||||
|
res.code = false
|
||||||
|
res.message = radioPlaceholder.value;
|
||||||
|
}
|
||||||
|
errorInfo.value = res;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单组件数据
|
||||||
|
const reset = () => {
|
||||||
|
selectedRadioId.value='';
|
||||||
|
pullDownVal.value = [];
|
||||||
|
selectValue.value = [];
|
||||||
|
diyComponent.value.field.value = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const pullDownCancelFn = ()=>{
|
||||||
|
selectShow.value = false;
|
||||||
|
// pullDownVal.value = diyComponent.value.field.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pullDownConfirmFn = (item:any) => {
|
||||||
|
selectShow.value = false;
|
||||||
|
pullDownVal.value = item.id;;
|
||||||
|
diyComponent.value.field.value = [{ id: item.id, text: item.text }];
|
||||||
|
// diyComponent.value.field.value = pullDownVal.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取选中的单选项名称
|
||||||
|
const getSelectRadioName = computed(() => {
|
||||||
|
let names = [];
|
||||||
|
diyComponent.value.field.value.forEach((selectedItem) => {
|
||||||
|
const item = diyComponent.value.options.find(option => option.id === selectedItem.id);
|
||||||
|
if (item) {
|
||||||
|
names.push(item.text);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return names.join(', ');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const isDisabled = computed(() => {
|
||||||
|
return diyStore.mode === 'decorate';
|
||||||
|
});
|
||||||
|
|
||||||
|
const openPicker = () => {
|
||||||
|
if(isDisabled.value){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
selectShow.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const groupChange = (value) => {
|
||||||
|
selectedRadioId.value = value;
|
||||||
|
const selectedItem = diyComponent.value.options.find(item => item.id === value);
|
||||||
|
diyComponent.value.field.value = [{ id: selectedItem.id, text: selectedItem.text }];
|
||||||
|
selectShow.value = false;
|
||||||
|
};
|
||||||
|
const selectRadio = (item) => {
|
||||||
|
if (isDisabled.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
selectedRadioId.value = item.id;;
|
||||||
|
diyComponent.value.field.value = [{ id: item.id, text: item.text }];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
verify,
|
||||||
|
reset
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
.pull-down-arrow{
|
||||||
|
transition: all .3s;
|
||||||
|
transform: rotate(0);
|
||||||
|
&.selected{
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 覆盖 u-radio 样式 */
|
||||||
|
// ::v-deep(.u-radio) {
|
||||||
|
// border-bottom: 2rpx solid #e6e6e6;
|
||||||
|
// height: 90rpx;
|
||||||
|
// }
|
||||||
|
.form-item-frame :deep(.u-radio-group .u-radio__icon-wrap){
|
||||||
|
width: 30rpx !important;
|
||||||
|
height: 30rpx !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
341
uni-app/src/app/components/diy/form-submit/index.vue
Normal file
341
uni-app/src/app/components/diy/form-submit/index.vue
Normal file
@ -0,0 +1,341 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<view class="overflow-hidden">
|
||||||
|
<view :style="maskLayer"></view>
|
||||||
|
<view class="relative submit-wrap z-10" :style="warpCss">
|
||||||
|
<view class="flex flex-col items-center" :style="boxCss">
|
||||||
|
<view class="w-[100%] h-[86rpx] text-[28rpx] flex items-center justify-center" @click="submit" :style="submitItem">{{ diyComponent.submitBtn.text }}</view>
|
||||||
|
<view v-if="diyComponent.resetBtn.control" class="w-[100%] h-[86rpx] mt-[20rpx] text-[28rpx] flex items-center justify-center" @click="reset" :style="resetItem">{{ diyComponent.resetBtn.text }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="diyComponent.btnPosition == 'hover_screen_bottom' && diyStore.mode != 'decorate'" class="w-[100%]" :style="submitFillHeight"></view>
|
||||||
|
<!-- 苹果安全距离,辅助计算 -->
|
||||||
|
<view class="iphone-secure"></view>
|
||||||
|
<!-- 遮罩层,装修使用 -->
|
||||||
|
<view v-if="diyStore.mode == 'decorate'" class="form-item-mask"></view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// 表单提交组件
|
||||||
|
import { ref, computed, watch,onMounted, nextTick, getCurrentInstance } from 'vue';
|
||||||
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
import { img, redirect,getValidTime, deepClone } from '@/utils/common';
|
||||||
|
import { addFormRecord } from '@/app/api/diy_form';
|
||||||
|
|
||||||
|
const props = defineProps(['component', 'index', 'global']);
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
const tabbarInfo = ref();
|
||||||
|
|
||||||
|
const diyComponent = computed(() => {
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return diyStore.value[props.index];
|
||||||
|
} else {
|
||||||
|
return props.component;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const diyGlobal = computed(() => {
|
||||||
|
return props.global;
|
||||||
|
})
|
||||||
|
|
||||||
|
const warpCss = computed(() => {
|
||||||
|
var style = '';
|
||||||
|
style += 'position:relative;';
|
||||||
|
if (diyComponent.value.componentStartBgColor && diyComponent.value.componentEndBgColor) style += `background:linear-gradient(${diyComponent.value.componentGradientAngle},${diyComponent.value.componentStartBgColor},${diyComponent.value.componentEndBgColor});`;
|
||||||
|
else if (diyComponent.value.componentStartBgColor) style += 'background-color:' + diyComponent.value.componentStartBgColor + ';';
|
||||||
|
else if (diyComponent.value.componentEndBgColor) style += 'background-color:' + diyComponent.value.componentEndBgColor + ';';
|
||||||
|
|
||||||
|
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;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
|
||||||
|
if(diyStore.mode != 'decorate' && diyComponent.value.btnPosition == 'hover_screen_bottom'){
|
||||||
|
style += "position: fixed !important;";
|
||||||
|
var height = tabbarInfo.value ? tabbarInfo.value.height : 0;
|
||||||
|
style += `left: 0;`;
|
||||||
|
style += `right: 0;`;
|
||||||
|
if(height && diyGlobal.value.bottomTabBarSwitch){
|
||||||
|
style += `bottom: ${height}px;`;
|
||||||
|
}else{
|
||||||
|
style += `bottom: 0;`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diyComponent.value.pageStartBgColor) {
|
||||||
|
if (diyComponent.value.pageStartBgColor && diyComponent.value.pageEndBgColor) style += `background:linear-gradient(${ diyComponent.value.pageGradientAngle },${ diyComponent.value.pageStartBgColor },${ diyComponent.value.pageEndBgColor });`;
|
||||||
|
else if (diyComponent.value.pageStartBgColor) style += `background: ${ diyComponent.value.pageStartBgColor };`;
|
||||||
|
else if (diyComponent.value.pageEndBgColor) style += `background: ${ diyComponent.value.pageEndBgColor };`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diyComponent.value.margin) {
|
||||||
|
if (diyComponent.value.margin.top > 0) {
|
||||||
|
style += 'padding-top:' + diyComponent.value.margin.top * 2 + 'rpx' + ';';
|
||||||
|
}
|
||||||
|
if(height && diyGlobal.value.bottomTabBarSwitch){
|
||||||
|
style += 'padding-bottom:' + diyComponent.value.margin.bottom * 2 + 'rpx' + ';';
|
||||||
|
}else{
|
||||||
|
style += `padding-bottom: ${(diyComponent.value.margin.bottom + iphoneSecureVal.value) * 2}rpx;`;
|
||||||
|
}
|
||||||
|
|
||||||
|
style += 'padding-right:' + diyComponent.value.margin.both * 2 + 'rpx' + ';';
|
||||||
|
style += 'padding-left:' + diyComponent.value.margin.both * 2 + 'rpx' + ';';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
const boxCss = computed(() => {
|
||||||
|
var style = '';
|
||||||
|
|
||||||
|
if(diyComponent.value.btnPosition == 'hover_screen_bottom'){
|
||||||
|
if (diyComponent.value.componentStartBgColor && diyComponent.value.componentEndBgColor) style += `background:linear-gradient(${diyComponent.value.componentGradientAngle},${diyComponent.value.componentStartBgColor},${diyComponent.value.componentEndBgColor});`;
|
||||||
|
else if (diyComponent.value.componentStartBgColor) style += 'background-color:' + diyComponent.value.componentStartBgColor + ';';
|
||||||
|
else if (diyComponent.value.componentEndBgColor) style += 'background-color:' + diyComponent.value.componentEndBgColor + ';';
|
||||||
|
}
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 背景图加遮罩层
|
||||||
|
const maskLayer = computed(()=>{
|
||||||
|
var style = '';
|
||||||
|
if(diyComponent.value.componentBgUrl) {
|
||||||
|
style += 'position:absolute;top:0;right:0;left:0;bottom:0;';
|
||||||
|
style += `background: rgba(0,0,0,${diyComponent.value.componentBgAlpha / 10});`;
|
||||||
|
|
||||||
|
if (diyComponent.value.topRounded) style += 'border-top-left-radius:' + diyComponent.value.topRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.topRounded) style += 'border-top-right-radius:' + diyComponent.value.topRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
}
|
||||||
|
|
||||||
|
return style;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 重置样式
|
||||||
|
const resetItem = computed(() => {
|
||||||
|
var style = '';
|
||||||
|
style += `color: ${diyComponent.value.resetBtn.color};`;
|
||||||
|
style += `background-color: ${diyComponent.value.resetBtn.bgColor};`;
|
||||||
|
if (diyComponent.value.topElementRounded) style += 'border-top-left-radius:' + diyComponent.value.topElementRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.topElementRounded) style += 'border-top-right-radius:' + diyComponent.value.topElementRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomElementRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomElementRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomElementRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomElementRounded * 2 + 'rpx;';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 保存样式
|
||||||
|
const submitItem = computed(() => {
|
||||||
|
var style = '';
|
||||||
|
style += `color: ${diyComponent.value.submitBtn.color};`;
|
||||||
|
style += `background-color: ${diyComponent.value.submitBtn.bgColor};`;
|
||||||
|
if (diyComponent.value.topElementRounded) style += 'border-top-left-radius:' + diyComponent.value.topElementRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.topElementRounded) style += 'border-top-right-radius:' + diyComponent.value.topElementRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomElementRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomElementRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomElementRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomElementRounded * 2 + 'rpx;';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 提交按钮,悬浮时的填充
|
||||||
|
const submitFillHeight = computed(() => {
|
||||||
|
let style = '';
|
||||||
|
style += `padding-bottom: ${submitHeight.value}px;`;
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
const formComponent: any = ref([])
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
refresh();
|
||||||
|
// 装修模式下刷新
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
watch(
|
||||||
|
() => diyComponent.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue && newValue.componentName == 'FormSubmit') {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
getFormComponent();
|
||||||
|
watch(
|
||||||
|
() => diyStore.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue) {
|
||||||
|
let formData = getFormSComponentsData(newValue);
|
||||||
|
if (formData.components.length) {
|
||||||
|
uni.setStorageSync('diyFormStorage_' + diyStore.id, formData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
nextTick(() => {
|
||||||
|
tabbarInfo.value = uni.getStorageSync('tabbarInfo')
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const refresh = ()=> {
|
||||||
|
}
|
||||||
|
|
||||||
|
const getFormComponent = () => {
|
||||||
|
// 需要过滤 组件类型,筛选出来表单
|
||||||
|
for (let i = 0; i < diyStore.value.length; i++) {
|
||||||
|
let item = diyStore.value[i];
|
||||||
|
// 筛选出来表单组件,排除表单提交组件
|
||||||
|
if (item.componentType == 'diy_form' && item.componentName != 'FormSubmit') {
|
||||||
|
formComponent.value.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const repeat = ref(false)
|
||||||
|
|
||||||
|
const submit = () => {
|
||||||
|
if (diyStore.mode === 'decorate') return
|
||||||
|
|
||||||
|
let allPass = true; // 是否全部通过验证
|
||||||
|
|
||||||
|
// 需要过滤 组件类型,筛选出来表单
|
||||||
|
for (let i = 0; i < formComponent.value.length; i++) {
|
||||||
|
let item = formComponent.value[i];
|
||||||
|
if (item.field.required || item.field.value) {
|
||||||
|
let refKey = `diy${ item.componentName }Ref`;
|
||||||
|
let isBreak = false;
|
||||||
|
if (diyStore.componentRefs[refKey]) {
|
||||||
|
for (let k = 0; k < diyStore.componentRefs[refKey].length; k++) {
|
||||||
|
let compRef = diyStore.componentRefs[refKey][k];
|
||||||
|
let verify = compRef.verify(); // 验证表单组件数据
|
||||||
|
if (verify && !verify.code) {
|
||||||
|
isBreak = true;
|
||||||
|
uni.showToast({
|
||||||
|
title: verify.message,
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (isBreak) {
|
||||||
|
allPass = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!allPass) return;
|
||||||
|
|
||||||
|
if (repeat.value) return
|
||||||
|
repeat.value = true
|
||||||
|
|
||||||
|
let diyFormStorage = uni.getStorageSync('diyFormStorage_' + diyStore.id)
|
||||||
|
let value = {};
|
||||||
|
if(diyFormStorage){
|
||||||
|
value = diyFormStorage.components
|
||||||
|
}else{
|
||||||
|
value = getFormSComponentsData(formComponent.value).components;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
form_id: diyStore.id,
|
||||||
|
value,
|
||||||
|
relate_id: '' // todo 关联业务id,需要考虑如何传入
|
||||||
|
}
|
||||||
|
|
||||||
|
addFormRecord(data).then((res: any) => {
|
||||||
|
uni.removeStorageSync('diyFormStorage_' + diyStore.id)
|
||||||
|
// 跳转到 表单提交结果页面
|
||||||
|
redirect({
|
||||||
|
url: '/app/pages/index/diy_form_result',
|
||||||
|
param: { record_id: res.data, form_id: diyStore.id },
|
||||||
|
mode: 'redirectTo'
|
||||||
|
})
|
||||||
|
repeat.value = false
|
||||||
|
}).catch(() => {
|
||||||
|
repeat.value = false
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
// 重置表单组件数据
|
||||||
|
const reset = () => {
|
||||||
|
// 需要过滤 组件类型,筛选出来表单
|
||||||
|
for (let i = 0; i < formComponent.value.length; i++) {
|
||||||
|
let item = formComponent.value[i];
|
||||||
|
let refKey = `diy${ item.componentName }Ref`;
|
||||||
|
if (diyStore.componentRefs[refKey]) {
|
||||||
|
diyStore.componentRefs[refKey].forEach((compRef: any) => {
|
||||||
|
if (compRef.reset) compRef.reset(item);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取表单组件数据
|
||||||
|
const getFormSComponentsData = (data:any)=>{
|
||||||
|
let formData: any = {
|
||||||
|
validTime: getValidTime(5), // 缓存数据有效期为5分钟
|
||||||
|
components: []
|
||||||
|
};
|
||||||
|
|
||||||
|
data.forEach((item: any) => {
|
||||||
|
// 只存表单组件 -- 用于直接保存
|
||||||
|
if (item.componentType == 'diy_form' && item.componentName != 'FormSubmit') {
|
||||||
|
// 只存储表单数据,压缩存储空间
|
||||||
|
let field = deepClone(item.field);
|
||||||
|
// 移除不需要存储的数据
|
||||||
|
delete field.remark; // 字段说明
|
||||||
|
delete field.detailComponent; // 用于详情展示
|
||||||
|
delete field.default; // 默认值
|
||||||
|
formData.components.push({
|
||||||
|
id: item.id,
|
||||||
|
componentName: item.componentName,
|
||||||
|
componentType: item.componentType,
|
||||||
|
componentTitle: item.componentTitle,
|
||||||
|
isHidden: item.isHidden,
|
||||||
|
field: field
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return formData;
|
||||||
|
}
|
||||||
|
|
||||||
|
let submitHeight = ref(0);
|
||||||
|
const instance = getCurrentInstance();
|
||||||
|
let iphoneSecureVal = ref(0);
|
||||||
|
nextTick(() => {
|
||||||
|
const query = uni.createSelectorQuery().in(instance);
|
||||||
|
query.select('.iphone-secure').boundingClientRect((data: any) => {
|
||||||
|
iphoneSecureVal.value = data ? data.height : 0;
|
||||||
|
}).exec();
|
||||||
|
|
||||||
|
setTimeout(()=>{
|
||||||
|
query.select('.submit-wrap').boundingClientRect((data: any) => {
|
||||||
|
submitHeight.value = data ? data.height : 0;
|
||||||
|
}).exec();
|
||||||
|
},500)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
.iphone-secure{
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: -1;
|
||||||
|
padding-bottom: constant(safe-area-inset-bottom);
|
||||||
|
padding-bottom: env(safe-area-inset-bottom);
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
96
uni-app/src/app/components/diy/form-table/index.vue
Normal file
96
uni-app/src/app/components/diy/form-table/index.vue
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<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>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// 表单 表格组件
|
||||||
|
import { ref, computed, watch,onMounted } from 'vue';
|
||||||
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
import { img } from '@/utils/common';
|
||||||
|
|
||||||
|
const props = defineProps(['component', 'index','global']);
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
|
||||||
|
const diyComponent = computed(() => {
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return diyStore.value[props.index];
|
||||||
|
} else {
|
||||||
|
return props.component;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
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 + ';';
|
||||||
|
}
|
||||||
|
|
||||||
|
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;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
refresh();
|
||||||
|
// 装修模式下刷新
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
watch(
|
||||||
|
() => diyComponent.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue && newValue.componentName == 'FormTable') {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}else{
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const refresh = ()=> {
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单组件验证
|
||||||
|
const verify = () => {
|
||||||
|
const res = { code: true, message: '' }
|
||||||
|
// todo 验证组件,diyComponent.value.field.value
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单组件数据
|
||||||
|
const reset = () => {
|
||||||
|
// todo 清空组件数据,diyComponent.value.field.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
verify,
|
||||||
|
reset
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
.text-overflow-ellipsis {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
208
uni-app/src/app/components/diy/form-textarea/index.vue
Normal file
208
uni-app/src/app/components/diy/form-textarea/index.vue
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
<template>
|
||||||
|
<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 class="">{{ 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">已隐藏</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="layout-one-content !py-[20rpx] !h-[auto]">
|
||||||
|
<textarea class="w-[100%]" :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', 'height': textareaHeight}" v-model="diyComponent.field.value" :disabled="isDisabled" @linechange="linechangeFn" maxlength="500"/>
|
||||||
|
</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">已隐藏</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>
|
||||||
|
<viwe class="layout-two-content">
|
||||||
|
<textarea class="w-[100%]" :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', 'height': textareaHeight}" v-model="diyComponent.field.value" :disabled="isDisabled" @linechange="linechangeFn" maxlength="500"/>
|
||||||
|
</viwe>
|
||||||
|
</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>
|
||||||
|
<form-privacy-pop ref="formPrivacyRef" :data="formPrivacyData" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// 表单 多行文本组件
|
||||||
|
import { ref, computed, watch,onMounted,nextTick } from 'vue';
|
||||||
|
import { img } from '@/utils/common';
|
||||||
|
import formPrivacyPop from './../form-privacy-pop/index.vue';
|
||||||
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
|
||||||
|
const props = defineProps(['component', 'index', 'global']);
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
const errorInfo:any = ref(null);
|
||||||
|
const formPrivacyRef: any = ref(null);
|
||||||
|
|
||||||
|
const diyComponent = computed(() => {
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return diyStore.value[props.index];
|
||||||
|
} else {
|
||||||
|
return props.component;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const diyGlobal = computed(() => {
|
||||||
|
return props.global;
|
||||||
|
})
|
||||||
|
|
||||||
|
const inputPlaceholder = computed(() => {
|
||||||
|
let str = '';
|
||||||
|
str += diyComponent.value.placeholder
|
||||||
|
return str;
|
||||||
|
})
|
||||||
|
|
||||||
|
const formPrivacyData = computed(() => {
|
||||||
|
let str = `${diyComponent.value.field.name}已开启隐私保护,提交后会部分打码,只有你自己和管理员才能查看完整信息`;
|
||||||
|
return str;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 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 eventFn = (type:any)=>{
|
||||||
|
if(type == 'privacy'){
|
||||||
|
// 查看隐私
|
||||||
|
formPrivacyRef.value.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const warpCss = computed(() => {
|
||||||
|
var style = '';
|
||||||
|
style += 'position:relative;';
|
||||||
|
if (diyComponent.value.componentStartBgColor && diyComponent.value.componentEndBgColor) style += `background:linear-gradient(${diyComponent.value.componentGradientAngle},${diyComponent.value.componentStartBgColor},${diyComponent.value.componentEndBgColor});`;
|
||||||
|
else if (diyComponent.value.componentStartBgColor) style += 'background-color:' + diyComponent.value.componentStartBgColor + ';';
|
||||||
|
else if (diyComponent.value.componentEndBgColor) style += 'background-color:' + diyComponent.value.componentEndBgColor + ';';
|
||||||
|
|
||||||
|
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;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
refresh();
|
||||||
|
// 装修模式下刷新
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
watch(
|
||||||
|
() => diyComponent.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue && newValue.componentName == 'FormTextarea') {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}else{
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const refresh = ()=> {
|
||||||
|
// 装修模式下,展示默认值
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
diyComponent.value.field.value = diyComponent.value.field.default;
|
||||||
|
}else {
|
||||||
|
// 实际展示,优先缓存,其次默认值
|
||||||
|
if (diyComponent.value.field.value == '' && diyComponent.value.field.default) {
|
||||||
|
diyComponent.value.field.value = diyComponent.value.field.default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const textareaHeight = ref('38rpx')
|
||||||
|
const linechangeFn = (e)=>{
|
||||||
|
let height = e.detail.height / e.detail.lineCount;
|
||||||
|
if(diyComponent.value.rowCount > e.detail.lineCount){
|
||||||
|
textareaHeight.value = e.detail.height * 2 + 'rpx';
|
||||||
|
}else if(diyComponent.value.rowCount <= e.detail.lineCount){
|
||||||
|
textareaHeight.value = height * diyComponent.value.rowCount * 2 + 'rpx';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单组件验证
|
||||||
|
const verify = () => {
|
||||||
|
const res = { code: true, message: '' }
|
||||||
|
if (diyComponent.value.field.required && diyComponent.value.field.value == '' && diyStore.mode != 'decorate') {
|
||||||
|
res.code = false
|
||||||
|
res.message = `${ inputPlaceholder.value }`;
|
||||||
|
}
|
||||||
|
errorInfo.value = res;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单组件数据
|
||||||
|
const reset = () => {
|
||||||
|
diyComponent.value.field.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const isDisabled = computed(() => {
|
||||||
|
return diyStore.mode == 'decorate';
|
||||||
|
});
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
verify,
|
||||||
|
reset
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
</style>
|
||||||
345
uni-app/src/app/components/diy/form-time-scope/index.vue
Normal file
345
uni-app/src/app/components/diy/form-time-scope/index.vue
Normal file
@ -0,0 +1,345 @@
|
|||||||
|
<template>
|
||||||
|
<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.start.date }} - {{ diyComponent.field.value.end.date }}</text>
|
||||||
|
</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="detail-two-content-value w-[80%]">{{ diyComponent.field.value.start.date }} - {{ diyComponent.field.value.end.date }}</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="name" :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">已隐藏</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 items-center">
|
||||||
|
<view class="layout-one-content flex-1" @click="startDatetime = true">
|
||||||
|
<view class="nc-iconfont nc-icon-a-shijianV6xx-36 !text-[32rpx] text-[#999] mr-[16rpx]"></view>
|
||||||
|
<view class="flex-1 text-overflow-ellipsis" :class="{'!text-[#999]' : !diyComponent.defaultControl && !diyComponent.field.value.start.date}" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}">
|
||||||
|
{{ startTime }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="mx-[10rpx]" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}">-</view>
|
||||||
|
<view class="layout-one-content flex-1" @click="endDatetime = true">
|
||||||
|
<view class="nc-iconfont nc-icon-a-shijianV6xx-36 !text-[32rpx] text-[#999] mr-[16rpx]"></view>
|
||||||
|
<view class="flex-1 text-overflow-ellipsis" :class="{'!text-[#999]' : !diyComponent.defaultControl && !diyComponent.field.value.end.date}" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}">
|
||||||
|
{{ endTime }}
|
||||||
|
</view>
|
||||||
|
</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">已隐藏</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" @click="openCalendar">
|
||||||
|
<view class="text-overflow-ellipsis flex justify-center" :class="{'!text-[#999]' : !diyComponent.field.value.start.date && !diyComponent.defaultControl}" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}" @click="startDatetime = true">
|
||||||
|
{{ startTime }}
|
||||||
|
</view>
|
||||||
|
<view class="mx-[10rpx]" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}">-</view>
|
||||||
|
<view class="text-overflow-ellipsis flex justify-center" :class="{'!text-[#999]' : !diyComponent.field.value.end.date && !diyComponent.defaultControl}" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}" @click="endDatetime = true">
|
||||||
|
{{ endTime }}
|
||||||
|
</view>
|
||||||
|
<text class="nc-iconfont !text-[#666] !text-[36rpx] nc-icon-youV6xx -mr-[8rpx]"></text>
|
||||||
|
</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>
|
||||||
|
<u-datetime-picker :show="startDatetime" v-model="diyComponent.field.value.start.date" mode="time" @cancel="startDatetime=false" @confirm="startTimeConfirm" @close="startDatetime=false" closeOnClickOverlay="true"></u-datetime-picker>
|
||||||
|
<u-datetime-picker :show="endDatetime" :minHour="endMinHour" :minMinute="endMinMinute" v-model="diyComponent.field.value.end.date" mode="time" @cancel="endTimeCancel" @confirm="endTimeConfirm" @change="endTimeChange" @close="startDatetime=false" closeOnClickOverlay="true"></u-datetime-picker>
|
||||||
|
<!-- 遮罩层,装修使用 -->
|
||||||
|
<view v-if="diyStore.mode == 'decorate'" class="form-item-mask"></view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// 表单 时间范围组件
|
||||||
|
import { ref, computed, watch,onMounted } from 'vue';
|
||||||
|
import { img } from '@/utils/common';
|
||||||
|
import { t } from '@/locale'
|
||||||
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
|
||||||
|
const props = defineProps(['component', 'index','global']);
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
const startDatetime = ref(false);
|
||||||
|
const endDatetime = ref(false);
|
||||||
|
const calendarShow = ref(false);
|
||||||
|
|
||||||
|
const errorInfo:any = ref(null);
|
||||||
|
|
||||||
|
const diyComponent = computed(() => {
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return diyStore.value[props.index];
|
||||||
|
} else {
|
||||||
|
return props.component;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const diyGlobal = computed(() => {
|
||||||
|
return props.global;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 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 eventFn = (type:any)=>{}
|
||||||
|
|
||||||
|
// 开始时间
|
||||||
|
const startTime = computed(() => {
|
||||||
|
let returnTime = '';
|
||||||
|
let time = ''
|
||||||
|
if(diyComponent.value.field.value.start.date){
|
||||||
|
returnTime = diyComponent.value.field.value.start.date;
|
||||||
|
time = diyComponent.value.field.value.start.date;
|
||||||
|
}else{
|
||||||
|
if(diyComponent.value.start.defaultControl){
|
||||||
|
if(diyComponent.value.start.timeWay == 'current'){
|
||||||
|
returnTime = getTimeFn();
|
||||||
|
time = getTimeFn();
|
||||||
|
}else if(diyComponent.value.start.timeWay == 'diy'){
|
||||||
|
returnTime = diyComponent.value.field.default.start.date;
|
||||||
|
time = diyComponent.value.field.default.start.date;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
returnTime = diyComponent.value.start.placeholder;
|
||||||
|
time = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diyComponent.value.field.value.start.date = time;
|
||||||
|
diyComponent.value.field.value.start.timestamp = time ? timeInvertSecond(time) : 0;
|
||||||
|
return returnTime;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 结束时间
|
||||||
|
const endTime = computed(() => {
|
||||||
|
let returnTime = '';
|
||||||
|
let time = ''
|
||||||
|
if(diyComponent.value.field.value.end.date){
|
||||||
|
returnTime = diyComponent.value.field.value.end.date;
|
||||||
|
time = diyComponent.value.field.value.end.date;
|
||||||
|
}else{
|
||||||
|
if(diyComponent.value.end.defaultControl){
|
||||||
|
if(diyComponent.value.end.timeWay == 'current'){
|
||||||
|
let now = new Date();
|
||||||
|
let tenMinutesLater =new Date(now.getTime()+10 *60* 1000);
|
||||||
|
returnTime = getTimeFn(tenMinutesLater);
|
||||||
|
time = getTimeFn(tenMinutesLater);
|
||||||
|
}else if(diyComponent.value.end.timeWay == 'diy'){
|
||||||
|
returnTime = diyComponent.value.field.default.end.date;
|
||||||
|
time = diyComponent.value.field.default.end.date;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
returnTime = diyComponent.value.end.placeholder;
|
||||||
|
time = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diyComponent.value.field.value.end.date = time;
|
||||||
|
diyComponent.value.field.value.end.timestamp = time ? timeInvertSecond(time) : 0;
|
||||||
|
return returnTime;
|
||||||
|
})
|
||||||
|
|
||||||
|
const warpCss = computed(() => {
|
||||||
|
var style = '';
|
||||||
|
style += 'position:relative;';
|
||||||
|
if (diyComponent.value.componentStartBgColor && diyComponent.value.componentEndBgColor) style += `background:linear-gradient(${diyComponent.value.componentGradientAngle},${diyComponent.value.componentStartBgColor},${diyComponent.value.componentEndBgColor});`;
|
||||||
|
else if (diyComponent.value.componentStartBgColor) style += 'background-color:' + diyComponent.value.componentStartBgColor + ';';
|
||||||
|
else if (diyComponent.value.componentEndBgColor) style += 'background-color:' + diyComponent.value.componentEndBgColor + ';';
|
||||||
|
|
||||||
|
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;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
refresh();
|
||||||
|
// 装修模式下刷新
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
watch(
|
||||||
|
() => diyComponent.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue && newValue.componentName == 'FormTimeScope') {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const refresh = ()=> {
|
||||||
|
// todo 开始、结束时间给予默认值
|
||||||
|
// {{ diyComponent.start.defaultControl ? diyComponent.field.value.start : diyComponent.start.placeholder }}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单组件验证
|
||||||
|
const verify = () => {
|
||||||
|
const res = { code: true, message: '' }
|
||||||
|
if (diyComponent.value.field.required && diyComponent.value.field.value.start.date == '') {
|
||||||
|
res.code = false
|
||||||
|
res.message = `请选择${ diyComponent.value.start.placeholder }`;
|
||||||
|
}else if (diyComponent.value.field.required && diyComponent.value.field.value.end.date == '') {
|
||||||
|
res.code = false
|
||||||
|
res.message = `请选择${ diyComponent.value.end.placeholder }`;
|
||||||
|
}else if (diyComponent.value.field.value.start.timestamp >= diyComponent.value.field.value.end.timestamp) {
|
||||||
|
res.code = false
|
||||||
|
res.message = `开始时间不能大于等于结束时间`;
|
||||||
|
}
|
||||||
|
errorInfo.value = res;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单组件数据
|
||||||
|
const reset = () => {
|
||||||
|
diyComponent.value.field.value.start.date = '';
|
||||||
|
diyComponent.value.field.value.start.timestamp = 0;
|
||||||
|
diyComponent.value.field.value.end.date = '';
|
||||||
|
diyComponent.value.field.value.end.timestamp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const openCalendar = () =>{
|
||||||
|
if(diyStore.mode === 'decorate') return;
|
||||||
|
calendarShow.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const startTimeConfirm = (e) => {
|
||||||
|
diyComponent.value.field.value.start.date = e.value;
|
||||||
|
diyComponent.value.field.value.start.timestamp = timeInvertSecond(e.value);
|
||||||
|
|
||||||
|
let returnTime = e.value;
|
||||||
|
let startTime = new Date(`1970-01-01T${e.value}:00`);
|
||||||
|
startTime.setMinutes(startTime.getMinutes() + 10);
|
||||||
|
returnTime = getTimeFn(startTime);
|
||||||
|
diyComponent.value.field.value.end.date = returnTime;
|
||||||
|
diyComponent.value.field.value.end.timestamp = timeInvertSecond(returnTime);
|
||||||
|
|
||||||
|
startDatetime.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const endTimeConfirm = (e)=>{
|
||||||
|
diyComponent.value.field.value.end.date = e.value;
|
||||||
|
diyComponent.value.field.value.end.timestamp = timeInvertSecond(e.value);
|
||||||
|
endDatetime.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 辅助设置结束时间可选的最小分钟
|
||||||
|
const endTimeChange = (e)=>{
|
||||||
|
if(!temporaryEndTime.value) temporaryEndTime.value = diyComponent.value.field.value.end.date;
|
||||||
|
diyComponent.value.field.value.end.date = e.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const endTimeCancel = ()=>{
|
||||||
|
if(temporaryEndTime.value) diyComponent.value.field.value.end.date = temporaryEndTime.value;
|
||||||
|
temporaryEndTime.value = '';
|
||||||
|
endDatetime.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置结束时间的最小小时
|
||||||
|
const endMinHour = computed(() => {
|
||||||
|
let arr = diyComponent.value.field.value.start.date.split(':')
|
||||||
|
return Number(arr[0] ? arr[0] : '0');
|
||||||
|
})
|
||||||
|
// 设置结束时间的最小分钟
|
||||||
|
let temporaryEndTime:any = ref("");
|
||||||
|
const endMinMinute = computed({
|
||||||
|
get: () => {
|
||||||
|
let startArr = diyComponent.value.field.value.start.date.split(':');
|
||||||
|
let endArr = diyComponent.value.field.value.end.date.split(':');
|
||||||
|
let num = startArr[0] == endArr[0] ? startArr[1] : 0;
|
||||||
|
return Number(num ? num : '0');
|
||||||
|
},
|
||||||
|
set: (newValue) => {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const confirm = (e)=> {
|
||||||
|
calendarShow.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getTimeFn = (data:any='')=>{
|
||||||
|
let now = data ? new Date(data) : new Date();
|
||||||
|
const hours = String(now.getHours()).padStart(2, '0');
|
||||||
|
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||||||
|
let str = `${hours}:${minutes}`;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 时间转换为秒
|
||||||
|
const timeInvertSecond = (time:any)=>{
|
||||||
|
let arr = time.split(":");
|
||||||
|
let num = 0;
|
||||||
|
if(arr[0]){
|
||||||
|
num += arr[0] * 60 * 60;
|
||||||
|
}
|
||||||
|
if(arr[1]){
|
||||||
|
num += arr[1] * 60;
|
||||||
|
}
|
||||||
|
if(arr[2]){
|
||||||
|
num += arr[2];
|
||||||
|
}
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
verify,
|
||||||
|
reset
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
.text-overflow-ellipsis {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.form-item-frame :deep(.u-picker .u-toolbar__wrapper__cancel), .form-item-frame :deep(.u-picker .u-toolbar__wrapper__confirm){
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
231
uni-app/src/app/components/diy/form-time/index.vue
Normal file
231
uni-app/src/app/components/diy/form-time/index.vue
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
<template>
|
||||||
|
<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">
|
||||||
|
<text class="detail-two-content-label">{{ diyComponent.field.name }}</text>
|
||||||
|
<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="name" :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">已隐藏</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="layout-one-content">
|
||||||
|
<view class="nc-iconfont nc-icon-a-shijianV6xx-36 !text-[32rpx] text-[#999] mr-[16rpx]"></view>
|
||||||
|
<view class="flex-1 text-overflow-ellipsis flex" :class="{'!text-[#999]' : !diyComponent.field.value && !diyComponent.defaultControl}" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}" @click="startDatetime = true">
|
||||||
|
{{ startTime }}
|
||||||
|
</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">已隐藏</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" @click="openCalendar">
|
||||||
|
<view class="flex-1 text-overflow-ellipsis flex justify-end " :class="{'!text-[#999]' : !diyComponent.field.value && !diyComponent.defaultControl}" :style="{'color': diyComponent.textColor,'font-size': (diyComponent.fontSize * 2) + 'rpx'}" @click="startDatetime = true">
|
||||||
|
{{ startTime }}
|
||||||
|
</view>
|
||||||
|
<text class="nc-iconfont !text-[#666] !text-[36rpx] nc-icon-youV6xx -mr-[8rpx]"></text>
|
||||||
|
</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>
|
||||||
|
<u-datetime-picker :show="startDatetime" v-model="diyComponent.field.value" mode="time" @cancel="startDatetime=false" @close="startDatetime=false" @confirm="startTimeConfirm" closeOnClickOverlay="true"></u-datetime-picker>
|
||||||
|
<!-- 遮罩层,装修使用 -->
|
||||||
|
<view v-if="diyStore.mode == 'decorate'" class="form-item-mask"></view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// 表单 时间范围组件
|
||||||
|
import { ref, computed, watch,onMounted } from 'vue';
|
||||||
|
import { img,timeStampTurnTime } from '@/utils/common';
|
||||||
|
import { t } from '@/locale'
|
||||||
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
|
||||||
|
const props = defineProps(['component', 'index','global']);
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
const startDatetime = ref(false);
|
||||||
|
const endDatetime = ref(false);
|
||||||
|
const calendarShow = ref(false);
|
||||||
|
|
||||||
|
const errorInfo:any = ref(null);
|
||||||
|
|
||||||
|
const diyComponent = computed(() => {
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return diyStore.value[props.index];
|
||||||
|
} else {
|
||||||
|
return props.component;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const diyGlobal = computed(() => {
|
||||||
|
return props.global;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 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 eventFn = (type:any)=>{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始时间
|
||||||
|
const startTime = computed(() => {
|
||||||
|
var time = '';
|
||||||
|
if(diyComponent.value.field.value){
|
||||||
|
time = diyComponent.value.field.value;
|
||||||
|
diyComponent.value.field.value = time;
|
||||||
|
}else{
|
||||||
|
if(diyComponent.value.defaultControl){
|
||||||
|
if(diyComponent.value.timeWay == 'current'){
|
||||||
|
time = getTimeFn();
|
||||||
|
}else if(diyComponent.value.timeWay == 'diy'){
|
||||||
|
time = diyComponent.value.field.default;
|
||||||
|
}
|
||||||
|
|
||||||
|
diyComponent.value.field.value = time;
|
||||||
|
}else{
|
||||||
|
time = diyComponent.value.placeholder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return time;
|
||||||
|
})
|
||||||
|
|
||||||
|
const warpCss = computed(() => {
|
||||||
|
var style = '';
|
||||||
|
style += 'position:relative;';
|
||||||
|
if (diyComponent.value.componentStartBgColor && diyComponent.value.componentEndBgColor) style += `background:linear-gradient(${diyComponent.value.componentGradientAngle},${diyComponent.value.componentStartBgColor},${diyComponent.value.componentEndBgColor});`;
|
||||||
|
else if (diyComponent.value.componentStartBgColor) style += 'background-color:' + diyComponent.value.componentStartBgColor + ';';
|
||||||
|
else if (diyComponent.value.componentEndBgColor) style += 'background-color:' + diyComponent.value.componentEndBgColor + ';';
|
||||||
|
|
||||||
|
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;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
refresh();
|
||||||
|
// 装修模式下刷新
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
watch(
|
||||||
|
() => diyComponent.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue && newValue.componentName == 'FormTime') {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const refresh = ()=> {
|
||||||
|
// todo 开始、结束时间给予默认值
|
||||||
|
// {{ diyComponent.start.defaultControl ? diyComponent.field.value : diyComponent.start.placeholder }}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单组件验证
|
||||||
|
const verify = () => {
|
||||||
|
const res = { code: true, message: '' }
|
||||||
|
if (diyComponent.value.field.required && diyComponent.value.field.value == '') {
|
||||||
|
res.code = false
|
||||||
|
res.message = `请选择${ diyComponent.value.placeholder }`;
|
||||||
|
}
|
||||||
|
errorInfo.value = res;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单组件数据
|
||||||
|
const reset = () => {
|
||||||
|
diyComponent.value.field.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const openCalendar = () =>{
|
||||||
|
if(diyStore.mode === 'decorate') return;
|
||||||
|
calendarShow.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const startTimeConfirm = (e)=>{
|
||||||
|
diyComponent.value.field.value = e.value;
|
||||||
|
startDatetime.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirm = (e)=> {
|
||||||
|
calendarShow.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getTimeFn = (data:any='')=>{
|
||||||
|
let now = data ? new Date(data) : new Date();
|
||||||
|
|
||||||
|
let str = '';
|
||||||
|
const hours = String(now.getHours()).padStart(2, '0');
|
||||||
|
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||||||
|
str = `${hours}:${minutes}`;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
verify,
|
||||||
|
reset
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
.text-overflow-ellipsis {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.form-item-frame :deep(.u-picker .u-toolbar__wrapper__cancel), .form-item-frame :deep(.u-picker .u-toolbar__wrapper__confirm){
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
124
uni-app/src/app/components/diy/form-video/index.vue
Normal file
124
uni-app/src/app/components/diy/form-video/index.vue
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
<template>
|
||||||
|
<view :style="warpCss">
|
||||||
|
form-video
|
||||||
|
<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-[#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"/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// 表单 视频组件
|
||||||
|
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']);
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
const selectValue = ref([])
|
||||||
|
|
||||||
|
const diyComponent = computed(() => {
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return diyStore.value[props.index];
|
||||||
|
} else {
|
||||||
|
return props.component;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
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 + ';';
|
||||||
|
}
|
||||||
|
|
||||||
|
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;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
refresh();
|
||||||
|
// 装修模式下刷新
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
watch(
|
||||||
|
() => diyComponent.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue && newValue.componentName == 'FormVideo') {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const isDisabled = computed(() => {
|
||||||
|
return diyStore.mode === 'decorate';
|
||||||
|
});
|
||||||
|
|
||||||
|
const imgListPreview = computed(() => {
|
||||||
|
return selectValue.value.map(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(() => {
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const deletePic = (event)=> {
|
||||||
|
selectValue.value.splice(event.index, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
const refresh = ()=> {
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单组件验证
|
||||||
|
const verify = () => {
|
||||||
|
const res = { code: true, message: '' }
|
||||||
|
// todo 验证组件,diyComponent.value.field.value
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单组件数据
|
||||||
|
const reset = () => {
|
||||||
|
// todo 清空组件数据,diyComponent.value.field.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
verify,
|
||||||
|
reset
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
</style>
|
||||||
96
uni-app/src/app/components/diy/form-wechat-name/index.vue
Normal file
96
uni-app/src/app/components/diy/form-wechat-name/index.vue
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<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>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// 表单 微信名组件
|
||||||
|
import { ref, computed, watch,onMounted } from 'vue';
|
||||||
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
import { img } from '@/utils/common';
|
||||||
|
|
||||||
|
const props = defineProps(['component', 'index','global']);
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
|
||||||
|
const diyComponent = computed(() => {
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return diyStore.value[props.index];
|
||||||
|
} else {
|
||||||
|
return props.component;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
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 + ';';
|
||||||
|
}
|
||||||
|
|
||||||
|
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;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-left-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
if (diyComponent.value.bottomRounded) style += 'border-bottom-right-radius:' + diyComponent.value.bottomRounded * 2 + 'rpx;';
|
||||||
|
return style;
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
refresh();
|
||||||
|
// 装修模式下刷新
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
watch(
|
||||||
|
() => diyComponent.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue && newValue.componentName == 'FormWechatName') {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}else{
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const refresh = ()=> {
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单组件验证
|
||||||
|
const verify = () => {
|
||||||
|
const res = { code: true, message: '' }
|
||||||
|
// todo 验证组件,diyComponent.value.field.value
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单组件数据
|
||||||
|
const reset = () => {
|
||||||
|
// todo 清空组件数据,diyComponent.value.field.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
verify,
|
||||||
|
reset
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy_form.scss';
|
||||||
|
.text-overflow-ellipsis {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -167,7 +167,7 @@
|
|||||||
import { img } from '@/utils/common';
|
import { img } from '@/utils/common';
|
||||||
import useDiyStore from '@/app/stores/diy';
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
const props = defineProps(['component', 'index']);
|
||||||
|
|
||||||
const diyStore = useDiyStore();
|
const diyStore = useDiyStore();
|
||||||
|
|
||||||
@ -226,13 +226,6 @@
|
|||||||
return style;
|
return style;
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.pullDownRefreshCount,
|
|
||||||
(newValue, oldValue) => {
|
|
||||||
// 处理下拉刷新业务
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const swiperIndex = ref(0);
|
const swiperIndex = ref(0);
|
||||||
|
|
||||||
const swiperChange = e => {
|
const swiperChange = e => {
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
import { computed, watch } from 'vue';
|
import { computed, watch } from 'vue';
|
||||||
import useDiyStore from '@/app/stores/diy';
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
const props = defineProps(['component', 'index']);
|
||||||
|
|
||||||
const diyStore = useDiyStore();
|
const diyStore = useDiyStore();
|
||||||
|
|
||||||
@ -33,12 +33,6 @@
|
|||||||
return style;
|
return style;
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.pullDownRefreshCount,
|
|
||||||
(newValue, oldValue) => {
|
|
||||||
// 处理下拉刷新业务
|
|
||||||
}
|
|
||||||
)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style></style>
|
<style></style>
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
import { computed, watch } from 'vue';
|
import { computed, watch } from 'vue';
|
||||||
import useDiyStore from '@/app/stores/diy';
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
const props = defineProps(['component', 'index']);
|
||||||
|
|
||||||
const diyStore = useDiyStore();
|
const diyStore = useDiyStore();
|
||||||
|
|
||||||
@ -29,12 +29,6 @@
|
|||||||
return style;
|
return style;
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.pullDownRefreshCount,
|
|
||||||
(newValue, oldValue) => {
|
|
||||||
// 处理下拉刷新业务
|
|
||||||
}
|
|
||||||
)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style></style>
|
<style></style>
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
import useDiyStore from '@/app/stores/diy';
|
import useDiyStore from '@/app/stores/diy';
|
||||||
import { img } from '@/utils/common';
|
import { img } from '@/utils/common';
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
const props = defineProps(['component', 'index']);
|
||||||
|
|
||||||
const diyStore = useDiyStore();
|
const diyStore = useDiyStore();
|
||||||
|
|
||||||
@ -79,12 +79,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.pullDownRefreshCount,
|
|
||||||
(newValue, oldValue) => {
|
|
||||||
// 处理下拉刷新业务
|
|
||||||
}
|
|
||||||
)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
import useDiyStore from '@/app/stores/diy';
|
import useDiyStore from '@/app/stores/diy';
|
||||||
import { img } from '@/utils/common';
|
import { img } from '@/utils/common';
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
const props = defineProps(['component', 'index']);
|
||||||
const systemInfo = uni.getSystemInfoSync();
|
const systemInfo = uni.getSystemInfoSync();
|
||||||
|
|
||||||
const diyStore = useDiyStore();
|
const diyStore = useDiyStore();
|
||||||
@ -86,13 +86,6 @@
|
|||||||
return style;
|
return style;
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.pullDownRefreshCount,
|
|
||||||
(newValue, oldValue) => {
|
|
||||||
// 处理下拉刷新业务
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const imgHeight = computed(() => {
|
const imgHeight = computed(() => {
|
||||||
return (diyComponent.value.imageHeight * 2) + 'rpx';
|
return (diyComponent.value.imageHeight * 2) + 'rpx';
|
||||||
})
|
})
|
||||||
|
|||||||
@ -72,7 +72,7 @@
|
|||||||
import useDiyStore from '@/app/stores/diy'
|
import useDiyStore from '@/app/stores/diy'
|
||||||
import useConfigStore from '@/stores/config'
|
import useConfigStore from '@/stores/config'
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount','global']);
|
const props = defineProps(['component', 'index','global']);
|
||||||
|
|
||||||
const configStore = useConfigStore()
|
const configStore = useConfigStore()
|
||||||
const diyStore = useDiyStore();
|
const diyStore = useDiyStore();
|
||||||
@ -103,13 +103,6 @@
|
|||||||
return style;
|
return style;
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.pullDownRefreshCount,
|
|
||||||
(newValue, oldValue) => {
|
|
||||||
// 处理下拉刷新业务
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const memberStore = useMemberStore()
|
const memberStore = useMemberStore()
|
||||||
|
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
@ -157,9 +150,12 @@
|
|||||||
uni.showToast({ title: '商家未开启登录注册', icon: 'none' })
|
uni.showToast({ title: '商家未开启登录注册', icon: 'none' })
|
||||||
} else if (configStore.login.is_username || configStore.login.is_mobile || configStore.login.is_bind_mobile) {
|
} else if (configStore.login.is_username || configStore.login.is_mobile || configStore.login.is_bind_mobile) {
|
||||||
useLogin().setLoginBack({ url: '/app/pages/member/index' })
|
useLogin().setLoginBack({ url: '/app/pages/member/index' })
|
||||||
} else if (normalLogin && configStore.login.is_auth_register) {
|
} else if (normalLogin && configStore.login.is_auth_register && configStore.login.is_force_access_user_info) {
|
||||||
// 判断是否开启第三方自动注册登录
|
// 判断是否开启第三方自动注册登录,并且开启强制获取用户信息
|
||||||
useLogin().getAuthCode({ scopes: 'snsapi_userinfo' })
|
useLogin().getAuthCode({ scopes: 'snsapi_userinfo' })
|
||||||
|
} else if (normalLogin && configStore.login.is_auth_register && !configStore.login.is_force_access_user_info) {
|
||||||
|
// 判断是否开启第三方自动注册登录,并且关闭强制获取用户信息
|
||||||
|
useLogin().getAuthCode({ scopes: 'snsapi_base' })
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 普通浏览器
|
// 普通浏览器
|
||||||
@ -176,11 +172,18 @@
|
|||||||
uni.showToast({ title: '商家未开启登录注册', icon: 'none' })
|
uni.showToast({ title: '商家未开启登录注册', icon: 'none' })
|
||||||
} else if (configStore.login.is_username || configStore.login.is_mobile || configStore.login.is_bind_mobile) {
|
} else if (configStore.login.is_username || configStore.login.is_mobile || configStore.login.is_bind_mobile) {
|
||||||
useLogin().setLoginBack({ url: '/app/pages/member/index' })
|
useLogin().setLoginBack({ url: '/app/pages/member/index' })
|
||||||
} else if (normalLogin && configStore.login.is_auth_register) {
|
} else if (normalLogin && configStore.login.is_auth_register && !configStore.login.is_force_access_user_info) {
|
||||||
// 判断是否开启第三方自动注册登录
|
// 判断是否开启第三方自动注册登录
|
||||||
useLogin().getAuthCode()
|
useLogin().getAuthCode()
|
||||||
|
} else if (configStore.login.is_auth_register && configStore.login.is_force_access_user_info) {
|
||||||
|
// 开启了第三方自动注册登录,但是需要强制获取昵称
|
||||||
|
useLogin().setLoginBack({ url: '/app/pages/member/index' })
|
||||||
|
} else if (configStore.login.is_auth_register && configStore.login.is_bind_mobile) {
|
||||||
|
// 开启了第三方自动注册登录,但是需要强制获取手机号
|
||||||
|
useLogin().setLoginBack({ url: '/app/pages/member/index' })
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const infoFill: any = ref(false)
|
const infoFill: any = ref(false)
|
||||||
|
|||||||
@ -112,7 +112,7 @@
|
|||||||
import { t } from '@/locale'
|
import { t } from '@/locale'
|
||||||
import useDiyStore from '@/app/stores/diy'
|
import useDiyStore from '@/app/stores/diy'
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
const props = defineProps(['component', 'index']);
|
||||||
const diyStore = useDiyStore();
|
const diyStore = useDiyStore();
|
||||||
const memberStore = useMemberStore()
|
const memberStore = useMemberStore()
|
||||||
|
|
||||||
@ -133,13 +133,6 @@
|
|||||||
return style;
|
return style;
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.pullDownRefreshCount,
|
|
||||||
(newValue, oldValue) => {
|
|
||||||
// 处理下拉刷新业务
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// 获取会员等级列表
|
// 获取会员等级列表
|
||||||
const upgradeGrowth = ref(0) // 升级下级会员所需的成长值
|
const upgradeGrowth = ref(0) // 升级下级会员所需的成长值
|
||||||
const currIndex = ref(0) //当前会员索引
|
const currIndex = ref(0) //当前会员索引
|
||||||
@ -160,6 +153,7 @@
|
|||||||
return wap_member_info.value||{};
|
return wap_member_info.value||{};
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const list:any = computed(() => {
|
const list:any = computed(() => {
|
||||||
// 装修模式
|
// 装修模式
|
||||||
if (diyStore.mode == 'decorate') {
|
if (diyStore.mode == 'decorate') {
|
||||||
@ -170,11 +164,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const getMemberLevelFn = (list:any)=> {
|
const getMemberLevelFn = (list:any)=> {
|
||||||
if (!list || !list.length) return false;
|
if (!list || !list.length) return false;
|
||||||
let isSet = false;
|
let isSet = false;
|
||||||
// 刚进来处理会员等级数据
|
// 刚进来处理会员等级数据
|
||||||
if (info.value && list && list.length) {
|
if (info.value && info.value.member_level && list && list.length) {
|
||||||
list.forEach((item: any, index: any) => {
|
list.forEach((item: any, index: any) => {
|
||||||
if (item.level_id == info.value.member_level) {
|
if (item.level_id == info.value.member_level) {
|
||||||
currIndex.value = index + 1;
|
currIndex.value = index + 1;
|
||||||
@ -206,7 +201,7 @@
|
|||||||
} else {
|
} else {
|
||||||
// 当前会员没有会员等级,则展示会员等级中的最后一个等级
|
// 当前会员没有会员等级,则展示会员等级中的最后一个等级
|
||||||
info.value.member_level_name = list[0].level_name;
|
info.value.member_level_name = list[0].level_name;
|
||||||
upgradeGrowth.value = list[0].growth - info.value.growth;
|
upgradeGrowth.value = list[0].growth - (info.value.growth || 0);
|
||||||
afterCurrIndex.value = 0;
|
afterCurrIndex.value = 0;
|
||||||
currIndex.value = 1;
|
currIndex.value = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -62,7 +62,7 @@ import { ref,computed, watch, onMounted, nextTick,getCurrentInstance } from 'vue
|
|||||||
import { img } from '@/utils/common';
|
import { img } from '@/utils/common';
|
||||||
import useDiyStore from '@/app/stores/diy';
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
const props = defineProps(['component', 'index']);
|
||||||
const diyStore = useDiyStore();
|
const diyStore = useDiyStore();
|
||||||
const noticeShow = ref(false);
|
const noticeShow = ref(false);
|
||||||
const noticeContent = ref('');
|
const noticeContent = ref('');
|
||||||
@ -112,13 +112,6 @@ const maskLayer = computed(()=>{
|
|||||||
return style;
|
return style;
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.pullDownRefreshCount,
|
|
||||||
(newValue, oldValue) => {
|
|
||||||
// 处理下拉刷新业务
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const marqueeBodyWidth = ref(0); // 容器宽度
|
const marqueeBodyWidth = ref(0); // 容器宽度
|
||||||
const marqueeOneWidth = ref(0); // 内容宽度
|
const marqueeOneWidth = ref(0); // 内容宽度
|
||||||
const marqueeStyle = ref(''); // 横向滚动样式
|
const marqueeStyle = ref(''); // 横向滚动样式
|
||||||
|
|||||||
@ -42,7 +42,7 @@
|
|||||||
import { img } from '@/utils/common';
|
import { img } from '@/utils/common';
|
||||||
import useDiyStore from '@/app/stores/diy';
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount', 'global', 'scrollBool']);
|
const props = defineProps(['component', 'index', 'global', 'scrollBool']);
|
||||||
const diyStore = useDiyStore();
|
const diyStore = useDiyStore();
|
||||||
const diyComponent = computed(() => {
|
const diyComponent = computed(() => {
|
||||||
if (diyStore.mode == 'decorate') {
|
if (diyStore.mode == 'decorate') {
|
||||||
@ -105,13 +105,6 @@
|
|||||||
return style;
|
return style;
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.pullDownRefreshCount,
|
|
||||||
(newValue, oldValue) => {
|
|
||||||
// 处理下拉刷新业务
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
refresh();
|
refresh();
|
||||||
// 装修模式下刷新
|
// 装修模式下刷新
|
||||||
|
|||||||
@ -38,7 +38,7 @@
|
|||||||
import useDiyStore from '@/app/stores/diy';
|
import useDiyStore from '@/app/stores/diy';
|
||||||
import { img } from '@/utils/common';
|
import { img } from '@/utils/common';
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
const props = defineProps(['component', 'index']);
|
||||||
|
|
||||||
const diyStore = useDiyStore();
|
const diyStore = useDiyStore();
|
||||||
|
|
||||||
@ -87,13 +87,6 @@
|
|||||||
return style;
|
return style;
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.pullDownRefreshCount,
|
|
||||||
(newValue, oldValue) => {
|
|
||||||
// 处理下拉刷新业务
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
refresh();
|
refresh();
|
||||||
// 装修模式下刷新
|
// 装修模式下刷新
|
||||||
|
|||||||
@ -78,7 +78,7 @@
|
|||||||
import useDiyStore from '@/app/stores/diy';
|
import useDiyStore from '@/app/stores/diy';
|
||||||
import { img } from '@/utils/common';
|
import { img } from '@/utils/common';
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
const props = defineProps(['component', 'index']);
|
||||||
|
|
||||||
const diyStore = useDiyStore();
|
const diyStore = useDiyStore();
|
||||||
|
|
||||||
@ -189,13 +189,6 @@
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.pullDownRefreshCount,
|
|
||||||
(newValue, oldValue) => {
|
|
||||||
// 处理下拉刷新业务
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
refresh();
|
refresh();
|
||||||
// 装修模式下刷新
|
// 装修模式下刷新
|
||||||
|
|||||||
@ -43,7 +43,7 @@
|
|||||||
import useDiyStore from '@/app/stores/diy';
|
import useDiyStore from '@/app/stores/diy';
|
||||||
import { img } from '@/utils/common';
|
import { img } from '@/utils/common';
|
||||||
|
|
||||||
const props = defineProps(['component', 'index', 'pullDownRefreshCount']);
|
const props = defineProps(['component', 'index']);
|
||||||
const diyStore = useDiyStore();
|
const diyStore = useDiyStore();
|
||||||
|
|
||||||
const diyComponent = computed(() => {
|
const diyComponent = computed(() => {
|
||||||
@ -91,13 +91,6 @@
|
|||||||
return style;
|
return style;
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.pullDownRefreshCount,
|
|
||||||
(newValue, oldValue) => {
|
|
||||||
// 处理下拉刷新业务
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
refresh();
|
refresh();
|
||||||
// 装修模式下刷新
|
// 装修模式下刷新
|
||||||
|
|||||||
@ -1,15 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view>
|
|
||||||
固定模板示例,我也可以装修
|
|
||||||
<!-- 自定义模板渲染 -->
|
|
||||||
<diy-group :data="props.data" :pullDownRefreshCount="props.pullDownRefreshCount"></diy-group>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { computed, watch } from 'vue';
|
|
||||||
import diyGroup from '@/addon/components/diy/group/index.vue'
|
|
||||||
const props = defineProps(['data', 'pullDownRefreshCount']);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style></style>
|
|
||||||
@ -1,7 +1,9 @@
|
|||||||
{
|
{
|
||||||
"alipayAccountNo": "支付宝账号",
|
"alipayAccountNo": "支付宝收款码",
|
||||||
|
"wechatCode":"微信收款码",
|
||||||
"addBankCard": "添加银行卡",
|
"addBankCard": "添加银行卡",
|
||||||
"addAlipayAccount": "添加支付宝账号",
|
"addWechatCode":"添加微信收款码",
|
||||||
|
"addAlipayAccount": "添加支付宝收款码",
|
||||||
"endNumber": "尾号",
|
"endNumber": "尾号",
|
||||||
"bankCard": "银行卡"
|
"bankCard": "银行卡"
|
||||||
}
|
}
|
||||||
@ -5,10 +5,14 @@
|
|||||||
"addBankCardTips": "请添加持卡人本人的银行卡",
|
"addBankCardTips": "请添加持卡人本人的银行卡",
|
||||||
"editBankCard": "编辑银行卡",
|
"editBankCard": "编辑银行卡",
|
||||||
"editBankCardTips": "请编辑持卡人本人的银行卡",
|
"editBankCardTips": "请编辑持卡人本人的银行卡",
|
||||||
"addAlipayAccount": "添加支付宝账号",
|
"addAlipayAccount": "添加支付宝收款码",
|
||||||
"addAlipayAccountTips": "请添加已实名的支付宝账号",
|
"addAlipayAccountTips": "请添加已实名的支付宝账号",
|
||||||
"editAlipayAccount": "编辑支付宝账号",
|
"editAlipayAccount": "编辑支付宝收款码",
|
||||||
"editAlipayAccountTips": "请编辑已实名的支付宝账号",
|
"editAlipayAccountTips": "请编辑已实名的支付宝账号",
|
||||||
|
"addWechatCodeAccount": "添加微信收款码",
|
||||||
|
"addWechatCodeAccountTips": "请添加已实名的微信账号",
|
||||||
|
"editWechatCodeAccount": "编辑微信收款码",
|
||||||
|
"editWechatCodeAccountTips": "请编辑已实名的微信账号",
|
||||||
"bankRealname": "持卡人姓名",
|
"bankRealname": "持卡人姓名",
|
||||||
"bankRealnamePlaceholder": "请输入持卡人姓名",
|
"bankRealnamePlaceholder": "请输入持卡人姓名",
|
||||||
"bankName": "银行名称",
|
"bankName": "银行名称",
|
||||||
@ -19,5 +23,9 @@
|
|||||||
"alipayRealnamePlaceholder": "请输入真实姓名",
|
"alipayRealnamePlaceholder": "请输入真实姓名",
|
||||||
"alipayAccountNo": "支付宝账号",
|
"alipayAccountNo": "支付宝账号",
|
||||||
"alipayAccountNoPlaceholder": "请输入支付宝账号",
|
"alipayAccountNoPlaceholder": "请输入支付宝账号",
|
||||||
|
"wechatCodeAccountNo": "微信账号",
|
||||||
|
"wechatCodeAccountNoPlaceholder": "请输入微信账号",
|
||||||
|
"alipayAccountImgPlaceholder": "请上传支付宝收款码",
|
||||||
|
"wechatCodeAccountImgPlaceholder": "请上传微信收款码",
|
||||||
"deleteConfirm": "确定要删除该账号吗?"
|
"deleteConfirm": "确定要删除该账号吗?"
|
||||||
}
|
}
|
||||||
@ -10,13 +10,16 @@
|
|||||||
"minWithdrawal": "最小提现金额为",
|
"minWithdrawal": "最小提现金额为",
|
||||||
"commissionTo": "手续费为",
|
"commissionTo": "手续费为",
|
||||||
"cashOutList": "提现记录",
|
"cashOutList": "提现记录",
|
||||||
"cashOutToWechat": "提现至微信",
|
"cashOutToWechat": "提现至微信零钱",
|
||||||
"cashOutToWechatTips": "提现至微信零钱",
|
"cashOutToWechatTips": "提现至微信零钱",
|
||||||
"cashOutToAlipay": "提现至支付宝",
|
"cashOutToAlipay": "提现至支付宝",
|
||||||
"cashOutToAlipayTips": "请先添加支付宝账号",
|
"cashOutToAlipayTips": "请先添加支付宝账号",
|
||||||
"cashOutToBank": "提现至银行卡",
|
"cashOutToBank": "提现至银行卡",
|
||||||
"cashOutToBankTips": "请先添加银行卡",
|
"cashOutToBankTips": "请先添加银行卡",
|
||||||
|
"cashOutToWechatCode": "提现至微信",
|
||||||
|
"cashOutToWechatCodeTips": "请先添加微信号",
|
||||||
"alipayAccountNo": "支付宝账号",
|
"alipayAccountNo": "支付宝账号",
|
||||||
|
"wechatCodeAccountNo": "微信号",
|
||||||
"debitCard": "储蓄卡",
|
"debitCard": "储蓄卡",
|
||||||
"abnormalOperation": "异常操作",
|
"abnormalOperation": "异常操作",
|
||||||
"noAvailableCashOutType": "没有可用的提现方式",
|
"noAvailableCashOutType": "没有可用的提现方式",
|
||||||
|
|||||||
@ -8,5 +8,5 @@
|
|||||||
"commissionDetail": "佣金记录",
|
"commissionDetail": "佣金记录",
|
||||||
"emptyTip": "暂无提现记录",
|
"emptyTip": "暂无提现记录",
|
||||||
"commissemptyTip": "暂无佣金记录",
|
"commissemptyTip": "暂无佣金记录",
|
||||||
"rechargeType":"充值方式:"
|
"rechargeType":"提现方式:"
|
||||||
}
|
}
|
||||||
@ -1,12 +1,22 @@
|
|||||||
{
|
{
|
||||||
"statusName": "当前状态",
|
"statusName": "当前状态",
|
||||||
"cashOutNo": "交易号",
|
"cashOutNo": "提现单号",
|
||||||
"serviceMoney": "手续费",
|
"serviceMoney": "手续费",
|
||||||
"createTime": "申请时间",
|
"createTime": "申请时间",
|
||||||
"auditTime": "审核时间",
|
"auditTime": "审核时间",
|
||||||
"transferBank": "银行名称",
|
"transferBank": "银行名称",
|
||||||
"transferAccount": "收款账号",
|
"transferAccount": "收款账号",
|
||||||
"refuseReason": "拒绝理由",
|
"refuseReason": "拒绝理由",
|
||||||
"transferTypeName": "转账方式名称",
|
"transferTypeName": "转账方式",
|
||||||
"transferTime": "转账时间"
|
"transferTime": "转账时间",
|
||||||
|
"transferVoucher":"付款凭证",
|
||||||
|
"transferRemark":"转账补充说明",
|
||||||
|
"realname":"真实姓名",
|
||||||
|
"bankRealname":"持卡人姓名",
|
||||||
|
"transferCode":"收款码",
|
||||||
|
"proceedsInfo":"收款方信息",
|
||||||
|
"transferInfo":"转账信息",
|
||||||
|
"transferNickname":"收款方昵称",
|
||||||
|
"transferImg":"收款方头像",
|
||||||
|
"transferNo":"转账单号"
|
||||||
}
|
}
|
||||||
@ -20,7 +20,7 @@
|
|||||||
<view class="mt-[181rpx]">
|
<view class="mt-[181rpx]">
|
||||||
|
|
||||||
<!-- #ifdef H5 -->
|
<!-- #ifdef H5 -->
|
||||||
<!-- 微信公众号快捷登录 -->
|
<!-- 微信公众号快捷登录,开启自动注册的情况下才能使用 -->
|
||||||
<view v-if="isWeixinBrowser() && loginConfig.is_auth_register" class="w-full flex items-center justify-center mb-[40rpx]">
|
<view v-if="isWeixinBrowser() && loginConfig.is_auth_register" class="w-full flex items-center justify-center mb-[40rpx]">
|
||||||
<button class="w-[630rpx] h-[88rpx] !mx-[0] !bg-[var(--primary-color)] text-[26rpx] rounded-[44rpx] leading-[88rpx] font-500 !text-[#fff]" @click="oneClickLogin()">{{t('quickLoginOrLogout')}}</button>
|
<button class="w-[630rpx] h-[88rpx] !mx-[0] !bg-[var(--primary-color)] text-[26rpx] rounded-[44rpx] leading-[88rpx] font-500 !text-[#fff]" @click="oneClickLogin()">{{t('quickLoginOrLogout')}}</button>
|
||||||
</view>
|
</view>
|
||||||
@ -32,8 +32,8 @@
|
|||||||
<!-- 优先显示第三方登录/注册 -->
|
<!-- 优先显示第三方登录/注册 -->
|
||||||
<view class="w-full flex items-center justify-center mb-[40rpx]" v-if="loginConfig.is_auth_register">
|
<view class="w-full flex items-center justify-center mb-[40rpx]" v-if="loginConfig.is_auth_register">
|
||||||
|
|
||||||
<!-- 开启强制绑定手机号或者手机号登录的情况 -->
|
<!-- 开启强制绑定手机号或者手机号登录的情况,排除强制获取用户信息的情况(is_force_access_user_info为0) -->
|
||||||
<button v-if="!wapMemberMobile && loginConfig.is_bind_mobile"
|
<button v-if="!wapMemberMobile && loginConfig.is_bind_mobile && !loginConfig.is_force_access_user_info"
|
||||||
class="w-[630rpx] h-[88rpx] !bg-[var(--primary-color)] !mx-[0] text-[26rpx] rounded-[44rpx] leading-[88rpx] font-500 !text-[#fff]"
|
class="w-[630rpx] h-[88rpx] !bg-[var(--primary-color)] !mx-[0] text-[26rpx] rounded-[44rpx] leading-[88rpx] font-500 !text-[#fff]"
|
||||||
:open-type="openType" @getphonenumber="mobileAuth" @click="checkWxPrivacy">{{t('quickLoginOrLogout')}}</button>
|
:open-type="openType" @getphonenumber="mobileAuth" @click="checkWxPrivacy">{{t('quickLoginOrLogout')}}</button>
|
||||||
|
|
||||||
@ -44,7 +44,7 @@
|
|||||||
|
|
||||||
<!-- 未开启第三方登录/注册,但是开启了手机号登录,则一键手机号登录/注册 -->
|
<!-- 未开启第三方登录/注册,但是开启了手机号登录,则一键手机号登录/注册 -->
|
||||||
<view class="w-full flex items-center justify-center mb-[40rpx]" v-else-if="!loginConfig.is_auth_register && loginConfig.is_mobile">
|
<view class="w-full flex items-center justify-center mb-[40rpx]" v-else-if="!loginConfig.is_auth_register && loginConfig.is_mobile">
|
||||||
<button v-if="!wapMemberMobile" class="w-[630rpx] h-[88rpx] !bg-[var(--primary-color)] !mx-[0] text-[26rpx] rounded-[44rpx] leading-[88rpx] font-500 !text-[#fff]" :open-type="openType" @getphonenumber="mobileAuth" @click="checkWxPrivacy">{{t('quickLoginOrLogout')}}</button>
|
<button v-if="!wapMemberMobile" class="w-[630rpx] h-[88rpx] !bg-[var(--primary-color)] !mx-[0] text-[26rpx] rounded-[44rpx] leading-[88rpx] font-500 !text-[#fff]" :open-type="openType" @getphonenumber="mobileAuth" @click="checkWxPrivacy('mobileAuth')">{{t('quickLoginOrLogout')}}</button>
|
||||||
<button v-else class="w-[630rpx] h-[88rpx] !bg-[var(--primary-color)] !mx-[0] text-[26rpx] rounded-[44rpx] leading-[88rpx] font-500 !text-[#fff]" @click="oneClickLogin()">{{t('quickLoginOrLogout')}}</button>
|
<button v-else class="w-[630rpx] h-[88rpx] !bg-[var(--primary-color)] !mx-[0] text-[26rpx] rounded-[44rpx] leading-[88rpx] font-500 !text-[#fff]" @click="oneClickLogin()">{{t('quickLoginOrLogout')}}</button>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@ -112,6 +112,13 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</uni-popup>
|
</uni-popup>
|
||||||
|
|
||||||
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
|
<information-filling ref="infoFill"></information-filling>
|
||||||
|
<!-- #endif -->
|
||||||
|
|
||||||
|
<!-- 强制绑定手机号 -->
|
||||||
|
<bind-mobile ref="bindMobileRef" />
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -125,6 +132,7 @@
|
|||||||
import { onLoad,onShow } from '@dcloudio/uni-app'
|
import { onLoad,onShow } from '@dcloudio/uni-app'
|
||||||
import { topTabar } from '@/utils/topTabbar'
|
import { topTabar } from '@/utils/topTabbar'
|
||||||
import useSystemStore from '@/stores/system'
|
import useSystemStore from '@/stores/system'
|
||||||
|
import { getMobile } from '@/app/api/member'
|
||||||
|
|
||||||
let menuButtonInfo: any = {};
|
let menuButtonInfo: any = {};
|
||||||
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API,尚未兼容)
|
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API,尚未兼容)
|
||||||
@ -163,16 +171,26 @@
|
|||||||
});
|
});
|
||||||
const loginLoading = ref(false)
|
const loginLoading = ref(false)
|
||||||
|
|
||||||
|
const infoFill: any = ref(false)
|
||||||
|
|
||||||
const popupRef = ref()
|
const popupRef = ref()
|
||||||
|
|
||||||
const dialogClose =()=>{
|
const dialogClose =()=>{
|
||||||
popupRef.value.close();
|
popupRef.value.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
const dialogConfirm =()=> {
|
const dialogConfirm =()=> {
|
||||||
isAgree.value = true
|
isAgree.value = true
|
||||||
popupRef.value.close();
|
popupRef.value.close();
|
||||||
oneClickLogin()
|
oneClickLogin()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 强制绑定手机号
|
||||||
|
const bindMobileRef: any = ref(null)
|
||||||
|
const bindMobileFn = () =>{
|
||||||
|
bindMobileRef.value.open()
|
||||||
|
}
|
||||||
|
|
||||||
onLoad(async ()=> {
|
onLoad(async ()=> {
|
||||||
await systemStore.getSiteInfoFn()
|
await systemStore.getSiteInfoFn()
|
||||||
await configStore.getLoginConfig()
|
await configStore.getLoginConfig()
|
||||||
@ -230,17 +248,21 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 检测是否同意小程序隐私协议和登录政策协议
|
// 检测是否同意小程序隐私协议和登录政策协议
|
||||||
const checkWxPrivacy = ()=> {
|
const checkWxPrivacy = (status: any = '')=> {
|
||||||
if (!isAgree.value && configStore.login.agreement_show) {
|
if (!isAgree.value && configStore.login.agreement_show) {
|
||||||
|
// 针对微信小程序获取手机号特殊处理
|
||||||
|
if (status) {
|
||||||
|
uni.showToast({ title: t('isAgreeTips'), icon: 'none' })
|
||||||
|
} else {
|
||||||
popupRef.value.open();
|
popupRef.value.open();
|
||||||
// uni.showToast({ title: t('isAgreeTips'), icon: 'none' })
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 一键登录
|
// 一键登录
|
||||||
const oneClickLogin = (callback:any = null)=> {
|
const oneClickLogin = (callback:any = null,data:any = null)=> {
|
||||||
if (checkWxPrivacy()) return;
|
if (checkWxPrivacy()) return;
|
||||||
|
|
||||||
if (loginLoading.value) return
|
if (loginLoading.value) return
|
||||||
@ -258,21 +280,40 @@
|
|||||||
|
|
||||||
// 第三方平台自动登录
|
// 第三方平台自动登录
|
||||||
// #ifdef MP
|
// #ifdef MP
|
||||||
weappLogin(callback)
|
weappLogin(callback, data)
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// 微信公众登录
|
// 微信公众登录
|
||||||
const wechatLogin = ()=> {
|
const wechatLogin = ()=> {
|
||||||
if (isWeixinBrowser()) {
|
if (isWeixinBrowser()) {
|
||||||
login.getAuthCode({ scopes : 'snsapi_userinfo' })
|
let loginConfig = uni.getStorageSync('login_config')
|
||||||
|
if (loginConfig.is_auth_register) {
|
||||||
|
// 开启强制绑定手机号,必须填写才能注册
|
||||||
|
if (loginConfig.is_bind_mobile) {
|
||||||
|
bindMobileFn();
|
||||||
|
} else if (loginConfig.is_force_access_user_info) {
|
||||||
|
// 开启强制获取用户信息
|
||||||
|
login.getAuthCode({ scopes: 'snsapi_userinfo' }) // 强制获取用户信息
|
||||||
|
} else if (!loginConfig.is_force_access_user_info) {
|
||||||
|
// 关闭强制获取用户信息,昵称随机生成
|
||||||
|
login.getAuthCode({ scopes: 'snsapi_base' }) // 静默获取
|
||||||
|
}
|
||||||
|
}
|
||||||
loginLoading.value = false
|
loginLoading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 微信小程序登录
|
// 微信小程序登录
|
||||||
const weappLogin = (successCallback: any)=> {
|
const weappLogin = (successCallback: any,data: any)=> {
|
||||||
login.getAuthCode({ backFlag: true, successCallback })
|
let loginConfig = uni.getStorageSync('login_config')
|
||||||
|
if(loginConfig.is_auth_register && loginConfig.is_force_access_user_info) {
|
||||||
|
infoFill.value.show = true
|
||||||
|
loginLoading.value = false
|
||||||
|
}else {
|
||||||
|
data = data || {};
|
||||||
|
login.getAuthCode({ backFlag: true, successCallback, ...data })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const agreeChange = () => {
|
const agreeChange = () => {
|
||||||
@ -288,7 +329,7 @@
|
|||||||
uni.setStorageSync('wap_member_mobile', memberInfo.value.mobile) // 存储会员手机号,防止重复请求微信获取手机号接口
|
uni.setStorageSync('wap_member_mobile', memberInfo.value.mobile) // 存储会员手机号,防止重复请求微信获取手机号接口
|
||||||
}
|
}
|
||||||
loginLoading.value = false
|
loginLoading.value = false
|
||||||
});
|
}, { mobile_code: e.detail.code });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.detail.errno == 104) {
|
if (e.detail.errno == 104) {
|
||||||
|
|||||||
@ -98,7 +98,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, computed, onMounted,nextTick } from 'vue'
|
import { ref, reactive, computed, onMounted } from 'vue'
|
||||||
import { usernameLogin, mobileLogin } from '@/app/api/auth'
|
import { usernameLogin, mobileLogin } from '@/app/api/auth'
|
||||||
import useMemberStore from '@/stores/member'
|
import useMemberStore from '@/stores/member'
|
||||||
import useConfigStore from '@/stores/config'
|
import useConfigStore from '@/stores/config'
|
||||||
@ -128,17 +128,21 @@
|
|||||||
const isShowQuickLogin = ref(false) // 是否显示快捷登录
|
const isShowQuickLogin = ref(false) // 是否显示快捷登录
|
||||||
const popupRef = ref()
|
const popupRef = ref()
|
||||||
const isPassword = ref(true)
|
const isPassword = ref(true)
|
||||||
|
|
||||||
const changePassword =()=>{
|
const changePassword =()=>{
|
||||||
isPassword.value = !isPassword.value
|
isPassword.value = !isPassword.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const dialogClose =()=>{
|
const dialogClose =()=>{
|
||||||
popupRef.value.close();
|
popupRef.value.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
const dialogConfirm =()=>{
|
const dialogConfirm =()=>{
|
||||||
isAgree.value=true
|
isAgree.value=true
|
||||||
popupRef.value.close();
|
popupRef.value.close();
|
||||||
handleLogin()
|
handleLogin()
|
||||||
}
|
}
|
||||||
|
|
||||||
onLoad(async (option: any)=> {
|
onLoad(async (option: any)=> {
|
||||||
await configStore.getLoginConfig()
|
await configStore.getLoginConfig()
|
||||||
if (!getToken() && !configStore.login.is_username && !configStore.login.is_mobile) {
|
if (!getToken() && !configStore.login.is_username && !configStore.login.is_mobile) {
|
||||||
|
|||||||
@ -26,14 +26,13 @@
|
|||||||
<view class="px-[20rpx] box-border">
|
<view class="px-[20rpx] box-border">
|
||||||
<button class="bg-[#FFB4B1] !text-[#fff] h-[80rpx] leading-[80rpx] rounded-[100rpx] text-[26rpx] font-500" hover-class="none" v-if="friendsInfo.status == 2 ">{{ t('finish') }}</button>
|
<button class="bg-[#FFB4B1] !text-[#fff] h-[80rpx] leading-[80rpx] rounded-[100rpx] text-[26rpx] font-500" hover-class="none" v-if="friendsInfo.status == 2 ">{{ t('finish') }}</button>
|
||||||
<button class="bg-[#FFB4B1] !text-[#fff] h-[80rpx] leading-[80rpx] rounded-[100rpx] text-[26rpx] font-500" hover-class="none" v-else-if="friendsInfo.status == -1">{{ t('close') }}</button>
|
<button class="bg-[#FFB4B1] !text-[#fff] h-[80rpx] leading-[80rpx] rounded-[100rpx] text-[26rpx] font-500" hover-class="none" v-else-if="friendsInfo.status == -1">{{ t('close') }}</button>
|
||||||
<button class="primary-btn-bg !text-[#fff] h-[80rpx] leading-[80rpx] rounded-[100rpx] text-[26rpx] font-500" hover-class="none" v-else :loading="operateLoading" @click="save">{{ friendsInfo.config.pay_button_name ? friendsInfo.config.pay_button_name : t('payGenerously') }}</button>
|
<button class="botton-color !text-[#fff] h-[80rpx] leading-[80rpx] rounded-[100rpx] text-[26rpx] font-500" hover-class="none" v-else :loading="operateLoading" @click="save">{{ friendsInfo.config.pay_button_name ? friendsInfo.config.pay_button_name : t('payGenerously') }}</button>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-[20rpx] flex items-baseline justify-center text-[var(--text-color-light9)]" @click="redirect({url: '/app/pages/index/index'})">
|
<view class="mt-[20rpx] flex items-baseline justify-center text-[var(--text-color-light9)]" @click="redirect({url: '/app/pages/index/index'})">
|
||||||
<text class="text-[24rpx] mr-[6rpx]">返回首页</text>
|
<text class="text-[24rpx] mr-[6rpx]">返回首页</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="card-template sidebar-margin mb-[var(--top-m)]">
|
<view class="card-template sidebar-margin mb-[var(--top-m)]" v-if="friendsInfo.config.pay_info_switch">
|
||||||
<template v-if="friendsInfo.config.pay_info_switch">
|
|
||||||
<template v-if="JSON.stringify(friendsInfo.trade_info) !== '[]' && friendsInfo.trade_info.item_list.length">
|
<template v-if="JSON.stringify(friendsInfo.trade_info) !== '[]' && friendsInfo.trade_info.item_list.length">
|
||||||
<view class="flex justify-between items-center mb-[30rpx]">
|
<view class="flex justify-between items-center mb-[30rpx]">
|
||||||
<view class="text-[30rpx] text-[#333] font-500">{{ t('helpPayInfo') }}</view>
|
<view class="text-[30rpx] text-[#333] font-500">{{ t('helpPayInfo') }}</view>
|
||||||
@ -72,7 +71,6 @@
|
|||||||
<template v-else>
|
<template v-else>
|
||||||
<view class="text-[28rpx] leading-[40rpx] text-[#333]">{{ friendsInfo.body }}</view>
|
<view class="text-[28rpx] leading-[40rpx] text-[#333]">{{ friendsInfo.body }}</view>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- 帮付说明 -->
|
<!-- 帮付说明 -->
|
||||||
@ -216,4 +214,7 @@ const save = () =>{
|
|||||||
transform: translateX(-50%) translateY(-50%) rotate(45deg);
|
transform: translateX(-50%) translateY(-50%) rotate(45deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.botton-color{
|
||||||
|
background: linear-gradient( 94deg, #FB7939 0%, #FE120E 99%), #EF000C;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
<view class="px-[20rpx] box-border">
|
<view class="px-[20rpx] box-border">
|
||||||
<button class="bg-[#FFB4B1] !text-[#fff] h-[80rpx] leading-[80rpx] rounded-[100rpx] text-[26rpx] font-500" hover-class="none" v-if="friendsInfo.status == 2">{{ t('finish') }}</button>
|
<button class="bg-[#FFB4B1] !text-[#fff] h-[80rpx] leading-[80rpx] rounded-[100rpx] text-[26rpx] font-500" hover-class="none" v-if="friendsInfo.status == 2">{{ t('finish') }}</button>
|
||||||
<button class="bg-[#FFB4B1] !text-[#fff] h-[80rpx] leading-[80rpx] rounded-[100rpx] text-[26rpx] font-500" hover-class="none" v-else-if="friendsInfo.status == -1">{{ t('close') }}</button>
|
<button class="bg-[#FFB4B1] !text-[#fff] h-[80rpx] leading-[80rpx] rounded-[100rpx] text-[26rpx] font-500" hover-class="none" v-else-if="friendsInfo.status == -1">{{ t('close') }}</button>
|
||||||
<button class="primary-btn-bg !text-[#fff] h-[80rpx] leading-[80rpx] rounded-[100rpx] text-[26rpx] font-500" hover-class="none" v-else :loading="operateLoading" @click="openShareFn">{{ friendsInfo.config.pay_type_name ? friendsInfo.config.pay_type_name : t('friendPay') }}</button>
|
<button class="botton-color !text-[#fff] h-[80rpx] leading-[80rpx] rounded-[100rpx] text-[26rpx] font-500" hover-class="none" v-else :loading="operateLoading" @click="openShareFn">{{ friendsInfo.config.pay_type_name ? friendsInfo.config.pay_type_name : t('friendPay') }}</button>
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-[20rpx] flex items-baseline justify-center text-[var(--text-color-light9)]" v-if="friendsInfo.status == 2 && JSON.stringify(friendsInfo.trade_info) !== '[]' && friendsInfo.trade_info.detail_url" @click="redirect({url: friendsInfo.trade_info.detail_url })">
|
<view class="mt-[20rpx] flex items-baseline justify-center text-[var(--text-color-light9)]" v-if="friendsInfo.status == 2 && JSON.stringify(friendsInfo.trade_info) !== '[]' && friendsInfo.trade_info.detail_url" @click="redirect({url: friendsInfo.trade_info.detail_url })">
|
||||||
<text class="text-[24rpx] mr-[6rpx]">查看订单</text>
|
<text class="text-[24rpx] mr-[6rpx]">查看订单</text>
|
||||||
@ -182,7 +182,19 @@ const getFriendspayInfoFn = (tradeType : string, tradeId : number) => {
|
|||||||
share.title = `${name}希望你帮他付${friendsInfo.value.money}元`
|
share.title = `${name}希望你帮他付${friendsInfo.value.money}元`
|
||||||
}
|
}
|
||||||
if(JSON.stringify(friendsInfo.value.trade_info) !== '[]' && friendsInfo.value.trade_info.item_list.length){
|
if(JSON.stringify(friendsInfo.value.trade_info) !== '[]' && friendsInfo.value.trade_info.item_list.length){
|
||||||
share.url = friendsInfo.value.trade_info.item_list[0].item_image
|
// #ifdef H5
|
||||||
|
share.url = friendsInfo.value.trade_info.item_list[0].item_image ? friendsInfo.value.trade_info.item_list[0].item_image : friendsInfo.value.config.pay_wechat_share_image
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
share.url = friendsInfo.value.trade_info.item_list[0].item_image ? friendsInfo.value.trade_info.item_list[0].item_image : friendsInfo.value.config.pay_weapp_share_image
|
||||||
|
// #endif
|
||||||
|
}else{
|
||||||
|
// #ifdef H5
|
||||||
|
share.url = friendsInfo.value.config.pay_wechat_share_image
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
share.url = friendsInfo.value.config.pay_weapp_share_image
|
||||||
|
// #endif
|
||||||
}
|
}
|
||||||
setShare({
|
setShare({
|
||||||
wechat: {
|
wechat: {
|
||||||
@ -258,4 +270,7 @@ const openShareFn = ()=>{
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
.botton-color{
|
||||||
|
background: linear-gradient( 94deg, #FB7939 0%, #FE120E 99%), #EF000C;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -6,16 +6,9 @@
|
|||||||
<view v-show="!diy.getLoading()">
|
<view v-show="!diy.getLoading()">
|
||||||
|
|
||||||
<!-- 自定义模板渲染 -->
|
<!-- 自定义模板渲染 -->
|
||||||
<view class="diy-template-wrap bg-index" v-if="diy.data.pageMode != 'fixed'" :style="diy.pageStyle()">
|
<view class="diy-template-wrap bg-index" :style="diy.pageStyle()">
|
||||||
|
|
||||||
<diy-group ref="diyGroupRef" :data="diy.data" :pullDownRefreshCount="diy.pullDownRefreshCount" />
|
<diy-group ref="diyGroupRef" :data="diy.data" />
|
||||||
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 固定模板渲染 -->
|
|
||||||
<view class="fixed-template-wrap" v-if="diy.data.pageMode == 'fixed'">
|
|
||||||
|
|
||||||
<fixed-group :data="diy.data" :pullDownRefreshCount="diy.pullDownRefreshCount" />
|
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@ -34,7 +27,6 @@
|
|||||||
import {useDiy} from '@/hooks/useDiy'
|
import {useDiy} from '@/hooks/useDiy'
|
||||||
import {useShare} from '@/hooks/useShare'
|
import {useShare} from '@/hooks/useShare'
|
||||||
import diyGroup from '@/addon/components/diy/group/index.vue'
|
import diyGroup from '@/addon/components/diy/group/index.vue'
|
||||||
import fixedGroup from '@/addon/components/fixed/group/index.vue'
|
|
||||||
|
|
||||||
const {setShare} = useShare()
|
const {setShare} = useShare()
|
||||||
|
|
||||||
@ -65,9 +57,6 @@
|
|||||||
// 监听页面卸载
|
// 监听页面卸载
|
||||||
diy.onUnload();
|
diy.onUnload();
|
||||||
|
|
||||||
// 监听下拉刷新事件
|
|
||||||
diy.onPullDownRefresh()
|
|
||||||
|
|
||||||
// 监听滚动事件
|
// 监听滚动事件
|
||||||
diy.onPageScroll()
|
diy.onPageScroll()
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
118
uni-app/src/app/pages/index/diy_form.vue
Normal file
118
uni-app/src/app/pages/index/diy_form.vue
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
<template>
|
||||||
|
<view :style="themeColor()">
|
||||||
|
|
||||||
|
<loading-page :loading="diy.getLoading()"></loading-page>
|
||||||
|
|
||||||
|
<view v-show="requestData.status == 1 && requestData.error && requestData.error.length === 0 && !diy.getLoading()">
|
||||||
|
|
||||||
|
<!-- 自定义模板渲染 -->
|
||||||
|
<view class="diy-template-wrap bg-index" :style="diy.pageStyle()">
|
||||||
|
|
||||||
|
<diy-group ref="diyGroupRef" :data="diy.data" />
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<view class="w-screen h-screen flex flex-col " v-if="requestData.error && requestData.error.length > 0">
|
||||||
|
<view class="flex-1 flex flex-col items-center pt-[180rpx] px-[60rpx]" v-for="(item, index) in requestData.error.slice(0, 1)" :key="index">
|
||||||
|
<text class="nc-iconfont nc-icon-tanhaoV6mm text-[#ccc] mb-[30rpx] !text-[100rpx]"></text>
|
||||||
|
<view class="text-[38rpx] font-bold mt-3">{{item.title}}</view>
|
||||||
|
<view class="p-[30rpx] mt-10 w-full ">
|
||||||
|
<view class="flex w-full">
|
||||||
|
<view class="w-[30%] text-[#999] text-left">{{item.type}}</view>
|
||||||
|
<view class="w-[70%] text-left">{{item.desc}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="pb-[260rpx]" >
|
||||||
|
<button class="w-[380rpx] !border-0 h-[80rpx] text-[28rpx] text-[#333] !bg-[#f2f2f2] flex-center font-500 rounded-[20rpx]" :plain="true" @click="finishFn">关闭</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
|
<!-- 小程序隐私协议 -->
|
||||||
|
<wx-privacy-popup ref="wxPrivacyPopupRef"></wx-privacy-popup>
|
||||||
|
<!-- #endif -->
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {ref,nextTick,computed} from 'vue';
|
||||||
|
import {useDiyForm} from '@/hooks/useDiyForm'
|
||||||
|
import {useShare} from '@/hooks/useShare'
|
||||||
|
import { img,redirect} from '@/utils/common';
|
||||||
|
import diyGroup from '@/addon/components/diy/group/index.vue'
|
||||||
|
import MescrollEmpty from '@/components/mescroll/mescroll-empty/mescroll-empty.vue';
|
||||||
|
|
||||||
|
const {setShare} = useShare()
|
||||||
|
|
||||||
|
const diy = useDiyForm({
|
||||||
|
needLogin: true // 检测登录
|
||||||
|
})
|
||||||
|
|
||||||
|
const diyGroupRef = ref(null)
|
||||||
|
|
||||||
|
const wxPrivacyPopupRef:any = ref(null)
|
||||||
|
|
||||||
|
const requestData = computed(()=>{
|
||||||
|
return diy.requestData;
|
||||||
|
})
|
||||||
|
|
||||||
|
const finishFn = () => {
|
||||||
|
redirect({
|
||||||
|
url: '/app/pages/index/index',
|
||||||
|
mode: 'reLaunch'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
diy.onLoad((data:any)=>{
|
||||||
|
let share = data.share ? data.share : null;
|
||||||
|
setShare(share);
|
||||||
|
diyGroupRef.value?.refresh();
|
||||||
|
// #ifdef MP
|
||||||
|
nextTick(()=>{
|
||||||
|
if(wxPrivacyPopupRef.value) wxPrivacyPopupRef.value.proactive();
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
});
|
||||||
|
|
||||||
|
// 监听页面显示
|
||||||
|
diy.onShow((data: any) => {
|
||||||
|
let share = data.share ? data.share : null;
|
||||||
|
if(share) {
|
||||||
|
setShare(share);
|
||||||
|
}
|
||||||
|
diyGroupRef.value?.refresh();
|
||||||
|
// #ifdef MP
|
||||||
|
nextTick(()=>{
|
||||||
|
if(wxPrivacyPopupRef.value) wxPrivacyPopupRef.value.proactive();
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
});
|
||||||
|
|
||||||
|
// 监听页面隐藏
|
||||||
|
diy.onHide();
|
||||||
|
|
||||||
|
// 监听页面卸载
|
||||||
|
diy.onUnload();
|
||||||
|
|
||||||
|
// 监听滚动事件
|
||||||
|
diy.onPageScroll()
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/styles/diy.scss';
|
||||||
|
</style>
|
||||||
|
<style lang="scss">
|
||||||
|
.diy-template-wrap {
|
||||||
|
/* #ifdef MP */
|
||||||
|
.child-diy-template-wrap {
|
||||||
|
::v-deep .diy-group {
|
||||||
|
> .draggable-element.top-fixed-diy {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
</style>
|
||||||
28
uni-app/src/app/pages/index/diy_form_detail.vue
Normal file
28
uni-app/src/app/pages/index/diy_form_detail.vue
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<template>
|
||||||
|
<view :style="themeColor()">
|
||||||
|
<view class="w-screen h-screen bg-[var(--page-bg-color)] min-h-[100vh]">
|
||||||
|
<view class="bg-white p-3">
|
||||||
|
<view class="text-[30rpx] font-500 leading-[45rpx]">详细信息</view>
|
||||||
|
<u-divider text=""></u-divider>
|
||||||
|
<!-- 动态渲染表单组件详情 -->
|
||||||
|
<diy-form-detail :record_id="recordId" completeLayout="style-1" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import { t } from '@/locale'
|
||||||
|
import diyFormDetail from '@/addon/components/diy-form-detail/index.vue'
|
||||||
|
|
||||||
|
const recordId = ref(0)
|
||||||
|
onLoad((data : any) => {
|
||||||
|
recordId.value = data.record_id
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
83
uni-app/src/app/pages/index/diy_form_result.vue
Normal file
83
uni-app/src/app/pages/index/diy_form_result.vue
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<template>
|
||||||
|
<view :style="themeColor()">
|
||||||
|
<view class="w-screen h-screen flex flex-col items-center" v-if="recordInfo">
|
||||||
|
<top-tabbar ref="topTabbarRef" :data="topTabbarParam" />
|
||||||
|
<view class="flex-1 flex flex-col items-center w-full pt-[180rpx]">
|
||||||
|
<text class="nc-iconfont nc-icon-duihaoV6mm text-[#06ae56] mb-[30rpx] !text-[65rpx]"></text>
|
||||||
|
<view class="px-[30rpx] text-center leading-[1.3] text-[42rpx] font-bold mb-[30rpx]">
|
||||||
|
{{ recordInfo.submitConfig.tips_type=='default' ? '填写成功' : recordInfo.submitConfig.tips_text }}
|
||||||
|
</view>
|
||||||
|
<view class="text-[32rpx] mt-[32rpx] text-[#576b95]" @click="toDetail()">查看填写详情</view>
|
||||||
|
</view>
|
||||||
|
<view class="pb-[260rpx] action-wrap">
|
||||||
|
<template v-if="recordInfo.submitConfig.success_after_action.finish">
|
||||||
|
<button class="w-[380rpx] !border-0 h-[80rpx] text-[28rpx] !text-[#ffffff] !bg-[#20bf64] flex-center font-500 rounded-[6rpx]" :plain="true" @click="finishFn">完成</button>
|
||||||
|
</template>
|
||||||
|
<template v-if="recordInfo.submitConfig.success_after_action.goback">
|
||||||
|
<button class="w-[380rpx] !border-0 h-[80rpx] text-[28rpx] text-[#333] !bg-[#f2f2f2] flex-center font-500 rounded-[6rpx]" :plain="true" @click="goback">返回</button>
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import { getFormResultInfo } from '@/app/api/diy_form';
|
||||||
|
import { t } from '@/locale'
|
||||||
|
import { redirect } from '@/utils/common'
|
||||||
|
import { topTabar } from '@/utils/topTabbar'
|
||||||
|
|
||||||
|
const recordInfo = ref<AnyObject | null>(null)
|
||||||
|
const recordId = ref(0)
|
||||||
|
const formId = ref(0)
|
||||||
|
|
||||||
|
/********* 自定义头部 - start ***********/
|
||||||
|
const topTabarObj = topTabar()
|
||||||
|
let topTabbarParam = topTabarObj.setTopTabbarParam({title:'',isBack:false})
|
||||||
|
/********* 自定义头部 - end ***********/
|
||||||
|
|
||||||
|
onLoad((data : any) => {
|
||||||
|
recordId.value = data.record_id || 0;
|
||||||
|
formId.value = data.form_id || 0;
|
||||||
|
getInfo()
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取表单填写信息
|
||||||
|
*/
|
||||||
|
const getInfo = () => {
|
||||||
|
getFormResultInfo({
|
||||||
|
record_id: recordId.value
|
||||||
|
}).then((res: any) => {
|
||||||
|
recordInfo.value = res.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const toDetail = ()=>{
|
||||||
|
redirect({ url: '/app/pages/index/diy_form_detail',param: { record_id: recordId.value }, mode: 'redirectTo' })
|
||||||
|
}
|
||||||
|
|
||||||
|
const finishFn = () => {
|
||||||
|
redirect({
|
||||||
|
url: '/app/pages/index/index',
|
||||||
|
mode: 'reLaunch'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const goback = ()=>{
|
||||||
|
redirect({ url: '/app/pages/index/diy_form',param: { form_id: formId.value }, mode: 'redirectTo' })
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.action-wrap{
|
||||||
|
button{
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
&:last-child{
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -6,16 +6,9 @@
|
|||||||
<view v-show="!diy.getLoading()">
|
<view v-show="!diy.getLoading()">
|
||||||
|
|
||||||
<!-- 自定义模板渲染 -->
|
<!-- 自定义模板渲染 -->
|
||||||
<view class="diy-template-wrap bg-index" v-if="diy.data.pageMode != 'fixed'" :style="diy.pageStyle()">
|
<view class="diy-template-wrap bg-index" :style="diy.pageStyle()">
|
||||||
|
|
||||||
<diy-group ref="diyGroupRef" :data="diy.data" :pullDownRefreshCount="diy.pullDownRefreshCount" />
|
<diy-group ref="diyGroupRef" :data="diy.data" />
|
||||||
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 固定模板渲染 -->
|
|
||||||
<view class="fixed-template-wrap" v-if="diy.data.pageMode == 'fixed'">
|
|
||||||
|
|
||||||
<fixed-group :data="diy.data" :pullDownRefreshCount="diy.pullDownRefreshCount" />
|
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@ -34,9 +27,6 @@
|
|||||||
import {useDiy} from '@/hooks/useDiy'
|
import {useDiy} from '@/hooks/useDiy'
|
||||||
import {redirect} from '@/utils/common';
|
import {redirect} from '@/utils/common';
|
||||||
import diyGroup from '@/addon/components/diy/group/index.vue'
|
import diyGroup from '@/addon/components/diy/group/index.vue'
|
||||||
import fixedGroup from '@/addon/components/fixed/group/index.vue'
|
|
||||||
|
|
||||||
uni.hideTabBar() // 隐藏tabbar
|
|
||||||
|
|
||||||
const diy = useDiy({
|
const diy = useDiy({
|
||||||
name: 'DIY_INDEX'
|
name: 'DIY_INDEX'
|
||||||
@ -73,9 +63,6 @@
|
|||||||
// 监听页面卸载
|
// 监听页面卸载
|
||||||
diy.onUnload();
|
diy.onUnload();
|
||||||
|
|
||||||
// 监听下拉刷新事件
|
|
||||||
diy.onPullDownRefresh()
|
|
||||||
|
|
||||||
// 监听滚动事件
|
// 监听滚动事件
|
||||||
diy.onPageScroll()
|
diy.onPageScroll()
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -8,10 +8,11 @@
|
|||||||
<view class="flex items-center">
|
<view class="flex items-center">
|
||||||
<view class="w-[80rpx] h-[80rpx] flex items-center justify-center" @click="handleClick(item)">
|
<view class="w-[80rpx] h-[80rpx] flex items-center justify-center" @click="handleClick(item)">
|
||||||
<image class="w-[80rpx] h-[52rpx] align-middle" :src="img('static/resource/images/member/apply_withdrawal/bank-icon.png')" mode="widthFix" v-if="item.account_type == 'bank'" />
|
<image class="w-[80rpx] h-[52rpx] align-middle" :src="img('static/resource/images/member/apply_withdrawal/bank-icon.png')" mode="widthFix" v-if="item.account_type == 'bank'" />
|
||||||
|
<image class="w-[80rpx] h-[52rpx] align-middle" :src="img('static/resource/images/member/apply_withdrawal/wechat_code.png')" mode="widthFix" v-else-if="item.account_type == 'wechat_code'" />
|
||||||
<image class="h-[78rpx] w-[78rpx] align-middle" v-else :src="img('static/resource/images/member/apply_withdrawal/alipay-icon.png')" mode="widthFix" />
|
<image class="h-[78rpx] w-[78rpx] align-middle" v-else :src="img('static/resource/images/member/apply_withdrawal/alipay-icon.png')" mode="widthFix" />
|
||||||
</view>
|
</view>
|
||||||
<view class="flex flex-col ml-[20rpx]" @click="handleClick(item)">
|
<view class="flex flex-col ml-[20rpx]" @click="handleClick(item)">
|
||||||
<view class="text-[#333] text-[28rpx]">{{ item.account_type == 'bank' ? item.bank_name : t('alipayAccountNo') }}</view>
|
<view class="text-[#333] text-[28rpx]">{{ item.account_type == 'bank' ? item.bank_name : item.account_type == 'wechat_code'?t('wechatCode') : t('alipayAccountNo') }}</view>
|
||||||
<view v-if="item.account_type == 'bank'" class="text-[var(--text-color-light9)] text-[24rpx] mt-[12rpx]">{{ t('endNumber') }} {{ item.account_no.substring(item.account_no.length - 4) }}{{ t('bankCard') }}</view>
|
<view v-if="item.account_type == 'bank'" class="text-[var(--text-color-light9)] text-[24rpx] mt-[12rpx]">{{ t('endNumber') }} {{ item.account_no.substring(item.account_no.length - 4) }}{{ t('bankCard') }}</view>
|
||||||
<view v-else class="text-[var(--text-color-light9)] text-[24rpx] mt-[12rpx]">{{ item.account_no }}</view>
|
<view v-else class="text-[var(--text-color-light9)] text-[24rpx] mt-[12rpx]">{{ item.account_no }}</view>
|
||||||
</view>
|
</view>
|
||||||
@ -23,7 +24,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="card-template sidebar-margin my-[var(--top-m)] flex items-center" @click="redirect({ url: '/app/pages/member/account_edit', param: { type: accountType, mode } })">
|
<view class="card-template sidebar-margin my-[var(--top-m)] flex items-center" @click="redirect({ url: '/app/pages/member/account_edit', param: { type: accountType, mode } })">
|
||||||
<text class="nc-iconfont nc-icon-jiahaoV6xx text-[30rpx]"></text>
|
<text class="nc-iconfont nc-icon-jiahaoV6xx text-[30rpx]"></text>
|
||||||
<text class="text-[28rpx] ml-[10rpx] flex-1">{{ accountType == 'bank' ? t('addBankCard') : t('addAlipayAccount') }}</text>
|
<text class="text-[28rpx] ml-[10rpx] flex-1">{{ accountType == 'bank' ? t('addBankCard') : accountType == 'wechat_code' ? t('addWechatCode') : t('addAlipayAccount') }}</text>
|
||||||
<text class="nc-iconfont nc-icon-youV6xx text-[24rpx] text-[var(--text-color-light6)]"></text>
|
<text class="nc-iconfont nc-icon-youV6xx text-[24rpx] text-[var(--text-color-light6)]"></text>
|
||||||
</view>
|
</view>
|
||||||
</mescroll-body>
|
</mescroll-body>
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
<block v-if="formData.account_type == 'alipay'">
|
<block 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-[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>
|
<!-- <view class="text-center text-[28rpx] mt-[16rpx] text-[var(--text-color-light9)] leading-[36rpx]">{{ formData.account_id ? t('editAlipayAccountTips') : t('addAlipayAccountTips') }}</view> -->
|
||||||
|
|
||||||
<view class="mt-[70rpx] px-[10rpx]">
|
<view class="mt-[70rpx] px-[10rpx]">
|
||||||
<u-form labelPosition="left" :model="formData" labelWidth="200rpx" errorType='toast' :rules="rules" ref="formRef">
|
<u-form labelPosition="left" :model="formData" labelWidth="200rpx" errorType='toast' :rules="rules" ref="formRef">
|
||||||
@ -41,6 +41,48 @@
|
|||||||
<u-form-item :label="t('alipayAccountNo')" prop="account_no">
|
<u-form-item :label="t('alipayAccountNo')" prop="account_no">
|
||||||
<u-input v-model.trim="formData.account_no" border="none" maxlength="30" fontSize="28rpx" clearable :placeholder="t('alipayAccountNoPlaceholder')"/>
|
<u-input v-model.trim="formData.account_no" border="none" maxlength="30" fontSize="28rpx" clearable :placeholder="t('alipayAccountNoPlaceholder')"/>
|
||||||
</u-form-item>
|
</u-form-item>
|
||||||
|
</view>
|
||||||
|
<view class="mt-[16rpx]">
|
||||||
|
<u-form-item label="收款码" prop="transfer_payment_code">
|
||||||
|
<view class="relative w-[160rpx] h-[160rpx]" v-if="formData.transfer_payment_code">
|
||||||
|
<image class="w-[160rpx] h-[160rpx]" :src="img(formData.transfer_payment_code)" mode="aspectFill" @click="previewImageFn(img(formData.transfer_payment_code))"></image>
|
||||||
|
<view class="absolute top-0 right-0 bg-[#373737] flex justify-end h-[28rpx] w-[28rpx] rounded-bl-[40rpx]" @click="collectionCodeDeleteFn">
|
||||||
|
<text class="nc-iconfont nc-icon-guanbiV6xx !text-[20rpx] mt-[2rpx] mr-[2rpx] text-[#fff]"></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<u-upload v-else @afterRead="collectionCodeAfterRead" @delete="collectionCodeDeleteFn" :maxCount="1"></u-upload>
|
||||||
|
</u-form-item>
|
||||||
|
</view>
|
||||||
|
</u-form>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
|
||||||
|
<block 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> -->
|
||||||
|
|
||||||
|
<view class="mt-[70rpx] px-[10rpx]">
|
||||||
|
<u-form labelPosition="left" :model="formData" labelWidth="200rpx" errorType='toast' :rules="rules" ref="formRef">
|
||||||
|
<view>
|
||||||
|
<u-form-item :label="t('alipayRealname')" prop="realname">
|
||||||
|
<u-input v-model.trim="formData.realname" maxlength="30" border="none" fontSize="28rpx" clearable :placeholder="t('alipayRealnamePlaceholder')"/>
|
||||||
|
</u-form-item>
|
||||||
|
</view>
|
||||||
|
<view class="mt-[16rpx]">
|
||||||
|
<u-form-item :label="t('wechatCodeAccountNo')" prop="account_no">
|
||||||
|
<u-input v-model.trim="formData.account_no" border="none" maxlength="30" fontSize="28rpx" clearable :placeholder="t('wechatCodeAccountNoPlaceholder')"/>
|
||||||
|
</u-form-item>
|
||||||
|
</view>
|
||||||
|
<view class="mt-[16rpx]">
|
||||||
|
<u-form-item label="收款码" prop="transfer_payment_code">
|
||||||
|
<view class="relative w-[160rpx] h-[160rpx]" v-if="formData.transfer_payment_code">
|
||||||
|
<image class="w-[160rpx] h-[160rpx]" :src="img(formData.transfer_payment_code)" mode="aspectFill" @click="previewImageFn(img(formData.transfer_payment_code))"></image>
|
||||||
|
<view class="absolute top-0 right-0 bg-[#373737] flex justify-end h-[28rpx] w-[28rpx] rounded-bl-[40rpx]" @click="collectionCodeDeleteFn">
|
||||||
|
<text class="nc-iconfont nc-icon-guanbiV6xx !text-[20rpx] mt-[2rpx] mr-[2rpx] text-[#fff]"></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<u-upload v-else @afterRead="collectionCodeAfterRead" @delete="collectionCodeDeleteFn" :maxCount="1"></u-upload>
|
||||||
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
</u-form>
|
</u-form>
|
||||||
</view>
|
</view>
|
||||||
@ -61,7 +103,8 @@
|
|||||||
import { onLoad } from '@dcloudio/uni-app'
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
import { getCashoutAccountInfo, addCashoutAccount, editCashoutAccount, deleteCashoutAccount } from '@/app/api/member'
|
import { getCashoutAccountInfo, addCashoutAccount, editCashoutAccount, deleteCashoutAccount } from '@/app/api/member'
|
||||||
import { t } from '@/locale'
|
import { t } from '@/locale'
|
||||||
import { redirect } from '@/utils/common'
|
import { uploadImage } from '@/app/api/system'
|
||||||
|
import { redirect, img } from '@/utils/common'
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const formRef: any = ref(null)
|
const formRef: any = ref(null)
|
||||||
@ -72,7 +115,8 @@
|
|||||||
account_type: 'bank',
|
account_type: 'bank',
|
||||||
bank_name: '',
|
bank_name: '',
|
||||||
realname: '',
|
realname: '',
|
||||||
account_no: ''
|
account_no: '',
|
||||||
|
transfer_payment_code: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
const rules = computed(() => {
|
const rules = computed(() => {
|
||||||
@ -89,11 +133,15 @@
|
|||||||
message: t('bankNamePlaceholder'),
|
message: t('bankNamePlaceholder'),
|
||||||
trigger: ['blur', 'change'],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
'account_no': {
|
'transfer_payment_code': {
|
||||||
type: 'string',
|
validator(rule, value, callback) {
|
||||||
required: true,
|
if (!value || !value.length){
|
||||||
message: formData.account_type == 'bank' ? t('bankAccountNoPlaceholder') : t('alipayAccountNoPlaceholder'),
|
let tips = formData.account_type == 'alipay' ? t('alipayAccountImgPlaceholder') : t('wechatCodeAccountImgPlaceholder');
|
||||||
trigger: ['blur', 'change'],
|
callback(new Error(tips))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -139,11 +187,37 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const collectionCodeAfterRead = (e)=>{
|
||||||
|
uploadImage({
|
||||||
|
filePath: e.file.url,
|
||||||
|
name: 'file'
|
||||||
|
}).then(res => {
|
||||||
|
if(res.data){
|
||||||
|
formData.transfer_payment_code = '';
|
||||||
|
formData.transfer_payment_code = res.data.url;
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除图片
|
||||||
|
const collectionCodeDeleteFn = (e) =>{
|
||||||
|
formData.transfer_payment_code = '';
|
||||||
|
}
|
||||||
|
|
||||||
const handleDelete = () => {
|
const handleDelete = () => {
|
||||||
deleteCashoutAccount(formData.account_id).then(() => {
|
deleteCashoutAccount(formData.account_id).then(() => {
|
||||||
redirect({ url: '/app/pages/member/account', mode: 'redirectTo' })
|
redirect({ url: '/app/pages/member/account', mode: 'redirectTo' })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 预览
|
||||||
|
const previewImageFn = (url:any) => {
|
||||||
|
uni.previewImage({
|
||||||
|
current: 0,
|
||||||
|
urls: [url]
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -18,16 +18,16 @@
|
|||||||
<view v-if="!formData.area" class="text-[#888] text-[28rpx] flex-1">{{ t('selectAreaPlaceholder') }}</view>
|
<view v-if="!formData.area" class="text-[#888] text-[28rpx] flex-1">{{ t('selectAreaPlaceholder') }}</view>
|
||||||
<view v-else class="text-[28rpx] flex-1 leading-[1.4]">{{ formData.area }}</view>
|
<view v-else class="text-[28rpx] flex-1 leading-[1.4]">{{ formData.area }}</view>
|
||||||
<view @click.stop="chooseLocation" class="flex items-center">
|
<view @click.stop="chooseLocation" class="flex items-center">
|
||||||
<text class="nc-iconfont nc-icon-dizhiguanliV6xx mr-[4rpx] text-[32rpx] text-[#e93323]"></text>
|
<text class="nc-iconfont nc-icon-dizhiguanliV6xx mr-[4rpx] text-[32rpx] text-[var(--primary-color)]"></text>
|
||||||
<text class="text-[24rpx] whitespace-nowrap text-[#e93323]">定位</text>
|
<text class="text-[24rpx] whitespace-nowrap text-[var(--primary-color)]">定位</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-else class="flex justify-between items-center flex-1 h-[52rpx]" @click="chooseLocation">
|
<view v-else class="flex justify-between items-center flex-1 h-[52rpx]" @click="chooseLocation">
|
||||||
<view class="text-[28rpx] text-[#303133] leading-[1.4]" v-if="formData.area || formData.address_name">{{formData.area || formData.address_name}}</view>
|
<view class="text-[28rpx] text-[#303133] leading-[1.4]" v-if="formData.area || formData.address_name">{{formData.area || formData.address_name}}</view>
|
||||||
<view class="text-[#888] text-[28rpx]" v-else>{{t('selectAddressPlaceholder')}}</view>
|
<view class="text-[#888] text-[28rpx]" v-else>{{t('selectAddressPlaceholder')}}</view>
|
||||||
<view class="flex items-center">
|
<view class="flex items-center">
|
||||||
<text class="nc-iconfont nc-icon-dizhiguanliV6xx text-[32rpx] mr-[4rpx] text-[#e93323]"></text>
|
<text class="nc-iconfont nc-icon-dizhiguanliV6xx text-[32rpx] mr-[4rpx] text-[var(--primary-color)]"></text>
|
||||||
<text class="text-[24rpx] whitespace-nowrap text-[#e93323]">定位</text>
|
<text class="text-[24rpx] whitespace-nowrap text-[var(--primary-color)]">定位</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</u-form-item>
|
</u-form-item>
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
<view class="flex pt-[30rpx] pb-[8rpx] items-center border-0 border-b-[2rpx] border-solid border-[#F1F2F5]">
|
<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>
|
<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-class="apply-price" :adjust-position="false"/>
|
<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-class="apply-price" :adjust-position="false"/>
|
||||||
|
<text v-if="Number(serviceMoney)" class="text-[24rpx] text-[var(--text-color-light6)] mr-[20rpx]">手续费{{ serviceMoney }}</text>
|
||||||
<text @click="clearMoney" v-if="applyData.apply_money" class="nc-iconfont nc-icon-cuohaoV6xx1 !text-[32rpx] text-[var(--text-color-light9)]"></text>
|
<text @click="clearMoney" v-if="applyData.apply_money" class="nc-iconfont nc-icon-cuohaoV6xx1 !text-[32rpx] text-[var(--text-color-light9)]"></text>
|
||||||
</view>
|
</view>
|
||||||
<view class="pt-[16rpx] flex items-center justify-between px-[4rpx]">
|
<view class="pt-[16rpx] flex items-center justify-between px-[4rpx]">
|
||||||
@ -21,7 +22,7 @@
|
|||||||
<view class="mt-[20rpx] card-template">
|
<view class="mt-[20rpx] card-template">
|
||||||
<view class="font-500 text-[30rpx] text-[#333] leading-[42rpx] mb-[30rpx]">到账方式</view>
|
<view class="font-500 text-[30rpx] text-[#333] leading-[42rpx] mb-[30rpx]">到账方式</view>
|
||||||
<!-- 提现到微信 -->
|
<!-- 提现到微信 -->
|
||||||
<view class="p-[20rpx] mb-[20rpx] flex items-center rounded-[var(--rounded-mid)] border-[1rpx] border-solid border-[#eee]" v-if="config.transfer_type.includes('wechatpay') && memberStore.info && (memberStore.info.wx_openid || memberStore.info.weapp_openid)" @click="applyData.transfer_type = 'wechatpay'" :class="{'border-[#00C800] bg-[#ECF9EF]': applyData.transfer_type == 'wechatpay'}">
|
<view class="p-[20rpx] mb-[20rpx] flex items-center rounded-[var(--rounded-mid)] border-[1rpx] border-solid border-[#eee]" v-if="config.transfer_type.includes('wechatpay') && memberStore.info && (memberStore.info.wx_openid || memberStore.info.weapp_openid)" :class="{'border-[#00C800] bg-[#ECF9EF]': applyData.transfer_type == 'wechatpay'}" @click="transferWeixin">
|
||||||
<view>
|
<view>
|
||||||
<image class="h-[60rpx] w-[60rpx]" :src="img('static/resource/images/member/apply_withdrawal/wechat.png')" mode="widthFix" />
|
<image class="h-[60rpx] w-[60rpx]" :src="img('static/resource/images/member/apply_withdrawal/wechat.png')" mode="widthFix" />
|
||||||
</view>
|
</view>
|
||||||
@ -31,6 +32,27 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- 提现到微信收款码 -->
|
||||||
|
<view class="p-[20rpx] mb-[20rpx] flex items-center rounded-[var(--rounded-mid)] border-[1rpx] border-solid border-[#eee]" v-if="config.transfer_type.includes('wechat_code')" :class="{'border-[#00C800] bg-[#ECF9EF]': applyData.transfer_type == 'wechat_code' && wechatCodeInfo}" >
|
||||||
|
<view @click="transferWechatCode" >
|
||||||
|
<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-[var(--text-color-light9)] text-[24rpx] leading-[34rpx]">
|
||||||
|
<view v-if="wechatCodeInfo" class="truncate max-w-[440rpx]">
|
||||||
|
<text>{{ t('cashOutTo') }}{{ t('wechatCodeAccountNo') }}</text>
|
||||||
|
<text class="text-[#333]">{{ wechatCodeInfo.account_no }}</text>
|
||||||
|
</view>
|
||||||
|
<view v-else>{{ t('cashOutToWechatCodeTips') }}</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>
|
||||||
|
<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>
|
||||||
|
</view>
|
||||||
|
|
||||||
<!-- 提现到支付宝 -->
|
<!-- 提现到支付宝 -->
|
||||||
<view class="p-[20rpx] mb-[20rpx] flex items-center rounded-[var(--rounded-mid)] border-[1rpx] border-solid border-[#eee]" v-if="config.transfer_type.includes('alipay')" :class="{'border-[#009FE8] bg-[#EEF8FC]': applyData.transfer_type == 'alipay' && alipayAccountInfo}" >
|
<view class="p-[20rpx] mb-[20rpx] flex items-center rounded-[var(--rounded-mid)] border-[1rpx] border-solid border-[#eee]" v-if="config.transfer_type.includes('alipay')" :class="{'border-[#009FE8] bg-[#EEF8FC]': applyData.transfer_type == 'alipay' && alipayAccountInfo}" >
|
||||||
<view @click="transferAlipay" >
|
<view @click="transferAlipay" >
|
||||||
@ -77,7 +99,7 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="tab-bar-placeholder"></view>
|
<view class="tab-bar-placeholder"></view>
|
||||||
<view class="fixed bottom-[0] tab-bar left-0 right-0 px-[var(--sidebar-m)]">
|
<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">{{t('cashOutNow')}}</button>
|
||||||
<view class="mt-[30rpx] text-center text-[26rpx] text-primary" @click.stop="redirect({ url: '/app/pages/member/cash_out'})">
|
<view class="mt-[30rpx] text-center text-[26rpx] text-primary" @click.stop="redirect({ url: '/app/pages/member/cash_out'})">
|
||||||
{{t('cashOutList')}}
|
{{t('cashOutList')}}
|
||||||
@ -99,7 +121,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive, watch, computed } from 'vue'
|
import { ref, reactive, watch, computed } from 'vue'
|
||||||
import { t } from '@/locale'
|
import { t } from '@/locale'
|
||||||
import { moneyFormat, redirect, getToken ,img, deepClone } from '@/utils/common'
|
import { moneyFormat, redirect, getToken ,img, deepClone, getWinxinOpenId } from '@/utils/common'
|
||||||
import useMemberStore from '@/stores/member'
|
import useMemberStore from '@/stores/member'
|
||||||
import { cashOutConfig, cashOutApply, getFirstCashoutAccountInfo, getCashoutAccountInfo } from '@/app/api/member'
|
import { cashOutConfig, cashOutApply, getFirstCashoutAccountInfo, getCashoutAccountInfo } from '@/app/api/member'
|
||||||
import { onLoad } from '@dcloudio/uni-app'
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
@ -113,7 +135,11 @@
|
|||||||
apply_money: '',
|
apply_money: '',
|
||||||
transfer_type: '',
|
transfer_type: '',
|
||||||
account_type: 'money',
|
account_type: 'money',
|
||||||
account_id: 0
|
account_id: 0,
|
||||||
|
transfer_payee:{
|
||||||
|
open_id: '',
|
||||||
|
channel: ''
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 可提现金额
|
// 可提现金额
|
||||||
@ -129,6 +155,9 @@
|
|||||||
case 'alipay':
|
case 'alipay':
|
||||||
applyData.account_id = alipayAccountInfo.value ? alipayAccountInfo.value.account_id : 0
|
applyData.account_id = alipayAccountInfo.value ? alipayAccountInfo.value.account_id : 0
|
||||||
break;
|
break;
|
||||||
|
case 'wechat_code':
|
||||||
|
applyData.account_id = wechatCodeInfo.value ? wechatCodeInfo.value.account_id : 0
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
applyData.account_id = 0
|
applyData.account_id = 0
|
||||||
}
|
}
|
||||||
@ -181,9 +210,14 @@
|
|||||||
for (let key in deepClone(res.data)) {
|
for (let key in deepClone(res.data)) {
|
||||||
config[key] = deepClone(res.data[key]);
|
config[key] = deepClone(res.data[key]);
|
||||||
}
|
}
|
||||||
if (config.transfer_type.includes('wechatpay') && memberStore.info && (!memberStore.info.wx_openid && !memberStore.info.weapp_openid)) config.transfer_type.splice(config.transfer_type.indexOf('wechatpay'),1)
|
if (config.transfer_type.includes('wechatpay') && memberStore.info && (!memberStore.info.wx_openid && !memberStore.info.weapp_openid)){
|
||||||
|
config.transfer_type.splice(config.transfer_type.indexOf('wechatpay'),1)
|
||||||
|
} else{
|
||||||
|
config.transfer_type.includes('wechatpay') && transferWeixin()
|
||||||
|
}
|
||||||
config.transfer_type.includes('bank') && getBankAccountInfo()
|
config.transfer_type.includes('bank') && getBankAccountInfo()
|
||||||
config.transfer_type.includes('alipay') && getAlipayAccountInfo()
|
config.transfer_type.includes('alipay') && getAlipayAccountInfo()
|
||||||
|
config.transfer_type.includes('wechat_code') && getWechatCodeInfo()
|
||||||
applyData.transfer_type = config.transfer_type[0]
|
applyData.transfer_type = config.transfer_type[0]
|
||||||
if(query.type){
|
if(query.type){
|
||||||
applyData.transfer_type = query.type
|
applyData.transfer_type = query.type
|
||||||
@ -192,6 +226,15 @@
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 手续费
|
||||||
|
const serviceMoney = computed(() => {
|
||||||
|
let money = 0
|
||||||
|
if(applyData.apply_money && Number(config.rate)){
|
||||||
|
money = Number(applyData.apply_money) * Number(config.rate) / 100
|
||||||
|
}
|
||||||
|
return money.toFixed(2);
|
||||||
|
})
|
||||||
|
|
||||||
//全部提现
|
//全部提现
|
||||||
const allMoney = () => {
|
const allMoney = () => {
|
||||||
if(parseFloat(cashOutMoney.value)) applyData.apply_money = moneyFormat(cashOutMoney.value)
|
if(parseFloat(cashOutMoney.value)) applyData.apply_money = moneyFormat(cashOutMoney.value)
|
||||||
@ -278,6 +321,33 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取微信收款码提现账号信息
|
||||||
|
*/
|
||||||
|
const wechatCodeLoading = ref(false)
|
||||||
|
const wechatCodeInfo: any = ref(null)
|
||||||
|
const getWechatCodeInfo = () => {
|
||||||
|
const data = { account_type: 'wechat_code', account_id: 0 }
|
||||||
|
let request = getFirstCashoutAccountInfo
|
||||||
|
|
||||||
|
if (query.type && query.type == 'wechat_code' && query.account_id) {
|
||||||
|
request = getCashoutAccountInfo
|
||||||
|
data.account_id = query.account_id
|
||||||
|
}
|
||||||
|
wechatCodeLoading.value = true
|
||||||
|
request(data).then((res: any) => {
|
||||||
|
if (res.data && res.data.account_id) {
|
||||||
|
wechatCodeInfo.value = res.data
|
||||||
|
// 初始化赋值
|
||||||
|
if(applyData.transfer_type == 'wechat_code' && !applyData.account_id){
|
||||||
|
applyData.account_id = wechatCodeInfo.value.account_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wechatCodeLoading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 申请提现
|
* 申请提现
|
||||||
*/
|
*/
|
||||||
@ -286,9 +356,15 @@
|
|||||||
if (loading.value) return
|
if (loading.value) return
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
||||||
cashOutApply(applyData).then(res => {
|
cashOutApply(applyData).then((res: any) => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
memberStore.getMemberInfo(()=>{redirect({ url: '/app/pages/member/cash_out' })})
|
memberStore.getMemberInfo(()=>{
|
||||||
|
if(applyData.transfer_type == 'wechatpay'){
|
||||||
|
redirect({ url: '/app/pages/member/cash_out_detail', param: { id: res.data} })
|
||||||
|
}else{
|
||||||
|
redirect({ url: '/app/pages/member/cash_out' })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@ -312,6 +388,24 @@
|
|||||||
}
|
}
|
||||||
applyData.transfer_type = 'bank'
|
applyData.transfer_type = 'bank'
|
||||||
}
|
}
|
||||||
|
// 选中提现到微信
|
||||||
|
const transferWeixin = ()=>{
|
||||||
|
let data = getWinxinOpenId();
|
||||||
|
|
||||||
|
applyData.transfer_payee.open_id = data.wechat ? data.wechat : data.weapp;
|
||||||
|
applyData.transfer_payee.channel = data.wechat ? 'wechat' : 'weapp';
|
||||||
|
|
||||||
|
applyData.transfer_type = 'wechatpay'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选中提现到微信收款码
|
||||||
|
const transferWechatCode = ()=>{
|
||||||
|
if(!wechatCodeInfo.value){
|
||||||
|
uni.showToast({ title: t('cashOutToWechatCodeTips'), icon: 'none' })
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
applyData.transfer_type = 'wechat_code'
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -93,6 +93,7 @@
|
|||||||
|
|
||||||
const cashOutConfigObj: any = reactive({})
|
const cashOutConfigObj: any = reactive({})
|
||||||
const rechargeConfigObj: any = reactive({})
|
const rechargeConfigObj: any = reactive({})
|
||||||
|
|
||||||
// 监听 siteAddons 变化
|
// 监听 siteAddons 变化
|
||||||
watch(
|
watch(
|
||||||
() => systemStore.siteAddons,
|
() => systemStore.siteAddons,
|
||||||
@ -109,6 +110,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
cashOutConfig().then((res: any) => {
|
cashOutConfig().then((res: any) => {
|
||||||
for (let key in res.data) {
|
for (let key in res.data) {
|
||||||
|
|||||||
@ -2,17 +2,21 @@
|
|||||||
<view class="min-h-[100vh] bg-[var(--page-bg-color)] overflow-hidden" :style="themeColor()">
|
<view class="min-h-[100vh] bg-[var(--page-bg-color)] overflow-hidden" :style="themeColor()">
|
||||||
<block v-if="!loading">
|
<block v-if="!loading">
|
||||||
<view class="sidebar-margin card-template mt-[20rpx] !pt-[60rpx] !pb-[40rpx]">
|
<view class="sidebar-margin card-template mt-[20rpx] !pt-[60rpx] !pb-[40rpx]">
|
||||||
<view class="flex items-center flex-col mb-[80rpx]">
|
<view class="flex flex-col justify-center items-center mb-[44rpx]" v-if="cashOutInfo.status == 4 && cashOutInfo.transfer_type == 'wechatpay'">
|
||||||
<text class="text-[60rpx] font-bold price-font mb-[20rpx]">-{{ cashOutInfo.apply_money }}</text>
|
<image class="h-[70rpx] w-[70rpx] mb-[24rpx]" :src="img('static/resource/images/member/apply_withdrawal/transfer.png')" mode="widthFix" />
|
||||||
<text class="text-[28rpx] text-[#333]" :class="{'text-primary': cashOutInfo.status == 1}">{{ cashOutInfo.status_name }}</text>
|
<view class="text-[28rpx] text-[#333]">处理中,预计2小时内到账</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- 状态1.待审核2.待转账 3.已转账 -1拒绝' -->
|
<view class="flex items-center flex-col mb-[80rpx]">
|
||||||
|
<text class="text-[60rpx] font-bold price-font mb-[16rpx]">{{ cashOutInfo.apply_money }}</text>
|
||||||
|
<text class="text-[28rpx] text-[#333]" :class="{'text-primary': cashOutInfo.status == 1, 'text-[#999]': cashOutInfo.status == 4 }">{{ cashOutInfo.status_name }}</text>
|
||||||
|
</view>
|
||||||
|
<!-- 状态1.待审核2.待转账 3.已转账 4.转账中 -1拒绝' -->
|
||||||
<view>
|
<view>
|
||||||
<view class="flex justify-between text-[28rpx] mt-[34rpx] leading-[32rpx]">
|
<view class="flex justify-between text-[28rpx] mt-[34rpx] leading-[32rpx]">
|
||||||
<text class="text-[#333] w-[200rpx]">{{t('cashOutNo')}}</text>
|
<text class="text-[#333] w-[200rpx]">{{t('cashOutNo')}}</text>
|
||||||
<text class="text-[#333]">{{ cashOutInfo.cash_out_no }}</text>
|
<text class="text-[#333]">{{ cashOutInfo.cash_out_no }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="flex justify-between text-[28rpx] mt-[34rpx] leading-[32rpx]">
|
<view class="flex justify-between text-[28rpx] mt-[34rpx] leading-[32rpx]" v-if="Number(cashOutInfo.service_money)">
|
||||||
<text class="text-[#333] w-[200rpx]">{{t('serviceMoney')}}</text>
|
<text class="text-[#333] w-[200rpx]">{{t('serviceMoney')}}</text>
|
||||||
<text class="text-[#333]">¥{{ cashOutInfo.service_money }}</text>
|
<text class="text-[#333]">¥{{ cashOutInfo.service_money }}</text>
|
||||||
</view>
|
</view>
|
||||||
@ -24,26 +28,75 @@
|
|||||||
<text class="text-[#333] w-[200rpx]">{{t('auditTime')}}</text>
|
<text class="text-[#333] w-[200rpx]">{{t('auditTime')}}</text>
|
||||||
<text class="text-[#333]">{{ cashOutInfo.audit_time }}</text>
|
<text class="text-[#333]">{{ cashOutInfo.audit_time }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="flex justify-between text-[28rpx] mt-[34rpx] leading-[32rpx]" v-if="cashOutInfo.transfer_bank">
|
|
||||||
<text class="text-[#333] w-[200rpx]">{{t('transferBank')}}</text>
|
|
||||||
<text class="text-[#333] truncate">{{ cashOutInfo.transfer_bank }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="flex justify-between text-[28rpx] mt-[34rpx] leading-[32rpx]">
|
|
||||||
<text class="text-[#333] w-[200rpx]">{{t('transferAccount')}}</text>
|
|
||||||
<text class="text-[#333] truncate">{{ cashOutInfo.transfer_type == 'wechatpay' ? '微信' : cashOutInfo.transfer_account }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="flex justify-between text-[28rpx] mt-[34rpx] leading-[32rpx]" v-if="cashOutInfo.status == -1 && cashOutInfo.refuse_reason">
|
<view class="flex justify-between text-[28rpx] mt-[34rpx] leading-[32rpx]" v-if="cashOutInfo.status == -1 && cashOutInfo.refuse_reason">
|
||||||
<text class="text-[#333] w-[200rpx]">{{t('refuseReason')}}</text>
|
<text class="text-[#333] w-[200rpx] flex-shrink-0">{{t('refuseReason')}}</text>
|
||||||
<text class="text-[#333] truncate">{{ cashOutInfo.refuse_reason }}</text>
|
<text class="text-[#333] ml-[20rpx]">{{ cashOutInfo.refuse_reason }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="flex justify-between text-[28rpx] mt-[34rpx] leading-[32rpx]" v-if="cashOutInfo.status == 3">
|
<view class="flex justify-between text-[28rpx] mt-[34rpx] leading-[32rpx]" v-if="cashOutInfo.status == 3">
|
||||||
<text class="text-[#333] w-[200rpx]">{{t('transferTypeName')}}</text>
|
<text class="text-[#333] w-[200rpx]">{{t('transferTypeName')}}</text>
|
||||||
<text class="text-[#333] truncate">{{ cashOutInfo.transfer_type_name }}</text>
|
<text class="text-[#333] truncate">{{ cashOutInfo.transfer_type_name }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="flex justify-between text-[28rpx] mt-[34rpx] leading-[32rpx]" v-if="cashOutInfo.status == 3 && cashOutInfo.transfer_time">
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="sidebar-margin card-template mt-[20rpx]" v-if="cashOutInfo.transfer_type == 'wechatpay' && (cashOutInfo.status == 2 || cashOutInfo.status == 3 || cashOutInfo.status == 4)">
|
||||||
|
<u-steps :current="current" direction="column" activeColor="var(--primary-color)" activeIcon="checkmark-circle-fill" inactiveIcon="checkmark-circle-fill">
|
||||||
|
<u-steps-item title="提现申请" :desc="cashOutInfo.create_time" ></u-steps-item>
|
||||||
|
<u-steps-item title="处理中" :desc="cashOutInfo.audit_time ? cashOutInfo.audit_time : '-'"></u-steps-item>
|
||||||
|
<u-steps-item title="提现成功" :desc="cashOutInfo.transfer_time ? cashOutInfo.transfer_time : '-' "></u-steps-item>
|
||||||
|
</u-steps>
|
||||||
|
</view>
|
||||||
|
<view class="sidebar-margin card-template mt-[20rpx]">
|
||||||
|
<view class="title">{{ t('proceedsInfo') }}</view>
|
||||||
|
<view class="flex justify-between text-[28rpx] mt-[34rpx] leading-[32rpx]">
|
||||||
|
<text class="text-[#333] w-[200rpx]">{{t('transferAccount')}}</text>
|
||||||
|
<text class="text-[#333] truncate">{{ cashOutInfo.transfer_type == 'wechatpay' ? '微信零钱' : cashOutInfo.transfer_account }}</text>
|
||||||
|
</view>
|
||||||
|
<template v-if="cashOutInfo.transfer_type == 'wechatpay'">
|
||||||
|
<view class="flex justify-between text-[28rpx] mt-[34rpx] leading-[32rpx]">
|
||||||
|
<text class="text-[#333] w-[200rpx]">{{ t('transferNickname') }}</text>
|
||||||
|
<text class="text-[#333]">{{ cashOutInfo.nickname }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex justify-between text-[28rpx] mt-[34rpx] leading-[32rpx]">
|
||||||
|
<text class="text-[#333] w-[200rpx]">{{ t('transferImg') }}</text>
|
||||||
|
<u-avatar :src="img(cashOutInfo.headimg)" size="30" leftIcon="none" :default-url="img('static/resource/images/default_headimg.png')" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<template v-if="cashOutInfo.transfer_type !== 'wechatpay'">
|
||||||
|
<view class="flex justify-between text-[28rpx] mt-[34rpx] leading-[32rpx]">
|
||||||
|
<text class="text-[#333] w-[200rpx]">{{cashOutInfo.transfer_type == 'bank' ? t('bankRealname') : t('realname')}}</text>
|
||||||
|
<text class="text-[#333]">{{ cashOutInfo.transfer_realname }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex justify-between text-[28rpx] mt-[34rpx] leading-[32rpx]" v-if="cashOutInfo.transfer_bank">
|
||||||
|
<text class="text-[#333] w-[200rpx]">{{t('transferBank')}}</text>
|
||||||
|
<text class="text-[#333] truncate">{{ cashOutInfo.transfer_bank }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex justify-between text-[28rpx] mt-[34rpx] leading-[32rpx]" v-if="cashOutInfo.transfer_type == 'wechat_code' || cashOutInfo.transfer_type == 'alipay'">
|
||||||
|
<text class="text-[#333] w-[200rpx]">{{t('transferCode')}}</text>
|
||||||
|
<view class="flex items-center" @click="previewImg()">
|
||||||
|
<image :src="img(cashOutInfo.transfer_payment_code)" class="w-[140rpx] h-[140rpx] rounded-[var(--rounded-small)]"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
|
<view class="sidebar-margin card-template my-[20rpx]" v-if="cashOutInfo.status == 3">
|
||||||
|
<view class="title">{{ t('transferInfo') }}</view>
|
||||||
|
<view class="flex justify-between text-[28rpx] leading-[32rpx]" v-if="cashOutInfo.transfer_time">
|
||||||
<text class="text-[#333] w-[200rpx]">{{t('transferTime')}}</text>
|
<text class="text-[#333] w-[200rpx]">{{t('transferTime')}}</text>
|
||||||
<text class="text-[#333] truncate">{{ cashOutInfo.transfer_time }}</text>
|
<text class="text-[#333] truncate">{{ cashOutInfo.transfer_time }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="flex justify-between text-[28rpx] mt-[34rpx] leading-[32rpx]" v-if="cashOutInfo.transfer_no">
|
||||||
|
<text class="text-[#333] w-[200rpx]">{{ t('transferNo') }}</text>
|
||||||
|
<text class="text-[#333] truncate">{{ cashOutInfo.transfer.transfer_no }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex justify-between text-[28rpx] mt-[34rpx] leading-[32rpx]" v-if="cashOutInfo.transfer && cashOutInfo.transfer.transfer_remark">
|
||||||
|
<text class="text-[#333] w-[200rpx] flex-shrink-0">{{t('transferRemark')}}</text>
|
||||||
|
<text class="text-[#333] ml-[20rpx]">{{ cashOutInfo.transfer.transfer_remark }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex justify-between text-[28rpx] mt-[34rpx] leading-[32rpx]" v-if="cashOutInfo.transfer && cashOutInfo.transfer.transfer_voucher">
|
||||||
|
<text class="text-[#333] w-[200rpx]">{{t('transferVoucher')}}</text>
|
||||||
|
<view class="flex items-center" @click="handleImg()">
|
||||||
|
<image :src="img(cashOutInfo.transfer.transfer_voucher)" class="w-[140rpx] h-[140rpx] rounded-[var(--rounded-small)]"></image>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
@ -53,12 +106,13 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { onLoad } from '@dcloudio/uni-app'
|
import { onLoad, onUnload } from '@dcloudio/uni-app'
|
||||||
import { t } from '@/locale'
|
import { t } from '@/locale'
|
||||||
import { redirect, img, goback } from '@/utils/common';
|
import { redirect, img, goback } from '@/utils/common';
|
||||||
import { getCashOutDetail } from '@/app/api/member';
|
import { getCashOutDetail } from '@/app/api/member';
|
||||||
|
|
||||||
const cashOutInfo = ref({});
|
const cashOutInfo = ref<any>({});
|
||||||
|
const current = ref(0);
|
||||||
const loading = ref<boolean>(true);
|
const loading = ref<boolean>(true);
|
||||||
onLoad((option: any) => {
|
onLoad((option: any) => {
|
||||||
let id = option.id || "";
|
let id = option.id || "";
|
||||||
@ -79,12 +133,56 @@ const getCashoutAccountListFn = (id: any) => {
|
|||||||
|
|
||||||
getCashOutDetail(id).then((res: any) => {
|
getCashOutDetail(id).then((res: any) => {
|
||||||
cashOutInfo.value = res.data;
|
cashOutInfo.value = res.data;
|
||||||
|
if(cashOutInfo.value.transfer_type == 'wechatpay'){
|
||||||
|
if(cashOutInfo.value.status == 1){
|
||||||
|
current.value = 0;
|
||||||
|
|
||||||
|
}else if(cashOutInfo.value.status == 2 || cashOutInfo.value.status == 4){
|
||||||
|
current.value = 1;
|
||||||
|
}else if(cashOutInfo.value.status == 3){
|
||||||
|
current.value = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
const previewImg = () =>{
|
||||||
|
uni.previewImage({
|
||||||
|
urls: [img(cashOutInfo.value.transfer_payment_code)],
|
||||||
|
indicator: "number",
|
||||||
|
loop: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const handleImg = () => {
|
||||||
|
uni.previewImage({
|
||||||
|
urls: [img(cashOutInfo.value.transfer.transfer_voucher)],
|
||||||
|
indicator: "number",
|
||||||
|
loop: true
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭预览图片
|
||||||
|
onUnload(()=>{
|
||||||
|
// #ifdef H5 || APP
|
||||||
|
try {
|
||||||
|
uni.closePreviewImage()
|
||||||
|
}catch (e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
|
:deep(.u-text__value--main){
|
||||||
|
font-size: 24rpx !important;
|
||||||
|
color: #606266;
|
||||||
|
}
|
||||||
|
:deep(.u-text__value){
|
||||||
|
font-size: 24rpx !important;
|
||||||
|
color: #606266;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -5,16 +5,9 @@
|
|||||||
<view v-show="!diy.getLoading()">
|
<view v-show="!diy.getLoading()">
|
||||||
|
|
||||||
<!-- 自定义模板渲染 -->
|
<!-- 自定义模板渲染 -->
|
||||||
<view class="diy-template-wrap bg-index" v-if="diy.data.pageMode != 'fixed'" :style="diy.pageStyle()">
|
<view class="diy-template-wrap bg-index" :style="diy.pageStyle()">
|
||||||
|
|
||||||
<diy-group ref="diyGroupRef" :data="diy.data" :pullDownRefreshCount="diy.pullDownRefreshCount" />
|
<diy-group ref="diyGroupRef" :data="diy.data" />
|
||||||
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 固定模板渲染 -->
|
|
||||||
<view class="fixed-template-wrap" v-if="diy.data.pageMode == 'fixed'">
|
|
||||||
|
|
||||||
<fixed-group :data="diy.data" :pullDownRefreshCount="diy.pullDownRefreshCount" />
|
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@ -33,11 +26,8 @@
|
|||||||
import {useDiy} from '@/hooks/useDiy'
|
import {useDiy} from '@/hooks/useDiy'
|
||||||
import {redirect} from '@/utils/common';
|
import {redirect} from '@/utils/common';
|
||||||
import diyGroup from '@/addon/components/diy/group/index.vue'
|
import diyGroup from '@/addon/components/diy/group/index.vue'
|
||||||
import fixedGroup from '@/addon/components/fixed/group/index.vue'
|
|
||||||
import useMemberStore from '@/stores/member'
|
import useMemberStore from '@/stores/member'
|
||||||
|
|
||||||
uni.hideTabBar() // 隐藏tabbar
|
|
||||||
|
|
||||||
// 会员信息
|
// 会员信息
|
||||||
const memberStore = useMemberStore()
|
const memberStore = useMemberStore()
|
||||||
const userInfo = computed(() => memberStore.info)
|
const userInfo = computed(() => memberStore.info)
|
||||||
@ -80,9 +70,6 @@
|
|||||||
// 监听页面卸载
|
// 监听页面卸载
|
||||||
diy.onUnload();
|
diy.onUnload();
|
||||||
|
|
||||||
// 监听下拉刷新事件
|
|
||||||
diy.onPullDownRefresh()
|
|
||||||
|
|
||||||
// 监听滚动事件
|
// 监听滚动事件
|
||||||
diy.onPageScroll()
|
diy.onPageScroll()
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -11,8 +11,8 @@
|
|||||||
<view class="type-class">
|
<view class="type-class">
|
||||||
<u-popup :show="typePopup" mode="top" @close="typePopup = false">
|
<u-popup :show="typePopup" mode="top" @close="typePopup = false">
|
||||||
<view @touchmove.prevent.stop class="py-[22rpx]">
|
<view @touchmove.prevent.stop class="py-[22rpx]">
|
||||||
<view class="leading-[80rpx] text-[26rpx] text-[#333] px-[50rpx]" :class="{'bg-[#FDF8F8] !text-primary font-500' : from_type == ''}" @click="searchTypeFn()">全部</view>
|
<view class="leading-[80rpx] text-[26rpx] text-[#333] px-[50rpx]" :class="{'bg-[var(--primary-color-light)] !text-primary font-500' : from_type == ''}" @click="searchTypeFn()">全部</view>
|
||||||
<view class="leading-[80rpx] text-[26rpx] text-[#333] px-[50rpx]" :class="{'bg-[#FDF8F8] !text-primary font-500' : from_type == index}" v-for="(item,index) in pointType" @click="searchTypeFn(index,item)">{{ item.name }}</view>
|
<view class="leading-[80rpx] text-[26rpx] text-[#333] px-[50rpx]" :class="{'bg-[var(--primary-color-light)] !text-primary font-500' : from_type == index}" v-for="(item,index) in pointType" @click="searchTypeFn(index,item)">{{ item.name }}</view>
|
||||||
</view>
|
</view>
|
||||||
</u-popup>
|
</u-popup>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@ -63,7 +63,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="w-[10rpx] h-[10rpx] rounded-[50%] bg-[#FF5527]" v-if="isCurrentDate(item)"></view>
|
<view class="w-[10rpx] h-[10rpx] rounded-[50%] bg-[var(--primary-color)]" v-if="isCurrentDate(item)"></view>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
</view>
|
</view>
|
||||||
@ -81,7 +81,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="w-[10rpx] h-[10rpx] rounded-[50%] bg-[#FF5527]" v-if="isCurrentDate(item)"></view>
|
<view class="w-[10rpx] h-[10rpx] rounded-[50%] bg-[var(--primary-color)]" v-if="isCurrentDate(item)"></view>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import { useLogin } from '@/hooks/useLogin';
|
|||||||
|
|
||||||
interface Diy {
|
interface Diy {
|
||||||
mode: string, // 模式:decorate 装修,为空表示正常
|
mode: string, // 模式:decorate 装修,为空表示正常
|
||||||
|
id: any,
|
||||||
pageMode: string, // 页面展示模式,diy:自定义,fixed:固定
|
pageMode: string, // 页面展示模式,diy:自定义,fixed:固定
|
||||||
currentIndex: number,
|
currentIndex: number,
|
||||||
global: {
|
global: {
|
||||||
@ -18,13 +19,15 @@ interface Diy {
|
|||||||
value: any[],
|
value: any[],
|
||||||
topFixedStatus: string, // 置顶组件的状态
|
topFixedStatus: string, // 置顶组件的状态
|
||||||
scrollTop: number,
|
scrollTop: number,
|
||||||
topTabarHeight: number
|
topTabarHeight: number,
|
||||||
|
componentRefs: any
|
||||||
}
|
}
|
||||||
|
|
||||||
const useDiyStore = defineStore('diy', {
|
const useDiyStore = defineStore('diy', {
|
||||||
state: (): Diy => {
|
state: (): Diy => {
|
||||||
return {
|
return {
|
||||||
mode: '',
|
mode: '',
|
||||||
|
id: 0,
|
||||||
pageMode: 'diy',
|
pageMode: 'diy',
|
||||||
currentIndex: -99,
|
currentIndex: -99,
|
||||||
global: {
|
global: {
|
||||||
@ -37,7 +40,8 @@ const useDiyStore = defineStore('diy', {
|
|||||||
value: [], // 组件集合
|
value: [], // 组件集合
|
||||||
topFixedStatus: 'home', // 顶部 置顶组件状态,home:展示首页数据、diy:展示置顶组件定义的子页面
|
topFixedStatus: 'home', // 顶部 置顶组件状态,home:展示首页数据、diy:展示置顶组件定义的子页面
|
||||||
scrollTop: 0, // 滚动位置
|
scrollTop: 0, // 滚动位置
|
||||||
topTabarHeight: 0
|
topTabarHeight: 0,
|
||||||
|
componentRefs: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getters: {},
|
getters: {},
|
||||||
@ -131,7 +135,7 @@ const useDiyStore = defineStore('diy', {
|
|||||||
}
|
}
|
||||||
diyRedirect(data);
|
diyRedirect(data);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
<u-popup :show="show" @close="show = false" mode="bottom" :round="10">
|
<u-popup :show="show" @close="show = false" mode="bottom" :round="10">
|
||||||
<view @touchmove.prevent.stop class="popup-common">
|
<view @touchmove.prevent.stop class="popup-common">
|
||||||
<view class="title">请选择地区</view>
|
<view class="title">请选择地区</view>
|
||||||
|
|
||||||
<view class="flex p-[30rpx] pt-[0] text-sm font-500">
|
<view class="flex p-[30rpx] pt-[0] text-sm font-500">
|
||||||
<view v-if="areaList.province.length" class="flex-1 pr-[10rpx]" :class="{'text-[var(--primary-color)]': currSelect == 'province'}" @click="currSelect = 'province'">
|
<view v-if="areaList.province.length" class="flex-1 pr-[10rpx]" :class="{'text-[var(--primary-color)]': currSelect == 'province'}" @click="currSelect = 'province'">
|
||||||
<view v-if="selected.province">{{ selected.province.name }}</view>
|
<view v-if="selected.province">{{ selected.province.name }}</view>
|
||||||
|
|||||||
@ -41,9 +41,11 @@
|
|||||||
import { ref, reactive, computed, onMounted } from 'vue'
|
import { ref, reactive, computed, onMounted } from 'vue'
|
||||||
import { t } from '@/locale'
|
import { t } from '@/locale'
|
||||||
import { bindMobile } from '@/app/api/member'
|
import { bindMobile } from '@/app/api/member'
|
||||||
|
import { mobileLogin } from '@/app/api/auth'
|
||||||
import useMemberStore from '@/stores/member'
|
import useMemberStore from '@/stores/member'
|
||||||
import useConfigStore from '@/stores/config'
|
import useConfigStore from '@/stores/config'
|
||||||
import { redirect } from '@/utils/common'
|
import { redirect } from '@/utils/common'
|
||||||
|
import { useLogin } from '@/hooks/useLogin'
|
||||||
|
|
||||||
const show = ref(false)
|
const show = ref(false)
|
||||||
const memberStore = useMemberStore()
|
const memberStore = useMemberStore()
|
||||||
@ -69,9 +71,11 @@
|
|||||||
real_name_input.value = false;
|
real_name_input.value = false;
|
||||||
}, 800)
|
}, 800)
|
||||||
|
|
||||||
uni.getStorageSync('openid') && (Object.assign(formData, { openid: uni.getStorageSync('openid') }))
|
|
||||||
uni.getStorageSync('pid') && (Object.assign(formData, { pid: uni.getStorageSync('pid') }))
|
uni.getStorageSync('pid') && (Object.assign(formData, { pid: uni.getStorageSync('pid') }))
|
||||||
|
uni.getStorageSync('openid') && (Object.assign(formData, { openid: uni.getStorageSync('openid') }))
|
||||||
uni.getStorageSync('unionid') && (Object.assign(formData, { unionid: uni.getStorageSync('unionid') }))
|
uni.getStorageSync('unionid') && (Object.assign(formData, { unionid: uni.getStorageSync('unionid') }))
|
||||||
|
uni.getStorageSync('nickname') && (Object.assign(formData, { nickname: uni.getStorageSync('nickname') }))
|
||||||
|
uni.getStorageSync('avatar') && (Object.assign(formData, { headimg: uni.getStorageSync('avatar') }))
|
||||||
});
|
});
|
||||||
|
|
||||||
const rules = {
|
const rules = {
|
||||||
@ -84,8 +88,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
validator(rule: any, value: any, callback: any) {
|
validator(rule: any, value: any, callback: any) {
|
||||||
let mobile = /^1[3-9]\d{9}$/;
|
if (!uni.$u.test.mobile(value)){
|
||||||
if (!mobile.test(value)){
|
|
||||||
callback(new Error('请输入正确的手机号'))
|
callback(new Error('请输入正确的手机号'))
|
||||||
} else {
|
} else {
|
||||||
callback()
|
callback()
|
||||||
@ -119,11 +122,18 @@
|
|||||||
if (loading.value) return
|
if (loading.value) return
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
||||||
bindMobile(formData).then((res) => {
|
const request = info.value ? bindMobile : mobileLogin;
|
||||||
|
|
||||||
|
request(formData).then((res: any) => {
|
||||||
|
if (info.value) {
|
||||||
memberStore.getMemberInfo()
|
memberStore.getMemberInfo()
|
||||||
if (info.value.mobile) {
|
if (info.value.mobile) {
|
||||||
uni.removeStorageSync('isbindmobile');
|
uni.removeStorageSync('isbindmobile');
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
memberStore.setToken(res.data.token)
|
||||||
|
useLogin().handleLoginBack()
|
||||||
|
}
|
||||||
show.value = false
|
show.value = false
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
|
|||||||
@ -1,26 +1,33 @@
|
|||||||
<template>
|
<template>
|
||||||
<u-popup :show="show" :round="10" @close="show = false" :closeable="true">
|
<u-popup :show="show" :round="10" @close="show = false">
|
||||||
<view class="mx-[30rpx] pb-[20rpx] pt-[40rpx] border-t">
|
<view class="information-filling">
|
||||||
<view class="text-base">{{ t('getAvatarNickname') }}</view>
|
<view class="relative">
|
||||||
<view class="text-sm mt-[18rpx] text-gray-400">{{ t('getAvatarNicknameTips') }}</view>
|
<view class="mx-[30rpx] pb-[20rpx] pt-[36rpx] border-t">
|
||||||
|
<view class="text-[30rpx]">{{ t('getAvatarNickname') }}</view>
|
||||||
|
<view class="text-[24rpx] mt-[18rpx] leading-[1.4] text-gray-400">{{ t('getAvatarNicknameTips') }}</view>
|
||||||
|
</view>
|
||||||
|
<text class="nc-iconfont nc-icon-guanbiV6xx2 !text-[40rpx] absolute top-[28rpx] right-[30rpx]" @click="show = false"></text>
|
||||||
</view>
|
</view>
|
||||||
<u-form labelPosition="left" :model="formData" errorType='toast' :rules="rules" ref="formRef" labelWidth="65">
|
<u-form labelPosition="left" :model="formData" errorType='toast' :rules="rules" ref="formRef" labelWidth="65">
|
||||||
<view class="mx-[30rpx]">
|
<view class="mx-[30rpx]">
|
||||||
<view class="mt-[20rpx]">
|
<view class="mt-[20rpx]">
|
||||||
<u-form-item :label="t('headimg')" prop="headimg" :border-bottom="true">
|
<u-form-item :label="t('headimg')" prop="headimg" :border-bottom="true">
|
||||||
<button class="m-0 my-[10rpx] p-0 w-[140rpx] h-[140rpx]" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
|
<button class="m-0 p-0 w-[120rpx] h-[120rpx]" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
|
||||||
<view class="w-full h-full flex items-center justify-center overflow-hidden">
|
<view class="w-full h-full flex items-center justify-center overflow-hidden">
|
||||||
<u-image :src="img(formData.headimg)" width="140rpx" height="140rpx" v-if="formData.headimg" mode="aspectFill"></u-image>
|
<u-image :src="img(formData.headimg)" width="120rpx" height="120rpx" v-if="formData.headimg" mode="aspectFill"></u-image>
|
||||||
<u-icon name="plus" v-else></u-icon>
|
<u-icon name="plus" v-else></u-icon>
|
||||||
</view>
|
</view>
|
||||||
</button>
|
</button>
|
||||||
</u-form-item>
|
</u-form-item>
|
||||||
<u-form-item :label=" t('nickname')" prop="nickname" :border-bottom="true">
|
<u-form-item :label=" t('nickname')" prop="nickname" :border-bottom="true">
|
||||||
<input type="nickname" v-model="formData.nickname" :placeholder="t('nicknamePlaceholder')" @blur="bindNickname">
|
<input type="nickname" v-model="formData.nickname" :placeholder="t('nicknamePlaceholder')" placeholderClass="text-[28rpx]" class="text-[28rpx]" @blur="bindNickname">
|
||||||
</u-form-item>
|
</u-form-item>
|
||||||
<u-form-item :label="t('mobile')" prop="mobile" :border-bottom="true" v-if="isBindMobile">
|
<u-form-item :label="t('mobile')" prop="mobile" :border-bottom="true" v-if="isBindMobile">
|
||||||
<input type="mobile" v-model="formData.mobile" :disabled="true" v-if="formData.mobile">
|
<input type="mobile" v-model="formData.mobile" :disabled="true" v-if="formData.mobile">
|
||||||
<u-button :customStyle="{border:'none',color: 'var(--primary-color)',width:'140rpx', textAlign:'left',margin:'0rpx'}" :text="t('getMobile')" open-type="getPhoneNumber" @getphonenumber="memberStore.bindMobile" v-else></u-button>
|
<template v-else>
|
||||||
|
<u-button v-if="info" :customStyle="{border:'none',color: 'var(--primary-color)',width:'140rpx', textAlign:'left',margin:'0rpx'}" :text="t('getMobile')" open-type="getPhoneNumber" @getphonenumber="memberStore.bindMobile"></u-button>
|
||||||
|
<u-button v-else :customStyle="{border:'none',color: 'var(--primary-color)',width:'140rpx', textAlign:'left',margin:'0rpx'}" :text="t('getMobile')" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber"></u-button>
|
||||||
|
</template>
|
||||||
</u-form-item>
|
</u-form-item>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -28,6 +35,7 @@
|
|||||||
<button :loading="loading" class="bg-[var(--primary-color)] text-[#fff] h-[80rpx] leading-[80rpx] rounded-[100rpx] text-[28rpx]" @click="confirm">{{t('confirm')}}</button>
|
<button :loading="loading" class="bg-[var(--primary-color)] text-[#fff] h-[80rpx] leading-[80rpx] rounded-[100rpx] text-[28rpx]" @click="confirm">{{t('confirm')}}</button>
|
||||||
</view>
|
</view>
|
||||||
</u-form>
|
</u-form>
|
||||||
|
</view>
|
||||||
<!-- #ifdef MP-WEIXIN -->
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
<!-- 小程序隐私协议 -->
|
<!-- 小程序隐私协议 -->
|
||||||
<wx-privacy-popup ref="wxPrivacyPopupRef"></wx-privacy-popup>
|
<wx-privacy-popup ref="wxPrivacyPopupRef"></wx-privacy-popup>
|
||||||
@ -40,14 +48,16 @@
|
|||||||
import { t } from '@/locale'
|
import { t } from '@/locale'
|
||||||
import useMemberStore from '@/stores/member'
|
import useMemberStore from '@/stores/member'
|
||||||
import { img } from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import { modifyMember } from '@/app/api/member'
|
import { modifyMember,getMobile } from '@/app/api/member'
|
||||||
import { fetchBase64Image } from '@/app/api/system'
|
import { fetchBase64Image } from '@/app/api/system'
|
||||||
import { useLogin } from '@/hooks/useLogin'
|
import { useLogin } from '@/hooks/useLogin'
|
||||||
|
import useConfigStore from '@/stores/config'
|
||||||
|
|
||||||
const show = ref(false)
|
const show = ref(false)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const memberStore = useMemberStore()
|
const memberStore = useMemberStore()
|
||||||
const info = computed(() => memberStore.info)
|
const info = computed(() => memberStore.info)
|
||||||
|
const config = useConfigStore()
|
||||||
|
|
||||||
const formData = reactive({
|
const formData = reactive({
|
||||||
nickname: '',
|
nickname: '',
|
||||||
@ -110,7 +120,7 @@
|
|||||||
},
|
},
|
||||||
'mobile': {
|
'mobile': {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: isBindMobile.value ? true : false,
|
required: config.login.is_bind_mobile ? true : false,
|
||||||
message: t('mobileTips'),
|
message: t('mobileTips'),
|
||||||
trigger: ['blur', 'change'],
|
trigger: ['blur', 'change'],
|
||||||
}
|
}
|
||||||
@ -118,11 +128,38 @@
|
|||||||
|
|
||||||
const formRef: any = ref(null)
|
const formRef: any = ref(null)
|
||||||
|
|
||||||
|
// 获取手机号
|
||||||
|
const getPhoneNumber = (e:any)=> {
|
||||||
|
if (e.detail.errMsg == 'getPhoneNumber:ok') {
|
||||||
|
uni.showLoading({ title: '' })
|
||||||
|
getMobile({
|
||||||
|
mobile_code: e.detail.code
|
||||||
|
}).then((res: any) => {
|
||||||
|
formData.mobile = res.data.mobile
|
||||||
|
uni.hideLoading()
|
||||||
|
}).catch(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.hideLoading()
|
||||||
|
}, 2000);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.detail.errno == 104) {
|
||||||
|
let msg = '用户未授权隐私权限';
|
||||||
|
uni.showToast({ title: msg, icon: 'none' })
|
||||||
|
}
|
||||||
|
if (e.detail.errMsg == "getPhoneNumber:fail user deny") {
|
||||||
|
let msg = '用户拒绝获取手机号码';
|
||||||
|
uni.showToast({ title: msg, icon: 'none' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const confirm = async () => {
|
const confirm = async () => {
|
||||||
formRef.value.validate().then(async() => {
|
formRef.value.validate().then(async() => {
|
||||||
if (loading.value) return
|
if (loading.value) return
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
||||||
|
if (info.value) {
|
||||||
// 修改头像
|
// 修改头像
|
||||||
await modifyMember({ field: 'headimg', value: formData.headimg }).then(() => {
|
await modifyMember({ field: 'headimg', value: formData.headimg }).then(() => {
|
||||||
memberStore.info.headimg = formData.headimg
|
memberStore.info.headimg = formData.headimg
|
||||||
@ -139,12 +176,20 @@
|
|||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
|
|
||||||
// #ifdef MP-WEIXIN
|
// #ifdef MP-WEIXIN
|
||||||
const login = useLogin()
|
const login = useLogin()
|
||||||
if (info.value && !info.value.weapp_openid) {
|
if (info.value && !info.value.weapp_openid) {
|
||||||
login.getAuthCode({ updateFlag: true }) // 更新oppenid
|
login.getAuthCode({ updateFlag: true }) // 更新oppenid
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
|
} else {
|
||||||
|
// todo 如果没有登录过,则注册
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
const login = useLogin()
|
||||||
|
login.getAuthCode({ backFlag: true, ...formData }) // 注册
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,47 +0,0 @@
|
|||||||
<!-- 下拉刷新区域 -->
|
|
||||||
<template>
|
|
||||||
<view v-if="mOption.use" class="mescroll-downwarp" :style="{'background-color':mOption.bgColor,'color':mOption.textColor}">
|
|
||||||
<view class="downwarp-content">
|
|
||||||
<view class="downwarp-progress" :class="{'mescroll-rotate': isDownLoading}" :style="{'border-color':mOption.textColor, 'transform':downRotate}"></view>
|
|
||||||
<view class="downwarp-tip">{{downText}}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
option: Object , // down的配置项
|
|
||||||
type: Number, // 下拉状态(inOffset:1, outOffset:2, showLoading:3, endDownScroll:4)
|
|
||||||
rate: Number // 下拉比率 (inOffset: rate<1; outOffset: rate>=1)
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
// 支付宝小程序需写成计算属性,prop定义default仍报错
|
|
||||||
mOption(){
|
|
||||||
return this.option || {}
|
|
||||||
},
|
|
||||||
// 是否在加载中
|
|
||||||
isDownLoading(){
|
|
||||||
return this.type === 3
|
|
||||||
},
|
|
||||||
// 旋转的角度
|
|
||||||
downRotate(){
|
|
||||||
return 'rotate(' + 360 * this.rate + 'deg)'
|
|
||||||
},
|
|
||||||
// 文本提示
|
|
||||||
downText(){
|
|
||||||
switch (this.type){
|
|
||||||
case 1: return this.mOption.textInOffset;
|
|
||||||
case 2: return this.mOption.textOutOffset;
|
|
||||||
case 3: return this.mOption.textLoading;
|
|
||||||
case 4: return this.mOption.textLoading;
|
|
||||||
default: return this.mOption.textInOffset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
@import "./mescroll-down.css";
|
|
||||||
</style>
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
<!-- 上拉加载区域 -->
|
|
||||||
<template>
|
|
||||||
<view class="mescroll-upwarp" :style="{'background-color':mOption.bgColor,'color':mOption.textColor}">
|
|
||||||
<!-- 加载中 (此处不能用v-if,否则android小程序快速上拉可能会不断触发上拉回调) -->
|
|
||||||
<view v-show="isUpLoading">
|
|
||||||
<view class="upwarp-progress mescroll-rotate" :style="{'border-color':mOption.textColor}"></view>
|
|
||||||
<view class="upwarp-tip">{{ mOption.textLoading }}</view>
|
|
||||||
</view>
|
|
||||||
<!-- 无数据 -->
|
|
||||||
<view v-if="isUpNoMore" class="upwarp-nodata">{{ mOption.textNoMore }}</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
option: Object, // up的配置项
|
|
||||||
type: Number // 上拉加载的状态:0(loading前),1(loading中),2(没有更多了)
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
// 支付宝小程序需写成计算属性,prop定义default仍报错
|
|
||||||
mOption() {
|
|
||||||
return this.option || {};
|
|
||||||
},
|
|
||||||
// 加载中
|
|
||||||
isUpLoading() {
|
|
||||||
return this.type === 1;
|
|
||||||
},
|
|
||||||
// 没有更多了
|
|
||||||
isUpNoMore() {
|
|
||||||
return this.type === 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
@import './mescroll-up.css';
|
|
||||||
</style>
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
/**
|
|
||||||
* mescroll-body写在子组件时,需通过mescroll的mixins补充子组件缺少的生命周期
|
|
||||||
*/
|
|
||||||
const MescrollCompMixin = {
|
|
||||||
// 因为子组件无onPageScroll和onReachBottom的页面生命周期,需在页面传递进到子组件 (一级)
|
|
||||||
onPageScroll(e) {
|
|
||||||
this.handlePageScroll(e)
|
|
||||||
},
|
|
||||||
onReachBottom() {
|
|
||||||
this.handleReachBottom()
|
|
||||||
},
|
|
||||||
// 当down的native: true时, 还需传递此方法进到子组件
|
|
||||||
onPullDownRefresh(){
|
|
||||||
this.handlePullDownRefresh()
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
mescroll: { // mescroll-body写在子子子...组件的情况 (多级)
|
|
||||||
onPageScroll: e=>{
|
|
||||||
this.handlePageScroll(e)
|
|
||||||
},
|
|
||||||
onReachBottom: ()=>{
|
|
||||||
this.handleReachBottom()
|
|
||||||
},
|
|
||||||
onPullDownRefresh: ()=>{
|
|
||||||
this.handlePullDownRefresh()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods:{
|
|
||||||
handlePageScroll(e){
|
|
||||||
let item = this.$refs["mescrollItem"];
|
|
||||||
if(item && item.mescroll) item.mescroll.onPageScroll(e);
|
|
||||||
},
|
|
||||||
handleReachBottom(){
|
|
||||||
let item = this.$refs["mescrollItem"];
|
|
||||||
if(item && item.mescroll) item.mescroll.onReachBottom();
|
|
||||||
},
|
|
||||||
handlePullDownRefresh(){
|
|
||||||
let item = this.$refs["mescrollItem"];
|
|
||||||
if(item && item.mescroll) item.mescroll.onPullDownRefresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default MescrollCompMixin;
|
|
||||||
@ -1,66 +0,0 @@
|
|||||||
/**
|
|
||||||
* mescroll-more-item的mixins, 仅在多个 mescroll-body 写在子组件时使用 (参考 mescroll-more 案例)
|
|
||||||
*/
|
|
||||||
const MescrollMoreItemMixin = {
|
|
||||||
// 支付宝小程序不支持props的mixin,需写在具体的页面中
|
|
||||||
// #ifndef MP-ALIPAY || MP-DINGTALK
|
|
||||||
props:{
|
|
||||||
i: Number, // 每个tab页的专属下标
|
|
||||||
index: { // 当前tab的下标
|
|
||||||
type: Number,
|
|
||||||
default(){
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// #endif
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
downOption:{
|
|
||||||
auto:false // 不自动加载
|
|
||||||
},
|
|
||||||
upOption:{
|
|
||||||
auto:false // 不自动加载
|
|
||||||
},
|
|
||||||
isInit: false // 当前tab是否已初始化
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch:{
|
|
||||||
// 监听下标的变化
|
|
||||||
index(val){
|
|
||||||
if (this.i === val && !this.isInit) this.mescrollTrigger()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 以ref的方式初始化mescroll对象 (兼容字节跳动小程序)
|
|
||||||
mescrollInitByRef() {
|
|
||||||
if(!this.mescroll || !this.mescroll.resetUpScroll){
|
|
||||||
// 字节跳动小程序编辑器不支持一个页面存在相同的ref, 多mescroll的ref需动态生成, 格式为'mescrollRef下标'
|
|
||||||
let mescrollRef = this.$refs.mescrollRef || this.$refs['mescrollRef'+this.i];
|
|
||||||
if(mescrollRef) this.mescroll = mescrollRef.mescroll
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// mescroll组件初始化的回调,可获取到mescroll对象 (覆盖mescroll-mixins.js的mescrollInit, 为了标记isInit)
|
|
||||||
mescrollInit(mescroll) {
|
|
||||||
this.mescroll = mescroll;
|
|
||||||
this.mescrollInitByRef && this.mescrollInitByRef(); // 兼容字节跳动小程序
|
|
||||||
// 自动加载当前tab的数据
|
|
||||||
if(this.i === this.index){
|
|
||||||
this.mescrollTrigger()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 主动触发加载
|
|
||||||
mescrollTrigger(){
|
|
||||||
this.isInit = true; // 标记为true
|
|
||||||
if (this.mescroll) {
|
|
||||||
if (this.mescroll.optDown.use) {
|
|
||||||
this.mescroll.triggerDownScroll();
|
|
||||||
} else{
|
|
||||||
this.mescroll.triggerUpScroll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default MescrollMoreItemMixin;
|
|
||||||
@ -1,74 +0,0 @@
|
|||||||
/**
|
|
||||||
* mescroll-body写在子组件时, 需通过mescroll的mixins补充子组件缺少的生命周期
|
|
||||||
*/
|
|
||||||
const MescrollMoreMixin = {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
tabIndex: 0, // 当前tab下标
|
|
||||||
mescroll: { // mescroll-body写在子子子...组件的情况 (多级)
|
|
||||||
onPageScroll: e=>{
|
|
||||||
this.handlePageScroll(e)
|
|
||||||
},
|
|
||||||
onReachBottom: ()=>{
|
|
||||||
this.handleReachBottom()
|
|
||||||
},
|
|
||||||
onPullDownRefresh: ()=>{
|
|
||||||
this.handlePullDownRefresh()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 因为子组件无onPageScroll和onReachBottom的页面生命周期,需在页面传递进到子组件
|
|
||||||
onPageScroll(e) {
|
|
||||||
this.handlePageScroll(e)
|
|
||||||
},
|
|
||||||
onReachBottom() {
|
|
||||||
this.handleReachBottom()
|
|
||||||
},
|
|
||||||
// 当down的native: true时, 还需传递此方法进到子组件
|
|
||||||
onPullDownRefresh(){
|
|
||||||
this.handlePullDownRefresh()
|
|
||||||
},
|
|
||||||
methods:{
|
|
||||||
handlePageScroll(e){
|
|
||||||
let mescroll = this.getMescroll(this.tabIndex);
|
|
||||||
mescroll && mescroll.onPageScroll(e);
|
|
||||||
},
|
|
||||||
handleReachBottom(){
|
|
||||||
let mescroll = this.getMescroll(this.tabIndex);
|
|
||||||
mescroll && mescroll.onReachBottom();
|
|
||||||
},
|
|
||||||
handlePullDownRefresh(){
|
|
||||||
let mescroll = this.getMescroll(this.tabIndex);
|
|
||||||
mescroll && mescroll.onPullDownRefresh();
|
|
||||||
},
|
|
||||||
// 根据下标获取对应子组件的mescroll
|
|
||||||
getMescroll(i){
|
|
||||||
if(!this.mescrollItems) this.mescrollItems = [];
|
|
||||||
if(!this.mescrollItems[i]) {
|
|
||||||
// v-for中的refs
|
|
||||||
let vForItem = this.$refs["mescrollItem"];
|
|
||||||
if(vForItem){
|
|
||||||
this.mescrollItems[i] = vForItem[i]
|
|
||||||
}else{
|
|
||||||
// 普通的refs,不可重复
|
|
||||||
this.mescrollItems[i] = this.$refs["mescrollItem"+i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let item = this.mescrollItems[i]
|
|
||||||
return item ? item.mescroll : null
|
|
||||||
},
|
|
||||||
// 切换tab,恢复滚动条位置
|
|
||||||
tabChange(i){
|
|
||||||
let mescroll = this.getMescroll(i);
|
|
||||||
if(mescroll){
|
|
||||||
// 延时(比$nextTick靠谱一些),确保元素已渲染
|
|
||||||
setTimeout(()=>{
|
|
||||||
mescroll.scrollTo(mescroll.getScrollTop(),0)
|
|
||||||
},30)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default MescrollMoreMixin;
|
|
||||||
@ -94,5 +94,4 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
<view class="absolute top-[36rpx] right-[36rpx] text-[24rpx] text-[var(--text-color-light6)] leading-[30rpx] z-10" @click="clearDate">清除</view>
|
<view class="absolute top-[36rpx] right-[36rpx] text-[24rpx] text-[var(--text-color-light6)] leading-[30rpx] z-10" @click="clearDate">清除</view>
|
||||||
<view class="px-[var(--popup-sidebar-m)] mb-[20rpx] mt-[10rpx]">
|
<view class="px-[var(--popup-sidebar-m)] mb-[20rpx] mt-[10rpx]">
|
||||||
<view class="flex items-center justify-between mb-[30rpx]">
|
<view class="flex items-center justify-between mb-[30rpx]">
|
||||||
<view class="w-[160rpx] h-[66rpx] box-border flex-center rounded-[33rpx] bg-[var(--temp-bg)] text-center text-[26rpx] text-[var(--text-color-light6)] border-[2rpx] border-solid border-[var(--temp-bg)]" v-for="(item,index) in curselectDate" :key="'a'+index" :class="{'text-primary !border-[var(--primary-color)] !bg-[rgba(239,0,12,0.04)]': currentValue.type == item.type}" @click="loadDateFn(item)">{{item.name}}</view>
|
<view class="w-[160rpx] h-[66rpx] box-border flex-center rounded-[33rpx] bg-[var(--temp-bg)] text-center text-[26rpx] text-[var(--text-color-light6)] border-[2rpx] border-solid border-[var(--temp-bg)]" v-for="(item,index) in curselectDate" :key="'a'+index" :class="{'text-primary !border-[var(--primary-color)] !bg-[var(--primary-color-light)]': currentValue.type == item.type}" @click="loadDateFn(item)">{{item.name}}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="flex items-center justify-between">
|
<view class="flex items-center justify-between">
|
||||||
<view class="w-[316rpx] h-[66rpx] box-border leading-[62rpx] rounded-[33rpx] bg-[var(--temp-bg)] text-center text-[26rpx] text-[var(--text-color-light6)] border-[2rpx] border-solid border-[var(--temp-bg)]" :class="{'text-primary !border-[var(--primary-color)] !bg-[var(--primary-color-light)]': currentValue.type == 'first'}" @click="currentValue.type = 'first'">{{dateList.nowDate[0].substr(0,10)}}</view>
|
<view class="w-[316rpx] h-[66rpx] box-border leading-[62rpx] rounded-[33rpx] bg-[var(--temp-bg)] text-center text-[26rpx] text-[var(--text-color-light6)] border-[2rpx] border-solid border-[var(--temp-bg)]" :class="{'text-primary !border-[var(--primary-color)] !bg-[var(--primary-color-light)]': currentValue.type == 'first'}" @click="currentValue.type = 'first'">{{dateList.nowDate[0].substr(0,10)}}</view>
|
||||||
|
|||||||
237
uni-app/src/components/share-popup/share-popup.vue
Normal file
237
uni-app/src/components/share-popup/share-popup.vue
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 分享弹窗 -->
|
||||||
|
<view @touchmove.prevent.stop class="share-popup">
|
||||||
|
<u-popup :show="sharePopupShow" type="bottom" @close="sharePopupClose" overlayOpacity="0.8">
|
||||||
|
<view @touchmove.prevent.stop>
|
||||||
|
<view class="share-content">
|
||||||
|
<!-- #ifdef MP || APP-PLUS -->
|
||||||
|
<view class="share-box">
|
||||||
|
<button class="share-btn" :plain="true" open-type="share">
|
||||||
|
<view class="text-[#07c160] iconfont iconweixin11"></view>
|
||||||
|
<text>分享给好友</text>
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
<!-- #endif -->
|
||||||
|
|
||||||
|
<!-- #ifdef H5 -->
|
||||||
|
<view class="share-box" @click="copyUrl">
|
||||||
|
<button class="share-btn" :plain="true">
|
||||||
|
<view class="text-[#07c160] iconfont iconfuzhilianjie"></view>
|
||||||
|
<text>复制链接</text>
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
<!-- #endif -->
|
||||||
|
</view>
|
||||||
|
<view class="share-footer" @click="sharePopupClose"><text>取消分享</text></view>
|
||||||
|
</view>
|
||||||
|
</u-popup>
|
||||||
|
<u-popup :show="show" mode="center" :round="10" :closeable="true" @close="show = false" :safe-area-inset-bottom="false">
|
||||||
|
<view class="dialog-popup">
|
||||||
|
<view class="title">提示</view>
|
||||||
|
<view class="message">您拒绝了保存图片到相册的授权请求,无法保存图片到相册,如需正常使用,请授权之后再进行操作。</view>
|
||||||
|
<view class="action-wrap">
|
||||||
|
<view @click="closeDialog">取消</view>
|
||||||
|
<view>
|
||||||
|
<button type="default" class="authorization-btn" open-type="openSetting" @opensetting="closeDialog" hover-class="none">立即授权</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</u-popup>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { img, copy } from '@/utils/common';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
copyUrl: { // 例 "/wap/addon/shop_fenxiao/pages/goods"
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
copyUrlParam: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emits = defineEmits(['close'])
|
||||||
|
|
||||||
|
const sharePopupShow = ref(false);
|
||||||
|
|
||||||
|
// 复制
|
||||||
|
const copyUrl = () => {
|
||||||
|
let data = ''
|
||||||
|
if (props.copyUrl) {
|
||||||
|
let pathName = location.pathname;
|
||||||
|
let packageArr: any = ['/app/', '/addon/'];
|
||||||
|
for (let i = 0; i < packageArr.length; i++) {
|
||||||
|
if (pathName.indexOf(packageArr[i]) != -1) {
|
||||||
|
pathName = pathName.substr(0, pathName.indexOf(packageArr[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data = location.origin + pathName + props.copyUrl + props.copyUrlParam;
|
||||||
|
} else {
|
||||||
|
data = location.origin + location.pathname + props.copyUrlParam;
|
||||||
|
}
|
||||||
|
copy(data, () => {
|
||||||
|
sharePopupShow.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const openShare = ()=>{
|
||||||
|
sharePopupShow.value = true
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const show = ref(false);
|
||||||
|
|
||||||
|
const closeDialog = ()=> {
|
||||||
|
show.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const shareTop: any = ref(0)
|
||||||
|
/************ 获取微信头部-start ****************/
|
||||||
|
// 获取系统状态栏的高度
|
||||||
|
let menuButtonInfo: any = {};
|
||||||
|
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API,尚未兼容)
|
||||||
|
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
|
||||||
|
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
||||||
|
shareTop.value = menuButtonInfo.top + menuButtonInfo.height + 'px';
|
||||||
|
// #endif
|
||||||
|
/************ 获取微信头部-end ****************/
|
||||||
|
|
||||||
|
const sharePopupClose = ()=>{
|
||||||
|
sharePopupShow.value = false;
|
||||||
|
emits('close');
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
openShare
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.share-popup {
|
||||||
|
:deep(.u-transition), :deep(.u-popup__content){
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
.share-content {
|
||||||
|
border-top-left-radius: 40rpx;
|
||||||
|
border-top-right-radius: 40rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
display: -webkit-flex;
|
||||||
|
-webkit-flex-wrap: wrap;
|
||||||
|
-moz-flex-wrap: wrap;
|
||||||
|
-ms-flex-wrap: wrap;
|
||||||
|
-o-flex-wrap: wrap;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
padding: 40rpx 15rpx ;
|
||||||
|
background-color: #fff;
|
||||||
|
|
||||||
|
.share-box {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.share-btn {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: none;
|
||||||
|
line-height: 1;
|
||||||
|
height: auto;
|
||||||
|
background: none;
|
||||||
|
|
||||||
|
text {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
display: block;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
font-size: 80rpx;
|
||||||
|
line-height: initial;
|
||||||
|
}
|
||||||
|
.icon-fuzhilianjie,
|
||||||
|
.icon-pengyouquan,
|
||||||
|
.icon-haowuquan,
|
||||||
|
.icon-share-friend {
|
||||||
|
color: #07c160;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.share-footer {
|
||||||
|
background-color: #fff;
|
||||||
|
height: 90rpx;
|
||||||
|
line-height: 90rpx;
|
||||||
|
border-top: 2rpx solid #eee;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.dialog-popup {
|
||||||
|
width: 580rpx;
|
||||||
|
background: #fff;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
height: initial;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
padding: 30rpx 30rpx 0 30rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
padding: 0 30rpx;
|
||||||
|
color: #666;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1.3;
|
||||||
|
margin-top: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-wrap {
|
||||||
|
margin-top: 50rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
display: flex;
|
||||||
|
border-top: 2rpx solid #eee;
|
||||||
|
|
||||||
|
&>view {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 80rpx;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
border-right: 2rpx solid #eee;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border: none;
|
||||||
|
line-height: 80rpx;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.authorization-btn{
|
||||||
|
background-color: #07c160;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 28rpx;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
59
uni-app/src/components/sow-show/sow-show.vue
Normal file
59
uni-app/src/components/sow-show/sow-show.vue
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<template>
|
||||||
|
<view class="card-template mt-[var(--top-m)]" v-if="items.list && items.list.length>0">
|
||||||
|
<view class="flex justify-between items-center" @click="toLink">
|
||||||
|
<view class="text-[30rpx]">
|
||||||
|
<text>种草秀</text>
|
||||||
|
<text class="ml-[6rpx] text-[24rpx] text-[var(--text-color-light9)]" v-if="items.count">({{items.count}})</text>
|
||||||
|
</view>
|
||||||
|
<text class="nc-iconfont nc-icon-youV6xx text-[26rpx] text-[var(--text-color-light6)] ml-[8rpx]"></text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="grid grid-cols-3 gap-2 mt-[20rpx]">
|
||||||
|
<view class="w-[210rpx] h-[210rpx]" v-for="(item, index) in items.list" :key="index" @click="handleClick(item)">
|
||||||
|
<image :src="img(item.content_cover)" mode="aspectFill" class="w-[210rpx] h-[210rpx] rounded-[20rpx]" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref,onMounted} from 'vue';
|
||||||
|
import { img,redirect } from '@/utils/common';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
items: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
default: () => ({}),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const treasureId = ref(null);
|
||||||
|
|
||||||
|
function extractTreasureId(url) {
|
||||||
|
const match = url.match(/treasure_id=(\d+)/);
|
||||||
|
return match ? match[1] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (props.items && props.items.url) {
|
||||||
|
treasureId.value = extractTreasureId(props.items.url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const toLink = () => {
|
||||||
|
redirect({ url: '/addon/sow_community/pages/sow_show', param: { treasure_id: treasureId.value }})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClick = (item:any) => {
|
||||||
|
if(item.content_type == 1){
|
||||||
|
redirect({url: '/addon/sow_community/pages/image/detail', param: { content_id: item.content_id }})
|
||||||
|
}else{
|
||||||
|
redirect({url: '/addon/sow_community/pages/video/detail', param: { content_id: item.content_id }})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@ -1,15 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<template v-if="tabbar && Object.keys(tabbar).length">
|
<template v-if="tabbar && Object.keys(tabbar).length">
|
||||||
<u-tabbar :value="value" zIndex="9999" :fixed="true" :placeholder="true" :safeAreaInsetBottom="true"
|
<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">
|
||||||
:inactive-color="tabbar.value.textColor" :active-color="tabbar.value.textHoverColor">
|
|
||||||
<block v-for="item in tabbar.value.list">
|
<block v-for="item in tabbar.value.list">
|
||||||
<u-tabbar-item class="py-[5rpx]" :style="{'background-color': tabbar.value.backgroundColor}" :text="item.text"
|
<u-tabbar-item class="py-[5rpx]" :custom-style="{'background-color': tabbar.value.backgroundColor}" :text="item.text"
|
||||||
:icon="img(value == item.link.url ? item.iconSelectPath : item.iconPath)" :name="item.link.url"
|
:icon="img(value == item.link.url ? item.iconSelectPath : item.iconPath)" :name="item.link.url"
|
||||||
v-if="tabbar.value.type == 1" @click="itemBtn(item.link.url)"></u-tabbar-item>
|
v-if="tabbar.value.type == 1" @click="itemBtn(item.link.url)"></u-tabbar-item>
|
||||||
<u-tabbar-item class="py-[5rpx]" :style="{'background-color': tabbar.value.backgroundColor}"
|
<u-tabbar-item class="py-[5rpx]" :custom-style="{'background-color': tabbar.value.backgroundColor}"
|
||||||
:icon="img(value == item.link.url ? item.iconSelectPath : item.iconPath)" :name="item.link.url"
|
: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>
|
v-if="tabbar.value.type == 2" @click="itemBtn(item.link.url)"></u-tabbar-item>
|
||||||
<u-tabbar-item class="py-[5rpx]" :style="{'background-color': tabbar.value.backgroundColor}" :text="item.text" :name="item.link.url"
|
<u-tabbar-item class="py-[5rpx]" :custom-style="{'background-color': tabbar.value.backgroundColor}" :text="item.text" :name="item.link.url"
|
||||||
v-if="tabbar.value.type == 3" @click="itemBtn(item.link.url)"></u-tabbar-item>
|
v-if="tabbar.value.type == 3" @click="itemBtn(item.link.url)"></u-tabbar-item>
|
||||||
</block>
|
</block>
|
||||||
</u-tabbar>
|
</u-tabbar>
|
||||||
@ -18,7 +17,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref,reactive,computed,watch } from 'vue'
|
import { reactive, computed, watch, nextTick, getCurrentInstance } from 'vue'
|
||||||
import { redirect, currRoute,currShareRoute, img } from '@/utils/common'
|
import { redirect, currRoute,currShareRoute, img } from '@/utils/common'
|
||||||
import useConfigStore from '@/stores/config'
|
import useConfigStore from '@/stores/config'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
@ -27,6 +26,20 @@
|
|||||||
addon: {
|
addon: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {
|
||||||
|
backgroundColor: '', // 背景色
|
||||||
|
textColor: '', // 文字颜色
|
||||||
|
textHoverColor: '', // 文字选中颜色
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
border: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -73,11 +86,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if (props.color) {
|
||||||
|
for (let key in props.color) {
|
||||||
|
if (props.color[key] && tabbar.value[key]) {
|
||||||
|
tabbar.value[key] = props.color[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setTabbar()
|
setTabbar()
|
||||||
@ -92,6 +111,16 @@
|
|||||||
, { immediate: true }
|
, { immediate: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.color,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if(newValue && oldValue && newValue != oldValue) {
|
||||||
|
setTabbar()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
, { immediate: true,deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
if(!props.addon) {
|
if(!props.addon) {
|
||||||
watch(
|
watch(
|
||||||
() => useConfigStore().tabbarList,
|
() => useConfigStore().tabbarList,
|
||||||
@ -113,11 +142,7 @@
|
|||||||
return '/' + currRoute() + (str.length > 0 ? '?' + str.join('&') : '')
|
return '/' + currRoute() + (str.length > 0 ? '?' + str.join('&') : '')
|
||||||
})
|
})
|
||||||
|
|
||||||
// const tabbarChange = (url : string) => {
|
const itemBtn = (url: any)=> {
|
||||||
// 外部链接
|
|
||||||
// }
|
|
||||||
|
|
||||||
const itemBtn = (url)=>{
|
|
||||||
if (url.indexOf('http') != -1 || url.indexOf('http') != -1) {
|
if (url.indexOf('http') != -1 || url.indexOf('http') != -1) {
|
||||||
|
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
@ -140,13 +165,23 @@
|
|||||||
redirect({ url, mode: 'reLaunch' })
|
redirect({ url, mode: 'reLaunch' })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
defineExpose({
|
|
||||||
|
const instance = getCurrentInstance();
|
||||||
|
nextTick(() => {
|
||||||
|
const query = uni.createSelectorQuery().in(instance);
|
||||||
|
query.select('.tab-bar-placeholder').boundingClientRect((data: any) => {
|
||||||
|
let height = data ? data.height : 0;
|
||||||
|
let tabbarInfo = {
|
||||||
|
height: height
|
||||||
|
};
|
||||||
|
uni.setStorageSync('tabbarInfo', tabbarInfo);
|
||||||
|
}).exec();
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.tab-bar-placeholder {
|
.tab-bar-placeholder {
|
||||||
padding-bottom: calc(constant(safe-area-inset-bottom) + 112rpx);
|
padding-bottom: calc(constant(safe-area-inset-bottom) + 50px);
|
||||||
padding-bottom: calc(env(safe-area-inset-bottom) + 112rpx);
|
padding-bottom: calc(env(safe-area-inset-bottom) + 50px);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -3,13 +3,13 @@
|
|||||||
<view class="u-navbar" :class="{'fixed': props.scrollBool != -1, 'absolute': props.scrollBool == -1}" :style="{ backgroundColor: bgColor}">
|
<view class="u-navbar" :class="{'fixed': props.scrollBool != -1, 'absolute': props.scrollBool == -1}" :style="{ backgroundColor: bgColor}">
|
||||||
<view class="navbar-inner" :style="{ width: '100%', height: placeholderHeight + 'px' }">
|
<view class="navbar-inner" :style="{ width: '100%', height: placeholderHeight + 'px' }">
|
||||||
<view v-if="topStatusBarData.style == 'style-1'" class="content-wrap" :class="[topStatusBarData.textAlign]" :style="navbarInnerStyle">
|
<view v-if="topStatusBarData.style == 'style-1'" class="content-wrap" :class="[topStatusBarData.textAlign]" :style="navbarInnerStyle">
|
||||||
<view v-if="isBack && isBackShow" class="back-wrap -ml-[16rpx] text-[27px] nc-iconfont nc-icon-zuoV6xx" :style="{ color: titleTextColor }" @tap="goBack"></view>
|
<view v-if="isBack" class="back-wrap -ml-[16rpx] text-[26px] nc-iconfont nc-icon-zuoV6xx" :style="{ color: titleTextColor }" @tap="goBack"></view>
|
||||||
<view class="title-wrap" :style="styleOneFontSize">
|
<view class="title-wrap" :style="styleOneFontSize">
|
||||||
{{ data.title }}
|
{{ data.title }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-if="topStatusBarData.style == 'style-2'" class="content-wrap" :style="navbarInnerStyle" @click="diyStore.toRedirect(topStatusBarData.link)">
|
<view v-if="topStatusBarData.style == 'style-2'" class="content-wrap" :style="navbarInnerStyle" @click="diyStore.toRedirect(topStatusBarData.link)">
|
||||||
<view v-if="isBack && isBackShow" class="back-wrap -ml-[16rpx] text-[27px] nc-iconfont nc-icon-zuoV6xx" :style="{ color: titleTextColor }" @tap="goBack"></view>
|
<view v-if="isBack" class="back-wrap -ml-[16rpx] text-[26px] nc-iconfont nc-icon-zuoV6xx" :style="{ color: titleTextColor }" @tap="goBack"></view>
|
||||||
<view class="title-wrap" :style="{ color: topStatusBarData.textColor }">
|
<view class="title-wrap" :style="{ color: topStatusBarData.textColor }">
|
||||||
<view>
|
<view>
|
||||||
<image :src="img(topStatusBarData.imgUrl)" mode="heightFix"></image>
|
<image :src="img(topStatusBarData.imgUrl)" mode="heightFix"></image>
|
||||||
@ -19,7 +19,7 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view v-if="topStatusBarData.style == 'style-3'" :style="navbarInnerStyle" class="content-wrap">
|
<view v-if="topStatusBarData.style == 'style-3'" :style="navbarInnerStyle" class="content-wrap">
|
||||||
<view v-if="isBack && isBackShow" class="back-wrap -ml-[16rpx] text-[27px] nc-iconfont nc-icon-zuoV6xx" :style="{ color: titleTextColor }" @tap="goBack"></view>
|
<view v-if="isBack" class="back-wrap -ml-[16rpx] text-[26px] nc-iconfont nc-icon-zuoV6xx" :style="{ color: titleTextColor }" @tap="goBack"></view>
|
||||||
<view class="title-wrap" @click="diyStore.toRedirect(topStatusBarData.link)">
|
<view class="title-wrap" @click="diyStore.toRedirect(topStatusBarData.link)">
|
||||||
<image :src="img(topStatusBarData.imgUrl)" mode="heightFix"></image>
|
<image :src="img(topStatusBarData.imgUrl)" mode="heightFix"></image>
|
||||||
</view>
|
</view>
|
||||||
@ -31,7 +31,7 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view v-if="topStatusBarData.style == 'style-4'" :style="navbarInnerStyle" class="content-wrap">
|
<view v-if="topStatusBarData.style == 'style-4'" :style="navbarInnerStyle" class="content-wrap">
|
||||||
<view v-if="isBack && isBackShow" class="back-wrap -ml-[16rpx] text-[27px] nc-iconfont nc-icon-zuoV6xx" :style="{ color: titleTextColor }" @tap="goBack"></view>
|
<view v-if="isBack" class="back-wrap -ml-[16rpx] text-[26px] nc-iconfont nc-icon-zuoV6xx" :style="{ color: titleTextColor }" @tap="goBack"></view>
|
||||||
<text class="nc-iconfont nc-icon-dizhiguanliV6xx text-[28rpx]" :style="{ color: topStatusBarData.textColor }"></text>
|
<text class="nc-iconfont nc-icon-dizhiguanliV6xx text-[28rpx]" :style="{ color: topStatusBarData.textColor }"></text>
|
||||||
<view class="title-wrap" @click.stop="locationVal.reposition()" :style="{ color: topStatusBarData.textColor }" v-if="systemStore.diyAddressInfo">{{ systemStore.diyAddressInfo.community }}</view>
|
<view class="title-wrap" @click.stop="locationVal.reposition()" :style="{ color: topStatusBarData.textColor }" v-if="systemStore.diyAddressInfo">{{ systemStore.diyAddressInfo.community }}</view>
|
||||||
<view class="title-wrap" @click.stop="locationVal.reposition()" :style="{ color: topStatusBarData.textColor }" v-else>{{ systemStore.defaultPositionAddress }}</view>
|
<view class="title-wrap" @click.stop="locationVal.reposition()" :style="{ color: topStatusBarData.textColor }" v-else>{{ systemStore.defaultPositionAddress }}</view>
|
||||||
@ -113,7 +113,7 @@ const topStatusBarData = computed(() => {
|
|||||||
const navbarInnerStyle = computed(() => {
|
const navbarInnerStyle = computed(() => {
|
||||||
let style = '';
|
let style = '';
|
||||||
|
|
||||||
if(props.isBack && isBackShow.value){
|
if(props.isBack){
|
||||||
style += 'padding-left: 30rpx;';//30=>右边留边 44=>箭头宽度 10=>箭头的右maring
|
style += 'padding-left: 30rpx;';//30=>右边留边 44=>箭头宽度 10=>箭头的右maring
|
||||||
if(topStatusBarData.value.style == 'style-1') //样式一需要居中需要有右边padding辅助
|
if(topStatusBarData.value.style == 'style-1') //样式一需要居中需要有右边padding辅助
|
||||||
style += 'padding-right:' + (40+30+10) + 'rpx;'; //30=>左边留边 44=>箭头宽度 10=>箭头的右maring
|
style += 'padding-right:' + (40+30+10) + 'rpx;'; //30=>左边留边 44=>箭头宽度 10=>箭头的右maring
|
||||||
@ -191,13 +191,14 @@ if(componentsScrollVal){
|
|||||||
/******************************* 存储滚动值-end ***********************/
|
/******************************* 存储滚动值-end ***********************/
|
||||||
|
|
||||||
/******************************* 返回按钮-start ***********************/
|
/******************************* 返回按钮-start ***********************/
|
||||||
const isBackShow = ref(false);
|
// const isBackShow = ref(false);
|
||||||
let pages = getCurrentPages();
|
let pages = getCurrentPages();
|
||||||
|
|
||||||
// 返回按钮的函数
|
// 返回按钮的函数
|
||||||
const goBack = () => {
|
const goBack = () => {
|
||||||
// 兼容小程序,未登录状态下点击某个功能跳转到登录页,不登录无法返回的情况
|
// 兼容小程序,未登录状态下点击某个功能跳转到登录页,不登录无法返回的情况
|
||||||
if(pages.length == 1 && pages[0].route == 'app/pages/auth/index'){
|
if (pages.length === 1) {
|
||||||
|
if (pages[0].route === 'app/pages/auth/index') {
|
||||||
uni.getStorage({
|
uni.getStorage({
|
||||||
key: 'loginBack',
|
key: 'loginBack',
|
||||||
success: (res: any) => {
|
success: (res: any) => {
|
||||||
@ -211,7 +212,10 @@ const goBack = () => {
|
|||||||
fail: (res) => {
|
fail: (res) => {
|
||||||
redirect({ url: '/app/pages/index/index', mode: 'switchTab' })
|
redirect({ url: '/app/pages/index/index', mode: 'switchTab' })
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
} else {
|
||||||
|
redirect({ url: '/app/pages/index/index', mode: 'switchTab' });
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
// 如果自定义了点击返回按钮的函数,则执行,否则执行返回逻辑
|
// 如果自定义了点击返回按钮的函数,则执行,否则执行返回逻辑
|
||||||
if (typeof props.customBack === 'function') {
|
if (typeof props.customBack === 'function') {
|
||||||
@ -259,12 +263,12 @@ const navbarPlaceholderHeight = () => {
|
|||||||
let imageAdsSameScreen = ref(false);
|
let imageAdsSameScreen = ref(false);
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
navbarPlaceholderHeight();
|
navbarPlaceholderHeight();
|
||||||
if (pages.length > 1) {
|
// if (pages.length > 1) {
|
||||||
isBackShow.value = true;
|
// isBackShow.value = true;
|
||||||
// 兼容小程序,未登录状态下点击某个功能跳转到登录页,不登录无法返回的情况
|
// // 兼容小程序,未登录状态下点击某个功能跳转到登录页,不登录无法返回的情况
|
||||||
}else if(pages.length == 1 && pages[0].route == 'app/pages/auth/index'){
|
// }else if(pages.length == 1 && pages[0].route == 'app/pages/auth/index'){
|
||||||
isBackShow.value = true;
|
// isBackShow.value = true;
|
||||||
}
|
// }
|
||||||
// 刷新定位
|
// 刷新定位
|
||||||
locationVal.refresh();
|
locationVal.refresh();
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { ref, reactive, computed } from 'vue';
|
import { ref, reactive, computed } from 'vue';
|
||||||
import { onLoad, onShow, onHide, onPullDownRefresh, onPageScroll, onUnload } from '@dcloudio/uni-app';
|
import { onLoad, onShow, onHide, onPageScroll, onUnload } from '@dcloudio/uni-app';
|
||||||
import { img, handleOnloadParams } from '@/utils/common';
|
import { img, handleOnloadParams } from '@/utils/common';
|
||||||
import { getDiyInfo } from '@/app/api/diy';
|
import { getDiyInfo } from '@/app/api/diy';
|
||||||
import useDiyStore from '@/app/stores/diy';
|
import useDiyStore from '@/app/stores/diy';
|
||||||
@ -8,12 +8,12 @@ export function useDiy(params: any = {}) {
|
|||||||
|
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
const diyStore = useDiyStore();
|
const diyStore = useDiyStore();
|
||||||
const pullDownRefreshCount = ref(0)
|
|
||||||
|
|
||||||
const id = ref(0)
|
const id = ref(0)
|
||||||
const name = ref(params.name || '')
|
const name = ref(params.name || '')
|
||||||
const template = ref('')
|
const template = ref('')
|
||||||
let currRoute = "" //当前路由
|
const currRoute = ref('') //当前路由
|
||||||
|
const requestData: any = reactive({});
|
||||||
|
|
||||||
// 自定义页面 数据
|
// 自定义页面 数据
|
||||||
const diyData = reactive({
|
const diyData = reactive({
|
||||||
@ -86,14 +86,14 @@ export function useDiy(params: any = {}) {
|
|||||||
onShow(() => {
|
onShow(() => {
|
||||||
/******** 解决跳转自定义页面空白问题-第二步-start **********/
|
/******** 解决跳转自定义页面空白问题-第二步-start **********/
|
||||||
let curPage: any = getCurrentPages();
|
let curPage: any = getCurrentPages();
|
||||||
currRoute = curPage[curPage.length - 1] ? curPage[curPage.length - 1].route : ''; //获取当前页面的路由
|
currRoute.value = curPage[curPage.length - 1] ? curPage[curPage.length - 1].route : ''; //获取当前页面的路由
|
||||||
let urlArr = []
|
let urlArr = []
|
||||||
if (uni.getStorageSync('diyPageBlank')) {
|
if (uni.getStorageSync('diyPageBlank')) {
|
||||||
urlArr = uni.getStorageSync('diyPageBlank');
|
urlArr = uni.getStorageSync('diyPageBlank');
|
||||||
}
|
}
|
||||||
if (!urlArr.length || urlArr.length && urlArr.indexOf(currRoute) == -1) {
|
if (!urlArr.length || urlArr.length && urlArr.indexOf(currRoute.value) == -1) {
|
||||||
diyStore.topFixedStatus = 'home'
|
diyStore.topFixedStatus = 'home'
|
||||||
} else if (urlArr.length && urlArr.indexOf(currRoute) != -1) {
|
} else if (urlArr.length && urlArr.indexOf(currRoute.value) != -1) {
|
||||||
diyStore.topFixedStatus = 'diy'
|
diyStore.topFixedStatus = 'diy'
|
||||||
}
|
}
|
||||||
/******** 解决跳转自定义页面空白问题-第二步-end **********/
|
/******** 解决跳转自定义页面空白问题-第二步-end **********/
|
||||||
@ -107,12 +107,13 @@ export function useDiy(params: any = {}) {
|
|||||||
name: name.value,
|
name: name.value,
|
||||||
template: template.value
|
template: template.value
|
||||||
}).then((res: any) => {
|
}).then((res: any) => {
|
||||||
let requestData = res.data;
|
Object.assign(requestData, res.data);
|
||||||
if (requestData.value) {
|
if (requestData.value) {
|
||||||
diyData.pageMode = requestData.mode;
|
diyData.pageMode = requestData.mode;
|
||||||
diyData.title = requestData.title;
|
diyData.title = requestData.title;
|
||||||
|
|
||||||
let sources = JSON.parse(requestData.value);
|
let sources = JSON.parse(requestData.value); // todo diy的结构应该后台处理好,前端就不需要再转换了
|
||||||
|
|
||||||
diyData.global = sources.global;
|
diyData.global = sources.global;
|
||||||
diyData.value = sources.value;
|
diyData.value = sources.value;
|
||||||
diyData.value.forEach((item: any, index) => {
|
diyData.value.forEach((item: any, index) => {
|
||||||
@ -149,7 +150,6 @@ export function useDiy(params: any = {}) {
|
|||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,7 +166,7 @@ export function useDiy(params: any = {}) {
|
|||||||
if (url.length) {
|
if (url.length) {
|
||||||
url = Array.from(new Set(url))
|
url = Array.from(new Set(url))
|
||||||
url.forEach((item, index, arr) => {
|
url.forEach((item, index, arr) => {
|
||||||
if (item == currRoute) {
|
if (item == currRoute.value) {
|
||||||
arr.splice(index, 1);
|
arr.splice(index, 1);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -174,7 +174,7 @@ export function useDiy(params: any = {}) {
|
|||||||
|
|
||||||
// 当diyStore.topFixedStatus == "diy"时,存储到diyPageBlank缓存中
|
// 当diyStore.topFixedStatus == "diy"时,存储到diyPageBlank缓存中
|
||||||
if (diyStore.topFixedStatus == "diy") {
|
if (diyStore.topFixedStatus == "diy") {
|
||||||
url.push(currRoute);
|
url.push(currRoute.value);
|
||||||
}
|
}
|
||||||
uni.setStorageSync('diyPageBlank', url);
|
uni.setStorageSync('diyPageBlank', url);
|
||||||
/******** 解决跳转自定义页面空白问题-第一步 -end **********/
|
/******** 解决跳转自定义页面空白问题-第一步 -end **********/
|
||||||
@ -190,14 +190,6 @@ export function useDiy(params: any = {}) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听下拉刷新事件
|
|
||||||
const onPullDownRefreshLifeCycle = () => {
|
|
||||||
onPullDownRefresh(() => {
|
|
||||||
pullDownRefreshCount.value++;
|
|
||||||
uni.stopPullDownRefresh();
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 监听滚动事件
|
// 监听滚动事件
|
||||||
const onPageScrollLifeCycle = () => {
|
const onPageScrollLifeCycle = () => {
|
||||||
onPageScroll((e) => {
|
onPageScroll((e) => {
|
||||||
@ -209,7 +201,6 @@ export function useDiy(params: any = {}) {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
getLoading,
|
getLoading,
|
||||||
pullDownRefreshCount,
|
|
||||||
data: data.value,
|
data: data.value,
|
||||||
isShowTopTabbar,
|
isShowTopTabbar,
|
||||||
pageStyle,
|
pageStyle,
|
||||||
@ -217,7 +208,6 @@ export function useDiy(params: any = {}) {
|
|||||||
onShow: onShowLifeCycle,
|
onShow: onShowLifeCycle,
|
||||||
onHide: onHideLifeCycle,
|
onHide: onHideLifeCycle,
|
||||||
onUnload: onUnloadLifeCycle,
|
onUnload: onUnloadLifeCycle,
|
||||||
onPullDownRefresh: onPullDownRefreshLifeCycle,
|
|
||||||
onPageScroll: onPageScrollLifeCycle,
|
onPageScroll: onPageScrollLifeCycle,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
277
uni-app/src/hooks/useDiyForm.ts
Normal file
277
uni-app/src/hooks/useDiyForm.ts
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
import { ref, reactive, computed } from 'vue';
|
||||||
|
import { onLoad, onShow, onHide, onPageScroll, onUnload } from '@dcloudio/uni-app';
|
||||||
|
import { img, handleOnloadParams, getToken, deepClone } from '@/utils/common';
|
||||||
|
import { getDiyFormInfo } from '@/app/api/diy_form';
|
||||||
|
import useDiyStore from '@/app/stores/diy';
|
||||||
|
import { useLogin } from '@/hooks/useLogin';
|
||||||
|
|
||||||
|
export function useDiyForm(params: any = {}) {
|
||||||
|
|
||||||
|
const loading = ref(true);
|
||||||
|
const diyStore = useDiyStore();
|
||||||
|
|
||||||
|
const form_id = ref(params.form_id || 0)
|
||||||
|
const name = ref(params.name || '')
|
||||||
|
const template = ref('')
|
||||||
|
const currRoute = ref('') //当前路由
|
||||||
|
const requestData: any = reactive({});
|
||||||
|
const needLogin = ref(params.needLogin || false) // 是否检测登录
|
||||||
|
|
||||||
|
// 自定义页面 数据
|
||||||
|
const diyData = reactive({
|
||||||
|
pageMode: 'diy',
|
||||||
|
title: '',
|
||||||
|
global: {},
|
||||||
|
value: [],
|
||||||
|
status: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
const getLoading = () => {
|
||||||
|
return loading.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data: any = computed(() => {
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
return diyStore;
|
||||||
|
} else {
|
||||||
|
return diyData;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const isShowTopTabbar = ref(false);
|
||||||
|
|
||||||
|
const pageStyle = () => {
|
||||||
|
var style = '';
|
||||||
|
if (data.value.global.pageStartBgColor) {
|
||||||
|
if (data.value.global.pageStartBgColor && data.value.global.pageEndBgColor) style += `background:linear-gradient(${ data.value.global.pageGradientAngle },${ data.value.global.pageStartBgColor },${ data.value.global.pageEndBgColor });`;
|
||||||
|
else style += 'background-color:' + data.value.global.pageStartBgColor + ';';
|
||||||
|
}
|
||||||
|
if (data.value.global.bottomTabBarSwitch) {
|
||||||
|
style += 'min-height:calc(100vh - 50px);';
|
||||||
|
} else {
|
||||||
|
style += 'min-height:calc(100vh);';
|
||||||
|
}
|
||||||
|
if (data.value.global.bgUrl) {
|
||||||
|
style += `background-image:url('${ img(data.value.global.bgUrl) }');`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.value.global.bgHeightScale) {
|
||||||
|
style += `background-size: 100% ${ data.value.global.bgHeightScale }%;`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return style;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 监听页面加载
|
||||||
|
const onLoadLifeCycle = (callback: any = null) => {
|
||||||
|
onLoad((option: any) => {
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
// 处理小程序场景值参数
|
||||||
|
option = handleOnloadParams(option);
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef H5
|
||||||
|
// 装修模式
|
||||||
|
diyStore.mode = option.mode || '';
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
requestData.status = 1;
|
||||||
|
requestData.error = [];
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
form_id.value = option.form_id || '';
|
||||||
|
// if (name.value == '') name.value = option.name || '';
|
||||||
|
// template.value = option.template || '';
|
||||||
|
getData(callback)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听页面显示
|
||||||
|
const onShowLifeCycle = (callback: any = null) => {
|
||||||
|
onShow(() => {
|
||||||
|
if (callback) callback(requestData)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getData = (callback: any = null) => {
|
||||||
|
/******** 解决跳转自定义页面空白问题-第二步-start **********/
|
||||||
|
let curPage: any = getCurrentPages();
|
||||||
|
currRoute.value = curPage[curPage.length - 1] ? curPage[curPage.length - 1].route : ''; //获取当前页面的路由
|
||||||
|
let urlArr = []
|
||||||
|
if (uni.getStorageSync('diyPageBlank')) {
|
||||||
|
urlArr = uni.getStorageSync('diyPageBlank');
|
||||||
|
}
|
||||||
|
if (!urlArr.length || urlArr.length && urlArr.indexOf(currRoute.value) == -1) {
|
||||||
|
diyStore.topFixedStatus = 'home'
|
||||||
|
} else if (urlArr.length && urlArr.indexOf(currRoute.value) != -1) {
|
||||||
|
diyStore.topFixedStatus = 'diy'
|
||||||
|
}
|
||||||
|
/******** 解决跳转自定义页面空白问题-第二步-end **********/
|
||||||
|
|
||||||
|
// 装修模式
|
||||||
|
if (diyStore.mode == 'decorate') {
|
||||||
|
diyStore.init();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (!form_id.value) return; // 空值情况下不调用接口
|
||||||
|
|
||||||
|
// 填写万能表单需要检测登录
|
||||||
|
if (needLogin.value && !getToken()) {
|
||||||
|
useLogin().setLoginBack({
|
||||||
|
url: '/app/pages/index/diy_form',
|
||||||
|
param: {
|
||||||
|
form_id: form_id.value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
getDiyFormInfo({
|
||||||
|
form_id: form_id.value,
|
||||||
|
// name: name.value, todo 暂时没用
|
||||||
|
// template: template.value // todo 暂时没用
|
||||||
|
}).then((res: any) => {
|
||||||
|
Object.assign(requestData, res.data);
|
||||||
|
diyData.status = res.data.status;
|
||||||
|
if (requestData.value) {
|
||||||
|
diyData.pageMode = requestData.mode;
|
||||||
|
diyData.title = requestData.title;
|
||||||
|
|
||||||
|
diyStore.id = requestData.form_id;
|
||||||
|
let sources = requestData.value;
|
||||||
|
// 匹配缓存,赋值
|
||||||
|
let diyFormStorage = uni.getStorageSync('diyFormStorage_' + diyStore.id)
|
||||||
|
if (diyFormStorage) {
|
||||||
|
var date = new Date();
|
||||||
|
let currentTime: any = parseInt(date.getTime() / 1000); // 定位信息 5分钟内有效,过期后将重新获取定位信息
|
||||||
|
if (diyFormStorage.validTime > currentTime) {
|
||||||
|
if (diyFormStorage.components) {
|
||||||
|
diyFormStorage.components.forEach((item: any) => {
|
||||||
|
for (let i = 0; i < sources.value.length; i++) {
|
||||||
|
if (sources.value[i].componentType == 'diy_form' && item.id == sources.value[i].id) {
|
||||||
|
let comp = deepClone(item);
|
||||||
|
let field = deepClone(comp.field);
|
||||||
|
delete comp.field;
|
||||||
|
// 移除不需要的数据
|
||||||
|
delete field.required; // 是否必填
|
||||||
|
delete field.unique; // 内容不可重复提交
|
||||||
|
delete field.autofill; // 自动填充上次填写的内容
|
||||||
|
delete field.privacyProtection; // 隐私保护
|
||||||
|
Object.assign(sources.value[i], comp)
|
||||||
|
Object.assign(sources.value[i].field, field)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uni.removeStorageSync('diyFormStorage_' + diyStore.id) // 清除过期的表单缓存数据
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diyStore.value = sources.value; // 用于 万能表单 收集数据,组件之间的数据通讯
|
||||||
|
diyData.global = sources.global;
|
||||||
|
diyData.value = sources.value;
|
||||||
|
diyData.value.forEach((item: any, index) => {
|
||||||
|
if (item.isHidden) {
|
||||||
|
// 隐藏组件
|
||||||
|
diyData.value.splice(index, 1)
|
||||||
|
// 过滤表单-提交组件且按钮悬空的情况下不设置样式
|
||||||
|
} else {
|
||||||
|
item.pageStyle = '';
|
||||||
|
if (item.componentName != 'FormSubmit' || item.componentName == 'FormSubmit' && item.btnPosition != 'hover_screen_bottom') {
|
||||||
|
if (item.pageStartBgColor) {
|
||||||
|
if (item.pageStartBgColor && item.pageEndBgColor) item.pageStyle += `background:linear-gradient(${ item.pageGradientAngle },${ item.pageStartBgColor },${ item.pageEndBgColor });`;
|
||||||
|
else item.pageStyle += 'background-color:' + item.pageStartBgColor + ';';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.margin) {
|
||||||
|
if (item.margin.top > 0) {
|
||||||
|
item.pageStyle += 'padding-top:' + item.margin.top * 2 + 'rpx' + ';';
|
||||||
|
}
|
||||||
|
item.pageStyle += 'padding-bottom:' + item.margin.bottom * 2 + 'rpx' + ';';
|
||||||
|
item.pageStyle += 'padding-right:' + item.margin.both * 2 + 'rpx' + ';';
|
||||||
|
item.pageStyle += 'padding-left:' + item.margin.both * 2 + 'rpx' + ';';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 控制自定义头部是否出现 | 微信小程序
|
||||||
|
isShowTopTabbar.value = diyData.value.some((item: any) => {
|
||||||
|
return item && item.position && item.position == 'top_fixed'
|
||||||
|
});
|
||||||
|
|
||||||
|
uni.setNavigationBarTitle({
|
||||||
|
title: diyData.title
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
loading.value = false;
|
||||||
|
|
||||||
|
if (callback) callback(requestData)
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听页面隐藏
|
||||||
|
const onHideLifeCycle = (callback: any = null) => {
|
||||||
|
onHide(() => {
|
||||||
|
/******** 解决跳转自定义页面空白问题-第一步 -start **********/
|
||||||
|
let url = [];
|
||||||
|
if (uni.getStorageSync('diyPageBlank')) {
|
||||||
|
url = uni.getStorageSync('diyPageBlank');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清空重复、与当前页面路径一致的url
|
||||||
|
if (url.length) {
|
||||||
|
url = Array.from(new Set(url))
|
||||||
|
url.forEach((item, index, arr) => {
|
||||||
|
if (item == currRoute.value) {
|
||||||
|
arr.splice(index, 1);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当diyStore.topFixedStatus == "diy"时,存储到diyPageBlank缓存中
|
||||||
|
if (diyStore.topFixedStatus == "diy") {
|
||||||
|
url.push(currRoute.value);
|
||||||
|
}
|
||||||
|
uni.setStorageSync('diyPageBlank', url);
|
||||||
|
/******** 解决跳转自定义页面空白问题-第一步 -end **********/
|
||||||
|
|
||||||
|
if (callback) callback()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听页面卸载
|
||||||
|
const onUnloadLifeCycle = () => {
|
||||||
|
onUnload(() => {
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听滚动事件
|
||||||
|
const onPageScrollLifeCycle = () => {
|
||||||
|
onPageScroll((e) => {
|
||||||
|
if (e.scrollTop > 0) {
|
||||||
|
diyStore.scrollTop = e.scrollTop;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
getLoading,
|
||||||
|
requestData,
|
||||||
|
data: data.value,
|
||||||
|
isShowTopTabbar,
|
||||||
|
pageStyle,
|
||||||
|
onLoad: onLoadLifeCycle,
|
||||||
|
onShow: onShowLifeCycle,
|
||||||
|
onHide: onHideLifeCycle,
|
||||||
|
onUnload: onUnloadLifeCycle,
|
||||||
|
onPageScroll: onPageScrollLifeCycle,
|
||||||
|
getData
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { redirect, isWeixinBrowser, urlDeconstruction } from '@/utils/common'
|
import { redirect, isWeixinBrowser, urlDeconstruction, currRoute } from '@/utils/common'
|
||||||
import {
|
import {
|
||||||
weappLogin,
|
weappLogin,
|
||||||
updateWeappOpenid,
|
updateWeappOpenid,
|
||||||
@ -23,15 +23,13 @@ export function useLogin() {
|
|||||||
|
|
||||||
// #ifdef MP-WEIXIN
|
// #ifdef MP-WEIXIN
|
||||||
if (!uni.getStorageSync('autoLoginLock') && uni.getStorageSync('openid') && config.login.is_bind_mobile) {
|
if (!uni.getStorageSync('autoLoginLock') && uni.getStorageSync('openid') && config.login.is_bind_mobile) {
|
||||||
uni.setStorageSync('isbindmobile', true)
|
uni.setStorageSync('isbindmobile', true) // 强制绑定手机号标识
|
||||||
return
|
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
if (!uni.getStorageSync('autoLoginLock') && isWeixinBrowser() && uni.getStorageSync('openid') && config.login.is_bind_mobile) {
|
if (!uni.getStorageSync('autoLoginLock') && isWeixinBrowser() && uni.getStorageSync('openid') && config.login.is_bind_mobile) {
|
||||||
uni.setStorageSync('isbindmobile', true)
|
uni.setStorageSync('isbindmobile', true) // 强制绑定手机号标识
|
||||||
return
|
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
@ -70,6 +68,7 @@ export function useLogin() {
|
|||||||
// #endif
|
// #endif
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行登录后跳转
|
* 执行登录后跳转
|
||||||
*/
|
*/
|
||||||
@ -97,7 +96,11 @@ export function useLogin() {
|
|||||||
*/
|
*/
|
||||||
const authLogin = (params: any) => {
|
const authLogin = (params: any) => {
|
||||||
let obj: any = {
|
let obj: any = {
|
||||||
code: params.code
|
code: params.code,
|
||||||
|
nickname: params.nickname,
|
||||||
|
headimg: params.headimg,
|
||||||
|
mobile: params.mobile,
|
||||||
|
mobile_code: params.mobile_code
|
||||||
};
|
};
|
||||||
|
|
||||||
// #ifdef MP-WEIXIN
|
// #ifdef MP-WEIXIN
|
||||||
@ -126,7 +129,7 @@ export function useLogin() {
|
|||||||
if (params.backFlag) handleLoginBack() // 一键登录返回
|
if (params.backFlag) handleLoginBack() // 一键登录返回
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// 目前业务不会执行到这里
|
// 强制获取昵称和头像,先存储起来
|
||||||
uni.setStorageSync('openid', res.data.openid)
|
uni.setStorageSync('openid', res.data.openid)
|
||||||
uni.setStorageSync('unionid', res.data.unionid)
|
uni.setStorageSync('unionid', res.data.unionid)
|
||||||
}
|
}
|
||||||
@ -153,11 +156,18 @@ export function useLogin() {
|
|||||||
if (config.login.is_bind_mobile && memberInfo && !memberInfo.mobile) {
|
if (config.login.is_bind_mobile && memberInfo && !memberInfo.mobile) {
|
||||||
uni.setStorageSync('isbindmobile', true)
|
uni.setStorageSync('isbindmobile', true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let loginBack = uni.getStorageSync('loginBack');
|
||||||
|
if (loginBack && loginBack.url && currRoute() == 'app/pages/auth/index') {
|
||||||
|
handleLoginBack(); // 跳转到上一个页面
|
||||||
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// 目前业务不会执行到这里
|
// 强制获取昵称和头像,先存储起来
|
||||||
uni.setStorageSync('openid', res.data.openid)
|
uni.setStorageSync('openid', res.data.openid)
|
||||||
uni.setStorageSync('unionid', res.data.unionid)
|
uni.setStorageSync('unionid', res.data.unionid)
|
||||||
|
if(res.data.nickname) uni.setStorageSync('nickname', res.data.nickname)
|
||||||
|
if(res.data.avatar) uni.setStorageSync('avatar', res.data.avatar)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -210,6 +220,10 @@ export function useLogin() {
|
|||||||
params.updateFlag = params.updateFlag || false; // updateFlag:更新oppenid
|
params.updateFlag = params.updateFlag || false; // updateFlag:更新oppenid
|
||||||
params.backFlag = params.backFlag || false; // backFlag 控制一键登录返回
|
params.backFlag = params.backFlag || false; // backFlag 控制一键登录返回
|
||||||
params.successCallback = params.successCallback || null;
|
params.successCallback = params.successCallback || null;
|
||||||
|
params.nickname = params.nickname || '';
|
||||||
|
params.headimg = params.headimg || '';
|
||||||
|
params.mobile = params.mobile || '';
|
||||||
|
params.mobile_code = params.mobile_code || '';
|
||||||
|
|
||||||
// #ifdef MP-WEIXIN
|
// #ifdef MP-WEIXIN
|
||||||
wx.login({
|
wx.login({
|
||||||
@ -217,6 +231,10 @@ export function useLogin() {
|
|||||||
if (res.code) {
|
if (res.code) {
|
||||||
params.updateFlag ? updateOpenid(res.code) : authLogin({
|
params.updateFlag ? updateOpenid(res.code) : authLogin({
|
||||||
code: res.code,
|
code: res.code,
|
||||||
|
nickname: params.nickname,
|
||||||
|
headimg: params.headimg,
|
||||||
|
mobile: params.mobile,
|
||||||
|
mobile_code: params.mobile_code,
|
||||||
backFlag: params.backFlag,
|
backFlag: params.backFlag,
|
||||||
successCallback: params.successCallback
|
successCallback: params.successCallback
|
||||||
})
|
})
|
||||||
|
|||||||
@ -5,6 +5,8 @@
|
|||||||
"pages.index.develop": "开发环境配置",
|
"pages.index.develop": "开发环境配置",
|
||||||
"pages.index.diy": "",
|
"pages.index.diy": "",
|
||||||
"pages.index.diy_form": "",
|
"pages.index.diy_form": "",
|
||||||
|
"pages.index.diy_form_result": "",
|
||||||
|
"pages.index.diy_form_detail": "表单详情",
|
||||||
"pages.article.list": "资讯中心",
|
"pages.article.list": "资讯中心",
|
||||||
"pages.article.detail": "文章详情",
|
"pages.article.detail": "文章详情",
|
||||||
"pages.auth.index": "登录",
|
"pages.auth.index": "登录",
|
||||||
@ -98,7 +100,7 @@
|
|||||||
"shop.pages.point.detail": "积分商品详情",
|
"shop.pages.point.detail": "积分商品详情",
|
||||||
"shop.pages.point.payment": "待付款订单",
|
"shop.pages.point.payment": "待付款订单",
|
||||||
"shop.pages.point.order_list": "积分兑换记录",
|
"shop.pages.point.order_list": "积分兑换记录",
|
||||||
"shop.pages.newcomer.list":"新人专享列表",
|
"shop.pages.newcomer.list": "新人专享",
|
||||||
"cms.pages.list": "资讯中心",
|
"cms.pages.list": "资讯中心",
|
||||||
"cms.pages.detail": "文章详情",
|
"cms.pages.detail": "文章详情",
|
||||||
"shop_fenxiao.pages.index": "分销中心",
|
"shop_fenxiao.pages.index": "分销中心",
|
||||||
@ -106,7 +108,7 @@
|
|||||||
"shop_fenxiao.pages.level": "分销商等级",
|
"shop_fenxiao.pages.level": "分销商等级",
|
||||||
"shop_fenxiao.pages.child_fenxiao": "分销商",
|
"shop_fenxiao.pages.child_fenxiao": "分销商",
|
||||||
"shop_fenxiao.pages.goods": "分销商品",
|
"shop_fenxiao.pages.goods": "分销商品",
|
||||||
"shop_fenxiao.pages.team": "团队",
|
"shop_fenxiao.pages.team": "我的团队",
|
||||||
"shop_fenxiao.pages.ranking_list": "排行榜",
|
"shop_fenxiao.pages.ranking_list": "排行榜",
|
||||||
"shop_fenxiao.pages.agent_list": "渠道代理",
|
"shop_fenxiao.pages.agent_list": "渠道代理",
|
||||||
"shop_fenxiao.pages.bill": "账单",
|
"shop_fenxiao.pages.bill": "账单",
|
||||||
@ -118,8 +120,8 @@
|
|||||||
"shop_fenxiao.pages.task_rewards_detail": "任务奖励明细",
|
"shop_fenxiao.pages.task_rewards_detail": "任务奖励明细",
|
||||||
"shop_fenxiao.pages.sale": "销售奖励",
|
"shop_fenxiao.pages.sale": "销售奖励",
|
||||||
"shop_fenxiao.pages.sale_detail": "销售奖励详情",
|
"shop_fenxiao.pages.sale_detail": "销售奖励详情",
|
||||||
"shop_fenxiao.pages.sale_ranking": "销售排行榜",
|
"shop_fenxiao.pages.sale_ranking": "销售奖励排行榜",
|
||||||
"shop_fenxiao.pages.promote_code": "分销推广",
|
"shop_fenxiao.pages.promote_code": "分享海报",
|
||||||
"shop_giftcard.pages.index": "礼品卡首页",
|
"shop_giftcard.pages.index": "礼品卡首页",
|
||||||
"shop_giftcard.pages.list": "礼品卡列表",
|
"shop_giftcard.pages.list": "礼品卡列表",
|
||||||
"shop_giftcard.pages.detail": "加载中",
|
"shop_giftcard.pages.detail": "加载中",
|
||||||
@ -136,5 +138,42 @@
|
|||||||
"shop_giftcard.pages.receive_info": "领取礼品卡",
|
"shop_giftcard.pages.receive_info": "领取礼品卡",
|
||||||
"shop_giftcard.pages.use_card": "礼品卡使用",
|
"shop_giftcard.pages.use_card": "礼品卡使用",
|
||||||
"shop_giftcard.pages.use_goods_select": "选择兑换商品",
|
"shop_giftcard.pages.use_goods_select": "选择兑换商品",
|
||||||
"shop_giftcard.pages.payment": "待付款订单"
|
"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":"话题列表"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -99,5 +99,35 @@
|
|||||||
"emptyAddress": "暂无收货地址,请先创建地址",
|
"emptyAddress": "暂无收货地址,请先创建地址",
|
||||||
"addAddress": "新增收货地址",
|
"addAddress": "新增收货地址",
|
||||||
"selectAddress": "选择地址",
|
"selectAddress": "选择地址",
|
||||||
"coupon": "优惠劵"
|
"coupon": "优惠劵",
|
||||||
|
"tourism.orderNo": "订单号",
|
||||||
|
"tourism.rise": "起",
|
||||||
|
"tourism.starLevel": "星级",
|
||||||
|
"tourism.star": "星",
|
||||||
|
"vipcard.cardReserve": "项目预约",
|
||||||
|
"vipcard.card": "办理次卡",
|
||||||
|
"vipcard.reserveSuccess": "预约成功",
|
||||||
|
"vipcard.reserve": "预约",
|
||||||
|
"vipcard.cardLink": "次卡",
|
||||||
|
"vipcard.reserveBtn": "去抢购",
|
||||||
|
"vipcard.cardBtn": "办理",
|
||||||
|
"vipcard.soldOut": "已售",
|
||||||
|
"vipcard.orderNo": "订单号",
|
||||||
|
"vipcard.myLink": "我的",
|
||||||
|
"vipcard.memberCode": "会员码",
|
||||||
|
"recharge.orderNo": "订单号",
|
||||||
|
"shop.orderNo": "订单号",
|
||||||
|
"shop.actualPayment": "实付款",
|
||||||
|
"shop.orderClose": "关闭订单",
|
||||||
|
"shop.orderFinish": "确认收货",
|
||||||
|
"shop.coupon": "优惠劵",
|
||||||
|
"o2o.way": "线路",
|
||||||
|
"o2o.hotel": "酒店",
|
||||||
|
"o2o.scenic": "景点",
|
||||||
|
"o2o.reserveBtn": "去抢购",
|
||||||
|
"o2o.noHomeAddress": "没有更多内容啦~",
|
||||||
|
"o2o.soldOut": "已售",
|
||||||
|
"o2o.orderNo": "订单号",
|
||||||
|
"o2o.actualPayment": "实付款",
|
||||||
|
"o2o.orderDetail": "详情"
|
||||||
}
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name" : "",
|
"name" : "",
|
||||||
"appid" : "__UNI__713550E",
|
"appid" : "__UNI__ED923AB",
|
||||||
"description" : "",
|
"description" : "",
|
||||||
"versionName" : "1.0.0",
|
"versionName" : "1.0.0",
|
||||||
"versionCode" : "100",
|
"versionCode" : "100",
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"pages": [ // pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
"pages": [
|
||||||
|
// pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||||
{
|
{
|
||||||
"path": "app/pages/index/index",
|
"path": "app/pages/index/index",
|
||||||
"style": {
|
"style": {
|
||||||
@ -8,12 +9,10 @@
|
|||||||
// #endif
|
// #endif
|
||||||
"navigationBarTitleText": "%pages.index.index%",
|
"navigationBarTitleText": "%pages.index.index%",
|
||||||
"usingComponents": {
|
"usingComponents": {
|
||||||
"diy-group": "../../../../addon/components/diy/group/index",
|
"diy-group": "../../../../addon/components/diy/group/index"
|
||||||
"fixed-group": "../../../../addon/components/fixed/group/index"
|
|
||||||
},
|
},
|
||||||
"componentPlaceholder": {
|
"componentPlaceholder": {
|
||||||
"diy-group": "view",
|
"diy-group": "view"
|
||||||
"fixed-group": "view"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -76,15 +75,45 @@
|
|||||||
// #endif
|
// #endif
|
||||||
"navigationBarTitleText": "%pages.index.diy%",
|
"navigationBarTitleText": "%pages.index.diy%",
|
||||||
"usingComponents": {
|
"usingComponents": {
|
||||||
"diy-group": "../../../../addon/components/diy/group/index",
|
"diy-group": "../../../../addon/components/diy/group/index"
|
||||||
"fixed-group": "../../../../addon/components/fixed/group/index"
|
|
||||||
},
|
},
|
||||||
"componentPlaceholder": {
|
"componentPlaceholder": {
|
||||||
"diy-group": "view",
|
"diy-group": "view"
|
||||||
"fixed-group": "view"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "app/pages/index/diy_form",
|
||||||
|
"style": {
|
||||||
|
// #ifndef H5
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
// #endif
|
||||||
|
"navigationBarTitleText": "%pages.index.diy_form%",
|
||||||
|
"usingComponents": {
|
||||||
|
"diy-group": "../../../../addon/components/diy/group/index"
|
||||||
|
},
|
||||||
|
"componentPlaceholder": {
|
||||||
|
"diy-group": "view"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "app/pages/index/diy_form_result",
|
||||||
|
"style": {
|
||||||
|
// #ifndef H5
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
// #endif
|
||||||
|
"navigationBarTitleText": "%pages.index.diy_form_result%"
|
||||||
|
},
|
||||||
|
"needLogin": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "app/pages/index/diy_form_detail",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "%pages.index.diy_form_detail%"
|
||||||
|
},
|
||||||
|
"needLogin": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "app/pages/index/close",
|
"path": "app/pages/index/close",
|
||||||
"style": {
|
"style": {
|
||||||
@ -97,146 +126,6 @@
|
|||||||
"navigationBarTitleText": "%pages.index.nosite%"
|
"navigationBarTitleText": "%pages.index.nosite%"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"path": "app/pages/member/apply_cash_out",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "%pages.member.apply_cash_out%"
|
|
||||||
},
|
|
||||||
"needLogin": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "app/pages/member/commission",
|
|
||||||
"style": {
|
|
||||||
// #ifndef H5
|
|
||||||
"navigationStyle": "custom",
|
|
||||||
// #endif
|
|
||||||
"navigationBarTitleText": "%pages.member.commission%"
|
|
||||||
},
|
|
||||||
"needLogin": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "app/pages/member/balance",
|
|
||||||
"style": {
|
|
||||||
// #ifndef H5
|
|
||||||
"navigationStyle": "custom",
|
|
||||||
// #endif
|
|
||||||
"navigationBarTitleText": "%pages.member.balance%"
|
|
||||||
},
|
|
||||||
"needLogin": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "app/pages/member/level",
|
|
||||||
"style": {
|
|
||||||
// #ifndef H5
|
|
||||||
"navigationStyle": "custom",
|
|
||||||
// #endif
|
|
||||||
"navigationBarTitleText": "%pages.member.level%"
|
|
||||||
},
|
|
||||||
"needLogin": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "app/pages/member/detailed_account",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "%pages.member.detailed_account%"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "app/pages/member/cash_out",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "%pages.member.cash_out%"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "app/pages/member/cash_out_detail",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "%pages.member.cash_out_detail%"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "app/pages/member/index",
|
|
||||||
"style": {
|
|
||||||
// #ifndef H5
|
|
||||||
"navigationStyle": "custom",
|
|
||||||
// #endif
|
|
||||||
"navigationBarTitleText": "%pages.member.index%",
|
|
||||||
"usingComponents": {
|
|
||||||
"diy-group": "../../../../addon/components/diy/group/index",
|
|
||||||
"fixed-group": "../../../../addon/components/fixed/group/index"
|
|
||||||
},
|
|
||||||
"componentPlaceholder": {
|
|
||||||
"diy-group": "view",
|
|
||||||
"fixed-group": "view"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "app/pages/member/personal",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "%pages.member.personal%"
|
|
||||||
},
|
|
||||||
"needLogin": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "app/pages/member/point",
|
|
||||||
"style": {
|
|
||||||
// #ifndef H5
|
|
||||||
"navigationStyle": "custom",
|
|
||||||
// #endif
|
|
||||||
"navigationBarTitleText": "%pages.member.point%"
|
|
||||||
},
|
|
||||||
"needLogin": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "app/pages/member/point_detail",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "%pages.member.point_detail%"
|
|
||||||
},
|
|
||||||
"needLogin": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "app/pages/member/account",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "%pages.member.account%"
|
|
||||||
},
|
|
||||||
"needLogin": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "app/pages/member/account_edit",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "%pages.member.account_edit%"
|
|
||||||
},
|
|
||||||
"needLogin": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "app/pages/member/address",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "%pages.member.address%"
|
|
||||||
},
|
|
||||||
"needLogin": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "app/pages/member/address_edit",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "%pages.member.address_edit%"
|
|
||||||
},
|
|
||||||
"needLogin": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "app/pages/member/sign_in",
|
|
||||||
"style": {
|
|
||||||
// #ifndef H5
|
|
||||||
"navigationStyle": "custom",
|
|
||||||
// #endif
|
|
||||||
"navigationBarTitleText": "%pages.member.sign_in%"
|
|
||||||
},
|
|
||||||
"needLogin": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "app/pages/member/contact",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "%pages.member.contact%"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"path": "app/pages/pay/browser",
|
"path": "app/pages/pay/browser",
|
||||||
"style": {
|
"style": {
|
||||||
@ -326,13 +215,152 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"subPackages": [
|
"subPackages": [
|
||||||
{
|
|
||||||
"root": "addon",
|
|
||||||
"pages": [
|
|
||||||
// {{ PAGE_BEGAIN }}
|
// {{ PAGE_BEGAIN }}
|
||||||
// {{ PAGE_END }}}
|
// {{ PAGE_END }}
|
||||||
{
|
{
|
||||||
"path": "end"
|
"root": "app/components",
|
||||||
|
"pages": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"root": "app/pages/member",
|
||||||
|
"pages": [
|
||||||
|
{
|
||||||
|
"path": "apply_cash_out",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "%pages.member.apply_cash_out%"
|
||||||
|
},
|
||||||
|
"needLogin": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "commission",
|
||||||
|
"style": {
|
||||||
|
// #ifndef H5
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
// #endif
|
||||||
|
"navigationBarTitleText": "%pages.member.commission%"
|
||||||
|
},
|
||||||
|
"needLogin": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "balance",
|
||||||
|
"style": {
|
||||||
|
// #ifndef H5
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
// #endif
|
||||||
|
"navigationBarTitleText": "%pages.member.balance%"
|
||||||
|
},
|
||||||
|
"needLogin": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "level",
|
||||||
|
"style": {
|
||||||
|
// #ifndef H5
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
// #endif
|
||||||
|
"navigationBarTitleText": "%pages.member.level%"
|
||||||
|
},
|
||||||
|
"needLogin": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "detailed_account",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "%pages.member.detailed_account%"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "cash_out",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "%pages.member.cash_out%"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "cash_out_detail",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "%pages.member.cash_out_detail%"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "index",
|
||||||
|
"style": {
|
||||||
|
// #ifndef H5
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
// #endif
|
||||||
|
"navigationBarTitleText": "%pages.member.index%",
|
||||||
|
"usingComponents": {
|
||||||
|
"diy-group": "../../../../addon/components/diy/group/index"
|
||||||
|
},
|
||||||
|
"componentPlaceholder": {
|
||||||
|
"diy-group": "view"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "personal",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "%pages.member.personal%"
|
||||||
|
},
|
||||||
|
"needLogin": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "point",
|
||||||
|
"style": {
|
||||||
|
// #ifndef H5
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
// #endif
|
||||||
|
"navigationBarTitleText": "%pages.member.point%"
|
||||||
|
},
|
||||||
|
"needLogin": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "point_detail",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "%pages.member.point_detail%"
|
||||||
|
},
|
||||||
|
"needLogin": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "account",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "%pages.member.account%"
|
||||||
|
},
|
||||||
|
"needLogin": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "account_edit",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "%pages.member.account_edit%"
|
||||||
|
},
|
||||||
|
"needLogin": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "address",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "%pages.member.address%"
|
||||||
|
},
|
||||||
|
"needLogin": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "address_edit",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "%pages.member.address_edit%"
|
||||||
|
},
|
||||||
|
"needLogin": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "sign_in",
|
||||||
|
"style": {
|
||||||
|
// #ifndef H5
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
// #endif
|
||||||
|
"navigationBarTitleText": "%pages.member.sign_in%"
|
||||||
|
},
|
||||||
|
"needLogin": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "contact",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "%pages.member.contact%"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -350,7 +378,7 @@
|
|||||||
"pagePath": "app/pages/index/index"
|
"pagePath": "app/pages/index/index"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pagePath": "app/pages/member/index"
|
"pagePath": "app/pages/index/diy"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -358,12 +386,10 @@
|
|||||||
"easycom": {
|
"easycom": {
|
||||||
"custom": {
|
"custom": {
|
||||||
"diy-group": "@/addon/components/diy/group/index.vue",
|
"diy-group": "@/addon/components/diy/group/index.vue",
|
||||||
"fixed-group": "@/addon/components/fixed/group/index.vue",
|
|
||||||
"^u-(.*)": "uview-plus/components/u-$1/u-$1.vue",
|
"^u-(.*)": "uview-plus/components/u-$1/u-$1.vue",
|
||||||
"^up-(.*)": "uview-plus/components/u-$1/u-$1.vue",
|
"^up-(.*)": "uview-plus/components/u-$1/u-$1.vue",
|
||||||
"^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue",
|
"^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue",
|
||||||
"diy-(\W.*)": "@/app/components/diy/$1/index.vue",
|
"diy-(\W.*)": "@/app/components/diy/$1/index.vue"
|
||||||
"fixed-(\W.*)": "@/app/components/fixed/$1/index.vue"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -63,6 +63,8 @@ const useMemberStore = defineStore('member', {
|
|||||||
uni.removeStorageSync('openid');
|
uni.removeStorageSync('openid');
|
||||||
uni.removeStorageSync('unionid');
|
uni.removeStorageSync('unionid');
|
||||||
uni.removeStorageSync('isbindmobile');
|
uni.removeStorageSync('isbindmobile');
|
||||||
|
uni.removeStorageSync('nickname');
|
||||||
|
uni.removeStorageSync('avatar');
|
||||||
isRedirect && redirect({ url: '/app/pages/index/index', mode: 'switchTab' })
|
isRedirect && redirect({ url: '/app/pages/index/index', mode: 'switchTab' })
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
removeToken()
|
removeToken()
|
||||||
@ -70,6 +72,8 @@ const useMemberStore = defineStore('member', {
|
|||||||
uni.removeStorageSync('openid');
|
uni.removeStorageSync('openid');
|
||||||
uni.removeStorageSync('unionid');
|
uni.removeStorageSync('unionid');
|
||||||
uni.removeStorageSync('isbindmobile');
|
uni.removeStorageSync('isbindmobile');
|
||||||
|
uni.removeStorageSync('nickname');
|
||||||
|
uni.removeStorageSync('avatar');
|
||||||
isRedirect && redirect({ url: '/app/pages/index/index', mode: 'switchTab' })
|
isRedirect && redirect({ url: '/app/pages/index/index', mode: 'switchTab' })
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|||||||
@ -67,6 +67,9 @@ const useSystemStore = defineStore('system', {
|
|||||||
this.mapConfig.valid_time = data.map_config.valid_time;
|
this.mapConfig.valid_time = data.map_config.valid_time;
|
||||||
uni.setStorageSync('mapConfig', this.mapConfig);
|
uni.setStorageSync('mapConfig', this.mapConfig);
|
||||||
|
|
||||||
|
// 主题色
|
||||||
|
uni.setStorageSync('theme_color_list', data.theme_list);
|
||||||
|
|
||||||
// 站点信息
|
// 站点信息
|
||||||
this.site = data.site_info
|
this.site = data.site_info
|
||||||
this.siteApps = data.site_info.app
|
this.siteApps = data.site_info.app
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
--primary-color-dark: #398ade;
|
--primary-color-dark: #398ade;
|
||||||
--primary-color-disabled: #9acafc;
|
--primary-color-disabled: #9acafc;
|
||||||
--primary-color-light: #ecf5ff;
|
--primary-color-light: #ecf5ff;
|
||||||
--primary-color-light: #ecf5ff;
|
|
||||||
--page-bg-color: #f6f6f6;
|
--page-bg-color: #f6f6f6;
|
||||||
--text-color-light6: #666;
|
--text-color-light6: #666;
|
||||||
--text-color-light9: #999;
|
--text-color-light9: #999;
|
||||||
@ -67,7 +66,8 @@ button[type='primary'],uni-button[type='primary']{
|
|||||||
|
|
||||||
// 提交按钮背景颜色
|
// 提交按钮背景颜色
|
||||||
.primary-btn-bg{
|
.primary-btn-bg{
|
||||||
background: linear-gradient( 94deg, #FB7939 0%, #FE120E 99%), #EF000C;
|
// background: linear-gradient( 94deg, #FB7939 0%, #FE120E 99%), #EF000C;
|
||||||
|
background: linear-gradient( 94deg, var(--primary-help-color) 0%, var(--primary-color) 99%), var(--primary-color);
|
||||||
}
|
}
|
||||||
// 侧边栏宽度
|
// 侧边栏宽度
|
||||||
.sidebar-margin{
|
.sidebar-margin{
|
||||||
@ -171,7 +171,38 @@ button[type='primary'],uni-button[type='primary']{
|
|||||||
border-radius: 100rpx;
|
border-radius: 100rpx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 空页面
|
||||||
|
.empty-page-popup{
|
||||||
|
margin: var(--top-m) auto 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: var(--rounded-big);
|
||||||
|
height: 340rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
box-sizing: border-box;
|
||||||
|
.img{
|
||||||
|
width: 320rpx;
|
||||||
|
height: 240rpx;
|
||||||
|
}
|
||||||
|
.desc{
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: var(--text-color-light9);
|
||||||
|
}
|
||||||
|
.btn{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 260rpx;
|
||||||
|
height: 66rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
margin-top: 40rpx;
|
||||||
|
color: var(--primary-color);
|
||||||
|
border: 2rpx solid var(--primary-color);
|
||||||
|
border-radius: 100rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
// 搜索input
|
// 搜索input
|
||||||
.search-input{
|
.search-input{
|
||||||
@apply flex-1 flex items-center;
|
@apply flex-1 flex items-center;
|
||||||
@ -184,6 +215,7 @@ button[type='primary'],uni-button[type='primary']{
|
|||||||
@apply flex-1;
|
@apply flex-1;
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
padding-right: 32rpx;
|
padding-right: 32rpx;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
.clear{
|
.clear{
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
@ -394,6 +426,11 @@ button[type='primary'],uni-button[type='primary']{
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
.flex-between-center{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;;
|
||||||
|
}
|
||||||
|
|
||||||
/* 单行超出隐藏 */
|
/* 单行超出隐藏 */
|
||||||
.using-hidden {
|
.using-hidden {
|
||||||
@ -484,3 +521,34 @@ button[type='primary'],uni-button[type='primary']{
|
|||||||
}
|
}
|
||||||
/* #endif */
|
/* #endif */
|
||||||
/******************** u-switch end **********************/
|
/******************** u-switch end **********************/
|
||||||
|
|
||||||
|
/******************** 表单组件兼容性 start **********************/
|
||||||
|
/* #ifdef MP */
|
||||||
|
.form-item-frame .u-checkbox .u-checkbox__icon-wrap{
|
||||||
|
width: 30rpx !important;
|
||||||
|
height: 30rpx !important;
|
||||||
|
}
|
||||||
|
.form-item-frame .u-radio-group .u-radio__icon-wrap{
|
||||||
|
width: 30rpx !important;
|
||||||
|
height: 30rpx !important;
|
||||||
|
}
|
||||||
|
.form-item-frame .u-picker .u-toolbar__wrapper__cancel, .form-item-frame .u-picker .u-toolbar__wrapper__confirm{
|
||||||
|
font-size: 28rpx !important;
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
.form-item-frame .calendar-wrap .u-calendar ::v-deep .u-calendar-header__title, .form-item-frame .calendar-wrap .u-calendar ::v-deep .u-calendar-header__subtitle, .form-item-frame .calendar-wrap .u-calendar ::v-deep .u-calendar-month__title{
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.form-item-frame .calendar-wrap .u-calendar .u-calendar-header__title, .u-calendar-header__subtitle, .u-calendar-month__title{
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
/******************** 表单组件兼容性 end **********************/
|
||||||
|
|
||||||
|
|
||||||
|
.information-filling .u-form .u-form-item__body__left__content__label{
|
||||||
|
font-size: 28rpx !important;
|
||||||
|
}
|
||||||
|
.information-filling .u-line{
|
||||||
|
border-color: #dddddd !important;
|
||||||
|
}
|
||||||
174
uni-app/src/styles/diy_form.scss
Normal file
174
uni-app/src/styles/diy_form.scss
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
.form-item-frame{
|
||||||
|
@apply overflow-hidden relative;
|
||||||
|
.base-layout-one{
|
||||||
|
@apply relative flex flex-col;
|
||||||
|
.layout-one-label{
|
||||||
|
@apply flex items-center;
|
||||||
|
line-height: 1.3;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
.is-hidden{
|
||||||
|
@apply border-solid;
|
||||||
|
font-size: 20rpx;
|
||||||
|
line-height: 20rpx;
|
||||||
|
border-width: 2rpx;
|
||||||
|
border-color: #999;
|
||||||
|
padding: 4rpx;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
margin-left: 6rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
.required{
|
||||||
|
color: #ec0003;
|
||||||
|
padding-top: 4rpx;
|
||||||
|
margin-left: 4rpx;
|
||||||
|
}
|
||||||
|
.name{
|
||||||
|
@apply overflow-ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.layout-one-remark{
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
.layout-one-error-message{
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: red;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
}
|
||||||
|
.layout-one-content{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 80rpx;
|
||||||
|
padding: 0 16rpx;
|
||||||
|
border: 2rpx solid #F2F2F2;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.layout-one-input-placeholder{
|
||||||
|
color: var(--text-color-light9);
|
||||||
|
}
|
||||||
|
.layout-one-attribute-wrap{
|
||||||
|
@apply flex items-center;
|
||||||
|
margin-top: 16rpx;
|
||||||
|
.layout-one-attribute-item{
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
margin-right: 6rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.detail-one-content{
|
||||||
|
padding: 5rpx 10rpx;
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 34rpx;
|
||||||
|
flex-direction: column;
|
||||||
|
.detail-one-content-label{
|
||||||
|
color: #999;
|
||||||
|
font-size: 26rpx;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
.detail-one-content-value{
|
||||||
|
font-size: 28rpx;
|
||||||
|
margin-top: 5rpx;
|
||||||
|
line-height: 1.4;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.base-layout-two{
|
||||||
|
@apply relative;
|
||||||
|
.layout-two-is-hidden{
|
||||||
|
font-size: 20rpx;
|
||||||
|
border: 2rpx solid #999;
|
||||||
|
padding: 4rpx;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
margin-left: 6rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
.layout-two-wrap{
|
||||||
|
@apply flex items-center border-solid box-border;
|
||||||
|
border-width: 0;
|
||||||
|
border-bottom-width: 2rpx;
|
||||||
|
border-color: #F2F2F2;
|
||||||
|
padding: 0 16rpx;
|
||||||
|
.layout-two-label{
|
||||||
|
@apply flex items-center;
|
||||||
|
width: 27%;
|
||||||
|
padding-right: 20rpx;
|
||||||
|
.required{
|
||||||
|
color: #ec0003;
|
||||||
|
padding-top: 4rpx;
|
||||||
|
margin-right: 6rpx;
|
||||||
|
}
|
||||||
|
.name{
|
||||||
|
@apply overflow-ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.layout-two-content{
|
||||||
|
width: 73%;
|
||||||
|
min-height: 90rpx;
|
||||||
|
text-align: right;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
&.no-flex{
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.layout-two-input-placeholder{
|
||||||
|
color: var(--text-color-light9);
|
||||||
|
}
|
||||||
|
&.no-border{
|
||||||
|
padding: 0;
|
||||||
|
border-width: 0;
|
||||||
|
.layout-two-content{
|
||||||
|
min-height: 72rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.layout-two-remark{
|
||||||
|
margin-top: 16rpx;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
.layout-two-error-message{
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: red;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
}
|
||||||
|
.layout-two-attribute-wrap{
|
||||||
|
@apply flex items-center;
|
||||||
|
margin-top: 16rpx;
|
||||||
|
.layout-two-attribute-item{
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
margin-right: 6rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.detail-two-content{
|
||||||
|
padding: 0rpx 10rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
margin-bottom: 34rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
.detail-two-content-label{
|
||||||
|
|
||||||
|
}
|
||||||
|
.detail-two-content-value {
|
||||||
|
line-height: 1.4;
|
||||||
|
word-wrap: break-word;
|
||||||
|
word-break: break-word;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.form-item-mask{
|
||||||
|
@apply absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,8 +1,8 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: "nc-iconfont"; /* Project id 4567203 */
|
font-family: "nc-iconfont"; /* Project id 4567203 */
|
||||||
src: url('//at.alicdn.com/t/c/font_4567203_8cgr9qgefz9.woff2?t=1734663182190') format('woff2'),
|
src: url('//at.alicdn.com/t/c/font_4567203_r6wh4er3yxa.woff2?t=1736824513371') format('woff2'),
|
||||||
url('//at.alicdn.com/t/c/font_4567203_8cgr9qgefz9.woff?t=1734663182190') format('woff'),
|
url('//at.alicdn.com/t/c/font_4567203_r6wh4er3yxa.woff?t=1736824513371') format('woff'),
|
||||||
url('//at.alicdn.com/t/c/font_4567203_8cgr9qgefz9.ttf?t=1734663182190') format('truetype');
|
url('//at.alicdn.com/t/c/font_4567203_r6wh4er3yxa.ttf?t=1736824513371') format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
.nc-iconfont {
|
.nc-iconfont {
|
||||||
@ -13,6 +13,90 @@
|
|||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nc-icon-a-xiangyouV6mm:before {
|
||||||
|
content: "\e849";
|
||||||
|
}
|
||||||
|
|
||||||
|
.nc-icon-a-xiangyouV6xx1:before {
|
||||||
|
content: "\e797";
|
||||||
|
}
|
||||||
|
|
||||||
|
.nc-icon-xiaoxiV6mm1:before {
|
||||||
|
content: "\e83c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.nc-icon-guanbiV6xx2:before {
|
||||||
|
content: "\e857";
|
||||||
|
}
|
||||||
|
|
||||||
|
.nc-icon-guanbiV6xx-1:before {
|
||||||
|
content: "\e856";
|
||||||
|
}
|
||||||
|
|
||||||
|
.nc-icon-fenxiangV6mm2:before {
|
||||||
|
content: "\e854";
|
||||||
|
}
|
||||||
|
|
||||||
|
.nc-icon-fenxiangV6xx4:before {
|
||||||
|
content: "\e853";
|
||||||
|
}
|
||||||
|
|
||||||
|
.nc-icon-a-sousuoV6xx-34:before {
|
||||||
|
content: "\e855";
|
||||||
|
}
|
||||||
|
|
||||||
|
.nc-icon-sousuoV6xx11:before {
|
||||||
|
content: "\e851";
|
||||||
|
}
|
||||||
|
|
||||||
|
.nc-icon-a-shipinV6xx-28-1:before {
|
||||||
|
content: "\e850";
|
||||||
|
}
|
||||||
|
|
||||||
|
.nc-icon-a-gengduoV6xx-28:before {
|
||||||
|
content: "\e84f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.nc-icon-fenxiangV6mm1:before {
|
||||||
|
content: "\e847";
|
||||||
|
}
|
||||||
|
|
||||||
|
.nc-icon-tupiandaohangpc:before {
|
||||||
|
content: "\e7dc";
|
||||||
|
}
|
||||||
|
|
||||||
|
.nc-icon-shequfenleiV6xx-1:before {
|
||||||
|
content: "\e84a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.nc-icon-gouwuV6xx1:before {
|
||||||
|
content: "\e844";
|
||||||
|
}
|
||||||
|
|
||||||
|
.nc-icon-a-xiangyouV6xx2:before {
|
||||||
|
content: "\e848";
|
||||||
|
}
|
||||||
|
|
||||||
|
.nc-icon-dianxinxiV6xx1:before {
|
||||||
|
content: "\e842";
|
||||||
|
}
|
||||||
|
|
||||||
|
.nc-icon-a-dianzanV6xx-36:before {
|
||||||
|
content: "\e7df";
|
||||||
|
}
|
||||||
|
|
||||||
|
.nc-icon-fenxiangV6xx3:before {
|
||||||
|
content: "\e846";
|
||||||
|
}
|
||||||
|
|
||||||
|
.nc-icon-xiaoxiV6xx1:before {
|
||||||
|
content: "\e83d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.nc-icon-liebiaoV6xx1:before {
|
||||||
|
content: "\e841";
|
||||||
|
}
|
||||||
|
|
||||||
.nc-icon-daifujineV6xx:before {
|
.nc-icon-daifujineV6xx:before {
|
||||||
content: "\e83b";
|
content: "\e83b";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -401,18 +401,52 @@ export function timeStampTurnTime(timeStamp: any, type = "") {
|
|||||||
* 日期格式转时间戳
|
* 日期格式转时间戳
|
||||||
* @param {Object} date
|
* @param {Object} date
|
||||||
*/
|
*/
|
||||||
export function timeTurnTimeStamp(date: string) {
|
export function timeTurnTimeStamp(dateStr: string) {
|
||||||
var f = date.split(' ', 2);
|
let timestamp;
|
||||||
var d = (f[0] ? f[0] : '').split('-', 3);
|
let date;
|
||||||
var t = (f[1] ? f[1] : '').split(':', 3);
|
|
||||||
return (new Date(
|
// 尝试解析 'YYYY年M月D日'
|
||||||
parseInt(d[0], 10) || null,
|
try {
|
||||||
(parseInt(d[1], 10) || 1) - 1,
|
let dateStr1 = dateStr.replace('年', '-').replace('月', '-').replace('日', '');
|
||||||
parseInt(d[2], 10) || null,
|
date = new Date(dateStr1);
|
||||||
parseInt(t[0], 10) || null,
|
timestamp = date.getTime();
|
||||||
parseInt(t[1], 10) || null,
|
} catch (e) {
|
||||||
parseInt(t[2], 10) || null
|
// 尝试解析 'YYYY-MM-DD'
|
||||||
)).getTime() / 1000;
|
try {
|
||||||
|
date = new Date(dateStr);
|
||||||
|
timestamp = date.getTime();
|
||||||
|
} catch (e) {
|
||||||
|
// 尝试解析 'YYYY/MM/DD'
|
||||||
|
try {
|
||||||
|
date = new Date(dateStr.replace(/\//g, "-"));
|
||||||
|
timestamp = date.getTime();
|
||||||
|
} catch (e) {
|
||||||
|
// 尝试解析 'YYYY年M月D日 HH时mm分'
|
||||||
|
try {
|
||||||
|
let dateStr1 = dateStr.replace('年', '-').replace('月', '-').replace('日', ' ').replace('时', ':').replace('分', '');
|
||||||
|
date = new Date(dateStr1);
|
||||||
|
timestamp = date.getTime();
|
||||||
|
} catch (e) {
|
||||||
|
// 尝试解析 'YYYY-MM-DD HH:mm'
|
||||||
|
try {
|
||||||
|
date = new Date(dateStr);
|
||||||
|
timestamp = date.getTime();
|
||||||
|
} catch (e) {
|
||||||
|
// 尝试解析 'YYYY/MM/DD HH:mm'
|
||||||
|
try {
|
||||||
|
date = new Date(dateStr.replace(/\//g, "-"));
|
||||||
|
timestamp = date.getTime();
|
||||||
|
} catch (e) {
|
||||||
|
// 如果所有格式都失败,返回null
|
||||||
|
console.error("无法解析日期字符串:", dateStr);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (timestamp / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -563,3 +597,81 @@ export function goback(data: any) {
|
|||||||
}
|
}
|
||||||
}, 600);
|
}, 600);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 获取微信OpenId、微信公众号OpenId
|
||||||
|
export function getWinxinOpenId() {
|
||||||
|
const memberStore = useMemberStore();
|
||||||
|
const memberInfo = memberStore.info;
|
||||||
|
|
||||||
|
let obj = {
|
||||||
|
weapp: '',
|
||||||
|
wechat: ''
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memberInfo) {
|
||||||
|
obj.weapp = memberInfo.weapp_openid;
|
||||||
|
obj.wechat = memberInfo.wx_openid;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取有效期
|
||||||
|
export function getValidTime(minutes: any = 1) {
|
||||||
|
var date = new Date();
|
||||||
|
date.setSeconds(60 * minutes);
|
||||||
|
let validTime: any = parseInt(date.getTime() / 1000); // 定位信息 5分钟内有效,过期后将重新获取定位信息
|
||||||
|
return validTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测当前访问的是系统(app)还是插件
|
||||||
|
* 设置插件的底部导航
|
||||||
|
* 设置插件应用的主色调
|
||||||
|
* @param path
|
||||||
|
*/
|
||||||
|
export function setThemeColor (path: string) {
|
||||||
|
let pathArr = path.split('/')
|
||||||
|
let index = !pathArr[0] ? 1 : 0;
|
||||||
|
let route = pathArr[index] == 'addon' ? pathArr[(index+1)] : 'app';
|
||||||
|
|
||||||
|
// 设置底部导航
|
||||||
|
const configStore = useConfigStore()
|
||||||
|
if (configStore.addon != route) {
|
||||||
|
configStore.addon = route;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置插件应用的主色调,排除系统
|
||||||
|
const theme_color_list = uni.getStorageSync('theme_color_list');
|
||||||
|
const current_theme_color = uni.getStorageSync('current_theme_color');
|
||||||
|
let theme = '';
|
||||||
|
if (route != 'app') {
|
||||||
|
try {
|
||||||
|
theme = theme_color_list[route];
|
||||||
|
if(theme && theme.value){
|
||||||
|
configStore.themeColor = theme.value
|
||||||
|
uni.setStorageSync('current_theme_color', JSON.stringify(theme.value));
|
||||||
|
}else if( !theme && current_theme_color){
|
||||||
|
configStore.themeColor = ''
|
||||||
|
}else{
|
||||||
|
theme = theme_color_list.app || Object.values(theme_color_list)[0];
|
||||||
|
configStore.themeColor = theme.value
|
||||||
|
uni.setStorageSync('current_theme_color', JSON.stringify(theme.value));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// 设置插件应用的主色调发生错误,若不存在则使用最后有效的主色调
|
||||||
|
if(!current_theme_color && theme_color_list){
|
||||||
|
theme = theme_color_list.app || Object.values(theme_color_list)[0];
|
||||||
|
configStore.themeColor = theme.value
|
||||||
|
uni.setStorageSync('current_theme_color', JSON.stringify(theme.value));
|
||||||
|
}else{
|
||||||
|
configStore.themeColor = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}else if(!current_theme_color && theme_color_list){
|
||||||
|
theme = theme_color_list.app || Object.values(theme_color_list)[0];
|
||||||
|
configStore.themeColor = theme.value
|
||||||
|
uni.setStorageSync('current_theme_color', JSON.stringify(theme.value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { language } from '@/locale'
|
import { language } from '@/locale'
|
||||||
import { checkNeedLogin } from '@/utils/auth'
|
import { checkNeedLogin } from '@/utils/auth'
|
||||||
import { redirect, getToken, getSiteId,currRoute } from '@/utils/common'
|
import { redirect, getToken, getSiteId,currRoute, setThemeColor } from '@/utils/common'
|
||||||
import { memberLog } from '@/app/api/auth'
|
import { memberLog } from '@/app/api/auth'
|
||||||
import useConfigStore from "@/stores/config";
|
import useConfigStore from "@/stores/config";
|
||||||
import { useShare } from '@/hooks/useShare'
|
import { useShare } from '@/hooks/useShare'
|
||||||
@ -12,7 +12,7 @@ export const redirectInterceptor = (route: { path: string, query: object }) => {
|
|||||||
route.path = `/${ route.path }`
|
route.path = `/${ route.path }`
|
||||||
|
|
||||||
// 检测当前访问的是系统(app)还是插件
|
// 检测当前访问的是系统(app)还是插件
|
||||||
setAddonName(route.path)
|
setThemeColor(route.path)
|
||||||
|
|
||||||
// 开发模式下,如果未配置站点ID,则跳转到开发环境配置页面
|
// 开发模式下,如果未配置站点ID,则跳转到开发环境配置页面
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
@ -67,7 +67,7 @@ export const launchInterceptor = () => {
|
|||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// 检测当前访问的是系统(app)还是插件
|
// 检测当前访问的是系统(app)还是插件
|
||||||
setAddonName(launch.path);
|
setThemeColor(launch.path);
|
||||||
|
|
||||||
// 加载语言包
|
// 加载语言包
|
||||||
language.loadAllLocaleMessages('app', uni.getLocale())
|
language.loadAllLocaleMessages('app', uni.getLocale())
|
||||||
@ -90,35 +90,6 @@ export const launchInterceptor = () => {
|
|||||||
if (getToken()) memberLog({ route: launch.path, params: JSON.stringify(launch.query || {}), pre_route: '' })
|
if (getToken()) memberLog({ route: launch.path, params: JSON.stringify(launch.query || {}), pre_route: '' })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 检测当前访问的是系统(app)还是插件
|
|
||||||
* 设置插件的底部导航
|
|
||||||
* 设置插件应用的主色调
|
|
||||||
* @param path
|
|
||||||
*/
|
|
||||||
const setAddonName = async(path: string) => {
|
|
||||||
let pathArr = path.split('/')
|
|
||||||
let route = pathArr[1] == 'addon' ? pathArr[2] : 'app';
|
|
||||||
|
|
||||||
// 设置底部导航
|
|
||||||
const configStore = useConfigStore()
|
|
||||||
if (configStore.addon != route) {
|
|
||||||
configStore.addon = route;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置插件应用的主色调,排除系统
|
|
||||||
if (route != 'app') {
|
|
||||||
try {
|
|
||||||
const theme = await import(`../addon/${ route }/utils/theme.json`)
|
|
||||||
configStore.themeColor = theme.default
|
|
||||||
uni.setStorageSync('current_theme_color', JSON.stringify(theme.default));
|
|
||||||
} catch (e) {
|
|
||||||
// 设置插件应用的主色调发生错误,若不存在则使用最后有效的主色调
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加载分享
|
// 加载分享
|
||||||
const loadShare = () => {
|
const loadShare = () => {
|
||||||
@ -134,6 +105,7 @@ const loadShare = () => {
|
|||||||
'addon/shop_giftcard/pages/detail',
|
'addon/shop_giftcard/pages/detail',
|
||||||
'addon/shop_giftcard/pages/give',
|
'addon/shop_giftcard/pages/give',
|
||||||
'app/pages/index/diy',
|
'app/pages/index/diy',
|
||||||
|
'app/pages/index/diy_form',
|
||||||
'app/pages/friendspay/share',
|
'app/pages/friendspay/share',
|
||||||
'app/pages/friendspay/money'
|
'app/pages/friendspay/money'
|
||||||
]
|
]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user