|
|
@@ -1,51 +1,648 @@
|
|
|
<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="list-page">
|
|
|
+ <!-- 搜索栏 -->
|
|
|
+ <view class="search-bar">
|
|
|
+ <view class="search-box">
|
|
|
+ <image class="search-icon" src="/static/images/workbench/list/1.png" mode="aspectFit"></image>
|
|
|
+ <input
|
|
|
+ class="search-input"
|
|
|
+ placeholder="搜索工单编号、风机编号"
|
|
|
+ v-model="searchKeyword"
|
|
|
+ @confirm="handleSearch"
|
|
|
+ />
|
|
|
+ <text v-if="searchKeyword.length > 0" class="clear-icon" @click="clearSearch">✕</text>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
+
|
|
|
+ <!-- 工单评分状态筛选 -->
|
|
|
+ <view class="status-bar">
|
|
|
+ <view class="status-box">
|
|
|
+ <text
|
|
|
+ class="status-txt"
|
|
|
+ :class="{ 'stauts-sel': statusFilter === '' }"
|
|
|
+ @click="filterByStatus('')"
|
|
|
+ >
|
|
|
+ 全部
|
|
|
+ </text>
|
|
|
+ <text
|
|
|
+ class="status-txt"
|
|
|
+ :class="{ 'stauts-sel': statusFilter === 'to_self' }"
|
|
|
+ @click="filterByStatus('to_self')"
|
|
|
+ >
|
|
|
+ 待自评
|
|
|
+ </text>
|
|
|
+ <text
|
|
|
+ class="status-txt"
|
|
|
+ :class="{ 'stauts-sel': statusFilter === 'to_re' }"
|
|
|
+ @click="filterByStatus('to_re')"
|
|
|
+ >
|
|
|
+ 待复评
|
|
|
+ </text>
|
|
|
+ <text
|
|
|
+ class="status-txt"
|
|
|
+ :class="{ 'stauts-sel': statusFilter === 'to_confirm' }"
|
|
|
+ @click="filterByStatus('to_confirm')"
|
|
|
+ >
|
|
|
+ 待确认
|
|
|
+ </text>
|
|
|
+ <text
|
|
|
+ class="status-txt"
|
|
|
+ :class="{ 'stauts-sel': statusFilter === 'to_final' }"
|
|
|
+ @click="filterByStatus('to_final')"
|
|
|
+ >
|
|
|
+ 待终评
|
|
|
+ </text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 工分统计 -->
|
|
|
+ <view class="stats-section">
|
|
|
+ <view class="stats-header">
|
|
|
+ <text class="stats-title">{{ monthTitle }}月度工分</text>
|
|
|
+ <view class="month-filters">
|
|
|
+ <text
|
|
|
+ class="month-filter"
|
|
|
+ :class="{ 'month-filter-sel': selectedMonth === 'prev' }"
|
|
|
+ @click="changeMonth('prev')"
|
|
|
+ >
|
|
|
+ 上月
|
|
|
+ </text>
|
|
|
+ <text
|
|
|
+ class="month-filter"
|
|
|
+ :class="{ 'month-filter-sel': selectedMonth === 'current' }"
|
|
|
+ @click="changeMonth('current')"
|
|
|
+ >
|
|
|
+ 本月
|
|
|
+ </text>
|
|
|
+ <text
|
|
|
+ class="month-filter"
|
|
|
+ :class="{ 'month-filter-sel': selectedMonth === 'next' }"
|
|
|
+ @click="changeMonth('next')"
|
|
|
+ >
|
|
|
+ 下月
|
|
|
+ </text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 统计数据 -->
|
|
|
+ <view class="stats-content">
|
|
|
+ <view class="total-score">
|
|
|
+ <text class="score-value">{{ totalScore }}分</text>
|
|
|
+ <text class="score-label">{{ monthTitle }}总工分</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="score-breakdown">
|
|
|
+ <view class="breakdown-item">
|
|
|
+ <text class="breakdown-label">维保工分</text>
|
|
|
+ <text class="breakdown-value">{{ maintenanceScore }}分</text>
|
|
|
+ </view>
|
|
|
+ <view class="breakdown-item">
|
|
|
+ <text class="breakdown-label">维修工分</text>
|
|
|
+ <text class="breakdown-value">{{ repairScore }}分</text>
|
|
|
+ </view>
|
|
|
+ <view v-if="rank !== null && totalRankingUsers !== null" class="breakdown-item">
|
|
|
+ <text class="breakdown-label">排名</text>
|
|
|
+ <text class="breakdown-value">{{ rank }}/{{ totalRankingUsers }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 工单评分列表 -->
|
|
|
+ <common-list
|
|
|
+ :dataList="orderList"
|
|
|
+ :loading="loading"
|
|
|
+ :refreshing="refreshing"
|
|
|
+ :hasMore="hasMore"
|
|
|
+ @refresh="handleRefresh"
|
|
|
+ @loadMore="loadMore"
|
|
|
+ @itemClick="handleItemClick"
|
|
|
+ class="list-with-padding"
|
|
|
+ >
|
|
|
+ <template #default="{ item, index }">
|
|
|
+ <view class="list-item">
|
|
|
+ <view class="item-container">
|
|
|
+ <view class="item-header">
|
|
|
+ <text class="item-title">{{ getPropertyValue(item, 'workOrderProjectNo') }}-风机编号{{ getPropertyValue(item, 'pcsDeviceName') }}的{{ getWorkOrderTypeText(getPropertyValue(item, 'orderType')) }}</text>
|
|
|
+ <text class="info-value">{{ getScoringStatus(item) }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="info-row">
|
|
|
+ <view class="info-label">
|
|
|
+ <text class="text-gray"><!-- {{ getWorkOrderTypeText(getPropertyValue(item, 'orderType')) }} --></text>
|
|
|
+ </view>
|
|
|
+ <view class="info-value-row">
|
|
|
+ <text class="score-text">{{ formatNumber(parseFloat(getPropertyValue(item, 'score'))) }}分</text>
|
|
|
+ <!-- <text class="status-text">{{ getOrderStatusText(getPropertyValue(item, 'scoreStatus')) }}</text> -->
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </template>
|
|
|
+ </common-list>
|
|
|
+
|
|
|
+ <!-- 底部 TabBar -->
|
|
|
+ <custom-tabbar :current="3" />
|
|
|
+ </view>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="uts">
|
|
|
- import { ref, onMounted } from 'vue'
|
|
|
- import { getUserInfo } from '../../utils/storage'
|
|
|
- // @ts-ignore
|
|
|
- import manifest from '@/manifest.json'
|
|
|
-
|
|
|
- // 初始化
|
|
|
- onMounted(() => {
|
|
|
+ import { ref, computed, onMounted } from 'vue'
|
|
|
+ import { listOrderScores, getOrderScoreStatistics, listMobileOrderScores } from '@/api/score/index'
|
|
|
+ import { getDictDataByType } from '@/api/dict/index'
|
|
|
+ import type { SysDictData } from '@/types/dict'
|
|
|
+
|
|
|
+ // 数据状态
|
|
|
+ const searchKeyword = ref<string>('')
|
|
|
+ const statusFilter = ref<string>('')
|
|
|
+ const selectedMonth = ref<string>('current')
|
|
|
+ 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 totalScore = ref<number>(0)
|
|
|
+ const maintenanceScore = ref<number>(0)
|
|
|
+ const repairScore = ref<number>(0)
|
|
|
+ const rank = ref<number | null>(null)
|
|
|
+ const totalRankingUsers = ref<number | null>(null)
|
|
|
+
|
|
|
+ // 工单状态字典列表
|
|
|
+ const statusDictList = ref<SysDictData[]>([])
|
|
|
+ const dictLoaded = ref<boolean>(false)
|
|
|
+
|
|
|
+ // 计算属性
|
|
|
+ const monthTitle = computed(() => {
|
|
|
+ switch (selectedMonth.value) {
|
|
|
+ case 'prev':
|
|
|
+ return '上月'
|
|
|
+ case 'current':
|
|
|
+ return '本月'
|
|
|
+ case 'next':
|
|
|
+ return '下月'
|
|
|
+ default:
|
|
|
+ return '本月'
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ // 获取工单评分状态字典列表
|
|
|
+ const loadStatusDictList = async (): Promise<void> => {
|
|
|
+ try {
|
|
|
+ const result = await getDictDataByType('gxt_scoring_status')
|
|
|
+ const resultObj = result as UTSJSONObject
|
|
|
+
|
|
|
+ if (resultObj['code'] == 200) {
|
|
|
+ const data = resultObj['data'] as any[]
|
|
|
+ const dictData: SysDictData[] = []
|
|
|
+
|
|
|
+ if (data != null && data.length > 0) {
|
|
|
+ for (let i = 0; i < data.length; i++) {
|
|
|
+ const item = data[i] as UTSJSONObject
|
|
|
+ // 只提取需要的字段
|
|
|
+ const dictItem: SysDictData = {
|
|
|
+ dictValue: item['dictValue'] as string | null,
|
|
|
+ dictLabel: item['dictLabel'] as string | null,
|
|
|
+ dictCode: null,
|
|
|
+ dictSort: null,
|
|
|
+ dictType: null,
|
|
|
+ cssClass: null,
|
|
|
+ listClass: null,
|
|
|
+ isDefault: null,
|
|
|
+ status: null,
|
|
|
+ default: null,
|
|
|
+ createTime: null,
|
|
|
+ remark: null
|
|
|
+ }
|
|
|
+ dictData.push(dictItem)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ statusDictList.value = dictData
|
|
|
+ dictLoaded.value = true
|
|
|
+ }
|
|
|
+ } catch (e: any) {
|
|
|
+ console.error('获取工单评分状态字典失败:', e.message)
|
|
|
+ dictLoaded.value = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 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 getWorkOrderTypeText(orderType: string | null): string {
|
|
|
+ if (orderType != null) {
|
|
|
+ if (orderType == "1") {
|
|
|
+ return "维修工单"
|
|
|
+ } else if (orderType == "2") {
|
|
|
+ return "维保工单"
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return ""
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取工单状态文本
|
|
|
+ function getScoringStatus(item: any | null): string | null {
|
|
|
+ if (item == null) return ''
|
|
|
+ const rawStatus = getPropertyValue(item, 'scoringStatus')
|
|
|
+
|
|
|
+ if (rawStatus == null || rawStatus == '') return ''
|
|
|
|
|
|
+ // 如果字典尚未加载,返回原始值
|
|
|
+ if (!dictLoaded.value) {
|
|
|
+ return rawStatus
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查找字典中对应的标签
|
|
|
+ const dictItem = statusDictList.value.find(dict => dict.dictValue == rawStatus)
|
|
|
+ return dictItem != null ? dictItem.dictLabel : rawStatus
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取工单评分状态文本
|
|
|
+ function getOrderStatusText(status: string | null): string {
|
|
|
+ const statusMap: UTSJSONObject = {
|
|
|
+ '1': '待自评',
|
|
|
+ '2': '待复评',
|
|
|
+ '3': '待确认',
|
|
|
+ '4': '待终评'
|
|
|
+ }
|
|
|
+
|
|
|
+ if (status == null) return ''
|
|
|
+ const result = statusMap[status]
|
|
|
+ return result != null ? result as string : '未知状态'
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取统计数据
|
|
|
+ function getStatistics() {
|
|
|
+ const params: UTSJSONObject = {
|
|
|
+ //scoringStatus: statusFilter.value,
|
|
|
+ month: selectedMonth.value
|
|
|
+ }
|
|
|
+
|
|
|
+ getOrderScoreStatistics(params).then((response: any) => {
|
|
|
+ const resultObj = response as UTSJSONObject
|
|
|
+ const responseData = resultObj['data'] as UTSJSONObject
|
|
|
+
|
|
|
+ if (responseData != null) {
|
|
|
+ totalScore.value = (responseData['totalScore'] != null) ? parseFloat((responseData['totalScore'] as number).toFixed(1)) : 0
|
|
|
+ maintenanceScore.value = (responseData['maintenanceScore'] != null) ? parseFloat((responseData['maintenanceScore'] as number).toFixed(1)) : 0
|
|
|
+ repairScore.value = (responseData['repairScore'] != null) ? parseFloat((responseData['repairScore'] as number).toFixed(1)) : 0
|
|
|
+ rank.value = (responseData['rank'] != null) ? responseData['rank'] as number : null
|
|
|
+ totalRankingUsers.value = (responseData['totalRankingUsers'] != null) ? responseData['totalRankingUsers'] as number : null
|
|
|
+ } else {
|
|
|
+ totalScore.value = 0
|
|
|
+ maintenanceScore.value = 0
|
|
|
+ repairScore.value = 0
|
|
|
+ rank.value = null
|
|
|
+ totalRankingUsers.value = null
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 方法
|
|
|
+ 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: 5,
|
|
|
+ keyword: searchKeyword.value,
|
|
|
+ scoringStatus: statusFilter.value,
|
|
|
+ //month: selectedMonth.value
|
|
|
+ }
|
|
|
+
|
|
|
+ listMobileOrderScores(params).then((response: any) => {
|
|
|
+ // 提取响应数据
|
|
|
+ const resultObj = response as UTSJSONObject
|
|
|
+ console.log('API响应数据:', resultObj)
|
|
|
+ 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
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ function handleSearch() {
|
|
|
+ loadData(true)
|
|
|
+ }
|
|
|
+
|
|
|
+ function clearSearch() {
|
|
|
+ searchKeyword.value = ""
|
|
|
+ loadData(true)
|
|
|
+ }
|
|
|
+
|
|
|
+ function filterByStatus(status: string) {
|
|
|
+ statusFilter.value = status
|
|
|
+ loadData(true)
|
|
|
+ getStatistics()
|
|
|
+ }
|
|
|
+
|
|
|
+ function changeMonth(month: string) {
|
|
|
+ selectedMonth.value = month
|
|
|
+ //loadData(true)
|
|
|
+ getStatistics()
|
|
|
+ }
|
|
|
+
|
|
|
+ function loadMore() {
|
|
|
+ if (!hasMore.value || loading.value) return
|
|
|
+
|
|
|
+ currentPage.value++
|
|
|
+ loadData(false)
|
|
|
+ }
|
|
|
+
|
|
|
+ function handleRefresh() {
|
|
|
+ loadData(true)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 点击列表项
|
|
|
+ function handleItemClick(item: any | null, index: number): void {
|
|
|
+ if (item == null) return
|
|
|
+ const itemObj = item as UTSJSONObject
|
|
|
+ const id = itemObj.get('id')
|
|
|
+ const orderType = itemObj.get('orderType')
|
|
|
+ if (id != null && orderType != null) {
|
|
|
+ // 转换为字符串
|
|
|
+ const idStr = '' + id
|
|
|
+ const orderTypeStr = '' + orderType
|
|
|
+ uni.navigateTo({
|
|
|
+ url: `/pages/score/detail/index?id=${idStr}&orderType=${orderTypeStr}`
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function formatNumber(value: number | null) {
|
|
|
+ if (value === null) return '0.0'
|
|
|
+ return value.toFixed(1)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 生命周期
|
|
|
+ onMounted(() => {
|
|
|
+ loadStatusDictList()
|
|
|
+ loadData(false)
|
|
|
+ getStatistics()
|
|
|
})
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss">
|
|
|
- .page-container {
|
|
|
- position: relative;
|
|
|
- flex: 1;
|
|
|
- background: #f5f8fb;
|
|
|
- padding-top: env(safe-area-inset-top);
|
|
|
- }
|
|
|
-
|
|
|
- .bg-image {
|
|
|
- position: absolute;
|
|
|
- top: 0;
|
|
|
- left: 0;
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- z-index: 0;
|
|
|
- }
|
|
|
-
|
|
|
- .view-title{
|
|
|
- padding-top: 10px;
|
|
|
- color:#fff;
|
|
|
- }
|
|
|
+.list-page {
|
|
|
+ flex: 1;
|
|
|
+ background-color: #e8f0f9;
|
|
|
+ padding-bottom: 150rpx; // 为底部 TabBar 留出空间
|
|
|
+}
|
|
|
+
|
|
|
+/* 搜索栏样式 */
|
|
|
+.search-bar {
|
|
|
+ padding: 20rpx 30rpx;
|
|
|
+ background-color: #d7eafe;
|
|
|
+}
|
|
|
+
|
|
|
+.search-box {
|
|
|
+ flex-direction: row;
|
|
|
+ align-items: center;
|
|
|
+ height: 72rpx;
|
|
|
+ padding: 0 24rpx;
|
|
|
+ background-color: #f5f5f5;
|
|
|
+ border-radius: 36rpx;
|
|
|
+
|
|
|
+ .search-icon {
|
|
|
+ width: 32rpx;
|
|
|
+ height: 32rpx;
|
|
|
+ margin-right: 12rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .search-input {
|
|
|
+ flex: 1;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333333;
|
|
|
+ }
|
|
|
+
|
|
|
+ .clear-icon {
|
|
|
+ margin-left: 12rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #999999;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 工单状态筛选 */
|
|
|
+.status-bar {
|
|
|
+ padding-bottom: 10px;
|
|
|
+ padding-left: 30rpx;
|
|
|
+ background-color: #d7eafe;
|
|
|
+}
|
|
|
+
|
|
|
+.status-box {
|
|
|
+ flex-direction: row;
|
|
|
+ align-items: center;
|
|
|
+ height: 72rpx;
|
|
|
+ flex: 1;
|
|
|
+
|
|
|
+ .status-txt {
|
|
|
+ padding: 8px 12px;
|
|
|
+ text-align: center;
|
|
|
+ margin-right: 12rpx;
|
|
|
+ border-radius: 36rpx;
|
|
|
+ background-color: #fff;
|
|
|
+ font-size: 28rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .stauts-sel {
|
|
|
+ background-color: #007AFF;
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 工分统计 */
|
|
|
+.stats-section {
|
|
|
+ margin: 15rpx 30rpx;
|
|
|
+ background-color: #ffffff;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ padding: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.stats-header {
|
|
|
+ flex-direction: row;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.stats-title {
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ flex: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.month-filters {
|
|
|
+ flex-direction: row;
|
|
|
+ justify-content: flex-end;
|
|
|
+}
|
|
|
+
|
|
|
+.month-filter {
|
|
|
+ padding: 6rpx 16rpx;
|
|
|
+ margin-left: 12rpx;
|
|
|
+ font-size: 24rpx;
|
|
|
+ border-radius: 24rpx;
|
|
|
+ background-color: #f2f3f5;
|
|
|
+ color: #666;
|
|
|
+ white-space: nowrap;
|
|
|
+}
|
|
|
+
|
|
|
+.month-filter-sel {
|
|
|
+ background-color: #165dff;
|
|
|
+ color: white;
|
|
|
+}
|
|
|
+
|
|
|
+.stats-content {
|
|
|
+ margin-top: 20rpx;
|
|
|
+ flex-direction: column;
|
|
|
+}
|
|
|
+
|
|
|
+.total-score {
|
|
|
+ margin-bottom: 30rpx;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.score-label {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #666;
|
|
|
+ display: flex;
|
|
|
+ margin-bottom: 8rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.score-value {
|
|
|
+ display: flex;
|
|
|
+ font-size: 48rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #165dff;
|
|
|
+ line-height: 1.2;
|
|
|
+}
|
|
|
+
|
|
|
+.score-breakdown {
|
|
|
+ flex-direction: row;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+
|
|
|
+.breakdown-item {
|
|
|
+ flex: 1;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.breakdown-label {
|
|
|
+ display: flex;
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ line-height: 1.4;
|
|
|
+}
|
|
|
+
|
|
|
+.breakdown-value {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #666;
|
|
|
+ display: flex;
|
|
|
+ margin-bottom: 8rpx;
|
|
|
+}
|
|
|
+
|
|
|
+/* 列表项样式 */
|
|
|
+.list-item {
|
|
|
+ margin: 12rpx 30rpx;
|
|
|
+ background-color: #ffffff;
|
|
|
+ border-radius: 16rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.item-container {
|
|
|
+ padding: 30rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.item-header {
|
|
|
+ flex-direction: row;
|
|
|
+ align-items: flex-start;
|
|
|
+ margin-bottom: 16rpx;
|
|
|
+
|
|
|
+ .item-title {
|
|
|
+ font-size: 30rpx;
|
|
|
+ color: #333333;
|
|
|
+ font-weight: bold;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ flex: 0 1 70%;
|
|
|
+ min-width: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .info-value {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #999999;
|
|
|
+ margin-left: auto;
|
|
|
+ flex: 0 0 auto;
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.info-row {
|
|
|
+ flex-direction: row;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .info-label {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #666;
|
|
|
+ }
|
|
|
+
|
|
|
+ .info-value-row {
|
|
|
+ flex-direction: row;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .score-text {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #ff9900;
|
|
|
+ font-weight: bold;
|
|
|
+ margin-right: 20rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .status-text {
|
|
|
+ font-size: 24rpx;
|
|
|
+ padding: 4rpx 12rpx;
|
|
|
+ border-radius: 24rpx;
|
|
|
+ background-color: #f2f3f5;
|
|
|
+ color: #666;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.text-gray{
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #666;
|
|
|
+}
|
|
|
+
|
|
|
+// 添加底部填充的类
|
|
|
+.list-with-padding {
|
|
|
+ padding-bottom: 40rpx;
|
|
|
+}
|
|
|
</style>
|