Commit fc9295c6 authored by 张九刚's avatar 张九刚

Merge branch 'master' into feature/20250901_share

parents 58fc3df5 27e1aa78
File added
unpackage/
dist/
static/
node_modules/
.DS_Store
\ No newline at end of file
// {
// // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
// // launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
// "version" : "0.0",
// "configurations" : [
// {
// "default" : {
// "launchtype" : "local"
// },
// "mp-weixin" : {
// "launchtype" : "local"
// },
// "type" : "uniCloud"
// },
// {
// "openVueDevtools" : false,
// "type" : "uni-app:miniProgram"
// },
// {
// "openVueDevtools" : false,
// "type" : "uni-app:h5"
// }
// ]
// }
{
"version" : "1.0",
"configurations" : [
......
import requestModule from './request.js'
const {api} = requestModule
/**
* 星妈会藏馆
* @returns
*/
export const fetchRecordList = (pageNum, pageSize) => api.get('/c/lab/record/list', {
pageNum: pageNum,
pageSize: pageSize
})
/**
* 我的收藏
* @returns
*/
export const fetchFavoriteList = (pageNum, pageSize) => api.get('/c/lab/favorite/list', {
pageNum: pageNum,
pageSize: pageSize
})
/**
* 我的藏品
* @returns
*/
export const fetchRecordMyrecords = (pageNum, pageSize) => api.get('/c/lab/record/myRecords', {
pageNum: pageNum,
pageSize: pageSize
})
export const fetchRecordIndex = () => api.get('/c/lab/home')
export const fetchRecordPublish = (data) => api.post('/c/lab/record/create', data)
export const fetchRecordDetail = (data) => api.get('/c/lab/record/detail', data)
export const fetchFavoriteAdd = (data) => api.get('/c/lab/favorite/add', data)
export const fetchFavoriteRemove = (data) => api.get('/c/lab/favorite/remove', data)
......@@ -144,7 +144,7 @@
</template>
<script setup>
import { getCurrentInstance, computed,onMounted } from 'vue'
import { getCurrentInstance, computed, onMounted } from 'vue'
import { YEAR_GIFT_IMAGES } from './yearGiftImages.js'
import md from '../../md.js'
......@@ -205,7 +205,7 @@ onMounted(() => {
xcxComponentExposure: "true",
pageName: "积分服务页",
componentName: "会员权益",
componentContent: "周岁礼-"+buttonInfo.value.text
componentContent: "周岁礼-" + buttonInfo.value.text
});
})
// 按钮点击事件处理
......@@ -214,7 +214,7 @@ const handleButtonClick = () => {
xcxComponentClick: "true",
pageName: "积分服务页",
componentName: "会员权益",
componentContent: "周岁礼-"+buttonInfo.value.text
componentContent: "周岁礼-" + buttonInfo.value.text
});
if (buttonInfo.value.action === 'upgrade') {
// 跳转到升级页面
......@@ -224,7 +224,7 @@ const handleButtonClick = () => {
} else if (buttonInfo.value.action === 'view') {
// 跳转到查看页面
uni.navigateTo({
url: '/pages/webview/webview?url=https://member.feihe.com/memberH5/#/memberGrowthGift?activityCode=hyczl&sceneCode=WXG07'
url: `/pages/webview/webview?url=${encodeURIComponent('https://member.feihe.com/memberH5/#/memberGrowthGift?activityCode=hyczl&sceneCode=WXG07')}`
});
}
}
......
# XingmaLab 弹窗组件图片资源说明
本文档说明 XingmaLab 弹窗组件所需的图片资源,参考 `babyClass` 组件的图片管理方式。
## 图片配置结构
图片资源通过 `xingmalabImages.js` 文件进行配置管理,采用常量对象的方式:
```javascript
export const XINGMALAB_IMAGES = {
CONFIRM: {
BG: `XingmaLabPop/v1/XingmaLabConfirmPopBg.png`,
CONFIRM_BTN: `XingmaLabPop/v1/XingmaLabConfirmPopConfirmBtn.png`,
CANCEL_BTN: `XingmaLabPop/v1/XingmaLabCancelBtn.png`
},
NO_TIME: {
BG: `XingmaLabPop/v1/XingmaLabNoTimePopBg.png`,
BTN: `XingmaLabPop/v1/XingmaLabNoTimePopBtn.png`
}
}
```
## 目录结构
```
static/
└── XingmaLabPop/
└── v1/
├── XingmaLabConfirmPopBg.png # 确认弹窗背景图片
├── XingmaLabConfirmPopConfirmBtn.png # 确认弹窗确认按钮图片
├── XingmaLabCancelBtn.png # 确认弹窗取消按钮图片
├── XingmaLabNoTimePopBg.png # 无时间弹窗背景图片
└── XingmaLabNoTimePopBtn.png # 无时间弹窗按钮图片
```
## 图片规格要求
### 确认弹窗图片
#### 1. XingmaLabConfirmPopBg.png (背景图片)
- **尺寸**: 618rpx × 557rpx
- **格式**: PNG
- **用途**: 确认弹窗的背景图片
- **设计要求**: 透明背景,包含弹窗框架和装饰元素
#### 2. XingmaLabConfirmPopConfirmBtn.png (确认按钮)
- **尺寸**: 275rpx × 97rpx
- **格式**: PNG
- **用途**: 确认按钮的图片
- **设计要求**: 透明背景,包含按钮文字和样式
#### 3. XingmaLabCancelBtn.png (取消按钮)
- **尺寸**: 279rpx × 101rpx
- **格式**: PNG
- **用途**: 取消按钮的图片
- **设计要求**: 透明背景,包含按钮文字和样式
### 无时间弹窗图片
#### 1. XingmaLabNoTimePopBg.png (背景图片)
- **尺寸**: 618rpx × 460rpx
- **格式**: PNG
- **用途**: 无时间弹窗的背景图片
- **设计要求**: 透明背景,包含弹窗框架和提示信息
#### 2. XingmaLabNoTimePopBtn.png (按钮)
- **尺寸**: 466rpx × 97rpx
- **格式**: PNG
- **用途**: 无时间弹窗的按钮图片
- **设计要求**: 透明背景,包含按钮文字和样式
## 图片命名规范
### 命名规则
- 使用 PascalCase 命名方式
- 包含组件类型和元素类型
- 版本号使用小写字母
### 命名示例
```
XingmaLabConfirmPopBg.png # 确认弹窗背景
XingmaLabConfirmPopConfirmBtn.png # 确认弹窗确认按钮
XingmaLabCancelBtn.png # 确认弹窗取消按钮
XingmaLabNoTimePopBg.png # 无时间弹窗背景
XingmaLabNoTimePopBtn.png # 无时间弹窗按钮
```
## 版本管理
### 版本结构
```
XingmaLabPop/
├── v1/ # 当前版本
│ ├── XingmaLabConfirmPopBg.png
│ ├── XingmaLabConfirmPopConfirmBtn.png
│ ├── XingmaLabCancelBtn.png
│ ├── XingmaLabNoTimePopBg.png
│ └── XingmaLabNoTimePopBtn.png
└── v2/ # 未来版本(可选)
└── ...
```
### 版本更新
1.`xingmalabImages.js` 中修改 `version` 变量
2.`static/XingmaLabPop/` 目录下创建新版本文件夹
3. 将新图片放入对应版本文件夹
4. 更新组件中的图片引用
## 图片优化建议
### 文件大小
- 单个图片文件大小控制在 100KB 以内
- 使用 PNG 格式保证透明背景效果
- 适当压缩图片,平衡质量和文件大小
### 设计规范
- 保持与整体 UI 风格一致
- 按钮图片包含合适的点击状态
- 背景图片支持不同屏幕尺寸适配
### 性能考虑
- 图片尺寸与显示尺寸保持一致
- 避免过大的图片文件影响加载速度
- 使用 `mode="aspectFit"` 确保图片正确显示
## 与 babyClass 组件的对比
### 相似点
1. **图片配置方式**: 都使用常量对象管理图片路径
2. **目录结构**: 都使用版本化的目录结构
3. **命名规范**: 都使用 PascalCase 命名方式
4. **格式要求**: 都使用 PNG 格式支持透明背景
### 不同点
1. **图片数量**: babyClass 有多个等级图片,xingmalab 只有弹窗图片
2. **图片用途**: babyClass 主要用于展示,xingmalab 主要用于交互
3. **图片尺寸**: babyClass 图片尺寸多样,xingmalab 图片尺寸相对固定
## 使用示例
### 在组件中使用
```vue
<template>
<image
class="xingmalabconfirmpopbg"
:src="`${$baseUrl}${XINGMALAB_IMAGES.CONFIRM.BG}`"
mode="aspectFit"
></image>
</template>
<script setup>
import { XINGMALAB_IMAGES } from './xingmalabImages.js'
</script>
```
### 动态获取图片路径
```javascript
// 获取确认弹窗背景图片
const confirmBgPath = XINGMALAB_IMAGES.CONFIRM.BG
// 获取无时间弹窗按钮图片
const noTimeBtnPath = XINGMALAB_IMAGES.NO_TIME.BTN
```
## 注意事项
1. **路径一致性**: 确保 `xingmalabImages.js` 中的路径与实际文件路径一致
2. **版本同步**: 修改版本号时需要同步更新所有相关图片
3. **图片质量**: 确保图片清晰度满足不同设备显示需求
4. **文件格式**: 统一使用 PNG 格式,支持透明背景
5. **命名规范**: 严格遵循命名规范,便于维护和管理
6. **尺寸匹配**: 图片尺寸与 CSS 中定义的尺寸保持一致
7. **性能优化**: 合理控制图片文件大小,优化加载性能
8. **跨平台兼容**: 确保图片在不同平台上的显示效果一致
## 维护和更新
### 日常维护
- 定期检查图片文件是否存在
- 验证图片路径配置是否正确
- 监控图片加载性能
### 版本更新
- 记录版本更新日志
- 备份旧版本图片资源
- 测试新版本图片显示效果
### 问题排查
- 图片不显示:检查路径配置和文件存在性
- 图片变形:检查 CSS 尺寸设置
- 加载缓慢:优化图片文件大小和格式
## 弹窗布局结构
### 双层结构设计
弹窗组件采用双层结构设计,确保背景遮罩和弹窗内容正确显示:
```
弹窗容器 (100vw × 100vh)
├── 背景遮罩 (.mask)
│ ├── 位置: 覆盖整个屏幕
│ ├── 背景: rgba(0, 0, 0, 0.5) 半透明黑色
│ └── 层级: 基础层
└── 弹窗内容 (.popup-content)
├── 位置: 居中显示
├── 尺寸: 根据弹窗类型确定
└── 层级: 内容层 (z-index: 1)
```
### 布局特点
1. **全屏覆盖**: 弹窗容器使用 `position: fixed``100vw × 100vh`
2. **居中显示**: 使用 `display: flex``align-items: center`, `justify-content: center`
3. **层级管理**: 遮罩层和内容层使用不同的 z-index 值
4. **响应式**: 支持不同屏幕尺寸的适配
### 弹窗类型尺寸
#### 确认弹窗
- **容器尺寸**: 100vw × 100vh (全屏)
- **内容尺寸**: 618rpx × 557rpx
- **背景图片**: 618rpx × 557rpx
- **确认按钮**: 275rpx × 97rpx (位置: left: 318rpx, top: 408rpx)
- **取消按钮**: 279rpx × 101rpx (位置: left: 28rpx, top: 406rpx)
#### 无时间弹窗
- **容器尺寸**: 100vw × 100vh (全屏)
- **内容尺寸**: 618rpx × 460rpx
- **背景图片**: 618rpx × 460rpx
- **按钮**: 466rpx × 97rpx (位置: left: 76rpx, top: 312rpx)
# XingmaLab 弹窗组件库
这是一个弹窗组件库,包含多个弹窗组件,用于不同的业务场景。参考 `babyClass` 组件的实现方式,使用简洁的图片标签和样式结构。
## 组件列表
### 1. Xingmalabconfirmpop - 确认弹窗组件
用于显示确认对话框,支持确认和取消操作。
### 2. Xingmalabnotimepop - 无时间弹窗组件
用于显示无时间状态的弹窗,通常只有一个按钮。
## 功能特性
- 支持显示/隐藏控制
- 响应式设计
- 图片资源集中配置管理
- 支持版本控制和图片更新
- 统一的样式和交互规范
- 支持自定义文案和样式
- 参考 babyClass 组件的简洁实现方式
## 实现方式
### 背景遮罩实现
弹窗组件使用双层结构实现背景遮罩效果:
```vue
<template>
<view class="xingmalabconfirmpop">
<!-- 背景遮罩 -->
<view class="mask"></view>
<!-- 弹窗内容 -->
<view class="popup-content">
<!-- 弹窗图片和按钮 -->
</view>
</view>
</template>
```
### 遮罩样式
```less
.mask {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5); // 半透明黑色背景
}
.popup-content {
position: relative;
z-index: 1; // 确保内容在遮罩之上
}
```
### 图片标签使用
组件使用 `<image>` 标签而不是 `<span>` 标签,提供更好的图片显示效果:
```vue
<image
class="xingmalabconfirmpopbg"
:src="`${$baseUrl}${XINGMALAB_IMAGES.CONFIRM.BG}`"
mode="aspectFit"
></image>
```
### 图片配置管理
图片路径通过 `xingmalabImages.js` 文件集中管理:
```javascript
export const XINGMALAB_IMAGES = {
CONFIRM: {
BG: `XingmaLabPop/v1/XingmaLabConfirmPopBg.png`,
CONFIRM_BTN: `XingmaLabPop/v1/XingmaLabConfirmPopConfirmBtn.png`,
CANCEL_BTN: `XingmaLabPop/v1/XingmaLabCancelBtn.png`
},
NO_TIME: {
BG: `XingmaLabPop/v1/XingmaLabNoTimePopBg.png`,
BTN: `XingmaLabPop/v1/XingmaLabNoTimePopBtn.png`
}
}
```
### 样式结构
使用简洁的 Less 样式,直接定义尺寸和位置:
```less
.xingmalabconfirmpop {
width: 750rpx;
height: 1624rpx;
left: 0rpx;
top: 0rpx;
position: absolute;
z-index: 9999;
.xingmalabconfirmpopbg {
width: 618rpx;
height: 557rpx;
left: 0rpx;
top: 0rpx;
position: absolute;
}
}
```
## 使用方法
### Xingmalabconfirmpop 组件
```vue
<template>
<view>
<button @click="showConfirm = true">显示确认弹窗</button>
<Xingmalabconfirmpop
:visible="showConfirm"
title="确认操作"
confirm-text="确定"
cancel-text="取消"
@confirm="handleConfirm"
@cancel="handleCancel"
@close="showConfirm = false"
/>
</view>
</template>
<script setup>
import { ref } from 'vue'
import Xingmalabconfirmpop from '@/components/xingmaLab/Xingmalabconfirmpop.vue'
const showConfirm = ref(false)
const handleConfirm = () => {
console.log('用户点击了确认')
showConfirm.value = false
}
const handleCancel = () => {
console.log('用户点击了取消')
showConfirm.value = false
}
</script>
```
### Xingmalabnotimepop 组件
```vue
<template>
<view>
<button @click="showNoTime = true">显示无时间弹窗</button>
<Xingmalabnotimepop
:visible="showNoTime"
title="暂无时间"
@button-click="handleButtonClick"
@close="showNoTime = false"
/>
</view>
</template>
<script setup>
import { ref } from 'vue'
import Xingmalabnotimepop from '@/components/xingmaLab/Xingmalabnotimepop.vue'
const showNoTime = ref(false)
const handleButtonClick = () => {
console.log('用户点击了按钮')
showNoTime.value = false
}
</script>
```
## 在发布页面中的使用
弹窗组件在 `XingmaLabPublishPage.vue` 中的使用示例:
```vue
<!-- 确认发布弹窗 -->
<Xingmalabconfirmpop
:visible="showConfirmPopup"
title="确认发布"
confirm-text="确认发布"
cancel-text="取消"
@confirm="handleConfirmPublish"
@cancel="handleCancelPublish"
@close="showConfirmPopup = false"
/>
<!-- 无次数弹窗 -->
<Xingmalabnotimepop
:visible="showNoTimePopup"
title="发布次数已用完"
@button-click="handleNoTimeButtonClick"
@close="showNoTimePopup = false"
/>
```
## Props
### Xingmalabconfirmpop Props
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| visible | Boolean | false | 控制弹窗显示/隐藏 |
| title | String | '确认' | 弹窗标题 |
| confirmText | String | '确认' | 确认按钮文本 |
| cancelText | String | '取消' | 取消按钮文本 |
### Xingmalabnotimepop Props
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| visible | Boolean | false | 控制弹窗显示/隐藏 |
| title | String | '暂无时间' | 弹窗标题 |
## Events
### Xingmalabconfirmpop Events
| 事件名 | 说明 | 回调参数 |
|--------|------|----------|
| confirm | 点击确认按钮时触发 | - |
| cancel | 点击取消按钮时触发 | - |
| close | 点击遮罩层时触发 | - |
### Xingmalabnotimepop Events
| 事件名 | 说明 | 回调参数 |
|--------|------|----------|
| button-click | 点击按钮时触发 | - |
| close | 点击遮罩层时触发 | - |
## 图片配置
组件使用集中化的图片配置管理,所有图片路径都在 `xingmalabImages.js` 文件中配置:
```javascript
// 确认弹窗图片配置
CONFIRM: {
BG: `XingmaLabPop/v1/XingmaLabConfirmPopBg.png`,
CONFIRM_BTN: `XingmaLabPop/v1/XingmaLabConfirmPopConfirmBtn.png`,
CANCEL_BTN: `XingmaLabPop/v1/XingmaLabCancelBtn.png`
}
// 无时间弹窗图片配置
NO_TIME: {
BG: `XingmaLabPop/v1/XingmaLabNoTimePopBg.png`,
BTN: `XingmaLabPop/v1/XingmaLabNoTimePopBtn.png`
}
```
### 图片目录结构
```
static/
└── XingmaLabPop/
└── v1/
├── XingmaLabConfirmPopBg.png # 确认弹窗背景
├── XingmaLabConfirmPopConfirmBtn.png # 确认弹窗确认按钮
├── XingmaLabCancelBtn.png # 确认弹窗取消按钮
├── XingmaLabNoTimePopBg.png # 无时间弹窗背景
└── XingmaLabNoTimePopBtn.png # 无时间弹窗按钮
```
## 按钮位置配置
### 与React版本对比
为了确保Vue组件与原始React组件完全一致,按钮位置配置如下:
#### Xingmalabconfirmpop 按钮位置
| 按钮 | React版本 (px) | Vue版本 (rpx) | 说明 |
|------|----------------|---------------|------|
| 确认按钮 | left: 318, top: 408 | left: 318, top: 408 | 完全一致 |
| 取消按钮 | left: 28, top: 406 | left: 28, top: 406 | 完全一致 |
#### Xingmalabnotimepop 按钮位置
| 按钮 | React版本 (px) | Vue版本 (rpx) | 说明 |
|------|----------------|---------------|------|
| 按钮 | left: 76, top: 312 | left: 76, top: 312 | 完全一致 |
### 定位方式
- **React版本**: 使用 `position: absolute` 和固定的 `left``top`
- **Vue版本**: 使用 `position: absolute` 和相同的 `left``top`
- **单位转换**: React使用 `px`,Vue使用 `rpx`,但数值保持一致
### 尺寸配置
- **弹窗容器**: 750rpx × 1624rpx (与React的750px × 1624px对应)
- **背景图片**: 618rpx × 557rpx (确认弹窗) / 618rpx × 460rpx (无时间弹窗)
- **按钮尺寸**: 与React版本完全一致
## 样式配置
```javascript
// 按钮交互效果
transition: transform 0.2s ease;
&:active {
transform: scale(0.95);
}
```
## 版本控制
组件支持版本控制,通过修改 `xingmalabImages.js` 中的 `version` 变量来管理不同版本的图片资源:
```javascript
const version = 'v1' // 当前版本
```
## 与 babyClass 组件的对比
### 相似点
1. **图片标签使用**: 都使用 `<image>` 标签
2. **图片配置管理**: 都使用独立的图片配置文件
3. **样式结构**: 都使用简洁的 Less 样式
4. **版本控制**: 都支持版本管理
### 不同点
1. **业务逻辑**: babyClass 处理等级展示,xingmalab 处理弹窗交互
2. **图片数量**: babyClass 有多个等级图片,xingmalab 只有弹窗图片
3. **交互方式**: babyClass 主要是展示,xingmalab 主要是交互
## 注意事项
1. **图片资源**: 需要准备对应的背景图片文件并放置在正确的目录结构中
2. **样式单位**: 组件使用 rpx 单位,确保跨平台兼容性
3. **事件处理**: 组件会发射标准事件,父组件可以监听处理
4. **配置管理**: 所有图片路径都在 `xingmalabImages.js` 中集中管理
5. **版本更新**: 如需更新图片,只需替换文件并更新版本号即可
6. **组件复用**: 多个弹窗组件共享相同的配置管理机制
7. **发布流程**: 在发布页面中,弹窗组件用于二次确认和次数限制提示
8. **实现方式**: 参考 babyClass 组件的简洁实现,使用 image 标签和直接样式
## 文件结构
```
components/xingmaLab/
├── Xingmalabconfirmpop.vue # 确认弹窗组件
├── Xingmalabnotimepop.vue # 无时间弹窗组件
├── xingmalabImages.js # 图片配置文件
├── config.js # 旧版配置文件(已废弃)
├── README.md # 使用说明
└── IMAGES.md # 图片资源说明
```
## 迁移说明
从旧版配置系统迁移到新的图片配置系统:
1. **移除依赖**: 不再依赖 `config.js` 中的复杂配置
2. **简化导入**: 直接导入 `XINGMALAB_IMAGES` 常量
3. **简化样式**: 移除计算属性,直接使用 CSS 样式
4. **保持兼容**: 按钮位置和尺寸与 React 版本完全一致
<template>
<view v-if="visible" class="xingmalabconfirmpop" @click="handleOverlayClick">
<!-- 背景遮罩 -->
<view class="mask"></view>
<!-- 弹窗内容 -->
<view class="popup-content">
<image class="xingmalabconfirmpopbg" :src="`${$baseUrl}${XINGMALAB_IMAGES.CONFIRM.BG}`" mode="aspectFit"></image>
<image class="xingmalabconfirmpopconfirmbtn" :src="`${$baseUrl}${XINGMALAB_IMAGES.CONFIRM.CONFIRM_BTN}`"
mode="aspectFit" @click="handleConfirm"></image>
<image class="xingmalabcancelbtn" :src="`${$baseUrl}${XINGMALAB_IMAGES.CONFIRM.CANCEL_BTN}`" mode="aspectFit"
@click="handleCancel"></image>
</view>
</view>
</template>
<script setup>
import { defineProps, defineEmits, getCurrentInstance } from 'vue'
import { XINGMALAB_IMAGES } from './xingmalabImages.js'
// 获取全局属性
const { proxy } = getCurrentInstance()
const $baseUrl = proxy.$baseUrl
// 定义组件属性
const props = defineProps({
visible: {
type: Boolean,
default: false
},
title: {
type: String,
default: '确认'
},
confirmText: {
type: String,
default: '确认'
},
cancelText: {
type: String,
default: '取消'
}
})
// 定义组件事件
const emit = defineEmits(['confirm', 'cancel', 'close'])
// 确认按钮点击事件
const handleConfirm = () => {
emit('confirm')
}
// 取消按钮点击事件
const handleCancel = () => {
emit('cancel')
}
// 遮罩层点击事件
const handleOverlayClick = (event) => {
// 阻止事件冒泡
// event.stopPropagation()
// emit('close')
}
</script>
<style lang="less" scoped>
@import "../../common.less";
.xingmalabconfirmpop {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
.mask {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
}
.popup-content {
position: relative;
width: 618rpx;
height: 557rpx;
z-index: 1;
}
.xingmalabconfirmpopbg {
width: 618rpx;
height: 557rpx;
left: 0rpx;
top: 0rpx;
position: absolute;
}
.xingmalabconfirmpopconfirmbtn {
width: 275rpx;
height: 97rpx;
left: 318rpx;
top: 408rpx;
position: absolute;
transition: transform 0.2s ease;
&:active {
transform: scale(0.95);
}
}
.xingmalabcancelbtn {
width: 279rpx;
height: 101rpx;
left: 28rpx;
top: 406rpx;
position: absolute;
transition: transform 0.2s ease;
&:active {
transform: scale(0.95);
}
}
}
</style>
<template>
<view v-if="visible" class="xingmalabnotimepop" @click="handleOverlayClick">
<!-- 背景遮罩 -->
<view class="mask"></view>
<!-- 弹窗内容 -->
<view class="popup-content">
<image class="xingmalabnotimepopbg" :src="`${$baseUrl}${XINGMALAB_IMAGES.NO_TIME.BG}`" mode="aspectFit"></image>
<image class="xingmalabnotimepopbtn" :src="`${$baseUrl}${XINGMALAB_IMAGES.NO_TIME.BTN}`" mode="aspectFit" @click="handleButtonClick"></image>
</view>
</view>
</template>
<script setup>
import { defineProps, defineEmits, getCurrentInstance } from 'vue'
import { XINGMALAB_IMAGES } from './xingmalabImages.js'
// 获取全局属性
const { proxy } = getCurrentInstance()
const $baseUrl = proxy.$baseUrl
// 定义组件属性
const props = defineProps({
visible: {
type: Boolean,
default: false
},
title: {
type: String,
default: '暂无时间'
}
})
// 定义组件事件
const emit = defineEmits(['button-click', 'close'])
// 按钮点击事件
const handleButtonClick = () => {
emit('button-click')
}
// 遮罩层点击事件
const handleOverlayClick = (event) => {
// 阻止事件冒泡
// event.stopPropagation()
// emit('close')
}
</script>
<style lang="less" scoped>
@import "../../common.less";
.xingmalabnotimepop {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
.mask {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
}
.popup-content {
position: relative;
width: 618rpx;
height: 460rpx;
z-index: 1;
}
.xingmalabnotimepopbg {
width: 618rpx;
height: 460rpx;
left: 0rpx;
top: 0rpx;
position: absolute;
}
.xingmalabnotimepopbtn {
width: 466rpx;
height: 97rpx;
left: 76rpx;
top: 312rpx;
position: absolute;
transition: transform 0.2s ease;
&:active {
transform: scale(0.95);
}
}
}
</style>
\ No newline at end of file
const version = 'v1'
// Xingmalabconfirmpop 组件配置
export const xingmalabConfirmConfig = {
// 图片资源路径配置
images: {
// 弹窗背景图片
background: `XingmaLabPop/${version}/XingmaLabConfirmPopBg.png`,
// 确认按钮图片
confirmBtn: `XingmaLabPop/${version}/XingmaLabConfirmPopConfirmBtn.png`,
// 取消按钮图片
cancelBtn: `XingmaLabPop/${version}/XingmaLabCancelBtn.png`
},
// 弹窗尺寸配置
dimensions: {
width: 750,
height: 1624,
background: {
width: 618,
height: 557,
image: `XingmaLabPop/${version}/XingmaLabConfirmPopBg.png`
},
confirmBtn: {
width: 275,
height: 97,
left: 318,
top: 408,
image: `XingmaLabPop/${version}/XingmaLabConfirmPopConfirmBtn.png`
},
cancelBtn: {
width: 279,
height: 101,
left: 28,
top: 406,
image: `XingmaLabPop/${version}/XingmaLabCancelBtn.png`
}
},
// 文案配置
texts: {
defaultTitle: '确认',
defaultConfirmText: '确认',
defaultCancelText: '取消'
},
// 样式配置
styles: {
zIndex: 999,
borderRadius: '16rpx',
transition: 'all 0.3s ease'
}
}
// Xingmalabnotimepop 组件配置
export const xingmalabNoTimeConfig = {
// 图片资源路径配置
images: {
// 弹窗背景图片
background: `XingmaLabPop/${version}/XingmaLabNoTimePopBg.png`,
// 按钮图片
button: `XingmaLabPop/${version}/XingmaLabNoTimePopBtn.png`
},
// 弹窗尺寸配置
dimensions: {
width: 750,
height: 1624,
background: {
width: 618,
height: 460,
image: `XingmaLabPop/${version}/XingmaLabNoTimePopBg.png`
},
button: {
width: 466,
height: 97,
left: 76,
top: 312,
image: `XingmaLabPop/${version}/XingmaLabNoTimePopBtn.png`
}
},
// 文案配置
texts: {
defaultTitle: '暂无时间'
},
// 样式配置
styles: {
zIndex: 999,
borderRadius: '16rpx',
transition: 'all 0.3s ease'
}
}
// 获取完整图片URL
export const getImageUrl = (imagePath) => {
return `${imagePath}`
}
// 获取所有图片配置
export const getAllImages = () => {
return {
confirm: xingmalabConfirmConfig.images,
noTime: xingmalabNoTimeConfig.images
}
}
// 获取尺寸配置
export const getDimensions = (type = 'confirm') => {
return type === 'noTime' ? xingmalabNoTimeConfig.dimensions : xingmalabConfirmConfig.dimensions
}
// 获取样式配置
export const getStyles = (type = 'confirm') => {
return type === 'noTime' ? xingmalabNoTimeConfig.styles : xingmalabConfirmConfig.styles
}
// 获取指定组件的配置
export const getComponentConfig = (type = 'confirm') => {
return type === 'noTime' ? xingmalabNoTimeConfig : xingmalabConfirmConfig
}
// 获取指定组件的图片配置
export const getComponentImages = (type = 'confirm') => {
return type === 'noTime' ? xingmalabNoTimeConfig.images : xingmalabConfirmConfig.images
}
// 获取指定组件的完整图片URL
export const getComponentImageUrl = (type = 'confirm', imageKey) => {
const images = getComponentImages(type)
return images[imageKey] ? `${getImageUrl(images[imageKey])}` : ''
}
// 获取指定组件的所有图片URL
export const getAllComponentImageUrls = (type = 'confirm') => {
const images = getComponentImages(type)
const result = {}
Object.keys(images).forEach(key => {
result[key] = getComponentImageUrl(type, key)
})
return result
}
<template>
<view class="example-page">
<view class="header">
<text class="title">XingmaLab 弹窗组件示例</text>
</view>
<view class="content">
<view class="section">
<text class="section-title">确认弹窗组件</text>
<view class="button-group">
<button
class="btn btn-primary"
@click="showBasicConfirm = true"
>
基础确认弹窗
</button>
<button
class="btn btn-secondary"
@click="showCustomConfirm = true"
>
自定义文本弹窗
</button>
<button
class="btn btn-warning"
@click="showDeleteConfirm = true"
>
删除确认弹窗
</button>
</view>
</view>
<view class="section">
<text class="section-title">无时间弹窗组件</text>
<view class="button-group">
<button
class="btn btn-info"
@click="showNoTime = true"
>
显示无时间弹窗
</button>
<button
class="btn btn-success"
@click="showCustomNoTime = true"
>
自定义标题弹窗
</button>
</view>
</view>
</view>
<!-- 基础确认弹窗 -->
<Xingmalabconfirmpop
:visible="showBasicConfirm"
@confirm="handleBasicConfirm"
@cancel="handleBasicCancel"
@close="showBasicConfirm = false"
/>
<!-- 自定义文本弹窗 -->
<Xingmalabconfirmpop
:visible="showCustomConfirm"
title="自定义操作"
confirm-text="确定执行"
cancel-text="暂不执行"
@confirm="handleCustomConfirm"
@cancel="handleCustomCancel"
@close="showCustomConfirm = false"
/>
<!-- 删除确认弹窗 -->
<Xingmalabconfirmpop
:visible="showDeleteConfirm"
title="删除确认"
confirm-text="删除"
cancel-text="取消"
@confirm="handleDeleteConfirm"
@cancel="handleDeleteCancel"
@close="showDeleteConfirm = false"
/>
<!-- 无时间弹窗 -->
<Xingmalabnotimepop
:visible="showNoTime"
@button-click="handleNoTimeButtonClick"
@close="showNoTime = false"
/>
<!-- 自定义标题无时间弹窗 -->
<Xingmalabnotimepop
:visible="showCustomNoTime"
title="系统繁忙"
@button-click="handleCustomNoTimeButtonClick"
@close="showCustomNoTime = false"
/>
</view>
</template>
<script setup>
import { ref } from 'vue'
import Xingmalabconfirmpop from './Xingmalabconfirmpop.vue'
import Xingmalabnotimepop from './Xingmalabnotimepop.vue'
// 确认弹窗显示状态
const showBasicConfirm = ref(false)
const showCustomConfirm = ref(false)
const showDeleteConfirm = ref(false)
// 无时间弹窗显示状态
const showNoTime = ref(false)
const showCustomNoTime = ref(false)
// 基础确认弹窗事件处理
const handleBasicConfirm = () => {
uni.showToast({
title: '用户点击了确认',
icon: 'success'
})
showBasicConfirm.value = false
}
const handleBasicCancel = () => {
uni.showToast({
title: '用户点击了取消',
icon: 'none'
})
showBasicConfirm.value = false
}
// 自定义文本弹窗事件处理
const handleCustomConfirm = () => {
uni.showToast({
title: '执行自定义操作',
icon: 'success'
})
showCustomConfirm.value = false
}
const handleCustomCancel = () => {
uni.showToast({
title: '暂不执行操作',
icon: 'none'
})
showCustomConfirm.value = false
}
// 删除确认弹窗事件处理
const handleDeleteConfirm = () => {
uni.showModal({
title: '提示',
content: '确定要删除这个项目吗?',
success: (res) => {
if (res.confirm) {
uni.showToast({
title: '删除成功',
icon: 'success'
})
}
}
})
showDeleteConfirm.value = false
}
const handleDeleteCancel = () => {
uni.showToast({
title: '取消删除',
icon: 'none'
})
showDeleteConfirm.value = false
}
// 无时间弹窗事件处理
const handleNoTimeButtonClick = () => {
uni.showToast({
title: '用户点击了按钮',
icon: 'success'
})
showNoTime.value = false
}
const handleCustomNoTimeButtonClick = () => {
uni.showToast({
title: '系统繁忙,请稍后再试',
icon: 'none'
})
showCustomNoTime.value = false
}
</script>
<style lang="less" scoped>
.example-page {
padding: 40rpx;
background-color: #f5f5f5;
min-height: 100vh;
}
.header {
text-align: center;
margin-bottom: 60rpx;
.title {
font-size: 48rpx;
font-weight: bold;
color: #333;
}
}
.content {
.section {
margin-bottom: 60rpx;
.section-title {
display: block;
font-size: 36rpx;
font-weight: 600;
color: #333;
margin-bottom: 30rpx;
padding-left: 20rpx;
border-left: 8rpx solid #007aff;
}
.button-group {
display: flex;
flex-direction: column;
gap: 30rpx;
.btn {
padding: 30rpx;
border-radius: 16rpx;
border: none;
font-size: 32rpx;
font-weight: 500;
&.btn-primary {
background-color: #007aff;
color: white;
}
&.btn-secondary {
background-color: #34c759;
color: white;
}
&.btn-warning {
background-color: #ff3b30;
color: white;
}
&.btn-info {
background-color: #5ac8fa;
color: white;
}
&.btn-success {
background-color: #4cd964;
color: white;
}
&:active {
opacity: 0.8;
}
}
}
}
}
</style>
const version = 'v1'
// XingmaLab 弹窗组件图片资源常量
export const XINGMALAB_IMAGES = {
// 确认弹窗相关图片
CONFIRM: {
BG: `XingmaLabPop/${version}/XingmaLabConfirmPopBg.png`,
CONFIRM_BTN: `XingmaLabPop/${version}/XingmaLabConfirmPopConfirmBtn.png`,
CANCEL_BTN: `XingmaLabPop/${version}/XingmaLabCancelBtn.png`
},
// 无时间弹窗相关图片
NO_TIME: {
BG: `XingmaLabPop/${version}/XingmaLabNoTimePopBg.png`,
BTN: `XingmaLabPop/${version}/XingmaLabNoTimePopBtn.png`
}
}
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -51,6 +51,12 @@
"navigationStyle": "custom"
}
},
{
"path": "pages/xingmaLab/xingmaLab",
"style": {
"navigationStyle": "custom"
}
},
{
"path": "pages/goodsDetail/goodsDetail",
"style": {
......@@ -163,17 +169,32 @@
}
},
{
"path" : "pages/testPage/testPage",
"style" :
{
"navigationBarTitleText" : ""
"path": "pages/testPage/testPage",
"style": {
"navigationBarTitleText": ""
}
},
{
"path" : "pages/thirdJumpMiddlePage/thirdJumpMiddlePage",
"style" :
{
"navigationBarTitleText" : ""
"path": "pages/thirdJumpMiddlePage/thirdJumpMiddlePage",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/XingmaLabDetailPage/XingmaLabDetailPage",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom",
"enableShare": true,
"shareAppMessage": true,
"shareTimeline": false
}
},
{
"path": "pages/XingmaLabPublishPage/XingmaLabPublishPage",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom"
}
}
],
......
# 星妈实验室详情页面 (XingmaLabDetailPage)
## 概述
这是一个基于Vue 3 Composition API开发的星妈实验室详情页面组件,用于展示藏品详情、点赞和分享功能。
## 功能特性
- **藏品展示**:展示藏品图片、编号和标题
- **动态时间**:自动显示当前时间
- **点赞功能**:支持点赞/取消点赞状态切换
- **分享功能**:集成uni-app分享API
- **响应式设计**:支持不同屏幕尺寸的适配
- **交互动画**:包含淡入动画和悬停效果
## 文件结构
```
XingmaLabDetailPage/
├── XingmaLabDetailPage.vue # 主组件文件
├── XingmaLabDetailPage.less # 样式文件
├── config.js # 配置文件
└── README.md # 说明文档
```
## 使用方法
### 1. 基本使用
```vue
<template>
<XingmaLabDetailPage />
</template>
<script setup>
import XingmaLabDetailPage from '@/pages/XingmaLabDetailPage/XingmaLabDetailPage.vue'
</script>
```
### 2. 功能说明
#### 藏品信息展示
- 藏品背景图片
- 藏品主图片
- 藏品编号(唯一标识)
- 藏品标题
#### 交互功能
- **点赞按钮**:点击切换点赞状态,显示相应提示
- **分享按钮**:调用uni-app分享功能
#### 时间显示
- 自动显示当前日期和地点
- 格式:YYYY-MM-DD 北京
## 配置说明
### 图片资源配置
`config.js` 中配置图片资源路径:
```javascript
export const xingmaLabDetailConfig = {
baseUrl: 'https://factory-walk.feihe.com',
images: {
background: '/farqbxzczytcami/images/XingmaLabDetailPage/XingmaLabDetailPageBg.png',
picBg: '/farqbxzczytcami/images/XingmaLabDetailPage/XingmaLabDetailPagePicBg.png',
pic: '/farqbxzczytcami/images/XingmaLabDetailPage/XingmaLabDetailPagePic.png',
// ... 其他图片配置
}
}
```
### 文案配置
```javascript
texts: {
title: '快来用星妈会小程序',
collectionNumber: '唯一藏品编号:'
}
```
## 样式定制
### 主要样式类
- `.xingmalabdetailpage`: 主容器
- `.xingmalabdetailpagebg`: 背景图片
- `.xingmalabdetailpagepic`: 藏品主图片
- `.xingmalabdetailpagepicbg`: 图片背景框
- `.xingmalabdetailpagebottomcon`: 底部操作容器
- `.xingmalabdetailpagebottomconlikebtn`: 点赞按钮
- `.xingmalabdetailpagebottomconsharebtn`: 分享按钮
### 响应式断点
- 默认:750rpx 宽度(移动端)
- 响应式:小于750px时自动适配为100vw
### 动画效果
- `fadeIn`: 页面淡入动画
- `slideInUp`: 图片和底部容器从下往上滑入动画
- 点赞状态变化时的视觉反馈
## 交互功能
### 点赞功能
```javascript
const handleLikeClick = () => {
isLiked.value = !isLiked.value
// 显示点赞状态提示
uni.showToast({
title: isLiked.value ? '已点赞' : '取消点赞',
icon: 'success'
})
}
```
### 分享功能
```javascript
const handleShareClick = () => {
// 调用uni-app分享API
uni.showShareMenu({
withShareTicket: true,
menus: ['shareAppMessage', 'shareTimeline']
})
}
```
## 开发规范
- 使用Vue 3 Composition API
- 遵循项目ESLint和Prettier规范
- 使用Less预处理器
- 支持uni-app跨平台开发
- 使用响应式数据管理状态
## 注意事项
1. 确保图片资源路径正确配置
2. 图片资源需要支持HTTPS协议
3. 组件使用绝对定位布局,注意父容器样式设置
4. 点赞状态会保存在组件内部,页面刷新后会重置
5. 时间显示基于客户端时间,确保设备时间准确
## 更新日志
- v1.0.0: 初始版本,支持藏品展示、点赞和分享功能
- 支持动态资源管理和响应式设计
- 集成uni-app分享API
- 添加交互动画和状态反馈
// 星妈实验室详情页面样式
.xingmalabdetailpage {
width: 750rpx;
height: calc(100vh - 218rpx);
left: 0rpx;
top: 0rpx;
overflow-y: auto;
position: absolute;
// 左上角头部区域 - 脱离滚动
.xingmalabdetailpageheader {
position: fixed;
top: 0;
left: 0;
width: 750rpx;
height: 200rpx;
z-index: 100;
display: flex;
align-items: center;
// justify-content: space-between;
padding: 80rpx 40rpx 30rpx 40rpx;
background-color: #fff;
box-sizing: border-box;
// 返回按钮
.xingmalabdetailpagebackbtn {
width: 20rpx;
height: 33rpx;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
// cursor: pointer;
z-index: 101;
margin-right: 35rpx;
}
// 用户信息
.xingmalabdetailpageuserinfo {
display: flex;
align-items: center;
gap: 10rpx;
// 头像
.xingmalabdetailpageavatar {
width: 66rpx;
height: 66rpx;
border-radius: 50%;
object-fit: contain;
background-color: #f8f9fa;
}
// 昵称
.xingmalabdetailpagenickname {
font-size: 28rpx;
font-weight: 600;
color: #1d1e25;
text-shadow: 0 2rpx 4rpx rgba(255, 255, 255, 0.8);
max-width: 300rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
.xingmalabdetailpagebg {
width: 750rpx;
height: 1842rpx;
left: 0rpx;
top: 0rpx;
position: absolute;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
// 文本和时间容器
.xingmalabdetailpagecontent {
width: 688rpx;
left: 31rpx;
top: 1232rpx;
position: absolute;
// 确保内容不被底部固定容器遮挡
z-index: 1;
}
.xingmalabdetailpagetext {
width: 100%;
min-height: 131rpx;
white-space: pre-wrap;
position: relative;
font-size: 32rpx;
line-height: 50rpx;
color: rgba(29, 30, 37, 1);
text-align: left;
word-wrap: break-word;
word-break: break-all;
// 移除固定高度,让内容自适应
height: auto;
display: block;
}
.xingmalabdetailpagepicbg {
width: 730rpx;
height: 1030rpx;
left: 10rpx;
top: 191rpx;
position: absolute;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
.xingmalabdetailpagepic {
width: 688rpx;
height: 914rpx;
left: 31rpx;
top: 207rpx;
border-radius: 24rpx;
position: absolute;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
background-color: #f8f9fa;
}
.xingmalabdetailpagenum {
width: 348rpx;
height: 26rpx;
left: 207rpx;
top: 1144rpx;
position: absolute;
font-size: 28rpx;
line-height: 26rpx;
color: rgba(178, 124, 30, 1);
text-align: center;
}
.xingmalabdetailpagebottomcon {
width: 750rpx;
height: 218rpx;
left: 0rpx;
bottom: 0rpx;
background-color: #fff;
position: fixed;
.xingmalabdetailpagebottomconbg {
width: 750rpx;
height: 218rpx;
left: 0rpx;
top: 0rpx;
position: absolute;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
.xingmalabdetailpagebottomconlikebtn {
width: 119rpx;
height: 44rpx;
left: 135rpx;
top: 56rpx;
position: absolute;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
transition: opacity 0.3s ease;
&:hover {
opacity: 0.8;
}
}
.xingmalabdetailpagebottomconsharebtn {
width: 121rpx;
height: 42rpx;
left: 498rpx;
top: 58rpx;
position: absolute;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
border: none;
padding: 0;
margin: 0;
line-height: 1;
font-size: 0;
color: transparent;
background-color: transparent !important;
transition: opacity 0.3s ease;
// &:hover {
// opacity: 0.8;
// }
&::after {
border: none !important;
}
}
}
.xingmalabdetailpagetime {
width: 203rpx;
height: 23rpx;
margin-top: 20rpx;
position: relative;
font-size: 24rpx;
line-height: 23rpx;
color: rgba(111, 109, 103, 1);
display: block;
}
}
// 手机号授权按钮样式
.phone-auth-btn-cover {
background: transparent !important;
border: none !important;
padding: 0 !important;
margin: 0 !important;
line-height: 1 !important;
font-size: 0 !important;
color: transparent !important;
&::after {
border: none !important;
}
}
// 授权覆盖层样式
.auth-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 10;
.auth-like-btn {
position: absolute;
width: 119rpx;
height: 44rpx;
left: 135rpx;
top: 56rpx;
}
.auth-share-btn {
position: absolute;
width: 121rpx;
height: 42rpx;
left: 498rpx;
top: 58rpx;
}
}
This diff is collapsed.
const version = 'v1'
// 星妈实验室详情页面配置
export const xingmaLabDetailConfig = {
// 图片资源路径配置
images: {
// 背景图片
background: `XingmaLabDetailPage/${version}/XingmaLabDetailPageBg.png`,
// 图片背景
picBg: `XingmaLabDetailPage/${version}/XingmaLabDetailPagePicBg.png`,
// 主图片
pic: `XingmaLabDetailPage/${version}/XingmaLabDetailPagePic.png`,
// 底部容器背景
bottomConBg: `XingmaLabDetailPage/${version}/XingmaLabDetailPageBottomConBg.png`,
// 收藏按钮
bottomConLikeBtn: `XingmaLabDetailPage/${version}/XingmaLabDetailPageBottomConLikeBtn.png`,
// 已收藏按钮
bottomConLikeBtnSel: `XingmaLabDetailPage/${version}/XingmaLabDetailPageBottomConLikeBtnSel.png`,
// 分享按钮
bottomConShareBtn: `XingmaLabDetailPage/${version}/XingmaLabDetailPageBottomConShareBtn.png`,
// 返回按钮
backBtn: `XingmaLabDetailPage/${version}/XingmaLabDetailPageBackBtn.png`
},
// 文案配置
texts: {
title: '快来用星妈会小程序',
collectionNumber: '唯一藏品编号:'
},
// 页面配置
page: {
width: 750,
height: 1624
}
}
// 获取完整图片URL
export const getImageUrl = (imagePath) => {
return `${imagePath}`
}
// 获取页面尺寸配置
export const getPageConfig = () => {
return xingmaLabDetailConfig.page
}
# 星妈实验室发布页面更新日志
## 版本 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. 遵循项目开发规范
# 星妈实验室发布页面
## 功能概述
这是一个星妈实验室的藏品发布页面,支持用户上传藏品图片、编辑文案介绍,并进行发布。
## 主要功能
### 1. 藏品图片上传
- **限制数量**:仅限上传1张图片
- **尺寸限制**:固定宽度,不限制高度比例
- **大小限制**:可配置最大文件大小(默认10MB)
- **格式支持**:jpg、png、jpeg
- **交互方式**:点击上传区域拉起相机/相册选择器
- **错误提示**:超过大小限制时显示"照片太大啦,换一张试试吧~"
### 2. 重新上传功能
- **触发方式**:点击"重新上传"按钮
- **选择方式**:拉起相机/相册图库
- **格式限制**:jpg/png/jpeg
- **位置**:已上传图片右下角
### 3. 藏品文案介绍
- **字数限制**:最多1000字
- **输入方式**:点击拉起输入键盘
- **内容类型**:纯文本,不支持富文本
- **字数提示**:实时显示当前字数/最大字数
- **超限提示**:达到上限时显示"字数已达上限"
### 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. 显示发布成功页面
## 注意事项
- 保持原有样式和图片格局不变
- 所有交互都遵循微信小程序规范
- 错误处理完善,用户体验友好
- 支持响应式布局
- 遵循Vue 3 Composition API开发规范
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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