first commit
This commit is contained in:
		
							
								
								
									
										31
									
								
								pages/agent/agent.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								pages/agent/agent.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| Page({ | ||||
|     data: {}, | ||||
|     onLoad: function(n) {}, | ||||
|     onReady: function() {}, | ||||
|     onShow: function() {}, | ||||
|     onHide: function() {}, | ||||
|     onUnload: function() {}, | ||||
|     onPullDownRefresh: function() {}, | ||||
|     onReachBottom: function() {}, | ||||
|     onShareAppMessage: function() { | ||||
|         return { | ||||
|             title: "推荐一款免费又超好用的视频文案创作工具,分享给大家一起使用", | ||||
|             path: "/pages/index/index?uuid=" + wx.getStorageSync("uuid"), | ||||
|             imageUrl: "/images/share.jpg", | ||||
|             success: function(n) { | ||||
|                 wx.showToast({ | ||||
|                     title: "分享成功", | ||||
|                     icon: "success", | ||||
|                     duration: 2e3 | ||||
|                 }); | ||||
|             }, | ||||
|             fail: function(n) { | ||||
|                 wx.showToast({ | ||||
|                     title: "分享失败", | ||||
|                     icon: "none", | ||||
|                     duration: 2e3 | ||||
|                 }); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }); | ||||
							
								
								
									
										3
									
								
								pages/agent/agent.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								pages/agent/agent.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| { | ||||
|     "usingComponents": {} | ||||
| } | ||||
							
								
								
									
										1
									
								
								pages/agent/agent.wxml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								pages/agent/agent.wxml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| <text>pages/agent/agent.wxml</text> | ||||
							
								
								
									
										0
									
								
								pages/agent/agent.wxss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pages/agent/agent.wxss
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										641
									
								
								pages/aitools/aitools.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										641
									
								
								pages/aitools/aitools.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,641 @@ | ||||
| //index.js | ||||
| const app = getApp() | ||||
| import TextDecoder from '../../utils/miniprogram-text-decoder' | ||||
| Page({ | ||||
|   data: { | ||||
|     currentTab: 'ToText', // 初始选择文生视频 | ||||
|     uploadedImage: '', | ||||
|     userInfo: {}, | ||||
|     videoUrl: '', | ||||
|     uuid: '', | ||||
|     inputValue: '', | ||||
|     charCount: 0, | ||||
|     picInputValue: '', | ||||
|     picCharCount: 0, | ||||
|     sizes: [{ | ||||
|         ratio: '1:1', | ||||
|         width: 1080, | ||||
|         height: 1080 | ||||
|       }, | ||||
|       { | ||||
|         ratio: '16:9', | ||||
|         width: 1920, | ||||
|         height: 1080 | ||||
|       }, | ||||
|       { | ||||
|         ratio: '9:16', | ||||
|         width: 1080, | ||||
|         height: 1920 | ||||
|       }, | ||||
|       { | ||||
|         ratio: '4:3', | ||||
|         width: 1440, | ||||
|         height: 1080 | ||||
|       }, | ||||
|       { | ||||
|         ratio: '3:4', | ||||
|         width: 1080, | ||||
|         height: 1440 | ||||
|       } | ||||
|     ], | ||||
|     selectedSize: '9:16', | ||||
|     selectedWidth: 1080, | ||||
|     selectedHeight: 1920, | ||||
|     styles: { | ||||
|       abandoned: '废弃', | ||||
|       abstract_sculpture: '抽象', | ||||
|       advertising: '广告', | ||||
|       anime: '动漫', | ||||
|       cine_lens: '电影镜头', | ||||
|       cinematic: '电影', | ||||
|       concept_art: '艺术', | ||||
|       forestpunk: '赛博朋克', | ||||
|       frost: '雪', | ||||
|       graphite: '石墨', | ||||
|       macro_photography: '宏观', | ||||
|       pixel_art: '像素艺术', | ||||
|       retro_photography: '复古', | ||||
|       sci_fi_art: '科幻', | ||||
|       thriller: '惊悚', | ||||
|       '35mm': '35mm', | ||||
|       vector: '矢量', | ||||
|       watercolor: '水彩' | ||||
|     }, | ||||
|     selectedStyle: '', | ||||
|     enhanceValue: 5, // 初始值设置为5 | ||||
|     picEnhanceValue: 5, | ||||
|  | ||||
|     ShowPicUrl: '', | ||||
|     tempImg: null, // 图片 | ||||
|     messages: {}, | ||||
|     messagesTemp: { | ||||
|       is_response: true, | ||||
|       content: '您好,我是智能AI助手,请问有什么可以帮助您的?' | ||||
|     }, | ||||
|     inputMessage: "", | ||||
|     toView: 'toBottom1', | ||||
|     showRoleDropdown: false, | ||||
|     currentRole: 9, // 默认角色 | ||||
|     currentRoleText: '选择角色', | ||||
|     roles: [] | ||||
|  | ||||
|   }, | ||||
|  | ||||
|  | ||||
|   // 文生视频提交 | ||||
|   textGenerateSubmit() { | ||||
|     if (this.data.inputValue === "") { | ||||
|       wx.showToast({ | ||||
|         title: '请输入视频描述', | ||||
|         icon: 'error' | ||||
|       }) | ||||
|       return | ||||
|     } | ||||
|  | ||||
|     let userId = wx.getStorageSync('userId') | ||||
|     const data = { | ||||
|       user_id: userId, | ||||
|       text_prompt: this.data.inputValue, | ||||
|       width: this.data.selectedWidth, | ||||
|       height: this.data.selectedHeight, | ||||
|       motion_score: this.data.enhanceValue, | ||||
|       style: this.data.selectedStyle | ||||
|     } | ||||
|     wx.showLoading({ | ||||
|       title: '任务提交中', | ||||
|     }) | ||||
|     app.apiRequest({ | ||||
|       url: "/myapp/generate_video/", | ||||
|       method: "POST", | ||||
|       data, | ||||
|       success: res => { | ||||
|         console.log('res', res); | ||||
|         if (res.data.success === false) { | ||||
|           wx.showModal({ | ||||
|             title: "文生视频", | ||||
|             content: "哎呀!创意点数不足, 请充值", | ||||
|             confirmColor: "#00B269", | ||||
|             cancelColor: "#858585", | ||||
|             success: function (e) { | ||||
|               e.confirm ? (console.log("确定"), wx.navigateTo({ | ||||
|                 url: "../vip_recharge/vip_recharge?show=true" | ||||
|               })) : e.cancel && console.log("取消"); | ||||
|             } | ||||
|           }) | ||||
|         } else { | ||||
|           wx.navigateTo({ | ||||
|             url: '/pages/tips/tips', | ||||
|           }) | ||||
|         } | ||||
|       }, | ||||
|       fail: err => { | ||||
|         console.log('err', err); | ||||
|       }, | ||||
|       complete: () => { | ||||
|         wx.hideLoading() | ||||
|       } | ||||
|     }) | ||||
|   }, | ||||
|   // 图生视频提交 | ||||
|   async picGenerateSubmit() { | ||||
|     if (this.data.ShowPicUrl === "") { | ||||
|       wx.showToast({ | ||||
|         title: '请上传图片', | ||||
|         icon: 'error' | ||||
|       }) | ||||
|       return | ||||
|     } | ||||
|     if (this.data.picInputValue === "") { | ||||
|       wx.showToast({ | ||||
|         title: '请输入视频描述', | ||||
|         icon: 'error' | ||||
|       }) | ||||
|       return | ||||
|     } | ||||
|  | ||||
|     let imageUrl = '' | ||||
|     wx.showLoading({ | ||||
|       title: '任务提交中', | ||||
|     }) | ||||
|     try { | ||||
|       let res = await app.uploadFile(this.data.ShowPicUrl) | ||||
|       imageUrl = app.globalData.apiDomain + JSON.parse(res).file_url | ||||
|     } catch (error) { | ||||
|       console.log('error', error); | ||||
|       wx.hideLoading() | ||||
|       wx.showToast({ | ||||
|         title: '图片上传失败,请稍后重试~', | ||||
|         icon: 'error' | ||||
|       }); | ||||
|       return | ||||
|     } | ||||
|     let userId = wx.getStorageSync('userId') | ||||
|     const data = { | ||||
|       user_id: userId, | ||||
|       image_url: imageUrl, | ||||
|       text_prompt: this.data.picInputValue, | ||||
|       motion_score: this.data.picEnhanceValue | ||||
|     } | ||||
|     app.apiRequest({ | ||||
|       url: "/myapp/generate_image_video/", | ||||
|       method: "POST", | ||||
|       data, | ||||
|       success: res => { | ||||
|         console.log('res', res); | ||||
|         if (res.data.success === false) { | ||||
|           wx.showModal({ | ||||
|             title: "图生视频", | ||||
|             content: "哎呀!创意点数不足, 请充值", | ||||
|             confirmColor: "#00B269", | ||||
|             cancelColor: "#858585", | ||||
|             success: function (e) { | ||||
|               e.confirm ? (console.log("确定"), wx.navigateTo({ | ||||
|                 url: "../vip_recharge/vip_recharge?show=true" | ||||
|               })) : e.cancel && console.log("取消"); | ||||
|             } | ||||
|           }) | ||||
|         } else { | ||||
|           wx.navigateTo({ | ||||
|             url: '/pages/tips/tips', | ||||
|           }) | ||||
|  | ||||
|         } | ||||
|       }, | ||||
|       fail: err => { | ||||
|         console.log('err', err); | ||||
|       }, | ||||
|       complete: () => { | ||||
|         wx.hideLoading() | ||||
|       } | ||||
|     }) | ||||
|   }, | ||||
|   // 点击上传图片 | ||||
|   uploadImage() { | ||||
|     let that = this | ||||
|     wx.chooseMedia({ | ||||
|       count: 1, | ||||
|       mediaType: ['image'], | ||||
|       sourceType: ['album'], | ||||
|       success(res) { | ||||
|         console.log(res) | ||||
|         let tempImg = res.tempFiles[0] | ||||
|         let pictureSize = tempImg.size | ||||
|         let ShowPicUrl = tempImg.tempFilePath | ||||
|         if (pictureSize > 1024 * 1024 * 10) { | ||||
|           wx.showToast({ | ||||
|             title: '图片大小不能超过10MB', | ||||
|             icon: 'error' | ||||
|           }) | ||||
|           return | ||||
|         } | ||||
|         that.setData({ | ||||
|           tempImg, | ||||
|           ShowPicUrl | ||||
|         }) | ||||
|       } | ||||
|     }) | ||||
|   }, | ||||
|   switchNav(e) { | ||||
|     const nav = e.currentTarget.dataset.nav; | ||||
|     console.log(nav) | ||||
|     this.setData({ | ||||
|       currentTab: nav | ||||
|     }); | ||||
|   }, | ||||
|   // 文生视频输入 | ||||
|   onInput(e) { | ||||
|     const value = e.detail.value; | ||||
|     this.setData({ | ||||
|       inputValue: value, | ||||
|       charCount: value.length | ||||
|     }); | ||||
|   }, | ||||
|   // 图生视频输入 | ||||
|   onPicInput(e) { | ||||
|     const value = e.detail.value; | ||||
|     this.setData({ | ||||
|       picInputValue: value, | ||||
|       picCharCount: value.length | ||||
|     }); | ||||
|   }, | ||||
|   optimizePrompt() { | ||||
|     // 优化提示词的逻辑 | ||||
|     console.log("优化提示词按钮被点击"); | ||||
|     // 可以在这里实现优化提示词的功能 | ||||
|   }, | ||||
|   // 文生视频运动增强 | ||||
|   onSliderChange(e) { | ||||
|     const value = e.detail.value; | ||||
|     this.setData({ | ||||
|       enhanceValue: value | ||||
|     }); | ||||
|   }, | ||||
|   // 图生视频运动增强 | ||||
|   onPicSliderChange(e) { | ||||
|     const value = e.detail.value; | ||||
|     this.setData({ | ||||
|       picEnhanceValue: value | ||||
|     }); | ||||
|   }, | ||||
|   selectStyle(e) { | ||||
|     const { | ||||
|       key | ||||
|     } = e.currentTarget.dataset; | ||||
|     this.setData({ | ||||
|       selectedStyle: key | ||||
|     }); | ||||
|   }, | ||||
|   selectSize(e) { | ||||
|     const { | ||||
|       ratio, | ||||
|       width, | ||||
|       height | ||||
|     } = e.currentTarget.dataset; | ||||
|     this.setData({ | ||||
|       selectedSize: ratio, | ||||
|       selectedWidth: width, | ||||
|       selectedHeight: height | ||||
|     }); | ||||
|   }, | ||||
|   onSliderChange(e) { | ||||
|     const value = e.detail.value; | ||||
|     this.setData({ | ||||
|       enhanceValue: value | ||||
|     }); | ||||
|   }, | ||||
|   onLoad: function (options) { | ||||
|     let uuid = options.uuid || '' | ||||
|     this.setData({ | ||||
|       uuid: uuid | ||||
|     }) | ||||
|     wx.showShareMenu({ | ||||
|       withShareTicket: true, | ||||
|       menus: ['shareAppMessage', 'shareTimeline'] | ||||
|     }) | ||||
|  | ||||
|     // 获取角色列表 | ||||
|     this.getRoles() | ||||
|     // 获取聊天记录 | ||||
|     this.getChatRecords() | ||||
|   }, | ||||
|   // 获取角色列表 | ||||
|   getRoles() { | ||||
|     let that = this | ||||
|     wx.showLoading({ | ||||
|       title: '加载中', | ||||
|     }) | ||||
|     app.chatApiRequest({ | ||||
|       url: "/chat/getRoles", | ||||
|       method: "GET", | ||||
|       success: res => { | ||||
|         console.log('res', res) | ||||
|         this.setData({ | ||||
|           roles: res.data.roles, | ||||
|           currentRole: 9 // 默认9  AI助手 | ||||
|         }) | ||||
|       }, | ||||
|       fail: err => { | ||||
|         console.log('err', err) | ||||
|       }, | ||||
|       complete: () => { | ||||
|  | ||||
|       } | ||||
|     }) | ||||
|   }, | ||||
|   // 获取聊天记录 | ||||
|   getChatRecords() { | ||||
|     let that = this | ||||
|     let userId = wx.getStorageSync('userId') | ||||
|     let openId = wx.getStorageSync('openid') | ||||
|     wx.showLoading({ | ||||
|       title: '加载中', | ||||
|     }) | ||||
|     app.chatApiRequest({ | ||||
|       url: '/chat/getRecord', | ||||
|       method: 'POST', | ||||
|       data: { | ||||
|         nickname: userId, | ||||
|         openid: openId, | ||||
|         role_id: this.data.currentRole | ||||
|       }, | ||||
|       success: (res) => { | ||||
|         let messages = this.data.messages | ||||
|         messages[that.data.currentRole] = res.data.records | ||||
|         that.setData({ | ||||
|           messages | ||||
|         }) | ||||
|         that.scrollToBottom() | ||||
|       }, | ||||
|       fail: (err) => { | ||||
|         console.log('err', err) | ||||
|       }, | ||||
|       complete: () => { | ||||
|         wx.hideLoading() | ||||
|       } | ||||
|     }) | ||||
|   }, | ||||
|   bindInput(e) { | ||||
|     this.setData({ | ||||
|       inputMessage: e.detail.value | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   // 滚动条置底 | ||||
|   scrollToBottom() { | ||||
|     this.setData({ | ||||
|       toView: this.data.toView === 'toBottom1' ? 'toBottom2' : 'toBottom1' | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   // 发送 | ||||
|   sendMessage() { | ||||
|     let that = this | ||||
|     let inputMessage = this.data.inputMessage | ||||
|     if (inputMessage === '') { | ||||
|       wx.showToast({ | ||||
|         title: '请输入消息', | ||||
|         icon: 'none' | ||||
|       }) | ||||
|       return false | ||||
|     } | ||||
|  | ||||
|     let messages = that.data.messages | ||||
|     // 获取会话session_id | ||||
|     let sessionID | ||||
|     if (messages[this.data.currentRole].length !== 0) { | ||||
|       sessionID = messages[this.data.currentRole][messages[this.data.currentRole].length - 1].session_id | ||||
|     } | ||||
|     messages[this.data.currentRole].push({ | ||||
|       is_response: false, | ||||
|       message_content: inputMessage | ||||
|     }) | ||||
|     this.setData({ | ||||
|       inputMessage: '' | ||||
|     }) | ||||
|  | ||||
|     messages[this.data.currentRole].push({ | ||||
|       is_response: true, | ||||
|       message_content: '', | ||||
|       isGenerating: true | ||||
|     }) | ||||
|     that.setData({ | ||||
|       messages: messages, | ||||
|     }) | ||||
|     this.scrollToBottom() | ||||
|     let userId = wx.getStorageSync('userId') | ||||
|     let openid = wx.getStorageSync('openid') | ||||
|     let role = this.data.currentRole | ||||
|  | ||||
|  | ||||
|     let reqTask = app.chatApiRequest({ | ||||
|       url: '/chat/send', | ||||
|       method: 'POST', | ||||
|       enableChunked: true, | ||||
|       data: { | ||||
|         openid, | ||||
|         userid: userId, | ||||
|         prompt: inputMessage, | ||||
|         role_id: role, | ||||
|         session_id: sessionID | ||||
|       }, | ||||
|       success: (res) => { | ||||
|         // console.log('res', res) | ||||
|       }, | ||||
|       fail: (err) => { | ||||
|         console.log('err', err) | ||||
|       } | ||||
|     }) | ||||
|     let newMessages = this.data.messages | ||||
|     let currentMessages = newMessages[this.data.currentRole] | ||||
|     let lastMessages = currentMessages[currentMessages.length - 1] | ||||
|     reqTask.onChunkReceived(r => { | ||||
|       let decoder = new TextDecoder('utf-8'); | ||||
|       let str = decoder.decode(r.data); | ||||
|       let lines = str.split('\n\n') | ||||
|       lines.pop() | ||||
|       for (let i of lines) { | ||||
|         let jsonStr = i | ||||
|         if (i.startsWith("data:")) { | ||||
|           jsonStr = jsonStr.substring(5); | ||||
|         } | ||||
|         let messageObject = JSON.parse(jsonStr) | ||||
|         lastMessages.isGenerating = false | ||||
|         lastMessages.message_content += messageObject.output.text | ||||
|         lastMessages.session_id = messageObject.output.session_id | ||||
|         this.setData({ | ||||
|           messages: newMessages | ||||
|         }) | ||||
|       } | ||||
|  | ||||
|       that.scrollToBottom() | ||||
|     }) | ||||
|   }, | ||||
|  | ||||
|   utf8ArrayToStr(array) { | ||||
|     var out, i, len, c; | ||||
|     var char2, char3; | ||||
|  | ||||
|     out = ""; | ||||
|     len = array.length; | ||||
|     i = 0; | ||||
|     while (i < len) { | ||||
|       c = array[i++]; | ||||
|       switch (c >> 4) { | ||||
|         case 0: | ||||
|         case 1: | ||||
|         case 2: | ||||
|         case 3: | ||||
|         case 4: | ||||
|         case 5: | ||||
|         case 6: | ||||
|         case 7: | ||||
|           // 0xxxxxxx | ||||
|           out += String.fromCharCode(c); | ||||
|           break; | ||||
|         case 12: | ||||
|         case 13: | ||||
|           // 110x xxxx   10xx xxxx | ||||
|           char2 = array[i++]; | ||||
|           out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F)); | ||||
|           break; | ||||
|         case 14: | ||||
|           // 1110 xxxx  10xx xxxx  10xx xxxx | ||||
|           char2 = array[i++]; | ||||
|           char3 = array[i++]; | ||||
|           out += String.fromCharCode(((c & 0x0F) << 12) | | ||||
|             ((char2 & 0x3F) << 6) | | ||||
|             ((char3 & 0x3F) << 0)); | ||||
|           break; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     return out; | ||||
|   }, | ||||
|  | ||||
|  | ||||
|   toggleRoleDropdown() { | ||||
|     this.setData({ | ||||
|       showRoleDropdown: !this.data.showRoleDropdown, | ||||
|     }); | ||||
|   }, | ||||
|   switchRole(event) { | ||||
|     const roleIndex = event.currentTarget.dataset.role; | ||||
|     this.setData({ | ||||
|       currentRole: this.data.roles[roleIndex].id, | ||||
|       currentRoleText: this.data.roles[roleIndex].name, | ||||
|       showRoleDropdown: false, | ||||
|     }); | ||||
|     this.getChatRecords() | ||||
|     // 在这里你可以根据需要添加更多逻辑,比如切换到不同的AI模型 | ||||
|   }, | ||||
|  | ||||
|   // 判断邀请用户 | ||||
|   sendReward_invitation: function (uuid) { | ||||
|     app.apiRequest({ | ||||
|       url: '/myapp/reward_invitation', // 后端接口URL | ||||
|       method: 'POST', | ||||
|       data: { | ||||
|         openid: wx.getStorageSync('openid'), | ||||
|         uuid: uuid, | ||||
|       }, | ||||
|       success(res) { | ||||
|         console.log(res); | ||||
|         if (res.data.success == true) { | ||||
|           wx.setStorageSync('defaultDailyFreeParseNum', wx.getStorageSync('defaultDailyFreeParseNum') + 10); | ||||
|         } | ||||
|       }, | ||||
|       fail(err) { | ||||
|         console.error(err); | ||||
|         // 错误处理 | ||||
|       } | ||||
|     }); | ||||
|  | ||||
|   }, | ||||
|  | ||||
|  | ||||
|   onShow() { | ||||
|     app.getCurrentTabbar(1, this); | ||||
|     app.checkUpdateVersion() | ||||
|     wx.showLoading() | ||||
|     app.getUserInfo().then(() => { | ||||
|       if (this.data.uuid != '' && wx.getStorageSync('openid') != '' && wx.getStorageSync('uuid') != this.data.uuid) { | ||||
|         this.sendReward_invitation(this.data.uuid); | ||||
|       } | ||||
|     }).catch(error => { | ||||
|       console.error('获取用户信息失败:', error); | ||||
|     }).finally(() => { | ||||
|       console.log('getUserInfo调用完成'); | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   // 清空输入框 | ||||
|   inputClear: function () { | ||||
|     this.setData({ | ||||
|       videoUrl: '' | ||||
|     }) | ||||
|   }, | ||||
|  | ||||
|   copyContent(e) { | ||||
|     console.log(e) | ||||
|     const content = e.target.dataset.content; | ||||
|     wx.setClipboardData({ | ||||
|       data: content, | ||||
|       success() { | ||||
|         wx.showToast({ | ||||
|           title: '内容已复制', | ||||
|           icon: 'none', | ||||
|         }); | ||||
|       }, | ||||
|       fail(err) { | ||||
|         wx.showToast({ | ||||
|           title: '复制失败', | ||||
|           icon: 'none', | ||||
|         }); | ||||
|         console.error('复制失败', err); | ||||
|       } | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   onShareAppMessage: function () { | ||||
|     return { | ||||
|       title: '推荐一款免费又超好用的AI视频文案创作工具,快来体验吧', | ||||
|       path: '/pages/index/index?uuid=' + wx.getStorageSync('uuid'), | ||||
|       imageUrl: '/images/index.jpg', | ||||
|       success: function (e) { | ||||
|         wx.showToast({ | ||||
|           title: "分享成功", | ||||
|           icon: "success", | ||||
|           duration: 2e3 | ||||
|         }); | ||||
|       }, | ||||
|       fail: function (e) { | ||||
|         wx.showToast({ | ||||
|           title: "分享失败", | ||||
|           icon: "none", | ||||
|           duration: 2e3 | ||||
|         }); | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   onShareTimeline: function () { | ||||
|     return { | ||||
|       title: '推荐一款免费又超好用的AI视频文案创作工具,快来体验吧', | ||||
|       path: '/pages/index/index?uuid=' + wx.getStorageSync('uuid'), | ||||
|       imageUrl: '/images/index.jpg', | ||||
|       success: function (e) { | ||||
|         wx.showToast({ | ||||
|           title: "分享成功", | ||||
|           icon: "success", | ||||
|           duration: 2e3 | ||||
|         }); | ||||
|       }, | ||||
|       fail: function (e) { | ||||
|         wx.showToast({ | ||||
|           title: "分享失败", | ||||
|           icon: "none", | ||||
|           duration: 2e3 | ||||
|         }); | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
| }) | ||||
							
								
								
									
										7
									
								
								pages/aitools/aitools.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								pages/aitools/aitools.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| { | ||||
|   "usingComponents": {}, | ||||
|   "navigationBarTitleText": "创作助手", | ||||
|   "navigationBarBackgroundColor": "#222238", | ||||
|   "navigationBarTextStyle": "white", | ||||
|   "custom-tab-bar": "/custom-tab-bar/index" | ||||
| } | ||||
							
								
								
									
										73
									
								
								pages/aitools/aitools.wxml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								pages/aitools/aitools.wxml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| <view class="container"> | ||||
|     <view class="navbar"></view> | ||||
|     <view wx:if="{{currentTab==='textToVideo'}}"> | ||||
|         <view class="input-container"> | ||||
|             <textarea bindinput="onInput" class="input-box" maxlength="320" placeholder="输入文本或者图片即可生成原创视频,请用一句话描述您的视频主题、场景、风格等,简洁明了!" value="{{inputValue}}"></textarea> | ||||
|             <view class="char-count">{{charCount}}/320</view> | ||||
|         </view> | ||||
|         <view class="style-selector"> | ||||
|             <view class="style-text">选择风格:</view> | ||||
|             <view class="style-options"> | ||||
|                 <view bindtap="selectStyle" class="style-option {{selectedStyle===key?'active':''}}" data-key="{{key}}" wx:for="{{styles}}" wx:for-index="key" wx:for-item="style" wx:key="{{key}}"> {{style}} </view> | ||||
|             </view> | ||||
|         </view> | ||||
|         <view class="size-selector"> | ||||
|             <text class="size-text">选择尺寸:</text> | ||||
|             <view class="size-options"> | ||||
|                 <view bindtap="selectSize" class="size-option {{selectedSize===item.ratio?'active':''}}" data-height="{{item.height}}" data-ratio="{{item.ratio}}" data-width="{{item.width}}" wx:for="{{sizes}}" wx:key="index"> {{item.ratio}} </view> | ||||
|             </view> | ||||
|         </view> | ||||
|         <view class="enhance-container"> | ||||
|             <text class="enhance-text">运动增强:</text> | ||||
|             <slider showValue bindchange="onSliderChange" class="enhance-slider" max="10" min="0" value="{{enhanceValue}}"></slider> | ||||
|         </view> | ||||
|         <text class="description-text">数值越高,视频画面越丰富 【文生视频消耗 10创意点/次】</text> | ||||
|         <button bindtap="textGenerateSubmit" class="generate-button">生成视频</button> | ||||
|     </view> | ||||
|     <view class="full-container" wx:if="{{currentTab==='imageToVideo'}}"> | ||||
|         <view bindtap="uploadImage" class="upload-container"> | ||||
|             <image class="upload-pic" mode="aspectFit" src="{{ShowPicUrl}}" wx:if="{{ShowPicUrl}}"></image> | ||||
|             <view class="upload-wrap" wx:else> | ||||
|                 <image class="upload-icon" src="/images/icon-upload.png"></image> | ||||
|                 <text class="upload-text"> | ||||
|                     <text class="upload-link">点击上传图片</text> | ||||
|                 </text> | ||||
|                 <text class="upload-info">只能上传jpg/png文件,且不超过10MB</text> | ||||
|             </view> | ||||
|         </view> | ||||
|         <view class="img-input-container"> | ||||
|             <textarea bindinput="onPicInput" class="input-box" maxlength="320" placeholder="输入提示词来描述您想要的视频内容" value="{{picInputValue}}"></textarea> | ||||
|             <view class="char-count">{{picCharCount}}/320</view> | ||||
|         </view> | ||||
|         <view class="enhance-container" style="margin-top: 10px;"> | ||||
|             <text class="enhance-text">运动增强:</text> | ||||
|             <slider showValue bindchange="onPicSliderChange" class="enhance-slider" max="10" min="0" value="{{picEnhanceValue}}"></slider> | ||||
|         </view> | ||||
|         <text class="description-text" style="float: left;">数值越高,视频画面越丰富 【图生视频消耗 10创意点/次】</text> | ||||
|         <button bindtap="picGenerateSubmit" class="generate-button">生成视频</button> | ||||
|     </view> | ||||
|     <view class="chat-box" wx:if="{{currentTab==='ToText'}}"> | ||||
|         <view class="role-switch"> | ||||
|             <button bindtap="toggleRoleDropdown" class="role-button">{{currentRoleText}} <image class="role-icon" src="../../images/切换角色.png"></image> | ||||
|             </button> | ||||
|             <view class="role-dropdown" wx:if="{{showRoleDropdown}}"> | ||||
|                 <view bindtap="switchRole" class="role-option" data-role="{{index}}" wx:for="{{roles}}" wx:key="index">{{item.name}}</view> | ||||
|             </view> | ||||
|         </view> | ||||
|         <scroll-view class="chat-window" scrollIntoView="{{toView}}" scrollY="true"> | ||||
|             <view class="message {{item.is_response?'ai':'user'}}" wx:for="{{messages[currentRole?currentRole:9]}}" wx:key="index"> | ||||
|                 <image class="avatar" src="{{item.is_response?'../../images/人工智能机器人.png':'../../images/老师教师男人.png'}}"></image> | ||||
|                 <view class="bubble"> | ||||
|                     <view class="loading-dot" wx:if="{{item.isGenerating}}"></view> | ||||
|                     <text bindtap="copyContent" class="content" data-content="{{item.message_content}}" wx:else>{{item.message_content}}</text> | ||||
|                 </view> | ||||
|             </view> | ||||
|             <view id="toBottom1"></view> | ||||
|             <view id="toBottom2"></view> | ||||
|         </scroll-view> | ||||
|         <view class="input-area"> | ||||
|             <input autoHeight adjust-position='true' bindinput="bindInput" class="input-field"  placeholder="请输入消息..." value="{{inputMessage}}"></input> | ||||
|             <button bindtap="sendMessage" class="send-button">发送</button> | ||||
|         </view> | ||||
|     </view> | ||||
| </view> | ||||
							
								
								
									
										414
									
								
								pages/aitools/aitools.wxss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										414
									
								
								pages/aitools/aitools.wxss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,414 @@ | ||||
| .container,page { | ||||
|     background-color: #222238; | ||||
| } | ||||
|  | ||||
| .container { | ||||
|     border-top: 1px solid hsla(0,31%,87%,.5); | ||||
|     box-sizing: border-box; | ||||
|     color: #fff; | ||||
|     padding: 10px 10px 61px; | ||||
| } | ||||
|  | ||||
| .navbar { | ||||
|     background: linear-gradient(180deg,#8d72d2,#7183f3); | ||||
|     border-radius: 5px; | ||||
|     display: flex; | ||||
|     justify-content: space-between; | ||||
|     width: 300px; | ||||
| } | ||||
|  | ||||
| .nav-item { | ||||
|     color: #fff; | ||||
|     flex: 1; | ||||
|     padding: 5px 10px; | ||||
|     text-align: center; | ||||
| } | ||||
|  | ||||
| .nav-item.active { | ||||
|     background: linear-gradient(90deg,#6949bb,#4d65fd); | ||||
|     border-bottom: 3px solid #d9d4e4; | ||||
|     border-radius: 5px; | ||||
| } | ||||
|  | ||||
| .description-text { | ||||
|     color: #a790e2; | ||||
|     font-size: 12px; | ||||
| } | ||||
|  | ||||
| .input-container { | ||||
|     margin: 10px 0; | ||||
|     position: relative; | ||||
|     width: 100%; | ||||
| } | ||||
|  | ||||
| .input-box { | ||||
|     background-color: #333; | ||||
|     border: none; | ||||
|     color: #fff; | ||||
|     height: 150px; | ||||
| } | ||||
|  | ||||
| .char-count { | ||||
|     bottom: 10px; | ||||
|     color: #ccc; | ||||
|     position: absolute; | ||||
|     right: 10px; | ||||
| } | ||||
|  | ||||
| .optimize-button { | ||||
|     background: linear-gradient(90deg,#6949bb,#4d65fd); | ||||
|     border-radius: 5px; | ||||
|     bottom: 3px; | ||||
|     font-size: 13px; | ||||
|     left: 3px; | ||||
|     padding: 5px; | ||||
|     position: absolute; | ||||
|     text-align: center; | ||||
|     z-index: 9999; | ||||
| } | ||||
|  | ||||
| .platform-selector { | ||||
|     background-color: #333; | ||||
|     border-radius: 5px; | ||||
|     margin-bottom: 20px; | ||||
|     padding: 10px; | ||||
| } | ||||
|  | ||||
| .platform-text { | ||||
|     font-weight: 700; | ||||
| } | ||||
|  | ||||
| .platform-dropdown { | ||||
|     margin-top: 10px; | ||||
| } | ||||
|  | ||||
| .size-selector,.style-selector { | ||||
|     margin-bottom: 20px; | ||||
|     width: 100%; | ||||
| } | ||||
|  | ||||
| .size-text,.style-text { | ||||
|     font-weight: 700; | ||||
|     margin-bottom: 10px; | ||||
| } | ||||
|  | ||||
| .size-options,.style-options { | ||||
|     display: flex; | ||||
|     flex-wrap: wrap; | ||||
|     justify-content: space-between; | ||||
| } | ||||
|  | ||||
| .size-option,.style-option { | ||||
|     background-color: #333; | ||||
|     border-radius: 5px; | ||||
|     box-shadow: 1px 3px 3px 1px rgba(0,0,0,.3); | ||||
|     color: #fff; | ||||
|     flex: 1; | ||||
|     font-size: 13px; | ||||
|     margin-bottom: 10px; | ||||
|     margin-right: 10px; | ||||
|     padding: 10px; | ||||
|     text-align: center; | ||||
|     transition: all .3s; | ||||
|     white-space: nowrap; | ||||
| } | ||||
|  | ||||
| .size-option.active,.style-option.active { | ||||
|     background-color: #4a90e2; | ||||
| } | ||||
|  | ||||
| .size-option:last-child,.style-option:last-child { | ||||
|     margin-right: 0; | ||||
| } | ||||
|  | ||||
| .enhance-container { | ||||
|     align-items: center; | ||||
|     display: flex; | ||||
|     width: 100%; | ||||
| } | ||||
|  | ||||
| .enhance-text { | ||||
|     font-weight: 700; | ||||
|     margin-right: 10px; | ||||
| } | ||||
|  | ||||
| .enhance-slider { | ||||
|     flex: 1; | ||||
| } | ||||
|  | ||||
| .generate-button { | ||||
|     background: linear-gradient(90deg,#6949bb,#4d65fd); | ||||
|     border: none; | ||||
|     border-radius: 5px; | ||||
|     color: #fff; | ||||
|     margin: 10px auto; | ||||
|     padding: 5px; | ||||
|     text-align: center; | ||||
|     width: 150px; | ||||
| } | ||||
|  | ||||
| .full-container { | ||||
|     align-items: center; | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     width: 100%; | ||||
| } | ||||
|  | ||||
| .upload-container { | ||||
|     background-color: #333; | ||||
|     border: 1px dashed #666; | ||||
|     border-radius: 10px; | ||||
|     box-shadow: 0 4px 8px rgba(0,0,0,.1); | ||||
|     cursor: pointer; | ||||
|     height: 250px; | ||||
|     margin-top: 15px; | ||||
|     max-width: 400px; | ||||
|     width: 100%; | ||||
| } | ||||
|  | ||||
| .upload-wrap { | ||||
|     align-items: center; | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     height: 250px; | ||||
|     justify-content: center; | ||||
| } | ||||
|  | ||||
| .upload-pic { | ||||
|     height: 100%; | ||||
|     width: 100%; | ||||
| } | ||||
|  | ||||
| .upload-icon { | ||||
|     height: 50px; | ||||
|     margin-bottom: 10px; | ||||
|     width: 50px; | ||||
| } | ||||
|  | ||||
| .upload-text { | ||||
|     color: #999; | ||||
|     font-size: 14px; | ||||
|     margin-bottom: 5px; | ||||
| } | ||||
|  | ||||
| .upload-link { | ||||
|     color: #4a90e2; | ||||
|     text-decoration: underline; | ||||
| } | ||||
|  | ||||
| .upload-info { | ||||
|     color: #666; | ||||
|     font-size: 12px; | ||||
| } | ||||
|  | ||||
| .img-input-container { | ||||
|     margin-top: 10px; | ||||
|     max-width: 400px; | ||||
|     min-height: 200px; | ||||
|     position: relative; | ||||
|     width: 100%; | ||||
| } | ||||
|  | ||||
| .input-box { | ||||
|     border: 1px solid #ccc; | ||||
|     border-radius: 5px; | ||||
|     box-sizing: border-box; | ||||
|     font-size: 14px; | ||||
|     min-height: 200px; | ||||
|     padding: 10px; | ||||
|     resize: none; | ||||
|     width: 100%; | ||||
| } | ||||
|  | ||||
| .char-count { | ||||
|     color: #999; | ||||
|     font-size: 12px; | ||||
|     margin-top: 5px; | ||||
|     text-align: right; | ||||
| } | ||||
|  | ||||
| .chat-box { | ||||
|    | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     height: calc(100vh - 127px); | ||||
|     margin-top: 10px; | ||||
| } | ||||
|  | ||||
| .chat-box,.role-switch { | ||||
|     position: relative; | ||||
|     width: 100%; | ||||
| } | ||||
|  | ||||
| .role-switch { | ||||
|     margin: 0 auto; | ||||
|     text-align: center; | ||||
| } | ||||
|  | ||||
| .role-button { | ||||
|     align-items: center; | ||||
|     background: linear-gradient(180deg,#2b2b49,#26263a); | ||||
|     border: none; | ||||
|     border-radius: 5px; | ||||
|     box-shadow: 0 4px 6px rgba(0,0,0,.3),0 1px 3px rgba(0,0,0,.08); | ||||
|     color: #fff; | ||||
|     cursor: pointer; | ||||
|     font-size: 16px; | ||||
|     width: 100%; | ||||
| } | ||||
|  | ||||
| .role-icon { | ||||
|     height: 16px; | ||||
|     margin-left: 5px; | ||||
|     vertical-align: middle; | ||||
|     width: 16px; | ||||
| } | ||||
|  | ||||
| .role-dropdown { | ||||
|     background: linear-gradient(180deg,#2b2b49,#26263a); | ||||
|     border-radius: 5px; | ||||
|     box-shadow: 0 4px 8px rgba(0,0,0,.3); | ||||
|     left: 50%; | ||||
|     margin-top: 5px; | ||||
|     position: absolute; | ||||
|     top: 100%; | ||||
|     transform: translateX(-50%); | ||||
|     z-index: 1000; | ||||
| } | ||||
|  | ||||
| .role-option { | ||||
|     border-bottom: 1px solid #b39494; | ||||
|     color: #fff; | ||||
|     cursor: pointer; | ||||
|     padding: 10px; | ||||
| } | ||||
|  | ||||
| .role-option:hover { | ||||
|     background: #444; | ||||
| } | ||||
|  | ||||
| .chat-window { | ||||
|     box-sizing: border-box; | ||||
|     flex: 1; | ||||
|     overflow-y: auto; | ||||
|     padding: 10px; | ||||
| } | ||||
|  | ||||
| .message { | ||||
|     display: flex; | ||||
|     margin-bottom: 10px; | ||||
|     margin-top: 10px; | ||||
| } | ||||
|  | ||||
| .message.user { | ||||
|     flex-direction: row-reverse; | ||||
| } | ||||
|  | ||||
| .message .avatar { | ||||
|     border-radius: 20px; | ||||
|     height: 40px; | ||||
|     margin: 0 3px; | ||||
|     width: 40px; | ||||
| } | ||||
|  | ||||
| .bubble { | ||||
|     border-radius: 10px; | ||||
|     box-shadow: 0 0 5px rgba(0,0,0,.5); | ||||
|     color: #d6d3dd; | ||||
|     max-width: 70%; | ||||
|     padding: 10px; | ||||
| } | ||||
|  | ||||
| .message.user .bubble { | ||||
|     background: #6949bb; | ||||
|     color: #fff; | ||||
| } | ||||
|  | ||||
| .message.ai .bubble { | ||||
|     background: #505579; | ||||
|     color: #fff; | ||||
| } | ||||
|  | ||||
| .username { | ||||
|     color: #888; | ||||
|     font-size: 12px; | ||||
| } | ||||
|  | ||||
| .content { | ||||
|     font-size: 14px; | ||||
|     margin-top: 5px; | ||||
| } | ||||
|  | ||||
| .input-area { | ||||
|     background-color: #222238; | ||||
|     box-sizing: border-box; | ||||
|     display: flex; | ||||
|     padding: 10px; | ||||
|     width: 100%; | ||||
|     height: 40px; | ||||
| } | ||||
|  | ||||
| .input-field { | ||||
|     border: 1px solid #ccc; | ||||
|     border-radius: 5px; | ||||
|     box-sizing: border-box; | ||||
|     flex: 1; | ||||
|     min-height: 40px; | ||||
|     padding: 8px; | ||||
|  | ||||
| } | ||||
|  | ||||
| .send-button { | ||||
|     background: linear-gradient(90deg,#6949bb,#4d65fd); | ||||
|     border: none; | ||||
|     border-radius: 5px; | ||||
|     box-sizing: border-box; | ||||
|     color: #fff; | ||||
|     font-size: 16px; | ||||
|     font-weight: 700; | ||||
|     height: 40px; | ||||
|     line-height: 40px; | ||||
|     margin-left: 10px; | ||||
|     padding: 0 20px; | ||||
| } | ||||
|  | ||||
| .buttom { | ||||
|     background-color: initial; | ||||
|     height: 60px; | ||||
|     width: 100%; | ||||
| } | ||||
|  | ||||
| .loading-container { | ||||
|     align-items: center; | ||||
|     display: flex; | ||||
|     height: 100vh; | ||||
|     justify-content: center; | ||||
| } | ||||
|  | ||||
| .loading-dot { | ||||
|     animation: pulse .8s infinite alternate; | ||||
|     background-color: #007bff; | ||||
|     border-radius: 50%; | ||||
|     height: 18px; | ||||
|     width: 18px; | ||||
| } | ||||
|  | ||||
| @-webkit-keyframes pulse { | ||||
|     0% { | ||||
|         transform: scale(1); | ||||
|     } | ||||
|  | ||||
|     100% { | ||||
|         transform: scale(1.4); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @keyframes pulse { | ||||
|     0% { | ||||
|         transform: scale(1); | ||||
|     } | ||||
|  | ||||
|     100% { | ||||
|         transform: scale(1.4); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										263
									
								
								pages/bot-list/bot-list.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										263
									
								
								pages/bot-list/bot-list.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,263 @@ | ||||
| // pages/bot-list/bot-list.js | ||||
| const app = getApp(); | ||||
|  | ||||
| Page({ | ||||
|   data: { | ||||
|     botList: [], | ||||
|     statusText: { | ||||
|       normal: '状态正常', | ||||
|       abnormal: '状态异常', | ||||
|       full: '已满人' | ||||
|     }, | ||||
|     showQrModal: false, | ||||
|     selectedBot: null, | ||||
|     loading: true, | ||||
|     refreshing: false, | ||||
|     error: null, | ||||
|     refreshTimer: null, | ||||
|     lastUpdateTime: 0, | ||||
|     lastUpdateTimeText: '' | ||||
|   }, | ||||
|  | ||||
|   onLoad() { | ||||
|     this.loadBotData(); | ||||
|     this.startAutoRefresh(); | ||||
|   }, | ||||
|  | ||||
|   onUnload() { | ||||
|     this.clearAutoRefresh(); | ||||
|   }, | ||||
|  | ||||
|   startAutoRefresh() { | ||||
|     this.clearAutoRefresh(); | ||||
|     this.data.refreshTimer = setInterval(() => { | ||||
|       if (Date.now() - this.data.lastUpdateTime > 30000) { // 30秒自动刷新 | ||||
|         this.loadBotData(false); | ||||
|       } | ||||
|       this.updateTimeText(); | ||||
|     }, 1000); | ||||
|   }, | ||||
|  | ||||
|   clearAutoRefresh() { | ||||
|     if (this.data.refreshTimer) { | ||||
|       clearInterval(this.data.refreshTimer); | ||||
|       this.data.refreshTimer = null; | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   updateTimeText() { | ||||
|     const diff = Math.floor((Date.now() - this.data.lastUpdateTime) / 1000); | ||||
|     let text = ''; | ||||
|     if (diff < 60) { | ||||
|       text = `${diff}秒前更新`; | ||||
|     } else if (diff < 3600) { | ||||
|       text = `${Math.floor(diff / 60)}分钟前更新`; | ||||
|     } else { | ||||
|       text = `${Math.floor(diff / 3600)}小时前更新`; | ||||
|     } | ||||
|     this.setData({ lastUpdateTimeText: text }); | ||||
|   }, | ||||
|  | ||||
|   async onPullRefresh() { | ||||
|     this.setData({ refreshing: true }); | ||||
|     await this.loadBotData(false); | ||||
|     this.setData({ refreshing: false }); | ||||
|   }, | ||||
|  | ||||
|   loadBotData(showLoading = true) { | ||||
|     if (showLoading) { | ||||
|       this.setData({ loading: true, error: null }); | ||||
|     } | ||||
|  | ||||
|     return new Promise((resolve) => { | ||||
|       app.apiRequest({ | ||||
|         url: `/myapp/api/bots/`, | ||||
|         method: 'GET', | ||||
|         success: (res) => { | ||||
|           if (res.statusCode === 200 && res.data.success) { | ||||
|             this.handleDataSuccess(res.data); | ||||
|           } else { | ||||
|             this.handleDataError(res.data.error || '数据加载失败'); | ||||
|           } | ||||
|         }, | ||||
|         fail: (err) => { | ||||
|           this.handleDataError('网络请求失败'); | ||||
|           console.error('API请求失败:', err); | ||||
|         }, | ||||
|         complete: () => { | ||||
|           if (showLoading) { | ||||
|             this.setData({ loading: false }); | ||||
|           } | ||||
|           resolve(); | ||||
|         } | ||||
|       }); | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   handleDataSuccess(response) { | ||||
|     const formattedData = response.data.map(bot => ({ | ||||
|       ...bot, | ||||
|       last_check: this.formatDateTime(bot.last_check), | ||||
|       selected: false | ||||
|     })); | ||||
|  | ||||
|     this.setData({ | ||||
|       botList: formattedData, | ||||
|       lastUpdateTime: Date.now(), | ||||
|       error: null | ||||
|     }); | ||||
|     this.updateTimeText(); | ||||
|   }, | ||||
|  | ||||
|   handleDataError(message) { | ||||
|     this.setData({ | ||||
|       error: message, | ||||
|       loading: false | ||||
|     }); | ||||
|     wx.showToast({ | ||||
|       title: message, | ||||
|       icon: 'none', | ||||
|       duration: 2000 | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   formatDateTime(datetimeStr) { | ||||
|     if (!datetimeStr) return '暂无数据'; | ||||
|     try { | ||||
|       const date = new Date(datetimeStr); | ||||
|       return `${date.getFullYear()}-${(date.getMonth()+1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`; | ||||
|     } catch { | ||||
|       return datetimeStr; | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   selectBot(e) { | ||||
|     const bot = e.currentTarget.dataset.bot; | ||||
|     const botList = this.data.botList.map(item => ({ | ||||
|       ...item, | ||||
|       selected: item.wxid === bot.wxid | ||||
|     })); | ||||
|     this.setData({ botList }); | ||||
|   }, | ||||
|  | ||||
|   copyAccount(e) { | ||||
|     const account = e.currentTarget.dataset.account; | ||||
|     wx.setClipboardData({ | ||||
|       data: account, | ||||
|       success: () => { | ||||
|         wx.showToast({  | ||||
|           title: '微信号已复制', | ||||
|           icon: 'success' | ||||
|         }); | ||||
|       }, | ||||
|       fail: () => { | ||||
|         wx.showToast({  | ||||
|           title: '复制失败', | ||||
|           icon: 'none' | ||||
|         }); | ||||
|       } | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   showQrcode(e) { | ||||
|     const index = e.currentTarget.dataset.index; | ||||
|     const selectedBot = this.data.botList[index]; | ||||
|     this.setData({ | ||||
|       showQrModal: true, | ||||
|       selectedBot | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   closeQrcode() { | ||||
|     this.setData({  | ||||
|       showQrModal: false, | ||||
|       selectedBot: null, | ||||
|       botList: this.data.botList.map(bot => ({ | ||||
|         ...bot, | ||||
|         selected: false | ||||
|       })) | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   preventBubble() { | ||||
|     // 防止点击内容区域关闭弹窗 | ||||
|     return; | ||||
|   }, | ||||
|  | ||||
|   saveQrcode() { | ||||
|     if (!this.data.selectedBot?.qrcode_url) { | ||||
|       wx.showToast({ | ||||
|         title: '二维码地址无效', | ||||
|         icon: 'none' | ||||
|       }); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     wx.getSetting({ | ||||
|       success: (res) => { | ||||
|         if (!res.authSetting['scope.writePhotosAlbum']) { | ||||
|           wx.authorize({ | ||||
|             scope: 'scope.writePhotosAlbum', | ||||
|             success: () => this.doSaveImage(), | ||||
|             fail: () => this.showAuthGuide() | ||||
|           }); | ||||
|         } else { | ||||
|           this.doSaveImage(); | ||||
|         } | ||||
|       } | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   doSaveImage() { | ||||
|     wx.showLoading({ title: '保存中...' }); | ||||
|     wx.downloadFile({ | ||||
|       url: this.data.selectedBot.qrcode_url, | ||||
|       success: (res) => { | ||||
|         wx.saveImageToPhotosAlbum({ | ||||
|           filePath: res.tempFilePath, | ||||
|           success: () => { | ||||
|             wx.hideLoading(); | ||||
|             wx.showToast({  | ||||
|               title: '已保存到相册', | ||||
|               icon: 'success' | ||||
|             }); | ||||
|           }, | ||||
|           fail: () => { | ||||
|             wx.hideLoading(); | ||||
|             wx.showToast({  | ||||
|               title: '保存失败', | ||||
|               icon: 'none' | ||||
|             }); | ||||
|           } | ||||
|         }); | ||||
|       }, | ||||
|       fail: () => { | ||||
|         wx.hideLoading(); | ||||
|         wx.showToast({  | ||||
|           title: '图片下载失败', | ||||
|           icon: 'none' | ||||
|         }); | ||||
|       } | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   showAuthGuide() { | ||||
|     wx.showModal({ | ||||
|       title: '需要授权', | ||||
|       content: '请允许保存图片到相册,以便保存二维码', | ||||
|       confirmText: '去设置', | ||||
|       success: (res) => { | ||||
|         if (res.confirm) { | ||||
|           wx.openSetting(); | ||||
|         } | ||||
|       } | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   handleImageError() { | ||||
|     wx.showToast({ | ||||
|       title: '二维码加载失败', | ||||
|       icon: 'none' | ||||
|     }); | ||||
|   } | ||||
| }); | ||||
							
								
								
									
										6
									
								
								pages/bot-list/bot-list.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								pages/bot-list/bot-list.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| { | ||||
|   "navigationBarTitleText": "机器人监控", | ||||
|   "navigationBarBackgroundColor": "#222238", | ||||
|   "navigationBarTextStyle": "white" | ||||
|    | ||||
| } | ||||
							
								
								
									
										86
									
								
								pages/bot-list/bot-list.wxml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								pages/bot-list/bot-list.wxml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | ||||
| <!-- pages/bot-list/bot-list.wxml --> | ||||
| <view class="container"> | ||||
|   <!-- 功能介绍区域 --> | ||||
|   <view class="guide-box"> | ||||
|     <image src="/images/butterfly-icon.png" class="guide-icon" mode="aspectFit"></image> | ||||
|     <text class="guide-text">下载蝴蝶号视频教程:\n1. 添加下方机器人\n2. 转发视频给机器人\n3. 自动回复下载链接</text> | ||||
|   </view> | ||||
|  | ||||
|   <!-- 状态监控动画 --> | ||||
|   <view class="monitoring-box"> | ||||
|     <image src="/images/radar.png" class="radar-icon"></image> | ||||
|     <text>机器人状态持续监控中...</text> | ||||
|     <text class="update-time">{{lastUpdateTimeText}}</text> | ||||
|   </view> | ||||
|  | ||||
|   <!-- 加载状态 --> | ||||
|   <view class="loading-box" wx:if="{{loading}}"> | ||||
|     <image src="/images/loading.png" class="loading-icon"></image> | ||||
|     <text>数据加载中...</text> | ||||
|   </view> | ||||
|  | ||||
|   <!-- 错误状态 --> | ||||
|   <view class="error-box" wx:if="{{error}}"> | ||||
|     <text>{{error}}</text> | ||||
|     <button class="retry-btn" bindtap="loadBotData">重新加载</button> | ||||
|   </view> | ||||
|  | ||||
|   <!-- 机器人列表 --> | ||||
|   <scroll-view  | ||||
|     scroll-y  | ||||
|     class="bot-list"  | ||||
|     wx:if="{{!loading && !error}}" | ||||
|     refresher-enabled="{{true}}" | ||||
|     refresher-triggered="{{refreshing}}" | ||||
|     bindrefresherrefresh="onPullRefresh"> | ||||
|     <view class="bot-list-inner"> | ||||
|       <view class="bot-item {{item.selected ? 'selected' : ''}}"  | ||||
|             wx:for="{{botList}}"  | ||||
|             wx:key="wxid" | ||||
|             bindtap="selectBot" | ||||
|             data-bot="{{item}}"> | ||||
|         <view class="status-indicator {{item.status}}"></view> | ||||
|         <view class="bot-info"> | ||||
|           <text class="bot-account">{{item.account}}</text> | ||||
|           <text class="bot-status">{{statusText[item.status]}}</text> | ||||
|           <text class="bot-update">最后检测: {{item.last_check}}</text> | ||||
|         </view> | ||||
|         <view class="action-buttons"> | ||||
|           <button  | ||||
|             class="btn copy-btn"  | ||||
|             catchtap="copyAccount"  | ||||
|             data-account="{{item.account}}"> | ||||
|             复制微信号 | ||||
|           </button> | ||||
|           <button  | ||||
|             class="btn qrcode-btn"  | ||||
|             catchtap="showQrcode"  | ||||
|             data-index="{{index}}"> | ||||
|             查看二维码 | ||||
|           </button> | ||||
|         </view> | ||||
|       </view> | ||||
|     </view> | ||||
|   </scroll-view> | ||||
|  | ||||
|   <!-- 二维码弹窗 --> | ||||
|   <view class="qr-modal {{showQrModal ? 'show' : ''}}" bindtap="closeQrcode"> | ||||
|   <view class="modal-container" catchtap="preventBubble"> | ||||
|     <view class="modal-header"> | ||||
|       <text class="modal-title">{{selectedBot.account}}</text> | ||||
|       <view class="close-btn" bindtap="closeQrcode">×</view> | ||||
|     </view> | ||||
|     <view class="modal-content"> | ||||
|       <image  | ||||
|         src="{{selectedBot.qrcode_url}}"  | ||||
|         mode="widthFix"  | ||||
|         class="qrcode-image" | ||||
|         binderror="handleImageError"> | ||||
|       </image> | ||||
|     </view> | ||||
|     <view class="modal-footer"> | ||||
|       <button class="save-btn" bindtap="saveQrcode">保存到相册</button> | ||||
|     </view> | ||||
|   </view> | ||||
| </view> | ||||
| </view> | ||||
							
								
								
									
										317
									
								
								pages/bot-list/bot-list.wxss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										317
									
								
								pages/bot-list/bot-list.wxss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,317 @@ | ||||
| /* pages/bot-list/bot-list.wxss */ | ||||
|  | ||||
| .container { | ||||
|   padding: 24rpx; | ||||
|   min-height: 100vh; | ||||
|   background: linear-gradient(135deg, #f5f7fa 0%, #e4e8ed 100%); | ||||
| } | ||||
|  | ||||
| /* 功能介绍区域 */ | ||||
| .guide-box { | ||||
|   background: white; | ||||
|   border-radius: 16rpx; | ||||
|   padding: 32rpx; | ||||
|   margin-bottom: 24rpx; | ||||
|   box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05); | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   animation: slideIn 0.5s ease-out; | ||||
| } | ||||
|  | ||||
| .guide-icon { | ||||
|   width: 80rpx; | ||||
|   height: 80rpx; | ||||
|   margin-right: 24rpx; | ||||
| } | ||||
|  | ||||
| .guide-text { | ||||
|   font-size: 28rpx; | ||||
|   color: #333; | ||||
|   line-height: 1.6; | ||||
| } | ||||
|  | ||||
| /* 状态监控动画 */ | ||||
| .monitoring-box { | ||||
|   background: rgba(255, 255, 255, 0.9); | ||||
|   border-radius: 12rpx; | ||||
|   padding: 16rpx 24rpx; | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   margin-bottom: 24rpx; | ||||
|   box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05); | ||||
| } | ||||
|  | ||||
| .radar-icon { | ||||
|   width: 40rpx; | ||||
|   height: 40rpx; | ||||
|   margin-right: 16rpx; | ||||
|   animation: rotate 2s linear infinite; | ||||
| } | ||||
|  | ||||
| @keyframes rotate { | ||||
|   from { transform: rotate(0deg); } | ||||
|   to { transform: rotate(360deg); } | ||||
| } | ||||
|  | ||||
| /* 加载状态 */ | ||||
| .loading-box { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   align-items: center; | ||||
|   padding: 48rpx 0; | ||||
| } | ||||
|  | ||||
| .loading-icon { | ||||
|   width: 80rpx; | ||||
|   height: 80rpx; | ||||
|   margin-bottom: 16rpx; | ||||
|   animation: pulse 1.5s ease-in-out infinite; | ||||
| } | ||||
|  | ||||
| @keyframes pulse { | ||||
|   0% { transform: scale(0.95); } | ||||
|   50% { transform: scale(1.05); } | ||||
|   100% { transform: scale(0.95); } | ||||
| } | ||||
|  | ||||
| /* 错误状态 */ | ||||
| .error-box { | ||||
|   text-align: center; | ||||
|   padding: 48rpx 24rpx; | ||||
|   color: #ff4d4f; | ||||
| } | ||||
|  | ||||
| .retry-btn { | ||||
|   margin-top: 24rpx; | ||||
|   background: #1890ff; | ||||
|   color: white; | ||||
|   border-radius: 8rpx; | ||||
|   font-size: 28rpx; | ||||
|   padding: 16rpx 32rpx; | ||||
| } | ||||
|  | ||||
| /* 机器人列表 */ | ||||
| .bot-list { | ||||
|   max-height: calc(100vh - 300rpx); | ||||
| } | ||||
|  | ||||
| .bot-item { | ||||
|   background: white; | ||||
|   border-radius: 12rpx; | ||||
|   padding: 24rpx; | ||||
|   margin-bottom: 16rpx; | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   transition: transform 0.2s ease; | ||||
|   box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05); | ||||
| } | ||||
|  | ||||
| .bot-item:active { | ||||
|   transform: scale(0.98); | ||||
| } | ||||
|  | ||||
| .status-indicator { | ||||
|   width: 16rpx; | ||||
|   height: 16rpx; | ||||
|   border-radius: 50%; | ||||
|   margin-right: 16rpx; | ||||
| } | ||||
|  | ||||
| .status-indicator.normal { | ||||
|   background: #52c41a; | ||||
|   box-shadow: 0 0 12rpx rgba(82, 196, 26, 0.4); | ||||
| } | ||||
|  | ||||
| .status-indicator.abnormal { | ||||
|   background: #ff4d4f; | ||||
|   box-shadow: 0 0 12rpx rgba(255, 77, 79, 0.4); | ||||
| } | ||||
|  | ||||
| .status-indicator.full { | ||||
|   background: #faad14; | ||||
|   box-shadow: 0 0 12rpx rgba(250, 173, 20, 0.4); | ||||
| } | ||||
|  | ||||
| .bot-info { | ||||
|   flex: 1; | ||||
| } | ||||
|  | ||||
| .bot-account { | ||||
|   font-size: 32rpx; | ||||
|   font-weight: 500; | ||||
|   color: #333; | ||||
|   display: block; | ||||
| } | ||||
|  | ||||
| .bot-status { | ||||
|   font-size: 24rpx; | ||||
|   color: #666; | ||||
|   margin-top: 8rpx; | ||||
|   display: block; | ||||
| } | ||||
|  | ||||
| .bot-update { | ||||
|   font-size: 22rpx; | ||||
|   color: #999; | ||||
|   margin-top: 4rpx; | ||||
|   display: block; | ||||
| } | ||||
|  | ||||
| .action-buttons { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   gap: 12rpx; | ||||
| } | ||||
|  | ||||
| .btn { | ||||
|   font-size: 24rpx; | ||||
|   padding: 12rpx 24rpx; | ||||
|   border-radius: 6rpx; | ||||
|   border: none; | ||||
| } | ||||
|  | ||||
| .copy-btn { | ||||
|   background: #e6f7ff; | ||||
|   color: #1890ff; | ||||
| } | ||||
|  | ||||
| .qrcode-btn { | ||||
|   background: #f6ffed; | ||||
|   color: #52c41a; | ||||
| } | ||||
|  | ||||
| /* 二维码弹窗 */ | ||||
| /* pages/bot-list/bot-list.wxss */ | ||||
| /* 添加或更新以下样式 */ | ||||
|  | ||||
| .qr-modal { | ||||
|   position: fixed; | ||||
|   top: 0; | ||||
|   left: 0; | ||||
|   right: 0; | ||||
|   bottom: 0; | ||||
|   background-color: rgba(0, 0, 0, 0.6); | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   justify-content: center; | ||||
|   opacity: 0; | ||||
|   visibility: hidden; | ||||
|   transition: all 0.3s ease; | ||||
|   z-index: 999; | ||||
| } | ||||
|  | ||||
| .qr-modal.show { | ||||
|   opacity: 1; | ||||
|   visibility: visible; | ||||
| } | ||||
|  | ||||
| .modal-container { | ||||
|   width: 90%; | ||||
|   background: white; | ||||
|   border-radius: 12rpx; | ||||
|   transform: translateY(50rpx); | ||||
|   opacity: 0; | ||||
|   transition: all 0.3s ease; | ||||
| } | ||||
|  | ||||
| .qr-modal.show .modal-container { | ||||
|   transform: translateY(0); | ||||
|   opacity: 1; | ||||
| } | ||||
|  | ||||
| .modal-header { | ||||
|   padding: 24rpx; | ||||
|   border-bottom: 1px solid #eee; | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   align-items: center; | ||||
| } | ||||
|  | ||||
| .modal-title { | ||||
|   font-size: 32rpx; | ||||
|   font-weight: 500; | ||||
|   color: #333; | ||||
| } | ||||
|  | ||||
| .close-btn { | ||||
|   width: 64rpx; | ||||
|   height: 64rpx; | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   justify-content: center; | ||||
|   font-size: 40rpx; | ||||
|   color: #999; | ||||
|   cursor: pointer; | ||||
| } | ||||
|  | ||||
| .modal-content { | ||||
|   padding: 32rpx; | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   align-items: center; | ||||
| } | ||||
|  | ||||
| .qrcode-image { | ||||
|   width: 100%; | ||||
|   height: auto; | ||||
|   max-width: 500rpx; | ||||
|   margin: 0 auto; | ||||
| } | ||||
|  | ||||
| .tip-text { | ||||
|   margin-top: 24rpx; | ||||
|   font-size: 26rpx; | ||||
|   color: #666; | ||||
| } | ||||
|  | ||||
| .modal-footer { | ||||
|   padding: 24rpx; | ||||
|   border-top: 1px solid #eee; | ||||
|   display: flex; | ||||
|   justify-content: center; | ||||
| } | ||||
|  | ||||
| .save-btn { | ||||
|   background: #07C160; | ||||
|   color: white; | ||||
|   font-size: 28rpx; | ||||
|   padding: 16rpx 48rpx; | ||||
|   border-radius: 8rpx; | ||||
|   border: none; | ||||
|   width: 80%; | ||||
| } | ||||
|  | ||||
| .save-btn:active { | ||||
|   opacity: 0.9; | ||||
| } | ||||
|  | ||||
| @keyframes slideIn { | ||||
|   from { | ||||
|     opacity: 0; | ||||
|     transform: translateY(20rpx); | ||||
|   } | ||||
|   to { | ||||
|     opacity: 1; | ||||
|     transform: translateY(0); | ||||
|   } | ||||
| } | ||||
|  | ||||
| /* 添加响应式设计 */ | ||||
| @media screen and (max-width: 375px) { | ||||
|   .container { | ||||
|     padding: 16rpx; | ||||
|   } | ||||
|    | ||||
|   .bot-item { | ||||
|     padding: 16rpx; | ||||
|   } | ||||
|    | ||||
|   .action-buttons { | ||||
|     gap: 8rpx; | ||||
|   } | ||||
|    | ||||
|   .btn { | ||||
|     padding: 8rpx 16rpx; | ||||
|     font-size: 22rpx; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										11
									
								
								pages/business_cooperation/business_cooperation.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								pages/business_cooperation/business_cooperation.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| Page({ | ||||
|     data: {}, | ||||
|     onLoad: function(n) {}, | ||||
|     onReady: function() {}, | ||||
|     onShow: function() {}, | ||||
|     onHide: function() {}, | ||||
|     onUnload: function() {}, | ||||
|     onPullDownRefresh: function() {}, | ||||
|     onReachBottom: function() {}, | ||||
|     onShareAppMessage: function() {} | ||||
| }); | ||||
							
								
								
									
										7
									
								
								pages/business_cooperation/business_cooperation.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								pages/business_cooperation/business_cooperation.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| { | ||||
|     "navigationBarTitleText": "商业合作", | ||||
|     "navigationBarBackgroundColor": "#222238", | ||||
|     "navigationBarTextStyle": "white", | ||||
|     "component": true, | ||||
|     "usingComponents": {} | ||||
| } | ||||
							
								
								
									
										1
									
								
								pages/business_cooperation/business_cooperation.wxml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								pages/business_cooperation/business_cooperation.wxml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| <image class="qrcode" src="https://file.guimiaokeji.com/1.png"></image> | ||||
							
								
								
									
										9
									
								
								pages/business_cooperation/business_cooperation.wxss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								pages/business_cooperation/business_cooperation.wxss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| view { | ||||
|     margin: 0; | ||||
|     padding: 0; | ||||
| } | ||||
|  | ||||
| .qrcode { | ||||
|     height: 100vh; | ||||
|     width: 100%; | ||||
| } | ||||
							
								
								
									
										245
									
								
								pages/details/details.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										245
									
								
								pages/details/details.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,245 @@ | ||||
| var app = getApp(); | ||||
|  | ||||
| Page({ | ||||
|   data: { | ||||
|     currentPath: '', // 当前路径 | ||||
|     breadcrumbPath: '', // 上一级路径 | ||||
|     currentItems: [], // 当前目录内容 | ||||
|     hasMore: false, // 是否有更多数据 | ||||
|     showQRPopup: false, // 控制二维码弹窗显示 | ||||
|     popupAnimation: {}, // 弹窗动画 | ||||
|     page: 1, // 当前页码 | ||||
|     pageSize: 20, // 每页大小 | ||||
|     isRoot: true, // 是否是根目录 | ||||
|     qrcodeUrl: 'https://file.guimiaokeji.com/%E5%B9%BF%E5%91%8A/C55BDC06151A606BDAEBCF787283874E.jpg', // 二维码图片链接 | ||||
|   }, | ||||
|  | ||||
|   onLoad() { | ||||
|  | ||||
|     wx.showShareMenu({ | ||||
|       withShareTicket: !0, | ||||
|       menus: [ "shareAppMessage", "shareTimeline" ] | ||||
|   }); | ||||
|   }, | ||||
|   showVip(){ | ||||
|     wx.navigateTo({ | ||||
|       url: "../vip_recharge/vip_recharge?show=true" | ||||
|     }) | ||||
|   } | ||||
|   , | ||||
|   // 默认加载第一个目录 | ||||
|   loadDefaultDirectory() { | ||||
|     wx.showLoading({ title: '加载中...' }); | ||||
|  | ||||
|     app.apiRequest({ | ||||
|       url: '/api/courses/', | ||||
|       method: 'GET', | ||||
|       data: { | ||||
|         path: '/', // 根路径 | ||||
|         page_num: 1, | ||||
|         page_size: 1, // 仅获取第一个目录 | ||||
|       }, | ||||
|       success: (res) => { | ||||
|         if (res.data.status === 'success') { | ||||
|           const firstItem = res.data.data.files[0]; | ||||
|  | ||||
|           if (firstItem && firstItem.type === 1) { | ||||
|             // 如果第一个项目是目录,加载该目录 | ||||
|             this.loadDirectory(`/${firstItem.name}`); | ||||
|           } else { | ||||
|             wx.showToast({ title: '没有可用的目录', icon: 'none' }); | ||||
|           } | ||||
|         } else { | ||||
|           wx.showToast({ title: '获取数据失败', icon: 'none' }); | ||||
|         } | ||||
|       }, | ||||
|       fail: (err) => { | ||||
|         wx.showToast({ title: '加载失败,请重试', icon: 'none' }); | ||||
|         console.error(err); | ||||
|       }, | ||||
|       complete: () => wx.hideLoading(), | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   // 加载指定目录内容 | ||||
|   loadDirectory(path, append = false) { | ||||
|     wx.showLoading({ title: '加载中...' }); | ||||
|  | ||||
|     // 确保路径不会出现多个斜杠 | ||||
|     const sanitizedPath = path.replace(/\/+/g, '/'); | ||||
|  | ||||
|     app.apiRequest({ | ||||
|       url: '/api/courses/', | ||||
|       method: 'GET', | ||||
|       data: { | ||||
|         path: sanitizedPath, | ||||
|         page_num: this.data.page, | ||||
|         page_size: this.data.pageSize, | ||||
|       }, | ||||
|       success: (res) => { | ||||
|         if (res.data.status === 'success') { | ||||
|           const newItems = res.data.data.files.map((item) => ({ | ||||
|             ...item, | ||||
|             path: `${sanitizedPath}/${item.name}`, | ||||
|           })); | ||||
|  | ||||
|           const paths = sanitizedPath.split('/').filter(Boolean); | ||||
|           const breadcrumbPath = paths.slice(0, -1).join('/') || '/'; | ||||
|  | ||||
|           this.setData({ | ||||
|             currentItems: append ? this.data.currentItems.concat(newItems) : newItems, | ||||
|             currentPath: sanitizedPath, | ||||
|             breadcrumbPath, | ||||
|             hasMore: newItems.length === this.data.pageSize, | ||||
|             isRoot: sanitizedPath === '/', // 根目录判断 | ||||
|           }); | ||||
|         } else { | ||||
|           wx.showToast({ title: '获取数据失败', icon: 'none' }); | ||||
|         } | ||||
|       }, | ||||
|       fail: (err) => { | ||||
|         wx.showToast({ title: '加载失败,请重试', icon: 'none' }); | ||||
|         console.error(err); | ||||
|       }, | ||||
|       complete: () => wx.hideLoading(), | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   // 点击目录或文件 | ||||
|   handleItemClick(e) { | ||||
|     const { type, path } = e.currentTarget.dataset; | ||||
|  | ||||
|     if (type === 1) { // 目录 | ||||
|       this.setData({ page: 1 }); | ||||
|       this.loadDirectory(path); | ||||
|     } else if (type === 0) { // 文件 | ||||
|       this.setData({ | ||||
|         qrcodeUrl: this.data.qrcodeUrl, // 假设文件路径作为二维码图片链接 | ||||
|       }); | ||||
|       this.showQRCode(); | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   // 返回上级目录 | ||||
|   goToParent() { | ||||
|     const paths = this.data.currentPath.split('/').filter(Boolean); | ||||
|     paths.pop(); | ||||
|     const parentPath = '/' + paths.join('/'); | ||||
|  | ||||
|     this.setData({ page: 1 }); | ||||
|     this.loadDirectory(parentPath); | ||||
|   }, | ||||
|  | ||||
|   // 加载更多 | ||||
|   loadMore() { | ||||
|     if (!this.data.hasMore) return; | ||||
|  | ||||
|     this.setData({ page: this.data.page + 1 }); | ||||
|     this.loadDirectory(this.data.currentPath, true); | ||||
|   }, | ||||
|  | ||||
|   // 显示二维码弹窗 | ||||
|   showQRCode() { | ||||
|     this.setData({ showQRPopup: true }); | ||||
|     const animation = wx.createAnimation({ | ||||
|       duration: 300, | ||||
|       timingFunction: 'ease', | ||||
|     }); | ||||
|     animation.scale(1).opacity(1).step(); | ||||
|     this.setData({ popupAnimation: animation.export() }); | ||||
|   }, | ||||
|  | ||||
|   // 关闭二维码弹窗 | ||||
|   closeQRCode() { | ||||
|     const animation = wx.createAnimation({ | ||||
|       duration: 300, | ||||
|       timingFunction: 'ease', | ||||
|     }); | ||||
|     animation.scale(0.8).opacity(0).step(); | ||||
|     this.setData({ popupAnimation: animation.export() }); | ||||
|  | ||||
|     setTimeout(() => { | ||||
|       this.setData({ showQRPopup: false }); | ||||
|     }, 300); | ||||
|   }, | ||||
|  | ||||
|   // 防止点击弹窗内部关闭弹窗 | ||||
|   preventClose() { | ||||
|     // 空函数,阻止事件冒泡 | ||||
|   }, | ||||
|  | ||||
|   // 保存二维码到相册 | ||||
|   saveQRCode() { | ||||
|     const { qrcodeUrl } = this.data; | ||||
|  | ||||
|     wx.showLoading({ title: '正在保存...' }); | ||||
|  | ||||
|     wx.downloadFile({ | ||||
|       url: qrcodeUrl, | ||||
|       success: (res) => { | ||||
|         if (res.statusCode === 200) { | ||||
|           wx.saveImageToPhotosAlbum({ | ||||
|             filePath: res.tempFilePath, | ||||
|             success: () => { | ||||
|               wx.showToast({ title: '二维码已保存', icon: 'success' }); | ||||
|             }, | ||||
|             fail: (err) => { | ||||
|               wx.showToast({ title: '保存失败,请重试', icon: 'none' }); | ||||
|               console.error(err); | ||||
|             }, | ||||
|           }); | ||||
|         } | ||||
|       }, | ||||
|       fail: (err) => { | ||||
|         wx.showToast({ title: '下载失败,请重试', icon: 'none' }); | ||||
|         console.error(err); | ||||
|       }, | ||||
|       complete: () => wx.hideLoading(), | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|    | ||||
|   onShareAppMessage: function () { | ||||
|     return { | ||||
|       title: '分享给你一份全链路的自媒体课程,赶快来领取吧', | ||||
|       path: '/pages/details/details?uuid=' + wx.getStorageSync('uuid'), | ||||
|       imageUrl: 'https://file.guimiaokeji.com/kecheng.png', | ||||
|       success: function (e) { | ||||
|         wx.showToast({ | ||||
|           title: "分享成功", | ||||
|           icon: "success", | ||||
|           duration: 2e3 | ||||
|         }); | ||||
|       }, | ||||
|       fail: function (e) { | ||||
|         wx.showToast({ | ||||
|           title: "分享失败", | ||||
|           icon: "none", | ||||
|           duration: 2e3 | ||||
|         }); | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   onShareTimeline: function () { | ||||
|     return { | ||||
|       title: '分享给你一份全链路的自媒体课程,赶快来领取吧', | ||||
|       path: '/pages/details/details?uuid=' + wx.getStorageSync('uuid'), | ||||
|       imageUrl: 'https://file.guimiaokeji.com/kecheng.png', | ||||
|       success: function (e) { | ||||
|         wx.showToast({ | ||||
|           title: "分享成功", | ||||
|           icon: "success", | ||||
|           duration: 2e3 | ||||
|         }); | ||||
|       }, | ||||
|       fail: function (e) { | ||||
|         wx.showToast({ | ||||
|           title: "分享失败", | ||||
|           icon: "none", | ||||
|           duration: 2e3 | ||||
|         }); | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|  | ||||
| }); | ||||
							
								
								
									
										9
									
								
								pages/details/details.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								pages/details/details.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "usingComponents": { | ||||
|     "popup": "/popup/popup" | ||||
|   }, | ||||
|   "navigationBarTitleText": "创意启航站", | ||||
|   "navigationBarBackgroundColor": "#222238", | ||||
|   "navigationBarTextStyle": "white" | ||||
|    | ||||
| } | ||||
							
								
								
									
										39
									
								
								pages/details/details.wxml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								pages/details/details.wxml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| <view class="course-detail-container"> | ||||
|   <!-- 课程介绍 --> | ||||
|   <view class="course-intro"> | ||||
|     <view class="intro-title">📚 精品资源分享</view> | ||||
|     <text class="intro-description"> | ||||
|   - 🎁 价值上万的*学习资源*,让你轻松打造高质量作品 | ||||
|   - 🛠️ 实用*免费视频剪辑工具和AI创作资料*,提高创作效率 | ||||
|   - 💡 专业的*平台算法解析*和实战技巧,让你少走弯路 | ||||
|   - 🔔 现在仅需 ¥29 即可获得一份精品课程 | ||||
|   - 🩸 现在仅需 ¥599 即可获得代理资格,拥有创意站分销权限和所有课程分销和免费看 | ||||
|     </text> | ||||
|   </view> | ||||
|  | ||||
|  | ||||
|  | ||||
|   <!-- 功能按钮 --> | ||||
|   <view class="action-buttons"> | ||||
|     <view class="button-row"> | ||||
|       <button class="action-btn green-btn" bindtap="showQRCode">🎁 领取课程资源</button> | ||||
|       <button class="action-btn purple-btn" bindtap="showVip">🛠️ 成为代理会员</button> | ||||
|     </view> | ||||
|     <view class="button-row"> | ||||
|       <button class="action-btn orange-btn" bindtap="showQRCode">📦 免费素材资源</button> | ||||
|       <button class="action-btn yellow-btn" bindtap="showQRCode">💡 运营专家解答</button> | ||||
|     </view> | ||||
|   </view> | ||||
|  | ||||
|   <!-- 弹出二维码弹窗 --> | ||||
|   <view wx:if="{{showQRPopup}}" class="qrcode-popup-mask" animation="{{popupAnimation}}" catchtap="closeQRCode"> | ||||
|     <view class="qrcode-popup" catchtap="preventClose"> | ||||
|       <text class="close-icon" bindtap="closeQRCode">✕</text> | ||||
|       <view class="qrcode-text"> | ||||
|         <text>📱 长按保存二维码</text> | ||||
|         <text>扫一扫领取资料</text> | ||||
|       </view> | ||||
|       <image class="qrcode-img" src="{{qrcodeUrl}}" mode="aspectFit" bindlongtap="saveQRCode"></image> | ||||
|     </view> | ||||
|   </view> | ||||
| </view> | ||||
							
								
								
									
										208
									
								
								pages/details/details.wxss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								pages/details/details.wxss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,208 @@ | ||||
| /* 页面整体样式 */ | ||||
| page { | ||||
|   background-color: #222238; | ||||
|   border-top: 1px solid hsla(0,31%,87%,.5); | ||||
|   font-size: 32rpx; | ||||
|   line-height: 1.6; | ||||
| } | ||||
| /* 页面整体样式 */ | ||||
| .course-detail-container { | ||||
|   padding: 20rpx; | ||||
|   background-color: #1a1d3b; | ||||
|   color: #fff; | ||||
| } | ||||
|  | ||||
| /* 课程介绍 */ | ||||
| .course-intro { | ||||
|   margin-bottom: 40rpx; | ||||
| } | ||||
|  | ||||
| .intro-title { | ||||
|   font-size: 36rpx; | ||||
|   font-weight: bold; | ||||
|   color: #ffcc00; | ||||
|   margin-bottom: 20rpx; | ||||
|   text-align: center; | ||||
|   margin: 0 auto; | ||||
| } | ||||
|  | ||||
| .intro-description { | ||||
|   font-size: 28rpx; | ||||
|   line-height: 1.6; | ||||
|   color: #ccc; | ||||
| } | ||||
|  | ||||
| /* 两张图片并排展示 */ | ||||
| /* 整体背景 */ | ||||
| .file-browser { | ||||
|   padding: 20rpx; | ||||
|   background-color: #1a1d3b; | ||||
|   color: #fff; | ||||
|   height: 100vh; | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
| } | ||||
|  | ||||
| /* 头部:返回按钮和路径 */ | ||||
| .header { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   margin-bottom: 20rpx; | ||||
|   background-color: #2a2e50; | ||||
|   padding: 10rpx; | ||||
|   border-radius: 10rpx; | ||||
|   box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.2); | ||||
| } | ||||
|  | ||||
| .back-icon { | ||||
|   width: 40rpx; | ||||
|   height: 40rpx; | ||||
|   margin-right: 10rpx; | ||||
| } | ||||
|  | ||||
| .breadcrumb-path { | ||||
|   font-size: 28rpx; | ||||
|   color: #ccc; | ||||
|   white-space: nowrap; | ||||
|   overflow: hidden; | ||||
|   text-overflow: ellipsis; | ||||
|   flex: 1; | ||||
| } | ||||
|  | ||||
| /* 文件和目录列表 */ | ||||
| .file-list { | ||||
|   flex: 1; | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   gap: 20rpx; | ||||
|   overflow-y: scroll; | ||||
| } | ||||
|  | ||||
| .file-list-root { | ||||
|   height: auto; /* 根目录时内容高度自适应 */ | ||||
| } | ||||
|  | ||||
| .file-card { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   padding: 20rpx; | ||||
|   background-color: #2a2e50; | ||||
|   border-radius: 10rpx; | ||||
|   border-bottom: 1px solid #fff; | ||||
|   box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.2); | ||||
|    | ||||
| } | ||||
|  | ||||
| .file-icon { | ||||
|   width: 60rpx; | ||||
|   height: 60rpx; | ||||
|   margin-right: 20rpx; | ||||
| } | ||||
|  | ||||
| .file-info { | ||||
|   flex: 1; | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   gap: 10rpx; | ||||
|   white-space: nowrap; | ||||
|   overflow: hidden; | ||||
|   text-overflow: ellipsis; /* 长文字处理 */ | ||||
|   max-width: 80%; /* 确保图标不被挤掉 */ | ||||
| } | ||||
|  | ||||
| .file-name { | ||||
|   font-size: 28rpx; | ||||
|   color: #fff; | ||||
|   white-space: nowrap; | ||||
|   overflow: hidden; | ||||
|   text-overflow: ellipsis; /* 长文字处理 */ | ||||
|   max-width: 80%; /* 确保图标不被挤掉 */ | ||||
| } | ||||
|  | ||||
| .file-updated { | ||||
|   font-size: 24rpx; | ||||
|   color: #aaa; | ||||
| } | ||||
|  | ||||
| .load-more { | ||||
|   text-align: center; | ||||
|   color: #aaa; | ||||
|   padding: 20rpx 0; | ||||
|   font-size: 13px; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* 功能按钮两行布局 */ | ||||
| .action-buttons { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   margin-bottom: 40rpx; | ||||
| } | ||||
|  | ||||
| .button-row { | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   margin-bottom: 20rpx; | ||||
| } | ||||
|  | ||||
| .action-btn { | ||||
|   width: 48%; | ||||
|   font-size: 28rpx; | ||||
|   padding: 20rpx 0; | ||||
|   color: #fff; | ||||
|   text-align: center; | ||||
|   border-radius: 10rpx; | ||||
| } | ||||
|  | ||||
| .green-btn { background-color: #28a745; } | ||||
| .purple-btn { background-color: #6f42c1; } | ||||
| .orange-btn { background-color: #fd7e14; } | ||||
| .yellow-btn { background-color: #ffc107; } | ||||
|  | ||||
| /* 弹窗样式 */ | ||||
| .qrcode-popup-mask { | ||||
|   position: fixed; | ||||
|   top: 0; | ||||
|   left: 0; | ||||
|   width: 100%; | ||||
|   height: 100%; | ||||
|   background: rgba(0, 0, 0, 0.6); | ||||
|   z-index: 999; | ||||
|   display: flex; | ||||
|   justify-content: center; | ||||
|   align-items: center; | ||||
| } | ||||
|  | ||||
| .qrcode-popup { | ||||
|   background: rgba(255, 255, 255, 0.9); | ||||
|   padding: 40rpx; | ||||
|   border-radius: 20rpx; | ||||
|   text-align: center; | ||||
|   position: relative; | ||||
|   animation: fadeIn 0.3s ease-in-out; | ||||
| } | ||||
|  | ||||
| .close-icon { | ||||
|   position: absolute; | ||||
|   top: 20rpx; | ||||
|   right: 20rpx; | ||||
|   font-size: 36rpx; | ||||
|   color: #666; | ||||
| } | ||||
|  | ||||
| .qrcode-text { | ||||
|   font-size: 28rpx; | ||||
|   color: #333; | ||||
|   margin-bottom: 20rpx; | ||||
| } | ||||
|  | ||||
| .qrcode-text text { | ||||
|   display: block; | ||||
| } | ||||
|  | ||||
| .qrcode-img { | ||||
|   width: 500rpx; | ||||
|   height: 500rpx; | ||||
|   margin: 20rpx auto; | ||||
|   border-radius: 10rpx; | ||||
| } | ||||
							
								
								
									
										182
									
								
								pages/extract/extract.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										182
									
								
								pages/extract/extract.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,182 @@ | ||||
| var util = require('../../utils/util.js'); // 确保你有这样一个文件 | ||||
|  | ||||
| var e = getApp(); | ||||
|  | ||||
| Page({ | ||||
|     data: { | ||||
|         text: "", | ||||
|         type: "", | ||||
|         wxid: "", | ||||
|         alias: "", | ||||
|         uuid: "", | ||||
|         openid: "" | ||||
|     }, | ||||
|     onLoad: function(e) { | ||||
|         wx.showShareMenu({ | ||||
|             withShareTicket: !0, | ||||
|             menus: [ "shareAppMessage", "shareTimeline" ] | ||||
|         }), this.setData({ | ||||
|             text: decodeURIComponent(e.text), | ||||
|             type: decodeURIComponent(e.type) || "", | ||||
|             wxid: decodeURIComponent(e.wxid) || "", | ||||
|             alias: decodeURIComponent(e.alias) || "" | ||||
|         }); | ||||
|     }, | ||||
|     copyText: function() { | ||||
|         wx.setClipboardData({ | ||||
|             success: function() { | ||||
|                 wx.showToast({ | ||||
|                     title: "复制成功", | ||||
|                     duration: 1200 | ||||
|                 }); | ||||
|             }, | ||||
|             data: this.data.text | ||||
|         }); | ||||
|     }, | ||||
|     onAdClick: function() { | ||||
|         e.广告(); | ||||
|     }, | ||||
|     rewriteText: function() { | ||||
|         if (console.log(wx.getStorageSync("defaultDailyFreeParseNum")), wx.getStorageSync("defaultDailyFreeParseNum") > 0 || wx.getStorageSync("isMember")) { | ||||
|             var t = this; | ||||
|             wx.showLoading({ | ||||
|                 title: "ai改写中..." | ||||
|             }), e.apiRequest({ | ||||
|                 url: "/myapp/rewrite_text/", | ||||
|                 method: "POST", | ||||
|                 data: { | ||||
|                     text: this.data.text, | ||||
|                     uuid: wx.getStorageSync("uuid"), | ||||
|                     openid: wx.getStorageSync("openid"), | ||||
|                     type: this.data.type || "", | ||||
|                     wxid: this.data.wxid || "", | ||||
|                     alias: this.data.alias || "" | ||||
|                 }, | ||||
|                 success: function(e) { | ||||
|                     wx.hideLoading(), "success" === e.data.status ? ( | ||||
|                       t.setData({ | ||||
|                         text: e.data.rewritten_text | ||||
|                     }),  | ||||
|                     wx.showToast({ | ||||
|                         title: "改写完成", | ||||
|                         icon: "success", | ||||
|                         duration: 2e3 | ||||
|                     }) | ||||
|                     ) : "次数不足或不是会员" == e.data.error ? wx.showModal({ | ||||
|                         title: "提示", | ||||
|                         content: "已无体验次数,前往个人中心领取或开通会员", | ||||
|                         confirmColor: "#00B269", | ||||
|                         cancelColor: "#858585", | ||||
|                         success: function(e) { | ||||
|                             e.confirm ? (console.log("确定"), wx.navigateTo({ | ||||
|                                 url: "../vip_recharge/vip_recharge?show=true" | ||||
|                             })) : e.cancel && console.log("取消"); | ||||
|                         } | ||||
|                     }) : wx.showToast({ | ||||
|                         title: e.data.error, | ||||
|                         icon: "none", | ||||
|                         duration: 2e3 | ||||
|                     }); | ||||
|                 }, | ||||
|                 fail: function(e) { | ||||
|                     console.error("改写请求失败", e), wx.hideLoading(), wx.showToast({ | ||||
|                         title: "请求出错", | ||||
|                         icon: "none", | ||||
|                         duration: 2e3 | ||||
|                     }); | ||||
|                 } | ||||
|             }); | ||||
|         } else wx.showToast({ | ||||
|             title: "免费次数已用完!", | ||||
|             icon: "none" | ||||
|         }), wx.showModal({ | ||||
|             title: "提示", | ||||
|             content: "已无体验次数,前往个人中心领取或开通会员", | ||||
|             confirmColor: "#00B269", | ||||
|             cancelColor: "#858585", | ||||
|             success: function(e) { | ||||
|                 e.confirm ? (console.log("确定"), wx.navigateTo({ | ||||
|                     url: "../vip_recharge/vip_recharge?show=true" | ||||
|                 })) : e.cancel && console.log("取消"); | ||||
|             } | ||||
|         }); | ||||
|     }, | ||||
|     saveCopywriting: function() { | ||||
|         e.apiRequest({ | ||||
|             url: "/myapp/create_copywriting/", | ||||
|             method: "POST", | ||||
|             data: { | ||||
|                 text_content: this.data.text, | ||||
|                 uuid: wx.getStorageSync("uuid") || "", | ||||
|                 openid: wx.getStorageSync("openid") || "", | ||||
|                 source: this.data.type || "", | ||||
|                 tag: this.data.wxid || "", | ||||
|                 type: this.data.type || "", | ||||
|                 wxid: this.data.wxid || "", | ||||
|                 alias: this.data.alias || "" | ||||
|             }, | ||||
|             success: function(e) { | ||||
|                 console.log(e); | ||||
|             }, | ||||
|             fail: function(e) { | ||||
|                 console.error("请求失败:", e); | ||||
|             } | ||||
|         }); | ||||
|     }, | ||||
|     onReady: function() {}, | ||||
|     onShow: function() {  | ||||
|         e.checkUpdateVersion(), wx.showLoading(), e.getUserInfo().then(function() { | ||||
|             console.log("获取用户开始"), console.log("获取用户结束"); | ||||
|         }).catch(function(e) { | ||||
|             console.error("获取用户信息失败:", e); | ||||
|         }).finally(function() { | ||||
|             console.log("getUserInfo调用完成"); | ||||
|         }); | ||||
|     }, | ||||
|     onHide: function() {}, | ||||
|     onUnload: function() {}, | ||||
|     onPullDownRefresh: function() {}, | ||||
|     onReachBottom: function() {}, | ||||
|     onShareAppMessage: function() { | ||||
|         return { | ||||
|             title: "推荐一款免费又超好用的视频文案创作工具,分享给大家一起使用", | ||||
|             path: "/pages/index/index?uuid=" + wx.getStorageSync("uuid"), | ||||
|             imageUrl: "/images/share.jpg", | ||||
|             success: function(e) { | ||||
|                 wx.showToast({ | ||||
|                     title: "分享成功", | ||||
|                     icon: "success", | ||||
|                     duration: 2e3 | ||||
|                 }); | ||||
|             }, | ||||
|             fail: function(e) { | ||||
|                 wx.showToast({ | ||||
|                     title: "分享失败", | ||||
|                     icon: "none", | ||||
|                     duration: 2e3 | ||||
|                 }); | ||||
|             } | ||||
|         }; | ||||
|     }, | ||||
|     onShareTimeline: function() { | ||||
|         return { | ||||
|             title: "推荐一款免费又超好用的视频文案创作工具,分享给大家一起使用", | ||||
|             path: "/pages/index/index?uuid=" + wx.getStorageSync("uuid"), | ||||
|             imageUrl: "/images/share.jpg", | ||||
|             success: function(e) { | ||||
|                 wx.showToast({ | ||||
|                     title: "分享成功", | ||||
|                     icon: "success", | ||||
|                     duration: 2e3 | ||||
|                 }); | ||||
|             }, | ||||
|             fail: function(e) { | ||||
|                 wx.showToast({ | ||||
|                     title: "分享失败", | ||||
|                     icon: "none", | ||||
|                     duration: 2e3 | ||||
|                 }); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }); | ||||
							
								
								
									
										7
									
								
								pages/extract/extract.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								pages/extract/extract.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| { | ||||
|     "navigationBarTitleText": "文案提取", | ||||
|     "navigationBarBackgroundColor": "#222238", | ||||
|     "navigationBarTextStyle": "white", | ||||
|     "component": true, | ||||
|     "usingComponents": {} | ||||
| } | ||||
							
								
								
									
										12
									
								
								pages/extract/extract.wxml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								pages/extract/extract.wxml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| <view class="container"> | ||||
|     <textarea readonly class="extracted-text" maxlength="-1" placeholder="这里将显示提取的文案" value="{{text}}"></textarea> | ||||
|     <view class="buttons-container"> | ||||
|         <button bindtap="copyText" class="action-button copy">复制文案</button> | ||||
|         <button bindtap="rewriteText" class="action-button rewrite">AI改写</button> | ||||
|     </view> | ||||
| </view> | ||||
| <view class="center" style="color: #fff;font-size: 12px;">文字不要超出2000字哦,否则改写失败</view> | ||||
| <view class="center">版权归视频原作者和平台所有</view> | ||||
| <!-- <view bindtap="onAdClick" class="advertisement"> | ||||
|     <image src="https://file.guimiaokeji.com/kecheng.png"></image> | ||||
| </view> --> | ||||
							
								
								
									
										63
									
								
								pages/extract/extract.wxss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								pages/extract/extract.wxss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| page { | ||||
|     border-top: 1px solid hsla(0,31%,87%,.5); | ||||
| } | ||||
|  | ||||
| .container,page { | ||||
|     background-color: #222238; | ||||
| } | ||||
|  | ||||
| .container { | ||||
|     align-items: center; | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     padding: 20px; | ||||
| } | ||||
|  | ||||
| .extracted-text { | ||||
|     background-color: #333; | ||||
|     border: 1px solid #333; | ||||
|     border-radius: 8px; | ||||
|     color: #fff; | ||||
|     font-size: 16px; | ||||
|     height: 300px; | ||||
|     margin-bottom: 20px; | ||||
|     padding: 10px; | ||||
|     width: 90%; | ||||
| } | ||||
|  | ||||
| .buttons-container { | ||||
|     display: flex; | ||||
|     justify-content: space-between; | ||||
|     width: 90%; | ||||
| } | ||||
|  | ||||
| .action-button { | ||||
|     border-radius: 25px; | ||||
|     flex: 1; | ||||
|     font-size: 18px; | ||||
|     font-weight: 700; | ||||
|     height: 50px; | ||||
|     line-height: 50px; | ||||
|     margin: 0 10px; | ||||
| } | ||||
|  | ||||
| .copy,.rewrite { | ||||
|     background: linear-gradient(90deg,#6949bb,#4052ca); | ||||
|     color: #fff; | ||||
| } | ||||
|  | ||||
| .center { | ||||
|     color: #f0f0f0; | ||||
|     font-size: 12px; | ||||
|     text-align: center; | ||||
| } | ||||
|  | ||||
| .advertisement { | ||||
|     margin: 5px 0; | ||||
|     width: 100%; | ||||
|     z-index: 9999; | ||||
| } | ||||
|  | ||||
| .advertisement image { | ||||
|     width: 100%; | ||||
| } | ||||
							
								
								
									
										119
									
								
								pages/faq/faq.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								pages/faq/faq.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,119 @@ | ||||
| const n = getApp(); | ||||
| Page({ | ||||
|     data: { | ||||
|         list: null | ||||
|     }, | ||||
|     onLoad: function() { | ||||
|         wx.showShareMenu({ | ||||
|             withShareTicket: true, | ||||
|             menus: ["shareAppMessage", "shareTimeline"] | ||||
|         }); | ||||
|     }, | ||||
|     saveImage: function(e) { | ||||
|         const n = e.currentTarget.dataset.url; | ||||
|         wx.showActionSheet({ | ||||
|             itemList: ["保存图片"], | ||||
|             success: function(e) { | ||||
|                 if (e.tapIndex === 0) { | ||||
|                     wx.downloadFile({ | ||||
|                         url: n, | ||||
|                         success: function(res) { | ||||
|                             if (res.statusCode === 200) { | ||||
|                                 wx.saveImageToPhotosAlbum({ | ||||
|                                     filePath: res.tempFilePath, | ||||
|                                     success: function() { | ||||
|                                         wx.showToast({ | ||||
|                                             title: "保存成功", | ||||
|                                             icon: "success", | ||||
|                                             duration: 2000 | ||||
|                                         }); | ||||
|                                     }, | ||||
|                                     fail: function(err) { | ||||
|                                         console.log(err); | ||||
|                                         wx.showToast({ | ||||
|                                             title: "保存失败", | ||||
|                                             icon: "none", | ||||
|                                             duration: 2000 | ||||
|                                         }); | ||||
|                                     } | ||||
|                                 }); | ||||
|                             } | ||||
|                         }, | ||||
|                         fail: function(err) { | ||||
|                             console.log(err); | ||||
|                             wx.showToast({ | ||||
|                                 title: "下载失败", | ||||
|                                 icon: "none", | ||||
|                                 duration: 2000 | ||||
|                             }); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             }, | ||||
|             fail: function(err) { | ||||
|                 console.log(err); | ||||
|             } | ||||
|         }); | ||||
|     }, | ||||
|     onShow: function() { | ||||
|         const e = this; | ||||
|         n.check_status() | ||||
|             .then(function(res) { | ||||
|                 console.log("获取文章信息", res); | ||||
|                 e.setData({ | ||||
|                     list: res.data.data.list | ||||
|                 }); | ||||
|             }) | ||||
|             .catch(function(err) { | ||||
|                 console.error("获取文章信息失败:", err); | ||||
|             }) | ||||
|             .finally(function() { | ||||
|                 console.log("check_status调用完成"); | ||||
|             }); | ||||
|     }, | ||||
|     onAdClick: function() { | ||||
|       n.广告(); | ||||
|   }, | ||||
|     onShareAppMessage: function() { | ||||
|         return { | ||||
|             title: "推荐一款免费又超好用的视频文案创作工具,分享给大家一起使用", | ||||
|             path: "/pages/index/index?uuid=" + wx.getStorageSync("uuid"), | ||||
|             imageUrl: "/images/share.jpg", | ||||
|             success: function() { | ||||
|                 wx.showToast({ | ||||
|                     title: "分享成功", | ||||
|                     icon: "success", | ||||
|                     duration: 2000 | ||||
|                 }); | ||||
|             }, | ||||
|             fail: function() { | ||||
|                 wx.showToast({ | ||||
|                     title: "分享失败", | ||||
|                     icon: "none", | ||||
|                     duration: 2000 | ||||
|                 }); | ||||
|             } | ||||
|         }; | ||||
|     }, | ||||
|     onShareTimeline: function() { | ||||
|         return { | ||||
|             title: "推荐一款免费又超好用的视频文案创作工具,分享给大家一起使用", | ||||
|             path: "/pages/index/index?uuid=" + wx.getStorageSync("uuid"), | ||||
|             imageUrl: "/images/share.jpg", | ||||
|             success: function() { | ||||
|                 wx.showToast({ | ||||
|                     title: "分享成功", | ||||
|                     icon: "success", | ||||
|                     duration: 2000 | ||||
|                 }); | ||||
|             }, | ||||
|             fail: function() { | ||||
|                 wx.showToast({ | ||||
|                     title: "分享失败", | ||||
|                     icon: "none", | ||||
|                     duration: 2000 | ||||
|                 }); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }); | ||||
							
								
								
									
										7
									
								
								pages/faq/faq.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								pages/faq/faq.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| { | ||||
|     "navigationBarTitleText": "使用教程", | ||||
|     "navigationBarBackgroundColor": "#222238", | ||||
|     "navigationBarTextStyle": "white", | ||||
|     "component": true, | ||||
|     "usingComponents": {} | ||||
| } | ||||
							
								
								
									
										19
									
								
								pages/faq/faq.wxml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								pages/faq/faq.wxml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| <view class="container"> | ||||
|     <view class="title">帮助文档</view> | ||||
|     <view class="section"> | ||||
|         <view class="section-title">教程列表</view> | ||||
|         <view class="section-content"> | ||||
|             <navigator class="article-link" url="/pages/webview/webview?url={{item.url}}" wx:for="{{list}}" wx:key="index"> {{item.title}} </navigator> | ||||
|         </view> | ||||
|     </view> | ||||
|     <view class="section"> | ||||
|         <view class="section-title">联系我们</view> | ||||
|         <view class="section-content help"> | ||||
|             <text style="color: #a790e2;text-align: center;display: block;">【保存二维码扫码添加下载机器人】</text> | ||||
|             <image bindlongtap="saveImage" class="user-qun" data-url="https://file.guimiaokeji.com/%E5%B9%BF%E5%91%8A/1.jpg" mode="aspectFit" src="https://file.guimiaokeji.com/%E5%B9%BF%E5%91%8A/1.jpg"></image> | ||||
|         </view> | ||||
|     </view> | ||||
|     <!-- <view bindtap="onAdClick" class="advertisement"> | ||||
|         <image src="https://file.guimiaokeji.com/kecheng.png"></image> | ||||
|     </view> --> | ||||
| </view> | ||||
							
								
								
									
										73
									
								
								pages/faq/faq.wxss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								pages/faq/faq.wxss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| page { | ||||
|     background-color: #222238; | ||||
|     border-top: 1px solid hsla(0,31%,87%,.5); | ||||
| } | ||||
|  | ||||
| .container { | ||||
|     padding: 20rpx; | ||||
| } | ||||
|  | ||||
| .title { | ||||
|     color: #a790e2; | ||||
|     font-size: 36rpx; | ||||
|     font-weight: 700; | ||||
|     margin-bottom: 20rpx; | ||||
|     text-align: center; | ||||
| } | ||||
|  | ||||
| .section { | ||||
|     border-radius: 10rpx; | ||||
|     box-shadow: 0 4rpx 8rpx rgba(0,0,0,.1); | ||||
|     margin-bottom: 30rpx; | ||||
|     padding: 20rpx; | ||||
|     width: 100%; | ||||
| } | ||||
|  | ||||
| .section-title { | ||||
|     border-bottom: 2rpx solid hsla(0,31%,87%,.5); | ||||
|     color: #fff; | ||||
|     font-size: 30rpx; | ||||
|     font-weight: 700; | ||||
|     margin-bottom: 20rpx; | ||||
|     padding-bottom: 10rpx; | ||||
| } | ||||
|  | ||||
| .section-content { | ||||
|     padding-left: 20rpx; | ||||
| } | ||||
|  | ||||
| .article-link { | ||||
|     background-color: #333; | ||||
|     border-radius: 5rpx; | ||||
|     color: #fff; | ||||
|     display: block; | ||||
|     font-size: 28rpx; | ||||
|     margin-bottom: 20rpx; | ||||
|     padding: 10rpx; | ||||
|     transition: all .3s ease; | ||||
| } | ||||
|  | ||||
| .article-link:hover { | ||||
|     background-color: #e6f2ff; | ||||
|     box-shadow: 0 4rpx 8rpx rgba(0,0,0,.1); | ||||
|     color: #a790e2; | ||||
| } | ||||
|  | ||||
| .help,.user-qun { | ||||
|     margin-top: 20rpx; | ||||
| } | ||||
|  | ||||
| .user-qun { | ||||
|     border-radius: 10rpx; | ||||
|     box-shadow: 0 4rpx 8rpx rgba(0,0,0,.1); | ||||
|     width: 100%; | ||||
| } | ||||
| .advertisement { | ||||
|   margin: 5px 0; | ||||
|   width: 100%; | ||||
|   z-index: 9999; | ||||
| } | ||||
|  | ||||
| .advertisement image { | ||||
|   width: 100%; | ||||
| } | ||||
							
								
								
									
										463
									
								
								pages/index/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										463
									
								
								pages/index/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,463 @@ | ||||
| const app = getApp(); | ||||
|  | ||||
| Page({ | ||||
|     data: { | ||||
|         mode: 'link', // 默认模式为链接提取 | ||||
|         videoUrl: '', // 视频链接 | ||||
|         uploadFilePath: '', // 上传文件路径 | ||||
|         uuid: '', // 页面参数 uuid | ||||
|         showPopup: false, // 弹窗显示状态 | ||||
|         popupType: '', // 弹窗类型 | ||||
|         popupContent: '', // 弹窗内容 | ||||
|         showMask: false, | ||||
|         records: [], | ||||
|         page: 1, | ||||
|         isLoading: false, | ||||
|         hasMore: true, | ||||
|         externalOpenid:'' | ||||
|     }, | ||||
|  | ||||
|     // 切换单选框模式 | ||||
|     switchMode(e) { | ||||
|         const selectedMode = e.currentTarget.dataset.value; // 获取当前点击的值 | ||||
|         console.log("选择的模式:", selectedMode); | ||||
|         this.setData({ | ||||
|             mode: selectedMode | ||||
|         }); | ||||
|     }, | ||||
|  | ||||
|     // 输入视频链接 | ||||
|     bindVideoInput(e) { | ||||
|         this.setData({ | ||||
|             videoUrl: e.detail.value // 更新输入的视频链接 | ||||
|         }); | ||||
|     }, | ||||
|  | ||||
| //文案提取记录 | ||||
|   // 显示记录蒙版 | ||||
|   showRecordMask() { | ||||
|     this.setData({ showMask: true }); | ||||
|     console.log('显示记录蒙版') | ||||
|     this.loadRecords(); | ||||
| }, | ||||
|  | ||||
| // 隐藏蒙版 | ||||
| hideMask() { | ||||
|     this.setData({ showMask: false }); | ||||
| }, | ||||
|  | ||||
| // 阻止冒泡 | ||||
| preventDefault() { | ||||
|     return; | ||||
| }, | ||||
|  | ||||
| // 加载记录 | ||||
| // 加载记录 | ||||
| // 加载记录 | ||||
| loadRecords() { | ||||
|   if (this.data.isLoading || !this.data.hasMore) return; | ||||
|    | ||||
|   this.setData({ isLoading: true }); | ||||
|    | ||||
|   app.apiRequest({ | ||||
|       url: '/myapp/get_transcription_records/', | ||||
|       method: "POST", | ||||
|       data: { | ||||
|           page: this.data.page, | ||||
|           uuid: wx.getStorageSync("uuid"), | ||||
|           openid: wx.getStorageSync("openid") | ||||
|       }, | ||||
|       success: (res) => { | ||||
|           console.log('原始数据:', res.data); | ||||
|            | ||||
|           if (!res.data || !res.data.records) { | ||||
|               console.error('返回数据格式错误'); | ||||
|               return; | ||||
|           } | ||||
|  | ||||
|           // 获取当前records | ||||
|           const currentRecords = this.data.records || []; | ||||
|            | ||||
|           // 处理新数据 | ||||
|           const newRecords = res.data.records.map(record => { | ||||
|               const formattedResult = this.removeTimestampAndMergeLines(record.result || ''); | ||||
|               return { | ||||
|                   id: record.id, | ||||
|                   video_url: record.video_url, | ||||
|                   task_id: record.task_id, | ||||
|                   status: record.status, | ||||
|                   result: formattedResult, | ||||
|                   preview: formattedResult.substring(0, 15) + '...', | ||||
|                   created_at: this.formatTime(record.created_at) | ||||
|               }; | ||||
|           }); | ||||
|  | ||||
|           console.log('处理后的新数据:', newRecords); | ||||
|  | ||||
|           // 使用回调确保数据更新完成 | ||||
|           this.setData({ | ||||
|               records: currentRecords.concat(newRecords), | ||||
|               page: this.data.page + 1, | ||||
|               hasMore: res.data.has_more | ||||
|           }, () => { | ||||
|               console.log('更新后的完整数据:', this.data.records); | ||||
|           }); | ||||
|       }, | ||||
|       fail: (error) => { | ||||
|           console.error('请求失败:', error); | ||||
|       }, | ||||
|       complete: () => { | ||||
|           this.setData({ isLoading: false }); | ||||
|       } | ||||
|   }); | ||||
| }, | ||||
|  | ||||
| // 格式化时间显示 | ||||
| formatTime(timestamp) { | ||||
|   const date = new Date(timestamp); | ||||
|   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 `${month}-${day} ${hours}:${minutes}`; | ||||
| }, | ||||
|  | ||||
| // 加载更多 | ||||
| loadMore() { | ||||
|     this.loadRecords(); | ||||
| }, | ||||
|  | ||||
| // 跳转到文案页 | ||||
| goToExtract(e) { | ||||
|     | ||||
|     const text = encodeURIComponent(this.data.records[e.currentTarget.dataset.text].result); | ||||
|     wx.navigateTo({ | ||||
|         url: `../extract/extract?text=${text}` | ||||
|     }); | ||||
| }, | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|     // 上传文件 | ||||
|     uploadFile() { | ||||
|       wx.showToast({ | ||||
|         title: "功能开发者,敬请期待", | ||||
|         icon: "none" | ||||
|     }); | ||||
|     }, | ||||
|     // 提取视频功能 | ||||
|     parseVideo() { | ||||
|       if (!this.data.videoUrl) { | ||||
|           wx.showToast({ | ||||
|               title: "请输入有效的视频链接", | ||||
|               icon: "none" | ||||
|           }); | ||||
|           return; | ||||
|       } | ||||
|  | ||||
|       wx.showLoading({ | ||||
|           title: "正在提取..." | ||||
|       }); | ||||
|  | ||||
|       app.apiRequest({ | ||||
|           url: "/myapp/video/", // 替换为实际后端接口 | ||||
|           method: "POST", | ||||
|           data: { | ||||
|               url: this.data.videoUrl, | ||||
|               uuid: wx.getStorageSync("uuid"), | ||||
|               openid: wx.getStorageSync("openid") | ||||
|           }, | ||||
|           success: (res) => { | ||||
|               console.log("视频提取结果:", res); | ||||
|               if (res.data.data.medias[0]) { | ||||
|                   const media = res.data.data.medias[0]; | ||||
|                   wx.navigateTo({ | ||||
|                       url: `../video/video?url=${encodeURIComponent(media.resource_url)}&image=${encodeURIComponent(media.preview_url)}&preview=${encodeURIComponent(res.data.data.text)}&type=index&read_count=0` | ||||
|                   }); | ||||
|               } else { | ||||
|                   wx.showToast({ | ||||
|                       title: "不支持此链接提交。", | ||||
|                       icon: "none" | ||||
|                   }); | ||||
|               } | ||||
|           }, | ||||
|           fail: (err) => { | ||||
|               console.error("视频解析失败:", err); | ||||
|               wx.showToast({ | ||||
|                   title: "请求失败,请检查网络并稍后重试", | ||||
|                   icon: "none" | ||||
|               }); | ||||
|           }, | ||||
|           complete: () => { | ||||
|               wx.hideLoading(); | ||||
|           } | ||||
|       }); | ||||
|   }, | ||||
| // 提取文案功能 | ||||
| extractText() { | ||||
|   if (this.data.mode === 'link') { | ||||
|       if (!this.data.videoUrl) { | ||||
|           wx.showToast({ | ||||
|               title: "请输入有效链接", | ||||
|               icon: "none" | ||||
|           }); | ||||
|           return; | ||||
|       } | ||||
|  | ||||
|       let openid = wx.getStorageSync('openid') || ''; | ||||
|       let uuid = wx.getStorageSync('uuid') || ''; | ||||
|        | ||||
|       wx.showLoading({ | ||||
|           title: '后台处理中', | ||||
|       }); | ||||
|        | ||||
|       var that = this; | ||||
|       app.apiRequest({ | ||||
|           url: '/myapp/video_to_text/', | ||||
|           method: 'POST', | ||||
|           header: { | ||||
|               'content-type': 'application/json', | ||||
|           }, | ||||
|           data: { | ||||
|               url: this.data.videoUrl, | ||||
|               openid: openid, | ||||
|               uuid: uuid | ||||
|           }, | ||||
|           success(res) { | ||||
|               if (res.data.success === false) { | ||||
|                   wx.showModal({ | ||||
|                       title: "提取视频", | ||||
|                       content: '哎呀!去开通会员不限次数使用哦', | ||||
|                       confirmColor: "#00B269", | ||||
|                       cancelColor: "#858585", | ||||
|                       success: function(e) { | ||||
|                           e.confirm ? (console.log("确定"), wx.navigateTo({ | ||||
|                               url: "../vip_recharge/vip_recharge?show=true" | ||||
|                           })) : e.cancel && console.log("取消"); | ||||
|                       } | ||||
|                   }); | ||||
|                   wx.hideLoading(); | ||||
|                   return; | ||||
|               } | ||||
|  | ||||
|               let data = res.data; | ||||
|               let taskId = (data?.Data?.TaskId) || data.task_id; | ||||
|  | ||||
|               if (data.result) { | ||||
|                   wx.hideLoading(); | ||||
|                   let text = that.removeTimestampAndMergeLines(data.result); | ||||
|                   text = encodeURIComponent(text); | ||||
|                   wx.navigateTo({ | ||||
|                       url: `../extract/extract?text=${text}` | ||||
|                   }); | ||||
|               } else if (taskId) { | ||||
|                   that.search_result(taskId, openid, uuid, (result) => { | ||||
|                       wx.hideLoading(); | ||||
|                       if (result != 0) { | ||||
|                           wx.showToast({ | ||||
|                               title: '提取成功', | ||||
|                               icon: 'success' | ||||
|                           }); | ||||
|  | ||||
|                           let text = that.removeTimestampAndMergeLines(result); | ||||
|                           text = encodeURIComponent(text); | ||||
|                           wx.navigateTo({ | ||||
|                               url: `../extract/extract?text=${text}` | ||||
|                           }); | ||||
|                       } else { | ||||
|                           wx.showToast({ | ||||
|                               title: '异常', | ||||
|                               icon: 'error' | ||||
|                           }); | ||||
|                       } | ||||
|                   }); | ||||
|               } else { | ||||
|                   wx.showToast({ | ||||
|                       title: '发送文件失败', | ||||
|                       icon: 'none' | ||||
|                   }); | ||||
|               } | ||||
|           }, | ||||
|           fail(err) { | ||||
|               wx.hideLoading(); | ||||
|               wx.showToast({ | ||||
|                   title: '网络异常', | ||||
|                   icon: 'none' | ||||
|               }); | ||||
|           } | ||||
|       }); | ||||
|   } else if (this.data.mode === 'upload') { | ||||
|       wx.showToast({ | ||||
|           title: "功能开发中,敬请期待", | ||||
|           icon: "none" | ||||
|       }); | ||||
|   } | ||||
| }, | ||||
|  | ||||
| // 查询任务状态 | ||||
| search_result: function(task_id, openid, uuid, handleResult) { | ||||
|   console.log('查询任务'); | ||||
|   const checkResult = (maxRetries) => { | ||||
|       const fetchTaskStatus = () => { | ||||
|           app.apiRequest({ | ||||
|               url: '/myapp/query_task/', | ||||
|               method: 'POST', | ||||
|               header: { | ||||
|                   'content-type': 'application/json', | ||||
|               }, | ||||
|               data: { | ||||
|                   task_id: task_id, | ||||
|                   openid: openid, | ||||
|                   uuid: uuid | ||||
|               }, | ||||
|               success: function(res) { | ||||
|                   const data = res.data; | ||||
|                   if (data.result) { | ||||
|                       handleResult(data.result); | ||||
|                   } else if (maxRetries > 0) { | ||||
|                       setTimeout(fetchTaskStatus, 3000); | ||||
|                       maxRetries--; | ||||
|                   } else { | ||||
|                       wx.hideLoading(); | ||||
|                       wx.showToast({ | ||||
|                           title: '请稍后重试', | ||||
|                           icon: 'error' | ||||
|                       }); | ||||
|                       handleResult(0); | ||||
|                       console.log('已达到最大重试次数,停止查询。'); | ||||
|                   } | ||||
|               }, | ||||
|           }); | ||||
|       }; | ||||
|       fetchTaskStatus(); | ||||
|   }; | ||||
|  | ||||
|   const maxRetries = 100; | ||||
|   checkResult(maxRetries); | ||||
| }, | ||||
| extractVideoFromVideoAccount() { | ||||
|   wx.navigateTo({ | ||||
|     url: `../bot-list/bot-list` | ||||
| }); | ||||
| }, | ||||
| openDownloadRobot(){ | ||||
|   wx.navigateTo({ | ||||
|     url: `../bot-list/bot-list` | ||||
| }); | ||||
| }, | ||||
| // 去掉时间戳并合并行 | ||||
| removeTimestampAndMergeLines: function(textWithTimestamp) { | ||||
|   let txt = textWithTimestamp.replace(/\[.*\]/g, ""); | ||||
|   txt = txt.replace(/\s+/g, ""); | ||||
|   return txt; | ||||
| }, | ||||
|  | ||||
|     // 页面加载时触发 | ||||
|     onLoad(options) { | ||||
|         console.log("页面参数:", options); | ||||
|         const uuid = options.uuid || ""; | ||||
|         this.setData({ | ||||
|             uuid: uuid | ||||
|         }); | ||||
|  | ||||
|         wx.showShareMenu({ | ||||
|             withShareTicket: true, | ||||
|             menus: ["shareAppMessage", "shareTimeline"] | ||||
|         }); | ||||
|  | ||||
|         const { externalOpenid, token } = options; | ||||
|  | ||||
|         if (!externalOpenid || !token) { | ||||
|  | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // 获取新小程序用户的 openid | ||||
|         const newOpenid = wx.getStorageSync("openid"); // 假设登录状态中已存储 openid | ||||
|         if (!newOpenid) { | ||||
|             wx.showToast({ title: "获取新用户信息失败,请重新登录", icon: "none" }); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // 请求后端完成迁移 | ||||
|         app.apiRequest({ | ||||
|             url: "/myapp/migrate_member/", // 替换为后端迁移接口地址 | ||||
|             method: "POST", | ||||
|             data: { | ||||
|                 old_openid: externalOpenid, | ||||
|                 new_openid: newOpenid, // 新小程序 openid | ||||
|                 token: token, // 加密的 token | ||||
|             }, | ||||
|             success: (res) => { | ||||
|                 if (res.data.message === "会员迁移成功") { | ||||
|                     this.setData({ migrationStatus: "迁移成功" }); | ||||
|                     wx.showToast({ title: "迁移成功", icon: "success" }); | ||||
|                     wx.switchTab({ url: "/pages/mine/mine" }); // 跳转到用户中心 | ||||
|                 } else { | ||||
|                     this.setData({ migrationStatus: "迁移失败" }); | ||||
|                     wx.showToast({ title: res.data.error || "迁移失败", icon: "none" }); | ||||
|                 } | ||||
|             }, | ||||
|             fail: (err) => { | ||||
|                 console.error("迁移失败", err); | ||||
|                 this.setData({ migrationStatus: "迁移失败" }); | ||||
|                 wx.showToast({ title: "迁移失败,请稍后重试", icon: "none" }); | ||||
|             }, | ||||
|         }); | ||||
|   | ||||
|  | ||||
|     }, | ||||
|  | ||||
|     // 页面显示时触发 | ||||
|     onShow() { | ||||
|         app.getPopupConfig() | ||||
|             .then(() => { | ||||
|                 const isEnabled = wx.getStorageSync('popupEnabled'); | ||||
|                 const popupType = wx.getStorageSync('popupType'); | ||||
|                 const popupContent = wx.getStorageSync('popupContent'); | ||||
|  | ||||
|                 if (isEnabled) { | ||||
|                     this.setData({ | ||||
|                         showPopup: true, | ||||
|                         popupType: popupType, | ||||
|                         popupContent: popupContent | ||||
|                     }); | ||||
|                 } | ||||
|             }) | ||||
|             .catch((error) => { | ||||
|                 console.error('获取弹窗配置失败:', error); | ||||
|             }); | ||||
|     }, | ||||
|  | ||||
|     // 清空输入框 | ||||
|     inputClear() { | ||||
|         this.setData({ | ||||
|             videoUrl: "" | ||||
|         }); | ||||
|     }, | ||||
|  | ||||
|     // 关闭弹窗 | ||||
|     closePopup() { | ||||
|         this.setData({ | ||||
|             showPopup: false | ||||
|         }); | ||||
|     }, | ||||
|  | ||||
|     // 分享逻辑 | ||||
|     onShareAppMessage() { | ||||
|         return { | ||||
|             title: "推荐一款免费又超好用的视频文案创作工具,分享给大家一起使用", | ||||
|             path: `/pages/index/index?uuid=${wx.getStorageSync("uuid")}`, | ||||
|             imageUrl: "/images/share.jpg" | ||||
|         }; | ||||
|     }, | ||||
|  | ||||
|     onShareTimeline() { | ||||
|         return { | ||||
|             title: "推荐一款免费又超好用的视频文案创作工具,分享给大家一起使用", | ||||
|             path: `/pages/index/index?uuid=${wx.getStorageSync("uuid")}`, | ||||
|             imageUrl: "/images/share.jpg" | ||||
|         }; | ||||
|     } | ||||
| }); | ||||
							
								
								
									
										9
									
								
								pages/index/index.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								pages/index/index.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|     "usingComponents": { | ||||
|       "popup": "/popup/popup" | ||||
|     }, | ||||
|     "navigationBarTitleText": "快影下载", | ||||
|     "navigationBarBackgroundColor": "#222238", | ||||
|     "navigationBarTextStyle": "white" | ||||
|      | ||||
| } | ||||
							
								
								
									
										114
									
								
								pages/index/index.wxml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								pages/index/index.wxml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,114 @@ | ||||
| <view class="container"> | ||||
|     <!-- 提取视频卡片 --> | ||||
|     <view class="card video-extract"> | ||||
|   <view class="card-title">提取视频</view> | ||||
|   <view class="input-section"> | ||||
|     <image src="../../images/link_icon.png" class="input-icon"></image> | ||||
|     <input placeholder="请输入视频链接,支持多平台" class="input-field" bindinput="bindVideoInput"></input> | ||||
|   </view> | ||||
|   <button class="action-button" bindtap="parseVideo">提取视频</button> | ||||
|  | ||||
|   <view class="bottom-actions"> | ||||
|     <view class="bottom-button" bindtap="extractVideoFromVideoAccount">->视频号提取</view> | ||||
|     <view class="bottom-button" bindtap="openDownloadRobot">->下载机器人</view> | ||||
|   </view> | ||||
| </view> | ||||
|  | ||||
|     <!-- 视频转文案卡片 --> | ||||
|     <view class="card text-extract"> | ||||
|         <view class="card-title">视频转文案</view> | ||||
|  | ||||
|         <!-- 单选切换 --> | ||||
|         <view class="radio-buttons"> | ||||
|     <!-- 粘贴链接提取 --> | ||||
|     <view class="radio-option" bindtap="switchMode" data-value="link"> | ||||
|         <view class="radio-circle {{mode === 'link' ? 'selected' : ''}}"></view> | ||||
|         <text>粘贴链接提取</text> | ||||
|     </view> | ||||
|     <!-- 上传本地文件 --> | ||||
|     <view class="radio-option" bindtap="switchMode" data-value="upload"> | ||||
|         <view class="radio-circle {{mode === 'upload' ? 'selected' : ''}}"></view> | ||||
|         <text>上传本地文件</text> | ||||
|     </view> | ||||
| </view> | ||||
|  | ||||
|  | ||||
| <!-- 链接输入框 --> | ||||
| <view wx:if="{{mode === 'link'}}" class="input-section"> | ||||
|     <image src="../../images/link_icon.png" class="input-icon"></image> | ||||
|     <input placeholder="请输入视频链接,支持多平台" class="input-field" bindinput="bindVideoInput"></input> | ||||
| </view> | ||||
|  | ||||
|         <!-- 文件上传框 --> | ||||
|         <view wx:if="{{mode === 'upload'}}" class="input-section"> | ||||
|  | ||||
|             <view class="upload-button" bindtap="uploadFile"> | ||||
|                         <image src="../../images/upload_icon.png"   class="input-icon"></image> | ||||
|             </view> | ||||
|         </view> | ||||
|  | ||||
|         <button class="action-button" bindtap="extractText">提取文案</button> | ||||
|     </view> | ||||
| </view> | ||||
|  | ||||
| <!-- 文案提取记录按钮 放在最后的</view>标签前 --> | ||||
| <!-- 记录按钮 --> | ||||
| <view class="record-button-container"> | ||||
|     <view class="record-button" bindtap="showRecordMask"> | ||||
|         <text class="record-text">文案提取记录</text> | ||||
|     </view> | ||||
| </view> | ||||
|  | ||||
| <!-- 记录蒙版 --> | ||||
| <view class="record-mask {{showMask ? 'show' : ''}}" bindtap="hideMask"> | ||||
|     <view class="record-content" catchtap="preventDefault"> | ||||
|         <!-- 标题栏 --> | ||||
|         <view class="record-header"> | ||||
|             <text>提取记录</text> | ||||
|             <view class="close-btn" bindtap="hideMask">×</view> | ||||
|         </view> | ||||
|          | ||||
|         <!-- 记录列表 --> | ||||
|         <scroll-view  | ||||
|             scroll-y="true"  | ||||
|             class="record-list" | ||||
|             bindscrolltolower="loadMore" | ||||
|             lower-threshold="50"> | ||||
|              | ||||
|             <view wx:for="{{records}}"  | ||||
|                   wx:key="id"  | ||||
|                   class="record-item" | ||||
|                   bindtap="goToExtract" | ||||
|                   data-text="{{index}}"> | ||||
|                 <view class="record-item-left"> | ||||
|                     <view class="record-num">{{index + 1}}</view> | ||||
|                     <view class="record-info"> | ||||
|                         <text class="record-text" style="color:rgb(61, 61, 61)">{{item.preview}}</text> | ||||
|                         <text class="record-time">{{item.created_at}}</text> | ||||
|                     </view> | ||||
|                 </view> | ||||
|                 <view class="record-status {{item.status === 'completed' ? 'completed' : 'False'}}"> | ||||
|                     {{item.status === 'completed' ? '完成' : '失败'}} | ||||
|                 </view> | ||||
|             </view> | ||||
|  | ||||
|             <!-- 加载更多 --> | ||||
|             <view class="loading" wx:if="{{isLoading}}"> | ||||
|                 <view class="loading-dots"> | ||||
|                     <view class="dot"></view> | ||||
|                     <view class="dot"></view> | ||||
|                     <view class="dot"></view> | ||||
|                 </view> | ||||
|                 <text>加载中...</text> | ||||
|             </view> | ||||
|         </scroll-view> | ||||
|     </view> | ||||
| </view> | ||||
|  | ||||
| <popup  | ||||
|   wx:if="{{showPopup}}" | ||||
|   popupType="{{popupType}}"  | ||||
|   popupContent="{{popupContent}}"  | ||||
|   buttonText="查看详情"  | ||||
|   targetUrl="/pages/details/details" | ||||
| /> | ||||
							
								
								
									
										358
									
								
								pages/index/index.wxss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										358
									
								
								pages/index/index.wxss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,358 @@ | ||||
| /* 背景渐变和星星样式 */ | ||||
| page { | ||||
|   background: linear-gradient(135deg, #1A1A1A 0%, #3A3A57 50%, #000C40 100%); | ||||
|   background-size: cover, 3px 3px; | ||||
|   background-repeat: no-repeat, repeat; | ||||
|   font-size: 32rpx; | ||||
|   line-height: 1.6; | ||||
| } | ||||
|  | ||||
| /* 容器样式 */ | ||||
| .container { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   align-items: center; | ||||
|   justify-content: center; | ||||
|   padding: 20px; | ||||
| } | ||||
|  | ||||
| /* 卡片样式 */ | ||||
| .video-extract { | ||||
|   width: 90%; | ||||
|   max-width: 400px; | ||||
|   background: linear-gradient(to bottom right, rgba(58, 85, 97, 0.2), rgba(56, 76, 165, 0.2), rgba(142, 98, 96, 0.2)); | ||||
|   backdrop-filter: blur(20px); | ||||
|   border-radius: 1rem; | ||||
|   box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); | ||||
|   border: 1px solid rgba(255, 255, 255, 0.3); | ||||
|   padding: 20px; | ||||
|   margin-bottom: 20px; | ||||
|   transition: transform 0.3s ease, box-shadow 0.3s ease; | ||||
| } | ||||
| .text-extract { | ||||
|   width: 90%; | ||||
|   max-width: 400px; | ||||
|   background: linear-gradient(to bottom right, rgba(105, 105, 105, 0.3), rgba(169, 169, 169, 0.3), rgba(192, 192, 192, 0.3)); /* 金属灰渐变 */ | ||||
|   backdrop-filter: blur(20px); | ||||
|   border-radius: 1rem; | ||||
|   box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); | ||||
|   border: 1px solid rgba(255, 255, 255, 0.3); | ||||
|   padding: 20px; | ||||
|   margin-bottom: 20px; | ||||
|   transition: transform 0.3s ease, box-shadow 0.3s ease; | ||||
| } | ||||
| .card:hover { | ||||
|   transform: translateY(-5px); | ||||
|   box-shadow: 0 12px 25px rgba(0, 0, 0, 0.3); | ||||
| } | ||||
| .bottom-actions { | ||||
|   display: flex; | ||||
|   justify-content: space-around; | ||||
|   margin-top: 20px; | ||||
| } | ||||
|  | ||||
| .bottom-button { | ||||
|   border-radius: 20px; | ||||
|   padding: 5px 20px; | ||||
|   font-size: 14px; | ||||
|   border: none; | ||||
|   box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); /* 添加阴影,增强立体效果 */ | ||||
|   transition: transform 0.3s ease, box-shadow 0.3s ease; | ||||
| } | ||||
|  | ||||
| .bottom-button:hover { | ||||
|   transform: translateY(-3px); /* 悬停时轻微上移 */ | ||||
|   box-shadow: 0 6px 12px rgba(0, 0, 0, 0.3); /* 悬停时阴影加深 */ | ||||
| } | ||||
|  | ||||
| .bottom-button:first-child { | ||||
|   background-color: #4CAF50; /* 视频号提取按钮颜色:绿色 */ | ||||
|   color: white; | ||||
| } | ||||
|  | ||||
| .bottom-button:last-child { | ||||
|   background-color: #ecb35e; /* 下载机器人按钮颜色:橙色 */ | ||||
|   color: white; | ||||
| } | ||||
| /* 卡片标题 */ | ||||
| .card-title { | ||||
|   font-size: 18px; | ||||
|   font-weight: bold; | ||||
|   color: rgb(255, 255, 255); | ||||
|   margin-bottom: 10px; | ||||
|   text-align: center; | ||||
| } | ||||
|  | ||||
| /* 卡片描述 */ | ||||
| .card-description { | ||||
|   font-size: 14px; | ||||
|   color: rgb(201, 199, 199); | ||||
|   margin-bottom: 20px; | ||||
|   text-align: center; | ||||
| } | ||||
|  | ||||
| /* 输入框部分 */ | ||||
| .input-section { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   border-radius: 8px; | ||||
|   padding: 10px; | ||||
|   border: solid .2px rgb(155, 150, 150); | ||||
|   margin-bottom: 15px; | ||||
| } | ||||
|  | ||||
| .input-icon { | ||||
|   width: 20px; | ||||
|   height: 20px; | ||||
|   margin-right: 10px; | ||||
| } | ||||
|  | ||||
| .input-field { | ||||
|   flex: 1; | ||||
|   border: none; | ||||
|   outline: none; | ||||
|   font-size: 14px; | ||||
|   background: none; | ||||
|   color: rgb(201, 199, 199); | ||||
| } | ||||
|  | ||||
| /* 上传按钮 */ | ||||
| .upload-button { | ||||
|   flex: 1; | ||||
|   padding: 10px; | ||||
|   color: white; | ||||
|   font-size: 14px; | ||||
|   text-align: center; | ||||
|   border-radius: 8px; | ||||
|  | ||||
| } | ||||
|  | ||||
| /* 操作按钮 */ | ||||
| .action-button { | ||||
|   width: 100%; | ||||
|   background: linear-gradient(90deg, #8d72d2, #7183f3); | ||||
|   border-radius: 1rem; | ||||
|   box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); | ||||
|   color: white; | ||||
|   font-size: 16px; | ||||
|   font-weight: bold; | ||||
|   text-align: center; | ||||
|   border: none; | ||||
|   transition: background 0.3s ease, transform 0.3s ease; | ||||
| } | ||||
|  | ||||
| .action-button:hover { | ||||
|   background: linear-gradient(to bottom right, rgba(58, 85, 97, 0.8), rgba(56, 76, 165, 0.8), rgba(142, 98, 96, 0.8)); | ||||
|   transform: scale(1.02); | ||||
| } | ||||
| /* 单选按钮组样式 */ | ||||
| .radio-buttons { | ||||
|   display: flex; | ||||
|   justify-content: space-around; | ||||
|   margin-bottom: 15px; | ||||
| } | ||||
|  | ||||
| /* 单个选项样式 */ | ||||
| .radio-option { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   font-size: 14px; | ||||
|   color: rgb(201, 199, 199); | ||||
|   cursor: pointer; | ||||
| } | ||||
|  | ||||
| /* 圆圈样式 */ | ||||
| .radio-circle { | ||||
|   width: 16px; | ||||
|   height: 16px; | ||||
|   border: 2px solid #ccc; | ||||
|   border-radius: 50%; | ||||
|   margin-right: 8px; | ||||
|   background-color: transparent; /* 默认空心 */ | ||||
|   transition: background-color 0.3s, border-color 0.3s; | ||||
| } | ||||
|  | ||||
| /* 选中状态 */ | ||||
| .radio-circle.selected { | ||||
|   background-color: #5b8def; /* 圆圈变为实心 */ | ||||
|   border-color: #eeeeee; /* 边框颜色跟随实心颜色 */ | ||||
| } | ||||
|  | ||||
| .record-button-container { | ||||
|   width: 100%; | ||||
|   display: flex; | ||||
|   justify-content: center; | ||||
|   padding: 20rpx 0; | ||||
|   margin-top: 30rpx; | ||||
| } | ||||
|  | ||||
| .record-button { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   justify-content: center; | ||||
|   background: linear-gradient(135deg, #4CAF50, #45a049); | ||||
|   padding: 20rpx 40rpx; | ||||
|   border-radius: 40rpx; | ||||
|   box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15); | ||||
|   transition: transform 0.2s ease; | ||||
| } | ||||
|  | ||||
| .record-button:active { | ||||
|   transform: scale(0.98); | ||||
| } | ||||
|  | ||||
| .record-icon { | ||||
|   width: 40rpx; | ||||
|   height: 40rpx; | ||||
|   margin-right: 10rpx; | ||||
| } | ||||
|  | ||||
| .record-text { | ||||
|   color: #ecf5f3; | ||||
|   font-size: 28rpx; | ||||
|   font-weight: 500; | ||||
| } | ||||
| /* 蒙版样式 */ | ||||
| .record-mask { | ||||
|   position: fixed; | ||||
|   top: 0; | ||||
|   left: 0; | ||||
|   right: 0; | ||||
|   bottom: 0; | ||||
|   background: rgba(0, 0, 0, 0.5); | ||||
|   z-index: 999; | ||||
|   opacity: 0; | ||||
|   visibility: hidden; | ||||
|   transition: all 0.3s ease; | ||||
| } | ||||
| .record-num{ | ||||
|   color:rgb(192, 186, 180) | ||||
| } | ||||
| .record-mask.show { | ||||
|   opacity: 1; | ||||
|   visibility: visible; | ||||
| } | ||||
|  | ||||
| .record-content { | ||||
|   position: fixed; | ||||
|   bottom: -100%; | ||||
|   left: 0; | ||||
|   width: 100%; | ||||
|   height: 80vh; | ||||
|   background: #fff; | ||||
|   border-radius: 24rpx 24rpx 0 0; | ||||
|   transition: all 0.3s ease; | ||||
| } | ||||
|  | ||||
| .record-mask.show .record-content { | ||||
|   bottom: 0; | ||||
| } | ||||
|  | ||||
| /* 标题栏 */ | ||||
| .record-header { | ||||
|   padding: 30rpx; | ||||
|   border-bottom: 1rpx solid #eee; | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   align-items: center; | ||||
| } | ||||
|  | ||||
| .close-btn { | ||||
|   font-size: 40rpx; | ||||
|   color: #999; | ||||
|   padding: 10rpx; | ||||
| } | ||||
|  | ||||
| /* 记录列表 */ | ||||
| .record-list { | ||||
|   height: calc(80vh - 100rpx); | ||||
| } | ||||
|  | ||||
| .record-item { | ||||
|   padding: 30rpx; | ||||
|   border-bottom: 1rpx solid #f5f5f5; | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   align-items: center; | ||||
|   transition: background-color 0.2s ease; | ||||
| } | ||||
|  | ||||
| .record-item:active { | ||||
|   background-color: #f9f9f9; | ||||
| } | ||||
|  | ||||
| .record-item-left { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   flex: 1; | ||||
| } | ||||
|  | ||||
|  | ||||
| .record-info { | ||||
|   margin-left: 20rpx; | ||||
|   flex: 1; | ||||
| } | ||||
|  | ||||
|  | ||||
| .record-time { | ||||
|   font-size: 24rpx; | ||||
|   color: #999; | ||||
|   margin-top: 8rpx; | ||||
|   display: block; | ||||
| } | ||||
|  | ||||
| .record-status { | ||||
|   font-size: 24rpx; | ||||
|   padding: 6rpx 16rpx; | ||||
|   border-radius: 20rpx; | ||||
| } | ||||
|  | ||||
| .record-status.completed { | ||||
|   background: #e8f5e9; | ||||
|   color: #4caf50; | ||||
| } | ||||
|  | ||||
| .record-status.False { | ||||
|   background: #fcfeff; | ||||
|   color: #e97a92; | ||||
| } | ||||
|  | ||||
| /* 加载动画 */ | ||||
| .loading { | ||||
|   padding: 30rpx; | ||||
|   text-align: center; | ||||
|   color: #999; | ||||
|   font-size: 24rpx; | ||||
| } | ||||
|  | ||||
| .loading-dots { | ||||
|   display: flex; | ||||
|   justify-content: center; | ||||
|   margin-bottom: 10rpx; | ||||
| } | ||||
|  | ||||
| .dot { | ||||
|   width: 12rpx; | ||||
|   height: 12rpx; | ||||
|   background: #999; | ||||
|   border-radius: 50%; | ||||
|   margin: 0 6rpx; | ||||
|   animation: dot-jump 1.2s infinite; | ||||
| } | ||||
|  | ||||
| .dot:nth-child(2) { | ||||
|   animation-delay: 0.2s; | ||||
| } | ||||
|  | ||||
| .dot:nth-child(3) { | ||||
|   animation-delay: 0.4s; | ||||
| } | ||||
|  | ||||
| @keyframes dot-jump { | ||||
|   0%, 80%, 100% { | ||||
|       transform: translateY(0); | ||||
|   } | ||||
|   40% { | ||||
|       transform: translateY(-10rpx); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										11
									
								
								pages/invite/invite.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								pages/invite/invite.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| Page({ | ||||
|     data: {}, | ||||
|     onLoad: function(n) {}, | ||||
|     onReady: function() {}, | ||||
|     onShow: function() {}, | ||||
|     onHide: function() {}, | ||||
|     onUnload: function() {}, | ||||
|     onPullDownRefresh: function() {}, | ||||
|     onReachBottom: function() {}, | ||||
|     onShareAppMessage: function() {} | ||||
| }); | ||||
							
								
								
									
										3
									
								
								pages/invite/invite.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								pages/invite/invite.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| { | ||||
|     "usingComponents": {} | ||||
| } | ||||
							
								
								
									
										1
									
								
								pages/invite/invite.wxml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								pages/invite/invite.wxml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| <text>pages/invite/invite.wxml</text> | ||||
							
								
								
									
										0
									
								
								pages/invite/invite.wxss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pages/invite/invite.wxss
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										81
									
								
								pages/invite_incentive/invite_incentive.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								pages/invite_incentive/invite_incentive.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| var e = getApp(); | ||||
|  | ||||
| Page({ | ||||
|     data: { | ||||
|         inviteCount: 0, | ||||
|         rewardCount: 0, | ||||
|         countdown: "3天12时30分20秒", | ||||
|         number: 0, | ||||
|         uuid:wx.getStorageSync("uuid"), | ||||
|     }, | ||||
|     onLoad: function(e) { | ||||
|         wx.showShareMenu({ | ||||
|             withShareTicket: !0, | ||||
|             menus: [ "shareAppMessage", "shareTimeline" ] | ||||
|         }), console.log(1), this.startCountdown(); | ||||
|     }, | ||||
|     startCountdown: function() { | ||||
|         var e = this, n = 30422e4; | ||||
|         setTimeout(function t() { | ||||
|             var o = Math.floor(n / 864e5) + "天" + Math.floor(n % 864e5 / 36e5) + "时" + Math.floor(n % 36e5 / 6e4) + "分" + Math.floor(n % 6e4 / 1e3) + "秒"; | ||||
|             e.setData({ | ||||
|                 countdown: o | ||||
|             }), (n -= 1e3) >= 0 ? setTimeout(t, 1e3) : e.setData({ | ||||
|                 countdown: "活动已结束" | ||||
|             }); | ||||
|         }, 1e3); | ||||
|     }, | ||||
|     onReady: function() {}, | ||||
|     onShow: function() { | ||||
|         var n = this; | ||||
|         e.getUserInfo().then(function() { | ||||
|             console.log(wx.getStorageSync("invitees_count"), "人"), console.log(10 * wx.getStorageSync("invitees_count"), "次"),  | ||||
|             n.setData({ | ||||
|                 inviteCount: wx.getStorageSync("invitees_count"), | ||||
|                 rewardCount: 10 * wx.getStorageSync("invitees_count"), | ||||
|                 number: wx.getStorageSync("balance") | ||||
|             }); | ||||
|         }).catch(function(e) { | ||||
|             console.error("An error occurred:", e); | ||||
|         }); | ||||
|     }, | ||||
|     copyPath: function () { | ||||
|       const path = '/pages/index/index?uuid=' + this.data.uuid; | ||||
|       wx.setClipboardData({ | ||||
|         data: path, | ||||
|         success: function (res) { | ||||
|           wx.showToast({ | ||||
|             title: '复制成功', | ||||
|             icon: 'success', | ||||
|             duration: 1500 | ||||
|           }); | ||||
|         } | ||||
|       }); | ||||
|     }, | ||||
|    | ||||
|     onHide: function() {}, | ||||
|     onUnload: function() {}, | ||||
|     onPullDownRefresh: function() {}, | ||||
|     onReachBottom: function() {}, | ||||
|     onShareAppMessage: function() { | ||||
|         return { | ||||
|             title: "推荐一款免费又超好用的AI视频文案创作工具,分享给大家一起使用", | ||||
|             path: "/pages/index/index?uuid=" + wx.getStorageSync("uuid"), | ||||
|             imageUrl: "/images/share.jpg", | ||||
|             success: function(e) { | ||||
|                 wx.showToast({ | ||||
|                     title: "分享成功", | ||||
|                     icon: "success", | ||||
|                     duration: 2e3 | ||||
|                 }); | ||||
|             }, | ||||
|             fail: function(e) { | ||||
|                 wx.showToast({ | ||||
|                     title: "分享失败", | ||||
|                     icon: "none", | ||||
|                     duration: 2e3 | ||||
|                 }); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }); | ||||
							
								
								
									
										7
									
								
								pages/invite_incentive/invite_incentive.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								pages/invite_incentive/invite_incentive.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| { | ||||
|     "navigationBarTitleText": "邀请奖励", | ||||
|     "navigationBarBackgroundColor": "#222238", | ||||
|     "navigationBarTextStyle": "white", | ||||
|     "component": true, | ||||
|     "usingComponents": {} | ||||
| } | ||||
							
								
								
									
										33
									
								
								pages/invite_incentive/invite_incentive.wxml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								pages/invite_incentive/invite_incentive.wxml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| <view class="container"> | ||||
|   <view class="section1"> | ||||
|     <view class="item"> | ||||
|       <text class="title">已邀请:</text> | ||||
|       <text class="count">{{inviteCount}} 人</text> | ||||
|     </view> | ||||
|     <view class="item"> | ||||
|       <text class="title">邀请奖励:</text> | ||||
|       <text class="count">{{number}} 元</text> | ||||
|     </view> | ||||
|   </view> | ||||
|   <view class="section2"> | ||||
|     <text class="subtitle">邀请规则:</text> | ||||
|  | ||||
|     <view class="description">每邀请一个新用户使用小程序奖励,</view> | ||||
|     <view class="description">分享给好友使用即可获得奖励。</view> | ||||
|     <view class="description">邀请的用户首次开通会员,您将获得80%返利。</view> | ||||
|     <view class="description">后续续费,您将获得40%奖励。</view> | ||||
|     <view class="description">提现门槛:100元。</view> | ||||
|     <view class="description warning">禁止任何形式的作弊行为,</view> | ||||
|     <view class="description warning">如发现使用外挂等违规行为,</view> | ||||
|     <view class="description warning">将取消活动资格。</view> | ||||
|     <view class="countdown">活动限时有效</view> | ||||
|     <view class="invite-path"> | ||||
|     | ||||
|       <text class="path-text" bindtap="copyPath" selectable="true">/pages/index/index?uuid={{uuid}}</text> | ||||
|     </view> | ||||
|   </view> | ||||
|   <view class="button-container"> | ||||
|     <button class="reward-button reward-button1" openType="contact">提现</button> | ||||
|     <button class="reward-button reward-button2" openType="share">邀请好友</button> | ||||
|   </view> | ||||
| </view> | ||||
							
								
								
									
										126
									
								
								pages/invite_incentive/invite_incentive.wxss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								pages/invite_incentive/invite_incentive.wxss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | ||||
| .container { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   align-items: center; | ||||
|   padding: 20px; | ||||
|   background-color: #f8f8f8; | ||||
| } | ||||
|  | ||||
| .section1 { | ||||
|   width: 90%; | ||||
|   max-width: 600px; | ||||
|   background-color: white; | ||||
|   padding: 20px; | ||||
|   border-radius: 10px; | ||||
|   box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | ||||
|   margin-bottom: 20px; | ||||
|   display: flex; | ||||
|   justify-content: space-around; | ||||
| } | ||||
|  | ||||
| .item { | ||||
|   text-align: center; | ||||
| } | ||||
|  | ||||
| .title { | ||||
|   font-size: 14px; | ||||
|   color: #333; | ||||
|   margin-bottom: 5px; | ||||
| } | ||||
|  | ||||
| .count { | ||||
|   font-size: 18px; | ||||
|   font-weight: bold; | ||||
|   color: #007bff; | ||||
| } | ||||
|  | ||||
| .section2 { | ||||
|   width: 90%; | ||||
|   max-width: 600px; | ||||
|   background-color: white; | ||||
|   padding: 20px; | ||||
|   border-radius: 10px; | ||||
|   box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | ||||
|   margin-bottom: 20px; | ||||
| } | ||||
|  | ||||
| .subtitle { | ||||
|   font-size: 16px; | ||||
|   font-weight: bold; | ||||
|   color: #333; | ||||
|   text-align: center; | ||||
|  | ||||
| } | ||||
|  | ||||
| .description { | ||||
|   margin-top: 15px; | ||||
|   font-size: 14px; | ||||
|   color: #666; | ||||
|   line-height: 1.6; | ||||
|   margin-bottom: 8px; | ||||
| } | ||||
|  | ||||
| .warning { | ||||
|   color: #d9534f; | ||||
|   margin-top: 5px; | ||||
| } | ||||
|  | ||||
| .countdown { | ||||
|   font-size: 14px; | ||||
|   color: #999; | ||||
|   text-align: center; | ||||
|   margin-top: 15px; | ||||
| } | ||||
|  | ||||
| .button-container { | ||||
|   width: 90%; | ||||
|   max-width: 600px; | ||||
|   display: flex; | ||||
|   justify-content: space-around; | ||||
| } | ||||
| .invite-path { | ||||
|   margin-top: 20px; | ||||
|   padding: 10px; | ||||
|   background-color: #f0f0f0; | ||||
|   border-radius: 5px; | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
| } | ||||
|  | ||||
| .path-title { | ||||
|   font-size: 14px; | ||||
|   color: #333; | ||||
|   margin-right: 10px; | ||||
| } | ||||
|  | ||||
| .path-text { | ||||
|   font-size: 14px; | ||||
|   color: #007bff; | ||||
|   word-break: break-all; /* 长路径自动换行 */ | ||||
| } | ||||
| .reward-button { | ||||
|   width: 48%; | ||||
|  | ||||
|   margin: 10px; | ||||
|   border-radius: 25px; | ||||
|   font-size: 16px; | ||||
|   font-weight: 500; | ||||
|   color: white; /* 字体颜色改为白色 */ | ||||
|   border: none; | ||||
|   box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); /* 阴影更明显 */ | ||||
|   transition: transform 0.2s ease, box-shadow 0.2s ease; | ||||
|   text-align: center; | ||||
| } | ||||
|  | ||||
| .reward-button:active { | ||||
|   transform: translateY(2px); | ||||
|   box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); | ||||
| } | ||||
|  | ||||
| .reward-button1 { | ||||
|   background: linear-gradient(135deg, #4CAF50, #2E7D32); /* 深绿色渐变 */ | ||||
| } | ||||
|  | ||||
| .reward-button2 { | ||||
|   background: linear-gradient(135deg, #2196F3, #1976D2); /* 深蓝色渐变 */ | ||||
| } | ||||
							
								
								
									
										164
									
								
								pages/mine/mine.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								pages/mine/mine.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,164 @@ | ||||
| var util = require('../../utils/util.js'); // 确保你有这样一个文件 | ||||
|  | ||||
|  | ||||
| var e = getApp(); | ||||
|  | ||||
| Component({ | ||||
|     data: { | ||||
|         defaultDailyFreeParseNum: "--", | ||||
|         totalParseNum: "--", | ||||
|         userInfo: null, | ||||
|         hasUserInfo: !1, | ||||
|         uuid: null, | ||||
|         isVip: !1, | ||||
|         startTime: "--", | ||||
|         endTime: "--", | ||||
|         formattedEndTime: "" | ||||
|     }, | ||||
|     methods: { | ||||
|         onLoad: function() { | ||||
|             wx.showShareMenu({ | ||||
|                 withShareTicket: !0, | ||||
|                 menus: [ "shareAppMessage", "shareTimeline" ] | ||||
|             }); | ||||
|         }, | ||||
|         onShow: function() { | ||||
|             var t = this; | ||||
|             e.getCurrentTabbar(3, this), e.checkUpdateVersion(), console.log("执行用户.jsonShow"),  | ||||
|             e.getUserInfo().then(function() { | ||||
|                 console.log("获取用户信息开始"), console.log(wx.getStorageSync("defaultDailyFreeParseNum")),  | ||||
|                 t.setData({ | ||||
|                     hasUserInfo: !0, | ||||
|                     uuid: wx.getStorageSync("uuid"), | ||||
|                     defaultDailyFreeParseNum: wx.getStorageSync("defaultDailyFreeParseNum"), | ||||
|                     totalParseNum: wx.getStorageSync("totalParseNum"), | ||||
|                     isVip: wx.getStorageSync("isMember"), | ||||
|                     startTime: wx.getStorageSync("startTime"), | ||||
|                     endTime: wx.getStorageSync("endTime") | ||||
|                 }), t.formatEndTime(), console.log("获取用户信息结束"); | ||||
|             }).catch(function(e) { | ||||
|                 console.error("获取用户信息失败:", e); | ||||
|             }).finally(function() { | ||||
|                 console.log("getUserInfo调用完成"); | ||||
|             }); | ||||
|         }, | ||||
|         formatEndTime: function() { | ||||
|             var e = this.data.endTime; | ||||
|               // 将秒时间戳转换为毫秒时间戳 | ||||
|               var date = new Date(e * 1000); | ||||
|  | ||||
|               // 格式化为“YYYY年MM月DD日” | ||||
|               var year = date.getFullYear(); | ||||
|               var month = String(date.getMonth() + 1).padStart(2, "0"); // 月份从 0 开始,需要 +1 | ||||
|               var day = String(date.getDate()).padStart(2, "0"); | ||||
|  | ||||
|               var formattedDate = `${year}-${month}-${day}`; | ||||
|  | ||||
|               // 更新到 data | ||||
|               this.setData({ | ||||
|                   formattedEndTime: formattedDate | ||||
|               }); | ||||
|  | ||||
|         }, | ||||
|         getUserInfo: function(e) {}, | ||||
|         openvip: function(e) { | ||||
|             wx.navigateTo({ | ||||
|                 url: "../vip_recharge/vip_recharge?show=true" | ||||
|             }); | ||||
|         }, | ||||
|         opennum: function(e) { | ||||
|             wx.navigateTo({ | ||||
|                 url: "../vip_recharge/vip_recharge?show=true" | ||||
|             }); | ||||
|         }, | ||||
|         getTotalParseNum: function() { | ||||
|             this.setData({ | ||||
|                 defaultDailyFreeParseNum: wx.getStorageSync("defaultDailyFreeParseNum") | ||||
|             }); | ||||
|         }, | ||||
|         showExchangeModal: function(t) { | ||||
|             var o = this; | ||||
|             wx.showLoading(), wx.showModal({ | ||||
|                 title: "卡密兑换", | ||||
|                 content: "", | ||||
|                 editable: !0, | ||||
|                 placeholderText: "输入卡密", | ||||
|                 success: function(t) { | ||||
|                     t.confirm ? (console.log("用户点击确定"), e.apiRequest({ | ||||
|                         url: "/myapp/redeem_card/", | ||||
|                         method: "POST", | ||||
|                         data: { | ||||
|                             openid: wx.getStorageSync("openid"), | ||||
|                             uuid: wx.getStorageSync("uuid"), | ||||
|                             card_code: t.content | ||||
|                         }, | ||||
|                         success: function(t) { | ||||
|                             e.getUserInfo().then(function() { | ||||
|                                 o.getTotalParseNum(), console.log(wx.getStorageSync("defaultDailyFreeParseNum")); | ||||
|                             }).catch(function(e) { | ||||
|                                 console.error("An error occurred:", e); | ||||
|                             }), "success" == t.data.status ? wx.showToast({ | ||||
|                                 title: t.data.message, | ||||
|                                 icon: "success", | ||||
|                                 duration: 1e3 | ||||
|                             }) : wx.showToast({ | ||||
|                                 title: t.data.error, | ||||
|                                 icon: "error", | ||||
|                                 duration: 1e3 | ||||
|                             }), console.log("卡密兑换成功:", t.data); | ||||
|                         }, | ||||
|                         fail: function(e) { | ||||
|                             wx.showToast({ | ||||
|                                 title: "请求网络失败", | ||||
|                                 icon: "none", | ||||
|                                 duration: 1e3 | ||||
|                             }), console.error("卡密兑换失败:", e); | ||||
|                         } | ||||
|                     })) : t.cancel && (console.log("用户点击取消"), wx.hideLoading()); | ||||
|                 } | ||||
|             }); | ||||
|         }, | ||||
|         onShareAppMessage: function() { | ||||
|             return { | ||||
|                 title: "推荐一款免费又超好用的视频文案创作工具,分享给大家一起使用", | ||||
|                 path: "/pages/index/index?uuid=" + wx.getStorageSync("uuid"), | ||||
|                 imageUrl: "/images/share.jpg", | ||||
|                 success: function(e) { | ||||
|                     wx.showToast({ | ||||
|                         title: "分享成功", | ||||
|                         icon: "success", | ||||
|                         duration: 2e3 | ||||
|                     }); | ||||
|                 }, | ||||
|                 fail: function(e) { | ||||
|                     wx.showToast({ | ||||
|                         title: "分享失败", | ||||
|                         icon: "none", | ||||
|                         duration: 2e3 | ||||
|                     }); | ||||
|                 } | ||||
|             }; | ||||
|         } | ||||
|     }, | ||||
|     onShareTimeline: function() { | ||||
|         return { | ||||
|             title: "推荐一款免费又超好用的视频文案创作工具,分享给大家一起使用", | ||||
|             path: "/pages/index/index?uuid=" + wx.getStorageSync("uuid"), | ||||
|             imageUrl: "/images/share.jpg", | ||||
|             success: function(e) { | ||||
|                 wx.showToast({ | ||||
|                     title: "分享成功", | ||||
|                     icon: "success", | ||||
|                     duration: 2e3 | ||||
|                 }); | ||||
|             }, | ||||
|             fail: function(e) { | ||||
|                 wx.showToast({ | ||||
|                     title: "分享失败", | ||||
|                     icon: "none", | ||||
|                     duration: 2e3 | ||||
|                 }); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }); | ||||
							
								
								
									
										8
									
								
								pages/mine/mine.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								pages/mine/mine.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| { | ||||
|     "navigationBarTitleText": "个人中心", | ||||
|     "navigationBarBackgroundColor": "#222238", | ||||
|     "navigationBarTextStyle": "white", | ||||
|     "component": true, | ||||
|     "custom-tab-bar": "/custom-tab-bar/index", | ||||
|     "usingComponents": {} | ||||
| } | ||||
							
								
								
									
										70
									
								
								pages/mine/mine.wxml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								pages/mine/mine.wxml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | ||||
| <view class="center"> | ||||
|     <view class="blue-top"> | ||||
|         <view class="user-card"> | ||||
|             <view class="card-top"> | ||||
|                 <view class="user-top"> | ||||
|                     <view class="user-vip" style="position:relative;"> | ||||
|                         <image class="user-pic" src="/images/老师教师男人.png"></image> | ||||
|                     </view> | ||||
|                     <view class="user-board"> | ||||
|                         <button bindgetuserinfo="getUserInfo" class="user-name" openType="getUserInfo" wx:if="{{!hasUserInfo}}">点击登陆</button> | ||||
|                         <view class="user-name" userSelect="true" wx:if="{{hasUserInfo}}">ID:{{uuid}}</view> | ||||
|                     </view> | ||||
|                 </view> | ||||
|             </view> | ||||
|             <view class="card-bottom"> | ||||
|                 <view class="left"> | ||||
|                     <view class="count"> | ||||
|                         <text class="num">{{defaultDailyFreeParseNum}} </text> | ||||
|                     </view> | ||||
|                     <!-- <text bindtap="opennum" class="txt">创意点</text> --> | ||||
|                     <text class="txt">创意点</text> | ||||
|                 </view> | ||||
|                 <view class="right"> | ||||
|                     <view class="count"> | ||||
|                         <text class="num" style="color:rgb(253, 217, 10)" wx:if="{{isVip}}">{{formattedEndTime}}</text> | ||||
|                         <text class="num"  bindtap="openvip" wx:else>开通会员</text> | ||||
|                         <!-- <text  class="num" wx:else>Null</text> --> | ||||
|                     </view> | ||||
|                     <text class="txt" style="color:rgb(253, 217, 10)" wx:if="{{isVip}}">尊贵VIP</text> | ||||
|                     <text class="txt" wx:else>您还不是会员</text> | ||||
|                 </view> | ||||
|             </view> | ||||
|         </view> | ||||
|     </view>   | ||||
|     <!-- <navigator class="center-list-item" url="/pages/vip_recharge/vip_recharge"> --> | ||||
|  | ||||
|  <view class="center-list">  | ||||
|           <navigator class="center-list-item" url="/pages/vip_recharge/vip_recharge"> | ||||
|             <image class="icon1" src="../../images/huiyuan.png" style="width: 30px; height: 30px;"></image> | ||||
|             <text class="list-text">开通会员</text> | ||||
|         </navigator> | ||||
|  | ||||
|         <navigator class="center-list-item" url="/pages/details/details"> | ||||
|             <image class="icon1" src="../../icons/lw.png" style="width: 30px; height: 30px;"></image> | ||||
|             <text class="list-text">新人礼包</text> | ||||
|         </navigator> | ||||
|         <view bindtap="showExchangeModal" class="center-list-item"> | ||||
|             <image class="icon1" src="../../images/兑换码.png" style="width: 30px; height: 30px;"></image> | ||||
|             <text class="list-text">卡密兑换</text> | ||||
|         </view> | ||||
|         <navigator class="center-list-item" url="/pages/invite_incentive/invite_incentive"> | ||||
|             <image class="icon1" src="../../images/人民币.png" style="width: 30px; height: 30px;"></image> | ||||
|             <text class="list-text">分享奖励</text> | ||||
|         </navigator> | ||||
|         <!-- <navigator class="center-list-item" url="/pages/business_cooperation/business_cooperation"> | ||||
|             <image class="icon1" src="../../images/代理商.png" style="width: 30px; height: 30px;"></image> | ||||
|             <text class="list-text">商业合作</text> | ||||
|         </navigator> --> | ||||
|         <button class="center-list-item" openType="contact"> | ||||
|             <image class="icon1" src="../../images/客服.png" style="width: 30px; height: 30px;"></image> | ||||
|             <text class="list-text">联系客服</text> | ||||
|         </button> | ||||
|         <navigator class="center-list-item" url="/pages/faq/faq"> | ||||
|             <image class="icon1" src="../../images/帮助.png" style="width: 30px; height: 30px;"></image> | ||||
|             <text class="list-text">使用教程</text> | ||||
|         </navigator> | ||||
|     </view> | ||||
|     <view class="relief">© 2024 创作者服务</view> | ||||
|     <view class="buttom" style="height: 65px;"></view> | ||||
| </view> | ||||
							
								
								
									
										248
									
								
								pages/mine/mine.wxss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										248
									
								
								pages/mine/mine.wxss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,248 @@ | ||||
| page { | ||||
|     background: #f5f5f5; | ||||
| } | ||||
|  | ||||
| .cu-avatar { | ||||
|     align-items: center; | ||||
|     background-color: #ccc; | ||||
|     background-position: 50%; | ||||
|     background-size: cover; | ||||
|     color: var(--white); | ||||
|     display: inline-flex; | ||||
|     font-size: 1.5em; | ||||
|     font-variant: small-caps; | ||||
|     height: 64rpx; | ||||
|     justify-content: center; | ||||
|     text-align: center; | ||||
|     vertical-align: middle; | ||||
|     white-space: nowrap; | ||||
|     width: 64rpx; | ||||
| } | ||||
|  | ||||
| .cu-avatar,button { | ||||
|     margin: 0; | ||||
|     padding: 0; | ||||
|     position: relative; | ||||
| } | ||||
|  | ||||
| button { | ||||
|     -webkit-tap-highlight-color: transparent; | ||||
|     background-color: inherit; | ||||
|     border-radius: 0; | ||||
|     box-sizing: border-box; | ||||
|     color: inherit; | ||||
|     display: block; | ||||
|     font-size: inherit; | ||||
|     line-height: inherit; | ||||
|     overflow: hidden; | ||||
|     text-align: inherit; | ||||
|     text-decoration: none; | ||||
| } | ||||
|  | ||||
| button::after { | ||||
|     border: none; | ||||
| } | ||||
|  | ||||
| .center { | ||||
|     -webkit-box-orient: vertical; | ||||
|     -webkit-box-direction: normal; | ||||
|     flex-direction: column; | ||||
|     padding-bottom: 61px; | ||||
| } | ||||
|  | ||||
| .center .blue-top { | ||||
|     background-color: #0b0c0c; | ||||
|     border-radius: 0 0 350rpx 350rpx/0 0 30rpx 30rpx; | ||||
|     height: 230rpx; | ||||
|     margin-bottom: 160rpx; | ||||
|     width: 750rpx; | ||||
| } | ||||
|  | ||||
| .center .blue-top .user-card { | ||||
|     background: linear-gradient(90deg,#8d72d2,#7183f3); | ||||
|     border-radius: 20rpx; | ||||
|     box-sizing: border-box; | ||||
|     height: 330rpx; | ||||
|     left: 50%; | ||||
|     position: absolute; | ||||
|     transform: translate(-50%,28rpx); | ||||
|     width: 686rpx; | ||||
| } | ||||
|  | ||||
| .center .blue-top .user-card .card-top { | ||||
|     border-bottom: 1px solid #eee; | ||||
|     box-sizing: border-box; | ||||
|     height: 190rpx; | ||||
|     position: relative; | ||||
| } | ||||
|  | ||||
| .center .blue-top .user-card .card-top .user-top { | ||||
|     position: absolute; | ||||
|     top: -26rpx; | ||||
|     width: 100%; | ||||
| } | ||||
|  | ||||
| .center .blue-top .user-card .card-top .user-top .user-vip { | ||||
|     height: 130rpx; | ||||
|     margin: 0 auto; | ||||
|     width: 130rpx; | ||||
| } | ||||
|  | ||||
| .center .blue-top .user-card .card-top .user-top .user-vip .user-pic { | ||||
|     background: #fff; | ||||
|     border-radius: 50%; | ||||
|     display: block; | ||||
|     height: 130rpx; | ||||
|     margin: 0 auto; | ||||
|     overflow: hidden; | ||||
|     width: 130rpx; | ||||
| } | ||||
|  | ||||
| .center .blue-top .user-card .card-top .user-top .user-board { | ||||
|     -webkit-box-pack: center; | ||||
|     -ms-flex-pack: center; | ||||
|     display: -ms-flexbox; | ||||
|     display: flex; | ||||
|     justify-content: center; | ||||
|     margin-top: 20rpx; | ||||
|     width: 100%; | ||||
| } | ||||
|  | ||||
| .center .blue-top .user-card .card-top .user-top .user-board .user-name { | ||||
|     color: #ccc; | ||||
|     font-size: 36rpx; | ||||
|     font-weight: 700; | ||||
| } | ||||
|  | ||||
| .center .blue-top .user-card .card-top .user-top .user-board .vip-icon { | ||||
|     display: block; | ||||
|     height: 44rpx; | ||||
|     margin-left: 17rpx; | ||||
|     margin-top: 2rpx; | ||||
|     width: 44rpx; | ||||
| } | ||||
|  | ||||
| .center .blue-top .user-card .card-bottom { | ||||
|     box-sizing: border-box; | ||||
|     display: -ms-flexbox; | ||||
|     display: flex; | ||||
|     height: 140rpx; | ||||
|     padding: 18rpx 0; | ||||
|     text-align: center; | ||||
| } | ||||
|  | ||||
| .center .blue-top .user-card .card-bottom .left { | ||||
|     border-right: 1px solid #eee; | ||||
| } | ||||
|  | ||||
| .center .blue-top .user-card .card-bottom .left,.center .blue-top .user-card .card-bottom .right { | ||||
|     -webkit-box-orient: vertical; | ||||
|     -webkit-box-direction: normal; | ||||
|     -webkit-box-pack: center; | ||||
|     -ms-flex-pack: center; | ||||
|     display: -ms-flexbox; | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     justify-content: center; | ||||
|     width: 50%; | ||||
| } | ||||
|  | ||||
| .center .blue-top .user-card .card-bottom .count { | ||||
|     color: #fff; | ||||
|     font-size: 36rpx; | ||||
|     font-weight: 700; | ||||
|     margin-bottom: 10rpx; | ||||
| } | ||||
|  | ||||
| .center .blue-top .user-card .card-bottom .count .num { | ||||
|     color: #fff; | ||||
|     display: inline; | ||||
| } | ||||
|  | ||||
| .center .blue-top .user-card .card-bottom .txt { | ||||
|     color: #fff; | ||||
|     font-size: 24rpx; | ||||
| } | ||||
|  | ||||
| .center-list { | ||||
|     -webkit-box-orient: vertical; | ||||
|     background-color: #fff; | ||||
|     border-radius: 20rpx; | ||||
|     display: -ms-flexbox; | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     margin: 0 auto; | ||||
|     overflow: hidden; | ||||
| } | ||||
|  | ||||
| .center-list,.center-list-item { | ||||
|     -webkit-box-direction: normal; | ||||
|     width: 686rpx; | ||||
| } | ||||
|  | ||||
| .center-list-item { | ||||
|     -webkit-box-orient: horizontal; | ||||
|     border-bottom: 1px solid; | ||||
|     border-color: #eee; | ||||
|     box-sizing: border-box; | ||||
|     display: -webkit-box; | ||||
|     display: -ms-flexbox; | ||||
|     flex-direction: row; | ||||
|     height: 114rpx; | ||||
|     padding: 0rpx 32rpx; | ||||
| } | ||||
|  | ||||
| .center-list-item:last-child { | ||||
|     border-bottom: 0; | ||||
| } | ||||
|  | ||||
| .center-list-item .icon1 { | ||||
|     background-position: 50%; | ||||
|     background-repeat: no-repeat; | ||||
|     background-size: 50rpx 50rpx; | ||||
|     color: #00c8fd; | ||||
|     display: block; | ||||
|     margin-right: 18rpx; | ||||
|     width: 50rpx; | ||||
| } | ||||
|  | ||||
| .center-list-item .icon1,.list-text { | ||||
|     height: 114rpx; | ||||
|     line-height: 114rpx; | ||||
|     text-align: left; | ||||
| } | ||||
|  | ||||
| .list-text { | ||||
|     -webkit-box-flex: 1; | ||||
|     color: #1f1f1f; | ||||
|     flex: 1; | ||||
|     font-size: 28rpx; | ||||
| } | ||||
|  | ||||
| .icon2 { | ||||
|     color: #8a8a8a; | ||||
|     display: block; | ||||
|     height: 114rpx; | ||||
|     line-height: 114rpx; | ||||
|     text-align: right; | ||||
|     width: 40rpx; | ||||
| } | ||||
|  | ||||
| .relief { | ||||
|     color: #999; | ||||
|     font-size: 24rpx; | ||||
|     padding-top: 30rpx; | ||||
|     text-align: center; | ||||
| } | ||||
|  | ||||
| .center-list-item { | ||||
|     align-items: center; | ||||
|     display: flex; | ||||
|     justify-content: flex-start; | ||||
| } | ||||
|  | ||||
| .icon1 { | ||||
|     height: 30px; | ||||
|     margin-right: 10px; | ||||
|     width: 30px; | ||||
| } | ||||
							
								
								
									
										11
									
								
								pages/payment/payment.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								pages/payment/payment.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| Page({ | ||||
|     data: {}, | ||||
|     onLoad: function(n) {}, | ||||
|     onReady: function() {}, | ||||
|     onShow: function() {}, | ||||
|     onHide: function() {}, | ||||
|     onUnload: function() {}, | ||||
|     onPullDownRefresh: function() {}, | ||||
|     onReachBottom: function() {}, | ||||
|     onShareAppMessage: function() {} | ||||
| }); | ||||
							
								
								
									
										3
									
								
								pages/payment/payment.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								pages/payment/payment.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| { | ||||
|     "usingComponents": {} | ||||
| } | ||||
							
								
								
									
										1
									
								
								pages/payment/payment.wxml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								pages/payment/payment.wxml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| <text>pages/payment/payment.wxml</text> | ||||
							
								
								
									
										0
									
								
								pages/payment/payment.wxss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pages/payment/payment.wxss
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										11
									
								
								pages/users/users.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								pages/users/users.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| Page({ | ||||
|     data: {}, | ||||
|     onLoad: function(n) {}, | ||||
|     onReady: function() {}, | ||||
|     onShow: function() {}, | ||||
|     onHide: function() {}, | ||||
|     onUnload: function() {}, | ||||
|     onPullDownRefresh: function() {}, | ||||
|     onReachBottom: function() {}, | ||||
|     onShareAppMessage: function() {} | ||||
| }); | ||||
							
								
								
									
										3
									
								
								pages/users/users.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								pages/users/users.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| { | ||||
|     "usingComponents": {} | ||||
| } | ||||
							
								
								
									
										1
									
								
								pages/users/users.wxml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								pages/users/users.wxml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| <text>pages/users/users.wxml</text> | ||||
							
								
								
									
										0
									
								
								pages/users/users.wxss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pages/users/users.wxss
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										554
									
								
								pages/video/video.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										554
									
								
								pages/video/video.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,554 @@ | ||||
| var util = require('../../utils/util.js'); // 确保你有这样一个文件 | ||||
| var app = getApp(), | ||||
|   n = ''; | ||||
| Page({ | ||||
|   data: { | ||||
|     dataUrl: '', | ||||
|     dataImage: '', | ||||
|     preview: '', | ||||
|     type: '', | ||||
|     wxid: '', | ||||
|     alias: '', | ||||
|     videoSize: 0, // 初始化视频大小为0 | ||||
|     totalLength: 0, | ||||
|     isExtracting: false, | ||||
|     read_count: 0, | ||||
|  | ||||
|   }, | ||||
|   onLoad: function (options) { | ||||
|     console.log(options) | ||||
|     this.setData({ | ||||
|       dataUrl: decodeURIComponent(options.url), // 视频链接 | ||||
|       dataImage: decodeURIComponent(options.image) || '', // 视频封面 | ||||
|       preview: decodeURIComponent(options.preview), // 视频标题 | ||||
|       type: decodeURIComponent(options.type) || '', // 设置type的值 | ||||
|       wxid: decodeURIComponent(options.wxid) || '', // 设置微信id | ||||
|       alias: decodeURIComponent(options.alias) || '', // 设置微信号 | ||||
|       read_count: decodeURIComponent(options.read_count) || 0, // 设置微信号 | ||||
|     }); | ||||
|     wx.showShareMenu({ | ||||
|       withShareTicket: true, | ||||
|       menus: ['shareAppMessage', 'shareTimeline'] | ||||
|     }) | ||||
|  | ||||
|   }, | ||||
|   onShow: function () { | ||||
|  | ||||
|     app.checkUpdateVersion() | ||||
|     // 页面显示前更新数据 | ||||
|     console.log('执行video.js onShow') | ||||
|     app.getPopupConfig() | ||||
|     .then(() => { | ||||
|       // 从本地缓存读取数据 | ||||
|       const isEnabled = wx.getStorageSync('popupEnabled'); | ||||
|       const popupType = wx.getStorageSync('popupType'); | ||||
|       const popupContent = wx.getStorageSync('popupContent'); | ||||
|  | ||||
|       if (isEnabled) { | ||||
|         this.setData({ | ||||
|           showPopup: true, | ||||
|           popupType: popupType, | ||||
|           popupContent: popupContent | ||||
|         }); | ||||
|       } | ||||
|     }) | ||||
|     .catch((error) => { | ||||
|       console.error('获取弹窗配置失败:', error); | ||||
|     }); | ||||
|     console.log(this.data.type) | ||||
|     app.getUserInfo().then(() => { | ||||
|       console.log('获取用户信息开始'); | ||||
|       console.log(wx.getStorageSync('defaultDailyFreeParseNum'), ) | ||||
|       // 判断type,并发送提取记录到后端 | ||||
|       if (this.data.type === 'weixin' & wx.getStorageSync('defaultDailyFreeParseNum') > 0) { | ||||
|         console.log('来源微信') | ||||
|         this.getVideoSize(decodeURIComponent(this.data.dataUrl)) | ||||
|         //更新次数 | ||||
|       } else { | ||||
|         this.getVideoSize(app.globalData.downloadPrefix + decodeURIComponent(this.data.dataUrl)) | ||||
|       } | ||||
|       console.log('获取用户信息结束'); | ||||
|     }).catch(error => { | ||||
|       console.error('获取用户信息失败:', error); | ||||
|     }).finally(() => { | ||||
|       console.log('getUserInfo调用完成'); | ||||
|     }); | ||||
|     wx.showToast({ | ||||
|       title: '提取成功', | ||||
|       icon: 'success', | ||||
|       duration: 1500, | ||||
|     }); | ||||
|  | ||||
|   }, | ||||
|  | ||||
|   updateExtractingStatus: function (status) { | ||||
|     console.log(status) | ||||
|     this.setData({ | ||||
|       isExtracting: status, | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|  | ||||
|  | ||||
|   getVideoSize: function (url) { | ||||
|     let that = this; | ||||
|     wx.request({ | ||||
|       url: url, | ||||
|       method: 'HEAD', // HEAD请求不会下载资源的body,只请求header信息 | ||||
|       success: function (res) { | ||||
|         if (res.statusCode === 200 && res.header['CONTENT-LENGTH'] || res.header['X-Content-Length']) { | ||||
|           let size = res.header['CONTENT-LENGTH'] || res.header['X-Content-Length']; | ||||
|           let sizeInMb = (size / (1024 * 1024)).toFixed(2); // 将大小转换为MB | ||||
|           that.setData({ | ||||
|             videoSize: sizeInMb, // 更新页面数据, | ||||
|             totalLength: size | ||||
|           }); | ||||
|         } | ||||
|       }, | ||||
|       fail: function (err) { | ||||
|         console.log('获取视频大小失败', err); | ||||
|       } | ||||
|     }); | ||||
|   }, | ||||
|   //复制 | ||||
|   copyUrl: async function () { | ||||
|     if (this.data.type == 'weixin') { | ||||
|       wx.showLoading({ | ||||
|         title: '正在请求复制...', | ||||
|       }); | ||||
|       if (!await this.CreditLimit()) return | ||||
|     } | ||||
|     wx.setClipboardData({ | ||||
|       data: this.data.dataUrl, | ||||
|       success: () => { | ||||
|         wx.showToast({ | ||||
|           title: '复制成功', | ||||
|           duration: 2200, | ||||
|         }); | ||||
|       }, | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   // 扣除额度 | ||||
|   CreditLimit() { | ||||
|     return new Promise((resolve, reject) => { | ||||
|       app.apiRequest({ | ||||
|         url: '/myapp/increment-download-count/', | ||||
|         method: "POST", | ||||
|         data: { | ||||
|           uuid: wx.getStorageSync("uuid"), | ||||
|           openid: wx.getStorageSync("openid") | ||||
|         }, | ||||
|         success: function (e) { | ||||
|           console.log(e, !e.data.success) | ||||
|           if (e.data.success === false) { | ||||
|             wx.hideLoading() | ||||
|             wx.showModal({ | ||||
|               title: "提取视频", | ||||
|               content: '哎呀!去开通会员不限次数使用哦', | ||||
|               confirmColor: "#00B269", | ||||
|               cancelColor: "#858585", | ||||
|               success: function (e) { | ||||
|                 e.confirm ? (console.log("确定"), wx.navigateTo({ | ||||
|                   url: "../vip_recharge/vip_recharge?show=true" | ||||
|                 })) : e.cancel && console.log("取消"); | ||||
|               } | ||||
|             }) | ||||
|             resolve(false) | ||||
|           } | ||||
|           resolve(true) | ||||
|         } | ||||
|       }) | ||||
|     }) | ||||
|   }, | ||||
|   onAdClick: function() { | ||||
|     app.广告(); | ||||
| }, | ||||
|   //提取视频 | ||||
|   download: async function () { | ||||
|     wx.showLoading({ | ||||
|       title: '正在下载...', | ||||
|     }); | ||||
|     if (this.data.type == 'weixin') { | ||||
|       if (!await this.CreditLimit()) return | ||||
|     } | ||||
|     var t = this, | ||||
|       e = t.data.dataUrl; | ||||
|     if (t.data.type === 'index') { | ||||
|       e = app.globalData.downloadPrefix + t.data.dataUrl; // 通过nginx中转 | ||||
|     } else { | ||||
|       e = t.data.dataUrl; | ||||
|     } | ||||
|     // 开始实际的下载任务 | ||||
|     const downloadTask = wx.downloadFile({ | ||||
|       url: e, | ||||
|       success: function (o) { | ||||
|         wx.hideLoading(); | ||||
|         wx.saveVideoToPhotosAlbum({ | ||||
|           filePath: o.tempFilePath, | ||||
|           success: function (o) { | ||||
|             t.showToast('保存成功', 'success'); | ||||
|             setTimeout(function () { | ||||
|               wx.setClipboardData({ | ||||
|                 data: '', | ||||
|               }); | ||||
|               t.goBack(); | ||||
|             }, 1000); | ||||
|           }, | ||||
|           fail: function (o) { | ||||
|             t.showToast('保存失败'); | ||||
|           } | ||||
|         }); | ||||
|       }, | ||||
|       fail: function (o) { | ||||
|         wx.hideLoading(); | ||||
|         t.showToast('下载失败'); | ||||
|       } | ||||
|     }); | ||||
|  | ||||
|     // 监听下载进度并计算百分比 | ||||
|     downloadTask.onProgressUpdate((o) => { | ||||
|       let percent = this.data.totalLength ? (o.totalBytesWritten / this.data.totalLength) * 100 : o.progress; | ||||
|       if (percent < 100) { | ||||
|         wx.showToast({ | ||||
|           title: `保存中 ${Math.round(percent)}%`, | ||||
|           mask: true, // 添加 mask 参数,保证覆盖式显示 | ||||
|           icon: 'loading' | ||||
|         }); | ||||
|       } else { | ||||
|         wx.hideLoading(); // 下载完成后隐藏加载提示 | ||||
|       } | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   // showToast: function (title, icon = 'none') { | ||||
|   //   wx.showToast({ | ||||
|   //     title: title, | ||||
|   //     icon: icon, | ||||
|   //     duration: 2000 | ||||
|   //   }); | ||||
|   // }, | ||||
|  | ||||
|  | ||||
|  | ||||
|   // 保存到相册 | ||||
|   postSave: function () { | ||||
|  | ||||
|     var that = this; | ||||
|     wx.getSetting({ | ||||
|       success(res) { | ||||
|         // 检查用户是否已授权小程序写入相册的权限 | ||||
|         if (res.authSetting['scope.writePhotosAlbum']) { | ||||
|           // 用户已授权,下载视频 | ||||
|           that.download(); | ||||
|         } else { | ||||
|           // 用户未授权,请求相册权限 | ||||
|           wx.authorize({ | ||||
|             scope: 'scope.writePhotosAlbum', | ||||
|             success() { | ||||
|               // 用户授权成功,下载视频 | ||||
|               that.download(); | ||||
|             }, | ||||
|             fail() { | ||||
|               // 用户拒绝授权,显示提示对话框引导用户开启权限 | ||||
|               wx.showModal({ | ||||
|                 title: '提示', | ||||
|                 content: '保存视频到相册需要您授权', | ||||
|                 showCancel: false, | ||||
|                 success(modalRes) { | ||||
|                   if (modalRes.confirm) { | ||||
|                     // 引导用户前往设置页面手动开启权限 | ||||
|                     wx.openSetting({ | ||||
|                       success(settingData) { | ||||
|                         if (settingData.authSetting['scope.writePhotosAlbum']) { | ||||
|                           // 用户在设置页面授权成功,下载视频 | ||||
|                           that.download(); | ||||
|                         } else { | ||||
|                           // 用户最终未授权,可能需要展示一些提示信息 | ||||
|                           wx.showToast({ | ||||
|                             title: '授权失败,无法保存视频', | ||||
|                             icon: 'none' | ||||
|                           }); | ||||
|                         } | ||||
|                       } | ||||
|                     }); | ||||
|                   } | ||||
|                 } | ||||
|               }); | ||||
|             } | ||||
|           }); | ||||
|         } | ||||
|       } | ||||
|     }); | ||||
|  | ||||
|   }, | ||||
|  | ||||
|  | ||||
|   performDownload: function () { | ||||
|     // 在这里实现下载视频并保存到相册的逻辑 | ||||
|     this.download(); | ||||
|   }, | ||||
|  | ||||
|  | ||||
|   removeTimestampAndMergeLines: function (textWithTimestamp) { | ||||
|     let txt = textWithTimestamp.replace(/\[.*\]/g, ""); // 去掉时间前缀 | ||||
|     console.log(txt); | ||||
|     txt = txt.replace(/\s+/g, ""); // 去掉换行、空格字符 | ||||
|     console.log(txt); | ||||
|     return txt; // 删除前后的空白字符并返回 | ||||
|   }, | ||||
|  | ||||
|   // 提取文案功能 | ||||
|   extractText: function () { | ||||
|     // if (this.data.videoSize > 300 || !this.data.videoSize) { | ||||
|     //   wx.showToast({ | ||||
|     //     title: '视频太大,无法提取', | ||||
|     //     icon: 'none' | ||||
|     //   }) | ||||
|     //   return | ||||
|     // } | ||||
|     let openid = wx.getStorageSync('openid') || ''; | ||||
|     let uuid = wx.getStorageSync('uuid') || ''; | ||||
|     let type = this.data.type || ''; | ||||
|     let wxid = this.data.wxid || ''; | ||||
|     let alias = this.data.alias || ''; | ||||
|     let url = this.data.dataUrl; | ||||
|     console.log('文案提取:' + url); | ||||
|     wx.showLoading({ | ||||
|       title: '后台处理中', | ||||
|     }); | ||||
|     var that = this; | ||||
|     app.apiRequest({ | ||||
|       url: '/myapp/video_to_text/', // 后端接口URL,根据实际情况调整 | ||||
|       method: 'POST', | ||||
|       header: { | ||||
|         'content-type': 'application/json', | ||||
|       }, | ||||
|       data: { | ||||
|         url: url, | ||||
|         openid: openid, | ||||
|         uuid: uuid, | ||||
|         type: type, | ||||
|         wxid: wxid, | ||||
|         alias: alias, | ||||
|       }, | ||||
|       success(res) { | ||||
|         if (res.data.success === false) { | ||||
|           wx.showModal({ | ||||
|             title: "提取视频", | ||||
|             content: '哎呀!去开通会员不限次数使用哦', | ||||
|             confirmColor: "#00B269", | ||||
|             cancelColor: "#858585", | ||||
|             success: function (e) { | ||||
|               e.confirm ? (console.log("确定"), wx.navigateTo({ | ||||
|                 url: "../vip_recharge/vip_recharge?show=true" | ||||
|               })) : e.cancel && console.log("取消"); | ||||
|             } | ||||
|           }) | ||||
|           wx.hideLoading() | ||||
|           return | ||||
|         } | ||||
|         let data = res.data; | ||||
|         let taskId = (data?.Data?.TaskId) || data.task_id; | ||||
|         if (data.result) { | ||||
|           wx.hideLoading(); | ||||
|           let text = that.removeTimestampAndMergeLines(data.result); | ||||
|           text = encodeURIComponent(text); | ||||
|           wx.navigateTo({ | ||||
|             url: "../extract/extract?text=" + text + "&type=" + type + "&wxid=" + wxid + "&alias=" + alias, | ||||
|           }); | ||||
|  | ||||
|         } else if (taskId) { | ||||
|           that.search_result(taskId, openid, uuid, type, wxid, alias, (result) => { | ||||
|             wx.hideLoading(); | ||||
|             console.log('处理查询结果:', result); | ||||
|             if (result != 0) { | ||||
|               wx.showToast({ | ||||
|                 title: '提取成功', | ||||
|                 icon: 'success' | ||||
|               }); | ||||
|  | ||||
|               let text = that.removeTimestampAndMergeLines(result); | ||||
|               text = encodeURIComponent(text); | ||||
|               wx.navigateTo({ | ||||
|                 url: "../extract/extract?text=" + text + "&type=" + type + "&wxid=" + wxid + "&alias=" + alias, | ||||
|               }); | ||||
|             } else { | ||||
|               wx.showToast({ | ||||
|                 title: '异常', | ||||
|                 icon: 'error' | ||||
|               }); | ||||
|             } | ||||
|           }); | ||||
|         } else { | ||||
|           wx.showToast({ | ||||
|             title: '发送文件失败', | ||||
|             icon: 'none' | ||||
|           }); | ||||
|         } | ||||
|       }, | ||||
|       fail(err) { | ||||
|         wx.hideLoading(); | ||||
|         wx.showToast({ | ||||
|           title: '网络异常', | ||||
|           icon: 'none' | ||||
|         }); | ||||
|       } | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   // 查询任务状态 | ||||
|   search_result: function (task_id, openid, uuid, type, wxid, alias, handleResult) { | ||||
|     console.log('查询任务'); | ||||
|     const checkResult = (maxRetries) => { | ||||
|       const fetchTaskStatus = () => { | ||||
|         app.apiRequest({ | ||||
|           url: '/myapp/query_task/', | ||||
|           method: 'POST', | ||||
|           header: { | ||||
|             'content-type': 'application/json', | ||||
|           }, | ||||
|           data: { | ||||
|             task_id: task_id, | ||||
|             openid: openid, | ||||
|             uuid: uuid, | ||||
|             type: type, | ||||
|             wxid: wxid, | ||||
|             alias: alias, | ||||
|           }, | ||||
|           success: function (res) { | ||||
|             const data = res.data; | ||||
|             console.log('查询任务:', data) | ||||
|             if (data.result) { | ||||
|               handleResult(data.result); | ||||
|             } else if (maxRetries > 0) { | ||||
|               setTimeout(fetchTaskStatus, 3000); // 每3秒查询一次 | ||||
|               maxRetries--; | ||||
|             } else { | ||||
|               wx.hideLoading(); | ||||
|               wx.showToast({ | ||||
|                 title: '请稍重试', | ||||
|                 icon: 'error' | ||||
|               }); | ||||
|               handleResult(0); | ||||
|               console.log('已达到最大重试次数,停止查询。'); | ||||
|             } | ||||
|           }, | ||||
|         }); | ||||
|       }; | ||||
|       fetchTaskStatus(); // 启动任务状态查询 | ||||
|     }; | ||||
|  | ||||
|     const maxRetries = 100; | ||||
|     checkResult(maxRetries); | ||||
|   }, | ||||
|  | ||||
|   // 去掉时间戳并合并行 | ||||
|   removeTimestampAndMergeLines: function (textWithTimestamp) { | ||||
|     let txt = textWithTimestamp.replace(/\[.*\]/g, ""); // 去掉时间前缀 | ||||
|     console.log(txt); | ||||
|     txt = txt.replace(/\s+/g, ""); // 去掉换行、空格字符 | ||||
|     console.log(txt); | ||||
|     return txt; // 删除前后的空白字符并返回 | ||||
|   }, | ||||
|  | ||||
|   // 更新提取状态 | ||||
|   updateExtractingStatus: function (status) { | ||||
|     this.setData({ | ||||
|       extracting: status | ||||
|     }); | ||||
|   }, | ||||
|   onUnload: function () { | ||||
|     console.log('页面卸载'); | ||||
|   }, | ||||
|   goBack: function () { | ||||
|     wx.reLaunch({ | ||||
|       url: '/pages/index/index', | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   showToast: function (title, icon = 'none', duration = 2000) { | ||||
|     wx.showToast({ | ||||
|       title: title, | ||||
|       icon: icon, | ||||
|       duration: duration | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|  | ||||
|   onShareAppMessage: function () { | ||||
|     return { | ||||
|       title: '推荐一款免费又超好用的视频文案创作工具,分享给大家一起使用', | ||||
|       path: '/pages/index/index?uuid=' + wx.getStorageSync('uuid'), | ||||
|       imageUrl: '/images/1.png', | ||||
|       success: function (e) { | ||||
|         wx.showToast({ | ||||
|           title: "分享成功", | ||||
|           icon: "success", | ||||
|           duration: 2e3 | ||||
|         }); | ||||
|       }, | ||||
|       fail: function (e) { | ||||
|         wx.showToast({ | ||||
|           title: "分享失败", | ||||
|           icon: "none", | ||||
|           duration: 2e3 | ||||
|         }); | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   onShareTimeline: function () { | ||||
|     return { | ||||
|       title: '推荐一款免费又超好用的视频文案创作工具,分享给大家一起使用', | ||||
|       path: '/pages/index/index?uuid=' + wx.getStorageSync('uuid'), | ||||
|       imageUrl: '/images/1.png', | ||||
|       success: function (e) { | ||||
|         wx.showToast({ | ||||
|           title: "分享成功", | ||||
|           icon: "success", | ||||
|           duration: 2e3 | ||||
|         }); | ||||
|       }, | ||||
|       fail: function (e) { | ||||
|         wx.showToast({ | ||||
|           title: "分享失败", | ||||
|           icon: "none", | ||||
|           duration: 2e3 | ||||
|         }); | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|  | ||||
|   // 发送提取记录到后端的方法  | ||||
|   sendExtractionRecordToBackend: function (e) { | ||||
|     const { | ||||
|       dataUrl, | ||||
|       dataImage, | ||||
|       preview, | ||||
|       wxid, | ||||
|       alias | ||||
|     } = this.data; | ||||
|     app.apiRequest({ | ||||
|       url: '/myapp/record_extraction/', // 后端接口URL | ||||
|       method: 'POST', | ||||
|       data: { | ||||
|         openid: wx.getStorageSync('openid'), | ||||
|         uuid: wx.getStorageSync('uuid'), | ||||
|         videoUrl: dataUrl, | ||||
|         videoTitle: preview, | ||||
|         wxid: wxid, | ||||
|         wechatAlias: alias, | ||||
|         type: e || 'weixin' | ||||
|       }, | ||||
|       success(res) { | ||||
|         console.log('提取记录发送成功', res); | ||||
|         // 可以在这里处理后端返回的响应 | ||||
|       }, | ||||
|       fail(err) { | ||||
|         console.error('提取记录发送失败', err); | ||||
|         // 错误处理 | ||||
|       } | ||||
|     }); | ||||
|   }, | ||||
| }); | ||||
							
								
								
									
										10
									
								
								pages/video/video.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								pages/video/video.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| { | ||||
|   "navigationBarTitleText": "视频提取浏览", | ||||
|   "navigationBarBackgroundColor": "#222238", | ||||
|   "navigationBarTextStyle": "white", | ||||
|   "component": true, | ||||
|   "custom-tab-bar": "/custom-tab-bar/index", | ||||
|   "usingComponents": { | ||||
|     "popup": "/popup/popup" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										28
									
								
								pages/video/video.wxml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								pages/video/video.wxml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| <view class="wrap"> | ||||
|     <textarea autoHeight class="video-title" value="{{preview}}"></textarea> | ||||
|     <video class="video-box" poster="{{dataImage}}" src="{{dataUrl}}" wx:if="{{dataUrl!=''}}"></video> | ||||
|     <image class="video-box" src="{{dataImage}}" wx:else></image> | ||||
|     <view style="font-size: 10px; text-align: center; color: #a790e2;font-size: 15px;">视频太大的建议复制地址到浏览器自行下载</view> | ||||
|     <view style="font-size: 10px; text-align: center;color: #a790e2;font-size: 15px;">保存失败的也复制链接到浏览器下载</view> | ||||
|     <view style="width: 100%;"></view> | ||||
|     <view class="buttons-row"> | ||||
|         <button bindgetuserinfo="postSave" class="parsing" openType="getUserInfo">保存到相册</button> | ||||
|         <button bindtap="copyUrl" class="parsing copy-url">复制地址</button> | ||||
|     </view> | ||||
|     <view class="buttons-row"> | ||||
|         <button bindtap="extractText" class="parsing extract-text" data-url="{{dataUrl}}" disabled="{{isExtracting}}">视频文案提取</button> | ||||
|         <button bindtap="goBack" class="parsing go-back">返回首页</button> | ||||
|     </view> | ||||
|     <view class="center" style="color: #a790e2; margin-top: 10px;font-size: 13px;">版权归视频原作者所有</view> | ||||
|     <!-- <view bindtap="onAdClick" class="advertisement"> | ||||
|         <image src="https://file.guimiaokeji.com/kecheng.png"></image> | ||||
|     </view> --> | ||||
| </view> | ||||
|  | ||||
| <popup  | ||||
|   wx:if="{{showPopup}}" | ||||
|   popupType="{{popupType}}"  | ||||
|   popupContent="{{popupContent}}"  | ||||
|   buttonText="查看详情"  | ||||
|   targetUrl="/pages/details/details" | ||||
| /> | ||||
							
								
								
									
										89
									
								
								pages/video/video.wxss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								pages/video/video.wxss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | ||||
| page { | ||||
|     background-color: #222238; | ||||
|     border-top: 1px solid hsla(0,31%,87%,.5); | ||||
| } | ||||
|  | ||||
| .wrap { | ||||
|     align-items: center; | ||||
|     flex-direction: column; | ||||
| } | ||||
|  | ||||
| .buttons-row,.wrap { | ||||
|     display: flex; | ||||
| } | ||||
|  | ||||
| .buttons-row { | ||||
|     justify-content: space-around; | ||||
|     margin-top: 20rpx; | ||||
|     width: 100%; | ||||
| } | ||||
|  | ||||
| .video-box { | ||||
|     display: block; | ||||
|     height: 700rpx; | ||||
|     margin: 40rpx auto; | ||||
|     width: 560rpx; | ||||
| } | ||||
|  | ||||
| .video-title { | ||||
|     word-wrap: break-word; | ||||
|     background-color: #333; | ||||
|     color: #a790e2; | ||||
|     height: 50px; | ||||
|     margin-top: 10px; | ||||
|     padding: 8px; | ||||
|     user-select: text; | ||||
|     white-space: pre-wrap; | ||||
|     width: 90%; | ||||
| } | ||||
|  | ||||
| .parsing { | ||||
|     background: linear-gradient(90deg,#6949bb,#4052ca); | ||||
|     box-shadow: 0 14rpx 28rpx rgba(51,122,255,.3); | ||||
|     color: #fff; | ||||
|     display: inline-block; | ||||
|     height: 88rpx; | ||||
|     line-height: 88rpx; | ||||
|     overflow: hidden; | ||||
|     text-align: center; | ||||
|     width: 320rpx; | ||||
| } | ||||
|  | ||||
| .copy-url,.extract-text { | ||||
|     background: linear-gradient(90deg,#6949bb,#4d65fd); | ||||
| } | ||||
|  | ||||
| .go-back { | ||||
|     background-color: #f8f8f8; | ||||
|     color: #fff; | ||||
| } | ||||
|  | ||||
| .video-title-textarea { | ||||
|     background-color: #f8f8f8; | ||||
|     border: 1px solid #ccc; | ||||
|     border-radius: 5rpx; | ||||
|     color: #333; | ||||
|     display: block; | ||||
|     font-size: 20rpx; | ||||
|     height: 80rpx; | ||||
|     line-height: 1.5; | ||||
|     margin: 20rpx auto; | ||||
|     padding: 15rpx; | ||||
|     resize: none; | ||||
|     width: 90%; | ||||
| } | ||||
|  | ||||
| .read_count { | ||||
|     color: blue; | ||||
|     font-size: 1rem; | ||||
| } | ||||
|  | ||||
| .advertisement { | ||||
|     margin: 5px 0; | ||||
|     width: 100%; | ||||
|     z-index: 9999; | ||||
| } | ||||
|  | ||||
| .advertisement image { | ||||
|     width: 100%; | ||||
| } | ||||
							
								
								
									
										328
									
								
								pages/video_list/video_list.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										328
									
								
								pages/video_list/video_list.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,328 @@ | ||||
| const app = getApp(); | ||||
|  | ||||
| Page({ | ||||
|   data: { | ||||
|     inputValue: '',          // 输入框的内容 | ||||
|     detectResult: '',        // 识别结果 | ||||
|     detectType: 'text',      // 默认识别类型为文本 | ||||
|     maxLength: 20000,        // 最大允许的字节数 | ||||
|     inputLength: 0,          // 当前输入的字节数 | ||||
|     task_id: '',             // 任务ID | ||||
|     detectButtonDisabled: false,  // 文本检测按钮是否禁用 | ||||
|     modifyButtonDisabled: false   // 智能修改按钮是否禁用 | ||||
|   }, | ||||
|  | ||||
|   onLoad: function(e) { | ||||
|     wx.showShareMenu({ | ||||
|       withShareTicket: true, | ||||
|       menus: ["shareAppMessage", "shareTimeline"] | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   onShow: function() { | ||||
|     var t = this; | ||||
|     t.resetData() | ||||
|     app.getCurrentTabbar(2, this); | ||||
|     app.checkUpdateVersion(); | ||||
|     app.getUserInfo().then(() => { | ||||
|       console.log('获取用户信息完成'); | ||||
|       console.log(wx.getStorageSync('defaultDailyFreeParseNum')); | ||||
|       const rewrittenText = wx.getStorageSync('rewrittenText');  // 从缓存中获取存储的文案 | ||||
|       if (rewrittenText) { | ||||
|         this.setData({ | ||||
|           inputValue: rewrittenText  // 设置到页面的数据中 | ||||
|         }); | ||||
|         wx.removeStorageSync('rewrittenText');  // 清除数据,避免下次重复加载 | ||||
|         wx.showToast({ | ||||
|           title: '点击开始检测按钮检测文本违规词。', | ||||
|           icon: 'none' | ||||
|         }); | ||||
|       } | ||||
|  | ||||
|     }).catch(error => { | ||||
|       console.error('获取用户信息失败:', error); | ||||
|     }).finally(() => { | ||||
|       console.log('getUserInfo调用完成'); | ||||
|     }); | ||||
|   }, | ||||
|   resetData: function() { | ||||
|     // 重置页面数据为默认值 | ||||
|     this.setData({ | ||||
|       inputValue: '',          // 输入框的内容 | ||||
|       detectResult: '',        // 识别结果 | ||||
|       detectType: 'text',      // 默认识别类型为文本 | ||||
|       inputLength: 0,          // 当前输入的字节数 | ||||
|       task_id: '',             // 任务ID | ||||
|       detectButtonDisabled: false,  // 文本检测按钮是否禁用 | ||||
|       modifyButtonDisabled: false   // 智能修改按钮是否禁用 | ||||
|     }); | ||||
|   }, | ||||
|   // 切换识别类型 | ||||
|   switchDetectType(e) { | ||||
|     const detectType = e.currentTarget.dataset.type; | ||||
|     this.recordClick(detectType); | ||||
|     this.setData({ | ||||
|       detectType, | ||||
|       detectResult: '' // 切换时清空结果 | ||||
|     }); | ||||
|  | ||||
|     if (detectType === 'audio' || detectType === 'video') { | ||||
|       wx.showToast({ | ||||
|         title: '该功能正在开发中', | ||||
|         icon: 'none' | ||||
|       }); | ||||
|     } else { | ||||
|       wx.showToast({ | ||||
|         title: '切换到文本识别', | ||||
|         icon: 'none' | ||||
|       }); | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   // 文本识别函数 | ||||
|   detectText() { | ||||
|     const { inputValue, maxLength } = this.data; | ||||
|     const byteSize = this.getByteLength(inputValue); | ||||
|  | ||||
|     // 检查文本是否为空或长度过短 | ||||
|     if (!inputValue.trim() || this.getByteLength(inputValue) < 10) { | ||||
|       wx.showToast({ | ||||
|         title: '请输入有效的文本', | ||||
|         icon: 'none' | ||||
|       }); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     // 超出字节长度检测 | ||||
|     if (byteSize > maxLength) { | ||||
|       wx.showToast({ | ||||
|         title: `内容不能超过 ${maxLength} 字节`, | ||||
|         icon: 'none' | ||||
|       }); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     // 禁用检测按钮 | ||||
|     this.setData({ detectButtonDisabled: true }); | ||||
|  | ||||
|     wx.showLoading({ | ||||
|       title: '正在检测...', | ||||
|     }); | ||||
|  | ||||
|     // 调用后端审核接口 | ||||
|     app.apiRequest({ | ||||
|       url: '/myapp/text_review/', | ||||
|       method: 'POST', | ||||
|       data: { | ||||
|         text: inputValue, | ||||
|         openid: wx.getStorageSync('openid'), | ||||
|         nickname: wx.getStorageSync('uuid') | ||||
|       }, | ||||
|       success: (res) => { | ||||
|         wx.hideLoading(); | ||||
|         this.setData({ detectButtonDisabled: false });  // 启用检测按钮 | ||||
|         if (res.data.code === 200) { | ||||
|           // 审核成功 | ||||
|           this.setData({ | ||||
|             detectResult: res.data.data.result, | ||||
|             task_id: res.data.task_id | ||||
|           }); | ||||
|           console.log(res.data.data.result); | ||||
|           wx.showToast({ | ||||
|             title: '检测成功', | ||||
|             icon: 'success' | ||||
|           }); | ||||
|           if (res.data.data.result.conclusion === '不合规') { | ||||
|             wx.showModal({ | ||||
|               title: "提示", | ||||
|               content: "检测结果不合规,是否使用智能合规功能一键修改文案?", | ||||
|               confirmText: "一键修改", | ||||
|               cancelText: "取消", | ||||
|               success: (modalRes) => { | ||||
|                 if (modalRes.confirm) { | ||||
|                   this.modifyContent();  // 调用一键合规函数 | ||||
|                 } | ||||
|               } | ||||
|             }); | ||||
|           } | ||||
|         } else if (res.data.code === 400 && res.data.message === '余额不足') { | ||||
|           // 积分不足,提示充值 | ||||
|           wx.showModal({ | ||||
|             title: "检测文本", | ||||
|             content: '创意点不足!', | ||||
|             confirmColor: "#00B269", | ||||
|             cancelColor: "#858585", | ||||
|             success: function(e) { | ||||
|               if (e.confirm) { | ||||
|                 console.log("确定"); | ||||
|                 wx.navigateTo({ | ||||
|                   url: "../vip_recharge/vip_recharge?show=true" | ||||
|                 }); | ||||
|               } else { | ||||
|                 console.log("取消"); | ||||
|               } | ||||
|             } | ||||
|           }); | ||||
|         } else { | ||||
|           // 其他失败情况 | ||||
|           wx.showToast({ | ||||
|             title: res.data.message || '检测失败,请稍后重试', | ||||
|             icon: 'none' | ||||
|           }); | ||||
|         } | ||||
|       }, | ||||
|       fail: (err) => { | ||||
|         wx.hideLoading(); | ||||
|         this.setData({ detectButtonDisabled: false });  // 启用检测按钮 | ||||
|         console.error('请求失败:', err); | ||||
|         wx.showToast({ | ||||
|           title: '网络异常,请稍后重试', | ||||
|           icon: 'none' | ||||
|         }); | ||||
|       } | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   // 计算文本的字节长度(区分中英文) | ||||
|   getByteLength(text) { | ||||
|     return text.replace(/[^\x00-\xff]/g, 'aa').length; | ||||
|   }, | ||||
|  | ||||
|   // 处理输入框内容变化 | ||||
|   bindInput(e) { | ||||
|     const inputValue = e.detail.value; | ||||
|     const inputLength = this.getByteLength(inputValue); | ||||
|  | ||||
|     // 更新输入内容和字节长度 | ||||
|     this.setData({ | ||||
|       inputValue, | ||||
|       inputLength | ||||
|     }); | ||||
|  | ||||
|     // 如果字数超出最大限制,提示用户 | ||||
|     if (inputLength > this.data.maxLength) { | ||||
|       wx.showToast({ | ||||
|         title: `已超出 ${this.data.maxLength} 字节`, | ||||
|         icon: 'none' | ||||
|       }); | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   // 复制内容 | ||||
|   copyContent() { | ||||
|     wx.setClipboardData({ | ||||
|       data: this.data.inputValue, | ||||
|       success() { | ||||
|         wx.showToast({ | ||||
|           title: '内容已复制', | ||||
|           icon: 'none' | ||||
|         }); | ||||
|       } | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   // 清空输入框内容 | ||||
|   clearInput() { | ||||
|     wx.showModal({ | ||||
|       title: "提示", | ||||
|       content: "确定要清空所有内容吗?", | ||||
|       success: (res) => { | ||||
|         if (res.confirm) { | ||||
|           this.setData({ | ||||
|             inputValue: '', | ||||
|             inputLength: 0, | ||||
|             detectResult: '' | ||||
|           }); | ||||
|           wx.showToast({ | ||||
|             title: '已清空内容', | ||||
|             icon: 'none' | ||||
|           }); | ||||
|         } | ||||
|       } | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   // 调用智能修改(AI合规) | ||||
|   modifyContent() { | ||||
|     // 禁用智能修改按钮 | ||||
|     this.setData({ modifyButtonDisabled: true }); | ||||
|  | ||||
|     wx.showLoading({ | ||||
|       title: '正在修改...', | ||||
|     }); | ||||
|  | ||||
|     app.apiRequest({ | ||||
|       url: '/myapp/ai_modify_text/', | ||||
|       method: 'POST', | ||||
|       data: { | ||||
|         task_id: this.data.task_id, | ||||
|         openid: wx.getStorageSync('openid') | ||||
|       }, | ||||
|       success: (res) => { | ||||
|         wx.hideLoading(); | ||||
|         this.setData({ modifyButtonDisabled: false });  // 启用智能修改按钮 | ||||
|         if (res.data.code === 200) { | ||||
|           // 修改成功 | ||||
|           this.setData({ | ||||
|             inputValue: res.data.data.modified_text, | ||||
|             detectResult: '' // 清空检测结果 | ||||
|           }); | ||||
|           wx.showToast({ | ||||
|             title: '修改成功', | ||||
|             icon: 'success' | ||||
|           }); | ||||
|         }else if (res.data.code === 400 && res.data.message === '积分不足,请充值') { | ||||
|           // 积分不足,提示用户充值并引导 | ||||
|           wx.showModal({ | ||||
|             title: "提示", | ||||
|             content: "您的积分不足,无法进行智能修改,请充值后再尝试。", | ||||
|             confirmText: "去充值", | ||||
|             cancelText: "取消", | ||||
|             success: (modalRes) => { | ||||
|               if (modalRes.confirm) { | ||||
|                 wx.navigateTo({ | ||||
|                   url: "../vip_recharge/vip_recharge?show=true" | ||||
|                 }); | ||||
|               } | ||||
|             } | ||||
|           }); | ||||
|         } else { | ||||
|           // 其他失败情况 | ||||
|           wx.showToast({ | ||||
|             title: res.data.message || '修改失败,请稍后重试', | ||||
|             icon: 'none' | ||||
|           }); | ||||
|         } | ||||
|       }, | ||||
|       fail: (err) => { | ||||
|         wx.hideLoading(); | ||||
|         this.setData({ modifyButtonDisabled: false });  // 启用智能修改按钮 | ||||
|         console.error('请求失败:', err); | ||||
|         wx.showToast({ | ||||
|           title: '网络异常,请稍后重试', | ||||
|           icon: 'none' | ||||
|         }); | ||||
|       } | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   // 记录点击的功能类型 | ||||
|   recordClick(functionClicked) { | ||||
|     app.apiRequest({ | ||||
|       url: `/myapp/record_click/`, // 点击统计接口 | ||||
|       method: 'POST', | ||||
|       data: { | ||||
|         openid: wx.getStorageSync('openid'), | ||||
|         nickname: wx.getStorageSync('uuid'), | ||||
|         function_clicked: functionClicked | ||||
|       }, | ||||
|       header: { | ||||
|         'content-type': 'application/json' | ||||
|       }, | ||||
|       success: (res) => { | ||||
|  | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|  | ||||
| }); | ||||
							
								
								
									
										7
									
								
								pages/video_list/video_list.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								pages/video_list/video_list.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| { | ||||
|   "navigationBarTitleText": "违规词识别", | ||||
|   "navigationBarBackgroundColor": "#222238", | ||||
|   "navigationBarTextStyle": "white", | ||||
|   "component": true, | ||||
|   "custom-tab-bar": "/custom-tab-bar/index" | ||||
| } | ||||
							
								
								
									
										85
									
								
								pages/video_list/video_list.wxml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								pages/video_list/video_list.wxml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| <view class="container"> | ||||
|   <!-- 顶部按钮组 --> | ||||
|   <view class="header"> | ||||
|     <view class="button-group"> | ||||
|       <button class="detect-button active" data-type="text" bindtap="switchDetectType">文本识别</button> | ||||
|       <button class="detect-button" data-type="audio" bindtap="switchDetectType">音频识别</button> | ||||
|       <button class="detect-button" data-type="video" bindtap="switchDetectType">视频识别</button> | ||||
|     </view> | ||||
|   </view> | ||||
|  | ||||
|   <!-- 输入框区域 --> | ||||
|   <view class="input-area"> | ||||
|    | ||||
|     <textarea class="input-field"  | ||||
|       bindinput="bindInput"  | ||||
|       value="{{inputValue}}"  | ||||
|       placeholder-class="b-palceholder"  | ||||
|       placeholder="输入或粘贴文本,自动识别违规内容并智能修改..."  | ||||
|       maxlength="20000"> | ||||
|     </textarea> | ||||
|  | ||||
|     <!-- 字数统计及提示信息 --> | ||||
|     <view class="text-counter"> | ||||
|       <text>{{inputLength}} / {{maxLength}}</text> | ||||
|       <text wx:if="{{inputLength > maxLength}}" class="error-text">内容不能超过 {{maxLength}} 字节</text> | ||||
|     </view> | ||||
|  | ||||
|     <!-- 操作按钮 第一行:检测和智能修改 --> | ||||
|     <view class="button-group"> | ||||
|       <button class="detect-button" disabled="{{detectButtonDisabled}}"     bindtap="detectText">开始检测</button> | ||||
|       <button class="modify-button"  disabled="{{modifyButtonDisabled}}" bindtap="modifyContent">一键合规</button> | ||||
|     </view> | ||||
|  | ||||
|     <!-- 操作按钮 第二行:复制和清空 --> | ||||
|     <view class="button-group"> | ||||
|       <button class="copy-button" bindtap="copyContent">复制内容</button> | ||||
|       <button class="clear-button" bindtap="clearInput">清空输入</button> | ||||
|     </view> | ||||
|     <view class="disclaimer"> | ||||
|   <text>单次消耗3创意点。检测中请勿退出本页面,很快完成</text> | ||||
|   </view> | ||||
|   </view> | ||||
|  | ||||
|   <view class="report-container" wx:if="{{detectResult}}"> | ||||
|   <!-- 报告标题 --> | ||||
|   <view class="report-title">检测报告</view> | ||||
|    | ||||
|   <!-- 检测结果 --> | ||||
|   <view class="result-summary"> | ||||
|     <text class="{{detectResult.conclusion === '合规' ? 'compliant' : 'non-compliant'}}"> | ||||
|       检测结果: {{detectResult.conclusion}} | ||||
|     </text> | ||||
|   </view> | ||||
|  | ||||
|   <!-- 表格 --> | ||||
|   <view class="result-table"> | ||||
|     <!-- 表头 --> | ||||
|     <view class="table-row table-header"> | ||||
|       <view class="table-cell">疑似命中</view> | ||||
|       <view class="table-cell">关键词</view> | ||||
|       <view class="table-cell">字符位置</view> | ||||
|       <view class="table-cell">置信度</view> | ||||
|     </view> | ||||
|  | ||||
|     <!-- 表格内容 --> | ||||
|     <block wx:for="{{detectResult.data}}" wx:key="index"> | ||||
|       <view class="table-row"> | ||||
|         <view class="table-cell">{{item.reason}}</view> | ||||
|         <view class="table-cell">{{item.keyword}}</view> | ||||
|         <view class="table-cell">{{item.position}}</view> | ||||
|         <view class="table-cell">{{item.confidence}}</view> | ||||
|       </view> | ||||
|     </block> | ||||
|   </view> | ||||
|  | ||||
|   <!-- 设置底部间距 --> | ||||
|   <view class="bottom-space"></view> | ||||
|   <view class="disclaimer"> | ||||
|   <text>功能介绍:本功能用于检测文本中可能存在的违规内容,帮助用户规避潜在风险。\n</text> | ||||
|   <text>免责声明:本检测结果仅供参考,具体结果请以实际情况为准,平台不承担由此产生的任何法律责任。</text> | ||||
|   </view> | ||||
| </view> | ||||
|  | ||||
|  | ||||
| </view> | ||||
							
								
								
									
										204
									
								
								pages/video_list/video_list.wxss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								pages/video_list/video_list.wxss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,204 @@ | ||||
| page { | ||||
|   background-color: #222238; | ||||
|   border-top: 1px solid hsla(0,31%,87%,.5); | ||||
| } | ||||
|  | ||||
| .container { | ||||
|   align-items: center; | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   padding: 20px; | ||||
| } | ||||
|  | ||||
| .header { | ||||
|   display: flex; | ||||
|   justify-content: space-around; | ||||
|   margin-bottom: 20px; | ||||
|   width: 100%; | ||||
| } | ||||
|  | ||||
| .button-group { | ||||
|   display: flex; | ||||
|   width: 100%; | ||||
|   justify-content: space-around; | ||||
| } | ||||
|  | ||||
| .detect-button{ | ||||
|   width: 30%; | ||||
|   height: 35px; | ||||
|   font-size: 12px; | ||||
|   line-height: 35px; | ||||
|   background: linear-gradient(90deg, #8d72d2, #7183f3); | ||||
|   border-radius: 5px; | ||||
|   text-align: center; | ||||
|   color: white; | ||||
|   box-shadow: 0 4px 10px rgba(141, 114, 210, 0.4); | ||||
|   transition: background 0.3s, transform 0.3s; | ||||
| } | ||||
|  | ||||
| .detect-button:hover { | ||||
|   background: linear-gradient(90deg, #664da5, #4e66d8); | ||||
|    | ||||
| } | ||||
|  | ||||
| .active { | ||||
|   border: 1px solid #fff; | ||||
| } | ||||
|  | ||||
| .input-area { | ||||
|   width: 100%; | ||||
|   background-color: #222238; | ||||
|   box-shadow: 0 4px 10px rgba(141, 114, 210, 0.4); | ||||
|   padding: 20px; | ||||
|   box-sizing: border-box; | ||||
|   border-radius: 10px; | ||||
|   margin-bottom: 20px; | ||||
| } | ||||
|  | ||||
| .input-field { | ||||
|   background: #33334c; | ||||
|   color: #a790e2; | ||||
|   padding: 15px; | ||||
|   box-sizing: border-box; | ||||
|   border-radius: 5px; | ||||
|   width: 100%; | ||||
|   height: 230px; | ||||
|   border: 1px solid #a790e2; | ||||
|   outline: none; | ||||
|   resize: none; | ||||
|   font-size: 14px; | ||||
| } | ||||
|  | ||||
| .input-field:hover { | ||||
|   border-color: #fff; | ||||
| } | ||||
|  | ||||
| .button-group { | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   margin-top: 10px; | ||||
| } | ||||
|  | ||||
| .copy-button, .modify-button ,.detect-button, .clear-button{ | ||||
|   width: 30%; | ||||
|  | ||||
|   box-sizing: border-box; | ||||
|   background: linear-gradient(90deg, #8d72d2, #7183f3); | ||||
|   border-radius: 5px; | ||||
|   text-align: center; | ||||
|   color: white; | ||||
|   font-size: 14px; | ||||
|  | ||||
|   box-shadow: 0 4px 10px rgba(141, 114, 210, 0.4); | ||||
|   transition: background 0.3s, transform 0.3s; | ||||
| } | ||||
|  | ||||
| .copy-button:hover, .modify-button:hover { | ||||
|   background: linear-gradient(90deg, #664da5, #4e66d8); | ||||
|   transform: translateY(-2px); | ||||
| } | ||||
|  | ||||
| .result-area { | ||||
|   margin-top: 20px; | ||||
|   background: linear-gradient(135deg, #a3a3df, #eaeaf5); /* 浅色渐变背景 */ | ||||
|   width: 90%; | ||||
|   padding: 15px; | ||||
|   border-radius: 10px; | ||||
|   box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1); /* 添加轻微阴影效果 */ | ||||
|   margin-bottom: 20px; | ||||
|   border: 1px solid #ddd; /* 增加边框 */ | ||||
| } | ||||
| .text-counter{ | ||||
|   font-size: 12px; | ||||
|   color: white; | ||||
|   text-align: left; | ||||
|   margin:2px; | ||||
| } | ||||
| .error-text { | ||||
|   color: red; | ||||
|   margin-left: 60px; | ||||
| } | ||||
|  | ||||
| /* 报告容器样式 */ | ||||
| .report-container { | ||||
|   width: 95%; | ||||
|   background-color: #f5f8ff; | ||||
|   padding: 20rpx; | ||||
|   border-radius: 15rpx; | ||||
|   box-shadow: 0rpx 5rpx 15rpx rgba(0, 0, 0, 0.1); | ||||
|   margin-top: 20rpx; | ||||
|   margin-bottom: 45px; | ||||
| } | ||||
|  | ||||
| /* 标题样式 */ | ||||
| .report-title { | ||||
|   font-size: 36rpx; | ||||
|   color: #333; | ||||
|   font-weight: bold; | ||||
|   text-align: center; | ||||
|   margin-bottom: 2rpx; | ||||
| } | ||||
|  | ||||
| /* 检测结果样式 */ | ||||
| .result-summary { | ||||
|   font-size: 28rpx; | ||||
|   color: #666; | ||||
|   margin-bottom: 20rpx; | ||||
|   text-align: center; | ||||
| } | ||||
|  | ||||
| /* 合规与不合规文本样式 */ | ||||
| .compliant { | ||||
|   color: #00b269; /* 绿色 */ | ||||
| } | ||||
|  | ||||
| .non-compliant { | ||||
|   color: #ff4d4f; /* 红色 */ | ||||
| } | ||||
|  | ||||
| /* 表格样式 */ | ||||
| .result-table { | ||||
|   width: 100%; | ||||
|   border-collapse: collapse; | ||||
| } | ||||
|  | ||||
| /* 表格行样式 */ | ||||
| .table-row { | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   padding: 10rpx 0; | ||||
|   border-bottom: 1rpx solid #eaeaea; | ||||
| } | ||||
|  | ||||
| /* 表格头部样式 */ | ||||
| .table-header { | ||||
|   font-weight: bold; | ||||
|   background-color: #eef1f8; | ||||
|   padding: 10rpx 0; | ||||
|   text-align: center; | ||||
| } | ||||
|  | ||||
| /* 表格单元格样式 */ | ||||
| .table-cell { | ||||
|   flex: 1; | ||||
|   text-align: center; | ||||
|   font-size: 26rpx; | ||||
|   color: #333; | ||||
|   padding: 10rpx 0; | ||||
| } | ||||
|  | ||||
| /* 底部空白区 */ | ||||
| .bottom-space { | ||||
|   height: 50rpx; | ||||
| } | ||||
|  | ||||
| /* Disclaimer styling */ | ||||
| .disclaimer { | ||||
|   margin-top: 20rpx; | ||||
|   padding: 10rpx; | ||||
|   color: #999; | ||||
|   font-size: 22rpx; /* 小号字体 */ | ||||
|   text-align: center; | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										187
									
								
								pages/vip_recharge/vip_recharge.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								pages/vip_recharge/vip_recharge.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,187 @@ | ||||
| var e = getApp(); | ||||
|  | ||||
| Page({ | ||||
|     data: { | ||||
|         isVip: false, | ||||
|         startTime: "--", | ||||
|         endTime: "--", | ||||
|         selectedType: null, | ||||
|         cards: [], | ||||
|         isQuota: false, | ||||
|         show: false, | ||||
|         isIOS: false, // 是否为 iOS 系统 | ||||
|     }, | ||||
|     onLoad: function (e) { | ||||
|       const that = this; | ||||
|       getApp().check_status() | ||||
|           .then(function(res) { | ||||
|               that.setData({ | ||||
|                   show: res.data.data.show | ||||
|               }); | ||||
|               if (!that.data.show) { | ||||
|                 wx.showModal({ | ||||
|                     title: "提示", | ||||
|                     content: "iOS 暂时无法使用此功能,请稍后再试。", | ||||
|                     showCancel: false, | ||||
|                     confirmText: "知道了", | ||||
|                     success: () => { | ||||
|                         // 可选:用户确认后返回上一级页面 | ||||
|                         wx.reLaunch({ | ||||
|                           url: "/pages/index/index", | ||||
|                         }) | ||||
|                     } | ||||
|                 }); | ||||
|                 return; // 停止执行后续逻辑 | ||||
|             } | ||||
|           }) | ||||
|           .catch(function(err) { | ||||
|               console.error("获取文章信息失败:", err); | ||||
|           }) | ||||
|           .finally(function() { | ||||
|               console.log("check_status调用完成"); | ||||
|           }); | ||||
|         // 使用 wx.getDeviceInfo() 检测系统是否为 iOS | ||||
|  | ||||
|  | ||||
|  | ||||
|         // 非 iOS 系统,继续加载页面逻辑 | ||||
|         var t = wx.getStorageSync("cards").filter(function (t) { | ||||
|             return t.is_quota === JSON.parse(e.isQuota || "false"); | ||||
|         }); | ||||
|  | ||||
|         console.log("renderCards", t); | ||||
|         this.setData({ | ||||
|             cards: t, | ||||
|             isQuota: JSON.parse(e.isQuota || "false"), | ||||
|         }); | ||||
|     }, | ||||
|  | ||||
|  | ||||
|     onRecharge: function (e) { | ||||
|         this.setData({ | ||||
|             selectedType: e.currentTarget.dataset.type, | ||||
|         }); | ||||
|     }, | ||||
|     // open_button: function (e) { | ||||
|     //     // 如果是 iOS,弹出提示框(备用逻辑) | ||||
|     //     if (this.data.isIOS) { | ||||
|     //         wx.showModal({ | ||||
|     //             title: "提示", | ||||
|     //             content: "iOS 暂时无法使用此功能,请稍后再试。", | ||||
|     //             showCancel: false, | ||||
|     //             confirmText: "知道了", | ||||
|     //         }); | ||||
|     //         return; | ||||
|     //     } | ||||
|  | ||||
|     //     // 非 iOS 正常跳转到支付小程序 | ||||
|     //     var t = e.currentTarget.dataset.type, | ||||
|     //         n = e.currentTarget.dataset.price; | ||||
|     //     this.setData({ | ||||
|     //         selectedType: t, | ||||
|     //     }), | ||||
|     //         console.log(t, n), | ||||
|     //         wx.navigateToMiniProgram({ | ||||
|     //             appId: "wxbe54dfa3311e0443", | ||||
|     //             path: "pages/payment/payment?type=" | ||||
|     //                 .concat(t, "&externalOpenid=") | ||||
|     //                 .concat(wx.getStorageSync("openid"), "&total_fee=") | ||||
|     //                 .concat(n, "&transaction_type=member&isDebug=false"), | ||||
|     //             envVersion: "release", | ||||
|     //             success: function (e) { | ||||
|     //                 console.log("跳转到支付小程序成功", e); | ||||
|     //             }, | ||||
|     //             fail: function (e) { | ||||
|     //                 console.error("跳转到支付小程序失败", e); | ||||
|     //             }, | ||||
|     //         }); | ||||
|     // }, | ||||
|     open_button: function(t) { | ||||
|       var n = t.currentTarget.dataset.type, o = t.currentTarget.dataset.price; | ||||
|       this.setData({ | ||||
|           selectedType: n | ||||
|       }), console.log(t), e.apiRequest({ | ||||
|           url: "/myapp/wx_pay/", | ||||
|           method: "POST", | ||||
|           data: { | ||||
|               type: n, | ||||
|               openid: wx.getStorageSync("openid"), | ||||
|               total_fee: o, | ||||
|               transaction_type: "member" | ||||
|           }, | ||||
|           success: function(t) { | ||||
|               console.log(t), t.data && t.data.paySign ? wx.requestPayment({ | ||||
|                   timeStamp: t.data.timeStamp, | ||||
|                   nonceStr: t.data.nonceStr, | ||||
|                   package: t.data.package, | ||||
|                   signType: "RSA", | ||||
|                   paySign: t.data.paySign, | ||||
|                   success: function(t) { | ||||
|                       e.getinfo().then(function() { | ||||
|                           console.log(wx.getStorageSync("cards")), wx.navigateBack({ | ||||
|                               delta: 1, | ||||
|                               success: function(e) { | ||||
|                                   console.log("返回上一页成功"); | ||||
|                               } | ||||
|                           }); | ||||
|                       }).catch(function(e) { | ||||
|                           console.error("An error occurred:", e); | ||||
|                       }), console.log(t), wx.showToast({ | ||||
|                           title: "支付成功", | ||||
|                           icon: "success" | ||||
|                       }); | ||||
|                   }, | ||||
|                   fail: function(e) { | ||||
|                       wx.showToast({ | ||||
|                           title: "支付失败", | ||||
|                           icon: "error" | ||||
|                       }); | ||||
|                   } | ||||
|               }) : wx.showToast({ | ||||
|                   title: "创建订单失败", | ||||
|                   icon: "error" | ||||
|               }); | ||||
|           } | ||||
|       }); | ||||
|   }, | ||||
|     onReady: function () {}, | ||||
|     onShow: function () { | ||||
|         var t = this; | ||||
|         e.getUserInfo() | ||||
|             .then(function () { | ||||
|                 t.setData({ | ||||
|                     isVip: wx.getStorageSync("isMember"), | ||||
|                     startTime: t.formatEndTime(wx.getStorageSync("startTime")), | ||||
|                     endTime: t.formatEndTime(wx.getStorageSync("endTime")), | ||||
|                 }); | ||||
|             }) | ||||
|             .catch(function (e) { | ||||
|                 console.error("获取用户信息失败:", e); | ||||
|             }) | ||||
|             .finally(function () { | ||||
|                 console.log("getUserInfo调用完成"); | ||||
|             }); | ||||
|  | ||||
|             // | ||||
|  | ||||
|     }, | ||||
|     formatEndTime: function(e) { | ||||
|         // 将秒时间戳转换为毫秒时间戳 | ||||
|         var date = new Date(e * 1000); | ||||
|  | ||||
|         // 格式化为“YYYY年MM月DD日” | ||||
|         var year = date.getFullYear(); | ||||
|         var month = String(date.getMonth() + 1).padStart(2, "0"); // 月份从 0 开始,需要 +1 | ||||
|         var day = String(date.getDate()).padStart(2, "0"); | ||||
|  | ||||
|         var formattedDate = `${year}-${month}-${day}`; | ||||
|  | ||||
|        return formattedDate | ||||
|  | ||||
|   }, | ||||
|     onHide: function () {}, | ||||
|     onUnload: function () {}, | ||||
|     onPullDownRefresh: function () {}, | ||||
|     onReachBottom: function () {}, | ||||
|     onShareAppMessage: function () {}, | ||||
| }); | ||||
							
								
								
									
										7
									
								
								pages/vip_recharge/vip_recharge.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								pages/vip_recharge/vip_recharge.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| { | ||||
|     "navigationBarTitleText": "会员中心", | ||||
|     "navigationBarBackgroundColor": "#222238", | ||||
|     "navigationBarTextStyle": "white", | ||||
|     "component": true, | ||||
|     "usingComponents": {} | ||||
| } | ||||
							
								
								
									
										32
									
								
								pages/vip_recharge/vip_recharge.wxml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								pages/vip_recharge/vip_recharge.wxml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| <view class="container"  wx:if="{{show}}"> | ||||
|     <view class="status-section" wx:if="{{isVip}}"> | ||||
|         <view class="user-vip " style="position:relative;"> | ||||
|             <image class="user-pic" src="/images/老师教师男人.png"></image> | ||||
|             <view style="width: 200px;text-align: left; color: rgb(253, 217, 10);font-weight: 800;">尊贵VIP</view> | ||||
|         </view> | ||||
|         <view class="right"> | ||||
|             <view>开通时间:{{startTime}}</view> | ||||
|             <view>到期时间:{{endTime}}</view> | ||||
|             <button bindtap="open_button" class="renew-button small-button" data-price="{{cards[4].price}}" data-type="{{cards[4].type}}">续费</button> | ||||
|         </view> | ||||
|     </view> | ||||
|     <view class="recharge-options"> | ||||
|         <text class="title">选择订阅套餐:</text> | ||||
|         <view bindtap="onRecharge" class="card" data-price="{{item.price}}" data-type="{{item.type}}" wx:for="{{cards}}" wx:key="index"> | ||||
|             <image class="card-icon" src="https://file.guimiaokeji.com/VIP.png" wx:if="{{!isQuota}}"></image> | ||||
|             <image class="card-icon" src="../../images/积分.png" wx:if="{{isQuota}}"></image> | ||||
|             <view class="card-content"> | ||||
|                 <text class="card-title">{{item.title}}</text> | ||||
|                 <view class="price-wrapper"> | ||||
|                     <text class="original-price">原价¥{{item.price*2}}</text> | ||||
|                     <text class="current-price">限时¥{{item.price}}</text> | ||||
|                 </view> | ||||
|                 <view class='desc'>{{item.description}}</view> | ||||
|             </view> | ||||
|             <button bindtap="open_button" class="open-button" data-price="{{item.price}}" data-type="{{item.type}}" wx:if="{{selectedType===item.type}}">开通</button> | ||||
|         </view> | ||||
|     </view> | ||||
|     <view class="footer"> | ||||
|         <text>成为会员,享受无限使用功能特权,体验更多专属内容!</text> | ||||
|     </view> | ||||
| </view> | ||||
							
								
								
									
										133
									
								
								pages/vip_recharge/vip_recharge.wxss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								pages/vip_recharge/vip_recharge.wxss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| page { | ||||
|     background-color: #222238; | ||||
|     border-top: 1px solid hsla(0,31%,87%,.5); | ||||
| } | ||||
|  | ||||
| .container { | ||||
|     font-family: Arial; | ||||
|     padding: 20px; | ||||
| } | ||||
| .desc{ | ||||
|   white-space: pre-wrap; /* 支持换行 */ | ||||
|   color: #fff; | ||||
|   font-size: 22rpx; | ||||
|   font-weight: 300; | ||||
| } | ||||
| .status-section { | ||||
|     background: linear-gradient(90deg,#8d72d2,#7183f3); | ||||
|     display: flex; | ||||
|     justify-content: space-between; | ||||
|     margin-bottom: 20px; | ||||
|     text-align: center; | ||||
| } | ||||
|  | ||||
| .footer,.recharge-options,.status-section { | ||||
|     border-radius: 10px; | ||||
|     box-shadow: 0 2px 10px rgba(0,0,0,.1); | ||||
|     color: #a790e2; | ||||
|     padding: 20px 10px; | ||||
|     width: 100%; | ||||
| } | ||||
|  | ||||
| .card { | ||||
|     align-items: center; | ||||
|     background-color: #2f2f50; | ||||
|         border-radius: 20rpx; | ||||
|     box-shadow: 0 4px 6px rgba(0,0,0,.3),0 1px 3px rgba(0,0,0,.08); | ||||
|     display: flex; | ||||
|     margin-top: 10px; | ||||
|     padding: 10px; | ||||
|     transition: all .2s; | ||||
| } | ||||
|  | ||||
| .card-icon { | ||||
|     height: 50px; | ||||
|     margin-right: 10px; | ||||
|     width: 50px; | ||||
| } | ||||
|  | ||||
| .card-content { | ||||
|     flex-grow: 1; | ||||
|     width: 60%; | ||||
|      | ||||
| } | ||||
|  | ||||
| .card-title { | ||||
|     color: #a790e2; | ||||
|     font-size: 16px; | ||||
|     font-weight: 700; | ||||
| } | ||||
|  | ||||
| .price-wrapper { | ||||
|     align-items: center; | ||||
|     display: flex; | ||||
|      | ||||
| } | ||||
|  | ||||
| .original-price { | ||||
|     color: #97a09a; | ||||
|     margin-right: 10rpx; | ||||
|     text-decoration: line-through; | ||||
| } | ||||
|  | ||||
| .current-price { | ||||
|     color: #f861f8; | ||||
| } | ||||
|  | ||||
| .renew-button { | ||||
|     line-height: 2.4rem; | ||||
|      | ||||
| } | ||||
|  | ||||
| .open-button,.renew-button { | ||||
|  | ||||
|     background: linear-gradient(90deg,#592bcc,#d231d8); | ||||
|     border: none; | ||||
|     border-radius: 5px; | ||||
|     box-shadow: 0 4px 8px rgba(0,0,0,.2); | ||||
|     color: #fff; | ||||
|     cursor: pointer; | ||||
|     font-size: 1rem; | ||||
|     height: 2.5rem; | ||||
|     margin-top: 10px; | ||||
|     padding: .5rem 1rem; | ||||
|     text-align: center; | ||||
|     transition: background-color .3s,box-shadow .3s; | ||||
|     width: 6rem; | ||||
| } | ||||
|  | ||||
| .open-button { | ||||
|     line-height: 1.9rem; | ||||
| } | ||||
|  | ||||
| .open-button:hover,.renew-button:hover { | ||||
|     background-color: #e43333; | ||||
|     box-shadow: 0 6px 12px rgba(0,0,0,.3); | ||||
| } | ||||
|  | ||||
| .small-button { | ||||
|     padding: 5px; | ||||
| } | ||||
|  | ||||
| .footer { | ||||
|     color: #777; | ||||
|     font-size: 14px; | ||||
|     text-align: center; | ||||
| } | ||||
|  | ||||
| .user-vip,.user-vip .user-pic { | ||||
|     height: 130rpx; | ||||
|     margin: 0 auto; | ||||
|     width: 130rpx; | ||||
| } | ||||
|  | ||||
| .user-vip .user-pic { | ||||
|     background: #fff; | ||||
|     border-radius: 50%; | ||||
|     display: block; | ||||
|     overflow: hidden; | ||||
| } | ||||
|  | ||||
| .right { | ||||
|     color: #fff; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Jane Doe
					Jane Doe