Browse Source

静态

dev_des
1054425342@qq.com 2 months ago
parent
commit
d4cae0e13c
  1. 52
      common/index.js
  2. 25
      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. 256
      pages/index/iSoul.vue
  10. 14
      pages/index/index.vue
  11. 71
      pages/index/timeShopBank.vue
  12. 631
      pages/notes/detail.vue
  13. 445
      pages/notes/publish.vue
  14. 166
      subPackages/equityGoods/detail.vue
  15. 398
      subPackages/equityGoods/list.vue
  16. 339
      subPackages/memorialAlbum/detail.vue
  17. 219
      subPackages/memorialAlbum/index.vue
  18. 772
      subPackages/orderQy/confrim.vue
  19. 704
      subPackages/orderQy/detail.vue
  20. 325
      subPackages/orderQy/list.vue
  21. 177
      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,
};

25
components/DynamicIsland.vue

@ -16,9 +16,14 @@
>
<!-- 展开状态 -->
<view v-if="!actualCompactState" class="expanded-content">
<!-- <view style="display: flex;align-items: center;justify-content: center;color: white;" v-if="!(userInfo&&userInfo.token)">
去登录
</view> -->
<template >
<template v-if="styleType != 'timeShop'">
<view class="top-section">
<text class="welcome-text">{{ title }}</text>
<text class="welcome-text" v-if="userInfo&&userInfo.token">{{ title }}</text>
<text class="welcome-text" v-else @click="toLogin">hi 快去登录 ></text>
<view class="qr-code">
<image
style="width: 39rpx; height: 39rpx"
@ -41,6 +46,7 @@
<view class="action-section">
<text class="action-text">{{ actionText }}</text>
<image
@click="toWebView"
class="avatar"
src="https://epic.js-dyyj.com/uploads/20250728/7d9ba1fe109643681396cb03f60f3218.png"
mode="aspectFill"
@ -85,6 +91,7 @@
</view>
</view>
</template>
</template>
</view>
<!-- 紧凑状态 -->
@ -143,7 +150,7 @@ export default {
isExpanded: false,
statusBarHeight: 0,
isScrolled: false,
scrollThreshold: 160, // 160rpx
scrollThreshold: 140, // 160rpx
// props
currentTitle: "Hi!用户,欢迎回来~",
currentSubtitle: "2个权益 | 120时间银行",
@ -205,6 +212,11 @@ export default {
this.removeScrollListener();
},
methods: {
toLogin(){
uni.navigateTo({
url: "/pages/login/login",
});
},
handleToggle() {
if (this.isScrolled) {
//
@ -294,6 +306,7 @@ export default {
JSON.parse(uni.getStorageSync("userInfo"))) ||
this.$store.state.user.userInfo ||
{};
console.log(this.userInfo,'this.userInfo')
//
if (this.userInfo && this.userInfo.nickname) {
this.currentTitle = `Hi!${this.userInfo.nickname},欢迎回来~`;
@ -303,6 +316,11 @@ export default {
this.userInfo = {};
}
},
toWebView(){
uni.navigateTo({
url:'/subPackages/webPage/webPage?url='+'https://www.dayunyuanjian.cn/dist/#/chat-demo'
})
}
},
};
</script>
@ -410,10 +428,7 @@ export default {
.qr-code {
width: 32rpx;
height: 32rpx;
<<<<<<< HEAD
=======
>>>>>>> 402de12 (feat首页静态)
}
.qr-icon {

4
components/header.vue

@ -10,7 +10,7 @@
>
<!-- 左侧地区筛选和搜索 -->
<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>
<image
class="dropdown-icon"
@ -59,6 +59,7 @@ export default {
type: Boolean,
default: false,
},
selectedLocation:''
},
name: "header",
data() {
@ -67,7 +68,6 @@ export default {
height: 0,
statusBarHeight: 0,
//
selectedLocation: "苏州",
};
},
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/CommonFunction.js'
import {myMixins} from '@/mixins/myMixins.js'
import main from "@/common/index.js"
Vue.prototype.$main = main
Vue.mixin(myMixins)
Vue.config.productionTip = false

9
manifest.json

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

32
pages.json

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

256
pages/index/iSoul.vue

@ -29,8 +29,8 @@
></image>
</view>
<view class="user-info">
<view class="username">{{ userInfo.nickname || "用户" }}</view>
<view class="user-id">ID{{ userInfo.redBookId || "123456" }}</view>
<view class="username">{{ userInfo.nickname || "去登录" }}</view>
<view class="user-id" v-if="userInfo.redBookId">ID{{ userInfo.redBookId || "123456" }}</view>
<!-- <view class="location">
<text class="location-icon">📍</text>
<text>IP属地{{ userInfo.location || "上海" }}</text>
@ -51,6 +51,7 @@
<!-- 统计数据 -->
<view class="stats-section">
<view class="stats-left">
<view class="stat-item">
<view class="stat-number">{{ userStats.following || "140" }}</view>
<view class="stat-label">关注</view>
@ -64,6 +65,12 @@
<view class="stat-label">获赞与收藏</view>
</view>
</view>
<!-- 权益兑换入口 -->
<view class="exchange-entry" @click="showExchangePopup">
<view class="exchange-icon">🎁</view>
<view class="exchange-text">权益兑换</view>
</view>
</view>
</view>
<!-- 待激活的Agent -->
<view class="agent-section">
@ -222,6 +229,33 @@
<CustomTabBar :currentTab="4" />
<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>
</template>
@ -284,6 +318,7 @@ export default {
icon: "💬",
},
],
exchangeCode: "", //
};
},
onLoad() {
@ -427,16 +462,90 @@ export default {
},
//
handleMemorialClick(index) {
if (index === 0) {
//
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",
});
return;
}
//
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.navigateTo({
url: "/subPackages/video/video",
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>
@ -571,13 +680,21 @@ view {
/* 统计数据 */
.stats-section {
display: flex;
justify-content: space-around;
justify-content: space-between;
align-items: center;
margin-top: 80rpx;
padding-bottom: 50rpx;
padding: 0 40rpx;
}
.stats-left {
display: flex;
gap: 60rpx;
}
.stat-item {
text-align: center;
min-width: 80rpx;
}
.stat-number {
@ -592,6 +709,34 @@ view {
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 {
display: flex;
@ -893,7 +1038,12 @@ view {
border-bottom: none;
}
//
.user-top {
background-size: cover;
background-position: center;
background-repeat: no-repeat;
padding-bottom: 20rpx;
}
.digital-img {
@ -901,4 +1051,96 @@ view {
width: 100%;
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>

14
pages/index/index.vue

@ -1,6 +1,6 @@
<template>
<view class="bg">
<headerVue fixed isLocation></headerVue>
<headerVue :selectedLocation="selectedLocation" fixed isLocation></headerVue>
<!-- 灵动岛组件 -->
<!-- 灵动岛组件 - 自包含无需传递参数 -->
@ -86,11 +86,11 @@ export default {
],
productListFeeling: [
{
id: 32,
id: 34,
image:
"https://epic.js-dyyj.com/uploads/20250728/22e319f3feb1b63fbb539d425c51fe70.png",
title: "OUT OF SPACE 东方线香",
price: "588.00",
price: "138.00",
isLiked: true,
isShop:true
},
@ -103,11 +103,17 @@ export default {
isLiked: false,
},
],
selectedLocation:''
};
},
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();
},
onShow() {
this.browse_record({ type: "page", title: "首页" });

71
pages/index/timeShopBank.vue

@ -22,6 +22,13 @@
</view>
</view>
<!-- 发布按钮 -->
<view class="fab-container">
<button class="fab-btn" @click="goToPublish">
<text class="fab-icon">+</text>
</button>
</view>
<!-- 瀑布流组件 -->
<WaterfallLayout
:items="waterfallItems"
@ -66,10 +73,10 @@ export default {
return {
currentTab: 1, // ""
tabs: [
{ name: '划线', id: 'underline' },
{ name: '笔记', id: 'notes' },
{ name: '关注', id: 'follow' },
{ name: '推荐', id: 'recommend' }
{ name: "划线", id: "underline" },
{ name: "笔记", id: "notes" },
{ name: "关注", id: "follow" },
{ name: "推荐", id: "recommend" },
],
waterfallItems: [],
autoAddEnabled: false,
@ -141,7 +148,7 @@ export default {
// -
onPageScroll(e) {
// ID
uni.$emit('pageScroll_timeShopBank_page', e.scrollTop);
uni.$emit("pageScroll_timeShopBank_page", e.scrollTop);
},
methods: {
//
@ -203,17 +210,22 @@ export default {
//
handleItemClick(item) {
uni.showToast({
title: `点击了: ${item.title}`,
icon: "none",
duration: 2000,
//
uni.navigateTo({
url: `/pages/notes/detail`,
});
},
//
handleItemAdded(item) {
//
goToPublish() {
uni.navigateTo({
url: "/pages/notes/publish",
});
},
//
handleItemAdded(item) {},
//
handleAutoAddRequest() {
this.addRandomItem();
@ -226,8 +238,6 @@ export default {
newItems.push(this.getRandomItem());
}
this.waterfallItems.push(...newItems);
},
// Tab
@ -343,7 +353,7 @@ export default {
transform: translateX(-50%);
width: 80rpx;
height: 4rpx;
background: #33FEFE;
background: #33fefe;
border-radius: 3rpx;
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组件内部 */
</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>

166
subPackages/equityGoods/detail.vue

@ -2,21 +2,37 @@
<view class="detail-container">
<!-- 轮播图区域 -->
<view class="banner-content">
<swiper class="top-banner" :circular="true" :interval="6000" :duration="800" :indicator-dots="false"
:autoplay="true" @change="swiperChange">
<swiper
class="top-banner"
:circular="true"
:interval="6000"
:duration="800"
:indicator-dots="false"
:autoplay="true"
@change="swiperChange"
>
<swiper-item v-for="(item, index) in topBanner" :key="index">
<image class="top-banner" :src="showImg(item)" mode="aspectFill"></image>
<image
class="top-banner"
:src="showImg(item)"
mode="aspectFill"
></image>
</swiper-item>
</swiper>
<view class="dot-container">
<view :class="['dot-line', index == swiperIndex ? 'active' : '']" v-for="(item, index) in topBanner"
:key="index"></view>
<view
:class="['dot-line', index == swiperIndex ? 'active' : '']"
v-for="(item, index) in topBanner"
:key="index"
></view>
</view>
<!-- 页码指示器 -->
<view class="page-indicator">
<text class="page-text">{{ swiperIndex + 1 }}/{{ topBanner.length }}</text>
<text class="page-text"
>{{ swiperIndex + 1 }}/{{ topBanner.length }}</text
>
</view>
</view>
@ -39,15 +55,17 @@
<text class="price">699.00</text>
</view>
<view class="collect-container">
<image class="heart-icon"
<image
class="heart-icon"
src="https://epic.js-dyyj.com/uploads/20250728/2f3ae212c01fa3b67be81abc5723cf5c.png"
@click.stop="handleLikeClick(item, index)"></image>
@click.stop="handleLikeClick(item, index)"
></image>
<text class="collect-count">1700收藏</text>
</view>
</view>
<!-- 权益信息 -->
<view class="equity-section">
<!-- <view class="equity-section">
<view class="equity-row">
<view class="equity-item">
<view class="equity-label">创作数字资产所属方者</view>
@ -62,38 +80,46 @@
<view class="equity-value">江苏文交所</view>
</view>
</view>
</view>
</view> -->
<!-- 权益信息标题 -->
<view class="equity-title">
<!-- <view class="equity-title">
<view class="title-line"></view>
<text class="title-text">权益信息</text>
<view class="title-line"></view>
</view>
</view> -->
<!-- 权益详情 -->
<view class="equity-details">
<!-- 显示前两个权益项 -->
<view class="equity-detail-item" v-for="(item, index) in displayEquityList" :key="index">
<view
class="equity-detail-item"
v-for="(item, index) in displayEquityList"
:key="index"
>
<view class="detail-content-wrapper">
<text class="detail-label">{{ item.label }}</text>
<text class="detail-content">{{ item.content }}</text>
</view>
<!-- 在最后一个显示项的右侧添加展开收起图标 -->
<view v-if="index === displayEquityList.length - 1" class="toggle-icon" @click="toggleEquityExpand">
<!-- <view v-if="index === displayEquityList.length - 1" class="toggle-icon" @click="toggleEquityExpand">
<text class="icon-text">{{
isEquityExpanded ? "收起" : "展开"
}}</text>
<text class="icon-arrow" :class="{ expanded: isEquityExpanded }"></text>
</view>
</view> -->
</view>
</view>
</view>
<!-- Tab切换区域 -->
<view class="tab-nav">
<view v-for="(tab, index) in tabList" :key="index" :class="['tab-item', { active: currentTab === index }]"
@click="switchTab(index)">
<view
v-for="(tab, index) in tabList"
:key="index"
:class="['tab-item', { active: currentTab === index }]"
@click="switchTab(index)"
>
<text class="tab-text">{{ tab.name }}</text>
</view>
</view>
@ -105,30 +131,44 @@
<!-- 登记证书 -->
<view v-if="currentTab === 0" class="tab-panel">
<view class="certificate-container">
<image class="certificate-image"
<image
class="certificate-image"
src="https://epic.js-dyyj.com/uploads/20250731/d7d5be03617e3cce94dc34e8de426395.png"
mode="widthFix"></image>
mode="widthFix"
></image>
</view>
</view>
<!-- IP资产详情 -->
<view v-if="currentTab === 1" class="tab-panel">
<image :src="
<image
:src="
showImg('/uploads/20250731/0d8cb190c358c0cf52fab89bb98a0373.jpg')
" style="width: 100%" mode="widthFix"></image>
"
style="width: 100%"
mode="widthFix"
></image>
</view>
<!-- 数据商品详情 -->
<view v-if="currentTab === 2" class="tab-panel">
<image :src="
<image
:src="
showImg('/uploads/20250731/ecf91ddfb9f89658a7d82e3ff846f71c.png')
" style="width: 100%" mode="widthFix"></image>
"
style="width: 100%"
mode="widthFix"
></image>
</view>
<!-- 权益信息 -->
<view v-if="currentTab === 3" class="tab-panel">
<image :src="
<image
:src="
showImg('/uploads/20250731/83af15ea93f0cd91eb780a7bb240257a.jpg')
" style="width: 100%" mode="widthFix"></image>
"
style="width: 100%"
mode="widthFix"
></image>
</view>
</view>
</view>
@ -154,32 +194,33 @@
swiperIndex: 0,
isEquityExpanded: false, //
currentTab: 0, // tab
tabList: [{
name: "登记证书"
tabList: [
{
name: "登记证书",
},
{
name: "IP资产详情"
name: "IP资产详情",
},
{
name: "资源商品详情"
name: "资源商品详情",
},
{
name: "资源商品详情"
name: "资源商品详情",
},
],
equityList: [
//
{
label: "权益1:",
content: "数字资产*1、数字资产*1"
content: "数字资产*1、数字资产*1",
},
{
label: "权益2:",
content: "IP文创公仔*1、IP文创公仔*1"
content: "IP文创公仔*1、IP文创公仔*1",
},
{
label: "权益3:",
content: "XX园林门票*1、XX园林门票*1"
content: "XX园林门票*1、XX园林门票*1",
},
],
};
@ -187,9 +228,10 @@
computed: {
//
displayEquityList() {
return this.isEquityExpanded ?
this.equityList :
this.equityList.slice(0, 2);
return this.equityList;
// return this.isEquityExpanded ?
// this.equityList :
// this.equityList.slice(0, 2);
},
},
methods: {
@ -204,6 +246,10 @@
//
handlePurchase() {
console.log("立即购买");
uni.showToast({
title: "(暂未开放)为您跳转到君道苏州下单~",
icon: "none",
});
//
},
//
@ -251,7 +297,7 @@
background: RGBA(189, 170, 173, 0.8);
&.active {
background: #ff1e55;
background: #94fafa;
}
}
}
@ -296,8 +342,8 @@
flex-wrap: wrap;
.limit-tag {
background: #ff1e55;
color: white;
background: #94fafa;
color: #333333;
padding: 8rpx 16rpx;
font-size: 20rpx;
border-radius: 6rpx 0 0 6rpx;
@ -323,7 +369,7 @@
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 40rpx;
margin-bottom: 20rpx;
.price-container {
display: flex;
@ -413,23 +459,26 @@
.title-line {
width: 30rpx;
height: 2rpx;
background: #ff1e55;
background: #94fafa;
}
.title-text {
padding: 0 30rpx;
font-size: 25rpx;
color: #ff1e55;
color: #94fafa;
font-weight: bold;
}
}
.equity-details {
border-top: 1rpx solid #e5e5e5;
padding-top: 60rpx;
padding-bottom: 20rpx;
.equity-detail-item {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20rpx;
margin-bottom: 10rpx;
line-height: 1.5;
.detail-content-wrapper {
@ -437,14 +486,14 @@
flex: 1;
.detail-label {
font-size: 23rpx;
color: #231815;
font-size: 26rpx;
color: #808080;
font-weight: 500;
}
.detail-content {
font-size: 23rpx;
color: #231815;
font-size: 26rpx;
color: #808080;
flex: 1;
font-weight: 500;
}
@ -455,7 +504,7 @@
align-items: center;
gap: 8rpx;
cursor: pointer;
padding: 10rpx;
padding: 0rpx;
margin-left: 20rpx;
.icon-text {
@ -495,16 +544,19 @@
color: #3e3a39;
cursor: pointer;
transition: all 0.3s ease;
background-color: #94fafa66;
display: flex;
align-items: center;
&.active {
background-color: #ff1e55;
color: #fff;
border-radius: 20rpx 20rpx 0 0;
background-color: #94fafa;
color: #525454;
font-size: 24rpx;
border-radius: 10rpx 10rpx 0 0;
font-weight: bold;
}
.tab-text {
font-size: 23rpx;
font-weight: bold;
font-size: 24rpx;
}
}
}
@ -621,12 +673,12 @@
.purchase-button {
width: 100%;
height: 88rpx;
background: linear-gradient(135deg, #ff1e55 0%, #ff4081 100%);
background: #94fafa;
border-radius: 44rpx;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 8rpx 20rpx rgba(255, 30, 85, 0.3);
box-shadow: 0 8rpx 20rpx #94fafa;
transition: all 0.3s ease;
&:active {
@ -637,7 +689,7 @@
.purchase-text {
font-size: 32rpx;
font-weight: bold;
color: white;
color: #525454;
}
}
}

398
subPackages/equityGoods/list.vue

@ -1,7 +1,10 @@
<template>
<view class="equity-goods-page">
<image style="width: 100%;" mode="widthFix"
:src="showImg('/uploads/20250728/748adc244fc7db313f569a6005344950.png')"></image>
<image
style="width: 100%"
mode="widthFix"
:src="showImg('/uploads/20250728/748adc244fc7db313f569a6005344950.png')"
></image>
<view class="location-selector">
<text class="location-text">扬州</text>
<image
@ -21,15 +24,32 @@
<!-- 商品网格 -->
<view class="products-grid">
<view class="product-item" :style="{'border-width':(index==productList.length-1||index==productList.length-2)?0:'0.5rpx'}" v-for="(item, index) in productList" :key="index" @click="goToDetail(item)">
<image class="product-image" :src="item.image" mode="aspectFill"></image>
<view
class="product-item"
:style="{
'border-width':
index == productList.length - 1 || index == productList.length - 2
? 0
: '0.5rpx',
}"
v-for="(item, index) in productList"
:key="index"
@click="goToDetail(item)"
>
<image
class="product-image"
:src="item.image"
mode="aspectFill"
></image>
<view class="product-info">
<view class="product-title">{{ item.title }}</view>
<view class="product-price-box">
<view class="product-price">{{ item.price }}</view>
<view class="">
<image class="heart-icon"
src="https://epic.js-dyyj.com/uploads/20250728/2f3ae212c01fa3b67be81abc5723cf5c.png">
<image
class="heart-icon"
src="https://epic.js-dyyj.com/uploads/20250728/2f3ae212c01fa3b67be81abc5723cf5c.png"
>
</image>
<!-- <image
v-else
@ -37,8 +57,10 @@
src="https://epic.js-dyyj.com/uploads/20250728/dd7ed269b24e84a2dd141da6ab980fd6.png"
@click.stop="handleLikeClick(item, index)"
></image> -->
<image class="shop-icon"
src="https://epic.js-dyyj.com/uploads/20250728/195bfc195a54b93c13595a01a5d8bb3b.png">
<image
class="shop-icon"
src="https://epic.js-dyyj.com/uploads/20250728/195bfc195a54b93c13595a01a5d8bb3b.png"
>
</image>
<!-- <image
v-else
@ -59,105 +81,245 @@
<!-- 底部地图区域 -->
<view class="map-section">
<view class="map-title">业务办理 | 预约参观</view>
<view class="map-title" @click="showReservationPopup"
>业务办理 | 预约参观</view
>
<view class="map-container">
<map class="map-component" :latitude="mapData.latitude" :longitude="mapData.longitude"
:scale="mapData.scale"></map>
<map
class="map-component"
:latitude="mapData.latitude"
:longitude="mapData.longitude"
:scale="mapData.scale"
></map>
</view>
<view class="map-description">
<view class="location-info">
<image class="location-icon"
:src="showImg('/uploads/20250728/56804fe109efd614ba955d3110cd6750.png')"
mode="widthFix"></image>
<text class="location-name">国家文化大数据华东区域交易平台扬州运营中心</text>
<image
class="location-icon"
:src="
showImg('/uploads/20250728/56804fe109efd614ba955d3110cd6750.png')
"
mode="widthFix"
></image>
<text class="location-name"
>国家文化大数据华东区域交易平台扬州运营中心</text
>
</view>
</view>
</view>
<!-- 预约参观弹窗 -->
<uni-popup ref="reservationPopup" type="center">
<view class="reservation-popup">
<view class="popup-header">
<text class="popup-title">预约参观</text>
<text class="popup-close" @click="closeReservationPopup">×</text>
</view>
<view class="popup-content">
<view class="input-section">
<text class="input-label">姓名</text>
<input
class="reservation-input"
v-model="reservationForm.name"
placeholder="请输入您的姓名"
maxlength="10"
/>
</view>
<view class="input-section">
<text class="input-label">手机号</text>
<input
class="reservation-input"
v-model="reservationForm.phone"
placeholder="请输入手机号码"
type="number"
maxlength="11"
/>
</view>
<view class="popup-actions">
<button class="cancel-btn" @click="closeReservationPopup">
取消
</button>
<button class="confirm-btn" @click="confirmReservation">
确认预约
</button>
</view>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
export default {
name: 'EquityGoodsList',
name: "EquityGoodsList",
mixins: [require("@/mixins/myMixins.js")],
data() {
return {
productList: [{
productList: [
{
id: 1,
title: '食在扬州|世界美食之都巡礼',
price: '699.00',
image: 'https://images.unsplash.com/photo-1414235077428-338989a2e8c0?auto=format&fit=crop&w=800',
title: "食在扬州|世界美食之都巡礼",
price: "699.00",
image:
"https://images.unsplash.com/photo-1414235077428-338989a2e8c0?auto=format&fit=crop&w=800",
isLiked: false,
limitInfo: '限量发售 x 1000份',
paymentInfo: '100+付款',
viewInfo: '浏览10W'
limitInfo: "限量发售 x 1000份",
paymentInfo: "100+付款",
viewInfo: "浏览10W",
},
{
id: 2,
title: '二十四桥|诗意之城',
price: '588.00',
image: 'https://images.unsplash.com/photo-1578662996442-48f60103fc96?auto=format&fit=crop&w=800',
title: "二十四桥|诗意之城",
price: "588.00",
image:
"https://images.unsplash.com/photo-1578662996442-48f60103fc96?auto=format&fit=crop&w=800",
isLiked: true,
limitInfo: '限量发售 x 1000份',
paymentInfo: '100+付款',
viewInfo: '浏览10W'
limitInfo: "限量发售 x 1000份",
paymentInfo: "100+付款",
viewInfo: "浏览10W",
},
{
id: 3,
title: '以手抄心|书法体验',
price: '699.00',
image: 'https://images.unsplash.com/photo-1513475382585-d06e58bcb0e0?auto=format&fit=crop&w=800',
title: "以手抄心|书法体验",
price: "699.00",
image:
"https://images.unsplash.com/photo-1513475382585-d06e58bcb0e0?auto=format&fit=crop&w=800",
isLiked: false,
limitInfo: '限量发售 x 1000份',
paymentInfo: '100+付款',
viewInfo: '浏览10W'
limitInfo: "限量发售 x 1000份",
paymentInfo: "100+付款",
viewInfo: "浏览10W",
},
{
id: 4,
title: '世界花园|诗学之旅',
price: '588.00',
image: 'https://images.unsplash.com/photo-1490750967868-88aa4486c946?auto=format&fit=crop&w=800',
title: "世界花园|诗学之旅",
price: "588.00",
image:
"https://images.unsplash.com/photo-1490750967868-88aa4486c946?auto=format&fit=crop&w=800",
isLiked: false,
limitInfo: '限量发售 x 1000份',
paymentInfo: '100+付款',
viewInfo: '浏览10W'
}
limitInfo: "限量发售 x 1000份",
paymentInfo: "100+付款",
viewInfo: "浏览10W",
},
],
heartIcon: 'https://epic.js-dyyj.com/uploads/20250728/2f3ae212c01fa3b67be81abc5723cf5c.png',
heartFilledIcon: 'https://epic.js-dyyj.com/uploads/20250728/dd7ed269b24e84a2dd141da6ab980fd6.png',
cartIcon: 'https://images.unsplash.com/photo-1563013544-824ae1b704d3?auto=format&fit=crop&w=100',
heartIcon:
"https://epic.js-dyyj.com/uploads/20250728/2f3ae212c01fa3b67be81abc5723cf5c.png",
heartFilledIcon:
"https://epic.js-dyyj.com/uploads/20250728/dd7ed269b24e84a2dd141da6ab980fd6.png",
cartIcon:
"https://images.unsplash.com/photo-1563013544-824ae1b704d3?auto=format&fit=crop&w=100",
mapData: {
latitude: 31.2989,
longitude: 120.5853,
scale: 17,
}
}
},
//
reservationForm: {
name: "",
phone: "",
},
};
},
methods: {
goToDetail(item) {
uni.navigateTo({
url: `/subPackages/equityGoods/detail?id=${item.id}`
})
url: `/subPackages/equityGoods/detail?id=${item.id}`,
});
},
toggleLike(item, index) {
this.productList[index].isLiked = !this.productList[index].isLiked
this.productList[index].isLiked = !this.productList[index].isLiked;
uni.showToast({
title: this.productList[index].isLiked ? '已收藏' : '取消收藏',
icon: 'none'
})
title: this.productList[index].isLiked ? "已收藏" : "取消收藏",
icon: "none",
});
},
addToCart(item) {
uni.showToast({
title: '已加入购物车',
icon: 'success'
})
title: "已加入购物车",
icon: "success",
});
},
//
showReservationPopup() {
this.$refs.reservationPopup.open();
},
//
closeReservationPopup() {
this.$refs.reservationPopup.close();
//
this.reservationForm.name = "";
this.reservationForm.phone = "";
},
//
async confirmReservation() {
//
if (!this.reservationForm.name.trim()) {
uni.showToast({
title: "请输入姓名",
icon: "none",
});
return;
}
if (!this.reservationForm.phone.trim()) {
uni.showToast({
title: "请输入手机号",
icon: "none",
});
return;
}
//
const phoneRegex = /^1[3-9]\d{9}$/;
if (!phoneRegex.test(this.reservationForm.phone)) {
uni.showToast({
title: "请输入正确的手机号",
icon: "none",
});
return;
}
try {
uni.showLoading({
title: "提交中...",
});
//
await this.submitReservation(this.reservationForm);
uni.hideLoading();
uni.showToast({
title: "预约成功!",
icon: "success",
});
this.closeReservationPopup();
} catch (error) {
uni.hideLoading();
uni.showToast({
title: "预约失败,请重试",
icon: "none",
});
}
},
// API
async submitReservation(formData) {
return new Promise((resolve, reject) => {
setTimeout(() => {
// API
console.log("预约信息:", formData);
resolve({
success: true,
message: "预约成功",
});
}, 1500);
});
},
},
};
</script>
<style>
page {
background-color: #F5F5F5;
background-color: #f5f5f5;
}
</style>
<style lang="scss" scoped>
@ -240,7 +402,6 @@
color: #000000;
}
.product-details {
display: flex;
align-items: center;
@ -293,7 +454,6 @@
.location-icon {
width: 40rpx;
}
.location-name {
@ -369,4 +529,122 @@
height: 16rpx;
}
}
//
.reservation-popup {
width: 600rpx;
background: white;
border-radius: 24rpx;
overflow: hidden;
.popup-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 32rpx 32rpx 24rpx;
border-bottom: 1rpx solid #f0f0f0;
.popup-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
}
.popup-close {
font-size: 40rpx;
color: #999;
line-height: 1;
padding: 8rpx;
cursor: pointer;
transition: color 0.3s;
&:active {
color: #666;
}
}
}
.popup-content {
padding: 32rpx;
.input-section {
margin-bottom: 32rpx;
.input-label {
display: block;
font-size: 28rpx;
color: #333;
margin-bottom: 16rpx;
font-weight: 500;
}
.reservation-input {
width: 100%;
height: 88rpx;
border: 2rpx solid #e0e0e0;
border-radius: 12rpx;
padding: 0 24rpx;
font-size: 28rpx;
color: #333;
background: #fafafa;
transition: all 0.3s;
box-sizing: border-box;
&:focus {
border-color: #007aff;
background: white;
}
&::placeholder {
color: #999;
}
}
}
.popup-actions {
display: flex;
gap: 24rpx;
margin-top: 40rpx;
.cancel-btn,
.confirm-btn {
flex: 1;
height: 74rpx;
border-radius: 12rpx;
font-size: 28rpx;
font-weight: 600;
border: none;
transition: all 0.3s;
&:active {
transform: scale(0.98);
}
}
.cancel-btn {
background: #f5f5f5;
color: #666;
&:active {
background: #e8e8e8;
}
}
.confirm-btn {
background: #007aff;
color: white;
&:active {
background: #0056cc;
}
}
}
}
}
//
.map-title {
cursor: pointer;
transition: all 0.3s;
}
</style>

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>

704
subPackages/orderQy/detail.vue

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

325
subPackages/orderQy/list.vue

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

177
subPackages/user/travelerList.vue

@ -24,9 +24,7 @@
</view>
</view>
<view class="idcard">
<view class="">
{{item.document_type_text}}:
</view>
<view class=""> {{ item.document_type_text }}: </view>
<view class="">
{{ item.id_number }}
</view>
@ -44,12 +42,8 @@
</view> -->
</view>
<view class="btn-list">
<view class="btn-item" @click.stop="edit(item.id)">
修改
</view>
<view class="btn-item" @click.stop="delet(item)">
删除
</view>
<view class="btn-item" @click.stop="edit(item.id)"> 修改 </view>
<view class="btn-item" @click.stop="delet(item)"> 删除 </view>
</view>
</view>
</view>
@ -57,7 +51,12 @@
<!-- 收货地址 -->
<view v-else>
<view class="item" v-for="(item,index) in addressList" :key="index">
<view
class="item"
v-for="(item, index) in addressList"
:key="index"
@click="selectAddressForOrder(item)"
>
<view class="name">
<view>
{{ item.name }}
@ -68,29 +67,34 @@
</view>
</view>
<view class="idcard">
<view class="">
收货地址:
</view>
<view class=""> 收货地址: </view>
<view class="text-overflow">
{{ item.address }}
</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-item" @click.stop="edit(item.id)">
修改
</view>
<view class="btn-item" @click.stop="delet(item)">
删除
<view class="btn-item" @click.stop="edit(item.id)"> 修改 </view>
<view class="btn-item" @click.stop="delet(item)"> 删除 </view>
</view>
</view>
<!-- 选择指示器 -->
<view class="select-indicator" v-if="isSelectMode">
<uni-icons type="right" size="16" color="#6CA5AA" />
</view>
</view>
</view>
<view class="btn-box">
<navigator :url="showType ? '/subPackages/user/myAddressAdd' : '/subPackages/user/myContactsAdd'" class="btn">
{{showType ? '新增收货地址' : '添加联系人'}}
<navigator
:url="
showType
? '/subPackages/user/myAddressAdd'
: '/subPackages/user/myContactsAdd'
"
class="btn"
>
{{ showType ? "新增收货地址" : "添加联系人" }}
</navigator>
</view>
</view>
@ -103,11 +107,20 @@
return {
showType: 1,
travelList: [],
addressList: []
addressList: [],
isSelectMode: false, //
fromPage: "", //
};
},
onLoad(options) {
//
if (options.from) {
this.isSelectMode = true;
this.fromPage = options.from;
}
},
onShow() {
this.init()
this.init();
},
methods: {
init() {
@ -117,65 +130,98 @@
// })
//
this.Post({}, '/api/user/consigneeList').then(res => {
if(res) this.addressList = res.data
})
this.Post({}, "/api/user/consigneeList").then((res) => {
if (res) this.addressList = res.data;
});
},
delet(item) {
let that = this
let that = this;
uni.showModal({
title: '提示',
content: '确定要删除该出行人吗?',
title: "提示",
content: "确定要删除该出行人吗?",
success: function (res) {
if (res.confirm) {
that.Post({
id: item.id
}, "/api/user/delDetail").then(res => {
that
.Post(
{
id: item.id,
},
"/api/user/delDetail"
)
.then((res) => {
if (res) {
uni.showToast({
icon: "none",
title: res.msg
})
title: res.msg,
});
}
that.init()
})
that.init();
});
} else if (res.cancel) {
console.log('用户点击取消');
}
console.log("用户点击取消");
}
},
});
},
defaultC(item) {
this.Post({
this.Post(
{
id: item.id,
is_default: 1
}, "/api/user/editContact").then(res => {
is_default: 1,
},
"/api/user/editContact"
).then((res) => {
if (res.code == 1) {
this.travelList.forEach(i => i.is_default = 0)
item.is_default = !item.is_default
this.travelList.forEach((i) => (i.is_default = 0));
item.is_default = !item.is_default;
}
})
});
},
//
edit(id) {
let url = ''
let url = "";
if (this.showType) {
url = '/subPackages/user/myAddressAdd?id='+id
url = "/subPackages/user/myAddressAdd?id=" + id;
} else {
url = "/subPackages/user/myContactsAdd?type=edit&id="+id
url = "/subPackages/user/myContactsAdd?type=edit&id=" + id;
}
uni.navigateTo({
url: url
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>
<style lang="scss" scoped>
.bg {
position: relative;
background: #F7F7F7;
background: #f7f7f7;
height: 100vh;
overflow-x: hidden;
padding-bottom: 200rpx;
@ -188,7 +234,7 @@
flex-shrink: 0;
background-color: #fff;
.concat-nav-item {
ffont-weight: 500;
font-weight: 500;
font-size: 35rpx;
color: #000000;
height: 100%;
@ -214,10 +260,11 @@
.item {
width: 697rpx;
background: #FFFFFF;
background: #ffffff;
border-radius: 13rpx;
margin: 28rpx auto 0;
padding: 26rpx;
position: relative;
.name,
.idcard {
@ -225,7 +272,6 @@
font-size: 31rpx;
font-weight: bold;
color: #333333;
}
.name {
@ -239,7 +285,7 @@
border-radius: 7rpx;
font-weight: bold;
font-size: 24rpx;
color: #FFFFFF;
color: #ffffff;
margin-left: 15rpx;
}
}
@ -251,7 +297,6 @@
margin-left: 14rpx;
font-weight: 400;
max-width: 492rpx;
}
}
@ -295,11 +340,10 @@
view {
width: 134rpx;
height: 54rpx;
background: #FFFFFF;
background: #ffffff;
border: 1px solid #999999;
border-radius: 27rpx;
font-size: 27rpx;
font-weight: 500;
color: #333333;
@ -325,7 +369,7 @@
.btn {
width: 697rpx;
line-height: 80rpx;
background: #6CA5AA;
background: #6ca5aa;
border-radius: 37rpx;
font-weight: 500;
font-size: 36rpx;
@ -336,4 +380,19 @@
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>

Loading…
Cancel
Save