From b87f40d077669eaceced44aadf7e02117f53671e Mon Sep 17 00:00:00 2001 From: zxl <763096477@qq.com> Date: 星期五, 06 六月 2025 15:25:50 +0800 Subject: [PATCH] 优化我的收藏,活动报名,我的活动页面,活动页面页面,新增加载更多 --- api/common.js | 9 pages/mine/activity/detail.vue | 54 ++ pages/userPermissions/addStoreMember.vue | 6 pages.json | 42 + api/collect.js | 13 pages/mine/activity/reportActivity.vue | 433 +++++++++++++--------- pages/userPermissions/userPermissions.vue | 15 pages/mine/activity/myActivity.vue | 15 api/activity.js | 33 - api/userPermissions.js | 8 pages/mine/myCollect/myCollect.vue | 512 ++++++++++++++++++++------ 11 files changed, 769 insertions(+), 371 deletions(-) diff --git a/api/activity.js b/api/activity.js index 11a43ba..1557181 100644 --- a/api/activity.js +++ b/api/activity.js @@ -18,34 +18,6 @@ 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 - }); -} /** * 鍙栨秷鎶ュ悕 @@ -91,11 +63,12 @@ * * @param params */ - export function getActivityReportList() { + export function getActivityReportList(param) { return http.request({ url: "/lmk/activityReport", method: Method.GET, - needToken: true + needToken: true, + params:param }); } diff --git a/api/collect.js b/api/collect.js index 4a12dec..ed4b199 100644 --- a/api/collect.js +++ b/api/collect.js @@ -20,3 +20,16 @@ data: data }); } + +/** + * 鑾峰緱鎴戠殑鏀惰棌鎸変紶鍏ョ被鍨� video锛宎ctivity锛宻tore + * @param {Object} param + */ +export function getMyCollectList(param){ + return http.request({ + url: "/lmk/my-collect/getMyCollectList", + method: Method.GET, + needToken: true, + params: param + }); +} \ No newline at end of file diff --git a/api/common.js b/api/common.js index bbedae0..023c24b 100644 --- a/api/common.js +++ b/api/common.js @@ -35,15 +35,6 @@ }); } -export function getPreviewUrl(params){ - return http.request({ - url: `${api.common}/lmk/file/preview`, - method: Method.POST, - data:params - }); -} - - /** * 鑾峰彇鏂囦欢璁块棶鍦板潃 */ diff --git a/api/userPermissions.js b/api/userPermissions.js index 513068a..63e3d92 100644 --- a/api/userPermissions.js +++ b/api/userPermissions.js @@ -58,4 +58,12 @@ needToken: true }) +} + +export function restPassword(param){ + return http.request({ + url:'/lmk/lmk-user-permissions/restPassword/'+param, + method: Method.PUT, + needToken: true + }) } \ No newline at end of file diff --git a/pages.json b/pages.json index 95a8839..569ee1b 100644 --- a/pages.json +++ b/pages.json @@ -672,14 +672,8 @@ }, { "path": "activity/detail", "style": { - "navigationBarTitleText": "娲诲姩璇︽儏" - } - }, { - "path": "activity/myActivity", - "style": { - "navigationBarTitleText": "鎴戠殑娲诲姩", + "navigationBarTitleText": "娲诲姩璇︽儏", "enablePullDownRefresh": true, //涓嬫媺鍒锋柊 - "navigationStyle": "custom", "componentPlaceholder": { "u-form": "view", "u-form-item": "view", @@ -688,7 +682,27 @@ "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" } } }, { @@ -696,7 +710,6 @@ "style": { "navigationBarTitleText": "娲诲姩", "enablePullDownRefresh": true, //涓嬫媺鍒锋柊 - "navigationStyle": "custom", "componentPlaceholder": { "u-form": "view", "u-form-item": "view", @@ -705,13 +718,17 @@ "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", @@ -721,7 +738,10 @@ "u-popup": "view", "u-search": "view", "u-loading": "view", - "u-navbar": "view" + "u-navbar": "view", + "u-image": "view", + "u-loadmore": "view" + } } diff --git a/pages/mine/activity/detail.vue b/pages/mine/activity/detail.vue index 4c5bb5b..fb61737 100644 --- a/pages/mine/activity/detail.vue +++ b/pages/mine/activity/detail.vue @@ -4,8 +4,12 @@ <!-- 鍔ㄦ�佸皝闈㈠尯鍩� --> <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 === '鏂囧瓧'"> @@ -53,18 +57,24 @@ </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: { @@ -79,12 +89,17 @@ activityType: '', limitUserNum:'', }, + isCollect:false, reportBtn:false, detailId: null, // 瀛樺偍鎺ユ敹鐨勫弬鏁� reportFrom: { activityId: '', cancel: false, //鎶ュ悕鎺ュ彛榛樿鎴慺alse - } + }, + collectForm:{ + collectType:'', + refId:'', + }, }; }, onLoad(options) { @@ -96,6 +111,20 @@ } }, 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', // 鍥炬爣绫诲瀷锛坰uccess/loading/none锛� + mask: true // 鏄惁鏄剧ず閫忔槑钂欏眰锛堥槻姝㈣Е鎽哥┛閫忥級 + }); + } + }) + }, //鎶ュ悕 activityReport() { this.reportFrom.activityId = this.detailId @@ -111,8 +140,10 @@ }) }, - getPreviewUrl(params){ - return getPreviewUrl(params); + getUrl(params){ + getFilePreviewUrl(params).then(res =>{ + return res.data.data + }) }, getActivityDetail(id) { uni.showLoading({ @@ -120,6 +151,7 @@ }); getActivityDetail(id).then(res => { uni.hideLoading(); + console.log(res.data) if (res.statusCode === 200) { //璧嬪�� this.activityInfo.coverType = res.data.data.coverType; @@ -132,7 +164,7 @@ 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; } }) }, @@ -277,4 +309,10 @@ height: 40rpx; margin-bottom: 10rpx; } + .btn-container { + display: flex; + justify-content: center; + align-items: center; + margin-top: 8px; /* 涓庝笂鏂规爣棰樹繚鎸侀棿璺� */ + } </style> \ No newline at end of file diff --git a/pages/mine/activity/myActivity.vue b/pages/mine/activity/myActivity.vue index 12902c1..c977479 100644 --- a/pages/mine/activity/myActivity.vue +++ b/pages/mine/activity/myActivity.vue @@ -1,6 +1,5 @@ <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"> @@ -29,7 +28,7 @@ <!-- 灏侀潰鍖哄煙 --> <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> @@ -82,7 +81,7 @@ > <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> @@ -125,7 +124,7 @@ > <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> @@ -162,7 +161,7 @@ <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 { @@ -199,8 +198,10 @@ } }) }, - getPreviewUrl(params){ - return getPreviewUrl(params); + getUrl(params){ + getFilePreviewUrl(params).then(res =>{ + return res.data.data + }) }, switchTab(index) { if (this.currentTab !== index) { diff --git a/pages/mine/activity/reportActivity.vue b/pages/mine/activity/reportActivity.vue index 2f34778..26f3407 100644 --- a/pages/mine/activity/reportActivity.vue +++ b/pages/mine/activity/reportActivity.vue @@ -1,47 +1,73 @@ <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: '姝e湪鍔犺浇', + 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: [ @@ -50,45 +76,94 @@ ], // 鍙屽垪甯冨眬 mockData: [], colHeight: [0, 0], // 璁板綍鍚勫垪楂樺害 - + baseImageHeight: 300, // 鍥剧墖鍩虹楂樺害 + baseVideoHeight: 350, // 瑙嗛鍩虹楂樺害 + baseTextHeight: 120, // 鏂囧瓧鍩虹楂樺害 + query: { + pageNumber: 1, + pageSize: 8, + }, + loading: false, // 鏄惁姝e湪鍔犺浇 + 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; + + // 寤惰繜鎵ц璁︰I鏈夊弽搴旀椂闂� + 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() { @@ -100,19 +175,9 @@ 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) { @@ -124,176 +189,200 @@ const item = e.currentTarget.dataset.item; // 閲嶆柊璁$畻瀹為檯鏄剧ず楂樺害 - const viewWidth = 345; + const viewWidth = uni.upx2px(345); // 灏唕px杞崲涓簆x 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> \ No newline at end of file diff --git a/pages/mine/myCollect/myCollect.vue b/pages/mine/myCollect/myCollect.vue index 4b0fd27..7251419 100644 --- a/pages/mine/myCollect/myCollect.vue +++ b/pages/mine/myCollect/myCollect.vue @@ -10,103 +10,147 @@ </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: '姝e湪鍔犺浇', + 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: '姝e湪鍔犺浇', + 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: '姝e湪鍔犺浇', + nomore: '娌℃湁鏇村浜�' + }" /> + </view> + <view style="height: 150rpx"></view> + </scroll-view> </view> @@ -120,88 +164,300 @@ </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, // 褰撳墠閫変腑鐨則ab绱㈠紩 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 鏈櫥褰曢渶瑕乮d锛屾祴璇曠敤鍐欐\ - 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; + // 寤惰繜鎵ц璁︰I鏈夊弽搴旀椂闂� + 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', // 鍥炬爣绫诲瀷锛坰uccess/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; diff --git a/pages/userPermissions/addStoreMember.vue b/pages/userPermissions/addStoreMember.vue index 265e0fc..26c68da 100644 --- a/pages/userPermissions/addStoreMember.vue +++ b/pages/userPermissions/addStoreMember.vue @@ -14,12 +14,8 @@ <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> diff --git a/pages/userPermissions/userPermissions.vue b/pages/userPermissions/userPermissions.vue index 12cf83f..1c2079f 100644 --- a/pages/userPermissions/userPermissions.vue +++ b/pages/userPermissions/userPermissions.vue @@ -23,6 +23,7 @@ </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> @@ -51,7 +52,8 @@ 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'; @@ -95,6 +97,17 @@ this.getPage() }, methods: { + restPassword(id){ + restPassword(id).then(res=>{ + if(res.statusCode === 200){ + uni.showToast({ + title: res.data.msg, // 鎻愮ず鏂囧瓧 + icon: 'none', // 鍥炬爣绫诲瀷锛坰uccess/loading/none锛� + mask: true // 鏄惁鏄剧ず閫忔槑钂欏眰锛堥槻姝㈣Е鎽哥┛閫忥級 + }); + } + }) + }, async getPage() { // uni.showLoading({ -- Gitblit v1.8.0