791 lines
20 KiB
Vue
791 lines
20 KiB
Vue
<template>
|
||
<view class="service-records-page">
|
||
<!-- 头部区域 -->
|
||
<NavHeader title="服务记录" />
|
||
|
||
<!-- Tab 切换 -->
|
||
<view class="tab-bar">
|
||
<view
|
||
class="tab-item"
|
||
:class="{ active: currentTab === 'pending_payment' }"
|
||
@click="switchTab('pending_payment')"
|
||
>
|
||
<text class="tab-text">待支付</text>
|
||
</view>
|
||
<view
|
||
class="tab-item"
|
||
:class="{ active: currentTab === 'pending_verification' }"
|
||
@click="switchTab('pending_verification')"
|
||
>
|
||
<text class="tab-text">已完成</text>
|
||
</view>
|
||
<view
|
||
class="tab-item"
|
||
:class="{ active: currentTab === 'chargeback' }"
|
||
@click="switchTab('chargeback')"
|
||
>
|
||
<text class="tab-text">已退款</text>
|
||
</view>
|
||
<view
|
||
class="tab-item"
|
||
:class="{ active: currentTab === 'cancelled' }"
|
||
@click="switchTab('cancelled')"
|
||
>
|
||
<text class="tab-text">已取消</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 列表内容 -->
|
||
<scroll-view
|
||
class="record-list"
|
||
scroll-y="true"
|
||
:refresher-enabled="true"
|
||
:refresher-triggered="refreshing"
|
||
@refresherrefresh="handleRefresh"
|
||
@scrolltolower="handleLoadMore"
|
||
:lower-threshold="100"
|
||
>
|
||
<!-- 空数据提示 -->
|
||
<view class="empty-state" v-if="!loading && currentList.length === 0">
|
||
<image
|
||
class="empty-icon"
|
||
src="/static/home/entry_icon.png"
|
||
mode="aspectFit"
|
||
></image>
|
||
<text class="empty-text">暂无{{ getTabLabel() }}记录</text>
|
||
</view>
|
||
|
||
<!-- 记录列表项 -->
|
||
<view
|
||
class="record-item"
|
||
v-for="(item, index) in currentList"
|
||
:key="index"
|
||
>
|
||
<!-- 头部:门店 + 状态 -->
|
||
<view class="record-header">
|
||
<view class="record-shop-row">
|
||
<text class="shop-name">{{ item.shopName }}</text>
|
||
<view class="status-badge" :class="getStatusClass(item.status)">
|
||
<text class="status-text">{{ getStatusText(item.status) }}</text>
|
||
</view>
|
||
</view>
|
||
<text class="record-time">{{ formatTime(item.createTime) }}</text>
|
||
</view>
|
||
|
||
<!-- 中部:类似商品卡片 -->
|
||
<view class="record-body" @click="handleRecordClick(item)">
|
||
<view
|
||
class="record-goods"
|
||
v-for="(goods, gIndex) in getGoodsList(item)"
|
||
:key="goods.id || goods.couponId || gIndex"
|
||
>
|
||
<image
|
||
class="goods-image"
|
||
:src="
|
||
goods.coverUrl ||
|
||
goods.couponCoverUrl ||
|
||
goods.picUrl ||
|
||
'/static/home/entry_icon.png'
|
||
"
|
||
mode="aspectFill"
|
||
></image>
|
||
<view class="goods-info">
|
||
<text class="goods-title">{{ goods.couponName || goods.name }}</text>
|
||
<!-- <text class="goods-subtitle">
|
||
订单号:{{ item.orderNumber }}
|
||
</text> -->
|
||
<view class="goods-meta-row">
|
||
<text class="goods-price">¥{{ formatFen(goods.salePrice) }}</text>
|
||
<text
|
||
class="goods-count"
|
||
v-if="(goods.num || goods.count || goods.quantity || goods.qty) > 1"
|
||
>
|
||
×{{ goods.num || goods.count || goods.quantity || goods.qty }}
|
||
</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 底部:合计 + 操作按钮 -->
|
||
<view class="record-footer">
|
||
<view class="total-info">
|
||
<text class="total-label">实付款:</text>
|
||
<text class="total-amount">¥{{ formatFen(item.payableAmount) }}</text>
|
||
</view>
|
||
|
||
<!-- 操作按钮区域 -->
|
||
<view class="record-actions" v-if="item.status === 0">
|
||
<button
|
||
class="action-btn cancel-btn"
|
||
@click.stop="handleCancel(item)"
|
||
>
|
||
取消订单
|
||
</button>
|
||
<button class="action-btn pay-btn" @click.stop="handlePay(item)">
|
||
立即支付
|
||
</button>
|
||
</view>
|
||
<view class="record-actions" v-else-if="item.status === 1">
|
||
<!-- <button
|
||
class="action-btn detail-btn"
|
||
@click.stop="handleViewDetail(item)"
|
||
>
|
||
去核销
|
||
</button> -->
|
||
</view>
|
||
<view class="record-actions" v-else-if="item.status === 3">
|
||
<!-- <button
|
||
class="action-btn detail-btn"
|
||
@click.stop="handleViewDetail(item)"
|
||
>
|
||
查看详情
|
||
</button>
|
||
<button
|
||
class="action-btn review-btn"
|
||
@click.stop="handleReview(item)"
|
||
>
|
||
评价
|
||
</button> -->
|
||
</view>
|
||
<view class="record-actions" v-else-if="item.status === 4">
|
||
<button
|
||
class="action-btn detail-btn"
|
||
@click.stop="handleViewDetail(item)"
|
||
>
|
||
删除
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 加载更多提示 -->
|
||
<view class="load-more" v-if="currentList.length > 0">
|
||
<text v-if="loadingMore" class="load-more-text">加载中...</text>
|
||
<text v-else-if="!hasMore" class="load-more-text">没有更多数据了</text>
|
||
<text v-else class="load-more-text">上拉加载更多</text>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import NavHeader from "@/components/NavHeader/NavHeader.vue";
|
||
import { getLuMyOrderPage, cancelOrder, getPaySign } from "@/api/service";
|
||
|
||
export default {
|
||
components: {
|
||
NavHeader,
|
||
},
|
||
data() {
|
||
return {
|
||
currentTab: "pending_payment", // 当前选中的 tab
|
||
refreshing: false,
|
||
loading: false,
|
||
loadingMore: false,
|
||
hasMore: true,
|
||
pageNo: 1,
|
||
pageSize: 10,
|
||
// 各状态对应的订单列表
|
||
recordsMap: {
|
||
pending_payment: [],
|
||
pending_verification: [],
|
||
completed: [],
|
||
cancelled: [],
|
||
},
|
||
};
|
||
},
|
||
computed: {
|
||
currentList() {
|
||
return this.recordsMap[this.currentTab] || [];
|
||
},
|
||
},
|
||
onLoad(options) {
|
||
// 如果通过参数传入 tab,优先使用传入的 tab 值
|
||
if (options && options.tab) {
|
||
this.currentTab = options.tab;
|
||
}
|
||
this.loadData();
|
||
},
|
||
methods: {
|
||
// 一个订单可能包含多个商品(couponPurchaseRespVOS)
|
||
getGoodsList(order) {
|
||
const list = (order && order.couponPurchaseRespVOS) || [];
|
||
return Array.isArray(list) && list.length ? list : [order || {}];
|
||
},
|
||
// 金额分转元(去掉后两位)
|
||
formatFen(fen) {
|
||
const n = Number(fen);
|
||
if (!Number.isFinite(n)) return fen || "0.00";
|
||
return (n / 100).toFixed(2);
|
||
},
|
||
// 时间戳转可读时间(支持秒/毫秒)
|
||
formatTime(val) {
|
||
if (val == null || val === "") return "";
|
||
let ts = Number(val);
|
||
if (!Number.isFinite(ts)) return val;
|
||
if (String(ts).length <= 10) ts *= 1000;
|
||
const d = new Date(ts);
|
||
const y = d.getFullYear();
|
||
const m = String(d.getMonth() + 1).padStart(2, "0");
|
||
const day = String(d.getDate()).padStart(2, "0");
|
||
const h = String(d.getHours()).padStart(2, "0");
|
||
const min = String(d.getMinutes()).padStart(2, "0");
|
||
const s = String(d.getSeconds()).padStart(2, "0");
|
||
return `${y}-${m}-${day} ${h}:${min}:${s}`;
|
||
},
|
||
// 根据当前 tab 映射到接口所需的 status 值
|
||
getStatusValue() {
|
||
const map = {
|
||
pending_payment: 0, // 待支付
|
||
pending_verification: 1, // 已完成
|
||
chargeback: 3, // 已退款
|
||
cancelled: 4, // 已取消
|
||
};
|
||
return map[this.currentTab];
|
||
},
|
||
// 切换 Tab
|
||
switchTab(tab) {
|
||
if (this.currentTab === tab) return;
|
||
this.currentTab = tab;
|
||
this.pageNo = 1;
|
||
this.hasMore = true;
|
||
this.loadData();
|
||
},
|
||
// 获取 Tab 标签文本
|
||
getTabLabel() {
|
||
const labels = {
|
||
pending_payment: "待支付",
|
||
pending_verification: "待核销",
|
||
completed: "已完成",
|
||
cancelled: "已取消",
|
||
};
|
||
return labels[this.currentTab] || "";
|
||
},
|
||
// 获取状态文本
|
||
getStatusText(status) {
|
||
return status === 0
|
||
? "待支付"
|
||
: status === 1
|
||
? "已完成"
|
||
: status === 3
|
||
? "已退款"
|
||
: status === 4
|
||
? "已取消"
|
||
: "";
|
||
},
|
||
// 获取状态样式类
|
||
getStatusClass(status) {
|
||
return status === 0
|
||
? "status-pending"
|
||
: status === 1
|
||
? "status-verification"
|
||
: status === 3
|
||
? "status-completed"
|
||
: status === 4
|
||
? "status-cancelled"
|
||
: "";
|
||
},
|
||
// 加载数据
|
||
async loadData(append = false) {
|
||
if (this.loading) return;
|
||
this.loading = true;
|
||
const status = this.getStatusValue();
|
||
try {
|
||
const res = await getLuMyOrderPage({
|
||
pageNo: this.pageNo,
|
||
pageSize: this.pageSize,
|
||
status,
|
||
});
|
||
const list = res.list || [];
|
||
|
||
const currentList = this.recordsMap[this.currentTab] || [];
|
||
this.recordsMap = {
|
||
...this.recordsMap,
|
||
[this.currentTab]: append ? currentList.concat(list) : list,
|
||
};
|
||
|
||
// 是否还有更多
|
||
this.hasMore = list.length >= this.pageSize;
|
||
} catch (e) {
|
||
console.error("加载服务记录失败:", e);
|
||
uni.showToast({
|
||
title: "加载服务记录失败",
|
||
icon: "none",
|
||
});
|
||
} finally {
|
||
this.loading = false;
|
||
this.refreshing = false;
|
||
this.loadingMore = false;
|
||
}
|
||
},
|
||
// 下拉刷新
|
||
handleRefresh() {
|
||
this.refreshing = true;
|
||
this.pageNo = 1;
|
||
this.hasMore = true;
|
||
this.loadData();
|
||
},
|
||
// 上拉加载更多
|
||
handleLoadMore() {
|
||
if (this.hasMore && !this.loadingMore && !this.loading) {
|
||
this.loadingMore = true;
|
||
this.pageNo += 1;
|
||
this.loadData(true);
|
||
}
|
||
},
|
||
// 点击记录项
|
||
handleRecordClick(item) {
|
||
// 可以跳转到详情页
|
||
console.log("点击记录:", item);
|
||
},
|
||
// 取消订单
|
||
handleCancel(item) {
|
||
uni.showModal({
|
||
title: "提示",
|
||
content: "确定要取消该订单吗?",
|
||
success: async (res) => {
|
||
if (res.confirm) {
|
||
// 这里应该调用接口取消订单,然后刷新列表
|
||
const res = await cancelOrder({
|
||
id: item.id,
|
||
});
|
||
if (res) {
|
||
uni.showToast({
|
||
title: "订单已取消",
|
||
icon: "success",
|
||
});
|
||
this.loadData();
|
||
}
|
||
}
|
||
},
|
||
});
|
||
},
|
||
// 立即支付(与店铺详情页 handlePay 逻辑一致,跳转收银台小程序)
|
||
async handlePay(item) {
|
||
if (!item || !item.orderNumber) {
|
||
uni.showToast({ title: "订单信息异常", icon: "none" });
|
||
return;
|
||
}
|
||
const couponArray = item.couponPurchaseRespVOS || [];
|
||
const couponMap = new Map();
|
||
couponArray.forEach((goods) => {
|
||
const key = goods.couponId;
|
||
if (!key) return;
|
||
const currentList = couponMap.get(key) || [];
|
||
currentList.push(goods);
|
||
couponMap.set(key, currentList);
|
||
});
|
||
let bodyStr = "";
|
||
couponMap.forEach((couponList) => {
|
||
bodyStr =
|
||
bodyStr +
|
||
(couponList[0] && couponList[0].couponName
|
||
? couponList[0].couponName
|
||
: "商品") +
|
||
"x" +
|
||
couponList.length +
|
||
";";
|
||
});
|
||
|
||
const randomstr = Math.floor(Math.random() * 10000000) + "";
|
||
const trxamt =
|
||
item.payableAmount != null && item.payableAmount !== ""
|
||
? String(item.payableAmount)
|
||
: "1";
|
||
const params = {
|
||
appid: "00390105",
|
||
body: bodyStr,
|
||
cusid: "56479107531MPMN",
|
||
notify_url:
|
||
"http://e989c692.natappfree.cc/admin-api/member/lu-order/tlNotice",
|
||
orgid: "56479107392N35H",
|
||
paytype: "W06",
|
||
randomstr: randomstr,
|
||
orderNumber: item.orderNumber,
|
||
remark: "1:" + item.orderNumber + ":" + bodyStr,
|
||
reqsn: item.orderNumber,
|
||
sign: "",
|
||
signtype: "RSA",
|
||
trxamt,
|
||
version: "12",
|
||
};
|
||
|
||
if (item.orderNumber) {
|
||
uni.setStorageSync("lastOrderNumber", item.orderNumber);
|
||
}
|
||
|
||
try {
|
||
const sign = await getPaySign(params);
|
||
params["sign"] = sign;
|
||
uni.navigateToMiniProgram({
|
||
appId: "wxef277996acc166c3",
|
||
extraData: params,
|
||
success(res) {
|
||
console.log("小程序跳转成功", res);
|
||
},
|
||
fail(err) {
|
||
console.error("小程序跳转失败", err);
|
||
uni.showToast({ title: "跳转失败,请稍后重试", icon: "none" });
|
||
},
|
||
});
|
||
} catch (e) {
|
||
console.error("获取支付签名失败:", e);
|
||
uni.showToast({ title: "支付准备失败,请稍后重试", icon: "none" });
|
||
}
|
||
},
|
||
// 查看详情
|
||
handleViewDetail(item) {
|
||
uni.showToast({
|
||
title: "该功能正在开发中",
|
||
icon: "none",
|
||
});
|
||
},
|
||
// 评价
|
||
handleReview(item) {
|
||
uni.showToast({
|
||
title: "该功能正在开发中",
|
||
icon: "none",
|
||
});
|
||
},
|
||
},
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.service-records-page {
|
||
min-height: 100vh;
|
||
background: #e2e8f1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
/* Tab 切换栏 */
|
||
.tab-bar {
|
||
display: flex;
|
||
padding: 0 20rpx;
|
||
|
||
.tab-item {
|
||
flex: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: 88rpx;
|
||
position: relative;
|
||
|
||
.tab-text {
|
||
font-family: PingFang-SC, PingFang-SC;
|
||
font-weight: 500;
|
||
font-size: 28rpx;
|
||
color: #999999;
|
||
}
|
||
|
||
&.active {
|
||
.tab-text {
|
||
color: #004294;
|
||
font-weight: 600;
|
||
}
|
||
|
||
&::after {
|
||
content: "";
|
||
position: absolute;
|
||
bottom: 0;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
width: 60rpx;
|
||
height: 4rpx;
|
||
background-color: #004294;
|
||
border-radius: 2rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 列表区域 */
|
||
.record-list {
|
||
flex: 1;
|
||
padding: 20rpx;
|
||
height: 0; // 配合 flex: 1 使用
|
||
box-sizing: border-box;
|
||
|
||
/* 空数据提示 */
|
||
.empty-state {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 200rpx 0;
|
||
min-height: 500rpx;
|
||
|
||
.empty-icon {
|
||
width: 200rpx;
|
||
height: 200rpx;
|
||
margin-bottom: 40rpx;
|
||
opacity: 0.5;
|
||
}
|
||
|
||
.empty-text {
|
||
font-family: PingFang-SC, PingFang-SC;
|
||
font-weight: 500;
|
||
font-size: 28rpx;
|
||
color: #999999;
|
||
}
|
||
}
|
||
|
||
/* 加载更多提示 */
|
||
.load-more {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
padding: 40rpx 0;
|
||
min-height: 80rpx;
|
||
|
||
.load-more-text {
|
||
font-family: PingFang-SC, PingFang-SC;
|
||
font-weight: 400;
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
}
|
||
}
|
||
|
||
/* 记录项 */
|
||
.record-item {
|
||
background-color: #ffffff;
|
||
border-radius: 20rpx;
|
||
margin-bottom: 20rpx;
|
||
padding: 24rpx 24rpx 20rpx;
|
||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
|
||
|
||
.record-header {
|
||
margin-bottom: 16rpx;
|
||
|
||
.record-shop-row {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: 8rpx;
|
||
|
||
.shop-name {
|
||
flex: 1;
|
||
font-family: PingFang-SC, PingFang-SC;
|
||
font-weight: 600;
|
||
font-size: 28rpx;
|
||
color: #1a1819;
|
||
}
|
||
|
||
.status-badge {
|
||
padding: 6rpx 16rpx;
|
||
border-radius: 20rpx;
|
||
font-size: 22rpx;
|
||
|
||
.status-text {
|
||
font-family: PingFang-SC, PingFang-SC;
|
||
font-weight: 500;
|
||
}
|
||
|
||
&.status-pending {
|
||
background-color: rgba(255, 107, 0, 0.1);
|
||
.status-text {
|
||
color: #ff6b00;
|
||
}
|
||
}
|
||
|
||
&.status-verification {
|
||
background-color: rgba(0, 66, 148, 0.1);
|
||
.status-text {
|
||
color: #004294;
|
||
}
|
||
}
|
||
|
||
&.status-completed {
|
||
background-color: rgba(76, 175, 80, 0.1);
|
||
.status-text {
|
||
color: #4caf50;
|
||
}
|
||
}
|
||
|
||
&.status-cancelled {
|
||
background-color: rgba(158, 158, 158, 0.1);
|
||
.status-text {
|
||
color: #9e9e9e;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.record-time {
|
||
font-family: PingFang-SC, PingFang-SC;
|
||
font-weight: 400;
|
||
font-size: 22rpx;
|
||
color: #999999;
|
||
}
|
||
}
|
||
|
||
.record-content {
|
||
margin-bottom: 24rpx;
|
||
|
||
.record-info-row {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
margin-bottom: 16rpx;
|
||
line-height: 1.5;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.info-label {
|
||
font-family: PingFang-SC, PingFang-SC;
|
||
font-weight: 500;
|
||
font-size: 24rpx;
|
||
color: #888888;
|
||
margin-right: 8rpx;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.info-value {
|
||
font-family: PingFang-SC, PingFang-SC;
|
||
font-weight: 500;
|
||
font-size: 24rpx;
|
||
color: #333333;
|
||
flex: 1;
|
||
|
||
&.price {
|
||
color: #d51c3c;
|
||
font-weight: 600;
|
||
font-size: 28rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.record-body {
|
||
background-color: #f8f9fb;
|
||
border-radius: 16rpx;
|
||
padding: 18rpx;
|
||
|
||
.record-goods {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 16rpx;
|
||
|
||
.goods-image {
|
||
width: 120rpx;
|
||
height: 120rpx;
|
||
border-radius: 12rpx;
|
||
margin-right: 16rpx;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.goods-info {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 8rpx;
|
||
|
||
.goods-title {
|
||
font-family: PingFang-SC, PingFang-SC;
|
||
font-weight: 500;
|
||
font-size: 26rpx;
|
||
color: #1a1819;
|
||
}
|
||
|
||
.goods-subtitle {
|
||
font-family: PingFang-SC, PingFang-SC;
|
||
font-weight: 400;
|
||
font-size: 22rpx;
|
||
color: #888888;
|
||
}
|
||
|
||
.goods-meta-row {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-top: 4rpx;
|
||
|
||
.goods-price {
|
||
font-family: PingFang-SC, PingFang-SC;
|
||
font-weight: 600;
|
||
font-size: 28rpx;
|
||
color: #d51c3c;
|
||
}
|
||
|
||
.goods-count {
|
||
font-family: PingFang-SC, PingFang-SC;
|
||
font-weight: 400;
|
||
font-size: 22rpx;
|
||
color: #666666;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.record-footer {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-top: 4rpx;
|
||
|
||
.total-info {
|
||
display: flex;
|
||
align-items: baseline;
|
||
|
||
.total-label {
|
||
font-family: PingFang-SC, PingFang-SC;
|
||
font-weight: 400;
|
||
font-size: 22rpx;
|
||
color: #666666;
|
||
}
|
||
|
||
.total-amount {
|
||
margin-left: 4rpx;
|
||
font-family: PingFang-SC, PingFang-SC;
|
||
font-weight: 600;
|
||
font-size: 30rpx;
|
||
color: #1a1819;
|
||
}
|
||
}
|
||
|
||
.record-actions {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 16rpx;
|
||
|
||
button {
|
||
margin: 0;
|
||
padding: 0;
|
||
}
|
||
|
||
.action-btn {
|
||
min-width: 150rpx;
|
||
height: 56rpx;
|
||
padding: 0 20rpx;
|
||
font-family: PingFang-SC, PingFang-SC;
|
||
font-weight: 500;
|
||
font-size: 24rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.pay-btn {
|
||
background-color: #004294;
|
||
color: #ffffff;
|
||
}
|
||
|
||
.detail-btn {
|
||
background-color: #f5f5f5;
|
||
color: #666666;
|
||
}
|
||
|
||
.review-btn {
|
||
background-color: #004294;
|
||
color: #ffffff;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|