| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359 |
- <template>
- <view class="edit-container">
- <!-- 自定义导航 -->
- <view class="edit-header">
- <view class="header-left" @click="onBack">
- <text class="back-icon">←</text>
- <text class="back-text">返回</text>
- </view>
- <text class="header-title">写成长记录</text>
- <view class="header-right" @click="goMyPosts">
- <text class="history-text">历史</text>
- </view>
- </view>
- <scroll-view scroll-y class="edit-form">
- <!-- 封面图 -->
- <view class="form-cover" @click="chooseCover">
- <image v-if="coverImage" :src="coverImage" mode="aspectFill" class="cover-preview" />
- <view v-else class="cover-placeholder">
- <text class="cover-icon">📷</text>
- <text class="cover-hint">添加封面</text>
- </view>
- <view v-if="coverImage" class="cover-change" @click.stop="chooseCover">
- <text class="change-text">更换</text>
- </view>
- </view>
- <!-- 标题 -->
- <view class="form-group">
- <input
- class="form-input title-input"
- v-model="title"
- placeholder="给这篇记录取个标题"
- maxlength="50"
- />
- <text class="char-count">{{ title.length }}/50</text>
- </view>
- <!-- 维度选择 -->
- <view class="form-group">
- <text class="form-label">关联维度(选填)</text>
- <view class="dimension-chips">
- <view
- v-for="dim in dimensionList"
- :key="dim.code"
- :class="['dim-chip', selectedDimensions.indexOf(dim.code) >= 0 ? 'active' : '']"
- :style="selectedDimensions.indexOf(dim.code) >= 0 ? 'background:' + dim.color + ';color:#fff;border-color:' + dim.color : ''"
- @click="toggleDimension(dim.code)"
- >
- {{ dim.name }}
- </view>
- </view>
- </view>
- <!-- 正文 -->
- <view class="form-group">
- <textarea
- class="form-textarea"
- v-model="content"
- placeholder="记录孩子的成长点滴..."
- maxlength="2000"
- />
- <text class="char-count">{{ content.length }}/2000</text>
- </view>
- <!-- 可见范围 -->
- <view class="form-group">
- <text class="form-label">可见范围</text>
- <view class="visibility-options">
- <view
- :class="['vis-option', visibility === 'private' ? 'active' : '']"
- @click="visibility = 'private'"
- >
- <text class="vis-icon">🏠</text>
- <text class="vis-text">仅家庭</text>
- <text class="vis-desc">仅家庭成员可见</text>
- </view>
- <view
- :class="['vis-option', visibility === 'public' ? 'active' : '']"
- @click="visibility = 'public'"
- >
- <text class="vis-icon">🌍</text>
- <text class="vis-text">公开发布</text>
- <text class="vis-desc">所有人可见,需审核</text>
- </view>
- </view>
- </view>
- <!-- 发布按钮 -->
- <button class="publish-btn" :disabled="!canPublish" @click="onPublish">
- {{ publishing ? '发布中...' : '发布' }}
- </button>
- <view style="height: 60rpx;"></view>
- </scroll-view>
- </view>
- </template>
- <script>
- import { publishArticle } from '@/utils/api.js'
- import config from '@/config.js'
- export default {
- data() {
- return {
- title: '',
- coverImage: '',
- content: '',
- visibility: 'private',
- selectedDimensions: [],
- publishing: false,
- dimensionList: [
- { code: 'body', name: '身', color: '#FF8C42' },
- { code: 'mind', name: '智', color: '#6366F1' },
- { code: 'wisdom', name: '心', color: '#FF6B9D' },
- { code: 'action', name: '行', color: '#10B981' },
- { code: 'wealth', name: '富', color: '#F59E0B' }
- ]
- }
- },
- computed: {
- canPublish: function() {
- return this.title.trim().length > 0 && this.content.trim().length > 0 && !this.publishing
- }
- },
- methods: {
- chooseCover() {
- var self = this
- uni.chooseImage({
- count: 1,
- sizeType: ['compressed'],
- sourceType: ['album', 'camera'],
- success: function(res) {
- var tempPath = res.tempFilePaths[0]
- // 上传图片
- var token = uni.getStorageSync('token')
- uni.uploadFile({
- url: (config.default && config.default.API_BASE_URL) || config.API_BASE_URL || '' + '/api/media/upload',
- filePath: tempPath,
- name: 'file',
- header: {
- 'Authorization': token ? 'Bearer ' + token : ''
- },
- success: function(uploadRes) {
- try {
- var data = JSON.parse(uploadRes.data)
- if (data && data.code === 200) {
- self.coverImage = data.data
- } else {
- uni.showToast({ title: '上传失败', icon: 'none' })
- }
- } catch (e) {
- uni.showToast({ title: '上传失败', icon: 'none' })
- }
- },
- fail: function() {
- uni.showToast({ title: '上传失败', icon: 'none' })
- }
- })
- }
- })
- },
- toggleDimension(code) {
- var idx = this.selectedDimensions.indexOf(code)
- if (idx >= 0) {
- this.selectedDimensions.splice(idx, 1)
- } else {
- this.selectedDimensions.push(code)
- }
- },
- onBack() {
- if (this.title || this.content) {
- var self = this
- uni.showModal({
- title: '提示',
- content: '是否保存草稿?',
- success: function(res) {
- if (res.confirm) {
- uni.setStorageSync('article_draft', {
- title: self.title,
- coverImage: self.coverImage,
- content: self.content,
- visibility: self.visibility,
- selectedDimensions: self.selectedDimensions
- })
- }
- uni.navigateBack()
- }
- })
- } else {
- uni.navigateBack()
- }
- },
- goMyPosts() {
- uni.navigateTo({ url: '/pages/article-center/my-posts' })
- },
- async onPublish() {
- if (!this.canPublish) return
- this.publishing = true
- try {
- var res = await publishArticle({
- title: this.title.trim(),
- content: this.content.trim(),
- coverImage: this.coverImage,
- visibility: this.visibility,
- relatedDimensions: this.selectedDimensions.join(',')
- })
- if (res.code === 200) {
- var msg = this.visibility === 'public'
- ? '发布成功,等待审核'
- : '发布成功,已对家庭可见'
- uni.showToast({ title: msg, icon: 'success', duration: 2000 })
- uni.removeStorageSync('article_draft')
- var self = this
- setTimeout(function() {
- uni.navigateBack()
- }, 1500)
- } else {
- uni.showToast({ title: res.message || '发布失败', icon: 'none' })
- }
- } catch (e) {
- uni.showToast({ title: '发布失败', icon: 'none' })
- } finally {
- this.publishing = false
- }
- }
- },
- onLoad() {
- // 加载草稿
- try {
- var draft = uni.getStorageSync('article_draft')
- if (draft) {
- this.title = draft.title || ''
- this.coverImage = draft.coverImage || ''
- this.content = draft.content || ''
- this.visibility = draft.visibility || 'private'
- this.selectedDimensions = draft.selectedDimensions || []
- }
- } catch (e) {}
- }
- }
- </script>
- <style scoped>
- .edit-container { min-height: 100vh; background: #f5f7fa; }
- .edit-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 80rpx 30rpx 20rpx;
- background: #fff;
- position: sticky;
- top: 0;
- z-index: 10;
- }
- .header-left { display: flex; align-items: center; }
- .back-icon { font-size: 36rpx; margin-right: 8rpx; }
- .back-text { font-size: 26rpx; color: #333; }
- .header-title { font-size: 32rpx; font-weight: bold; color: #333; }
- .header-right { }
- .history-text { font-size: 26rpx; color: #5B9BD5; }
- .edit-form { padding: 20rpx 30rpx; }
- /* 封面 */
- .form-cover {
- width: 100%;
- height: 300rpx;
- background: #eee;
- border-radius: 16rpx;
- overflow: hidden;
- margin-bottom: 20rpx;
- position: relative;
- }
- .cover-preview { width: 100%; height: 100%; }
- .cover-placeholder {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- height: 100%;
- }
- .cover-icon { font-size: 60rpx; margin-bottom: 10rpx; }
- .cover-hint { font-size: 24rpx; color: #999; }
- .cover-change {
- position: absolute;
- right: 16rpx;
- bottom: 16rpx;
- background: rgba(0,0,0,0.5);
- color: #fff;
- padding: 6rpx 20rpx;
- border-radius: 20rpx;
- font-size: 22rpx;
- }
- /* 表单组 */
- .form-group {
- background: #fff;
- border-radius: 16rpx;
- padding: 24rpx;
- margin-bottom: 20rpx;
- }
- .form-input {
- width: 100%;
- font-size: 30rpx;
- color: #333;
- border: none;
- outline: none;
- }
- .title-input { font-weight: bold; }
- .char-count { display: block; text-align: right; font-size: 20rpx; color: #bbb; margin-top: 8rpx; }
- .form-label { font-size: 24rpx; color: #666; display: block; margin-bottom: 16rpx; }
- /* 维度 */
- .dimension-chips { display: flex; flex-wrap: wrap; gap: 16rpx; }
- .dim-chip {
- padding: 10rpx 28rpx;
- border-radius: 30rpx;
- font-size: 24rpx;
- border: 2rpx solid #ddd;
- color: #666;
- }
- .dim-chip.active { color: #fff; border-color: transparent; }
- /* 文本框 */
- .form-textarea {
- width: 100%;
- height: 300rpx;
- font-size: 28rpx;
- color: #333;
- line-height: 1.6;
- border: none;
- outline: none;
- resize: none;
- }
- /* 可见范围 */
- .visibility-options { display: flex; gap: 20rpx; }
- .vis-option {
- flex: 1;
- padding: 24rpx;
- border-radius: 12rpx;
- border: 2rpx solid #eee;
- text-align: center;
- }
- .vis-option.active { border-color: #5B9BD5; background: #E8F4FD; }
- .vis-icon { font-size: 40rpx; display: block; margin-bottom: 8rpx; }
- .vis-text { font-size: 26rpx; font-weight: bold; color: #333; display: block; }
- .vis-desc { font-size: 20rpx; color: #999; display: block; margin-top: 4rpx; }
- /* 发布按钮 */
- .publish-btn {
- width: 100%;
- height: 88rpx;
- line-height: 88rpx;
- background: linear-gradient(135deg, #F97316, #EA580C);
- color: #fff;
- font-size: 32rpx;
- font-weight: bold;
- border-radius: 44rpx;
- text-align: center;
- border: none;
- margin-top: 20rpx;
- }
- .publish-btn[disabled] { opacity: 0.4; }
- .publish-btn::after { border: none; }
- </style>
|