Browse Source

静态

dev_des
1054425342@qq.com 2 months ago
parent
commit
d4cae0e13c
  1. 52
      common/index.js
  2. 161
      components/DynamicIsland.vue
  3. 4
      components/header.vue
  4. 1122
      libs/qqmap-wx-jssdk1.2/qqmap-wx-jssdk.js
  5. 1
      libs/qqmap-wx-jssdk1.2/qqmap-wx-jssdk.min.js
  6. 3
      main.js
  7. 9
      manifest.json
  8. 32
      pages.json
  9. 280
      pages/index/iSoul.vue
  10. 14
      pages/index/index.vue
  11. 91
      pages/index/timeShopBank.vue
  12. 631
      pages/notes/detail.vue
  13. 445
      pages/notes/publish.vue
  14. 1290
      subPackages/equityGoods/detail.vue
  15. 986
      subPackages/equityGoods/list.vue
  16. 339
      subPackages/memorialAlbum/detail.vue
  17. 219
      subPackages/memorialAlbum/index.vue
  18. 772
      subPackages/orderQy/confrim.vue
  19. 746
      subPackages/orderQy/detail.vue
  20. 325
      subPackages/orderQy/list.vue
  21. 687
      subPackages/user/travelerList.vue

52
common/index.js

@ -0,0 +1,52 @@
import QQMapWX from '@/libs/qqmap-wx-jssdk1.2/qqmap-wx-jssdk.js';
//获取位置信息
async function getLocationInfo() {
return new Promise((resolve) => {
//位置信息默认数据
let location = {
longitude: 0,
latitude: 0,
province: '',
city: '',
area: '',
street: '',
address: '',
};
uni.getLocation({
type: 'gcj02',
success(res) {
location.longitude = res.longitude;
location.latitude = res.latitude;
// 腾讯地图Api
const qqmapsdk = new QQMapWX({
key: 'X5YBZ-ES6K3-Q6E3P-RUVXH-2R5ZQ-ERBFG', //这里填写自己申请的key
});
qqmapsdk.reverseGeocoder({
location,
success(response) {
console.log(response)
let info = response.result;
location.province = info.address_component.province;
location.cityCode = info.ad_info.city_code.slice(3);
location.city = info.address_component.city;
location.area = info.address_component.district;
location.street = info.address_component.street;
location.address = info.address;
resolve(location);
},
fail(e){
console.log(e,'地址信息报错')
}
});
},
fail(err) {
console.log(err);
resolve(location);
},
});
});
}
//导出
module.exports = {
getLocationInfo,
};

161
components/DynamicIsland.vue

@ -16,75 +16,82 @@
> >
<!-- 展开状态 --> <!-- 展开状态 -->
<view v-if="!actualCompactState" class="expanded-content"> <view v-if="!actualCompactState" class="expanded-content">
<template v-if="styleType != 'timeShop'"> <!-- <view style="display: flex;align-items: center;justify-content: center;color: white;" v-if="!(userInfo&&userInfo.token)">
<view class="top-section"> 去登录
<text class="welcome-text">{{ title }}</text> </view> -->
<view class="qr-code"> <template >
<image <template v-if="styleType != 'timeShop'">
style="width: 39rpx; height: 39rpx" <view class="top-section">
src="https://epic.js-dyyj.com/uploads/20250728/88e0991e58e692c86c25e42537edc6ca.png" <text class="welcome-text" v-if="userInfo&&userInfo.token">{{ title }}</text>
></image> <text class="welcome-text" v-else @click="toLogin">hi 快去登录 ></text>
</view> <view class="qr-code">
</view> <image
<view class="bottom-section"> style="width: 39rpx; height: 39rpx"
<view class="stats-section"> src="https://epic.js-dyyj.com/uploads/20250728/88e0991e58e692c86c25e42537edc6ca.png"
<view class="stat-item"> ></image>
<text class="stat-number">{{ getStatNumber("权益") }}</text> </view>
<text class="stat-label">权益</text> </view>
</view> <view class="bottom-section">
<view class="stat-item"> <view class="stats-section">
<text class="stat-number">{{ getStatNumber("时间银行") }}</text> <view class="stat-item">
<text class="stat-label">时间银行</text> <text class="stat-number">{{ getStatNumber("权益") }}</text>
</view> <text class="stat-label">权益</text>
</view> </view>
<view class="divider"></view> <view class="stat-item">
<view class="action-section"> <text class="stat-number">{{ getStatNumber("时间银行") }}</text>
<text class="action-text">{{ actionText }}</text> <text class="stat-label">时间银行</text>
<image </view>
class="avatar" </view>
src="https://epic.js-dyyj.com/uploads/20250728/7d9ba1fe109643681396cb03f60f3218.png" <view class="divider"></view>
mode="aspectFill" <view class="action-section">
></image> <text class="action-text">{{ actionText }}</text>
</view> <image
</view> @click="toWebView"
</template> class="avatar"
<template v-if="styleType == 'timeShop'"> src="https://epic.js-dyyj.com/uploads/20250728/7d9ba1fe109643681396cb03f60f3218.png"
<view class="bottom-section"> mode="aspectFill"
<view class="stats-section"> ></image>
<view class="stat-item"> </view>
<text class="stat-number">{{ getStatNumber("时间银行") }}</text> </view>
<text class="stat-label">时间银行</text> </template>
</view> <template v-if="styleType == 'timeShop'">
</view> <view class="bottom-section">
<view class="divider"></view> <view class="stats-section">
<view class="action-section"> <view class="stat-item">
<view class="action-text-box"> <text class="stat-number">{{ getStatNumber("时间银行") }}</text>
<view class="action-text-box-des"> <text class="stat-label">时间银行</text>
在努力一点点为更好的未来蓄力吧 </view>
</view> </view>
<view class="action-text-box-msg"> <view class="divider"></view>
<image <view class="action-section">
class="action-text-box-img" <view class="action-text-box">
:src=" <view class="action-text-box-des">
showImg( 在努力一点点为更好的未来蓄力吧
'/uploads/20250728/d7ac383902515c9b507c78fdc8d29520.png' </view>
) <view class="action-text-box-msg">
" <image
></image> class="action-text-box-img"
今日点赞和留言<text :src="
style="font-size: 30rpx; font-weight: bold; margin: 0 10rpx" showImg(
>100</text '/uploads/20250728/d7ac383902515c9b507c78fdc8d29520.png'
> )
</view> "
</view> ></image>
<image 今日点赞和留言<text
class="avatar" style="font-size: 30rpx; font-weight: bold; margin: 0 10rpx"
src="https://epic.js-dyyj.com/uploads/20250728/7d9ba1fe109643681396cb03f60f3218.png" >100</text
mode="aspectFill" >
></image> </view>
</view> </view>
</view> <image
</template> class="avatar"
src="https://epic.js-dyyj.com/uploads/20250728/7d9ba1fe109643681396cb03f60f3218.png"
mode="aspectFill"
></image>
</view>
</view>
</template>
</template>
</view> </view>
<!-- 紧凑状态 --> <!-- 紧凑状态 -->
@ -143,7 +150,7 @@ export default {
isExpanded: false, isExpanded: false,
statusBarHeight: 0, statusBarHeight: 0,
isScrolled: false, isScrolled: false,
scrollThreshold: 160, // 160rpx scrollThreshold: 140, // 160rpx
// props // props
currentTitle: "Hi!用户,欢迎回来~", currentTitle: "Hi!用户,欢迎回来~",
currentSubtitle: "2个权益 | 120时间银行", currentSubtitle: "2个权益 | 120时间银行",
@ -205,6 +212,11 @@ export default {
this.removeScrollListener(); this.removeScrollListener();
}, },
methods: { methods: {
toLogin(){
uni.navigateTo({
url: "/pages/login/login",
});
},
handleToggle() { handleToggle() {
if (this.isScrolled) { if (this.isScrolled) {
// //
@ -294,6 +306,7 @@ export default {
JSON.parse(uni.getStorageSync("userInfo"))) || JSON.parse(uni.getStorageSync("userInfo"))) ||
this.$store.state.user.userInfo || this.$store.state.user.userInfo ||
{}; {};
console.log(this.userInfo,'this.userInfo')
// //
if (this.userInfo && this.userInfo.nickname) { if (this.userInfo && this.userInfo.nickname) {
this.currentTitle = `Hi!${this.userInfo.nickname},欢迎回来~`; this.currentTitle = `Hi!${this.userInfo.nickname},欢迎回来~`;
@ -303,6 +316,11 @@ export default {
this.userInfo = {}; this.userInfo = {};
} }
}, },
toWebView(){
uni.navigateTo({
url:'/subPackages/webPage/webPage?url='+'https://www.dayunyuanjian.cn/dist/#/chat-demo'
})
}
}, },
}; };
</script> </script>
@ -410,10 +428,7 @@ export default {
.qr-code { .qr-code {
width: 32rpx; width: 32rpx;
height: 32rpx; height: 32rpx;
<<<<<<< HEAD
=======
>>>>>>> 402de12 (feat首页静态)
} }
.qr-icon { .qr-icon {

4
components/header.vue

@ -10,7 +10,7 @@
> >
<!-- 左侧地区筛选和搜索 --> <!-- 左侧地区筛选和搜索 -->
<view class="left-section" v-if="isSearch"> <view class="left-section" v-if="isSearch">
<view class="location-selector" @click="showLocationPicker" v-if="isLocation"> <view class="location-selector" @click="showLocationPicker" v-if="isLocation&&selectedLocation">
<text class="location-text">{{ selectedLocation }}</text> <text class="location-text">{{ selectedLocation }}</text>
<image <image
class="dropdown-icon" class="dropdown-icon"
@ -59,6 +59,7 @@ export default {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
selectedLocation:''
}, },
name: "header", name: "header",
data() { data() {
@ -67,7 +68,6 @@ export default {
height: 0, height: 0,
statusBarHeight: 0, statusBarHeight: 0,
// //
selectedLocation: "苏州",
}; };
}, },
mounted() { mounted() {

1122
libs/qqmap-wx-jssdk1.2/qqmap-wx-jssdk.js

File diff suppressed because it is too large

1
libs/qqmap-wx-jssdk1.2/qqmap-wx-jssdk.min.js

File diff suppressed because one or more lines are too long

3
main.js

@ -5,7 +5,8 @@ import store from './store'
import '@/static/js/request.js' import '@/static/js/request.js'
import '@/static/js/CommonFunction.js' import '@/static/js/CommonFunction.js'
import {myMixins} from '@/mixins/myMixins.js' import {myMixins} from '@/mixins/myMixins.js'
import main from "@/common/index.js"
Vue.prototype.$main = main
Vue.mixin(myMixins) Vue.mixin(myMixins)
Vue.config.productionTip = false Vue.config.productionTip = false

9
manifest.json

@ -57,7 +57,14 @@
"postcss" : true, "postcss" : true,
"minified" : true "minified" : true
}, },
"usingComponents" : true "usingComponents" : true,
"permission" : {
"scope.userLocation" : {
"desc" : "为了提供更好更快速的体验,需要获取您的当前位置"
}
},
"lazyCodeLoading" : "requiredComponents",
"requiredPrivateInfos" : [ "getLocation", "chooseLocation" ]
}, },
"mp-alipay" : { "mp-alipay" : {
"usingComponents" : true "usingComponents" : true

32
pages.json

@ -49,6 +49,22 @@
"navigationBarTitleText": "时间银行", "navigationBarTitleText": "时间银行",
"navigationStyle": "custom" "navigationStyle": "custom"
} }
},
{
"path": "pages/notes/detail",
"style": {
"navigationBarTitleText": "笔记详情",
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black"
}
},
{
"path": "pages/notes/publish",
"style": {
"navigationBarTitleText": "发布笔记",
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black"
}
} }
], ],
"subPackages": [ "subPackages": [
@ -214,6 +230,22 @@
"style": { "style": {
"navigationBarTitleText": "确认订单" "navigationBarTitleText": "确认订单"
} }
},
{
"path": "memorialAlbum/index",
"style": {
"navigationBarTitleText": "数字资产纪念册",
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black"
}
},
{
"path": "memorialAlbum/detail",
"style": {
"navigationBarTitleText": "藏品详情",
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black"
}
} }
] ]
}, },

280
pages/index/iSoul.vue

@ -29,8 +29,8 @@
></image> ></image>
</view> </view>
<view class="user-info"> <view class="user-info">
<view class="username">{{ userInfo.nickname || "用户" }}</view> <view class="username">{{ userInfo.nickname || "去登录" }}</view>
<view class="user-id">ID{{ userInfo.redBookId || "123456" }}</view> <view class="user-id" v-if="userInfo.redBookId">ID{{ userInfo.redBookId || "123456" }}</view>
<!-- <view class="location"> <!-- <view class="location">
<text class="location-icon">📍</text> <text class="location-icon">📍</text>
<text>IP属地{{ userInfo.location || "上海" }}</text> <text>IP属地{{ userInfo.location || "上海" }}</text>
@ -51,17 +51,24 @@
<!-- 统计数据 --> <!-- 统计数据 -->
<view class="stats-section"> <view class="stats-section">
<view class="stat-item"> <view class="stats-left">
<view class="stat-number">{{ userStats.following || "140" }}</view> <view class="stat-item">
<view class="stat-label">关注</view> <view class="stat-number">{{ userStats.following || "140" }}</view>
</view> <view class="stat-label">关注</view>
<view class="stat-item"> </view>
<view class="stat-number">{{ userStats.followers || "2462" }}</view> <view class="stat-item">
<view class="stat-label">粉丝</view> <view class="stat-number">{{ userStats.followers || "2462" }}</view>
<view class="stat-label">粉丝</view>
</view>
<view class="stat-item">
<view class="stat-number">{{ userStats.likes || "5.4万" }}</view>
<view class="stat-label">获赞与收藏</view>
</view>
</view> </view>
<view class="stat-item"> <!-- 权益兑换入口 -->
<view class="stat-number">{{ userStats.likes || "5.4万" }}</view> <view class="exchange-entry" @click="showExchangePopup">
<view class="stat-label">获赞与收藏</view> <view class="exchange-icon">🎁</view>
<view class="exchange-text">权益兑换</view>
</view> </view>
</view> </view>
</view> </view>
@ -222,6 +229,33 @@
<CustomTabBar :currentTab="4" /> <CustomTabBar :currentTab="4" />
<MusicControl /> <MusicControl />
<!-- 权益兑换弹窗 -->
<uni-popup ref="exchangePopup" type="center">
<view class="exchange-popup">
<view class="popup-header">
<text class="popup-title">权益兑换</text>
<text class="popup-close" @click="closeExchangePopup">×</text>
</view>
<view class="popup-content">
<view class="input-section">
<text class="input-label">请输入兑换码</text>
<input
class="exchange-input"
v-model="exchangeCode"
placeholder="请输入兑换码"
maxlength="20"
/>
</view>
<view class="popup-actions">
<button class="cancel-btn" @click="closeExchangePopup">取消</button>
<button class="confirm-btn" @click="confirmExchange">
确认兑换
</button>
</view>
</view>
</view>
</uni-popup>
</view> </view>
</template> </template>
@ -284,6 +318,7 @@ export default {
icon: "💬", icon: "💬",
}, },
], ],
exchangeCode: "", //
}; };
}, },
onLoad() { onLoad() {
@ -427,16 +462,90 @@ export default {
}, },
// //
handleMemorialClick(index) { handleMemorialClick(index) {
if (index === 0) { //
uni.navigateTo({ uni.navigateTo({
url: "/subPackages/readingBody/index", url: "/subPackages/memorialAlbum/index",
});
},
//
showExchangePopup() {
this.exchangeCode = ""; //
this.$refs.exchangePopup.open();
},
//
closeExchangePopup() {
this.$refs.exchangePopup.close();
},
//
async confirmExchange() {
if (!this.exchangeCode.trim()) {
uni.showToast({
title: "请输入兑换码",
icon: "none",
}); });
} else { return;
uni.navigateTo({ }
url: "/subPackages/video/video",
//
uni.showLoading({
title: "兑换中...",
});
try {
// API
const result = await this.exchangeEquity(this.exchangeCode);
uni.hideLoading();
if (result.success) {
uni.showToast({
title: "兑换成功!",
icon: "success",
});
this.closeExchangePopup();
} else {
uni.showToast({
title: result.message || "兑换失败",
icon: "none",
});
}
} catch (error) {
uni.hideLoading();
uni.showToast({
title: "兑换失败,请稍后重试",
icon: "none",
}); });
} }
}, },
// API -
async exchangeEquity(code) {
// API
return new Promise((resolve) => {
setTimeout(() => {
//
if (code === "EPIC2024") {
resolve({
success: true,
message: "兑换成功!获得数字藏品一枚",
});
} else if (code === "TEST123") {
resolve({
success: true,
message: "兑换成功!获得优惠券一张",
});
} else {
resolve({
success: false,
message: "兑换码无效或已使用",
});
}
}, 1500);
});
},
}, },
}; };
</script> </script>
@ -571,13 +680,21 @@ view {
/* 统计数据 */ /* 统计数据 */
.stats-section { .stats-section {
display: flex; display: flex;
justify-content: space-around; justify-content: space-between;
align-items: center;
margin-top: 80rpx; margin-top: 80rpx;
padding-bottom: 50rpx; padding-bottom: 50rpx;
padding: 0 40rpx;
}
.stats-left {
display: flex;
gap: 60rpx;
} }
.stat-item { .stat-item {
text-align: center; text-align: center;
min-width: 80rpx;
} }
.stat-number { .stat-number {
@ -592,6 +709,34 @@ view {
color: rgba(255, 255, 255, 0.8); color: rgba(255, 255, 255, 0.8);
} }
/* 权益兑换入口 */
.exchange-entry {
display: flex;
flex-direction: column;
align-items: center;
padding: 16rpx;
background: rgba(255, 255, 255, 0.1);
border-radius: 20rpx;
min-width: 120rpx;
transition: all 0.3s ease;
&:active {
transform: scale(0.95);
background: rgba(255, 255, 255, 0.2);
}
}
.exchange-icon {
font-size: 32rpx;
margin-bottom: 8rpx;
}
.exchange-text {
font-size: 22rpx;
color: rgba(255, 255, 255, 0.9);
font-weight: 500;
}
/* 操作按钮 */ /* 操作按钮 */
.action-buttons { .action-buttons {
display: flex; display: flex;
@ -893,7 +1038,12 @@ view {
border-bottom: none; border-bottom: none;
} }
//
.user-top { .user-top {
background-size: cover;
background-position: center;
background-repeat: no-repeat;
padding-bottom: 20rpx;
} }
.digital-img { .digital-img {
@ -901,4 +1051,96 @@ view {
width: 100%; width: 100%;
border-radius: 20rpx; border-radius: 20rpx;
} }
/* 权益兑换弹窗 */
.exchange-popup {
width: 600rpx;
background-color: #ffffff;
border-radius: 16rpx;
overflow: hidden;
}
.popup-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
border-bottom: 1px solid #f0f0f0;
}
.popup-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
}
.popup-close {
font-size: 40rpx;
color: #999;
padding: 0 10rpx;
}
.popup-content {
padding: 40rpx 30rpx 30rpx;
}
.input-section {
margin-bottom: 40rpx;
}
.input-label {
display: block;
font-size: 28rpx;
color: #333;
margin-bottom: 20rpx;
font-weight: 500;
}
.exchange-input {
width: 100%;
height: 88rpx;
border: 2rpx solid #e0e0e0;
border-radius: 12rpx;
padding: 0 20rpx;
font-size: 28rpx;
color: #333;
box-sizing: border-box;
&:focus {
border-color: #667eea;
}
}
.popup-actions {
display: flex;
gap: 20rpx;
}
.cancel-btn,
.confirm-btn {
flex: 1;
height: 80rpx;
border-radius: 12rpx;
font-size: 28rpx;
font-weight: 600;
border: none;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
&:active {
transform: scale(0.98);
}
}
.cancel-btn {
background: #f5f5f5;
color: #666;
}
.confirm-btn {
background: #667eea;
color: #ffffff;
}
</style> </style>

14
pages/index/index.vue

@ -1,6 +1,6 @@
<template> <template>
<view class="bg"> <view class="bg">
<headerVue fixed isLocation></headerVue> <headerVue :selectedLocation="selectedLocation" fixed isLocation></headerVue>
<!-- 灵动岛组件 --> <!-- 灵动岛组件 -->
<!-- 灵动岛组件 - 自包含无需传递参数 --> <!-- 灵动岛组件 - 自包含无需传递参数 -->
@ -86,11 +86,11 @@ export default {
], ],
productListFeeling: [ productListFeeling: [
{ {
id: 32, id: 34,
image: image:
"https://epic.js-dyyj.com/uploads/20250728/22e319f3feb1b63fbb539d425c51fe70.png", "https://epic.js-dyyj.com/uploads/20250728/22e319f3feb1b63fbb539d425c51fe70.png",
title: "OUT OF SPACE 东方线香", title: "OUT OF SPACE 东方线香",
price: "588.00", price: "138.00",
isLiked: true, isLiked: true,
isShop:true isShop:true
}, },
@ -103,11 +103,17 @@ export default {
isLiked: false, isLiked: false,
}, },
], ],
selectedLocation:''
}; };
}, },
onLoad() {}, onLoad() {},
onReady() { async onReady() {
let res =await this.$main.getLocationInfo()
console.log(res)
this.selectedLocation = res&&res.city
uni.setStorageSync('SYS_ADDRESS_INFO',JSON.stringify(res))
this.getList(); this.getList();
}, },
onShow() { onShow() {
this.browse_record({ type: "page", title: "首页" }); this.browse_record({ type: "page", title: "首页" });

91
pages/index/timeShopBank.vue

@ -5,12 +5,12 @@
<!-- 灵动岛组件 --> <!-- 灵动岛组件 -->
<DynamicIsland :page-id="'timeShopBank_page'" :style-type="'timeShop'" /> <DynamicIsland :page-id="'timeShopBank_page'" :style-type="'timeShop'" />
<!-- Tab切换组件 --> <!-- Tab切换组件 -->
<view class="tab-container"> <view class="tab-container">
<view class="tab-wrapper"> <view class="tab-wrapper">
<view <view
v-for="(tab, index) in tabs" v-for="(tab, index) in tabs"
:key="index" :key="index"
class="tab-item" class="tab-item"
:class="{ active: currentTab === index }" :class="{ active: currentTab === index }"
@ -21,7 +21,14 @@
</view> </view>
</view> </view>
</view> </view>
<!-- 发布按钮 -->
<view class="fab-container">
<button class="fab-btn" @click="goToPublish">
<text class="fab-icon">+</text>
</button>
</view>
<!-- 瀑布流组件 --> <!-- 瀑布流组件 -->
<WaterfallLayout <WaterfallLayout
:items="waterfallItems" :items="waterfallItems"
@ -66,10 +73,10 @@ export default {
return { return {
currentTab: 1, // "" currentTab: 1, // ""
tabs: [ tabs: [
{ name: '划线', id: 'underline' }, { name: "划线", id: "underline" },
{ name: '笔记', id: 'notes' }, { name: "笔记", id: "notes" },
{ name: '关注', id: 'follow' }, { name: "关注", id: "follow" },
{ name: '推荐', id: 'recommend' } { name: "推荐", id: "recommend" },
], ],
waterfallItems: [], waterfallItems: [],
autoAddEnabled: false, autoAddEnabled: false,
@ -84,8 +91,8 @@ export default {
// //
avatars: [ avatars: [
"https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?auto=format&fit=crop&w=100", "https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?auto=format&fit=crop&w=100",
"https://images.unsplash.com/photo-1438761681033-6461ffad8d80?auto=format&fit=crop&w=100", "https://images.unsplash.com/photo-1438761681033-6461ffad8d80?auto=format&fit=crop&w=100",
"https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?auto=format&fit=crop&w=100", "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?auto=format&fit=crop&w=100",
"https://images.unsplash.com/photo-1438761681033-6461ffad8d80?auto=format&fit=crop&w=100", "https://images.unsplash.com/photo-1438761681033-6461ffad8d80?auto=format&fit=crop&w=100",
"https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?auto=format&fit=crop&w=100", "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?auto=format&fit=crop&w=100",
], ],
@ -137,11 +144,11 @@ export default {
onReachBottom() { onReachBottom() {
this.loadMoreItems(); this.loadMoreItems();
}, },
// - // -
onPageScroll(e) { onPageScroll(e) {
// ID // ID
uni.$emit('pageScroll_timeShopBank_page', e.scrollTop); uni.$emit("pageScroll_timeShopBank_page", e.scrollTop);
}, },
methods: { methods: {
// //
@ -203,17 +210,22 @@ export default {
// //
handleItemClick(item) { handleItemClick(item) {
uni.showToast({ //
title: `点击了: ${item.title}`, uni.navigateTo({
icon: "none", url: `/pages/notes/detail`,
duration: 2000,
}); });
}, },
// //
handleItemAdded(item) { goToPublish() {
uni.navigateTo({
url: "/pages/notes/publish",
});
}, },
//
handleItemAdded(item) {},
// //
handleAutoAddRequest() { handleAutoAddRequest() {
this.addRandomItem(); this.addRandomItem();
@ -226,8 +238,6 @@ export default {
newItems.push(this.getRandomItem()); newItems.push(this.getRandomItem());
} }
this.waterfallItems.push(...newItems); this.waterfallItems.push(...newItems);
}, },
// Tab // Tab
@ -247,9 +257,9 @@ export default {
}; };
</script> </script>
<style> <style>
page{ page {
background-color: white; background-color: white;
} }
</style> </style>
<style lang="scss" scoped> <style lang="scss" scoped>
.page-container { .page-container {
@ -343,7 +353,7 @@ export default {
transform: translateX(-50%); transform: translateX(-50%);
width: 80rpx; width: 80rpx;
height: 4rpx; height: 4rpx;
background: #33FEFE; background: #33fefe;
border-radius: 3rpx; border-radius: 3rpx;
animation: slideIn 0.3s ease; animation: slideIn 0.3s ease;
} }
@ -359,5 +369,38 @@ export default {
} }
} }
/* 悬浮发布按钮 */
.fab-container {
position: fixed;
bottom: 200rpx;
right: 40rpx;
z-index: 999;
}
.fab-btn {
width: 120rpx;
height: 120rpx;
border-radius: 60rpx;
background: linear-gradient(135deg, #ff4757, #ff6b7a);
color: #fff;
border: none;
box-shadow: 0 8rpx 24rpx rgba(255, 71, 87, 0.4);
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
&:active {
transform: scale(0.95);
box-shadow: 0 4rpx 12rpx rgba(255, 71, 87, 0.3);
}
.fab-icon {
font-size: 48rpx;
font-weight: 300;
line-height: 1;
}
}
/* 自定义样式已移至WaterfallLayout组件内部 */ /* 自定义样式已移至WaterfallLayout组件内部 */
</style> </style>

631
pages/notes/detail.vue

@ -0,0 +1,631 @@
<template>
<view class="note-detail-container">
<!-- 笔记内容区域 -->
<view class="content-scroll" >
<!-- 作者信息 -->
<view class="author-section">
<image
class="author-avatar"
:src="noteDetail.user.avatar"
mode="aspectFill"
/>
<view class="author-info">
<text class="author-name">{{ noteDetail.user.name }}</text>
<text class="publish-time">{{
formatTime(noteDetail.createTime)
}}</text>
</view>
<button
class="follow-btn"
:class="{ followed: noteDetail.user.isFollowed }"
@click="toggleFollow"
>
{{ noteDetail.user.isFollowed ? "已关注" : "+ 关注" }}
</button>
</view>
<!-- 笔记标题 -->
<view class="note-title">
{{ noteDetail.title }}
</view>
<!-- 笔记主图 -->
<view class="note-image-container" v-if="noteDetail.image">
<image
class="note-image"
:src="noteDetail.image"
mode="aspectFill"
@click="previewImage(noteDetail.image)"
/>
</view>
<!-- 笔记内容 -->
<view class="note-content">
<text class="content-text">{{ noteDetail.content }}</text>
</view>
<!-- 标签 -->
<view
class="tags-section"
v-if="noteDetail.tags && noteDetail.tags.length"
>
<view class="tag-item" v-for="tag in noteDetail.tags" :key="tag">
#{{ tag }}
</view>
</view>
<!-- 互动数据 -->
<view class="interaction-section">
<view class="interaction-item" @click="toggleLike">
<text class="interaction-icon" :class="{ liked: noteDetail.isLiked }"
></text
>
<text class="interaction-text">{{ noteDetail.likes }}</text>
</view>
<view class="interaction-item" @click="toggleCollect">
<text
class="interaction-icon"
:class="{ collected: noteDetail.isCollected }"
></text
>
<text class="interaction-text">{{ noteDetail.collects }}</text>
</view>
<view class="interaction-item" @click="showShareMenu">
<text class="interaction-icon"></text>
<text class="interaction-text">分享</text>
</view>
</view>
<!-- 评论区域 -->
<view class="comments-section">
<view class="comments-header">
<text class="comments-title"
>评论 ({{ noteDetail.comments.length }})</text
>
</view>
<view
class="comment-item"
v-for="comment in noteDetail.comments"
:key="comment.id"
>
<image
class="comment-avatar"
:src="comment.user.avatar"
mode="aspectFill"
/>
<view class="comment-content">
<view class="comment-header">
<text class="comment-user">{{ comment.user.name }}</text>
<text class="comment-time">{{
formatTime(comment.createTime)
}}</text>
</view>
<text class="comment-text">{{ comment.content }}</text>
<view class="comment-actions">
<view class="comment-like" @click="toggleCommentLike(comment)">
<text class="like-icon" :class="{ liked: comment.isLiked }"
></text
>
<text class="like-count">{{ comment.likes }}</text>
</view>
</view>
</view>
</view>
</view>
<!-- 底部占位 -->
<view class="bottom-placeholder"></view>
</view>
<!-- 底部评论输入框 -->
<view class="comment-input-section">
<input
class="comment-input"
v-model="commentText"
placeholder="写下你的想法..."
@confirm="submitComment"
/>
<button
class="send-btn"
@click="submitComment"
:disabled="!commentText.trim()"
>
发送
</button>
</view>
</view>
</template>
<script>
import headerVue from "@/components/header.vue";
export default {
name: "NoteDetail",
components: {
headerVue,
},
data() {
return {
noteId: "",
commentText: "",
noteDetail: {
id: "",
title: "",
content: "",
image: "",
tags: [],
likes: 0,
collects: 0,
isLiked: false,
isCollected: false,
createTime: "",
user: {
id: "",
name: "",
avatar: "",
isFollowed: false,
},
comments: [],
},
};
},
onLoad(options) {
if (options.id) {
this.noteId = options.id;
this.loadNoteDetail();
} else {
this.loadMockData();
}
},
methods: {
//
async loadNoteDetail() {
try {
uni.showLoading({ title: "加载中..." });
// API
const res = await this.getNoteDetail(this.noteId);
this.noteDetail = res.data;
} catch (error) {
console.error("加载笔记详情失败:", error);
uni.showToast({
title: "加载失败",
icon: "none",
});
} finally {
uni.hideLoading();
}
},
//
loadMockData() {
this.noteDetail = {
id: "mock001",
title: "这里是用户发布内容的标题",
content:
"这里是用户发布的内容这里是用户发布的内容这里是用户发布的内容这里是用户发布的内容这里是用户发布的内容这里是用户发布的内容这里是用户发布的内容这里是用户发布的内容这里是用户发布的内容这里是用户发布的内容这里是用户发布的内容这里是用户发布的内容这里是用户发布的内容这里是用户发布的内容这里是用户发布的内容这里是用户发布的内容这里是用户发布的内容这里是用户发布的内容这里是用户发布的内容",
image: "https://picsum.photos/800/600",
tags: ["时间力", "阅读体验"],
likes: 128,
collects: 64,
isLiked: false,
isCollected: false,
createTime: "2024-01-15 14:30:00",
user: {
id: "user001",
name: "杨璐摄影",
avatar:
"https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?auto=format&fit=crop&w=100",
isFollowed: false,
},
comments: [
{
id: "comment001",
content: "很棒的分享,学到了很多!",
likes: 5,
isLiked: false,
createTime: "2024-01-15 15:00:00",
user: {
id: "user002",
name: "读书爱好者",
avatar:
"https://images.unsplash.com/photo-1438761681033-6461ffad8d80?auto=format&fit=crop&w=100",
},
},
{
id: "comment002",
content: "感谢分享,很有启发性的内容",
likes: 3,
isLiked: false,
createTime: "2024-01-15 16:20:00",
user: {
id: "user003",
name: "时间管理达人",
avatar:
"https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?auto=format&fit=crop&w=100",
},
},
],
};
},
//
previewImage(imageUrl) {
uni.previewImage({
urls: [imageUrl],
current: imageUrl,
});
},
//
toggleFollow() {
this.noteDetail.user.isFollowed = !this.noteDetail.user.isFollowed;
uni.showToast({
title: this.noteDetail.user.isFollowed ? "已关注" : "取消关注",
icon: "none",
});
},
//
toggleLike() {
this.noteDetail.isLiked = !this.noteDetail.isLiked;
this.noteDetail.likes += this.noteDetail.isLiked ? 1 : -1;
},
//
toggleCollect() {
this.noteDetail.isCollected = !this.noteDetail.isCollected;
this.noteDetail.collects += this.noteDetail.isCollected ? 1 : -1;
},
//
showShareMenu() {
uni.share({
provider: "weixin",
scene: "WXSceneSession",
type: 0,
href: `https://example.com/notes/${this.noteDetail.id}`,
title: this.noteDetail.title,
summary: this.noteDetail.content.substring(0, 100),
imageUrl: this.noteDetail.image,
});
},
//
toggleCommentLike(comment) {
comment.isLiked = !comment.isLiked;
comment.likes += comment.isLiked ? 1 : -1;
},
//
async submitComment() {
if (!this.commentText.trim()) {
return;
}
const newComment = {
id: "comment" + Date.now(),
content: this.commentText,
likes: 0,
isLiked: false,
createTime: new Date().toISOString(),
user: {
id: "current_user",
name: "当前用户",
avatar:
"https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?auto=format&fit=crop&w=100",
},
};
this.noteDetail.comments.unshift(newComment);
this.commentText = "";
uni.showToast({
title: "评论成功",
icon: "success",
});
},
//
formatTime(timeString) {
const time = new Date(timeString);
const now = new Date();
const diff = now.getTime() - time.getTime();
if (diff < 60 * 1000) {
return "刚刚";
} else if (diff < 60 * 60 * 1000) {
return Math.floor(diff / (60 * 1000)) + "分钟前";
} else if (diff < 24 * 60 * 60 * 1000) {
return Math.floor(diff / (60 * 60 * 1000)) + "小时前";
} else {
return time.toLocaleDateString();
}
},
// API -
async getNoteDetail(noteId) {
return new Promise((resolve) => {
setTimeout(() => {
this.loadMockData();
resolve({
code: 200,
data: this.noteDetail,
});
}, 500);
});
},
},
};
</script>
<style lang="scss" scoped>
.note-detail-container {
min-height: 100vh;
background: #fff;
display: flex;
flex-direction: column;
}
.content-scroll {
flex: 1;
padding: 0 32rpx;
}
//
.author-section {
display: flex;
align-items: center;
padding: 32rpx 0;
border-bottom: 1rpx solid #f0f0f0;
.author-avatar {
width: 80rpx;
height: 80rpx;
border-radius: 40rpx;
margin-right: 24rpx;
}
.author-info {
flex: 1;
.author-name {
display: block;
font-size: 32rpx;
font-weight: 600;
color: #333;
margin-bottom: 8rpx;
}
.publish-time {
font-size: 24rpx;
color: #999;
}
}
.follow-btn {
border-radius: 30rpx;
font-size: 24rpx;
border: 2rpx solid #ff4757;
background: transparent;
color: #ff4757;
font-weight: 600;
&.followed {
background: #ff4757;
color: #fff;
}
}
}
//
.note-title {
font-size: 40rpx;
font-weight: 600;
color: #333;
line-height: 1.4;
margin: 32rpx 0;
}
//
.note-image-container {
margin: 32rpx 0;
.note-image {
width: 100%;
max-height: 800rpx;
border-radius: 16rpx;
}
}
//
.note-content {
margin: 32rpx 0;
.content-text {
font-size: 32rpx;
line-height: 1.6;
color: #333;
}
}
//
.tags-section {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
margin: 32rpx 0;
.tag-item {
padding: 12rpx 24rpx;
background: #f8f9fa;
border-radius: 32rpx;
font-size: 24rpx;
color: #666;
}
}
//
.interaction-section {
display: flex;
align-items: center;
gap: 48rpx;
padding: 32rpx 0;
border-bottom: 1rpx solid #f0f0f0;
.interaction-item {
display: flex;
align-items: center;
gap: 8rpx;
cursor: pointer;
.interaction-icon {
font-size: 32rpx;
color: #999;
transition: color 0.3s;
&.liked {
color: #ff4757;
}
&.collected {
color: #ffd700;
}
}
.interaction-text {
font-size: 28rpx;
color: #666;
}
}
}
//
.comments-section {
margin: 32rpx 0;
.comments-header {
margin-bottom: 32rpx;
.comments-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
}
}
.comment-item {
display: flex;
margin-bottom: 32rpx;
.comment-avatar {
width: 64rpx;
height: 64rpx;
border-radius: 32rpx;
margin-right: 24rpx;
}
.comment-content {
flex: 1;
.comment-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12rpx;
.comment-user {
font-size: 28rpx;
font-weight: 600;
color: #333;
}
.comment-time {
font-size: 24rpx;
color: #999;
}
}
.comment-text {
font-size: 30rpx;
line-height: 1.5;
color: #333;
margin-bottom: 16rpx;
}
.comment-actions {
display: flex;
align-items: center;
.comment-like {
display: flex;
align-items: center;
gap: 8rpx;
cursor: pointer;
.like-icon {
font-size: 24rpx;
color: #999;
&.liked {
color: #ff4757;
}
}
.like-count {
font-size: 24rpx;
color: #999;
}
}
}
}
}
}
//
.comment-input-section {
display: flex;
align-items: center;
padding: 24rpx 32rpx;
background: #fff;
border-top: 1rpx solid #f0f0f0;
padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 999;
.comment-input {
flex: 1;
height: 80rpx;
background: #f8f9fa;
border-radius: 40rpx;
padding: 0 32rpx;
font-size: 28rpx;
border: none;
margin-right: 16rpx;
}
.send-btn {
width: 120rpx;
height: 60rpx;
line-height: 60rpx;
background: #ff4757;
color: #fff;
border-radius: 40rpx;
font-size: 28rpx;
border: none;
font-weight: 600;
&:disabled {
background: #ccc;
}
}
}
.bottom-placeholder {
height: 130rpx;
padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
padding-bottom: calc(24rpx + constant(safe-area-inset-bottom));
}
</style>

445
pages/notes/publish.vue

@ -0,0 +1,445 @@
<template>
<view class="publish-container">
<!-- 内容区域 -->
<view class="content-scroll">
<!-- 图片区域 -->
<view class="image-section">
<view class="image-grid">
<!-- 已选图片 -->
<view
class="image-item"
v-for="(image, index) in selectedImages"
:key="index"
>
<image class="image-preview" :src="image" mode="aspectFill" />
<view class="image-delete" @click="removeImage(index)">
<text class="delete-icon">×</text>
</view>
</view>
<!-- 添加图片按钮 -->
<view
class="add-image-btn"
@click="chooseImage"
v-if="selectedImages.length < 9"
>
<text class="add-icon">+</text>
</view>
</view>
</view>
<!-- 标题区域 -->
<view class="title-section">
<textarea
class="title-input"
v-model="noteForm.title"
placeholder="请输入标题..."
maxlength="100"
auto-height
/>
</view>
<!-- 详情区域 -->
<view class="content-section">
<textarea
class="content-input"
v-model="noteForm.content"
placeholder="分享你的想法..."
maxlength="2000"
auto-height
/>
</view>
<!-- 快速标签区域 -->
<view class="quick-tags-section">
<view class="quick-tags-list">
<view
class="quick-tag-item"
v-for="tag in quickTags"
:key="tag"
@click="insertQuickTag(tag)"
>
#{{ tag }}
</view>
</view>
</view>
<!-- 已添加标签 -->
<view class="selected-tags-section" v-if="noteForm.tags.length">
<view class="selected-tags-list">
<view
class="selected-tag-item"
v-for="(tag, index) in noteForm.tags"
:key="index"
@click="removeTag(index)"
>
<text class="tag-text">#{{ tag }}</text>
<text class="tag-close">×</text>
</view>
</view>
</view>
<!-- 底部占位 -->
<view class="bottom-placeholder"></view>
</view>
<!-- 底部发布按钮 -->
<view class="bottom-publish">
<button class="publish-btn" @click="publishNote" :disabled="!canPublish">
发布笔记
</button>
</view>
</view>
</template>
<script>
export default {
name: "PublishNote",
data() {
return {
selectedImages: [],
noteForm: {
title: "",
content: "",
tags: [],
images: [],
},
quickTags: [
"阅读体验",
"时间力",
"读书笔记",
"生活感悟",
"学习心得",
"思考",
],
};
},
computed: {
canPublish() {
return (
this.noteForm.title.trim() ||
this.noteForm.content.trim() ||
this.selectedImages.length > 0
);
},
},
methods: {
//
goBack() {
if (this.canPublish) {
uni.showModal({
title: "确认退出",
content: "退出后内容将不会保存,确定要退出吗?",
success: (res) => {
if (res.confirm) {
uni.navigateBack();
}
},
});
} else {
uni.navigateBack();
}
},
//
chooseImage() {
const remainingCount = 9 - this.selectedImages.length;
uni.chooseImage({
count: remainingCount,
sizeType: ["original", "compressed"],
sourceType: ["album", "camera"],
success: (res) => {
this.selectedImages.push(...res.tempFilePaths);
this.noteForm.images = [...this.selectedImages];
},
fail: (err) => {
console.error("选择图片失败:", err);
},
});
},
//
removeImage(index) {
this.selectedImages.splice(index, 1);
this.noteForm.images = [...this.selectedImages];
},
//
insertQuickTag(tag) {
if (!this.noteForm.tags.includes(tag)) {
this.noteForm.tags.push(tag);
}
},
//
removeTag(index) {
this.noteForm.tags.splice(index, 1);
},
//
async publishNote() {
if (!this.canPublish) {
uni.showToast({
title: "请添加内容",
icon: "none",
});
return;
}
try {
uni.showLoading({ title: "发布中..." });
// API
await this.submitNote(this.noteForm);
uni.hideLoading();
uni.showToast({
title: "发布成功",
icon: "success",
duration: 2000,
});
//
setTimeout(() => {
uni.navigateBack();
}, 1500);
} catch (error) {
uni.hideLoading();
uni.showToast({
title: "发布失败,请重试",
icon: "none",
});
}
},
// API
async submitNote(noteData) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("发布笔记数据:", noteData);
resolve({
code: 200,
message: "发布成功",
data: {
id: "note_" + Date.now(),
...noteData,
},
});
}, 1500);
});
},
},
};
</script>
<style lang="scss" scoped>
.publish-container {
min-height: 100vh;
background: #fff;
display: flex;
flex-direction: column;
}
//
.content-scroll {
flex: 1;
padding: 0 30rpx;
width: 690rpx;
}
//
.image-section {
margin: 32rpx 0;
padding-bottom: 32rpx;
border-bottom: 1rpx solid #f0f0f0;
.image-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16rpx;
}
.image-item {
position: relative;
width: 100%;
aspect-ratio: 1;
border-radius: 16rpx;
overflow: hidden;
.image-preview {
width: 100%;
height: 100%;
}
.image-delete {
position: absolute;
top: 8rpx;
right: 8rpx;
width: 48rpx;
height: 48rpx;
background: rgba(0, 0, 0, 0.6);
border-radius: 24rpx;
display: flex;
align-items: center;
justify-content: center;
.delete-icon {
font-size: 32rpx;
color: #fff;
}
}
}
.add-image-btn {
width: 100%;
aspect-ratio: 1;
border: 2rpx dashed #ddd;
border-radius: 16rpx;
display: flex;
align-items: center;
justify-content: center;
background: #fafafa;
.add-icon {
font-size: 48rpx;
color: #999;
}
}
}
//
.title-section {
margin: 32rpx 0;
padding-bottom: 32rpx;
border-bottom: 1rpx solid #f0f0f0;
.title-input {
width: 100%;
min-height: 60rpx;
font-size: 36rpx;
font-weight: 600;
line-height: 1.4;
color: #333;
border: none;
padding: 0;
resize: none;
}
}
//
.content-section {
margin: 32rpx 0;
padding-bottom: 32rpx;
border-bottom: 1rpx solid #f0f0f0;
.content-input {
width: 100%;
min-height: 300rpx;
font-size: 32rpx;
line-height: 1.6;
color: #333;
border: none;
padding: 0;
resize: none;
}
}
//
.quick-tags-section {
margin: 24rpx 0;
.quick-tags-list {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
.quick-tag-item {
padding: 16rpx 24rpx;
background: #f8f9fa;
border: 1rpx solid #e0e0e0;
border-radius: 32rpx;
font-size: 28rpx;
color: #666;
cursor: pointer;
transition: all 0.3s ease;
&:active {
background: #e9ecef;
transform: scale(0.96);
}
}
}
}
//
.selected-tags-section {
margin: 24rpx 0;
padding-top: 24rpx;
border-top: 1rpx solid #f0f0f0;
.selected-tags-list {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
.selected-tag-item {
display: flex;
align-items: center;
gap: 8rpx;
padding: 12rpx 20rpx;
background: #ff4757;
border-radius: 32rpx;
cursor: pointer;
.tag-text {
font-size: 26rpx;
color: #fff;
}
.tag-close {
font-size: 24rpx;
color: #fff;
opacity: 0.8;
margin-left: 8rpx;
}
}
}
}
//
.bottom-publish {
padding: 24rpx 32rpx;
background: #fff;
border-top: 1rpx solid #f0f0f0;
padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 100;
.publish-btn {
width: 100%;
height: 88rpx;
background: #ff4757;
color: #fff;
border-radius: 44rpx;
font-size: 32rpx;
font-weight: 600;
border: none;
transition: all 0.3s ease;
&:disabled {
background: #ccc;
}
&:not(:disabled):active {
transform: scale(0.98);
}
}
}
.bottom-placeholder {
height: 140rpx;
padding-bottom: calc(24rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
}
</style>

1290
subPackages/equityGoods/detail.vue

File diff suppressed because it is too large

986
subPackages/equityGoods/list.vue

File diff suppressed because it is too large

339
subPackages/memorialAlbum/detail.vue

@ -0,0 +1,339 @@
<template>
<view class="memorial-detail">
<!-- 主图区域 -->
<view class="main-image-section">
<image
:src="showImg(detailInfo.image)"
mode="aspectFill"
class="main-image"
@click="previewMainImage"
/>
</view>
<!-- 数字资产信息卡片 -->
<view class="asset-info-card">
<view class="card-header">
<text class="asset-title">{{ detailInfo.title }}</text>
</view>
<view class="info-row">
<text class="info-label">发行数量</text>
<text class="info-value">{{ detailInfo.totalSupply }}</text>
</view>
<view class="divider"></view>
<view class="info-row">
<text class="info-label">数字资产所有方</text>
<text class="info-value">{{ detailInfo.owner }}</text>
</view>
<view class="info-row">
<text class="info-label">数字资产权利方</text>
<text class="info-value">{{ detailInfo.rightHolder }}</text>
</view>
<view class="info-row">
<text class="info-label">数字资产所有方</text>
<text class="info-value">{{ detailInfo.assetOwner }}</text>
</view>
<!-- 收藏信息 -->
<view class="collection-info">
<view class="collection-header"> 收藏信息 </view>
<view class="collector-info">
<text class="collector-label">收藏者</text>
<text class="collector-name">{{ detailInfo.collector }}</text>
<text class="collection-number">编号</text>
<text class="collection-code">{{ detailInfo.collectionCode }}</text>
<text class="collection-time-label">收藏时间</text>
<text class="collection-time">{{ detailInfo.collectionTime }}</text>
</view>
</view>
</view>
<!-- 认证信息卡片 -->
<view class="cert-info-card">
<view class="cert-header"> 认证信息 </view>
<view class="cert-row">
<text class="cert-label">权证码</text>
<text class="cert-value">{{ detailInfo.certificateCode }}</text>
</view>
<view class="cert-row">
<text class="cert-label">合约地址</text>
<text class="cert-value">{{ detailInfo.contractAddress }}</text>
</view>
<view class="cert-row">
<text class="cert-label">交易HASH</text>
<text class="cert-value">{{ detailInfo.transactionHash }}</text>
</view>
<view class="cert-row">
<text class="cert-label">钱包地址</text>
<text class="cert-value">{{ detailInfo.walletAddress }}</text>
</view>
</view>
<!-- 藏品详情卡片 -->
<view class="product-detail-card">
<view class="product-header"> 藏品详情 </view>
<view class="product-content">
<!-- 这里可以放置藏品的详细描述内容 -->
<text class="product-description">{{ detailInfo.description }}</text>
</view>
</view>
</view>
</template>
<script>
export default {
name: "MemorialDetail",
data() {
return {
detailInfo: {
id: "",
title: "这里是数字资产的名称",
totalSupply: "2000",
owner: "XXX博物馆",
rightHolder: "江苏大运河公司",
assetOwner: "江苏大运河公司",
collector: "XXX用户",
collectionCode: "#001-0050/1000",
collectionTime: "2025-085-04 15:20:20",
certificateCode: "SUA-DA-01-20250729A123456-001-0050/1000-v1",
contractAddress: "0xd4efaba236f7c110fe85fcbcde5489a7a3c71ec3",
transactionHash: "0xd412da236f7c110fe81ewl5fcbcde5489a7a3c7",
walletAddress: "0x8df5d733a0dd127022f7740be4f9c10ec8a23b",
image: "/uploads/20250729/42fe2364167c2342076c4e094df3d288.png",
description: "这里是藏品的详细描述信息...",
},
};
},
onLoad(options) {
//
if (options.id) {
this.loadDetailInfo(options.id);
}
},
methods: {
//
async loadDetailInfo(id) {
try {
// API
// const response = await this.getMemorialDetail(id);
// this.detailInfo = response.data;
//
console.log("加载纪念册详情,ID:", id);
} catch (error) {
console.error("加载详情失败:", error);
uni.showToast({
title: "加载失败",
icon: "none",
});
}
},
//
previewMainImage() {
const imageUrl = this.showImg(this.detailInfo.image);
uni.previewImage({
urls: [imageUrl],
current: imageUrl,
});
},
//
showImg(img) {
if (!img) return "";
if (img.startsWith("http")) {
return img;
}
const NEWAPIURL = "https://epic.js-dyyj.com";
return `${NEWAPIURL}${img}`;
},
},
};
</script>
<style lang="scss" scoped>
.memorial-detail {
min-height: 100vh;
background: #f8f9fa;
padding-bottom: env(safe-area-inset-bottom);
}
//
.main-image-section {
width: 100%;
height: 600rpx;
background: #f0f0f0;
display: flex;
align-items: center;
justify-content: center;
.main-image {
width: 100%;
height: 100%;
object-fit: cover;
}
}
//
.asset-info-card,
.cert-info-card,
.product-detail-card {
margin: 20rpx;
background: white;
border-radius: 16rpx;
padding: 32rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
}
//
.asset-info-card {
.card-header {
margin-bottom: 32rpx;
.asset-title {
font-size: 36rpx;
font-weight: 600;
color: #333;
line-height: 1.4;
}
}
.info-row {
display: flex;
margin-bottom: 20rpx;
align-items: flex-start;
.info-label {
font-size: 28rpx;
color: #666;
margin-right: 16rpx;
flex-shrink: 0;
}
.info-value {
font-size: 28rpx;
color: #333;
flex: 1;
}
}
.divider {
height: 1rpx;
background: #e0e0e0;
margin: 24rpx 0;
}
//
.collection-info {
margin-top: 40rpx;
padding: 32rpx;
background: #f8f9fa;
border-radius: 12rpx;
border: 2rpx solid #e0e0e0;
.collection-header {
text-align: center;
font-size: 28rpx;
color: #666;
margin-bottom: 24rpx;
font-weight: 500;
}
.collector-info {
display: grid;
grid-template-columns: auto auto;
gap: 16rpx 24rpx;
text-align: center;
.collector-label,
.collection-number,
.collection-time-label {
font-size: 24rpx;
color: #666;
}
.collector-name,
.collection-code,
.collection-time {
font-size: 26rpx;
color: #333;
font-weight: 500;
}
.collection-code {
font-family: "Courier New", monospace;
}
.collection-time {
font-family: "Courier New", monospace;
}
}
}
}
//
.cert-info-card {
.cert-header {
text-align: center;
font-size: 28rpx;
color: #666;
margin-bottom: 32rpx;
font-weight: 500;
}
.cert-row {
margin-bottom: 24rpx;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #f0f0f0;
&:last-child {
margin-bottom: 0;
padding-bottom: 0;
border-bottom: none;
}
.cert-label {
display: block;
font-size: 26rpx;
color: #666;
margin-bottom: 8rpx;
}
.cert-value {
display: block;
font-size: 24rpx;
color: #333;
font-family: "Courier New", monospace;
word-break: break-all;
line-height: 1.5;
}
}
}
//
.product-detail-card {
.product-header {
text-align: center;
font-size: 28rpx;
color: #666;
margin-bottom: 32rpx;
font-weight: 500;
}
.product-content {
.product-description {
font-size: 28rpx;
color: #333;
line-height: 1.6;
}
}
}
</style>

219
subPackages/memorialAlbum/index.vue

@ -0,0 +1,219 @@
<template>
<view class="memorial-album">
<!-- 纪念册网格 -->
<view class="memorial-grid">
<view
class="memorial-item"
v-for="(item, index) in memorialItems"
:key="index"
@click="goToDetail(item)"
>
<view class="memorial-card">
<image
:src="showImg(item.image)"
mode="aspectFill"
class="memorial-image"
/>
<view class="memorial-info">
<text class="memorial-title">{{ item.title }}</text>
<text class="memorial-code">{{ item.code }}</text>
<text class="memorial-status">{{ item.status }}</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: "MemorialAlbum",
data() {
return {
memorialItems: [
{
id: 1,
title: "香在苏州|世界美食之都",
code: "#001-0050/1000",
status: "XXX博物馆",
image: "/uploads/20250729/42fe2364167c2342076c4e094df3d288.png",
},
{
id: 2,
title: "香在苏州|世界美食之都",
code: "#001-0050/1000",
status: "XXX博物馆",
image: "/uploads/20250729/105755e9b2e570e46b96d54ed61abe51.png",
},
{
id: 3,
title: "香在苏州|世界美食之都",
code: "#001-0050/1000",
status: "XXX博物馆",
image: "/uploads/20250729/105755e9b2e570e46b96d54ed61abe51.png",
},
{
id: 4,
title: "香在苏州|世界美食之都",
code: "#001-0050/1000",
status: "XXX博物馆",
image: "/uploads/20250729/42fe2364167c2342076c4e094df3d288.png",
},
],
};
},
methods: {
//
goBack() {
uni.navigateBack();
},
//
goToDetail(item) {
uni.navigateTo({
url: `/subPackages/memorialAlbum/detail?id=${item.id}`,
});
},
//
previewImage(imagePath) {
const imageUrl = this.showImg(imagePath);
uni.previewImage({
urls: [imageUrl],
current: imageUrl,
});
},
//
showImg(img) {
if (!img) return "";
if (img.startsWith("http")) {
return img;
}
// API
const NEWAPIURL = "https://epic.js-dyyj.com";
return `${NEWAPIURL}${img}`;
},
},
};
</script>
<style lang="scss" scoped>
.memorial-album {
min-height: 100vh;
background: #f8f9fa;
padding-bottom: env(safe-area-inset-bottom);
}
//
.nav-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx 30rpx;
background: white;
border-bottom: 1rpx solid #eee;
position: sticky;
top: 0;
z-index: 100;
}
.nav-back {
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
}
.nav-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
}
.nav-placeholder {
width: 60rpx;
}
//
.memorial-grid {
padding: 30rpx;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20rpx;
}
.memorial-item {
background: white;
border-radius: 16rpx;
overflow: hidden;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
transition: transform 0.2s ease;
&:active {
transform: scale(0.98);
}
}
.memorial-card {
width: 100%;
}
.memorial-image {
width: 100% !important;
height: 460rpx !important;
background: #f5f5f5;
display: block;
object-fit: cover;
}
.memorial-info {
padding: 28rpx 24rpx;
display: flex;
flex-direction: column;
gap: 12rpx;
}
.memorial-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
line-height: 1.4;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
overflow: hidden;
}
.memorial-code {
font-size: 26rpx;
color: #666;
font-family: "Courier New", monospace;
}
.memorial-status {
font-size: 24rpx;
color: #999;
}
//
@media screen and (max-width: 400px) {
.memorial-grid {
padding: 20rpx;
gap: 15rpx;
}
.memorial-image {
height: 460rpx !important; // 使
}
.memorial-info {
padding: 24rpx 20rpx;
}
.memorial-title {
font-size: 28rpx;
}
}
</style>

772
subPackages/orderQy/confrim.vue

@ -0,0 +1,772 @@
<template>
<view class="confirm-container">
<scroll-view class="content-scroll" scroll-y>
<!-- 收货地址 -->
<view class="address-section">
<!-- 有地址时显示 -->
<view class="section-header" @click="selectAddress" v-if="address.name">
<view class="address-info">
<view class="user-info">
<text class="username">{{ address.name }}</text>
<text class="phone">{{ formatPhone(address.phone) }}</text>
<text class="default-tag" v-if="address.isDefault">默认地址</text>
</view>
<view class="address-detail">
<text>{{ address.fullAddress }}</text>
</view>
</view>
<uni-icons type="right" size="16" color="#c0c4cc" />
</view>
<!-- 没有地址时显示 -->
<view class="empty-address" @click="selectAddress" v-else>
<view class="empty-address-content">
<uni-icons type="location" size="24" color="#c0c4cc" />
<view class="empty-address-text">
<text class="empty-title">请选择收货地址</text>
<text class="empty-tip">点击添加收货地址信息</text>
</view>
</view>
<uni-icons type="right" size="16" color="#c0c4cc" />
</view>
</view>
<!-- 预约日期 -->
<view class="date-section">
<view class="section-title">
<text>预约日期</text>
<text class="required">*</text>
</view>
<view class="date-picker-container">
<uni-datetime-picker
v-model="selectedDate"
type="date"
:clear-icon="false"
placeholder="请选择预约日期"
@change="onDateChange"
>
<view class="date-input">
<text class="date-text" :class="{ placeholder: !selectedDate }">
{{ selectedDate || "请选择预约日期" }}
</text>
<uni-icons type="calendar" size="18" color="#c0c4cc" />
</view>
</uni-datetime-picker>
</view>
</view>
<!-- 商品信息 -->
<view class="goods-section">
<view class="section-title">
<text>IP资产供应商{{ supplier || "苏州XXX博物馆" }}</text>
</view>
<view class="goods-card" v-for="item in 4">
<image
class="goods-image"
:src="goodsInfo.image || '/static/image/goods-default.jpg'"
mode="aspectFill"
/>
<view class="goods-info">
<text class="goods-name">{{
goodsInfo.name || "食在苏州 | 世界美食之都巡礼+实物探真"
}}</text>
<text class="goods-desc">{{
goodsInfo.desc || "商品规格信息描述"
}}</text>
<text class="goods-price">¥{{ goodsInfo.price || "699.00" }}</text>
</view>
</view>
</view>
<!-- 履约方式 -->
<!-- <view class="delivery-section">
<view class="section-row" @click="selectDeliveryMethod">
<text class="section-label">履约方式</text>
<view class="section-value">
<text :class="{ placeholder: !deliveryMethod }">
{{ deliveryMethod || "预约发货+到店核销 >" }}
</text>
</view>
</view>
</view> -->
<!-- 备注 -->
<view class="note-section">
<view class="section-row">
<text class="section-label">备注</text>
<view class="note-input">
<input
v-model="note"
placeholder="选填"
placeholder-class="placeholder"
maxlength="200"
/>
</view>
</view>
</view>
<!-- 费用明细 -->
<view class="cost-section">
<view class="cost-item">
<text class="cost-label">商品金额</text>
<text class="cost-value">¥{{ goodsInfo.price || "699.00" }}</text>
</view>
<view class="cost-item">
<text class="cost-label">运费</text>
<text class="cost-value">{{ shipping || "预约发货时计算" }}</text>
</view>
<view class="cost-item">
<text class="cost-label">优惠券</text>
<text class="cost-value coupon">{{ coupon || "无可用 >" }}</text>
</view>
</view>
<view class="submit-section-content" style="height: 230rpx"> </view>
</scroll-view>
<!-- 底部提交区域 -->
<view
class=" "
style="position: fixed; width: 100%; bottom: 0; z-index: 98"
>
<view class="submit-section">
<view class="total-price">
<text class="total-amount">¥{{ totalAmount || "699.00" }}</text>
</view>
<button class="submit-btn" @click="submitOrder">提交订单</button>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
//
address: {
name: "",
phone: "",
fullAddress: "",
isDefault: false,
},
//
selectedDate: "",
//
goodsInfo: {
id: "",
name: "",
desc: "",
price: "",
image: "",
},
//
supplier: "",
//
deliveryMethod: "",
//
note: "",
//
shipping: "",
//
coupon: "",
//
totalAmount: "",
};
},
onLoad(options) {
//
if (options.goodsId) {
this.loadGoodsInfo(options.goodsId);
}
if (options.goodsName) {
this.goodsInfo.name = decodeURIComponent(options.goodsName);
}
this.loadDefaultAddress();
//
uni.$on("addressSelected", this.handleAddressSelected);
},
onShow() {
//
const hasSelectedAddress = this.checkSelectedAddress();
//
if (!hasSelectedAddress && !this.address.id) {
this.loadDefaultAddress();
}
},
onUnload() {
//
uni.$off("addressSelected", this.handleAddressSelected);
},
methods: {
//
goBack() {
uni.navigateBack();
},
//
handleAddressSelected(data) {
if (data.fromPage === "orderConfirm") {
this.updateAddressInfo(data.address);
console.log("地址已更新:", this.address);
}
},
//
updateAddressInfo(addressData) {
this.address = {
id: addressData.id,
name: addressData.name,
phone: addressData.tel,
fullAddress: addressData.address || this.getFullAddress(addressData),
isDefault: addressData.is_default == 1,
};
},
// storage
checkSelectedAddress() {
try {
const selectedAddress = uni.getStorageSync("selectedAddress");
if (selectedAddress) {
this.updateAddressInfo(selectedAddress);
// storage
uni.removeStorageSync("selectedAddress");
return true; //
}
return false;
} catch (error) {
console.error("读取选中地址失败:", error);
return false;
}
},
//
getFullAddress(addressData) {
const province = addressData.province_text || "";
const city = addressData.city_text || "";
const district = addressData.district_text || "";
const detail = addressData.detail_addr || "";
return `${province}${city}${district}${detail}`;
},
//
formatPhone(phone) {
if (!phone) return "";
return phone.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2");
},
//
selectAddress() {
uni.navigateTo({
url: "/subPackages/user/travelerList?from=orderConfirm",
});
},
//
onDateChange(date) {
this.selectedDate = date;
console.log("选择的日期:", date);
},
//
selectDeliveryMethod() {
const itemList = ["预约发货+到店核销", "预约发货+快递配送", "到店自提"];
uni.showActionSheet({
itemList: itemList,
success: (res) => {
this.deliveryMethod = itemList[res.tapIndex];
console.log("选择的履约方式:", this.deliveryMethod);
},
fail: (err) => {
console.log("取消选择履约方式");
},
});
},
//
async loadGoodsInfo(goodsId) {
try {
// API
const goodsData = await this.getGoodsDetail(goodsId);
this.goodsInfo = goodsData;
this.supplier = goodsData.supplier;
this.totalAmount = goodsData.price;
} catch (error) {
console.error("加载商品信息失败:", error);
}
},
//
async loadDefaultAddress() {
try {
// API
const addressData = await this.getDefaultAddress();
if (addressData && !this.address.id) {
//
this.updateAddressInfo(addressData);
}
} catch (error) {
console.error("加载默认地址失败:", error);
}
},
//
async submitOrder() {
//
if (!this.selectedDate) {
uni.showToast({
title: "请选择预约日期",
icon: "none",
});
return;
}
if (!this.deliveryMethod) {
uni.showToast({
title: "请选择履约方式",
icon: "none",
});
return;
}
if (!this.address.name) {
uni.showToast({
title: "请选择收货地址",
icon: "none",
});
return;
}
try {
uni.showLoading({
title: "提交中...",
});
const orderData = {
goodsId: this.goodsInfo.id,
addressId: this.address.id,
deliveryDate: this.selectedDate,
deliveryMethod: this.deliveryMethod,
note: this.note,
totalAmount: this.totalAmount,
};
const result = await this.createOrder(orderData);
uni.hideLoading();
if (result.success) {
uni.showToast({
title: "订单提交成功",
icon: "success",
});
//
setTimeout(() => {
uni.redirectTo({
url: "/subPackages/orderQy/detail?orderId=" + result.orderId,
});
}, 1500);
}
} catch (error) {
uni.hideLoading();
console.error("提交订单失败:", error);
uni.showToast({
title: "提交失败,请重试",
icon: "none",
});
}
},
// API -
async getGoodsDetail(goodsId) {
// API
return new Promise((resolve) => {
setTimeout(() => {
resolve({
id: goodsId,
name: "食在苏州 | 世界美食之都巡礼+实物探真",
desc: "商品规格信息描述",
price: "699.00",
image: "/static/image/goods-sample.jpg",
supplier: "苏州XXX博物馆",
});
}, 500);
});
},
// API -
async getDefaultAddress() {
// API
return new Promise((resolve) => {
setTimeout(() => {
resolve({
id: 1,
name: "XX先生",
tel: "18312341234",
address: "江苏省苏州市姑苏区XXXXXX",
province_text: "江苏省",
city_text: "苏州市",
district_text: "姑苏区",
detail_addr: "XXXXXX",
is_default: 1,
});
}, 500);
});
},
// API -
async createOrder(orderData) {
// API
return new Promise((resolve) => {
setTimeout(() => {
resolve({
success: true,
orderId: "EQ" + Date.now(),
});
}, 1000);
});
},
},
};
</script>
<style lang="scss" scoped>
//
$primary-color: #667eea;
$secondary-color: #f8f9fa;
$text-primary: #2d3748;
$text-secondary: #718096;
$text-muted: #a0aec0;
$border-color: #e2e8f0;
$success-color: #48bb78;
$warning-color: #ed8936;
$danger-color: #f56565;
$bg-light: #f7fafc;
.confirm-container {
height: 100vh;
background-color: $bg-light;
display: flex;
flex-direction: column;
}
.content-scroll {
flex: 1;
padding: 20rpx;
width: 710rpx;
}
// section
.section-header,
.section-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 24rpx 30rpx;
background-color: #ffffff;
border-radius: 16rpx;
margin-bottom: 20rpx;
}
.section-title {
font-size: 28rpx;
color: $text-primary;
font-weight: 600;
margin-bottom: 16rpx;
.required {
color: $danger-color;
margin-left: 4rpx;
}
}
//
.address-section {
margin-bottom: 24rpx;
}
.address-info {
flex: 1;
}
.user-info {
display: flex;
align-items: center;
margin-bottom: 12rpx;
gap: 16rpx;
}
.username {
font-size: 28rpx;
color: $text-primary;
font-weight: 600;
}
.phone {
font-size: 24rpx;
color: $text-secondary;
}
.default-tag {
font-size: 20rpx;
color: $primary-color;
background-color: rgba(102, 126, 234, 0.1);
padding: 4rpx 12rpx;
border-radius: 12rpx;
}
.address-detail {
font-size: 26rpx;
color: $text-secondary;
line-height: 1.4;
}
//
.empty-address {
display: flex;
justify-content: space-between;
align-items: center;
padding: 24rpx 30rpx;
background-color: #ffffff;
border-radius: 16rpx;
margin-bottom: 20rpx;
border: 2rpx dashed $border-color;
transition: all 0.3s ease;
&:active {
background-color: rgba(102, 126, 234, 0.02);
border-color: $primary-color;
}
}
.empty-address-content {
display: flex;
align-items: center;
gap: 16rpx;
}
.empty-address-text {
display: flex;
flex-direction: column;
gap: 6rpx;
}
.empty-title {
font-size: 28rpx;
color: $text-primary;
font-weight: 500;
}
.empty-tip {
font-size: 24rpx;
color: $text-muted;
}
//
.date-section {
margin-bottom: 24rpx;
}
.date-picker-container {
background-color: #ffffff;
border-radius: 16rpx;
padding: 24rpx 30rpx;
}
.date-input {
display: flex;
justify-content: space-between;
align-items: center;
}
.date-text {
font-size: 28rpx;
color: $text-primary;
&.placeholder {
color: $text-muted;
}
}
//
.goods-section {
margin-bottom: 24rpx;
}
.goods-card {
display: flex;
background-color: #ffffff;
border-radius: 16rpx;
padding: 24rpx;
gap: 20rpx;
}
.goods-image {
width: 120rpx;
height: 120rpx;
border-radius: 12rpx;
flex-shrink: 0;
}
.goods-info {
flex: 1;
display: flex;
flex-direction: column;
gap: 12rpx;
}
.goods-name {
font-size: 26rpx;
color: $text-primary;
font-weight: 600;
line-height: 1.4;
}
.goods-desc {
font-size: 24rpx;
color: $text-secondary;
line-height: 1.3;
}
.goods-price {
font-size: 32rpx;
color: $danger-color;
font-weight: 600;
margin-top: auto;
}
//
.delivery-section {
margin-bottom: 24rpx;
}
.section-label {
font-size: 28rpx;
color: $text-primary;
font-weight: 500;
}
.section-value {
display: flex;
align-items: center;
text {
font-size: 26rpx;
color: $text-primary;
&.placeholder {
color: $text-muted;
}
}
}
//
.note-section {
margin-bottom: 24rpx;
.section-row {
align-items: flex-start;
}
}
.note-input {
flex: 1;
margin-left: 40rpx;
input {
font-size: 26rpx;
color: $text-primary;
text-align: right;
width: 100%;
}
.placeholder {
color: $text-muted;
}
}
//
.cost-section {
background-color: #ffffff;
border-radius: 16rpx;
padding: 24rpx 30rpx;
margin-bottom: 24rpx;
}
.cost-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16rpx 0;
&:not(:last-child) {
border-bottom: 1px solid $border-color;
}
}
.cost-label {
font-size: 26rpx;
color: $text-primary;
}
.cost-value {
font-size: 26rpx;
color: $text-primary;
&.coupon {
color: $text-muted;
}
}
//
.submit-section {
flex-shrink: 0; //
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx 30rpx;
background-color: #ffffff;
border-top: 1px solid $border-color;
box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.04);
//
padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
}
.submit-section-content {
padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
}
.total-price {
flex: 1;
}
.total-amount {
font-size: 36rpx;
color: $danger-color;
font-weight: 600;
font-family: "SF Mono", "Monaco", "Cascadia Code", monospace;
}
.submit-btn {
background-color: $text-primary;
color: #ffffff;
border: none;
border-radius: 32rpx;
padding: 4rpx 48rpx;
font-size: 28rpx;
font-weight: 600;
transition: all 0.3s ease;
&:active {
transform: scale(0.95);
background-color: rgba(45, 55, 72, 0.8);
}
}
</style>

746
subPackages/orderQy/detail.vue

@ -1,143 +1,151 @@
<template> <template>
<view class="order-detail-container"> <view class="order-detail-container">
<!-- 订单状态 --> <!-- 订单状态头部 -->
<view class="status-section"> <view class="status-header">
<view class="status-icon"> <view class="status-badge" :class="[getStatusClass(orderDetail.status)]">
<image {{ getStatusText(orderDetail.status) }}
:src="getStatusIcon(orderDetail.status)"
mode="aspectFit"
class="icon"
/>
</view>
<view class="status-info">
<text class="status-text">{{ getStatusText(orderDetail.status) }}</text>
<text class="status-desc">{{ getStatusDesc(orderDetail.status) }}</text>
</view> </view>
<view class="order-title">订单详情</view>
</view> </view>
<!-- 订单信息 --> <!-- 收货地址信息 -->
<view class="order-info-section"> <view class="address-section" v-if="hasPhysicalGoods">
<view class="section-title">订单信息</view> <view class="section-label">收货地址</view>
<view class="info-item"> <view class="address-card" v-if="orderDetail.address">
<text class="label">订单号</text> <view class="address-info">
<text class="value">{{ orderDetail.orderNo }}</text> <text class="address-text">{{
<text class="copy-btn" @click="copyOrderNo">复制</text> orderDetail.address.fullAddress
}}</text>
<view class="contact-info">
<text class="contact-name">{{ orderDetail.address.name }}</text>
<text class="contact-phone">{{ orderDetail.address.phone }}</text>
</view>
</view>
</view> </view>
<view class="info-item"> <view class="no-address" v-else>
<text class="label">下单时间</text> <text>该订单无需收货地址</text>
<text class="value">{{ formatTime(orderDetail.createTime) }}</text>
</view> </view>
<view class="info-item" v-if="orderDetail.payTime"> </view>
<text class="label">付款时间</text>
<text class="value">{{ formatTime(orderDetail.payTime) }}</text> <!-- 预约发货时间 -->
<view class="delivery-section">
<view class="info-row">
<text class="info-label">预约发货时间</text>
<text class="info-value">{{ orderDetail.deliveryDate || "--" }}</text>
</view> </view>
<view class="info-item"> <view class="info-row">
<text class="label">支付方式</text> <text class="info-label">快递单号</text>
<text class="value">{{ orderDetail.payMethod || "微信支付" }}</text> <text class="info-value">{{ orderDetail.trackingNo || "--" }}</text>
</view> </view>
</view> </view>
<!-- 权益商品包 --> <!-- 商品标题 -->
<view class="package-section"> <view class="product-title">
<view class="section-title">权益商品包</view> {{ orderDetail.packageName }}
<view class="package-name">{{ orderDetail.packageName }}</view>
</view> </view>
<!-- 商品列表 --> <!-- 商品列表 -->
<view class="goods-section"> <view class="goods-section">
<view class="section-title">商品清单</view>
<view <view
class="goods-item" class="goods-item"
v-for="goods in orderDetail.goodsList" v-for="goods in orderDetail.goodsList"
:key="goods.id" :key="goods.id"
> >
<image class="goods-image" :src="goods.image" mode="aspectFill" /> <view class="goods-checkbox">
<view class="goods-info"> <view class="checkbox-icon">
<text class="goods-name">{{ goods.name }}</text> <image mode="aspectFill" src="https://picsum.photos/200/300"></image>
<text class="goods-type">{{ getGoodsTypeName(goods.type) }}</text> </view>
<text class="goods-spec" v-if="goods.spec">{{ goods.spec }}</text>
</view> </view>
<view class="goods-price"> <view class="goods-content">
<text class="price">¥{{ goods.price }}</text> <view class="goods-info">
<text class="quantity">×{{ goods.quantity || 1 }}</text> <view class="goods-name">{{ goods.name }}</view>
<view class="goods-desc">{{
goods.description || goods.spec
}}</view>
</view>
<view class="goods-actions">
<button class="action-btn" :class="[getGoodsActionClass(goods.type)]">
{{ getGoodsActionText(goods.type) }}
</button>
</view>
</view> </view>
</view> </view>
</view> </view>
<!-- 权益码信息 --> <!-- 订单信息 -->
<view class="equity-section" v-if="orderDetail.status !== 0"> <view class="order-info-section">
<view class="section-title">权益码信息</view> <view class="section-title">订单信息</view>
<view class="equity-card" @click="showEquityCode"> <view class="info-row">
<view class="equity-info"> <text class="info-label">订单编号</text>
<text class="equity-label">权益码</text> <text class="info-value">{{ orderDetail.orderNo }}</text>
<text class="equity-code">{{ orderDetail.equityCode }}</text>
</view>
<view class="equity-action">
<text class="view-qr">查看二维码</text>
</view>
</view> </view>
</view> <view class="info-row">
<text class="info-label">商品合计</text>
<!-- 费用明细 --> <text class="info-value">{{ orderDetail.goodsAmount }}</text>
<view class="cost-section">
<view class="section-title">费用明细</view>
<view class="cost-item">
<text class="cost-label">商品总价</text>
<text class="cost-value">¥{{ orderDetail.goodsAmount }}</text>
</view> </view>
<view class="cost-item" v-if="orderDetail.discountAmount > 0"> <view class="info-row">
<text class="cost-label">优惠金额</text> <text class="info-label">物流运费</text>
<text class="cost-value discount" <text class="info-value">{{ orderDetail.shippingFee || "5.00" }}</text>
>-¥{{ orderDetail.discountAmount }}</text
>
</view> </view>
<view class="cost-item total"> <view class="info-row">
<text class="cost-label">实付金额</text> <text class="info-label">优惠券</text>
<text class="cost-value">¥{{ orderDetail.totalAmount }}</text> <text class="info-value">{{
orderDetail.discountAmount > 0 ? "无" : "无"
}}</text>
</view> </view>
</view> <view class="info-row total">
<text class="info-label">合计实付</text>
<!-- 收货信息 --> <text class="info-value total-amount">{{
<view class="address-section" v-if="hasPhysicalGoods"> orderDetail.totalAmount
<view class="section-title">收货信息</view>
<view class="address-info" v-if="orderDetail.address">
<view class="receiver-info">
<text class="receiver-name">{{ orderDetail.address.name }}</text>
<text class="receiver-phone">{{ orderDetail.address.phone }}</text>
</view>
<text class="receiver-address">{{
orderDetail.address.fullAddress
}}</text> }}</text>
</view> </view>
<view class="no-address" v-else> <view class="info-row">
<text>该订单无需收货地址</text> <text class="info-label">积分</text>
<text class="info-value">{{ orderDetail.points || "已获得1分" }}</text>
</view>
<view class="info-row">
<text class="info-label">支付方式</text>
<text class="info-value">{{
orderDetail.payMethod || "线上支付"
}}</text>
</view>
<view class="info-row">
<text class="info-label">支付时间</text>
<text class="info-value">{{
formatTime(orderDetail.payTime) || formatTime(orderDetail.createTime)
}}</text>
</view>
<view class="info-row">
<text class="info-label">预约发货时间</text>
<text class="info-value">{{
orderDetail.deliveryDate || formatTime(orderDetail.createTime)
}}</text>
</view>
<view class="info-row">
<text class="info-label">实际发货时间</text>
<text class="info-value">{{
formatTime(orderDetail.shippingTime) ||
formatTime(orderDetail.createTime)
}}</text>
</view>
<view class="info-row">
<text class="info-label">备注</text>
<text class="info-value">{{ orderDetail.remark || "XXXX" }}</text>
</view> </view>
</view> </view>
<!-- 底部按钮占位div -->
<view class="bottom-placeholder"></view>
<!-- 底部操作 --> <!-- 底部操作 -->
<view class="bottom-actions" v-if="showBottomActions"> <!-- <view class="bottom-actions">
<button <button class="action-btn secondary" @click="goBack">
class="action-btn secondary" {{ orderDetail.status === 0 ? "申请售后" : "返回" }}
v-if="orderDetail.status === 0"
@click="cancelOrder"
>
取消订单
</button> </button>
<button <button class="action-btn primary" @click="handleMainAction">
class="action-btn primary" {{ getMainActionText() }}
v-if="orderDetail.status === 0"
@click="payOrder"
>
立即支付
</button> </button>
<button </view> -->
class="action-btn primary"
v-if="orderDetail.status === 3"
@click="buyAgain"
>
再次购买
</button>
</view>
<!-- 权益码弹窗 --> <!-- 权益码弹窗 -->
<view <view
@ -188,6 +196,12 @@ export default {
totalAmount: "0.00", totalAmount: "0.00",
goodsAmount: "0.00", goodsAmount: "0.00",
discountAmount: "0.00", discountAmount: "0.00",
shippingFee: "5.00",
points: "",
remark: "",
deliveryDate: "",
trackingNo: "",
shippingTime: "",
createTime: "", createTime: "",
payTime: "", payTime: "",
payMethod: "", payMethod: "",
@ -211,6 +225,9 @@ export default {
if (options.id) { if (options.id) {
this.orderId = options.id; this.orderId = options.id;
this.loadOrderDetail(); this.loadOrderDetail();
} else {
// ID使
this.loadMockData();
} }
}, },
methods: { methods: {
@ -231,6 +248,67 @@ export default {
} }
}, },
//
loadMockData() {
this.orderDetail = {
id: "mock001",
orderNo: "238232342424234423",
status: 2, //
packageName: "食在扬州|世界美食之都巡礼",
packageId: "pkg001",
totalAmount: "699.00",
goodsAmount: "699.00",
discountAmount: "0.00",
shippingFee: "0.00",
points: "已获得1分",
remark: "XXXX",
deliveryDate: "2025-08-10",
trackingNo: "SF120025020202",
shippingTime: "2025-07-15 01:46:25",
createTime: "2025-07-15 00:46:25",
payTime: "2025-07-15 00:46:25",
payMethod: "线上支付",
equityCode: "EPIC2024010112345",
qrcode: "/static/image/qrcode-sample.png",
goodsList: [
{
id: 1,
name: "IP数字资产",
type: 1,
description: "在数字资产相册中查看",
price: "99.00",
quantity: 1,
},
{
id: 2,
name: "IP文创公仔",
type: 2,
description: "这里是XXX相仿介绍介绍",
price: "150.00",
quantity: 1,
},
{
id: 3,
name: "XXX园叮门票",
type: 3,
description: "这里是XXX园叮门票的介绍介绍介绍",
price: "50.00",
quantity: 1,
},
],
address: {
name: "XX先生",
phone: "183****1234",
fullAddress: "江苏省苏州市姑苏区XXXXXX",
province_text: "江苏省",
city_text: "苏州市",
district_text: "姑苏区",
detail_addr: "XXXXXX",
is_default: 1,
},
};
},
// //
getStatusIcon(status) { getStatusIcon(status) {
const iconMap = { const iconMap = {
@ -246,25 +324,57 @@ export default {
// //
getStatusText(status) { getStatusText(status) {
const statusMap = { const statusMap = {
0: "待付款", 0: "待使用",
1: "待使用", 1: "待收货",
2: "待收货", 2: "待收货",
3: "已完成", 3: "已完成",
4: "售后/退款", 4: "用户已驳回",
}; };
return statusMap[status] || "未知状态"; return statusMap[status] || "未知状态";
}, },
// //
getStatusDesc(status) { getStatusClass(status) {
const descMap = { const classMap = {
0: "请尽快完成支付", 0: "status-pending",
1: "权益商品可随时使用", 1: "status-waiting",
2: "商品正在配送中", 2: "status-shipping",
3: "订单已完成,感谢您的购买", 3: "status-completed",
4: "退款处理中", 4: "status-rejected",
};
return classMap[status] || "status-default";
},
//
getGoodsActionText(type) {
const textMap = {
1: "去查看",
2: "查看物流",
3: "已使用",
}; };
return descMap[status] || ""; return textMap[type] || "去查看";
},
//
getGoodsActionClass(type) {
const classMap = {
1: "btn-view",
2: "btn-logistics",
3: "btn-used",
};
return classMap[type] || "btn-view";
},
//
getMainActionText() {
const textMap = {
0: "立即支付",
1: "返回",
2: "返回",
3: "返回",
4: "返回",
};
return textMap[this.orderDetail.status] || "返回";
}, },
// //
@ -353,6 +463,20 @@ export default {
}); });
}, },
//
goBack() {
uni.navigateBack();
},
//
handleMainAction() {
if (this.orderDetail.status === 0) {
this.payOrder();
} else {
this.goBack();
}
},
// //
formatTime(time) { formatTime(time) {
if (!time) return ""; if (!time) return "";
@ -367,58 +491,77 @@ export default {
// API - // API -
async getOrderDetail(orderId) { async getOrderDetail(orderId) {
// API // API - ID
return new Promise((resolve) => { return new Promise((resolve) => {
setTimeout(() => { setTimeout(() => {
// ID
const statusMapping = {
1: 0, // 使
2: 1, //
3: 2, //
4: 3, //
5: 4, //
};
const orderStatus = statusMapping[orderId] || 1;
const mockData = { const mockData = {
code: 200, code: 200,
data: { data: {
id: orderId, id: orderId,
orderNo: "EQ202401011234567", orderNo: "238232342424234423",
status: 1, status: orderStatus,
packageName: "Epic Soul限定权益包", packageName: "食在扬州|世界美食之都巡礼",
packageId: "pkg001", packageId: "pkg001",
totalAmount: "249.00", totalAmount: "699.00",
goodsAmount: "299.00", goodsAmount: "699.00",
discountAmount: "50.00", discountAmount: "0.00",
createTime: "2024-01-01 12:00:00", shippingFee: "0.00",
payTime: "2024-01-01 12:05:00", points: "已获得1分",
payMethod: "微信支付", remark: "XXXX",
deliveryDate: "2025-08-10",
trackingNo: orderStatus >= 1 ? "SF120025020202" : "--",
shippingTime: orderStatus >= 2 ? "2025-07-15 01:46:25" : "",
createTime: "2025-07-15 00:46:25",
payTime: orderStatus >= 1 ? "2025-07-15 00:46:25" : "",
payMethod: "线上支付",
equityCode: "EPIC2024010112345", equityCode: "EPIC2024010112345",
qrcode: "/static/image/qrcode-sample.png", qrcode: "/static/image/qrcode-sample.png",
goodsList: [ goodsList: [
{ {
id: 1, id: 1,
name: "数字藏品-桃子系列", name: "IP数字资产",
type: 1, type: 1,
description: "在数字资产相册中查看",
price: "99.00", price: "99.00",
quantity: 1, quantity: 1,
image: "/static/image/goods1.jpg",
spec: "限量版",
}, },
{ {
id: 2, id: 2,
name: "文创周边产品", name: "IP文创公仔",
type: 2, type: 2,
description: "这里是XXX相仿介绍介绍",
price: "150.00", price: "150.00",
quantity: 1, quantity: 1,
image: "/static/image/goods2.jpg",
spec: "桃花主题",
}, },
{ {
id: 3, id: 3,
name: "君道苏州体验门票", name: "XXX园叮门票",
type: 3, type: 3,
description: "这里是XXX园叮门票的介绍介绍介绍",
price: "50.00", price: "50.00",
quantity: 1, quantity: 1,
image: "/static/image/goods3.jpg",
spec: "成人票",
}, },
], ],
address: { address: {
name: "张三", name: "XX先生",
phone: "138****8888", phone: "183****1234",
fullAddress: "江苏省苏州市工业园区某某街道某某小区1号楼101室", fullAddress: "江苏省苏州市姑苏区XXXXXX",
province_text: "江苏省",
city_text: "苏州市",
district_text: "姑苏区",
detail_addr: "XXXXXX",
is_default: 1,
}, },
}, },
}; };
@ -443,120 +586,151 @@ export default {
.order-detail-container { .order-detail-container {
min-height: 100vh; min-height: 100vh;
background-color: #f5f5f5; background-color: #f5f5f5;
padding-bottom: 140rpx;
} }
// //
.status-section { .status-header {
background-color: #fff; background-color: #fff;
padding: 40rpx 30rpx; padding: 20rpx 30rpx;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between;
margin-bottom: 20rpx; margin-bottom: 20rpx;
} }
.status-icon { .status-badge {
margin-right: 30rpx; padding: 8rpx 16rpx;
border-radius: 20rpx;
font-size: 24rpx;
color: #fff;
.icon { &.status-pending {
width: 80rpx; background-color: #ff9500;
height: 80rpx;
} }
}
.status-info { &.status-waiting {
flex: 1; background-color: #007aff;
}
&.status-shipping {
background-color: #34c759;
}
&.status-completed {
background-color: #666;
}
&.status-rejected {
background-color: #ff3b30;
}
} }
.status-text { .order-title {
display: block;
font-size: 32rpx; font-size: 32rpx;
font-weight: bold; font-weight: 600;
color: #333; color: #333;
margin-bottom: 10rpx;
}
.status-desc {
font-size: 26rpx;
color: #666;
} }
// //
.section-title { .section-title {
font-size: 30rpx; font-size: 28rpx;
font-weight: bold; font-weight: 600;
color: #333; color: #333;
margin-bottom: 30rpx; margin-bottom: 24rpx;
} }
// .section-label {
.order-info-section, font-size: 28rpx;
.package-section, color: #333;
.goods-section, margin-bottom: 16rpx;
.equity-section, }
.cost-section,
//
.address-section { .address-section {
background-color: #fff; background-color: #fff;
padding: 30rpx; padding: 30rpx;
margin-bottom: 20rpx; margin-bottom: 20rpx;
} }
.info-item { .address-card {
display: flex; background-color: #f8f9fa;
align-items: center; border-radius: 12rpx;
margin-bottom: 20rpx; padding: 24rpx;
}
&:last-child { .address-text {
margin-bottom: 0; font-size: 26rpx;
} color: #333;
line-height: 1.5;
margin-bottom: 16rpx;
} }
.label { .contact-info {
font-size: 28rpx; display: flex;
color: #666; gap: 20rpx;
width: 160rpx;
} }
.value { .contact-name,
flex: 1; .contact-phone {
font-size: 28rpx; font-size: 26rpx;
color: #333; color: #666;
} }
.copy-btn { //
font-size: 24rpx; .delivery-section {
color: #007aff; background-color: #fff;
padding: 8rpx 16rpx; padding: 30rpx;
border: 1px solid #007aff; margin-bottom: 20rpx;
border-radius: 20rpx;
} }
// //
.package-name { .product-title {
background-color: #fff;
padding: 20rpx 30rpx;
font-size: 28rpx; font-size: 28rpx;
font-weight: 600;
color: #333; color: #333;
background-color: #f8f9fa; margin-bottom: 20rpx;
padding: 20rpx;
border-radius: 12rpx;
} }
// //
.goods-section {
background-color: #fff;
padding: 0;
margin-bottom: 20rpx;
}
.goods-item { .goods-item {
display: flex; display: flex;
align-items: center; align-items: flex-start;
padding: 20rpx 0; padding: 30rpx;
border-bottom: 1px solid #f0f0f0; border-bottom: 1rpx solid #f0f0f0;
&:last-child { &:last-child {
border-bottom: none; border-bottom: none;
} }
} }
.goods-image { .goods-checkbox {
width: 120rpx;
height: 120rpx;
border-radius: 12rpx;
margin-right: 20rpx; margin-right: 20rpx;
margin-top: 8rpx;
}
.checkbox-icon {
width: 150rpx;
height:150rpx;
image{
width: 100%;
height: 100%;
border-radius: 10rpx;
}
}
.goods-content {
flex: 1;
display: flex;
justify-content: space-between;
align-items: flex-start;
} }
.goods-info { .goods-info {
@ -565,80 +739,52 @@ export default {
} }
.goods-name { .goods-name {
display: block;
font-size: 28rpx; font-size: 28rpx;
color: #333; color: #333;
font-weight: 600;
margin-bottom: 8rpx; margin-bottom: 8rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} }
.goods-type { .goods-desc {
display: block;
font-size: 24rpx;
color: #999;
margin-bottom: 8rpx;
}
.goods-spec {
font-size: 24rpx; font-size: 24rpx;
color: #666; color: #666;
line-height: 1.4;
} }
.goods-price { .goods-actions {
text-align: right; flex-shrink: 0;
}
.price {
display: block;
font-size: 28rpx;
color: #ff4757;
font-weight: bold;
margin-bottom: 5rpx;
} }
.quantity { .action-btn {
padding: 12rpx 24rpx;
border-radius: 20rpx;
font-size: 24rpx; font-size: 24rpx;
color: #999; border: none;
}
//
.equity-card {
display: flex;
align-items: center;
padding: 30rpx;
background-color: #f8f9fa;
border-radius: 12rpx;
border: 2rpx dashed #007aff;
}
.equity-info { &.btn-view {
flex: 1; background-color: #f0f0f0;
} color: #666;
}
.equity-label { &.btn-logistics {
display: block; background-color: #007aff;
font-size: 26rpx; color: #fff;
color: #666; }
margin-bottom: 10rpx;
}
.equity-code { &.btn-used {
font-size: 32rpx; background-color: #34c759;
color: #333; color: #fff;
font-weight: bold; }
} }
.equity-action { //
.view-qr { .order-info-section {
font-size: 26rpx; background-color: #fff;
color: #007aff; padding: 30rpx;
} margin-bottom: 20rpx;
} }
// .info-row {
.cost-item {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
@ -649,62 +795,40 @@ export default {
} }
&.total { &.total {
padding-top: 20rpx; padding-top: 16rpx;
border-top: 1px solid #f0f0f0; border-top: 1rpx solid #f0f0f0;
margin-top: 24rpx;
.cost-label,
.cost-value {
font-size: 32rpx;
font-weight: bold;
}
} }
} }
.cost-label { .info-label {
font-size: 28rpx; font-size: 26rpx;
color: #666; color: #666;
} }
.cost-value { .info-value {
font-size: 28rpx; font-size: 26rpx;
color: #333; color: #333;
&.discount { &.total-amount {
color: #ff4757; font-size: 28rpx;
font-weight: 600;
color: #ff3b30;
} }
} }
//
.receiver-info {
display: flex;
align-items: center;
margin-bottom: 15rpx;
}
.receiver-name {
font-size: 28rpx;
color: #333;
font-weight: bold;
margin-right: 20rpx;
}
.receiver-phone {
font-size: 28rpx;
color: #666;
}
.receiver-address {
font-size: 26rpx;
color: #666;
line-height: 1.5;
}
.no-address { .no-address {
text-align: center; text-align: center;
padding: 30rpx; padding: 30rpx;
color: #999; color: #999;
} }
//
.bottom-placeholder {
height: 180rpx;
padding-bottom: env(safe-area-inset-bottom);
}
// //
.bottom-actions { .bottom-actions {
position: fixed; position: fixed;
@ -713,26 +837,28 @@ export default {
right: 0; right: 0;
background-color: #fff; background-color: #fff;
padding: 20rpx 30rpx; padding: 20rpx 30rpx;
border-top: 1px solid #eee; padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
border-top: 1rpx solid #eee;
display: flex; display: flex;
gap: 20rpx; gap: 20rpx;
}
.action-btn { .action-btn {
flex: 1; flex: 1;
height: 80rpx; height: 80rpx;
border-radius: 40rpx; border-radius: 40rpx;
font-size: 28rpx; font-size: 28rpx;
border: none; border: none;
font-weight: 600;
&.secondary {
background-color: #f0f0f0; &.secondary {
color: #666; background-color: #f0f0f0;
} color: #666;
}
&.primary { &.primary {
background-color: #007aff; background-color: #333;
color: #fff; color: #fff;
}
} }
} }

325
subPackages/orderQy/list.vue

@ -19,11 +19,18 @@
scroll-y scroll-y
@scrolltolower="loadMore" @scrolltolower="loadMore"
refresher-enabled refresher-enabled
:show-scrollbar="false"
:refresher-triggered="refresherTriggered" :refresher-triggered="refresherTriggered"
@refresherrefresh="onRefresh" @refresherrefresh="onRefresh"
enhanced
> >
<!-- 订单项 --> <!-- 订单项 -->
<view class="order-item" v-for="order in orderList" :key="order.id"> <view
class="order-item"
v-for="order in orderList"
:key="order.id"
@click="goToOrderDetail(order)"
>
<!-- 订单头部 --> <!-- 订单头部 -->
<view class="order-header"> <view class="order-header">
<view class="order-left"> <view class="order-left">
@ -67,7 +74,7 @@
<button <button
class="action-btn" class="action-btn"
:class="[getActionBtnClass(goods.type)]" :class="[getActionBtnClass(goods.type)]"
@click="handleGoodsAction(goods)" @click.stop="handleGoodsAction(goods)"
> >
{{ getActionBtnText(goods.type) }} {{ getActionBtnText(goods.type) }}
</button> </button>
@ -91,7 +98,7 @@
<view class="order-actions"> <view class="order-actions">
<button <button
class="equity-code-btn" class="equity-code-btn"
@click="showEquityCode(order)" @click.stop="showEquityCode(order)"
v-if="order.status !== 0" v-if="order.status !== 0"
> >
<text class="btn-icon">🎫</text> <text class="btn-icon">🎫</text>
@ -101,10 +108,15 @@
</view> </view>
</view> </view>
<!-- 空状态 --> <!-- 空状态 -->
<view class="empty-state" v-if="goodsList&&goodsList.length==0||loading"> <view
class="empty-state"
v-if="(goodsList && goodsList.length == 0) || loading"
>
<image <image
class="empty-image" class="empty-image"
:src="showImg('/uploads/20250808/c16267f9cc2b7a68bf23713b5847987e.png')" :src="
showImg('/uploads/20250808/c16267f9cc2b7a68bf23713b5847987e.png')
"
mode="aspectFit" mode="aspectFit"
/> />
<text class="empty-text">暂无订单</text> <text class="empty-text">暂无订单</text>
@ -322,10 +334,11 @@ export default {
// //
reserveDelivery(goods) { reserveDelivery(goods) {
// //
uni.showToast({ uni.navigateTo({
title: "预约发货", url: `/subPackages/orderQy/confrim?goodsId=${
icon: "none", goods.id
}&goodsName=${encodeURIComponent(goods.name)}`,
}); });
}, },
@ -338,6 +351,13 @@ export default {
}); });
}, },
//
goToOrderDetail(order) {
uni.navigateTo({
url: `/subPackages/orderQy/detail?id=${order.id}&orderNo=${order.orderNo}`,
});
},
// //
showEquityCode(order) { showEquityCode(order) {
this.currentEquity = { this.currentEquity = {
@ -386,6 +406,39 @@ export default {
code: 200, code: 200,
data: { data: {
list: [ list: [
{
id: 1,
orderNo: "EQ202401011234567",
packageName: "Epic Soul限定权益包",
status: 1,
totalAmount: "299.00",
createTime: "2024-01-01 12:00:00",
qrcode: "/static/image/qrcode-sample.png",
equityCode: "EPIC2024010112345",
goodsList: [
{
id: 1,
name: "数字藏品-桃子系列",
type: 1,
price: "99.00",
image: "/static/image/goods1.jpg",
},
{
id: 2,
name: "文创周边产品",
type: 2,
price: "150.00",
image: "/static/image/goods2.jpg",
},
{
id: 3,
name: "君道苏州体验门票",
type: 3,
price: "50.00",
image: "/static/image/goods3.jpg",
},
],
},
{ {
id: 1, id: 1,
orderNo: "EQ202401011234567", orderNo: "EQ202401011234567",
@ -432,20 +485,31 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
//
$primary-color: #667eea;
$secondary-color: #f8f9fa;
$text-primary: #2d3748;
$text-secondary: #718096;
$text-muted: #a0aec0;
$border-color: #e2e8f0;
$success-color: #48bb78;
$warning-color: #ed8936;
$danger-color: #f56565;
$bg-light: #f7fafc;
.order-list-container { .order-list-container {
min-height: 100vh; min-height: 100vh;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); background-color: $bg-light;
} }
// Tab // Tab
.tab-container { .tab-container {
display: flex; display: flex;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); background-color: $primary-color;
border-bottom: 1px solid rgba(255, 255, 255, 0.2); border-bottom: 1px solid rgba(255, 255, 255, 0.1);
position: sticky; position: sticky;
top: 0; top: 0;
z-index: 10; z-index: 10;
box-shadow: 0 4rpx 20rpx rgba(102, 126, 234, 0.3);
} }
.tab-item { .tab-item {
@ -458,8 +522,7 @@ export default {
&.active { &.active {
.tab-text { .tab-text {
color: #ffffff; color: #ffffff;
font-weight: 700; font-weight: 600;
transform: scale(1.05);
} }
&::after { &::after {
@ -468,11 +531,10 @@ export default {
bottom: 0; bottom: 0;
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
width: 80rpx; width: 60rpx;
height: 6rpx; height: 4rpx;
background: linear-gradient(45deg, #ffffff, #f1f2f6); background-color: #ffffff;
border-radius: 3rpx; border-radius: 2rpx;
box-shadow: 0 2rpx 8rpx rgba(255, 255, 255, 0.4);
} }
} }
@ -487,29 +549,27 @@ export default {
font-size: 26rpx; font-size: 26rpx;
color: #ffffff; color: #ffffff;
font-weight: 600; font-weight: 600;
letter-spacing: 0.5rpx;
transition: all 0.3s ease; transition: all 0.3s ease;
} }
// //
.order-scroll { .order-scroll {
height: calc(100vh - 120rpx); height: calc(100vh - 120rpx);
margin: 20rpx; padding: 0 24rpx;
width: 710rpx; width: 702rpx;
} }
.order-item { .order-item {
background-color: #fff; background-color: #ffffff;
border-radius: 24rpx; border-radius: 20rpx;
margin-bottom: 24rpx;
overflow: hidden; overflow: hidden;
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.08); box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
border: 1px solid rgba(255, 255, 255, 0.8); border: none;
transition: all 0.3s ease; transition: all 0.3s ease;
margin-top: 40rpx;
&:hover { &:active {
transform: translateY(-4rpx); transform: scale(0.98);
box-shadow: 0 16rpx 48rpx rgba(0, 0, 0, 0.12);
} }
} }
@ -517,10 +577,9 @@ export default {
.order-header { .order-header {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: flex-start; align-items: center;
padding: 24rpx 30rpx; padding: 24rpx 28rpx 20rpx;
background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%); background: $secondary-color;
border-bottom: 1px solid #e9ecef;
} }
.order-left { .order-left {
@ -534,16 +593,17 @@ export default {
} }
.order-label { .order-label {
font-size: 22rpx; font-size: 24rpx;
color: #8e9aaf; color: $text-muted;
font-weight: 500; font-weight: 500;
} }
.order-number { .order-number {
font-size: 26rpx; font-size: 28rpx;
color: #495057; color: $text-primary;
font-weight: 600; font-weight: 600;
font-family: "SF Mono", "Monaco", "Cascadia Code", monospace; font-family: -apple-system, BlinkMacSystemFont, "PingFang SC",
"Helvetica Neue", STHeiti, "Microsoft Yahei", Tahoma, Simsun, sans-serif;
} }
.order-status-wrapper { .order-status-wrapper {
@ -552,41 +612,35 @@ export default {
} }
.order-status { .order-status {
font-size: 24rpx; font-size: 26rpx;
padding: 10rpx 20rpx; padding: 12rpx 20rpx;
border-radius: 50rpx; border-radius: 24rpx;
font-weight: 600; font-weight: 600;
letter-spacing: 0.5rpx; letter-spacing: 0.5rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
&.status-pending { &.status-pending {
background: linear-gradient(45deg, #fff3cd, #ffeaa7); background: #fff3cd;
color: #856404; color: #856404;
border: 1px solid #ffeaa7;
} }
&.status-waiting { &.status-waiting {
background: linear-gradient(45deg, #d4edda, #00b894); background: $success-color;
color: #ffffff; color: #ffffff;
border: 1px solid #00b894;
} }
&.status-shipping { &.status-shipping {
background: linear-gradient(45deg, #cce5ff, #0984e3); background: $primary-color;
color: #ffffff; color: #ffffff;
border: 1px solid #0984e3;
} }
&.status-completed { &.status-completed {
background: linear-gradient(45deg, #e2e3e5, #636e72); background: $text-secondary;
color: #ffffff; color: #ffffff;
border: 1px solid #636e72;
} }
&.status-refund { &.status-refund {
background: linear-gradient(45deg, #f8d7da, #e17055); background: $danger-color;
color: #ffffff; color: #ffffff;
border: 1px solid #e17055;
} }
} }
@ -594,22 +648,19 @@ export default {
.package-section { .package-section {
display: flex; display: flex;
align-items: center; align-items: center;
padding: 20rpx 30rpx; padding: 20rpx 28rpx;
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
margin: 0 20rpx; margin: 0 20rpx;
border-radius: 16rpx; margin-top: -6rpx;
margin-top: -10rpx;
box-shadow: 0 4rpx 20rpx rgba(102, 126, 234, 0.3);
} }
.package-icon { .package-icon {
font-size: 32rpx; font-size: 36rpx;
margin-right: 16rpx; margin-right: 20rpx;
} }
.package-name { .package-name {
font-size: 28rpx; font-size: 30rpx;
color: #ffffff; color: $text-primary;
font-weight: 600; font-weight: 600;
letter-spacing: 0.5rpx; letter-spacing: 0.5rpx;
} }
@ -620,11 +671,11 @@ export default {
} }
.goods-title { .goods-title {
font-size: 26rpx; font-size: 28rpx;
color: #495057; color: $text-primary;
font-weight: 600; font-weight: 600;
padding: 0 30rpx 16rpx; padding: 0 28rpx 16rpx;
border-bottom: 2rpx solid #e9ecef; border-bottom: 2rpx solid $border-color;
margin-bottom: 20rpx; margin-bottom: 20rpx;
} }
@ -635,30 +686,29 @@ export default {
.goods-item { .goods-item {
display: flex; display: flex;
align-items: center; align-items: center;
padding: 24rpx 20rpx; padding: 20rpx;
margin-bottom: 16rpx; margin-bottom: 12rpx;
background: #ffffff; background: #ffffff;
border-radius: 16rpx; border-radius: 16rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08); border: 1px solid rgba(0, 0, 0, 0.05);
border: 1px solid #f1f3f4;
transition: all 0.3s ease; transition: all 0.3s ease;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
&:hover {
transform: translateY(-2rpx);
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.12);
}
&:last-child { &:last-child {
margin-bottom: 0; margin-bottom: 0;
} }
&:active {
transform: scale(0.98);
background: #f8f9fa;
}
} }
.goods-image { .goods-image {
width: 100rpx; width: 100rpx;
height: 100rpx; height: 100rpx;
border-radius: 16rpx; border-radius: 12rpx;
margin-right: 20rpx; margin-right: 20rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
} }
.goods-info { .goods-info {
@ -668,8 +718,8 @@ export default {
.goods-name { .goods-name {
display: block; display: block;
font-size: 26rpx; font-size: 30rpx;
color: #2d3748; color: $text-primary;
font-weight: 600; font-weight: 600;
margin-bottom: 12rpx; margin-bottom: 12rpx;
line-height: 1.4; line-height: 1.4;
@ -685,48 +735,47 @@ export default {
} }
.goods-type { .goods-type {
font-size: 22rpx; font-size: 24rpx;
color: #718096; color: $text-secondary;
background: #edf2f7; background: $secondary-color;
padding: 6rpx 12rpx; padding: 8rpx 16rpx;
border-radius: 20rpx; border-radius: 20rpx;
font-weight: 500; font-weight: 500;
} }
.goods-price { .goods-price {
font-size: 26rpx; font-size: 26rpx;
color: #e53e3e; color: $danger-color;
font-weight: 700; font-weight: 600;
font-family: "SF Mono", "Monaco", "Cascadia Code", monospace; font-family: "SF Mono", "Monaco", "Cascadia Code", monospace;
} }
.goods-action { .goods-action {
.action-btn { .action-btn {
padding: 2rpx 25rpx; padding: 0rpx 20rpx;
border-radius: 24rpx; border-radius: 20rpx;
font-size: 22rpx; font-size: 24rpx;
font-weight: 600; font-weight: 600;
border: none; border: none;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.15); color: #ffffff;
transition: all 0.3s ease; transition: all 0.3s ease;
min-width: 100rpx;
text-align: center;
&:active { &:active {
transform: scale(0.95); transform: scale(0.95);
} }
&.btn-view { &.btn-view {
background: linear-gradient(45deg, #667eea, #764ba2); background: $primary-color;
color: #fff;
} }
&.btn-reserve { &.btn-reserve {
background: linear-gradient(45deg, #f093fb, #f5576c); background: $warning-color;
color: #fff;
} }
&.btn-use { &.btn-use {
background: linear-gradient(45deg, #4facfe, #00f2fe); background: $success-color;
color: #fff;
} }
} }
} }
@ -736,16 +785,15 @@ export default {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 24rpx 30rpx; padding: 24rpx 28rpx;
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); background: $secondary-color;
border-top: 1px solid #dee2e6;
margin-top: 20rpx; margin-top: 20rpx;
} }
.order-info { .order-info {
flex: 1; flex: 1;
display: flex; display: flex;
gap: 40rpx; gap: 32rpx;
} }
.order-time-section, .order-time-section,
@ -757,39 +805,41 @@ export default {
.time-label, .time-label,
.total-label { .total-label {
font-size: 20rpx; font-size: 22rpx;
color: #8e9aaf; color: $text-muted;
font-weight: 500; font-weight: 500;
} }
.order-time { .order-time {
font-size: 24rpx; font-size: 26rpx;
color: #495057; color: $text-primary;
font-weight: 500; font-weight: 500;
font-family: "SF Mono", "Monaco", "Cascadia Code", monospace; font-family: -apple-system, BlinkMacSystemFont, "PingFang SC",
"Helvetica Neue", STHeiti, "Microsoft Yahei", Tahoma, Simsun, sans-serif;
} }
.order-total { .order-total {
font-size: 28rpx; font-size: 32rpx;
color: #e53e3e; color: $danger-color;
font-weight: 700; font-weight: 600;
font-family: "SF Mono", "Monaco", "Cascadia Code", monospace; font-family: -apple-system, BlinkMacSystemFont, "PingFang SC",
"Helvetica Neue", STHeiti, "Microsoft Yahei", Tahoma, Simsun, sans-serif;
} }
.order-actions { .order-actions {
.equity-code-btn { .equity-code-btn {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8rpx; gap: 10rpx;
padding: 0rpx 25rpx; padding: 2rpx 24rpx;
background: linear-gradient(45deg, #667eea, #764ba2); background: $primary-color;
color: #fff; color: #ffffff;
border-radius: 32rpx; border-radius: 24rpx;
font-size: 24rpx; font-size: 24rpx;
font-weight: 600; font-weight: 600;
border: none; border: none;
box-shadow: 0 4rpx 16rpx rgba(102, 126, 234, 0.4);
transition: all 0.3s ease; transition: all 0.3s ease;
box-shadow: 0 2rpx 8rpx rgba(102, 126, 234, 0.2);
&:active { &:active {
transform: scale(0.95); transform: scale(0.95);
@ -804,7 +854,7 @@ export default {
// //
.empty-state { .empty-state {
text-align: center; text-align: center;
padding: 200rpx 0; padding: 240rpx 40rpx;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -812,34 +862,37 @@ export default {
} }
.empty-image { .empty-image {
width: 200rpx; width: 240rpx;
height: 200rpx; height: 240rpx;
margin-bottom: 30rpx; margin-bottom: 40rpx;
opacity: 0.8;
} }
.empty-text { .empty-text {
font-size: 28rpx; font-size: 32rpx;
color: #999; color: $text-muted;
font-weight: 500;
} }
// //
.load-more, .load-more,
.no-more { .no-more {
text-align: center; text-align: center;
padding: 30rpx; padding: 40rpx;
} }
.load-text, .load-text,
.no-more-text { .no-more-text {
font-size: 26rpx; font-size: 28rpx;
color: #999; color: $text-muted;
font-weight: 500;
} }
// //
.equity-popup { .equity-popup {
width: 600rpx; width: 600rpx;
background-color: #fff; background-color: #ffffff;
border-radius: 20rpx; border-radius: 16rpx;
overflow: hidden; overflow: hidden;
} }
@ -848,18 +901,18 @@ export default {
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 30rpx; padding: 30rpx;
border-bottom: 1px solid #f0f0f0; border-bottom: 1px solid $border-color;
} }
.popup-title { .popup-title {
font-size: 32rpx; font-size: 32rpx;
font-weight: bold; font-weight: 600;
color: #333; color: $text-primary;
} }
.popup-close { .popup-close {
font-size: 40rpx; font-size: 40rpx;
color: #999; color: $text-muted;
} }
.popup-content { .popup-content {
@ -874,7 +927,7 @@ export default {
.qrcode-image { .qrcode-image {
width: 300rpx; width: 300rpx;
height: 300rpx; height: 300rpx;
border: 1px solid #eee; border: 1px solid $border-color;
border-radius: 12rpx; border-radius: 12rpx;
} }
@ -884,21 +937,21 @@ export default {
.code-label { .code-label {
font-size: 28rpx; font-size: 28rpx;
color: #666; color: $text-secondary;
margin-right: 10rpx; margin-right: 10rpx;
} }
.code-value { .code-value {
font-size: 28rpx; font-size: 28rpx;
color: #333; color: $text-primary;
font-weight: bold; font-weight: 600;
background-color: #f8f9fa; background-color: $secondary-color;
padding: 8rpx 16rpx; padding: 8rpx 16rpx;
border-radius: 8rpx; border-radius: 8rpx;
} }
.code-tip { .code-tip {
font-size: 24rpx; font-size: 24rpx;
color: #999; color: $text-muted;
} }
</style> </style>

687
subPackages/user/travelerList.vue

@ -1,6 +1,6 @@
<template> <template>
<view class="bg"> <view class="bg">
<!-- <view class="cancat-nav flex-around"> <!-- <view class="cancat-nav flex-around">
<view :class="['concat-nav-item',showType===0?'active':'']" @click="showType=0"> <view :class="['concat-nav-item',showType===0?'active':'']" @click="showType=0">
<view>出行人信息</view> <view>出行人信息</view>
<view v-if="showType===0" class="active-bar"></view> <view v-if="showType===0" class="active-bar"></view>
@ -10,30 +10,28 @@
<view v-if="showType===1" class="active-bar"></view> <view v-if="showType===1" class="active-bar"></view>
</view> </view>
</view> --> </view> -->
<!-- 出行人信息 --> <!-- 出行人信息 -->
<view v-if="showType===0"> <view v-if="showType === 0">
<view class="item" v-for="(item,index) in travelList" :key="index"> <view class="item" v-for="(item, index) in travelList" :key="index">
<view class="name"> <view class="name">
<view class=""> <view class="">
{{item.name}} {{ item.name }}
</view> </view>
<view class=""> <view class="">
{{item.tel}} {{ item.tel }}
<span v-if="item.is_default==1">默认</span> <span v-if="item.is_default == 1">默认</span>
</view> </view>
</view> </view>
<view class="idcard"> <view class="idcard">
<view class=""> <view class=""> {{ item.document_type_text }}: </view>
{{item.document_type_text}}: <view class="">
</view> {{ item.id_number }}
<view class=""> </view>
{{item.id_number}} </view>
</view> <view class="item-btn">
</view> <view class="choice">
<view class="item-btn"> <!-- <image src="https://static.ticket.sz-trip.com/yandu/images/user/dui.png" mode="aspectFill"
<view class="choice">
<!-- <image src="https://static.ticket.sz-trip.com/yandu/images/user/dui.png" mode="aspectFill"
v-if="item.is_default==1"> v-if="item.is_default==1">
</image> </image>
<view class="yuan" v-else @click.stop="defaultC(item)"> <view class="yuan" v-else @click.stop="defaultC(item)">
@ -42,298 +40,359 @@
<view class=""> <view class="">
默认出行人 默认出行人
</view> --> </view> -->
</view> </view>
<view class="btn-list"> <view class="btn-list">
<view class="btn-item" @click.stop="edit(item.id)"> <view class="btn-item" @click.stop="edit(item.id)"> 修改 </view>
修改 <view class="btn-item" @click.stop="delet(item)"> 删除 </view>
</view> </view>
<view class="btn-item" @click.stop="delet(item)"> </view>
删除 </view>
</view> </view>
</view>
</view> <!-- 收货地址 -->
</view> <view v-else>
</view> <view
class="item"
<!-- 收货地址 --> v-for="(item, index) in addressList"
<view v-else> :key="index"
<view class="item" v-for="(item,index) in addressList" :key="index"> @click="selectAddressForOrder(item)"
<view class="name"> >
<view> <view class="name">
{{item.name}} <view>
</view> {{ item.name }}
<view class=""> </view>
{{item.tel}} <view class="">
<span v-if="item.is_default==1">默认</span> {{ item.tel }}
</view> <span v-if="item.is_default == 1">默认</span>
</view> </view>
<view class="idcard"> </view>
<view class=""> <view class="idcard">
收货地址: <view class=""> 收货地址: </view>
</view> <view class="text-overflow">
<view class="text-overflow"> {{ item.address }}
{{item.address}} </view>
</view> </view>
</view> <view class="item-btn" style="justify-content: flex-end">
<view class="item-btn" style="justify-content: flex-end;"> <view class="btn-list">
<view class="btn-list"> <view class="btn-item" @click.stop="edit(item.id)"> 修改 </view>
<view class="btn-item" @click.stop="edit(item.id)"> <view class="btn-item" @click.stop="delet(item)"> 删除 </view>
修改 </view>
</view> </view>
<view class="btn-item" @click.stop="delet(item)"> <!-- 选择指示器 -->
删除 <view class="select-indicator" v-if="isSelectMode">
</view> <uni-icons type="right" size="16" color="#6CA5AA" />
</view> </view>
</view> </view>
</view> </view>
</view>
<view class="btn-box">
<view class="btn-box"> <navigator
<navigator :url="showType ? '/subPackages/user/myAddressAdd' : '/subPackages/user/myContactsAdd'" class="btn"> :url="
{{showType ? '新增收货地址' : '添加联系人'}} showType
</navigator> ? '/subPackages/user/myAddressAdd'
</view> : '/subPackages/user/myContactsAdd'
</view> "
class="btn"
>
{{ showType ? "新增收货地址" : "添加联系人" }}
</navigator>
</view>
</view>
</template> </template>
<script> <script>
export default { export default {
name: "travelerList", name: "travelerList",
data() { data() {
return { return {
showType: 1, showType: 1,
travelList: [], travelList: [],
addressList: [] addressList: [],
}; isSelectMode: false, //
}, fromPage: "", //
onShow() { };
this.init() },
}, onLoad(options) {
methods: { //
init () { if (options.from) {
// this.isSelectMode = true;
// this.Post({}, "/api/user/contactList").then(res => { this.fromPage = options.from;
// if (res) this.travelList = res.data }
// }) },
onShow() {
// this.init();
this.Post({}, '/api/user/consigneeList').then(res => { },
if(res) this.addressList = res.data methods: {
}) init() {
}, //
delet(item) { // this.Post({}, "/api/user/contactList").then(res => {
let that = this // if (res) this.travelList = res.data
uni.showModal({ // })
title: '提示',
content: '确定要删除该出行人吗?', //
success: function(res) { this.Post({}, "/api/user/consigneeList").then((res) => {
if (res.confirm) { if (res) this.addressList = res.data;
that.Post({ });
id: item.id },
}, "/api/user/delDetail").then(res => { delet(item) {
if (res) { let that = this;
uni.showToast({ uni.showModal({
icon: "none", title: "提示",
title: res.msg content: "确定要删除该出行人吗?",
}) success: function (res) {
} if (res.confirm) {
that.init() that
}) .Post(
} else if (res.cancel) { {
console.log('用户点击取消'); id: item.id,
} },
} "/api/user/delDetail"
}); )
}, .then((res) => {
defaultC(item) { if (res) {
this.Post({ uni.showToast({
id: item.id, icon: "none",
is_default: 1 title: res.msg,
}, "/api/user/editContact").then(res => { });
if (res.code == 1) { }
this.travelList.forEach(i => i.is_default = 0) that.init();
item.is_default = !item.is_default });
} } else if (res.cancel) {
}) console.log("用户点击取消");
}, }
// },
edit(id){ });
let url = '' },
if(this.showType) { defaultC(item) {
url = '/subPackages/user/myAddressAdd?id='+id this.Post(
}else { {
url = "/subPackages/user/myContactsAdd?type=edit&id="+id id: item.id,
} is_default: 1,
uni.navigateTo({ },
url: url "/api/user/editContact"
}); ).then((res) => {
} if (res.code == 1) {
} this.travelList.forEach((i) => (i.is_default = 0));
} item.is_default = !item.is_default;
}
});
},
//
edit(id) {
let url = "";
if (this.showType) {
url = "/subPackages/user/myAddressAdd?id=" + id;
} else {
url = "/subPackages/user/myContactsAdd?type=edit&id=" + id;
}
uni.navigateTo({
url: url,
});
},
//
selectAddressForOrder(address) {
if (!this.isSelectMode) {
return; //
}
// 线
uni.$emit("addressSelected", {
address: address,
fromPage: this.fromPage,
});
// storage
uni.setStorageSync("selectedAddress", address);
uni.showToast({
title: "地址选择成功",
icon: "success",
});
setTimeout(() => {
uni.navigateBack();
}, 800);
},
},
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.bg { .bg {
position: relative; position: relative;
background: #F7F7F7; background: #f7f7f7;
height: 100vh; height: 100vh;
overflow-x: hidden; overflow-x: hidden;
padding-bottom: 200rpx; padding-bottom: 200rpx;
} }
.cancat-nav{ .cancat-nav {
width: 100%; width: 100%;
display: flex; display: flex;
height: 112rpx; height: 112rpx;
flex-shrink: 0; flex-shrink: 0;
background-color: #fff; background-color: #fff;
.concat-nav-item{ .concat-nav-item {
ffont-weight: 500; font-weight: 500;
font-size: 35rpx; font-size: 35rpx;
color: #000000; color: #000000;
height: 100%; height: 100%;
text-align: center; text-align: center;
position: relative; position: relative;
padding-top: 35rpx; padding-top: 35rpx;
} }
.concat-nav-item.active{ .concat-nav-item.active {
color: #000000; color: #000000;
} }
.active-bar{ .active-bar {
width: 73rpx; width: 73rpx;
height: 7rpx; height: 7rpx;
background: #515150; background: #515150;
border-radius: 3rpx; border-radius: 3rpx;
margin: auto; margin: auto;
position: absolute; position: absolute;
bottom: 0; bottom: 0;
left: 0; left: 0;
right: 0; right: 0;
} }
} }
.item { .item {
width: 697rpx; width: 697rpx;
background: #FFFFFF; background: #ffffff;
border-radius: 13rpx; border-radius: 13rpx;
margin: 28rpx auto 0; margin: 28rpx auto 0;
padding: 26rpx; padding: 26rpx;
position: relative;
.name,
.idcard { .name,
display: flex; .idcard {
font-size: 31rpx; display: flex;
font-weight: bold; font-size: 31rpx;
color: #333333; font-weight: bold;
color: #333333;
} }
.name { .name {
view:last-child{ view:last-child {
margin-left: 40rpx; margin-left: 40rpx;
} }
span { span {
padding: 3rpx 9rpx; padding: 3rpx 9rpx;
background: #515150; background: #515150;
border-radius: 7rpx; border-radius: 7rpx;
font-weight: bold; font-weight: bold;
font-size: 24rpx; font-size: 24rpx;
color: #FFFFFF; color: #ffffff;
margin-left: 15rpx; margin-left: 15rpx;
} }
} }
.idcard { .idcard {
margin-top: 26rpx; margin-top: 26rpx;
view:last-child { view:last-child {
margin-left: 14rpx; margin-left: 14rpx;
font-weight: 400; font-weight: 400;
max-width: 492rpx; max-width: 492rpx;
}
} }
}
.item-btn {
.item-btn { display: flex;
display: flex; align-items: center;
align-items: center; justify-content: space-between;
justify-content: space-between; margin-top: 40rpx;
margin-top: 40rpx;
.choice {
.choice { display: flex;
display: flex; align-items: center;
align-items: center;
view:last-child {
view:last-child { margin-left: 20rpx;
margin-left: 20rpx;
font-size: 27rpx;
font-size: 27rpx;
font-weight: 500;
font-weight: 500; color: #333333;
color: #333333; }
}
image {
image { width: 40rpx;
width: 40rpx; height: 40rpx;
height: 40rpx; }
}
.yuan {
.yuan { width: 40rpx;
width: 40rpx; height: 40rpx;
height: 40rpx; background: rgba(255, 200, 37, 0);
background: rgba(255, 200, 37, 0); border: 1rpx solid #999999;
border: 1rpx solid #999999; border-radius: 20rpx;
border-radius: 20rpx; }
} }
}
.btn-list {
.btn-list { display: flex;
display: flex; align-items: center;
align-items: center;
view {
view { width: 134rpx;
width: 134rpx; height: 54rpx;
height: 54rpx; background: #ffffff;
background: #FFFFFF; border: 1px solid #999999;
border: 1px solid #999999; border-radius: 27rpx;
border-radius: 27rpx;
font-size: 27rpx;
font-weight: 500;
font-size: 27rpx; color: #333333;
font-weight: 500; line-height: 52rpx;
color: #333333; text-align: center;
line-height: 52rpx; }
text-align: center;
} view:last-child {
margin-left: 14rpx;
view:last-child { }
margin-left: 14rpx; }
} }
} }
}
} .btn-box {
position: fixed;
.btn-box { bottom: 0;
position: fixed; left: 0;
bottom: 0; width: 100%;
left: 0; height: 200rpx;
width: 100%; background-color: #fff;
height: 200rpx;
background-color: #fff; .btn {
width: 697rpx;
.btn { line-height: 80rpx;
width: 697rpx; background: #6ca5aa;
line-height: 80rpx; border-radius: 37rpx;
background: #6CA5AA; font-weight: 500;
border-radius: 37rpx; font-size: 36rpx;
font-weight: 500; color: #fff;
font-size: 36rpx; text-align: center;
color: #fff; position: fixed;
text-align: center; bottom: 53rpx;
position: fixed; left: 26.67rpx;
bottom: 53rpx; }
left: 26.67rpx; }
}
} //
.select-indicator {
position: absolute;
right: 26rpx;
top: 50%;
transform: translateY(-50%);
background-color: rgba(108, 165, 170, 0.1);
border-radius: 50%;
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
}
</style> </style>

Loading…
Cancel
Save