mrr.sj.front/pages/ruzhu/sj-info.vue

2076 lines
59 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 class="store-info-page">
<!-- 门店信息标题 -->
<view class="section-title">
<view class="title-bar"></view>
<text>门店信息</text>
</view>
<!-- 店铺logo -->
<view class="form-item box-cont">
<view class="label-wrapper">
<text class="label required">店铺logo</text>
<image class="label-icon" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/25bd7f38-1a3e-4282-84ea-190d7f820108" mode="aspectFit" @click="showTipPopup('head_photo')"></image>
</view>
<view class="upload-box" @click="chooseImage('head_photo')">
<image v-if="formData.head_photo" :src="formData.head_photo" mode="aspectFill" class="logo-image"></image>
<view class="upload-placeholder" v-else>
<image src="/static/images/upload-img.png" mode="aspectFit" class="upload-icon"></image>
</view>
</view>
</view>
<!-- 店铺名称 -->
<view class="form-item-one box-cont">
<view class="label-wrapper">
<text class="label required">店铺名称</text>
<image class="label-icon" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/25bd7f38-1a3e-4282-84ea-190d7f820108" mode="aspectFit" @click="showTipPopup('name')"></image>
</view>
<input type="text" v-model="formData.name" placeholder="请输入营业执照的店铺名称"
placeholder-class="placeholder" class="input"
@input="saveFormDataToLocalDebounce" />
</view>
<!-- 营业时间 -->
<view class="form-item-two box-cont" @click="openTimePicker">
<text class="label required">营业时间</text>
<view class="picker-content">
<text :class="formData.business_time ? 'picker-value' : 'placeholder'">
{{formData.business_time || '请输入营业时间'}}
</text>
<image src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/dccc4513-377c-4bfa-9fd2-a5cfdb9798f3" class="arrow-right" mode="aspectFit"></image>
</view>
</view>
<!-- 服务技能 -->
<view class="form-item-two box-cont" @click="showServicePopup">
<text class="label required">服务技能(多选)</text>
<view class="picker-content">
<text :class="formData.servers_kill.length > 0 ? 'picker-value' : 'placeholder'" v-if="formData.servers_kill">
{{selectedServicesText || '请选择'}}
</text>
<image src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/dccc4513-377c-4bfa-9fd2-a5cfdb9798f3" class="arrow-right" mode="aspectFit"></image>
</view>
</view>
<!-- 门店所在地 -->
<view class="form-item-two box-cont" @click="showLocationPopup">
<text class="label required">门店所在地:</text>
<view class="picker-content">
<text :class="formData.dependency ? 'picker-value' : 'placeholder'">
{{formData.dependency || '请选择'}}
</text>
<image src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/dccc4513-377c-4bfa-9fd2-a5cfdb9798f3" class="arrow-right" mode="aspectFit"></image>
</view>
</view>
<!-- 门店详细地址 -->
<view class="form-item-two box-cont" @click="getAddressInfo">
<text class="label required">门店详细地址:</text>
<view class="picker-content">
<text :class="formData.address ? 'picker-value' : 'placeholder'">
{{formData.address || '请选择'}}
</text>
<image src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/dccc4513-377c-4bfa-9fd2-a5cfdb9798f3" class="arrow-right" mode="aspectFit"></image>
</view>
</view>
<!-- 其他信息标题 -->
<view class="section-title">
<view class="title-bar"></view>
<text>其他信息</text>
</view>
<!-- 获取消息方式 -->
<!-- <view class="form-item-two box-cont" @click="openMessageMethodPicker">
<text class="label required">获取消息方式:</text>
<view class="picker-content">
<text :class="formData.apply_state ? 'picker-value' : 'placeholder'">
{{messageMethodText || '请选择'}}
</text>
<image src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/dccc4513-377c-4bfa-9fd2-a5cfdb9798f3" class="arrow-right" mode="aspectFit"></image>
</view>
</view> -->
<!-- 邀请码 -->
<view class="form-item-one-yqr box-cont invite-code-container">
<view class="invite-code-top">
<view class="label-wrapper">
<text class="label required">邀请码</text>
</view>
<input type="text" v-model="formData.invite_code_other" placeholder="请输入邀请码"
placeholder-class="placeholder" class="input"
@input="handleInviteCodeInput" />
</view>
<!-- 分割线 -->
<view class="divider"></view>
<!-- 邀请人信息 -->
<view class="invite-info-container">
<!-- 默认提示 -->
<text v-if="!formData.invite_code_other" class="invite-tip">
请填写邀请人的邀请码若没有邀请人请填写13131313
</text>
<!-- 验证中 -->
<view v-else-if="inviteCodeValidating" class="invite-validating">
<text>验证中...</text>
</view>
<!-- 验证失败 -->
<view v-else-if="inviteCodeError" class="invite-error" :class="{ 'shake-animation': shakeInviteError }">
<text>邀请码无效</text>
</view>
<!-- 特殊邀请码13131313 -->
<view v-else-if="formData.invite_code_other === '13131313' && !inviterInfo" class="invite-tip">
请填写邀请人的邀请码若没有邀请人请填写13131313
</view>
<!-- 显示邀请人信息 -->
<view v-else-if="inviterInfo" class="inviter-info">
<text class="inviter-label">邀请人:</text>
<text class="inviter-name">{{ inviterInfo.name || inviterInfo.nick_name }}</text>
<text class="inviter-divider">/</text>
<text class="inviter-phone">{{ inviterInfo.account }}</text>
</view>
<!-- 其他情况(接口返回成功但没有认证铁军的邀请码) -->
<view v-else class="invite-error" :class="{ 'shake-animation': shakeInviteError }">
<text>邀请码无效</text>
</view>
</view>
</view>
<!-- 专业经验 -->
<view class="form-item-two box-cont" @click="openExperiencePicker">
<text class="label required">专业经验:</text>
<view class="picker-content">
<text :class="formData.major ? 'picker-value' : 'placeholder'">
{{experienceText || '请选择'}}
</text>
<image src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/dccc4513-377c-4bfa-9fd2-a5cfdb9798f3" class="arrow-right" mode="aspectFit"></image>
</view>
</view>
<!-- 服务技能弹出框 -->
<view class="popup" :class="{ show: showServicePopupFlag }">
<view class="popup-mask" @click="hideServicePopup"></view>
<view class="popup-content">
<view class="popup-header">
<text class="popup-title">选择服务技能</text>
<text class="popup-close" @click="hideServicePopup">×</text>
</view>
<view class="popup-body">
<view class="checkbox-list">
<view class="checkbox-item" v-for="(item, index) in serviceList" :key="index"
@click="toggleServiceSelect(index)">
<view class="checkbox" :class="{ checked: item.checked }">
<image v-if="item.checked" class="check-icon" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/66325904-4603-48fd-b03b-90c684af96e9" mode="aspectFit"></image>
</view>
<text class="checkbox-label">{{item.title}}</text>
</view>
</view>
</view>
<view class="popup-footer">
<view class="popup-btn cancel" @click="hideServicePopup">
<text class="btn-text">取消</text>
</view>
<view class="popup-btn confirm" @click="confirmServiceSelect">
<text class="btn-text">确定</text>
</view>
</view>
</view>
</view>
<!-- 所在地选择弹出框 -->
<view class="popup" :class="{ show: showLocationPopupFlag }">
<view class="popup-mask" @click="hideLocationPopup"></view>
<view class="popup-content">
<view class="popup-header">
<text class="popup-title">选择所在地</text>
<text class="popup-close" @click="hideLocationPopup">×</text>
</view>
<view class="region-body">
<picker-view @change="bindChangeLocation" class="picker-scroll"
:indicator-style="indicatorStyle" :value="locationValue">
<picker-view-column>
<view class="picker-item" v-for="(item,index) in ChinaCitys" :key="index">
{{item.province}}
</view>
</picker-view-column>
<picker-view-column>
<view class="picker-item" v-for="(item,index) in locatinCitys" :key="index">
{{item.city}}
</view>
</picker-view-column>
<picker-view-column>
<view class="picker-item" v-for="(item,index) in locationAreas" :key="index">
{{item.area}}
</view>
</picker-view-column>
</picker-view>
</view>
<view class="popup-footer">
<view class="popup-btn cancel" @click="hideLocationPopup">
<text class="btn-text">取消</text>
</view>
<view class="popup-btn confirm" @click="confirmLocationSelect">
<text class="btn-text">确定</text>
</view>
</view>
</view>
</view>
<!-- 营业时间选择器 -->
<view class="popup" :class="{ show: showTimePicker }">
<view class="popup-mask" @click="hideTimePopup"></view>
<view class="popup-content">
<view class="popup-header">
<text class="cancel-text" @click="hideTimePopup">取消</text>
<text class="title">选择营业时间</text>
<text class="confirm-text" @click="confirmTime">确定</text>
</view>
<view class="time-range">
<view class="time-block" :class="{ active: timeType === 'start' }"
@click="switchTimeType('start')">
<text class="time-value">{{formatTime(startTime)}}</text>
<text class="time-label">开始时间</text>
</view>
<text class="time-separator">至</text>
<view class="time-block" :class="{ active: timeType === 'end' }"
@click="switchTimeType('end')">
<text class="time-value">{{formatTime(endTime)}}</text>
<text class="time-label">结束时间</text>
</view>
</view>
<view class="region-body">
<picker-view :value="pickerValue" @change="handleTimeChange" class="picker-scroll"
:indicator-style="indicatorStyle">
<picker-view-column>
<view class="picker-item" v-for="(hour, index) in hours" :key="index">
{{hour}}
</view>
</picker-view-column>
<picker-view-column>
<view class="picker-item" v-for="(minute, index) in minutes" :key="index">
{{minute}}
</view>
</picker-view-column>
<picker-view-column>
<view class="picker-item">-</view>
</picker-view-column>
<picker-view-column>
<view class="picker-item" v-for="(hour, index) in hours" :key="index">
{{hour}}
</view>
</picker-view-column>
<picker-view-column>
<view class="picker-item" v-for="(minute, index) in minutes" :key="index">
{{minute}}
</view>
</picker-view-column>
</picker-view>
</view>
</view>
</view>
<!-- 提示信息弹窗 -->
<view class="tip-popup" :class="{ show: showTipPopupFlag }">
<view class="tip-popup-mask" @click="hideTipPopup"></view>
<view class="tip-popup-content">
<!-- 弹窗背景图片 -->
<image class="tip-popup-bg" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/ab410a5d-5819-47f2-a0fc-3fd6b90d6770" mode="aspectFit"></image>
<!-- 弹窗内容 -->
<view class="tip-popup-body">
<view class="tip-title">{{ tipTitle }}</view>
<view class="tip-image-container">
<image class="tip-image" :class="currentTipType" :src="tipImage" mode="widthFix"></image>
</view>
<view class="tip-buttons">
<view class="tip-btn cancel" @click="hideTipPopup">
<text class="btn-text">取消</text>
</view>
<view class="tip-btn confirm" @click="hideTipPopup">
<text class="btn-text">我已了解</text>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import request from '../../utils/request';
import ChinaCitys from '../../static/data/ChinaCitys.json';
import { debounce } from '@/utils/debounce.js';
export default {
data() {
const loadedData = this.loadFormDataFromLocal();
return {
formData: loadedData || {
head_photo: '',
name: '',
business_time: '',
servers_kill: [],
dependency: '',
address: '',
apply_state: '',
invite_code_other: '',
major: '',
dependency_code: '', // 区code
dependency_province: '', // 省code
dependency_city: '', // 市code
longitude: '', // 经度
latitude: '', // 纬度
},
ChinaCitys: ChinaCitys,
locatinCitys: [],
locationAreas: [],
locationValue: [0, 0, 0],
showServicePopupFlag: false,
serviceList: [],
selectedServicesText: '',
showLocationPopupFlag: false,
showTimePicker: false,
pickerValue: [8, 0, 0, 18, 0],
hours: Array.from({ length: 24 }, (_, i) => i < 10 ? `0${i}` : `${i}`),
minutes: Array.from({ length: 60 }, (_, i) => i < 10 ? `0${i}` : `${i}`),
timeType: 'start',
indicatorStyle: 'height: 68rpx;',
messageMethodText: '',
experienceText: '',
showTipPopupFlag: false,
tipTitle: '',
tipImage: '',
currentTipType: '',
userId: null,
identity: 2,
tipImagesPreloaded: false,
tipPopupBg: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/ab410a5d-5819-47f2-a0fc-3fd6b90d6770',
// 邀请码相关字段
inviteCodeValidating: false,
inviteCodeError: false,
inviterInfo: null,
currentValidatingCode: '',
fromAddressPage: false,
addressListener: null,
// 抖动效果控制
shakeInviteError: false,
inviteValidationTimer: null, // 邀请码验证定时器
}
},
computed: {
startTime() {
return {
hour: this.hours[this.pickerValue[0]],
minute: this.minutes[this.pickerValue[1]]
}
},
endTime() {
return {
hour: this.hours[this.pickerValue[3]],
minute: this.minutes[this.pickerValue[4]]
}
}
},
watch: {
'name'(newVal) {
this.saveFormDataToLocalDebounce();
},
'formData.head_photo'(newVal) {
this.saveFormDataToLocalDebounce();
},
'formData.invite_code_other'(newVal) {
this.saveFormDataToLocalDebounce();
},
'formData.address'(newVal) {
this.saveFormDataToLocalDebounce();
}
},
onLoad() {
uni.$on('address-selected-for-sj', (addressData) => {
this.handleAddressSelected(addressData);
});
},
onUnload() {
uni.$off('address-selected-for-sj');
},
mounted() {
this.getUserInfo();
this.preloadTipImages();
this.locatinCitys = this.ChinaCitys[0].citys;
this.locationAreas = this.locatinCitys[0].areas;
this.loadServiceSkills();
this.updateSelectedServicesText();
// 初始化消息方式和专业经验显示文本
if (this.formData.apply_state) {
const methods = ['朋友圈', '抖音', '地推', '朋友介绍', '微博'];
this.messageMethodText = methods[this.formData.apply_state - 1] || '';
}
if (this.formData.major) {
const experiences = ['实习', '1-3年', '3-5年', '5-10年', '10年以上'];
this.experienceText = experiences[this.formData.major - 1] || '';
}
this.setupAddressListener();
if (this.formData.invite_code_other) {
this.validateInviteCode(this.formData.invite_code_other);
}
},
beforeDestroy() {
if (this.addressListener) {
uni.$off('address-selected', this.addressListener);
}
},
onShow() {
this.checkAddressData();
const localData = this.loadFormDataFromLocal();
if (localData) {
Object.assign(this.formData, localData);
// 立即更新显示文本(即使在 serviceList 加载完成前)
this.updateSelectedServicesTextImmediately();
// 恢复服务技能的选中状态
if (this.serviceList.length > 0) {
this.restoreServiceSkillsSelection();
}
// 恢复获取消息方式的显示文本
if (this.formData.apply_state) {
const methods = ['朋友圈', '抖音', '地推', '朋友介绍', '微博'];
this.messageMethodText = methods[this.formData.apply_state - 1] || '';
}
// 恢复专业经验的显示文本
if (this.formData.major) {
const experiences = ['实习', '1-3年', '3-5年', '5-10年', '10年以上'];
this.experienceText = experiences[this.formData.major - 1] || '';
}
}
// 重新从本地存储加载邀请码验证状态
this.loadInviteStateFromLocal();
this.checkGlobalData();
// 邀请码验证
if (this.formData.invite_code_other) {
this.validateInviteCode(this.formData.invite_code_other);
}
},
onHide() {
this.saveFormDataToLocal();
},
onUnload() {
this.saveFormDataToLocal();
},
methods: {
// 邀请码相关方法
// 从本地存储加载邀请码验证状态
loadInviteStateFromLocal() {
try {
const inviteState = uni.getStorageSync('store_invite_state');
if (inviteState) {
console.log('加载邀请码验证状态:', inviteState);
// 恢复邀请码验证状态
this.inviterInfo = inviteState.inviterInfo || null;
this.inviteCodeError = inviteState.inviteCodeError || false;
this.currentValidatingCode = inviteState.currentValidatingCode || '';
// 特殊处理如果当前邀请码是13131313确保状态正确
if (this.formData.invite_code_other === '13131313') {
console.log('检测到特殊邀请码13131313重置验证状态');
this.inviteCodeError = false;
this.inviterInfo = null;
this.currentValidatingCode = '13131313';
}
// 如果正在验证的邀请码与当前表单中的一致,保持验证状态
if (this.currentValidatingCode === this.formData.invite_code_other) {
// 状态已恢复,无需额外操作
} else {
// 如果不一致,重新验证
if (this.formData.invite_code_other && this.formData.invite_code_other.trim() !== '') {
console.log('邀请码不一致,重新验证:', this.formData.invite_code_other);
this.handleInviteCodeInput({ detail: { value: this.formData.invite_code_other } });
}
}
} else {
// 如果没有保存的状态,重置为初始状态
this.resetInviteCodeState();
}
} catch (e) {
console.log('加载邀请码验证状态失败:', e);
this.resetInviteCodeState();
}
},
// 新增方法:重置邀请码状态
resetInviteCodeState() {
this.inviteCodeValidating = false;
this.inviteCodeError = false;
this.inviterInfo = null;
this.currentValidatingCode = '';
this.shakeInviteError = false;
},
// 新增方法:专门保存邀请码验证状态
saveInviteStateToLocal() {
try {
const inviteState = {
inviterInfo: this.inviterInfo,
inviteCodeError: this.inviteCodeError,
currentValidatingCode: this.currentValidatingCode || this.formData.invite_code_other || ''
};
uni.setStorageSync('store_invite_state', inviteState);
console.log('邀请码验证状态已保存:', {
hasInviterInfo: !!this.inviterInfo,
inviteCodeError: this.inviteCodeError,
currentValidatingCode: this.currentValidatingCode
});
} catch (e) {
console.log('保存邀请码验证状态失败:', e);
}
},
// 触发邀请码错误抖动效果
triggerInviteErrorShake() {
// 触发抖动效果
this.shakeInviteError = true;
// 滚动到邀请码容器位置
this.$nextTick(() => {
// 使用uni.createSelectorQuery获取邀请码容器的位置
const query = uni.createSelectorQuery().in(this);
query.select('.invite-code-container').boundingClientRect((rect) => {
if (rect) {
// 获取当前窗口高度
const windowHeight = uni.getSystemInfoSync().windowHeight;
// 判断邀请码容器是否已经在可视区域内
// 计算容器在屏幕中的位置比例0-1之间
const containerTopRatio = rect.top / windowHeight;
const containerBottomRatio = (rect.top + rect.height) / windowHeight;
// 如果容器已经在屏幕中上部(顶部在屏幕中间以上),就不需要滚动
// 或者容器整体都在屏幕内,也不需要滚动
if (containerTopRatio >= 0 && containerTopRatio < 0.7 &&
containerBottomRatio <= 1) {
console.log('邀请码容器已在可视区域内,不需要滚动');
return;
}
// 滚动到邀请码容器位置,减去一些偏移量让用户体验更好
uni.pageScrollTo({
scrollTop: rect.top - 50,
duration: 300
});
}
}).exec();
});
// 0.5秒后重置抖动状态
setTimeout(() => {
this.shakeInviteError = false;
}, 500);
},
// 处理邀请码输入
handleInviteCodeInput(e) {
const code = e.detail ? e.detail.value : this.formData.invite_code_other;
console.log('邀请码输入:', code);
// 立即重置状态
this.inviteCodeValidating = false;
this.inviteCodeError = false;
this.inviterInfo = null;
// 如果邀请码为空,不进行验证
if (!code || code.trim() === '') {
this.formData.invite_code_other = '';
this.saveFormDataToLocalDebounce();
// 保存空状态
this.saveInviteStateToLocal();
return;
}
this.formData.invite_code_other = code;
this.saveFormDataToLocalDebounce();
// 【关键修复】如果是13131313立即通过验证并取消任何正在进行的验证
if (code === '13131313') {
console.log('检测到特殊邀请码13131313立即通过');
// 清除任何可能的定时器
if (this.inviteValidationTimer) {
clearTimeout(this.inviteValidationTimer);
this.inviteValidationTimer = null;
}
// 立即更新状态
this.inviteCodeValidating = false;
this.inviteCodeError = false;
this.inviterInfo = null;
this.currentValidatingCode = code;
// 特殊邀请码也需要保存状态
const inviteState = {
inviterInfo: null,
inviteCodeError: false,
currentValidatingCode: code
};
uni.setStorageSync('store_invite_state', inviteState);
// 强制更新视图
this.$forceUpdate();
return;
}
// 记录当前正在验证的邀请码
this.currentValidatingCode = code;
// 立即保存状态(验证中)
this.saveInviteStateToLocal();
// 清除之前的定时器
if (this.inviteValidationTimer) {
clearTimeout(this.inviteValidationTimer);
this.inviteValidationTimer = null;
}
// 设置新的定时器
this.inviteValidationTimer = setTimeout(() => {
// 检查邀请码是否变化
if (this.formData.invite_code_other !== this.currentValidatingCode) {
console.log('邀请码已变化,取消验证');
return;
}
// 再次检查是否是13131313双重检查
if (this.formData.invite_code_other === '13131313') {
console.log('双重检查检测到特殊邀请码13131313');
this.inviteCodeValidating = false;
this.inviteCodeError = false;
this.inviterInfo = null;
this.currentValidatingCode = '13131313';
const inviteState = {
inviterInfo: null,
inviteCodeError: false,
currentValidatingCode: '13131313'
};
uni.setStorageSync('store_invite_state', inviteState);
return;
}
console.log('开始验证邀请码:', this.formData.invite_code_other);
this.validateInviteCode(this.formData.invite_code_other);
// 清理定时器
this.inviteValidationTimer = null;
}, 600); // 适当增加延迟时间
},
// 验证邀请码
async validateInviteCode(code) {
console.log('开始验证邀请码:', code);
// 特殊邀请码13131313直接通过
if (code === '13131313') {
console.log('特殊邀请码13131313直接通过');
this.inviteCodeValidating = false;
this.inviteCodeError = false;
this.inviterInfo = null;
this.currentValidatingCode = code;
// 特殊邀请码也需要保存状态
const inviteState = {
inviterInfo: null,
inviteCodeError: false,
currentValidatingCode: code
};
uni.setStorageSync('store_invite_state', inviteState);
// 强制更新视图
this.$forceUpdate();
return;
}
// 如果邀请码为空
if (!code || code.trim() === '') {
this.inviteCodeValidating = false;
this.inviteCodeError = false;
this.inviterInfo = null;
this.currentValidatingCode = '';
const inviteState = {
inviterInfo: null,
inviteCodeError: false,
currentValidatingCode: ''
};
uni.setStorageSync('store_invite_state', inviteState);
return;
}
// 设置验证中状态
this.inviteCodeValidating = true;
this.inviteCodeError = false;
this.inviterInfo = null;
this.currentValidatingCode = code;
try {
// 调用接口验证邀请码
const response = await request.post('/user/user/getInvite', {
invite_code: code
});
console.log('邀请码验证响应:', response);
// 验证完成
this.inviteCodeValidating = false;
if (response && response.code === 200 && response.data) {
const userData = response.data;
//检查返回的数据是否有效
if (userData.account) {
// 邀请码有效,保存邀请人信息
this.inviterInfo = userData;
this.inviteCodeError = false;
console.log('邀请码验证通过,邀请人:', userData);
} else {
// 接口返回数据但没有account字段说明不是有效邀请人
console.log('接口返回数据无效没有account字段:', userData);
this.inviterInfo = null;
this.inviteCodeError = true;
}
} else {
// 接口返回错误或数据为空
console.log('接口返回错误:', response?.msg || '未知错误');
this.inviterInfo = null;
this.inviteCodeError = true;
}
} catch (error) {
console.error('验证邀请码失败:', error);
this.inviteCodeValidating = false;
this.inviteCodeError = true;
this.inviterInfo = null;
} finally {
// 无论成功失败都保存状态
const inviteState = {
inviterInfo: this.inviterInfo,
inviteCodeError: this.inviteCodeError,
currentValidatingCode: this.currentValidatingCode
};
uni.setStorageSync('store_invite_state', inviteState);
}
},
// 从本地存储加载数据
loadFormDataFromLocal() {
try {
const stored = uni.getStorageSync('store_info_form_data');
if (stored) {
console.log('从本地存储加载门店数据:', stored);
// 同时加载邀请码验证状态
const inviteState = uni.getStorageSync('store_invite_state');
if (inviteState) {
this.inviterInfo = inviteState.inviterInfo;
this.inviteCodeError = inviteState.inviteCodeError || false;
this.currentValidatingCode = inviteState.currentValidatingCode || '';
console.log('加载邀请码验证状态:', inviteState);
}
return stored;
}
} catch (e) {
console.log('读取门店数据失败:', e);
}
return null;
},
// 保存数据到本地存储
saveFormDataToLocal() {
try {
uni.setStorageSync('store_info_form_data', this.formData);
// 同时保存邀请码验证状态
const inviteState = {
inviterInfo: this.inviterInfo,
inviteCodeError: this.inviteCodeError,
currentValidatingCode: this.currentValidatingCode
};
uni.setStorageSync('store_invite_state', inviteState);
console.log('门店数据已保存到本地存储');
} catch (e) {
console.log('保存门店数据失败:', e);
}
},
// 防抖保存
saveFormDataToLocalDebounce() {
// 使用debounce函数
if (!this._saveDebounce) {
this._saveDebounce = debounce(() => {
this.saveFormDataToLocal();
}, 500);
}
this._saveDebounce();
},
// 清空本地存储
clearFormDataLocal() {
try {
uni.removeStorageSync('store_info_form_data');
console.log('已清空门店数据');
} catch (e) {
console.log('清空门店数据失败:', e);
}
},
// 立即更新已选择服务技能的显示文本(不依赖 serviceList
updateSelectedServicesText() {
if (this.formData.servers_kill && this.formData.servers_kill.length > 0) {
if (this.serviceList.length > 0) {
const selectedServices = this.serviceList
.filter(item => this.formData.servers_kill.includes(item.id))
.map(item => {
item.checked = true;
return item.title;
});
this.selectedServicesText = selectedServices.join('、');
} else {
// serviceList 还未加载,显示数量
this.selectedServicesText = `已选择${this.formData.servers_kill.length}`;
}
} else {
this.selectedServicesText = '';
}
},
// 地址相关方法
setupAddressListener() {
this.addressListener = (addressData) => {
this.handleAddressSelected(addressData);
};
uni.$on('address-selected', this.addressListener);
},
// 检查地址数据
checkAddressData() {
try {
const sjAddress = uni.getStorageSync('sj_selected_address');
if (sjAddress) {
this.handleAddressSelected(sjAddress);
uni.removeStorageSync('sj_selected_address');
return;
}
} catch (e) {}
if (getApp().globalData && getApp().globalData.selectedAddress) {
this.handleAddressSelected(getApp().globalData.selectedAddress);
delete getApp().globalData.selectedAddress;
}
try {
const storedAddress = uni.getStorageSync('selectedAddress');
if (storedAddress) {
this.handleAddressSelected(storedAddress);
uni.removeStorageSync('selectedAddress');
}
} catch (e) {}
},
// 处理地址选择结果
handleAddressSelected(addressData) {
if (!addressData) return
// 详细地址优先取 address不再优先取完整地址 name
let detailAddress = ''
if (addressData.address) {
detailAddress = String(addressData.address).trim()
} else if (addressData.name) {
detailAddress = String(addressData.name).trim()
const regionParts = []
if (addressData.pname) regionParts.push(addressData.pname)
if (addressData.cityname && addressData.cityname !== addressData.pname) regionParts.push(addressData.cityname)
if (addressData.adname) regionParts.push(addressData.adname)
const regionText = regionParts.join('')
const regionTextWithDash = regionParts.join('-')
if (regionText && detailAddress.indexOf(regionText) === 0) {
detailAddress = detailAddress.slice(regionText.length).trim()
} else if (regionTextWithDash && detailAddress.indexOf(regionTextWithDash) === 0) {
detailAddress = detailAddress.slice(regionTextWithDash.length).trim()
}
detailAddress = detailAddress.replace(/^[\s,-]+/, '').trim()
}
this.formData.address = detailAddress
if (addressData.location) {
const [longitude, latitude] = String(addressData.location).split(',')
this.formData.longitude = longitude || ''
this.formData.latitude = latitude || ''
}
if (addressData.pname || addressData.cityname || addressData.adname) {
const locationParts = []
if (addressData.pname) locationParts.push(addressData.pname)
if (addressData.cityname) locationParts.push(addressData.cityname)
if (addressData.adname) locationParts.push(addressData.adname)
this.formData.dependency = locationParts.join('-')
}
this.formData.dependency_province = addressData.provinceCode || ''
this.formData.dependency_city = addressData.cityCode || ''
this.formData.dependency_code = addressData.districtCode || ''
this.saveFormDataToLocal()
this.$forceUpdate()
},
// 检查全局数据
checkGlobalData() {
if (getApp().globalData.storeInfoData) {
Object.assign(this.formData, getApp().globalData.storeInfoData);
this.saveFormDataToLocal();
// delete getApp().globalData.storeInfoData;
getApp().globalData.qualificationData = null;
}
},
// 更新已选择服务技能的显示文本
updateSelectedServicesText() {
if (this.formData.servers_kill && this.formData.servers_kill.length > 0 && this.serviceList.length > 0) {
const selectedServices = this.serviceList
.filter(item => this.formData.servers_kill.includes(item.id))
.map(item => {
item.checked = true;
return item.title;
});
this.selectedServicesText = selectedServices.join('、');
}
},
// 获取用户信息
getUserInfo() {
request.post('/sj/User/getUser').then(result => {
this.userId = result.data.id;
})
},
getFormData() {
return this.formData;
},
// 预加载提示弹窗图片
preloadTipImages() {
const images = [
this.tipPopupBg, // 弹窗背景图片
'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/98ad5649-db6d-4453-a308-c592fe155ed9', // 店铺logo提示图片
'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/4a2dc8c2-98d4-4465-ae31-b2ea2d13aa23' // 店铺名称提示图片
];
console.log('开始预加载提示弹窗图片...');
// 使用 Promise.all 确保所有图片都加载完成
const loadPromises = images.map(src => this.loadImage(src));
Promise.all(loadPromises)
.then(() => {
console.log('所有提示弹窗图片预加载完成');
this.tipImagesPreloaded = true;
})
.catch(error => {
console.warn('部分图片预加载失败:', error);
// 即使部分图片加载失败,也设置为预加载完成,避免影响用户操作
this.tipImagesPreloaded = true;
});
},
// 加载单个图片
loadImage(src) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => {
console.log('图片加载成功:', src);
resolve();
};
img.onerror = () => {
console.warn('图片加载失败:', src);
reject(new Error(`图片加载失败: ${src}`));
};
img.src = src;
});
},
// 显示提示弹窗
showTipPopup(field) {
const tipConfig = {
'head_photo': {
title: '如何查看店铺logo',
image: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/98ad5649-db6d-4453-a308-c592fe155ed9'
},
'name': {
title: '如何查看店铺名称',
image: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/4a2dc8c2-98d4-4465-ae31-b2ea2d13aa23'
}
};
if (tipConfig[field]) {
this.currentTipType = field; // 设置当前类型
this.tipTitle = tipConfig[field].title;
this.tipImage = tipConfig[field].image;
// 等待图片预加载完成后再显示弹窗
if (this.tipImagesPreloaded) {
this.showTipPopupFlag = true;
} else {
// 如果图片还没预加载完成,立即加载当前图片
console.log('图片还未预加载完成,立即加载当前图片');
this.loadImage(this.tipImage).then(() => {
this.showTipPopupFlag = true;
}).catch(() => {
// 即使加载失败也显示弹窗,避免用户无法操作
this.showTipPopupFlag = true;
});
}
}
},
// 隐藏提示弹窗
hideTipPopup() {
this.showTipPopupFlag = false;
},
// 加载服务技能列表
async loadServiceSkills() {
try {
const res = await request.post('/sj/firstclass');
this.serviceList = res.data.map(item => ({
...item,
checked: false
}));
// 加载完成后立即恢复选中状态
this.restoreServiceSkillsSelection();
// 再次更新显示文本,确保显示具体的技能名称
this.updateSelectedServicesText();
} catch (error) {
console.error('加载服务技能失败:', error);
}
},
// 恢复服务技能选择状态
restoreServiceSkillsSelection() {
if (this.formData.servers_kill && this.formData.servers_kill.length > 0) {
this.serviceList.forEach(item => {
item.checked = this.formData.servers_kill.includes(item.id);
});
this.updateSelectedServicesText();
}
},
// 选择图片
chooseImage(type) {
this.openCamera(type);
},
async openCamera(type) {
try {
const chooseResult = await new Promise((resolve, reject) => {
uni.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: resolve,
fail: reject
});
});
if (!chooseResult.tempFilePaths || chooseResult.tempFilePaths.length === 0) {
return;
}
const tempFilePath = chooseResult.tempFilePaths[0];
const file = { path: tempFilePath, size: 0 };
const result = await this.directUpload(file, this.userId, this.identity + 1);
if (result) {
this.formData[type] = result;
this.saveFormDataToLocal();
}
} catch (err) {
console.log('上传图片错误:', err);
}
},
// 直接上传方法
async directUpload(file, userId, type) {
try {
let date = new Date().getTime();
let artisan = type == 1 ? 'yh' : type == 2 ? 'syr' : type == 3 ? 'sj' : '';
let fileExtension = 'jpg';
if (file.path.includes('.')) {
let parts = file.path.split('.');
let ext = parts[parts.length - 1].toLowerCase();
if (ext && ext.length <= 4) {
fileExtension = ext;
}
}
let name = `${userId}_${artisan}_${date}.${fileExtension}`;
const ossConfig = await request.post('/user/getalioss', {type: type, kind: 1});
return await new Promise((resolve, reject) => {
uni.uploadFile({
url: ossConfig.host,
filePath: file.path,
name: 'file',
formData: {
key: ossConfig.dir + name,
policy: ossConfig.policy,
OSSAccessKeyId: ossConfig.ossAccessKeyId,
success_action_status: '200',
signature: ossConfig.signature
},
success: (res) => {
if (res.statusCode === 200) {
const fileUrl = `${ossConfig.host}/${ossConfig.dir}${name}`;
resolve(fileUrl);
} else {
reject(new Error('上传失败'));
}
},
fail: reject
});
});
} catch (error) {
console.error('直接上传失败:', error);
throw error;
}
},
// 打开时间选择器
openTimePicker() {
this.showTimePicker = true;
},
// 隐藏时间选择器
hideTimePopup() {
this.showTimePicker = false;
},
// 切换时间类型
switchTimeType(type) {
this.timeType = type;
},
// 处理时间变化
handleTimeChange(e) {
const values = e.detail.value;
this.pickerValue = values;
},
// 格式化时间显示
formatTime(time) {
return `${time.hour}:${time.minute}`;
},
// 确认时间选择
confirmTime() {
this.formData.business_time = `${this.formatTime(this.startTime)}-${this.formatTime(this.endTime)}`;
this.saveFormDataToLocal();
this.hideTimePopup();
},
// 显示服务技能弹出框
showServicePopup() {
this.showServicePopupFlag = true;
},
// 隐藏服务技能弹出框
hideServicePopup() {
this.showServicePopupFlag = false;
},
// 切换服务技能选择状态
toggleServiceSelect(index) {
this.$set(this.serviceList[index], 'checked', !this.serviceList[index].checked);
},
// 确认服务技能选择
confirmServiceSelect() {
const selectedServices = this.serviceList
.filter(item => item.checked)
.map(item => item.title);
const selectedServicesId = this.serviceList
.filter(item => item.checked)
.map(item => item.id);
if (selectedServices.length === 0) {
uni.showToast({ title: '请至少选择一个服务技能', icon: 'none' });
return;
}
this.formData.servers_kill = selectedServicesId;
this.selectedServicesText = selectedServices.join('、');
this.saveFormDataToLocal();
this.hideServicePopup();
},
// 显示所在地选择弹出框
showLocationPopup() {
this.showLocationPopupFlag = true;
},
// 隐藏所在地选择弹出框
hideLocationPopup() {
this.showLocationPopupFlag = false;
},
// 所在地选择变化
bindChangeLocation(e) {
this.locationValue = e.detail.value;
let index1 = e.detail.value[0] || 0;
let index2 = e.detail.value[1] || 0;
this.locatinCitys = this.ChinaCitys[index1].citys;
this.locationAreas = this.locatinCitys[index2].areas;
},
// 确认所在地选择
confirmLocationSelect() {
let valueArr = this.locationValue;
let index1 = valueArr[0] || 0;
let index2 = valueArr[1] || 0;
let index3 = valueArr[2] || 0;
let province = this.ChinaCitys[index1].province;
let city = this.locatinCitys[index2].city;
let area = this.locationAreas[index3].area;
this.formData.dependency = province + '-' + city + '-' + area;
// 清空详细地址,因为所在地已经改变
this.formData.address = '';
this.formData.longitude = '';
this.formData.latitude = '';
if (this.ChinaCitys[index1] && this.ChinaCitys[index1].code) {
let provinceCode = this.ChinaCitys[index1].code.toString();
this.formData.dependency_province = provinceCode.substring(0, 6);
}
if (this.locatinCitys[index2] && this.locatinCitys[index2].code) {
let cityCode = this.locatinCitys[index2].code.toString();
this.formData.dependency_city = cityCode.substring(0, 6);
}
if (this.locationAreas[index3] && this.locationAreas[index3].code) {
let areaCode = this.locationAreas[index3].code.toString();
this.formData.dependency_code = areaCode.substring(0, 6);
}
this.saveFormDataToLocal();
this.hideLocationPopup();
},
buildRegionTextForSearch() {
const dependency = String(this.formData.dependency || '').trim()
if (!dependency) return ''
const parts = dependency.split('-')
const province = parts[0] || ''
const city = parts[1] || ''
const district = parts[2] || ''
let regionText = ''
if (province) regionText += province
if (city && city !== province) regionText += city
if (district) regionText += district
return regionText
},
getAddressValueForSearch() {
const rawAddress = String(this.formData.address || '').trim()
if (!rawAddress) return ''
const dependencyText = String(this.formData.dependency || '').trim()
const regionText = this.buildRegionTextForSearch()
let detail = rawAddress
// 兼容老数据里 address 被存成完整地址的情况
if (regionText && detail.indexOf(regionText) === 0) {
detail = detail.slice(regionText.length).trim()
} else if (dependencyText && detail.indexOf(dependencyText) === 0) {
detail = detail.slice(dependencyText.length).trim()
}
detail = detail.replace(/^[\s,-]+/, '').trim()
return detail || rawAddress
},
// 获取详细地址
getAddressInfo() {
this.saveFormDataToLocal()
const dependency = String(this.formData.dependency || '').trim()
const dependencyCode = String(this.formData.dependency_code || '').trim()
const address = this.getAddressValueForSearch()
const longitude = String(this.formData.longitude || '').trim()
const latitude = String(this.formData.latitude || '').trim()
const hasDependency = !!dependency
const hasAddress = !!address
const hasLocation = !!(longitude && latitude)
let params = 'source=sj_info'
// 已选所在地时,继续把地区传过去
if (hasDependency) {
params += `&dependency=${encodeURIComponent(dependency)}`
if (dependencyCode) {
params += `&dependency_code=${dependencyCode}`
}
}
// 已有详细地址时,把纯详细地址传过去,不带省市区
if (hasAddress) {
params += `&address=${encodeURIComponent(address)}`
}
// 已有坐标时,继续用已有坐标定位
if (hasLocation) {
params += `&longitude=${longitude}&latitude=${latitude}`
}
// 完全空白进入时:
// 已授权 -> 搜索页按当前定位初始化
// 未授权/拒绝 -> 搜索页静默失败后保持所在地、详细地址都为空
if (!hasDependency && !hasAddress && !hasLocation) {
params += '&init_current_location=1&silent_locate=1'
}
console.log('跳转URL参数:', params)
uni.navigateTo({
url: `/pages/address/search?${params}`
})
},
// 打开获取消息方式选择器
openMessageMethodPicker() {
uni.showActionSheet({
itemList: ['朋友圈', '抖音', '地推', '朋友介绍', '微博'],
success: (res) => {
const methods = ['朋友圈', '抖音', '地推', '朋友介绍', '微博'];
this.formData.apply_state = res.tapIndex + 1;
this.messageMethodText = methods[res.tapIndex];
this.saveFormDataToLocal();
}
});
},
// 打开专业经验选择器
openExperiencePicker() {
uni.showActionSheet({
itemList: ['实习', '1-3年', '3-5年', '5-10年', '10年以上'],
success: (res) => {
const experiences = ['实习', '1-3年', '3-5年', '5-10年', '10年以上'];
this.formData.major = res.tapIndex + 1;
this.experienceText = experiences[res.tapIndex];
this.saveFormDataToLocal();
}
});
},
// 保存表单数据(用于提交前验证)
saveFormData() {
// 验证必填字段
if (!this.formData.head_photo) {
uni.showToast({
title: '请上传店铺logo',
icon: 'none'
});
return false;
}
if (!this.formData.name) {
uni.showToast({
title: '请输入店铺名称',
icon: 'none'
});
return false;
}
if (!this.formData.business_time) {
uni.showToast({
title: '请选择营业时间',
icon: 'none'
});
return false;
}
if (this.formData.servers_kill.length === 0) {
uni.showToast({
title: '请选择服务技能',
icon: 'none'
});
return false;
}
if (!this.formData.dependency) {
uni.showToast({
title: '请选择门店所在地',
icon: 'none'
});
return false;
}
if (!this.formData.address) {
uni.showToast({
title: '请选择门店详细地址',
icon: 'none'
});
return false;
}
// if (!this.formData.apply_state) {
// uni.showToast({
// title: '请选择获取消息方式',
// icon: 'none'
// });
// return false;
// }
if (!this.formData.invite_code_other) {
uni.showToast({
title: '请输入邀请码',
icon: 'none'
});
return false;
}
// 邀请码有效性验证
if (this.inviteCodeValidating) {
uni.showToast({ title: '邀请码验证中,请稍候', icon: 'none' });
return false;
}
// 特殊邀请码13131313直接通过
if (this.formData.invite_code_other === '13131313') {
// 直接通过
} else if (this.inviteCodeError || !this.inviterInfo) {
// 邀请码无效,触发抖动效果
this.triggerInviteErrorShake();
return false;
}
if (!this.formData.major) {
uni.showToast({
title: '请选择专业经验',
icon: 'none'
});
return false;
}
// 将数据保存到全局,以便在下一步使用
getApp().globalData.storeInfoData = this.formData;
return true;
}
}
}
</script>
<style scoped>
.store-info-page {
/* padding: 28rpx 0; */
}
.section-title {
display: flex;
align-items: center;
margin-bottom: 30rpx;
}
.title-bar {
width: 6rpx;
height: 30rpx;
background-color: #E8101E;
margin-right: 7rpx;
border-radius: 5rpx;
}
.section-title text {
font-size: 32rpx;
color: #1D2129;
font-weight: 500;
}
.box-cont {
background: #ffffff;
border-radius: 20rpx;
margin-bottom: 24rpx;
margin-left: 8rpx;
margin-right: 8rpx;
box-shadow: none;
}
.form-item {
padding: 24rpx;
}
.label {
display: block;
font-size: 28rpx;
color: #333333;
font-weight: 500;
}
.required::before {
content: '*';
color: #FF0000;
margin-right: 4rpx;
}
.upload-box {
display: flex;
justify-content: center;
align-items: center;
height: 160rpx;
border-radius: 20rpx;
}
.upload-placeholder {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.upload-icon {
width: 120rpx;
height: 120rpx;
}
.upload-text {
font-size: 24rpx;
color: #999999;
}
.logo-image {
width: 120rpx;
height: 120rpx;
border-radius: 20rpx;
}
.form-item-one {
display: flex;
align-items: center;
padding: 24rpx;
}
.form-item-one-yqr {
flex-direction: column;
align-items: stretch;
padding: 0;
}
/* 创建内部的上半部分 */
.invite-code-top {
display: flex;
align-items: center;
padding: 24rpx;
width: 100%;
box-sizing: border-box;
}
/* 分割线 */
.divider {
height: 1rpx;
background-color: #00000013;
width: 100%;
}
/* 邀请信息容器 */
.invite-info-container {
padding: 20rpx 24rpx;
width: 100%;
box-sizing: border-box;
min-height: 60rpx;
}
.label-wrapper {
display: inline-flex;
align-items: center;
}
.label {
font-size: 28rpx;
color: #333333;
font-weight: 500;
line-height: 1;
}
.label-icon {
width: 26rpx;
height: 26rpx;
margin-left: 8rpx;
align-items: center;
}
.form-item-two {
display: flex;
align-items: flex-start;
justify-content: space-between;
padding: 24rpx;
}
/* 左侧标签:固定宽度,不换行 */
.form-item-two > text.label {
flex-shrink: 0;
font-size: 28rpx;
color: #333333;
font-weight: 500;
}
.input {
flex: 1;
font-size: 28rpx;
color: #333333;
text-align: right;
}
.placeholder {
color: #999999;
}
.picker-content {
display: flex;
align-items: center;
}
.picker-value,
.placeholder {
flex: 1; /* 占据剩余宽度 */
text-align: right; /* 文字右对齐 */
font-size: 28rpx;
word-break: break-all;
white-space: normal;
line-height: 1.4;
}
.arrow-right {
width: 14rpx;
height: 26rpx;
margin-left: 16rpx;
flex-shrink: 0;
}
/* 邀请码相关样式 */
.invite-tip {
font-size: 24rpx;
color: #666666;
}
.invite-validating {
font-size: 20rpx;
color: #999999;
}
.invite-error {
font-size: 24rpx;
color: #E8101E;
}
.inviter-info {
display: flex;
align-items: center;
font-size: 20rpx;
}
.inviter-label {
color: #666666;
}
.inviter-name {
color: #333333;
font-weight: 500;
}
.inviter-divider {
color: #666666;
margin: 0 5rpx;
}
.inviter-phone {
color: #666666;
}
/* 添加抖动动画样式 */
@keyframes shake {
0%, 100% { transform: translateX(0); }
10%, 30%, 50%, 70%, 90% { transform: translateX(-7rpx); }
20%, 40%, 60%, 80% { transform: translateX(7rpx); }
}
.shake-animation {
animation: shake 0.5s ease-in-out;
color: #E8101E; /* 保持红色 */
}
/* 弹窗样式 */
.popup {
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 999;
visibility: hidden;
opacity: 0;
transition: all 0.3s ease;
}
.popup.show {
visibility: visible;
opacity: 1;
}
.popup-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
}
.popup-content {
position: relative;
background-color: #FFFFFF;
border-radius: 24rpx 24rpx 0 0;
padding: 32rpx;
transform: translateY(100%);
transition: transform 0.3s ease;
}
.popup.show .popup-content {
transform: translateY(0);
}
.popup-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20rpx;
}
.popup-title {
font-size: 32rpx;
color: #333333;
font-weight: 500;
}
.popup-close {
font-size: 40rpx;
color: #999999;
padding: 16rpx;
}
.popup-body {
max-height: 600rpx;
overflow-y: auto;
}
.checkbox-list {
display: flex;
flex-wrap: wrap;
}
.checkbox-item {
width: 50%;
padding: 14rpx;
display: flex;
align-items: center;
}
.checkbox {
width: 40rpx;
height: 40rpx;
border: 2rpx solid #DDDDDD;
border-radius: 8rpx;
display: flex;
align-items: center;
justify-content: center;
margin-right: 16rpx;
}
.checkbox.checked {
background-color: #E8101E;
border-color: #E8101E;
}
.check-icon {
width: 42rpx;
height: 42rpx;
}
.checkbox-label {
font-size: 28rpx;
color: #333333;
}
.popup-footer {
display: flex;
margin-top: 32rpx;
}
.popup-btn {
flex: 1;
height: 88rpx;
border-radius: 44rpx;
display: flex;
align-items: center;
justify-content: center;
margin: 0 16rpx;
}
.popup-btn.cancel {
background-color: #F5F5F5;
}
.popup-btn.confirm {
background: linear-gradient(180deg, #f52540 0%, #e8101e 100%);
}
.popup-btn .btn-text {
font-size: 32rpx;
font-weight: 500;
}
.popup-btn.cancel .btn-text {
color: #666666;
}
.popup-btn.confirm .btn-text {
color: #FFFFFF;
}
.region-body {
height: 400rpx;
}
.picker-scroll {
height: 400rpx;
}
.picker-item {
height: 68rpx;
line-height: 68rpx;
text-align: center;
}
/* 时间选择器样式 */
.cancel-text {
font-size: 32rpx;
color: #666666;
}
.confirm-text {
font-size: 32rpx;
color: #E8101E;
font-weight: 500;
}
.time-range {
display: flex;
align-items: center;
justify-content: center;
padding: 32rpx;
background: #F8F9FC;
}
.time-block {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
background: #FFFFFF;
border-radius: 12rpx;
padding: 24rpx 0;
transition: all 0.3s ease;
}
.time-block.active {
background: #ECF2FF;
}
.time-label {
font-size: 26rpx;
color: #999999;
margin-top: 8rpx;
}
.time-value {
font-size: 40rpx;
color: #333333;
font-weight: 500;
}
.time-block.active .time-value {
color: #E8101E;
}
.time-separator {
font-size: 28rpx;
color: #999999;
margin: 0 24rpx;
}
/* 提示弹窗样式 */
.tip-popup {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
visibility: hidden;
opacity: 0;
transition: all 0.3s ease;
}
.tip-popup.show {
visibility: visible;
opacity: 1;
}
.tip-popup-mask {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
}
.tip-popup-content {
position: relative;
width: 620rpx;
height: 810rpx;
}
.tip-popup-bg {
width: 620rpx;
height: 810rpx;
position: absolute;
top: 0;
left: 0;
}
.tip-popup-body {
position: relative;
flex-direction: column;
padding: 80rpx 20rpx 40rpx 20rpx;
box-sizing: border-box;
}
.tip-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
text-align: center;
margin-top: 107rpx;
margin-bottom: 37rpx;
}
.tip-image-container {
align-items: center;
justify-content: center;
margin-bottom: 50rpx;
}
.tip-image {
width: 627rpx;
height: 327rpx;
margin-left: 13rpx;
}
/* 店铺logo图片的特殊样式 */
.tip-image.head_photo {
width: 582rpx;
height: 327rpx;
margin-right: 0;
margin-left: -15rpx;
}
/* 店铺名称图片的特殊样式 */
.tip-image.store_name {
width: 627rpx;
height: 327rpx;
margin-left: 13rpx;
}
.tip-buttons {
display: flex;
justify-content: space-between;
padding: 0 28rpx;
}
.tip-btn {
width: 250rpx;
height: 80rpx;
border-radius: 40rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
font-weight: 500;
}
.tip-btn.cancel {
border: #E8101E 2rpx solid;
background-color: transparent;
color: #e8101e;
}
.tip-btn.confirm {
background: linear-gradient(180deg, #f52540 0%, #e8101e 100%);
color: #FFFFFF;
}
.tip-btn .btn-text {
color: inherit;
}
</style>