diff --git a/manifest.json b/manifest.json index ea94134..9a538a2 100644 --- a/manifest.json +++ b/manifest.json @@ -2,8 +2,8 @@ "name" : "美融融商家", "appid" : "__UNI__BBE6285", "description" : "同城便捷到家美业“技术外卖”服务、同城预约到店服务平台美融融为同城爱美人群提供更优质的更全面的服务。", - "versionName" : "1.0.17", - "versionCode" : 1017, + "versionName" : "1.0.20", + "versionCode" : 1020, "transformPx" : false, /* 5+App特有相关 */ "app-plus" : { diff --git a/pages/home/components/skill-card.vue b/pages/home/components/skill-card.vue index fce4095..0e0e9ba 100644 --- a/pages/home/components/skill-card.vue +++ b/pages/home/components/skill-card.vue @@ -193,4 +193,4 @@ export default { -webkit-line-clamp: 2; overflow: hidden; } - \ No newline at end of file + diff --git a/pages/jingxuan/brand-detail.vue b/pages/jingxuan/brand-detail.vue index 1910932..826ee7a 100644 --- a/pages/jingxuan/brand-detail.vue +++ b/pages/jingxuan/brand-detail.vue @@ -3,8 +3,12 @@ + :showUser="true" backgroundColor="#ffffff" titleColor="#333" borderBottom="none"> + @@ -721,6 +725,31 @@ export default { position: relative; } +.brand-detail-page ::v-deep .right-area { + border: none; + border-radius: 0; + background: transparent; +} + +.collect-btn { + width: 46rpx; + height: 46rpx; + display: flex; + align-items: center; + justify-content: center; + background: transparent; +} + +.collect-icon { + font-size: 42rpx; + line-height: 46rpx; + color: #C9CDD4; + + &.active { + color: #FF4767; + } +} + /* 导航栏左侧新增动态拨号图标 */ .nav-phone-wrap { position: fixed; diff --git a/pages/jingxuan/selected-skills.vue b/pages/jingxuan/selected-skills.vue index 444aa73..f01ed2a 100644 --- a/pages/jingxuan/selected-skills.vue +++ b/pages/jingxuan/selected-skills.vue @@ -466,7 +466,7 @@ export default { } .list-container { - padding: 30rpx 24rpx; + padding: 0 24rpx 30rpx; } .filter-panel { diff --git a/pages/jingxuan/skill-detail.vue b/pages/jingxuan/skill-detail.vue index 57b2e34..3b810f2 100644 --- a/pages/jingxuan/skill-detail.vue +++ b/pages/jingxuan/skill-detail.vue @@ -70,12 +70,9 @@ - + - - 暂无图文介绍 - diff --git a/pages/my/my.vue b/pages/my/my.vue index d3cceaf..a81af22 100644 --- a/pages/my/my.vue +++ b/pages/my/my.vue @@ -363,7 +363,7 @@ export default { title: "", id_type: 1, self_state: false, - url: "https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/30b42fe6-21f9-443f-a091-5439d57e3593.png", + url: "https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/545f2db0-d66a-41ca-b1f5-6a28469e65ba.png", path: "/pages/selfOperated/agreement?title=平台自营项目介绍&type=18", }, { @@ -781,55 +781,55 @@ export default { }); this.getInviteList(); }, - // 获取入驻详情 - fetchAuthDetails() { - return request.post("/sj/userSjAuth/details", { - type: 1, - id_type: '1' - }).then(res => { - if (res.code == 200 && res.data) { - this.authDetails = res.data; - } - return res; - }); - }, - async ensureAuthDetails() { - if (!this.isSettled || (this.authDetails && Object.keys(this.authDetails).length > 0)) { - return; - } - await this.fetchAuthDetails(); - }, - navigateToCertificationForm() { - if (this.isSettled) { - uni.navigateTo({ - url: '/pages/ruzhu/ruzhu?step=3' - }); - } else { - uni.navigateTo({ - url: '/pages/ruzhu/ruzhu' - }); - } - }, - async navigateToCertificationProcess() { - if (this.isCertified) { - uni.navigateTo({ - url: '/pages/shop/qualification_sj_change' - }); - return; - } - await this.ensureAuthDetails(); - if (!this.isSettled) { - uni.navigateTo({ - url: '/pages/ruzhu/ruzhu' - }); - } else if (this.isUnderReview) { - uni.navigateTo({ - url: '/pages/ruzhu/ruzhu?type=1' - }); - } else { - this.navigateToCertificationForm(); - } - }, + // 获取入驻详情 + fetchAuthDetails() { + return request.post("/sj/userSjAuth/details", { + type: 1, + id_type: '1' + }).then(res => { + if (res.code == 200 && res.data) { + this.authDetails = res.data; + } + return res; + }); + }, + async ensureAuthDetails() { + if (!this.isSettled || (this.authDetails && Object.keys(this.authDetails).length > 0)) { + return; + } + await this.fetchAuthDetails(); + }, + navigateToCertificationForm() { + if (this.isSettled) { + uni.navigateTo({ + url: '/pages/ruzhu/ruzhu?step=3' + }); + } else { + uni.navigateTo({ + url: '/pages/ruzhu/ruzhu' + }); + } + }, + async navigateToCertificationProcess() { + if (this.isCertified) { + uni.navigateTo({ + url: '/pages/shop/qualification_sj_change' + }); + return; + } + await this.ensureAuthDetails(); + if (!this.isSettled) { + uni.navigateTo({ + url: '/pages/ruzhu/ruzhu' + }); + } else if (this.isUnderReview) { + uni.navigateTo({ + url: '/pages/ruzhu/ruzhu?type=1' + }); + } else { + this.navigateToCertificationForm(); + } + }, async goLogin() { // 添加访问检查 if (this.isAccountDisabled) { @@ -879,17 +879,17 @@ export default { return; } - // 2. 未登录 → 提示 - if (!this.isLogin) { - if (item.path == "/pages/ruzhu/ruzhu") { - uni.navigateTo({ - url: "/pages/blogPopup/blogPopup", - }); - return; - } - uni.showToast({ - title: `您暂未登录,无法使用${item.title || item.text || ''}!`, - icon: "none", + // 2. 未登录 → 提示 + if (!this.isLogin) { + if (item.path == "/pages/ruzhu/ruzhu") { + uni.navigateTo({ + url: "/pages/blogPopup/blogPopup", + }); + return; + } + uni.showToast({ + title: `您暂未登录,无法使用${item.title || item.text || ''}!`, + icon: "none", }); return; } @@ -964,9 +964,9 @@ export default { url: "/pages/artisan/profile", }); }, - toruzhu() { - this.navigateToCertificationProcess(); - }, + toruzhu() { + this.navigateToCertificationProcess(); + }, closeSetupModal() { this.showSetupModal = false; }, @@ -982,10 +982,10 @@ export default { url: '/pages/shop/service-skills' }); }, - goToAuth() { - this.showSetupModal = false; - this.navigateToCertificationProcess(); - }, + goToAuth() { + this.showSetupModal = false; + this.navigateToCertificationProcess(); + }, goToInviteList() { // 添加访问检查 if (this.isAccountDisabled) { @@ -1703,7 +1703,7 @@ button::after { gap: 12rpx; margin-top: 10rpx; width: auto; - height: 46rpx; + height: 46rpx; padding: 0 8rpx 0 8rpx; background-image: url('https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/378a6936-a543-4ff5-9aa0-cfcb4d4e14b3.png'); background-size: 100% 100%; @@ -1889,4 +1889,4 @@ button::after { } } } - + diff --git a/pages/shop/business-time.vue b/pages/shop/business-time.vue index a70c4c2..a1563e1 100644 --- a/pages/shop/business-time.vue +++ b/pages/shop/business-time.vue @@ -240,6 +240,12 @@ export default { }, isCertified() { if (!this.isLogin || typeof this.userInfo.id_type === 'undefined') return false; + if (typeof this.userInfo.credentials_state !== 'undefined' && this.userInfo.credentials_state !== null) { + const credentialsState = Number(this.userInfo.credentials_state); + if (!Number.isNaN(credentialsState)) { + return credentialsState === 2 || (this.userInfo.id_type > 0 && credentialsState === 0); + } + } return this.userInfo.id_type > 0; }, hasBusinessTime() { @@ -351,13 +357,20 @@ export default { // 核心切换逻辑:营业中 / 休息中 toggleStatus() { - const currentStatus = this.userInfo.order_taking; - const isCurrentlyResting = currentStatus != 1; // 当前不是营业中即为休息中 + if (!this.isCertified) { + uni.showToast({ title: '请完成资质认证', icon: 'none' }); + return; + } - // 准备切换的新状态 - let newStatus = currentStatus == 1 ? 2 : 1; + // 未入驻状态不允许切换接单状态 + if (!this.isSettled) { + uni.showToast({ title: '请先完成入驻', icon: 'none' }); + return; + } + + // 以页面展示状态为准,避免资料未完成时后端仍为接单中导致首次点击变成停止接单 + let newStatus = this.isOpenStore ? 2 : 1; - // 想要开始接单时,检查资料是否完善 if (newStatus === 1 && !this.canOpenStore) { uni.showToast({ title: '当前资料不完善,无法开启接单', icon: 'none' }); return; diff --git a/utils/request.js b/utils/request.js index cfa905c..1db7033 100644 --- a/utils/request.js +++ b/utils/request.js @@ -1,78 +1,66 @@ -import { - getToken, - setToken, - removeToken -} from './auth' -import { - setVersion -} from '../utils/version.js' -import { - getBaseUrl -} from '../utils/version.js' +import { getToken, setToken, removeToken } from "./auth"; +import { setVersion } from "../utils/version.js"; +import { getBaseUrl } from "../utils/version.js"; let baseURL; -setVersion() +setVersion(); -let isRefreshing = false -let subscribers = [] +let isRefreshing = false; +let subscribers = []; // 订阅 Token 刷新 function subscribeTokenRefresh(cb) { - subscribers.push(cb) + subscribers.push(cb); } // 发布 Token 刷新完成 function onRrefreshed(token) { - subscribers.forEach(cb => cb(token)) - subscribers = [] + subscribers.forEach((cb) => cb(token)); + subscribers = []; } // 请求拦截器 const requestInterceptor = (options) => { - // 获取token - const token = uni.getStorageSync('accessToken') - if (token) { - options.header = { - ...options.header, - 'Authorization': `Bearer ${token}` - } - } + // 获取token + const token = uni.getStorageSync("accessToken"); + if (token) { + options.header = { + ...options.header, + Authorization: `Bearer ${token}`, + }; + } - // #ifdef H5 - // H5端跨域处理 - options.header = { - ...options.header, - 'Access-Control-Allow-Origin': '*' - } - // #endif + // #ifdef H5 + // H5端跨域处理 + options.header = { + ...options.header, + "Access-Control-Allow-Origin": "*", + }; + // #endif - return options -} + return options; +}; -// 响应拦截器 +// 响应拦截器 const responseInterceptor = async (options, response, resolve, reject) => { - const { - statusCode, - data - } = response - // 请求成功 - if (statusCode >= 200 && statusCode < 300) { - return data - } + const { statusCode, data } = response; + // 请求成功 + if (statusCode >= 200 && statusCode < 300) { + return data; + } - // 处理错误 - if (statusCode === 401) { + // 处理错误 + if (statusCode === 401) { + return await handleUnauthorized(options, resolve, reject); + } - return await handleUnauthorized(options, resolve, reject) - } - - // 其他错误 - uni.showToast({ - title: data.message || '请求失败', - icon: 'none' - }) - return Promise.reject(data) -} + // 其他错误 + uni.showToast({ + title: data.message || "请求失败", + icon: "none", + }); + return Promise.reject(data); +}; // 创建 uni.request 的封装 // const request = (options) => { // return new Promise((resolve, reject) => { @@ -95,258 +83,256 @@ const responseInterceptor = async (options, response, resolve, reject) => { // 请求方法 const request = async (options, isUpdate) => { - // 合并配置 - let url = uni.getStorageSync('baseUrl') - if (uni.getStorageSync('setVersion').VersionCode == '') { - setVersion() - } + // 合并配置 + let url = uni.getStorageSync("baseUrl"); + if (uni.getStorageSync("setVersion").VersionCode == "") { + setVersion(); + } - if (!url) { - await new Promise((resolve, reject) => { - uni.request({ - url: 'https://api.mrrwlkj.top/api/openPuc/getSjApiUrl', // 接口地址 - method: 'GET', // 请求方法(默认 GET) - header: { - 'Content-Type': 'application/json', // 请求头 - 'VersionCode': uni.getStorageSync('setVersion').VersionCode, - 'DeviceBrand': uni.getStorageSync('setVersion').DeviceBrand, - 'DeviceType': uni.getStorageSync('setVersion').DeviceType - }, - success: (res) => { - if (res.data.code == 200) { - uni.setStorageSync('baseUrl', res.data.data.url) - url = res.data.data.url - resolve(url) - } - console.log('请求成功', res.data); - }, - fail: (err) => { - console.log('请求失败', err); - }, - complete: () => { - console.log('请求完成(无论成功失败都会执行)'); - } - }); - }) + if (!url) { + await new Promise((resolve, reject) => { + uni.request({ + url: "https://api.mrrwlkj.top/api/openPuc/getSjApiUrl", // 接口地址 + method: "GET", // 请求方法(默认 GET) + header: { + "Content-Type": "application/json", // 请求头 + VersionCode: uni.getStorageSync("setVersion").VersionCode, + DeviceBrand: uni.getStorageSync("setVersion").DeviceBrand, + DeviceType: uni.getStorageSync("setVersion").DeviceType, + }, + success: (res) => { + if (res.data.code == 200) { + uni.setStorageSync("baseUrl", res.data.data.url); + url = res.data.data.url; + resolve(url); + } + console.log("请求成功", res.data); + }, + fail: (err) => { + console.log("请求失败", err); + }, + complete: () => { + console.log("请求完成(无论成功失败都会执行)"); + }, + }); + }); + } - } + if (process.env.NODE_ENV === "development") { + baseURL = url; // 发布到生产环境时,此处代码会被摇树移除掉。 + baseURL = "http://test.mrrwlkj.top"; // 发布到生产环境时,此处代码会被摇树移除掉。 + //baseURL = 'http://dev.mrrwlkj.top'; // 发布到生产环境时,此处代码会被摇树移除掉。 + // baseURL = "https://app.mrrweb.com.cn"; + } else { + baseURL = url; // 发布到生产环境时,此处代码会被摇树移除掉。 + baseURL = "http://test.mrrwlkj.top"; // 发布到生产环境时,此处代码会被摇树移除掉。 + //baseURL = 'http://dev.mrrwlkj.top'; // 发布到生产环境时,此处代码会被摇树移除掉。 + // baseURL = "https://app.mrrweb.com.cn"; + console.log("生产环境"); + } + // 基础配置 + const config = { + baseURL: baseURL, // APP和H5的开发URL + baseURL: baseURL, // APP和H5的开发URL + // baseURL: 'https://app.mrrweb.com.cn', // APP和H5的生产URL - if (process.env.NODE_ENV === 'development') { - baseURL = url; // 发布到生产环境时,此处代码会被摇树移除掉。 - baseURL = 'http://test.mrrwlkj.top'; // 发布到生产环境时,此处代码会被摇树移除掉。 - //baseURL = 'http://dev.mrrwlkj.top'; // 发布到生产环境时,此处代码会被摇树移除掉。 - //baseURL = 'https://app.mrrweb.com.cn'; - } else { - baseURL = url; // 发布到生产环境时,此处代码会被摇树移除掉。 - baseURL = 'http://test.mrrwlkj.top'; // 发布到生产环境时,此处代码会被摇树移除掉。 - //baseURL = 'http://dev.mrrwlkj.top'; // 发布到生产环境时,此处代码会被摇树移除掉。 - //baseURL = 'https://app.mrrweb.com.cn'; + header: { + "content-type": "application/json", + VersionCode: uni.getStorageSync("setVersion").VersionCode, + DeviceBrand: uni.getStorageSync("setVersion").DeviceBrand, + DeviceType: uni.getStorageSync("setVersion").DeviceType, + }, + timeout: 60000, // 超时时间 + }; - console.log('生产环境'); - } + options = { + ...config, + ...options, + url: !isUpdate ? `${config.baseURL}${options.url}` : options.url, + }; - // 基础配置 - const config = { - baseURL: baseURL, // APP和H5的开发URL - baseURL: baseURL, // APP和H5的开发URL - // baseURL: 'https://app.mrrweb.com.cn', // APP和H5的生产URL + // 请求拦截 + options = requestInterceptor(options); - header: { - 'content-type': 'application/json', - 'VersionCode': uni.getStorageSync('setVersion').VersionCode, - 'DeviceBrand': uni.getStorageSync('setVersion').DeviceBrand, - 'DeviceType': uni.getStorageSync('setVersion').DeviceType - }, - timeout: 60000 // 超时时间 - } + // 发起请求 + return new Promise((resolve, reject) => { + // #ifdef H5 + // H5端添加loading + if (!options.hideLoading) { + uni.showLoading({ + title: "加载中...", + }); + } + // #endif + uni.request({ + ...options, + success: (res) => { + // #ifdef H5 + if (!options.hideLoading) { + uni.hideLoading(); + } + // #endif + try { + const result = responseInterceptor(options, res, resolve, reject); + if (result && typeof result.then === "function") { + result.then((data) => resolve(data)).catch((err) => reject(err)); + } else { + resolve(result); + } + } catch (err) { + reject(err); + } + }, + fail: (err) => { + // #ifdef H5 + if (!options.hideLoading) { + uni.hideLoading(); + } + // #endif - options = { - ...config, - ...options, - url: !isUpdate ? `${config.baseURL}${options.url}` : options.url - } + // 网络错误处理 + let errorMsg = "网络错误,请稍后重试"; + // #ifdef H5 + if (err.errMsg.includes("timeout")) { + errorMsg = "请求超时,请检查网络"; + } + // #endif - - // 请求拦截 - options = requestInterceptor(options) - - // 发起请求 - return new Promise((resolve, reject) => { - // #ifdef H5 - // H5端添加loading - if (!options.hideLoading) { - uni.showLoading({ - title: '加载中...' - }) - } - // #endif - - uni.request({ - ...options, - success: (res) => { - // #ifdef H5 - if (!options.hideLoading) { - uni.hideLoading() - } - // #endif - try { - const result = responseInterceptor(options, res, resolve, reject) - if (result && typeof result.then === 'function') { - result.then(data => resolve(data)).catch(err => reject(err)) - } else { - resolve(result) - } - } catch (err) { - reject(err) - } - }, - fail: (err) => { - // #ifdef H5 - if (!options.hideLoading) { - uni.hideLoading() - } - // #endif - - // 网络错误处理 - let errorMsg = '网络错误,请稍后重试' - // #ifdef H5 - if (err.errMsg.includes('timeout')) { - errorMsg = '请求超时,请检查网络' - } - // #endif - - uni.showToast({ - title: errorMsg, - icon: 'none' - }) - reject(err) - } - }) - }) -} + uni.showToast({ + title: errorMsg, + icon: "none", + }); + reject(err); + }, + }); + }); +}; // 处理 401 未授权 async function handleUnauthorized(originalRequest, resolve, reject) { - if (!getToken()) { - reject(new Error('未登录')) - return redirectToLogin() - } - // 如果正在刷新 Token,将请求加入队列 - if (isRefreshing) { - return subscribeTokenRefresh(token => { - originalRequest.header['Authorization'] = `Bearer ${token}` - request(originalRequest, true).then(resolve).catch(reject) - }) - } + if (!getToken()) { + reject(new Error("未登录")); + return redirectToLogin(); + } + // 如果正在刷新 Token,将请求加入队列 + if (isRefreshing) { + return subscribeTokenRefresh((token) => { + originalRequest.header["Authorization"] = `Bearer ${token}`; + request(originalRequest, true).then(resolve).catch(reject); + }); + } - isRefreshing = true + isRefreshing = true; - try { - const newToken = await refreshToken() - setToken(newToken) - onRrefreshed(newToken) + try { + const newToken = await refreshToken(); + setToken(newToken); + onRrefreshed(newToken); - // 用新 Token 重试原始请求 - originalRequest.header['Authorization'] = `Bearer ${newToken}` - const response = await request(originalRequest, true) - // resolve(response) - return response - } catch (error) { - removeToken() - redirectToLogin() - reject(error) - return error - } finally { - isRefreshing = false - } + // 用新 Token 重试原始请求 + originalRequest.header["Authorization"] = `Bearer ${newToken}`; + const response = await request(originalRequest, true); + // resolve(response) + return response; + } catch (error) { + removeToken(); + redirectToLogin(); + reject(error); + return error; + } finally { + isRefreshing = false; + } } // 刷新 Token async function refreshToken() { - const refreshToken = uni.getStorageSync('refreshToken') - if (!refreshToken) { - throw new Error('No refresh token') - } - const res = await request({ - url: '/sj/refreshtoken', - data: { - refresh_token: uni.getStorageSync('refreshToken'), - deviceid: getApp().globalData.deviceid - }, - method: 'POST' - }) + const refreshToken = uni.getStorageSync("refreshToken"); + if (!refreshToken) { + throw new Error("No refresh token"); + } + const res = await request({ + url: "/sj/refreshtoken", + data: { + refresh_token: uni.getStorageSync("refreshToken"), + deviceid: getApp().globalData.deviceid, + }, + method: "POST", + }); - if (res.state == 1 || res.code == 200) { - const tokenData = res.data || res - if (!tokenData.access_token) { - throw new Error('Refresh token response missing access_token') - } - uni.setStorageSync('accessToken', tokenData.access_token) - if (tokenData.refresh_token) { - uni.setStorageSync('refreshToken', tokenData.refresh_token) - } - if (tokenData.refresh_token_expries) { - uni.setStorageSync('refresh_token_expries', tokenData.refresh_token_expries) - } - return tokenData.access_token - } + if (res.state == 1 || res.code == 200) { + const tokenData = res.data || res; + if (!tokenData.access_token) { + throw new Error("Refresh token response missing access_token"); + } + uni.setStorageSync("accessToken", tokenData.access_token); + if (tokenData.refresh_token) { + uni.setStorageSync("refreshToken", tokenData.refresh_token); + } + if (tokenData.refresh_token_expries) { + uni.setStorageSync( + "refresh_token_expries", + tokenData.refresh_token_expries, + ); + } + return tokenData.access_token; + } - throw new Error('Refresh token failed') + throw new Error("Refresh token failed"); } // 跳转到登录页 function redirectToLogin() { - // uni.reLaunch({ - // url: '/pages/login/login' - // }) - //一键登录测试 - // uni.oprPresentLogin() - uni.navigateTo({ - url: '/pages/blogPopup/blogPopup' - }); + // uni.reLaunch({ + // url: '/pages/login/login' + // }) + //一键登录测试 + // uni.oprPresentLogin() + uni.navigateTo({ + url: "/pages/blogPopup/blogPopup", + }); } // 导出请求方法 export default { - // GET请求 - get(url, data = {}, options = {}) { - return request({ - url, - data, - method: 'GET', - ...options - }) - }, + // GET请求 + get(url, data = {}, options = {}) { + return request({ + url, + data, + method: "GET", + ...options, + }); + }, - // POST请求 - post(url, data = {}, options = {}) { - return request({ - url, - data, - method: 'POST', - ...options - }) - }, + // POST请求 + post(url, data = {}, options = {}) { + return request({ + url, + data, + method: "POST", + ...options, + }); + }, - // PUT请求 - put(url, data = {}, options = {}) { - return request({ - url, - data, - method: 'PUT', - ...options - }) - }, + // PUT请求 + put(url, data = {}, options = {}) { + return request({ + url, + data, + method: "PUT", + ...options, + }); + }, - // DELETE请求 - delete(url, data = {}, options = {}) { - return request({ - url, - data, - method: 'DELETE', - ...options - }) - } -} + // DELETE请求 + delete(url, data = {}, options = {}) { + return request({ + url, + data, + method: "DELETE", + ...options, + }); + }, +};