Files
lucky_shop/pages_tool/form/formdata.vue
ZF sun aafb75bad3 style: 调整多个页面的回到顶部按钮位置适配多端
为H5和小程序平台分别配置mescroll-totop的right和bottom样式,修复不同终端下按钮位置适配问题
2026-07-16 17:07:30 +08:00

216 lines
5.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view :style="themeColor">
<block v-if="detail">
<view class="page">
<view class="system-form-wrap">
<!-- 复用 diy-form:banner / tip / 表单字段 / 提交按钮 全部由其内部渲染,样式(bannerPaddingX/tipColor/submitBgColor 等)由 form_config 控制。
@submit 接管提交逻辑(带 uniacid + showModal) -->
<diy-form
ref="form"
:value="diyValue"
dataMode="raw"
@submit="create"
/>
</view>
</view>
</block>
<block v-else>
<ns-empty :text="complete ? $lang('form.formdata.submitSuccess') : $lang('form.formdata.noFormInfo')" :isIndex="false"></ns-empty>
</block>
<loading-cover ref="loadingCover"></loading-cover>
<ns-login ref="login"></ns-login>
<to-top v-if="showTop" @toTop="scrollToTopNative()"></to-top>
</view>
</template>
<script>
import diyForm from '@/components-diy/diy-form.vue';
import scroll from '@/common/js/scroll-view.js';
export default {
components: {
diyForm
},
mixins: [scroll],
data() {
return {
id: 0,
detail: null,
isRepeat: false,
complete: false,
scroll: true,
uniacid: 0,
isFromMpWebView: false, // 是否是从微信小程序的WebView跳转过来的
hideNavbar: false, // 查询参数中支持隐藏Navbar
// #ifdef H5
formTitle: '', // 查询参数传入的Title
enableSetTitle: false, // 查询参数传入的是否可以强制设置Title
// #endif
}
},
computed: {
// 构造 diy-form raw 模式期望的 value 形态:
// - jsonData:透传给 ns-newform(已是 ns-newform 期望的 [{ controller, value, val }])
// - formConfig:后端返回 camelCase(如 formPaddingX / formBgColor / labelFontSize),
// diy-form 内部 mergedFormConfig 同时兼容 snake_case 后再交给 ns-newform
// - show_banner / form_banner:交给 diy-form 渲染 banner,样式走 form_config.bannerPaddingX;form_banner 给保底图
// - show_tip / form_tip:交给 diy-form 渲染 tip,样式走 form_config;form_tip 给保底文案
// 注:本 computed 只在 <block v-if="detail"> 内被消费,无需 null 守卫
diyValue() {
return {
jsonData: this.detail.json_data,
formConfig: this.detail.form_config,
show_banner: this.detail.show_banner,
form_banner: this.detail.form_banner || 'public/uniapp/form/banner.png',
show_tip: this.detail.show_tip,
form_tip: this.detail.form_tip || this.$lang('form.formdata.formTipPlaceholder')
}
}
},
onLoad(options) {
if (!options.uniacid) {
uni.showModal({
title: this.$lang('form.formdata.tip'),
content: this.$lang('form.formdata.paramError'),
showCancel: false,
success: () => { }
})
return false
}
uni.setStorageSync('skipPrivacyCheck', true);
// #ifdef H5
this.formTitle = options?.title ?? '';
this.enableSetTitle = options?.enable_set_title == 1;
// #endif
this.uniacid = options.uniacid
this.id = options.id || 0
this.isFromMpWebView = options.from === 'mp-webview';
this.hideNavbar = Boolean(options?.hide_navbar);
if (options.scene) {
const scene = decodeURIComponent(options.scene)
const params = scene.split('&')
params.length && params.forEach(item => {
if (item.indexOf('id') != -1) {
this.id = item.split('-')[1]
}
})
}
// #ifdef H5
if (this.isFromMpWebView || this.hideNavbar) {
this.$nextTick(() => {
const navbar = document.querySelector('uni-page-head')
if (navbar) navbar.style.display = 'none'
})
}
// #endif
this.getData()
},
watch: {
storeToken(newVal, oldVal) {
newVal && this.getData()
}
},
onShow() {
this.updateNavbarTitle();
},
methods: {
getData() {
this.$api.sendRequest({
url: '/form/api/form/info',
data: {
form_id: this.id,
uniacid: this.uniacid
},
success: res => {
if (res.code == 0 && res.data) {
this.detail = res.data
this.updateNavbarTitle();
}
this.$refs.loadingCover && this.$refs.loadingCover.hide()
},
fail: () => {
this.$refs.loadingCover && this.$refs.loadingCover.hide()
}
})
},
updateNavbarTitle() {
if (!this.detail?.form_name) return;
let formName = this.detail.form_name;
// #ifdef H5
if (this.enableSetTitle && this.formTitle) {
formName = this.formTitle;
}
// #endif
uni.setNavigationBarTitle({ title: formName });
},
// 由 diy-form 内置提交按钮触发:diy-form 已先做 verify(),仅在通过时才 emit('submit', formData)
create(formData) {
if (this.isRepeat) return
this.isRepeat = true
this.$api.sendRequest({
url: '/form/api/form/create',
data: {
form_id: this.id,
form_data: typeof formData === 'string' ? formData : JSON.stringify(formData),
uniacid: this.uniacid
},
success: res => {
if (res.code == 0) {
uni.showModal({
title: this.$lang('form.formdata.tip'),
content: this.$lang('form.formdata.submitSuccess'),
showCancel: false,
success: () => { }
})
} else {
this.isRepeat = false
this.$util.showToast({
title: res.message
})
}
}
})
}
}
}
</script>
<style lang="scss" scoped>
page {
background: #fff;
}
.system-form-wrap {
overflow: hidden;
margin: 0 0 60rpx 0;
}
// 穿透 diy-form 包装层:消除其自带的 10rpx 圆角与白色背景,
// 让 form 内容区域保持与原始 ns-newform 接入时一致的视觉
.system-form-wrap ::v-deep .diy-from {
background: transparent;
border-radius: 0;
}
::v-deep .mescroll-totop {
/* #ifdef H5 */
right: 27rpx !important;
bottom: 120rpx !important;
/* #endif */
/* #ifdef MP */
right: 27rpx !important;
bottom: 180rpx !important;
/* #endif */
}
</style>