This commit is contained in:
wenfp
2026-08-21 14:12:00 +08:00
parent 68dc57ffe5
commit 13bb939099
13 changed files with 510 additions and 415 deletions
+8 -9
View File
@@ -1,19 +1,18 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="" manifest="IGNORE.manifest"> <html lang="" manifest="IGNORE.manifest">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8" />
<meta http-equiv="Pragma" content="no-cache"> <meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Cache" content="no-cache"> <meta http-equiv="Cache" content="no-cache" />
<meta http-equiv="Cache-control" content="no-cache,must-revalidate"> <meta http-equiv="Cache-control" content="no-cache,must-revalidate" />
<meta http-equiv="cache-control" content="max-age=0" /> <meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="cache-control" content="no-cache" /> <meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="expires" content="0" /> <meta http-equiv="expires" content="0" />
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" /> <meta name="referrer" content="never" />
<meta name="referrer" content="never"> <meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no" />
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">
<script src="https://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script> <script src="https://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> <link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<title></title> <title></title>
</head> </head>
<body> <body>
+1 -1
View File
@@ -1,4 +1,4 @@
@import 'variable.scss'; @use "./variable.scss" as *;
.divider { .divider {
height: .24rem; height: .24rem;
+96 -58
View File
@@ -1,88 +1,126 @@
let wechatInstance; let wechatInstance;
import util from "@/util"; let wechatReadyPromise = null;
// import util from "@/util";
function getShareConfig(shareConfig = {}) {
// const link = shareConfig.link || location.href;
return {
title: shareConfig.title || document.title || "自在福田",
desc: shareConfig.desc || "",
link: shareConfig.link,
imgUrl: shareConfig.imgUrl || "",
callback: shareConfig.callback,
};
}
function emitShareCallback(shareConfig, key, res) {
shareConfig.callback &&
shareConfig.callback({
key,
...res,
});
}
function signToWechat(config, shareConfig) { function signToWechat(config, shareConfig) {
if (!wx) { if (!wx) {
console.warn("请安装微信网页JS-SDK, url: https://res2.wx.qq.com/open/js/jweixin-1.6.0.js"); console.warn("请安装微信网页JS-SDK, url: https://res2.wx.qq.com/open/js/jweixin-1.6.0.js");
return;
} }
const defaultConfig = { const defaultConfig = {
...config, ...config,
debug: false, debug: false,
jsApiList: ["onMenuShareTimeline", "onMenuShareAppMessage", "scanQRCode", "getLocation", "openLocation", "updateAppMessageShareData", "updateTimelineShareData"], jsApiList: ["onMenuShareTimeline", "onMenuShareAppMessage", "scanQRCode", "getLocation", "openLocation", "updateAppMessageShareData", "updateTimelineShareData"],
}; };
wx.config(defaultConfig); wechatReadyPromise = new Promise((resolve, reject) => {
wx.ready(function () { wx.ready(function () {
console.log("wechat sdk config success");
wechatInstance = wx; wechatInstance = wx;
wx.onMenuShareAppMessage({ const safeShareConfig = getShareConfig(shareConfig);
title: shareConfig.title, if (typeof wx.updateAppMessageShareData === "function") {
desc: shareConfig.desc, wx.updateAppMessageShareData({
link: util.addExternalParamsToQuery(shareConfig.link, "no_login", 1), title: safeShareConfig.title,
imgUrl: shareConfig.imgUrl, desc: safeShareConfig.desc,
link: safeShareConfig.link,
imgUrl: safeShareConfig.imgUrl,
complete: (res) => { complete: (res) => {
shareConfig.callback && emitShareCallback(safeShareConfig, "updateAppMessageShareData", res);
shareConfig.callback({
key: "updateAppMessageShareData",
...res,
});
}, },
}); });
// // 分享朋友圈
wx.onMenuShareTimeline({
title: shareConfig.title,
link: util.addExternalParamsToQuery(shareConfig.link, "no_login", 1),
imgUrl: shareConfig.imgUrl,
complete: (res) => {
shareConfig.callback &&
shareConfig.callback({
key: "updateTimelineShareData",
...res,
});
},
});
// wx.updateAppMessageShareData({
// title: shareConfig.title,
// desc: shareConfig.desc,
// link: shareConfig.link,
// imgUrl: shareConfig.imgUrl,
// complete: res => {
// shareConfig.callback && shareConfig.callback({
// key: 'updateAppMessageShareData',
// ...res
// });
// }
// });
// // 分享朋友圈
// wx.updateTimelineShareData({
// title: shareConfig.title,
// link: shareConfig.link,
// imgUrl: shareConfig.imgUrl,
// complete: res => {
// shareConfig.callback && shareConfig.callback({
// key: 'updateTimelineShareData',
// ...res
// });
// }
// });
});
} }
function getLocation() { if (typeof wx.updateTimelineShareData === "function") {
wx.updateTimelineShareData({
title: safeShareConfig.title,
link: safeShareConfig.link,
imgUrl: safeShareConfig.imgUrl,
complete: (res) => {
emitShareCallback(safeShareConfig, "updateTimelineShareData", res);
},
});
}
if (typeof wx.onMenuShareAppMessage === "function") {
wx.onMenuShareAppMessage({
title: safeShareConfig.title,
desc: safeShareConfig.desc,
link: safeShareConfig.link,
imgUrl: safeShareConfig.imgUrl,
complete: (res) => {
emitShareCallback(safeShareConfig, "onMenuShareAppMessage", res);
},
});
}
if (typeof wx.onMenuShareTimeline === "function") {
wx.onMenuShareTimeline({
title: safeShareConfig.title,
link: safeShareConfig.link,
imgUrl: safeShareConfig.imgUrl,
complete: (res) => {
emitShareCallback(safeShareConfig, "onMenuShareTimeline", res);
},
});
}
resolve(wx);
});
if (typeof wx.error === "function") {
wx.error((error) => {
reject(error);
});
}
});
wx.config(defaultConfig);
}
async function getWechatInstance() {
if (wechatInstance) {
return wechatInstance;
}
if (wechatReadyPromise) {
return wechatReadyPromise;
}
return Promise.reject(new Error("微信 JS-SDK 尚未初始化"));
}
async function getLocation() {
const instance = await getWechatInstance();
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
wechatInstance.getLocation({ instance.getLocation({
type: "wgs84", type: "wgs84",
success: (res) => { success: (res) => {
if (res.errMsg === "getLocation:ok") { if (res.errMsg === "getLocation:ok") {
resolve(res); resolve(res);
} else { } else {
reject(); reject(new Error(res.errMsg || "获取定位失败"));
} }
}, },
error: () => { fail: (error) => {
reject(); reject(error || new Error("获取定位失败"));
},
cancel: () => {
reject(new Error("用户取消定位"));
}, },
}); });
}); });
+2
View File
@@ -40,6 +40,8 @@ export default {
height: 2.93rem; height: 2.93rem;
margin-right: 0.4rem; margin-right: 0.4rem;
border-radius: 0.11rem; border-radius: 0.11rem;
object-fit: contain;
background: #f1f1f1;
} }
.info { .info {
flex: 1; flex: 1;
+2 -1
View File
@@ -51,12 +51,13 @@ export default {
align-items: flex-end; align-items: flex-end;
margin-bottom: 0.2rem; margin-bottom: 0.2rem;
font-size: 0.4rem; font-size: 0.4rem;
line-height: 1.3;
} }
p.goods_name { p.goods_name {
font-size: 0.34rem; font-size: 0.34rem;
max-width: 15em; max-width: 15em;
line-height: 1.2; line-height: 1.2;
overflow-x: hidden; overflow: hidden;
color: #666; color: #666;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
+19 -11
View File
@@ -1,12 +1,12 @@
<template> <template>
<div class="goods-detail" v-if="data" :style="{ paddingBottom: paddingBottom + 'px' }"> <div class="goods-detail" v-if="data" :style="{ paddingBottom: paddingBottom + 'px' }">
<swiper class="swiper-container" :options="swiperOption"> <van-swipe class="swiper-container" :autoplay="4000" indicator-color="white">
<swiper-slide> <van-swipe-item v-for="(banner, index) in pictures" :key="index">
<div style="height: 100vw" class="picture"> <div class="picture-wrap">
<img :src="data.cover_url" alt="" /> <img :src="banner" alt="" />
</div> </div>
</swiper-slide> </van-swipe-item>
</swiper> </van-swipe>
<div class="monk-profile"> <div class="monk-profile">
<h1 class="position">{{ data.name }}</h1> <h1 class="position">{{ data.name }}</h1>
<div class="bar"> <div class="bar">
@@ -83,7 +83,6 @@
<script> <script>
import "swiper/css/swiper.css"; import "swiper/css/swiper.css";
import { swiper, swiperSlide } from "vue-awesome-swiper";
import { getGoodsDetail, getOrderCompare, hasLogin } from "@/api"; import { getGoodsDetail, getOrderCompare, hasLogin } from "@/api";
import SelectSpec from "./components/select-spec.vue"; import SelectSpec from "./components/select-spec.vue";
import FillInformation from "./components/fill-information.vue"; import FillInformation from "./components/fill-information.vue";
@@ -92,8 +91,6 @@ import CustomerService from "@/components/customer-service/index.vue";
export default { export default {
components: { components: {
swiper,
swiperSlide,
SelectSpec, SelectSpec,
CustomerService, CustomerService,
FillInformation, FillInformation,
@@ -117,9 +114,9 @@ export default {
dreamInfo: null, dreamInfo: null,
anyPrice: 0, // 随喜金额 anyPrice: 0, // 随喜金额
swiperOption: { swiperOption: {
autoplay: 8000, autoplay: 5000,
initialSlide: 1, initialSlide: 1,
loop: false, loop: true,
pagination: ".swiper-pagination", pagination: ".swiper-pagination",
onSlideChangeEnd: () => {}, onSlideChangeEnd: () => {},
}, },
@@ -146,6 +143,9 @@ export default {
} }
return Number(spec.price); return Number(spec.price);
}, },
pictures() {
return [this.data.cover_url, ...this.data.pictures];
},
priceTotal() { priceTotal() {
if (this.is_auto) { if (this.is_auto) {
return (parseInt(this.priceUnit * 100, 10) * this.quantity * 30) / 100; return (parseInt(this.priceUnit * 100, 10) * this.quantity * 30) / 100;
@@ -397,10 +397,18 @@ $lightWidth: 1.3rem;
} }
.swiper-container { .swiper-container {
background: #f5f5f5; background: #f5f5f5;
height: 10rem;
.picture-wrap {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.picture, .picture,
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
object-fit: cover;
} }
} }
.monk-profile { .monk-profile {
+23 -19
View File
@@ -166,6 +166,14 @@ export default {
this.data = res; this.data = res;
this.$store.commit("setTempleMeritId", res.temple_merit_id); this.$store.commit("setTempleMeritId", res.temple_merit_id);
this.data.icon_data = this.sliceNav(res.icon_data); this.data.icon_data = this.sliceNav(res.icon_data);
this.wechatReady({
...res.shareConfig,
link: location.href.replace("#/home", ""),
title: "菩提家园",
desc: "给心一个家",
imgUrl: "https://temple-h5-new.oss-cn-hangzhou.aliyuncs.com/uploads/dev/2025/04/16/phpGweHzl.jpg",
});
setTimeout(() => { setTimeout(() => {
document.title = "自在福田"; document.title = "自在福田";
}, 10); }, 10);
@@ -265,7 +273,7 @@ export default {
.panel { .panel {
padding-bottom: 0; padding-bottom: 0;
} }
}
.merit-scroll-container { .merit-scroll-container {
margin: 0 0.4rem; margin: 0 0.4rem;
height: 3.39rem; height: 3.39rem;
@@ -278,34 +286,30 @@ export default {
padding-bottom: 0.4rem; padding-bottom: 0.4rem;
} }
.merit { .merit {
width: 3.39rem; display: flex;
height: 3.39rem;
display: inline-block;
position: relative; position: relative;
border-radius: 0.16rem;
vertical-align: top; vertical-align: top;
overflow: hidden; gap: 0.2rem;
border-bottom: 1px solid #f1f1f1;
padding-bottom: 0.4rem;
& ~ .merit { & ~ .merit {
margin-left: 0.4rem; margin-top: 0.4rem;
} }
img { img {
width: 100%; width: 2rem;
height: 100%; height: 2rem;
object-fit: cover;
border-radius: 0.1rem;
} }
.title { .title {
position: absolute; color: #333;
left: 0; flex: 1;
right: 0;
bottom: 0;
height: 0.91rem;
background: rgba(0, 0, 0, 0.7);
color: white;
line-height: 0.91rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
font-size: 0.37rem; font-size: 0.37rem;
padding: 0 0.11rem; padding: 0 0.11rem;
} }
} }
}
</style> </style>
+17 -29
View File
@@ -14,7 +14,7 @@
</div> </div>
<div class="container"> <div class="container">
<div class="swiper" v-if="data.banner_data.length > 0"> <div class="swiper" v-if="data.banner_data.length > 0">
<van-swipe class="my-swipe" :autoplay="8000" indicator-color="white"> <van-swipe class="my-swipe" :autoplay="5000" indicator-color="white">
<van-swipe-item v-for="(banner, index) in data.banner_data" :key="index"> <van-swipe-item v-for="(banner, index) in data.banner_data" :key="index">
<img :src="banner.cover" alt="" @click="$router.push({ path: banner.url })" /> <img :src="banner.cover" alt="" @click="$router.push({ path: banner.url })" />
</van-swipe-item> </van-swipe-item>
@@ -52,7 +52,7 @@
<div class="divider"></div> <div class="divider"></div>
<div class="panel"> <div class="panel">
<div class="panel-head"> <div class="panel-head">
<span class="title">功德无量</span> <span class="title">近期活动</span>
<arrow-more @click="$router.push({ name: 'merit-list', query: { temple_id: query.temple_id } })"></arrow-more> <arrow-more @click="$router.push({ name: 'merit-list', query: { temple_id: query.temple_id } })"></arrow-more>
</div> </div>
<div class="panel-body"> <div class="panel-body">
@@ -67,7 +67,7 @@
</div> </div>
</div> </div>
<div class="divider"></div> <div class="divider"></div>
<div class="panel temple-home-activity"> <div class="panel temple-home-activity" v-if="data.dynamic_data.length">
<div class="panel-head"> <div class="panel-head">
<span class="title">活动进展</span> <span class="title">活动进展</span>
<arrow-more @click="onMoreProcess"></arrow-more> <arrow-more @click="onMoreProcess"></arrow-more>
@@ -79,11 +79,10 @@
<i class="iconfont icon-arrow-right"></i> <i class="iconfont icon-arrow-right"></i>
</div> </div>
</div> </div>
</div>
<div class="divider"></div> <div class="divider"></div>
<thanks-giving :temple-id="query.temple_id || '1'"></thanks-giving> <thanks-giving :temple-id="query.temple_id || '1'"></thanks-giving>
<button class="temple-station-in" @click="onTempleStation">寺院入驻</button> <button class="temple-station-in" @click="onTempleStation">寺院入驻</button>
</div>
<div class="panel-menu-btn" @click="showUserMenu = true"> <div class="panel-menu-btn" @click="showUserMenu = true">
<span class="iconfont icon-liebiao"></span> <span class="iconfont icon-liebiao"></span>
@@ -280,11 +279,8 @@ export default {
margin-right: auto; margin-right: auto;
} }
.merit-scroll-container { .merit-scroll-container {
height: 3.39rem;
margin: 0; margin: 0;
overflow-x: auto;
.merit-scroll-wrapper { .merit-scroll-wrapper {
white-space: nowrap;
} }
} }
.temple-station-in { .temple-station-in {
@@ -569,7 +565,7 @@ export default {
.panel { .panel {
.panel-head { .panel-head {
padding: 0.53rem 0.4rem; padding: 0.13rem 0.4rem;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
@@ -582,7 +578,7 @@ export default {
.panel-body { .panel-body {
padding: 0 0.4rem; padding: 0 0.4rem;
overflow-x: scroll; overflow-x: hidden;
.merit-group { .merit-group {
display: flex; display: flex;
@@ -605,34 +601,26 @@ export default {
} }
.merit { .merit {
width: 3.39rem; display: flex;
height: 3.39rem;
display: inline-block;
position: relative; position: relative;
border-radius: 0.16rem;
vertical-align: top; vertical-align: top;
overflow: hidden; gap: 0.2rem;
border-bottom: 1px solid #f1f1f1;
padding-bottom: 0.4rem;
& ~ .merit { & ~ .merit {
margin-left: 0.4rem; margin-top: 0.4rem;
} }
img { img {
width: 100%; width: 2rem;
height: 100%; height: 2rem;
object-fit: cover;
border-radius: 0.1rem;
} }
.title { .title {
position: absolute; color: #333;
left: 0; flex: 1;
right: 0;
bottom: 0;
height: 0.91rem;
background: rgba(0, 0, 0, 0.7);
color: white;
line-height: 0.91rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
font-size: 0.37rem; font-size: 0.37rem;
padding: 0 0.11rem; padding: 0 0.11rem;
+195 -151
View File
@@ -69,7 +69,7 @@
<div class="administrator_wechat" v-if="step === 3"> <div class="administrator_wechat" v-if="step === 3">
<h1 class="title">扫码添加平台管理员微信</h1> <h1 class="title">扫码添加平台管理员微信</h1>
<img class="qrcode" src="https://wdx-temple.oss-cn-hangzhou.aliyuncs.com/uploads/common/religion-cert-bg.jpg" alt=""> <img class="qrcode" src="https://wdx-temple.oss-cn-hangzhou.aliyuncs.com/uploads/common/religion-cert-bg.jpg" alt="" />
<p class="label">平台入驻管理员微信</p> <p class="label">平台入驻管理员微信</p>
<p class="notice">审核通过后将微信通知入驻上架具体事宜</p> <p class="notice">审核通过后将微信通知入驻上架具体事宜</p>
<div class="button-group"> <div class="button-group">
@@ -83,23 +83,16 @@
</div> </div>
<van-popup v-model="showProvince" round position="bottom" safe-area-inset-bottom> <van-popup v-model="showProvince" round position="bottom" safe-area-inset-bottom>
<van-cascader <van-cascader v-model="cascaderValue" title="请选择所在地区" :options="cityOptions" @close="showProvince = false" @finish="onFinishProvince" @change="onChangeProvince" />
v-model="cascaderValue"
title="请选择所在地区"
:options="cityOptions"
@close="showProvince = false"
@finish="onFinishProvince"
@change="onChangeProvince"
/>
</van-popup> </van-popup>
</div> </div>
</template> </template>
<script> <script>
import { getRegion, getStationTemplate, postTemple } from '@/api'; import { getRegion, getStationTemplate, postTemple } from "@/api";
import { getLocation } from '@/common/wechat-web'; import { getLocation } from "@/common/wechat-web";
import TMAPLoader from '@/common/tmap'; import TMAPLoader from "@/common/tmap";
import Schema from 'async-validator'; import Schema from "async-validator";
export default { export default {
data() { data() {
@@ -107,25 +100,26 @@ export default {
const testForm = { const testForm = {
// register_cert_url: [{url: 'https://caiyuehui.oss-cn-hangzhou.aliyuncs.com/uploads/dev/2021/11/04/phpjXpokW.jpeg'}], // register_cert_url: [{url: 'https://caiyuehui.oss-cn-hangzhou.aliyuncs.com/uploads/dev/2021/11/04/phpjXpokW.jpeg'}],
register_cert_url: [], register_cert_url: [],
unit_name: '123', // 单位名称 unit_name: "123", // 单位名称
institution_code: '123123123123123123', // 机构代码 institution_code: "123123123123123123", // 机构代码
province_id: 3, // 省份ID province_id: 3, // 省份ID
city_name: 32, // 省份ID city_name: 32, // 省份ID
city_id: [3, 23, 32], city_id: [3, 23, 32],
details_address: '孤男弘法寺', // 详细地址 details_address: "孤男弘法寺", // 详细地址
lng: 103.5, // 经度 lng: 103.5, // 经度
lat: 23, // 纬度 lat: 23, // 纬度
represent: '赵', // 寺院法人 represent: "赵", // 寺院法人
mobile: '13892894922', // 手机号 mobile: "13892894922", // 手机号
source: '网络', // 寺院来源 source: "网络", // 寺院来源
is_representd: false, // 是否为寺院法人 is_representd: false, // 是否为寺院法人
register_name: '赵', // 法人姓名 register_name: "赵", // 法人姓名
login_mobile: '13983828488', // 登录手机号 login_mobile: "13983828488", // 登录手机号
password: '123456', // 登录密码 password: "123456", // 登录密码
password_confirm: '123456', // 确认密码 password_confirm: "123456", // 确认密码
} };
return { return {
loading: false, loading: false,
locating: false,
query: this.$route.query, query: this.$route.query,
active: 0, active: 0,
agreement: true, // 是否同意寺院联盟服务协议 agreement: true, // 是否同意寺院联盟服务协议
@@ -136,73 +130,75 @@ export default {
form: { form: {
register_cert_url: [], register_cert_url: [],
unit_name: '', // 单位名称 unit_name: "", // 单位名称
institution_code: '', // 机构代码 institution_code: "", // 机构代码
province_id: '', // 省份ID province_id: "", // 省份ID
city_name: '', // 城市名称 city_name: "", // 城市名称
details_address: '', // 详细地址 details_address: "", // 详细地址
lng: '', // 经度 lng: "", // 经度
lat: '', // 纬度 lat: "", // 纬度
represent: '', // 寺院法人 represent: "", // 寺院法人
mobile: '', // 手机号 mobile: "", // 手机号
source: '', // 寺院来源 source: "", // 寺院来源
is_representd: '', // 是否为寺院法人 is_representd: "", // 是否为寺院法人
register_name: '', // 法人姓名 register_name: "", // 法人姓名
login_mobile: '', // 登录手机号 login_mobile: "", // 登录手机号
password: '', // 登录密码 password: "", // 登录密码
password_confirm: '', // 确认密码 password_confirm: "", // 确认密码
}, },
formRules: { formRules: {
unit_name: { required: true, message: '请输入单位名称' }, unit_name: { required: true, message: "请输入单位名称" },
institution_code: [ institution_code: [
{ required: true, message: '请输入机构代码' }, { required: true, message: "请输入机构代码" },
{ message: '请输入18位的机构代码', validator: (rule, value) => value.length === 18 } { message: "请输入18位的机构代码", validator: (rule, value) => value.length === 18 },
], ],
city_id: { required: true, message: '请选择城市' }, city_id: { required: true, message: "请选择城市" },
details_address: { required: true, message: '请输入详细地址' }, details_address: { required: true, message: "请输入详细地址" },
represent: { required: true, message: '请输入寺院法人' }, represent: { required: true, message: "请输入寺院法人" },
mobile: [ mobile: [
{ required: true, message: '请输入手机号码' }, { required: true, message: "请输入手机号码" },
{ validator: (rule, value) => this.$config.RegExp.mobile.test(value), message: '请输入合法的手机号码'} { validator: (rule, value) => this.$config.RegExp.mobile.test(value), message: "请输入合法的手机号码" },
], ],
source: { required: true, message: '请输入寺院来源' }, source: { required: true, message: "请输入寺院来源" },
register_name: { validator: {} }, register_name: { validator: {} },
login_mobile: { required: true, message: '请输入法人手机号码' }, login_mobile: { required: true, message: "请输入法人手机号码" },
password: { required: true, message: '请输入登陆密码' }, password: { required: true, message: "请输入登陆密码" },
password_confirm: { required: true, message: '请确认登录密码' } password_confirm: { required: true, message: "请确认登录密码" },
}, },
// form: testForm, // form: testForm,
geocoder: null, geocoder: null,
TMap: null, TMap: null,
mapReady: null,
selectedOptions: [], selectedOptions: [],
} };
}, },
computed: { computed: {
step: { step: {
get() { get() {
return Number(this.$route.query.step) || 1; return Number(this.$route.query.step) || 1;
} },
}, },
canNextStep2() { canNextStep2() {
return this.form.register_cert_url.length > 0 && this.agreement return this.form.register_cert_url.length > 0 && this.agreement;
} },
}, },
created() { created() {
TMAPLoader.load({ this.mapReady = TMAPLoader.load({
key: process.env.VUE_APP_TMAP_KEY, key: process.env.VUE_APP_TMAP_KEY,
libraries: ['service'] libraries: ["service"],
}).then(TMap => { }).then((TMap) => {
this.TMap = TMap; this.TMap = TMap;
this.geocoder = new TMap.service.Geocoder(); this.geocoder = new TMap.service.Geocoder();
}) return TMap;
});
this.getParams(); this.getParams();
this.wechatReady(() => { this.wechatReady(() => {
console.log('wechat ready') console.log("wechat ready");
}); });
}, },
mounted() { mounted() {
if (this.$route.query.template_id) { if (this.$route.query.template_id) {
return this.getStationTemplate() return this.getStationTemplate();
} }
if (this.form.register_cert_url.length === 0 && Number(this.$route.query.step) !== 1) { if (this.form.register_cert_url.length === 0 && Number(this.$route.query.step) !== 1) {
return this.$router.push({ query: { step: 1 } }); return this.$router.push({ query: { step: 1 } });
@@ -213,125 +209,172 @@ export default {
this.loading = true; this.loading = true;
const data = await getStationTemplate(this.$route.query.template_id); const data = await getStationTemplate(this.$route.query.template_id);
this.loading = false; this.loading = false;
data.register_cert_url = data.register_cert_url.split(',').map(item => ({ url: item })); data.register_cert_url = data.register_cert_url.split(",").map((item) => ({ url: item }));
data.is_representd = data.is_representd === 1; data.is_representd = data.is_representd === 1;
this.form = { ...this.form, ...data } this.form = { ...this.form, ...data };
const selectedOptions = []; const selectedOptions = [];
const province = this.cityOptions.find(item => item.value === data.province_id); const province = this.cityOptions.find((item) => item.value === data.province_id);
selectedOptions.push(province); selectedOptions.push(province);
const city = province.children.find(item => item.value === data.city_id); const city = province.children.find((item) => item.value === data.city_id);
selectedOptions.push(city) selectedOptions.push(city);
this.onFinishProvince({ selectedOptions }) this.onFinishProvince({ selectedOptions });
}, },
onAgreement() { onAgreement() {
this.$router.push({ name: 'user-temple-station-agreement' }) this.$router.push({ name: "user-temple-station-agreement" });
}, },
handleErrors(errors) { handleErrors(errors) {
for (let i = 0; i < errors.length; i++) { for (let i = 0; i < errors.length; i++) {
if (errors[i]) { if (errors[i]) {
this.$toast.fail(errors[i].message) this.$toast.fail(errors[i].message);
break; break;
} }
} }
}, },
onNextStep(step = 1) { onNextStep(step = 1) {
this.$router.push({ query: { step: this.step + step }}) this.$router.push({ query: { step: this.step + step } });
}, },
onGetAddress(){ async ensureMapReady() {
getLocation().then(({ longitude, latitude}) => { if (this.geocoder && this.TMap) {
const location = new this.TMap.LatLng(latitude, longitude) return;
this.geocoder.getAddress({ location }).then(res => { }
this.form.details_address = res.result.address await this.mapReady;
this.form.lng = longitude },
this.form.lat = latitude async onGetAddress() {
}) try {
}) this.locating = true;
await this.ensureMapReady();
const { longitude, latitude } = await getLocation();
const location = new this.TMap.LatLng(latitude, longitude);
const res = await this.geocoder.getAddress({ location });
this.form.details_address = res.result.address;
this.form.lng = longitude || "0.0";
this.form.lat = latitude || "0.0";
} catch (error) {
const message = error && error.message ? error.message : "自动获取地址失败,请稍后重试";
this.$toast.fail(message);
} finally {
this.locating = false;
}
}, },
async getLatLngByAddress(addressText) { async getLatLngByAddress(addressText) {
await this.ensureMapReady();
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.loading = true; this.loading = true;
const cityAddress = this.selectedOptions.map(v => v.text).join('') const cityAddress = this.selectedOptions.map((v) => v.text).join("");
this.geocoder.getLocation({address: cityAddress + addressText}).then(res => { const address = `${cityAddress}${addressText || ""}`.trim();
this.loading = false this.geocoder
resolve(res.result.location) .getLocation({ address })
}).catch(error => { .then((res) => {
this.loading = false;
if (res && res.result && res.result.location) {
resolve(res.result.location);
return;
}
reject(new Error("未查询到地址信息,请核对地址"));
})
.catch((error) => {
this.loading = false; this.loading = false;
if (error.status === 347) { if (error.status === 347) {
this.$toast.fail('未查询到地址信息,请核对地址') reject(new Error("未查询到地址信息,请核对地址"));
reject(); return;
} }
reject(error || new Error("地址解析失败"));
});
}); });
})
}, },
// 根据地址更新坐标 // 根据地址更新坐标
async onUpdateLatLng({ target: { value } }) { async onUpdateLatLng({ target: { value } }) {
const { lat, lng } = await this.getLatLngByAddress(value) if (!value || !this.selectedOptions.length) {
return;
}
try {
const { lat, lng } = await this.getLatLngByAddress(value);
this.form.lat = lat;
this.form.lng = lng;
} catch (error) {
const message = error && error.message ? error.message : "地址解析失败";
this.$toast.fail(message);
}
},
getParams() {
getRegion().then((city) => {
this.cityOptions = city;
});
},
onChangeProvince() {},
async ensureFormLatLng() {
if (this.form.lat && this.form.lng) {
return;
}
if (!this.form.details_address || !this.selectedOptions.length) {
throw new Error("请先完善省市和详细地址");
}
const { lat, lng } = await this.getLatLngByAddress(this.form.details_address);
this.form.lat = lat; this.form.lat = lat;
this.form.lng = lng; this.form.lng = lng;
},
getParams(){
getRegion().then(city => {
this.cityOptions = city
})
},
onChangeProvince(){
}, },
onSubmitBefore() { onSubmitBefore() {
const validator = new Schema(this.formRules); const validator = new Schema(this.formRules);
validator.validate(this.form, ((errors) => { validator.validate(this.form, async (errors) => {
if (errors) { if (errors) {
return this.handleErrors(errors) return this.handleErrors(errors);
}
try {
await this.ensureFormLatLng();
} catch (error) {
this.$toast.fail(error.message || "经纬度获取失败,请检查地址后重试");
return;
} }
//
this.onNextStep(1); this.onNextStep(1);
})) });
}, },
async onSubmit() { async onSubmit() {
const [province_id, city_id, country_id] = this.form.city_id; const [province_id, city_id, country_id] = this.form.city_id;
const request = { const request = {
...this.form, ...this.form,
is_representd: this.form.is_representd ? 1 : 0, is_representd: this.form.is_representd ? 1 : 0,
province_id, city_id, country_id, province_id,
register_cert_url: this.form.register_cert_url.map(v => v.url), city_id,
} country_id,
register_cert_url: this.form.register_cert_url.map((v) => v.url),
};
await postTemple(request); await postTemple(request);
this.$toast.success('提交成功') this.$toast.success("提交成功");
await this.$delay(2000) await this.$delay(2000);
this.$router.replace({ name: 'user-home'}) this.$router.replace({ name: "user-home" });
}, },
onFinishProvince({ selectedOptions }) { onFinishProvince({ selectedOptions }) {
this.selectedOptions = selectedOptions; this.selectedOptions = selectedOptions;
this.showProvince = false; this.showProvince = false;
this.form.city_name = selectedOptions.map(v => v.text).join(' / ') this.form.city_name = selectedOptions.map((v) => v.text).join(" / ");
this.form.city_id = selectedOptions.map(v => v.value) this.form.city_id = selectedOptions.map((v) => v.value);
} },
} },
} };
</script> </script>
<style lang="scss"> <style lang="scss">
.steps { .steps {
background: #f5f5f5; background: #f5f5f5;
padding: .27rem .4rem; padding: 0.27rem 0.4rem;
font-size: .37rem; font-size: 0.37rem;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
border-bottom: 1px solid #ddd; border-bottom: 1px solid #ddd;
.circle { .circle {
width: .8rem; width: 0.8rem;
height: .8rem; height: 0.8rem;
display: inline-block; display: inline-block;
text-align: center; text-align: center;
vertical-align: middle; vertical-align: middle;
line-height: .9rem; line-height: 0.9rem;
background: #ddd; background: #ddd;
color: white; color: white;
border-radius: .53rem; border-radius: 0.53rem;
margin-right: .27rem; margin-right: 0.27rem;
} }
.text { .text {
font-size: .37rem; font-size: 0.37rem;
color: #666; color: #666;
} }
.active { .active {
@@ -340,63 +383,65 @@ export default {
color: white; color: white;
} }
span { span {
color: rgb(187, 95, 95);; color: rgb(187, 95, 95);
} }
} }
} }
.settle-in { .settle-in {
.infor { .infor {
padding: .53rem .7rem; padding: 0.53rem 0.7rem;
.title { .title {
font-size: .37rem; font-size: 0.37rem;
line-height: 1.2; line-height: 1.2;
margin-bottom: 1rem; margin-bottom: 1rem;
} }
.cert-group { .cert-group {
.cert { .cert {
font-size: .37rem; font-size: 0.37rem;
color: #666; color: #666;
span { span {
font-size: .28rem; font-size: 0.28rem;
} }
} }
.uploader { .uploader {
text-align: center; text-align: center;
padding: .4rem 0; padding: 0.4rem 0;
margin-top: .4rem; margin-top: 0.4rem;
} }
} }
.attention { .attention {
font-size: .35rem; font-size: 0.35rem;
color: #999; color: #999;
margin-top: .3rem; margin-top: 0.3rem;
line-height: 1.4; line-height: 1.4;
text-align: justify; text-align: justify;
&::before { &::before {
content: '*'; content: "*";
color: red; color: red;
margin-right: .1rem; margin-right: 0.1rem;
} }
} }
.agreement { .agreement {
text-align: center; text-align: center;
font-size: .37rem; font-size: 0.37rem;
padding: 1rem 0; padding: 1rem 0;
display: flex; display: flex;
justify-content: center; justify-content: center;
} }
} }
.loading { .loading {
position: fixed; position: fixed;
left: 0;top:0;right: 0;bottom: 0; left: 0;
top: 0;
right: 0;
bottom: 0;
width: 3rem; width: 3rem;
height: 3rem; height: 3rem;
background: rgba(0, 0, 0, 0.6); background: rgba(0, 0, 0, 0.6);
margin: auto; margin: auto;
border-radius: .3rem; border-radius: 0.3rem;
font-size: .3rem; font-size: 0.3rem;
color: white; color: white;
display: flex; display: flex;
justify-content: center; justify-content: center;
@@ -410,16 +455,16 @@ export default {
} }
} }
.form { .form {
padding: .4rem 0; padding: 0.4rem 0;
.group { .group {
margin-bottom: .6rem; margin-bottom: 0.6rem;
.label-temple { .label-temple {
font-size: .4rem; font-size: 0.4rem;
padding-left: .4rem; padding-left: 0.4rem;
&::before { &::before {
content: ''; content: "";
width: 4px; width: 4px;
height: .37rem; height: 0.37rem;
background: #bb5f5f; background: #bb5f5f;
display: inline-block; display: inline-block;
margin-right: 5px; margin-right: 5px;
@@ -431,17 +476,17 @@ export default {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: .5rem .4rem .3rem; padding: 0.5rem 0.4rem 0.3rem;
.label { .label {
font-size: .37rem; font-size: 0.37rem;
} }
} }
} }
} }
.administrator_wechat { .administrator_wechat {
padding: .4rem; padding: 0.4rem;
.title { .title {
font-size: .4rem; font-size: 0.4rem;
margin-top: 1rem; margin-top: 1rem;
margin-bottom: 1rem; margin-bottom: 1rem;
} }
@@ -453,12 +498,12 @@ export default {
margin-right: auto; margin-right: auto;
} }
.label { .label {
font-size: .4rem; font-size: 0.4rem;
padding: .5rem 0; padding: 0.5rem 0;
text-align: center; text-align: center;
} }
.notice { .notice {
font-size: .4rem; font-size: 0.4rem;
color: rgb(129, 43, 43); color: rgb(129, 43, 43);
margin-top: 2rem; margin-top: 2rem;
text-align: center; text-align: center;
@@ -467,15 +512,14 @@ export default {
margin-top: 2rem; margin-top: 2rem;
display: flex; display: flex;
.prev { .prev {
margin-right: .3rem; margin-right: 0.3rem;
width: 3rem; width: 3rem;
} }
} }
} }
.button-group { .button-group {
padding: 0 .4rem; padding: 0 0.4rem;
padding-top: 0rem; padding-top: 0rem;
} }
} }
</style> </style>
+3 -3
View File
@@ -66,13 +66,13 @@ const routes = [
{ {
path: "/merit-list", path: "/merit-list",
name: "merit-list", name: "merit-list",
meta: { title: "功德无量", navBarBackgroundColor: "white" }, meta: { title: "近期活动", navBarBackgroundColor: "white" },
component: () => import("@/pages/merit-list"), component: () => import("@/pages/merit-list"),
}, },
{ {
path: "/merit-box", path: "/merit-box",
name: "merit-box", name: "merit-box",
meta: { title: "功德无量", navBarBackgroundColor: "white", showNavBar: false }, meta: { title: "近期活动", navBarBackgroundColor: "white", showNavBar: false },
component: () => import("@/pages/merit-box"), component: () => import("@/pages/merit-box"),
}, },
@@ -91,7 +91,7 @@ const routes = [
{ {
path: "/pay-result", path: "/pay-result",
name: "pay-result", name: "pay-result",
meta: { title: "捐赠成功", navBarBackgroundColor: "white" }, meta: { title: "护持成功", navBarBackgroundColor: "white" },
component: () => import("@/pages/pay-result"), component: () => import("@/pages/pay-result"),
}, },
{ {
+15 -16
View File
@@ -1,34 +1,33 @@
export default { export default {
setSearchParamsFromObj(obj) { setSearchParamsFromObj(obj) {
let search = '?'; let search = "?";
for (let i in obj) { for (let i in obj) {
search += `${i}=${obj[i]}&` search += `${i}=${obj[i]}&`;
} }
return search.slice(0, -1); return search.slice(0, -1);
}, },
addExternalParamsToQuery(url, key, value) { addExternalParamsToQuery(url, key, value) {
if (!url) { if (!url) {
return '' return "";
} }
const hasQuery = url.indexOf('?') > -1 const [beforeHash] = url.split("#");
url = url.split('?') const [beforeQuery, query = ""] = beforeHash.split("?");
const before = url.shift() const searchParams = new URLSearchParams(query);
let after = url.join('&')
const searchParams = new URLSearchParams(after);
if (!searchParams.has(key)) { if (!searchParams.has(key)) {
return before+'?'+after+'&'+key+'='+value; searchParams.set(key, value);
} }
return before+(hasQuery ? '?': '&') + after; const queryString = searchParams.toString();
return `${beforeQuery}?${queryString}`;
}, },
queryStringToObj(queryString) { queryStringToObj(queryString) {
const string = queryString.split('&'); const string = queryString.split("&");
const obj = {}; const obj = {};
string.forEach(str => { string.forEach((str) => {
const [key, value] = str.split('='); const [key, value] = str.split("=");
obj[key] = value; obj[key] = value;
}) });
return obj; return obj;
} },
} };
+12
View File
@@ -50,5 +50,17 @@ module.exports = {
}, },
css: { css: {
sourceMap: false, sourceMap: false,
loaderOptions: {
sass: {
sassOptions: {
silenceDeprecations: ["legacy-js-api", "import"],
},
},
scss: {
sassOptions: {
silenceDeprecations: ["legacy-js-api", "import"],
},
},
},
}, },
}; };
+1 -1
View File
File diff suppressed because one or more lines are too long