mrr.sj.front/pages/shop/sj-info-change.vue

1702 lines
62 KiB
Vue
Raw Permalink 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">
<!-- 顶部导航栏 -->
<custom-navbar :title="navTitle" :showBack="true"></custom-navbar>
<!-- 变更提示 -->
<view class="change-tip" v-if="editable">
<text>请变更您需要变更的信息</text>
</view>
<!-- 页面内容容器 -->
<view class="page-content" :style="{ paddingBottom: buttonAreaHeight + 'px' }">
<!-- 门店信息标题 -->
<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('store_logo')"></image>
</view>
<view class="upload-box" @click="chooseImage('head_photo')">
<image v-if="displayData.head_photo" :src="displayData.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('store_name')"></image>
</view>
<input type="text" v-model="displayData.name" placeholder="请输入营业执照的店铺名称" :disabled="!editable"
placeholder-class="placeholder" class="input" />
</view>
<!-- 门店所在地 -->
<view class="form-item-two box-cont" @click="editable ? showLocationPopup() : null">
<text class="label required">门店所在地:</text>
<view class="picker-content">
<text :class="displayData.dependency ? 'picker-value' : 'placeholder'">
{{displayData.dependency || '请选择'}}
</text>
<image v-if="editable"
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="displayData.address ? 'picker-value' : 'placeholder'">
{{displayData.address || '请选择'}}
</text>
<image v-if="editable"
src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/dccc4513-377c-4bfa-9fd2-a5cfdb9798f3"
class="arrow-right" mode="aspectFit"></image>
</view>
</view>
</view>
<!-- 底部按钮区域 -->
<view class="bottom-actions" ref="buttonArea">
<!-- 驳回原因提示 -->
<view class="reject-reason" v-if="shouldShowRejectReason && auditStatus === 3 && backText">
<view class="reject-title">您的提交已驳回</view>
<view class="reject-detail">驳回原因:{{ backText }}</view>
</view>
<!-- 审核中提示 -->
<view class="audit-tip" v-if="showAuditTip">
<text class="audit-text">您的提交变更正在审核中...</text>
</view>
<!-- 变更信息按钮 -->
<view class="action-btn change-info-btn" v-if="buttonType === 'change'" @click="startChange">
<text class="btn-text">变更信息</text>
</view>
<!-- 取消和提交按钮 -->
<view class="action-buttons-row" v-if="buttonType === 'edit'">
<view class="action-btn cancel-btn" @click="cancelChange">
<text class="btn-text cancel-text">取消</text>
</view>
<view class="action-btn submit-btn" @click="submitChange">
<text class="btn-text">提交</text>
</view>
</view>
<!-- 查看我的变更/返回按钮 -->
<view class="action-btn view-change-btn" v-if="buttonType === 'view'" @click="togglePendingData">
<text class="btn-text">{{ showPendingData ? '返回' : '查看我的变更' }}</text>
</view>
<!-- 重新提交按钮 -->
<view class="action-btn resubmit-btn" v-if="buttonType === 'reject'" @click="startChange">
<text class="btn-text">重新提交</text>
</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="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 class="permission" :class="{ transform: isShowStoragePer }">
<view class="per-tit">美融融plus 对储存空间/照片权限申请说明</view>
<view class="per-cont">便于您使用该功能上传您的照片/图片/视频以及用于更换头像发布商品等场景中读取相册和文件内容</view>
</view>
<!-- 相机权限提示 -->
<view class="permission" :class="{ transform: isShowCameraPer }">
<view class="per-tit">美融融plus 对相机拍摄权限申请说明</view>
<view class="per-cont">便于您使用该功能上传您的照片/图片/视频以及用于更换头像发布商品等场景中所需内容</view>
</view>
<!-- 定位权限提示 -->
<view class="permission" :class="{ transform: isShowLocationPer }">
<view class="per-tit">美融融plus 对精确定位权限申请说明</view>
<view class="per-cont">便于您使用该功能获取您附近的手艺人以及店铺下的服务内容</view>
</view>
</view>
</template>
<script>
import request from '../../utils/request';
import ChinaCitys from '../../static/data/ChinaCitys.json';
import {
debounce
} from '@/utils/debounce.js';
import uploadImage from '../../utils/uploadImage';
import permissionUtils from '../../utils/per'; // 新增
import locationService from '../../utils/locationService'; // 新增
export default {
data() {
return {
// 页面状态
editable: false,
buttonType: 'change',
showAuditTip: false,
auditStatus: null,
applyId: null,
showPendingData: false,
navTitle: '门店信息变更',
buttonAreaHeight: 120,
backText: '',
hasResubmitted: false,
// 数据管理
originalData: {},
pendingData: {},
displayData: {},
// 门店信息字段
ChinaCitys: ChinaCitys,
locatinCitys: [],
locationAreas: [],
locationValue: [0, 0, 0],
showLocationPopupFlag: false,
showTipPopupFlag: false,
tipTitle: '',
tipImage: '',
currentTipType: '',
userId: null,
identity: 3,
applyType: 3,
// 选择器数据
hours: Array.from({
length: 24
}, (_, i) => i < 10 ? `0${i}` : `${i}`),
minutes: Array.from({
length: 60
}, (_, i) => i < 10 ? `0${i}` : `${i}`),
indicatorStyle: 'height: 68rpx;',
// 地址相关
fromAddressPage: false,
addressListener: null,
dependency_code: '',
dependency_province: '',
dependency_city: '',
longitude: '',
latitude: '',
// 权限控制变量
isShowStoragePer: false,
isShowCameraPer: false,
isShowLocationPer: false,
}
},
computed: {
shouldShowRejectReason() {
if (this.auditStatus !== 3) return false;
if (!this.backText) return false;
if (this.showPendingData) return false;
return true;
}
},
onLoad() {
uni.$on('address-selected-for-sj', (addressData) => {
this.handleAddressSelected(addressData);
});
console.log('页面开始加载...');
this.identity = getApp().globalData.artisanType;
console.log('当前身份类型:', this.identity);
this.getUserInfo();
this.loadApplyDetails();
this.locatinCitys = this.ChinaCitys[0].citys;
this.locationAreas = this.locatinCitys[0]?.areas || [];
},
onUnload() {
uni.$off('address-selected-for-sj');
},
onReady() {
this.getButtonAreaHeight();
},
onShow() {
console.log('页面显示,检查地址数据');
this.checkAddressData();
if (!this.editable) {
this.loadApplyDetails();
} else {
console.log('编辑模式下,跳过自动刷新,保持当前编辑状态');
}
if (this.auditStatus !== 3) {
this.backText = '';
this.hasResubmitted = false;
}
},
onHide() {
this.fromAddressPage = false;
},
methods: {
// 检查地址数据(原有)
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) {}
},
// 兼容接口里门店地址字段的不同命名
pickFirst(data, fields) {
for (const field of fields) {
const value = data && data[field];
if (value !== undefined && value !== null && String(value).trim() !== '') {
return value;
}
}
return '';
},
normalizeStoreInfo(data = {}) {
return {
head_photo: this.pickFirst(data, ['head_photo', 'shop_head_photo']),
name: this.pickFirst(data, ['name', 'shop_name']),
dependency: this.pickFirst(data, ['dependency', 'shop_dependency', 'uscc_dependency']),
address: this.pickFirst(data, ['address', 'shop_address', 'uscc_address']),
dependency_code: this.pickFirst(data, ['dependency_code', 'shop_dependency_code', 'uscc_area']),
dependency_province: this.pickFirst(data, ['dependency_province', 'shop_dependency_province', 'uscc_province']),
dependency_city: this.pickFirst(data, ['dependency_city', 'shop_dependency_city', 'uscc_city']),
longitude: this.pickFirst(data, ['longitude', 'shop_longitude']),
latitude: this.pickFirst(data, ['latitude', 'shop_latitude'])
};
},
mergeStoreInfoWithOriginal(data = {}) {
const storeInfo = this.normalizeStoreInfo(data);
return {
head_photo: storeInfo.head_photo || this.originalData.head_photo,
name: storeInfo.name || this.originalData.name,
dependency: storeInfo.dependency || this.originalData.dependency,
address: storeInfo.address || this.originalData.address,
dependency_code: storeInfo.dependency_code || this.originalData.dependency_code,
dependency_province: storeInfo.dependency_province || this.originalData.dependency_province,
dependency_city: storeInfo.dependency_city || this.originalData.dependency_city,
longitude: storeInfo.longitude || this.originalData.longitude,
latitude: storeInfo.latitude || this.originalData.latitude
};
},
// 获取用户信息
getUserInfo() {
console.log('开始获取用户信息...');
const type = 3;
request.post('/sj/user/getuser', {
type
}).then(result => {
console.log('接口返回完整数据:', result);
if (result.state === 1 && result.data) {
const userData = result.data;
console.log('用户数据详情:', userData);
this.userId = userData.id;
this.originalData = this.normalizeStoreInfo(userData);
this.dependency_code = this.originalData.dependency_code || '';
this.dependency_province = this.originalData.dependency_province || '';
this.dependency_city = this.originalData.dependency_city || '';
this.longitude = this.originalData.longitude || '';
this.latitude = this.originalData.latitude || '';
this.pendingData = {
...this.originalData
};
this.displayData = {
...this.originalData
};
console.log('数据初始化完成');
} else {
console.warn('接口返回state不是1或data为空');
}
}).catch(error => {
console.error('获取用户信息失败:', error);
});
},
// 智能判断申请状态(原有)
intelligentStatusCheck(detail) {
if (detail.apply_state === 2) {
console.log('智能判断:申请已审核通过');
return {
isValid: true,
status: 2,
backText: ''
};
}
if (detail.apply_time) {
const applyDate = new Date(detail.apply_time);
const now = new Date();
const daysDiff = (now - applyDate) / (1000 * 60 * 60 * 24);
if (daysDiff > 7 && this.originalData.name !== detail.name) {
console.log('智能判断:申请记录已过期,忽略历史记录');
return {
isValid: false,
status: null,
backText: ''
};
}
}
return {
isValid: true,
status: detail.apply_state,
backText: detail.back_text || ''
};
},
// 加载申请详情(原有)
async loadApplyDetails() {
try {
console.log('开始加载申请详情...');
const res = await request.post('/sj/userSjAuth/details', {
apply_type: this.applyType
});
console.log('申请详情接口返回:', res);
if (res.code === 200 && res.data) {
const detail = res.data;
const statusCheck = this.intelligentStatusCheck(detail);
if (!statusCheck.isValid) {
this.auditStatus = null;
this.backText = '';
this.applyId = null;
} else {
this.applyId = detail.id;
this.auditStatus = statusCheck.status;
this.backText = statusCheck.backText;
console.log('审核状态:', this.auditStatus);
console.log('驳回原因:', this.backText);
if (this.auditStatus === 2) {
console.log('审核通过,强制清除驳回相关状态');
this.backText = '';
this.hasResubmitted = false;
}
if (this.auditStatus === 1 || this.auditStatus === 3) {
this.pendingData = this.mergeStoreInfoWithOriginal(detail);
}
if (this.auditStatus === 2) {
this.originalData = {
...this.pendingData
};
}
}
this.updatePageStatus();
} else {
console.log('申请详情返回数据为空或code不为200:', res);
this.backText = '';
this.updatePageStatus();
}
} catch (error) {
console.error('加载申请详情失败:', error);
this.backText = '';
this.updatePageStatus();
}
},
// 更新页面状态(原有)
updatePageStatus() {
console.log('更新页面状态,审核状态:', this.auditStatus);
if (this.auditStatus !== 3) {
this.backText = '';
}
if (this.hasResubmitted && this.auditStatus === 3) {
console.log('检测到已重新提交,强制设置为审核中状态');
this.auditStatus = 1;
this.backText = '';
}
if (this.auditStatus === 1) {
this.showAuditTip = true;
this.buttonType = 'view';
this.editable = false;
this.showPendingData = false;
this.displayData = {
...this.originalData
};
} else if (this.auditStatus === 3) {
this.showAuditTip = false;
this.buttonType = 'reject';
this.editable = false;
this.showPendingData = false;
this.displayData = {
...this.originalData
};
} else {
this.showAuditTip = false;
this.buttonType = 'change';
this.editable = false;
this.showPendingData = false;
this.displayData = {
...this.originalData
};
}
this.updateNavTitle();
},
updateNavTitle() {
if (this.editable || this.showPendingData) {
this.navTitle = '门店信息变更';
} else {
this.navTitle = '门店信息';
}
},
startChange() {
this.editable = true;
this.buttonType = 'edit';
this.displayData = {
...this.pendingData
};
this.updateNavTitle();
},
cancelChange() {
this.editable = false;
this.buttonType = 'change';
this.displayData = {
...this.originalData
};
this.updateNavTitle();
},
togglePendingData() {
this.showPendingData = !this.showPendingData;
if (this.showPendingData) {
this.displayData = {
...this.pendingData
};
} else {
this.displayData = {
...this.originalData
};
}
this.updateNavTitle();
},
async submitChange() {
console.log('开始提交变更...');
console.log('提交前的displayData:', this.displayData);
if (!this.validateForm()) {
return;
}
try {
uni.showLoading({
title: '提交中...'
});
this.pendingData = {
...this.displayData
};
const submitData = {
apply_type: this.applyType,
head_photo: this.displayData.head_photo,
name: this.displayData.name,
dependency: this.displayData.dependency,
address: this.displayData.address,
longitude: this.displayData.longitude,
latitude: this.displayData.latitude,
dependency_code: this.displayData.dependency_code,
dependency_province: this.displayData.dependency_province,
dependency_city: this.displayData.dependency_city
};
console.log('提交的数据:', submitData);
const res = await request.post('/sj/userSjAuth/apply', submitData);
uni.hideLoading();
if (res.code === 200) {
uni.showToast({
title: '提交成功',
icon: 'none'
});
this.backText = '';
this.auditStatus = 1;
this.hasResubmitted = true;
this.pendingData = {
...this.displayData
};
this.editable = false;
this.buttonType = 'view';
this.showAuditTip = true;
this.showPendingData = false;
setTimeout(() => {
this.loadApplyDetails();
}, 1500);
} else {
uni.showToast({
title: res.msg || '提交失败',
icon: 'none'
});
}
} catch (error) {
uni.hideLoading();
console.error('提交失败:', error);
uni.showToast({
title: '网络错误,请重试',
icon: 'none'
});
}
},
validateForm() {
if (!this.displayData.head_photo) {
uni.showToast({
title: '请上传店铺logo',
icon: 'none'
});
return false;
}
if (!this.displayData.name) {
uni.showToast({
title: '请输入店铺名称',
icon: 'none'
});
return false;
}
if (!this.displayData.dependency) {
uni.showToast({
title: '请选择门店所在地',
icon: 'none'
});
return false;
}
if (!this.displayData.address) {
uni.showToast({
title: '请选择门店详细地址',
icon: 'none'
});
return false;
}
return true;
},
getButtonAreaHeight() {
setTimeout(() => {
const query = uni.createSelectorQuery().in(this);
query.select('.bottom-actions').boundingClientRect(data => {
if (data) this.buttonAreaHeight = data.height + 20;
}).exec();
}, 100);
},
showTipPopup(field) {
const tipConfig = {
'store_logo': {
title: '如何查看店铺logo',
image: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/98ad5649-db6d-4453-a308-c592fe155ed9'
},
'store_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;
this.showTipPopupFlag = true;
}
},
hideTipPopup() {
this.showTipPopupFlag = false;
},
// 修改后的 chooseImage加入权限检查
async chooseImage(type) {
if (!this.editable) return;
const systemInfo = uni.getSystemInfoSync();
const isIOS = systemInfo.platform === 'ios';
// 弹出操作菜单
const res = await new Promise((resolve, reject) => {
uni.showActionSheet({
itemList: ['拍照', '从相册选择'],
success: resolve,
fail: reject
});
}).catch(() => ({
tapIndex: -1
}));
if (res.tapIndex === -1) return; // 用户取消
// 处理拍照
if (res.tapIndex === 0) {
if (isIOS) {
this._openCamera(type, ['camera']);
} else {
this.isShowCameraPer = true;
const {
granted
} = await permissionUtils.checkPermission('camera', '需要相机权限以拍照');
if (granted) {
this.isShowCameraPer = false;
this._openCamera(type, ['camera']);
return;
}
this.isShowCameraPer = false;
const confirm = await this.showPermissionDialog('相机权限申请', '我们需要访问您的相机权限以便您拍照上传店铺logo');
if (!confirm) return;
const result = await permissionUtils.requestPermission('camera', '需要相机权限以拍照');
if (result) {
this._openCamera(type, ['camera']);
} else {
locationService.openAppSettings();
}
}
}
// 处理从相册选择
else if (res.tapIndex === 1) {
if (isIOS) {
this._openCamera(type, ['album']);
} else {
this.isShowStoragePer = true;
const {
granted
} = await permissionUtils.checkPermission('photo_library', '需要存储权限以选择照片');
if (granted) {
this.isShowStoragePer = false;
this._openCamera(type, ['album']);
return;
}
this.isShowStoragePer = false;
const confirm = await this.showPermissionDialog('存储权限申请', '我们需要访问您的相册权限以便您上传店铺logo');
if (!confirm) return;
const result = await permissionUtils.requestPermission('photo_library', '需要存储权限以选择照片');
if (result) {
this._openCamera(type, ['album']);
} else {
locationService.openAppSettings();
}
}
}
},
// 实际打开相机/相册
async _openCamera(type, sourceType) {
try {
const chooseResult = await new Promise((resolve, reject) => {
uni.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: sourceType,
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.displayData.head_photo = result;
console.log('图片上传成功head_photo 更新为:', result);
}
} catch (err) {
console.log('上传图片错误:', err);
if (!err.errMsg || !err.errMsg.includes('cancel')) {
uni.showToast({
title: '上传失败',
icon: 'none'
});
}
}
},
// 显示权限说明弹窗
showPermissionDialog(title, content) {
return new Promise((resolve) => {
uni.showModal({
title,
content,
confirmText: '去开启',
success(res) {
resolve(res.confirm);
}
});
});
},
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.displayData.head_photo = result;
console.log('图片上传成功head_photo 更新为:', result);
}
} catch (err) {
console.log('上传图片错误:', err);
if (!err.errMsg || !err.errMsg.includes('cancel')) {
uni.showToast({
title: '上传失败',
icon: 'none'
});
}
}
},
// 直接上传方法(原有)
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}`;
console.log('安全文件名:', name);
const ossConfig = await request.post('/user/getalioss', {
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;
}
},
// 所在地选择相关方法(原有,略)
showLocationPopup() {
if (!this.editable) return;
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.displayData.dependency = province + '-' + city + '-' + area;
this.displayData.address = '';
this.displayData.longitude = '';
this.displayData.latitude = '';
if (this.ChinaCitys[index1] && this.ChinaCitys[index1].code) {
let provinceCode = this.ChinaCitys[index1].code.toString();
this.displayData.dependency_province = provinceCode.substring(0, 6);
}
if (this.locatinCitys[index2] && this.locatinCitys[index2].code) {
let cityCode = this.locatinCitys[index2].code.toString();
this.displayData.dependency_city = cityCode.substring(0, 6);
}
if (this.locationAreas[index3] && this.locationAreas[index3].code) {
let areaCode = this.locationAreas[index3].code.toString();
this.displayData.dependency_code = areaCode.substring(0, 6);
}
this.hideLocationPopup();
},
buildRegionTextForSearch() {
const dependency = String(this.displayData.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.displayData.address || '').trim();
if (!rawAddress) return '';
const dependencyText = String(this.displayData.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;
},
async getAddressInfo() {
if (!this.editable) return;
const systemInfo = uni.getSystemInfoSync();
const isIOS = systemInfo.platform === 'ios';
const hasDependency = !!String(this.displayData.dependency || '').trim();
const hasAddress = !!String(this.getAddressValueForSearch() || '').trim();
const hasLocation = !!(this.displayData.longitude && this.displayData.latitude);
const hasExistingAddressData = hasDependency || hasAddress || hasLocation;
// iOS不走你这套权限工具的二次弹窗逻辑直接进搜索页
// 如果当前没有任何地址信息,则让搜索页自己只尝试一次定位
if (isIOS) {
this._navigateToAddress({
canInitCurrentLocation: !hasExistingAddressData
});
return;
}
// 已有所在地/详细地址/经纬度时,直接带现有值进入,不再额外申请定位
if (hasExistingAddressData) {
this._navigateToAddress({
canInitCurrentLocation: false
});
return;
}
// 只有完全空白进入时,才申请一次定位权限
this.isShowLocationPer = true;
let granted = false;
try {
const checkRes = await permissionUtils.checkPermission('location', '需要定位权限以获取您的位置');
granted = typeof checkRes === 'boolean' ? checkRes : !!(checkRes && checkRes.granted);
if (!granted) {
const requestRes = await permissionUtils.requestPermission('location', '需要定位权限以获取您的位置');
granted = typeof requestRes === 'boolean' ? requestRes : !!(requestRes && requestRes.granted);
}
} catch (error) {
console.log('定位权限申请流程异常:', error);
granted = false;
}
this.isShowLocationPer = false;
// 不管用户同不同意,都进入搜索地址页
// 同意:按当前位置初始化
// 不同意/没给权限:进入页面但不自动精确定位
this._navigateToAddress({
canInitCurrentLocation: granted
});
},
_navigateToAddress({
canInitCurrentLocation = false
} = {}) {
let params = 'source=sj_info';
const dependency = String(this.displayData.dependency || '').trim();
const dependencyCode = String(this.displayData.dependency_code || '').trim();
const address = this.getAddressValueForSearch();
const longitude = this.displayData.longitude;
const latitude = this.displayData.latitude;
const hasDependency = !!dependency;
const hasAddress = !!address;
const hasLocation = !!(longitude && latitude);
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) {
if (canInitCurrentLocation) {
params += '&init_current_location=1&silent_locate=1';
} else {
params += '&skip_auto_locate=1';
}
}
this.fromAddressPage = true;
uni.navigateTo({
url: `/pages/address/search?${params}`,
success: () => console.log('成功跳转到地址选择页面'),
fail: (err) => console.error('跳转地址选择页面失败:', err)
});
},
handleAddressSelected(addressData) {
if (!addressData) return;
// 详细地址只取 address不再优先取 name
let detailAddress = '';
if (addressData.address) {
detailAddress = String(addressData.address).trim();
} else if (addressData.name) {
// 兜底老数据里如果只有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.displayData.address = detailAddress;
this.pendingData.address = detailAddress;
if (addressData.location) {
const [longitude, latitude] = addressData.location.split(',');
this.displayData.longitude = longitude || '';
this.displayData.latitude = latitude || '';
this.pendingData.longitude = longitude || '';
this.pendingData.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);
const dependency = locationParts.join('-');
this.displayData.dependency = dependency;
this.pendingData.dependency = dependency;
}
if (addressData.provinceCode || addressData.cityCode || addressData.districtCode) {
this.displayData.dependency_province = addressData.provinceCode || '';
this.displayData.dependency_city = addressData.cityCode || '';
this.displayData.dependency_code = addressData.districtCode || '';
this.pendingData.dependency_province = addressData.provinceCode || '';
this.pendingData.dependency_city = addressData.cityCode || '';
this.pendingData.dependency_code = addressData.districtCode || '';
}
console.log('地址更新完成:', {
address: this.displayData.address,
dependency: this.displayData.dependency,
longitude: this.displayData.longitude,
latitude: this.displayData.latitude
});
this.$forceUpdate();
}
}
}
</script>
<style scoped lang="less">
.store-info-page {
padding-bottom: 20rpx;
}
.page-content {
flex: 1;
overflow-y: auto;
box-sizing: border-box;
padding: 20rpx 20rpx;
}
.change-tip {
background: #FAE7EC;
padding: 20rpx;
text-align: center;
}
.change-tip text {
font-size: 28rpx;
color: #D4131F;
}
.audit-tip {
margin: 20rpx 24rpx 20rpx 24rpx;
border-radius: 12rpx;
}
.audit-text {
font-weight: 400;
font-size: 32rpx;
color: #333333;
text-align: center;
display: block;
}
.reject-reason {
background: transparent;
padding: 24rpx;
}
.reject-title {
font-family: PingFangSC, PingFang SC;
font-weight: 500;
font-size: 32rpx;
color: #333333;
line-height: 45rpx;
text-align: center;
font-style: normal;
}
.reject-detail {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 28rpx;
color: #999999;
line-height: 40rpx;
text-align: center;
font-style: normal;
margin-top: 12rpx;
}
.section-title {
display: flex;
align-items: center;
margin-bottom: 30rpx;
}
.title-bar {
width: 6rpx;
height: 30rpx;
background-color: #FF4767;
margin-right: 7rpx;
border-radius: 5rpx;
}
.section-title text {
font-size: 36rpx;
color: #1D2129;
font-weight: 400;
}
.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;
}
.logo-image {
width: 120rpx;
height: 120rpx;
border-radius: 20rpx;
}
.form-item-one {
display: flex;
align-items: center;
padding: 24rpx;
}
.label-wrapper {
display: inline-flex;
align-items: center;
transform: translateY(4rpx);
}
.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;
.label {
transform: translateY(4rpx);
}
}
/* 左侧标签:固定宽度,不换行 */
.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 {
flex: 1;
display: flex;
align-items: center;
/* justify-content: center; */
gap: 16rpx;
word-break: break-all;
}
.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;
flex-shrink: 0;
/* margin-left: 16rpx; */
}
.bottom-actions {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 0rpx 24rpx 40rpx 24rpx;
background: #ffffff;
z-index: 100;
}
.action-btn {
height: 88rpx;
border-radius: 43rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
font-weight: 400;
margin-top: 20rpx;
}
.change-info-btn,
.view-change-btn,
.resubmit-btn {
background: linear-gradient(180deg, #ff8e9d 0%, #FF4767 100%);
}
.action-buttons-row {
display: flex;
justify-content: space-between;
margin: 0 30rpx;
}
.action-buttons-row .action-btn {
width: 270rpx;
}
.cancel-btn {
background: #E5E5E5;
border-radius: 43rpx;
padding: 0 15rpx;
}
.submit-btn {
background: linear-gradient(180deg, #ff8e9d 0%, #FF4767 100%);
border-radius: 43rpx;
padding: 0 15rpx;
}
.btn-text {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 36rpx;
color: #FFFFFF;
line-height: 50rpx;
text-align: left;
font-style: normal;
}
.cancel-text {
color: #666666;
}
.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;
}
.region-body {
height: 400rpx;
}
.picker-scroll {
height: 400rpx;
}
.picker-item {
height: 68rpx;
line-height: 68rpx;
text-align: center;
}
.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, #ff8e9d 0%, #FF4767 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;
}
.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.store_logo {
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: #FF4767 2rpx solid;
background-color: transparent;
color: #FF4767;
}
.tip-btn.confirm {
background: linear-gradient(180deg, #ff8e9d 0%, #FF4767 100%);
color: #FFFFFF;
}
.tip-btn .btn-text {
color: inherit;
}
.permission.transform {
top: calc(var(--status-bar-height) + 88rpx + 20rpx);
opacity: 1;
visibility: visible;
}
</style>