322 lines
7.2 KiB
Plaintext
322 lines
7.2 KiB
Plaintext
<template>
|
|
<cl-page>
|
|
<cl-topbar title="种子成长" />
|
|
|
|
<scroll-view scroll-y class="content" v-if="userSeed">
|
|
<view class="seed-header">
|
|
<image class="seed-image" :src="userSeed.seedImage != null ? userSeed.seedImage : '/static/images/seed.png'" mode="aspectFill" />
|
|
<view class="seed-info">
|
|
<text class="seed-name">{{ userSeed.seedName }}</text>
|
|
<text class="seed-status" :class="getStatusClass(userSeed.status)">{{ getStatusText(userSeed.status) }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="progress-section">
|
|
<text class="section-title">成长进度</text>
|
|
<view class="progress-container">
|
|
<view class="progress-bar">
|
|
<view class="progress-fill" :style="{ width: userSeed.progress + '%' }"></view>
|
|
</view>
|
|
<text class="progress-text">{{ userSeed.progress }}%</text>
|
|
</view>
|
|
<view class="stage-list">
|
|
<view v-for="i in 4" :key="i" class="stage-item" :class="{ active: userSeed.currentStage >= i, current: userSeed.currentStage === i }">
|
|
<view class="stage-dot"></view>
|
|
<text class="stage-name">{{ getStageLabel(i) }}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="health-section">
|
|
<text class="section-title">健康状态</text>
|
|
<view class="health-bar">
|
|
<view class="health-fill" :style="{ width: userSeed.health + '%', background: getHealthColor(userSeed.health) }"></view>
|
|
</view>
|
|
<text class="health-text">健康值: {{ userSeed.health }}%</text>
|
|
</view>
|
|
|
|
<view class="action-section">
|
|
<text class="section-title">养护操作</text>
|
|
<view class="action-grid">
|
|
<view class="action-item" @click="doAction('water')">
|
|
<cl-icon name="water" :size="48" color="#1890ff" />
|
|
<text class="action-name">浇水</text>
|
|
</view>
|
|
<view class="action-item" @click="doAction('fertilize')">
|
|
<cl-icon name="flask" :size="48" color="#52c41a" />
|
|
<text class="action-name">施肥</text>
|
|
</view>
|
|
<view class="action-item" @click="doAction('sunshine')">
|
|
<cl-icon name="sun" :size="48" color="#faad14" />
|
|
<text class="action-name">晒太阳</text>
|
|
</view>
|
|
<view class="action-item" @click="doAction('music')">
|
|
<cl-icon name="music" :size="48" color="#722ed1" />
|
|
<text class="action-name">听音乐</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view v-if="userSeed.status === 2" class="harvest-section">
|
|
<cl-button type="primary" size="large" round @click="requestDelivery">申请发货</cl-button>
|
|
</view>
|
|
</scroll-view>
|
|
</cl-page>
|
|
</template>
|
|
|
|
<script setup lang="uts">
|
|
import { ref, onMounted } from 'vue';
|
|
import { router, useCool } from '@/cool';
|
|
|
|
const { service } = useCool();
|
|
|
|
const userSeed = ref<any>(null);
|
|
|
|
function getStatusClass(status: number) {
|
|
return { growing: status === 1, mature: status === 2, shipped: status === 3 };
|
|
}
|
|
|
|
function getStatusText(status: number): string {
|
|
const texts: Record<number, string> = { 1: '生长中', 2: '已成熟', 3: '已发货' };
|
|
const text = texts[status];
|
|
return text != null ? text : '未知';
|
|
}
|
|
|
|
function getStageLabel(stage: number): string {
|
|
const labels: Record<number, string> = { 1: '播种', 2: '发芽', 3: '成长', 4: '成熟' };
|
|
const label = labels[stage];
|
|
return label != null ? label : '';
|
|
}
|
|
|
|
function getHealthColor(health: number) {
|
|
if (health >= 80) return '#52c41a';
|
|
if (health >= 50) return '#faad14';
|
|
return '#ff4d4f';
|
|
}
|
|
|
|
async function loadUserSeed() {
|
|
const pages = getCurrentPages();
|
|
const currentPage = pages[pages.length - 1];
|
|
const userSeedId = Number(currentPage.options != null && currentPage.options!['id'] != null ? currentPage.options!['id'] : 0);
|
|
|
|
if (userSeedId != 0) {
|
|
try {
|
|
const res = await service.nongchuang.seed.growth(userSeedId);
|
|
userSeed.value = res;
|
|
} catch (e) {
|
|
userSeed.value = {
|
|
id: userSeedId,
|
|
seedName: '有机番茄',
|
|
seedImage: '/static/images/tomato.png',
|
|
status: 1,
|
|
progress: 65,
|
|
currentStage: 3,
|
|
health: 95
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
async function doAction(action: string) {
|
|
const actionNames: Record<string, string> = {
|
|
water: '浇水',
|
|
fertilize: '施肥',
|
|
sunshine: '晒太阳',
|
|
music: '听音乐'
|
|
};
|
|
|
|
uni.showToast({ title: `${actionNames[action]}成功`, icon: 'success' });
|
|
|
|
if (userSeed.value) {
|
|
userSeed.value.progress = Math.min(100, userSeed.value.progress + 5);
|
|
if (userSeed.value.progress >= 100) {
|
|
userSeed.value.status = 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
function requestDelivery() {
|
|
uni.showModal({
|
|
title: '申请发货',
|
|
content: '您的种子已成熟,确认申请发货吗?',
|
|
success: (res) => {
|
|
if (res.confirm) {
|
|
uni.showToast({ title: '已申请发货', icon: 'success' });
|
|
if (userSeed.value) {
|
|
userSeed.value.status = 3;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
onMounted(() => {
|
|
loadUserSeed();
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.content {
|
|
flex: 1;
|
|
padding: 20rpx;
|
|
}
|
|
|
|
.seed-header {
|
|
display: flex;
|
|
flex-direction: row;
|
|
background: linear-gradient(135deg, #52c41a, #95de64);
|
|
border-radius: 16rpx;
|
|
padding: 30rpx;
|
|
|
|
.seed-image {
|
|
width: 120rpx;
|
|
height: 120rpx;
|
|
border-radius: 60rpx;
|
|
border: 4rpx solid rgba(255, 255, 255, 0.5);
|
|
margin-right: 24rpx;
|
|
}
|
|
|
|
.seed-info {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
|
|
.seed-name {
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
color: #fff;
|
|
}
|
|
|
|
.seed-status {
|
|
margin-top: 12rpx;
|
|
padding: 6rpx 20rpx;
|
|
border-radius: 20rpx;
|
|
font-size: 24rpx;
|
|
background: rgba(255, 255, 255, 0.3);
|
|
color: #fff;
|
|
}
|
|
}
|
|
}
|
|
|
|
.progress-section, .health-section, .action-section {
|
|
margin-top: 20rpx;
|
|
background: #fff;
|
|
border-radius: 16rpx;
|
|
padding: 24rpx;
|
|
|
|
.section-title {
|
|
font-size: 28rpx;
|
|
font-weight: bold;
|
|
color: #333;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
}
|
|
|
|
.progress-container {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
|
|
.progress-bar {
|
|
flex: 1;
|
|
height: 16rpx;
|
|
background: #f0f0f0;
|
|
border-radius: 8rpx;
|
|
overflow: hidden;
|
|
margin-right: 16rpx;
|
|
|
|
.progress-fill {
|
|
height: 100%;
|
|
background: linear-gradient(90deg, #52c41a, #95de64);
|
|
border-radius: 8rpx;
|
|
}
|
|
}
|
|
|
|
.progress-text {
|
|
font-size: 28rpx;
|
|
font-weight: bold;
|
|
color: #52c41a;
|
|
}
|
|
}
|
|
|
|
.stage-list {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
margin-top: 24rpx;
|
|
|
|
.stage-item {
|
|
text-align: center;
|
|
|
|
.stage-dot {
|
|
width: 24rpx;
|
|
height: 24rpx;
|
|
border-radius: 12rpx;
|
|
background: #ddd;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.stage-name {
|
|
font-size: 22rpx;
|
|
color: #999;
|
|
margin-top: 8rpx;
|
|
}
|
|
|
|
&.active .stage-dot {
|
|
background: #52c41a;
|
|
}
|
|
|
|
&.current .stage-dot {
|
|
box-shadow: 0 0 0 4rpx rgba(82, 196, 26, 0.3);
|
|
}
|
|
}
|
|
}
|
|
|
|
.health-bar {
|
|
height: 16rpx;
|
|
background: #f0f0f0;
|
|
border-radius: 8rpx;
|
|
overflow: hidden;
|
|
|
|
.health-fill {
|
|
height: 100%;
|
|
border-radius: 8rpx;
|
|
}
|
|
}
|
|
|
|
.health-text {
|
|
font-size: 24rpx;
|
|
color: #666;
|
|
margin-top: 10rpx;
|
|
}
|
|
|
|
.action-grid {
|
|
display: flex;
|
|
flex-direction: row;
|
|
flex-wrap: wrap;
|
|
justify-content: space-between;
|
|
|
|
.action-item {
|
|
width: 23%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
padding: 20rpx;
|
|
background: #f9f9f9;
|
|
border-radius: 12rpx;
|
|
margin-bottom: 20rpx;
|
|
|
|
.action-name {
|
|
font-size: 24rpx;
|
|
color: #666;
|
|
margin-top: 10rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.harvest-section {
|
|
margin-top: 40rpx;
|
|
padding: 0 20rpx;
|
|
}
|
|
</style>
|