LiuShu_0203 1 kuukausi sitten
vanhempi
commit
1d02ce2c03
68 muutettua tiedostoa jossa 8217 lisäystä ja 302 poistoa
  1. 33 0
      app.js
  2. 0 7
      app.json
  3. 1 1
      app.wxss
  4. 5 0
      cloud/cloudbase_auth/Readme.md
  5. 30 0
      cloud/cloudbase_auth/index.js
  6. 24 0
      cloud/cloudbase_auth/package.json
  7. 19 0
      cloud/cloudbase_auth/serverless.yaml
  8. 5 0
      cloud/database/Readme.md
  9. 164 0
      cloud/database/common.js
  10. 13 0
      cloud/database/db.js
  11. 186 0
      cloud/database/index.js
  12. 220 0
      cloud/database/interface/abnormal.js
  13. 327 0
      cloud/database/interface/aftersales.js
  14. 188 0
      cloud/database/interface/download.js
  15. 609 0
      cloud/database/interface/groupbuy.js
  16. 232 0
      cloud/database/interface/home.js
  17. 385 0
      cloud/database/interface/order.js
  18. 197 0
      cloud/database/interface/payment.js
  19. 30 0
      cloud/database/interface/recommend.js
  20. 219 0
      cloud/database/interface/userstats.js
  21. 3355 0
      cloud/database/package-lock.json
  22. 24 0
      cloud/database/package.json
  23. 40 0
      cloud/database/repository.js
  24. 19 0
      cloud/database/serverless.yaml
  25. 34 0
      cloud/login/index.js
  26. 6 0
      cloud/lxp/config.json
  27. 16 0
      cloud/lxp/index.js
  28. 1169 0
      cloud/lxp/package-lock.json
  29. 15 0
      cloud/lxp/package.json
  30. 168 0
      cloud/lxp/utils/smsUtil.js
  31. 17 0
      components/captcha/captcha.js
  32. 3 1
      components/captcha/captcha.wxml
  33. 6 6
      custom-tab-bar/index.js
  34. 1 2
      package-lock.json
  35. 0 1
      package.json
  36. 2 2
      pages/groupbuying/groupbuying.js
  37. 3 3
      pages/groupbuying/groupbuying.wxss
  38. 39 24
      pages/index/index.js
  39. 2 0
      pages/index/index.wxml
  40. 1 1
      pages/logins/logins.wxml
  41. 25 6
      pages/me/me.js
  42. 1 1
      pages/shoppingcart/shoppingcart.js
  43. 1 1
      project.config.json
  44. 56 51
      subpackages/changephone/changephone.js
  45. 3 1
      subpackages/changephone/changephone.json
  46. 7 4
      subpackages/changephone/changephone.wxml
  47. 15 2
      subpackages/collect/collect.js
  48. 34 22
      subpackages/jxhome/jxhome.js
  49. 32 20
      subpackages/kchome/kchome.js
  50. 4 5
      subpackages/productdetails/productdetails.js
  51. 2 2
      subpackages/productdetails/productdetails.wxml
  52. 3 3
      subpackages/productdetails/productdetails.wxss
  53. 15 2
      subpackages/purchasehistory/purchasehistory.js
  54. 33 21
      subpackages/pxhome/pxhome.js
  55. 33 21
      subpackages/zshome/zshome.js
  56. 6 6
      subpackagestow/course/course.js
  57. 1 1
      subpackagestow/course/course.wxss
  58. 73 54
      subpackagestow/details/details.js
  59. 3 3
      subpackagestow/details/details.wxml
  60. 12 3
      subpackagestow/details/details.wxss
  61. 20 4
      subpackagestow/down/down.js
  62. 3 8
      subpackagestow/show/show.js
  63. 1 1
      subpackagestow/show/show.wxss
  64. 3 3
      subpackagestow/teaching/teaching.js
  65. 1 1
      subpackagestow/teaching/teaching.wxss
  66. 3 3
      subpackagestow/training/training.js
  67. 1 1
      subpackagestow/training/training.wxss
  68. 19 4
      utils/cloudbase.js

+ 33 - 0
app.js

@@ -2,6 +2,8 @@
 App({
   globalData: {
     isLoggedIn: false, // 登录状态
+    isLoggedIns: false, // 登录状态
+    token: null
   },
 
   // 检查登录状态并弹出提示框
@@ -35,7 +37,38 @@ App({
   
     return true;
   },
+
+  async login() {
+    try {
+      const res = await wx.cloud.callFunction({
+        name: 'login', 
+        data: { 
+          username: 'admin',
+          password: 'Admin1234_'
+         }
+      })
+      if (res.result.code === 0) {
+        const token = res.result.token
+        this.globalData.isLoggedIns = true
+        this.globalData.token = token
+        wx.setStorageSync('token', token)
+        return token
+      } else {
+        wx.showToast({ title: res.result.msg, icon: 'none' })
+      }
+    } catch (err) {
+      console.error(err)
+      wx.showToast({ title: '登录失败', icon: 'none' })
+    }
+  },
+
   onLaunch() {
+    // 可以尝试读取本地缓存
+    const token = wx.getStorageSync('token')
+    if (token) {
+      this.globalData.isLoggedIns = true
+      this.globalData.token = token
+    }
     // wx.cloud.init({
     //   env: 'cloud1-6g98iw7i28b01747',
     //   traceUser: true

+ 0 - 7
app.json

@@ -8,7 +8,6 @@
   "pages": [
     "pages/index/index",
     "pages/groupbuying/groupbuying",
-    "pages/shoppingcart/shoppingcart",
     "pages/me/me",
     "pages/login/login",
     "pages/logins/logins",
@@ -38,12 +37,6 @@
         "iconPath": "image/tuangou.png",
         "selectedIconPath": "image/tuangou_1.png"
       },
-      {
-        "pagePath": "pages/shoppingcart/shoppingcart",
-        "text": "购物车",
-        "iconPath": "image/tuangou.png",
-        "selectedIconPath": "image/tuangou_1.png"
-      },
       {
         "pagePath": "pages/me/me",
         "text": "我的",

+ 1 - 1
app.wxss

@@ -5,7 +5,7 @@
   flex-direction: column;
   align-items: center;
   /* justify-content: space-between; */
-  padding: 200rpx 0;
+  /* padding: 200rpx 0; */
   box-sizing: border-box;
   background: #f5f5f5 !important;
 } 

+ 5 - 0
cloud/cloudbase_auth/Readme.md

@@ -0,0 +1,5 @@
+# 云函数空白模板
+
+此模板为云函数的空白文档,使用 Nodejs 运行环境部署。
+
+运行后会返回:{"hello":"world"},以及请求参数,环境参数。

+ 30 - 0
cloud/cloudbase_auth/index.js

@@ -0,0 +1,30 @@
+const cloud = require('wx-server-sdk')
+cloud.init({
+  env: cloud.DYNAMIC_CURRENT_ENV
+})
+
+// 云函数入口函数
+exports.main = async (event, context) => {
+  const wxContext = cloud.getWXContext()
+
+  console.log(event)
+  console.log(wxContext)
+  // 跨账号调用时,由此拿到来源方小程序/公众号 AppID
+  console.log(wxContext.FROM_APPID)
+  // 跨账号调用时,由此拿到来源方小程序/公众号的用户 OpenID
+  console.log(wxContext.FROM_OPENID)
+  // 跨账号调用、且满足 unionid 获取条件时,由此拿到同主体下的用户 UnionID
+  console.log(wxContext.FROM_UNIONID)
+
+  return {
+    errCode: 0,
+    errMsg: '',
+    auth: JSON.stringify({
+      // 自定义安全规则
+      // 在前端访问资源方数据库、云函数等资源时,资源方可以通过
+      // 安全规则的 `auth.custom` 字段获取此对象的内容做校验,
+      // 像这个示例就是资源方可以在安全规则中通过 `auth.custom.x` 获取
+      x: 1,
+    }),
+  }
+}

+ 24 - 0
cloud/cloudbase_auth/package.json

@@ -0,0 +1,24 @@
+{
+  "name": "@function/cloudbase_auth",
+  "version": "1.0.0",
+  "description": "",
+  "license": "ISC",
+  "author": "",
+  "type": "commonjs",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1",
+    "tcb-ff": "tcb-ff",
+    "dev": "tcb cloudfunction run -w",
+    "deploy": "tcb cloudfunction deploy"
+  },
+  "tcbRepo": {
+    "type": "function"
+  },
+  "dependencies": {
+    "@cloudbase/node-sdk": "^3.7.0"
+  },
+  "devDependencies": {
+    "@cloudbase/functions-framework": "^1.8.0"
+  }
+}

+ 19 - 0
cloud/cloudbase_auth/serverless.yaml

@@ -0,0 +1,19 @@
+component: scf
+name: cloudbase_auth
+inputs:
+  handler: index.main
+  description: Nodejs 语言 空白 helloworld 模板
+  runtime: Nodejs18.15
+  memorySize: 256
+  installDependency: true
+  timeout: 3
+  vpcConfig:
+    vpcId: ""
+    subnetId: ""
+  events: []
+  layers: []
+  initTimeout: 65
+  protocolParams: null
+  protocolType: ""
+  eip: false
+  publicAccess: true

+ 5 - 0
cloud/database/Readme.md

@@ -0,0 +1,5 @@
+# 云函数空白模板
+
+此模板为云函数的空白文档,使用 Nodejs 运行环境部署。
+
+运行后会返回:{"hello":"world"},以及请求参数,环境参数。

+ 164 - 0
cloud/database/common.js

@@ -0,0 +1,164 @@
+const { models } = require('./db')
+
+/**
+ * 校验是否空值
+ * @param {*} field 校验字段
+ * @param {*} comment 字段名称
+ * @returns 结果
+ */
+const validateField = (field, comment) => {
+    const result = {
+        flag: true,
+        msg: ''
+    }
+    if (field == null) {
+        result.flag = false
+        result.msg = '错误: 字段[ ' + comment + ' ]不能为空!'
+    }
+    return result
+}
+/**
+ * 新增函数
+ * @param {*} parameter 参数(用于打印错误)
+ * @param {*} data 数据(插入数据库的数据)
+ * @param {*} tableName 表名
+ * @returns 结果
+ */
+async function handleAdd(parameter, data, tableName) {
+    try {
+        // 新增数据
+        const result = await models[tableName].create({ data })
+        return {
+            success: true,
+            msg: '新增数据成功',
+            data: result.data,
+        }
+    } catch (error) {
+        return {
+            success: false,
+            msg: '新增数据失败',
+            error: error,
+            parameter
+        }
+    }
+    // 新增数据
+    // const result = await models[tableName].create({ data })
+    // return {
+    //     success: true,
+    //     msg: '新增数据成功',
+    //     data: result.data,
+    // }
+}
+/**
+ * 编辑函数(根据Id编辑)
+ * @param {*} parameter 参数(用于打印错误)
+ * @param {*} data 修改的数据
+ * @param {*} tableName 表名
+ * @returns 结果
+ */
+async function handleUpdate(parameter, id, data, tableName) {
+    try {
+        // 更新数据
+        const result = await models[tableName].update({
+            data,
+            filter: {
+                where: {
+                    _id: {
+                        $eq: id
+                    }
+                }
+            }
+        })
+        return {
+            success: true,
+            msg: '修改数据成功',
+            data: result,
+        }
+    } catch (error) {
+        return {
+            success: false,
+            msg: '修改数据失败',
+            error: error,
+            parameter
+        }
+    }
+}
+/**
+ * 根据Id删除
+ * @param {*} parameter 参数(用于打印错误)
+ * @param {*} id 要删除的数据的Id
+ * @param {*} tableName 表名
+ */
+async function handleDelete(parameter, id, tableName) {
+    try {
+        await models[tableName].delete({
+            filter: {
+                where: {
+                    $and: [
+                        {
+                            _id: {
+                                $eq: id,
+                            },
+                        },
+                    ]
+                }
+            },
+            envType: "prod",
+        })
+        return {
+            success: true,
+            msg: '删除数据成功',
+        }
+    } catch (error) {
+        return {
+            success: false,
+            msg: '删除数据失败',
+            error: error,
+            parameter
+        }
+    }
+}
+/**
+ * 根据某一字段查询数据
+ * @param {*} select 可以指定返回本表或者关联表的字段,如果想查询本表所有字段,请使用 { $master: true }
+ * @param {*} field 查询条件使用的字段
+ * @param {*} fieldVal 字段的值
+ * @param {*} tableName 表名
+ * @returns List
+ */
+async function handleFindByField(select, field, fieldVal, tableName) {
+    try {
+        const result = await models[tableName].list({
+            select,
+            filter: {
+                where: {
+                    [field]: {
+                        $eq: fieldVal, // 推荐传入_id数据标识进行操作
+                    },
+                }
+            },
+            envType: "prod",
+        })
+        return {
+            success: true,
+            msg: '查询成功',
+            data: result.data.records,
+            // sql
+        }
+    } catch (error) {
+        return {
+            success: false,
+            msg: '查询失败',
+            parameter,
+            error: error
+        }
+    }
+}
+
+module.exports = {
+    validateField,
+    handleAdd,
+    handleUpdate,
+    handleDelete,
+    handleFindByField
+}

+ 13 - 0
cloud/database/db.js

@@ -0,0 +1,13 @@
+const cloudbase = require('@cloudbase/node-sdk');
+
+const app = cloudbase.init({
+    env: "honghgaier-5guiffgcf17a2eea",
+    timeout: 15000
+});
+
+// exports.models = app.models;
+
+module.exports = {
+    models: app.models,
+    database: app.database
+}

+ 186 - 0
cloud/database/index.js

@@ -0,0 +1,186 @@
+'use strict';
+const repository = require('./repository.js');
+
+
+exports.main = async function main(event, context) {
+    const { page, action, data } = event;
+
+    switch (page) {
+        // 团购页面
+        case 'tuangou':
+            if (action === 'findGroupBuyPage') {
+                // 分页查询团购数据
+                return await repository.groupbuy.findGroupBuyPage(data)
+            } else if (action === 'addGroupBuy') {
+                // 新增团购
+                return await repository.groupbuy.addGroupBuy(data)
+            } else if (action === 'updateGroupBuy') {
+                // 编辑团购(根据Id)
+                return await repository.groupbuy.updateGroupBuy(data)
+            } else if (action === 'deleteGroupBuy') {
+                // 删除团购(根据Id)
+                return await repository.groupbuy.deleteGroupBuy(data)
+            } else if (action === 'findguigeBytuangouId') {
+                // 根据团购Id查询规格
+                return await repository.groupbuy.findguigeBytuangouId(data)
+            } else if (action === 'addguige') {
+                // 新增商品规格
+                return await repository.groupbuy.addguige(data)
+            } else if (action === 'updateguigeById') {
+                // 编辑商品规格
+                return await repository.groupbuy.updateguigeById(data)
+            } else if (action === 'deleteguigeById') {
+                // 根据Id删除商品规格
+                return await repository.groupbuy.deleteguigeById(data)
+            } else {
+                throw new Error('接口未实现!')
+            }
+        // 异常行为预警页面
+        case 'yichangxingweiyujing':
+            if (action === 'addBehaviorAlarm') {
+                // 新增异常行为告警
+                return await repository.abnormal.addBehaviorAlarm(data)
+            } else if (action === 'deleteBehaviorAlarm') {
+                // 删除异常行为告警
+                return await repository.abnormal.deleteBehaviorAlarm(data)
+            } else if (action === 'updateBehaviorAlarm') {
+                // 编辑异常行为告警
+                return await repository.abnormal.updateBehaviorAlarm(data)
+            } else if (action === 'findBehaviorAlarmPage') {
+                // 条件分页查询
+                return await repository.abnormal.findBehaviorAlarmPage(data)
+            } else if (action === 'findBehaviorAlarmById') {
+                // 根据Id查询
+                return await repository.abnormal.findBehaviorAlarmById(data)
+            } else {
+                throw new Error('接口未实现!')
+            }
+        // 售后管理页面
+        case 'shouhouguanli':
+            if (action === 'findSchoolAll') {
+                // 查询所有学校
+                return await repository.aftersales.findSchoolAll(data)
+            } else if (action === 'addAfterService') {
+                // 新增售后
+                return await repository.aftersales.addAfterService(data)
+            } else if (action === 'deleteAfterService') {
+                // 删除售后
+                return await repository.aftersales.deleteAfterService(data)
+            } else if (action === 'updateAfterService') {
+                // 编辑异常行为告警
+                return await repository.aftersales.updateAfterService(data)
+            } else if (action === 'findAfterServicePage') {
+                // 条件分页查询 
+                return await repository.aftersales.findAfterServicePage(data)
+            } else if (action === 'findAfterServiceById') {
+                // 根据Id查询 
+                return await repository.aftersales.findAfterServiceById(data)
+            } else {
+                throw new Error('接口未实现!')
+            }
+        // 下载量统计页面
+        case 'xiazailiangtongji':
+            if (action === 'findSchoolAll') {
+                // 查询所有学校
+                return await repository.aftersales.findSchoolAll(data)
+            } else if (action === 'addMicrocode') {
+                // 新增
+                return await repository.download.addMicrocode(data)
+            } else if (action === 'deleteMicrocode') {
+                // 删除
+                return await repository.download.deleteMicrocode(data)
+            } else if (action === 'updateMicrocode') {
+                // 编辑
+                return await repository.download.updateMicrocode(data)
+            } else if (action === 'findMicrocodePage') {
+                // 条件分页查询 
+                return await repository.download.findMicrocodePage(data)
+            } else if (action === 'findMicrocodeById') {
+                // 根据Id查询 
+                return await repository.download.findMicrocodeById(data)
+            } else {
+                throw new Error('接口未实现!')
+            }
+        // 订单管理页面
+        case 'dingdanguanli':
+            if (action === 'addOrder') {
+                // 新增
+                return await repository.order.addOrder(data)
+            } else if (action === 'deleteOrder') {
+                // 删除
+                return await repository.order.deleteOrder(data)
+            } else if (action === 'updateOrder') {
+                // 编辑
+                return await repository.order.updateOrder(data)
+            } else if (action === 'findOrderPage') {
+                // 条件
+                return await repository.order.findOrderPage(data)
+            } else if (action === 'findOrderById') {
+                // 根据Id查询 
+                return await repository.order.findOrderById(data)
+            } else {
+                throw new Error('接口未实现!')
+            }
+        // 用户行为统计页面
+        case 'userstats':
+            if (action === 'addMmonitorBehavior') {
+                // 新增
+                return await repository.userstats.addMmonitorBehavior(data)
+            } else if (action === 'deleteMmonitorBehavior') {
+                // 删除
+                return await repository.userstats.deleteMmonitorBehavior(data)
+            } else if (action === 'updateMmonitorBehavior') {
+                // 编辑
+                return await repository.userstats.updateMmonitorBehavior(data)
+            } else if (action === 'findMmonitorBehaviorPage') {
+                // 条件
+                return await repository.userstats.findMmonitorBehaviorPage(data)
+            } else if (action === 'findMmonitorBehaviorById') {
+                // 根据Id查询 
+                return await repository.userstats.findMmonitorBehaviorById(data)
+            } else {
+                throw new Error('接口未实现!')
+            }
+        // 付款统计页面接口
+        case 'payment':
+            if (action === 'findPaymentPage') {
+                // 按照班级分组
+                return await repository.payment.findPaymentPage(data)
+            } else if (action === 'findPaymentPageBySchool') {
+                // 按照学校分组
+                return await repository.payment.findPaymentPageBySchool(data)
+            } else {
+                throw new Error('接口未实现!')
+            }
+        // 首页接口
+        case 'home':
+            if (action === 'findCountAndTotal') {
+                // 今日,今年下单付款统计
+                return await repository.home.findCountAndTotal()
+            } else if (action === 'findBehaviorAlarm') {
+                // 查询异常行为预警
+                return await repository.home.findBehaviorAlarm()
+            } else if (action === 'findOrderCountByMonth') {
+                // 按月份统计下单量
+                return await repository.home.findOrderCountByMonth(data)
+            } else if (action === 'findOrderCountByDay') {
+                // 按天统计下单量
+                return await repository.home.findOrderCountByDay(data)
+            } else if (action === 'findFileCount') {
+                // 按月份分组查询课件上传统计
+                return await repository.home.findFileCount(data)
+            } else {
+                throw new Error('接口未实现!')
+            }
+        //推荐
+        case 'recommende':
+            if (action === 'findFileRangee') {
+                return await repository.recommend.findFileRangee(data)
+            } else {
+                throw new Error('接口未实现!')
+            }
+
+        default:
+            throw new Error('未知的操作类型')
+    }
+}

+ 220 - 0
cloud/database/interface/abnormal.js

@@ -0,0 +1,220 @@
+const { models } = require('../db')
+const { validateField, handleAdd, handleUpdate, handleFindByField, handleDelete } = require('../common')
+
+/**
+ * 
+ * 异常行为告警 表格   调 abnormal_behavior_alarm(异常行为报警)
+ * 
+ *         字段展示   用户名  根据 异常行为报警表 user_id 去 老师表(wx_teacher_user)里查_id是否相同 相同取园所名称(name)
+ *                   学校名 —— school_id  根据 监异常行为报警表 school_id 去 老师表(wx_school)里查_id是否相同 相同取园所名称(name)
+ *                   课件名称 —— file_name
+ *                   异常行为 —— reason
+ *                   报警时间 —— createdAt
+ * 
+ */
+/**
+ * 新增异常行为告警
+ * @param {*} file_name 课件名称
+ * @param {*} reason 异常行为
+ * @param {*} user_id 用户Id
+ * @param {*} type 报警端: 0-教师 1-家长
+ * @returns 
+ */
+async function addBehaviorAlarm(parameter) {
+    const { file_name, reason, user_id, type } = parameter
+    const v1 = validateField(file_name, 'file_name')
+    if (!v1.flag) {
+        return {
+            success: false,
+            msg: v1.msg
+        }
+    }
+    const v2 = validateField(reason, 'reason')
+    if (!v2.flag) {
+        return {
+            success: false,
+            msg: v2.msg
+        }
+    }
+    const v3 = validateField(user_id, 'user_id')
+    if (!v3.flag) {
+        return {
+            success: false,
+            msg: v3.msg
+        }
+    }
+    const v4 = validateField(type, 'type')
+    if (!v4.flag) {
+        return {
+            flag: false,
+            msg: v4.msg
+        }
+    }
+
+    const user = await models[type === 1 ? 'wx_user' : 'wx_teacher_user'].get({
+        select: {
+            school_id: true
+        },
+        filter: {
+            where: {
+                _id: {
+                    $eq: user_id
+                }
+            }
+        }
+    })
+
+    const data = {
+        file_name,
+        reason,
+        user_id,
+        type,
+        school_id: user.data.school_id,
+        createdAt: new Date().getTime(),
+    }
+    return await handleAdd(parameter, data, 'abnormal_behavior_alarm')
+}
+/**
+ * 根据Id删除商品规格
+ * @param {*} _id 规格Id 
+ */
+async function deleteBehaviorAlarm(parameter) {
+    const { _id } = parameter
+    return handleDelete(parameter, _id, 'abnormal_behavior_alarm')
+}
+/**
+ * 编辑异常行为告警
+ * @param {*} _id 主键Id
+ * @param {*} file_name 课件名称
+ * @param {*} reason 异常行为
+ * @param {*} user_id 用户Id
+ * @param {*} type 报警端: 0-教师 1-家长
+ * @param {*} id 团购Id
+ * @returns
+ */
+async function updateBehaviorAlarm(parameter) {
+    const { _id, file_name, reason, user_id, type } = parameter
+    const obj = {}
+    const v0 = validateField(_id, '_id')
+    if (!v0.flag) {
+        return {
+            success: false,
+            msg: v0.msg
+        }
+    }
+    const v1 = validateField(file_name, 'file_name')
+    if (v1.flag) {
+        obj.file_name = file_name
+    }
+    const v2 = validateField(reason, 'reason')
+    if (v2.flag) {
+        obj.reason = reason
+    }
+    const v3 = validateField(user_id, 'user_id')
+    if (v3.flag) {
+        obj.user_id = user_id
+    }
+    const v4 = validateField(type, 'type')
+    if (v4.flag) {
+        obj.type = type
+    }
+    return await handleUpdate(parameter, _id, obj, 'abnormal_behavior_alarm')
+}
+/**
+ * 分页查询异常行为告警
+ * @param {*} startTime 开始时间
+ * @param {*} endTime 结束时间
+ * @param {*} pageNum 当前页面
+ * @param {*} pageSize 每页展示数量
+ * @returns 分页数据
+ */
+async function findBehaviorAlarmPage(parameter) {
+    const { startTime, endTime, pageNum, pageSize } = parameter
+    const v1 = validateField(pageNum)
+    if (!v1.flag) {
+        return {
+            success: false,
+            records: [],
+            msg: v1.msg
+        }
+    }
+    const v2 = validateField(pageSize)
+    if (!v2.flag) {
+        return {
+            success: false,
+            records: [],
+            msg: v2.msg
+        }
+    }
+    // 查询参数
+    const params = {
+        pageNum,
+        pageSize
+    }
+    // 拼接查询条件
+    let condition = " where aba.type = 0 "
+    if (startTime != null && endTime != null) {
+        condition += " and aba.createdAt >= {{startTime}} and aba.createdAt <= {{endTime}} "
+        params.startTime = startTime
+        params.endTime = endTime
+    }
+
+    const skip = (pageNum - 1) * pageSize
+    // 查询sql
+    const sql = "select " +
+        "aba._id as id, " +
+        "tu.name as yonghuming, " +
+        "s.name as xuexiaomingcheng, " +
+        "aba.file_name as kejianmingcheng, " +
+        "aba.reason as yichangxingwei, " +
+        "aba.type, " +
+        "aba.createdAt " +
+        "from abnormal_behavior_alarm aba " +
+        "left join wx_teacher_user tu on aba.user_id = tu._id " +
+        "left join wx_school s on tu.school_id = s._id " +
+        condition +
+        " order by createdAt desc " + "limit " + skip + ", " + pageSize
+    const countSql = "select count(*) as total from abnormal_behavior_alarm aba " +
+        "left join wx_teacher_user tu on aba.user_id = tu._id " +
+        "left join wx_school s on tu.school_id = s._id " +
+        condition
+    try {
+        // 查询数据sql
+        const records = await models.$runSQL(sql, params)
+        const count = await models.$runSQL(countSql, params)
+        return {
+            sql,
+            countSql,
+            params,
+            success: true,
+            msg: '查询成功',
+            records: records.data.executeResultList,
+            total: count.data.executeResultList[0].total
+        }
+    } catch (error) {
+        return {
+            success: false,
+            msg: '查询失败',
+            params,
+            sql,
+            countSql,
+            error: error
+        }
+    }
+}
+/**
+ * 根据Id查询
+ * @param {*} _id Id 
+ */
+async function findBehaviorAlarmById(parameter) {
+    const { _id } = parameter
+    return handleFindByField(parameter, _id, 'abnormal_behavior_alarm')
+}
+
+module.exports = {
+    addBehaviorAlarm,
+    deleteBehaviorAlarm,
+    updateBehaviorAlarm,
+    findBehaviorAlarmPage,
+    findBehaviorAlarmById,
+};

+ 327 - 0
cloud/database/interface/aftersales.js

@@ -0,0 +1,327 @@
+const { models } = require('../db')
+const { validateField, handleAdd, handleUpdate, handleDelete } = require('../common')
+/**
+ * 
+ * 售后管理    表格   调 wx_afterservice(售后管理)
+ * 
+ *         字段展示   用户名  根据 售后管理表 user_id 去 家长表(wx_user)里查_id是否相同 相同取园所名称(name)
+ *                   手机号 phone
+ *                   园所 根据 售后管理表 school_id 去 学校表(wx_school)里查_id是否相同 相同取园所名称(name)
+ *                   订单号 order_id
+ *                   图片 —— url
+ *                   描述 —— des
+ *                   售后状态(0-未处理 1-处理中 2-已处理) —— state
+ *                   创建时间 —— createdAt
+ * 
+ *          查询  调 wx_afterservice(售后管理)
+ *                user_id —— 用户名
+ *                phone —— 手机号
+ *                school_id —— 园所_id  园所是下拉  调 wx_school(园所表)
+ *                state —— 售后状态(0-未处理 1-处理中 2-已处理)
+ * 
+ *          修改  调 wx_afterservice(售后管理)
+ *                state —— 售后状态
+ *                加传 _id
+ * 
+ * 
+ */
+/**
+ * 查询所有学校
+ * @param {*} parameter 
+ */
+async function findSchoolAll(parameter) {
+    const result = await models.wx_school.list({
+        select: {
+            _id: true,
+            name: true,
+            phone: true,
+            remark: true,
+            adress: true,
+            contacts: true,
+        },
+        filter: {
+            where: {}
+        },
+        getCount: true,
+        pageSize: 100,
+        pageNumber: 1,
+        envType: "prod"
+    })
+    return result
+}
+/**
+ * 新增售后
+ * @param {*} school_id 学校Id
+ * @param {*} user_id 用户Id
+ * @param {*} order_id 订单Id
+ * @param {*} phone 手机号码
+ * @param {*} des 描述
+ * @param {*} url 图片路径(数组)
+ * @param {*} goods_id 商品Id
+ * @returns 
+ */
+async function addAfterService(parameter) {
+    const { school_id, user_id, order_id, phone, des, url, goods_id } = parameter
+    const v1 = validateField(school_id, 'school_id')
+    if (!v1.flag) {
+        return {
+            success: false,
+            msg: v1.msg
+        }
+    }
+    const v2 = validateField(user_id, 'user_id')
+    if (!v2.flag) {
+        return {
+            success: false,
+            msg: v2.msg
+        }
+    }
+    const v3 = validateField(order_id, 'order_id')
+    if (!v3.flag) {
+        return {
+            success: false,
+            msg: v3.msg
+        }
+    }
+    const v4 = validateField(phone, 'phone')
+    if (!v4.flag) {
+        return {
+            flag: false,
+            msg: v4.msg
+        }
+    }
+    const v5 = validateField(des, 'des')
+    if (!v5.flag) {
+        return {
+            flag: false,
+            msg: v5.msg
+        }
+    }
+    const v6 = validateField(url, 'url')
+    if (!v6.flag) {
+        return {
+            flag: false,
+            msg: v6.msg
+        }
+    }
+    const v7 = validateField(goods_id, 'goods_id')
+    if (!v7.flag) {
+        return {
+            flag: false,
+            msg: v7.msg
+        }
+    }
+
+    const data = {
+        school_id,
+        user_id,
+        order_id,
+        phone,
+        des,
+        url,
+        goods_id,
+        state: 0,
+        createdAt: new Date().getTime(),
+    }
+    return await handleAdd(parameter, data, 'wx_afterservice')
+}
+/**
+ * 根据Id删除售后
+ * @param {*} _id 规格Id 
+ */
+async function deleteAfterService(parameter) {
+    const { _id } = parameter
+    return handleDelete(parameter, _id, 'wx_afterservice')
+}
+/**
+ * 编辑售后管理
+ * @param {*} _id 主键Id
+ * @param {*} school_id 学校Id
+ * @param {*} user_id 用户Id
+ * @param {*} order_id 订单Id
+ * @param {*} phone 手机号码
+ * @param {*} des 描述
+ * @param {*} url 图片路径(数组)
+ * @param {*} goods_id 商品Id
+ * @returns 
+ */
+async function updateAfterService(parameter) {
+    const { _id, school_id, user_id, order_id, phone, des, url, goods_id, state } = parameter
+    const obj = {}
+    const v0 = validateField(_id, '_id')
+    if (!v0.flag) {
+        return {
+            success: false,
+            msg: v0.msg
+        }
+    }
+    const v1 = validateField(school_id, 'school_id')
+    if (v1.flag) {
+        obj.school_id = school_id
+    }
+    const v2 = validateField(user_id, 'user_id')
+    if (v2.flag) {
+        obj.user_id = user_id
+    }
+    const v3 = validateField(order_id, 'order_id')
+    if (v3.flag) {
+        obj.order_id = order_id
+    }
+    const v4 = validateField(phone, 'phone')
+    if (v4.flag) {
+        obj.phone = phone
+    }
+    const v5 = validateField(des, 'des')
+    if (v5.flag) {
+        obj.des = des
+    }
+    const v6 = validateField(url, 'url')
+    if (v6.flag) {
+        obj.url = url
+    }
+    const v7 = validateField(goods_id, 'goods_id')
+    if (v7.flag) {
+        obj.goods_id = goods_id
+    }
+
+    const v8 = validateField(state, 'state')
+    if (v8.flag) {
+        obj.state = state
+    }
+    return await handleUpdate(parameter, _id, obj, 'wx_afterservice')
+}
+/**
+ * 分页查询售后管理
+ * @param {*} startTime 开始时间
+ * @param {*} endTime 结束时间
+ * @param {*} pageNum 当前页面
+ * @param {*} pageSize 每页展示数量
+ * @returns 分页数据
+ */
+async function findAfterServicePage(parameter) {
+    const { username, phone, school_id, state, startTime, endTime, pageNum, pageSize } = parameter
+    const v1 = validateField(pageNum)
+    if (!v1.flag) {
+        return {
+            success: false,
+            records: [],
+            msg: v1.msg
+        }
+    }
+    const v2 = validateField(pageSize)
+    if (!v2.flag) {
+        return {
+            success: false,
+            records: [],
+            msg: v2.msg
+        }
+    }
+    // 查询参数
+    const params = {
+        pageNum,
+        pageSize
+    }
+    // 拼接查询条件
+    let condition = ""
+    if (username != null) {
+        condition += " where u.user_name like '%{{username}}%' "
+        params.username = username
+    }
+    if (phone != null) {
+        if (condition) {
+            condition += " and u.phone like '%{{phone}}%' "
+        } else {
+            condition += " where u.phone like '%{{phone}}%'  "
+        }
+        params.phone = phone
+    }
+    if (school_id != null) {
+        if (condition) {
+            condition += " and s._id = {{school_id}} "
+        } else {
+            condition += " where s._id = {{school_id}} "
+        }
+        params.school_id = school_id
+    }
+    if (state != null) {
+        if (condition) {
+            condition += " and a.state = {{state}} "
+        } else {
+            condition += " where a.state = {{state}} "
+        }
+        params.state = state
+    }
+    if (startTime != null && endTime != null) {
+        if (condition) {
+            condition += " and a.createdAt >= {{startTime}} and a.createdAt <= {{endTime}} "
+        } else {
+            condition += " where a.createdAt >= {{startTime}} and a.createdAt <= {{endTime}} "
+        }
+        params.startTime = startTime
+        params.endTime = endTime
+    }
+
+    const skip = (pageNum - 1) * pageSize
+    // 查询sql
+    const sql = "select " +
+        "a._id      as _id, " +
+        "u.name      as username, " +
+        "u.phone     as phone, " +
+        "s.name      as schoolName, " +
+        "o.order_id  as orderId, " +
+        "a.url       as url, " +
+        "a.des       as description, " +
+        "a.state     as state, " +
+        "a.createdAt as createdAt " +
+        "from wx_afterservice a " +
+        "left join wx_user u on a.user_id = u._id " +
+        "left join wx_school s on a.school_id = s._id " +
+        "left join orders o on a.order_id = o._id" +
+        condition +
+        " order by createdAt desc " + "limit " + skip + ", " + pageSize
+    const countSql = "select count(*) as total from wx_afterservice a " +
+        "left join wx_user u on a.user_id = u._id " +
+        "left join wx_school s on a.school_id = s._id " +
+        "left join orders o on a.order_id = o._id " +
+        condition
+    try {
+        // 查询数据sql
+        const records = await models.$runSQL(sql, params)
+        const count = await models.$runSQL(countSql, params)
+        return {
+            sql,
+            countSql,
+            params,
+            success: true,
+            msg: '查询成功',
+            records: records.data.executeResultList,
+            total: count.data.executeResultList[0].total
+        }
+    } catch (error) {
+        return {
+            success: false,
+            msg: '查询失败',
+            params,
+            sql,
+            countSql,
+            error: error
+        }
+    }
+}
+/**
+ * 根据Id查询
+ * @param {*} _id Id 
+ */
+async function findAfterServiceById(parameter) {
+    const { _id } = parameter
+    return handleFindByField(parameter, _id, 'wx_afterservice')
+}
+
+module.exports = {
+    findSchoolAll,
+    addAfterService,
+    deleteAfterService,
+    updateAfterService,
+    findAfterServicePage,
+    findAfterServiceById,
+}

+ 188 - 0
cloud/database/interface/download.js

@@ -0,0 +1,188 @@
+const { models } = require('../db')
+const { validateField, handleAdd, handleUpdate, handleDelete, handleFindByField } = require('../common')
+/**
+ * 
+ * 下载量统计 表格   调 microcode(访问下载量统计)
+ * 
+ *         字段展示   园所 根据 售后管理表 school_id 去 学校表(wx_school)里查_id是否相同 相同取园所名称(name)
+ *                   课件名 —— 根据 售后管理表 file_id 去 文件表(file_manage)里查_id是否相同 相同取园所名称(name)
+ *                   下载量 —— download
+ *                   创建时间 —— createdAt
+ * 
+ *          查询  调 microcode(访问下载量统计)
+ *                  school_id —— 园所_id  园所是下拉  调 wx_school(园所表)
+ *                  createdAt —— 创建时间
+ * 
+ * 
+ */
+/**
+ * 新增访问下载量统计
+ * @param {*} file_id 课件Id
+ * @param {*} school_id 学校Id
+ * @returns 
+ */
+async function addMicrocode(parameter) {
+    const { file_id, school_id } = parameter
+    const v1 = validateField(school_id, 'school_id')
+    if (!v1.flag) {
+        return {
+            success: false,
+            msg: v1.msg
+        }
+    }
+    const v2 = validateField(file_id, 'file_id')
+    if (!v2.flag) {
+        return {
+            success: false,
+            msg: v2.msg
+        }
+    }
+
+    const data = {
+        school_id,
+        file_id,
+        visits: 0,
+        download: 0,
+    }
+    return await handleAdd(parameter, data, 'microcode')
+}
+/**
+ * 根据Id删除
+ * @param {*} _id Id 
+ */
+async function deleteMicrocode(parameter) {
+    const { _id } = parameter
+    return handleDelete(parameter, _id, 'microcode')
+}
+/**
+ * 编辑
+ * @param {*} _id 主键Id
+ * @param {*} file_id 课件Id
+ * @param {*} school_id 学校Id
+ * @returns 
+ */
+async function updateMicrocode(parameter) {
+    const { _id, school_id, file_id } = parameter
+    const obj = {}
+    const v0 = validateField(_id, '_id')
+    if (!v0.flag) {
+        return {
+            success: false,
+            msg: v0.msg
+        }
+    }
+    const v1 = validateField(school_id, 'school_id')
+    if (v1.flag) {
+        obj.school_id = school_id
+    }
+    const v2 = validateField(file_id, 'file_id')
+    if (v2.flag) {
+        obj.file_id = file_id
+    }
+    return await handleUpdate(parameter, _id, obj, 'microcode')
+}
+/**
+ * 分页查询
+ * @param {*} school_id 学校Id
+ * @param {*} startTime 开始时间
+ * @param {*} endTime 结束时间
+ * @param {*} pageNum 当前页面
+ * @param {*} pageSize 每页展示数量
+ * @returns 分页数据
+ */
+async function findMicrocodePage(parameter) {
+    const { school_id, startTime, endTime, pageNum, pageSize } = parameter
+    const v1 = validateField(pageNum)
+    if (!v1.flag) {
+        return {
+            success: false,
+            records: [],
+            msg: v1.msg
+        }
+    }
+    const v2 = validateField(pageSize)
+    if (!v2.flag) {
+        return {
+            success: false,
+            records: [],
+            msg: v2.msg
+        }
+    }
+    // 查询参数
+    const params = {
+        pageNum,
+        pageSize
+    }
+    // 拼接查询条件
+    let condition = ""
+    if (school_id != null) {
+        condition += " where s._id = {{school_id}} "
+        params.school_id = school_id
+    }
+    if (startTime != null && endTime != null) {
+        if (condition) {
+            condition += " and fm.createdAt >= {{startTime}} and fm.createdAt <= {{endTime}} "
+        } else {
+            condition += " where fm.createdAt >= {{startTime}} and fm.createdAt <= {{endTime}} "
+        }
+        params.startTime = startTime
+        params.endTime = endTime
+    }
+
+    const skip = (pageNum - 1) * pageSize
+    // 查询sql
+    const sql = "select " +
+        "s.name     as schoolName, " +
+        "fm.name    as fileName, " +
+        "m.download as download, " +
+        "m.visits   as visits, " +
+        "fm.createdAt as createdAt " +
+        "from microcode m " +
+        "left join wx_school s on m.school_id = s._id " +
+        "left join file_manage fm on m.file_id = fm._id " +
+        condition +
+        " order by fm.createdAt desc " + "limit " + skip + ", " + pageSize
+    const countSql = "select count(*) as total from microcode m " +
+        "left join wx_school s on m.school_id = s._id " +
+        "left join file_manage fm on m.file_id = fm._id " +
+        condition
+    try {
+        // 查询数据sql
+        const records = await models.$runSQL(sql, params)
+        const count = await models.$runSQL(countSql, params)
+        return {
+            sql,
+            countSql,
+            params,
+            success: true,
+            msg: '查询成功',
+            records: records.data.executeResultList,
+            total: count.data.executeResultList[0].total
+        }
+    } catch (error) {
+        return {
+            success: false,
+            msg: '查询失败',
+            params,
+            sql,
+            countSql,
+            error: error
+        }
+    }
+}
+/**
+ * 根据Id查询
+ * @param {*} _id Id 
+ */
+async function findMicrocodeById(parameter) {
+    const { _id } = parameter
+    return handleFindByField(parameter, _id, 'microcode')
+}
+
+module.exports = {
+    addMicrocode,
+    deleteMicrocode,
+    updateMicrocode,
+    findMicrocodePage,
+    findMicrocodeById,
+}

+ 609 - 0
cloud/database/interface/groupbuy.js

@@ -0,0 +1,609 @@
+const { models } = require('../db')
+const { validateField, handleAdd, handleUpdate, handleFindByField, handleDelete } = require('../common')
+
+/**
+ * 
+ * 团购管理    表格   调 wx_merchandise(团购表)
+ * 
+ *         字段展示   学校名称  根据 团购表 里面的school_id 去 园所表(wx_school)里查_id是否相同 相同取园所名称(name)
+ *                   封面 —— img
+ *                   团购名称 —— name
+ *                   已拼数量 —— count  
+ *                   浏览量 —— browse
+ *                   活动开始时间 —— eventstarttime
+ *                   活动结束时间 —— eventendstime
+ *                   收货方式(0-邮寄1-自提) —— way
+ *                   团购状态(0-进行中 1-即将结束 2-已结束) —— groupbuy_state
+ * 
+ *          查询  调 wx_merchandise(团购表)
+ *                school_id —— 园所_id  园所是下拉  调 wx_school(园所表)
+ *                name —— 团购名称
+ *                groupbuy_state —— 团购状态(0-进行中 1-即将结束 2-已结束)
+ * 
+ *   新增编辑团购  新增 wx_merchandise(团购表) 
+ *                园所id —— school_id
+ *                团购名称 —— name
+ *                封面 —— img
+ *                收货方式(0-邮寄1-自提) —— way
+ *                编辑多个 _id
+ * 
+ *          删除  调 wx_merchandise(团购表)
+ *                传 _id
+ *                同时调 调 wx_groupbuy_groupbuy(团购规格表)
+ *                传 groupbuy_id 相同的全删
+ * 
+ *      二层表格   调 wx_groupbuy_groupbuy(团购规格表)
+ *      
+ *      字段展示   详情图 —— detail_images
+ *                产品详情 —— details
+ *                规格 —— count
+ *                原价 —— old_price
+ *                价格 —— price
+ * 
+ *  二层新增编辑团购   商品_id —— groupbuy_id
+ *                    详情图 —— detail_images (数组类型)
+ *                    产品详情 —— details
+ *                    规格 —— spec
+ *                    原价 —— old_price
+ *                    价格 —— price
+ *                    编辑多个 _id
+ * 
+ *              删除  调 wx_groupbuy_groupbuy(团购规格表)
+ *                    传 _id
+ * 
+ * 
+ * 
+ */
+
+async function findGroupBuyPageOld(parameter) {
+    const { school_id, groupbuy_name, groupbuy_state, startTime, endTime, pageNum, pageSize } = parameter
+    const v1 = validateField(pageNum)
+    if (!v1.flag) {
+        return {
+            success: false,
+            records: [],
+            msg: v1.msg
+        }
+    }
+    const v2 = validateField(pageSize)
+    if (!v2.flag) {
+        return {
+            success: false,
+            records: [],
+            msg: v2.msg
+        }
+    }
+    // 查询参数
+    const params = {}
+    // 拼接查询条件
+    let condition = ""
+    if (school_id != null) {
+        condition += " where m.school_id = {{school_id}} "
+        params.school_id = school_id
+    }
+    if (groupbuy_name != null) {
+        if (condition) {
+            condition += " and m.name like {{groupbuy_name}} "
+        } else {
+            condition += " where m.name like {{groupbuy_name}} "
+        }
+        params.groupbuy_name = groupbuy_name
+    }
+    if (groupbuy_state != null) {
+        if (condition) {
+            condition += " and m.groupbuy_state = {{groupbuy_state}} "
+        } else {
+            condition += " where m.groupbuy_state = {{groupbuy_state}} "
+        }
+        params.groupbuy_state = groupbuy_state
+    }
+    if (startTime != null && endTime != null) {
+        if (condition) {
+            condition += " and m.eventstarttime >= {{startTime}} and m.eventendstime <= {{endTime}} "
+        } else {
+            condition += " where m.eventstarttime >= {{startTime}} and m.eventendstime <= {{endTime}} "
+        }
+        params.startTime = startTime
+        params.endTime = endTime
+    }
+
+    const skip = (pageNum - 1) * pageSize
+    // 查询sql
+    const sql = "select s.name as schoolName, " +
+        "m.img as fengmian, " +
+        "m.name as tuangouName, " +
+        // 已拼数量
+        // 浏览量
+        "m.eventstarttime as kaishishijian, " +
+        "m.eventendstime as jieshushijian, " +
+        "m.way as shouhuofangshi, " +
+        "m.groupbuy_state as tuangouzhuangtai " +
+        "from wx_merchandise m " +
+        "left join wx_school s on m.school_id = s._id " +
+        condition +
+        " order by m.createdAt " + "limit " + skip + ", " + pageSize
+
+    // 查询数据sql
+    const records = await models.$runSQL(sql, params)
+    return {
+        sql,
+        params: { ...params },
+        success: true,
+        msg: '查询成功',
+        records: records.data.executeResultList,
+    }
+}
+async function findGroupBuyCountOld(parameter) {
+    const { school_id, groupbuy_name, groupbuy_state, startTime, endTime } = parameter
+    // 查询参数
+    const params = {}
+    // 拼接查询条件
+    let condition = ""
+    if (school_id != null) {
+        condition += " where m.school_id = {{school_id}} "
+        params.school_id = school_id
+    }
+    if (groupbuy_name != null) {
+        if (condition) {
+            condition += " and m.name like {{groupbuy_name}} "
+        } else {
+            condition += " where m.name like {{groupbuy_name}} "
+        }
+        params.groupbuy_name = groupbuy_name
+    }
+    if (groupbuy_state != null) {
+        if (condition) {
+            condition += " and m.groupbuy_state = {{groupbuy_state}} "
+        } else {
+            condition += " where m.groupbuy_state = {{groupbuy_state}} "
+        }
+        params.groupbuy_state = groupbuy_state
+    }
+    if (startTime != null && endTime != null) {
+        if (condition) {
+            condition += " and m.eventstarttime >= {{startTime}} and m.eventendstime <= {{endTime}} "
+        } else {
+            condition += " where m.eventstarttime >= {{startTime}} and m.eventendstime <= {{endTime}} "
+        }
+        params.startTime = startTime
+        params.endTime = endTime
+    }
+    // 查询总数sql
+    const sql = "select count(*) as total from wx_merchandise m " +
+        "left join wx_school s on m.school_id = s._id " +
+        condition
+
+    const count = await models.$runSQL(sql, params)
+    return {
+        sql,
+        success: true,
+        msg: '查询成功',
+        total: count.data.executeResultList[0].total
+    }
+}
+/**
+ * 分页查询团购数据
+ * @param {*} school_id 学校Id
+ * @param {*} groupbuy_name 团购名称
+ * @param {*} groupbuy_state 团购状态
+ * @param {*} startTime 开始时间
+ * @param {*} endTime 结束时间
+ * @param {*} pageNum 当前页
+ * @param {*} pageSize 每页展示数量
+ * @returns 分页数据
+ */
+async function findGroupBuyPage(parameter) {
+    const { school_id, groupbuy_name, groupbuy_state, startTime, endTime, pageNum, pageSize } = parameter
+    const v1 = validateField(pageNum)
+    if (!v1.flag) {
+        return {
+            success: false,
+            records: [],
+            msg: v1.msg
+        }
+    }
+    const v2 = validateField(pageSize)
+    if (!v2.flag) {
+        return {
+            success: false,
+            records: [],
+            msg: v2.msg
+        }
+    }
+    // 查询参数
+    const params = {
+        pageNum,
+        pageSize
+    }
+    // 拼接查询条件
+    let condition = ""
+    if (school_id != null) {
+        condition += " where m.school_id = {{school_id}} "
+        params.school_id = school_id
+    }
+    if (groupbuy_name != null) {
+        if (condition) {
+            condition += " and m.name like {{groupbuy_name}} "
+        } else {
+            condition += " where m.name like {{groupbuy_name}} "
+        }
+        params.groupbuy_name = groupbuy_name
+    }
+    if (groupbuy_state != null) {
+        if (condition) {
+            condition += " and m.groupbuy_state = {{groupbuy_state}} "
+        } else {
+            condition += " where m.groupbuy_state = {{groupbuy_state}} "
+        }
+        params.groupbuy_state = groupbuy_state
+    }
+    if (startTime != null && endTime != null) {
+        if (condition) {
+            condition += " and m.eventstarttime >= {{startTime}} and m.eventendstime <= {{endTime}} "
+        } else {
+            condition += " where m.eventstarttime >= {{startTime}} and m.eventendstime <= {{endTime}} "
+        }
+        params.startTime = startTime
+        params.endTime = endTime
+    }
+
+    const skip = (pageNum - 1) * pageSize
+    // 查询sql
+    const sql = "select m._id as id, " +
+        "s.name as schoolName, " +
+        "m.img as fengmian, " +
+        "m.name as tuangouName, " +
+        "m.browse as browse, " +
+        "m.count as count, " +
+        "m.school_id      as school_id, " +
+        "m.tag_id         as tag_id, " +
+        "m.eventstarttime as kaishishijian, " +
+        "m.eventendstime as jieshushijian, " +
+        "m.way as shouhuofangshi, " +
+        "m.groupbuy_state as tuangouzhuangtai " +
+        "from wx_merchandise m " +
+        "left join wx_school s on m.school_id = s._id " +
+        condition +
+        " order by m.createdAt " + "limit " + skip + ", " + pageSize
+    const countSql = "select count(*) as total from wx_merchandise m " + "left join wx_school s on m.school_id = s._id " + condition
+    try {
+        // 查询数据sql
+        const records = await models.$runSQL(sql, params)
+        const count = await models.$runSQL(countSql, params)
+        return {
+            sql,
+            countSql,
+            params,
+            success: true,
+            msg: '查询成功',
+            records: records.data.executeResultList,
+            total: count.data.executeResultList[0].total
+        }
+    } catch (error) {
+        return {
+            success: false,
+            msg: '查询失败',
+            params,
+            sql,
+            countSql,
+            error: error
+        }
+    }
+}
+/**
+ * 新增团购
+ * @param {*} school_id 园所Id
+ * @param {*} name 团购名称
+ * @param {*} img 封面
+ * @param {*} startTime 开始时间按
+ * @param {*} endTime 结束时间
+ * @param {*} way 收货方式
+ * @returns 
+ */
+async function addGroupBuy(parameter) {
+    const { schoolId, name, img, startTime, endTime, way, tagId } = parameter
+    const v1 = validateField(schoolId)
+    if (!v1.flag) {
+        return {
+            success: false,
+            msg: v1.msg
+        }
+    }
+    const v2 = validateField(name)
+    if (!v2.flag) {
+        return {
+            success: false,
+            msg: v2.msg
+        }
+    }
+    const v3 = validateField(img)
+    if (!v3.flag) {
+        return {
+            success: false,
+            msg: v3.msg
+        }
+    }
+    const v4 = validateField(startTime)
+    if (!v4.flag) {
+        return {
+            flag: false,
+            msg: v4.msg
+        }
+    }
+    const v5 = validateField(endTime)
+    if (!v5.flag) {
+        return {
+            flag: false,
+            msg: v5.msg
+        }
+    }
+    const v6 = validateField(way)
+    if (!v6.flag) {
+        return {
+            success: false,
+            msg: v6.msg
+        }
+    }
+    const v7 = validateField(tagId)
+    if (!v7.flag) {
+        return {
+            success: false,
+            msg: v7.msg
+        }
+    }
+
+    const data = {
+        school_id: schoolId,
+        name: name,
+        img: img,
+        eventstarttime: startTime,
+        eventendstime: endTime,
+        way: way,
+        tag_id: tagId,
+        count: 0,
+        browse: 0,
+    }
+    return await handleAdd(parameter, data, 'wx_merchandise')
+}
+/**
+ * 编辑团购
+ * @param {*} school_id 园所Id
+ * @param {*} name 团购名称
+ * @param {*} img 团购封面
+ * @param {*} way 收货方式(0-邮寄1-自提)
+ * @param {*} id 团购Id
+ * @returns 是否成功
+ */
+async function updateGroupBuy(parameter) {
+    const { id, schoolId, name, img, startTime, endTime, way, tagId } = parameter
+    const obj = {}
+    const v0 = validateField(id)
+    if (!v0.flag) {
+        return {
+            success: false,
+            records: [],
+            msg: v0.msg
+        }
+    }
+    const v1 = validateField(schoolId)
+    if (v1.flag) {
+        obj.school_id = schoolId
+    }
+    const v2 = validateField(name)
+    if (v2.flag) {
+        obj.name = name
+    }
+    const v3 = validateField(img)
+    if (v3.flag) {
+        obj.img = img
+    }
+    const v4 = validateField(startTime)
+    if (v4.flag) {
+        obj.eventstarttime = startTime
+    }
+    const v5 = validateField(endTime)
+    if (v5.flag) {
+        obj.eventendstime = endTime
+    }
+    const v6 = validateField(way)
+    if (v6.flag) {
+        obj.way = way
+    }
+    const v9 = validateField(tagId)
+    if (v9.flag) {
+        obj.tag_id = tagId
+    }
+
+    return await handleUpdate(parameter, id, obj, 'wx_merchandise')
+
+}
+/**
+ * 删除团购
+ * @param {*} id 团购Id
+ * @returns 是否成功
+ */
+async function deleteGroupBuy(parameter) {
+    const { id } = parameter
+    try {
+        // 删除商品表数据
+        const result1 = await models.wx_merchandise.delete({
+            filter: {
+                where: {
+                    $and: [
+                        {
+                            _id: {
+                                $eq: id,
+                            },
+                        },
+                    ]
+                }
+            },
+            envType: "prod",
+        })
+        // 删除商品规格表数据
+        const result2 = await models.wx_groupbuy_groupbuy.delete({
+            filter: {
+                where: {
+                    $and: [
+                        {
+                            groupbuy_id: {
+                                $eq: id,
+                            },
+                        },
+                    ]
+                }
+            },
+            envType: "prod",
+        })
+        return {
+            success: true,
+            msg: '删除数据成功',
+            data: {
+                shangpincount: result1.data.count,
+                shangpinguigecount: result2.data.count
+            },
+        }
+    } catch (error) {
+        return {
+            success: false,
+            msg: '删除数据失败',
+            error: error,
+            parameter
+        }
+    }
+}
+/**
+ * 根据团购Id查询规格
+ * @param {*} tuangou_id 团购Id
+ * @returns 团购规格数据List
+ */
+async function findguigeBytuangouId(parameter) {
+    const { tuangou_id } = parameter
+    // const sql = "select _id, price, old_price, spec, details, detail_images, groupbuy_id from wx_groupbuy_groupbuy where groupbuy_id = {{tuangou_id}}"
+    // const params = {
+    //     tuangou_id
+    // }
+    // const records = await models.$runSQL(sql, params)
+    const select = {
+        "_id": true,
+        "price": true,
+        "old_price": true,
+        "spec": true,
+        "details": true,
+        "detail_images": true,
+        "groupbuy_id": true
+    }
+    return await handleFindByField(select, 'groupbuy_id', tuangou_id, 'wx_groupbuy_groupbuy')
+}
+/**
+ * 新增商品规格
+ * @param {*} price 价格
+ * @param {*} old_price 原价
+ * @param {*} spec 规格名称
+ * @param {*} details 商品详情
+ * @param {*} detail_images 商品图片(数组) 
+ * @param {*} groupbuy_id 商品Id
+ * @returns 新增结果
+ */
+async function addguige(parameter) {
+    const { price, old_price, spec, details, detail_images, groupbuy_id } = parameter
+    const v1 = validateField(price)
+    if (!v1.flag) {
+        return {
+            success: false,
+            msg: v1.msg
+        }
+    }
+    const v2 = validateField(old_price)
+    if (!v2.flag) {
+        return {
+            success: false,
+            msg: v2.msg
+        }
+    }
+    const v3 = validateField(spec)
+    if (!v3.flag) {
+        return {
+            success: false,
+            msg: v3.msg
+        }
+    }
+    const v4 = validateField(groupbuy_id)
+    if (!v4.flag) {
+        return {
+            success: false,
+            msg: v4.msg
+        }
+    }
+    const data = {
+        price,
+        old_price,
+        spec,
+        details,
+        detail_images,
+        groupbuy_id
+    }
+    return await handleAdd(parameter, data, 'wx_groupbuy_groupbuy')
+}
+/**
+ * 编辑商品规格
+ * @param {*} id 规格Id
+ * @param {*} price 价格
+ * @param {*} old_price 原价
+ * @param {*} spec 规格名称
+ * @param {*} details 商品详情
+ * @param {*} detail_images 商品图片(数组) 
+ * @param {*} groupbuy_id 商品Id
+ * @returns 编辑结果
+ */
+async function updateguigeById(parameter) {
+    const { id, price, old_price, spec, details, detail_images, groupbuy_id } = parameter
+    const obj = {
+        details,
+        detail_images,
+    }
+    const v0 = validateField(id)
+    if (!v0.flag) {
+        return {
+            success: false,
+            msg: v0.msg
+        }
+    }
+    const v1 = validateField(price)
+    if (v1.flag) {
+        obj.price = price
+    }
+    const v2 = validateField(old_price)
+    if (v2.flag) {
+        obj.old_price = old_price
+    }
+    const v3 = validateField(spec)
+    if (v3.flag) {
+        obj.spec = spec
+    }
+    const v4 = validateField(groupbuy_id)
+    if (v4.flag) {
+        obj.old_price = groupbuy_id
+    }
+    return await handleUpdate(parameter, id, obj, 'wx_groupbuy_groupbuy')
+}
+
+/**
+ * 根据Id删除商品规格
+ * @param {*} id 规格Id 
+ */
+async function deleteguigeById(parameter) {
+    const { id } = parameter
+    return handleDelete(parameter, id, 'wx_groupbuy_groupbuy')
+}
+
+module.exports = {
+    findGroupBuyPage,
+    addGroupBuy,
+    updateGroupBuy,
+    deleteGroupBuy,
+    findguigeBytuangouId,
+    addguige,
+    updateguigeById,
+    deleteguigeById
+};

+ 232 - 0
cloud/database/interface/home.js

@@ -0,0 +1,232 @@
+const { models } = require('../db')
+
+
+// 获取今日起止时间
+function getTodayRange() {
+    const now = new Date();
+
+    // 当天起始时间(00:00:00.000)
+    const startOfDay = new Date(now);
+    startOfDay.setHours(0, 0, 0, 0);
+
+    // 当天结束时间(23:59:59.999)
+    const endOfDay = new Date(now);
+    endOfDay.setHours(23, 59, 59, 999);
+
+    return { startOfDay, endOfDay };
+}
+
+// 获取本年起止时间
+function getYearRange() {
+    const now = new Date();
+    const currentYear = now.getFullYear();
+
+    // 本年起始时间(1月1日 00:00:00.000)
+    const startOfYear = new Date(currentYear, 0, 1);
+
+    // 本年结束时间(12月31日 23:59:59.999)
+    const endOfYear = new Date(currentYear + 1, 0, 0); // 下一年1月0日即本年最后一天
+
+    return { startOfYear, endOfYear };
+}
+
+/**
+ * 今日今年下单付款统计
+ */
+async function findCountAndTotal() {
+    const todayRange = getTodayRange()
+    const sql = "select IF(count(*) <=> null, 0, count(*)) as ri_xiadan, IF(sum(real_money) <=> null, 0, sum(real_money)) as ri_jine from orders where createdAt >= {{start}} AND createdAt <= {{end}} and (status = 1 or status = 2)"
+    try {
+        const today = await models.$runSQL(sql, {
+            start: todayRange.startOfDay.getTime(),
+            end: todayRange.endOfDay.getTime(),
+        })
+        const todayData = today.data.executeResultList[0]
+        const yearRange = getYearRange()
+        const params = {
+            start: yearRange.startOfYear.getTime(),
+            end: yearRange.endOfYear.getTime(),
+        }
+        const year = await models.$runSQL(sql, params)
+        const yearData = year.data.executeResultList[0]
+        const result = {
+            ri_jine: todayData.ri_jine,
+            ri_xiadan: todayData.ri_xiadan,
+            nian_jine: yearData.ri_jine,
+            nian_xiadan: yearData.ri_xiadan
+        }
+        return {
+            success: true,
+            msg: '查询成功',
+            data: result,
+        }
+    } catch (error) {
+        console.error('error =>', error)
+        return {
+            success: false,
+            msg: '查询失败',
+            error: error,
+        }
+    }
+}
+
+/**
+ * 异常行为预警
+ */
+async function findBehaviorAlarm() {
+    try {
+        const sql = "select aba._id       as _id, " +
+            "       aba.file_name as file_name, " +
+            "       s.name        as school_name, " +
+            "       aba.reason    as reason, " +
+            "       aba.createdAt, " +
+            "       tu.name       as teacher_name " +
+            "from abnormal_behavior_alarm aba " +
+            "         left join wx_teacher_user tu on aba.user_id = tu._id " +
+            "         left join wx_school s on tu.school_id = s._id " +
+            "where aba.type = 0 " +
+            "order by aba.createdAt desc " +
+            "limit 4 "
+        const result = await models.$runSQL(sql, {})
+        return {
+            success: true,
+            msg: '查询成功',
+            data: result.data.executeResultList,
+        }
+    } catch (error) {
+        console.error('error =>', error)
+        return {
+            success: false,
+            msg: '查询失败',
+            error: error,
+        }
+    }
+}
+/**
+ * 按月份统计下单量
+ * @param {*} parameter 年份 e.g: 2025
+ */
+async function findOrderCountByMonth(parameter) {
+    const { year } = parameter
+    try {
+        // const sql = "WITH RECURSIVE months AS ( " +
+        //     "    SELECT 1 AS month_num " +
+        //     "    UNION ALL " +
+        //     "    SELECT month_num + 1 " +
+        //     "    FROM months " +
+        //     "    WHERE month_num < 12 " +
+        //     "), " +
+        //     "target_year AS ( " +
+        //     "    SELECT COALESCE(YEAR(FROM_UNIXTIME(MIN(createdAt)/1000)), YEAR(CURDATE())) AS year " +
+        //     "    FROM orders " +
+        //     ") " +
+        //     "SELECT " +
+        //     "    ty.year, " +
+        //     "    CONCAT(ty.year, '-', LPAD(m.month_num, 2, '0')) AS month, " +
+        //     "    COUNT(o._id) AS order_count " +
+        //     "FROM target_year ty " +
+        //     "CROSS JOIN months m " +
+        //     "LEFT JOIN orders o " +
+        //     "    ON DATE_FORMAT(FROM_UNIXTIME(o.createdAt/1000), '%Y-%m') = CONCAT(ty.year, '-', LPAD(m.month_num, 2, '0')) " +
+        //     "where ty.year = {{searchYear}}" +
+        //     " GROUP BY ty.year, m.month_num " +
+        //     "ORDER BY ty.year, m.month_num "
+        const sql = "select * " +
+            "from (select COUNT(*)                                                     as count, " +
+            "             DATE_FORMAT(FROM_UNIXTIME(orders.createdAt / 1000), '%Y-%m') as month, " +
+            "             DATE_FORMAT(FROM_UNIXTIME(orders.createdAt / 1000), '%Y')    as year " +
+            "      from orders " +
+            "      group by month, year " +
+            "      order by year, month) t " +
+            "where year = {{searchYear}}"
+        const result = await models.$runSQL(sql, { searchYear: year })
+        console.log(result.data);
+        return {
+            success: true,
+            msg: '查询成功',
+            data: result.data.executeResultList,
+        }
+    } catch (error) {
+        console.error('error =>', error)
+        return {
+            success: false,
+            msg: '查询失败',
+            error: error,
+        }
+    }
+}
+/**
+ * 按天统计下单量
+ * @param {*} parameter 年份 e.g: 2025
+ * @returns 
+ */
+async function findOrderCountByDay(parameter) {
+    const { year } = parameter
+    try {
+        const sql = "select * " +
+            "from (select COUNT(*)                                                        as count, " +
+            "             DATE_FORMAT(FROM_UNIXTIME(orders.createdAt / 1000), '%Y-%m-%d') as day, " +
+            "             DATE_FORMAT(FROM_UNIXTIME(orders.createdAt / 1000), '%Y')       as year " +
+            "      from orders " +
+            "      group by day, year " +
+            "      order by year, day) t " +
+            "where year = {{searchYear}}"
+        const params = {
+            searchYear: year
+        }
+        const result = await models.$runSQL(sql, params)
+        return {
+            success: true,
+            msg: '查询成功',
+            data: result.data.executeResultList,
+        }
+    } catch (error) {
+        console.error('error =>', error)
+        return {
+            success: false,
+            msg: '查询失败',
+            error: error,
+        }
+    }
+}
+/**
+ * 按月份分组查询课件上传统计
+ * @param {*} parameter 年份 e.g: 2025
+ */
+async function findFileCount(parameter) {
+    const { year } = parameter
+    try {
+        const sql = "select * " +
+            "from (select COUNT(*)                                                     as count, " +
+            "             DATE_FORMAT(FROM_UNIXTIME(createdAt / 1000), '%Y-%m') as month, " +
+            "             DATE_FORMAT(FROM_UNIXTIME(createdAt / 1000), '%Y')    as year " +
+            "      from file_manage " +
+            "      group by month, year " +
+            "      order by year, month) t " +
+            "where year = {{searchYear}}"
+        const params = {
+            searchYear: year
+        }
+        const result = await models.$runSQL(sql, params)
+        return {
+            success: true,
+            msg: '查询成功',
+            data: result.data.executeResultList,
+        }
+    } catch (error) {
+        console.error('error =>', error)
+        return {
+            success: false,
+            msg: '查询失败',
+            error: error,
+        }
+    }
+}
+
+module.exports = {
+    findCountAndTotal,
+    findBehaviorAlarm,
+    findOrderCountByMonth,
+    findOrderCountByDay,
+    findFileCount,
+}

+ 385 - 0
cloud/database/interface/order.js

@@ -0,0 +1,385 @@
+const { models } = require('../db')
+const { validateField, handleAdd, handleUpdate, handleDelete, handleFindByField } = require('../common')
+
+/**
+ * 
+ * 订单管理    表格   调 orders(订单表)
+ * 
+ *         字段展示   用户名  根据 订单表 user_id 去 家长表(wx_user)里查_id是否相同 相同取园所名称(name)
+ *                   规格 —— groupbuy_id  根据 订单表 groupbuy_id 去 规格表(wx_groupbuy_groupbuy)里查_id是否相同 相同取园所名称(spec)
+ *                   团购名称 —— merchandise_id  根据 订单表 merchandise_id 去 商品表(wx_merchandise)里查_id是否相同 相同取园所名称(name)
+ *                   下单数量 —— num_index
+ *                   订单状态(0-待付款 1-待收货 2-已完成 3-已取消) —— status
+ *                   收货方式(0-邮寄1-自提) —— eventstarttime
+ *                   订单号 —— order_id
+ *                   物流单号 —— tracking_number
+ *                   修改前地址、 修改前手机号、 修改前收货人 这三字段需要根据 地址id(adresses_id)去 地址表(adresses)里查_id是否相同 相同取园所名称(收货人:name、手机号:phone、地址:address )
+ *                   修改后地址 —— updat_adress
+ *                   修改后手机号 —— update_phone
+ *                   修改后收货人 —— update_name
+ *                   下单时间 —— createdAt
+ * 
+ *          查询  调 orders(订单表)
+ *                merchandise_id —— 团购名称  根据 订单表 merchandise_id 去 商品表(wx_merchandise)里查_id是否相同 相同取园所名称(name)
+ *                user_id —— 用户名    根据 订单表 user_id 去 家长表(wx_user)里查_id是否相同 相同取园所名称(name)
+ *                status —— 订单状态(0-待付款 1-待收货 2-已完成 3-已取消)
+ *                order_id —— 订单号
+ *                tracking_number —— 物流单号
+ * 
+ *       编辑订单  改 orders(订单表) 
+ *                修改后姓名 —— update_name
+ *                修改后手机号 —— update_phone
+ *                修改后地址 —— updat_adress
+ *   填写物流单号  改 orders(订单表) 
+ *                传 _id、 tracking_number 根据 _id 查到 订单表里面的那条数据里面的 tracking_number 更新这个数据
+ * 
+ *          删除  调 orders(订单表)
+ *                传 _id
+ * 
+ * 
+ */
+
+/**
+ * 新增
+ * @param {*} order_id 订单Id
+ * @param {*} user_id 用户Id
+ * @param {*} merchandise_id 商品Id 
+ * @param {*} groupbuy_id 规格Id
+ * @param {*} num_index 购买数量
+ * @param {*} real_money 实际付款金额
+ * @param {*} adresses_id 地址id
+ * @param {*} tracking_number 物流单号
+ * @param {*} update_phone 修改后的手机号
+ * @param {*} update_name 修改后的收货人
+ * @param {*} updat_adress 修改后地址
+ * @param {*} status 0-待付款 1-待收货 2-已完成 3-已取消
+ * @returns 
+ */
+async function addOrder(parameter) {
+    const { order_id, user_id, merchandise_id, groupbuy_id, num_index, real_money, adresses_id, tracking_number, update_phone, update_name, updat_adress, status } = parameter
+    const v1 = validateField(order_id, 'order_id')
+    if (!v1.flag) {
+        return {
+            success: false,
+            msg: v1.msg
+        }
+    }
+    const v2 = validateField(user_id, 'user_id')
+    if (!v2.flag) {
+        return {
+            success: false,
+            msg: v2.msg
+        }
+    }
+    const v3 = validateField(merchandise_id, 'merchandise_id')
+    if (!v3.flag) {
+        return {
+            success: false,
+            msg: v3.msg
+        }
+    }
+    const v4 = validateField(groupbuy_id, 'groupbuy_id')
+    if (!v4.flag) {
+        return {
+            success: false,
+            msg: v4.msg
+        }
+    }
+    const v5 = validateField(num_index, 'num_index')
+    if (!v5.flag) {
+        return {
+            success: false,
+            msg: v5.msg
+        }
+    }
+    const v6 = validateField(real_money, 'real_money')
+    if (!v6.flag) {
+        return {
+            success: false,
+            msg: v6.msg
+        }
+    }
+    const v7 = validateField(adresses_id, 'adresses_id')
+    if (!v7.flag) {
+        return {
+            success: false,
+            msg: v7.msg
+        }
+    }
+    const data = {
+        order_id, user_id, merchandise_id, groupbuy_id, num_index, real_money, adresses_id, tracking_number, update_phone, update_name, updat_adress, status: status == null ? 0 : status
+    }
+    return await handleAdd(parameter, data, 'orders')
+}
+/**
+ * 根据Id删除
+ * @param {*} _id 主键Id 
+ */
+async function deleteOrder(parameter) {
+    const { _id } = parameter
+    try {
+        // 更新数据
+        const result = await models.orders.update({
+            data: { delete: 1 },
+            filter: {
+                where: {
+                    _id: {
+                        $eq: _id
+                    }
+                }
+            }
+        })
+        return {
+            success: true,
+            msg: '删除数据成功',
+            data: result,
+        }
+    } catch (error) {
+        return {
+            success: false,
+            msg: '删除数据失败',
+            error: error,
+            parameter
+        }
+    }
+}
+/**
+ * 编辑
+ * @param {*} _id 主键Id
+ * @param {*} order_id 订单号
+ * @param {*} user_id 用户Id
+ * @param {*} merchandise_id 商品Id 
+ * @param {*} groupbuy_id 规格Id
+ * @param {*} num_index 购买数量
+ * @param {*} real_money 实际付款金额
+ * @param {*} adresses_id 地址Id
+ * @param {*} tracking_number 物流单号
+ * @param {*} update_phone 修改后的手机号
+ * @param {*} update_name 修改后的收货人
+ * @param {*} updat_adress 修改后地址
+ * @param {*} status 订单状态
+ * @returns 
+ */
+async function updateOrder(parameter) {
+    const { _id, order_id, user_id, merchandise_id, groupbuy_id, num_index, real_money, adresses_id, tracking_number, update_phone, update_name, updat_adress, status } = parameter
+    const obj = {}
+    const v0 = validateField(_id, '_id')
+    if (!v0.flag) {
+        return {
+            success: false,
+            msg: v0.msg
+        }
+    }
+    const v1 = validateField(order_id, 'order_id')
+    if (v1.flag) {
+        obj.order_id = order_id
+    }
+    const v2 = validateField(user_id, 'user_id')
+    if (v2.flag) {
+        obj.user_id = user_id
+    }
+    const v3 = validateField(merchandise_id, 'merchandise_id')
+    if (v3.flag) {
+        obj.merchandise_id = merchandise_id
+    }
+    const v4 = validateField(groupbuy_id, 'groupbuy_id')
+    if (v4.flag) {
+        obj.groupbuy_id = groupbuy_id
+    }
+    const v5 = validateField(num_index, 'num_index')
+    if (v5.flag) {
+        obj.num_index = num_index
+    }
+    const v6 = validateField(real_money, 'real_money')
+    if (v6.flag) {
+        obj.real_money = real_money
+    }
+    const v7 = validateField(adresses_id, 'adresses_id')
+    if (v7.flag) {
+        obj.adresses_id = adresses_id
+    }
+    const v8 = validateField(tracking_number, 'tracking_number')
+    if (v8.flag) {
+        obj.tracking_number = tracking_number
+    }
+    const v9 = validateField(update_phone, 'update_phone')
+    if (v9.flag) {
+        obj.update_phone = update_phone
+    }
+    const v10 = validateField(update_name, 'update_name')
+    if (v10.flag) {
+        obj.update_name = update_name
+    }
+    const v11 = validateField(updat_adress, 'updat_adress')
+    if (v11.flag) {
+        obj.updat_adress = updat_adress
+    }
+    const v12 = validateField(status, 'status')
+    if (v12.flag) {
+        obj.status = status
+    }
+    return await handleUpdate(parameter, _id, obj, 'orders')
+}
+/**
+ * 分页查询
+ * @param {*} name 团购名称
+ * @param {*} user_name 用户名
+ * @param {*} status 订单状态
+ * @param {*} order_id 订单号
+ * @param {*} tracking_number 物流单号 
+ * @param {*} startTime 开始时间
+ * @param {*} endTime 结束时间
+ * @param {*} pageNum 当前页数
+ * @param {*} pageSize 每页展示数量
+ * @returns 
+ */
+async function findOrderPage(parameter) {
+    const { name, user_name, status, order_id, tracking_number, startTime, endTime, pageNum, pageSize } = parameter
+    const v1 = validateField(pageNum)
+    if (!v1.flag) {
+        return {
+            success: false,
+            records: [],
+            msg: v1.msg
+        }
+    }
+    const v2 = validateField(pageSize)
+    if (!v2.flag) {
+        return {
+            success: false,
+            records: [],
+            msg: v2.msg
+        }
+    }
+    // 查询参数
+    const params = {
+        pageNum,
+        pageSize
+    }
+    // 拼接查询条件
+    let condition = ""
+    if (name != null) {
+        condition += " where m.name like {{name}} "
+        params.name = '%' + name + '%'
+    }
+    if (user_name != null) {
+        if (condition) {
+            condition += " and u.user_name like {{user_name}} "
+        } else {
+            condition += " where u.user_name like {{user_name}} "
+        }
+        params.user_name = '%' + user_name + '%'
+    }
+    if (status != null) {
+        if (condition) {
+            condition += " and o.status = {{status}} "
+        } else {
+            condition += " where o.status = {{status}} "
+        }
+        params.status = status
+    }
+    if (order_id != null) {
+        if (condition) {
+            condition += " and o.order_id = {{order_id}} "
+        } else {
+            condition += " where o.order_id = {{order_id}} "
+        }
+        params.order_id = order_id
+    }
+    if (tracking_number != null) {
+        if (condition) {
+            condition += " and o.tracking_number = {{tracking_number}} "
+        } else {
+            condition += " where o.tracking_number = {{tracking_number}} "
+        }
+        params.tracking_number = tracking_number
+    }
+    if (startTime != null && endTime != null) {
+        if (condition) {
+            condition += " and o.createdAt >= {{startTime}} and o.createdAt <= {{endTime}} "
+        } else {
+            condition += " where o.createdAt >= {{startTime}} and o.createdAt <= {{endTime}} "
+        }
+        params.startTime = startTime
+        params.endTime = endTime
+    }
+
+    if (condition) {
+        condition += " and o.delete = 0"
+    } else {
+        condition += " where o.delete = 0"
+    }
+
+    const skip = (pageNum - 1) * pageSize
+    // 查询sql
+    const sql = "select " +
+        "gg.spec     as spec, " +
+        "o._id             as _id, " +
+        "u.user_name       as username, " +
+        "m.name            as tuangoumingcheng, " +
+        "gg.spec           as guige, " +
+        "o.num_index       as xiadanshuliang, " +
+        "o.status          as dingdanzhuangtai, " +
+        "m.way             as shouhuofangshi, " +
+        "o.order_id        as dingdanhao, " +
+        "o.tracking_number as wuliudanhao, " +
+        "addr.address      as addressBefore, " +
+        "o.updat_adress    as addressAfter, " +
+        "addr.phone        as phoneBefore, " +
+        "o.update_phone    as phoneAfter, " +
+        "addr.name         as shouhuorenBefore, " +
+        "o.update_name     as shouhuorenAfter, " +
+        "o.createdAt       as createdAt " +
+        "from orders o " +
+        "left join wx_user u on o.user_id = u._id " +
+        "left join wx_merchandise m on o.merchandise_id = m._id " +
+        "left join wx_groupbuy_groupbuy gg on o.groupbuy_id = gg._id " +
+        "left join adresses addr on o.adresses_id = addr._id " +
+        condition +
+        " order by o.createdAt desc " + "limit " + skip + ", " + pageSize
+    const countSql = "select count(*) as total from orders o " +
+        "left join wx_user u on o.user_id = u._id " +
+        "left join wx_merchandise m on o.merchandise_id = m._id " +
+        "left join wx_groupbuy_groupbuy gg on o.groupbuy_id = gg._id " +
+        "left join adresses addr on o.adresses_id = addr._id " +
+        condition
+    try {
+        // 查询数据sql
+        const records = await models.$runSQL(sql, params)
+        const count = await models.$runSQL(countSql, params)
+        return {
+            sql,
+            countSql,
+            params,
+            success: true,
+            msg: '查询成功',
+            records: records.data.executeResultList,
+            total: count.data.executeResultList[0].total
+        }
+    } catch (error) {
+        return {
+            success: false,
+            msg: '查询失败',
+            params,
+            sql,
+            countSql,
+            error: error
+        }
+    }
+}
+/**
+ * 根据Id查询
+ * @param {*} _id Id 
+ */
+async function findOrderById(parameter) {
+    const { _id } = parameter
+    return handleFindByField(parameter, _id, 'orders')
+}
+
+module.exports = {
+    addOrder,
+    deleteOrder,
+    updateOrder,
+    findOrderPage,
+    findOrderById,
+}

+ 197 - 0
cloud/database/interface/payment.js

@@ -0,0 +1,197 @@
+const { models } = require('../db')
+const { validateField } = require('../common')
+/**
+ * 
+ * 付款统计
+ * 
+ */
+/**
+ * 分页查询付款统计数据(按照班级分组)
+ * @param {*} school_id 学校Id
+ * @param {*} grade 年级
+ * @param {*} pageNum 当前页
+ * @param {*} pageSize 每页展示数量
+ * @returns 分页数据
+ */
+async function findPaymentPage(parameter) {
+    const { school_id, grade, pageNum, pageSize } = parameter
+    const v1 = validateField(pageNum)
+    if (!v1.flag) {
+        return {
+            success: false,
+            records: [],
+            msg: v1.msg
+        }
+    }
+    const v2 = validateField(pageSize)
+    if (!v2.flag) {
+        return {
+            success: false,
+            records: [],
+            msg: v2.msg
+        }
+    }
+    // 查询参数
+    const params = {
+        pageNum,
+        pageSize
+    }
+    // 拼接查询条件
+    let condition = ""
+    if (school_id != null) {
+        condition += " where s._id = {{school_id}} "
+        params.school_id = school_id
+    }
+    if (grade != null) {
+        if (condition) {
+            condition += " and u.grade = {{grade}} "
+        } else {
+            condition += " where u.grade = {{grade}} "
+        }
+        params.grade = grade
+    }
+
+    const skip = (pageNum - 1) * pageSize
+    // 查询sql
+    const sql = "select * " +
+        "from (select s.name                                       as schoolName, " +
+        "             u.grade                                      as grade, " +
+        "             count(IF(o.status IN (0, 3), o._id, NULL))   as unpaidCount, " +
+        "             count(IF(o.status IN (1, 2), o._id, NULL))   as paidCount, " +
+        "             sum(IF(o.status IN (0, 3), o.real_money, 0)) as unpaidMoney, " +
+        "             sum(IF(o.status IN (1, 2), o.real_money, 0)) as paidMoney " +
+        "      from orders o " +
+        "               left join wx_user u on o.user_id = u._id " +
+        "               left join wx_school s on u.school_id = s._id " +
+        condition +
+        "      group by s.name, u.grade) as t " +
+        "limit " + skip + ", " + pageSize
+    const countSql = "select count(*) as total " +
+        "from (select s.name                                       as schoolName," +
+        "             u.grade                                      as grade, " +
+        "             count(IF(o.status IN (0, 3), o._id, NULL))   as unpaidCount, " +
+        "             count(IF(o.status IN (1, 2), o._id, NULL))   as paidCount, " +
+        "             sum(IF(o.status IN (0, 3), o.real_money, 0)) as unpaidMoney, " +
+        "             sum(IF(o.status IN (1, 2), o.real_money, 0)) as paidMoney " +
+        "      from orders o " +
+        "               left join wx_user u on o.user_id = u._id " +
+        "               left join wx_school s on u.school_id = s._id " +
+        condition +
+        "       group by s.name, u.grade) as t "
+    try {
+        // 查询数据sql
+        const records = await models.$runSQL(sql, params)
+        const count = await models.$runSQL(countSql, params)
+        return {
+            sql,
+            countSql,
+            params,
+            success: true,
+            msg: '查询成功',
+            records: records.data.executeResultList,
+            total: count.data.executeResultList[0].total
+        }
+    } catch (error) {
+        return {
+            success: false,
+            msg: '查询失败',
+            params,
+            sql,
+            countSql,
+            error: error
+        }
+    }
+}
+
+/**
+ * 分页查询付款统计数据(按照学校分组)
+ * @param {*} school_id 学校Id
+ * @param {*} pageNum 当前页
+ * @param {*} pageSize 每页展示数量
+ * @returns 分页数据
+ */
+async function findPaymentPageBySchool(parameter) {
+    const { school_id, pageNum, pageSize } = parameter
+    const v1 = validateField(pageNum)
+    if (!v1.flag) {
+        return {
+            success: false,
+            records: [],
+            msg: v1.msg
+        }
+    }
+    const v2 = validateField(pageSize)
+    if (!v2.flag) {
+        return {
+            success: false,
+            records: [],
+            msg: v2.msg
+        }
+    }
+    // 查询参数
+    const params = {
+        pageNum,
+        pageSize
+    }
+    // 拼接查询条件
+    let condition = ""
+    if (school_id != null) {
+        condition += " where s._id = {{school_id}} "
+        params.school_id = school_id
+    }
+
+    const skip = (pageNum - 1) * pageSize
+    // 查询sql
+    const sql = "select * " +
+        "from (select s.name                                       as schoolName, " +
+        "             count(IF(o.status IN (0, 3), o._id, NULL))   as unpaidCount, " +
+        "             count(IF(o.status IN (1, 2), o._id, NULL))   as paidCount, " +
+        "             sum(IF(o.status IN (0, 3), o.real_money, 0)) as unpaidMoney, " +
+        "             sum(IF(o.status IN (1, 2), o.real_money, 0)) as paidMoney " +
+        "      from orders o " +
+        "               left join wx_user u on o.user_id = u._id " +
+        "               left join wx_school s on u.school_id = s._id " +
+        condition +
+        "      group by s.name) as t " +
+        "limit " + skip + ", " + pageSize
+    const countSql = "select count(*) as total " +
+        "from (select s.name                                       as schoolName," +
+        "             u.grade                                      as grade, " +
+        "             count(IF(o.status IN (0, 3), o._id, NULL))   as unpaidCount, " +
+        "             count(IF(o.status IN (1, 2), o._id, NULL))   as paidCount, " +
+        "             sum(IF(o.status IN (0, 3), o.real_money, 0)) as unpaidMoney, " +
+        "             sum(IF(o.status IN (1, 2), o.real_money, 0)) as paidMoney " +
+        "      from orders o " +
+        "               left join wx_user u on o.user_id = u._id " +
+        "               left join wx_school s on u.school_id = s._id " +
+        condition +
+        "       group by s.name, u.grade) as t "
+    try {
+        // 查询数据sql
+        const records = await models.$runSQL(sql, params)
+        const count = await models.$runSQL(countSql, params)
+        return {
+            sql,
+            countSql,
+            params,
+            success: true,
+            msg: '查询成功',
+            records: records.data.executeResultList,
+            total: count.data.executeResultList[0].total
+        }
+    } catch (error) {
+        return {
+            success: false,
+            msg: '查询失败',
+            params,
+            sql,
+            countSql,
+            error: error
+        }
+    }
+}
+
+module.exports = {
+    findPaymentPage,
+    findPaymentPageBySchool,
+}

+ 30 - 0
cloud/database/interface/recommend.js

@@ -0,0 +1,30 @@
+const { models } = require('../db')
+const { validateField, handleAdd, handleUpdate, handleDelete } = require('../common')
+
+async function findFileRangee(parameter) {
+    const { _id, rangee, tag_id } = parameter
+
+    //sql语句
+    const sql = "select * from file_manage where _id != '" + _id + "' and tag_id = '" + tag_id + "' and rangee REGEXP '" + rangee + "'"
+    try {
+        // 查询数据sql
+        const records = await models.$runSQL(sql)
+        return {
+            sql,
+            success: true,
+            msg: '查询成功',
+            records: records.data.executeResultList,
+        }
+    } catch (error) {
+        return {
+            success: false,
+            msg: '查询失败',
+            sql,
+            error: error
+        }
+    }
+}
+
+module.exports = {
+    findFileRangee
+}

+ 219 - 0
cloud/database/interface/userstats.js

@@ -0,0 +1,219 @@
+const { models } = require('../db')
+const { validateField, handleAdd, handleUpdate, handleDelete, handleFindByField } = require('../common')
+
+/**
+ * 
+ * 记录用户行为 表格   调 monitor_behavior(监听用户行为)
+ * 
+ *         字段展示   用户名  根据 监听用户行为表 user_id 去 老师表(wx_teacher_user)里查_id是否相同 相同取园所名称(name)
+ *                   进入时间 —— start_time
+ *                   退出时间 —— end_time
+ *                   流量时长 —— duration
+ *                   修改后手机号 —— update_phone
+ *                   修改后收货人 —— update_name
+ *                   下单时间 —— createdAt
+ * 
+ *          查询  调 monitor_behavior(监听用户行为)
+ *                createdAt —— 创建时间
+ * 
+ * 
+ */
+/**
+ * 新增
+ * @param {*} user_id 用户Id
+ * @param {*} type 用户端(0-教师 1-家长)
+ * @param {*} duration 时长
+ * @param {*} start_time 进入时间
+ * @param {*} end_time 退出时间
+ * @param {*} file_id 课件Id
+ * @returns 
+ */
+async function addMmonitorBehavior(parameter) {
+    const { user_id, type, duration, start_time, end_time, file_id } = parameter
+    const v1 = validateField(user_id, 'user_id')
+    if (!v1.flag) {
+        return {
+            success: false,
+            msg: v1.msg
+        }
+    }
+    const v2 = validateField(type, 'type')
+    if (!v2.flag) {
+        return {
+            success: false,
+            msg: v2.msg
+        }
+    }
+    const v3 = validateField(file_id, 'file_id')
+    if (!v3.flag) {
+        return {
+            success: false,
+            msg: v3.msg
+        }
+    }
+    const v4 = validateField(start_time, 'start_time')
+    if (!v4.flag) {
+        return {
+            success: false,
+            msg: v4.msg
+        }
+    }
+
+    const data = {
+        user_id, type, duration, start_time, end_time
+    }
+    return await handleAdd(parameter, data, 'monitor_behavior')
+}
+/**
+ * 根据Id删除
+ * @param {*} _id Id 
+ */
+async function deleteMmonitorBehavior(parameter) {
+    const { _id } = parameter
+    return handleDelete(parameter, _id, 'monitor_behavior')
+}
+/**
+ * 编辑
+ * @param {*} _id 主键Id
+ * @param {*} user_id 用户Id
+ * @param {*} type 用户端(0-教师 1-家长)
+ * @param {*} duration 时长
+ * @param {*} start_time 进入时间
+ * @param {*} end_time 退出时间
+ * @param {*} file_id 课件Id
+ * @returns 
+ */
+async function updateMmonitorBehavior(parameter) {
+    const { _id, user_id, type, duration, start_time, end_time, file_id } = parameter
+    const obj = {}
+    const v0 = validateField(_id, '_id')
+    if (!v0.flag) {
+        return {
+            success: false,
+            msg: v0.msg
+        }
+    }
+    const v1 = validateField(user_id, 'user_id')
+    if (v1.flag) {
+        obj.user_id = user_id
+    }
+    const v2 = validateField(type, 'type')
+    if (v2.flag) {
+        obj.type = type
+    }
+    const v3 = validateField(duration, 'duration')
+    if (v3.flag) {
+        obj.duration = duration
+    }
+    const v4 = validateField(start_time, 'start_time')
+    if (v4.flag) {
+        obj.start_time = start_time
+    }
+    const v5 = validateField(end_time, 'end_time')
+    if (v5.flag) {
+        obj.end_time = end_time
+    }
+    const v6 = validateField(file_id, 'file_id')
+    if (v6.flag) {
+        obj.file_id = file_id
+    }
+    return await handleUpdate(parameter, _id, obj, 'monitor_behavior')
+}
+/**
+ * 分页查询
+ * @param {*} startTime 开始时间
+ * @param {*} endTime 结束时间
+ * @param {*} pageNum 当前页面
+ * @param {*} pageSize 每页展示数量
+ * @returns 分页数据
+ */
+async function findMmonitorBehaviorPage(parameter) {
+    const { startTime, endTime, pageNum, pageSize } = parameter
+    const v1 = validateField(pageNum)
+    if (!v1.flag) {
+        return {
+            success: false,
+            records: [],
+            msg: v1.msg
+        }
+    }
+    const v2 = validateField(pageSize)
+    if (!v2.flag) {
+        return {
+            success: false,
+            records: [],
+            msg: v2.msg
+        }
+    }
+    // 查询参数
+    const params = {
+        pageNum,
+        pageSize
+    }
+    // 拼接查询条件
+    let condition = ""
+    if (startTime != null && endTime != null) {
+        condition += " where mb.createdAt >= {{startTime}} and mb.createdAt <= {{endTime}} "
+        params.startTime = startTime
+        params.endTime = endTime
+    }
+
+    const skip = (pageNum - 1) * pageSize
+    // 查询sql
+    const sql = "select " +
+        "mb._id, " +
+        "tu.user_name, " +
+        "mb.start_time, " +
+        "mb.end_time, " +
+        "mb.duration, " +
+        "mb.createdAt, " +
+        "(select count(*) from download_history dh where dh.user_id = mb.user_id and mb.file_id = dh.file_manage_id) as total " +
+        "from monitor_behavior mb " +
+        "left join wx_teacher_user tu on mb.user_id = tu._id " +
+        condition +
+        " order by mb.createdAt desc " + "limit " + skip + ", " + pageSize
+
+
+    const countSql = "select count(*) as total from monitor_behavior mb " +
+        "left join wx_teacher_user tu on mb.user_id = tu._id " +
+        condition
+    try {
+        // 查询数据sql
+        const records = await models.$runSQL(sql, params)
+        const count = await models.$runSQL(countSql, params)
+        return {
+            sql,
+            countSql,
+            params,
+            success: true,
+            msg: '查询成功',
+            records: records.data.executeResultList,
+            total: count.data.executeResultList[0].total
+        }
+    } catch (error) {
+        return {
+            success: false,
+            msg: '查询失败',
+            params,
+            sql,
+            countSql,
+            error: error
+        }
+    }
+}
+/**
+ * 根据Id查询
+ * @param {*} _id Id 
+ */
+async function findMmonitorBehaviorById(parameter) {
+    const { _id } = parameter
+    return handleFindByField(parameter, _id, 'monitor_behavior')
+}
+
+module.exports = {
+    addMmonitorBehavior,
+    deleteMmonitorBehavior,
+    updateMmonitorBehavior,
+    findMmonitorBehaviorPage,
+    findMmonitorBehaviorById,
+}

+ 3355 - 0
cloud/database/package-lock.json

@@ -0,0 +1,3355 @@
+{
+  "name": "@function/database",
+  "version": "1.0.0",
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {
+    "": {
+      "name": "@function/database",
+      "version": "1.0.0",
+      "license": "ISC",
+      "dependencies": {
+        "@cloudbase/node-sdk": "^3.7.0"
+      },
+      "devDependencies": {
+        "@cloudbase/functions-framework": "^1.8.0"
+      }
+    },
+    "node_modules/@babel/code-frame": {
+      "version": "7.27.1",
+      "resolved": "http://mirrors.tencent.com/npm/@babel/code-frame/-/code-frame-7.27.1.tgz",
+      "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-validator-identifier": "^7.27.1",
+        "js-tokens": "^4.0.0",
+        "picocolors": "^1.1.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-validator-identifier": {
+      "version": "7.27.1",
+      "resolved": "http://mirrors.tencent.com/npm/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
+      "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@cloudbase/database": {
+      "version": "1.4.2",
+      "resolved": "http://mirrors.tencent.com/npm/@cloudbase/database/-/database-1.4.2.tgz",
+      "integrity": "sha512-W4kvlNFstj2ahMQtuE6DVRGYFlhxoCn10dAODZ0UMRqxrGaojsGwX9gF2uURBxPYRnIhukt3lz/DkQi/asSHpQ==",
+      "license": "ISC",
+      "dependencies": {
+        "bson": "^4.0.3",
+        "lodash.clonedeep": "4.5.0",
+        "lodash.set": "4.3.2",
+        "lodash.unset": "4.5.2"
+      }
+    },
+    "node_modules/@cloudbase/functions-framework": {
+      "version": "1.14.0",
+      "resolved": "http://mirrors.tencent.com/npm/@cloudbase/functions-framework/-/functions-framework-1.14.0.tgz",
+      "integrity": "sha512-e1z8tBMJlB2o3oqf3IQGatYaCTrdH4JxGAln6Sqo1Km3kC76S3rIjFPhEYvO0NFStdl13g99Q+d/s7W5dyQH8g==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@cloudbase/functions-typings": "^1.2.1",
+        "@dotenvx/dotenvx": "^1.43.0",
+        "@koa/cors": "^5.0.0",
+        "@types/ws": "^8.5.12",
+        "ajv": "^8.17.1",
+        "koa": "^2.15.3",
+        "koa-body": "^6.0.1",
+        "koa-compose": "^4.1.0",
+        "koa-convert": "^2.0.0",
+        "minimist": "^1.2.8",
+        "nodemon": "^3.1.4",
+        "radix3": "^1.1.2",
+        "raw-body": "^3.0.0",
+        "read-pkg-up": "^7.0.1",
+        "uuid": "^10.0.0",
+        "whatwg-mimetype": "^4.0.0",
+        "winston": "^3.13.1",
+        "winston-daily-rotate-file": "^4.7.1",
+        "ws": "^8.18.0"
+      },
+      "bin": {
+        "tcb-ff": "bin/tcb-ff.js"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      }
+    },
+    "node_modules/@cloudbase/functions-typings": {
+      "version": "1.2.1",
+      "resolved": "http://mirrors.tencent.com/npm/@cloudbase/functions-typings/-/functions-typings-1.2.1.tgz",
+      "integrity": "sha512-IteJl7RjPYjsqQbmSr6Vr0el6I19SzI1ya6Nw1ov4KEHxXdwrjJ2uubBeUK4mc54kmzFmvTwqBuyJdhUQ/YDXA==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=18.0.0"
+      }
+    },
+    "node_modules/@cloudbase/node-sdk": {
+      "version": "3.10.1",
+      "resolved": "http://mirrors.tencent.com/npm/@cloudbase/node-sdk/-/node-sdk-3.10.1.tgz",
+      "integrity": "sha512-ocGpKs7bY0SUizGGD4PBs8jCyL1I3YGZVQR7uF2R03vC6RYUspZc5tL4Gk7ASuJZTesnJY29JSsZpwsZnEzFqQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@cloudbase/database": "1.4.2",
+        "@cloudbase/signature-nodejs": "2.0.0",
+        "@cloudbase/wx-cloud-client-sdk": "1.6.1",
+        "agentkeepalive": "^4.3.0",
+        "axios": "0.27.2",
+        "form-data": "^4.0.0",
+        "http-proxy-agent": "^5.0.0",
+        "https-proxy-agent": "^5.0.1",
+        "jsonwebtoken": "^9.0.2",
+        "retry": "^0.13.1",
+        "xml2js": "^0.6.2"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@cloudbase/signature-nodejs": {
+      "version": "2.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/@cloudbase/signature-nodejs/-/signature-nodejs-2.0.0.tgz",
+      "integrity": "sha512-eFtRiZuD21+/s/4opejhcN8msFLBK5POwkT445yyA47kps35qXrHGqlLQgt00bmRU4VtjwN6LHr2O3PjHjWW6Q==",
+      "dependencies": {
+        "@types/clone": "^2.1.0",
+        "clone": "^2.1.2",
+        "is-stream": "^2.0.0",
+        "url": "^0.11.0"
+      }
+    },
+    "node_modules/@cloudbase/wx-cloud-client-sdk": {
+      "version": "1.6.1",
+      "resolved": "http://mirrors.tencent.com/npm/@cloudbase/wx-cloud-client-sdk/-/wx-cloud-client-sdk-1.6.1.tgz",
+      "integrity": "sha512-TeLhz+LMlTe1bZiCbwflU2nXX4FHXnLk1ojbrOfY9ki1gO1gYll9Snl2g3zBhiTGye/OfhzBEDCwVhGxzOxs4Q=="
+    },
+    "node_modules/@colors/colors": {
+      "version": "1.6.0",
+      "resolved": "http://mirrors.tencent.com/npm/@colors/colors/-/colors-1.6.0.tgz",
+      "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.1.90"
+      }
+    },
+    "node_modules/@dabh/diagnostics": {
+      "version": "2.0.3",
+      "resolved": "http://mirrors.tencent.com/npm/@dabh/diagnostics/-/diagnostics-2.0.3.tgz",
+      "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "colorspace": "1.1.x",
+        "enabled": "2.0.x",
+        "kuler": "^2.0.0"
+      }
+    },
+    "node_modules/@dotenvx/dotenvx": {
+      "version": "1.49.0",
+      "resolved": "http://mirrors.tencent.com/npm/@dotenvx/dotenvx/-/dotenvx-1.49.0.tgz",
+      "integrity": "sha512-M1cyP6YstFQCjih54SAxCqHLMMi8QqV8tenpgGE48RTXWD7vfMYJiw/6xcCDpS2h28AcLpTsFCZA863Ge9yxzA==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "commander": "^11.1.0",
+        "dotenv": "^17.2.1",
+        "eciesjs": "^0.4.10",
+        "execa": "^5.1.1",
+        "fdir": "^6.2.0",
+        "ignore": "^5.3.0",
+        "object-treeify": "1.1.33",
+        "picomatch": "^4.0.2",
+        "which": "^4.0.0"
+      },
+      "bin": {
+        "dotenvx": "src/cli/dotenvx.js"
+      },
+      "funding": {
+        "url": "https://dotenvx.com"
+      }
+    },
+    "node_modules/@ecies/ciphers": {
+      "version": "0.2.4",
+      "resolved": "http://mirrors.tencent.com/npm/@ecies/ciphers/-/ciphers-0.2.4.tgz",
+      "integrity": "sha512-t+iX+Wf5nRKyNzk8dviW3Ikb/280+aEJAnw9YXvCp2tYGPSkMki+NRY+8aNLmVFv3eNtMdvViPNOPxS8SZNP+w==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "bun": ">=1",
+        "deno": ">=2",
+        "node": ">=16"
+      },
+      "peerDependencies": {
+        "@noble/ciphers": "^1.0.0"
+      }
+    },
+    "node_modules/@hapi/bourne": {
+      "version": "3.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/@hapi/bourne/-/bourne-3.0.0.tgz",
+      "integrity": "sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w==",
+      "dev": true,
+      "license": "BSD-3-Clause"
+    },
+    "node_modules/@koa/cors": {
+      "version": "5.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/@koa/cors/-/cors-5.0.0.tgz",
+      "integrity": "sha512-x/iUDjcS90W69PryLDIMgFyV21YLTnG9zOpPXS7Bkt2b8AsY3zZsIpOLBkYr9fBcF3HbkKaER5hOBZLfpLgYNw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "vary": "^1.1.2"
+      },
+      "engines": {
+        "node": ">= 14.0.0"
+      }
+    },
+    "node_modules/@noble/ciphers": {
+      "version": "1.3.0",
+      "resolved": "http://mirrors.tencent.com/npm/@noble/ciphers/-/ciphers-1.3.0.tgz",
+      "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "^14.21.3 || >=16"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/@noble/curves": {
+      "version": "1.9.7",
+      "resolved": "http://mirrors.tencent.com/npm/@noble/curves/-/curves-1.9.7.tgz",
+      "integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@noble/hashes": "1.8.0"
+      },
+      "engines": {
+        "node": "^14.21.3 || >=16"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/@noble/hashes": {
+      "version": "1.8.0",
+      "resolved": "http://mirrors.tencent.com/npm/@noble/hashes/-/hashes-1.8.0.tgz",
+      "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "^14.21.3 || >=16"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/@paralleldrive/cuid2": {
+      "version": "2.2.2",
+      "resolved": "http://mirrors.tencent.com/npm/@paralleldrive/cuid2/-/cuid2-2.2.2.tgz",
+      "integrity": "sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@noble/hashes": "^1.1.5"
+      }
+    },
+    "node_modules/@tootallnate/once": {
+      "version": "2.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/@tootallnate/once/-/once-2.0.0.tgz",
+      "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@types/accepts": {
+      "version": "1.3.7",
+      "resolved": "http://mirrors.tencent.com/npm/@types/accepts/-/accepts-1.3.7.tgz",
+      "integrity": "sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/body-parser": {
+      "version": "1.19.6",
+      "resolved": "http://mirrors.tencent.com/npm/@types/body-parser/-/body-parser-1.19.6.tgz",
+      "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/connect": "*",
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/clone": {
+      "version": "2.1.4",
+      "resolved": "http://mirrors.tencent.com/npm/@types/clone/-/clone-2.1.4.tgz",
+      "integrity": "sha512-NKRWaEGaVGVLnGLB2GazvDaZnyweW9FJLLFL5LhywGJB3aqGMT9R/EUoJoSRP4nzofYnZysuDmrEJtJdAqUOtQ==",
+      "license": "MIT"
+    },
+    "node_modules/@types/co-body": {
+      "version": "6.1.3",
+      "resolved": "http://mirrors.tencent.com/npm/@types/co-body/-/co-body-6.1.3.tgz",
+      "integrity": "sha512-UhuhrQ5hclX6UJctv5m4Rfp52AfG9o9+d9/HwjxhVB5NjXxr5t9oKgJxN8xRHgr35oo8meUEHUPFWiKg6y71aA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*",
+        "@types/qs": "*"
+      }
+    },
+    "node_modules/@types/connect": {
+      "version": "3.4.38",
+      "resolved": "http://mirrors.tencent.com/npm/@types/connect/-/connect-3.4.38.tgz",
+      "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/content-disposition": {
+      "version": "0.5.9",
+      "resolved": "http://mirrors.tencent.com/npm/@types/content-disposition/-/content-disposition-0.5.9.tgz",
+      "integrity": "sha512-8uYXI3Gw35MhiVYhG3s295oihrxRyytcRHjSjqnqZVDDy/xcGBRny7+Xj1Wgfhv5QzRtN2hB2dVRBUX9XW3UcQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@types/cookies": {
+      "version": "0.9.1",
+      "resolved": "http://mirrors.tencent.com/npm/@types/cookies/-/cookies-0.9.1.tgz",
+      "integrity": "sha512-E/DPgzifH4sM1UMadJMWd6mO2jOd4g1Ejwzx8/uRCDpJis1IrlyQEcGAYEomtAqRYmD5ORbNXMeI9U0RiVGZbg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/connect": "*",
+        "@types/express": "*",
+        "@types/keygrip": "*",
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/express": {
+      "version": "5.0.3",
+      "resolved": "http://mirrors.tencent.com/npm/@types/express/-/express-5.0.3.tgz",
+      "integrity": "sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/body-parser": "*",
+        "@types/express-serve-static-core": "^5.0.0",
+        "@types/serve-static": "*"
+      }
+    },
+    "node_modules/@types/express-serve-static-core": {
+      "version": "5.0.7",
+      "resolved": "http://mirrors.tencent.com/npm/@types/express-serve-static-core/-/express-serve-static-core-5.0.7.tgz",
+      "integrity": "sha512-R+33OsgWw7rOhD1emjU7dzCDHucJrgJXMA5PYCzJxVil0dsyx5iBEPHqpPfiKNJQb7lZ1vxwoLR4Z87bBUpeGQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*",
+        "@types/qs": "*",
+        "@types/range-parser": "*",
+        "@types/send": "*"
+      }
+    },
+    "node_modules/@types/formidable": {
+      "version": "2.0.6",
+      "resolved": "http://mirrors.tencent.com/npm/@types/formidable/-/formidable-2.0.6.tgz",
+      "integrity": "sha512-L4HcrA05IgQyNYJj6kItuIkXrInJvsXTPC5B1i64FggWKKqSL+4hgt7asiSNva75AoLQjq29oPxFfU4GAQ6Z2w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/http-assert": {
+      "version": "1.5.6",
+      "resolved": "http://mirrors.tencent.com/npm/@types/http-assert/-/http-assert-1.5.6.tgz",
+      "integrity": "sha512-TTEwmtjgVbYAzZYWyeHPrrtWnfVkm8tQkP8P21uQifPgMRgjrow3XDEYqucuC8SKZJT7pUnhU/JymvjggxO9vw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@types/http-errors": {
+      "version": "2.0.5",
+      "resolved": "http://mirrors.tencent.com/npm/@types/http-errors/-/http-errors-2.0.5.tgz",
+      "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@types/keygrip": {
+      "version": "1.0.6",
+      "resolved": "http://mirrors.tencent.com/npm/@types/keygrip/-/keygrip-1.0.6.tgz",
+      "integrity": "sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@types/koa": {
+      "version": "2.15.0",
+      "resolved": "http://mirrors.tencent.com/npm/@types/koa/-/koa-2.15.0.tgz",
+      "integrity": "sha512-7QFsywoE5URbuVnG3loe03QXuGajrnotr3gQkXcEBShORai23MePfFYdhz90FEtBBpkyIYQbVD+evKtloCgX3g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/accepts": "*",
+        "@types/content-disposition": "*",
+        "@types/cookies": "*",
+        "@types/http-assert": "*",
+        "@types/http-errors": "*",
+        "@types/keygrip": "*",
+        "@types/koa-compose": "*",
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/koa-compose": {
+      "version": "3.2.8",
+      "resolved": "http://mirrors.tencent.com/npm/@types/koa-compose/-/koa-compose-3.2.8.tgz",
+      "integrity": "sha512-4Olc63RY+MKvxMwVknCUDhRQX1pFQoBZ/lXcRLP69PQkEpze/0cr8LNqJQe5NFb/b19DWi2a5bTi2VAlQzhJuA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/koa": "*"
+      }
+    },
+    "node_modules/@types/mime": {
+      "version": "1.3.5",
+      "resolved": "http://mirrors.tencent.com/npm/@types/mime/-/mime-1.3.5.tgz",
+      "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@types/node": {
+      "version": "24.3.0",
+      "resolved": "http://mirrors.tencent.com/npm/@types/node/-/node-24.3.0.tgz",
+      "integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "undici-types": "~7.10.0"
+      }
+    },
+    "node_modules/@types/normalize-package-data": {
+      "version": "2.4.4",
+      "resolved": "http://mirrors.tencent.com/npm/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz",
+      "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@types/qs": {
+      "version": "6.14.0",
+      "resolved": "http://mirrors.tencent.com/npm/@types/qs/-/qs-6.14.0.tgz",
+      "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@types/range-parser": {
+      "version": "1.2.7",
+      "resolved": "http://mirrors.tencent.com/npm/@types/range-parser/-/range-parser-1.2.7.tgz",
+      "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@types/send": {
+      "version": "0.17.5",
+      "resolved": "http://mirrors.tencent.com/npm/@types/send/-/send-0.17.5.tgz",
+      "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/mime": "^1",
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/serve-static": {
+      "version": "1.15.8",
+      "resolved": "http://mirrors.tencent.com/npm/@types/serve-static/-/serve-static-1.15.8.tgz",
+      "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/http-errors": "*",
+        "@types/node": "*",
+        "@types/send": "*"
+      }
+    },
+    "node_modules/@types/triple-beam": {
+      "version": "1.3.5",
+      "resolved": "http://mirrors.tencent.com/npm/@types/triple-beam/-/triple-beam-1.3.5.tgz",
+      "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@types/ws": {
+      "version": "8.18.1",
+      "resolved": "http://mirrors.tencent.com/npm/@types/ws/-/ws-8.18.1.tgz",
+      "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/accepts": {
+      "version": "1.3.8",
+      "resolved": "http://mirrors.tencent.com/npm/accepts/-/accepts-1.3.8.tgz",
+      "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "mime-types": "~2.1.34",
+        "negotiator": "0.6.3"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/agent-base": {
+      "version": "6.0.2",
+      "resolved": "http://mirrors.tencent.com/npm/agent-base/-/agent-base-6.0.2.tgz",
+      "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+      "license": "MIT",
+      "dependencies": {
+        "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6.0.0"
+      }
+    },
+    "node_modules/agentkeepalive": {
+      "version": "4.6.0",
+      "resolved": "http://mirrors.tencent.com/npm/agentkeepalive/-/agentkeepalive-4.6.0.tgz",
+      "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==",
+      "license": "MIT",
+      "dependencies": {
+        "humanize-ms": "^1.2.1"
+      },
+      "engines": {
+        "node": ">= 8.0.0"
+      }
+    },
+    "node_modules/ajv": {
+      "version": "8.17.1",
+      "resolved": "http://mirrors.tencent.com/npm/ajv/-/ajv-8.17.1.tgz",
+      "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "fast-deep-equal": "^3.1.3",
+        "fast-uri": "^3.0.1",
+        "json-schema-traverse": "^1.0.0",
+        "require-from-string": "^2.0.2"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
+      }
+    },
+    "node_modules/anymatch": {
+      "version": "3.1.3",
+      "resolved": "http://mirrors.tencent.com/npm/anymatch/-/anymatch-3.1.3.tgz",
+      "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/anymatch/node_modules/picomatch": {
+      "version": "2.3.1",
+      "resolved": "http://mirrors.tencent.com/npm/picomatch/-/picomatch-2.3.1.tgz",
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/asap": {
+      "version": "2.0.6",
+      "resolved": "http://mirrors.tencent.com/npm/asap/-/asap-2.0.6.tgz",
+      "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/async": {
+      "version": "3.2.6",
+      "resolved": "http://mirrors.tencent.com/npm/async/-/async-3.2.6.tgz",
+      "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "http://mirrors.tencent.com/npm/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+      "license": "MIT"
+    },
+    "node_modules/axios": {
+      "version": "0.27.2",
+      "resolved": "http://mirrors.tencent.com/npm/axios/-/axios-0.27.2.tgz",
+      "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
+      "license": "MIT",
+      "dependencies": {
+        "follow-redirects": "^1.14.9",
+        "form-data": "^4.0.0"
+      }
+    },
+    "node_modules/balanced-match": {
+      "version": "1.0.2",
+      "resolved": "http://mirrors.tencent.com/npm/balanced-match/-/balanced-match-1.0.2.tgz",
+      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/base64-js": {
+      "version": "1.5.1",
+      "resolved": "http://mirrors.tencent.com/npm/base64-js/-/base64-js-1.5.1.tgz",
+      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT"
+    },
+    "node_modules/binary-extensions": {
+      "version": "2.3.0",
+      "resolved": "http://mirrors.tencent.com/npm/binary-extensions/-/binary-extensions-2.3.0.tgz",
+      "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/brace-expansion": {
+      "version": "1.1.12",
+      "resolved": "http://mirrors.tencent.com/npm/brace-expansion/-/brace-expansion-1.1.12.tgz",
+      "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/braces": {
+      "version": "3.0.3",
+      "resolved": "http://mirrors.tencent.com/npm/braces/-/braces-3.0.3.tgz",
+      "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "fill-range": "^7.1.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/bson": {
+      "version": "4.7.2",
+      "resolved": "http://mirrors.tencent.com/npm/bson/-/bson-4.7.2.tgz",
+      "integrity": "sha512-Ry9wCtIZ5kGqkJoi6aD8KjxFZEx78guTQDnpXWiNthsxzrxAK/i8E6pCHAIZTbaEFWcOCvbecMukfK7XUvyLpQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "buffer": "^5.6.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/buffer": {
+      "version": "5.7.1",
+      "resolved": "http://mirrors.tencent.com/npm/buffer/-/buffer-5.7.1.tgz",
+      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "base64-js": "^1.3.1",
+        "ieee754": "^1.1.13"
+      }
+    },
+    "node_modules/buffer-equal-constant-time": {
+      "version": "1.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+      "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
+      "license": "BSD-3-Clause"
+    },
+    "node_modules/bytes": {
+      "version": "3.1.2",
+      "resolved": "http://mirrors.tencent.com/npm/bytes/-/bytes-3.1.2.tgz",
+      "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/cache-content-type": {
+      "version": "1.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/cache-content-type/-/cache-content-type-1.0.1.tgz",
+      "integrity": "sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "mime-types": "^2.1.18",
+        "ylru": "^1.2.0"
+      },
+      "engines": {
+        "node": ">= 6.0.0"
+      }
+    },
+    "node_modules/call-bind-apply-helpers": {
+      "version": "1.0.2",
+      "resolved": "http://mirrors.tencent.com/npm/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+      "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "function-bind": "^1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/call-bound": {
+      "version": "1.0.4",
+      "resolved": "http://mirrors.tencent.com/npm/call-bound/-/call-bound-1.0.4.tgz",
+      "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+      "license": "MIT",
+      "dependencies": {
+        "call-bind-apply-helpers": "^1.0.2",
+        "get-intrinsic": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/chokidar": {
+      "version": "3.6.0",
+      "resolved": "http://mirrors.tencent.com/npm/chokidar/-/chokidar-3.6.0.tgz",
+      "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "anymatch": "~3.1.2",
+        "braces": "~3.0.2",
+        "glob-parent": "~5.1.2",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.6.0"
+      },
+      "engines": {
+        "node": ">= 8.10.0"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/clone": {
+      "version": "2.1.2",
+      "resolved": "http://mirrors.tencent.com/npm/clone/-/clone-2.1.2.tgz",
+      "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/co": {
+      "version": "4.6.0",
+      "resolved": "http://mirrors.tencent.com/npm/co/-/co-4.6.0.tgz",
+      "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "iojs": ">= 1.0.0",
+        "node": ">= 0.12.0"
+      }
+    },
+    "node_modules/co-body": {
+      "version": "6.2.0",
+      "resolved": "http://mirrors.tencent.com/npm/co-body/-/co-body-6.2.0.tgz",
+      "integrity": "sha512-Kbpv2Yd1NdL1V/V4cwLVxraHDV6K8ayohr2rmH0J87Er8+zJjcTa6dAn9QMPC9CRgU8+aNajKbSf1TzDB1yKPA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@hapi/bourne": "^3.0.0",
+        "inflation": "^2.0.0",
+        "qs": "^6.5.2",
+        "raw-body": "^2.3.3",
+        "type-is": "^1.6.16"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/co-body/node_modules/http-errors": {
+      "version": "2.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/http-errors/-/http-errors-2.0.0.tgz",
+      "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "depd": "2.0.0",
+        "inherits": "2.0.4",
+        "setprototypeof": "1.2.0",
+        "statuses": "2.0.1",
+        "toidentifier": "1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/co-body/node_modules/iconv-lite": {
+      "version": "0.4.24",
+      "resolved": "http://mirrors.tencent.com/npm/iconv-lite/-/iconv-lite-0.4.24.tgz",
+      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/co-body/node_modules/raw-body": {
+      "version": "2.5.2",
+      "resolved": "http://mirrors.tencent.com/npm/raw-body/-/raw-body-2.5.2.tgz",
+      "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "bytes": "3.1.2",
+        "http-errors": "2.0.0",
+        "iconv-lite": "0.4.24",
+        "unpipe": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/co-body/node_modules/statuses": {
+      "version": "2.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/statuses/-/statuses-2.0.1.tgz",
+      "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/color": {
+      "version": "3.2.1",
+      "resolved": "http://mirrors.tencent.com/npm/color/-/color-3.2.1.tgz",
+      "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "color-convert": "^1.9.3",
+        "color-string": "^1.6.0"
+      }
+    },
+    "node_modules/color-convert": {
+      "version": "1.9.3",
+      "resolved": "http://mirrors.tencent.com/npm/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "color-name": "1.1.3"
+      }
+    },
+    "node_modules/color-name": {
+      "version": "1.1.3",
+      "resolved": "http://mirrors.tencent.com/npm/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/color-string": {
+      "version": "1.9.1",
+      "resolved": "http://mirrors.tencent.com/npm/color-string/-/color-string-1.9.1.tgz",
+      "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "color-name": "^1.0.0",
+        "simple-swizzle": "^0.2.2"
+      }
+    },
+    "node_modules/colorspace": {
+      "version": "1.1.4",
+      "resolved": "http://mirrors.tencent.com/npm/colorspace/-/colorspace-1.1.4.tgz",
+      "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "color": "^3.1.3",
+        "text-hex": "1.0.x"
+      }
+    },
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "http://mirrors.tencent.com/npm/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "license": "MIT",
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/commander": {
+      "version": "11.1.0",
+      "resolved": "http://mirrors.tencent.com/npm/commander/-/commander-11.1.0.tgz",
+      "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=16"
+      }
+    },
+    "node_modules/concat-map": {
+      "version": "0.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/content-disposition": {
+      "version": "0.5.4",
+      "resolved": "http://mirrors.tencent.com/npm/content-disposition/-/content-disposition-0.5.4.tgz",
+      "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "safe-buffer": "5.2.1"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/content-type": {
+      "version": "1.0.5",
+      "resolved": "http://mirrors.tencent.com/npm/content-type/-/content-type-1.0.5.tgz",
+      "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/cookies": {
+      "version": "0.9.1",
+      "resolved": "http://mirrors.tencent.com/npm/cookies/-/cookies-0.9.1.tgz",
+      "integrity": "sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "depd": "~2.0.0",
+        "keygrip": "~1.1.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/cross-spawn": {
+      "version": "7.0.6",
+      "resolved": "http://mirrors.tencent.com/npm/cross-spawn/-/cross-spawn-7.0.6.tgz",
+      "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "path-key": "^3.1.0",
+        "shebang-command": "^2.0.0",
+        "which": "^2.0.1"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/cross-spawn/node_modules/isexe": {
+      "version": "2.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/cross-spawn/node_modules/which": {
+      "version": "2.0.2",
+      "resolved": "http://mirrors.tencent.com/npm/which/-/which-2.0.2.tgz",
+      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "node-which": "bin/node-which"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/debug": {
+      "version": "4.4.1",
+      "resolved": "http://mirrors.tencent.com/npm/debug/-/debug-4.4.1.tgz",
+      "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+      "license": "MIT",
+      "dependencies": {
+        "ms": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/deep-equal": {
+      "version": "1.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/deep-equal/-/deep-equal-1.0.1.tgz",
+      "integrity": "sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/delegates": {
+      "version": "1.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/delegates/-/delegates-1.0.0.tgz",
+      "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/depd": {
+      "version": "2.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/depd/-/depd-2.0.0.tgz",
+      "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/destroy": {
+      "version": "1.2.0",
+      "resolved": "http://mirrors.tencent.com/npm/destroy/-/destroy-1.2.0.tgz",
+      "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8",
+        "npm": "1.2.8000 || >= 1.4.16"
+      }
+    },
+    "node_modules/dezalgo": {
+      "version": "1.0.4",
+      "resolved": "http://mirrors.tencent.com/npm/dezalgo/-/dezalgo-1.0.4.tgz",
+      "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "asap": "^2.0.0",
+        "wrappy": "1"
+      }
+    },
+    "node_modules/dotenv": {
+      "version": "17.2.2",
+      "resolved": "http://mirrors.tencent.com/npm/dotenv/-/dotenv-17.2.2.tgz",
+      "integrity": "sha512-Sf2LSQP+bOlhKWWyhFsn0UsfdK/kCWRv1iuA2gXAwt3dyNabr6QSj00I2V10pidqz69soatm9ZwZvpQMTIOd5Q==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://dotenvx.com"
+      }
+    },
+    "node_modules/dunder-proto": {
+      "version": "1.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/dunder-proto/-/dunder-proto-1.0.1.tgz",
+      "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+      "license": "MIT",
+      "dependencies": {
+        "call-bind-apply-helpers": "^1.0.1",
+        "es-errors": "^1.3.0",
+        "gopd": "^1.2.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ecdsa-sig-formatter": {
+      "version": "1.0.11",
+      "resolved": "http://mirrors.tencent.com/npm/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+      "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/eciesjs": {
+      "version": "0.4.15",
+      "resolved": "http://mirrors.tencent.com/npm/eciesjs/-/eciesjs-0.4.15.tgz",
+      "integrity": "sha512-r6kEJXDKecVOCj2nLMuXK/FCPeurW33+3JRpfXVbjLja3XUYFfD9I/JBreH6sUyzcm3G/YQboBjMla6poKeSdA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@ecies/ciphers": "^0.2.3",
+        "@noble/ciphers": "^1.3.0",
+        "@noble/curves": "^1.9.1",
+        "@noble/hashes": "^1.8.0"
+      },
+      "engines": {
+        "bun": ">=1",
+        "deno": ">=2",
+        "node": ">=16"
+      }
+    },
+    "node_modules/ee-first": {
+      "version": "1.1.1",
+      "resolved": "http://mirrors.tencent.com/npm/ee-first/-/ee-first-1.1.1.tgz",
+      "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/enabled": {
+      "version": "2.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/enabled/-/enabled-2.0.0.tgz",
+      "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/encodeurl": {
+      "version": "1.0.2",
+      "resolved": "http://mirrors.tencent.com/npm/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/error-ex": {
+      "version": "1.3.2",
+      "resolved": "http://mirrors.tencent.com/npm/error-ex/-/error-ex-1.3.2.tgz",
+      "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-arrayish": "^0.2.1"
+      }
+    },
+    "node_modules/es-define-property": {
+      "version": "1.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/es-define-property/-/es-define-property-1.0.1.tgz",
+      "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-errors": {
+      "version": "1.3.0",
+      "resolved": "http://mirrors.tencent.com/npm/es-errors/-/es-errors-1.3.0.tgz",
+      "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-object-atoms": {
+      "version": "1.1.1",
+      "resolved": "http://mirrors.tencent.com/npm/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+      "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-set-tostringtag": {
+      "version": "2.1.0",
+      "resolved": "http://mirrors.tencent.com/npm/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+      "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.6",
+        "has-tostringtag": "^1.0.2",
+        "hasown": "^2.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/escape-html": {
+      "version": "1.0.3",
+      "resolved": "http://mirrors.tencent.com/npm/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/execa": {
+      "version": "5.1.1",
+      "resolved": "http://mirrors.tencent.com/npm/execa/-/execa-5.1.1.tgz",
+      "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "cross-spawn": "^7.0.3",
+        "get-stream": "^6.0.0",
+        "human-signals": "^2.1.0",
+        "is-stream": "^2.0.0",
+        "merge-stream": "^2.0.0",
+        "npm-run-path": "^4.0.1",
+        "onetime": "^5.1.2",
+        "signal-exit": "^3.0.3",
+        "strip-final-newline": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sindresorhus/execa?sponsor=1"
+      }
+    },
+    "node_modules/fast-deep-equal": {
+      "version": "3.1.3",
+      "resolved": "http://mirrors.tencent.com/npm/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/fast-uri": {
+      "version": "3.1.0",
+      "resolved": "http://mirrors.tencent.com/npm/fast-uri/-/fast-uri-3.1.0.tgz",
+      "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fastify"
+        },
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/fastify"
+        }
+      ],
+      "license": "BSD-3-Clause"
+    },
+    "node_modules/fdir": {
+      "version": "6.5.0",
+      "resolved": "http://mirrors.tencent.com/npm/fdir/-/fdir-6.5.0.tgz",
+      "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12.0.0"
+      },
+      "peerDependencies": {
+        "picomatch": "^3 || ^4"
+      },
+      "peerDependenciesMeta": {
+        "picomatch": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/fecha": {
+      "version": "4.2.3",
+      "resolved": "http://mirrors.tencent.com/npm/fecha/-/fecha-4.2.3.tgz",
+      "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/file-stream-rotator": {
+      "version": "0.6.1",
+      "resolved": "http://mirrors.tencent.com/npm/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz",
+      "integrity": "sha512-u+dBid4PvZw17PmDeRcNOtCP9CCK/9lRN2w+r1xIS7yOL9JFrIBKTvrYsxT4P0pGtThYTn++QS5ChHaUov3+zQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "moment": "^2.29.1"
+      }
+    },
+    "node_modules/fill-range": {
+      "version": "7.1.1",
+      "resolved": "http://mirrors.tencent.com/npm/fill-range/-/fill-range-7.1.1.tgz",
+      "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "to-regex-range": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "http://mirrors.tencent.com/npm/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/fn.name": {
+      "version": "1.1.0",
+      "resolved": "http://mirrors.tencent.com/npm/fn.name/-/fn.name-1.1.0.tgz",
+      "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/follow-redirects": {
+      "version": "1.15.11",
+      "resolved": "http://mirrors.tencent.com/npm/follow-redirects/-/follow-redirects-1.15.11.tgz",
+      "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://github.com/sponsors/RubenVerborgh"
+        }
+      ],
+      "license": "MIT",
+      "engines": {
+        "node": ">=4.0"
+      },
+      "peerDependenciesMeta": {
+        "debug": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/form-data": {
+      "version": "4.0.4",
+      "resolved": "http://mirrors.tencent.com/npm/form-data/-/form-data-4.0.4.tgz",
+      "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
+      "license": "MIT",
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "es-set-tostringtag": "^2.1.0",
+        "hasown": "^2.0.2",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/formidable": {
+      "version": "2.1.5",
+      "resolved": "http://mirrors.tencent.com/npm/formidable/-/formidable-2.1.5.tgz",
+      "integrity": "sha512-Oz5Hwvwak/DCaXVVUtPn4oLMLLy1CdclLKO1LFgU7XzDpVMUU5UjlSLpGMocyQNNk8F6IJW9M/YdooSn2MRI+Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@paralleldrive/cuid2": "^2.2.2",
+        "dezalgo": "^1.0.4",
+        "once": "^1.4.0",
+        "qs": "^6.11.0"
+      },
+      "funding": {
+        "url": "https://ko-fi.com/tunnckoCore/commissions"
+      }
+    },
+    "node_modules/fresh": {
+      "version": "0.5.2",
+      "resolved": "http://mirrors.tencent.com/npm/fresh/-/fresh-0.5.2.tgz",
+      "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/fsevents": {
+      "version": "2.3.3",
+      "resolved": "http://mirrors.tencent.com/npm/fsevents/-/fsevents-2.3.3.tgz",
+      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+      "dev": true,
+      "hasInstallScript": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
+    "node_modules/function-bind": {
+      "version": "1.1.2",
+      "resolved": "http://mirrors.tencent.com/npm/function-bind/-/function-bind-1.1.2.tgz",
+      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/get-intrinsic": {
+      "version": "1.3.0",
+      "resolved": "http://mirrors.tencent.com/npm/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+      "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+      "license": "MIT",
+      "dependencies": {
+        "call-bind-apply-helpers": "^1.0.2",
+        "es-define-property": "^1.0.1",
+        "es-errors": "^1.3.0",
+        "es-object-atoms": "^1.1.1",
+        "function-bind": "^1.1.2",
+        "get-proto": "^1.0.1",
+        "gopd": "^1.2.0",
+        "has-symbols": "^1.1.0",
+        "hasown": "^2.0.2",
+        "math-intrinsics": "^1.1.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/get-proto": {
+      "version": "1.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/get-proto/-/get-proto-1.0.1.tgz",
+      "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+      "license": "MIT",
+      "dependencies": {
+        "dunder-proto": "^1.0.1",
+        "es-object-atoms": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/get-stream": {
+      "version": "6.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/get-stream/-/get-stream-6.0.1.tgz",
+      "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/glob-parent": {
+      "version": "5.1.2",
+      "resolved": "http://mirrors.tencent.com/npm/glob-parent/-/glob-parent-5.1.2.tgz",
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "is-glob": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/gopd": {
+      "version": "1.2.0",
+      "resolved": "http://mirrors.tencent.com/npm/gopd/-/gopd-1.2.0.tgz",
+      "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/has-flag": {
+      "version": "3.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/has-symbols": {
+      "version": "1.1.0",
+      "resolved": "http://mirrors.tencent.com/npm/has-symbols/-/has-symbols-1.1.0.tgz",
+      "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/has-tostringtag": {
+      "version": "1.0.2",
+      "resolved": "http://mirrors.tencent.com/npm/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+      "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+      "license": "MIT",
+      "dependencies": {
+        "has-symbols": "^1.0.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/hasown": {
+      "version": "2.0.2",
+      "resolved": "http://mirrors.tencent.com/npm/hasown/-/hasown-2.0.2.tgz",
+      "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+      "license": "MIT",
+      "dependencies": {
+        "function-bind": "^1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/hosted-git-info": {
+      "version": "2.8.9",
+      "resolved": "http://mirrors.tencent.com/npm/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+      "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/http-assert": {
+      "version": "1.5.0",
+      "resolved": "http://mirrors.tencent.com/npm/http-assert/-/http-assert-1.5.0.tgz",
+      "integrity": "sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "deep-equal": "~1.0.1",
+        "http-errors": "~1.8.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/http-errors": {
+      "version": "1.8.1",
+      "resolved": "http://mirrors.tencent.com/npm/http-errors/-/http-errors-1.8.1.tgz",
+      "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "depd": "~1.1.2",
+        "inherits": "2.0.4",
+        "setprototypeof": "1.2.0",
+        "statuses": ">= 1.5.0 < 2",
+        "toidentifier": "1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/http-errors/node_modules/depd": {
+      "version": "1.1.2",
+      "resolved": "http://mirrors.tencent.com/npm/depd/-/depd-1.1.2.tgz",
+      "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/http-proxy-agent": {
+      "version": "5.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
+      "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
+      "license": "MIT",
+      "dependencies": {
+        "@tootallnate/once": "2",
+        "agent-base": "6",
+        "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/https-proxy-agent": {
+      "version": "5.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+      "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+      "license": "MIT",
+      "dependencies": {
+        "agent-base": "6",
+        "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/human-signals": {
+      "version": "2.1.0",
+      "resolved": "http://mirrors.tencent.com/npm/human-signals/-/human-signals-2.1.0.tgz",
+      "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=10.17.0"
+      }
+    },
+    "node_modules/humanize-ms": {
+      "version": "1.2.1",
+      "resolved": "http://mirrors.tencent.com/npm/humanize-ms/-/humanize-ms-1.2.1.tgz",
+      "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
+      "license": "MIT",
+      "dependencies": {
+        "ms": "^2.0.0"
+      }
+    },
+    "node_modules/iconv-lite": {
+      "version": "0.7.0",
+      "resolved": "http://mirrors.tencent.com/npm/iconv-lite/-/iconv-lite-0.7.0.tgz",
+      "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/express"
+      }
+    },
+    "node_modules/ieee754": {
+      "version": "1.2.1",
+      "resolved": "http://mirrors.tencent.com/npm/ieee754/-/ieee754-1.2.1.tgz",
+      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "BSD-3-Clause"
+    },
+    "node_modules/ignore": {
+      "version": "5.3.2",
+      "resolved": "http://mirrors.tencent.com/npm/ignore/-/ignore-5.3.2.tgz",
+      "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/ignore-by-default": {
+      "version": "1.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
+      "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/inflation": {
+      "version": "2.1.0",
+      "resolved": "http://mirrors.tencent.com/npm/inflation/-/inflation-2.1.0.tgz",
+      "integrity": "sha512-t54PPJHG1Pp7VQvxyVCJ9mBbjG3Hqryges9bXoOO6GExCPa+//i/d5GSuFtpx3ALLd7lgIAur6zrIlBQyJuMlQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/inherits": {
+      "version": "2.0.4",
+      "resolved": "http://mirrors.tencent.com/npm/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/is-arrayish": {
+      "version": "0.2.1",
+      "resolved": "http://mirrors.tencent.com/npm/is-arrayish/-/is-arrayish-0.2.1.tgz",
+      "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/is-binary-path": {
+      "version": "2.1.0",
+      "resolved": "http://mirrors.tencent.com/npm/is-binary-path/-/is-binary-path-2.1.0.tgz",
+      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "binary-extensions": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/is-core-module": {
+      "version": "2.16.1",
+      "resolved": "http://mirrors.tencent.com/npm/is-core-module/-/is-core-module-2.16.1.tgz",
+      "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "hasown": "^2.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-extglob": {
+      "version": "2.1.1",
+      "resolved": "http://mirrors.tencent.com/npm/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-generator-function": {
+      "version": "1.1.0",
+      "resolved": "http://mirrors.tencent.com/npm/is-generator-function/-/is-generator-function-1.1.0.tgz",
+      "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.3",
+        "get-proto": "^1.0.0",
+        "has-tostringtag": "^1.0.2",
+        "safe-regex-test": "^1.1.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-glob": {
+      "version": "4.0.3",
+      "resolved": "http://mirrors.tencent.com/npm/is-glob/-/is-glob-4.0.3.tgz",
+      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-extglob": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-number": {
+      "version": "7.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/is-number/-/is-number-7.0.0.tgz",
+      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.12.0"
+      }
+    },
+    "node_modules/is-regex": {
+      "version": "1.2.1",
+      "resolved": "http://mirrors.tencent.com/npm/is-regex/-/is-regex-1.2.1.tgz",
+      "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "gopd": "^1.2.0",
+        "has-tostringtag": "^1.0.2",
+        "hasown": "^2.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-stream": {
+      "version": "2.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/is-stream/-/is-stream-2.0.1.tgz",
+      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/isexe": {
+      "version": "3.1.1",
+      "resolved": "http://mirrors.tencent.com/npm/isexe/-/isexe-3.1.1.tgz",
+      "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": ">=16"
+      }
+    },
+    "node_modules/js-tokens": {
+      "version": "4.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/js-tokens/-/js-tokens-4.0.0.tgz",
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/json-parse-even-better-errors": {
+      "version": "2.3.1",
+      "resolved": "http://mirrors.tencent.com/npm/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/json-schema-traverse": {
+      "version": "1.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/jsonwebtoken": {
+      "version": "9.0.2",
+      "resolved": "http://mirrors.tencent.com/npm/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
+      "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
+      "license": "MIT",
+      "dependencies": {
+        "jws": "^3.2.2",
+        "lodash.includes": "^4.3.0",
+        "lodash.isboolean": "^3.0.3",
+        "lodash.isinteger": "^4.0.4",
+        "lodash.isnumber": "^3.0.3",
+        "lodash.isplainobject": "^4.0.6",
+        "lodash.isstring": "^4.0.1",
+        "lodash.once": "^4.0.0",
+        "ms": "^2.1.1",
+        "semver": "^7.5.4"
+      },
+      "engines": {
+        "node": ">=12",
+        "npm": ">=6"
+      }
+    },
+    "node_modules/jwa": {
+      "version": "1.4.2",
+      "resolved": "http://mirrors.tencent.com/npm/jwa/-/jwa-1.4.2.tgz",
+      "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==",
+      "license": "MIT",
+      "dependencies": {
+        "buffer-equal-constant-time": "^1.0.1",
+        "ecdsa-sig-formatter": "1.0.11",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/jws": {
+      "version": "3.2.2",
+      "resolved": "http://mirrors.tencent.com/npm/jws/-/jws-3.2.2.tgz",
+      "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+      "license": "MIT",
+      "dependencies": {
+        "jwa": "^1.4.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/keygrip": {
+      "version": "1.1.0",
+      "resolved": "http://mirrors.tencent.com/npm/keygrip/-/keygrip-1.1.0.tgz",
+      "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "tsscmp": "1.0.6"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/koa": {
+      "version": "2.16.2",
+      "resolved": "http://mirrors.tencent.com/npm/koa/-/koa-2.16.2.tgz",
+      "integrity": "sha512-+CCssgnrWKx9aI3OeZwroa/ckG4JICxvIFnSiOUyl2Uv+UTI+xIw0FfFrWS7cQFpoePpr9o8csss7KzsTzNL8Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "accepts": "^1.3.5",
+        "cache-content-type": "^1.0.0",
+        "content-disposition": "~0.5.2",
+        "content-type": "^1.0.4",
+        "cookies": "~0.9.0",
+        "debug": "^4.3.2",
+        "delegates": "^1.0.0",
+        "depd": "^2.0.0",
+        "destroy": "^1.0.4",
+        "encodeurl": "^1.0.2",
+        "escape-html": "^1.0.3",
+        "fresh": "~0.5.2",
+        "http-assert": "^1.3.0",
+        "http-errors": "^1.6.3",
+        "is-generator-function": "^1.0.7",
+        "koa-compose": "^4.1.0",
+        "koa-convert": "^2.0.0",
+        "on-finished": "^2.3.0",
+        "only": "~0.0.2",
+        "parseurl": "^1.3.2",
+        "statuses": "^1.5.0",
+        "type-is": "^1.6.16",
+        "vary": "^1.1.2"
+      },
+      "engines": {
+        "node": "^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4"
+      }
+    },
+    "node_modules/koa-body": {
+      "version": "6.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/koa-body/-/koa-body-6.0.1.tgz",
+      "integrity": "sha512-M8ZvMD8r+kPHy28aWP9VxL7kY8oPWA+C7ZgCljrCMeaU7uX6wsIQgDHskyrAr9sw+jqnIXyv4Mlxri5R4InIJg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/co-body": "^6.1.0",
+        "@types/formidable": "^2.0.5",
+        "@types/koa": "^2.13.5",
+        "co-body": "^6.1.0",
+        "formidable": "^2.0.1",
+        "zod": "^3.19.1"
+      }
+    },
+    "node_modules/koa-compose": {
+      "version": "4.1.0",
+      "resolved": "http://mirrors.tencent.com/npm/koa-compose/-/koa-compose-4.1.0.tgz",
+      "integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/koa-convert": {
+      "version": "2.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/koa-convert/-/koa-convert-2.0.0.tgz",
+      "integrity": "sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "co": "^4.6.0",
+        "koa-compose": "^4.1.0"
+      },
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/kuler": {
+      "version": "2.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/kuler/-/kuler-2.0.0.tgz",
+      "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/lines-and-columns": {
+      "version": "1.2.4",
+      "resolved": "http://mirrors.tencent.com/npm/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+      "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "p-locate": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/lodash.clonedeep": {
+      "version": "4.5.0",
+      "resolved": "http://mirrors.tencent.com/npm/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+      "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
+      "license": "MIT"
+    },
+    "node_modules/lodash.includes": {
+      "version": "4.3.0",
+      "resolved": "http://mirrors.tencent.com/npm/lodash.includes/-/lodash.includes-4.3.0.tgz",
+      "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
+      "license": "MIT"
+    },
+    "node_modules/lodash.isboolean": {
+      "version": "3.0.3",
+      "resolved": "http://mirrors.tencent.com/npm/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
+      "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
+      "license": "MIT"
+    },
+    "node_modules/lodash.isinteger": {
+      "version": "4.0.4",
+      "resolved": "http://mirrors.tencent.com/npm/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+      "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
+      "license": "MIT"
+    },
+    "node_modules/lodash.isnumber": {
+      "version": "3.0.3",
+      "resolved": "http://mirrors.tencent.com/npm/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+      "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
+      "license": "MIT"
+    },
+    "node_modules/lodash.isplainobject": {
+      "version": "4.0.6",
+      "resolved": "http://mirrors.tencent.com/npm/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+      "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
+      "license": "MIT"
+    },
+    "node_modules/lodash.isstring": {
+      "version": "4.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+      "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
+      "license": "MIT"
+    },
+    "node_modules/lodash.once": {
+      "version": "4.1.1",
+      "resolved": "http://mirrors.tencent.com/npm/lodash.once/-/lodash.once-4.1.1.tgz",
+      "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
+      "license": "MIT"
+    },
+    "node_modules/lodash.set": {
+      "version": "4.3.2",
+      "resolved": "http://mirrors.tencent.com/npm/lodash.set/-/lodash.set-4.3.2.tgz",
+      "integrity": "sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg==",
+      "license": "MIT"
+    },
+    "node_modules/lodash.unset": {
+      "version": "4.5.2",
+      "resolved": "http://mirrors.tencent.com/npm/lodash.unset/-/lodash.unset-4.5.2.tgz",
+      "integrity": "sha512-bwKX88k2JhCV9D1vtE8+naDKlLiGrSmf8zi/Y9ivFHwbmRfA8RxS/aVJ+sIht2XOwqoNr4xUPUkGZpc1sHFEKg==",
+      "license": "MIT"
+    },
+    "node_modules/logform": {
+      "version": "2.7.0",
+      "resolved": "http://mirrors.tencent.com/npm/logform/-/logform-2.7.0.tgz",
+      "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@colors/colors": "1.6.0",
+        "@types/triple-beam": "^1.3.2",
+        "fecha": "^4.2.0",
+        "ms": "^2.1.1",
+        "safe-stable-stringify": "^2.3.1",
+        "triple-beam": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 12.0.0"
+      }
+    },
+    "node_modules/math-intrinsics": {
+      "version": "1.1.0",
+      "resolved": "http://mirrors.tencent.com/npm/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+      "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/media-typer": {
+      "version": "0.3.0",
+      "resolved": "http://mirrors.tencent.com/npm/media-typer/-/media-typer-0.3.0.tgz",
+      "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/merge-stream": {
+      "version": "2.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/merge-stream/-/merge-stream-2.0.0.tgz",
+      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "http://mirrors.tencent.com/npm/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "http://mirrors.tencent.com/npm/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "license": "MIT",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mimic-fn": {
+      "version": "2.1.0",
+      "resolved": "http://mirrors.tencent.com/npm/mimic-fn/-/mimic-fn-2.1.0.tgz",
+      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "http://mirrors.tencent.com/npm/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/minimist": {
+      "version": "1.2.8",
+      "resolved": "http://mirrors.tencent.com/npm/minimist/-/minimist-1.2.8.tgz",
+      "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+      "dev": true,
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/moment": {
+      "version": "2.30.1",
+      "resolved": "http://mirrors.tencent.com/npm/moment/-/moment-2.30.1.tgz",
+      "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ms": {
+      "version": "2.1.3",
+      "resolved": "http://mirrors.tencent.com/npm/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+      "license": "MIT"
+    },
+    "node_modules/negotiator": {
+      "version": "0.6.3",
+      "resolved": "http://mirrors.tencent.com/npm/negotiator/-/negotiator-0.6.3.tgz",
+      "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/nodemon": {
+      "version": "3.1.10",
+      "resolved": "http://mirrors.tencent.com/npm/nodemon/-/nodemon-3.1.10.tgz",
+      "integrity": "sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "chokidar": "^3.5.2",
+        "debug": "^4",
+        "ignore-by-default": "^1.0.1",
+        "minimatch": "^3.1.2",
+        "pstree.remy": "^1.1.8",
+        "semver": "^7.5.3",
+        "simple-update-notifier": "^2.0.0",
+        "supports-color": "^5.5.0",
+        "touch": "^3.1.0",
+        "undefsafe": "^2.0.5"
+      },
+      "bin": {
+        "nodemon": "bin/nodemon.js"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/nodemon"
+      }
+    },
+    "node_modules/normalize-package-data": {
+      "version": "2.5.0",
+      "resolved": "http://mirrors.tencent.com/npm/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+      "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "hosted-git-info": "^2.1.4",
+        "resolve": "^1.10.0",
+        "semver": "2 || 3 || 4 || 5",
+        "validate-npm-package-license": "^3.0.1"
+      }
+    },
+    "node_modules/normalize-package-data/node_modules/semver": {
+      "version": "5.7.2",
+      "resolved": "http://mirrors.tencent.com/npm/semver/-/semver-5.7.2.tgz",
+      "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+      "dev": true,
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/normalize-path": {
+      "version": "3.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/normalize-path/-/normalize-path-3.0.0.tgz",
+      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/npm-run-path": {
+      "version": "4.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/npm-run-path/-/npm-run-path-4.0.1.tgz",
+      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "path-key": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/object-hash": {
+      "version": "2.2.0",
+      "resolved": "http://mirrors.tencent.com/npm/object-hash/-/object-hash-2.2.0.tgz",
+      "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/object-inspect": {
+      "version": "1.13.4",
+      "resolved": "http://mirrors.tencent.com/npm/object-inspect/-/object-inspect-1.13.4.tgz",
+      "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/object-treeify": {
+      "version": "1.1.33",
+      "resolved": "http://mirrors.tencent.com/npm/object-treeify/-/object-treeify-1.1.33.tgz",
+      "integrity": "sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/on-finished": {
+      "version": "2.4.1",
+      "resolved": "http://mirrors.tencent.com/npm/on-finished/-/on-finished-2.4.1.tgz",
+      "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ee-first": "1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/once": {
+      "version": "1.4.0",
+      "resolved": "http://mirrors.tencent.com/npm/once/-/once-1.4.0.tgz",
+      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "wrappy": "1"
+      }
+    },
+    "node_modules/one-time": {
+      "version": "1.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/one-time/-/one-time-1.0.0.tgz",
+      "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "fn.name": "1.x.x"
+      }
+    },
+    "node_modules/onetime": {
+      "version": "5.1.2",
+      "resolved": "http://mirrors.tencent.com/npm/onetime/-/onetime-5.1.2.tgz",
+      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "mimic-fn": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/only": {
+      "version": "0.0.2",
+      "resolved": "http://mirrors.tencent.com/npm/only/-/only-0.0.2.tgz",
+      "integrity": "sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==",
+      "dev": true
+    },
+    "node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "http://mirrors.tencent.com/npm/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/p-locate": {
+      "version": "4.1.0",
+      "resolved": "http://mirrors.tencent.com/npm/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "p-limit": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/p-try": {
+      "version": "2.2.0",
+      "resolved": "http://mirrors.tencent.com/npm/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/parse-json": {
+      "version": "5.2.0",
+      "resolved": "http://mirrors.tencent.com/npm/parse-json/-/parse-json-5.2.0.tgz",
+      "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/code-frame": "^7.0.0",
+        "error-ex": "^1.3.1",
+        "json-parse-even-better-errors": "^2.3.0",
+        "lines-and-columns": "^1.1.6"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/parseurl": {
+      "version": "1.3.3",
+      "resolved": "http://mirrors.tencent.com/npm/parseurl/-/parseurl-1.3.3.tgz",
+      "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/path-exists": {
+      "version": "4.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/path-exists/-/path-exists-4.0.0.tgz",
+      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/path-key": {
+      "version": "3.1.1",
+      "resolved": "http://mirrors.tencent.com/npm/path-key/-/path-key-3.1.1.tgz",
+      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/path-parse": {
+      "version": "1.0.7",
+      "resolved": "http://mirrors.tencent.com/npm/path-parse/-/path-parse-1.0.7.tgz",
+      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/picocolors": {
+      "version": "1.1.1",
+      "resolved": "http://mirrors.tencent.com/npm/picocolors/-/picocolors-1.1.1.tgz",
+      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/picomatch": {
+      "version": "4.0.3",
+      "resolved": "http://mirrors.tencent.com/npm/picomatch/-/picomatch-4.0.3.tgz",
+      "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/pstree.remy": {
+      "version": "1.1.8",
+      "resolved": "http://mirrors.tencent.com/npm/pstree.remy/-/pstree.remy-1.1.8.tgz",
+      "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/punycode": {
+      "version": "1.4.1",
+      "resolved": "http://mirrors.tencent.com/npm/punycode/-/punycode-1.4.1.tgz",
+      "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==",
+      "license": "MIT"
+    },
+    "node_modules/qs": {
+      "version": "6.14.0",
+      "resolved": "http://mirrors.tencent.com/npm/qs/-/qs-6.14.0.tgz",
+      "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "side-channel": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=0.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/radix3": {
+      "version": "1.1.2",
+      "resolved": "http://mirrors.tencent.com/npm/radix3/-/radix3-1.1.2.tgz",
+      "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/raw-body": {
+      "version": "3.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/raw-body/-/raw-body-3.0.1.tgz",
+      "integrity": "sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "bytes": "3.1.2",
+        "http-errors": "2.0.0",
+        "iconv-lite": "0.7.0",
+        "unpipe": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/raw-body/node_modules/http-errors": {
+      "version": "2.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/http-errors/-/http-errors-2.0.0.tgz",
+      "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "depd": "2.0.0",
+        "inherits": "2.0.4",
+        "setprototypeof": "1.2.0",
+        "statuses": "2.0.1",
+        "toidentifier": "1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/raw-body/node_modules/statuses": {
+      "version": "2.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/statuses/-/statuses-2.0.1.tgz",
+      "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/read-pkg": {
+      "version": "5.2.0",
+      "resolved": "http://mirrors.tencent.com/npm/read-pkg/-/read-pkg-5.2.0.tgz",
+      "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/normalize-package-data": "^2.4.0",
+        "normalize-package-data": "^2.5.0",
+        "parse-json": "^5.0.0",
+        "type-fest": "^0.6.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg-up": {
+      "version": "7.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
+      "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "find-up": "^4.1.0",
+        "read-pkg": "^5.2.0",
+        "type-fest": "^0.8.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/read-pkg/node_modules/type-fest": {
+      "version": "0.6.0",
+      "resolved": "http://mirrors.tencent.com/npm/type-fest/-/type-fest-0.6.0.tgz",
+      "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
+      "dev": true,
+      "license": "(MIT OR CC0-1.0)",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/readable-stream": {
+      "version": "3.6.2",
+      "resolved": "http://mirrors.tencent.com/npm/readable-stream/-/readable-stream-3.6.2.tgz",
+      "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/readdirp": {
+      "version": "3.6.0",
+      "resolved": "http://mirrors.tencent.com/npm/readdirp/-/readdirp-3.6.0.tgz",
+      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "picomatch": "^2.2.1"
+      },
+      "engines": {
+        "node": ">=8.10.0"
+      }
+    },
+    "node_modules/readdirp/node_modules/picomatch": {
+      "version": "2.3.1",
+      "resolved": "http://mirrors.tencent.com/npm/picomatch/-/picomatch-2.3.1.tgz",
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/require-from-string": {
+      "version": "2.0.2",
+      "resolved": "http://mirrors.tencent.com/npm/require-from-string/-/require-from-string-2.0.2.tgz",
+      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/resolve": {
+      "version": "1.22.10",
+      "resolved": "http://mirrors.tencent.com/npm/resolve/-/resolve-1.22.10.tgz",
+      "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-core-module": "^2.16.0",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
+      },
+      "bin": {
+        "resolve": "bin/resolve"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/retry": {
+      "version": "0.13.1",
+      "resolved": "http://mirrors.tencent.com/npm/retry/-/retry-0.13.1.tgz",
+      "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/safe-buffer": {
+      "version": "5.2.1",
+      "resolved": "http://mirrors.tencent.com/npm/safe-buffer/-/safe-buffer-5.2.1.tgz",
+      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT"
+    },
+    "node_modules/safe-regex-test": {
+      "version": "1.1.0",
+      "resolved": "http://mirrors.tencent.com/npm/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+      "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "es-errors": "^1.3.0",
+        "is-regex": "^1.2.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/safe-stable-stringify": {
+      "version": "2.5.0",
+      "resolved": "http://mirrors.tencent.com/npm/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz",
+      "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "http://mirrors.tencent.com/npm/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/sax": {
+      "version": "1.4.1",
+      "resolved": "http://mirrors.tencent.com/npm/sax/-/sax-1.4.1.tgz",
+      "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==",
+      "license": "ISC"
+    },
+    "node_modules/semver": {
+      "version": "7.7.2",
+      "resolved": "http://mirrors.tencent.com/npm/semver/-/semver-7.7.2.tgz",
+      "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/setprototypeof": {
+      "version": "1.2.0",
+      "resolved": "http://mirrors.tencent.com/npm/setprototypeof/-/setprototypeof-1.2.0.tgz",
+      "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/shebang-command": {
+      "version": "2.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/shebang-command/-/shebang-command-2.0.0.tgz",
+      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "shebang-regex": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/shebang-regex": {
+      "version": "3.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/shebang-regex/-/shebang-regex-3.0.0.tgz",
+      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/side-channel": {
+      "version": "1.1.0",
+      "resolved": "http://mirrors.tencent.com/npm/side-channel/-/side-channel-1.1.0.tgz",
+      "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "object-inspect": "^1.13.3",
+        "side-channel-list": "^1.0.0",
+        "side-channel-map": "^1.0.1",
+        "side-channel-weakmap": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/side-channel-list": {
+      "version": "1.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/side-channel-list/-/side-channel-list-1.0.0.tgz",
+      "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "object-inspect": "^1.13.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/side-channel-map": {
+      "version": "1.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/side-channel-map/-/side-channel-map-1.0.1.tgz",
+      "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.5",
+        "object-inspect": "^1.13.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/side-channel-weakmap": {
+      "version": "1.0.2",
+      "resolved": "http://mirrors.tencent.com/npm/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+      "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.5",
+        "object-inspect": "^1.13.3",
+        "side-channel-map": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/signal-exit": {
+      "version": "3.0.7",
+      "resolved": "http://mirrors.tencent.com/npm/signal-exit/-/signal-exit-3.0.7.tgz",
+      "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/simple-swizzle": {
+      "version": "0.2.2",
+      "resolved": "http://mirrors.tencent.com/npm/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+      "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-arrayish": "^0.3.1"
+      }
+    },
+    "node_modules/simple-swizzle/node_modules/is-arrayish": {
+      "version": "0.3.2",
+      "resolved": "http://mirrors.tencent.com/npm/is-arrayish/-/is-arrayish-0.3.2.tgz",
+      "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/simple-update-notifier": {
+      "version": "2.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
+      "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "semver": "^7.5.3"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/spdx-correct": {
+      "version": "3.2.0",
+      "resolved": "http://mirrors.tencent.com/npm/spdx-correct/-/spdx-correct-3.2.0.tgz",
+      "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "spdx-expression-parse": "^3.0.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "node_modules/spdx-exceptions": {
+      "version": "2.5.0",
+      "resolved": "http://mirrors.tencent.com/npm/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
+      "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
+      "dev": true,
+      "license": "CC-BY-3.0"
+    },
+    "node_modules/spdx-expression-parse": {
+      "version": "3.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+      "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "spdx-exceptions": "^2.1.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "node_modules/spdx-license-ids": {
+      "version": "3.0.22",
+      "resolved": "http://mirrors.tencent.com/npm/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz",
+      "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==",
+      "dev": true,
+      "license": "CC0-1.0"
+    },
+    "node_modules/stack-trace": {
+      "version": "0.0.10",
+      "resolved": "http://mirrors.tencent.com/npm/stack-trace/-/stack-trace-0.0.10.tgz",
+      "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/statuses": {
+      "version": "1.5.0",
+      "resolved": "http://mirrors.tencent.com/npm/statuses/-/statuses-1.5.0.tgz",
+      "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/string_decoder": {
+      "version": "1.3.0",
+      "resolved": "http://mirrors.tencent.com/npm/string_decoder/-/string_decoder-1.3.0.tgz",
+      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "safe-buffer": "~5.2.0"
+      }
+    },
+    "node_modules/strip-final-newline": {
+      "version": "2.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+      "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/supports-color": {
+      "version": "5.5.0",
+      "resolved": "http://mirrors.tencent.com/npm/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/supports-preserve-symlinks-flag": {
+      "version": "1.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/text-hex": {
+      "version": "1.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/text-hex/-/text-hex-1.0.0.tgz",
+      "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/to-regex-range": {
+      "version": "5.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/to-regex-range/-/to-regex-range-5.0.1.tgz",
+      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-number": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=8.0"
+      }
+    },
+    "node_modules/toidentifier": {
+      "version": "1.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/toidentifier/-/toidentifier-1.0.1.tgz",
+      "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/touch": {
+      "version": "3.1.1",
+      "resolved": "http://mirrors.tencent.com/npm/touch/-/touch-3.1.1.tgz",
+      "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==",
+      "dev": true,
+      "license": "ISC",
+      "bin": {
+        "nodetouch": "bin/nodetouch.js"
+      }
+    },
+    "node_modules/triple-beam": {
+      "version": "1.4.1",
+      "resolved": "http://mirrors.tencent.com/npm/triple-beam/-/triple-beam-1.4.1.tgz",
+      "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 14.0.0"
+      }
+    },
+    "node_modules/tsscmp": {
+      "version": "1.0.6",
+      "resolved": "http://mirrors.tencent.com/npm/tsscmp/-/tsscmp-1.0.6.tgz",
+      "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.6.x"
+      }
+    },
+    "node_modules/type-fest": {
+      "version": "0.8.1",
+      "resolved": "http://mirrors.tencent.com/npm/type-fest/-/type-fest-0.8.1.tgz",
+      "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+      "dev": true,
+      "license": "(MIT OR CC0-1.0)",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/type-is": {
+      "version": "1.6.18",
+      "resolved": "http://mirrors.tencent.com/npm/type-is/-/type-is-1.6.18.tgz",
+      "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "media-typer": "0.3.0",
+        "mime-types": "~2.1.24"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/undefsafe": {
+      "version": "2.0.5",
+      "resolved": "http://mirrors.tencent.com/npm/undefsafe/-/undefsafe-2.0.5.tgz",
+      "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/undici-types": {
+      "version": "7.10.0",
+      "resolved": "http://mirrors.tencent.com/npm/undici-types/-/undici-types-7.10.0.tgz",
+      "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/unpipe": {
+      "version": "1.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/unpipe/-/unpipe-1.0.0.tgz",
+      "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/url": {
+      "version": "0.11.4",
+      "resolved": "http://mirrors.tencent.com/npm/url/-/url-0.11.4.tgz",
+      "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==",
+      "license": "MIT",
+      "dependencies": {
+        "punycode": "^1.4.1",
+        "qs": "^6.12.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "http://mirrors.tencent.com/npm/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/uuid": {
+      "version": "10.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/uuid/-/uuid-10.0.0.tgz",
+      "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
+      "dev": true,
+      "funding": [
+        "https://github.com/sponsors/broofa",
+        "https://github.com/sponsors/ctavan"
+      ],
+      "license": "MIT",
+      "bin": {
+        "uuid": "dist/bin/uuid"
+      }
+    },
+    "node_modules/validate-npm-package-license": {
+      "version": "3.0.4",
+      "resolved": "http://mirrors.tencent.com/npm/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+      "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "spdx-correct": "^3.0.0",
+        "spdx-expression-parse": "^3.0.0"
+      }
+    },
+    "node_modules/vary": {
+      "version": "1.1.2",
+      "resolved": "http://mirrors.tencent.com/npm/vary/-/vary-1.1.2.tgz",
+      "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/whatwg-mimetype": {
+      "version": "4.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
+      "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/which": {
+      "version": "4.0.0",
+      "resolved": "http://mirrors.tencent.com/npm/which/-/which-4.0.0.tgz",
+      "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "isexe": "^3.1.1"
+      },
+      "bin": {
+        "node-which": "bin/which.js"
+      },
+      "engines": {
+        "node": "^16.13.0 || >=18.0.0"
+      }
+    },
+    "node_modules/winston": {
+      "version": "3.17.0",
+      "resolved": "http://mirrors.tencent.com/npm/winston/-/winston-3.17.0.tgz",
+      "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@colors/colors": "^1.6.0",
+        "@dabh/diagnostics": "^2.0.2",
+        "async": "^3.2.3",
+        "is-stream": "^2.0.0",
+        "logform": "^2.7.0",
+        "one-time": "^1.0.0",
+        "readable-stream": "^3.4.0",
+        "safe-stable-stringify": "^2.3.1",
+        "stack-trace": "0.0.x",
+        "triple-beam": "^1.3.0",
+        "winston-transport": "^4.9.0"
+      },
+      "engines": {
+        "node": ">= 12.0.0"
+      }
+    },
+    "node_modules/winston-daily-rotate-file": {
+      "version": "4.7.1",
+      "resolved": "http://mirrors.tencent.com/npm/winston-daily-rotate-file/-/winston-daily-rotate-file-4.7.1.tgz",
+      "integrity": "sha512-7LGPiYGBPNyGHLn9z33i96zx/bd71pjBn9tqQzO3I4Tayv94WPmBNwKC7CO1wPHdP9uvu+Md/1nr6VSH9h0iaA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "file-stream-rotator": "^0.6.1",
+        "object-hash": "^2.0.1",
+        "triple-beam": "^1.3.0",
+        "winston-transport": "^4.4.0"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "peerDependencies": {
+        "winston": "^3"
+      }
+    },
+    "node_modules/winston-transport": {
+      "version": "4.9.0",
+      "resolved": "http://mirrors.tencent.com/npm/winston-transport/-/winston-transport-4.9.0.tgz",
+      "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "logform": "^2.7.0",
+        "readable-stream": "^3.6.2",
+        "triple-beam": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 12.0.0"
+      }
+    },
+    "node_modules/wrappy": {
+      "version": "1.0.2",
+      "resolved": "http://mirrors.tencent.com/npm/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/ws": {
+      "version": "8.18.3",
+      "resolved": "http://mirrors.tencent.com/npm/ws/-/ws-8.18.3.tgz",
+      "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=10.0.0"
+      },
+      "peerDependencies": {
+        "bufferutil": "^4.0.1",
+        "utf-8-validate": ">=5.0.2"
+      },
+      "peerDependenciesMeta": {
+        "bufferutil": {
+          "optional": true
+        },
+        "utf-8-validate": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/xml2js": {
+      "version": "0.6.2",
+      "resolved": "http://mirrors.tencent.com/npm/xml2js/-/xml2js-0.6.2.tgz",
+      "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==",
+      "license": "MIT",
+      "dependencies": {
+        "sax": ">=0.6.0",
+        "xmlbuilder": "~11.0.0"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/xmlbuilder": {
+      "version": "11.0.1",
+      "resolved": "http://mirrors.tencent.com/npm/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+      "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/ylru": {
+      "version": "1.4.0",
+      "resolved": "http://mirrors.tencent.com/npm/ylru/-/ylru-1.4.0.tgz",
+      "integrity": "sha512-2OQsPNEmBCvXuFlIni/a+Rn+R2pHW9INm0BxXJ4hVDA8TirqMj+J/Rp9ItLatT/5pZqWwefVrTQcHpixsxnVlA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 4.0.0"
+      }
+    },
+    "node_modules/zod": {
+      "version": "3.25.76",
+      "resolved": "http://mirrors.tencent.com/npm/zod/-/zod-3.25.76.tgz",
+      "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+      "dev": true,
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/sponsors/colinhacks"
+      }
+    }
+  }
+}

+ 24 - 0
cloud/database/package.json

@@ -0,0 +1,24 @@
+{
+  "name": "@function/database",
+  "version": "1.0.0",
+  "description": "",
+  "license": "ISC",
+  "author": "",
+  "type": "commonjs",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1",
+    "tcb-ff": "tcb-ff",
+    "dev": "tcb cloudfunction run -w",
+    "deploy": "tcb cloudfunction deploy"
+  },
+  "tcbRepo": {
+    "type": "function"
+  },
+  "dependencies": {
+    "@cloudbase/node-sdk": "^3.7.0"
+  },
+  "devDependencies": {
+    "@cloudbase/functions-framework": "^1.8.0"
+  }
+}

+ 40 - 0
cloud/database/repository.js

@@ -0,0 +1,40 @@
+const { models } = require('./db')
+
+// 团购页面接口
+const groupbuy = require('./interface/groupbuy')
+// 异常行为报警页面接口
+const abnormal = require('./interface/abnormal')
+// 售后管理页面接口
+const aftersales = require('./interface/aftersales')
+// 下载量统计页面接口
+const download = require('./interface/download')
+// 订单管理页面接口
+const order = require('./interface/order')
+// 用户行为统计页面接口
+const userstats = require('./interface/userstats')
+// 付款统计页面接口
+const payment = require('./interface/payment')
+// 首页接口
+const home = require('./interface/home')
+// 课程接口
+const recommend = require('./interface/recommend')
+
+// 测试
+async function getActiveByName(name) {
+    const sql = 'SELECT * FROM lxpceshi WHERE name like {{name}}'
+    const result = await models.$runSQL(sql, { name: `%${name}%` })
+    return result.data.executeResultList;
+}
+
+module.exports = {
+    getActiveByName,
+    groupbuy,
+    abnormal,
+    aftersales,
+    download,
+    order,
+    userstats,
+    payment,
+    home,
+    recommend
+}

+ 19 - 0
cloud/database/serverless.yaml

@@ -0,0 +1,19 @@
+component: scf
+name: database
+inputs:
+  handler: index.main
+  description: Nodejs 语言 空白 helloworld 模板
+  runtime: Nodejs18.15
+  memorySize: 256
+  installDependency: true
+  timeout: 3
+  vpcConfig:
+    vpcId: ""
+    subnetId: ""
+  events: []
+  layers: []
+  initTimeout: 65
+  protocolParams: null
+  protocolType: ""
+  eip: false
+  publicAccess: true

+ 34 - 0
cloud/login/index.js

@@ -0,0 +1,34 @@
+// 云函数 login
+const cloudbase = require('@cloudbase/js-sdk')
+
+// 初始化(注意:云函数里才能用 js-sdk)
+const app = cloudbase.init({
+  env: cloudbase.SYMBOL_CURRENT_ENV
+})
+
+const auth = app.auth()
+
+exports.main = async (event, context) => {
+  const { username, password } = event
+
+  try {
+    // 用 Web SDK 登录
+    const res = await auth.signIn({
+      username,
+      password
+    })
+
+    // 获取自定义登录 token
+    const tokenRes = await auth.getAccessToken()
+
+    return {
+      code: 0,
+      token: tokenRes.accessToken
+    }
+  } catch (err) {
+    return {
+      code: -1,
+      msg: err.message
+    }
+  }
+}

+ 6 - 0
cloud/lxp/config.json

@@ -0,0 +1,6 @@
+{
+  "permissions": {
+    "openapi": [
+    ]
+  }
+}

+ 16 - 0
cloud/lxp/index.js

@@ -0,0 +1,16 @@
+// 云函数入口文件
+const cloud = require('wx-server-sdk')
+const smsUtil = require('./utils/smsUtil')
+cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境
+// 云函数入口函数
+exports.main = async (event, context) => {
+  const wxContext = cloud.getWXContext()
+  const response = await smsUtil.sendSmsTp(event)
+  return {
+    event,
+    openid: wxContext.OPENID,
+    appid: wxContext.APPID,
+    unionid: wxContext.UNIONID,
+    response,
+  }
+}

+ 1169 - 0
cloud/lxp/package-lock.json

@@ -0,0 +1,1169 @@
+{
+  "name": "lxp",
+  "version": "1.0.0",
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {
+    "": {
+      "name": "lxp",
+      "version": "1.0.0",
+      "license": "ISC",
+      "dependencies": {
+        "request": "^2.88.2",
+        "wx-server-sdk": "~3.0.1"
+      }
+    },
+    "node_modules/@cloudbase/database": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/@cloudbase/database/-/database-1.4.1.tgz",
+      "integrity": "sha512-BYLXHS6c+WhxAvvdak8Z3W+heScqBBPu/CQ76gC8v1Scuy5qf4qxuPWNzyoxde/eZsmc+BRRCFyIq4xUnIot8g==",
+      "dependencies": {
+        "bson": "^4.0.3",
+        "lodash.clonedeep": "4.5.0",
+        "lodash.set": "4.3.2",
+        "lodash.unset": "4.5.2"
+      }
+    },
+    "node_modules/@cloudbase/node-sdk": {
+      "version": "2.10.0",
+      "resolved": "https://registry.npmmirror.com/@cloudbase/node-sdk/-/node-sdk-2.10.0.tgz",
+      "integrity": "sha512-P9loxdwN6qG3iIzjx2Z3uBk/4iyn9+KoiWYGi9ZwhWP1toijpQu0+eLSAaMupNJecJopS21IWUmmGSetlZh8UA==",
+      "dependencies": {
+        "@cloudbase/database": "1.4.1",
+        "@cloudbase/signature-nodejs": "1.0.0-beta.0",
+        "agentkeepalive": "^4.3.0",
+        "axios": "^0.21.1",
+        "jsonwebtoken": "^8.5.1",
+        "request": "^2.87.0",
+        "retry": "^0.13.1",
+        "xml2js": "^0.5.0"
+      },
+      "engines": {
+        "node": ">=8.6.0"
+      }
+    },
+    "node_modules/@cloudbase/signature-nodejs": {
+      "version": "1.0.0-beta.0",
+      "resolved": "https://registry.npmmirror.com/@cloudbase/signature-nodejs/-/signature-nodejs-1.0.0-beta.0.tgz",
+      "integrity": "sha512-gpKqwsVk/D2PzvFamYNReymXSdvRSY90eZ1ARf+1wZ8oT6OpK9kr6nmevGykMxN1n17Gn92hBbWqAxU9o3+kAQ==",
+      "dependencies": {
+        "@types/clone": "^0.1.30",
+        "clone": "^2.1.2",
+        "is-stream": "^2.0.0",
+        "url": "^0.11.0"
+      }
+    },
+    "node_modules/@protobufjs/aspromise": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+      "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
+    },
+    "node_modules/@protobufjs/base64": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/base64/-/base64-1.1.2.tgz",
+      "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
+    },
+    "node_modules/@protobufjs/codegen": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/codegen/-/codegen-2.0.4.tgz",
+      "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
+    },
+    "node_modules/@protobufjs/eventemitter": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
+      "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
+    },
+    "node_modules/@protobufjs/fetch": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/fetch/-/fetch-1.1.0.tgz",
+      "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
+      "dependencies": {
+        "@protobufjs/aspromise": "^1.1.1",
+        "@protobufjs/inquire": "^1.1.0"
+      }
+    },
+    "node_modules/@protobufjs/float": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/float/-/float-1.0.2.tgz",
+      "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
+    },
+    "node_modules/@protobufjs/inquire": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/inquire/-/inquire-1.1.0.tgz",
+      "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
+    },
+    "node_modules/@protobufjs/path": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/path/-/path-1.1.2.tgz",
+      "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
+    },
+    "node_modules/@protobufjs/pool": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/pool/-/pool-1.1.0.tgz",
+      "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
+    },
+    "node_modules/@protobufjs/utf8": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/utf8/-/utf8-1.1.0.tgz",
+      "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
+    },
+    "node_modules/@types/clone": {
+      "version": "0.1.30",
+      "resolved": "https://registry.npmmirror.com/@types/clone/-/clone-0.1.30.tgz",
+      "integrity": "sha512-vcxBr+ybljeSiasmdke1cQ9ICxoEwaBgM1OQ/P5h4MPj/kRyLcDl5L8PrftlbyV1kBbJIs3M3x1A1+rcWd4mEA=="
+    },
+    "node_modules/@types/node": {
+      "version": "24.3.0",
+      "resolved": "https://registry.npmmirror.com/@types/node/-/node-24.3.0.tgz",
+      "integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==",
+      "dependencies": {
+        "undici-types": "~7.10.0"
+      }
+    },
+    "node_modules/agentkeepalive": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmmirror.com/agentkeepalive/-/agentkeepalive-4.6.0.tgz",
+      "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==",
+      "dependencies": {
+        "humanize-ms": "^1.2.1"
+      },
+      "engines": {
+        "node": ">= 8.0.0"
+      }
+    },
+    "node_modules/ajv": {
+      "version": "6.12.6",
+      "resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz",
+      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+      "dependencies": {
+        "fast-deep-equal": "^3.1.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
+      }
+    },
+    "node_modules/asn1": {
+      "version": "0.2.6",
+      "resolved": "https://registry.npmmirror.com/asn1/-/asn1-0.2.6.tgz",
+      "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
+      "dependencies": {
+        "safer-buffer": "~2.1.0"
+      }
+    },
+    "node_modules/assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/assert-plus/-/assert-plus-1.0.0.tgz",
+      "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+    },
+    "node_modules/aws-sign2": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmmirror.com/aws-sign2/-/aws-sign2-0.7.0.tgz",
+      "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/aws4": {
+      "version": "1.13.2",
+      "resolved": "https://registry.npmmirror.com/aws4/-/aws4-1.13.2.tgz",
+      "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw=="
+    },
+    "node_modules/axios": {
+      "version": "0.21.4",
+      "resolved": "https://registry.npmmirror.com/axios/-/axios-0.21.4.tgz",
+      "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
+      "dependencies": {
+        "follow-redirects": "^1.14.0"
+      }
+    },
+    "node_modules/base64-js": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz",
+      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
+    },
+    "node_modules/bcrypt-pbkdf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+      "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
+      "dependencies": {
+        "tweetnacl": "^0.14.3"
+      }
+    },
+    "node_modules/bignumber.js": {
+      "version": "9.3.1",
+      "resolved": "https://registry.npmmirror.com/bignumber.js/-/bignumber.js-9.3.1.tgz",
+      "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/bson": {
+      "version": "4.7.2",
+      "resolved": "https://registry.npmmirror.com/bson/-/bson-4.7.2.tgz",
+      "integrity": "sha512-Ry9wCtIZ5kGqkJoi6aD8KjxFZEx78guTQDnpXWiNthsxzrxAK/i8E6pCHAIZTbaEFWcOCvbecMukfK7XUvyLpQ==",
+      "dependencies": {
+        "buffer": "^5.6.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/bson/node_modules/buffer": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmmirror.com/buffer/-/buffer-5.7.1.tgz",
+      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "dependencies": {
+        "base64-js": "^1.3.1",
+        "ieee754": "^1.1.13"
+      }
+    },
+    "node_modules/buffer-equal-constant-time": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+      "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
+    },
+    "node_modules/call-bind-apply-helpers": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+      "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "function-bind": "^1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/call-bound": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmmirror.com/call-bound/-/call-bound-1.0.4.tgz",
+      "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+      "dependencies": {
+        "call-bind-apply-helpers": "^1.0.2",
+        "get-intrinsic": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/caseless": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmmirror.com/caseless/-/caseless-0.12.0.tgz",
+      "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
+    },
+    "node_modules/clone": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmmirror.com/clone/-/clone-2.1.2.tgz",
+      "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/core-util-is": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.2.tgz",
+      "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="
+    },
+    "node_modules/dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
+      "dependencies": {
+        "assert-plus": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/dunder-proto": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
+      "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+      "dependencies": {
+        "call-bind-apply-helpers": "^1.0.1",
+        "es-errors": "^1.3.0",
+        "gopd": "^1.2.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ecc-jsbn": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmmirror.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+      "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
+      "dependencies": {
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.1.0"
+      }
+    },
+    "node_modules/ecdsa-sig-formatter": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmmirror.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+      "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/es-define-property": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
+      "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-errors": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
+      "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-object-atoms": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+      "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+      "dependencies": {
+        "es-errors": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmmirror.com/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+    },
+    "node_modules/extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==",
+      "engines": [
+        "node >=0.6.0"
+      ]
+    },
+    "node_modules/fast-deep-equal": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+    },
+    "node_modules/fast-json-stable-stringify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
+    },
+    "node_modules/follow-redirects": {
+      "version": "1.15.11",
+      "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.11.tgz",
+      "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://github.com/sponsors/RubenVerborgh"
+        }
+      ],
+      "engines": {
+        "node": ">=4.0"
+      },
+      "peerDependenciesMeta": {
+        "debug": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmmirror.com/forever-agent/-/forever-agent-0.6.1.tgz",
+      "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/form-data": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmmirror.com/form-data/-/form-data-2.3.3.tgz",
+      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.6",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 0.12"
+      }
+    },
+    "node_modules/function-bind": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
+      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/get-intrinsic": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+      "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+      "dependencies": {
+        "call-bind-apply-helpers": "^1.0.2",
+        "es-define-property": "^1.0.1",
+        "es-errors": "^1.3.0",
+        "es-object-atoms": "^1.1.1",
+        "function-bind": "^1.1.2",
+        "get-proto": "^1.0.1",
+        "gopd": "^1.2.0",
+        "has-symbols": "^1.1.0",
+        "hasown": "^2.0.2",
+        "math-intrinsics": "^1.1.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/get-proto": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz",
+      "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+      "dependencies": {
+        "dunder-proto": "^1.0.1",
+        "es-object-atoms": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmmirror.com/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
+      "dependencies": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "node_modules/gopd": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
+      "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/har-schema": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/har-schema/-/har-schema-2.0.0.tgz",
+      "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/har-validator": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npmmirror.com/har-validator/-/har-validator-5.1.5.tgz",
+      "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
+      "deprecated": "this library is no longer supported",
+      "dependencies": {
+        "ajv": "^6.12.3",
+        "har-schema": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/has-symbols": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
+      "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/hasown": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz",
+      "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+      "dependencies": {
+        "function-bind": "^1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/http-signature": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/http-signature/-/http-signature-1.2.0.tgz",
+      "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==",
+      "dependencies": {
+        "assert-plus": "^1.0.0",
+        "jsprim": "^1.2.2",
+        "sshpk": "^1.7.0"
+      },
+      "engines": {
+        "node": ">=0.8",
+        "npm": ">=1.3.7"
+      }
+    },
+    "node_modules/humanize-ms": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/humanize-ms/-/humanize-ms-1.2.1.tgz",
+      "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
+      "dependencies": {
+        "ms": "^2.0.0"
+      }
+    },
+    "node_modules/ieee754": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz",
+      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
+    },
+    "node_modules/is-stream": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz",
+      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
+    },
+    "node_modules/isstream": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmmirror.com/isstream/-/isstream-0.1.2.tgz",
+      "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g=="
+    },
+    "node_modules/jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmmirror.com/jsbn/-/jsbn-0.1.1.tgz",
+      "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg=="
+    },
+    "node_modules/json-bigint": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/json-bigint/-/json-bigint-1.0.0.tgz",
+      "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
+      "dependencies": {
+        "bignumber.js": "^9.0.0"
+      }
+    },
+    "node_modules/json-schema": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmmirror.com/json-schema/-/json-schema-0.4.0.tgz",
+      "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
+    },
+    "node_modules/json-schema-traverse": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+    },
+    "node_modules/json-stringify-safe": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmmirror.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+      "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="
+    },
+    "node_modules/jsonwebtoken": {
+      "version": "8.5.1",
+      "resolved": "https://registry.npmmirror.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
+      "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
+      "dependencies": {
+        "jws": "^3.2.2",
+        "lodash.includes": "^4.3.0",
+        "lodash.isboolean": "^3.0.3",
+        "lodash.isinteger": "^4.0.4",
+        "lodash.isnumber": "^3.0.3",
+        "lodash.isplainobject": "^4.0.6",
+        "lodash.isstring": "^4.0.1",
+        "lodash.once": "^4.0.0",
+        "ms": "^2.1.1",
+        "semver": "^5.6.0"
+      },
+      "engines": {
+        "node": ">=4",
+        "npm": ">=1.4.28"
+      }
+    },
+    "node_modules/jsprim": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmmirror.com/jsprim/-/jsprim-1.4.2.tgz",
+      "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
+      "dependencies": {
+        "assert-plus": "1.0.0",
+        "extsprintf": "1.3.0",
+        "json-schema": "0.4.0",
+        "verror": "1.10.0"
+      },
+      "engines": {
+        "node": ">=0.6.0"
+      }
+    },
+    "node_modules/jwa": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmmirror.com/jwa/-/jwa-1.4.2.tgz",
+      "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==",
+      "dependencies": {
+        "buffer-equal-constant-time": "^1.0.1",
+        "ecdsa-sig-formatter": "1.0.11",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/jws": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmmirror.com/jws/-/jws-3.2.2.tgz",
+      "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+      "dependencies": {
+        "jwa": "^1.4.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/lodash.clonedeep": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmmirror.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+      "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ=="
+    },
+    "node_modules/lodash.includes": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmmirror.com/lodash.includes/-/lodash.includes-4.3.0.tgz",
+      "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
+    },
+    "node_modules/lodash.isboolean": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
+      "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
+    },
+    "node_modules/lodash.isinteger": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmmirror.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+      "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
+    },
+    "node_modules/lodash.isnumber": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+      "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
+    },
+    "node_modules/lodash.isplainobject": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmmirror.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+      "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
+    },
+    "node_modules/lodash.isstring": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmmirror.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+      "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
+    },
+    "node_modules/lodash.once": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmmirror.com/lodash.once/-/lodash.once-4.1.1.tgz",
+      "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
+    },
+    "node_modules/lodash.set": {
+      "version": "4.3.2",
+      "resolved": "https://registry.npmmirror.com/lodash.set/-/lodash.set-4.3.2.tgz",
+      "integrity": "sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg=="
+    },
+    "node_modules/lodash.unset": {
+      "version": "4.5.2",
+      "resolved": "https://registry.npmmirror.com/lodash.unset/-/lodash.unset-4.5.2.tgz",
+      "integrity": "sha512-bwKX88k2JhCV9D1vtE8+naDKlLiGrSmf8zi/Y9ivFHwbmRfA8RxS/aVJ+sIht2XOwqoNr4xUPUkGZpc1sHFEKg=="
+    },
+    "node_modules/long": {
+      "version": "5.3.2",
+      "resolved": "https://registry.npmmirror.com/long/-/long-5.3.2.tgz",
+      "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="
+    },
+    "node_modules/math-intrinsics": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+      "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ms": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+    },
+    "node_modules/oauth-sign": {
+      "version": "0.9.0",
+      "resolved": "https://registry.npmmirror.com/oauth-sign/-/oauth-sign-0.9.0.tgz",
+      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/object-inspect": {
+      "version": "1.13.4",
+      "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.13.4.tgz",
+      "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/performance-now": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/performance-now/-/performance-now-2.1.0.tgz",
+      "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="
+    },
+    "node_modules/protobufjs": {
+      "version": "7.5.4",
+      "resolved": "https://registry.npmmirror.com/protobufjs/-/protobufjs-7.5.4.tgz",
+      "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==",
+      "hasInstallScript": true,
+      "dependencies": {
+        "@protobufjs/aspromise": "^1.1.2",
+        "@protobufjs/base64": "^1.1.2",
+        "@protobufjs/codegen": "^2.0.4",
+        "@protobufjs/eventemitter": "^1.1.0",
+        "@protobufjs/fetch": "^1.1.0",
+        "@protobufjs/float": "^1.0.2",
+        "@protobufjs/inquire": "^1.1.0",
+        "@protobufjs/path": "^1.1.2",
+        "@protobufjs/pool": "^1.1.0",
+        "@protobufjs/utf8": "^1.1.0",
+        "@types/node": ">=13.7.0",
+        "long": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=12.0.0"
+      }
+    },
+    "node_modules/psl": {
+      "version": "1.15.0",
+      "resolved": "https://registry.npmmirror.com/psl/-/psl-1.15.0.tgz",
+      "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==",
+      "dependencies": {
+        "punycode": "^2.3.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/lupomontero"
+      }
+    },
+    "node_modules/punycode": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz",
+      "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/qs": {
+      "version": "6.5.3",
+      "resolved": "https://registry.npmmirror.com/qs/-/qs-6.5.3.tgz",
+      "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/request": {
+      "version": "2.88.2",
+      "resolved": "https://registry.npmmirror.com/request/-/request-2.88.2.tgz",
+      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
+      "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142",
+      "dependencies": {
+        "aws-sign2": "~0.7.0",
+        "aws4": "^1.8.0",
+        "caseless": "~0.12.0",
+        "combined-stream": "~1.0.6",
+        "extend": "~3.0.2",
+        "forever-agent": "~0.6.1",
+        "form-data": "~2.3.2",
+        "har-validator": "~5.1.3",
+        "http-signature": "~1.2.0",
+        "is-typedarray": "~1.0.0",
+        "isstream": "~0.1.2",
+        "json-stringify-safe": "~5.0.1",
+        "mime-types": "~2.1.19",
+        "oauth-sign": "~0.9.0",
+        "performance-now": "^2.1.0",
+        "qs": "~6.5.2",
+        "safe-buffer": "^5.1.2",
+        "tough-cookie": "~2.5.0",
+        "tunnel-agent": "^0.6.0",
+        "uuid": "^3.3.2"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/retry": {
+      "version": "0.13.1",
+      "resolved": "https://registry.npmmirror.com/retry/-/retry-0.13.1.tgz",
+      "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==",
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/safe-buffer": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
+      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
+    },
+    "node_modules/safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+    },
+    "node_modules/sax": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/sax/-/sax-1.4.1.tgz",
+      "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="
+    },
+    "node_modules/semver": {
+      "version": "5.7.2",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.2.tgz",
+      "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/side-channel": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.1.0.tgz",
+      "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "object-inspect": "^1.13.3",
+        "side-channel-list": "^1.0.0",
+        "side-channel-map": "^1.0.1",
+        "side-channel-weakmap": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/side-channel-list": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/side-channel-list/-/side-channel-list-1.0.0.tgz",
+      "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "object-inspect": "^1.13.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/side-channel-map": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/side-channel-map/-/side-channel-map-1.0.1.tgz",
+      "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.5",
+        "object-inspect": "^1.13.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/side-channel-weakmap": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+      "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.5",
+        "object-inspect": "^1.13.3",
+        "side-channel-map": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/sshpk": {
+      "version": "1.18.0",
+      "resolved": "https://registry.npmmirror.com/sshpk/-/sshpk-1.18.0.tgz",
+      "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==",
+      "dependencies": {
+        "asn1": "~0.2.3",
+        "assert-plus": "^1.0.0",
+        "bcrypt-pbkdf": "^1.0.0",
+        "dashdash": "^1.12.0",
+        "ecc-jsbn": "~0.1.1",
+        "getpass": "^0.1.1",
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.0.2",
+        "tweetnacl": "~0.14.0"
+      },
+      "bin": {
+        "sshpk-conv": "bin/sshpk-conv",
+        "sshpk-sign": "bin/sshpk-sign",
+        "sshpk-verify": "bin/sshpk-verify"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/tough-cookie": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmmirror.com/tough-cookie/-/tough-cookie-2.5.0.tgz",
+      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+      "dependencies": {
+        "psl": "^1.1.28",
+        "punycode": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/tslib": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-1.14.1.tgz",
+      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+    },
+    "node_modules/tunnel-agent": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmmirror.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+      "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmmirror.com/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="
+    },
+    "node_modules/undici-types": {
+      "version": "7.10.0",
+      "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-7.10.0.tgz",
+      "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag=="
+    },
+    "node_modules/uri-js": {
+      "version": "4.4.1",
+      "resolved": "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz",
+      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+      "dependencies": {
+        "punycode": "^2.1.0"
+      }
+    },
+    "node_modules/url": {
+      "version": "0.11.4",
+      "resolved": "https://registry.npmmirror.com/url/-/url-0.11.4.tgz",
+      "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==",
+      "dependencies": {
+        "punycode": "^1.4.1",
+        "qs": "^6.12.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/url/node_modules/punycode": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/punycode/-/punycode-1.4.1.tgz",
+      "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="
+    },
+    "node_modules/url/node_modules/qs": {
+      "version": "6.14.0",
+      "resolved": "https://registry.npmmirror.com/qs/-/qs-6.14.0.tgz",
+      "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
+      "dependencies": {
+        "side-channel": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=0.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/uuid": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmmirror.com/uuid/-/uuid-3.4.0.tgz",
+      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+      "deprecated": "Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.",
+      "bin": {
+        "uuid": "bin/uuid"
+      }
+    },
+    "node_modules/verror": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmmirror.com/verror/-/verror-1.10.0.tgz",
+      "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
+      "engines": [
+        "node >=0.6.0"
+      ],
+      "dependencies": {
+        "assert-plus": "^1.0.0",
+        "core-util-is": "1.0.2",
+        "extsprintf": "^1.2.0"
+      }
+    },
+    "node_modules/wx-server-sdk": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/wx-server-sdk/-/wx-server-sdk-3.0.1.tgz",
+      "integrity": "sha512-b53tbqTV9knXJIfcmWTmksQvk+BC54vTU6WZNwEvAJ3iOxrRhPitcygyiwFfMBWpFm9YvkwITEhU821XoG8llQ==",
+      "dependencies": {
+        "@cloudbase/node-sdk": "2.10.0",
+        "json-bigint": "^1.0.0",
+        "protobufjs": "^7.2.4",
+        "tslib": "^1.9.3"
+      }
+    },
+    "node_modules/xml2js": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmmirror.com/xml2js/-/xml2js-0.5.0.tgz",
+      "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
+      "dependencies": {
+        "sax": ">=0.6.0",
+        "xmlbuilder": "~11.0.0"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/xmlbuilder": {
+      "version": "11.0.1",
+      "resolved": "https://registry.npmmirror.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+      "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
+      "engines": {
+        "node": ">=4.0"
+      }
+    }
+  }
+}

+ 15 - 0
cloud/lxp/package.json

@@ -0,0 +1,15 @@
+{
+  "name": "lxp",
+  "version": "1.0.0",
+  "description": "",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "author": "",
+  "license": "ISC",
+  "dependencies": {
+    "request": "^2.88.2",
+    "wx-server-sdk": "~3.0.1"
+  }
+}

+ 168 - 0
cloud/lxp/utils/smsUtil.js

@@ -0,0 +1,168 @@
+const request = require('request')
+
+const username = 'BJHHEhy'
+const password = 'jMRYvR4f)!qD#T^IfqoNnX8F!*Kq!HZN'
+
+/**
+ * 东八区当前时间戳,精确到秒,10位长度。
+ */
+const timest = () => {
+  var tmp = Date.parse( new Date() ).toString()
+  tmp = tmp.substr(0,10)
+  return tmp
+}
+
+/**
+ * 密码,密码采用32位小写MD5二次加密,例:md5( md5( password ) + tKey ) , +为拼接符,不参与加密。
+ * @param {*} data 明文密码
+ */
+const md5 = data => {
+  var Buffer = require('buffer').Buffer
+  var buf = new Buffer(data)
+  var str = buf.toString('binary')
+  var crypto = require('crypto')
+  return crypto.createHash('md5WithRSAEncryption').update(str).digest('hex')
+}
+
+/**
+ * 处理请求, 使用Promise将异步操作变为同步
+ * @param {*} event 
+ */
+const handleRequest = options => {
+  return new Promise((resolve, reject) => {
+    request(options, (error, response, body) => {
+      if (!error && response.statusCode === 200) {
+          resolve(body)
+      } else {
+          reject(error)
+      }
+    })
+  })
+}
+
+
+/**
+ * 短信模板查询
+ * @param {*} event 
+ */
+const templateQuery = event => {
+  //生成十位时间戳
+  const tKey = timest()
+  // 配置 POST 请求的选项
+  const options = {
+    // url: 'https://api-shss.zthysms.com/v2/sendSms',
+    url: 'https://api-shss.zthysms.com/sms/v2/template/query',
+    method: 'POST',
+    headers: { 'Content-Type': 'application/json' },
+    json: true,
+    body: {
+      username,
+      password: md5(md5(password) + tKey),
+      tKey,
+      temId: 397495,
+    }
+  }
+  return handleRequest(options)
+}
+
+/**
+ * 短信模板列表查询
+ * @param {*} event 
+ */
+const templateList = event => {
+  //生成十位时间戳
+  const tKey = timest()
+  // 配置 POST 请求的选项
+  const options = {
+    url: 'https://api-shss.zthysms.com/sms/v2/template/list',
+    method: 'POST',
+    headers: { 'Content-Type': 'application/json' },
+    json: true,
+    body: {
+      username,
+      password: md5(md5(password) + tKey),
+      tKey,
+      page: 1,
+      size: 10,
+    }
+  }
+  return handleRequest(options)
+}
+
+/**
+ * 短信签名列表查询
+ * @param {*} event 
+ */
+const signList = event => {
+  //生成十位时间戳
+  const tKey = timest()
+  // 配置 POST 请求的选项
+  const options = {
+    url: 'https://api-shss.zthysms.com/sms/v1/sign/list',
+    method: 'POST',
+    headers: { 'Content-Type': 'application/json' },
+    json: true,
+    body: {
+      username,
+      password: md5(md5(password) + tKey),
+      tKey,
+      // 审核状态 (1.待审核 2.审核通过 3.审核不通过)
+      status: 2,
+      page: 1,
+      size: 10,
+    }
+  }
+  return handleRequest(options)
+}
+
+/**
+ * 模板短信发送
+ * @param {*} event 
+ */
+const sendSmsTp = event => {
+  //生成十位时间戳
+  const tKey = timest()
+  // 配置 POST 请求的选项
+  const options = {
+    url: 'https://api-shss.zthysms.com/v2/sendSmsTp',
+    method: 'POST',
+    headers: { 'Content-Type': 'application/json' },
+    json: true,
+    body: {
+      username,
+      password: md5(md5(password) + tKey),
+      tKey,
+      // 已报备的签名
+      signature: '【红孩儿智慧教育】',
+      // 模板id
+      tpId: 397495,
+      // 扩展号。纯数字,最多8位。
+      ext: '',
+      // 发送时间。若为空,立即发送;若不为空,设置定时字符串日期,定时时间必须大于当前时间,格式:yyyy-MM-dd HH:mm:ss
+      time: '',
+      // 自定义参数,在获取状态报告时返回,最大长度100。
+      extend: '', 
+      records: [
+        {
+          mobile: event.mobile,
+          tpContent: {
+            valid_code: event.code,
+          }
+        }
+      ]
+    }
+  }
+  return handleRequest(options)
+}
+
+
+module.exports = {
+  // 根据模版Id查询模版
+  templateQuery,
+  // 查询所有模版
+  templateList,
+  // 短信签名列表查询
+  signList,
+  // 模板短信发送
+  sendSmsTp,
+}

+ 17 - 0
components/captcha/captcha.js

@@ -44,6 +44,9 @@ Component({
         return;
       }
       const generateCode = this.generateCode(); // 本地生成验证码(用于发送)
+      this.setData({ generateCode, isSending: true });
+
+      wx.showLoading({ title: '获取中...', mask: true });
       // 保存验证码到 data
       this.setData({ generateCode });
       wx.cloud.callFunction({
@@ -61,6 +64,8 @@ Component({
             title: '验证码发送成功',
             icon: 'none'
           });
+          // 启动倒计时
+          this.startCountdown(60);
         } else {
           console.error('数据获取失败 =>', res.result.response);
           wx.showToast({
@@ -102,5 +107,17 @@ Component({
       }
       return result
     },
+
+    startCountdown(seconds) {
+      this.setData({ countdown: seconds });
+      const timer = setInterval(() => {
+        if (this.data.countdown <= 1) {
+          clearInterval(timer);
+          this.setData({ countdown: 0, isSending: false }); // 倒计时结束后重置 isSending
+        } else {
+          this.setData({ countdown: this.data.countdown - 1 });
+        }
+      }, 1000);
+    },
   }
 })

+ 3 - 1
components/captcha/captcha.wxml

@@ -3,6 +3,8 @@
   <label>验证码</label>
   <view style="display: flex;">
     <input style="width: 95%;margin-right: 3%;" type="text" placeholder="请输入验证码" bindinput="onInputCode"/>
-    <button bindtap="getCode" class="get-code-btn">获取验证码</button>
+    <button bindtap="getCode" class="get-code-btn" disabled="{{isSending || countdown > 0}}">
+      {{countdown > 0 ? countdown + '秒后重试' : '获取验证码'}}
+    </button>
   </view>
 </view>

+ 6 - 6
custom-tab-bar/index.js

@@ -16,12 +16,12 @@ Component({
         iconPath: "/image/tuangou.png",
         selectedIconPath: "/image/tuangou_1.png"
       },
-      {
-        pagePath: "/pages/shoppingcart/shoppingcart",
-        text: "购物车",
-        iconPath: "/image/gouwuche.png",
-        selectedIconPath: "/image/gouwuche_1.png"
-      },
+      // {
+      //   pagePath: "/pages/shoppingcart/shoppingcart",
+      //   text: "购物车",
+      //   iconPath: "/image/gouwuche.png",
+      //   selectedIconPath: "/image/gouwuche_1.png"
+      // },
       {
         pagePath: "/pages/me/me",
         text: "我的",

+ 1 - 2
package-lock.json

@@ -11,8 +11,7 @@
       "dependencies": {
         "@cloudbase/wx-cloud-client-sdk": "^1.6.1",
         "vant-weapp": "^0.5.29"
-      },
-      "devDependencies": {}
+      }
     },
     "node_modules/@cloudbase/wx-cloud-client-sdk": {
       "version": "1.6.1",

+ 0 - 1
package.json

@@ -7,7 +7,6 @@
     "@cloudbase/wx-cloud-client-sdk": "^1.6.1",
     "vant-weapp": "^0.5.29"
   },
-  "devDependencies": {},
   "scripts": {
     "test": "echo \"Error: no test specified\" && exit 1"
   },

+ 2 - 2
pages/groupbuying/groupbuying.js

@@ -25,8 +25,8 @@ Page({
   onLoad(options) {
 
     const fileIDs = [
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/sou.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/gouwuc_img.png'
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/sou.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/gouwuc_img.png'
     ];
     
     // 并发下载多个 fileID

+ 3 - 3
pages/groupbuying/groupbuying.wxss

@@ -61,7 +61,7 @@
 .list_boxsss {
   width: 100%;
   /* width: calc(100% - 60rpx); */
-  height: calc(100% - 280rpx);
+  height: calc(100% - 360rpx);
   position: fixed;
   top: 260rpx;
   left: 0;
@@ -144,7 +144,7 @@
 .list_boxsss {
   /* width: calc( 100% - 60rpx); */
   padding: 0rpx 30rpx;
-  height: calc(100% - 270rpx);
+  height: calc(100% - 360rpx);
   position: fixed;
   top: 260rpx;
   left: 0;
@@ -157,7 +157,7 @@
 }
 
 .no-more-text {
-  padding-top: 20rpx;
+  padding: 20rpx 0;
   width: 100%;
   text-align: center;
 }

+ 39 - 24
pages/index/index.js

@@ -27,34 +27,49 @@ Page({
     this.getBanner();
     // 获取图片
     const fileIDs = [
-      // 'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/banner/carousel_1.jpg',
-      // 'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/banner/carousel_2.jpg',
-      // 'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/banner/carousel_3.jpg',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/homepage/homepage_4.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/homepage/homepage_3.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/homepage/homepage_2.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/homepage/homepage_1.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/sou.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/homepage/homepage_4.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/homepage/homepage_3.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/homepage/homepage_2.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/homepage/homepage_1.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/sou.png',
     ];
     
     // 并发下载多个 fileID
-    Promise.all(
-      fileIDs.map(fileID => wx.cloud.downloadFile({ fileID }))
-    ).then(results => {
-      // 每个 result 对应一个下载结果
-      const tempFilePaths = results.map(r => r.tempFilePath);
-      console.log('全部下载成功:', tempFilePaths);
-      this.setData({
-        // carousellist: tempFilePaths.slice(0, 2),
-        homepage_4: tempFilePaths[0],
-        homepage_3: tempFilePaths[1],
-        homepage_2: tempFilePaths[2],
-        homepage_1: tempFilePaths[3],
-        souimg: tempFilePaths[4]
-      });
-    }).catch(err => {
-      console.error('有文件下载失败:', err);
+    // Promise.all(
+    //   fileIDs.map(fileID => wx.cloud.downloadFile({ fileID }))
+    // ).then(results => {
+    //   // 每个 result 对应一个下载结果
+    //   const tempFilePaths = results.map(r => r.tempFilePath);
+    //   console.log('全部下载成功:', tempFilePaths);
+    //   this.setData({
+    //     // carousellist: tempFilePaths.slice(0, 2),
+    //     homepage_4: tempFilePaths[0],
+    //     homepage_3: tempFilePaths[1],
+    //     homepage_2: tempFilePaths[2],
+    //     homepage_1: tempFilePaths[3],
+    //     souimg: tempFilePaths[4]
+    //   });
+    // }).catch(err => {
+    //   console.error('有文件下载失败:', err);
+    // });
+
+    wx.cloud.getTempFileURL({
+      fileList: fileIDs,
+      success: res => {
+        console.log('getTempFileURL结果', res.fileList);
+        this.setData({
+          homepage_4: res.fileList[0].tempFileURL,
+          homepage_3: res.fileList[1].tempFileURL,
+          homepage_2: res.fileList[2].tempFileURL,
+          homepage_1: res.fileList[3].tempFileURL,
+          souimg: res.fileList[4].tempFileURL,
+        });
+      },
+      fail: err => {
+        console.error('getTempFileURL失败', err);
+      }
     });
+  
   },
 
     // 轮播数据

+ 2 - 0
pages/index/index.wxml

@@ -4,6 +4,7 @@
     <view class="search-bar" bindtap="goSearchPage">
       <input class="search-input" placeholder="搜索课件" disabled />
       <image class="search-icon" src="{{souimg}}" />
+      <!-- {{souimg}} -->
     </view>
     
     <!-- 空白区域 -->
@@ -19,6 +20,7 @@
 
     <!-- 课程分类按钮 -->
     <view class="course-buttons">
+      <!-- {{homepage_4}} -->
       <view class="course-button1" style="background-image: url({{homepage_4}}); background-size: cover;" bindtap="selectGroupOption" data-option="course">
         <view class="nr_boxs">
           <text>课程</text>

+ 1 - 1
pages/logins/logins.wxml

@@ -17,7 +17,7 @@
       </view>
     </view>
     <captcha id="loginCaptcha" phone="{{phone}}" />
-    <navigator url="/pages/login/login" open-type="navigate">您还没有账号,去注册</navigator>
+    <navigator url="/pages/login/login" open-type="navigate">您还没有绑定,去绑定</navigator>
     <button bindtap="onConfirm" class="confirm-btn">登录</button>
   </view>
 </view>

+ 25 - 6
pages/me/me.js

@@ -27,10 +27,10 @@ Page({
   onLoad(options) {
 
       const fileIDs = [
-        'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/xiugai.png',
-        'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/xiangji.png',
-        'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/xiazi.png',
-        'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/soucangs.png'
+        'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/xiugai.png',
+        'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/xiangji.png',
+        'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/xiazi.png',
+        'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/soucangs.png'
       ];
       
       // 并发下载多个 fileID
@@ -142,7 +142,11 @@ Page({
 
     // 第四步:更新页面数据(过滤掉失败项)
     this.setData({
-      historyItems: fileDetails.filter(Boolean)
+      // historyItems: fileDetails.filter(Boolean)
+      historyItems: fileDetails.filter(Boolean).map(item => ({
+        ...item,
+        createdAt: this.formatTime(item.createdAt)  // 格式化时间
+      }))
     });
   },
 
@@ -184,13 +188,28 @@ Page({
 
     // 第四步:更新页面数据
     this.setData({
-      collectFiles: fileRes.data.records || []
+      // collectFiles: fileRes.data.records || []
+      collectFiles: (fileRes.data.records || []).map(item => ({
+        ...item,
+        createdAt: this.formatTime(item.createdAt)
+      }))
     });
 
     console.log('收藏的文件数据:', fileRes.data.records);
 
   },
 
+  formatTime(ts) {
+    const date = new Date(ts);
+    const y = date.getFullYear();
+    const m = String(date.getMonth() + 1).padStart(2, '0');
+    const d = String(date.getDate()).padStart(2, '0');
+    const hh = String(date.getHours()).padStart(2, '0');
+    const mm = String(date.getMinutes()).padStart(2, '0');
+    const ss = String(date.getSeconds()).padStart(2, '0');
+    return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
+  },
+
   // 注销跳转
   handleLogout() {
     wx.navigateTo({

+ 1 - 1
pages/shoppingcart/shoppingcart.js

@@ -33,7 +33,7 @@ Page({
     this.updateTotalPrice();
 
     const fileIDs = [
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/sou.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/sou.png',
     ];
     
     // 并发下载多个 fileID

+ 1 - 1
project.config.json

@@ -37,7 +37,7 @@
     "tabIndent": "auto",
     "tabSize": 2
   },
-  "appid": "wx06f2b1b09ac5684f",
+  "appid": "wx1ee76fb4846f8901",
   "simulatorPluginLibVersion": {},
   "cloudfunctionTemplateRoot": "cloudfunctionTemplate/"
 }

+ 56 - 51
subpackages/changephone/changephone.js

@@ -1,66 +1,71 @@
 // subpackages/changephone/changephone.js
+import { models, db } from '../../utils/cloudbase.js'
 Page({
 
   /**
    * 页面的初始数据
    */
   data: {
-
-  },
-
-  /**
-   * 生命周期函数--监听页面加载
-   */
-  onLoad(options) {
-
-  },
-
-  /**
-   * 生命周期函数--监听页面初次渲染完成
-   */
-  onReady() {
-
-  },
-
-  /**
-   * 生命周期函数--监听页面显示
-   */
-  onShow() {
-
-  },
-
-  /**
-   * 生命周期函数--监听页面隐藏
-   */
-  onHide() {
-
+    phone: '',
   },
 
-  /**
-   * 生命周期函数--监听页面卸载
-   */
-  onUnload() {
-
-  },
-
-  /**
-   * 页面相关事件处理函数--监听用户下拉动作
-   */
-  onPullDownRefresh() {
-
+  onLoad() {
+    const userInfo = wx.getStorageSync('userInfo')
+    this.setData({
+      phone: userInfo.phone
+    })
   },
 
-  /**
-   * 页面上拉触底事件的处理函数
-   */
-  onReachBottom() {
-
+  // 监听手机号输入框
+  onPhoneInput(e) {
+    this.setData({
+      phone: e.detail.value
+    });
   },
 
-  /**
-   * 用户点击右上角分享
-   */
-  onShareAppMessage() {
-
+  // 确定
+  async bindingevents() {
+    let userInfo = wx.getStorageSync('userInfo')
+    console.log(userInfo._id, this.data.phone, 'userInfo._id');
+    const { data } = await models.wx_teacher_user.update({
+      data: {
+          phone: this.data.phone,  // 手机号
+        },
+      filter: {
+        where: {
+          $and: [
+            {
+              _id: {
+                $eq: userInfo._id, // 推荐传入_id数据标识进行操作
+              },
+            },
+          ]
+        }
+      },
+      envType: "prod",
+    });
+    if(data.count >= 1) {
+      // 更新本地缓存里的 userInfo
+      userInfo.phone = this.data.phone;
+      wx.setStorageSync('userInfo', userInfo);
+      wx.showToast({
+        title: '修改成功',
+        icon: 'success',
+        duration: 1500,
+        success() {
+          // 延迟一点时间再返回上一页
+          setTimeout(() => {
+            wx.navigateBack();
+          }, 1500);
+        }
+      });
+    } else {
+      wx.showToast({
+        title: '修改失败',
+        icon: 'none',
+        duration: 1500
+      });
+    }
   }
+
 })

+ 3 - 1
subpackages/changephone/changephone.json

@@ -1,4 +1,6 @@
 {
-  "usingComponents": {},
+  "usingComponents": {
+    "captcha": "/components/captcha/captcha"
+  },
   "navigationBarTitleText": "更改手机号"
 }

+ 7 - 4
subpackages/changephone/changephone.wxml

@@ -2,15 +2,18 @@
   <view class="goodslist_boxs">
     <view class="input-group">
       <label>手机号码</label>
-      <input type="text" placeholder="请输入手机号码" />
+      <input value="{{phone}}" bindinput="onPhoneInput" type="text" placeholder="请输入手机号码" />
     </view>
-    <view class="input-group">
+
+    <captcha id="registorCaptcha" phone="{{phone}}" />
+    
+    <!-- <view class="input-group">
       <label>验证码</label>
       <view style="display: flex;">
         <input style="width: 95%;margin-right: 3%;" type="text" placeholder="请输入验证码" />
         <button class="get-code-btn">获取验证码</button>
       </view>
-    </view>
-    <button class="confirm-btn">确定</button>
+    </view> -->
+    <button class="confirm-btn" bindtap="bindingevents">确定</button>
   </view>
 </view>

+ 15 - 2
subpackages/collect/collect.js

@@ -23,7 +23,7 @@ Page({
     // 页面加载时的初始化操作
 
     const fileIDs = [
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/soucangs.png'
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/soucangs.png'
     ];
     
     // 并发下载多个 fileID
@@ -95,7 +95,8 @@ Page({
   
       const newFiles = fileRes.data.records.map(item => ({
         ...item,
-        checked: false
+        checked: false,
+        createdAt: this.formatTime(item.createdAt) // 这里格式化
       }));
 
       this.setData({
@@ -111,6 +112,18 @@ Page({
     }
   },
 
+  // 格式化时间函数
+  formatTime(ts) {
+    const date = new Date(ts);
+    const y = date.getFullYear();
+    const m = String(date.getMonth() + 1).padStart(2, '0');
+    const d = String(date.getDate()).padStart(2, '0');
+    const hh = String(date.getHours()).padStart(2, '0');
+    const mm = String(date.getMinutes()).padStart(2, '0');
+    const ss = String(date.getSeconds()).padStart(2, '0');
+    return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
+  },
+
   // 收藏管理是否编辑 
   toggleManageMode() {
     const { isManaging, historyList } = this.data;

+ 34 - 22
subpackages/jxhome/jxhome.js

@@ -17,30 +17,42 @@ Page({
     this.getBanner();
     // 获取图片
     const fileIDs = [
-      // 'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/banner/carousel_1.jpg',
-      // 'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/banner/carousel_2.jpg',
-      // 'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/banner/carousel_3.jpg',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/homepage/homepage_7.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/homepage/homepage_6.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/homepage/homepage_5.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/homepage/homepage_7.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/homepage/homepage_6.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/homepage/homepage_5.png',
     ];
-    
-    // 并发下载多个 fileID
-    Promise.all(
-      fileIDs.map(fileID => wx.cloud.downloadFile({ fileID }))
-    ).then(results => {
-      // 每个 result 对应一个下载结果
-      const tempFilePaths = results.map(r => r.tempFilePath);
-      console.log('全部下载成功:', tempFilePaths);
-      this.setData({
-        // carousellist: tempFilePaths.slice(0, 2),
-        homepage_7: tempFilePaths[0],
-        homepage_6: tempFilePaths[1],
-        homepage_5: tempFilePaths[2],
-      });
-    }).catch(err => {
-      console.error('有文件下载失败:', err);
+
+    wx.cloud.getTempFileURL({
+      fileList: fileIDs,
+      success: res => {
+        console.log('getTempFileURL结果', res.fileList);
+        this.setData({
+          homepage_7: res.fileList[0].tempFileURL,
+          homepage_6: res.fileList[1].tempFileURL,
+          homepage_5: res.fileList[2].tempFileURL,
+        });
+      },
+      fail: err => {
+        console.error('getTempFileURL失败', err);
+      }
     });
+    
+    // // 并发下载多个 fileID
+    // Promise.all(
+    //   fileIDs.map(fileID => wx.cloud.downloadFile({ fileID }))
+    // ).then(results => {
+    //   // 每个 result 对应一个下载结果
+    //   const tempFilePaths = results.map(r => r.tempFilePath);
+    //   console.log('全部下载成功:', tempFilePaths);
+    //   this.setData({
+    //     // carousellist: tempFilePaths.slice(0, 2),
+    //     homepage_7: tempFilePaths[0],
+    //     homepage_6: tempFilePaths[1],
+    //     homepage_5: tempFilePaths[2],
+    //   });
+    // }).catch(err => {
+    //   console.error('有文件下载失败:', err);
+    // });
   },
 
   // 轮播数据

+ 32 - 20
subpackages/kchome/kchome.js

@@ -17,29 +17,41 @@ Page({
     this.getBanner();
     // 获取图片
     const fileIDs = [
-      // 'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/banner/carousel_1.jpg',
-      // 'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/banner/carousel_2.jpg',
-      // 'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/banner/carousel_3.jpg',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/homepage/homepage_7.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/homepage/homepage_6.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/homepage/homepage_5.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/homepage/homepage_7.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/homepage/homepage_6.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/homepage/homepage_5.png',
     ];
     
     // 并发下载多个 fileID
-    Promise.all(
-      fileIDs.map(fileID => wx.cloud.downloadFile({ fileID }))
-    ).then(results => {
-      // 每个 result 对应一个下载结果
-      const tempFilePaths = results.map(r => r.tempFilePath);
-      console.log('全部下载成功:', tempFilePaths);
-      this.setData({
-        // carousellist: tempFilePaths.slice(0, 2),
-        homepage_7: tempFilePaths[0],
-        homepage_6: tempFilePaths[1],
-        homepage_5: tempFilePaths[2],
-      });
-    }).catch(err => {
-      console.error('有文件下载失败:', err);
+    // Promise.all(
+    //   fileIDs.map(fileID => wx.cloud.downloadFile({ fileID }))
+    // ).then(results => {
+    //   // 每个 result 对应一个下载结果
+    //   const tempFilePaths = results.map(r => r.tempFilePath);
+    //   console.log('全部下载成功:', tempFilePaths);
+    //   this.setData({
+    //     // carousellist: tempFilePaths.slice(0, 2),
+    //     homepage_7: tempFilePaths[0],
+    //     homepage_6: tempFilePaths[1],
+    //     homepage_5: tempFilePaths[2],
+    //   });
+    // }).catch(err => {
+    //   console.error('有文件下载失败:', err);
+    // });
+
+    wx.cloud.getTempFileURL({
+      fileList: fileIDs,
+      success: res => {
+        console.log('getTempFileURL结果', res.fileList);
+        this.setData({
+          homepage_7: res.fileList[0].tempFileURL,
+          homepage_6: res.fileList[1].tempFileURL,
+          homepage_5: res.fileList[2].tempFileURL,
+        });
+      },
+      fail: err => {
+        console.error('getTempFileURL失败', err);
+      }
     });
   },
 

+ 4 - 5
subpackages/productdetails/productdetails.js

@@ -23,9 +23,8 @@ Page({
     });
 
     const fileIDs = [
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/show.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/fenxianglj.png'
-      // 'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/gouwuc_img.png'
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/show.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/fenxianglj.png'
     ];
     
     // 并发下载多个 fileID
@@ -110,10 +109,10 @@ Page({
     let path = '';
 
     if (shareType === 'teacher') {
-      title = '老师推荐的优质商品,快来看!';
+      title = '推荐给老师的优质商品,快来看!';
       path = `/subpackages/productdetails/productdetails?data=${encodeURIComponent(JSON.stringify(item))}&from=teacher`;
     } else {
-      title = '家长推荐的宝藏商品,别错过!';
+      title = '推荐给家长的宝藏商品,别错过!';
       path = `/subpackages/productdetails/productdetails?data=${encodeURIComponent(JSON.stringify(item))}&from=parent`;
     }
 

+ 2 - 2
subpackages/productdetails/productdetails.wxml

@@ -32,11 +32,11 @@
     <view class="specifications">
       <text style="font-size: 38rpx;">选择规格</text>
       <view wx:if="{{item.specList.length > 0}}" class="specifications_boxs">
-        <button wx:for="{{item.specList}}" wx:key="index" class="spec-btn {{gaoliao === index ? 'active' : ''}}"
+        <view wx:for="{{item.specList}}" wx:key="index" class="spec-btn {{gaoliao === index ? 'active' : ''}}"
         bindtap="selectSpec"
         data-specindex="{{index}}">
           {{item.spec}}
-        </button>
+        </view>
       </view>
       <view wx:else class="specifications_boxs">
         <text style="width: 100%; text-align: center; padding: 30rpx 0; color: #ccc;">暂无规格</text>

+ 3 - 3
subpackages/productdetails/productdetails.wxss

@@ -68,14 +68,14 @@
   height: 80%;
   margin-top: 20rpx;
   display: flex;
-  flex-wrap: wrap; /* 允许内容自动换行 */
-  justify-content: flex-start; /* 靠右排列 */
+  flex-wrap: wrap;
+  justify-content: flex-start;
   align-content: flex-start;
   gap: 20rpx; /* 设置项目之间的间距 */
 }
 
 .spec-btn {
-  width: 48% !important;
+  /* width: 48% !important; */
   margin-bottom: 20rpx; /* 设置底部边距,确保换行后有间距 */
   padding: 10rpx 20rpx;
   border: 1px solid #ccc;

+ 15 - 2
subpackages/purchasehistory/purchasehistory.js

@@ -22,7 +22,7 @@ Page({
     });
     // 页面加载时的初始化操作
     const fileIDs = [
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/xiazi.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/xiazi.png',
     ];
     
     // 并发下载多个 fileID
@@ -121,7 +121,8 @@ Page({
           return {
             ...file,
             checked: false,
-            download_history_id: historyRecord._id  // 关键:存 download_history 的 id
+            download_history_id: historyRecord._id,  // 关键:存 download_history 的 id
+            createdAt: this.formatTime(file.createdAt) // 这里格式化
           };
         });
 
@@ -139,6 +140,18 @@ Page({
     }
   },
 
+  // 格式化时间函数
+  formatTime(ts) {
+    const date = new Date(ts);
+    const y = date.getFullYear();
+    const m = String(date.getMonth() + 1).padStart(2, '0');
+    const d = String(date.getDate()).padStart(2, '0');
+    const hh = String(date.getHours()).padStart(2, '0');
+    const mm = String(date.getMinutes()).padStart(2, '0');
+    const ss = String(date.getSeconds()).padStart(2, '0');
+    return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
+  },
+
   // 收藏管理是否编辑 
   toggleManageMode() {
     const { isManaging, historyList } = this.data;

+ 33 - 21
subpackages/pxhome/pxhome.js

@@ -17,30 +17,42 @@ Page({
     this.getBanner();
     // 获取图片
     const fileIDs = [
-      // 'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/banner/carousel_1.jpg',
-      // 'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/banner/carousel_2.jpg',
-      // 'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/banner/carousel_3.jpg',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/homepage/homepage_7.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/homepage/homepage_6.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/homepage/homepage_5.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/homepage/homepage_7.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/homepage/homepage_6.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/homepage/homepage_5.png',
     ];
+
+    wx.cloud.getTempFileURL({
+      fileList: fileIDs,
+      success: res => {
+        console.log('getTempFileURL结果', res.fileList);
+        this.setData({
+          homepage_7: res.fileList[0].tempFileURL,
+          homepage_6: res.fileList[1].tempFileURL,
+          homepage_5: res.fileList[2].tempFileURL,
+        });
+      },
+      fail: err => {
+        console.error('getTempFileURL失败', err);
+      }
+    });
     
     // 并发下载多个 fileID
-    Promise.all(
-      fileIDs.map(fileID => wx.cloud.downloadFile({ fileID }))
-    ).then(results => {
-      // 每个 result 对应一个下载结果
-      const tempFilePaths = results.map(r => r.tempFilePath);
-      console.log('全部下载成功:', tempFilePaths);
-      this.setData({
-        // carousellist: tempFilePaths.slice(0, 2),
-        homepage_7: tempFilePaths[0],
-        homepage_6: tempFilePaths[1],
-        homepage_5: tempFilePaths[2],
-      });
-    }).catch(err => {
-      console.error('有文件下载失败:', err);
-    });
+    // Promise.all(
+    //   fileIDs.map(fileID => wx.cloud.downloadFile({ fileID }))
+    // ).then(results => {
+    //   // 每个 result 对应一个下载结果
+    //   const tempFilePaths = results.map(r => r.tempFilePath);
+    //   console.log('全部下载成功:', tempFilePaths);
+    //   this.setData({
+    //     // carousellist: tempFilePaths.slice(0, 2),
+    //     homepage_7: tempFilePaths[0],
+    //     homepage_6: tempFilePaths[1],
+    //     homepage_5: tempFilePaths[2],
+    //   });
+    // }).catch(err => {
+    //   console.error('有文件下载失败:', err);
+    // });
   },
 
   // 轮播数据

+ 33 - 21
subpackages/zshome/zshome.js

@@ -17,30 +17,42 @@ Page({
     this.getBanner();
     // 获取图片
     const fileIDs = [
-      // 'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/banner/carousel_1.jpg',
-      // 'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/banner/carousel_2.jpg',
-      // 'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/banner/carousel_3.jpg',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/homepage/homepage_7.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/homepage/homepage_6.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/homepage/homepage_5.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/homepage/homepage_7.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/homepage/homepage_6.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/homepage/homepage_5.png',
     ];
+
+    wx.cloud.getTempFileURL({
+      fileList: fileIDs,
+      success: res => {
+        console.log('getTempFileURL结果', res.fileList);
+        this.setData({
+          homepage_7: res.fileList[0].tempFileURL,
+          homepage_6: res.fileList[1].tempFileURL,
+          homepage_5: res.fileList[2].tempFileURL,
+        });
+      },
+      fail: err => {
+        console.error('getTempFileURL失败', err);
+      }
+    });
     
     // 并发下载多个 fileID
-    Promise.all(
-      fileIDs.map(fileID => wx.cloud.downloadFile({ fileID }))
-    ).then(results => {
-      // 每个 result 对应一个下载结果
-      const tempFilePaths = results.map(r => r.tempFilePath);
-      console.log('全部下载成功:', tempFilePaths);
-      this.setData({
-        // carousellist: tempFilePaths.slice(0, 2),
-        homepage_7: tempFilePaths[0],
-        homepage_6: tempFilePaths[1],
-        homepage_5: tempFilePaths[2],
-      });
-    }).catch(err => {
-      console.error('有文件下载失败:', err);
-    });
+    // Promise.all(
+    //   fileIDs.map(fileID => wx.cloud.downloadFile({ fileID }))
+    // ).then(results => {
+    //   // 每个 result 对应一个下载结果
+    //   const tempFilePaths = results.map(r => r.tempFilePath);
+    //   console.log('全部下载成功:', tempFilePaths);
+    //   this.setData({
+    //     // carousellist: tempFilePaths.slice(0, 2),
+    //     homepage_7: tempFilePaths[0],
+    //     homepage_6: tempFilePaths[1],
+    //     homepage_5: tempFilePaths[2],
+    //   });
+    // }).catch(err => {
+    //   console.error('有文件下载失败:', err);
+    // });
   },
 
   // 轮播数据

+ 6 - 6
subpackagestow/course/course.js

@@ -40,10 +40,10 @@ Page({
 
     // 获取图片
     const fileIDs = [
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/sou.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/show_1.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/xiazi.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/goods/goods_9.jpg'
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/sou.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/show_1.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/xiazi.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/goods/goods_9.jpg'
     ];
     
     // 并发下载多个 fileID
@@ -192,10 +192,10 @@ Page({
     //       range: ['大班'],  // 适用范围
     //       remark: "备注文本字段",  // 备注
     //       type: 3,  // 文件类型  0-视频 1-音频 2-pdf 3-ppt 4-图文
-    //       url: ['cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/newfile.ppt'],  // 路径
+    //       url: ['cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/newfile.ppt'],  // 路径
     //       download_count: 1,  // 下载人数
     //       dan: 0,  // 段位
-    //       cover: "cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/未命名的设计.png",  // 封面
+    //       cover: "cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/未命名的设计.png",  // 封面
     //       size: "123.12KB",  // 文件大小
     //       name: "亲子共读角1-ppt",  // 文件名
     //       tag_id: "BT6R8VECJU",  // 标签id

+ 1 - 1
subpackagestow/course/course.wxss

@@ -165,7 +165,7 @@
 }
 
 .download-icons {
-  width: 45rpx;
+  width: 40rpx;
   height: 40rpx;
   margin-right: 20rpx;
 }

+ 73 - 54
subpackagestow/details/details.js

@@ -1,5 +1,5 @@
 // subpackagestow/details/details.js
-import { models, db, _ } from '../../utils/cloudbase.js'
+import { models, db, _, client } from '../../utils/cloudbase.js'
 Page({
 
   /**
@@ -24,10 +24,14 @@ Page({
     // 获取传递过来的数据
     const itemStr = decodeURIComponent(options.item);
     const item = JSON.parse(itemStr);
+    // 格式化时间
+    item.createdAtText = this.formatTime(item.createdAt);
     // 设置到页面数据中
     this.setData({
       itemlist: item
     }, () => {
+    // 相关推荐
+    this.getcourseList()
       // 转换云文件ID为临时链接
     if (item.url && item.url.length > 0) {
       wx.cloud.getTempFileURL({
@@ -47,19 +51,17 @@ Page({
 
       // 收藏
       this.getcollect()
-      // 相关推荐
-      this.getcourseList()
       // 加访问量
       this.getvisits()
     });
     
     // 获取图片
     const fileIDs = [
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/shouchang.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/show_1.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/xiazi.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/xia_1.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/shoucang_s.png'
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/shouchang.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/show_1.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/xiazi.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/xia_1.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/shoucang_s.png'
     ];
     // 并发下载多个 fileID
     Promise.all(
@@ -80,27 +82,37 @@ Page({
     });
   },
 
+  formatTime(ts) {
+    const date = new Date(ts);
+    const y = date.getFullYear();
+    const m = String(date.getMonth() + 1).padStart(2, '0');
+    const d = String(date.getDate()).padStart(2, '0');
+    const hh = String(date.getHours()).padStart(2, '0');
+    const mm = String(date.getMinutes()).padStart(2, '0');
+    const ss = String(date.getSeconds()).padStart(2, '0');
+    return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
+  },
+
   // 相关课件推荐
   async getcourseList() {
-    console.log(this.data.itemlist.rangee, 'this.data.itemlist.range');
-    const { data } = await models.file_manage.list({
-      filter: {
-        where: {
-          rangee: _.in(this.data.itemlist.rangee),
-          tag_id: this.data.itemlist.tag_id
-        }
+    const result  = await client.callFunction({
+      name: "database",   // 云函数部署名
+      data: {
+        page: "recommende",
+        action: "findFileRangee",
+        data: {
+          _id: this.data.itemlist._id,
+          range: this.data.itemlist.range,
+          tag_id: this.data.itemlist.tag_id,
+          pageSize: 20,
+          pageNum: 1,
+        },
       },
-      pageSize: 20, // 分页大小,建议指定,如需设置为其它值,需要和 pageNumber 配合使用,两者同时指定才会生效
-      pageNumber: 1, // 第几页
-      getCount: true, // 开启用来获取总数
-      // envType: pre 体验环境, prod 正式环境
-      envType: "prod",
     });
     
-    // 返回查询到的数据列表 records 和 总数 total
-    console.log(data, 'data');
+    console.log(result, 'data++++++---------------');
     this.setData({
-      courseList: data.records
+      courseList: result.result.records
     })
   },
 
@@ -194,39 +206,46 @@ Page({
 
   // 预览
   previewPDF() {
-    wx.cloud.downloadFile({
-      fileID: this.data.itemlist.url[0],
+    const cloudUrl = this.data.itemlist.url[0];
+    if (!cloudUrl) return;
+  
+    wx.cloud.getTempFileURL({
+      fileList: [cloudUrl],
       success: res => {
-        const filePath = res.tempFilePath;
-        const extension = filePath.substring(filePath.lastIndexOf('.') + 1).toLowerCase();
-        console.log('文件后缀:', extension);
-        // 根据文件类型处理
-        if (['pdf', 'ppt', 'pptx'].includes(extension)) {
-          wx.openDocument({
-            filePath: filePath,
-            fileType: extension,
-            success: () => {
-              console.log('文档打开成功');
-            },
-            fail: err => {
-              console.error('文档打开失败', err);
-            }
-          });
-        } else if (['mp3', 'aac', 'wav'].includes(extension)) {
-          console.log('这是一个音频文件,可以跳转到播放页面或使用音频组件');
-          this.toggleAudio()
-        } else if (['mp4', 'mov'].includes(extension)) {
-          console.log('这是一个视频文件,可以跳转到视频播放页');
-          this.toggleVideo()
-        } else {
-          wx.showToast({
-            title: '暂不支持该文件类型预览',
-            icon: 'none'
-          });
+        if (res.fileList && res.fileList.length > 0) {
+          const tempUrl = res.fileList[0].tempFileURL;
+          const extension = tempUrl.substring(tempUrl.lastIndexOf('.') + 1).toLowerCase();
+  
+          if (['pdf', 'ppt', 'pptx'].includes(extension)) {
+            // 先下载到本地
+            wx.downloadFile({
+              url: tempUrl,
+              success: dlRes => {
+                wx.openDocument({
+                  filePath: dlRes.tempFilePath,
+                  fileType: extension,
+                  success: () => console.log('文档打开成功'),
+                  fail: err => console.error('文档打开失败', err)
+                });
+              },
+              fail: err => {
+                wx.showToast({ title: '下载文件失败', icon: 'none' });
+                console.error('下载文件失败', err);
+              }
+            });
+          } else if (['mp3', 'aac', 'wav'].includes(extension)) {
+            this._playAudio(tempUrl);
+          } else if (['mp4', 'mov'].includes(extension)) {
+            this.setData({ 'itemlist.playUrl': tempUrl });
+            this.toggleVideo();
+          } else {
+            wx.showToast({ title: '暂不支持该文件类型预览', icon: 'none' });
+          }
         }
       },
       fail: err => {
-        console.error('文件下载失败', err);
+        wx.showToast({ title: '获取播放链接失败', icon: 'none' });
+        console.error('获取临时链接失败', err);
       }
     });
   },
@@ -321,7 +340,7 @@ Page({
       filter: {
         where: {
           school_id: schoolId,
-          user_id: userId,
+          // user_id: userId,
           file_id: fileId
         }
       },
@@ -362,7 +381,7 @@ Page({
           visits: 1,
           download: 1,
           school_id: schoolId,
-          user_id: userId,
+          // user_id: userId,
           file_id: fileId,
         },
         envType: "prod",

+ 3 - 3
subpackagestow/details/details.wxml

@@ -2,7 +2,7 @@
   <view class="container">
     <view class="header">
       <text>{{ itemlist.name }}</text>
-      <text>{{itemlist.publisher}} • {{ itemlist.createdAt }}</text>
+      <text>{{itemlist.publisher}} • {{ itemlist.createdAtText }}</text>
       <text>{{itemlist.type === 0 ? '视频' : itemlist.type === 1 ? '音频' : itemlist.type === 2 ? 'PDF' : itemlist.type === 3 ? 'PPT' : '图文'}} 适用于 {{ itemlist.range }}</text>
     </view>
     <!-- 预览 -->
@@ -34,7 +34,7 @@
         在线预览
       </button>
       <button bindtap="goTocollect" data-item="{{itemlist}}"  class="preview-btns shoucang {{isCollected ? 'active' : ''}}">
-        <image wx:if="{{isCollected}}" class="download-iconss" src="{{shouchangs}}" />
+        <image wx:if="{{isCollected}}" class="download-iconss2" src="{{shouchangs}}" />
         <image wx:else class="download-iconss" src="{{shouchang}}" />
         收藏
       </button>
@@ -56,7 +56,7 @@
             <view class="item-title">{{item.name}}</view>
             <view style="display: flex; justify-content: space-between;">
               <view class="item-subtitle">
-                {{item.describe}}
+                {{item.range}}
               </view>
               <view class="item-download-count">
                已有{{item.download_count}}人下载

+ 12 - 3
subpackagestow/details/details.wxss

@@ -77,15 +77,16 @@ video, audio {
 }
 
 .preview-btns, .download-btn {
-  /* background-color: #409eff; */
-  /* color: white; */
   border: none;
   padding: 15rpx 0 !important;
   border-radius: 40rpx;
   width: 30% !important;
-  height: 70rpx;
+  /* height: 70rpx; */
   font-size: 28rpx;
   font-weight: 500;
+  display: flex;
+  justify-content: center;
+  align-content: center;
 }
 
 .yulan {
@@ -292,9 +293,17 @@ video, audio {
 }
 
 .download-iconss {
+  width: 35rpx;
+  height: 35rpx;
+  margin-right: 15rpx;
+  margin-top: 0.5rpx;
+}
+
+.download-iconss2 {
   width: 30rpx;
   height: 30rpx;
   margin-right: 15rpx;
+  margin-top: 3rpx;
 }
 
 .active {

+ 20 - 4
subpackagestow/down/down.js

@@ -44,7 +44,7 @@ Page({
     });
 
     const fileIDs = [
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/fuzhi.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/fuzhi.png',
     ];
     
     // 并发下载多个 fileID
@@ -140,6 +140,7 @@ Page({
   // 下载
   handleDownloadFile() {
     const url = this.data.itemtempFileURL;
+    console.log(url);
     if (!url) {
       wx.showToast({
         title: '文件链接不存在',
@@ -157,7 +158,8 @@ Page({
       url: url,
       success: (res) => {
         wx.hideLoading();
-  
+
+        console.log('进来了++++++++');
         if (res.statusCode === 200) {
           const tempFilePath = res.tempFilePath;
           const fileExt = url.split('.').pop().toLowerCase();
@@ -282,12 +284,26 @@ Page({
     const schoolId = userInfo && userInfo.school_id ? userInfo.school_id : '';
     const fileId = this.data.itemlist._id;
 
+    const res = await models.download_history.create({
+      data: {
+          user_id: userId,  // 用户id
+          delete: 0,  // 逻辑删除
+          file_manage_id: fileId,  // 课件id
+        },
+      // envType: pre 体验环境, prod 正式环境
+      envType: "prod",
+    });
+    
+    // 返回创建的数据 id
+    console.log(res, '++++++++++++++++++++++++++++++');
+    // { count: 1}
+
     // 先查是否存在
     const { data } = await models.microcode.list({
       filter: {
         where: {
           school_id: schoolId,
-          user_id: userId,
+          // user_id: userId,
           file_id: fileId
         }
       },
@@ -328,7 +344,7 @@ Page({
           visits: 1,
           download: 1,
           school_id: schoolId,
-          user_id: userId,
+          // user_id: userId,
           file_id: fileId,
         },
         envType: "prod",

+ 3 - 8
subpackagestow/show/show.js

@@ -33,14 +33,9 @@ Page({
     this.getTabdata();
 
     const fileIDs = [
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/sou.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/show_1.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/xiazi.png',
-      // 'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/123123.mp4',
-      // 'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/硬盘发票.pdf',
-      // 'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/newfile.ppt',
-      // 'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/许嵩 - 有何不可.mp3',
-      // 'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/banner/carousel_1.jpg'
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/sou.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/show_1.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/xiazi.png',
     ];
     
     // 并发下载多个 fileID

+ 1 - 1
subpackagestow/show/show.wxss

@@ -208,7 +208,7 @@
 }
 
 .download-icons {
-  width: 45rpx;
+  width: 40rpx;
   height: 40rpx;
   margin-right: 20rpx;
 }

+ 3 - 3
subpackagestow/teaching/teaching.js

@@ -28,9 +28,9 @@ Page({
     this.getTabdata();
 
     const fileIDs = [
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/sou.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/show_1.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/xiazi.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/sou.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/show_1.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/xiazi.png',
     ];
     
     // 并发下载多个 fileID

+ 1 - 1
subpackagestow/teaching/teaching.wxss

@@ -243,7 +243,7 @@
 }
 
 .download-icons {
-  width: 45rpx;
+  width: 40rpx;
   height: 40rpx;
   margin-right: 20rpx;
 }

+ 3 - 3
subpackagestow/training/training.js

@@ -28,9 +28,9 @@ Page({
     this.getTabdata();
 
     const fileIDs = [
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/sou.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/show_1.png',
-      'cloud://cloud1-6g98iw7i28b01747.636c-cloud1-6g98iw7i28b01747-1367995226/images/icon/xiazi.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/sou.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/show_1.png',
+      'cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/images/icon/xiazi.png',
     ];
     
     // 并发下载多个 fileID

+ 1 - 1
subpackagestow/training/training.wxss

@@ -244,7 +244,7 @@
 }
 
 .download-icons {
-  width: 45rpx;
+  width: 40rpx;
   height: 40rpx;
   margin-right: 20rpx;
 }

+ 19 - 4
utils/cloudbase.js

@@ -1,14 +1,29 @@
-// utils/cloudbase.js
+// // utils/cloudbase.js
+// import { init } from '@cloudbase/wx-cloud-client-sdk'
+
+// wx.cloud.init({
+//   env: 'cloud1-6g98iw7i28b01747',
+//   traceUser: true
+// })
+
+// const client = init(wx.cloud)
+// const db = client.database()
+// const models = client.models
+// const _ = db.command // ✅ 添加这行,导出查询操作符
+
+// export { db, models, _ }
+
 import { init } from '@cloudbase/wx-cloud-client-sdk'
 
+// 初始化小程序 SDK
 wx.cloud.init({
-  env: 'cloud1-6g98iw7i28b01747',
+  env: 'honghgaier-5guiffgcf17a2eea',
   traceUser: true
 })
 
 const client = init(wx.cloud)
 const db = client.database()
 const models = client.models
-const _ = db.command // ✅ 添加这行,导出查询操作符
+const _ = db.command
 
-export { db, models, _ }
+export { db, models, _, client }