优化我的收藏,活动报名,我的活动页面,活动页面页面,新增加载更多
| | |
| | | params: params, |
| | | }); |
| | | } |
| | | /** |
| | | * 用户活动收藏列表 |
| | | * @param {Object} param |
| | | */ |
| | | export function getActivityCollectList(param){ |
| | | |
| | | } |
| | | /** |
| | | * 收藏活动 |
| | | * @param {Object} param |
| | | */ |
| | | |
| | | export function activityCollection(param){ |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 取消收藏 |
| | | * |
| | | */ |
| | | export function collectCancel(param){ |
| | | return http.request({ |
| | | url: "/lmk/my-activity/collectCancel", |
| | | method: Method.POST, |
| | | needToken: true, |
| | | data:param |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * 取消报名 |
| | |
| | | * |
| | | * @param params |
| | | */ |
| | | export function getActivityReportList() { |
| | | export function getActivityReportList(param) { |
| | | return http.request({ |
| | | url: "/lmk/activityReport", |
| | | method: Method.GET, |
| | | needToken: true |
| | | needToken: true, |
| | | params:param |
| | | }); |
| | | } |
| | | |
| | |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * 获得我的收藏按传入类型 video,activity,store |
| | | * @param {Object} param |
| | | */ |
| | | export function getMyCollectList(param){ |
| | | return http.request({ |
| | | url: "/lmk/my-collect/getMyCollectList", |
| | | method: Method.GET, |
| | | needToken: true, |
| | | params: param |
| | | }); |
| | | } |
| | |
| | | }); |
| | | } |
| | | |
| | | export function getPreviewUrl(params){ |
| | | return http.request({ |
| | | url: `${api.common}/lmk/file/preview`, |
| | | method: Method.POST, |
| | | data:params |
| | | }); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取文件访问地址 |
| | | */ |
| | |
| | | needToken: true |
| | | }) |
| | | |
| | | } |
| | | |
| | | export function restPassword(param){ |
| | | return http.request({ |
| | | url:'/lmk/lmk-user-permissions/restPassword/'+param, |
| | | method: Method.PUT, |
| | | needToken: true |
| | | }) |
| | | } |
| | |
| | | }, { |
| | | "path": "activity/detail", |
| | | "style": { |
| | | "navigationBarTitleText": "活动详情" |
| | | } |
| | | }, { |
| | | "path": "activity/myActivity", |
| | | "style": { |
| | | "navigationBarTitleText": "我的活动", |
| | | "navigationBarTitleText": "活动详情", |
| | | "enablePullDownRefresh": true, //下拉刷新 |
| | | "navigationStyle": "custom", |
| | | "componentPlaceholder": { |
| | | "u-form": "view", |
| | | "u-form-item": "view", |
| | |
| | | "u-action-sheet": "view", |
| | | "u-checkbox-group": "view", |
| | | "u-checkbox": "view", |
| | | "u-navbar": "view" |
| | | "u-navbar": "view", |
| | | "u-button": "view", |
| | | "u-image": "view" |
| | | } |
| | | } |
| | | }, { |
| | | "path": "activity/myActivity", |
| | | "style": { |
| | | "navigationBarTitleText": "我的活动", |
| | | "enablePullDownRefresh": true, //下拉刷新 |
| | | "componentPlaceholder": { |
| | | "u-form": "view", |
| | | "u-form-item": "view", |
| | | "u-input": "view", |
| | | "u-icon": "view", |
| | | "u-action-sheet": "view", |
| | | "u-checkbox-group": "view", |
| | | "u-checkbox": "view", |
| | | "u-navbar": "view", |
| | | "u-button": "view", |
| | | "u-image": "view" |
| | | } |
| | | } |
| | | }, { |
| | |
| | | "style": { |
| | | "navigationBarTitleText": "活动", |
| | | "enablePullDownRefresh": true, //下拉刷新 |
| | | "navigationStyle": "custom", |
| | | "componentPlaceholder": { |
| | | "u-form": "view", |
| | | "u-form-item": "view", |
| | |
| | | "u-action-sheet": "view", |
| | | "u-checkbox-group": "view", |
| | | "u-checkbox": "view", |
| | | "u-navbar": "view" |
| | | "u-navbar": "view", |
| | | "u-button": "view", |
| | | "u-image": "view", |
| | | "u-loadmore": "view" |
| | | } |
| | | } |
| | | }, { |
| | | "path": "myCollect/myCollect", |
| | | "style": { |
| | | "navigationBarTitleText": "我的收藏", |
| | | "enablePullDownRefresh": true, //下拉刷新 |
| | | "componentPlaceholder": { |
| | | "u-icon": "view", |
| | | "u-button": "view", |
| | |
| | | "u-popup": "view", |
| | | "u-search": "view", |
| | | "u-loading": "view", |
| | | "u-navbar": "view" |
| | | "u-navbar": "view", |
| | | "u-image": "view", |
| | | "u-loadmore": "view" |
| | | |
| | | } |
| | | |
| | | } |
| | |
| | | <!-- 动态封面区域 --> |
| | | <view class="cover-container"> |
| | | <!-- 图片类型 --> |
| | | <block v-if="activityInfo.coverType === '图片' || activityInfo.coverType === '视频'"> |
| | | <image :src="getPreviewUrl(activityInfo.cover)" mode="aspectFill" class="activity-cover" /> |
| | | <block v-if="activityInfo.coverType === '图片'"> |
| | | <image :src="getUrl(activityInfo.cover)" class="activity-cover" /> |
| | | </block> |
| | | <block v-if=" activityInfo.coverType === '视频'"> |
| | | <video :src="getUrl(item.cover)" |
| | | @play="handleVideoPlay" class="activity-cover"></video> |
| | | </block> |
| | | <!-- 文字类型 --> |
| | | <block v-if="activityInfo.coverType === '文字'"> |
| | |
| | | </view> |
| | | <!-- 报名状态 --> |
| | | <view class="status-bar" :style="{ backgroundColor: statusBarColor }"> |
| | | <button class="signup-btn" @click="activityReport()" :disabled="reportBtn" >{{ reportBtn ? '已报名': '立即报名'}}</button> |
| | | <u-button class="signup-btn" @click.stop="activityReport()" :disabled="reportBtn" >{{ reportBtn ? '已报名': '立即报名'}}</u-button> |
| | | <u-button class="signup-btn" @click.stop="collect()">{{ isCollect ? '取消收藏' : '收藏' }}</u-button> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import {getPreviewUrl} from '@/api/common.js' |
| | | import UButton from '@/uview-components/uview-ui/components/u-button/u-button.vue'; |
| | | import {changeCollect} from '@/api/collect.js' |
| | | import {getFilePreviewUrl} from '@/api/common.js' |
| | | import { |
| | | getActivityDetail, |
| | | activityReport |
| | | } from '@/api/activity.js'; |
| | | export default { |
| | | components: { |
| | | UButton |
| | | }, |
| | | data() { |
| | | return { |
| | | activityInfo: { |
| | |
| | | activityType: '', |
| | | limitUserNum:'', |
| | | }, |
| | | isCollect:false, |
| | | reportBtn:false, |
| | | detailId: null, // 存储接收的参数 |
| | | reportFrom: { |
| | | activityId: '', |
| | | cancel: false, //报名接口默认我false |
| | | } |
| | | }, |
| | | collectForm:{ |
| | | collectType:'', |
| | | refId:'', |
| | | }, |
| | | }; |
| | | }, |
| | | onLoad(options) { |
| | |
| | | } |
| | | }, |
| | | methods: { |
| | | collect(){ |
| | | this.collectForm.collectType = 'activity' |
| | | this.collectForm.refId = this.detailId |
| | | changeCollect(this.collectForm).then(res=>{ |
| | | if (res.statusCode === 200) { |
| | | this.isCollect = true; |
| | | uni.showToast({ |
| | | title: res.data.msg, // 提示文字 |
| | | icon: 'success', // 图标类型(success/loading/none) |
| | | mask: true // 是否显示透明蒙层(防止触摸穿透) |
| | | }); |
| | | } |
| | | }) |
| | | }, |
| | | //报名 |
| | | activityReport() { |
| | | this.reportFrom.activityId = this.detailId |
| | |
| | | |
| | | }) |
| | | }, |
| | | getPreviewUrl(params){ |
| | | return getPreviewUrl(params); |
| | | getUrl(params){ |
| | | getFilePreviewUrl(params).then(res =>{ |
| | | return res.data.data |
| | | }) |
| | | }, |
| | | getActivityDetail(id) { |
| | | uni.showLoading({ |
| | |
| | | }); |
| | | getActivityDetail(id).then(res => { |
| | | uni.hideLoading(); |
| | | console.log(res.data) |
| | | if (res.statusCode === 200) { |
| | | //赋值 |
| | | this.activityInfo.coverType = res.data.data.coverType; |
| | |
| | | this.activityInfo.activityType = res.data.data.activityType; |
| | | this.activityInfo.limitUserNum = res.data.data.limitUserNum; |
| | | this.reportBtn = res.data.data.isReport; |
| | | |
| | | this.isCollect = res.data.data.isCollect; |
| | | } |
| | | }) |
| | | }, |
| | |
| | | height: 40rpx; |
| | | margin-bottom: 10rpx; |
| | | } |
| | | .btn-container { |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | margin-top: 8px; /* 与上方标题保持间距 */ |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <view class="activity-container"> |
| | | <u-navbar :is-back="true" title="我的活动" title-color="#333" back-icon-color="#333"></u-navbar> |
| | | |
| | | <!-- 顶部 Tab 导航 --> |
| | | <view class="tab-nav"> |
| | |
| | | <!-- 封面区域 --> |
| | | <view class="cover-container"> |
| | | <block v-if="item.coverType === '图片' || item.coverType === '视频'"> |
| | | <image :src="getPreviewUrl(item.cover)" mode="aspectFill" class="activity-cover" /> |
| | | <image :src="getUrl(item.cover)" mode="aspectFill" class="activity-cover" /> |
| | | </block> |
| | | <block v-if="item.coverType === '文字'"> |
| | | <view class="activity-cover text-cover">{{ item.cover }}</view> |
| | |
| | | > |
| | | <view class="cover-container"> |
| | | <block v-if="item.coverType === '图片' || item.coverType === '视频'"> |
| | | <image :src="getPreviewUrl(item.cover)" mode="aspectFill" class="activity-cover" /> |
| | | <image :src="getUrl(item.cover)" mode="aspectFill" class="activity-cover" /> |
| | | </block> |
| | | <block v-if="item.coverType === '文字'"> |
| | | <view class="activity-cover text-cover">{{ item.cover }}</view> |
| | |
| | | > |
| | | <view class="cover-container"> |
| | | <block v-if="item.coverType === '图片' || item.coverType === '视频'"> |
| | | <image :src="getPreviewUrl(item.cover)" mode="aspectFill" class="activity-cover" /> |
| | | <image :src="getUrl(item.cover)" mode="aspectFill" class="activity-cover" /> |
| | | </block> |
| | | <block v-if="item.coverType === '文字'"> |
| | | <view class="activity-cover text-cover">{{ item.cover }}</view> |
| | |
| | | |
| | | <script> |
| | | import {getMyActivityList,collectCancel,activityCancel} from '@/api/activity.js' |
| | | import {getPreviewUrl} from '@/api/common.js' |
| | | import {getFilePreviewUrl} from '@/api/common.js' |
| | | export default { |
| | | data() { |
| | | return { |
| | |
| | | } |
| | | }) |
| | | }, |
| | | getPreviewUrl(params){ |
| | | return getPreviewUrl(params); |
| | | getUrl(params){ |
| | | getFilePreviewUrl(params).then(res =>{ |
| | | return res.data.data |
| | | }) |
| | | }, |
| | | switchTab(index) { |
| | | if (this.currentTab !== index) { |
| | |
| | | <template> |
| | | <view class="wrapper"> |
| | | <u-navbar :is-back="true" title="活动"> |
| | | </u-navbar> |
| | | <!-- 内容区域 --> |
| | | <scroll-view scroll-y class="content" :style="{ paddingBottom: safeAreaInsets.bottom + 'px' }"> |
| | | <scroll-view scroll-y class="content" style="height: 100vh;" @scrolltolower="loadMore" |
| | | :lower-threshold="100" |
| | | > |
| | | <view class="waterfall"> |
| | | <view class="column" v-for="(column, index) in columns" :key="index"> |
| | | <!-- 遍历每列内容 --> |
| | | <view class="item" v-for="(item, idx) in column" :key="item.id" @click="handleItemClick(item)"> |
| | | <!-- 图片类型 --> |
| | | <image v-if="item.type === '图片'" :src="item.content" mode="widthFix" class="media" |
| | | @load="imageLoad" :data-item="item" /> |
| | | <image v-if="item.type === '图片'" :src="getUrl(item.cover)" mode="widthFix" class="media" |
| | | @load="imageLoad" :data-item="item" :style="{ height: item.height + 'px' }" /> |
| | | |
| | | <!-- 视频类型 --> |
| | | <video v-if="item.type === '视频'" :src="item.content" class="media" controls |
| | | :poster="item.poster" @play="handleVideoPlay"></video> |
| | | <video v-if="item.type === '视频'" :src="getUrl(item.cover)" class="media" controls |
| | | :poster="item.poster" @play="handleVideoPlay" |
| | | :style="{ height: item.height + 'px' }"></video> |
| | | |
| | | <!-- 文字类型 --> |
| | | <view v-if="item.type === '文字'" class="text-content"> |
| | | <text class="title">{{ item.cover }}</text> |
| | | </view> |
| | | <text class="title">{{ item.title }}</text> |
| | | |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <!-- <view style="height: 150rpx;"></view> --> |
| | | <!-- 改进的加载更多提示 --> |
| | | <view class="load-more"> |
| | | <u-loadmore |
| | | v-if="mockData.length > 0" |
| | | :status="loading ? 'loading' : noMore ? 'nomore' : 'loadmore'" |
| | | :load-text="{ |
| | | loadmore: '上拉加载更多', |
| | | loading: '正在加载', |
| | | nomore: '没有更多了' |
| | | }" |
| | | /> |
| | | </view> |
| | | <view style="height:150rpx"> |
| | | |
| | | </view> |
| | | </scroll-view> |
| | | |
| | | |
| | | |
| | | <custom-tabbar bgColor="#ffffff" selected="activity"></custom-tabbar> |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | </view> |
| | | |
| | | |
| | | </template> |
| | | |
| | | <script> |
| | | import { |
| | | changeCollect |
| | | } from '@/api/collect.js' |
| | | import { |
| | | getFilePreviewUrl |
| | | } from '@/api/common.js' |
| | | import UButton from '@/uview-components/uview-ui/components/u-button/u-button.vue'; |
| | | import UImage from '@/uview-components/uview-ui/components/u-image/u-image.vue'; |
| | | import ULoadmore from '@/uview-components/uview-ui/components/u-loadmore/u-loadmore.vue' |
| | | import { |
| | | getActivityReportList, |
| | | } from '@/api/activity.js'; |
| | | export default { |
| | | components: { |
| | | UImage, |
| | | UButton, |
| | | ULoadmore |
| | | }, |
| | | data() { |
| | | return { |
| | | columns: [ |
| | |
| | | ], // 双列布局 |
| | | mockData: [], |
| | | colHeight: [0, 0], // 记录各列高度 |
| | | |
| | | baseImageHeight: 300, // 图片基础高度 |
| | | baseVideoHeight: 350, // 视频基础高度 |
| | | baseTextHeight: 120, // 文字基础高度 |
| | | query: { |
| | | pageNumber: 1, |
| | | pageSize: 8, |
| | | }, |
| | | loading: false, // 是否正在加载 |
| | | noMore: false, // 是否没有更多数据 |
| | | total: 0 // 总数据量 |
| | | }; |
| | | }, |
| | | onLoad() { |
| | | this.getActivityList(); |
| | | //获得userId |
| | | }, |
| | | methods: { |
| | | getUrl(params) { |
| | | getFilePreviewUrl(params).then(res => { |
| | | return res.data.data |
| | | }) |
| | | }, |
| | | |
| | | /** |
| | | * 下拉刷新时 |
| | | */ |
| | | onPullDownRefresh() { |
| | | this.query.pageNumber = 1; // 重置页码 |
| | | this.noMore = false; |
| | | this.mockData = []; // 清空数据 |
| | | this.getActivityList(); |
| | | }, |
| | | getActivityList() { |
| | | uni.showLoading({ |
| | | title: '加载中' |
| | | }); |
| | | const mock = []; |
| | | getActivityReportList().then(res => { |
| | | uni.hideLoading(); |
| | | if (res.statusCode === 200) { |
| | | for (const value of res.data.data) { |
| | | const type = value.coverType; |
| | | const baseHeight = type === '文字' ? 120 : 350; |
| | | mock.push({ |
| | | id: value.id, |
| | | type: type, |
| | | cover: value.cover, |
| | | height: baseHeight, |
| | | title: value.activityName, |
| | | content: value.activityContent, |
| | | poster: '', |
| | | }); |
| | | } |
| | | } |
| | | this.mockData = mock; |
| | | this.layoutItems(); |
| | | }) |
| | | loadMore() { |
| | | |
| | | // 显示加载状态 |
| | | this.loading = true; |
| | | |
| | | // 延迟执行让UI有反应时间 |
| | | setTimeout(() => { |
| | | this.query.pageNumber += 1; |
| | | this.getActivityList(); |
| | | }, 300); |
| | | }, |
| | | async getActivityList() { |
| | | |
| | | try { |
| | | |
| | | const res = await getActivityReportList(this.query); |
| | | this.loading = false; |
| | | if (res.statusCode === 200) { |
| | | const newData = res.data.data.map(value => ({ |
| | | id: value.id, |
| | | type: value.coverType, |
| | | cover: value.cover, |
| | | height: value.coverType === '图片' ? this.baseImageHeight : |
| | | value.coverType === '视频' ? this.baseVideoHeight : this.baseTextHeight, |
| | | title: value.activityName, |
| | | content: value.activityContent, |
| | | poster: '', |
| | | })); |
| | | |
| | | // 更新总数据量 |
| | | this.total = res.data.total || 0; |
| | | |
| | | // 追加或替换数据 |
| | | this.mockData = this.query.pageNumber === 1 |
| | | ? newData |
| | | : [...this.mockData, ...newData]; |
| | | |
| | | // 判断是否还有更多数据 |
| | | this.noMore = newData.length < this.query.pageSize || |
| | | this.mockData.length >= this.total; |
| | | |
| | | // 布局更新 |
| | | this.$nextTick(() => { |
| | | this.layoutItems(); |
| | | }); |
| | | } |
| | | } catch (error) { |
| | | console.error('加载失败:', error); |
| | | // 失败时回退页码 |
| | | if (this.query.pageNumber > 1) { |
| | | this.query.pageNumber -= 1; |
| | | } |
| | | } finally { |
| | | this.loading = false; |
| | | uni.hideLoading(); |
| | | uni.stopPullDownRefresh(); |
| | | } |
| | | }, |
| | | // 图片加载完成回调 |
| | | layoutItems() { |
| | |
| | | |
| | | this.mockData.forEach(item => { |
| | | const minIndex = this.colHeight.indexOf(Math.min(...this.colHeight)); |
| | | this.columns[minIndex].push(item); |
| | | |
| | | // 文字类型不需要计算图片高度 |
| | | if (item.type !== 'text') { |
| | | this.colHeight[minIndex] += item.height + 40; // 40为间距 |
| | | } else { |
| | | // 文字类型固定高度计算(根据字体大小和行数) |
| | | const lineHeight = 40; // 假设每行40rpx |
| | | const lines = Math.ceil(uni.getSystemInfoSync().windowWidth / 345 * 0.8); // 响应式行数 |
| | | this.colHeight[minIndex] += lineHeight * lines + 40; |
| | | } |
| | | this.columns[minIndex].push(item); //获得高度更小的 放入元素 |
| | | this.colHeight[minIndex] += item.height + 40; // 40为间距 |
| | | }); |
| | | console.log(this.colHeight) |
| | | }, |
| | | // 图片加载回调 |
| | | imageLoad(e) { |
| | |
| | | const item = e.currentTarget.dataset.item; |
| | | |
| | | // 重新计算实际显示高度 |
| | | const viewWidth = 345; |
| | | const viewWidth = uni.upx2px(345); // 将rpx转换为px |
| | | const viewHeight = viewWidth * ratio; |
| | | const index = this.columns[0].findIndex(i => i.id === item.id) || |
| | | this.columns[1].findIndex(i => i.id === item.id); |
| | | |
| | | if (index !== -1) { |
| | | const colIndex = this.colHeight[0] < this.colHeight[1] ? 0 : 1; |
| | | this.colHeight[colIndex] -= item.height; |
| | | this.colHeight[colIndex] += viewHeight; |
| | | item.height = viewHeight; |
| | | } |
| | | // 更新item高度 |
| | | item.height = viewHeight; |
| | | |
| | | // 重新计算列高度 |
| | | this.recalculateColumns(); |
| | | }, |
| | | // 重新计算列高度 |
| | | recalculateColumns() { |
| | | this.colHeight = [0, 0]; |
| | | this.columns.forEach((column, colIndex) => { |
| | | column.forEach(item => { |
| | | this.colHeight[colIndex] += item.height + 40; // 40为间距 |
| | | }); |
| | | }); |
| | | }, |
| | | handleItemClick(item) { |
| | | console.log(item) |
| | | uni.navigateTo({ |
| | | url: `/pages/mine/activity/detail?id=${item.id}` // 参数通过 URL 传递 |
| | | }); |
| | | |
| | | } |
| | | }, |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | /* 新增加载更多样式 */ |
| | | .load-more { |
| | | padding: 20rpx 0; |
| | | text-align: center; |
| | | color: #999; |
| | | font-size: 26rpx; |
| | | background-color: #f7f8fa; |
| | | } |
| | | .btn-container { |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | margin-top: 8px; |
| | | /* 与上方标题保持间距 */ |
| | | } |
| | | |
| | | /* 全局样式优化 */ |
| | | .wrapper { |
| | | height: 100vh; |
| | | display: flex; |
| | | flex-direction: column; |
| | | background-color: #f7f8fa; |
| | | height: 100vh; |
| | | display: flex; |
| | | flex-direction: column; |
| | | background-color: #f7f8fa; |
| | | } |
| | | |
| | | |
| | | /* 导航栏优化 */ |
| | | .u-navbar { |
| | | box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05); |
| | | box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05); |
| | | } |
| | | |
| | | |
| | | /* 内容区域优化 */ |
| | | .content { |
| | | flex: 1; |
| | | overflow: hidden; |
| | | padding: 0 20rpx; |
| | | box-sizing: border-box; |
| | | /* 确保可以滚动 */ |
| | | -webkit-overflow-scrolling: touch; |
| | | } |
| | | |
| | | |
| | | /* 瀑布流布局优化 */ |
| | | .waterfall { |
| | | display: flex; |
| | | padding: 20rpx 0; |
| | | gap: 20rpx; |
| | | display: flex; |
| | | padding: 20rpx 0; |
| | | gap: 20rpx; |
| | | } |
| | | |
| | | |
| | | .column { |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 20rpx; |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 20rpx; |
| | | } |
| | | |
| | | |
| | | /* 卡片项优化 */ |
| | | .item { |
| | | background: #fff; |
| | | border-radius: 16rpx; |
| | | overflow: hidden; |
| | | box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08); |
| | | transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); |
| | | |
| | | &:active { |
| | | transform: scale(0.98); |
| | | box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.12); |
| | | } |
| | | background: #fff; |
| | | border-radius: 16rpx; |
| | | overflow: hidden; |
| | | box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08); |
| | | transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); |
| | | |
| | | &:active { |
| | | transform: scale(0.98); |
| | | box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.12); |
| | | } |
| | | } |
| | | |
| | | |
| | | /* 媒体内容样式 */ |
| | | .media { |
| | | width: 100%; |
| | | display: block; |
| | | border-radius: 16rpx 16rpx 0 0; |
| | | background-color: #f5f5f5; |
| | | |
| | | &[mode="widthFix"] { |
| | | height: auto; |
| | | } |
| | | width: 100%; |
| | | display: block; |
| | | border-radius: 16rpx 16rpx 0 0; |
| | | background-color: #f5f5f5; |
| | | |
| | | &[mode="widthFix"] { |
| | | height: auto; |
| | | } |
| | | } |
| | | |
| | | |
| | | /* 视频特殊样式 */ |
| | | video.media { |
| | | object-fit: cover; |
| | | object-fit: cover; |
| | | } |
| | | |
| | | |
| | | /* 文字内容样式 */ |
| | | .text-content { |
| | | padding: 24rpx; |
| | | background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%); |
| | | min-height: 160rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | |
| | | .title { |
| | | color: #fff; |
| | | font-size: 32rpx; |
| | | font-weight: 500; |
| | | line-height: 1.4; |
| | | text-align: center; |
| | | display: -webkit-box; |
| | | -webkit-box-orient: vertical; |
| | | -webkit-line-clamp: 3; |
| | | overflow: hidden; |
| | | } |
| | | padding: 24rpx; |
| | | background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%); |
| | | min-height: 160rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | |
| | | .title { |
| | | color: #fff; |
| | | font-size: 32rpx; |
| | | font-weight: 500; |
| | | line-height: 1.4; |
| | | text-align: center; |
| | | display: -webkit-box; |
| | | -webkit-box-orient: vertical; |
| | | -webkit-line-clamp: 3; |
| | | overflow: hidden; |
| | | } |
| | | } |
| | | |
| | | |
| | | /* 标题样式优化 */ |
| | | .title { |
| | | padding: 20rpx 24rpx; |
| | | font-size: 28rpx; |
| | | color: #333; |
| | | line-height: 1.5; |
| | | display: -webkit-box; |
| | | -webkit-box-orient: vertical; |
| | | -webkit-line-clamp: 2; |
| | | overflow: hidden; |
| | | font-weight: 500; |
| | | |
| | | &:not(.text-content .title) { |
| | | border-top: 1rpx solid #f0f0f0; |
| | | } |
| | | padding: 20rpx 24rpx; |
| | | font-size: 28rpx; |
| | | color: #333; |
| | | line-height: 1.5; |
| | | display: -webkit-box; |
| | | -webkit-box-orient: vertical; |
| | | -webkit-line-clamp: 2; |
| | | overflow: hidden; |
| | | font-weight: 500; |
| | | |
| | | &:not(.text-content .title) { |
| | | border-top: 1rpx solid #f0f0f0; |
| | | } |
| | | } |
| | | |
| | | |
| | | /* 加载动画 */ |
| | | @keyframes fadeInUp { |
| | | from { |
| | | opacity: 0; |
| | | transform: translateY(20rpx); |
| | | } |
| | | to { |
| | | opacity: 1; |
| | | transform: translateY(0); |
| | | } |
| | | from { |
| | | opacity: 0; |
| | | transform: translateY(20rpx); |
| | | } |
| | | |
| | | to { |
| | | opacity: 1; |
| | | transform: translateY(0); |
| | | } |
| | | } |
| | | |
| | | |
| | | .item { |
| | | animation: fadeInUp 0.4s ease forwards; |
| | | opacity: 0; |
| | | |
| | | @for $i from 1 through 10 { |
| | | &:nth-child(#{$i}) { |
| | | animation-delay: $i * 0.05s; |
| | | } |
| | | } |
| | | animation: fadeInUp 0.4s ease forwards; |
| | | opacity: 0; |
| | | |
| | | @for $i from 1 through 10 { |
| | | &:nth-child(#{$i}) { |
| | | animation-delay: $i * 0.05s; |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | /* 空状态样式 */ |
| | | .empty-state { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | justify-content: center; |
| | | height: 60vh; |
| | | text-align: center; |
| | | |
| | | image { |
| | | width: 240rpx; |
| | | opacity: 0.6; |
| | | margin-bottom: 30rpx; |
| | | } |
| | | |
| | | text { |
| | | color: #c0c4cc; |
| | | font-size: 28rpx; |
| | | } |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | justify-content: center; |
| | | height: 60vh; |
| | | text-align: center; |
| | | |
| | | image { |
| | | width: 240rpx; |
| | | opacity: 0.6; |
| | | margin-bottom: 30rpx; |
| | | } |
| | | |
| | | text { |
| | | color: #c0c4cc; |
| | | font-size: 28rpx; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | </view> |
| | | |
| | | <!-- 视频列表 --> |
| | | <view class="activity-list" > |
| | | <view class="activity-list"> |
| | | <view v-if="currentTab === 0"> |
| | | <view v-if="signedActivities.length > 0"> |
| | | <view v-for="(item, idx) in signedActivities" :key="idx" class="activity-item"> |
| | | <!-- 封面区域 --> |
| | | <block v-if="item.coverType === '图片' || item.coverType === '视频'"> |
| | | <image :src="getPreviewUrl(item.cover)" mode="aspectFill" class="activity-cover" /> |
| | | </block> |
| | | <block v-if="item.coverType === '文字'"> |
| | | <view class="activity-cover">{{ item.cover }}</view> |
| | | </block> |
| | | <scroll-view scroll-y class="activity-list" style="height: 100vh;" @scrolltolower="loadMore" |
| | | :lower-threshold="100"> |
| | | <view v-if="videoCollects.length > 0"> |
| | | <view v-for="(item, idx) in videoCollects" :key="idx" class="video-item"> |
| | | <!-- 视频封面+播放按钮 --> |
| | | <view class="video-cover-container"> |
| | | <image :src="item.coverUrl" mode="aspectFill" class="video-cover" /> |
| | | <view class="play-icon"> |
| | | <u-icon name="play-circle-fill" size="60" color="#fff"></u-icon> |
| | | </view> |
| | | <view class="video-duration" v-if="item.duration">{{ item.duration }}</view> |
| | | </view> |
| | | |
| | | <!-- 活动信息 --> |
| | | <view class="activity-info"> |
| | | <view class="activity-title">{{ item.activityName }}</view> |
| | | <view class="activity-meta"> |
| | | <text class="activity-time">{{ item.startTime }} - {{ item.endTime }}</text> |
| | | <text class="activity-location">{{ item.activityLocation || '暂无' }}</text> |
| | | <!-- 视频信息 --> |
| | | <view class="video-info"> |
| | | <view class="video-title">{{ item.authorName || '未知作者' }}</view> |
| | | <view class="video-meta"> |
| | | <text class="video-weight" v-if="item.weight > 0"> |
| | | <u-icon name="thumb-up-fill" size="24" color="#999"></u-icon> |
| | | {{ item.weight }} |
| | | </text> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 操作按钮 --> |
| | | <view class="video-actions"> |
| | | <button class="cancel-btn" @click.stop="handleCancelCollection(item,'video')"> |
| | | 取消收藏 |
| | | </button> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 操作区域 --> |
| | | <view class="action-container"> |
| | | <button class="cancel-btn" @click="handleCancelCollection(item)" |
| | | hover-class="cancel-btn-hover"> |
| | | 取消收藏 |
| | | </button> |
| | | </view> |
| | | |
| | | </view> |
| | | </view> |
| | | <view v-else class="empty-tip"> |
| | | <text>暂无收藏视频</text> |
| | | </view> |
| | | <view class="load-more"> |
| | | <u-loadmore v-if="videoCollects.length > 0" |
| | | :status="loading ? 'loading' : noMore ? 'nomore' : 'loadmore'" :load-text="{ |
| | | loadmore: '上拉加载更多', |
| | | loading: '正在加载', |
| | | nomore: '没有更多了' |
| | | }" /> |
| | | </view> |
| | | </scroll-view> |
| | | |
| | | |
| | | |
| | | </view> |
| | | |
| | | <view v-if="currentTab === 1"> |
| | | <!-- 已结束活动列表 --> |
| | | <view v-if="endedActivities.length > 0"> |
| | | <view v-for="(item, idx) in endedActivities" :key="idx" class="activity-item"> |
| | | <!-- 封面区域 --> |
| | | <block v-if="item.coverType === '图片' || item.coverType === '视频'"> |
| | | <image :src="getPreviewUrl(item.cover)" mode="aspectFill" class="activity-cover" /> |
| | | </block> |
| | | <block v-if="item.coverType === '文字'"> |
| | | <view class="activity-cover">{{ item.cover }}</view> |
| | | </block> |
| | | <scroll-view scroll-y class="activity-list" style="height: 100vh;" @scrolltolower="loadMore" |
| | | :lower-threshold="100"> |
| | | <view v-if="goodsCollects.length > 0"> |
| | | <view v-for="(item, idx) in goodsCollects" :key="idx" class="activity-item"> |
| | | <!-- 封面区域 --> |
| | | <block> |
| | | <image :src="item.original" mode="aspectFill" class="activity-cover" /> |
| | | </block> |
| | | |
| | | <!-- 活动信息 --> |
| | | <view class="activity-info"> |
| | | <view class="activity-title">{{ item.activityName }}</view> |
| | | <view class="activity-meta"> |
| | | <text class="activity-time">{{ item.startTime }} - {{ item.endTime }}</text> |
| | | <text class="activity-location">{{ item.activityLocation || '暂无' }}</text> |
| | | <!-- 活动信息 --> |
| | | <view class="activity-info"> |
| | | <view class="activity-title">{{ item.goodsName }}</view> |
| | | <view class="activity-meta"> |
| | | <text class="activity-time">价格:{{ item.price }}元</text> |
| | | <text class="activity-location">{{ item.storeName || '暂无' }}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 操作区域 --> |
| | | <view class="action-container"> |
| | | <button class="cancel-btn" @click="handleCancelCollection(item)" |
| | | hover-class="cancel-btn-hover"> |
| | | 取消收藏 |
| | | </button> |
| | | </view> |
| | | <!-- 操作区域 --> |
| | | <view class="action-container"> |
| | | <button class="cancel-btn" @click="handleCancelCollection(item,'goods')" |
| | | hover-class="cancel-btn-hover"> |
| | | 取消收藏 |
| | | </button> |
| | | </view> |
| | | |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view v-else class="empty-tip"> |
| | | |
| | | <text>暂无收藏商品</text> |
| | | </view> |
| | | <view class="load-more"> |
| | | <u-loadmore v-if="goodsCollects.length > 0" |
| | | :status="loading ? 'loading' : noMore ? 'nomore' : 'loadmore'" :load-text="{ |
| | | loadmore: '上拉加载更多', |
| | | loading: '正在加载', |
| | | nomore: '没有更多了' |
| | | }" /> |
| | | </view> |
| | | </scroll-view> |
| | | </view> |
| | | |
| | | <view v-if="currentTab === 2"> |
| | | <!-- 已取消活动列表 --> |
| | | <view v-if="canceledActivities.length > 0"> |
| | | <view v-for="(item, idx) in endedActivities" :key="idx" class="activity-item"> |
| | | <!-- 封面区域 --> |
| | | <block v-if="item.coverType === '图片' || item.coverType === '视频'"> |
| | | <image :src="getPreviewUrl(item.cover)" mode="aspectFill" class="activity-cover" /> |
| | | </block> |
| | | <block v-if="item.coverType === '文字'"> |
| | | <view class="activity-cover">{{ item.cover }}</view> |
| | | </block> |
| | | <!-- 活动信息 --> |
| | | <view class="activity-info"> |
| | | <view class="activity-title">{{ item.activityName }}</view> |
| | | <view class="activity-meta"> |
| | | <text class="activity-time">{{ item.startTime }} - {{ item.endTime }}</text> |
| | | <text class="activity-location">{{ item.activityLocation || '暂无' }}</text> |
| | | <scroll-view scroll-y class="activity-list" style="height: 80vh;" @scrolltolower="loadMore" |
| | | :lower-threshold="100"> |
| | | <view v-if="activityCollects.length > 0"> |
| | | <view v-for="(item, idx) in activityCollects" :key="idx" class="activity-item"> |
| | | <!-- 封面区域 --> |
| | | <block v-if="item.coverType === '图片' || item.coverType === '视频'"> |
| | | <image :src="item.cover" mode="aspectFill" class="activity-cover" /> |
| | | </block> |
| | | <block v-if="item.coverType === '文字'"> |
| | | <view class="activity-cover text-cover">{{ item.cover }}</view> |
| | | </block> |
| | | <!-- 活动信息 --> |
| | | <view class="activity-info"> |
| | | <view class="activity-title">{{ item.activityName }}</view> |
| | | <view class="activity-meta"> |
| | | <text class="activity-time">{{ item.startTime }}</text> |
| | | <text class="activity-time"> {{ item.endTime }}</text> |
| | | <text class="activity-location">{{ item.activityLocation || '暂无' }}</text> |
| | | </view> |
| | | </view> |
| | | <!-- 操作区域 --> |
| | | <view class="action-container"> |
| | | <button class="cancel-btn" @click="handleCancelCollection(item,'activity')" |
| | | hover-class="cancel-btn-hover"> |
| | | 取消收藏 |
| | | </button> |
| | | </view> |
| | | |
| | | </view> |
| | | <!-- 操作区域 --> |
| | | <view class="action-container"> |
| | | <button class="cancel-btn" @click="handleCancelCollection(item)" |
| | | hover-class="cancel-btn-hover"> |
| | | 取消收藏 |
| | | </button> |
| | | </view> |
| | | |
| | | |
| | | |
| | | </view> |
| | | |
| | | |
| | | </view> |
| | | <view v-else class="empty-tip"> |
| | | <text>暂无收藏活动</text> |
| | | </view> |
| | | <view class="load-more"> |
| | | <u-loadmore v-if="activityCollects.length > 0" |
| | | :status="loading ? 'loading' : noMore ? 'nomore' : 'loadmore'" :load-text="{ |
| | | loadmore: '上拉加载更多', |
| | | loading: '正在加载', |
| | | nomore: '没有更多了' |
| | | }" /> |
| | | </view> |
| | | <view style="height: 150rpx"></view> |
| | | </scroll-view> |
| | | |
| | | </view> |
| | | |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import ULoadmore from '@/uview-components/uview-ui/components/u-loadmore/u-loadmore.vue' |
| | | import UImage from '@/uview-components/uview-ui/components/u-image/u-image.vue'; |
| | | import { |
| | | getMyActivityList, |
| | | activityCancel |
| | | } from '@/api/activity.js' |
| | | import { |
| | | getPreviewUrl |
| | | getFilePreviewUrl |
| | | } from '@/api/common.js' |
| | | import { |
| | | changeCollect, |
| | | getMyCollectList |
| | | } from '@/api/collect.js' |
| | | import { |
| | | ifError |
| | | } from 'assert' |
| | | export default { |
| | | components: { |
| | | UImage, |
| | | ULoadmore |
| | | }, |
| | | data() { |
| | | return { |
| | | total: 0, |
| | | loading: false, |
| | | noMore: { |
| | | video: false, |
| | | goods: false, |
| | | activity: false |
| | | }, |
| | | currentTab: 0, // 当前选中的tab索引 |
| | | tabs: ['视频', '商品', '活动'], |
| | | // |
| | | // |
| | | videoCollects: [], // 收藏视频列表 |
| | | storeCollects: [], // 收藏商品列表 |
| | | goodsCollects: [], // 收藏商品列表 |
| | | activityCollects: [], // 收藏活动列表 |
| | | query: { |
| | | id: '', |
| | | status: '', |
| | | cancel: false, |
| | | collectForm: { |
| | | collectType: '', |
| | | refId: '', |
| | | }, |
| | | query: { |
| | | type: 'video', |
| | | pageNumber: 1, |
| | | pageSize: 5, |
| | | } |
| | | } |
| | | }, |
| | | onLoad(){ |
| | | onLoad() { |
| | | this.currentTab = 0; |
| | | //TODO 未登录需要id,测试用写死\ |
| | | this.switchTab(this.currentTab); |
| | | this.getintit() |
| | | }, |
| | | methods: { |
| | | handleCancelCollection(id) { |
| | | |
| | | /** |
| | | * 下拉刷新时 |
| | | */ |
| | | onPullDownRefresh() { |
| | | this.currentTab = 0; |
| | | this.query.pageNumber = 1; // 重置页码 |
| | | this.noMore = false; |
| | | this.videoCollects = []; |
| | | this.goodsCollects = []; // 收藏商品列表 |
| | | this.activityCollects = []; // 收藏活动列表// 清空数据 |
| | | this.getintit(); |
| | | }, |
| | | getPreviewUrl(params) { |
| | | // return getPreviewUrl(params); |
| | | return ''; |
| | | loadMore() { |
| | | this.loading = true; |
| | | this.query.pageNumber += 1; |
| | | // 延迟执行让UI有反应时间 |
| | | setTimeout(() => { |
| | | this.query.pageNumber += 1; |
| | | this.getintit(); |
| | | }, 300); |
| | | }, |
| | | handleCancelCollection(item, type) { |
| | | console.log(item) |
| | | this.collectForm.collectType = type; |
| | | this.collectForm.refId = item.id; |
| | | changeCollect(this.collectForm).then(res => { |
| | | if (res.statusCode === 200) { |
| | | uni.showToast({ |
| | | title: res.data.msg, // 提示文字 |
| | | icon: 'none', // 图标类型(success/loading/none) |
| | | mask: true // 是否显示透明蒙层(防止触摸穿透) |
| | | }); |
| | | this.getintit(); |
| | | } |
| | | |
| | | }) |
| | | }, |
| | | getUrl(params) { |
| | | getFilePreviewUrl(params).then(res => { |
| | | return res.data.data |
| | | }) |
| | | }, |
| | | // 切换tab |
| | | switchTab(index) { |
| | | |
| | | if (this.currentTab !== index) { |
| | | this.currentTab = index |
| | | //切换时页码归0 |
| | | this.query.pageNumber = 0; |
| | | // 清空数据 |
| | | this.videoCollects = []; |
| | | this.goodsCollects = []; |
| | | this.activityCollects = []; |
| | | // 实际项目中可以在这里添加加载数据的逻辑 |
| | | if (this.currentTab === 0) { |
| | | //加载视频列表 |
| | | this.getMyCollectionVideoList(); |
| | | } else if (this.currentTab === 1) { |
| | | //加载商品列表 |
| | | this.getMyCollectionStoreList(); |
| | | } else if (this.currentTab === 2) { |
| | | //加载活动列表 |
| | | this.getMyCollectActivityList(); |
| | | } |
| | | this.getintit() |
| | | } |
| | | }, |
| | | async getintit() { |
| | | uni.showLoading({ |
| | | title: '加载中' |
| | | }); |
| | | if (this.currentTab === 0) { |
| | | this.query.type = 'video'; |
| | | getMyCollectList(this.query).then(res => { |
| | | uni.hideLoading(); |
| | | this.loading = false; |
| | | |
| | | if (res.statusCode === 200) { |
| | | const newData = res.data.data |
| | | this.total = res.data.total || 0; |
| | | // 追加或替换数据 |
| | | this.videoCollects = this.query.pageNumber === 1 ? |
| | | newData : |
| | | [...this.videoCollects, ...newData]; |
| | | // 判断是否还有更多数据 |
| | | this.noMore = newData.length < this.query.pageSize || |
| | | this.videoCollects.length >= this.total; |
| | | |
| | | } |
| | | }) |
| | | } else if (this.currentTab === 1) { |
| | | this.query.type = 'goods'; |
| | | getMyCollectList(this.query).then(res => { |
| | | uni.hideLoading(); |
| | | this.loading = false; |
| | | if (res.statusCode === 200) { |
| | | const newData = res.data.data |
| | | this.total = res.data.total || 0; |
| | | |
| | | this.goodsCollects = this.query.pageNumber === 1 ? |
| | | newData : |
| | | [...this.goodsCollects, ...newData]; |
| | | // 判断是否还有更多数据 |
| | | this.noMore = newData.length < this.query.pageSize || |
| | | this.goodsCollects.length >= this.total; |
| | | } |
| | | }) |
| | | } else if (this.currentTab === 2) { |
| | | this.query.type = 'activity'; |
| | | getMyCollectList(this.query).then(res => { |
| | | uni.hideLoading(); |
| | | this.loading = false; |
| | | if (res.statusCode === 200) { |
| | | const newData = res.data.data |
| | | this.total = res.data.total || 0; |
| | | |
| | | this.activityCollects = this.query.pageNumber === 1 ? |
| | | newData : |
| | | [...this.activityCollects, ...newData]; |
| | | this.noMore = newData.length < this.query.pageSize || |
| | | this.activityCollects.length >= this.total; |
| | | } |
| | | }) |
| | | } |
| | | |
| | | }, |
| | | getMyCollectionStoreList() { |
| | | uni.showLoading({ |
| | | title: '加载中' |
| | | }); |
| | | |
| | | uni.hideLoading(); |
| | | }, |
| | | getMyCollectionVideoList() { |
| | | uni.showLoading({ |
| | | title: '加载中' |
| | | }); |
| | | |
| | | uni.hideLoading(); |
| | | }, |
| | | getMyCollectActivityList() { |
| | | uni.showLoading({ |
| | | title: '加载中' |
| | | }); |
| | | |
| | | uni.hideLoading(); |
| | | }, |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | .text-cover { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%); |
| | | color: #fff; |
| | | font-size: 28rpx; |
| | | padding: 16rpx; |
| | | line-height: 1.4; |
| | | } |
| | | |
| | | /* 视频列表专用样式 */ |
| | | .video-item { |
| | | display: flex; |
| | | padding: 24rpx 0; |
| | | border-bottom: 1rpx solid #f5f5f5; |
| | | align-items: center; |
| | | |
| | | &:last-child { |
| | | border-bottom: none; |
| | | } |
| | | } |
| | | |
| | | .video-cover-container { |
| | | position: relative; |
| | | width: 240rpx; |
| | | height: 160rpx; |
| | | border-radius: 12rpx; |
| | | overflow: hidden; |
| | | margin-right: 24rpx; |
| | | flex-shrink: 0; |
| | | |
| | | .video-cover { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | .play-icon { |
| | | position: absolute; |
| | | top: 50%; |
| | | left: 50%; |
| | | transform: translate(-50%, -50%); |
| | | opacity: 0.9; |
| | | } |
| | | |
| | | .video-duration { |
| | | position: absolute; |
| | | right: 8rpx; |
| | | bottom: 8rpx; |
| | | background: rgba(0, 0, 0, 0.6); |
| | | color: #fff; |
| | | font-size: 20rpx; |
| | | padding: 4rpx 12rpx; |
| | | border-radius: 20rpx; |
| | | } |
| | | } |
| | | |
| | | .video-info { |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: space-between; |
| | | height: 160rpx; |
| | | |
| | | .video-title { |
| | | font-size: 30rpx; |
| | | color: #333; |
| | | font-weight: bold; |
| | | display: -webkit-box; |
| | | -webkit-box-orient: vertical; |
| | | -webkit-line-clamp: 2; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .video-meta { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | font-size: 24rpx; |
| | | color: #999; |
| | | |
| | | |
| | | |
| | | .video-weight { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .video-actions { |
| | | margin-left: 20rpx; |
| | | flex-shrink: 0; |
| | | |
| | | .cancel-btn { |
| | | background: #f5f5f5; |
| | | color: #666; |
| | | border: none; |
| | | font-size: 24rpx; |
| | | padding: 8rpx 20rpx; |
| | | border-radius: 20rpx; |
| | | |
| | | &:active { |
| | | background: #eee; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .empty-tip { |
| | | text-align: center; |
| | | padding: 100rpx 0; |
| | | |
| | | image { |
| | | width: 300rpx; |
| | | margin-bottom: 30rpx; |
| | | opacity: 0.6; |
| | | } |
| | | |
| | | text { |
| | | display: block; |
| | | font-size: 28rpx; |
| | | color: #999; |
| | | } |
| | | } |
| | | |
| | | .activity-container { |
| | | padding: 20rpx; |
| | | background-color: #f5f5f5; |
| | |
| | | <u-form-item label="电话" prop="mobile" borderBottom required="true"> |
| | | <u-input v-model="form.mobile" placeholder="请输入手机号码" border="none" type="number" /> |
| | | </u-form-item> |
| | | <!-- 旧密码 --> |
| | | <u-form-item label="旧密码" prop="password" borderBottom required="true" v-if="false"> |
| | | <u-input v-model="form.oldPassword" placeholder="请输入密码" border="none" type="password" /> |
| | | </u-form-item> |
| | | <!-- 密码 --> |
| | | <u-form-item label="新密码" prop="password" borderBottom required="true"> |
| | | <u-form-item label="密码" prop="password" borderBottom required="true" v-if="!form.id"> |
| | | <u-input v-model="form.password" placeholder="请输入密码" border="none" type="password" /> |
| | | </u-form-item> |
| | | |
| | |
| | | </view> |
| | | <!-- 操作按钮区域 --> |
| | | <view class="action-buttons"> |
| | | <u-button type="primary" size="mini" @click.stop="restPassword(user.memberId)" class="edit-btn">重置密码</u-button> |
| | | <u-button type="primary" size="mini" @click.stop="navigateToDetail(user.id)" class="edit-btn">修改</u-button> |
| | | <u-button type="error" size="mini" @click.stop="deleteUser(user.id)" |
| | | class="delete-btn">删除</u-button> |
| | |
| | | getPage, |
| | | del, |
| | | add, |
| | | update |
| | | update, |
| | | restPassword |
| | | } from "@/api/userPermissions.js" |
| | | import UIcon from '@/uview-components/uview-ui/components/u-icon/u-icon.vue'; |
| | | import UButton from '@/uview-components/uview-ui/components/u-button/u-button.vue'; |
| | |
| | | this.getPage() |
| | | }, |
| | | methods: { |
| | | restPassword(id){ |
| | | restPassword(id).then(res=>{ |
| | | if(res.statusCode === 200){ |
| | | uni.showToast({ |
| | | title: res.data.msg, // 提示文字 |
| | | icon: 'none', // 图标类型(success/loading/none) |
| | | mask: true // 是否显示透明蒙层(防止触摸穿透) |
| | | }); |
| | | } |
| | | }) |
| | | }, |
| | | async getPage() { |
| | | // |
| | | uni.showLoading({ |