|
|
@@ -0,0 +1,630 @@
|
|
|
+<template>
|
|
|
+ <view class="container">
|
|
|
+ <!-- 编辑模式 -->
|
|
|
+ <view class="edit-section" v-if="!readonly">
|
|
|
+ <view class="form-card">
|
|
|
+ <view class="form-title">活动信息</view>
|
|
|
+
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="form-label">活动标题 *</text>
|
|
|
+ <input class="form-input" v-model="form.title" placeholder="请输入活动标题" :disabled="readonly" />
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="form-label">活动分类</text>
|
|
|
+ <picker class="form-picker" :value="categoryIdx" :range="categoryOptions" range-key="label"
|
|
|
+ @change="onCategoryChange">
|
|
|
+ <text class="picker-text">{{ form.category ? categoryLabel(form.category) : '请选择分类' }}</text>
|
|
|
+ </picker>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="form-label">活动日期时间 *</text>
|
|
|
+ <view class="form-date-picker" @click="showDatePicker">
|
|
|
+ <text class="picker-text">{{ form.activityDate ? formatDate(form.activityDate) : '请选择日期和时间' }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="form-label">活动地点</text>
|
|
|
+ <input class="form-input" v-model="form.location" placeholder="请输入活动地点" />
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="form-item-row">
|
|
|
+ <view class="form-item half">
|
|
|
+ <text class="form-label">最大人数</text>
|
|
|
+ <input class="form-input" type="number" v-model="form.maxParticipants" placeholder="20" />
|
|
|
+ </view>
|
|
|
+ <view class="form-item half">
|
|
|
+ <text class="form-label">价格(元)</text>
|
|
|
+ <input class="form-input" type="digit" v-model="priceYuan" placeholder="0表示免费" />
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="form-label">封面图片URL</text>
|
|
|
+ <input class="form-input" v-model="form.coverImage" placeholder="输入图片URL" />
|
|
|
+ <view class="cover-preview" v-if="form.coverImage">
|
|
|
+ <image class="preview-img" :src="form.coverImage" mode="aspectFill" @error="onImgError" />
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="form-label">活动描述</text>
|
|
|
+ <textarea class="form-textarea" v-model="form.description" placeholder="请输入活动详细介绍" />
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="form-actions">
|
|
|
+ <view class="btn-save" @click="handleSave">
|
|
|
+ <text>保存</text>
|
|
|
+ </view>
|
|
|
+ <view class="btn-publish" v-if="form.status === 'draft'" @click="handlePublish">
|
|
|
+ <text>保存并发布</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 只读模式(已发布/已取消/已完成) -->
|
|
|
+ <view class="detail-section" v-else>
|
|
|
+ <view class="detail-cover" v-if="form.coverImage">
|
|
|
+ <image class="cover-img" :src="form.coverImage" mode="aspectFill" />
|
|
|
+ </view>
|
|
|
+ <view class="detail-cover placeholder" v-else>
|
|
|
+ <text class="placeholder-icon">{{ categoryIcon(form.category) }}</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="detail-card">
|
|
|
+ <view class="detail-header">
|
|
|
+ <text class="detail-title">{{ form.title }}</text>
|
|
|
+ <text class="detail-status" :class="'status-' + form.status">{{ statusText(form.status) }}</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="detail-meta-row">
|
|
|
+ <view class="meta-item">
|
|
|
+ <text class="meta-icon">📅</text>
|
|
|
+ <text class="meta-text">{{ form.activityDate ? formatDate(form.activityDate) : '待定' }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="meta-item" v-if="form.location">
|
|
|
+ <text class="meta-icon">📍</text>
|
|
|
+ <text class="meta-text">{{ form.location }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="detail-stats">
|
|
|
+ <view class="stat-box">
|
|
|
+ <text class="stat-val">{{ form.currentParticipants || 0 }}</text>
|
|
|
+ <text class="stat-label">已报名</text>
|
|
|
+ </view>
|
|
|
+ <view class="stat-box">
|
|
|
+ <text class="stat-val">{{ form.maxParticipants || 20 }}</text>
|
|
|
+ <text class="stat-label">最大人数</text>
|
|
|
+ </view>
|
|
|
+ <view class="stat-box">
|
|
|
+ <text class="stat-val">{{ form.price > 0 ? (form.price / 100 + '元') : '免费' }}</text>
|
|
|
+ <text class="stat-label">价格</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="detail-desc" v-if="form.description">
|
|
|
+ <text class="section-title">活动介绍</text>
|
|
|
+ <text class="desc-text">{{ form.description }}</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="detail-actions" v-if="form.status === 'draft'">
|
|
|
+ <view class="btn-edit" @click="readonly = false">
|
|
|
+ <text>编辑</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="loading" v-if="loading"><text class="loading-text">加载中...</text></view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { getActivityDetail, createActivity, updateActivity, publishActivity } from '../../../utils/api.js'
|
|
|
+
|
|
|
+export default {
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ activityId: null,
|
|
|
+ isNew: false,
|
|
|
+ readonly: false,
|
|
|
+ loading: false,
|
|
|
+ form: {
|
|
|
+ title: '',
|
|
|
+ description: '',
|
|
|
+ coverImage: '',
|
|
|
+ category: '',
|
|
|
+ location: '',
|
|
|
+ activityDate: null,
|
|
|
+ maxParticipants: 20,
|
|
|
+ price: 0,
|
|
|
+ status: 'draft'
|
|
|
+ },
|
|
|
+ priceYuan: '0',
|
|
|
+ categoryIdx: 0,
|
|
|
+ categoryOptions: [
|
|
|
+ { key: 'outdoor', label: '⛵ 户外运动' },
|
|
|
+ { key: 'nature', label: '🌿 自然探索' },
|
|
|
+ { key: 'culture', label: '🎨 文化体验' },
|
|
|
+ { key: 'sports', label: '⚽ 体育竞技' },
|
|
|
+ { key: 'other', label: '🏠 其他' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onLoad(options) {
|
|
|
+ this.activityId = options.activityId ? parseInt(options.activityId) : null
|
|
|
+ if (!this.activityId || this.activityId === 0) {
|
|
|
+ this.isNew = true
|
|
|
+ this.readonly = false
|
|
|
+ uni.setNavigationBarTitle({ title: '创建活动' })
|
|
|
+ } else {
|
|
|
+ this.loadDetail()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ loadDetail() {
|
|
|
+ var self = this
|
|
|
+ self.loading = true
|
|
|
+ getActivityDetail(self.activityId).then(function(res) {
|
|
|
+ self.loading = false
|
|
|
+ if (res.code === 200 && res.data) {
|
|
|
+ self.form = res.data
|
|
|
+ self.priceYuan = self.form.price ? (self.form.price / 100).toString() : '0'
|
|
|
+ self.readonly = self.form.status !== 'draft'
|
|
|
+ uni.setNavigationBarTitle({ title: self.readonly ? '活动详情' : '编辑活动' })
|
|
|
+ }
|
|
|
+ }).catch(function() { self.loading = false })
|
|
|
+ },
|
|
|
+ onCategoryChange(e) {
|
|
|
+ this.categoryIdx = e.detail.value
|
|
|
+ this.form.category = this.categoryOptions[this.categoryIdx].key
|
|
|
+ },
|
|
|
+ showDatePicker() {
|
|
|
+ var self = this
|
|
|
+ uni.showDatePicker({
|
|
|
+ mode: 'date',
|
|
|
+ success: function(res) {
|
|
|
+ var date = res.value
|
|
|
+ uni.showTimePicker({
|
|
|
+ mode: 'time',
|
|
|
+ success: function(res2) {
|
|
|
+ var time = res2.value
|
|
|
+ var d = new Date(date)
|
|
|
+ var parts = time.split(':')
|
|
|
+ d.setHours(parseInt(parts[0]), parseInt(parts[1]))
|
|
|
+ self.form.activityDate = d
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ handleSave() {
|
|
|
+ if (!this.form.title) {
|
|
|
+ uni.showToast({ title: '请输入活动标题', icon: 'none' })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.save(false)
|
|
|
+ },
|
|
|
+ handlePublish() {
|
|
|
+ if (!this.form.title) {
|
|
|
+ uni.showToast({ title: '请输入活动标题', icon: 'none' })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.save(true)
|
|
|
+ },
|
|
|
+ save(publishAfterSave) {
|
|
|
+ var self = this
|
|
|
+ var payload = Object.assign({}, self.form)
|
|
|
+ if (self.priceYuan) {
|
|
|
+ payload.price = Math.round(parseFloat(self.priceYuan) * 100)
|
|
|
+ }
|
|
|
+
|
|
|
+ var done = function() {
|
|
|
+ if (publishAfterSave && self.form.status === 'draft') {
|
|
|
+ publishActivity(self.form.id || self.activityId).then(function(r) {
|
|
|
+ if (r.code === 200) {
|
|
|
+ uni.showToast({ title: '已发布', icon: 'success' })
|
|
|
+ setTimeout(function() {
|
|
|
+ uni.redirectTo({ url: '/pages/guide/activities/index' })
|
|
|
+ }, 1000)
|
|
|
+ } else {
|
|
|
+ uni.showToast({ title: '发布失败', icon: 'none' })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ uni.showToast({ title: '保存成功', icon: 'success' })
|
|
|
+ setTimeout(function() {
|
|
|
+ uni.navigateBack()
|
|
|
+ }, 1000)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (self.isNew || !self.form.id) {
|
|
|
+ createActivity(payload).then(function(res) {
|
|
|
+ if (res.code === 200) {
|
|
|
+ self.form.id = res.data
|
|
|
+ self.isNew = false
|
|
|
+ if (publishAfterSave) {
|
|
|
+ publishActivity(res.data).then(function(r) {
|
|
|
+ if (r.code === 200) {
|
|
|
+ uni.showToast({ title: '已发布', icon: 'success' })
|
|
|
+ setTimeout(function() {
|
|
|
+ uni.redirectTo({ url: '/pages/guide/activities/index' })
|
|
|
+ }, 1000)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ done()
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ uni.showToast({ title: res.message || '保存失败', icon: 'none' })
|
|
|
+ }
|
|
|
+ }).catch(function() {
|
|
|
+ uni.showToast({ title: '网络异常', icon: 'none' })
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ payload.id = self.form.id || self.activityId
|
|
|
+ updateActivity(payload).then(function(res) {
|
|
|
+ if (res.code === 200) {
|
|
|
+ if (publishAfterSave) {
|
|
|
+ publishActivity(payload.id).then(function(r) {
|
|
|
+ if (r.code === 200) {
|
|
|
+ uni.showToast({ title: '已发布', icon: 'success' })
|
|
|
+ setTimeout(function() {
|
|
|
+ uni.redirectTo({ url: '/pages/guide/activities/index' })
|
|
|
+ }, 1000)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ done()
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ uni.showToast({ title: res.message || '保存失败', icon: 'none' })
|
|
|
+ }
|
|
|
+ }).catch(function() {
|
|
|
+ uni.showToast({ title: '网络异常', icon: 'none' })
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onImgError() {
|
|
|
+ this.form.coverImage = ''
|
|
|
+ },
|
|
|
+ categoryLabel(key) {
|
|
|
+ var map = { outdoor: '户外运动', nature: '自然探索', culture: '文化体验', sports: '体育竞技', other: '其他' }
|
|
|
+ return map[key] || '其他'
|
|
|
+ },
|
|
|
+ categoryIcon(category) {
|
|
|
+ var map = { outdoor: '⛵', nature: '🌿', culture: '🎨', sports: '⚽', other: '🏠' }
|
|
|
+ return map[category] || '🏠'
|
|
|
+ },
|
|
|
+ statusText(status) {
|
|
|
+ var map = { draft: '草稿', published: '已发布', cancelled: '已取消', completed: '已完成' }
|
|
|
+ return map[status] || status || '草稿'
|
|
|
+ },
|
|
|
+ formatDate(dateStr) {
|
|
|
+ if (!dateStr) return ''
|
|
|
+ var d = new Date(dateStr)
|
|
|
+ var y = d.getFullYear()
|
|
|
+ var m = ('0' + (d.getMonth() + 1)).slice(-2)
|
|
|
+ var day = ('0' + d.getDate()).slice(-2)
|
|
|
+ var h = ('0' + d.getHours()).slice(-2)
|
|
|
+ var mi = ('0' + d.getMinutes()).slice(-2)
|
|
|
+ return y + '-' + m + '-' + day + ' ' + h + ':' + mi
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.container {
|
|
|
+ min-height: 100vh;
|
|
|
+ background: #f5f7fa;
|
|
|
+ padding-bottom: 60rpx;
|
|
|
+}
|
|
|
+
|
|
|
+/* ===== 编辑表单 ===== */
|
|
|
+.edit-section {
|
|
|
+ padding: 20rpx 30rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.form-card {
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ padding: 28rpx;
|
|
|
+ box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.04);
|
|
|
+}
|
|
|
+
|
|
|
+.form-title {
|
|
|
+ font-size: 30rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ margin-bottom: 24rpx;
|
|
|
+ padding-bottom: 16rpx;
|
|
|
+ border-bottom: 1rpx solid #f0f0f0;
|
|
|
+}
|
|
|
+
|
|
|
+.form-item {
|
|
|
+ margin-bottom: 24rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.form-item:last-child {
|
|
|
+ margin-bottom: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.form-item-row {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ gap: 16rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.form-item.half {
|
|
|
+ flex: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.form-label {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #888;
|
|
|
+ display: block;
|
|
|
+ margin-bottom: 8rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.form-input {
|
|
|
+ width: 100%;
|
|
|
+ height: 80rpx;
|
|
|
+ background: #f9fafb;
|
|
|
+ border: 1rpx solid #e5e7eb;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ padding: 0 20rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.form-picker, .form-date-picker {
|
|
|
+ width: 100%;
|
|
|
+ min-height: 80rpx;
|
|
|
+ background: #f9fafb;
|
|
|
+ border: 1rpx solid #e5e7eb;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ padding: 20rpx;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.picker-text {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333;
|
|
|
+}
|
|
|
+
|
|
|
+.form-textarea {
|
|
|
+ width: 100%;
|
|
|
+ background: #f9fafb;
|
|
|
+ border: 1rpx solid #e5e7eb;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ padding: 16rpx 20rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333;
|
|
|
+ box-sizing: border-box;
|
|
|
+ min-height: 160rpx;
|
|
|
+ display: block;
|
|
|
+}
|
|
|
+
|
|
|
+.cover-preview {
|
|
|
+ margin-top: 12rpx;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ overflow: hidden;
|
|
|
+ height: 200rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.preview-img {
|
|
|
+ width: 100%;
|
|
|
+ height: 200rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.form-actions {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ gap: 16rpx;
|
|
|
+ justify-content: center;
|
|
|
+ margin-top: 32rpx;
|
|
|
+ padding-top: 24rpx;
|
|
|
+ border-top: 1rpx solid #f0f0f0;
|
|
|
+}
|
|
|
+
|
|
|
+.btn-save, .btn-publish {
|
|
|
+ padding: 18rpx 48rpx;
|
|
|
+ border-radius: 40rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+
|
|
|
+.btn-save {
|
|
|
+ background: linear-gradient(135deg, #10B981, #059669);
|
|
|
+ box-shadow: 0 4rpx 16rpx rgba(16, 185, 129, 0.3);
|
|
|
+}
|
|
|
+
|
|
|
+.btn-publish {
|
|
|
+ background: #fff;
|
|
|
+ border: 2rpx solid #10B981;
|
|
|
+ color: #10B981;
|
|
|
+}
|
|
|
+
|
|
|
+.btn-save:active, .btn-publish:active { opacity: 0.8; }
|
|
|
+
|
|
|
+.btn-save text, .btn-publish text {
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+
|
|
|
+/* ===== 详情模式 ===== */
|
|
|
+.detail-section {
|
|
|
+ padding: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.detail-cover {
|
|
|
+ width: 100%;
|
|
|
+ height: 400rpx;
|
|
|
+ background: linear-gradient(135deg, #10B981 0%, #059669 100%);
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+
|
|
|
+.cover-img {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.placeholder-icon {
|
|
|
+ font-size: 120rpx;
|
|
|
+ color: rgba(255,255,255,0.8);
|
|
|
+}
|
|
|
+
|
|
|
+.detail-card {
|
|
|
+ background: #fff;
|
|
|
+ margin: -40rpx 30rpx 0;
|
|
|
+ border-radius: 24rpx;
|
|
|
+ padding: 32rpx;
|
|
|
+ box-shadow: 0 8rpx 32rpx rgba(0,0,0,0.08);
|
|
|
+ position: relative;
|
|
|
+}
|
|
|
+
|
|
|
+.detail-header {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: flex-start;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.detail-title {
|
|
|
+ font-size: 36rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ flex: 1;
|
|
|
+ margin-right: 16rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.detail-status {
|
|
|
+ font-size: 24rpx;
|
|
|
+ padding: 6rpx 18rpx;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ flex-shrink: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.status-draft { background: #f3f4f6; color: #666; }
|
|
|
+.status-published { background: #d1fae5; color: #059669; }
|
|
|
+.status-cancelled { background: #fee2e2; color: #dc2626; }
|
|
|
+.status-completed { background: #dbeafe; color: #2563eb; }
|
|
|
+
|
|
|
+.detail-meta-row {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ gap: 24rpx;
|
|
|
+ margin-bottom: 24rpx;
|
|
|
+ padding-bottom: 20rpx;
|
|
|
+ border-bottom: 1rpx solid #f0f0f0;
|
|
|
+}
|
|
|
+
|
|
|
+.meta-item {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ align-items: center;
|
|
|
+ gap: 6rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.meta-icon {
|
|
|
+ font-size: 26rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.meta-text {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #666;
|
|
|
+}
|
|
|
+
|
|
|
+.detail-stats {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ gap: 20rpx;
|
|
|
+ margin-bottom: 24rpx;
|
|
|
+ padding-bottom: 20rpx;
|
|
|
+ border-bottom: 1rpx solid #f0f0f0;
|
|
|
+}
|
|
|
+
|
|
|
+.stat-box {
|
|
|
+ flex: 1;
|
|
|
+ background: #f9fafb;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ padding: 20rpx;
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+.stat-val {
|
|
|
+ font-size: 36rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #10B981;
|
|
|
+ display: block;
|
|
|
+}
|
|
|
+
|
|
|
+.stat-label {
|
|
|
+ font-size: 22rpx;
|
|
|
+ color: #888;
|
|
|
+ display: block;
|
|
|
+ margin-top: 4rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.section-title {
|
|
|
+ font-size: 28rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ display: block;
|
|
|
+ margin-bottom: 12rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.desc-text {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #666;
|
|
|
+ line-height: 1.7;
|
|
|
+ display: block;
|
|
|
+}
|
|
|
+
|
|
|
+.detail-desc {
|
|
|
+ margin-bottom: 24rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.detail-actions {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ justify-content: center;
|
|
|
+ margin-top: 24rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.btn-edit {
|
|
|
+ background: linear-gradient(135deg, #10B981, #059669);
|
|
|
+ padding: 18rpx 64rpx;
|
|
|
+ border-radius: 40rpx;
|
|
|
+ box-shadow: 0 4rpx 16rpx rgba(16, 185, 129, 0.3);
|
|
|
+}
|
|
|
+
|
|
|
+.btn-edit:active { opacity: 0.8; }
|
|
|
+
|
|
|
+.btn-edit text {
|
|
|
+ color: #fff;
|
|
|
+ font-size: 28rpx;
|
|
|
+ font-weight: bold;
|
|
|
+}
|
|
|
+
|
|
|
+.loading {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ padding: 80rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.loading-text {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #999;
|
|
|
+}
|
|
|
+</style>
|