|
|
@@ -1,51 +1,683 @@
|
|
|
<template>
|
|
|
- <uni-navbar-lite :showLeft=false title="工时"></uni-navbar-lite>
|
|
|
- <view class="page-container">
|
|
|
- <!-- 背景图 -->
|
|
|
- <image class="bg-image" src="/static/images/profile/1.png" mode="widthFix"></image>
|
|
|
-
|
|
|
- <view style="flex-grow: 1;">
|
|
|
- <view style="justify-content: center;align-items: center;">
|
|
|
- <text class="view-title">工时模块开发中......</text>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
-
|
|
|
- <!-- 底部 TabBar -->
|
|
|
- <custom-tabbar :current="2" />
|
|
|
+ <uni-navbar-lite :showLeft=false title="工时"></uni-navbar-lite>
|
|
|
+ <view class="page-container">
|
|
|
+ <!-- 搜索栏 -->
|
|
|
+ <view class="search-section">
|
|
|
+ <view class="search-box">
|
|
|
+ <text class="search-icon"></text>
|
|
|
+ <input
|
|
|
+ class="search-input"
|
|
|
+ placeholder="搜索工单编号、风机型号"
|
|
|
+ v-model="searchKeyword"
|
|
|
+ @confirm="handleSearch"
|
|
|
+ />
|
|
|
+ </view>
|
|
|
</view>
|
|
|
+
|
|
|
+ <!-- 工单分类筛选 -->
|
|
|
+ <scroll-view class="filter-tabs" scroll-x>
|
|
|
+ <view class="filter-container">
|
|
|
+ <view
|
|
|
+ class="filter-item"
|
|
|
+ :class="{ active: orderTypeFilter === '' }"
|
|
|
+ @click="filterByOrderType('')"
|
|
|
+ >
|
|
|
+ 全部
|
|
|
+ </view>
|
|
|
+ <view
|
|
|
+ class="filter-item"
|
|
|
+ :class="{ active: orderTypeFilter === '1' }"
|
|
|
+ @click="filterByOrderType('1')"
|
|
|
+ >
|
|
|
+ 维修工单
|
|
|
+ </view>
|
|
|
+ <view
|
|
|
+ class="filter-item"
|
|
|
+ :class="{ active: orderTypeFilter === '2' }"
|
|
|
+ @click="filterByOrderType('2')"
|
|
|
+ >
|
|
|
+ 维保工单
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </scroll-view>
|
|
|
+
|
|
|
+ <!-- 工时统计 -->
|
|
|
+ <view class="stats-section">
|
|
|
+ <view class="stats-header">
|
|
|
+ <text class="stats-title">{{ timeRangeTitle }}工时统计</text>
|
|
|
+ <view class="time-filters">
|
|
|
+ <text
|
|
|
+ class="time-filter"
|
|
|
+ :class="{ active: timeRange === 'week' }"
|
|
|
+ @click="changeTimeRange('week')"
|
|
|
+ >
|
|
|
+ 本周
|
|
|
+ </text>
|
|
|
+ <text
|
|
|
+ class="time-filter"
|
|
|
+ :class="{ active: timeRange === 'month' }"
|
|
|
+ @click="changeTimeRange('month')"
|
|
|
+ >
|
|
|
+ 本月
|
|
|
+ </text>
|
|
|
+ <text
|
|
|
+ class="time-filter"
|
|
|
+ :class="{ active: timeRange === 'custom' }"
|
|
|
+ @click="showCustomDatePicker"
|
|
|
+ >
|
|
|
+ 自定义
|
|
|
+ </text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 统计数据 -->
|
|
|
+ <view class="stats-content">
|
|
|
+ <view class="total-hours">
|
|
|
+ <text class="hours-value">{{ totalHours }}小时</text>
|
|
|
+ <text class="hours-label">{{ timeRangeTitle }}总工时</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="hours-breakdown">
|
|
|
+ <view v-if="orderTypeFilter !== '1'" class="breakdown-item">
|
|
|
+ <text class="breakdown-value">{{ maintenanceHours }}小时</text>
|
|
|
+ <text class="breakdown-label">维保工时</text>
|
|
|
+ </view>
|
|
|
+ <view v-if="orderTypeFilter !== '2'" class="breakdown-item">
|
|
|
+ <text class="breakdown-value">{{ repairHours }}小时</text>
|
|
|
+ <text class="breakdown-label">维修工时</text>
|
|
|
+ </view>
|
|
|
+ <view v-if="rank !== null" class="breakdown-item">
|
|
|
+ <text class="breakdown-value">第{{ rank }}名</text>
|
|
|
+ <text class="breakdown-label">排名</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 工单列表 -->
|
|
|
+ <view class="orders-section">
|
|
|
+ <common-list
|
|
|
+ :dataList="orderList"
|
|
|
+ :loading="loading"
|
|
|
+ :refreshing="refreshing"
|
|
|
+ :hasMore="hasMore"
|
|
|
+ @refresh="handleRefresh"
|
|
|
+ @loadMore="loadMore"
|
|
|
+ @itemClick="viewOrderDetail"
|
|
|
+ >
|
|
|
+ <template #default="{ item }">
|
|
|
+ <view class="order-item">
|
|
|
+ <view class="order-header">
|
|
|
+ <view class="order-info">
|
|
|
+ <text class="order-code">{{ getPropertyValue(item, 'workOrderProjectNo') }}</text>
|
|
|
+ <text class="device-name">{{ getPropertyValue(item, 'pcsDeviceName') }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="order-status" :class="'status-' + getPropertyValue(item, 'workOrderStatus')">
|
|
|
+ {{ getOrderStatusText(getPropertyValue(item, 'workOrderStatus')) }}
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="order-details">
|
|
|
+ <view class="detail-row">
|
|
|
+ <text class="detail-label">下发时间:</text>
|
|
|
+ <text class="detail-value">{{ formatDate(getPropertyValue(item, 'assignTime')) }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="detail-row">
|
|
|
+ <text class="detail-label">处理时长:</text>
|
|
|
+ <text class="detail-value">{{ formatNumber(parseFloat(getPropertyValue(item, 'handleHour'))) }}小时</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </template>
|
|
|
+ </common-list>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 自定义时间选择弹窗 -->
|
|
|
+ <l-popup v-model="showDatePickerPopup" position="bottom">
|
|
|
+ <view class="date-picker-popup">
|
|
|
+ <view class="popup-header">
|
|
|
+ <text class="popup-title">选择时间范围</text>
|
|
|
+ <view class="popup-actions">
|
|
|
+ <text class="cancel-btn" @click="closeDatePicker">取消</text>
|
|
|
+ <text class="confirm-btn" @click="confirmCustomDate">确定</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="date-picker-container">
|
|
|
+ <view class="date-picker-item">
|
|
|
+ <text class="date-label">开始时间</text>
|
|
|
+ <input type="date" v-model="startDate" class="date-input" />
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="date-picker-item">
|
|
|
+ <text class="date-label">结束时间</text>
|
|
|
+ <input type="date" v-model="endDate" class="date-input" />
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </l-popup>
|
|
|
+
|
|
|
+ <!-- 底部 TabBar -->
|
|
|
+ <custom-tabbar :current="2" />
|
|
|
+ </view>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="uts">
|
|
|
- import { ref, onMounted } from 'vue'
|
|
|
- import { getUserInfo } from '../../utils/storage'
|
|
|
- // @ts-ignore
|
|
|
- import manifest from '@/manifest.json'
|
|
|
+import { ref, reactive, computed, onMounted } from 'vue'
|
|
|
+import { listOrderHours, getOrderHourStatistics } from '@/api/worktime/index'
|
|
|
+
|
|
|
+// 数据状态
|
|
|
+const searchKeyword = ref<string>('')
|
|
|
+const orderTypeFilter = ref<string>('')
|
|
|
+const timeRange = ref<string>('month')
|
|
|
+const loading = ref<boolean>(false)
|
|
|
+const refreshing = ref<boolean>(false)
|
|
|
+const hasMore = ref<boolean>(true)
|
|
|
+const orderList = ref<any[]>([])
|
|
|
+const currentPage = ref<number>(1)
|
|
|
+const totalHours = ref<number>(0)
|
|
|
+const maintenanceHours = ref<number>(0)
|
|
|
+const repairHours = ref<number>(0)
|
|
|
+const rank = ref<number | null>(null)
|
|
|
|
|
|
- // 初始化
|
|
|
- onMounted(() => {
|
|
|
-
|
|
|
+// 弹窗显示状态
|
|
|
+const showDatePickerPopup = ref<boolean>(false)
|
|
|
+
|
|
|
+// 自定义日期表单
|
|
|
+const startDate = ref<string>('')
|
|
|
+const endDate = ref<string>('')
|
|
|
+
|
|
|
+// 弹窗引用
|
|
|
+const datePickerPopup = ref(null as any | null)
|
|
|
+
|
|
|
+// 计算属性
|
|
|
+const timeRangeTitle = computed(() => {
|
|
|
+ switch (timeRange.value) {
|
|
|
+ case 'week':
|
|
|
+ return '本周'
|
|
|
+ case 'month':
|
|
|
+ return '本月'
|
|
|
+ case 'custom':
|
|
|
+ return '自定义'
|
|
|
+ default:
|
|
|
+ return '本月'
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+// Helper function to safely extract properties from item
|
|
|
+function getPropertyValue(item: any | null, propertyName: string): string {
|
|
|
+ if (item == null) return ''
|
|
|
+ const itemObj = item as UTSJSONObject
|
|
|
+ const value = itemObj[propertyName]
|
|
|
+ return value != null ? '' + value : ''
|
|
|
+}
|
|
|
+
|
|
|
+// 方法
|
|
|
+function loadData(isRefresh: boolean) {
|
|
|
+ const shouldRefresh = isRefresh
|
|
|
+
|
|
|
+ if (loading.value && !shouldRefresh) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ loading.value = true
|
|
|
+ if (shouldRefresh) {
|
|
|
+ currentPage.value = 1
|
|
|
+ refreshing.value = true
|
|
|
+ }
|
|
|
+
|
|
|
+ const params: UTSJSONObject = {
|
|
|
+ pageNum: currentPage.value,
|
|
|
+ pageSize: 10,
|
|
|
+ keyword: searchKeyword.value,
|
|
|
+ orderType: orderTypeFilter.value,
|
|
|
+ timeRange: timeRange.value
|
|
|
+ }
|
|
|
+
|
|
|
+ if (timeRange.value === 'custom') {
|
|
|
+ params.beginDate = startDate.value
|
|
|
+ params.endDate = endDate.value
|
|
|
+ }
|
|
|
+
|
|
|
+ listOrderHours(params).then((response: any) => {
|
|
|
+ // 提取响应数据
|
|
|
+ const resultObj = response as UTSJSONObject
|
|
|
+ const responseData = resultObj['rows'] as any[]
|
|
|
+ const responseTotal = resultObj['total'] as number
|
|
|
+
|
|
|
+ if (shouldRefresh) {
|
|
|
+ orderList.value = Array.isArray(responseData) ? responseData : []
|
|
|
+ } else {
|
|
|
+ const currentRows = Array.isArray(responseData) ? responseData : []
|
|
|
+ orderList.value = [...orderList.value, ...currentRows]
|
|
|
+ }
|
|
|
+
|
|
|
+ hasMore.value = orderList.value.length < responseTotal
|
|
|
+ loading.value = false
|
|
|
+ refreshing.value = false
|
|
|
+ }).catch(() => {
|
|
|
+ loading.value = false
|
|
|
+ refreshing.value = false
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 生命周期
|
|
|
+onMounted(() => {
|
|
|
+ loadData(false)
|
|
|
+})
|
|
|
+
|
|
|
+function getStatistics() {
|
|
|
+ const params: UTSJSONObject = {
|
|
|
+ keyword: searchKeyword.value,
|
|
|
+ orderType: orderTypeFilter.value,
|
|
|
+ timeRange: timeRange.value
|
|
|
+ }
|
|
|
+
|
|
|
+ if (timeRange.value === 'custom') {
|
|
|
+ params.beginDate = startDate.value
|
|
|
+ params.endDate = endDate.value
|
|
|
+ }
|
|
|
+
|
|
|
+ getOrderHourStatistics(params).then((response: any) => {
|
|
|
+ const resultObj = response as UTSJSONObject
|
|
|
+ const responseData = resultObj['data'] as UTSJSONObject
|
|
|
+
|
|
|
+ if (responseData != null) {
|
|
|
+ totalHours.value = (responseData['totalHours'] != null) ? responseData['totalHours'] as number : 0
|
|
|
+ maintenanceHours.value = (responseData['maintenanceHours'] != null) ? responseData['maintenanceHours'] as number : 0
|
|
|
+ repairHours.value = (responseData['repairHours'] != null) ? responseData['repairHours'] as number : 0
|
|
|
+ rank.value = (responseData['rank'] != null) ? responseData['rank'] as number : null
|
|
|
+ } else {
|
|
|
+ totalHours.value = 0
|
|
|
+ maintenanceHours.value = 0
|
|
|
+ repairHours.value = 0
|
|
|
+ rank.value = null
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+function handleSearch() {
|
|
|
+ loadData(true)
|
|
|
+ getStatistics()
|
|
|
+}
|
|
|
+
|
|
|
+function filterByOrderType(type: string) {
|
|
|
+ orderTypeFilter.value = type
|
|
|
+ loadData(true)
|
|
|
+ getStatistics()
|
|
|
+}
|
|
|
+
|
|
|
+function changeTimeRange(range: string) {
|
|
|
+ timeRange.value = range
|
|
|
+ loadData(true)
|
|
|
+ getStatistics()
|
|
|
+}
|
|
|
+
|
|
|
+function loadMore() {
|
|
|
+ if (!hasMore.value || loading.value) return
|
|
|
+
|
|
|
+ currentPage.value++
|
|
|
+ loadData(false)
|
|
|
+}
|
|
|
+
|
|
|
+function handleRefresh() {
|
|
|
+ loadData(true)
|
|
|
+}
|
|
|
+
|
|
|
+function showCustomDatePicker() {
|
|
|
+ showDatePickerPopup.value = true;
|
|
|
+}
|
|
|
+
|
|
|
+function closeDatePicker() {
|
|
|
+ showDatePickerPopup.value = false;
|
|
|
+}
|
|
|
+
|
|
|
+function confirmCustomDate() {
|
|
|
+ if (startDate.value == null || startDate.value == '' || endDate.value == null || endDate.value == '') {
|
|
|
+ uni.showToast({ title: '请选择开始时间和结束时间', icon: 'none' })
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (startDate.value != null && endDate.value != null && new Date(startDate.value as string) > new Date(endDate.value as string)) {
|
|
|
+ uni.showToast({ title: '开始时间不能大于结束时间', icon: 'none' })
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ closeDatePicker()
|
|
|
+ timeRange.value = 'custom'
|
|
|
+ loadData(true)
|
|
|
+ getStatistics()
|
|
|
+}
|
|
|
+
|
|
|
+function viewOrderDetail(item: any) {
|
|
|
+ // 跳转到工单详情页面
|
|
|
+ if (item != null) {
|
|
|
+ const itemObj = item as UTSJSONObject
|
|
|
+ const id = itemObj['id']
|
|
|
+ const orderType = itemObj['orderType']
|
|
|
+ uni.navigateTo({
|
|
|
+ url: `/pages/worktime/detail?id=${id}&orderType=${orderType}`
|
|
|
})
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function getOrderStatusText(status: string): string {
|
|
|
+ const statusMap: UTSJSONObject = {
|
|
|
+ '1': '待接单',
|
|
|
+ '2': '进行中',
|
|
|
+ '3': '已完成',
|
|
|
+ '4': '已关闭'
|
|
|
+ }
|
|
|
+ const result = statusMap[status]
|
|
|
+ return result != null ? result as string : '未知状态'
|
|
|
+}
|
|
|
+
|
|
|
+function formatDate(dateString: string) {
|
|
|
+ if (dateString == '' || dateString == null) return ''
|
|
|
+ const date = new Date(dateString)
|
|
|
+ const year = date.getFullYear()
|
|
|
+ const month = (date.getMonth() + 1).toString().padStart(2, '0')
|
|
|
+ const day = date.getDate().toString().padStart(2, '0')
|
|
|
+ const hours = date.getHours().toString().padStart(2, '0')
|
|
|
+ const minutes = date.getMinutes().toString().padStart(2, '0')
|
|
|
+ return `${year}-${month}-${day} ${hours}:${minutes}`
|
|
|
+}
|
|
|
+
|
|
|
+function formatNumber(value: number | null) {
|
|
|
+ if (value === null) return '0.0'
|
|
|
+ return value.toFixed(1)
|
|
|
+}
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss">
|
|
|
- .page-container {
|
|
|
- position: relative;
|
|
|
- flex: 1;
|
|
|
- background: #f5f8fb;
|
|
|
- padding-top: env(safe-area-inset-top);
|
|
|
- }
|
|
|
+.page-container {
|
|
|
+ position: relative;
|
|
|
+ flex: 1;
|
|
|
+ background: #f5f8fb;
|
|
|
+ padding-top: env(safe-area-inset-top);
|
|
|
+ padding-bottom: env(safe-area-inset-bottom);
|
|
|
+}
|
|
|
|
|
|
- .bg-image {
|
|
|
- position: absolute;
|
|
|
- top: 0;
|
|
|
- left: 0;
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- z-index: 0;
|
|
|
- }
|
|
|
-
|
|
|
- .view-title{
|
|
|
- padding-top: 10px;
|
|
|
- color:#fff;
|
|
|
- }
|
|
|
-</style>
|
|
|
+/* 搜索栏样式 */
|
|
|
+.search-section {
|
|
|
+ padding: 20rpx;
|
|
|
+ background-color: #fff;
|
|
|
+}
|
|
|
+
|
|
|
+.search-box {
|
|
|
+ position: relative;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ height: 72rpx;
|
|
|
+ background-color: #f2f3f5;
|
|
|
+ border-radius: 36rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.search-icon {
|
|
|
+ position: absolute;
|
|
|
+ left: 24rpx;
|
|
|
+ font-family: "iconfont";
|
|
|
+ color: #999;
|
|
|
+ z-index: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.search-input {
|
|
|
+ flex: 1;
|
|
|
+ height: 72rpx;
|
|
|
+ padding-left: 70rpx;
|
|
|
+ padding-right: 30rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ background: transparent;
|
|
|
+}
|
|
|
+
|
|
|
+/* 工单分类筛选 */
|
|
|
+.filter-tabs {
|
|
|
+ white-space: nowrap;
|
|
|
+ padding: 0 20rpx 20rpx;
|
|
|
+ background-color: #fff;
|
|
|
+}
|
|
|
+
|
|
|
+.filter-container {
|
|
|
+ display: inline-flex;
|
|
|
+}
|
|
|
+
|
|
|
+.filter-item {
|
|
|
+ padding: 12rpx 32rpx;
|
|
|
+ margin-right: 20rpx;
|
|
|
+ background-color: #f2f3f5;
|
|
|
+ border-radius: 30rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #666;
|
|
|
+}
|
|
|
+
|
|
|
+.filter-item.active {
|
|
|
+ background-color: #165dff;
|
|
|
+ color: white;
|
|
|
+}
|
|
|
+
|
|
|
+/* 工时统计 */
|
|
|
+.stats-section {
|
|
|
+ margin: 20rpx;
|
|
|
+ background-color: #fff;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ padding: 30rpx;
|
|
|
+ // #ifndef APP-HARMONY
|
|
|
+ box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
|
|
|
+ // #endif
|
|
|
+}
|
|
|
+
|
|
|
+.stats-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 40rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.stats-title {
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+
|
|
|
+.time-filters {
|
|
|
+ display: flex;
|
|
|
+}
|
|
|
+
|
|
|
+.time-filter {
|
|
|
+ padding: 8rpx 20rpx;
|
|
|
+ margin-left: 16rpx;
|
|
|
+ font-size: 24rpx;
|
|
|
+ border-radius: 24rpx;
|
|
|
+ background-color: #f2f3f5;
|
|
|
+ color: #666;
|
|
|
+}
|
|
|
+
|
|
|
+.time-filter.active {
|
|
|
+ background-color: #165dff;
|
|
|
+ color: white;
|
|
|
+}
|
|
|
+
|
|
|
+/* 统计数据 */
|
|
|
+.stats-content {
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+.total-hours {
|
|
|
+ margin-bottom: 40rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.hours-value {
|
|
|
+ display: block;
|
|
|
+ font-size: 64rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #165dff;
|
|
|
+ line-height: 1.2;
|
|
|
+}
|
|
|
+
|
|
|
+.hours-label {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #666;
|
|
|
+}
|
|
|
+
|
|
|
+.hours-breakdown {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-around;
|
|
|
+}
|
|
|
+
|
|
|
+.breakdown-item {
|
|
|
+ flex: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.breakdown-value {
|
|
|
+ display: block;
|
|
|
+ font-size: 36rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ line-height: 1.4;
|
|
|
+}
|
|
|
+
|
|
|
+.breakdown-label {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #666;
|
|
|
+}
|
|
|
+
|
|
|
+/* 工单列表 */
|
|
|
+.orders-section {
|
|
|
+ flex: 1;
|
|
|
+ margin: 0 20rpx 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.order-item {
|
|
|
+ background-color: #fff;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ padding: 30rpx;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+ // #ifndef APP-HARMONY
|
|
|
+ box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
|
|
|
+ // #endif
|
|
|
+}
|
|
|
+
|
|
|
+.order-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: flex-start;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.order-info {
|
|
|
+ flex: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.order-code {
|
|
|
+ display: block;
|
|
|
+ font-size: 30rpx;
|
|
|
+ font-weight: 500;
|
|
|
+ color: #333;
|
|
|
+ margin-bottom: 8rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.device-name {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #999;
|
|
|
+}
|
|
|
+
|
|
|
+.order-status {
|
|
|
+ padding: 6rpx 16rpx;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ font-size: 24rpx;
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+
|
|
|
+.order-status.status-1 {
|
|
|
+ background-color: #eaf2ff;
|
|
|
+ color: #165dff;
|
|
|
+}
|
|
|
+
|
|
|
+.order-status.status-2 {
|
|
|
+ background-color: #fff3e6;
|
|
|
+ color: #ff7d00;
|
|
|
+}
|
|
|
+
|
|
|
+.order-status.status-3 {
|
|
|
+ background-color: #e6fffb;
|
|
|
+ color: #00b42a;
|
|
|
+}
|
|
|
+
|
|
|
+.order-status.status-4 {
|
|
|
+ background-color: #f2f3f5;
|
|
|
+ color: #86909c;
|
|
|
+}
|
|
|
+
|
|
|
+.order-details {
|
|
|
+ border-top: 2rpx dashed #eee;
|
|
|
+ padding-top: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.detail-row {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin-bottom: 10rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.detail-label {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #999;
|
|
|
+}
|
|
|
+
|
|
|
+.detail-value {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #333;
|
|
|
+}
|
|
|
+
|
|
|
+/* 日期选择弹窗 */
|
|
|
+.date-picker-popup {
|
|
|
+ background-color: white;
|
|
|
+ border-top-left-radius: 30rpx;
|
|
|
+ border-top-right-radius: 30rpx;
|
|
|
+ padding: 40rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.popup-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 40rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.popup-title {
|
|
|
+ font-size: 34rpx;
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+
|
|
|
+.cancel-btn {
|
|
|
+ color: #999;
|
|
|
+ padding: 10rpx 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.confirm-btn {
|
|
|
+ color: #165dff;
|
|
|
+ padding: 10rpx 20rpx;
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+
|
|
|
+.date-picker-container {
|
|
|
+ padding: 20rpx 0;
|
|
|
+}
|
|
|
+
|
|
|
+.date-picker-item {
|
|
|
+ margin-bottom: 40rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.date-label {
|
|
|
+ display: block;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+ font-size: 30rpx;
|
|
|
+ color: #333;
|
|
|
+}
|
|
|
+
|
|
|
+.date-input {
|
|
|
+ width: 100%;
|
|
|
+ padding: 20rpx;
|
|
|
+ border: 2rpx solid #ddd;
|
|
|
+ border-radius: 8rpx;
|
|
|
+ font-size: 32rpx;
|
|
|
+}
|
|
|
+</style>
|