完成consumer端同步

This commit is contained in:
2026-05-14 15:28:09 +08:00
parent 612fb3d360
commit 0ffbc53902
197 changed files with 92657 additions and 7564 deletions

View File

@@ -0,0 +1,83 @@
<template>
<view class="action-row" :class="compact ? 'compact-row' : ''">
<view v-for="item in actions" :key="item.key" class="action-btn" :class="item.tone" @click="handleClick(item.key)">
{{ item.label }}
</view>
</view>
</template>
<script setup lang="uts">
type ServiceActionItem = {
key: string
label: string
tone: string
}
defineProps({
actions: {
type: Array<ServiceActionItem>,
default: [] as Array<ServiceActionItem>
},
compact: {
type: Boolean,
default: false
}
})
const emit = defineEmits<{
(e: 'action', key: string): void
}>()
function handleClick(key: string) {
emit('action', key)
}
</script>
<style scoped>
.action-row {
margin-top: 20rpx;
flex-direction: row;
gap: 16rpx;
}
.compact-row {
margin-top: 12rpx;
}
.action-btn {
flex: 1;
padding: 20rpx 0;
border-radius: 16rpx;
text-align: center;
font-size: 26rpx;
font-weight: 700;
}
.ghost {
background: #ffffff;
color: #16324f;
border-width: 2rpx;
border-style: solid;
border-color: #d7e0ea;
}
.primary {
background: #1d4ed8;
color: #ffffff;
}
.warn {
background: #fff4e5;
color: #b45309;
}
.success {
background: #e8f7ef;
color: #15803d;
}
.teal {
background: #e6fffb;
color: #0f766e;
}
</style>

View File

@@ -0,0 +1,99 @@
<template>
<view class="info-card">
<view class="header-row">
<view>
<text class="title">{{ title }}</text>
<text class="code">{{ code }}</text>
</view>
<ServiceStatusTag v-if="statusText != ''" :text="statusText" :tone="statusTone"></ServiceStatusTag>
</view>
<view v-for="item in items" :key="item.label" class="info-line">
<text class="info-label">{{ item.label }}</text>
<text class="info-value">{{ item.value }}</text>
</view>
</view>
</template>
<script setup lang="uts">
import ServiceStatusTag from '@/components/homeService/ServiceStatusTag.uvue'
type ServiceInfoItem = {
label: string
value: string
}
defineProps({
title: {
type: String,
default: ''
},
code: {
type: String,
default: ''
},
statusText: {
type: String,
default: ''
},
statusTone: {
type: String,
default: 'neutral'
},
items: {
type: Array<ServiceInfoItem>,
default: [] as Array<ServiceInfoItem>
}
})
</script>
<style scoped>
.info-card {
padding: 24rpx;
border-radius: 20rpx;
background: #f8fbfc;
}
.header-row {
flex-direction: row;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 12rpx;
}
.title {
font-size: 34rpx;
font-weight: 700;
color: #16324f;
}
.code,
.info-label,
.info-value {
margin-top: 10rpx;
font-size: 26rpx;
line-height: 38rpx;
}
.code,
.info-label {
color: #66788a;
}
.info-value {
color: #16324f;
flex: 1;
text-align: right;
}
.info-line {
flex-direction: row;
justify-content: space-between;
align-items: flex-start;
padding-top: 14rpx;
border-top-width: 1rpx;
border-top-style: solid;
border-top-color: #e2e8f0;
margin-top: 14rpx;
gap: 24rpx;
}
</style>

View File

@@ -0,0 +1,49 @@
<template>
<view class="info-list">
<view v-for="item in items" :key="item.label" class="info-item">
<text class="info-label">{{ item.label }}</text>
<text class="info-value">{{ item.value }}</text>
</view>
</view>
</template>
<script setup lang="uts">
type ServiceInfoListItem = {
label: string
value: string
}
defineProps({
items: {
type: Array<ServiceInfoListItem>,
default: [] as Array<ServiceInfoListItem>
}
})
</script>
<style scoped>
.info-list {
gap: 14rpx;
}
.info-item {
flex-direction: row;
align-items: flex-start;
gap: 12rpx;
}
.info-label,
.info-value {
font-size: 26rpx;
line-height: 38rpx;
}
.info-label {
color: #66788a;
}
.info-value {
flex: 1;
color: #16324f;
}
</style>

View File

@@ -0,0 +1,58 @@
<template>
<view class="panel">
<view class="panel-header">
<view>
<text class="panel-title">{{ title }}</text>
<text v-if="subtitle != ''" class="panel-subtitle">{{ subtitle }}</text>
</view>
<slot name="extra"></slot>
</view>
<view class="panel-body">
<slot></slot>
</view>
</view>
</template>
<script setup lang="uts">
defineProps({
title: {
type: String,
default: ''
},
subtitle: {
type: String,
default: ''
}
})
</script>
<style scoped>
.panel {
background: #ffffff;
border-radius: 24rpx;
padding: 28rpx;
margin-bottom: 24rpx;
box-shadow: 0 8rpx 24rpx rgba(15, 23, 42, 0.05);
}
.panel-header {
flex-direction: row;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
}
.panel-title {
font-size: 32rpx;
font-weight: 700;
color: #12324a;
line-height: 44rpx;
}
.panel-subtitle {
margin-top: 8rpx;
font-size: 24rpx;
color: #6b7a89;
line-height: 36rpx;
}
</style>

View File

@@ -0,0 +1,63 @@
<template>
<view class="status-tag" :class="'tag-' + tone">
<text class="status-text">{{ text }}</text>
</view>
</template>
<script setup lang="uts">
defineProps({
text: {
type: String,
default: ''
},
tone: {
type: String,
default: 'neutral'
}
})
</script>
<style scoped>
.status-tag {
padding: 8rpx 20rpx;
border-radius: 999rpx;
align-self: flex-start;
}
.status-text {
font-size: 24rpx;
font-weight: 600;
}
.tag-primary {
background-color: #e8f2ff;
}
.tag-primary .status-text {
color: #2563eb;
}
.tag-warning {
background-color: #fff4e5;
}
.tag-warning .status-text {
color: #b45309;
}
.tag-success {
background-color: #e8f7ef;
}
.tag-success .status-text {
color: #15803d;
}
.tag-neutral {
background-color: #eef2f6;
}
.tag-neutral .status-text {
color: #475569;
}
</style>

View File

@@ -0,0 +1,67 @@
<template>
<view>
<view v-if="items.length == 0" class="empty-box">
<text class="empty-text">暂无过程记录</text>
</view>
<view v-for="item in items" :key="item.id" class="timeline-item">
<view class="dot"></view>
<view class="timeline-body">
<text class="timeline-title">{{ item.title }}</text>
<text class="timeline-time">{{ item.time }}</text>
<text class="timeline-desc">{{ item.description }}</text>
</view>
</view>
</view>
</template>
<script setup lang="uts">
import { HomeServiceTimelineItemType } from '@/types/home-service.uts'
defineProps({
items: {
type: Array<HomeServiceTimelineItemType>,
default: [] as Array<HomeServiceTimelineItemType>
}
})
</script>
<style scoped>
.timeline-item {
flex-direction: row;
align-items: flex-start;
margin-bottom: 20rpx;
}
.dot {
width: 18rpx;
height: 18rpx;
border-radius: 9rpx;
background: #0f766e;
margin-top: 10rpx;
margin-right: 16rpx;
}
.timeline-body {
flex: 1;
}
.timeline-title {
font-size: 28rpx;
font-weight: 700;
color: #16324f;
}
.timeline-time,
.timeline-desc,
.empty-text {
margin-top: 10rpx;
font-size: 26rpx;
line-height: 38rpx;
color: #66788a;
}
.empty-box {
padding: 24rpx 0;
align-items: center;
}
</style>