Commit 4b8db5af authored by spc's avatar spc

xingmalab

parent 5c39ee79
# 星妈实验室发布页面更新日志
## 版本 1.1.0 - 2024-01-XX
### 新增功能
#### 1. 藏品图片上传功能
- ✅ 支持单张图片上传(限制1张)
- ✅ 固定宽度显示,不限制高度比例
- ✅ 文件大小限制(可配置,默认10MB)
- ✅ 支持格式:jpg、png、jpeg
- ✅ 点击上传区域拉起相机/相册选择器
- ✅ 超过大小限制时显示友好提示:"照片太大啦,换一张试试吧~"
#### 2. 重新上传功能
- ✅ 已上传图片右下角显示"重新上传"按钮
- ✅ 点击重新拉起相机/相册图库
- ✅ 支持jpg/png/jpeg格式选择
- ✅ 上传中状态显示
#### 3. 藏品文案介绍
- ✅ 最多输入1000字限制
- ✅ 点击拉起输入键盘
- ✅ 纯文本输入,不支持富文本
- ✅ 实时字数统计显示
- ✅ 达到字数上限时提示:"字数已达上限"
#### 4. 发布按钮交互优化
- ✅ 首次发布用户自动拉起微信头像昵称授权
- ✅ 已有头像昵称信息用户直接进入确认弹窗
- ✅ 授权拒绝时停留当前页面,再次点击重新拉起授权
- ✅ 确认弹窗显示上传图片和文案内容
- ✅ 后端校验发布次数限制
- ✅ 发布成功后显示随机成功文案
### 技术改进
#### 状态管理
- ✅ 完善的三状态管理:未选择、选择、成功
- ✅ 响应式数据绑定
- ✅ 计算属性优化
#### 用户体验
- ✅ 完善的错误处理和提示
- ✅ 加载状态显示
- ✅ 友好的交互反馈
- ✅ 响应式布局适配
#### 代码质量
- ✅ 遵循Vue 3 Composition API规范
- ✅ 模块化配置管理
- ✅ 完善的注释和文档
- ✅ 保持原有样式格局不变
### 配置项
```javascript
// 图片上传配置
upload: {
maxSize: 10 * 1024 * 1024, // 10MB
maxSizeText: '照片太大啦,换一张试试吧~',
maxWords: 1000,
maxWordsText: '字数已达上限',
allowedTypes: ['jpg', 'png', 'jpeg'],
maxCount: 1
}
```
### 文件结构
```
pages/XingmaLabPublishPage/
├── XingmaLabPublishPage.vue # 主组件文件
├── XingmaLabPublishPage.less # 样式文件
├── config.js # 配置文件
├── README.md # 功能说明文档
└── CHANGELOG.md # 更新日志
```
### 兼容性
- ✅ 微信小程序
- ✅ uni-app框架
- ✅ Vue 3 Composition API
- ✅ 响应式设计
### 注意事项
1. 保持原有样式和图片格局完全不变
2. 所有交互遵循微信小程序开发规范
3. 错误处理完善,用户体验友好
4. 支持跨平台适配
5. 遵循项目开发规范
# 星妈实验室发布页面 (XingmaLabPublishPage)
# 星妈实验室发布页面
## 概述
## 功能概述
这是一个基于Vue 3 Composition API开发的星妈实验室发布页面组件,用于展示不同状态下的页面内容和交互,支持图片上传、文案编辑、发布流程等功能
这是一个星妈实验室的藏品发布页面,支持用户上传藏品图片、编辑文案介绍,并进行发布
## 功能特性
## 主要功能
- **三种状态展示**:未选择状态、选择状态、成功状态
- **图片上传功能**:支持相机/相册选择,限制大小和格式
- **文案编辑功能**:支持纯文本输入,限制字数上限
- **发布流程管理**:包含微信授权、确认弹窗、发布成功等步骤
- **动态资源管理**:通过配置文件统一管理图片资源
- **响应式设计**:支持不同屏幕尺寸的适配
- **交互动画**:包含淡入动画和悬停效果
- **状态管理**:使用Vue 3的响应式系统管理页面状态
## 文件结构
```
XingmaLabPublishPage/
├── XingmaLabPublishPage.vue # 主组件文件
├── XingmaLabPublishPage.less # 样式文件
├── config.js # 配置文件
└── README.md # 说明文档
```
## 使用方法
### 1. 基本使用
```vue
<template>
<XingmaLabPublishPage />
</template>
<script setup>
import XingmaLabPublishPage from '@/pages/XingmaLabPublishPage/XingmaLabPublishPage.vue'
</script>
```
### 2. 状态控制
组件内部管理三种状态:
- `nosel`: 未选择状态(默认)
- `sel`: 选择状态(图片上传和文案编辑)
- `suc`: 成功状态(发布成功展示)
### 3. 功能说明
#### 图片上传功能
- **上传方式**:支持相机拍照和相册选择
- **格式限制**:仅支持jpg/png/jpeg格式
### 1. 藏品图片上传
- **限制数量**:仅限上传1张图片
- **尺寸限制**:固定宽度,不限制高度比例
- **大小限制**:可配置最大文件大小(默认10MB)
- **数量限制**:仅限上传1张图片
- **交互反馈**:超出限制时显示相应提示信息
#### 文案编辑功能
- **输入限制**:最多输入1000字
- **格式支持**:jpg、png、jpeg
- **交互方式**:点击上传区域拉起相机/相册选择器
- **错误提示**:超过大小限制时显示"照片太大啦,换一张试试吧~"
### 2. 重新上传功能
- **触发方式**:点击"重新上传"按钮
- **选择方式**:拉起相机/相册图库
- **格式限制**:jpg/png/jpeg
- **位置**:已上传图片右下角
### 3. 藏品文案介绍
- **字数限制**:最多1000字
- **输入方式**:点击拉起输入键盘
- **内容类型**:纯文本,不支持富文本
- **字数提示**:实时显示当前字数/最大字数
- **格式支持**:纯文本输入,不支持富文本
- **交互反馈**:达到字数上限时显示提示
#### 发布流程
1. **前置检查**:必须上传图片并填写描述
2. **微信授权**:首次发布需要授权头像昵称
3. **确认弹窗**:显示发布内容预览
4. **发布执行**:调用后端API进行发布
5. **成功展示**:显示发布成功页面
## 配置说明
### 图片资源配置
`config.js` 中配置图片资源路径:
```javascript
export const xingmaLabConfig = {
baseUrl: 'https://factory-walk.feihe.com',
images: {
background: '/farqbxzczytcami/images/XingmaLabPublishPage/XingmaLabPublishPageBg.png',
// ... 其他图片配置
}
}
```
### 上传配置
```javascript
upload: {
maxSize: 10 * 1024 * 1024, // 10MB,待定
maxSizeText: '照片太大啦,换一张试试吧~',
maxWords: 1000,
maxWordsText: '字数已达上限',
allowedTypes: ['jpg', 'png', 'jpeg'],
maxCount: 1
}
```
### 发布成功文案配置
```javascript
successMessages: [
'最好的礼物不是玩具,是陪宝贝长大的光阴。欢迎将宝贝的珍贵回忆,存入你的"时光银行"。',
'时光会走远,影像能长存。星妈会,为您珍藏每一份稚的美好。',
// ... 更多文案
]
```
## 样式定制
### 主要样式类
- `.xingmalabpublishpage`: 主容器
- `.collection-image-area`: 图片上传区域
- `.collection-description-area`: 文案编辑区域
- `.confirm-popup`: 确认发布弹窗
- `.xingmalabpublishpagenosel`: 未选择状态容器
- `.xingmalabpublishpagesel`: 选择状态容器
- `.xingmalabpublishpagesuc`: 成功状态容器
### 响应式断点
- 默认:750rpx 宽度(移动端)
- 响应式:小于750px时自动适配为100vw
### 动画效果
- `fadeIn`: 页面淡入动画
- `slideInUp`: 图片和底部容器从下往上滑入动画
- 上传区域和文案区域的滑入动画
## 交互功能
### 图片上传
```javascript
const handleImageUpload = () => {
uni.chooseImage({
count: 1,
sizeType: ['original'],
sourceType: ['album', 'camera'],
success: (res) => {
// 处理图片选择和验证
}
})
}
```
### 文案编辑
```javascript
const handleDescriptionInput = (e) => {
const value = e.detail.value
if (value.length > config.upload.maxWords) {
// 显示字数超限提示
}
}
```
### 发布流程
```javascript
const handlePublishBtnClick = async () => {
// 检查前置条件
if (!canPublish.value) return
// 检查微信授权
if (!hasAuthorized.value) {
await requestWechatAuth()
return
}
// 显示确认弹窗
showConfirmPopup()
}
```
### 微信授权
```javascript
const requestWechatAuth = () => {
return new Promise((resolve) => {
uni.getUserProfile({
desc: '用于完善用户资料',
success: (res) => {
hasAuthorized.value = true
resolve(true)
},
fail: (err) => {
// 处理授权失败
resolve(false)
}
})
})
}
```
## 开发规范
- 使用Vue 3 Composition API
- 遵循项目ESLint和Prettier规范
- 使用Less预处理器
- 支持uni-app跨平台开发
- 使用响应式数据管理状态
- 集成微信授权API
- **超限提示**:达到上限时显示"字数已达上限"
### 4. 发布按钮交互
- **首次发布**:需要拉起微信头像昵称授权
- **授权处理**
- 允许:进入确认弹窗页面
- 拒绝:停留当前页面,再次点击重新拉起授权
- **非首次发布**:直接进入确认弹窗页面
- **确认弹窗**:显示上传的图片和文案,用户确认后才发布
- **次数限制**:后端校验用户发布次数是否已达上限
## 技术实现
### 状态管理
- `NOSEL`:未选择状态
- `SEL`:选择状态(已上传图片和文案)
- `SUC`:发布成功状态
### 关键方法
- `handleImageUpload()`:处理图片上传
- `handleDescriptionInput()`:处理文案输入
- `handlePublishBtnClick()`:处理发布按钮点击
- `requestUserInfo()`:请求用户信息授权
- `checkPublishLimit()`:检查发布次数限制
### 配置项
- 图片大小限制:`config.upload.maxSize`
- 文案字数限制:`config.upload.maxWords`
- 支持的文件格式:`config.upload.allowedTypes`
## 使用说明
1. 用户进入页面后,点击"记录这个时刻"按钮进入选择状态
2. 上传藏品图片(必填)
3. 输入藏品文案介绍(可选,最多1000字)
4. 点击发布按钮
5. 首次发布需要授权微信头像昵称
6. 确认发布内容后完成发布
7. 显示发布成功页面
## 注意事项
1. 确保图片资源路径正确配置
2. 图片资源需要支持HTTPS协议
3. 组件使用绝对定位布局,注意父容器样式设置
4. 微信授权需要在小程序环境中使用
5. 图片上传大小限制可根据实际需求调整
6. 发布成功文案会随机显示,增加用户体验
7. 确认弹窗使用uni-popup组件,确保已安装
## 更新日志
- v1.0.0: 初始版本,支持三种状态展示
- v1.1.0: 新增图片上传功能,支持格式和大小限制
- v1.2.0: 新增文案编辑功能,支持字数限制和实时统计
- v1.3.0: 新增发布流程管理,包含微信授权和确认弹窗
- v1.4.0: 新增发布成功页面,支持随机文案展示
- 支持动态资源管理和响应式设计
- 集成微信授权和分享API
- 添加交互动画和状态反馈
- 保持原有样式和图片格局不变
- 所有交互都遵循微信小程序规范
- 错误处理完善,用户体验友好
- 支持响应式布局
- 遵循Vue 3 Composition API开发规范
\ No newline at end of file
......@@ -26,14 +26,22 @@
position: absolute;
.xingmalabpublishpagenoseltextplaceholder {
width: 263rpx;
height: 31rpx;
left: 41rpx;
top: 953rpx;
width: 684rpx;
height: 160rpx;
left: 33rpx;
top: 949rpx;
position: absolute;
font-size: 32rpx;
line-height: 31rpx;
color: rgba(189, 191, 195, 1);
line-height: 1.5;
color: rgba(0, 0, 0, 1);
border: none;
background: transparent;
resize: none;
outline: none;
&::placeholder {
color: rgba(189, 191, 195, 1);
}
}
.xingmalabpublishpagenoselbottomcon {
......@@ -90,129 +98,18 @@
}
}
// 选择状态
.xingmalabpublishpagesel {
width: 750rpx;
height: 1416rpx;
left: 0rpx;
top: 208rpx;
position: absolute;
.xingmalabpublishpagenoseltext {
width: 295rpx;
height: 31rpx;
// 主内容区域(整合未选择状态和选择状态)
.xingmalabpublishpagenosel {
// 选择状态下的文案输入框样式
&:has(.xingmalabpublishpageselbottomcon) .xingmalabpublishpagenoseltextplaceholder {
width: 684rpx;
height: 160rpx;
left: 33rpx;
top: 949rpx;
position: absolute;
font-size: 32rpx;
line-height: 31rpx;
color: rgba(29, 30, 37, 1);
}
// 藏品图片上传区域
.collection-image-area {
position: absolute;
left: 32rpx;
top: 200rpx;
width: 686rpx;
height: 400rpx;
.upload-placeholder {
width: 100%;
height: 100%;
border: 2rpx dashed #ddd;
border-radius: 16rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #f8f9fa;
transition: all 0.3s ease;
&:hover {
border-color: #007aff;
background-color: #f0f8ff;
}
.upload-icon {
font-size: 80rpx;
color: #999;
margin-bottom: 20rpx;
}
.upload-text {
font-size: 28rpx;
color: #666;
}
}
.uploaded-image-container {
width: 100%;
height: 100%;
position: relative;
.uploaded-image {
width: 100%;
height: 100%;
border-radius: 16rpx;
object-fit: cover;
}
.reupload-btn {
position: absolute;
bottom: 20rpx;
right: 20rpx;
background-color: rgba(0, 0, 0, 0.7);
color: white;
padding: 12rpx 24rpx;
border-radius: 20rpx;
font-size: 24rpx;
transition: all 0.3s ease;
&:hover {
background-color: rgba(0, 0, 0, 0.9);
}
}
}
}
// 藏品文案介绍区域
.collection-description-area {
position: absolute;
left: 32rpx;
top: 650rpx;
width: 686rpx;
height: 200rpx;
.description-textarea {
width: 100%;
height: 160rpx;
border: 2rpx solid #e0e0e0;
border-radius: 16rpx;
padding: 20rpx;
font-size: 28rpx;
line-height: 1.5;
resize: none;
background-color: white;
&:focus {
border-color: #007aff;
outline: none;
}
}
.word-count {
position: absolute;
bottom: 10rpx;
right: 20rpx;
font-size: 24rpx;
color: #999;
}
color: rgba(0, 0, 0, 1);
}
// 选择状态下的底部按钮区域
.xingmalabpublishpageselbottomcon {
width: 750rpx;
height: 218rpx;
......@@ -249,15 +146,15 @@
}
}
// 已上传图片显示
.xingmalabpublishpageselpic {
width: 686rpx;
height: 912rpx;
left: 32rpx;
top: 0rpx;
position: absolute;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
object-fit: cover;
border-radius: 16rpx;
}
.xingmalabpublishpageselcpver {
......@@ -293,9 +190,9 @@
// 成功状态
.xingmalabpublishpagesuc {
width: 750rpx;
height: 1413rpx;
height: 1416rpx;
left: 0rpx;
top: 211rpx;
top: 208rpx;
position: absolute;
.xingmalabpublishpagesucbottomconicon {
......
......@@ -3,38 +3,43 @@
<span class="xingmalabpublishpagebg"
:style="{ backgroundImage: `url(${$baseUrl}${getImageUrl(config.images.background)})` }"></span>
<!-- 未选择状态 -->
<div class="xingmalabpublishpagenosel" v-if="currentState === config.states.NOSEL">
<span class="xingmalabpublishpagenoseltextplaceholder">{{ config.texts.noSel.placeholder }}</span>
<div class="xingmalabpublishpagenoselbottomcon">
<!-- 主内容区域 -->
<div class="xingmalabpublishpagenosel" v-if="currentState !== config.states.SUC">
<!-- 文案输入框 -->
<textarea v-model="description" class="xingmalabpublishpagenoseltextplaceholder"
:placeholder="hasContent ? config.texts.sel.descriptionPlaceholder : config.texts.noSel.placeholder"
:maxlength="config.upload.maxWords" @input="handleDescriptionInput"></textarea>
<!-- 底部按钮区域 -->
<div class="xingmalabpublishpagenoselbottomcon" v-if="!hasContent">
<span class="xingmalabpublishpagenoselbottomconbg"
:style="{ backgroundImage: `url(${$baseUrl}${getImageUrl(config.images.noSel.bottomConBg)})` }"></span>
:style="{ backgroundImage: `url(${$baseUrl}${getImageUrl(config.images.noSel.bottomConBg)})` }"
@click="handleImageUpload"></span>
<span class="xingmalabpublishpagenoselbottomconbtn"
:style="{ backgroundImage: `url(${$baseUrl}${getImageUrl(config.images.noSel.bottomConBtn)})` }"
@click="handleNoSelBtnClick"></span>
@click="handleImageUpload"></span>
</div>
<span class="xingmalabpublishpagenoselbtn"
:style="{ backgroundImage: `url(${$baseUrl}${getImageUrl(config.images.noSel.btn)})` }"
@click="handleNoSelBtnClick"></span>
</div>
<!-- 选择状态 -->
<div class="xingmalabpublishpagesel" v-if="currentState === config.states.SEL">
<span class="xingmalabpublishpagenoseltext">{{ config.texts.sel.title }}</span>
<div class="xingmalabpublishpageselbottomcon">
<div class="xingmalabpublishpageselbottomcon" v-if="hasContent">
<span class="xingmalabpublishpageselbottomconpublishbtnbg"
:style="{ backgroundImage: `url(${$baseUrl}${getImageUrl(config.images.sel.bottomConPublishBtnBg)})` }"></span>
<span class="xingmalabpublishpageselbottomconpublishbtn"
:style="{ backgroundImage: `url(${$baseUrl}${getImageUrl(config.images.sel.bottomConPublishBtn)})` }"
@click="handlePublishBtnClick"></span>
</div>
<span class="xingmalabpublishpageselpic"
:style="{ backgroundImage: `url(${$baseUrl}${getImageUrl(config.images.sel.pic)})` }"></span>
<span class="xingmalabpublishpageselcpver"
<!-- 上传按钮 -->
<span class="xingmalabpublishpagenoselbtn" v-if="!hasContent"
:style="{ backgroundImage: `url(${$baseUrl}${getImageUrl(config.images.noSel.btn)})` }"
@click="handleImageUpload"></span>
<!-- 已上传图片显示 -->
<image v-if="uploadedImage" :src="uploadedImage" class="xingmalabpublishpageselpic" mode="aspectFill" />
<span class="xingmalabpublishpageselcpver" v-if="uploadedImage"
:style="{ backgroundImage: `url(${$baseUrl}${getImageUrl(config.images.sel.cpver)})` }"></span>
<span class="xingmalabpublishpageselretry"
<span class="xingmalabpublishpageselretry" v-if="uploadedImage"
:style="{ backgroundImage: `url(${$baseUrl}${getImageUrl(config.images.sel.retry)})` }"
@click="handleRetryClick"></span>
@click="handleImageUpload"></span>
</div>
<!-- 成功状态 -->
......@@ -49,20 +54,38 @@
@click="handleSuccessBtnClick"></span>
</div>
<span class="xingmalabpublishpagesucdesc">
{{ config.texts.suc.desc }}
{{ successMessage }}
</span>
<span class="xingmalabpublishpagesucpicbg"
:style="{ backgroundImage: `url(${$baseUrl}${getImageUrl(config.images.suc.picBg)})` }"></span>
<span class="xingmalabpublishpagesucpic"
:style="{ backgroundImage: `url(${$baseUrl}${getImageUrl(config.images.suc.pic)})` }"></span>
<image v-if="uploadedImage" :src="uploadedImage" class="xingmalabpublishpagesucpic" mode="aspectFill" />
<span class="xingmalabpublishpagesucnum">{{ config.texts.suc.numberPrefix }}{{ publishNumber }}</span>
</div>
<!-- 确认发布弹窗 -->
<uni-popup ref="confirmPopup" type="center" :mask-click="false">
<view class="confirm-popup">
<view class="confirm-title">确认发布</view>
<view class="confirm-content">
<view class="confirm-image" v-if="uploadedImage">
<image :src="uploadedImage" mode="aspectFill" />
</view>
<view class="confirm-description">
{{ description || '暂无文案介绍' }}
</view>
</view>
<view class="confirm-actions">
<button class="confirm-btn cancel" @click="handleCancelPublish">取消</button>
<button class="confirm-btn confirm" @click="handleConfirmPublish">确认发布</button>
</view>
</view>
</uni-popup>
</view>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { xingmaLabConfig, getImageUrl } from './config.js'
import { ref, onMounted, computed } from 'vue'
import { xingmaLabConfig, getImageUrl, getRandomSuccessMessage } from './config.js'
// 组件名称
defineOptions({
......@@ -72,32 +95,260 @@ defineOptions({
// 响应式数据
const currentState = ref(xingmaLabConfig.states.NOSEL) // nosel, sel, suc
const publishNumber = ref('123456789')
const uploadedImage = ref('') // 上传的图片
const description = ref('') // 藏品文案介绍
const isUploading = ref(false) // 上传状态
const confirmPopup = ref(null) // 确认弹窗引用
const successMessage = ref('') // 成功文案
// 配置对象
const config = xingmaLabConfig
// 方法
const handleNoSelBtnClick = () => {
console.log('点击未选择状态按钮')
// 这里可以添加跳转逻辑或状态切换
// 例如:跳转到选择页面
// currentState.value = config.states.SEL
// 计算属性 - 判断是否有内容(图片和文案都要有)
const hasContent = computed(() => {
return uploadedImage.value && description.value.trim()
})
// 计算属性
const isFirstTimePublish = computed(() => {
// 检查用户是否首次发布(这里需要根据实际业务逻辑判断)
// 可以通过本地存储或用户信息来判断
const hasPublished = uni.getStorageSync('hasPublished')
return !hasPublished
})
const hasUserInfo = computed(() => {
// 检查用户是否已有头像昵称信息
const userInfo = uni.getStorageSync('userInfo')
return userInfo && userInfo.avatarUrl && userInfo.nickName
})
// 图片上传处理
const handleImageUpload = () => {
if (isUploading.value) return
uni.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
const tempFilePath = res.tempFilePaths[0]
// 检查文件大小
uni.getFileInfo({
filePath: tempFilePath,
success: (fileInfo) => {
if (fileInfo.size > config.upload.maxSize) {
uni.showToast({
title: config.upload.maxSizeText,
icon: 'none',
duration: 2000
})
return
}
// 检查文件格式
const fileExtension = tempFilePath.split('.').pop().toLowerCase()
if (!config.upload.allowedTypes.includes(fileExtension)) {
uni.showToast({
title: '请选择jpg、png或jpeg格式的图片',
icon: 'none',
duration: 2000
})
return
}
// 上传图片
uploadImage(tempFilePath)
},
fail: () => {
uni.showToast({
title: '获取文件信息失败',
icon: 'none'
})
}
})
},
fail: (err) => {
console.log('选择图片失败:', err)
}
})
}
const handlePublishBtnClick = () => {
console.log('点击发布按钮')
// 模拟发布过程
// 上传图片到服务器
const uploadImage = (filePath) => {
isUploading.value = true
// 这里应该调用实际的上传接口
// 暂时使用本地路径作为示例
setTimeout(() => {
currentState.value = config.states.SUC
// 生成随机发布编号
publishNumber.value = Math.random().toString().slice(2, 11)
uploadedImage.value = filePath
isUploading.value = false
uni.showToast({
title: '图片上传成功',
icon: 'success'
})
}, 1000)
}
const handleRetryClick = () => {
console.log('点击重试按钮')
// 重置状态
currentState.value = config.states.NOSEL
// 文案输入处理
const handleDescriptionInput = (e) => {
const value = e.detail.value
if (value.length > config.upload.maxWords) {
uni.showToast({
title: config.upload.maxWordsText,
icon: 'none',
duration: 2000
})
description.value = value.substring(0, config.upload.maxWords)
} else {
description.value = value
}
}
// 发布按钮点击处理
const handlePublishBtnClick = async () => {
console.log('点击发布按钮', isFirstTimePublish.value, hasUserInfo.value)
// 检查是否首次发布且需要授权
// if (isFirstTimePublish.value && !hasUserInfo.value) {
await requestUserInfo()
return
// }
// 显示确认弹窗
confirmPopup.value.open()
}
// 请求用户信息授权
const requestUserInfo = () => {
return new Promise((resolve, reject) => {
// 使用新的授权方式
uni.getUserInfo({
success: (res) => {
console.log('获取用户信息成功:', res)
// 保存用户信息
uni.setStorageSync('userInfo', res.userInfo)
// 显示确认弹窗
confirmPopup.value.open()
resolve(res)
},
fail: (err) => {
console.log('获取用户信息失败:', err)
// 如果获取失败,尝试使用按钮授权
uni.showModal({
title: '授权提示',
content: '需要获取您的头像和昵称信息才能发布内容',
confirmText: '去授权',
success: (modalRes) => {
if (modalRes.confirm) {
// 引导用户到设置页面授权
uni.openSetting({
success: (settingRes) => {
if (settingRes.authSetting['scope.userInfo']) {
// 用户已授权,重新获取用户信息
uni.getUserInfo({
success: (userRes) => {
uni.setStorageSync('userInfo', userRes.userInfo)
confirmPopup.value.open()
resolve(userRes)
},
fail: () => {
uni.showToast({
title: '授权失败,请重试',
icon: 'none'
})
reject()
}
})
} else {
uni.showToast({
title: '需要授权才能发布',
icon: 'none'
})
reject()
}
}
})
} else {
uni.showToast({
title: '需要授权才能发布',
icon: 'none'
})
reject()
}
}
})
}
})
})
}
// 取消发布
const handleCancelPublish = () => {
confirmPopup.value.close()
}
// 确认发布
const handleConfirmPublish = async () => {
confirmPopup.value.close()
try {
// 检查发布次数限制
const canPublish = await checkPublishLimit()
if (!canPublish) {
uni.showToast({
title: '发布次数已达上限',
icon: 'none'
})
return
}
// 执行发布
await performPublish()
// 标记用户已发布过
uni.setStorageSync('hasPublished', true)
// 切换到成功状态
currentState.value = config.states.SUC
successMessage.value = getRandomSuccessMessage()
publishNumber.value = generatePublishNumber()
} catch (error) {
console.error('发布失败:', error)
uni.showToast({
title: '发布失败,请重试',
icon: 'none'
})
}
}
// 检查发布次数限制
const checkPublishLimit = async () => {
// 这里应该调用后端接口检查发布次数
// 暂时返回true作为示例
return new Promise((resolve) => {
setTimeout(() => {
resolve(true)
}, 500)
})
}
// 执行发布
const performPublish = async () => {
// 这里应该调用后端发布接口
return new Promise((resolve) => {
setTimeout(() => {
console.log('发布成功')
resolve()
}, 1000)
})
}
// 生成发布编号
const generatePublishNumber = () => {
return Math.random().toString().slice(2, 11)
}
const handleSuccessBtnClick = () => {
......@@ -109,6 +360,8 @@ const handleSuccessBtnClick = () => {
// 生命周期
onMounted(() => {
console.log('星妈实验室发布页面已加载')
// 生成随机成功文案
successMessage.value = getRandomSuccessMessage()
})
</script>
......
......@@ -47,10 +47,12 @@ export const xingmaLabConfig = {
placeholder: '记录这个时刻……'
},
sel: {
title: '快来用星妈会小程序'
title: '快来用星妈会小程序',
descriptionPlaceholder: '请输入藏品文案介绍...'
},
suc: {
numberPrefix: 'No.'
numberPrefix: 'No.',
desc: '发布成功!'
}
},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment