| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- <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>
|