Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
groupPurchase-miniapp
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
彭佳妮(贵阳日报)
groupPurchase-miniapp
Commits
ef2de324
Commit
ef2de324
authored
Aug 03, 2024
by
彭佳妮(贵阳日报)
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
订单
parent
07edb666
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
847 additions
and
356 deletions
+847
-356
ticket.js
src/api/ticket.js
+8
-0
index.vue
src/pages/order/components/OrderList/index.vue
+0
-324
index.vue
src/pages/order/components/Payment/index.vue
+1
-1
order.vue
src/pages/order/order.vue
+376
-6
index.vue
src/pages/ticket/components/TicketList/index.vue
+0
-14
detail.vue
src/pages/ticket/detail.vue
+111
-4
ticket.vue
src/pages/ticket/ticket.vue
+351
-7
No files found.
src/api/ticket.js
View file @
ef2de324
...
@@ -34,3 +34,11 @@ export function receiveCoupon(data) {
...
@@ -34,3 +34,11 @@ export function receiveCoupon(data) {
data
,
data
,
});
});
}
}
// 优惠券使用须知
export
function
couponUsageNotice
()
{
return
request
({
url
:
`/sgyrdd/coupon/instructions`
,
method
:
'GET'
,
});
}
src/pages/order/components/OrderList/index.vue
deleted
100644 → 0
View file @
07edb666
<
template
>
<view
class=
"content"
v-if=
"dataList.length > 0"
>
<view
class=
"box"
v-for=
"(item, index) in dataList"
:key=
"index"
>
<view
class=
"header"
@
click=
"handleDetail(item.orderNumber)"
>
<view
class=
"left"
>
<image
src=
"@/static/order/shop.png"
/>
<view
class=
"title"
>
{{
item
.
shopName
}}
</view>
</view>
<view
class=
"right"
>
<span
class=
"status"
>
{{
statusList
[
item
.
status
]
}}
</span>
<wd-count-down
:time=
"time"
:format=
"format"
v-if=
"item.status == 1"
/>
</view>
</view>
<view
class=
"info"
@
click=
"handleDetail(item.orderNumber)"
>
<image
mode=
"aspectFill"
:src=
"fileDomain + item.orderItems[0].pic"
/>
<view
class=
"info-box"
>
<view
class=
"text"
>
下单时间:
{{
item
.
createTime
.
slice
(
0
,
16
)
}}
</view>
<view
class=
"text"
>
预约时间:
{{
item
.
receiverTime
}}
</view>
<view
class=
"text"
>
数量:
{{
item
.
orderItems
[
0
].
prodCount
}}
</view>
<view
class=
"text"
>
实付:¥
{{
item
.
actualTotal
}}
</view>
</view>
</view>
<view
class=
"btn"
>
<view
class=
"btn-info"
v-if=
"item.status == 5 || item.status == 6"
@
tap=
"handleDelete(item.orderNumber)"
>
删除
</view>
<view
class=
"btn-info"
v-if=
"item.status == 3"
@
tap=
"handleDetail(item.orderNumber)"
>
查看预约
</view>
<view
class=
"btn-info"
@
tap=
"handleCancel(item.orderNumber)"
v-if=
"item.status == 1"
>
取消订单
</view>
<view
class=
"btn-info"
v-if=
"item.status == 4"
@
tap=
"handleRemark(item)"
>
评价
</view>
<view
class=
"btn-info"
@
tap=
"callShopPhone(item.shopTel)"
>
联系商家
</view>
<view
class=
"btn-error"
v-if=
"item.status == 7"
>
售后详情
</view>
<view
class=
"btn-error"
v-if=
"item.status == 2 || item.status == 3 || item.status == 4"
@
click=
"handleRefund(item.orderNumber)"
>
申请退款
</view>
<view
class=
"btn-error"
v-if=
"item.status == 5"
>
再来一单
</view>
<view
class=
"btn-error"
v-if=
"item.status == 1"
>
立即支付
</view>
</view>
</view>
<wd-loadmore
:state=
"state"
@
reload=
"getList"
/>
</view>
<wd-status-tip
image=
"content"
tip=
"暂无内容"
v-else
/>
</
template
>
<
script
setup
>
import
{
getOrderList
,
deleteOrderApi
,
cancelOrderApi
}
from
'@/api/order'
;
const
fileDomain
=
import
.
meta
.
env
.
VITE_APP_IMG_URL
;
const
emits
=
defineEmits
([
'refresh'
]);
const
time
=
ref
(
30
*
60
*
1000
);
const
format
=
ref
(
'mm:ss'
);
const
state
=
ref
(
'loading'
);
const
catalog
=
reactive
({
current
:
0
,
size
:
10
,
startDate
:
''
,
endDate
:
''
,
keyword
:
''
,
status
:
''
,
// 订单状态,1-待付款,2-待接单,3-待取货,4-待评价,5-完成,6-取消,7-退款
});
const
statusList
=
ref
({
1
:
'待付款'
,
3
:
'待消费'
,
4
:
'待评价'
,
5
:
'已完成'
,
6
:
'已取消'
,
7
:
'已退款'
,
});
const
total
=
ref
(
0
);
const
dataList
=
ref
([]);
const
getList
=
async
()
=>
{
catalog
.
current
++
;
state
.
value
=
'loading'
;
const
res
=
await
getOrderList
(
catalog
);
if
(
res
.
code
===
0
)
{
if
(
res
.
data
.
records
.
length
>
0
)
{
dataList
.
value
.
push
(...
res
.
data
.
records
);
total
.
value
=
res
.
data
.
total
;
}
else
{
state
.
value
=
'finished'
;
}
}
else
{
state
.
value
=
'error'
;
}
state
.
value
=
'finished'
;
};
getList
();
onReachBottom
(()
=>
{
if
(
dataList
.
value
.
length
>=
total
.
value
)
{
state
.
value
=
'finished'
;
}
else
{
getList
();
}
});
const
handleDetail
=
(
id
)
=>
{
uni
.
navigateTo
({
url
:
`/pages/order/detail?orderNumber=
${
id
}
`
,
});
};
const
handleRefresh
=
(
e
)
=>
{
catalog
.
status
=
e
;
if
(
e
===
'0'
)
{
catalog
.
status
=
''
;
}
catalog
.
current
=
0
;
dataList
.
value
=
[];
total
.
value
=
0
;
getList
();
};
/**
* 拨打商家电话
* @param {*} phoneNumber
*/
function
callShopPhone
(
phoneNumber
)
{
xma
.
makePhoneCall
({
phoneNumber
,
// 仅为示例
});
}
/**
* 删除订单
* @param {*} ordrerNumber
*/
const
handleDelete
=
(
ordrerNumber
)
=>
{
uni
.
showModal
({
title
:
'提示'
,
content
:
'确定要删除订单吗?'
,
success
:
async
(
res
)
=>
{
if
(
res
.
confirm
)
{
const
res
=
await
deleteOrderApi
(
ordrerNumber
);
if
(
res
.
code
===
0
)
{
uni
.
showToast
({
title
:
'删除成功'
,
icon
:
'success'
,
});
handleRefresh
(
catalog
.
status
);
}
else
{
uni
.
showToast
({
title
:
'删除失败'
,
icon
:
'error'
,
});
}
}
},
});
};
/**
* 取消订单
* @param {*} ordrerNumber
*/
const
handleCancel
=
(
ordrerNumber
)
=>
{
uni
.
showModal
({
title
:
'提示'
,
content
:
'确定要取消订单吗?'
,
success
:
async
(
res
)
=>
{
if
(
res
.
confirm
)
{
const
res
=
await
cancelOrderApi
({
ordrerNumber
});
if
(
res
.
code
===
0
)
{
uni
.
showToast
({
title
:
'取消成功'
,
icon
:
'success'
,
});
handleRefresh
(
catalog
.
status
);
}
else
{
uni
.
showToast
({
title
:
'取消失败'
,
icon
:
'error'
,
});
}
}
},
});
};
const
handleRemark
=
(
item
)
=>
{
xma
.
navigateTo
({
url
:
`/pages/order/remark?orderNumber=
${
item
.
orderNumber
}
&shopName=
${
item
.
shopName
}
`
,
});
};
const
handleRefund
=
(
item
)
=>
{
xma
.
navigateTo
({
url
:
`/pages/order/refund?orderNumber=
${
item
.
orderNumber
}
`
,
});
};
defineExpose
({
refresh
:
handleRefresh
,
});
</
script
>
<
style
lang=
"scss"
scoped
>
.content
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
justify-content
:
center
;
padding
:
20rpx
;
gap
:
24rpx
;
.box
{
background-color
:
#fff
;
width
:
100%
;
border-radius
:
16rpx
;
padding
:
28rpx
18rpx
;
display
:
flex
;
flex-direction
:
column
;
box-sizing
:
border-box
;
gap
:
30rpx
;
.header
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
.left
{
display
:
flex
;
align-items
:
center
;
gap
:
6rpx
;
font-weight
:
bold
;
image
{
height
:
38rpx
;
width
:
38rpx
;
}
.title
{
color
:
#333
;
font-size
:
32rpx
;
font-family
:
PingFang
SC
;
}
}
.right
{
display
:
flex
;
align-items
:
center
;
gap
:
6rpx
;
.status
{
color
:
#666
;
font-size
:
28rpx
;
}
}
}
.info
{
display
:
flex
;
gap
:
20rpx
;
image
{
width
:
110rpx
;
height
:
110rpx
;
border-radius
:
12rpx
;
}
.info-box
{
display
:
flex
;
flex-direction
:
column
;
gap
:
18rpx
;
.text
{
color
:
#666
;
line-height
:
28rpx
;
font-size
:
28rpx
;
font-family
:
PingFang
SC
;
}
}
}
.btn
{
display
:
flex
;
justify-content
:
flex-end
;
gap
:
14rpx
;
.btn-info
{
width
:
162rpx
;
height
:
66rpx
;
border-radius
:
34rpx
;
border
:
1rpx
solid
#999999
;
color
:
#666
;
font-size
:
28rpx
;
font-family
:
PingFang
SC
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
}
.btn-error
{
width
:
162rpx
;
height
:
66rpx
;
border-radius
:
34rpx
;
border
:
1rpx
solid
#e9231b
;
color
:
#e9231b
;
font-size
:
28rpx
;
font-family
:
PingFang
SC
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
}
}
}
}
</
style
>
src/pages/order/components/Payment/index.vue
View file @
ef2de324
...
@@ -10,7 +10,7 @@
...
@@ -10,7 +10,7 @@
<view
class=
"pay-card"
>
<view
class=
"pay-card"
>
<view
class=
"header"
>
<view
class=
"header"
>
<view
class=
"title"
>
立即支付
</view>
<view
class=
"title"
>
立即支付
</view>
<wd-icon
name=
"close"
size=
"20"
color=
"#999"
></wd-icon>
<wd-icon
name=
"close"
size=
"20"
color=
"#999"
@
tap=
"close"
></wd-icon>
</view>
</view>
<radio-group
style=
"width: 100%"
@
change=
"radioChange"
>
<radio-group
style=
"width: 100%"
@
change=
"radioChange"
>
<view
class=
"pay-item"
>
<view
class=
"pay-item"
>
...
...
src/pages/order/order.vue
View file @
ef2de324
...
@@ -4,10 +4,82 @@
...
@@ -4,10 +4,82 @@
<view
class=
"tabs"
>
<view
class=
"tabs"
>
<wd-tabs
v-model=
"tab"
animated
:lineWidth=
"38"
:lineHeight=
"3"
@
change=
"handleChange"
>
<wd-tabs
v-model=
"tab"
animated
:lineWidth=
"38"
:lineHeight=
"3"
@
change=
"handleChange"
>
<block
v-for=
"item in tabs"
:key=
"item.value"
>
<block
v-for=
"item in tabs"
:key=
"item.value"
>
<wd-tab
:title=
"`$
{item.name}`" :name="item.value">
</wd-tab>
<wd-tab
:title=
"`$
{item.name}`" :name="item.value">
<view
class=
"content"
v-if=
"dataList.length > 0"
>
<view
class=
"box"
v-for=
"(item, index) in dataList"
:key=
"index"
>
<view
class=
"header"
@
click=
"handleDetail(item.orderNumber)"
>
<view
class=
"left"
>
<image
src=
"@/static/order/shop.png"
/>
<view
class=
"title"
>
{{
item
.
shopName
}}
</view>
</view>
<view
class=
"right"
>
<span
class=
"status"
>
{{
statusList
[
item
.
status
]
}}
</span>
<wd-count-down
:time=
"item.countDown"
:format=
"format"
@
finish=
"onFinish"
v-if=
"item.status == 1"
/>
</view>
</view>
<view
class=
"info"
@
click=
"handleDetail(item.orderNumber)"
>
<image
mode=
"aspectFill"
:src=
"fileDomain + item.orderItems[0].pic"
/>
<view
class=
"info-box"
>
<view
class=
"text"
>
下单时间:
{{
item
.
createTime
.
slice
(
0
,
16
)
}}
</view>
<view
class=
"text"
>
预约时间:
{{
item
.
receiverTime
}}
</view>
<view
class=
"text"
>
数量:
{{
item
.
orderItems
[
0
].
prodCount
}}
</view>
<view
class=
"text"
>
实付:¥
{{
item
.
actualTotal
}}
</view>
</view>
</view>
<view
class=
"btn"
>
<view
class=
"btn-info"
v-if=
"item.status == 5 || item.status == 6"
@
tap=
"handleDelete(item.orderNumber)"
>
删除
</view>
<view
class=
"btn-info"
v-if=
"item.status == 3"
@
tap=
"handleDetail(item.orderNumber)"
>
查看预约
</view>
<view
class=
"btn-info"
@
tap=
"handleCancel(item.orderNumber)"
v-if=
"item.status == 1"
>
取消订单
</view>
<view
class=
"btn-info"
v-if=
"item.status == 4"
@
tap=
"handleRemark(item)"
>
评价
</view>
<view
class=
"btn-info"
@
tap=
"callShopPhone(item.shopTel)"
>
联系商家
</view>
<view
class=
"btn-error"
v-if=
"item.status == 7"
>
售后详情
</view>
<view
class=
"btn-error"
v-if=
"item.status == 2 || item.status == 3 || item.status == 4"
@
click=
"handleRefund(item.orderNumber)"
>
申请退款
</view>
<view
class=
"btn-error"
v-if=
"item.status == 5"
>
再来一单
</view>
<view
class=
"btn-error"
v-if=
"item.status == 1"
@
tap=
"payNow(item.orderNumber)"
>
立即支付
</view>
</view>
</view>
<wd-loadmore
:state=
"state"
@
reload=
"getList"
/>
</view>
<wd-status-tip
image=
"content"
tip=
"暂无内容"
v-else
/>
</wd-tab>
</block>
</block>
</wd-tabs>
</wd-tabs>
<OrderList
ref=
"OrderListRef"
></OrderList>
</view>
</view>
<Payment
ref=
"PaymentRef"
></Payment>
<Payment
ref=
"PaymentRef"
></Payment>
</view>
</view>
...
@@ -15,8 +87,9 @@
...
@@ -15,8 +87,9 @@
<
script
setup
>
<
script
setup
>
import
Header
from
'./components/Header/index.vue'
;
import
Header
from
'./components/Header/index.vue'
;
import
OrderList
from
'./components/OrderList/index.vue'
;
import
Payment
from
'./components/Payment/index.vue'
;
import
Payment
from
'./components/Payment/index.vue'
;
import
{
getOrderList
,
deleteOrderApi
,
cancelOrderApi
}
from
'@/api/order'
;
const
fileDomain
=
import
.
meta
.
env
.
VITE_APP_IMG_URL
;
const
tabs
=
ref
([
const
tabs
=
ref
([
{
{
...
@@ -35,6 +108,10 @@ const tabs = ref([
...
@@ -35,6 +108,10 @@ const tabs = ref([
name
:
'待评价'
,
name
:
'待评价'
,
value
:
'4'
,
value
:
'4'
,
},
},
{
name
:
'已完成'
,
value
:
'5'
,
},
{
{
name
:
'退款/售后'
,
name
:
'退款/售后'
,
value
:
'7'
,
value
:
'7'
,
...
@@ -42,12 +119,192 @@ const tabs = ref([
...
@@ -42,12 +119,192 @@ const tabs = ref([
]);
]);
const
tab
=
ref
(
'0'
);
const
tab
=
ref
(
'0'
);
onReachBottom
(()
=>
{});
const
statusList
=
ref
({
1
:
'待付款'
,
3
:
'待消费'
,
4
:
'待评价'
,
5
:
'已完成'
,
6
:
'已取消'
,
7
:
'已退款'
,
});
// 触底函数
onReachBottom
(()
=>
{
if
(
dataList
.
value
.
length
>=
total
.
value
)
{
state
.
value
=
'finished'
;
}
else
{
getList
();
}
});
/**
* 获取订单列表
*/
const
total
=
ref
(
0
);
const
dataList
=
ref
([]);
const
state
=
ref
(
'loading'
);
const
catalog
=
reactive
({
current
:
0
,
size
:
10
,
startDate
:
''
,
endDate
:
''
,
keyword
:
''
,
status
:
''
,
// 订单状态,1-待付款,2-待接单,3-待取货,4-待评价,5-完成,6-取消,7-退款
});
const
getList
=
async
()
=>
{
catalog
.
status
=
tab
.
value
;
if
(
tab
.
value
===
'0'
)
{
catalog
.
status
=
''
;
}
catalog
.
current
++
;
state
.
value
=
'loading'
;
const
res
=
await
getOrderList
(
catalog
);
if
(
res
.
code
===
0
)
{
if
(
res
.
data
.
records
.
length
>
0
)
{
res
.
data
.
records
.
forEach
((
item
)
=>
{
if
(
item
.
status
===
'1'
)
{
item
.
countDown
=
calculateCountdown
(
item
.
createTime
);
}
});
dataList
.
value
.
push
(...
res
.
data
.
records
);
total
.
value
=
res
.
data
.
total
;
}
else
{
state
.
value
=
'finished'
;
}
}
else
{
state
.
value
=
'error'
;
}
state
.
value
=
'finished'
;
};
getList
();
const
OrderListRef
=
ref
(
null
);
const
handleChange
=
(
e
)
=>
{
const
handleChange
=
(
e
)
=>
{
tab
.
value
=
e
.
name
;
tab
.
value
=
e
.
name
;
OrderListRef
.
value
.
refresh
(
tab
.
value
);
initDataList
();
};
/**
* 刷新订单列表
*/
const
initDataList
=
()
=>
{
dataList
.
value
=
[];
total
.
value
=
0
;
catalog
.
current
=
0
;
getList
();
};
const
handleDetail
=
(
id
)
=>
{
uni
.
navigateTo
({
url
:
`/pages/order/detail?orderNumber=
${
id
}
`
,
});
};
/**
* 拨打商家电话
* @param {*} phoneNumber
*/
function
callShopPhone
(
phoneNumber
)
{
xma
.
makePhoneCall
({
phoneNumber
,
// 仅为示例
});
}
/**
* 删除订单
* @param {*} ordrerNumber
*/
const
handleDelete
=
(
ordrerNumber
)
=>
{
uni
.
showModal
({
title
:
'提示'
,
content
:
'确定要删除订单吗?'
,
success
:
async
(
res
)
=>
{
if
(
res
.
confirm
)
{
const
res
=
await
deleteOrderApi
(
ordrerNumber
);
if
(
res
.
code
===
0
)
{
uni
.
showToast
({
title
:
'删除成功'
,
icon
:
'success'
,
});
initDataList
();
}
else
{
uni
.
showToast
({
title
:
'删除失败'
,
icon
:
'error'
,
});
}
}
},
});
};
/**
* 取消订单
* @param {*} ordrerNumber
*/
const
handleCancel
=
(
ordrerNumber
)
=>
{
uni
.
showModal
({
title
:
'提示'
,
content
:
'确定要取消订单吗?'
,
success
:
async
(
res
)
=>
{
if
(
res
.
confirm
)
{
const
res
=
await
cancelOrderApi
({
ordrerNumber
});
if
(
res
.
code
===
0
)
{
uni
.
showToast
({
title
:
'取消成功'
,
icon
:
'success'
,
});
initDataList
();
}
else
{
uni
.
showToast
({
title
:
'取消失败'
,
icon
:
'error'
,
});
}
}
},
});
};
/**
* 立即支付
* @param {*} ordrerNumber
*/
const
PaymentRef
=
ref
(
null
);
const
payNow
=
(
orderNumber
)
=>
{
PaymentRef
.
value
.
open
();
};
/**
* 计算倒计时
*/
const
format
=
ref
(
'mm:ss'
);
const
calculateCountdown
=
(
item
)
=>
{
const
now
=
new
Date
().
getTime
();
const
orderTime
=
new
Date
(
item
).
getTime
();
const
countdown
=
orderTime
+
30
*
60
*
1000
-
now
;
if
(
countdown
<=
0
)
{
return
'00:00'
;
}
return
countdown
;
};
/**
* 倒计时结束触发
*/
const
onFinish
=
()
=>
{
initDataList
();
};
const
handleRemark
=
(
item
)
=>
{
xma
.
navigateTo
({
url
:
`/pages/order/remark?orderNumber=
${
item
.
orderNumber
}
&shopName=
${
item
.
shopName
}
`
,
});
};
const
handleRefund
=
(
item
)
=>
{
xma
.
navigateTo
({
url
:
`/pages/order/refund?orderNumber=
${
item
.
orderNumber
}
`
,
});
};
};
</
script
>
</
script
>
...
@@ -55,9 +312,11 @@ const handleChange = (e) => {
...
@@ -55,9 +312,11 @@ const handleChange = (e) => {
page
{
page
{
background
:
#f3f3f3
;
background
:
#f3f3f3
;
}
}
.container
{
.container
{
width
:
375
*
2rpx
;
width
:
375
*
2rpx
;
margin
:
0
auto
;
margin
:
0
auto
;
.tabs
{
.tabs
{
padding-top
:
44px
;
padding-top
:
44px
;
...
@@ -75,4 +334,115 @@ page {
...
@@ -75,4 +334,115 @@ page {
}
}
}
}
}
}
.content
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
justify-content
:
center
;
padding
:
20rpx
;
gap
:
24rpx
;
.box
{
background-color
:
#fff
;
width
:
100%
;
border-radius
:
16rpx
;
padding
:
28rpx
18rpx
;
display
:
flex
;
flex-direction
:
column
;
box-sizing
:
border-box
;
gap
:
30rpx
;
.header
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
.left
{
display
:
flex
;
align-items
:
center
;
gap
:
6rpx
;
font-weight
:
bold
;
image
{
height
:
38rpx
;
width
:
38rpx
;
}
.title
{
color
:
#333
;
font-size
:
32rpx
;
font-family
:
PingFang
SC
;
}
}
.right
{
display
:
flex
;
align-items
:
center
;
gap
:
6rpx
;
.status
{
color
:
#666
;
font-size
:
28rpx
;
}
}
}
.info
{
display
:
flex
;
gap
:
20rpx
;
image
{
width
:
110rpx
;
height
:
110rpx
;
border-radius
:
12rpx
;
}
.info-box
{
display
:
flex
;
flex-direction
:
column
;
gap
:
18rpx
;
.text
{
color
:
#666
;
line-height
:
28rpx
;
font-size
:
28rpx
;
font-family
:
PingFang
SC
;
}
}
}
.btn
{
display
:
flex
;
justify-content
:
flex-end
;
gap
:
14rpx
;
.btn-info
{
width
:
162rpx
;
height
:
66rpx
;
border-radius
:
34rpx
;
border
:
1rpx
solid
#999999
;
color
:
#666
;
font-size
:
28rpx
;
font-family
:
PingFang
SC
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
}
.btn-error
{
width
:
162rpx
;
height
:
66rpx
;
border-radius
:
34rpx
;
border
:
1rpx
solid
#e9231b
;
color
:
#e9231b
;
font-size
:
28rpx
;
font-family
:
PingFang
SC
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
}
}
}
}
</
style
>
</
style
>
src/pages/ticket/components/TicketList/index.vue
deleted
100644 → 0
View file @
07edb666
<
template
>
<!-- 优惠券列表 -->
<view></view>
</
template
>
<
script
setup
>
const
props
=
defineProps
({
couponData
:
{
type
:
Array
,
},
});
</
script
>
<
style
lang=
"scss"
scoped
></
style
>
src/pages/ticket/detail.vue
View file @
ef2de324
...
@@ -115,14 +115,22 @@
...
@@ -115,14 +115,22 @@
</view>
</view>
</view>
</view>
</view>
</view>
<view
class=
"coupon-tips"
v-if=
"couponInfo"
>
<view
class=
"tips"
>
使用须知
</view>
<view
class=
"desc"
>
{{
couponInfo
.
contentRdd
}}
</view>
</view>
</view>
</view>
<wd-status-tip
image=
"content"
tip=
"暂无优惠券"
v-else
/>
<wd-status-tip
image=
"content"
tip=
"暂无优惠券"
v-else
/>
</view>
</view>
<view
class=
"footer"
>
<view
class=
"btn"
@
tap=
"getCouponAll"
>
一键领取
</view>
</view>
</view>
</view>
</
template
>
</
template
>
<
script
setup
>
<
script
setup
>
import
{
shopCouponList
,
receiveCoupon
}
from
'@/api/ticket'
;
import
{
shopCouponList
,
receiveCoupon
,
couponUsageNotice
}
from
'@/api/ticket'
;
import
{
getShopDetail
}
from
'@/api/order'
;
import
{
getShopDetail
}
from
'@/api/order'
;
import
{
getDistance
}
from
'@/utils/common'
;
import
{
getDistance
}
from
'@/utils/common'
;
import
Header
from
'@/pages/order/components/Header/index.vue'
;
import
Header
from
'@/pages/order/components/Header/index.vue'
;
...
@@ -136,10 +144,10 @@ onShow(() => {
...
@@ -136,10 +144,10 @@ onShow(() => {
const
shopId
=
ref
();
const
shopId
=
ref
();
onLoad
((
options
)
=>
{
onLoad
((
options
)
=>
{
console
.
log
(
options
);
shopId
.
value
=
options
.
shopId
;
shopId
.
value
=
options
.
shopId
;
getShopMailDetail
();
getShopMailDetail
();
getList
();
getList
();
getCouponInfo
();
});
});
/**
/**
...
@@ -171,14 +179,51 @@ const getCoupon = async (item) => {
...
@@ -171,14 +179,51 @@ const getCoupon = async (item) => {
const
res
=
await
receiveCoupon
([
item
.
couponYzfId
]);
const
res
=
await
receiveCoupon
([
item
.
couponYzfId
]);
if
(
res
.
code
===
0
)
{
if
(
res
.
code
===
0
)
{
item
.
numState
=
1
;
item
.
numState
=
1
;
uni
.
showToast
({
xma
.
showToast
({
title
:
'领取成功'
,
title
:
'领取成功'
,
icon
:
'success'
,
icon
:
'success'
,
duration
:
2000
,
duration
:
2000
,
});
});
return
;
return
;
}
}
uni
.
showToast
({
xma
.
showToast
({
title
:
'领取失败'
,
icon
:
'error'
,
duration
:
2000
,
});
};
/**
* 一键领取优惠券
*/
const
getCouponAll
=
async
()
=>
{
const
ids
=
[];
couponData
.
value
.
forEach
((
item
)
=>
{
if
(
item
.
numState
===
0
)
{
ids
.
push
(
item
.
couponYzfId
);
}
});
if
(
ids
.
length
===
0
)
{
xma
.
showToast
({
title
:
'暂无可领取优惠券'
,
icon
:
'none'
,
duration
:
2000
,
});
return
;
}
const
res
=
await
receiveCoupon
(
ids
);
if
(
res
.
code
===
0
)
{
couponData
.
value
.
forEach
((
item
)
=>
{
item
.
numState
=
1
;
});
xma
.
showToast
({
title
:
'领取成功'
,
icon
:
'success'
,
duration
:
2000
,
});
return
;
}
xma
.
showToast
({
title
:
'领取失败'
,
title
:
'领取失败'
,
icon
:
'error'
,
icon
:
'error'
,
duration
:
2000
,
duration
:
2000
,
...
@@ -198,6 +243,17 @@ const getShopMailDetail = async () => {
...
@@ -198,6 +243,17 @@ const getShopMailDetail = async () => {
}
}
};
};
/**
* 获取优惠券信息
*/
const
couponInfo
=
ref
();
const
getCouponInfo
=
async
()
=>
{
const
res
=
await
couponUsageNotice
();
if
(
res
.
code
===
0
)
{
couponInfo
.
value
=
JSON
.
parse
(
res
.
data
.
paramValue
);
}
};
/**
/**
* 拨打商家电话
* 拨打商家电话
* @param {*} phoneNumber
* @param {*} phoneNumber
...
@@ -596,6 +652,57 @@ page {
...
@@ -596,6 +652,57 @@ page {
}
}
}
}
}
}
.coupon-tips
{
width
:
100%
;
background-color
:
#fff
;
border-radius
:
16rpx
;
display
:
flex
;
flex-direction
:
column
;
padding
:
40rpx
46rpx
40rpx
;
// min-height: 436rpx;
box-sizing
:
border-box
;
gap
:
38rpx
;
.tips
{
font-family
:
PingFang
SC
Bold-Regular
;
font-size
:
32rpx
;
color
:
#333333
;
line-height
:
32rpx
;
text-align
:
center
;
}
.desc
{
white-space
:
pre-line
;
/* 将空格和换行符保留在文本中 */
font-family
:
PingFang
SC
Regular
;
font-size
:
24rpx
;
color
:
#333333
;
line-height
:
36rpx
;
text-align
:
left
;
}
}
}
}
.footer
{
position
:
fixed
;
bottom
:
0
;
width
:
100%
;
padding
:
20rpx
26rpx
60rpx
;
box-sizing
:
border-box
;
background-color
:
#f5f5f5
;
.btn
{
width
:
100%
;
height
:
80rpx
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
font-family
:
PingFang
SC
Bold-Regular
;
font-size
:
32rpx
;
color
:
#ffffff
;
background
:
linear-gradient
(
180deg
,
#ff694d
0%
,
#ff3f33
100%
);
border-radius
:
46rpx
;
}
}
}
}
}
}
...
...
src/pages/ticket/ticket.vue
View file @
ef2de324
<
template
>
<
template
>
<view
class=
"container"
>
<view
class=
"container"
>
<Header
title=
"我的
码
"
></Header>
<Header
title=
"我的
券
"
></Header>
<view
class=
"tab"
>
<view
class=
"tab"
>
<view
<view
:class=
"currentTab == index ? 'tab-select' : 'tab-item'"
:class=
"currentTab == index ? 'tab-select' : 'tab-item'"
...
@@ -30,7 +30,78 @@
...
@@ -30,7 +30,78 @@
</view>
</view>
<!-- 优惠券列表 -->
<!-- 优惠券列表 -->
<TicketList></TicketList>
<view
class=
"ticket-list"
v-if=
"couponData.length"
>
<view
class=
"ticket-item"
v-for=
"(item, index) in couponData"
:key=
"index"
>
<view
class=
"ticket-box"
>
<view
class=
"ticket-left"
:class=
"item.status == 0 ? 'past' : 'normal'"
>
<view
class=
"ticket-box"
>
<view
class=
"ticket-price"
>
<text
class=
"price"
>
¥
</text>
<text
class=
"num"
>
{{
item
.
reduceAmount
}}
</text>
</view>
<view
class=
"ticket-desc"
>
<text
class=
"desc"
>
满
{{
item
.
cashCondition
}}
元可用
</text>
<!--
<text
class=
"desc"
>
数量:
{{
item
.
maxNum
}}
</text>
-->
</view>
</view>
</view>
<view
class=
"ticket-right"
>
<image
class=
"img"
:src=
"iconUrl[item.status]"
v-if=
"item.status == 0 || item.status == 2"
></image>
<view
class=
"head"
>
<text
class=
"title"
>
{{
item
.
couponName
}}
</text>
<view
class=
"headbox"
>
<text
class=
"time"
>
使用时间:
{{
item
.
userStartTime
.
slice
(
0
,
10
)
}}
-
{{
item
.
userEndTime
.
slice
(
0
,
10
)
}}
</text>
<view
class=
"btn"
@
tap=
"toShop(item.shopId)"
v-if=
"item.status == 3"
>
使用
</view>
</view>
</view>
<view
class=
"foot"
>
<view
class=
"line"
></view>
<view
class=
"footbox"
@
click=
"handleChangeDetail(index)"
>
<text
class=
"desc"
>
详细信息
</text>
<wd-icon
:name=
"item.showDetail ? 'chevron-down' : 'chevron-right'"
size=
"15px"
color=
"#9d9d9d"
></wd-icon>
</view>
</view>
</view>
</view>
<view
class=
"detail"
v-if=
"item.showDetail"
>
<view
class=
"line"
></view>
<view
class=
"detail-box"
>
<view
class=
"rowbox"
>
<text>
使用时间
</text>
<text
class=
"desc"
>
{{
item
.
userStartTime
.
slice
(
0
,
10
)
}}
-
{{
item
.
userEndTime
.
slice
(
0
,
10
)
}}
</text>
</view>
<view
class=
"rowbox"
>
<text>
使用条件
</text>
<text
class=
"desc"
>
满
{{
item
.
cashCondition
}}
元可用
</text>
</view>
<view
class=
"rowbox"
>
<text>
使用说明
</text>
<text
class=
"desc"
>
{{
item
.
couponExplain
}}
</text>
</view>
</view>
</view>
</view>
<wd-loadmore
:state=
"state"
@
reload=
"getCouponList"
/>
</view>
<wd-status-tip
image=
"content"
tip=
"暂无优惠券"
v-else
/>
</view>
</view>
</view>
</view>
</
template
>
</
template
>
...
@@ -38,18 +109,24 @@
...
@@ -38,18 +109,24 @@
<
script
setup
>
<
script
setup
>
import
{
myCouponListApi
,
userCouponStatisticsApi
}
from
'@/api/ticket'
;
import
{
myCouponListApi
,
userCouponStatisticsApi
}
from
'@/api/ticket'
;
import
Header
from
'@/pages/order/components/Header/index.vue'
;
import
Header
from
'@/pages/order/components/Header/index.vue'
;
import
TicketList
from
'@/pages/ticket/components/TicketList/index.vue'
;
const
fileDomain
=
import
.
meta
.
env
.
VITE_APP_IMG_URL
;
const
fileDomain
=
import
.
meta
.
env
.
VITE_APP_IMG_URL
;
// 优惠券状态 0:失效 2:已使用,3-未使用
const
iconUrl
=
ref
({
0
:
'@/static/ticket/past-icon.png'
,
2
:
'@/static/ticket/used-icon.png'
,
});
// 主状态
// 主状态
const
tabList
=
[
'有效优惠券'
,
'无效优惠券'
];
const
tabList
=
[
'有效优惠券'
,
'无效优惠券'
];
const
currentTab
=
ref
(
0
);
const
currentTab
=
ref
(
0
);
const
changeTab
=
(
index
)
=>
{
const
changeTab
=
(
index
)
=>
{
if
(
curren
Status
.
value
!==
index
)
{
if
(
curren
tTab
.
value
!==
index
)
{
currentTab
.
value
=
index
;
currentTab
.
value
=
parseInt
(
index
)
;
getStatistics
();
getStatistics
();
initCouponList
();
}
}
};
};
...
@@ -61,6 +138,7 @@ const changeStatus = (index) => {
...
@@ -61,6 +138,7 @@ const changeStatus = (index) => {
if
(
currenStatus
.
value
!==
index
)
{
if
(
currenStatus
.
value
!==
index
)
{
currenStatus
.
value
=
index
;
currenStatus
.
value
=
index
;
getStatistics
();
getStatistics
();
initCouponList
();
}
}
};
};
...
@@ -81,8 +159,11 @@ const getStatistics = async () => {
...
@@ -81,8 +159,11 @@ const getStatistics = async () => {
getStatistics
();
getStatistics
();
/**
/**
* 获取用户
统计
列表
* 获取用户
优惠券
列表
*/
*/
const
state
=
ref
(
'loading'
);
const
total
=
ref
(
0
);
const
couponData
=
ref
([]);
const
catalog
=
reactive
({
const
catalog
=
reactive
({
current
:
0
,
current
:
0
,
size
:
10
,
size
:
10
,
...
@@ -90,12 +171,56 @@ const catalog = reactive({
...
@@ -90,12 +171,56 @@ const catalog = reactive({
statuSon
:
0
,
statuSon
:
0
,
});
});
const
getCouponList
=
async
()
=>
{
const
getCouponList
=
async
()
=>
{
catalog
.
current
++
;
state
.
value
=
'loading'
;
catalog
.
statuMain
=
currentTab
.
value
;
catalog
.
statuMain
=
currentTab
.
value
;
catalog
.
statuSon
=
currenStatus
.
value
;
catalog
.
statuSon
=
currenStatus
.
value
;
const
res
=
await
myCouponListApi
(
catalog
);
const
res
=
await
myCouponListApi
(
catalog
);
console
.
log
(
res
);
if
(
res
.
code
===
0
)
{
if
(
res
.
data
.
records
.
length
>
0
)
{
res
.
data
.
records
.
forEach
((
item
)
=>
{
item
.
showDetail
=
false
;
});
couponData
.
value
.
push
(...
res
.
data
.
records
);
total
.
value
=
res
.
data
.
total
;
}
else
{
state
.
value
=
'finished'
;
}
}
else
{
state
.
value
=
'error'
;
}
state
.
value
=
'finished'
;
};
};
getCouponList
();
getCouponList
();
// 触底函数
onReachBottom
(()
=>
{
if
(
couponData
.
value
.
length
>=
total
.
value
)
{
state
.
value
=
'finished'
;
}
else
{
getCouponList
();
}
});
const
initCouponList
=
()
=>
{
couponData
.
value
=
[];
total
.
value
=
0
;
catalog
.
current
=
0
;
getCouponList
();
};
/**
* 修改优惠券详情显示状态
*/
const
handleChangeDetail
=
(
idx
)
=>
{
couponData
.
value
[
idx
].
showDetail
=
!
couponData
.
value
[
idx
].
showDetail
;
};
const
toShop
=
(
idx
)
=>
{
xma
.
navigateTo
({
url
:
`/pages/shop/shop?shopId=
${
idx
}
`
,
});
};
</
script
>
</
script
>
<
style
scoped
lang=
"scss"
>
<
style
scoped
lang=
"scss"
>
...
@@ -116,6 +241,7 @@ page {
...
@@ -116,6 +241,7 @@ page {
width
:
100%
;
width
:
100%
;
position
:
fixed
;
position
:
fixed
;
top
:
88rpx
;
top
:
88rpx
;
z-index
:
999
;
.tab-item
{
.tab-item
{
font-family
:
PingFang
SC
;
font-family
:
PingFang
SC
;
...
@@ -210,6 +336,224 @@ page {
...
@@ -210,6 +336,224 @@ page {
color
:
#f12a2a
;
color
:
#f12a2a
;
}
}
}
}
.ticket-list
{
display
:
flex
;
flex-direction
:
column
;
gap
:
36rpx
;
.ticket-item
{
width
:
100%
;
background-color
:
#fff
;
border-radius
:
16rpx
;
display
:
flex
;
flex-direction
:
column
;
.ticket-box
{
display
:
flex
;
.normal
{
background
:
url('../../static/ticket/ticket-normal.png')
no-repeat
;
background-size
:
100%
100%
;
}
.past
{
background
:
url('../../static/ticket/ticket-past.png')
no-repeat
;
background-size
:
100%
100%
;
}
.ticket-left
{
width
:
200rpx
;
height
:
200rpx
;
.ticket-box
{
width
:
94%
;
height
:
100%
;
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
justify-content
:
center
;
gap
:
30rpx
;
.ticket-price
{
display
:
flex
;
align-items
:
last
baseline
;
text
{
font-size
:
24rpx
;
line-height
:
24rpx
;
font-family
:
PingFang
SC
;
color
:
#fff
;
}
.num
{
font-size
:
52rpx
;
}
}
.ticket-desc
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
gap
:
24rpx
;
.desc
{
font-size
:
24rpx
;
line-height
:
24rpx
;
font-family
:
PingFang
SC
;
color
:
#fff
;
}
}
}
}
.ticket-right
{
display
:
flex
;
flex-direction
:
column
;
width
:
504rpx
;
position
:
relative
;
.img
{
width
:
126rpx
;
height
:
94rpx
;
position
:
absolute
;
right
:
28rpx
;
top
:
26rpx
;
}
.head
{
display
:
flex
;
flex-direction
:
column
;
padding
:
30rpx
22rpx
26rpx
32rpx
;
gap
:
4rpx
;
.title
{
font-family
:
PingFang
SC
Heavy-Regular
;
font-size
:
32rpx
;
color
:
#333333
;
line-height
:
32rpx
;
}
.headbox
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
end
;
height
:
50rpx
;
.time
{
font-family
:
PingFang
SC
Heavy-Regular
;
font-size
:
20rpx
;
color
:
#999999
;
line-height
:
20rpx
;
}
.btn
{
width
:
102rpx
;
height
:
50rpx
;
box-sizing
:
border-box
;
border-radius
:
26rpx
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
background
:
linear-gradient
(
90deg
,
#ff7051
0%
,
#ff382e
100%
);
color
:
#fff
;
font-size
:
24rpx
;
line-height
:
24rpx
;
}
}
}
.foot
{
display
:
flex
;
flex-direction
:
column
;
padding
:
0
22rpx
14rpx
32rpx
;
gap
:
14rpx
;
.line
{
border-top
:
2rpx
solid
#f2f2f2
;
}
.footbox
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
.desc
{
font-family
:
PingFang
SC
Heavy-Regular
;
font-size
:
20rpx
;
color
:
#999999
;
line-height
:
20rpx
;
}
}
}
}
}
.detail
{
display
:
flex
;
flex-direction
:
column
;
padding
:
24rpx
0rpx
56rpx
0rpx
;
gap
:
30rpx
;
.line
{
border-top
:
2rpx
solid
#e7e7e7
;
}
.detail-box
{
display
:
flex
;
flex-direction
:
column
;
gap
:
40rpx
;
padding
:
0
40rpx
0
22rpx
;
.rowbox
{
display
:
flex
;
flex-direction
:
row
;
gap
:
48rpx
;
text
{
font-family
:
PingFang
SC
Regular
;
font-size
:
28rpx
;
color
:
#666666
;
line-height
:
28rpx
;
}
.desc
{
width
:
476rpx
;
}
}
}
}
}
.coupon-tips
{
width
:
100%
;
background-color
:
#fff
;
border-radius
:
16rpx
;
display
:
flex
;
flex-direction
:
column
;
padding
:
40rpx
46rpx
40rpx
;
// min-height: 436rpx;
box-sizing
:
border-box
;
gap
:
38rpx
;
.tips
{
font-family
:
PingFang
SC
Bold-Regular
;
font-size
:
32rpx
;
color
:
#333333
;
line-height
:
32rpx
;
text-align
:
center
;
}
.desc
{
white-space
:
pre-line
;
/* 将空格和换行符保留在文本中 */
font-family
:
PingFang
SC
Regular
;
font-size
:
24rpx
;
color
:
#333333
;
line-height
:
36rpx
;
text-align
:
left
;
}
}
}
}
}
}
}
</
style
>
</
style
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment