浏览代码

采购订单模块

wuhb 1 天之前
父节点
当前提交
90db7eccb2
共有 5 个文件被更改,包括 957 次插入7 次删除
  1. 36 0
      api/purchase/index.uts
  2. 14 0
      pages.json
  3. 1 1
      pages/index/index.uvue
  4. 404 0
      pages/purchase/detail.uvue
  5. 502 6
      pages/purchase/index.uvue

+ 36 - 0
api/purchase/index.uts

@@ -14,4 +14,40 @@ export const createMergePurchase = (data: UTSJSONObject | null): Promise<any> =>
 		method: 'POST',
 		data: data
 	})
+}
+
+/**
+ * 查询采购订单列表
+ * @param query 查询条件
+ * @returns 
+ */
+export const listPurchase = (query: UTSJSONObject | null): Promise<any> => {
+	let url = '/mes/wm/purchase/list?'
+	if (query != null) {
+		const keys = Object.keys(query)
+		for (let i = 0; i < keys.length; i++) {
+			const key = keys[i]
+			const val = query[key]
+			if (val != null) {
+				if (i > 0) url += '&'
+				url += `${key}=${encodeURIComponent(val.toString())}`
+			}
+		}
+	}
+	return request({
+		url: url,
+		method: 'GET'
+	})
+}
+
+/**
+ * 查询采购订单详情
+ * @param purchaseId 采购订单ID
+ * @returns 
+ */
+export const getPurchase = (purchaseId: string): Promise<any> => {
+	return request({
+		url: '/mes/wm/purchase/' + purchaseId,
+		method: 'GET'
+	})
 }

+ 14 - 0
pages.json

@@ -216,6 +216,20 @@
 				"navigationBarTitleText": "生产汇报详情",
 				"navigationStyle": "custom"
 			}
+		},
+		{
+			"path": "pages/purchase/index",
+			"style": {
+				"navigationBarTitleText": "采购订单",
+				"navigationStyle": "custom"
+			}
+		},
+		{
+			"path": "pages/purchase/detail",
+			"style": {
+				"navigationBarTitleText": "采购订单详情",
+				"navigationStyle": "custom"
+			}
 		}
 	],
 	"globalStyle": {

+ 1 - 1
pages/index/index.uvue

@@ -127,7 +127,7 @@
             title: '采购订单',
             bgImage: '/static/images/workbench/6.png',
             icon: '',
-            path: '/pages/quality/index',
+            path: '/pages/purchase/index',
 			badge: 0,
 			permission: 'wm:purchase:list'
         },

+ 404 - 0
pages/purchase/detail.uvue

@@ -0,0 +1,404 @@
+<template>
+	<uni-navbar-lite :showRight=false :title="title"></uni-navbar-lite>
+	<view class="page-container">
+		<scroll-view class="page-content" :scroll-y="true">
+			<!-- 订单基本信息 -->
+			<view class="section">
+				<view class="section-header">
+					<view class="section-indicator"></view>
+					<text class="section-title">订单信息</text>
+				</view>
+				<view class="info-card">
+					<view class="info-row">
+						<text class="info-label">采购单编号</text>
+						<text class="info-value primary">{{ purchaseCode }}</text>
+					</view>
+					<view class="info-row">
+						<text class="info-label">供应商</text>
+						<text class="info-value">{{ vendorName || '-' }}</text>
+					</view>
+					<view class="info-row">
+						<text class="info-label">合同号</text>
+						<text class="info-value">{{ contractNumber || '-' }}</text>
+					</view>
+					<view class="info-row">
+						<text class="info-label">总金额</text>
+						<text class="info-value warning">{{ totalAmount }}</text>
+					</view>
+					<view class="info-row">
+						<text class="info-label">状态</text>
+						<view class="status-badge" :class="'status-' + status">
+							{{ statusText }}
+						</view>
+					</view>
+				</view>
+			</view>
+
+			<!-- 订单行列表 -->
+			<view class="section">
+				<view class="section-header">
+					<view class="section-indicator"></view>
+					<text class="section-title">采购明细</text>
+					<text class="section-count">共 {{ lineList.length }} 项</text>
+				</view>
+				<view class="line-list">
+					<view v-for="(item, index) in lineList" :key="getLineId(item, index)" class="line-card">
+						<view class="line-top">
+							<text class="line-index">{{ index + 1 }}</text>
+							<view class="line-right">
+								<text class="item-name">{{ getItemName(item) }}</text>
+								<text class="item-code-tag">{{ getItemCode(item) }}</text>
+							</view>
+						</view>
+						<view class="line-body">
+							<view class="line-row">
+								<view class="line-cell">
+									<text class="line-label">规格</text>
+									<text class="line-value">{{ item.specification || '-' }}</text>
+								</view>
+								<view class="line-cell">
+									<text class="line-label">单位</text>
+									<text class="line-value">{{ item.measureName || '-' }}</text>
+								</view>
+							</view>
+							<view class="line-row">
+								<view class="line-cell">
+									<text class="line-label">数量</text>
+									<text class="line-value qty">{{ item.quantity || '0' }}</text>
+								</view>
+								<view class="line-cell">
+									<text class="line-label">单价</text>
+									<text class="line-value">{{ getPrice(item) }}</text>
+								</view>
+							</view>
+							<view class="line-row">
+								<view class="line-cell">
+									<text class="line-label">金额</text>
+									<text class="line-value amount">{{ getTotalPrice(item) }}</text>
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+
+			<!-- 备注 -->
+			<view class="section" v-if="remark && remark.length > 0">
+				<view class="section-header">
+					<view class="section-indicator"></view>
+					<text class="section-title">备注</text>
+				</view>
+				<view class="info-card">
+					<text class="remark-text">{{ remark }}</text>
+				</view>
+			</view>
+
+			</scroll-view>
+	</view>
+</template>
+
+<script setup lang="uts">
+	import { ref, computed, onMounted } from 'vue'
+	import { getPurchase } from '../../api/purchase/index'
+
+	const purchaseId = ref<string>('')
+	
+	const purchaseCode = ref<string>('')
+	const vendorName = ref<string>('')
+	const contractNumber = ref<string>('')
+	const totalAmount = ref<string>('')
+	const status = ref<string>('')
+	const remark = ref<string>('')
+	const lineList = ref<any[]>([])
+
+	const title = computed(() => '采购订单详情')
+
+	const statusText = computed(() => {
+		switch (status.value) {
+			case 'PREPARE': return '草稿'
+			case 'CONFIRMED': return '已确认'
+			case 'FINISHED': return '已完成'
+			case 'CANCEL': return '已取消'
+			default: return status.value
+		}
+	})
+
+	const formatAmount = (val: any): string => {
+		if (val == null) return '0.00'
+		const num = Number(val)
+		if (isNaN(num)) return '0.00'
+		return num.toFixed(2)
+	}
+
+	const getPrice = (item: any | null): string => {
+		if (item == null) return '0.00'
+		const jsonItem = item as UTSJSONObject
+		return formatAmount(jsonItem['price'])
+	}
+
+	const getTotalPrice = (item: any | null): string => {
+		if (item == null) return '0.00'
+		const jsonItem = item as UTSJSONObject
+		return formatAmount(jsonItem['totalPrice'])
+	}
+
+	const getItemCode = (item: any | null): string => {
+		if (item == null) return ''
+		const jsonItem = item as UTSJSONObject
+		const val = jsonItem['itemCode']
+		return val != null ? val.toString() : ''
+	}
+
+	const getItemName = (item: any | null): string => {
+		if (item == null) return ''
+		const jsonItem = item as UTSJSONObject
+		const val = jsonItem['itemName']
+		let name = val != null ? val.toString() : ''
+		const idx = name.lastIndexOf('(')
+		if (idx > 0) {
+			name = name.substring(0, idx)
+		}
+		return name
+	}
+
+	const getLineId = (item: any, index: number): string => {
+		return `line-${index}`
+	}
+
+	const loadDetail = (): void => {
+		if (purchaseId.value.length === 0) return
+		getPurchase(purchaseId.value).then((response: any) => {
+			const res = response as UTSJSONObject
+			const data = res['data'] as UTSJSONObject
+			
+			purchaseCode.value = data['purchaseCode'] != null ? data['purchaseCode'].toString() : ''
+			vendorName.value = data['vendorName'] != null ? data['vendorName'].toString() : ''
+			contractNumber.value = data['contractNumber'] != null ? data['contractNumber'].toString() : ''
+			totalAmount.value = formatAmount(data['totalAmount'])
+			status.value = data['status'] != null ? data['status'].toString() : ''
+			remark.value = data['remark'] != null ? data['remark'].toString() : ''
+			const lines = data['wmItemPurchaseLineList'] as any[]
+			if (lines && lines.length > 0) {
+				lineList.value = lines
+			}
+		}).catch((e) => {
+			const error = e as UTSError
+			uni.showToast({ title: error?.message.toString() || '加载失败', icon: 'none' })
+		})
+	}
+
+	onMounted(() => {
+		const pages = getCurrentPages()
+		const currentPage = pages[pages.length - 1]
+		const options = currentPage.options
+		
+		if (options != null && options.id != null) {
+			purchaseId.value = options.id.toString()
+			loadDetail()
+		}
+	})
+</script>
+
+<style lang="scss">
+	.page-container {
+		flex: 1;
+		background-color: #e8f0f9;
+	}
+
+	.page-content {
+		flex: 1;
+		padding: 20rpx;
+		padding-bottom: 20rpx;
+	}
+
+	.section {
+		margin-bottom: 20rpx;
+		background: #ffffff;
+		border-radius: 16rpx;
+		padding: 20rpx;
+	}
+
+	.section-header {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		margin-bottom: 20rpx;
+	}
+
+	.section-indicator {
+		width: 6rpx;
+		height: 32rpx;
+		background-color: #007aff;
+		border-radius: 3rpx;
+		margin-right: 12rpx;
+	}
+
+	.section-title {
+		font-size: 32rpx;
+		font-weight: bold;
+		color: #333333;
+	}
+
+	.section-count {
+		margin-left: auto;
+		font-size: 24rpx;
+		color: #999999;
+	}
+
+	.info-card {
+		background-color: #f8f9fa;
+		border-radius: 12rpx;
+		padding: 20rpx;
+	}
+
+	.info-row {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		padding: 16rpx 0;
+		border-bottom: 1rpx solid #e9ecef;
+
+		&:last-child {
+			border-bottom: none;
+		}
+	}
+
+	.info-label {
+		font-size: 28rpx;
+		color: #666666;
+		width: 180rpx;
+		flex-shrink: 0;
+	}
+
+	.info-value {
+		font-size: 28rpx;
+		color: #333333;
+		flex: 1;
+
+		&.warning {
+			color: #faad14;
+		}
+
+		&.primary {
+			color: #007aff;
+			font-weight: bold;
+		}
+	}
+
+	.status-badge {
+		font-size: 24rpx;
+		padding: 6rpx 16rpx;
+		border-radius: 6rpx;
+
+		&.status-PREPARE {
+			background-color: #f0f0f0;
+			color: #666666;
+		}
+
+		&.status-CONFIRMED {
+			background-color: #e6f7ff;
+			color: #1890ff;
+		}
+
+		&.status-FINISHED {
+			background-color: #f6ffed;
+			color: #52c41a;
+		}
+
+		&.status-CANCEL {
+			background-color: #fff1f0;
+			color: #ff4d4f;
+		}
+	}
+
+	.line-list {
+		display: flex;
+		flex-direction: column;
+	}
+
+	.line-card {
+		background-color: #ffffff;
+		border-radius: 12rpx;
+		padding: 16rpx;
+		margin-bottom: 12rpx;
+	}
+
+	.line-top {
+		flex-direction: row;
+		align-items: center;
+		margin-bottom: 10rpx;
+	}
+
+	.line-index {
+		font-size: 40rpx;
+		font-weight: 700;
+		color: #007aff;
+		margin-right: 20rpx;
+		width: 60rpx;
+		text-align: center;
+	}
+
+	.line-right {
+		flex-direction: column;
+		flex: 1;
+	}
+
+	.item-name {
+		font-size: 30rpx;
+		font-weight: 600;
+		color: #1a1a1a;
+	}
+
+	.item-code-tag {
+		font-size: 20rpx;
+		color: #007aff;
+		margin-top: 4rpx;
+	}
+
+	.line-body {
+		display: flex;
+		flex-direction: column;
+		gap: 8rpx;
+	}
+
+	.line-row {
+		display: flex;
+		flex-direction: row;
+		gap: 12rpx;
+	}
+
+	.line-cell {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		flex: 1;
+		padding: 8rpx 12rpx;
+		background-color: #f8f9fa;
+		border-radius: 8rpx;
+	}
+
+	.line-label {
+		font-size: 22rpx;
+		color: #999999;
+		margin-right: 4rpx;
+	}
+
+	.line-value {
+		font-size: 24rpx;
+		color: #333333;
+
+		&.qty {
+			color: #007aff;
+		}
+
+		&.amount {
+			color: #faad14;
+		}
+	}
+
+	.remark-text {
+		font-size: 28rpx;
+		color: #333333;
+		line-height: 1.6;
+	}
+</style>

+ 502 - 6
pages/purchase/index.uvue

@@ -1,13 +1,509 @@
 <template>
-	<view>
-		
+	<uni-navbar-lite @rightClick="handleRight" :show-right="showRight" title="采购订单"></uni-navbar-lite>
+	<view class="list-page">
+		<view class="search-block">
+			<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" type="text" placeholder="请输入供应商名称" v-model="keyword" @input="handleSearch" />
+					<view v-if="keyword.length > 0" class="clear-btn" @tap="clearKeyword">
+						<text class="clear-btn-text">×</text>
+					</view>
+					<view class="search-btn" @tap="handleSearch">
+						<text class="search-btn-text">搜索</text>
+					</view>
+				</view>
+			</view>
+			<scroll-view class="status-tabs" scroll-x="true">
+				<view class="status-tab" :class="{ 'active': currentStatus === '' }" @tap="handleStatusChange('')">
+					<text class="status-tab-text" :class="{ 'active-text': currentStatus === '' }">全部</text>
+				</view>
+				<view class="status-tab" :class="{ 'active': currentStatus === 'PREPARE' }" @tap="handleStatusChange('PREPARE')">
+					<text class="status-tab-text" :class="{ 'active-text': currentStatus === 'PREPARE' }">草稿</text>
+				</view>
+				<view class="status-tab" :class="{ 'active': currentStatus === 'CONFIRMED' }" @tap="handleStatusChange('CONFIRMED')">
+					<text class="status-tab-text" :class="{ 'active-text': currentStatus === 'CONFIRMED' }">已确认</text>
+				</view>
+				<view class="status-tab" :class="{ 'active': currentStatus === 'FINISHED' }" @tap="handleStatusChange('FINISHED')">
+					<text class="status-tab-text" :class="{ 'active-text': currentStatus === 'FINISHED' }">已完成</text>
+				</view>
+				<view class="status-tab" :class="{ 'active': currentStatus === 'CANCEL' }" @tap="handleStatusChange('CANCEL')">
+					<text class="status-tab-text" :class="{ 'active-text': currentStatus === 'CANCEL' }">已取消</text>
+				</view>
+			</scroll-view>
+		</view>
+
+		<common-list
+			:dataList="dataList"
+			:loading="loading"
+			:refreshing="refreshing"
+			:hasMore="hasMore"
+			@refresh="handleRefresh"
+			@loadMore="loadMore"
+		>
+			<template #default="{ item, index }">
+				<view class="list-item" @tap="handleItemClick(item, index)">
+					<view class="item-container">
+						<view class="item-header">
+							<text class="item-title">{{ getPurchaseCode(item) }}</text>
+							<text class="item-status" :class="'status-' + getStatus(item)">{{ getStatusText(item) }}</text>
+						</view>
+						<view class="item-info">
+						<view class="info-row">
+							<view class="info-item">
+								<text class="info-label">供应商</text>
+								<text class="info-value">{{ getVendorName(item) }}</text>
+							</view>
+						</view>
+						<view class="info-row">
+							<view class="info-item">
+								<text class="info-label">创建人</text>
+								<text class="info-value">{{ getNickName(item) }}</text>
+							</view>
+							<view class="info-item">
+								<text class="info-label">创建时间</text>
+								<text class="info-value">{{ getCreateTime(item) }}</text>
+							</view>
+						</view>
+						<view class="info-row">
+							<view class="info-item">
+								<text class="info-label">金额</text>
+								<text class="info-value warning">{{ getTotalAmount(item) }}</text>
+							</view>
+							<view class="info-item">
+								<text class="info-label">合同</text>
+								<text class="info-value">{{ getContractNumber(item) || '-' }}</text>
+							</view>
+						</view>
+						</view>
+						<view class="item-footer">
+							<text class="item-name">{{ getPurchaseName(item) }}</text>
+							<text class="arrow">›</text>
+						</view>
+					</view>
+				</view>
+			</template>
+		</common-list>
 	</view>
 </template>
 
-<script setup>
-	
+<script setup lang="uts">
+	import { ref, onMounted } from 'vue'
+	import { onShow } from '@dcloudio/uni-app'
+	import { listPurchase } from '../../api/purchase/index'
+
+	const dataList = ref<any[]>([])
+	const keyword = ref<string>("")
+	let searchTimer: number | null = null
+	const currentStatus = ref<string>("")
+	const page = ref<number>(1)
+	const pageSize: number = 20
+	const hasMore = ref<boolean>(true)
+	const loading = ref<boolean>(false)
+	const refreshing = ref<boolean>(false)
+	const showRight = ref<boolean>(false)
+
+	const getPurchaseCode = (item: any | null): string => {
+		if (item == null) return ''
+		const jsonItem = item as UTSJSONObject
+		const val = jsonItem['purchaseCode']
+		return val != null ? val.toString() : ''
+	}
+
+	const getPurchaseName = (item: any | null): string => {
+		if (item == null) return ''
+		const jsonItem = item as UTSJSONObject
+		const val = jsonItem['purchaseName']
+		return val != null ? val.toString() : ''
+	}
+
+	const getStatus = (item: any | null): string => {
+		if (item == null) return ''
+		const jsonItem = item as UTSJSONObject
+		const val = jsonItem['status']
+		return val != null ? val.toString() : ''
+	}
+
+	const getStatusText = (item: any | null): string => {
+		if (item == null) return ''
+		const jsonItem = item as UTSJSONObject
+		const val = jsonItem['status']
+		const status = val != null ? val.toString() : ''
+		switch (status) {
+			case 'PREPARE': return '草稿'
+			case 'CONFIRMED': return '已确认'
+			case 'FINISHED': return '已完成'
+			case 'CANCEL': return '已取消'
+			default: return status
+		}
+	}
+
+	const getVendorName = (item: any | null): string => {
+		if (item == null) return ''
+		const jsonItem = item as UTSJSONObject
+		const val = jsonItem['vendorName']
+		return val != null ? val.toString() : '-'
+	}
+
+	const getTotalAmount = (item: any | null): string => {
+		if (item == null) return '0.00'
+		const jsonItem = item as UTSJSONObject
+		const val = jsonItem['totalAmount']
+		if (val == null) return '0.00'
+		const num = Number(val)
+		if (isNaN(num)) return '0.00'
+		return num.toFixed(2)
+	}
+
+	const getNickName = (item: any | null): string => {
+		if (item == null) return ''
+		const jsonItem = item as UTSJSONObject
+		const val = jsonItem['nickName']
+		return val != null ? val.toString() : '-'
+	}
+
+	const getCreateTime = (item: any | null): string => {
+		if (item == null) return ''
+		const jsonItem = item as UTSJSONObject
+		const val = jsonItem['createTime']
+		if (val == null) return '-'
+		const dateStr = val.toString()
+		if (dateStr.length >= 16) {
+			return dateStr.substring(0, 16)
+		}
+		return dateStr
+	}
+
+	const getContractNumber = (item: any | null): string => {
+		if (item == null) return ''
+		const jsonItem = item as UTSJSONObject
+		const val = jsonItem['contractNumber']
+		return val != null ? val.toString() : ''
+	}
+
+	const getFromSys = (item: any | null): string => {
+		if (item == null) return ''
+		const jsonItem = item as UTSJSONObject
+		const val = jsonItem['fromSys']
+		const sys = val != null ? val.toString() : ''
+		switch (sys) {
+			case 'oa': return 'OA'
+			case 'self': return '本系统'
+			default: return sys
+		}
+	}
+
+	const loadData = async (isRefresh: boolean): Promise<void> => {
+		if (loading.value) return
+		try {
+			loading.value = true
+			if (isRefresh) {
+				page.value = 1
+			}
+			const searchKeyword = keyword.value != null ? keyword.value : ''
+			const statusParam = currentStatus.value != null ? currentStatus.value : ''
+			const query = new UTSJSONObject()
+			query['pageNum'] = page.value
+			query['pageSize'] = pageSize
+			if (searchKeyword.length > 0) {
+				query['vendorName'] = searchKeyword
+			}
+			if (statusParam.length > 0) {
+				query['status'] = statusParam
+			}
+			const result = await listPurchase(query)
+			const resultObj = result as UTSJSONObject
+			const rows = resultObj['rows']
+			const total = resultObj['total'] as number
+			if (rows != null) {
+				const newData = rows as any[]
+				if (isRefresh) {
+					dataList.value = newData
+				} else {
+					dataList.value = [...dataList.value, ...newData]
+				}
+				hasMore.value = dataList.value.length < total
+			} else {
+				if (isRefresh) {
+					dataList.value = []
+				}
+				hasMore.value = false
+			}
+		} catch (e) {
+			console.error('加载失败:', e)
+		} finally {
+			loading.value = false
+			refreshing.value = false
+		}
+	}
+
+	const handleRefresh = (): void => {
+		refreshing.value = true
+		loadData(true)
+	}
+
+	const loadMore = (): void => {
+		if (!hasMore.value || loading.value) return
+		page.value++
+		loadData(false)
+	}
+
+	const handleSearch = (): void => {
+		const timer = searchTimer
+		if (timer != null) {
+			clearTimeout(timer)
+		}
+		searchTimer = setTimeout(() => {
+			loadData(true)
+		}, 300)
+	}
+
+	const clearKeyword = (): void => {
+		keyword.value = ''
+		loadData(true)
+	}
+
+	const handleStatusChange = (status: string): void => {
+		currentStatus.value = status
+		loadData(true)
+	}
+
+	const handleRight = (): void => {
+		uni.navigateTo({
+			url: `/pages/purchase/createByApply`
+		})
+	}
+
+	const handleItemClick = (item: any | null, index: number): void => {
+		if (item == null) return
+		const jsonItem = item as UTSJSONObject
+		const purchaseId = jsonItem['purchaseId']
+		if (purchaseId == null) return
+		const status = getStatus(item)
+		uni.navigateTo({
+			url: `/pages/purchase/detail?id=${purchaseId}`
+		})
+	}
+
+	onMounted(() => {
+		loadData(true)
+	})
+
+	onShow(() => {
+		const needRefresh = uni.getStorageSync('needRefresh')
+		if (needRefresh === 'true') {
+			uni.removeStorageSync('needRefresh')
+			loadData(true)
+		}
+	})
 </script>
 
-<style>
+<style lang="scss">
+	.list-page {
+		flex: 1;
+		background-color: #e8f0f9;
+	}
+
+	.search-block {
+		background-color: #ffffff;
+	}
+
+	.search-bar {
+		padding: 20rpx 30rpx;
+	}
+
+	.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;
+		}
+
+		.search-btn {
+			padding: 10rpx 20rpx;
+			background-color: #007aff;
+			border-radius: 8rpx;
+			margin-left: 10rpx;
+		}
+
+		.search-btn-text {
+			color: #ffffff;
+			font-size: 24rpx;
+		}
+
+		.clear-btn {
+			width: 36rpx;
+			height: 36rpx;
+			border-radius: 18rpx;
+			background-color: #cccccc;
+			align-items: center;
+			justify-content: center;
+			margin-left: 10rpx;
+		}
+
+		.clear-btn-text {
+			color: #ffffff;
+			font-size: 24rpx;
+			font-weight: bold;
+		}
+	}
+
+	.status-tabs {
+		display: flex;
+		flex-direction: row;
+		padding: 0rpx 30rpx 20rpx;
+		background-color: #ffffff;
+		white-space: nowrap;
+		width: 100%;
+	}
+
+	.status-tab {
+		display: inline-flex;
+		flex-direction: row;
+		align-items: center;
+		padding: 16rpx 24rpx;
+		text-align: center;
+		position: relative;
+		margin-right: 16rpx;
+		border-radius: 8rpx;
+		background-color: #f5f5f5;
+		justify-content: center;
+		align-items: center;
+
+		&.active {
+			background-color: #007aff;
+		}
+
+		.status-tab-text {
+			font-size: 26rpx;
+			color: #666666;
+			text-align: center;
+
+			&.active-text {
+				color: #ffffff;
+				font-weight: bold;
+			}
+		}
+	}
+
+	.list-item {
+		margin: 10rpx 20rpx;
+		background-color: #ffffff;
+		border-radius: 16rpx;
+	}
+
+	.item-container {
+		padding: 30rpx;
+	}
+
+	.item-header {
+		flex-direction: row;
+		align-items: center;
+		margin-bottom: 20rpx;
+
+		.item-title {
+			flex: 1;
+			font-size: 32rpx;
+			color: #333333;
+			font-weight: bold;
+		}
+
+		.item-status {
+			font-size: 26rpx;
+			padding: 6rpx 16rpx;
+			border-radius: 6rpx;
+
+			&.status-PREPARE {
+				background-color: #f0f0f0;
+				color: #666666;
+			}
+			&.status-CONFIRMED {
+				background-color: #e6f7ff;
+				color: #1890ff;
+			}
+			&.status-FINISHED {
+				background-color: #f6ffed;
+				color: #52c41a;
+			}
+			&.status-CANCEL {
+				background-color: #fff1f0;
+				color: #ff4d4f;
+			}
+		}
+	}
+
+	.item-info {
+		padding: 20rpx;
+		background-color: #f8f9fa;
+		border-radius: 8rpx;
+
+		.info-row {
+			flex-direction: row;
+			justify-content: space-between;
+			margin-bottom: 16rpx;
+
+			&:last-child {
+				margin-bottom: 0;
+			}
+
+			.info-item {
+				flex-direction: row;
+				align-items: center;
+				flex: 1;
+
+				&:last-child {
+					flex: 1;
+					justify-content: flex-end;
+				}
+
+				.info-label {
+					font-size: 26rpx;
+					color: #666666;
+					margin-right: 8rpx;
+					white-space: nowrap;
+				}
+
+				.info-value {
+					font-size: 26rpx;
+					color: #333333;
+					flex: 1;
+
+					&.warning {
+						color: #faad14;
+					}
+				}
+			}
+		}
+	}
+
+	.item-footer {
+		flex-direction: row;
+		justify-content: space-between;
+		align-items: center;
+		margin-top: 20rpx;
+
+		.item-name {
+			font-size: 26rpx;
+			color: #999999;
+			flex: 1;
+		}
 
-</style>
+		.arrow {
+			font-size: 36rpx;
+			color: #cccccc;
+		}
+	}
+</style>