From b34a015c4db21c0ae86ec9537d3f010e42704a1d Mon Sep 17 00:00:00 2001 From: ZhaoYang <565837861@qq.com> Date: Wed, 4 Feb 2026 18:49:35 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9C=A8=E7=BA=BF=E5=88=86=E4=BA=AB=EF=BC=8C?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=EF=BC=8C=E8=AF=A6=E6=83=85=EF=BC=8C=E5=88=97?= =?UTF-8?q?=E8=A1=A8=EF=BC=8C=E5=88=86=E7=B1=BB=E3=80=82=E4=B8=AA=E4=BA=BA?= =?UTF-8?q?=E4=B8=AD=E5=BF=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.json | 7 +- pages/home/home.js | 55 +- pages/home/home.wxml | 66 +- pages/home/home.wxss | 83 +- pages/personal/personal.js | 7 + pages/personal/personal.wxml | 2 +- pagesA/pages/attestation/attestation.js | 317 +++++ pagesA/pages/attestation/attestation.json | 4 + pagesA/pages/attestation/attestation.wxml | 185 +++ pagesA/pages/attestation/attestation.wxss | 546 ++++++++ .../experienceDetails/experienceDetails.js | 34 + .../experienceDetails/experienceDetails.json | 4 + .../experienceDetails/experienceDetails.wxml | 46 + .../experienceDetails/experienceDetails.wxss | 146 ++ pagesB/pages/experienceList/experienceList.js | 206 +++ .../pages/experienceList/experienceList.json | 4 + .../pages/experienceList/experienceList.wxml | 80 ++ .../pages/experienceList/experienceList.wxss | 332 +++++ pagesB/pages/forumlist/forumlist.js | 641 +++++---- pagesB/pages/forumlist/forumlist.json | 1 + pagesB/pages/forumlist/forumlist.wxml | 330 ++--- pagesB/pages/forumlist/forumlist.wxss | 1200 +++++++++++------ pagesB/pages/onlineAsk/onlineAsk.js | 455 +++---- pagesB/pages/onlineAsk/onlineAsk.wxml | 66 +- pagesB/pages/onlineAsk/onlineAsk.wxss | 30 +- utils/api.js | 44 +- utils/baseUrl.js | 3 +- 27 files changed, 3672 insertions(+), 1222 deletions(-) create mode 100644 pagesA/pages/attestation/attestation.js create mode 100644 pagesA/pages/attestation/attestation.json create mode 100644 pagesA/pages/attestation/attestation.wxml create mode 100644 pagesA/pages/attestation/attestation.wxss create mode 100644 pagesB/pages/experienceDetails/experienceDetails.js create mode 100644 pagesB/pages/experienceDetails/experienceDetails.json create mode 100644 pagesB/pages/experienceDetails/experienceDetails.wxml create mode 100644 pagesB/pages/experienceDetails/experienceDetails.wxss create mode 100644 pagesB/pages/experienceList/experienceList.js create mode 100644 pagesB/pages/experienceList/experienceList.json create mode 100644 pagesB/pages/experienceList/experienceList.wxml create mode 100644 pagesB/pages/experienceList/experienceList.wxss diff --git a/app.json b/app.json index b7785a1..38723fa 100644 --- a/app.json +++ b/app.json @@ -18,7 +18,8 @@ "pages/expert/expert", "pages/expertChat/expertChat", "pages/medicine/medicine", - "pages/medicineDetails/medicineDetails" + "pages/medicineDetails/medicineDetails", + "pages/attestation/attestation" ] }, { @@ -31,7 +32,9 @@ "pages/administrativeDivision/administrativeDivision", "pages/wzDetails/wzDetails", "pages/spDetails/spDetails", - "pages/forumlist/forumlist" + "pages/forumlist/forumlist", + "pages/experienceList/experienceList", + "pages/experienceDetails/experienceDetails" ], "independent": true } diff --git a/pages/home/home.js b/pages/home/home.js index a94f96a..e15bac2 100644 --- a/pages/home/home.js +++ b/pages/home/home.js @@ -9,6 +9,7 @@ Page({ // 通知公告数据 currentNotice: 0, noticeList: [], + forum:[] }, @@ -17,7 +18,6 @@ Page({ http.UserInfo({ data:{}, success:res=>{ - console.log(789,res); this.setData({ user:res.data.area }) @@ -25,6 +25,36 @@ Page({ }) }, + // 在线问答列表 + getforumList(){ + http.forumList({ + data:{}, + success:res=>{ + const zxwd = [] + zxwd.push(res.rows[0]) + this.setData({ + forum:zxwd + }) + } + }) + }, + + // 经验分享列表 + getexperience(){ + http.experience({ + data:{}, + success:res=>{ + console.log(111,res); + const zyfx = [] + zyfx.push(res.rows[0]) + this.setData({ + suffer:zyfx + }) + } + }) + }, + + // 轮播 getCarousel() { @@ -115,12 +145,29 @@ Page({ }, // 问答详情 - bindTw() { + bindTw(e) { + console.log(e); + const id = e.currentTarget.dataset.id + wx.navigateTo({ + url: `/pagesB/pages/onlineAsk/onlineAsk?id=${id}`, + }) + }, + + // 经验分享列表 + viewexperience(){ wx.navigateTo({ - url: '/pagesB/pages/onlineAsk/onlineAsk', + url: '/pagesB/pages/experienceList/experienceList', }) }, + // 经验分享详情 + bindfx(e){ + const id = e.currentTarget.dataset.id + wx.navigateTo({ + url: `/pagesB/pages/experienceDetails/experienceDetails?id=${id}`, + }) + }, + //获取当前位置信息 getLocation() { @@ -150,6 +197,8 @@ Page({ this.getDisaster() this.getCarousel() this.getLocation() + this.getforumList() + this.getexperience() }, onShow() { diff --git a/pages/home/home.wxml b/pages/home/home.wxml index db1c59c..84db7a7 100644 --- a/pages/home/home.wxml +++ b/pages/home/home.wxml @@ -15,7 +15,6 @@ {{user.name}} - @@ -120,28 +119,77 @@ - + - 发烧、流鼻涕、越来越瘦是什么原因?应该怎么治疗? + {{item.title}} + + {{item.createdAt}} + + + + + + + + + + + + + + + 经验分享 + 分享自己养殖经验 + + + 查看全部 + + + + + + + + + {{item.title}} + + + + + - 2025-12-25 + {{item.publishTime}} + \ No newline at end of file diff --git a/pages/home/home.wxss b/pages/home/home.wxss index 4c9549c..499d7fd 100644 --- a/pages/home/home.wxss +++ b/pages/home/home.wxss @@ -429,7 +429,7 @@ .title-text { font-size: 38rpx; font-weight: bold; - color: #333; + color: #7ad1cb; margin-bottom: 8rpx; position: relative; padding-left: 20rpx; @@ -447,12 +447,37 @@ border-radius: 4rpx; } + +.title-text1_1 { + font-size: 38rpx; + font-weight: bold; + color: #7499C8; + margin-bottom: 8rpx; + position: relative; + padding-left: 20rpx; +} + + +.title-text1_1::before { + content: ''; + position: absolute; + left: 0; + top: 50%; + transform: translateY(-50%); + width: 8rpx; + height: 32rpx; + background: #79b2d3; + border-radius: 4rpx; +} + .title-sub { font-size: 24rpx; color: #999; padding-left: 20rpx; } + + .view-all { display: flex; align-items: center; @@ -470,6 +495,21 @@ } +.view-all1_1{ + display: flex; + align-items: center; + font-size: 26rpx; + color: #608ac0; + padding: 12rpx 24rpx; + background: rgba(96, 192, 185, 0.1); + border-radius: 30rpx; + transition: all 0.3s ease; +} + +.view-all1_1:active { + background: rgba(131, 158, 199, 0.2); + transform: scale(0.98); +} @@ -537,16 +577,6 @@ margin-bottom: 6rpx; } -.user-location { - display: flex; - align-items: center; - gap: 6rpx; -} - -.user-location text { - font-size: 22rpx; - color: #999; -} .time-info { font-size: 22rpx; @@ -554,4 +584,35 @@ background: rgba(0, 0, 0, 0.04); padding: 6rpx 16rpx; border-radius: 16rpx; +} + + +.post-footer { + display: flex; + align-items: center; + justify-content: flex-end; +} + +.post-meta { + display: flex; + align-items: center; + gap: 25rpx; +} + +.meta-item { + display: flex; + align-items: center; + gap: 8rpx; +} + +.meta-icon { + width: 28rpx; + height: 28rpx; + opacity: 0.5; +} + +.meta-count { + font-size: 26rpx; + font-weight: 600; + color: #64748b; } \ No newline at end of file diff --git a/pages/personal/personal.js b/pages/personal/personal.js index 45ecd65..bd3d95e 100644 --- a/pages/personal/personal.js +++ b/pages/personal/personal.js @@ -28,6 +28,13 @@ Page({ this.loadUserInfo(); }, + // 跳转实名认证 + bindrz(){ + wx.navigateTo({ + url: '/pagesA/pages/attestation/attestation', + }) + }, + onShow() { }, diff --git a/pages/personal/personal.wxml b/pages/personal/personal.wxml index 4e6205a..3c7a4d1 100644 --- a/pages/personal/personal.wxml +++ b/pages/personal/personal.wxml @@ -57,7 +57,7 @@ 实名认证 - + {{userInfo.isVerified ? '已认证' : '去认证'}} diff --git a/pagesA/pages/attestation/attestation.js b/pagesA/pages/attestation/attestation.js new file mode 100644 index 0000000..9dfe01f --- /dev/null +++ b/pagesA/pages/attestation/attestation.js @@ -0,0 +1,317 @@ +// pages/real-name-auth/real-name-auth.js +Page({ + data: { + // 表单数据 + name: '', + phone: '', + smsCode: '', + + // 焦点状态 + nameFocus: false, + phoneFocus: false, + codeFocus: false, + + // 错误提示 + nameError: '', + phoneError: '', + smsCodeError: '', + + // 验证码相关 + canSendCode: false, + countdown: 0, + countdownTimer: null, + + // 协议状态 + agreed: false, + + // 提交状态 + canSubmit: false, + isSubmitting: false, + + // 弹窗 + showSuccessModal: false + }, + + onLoad() { + this.checkForm(); + }, + + onUnload() { + // 清除定时器 + if (this.data.countdownTimer) { + clearInterval(this.data.countdownTimer); + } + }, + + // 姓名输入处理 + onNameInput(e) { + const name = e.detail.value.trim(); + let nameError = ''; + + if (name && !/^[\u4e00-\u9fa5]{2,10}$/.test(name)) { + nameError = '姓名应为2-10个汉字'; + } + + this.setData({ + name: name, + nameError: nameError + }, () => { + this.checkForm(); + this.checkCanSendCode(); + }); + }, + + onNameFocus() { + this.setData({ nameFocus: true }); + }, + + onNameBlur() { + this.setData({ nameFocus: false }); + }, + + // 手机号输入处理 + onPhoneInput(e) { + const phone = e.detail.value.trim(); + let phoneError = ''; + + if (phone && !/^1[3-9]\d{9}$/.test(phone)) { + phoneError = '请输入正确的手机号码'; + } + + this.setData({ + phone: phone, + phoneError: phoneError + }, () => { + this.checkForm(); + this.checkCanSendCode(); + }); + }, + + onPhoneFocus() { + this.setData({ phoneFocus: true }); + }, + + onPhoneBlur() { + this.setData({ phoneFocus: false }); + }, + + // 验证码输入处理 + onSmsCodeInput(e) { + const smsCode = e.detail.value.trim(); + let smsCodeError = ''; + + if (smsCode && !/^\d{6}$/.test(smsCode)) { + smsCodeError = '请输入6位数字验证码'; + } + + this.setData({ + smsCode: smsCode, + smsCodeError: smsCodeError + }, () => { + this.checkForm(); + }); + }, + + onCodeFocus() { + this.setData({ codeFocus: true }); + }, + + onCodeBlur() { + this.setData({ codeFocus: false }); + }, + + // 检查是否可以发送验证码 + checkCanSendCode() { + const { name, phone, nameError, phoneError } = this.data; + const canSendCode = name && phone && !nameError && !phoneError; + this.setData({ canSendCode }); + }, + + // 发送验证码 + async sendSmsCode() { + const { name, phone, countdown } = this.data; + + if (countdown > 0) return; + + // 验证手机号格式 + if (!/^1[3-9]\d{9}$/.test(phone)) { + this.setData({ phoneError: '请输入正确的手机号码' }); + return; + } + + // 显示加载 + wx.showLoading({ + title: '发送中...', + mask: true + }); + + try { + // 模拟发送验证码请求 + await new Promise(resolve => setTimeout(resolve, 1500)); + + wx.hideLoading(); + + // 发送成功 + wx.showToast({ + title: '验证码已发送', + icon: 'success', + duration: 2000 + }); + + // 开始倒计时 + this.startCountdown(); + + } catch (error) { + wx.hideLoading(); + wx.showToast({ + title: '发送失败,请重试', + icon: 'error', + duration: 2000 + }); + } + }, + + // 开始倒计时 + startCountdown() { + this.setData({ countdown: 60 }); + + const timer = setInterval(() => { + let { countdown } = this.data; + countdown--; + + if (countdown <= 0) { + clearInterval(timer); + this.setData({ + countdown: 0, + countdownTimer: null + }); + } else { + this.setData({ + countdown: countdown, + countdownTimer: timer + }); + } + }, 1000); + }, + + // 协议处理 + toggleAgreement() { + this.setData({ + agreed: !this.data.agreed + }, () => { + this.checkForm(); + }); + }, + + viewAgreement() { + wx.navigateTo({ + url: '/pages/web-view/web-view?url=' + encodeURIComponent('https://your-domain.com/agreement') + }); + }, + + viewPrivacy() { + wx.navigateTo({ + url: '/pages/web-view/web-view?url=' + encodeURIComponent('https://your-domain.com/privacy') + }); + }, + + // 检查表单 + checkForm() { + const { + name, + phone, + smsCode, + nameError, + phoneError, + smsCodeError, + agreed + } = this.data; + + const isValid = name && + phone && + smsCode && + !nameError && + !phoneError && + !smsCodeError && + agreed; + + this.setData({ + canSubmit: isValid + }); + }, + + // 提交认证 + async submitAuth() { + if (!this.data.canSubmit || this.data.isSubmitting) return; + + this.setData({ isSubmitting: true }); + + // 验证数据 + const { name, phone, smsCode } = this.data; + + // 最终验证 + if (!/^[\u4e00-\u9fa5]{2,10}$/.test(name)) { + this.setData({ + nameError: '姓名应为2-10个汉字', + isSubmitting: false + }); + return; + } + + if (!/^1[3-9]\d{9}$/.test(phone)) { + this.setData({ + phoneError: '请输入正确的手机号码', + isSubmitting: false + }); + return; + } + + if (!/^\d{6}$/.test(smsCode)) { + this.setData({ + smsCodeError: '请输入6位数字验证码', + isSubmitting: false + }); + return; + } + + try { + // 模拟API请求 + await new Promise(resolve => setTimeout(resolve, 2000)); + + // 提交成功 + this.setData({ + isSubmitting: false, + showSuccessModal: true + }); + + // 保存认证信息到本地 + wx.setStorageSync('realNameAuth', { + name: name, + phone: phone, + certified: true, + certifiedTime: new Date().getTime() + }); + + } catch (error) { + this.setData({ isSubmitting: false }); + wx.showToast({ + title: '认证失败,请重试', + icon: 'error', + duration: 2000 + }); + } + }, + + // 成功弹窗处理 + closeSuccessModal() { + this.setData({ showSuccessModal: false }); + }, + + // 前往首页 + goToHome() { + this.closeSuccessModal(); + wx.switchTab({ + url: '/pages/index/index' + }); + } +}); \ No newline at end of file diff --git a/pagesA/pages/attestation/attestation.json b/pagesA/pages/attestation/attestation.json new file mode 100644 index 0000000..8b3ccf1 --- /dev/null +++ b/pagesA/pages/attestation/attestation.json @@ -0,0 +1,4 @@ +{ + "navigationBarTitleText":"实名认证", + "usingComponents": {} +} \ No newline at end of file diff --git a/pagesA/pages/attestation/attestation.wxml b/pagesA/pages/attestation/attestation.wxml new file mode 100644 index 0000000..b86f3a7 --- /dev/null +++ b/pagesA/pages/attestation/attestation.wxml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + 与牧同行 + 实名认证 + 开启您的牧业伙伴之旅 + + + + + + + + + 身份信息 + + 请填写您的真实信息 + + + + + + + 真实姓名 + + + + + + + + {{nameError || '请务必使用真实姓名'}} + + + + + + + + 手机号码 + + + + + + + + {{phoneError || '用于接收重要通知'}} + + + + + + + + 验证码 + + + + + + + + + + + {{smsCodeError || '输入6位数字验证码'}} + + + + + + + + + + + + + + + 认证成功后,您将享受与牧同行的专属服务 + + + + + + + + 与牧同行,伴您每一次成长 + + + + + + + + + + + 认证成功! + + 欢迎加入与牧同行大家庭 + + + 您已成功完成实名认证,开始享受专属服务吧! + + + + + \ No newline at end of file diff --git a/pagesA/pages/attestation/attestation.wxss b/pagesA/pages/attestation/attestation.wxss new file mode 100644 index 0000000..b0d69a0 --- /dev/null +++ b/pagesA/pages/attestation/attestation.wxss @@ -0,0 +1,546 @@ +/* pages/real-name-auth/real-name-auth.wxss */ +/* 基础样式 */ +.auth-container { + min-height: 100vh; + background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); + position: relative; + overflow: hidden; + padding: 40rpx 0 100rpx; + } + + /* 顶部装饰 */ + .top-decoration { + position: absolute; + top: 0; + left: 0; + right: 0; + height: 300rpx; + overflow: hidden; + z-index: 0; + } + + .decoration-circle { + position: absolute; + border-radius: 50%; + background: linear-gradient(135deg, rgba(255, 255, 255, 0.3) 0%, rgba(255, 255, 255, 0.1) 100%); + } + + .circle-1 { + width: 400rpx; + height: 400rpx; + top: -200rpx; + right: -100rpx; + } + + .circle-2 { + width: 300rpx; + height: 300rpx; + top: -150rpx; + left: -100rpx; + } + + .circle-3 { + width: 200rpx; + height: 200rpx; + top: 100rpx; + left: 50%; + margin-left: -100rpx; + } + + /* 头部 */ + .header { + text-align: center; + padding: 40rpx 0 60rpx; + position: relative; + z-index: 1; + } + + .logo { + width: 120rpx; + height: 120rpx; + margin: 0 auto 24rpx; + } + + .brand-name { + font-size: 48rpx; + font-weight: bold; + color: #2c3e50; + margin-bottom: 16rpx; + letter-spacing: 4rpx; + } + + .page-title { + font-size: 36rpx; + color: #2c3e50; + font-weight: 600; + margin-bottom: 12rpx; + } + + .page-subtitle { + font-size: 28rpx; + color: #7f8c8d; + } + + /* 表单卡片 */ + .form-card { + background: white; + border-radius: 32rpx; + padding: 48rpx 40rpx; + margin: 0 40rpx 30rpx; + box-shadow: 0 10rpx 40rpx rgba(0, 0, 0, 0.08); + position: relative; + z-index: 1; + animation: slideUp 0.6s ease-out; + } + + .card-header { + margin-bottom: 40rpx; + } + + .card-title { + display: flex; + align-items: center; + font-size: 32rpx; + font-weight: 600; + color: #2c3e50; + margin-bottom: 12rpx; + } + + .title-icon { + width: 36rpx; + height: 36rpx; + margin-right: 16rpx; + } + + .card-hint { + font-size: 26rpx; + color: #95a5a6; + } + + /* 输入组 */ + .input-group { + margin-bottom: 48rpx; + } + + .input-label { + display: flex; + align-items: center; + margin-bottom: 20rpx; + font-size: 28rpx; + color: #2c3e50; + font-weight: 500; + } + + .label-icon { + width: 32rpx; + height: 32rpx; + margin-right: 16rpx; + } + + .input-wrapper, + .code-input-container { + position: relative; + } + + .name-input, + .phone-input, + .code-input { + width: 100%; + height: 88rpx; + font-size: 28rpx; + color: #2c3e50; + padding: 0 24rpx; + background: #f8f9fa; + border-radius: 16rpx; + transition: all 0.3s ease; + } + + .placeholder { + color: #bdc3c7; + font-size: 28rpx; + } + + .input-border { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border: 2rpx solid transparent; + border-radius: 16rpx; + pointer-events: none; + } + + .input-focus-border { + position: absolute; + top: -2rpx; + left: -2rpx; + right: -2rpx; + bottom: -2rpx; + border: 4rpx solid transparent; + border-radius: 18rpx; + opacity: 0; + transition: all 0.3s ease; + pointer-events: none; + } + + .input-focus-border.active { + opacity: 1; + border-color: rgba(52, 152, 219, 0.3); + } + + .input-hint { + font-size: 24rpx; + color: #95a5a6; + margin-top: 12rpx; + min-height: 36rpx; + transition: all 0.3s ease; + } + + .input-hint.error { + color: #e74c3c; + } + + /* 验证码区域 */ + .code-input-wrapper { + display: flex; + align-items: center; + gap: 20rpx; + } + + .code-input-container { + flex: 1; + } + + .send-code-btn { + min-width: 200rpx; + height: 88rpx; + background: linear-gradient(135deg, #3498db 0%, #2980b9 100%); + border-radius: 16rpx; + font-size: 26rpx; + color: white; + padding: 0; + margin: 0; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.3s ease; + box-shadow: 0 4rpx 20rpx rgba(52, 152, 219, 0.3); + } + + .send-code-btn::after { + border: none; + } + + .btn-content { + display: flex; + align-items: center; + justify-content: center; + } + + .sms-icon { + width: 24rpx; + height: 24rpx; + margin-right: 8rpx; + } + + .send-code-btn.disabled { + background: #bdc3c7; + box-shadow: none; + opacity: 0.6; + } + + .send-code-btn.counting { + background: #95a5a6; + } + + .btn-hover { + opacity: 0.9; + transform: translateY(-2rpx); + } + + /* 协议 */ + .agreement-card { + background: white; + border-radius: 24rpx; + padding: 32rpx 40rpx; + margin: 0 40rpx 40rpx; + box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.06); + } + + .agreement-item { + display: flex; + align-items: flex-start; + } + + .checkbox { + width: 36rpx; + height: 36rpx; + border: 2rpx solid #bdc3c7; + border-radius: 8rpx; + margin-right: 20rpx; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + transition: all 0.3s ease; + } + + .checkbox.checked { + background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%); + border-color: transparent; + } + + .check-icon { + width: 20rpx; + height: 20rpx; + } + + .agreement-text { + font-size: 26rpx; + color: #2c3e50; + line-height: 1.4; + flex: 1; + } + + .link { + color: #3498db; + text-decoration: none; + } + + /* 提交按钮 */ + .submit-section { + padding: 0 40rpx; + position: relative; + z-index: 1; + } + + .submit-btn { + width: 100%; + height: 100rpx; + background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%); + border-radius: 50rpx; + font-size: 32rpx; + color: white; + font-weight: 600; + padding: 0; + margin: 0; + transition: all 0.3s ease; + box-shadow: 0 10rpx 40rpx rgba(46, 204, 113, 0.4); + } + + .submit-btn::after { + border: none; + } + + .submit-btn.disabled { + background: #bdc3c7; + box-shadow: none; + opacity: 0.7; + } + + .btn-inner { + display: flex; + align-items: center; + justify-content: center; + height: 100%; + } + + .arrow-icon { + width: 32rpx; + height: 32rpx; + margin-left: 12rpx; + opacity: 0.9; + } + + .submit-btn-hover { + opacity: 0.9; + transform: translateY(-2rpx); + } + + .submit-hint { + text-align: center; + font-size: 26rpx; + color: #7f8c8d; + margin-top: 24rpx; + } + + /* 底部装饰 */ + .bottom-decoration { + text-align: center; + margin-top: 60rpx; + position: relative; + z-index: 1; + animation: fadeInUp 0.8s ease-out 0.3s both; + } + + .sheep-illustration { + width: 200rpx; + height: 150rpx; + margin-bottom: 20rpx; + opacity: 0.8; + } + + .decoration-text { + font-size: 28rpx; + color: #7f8c8d; + } + + .highlight { + color: #3498db; + font-weight: 600; + } + + /* 成功弹窗 */ + .success-modal { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 1000; + opacity: 0; + visibility: hidden; + transition: all 0.3s ease; + } + + .success-modal.show { + opacity: 1; + visibility: visible; + } + + .modal-mask { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + backdrop-filter: blur(10rpx); + } + + .modal-content { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%) scale(0.9); + width: 600rpx; + background: white; + border-radius: 32rpx; + padding: 60rpx 40rpx; + text-align: center; + opacity: 0; + transition: all 0.3s ease; + } + + .success-modal.show .modal-content { + opacity: 1; + transform: translate(-50%, -50%) scale(1); + } + + .modal-icon { + width: 120rpx; + height: 120rpx; + background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + margin: 0 auto 32rpx; + } + + .success-icon { + width: 60rpx; + height: 60rpx; + } + + .modal-title { + font-size: 40rpx; + font-weight: bold; + color: #2c3e50; + margin-bottom: 20rpx; + } + + .modal-message { + font-size: 32rpx; + color: #2c3e50; + margin-bottom: 16rpx; + } + + .brand-highlight { + color: #3498db; + font-weight: 600; + } + + .modal-subtitle { + font-size: 26rpx; + color: #7f8c8d; + margin-bottom: 40rpx; + line-height: 1.5; + } + + .modal-btn { + background: linear-gradient(135deg, #3498db 0%, #2980b9 100%); + border-radius: 50rpx; + height: 88rpx; + font-size: 30rpx; + color: white; + font-weight: 600; + padding: 0 60rpx; + margin: 0; + display: flex; + align-items: center; + justify-content: center; + gap: 12rpx; + } + + .modal-btn::after { + border: none; + } + + .home-icon { + width: 32rpx; + height: 32rpx; + } + + /* 动画 */ + @keyframes slideUp { + from { + opacity: 0; + transform: translateY(50rpx); + } + to { + opacity: 1; + transform: translateY(0); + } + } + + @keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(30rpx); + } + to { + opacity: 1; + transform: translateY(0); + } + } + + /* 响应式 */ + @media (max-width: 480px) { + .form-card, + .agreement-card, + .submit-section { + margin-left: 30rpx; + margin-right: 30rpx; + } + + .code-input-wrapper { + flex-direction: column; + gap: 20rpx; + } + + .send-code-btn { + min-width: 100%; + } + } \ No newline at end of file diff --git a/pagesB/pages/experienceDetails/experienceDetails.js b/pagesB/pages/experienceDetails/experienceDetails.js new file mode 100644 index 0000000..5b88cbe --- /dev/null +++ b/pagesB/pages/experienceDetails/experienceDetails.js @@ -0,0 +1,34 @@ +import http from '../../../utils/api' +const baseUrl = require('../../../utils/baseUrl') +Page({ + data: { + id: '', // 文章ID + baseUrl:baseUrl, + detail: {} // 文章详情数据 + }, + + onLoad(options) { + this.getexperienceDetails(options) + }, + + // 经验分享详情 + getexperienceDetails(options){ + http.experienceDetails({ + data:{ + id:options.id + }, + success:res=>{ + console.log(1111,res); + var ch =' + + + + + + + + {{detail.categoryName}} + + + + {{detail.title}} + + + + + + + + + + {{detail.summary}} + + + + + + + + + \ No newline at end of file diff --git a/pagesB/pages/experienceDetails/experienceDetails.wxss b/pagesB/pages/experienceDetails/experienceDetails.wxss new file mode 100644 index 0000000..c61e5a0 --- /dev/null +++ b/pagesB/pages/experienceDetails/experienceDetails.wxss @@ -0,0 +1,146 @@ +.page-container { + background-color: #f5f7fa; + min-height: 100vh; + box-sizing: border-box; + } + + /* 内容区域 */ + .content-scroll { + height: 100vh; + padding-top: calc(88rpx + var(--status-bar-height)); + box-sizing: border-box; + } + + /* 文章头部 */ + .article-header { + background-color: white; + padding: 40rpx 32rpx 32rpx; + margin-bottom: 20rpx; + } + + .category-tag { + display: inline-block; + background-color: #E8F3FF; + padding: 8rpx 20rpx; + border-radius: 24rpx; + margin-bottom: 24rpx; + } + + .category-text { + font-size: 24rpx; + color: #4A90E2; + font-weight: 500; + } + + .article-title { + font-size: 40rpx; + color: #1a1a1a; + font-weight: 700; + line-height: 1.4; + margin-bottom: 32rpx; + } + + .article-meta { + display: flex; + align-items: center; + justify-content: space-between; + } + + .author-info { + display: flex; + align-items: center; + flex: 1; + } + + .author-avatar { + width: 64rpx; + height: 64rpx; + border-radius: 50%; + margin-right: 16rpx; + border: 2rpx solid #f0f0f0; + } + + .author-details { + display: flex; + flex-direction: column; + } + + .author-name { + font-size: 28rpx; + color: #333; + font-weight: 500; + margin-bottom: 4rpx; + } + + .publish-time { + font-size: 24rpx; + color: #999; + } + + .view-info { + display: flex; + align-items: center; + } + + .view-icon { + width: 32rpx; + height: 32rpx; + margin-right: 8rpx; + opacity: 0.7; + } + + .view-count { + font-size: 26rpx; + color: #999; + } + + /* 文章内容 */ + .article-content { + background-color: white; + padding: 32rpx; + } + + .article-summary { + font-size: 30rpx; + color: #666; + line-height: 1.6; + margin-bottom: 32rpx; + padding: 24rpx; + background-color: #f9f9f9; + border-radius: 12rpx; + border-left: 4rpx solid #4A90E2; + } + + .article-body { + font-size: 30rpx; + line-height: 1.8; + color: #333; + } + + .content-text { + font-size: 30rpx; + line-height: 1.8; + color: #333; + white-space: pre-line; + } + + .content-text p { + margin-bottom: 32rpx; + } + + + /* 响应式调整 */ + @media (max-width: 375px) { + .article-header, + .article-content { + padding: 24rpx; + } + + .article-title { + font-size: 36rpx; + } + + .content-text { + font-size: 28rpx; + } + } \ No newline at end of file diff --git a/pagesB/pages/experienceList/experienceList.js b/pagesB/pages/experienceList/experienceList.js new file mode 100644 index 0000000..74f1625 --- /dev/null +++ b/pagesB/pages/experienceList/experienceList.js @@ -0,0 +1,206 @@ +import http from '../../../utils/api' +const baseUrl = require('../../../utils/baseUrl') + +Page({ + data: { + // 搜索文本 + searchText: '', + baseUrl: baseUrl, + // 当前选中的分类 + activeCategory: '', + // 分类数据 + categories: [], + // 经验分享列表 + experienceList: [], + // 分页参数 + pageNum: 1, + pageSize: 10, + total: 0, + // 加载状态 + loading: false, + hasMore: true, + // 搜索防抖定时器 + searchTimer: null + }, + + onLoad() { + // 获取分类数据 + this.getCategories() + // 获取经验分享列表 + this.getExperienceList(true) + }, + + // 获取经验分享列表 + getExperienceList(isRefresh = false) { + if (this.data.loading) return + + const params = { + pageNum: isRefresh ? 1 : this.data.pageNum, + pageSize: this.data.pageSize + } + + // 添加搜索关键词 + if (this.data.searchText) { + params.searchKey = this.data.searchText.trim() + } + + // 添加分类筛选 + if (this.data.activeCategory) { + params.categoryName = this.data.activeCategory + } + + this.setData({ loading: true }) + + http.experience({ + data: params, + success: res => { + console.log('经验列表数据:', res) + + if (res.code === 200) { + const newList = isRefresh ? res.rows : [...this.data.experienceList, ...res.rows] + const total = res.total || 0 + const hasMore = newList.length < total + + this.setData({ + experienceList: newList, + total: total, + hasMore: hasMore, + pageNum: isRefresh ? 2 : this.data.pageNum + 1, + loading: false + }) + } else { + wx.showToast({ + title: res.msg || '加载失败', + icon: 'none' + }) + this.setData({ loading: false }) + } + }, + fail: err => { + console.error('请求失败:', err) + wx.showToast({ + title: '网络错误,请重试', + icon: 'none' + }) + this.setData({ loading: false }) + } + }) + }, + + // 获取分类数据 + getCategories() { + http.experiencezd({ + data: { + categoryName: 'category_id' + }, + success: res => { + console.log('分类数据:', res) + if (res.code === 200) { + this.setData({ + categories: res.data || [] + }) + } + }, + fail: err => { + console.error('获取分类失败:', err) + } + }) + }, + + // 处理搜索输入(带防抖) + onSearchInput(e) { + const searchText = e.detail.value + + this.setData({ + searchText: searchText + }) + + // 清除之前的定时器 + if (this.data.searchTimer) { + clearTimeout(this.data.searchTimer) + } + + // 设置新的定时器,500ms后执行搜索 + const timer = setTimeout(() => { + this.handleSearch() + }, 500) + + this.setData({ + searchTimer: timer + }) + }, + + // 搜索确认 + onSearchConfirm() { + if (this.data.searchTimer) { + clearTimeout(this.data.searchTimer) + } + this.handleSearch() + }, + + // 执行搜索 + handleSearch() { + this.setData({ + pageNum: 1, + hasMore: true + }) + this.getExperienceList(true) + }, + + // 清空搜索 + clearSearch() { + this.setData({ + searchText: '', + pageNum: 1, + hasMore: true + }) + this.getExperienceList(true) + }, + + // 分类点击事件 + onCategoryTap(e) { + const categoryId = e.currentTarget.dataset.id + + if (this.data.activeCategory === categoryId) { + return + } + + this.setData({ + activeCategory: categoryId, + pageNum: 1, + hasMore: true + }) + + this.getExperienceList(true) + }, + + // 滚动到底部加载更多 + onScrollToLower() { + if (!this.data.loading && this.data.hasMore) { + this.getExperienceList() + } + }, + + // 点击加载更多 + loadMoreData() { + if (!this.data.loading && this.data.hasMore) { + this.getExperienceList() + } + }, + + // 经验分享点击事件 + onExperienceTap(e) { + const id = e.currentTarget.dataset.id + + wx.navigateTo({ + url: `/pagesB/pages/experienceDetails/experienceDetails?id=${id}`, + }) + }, + + onUnload() { + // 清理定时器 + if (this.data.searchTimer) { + clearTimeout(this.data.searchTimer) + } + } +}) \ No newline at end of file diff --git a/pagesB/pages/experienceList/experienceList.json b/pagesB/pages/experienceList/experienceList.json new file mode 100644 index 0000000..b53559d --- /dev/null +++ b/pagesB/pages/experienceList/experienceList.json @@ -0,0 +1,4 @@ +{ + "navigationBarTitleText": "经验分享", + "usingComponents": {} +} \ No newline at end of file diff --git a/pagesB/pages/experienceList/experienceList.wxml b/pagesB/pages/experienceList/experienceList.wxml new file mode 100644 index 0000000..1598ecd --- /dev/null +++ b/pagesB/pages/experienceList/experienceList.wxml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + 全部 + + + {{item.label}} + + + + + + + + + + + + {{item.categoryName}} + + + {{item.publishTime}} + + + + {{item.title}} + + + {{item.summary}} + + + + + + + {{item.vetName}} + + + + + + {{item.viewCount}} + + + + + + + 点击加载更多 + + + + 加载中... + + + + 没有更多了 + + + + + 暂无相关经验分享 + {{searchText || activeCategory ? '换个关键词试试吧' : '快去分享你的经验吧'}} + + + + \ No newline at end of file diff --git a/pagesB/pages/experienceList/experienceList.wxss b/pagesB/pages/experienceList/experienceList.wxss new file mode 100644 index 0000000..2d4861b --- /dev/null +++ b/pagesB/pages/experienceList/experienceList.wxss @@ -0,0 +1,332 @@ +/* pages/experience/experience.wxss */ + +.page-container { + background-color: #f5f7fa; + min-height: 100vh; + } + + /* 搜索区域 */ + .search-container { + background: linear-gradient(135deg, #4A90E2 0%, #6AC5F8 100%); + padding: 20rpx 32rpx 32rpx; + } + + .search-box { + background-color: white; + border-radius: 50rpx; + padding: 20rpx 32rpx; + display: flex; + align-items: center; + box-shadow: 0 4rpx 16rpx rgba(74, 144, 226, 0.2); + } + + .search-icon { + width: 32rpx; + height: 32rpx; + margin-right: 16rpx; + } + + .search-input { + width: 95%; + font-size: 28rpx; + color: #333; + } + + .placeholder { + color: #999; + font-size: 28rpx; + } + + .clear-btn { + width: 32rpx; + height: 32rpx; + display: flex; + align-items: center; + justify-content: center; + } + + .clear-icon { + width: 30rpx; + height: 30rpx; + filter: brightness(0) contrast(100%); + } + + /* 分类区域 */ + .category-container { + background-color: white; + padding: 20rpx 32rpx; + white-space: nowrap; + box-sizing: border-box; + } + + .category-list { + display: inline-flex; + } + + .category-item { + display: inline-flex; + align-items: center; + padding: 12rpx 28rpx; + margin-right: 20rpx; + border-radius: 40rpx; + background-color: #f5f7fa; + border: 2rpx solid #f5f7fa; + transition: all 0.3s ease; + } + + .category-item.active { + background-color: #E8F3FF; + border-color: #4A90E2; + } + + .category-text { + font-size: 26rpx; + color: #666; + font-weight: 400; + } + + .category-item.active .category-text { + color: #4A90E2; + font-weight: 500; + } + + + + .category-item.active .category-count { + background-color: rgba(74, 144, 226, 0.1); + color: #4A90E2; + } + + /* 经验列表 */ + .experience-list { + padding: 32rpx; + } + + .experience-item { + background-color: white; + border-radius: 20rpx; + padding: 32rpx; + margin-bottom: 24rpx; + box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.04); + transition: all 0.3s ease; + } + + .experience-item:active { + transform: translateY(-2rpx); + box-shadow: 0 6rpx 24rpx rgba(0, 0, 0, 0.08); + } + + .tag{ + display: flex; + align-items: center; + justify-content: space-between; + padding-bottom: 20rpx; + } + + .item-category-tag { + display: inline-block; + background-color: #E8F3FF; + padding: 6rpx 16rpx; + border-radius: 20rpx; + } + + .tag-text { + font-size: 22rpx; + color: #4A90E2; + font-weight: 500; + } + + .item-title { + font-size: 34rpx; + color: #1a1a1a; + font-weight: 600; + line-height: 1.4; + margin-bottom: 16rpx; + } + + .item-summary { + font-size: 28rpx; + color: #666; + line-height: 1.5; + margin-bottom: 24rpx; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + } + + .item-footer { + display: flex; + align-items: center; + justify-content: space-between; + padding-top: 20rpx; + border-top: 1rpx solid #f0f0f0; + } + + .author-info { + display: flex; + align-items: center; + flex: 1; + } + + .author-avatar { + width: 48rpx; + height: 48rpx; + border-radius: 50%; + margin-right: 12rpx; + } + + .author-name { + font-size: 24rpx; + color: #999; + } + + .view-info { + display: flex; + align-items: center; + margin-right: 32rpx; + } + + .view-icon { + width: 28rpx; + height: 28rpx; + margin-right: 8rpx; + opacity: 0.6; + } + + .view-count { + font-size: 24rpx; + color: #999; + } + + .publish-time { + font-size: 24rpx; + color: #ccc; + flex-shrink: 0; + } + + /* 空状态 */ + .empty-state { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 100rpx 0; + } + + + .empty-text { + font-size: 32rpx; + color: #999; + margin-bottom: 16rpx; + } + + .empty-hint { + font-size: 26rpx; + color: #ccc; + } + + /* 新增样式 */ + +.experience-scroll { + box-sizing: border-box; +} + +/* 加载更多样式 */ +.load-more { + text-align: center; + padding: 40rpx 0; + color: #4A90E2; + font-size: 28rpx; +} + +.load-more-text { + padding: 16rpx 32rpx; + background-color: #E8F3FF; + border-radius: 24rpx; + display: inline-block; +} + +.loading { + text-align: center; + padding: 40rpx 0; + color: #999; + font-size: 28rpx; +} + +.loading-text { + display: inline-block; + padding: 16rpx 32rpx; +} + +.no-more { + text-align: center; + padding: 40rpx 0; + color: #ccc; + font-size: 26rpx; +} + +.no-more-text { + display: inline-block; + padding: 16rpx 32rpx; +} + +/* 优化空状态样式 */ +.empty-state { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 120rpx 0; + text-align: center; +} + +.empty-text { + font-size: 32rpx; + color: #999; + margin-bottom: 20rpx; + font-weight: 500; +} + +.empty-hint { + font-size: 28rpx; + color: #ccc; +} + +/* 优化列表项样式 */ +.experience-item { + position: relative; + overflow: hidden; +} + +.experience-item:last-child { + margin-bottom: 0; +} + +/* 响应式调整 */ +@media (max-width: 375px) { + .load-more, + .loading, + .no-more { + padding: 30rpx 0; + } + + .empty-state { + padding: 80rpx 0; + } +} + + /* 响应式调整 */ + @media (max-width: 375px) { + .search-container { + padding: 16rpx 24rpx 24rpx; + } + + .experience-list { + padding: 24rpx; + } + + .experience-item { + padding: 24rpx; + } + } \ No newline at end of file diff --git a/pagesB/pages/forumlist/forumlist.js b/pagesB/pages/forumlist/forumlist.js index 2084876..3c3607b 100644 --- a/pagesB/pages/forumlist/forumlist.js +++ b/pagesB/pages/forumlist/forumlist.js @@ -1,234 +1,161 @@ +import http from '../../../utils/api' +const baseUrl = require('../../../utils/baseUrl') + Page({ data: { + // 帖子列表相关 posts: [], + baseUrl: baseUrl, loading: false, + searchLoading: false, + initialLoading: true, loadingMore: false, refreshing: false, hasMore: true, page: 1, pageSize: 10, - currentFilter: 'all', searchKeyword: '', - currentUser: '当前用户' + lastSearchKeyword: '', // 新增:记录上次搜索关键词 + + scrollTop: 0, + showBackToTop: false, + scrollThreshold: 300, + + // 发布帖子相关 + showPostModal: false, + postTitle: '', + postContent: '', + postImages: [], + isSubmitting: false }, - onLoad: function() { - this.loadPosts(); - - // 监听页面显示,用于刷新数据 - wx.onAppShow(() => { - this.refreshData(); - }); + onLoad: function () { + this.loadPosts(true); }, - onShow: function() { + onShow: function () { + // 每次显示页面时刷新数据 this.refreshData(); }, // 加载帖子列表 - loadPosts: function(reset = false) { + loadPosts: function (reset = false) { + // 防止重复请求 if (reset) { this.setData({ page: 1, hasMore: true, - posts: [], - loading: true + loading: true, + searchLoading: !!this.data.searchKeyword }); } else if (this.data.loadingMore) { return; } - + + this.setData({ + loading: reset || this.data.page === 1, + loadingMore: !reset && this.data.page > 1 + }); + + // 准备请求参数 const params = { page: this.data.page, - pageSize: this.data.pageSize, - filter: this.data.currentFilter, - search: this.data.searchKeyword + pageSize: this.data.pageSize }; - - this.setData({ - loading: reset || this.data.page === 1, - loadingMore: !reset && this.data.page > 1 + + // 如果有搜索关键词,添加搜索参数 + const searchKeyword = this.data.searchKeyword.trim(); + if (searchKeyword) { + params.searchKey = searchKeyword; + } + + // 记录当前搜索关键词 + this.setData({ + lastSearchKeyword: searchKeyword }); - - // 模拟API请求 - setTimeout(() => { - const mockPosts = this.generateMockPosts(params); - - if (reset) { - this.setData({ - posts: mockPosts, - loading: false, - hasMore: mockPosts.length === params.pageSize + + // 调用接口获取数据 + http.forumList({ + data: params, + success: (res) => { + if (res.code === 200) { + let postsData = res.rows || []; + + // 处理图片字段(分割字符串为数组) + postsData = postsData.map(item => { + if (item.images && typeof item.images === 'string') { + item.images = item.images.split(',').filter(img => img.trim() !== ''); + } else { + item.images = []; + } + return item; + }); + + if (reset) { + this.setData({ + posts: postsData, + loading: false, + searchLoading: false, + initialLoading: false, + hasMore: postsData.length === this.data.pageSize + }); + } else { + this.setData({ + posts: [...this.data.posts, ...postsData], + loading: false, + initialLoading: false, + loadingMore: false, + hasMore: postsData.length === this.data.pageSize + }); + } + } else { + wx.showToast({ + title: res.msg || '加载失败', + icon: 'none' + }); + this.setData({ + loading: false, + searchLoading: false, + initialLoading: false, + loadingMore: false + }); + } + + if (this.data.refreshing) { + wx.stopPullDownRefresh(); + this.setData({ + refreshing: false + }); + } + }, + fail: (err) => { + wx.showToast({ + title: '网络错误', + icon: 'none' }); - } else { this.setData({ - posts: [...this.data.posts, ...mockPosts], loading: false, + searchLoading: false, + initialLoading: false, loadingMore: false, - hasMore: mockPosts.length === params.pageSize + refreshing: false }); } - - if (this.data.refreshing) { - wx.stopPullDownRefresh(); - this.setData({ refreshing: false }); - } - }, 800); - }, - - // 生成模拟数据 - generateMockPosts: function(params) { - const posts = []; - const currentUser = this.data.currentUser; - const baseId = (params.page - 1) * params.pageSize; - - for (let i = 0; i < params.pageSize; i++) { - const id = baseId + i + 1; - const solved = i % 4 === 0; - const hot = i % 3 === 0 && i % 2 === 0; - const isMine = i % 5 === 0; - - // 根据筛选条件过滤 - if (params.filter === 'solved' && !solved) continue; - if (params.filter === 'unsolved' && solved) continue; - if (params.filter === 'mine' && !isMine) continue; - - const tags = this.getRandomTags(); - const post = { - id: id, - title: this.getRandomTitle(id), - summary: this.getRandomSummary(id), - username: isMine ? currentUser : this.getRandomUsername(), - avatar: 'https://img.yzcdn.cn/vant/cat.jpeg', - time: this.getRandomTime(), - likeCount: Math.floor(Math.random() * 50), - replyCount: Math.floor(Math.random() * 30), - viewCount: Math.floor(Math.random() * 300), - solved: solved, - hot: hot, - tags: tags, - lastReply: Math.random() > 0.3 ? { - username: this.getRandomUsername(), - time: this.getRandomTime('short') - } : null - }; - - // 搜索过滤 - if (params.search) { - const keyword = params.search.toLowerCase(); - const titleMatch = post.title.toLowerCase().includes(keyword); - const summaryMatch = post.summary.toLowerCase().includes(keyword); - const tagMatch = post.tags.some(tag => tag.toLowerCase().includes(keyword)); - - if (!titleMatch && !summaryMatch && !tagMatch) { - continue; - } - } - - posts.push(post); - } - - // 热门排序 - if (params.filter === 'hot') { - posts.sort((a, b) => { - const aScore = a.likeCount * 2 + a.replyCount * 3 + a.viewCount; - const bScore = b.likeCount * 2 + b.replyCount * 3 + b.viewCount; - return bScore - aScore; - }); - } - - return posts; - }, - - // 随机生成标题 - getRandomTitle: function(id) { - const titles = [ - '微信小程序如何实现图片上传和预览功能?', - 'uni-app开发中如何处理不同平台的兼容性问题?', - 'JavaScript闭包的使用场景有哪些?', - 'Vue3组合式API和选项式API该如何选择?', - 'React Hooks在项目中的最佳实践', - 'Node.js高并发场景下的性能优化方案', - 'TypeScript在大型项目中的类型设计经验分享', - '微信小程序云开发数据库查询性能优化', - '前端工程化建设:从零搭建Webpack配置', - '移动端H5页面适配的最佳方案是什么?', - '如何优雅地处理前端错误监控和上报?', - '微前端架构在实际项目中的应用经验', - 'Webpack5 Module Federation实战分享', - '前端代码质量保证:ESLint + Prettier + Husky', - '跨端开发框架选型:Flutter vs React Native vs uni-app' - ]; - return titles[id % titles.length] || titles[0]; - }, - - // 随机生成摘要 - getRandomSummary: function(id) { - const summaries = [ - '我正在开发一个微信小程序,需要实现图片上传功能,并且能够在上传前预览图片。请问有什么好的实现方案吗?上传的图片大小限制和格式有什么建议?', - '最近在做一个uni-app项目,需要同时兼容微信小程序和H5,遇到了一些样式和API兼容性问题,大家有什么好的解决方案吗?', - '在实际项目中经常使用闭包,但对其原理和应用场景理解还不够深入,想请教一下大家在项目中都是如何使用闭包的?', - '公司新项目准备使用Vue3,对于组合式API和选项式API的选择有些纠结,大家有什么建议吗?各自的使用场景是什么?', - 'React Hooks确实很方便,但在大型项目中如何合理组织Hooks,避免过度使用导致代码难以维护?', - '我们的Node.js服务在高并发场景下性能表现不佳,有哪些常见的性能优化方案可以参考?', - '项目准备从JavaScript迁移到TypeScript,在类型设计方面有什么经验可以分享吗?如何设计合理的泛型和接口?' - ]; - return summaries[id % summaries.length] || summaries[0]; - }, - - // 随机生成用户名 - getRandomUsername: function() { - const usernames = [ - '前端工程师', '技术爱好者', '小程序开发', '全栈程序员', - '架构师老王', '代码艺术家', '算法工程师', '产品经理', - 'UI设计师', '测试工程师', '运维小哥', '数据分析师' - ]; - return usernames[Math.floor(Math.random() * usernames.length)]; - }, - - // 随机生成时间 - getRandomTime: function(type = 'normal') { - const times = type === 'short' - ? ['5分钟前', '10分钟前', '半小时前', '1小时前'] - : ['2小时前', '5小时前', '昨天', '2天前', '3天前', '一周前']; - return times[Math.floor(Math.random() * times.length)]; - }, - - // 随机生成标签 - getRandomTags: function() { - const allTags = [ - '微信小程序', '前端开发', 'JavaScript', 'Vue.js', 'React', - 'Node.js', 'TypeScript', 'uni-app', '性能优化', '工程化', - '移动端', 'H5', 'CSS', 'Webpack', 'Git' - ]; - - const count = Math.floor(Math.random() * 3) + 1; - const tags = []; - const usedIndices = new Set(); - - for (let i = 0; i < count; i++) { - let index; - do { - index = Math.floor(Math.random() * allTags.length); - } while (usedIndices.has(index)); - - usedIndices.add(index); - tags.push(allTags[index]); - } - - return tags; + }); }, // 下拉刷新 - onRefresh: function() { - this.setData({ refreshing: true }); + onRefresh: function () { + this.setData({ + refreshing: true + }); this.loadPosts(true); }, - // 滚动到底部加载更多 - loadMore: function() { + // 加载更多 + loadMore: function () { if (!this.data.hasMore || this.data.loadingMore) return; - + this.setData({ page: this.data.page + 1 }, () => { @@ -236,111 +163,315 @@ Page({ }); }, - // 筛选切换 - changeFilter: function(e) { - const filterType = e.currentTarget.dataset.type; - if (this.data.currentFilter === filterType) return; - + // 搜索输入(防抖) + onSearchInput: function (e) { + const keyword = e.detail.value; this.setData({ - currentFilter: filterType, - searchKeyword: '' // 切换筛选时清空搜索 - }, () => { - this.loadPosts(true); + searchKeyword: keyword }); - }, - // 搜索输入 - onSearchInput: function(e) { - this.setData({ searchKeyword: e.detail.value }); - // 防抖搜索 clearTimeout(this.searchTimer); + + // 如果输入框为空,立即重置搜索 + if (!keyword.trim()) { + this.setData({ + searchKeyword: '' + }); + // 清空搜索时立即重新加载数据 + this.loadPosts(true); + return; + } + this.searchTimer = setTimeout(() => { - if (e.detail.value.trim()) { + // 只有当有搜索词且与上次不同时才搜索 + if (keyword.trim() && keyword.trim() !== this.data.lastSearchKeyword) { this.loadPosts(true); } - }, 300); + }, 500); }, // 搜索确认 - onSearchConfirm: function(e) { + onSearchConfirm: function (e) { const keyword = e.detail.value.trim(); - if (keyword) { - this.setData({ searchKeyword: keyword }); + this.setData({ + searchKeyword: keyword + }); + + // 如果搜索词为空,加载所有帖子 + if (!keyword) { this.loadPosts(true); + } else { + // 只有当搜索词与上次不同时才搜索 + if (keyword !== this.data.lastSearchKeyword) { + this.loadPosts(true); + } } }, - // 清空搜索 - clearSearch: function() { - this.setData({ - searchKeyword: '', - currentFilter: 'all' - }, () => { - this.loadPosts(true); - }); + // 清空搜索 - 优化版 + clearSearch: function () { + // 如果当前已经有搜索词,才执行清空操作 + if (this.data.searchKeyword) { + this.setData({ + searchKeyword: '' + }, () => { + // 清空后立即加载所有帖子 + this.loadPosts(true); + }); + } }, // 跳转到详情页 - goToDetail: function(e) { + goToDetail: function (e) { const postId = e.currentTarget.dataset.id; wx.navigateTo({ - url: `/pages/forum/detail/detail?id=${postId}`, - success: () => { - // 记录浏览历史 - this.recordViewHistory(postId); - } + url: `/pagesB/pages/onlineAsk/onlineAsk?id=${postId}` }); }, - // 创建新帖子 - createPost: function() { - wx.navigateTo({ - url: '/pages/forum/create/create' + // 图片预览功能 + previewImage: function (e) { + const postIndex = e.currentTarget.dataset.postindex; + const imageIndex = e.currentTarget.dataset.imageindex; + const post = this.data.posts[postIndex]; + + if (!post || !post.images || post.images.length === 0) return; + + // 构建完整的图片URL数组 + const urls = post.images.map(img => this.data.baseUrl + img); + + wx.previewImage({ + current: urls[imageIndex], // 当前显示图片的链接 + urls: urls // 需要预览的图片链接列表 }); }, - // 记录浏览历史 - recordViewHistory: function(postId) { - try { - const history = wx.getStorageSync('forumViewHistory') || []; - const index = history.findIndex(item => item.id === postId); - - if (index !== -1) { - history.splice(index, 1); - } - - history.unshift({ - id: postId, - timestamp: Date.now() + // 显示发布模态框 + createPost: function () { + // 检查登录状态(如果需要) + // 这里可以添加登录检查逻辑 + + this.setData({ + showPostModal: true + }); + }, + + // 隐藏发布模态框 + hidePostModal: function () { + if (this.data.isSubmitting) return; + this.setData({ + showPostModal: false, + postTitle: '', + postContent: '', + postImages: [] + }); + }, + + // 阻止事件冒泡 + stopPropagation: function () {}, + + // 标题输入 + onPostTitleInput: function (e) { + this.setData({ + postTitle: e.detail.value + }); + }, + + // 内容输入 + onPostContentInput: function (e) { + this.setData({ + postContent: e.detail.value + }); + }, + + // 选择图片 + chooseImage: function () { + const remaining = 3 - this.data.postImages.length; + if (remaining <= 0) { + wx.showToast({ + title: '最多上传3张图片', + icon: 'none' }); - - // 只保留最近50条记录 - if (history.length > 50) { - history.pop(); + return; + } + + wx.chooseMedia({ + count: remaining, + mediaType: ['image'], + sizeType: ['compressed'], + sourceType: ['album', 'camera'], + success: (res) => { + const tempFiles = res.tempFiles; + const newImages = tempFiles.map(file => file.tempFilePath); + const postImages = [...this.data.postImages, ...newImages]; + + this.setData({ + postImages: postImages.slice(0, 3) // 确保不超过3张 + }); + }, + fail: (err) => { + console.error('选择图片失败:', err); } - - wx.setStorageSync('forumViewHistory', history); - } catch (error) { - console.error('记录浏览历史失败:', error); + }); + }, + + // 移除图片 + removeImage: function (e) { + const index = e.currentTarget.dataset.index; + const postImages = [...this.data.postImages]; + postImages.splice(index, 1); + this.setData({ + postImages + }); + }, + + // 提交帖子 + submitPost: function () { + const { postTitle, postContent, postImages } = this.data; + + // 验证输入 + if (!postTitle.trim()) { + wx.showToast({ + title: '请输入标题', + icon: 'none' + }); + return; + } + + if (!postContent.trim()) { + wx.showToast({ + title: '请输入内容', + icon: 'none' + }); + return; + } + + this.setData({ + isSubmitting: true + }); + + // 如果有图片,先上传图片 + const uploadPromises = postImages.map(imagePath => { + return new Promise((resolve, reject) => { + wx.uploadFile({ + url: baseUrl+'/common/upload', + header: { + 'Authorization': 'Bearer ' + wx.getStorageSync('token') + }, + filePath: imagePath, + name: 'file', + success: (res) => { + const data = JSON.parse(res.data); + console.log(data); + if (data.code === 200) { + resolve(data.fileName); // 假设返回的图片路径在data.url中 + } else { + reject(new Error('图片上传失败')); + } + }, + fail: (err) => { + reject(err); + } + }); + }); + }); + + // 处理图片上传 + Promise.all(uploadPromises) + .then((imageUrls) => { + // 所有图片上传成功,提交帖子数据 + const postData = { + title: postTitle, + content: postContent, + images: imageUrls.join(',') // 将图片URL用逗号拼接 + }; + + return http.forumAdd({ + data: postData, + success:res=>{ + console.log(1111,res); + if (res.code === 200) { + // 发布成功 + this.setData({ + showPostModal: false, + postTitle: '', + postContent: '', + postImages: [], + isSubmitting: false + }); + + wx.showToast({ + title: '发布成功', + icon: 'success', + duration: 2000 + }); + + // 刷新帖子列表 + setTimeout(() => { + this.loadPosts(true); + }, 500); + } else { + throw new Error(res.msg || '发布失败'); + } + } + }); + }) + }, + + // 滚动事件监听 + onScroll: function (e) { + const scrollTop = e.detail.scrollTop; + const showBackToTop = scrollTop > this.data.scrollThreshold; + + if (showBackToTop !== this.data.showBackToTop) { + this.setData({ + scrollTop: scrollTop, + showBackToTop: showBackToTop + }); } }, + // 返回顶部 + backToTop: function () { + this.setData({ + showBackToTop: false + }); + + wx.pageScrollTo({ + scrollTop: 0, + duration: 400, + success: () => { + this.setData({ + scrollTop: 0 + }); + }, + fail: (err) => { + console.log('滚动失败:', err); + this.setData({ + scrollTop: 0 + }); + } + }); + }, + // 刷新数据 - refreshData: function() { - // 这里可以检查是否有新数据需要刷新 - // 例如:从详情页返回时刷新点赞状态等 + refreshData: function () { + const pages = getCurrentPages(); + const currentPage = pages[pages.length - 1]; + if (currentPage.data && currentPage.data.refresh) { + this.loadPosts(true); + currentPage.setData({ + refresh: false + }); + } }, - onPullDownRefresh: function() { + onPullDownRefresh: function () { this.onRefresh(); }, - onReachBottom: function() { + onReachBottom: function () { this.loadMore(); - }, - - onPageScroll: function(e) { - // 可以在这里处理页面滚动时的效果 } }); \ No newline at end of file diff --git a/pagesB/pages/forumlist/forumlist.json b/pagesB/pages/forumlist/forumlist.json index 8835af0..73b574a 100644 --- a/pagesB/pages/forumlist/forumlist.json +++ b/pagesB/pages/forumlist/forumlist.json @@ -1,3 +1,4 @@ { + "navigationBarTitleText": "问答论坛", "usingComponents": {} } \ No newline at end of file diff --git a/pagesB/pages/forumlist/forumlist.wxml b/pagesB/pages/forumlist/forumlist.wxml index e6b826c..b0de02c 100644 --- a/pagesB/pages/forumlist/forumlist.wxml +++ b/pagesB/pages/forumlist/forumlist.wxml @@ -1,202 +1,208 @@ - - - - - 问答论坛 - - - - - - - - - 全部 - - - 待解决 - - - 已解决 - - - 热门 - - - 我的帖子 - - - + + + + + + + 问答社区 + 互帮互助,共同成长 + - + + + + + - - - - + + + + - × + × - + - - + + + + + + 搜索中... + + - - + 没有找到"{{searchKeyword}}"相关的问题 - 暂无帖子,快来发布第一个问题吧! + 这里还没有问题,快来发布第一个吧! - - + - + - - - - - - {{item.likeCount}} - 点赞 - - - {{item.replyCount}} - 回答 + + + + + + + {{item.createdAt}} - - {{item.viewCount}} - 浏览 + + + {{item.title}} - - - - - - - - {{item.title}} - - 已解决 - - - 热门 - + + + + {{item.content}} - - - {{item.summary}} - - - - + - - 上拉加载更多 + + 上拉加载更多 - - - 加载中... + + + 加载中... - + - 没有更多了 + + 已经到底了 + - + - - - - + - - - - - 加载中... - - - - - - + + + + + + + + + + + + + + + + + + + 发布问题 + + × + + + + + + + 问题标题 + {{postTitle.length}}/50 + + + + + + + 详细描述 + {{postContent.length}}/500 + +