|
|
@@ -1,166 +0,0 @@
|
|
|
-<template>
|
|
|
- <view class="container">
|
|
|
- <!-- 任务模板信息 -->
|
|
|
- <view class="package-header">
|
|
|
- <image class="cover" :src="getImageUrl(pkg.coverImage) || '/static/default-cover.png'" mode="aspectFill" />
|
|
|
- <view class="header-content">
|
|
|
- <text class="name">{{ pkg.name }}</text>
|
|
|
- <view class="meta">
|
|
|
- <text>{{ pkg.cycleDays }}天</text>
|
|
|
- <text>{{ pkg.category }}</text>
|
|
|
- </view>
|
|
|
- <text class="price">{{ formatPriceWithSymbol(pkg.price) }}</text>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
-
|
|
|
- <!-- 描述 -->
|
|
|
- <view class="section">
|
|
|
- <text class="section-title">任务模板介绍</text>
|
|
|
- <text class="description">{{ pkg.description || '暂无介绍' }}</text>
|
|
|
- </view>
|
|
|
-
|
|
|
- <!-- 任务项选择 -->
|
|
|
- <view class="section">
|
|
|
- <text class="section-title">选择任务项</text>
|
|
|
- <view class="item-list">
|
|
|
- <view
|
|
|
- class="item-card"
|
|
|
- v-for="item in items"
|
|
|
- :key="item.id"
|
|
|
- :class="{ disabled: item.isRequired }"
|
|
|
- @click="toggleItem(item)"
|
|
|
- >
|
|
|
- <view class="item-check">
|
|
|
- <checkbox :checked="selectedItems.includes(item.id)" :disabled="item.isRequired" />
|
|
|
- </view>
|
|
|
- <view class="item-content">
|
|
|
- <text class="item-name">{{ item.taskName }}</text>
|
|
|
- <text class="item-desc">{{ item.description }}</text>
|
|
|
- <view class="item-meta">
|
|
|
- <text>积分: {{ item.points }}</text>
|
|
|
- <text>频率: {{ item.frequency }}</text>
|
|
|
- <text v-if="item.isRequired" class="required-tag">必选</text>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
-
|
|
|
- <!-- 底部操作 -->
|
|
|
- <view class="footer">
|
|
|
- <button class="btn-apply" @click="applyPackage">立即应用</button>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script>
|
|
|
-import { getPackage, getPackageItems, purchasePackage } from '@/utils/api.js'
|
|
|
-import config from '@/config.js'
|
|
|
-
|
|
|
-export default {
|
|
|
- data() {
|
|
|
- return {
|
|
|
- pkgId: null,
|
|
|
- pkg: {},
|
|
|
- items: [],
|
|
|
- selectedItems: []
|
|
|
- }
|
|
|
- },
|
|
|
- onLoad(options) {
|
|
|
- this.pkgId = options.id
|
|
|
- this.loadPackage()
|
|
|
- this.loadItems()
|
|
|
- },
|
|
|
- methods: {
|
|
|
- async loadPackage() {
|
|
|
- try {
|
|
|
- const res = await getPackage(this.pkgId)
|
|
|
- this.pkg = res.data || {}
|
|
|
- } catch (e) {
|
|
|
- console.error(e)
|
|
|
- }
|
|
|
- },
|
|
|
- async loadItems() {
|
|
|
- try {
|
|
|
- const res = await getPackageItems(this.pkgId)
|
|
|
- this.items = res.data || []
|
|
|
- // 自动选中必选项
|
|
|
- this.items.forEach(item => {
|
|
|
- if (item.isRequired) {
|
|
|
- this.selectedItems.push(item.id)
|
|
|
- }
|
|
|
- })
|
|
|
- } catch (e) {
|
|
|
- console.error(e)
|
|
|
- }
|
|
|
- },
|
|
|
- toggleItem(item) {
|
|
|
- if (item.isRequired) return
|
|
|
- const idx = this.selectedItems.indexOf(item.id)
|
|
|
- if (idx > -1) {
|
|
|
- this.selectedItems.splice(idx, 1)
|
|
|
- } else {
|
|
|
- this.selectedItems.push(item.id)
|
|
|
- }
|
|
|
- },
|
|
|
- async applyPackage() {
|
|
|
- // 获取孩子列表,选择一个孩子
|
|
|
- uni.showActionSheet({
|
|
|
- itemList: ['选择孩子'],
|
|
|
- success: async () => {
|
|
|
- // 这里应该先获取孩子列表,让用户选择
|
|
|
- // 简化处理,直接使用当前家庭的孩子
|
|
|
- try {
|
|
|
- const res = await purchasePackage(this.pkgId, {
|
|
|
- selectedItemIds: this.selectedItems,
|
|
|
- memberId: 1 // TODO: 实际应该让用户选择
|
|
|
- })
|
|
|
- uni.showToast({ title: '应用成功' })
|
|
|
- setTimeout(() => {
|
|
|
- var pages = getCurrentPages()
|
|
|
- if (pages.length > 1) {
|
|
|
- uni.navigateBack()
|
|
|
- } else {
|
|
|
- uni.switchTab({ url: '/pages/index-home/index' })
|
|
|
- }
|
|
|
- }, 1500)
|
|
|
- } catch (e) {
|
|
|
- uni.showToast({ title: '应用失败', icon: 'none' })
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
- },
|
|
|
- getImageUrl: function(path) {
|
|
|
- return config.API_BASE_URL + path
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-</script>
|
|
|
-
|
|
|
-<style scoped>
|
|
|
-.container { min-height: 100vh; background: #f5f5f5; padding-bottom: 120rpx; }
|
|
|
-
|
|
|
-.package-header { position: relative; }
|
|
|
-.cover { width: 100%; height: 400rpx; }
|
|
|
-.header-content { position: absolute; bottom: 0; left: 0; right: 0; padding: 30rpx; background: linear-gradient(transparent, rgba(0,0,0,0.7)); color: #fff; }
|
|
|
-.name { font-size: 36rpx; font-weight: bold; display: block; margin-bottom: 10rpx; }
|
|
|
-.meta { display: flex; gap: 20rpx; font-size: 24rpx; opacity: 0.8; margin-bottom: 10rpx; }
|
|
|
-.price { font-size: 40rpx; font-weight: bold; }
|
|
|
-
|
|
|
-.section { background: #fff; padding: 30rpx; margin-bottom: 10rpx; }
|
|
|
-.section-title { font-size: 30rpx; font-weight: bold; display: block; margin-bottom: 20rpx; }
|
|
|
-.description { font-size: 28rpx; color: #666; line-height: 1.6; }
|
|
|
-
|
|
|
-.item-list { display: flex; flex-direction: column; gap: 16rpx; }
|
|
|
-.item-card { display: flex; padding: 20rpx; background: #f9f9f9; border-radius: 12rpx; }
|
|
|
-.item-card.disabled { opacity: 0.7; }
|
|
|
-.item-check { margin-right: 16rpx; }
|
|
|
-.item-content { flex: 1; }
|
|
|
-.item-name { font-size: 28rpx; font-weight: bold; display: block; margin-bottom: 8rpx; }
|
|
|
-.item-desc { font-size: 24rpx; color: #999; display: block; margin-bottom: 8rpx; }
|
|
|
-.item-meta { display: flex; gap: 16rpx; font-size: 22rpx; color: #666; }
|
|
|
-.required-tag { color: #ff9800; }
|
|
|
-
|
|
|
-.footer { position: fixed; bottom: 0; left: 0; right: 0; background: #fff; padding: 20rpx 30rpx; box-shadow: 0 -2rpx 10rpx rgba(0,0,0,0.05); }
|
|
|
-.btn-apply { background: #4CAF50; color: #fff; border-radius: 40rpx; }
|
|
|
-</style>
|