feat: 完成商家改版相关页面与请求工具修改

This commit is contained in:
丁杰 2026-06-03 17:49:38 +08:00
parent d5d7242ec7
commit 1e56c78f12
3 changed files with 186 additions and 155 deletions

View File

@ -1,7 +1,7 @@
<template> <template>
<view class="container"> <view class="container">
<view class="positonFixed"> <view class="positonFixed">
<view class="header-top flex-row-center" :style="{ height: `${100}rpx`,paddingTop:`${statusBarHeight}rpx`}"> <view class="header-top flex-row-center" :style="{ height: `${100 + statusBarHeight}rpx`,paddingTop:`${statusBarHeight}rpx`}">
<view class="left-area" @click="goBack"> <view class="left-area" @click="goBack">
<image src="/static/images/back.png" mode="aspectFit" class="back-icon"></image> <image src="/static/images/back.png" mode="aspectFit" class="back-icon"></image>
</view> </view>
@ -25,7 +25,7 @@
<swiper class="swiper" circular :style="swiperStyle" :current="current" @change="swiperChange" <swiper class="swiper" circular :style="swiperStyle" :current="current" @change="swiperChange"
:disable-touch="current==0"> :disable-touch="current==0">
<swiper-item> <swiper-item>
<scroll-view scroll-y :style="{height:`${viewportHeight-100-this.statusBarHeight}rpx`}"> <scroll-view scroll-y :style="{height:`${viewportHeight - 100 - statusBarHeight}rpx`}">
<view class="swiper-items3"> <view class="swiper-items3">
<view class="swiper-item3" :class="{item2Left:index%2 == 0}" <view class="swiper-item3" :class="{item2Left:index%2 == 0}"
v-for="(item,index) in videoList" :key="index" @click="tovideo(item)"> v-for="(item,index) in videoList" :key="index" @click="tovideo(item)">
@ -40,7 +40,7 @@
</scroll-view> </scroll-view>
</swiper-item> </swiper-item>
<swiper-item> <swiper-item>
<scroll-view scroll-y :style="{height:`${viewportHeight-100-this.statusBarHeight-100}rpx`}"> <scroll-view scroll-y :style="{height:`${viewportHeight - 100 - statusBarHeight - 100}rpx`}">
<view class="swiper-items2"> <view class="swiper-items2">
<view class="swiper-item2" :class="{item2Left:index%2 == 0}" <view class="swiper-item2" :class="{item2Left:index%2 == 0}"
v-for="(item,index) in imagObj[cardListIndex]" :key="index" @click="toimg(item)"> v-for="(item,index) in imagObj[cardListIndex]" :key="index" @click="toimg(item)">
@ -166,7 +166,7 @@
}; };
} }
return { return {
height: `${this.viewportHeight}rpx` height: `${this.viewportHeight - 100 - this.statusBarHeight}rpx`
}; };
}, },
swiperStyle2() { swiperStyle2() {
@ -176,7 +176,7 @@
}; };
} }
return { return {
height: `${this.viewportHeight}rpx` height: `${this.viewportHeight - 100 - this.statusBarHeight}rpx`
}; };
}, },
swiperStyle3() { swiperStyle3() {

View File

@ -542,7 +542,7 @@ export default {
// //
fetchNoticeList() { fetchNoticeList() {
request.post('/sj/notice/list', { page: 1, limit: 6 }).then(res => { request.post('/sj/notice/list', { page: 1, limit: 5 }).then(res => {
if(res.code == 200 && res.data && res.data.list.length > 0) { if(res.code == 200 && res.data && res.data.list.length > 0) {
this.noticeList = res.data.list; this.noticeList = res.data.list;
} }

View File

@ -1,40 +1,27 @@
<template> <template>
<view class="brand-detail-page"> <view class="brand-detail-page">
<custom-navbar <custom-navbar :title="info.name || '品牌详情'"
:title="info.name || '品牌详情'" :leftImg="'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/60ae3383-6ff6-4f42-818b-d9b09a9bd0e0.png'"
:leftImg="'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/60ae3383-6ff6-4f42-818b-d9b09a9bd0e0.png'" :showUser="true" backgroundColor="#ffffff" titleColor="#333" borderBottom="none" :show-headle="true"
:showUser="true" :headleSrc="isCollected ? iconCollectOn : iconCollectOff" @onHeadleClick="toggleCollectStatus">
backgroundColor="#ffffff"
titleColor="#333"
borderBottom="none"
:show-headle="true"
:headleSrc="isCollected ? iconCollectOn : iconCollectOff"
@onHeadleClick="toggleCollectStatus"
>
</custom-navbar> </custom-navbar>
<!-- 顶部导航栏扩展动态计算位置的拨号图标 --> <!-- 顶部导航栏扩展动态计算位置的拨号图标 -->
<view class="nav-phone-wrap" :style="{ top: phoneIconTop + 'px', right: phoneIconRight + 'px' }" @click="makeCall"> <view class="nav-phone-wrap" :style="{ top: phoneIconTop + 'px', right: phoneIconRight + 'px' }" @click="makeCall">
<image src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/c164280f-1ab9-41b4-9d60-846368364e9c.png" class="nav-phone-icon"></image> <image src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/c164280f-1ab9-41b4-9d60-846368364e9c.png"
class="nav-phone-icon"></image>
</view> </view>
<!-- <view class="mock-switch" @click="toggleMockData"> <!-- <view class="mock-switch" @click="toggleMockData">
<text>{{ useMockData ? '关闭模拟数据' : '开启模拟数据' }}</text> <text>{{ useMockData ? '关闭模拟数据' : '开启模拟数据' }}</text>
</view> --> </view> -->
<view class="banner-section" v-if="bannerList && bannerList.length || info.video"> <view class="banner-section" v-if="bannerList && bannerList.length || info.video">
<!-- 原生视频组件 (就地播放) --> <!-- 原生视频组件 (就地播放) -->
<video <video v-if="info.video && isVideoPlaying" id="myVideo" class="banner-video" :src="info.video" autoplay controls
v-if="info.video && isVideoPlaying" object-fit="cover"></video>
id="myVideo"
class="banner-video"
:src="info.video"
autoplay
controls
object-fit="cover"
></video>
<!-- 轮播图区域 (当视频播放时隐藏) --> <!-- 轮播图区域 (当视频播放时隐藏) -->
<swiper v-else class="banner-swiper" circular @change="onSwiperChange" :autoplay="!info.video"> <swiper v-else class="banner-swiper" circular @change="onSwiperChange" :autoplay="!info.video">
@ -42,15 +29,12 @@
<image class="banner-img" :src="item" mode="aspectFill"></image> <image class="banner-img" :src="item" mode="aspectFill"></image>
</swiper-item> </swiper-item>
</swiper> </swiper>
<!-- 居中的视频播放大图标 (当视频播放时隐藏) --> <!-- 居中的视频播放大图标 (当视频播放时隐藏) -->
<image <image v-if="info.video && !isVideoPlaying" class="center-play-icon"
v-if="info.video && !isVideoPlaying" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/bb720bb0-4ada-49f6-9ce5-38abfd613d5d.png"
class="center-play-icon" @click="playVideoInPlace"></image>
src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/bb720bb0-4ada-49f6-9ce5-38abfd613d5d.png"
@click="playVideoInPlace"
></image>
<!-- 视频/图片 相册切换组件 (当视频播放时隐藏) --> <!-- 视频/图片 相册切换组件 (当视频播放时隐藏) -->
<view class="album" v-if="(info.video || bannerList.length > 0) && !isVideoPlaying"> <view class="album" v-if="(info.video || bannerList.length > 0) && !isVideoPlaying">
<view class="album-left" @click="info.video ? playVideoInPlace() : goAlbum()"> <view class="album-left" @click="info.video ? playVideoInPlace() : goAlbum()">
@ -62,7 +46,7 @@
<image src="/static/images/icons/right7_13.png" class="album-right-img"></image> <image src="/static/images/icons/right7_13.png" class="album-right-img"></image>
</view> </view>
</view> </view>
<!-- 指示器 (当视频播放时隐藏) --> <!-- 指示器 (当视频播放时隐藏) -->
<view class="indicator" v-if="!isVideoPlaying && bannerList.length > 0"> <view class="indicator" v-if="!isVideoPlaying && bannerList.length > 0">
<text>{{ currentBannerIndex + 1 }} / {{ bannerList.length }}</text> <text>{{ currentBannerIndex + 1 }} / {{ bannerList.length }}</text>
@ -72,7 +56,7 @@
<view class="intro-section" v-if="info.name"> <view class="intro-section" v-if="info.name">
<view class="section-title">品牌介绍</view> <view class="section-title">品牌介绍</view>
<view class="intro-content" :class="{ 'is-expanded': isExpanded }"> <view class="intro-content" :class="{ 'is-expanded': isExpanded }">
<text v-html="info.detail || '暂无品牌介绍'" class="intro-text"></text> <rich-text :nodes="formatDetailContent" class="intro-text"></rich-text>
</view> </view>
<view class="expand-btn" @click="toggleExpand" v-if="info.detail && info.detail.length > 100"> <view class="expand-btn" @click="toggleExpand" v-if="info.detail && info.detail.length > 100">
<text class="expand-text">{{ isExpanded ? '收起查看' : '展开查看' }}</text> <text class="expand-text">{{ isExpanded ? '收起查看' : '展开查看' }}</text>
@ -84,19 +68,14 @@
<view class="divider-bg"></view> <view class="divider-bg"></view>
<view class="tab-section"> <view class="tab-section">
<view class="tab-header"> <view class="tab-header">
<view <view class="tab-item" v-for="(tab, index) in availableTabs" :key="tab.key"
class="tab-item" :class="{ active: activeTab === index }" @click="switchTab(index)">
v-for="(tab, index) in availableTabs"
:key="tab.key"
:class="{ active: activeTab === index }"
@click="switchTab(index)"
>
<!-- 加上 class="tab-text" 以便控制层级 --> <!-- 加上 class="tab-text" 以便控制层级 -->
<text class="tab-text">{{ tab.name }}</text> <text class="tab-text">{{ tab.name }}</text>
<view v-if="activeTab === index" class="active-line"></view> <view v-if="activeTab === index" class="active-line"></view>
</view> </view>
</view> </view>
<view class="tab-content" v-if="availableTabs[activeTab]"> <view class="tab-content" v-if="availableTabs[activeTab]">
<rich-text :nodes="availableTabs[activeTab].content"></rich-text> <rich-text :nodes="availableTabs[activeTab].content"></rich-text>
</view> </view>
@ -108,18 +87,19 @@
<view class="form-section"> <view class="form-section">
<!-- 动态标题当选中学员招募时显示"立即咨询"否则显示"在线留言" --> <!-- 动态标题当选中学员招募时显示"立即咨询"否则显示"在线留言" -->
<view class="section-title">{{ activeTabKey === 'student' ? '立即咨询' : '在线留言' }}</view> <view class="section-title">{{ activeTabKey === 'student' ? '立即咨询' : '在线留言' }}</view>
<view class="form-list"> <view class="form-list">
<view class="form-item"> <view class="form-item">
<view class="label"><text class="required">*</text>姓名</view> <view class="label"><text class="required">*</text>姓名</view>
<input class="input-el" v-model="formData.contact_name" placeholder="请输入您的姓名" placeholder-class="ph-style" /> <input class="input-el" v-model="formData.contact_name" placeholder="请输入您的姓名" placeholder-class="ph-style" />
</view> </view>
<view class="form-item"> <view class="form-item">
<view class="label"><text class="required">*</text>手机号码</view> <view class="label"><text class="required">*</text>手机号码</view>
<input class="input-el" type="number" maxlength="11" v-model="formData.contact_phone" placeholder="请输入您的手机号码" placeholder-class="ph-style" /> <input class="input-el" type="number" maxlength="11" v-model="formData.contact_phone" placeholder="请输入您的手机号码"
placeholder-class="ph-style" />
</view> </view>
<view class="form-item"> <view class="form-item">
<view class="label"><text class="required">*</text>所在城市</view> <view class="label"><text class="required">*</text>所在城市</view>
<!-- 替换为复用的弹窗选择器 --> <!-- 替换为复用的弹窗选择器 -->
@ -130,7 +110,7 @@
</view> </view>
</view> </view>
</view> </view>
<view class="form-item"> <view class="form-item">
<view class="label"><text class="required">*</text>意向</view> <view class="label"><text class="required">*</text>意向</view>
<picker class="picker-el" :range="intentionOptions" range-key="label" @change="onIntentionChange"> <picker class="picker-el" :range="intentionOptions" range-key="label" @change="onIntentionChange">
@ -140,10 +120,11 @@
</view> </view>
</picker> </picker>
</view> </view>
<view class="form-item border-none" v-if="formData.intention === 1"> <view class="form-item border-none" v-if="formData.intention === 1">
<view class="label"><text class="required">*</text>其他意向</view> <view class="label"><text class="required">*</text>其他意向</view>
<input class="input-el" v-model="formData.intention_other" placeholder="请填写您的其他意向" placeholder-class="ph-style" /> <input class="input-el" v-model="formData.intention_other" placeholder="请填写您的其他意向"
placeholder-class="ph-style" />
</view> </view>
</view> </view>
@ -159,18 +140,16 @@
<text class="popup-close" @click="hideLocationPopup">×</text> <text class="popup-close" @click="hideLocationPopup">×</text>
</view> </view>
<view class="region-body"> <view class="region-body">
<picker-view @change="bindChangeLocation" <picker-view @change="bindChangeLocation" class="picker-scroll" :indicator-style="indicatorStyle"
class="picker-scroll"
:indicator-style="indicatorStyle"
:value="locationValue"> :value="locationValue">
<picker-view-column> <picker-view-column>
<view class="picker-item" v-for="(item,index) in ChinaCitys" :key="index">{{item.province}}</view> <view class="picker-item" v-for="(item, index) in ChinaCitys" :key="index">{{ item.province }}</view>
</picker-view-column> </picker-view-column>
<picker-view-column> <picker-view-column>
<view class="picker-item" v-for="(item,index) in locatinCitys" :key="index">{{item.city}}</view> <view class="picker-item" v-for="(item, index) in locatinCitys" :key="index">{{ item.city }}</view>
</picker-view-column> </picker-view-column>
<picker-view-column> <picker-view-column>
<view class="picker-item" v-for="(item,index) in locationAreas" :key="index">{{item.area}}</view> <view class="picker-item" v-for="(item, index) in locationAreas" :key="index">{{ item.area }}</view>
</picker-view-column> </picker-view-column>
</picker-view> </picker-view>
</view> </view>
@ -196,7 +175,7 @@
import request from "@/utils/request"; import request from "@/utils/request";
import CustomNavbar from "@/components/custom-navbar/custom-navbar.vue"; import CustomNavbar from "@/components/custom-navbar/custom-navbar.vue";
import tipsPopup2 from "@/components/tips-popup/tips-popup2"; import tipsPopup2 from "@/components/tips-popup/tips-popup2";
import ChinaCitys from "@/static/data/ChinaCitys.json"; import ChinaCitys from "@/static/data/ChinaCitys.json";
export default { export default {
components: { components: {
@ -206,11 +185,11 @@ export default {
data() { data() {
return { return {
// //
useMockData: false, useMockData: false,
brandId: null, brandId: null,
info: {}, info: {},
bannerList: [], bannerList: [],
// ====== ====== // ====== ======
isLogin: false, // isLogin: false, //
@ -220,19 +199,19 @@ export default {
isCollected: false, // isCollected: false, //
// //
iconCollectOff: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/561715a5-3de0-49f3-80e4-2662febec500.png', iconCollectOff: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/561715a5-3de0-49f3-80e4-2662febec500.png',
// //
iconCollectOn: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/fe2011b0-a34d-46ee-911a-0ea6f099ad77.png', iconCollectOn: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/fe2011b0-a34d-46ee-911a-0ea6f099ad77.png',
// ================================== // ==================================
isVideoPlaying: false, // isVideoPlaying: false, //
phoneIconTop: 20, // Top phoneIconTop: 20, // Top
phoneIconRight: 50, // Right phoneIconRight: 50, // Right
currentBannerIndex: 0, currentBannerIndex: 0,
isExpanded: false, isExpanded: false,
activeTab: 0, activeTab: 0,
// //
showLocationPopupFlag: false, showLocationPopupFlag: false,
indicatorStyle: 'height: 68rpx;', indicatorStyle: 'height: 68rpx;',
@ -243,18 +222,20 @@ export default {
formData: { formData: {
id: null, id: null,
intention: '', intention: '',
intention_other: '', intention_other: '',
contact_name: '', contact_name: '',
contact_phone: '', contact_phone: '',
province_code: '', province_code: '',
city_code: '', city_code: '',
area_code: '' area_code: ''
}, },
cityNameText: '', cityNameText: '',
intentionText: '', intentionText: '',
hasSubmitted: false,
submittedData: null,
intentionOptions: [ intentionOptions: [
{ value: 2, label: '品牌加盟' }, { value: 2, label: '品牌加盟' },
{ value: 3, label: '购买产品' }, { value: 3, label: '购买产品' },
@ -268,18 +249,30 @@ export default {
activeTabKey() { activeTabKey() {
return this.availableTabs[this.activeTab]?.key || ''; return this.availableTabs[this.activeTab]?.key || '';
}, },
formatDetailContent() {
const html = this.info.detail;
if (!html) return '<div style="color:#999;font-size:13px;text-align:center;">暂无品牌介绍</div>';
let newHtml = html.replace(/<img[^>]*>/gi, function (match) {
match = match.replace(/style\s*=\s*["'][^"']*["']/gi, '');
return match.replace(/<img/gi, '<img style="max-width:100%; height:auto; display:block; border-radius:20rpx; margin:8px 0;"');
});
newHtml = newHtml.replace(/<p[^>]*>/gi, '<p style="margin-bottom: 0px; line-height: 1.6; word-break: break-all;">');
return newHtml;
},
availableTabs() { availableTabs() {
const tabs = []; const tabs = [];
// //
const formatRichText = (html) => { const formatRichText = (html) => {
if (!html) return '<div style="color:#999;font-size:13px;text-align:center;">暂无详细说明</div>'; if (!html) return '<div style="color:#999;font-size:13px;text-align:center;">暂无详细说明</div>';
let newHtml = html.replace(/<img[^>]*>/gi, function(match) { let newHtml = html.replace(/<img[^>]*>/gi, function (match) {
match = match.replace(/style\s*=\s*["'][^"']*["']/gi, ''); match = match.replace(/style\s*=\s*["'][^"']*["']/gi, '');
return match.replace(/<img/gi, '<img style="max-width:100%; height:auto; display:block; border-radius:20rpx; margin:8px 0;"'); return match.replace(/<img/gi, '<img style="max-width:100%; height:auto; display:block; border-radius:20rpx; margin:8px 0;"');
}); });
newHtml = newHtml.replace(/<p[^>]*>/gi, '<p style="margin-bottom: 0px; line-height: 1.6; word-break: break-all;">'); newHtml = newHtml.replace(/<p[^>]*>/gi, '<p style="margin-bottom: 0px; line-height: 1.6; word-break: break-all;">');
return newHtml; return newHtml;
}; };
@ -358,8 +351,8 @@ export default {
// 2. // 2.
if (!this.brandId) return; if (!this.brandId) return;
const targetState = this.isCollected ? 2 : 1; const targetState = this.isCollected ? 2 : 1;
// 3. (Mock) // 3. (Mock)
if (this.useMockData) { if (this.useMockData) {
this.isCollected = !this.isCollected; this.isCollected = !this.isCollected;
@ -375,9 +368,9 @@ export default {
}).then((res) => { }).then((res) => {
if (res.code == 200) { if (res.code == 200) {
this.isCollected = !this.isCollected; this.isCollected = !this.isCollected;
uni.showToast({ uni.showToast({
title: this.isCollected ? '收藏成功' : '已取消收藏', title: this.isCollected ? '收藏成功' : '已取消收藏',
icon: 'none' icon: 'none'
}); });
} else { } else {
uni.showToast({ title: res.msg || '操作失败', icon: 'none' }); uni.showToast({ title: res.msg || '操作失败', icon: 'none' });
@ -410,36 +403,36 @@ export default {
let index1 = valueArr[0] || 0; let index1 = valueArr[0] || 0;
let index2 = valueArr[1] || 0; let index2 = valueArr[1] || 0;
let index3 = valueArr[2] || 0; let index3 = valueArr[2] || 0;
let province = this.ChinaCitys[index1].province; let province = this.ChinaCitys[index1].province;
let city = this.locatinCitys[index2].city; let city = this.locatinCitys[index2].city;
let area = this.locationAreas[index3].area; let area = this.locationAreas[index3].area;
// //
this.cityNameText = `${province} / ${city} / ${area}`; this.cityNameText = `${province} / ${city} / ${area}`;
this.formData.province_code = province; this.formData.province_code = province;
this.formData.city_code = city; this.formData.city_code = city;
this.formData.area_code = area; this.formData.area_code = area;
this.showLocationPopupFlag = false; this.showLocationPopupFlag = false;
}, },
initNavLayout() { initNavLayout() {
let sysInfo = uni.getSystemInfoSync(); let sysInfo = uni.getSystemInfoSync();
// NavBar 44px 40px Y +2px // NavBar 44px 40px Y +2px
let top = (sysInfo.statusBarHeight || 0) + 2; let top = (sysInfo.statusBarHeight || 0) + 2;
// //
let right = 50; let right = 50;
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
let menuBtn = uni.getMenuButtonBoundingClientRect(); let menuBtn = uni.getMenuButtonBoundingClientRect();
if (menuBtn) { if (menuBtn) {
top = menuBtn.top + (menuBtn.height / 2) - 20; top = menuBtn.top + (menuBtn.height / 2) - 20;
// ( 45px ) // ( 45px )
right = sysInfo.windowWidth - menuBtn.left + 45; right = sysInfo.windowWidth - menuBtn.left + 45;
} }
// #endif // #endif
this.phoneIconTop = top; this.phoneIconTop = top;
this.phoneIconRight = right; this.phoneIconRight = right;
}, },
@ -447,7 +440,7 @@ export default {
// //
makeCall() { makeCall() {
// //
const phone = this.info.contact_phone || ''; const phone = this.info.contact_phone || '';
if (phone) { if (phone) {
uni.makePhoneCall({ uni.makePhoneCall({
phoneNumber: String(phone), phoneNumber: String(phone),
@ -486,8 +479,8 @@ export default {
} }
uni.showLoading({ title: '加载中...' }); uni.showLoading({ title: '加载中...' });
request.post("/sj/brand/details", { request.post("/sj/brand/details", {
id: this.brandId id: this.brandId
}).then((res) => { }).then((res) => {
if (res.code == 200 && res.data) { if (res.code == 200 && res.data) {
this.info = res.data; this.info = res.data;
@ -507,8 +500,8 @@ export default {
injectMockData() { injectMockData() {
this.info = { this.info = {
name: '蜜丝卡伦美甲美睫', name: '蜜丝卡伦美甲美睫',
contact_phone: '400-888-8888', contact_phone: '400-888-8888',
video: 'https://vjs.zencdn.net/v/oceans.mp4', video: 'https://vjs.zencdn.net/v/oceans.mp4',
banner_imgs: [ banner_imgs: [
'https://images.unsplash.com/photo-1610992015732-2449b76344bc?ixlib=rb-4.0.3&auto=format&fit=crop&w=750&q=80', 'https://images.unsplash.com/photo-1610992015732-2449b76344bc?ixlib=rb-4.0.3&auto=format&fit=crop&w=750&q=80',
'https://images.unsplash.com/photo-1522337660859-02fbefca4702?ixlib=rb-4.0.3&auto=format&fit=crop&w=750&q=80' 'https://images.unsplash.com/photo-1522337660859-02fbefca4702?ixlib=rb-4.0.3&auto=format&fit=crop&w=750&q=80'
@ -554,7 +547,7 @@ export default {
switchTab(index) { switchTab(index) {
this.activeTab = index; this.activeTab = index;
}, },
onIntentionChange(e) { onIntentionChange(e) {
const selectItem = this.intentionOptions[e.detail.value]; const selectItem = this.intentionOptions[e.detail.value];
this.intentionText = selectItem.label; this.intentionText = selectItem.label;
@ -566,15 +559,37 @@ export default {
uni.showToast({ title: '请填写完整必填信息', icon: 'none' }); uni.showToast({ title: '请填写完整必填信息', icon: 'none' });
return; return;
} }
if (!/^1[3-9]\d{9}$/.test(this.formData.contact_phone)) { if (!/^1[3-9]\d{9}$/.test(this.formData.contact_phone)) {
uni.showToast({ title: '请输入合法的手机号码', icon: 'none' }); uni.showToast({ title: '请输入合法的手机号码', icon: 'none' });
return; return;
} }
//
if (this.hasSubmitted && this.submittedData) {
const currentData = JSON.stringify({
contact_name: this.formData.contact_name,
contact_phone: this.formData.contact_phone,
province_code: this.formData.province_code,
city_code: this.formData.city_code,
area_code: this.formData.area_code,
intention: this.formData.intention,
intention_other: this.formData.intention_other
});
if (currentData === this.submittedData) {
uni.showModal({
title: '提示',
content: '未修改内容,不能再次提交',
showCancel: false,
confirmText: '知道了'
});
return;
}
}
if (this.useMockData) { if (this.useMockData) {
uni.showToast({ title: '模拟环境下留言提交成功!', icon: 'success' }); uni.showToast({ title: '模拟环境下留言提交成功!', icon: 'success' });
this.resetForm(); this.saveSubmittedData();
return; return;
} }
@ -582,7 +597,7 @@ export default {
request.post("/sj/brand/consult", this.formData).then((res) => { request.post("/sj/brand/consult", this.formData).then((res) => {
if (res.code == 200) { if (res.code == 200) {
uni.showToast({ title: '留言提交成功!', icon: 'success', duration: 2000 }); uni.showToast({ title: '留言提交成功!', icon: 'success', duration: 2000 });
this.resetForm(); this.saveSubmittedData();
} else { } else {
uni.showToast({ title: res.msg || '提交失败', icon: 'none' }); uni.showToast({ title: res.msg || '提交失败', icon: 'none' });
} }
@ -592,7 +607,20 @@ export default {
uni.hideLoading(); uni.hideLoading();
}); });
}, },
saveSubmittedData() {
this.hasSubmitted = true;
this.submittedData = JSON.stringify({
contact_name: this.formData.contact_name,
contact_phone: this.formData.contact_phone,
province_code: this.formData.province_code,
city_code: this.formData.city_code,
area_code: this.formData.area_code,
intention: this.formData.intention,
intention_other: this.formData.intention_other
});
},
resetForm() { resetForm() {
this.formData = { this.formData = {
id: this.brandId, id: this.brandId,
@ -630,11 +658,11 @@ export default {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
transition: opacity 0.2s; transition: opacity 0.2s;
&:active { &:active {
opacity: 0.7; opacity: 0.7;
} }
.nav-phone-icon { .nav-phone-icon {
width: 44rpx; width: 44rpx;
height: 44rpx; height: 44rpx;
@ -661,23 +689,23 @@ export default {
width: 100%; width: 100%;
height: 421rpx; height: 421rpx;
background-color: #f5f5f5; background-color: #f5f5f5;
.banner-video { .banner-video {
width: 100%; width: 100%;
height: 100%; height: 100%;
display: block; display: block;
} }
.banner-swiper { .banner-swiper {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.banner-img { .banner-img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.center-play-icon { .center-play-icon {
position: absolute; position: absolute;
top: 50%; top: 50%;
@ -687,12 +715,12 @@ export default {
height: 120rpx; height: 120rpx;
z-index: 20; z-index: 20;
transition: opacity 0.3s; transition: opacity 0.3s;
&:active { &:active {
opacity: 0.8; opacity: 0.8;
} }
} }
.album { .album {
position: absolute; position: absolute;
bottom: 10rpx; bottom: 10rpx;
@ -704,7 +732,7 @@ export default {
display: flex; display: flex;
align-items: center; align-items: center;
z-index: 10; z-index: 10;
.album-left { .album-left {
width: 73rpx; width: 73rpx;
height: 44rpx; height: 44rpx;
@ -744,7 +772,7 @@ export default {
} }
} }
} }
.indicator { .indicator {
position: absolute; position: absolute;
right: 20rpx; right: 20rpx;
@ -764,7 +792,7 @@ export default {
/* 2. 品牌介绍 */ /* 2. 品牌介绍 */
.intro-section { .intro-section {
padding: 40rpx 30rpx; padding: 40rpx 30rpx;
.section-title { .section-title {
font-weight: 500; font-weight: 500;
font-size: 30rpx; font-size: 30rpx;
@ -772,7 +800,7 @@ export default {
line-height: 42rpx; line-height: 42rpx;
margin-bottom: 24rpx; margin-bottom: 24rpx;
} }
.intro-content { .intro-content {
font-weight: 400; font-weight: 400;
font-size: 26rpx; font-size: 26rpx;
@ -782,13 +810,13 @@ export default {
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
-webkit-line-clamp: 19; -webkit-line-clamp: 19;
overflow: hidden; overflow: hidden;
white-space: pre-line; white-space: pre-line;
&.is-expanded { &.is-expanded {
-webkit-line-clamp: 9999; -webkit-line-clamp: 9999;
} }
} }
.expand-btn { .expand-btn {
display: flex; display: flex;
justify-content: center; justify-content: center;
@ -800,7 +828,7 @@ export default {
width: fit-content; width: fit-content;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
.expand-text { .expand-text {
font-weight: 400; font-weight: 400;
font-size: 24rpx; font-size: 24rpx;
@ -808,7 +836,7 @@ export default {
line-height: 33rpx; line-height: 33rpx;
margin-right: 8rpx; margin-right: 8rpx;
} }
.arrow { .arrow {
margin-bottom: -2rpx; margin-bottom: -2rpx;
width: 10rpx; width: 10rpx;
@ -817,7 +845,7 @@ export default {
border-bottom: 2rpx solid #999999; border-bottom: 2rpx solid #999999;
transform: rotate(45deg) translateY(-2rpx); transform: rotate(45deg) translateY(-2rpx);
transition: transform 0.2s ease; transition: transform 0.2s ease;
&.up { &.up {
transform: rotate(-135deg) translateY(2rpx); transform: rotate(-135deg) translateY(2rpx);
} }
@ -834,7 +862,7 @@ export default {
/* 3. 招募详情 Tab */ /* 3. 招募详情 Tab */
.tab-section { .tab-section {
padding: 0 30rpx 40rpx; padding: 0 30rpx 40rpx;
.tab-header { .tab-header {
display: flex; display: flex;
justify-content: center; justify-content: center;
@ -842,7 +870,7 @@ export default {
padding: 30rpx 0 0 0; padding: 30rpx 0 0 0;
gap: 120rpx; gap: 120rpx;
margin-bottom: 10rpx; margin-bottom: 10rpx;
.tab-item { .tab-item {
font-weight: 400; font-weight: 400;
font-size: 28rpx; font-size: 28rpx;
@ -851,7 +879,7 @@ export default {
position: relative; position: relative;
padding-bottom: 16rpx; padding-bottom: 16rpx;
transition: all 0.2s; transition: all 0.2s;
&.active { &.active {
font-weight: 500; font-weight: 500;
font-size: 30rpx; font-size: 30rpx;
@ -862,7 +890,7 @@ export default {
position: relative; position: relative;
z-index: 2; z-index: 2;
} }
.active-line { .active-line {
position: absolute; position: absolute;
bottom: 20rpx; bottom: 20rpx;
@ -877,13 +905,13 @@ export default {
} }
} }
} }
.tab-content { .tab-content {
font-weight: 400; font-weight: 400;
font-size: 26rpx; font-size: 26rpx;
color: #333333; color: #333333;
line-height: 37rpx; line-height: 37rpx;
::v-deep img { ::v-deep img {
max-width: 100% !important; max-width: 100% !important;
height: auto !important; height: auto !important;
@ -891,8 +919,9 @@ export default {
border-radius: 12rpx; border-radius: 12rpx;
margin: 20rpx 0; margin: 20rpx 0;
} }
::v-deep p, ::v-deep div { ::v-deep p,
::v-deep div {
margin-bottom: 24rpx; margin-bottom: 24rpx;
line-height: 1.6; line-height: 1.6;
} }
@ -902,7 +931,7 @@ export default {
/* 4. 在线留言表单 */ /* 4. 在线留言表单 */
.form-section { .form-section {
padding: 40rpx 30rpx; padding: 40rpx 30rpx;
.section-title { .section-title {
font-weight: 500; font-weight: 500;
font-size: 30rpx; font-size: 30rpx;
@ -910,51 +939,52 @@ export default {
line-height: 42rpx; line-height: 42rpx;
margin-bottom: 20rpx; margin-bottom: 20rpx;
} }
.form-list { .form-list {
.form-item { .form-item {
display: flex; display: flex;
align-items: center; align-items: center;
min-height: 104rpx; min-height: 104rpx;
border-bottom: 1rpx solid #F5F5F5; border-bottom: 1rpx solid #F5F5F5;
&.border-none { &.border-none {
border-bottom: none; border-bottom: none;
} }
.label { .label {
width: 190rpx; width: 190rpx;
font-size: 28rpx; font-size: 28rpx;
color: #333333; color: #333333;
line-height: 40rpx; line-height: 40rpx;
.required { .required {
color: #E5505F; color: #E5505F;
margin-right: 3rpx; margin-right: 3rpx;
} }
} }
.input-el, .picker-el { .input-el,
.picker-el {
flex: 1; flex: 1;
font-size: 28rpx; font-size: 28rpx;
color: #333333; color: #333333;
} }
.ph-style { .ph-style {
color: #C4C4C4; color: #C4C4C4;
} }
.picker-value { .picker-value {
color: #CCCCCC; color: #CCCCCC;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
width: 100%; width: 100%;
&.has-val { &.has-val {
color: #333333; color: #333333;
} }
.arrow-right { .arrow-right {
width: 12rpx; width: 12rpx;
height: 12rpx; height: 12rpx;
@ -965,7 +995,7 @@ export default {
} }
} }
} }
.submit-btn { .submit-btn {
margin-top: 60rpx; margin-top: 60rpx;
width: 100%; width: 100%;
@ -978,13 +1008,13 @@ export default {
text-align: center; text-align: center;
border: none; border: none;
transition: all 0.2s ease; transition: all 0.2s ease;
&::after { &::after {
border: none; border: none;
} }
&.is-active { &.is-active {
background-color: #FF4767; background-color: #FF4767;
color: #FFFFFF; color: #FFFFFF;
box-shadow: 0 8rpx 16rpx rgba(229, 80, 95, 0.15); box-shadow: 0 8rpx 16rpx rgba(229, 80, 95, 0.15);
} }
@ -997,7 +1027,8 @@ export default {
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
z-index: 9999; /* 层级调高,防止被挡住 */ z-index: 9999;
/* 层级调高,防止被挡住 */
visibility: hidden; visibility: hidden;
opacity: 0; opacity: 0;
transition: all 0.3s ease; transition: all 0.3s ease;