feat: 首页改版

This commit is contained in:
2026-08-25 17:52:05 +08:00
parent d65083aa51
commit d5253e3202
15 changed files with 1014 additions and 644 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
{ {
"customPlaygroundType" : "local", "customPlaygroundType" : "local",
"packageName" : "com.trustbridge.mm", "packageName" : "com.trustbridge.mm",
"playground" : "standard", "playground" : "custom",
"type" : "uni-app:app-android" "type" : "uni-app:app-android"
}, },
{ {
+2 -2
View File
@@ -655,7 +655,7 @@
.sort_comm_warp { .sort_comm_warp {
background: #ffffff; background: #ffffff;
padding: 20rpx; padding: 20rpx;
height: 170rpx; // height: 170rpx;
border-radius: 20rpx; border-radius: 20rpx;
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
@@ -666,7 +666,7 @@
.sort_item_comm { .sort_item_comm {
flex: 1; flex: 1;
text-align: center; text-align: center;
margin-bottom: 20rpx; // margin-bottom: 20rpx;
} }
.sort_item_title_comm { .sort_item_title_comm {
@@ -162,11 +162,6 @@ export default {
// #endif // #endif
}, },
beforeUnmount() { beforeUnmount() {
if (this.panelVisible) {
try {
uni.showTabBar({ animation: false });
} catch (e) {}
}
uni.$off("qiaobao-visibility-change", this.handleVisibilityChange); uni.$off("qiaobao-visibility-change", this.handleVisibilityChange);
// #ifdef H5 // #ifdef H5
window.removeEventListener("mousemove", this.handleMouseDragMove); window.removeEventListener("mousemove", this.handleMouseDragMove);
@@ -382,17 +377,11 @@ export default {
this.showBubble = false; this.showBubble = false;
this.panelVisible = true; this.panelVisible = true;
this.action = "blink"; this.action = "blink";
try {
uni.hideTabBar({ animation: false });
} catch (e) {}
this.$emit("open", this.currentPageKey); this.$emit("open", this.currentPageKey);
}, },
closeHelp() { closeHelp() {
this.panelVisible = false; this.panelVisible = false;
this.action = "idle"; this.action = "idle";
try {
uni.showTabBar({ animation: false });
} catch (e) {}
this.$emit("close", this.currentPageKey); this.$emit("close", this.currentPageKey);
}, },
openHideMenu() { openHideMenu() {
@@ -417,11 +406,6 @@ export default {
collapseToEdge(edge = getQiaobaoDockEdge()) { collapseToEdge(edge = getQiaobaoDockEdge()) {
this.collapsedEdge = edge === "left" ? "left" : "right"; this.collapsedEdge = edge === "left" ? "left" : "right";
this.collapsed = true; this.collapsed = true;
if (this.panelVisible) {
try {
uni.showTabBar({ animation: false });
} catch (e) {}
}
this.panelVisible = false; this.panelVisible = false;
this.showBubble = false; this.showBubble = false;
this.action = "idle"; this.action = "idle";
+149 -145
View File
@@ -1,39 +1,41 @@
{ {
"name": "信任桥", "name" : "信任桥",
"appid": "__UNI__4910728", "appid" : "__UNI__4910728",
"description": "信任桥优品是一款集线上商城、线下联盟商家的DAO聚合商城;通过“有趣”“有利”“有希望”的卖货玩法,吸引消费者、推广者、商家、投资人参与生态,共同打造共创共享的全球产业生态。", "description" : "信任桥优品是一款集线上商城、线下联盟商家的DAO聚合商城;通过“有趣”“有利”“有希望”的卖货玩法,吸引消费者、推广者、商家、投资人参与生态,共同打造共创共享的全球产业生态。",
"versionName": "1.0.3", "versionName" : "1.0.3",
"versionCode": 170, "versionCode" : 170,
"transformPx": false, "transformPx" : false,
/* 5+App特有相关 */ /* 5+App特有相关 */
"app-plus": { "app-plus" : {
"name": "哈希优品", "name" : "哈希优品",
"usingComponents": true, "usingComponents" : true,
"nvueStyleCompiler": "uni-app", "nvueStyleCompiler" : "uni-app",
"compilerVersion": 3, "compilerVersion" : 3,
"ios": { "ios" : {
"deploymentTarget": "13.0" "deploymentTarget" : "13.0"
}, },
"splashscreen": { "splashscreen" : {
"alwaysShowBeforeRender": true, "alwaysShowBeforeRender" : true,
"waiting": true, "waiting" : true,
"delay": 0, "delay" : 0,
"duration": 0, "duration" : 0,
"autoclose": false "autoclose" : false
}, },
/* 模块配置 */ /* 模块配置 */
"modules": { "modules" : {
"Payment": {}, "Payment" : {},
"Camera": {}, "Camera" : {},
"OAuth": {}, "OAuth" : {},
"Share": {} "Share" : {},
"Audio" : {},
"Record" : {}
}, },
/* 应用发布信息 */ /* 应用发布信息 */
"distribute": { "distribute" : {
/* android打包配置 */ /* android打包配置 */
"android": { "android" : {
"schemes": ["trustbridgeapp"], "schemes" : [ "trustbridgeapp" ],
"permissions": [ "permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>", "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>", "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>", "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
@@ -49,161 +51,163 @@
"<uses-feature android:name=\"android.hardware.camera\"/>", "<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>" "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
], ],
"abiFilters": ["armeabi-v7a", "arm64-v8a"], "abiFilters" : [ "armeabi-v7a", "arm64-v8a" ],
"targetSdkVersion": 30, "targetSdkVersion" : 30,
"minSdkVersion": 21 "minSdkVersion" : 21
}, },
/* ios打包配置 */ /* ios打包配置 */
"ios": { "ios" : {
"dSYMs": false, "dSYMs" : false,
"idfa": false, "idfa" : false,
"urltypes": [{ "urltypes" : [
"urlidentifier": "com.trustbridgeapp.mm", {
"urlschemes": ["trustbridgeapp"] "urlidentifier" : "com.trustbridgeapp.mm",
}], "urlschemes" : [ "trustbridgeapp" ]
"associatedDomains": ["applinks:ulink.trustbridgeapp.com"], }
"capabilities": { ],
"entitlements": { "associatedDomains" : [ "applinks:ulink.trustbridgeapp.com" ],
"com.apple.developer.associated-domains": ["applinks:app.tbmall.xin"] "capabilities" : {
"entitlements" : {
"com.apple.developer.associated-domains" : [ "applinks:app.tbmall.xin" ]
} }
}, },
"privacyDescription": { "privacyDescription" : {
"NSPhotoLibraryUsageDescription": "App需要您的同意才能访问相册,以便您选择本地图片上传头像或发布商品评价。例如:当您修改个人头像或发布带图评价时,需要从相册选择图片。", "NSPhotoLibraryUsageDescription" : "App需要您的同意才能访问相册,以便您选择本地图片上传头像或发布商品评价。例如:当您修改个人头像或发布带图评价时,需要从相册选择图片。",
"NSPhotoLibraryAddUsageDescription": "App需要您的同意才能添加图片到相册,以便您保存商品海报或图片到本地。例如:当您点击保存商品分享海报时,需要写入相册权限。", "NSPhotoLibraryAddUsageDescription" : "App需要您的同意才能添加图片到相册,以便您保存商品海报或图片到本地。例如:当您点击保存商品分享海报时,需要写入相册权限。",
"NSCameraUsageDescription": "App需要您的同意才能访问相机,以便您拍摄图片上传头像或发布商品评价。例如:当您修改个人头像或发布带图评价时,需要使用相机拍摄照片。" "NSCameraUsageDescription" : "App需要您的同意才能访问相机,以便您拍摄图片上传头像或发布商品评价。例如:当您修改个人头像或发布带图评价时,需要使用相机拍摄照片。"
} }
}, },
/* SDK配置 */ /* SDK配置 */
"sdkConfigs": { "sdkConfigs" : {
"payment": { "payment" : {
"alipay": { "alipay" : {
"__platform__": ["ios", "android"] "__platform__" : [ "ios", "android" ]
}, },
"weixin": { "weixin" : {
"__platform__": ["ios", "android"], "__platform__" : [ "ios", "android" ],
"appid": "wx7a5902cd556d9396", "appid" : "wx7a5902cd556d9396",
"UniversalLinks": "https://app.tbmall.xin/uni-universallinks/__UNI__4910728/" "UniversalLinks" : "https://app.tbmall.xin/uni-universallinks/__UNI__4910728/"
} }
}, },
"oauth": { "oauth" : {
"weixin": { "weixin" : {
"appid": "wx7a5902cd556d9396", "appid" : "wx7a5902cd556d9396",
"UniversalLinks": "https://app.tbmall.xin/uni-universallinks/__UNI__4910728/" "UniversalLinks" : "https://app.tbmall.xin/uni-universallinks/__UNI__4910728/"
}, },
"apple": {} "apple" : {}
}, },
"share": { "share" : {
"weixin": { "weixin" : {
"appid": "wx7a5902cd556d9396", "appid" : "wx7a5902cd556d9396",
"UniversalLinks": "https://app.tbmall.xin/uni-universallinks/__UNI__4910728/" "UniversalLinks" : "https://app.tbmall.xin/uni-universallinks/__UNI__4910728/"
} }
} }
}, },
"icons": { "icons" : {
"android": { "android" : {
"hdpi": "unpackage/res/icons/72x72.png", "hdpi" : "unpackage/res/icons/72x72.png",
"xhdpi": "unpackage/res/icons/96x96.png", "xhdpi" : "unpackage/res/icons/96x96.png",
"xxhdpi": "unpackage/res/icons/144x144.png", "xxhdpi" : "unpackage/res/icons/144x144.png",
"xxxhdpi": "unpackage/res/icons/192x192.png" "xxxhdpi" : "unpackage/res/icons/192x192.png"
}, },
"ios": { "ios" : {
"appstore": "unpackage/res/icons/1024x1024.png", "appstore" : "unpackage/res/icons/1024x1024.png",
"ipad": { "ipad" : {
"app": "unpackage/res/icons/76x76.png", "app" : "unpackage/res/icons/76x76.png",
"app@2x": "unpackage/res/icons/152x152.png", "app@2x" : "unpackage/res/icons/152x152.png",
"notification": "unpackage/res/icons/20x20.png", "notification" : "unpackage/res/icons/20x20.png",
"notification@2x": "unpackage/res/icons/40x40.png", "notification@2x" : "unpackage/res/icons/40x40.png",
"proapp@2x": "unpackage/res/icons/167x167.png", "proapp@2x" : "unpackage/res/icons/167x167.png",
"settings": "unpackage/res/icons/29x29.png", "settings" : "unpackage/res/icons/29x29.png",
"settings@2x": "unpackage/res/icons/58x58.png", "settings@2x" : "unpackage/res/icons/58x58.png",
"spotlight": "unpackage/res/icons/40x40.png", "spotlight" : "unpackage/res/icons/40x40.png",
"spotlight@2x": "unpackage/res/icons/80x80.png" "spotlight@2x" : "unpackage/res/icons/80x80.png"
}, },
"iphone": { "iphone" : {
"app@2x": "unpackage/res/icons/120x120.png", "app@2x" : "unpackage/res/icons/120x120.png",
"app@3x": "unpackage/res/icons/180x180.png", "app@3x" : "unpackage/res/icons/180x180.png",
"notification@2x": "unpackage/res/icons/40x40.png", "notification@2x" : "unpackage/res/icons/40x40.png",
"notification@3x": "unpackage/res/icons/60x60.png", "notification@3x" : "unpackage/res/icons/60x60.png",
"settings@2x": "unpackage/res/icons/58x58.png", "settings@2x" : "unpackage/res/icons/58x58.png",
"settings@3x": "unpackage/res/icons/87x87.png", "settings@3x" : "unpackage/res/icons/87x87.png",
"spotlight@2x": "unpackage/res/icons/80x80.png", "spotlight@2x" : "unpackage/res/icons/80x80.png",
"spotlight@3x": "unpackage/res/icons/120x120.png" "spotlight@3x" : "unpackage/res/icons/120x120.png"
} }
} }
}, },
"splashscreen": { "splashscreen" : {
"useOriginalMsgbox": true, "useOriginalMsgbox" : true,
"iosStyle": "common", "iosStyle" : "common",
"androidStyle": "common" "androidStyle" : "common"
} }
}, },
/*忽略版本提示*/ /*忽略版本提示*/
"compatible": { "compatible" : {
"ignoreVersion": true "ignoreVersion" : true
}, },
"nativePlugins": { "nativePlugins" : {
"Hyy-Alipay": { "Hyy-Alipay" : {
"__plugin_info__": { "__plugin_info__" : {
"name": "【免费开源】支付宝,授权,授权登录", "name" : "【免费开源】支付宝,授权,授权登录",
"description": "用过支付宝原生sdk,原生授权登录,更安全,有问题请联系作者", "description" : "用过支付宝原生sdk,原生授权登录,更安全,有问题请联系作者",
"platforms": "Android", "platforms" : "Android",
"url": "https://ext.dcloud.net.cn/plugin?id=11931", "url" : "https://ext.dcloud.net.cn/plugin?id=11931",
"android_package_name": "", "android_package_name" : "",
"ios_bundle_id": "", "ios_bundle_id" : "",
"isCloud": true, "isCloud" : true,
"bought": 1, "bought" : 1,
"pid": "11931", "pid" : "11931",
"parameters": {} "parameters" : {}
} }
} }
} }
}, },
/* 快应用特有相关 */ /* 快应用特有相关 */
"quickapp": {}, "quickapp" : {},
/* 小程序特有相关 */ /* 小程序特有相关 */
"mp-weixin": { "mp-weixin" : {
"appid": "wx376a16a88befe265", "appid" : "wx376a16a88befe265",
"lazyCodeLoading": "requiredComponents", "lazyCodeLoading" : "requiredComponents",
"setting": { "setting" : {
"urlCheck": false, "urlCheck" : false,
"minified": true, "minified" : true,
"uglifyFileName": true, "uglifyFileName" : true,
"es6": true, "es6" : true,
"postcss": true, "postcss" : true,
"sourcemap": false "sourcemap" : false
}, },
"usingComponents": true, "usingComponents" : true,
"optimization": { "optimization" : {
"subPackages": true "subPackages" : true
} }
}, },
"mp-alipay": { "mp-alipay" : {
"usingComponents": true "usingComponents" : true
}, },
"mp-baidu": { "mp-baidu" : {
"usingComponents": true "usingComponents" : true
}, },
"mp-toutiao": { "mp-toutiao" : {
"usingComponents": true "usingComponents" : true
}, },
"uniStatistics": { "uniStatistics" : {
"enable": false "enable" : false
}, },
"vueVersion": "3", "vueVersion" : "3",
"_spaceID": "mp-16f2830d-655c-4ed2-9763-d0258ba65ad9", "_spaceID" : "mp-16f2830d-655c-4ed2-9763-d0258ba65ad9",
"h5": { "h5" : {
"router": { "router" : {
"mode": "hash", "mode" : "hash",
"base": "" "base" : ""
}, },
"devServer": { "devServer" : {
"port": 5173, "port" : 5173,
"proxy": { "proxy" : {
"/proxy-api": { "/proxy-api" : {
"target": "https://api.o.tbmall.xin", "target" : "https://api.o.tbmall.xin",
"changeOrigin": true, "changeOrigin" : true,
"pathRewrite": { "pathRewrite" : {
"^/proxy-api": "" "^/proxy-api" : ""
} }
} }
} }
+224 -79
View File
@@ -1,11 +1,9 @@
<template> <template>
<view class="home_warp" :class="platformType ? '' : 'iosplatformType'"> <view class="home_warp" :class="platformType ? '' : 'iosplatformType'" @scroll="onScroll">
<!-- 带背景的头部 --> <!-- 变色搜索栏 -->
<view class="home_content_z_warp"> <view class="header_title_warp" :class="{ 'is-scrolled': isScrolled }" :style="mpHeaderStyle">
<view class="home_header_warp" :style="mpHeaderWarpStyle"> <view class="language_warp" style="flex: 1; justify-content: flex-start;" @click.stop="jumpSearch">
<view class="header_title_warp" :style="mpHeaderStyle"> <view :style="isMP ? 'display: flex; align-items: center;margin-top: 0;' : 'margin-top: 0;'">
<view class="language_warp" style="flex: 1; justify-content: flex-start;" @click="jumpSearch">
<view :style="isMP ? 'display: flex; align-items: center;margin-top: 10rpx;' : 'margin-top: 10rpx;'">
<up-image src="https://static.tbmall.xin/static/home/search_b.png" width="20" height="20" <up-image src="https://static.tbmall.xin/static/home/search_b.png" width="20" height="20"
bgColor="#f1f6ff00"></up-image> bgColor="#f1f6ff00"></up-image>
</view> </view>
@@ -16,22 +14,33 @@
<text v-if="kefuUnreadCount > 0" class="message-entry-badge">{{ formatKefuBadge(kefuUnreadCount) }}</text> <text v-if="kefuUnreadCount > 0" class="message-entry-badge">{{ formatKefuBadge(kefuUnreadCount) }}</text>
</view> </view>
</view> </view>
<view class="logo_banner">
<view style="padding: 20rpx 0 0 20rpx"> <!-- 页面内容容器 -->
<up-image src="https://static.tbmall.xin/static/home/logo_banner.png" width="108" height="16" <view class="home_content_z_warp">
bgColor="#f1f6ff00"></up-image> <!-- 轮播 Banner 区域 (整个紫色区域包含文案背景均为 Banner 图,延伸至头部安全区) -->
<view class="logo_banner_title">TB聚合商城</view> <view class="home_header_warp">
<view class="logo_banner_msg">全民共创共享的电商平台</view> <view class="banner_swiper_container" v-if="swiperList && swiperList.length > 0">
<up-swiper :list="swiperList" height="480rpx" radius="0" @change="e => currentNum = e.current"
bgColor="#ffffff00" @click="onSwiper">
<template #indicator>
<view class="indicator-dots" v-if="swiperList.length > 1">
<view v-for="(item, index) in swiperList.length" :key="index" class="indicator-dot"
:class="{ active: currentNum === index }"></view>
</view>
</template>
</up-swiper>
</view>
<view v-else class="banner_placeholder">
<up-swiper :list="['https://static.tbmall.xin/static/logo_banner2.png']" height="230" radius="0"
bgColor="#ffffff00"></up-swiper>
</view> </view>
<up-image src="https://static.tbmall.xin/static/logo_banner2.png" width="140" height="98"
bgColor="#f1f6ff00"></up-image>
</view> </view>
<!-- 分类 --> <!-- 分类(覆盖在Banner上) -->
<view class="home_sort_warp"> <view class="home_sort_warp">
<view class="sort_comm_warp" v-if="sortList && sortList.length !== 0 && isBlockedDate"> <view class="sort_comm_warp" v-if="sortList && sortList.length !== 0 && isBlockedDate">
<view v-for="item in sortList" :key="item.id" class="sort_item_comm" @click="jumpSort(item)"> <view v-for="item in sortList" :key="item.id" class="sort_item_comm" @click.stop="jumpSort(item)">
<up-image :src="item.icon" width="50" height="36" bgColor="#f1f6ff00"></up-image> <up-image :src="item.icon" width="100rpx" height="72rpx" bgColor="#f1f6ff00"></up-image>
<view class="sort_item_title_comm">{{ item.name }}</view> <view class="sort_item_title_comm">{{ item.name }}</view>
</view> </view>
</view> </view>
@@ -77,7 +86,6 @@
</view> </view>
</view> </view>
</view> </view>
</view>
<!-- 带灰色背景的内容 --> <!-- 带灰色背景的内容 -->
<view class="home_content_warp Hot_Picks_content"> <view class="home_content_warp Hot_Picks_content">
@@ -226,8 +234,8 @@ import {
getSeckillGoodsList, getSeckillGoodsList,
getGoodsTags, getGoodsTags,
} from "@/api/product.js"; } from "@/api/product.js";
import { checkAppVersion } from "@/api/common.js"; import { checkAppVersion, getCarouselImage } from "@/api/common.js";
import { SEARCH_TYPE, SORT_TYPE } from "@/utils/enumUtils.js"; import { SEARCH_TYPE, SORT_TYPE, APP_PAGE_TYPE } from "@/utils/enumUtils.js";
import CustomTabBar from "@/components/custom-tab-bar.vue"; // 引入自定义组件路径可能需要根据项目结构调整 import CustomTabBar from "@/components/custom-tab-bar.vue"; // 引入自定义组件路径可能需要根据项目结构调整
import dayjs from "dayjs"; import dayjs from "dayjs";
import useTabber from "tabber-component"; import useTabber from "tabber-component";
@@ -252,6 +260,7 @@ export default {
}, },
data() { data() {
return { return {
swiperList: [],
currentNum: 0, currentNum: 0,
sortList: [], sortList: [],
faddishProduct: [], // 爆款专区 faddishProduct: [], // 爆款专区
@@ -297,8 +306,15 @@ export default {
mpLanguageStyle: {}, mpLanguageStyle: {},
kefuUnreadCount: 0, kefuUnreadCount: 0,
kefuUnreadRefreshTimer: null, kefuUnreadRefreshTimer: null,
isScrolled: false,
scrollTop: 0,
}; };
}, },
onPageScroll(e) {
const top = e ? (e.scrollTop || 0) : 0;
this.scrollTop = top;
this.isScrolled = top > 10;
},
onShow() { onShow() {
this.refreshKefuUnread(); this.refreshKefuUnread();
startKefuRealtime(); startKefuRealtime();
@@ -324,6 +340,8 @@ export default {
this.getSortList(); this.getSortList();
this.querySearchList(SEARCH_TYPE.EXPLOSIVE); // 爆单专区 this.querySearchList(SEARCH_TYPE.EXPLOSIVE); // 爆单专区
this.onNews(); // 获取公告 this.onNews(); // 获取公告
this.getCarouselImage();
// 秒杀 // 秒杀
this.onGetSeckillCurrent(); this.onGetSeckillCurrent();
@@ -363,6 +381,34 @@ export default {
}, },
mounted() { }, mounted() { },
methods: { methods: {
onScroll(e) {
const top = e.detail ? e.detail.scrollTop : (e.target ? e.target.scrollTop : 0);
this.scrollTop = top;
this.isScrolled = top > 10;
},
// 查询轮播图
async getCarouselImage() {
const params = {
pageUi: APP_PAGE_TYPE.HOME,
};
const resp = await getCarouselImage(params);
if (resp && resp.bizcode === 100) {
const data = resp.data || [];
this.swiperDataList = data;
this.swiperList =
data.length !== 0 ? data.map((obj) => obj.carouselImage) : [];
}
},
onSwiper(index) {
console.log("--1---", this.swiperDataList[index])
const id = this.swiperDataList[index]?.goodsUrl;
if (!id) return;
uni.navigateTo({
url: `/pages/other_package/productInfo/productInfo?id=${id}`,
});
},
formatKefuBadge(value) { formatKefuBadge(value) {
return Number(value) > 99 ? "99+" : String(Number(value) || 0); return Number(value) > 99 ? "99+" : String(Number(value) || 0);
}, },
@@ -806,50 +852,65 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.home_warp { .home_warp {
background: #f4f4f4; background: #fff;
height: calc(100vh - env(safe-area-inset-bottom)); // 是底部的导航栏高度 min-height: 100vh;
overflow-y: auto;
overflow-x: hidden;
position: relative; position: relative;
box-sizing: border-box;
&.iosplatformType { &.iosplatformType {
height: 100vh; min-height: 100vh;
} }
} }
.home_header_warp { .home_header_warp {
background: linear-gradient(270deg, #af39c4 0%, #7732ff 100%); position: relative;
height: auto; width: 100%;
padding: calc(var(--status-bar-height) + 80rpx) 30rpx 30rpx; padding: 0;
margin: 0;
background: transparent;
overflow: hidden;
.banner_swiper_container,
.banner_placeholder {
width: 100%;
position: relative;
}
} }
.home_content_z_warp { /* 顶部固定/变色搜索栏 */
position: absolute; .header_title_warp {
left: 0;
width: 100%;
.header_title_warp {
display: flex; display: flex;
align-items: center; align-items: center;
margin-bottom: 30rpx;
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
right: 0; right: 0;
z-index: 999; z-index: 999;
background: linear-gradient(270deg, #af39c4 0%, #7732ff 100%); background: transparent;
padding: calc(var(--status-bar-height) + 20rpx) 30rpx 20rpx; padding: calc(var(--status-bar-height) + 12rpx) 24rpx 16rpx;
box-sizing: border-box; box-sizing: border-box;
transition: background-color 0.3s ease, box-shadow 0.3s ease;
&::after { &.is-scrolled {
content: ''; background: #ffffff !important;
position: absolute; box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
bottom: -2px;
left: 0; .language_warp {
right: 0; background: #f4f5f8;
height: 4px; border: 1rpx solid #e8e8e8;
//background: linear-gradient(270deg, #af39c4 0%, #7732ff 100%);
pointer-events: none; .search_msg_warp {
color: #888888;
}
::v-deep .up-image,
.up-image {
filter: brightness(0.3);
}
}
.chart_img {
filter: brightness(0.2);
} }
} }
@@ -860,20 +921,24 @@ export default {
} }
.language_warp { .language_warp {
flex: 1;
display: flex; display: flex;
justify-content: space-between; justify-content: flex-start;
align-items: center; align-items: center;
width: 100rpx; height: 68rpx;
padding: 10rpx 20rpx; padding: 0 24rpx;
background: #ffffff30; background: rgba(255, 255, 255, 0.35);
border-radius: 24rpx; border: 1rpx solid rgba(255, 255, 255, 0.4);
// background: linear-gradient(270deg, #ae39c5, #7932fe); border-radius: 34rpx;
box-sizing: border-box;
transition: all 0.3s ease;
} }
.chart_img { .chart_img {
width: 50rpx; width: 50rpx;
height: 50rpx; height: 50rpx;
display: block; display: block;
transition: filter 0.3s ease;
} }
.message-entry { .message-entry {
@@ -893,8 +958,8 @@ export default {
right: -8rpx; right: -8rpx;
min-width: 30rpx; min-width: 30rpx;
height: 30rpx; height: 30rpx;
padding: 0 7rpx; // padding: 0 7rpx;
border: 3rpx solid #8f3be9; // border: 3rpx solid #8f3be9;
border-radius: 18rpx; border-radius: 18rpx;
background: #f04438; background: #f04438;
color: #fff; color: #fff;
@@ -909,52 +974,131 @@ export default {
margin-left: 12rpx; margin-left: 12rpx;
font-weight: 500; font-weight: 500;
font-size: 28rpx; font-size: 28rpx;
color: #ffffffb3; color: rgba(255, 255, 255, 0.95);
transition: color 0.3s ease;
} }
} }
.home_content_z_warp {
position: absolute;
left: 0;
top: 0;
width: 100%;
}
.logo_banner { .logo_banner {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
// padding: 0 30rpx; align-items: center;
color: #ffffff; color: #ffffff;
margin-top: 50rpx; margin-top: 20rpx;
padding: 0 10rpx;
.logo_banner_left {
display: flex;
flex-direction: column;
}
.logo_banner_title { .logo_banner_title {
font-weight: bold; font-weight: bold;
font-size: 38rpx; font-size: 40rpx;
line-height: 36rpx; line-height: 46rpx;
margin: 20rpx 0; margin: 16rpx 0 10rpx;
color: #ffffff;
letter-spacing: 1rpx;
} }
.logo_banner_msg { .logo_banner_msg {
font-size: 22rpx; font-size: 24rpx;
color: rgba(255, 255, 255, 0.9);
letter-spacing: 0.5rpx;
}
.logo_banner_right {
flex-shrink: 0;
}
}
::v-deep .u-swiper__indicator {
position: absolute;
bottom: 105rpx !important;
left: 0 !important;
right: 0 !important;
width: 100% !important;
display: flex !important;
justify-content: center !important;
z-index: 15;
}
.indicator-dots,
.indicator-dots-static {
display: flex;
justify-content: center;
align-items: center;
gap: 10rpx;
.indicator-dot {
width: 16rpx;
height: 8rpx;
border-radius: 4rpx;
background: rgba(255, 255, 255, 0.45);
transition: all 0.3s ease;
&.active {
width: 28rpx;
height: 8rpx;
border-radius: 4rpx;
background: #ffffff;
}
} }
} }
.home_sort_warp { .home_sort_warp {
// position: absolute; position: relative;
top: 460rpx; z-index: 10;
width: 100%; margin: -60rpx 30rpx 0;
.sort_warp { .sort_comm_warp {
background: #ffffff; background: #ffffff;
padding: 20rpx; padding: 30rpx 16rpx 24rpx;
border-radius: 20rpx; border-radius: 28rpx;
box-shadow: 0 8rpx 24rpx rgba(118, 50, 255, 0.08);
display: flex; display: flex;
flex-wrap: wrap; justify-content: space-around;
justify-content: space-between; align-items: center;
.sort_item { .sort_item_comm {
width: 18%; flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-width: 0;
.sort_item_title_comm {
font-weight: 500;
font-size: 24rpx;
color: #333333;
margin-top: 10rpx;
white-space: nowrap;
text-align: center; text-align: center;
margin-bottom: 20rpx; }
}
} }
.sort_item_title { .not_order_warp {
font-weight: 500; background: #ffffff;
font-size: 22rpx; padding: 30rpx;
color: #333333; border-radius: 28rpx;
display: flex;
flex-direction: column;
align-items: center;
box-shadow: 0 8rpx 24rpx rgba(118, 50, 255, 0.08);
.not_order_msg_warp {
font-size: 24rpx;
color: #999999;
margin-top: 12rpx;
} }
} }
} }
@@ -963,10 +1107,11 @@ export default {
padding-bottom: 100rpx; padding-bottom: 100rpx;
&.Hot_Picks_Zone { &.Hot_Picks_Zone {
width: 100%; width: calc(100% - 60rpx);
margin: 0 30rpx 100rpx;
box-sizing: border-box; box-sizing: border-box;
height: auto; height: auto;
background: linear-gradient(344deg, #ffffff 0%, #ede3ff 100%); background: #fff;
border-radius: 28rpx; border-radius: 28rpx;
border: 1rpx solid #dfdfdf; border: 1rpx solid #dfdfdf;
padding: 24rpx 20rpx 20rpx; padding: 24rpx 20rpx 20rpx;
+11 -2
View File
@@ -571,11 +571,20 @@ export default {
} }
}, },
fail: (err) => { fail: (err) => {
this.loading = false;
console.log("Apple登录授权失败 err:", JSON.stringify(err), err);
// 判断是否为用户取消授权(Apple 登录取消错误码通常为 1001 或 code 1001)
if (err && (err.code === 1001 || err.errCode === 1001 || (err.errMsg && err.errMsg.includes("1001")))) {
this.$refs.uToastRef.show({ this.$refs.uToastRef.show({
type: "error", type: "error",
message: "Apple登录授权失败", message: "已取消Apple登录",
}); });
} else {
this.$refs.uToastRef.show({
type: "error",
message: (err && (err.errMsg || err.msg)) ? `Apple登录失败: ${err.errMsg || err.msg}` : "Apple登录授权失败",
});
}
} }
}); });
}, },
@@ -106,7 +106,7 @@
<view class="form-label"> <view class="form-label">
<text class="label-text">物流说明</text> <text class="label-text">物流说明</text>
</view> </view>
<input class="form-input" type="text" v-model="expressRemark" placeholder="这里展示后台设置的退货地址" <input class="form-input" type="text" v-model="expressRemark" placeholder="请填写物流说明(选填)"
placeholder-style="color: #CCCCCC; font-size: 28rpx;" /> placeholder-style="color: #CCCCCC; font-size: 28rpx;" />
</view> </view>
</view> </view>
+10 -19
View File
@@ -103,8 +103,8 @@
+¥{{ item.sumAmount }}</view> +¥{{ item.sumAmount }}</view>
<view class="collect_msg" v-if="!item.buyDeductionValue">运费:¥{{ item.postage }},商品总价:¥{{ item.sumAmount }} <view class="collect_msg" v-if="!item.buyDeductionValue">运费:¥{{ item.postage }},商品总价:¥{{ item.sumAmount }}
</view> </view>
<view class="collect_msg" v-if="!item.buyDeductionValue">共{{ item.buyNum }}件,合计¥{{ item.sumAmount + <view class="collect_msg" v-if="!item.buyDeductionValue">共{{ item.buyNum }}件,合计¥{{ item.sumAmount -
item.postage }}</view> item.buyDeduction }}</view>
<view class="collect_operate"> <view class="collect_operate">
<!-- <view class="operate_comm operate_but_1" v-if="item.status === ORDER_TYPE.UNSHIPPED" @click="checkCancel(true)">取消订单</view> --> <!-- <view class="operate_comm operate_but_1" v-if="item.status === ORDER_TYPE.UNSHIPPED" @click="checkCancel(true)">取消订单</view> -->
<view class="operate_comm operate_but_2" v-if=" <view class="operate_comm operate_but_2" v-if="
@@ -792,25 +792,16 @@ export default {
} }
const data = await getOrderList(params); const data = await getOrderList(params);
if (data && data.bizcode === 100) { if (data && data.bizcode === 100) {
for (let i = 0; i < data.data.entitys.length; i++) { // for (let i = 0; i < data.data.entitys.length; i++) {
for (let j = 0; j < data.data.entitys[i].items.length; j++) { // for (let j = 0; j < data.data.entitys[i].items.length; j++) {
if (data.data.entitys[i].items[j].expressNo) { // if (data.data.entitys[i].items[j].expressNo) {
data.data.entitys[i].items[j].expressData = // data.data.entitys[i].items[j].expressData =
await this.getOrderLogistics( // await this.getOrderLogistics(
data.data.entitys[i].items[j].expressNo // data.data.entitys[i].items[j].expressNo
); // );
} // }
}
}
// data.data.entitys.forEach(item=>{
// if(item.items.length){
// item.items.forEach(async (Iitem)=>{
// if(Iitem.expressNo){
// Iitem.expressData = await this.getOrderLogistics(Iitem.expressNo);
// } // }
// })
// } // }
// })
return data.data; return data.data;
} else { } else {
@@ -53,7 +53,10 @@
<view class="address_info_name">{{ orderInfo.name }}</view> <view class="address_info_name">{{ orderInfo.name }}</view>
<view class="address_info_mobile">{{ orderInfo.phone }}</view> <view class="address_info_mobile">{{ orderInfo.phone }}</view>
</view> </view>
<view class="address_but" :class="{ 'is-rejected': orderInfo.modifyShippingAddressStatus === 3 || getValue(LOGISTICS_STATUS_UPDATE, orderInfo.modifyShippingAddressStatus) === '审核驳回' }">{{ getValue(LOGISTICS_STATUS_UPDATE, orderInfo.modifyShippingAddressStatus) }}</view>
<view class="address_but" v-if="orderInfo.modifyShippingAddressStatus != 0"
:class="{ 'is-rejected': orderInfo.modifyShippingAddressStatus === 3 || getValue(LOGISTICS_STATUS_UPDATE, orderInfo.modifyShippingAddressStatus) === '审核驳回' }">
{{ getValue(LOGISTICS_STATUS_UPDATE, orderInfo.modifyShippingAddressStatus) }}</view>
</view> </view>
<view class="address_content"> <view class="address_content">
{{ assembleAddress(orderInfo).names }} {{ orderInfo.address }} {{ assembleAddress(orderInfo).names }} {{ orderInfo.address }}
@@ -116,9 +119,10 @@
<view class="item_value">¥{{ orderInfo.postage }}</view> <view class="item_value">¥{{ orderInfo.postage }}</view>
</view> </view>
<view class="data_item"> <view class="data_item">
<view class="item_title">平台优惠<text class="copy_order_coupon" v-if="orderInfo.coupon">优惠券</text> <view class="item_title">平台优惠<text class="copy_order_coupon"
v-if="orderInfo.buyDeduction">优惠券</text>
</view> </view>
<view class="item_value">-¥0.00</view> <view class="item_value">-¥{{ orderInfo.buyDeduction }}</view>
</view> </view>
<view class="data_item"> <view class="data_item">
<view class="item_title">应付款</view> <view class="item_title">应付款</view>
@@ -224,7 +228,7 @@
<up-toast ref="uToastRef"></up-toast> <up-toast ref="uToastRef"></up-toast>
<QrcodePreview ref="qrcodePreviewRef" :qrcodeVal="qrcodeVal" /> <QrcodePreview ref="qrcodePreviewRef" :qrcodeVal="qrcodeVal" />
<qiaobao-assistant page-key="pages/mine_package/mine_order_info/mine_order_info" title="订单详情" /> <qiaobao-assistant page-key="pages/mine_package/mine_order_info/mine_order_info" title="订单详情" />
</view> </view>
</template> </template>
<script> <script>
@@ -29,6 +29,7 @@
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5: WRITE_EXTERNAL_STORAGE / READ_EXTERNAL_STORAGE / 相册权限:读写外部存储及相册。用于缓存应用数据、保存图片至本地或读取上传所需的图片/文件。例如:当您发布评价或更换头像时,需要访问相册选择图片;当您分享商品海报时,需要将海报保存到您的手机相册。<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5: WRITE_EXTERNAL_STORAGE / READ_EXTERNAL_STORAGE / 相册权限:读写外部存储及相册。用于缓存应用数据、保存图片至本地或读取上传所需的图片/文件。例如:当您发布评价或更换头像时,需要访问相册选择图片;当您分享商品海报时,需要将海报保存到您的手机相册。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6: VIBRATE:允许手机震动。用于在接收到重要通知或特定交互时提供震动反馈。<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6: VIBRATE:允许手机震动。用于在接收到重要通知或特定交互时提供震动反馈。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7: WAKE_LOCK:唤醒锁定。用于在执行重要后台任务(如文件下载、数据同步)时防止手机进入休眠状态。<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7: WAKE_LOCK:唤醒锁定。用于在执行重要后台任务(如文件下载、数据同步)时防止手机进入休眠状态。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8: RECORD_AUDIO / 麦克风(录音)权限:允许应用访问麦克风进行音频录制。用于在您使用在线客服发送语音消息、语音搜索或按键语音开单等功能时录制您的声音信息。例如:当您在全媒体智能客服页面按住“按住说话”按钮发送语音消息时,我们需要调用麦克风权限采集音频。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;哪些信息会被收集以及我们如何使用这些信息?<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;哪些信息会被收集以及我们如何使用这些信息?<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;收集的信息类别<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;收集的信息类别<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;为了向您提供我们的服务,我们会要求您提供服务所必需的个人信息。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;为了向您提供我们的服务,我们会要求您提供服务所必需的个人信息。
@@ -46,8 +47,8 @@
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;后台/静默收集说明:当您将应用切换至后台或关闭应用但未注销登录时,为保证消息推送的及时性及设备状态同步的准确性,我们可能会在后台状态下收集您的设备标识符(OAID/Android ID)及服务使用记录(如设备在线状态)。后台收集频率不超过每5分钟一次,您可在系统设置中关闭“后台刷新”或“后台运行”权限以停止此类收集,但这可能导致您无法及时接收重要通知。<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;后台/静默收集说明:当您将应用切换至后台或关闭应用但未注销登录时,为保证消息推送的及时性及设备状态同步的准确性,我们可能会在后台状态下收集您的设备标识符(OAID/Android ID)及服务使用记录(如设备在线状态)。后台收集频率不超过每5分钟一次,您可在系统设置中关闭“后台刷新”或“后台运行”权限以停止此类收集,但这可能导致您无法及时接收重要通知。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;敏感个人信息声明<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;敏感个人信息声明<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我们收集的敏感个人信息包括:位置信息(精确经纬度)。我们仅在您明确开启位置权限后收集此类信息,并会采取严格保护措施。对于实名认证信息(姓名、身份证号),如您使用相关服务,我们将单独征得您的同意。<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我们收集的敏感个人信息包括:位置信息(精确经纬度)。我们仅在您明确开启位置权限后收集此类信息,并会采取严格保护措施。对于实名认证信息(姓名、身份证号),如您使用相关服务,我们将单独征得您的同意。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;使用权限:在使用应用的过程中,您可能需要授予应用访问相机的权限,以便进行扫码使用硬件设备。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;使用权限:在使用应用的过程中,您可能需要授予应用访问相机、相册或麦克风的权限,以便进行扫码、上传图片或发送语音消息。
我们仅在您授权的范围内使用相机权限,且不会将相机权限用于其他目的。<br /> 我们仅在您授权的范围内使用相关权限,且不会将相关权限用于其他目的。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;法律要求:在法律法规要求的情况下我们可能会根据适用的法律法规、法律程序或政府要求,披露您的个人信息。<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;法律要求:在法律法规要求的情况下我们可能会根据适用的法律法规、法律程序或政府要求,披露您的个人信息。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;自启动和关联启动说明<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;自启动和关联启动说明<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;为确保本应用处于关闭或后台运行状态下可正常接收到客户端推送的信息、完成订单状态同步等必要业务功能,本应用须使用(自启动)能力,将存在一定频率通过系统发送广播唤醒本应用自启动或关联启动行为,是因实现核心功能及服务所必要的。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;为确保本应用处于关闭或后台运行状态下可正常接收到客户端推送的信息、完成订单状态同步等必要业务功能,本应用须使用(自启动)能力,将存在一定频率通过系统发送广播唤醒本应用自启动或关联启动行为,是因实现核心功能及服务所必要的。
@@ -78,13 +78,13 @@
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6.2.一旦您在信任桥平台的账户被终止,您使用信任桥平台服务的权利即告终止。信任桥不因终止本协议对您承担任何责任,包括终止您的用户账户和删除您的用户内容;信任桥也没有义务向您或第三方提供您使用信任桥平台服务所形成的信息资料。<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6.2.一旦您在信任桥平台的账户被终止,您使用信任桥平台服务的权利即告终止。信任桥不因终止本协议对您承担任何责任,包括终止您的用户账户和删除您的用户内容;信任桥也没有义务向您或第三方提供您使用信任桥平台服务所形成的信息资料。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;七、知识产权声明<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;七、知识产权声明<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7.1【知识产权保护】信任桥是本软件的知识产权权利人。本软件的一切著作权、商标权、专利权、商业秘密等知识产权,以及与本软件相关的所有信息内容(包括但不限于文字、图片、音频、视频、图表、界面设计、版面框架、有关数据或电子文档等)均受您所在当地法律法规和相应的国际条约保护,信任桥享有上述知识产权。您使用信任桥帐号及信任桥平台服务的行为应符合相关协议关于知识产权的约定。<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7.1【知识产权保护】信任桥是本软件的知识产权权利人。本软件的一切著作权、商标权、专利权、商业秘密等知识产权,以及与本软件相关的所有信息内容(包括但不限于文字、图片、音频、视频、图表、界面设计、版面框架、有关数据或电子文档等)均受您所在当地法律法规和相应的国际条约保护,信任桥享有上述知识产权。您使用信任桥帐号及信任桥平台服务的行为应符合相关协议关于知识产权的约定。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7.2【知识产权许可】您在使用信任桥平台服务时利用信任桥帐号发表上传的文字、图片等原创信息的知识产权归您所有但是您确认您对该等信息的发表、上传行为视同为对信任桥非独占地、永久地、不可撤销地授予该等信息相关全部知识产权的使用、复制等权利,并且您同意信任桥可转授权上述权利。<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7.2【知识产权许可】您对利用本平台发表、上传的文字、图片等原创信息依法享有知识产权。为运营本平台并向您提供服务之目的,您授予信任桥一项附条件、可撤销的、非独占的使用权,以复制、使用、展示您所发布的内容。本授权在您主动删除相关内容或注销账号后自动终止。信任桥如需将您的内容用于平台运营之外的其他商业目的,或进行转授权,应另行获得您的书面同意。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7.3【知识产权归属】除非经过信任桥的在先书面同意,您未获得权利使用信任桥的任何知识产权。您保证、陈述并承诺您尊重信任桥的知识产权。您不会以自己名义或促使第三方,也不会同意或放任任何第三方,为了其任何营销、广告、促销或其他目的,在任何法域、以任何方式申请与信任桥或信任桥关联公司商标相似的商标、域名、无线网站、互联网搜索词或任何商号、服务标志。如出现上述情况,您须将所有相关权利转让给信任桥,费用由您承担。您保证、陈述并承诺,不会使用以下名称(包括但不限于“信任桥”)、上述品牌的附属标志及图案(包括但不限于等)作为企业、商户、服务或产品名称的一部分,亦不会使用与信任桥商标或近似商标的知识产权。如因您违反本条款约定而给信任桥造成损失的,该损失全部由您承担。<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7.3【知识产权归属】除非经过信任桥的在先书面同意,您未获得权利使用信任桥的任何知识产权。您保证、陈述并承诺您尊重信任桥的知识产权。您不会以自己名义或促使第三方,也不会同意或放任任何第三方,为了其任何营销、广告、促销或其他目的,在任何法域、以任何方式申请与信任桥或信任桥关联公司商标相似的商标、域名、无线网站、互联网搜索词或任何商号、服务标志。如出现上述情况,您须将所有相关权利转让给信任桥,费用由您承担。您保证、陈述并承诺,不会使用以下名称(包括但不限于“信任桥”)、上述品牌的附属标志及图案(包括但不限于等)作为企业、商户、服务或产品名称的一部分,亦不会使用与信任桥商标或近似商标的知识产权。如因您违反本条款约定而给信任桥造成损失的,该损失全部由您承担。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7.4【侵权处理】您在信任桥发布的信息不得侵犯任何第三人的知识产权,未经具有相关所有权人之事先书面同意,您不得以任何方式上传、发布、修改、传播或复制任何受著作权保护的材料、商标或属于其他人的专有信息。如您认为信任桥平台上的商品或其他信息侵犯了您的知识产权,请按照信任桥平台上公布的知识产权保护规则及流程处理。<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7.4【侵权处理】您在信任桥发布的信息不得侵犯任何第三人的知识产权,未经具有相关所有权人之事先书面同意,您不得以任何方式上传、发布、修改、传播或复制任何受著作权保护的材料、商标或属于其他人的专有信息。如您认为信任桥平台上的商品或其他信息侵犯了您的知识产权,请按照信任桥平台上公布的知识产权保护规则及流程处理。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;八、通知<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;八、通知<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;您在注册成为信任桥用户,并接受信任桥平台服务时,您应该向信任桥提供真实有效的联系方式(包括联系电话等),对于联系方式发生变更的,您有义务及时更新有关信息,并保持可被联系的状态。信任桥向您浏览界面推送的弹窗等通知形式,也作为向您发出的有效通知。信任桥将向您的上述联系方式的其中之一或其中若干向您送达各类通知,而此类通知的内容可能对您的权利义务产生重大的有利或不利影响,请您务必及时关注。您应当保证所提供的联系方式是准确、有效的,并进行实时更新。如果因提供的联系方式不确切,或不及时告知变更后的联系方式,使通知无法送达或未及时送达,由您自行承担由此可能产生的法律后果。<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;您在注册成为信任桥用户,并接受信任桥平台服务时,您应该向信任桥提供真实有效的联系方式(包括联系电话等),对于联系方式发生变更的,您有义务及时更新有关信息,并保持可被联系的状态。信任桥向您浏览界面推送的弹窗等通知形式,也作为向您发出的有效通知。信任桥将向您的上述联系方式的其中之一或其中若干向您送达各类通知,而此类通知的内容可能对您的权利义务产生重大的有利或不利影响,请您务必及时关注。您应当保证所提供的联系方式是准确、有效的,并进行实时更新。如果因提供的联系方式不确切,或不及时告知变更后的联系方式,使通知无法送达或未及时送达,由您自行承担由此可能产生的法律后果。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;九、适用法律及争议解决<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;九、适用法律及争议解决<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;9.1本协议应适用中华人民共和国法律。您因使用信任桥平台服务所产生及与信任桥平台服务有关的争议,由信任桥与您协商解决。协商不成时,任何一方均可向上海市青浦区有管辖权的人民法院提起诉讼。<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;9.1本协议应适用中华人民共和国法律。您因使用信任桥平台服务所产生及与信任桥平台服务有关的争议,由信任桥与您协商解决。协商不成时,任何一方均可向被告住所地有管辖权的人民法院提起诉讼。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;9.2本协议中的某些条款因故无法适用,则本协议的其他条款继续适用且无法适用的条款将会被修改,以便其能够依法适用。<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;9.2本协议中的某些条款因故无法适用,则本协议的其他条款继续适用且无法适用的条款将会被修改,以便其能够依法适用。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;9.3未明示授权的其他权利仍由信任桥保留,您在行使这些权利时须另外取得信任桥的书面许可。信任桥如果未行使前述任何权利,并不构成对该权利的放弃。<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;9.3未明示授权的其他权利仍由信任桥保留,您在行使这些权利时须另外取得信任桥的书面许可。信任桥如果未行使前述任何权利,并不构成对该权利的放弃。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;十、其他<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;十、其他<br />
+12 -1
View File
@@ -20,7 +20,7 @@
<!-- 优惠券列表及分页加载区域 --> <!-- 优惠券列表及分页加载区域 -->
<mescroll-uni <mescroll-uni
ref="mescrollRef" ref="mescrollRef"
top="176rpx" :top="mescrollTop"
@down="downCallback" @down="downCallback"
@up="upCallback" @up="upCallback"
:up="upOption" :up="upOption"
@@ -120,6 +120,17 @@ import { getMyCouponPage } from '@/api/coupon.js';
export default { export default {
mixins: [MescrollMixin], mixins: [MescrollMixin],
components: { Header, TopSafe, MescrollUni }, components: { Header, TopSafe, MescrollUni },
computed: {
mescrollTop() {
// #ifdef H5
return '176rpx';
// #endif
// #ifndef H5
const statusBarHeight = uni.getSystemInfoSync().statusBarHeight || 0;
return (statusBarHeight * 2 + 176) + 'rpx';
// #endif
}
},
data() { data() {
return { return {
currentTab: 0, currentTab: 0,
+7 -9
View File
@@ -125,12 +125,10 @@
<view class="product_info_box"> <view class="product_info_box">
<view class="product_title">{{ item.name || item.title }}</view> <view class="product_title">{{ item.name || item.title }}</view>
<view class="product_tags_row" v-if="item.sellingPoint && getSellingPointTags(item.sellingPoint).length > 0"> <view class="product_tags_row"
<text v-if="item.sellingPoint && getSellingPointTags(item.sellingPoint).length > 0">
class="tag_item tag_green" <text class="tag_item tag_green" v-for="(tag, tIndex) in getSellingPointTags(item.sellingPoint)"
v-for="(tag, tIndex) in getSellingPointTags(item.sellingPoint)" :key="tIndex">{{ tag }}</text>
:key="tIndex"
>{{ tag }}</text>
</view> </view>
<view class="product_price_row"> <view class="product_price_row">
@@ -692,7 +690,7 @@ page {
/* 左侧边栏 */ /* 左侧边栏 */
.left_sidebar_scroll { .left_sidebar_scroll {
width: 180rpx; width: 160rpx;
height: 100%; height: 100%;
flex-shrink: 0; flex-shrink: 0;
background-color: #f7f7f7; background-color: #f7f7f7;
@@ -838,7 +836,6 @@ page {
.product_title { .product_title {
font-size: 28rpx; font-size: 28rpx;
font-weight: bold;
color: #1a1a1a; color: #1a1a1a;
line-height: 38rpx; line-height: 38rpx;
max-height: 76rpx; max-height: 76rpx;
@@ -891,7 +888,8 @@ page {
} }
.price_val { .price_val {
font-size: 38rpx; font-size: 36rpx;
font-weight: normal;
} }
} }
@@ -918,6 +918,187 @@ export default {
await this.pickAndUploadImage() await this.pickAndUploadImage()
}, },
checkMicrophoneAuthorized() {
// #ifdef H5
return true
// #endif
// #ifdef MP-WEIXIN
return new Promise((resolve) => {
uni.getSetting({
success: (res) => {
resolve(res.authSetting['scope.record'] === true)
},
fail: () => resolve(false)
})
})
// #endif
// #ifdef APP-PLUS
return new Promise((resolve) => {
const platform = uni.getSystemInfoSync().platform
if (platform === 'android') {
try {
const main = plus.android.runtimeMainActivity()
const PackageManager = plus.android.importClass('android.content.pm.PackageManager')
const permission = main.checkSelfPermission('android.permission.RECORD_AUDIO')
resolve(permission === PackageManager.PERMISSION_GRANTED)
} catch (e) {
resolve(false)
}
} else if (platform === 'ios') {
try {
const avSession = plus.ios.importClass('AVAudioSession')
const audioSession = avSession.sharedInstance()
const permissionStatus = audioSession.recordPermission()
resolve(permissionStatus === 1970168948)
} catch (e) {
resolve(false)
}
} else {
resolve(true)
}
})
// #endif
},
async requestMicrophonePermission() {
// #ifdef H5
if (typeof navigator !== 'undefined' && navigator.mediaDevices && typeof navigator.mediaDevices.getUserMedia === 'function') {
try {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
stream.getTracks().forEach(track => track.stop())
return true
} catch (e) {
uni.showModal({
title: '麦克风权限提示',
content: '请允许浏览器访问麦克风以使用语音录制功能。',
showCancel: false
})
return false
}
}
return true
// #endif
// #ifdef MP-WEIXIN
return new Promise((resolve) => {
uni.getSetting({
success: (res) => {
const recordAuth = res.authSetting['scope.record']
if (recordAuth === true) {
resolve(true)
} else if (recordAuth === false) {
uni.showModal({
title: '麦克风权限未开启',
content: '需要访问您的麦克风发送语音消息,请前往设置开启权限。',
confirmText: '去设置',
success: (modalRes) => {
if (modalRes.confirm) {
uni.openSetting()
}
resolve(false)
}
})
} else {
uni.authorize({
scope: 'scope.record',
success: () => resolve(true),
fail: () => {
uni.showModal({
title: '授权提示',
content: '麦克风授权失败,无法使用语音功能。',
showCancel: false
})
resolve(false)
}
})
}
},
fail: () => resolve(true)
})
})
// #endif
// #ifdef APP-PLUS
return new Promise((resolve) => {
const platform = uni.getSystemInfoSync().platform
if (platform === 'android') {
try {
plus.android.requestPermissions(
['android.permission.RECORD_AUDIO'],
(result) => {
if (result.granted && result.granted.length > 0) {
resolve(true)
} else {
uni.showModal({
title: '麦克风权限未开启',
content: 'App 需要您的同意才能访问麦克风以发送语音消息。',
confirmText: '去设置',
success: (modalRes) => {
if (modalRes.confirm) {
const Intent = plus.android.importClass('android.content.Intent')
const Settings = plus.android.importClass('android.provider.Settings')
const Uri = plus.android.importClass('android.net.Uri')
const main = plus.android.runtimeMainActivity()
const intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
const uri = Uri.fromParts('package', main.getPackageName(), null)
intent.setData(uri)
main.startActivity(intent)
}
resolve(false)
}
})
}
},
(error) => {
console.error('requestPermissions error:', error)
resolve(true)
}
)
} catch (e) {
resolve(true)
}
} else if (platform === 'ios') {
try {
const avSession = plus.ios.importClass('AVAudioSession')
const audioSession = avSession.sharedInstance()
const permissionStatus = audioSession.recordPermission()
if (permissionStatus === 1970168948) { // AVAudioSessionRecordPermissionGranted
resolve(true)
} else if (permissionStatus === 1970168947) { // AVAudioSessionRecordPermissionDenied
uni.showModal({
title: '麦克风权限未开启',
content: 'App 需要您的同意才能访问麦克风,请前往设置开启麦克风权限。',
confirmText: '去设置',
success: (modalRes) => {
if (modalRes.confirm) {
const UIApplication = plus.ios.importClass('UIApplication')
const NSURL = plus.ios.importClass('NSURL')
const app = UIApplication.sharedApplication()
const settingsUrl = NSURL.URLWithString('app-settings:')
if (app.canOpenURL(settingsUrl)) {
app.openURL(settingsUrl)
}
}
resolve(false)
}
})
} else { // Undetermined
audioSession.requestRecordPermission((granted) => {
resolve(granted)
})
}
} catch (e) {
resolve(true)
}
} else {
resolve(true)
}
})
// #endif
},
toggleVoiceMode() { toggleVoiceMode() {
if (this.uploadingAttachment) return if (this.uploadingAttachment) return
if (this.recording) this.cancelVoiceRecording() if (this.recording) this.cancelVoiceRecording()
@@ -939,8 +1120,10 @@ export default {
this.voiceGestureActive = true this.voiceGestureActive = true
this.recordingCancelled = false this.recordingCancelled = false
this.voiceStartY = this.voiceEventY(event) this.voiceStartY = this.voiceEventY(event)
await this.startVoiceRecording() const ok = await this.startVoiceRecording()
if (!this.voiceGestureActive && this.recording) this.cancelVoiceRecording() if (!ok || (!this.voiceGestureActive && this.recording)) {
this.cancelVoiceRecording()
}
}, },
handleVoicePressMove(event) { handleVoicePressMove(event) {
@@ -28,13 +28,15 @@
/> />
<view v-else-if="normalizedType === contentType.AUDIO" class="audio-block"> <view v-else-if="normalizedType === contentType.AUDIO" class="audio-block">
<button class="audio-message" @click.stop="toggleAudio"> <button class="audio-message" @click.stop="toggleAudio">
<u-icon :name="audioPlaying ? 'pause-circle' : 'play-circle'" size="24" color="#7934f6" /> <view class="audio-message__left">
<text>{{ audioPlaying ? '正在播放' : '语音消息' }}</text> <u-icon :name="audioPlaying ? 'pause-circle' : 'play-circle'" size="26" color="#7934f6" />
<text class="audio-message__title">{{ audioPlaying ? '正在播放' : '语音消息' }}</text>
</view>
<text class="audio-duration">{{ attachment.duration ? `${attachment.duration}″` : '' }}</text> <text class="audio-duration">{{ attachment.duration ? `${attachment.duration}″` : '' }}</text>
</button> </button>
<text v-if="attachment.transcript" class="audio-transcript" selectable>{{ attachment.transcript }}</text> <text v-if="attachment.transcript" class="audio-transcript" selectable>{{ attachment.transcript }}</text>
<button v-else class="transcribe-button" :disabled="transcribing" @click.stop="$emit('transcribe', message)"> <button v-else class="transcribe-button" :disabled="transcribing" @click.stop="$emit('transcribe', message)">
{{ transcribing ? '识别中…' : '转文字' }} <text>{{ transcribing ? '识别中…' : '转文字' }}</text>
</button> </button>
</view> </view>
<button v-else-if="normalizedType === contentType.FILE" class="file-message" @click.stop="openFile"> <button v-else-if="normalizedType === contentType.FILE" class="file-message" @click.stop="openFile">
@@ -513,44 +515,82 @@ export default {
border: 0; border: 0;
} }
.audio-duration {
margin-left: auto;
color: #777983;
font-size: 22rpx;
}
.audio-block { .audio-block {
display: flex; display: flex;
min-width: 240rpx;
flex-direction: column; flex-direction: column;
min-width: 260rpx;
padding: 20rpx 26rpx;
box-sizing: border-box;
}
.audio-message {
display: flex;
width: 100%;
align-items: center;
justify-content: space-between;
gap: 16rpx;
margin: 0;
padding: 0;
background: transparent;
color: #1f1f23;
text-align: left;
line-height: 1;
&::after {
border: 0;
}
}
.audio-message__left {
display: flex;
align-items: center;
gap: 10rpx; gap: 10rpx;
} }
.audio-transcript { .audio-message__title {
padding-top: 10rpx; font-size: 27rpx;
border-top: 1rpx solid rgba(121, 52, 246, 0.14); font-weight: 500;
color: #35343b; color: #1f1f23;
}
.audio-duration {
margin-left: auto;
color: #7934f6;
font-size: 25rpx; font-size: 25rpx;
font-weight: 600;
}
.audio-transcript {
margin-top: 14rpx;
padding-top: 12rpx;
border-top: 1rpx solid rgba(121, 52, 246, 0.15);
color: #27272c;
font-size: 26rpx;
line-height: 1.55; line-height: 1.55;
white-space: normal; white-space: normal;
} }
.transcribe-button { .transcribe-button {
display: inline-flex;
align-items: center;
align-self: flex-start; align-self: flex-start;
margin: 0; margin-top: 12rpx;
padding: 0; padding: 6rpx 16rpx;
background: transparent; border-radius: 12rpx;
color: #6730d7; background: rgba(121, 52, 246, 0.08);
font-size: 23rpx; color: #7934f6;
line-height: 34rpx; font-size: 22rpx;
} font-weight: 500;
line-height: 1.4;
.transcribe-button::after { &::after {
border: 0; border: 0;
} }
.transcribe-button[disabled] { &[disabled] {
color: #8e8f96; color: #8e8f96;
background: rgba(0, 0, 0, 0.04);
}
} }
.file-message { .file-message {