first commit
This commit is contained in:
@@ -0,0 +1,450 @@
|
||||
<template>
|
||||
|
||||
<view v-if="loading" class="skeleton-container">
|
||||
<!-- 接单状态骨架屏 -->
|
||||
<view class="skeleton-status-section">
|
||||
<view class="skeleton-title"></view>
|
||||
<view class="skeleton-status-button"></view>
|
||||
</view>
|
||||
|
||||
<!-- 热门接单区域骨架屏 -->
|
||||
<view class="skeleton-map-section">
|
||||
<view class="skeleton-title"></view>
|
||||
<view class="skeleton-map-placeholder"></view>
|
||||
<view class="skeleton-map-tip"></view>
|
||||
</view>
|
||||
|
||||
<!-- 服务范围骨架屏 -->
|
||||
<view class="skeleton-service-section">
|
||||
<view class="skeleton-title"></view>
|
||||
<view class="skeleton-service-card">
|
||||
<view class="skeleton-icon"></view>
|
||||
<view class="skeleton-text"></view>
|
||||
<view class="skeleton-switch"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 提示信息骨架屏 -->
|
||||
<view class="skeleton-tip-section">
|
||||
<view class="skeleton-tip-card">
|
||||
<view class="skeleton-icon"></view>
|
||||
<view class="skeleton-tip-text"></view>
|
||||
</view>
|
||||
<view class="skeleton-tip-card">
|
||||
<view class="skeleton-icon"></view>
|
||||
<view class="skeleton-tip-text"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-else class="online-management-page">
|
||||
<!-- 接单状态 -->
|
||||
<view class="status-section">
|
||||
<view class="status-card">
|
||||
<text class="section-title">接单状态</text>
|
||||
<view class="status-button" @click="toggleStatus()" :class="{ 'online': isOnline, 'offline': !isOnline }">
|
||||
<text class="status-text">{{ isOnline ? '接单中 · 点击下线' : '已下线 · 点击上线' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 热门接单区域 -->
|
||||
<view class="map-section">
|
||||
<text class="section-title">热门接单区域</text>
|
||||
<view class="map-container">
|
||||
<!-- 地图占位,使用黑边白底样式 -->
|
||||
<view class="map-placeholder">
|
||||
<view class="map-content">
|
||||
<!-- 模拟地图上的区域标记 -->
|
||||
<view class="map-area red-area"></view>
|
||||
<view class="map-area yellow-area"></view>
|
||||
<view class="map-area green-area"></view>
|
||||
<text class="map-label">地图加载中...</text>
|
||||
</view>
|
||||
</view>
|
||||
<text class="map-tip">红色区域订单更多,建议在此范围内接单</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 服务范围 -->
|
||||
<text class="section-title">服务范围</text>
|
||||
<view class="service-card">
|
||||
<view class="range-setting">
|
||||
<view class="range-left">
|
||||
<up-icon name="map" size="20" color="#1890ff" style="margin-right: 16rpx;"></up-icon>
|
||||
<text class="range-text">手动划定接单范围</text>
|
||||
</view>
|
||||
<up-switch v-model="manualRangeEnabled" size="20" @change="handleRangeSwitchChange"></up-switch>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 提示信息 -->
|
||||
<view class="tip-card info">
|
||||
<up-icon name="info-circle" size="20" color="#1890ff" style="margin-right: 16rpx;"></up-icon>
|
||||
<text class="tip-text">上线后系统将自动推送附近订单,您可在'任务'查看并抢单。</text>
|
||||
</view>
|
||||
<view class="tip-card warning">
|
||||
<up-icon name="warning" size="20" color="#fa8c16" style="margin-right: 16rpx;"></up-icon>
|
||||
<text class="tip-text">请确保在服务区域内接单,超出范围可能影响配送效率和收入。</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import { ref } from 'vue';
|
||||
|
||||
let loading = ref(true)
|
||||
|
||||
// 接单状态
|
||||
const isOnline = ref(true);
|
||||
|
||||
// 是否启用手动划定范围
|
||||
const manualRangeEnabled = ref(false);
|
||||
|
||||
onLoad(() => {
|
||||
setTimeout(()=>{
|
||||
loading.value=false
|
||||
},1000)
|
||||
})
|
||||
|
||||
// 切换在线状态
|
||||
const toggleStatus = () => {
|
||||
const newStatus = !isOnline.value;
|
||||
// 显示确认对话框
|
||||
uni.showModal({
|
||||
title: newStatus ? '确认上线' : '确认下线',
|
||||
content: newStatus ? '上线后将接收订单推送,确定要上线吗?' : '下线后将停止接收订单推送,确定要下线吗?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
isOnline.value = newStatus;
|
||||
uni.showToast({
|
||||
title: newStatus ? '已成功上线' : '已成功下线',
|
||||
icon: 'success'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 处理范围开关变化
|
||||
const handleRangeSwitchChange = (value : boolean) => {
|
||||
manualRangeEnabled.value = value;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
/* 页面基础样式 */
|
||||
.online-management-page {
|
||||
margin: 20rpx;
|
||||
}
|
||||
|
||||
|
||||
/* 标题通用样式 */
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
/* 状态区域 */
|
||||
.status-section {
|
||||
background-color: #fff;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.status-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.status-button {
|
||||
height: 86rpx;
|
||||
border-radius: 60rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.status-button.online {
|
||||
background-color: #52c41a;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.status-button.offline {
|
||||
background-color: #d9d9d9;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.status-button:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* 地图区域 */
|
||||
.map-section {
|
||||
background-color: #fff;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.map-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.map-placeholder {
|
||||
width: 100%;
|
||||
height: 500rpx;
|
||||
border: 2rpx solid #ddd;
|
||||
background-color: #fff;
|
||||
border-radius: 12rpx;
|
||||
margin-bottom: 20rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.map-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
background-color: #f5f5f5;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* 地图上的区域标记 */
|
||||
.map-area {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.red-area {
|
||||
width: 300rpx;
|
||||
height: 300rpx;
|
||||
background-color: #ff4d4f;
|
||||
top: 120rpx;
|
||||
right: 150rpx;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.yellow-area {
|
||||
width: 250rpx;
|
||||
height: 250rpx;
|
||||
background-color: #faad14;
|
||||
top: 80rpx;
|
||||
left: 120rpx;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.green-area {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
background-color: #52c41a;
|
||||
bottom: 100rpx;
|
||||
right: 200rpx;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.map-label {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.map-tip {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* 服务范围 */
|
||||
.service-range-section {
|
||||
background-color: #fff;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.service-card {
|
||||
margin-top: 20rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
padding: 24rpx;
|
||||
}
|
||||
|
||||
.range-setting {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.range-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.range-text {
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* 提示信息 */
|
||||
|
||||
|
||||
.tip-card {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding: 24rpx;
|
||||
margin-top: 20rpx;
|
||||
border-radius: 12rpx;
|
||||
font-size: 26rpx;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.tip-card.info {
|
||||
background-color: #F6FFFB;
|
||||
}
|
||||
|
||||
.tip-card.warning {
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
.tip-text {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* 骨架屏样式 */
|
||||
.skeleton-container {
|
||||
margin: 20rpx;
|
||||
|
||||
}
|
||||
|
||||
.skeleton-status-section,
|
||||
.skeleton-map-section,
|
||||
.skeleton-service-section {
|
||||
background-color: #fff;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.skeleton-tip-section {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.skeleton-title {
|
||||
height: 32rpx;
|
||||
width: 160rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 4rpx;
|
||||
margin-bottom: 24rpx;
|
||||
animation: shimmer 1.5s infinite;
|
||||
}
|
||||
|
||||
.skeleton-status-button {
|
||||
height: 86rpx;
|
||||
width: 100%;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 60rpx;
|
||||
animation: shimmer 1.5s infinite;
|
||||
}
|
||||
|
||||
.skeleton-map-placeholder {
|
||||
height: 500rpx;
|
||||
width: 100%;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 12rpx;
|
||||
margin-bottom: 20rpx;
|
||||
animation: shimmer 1.5s infinite;
|
||||
}
|
||||
|
||||
.skeleton-map-tip {
|
||||
height: 26rpx;
|
||||
width: 70%;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 4rpx;
|
||||
animation: shimmer 1.5s infinite;
|
||||
}
|
||||
|
||||
.skeleton-service-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 24rpx;
|
||||
background-color: #fafafa;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.skeleton-icon {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 4rpx;
|
||||
animation: shimmer 1.5s infinite;
|
||||
}
|
||||
|
||||
.skeleton-text {
|
||||
height: 30rpx;
|
||||
width: 280rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 4rpx;
|
||||
margin-left: 16rpx;
|
||||
animation: shimmer 1.5s infinite;
|
||||
}
|
||||
|
||||
.skeleton-switch {
|
||||
width: 80rpx;
|
||||
height: 44rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 22rpx;
|
||||
animation: shimmer 1.5s infinite;
|
||||
}
|
||||
|
||||
.skeleton-tip-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 24rpx;
|
||||
margin-bottom: 20rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.skeleton-tip-text {
|
||||
flex: 1;
|
||||
height: 26rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 4rpx;
|
||||
margin-left: 16rpx;
|
||||
animation: shimmer 1.5s infinite;
|
||||
}
|
||||
|
||||
/* 骨架屏闪烁动画 */
|
||||
@keyframes shimmer {
|
||||
0% {
|
||||
background-position: -1000px 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: 1000px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.skeleton-title,
|
||||
.skeleton-status-button,
|
||||
.skeleton-map-placeholder,
|
||||
.skeleton-map-tip,
|
||||
.skeleton-icon,
|
||||
.skeleton-text,
|
||||
.skeleton-switch,
|
||||
.skeleton-tip-text {
|
||||
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||
background-size: 1000px 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,567 @@
|
||||
<template>
|
||||
<view class="uni-calendar">
|
||||
<view v-if="!insert&&show" class="uni-calendar__mask" :class="{'uni-calendar--mask-show':aniMaskShow}" @click="clean"></view>
|
||||
<view v-if="insert || show" class="uni-calendar__content" :class="{'uni-calendar--fixed':!insert,'uni-calendar--ani-show':aniMaskShow}">
|
||||
<view v-if="!insert" class="uni-calendar__header uni-calendar--fixed-top">
|
||||
<view class="uni-calendar__header-btn-box" @click="close">
|
||||
<text class="uni-calendar__header-text uni-calendar--fixed-width">{{cancelText}}</text>
|
||||
</view>
|
||||
<view class="uni-calendar__header-btn-box" @click="confirm">
|
||||
<text class="uni-calendar__header-text uni-calendar--fixed-width">{{okText}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-calendar__header">
|
||||
<view class="uni-calendar__header-btn-box" @click.stop="pre">
|
||||
<view class="uni-calendar__header-btn uni-calendar--left"></view>
|
||||
</view>
|
||||
<picker mode="date" :value="date" fields="month" @change="bindDateChange">
|
||||
<text class="uni-calendar__header-text">{{ (nowDate.year||'') +' / '+( nowDate.month||'')}}</text>
|
||||
</picker>
|
||||
<view class="uni-calendar__header-btn-box" @click.stop="next">
|
||||
<view class="uni-calendar__header-btn uni-calendar--right"></view>
|
||||
</view>
|
||||
<text class="uni-calendar__backtoday" @click="backToday">{{todayText}}</text>
|
||||
|
||||
</view>
|
||||
<view class="uni-calendar__box">
|
||||
<view v-if="showMonth" class="uni-calendar__box-bg">
|
||||
<text class="uni-calendar__box-bg-text">{{nowDate.month}}</text>
|
||||
</view>
|
||||
<view class="uni-calendar__weeks">
|
||||
<view class="uni-calendar__weeks-day">
|
||||
<text class="uni-calendar__weeks-day-text">{{SUNText}}</text>
|
||||
</view>
|
||||
<view class="uni-calendar__weeks-day">
|
||||
<text class="uni-calendar__weeks-day-text">{{monText}}</text>
|
||||
</view>
|
||||
<view class="uni-calendar__weeks-day">
|
||||
<text class="uni-calendar__weeks-day-text">{{TUEText}}</text>
|
||||
</view>
|
||||
<view class="uni-calendar__weeks-day">
|
||||
<text class="uni-calendar__weeks-day-text">{{WEDText}}</text>
|
||||
</view>
|
||||
<view class="uni-calendar__weeks-day">
|
||||
<text class="uni-calendar__weeks-day-text">{{THUText}}</text>
|
||||
</view>
|
||||
<view class="uni-calendar__weeks-day">
|
||||
<text class="uni-calendar__weeks-day-text">{{FRIText}}</text>
|
||||
</view>
|
||||
<view class="uni-calendar__weeks-day">
|
||||
<text class="uni-calendar__weeks-day-text">{{SATText}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex">
|
||||
<view class="uni-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex">
|
||||
<calendar-item class="uni-calendar-item--hook" :weeks="weeks" :calendar="calendar" :selected="selected" :lunar="lunar" @change="choiceDate"></calendar-item>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Calendar from './util.js';
|
||||
import CalendarItem from './uni-calendar-item.vue'
|
||||
|
||||
import { initVueI18n } from '@dcloudio/uni-i18n'
|
||||
import i18nMessages from './i18n/index.js'
|
||||
const { t } = initVueI18n(i18nMessages)
|
||||
|
||||
/**
|
||||
* Calendar 日历
|
||||
* @description 日历组件可以查看日期,选择任意范围内的日期,打点操作。常用场景如:酒店日期预订、火车机票选择购买日期、上下班打卡等
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=56
|
||||
* @property {String} date 自定义当前时间,默认为今天
|
||||
* @property {Boolean} lunar 显示农历
|
||||
* @property {String} startDate 日期选择范围-开始日期
|
||||
* @property {String} endDate 日期选择范围-结束日期
|
||||
* @property {Boolean} range 范围选择
|
||||
* @property {Boolean} insert = [true|false] 插入模式,默认为false
|
||||
* @value true 弹窗模式
|
||||
* @value false 插入模式
|
||||
* @property {Boolean} clearDate = [true|false] 弹窗模式是否清空上次选择内容
|
||||
* @property {Array} selected 打点,期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}]
|
||||
* @property {Boolean} showMonth 是否选择月份为背景
|
||||
* @event {Function} change 日期改变,`insert :ture` 时生效
|
||||
* @event {Function} confirm 确认选择`insert :false` 时生效
|
||||
* @event {Function} monthSwitch 切换月份时触发
|
||||
* @example <uni-calendar :insert="true":lunar="true" :start-date="'2019-3-2'":end-date="'2019-5-20'"@change="change" />
|
||||
*/
|
||||
export default {
|
||||
components: {
|
||||
CalendarItem
|
||||
},
|
||||
emits:['close','confirm','change','monthSwitch'],
|
||||
props: {
|
||||
date: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
selected: {
|
||||
type: Array,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
lunar: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
startDate: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
endDate: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
range: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
insert: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showMonth: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
clearDate: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
weeks: [],
|
||||
calendar: {},
|
||||
nowDate: '',
|
||||
aniMaskShow: false
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
/**
|
||||
* for i18n
|
||||
*/
|
||||
|
||||
okText() {
|
||||
return t("uni-calender.ok")
|
||||
},
|
||||
cancelText() {
|
||||
return t("uni-calender.cancel")
|
||||
},
|
||||
todayText() {
|
||||
return t("uni-calender.today")
|
||||
},
|
||||
monText() {
|
||||
return t("uni-calender.MON")
|
||||
},
|
||||
TUEText() {
|
||||
return t("uni-calender.TUE")
|
||||
},
|
||||
WEDText() {
|
||||
return t("uni-calender.WED")
|
||||
},
|
||||
THUText() {
|
||||
return t("uni-calender.THU")
|
||||
},
|
||||
FRIText() {
|
||||
return t("uni-calender.FRI")
|
||||
},
|
||||
SATText() {
|
||||
return t("uni-calender.SAT")
|
||||
},
|
||||
SUNText() {
|
||||
return t("uni-calender.SUN")
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
date(newVal) {
|
||||
// this.cale.setDate(newVal)
|
||||
this.init(newVal)
|
||||
},
|
||||
startDate(val){
|
||||
this.cale.resetSatrtDate(val)
|
||||
this.cale.setDate(this.nowDate.fullDate)
|
||||
this.weeks = this.cale.weeks
|
||||
},
|
||||
endDate(val){
|
||||
this.cale.resetEndDate(val)
|
||||
this.cale.setDate(this.nowDate.fullDate)
|
||||
this.weeks = this.cale.weeks
|
||||
},
|
||||
selected(newVal) {
|
||||
this.cale.setSelectInfo(this.nowDate.fullDate, newVal)
|
||||
this.weeks = this.cale.weeks
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.cale = new Calendar({
|
||||
selected: this.selected,
|
||||
startDate: this.startDate,
|
||||
endDate: this.endDate,
|
||||
range: this.range,
|
||||
})
|
||||
this.init(this.date)
|
||||
},
|
||||
methods: {
|
||||
// 取消穿透
|
||||
clean() {},
|
||||
bindDateChange(e) {
|
||||
const value = e.detail.value + '-1'
|
||||
this.setDate(value)
|
||||
|
||||
const { year,month } = this.cale.getDate(value)
|
||||
this.$emit('monthSwitch', {
|
||||
year,
|
||||
month
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 初始化日期显示
|
||||
* @param {Object} date
|
||||
*/
|
||||
init(date) {
|
||||
this.cale.setDate(date)
|
||||
this.weeks = this.cale.weeks
|
||||
this.nowDate = this.calendar = this.cale.getInfo(date)
|
||||
},
|
||||
/**
|
||||
* 打开日历弹窗
|
||||
*/
|
||||
open() {
|
||||
// 弹窗模式并且清理数据
|
||||
if (this.clearDate && !this.insert) {
|
||||
this.cale.cleanMultipleStatus()
|
||||
// this.cale.setDate(this.date)
|
||||
this.init(this.date)
|
||||
}
|
||||
this.show = true
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
this.aniMaskShow = true
|
||||
}, 50)
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 关闭日历弹窗
|
||||
*/
|
||||
close() {
|
||||
this.aniMaskShow = false
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
this.show = false
|
||||
this.$emit('close')
|
||||
}, 300)
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 确认按钮
|
||||
*/
|
||||
confirm() {
|
||||
this.setEmit('confirm')
|
||||
this.close()
|
||||
},
|
||||
/**
|
||||
* 变化触发
|
||||
*/
|
||||
change() {
|
||||
if (!this.insert) return
|
||||
this.setEmit('change')
|
||||
},
|
||||
/**
|
||||
* 选择月份触发
|
||||
*/
|
||||
monthSwitch() {
|
||||
let {
|
||||
year,
|
||||
month
|
||||
} = this.nowDate
|
||||
this.$emit('monthSwitch', {
|
||||
year,
|
||||
month: Number(month)
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 派发事件
|
||||
* @param {Object} name
|
||||
*/
|
||||
setEmit(name) {
|
||||
let {
|
||||
year,
|
||||
month,
|
||||
date,
|
||||
fullDate,
|
||||
lunar,
|
||||
extraInfo
|
||||
} = this.calendar
|
||||
this.$emit(name, {
|
||||
range: this.cale.multipleStatus,
|
||||
year,
|
||||
month,
|
||||
date,
|
||||
fulldate: fullDate,
|
||||
lunar,
|
||||
extraInfo: extraInfo || {}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 选择天触发
|
||||
* @param {Object} weeks
|
||||
*/
|
||||
choiceDate(weeks) {
|
||||
if (weeks.disable) return
|
||||
this.calendar = weeks
|
||||
// 设置多选
|
||||
this.cale.setMultiple(this.calendar.fullDate)
|
||||
this.weeks = this.cale.weeks
|
||||
this.change()
|
||||
},
|
||||
/**
|
||||
* 回到今天
|
||||
*/
|
||||
backToday() {
|
||||
const nowYearMonth = `${this.nowDate.year}-${this.nowDate.month}`
|
||||
const date = this.cale.getDate(new Date())
|
||||
const todayYearMonth = `${date.year}-${date.month}`
|
||||
|
||||
this.init(date.fullDate)
|
||||
|
||||
if(nowYearMonth !== todayYearMonth) {
|
||||
this.monthSwitch()
|
||||
}
|
||||
|
||||
this.change()
|
||||
},
|
||||
/**
|
||||
* 上个月
|
||||
*/
|
||||
pre() {
|
||||
const preDate = this.cale.getDate(this.nowDate.fullDate, -1, 'month').fullDate
|
||||
this.setDate(preDate)
|
||||
this.monthSwitch()
|
||||
|
||||
},
|
||||
/**
|
||||
* 下个月
|
||||
*/
|
||||
next() {
|
||||
const nextDate = this.cale.getDate(this.nowDate.fullDate, +1, 'month').fullDate
|
||||
this.setDate(nextDate)
|
||||
this.monthSwitch()
|
||||
},
|
||||
/**
|
||||
* 设置日期
|
||||
* @param {Object} date
|
||||
*/
|
||||
setDate(date) {
|
||||
this.cale.setDate(date)
|
||||
this.weeks = this.cale.weeks
|
||||
this.nowDate = this.cale.getInfo(date)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$uni-bg-color-mask: rgba($color: #000000, $alpha: 0.4);
|
||||
$uni-border-color: #EDEDED;
|
||||
$uni-text-color: #333;
|
||||
$uni-bg-color-hover:#f1f1f1;
|
||||
$uni-font-size-base:14px;
|
||||
$uni-text-color-placeholder: #808080;
|
||||
$uni-color-subtitle: #555555;
|
||||
$uni-text-color-grey:#999;
|
||||
.uni-calendar {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.uni-calendar__mask {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: $uni-bg-color-mask;
|
||||
transition-property: opacity;
|
||||
transition-duration: 0.3s;
|
||||
opacity: 0;
|
||||
/* #ifndef APP-NVUE */
|
||||
z-index: 99;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-calendar--mask-show {
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
.uni-calendar--fixed {
|
||||
position: fixed;
|
||||
/* #ifdef APP-NVUE */
|
||||
bottom: 0;
|
||||
/* #endif */
|
||||
left: 0;
|
||||
right: 0;
|
||||
transition-property: transform;
|
||||
transition-duration: 0.3s;
|
||||
transform: translateY(460px);
|
||||
/* #ifndef APP-NVUE */
|
||||
bottom: calc(var(--window-bottom));
|
||||
z-index: 99;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-calendar--ani-show {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.uni-calendar__content {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.uni-calendar__header {
|
||||
position: relative;
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 50px;
|
||||
border-bottom-color: $uni-border-color;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
|
||||
.uni-calendar--fixed-top {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
border-top-color: $uni-border-color;
|
||||
border-top-style: solid;
|
||||
border-top-width: 1px;
|
||||
}
|
||||
|
||||
.uni-calendar--fixed-width {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.uni-calendar__backtoday {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 25rpx;
|
||||
padding: 0 5px;
|
||||
padding-left: 10px;
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
font-size: 12px;
|
||||
border-top-left-radius: 25px;
|
||||
border-bottom-left-radius: 25px;
|
||||
color: $uni-text-color;
|
||||
background-color: $uni-bg-color-hover;
|
||||
}
|
||||
|
||||
.uni-calendar__header-text {
|
||||
text-align: center;
|
||||
width: 100px;
|
||||
font-size: $uni-font-size-base;
|
||||
color: $uni-text-color;
|
||||
}
|
||||
|
||||
.uni-calendar__header-btn-box {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.uni-calendar__header-btn {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-left-color: $uni-text-color-placeholder;
|
||||
border-left-style: solid;
|
||||
border-left-width: 2px;
|
||||
border-top-color: $uni-color-subtitle;
|
||||
border-top-style: solid;
|
||||
border-top-width: 2px;
|
||||
}
|
||||
|
||||
.uni-calendar--left {
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
.uni-calendar--right {
|
||||
transform: rotate(135deg);
|
||||
}
|
||||
|
||||
|
||||
.uni-calendar__weeks {
|
||||
position: relative;
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.uni-calendar__weeks-item {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.uni-calendar__weeks-day {
|
||||
flex: 1;
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 45px;
|
||||
border-bottom-color: #F5F5F5;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
|
||||
.uni-calendar__weeks-day-text {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.uni-calendar__box {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.uni-calendar__box-bg {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.uni-calendar__box-bg-text {
|
||||
font-size: 200px;
|
||||
font-weight: bold;
|
||||
color: $uni-text-color-grey;
|
||||
opacity: 0.1;
|
||||
text-align: center;
|
||||
/* #ifndef APP-NVUE */
|
||||
line-height: 1;
|
||||
/* #endif */
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,657 @@
|
||||
<template>
|
||||
|
||||
<!-- 骨架屏状态 -->
|
||||
<view v-if="loading" class="skeleton-loading">
|
||||
<!-- 收入概览骨架屏 -->
|
||||
<view class="skeleton-card income-overview">
|
||||
<view class="skeleton-income-title"></view>
|
||||
<view class="skeleton-income-amount"></view>
|
||||
<view class="skeleton-time-tabs">
|
||||
<view class="skeleton-tab-item"></view>
|
||||
<view class="skeleton-tab-item"></view>
|
||||
<view class="skeleton-tab-item"></view>
|
||||
</view>
|
||||
<view class="skeleton-month-total"></view>
|
||||
</view>
|
||||
|
||||
<!-- 收入构成骨架屏 -->
|
||||
<view class="skeleton-card income-composition">
|
||||
<view class="skeleton-pie-container">
|
||||
<view class="skeleton-pie-chart"></view>
|
||||
<view class="skeleton-legend-list">
|
||||
<view class="skeleton-legend-item" v-for="item in 3">
|
||||
<view class="skeleton-legend-dot"></view>
|
||||
<view class="skeleton-legend-text"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 钱包区域骨架屏 -->
|
||||
<view class="skeleton-card wallet-section">
|
||||
<view class="skeleton-wallet-header">
|
||||
<view class="skeleton-wallet-title"></view>
|
||||
<view class="skeleton-wallet-amount"></view>
|
||||
</view>
|
||||
<view class="skeleton-withdraw-button"></view>
|
||||
<view class="skeleton-withdraw-tip"></view>
|
||||
</view>
|
||||
|
||||
<!-- 收入明细骨架屏 -->
|
||||
<view class="skeleton-card">
|
||||
<view class="skeleton-detail-title"></view>
|
||||
</view>
|
||||
|
||||
<!-- 明细项骨架屏 -->
|
||||
<view v-for="index in 3" :key="index" class="skeleton-card detail-list">
|
||||
<view class="skeleton-detail-content">
|
||||
<view class="skeleton-icon-placeholder"></view>
|
||||
<view class="skeleton-detail-info">
|
||||
<view class="skeleton-order-id"></view>
|
||||
<view class="skeleton-order-time"></view>
|
||||
</view>
|
||||
<view class="skeleton-order-amount"></view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 加载更多 -->
|
||||
<view class="skeleton-card" style="display: flex; justify-content: center; ">
|
||||
<view class="skeleton-detail-title"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 收入概览区域 -->
|
||||
<view v-else class="income-container">
|
||||
<view class="income-overview">
|
||||
<view class="income-header">
|
||||
<text class="income-title">今日已赚</text>
|
||||
<text class="income-amount">¥86.50</text>
|
||||
</view>
|
||||
|
||||
<!-- 时间选择标签 -->
|
||||
<view class="time-tabs">
|
||||
<text v-for="(item ,index) in timeList" :key="index" @click="changeTab(index)"
|
||||
:class="{ 'active':currentTime==index }" class="tab-item">{{item}}</text>
|
||||
</view>
|
||||
<text class="month-total">本月累计¥1,240.00</text>
|
||||
</view>
|
||||
|
||||
<!-- 收入构成区域 -->
|
||||
<view class="income-composition">
|
||||
<!-- 饼图占位区域 -->
|
||||
<view class="pie-chart-placeholder">
|
||||
<view id="cahrt" class="pie-chart">
|
||||
<!-- 黑边白底的饼图占位 -->
|
||||
</view>
|
||||
<view class="chart-legend">
|
||||
<view class="legend-item">
|
||||
<view class="legend-dot blue"></view>
|
||||
<text class="legend-text">配送费¥60.50</text>
|
||||
</view>
|
||||
<view class="legend-item">
|
||||
<view class="legend-dot orange"></view>
|
||||
<text class="legend-text">冲单奖¥20.00</text>
|
||||
</view>
|
||||
<view class="legend-item">
|
||||
<view class="legend-dot green"></view>
|
||||
<text class="legend-text">恶劣天气补贴¥6.00</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 钱包区域 -->
|
||||
<view class="wallet-section">
|
||||
<view class="wallet-header">
|
||||
<text class="wallet-title">钱包余额</text>
|
||||
<text class="wallet-amount">¥86.50</text>
|
||||
</view>
|
||||
<u-button class="withdraw-button" @click="Service.GoPage('/pages/order/withdraw')" type="primary">立即提现</u-button>
|
||||
<text class="withdraw-tip">提现到账时间: T+1工作日</text>
|
||||
</view>
|
||||
|
||||
<!-- 收入明细区域 -->
|
||||
<view class="detail-header">
|
||||
<text class="detail-title">收入明细</text>
|
||||
</view>
|
||||
<view class="detail-list" @click="Service.GoPage('/pages/order/incomeDetail')" v-for="(item, index) in 3"
|
||||
:key="index">
|
||||
<view class="detail-content">
|
||||
<view class="icon-placeholder">
|
||||
<image :src="Service.GetIconImg('/static/index/income/order.png')"
|
||||
style="width: 55rpx; height: 55rpx;" mode=""></image>
|
||||
</view>
|
||||
<view class="detail-info">
|
||||
<text class="order-id">订单 MT20251020123456</text>
|
||||
<text class="order-time">10-20 18:35</text>
|
||||
</view>
|
||||
<text class="order-amount">+¥5.50</text>
|
||||
</view>
|
||||
</view>
|
||||
<up-loadmore :status="status" />
|
||||
<view class="" style="width: 100vw; height: 100rpx; ">
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import { ref, onMounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { Service } from '@/Service/Service';
|
||||
|
||||
let loading = ref(true)
|
||||
|
||||
let timeList = ref([
|
||||
'今日',
|
||||
'本周',
|
||||
'本月'
|
||||
])
|
||||
|
||||
let currentTime = ref(0)
|
||||
|
||||
let status = ref('nomore')
|
||||
|
||||
let test = ref(10)
|
||||
|
||||
let option = ref({
|
||||
tooltip: {
|
||||
'show': false
|
||||
},
|
||||
legend: {
|
||||
'show': false
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'Access From',
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
avoidLabelOverlap: true,
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center'
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: false,
|
||||
fontSize: 40,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{ value: test.value, name: "配送奖", itemStyle: { color: '#1890FF' } },
|
||||
{ value: 735, name: "冲单奖", itemStyle: { color: '#52C41A' } },
|
||||
{ value: 580, name: "恶劣天气奖", itemStyle: { color: '#FF4D4F' } }
|
||||
]
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
onLoad(() => {
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
setTimeout(() => {
|
||||
draw()
|
||||
}, 1000)
|
||||
}, 1000)
|
||||
})
|
||||
onMounted(() => {
|
||||
})
|
||||
|
||||
const draw = () => {
|
||||
let chartDom = ref(document.getElementById('cahrt'))
|
||||
let myChart = ref(echarts.init(chartDom.value))
|
||||
myChart.value.setOption(option.value)
|
||||
}
|
||||
|
||||
const changeTab = (index : number) => {
|
||||
currentTime.value = index
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
<style scoped>
|
||||
.income-container {
|
||||
padding: 20rpx;
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 收入概览区域 */
|
||||
.income-overview {
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.income-header {
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.income-title {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.income-amount {
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
color: #ff4d4f;
|
||||
}
|
||||
|
||||
/* 时间标签 */
|
||||
.time-tabs {
|
||||
display: flex;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.tab-item {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-right: 40rpx;
|
||||
padding-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.tab-item.active {
|
||||
color: #1890ff;
|
||||
border-bottom: 3rpx solid #1890ff;
|
||||
}
|
||||
|
||||
.month-total {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* 收入构成区域 */
|
||||
.income-composition {
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
/* 饼图占位 */
|
||||
.pie-chart-placeholder {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.pie-chart {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
margin-right: 30rpx;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
.chart-legend {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.legend-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
|
||||
.legend-dot {
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.legend-dot.blue {
|
||||
background-color: var(--nav-mian);
|
||||
}
|
||||
|
||||
.legend-dot.orange {
|
||||
background-color: var(--nav-vice);
|
||||
}
|
||||
|
||||
.legend-dot.green {
|
||||
background-color: var(--nav-diluted);
|
||||
}
|
||||
|
||||
.legend-text {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* 钱包区域 */
|
||||
.wallet-section {
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.wallet-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.wallet-title {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.wallet-amount {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #ff4d4f;
|
||||
}
|
||||
|
||||
.withdraw-button {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
font-size: 32rpx;
|
||||
border-radius: 40rpx;
|
||||
background-color: #1890ff;
|
||||
color: #fff;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.withdraw-tip {
|
||||
display: block;
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 收入明细区域 */
|
||||
.income-detail {
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
}
|
||||
|
||||
.detail-header {
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.detail-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
|
||||
.detail-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.detail-list {
|
||||
margin: 15rpx 0 0;
|
||||
background-color: #fff;
|
||||
padding: 20rpx 30rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
/* 图标占位符 - 黑边白底 */
|
||||
.icon-placeholder {
|
||||
width: 70rpx;
|
||||
height: 70rpx;
|
||||
background-color: #E6F7FF;
|
||||
border-radius: 8rpx;
|
||||
margin-right: 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.detail-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.order-id {
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
|
||||
.order-time {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.order-amount {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #ff4d4f;
|
||||
}
|
||||
|
||||
/* 没有更多记录 */
|
||||
.no-more {
|
||||
text-align: center;
|
||||
padding: 40rpx 0;
|
||||
}
|
||||
|
||||
.no-more-text {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 骨架屏样式 */
|
||||
.skeleton-loading .skeleton-card {
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 收入概览骨架屏 */
|
||||
.skeleton-income-title {
|
||||
width: 100rpx;
|
||||
height: 30rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 4rpx;
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
|
||||
.skeleton-income-amount {
|
||||
width: 200rpx;
|
||||
height: 50rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 4rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.skeleton-time-tabs {
|
||||
display: flex;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.skeleton-tab-item {
|
||||
width: 80rpx;
|
||||
height: 30rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 4rpx;
|
||||
margin-right: 40rpx;
|
||||
}
|
||||
|
||||
.skeleton-month-total {
|
||||
width: 200rpx;
|
||||
height: 30rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
/* 收入构成骨架屏 */
|
||||
.skeleton-pie-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.skeleton-pie-chart {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 50%;
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
|
||||
.skeleton-legend-list {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.skeleton-legend-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
|
||||
.skeleton-legend-dot {
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 50%;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.skeleton-legend-text {
|
||||
width: 200rpx;
|
||||
height: 30rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
/* 钱包区域骨架屏 */
|
||||
.skeleton-wallet-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.skeleton-wallet-title {
|
||||
width: 120rpx;
|
||||
height: 30rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
.skeleton-wallet-amount {
|
||||
width: 150rpx;
|
||||
height: 40rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
.skeleton-withdraw-button {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 40rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.skeleton-withdraw-tip {
|
||||
width: 300rpx;
|
||||
height: 24rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 4rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* 收入明细骨架屏 */
|
||||
.skeleton-detail-title {
|
||||
width: 150rpx;
|
||||
height: 30rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
.skeleton-detail-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.skeleton-icon-placeholder {
|
||||
width: 70rpx;
|
||||
height: 70rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 8rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.skeleton-detail-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.skeleton-order-id {
|
||||
width: 300rpx;
|
||||
height: 30rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 4rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.skeleton-order-time {
|
||||
width: 200rpx;
|
||||
height: 26rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
.skeleton-order-amount {
|
||||
width: 100rpx;
|
||||
height: 36rpx;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
/* 骨架屏动画 */
|
||||
.skeleton-loading .skeleton-income-title::after,
|
||||
.skeleton-loading .skeleton-income-amount::after,
|
||||
.skeleton-loading .skeleton-tab-item::after,
|
||||
.skeleton-loading .skeleton-month-total::after,
|
||||
.skeleton-loading .skeleton-pie-chart::after,
|
||||
.skeleton-loading .skeleton-legend-dot::after,
|
||||
.skeleton-loading .skeleton-legend-text::after,
|
||||
.skeleton-loading .skeleton-wallet-title::after,
|
||||
.skeleton-loading .skeleton-wallet-amount::after,
|
||||
.skeleton-loading .skeleton-withdraw-button::after,
|
||||
.skeleton-loading .skeleton-withdraw-tip::after,
|
||||
.skeleton-loading .skeleton-detail-title::after,
|
||||
.skeleton-loading .skeleton-icon-placeholder::after,
|
||||
.skeleton-loading .skeleton-order-id::after,
|
||||
.skeleton-loading .skeleton-order-time::after,
|
||||
.skeleton-loading .skeleton-order-amount::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||||
animation: shimmer 1.5s infinite;
|
||||
}
|
||||
|
||||
@keyframes shimmer {
|
||||
0% {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user