diff --git a/app.json b/app.json index 65c9d33..337f3eb 100644 --- a/app.json +++ b/app.json @@ -9,13 +9,17 @@ { "root": "pagesA", "pages": [ - "pages/askingSy/askingSy" + "pages/carouselDetail/carouselDetail" ] }, { "root": "pagesB", "pages": [ - "pages/repository/repository" + "pages/administrativeDivision/administrativeDivision", + "pages/training/training", + "pages/wzDetails/wzDetails", + "pages/spDetails/spDetails", + "pages/publishAdd/publishAdd" ], "independent": true } diff --git a/pages/home/home.js b/pages/home/home.js index 900b722..d76aa24 100644 --- a/pages/home/home.js +++ b/pages/home/home.js @@ -7,8 +7,7 @@ Page({ baseUrl: baseUrl, swiperList: [], articleList:[ - {title:'文章发布',describe:'快速发布养殖知识',icon:'/pages/images/fkjy.png'}, - {title:'在线学习',describe:'视频培训发布',icon:'/pages/images/tx.png'} + {title:'发布信息',describe:'快速发布养殖知识|视频培训发布',icon:'/pages/images/fkjy.png'}, ], // 通知公告数据 currentNotice: 0, @@ -33,6 +32,15 @@ Page({ }) }, + + // 跳转发布信息 + bindPx() { + wx.navigateTo({ + url: '/pagesB/pages/training/training', + }) + }, + + // 在线问答列表 getforumList() { http.forumList({ @@ -73,34 +81,7 @@ Page({ }) }, - // 灾害/通知公告 - getDisaster() { - http.disaster({ - data: {}, - success: res => { - // 处理通知数据,添加时间戳 - const notices = res.rows.map(item => { - return { - ...item, - // // 判断是否是24小时内的通知 - // isNew: this.isNewNotification(item.createdTime) - } - }) - this.setData({ - noticeList: notices - }) - } - }) - }, - // // 判断通知是否在24小时内 - // isNewNotification(createdTime) { - // if (!createdTime) return false - // const noticeTime = new Date(createdTime.replace(/-/g, '/')).getTime() - // const now = new Date().getTime() - // const twentyFourHours = 24 * 60 * 60 * 1000 - // return now - noticeTime < twentyFourHours - // }, // 区域划分跳转 bindXzqh() { @@ -200,7 +181,6 @@ Page({ }, onLoad() { - this.getDisaster() this.getCarousel() this.getLocation() this.getforumList() @@ -276,7 +256,6 @@ Page({ // 重新加载所有数据 Promise.all([ new Promise(resolve => this.getUserInfo(resolve)), - new Promise(resolve => this.getDisaster(resolve)), new Promise(resolve => this.getCarousel(resolve)), new Promise(resolve => this.getforumList(resolve)), new Promise(resolve => this.getexperience(resolve)) diff --git a/pages/home/home.wxml b/pages/home/home.wxml index e5f58ab..da8165c 100644 --- a/pages/home/home.wxml +++ b/pages/home/home.wxml @@ -17,10 +17,6 @@ - - - - @@ -71,7 +67,7 @@ - + {{item.title}} {{item.describe}} diff --git a/pages/home/home.wxss b/pages/home/home.wxss index 1f1675d..78e70d4 100644 --- a/pages/home/home.wxss +++ b/pages/home/home.wxss @@ -13,21 +13,7 @@ padding-bottom: 40rpx; } - /* AI问诊 */ - .Aidiagnosis { - position: fixed; - right: 0; - bottom: 150px; - margin: 0 auto; - z-index: 100; - } - - .Aidiagnosis image { - width: 120rpx; - height: 120rpx; - border-radius: 50%; - } - + .orientation{ display: flex; align-items: center; @@ -267,7 +253,7 @@ display: flex; align-items: center; justify-content: space-between; - padding: 10rpx 30rpx; + padding: 20rpx 30rpx; margin-top: 30rpx; } .article2 view:first-child{ @@ -276,7 +262,7 @@ .article2 view:last-child{ color: #C5C6CC; font-size: 24rpx; - margin-top: 10rpx; + margin-top: 20rpx; } .article3 image{ width: 100rpx; diff --git a/pages/images/sjh.png b/pages/images/sjh.png new file mode 100644 index 0000000..eecea1b Binary files /dev/null and b/pages/images/sjh.png differ diff --git a/pagesA/images/jh.png b/pagesA/images/jh.png new file mode 100644 index 0000000..ce4d71f Binary files /dev/null and b/pagesA/images/jh.png differ diff --git a/pagesA/pages/askingSy/askingSy.js b/pagesA/pages/askingSy/askingSy.js deleted file mode 100644 index cd87bc3..0000000 --- a/pagesA/pages/askingSy/askingSy.js +++ /dev/null @@ -1,66 +0,0 @@ -// pagesA/pages/askingSy/askingSy.js -Page({ - - /** - * 页面的初始数据 - */ - data: { - - }, - - /** - * 生命周期函数--监听页面加载 - */ - onLoad(options) { - - }, - - /** - * 生命周期函数--监听页面初次渲染完成 - */ - onReady() { - - }, - - /** - * 生命周期函数--监听页面显示 - */ - onShow() { - - }, - - /** - * 生命周期函数--监听页面隐藏 - */ - onHide() { - - }, - - /** - * 生命周期函数--监听页面卸载 - */ - onUnload() { - - }, - - /** - * 页面相关事件处理函数--监听用户下拉动作 - */ - onPullDownRefresh() { - - }, - - /** - * 页面上拉触底事件的处理函数 - */ - onReachBottom() { - - }, - - /** - * 用户点击右上角分享 - */ - onShareAppMessage() { - - } -}) \ No newline at end of file diff --git a/pagesA/pages/askingSy/askingSy.json b/pagesA/pages/askingSy/askingSy.json deleted file mode 100644 index 8835af0..0000000 --- a/pagesA/pages/askingSy/askingSy.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "usingComponents": {} -} \ No newline at end of file diff --git a/pagesA/pages/askingSy/askingSy.wxml b/pagesA/pages/askingSy/askingSy.wxml deleted file mode 100644 index 2930432..0000000 --- a/pagesA/pages/askingSy/askingSy.wxml +++ /dev/null @@ -1,2 +0,0 @@ - -pagesA/pages/askingSy/askingSy.wxml \ No newline at end of file diff --git a/pagesA/pages/askingSy/askingSy.wxss b/pagesA/pages/askingSy/askingSy.wxss deleted file mode 100644 index 19af59e..0000000 --- a/pagesA/pages/askingSy/askingSy.wxss +++ /dev/null @@ -1 +0,0 @@ -/* pagesA/pages/askingSy/askingSy.wxss */ \ No newline at end of file diff --git a/pagesA/pages/carouselDetail/carouselDetail.js b/pagesA/pages/carouselDetail/carouselDetail.js new file mode 100644 index 0000000..c75096e --- /dev/null +++ b/pagesA/pages/carouselDetail/carouselDetail.js @@ -0,0 +1,154 @@ +import http from '../../../utils/api'; +const baseUrl = require('../../../utils/baseUrl'); + +Page({ + /** + * 页面的初始数据 + */ + data: { + baseUrl: baseUrl, + detailInfo: {}, + id: null, + cardAnimation: {} // 卡片动画数据 + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + if (options.id) { + this.setData({ id: options.id }); + this.getCarouselDetail(options.id); + this.initAnimation(); + } else { + wx.showToast({ + title: '参数错误', + icon: 'none' + }); + } + }, + + /** + * 初始化卡片动画 + */ + initAnimation() { + const animation = wx.createAnimation({ + duration: 600, + timingFunction: 'ease-out', + delay: 100 + }); + + animation.translateY(0).opacity(1).step(); + + this.setData({ + cardAnimation: animation.export() + }); + }, + + /** + * 获取轮播详情 + */ + getCarouselDetail(id) { + wx.showLoading({ title: '加载中...', mask: true }); + + http.carouselDetail({ + data: { id: id }, + success: (res) => { + wx.hideLoading(); + console.log('轮播详情:', res); + + if (res && res.code === 200 && res.data) { + this.setData({ + detailInfo: res.data + }); + wx.setNavigationBarTitle({ + title: res.data.title || '轮播详情' + }); + } else { + wx.showToast({ + title: res?.msg || '数据加载失败', + icon: 'none' + }); + } + }, + fail: (err) => { + wx.hideLoading(); + console.error('请求失败:', err); + wx.showToast({ + title: '网络错误', + icon: 'none' + }); + } + }); + }, + + /** + * 颜色调整函数(用于渐变效果) + */ + adjustColor(hex, percent) { + if (!hex) return '#4CAF50'; + // 简单实现:如果传入颜色,返回稍浅的版本 + // 这里为了简化,直接返回原色稍微变浅,实际项目中可使用颜色处理库 + return hex; + }, + + /** + * 图片加载错误处理 + */ + imageLoadError(e) { + console.warn('图片加载失败', e); + + }, + + + /** + * 返回上一页 + */ + goBack() { + wx.navigateBack({ + delta: 1 + }); + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() {}, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() {}, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() {}, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() {}, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() {}, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() {}, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + const { title, imageUrl } = this.data.detailInfo; + return { + title: title || '轮播详情', + imageUrl: this.data.baseUrl + (imageUrl || ''), + path: `/pages/carousel/detail/detail?id=${this.data.id}` + }; + } +}); \ No newline at end of file diff --git a/pagesA/pages/carouselDetail/carouselDetail.json b/pagesA/pages/carouselDetail/carouselDetail.json new file mode 100644 index 0000000..faa193e --- /dev/null +++ b/pagesA/pages/carouselDetail/carouselDetail.json @@ -0,0 +1,4 @@ +{ + "navigationBarTitleText":"轮播详情", + "usingComponents": {} +} \ No newline at end of file diff --git a/pagesA/pages/carouselDetail/carouselDetail.wxml b/pagesA/pages/carouselDetail/carouselDetail.wxml new file mode 100644 index 0000000..8903e06 --- /dev/null +++ b/pagesA/pages/carouselDetail/carouselDetail.wxml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + {{detailInfo.adsType}} + + + + + + + + + {{detailInfo.title || '无标题'}} + {{detailInfo.subtitle || '暂无副标题'}} + + + + + + + + + + + + + + 📐 + + 图片尺寸 + {{detailInfo.imageSize}} + + + + + + 👁️ + + 浏览次数 + {{detailInfo.viewCount}} + + + + + + + 📅 + + 创建时间 + {{detailInfo.createdAt}} + + + + + + 🔄 + + 更新时间 + {{detailInfo.updatedAt}} + + + + + + + + 状态 + + + {{detailInfo.isActive === 1 ? '有效' : '无效'}} + + + + + + + + 📝 + {{detailInfo.remark}} + + + + + + 长期有效 + + + \ No newline at end of file diff --git a/pagesA/pages/carouselDetail/carouselDetail.wxss b/pagesA/pages/carouselDetail/carouselDetail.wxss new file mode 100644 index 0000000..a2bb5b5 --- /dev/null +++ b/pagesA/pages/carouselDetail/carouselDetail.wxss @@ -0,0 +1,284 @@ +.carousel-detail-container { + min-height: 100vh; + background-color: var(--bg-color, #F8F9FA); + position: relative; + padding-bottom: 40rpx; + } + + /* 沉浸式头部 */ + .hero-section { + position: relative; + width: 100%; + height: 600rpx; + overflow: hidden; + } + + .hero-image { + width: 100%; + height: 100%; + filter: brightness(0.9); + transition: transform 0.3s ease; + } + + .hero-image:active { + transform: scale(1.02); + } + + .hero-overlay { + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 200rpx; + pointer-events: none; + } + + /* 毛玻璃返回按钮 */ + .nav-back { + position: absolute; + top: 60rpx; + left: 30rpx; + width: 72rpx; + height: 72rpx; + border-radius: 36rpx; + display: flex; + align-items: center; + justify-content: center; + font-size: 40rpx; + color: #333; + z-index: 10; + } + + .glass { + background: rgba(255, 255, 255, 0.25); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + border: 1rpx solid rgba(255, 255, 255, 0.3); + box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1); + } + + .page-title { + position: absolute; + top: 60rpx; + right: 30rpx; + padding: 16rpx 32rpx; + border-radius: 40rpx; + font-size: 26rpx; + color: #333; + font-weight: 500; + z-index: 10; + letter-spacing: 1rpx; + } + + /* 主要内容卡片 */ + .content-card { + margin: -100rpx 30rpx 0; + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + border-radius: 48rpx; + padding: 48rpx 32rpx; + box-shadow: 0 30rpx 60rpx rgba(0, 0, 0, 0.1), + 0 10rpx 30rpx rgba(0, 0, 0, 0.05); + position: relative; + z-index: 5; + border: 1rpx solid rgba(255, 255, 255, 0.5); + opacity: 0; + transform: translateY(50rpx); + animation: cardFloat 0.6s ease-out forwards; + } + + @keyframes cardFloat { + to { + opacity: 1; + transform: translateY(0); + } + } + + /* 标题区域 */ + .title-section { + margin-bottom: 40rpx; + } + + .main-title { + display: block; + font-size: 56rpx; + font-weight: 700; + line-height: 1.3; + margin-bottom: 16rpx; + letter-spacing: -0.5rpx; + } + + .sub-title { + display: block; + font-size: 30rpx; + color: #666; + line-height: 1.5; + font-weight: 400; + opacity: 0.8; + } + + /* 装饰分割线 */ + .divider { + display: flex; + align-items: center; + margin: 30rpx 0 40rpx; + } + + .divider-line { + flex: 1; + height: 2rpx; + opacity: 0.2; + } + + .divider-dot { + width: 8rpx; + height: 8rpx; + border-radius: 4rpx; + margin: 0 20rpx; + opacity: 0.5; + } + + /* 信息网格 */ + .info-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 24rpx; + margin-bottom: 40rpx; + } + + .info-item { + background: rgba(0, 0, 0, 0.02); + border-radius: 28rpx; + padding: 28rpx 20rpx; + display: flex; + align-items: center; + border: 1rpx solid rgba(0, 0, 0, 0.03); + transition: all 0.3s ease; + } + + .info-item:active { + transform: scale(0.98); + background: rgba(0, 0, 0, 0.04); + } + + .info-icon { + font-size: 48rpx; + margin-right: 20rpx; + filter: drop-shadow(0 4rpx 8rpx rgba(0, 0, 0, 0.1)); + } + + .info-content { + flex: 1; + display: flex; + flex-direction: column; + } + + .info-label { + font-size: 22rpx; + color: #999; + margin-bottom: 8rpx; + letter-spacing: 0.5rpx; + } + + .info-value { + font-size: 28rpx; + font-weight: 600; + color: #333; + word-break: break-all; + } + + /* 状态特殊样式 */ + .status-item .info-content { + flex-direction: row; + align-items: center; + justify-content: space-between; + } + + .status-badge { + display: flex; + align-items: center; + padding: 8rpx 16rpx; + border-radius: 40rpx; + border-width: 1rpx; + border-style: solid; + background-color: rgba(76, 175, 80, 0.1); + } + + .status-dot { + width: 16rpx; + height: 16rpx; + border-radius: 8rpx; + margin-right: 8rpx; + animation: pulse 2s infinite; + } + + @keyframes pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.6; } + } + + .status-text { + font-size: 24rpx; + font-weight: 500; + } + + /* 备注区域 */ + .remark-section { + background: rgba(0, 0, 0, 0.02); + border-radius: 28rpx; + padding: 28rpx; + margin-bottom: 40rpx; + display: flex; + border-left: 8rpx solid var(--text-color, #2E7D32); + } + + .remark-icon { + font-size: 40rpx; + margin-right: 20rpx; + } + + .remark-content { + flex: 1; + font-size: 28rpx; + color: #444; + line-height: 1.6; + } + + + /* 始终有效标识 */ + .always-valid { + display: flex; + align-items: center; + justify-content: center; + margin-top: 30rpx; + padding: 20rpx; + background: linear-gradient(135deg, rgba(255, 215, 0, 0.1), rgba(255, 215, 0, 0.05)); + border-radius: 40rpx; + border: 1rpx solid rgba(255, 215, 0, 0.3); + } + + .valid-icon { + font-size: 32rpx; + margin-right: 12rpx; + animation: starTwinkle 1.5s infinite; + } + + @keyframes starTwinkle { + 0%, 100% { opacity: 1; transform: scale(1); } + 50% { opacity: 0.7; transform: scale(1.1); } + } + + .valid-text { + font-size: 26rpx; + color: #B8860B; + font-weight: 500; + } + + /* 响应式调整 */ + @media (min-width: 768px) { + .content-card { + max-width: 700rpx; + margin: -100rpx auto 0; + } + } \ No newline at end of file diff --git a/pagesB/images/bo.png b/pagesB/images/bo.png new file mode 100644 index 0000000..70f5106 Binary files /dev/null and b/pagesB/images/bo.png differ diff --git a/pagesB/images/hf.png b/pagesB/images/hf.png new file mode 100644 index 0000000..02b5a9f Binary files /dev/null and b/pagesB/images/hf.png differ diff --git a/pagesB/images/lll.png b/pagesB/images/lll.png new file mode 100644 index 0000000..e40135b Binary files /dev/null and b/pagesB/images/lll.png differ diff --git a/pagesB/images/sou.png b/pagesB/images/sou.png new file mode 100644 index 0000000..f90d5d6 Binary files /dev/null and b/pagesB/images/sou.png differ diff --git a/pagesB/pages/administrativeDivision/administrativeDivision.js b/pagesB/pages/administrativeDivision/administrativeDivision.js new file mode 100644 index 0000000..028d847 --- /dev/null +++ b/pagesB/pages/administrativeDivision/administrativeDivision.js @@ -0,0 +1,286 @@ +import http from '../../../utils/api' + +Page({ + /** + * 页面的初始数据 + */ + data: { + regionList: [], // 当前显示的区域列表 + selectedRegions: [], // 已选择的区域路径 + currentParentCode: '', // 当前父级code + loading: false, + showPicker: false, + regionTitle: '请选择区域', + autoShowPicker: false // 新增:控制是否自动弹出选择器 + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + // 首次加载,获取第一级数据 + this.getRegionData('', () => { + // 首次加载完成后自动弹出选择器 + this.setData({ + showPicker: true, + regionTitle: '请选择区域' + }) + }) + }, + + // 获取区域数据 + getRegionData(parentCode, callback) { + this.setData({ + loading: true + }) + + http.areaChildren({ + data: { + parentCode: parentCode || '' + }, + success: res => { + console.log('区域数据响应:', res) + if (res.code === 200 && res.data && res.data.length > 0) { + this.setData({ + regionList: res.data, + currentParentCode: parentCode, + loading: false + }) + } else { + // 没有更多数据了,说明已经是最后一级 + this.setData({ + loading: false, + regionList: [] + }) + + // 如果是最后一级,关闭选择器 + if (this.data.showPicker) { + this.setData({ + showPicker: false + }) + wx.showToast({ + title: '已选择到最后一级', + icon: 'none' + }) + } + } + + // 执行回调 + if (callback) { + callback() + } + }, + fail: err => { + console.error('请求失败:', err) + this.setData({ + loading: false + }) + wx.showToast({ + title: '加载失败', + icon: 'none' + }) + + if (callback) { + callback() + } + } + }) + }, + + // 开始选择(点击按钮时调用) + startSelection() { + // 如果还没有选择任何区域,重新加载第一级 + if (this.data.selectedRegions.length === 0) { + this.getRegionData('', () => { + this.setData({ + showPicker: true, + regionTitle: '请选择区域' + }) + }) + } else { + // 如果有已选择的区域,加载下一级 + const lastRegion = this.data.selectedRegions[this.data.selectedRegions.length - 1] + this.loadAndShowNextLevel(lastRegion.code) + } + }, + + // 加载并显示下一级区域选择器 + loadAndShowNextLevel(parentCode) { + this.getRegionData(parentCode, () => { + if (this.data.regionList.length > 0) { + // 有下一级数据,自动弹出选择器 + this.setData({ + showPicker: true, + regionTitle: `请选择${this.data.selectedRegions[this.data.selectedRegions.length - 1].name}的下一级区域` + }) + } else { + // 没有下一级数据,提示用户 + wx.showToast({ + title: '已经是最后一级,无法继续选择', + icon: 'none' + }) + } + }) + }, + + // 关闭选择器 + closePicker() { + this.setData({ + showPicker: false + }) + }, + + // 选择区域 + selectRegion(e) { + const index = e.currentTarget.dataset.index + const region = this.data.regionList[index] + + console.log('选择的区域:', region) + + // 获取当前已选择的最后一级 + const lastSelectedRegion = this.data.selectedRegions.length > 0 ? + this.data.selectedRegions[this.data.selectedRegions.length - 1] : + null + + // 检查是否是同级选择(替换最后一级) + const isSameLevel = lastSelectedRegion && + lastSelectedRegion.parentCode === region.parentCode + + let selectedRegions = [...this.data.selectedRegions] + + if (isSameLevel) { + // 同级选择,替换最后一级 + selectedRegions[selectedRegions.length - 1] = { + code: region.code, + name: region.name, + parentCode: region.parentCode + } + } else { + // 选择下一级,添加到路径 + selectedRegions.push({ + code: region.code, + name: region.name, + parentCode: region.parentCode + }) + } + + this.setData({ + selectedRegions + }) + + // 关闭当前选择器 + this.setData({ + showPicker: false + }) + + // 延迟一段时间后自动加载并显示下一级选择器 + setTimeout(() => { + this.loadAndShowNextLevel(region.code) + }, 300) + }, + + // 重新选择(点击已选择的任意层级) + reSelectRegion(e) { + const index = e.currentTarget.dataset.index + + // 截断到指定级别(包括点击的层级) + const selectedRegions = this.data.selectedRegions.slice(0, index + 1) + + this.setData({ + selectedRegions + }) + + // 获取该层级的数据 + const targetRegion = selectedRegions[selectedRegions.length - 1] + + // 获取点击层级的同级数据并显示选择器 + this.getRegionData(targetRegion.parentCode, () => { + this.setData({ + showPicker: true, + regionTitle: index === 0 ? + '请选择区域' : + `请选择${this.data.selectedRegions[index - 1]?.name || '区域'}的下一级` + }) + }) + }, + + // 完成选择 + completeSelection() { + if (this.data.selectedRegions.length === 0) { + wx.showToast({ + title: '请先选择区域', + icon: 'none' + }) + return + } + + const lastRegion = this.data.selectedRegions[this.data.selectedRegions.length - 1] + + // 这里可以调用你的业务接口,传递parentCode + this.submitRegion(lastRegion.code) + }, + + // 提交选择的区域(示例) + submitRegion(parentCode) { + console.log('提交的parentCode:', parentCode) + console.log('完整选择路径:', this.data.selectedRegions) + http.userCode({ + data: { + areaCode: parentCode + }, + success: res => { + console.log(11111, res); + if (res.code == 200) { + wx.showModal({ + title: '选择完成', + content: `已选择到: ${this.data.selectedRegions.map(r => r.name).join(' > ')}`, + showCancel: false, + success: (res) => { + if (res.confirm) { + wx.switchTab({ + url: '/pages/home/home', + }) + } + } + }) + } + } + }) + + + }, + + // 重置选择 + resetSelection() { + wx.showModal({ + title: '确认重置', + content: '确定要重置所有选择吗?', + success: (res) => { + if (res.confirm) { + this.setData({ + selectedRegions: [], + regionList: [], + currentParentCode: '', + showPicker: false + }) + + // 重新获取第一级数据 + this.getRegionData('', () => { + // 重置后自动弹出第一级选择器 + this.setData({ + showPicker: true, + regionTitle: '请选择区域' + }) + }) + } + } + }) + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + + } +}) \ No newline at end of file diff --git a/pagesB/pages/administrativeDivision/administrativeDivision.json b/pagesB/pages/administrativeDivision/administrativeDivision.json new file mode 100644 index 0000000..d5f59cc --- /dev/null +++ b/pagesB/pages/administrativeDivision/administrativeDivision.json @@ -0,0 +1,4 @@ +{ + "navigationBarTitleText":"区域选择", + "usingComponents": {} +} \ No newline at end of file diff --git a/pagesB/pages/administrativeDivision/administrativeDivision.wxml b/pagesB/pages/administrativeDivision/administrativeDivision.wxml new file mode 100644 index 0000000..24e78af --- /dev/null +++ b/pagesB/pages/administrativeDivision/administrativeDivision.wxml @@ -0,0 +1,95 @@ + + + + 已选择: + + + {{item.name}} + > + + + + + + + + + + + + + + + + + + + + + {{regionTitle}} + × + + + + + + + 加载中... + + + + + + + {{item.name}} + + + + + + + + {{selectedRegions.length > 0 ? '已选择到最后一级' : '暂无区域数据'}} + + + + + + + + + + 使用说明: + 1. 点击"开始选择区域"开始选择\n2. 选择后会加载下一级区域\n3. 点击已选择区域的任意级别可以重新选择\n4. 选择最后一级时会直接替换\n5. 完成选择后点击"完成选择"按钮 + + \ No newline at end of file diff --git a/pagesB/pages/administrativeDivision/administrativeDivision.wxss b/pagesB/pages/administrativeDivision/administrativeDivision.wxss new file mode 100644 index 0000000..524ead8 --- /dev/null +++ b/pagesB/pages/administrativeDivision/administrativeDivision.wxss @@ -0,0 +1,316 @@ +.container { + padding: 30rpx; + min-height: 100vh; + background: #f5f5f5; +} + +/* 已选择路径 */ +.selected-path { + background: white; + border-radius: 16rpx; + padding: 30rpx; + margin-bottom: 30rpx; + box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05); +} + +.path-title { + font-size: 28rpx; + color: #666; + display: block; + margin-bottom: 20rpx; +} + +.path-items { + display: flex; + flex-wrap: wrap; + align-items: center; + margin-bottom: 20rpx; +} + +.path-item { + display: flex; + align-items: center; + padding: 12rpx 20rpx; + background: #f0f8ff; + border-radius: 8rpx; + margin-right: 10rpx; + margin-bottom: 10rpx; + cursor: pointer; +} + +.path-item:active { + background: #e1f0ff; +} + +.path-item.last { + background: #e6f7ff; + border: 1rpx solid #1890ff; +} + +.path-item text:first-child { + font-size: 28rpx; + color: #1890ff; + font-weight: 500; +} + +.separator { + margin-left: 10rpx; + color: #999; +} + + +/* 选择按钮 */ +.select-btn-container { + margin: 40rpx 0; +} + +.select-btn { + width: 100%; + background: linear-gradient(135deg, #1890ff, #096dd9); + color: white; + border-radius: 12rpx; + font-size: 32rpx; + height: 88rpx; + line-height: 88rpx; + border: none; +} + +.select-btn::after { + border: none; +} + +.select-btn[loading] { + opacity: 0.8; +} + +.select-btn:active { + opacity: 0.9; +} + +/* 操作按钮 */ +.action-buttons { + display: flex; + gap: 20rpx; + margin-top: 50rpx; +} + +.btn { + flex: 1; + border-radius: 12rpx; + font-size: 28rpx; + height: 80rpx; + line-height: 80rpx; + border: none; +} + +.btn::after { + border: none; +} + +.complete-btn { + background: #07c160; + color: white; +} + +.complete-btn[disabled] { + background: #ccc; + color: #999; +} + +.complete-btn:active:not([disabled]) { + background: #06ad56; +} + +.reset-btn { + background: #fff; + color: #ff4d4f; + border: 1rpx solid #ff4d4f !important; +} + +.reset-btn:active { + background: #fff5f5; +} + +/* 选择器模态框 */ +.picker-modal { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 1000; +} + +.picker-mask { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + animation: fadeIn 0.3s ease; +} + +.picker-content { + position: absolute; + bottom: 0; + left: 0; + right: 0; + background: white; + border-radius: 32rpx 32rpx 0 0; + max-height: 70vh; + display: flex; + flex-direction: column; + animation: slideUp 0.3s ease; +} + +.picker-header { + padding: 32rpx 40rpx; + border-bottom: 1rpx solid #f0f0f0; + display: flex; + align-items: center; + justify-content: space-between; + position: relative; +} + +.picker-title { + font-size: 32rpx; + color: #333; + font-weight: 600; + flex: 1; + text-align: center; +} + +.picker-close { + font-size: 48rpx; + color: #999; + position: absolute; + right: 30rpx; + top: 50%; + transform: translateY(-50%); + width: 60rpx; + height: 60rpx; + text-align: center; + line-height: 60rpx; +} + +.picker-close:active { + background: #f5f5f5; + border-radius: 50%; +} + +.picker-body { + flex: 1; + overflow: hidden; +} + +/* 加载状态 */ +.loading-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 300rpx; +} + +.loading-spinner { + width: 60rpx; + height: 60rpx; + border: 4rpx solid #f0f0f0; + border-top-color: #1890ff; + border-radius: 50%; + animation: spin 1s linear infinite; + margin-bottom: 20rpx; +} + +.loading-text { + font-size: 28rpx; + color: #999; +} + +/* 区域列表 */ +.region-list { + height: 60vh; +} + +.region-item { + padding: 32rpx 40rpx; + border-bottom: 1rpx solid #f0f0f0; + display: flex; + align-items: center; + justify-content: space-between; +} + +.region-item:active { + background: #f5f5f5; +} + +.region-info { + flex: 1; +} + +.region-name { + font-size: 30rpx; + color: #333; + display: block; + margin-bottom: 8rpx; +} + +.arrow { + color: #ccc; + font-size: 36rpx; + margin-left: 20rpx; +} + +/* 空状态 */ +.empty-state { + display: flex; + justify-content: center; + align-items: center; + height: 200rpx; +} + +.empty-text { + font-size: 28rpx; + color: #999; +} + +/* 使用说明 */ +.instruction { + margin-top: 60rpx; + padding: 24rpx; + background: white; + border-radius: 12rpx; + border-left: 6rpx solid #1890ff; +} + +.instruction-title { + font-size: 28rpx; + color: #1890ff; + font-weight: 600; + display: block; + margin-bottom: 16rpx; +} + +.instruction-text { + font-size: 26rpx; + color: #666; + line-height: 1.6; + white-space: pre-line; +} + +/* 动画 */ +@keyframes fadeIn { + from { opacity: 0; } + to { opacity: 1; } +} + +@keyframes slideUp { + from { transform: translateY(100%); } + to { transform: translateY(0); } +} + +@keyframes spin { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } +} \ No newline at end of file diff --git a/pagesB/pages/publishAdd/publishAdd.js b/pagesB/pages/publishAdd/publishAdd.js new file mode 100644 index 0000000..2639ad4 --- /dev/null +++ b/pagesB/pages/publishAdd/publishAdd.js @@ -0,0 +1,580 @@ +import http from '../../../utils/api' +const baseUrl = require('../../../utils/baseUrl') + +Page({ + data: { + baseUrl, + currentTab: 'article', + + // 文章相关 + articleForm: { + title: '', + subtitle: '', + category: '', + content: '', + coverImage: '' // 这里存储服务器返回的文件名 + }, + articleCoverTemp: '', // 本地临时路径,用于预览 + articleCategory: null, + articleCategories: [], + + // 视频相关 + videoForm: { + title: '', + description: '', + category: '', + videoUrl: '', // 这里存储服务器返回的视频文件名 + coverImage: '' // 这里存储服务器返回的封面文件名 + }, + videoCoverTemp: '', // 本地临时路径,用于预览 + videoUrlTemp: '', // 本地临时路径,用于显示 + videoCategory: null, + videoCategories: [], + + // UI状态 + submitting: false, + isUploading: false, // 防止重复上传 + showLoadingMask: false, // 显示加载遮罩层 + loadingText: '发布中...', // 加载提示文字 + + // 表单验证状态 + articleFormValid: false, + videoFormValid: false, + }, + + onLoad() { + this.getArticleCategories() + this.getVideoCategories() + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() { + // 页面卸载时重置状态 + this.setData({ + submitting: false, + showLoadingMask: false + }); + }, + + // 获取文章分类 + getArticleCategories() { + http.articleZd({ + data: { + dictType: 'article_category' + }, + success: res => { + if (res.rows) { + this.setData({ + articleCategories: res.rows + }) + } + } + }) + }, + + // 获取视频分类 + getVideoCategories() { + http.videoZd({ + data: { + dictType: 'video_category' + }, + success: res => { + if (res.rows) { + this.setData({ + videoCategories: res.rows + }) + } + } + }) + }, + + // 切换标签 + switchTab(e) { + const type = e.currentTarget.dataset.type + if (type === this.data.currentTab) return + this.setData({ currentTab: type }) + }, + + // 验证文章表单 + validateArticleForm() { + const { articleForm } = this.data + const isValid = !!(articleForm.title?.trim() && articleForm.category && articleForm.content?.trim()) + this.setData({ articleFormValid: isValid }) + return isValid + }, + + // 验证视频表单 + validateVideoForm() { + const { videoForm } = this.data + const isValid = !!(videoForm.title?.trim() && videoForm.category && videoForm.videoUrl) + this.setData({ videoFormValid: isValid }) + return isValid + }, + + // 文章输入处理 + onArticleInput(e) { + const field = e.currentTarget.dataset.field + const value = e.detail.value + this.setData({ + [`articleForm.${field}`]: value + }, () => { + this.validateArticleForm() + }) + }, + + // 视频输入处理 + onVideoInput(e) { + const field = e.currentTarget.dataset.field + const value = e.detail.value + this.setData({ + [`videoForm.${field}`]: value + }, () => { + this.validateVideoForm() + }) + }, + + // 文章分类选择 + onArticleCategoryChange(e) { + const index = e.detail.value + const category = this.data.articleCategories[index] + this.setData({ + 'articleForm.category': category.dictValue, + articleCategory: category + }, () => { + this.validateArticleForm() + }) + }, + + // 视频分类选择 + onVideoCategoryChange(e) { + const index = e.detail.value + const category = this.data.videoCategories[index] + this.setData({ + 'videoForm.category': category.dictValue, + videoCategory: category + }, () => { + this.validateVideoForm() + }) + }, + + // 选择封面图片(文章或视频) + chooseCover(e) { + if (this.data.isUploading) { + wx.showToast({ + title: '正在上传中,请稍候', + icon: 'none' + }); + return; + } + + const type = e.currentTarget.dataset.type + + wx.chooseMedia({ + count: 1, + mediaType: ['image'], + sourceType: ['album', 'camera'], + sizeType: ['compressed'], + success: (res) => { + if (res.tempFiles && res.tempFiles.length > 0) { + this.setData({ + isUploading: true + }); + + // 显示加载提示 + wx.showLoading({ + title: '上传图片中...', + mask: true + }); + + // 上传图片 + this.uploadImage(res.tempFiles[0].tempFilePath, type); + } + } + }); + }, + + // 上传单张图片 + uploadImage(tempPath, type) { + wx.uploadFile({ + url: baseUrl + '/common/upload', + header: { + 'Authorization': 'Bearer ' + wx.getStorageSync('token') + }, + filePath: tempPath, + name: 'file', + success: (uploadRes) => { + try { + const result = JSON.parse(uploadRes.data); + if (result.code === 200 || result.fileName) { + const serverPath = result.fileName || result.url; + + if (type === 'article') { + // 文章封面 + this.setData({ + articleCoverTemp: tempPath, + 'articleForm.coverImage': serverPath, + isUploading: false + }); + } else { + // 视频封面 + this.setData({ + videoCoverTemp: tempPath, + 'videoForm.coverImage': serverPath, + isUploading: false + }, () => { + this.validateVideoForm(); + }); + } + + wx.hideLoading(); + wx.showToast({ + title: '上传成功', + icon: 'success' + }); + } else { + throw new Error(result.msg || '上传失败'); + } + } catch (error) { + wx.hideLoading(); + this.setData({ + isUploading: false + }); + wx.showToast({ + title: error.message || '上传失败', + icon: 'none' + }); + } + }, + fail: (error) => { + wx.hideLoading(); + this.setData({ + isUploading: false + }); + wx.showToast({ + title: '网络请求失败', + icon: 'none' + }); + } + }); + }, + + // 选择视频 + chooseVideo() { + if (this.data.isUploading) { + wx.showToast({ + title: '正在上传中,请稍候', + icon: 'none' + }); + return; + } + + wx.chooseMedia({ + count: 1, + mediaType: ['video'], + sourceType: ['album', 'camera'], + maxDuration: 300, + success: (res) => { + if (res.tempFiles && res.tempFiles.length > 0) { + this.setData({ + isUploading: true, + videoUrlTemp: res.tempFiles[0].tempFilePath // 先显示本地路径 + }); + + // 显示加载提示 + wx.showLoading({ + title: '上传视频中...', + mask: true + }); + + // 上传视频 + this.uploadVideo(res.tempFiles[0].tempFilePath); + } + } + }); + }, + + // 上传视频 + uploadVideo(tempPath) { + wx.uploadFile({ + url: baseUrl + '/common/upload', + header: { + 'Authorization': 'Bearer ' + wx.getStorageSync('token') + }, + filePath: tempPath, + name: 'file', + success: (uploadRes) => { + try { + const result = JSON.parse(uploadRes.data); + if (result.code === 200 || result.fileName) { + const serverPath = result.fileName || result.url; + + this.setData({ + 'videoForm.videoUrl': serverPath, + isUploading: false + }, () => { + this.validateVideoForm(); + }); + + wx.hideLoading(); + wx.showToast({ + title: '上传成功', + icon: 'success' + }); + } else { + throw new Error(result.msg || '上传失败'); + } + } catch (error) { + wx.hideLoading(); + this.setData({ + videoUrlTemp: '', // 上传失败清空临时路径 + isUploading: false + }); + wx.showToast({ + title: error.message || '上传失败', + icon: 'none' + }); + } + }, + fail: (error) => { + wx.hideLoading(); + this.setData({ + videoUrlTemp: '', // 上传失败清空临时路径 + isUploading: false + }); + wx.showToast({ + title: '网络请求失败', + icon: 'none' + }); + } + }); + }, + + // 提交文章 + submitArticle() { + const { articleForm, submitting, isUploading } = this.data + + if (submitting) return + + // 检查是否还有图片正在上传 + if (isUploading) { + wx.showToast({ + title: '图片正在上传中,请稍后提交', + icon: 'none' + }); + return; + } + + // 表单验证 + if (!this.validateArticleForm()) { + if (!articleForm.title?.trim()) { + this.showError('请输入文章标题') + } else if (!articleForm.category) { + this.showError('请选择文章分类') + } else if (!articleForm.content?.trim()) { + this.showError('请输入文章内容') + } + return + } + + // 显示加载遮罩层 + this.setData({ + submitting: true, + showLoadingMask: true, + loadingText: '发布中...' + }); + + // 构建提交数据 + const submitData = { + title: articleForm.title.trim(), + subtitle: articleForm.subtitle?.trim() || '', + content: articleForm.content.trim(), + coverImage: articleForm.coverImage || '', + category: articleForm.category + } + + // 调用接口 + http.articleAdd({ + data: submitData, + success: (res) => { + if (res.code == 200) { + this.setData({ + loadingText: '发布成功' + }); + + setTimeout(() => { + this.setData({ + submitting: false, + showLoadingMask: false + }); + + wx.showToast({ + title: '发布成功', + icon: 'success', + duration: 1500, + success: () => { + setTimeout(() => { + wx.navigateBack() + }, 1500); + } + }); + }, 1000); + } else { + this.setData({ + loadingText: '发布失败' + }); + + setTimeout(() => { + this.setData({ + submitting: false, + showLoadingMask: false + }); + + wx.showToast({ + title: res.msg || '发布失败,请重试', + icon: 'none', + duration: 2000 + }); + }, 1000); + } + }, + fail: (err) => { + this.setData({ + loadingText: '网络错误' + }); + + setTimeout(() => { + this.setData({ + submitting: false, + showLoadingMask: false + }); + + wx.showToast({ + title: '网络异常,请检查网络后重试', + icon: 'none', + duration: 2000 + }); + }, 1000); + } + }) + }, + + // 提交视频 + submitVideo() { + const { videoForm, submitting, isUploading } = this.data + + if (submitting) return + + // 检查是否还有图片或视频正在上传 + if (isUploading) { + wx.showToast({ + title: '文件正在上传中,请稍后提交', + icon: 'none' + }); + return; + } + + // 表单验证 + if (!this.validateVideoForm()) { + if (!videoForm.title?.trim()) { + this.showError('请输入视频标题') + } else if (!videoForm.category) { + this.showError('请选择视频分类') + } else if (!videoForm.videoUrl) { + this.showError('请选择视频') + } + return + } + + // 显示加载遮罩层 + this.setData({ + submitting: true, + showLoadingMask: true, + loadingText: '发布中...' + }); + + // 构建提交数据 + const submitData = { + title: videoForm.title.trim(), + description: videoForm.description?.trim() || '', + videoUrl: videoForm.videoUrl, + coverImage: videoForm.coverImage || '', + category: videoForm.category + } + + // 调用接口 + http.videoAdd({ + data: submitData, + success: (res) => { + if (res.code == 200) { + this.setData({ + loadingText: '发布成功' + }); + + setTimeout(() => { + this.setData({ + submitting: false, + showLoadingMask: false + }); + + wx.showToast({ + title: '发布成功', + icon: 'success', + duration: 1500, + success: () => { + setTimeout(() => { + wx.navigateBack() + }, 1500); + } + }); + }, 1000); + } else { + this.setData({ + loadingText: '发布失败' + }); + + setTimeout(() => { + this.setData({ + submitting: false, + showLoadingMask: false + }); + + wx.showToast({ + title: res.msg || '发布失败,请重试', + icon: 'none', + duration: 2000 + }); + }, 1000); + } + }, + fail: (err) => { + this.setData({ + loadingText: '网络错误' + }); + + setTimeout(() => { + this.setData({ + submitting: false, + showLoadingMask: false + }); + + wx.showToast({ + title: '网络异常,请检查网络后重试', + icon: 'none', + duration: 2000 + }); + }, 1000); + } + }) + }, + + // 显示错误提示 + showError(msg) { + wx.showToast({ + title: msg, + icon: 'none', + duration: 2000 + }); + } +}) \ No newline at end of file diff --git a/pagesB/pages/publishAdd/publishAdd.json b/pagesB/pages/publishAdd/publishAdd.json new file mode 100644 index 0000000..734e9ba --- /dev/null +++ b/pagesB/pages/publishAdd/publishAdd.json @@ -0,0 +1,4 @@ +{ + "navigationBarTitleText":"发布", + "usingComponents": {} +} \ No newline at end of file diff --git a/pagesB/pages/publishAdd/publishAdd.wxml b/pagesB/pages/publishAdd/publishAdd.wxml new file mode 100644 index 0000000..9b70b6c --- /dev/null +++ b/pagesB/pages/publishAdd/publishAdd.wxml @@ -0,0 +1,205 @@ + + + + + + + + + + + + 发布文章 + + + 发布视频 + + + + + +
+ + + + + + 文章标题 + * + + + + + + + + + + 副标题 + 选填 + + + + + + + + + + 文章分类 + * + + + + + + {{articleCategory.dictLabel}} + + + + 请选择文章分类 + + + + + + + + + + + + 封面图片 + 选填 + + + + + + + + 点击上传封面 + + + 建议尺寸 16:9,不超过5M + + + + + + + + + 文章内容 + * + +