From c146b580fdca424b6bb35b0f8d31ffec3952e642 Mon Sep 17 00:00:00 2001
From: zxl <763096477@qq.com>
Date: 星期二, 24 六月 2025 14:17:46 +0800
Subject: [PATCH] 新闻

---
 pages/tabbar/user/utils/tool.vue       |    4 
 api/news.js                            |   56 ++++++
 pages.json                             |   36 ++++
 pages/mine/activity/reportActivity.vue |    2 
 pages/news/news.vue                    |  178 +++++++++++++++++++
 pages/news/detail.vue                  |  212 +++++++++++++++++++++++
 6 files changed, 487 insertions(+), 1 deletions(-)

diff --git a/api/news.js b/api/news.js
new file mode 100644
index 0000000..a297a47
--- /dev/null
+++ b/api/news.js
@@ -0,0 +1,56 @@
+/**
+ * 鏂伴椈鐩稿叧API
+ */
+import { http, Method } from "@/utils/request.js";
+
+import api from "@/config/api.js";
+export  function getNews(params){
+	return http.request({
+		url: "/lmk/news/page",
+		method: Method.GET,
+		needToken: true,
+		params: params,
+	})
+}
+
+export  function detail(params){
+	return http.request({
+		url: "/lmk/news/" + params,
+		method: Method.GET,
+		needToken: true,
+	})
+}
+
+export  function addNews(params){
+	return http.request({
+		url: "/lmk/news",
+		method: Method.POST,
+		needToken: true,
+		data: params,
+	})
+}
+
+export  function editNews(params){
+	return http.request({
+		url: "/lmk/news",
+		method: Method.PUT,
+		needToken: true,
+		data: params,
+	})
+}
+export  function publish(params){
+	return http.request({
+		url: "/lmk/news/publish/" + params,
+		method: Method.PUT,
+		needToken: true,
+	})
+}
+export  function delById(params){
+	return http.request({
+		url: "/lmk/news/" + params,
+		method: Method.DELETE,
+		needToken: true,
+	})
+}
+
+
diff --git a/pages.json b/pages.json
index 608c6c0..309a483 100644
--- a/pages.json
+++ b/pages.json
@@ -282,6 +282,42 @@
 				}
 			}
 		},
+		{
+			"path": "pages/news/news",
+			"style": {
+				"navigationBarTitleText": "鏂伴椈",
+				"componentPlaceholder": {
+					"u-icon": "view",
+					"u-button": "view",
+					"u-form": "view",
+					"u-form-item": "view",
+					"u-input": "view",
+					"u-popup": "view",
+					"u-search": "view",
+					"u-loading": "view",
+					"u-navbar": "view",
+					"u-loadmore":"view"
+				}
+			}
+		},
+		{
+			"path": "pages/news/detail",
+			"style": {
+				"navigationBarTitleText": "鏂伴椈璇︽儏",
+				"componentPlaceholder": {
+					"u-icon": "view",
+					"u-button": "view",
+					"u-form": "view",
+					"u-form-item": "view",
+					"u-input": "view",
+					"u-popup": "view",
+					"u-search": "view",
+					"u-loading": "view",
+					"u-navbar": "view",
+					"u-loadmore":"view"
+				}
+			}
+		},
 		// {
 		// 	"path": "pages/customerManager/customerManager",
 		// 	"style": {
diff --git a/pages/mine/activity/reportActivity.vue b/pages/mine/activity/reportActivity.vue
index b035663..a1051f6 100644
--- a/pages/mine/activity/reportActivity.vue
+++ b/pages/mine/activity/reportActivity.vue
@@ -64,6 +64,7 @@
 				query: {
 					pageNumber: 1,
 					pageSize: 10,
+					publish:1,
 				},
 				loading: false, // 鏄惁姝e湪鍔犺浇
 				noMore: false, // 鏄惁娌℃湁鏇村鏁版嵁
@@ -84,7 +85,6 @@
 				this.getActivityList();
 			},
 			loadMore() {
-
 				// 鏄剧ず鍔犺浇鐘舵��
 				this.loading = true;
 
diff --git a/pages/news/detail.vue b/pages/news/detail.vue
new file mode 100644
index 0000000..ceabba6
--- /dev/null
+++ b/pages/news/detail.vue
@@ -0,0 +1,212 @@
+<template>
+  <view class="detail-page">
+    <!-- 鍔犺浇鐘舵�� -->
+    <view v-if="loading" class="loading-container">
+      <u-loading mode="circle" size="48"></u-loading>
+      <text class="loading-text">鍔犺浇涓�...</text>
+    </view>
+    
+    <!-- 鍐呭鍖哄煙 -->
+    <template v-else>
+      <!-- 鏍囬鍖� -->
+      <view class="header">
+        <text class="title">{{ detailData.title }}</text>
+        <text class="meta">
+          <text class="date">{{ formatDate(detailData.publishDate) }}</text>
+        </text>
+      </view>
+      
+      <!-- 瀵屾枃鏈唴瀹� -->
+      <scroll-view scroll-y class="content-wrapper">
+        <rich-text 
+          :nodes="formatContent(detailData.content)" 
+          class="content"
+        ></rich-text>
+      </scroll-view>
+    </template>
+    
+    <!-- 閿欒鎻愮ず -->
+    <u-toast ref="uToast"></u-toast>
+  </view>
+</template>
+
+<script>
+import { detail } from '@/api/news.js'
+
+export default {
+  data() {
+    return {
+      detailId: '',
+      loading: true,
+      detailData: {
+        title: '',
+        content: '',
+        publishDate: ''
+      }
+    }
+  },
+  onLoad(options) {
+    if (options.id) {
+      this.detailId = options.id
+      this.loadDetailData()
+    }
+  },
+  methods: {
+    async loadDetailData() {
+      this.loading = true
+      try {
+        const res = await detail(this.detailId)
+        if (res.statusCode === 200) {
+			this.detailData = {
+            title: res.data.data.title || '鏃犳爣棰�',
+            content: res.data.data.content || '',
+            publishDate: res.data.data.publishDate || ''
+          }
+        } else {
+          this.showError('鍔犺浇澶辫触: ' + (res.message || '鏈煡閿欒'))
+        }
+      } catch (error) {
+        console.error('鍔犺浇璇︽儏鍑洪敊:', error)
+        this.showError('缃戠粶璇锋眰澶辫触')
+      } finally {
+        this.loading = false
+      }
+    },
+    
+    formatDate(dateString) {
+      if (!dateString) return '鏈煡鏃堕棿'
+      
+      try {
+        const date = new Date(dateString)
+        if (isNaN(date.getTime())) return dateString
+        
+        const year = date.getFullYear()
+        const month = (date.getMonth() + 1).toString().padStart(2, '0')
+        const day = date.getDate().toString().padStart(2, '0')
+        const hours = date.getHours().toString().padStart(2, '0')
+        const minutes = date.getMinutes().toString().padStart(2, '0')
+        
+        return `${year}-${month}-${day} ${hours}:${minutes}`
+      } catch (e) {
+        console.error('鏃ユ湡鏍煎紡鍖栭敊璇�:', e)
+        return dateString
+      }
+    },
+    
+    formatContent(content) {
+      if (!content) return ''
+      
+      // 鍩虹澶勭悊锛氱‘淇濆浘鐗囪嚜閫傚簲
+      const processedContent = content
+        .replace(/<img/gi, '<img style="max-width:100%;height:auto;display:block;margin:20rpx auto;"')
+        .replace(/<table/gi, '<table style="width:100%;border-collapse:collapse;"')
+        .replace(/<td/gi, '<td style="border:1px solid #ddd;padding:8px;"')
+      
+      return processedContent
+    },
+    
+    showError(message) {
+      this.$refs.uToast.show({
+        type: 'error',
+        message: message,
+        duration: 2000
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.detail-page {
+  padding: 30rpx;
+  min-height: 100vh;
+  background-color: #f8f8f8;
+}
+
+.loading-container {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  height: 60vh;
+  
+  .loading-text {
+    margin-top: 20rpx;
+    font-size: 28rpx;
+    color: #999;
+  }
+}
+
+.header {
+  background-color: #fff;
+  border-radius: 16rpx;
+  padding: 30rpx;
+  margin-bottom: 30rpx;
+  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
+  
+  .title {
+    display: block;
+    font-size: 36rpx;
+    font-weight: bold;
+    color: #333;
+    line-height: 1.5;
+    margin-bottom: 20rpx;
+  }
+  
+  .meta {
+    display: flex;
+    justify-content: flex-end;
+    font-size: 24rpx;
+    color: #999;
+    
+    .date {
+      margin-left: 15rpx;
+    }
+  }
+}
+
+.content-wrapper {
+  background-color: #fff;
+  border-radius: 16rpx;
+  padding: 30rpx;
+  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
+  height: calc(100vh - 300rpx);
+  
+  .content {
+    font-size: 30rpx;
+    line-height: 1.8;
+    color: #333;
+    
+    // 瑕嗙洊rich-text鍐呴儴鍏冪礌鏍峰紡
+    /deep/ p {
+      margin-bottom: 20rpx;
+    }
+    
+    /deep/ h1, /deep/ h2, /deep/ h3 {
+      margin: 40rpx 0 20rpx;
+      font-weight: bold;
+    }
+    
+    /deep/ ul, /deep/ ol {
+      padding-left: 40rpx;
+      margin-bottom: 20rpx;
+    }
+    
+    /deep/ li {
+      margin-bottom: 10rpx;
+    }
+    
+    /deep/ a {
+      color: #007aff;
+      word-break: break-all;
+    }
+    
+    /deep/ blockquote {
+      border-left: 4rpx solid #ddd;
+      padding-left: 20rpx;
+      color: #666;
+      margin: 20rpx 0;
+    }
+  }
+}
+</style>
\ No newline at end of file
diff --git a/pages/news/news.vue b/pages/news/news.vue
new file mode 100644
index 0000000..1a11a47
--- /dev/null
+++ b/pages/news/news.vue
@@ -0,0 +1,178 @@
+<template>
+	<view class="wrapper">
+		<view style="height: 100rpx"></view>
+		<!-- 鍐呭鍖哄煙 -->
+		<scroll-view scroll-y class="content" style="height: 40vh;" @scrolltolower="loadMore" :lower-threshold="100">
+			<view class="waterfall">
+			
+					<view class="item" v-for="(item, idx) in mockData" :key="item.id" @click="handleItemClick(item)">
+						<text class="title">{{ item.title }}</text>
+						<text class="publishDate">鍙戝竷鏃堕棿:{{ item.publishDate }}</text>
+					</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>
+	</view>
+</template>
+
+<script>
+	import '@/components/uview-components/uview-ui';
+	import { getNews,addNews,editNews,publish,delById } from '@/api/news.js'
+	export default {
+		data() {
+			return {
+				query: {
+					pageNumber: 1,
+					pageSize: 10,
+					publish:1,
+				},
+				loading:false,
+				total:0,
+				mockData:[],
+				noMore:false,
+				
+			}
+		},
+		mounted() {
+			
+		},
+		onLoad() {
+			this.getNewsPage();
+		},
+		methods: {
+			handleItemClick(item){
+				uni.navigateTo({
+					url: `/pages/news/detail?id=${item.id}` // 鍙傛暟閫氳繃 URL 浼犻��
+				});
+			},
+			async getNewsPage(){
+				try {
+					const res = await getNews(this.query);
+					this.loading = false;
+					if(res.statusCode === 200){
+						const newData = res.data.data.map(value =>({
+							id:value.id,
+							title:value.title,
+							publish:value.publish,
+							publishDate:value.publishDate
+						}));
+						// 鏇存柊鎬绘暟鎹噺
+						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;
+						
+					}
+					
+				} catch (error) {
+					console.error('鍔犺浇澶辫触:', error);
+					// 澶辫触鏃跺洖閫�椤电爜
+					if (this.query.pageNumber > 1) {
+						this.query.pageNumber -= 1;
+					}
+				} finally {
+					this.loading = false;
+					uni.hideLoading();
+					uni.stopPullDownRefresh();
+				}
+				
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+.wrapper {
+  padding: 0 20rpx;
+  box-sizing: border-box;
+  background-color: #f5f5f5;
+  height: 100%;
+  
+  .content {
+    padding-bottom: 20rpx;
+    box-sizing: border-box;
+    
+    .waterfall {
+      display: flex;
+      flex-direction: column;
+      padding: 0 10rpx;
+      
+      .item {
+        background: #fff;
+        border-radius: 12rpx;
+        padding: 24rpx;
+        margin-bottom: 20rpx;
+        box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
+        transition: transform 0.2s ease, box-shadow 0.2s ease;
+        
+        &:active {
+          transform: scale(0.98);
+          box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.1);
+        }
+        
+        .title {
+          display: block;
+          font-size: 28rpx;
+          color: #333;
+          font-weight: 500;
+          line-height: 1.5;
+          margin-bottom: 12rpx;
+          overflow: hidden;
+          text-overflow: ellipsis;
+          display: -webkit-box;
+          -webkit-line-clamp: 3;
+          -webkit-box-orient: vertical;
+        }
+        
+        .publishDate {
+          display: block;
+          font-size: 22rpx;
+          color: #999;
+          text-align: right;
+        }
+      }
+    }
+    
+    .load-more {
+      padding: 30rpx 0;
+      background-color: transparent;
+      
+      .u-loadmore {
+        font-size: 26rpx !important;
+        color: #999 !important;
+      }
+    }
+  }
+}
+
+/* 骞虫澘鍙婁互涓婅澶囬�傞厤 */
+@media (min-width: 768px) {
+  .waterfall {
+    flex-direction: row !important;
+    flex-wrap: wrap;
+    
+    .item {
+      width: calc(50% - 10rpx);
+      margin: 0 5rpx 20rpx;
+    }
+  }
+}
+</style>
diff --git a/pages/tabbar/user/utils/tool.vue b/pages/tabbar/user/utils/tool.vue
index 9bf9844..1520f0e 100644
--- a/pages/tabbar/user/utils/tool.vue
+++ b/pages/tabbar/user/utils/tool.vue
@@ -66,6 +66,10 @@
 						<image src="/static/mine/shensu.png" mode=""></image>
 						<view>鐢ㄦ埛鏉冮檺</view>
 					</view>
+					<view class="interact-item" v-if="isStoreManger" @click="navigateTo('/pages/news/news')">
+						<image src="/static/mine/shensu.png" mode=""></image>
+						<view>鏂伴椈</view>
+					</view>
 
 				<!-- 	<view class="interact-item" v-if="isStoreManger" @click="navigateTo('/pages/customerManager/customerManager')">
 						<image src="/static/mine/shensu.png" mode=""></image>

--
Gitblit v1.8.0