17 changed files with 3529 additions and 617 deletions
@ -0,0 +1,818 @@ |
|||||
|
<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> |
||||
|
</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> |
||||
|
<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> |
||||
|
<view class="info-item"> |
||||
|
<text class="label">支付方式:</text> |
||||
|
<text class="value">{{ orderDetail.payMethod || "微信支付" }}</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 权益商品包 --> |
||||
|
<view class="package-section"> |
||||
|
<view class="section-title">权益商品包</view> |
||||
|
<view class="package-name">{{ orderDetail.packageName }}</view> |
||||
|
</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> |
||||
|
</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> |
||||
|
<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> |
||||
|
<view class="cost-item" v-if="orderDetail.discountAmount > 0"> |
||||
|
<text class="cost-label">优惠金额</text> |
||||
|
<text class="cost-value discount" |
||||
|
>-¥{{ orderDetail.discountAmount }}</text |
||||
|
> |
||||
|
</view> |
||||
|
<view class="cost-item total"> |
||||
|
<text class="cost-label">实付金额</text> |
||||
|
<text class="cost-value">¥{{ orderDetail.totalAmount }}</text> |
||||
|
</view> |
||||
|
</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> |
||||
|
<text class="receiver-address">{{ |
||||
|
orderDetail.address.fullAddress |
||||
|
}}</text> |
||||
|
</view> |
||||
|
<view class="no-address" v-else> |
||||
|
<text>该订单无需收货地址</text> |
||||
|
</view> |
||||
|
</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" |
||||
|
> |
||||
|
立即支付 |
||||
|
</button> |
||||
|
<button |
||||
|
class="action-btn primary" |
||||
|
v-if="orderDetail.status === 3" |
||||
|
@click="buyAgain" |
||||
|
> |
||||
|
再次购买 |
||||
|
</button> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 权益码弹窗 --> |
||||
|
<view |
||||
|
class="equity-popup-mask" |
||||
|
v-if="showEquityPopup" |
||||
|
@click="closeEquityPopup" |
||||
|
> |
||||
|
<view class="equity-popup" @click.stop> |
||||
|
<view class="popup-header"> |
||||
|
<text class="popup-title">权益码</text> |
||||
|
<text class="popup-close" @click="closeEquityPopup">×</text> |
||||
|
</view> |
||||
|
<view class="popup-content"> |
||||
|
<!-- 二维码 --> |
||||
|
<view class="qrcode-container"> |
||||
|
<image |
||||
|
class="qrcode-image" |
||||
|
:src="orderDetail.qrcode" |
||||
|
mode="aspectFit" |
||||
|
/> |
||||
|
</view> |
||||
|
<!-- 编号串码 --> |
||||
|
<view class="code-container"> |
||||
|
<text class="code-label">权益码:</text> |
||||
|
<text class="code-value" @longpress="copyEquityCode">{{ |
||||
|
orderDetail.equityCode |
||||
|
}}</text> |
||||
|
</view> |
||||
|
<text class="code-tip">长按编号可复制</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
orderId: "", |
||||
|
showEquityPopup: false, |
||||
|
orderDetail: { |
||||
|
id: "", |
||||
|
orderNo: "", |
||||
|
status: 0, |
||||
|
packageName: "", |
||||
|
goodsList: [], |
||||
|
totalAmount: "0.00", |
||||
|
goodsAmount: "0.00", |
||||
|
discountAmount: "0.00", |
||||
|
createTime: "", |
||||
|
payTime: "", |
||||
|
payMethod: "", |
||||
|
equityCode: "", |
||||
|
qrcode: "", |
||||
|
address: null, |
||||
|
}, |
||||
|
}; |
||||
|
}, |
||||
|
computed: { |
||||
|
// 是否有实体商品需要收货 |
||||
|
hasPhysicalGoods() { |
||||
|
return this.orderDetail.goodsList.some((goods) => goods.type === 2); |
||||
|
}, |
||||
|
// 是否显示底部操作按钮 |
||||
|
showBottomActions() { |
||||
|
return [0, 3].includes(this.orderDetail.status); |
||||
|
}, |
||||
|
}, |
||||
|
onLoad(options) { |
||||
|
if (options.id) { |
||||
|
this.orderId = options.id; |
||||
|
this.loadOrderDetail(); |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
// 加载订单详情 |
||||
|
async loadOrderDetail() { |
||||
|
try { |
||||
|
uni.showLoading({ title: "加载中..." }); |
||||
|
const res = await this.getOrderDetail(this.orderId); |
||||
|
this.orderDetail = res.data; |
||||
|
} catch (error) { |
||||
|
console.error("加载订单详情失败:", error); |
||||
|
uni.showToast({ |
||||
|
title: "加载失败", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
} finally { |
||||
|
uni.hideLoading(); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 获取状态图标 |
||||
|
getStatusIcon(status) { |
||||
|
const iconMap = { |
||||
|
0: "/static/icon/status-pending.png", |
||||
|
1: "/static/icon/status-waiting.png", |
||||
|
2: "/static/icon/status-shipping.png", |
||||
|
3: "/static/icon/status-completed.png", |
||||
|
4: "/static/icon/status-refund.png", |
||||
|
}; |
||||
|
return iconMap[status] || "/static/icon/status-default.png"; |
||||
|
}, |
||||
|
|
||||
|
// 获取状态文本 |
||||
|
getStatusText(status) { |
||||
|
const statusMap = { |
||||
|
0: "待付款", |
||||
|
1: "待使用", |
||||
|
2: "待收货", |
||||
|
3: "已完成", |
||||
|
4: "售后/退款", |
||||
|
}; |
||||
|
return statusMap[status] || "未知状态"; |
||||
|
}, |
||||
|
|
||||
|
// 获取状态描述 |
||||
|
getStatusDesc(status) { |
||||
|
const descMap = { |
||||
|
0: "请尽快完成支付", |
||||
|
1: "权益商品可随时使用", |
||||
|
2: "商品正在配送中", |
||||
|
3: "订单已完成,感谢您的购买", |
||||
|
4: "退款处理中", |
||||
|
}; |
||||
|
return descMap[status] || ""; |
||||
|
}, |
||||
|
|
||||
|
// 获取商品类型名称 |
||||
|
getGoodsTypeName(type) { |
||||
|
const typeMap = { |
||||
|
1: "IP数字资产", |
||||
|
2: "IP资源商品", |
||||
|
3: "君道苏州门票", |
||||
|
}; |
||||
|
return typeMap[type] || "未知类型"; |
||||
|
}, |
||||
|
|
||||
|
// 复制订单号 |
||||
|
copyOrderNo() { |
||||
|
uni.setClipboardData({ |
||||
|
data: this.orderDetail.orderNo, |
||||
|
success: () => { |
||||
|
uni.showToast({ |
||||
|
title: "订单号已复制", |
||||
|
icon: "success", |
||||
|
}); |
||||
|
}, |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
// 显示权益码 |
||||
|
showEquityCode() { |
||||
|
this.showEquityPopup = true; |
||||
|
}, |
||||
|
|
||||
|
// 关闭权益码弹窗 |
||||
|
closeEquityPopup() { |
||||
|
this.showEquityPopup = false; |
||||
|
}, |
||||
|
|
||||
|
// 复制权益码 |
||||
|
copyEquityCode() { |
||||
|
uni.setClipboardData({ |
||||
|
data: this.orderDetail.equityCode, |
||||
|
success: () => { |
||||
|
uni.showToast({ |
||||
|
title: "权益码已复制", |
||||
|
icon: "success", |
||||
|
}); |
||||
|
}, |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
// 取消订单 |
||||
|
async cancelOrder() { |
||||
|
const res = await uni.showModal({ |
||||
|
title: "确认取消", |
||||
|
content: "确定要取消这个订单吗?", |
||||
|
}); |
||||
|
|
||||
|
if (res.confirm) { |
||||
|
try { |
||||
|
await this.cancelOrderApi(this.orderId); |
||||
|
uni.showToast({ |
||||
|
title: "订单已取消", |
||||
|
icon: "success", |
||||
|
}); |
||||
|
this.loadOrderDetail(); |
||||
|
} catch (error) { |
||||
|
uni.showToast({ |
||||
|
title: "取消失败", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 支付订单 |
||||
|
payOrder() { |
||||
|
// 跳转到支付页面或调用支付接口 |
||||
|
uni.navigateTo({ |
||||
|
url: `/pages/payment/index?orderId=${this.orderId}`, |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
// 再次购买 |
||||
|
buyAgain() { |
||||
|
// 跳转到商品页面 |
||||
|
uni.navigateTo({ |
||||
|
url: `/subPackages/equityGoods/detail?id=${this.orderDetail.packageId}`, |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
// 格式化时间 |
||||
|
formatTime(time) { |
||||
|
if (!time) return ""; |
||||
|
const date = new Date(time); |
||||
|
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart( |
||||
|
2, |
||||
|
"0" |
||||
|
)}-${String(date.getDate()).padStart(2, "0")} ${String( |
||||
|
date.getHours() |
||||
|
).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}`; |
||||
|
}, |
||||
|
|
||||
|
// API接口 - 获取订单详情 |
||||
|
async getOrderDetail(orderId) { |
||||
|
// 模拟API数据 |
||||
|
return new Promise((resolve) => { |
||||
|
setTimeout(() => { |
||||
|
const mockData = { |
||||
|
code: 200, |
||||
|
data: { |
||||
|
id: orderId, |
||||
|
orderNo: "EQ202401011234567", |
||||
|
status: 1, |
||||
|
packageName: "Epic Soul限定权益包", |
||||
|
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: "微信支付", |
||||
|
equityCode: "EPIC2024010112345", |
||||
|
qrcode: "/static/image/qrcode-sample.png", |
||||
|
goodsList: [ |
||||
|
{ |
||||
|
id: 1, |
||||
|
name: "数字藏品-桃子系列", |
||||
|
type: 1, |
||||
|
price: "99.00", |
||||
|
quantity: 1, |
||||
|
image: "/static/image/goods1.jpg", |
||||
|
spec: "限量版", |
||||
|
}, |
||||
|
{ |
||||
|
id: 2, |
||||
|
name: "文创周边产品", |
||||
|
type: 2, |
||||
|
price: "150.00", |
||||
|
quantity: 1, |
||||
|
image: "/static/image/goods2.jpg", |
||||
|
spec: "桃花主题", |
||||
|
}, |
||||
|
{ |
||||
|
id: 3, |
||||
|
name: "君道苏州体验门票", |
||||
|
type: 3, |
||||
|
price: "50.00", |
||||
|
quantity: 1, |
||||
|
image: "/static/image/goods3.jpg", |
||||
|
spec: "成人票", |
||||
|
}, |
||||
|
], |
||||
|
address: { |
||||
|
name: "张三", |
||||
|
phone: "138****8888", |
||||
|
fullAddress: "江苏省苏州市工业园区某某街道某某小区1号楼101室", |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
resolve(mockData); |
||||
|
}, 500); |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
// API接口 - 取消订单 |
||||
|
async cancelOrderApi(orderId) { |
||||
|
return new Promise((resolve) => { |
||||
|
setTimeout(() => { |
||||
|
resolve({ code: 200, message: "取消成功" }); |
||||
|
}, 500); |
||||
|
}); |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.order-detail-container { |
||||
|
min-height: 100vh; |
||||
|
background-color: #f5f5f5; |
||||
|
padding-bottom: 140rpx; |
||||
|
} |
||||
|
|
||||
|
// 状态区域 |
||||
|
.status-section { |
||||
|
background-color: #fff; |
||||
|
padding: 40rpx 30rpx; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
margin-bottom: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.status-icon { |
||||
|
margin-right: 30rpx; |
||||
|
|
||||
|
.icon { |
||||
|
width: 80rpx; |
||||
|
height: 80rpx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.status-info { |
||||
|
flex: 1; |
||||
|
} |
||||
|
|
||||
|
.status-text { |
||||
|
display: block; |
||||
|
font-size: 32rpx; |
||||
|
font-weight: bold; |
||||
|
color: #333; |
||||
|
margin-bottom: 10rpx; |
||||
|
} |
||||
|
|
||||
|
.status-desc { |
||||
|
font-size: 26rpx; |
||||
|
color: #666; |
||||
|
} |
||||
|
|
||||
|
// 通用区域样式 |
||||
|
.section-title { |
||||
|
font-size: 30rpx; |
||||
|
font-weight: bold; |
||||
|
color: #333; |
||||
|
margin-bottom: 30rpx; |
||||
|
} |
||||
|
|
||||
|
// 订单信息 |
||||
|
.order-info-section, |
||||
|
.package-section, |
||||
|
.goods-section, |
||||
|
.equity-section, |
||||
|
.cost-section, |
||||
|
.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; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.label { |
||||
|
font-size: 28rpx; |
||||
|
color: #666; |
||||
|
width: 160rpx; |
||||
|
} |
||||
|
|
||||
|
.value { |
||||
|
flex: 1; |
||||
|
font-size: 28rpx; |
||||
|
color: #333; |
||||
|
} |
||||
|
|
||||
|
.copy-btn { |
||||
|
font-size: 24rpx; |
||||
|
color: #007aff; |
||||
|
padding: 8rpx 16rpx; |
||||
|
border: 1px solid #007aff; |
||||
|
border-radius: 20rpx; |
||||
|
} |
||||
|
|
||||
|
// 权益商品包 |
||||
|
.package-name { |
||||
|
font-size: 28rpx; |
||||
|
color: #333; |
||||
|
background-color: #f8f9fa; |
||||
|
padding: 20rpx; |
||||
|
border-radius: 12rpx; |
||||
|
} |
||||
|
|
||||
|
// 商品列表 |
||||
|
.goods-item { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
padding: 20rpx 0; |
||||
|
border-bottom: 1px solid #f0f0f0; |
||||
|
|
||||
|
&:last-child { |
||||
|
border-bottom: none; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.goods-image { |
||||
|
width: 120rpx; |
||||
|
height: 120rpx; |
||||
|
border-radius: 12rpx; |
||||
|
margin-right: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.goods-info { |
||||
|
flex: 1; |
||||
|
margin-right: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.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; |
||||
|
margin-bottom: 8rpx; |
||||
|
} |
||||
|
|
||||
|
.goods-spec { |
||||
|
font-size: 24rpx; |
||||
|
color: #666; |
||||
|
} |
||||
|
|
||||
|
.goods-price { |
||||
|
text-align: right; |
||||
|
} |
||||
|
|
||||
|
.price { |
||||
|
display: block; |
||||
|
font-size: 28rpx; |
||||
|
color: #ff4757; |
||||
|
font-weight: bold; |
||||
|
margin-bottom: 5rpx; |
||||
|
} |
||||
|
|
||||
|
.quantity { |
||||
|
font-size: 24rpx; |
||||
|
color: #999; |
||||
|
} |
||||
|
|
||||
|
// 权益码 |
||||
|
.equity-card { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
padding: 30rpx; |
||||
|
background-color: #f8f9fa; |
||||
|
border-radius: 12rpx; |
||||
|
border: 2rpx dashed #007aff; |
||||
|
} |
||||
|
|
||||
|
.equity-info { |
||||
|
flex: 1; |
||||
|
} |
||||
|
|
||||
|
.equity-label { |
||||
|
display: block; |
||||
|
font-size: 26rpx; |
||||
|
color: #666; |
||||
|
margin-bottom: 10rpx; |
||||
|
} |
||||
|
|
||||
|
.equity-code { |
||||
|
font-size: 32rpx; |
||||
|
color: #333; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
.equity-action { |
||||
|
.view-qr { |
||||
|
font-size: 26rpx; |
||||
|
color: #007aff; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 费用明细 |
||||
|
.cost-item { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
margin-bottom: 20rpx; |
||||
|
|
||||
|
&:last-child { |
||||
|
margin-bottom: 0; |
||||
|
} |
||||
|
|
||||
|
&.total { |
||||
|
padding-top: 20rpx; |
||||
|
border-top: 1px solid #f0f0f0; |
||||
|
|
||||
|
.cost-label, |
||||
|
.cost-value { |
||||
|
font-size: 32rpx; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.cost-label { |
||||
|
font-size: 28rpx; |
||||
|
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; |
||||
|
color: #333; |
||||
|
font-weight: bold; |
||||
|
margin-right: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.receiver-phone { |
||||
|
font-size: 28rpx; |
||||
|
color: #666; |
||||
|
} |
||||
|
|
||||
|
.receiver-address { |
||||
|
font-size: 26rpx; |
||||
|
color: #666; |
||||
|
line-height: 1.5; |
||||
|
} |
||||
|
|
||||
|
.no-address { |
||||
|
text-align: center; |
||||
|
padding: 30rpx; |
||||
|
color: #999; |
||||
|
} |
||||
|
|
||||
|
// 底部操作 |
||||
|
.bottom-actions { |
||||
|
position: fixed; |
||||
|
bottom: 0; |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
background-color: #fff; |
||||
|
padding: 20rpx 30rpx; |
||||
|
border-top: 1px solid #eee; |
||||
|
display: flex; |
||||
|
gap: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.action-btn { |
||||
|
flex: 1; |
||||
|
height: 80rpx; |
||||
|
border-radius: 40rpx; |
||||
|
font-size: 28rpx; |
||||
|
border: none; |
||||
|
|
||||
|
&.secondary { |
||||
|
background-color: #f0f0f0; |
||||
|
color: #666; |
||||
|
} |
||||
|
|
||||
|
&.primary { |
||||
|
background-color: #007aff; |
||||
|
color: #fff; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 权益码弹窗 |
||||
|
.equity-popup-mask { |
||||
|
position: fixed; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
bottom: 0; |
||||
|
background-color: rgba(0, 0, 0, 0.5); |
||||
|
z-index: 9999; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.equity-popup { |
||||
|
width: 600rpx; |
||||
|
background-color: #fff; |
||||
|
border-radius: 20rpx; |
||||
|
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: bold; |
||||
|
color: #333; |
||||
|
} |
||||
|
|
||||
|
.popup-close { |
||||
|
font-size: 40rpx; |
||||
|
color: #999; |
||||
|
} |
||||
|
|
||||
|
.popup-content { |
||||
|
padding: 40rpx 30rpx; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.qrcode-container { |
||||
|
margin-bottom: 40rpx; |
||||
|
} |
||||
|
|
||||
|
.qrcode-image { |
||||
|
width: 300rpx; |
||||
|
height: 300rpx; |
||||
|
border: 1px solid #eee; |
||||
|
border-radius: 12rpx; |
||||
|
} |
||||
|
|
||||
|
.code-container { |
||||
|
margin-bottom: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.code-label { |
||||
|
font-size: 28rpx; |
||||
|
color: #666; |
||||
|
margin-right: 10rpx; |
||||
|
} |
||||
|
|
||||
|
.code-value { |
||||
|
font-size: 28rpx; |
||||
|
color: #333; |
||||
|
font-weight: bold; |
||||
|
background-color: #f8f9fa; |
||||
|
padding: 8rpx 16rpx; |
||||
|
border-radius: 8rpx; |
||||
|
} |
||||
|
|
||||
|
.code-tip { |
||||
|
font-size: 24rpx; |
||||
|
color: #999; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,739 @@ |
|||||
|
<template> |
||||
|
<view class="order-list-container"> |
||||
|
<!-- Tab切换 --> |
||||
|
<view class="tab-container"> |
||||
|
<view |
||||
|
class="tab-item" |
||||
|
:class="{ active: currentTab === index }" |
||||
|
v-for="(tab, index) in tabs" |
||||
|
:key="index" |
||||
|
@click="switchTab(index)" |
||||
|
> |
||||
|
<text class="tab-text">{{ tab.name }}</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 订单列表 --> |
||||
|
<scroll-view |
||||
|
class="order-scroll" |
||||
|
scroll-y |
||||
|
@scrolltolower="loadMore" |
||||
|
refresher-enabled |
||||
|
:refresher-triggered="refresherTriggered" |
||||
|
@refresherrefresh="onRefresh" |
||||
|
> |
||||
|
<!-- 订单项 --> |
||||
|
<view class="order-item" v-for="order in orderList" :key="order.id"> |
||||
|
<!-- 订单头部 --> |
||||
|
<view class="order-header"> |
||||
|
<text class="order-number">订单号:{{ order.orderNo }}</text> |
||||
|
<text class="order-status" :class="[getStatusClass(order.status)]">{{ |
||||
|
getStatusText(order.status) |
||||
|
}}</text> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 权益商品包名 --> |
||||
|
<view class="package-name"> |
||||
|
<text>{{ order.packageName }}</text> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 商品列表 --> |
||||
|
<view class="goods-list"> |
||||
|
<view |
||||
|
class="goods-item" |
||||
|
v-for="goods in order.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-price">¥{{ goods.price }}</text> |
||||
|
</view> |
||||
|
<view class="goods-action"> |
||||
|
<button |
||||
|
class="action-btn" |
||||
|
:class="[getActionBtnClass(goods.type)]" |
||||
|
@click="handleGoodsAction(goods)" |
||||
|
> |
||||
|
{{ getActionBtnText(goods.type) }} |
||||
|
</button> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 订单底部 --> |
||||
|
<view class="order-footer"> |
||||
|
<view class="order-info"> |
||||
|
<text class="order-time">{{ formatTime(order.createTime) }}</text> |
||||
|
<text class="order-total">总计:¥{{ order.totalAmount }}</text> |
||||
|
</view> |
||||
|
<view class="order-actions"> |
||||
|
<button |
||||
|
class="equity-code-btn" |
||||
|
@click="showEquityCode(order)" |
||||
|
v-if="order.status !== 0" |
||||
|
> |
||||
|
权益码 |
||||
|
</button> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 空状态 --> |
||||
|
<view class="empty-state" v-if="orderList.length === 0 && !loading"> |
||||
|
<image |
||||
|
class="empty-image" |
||||
|
src="/static/image/empty-order.png" |
||||
|
mode="aspectFit" |
||||
|
/> |
||||
|
<text class="empty-text">暂无订单</text> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 加载更多 --> |
||||
|
<view class="load-more" v-if="hasMore && orderList.length > 0"> |
||||
|
<text class="load-text">{{ |
||||
|
loading ? "加载中..." : "上拉加载更多" |
||||
|
}}</text> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 没有更多数据 --> |
||||
|
<view class="no-more" v-if="!hasMore && orderList.length > 0"> |
||||
|
<text class="no-more-text">没有更多数据了</text> |
||||
|
</view> |
||||
|
</scroll-view> |
||||
|
|
||||
|
<!-- 权益码弹窗 --> |
||||
|
<uni-popup ref="equityPopup" type="center"> |
||||
|
<view class="equity-popup"> |
||||
|
<view class="popup-header"> |
||||
|
<text class="popup-title">权益码</text> |
||||
|
<text class="popup-close" @click="closeEquityPopup">×</text> |
||||
|
</view> |
||||
|
<view class="popup-content"> |
||||
|
<!-- 二维码 --> |
||||
|
<view class="qrcode-container"> |
||||
|
<image |
||||
|
class="qrcode-image" |
||||
|
:src="currentEquity.qrcode" |
||||
|
mode="aspectFit" |
||||
|
/> |
||||
|
</view> |
||||
|
<!-- 编号串码 --> |
||||
|
<view class="code-container"> |
||||
|
<text class="code-label">权益码:</text> |
||||
|
<text class="code-value" @longpress="copyCode">{{ |
||||
|
currentEquity.code |
||||
|
}}</text> |
||||
|
</view> |
||||
|
<text class="code-tip">长按编号可复制</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</uni-popup> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
currentTab: 0, |
||||
|
tabs: [ |
||||
|
{ name: "全部", status: "" }, |
||||
|
{ name: "待使用", status: 1 }, |
||||
|
{ name: "待收货", status: 2 }, |
||||
|
{ name: "已完成", status: 3 }, |
||||
|
{ name: "售后/退款", status: 4 }, |
||||
|
], |
||||
|
orderList: [], |
||||
|
loading: false, |
||||
|
refresherTriggered: false, |
||||
|
hasMore: true, |
||||
|
currentPage: 1, |
||||
|
pageSize: 10, |
||||
|
currentEquity: { |
||||
|
qrcode: "", |
||||
|
code: "", |
||||
|
}, |
||||
|
}; |
||||
|
}, |
||||
|
onLoad() { |
||||
|
this.loadOrderList(); |
||||
|
}, |
||||
|
methods: { |
||||
|
// 切换Tab |
||||
|
switchTab(index) { |
||||
|
this.currentTab = index; |
||||
|
this.resetList(); |
||||
|
this.loadOrderList(); |
||||
|
}, |
||||
|
|
||||
|
// 重置列表 |
||||
|
resetList() { |
||||
|
this.orderList = []; |
||||
|
this.currentPage = 1; |
||||
|
this.hasMore = true; |
||||
|
}, |
||||
|
|
||||
|
// 加载订单列表 |
||||
|
async loadOrderList() { |
||||
|
if (this.loading || !this.hasMore) return; |
||||
|
|
||||
|
this.loading = true; |
||||
|
try { |
||||
|
const params = { |
||||
|
page: this.currentPage, |
||||
|
pageSize: this.pageSize, |
||||
|
status: this.tabs[this.currentTab].status, |
||||
|
}; |
||||
|
|
||||
|
// 这里调用实际的API接口 |
||||
|
const res = await this.getOrderList(params); |
||||
|
|
||||
|
if (this.currentPage === 1) { |
||||
|
this.orderList = res.data.list || []; |
||||
|
} else { |
||||
|
this.orderList = [...this.orderList, ...(res.data.list || [])]; |
||||
|
} |
||||
|
|
||||
|
this.hasMore = res.data.list.length === this.pageSize; |
||||
|
this.currentPage++; |
||||
|
} catch (error) { |
||||
|
console.error("加载订单列表失败:", error); |
||||
|
uni.showToast({ |
||||
|
title: "加载失败", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
} finally { |
||||
|
this.loading = false; |
||||
|
this.refresherTriggered = false; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 上拉加载更多 |
||||
|
loadMore() { |
||||
|
this.loadOrderList(); |
||||
|
}, |
||||
|
|
||||
|
// 下拉刷新 |
||||
|
onRefresh() { |
||||
|
this.refresherTriggered = true; |
||||
|
this.resetList(); |
||||
|
this.loadOrderList(); |
||||
|
}, |
||||
|
|
||||
|
// 获取订单状态文本 |
||||
|
getStatusText(status) { |
||||
|
const statusMap = { |
||||
|
0: "待付款", |
||||
|
1: "待使用", |
||||
|
2: "待收货", |
||||
|
3: "已完成", |
||||
|
4: "售后/退款", |
||||
|
}; |
||||
|
return statusMap[status] || "未知"; |
||||
|
}, |
||||
|
|
||||
|
// 获取订单状态样式类 |
||||
|
getStatusClass(status) { |
||||
|
const classMap = { |
||||
|
0: "status-pending", |
||||
|
1: "status-waiting", |
||||
|
2: "status-shipping", |
||||
|
3: "status-completed", |
||||
|
4: "status-refund", |
||||
|
}; |
||||
|
return classMap[status] || ""; |
||||
|
}, |
||||
|
|
||||
|
// 获取商品类型名称 |
||||
|
getGoodsTypeName(type) { |
||||
|
const typeMap = { |
||||
|
1: "IP数字资产", |
||||
|
2: "IP资源商品", |
||||
|
3: "君道苏州门票", |
||||
|
}; |
||||
|
return typeMap[type] || "未知类型"; |
||||
|
}, |
||||
|
|
||||
|
// 获取操作按钮文本 |
||||
|
getActionBtnText(type) { |
||||
|
const textMap = { |
||||
|
1: "查看", |
||||
|
2: "预约发货", |
||||
|
3: "去使用", |
||||
|
}; |
||||
|
return textMap[type] || "操作"; |
||||
|
}, |
||||
|
|
||||
|
// 获取操作按钮样式类 |
||||
|
getActionBtnClass(type) { |
||||
|
const classMap = { |
||||
|
1: "btn-view", |
||||
|
2: "btn-reserve", |
||||
|
3: "btn-use", |
||||
|
}; |
||||
|
return classMap[type] || ""; |
||||
|
}, |
||||
|
|
||||
|
// 处理商品操作 |
||||
|
handleGoodsAction(goods) { |
||||
|
switch (goods.type) { |
||||
|
case 1: // IP数字资产 - 查看 |
||||
|
this.viewDigitalAsset(goods); |
||||
|
break; |
||||
|
case 2: // IP资源商品 - 预约发货 |
||||
|
this.reserveDelivery(goods); |
||||
|
break; |
||||
|
case 3: // 君道苏州门票 - 去使用 |
||||
|
this.useTicket(goods); |
||||
|
break; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 查看数字资产 |
||||
|
viewDigitalAsset(goods) { |
||||
|
// 跳转到数字资产详情页面 |
||||
|
uni.showToast({ |
||||
|
title: "查看数字资产", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
// 预约发货 |
||||
|
reserveDelivery(goods) { |
||||
|
// 处理预约发货逻辑 |
||||
|
uni.showToast({ |
||||
|
title: "预约发货", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
// 使用门票 |
||||
|
useTicket(goods) { |
||||
|
// 处理使用门票逻辑 |
||||
|
uni.showToast({ |
||||
|
title: "使用门票", |
||||
|
icon: "none", |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
// 显示权益码 |
||||
|
showEquityCode(order) { |
||||
|
this.currentEquity = { |
||||
|
qrcode: order.qrcode || "/static/image/default-qrcode.png", |
||||
|
code: order.equityCode || "EQUITY123456789", |
||||
|
}; |
||||
|
this.$refs.equityPopup.open(); |
||||
|
}, |
||||
|
|
||||
|
// 关闭权益码弹窗 |
||||
|
closeEquityPopup() { |
||||
|
this.$refs.equityPopup.close(); |
||||
|
}, |
||||
|
|
||||
|
// 复制权益码 |
||||
|
copyCode() { |
||||
|
uni.setClipboardData({ |
||||
|
data: this.currentEquity.code, |
||||
|
success: () => { |
||||
|
uni.showToast({ |
||||
|
title: "已复制到剪贴板", |
||||
|
icon: "success", |
||||
|
}); |
||||
|
}, |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
// 格式化时间 |
||||
|
formatTime(time) { |
||||
|
if (!time) return ""; |
||||
|
const date = new Date(time); |
||||
|
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart( |
||||
|
2, |
||||
|
"0" |
||||
|
)}-${String(date.getDate()).padStart(2, "0")} ${String( |
||||
|
date.getHours() |
||||
|
).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}`; |
||||
|
}, |
||||
|
|
||||
|
// API接口 - 获取订单列表 |
||||
|
async getOrderList(params) { |
||||
|
// 模拟API数据 |
||||
|
return new Promise((resolve) => { |
||||
|
setTimeout(() => { |
||||
|
const mockData = { |
||||
|
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", |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
// 可以添加更多模拟数据 |
||||
|
], |
||||
|
}, |
||||
|
}; |
||||
|
resolve(mockData); |
||||
|
}, 1000); |
||||
|
}); |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.order-list-container { |
||||
|
min-height: 100vh; |
||||
|
background-color: #f5f5f5; |
||||
|
} |
||||
|
|
||||
|
// Tab样式 |
||||
|
.tab-container { |
||||
|
display: flex; |
||||
|
background-color: #fff; |
||||
|
border-bottom: 1px solid #eee; |
||||
|
position: sticky; |
||||
|
top: 0; |
||||
|
z-index: 10; |
||||
|
} |
||||
|
|
||||
|
.tab-item { |
||||
|
flex: 1; |
||||
|
padding: 30rpx 0; |
||||
|
text-align: center; |
||||
|
position: relative; |
||||
|
|
||||
|
&.active { |
||||
|
.tab-text { |
||||
|
color: #007aff; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
&::after { |
||||
|
content: ""; |
||||
|
position: absolute; |
||||
|
bottom: 0; |
||||
|
left: 50%; |
||||
|
transform: translateX(-50%); |
||||
|
width: 60rpx; |
||||
|
height: 4rpx; |
||||
|
background-color: #007aff; |
||||
|
border-radius: 2rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.tab-text { |
||||
|
font-size: 28rpx; |
||||
|
color: #333; |
||||
|
} |
||||
|
|
||||
|
// 订单列表样式 |
||||
|
.order-scroll { |
||||
|
height: calc(100vh - 120rpx); |
||||
|
padding: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.order-item { |
||||
|
background-color: #fff; |
||||
|
border-radius: 16rpx; |
||||
|
margin-bottom: 20rpx; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
// 订单头部 |
||||
|
.order-header { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
padding: 30rpx; |
||||
|
border-bottom: 1px solid #f0f0f0; |
||||
|
} |
||||
|
|
||||
|
.order-number { |
||||
|
font-size: 28rpx; |
||||
|
color: #333; |
||||
|
} |
||||
|
|
||||
|
.order-status { |
||||
|
font-size: 26rpx; |
||||
|
padding: 8rpx 16rpx; |
||||
|
border-radius: 20rpx; |
||||
|
|
||||
|
&.status-pending { |
||||
|
background-color: #fff3cd; |
||||
|
color: #856404; |
||||
|
} |
||||
|
|
||||
|
&.status-waiting { |
||||
|
background-color: #d4edda; |
||||
|
color: #155724; |
||||
|
} |
||||
|
|
||||
|
&.status-shipping { |
||||
|
background-color: #cce5ff; |
||||
|
color: #004085; |
||||
|
} |
||||
|
|
||||
|
&.status-completed { |
||||
|
background-color: #e2e3e5; |
||||
|
color: #383d41; |
||||
|
} |
||||
|
|
||||
|
&.status-refund { |
||||
|
background-color: #f8d7da; |
||||
|
color: #721c24; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 权益商品包名 |
||||
|
.package-name { |
||||
|
padding: 20rpx 30rpx; |
||||
|
background-color: #f8f9fa; |
||||
|
border-bottom: 1px solid #f0f0f0; |
||||
|
|
||||
|
text { |
||||
|
font-size: 26rpx; |
||||
|
color: #666; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 商品列表 |
||||
|
.goods-list { |
||||
|
padding: 0 30rpx; |
||||
|
} |
||||
|
|
||||
|
.goods-item { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
padding: 30rpx 0; |
||||
|
border-bottom: 1px solid #f0f0f0; |
||||
|
|
||||
|
&:last-child { |
||||
|
border-bottom: none; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.goods-image { |
||||
|
width: 120rpx; |
||||
|
height: 120rpx; |
||||
|
border-radius: 12rpx; |
||||
|
margin-right: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.goods-info { |
||||
|
flex: 1; |
||||
|
margin-right: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.goods-name { |
||||
|
display: block; |
||||
|
font-size: 28rpx; |
||||
|
color: #333; |
||||
|
margin-bottom: 10rpx; |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
white-space: nowrap; |
||||
|
} |
||||
|
|
||||
|
.goods-type { |
||||
|
display: block; |
||||
|
font-size: 24rpx; |
||||
|
color: #999; |
||||
|
margin-bottom: 10rpx; |
||||
|
} |
||||
|
|
||||
|
.goods-price { |
||||
|
font-size: 28rpx; |
||||
|
color: #ff4757; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
.goods-action { |
||||
|
.action-btn { |
||||
|
padding: 12rpx 24rpx; |
||||
|
border-radius: 20rpx; |
||||
|
font-size: 24rpx; |
||||
|
border: none; |
||||
|
|
||||
|
&.btn-view { |
||||
|
background-color: #007aff; |
||||
|
color: #fff; |
||||
|
} |
||||
|
|
||||
|
&.btn-reserve { |
||||
|
background-color: #ff9500; |
||||
|
color: #fff; |
||||
|
} |
||||
|
|
||||
|
&.btn-use { |
||||
|
background-color: #34c759; |
||||
|
color: #fff; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 订单底部 |
||||
|
.order-footer { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
padding: 30rpx; |
||||
|
background-color: #f8f9fa; |
||||
|
} |
||||
|
|
||||
|
.order-info { |
||||
|
flex: 1; |
||||
|
} |
||||
|
|
||||
|
.order-time { |
||||
|
display: block; |
||||
|
font-size: 24rpx; |
||||
|
color: #999; |
||||
|
margin-bottom: 10rpx; |
||||
|
} |
||||
|
|
||||
|
.order-total { |
||||
|
font-size: 28rpx; |
||||
|
color: #333; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
.order-actions { |
||||
|
.equity-code-btn { |
||||
|
padding: 16rpx 32rpx; |
||||
|
background-color: #007aff; |
||||
|
color: #fff; |
||||
|
border-radius: 24rpx; |
||||
|
font-size: 26rpx; |
||||
|
border: none; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 空状态 |
||||
|
.empty-state { |
||||
|
text-align: center; |
||||
|
padding: 200rpx 0; |
||||
|
} |
||||
|
|
||||
|
.empty-image { |
||||
|
width: 200rpx; |
||||
|
height: 200rpx; |
||||
|
margin-bottom: 30rpx; |
||||
|
} |
||||
|
|
||||
|
.empty-text { |
||||
|
font-size: 28rpx; |
||||
|
color: #999; |
||||
|
} |
||||
|
|
||||
|
// 加载更多 |
||||
|
.load-more, |
||||
|
.no-more { |
||||
|
text-align: center; |
||||
|
padding: 30rpx; |
||||
|
} |
||||
|
|
||||
|
.load-text, |
||||
|
.no-more-text { |
||||
|
font-size: 26rpx; |
||||
|
color: #999; |
||||
|
} |
||||
|
|
||||
|
// 权益码弹窗 |
||||
|
.equity-popup { |
||||
|
width: 600rpx; |
||||
|
background-color: #fff; |
||||
|
border-radius: 20rpx; |
||||
|
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: bold; |
||||
|
color: #333; |
||||
|
} |
||||
|
|
||||
|
.popup-close { |
||||
|
font-size: 40rpx; |
||||
|
color: #999; |
||||
|
} |
||||
|
|
||||
|
.popup-content { |
||||
|
padding: 40rpx 30rpx; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.qrcode-container { |
||||
|
margin-bottom: 40rpx; |
||||
|
} |
||||
|
|
||||
|
.qrcode-image { |
||||
|
width: 300rpx; |
||||
|
height: 300rpx; |
||||
|
border: 1px solid #eee; |
||||
|
border-radius: 12rpx; |
||||
|
} |
||||
|
|
||||
|
.code-container { |
||||
|
margin-bottom: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.code-label { |
||||
|
font-size: 28rpx; |
||||
|
color: #666; |
||||
|
margin-right: 10rpx; |
||||
|
} |
||||
|
|
||||
|
.code-value { |
||||
|
font-size: 28rpx; |
||||
|
color: #333; |
||||
|
font-weight: bold; |
||||
|
background-color: #f8f9fa; |
||||
|
padding: 8rpx 16rpx; |
||||
|
border-radius: 8rpx; |
||||
|
} |
||||
|
|
||||
|
.code-tip { |
||||
|
font-size: 24rpx; |
||||
|
color: #999; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,91 @@ |
|||||
|
<template> |
||||
|
<text class="uni-icons" :style="styleObj"> |
||||
|
<slot>{{unicode}}</slot> |
||||
|
</text> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { fontData, IconsDataItem } from './uniicons_file' |
||||
|
|
||||
|
/** |
||||
|
* Icons 图标 |
||||
|
* @description 用于展示 icon 图标 |
||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=28 |
||||
|
* @property {Number,String} size 图标大小 |
||||
|
* @property {String} type 图标图案,参考示例 |
||||
|
* @property {String} color 图标颜色 |
||||
|
* @property {String} customPrefix 自定义图标 |
||||
|
* @event {Function} click 点击 Icon 触发事件 |
||||
|
*/ |
||||
|
export default { |
||||
|
name: "uni-icons", |
||||
|
props: { |
||||
|
type: { |
||||
|
type: String, |
||||
|
default: '' |
||||
|
}, |
||||
|
color: { |
||||
|
type: String, |
||||
|
default: '#333333' |
||||
|
}, |
||||
|
size: { |
||||
|
type: [Number, String], |
||||
|
default: 16 |
||||
|
}, |
||||
|
fontFamily: { |
||||
|
type: String, |
||||
|
default: '' |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return {}; |
||||
|
}, |
||||
|
computed: { |
||||
|
unicode() : string { |
||||
|
let codes = fontData.find((item : IconsDataItem) : boolean => { return item.font_class == this.type }) |
||||
|
if (codes !== null) { |
||||
|
return codes.unicode |
||||
|
} |
||||
|
return '' |
||||
|
}, |
||||
|
iconSize() : string { |
||||
|
const size = this.size |
||||
|
if (typeof size == 'string') { |
||||
|
const reg = /^[0-9]*$/g |
||||
|
return reg.test(size as string) ? '' + size + 'px' : '' + size; |
||||
|
// return '' + this.size |
||||
|
} |
||||
|
return this.getFontSize(size as number) |
||||
|
}, |
||||
|
styleObj() : UTSJSONObject { |
||||
|
if (this.fontFamily !== '') { |
||||
|
return { color: this.color, fontSize: this.iconSize, fontFamily: this.fontFamily } |
||||
|
} |
||||
|
return { color: this.color, fontSize: this.iconSize } |
||||
|
} |
||||
|
}, |
||||
|
created() { }, |
||||
|
methods: { |
||||
|
/** |
||||
|
* 字体大小 |
||||
|
*/ |
||||
|
getFontSize(size : number) : string { |
||||
|
return size + 'px'; |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
@font-face { |
||||
|
font-family: UniIconsFontFamily; |
||||
|
src: url('./uniicons.ttf'); |
||||
|
} |
||||
|
|
||||
|
.uni-icons { |
||||
|
font-family: UniIconsFontFamily; |
||||
|
font-size: 18px; |
||||
|
font-style: normal; |
||||
|
color: #333; |
||||
|
} |
||||
|
</style> |
Binary file not shown.
@ -0,0 +1,664 @@ |
|||||
|
|
||||
|
export type IconsData = { |
||||
|
id : string |
||||
|
name : string |
||||
|
font_family : string |
||||
|
css_prefix_text : string |
||||
|
description : string |
||||
|
glyphs : Array<IconsDataItem> |
||||
|
} |
||||
|
|
||||
|
export type IconsDataItem = { |
||||
|
font_class : string |
||||
|
unicode : string |
||||
|
} |
||||
|
|
||||
|
|
||||
|
export const fontData = [ |
||||
|
{ |
||||
|
"font_class": "arrow-down", |
||||
|
"unicode": "\ue6be" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "arrow-left", |
||||
|
"unicode": "\ue6bc" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "arrow-right", |
||||
|
"unicode": "\ue6bb" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "arrow-up", |
||||
|
"unicode": "\ue6bd" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "auth", |
||||
|
"unicode": "\ue6ab" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "auth-filled", |
||||
|
"unicode": "\ue6cc" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "back", |
||||
|
"unicode": "\ue6b9" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "bars", |
||||
|
"unicode": "\ue627" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "calendar", |
||||
|
"unicode": "\ue6a0" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "calendar-filled", |
||||
|
"unicode": "\ue6c0" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "camera", |
||||
|
"unicode": "\ue65a" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "camera-filled", |
||||
|
"unicode": "\ue658" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "cart", |
||||
|
"unicode": "\ue631" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "cart-filled", |
||||
|
"unicode": "\ue6d0" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "chat", |
||||
|
"unicode": "\ue65d" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "chat-filled", |
||||
|
"unicode": "\ue659" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "chatboxes", |
||||
|
"unicode": "\ue696" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "chatboxes-filled", |
||||
|
"unicode": "\ue692" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "chatbubble", |
||||
|
"unicode": "\ue697" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "chatbubble-filled", |
||||
|
"unicode": "\ue694" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "checkbox", |
||||
|
"unicode": "\ue62b" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "checkbox-filled", |
||||
|
"unicode": "\ue62c" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "checkmarkempty", |
||||
|
"unicode": "\ue65c" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "circle", |
||||
|
"unicode": "\ue65b" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "circle-filled", |
||||
|
"unicode": "\ue65e" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "clear", |
||||
|
"unicode": "\ue66d" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "close", |
||||
|
"unicode": "\ue673" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "closeempty", |
||||
|
"unicode": "\ue66c" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "cloud-download", |
||||
|
"unicode": "\ue647" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "cloud-download-filled", |
||||
|
"unicode": "\ue646" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "cloud-upload", |
||||
|
"unicode": "\ue645" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "cloud-upload-filled", |
||||
|
"unicode": "\ue648" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "color", |
||||
|
"unicode": "\ue6cf" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "color-filled", |
||||
|
"unicode": "\ue6c9" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "compose", |
||||
|
"unicode": "\ue67f" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "contact", |
||||
|
"unicode": "\ue693" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "contact-filled", |
||||
|
"unicode": "\ue695" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "down", |
||||
|
"unicode": "\ue6b8" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "bottom", |
||||
|
"unicode": "\ue6b8" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "download", |
||||
|
"unicode": "\ue68d" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "download-filled", |
||||
|
"unicode": "\ue681" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "email", |
||||
|
"unicode": "\ue69e" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "email-filled", |
||||
|
"unicode": "\ue69a" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "eye", |
||||
|
"unicode": "\ue651" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "eye-filled", |
||||
|
"unicode": "\ue66a" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "eye-slash", |
||||
|
"unicode": "\ue6b3" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "eye-slash-filled", |
||||
|
"unicode": "\ue6b4" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "fire", |
||||
|
"unicode": "\ue6a1" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "fire-filled", |
||||
|
"unicode": "\ue6c5" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "flag", |
||||
|
"unicode": "\ue65f" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "flag-filled", |
||||
|
"unicode": "\ue660" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "folder-add", |
||||
|
"unicode": "\ue6a9" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "folder-add-filled", |
||||
|
"unicode": "\ue6c8" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "font", |
||||
|
"unicode": "\ue6a3" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "forward", |
||||
|
"unicode": "\ue6ba" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "gear", |
||||
|
"unicode": "\ue664" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "gear-filled", |
||||
|
"unicode": "\ue661" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "gift", |
||||
|
"unicode": "\ue6a4" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "gift-filled", |
||||
|
"unicode": "\ue6c4" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "hand-down", |
||||
|
"unicode": "\ue63d" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "hand-down-filled", |
||||
|
"unicode": "\ue63c" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "hand-up", |
||||
|
"unicode": "\ue63f" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "hand-up-filled", |
||||
|
"unicode": "\ue63e" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "headphones", |
||||
|
"unicode": "\ue630" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "heart", |
||||
|
"unicode": "\ue639" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "heart-filled", |
||||
|
"unicode": "\ue641" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "help", |
||||
|
"unicode": "\ue679" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "help-filled", |
||||
|
"unicode": "\ue674" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "home", |
||||
|
"unicode": "\ue662" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "home-filled", |
||||
|
"unicode": "\ue663" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "image", |
||||
|
"unicode": "\ue670" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "image-filled", |
||||
|
"unicode": "\ue678" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "images", |
||||
|
"unicode": "\ue650" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "images-filled", |
||||
|
"unicode": "\ue64b" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "info", |
||||
|
"unicode": "\ue669" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "info-filled", |
||||
|
"unicode": "\ue649" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "left", |
||||
|
"unicode": "\ue6b7" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "link", |
||||
|
"unicode": "\ue6a5" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "list", |
||||
|
"unicode": "\ue644" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "location", |
||||
|
"unicode": "\ue6ae" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "location-filled", |
||||
|
"unicode": "\ue6af" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "locked", |
||||
|
"unicode": "\ue66b" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "locked-filled", |
||||
|
"unicode": "\ue668" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "loop", |
||||
|
"unicode": "\ue633" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "mail-open", |
||||
|
"unicode": "\ue643" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "mail-open-filled", |
||||
|
"unicode": "\ue63a" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "map", |
||||
|
"unicode": "\ue667" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "map-filled", |
||||
|
"unicode": "\ue666" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "map-pin", |
||||
|
"unicode": "\ue6ad" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "map-pin-ellipse", |
||||
|
"unicode": "\ue6ac" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "medal", |
||||
|
"unicode": "\ue6a2" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "medal-filled", |
||||
|
"unicode": "\ue6c3" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "mic", |
||||
|
"unicode": "\ue671" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "mic-filled", |
||||
|
"unicode": "\ue677" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "micoff", |
||||
|
"unicode": "\ue67e" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "micoff-filled", |
||||
|
"unicode": "\ue6b0" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "minus", |
||||
|
"unicode": "\ue66f" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "minus-filled", |
||||
|
"unicode": "\ue67d" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "more", |
||||
|
"unicode": "\ue64d" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "more-filled", |
||||
|
"unicode": "\ue64e" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "navigate", |
||||
|
"unicode": "\ue66e" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "navigate-filled", |
||||
|
"unicode": "\ue67a" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "notification", |
||||
|
"unicode": "\ue6a6" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "notification-filled", |
||||
|
"unicode": "\ue6c1" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "paperclip", |
||||
|
"unicode": "\ue652" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "paperplane", |
||||
|
"unicode": "\ue672" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "paperplane-filled", |
||||
|
"unicode": "\ue675" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "person", |
||||
|
"unicode": "\ue699" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "person-filled", |
||||
|
"unicode": "\ue69d" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "personadd", |
||||
|
"unicode": "\ue69f" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "personadd-filled", |
||||
|
"unicode": "\ue698" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "personadd-filled-copy", |
||||
|
"unicode": "\ue6d1" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "phone", |
||||
|
"unicode": "\ue69c" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "phone-filled", |
||||
|
"unicode": "\ue69b" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "plus", |
||||
|
"unicode": "\ue676" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "plus-filled", |
||||
|
"unicode": "\ue6c7" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "plusempty", |
||||
|
"unicode": "\ue67b" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "pulldown", |
||||
|
"unicode": "\ue632" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "pyq", |
||||
|
"unicode": "\ue682" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "qq", |
||||
|
"unicode": "\ue680" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "redo", |
||||
|
"unicode": "\ue64a" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "redo-filled", |
||||
|
"unicode": "\ue655" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "refresh", |
||||
|
"unicode": "\ue657" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "refresh-filled", |
||||
|
"unicode": "\ue656" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "refreshempty", |
||||
|
"unicode": "\ue6bf" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "reload", |
||||
|
"unicode": "\ue6b2" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "right", |
||||
|
"unicode": "\ue6b5" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "scan", |
||||
|
"unicode": "\ue62a" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "search", |
||||
|
"unicode": "\ue654" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "settings", |
||||
|
"unicode": "\ue653" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "settings-filled", |
||||
|
"unicode": "\ue6ce" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "shop", |
||||
|
"unicode": "\ue62f" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "shop-filled", |
||||
|
"unicode": "\ue6cd" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "smallcircle", |
||||
|
"unicode": "\ue67c" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "smallcircle-filled", |
||||
|
"unicode": "\ue665" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "sound", |
||||
|
"unicode": "\ue684" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "sound-filled", |
||||
|
"unicode": "\ue686" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "spinner-cycle", |
||||
|
"unicode": "\ue68a" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "staff", |
||||
|
"unicode": "\ue6a7" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "staff-filled", |
||||
|
"unicode": "\ue6cb" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "star", |
||||
|
"unicode": "\ue688" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "star-filled", |
||||
|
"unicode": "\ue68f" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "starhalf", |
||||
|
"unicode": "\ue683" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "trash", |
||||
|
"unicode": "\ue687" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "trash-filled", |
||||
|
"unicode": "\ue685" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "tune", |
||||
|
"unicode": "\ue6aa" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "tune-filled", |
||||
|
"unicode": "\ue6ca" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "undo", |
||||
|
"unicode": "\ue64f" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "undo-filled", |
||||
|
"unicode": "\ue64c" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "up", |
||||
|
"unicode": "\ue6b6" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "top", |
||||
|
"unicode": "\ue6b6" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "upload", |
||||
|
"unicode": "\ue690" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "upload-filled", |
||||
|
"unicode": "\ue68e" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "videocam", |
||||
|
"unicode": "\ue68c" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "videocam-filled", |
||||
|
"unicode": "\ue689" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "vip", |
||||
|
"unicode": "\ue6a8" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "vip-filled", |
||||
|
"unicode": "\ue6c6" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "wallet", |
||||
|
"unicode": "\ue6b1" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "wallet-filled", |
||||
|
"unicode": "\ue6c2" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "weibo", |
||||
|
"unicode": "\ue68b" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "weixin", |
||||
|
"unicode": "\ue691" |
||||
|
} |
||||
|
] as IconsDataItem[] |
||||
|
|
||||
|
// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)
|
@ -0,0 +1,649 @@ |
|||||
|
|
||||
|
export const fontData = [ |
||||
|
{ |
||||
|
"font_class": "arrow-down", |
||||
|
"unicode": "\ue6be" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "arrow-left", |
||||
|
"unicode": "\ue6bc" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "arrow-right", |
||||
|
"unicode": "\ue6bb" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "arrow-up", |
||||
|
"unicode": "\ue6bd" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "auth", |
||||
|
"unicode": "\ue6ab" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "auth-filled", |
||||
|
"unicode": "\ue6cc" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "back", |
||||
|
"unicode": "\ue6b9" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "bars", |
||||
|
"unicode": "\ue627" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "calendar", |
||||
|
"unicode": "\ue6a0" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "calendar-filled", |
||||
|
"unicode": "\ue6c0" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "camera", |
||||
|
"unicode": "\ue65a" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "camera-filled", |
||||
|
"unicode": "\ue658" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "cart", |
||||
|
"unicode": "\ue631" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "cart-filled", |
||||
|
"unicode": "\ue6d0" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "chat", |
||||
|
"unicode": "\ue65d" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "chat-filled", |
||||
|
"unicode": "\ue659" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "chatboxes", |
||||
|
"unicode": "\ue696" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "chatboxes-filled", |
||||
|
"unicode": "\ue692" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "chatbubble", |
||||
|
"unicode": "\ue697" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "chatbubble-filled", |
||||
|
"unicode": "\ue694" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "checkbox", |
||||
|
"unicode": "\ue62b" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "checkbox-filled", |
||||
|
"unicode": "\ue62c" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "checkmarkempty", |
||||
|
"unicode": "\ue65c" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "circle", |
||||
|
"unicode": "\ue65b" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "circle-filled", |
||||
|
"unicode": "\ue65e" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "clear", |
||||
|
"unicode": "\ue66d" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "close", |
||||
|
"unicode": "\ue673" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "closeempty", |
||||
|
"unicode": "\ue66c" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "cloud-download", |
||||
|
"unicode": "\ue647" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "cloud-download-filled", |
||||
|
"unicode": "\ue646" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "cloud-upload", |
||||
|
"unicode": "\ue645" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "cloud-upload-filled", |
||||
|
"unicode": "\ue648" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "color", |
||||
|
"unicode": "\ue6cf" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "color-filled", |
||||
|
"unicode": "\ue6c9" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "compose", |
||||
|
"unicode": "\ue67f" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "contact", |
||||
|
"unicode": "\ue693" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "contact-filled", |
||||
|
"unicode": "\ue695" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "down", |
||||
|
"unicode": "\ue6b8" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "bottom", |
||||
|
"unicode": "\ue6b8" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "download", |
||||
|
"unicode": "\ue68d" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "download-filled", |
||||
|
"unicode": "\ue681" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "email", |
||||
|
"unicode": "\ue69e" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "email-filled", |
||||
|
"unicode": "\ue69a" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "eye", |
||||
|
"unicode": "\ue651" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "eye-filled", |
||||
|
"unicode": "\ue66a" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "eye-slash", |
||||
|
"unicode": "\ue6b3" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "eye-slash-filled", |
||||
|
"unicode": "\ue6b4" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "fire", |
||||
|
"unicode": "\ue6a1" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "fire-filled", |
||||
|
"unicode": "\ue6c5" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "flag", |
||||
|
"unicode": "\ue65f" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "flag-filled", |
||||
|
"unicode": "\ue660" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "folder-add", |
||||
|
"unicode": "\ue6a9" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "folder-add-filled", |
||||
|
"unicode": "\ue6c8" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "font", |
||||
|
"unicode": "\ue6a3" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "forward", |
||||
|
"unicode": "\ue6ba" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "gear", |
||||
|
"unicode": "\ue664" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "gear-filled", |
||||
|
"unicode": "\ue661" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "gift", |
||||
|
"unicode": "\ue6a4" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "gift-filled", |
||||
|
"unicode": "\ue6c4" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "hand-down", |
||||
|
"unicode": "\ue63d" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "hand-down-filled", |
||||
|
"unicode": "\ue63c" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "hand-up", |
||||
|
"unicode": "\ue63f" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "hand-up-filled", |
||||
|
"unicode": "\ue63e" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "headphones", |
||||
|
"unicode": "\ue630" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "heart", |
||||
|
"unicode": "\ue639" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "heart-filled", |
||||
|
"unicode": "\ue641" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "help", |
||||
|
"unicode": "\ue679" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "help-filled", |
||||
|
"unicode": "\ue674" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "home", |
||||
|
"unicode": "\ue662" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "home-filled", |
||||
|
"unicode": "\ue663" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "image", |
||||
|
"unicode": "\ue670" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "image-filled", |
||||
|
"unicode": "\ue678" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "images", |
||||
|
"unicode": "\ue650" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "images-filled", |
||||
|
"unicode": "\ue64b" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "info", |
||||
|
"unicode": "\ue669" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "info-filled", |
||||
|
"unicode": "\ue649" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "left", |
||||
|
"unicode": "\ue6b7" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "link", |
||||
|
"unicode": "\ue6a5" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "list", |
||||
|
"unicode": "\ue644" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "location", |
||||
|
"unicode": "\ue6ae" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "location-filled", |
||||
|
"unicode": "\ue6af" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "locked", |
||||
|
"unicode": "\ue66b" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "locked-filled", |
||||
|
"unicode": "\ue668" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "loop", |
||||
|
"unicode": "\ue633" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "mail-open", |
||||
|
"unicode": "\ue643" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "mail-open-filled", |
||||
|
"unicode": "\ue63a" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "map", |
||||
|
"unicode": "\ue667" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "map-filled", |
||||
|
"unicode": "\ue666" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "map-pin", |
||||
|
"unicode": "\ue6ad" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "map-pin-ellipse", |
||||
|
"unicode": "\ue6ac" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "medal", |
||||
|
"unicode": "\ue6a2" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "medal-filled", |
||||
|
"unicode": "\ue6c3" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "mic", |
||||
|
"unicode": "\ue671" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "mic-filled", |
||||
|
"unicode": "\ue677" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "micoff", |
||||
|
"unicode": "\ue67e" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "micoff-filled", |
||||
|
"unicode": "\ue6b0" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "minus", |
||||
|
"unicode": "\ue66f" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "minus-filled", |
||||
|
"unicode": "\ue67d" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "more", |
||||
|
"unicode": "\ue64d" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "more-filled", |
||||
|
"unicode": "\ue64e" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "navigate", |
||||
|
"unicode": "\ue66e" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "navigate-filled", |
||||
|
"unicode": "\ue67a" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "notification", |
||||
|
"unicode": "\ue6a6" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "notification-filled", |
||||
|
"unicode": "\ue6c1" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "paperclip", |
||||
|
"unicode": "\ue652" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "paperplane", |
||||
|
"unicode": "\ue672" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "paperplane-filled", |
||||
|
"unicode": "\ue675" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "person", |
||||
|
"unicode": "\ue699" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "person-filled", |
||||
|
"unicode": "\ue69d" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "personadd", |
||||
|
"unicode": "\ue69f" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "personadd-filled", |
||||
|
"unicode": "\ue698" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "personadd-filled-copy", |
||||
|
"unicode": "\ue6d1" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "phone", |
||||
|
"unicode": "\ue69c" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "phone-filled", |
||||
|
"unicode": "\ue69b" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "plus", |
||||
|
"unicode": "\ue676" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "plus-filled", |
||||
|
"unicode": "\ue6c7" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "plusempty", |
||||
|
"unicode": "\ue67b" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "pulldown", |
||||
|
"unicode": "\ue632" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "pyq", |
||||
|
"unicode": "\ue682" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "qq", |
||||
|
"unicode": "\ue680" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "redo", |
||||
|
"unicode": "\ue64a" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "redo-filled", |
||||
|
"unicode": "\ue655" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "refresh", |
||||
|
"unicode": "\ue657" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "refresh-filled", |
||||
|
"unicode": "\ue656" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "refreshempty", |
||||
|
"unicode": "\ue6bf" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "reload", |
||||
|
"unicode": "\ue6b2" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "right", |
||||
|
"unicode": "\ue6b5" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "scan", |
||||
|
"unicode": "\ue62a" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "search", |
||||
|
"unicode": "\ue654" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "settings", |
||||
|
"unicode": "\ue653" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "settings-filled", |
||||
|
"unicode": "\ue6ce" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "shop", |
||||
|
"unicode": "\ue62f" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "shop-filled", |
||||
|
"unicode": "\ue6cd" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "smallcircle", |
||||
|
"unicode": "\ue67c" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "smallcircle-filled", |
||||
|
"unicode": "\ue665" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "sound", |
||||
|
"unicode": "\ue684" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "sound-filled", |
||||
|
"unicode": "\ue686" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "spinner-cycle", |
||||
|
"unicode": "\ue68a" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "staff", |
||||
|
"unicode": "\ue6a7" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "staff-filled", |
||||
|
"unicode": "\ue6cb" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "star", |
||||
|
"unicode": "\ue688" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "star-filled", |
||||
|
"unicode": "\ue68f" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "starhalf", |
||||
|
"unicode": "\ue683" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "trash", |
||||
|
"unicode": "\ue687" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "trash-filled", |
||||
|
"unicode": "\ue685" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "tune", |
||||
|
"unicode": "\ue6aa" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "tune-filled", |
||||
|
"unicode": "\ue6ca" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "undo", |
||||
|
"unicode": "\ue64f" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "undo-filled", |
||||
|
"unicode": "\ue64c" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "up", |
||||
|
"unicode": "\ue6b6" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "top", |
||||
|
"unicode": "\ue6b6" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "upload", |
||||
|
"unicode": "\ue690" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "upload-filled", |
||||
|
"unicode": "\ue68e" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "videocam", |
||||
|
"unicode": "\ue68c" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "videocam-filled", |
||||
|
"unicode": "\ue689" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "vip", |
||||
|
"unicode": "\ue6a8" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "vip-filled", |
||||
|
"unicode": "\ue6c6" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "wallet", |
||||
|
"unicode": "\ue6b1" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "wallet-filled", |
||||
|
"unicode": "\ue6c2" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "weibo", |
||||
|
"unicode": "\ue68b" |
||||
|
}, |
||||
|
{ |
||||
|
"font_class": "weixin", |
||||
|
"unicode": "\ue691" |
||||
|
} |
||||
|
] |
||||
|
|
||||
|
// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)
|
@ -1,369 +1,292 @@ |
|||||
<template> |
<template> |
||||
<view |
<!-- #ifndef APP-NVUE --> |
||||
v-if="isShow" |
<view v-show="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick"> |
||||
ref="ani" |
<slot></slot> |
||||
:animation="animationData" |
</view> |
||||
:class="customClass" |
<!-- #endif --> |
||||
:style="transformStyles" |
<!-- #ifdef APP-NVUE --> |
||||
@click="onClick" |
<view v-if="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick"> |
||||
><slot></slot |
<slot></slot> |
||||
></view> |
</view> |
||||
|
<!-- #endif --> |
||||
</template> |
</template> |
||||
|
|
||||
<script> |
<script> |
||||
// #ifndef MP-WEIXIN |
import { createAnimation } from './createAnimation' |
||||
import { createAnimation } from "./createAnimation"; |
|
||||
// #endif |
|
||||
// #ifdef MP-WEIXIN |
|
||||
const createAnimation = require("./createAnimation.js").createAnimation; |
|
||||
// #endif |
|
||||
|
|
||||
/** |
/** |
||||
* Transition 过渡动画 |
* Transition 过渡动画 |
||||
* @description 简单过渡动画组件 |
* @description 简单过渡动画组件 |
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=985 |
* @tutorial https://ext.dcloud.net.cn/plugin?id=985 |
||||
* @property {Boolean} show = [false|true] 控制组件显示或隐藏 |
* @property {Boolean} show = [false|true] 控制组件显示或隐藏 |
||||
* @property {Array|String} modeClass = [fade|slide-top|slide-right|slide-bottom|slide-left|zoom-in|zoom-out] 过渡动画类型 |
* @property {Array|String} modeClass = [fade|slide-top|slide-right|slide-bottom|slide-left|zoom-in|zoom-out] 过渡动画类型 |
||||
* @value fade 渐隐渐出过渡 |
* @value fade 渐隐渐出过渡 |
||||
* @value slide-top 由上至下过渡 |
* @value slide-top 由上至下过渡 |
||||
* @value slide-right 由右至左过渡 |
* @value slide-right 由右至左过渡 |
||||
* @value slide-bottom 由下至上过渡 |
* @value slide-bottom 由下至上过渡 |
||||
* @value slide-left 由左至右过渡 |
* @value slide-left 由左至右过渡 |
||||
* @value zoom-in 由小到大过渡 |
* @value zoom-in 由小到大过渡 |
||||
* @value zoom-out 由大到小过渡 |
* @value zoom-out 由大到小过渡 |
||||
* @property {Number} duration 过渡动画持续时间 |
* @property {Number} duration 过渡动画持续时间 |
||||
* @property {Object} styles 组件样式,同 css 样式,注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red` |
* @property {Object} styles 组件样式,同 css 样式,注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red` |
||||
*/ |
*/ |
||||
export default { |
export default { |
||||
name: "uniTransition", |
name: 'uniTransition', |
||||
emits: ["click", "change"], |
emits: ['click', 'change'], |
||||
props: { |
props: { |
||||
show: { |
show: { |
||||
type: Boolean, |
type: Boolean, |
||||
default: false, |
default: false |
||||
}, |
}, |
||||
modeClass: { |
modeClass: { |
||||
type: [Array, String], |
type: [Array, String], |
||||
default() { |
default () { |
||||
return "fade"; |
return 'fade' |
||||
}, |
} |
||||
}, |
}, |
||||
duration: { |
duration: { |
||||
type: Number, |
type: Number, |
||||
default: 300, |
default: 300 |
||||
}, |
}, |
||||
styles: { |
styles: { |
||||
type: Object, |
type: Object, |
||||
default() { |
default () { |
||||
return {}; |
return {} |
||||
}, |
} |
||||
}, |
}, |
||||
customClass: { |
customClass: { |
||||
type: String, |
type: String, |
||||
default: "", |
default: '' |
||||
}, |
}, |
||||
}, |
onceRender: { |
||||
data() { |
type: Boolean, |
||||
return { |
default: false |
||||
isShow: false, |
}, |
||||
transform: "", |
}, |
||||
opacity: 1, |
data() { |
||||
animationData: {}, |
return { |
||||
durationTime: 300, |
isShow: false, |
||||
config: {}, |
transform: '', |
||||
}; |
opacity: 0, |
||||
}, |
animationData: {}, |
||||
watch: { |
durationTime: 300, |
||||
show: { |
config: {} |
||||
handler(newVal) { |
} |
||||
if (newVal) { |
}, |
||||
this.open(); |
watch: { |
||||
} else { |
show: { |
||||
// 避免上来就执行 close,导致动画错乱 |
handler(newVal) { |
||||
if (this.isShow) { |
if (newVal) { |
||||
this.close(); |
this.open() |
||||
} |
} else { |
||||
} |
// 避免上来就执行 close,导致动画错乱 |
||||
}, |
if (this.isShow) { |
||||
immediate: true, |
this.close() |
||||
}, |
} |
||||
}, |
} |
||||
computed: { |
}, |
||||
// 生成样式数据 |
immediate: true |
||||
stylesObject() { |
} |
||||
let styles = { |
}, |
||||
...this.styles, |
computed: { |
||||
"transition-duration": this.duration / 1000 + "s", |
// 生成样式数据 |
||||
}; |
stylesObject() { |
||||
let transform = ""; |
let styles = { |
||||
for (let i in styles) { |
...this.styles, |
||||
let line = this.toLine(i); |
'transition-duration': this.duration / 1000 + 's' |
||||
transform += line + ":" + styles[i] + ";"; |
} |
||||
} |
let transform = '' |
||||
return transform; |
for (let i in styles) { |
||||
}, |
let line = this.toLine(i) |
||||
// 初始化动画条件 |
transform += line + ':' + styles[i] + ';' |
||||
transformStyles() { |
} |
||||
return ( |
return transform |
||||
"transform:" + |
}, |
||||
this.transform + |
// 初始化动画条件 |
||||
";" + |
transformStyles() { |
||||
"opacity:" + |
return 'transform:' + this.transform + ';' + 'opacity:' + this.opacity + ';' + this.stylesObject |
||||
this.opacity + |
} |
||||
";" + |
}, |
||||
this.stylesObject |
created() { |
||||
); |
// 动画默认配置 |
||||
}, |
this.config = { |
||||
}, |
duration: this.duration, |
||||
created() { |
timingFunction: 'ease', |
||||
// 动画默认配置 |
transformOrigin: '50% 50%', |
||||
this.config = { |
delay: 0 |
||||
duration: this.duration, |
} |
||||
timingFunction: "ease", |
this.durationTime = this.duration |
||||
transformOrigin: "50% 50%", |
}, |
||||
delay: 0, |
methods: { |
||||
}; |
/** |
||||
this.durationTime = this.duration; |
* ref 触发 初始化动画 |
||||
}, |
*/ |
||||
beforeUnmount() { |
init(obj = {}) { |
||||
// 组件销毁前清理定时器和动画对象 |
if (obj.duration) { |
||||
if (this.timer) { |
this.durationTime = obj.duration |
||||
clearTimeout(this.timer); |
} |
||||
this.timer = null; |
this.animation = createAnimation(Object.assign(this.config, obj), this) |
||||
} |
}, |
||||
if (this.animation) { |
/** |
||||
this.animation = null; |
* 点击组件触发回调 |
||||
} |
*/ |
||||
}, |
onClick() { |
||||
beforeDestroy() { |
this.$emit('click', { |
||||
// Vue2 兼容 |
detail: this.isShow |
||||
if (this.timer) { |
}) |
||||
clearTimeout(this.timer); |
}, |
||||
this.timer = null; |
/** |
||||
} |
* ref 触发 动画分组 |
||||
if (this.animation) { |
* @param {Object} obj |
||||
this.animation = null; |
*/ |
||||
} |
step(obj, config = {}) { |
||||
}, |
if (!this.animation) return this |
||||
methods: { |
Object.keys(obj).forEach(key => { |
||||
/** |
const value = obj[key] |
||||
* ref 触发 初始化动画 |
if (typeof this.animation[key] === 'function') { |
||||
*/ |
Array.isArray(value) ? |
||||
init(obj = {}) { |
this.animation[key](...value) : |
||||
if (obj.duration) { |
this.animation[key](value) |
||||
this.durationTime = obj.duration; |
} |
||||
} |
}) |
||||
this.animation = createAnimation(Object.assign(this.config, obj), this); |
this.animation.step(config) |
||||
}, |
return this |
||||
/** |
}, |
||||
* 点击组件触发回调 |
/** |
||||
*/ |
* ref 触发 执行动画 |
||||
onClick() { |
*/ |
||||
this.$emit("click", { |
run(fn) { |
||||
detail: this.isShow, |
if (!this.animation) return |
||||
}); |
this.animation.run(fn) |
||||
}, |
}, |
||||
/** |
// 开始过度动画 |
||||
* ref 触发 动画分组 |
open() { |
||||
* @param {Object} obj |
clearTimeout(this.timer) |
||||
*/ |
this.isShow = true |
||||
step(obj, config = {}) { |
// 新增初始状态重置逻辑(关键) |
||||
if (!this.animation) return this; |
this.transform = this.styleInit(false).transform || '' |
||||
for (let i in obj) { |
this.opacity = this.styleInit(false).opacity || 0 |
||||
try { |
|
||||
if (this.animation && typeof this.animation[i] === "function") { |
|
||||
if (typeof obj[i] === "object") { |
|
||||
this.animation[i](...obj[i]); |
|
||||
} else { |
|
||||
this.animation[i](obj[i]); |
|
||||
} |
|
||||
} |
|
||||
} catch (e) { |
|
||||
console.error(`方法 ${i} 不存在:`, e); |
|
||||
} |
|
||||
} |
|
||||
try { |
|
||||
if (this.animation && typeof this.animation.step === "function") { |
|
||||
this.animation.step(config); |
|
||||
} |
|
||||
} catch (e) { |
|
||||
console.error("动画step执行错误:", e); |
|
||||
} |
|
||||
return this; |
|
||||
}, |
|
||||
/** |
|
||||
* ref 触发 执行动画 |
|
||||
*/ |
|
||||
run(fn) { |
|
||||
if (!this.animation) return; |
|
||||
try { |
|
||||
if (this.animation && typeof this.animation.run === "function") { |
|
||||
this.animation.run(fn); |
|
||||
} |
|
||||
} catch (e) { |
|
||||
console.error("动画执行错误:", e); |
|
||||
} |
|
||||
}, |
|
||||
// 开始过度动画 |
|
||||
open() { |
|
||||
clearTimeout(this.timer); |
|
||||
this.transform = ""; |
|
||||
this.isShow = true; |
|
||||
let { opacity, transform } = this.styleInit(false); |
|
||||
if (typeof opacity !== "undefined") { |
|
||||
this.opacity = opacity; |
|
||||
} |
|
||||
this.transform = transform; |
|
||||
// 确保动态样式已经生效后,执行动画,如果不加 nextTick ,会导致 wx 动画执行异常 |
|
||||
this.$nextTick(() => { |
|
||||
// TODO 定时器保证动画完全执行,目前有些问题,后面会取消定时器 |
|
||||
this.timer = setTimeout(() => { |
|
||||
// 检查组件是否仍然存在且需要显示 |
|
||||
if (!this.isShow || !this.$el) { |
|
||||
return; |
|
||||
} |
|
||||
try { |
|
||||
this.animation = createAnimation(this.config, this); |
|
||||
if (this.animation && typeof this.animation.step === "function" && typeof this.animation.run === "function") { |
|
||||
this.tranfromInit(false); |
|
||||
if (typeof this.animation.step === "function") { |
|
||||
this.animation.step(); |
|
||||
if (typeof this.animation.run === "function") { |
|
||||
this.animation.run(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} catch (error) { |
|
||||
console.error('uni-transition animation error:', error); |
|
||||
} |
|
||||
this.$emit("change", { |
|
||||
detail: this.isShow, |
|
||||
}); |
|
||||
}, 20); |
|
||||
}); |
|
||||
}, |
|
||||
// 关闭过度动画 |
|
||||
close(type) { |
|
||||
if (!this.animation || typeof this.animation.step !== 'function' || typeof this.animation.run !== 'function') return; |
|
||||
try { |
|
||||
this.tranfromInit(true); |
|
||||
if (typeof this.animation.step === 'function') { |
|
||||
this.animation.step(); |
|
||||
if (typeof this.animation.run === 'function') { |
|
||||
this.animation.run(() => { |
|
||||
this.isShow = false; |
|
||||
this.animationData = null; |
|
||||
this.animation = null; |
|
||||
let { opacity, transform } = this.styleInit(false); |
|
||||
this.opacity = opacity || 1; |
|
||||
this.transform = transform; |
|
||||
this.$emit('change', { |
|
||||
detail: this.isShow, |
|
||||
}); |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
} catch (error) { |
|
||||
console.error('uni-transition close animation error:', error); |
|
||||
// 发生错误时直接关闭 |
|
||||
this.isShow = false; |
|
||||
this.animationData = null; |
|
||||
this.animation = null; |
|
||||
this.$emit('change', { |
|
||||
detail: this.isShow |
|
||||
}); |
|
||||
} |
|
||||
}, |
|
||||
// 处理动画开始前的默认样式 |
|
||||
styleInit(type) { |
|
||||
let styles = { |
|
||||
transform: "", |
|
||||
}; |
|
||||
let buildStyle = (type, mode) => { |
|
||||
if (mode === "fade") { |
|
||||
styles.opacity = this.animationType(type)[mode]; |
|
||||
} else { |
|
||||
styles.transform += this.animationType(type)[mode] + " "; |
|
||||
} |
|
||||
}; |
|
||||
if (typeof this.modeClass === "string") { |
|
||||
buildStyle(type, this.modeClass); |
|
||||
} else { |
|
||||
this.modeClass.forEach((mode) => { |
|
||||
buildStyle(type, mode); |
|
||||
}); |
|
||||
} |
|
||||
return styles; |
|
||||
}, |
|
||||
// 处理内置组合动画 |
|
||||
tranfromInit(type) { |
|
||||
if (!this.animation) { |
|
||||
console.warn('uni-transition: animation object is not initialized'); |
|
||||
return this.animation; |
|
||||
} |
|
||||
let buildTranfrom = (type, mode) => { |
|
||||
let aniNum = null; |
|
||||
if (mode === 'fade') { |
|
||||
aniNum = type ? 0 : 1; |
|
||||
} else { |
|
||||
aniNum = type ? '-100%' : '0'; |
|
||||
if (mode === 'zoom-in') { |
|
||||
aniNum = type ? 0.8 : 1; |
|
||||
} |
|
||||
if (mode === 'zoom-out') { |
|
||||
aniNum = type ? 1.2 : 1; |
|
||||
} |
|
||||
if (mode === 'slide-right') { |
|
||||
aniNum = type ? '100%' : '0'; |
|
||||
} |
|
||||
if (mode === 'slide-bottom') { |
|
||||
aniNum = type ? '100%' : '0'; |
|
||||
} |
|
||||
} |
|
||||
const animationMethod = this.animationMode()[mode]; |
|
||||
if (this.animation && typeof this.animation[animationMethod] === 'function') { |
|
||||
this.animation[animationMethod](aniNum); |
|
||||
} |
|
||||
}; |
|
||||
if (typeof this.modeClass === 'string') { |
|
||||
buildTranfrom(type, this.modeClass); |
|
||||
} else { |
|
||||
this.modeClass.forEach((mode) => { |
|
||||
buildTranfrom(type, mode); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
return this.animation; |
// 确保动态样式已经生效后,执行动画,如果不加 nextTick ,会导致 wx 动画执行异常 |
||||
}, |
this.$nextTick(() => { |
||||
animationType(type) { |
// TODO 定时器保证动画完全执行,目前有些问题,后面会取消定时器 |
||||
return { |
this.timer = setTimeout(() => { |
||||
fade: type ? 1 : 0, |
this.animation = createAnimation(this.config, this) |
||||
"slide-top": `translateY(${type ? "0" : "-100%"})`, |
this.tranfromInit(false).step() |
||||
"slide-right": `translateX(${type ? "0" : "100%"})`, |
this.animation.run(() => { |
||||
"slide-bottom": `translateY(${type ? "0" : "100%"})`, |
// #ifdef APP-NVUE |
||||
"slide-left": `translateX(${type ? "0" : "-100%"})`, |
this.transform = this.styleInit(false).transform || '' |
||||
"zoom-in": `scaleX(${type ? 1 : 0.8}) scaleY(${type ? 1 : 0.8})`, |
this.opacity = this.styleInit(false).opacity || 1 |
||||
"zoom-out": `scaleX(${type ? 1 : 1.2}) scaleY(${type ? 1 : 1.2})`, |
// #endif |
||||
}; |
// #ifndef APP-NVUE |
||||
}, |
this.transform = '' |
||||
// 内置动画类型与实际动画对应字典 |
this.opacity = this.styleInit(false).opacity || 1 |
||||
animationMode() { |
// #endif |
||||
return { |
this.$emit('change', { |
||||
fade: "opacity", |
detail: this.isShow |
||||
"slide-top": "translateY", |
}) |
||||
"slide-right": "translateX", |
}) |
||||
"slide-bottom": "translateY", |
}, 80) |
||||
"slide-left": "translateX", |
}) |
||||
"zoom-in": "scale", |
}, |
||||
"zoom-out": "scale", |
// 关闭过度动画 |
||||
}; |
close(type) { |
||||
}, |
if (!this.animation) return |
||||
// 驼峰转中横线 |
this.tranfromInit(true) |
||||
toLine(name) { |
.step() |
||||
return name.replace(/([A-Z])/g, "-$1").toLowerCase(); |
.run(() => { |
||||
}, |
this.isShow = false |
||||
}, |
this.animationData = null |
||||
}; |
this.animation = null |
||||
|
let { opacity, transform } = this.styleInit(false) |
||||
|
this.opacity = opacity || 1 |
||||
|
this.transform = transform |
||||
|
this.$emit('change', { |
||||
|
detail: this.isShow |
||||
|
}) |
||||
|
}) |
||||
|
}, |
||||
|
// 处理动画开始前的默认样式 |
||||
|
styleInit(type) { |
||||
|
let styles = { transform: '', opacity: 1 } |
||||
|
const buildStyle = (type, mode) => { |
||||
|
const value = this.animationType(type)[mode] // 直接使用 type 控制状态 |
||||
|
if (mode.startsWith('fade')) { |
||||
|
styles.opacity = value |
||||
|
} else { |
||||
|
styles.transform += value + ' ' |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (typeof this.modeClass === 'string') { |
||||
|
buildStyle(type, this.modeClass) |
||||
|
} else { |
||||
|
this.modeClass.forEach(mode => buildStyle(type, mode)) |
||||
|
} |
||||
|
return styles |
||||
|
}, |
||||
|
// 处理内置组合动画 |
||||
|
tranfromInit(type) { |
||||
|
let buildTranfrom = (type, mode) => { |
||||
|
let aniNum = null |
||||
|
if (mode === 'fade') { |
||||
|
aniNum = type ? 0 : 1 |
||||
|
} else { |
||||
|
aniNum = type ? '-100%' : '0' |
||||
|
if (mode === 'zoom-in') { |
||||
|
aniNum = type ? 0.8 : 1 |
||||
|
} |
||||
|
if (mode === 'zoom-out') { |
||||
|
aniNum = type ? 1.2 : 1 |
||||
|
} |
||||
|
if (mode === 'slide-right') { |
||||
|
aniNum = type ? '100%' : '0' |
||||
|
} |
||||
|
if (mode === 'slide-bottom') { |
||||
|
aniNum = type ? '100%' : '0' |
||||
|
} |
||||
|
} |
||||
|
this.animation[this.animationMode()[mode]](aniNum) |
||||
|
} |
||||
|
if (typeof this.modeClass === 'string') { |
||||
|
buildTranfrom(type, this.modeClass) |
||||
|
} else { |
||||
|
this.modeClass.forEach(mode => { |
||||
|
buildTranfrom(type, mode) |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
return this.animation |
||||
|
}, |
||||
|
animationType(type) { |
||||
|
return { |
||||
|
fade: type ? 1 : 0, |
||||
|
'slide-top': `translateY(${type ? '0' : '-100%'})`, |
||||
|
'slide-right': `translateX(${type ? '0' : '100%'})`, |
||||
|
'slide-bottom': `translateY(${type ? '0' : '100%'})`, |
||||
|
'slide-left': `translateX(${type ? '0' : '-100%'})`, |
||||
|
'zoom-in': `scaleX(${type ? 1 : 0.8}) scaleY(${type ? 1 : 0.8})`, |
||||
|
'zoom-out': `scaleX(${type ? 1 : 1.2}) scaleY(${type ? 1 : 1.2})` |
||||
|
} |
||||
|
}, |
||||
|
// 内置动画类型与实际动画对应字典 |
||||
|
animationMode() { |
||||
|
return { |
||||
|
fade: 'opacity', |
||||
|
'slide-top': 'translateY', |
||||
|
'slide-right': 'translateX', |
||||
|
'slide-bottom': 'translateY', |
||||
|
'slide-left': 'translateX', |
||||
|
'zoom-in': 'scale', |
||||
|
'zoom-out': 'scale' |
||||
|
} |
||||
|
}, |
||||
|
// 驼峰转中横线 |
||||
|
toLine(name) { |
||||
|
return name.replace(/([A-Z])/g, '-$1').toLowerCase() |
||||
|
} |
||||
|
} |
||||
|
} |
||||
</script> |
</script> |
||||
|
|
||||
<style></style> |
<style></style> |
||||
|
Loading…
Reference in new issue