down.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. // subpackagestow/down/down.js
  2. import { models, db, _ } from '../../utils/cloudbase.js'
  3. Page({
  4. /**
  5. * 页面的初始数据
  6. */
  7. data: {
  8. fuzhi: '',
  9. itemlist: {},
  10. itemtempFileURL: '',
  11. countdown: '00:05:00', // 倒计时文本
  12. countdownTime: 300, // 倒计时秒数(5分钟)
  13. timer: null, // 定时器句柄
  14. downloadTimestamps: [], // 记录下载时间戳
  15. hasAlarmed: false, // 防止重复报警
  16. },
  17. onLoad(options) {
  18. // 获取传递过来的数据
  19. const itemStr = decodeURIComponent(options.item);
  20. const item = JSON.parse(itemStr);
  21. // 设置到页面数据中
  22. this.setData({
  23. itemlist: item
  24. }, () => {
  25. wx.cloud.getTempFileURL({
  26. fileList: [
  27. {
  28. fileID: this.data.itemlist.url[0]
  29. }
  30. ],
  31. maxAge: 300 // 5分钟,单位秒
  32. })
  33. .then(res => {
  34. console.log(res.fileList, 'fileList');
  35. this.setData({
  36. itemtempFileURL: res.fileList[0].tempFileURL
  37. })
  38. this.startCountdown(); // 启动倒计时
  39. })
  40. .catch(err => {
  41. console.error(err);
  42. });
  43. });
  44. const fileIDs = [
  45. 'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/fuzhi.png',
  46. ];
  47. // 并发下载多个 fileID
  48. Promise.all(
  49. fileIDs.map(fileID => wx.cloud.downloadFile({ fileID }))
  50. ).then(results => {
  51. // 每个 result 对应一个下载结果
  52. const tempFilePaths = results.map(r => r.tempFilePath);
  53. console.log('全部下载成功:', tempFilePaths);
  54. this.setData({
  55. fuzhi: tempFilePaths[0],
  56. });
  57. }).catch(err => {
  58. console.error('有文件下载失败:', err);
  59. });
  60. },
  61. // 五分钟倒计时
  62. startCountdown() {
  63. const interval = setInterval(() => {
  64. let time = this.data.countdownTime;
  65. if (time <= 0) {
  66. clearInterval(interval);
  67. this.setData({
  68. countdown: '00:00:00',
  69. timer: null
  70. });
  71. return;
  72. }
  73. time--;
  74. const min = String(Math.floor(time / 60)).padStart(2, '0');
  75. const sec = String(time % 60).padStart(2, '0');
  76. const formatted = `00:${min}:${sec}`;
  77. this.setData({
  78. countdown: formatted,
  79. countdownTime: time,
  80. timer: interval
  81. });
  82. }, 1000);
  83. },
  84. // 分享到微信
  85. onShareAppMessage() {
  86. return {
  87. title: this.data.itemlist.name || '文件分享',
  88. path: `/subpackagestow/down/down?item=${encodeURIComponent(JSON.stringify(this.data.itemlist))}`,
  89. imageUrl: this.data.itemlist.cover, // 可选:自定义分享图
  90. }
  91. },
  92. handleShareTap() {
  93. wx.showToast({
  94. title: '请点击右上角“···”分享',
  95. icon: 'none',
  96. duration: 3000
  97. });
  98. this.getaddlishi()
  99. },
  100. // 保存链接地址
  101. handleCopyLink() {
  102. const link = this.data.itemtempFileURL;
  103. if (!link) {
  104. wx.showToast({
  105. title: '暂无可复制链接',
  106. icon: 'none'
  107. });
  108. return;
  109. }
  110. const that = this; // 保存页面上下文
  111. wx.setClipboardData({
  112. data: link,
  113. success() {
  114. that.getaddlishi()
  115. wx.showToast({
  116. title: '链接已复制',
  117. icon: 'success'
  118. });
  119. },
  120. fail() {
  121. wx.showToast({
  122. title: '复制失败',
  123. icon: 'none'
  124. });
  125. }
  126. });
  127. },
  128. // 下载
  129. handleDownloadFile() {
  130. const now = Date.now(); // 当前时间戳 毫秒
  131. let timestamps = this.data.downloadTimestamps || [];
  132. // 5分钟 = 5*60*1000 毫秒
  133. const FIVE_MINUTES = 5 * 60 * 1000;
  134. // 过滤掉超过5分钟的点击
  135. timestamps = timestamps.filter(ts => now - ts <= FIVE_MINUTES);
  136. // 加入当前点击
  137. timestamps.push(now);
  138. this.setData({
  139. downloadTimestamps: timestamps
  140. });
  141. // 超过10次 && 未报警 → 静默存一次
  142. if (timestamps.length >= 10 && !this.data.hasAlarmed) {
  143. this.setData({ hasAlarmed: true });
  144. this.saveAbnormalBehavior();
  145. }
  146. const link = this.data.itemtempFileURL;
  147. if (!link) {
  148. wx.showToast({
  149. title: '下载链接为空',
  150. icon: 'none'
  151. });
  152. return;
  153. }
  154. // 复制到剪贴板
  155. wx.setClipboardData({
  156. data: link,
  157. success: () => {
  158. wx.showModal({
  159. title: '提示',
  160. content: '下载链接已复制,请到浏览器粘贴并下载',
  161. showCancel: false, // 不显示取消按钮
  162. confirmText: '我知道了',
  163. success(res) {
  164. if (res.confirm) {
  165. console.log('用户点击确定,弹框关闭');
  166. }
  167. }
  168. });
  169. }
  170. });
  171. // const url = this.data.itemtempFileURL;
  172. // console.log(url);
  173. // if (!url) {
  174. // wx.showToast({
  175. // title: '文件链接不存在',
  176. // icon: 'none'
  177. // });
  178. // return;
  179. // }
  180. // wx.showLoading({
  181. // title: '下载中...',
  182. // mask: true
  183. // });
  184. // wx.downloadFile({
  185. // url: url,
  186. // success: (res) => {
  187. // wx.hideLoading();
  188. // console.log('进来了++++++++');
  189. // if (res.statusCode === 200) {
  190. // const tempFilePath = res.tempFilePath;
  191. // const fileExt = url.split('.').pop().toLowerCase();
  192. // const that = this; // 保存页面上下文
  193. // if (['pdf', 'ppt', 'pptx', 'doc', 'docx', 'xls', 'xlsx'].includes(fileExt)) {
  194. // // 打开文档
  195. // wx.openDocument({
  196. // filePath: tempFilePath,
  197. // showMenu: true,
  198. // success() {
  199. // console.log('打开文档成功');
  200. // that.getaddlishi()
  201. // },
  202. // fail(err) {
  203. // wx.showToast({
  204. // title: '打开文档失败',
  205. // icon: 'none'
  206. // });
  207. // console.error('文档打开失败', err);
  208. // }
  209. // });
  210. // } else if (['mp4', 'mov', 'avi'].includes(fileExt)) {
  211. // // 视频:先检查权限再保存
  212. // wx.getSetting({
  213. // success: (res) => {
  214. // if (!res.authSetting['scope.writePhotosAlbum']) {
  215. // wx.authorize({
  216. // scope: 'scope.writePhotosAlbum',
  217. // success: () => {
  218. // this.saveVideo(tempFilePath);
  219. // },
  220. // fail: () => {
  221. // wx.showModal({
  222. // title: '提示',
  223. // content: '保存视频需要开启“保存到相册”权限,请前往设置开启。',
  224. // showCancel: true,
  225. // success(result) {
  226. // if (result.confirm) {
  227. // wx.openSetting();
  228. // }
  229. // }
  230. // });
  231. // }
  232. // });
  233. // } else {
  234. // this.saveVideo(tempFilePath);
  235. // }
  236. // }
  237. // });
  238. // } else if (['mp3', 'wav', 'aac'].includes(fileExt)) {
  239. // // 音频保存到本地缓存
  240. // wx.saveFile({
  241. // tempFilePath,
  242. // success(result) {
  243. // wx.showToast({
  244. // title: '音频已保存',
  245. // icon: 'success'
  246. // });
  247. // that.getaddlishi()
  248. // console.log('音频保存路径:', result.savedFilePath);
  249. // },
  250. // fail(err) {
  251. // wx.showToast({
  252. // title: '保存失败',
  253. // icon: 'none'
  254. // });
  255. // console.error('音频保存失败:', err);
  256. // }
  257. // });
  258. // } else {
  259. // wx.showToast({
  260. // title: '暂不支持的文件类型',
  261. // icon: 'none'
  262. // });
  263. // }
  264. // } else {
  265. // wx.showToast({
  266. // title: '下载失败',
  267. // icon: 'none'
  268. // });
  269. // }
  270. // },
  271. // fail: (err) => {
  272. // wx.hideLoading();
  273. // wx.showToast({
  274. // title: '下载失败',
  275. // icon: 'none'
  276. // });
  277. // console.error('下载出错:', err);
  278. // }
  279. // });
  280. },
  281. // saveVideo(filePath) {
  282. // const that = this; // 保存页面上下文
  283. // wx.saveVideoToPhotosAlbum({
  284. // filePath,
  285. // success() {
  286. // wx.showToast({
  287. // title: '视频已保存',
  288. // icon: 'success'
  289. // });
  290. // that.getaddlishi()
  291. // },
  292. // fail(err) {
  293. // wx.showToast({
  294. // title: '保存失败',
  295. // icon: 'none'
  296. // });
  297. // console.error('视频保存失败:', err);
  298. // }
  299. // });
  300. // },
  301. // 新增下载历史
  302. async getaddlishi() {
  303. const userInfo = wx.getStorageSync('userInfo');
  304. const userId = userInfo && userInfo._id ? userInfo._id : '';
  305. const schoolId = userInfo && userInfo.school_id ? userInfo.school_id : '';
  306. const fileId = this.data.itemlist._id;
  307. const res = await models.download_history.create({
  308. data: {
  309. user_id: userId, // 用户id
  310. delete: 0, // 逻辑删除
  311. file_manage_id: fileId, // 课件id
  312. },
  313. // envType: pre 体验环境, prod 正式环境
  314. envType: "prod",
  315. });
  316. // 返回创建的数据 id
  317. console.log(res, '++++++++++++++++++++++++++++++');
  318. // { count: 1}
  319. // 先查是否存在
  320. const { data } = await models.microcode.list({
  321. filter: {
  322. where: {
  323. school_id: schoolId,
  324. // user_id: userId,
  325. file_id: fileId
  326. }
  327. },
  328. envType: "prod",
  329. });
  330. console.log(data,'datadatadata');
  331. const datalist = data.records || []
  332. if (datalist.length > 0) {
  333. // 已存在 → 更新 visits + 1
  334. const existItem = datalist[0];
  335. const recordId = String(existItem._id);
  336. console.log(existItem, 'existItem');
  337. await models.microcode.update({
  338. data: {
  339. download: existItem.download + 1 , // 访问量
  340. },
  341. filter: {
  342. where: {
  343. $and: [
  344. {
  345. _id: {
  346. $eq: recordId, // 推荐传入_id数据标识进行操作
  347. },
  348. },
  349. ]
  350. }
  351. },
  352. // envType: pre 体验环境, prod 正式环境
  353. envType: "prod",
  354. });
  355. console.log("更新成功:visits + 1");
  356. } else {
  357. // 不存在 → 创建新记录
  358. const { data: newData } = await models.microcode.create({
  359. data: {
  360. visits: 1,
  361. download: 1,
  362. school_id: schoolId,
  363. // user_id: userId,
  364. file_id: fileId,
  365. },
  366. envType: "prod",
  367. });
  368. console.log("创建成功", newData);
  369. }
  370. },
  371. // 清除定时器
  372. onUnload() {
  373. if (this.data.timer) {
  374. clearInterval(this.data.timer);
  375. this.setData({ timer: null });
  376. }
  377. },
  378. async saveAbnormalBehavior() {
  379. const userInfo = wx.getStorageSync('userInfo');
  380. const userId = userInfo && userInfo._id ? userInfo._id : '';
  381. const schoolId = userInfo && userInfo.school_id ? userInfo.school_id : '';
  382. const fileName = this.data.itemlist.name || '';
  383. try {
  384. await models.abnormal_behavior_alarm.create({
  385. data: {
  386. school_id: schoolId,
  387. reason: '五分钟内点击下载超过10次',
  388. type: 0, // 可自行定义数字类型,表示下载异常
  389. file_name: fileName,
  390. user_id: userId
  391. },
  392. envType: 'prod'
  393. });
  394. console.log('异常行为已记录');
  395. } catch (err) {
  396. console.error('记录异常行为失败', err);
  397. }
  398. }
  399. })