[
  {
    "path": ".gitignore",
    "content": "# Windows\n[Dd]esktop.ini\nThumbs.db\n$RECYCLE.BIN/\n\n# macOS\n.DS_Store\n.fseventsd\n.Spotlight-V100\n.TemporaryItems\n.Trashes\n\n# Node.js\nnode_modules/\n"
  },
  {
    "path": "README.md",
    "content": "## 功能 介绍 \n\n 旅游景区门户小程序是一个为游客朋友提供多元化服务的一站式数字文旅平台，提供“吃、住、游、购、娱”等旅游行程中的多种服务，全面支持景区介绍，景点攻略，景点预约，停车预约、景区导览等功能，游客可以在小程序中了解旅游度假区的景点信息、历史文化、各类活动等。前后端代码完整，采用腾讯提供的小程序云开发解决方案，无须服务器和域名。\n \n- 景点预约管理：开始/截止时间/人数均可灵活设置，可以自定义客户预约填写的数据项\n- 景点预约凭证：支持线下到场后校验签到/核销/二维码自助签到等多种方式\n- 详尽的预约数据：支持预约名单数据导出Excel，打印\n\n![image](https://user-images.githubusercontent.com/96864248/189519239-7707dfcc-5fe8-4ad1-9e07-e7bf73adb076.png)\n![image](https://user-images.githubusercontent.com/96864248/189519246-c5b61c34-958b-473a-b9ac-c3a2ff08fdb1.png)\n\n\n\n## 技术运用\n- 本项目使用微信小程序平台进行开发。\n- 使用腾讯专门的小程序云开发技术，云资源包含云函数，数据库，带宽，存储空间，定时器等，资源配额价格低廉，无需域名和服务器即可搭建。\n- 小程序本身的即用即走，适合小工具的使用场景，也适合快速开发迭代。\n- 云开发技术采用腾讯内部链路，没有被黑客攻击的风险，安全性高且免维护。\n- 资源承载力可根据业务发展需要随时弹性扩展。  \n\n\n\n## 作者\n- 如有疑问，欢迎骚扰联系我：开发交流，技术分享，问题答疑，功能建议收集，版本更新通知，安装部署协助，小程序开发定制等。\n- 俺的微信: \n ![image](https://user-images.githubusercontent.com/96864248/189519251-86ee2260-a55d-4158-b3ce-06c170f1ece4.png)\n\n\n\n\n## 演示 \n ![image](https://user-images.githubusercontent.com/96864248/189519248-5532edd2-e763-40d6-9fea-c69edca87287.png)\n\n\n## 安装\n\n- 安装手册见源码包里的word文档\n\n![image](https://user-images.githubusercontent.com/96864248/189519252-b69954c6-caf5-4800-9800-d4251ffa4011.png)\n![image](https://user-images.githubusercontent.com/96864248/189519255-c82f58e7-f790-4f42-8ea2-9d44ecfcacc4.png)\n![image](https://user-images.githubusercontent.com/96864248/189519258-0f46606e-35e2-4b4b-8760-1497419eac10.png)\n![image](https://user-images.githubusercontent.com/96864248/189519261-db1daaa2-1433-4b65-b3c6-efabb62bf047.png)\n![image](https://user-images.githubusercontent.com/96864248/189519265-24fd846c-466d-4257-b9c5-f5d0b4d00687.png)\n![image](https://user-images.githubusercontent.com/96864248/189519268-784bd0f0-009e-446b-81ce-a6b83cf9bcff.png)\n![image](https://user-images.githubusercontent.com/96864248/189519271-6e2a223e-8d88-43f8-aa30-eb2bc056274a.png)\n\n![image](https://user-images.githubusercontent.com/96864248/189519273-4aa22512-69bc-4a02-9b35-59e2be029aa9.png)\n![image](https://user-images.githubusercontent.com/96864248/189519278-64310e7e-321f-4f36-8a35-5918de0583fc.png)\n![image](https://user-images.githubusercontent.com/96864248/189519281-da759fef-9404-402d-8ae8-0e8ef1cd4706.png)\n\n\n## 截图\n \n\n## 后台管理系统截图 \n- 后台超级管理员默认账号:admin，密码123456，请登录后台后及时修改密码和创建普通管理员。\n\n![image](https://user-images.githubusercontent.com/96864248/189519285-09317ce4-779a-4ffb-a26d-bfe9e947ffd4.png)\n\n![image](https://user-images.githubusercontent.com/96864248/189519287-b4f08489-abe7-4395-84dd-0de6060d065b.png)\n![image](https://user-images.githubusercontent.com/96864248/189519290-56b56e45-ac29-48b7-b3ab-2de853657f97.png)\n![image](https://user-images.githubusercontent.com/96864248/189519293-dd9164cc-3235-42e0-98d9-aabbf0bafa99.png)\n![image](https://user-images.githubusercontent.com/96864248/189519296-a6255dd9-80b0-4091-a08a-ec1ded16c2dd.png)\n\n![image](https://user-images.githubusercontent.com/96864248/189519299-50e99c08-21e5-4587-ab3e-86feade044c3.png)\n![image](https://user-images.githubusercontent.com/96864248/189519302-5ed8d472-8a6e-4b41-9b24-24ae94280d54.png)\n\n\n\n"
  },
  {
    "path": "cloudfunctions/mcloud/config/config.js",
    "content": "module.exports = {\n\n\t//### 环境相关 \n\tCLOUD_ID: 'init-5go8b8pdc98ea814', //你的云环境id   \n\n\t// ##################################################################   \n\tCOLLECTION_PRFIX: 'bx_',\n\n\tIS_DEMO: false, //是否演示版 (后台不可操作提交动作)  \n\t// ##################################################################\n\t// #### 调试相关 \n\tTEST_MODE: false, // 测试模式 涉及小程序码生成路径， 用以下 TEST_TOKEN_ID openid.. \n\tTEST_TOKEN_ID: 'oD58U5Ej-gK0BjqSspqjQEPgXuQQ',\n \n\n\t// #### 内容安全\n\tCLIENT_CHECK_CONTENT: false, //前台图片文字是否校验\n\tADMIN_CHECK_CONTENT: false, //后台图片文字是否校验     \n\n\t// ### 后台业务相关\n\tADMIN_LOGIN_EXPIRE: 86400, //管理员token过期时间 (秒) \n}"
  },
  {
    "path": "cloudfunctions/mcloud/config.json",
    "content": "{\n\t\"permissions\": {\n\t\t\"openapi\": [\"wxacode.getUnlimited\", \"security.imgSecCheck\", \"security.msgSecCheck\",\"serviceMarket.invokeService\"]\n\t}\n}"
  },
  {
    "path": "cloudfunctions/mcloud/framework/cloud/cloud_base.js",
    "content": "/**\n * Notes: 云初始化实例\n * Ver : CCMiniCloud Framework 2.2.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-09-05 04:00:00 \n */\n\nconst config = require('../../config/config.js');\n\n/**\n * 获得云实例\n */\nfunction getCloud() {\n\tconst cloud = require('wx-server-sdk');\n\tcloud.init({\n\t\tenv: config.CLOUD_ID\n\t});\n\treturn cloud;\n}\n\nmodule.exports = {\n\tgetCloud\n}"
  },
  {
    "path": "cloudfunctions/mcloud/framework/cloud/cloud_util.js",
    "content": "/**\n * Notes: 云基本操作模块\n * Ver : CCMiniCloud Framework 2.3.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-09-05 04:00:00 \n */\nconst cloudBase = require('./cloud_base.js');\n\nfunction log(method, err, level = 'error') {\n\tconst cloud = cloudBase.getCloud();\n\tconst log = cloud.logger();\n\tlog.error({\n\t\tmethod: method,\n\t\terrCode: err.code,\n\t\terrMsg: err.message,\n\t\terrStack: err.stack\n\t});\n}\n\nasync function getTempFileURLOne(fileID) {\n\tif (!fileID) return '';\n\n\tconst cloud = cloudBase.getCloud();\n\tlet result = await cloud.getTempFileURL({\n\t\tfileList: [fileID],\n\t})\n\tif (result && result.fileList && result.fileList[0] && result.fileList[0].tempFileURL)\n\t\treturn result.fileList[0].tempFileURL;\n\treturn '';\n}\n\nasync function getTempFileURL(tempFileList, isValid = false) {\n\tif (!tempFileList || tempFileList.length == 0) return [];\n\n\tconst cloud = cloudBase.getCloud();\n\tlet result = await cloud.getTempFileURL({\n\t\tfileList: tempFileList,\n\t})\n\tconsole.log(result);\n\n\tlet list = result.fileList;\n\tlet outList = [];\n\tfor (let i = 0; i < list.length; i++) {\n\t\tlet pic = {};\n\t\tif (list[i].status == 0) {\n\t\t\t//获取到地址的\n\t\t\tpic.url = list[i].tempFileURL;\n\t\t\tpic.cloudId = list[i].fileID;\n\t\t\toutList.push(pic)\n\t\t} else {\n\t\t\t//未获取到地址的（已经转换过的)\n\t\t\tif (!isValid) {\n\t\t\t\tpic.url = list[i].fileID; // fileID为URL, tempFileURL为空\n\t\t\t\tpic.cloudId = list[i].fileID;\n\t\t\t\toutList.push(pic)\n\t\t\t}\n\t\t}\n\t}\n\treturn outList;\n}\n\nasync function handlerCloudFilesForForms(oldForms, newsForms) {\n\tlet oldFiles = [];\n\tlet newFiles = [];\n\n\tfor (let k = 0; k < oldForms.length; k++) {\n\t\tif (oldForms[k].type == 'image')\n\t\t\toldFiles = oldFiles.concat(oldForms[k].val);\n\t\telse if (oldForms[k].type == 'content') {\n\t\t\tlet contentVal = oldForms[k].val;\n\t\t\tfor (let n in contentVal) {\n\t\t\t\tif (contentVal[n].type == 'img')\n\t\t\t\t\toldFiles.push(contentVal[n].val);\n\t\t\t}\n\n\t\t}\n\t}\n\n\tfor (let j in newsForms) {\n\t\tif (newsForms[j].type == 'image')\n\t\t\tnewFiles = newFiles.concat(newsForms[j].val);\n\t\telse if (newsForms[j].type == 'content') {\n\t\t\tlet contentVal = newsForms[j].val;\n\t\t\tfor (let m in contentVal) {\n\t\t\t\tif (contentVal[m].type == 'img')\n\t\t\t\t\tnewFiles.push(contentVal[m].val);\n\t\t\t}\n\n\t\t}\n\t}\n\n\tawait handlerCloudFiles(oldFiles, newFiles);\n}\n\nasync function handlerCloudFiles(oldFiles, newFiles) {\n\t//if (oldFiles.length == 0 && newFiles.length == 0) return [];\n\n\tconst cloud = cloudBase.getCloud();\n\tfor (let i = 0; i < oldFiles.length; i++) {\n\t\tlet isDel = true;\n\t\tfor (let j = 0; j < newFiles.length; j++) {\n\t\t\tif (oldFiles[i] == newFiles[j]) {\n\t\t\t\t// 从旧文件数组里 找到 新组 还存在的文件 ，则不删除\n\t\t\t\tisDel = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t// 新组里不存在，直接删除\n\t\tif (isDel && oldFiles[i]) {\n\t\t\tlet result = await cloud.deleteFile({\n\t\t\t\tfileList: [oldFiles[i]],\n\t\t\t});\n\t\t\tconsole.log(result);\n\t\t}\n\n\t}\n\n\treturn newFiles;\n}\n\n\nasync function handlerCloudFilesByRichEditor(oldFiles, newFiles) {\n\tconst cloud = cloudBase.getCloud();\n\tfor (let i = 0; i < oldFiles.length; i++) {\n\t\tlet isDel = true;\n\t\tfor (let j = 0; j < newFiles.length; j++) {\n\t\t\tif (oldFiles[i].type == 'img' && newFiles[j].type == 'img' && oldFiles[i].val == newFiles[j].val) {\n\t\t\t\t// 从旧文件数组里 找到 新组 还存在的图片文件, 保存cloudID\n\t\t\t\t//newFiles[j].cloudId = oldFiles[i].cloudId;\n\t\t\t\tisDel = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t// 新组里不存在，直接删除\n\t\tif (isDel && oldFiles[i].type == 'img' && oldFiles[i].val) {\n\n\t\t\tlet result = await cloud.deleteFile({\n\t\t\t\tfileList: [oldFiles[i].val],\n\t\t\t});\n\t\t}\n\n\t}\n\n\treturn newFiles;\n}\n\nasync function deleteFiles(list) {\n\tif (!list) return;\n\tif (!Array.isArray(list)) list = [list];\n\tif (list.length == 0) return;\n\n\tconst cloud = cloudBase.getCloud();\n\tawait cloud.deleteFile({\n\t\tfileList: list,\n\t});\n}\n\nmodule.exports = {\n\tlog,\n\tgetTempFileURL,\n\tgetTempFileURLOne,\n\tdeleteFiles,\n\thandlerCloudFiles,\n\thandlerCloudFilesByRichEditor,\n\thandlerCloudFilesForForms\n}"
  },
  {
    "path": "cloudfunctions/mcloud/framework/core/app_code.js",
    "content": "/**\n * Notes: 错误代码定义\n * Ver : CCMiniCloud Framework 2.4.1 ALL RIGHTS RESERVED BY Cclinux0730 (wechat)\n * Date: 2020-09-05 04:00:00 \n */\nmodule.exports = {\n\tSUCC: 200,\n\tSVR: 500, // 服务器错误  \n\tLOGIC: 1600, //逻辑错误 \n\tDATA: 1301, // 数据校验错误 \n\tHEADER: 1302, // header 校验错误  \n\n\n\t//2000开始为业务错误代码，\n\n\tADMIN_ERROR: 2401 //管理员错误\n}"
  },
  {
    "path": "cloudfunctions/mcloud/framework/core/app_error.js",
    "content": "/**\n * Notes: 应用异常处理类\n * Ver : CCMiniCloud Framework 2.5.1 ALL RIGHTS RESERVED BY cClinux0730 (wechat)\n * Date: 2020-09-05 04:00:00 \n */\n\n\nconst appCode = require('./app_code.js');\n\nclass AppError extends Error {\n    constructor(message, code = appCode.LOGIC) {\n      super(message);  \n\t  this.name = 'AppError';  \n\t  this.code = code;\n    }\n  }\n\n  module.exports = AppError;"
  },
  {
    "path": "cloudfunctions/mcloud/framework/core/app_other.js",
    "content": "/**\n * Notes: 云函数非标业务处理\n * Ver : CCMiniCloud Framework 2.6.1 ALL RIGHTS RESERVED BY ccLinux@qq.com\n * Date: 2021-10-21 04:00:00 \n */\n\nfunction handlerOther(event) {\n\tlet isOther = false;\n\n\tif (!event) return {\n\t\tisOther,\n\t\teventX\n\t};\n\n\t// 公众号事件处理\n\tif (event['FromUserName'] && event['MsgType']) {\n\t\tconsole.log('公众号事件处理');\n\t\tlet ret = {\n\t\t\troute: 'oa/serve',\n\t\t\tparams: event\n\t\t}\n\t\treturn {\n\t\t\tisOther: true,\n\t\t\teventX: ret\n\t\t};\n\t}\n\n\treturn {\n\t\tisOther,\n\t\teventX: event\n\t};\n}\n\n\nmodule.exports = {\n\thandlerOther,\n}"
  },
  {
    "path": "cloudfunctions/mcloud/framework/core/app_util.js",
    "content": "/**\n * Notes: 云函数业务主逻辑函数\n * Ver : CCMiniCloud Framework 2.7.1 ALL RIGHTS RESERVED BY cclinuX0730 (wechat)\n * Date: 2021-02-09 04:00:00 \n */\n\nconst appCode = require('./app_code.js');\n\nfunction handlerBasic(code, msg = '', data = {}) {\n\n\tswitch (code) {\n\t\tcase appCode.SUCC:\n\t\t\tmsg = (msg) ? msg + ':ok' : 'ok';\n\t\t\tbreak;\n\t\tcase appCode.SVR:\n\t\t\tmsg = '服务器繁忙，请稍后再试';\n\t\t\tbreak;\n\t\tcase appCode.LOGIC:\n\t\t\tbreak;\n\t\tcase appCode.DATA:\n\t\t\tbreak;\n\n\t\t\t/*\n\t\t\tdefault:\n\t\t\t\tmsg = '服务器开小差了，请稍后再试';\n\t\t\t\tbreak;*/\n\t}\n\n\treturn {\n\t\tcode: code,\n\t\tmsg: msg,\n\t\tdata: data\n\t}\n\n}\n\nfunction handlerSvrErr(msg = '') {\n\treturn handlerBasic(appCode.SVR, msg);\n}\n\nfunction handlerSucc(msg = '') {\n\treturn handlerBasic(appCode.SUCC, msg);\n}\n\nfunction handlerAppErr(msg = '', code = appCode.LOGIC) {\n\treturn handlerBasic(code, msg);\n}\n\n\nfunction handlerData(data, msg = '') {\n\treturn handlerBasic(appCode.SUCC, msg, data);\n}\n\nmodule.exports = {\n\thandlerBasic,\n\thandlerData,\n\thandlerSucc,\n\thandlerSvrErr,\n\thandlerAppErr\n}"
  },
  {
    "path": "cloudfunctions/mcloud/framework/core/application.js",
    "content": "/**\n * Notes: 云函数业务主逻辑\n * Ver : CCMiniCloud Framework 2.8.1 ALL RIGHTS RESERVED BY cclinUX0730 (wechat)\n * Date: 2020-09-05 04:00:00 \n */\nconst util = require('../utils/util.js');\nconst cloudBase = require('../cloud/cloud_base.js');\nconst timeUtil = require('../utils/time_util.js');\nconst appUtil = require('./app_util.js');\nconst appCode = require('./app_code.js');\nconst appOther = require('./app_other.js');\nconst config = require('../../config/config.js');\nglobal.PID = 'unknown';\n\nasync function app(event, context) {\n\n\t// 非标业务处理\n\tlet {\n\t\teventX,\n\t\tisOther\n\t} = appOther.handlerOther(event);\n\tevent = eventX;\n\n\t// 取得openid\n\tconst cloud = cloudBase.getCloud();\n\tconst wxContext = cloud.getWXContext();\n\tlet r = '';\n\tlet PID = '';\n\ttry {\n\n\t\tif (!util.isDefined(event.route)) {\n\t\t\tshowEvent(event);\n\t\t\tconsole.error('Route Not Defined');\n\t\t\treturn appUtil.handlerSvrErr();\n\t\t}\n\n\t\tr = event.route.toLowerCase();\n\t\tif (!r.includes('/')) {\n\t\t\tshowEvent(event);\n\t\t\tconsole.error('Route Format error[' + r + ']');\n\t\t\treturn appUtil.handlerSvrErr();\n\t\t}\n\n\t\tPID = event.PID.trim();\n\t\tif (!PID) {\n\t\t\tshowEvent(event);\n\t\t\tconsole.error('PID Is NULL]');\n\t\t\treturn appUtil.handlerSvrErr();\n\t\t}\n\t\tglobal.PID = PID;\n\n\t\t// 路由不存在\n\t\troutes = require('project/' + PID + '/public/route.js');\n\t\tif (!util.isDefined(routes[r])) {\n\t\t\tshowEvent(event);\n\t\t\tconsole.error('Route [' + r + '] Is Not Exist');\n\t\t\treturn appUtil.handlerSvrErr();\n\t\t}\n\n\t\tlet routesArr = routes[r].split('@');\n\n\t\tlet controllerName = routesArr[0];\n\t\tlet actionName = routesArr[1];\n\n\t\t// 事前处理\n\t\tif (actionName.includes('#')) {\n\t\t\tlet actionNameArr = actionName.split('#');\n\t\t\tactionName = actionNameArr[0];\n\t\t\tif (actionNameArr[1] && config.IS_DEMO) {\n\t\t\t\tconsole.log('### APP Before = ' + actionNameArr[1]);\n\t\t\t\treturn beforeApp(actionNameArr[1]);\n\t\t\t}\n\t\t}\n\n\t\tconsole.log('');\n\t\tconsole.log('');\n\t\tlet time = timeUtil.time('Y-M-D h:m:s');\n\t\tlet timeTicks = timeUtil.time();\n\t\tlet openId = wxContext.OPENID;\n\n\t\tconsole.log('▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤');\n\t\tconsole.log(`【↘${time} ENV (${config.CLOUD_ID})】【Request Base↘↘↘】\\n【↘Route =***${r}】\\n【↘Controller = ${controllerName}】\\n【↘Action = ${actionName}】\\n【↘OPENID = ${openId}】\\n【↘PID = ${global.PID}】`);\n\n\t\t// 测试模式\n\t\tif (config.TEST_MODE)\n\t\t\topenId = config.TEST_TOKEN_ID; \n\n\t\tif (!openId) {\n\t\t\tconsole.error('OPENID is unfined');\n\t\t\treturn appUtil.handlerSvrErr();\n\t\t}\n\n\t\t// 引入逻辑controller \n\t\tcontrollerName = controllerName.toLowerCase().trim();\n\t\tconst ControllerClass = require('project/'+PID +'/controller/' + controllerName + '.js');\n\t\tconst controller = new ControllerClass(r, PID + '^^^' + openId, event);\n \n\t\t// 调用方法    \n\t\tawait controller['initSetup']();\n\t\tlet result = await controller[actionName]();\n\n\t\t// 返回值处理\n\t\tif (isOther) {\n\t\t\t// 非标处理\n\t\t\treturn result;\n\t\t} else {\n\t\t\tif (!result)\n\t\t\t\tresult = appUtil.handlerSucc(r); // 无数据返回\n\t\t\telse\n\t\t\t\tresult = appUtil.handlerData(result, r); // 有数据返回\n\t\t}\n\n\n\t\tconsole.log('------');\n\t\ttime = timeUtil.time('Y-M-D h:m:s');\n\t\ttimeTicks = timeUtil.time() - timeTicks;\n\t\tconsole.log(`【${time}】【Return Base↗↗↗】\\n【↗Route =***${r}】\\n【↗Duration = ${timeTicks}ms】\\n【↗↗OUT DATA】= `, result);\n\t\tconsole.log('▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦');\n\t\tconsole.log('');\n\t\tconsole.log('');\n\n\t\treturn result;\n\n\n\t} catch (ex) {\n\t\tconst log = cloud.logger();\n\n\t\tconsole.log('------');\n\t\ttime = timeUtil.time('Y-M-D h:m:s');\n\t\tconsole.error(`【${time}】【Return Base↗↗↗】\\n【↗Route = ${r}】\\Exception MSG = ${ex.message}, CODE=${ex.code}`);\n\n\t\t// 系统级错误定位调试\n\t\tif (config.TEST_MODE && ex.name != 'AppError') throw ex;\n\n\t\tconsole.log('▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦');\n\t\tconsole.log('');\n\t\tconsole.log('');\n\n\t\tif (ex.name == 'AppError') {\n\t\t\tlog.warn({\n\t\t\t\troute: r,\n\t\t\t\terrCode: ex.code,\n\t\t\t\terrMsg: ex.message\n\t\t\t});\n\t\t\t// 自定义error处理\n\t\t\treturn appUtil.handlerAppErr(ex.message, ex.code);\n\t\t} else {\n\t\t\t//console.log(ex); \n\t\t\tlog.error({\n\t\t\t\troute: r,\n\t\t\t\terrCode: ex.code,\n\t\t\t\terrMsg: ex.message,\n\t\t\t\terrStack: ex.stack\n\t\t\t});\n\n\n\t\t\t// 系统error\n\t\t\treturn appUtil.handlerSvrErr();\n\t\t}\n\t}\n}\n\n// 事前处理\nfunction beforeApp(method) {\n\tswitch (method) {\n\t\tcase 'demo': {\n\t\t\treturn appUtil.handlerAppErr('本系统仅为用户体验演示，后台提交的操作均不生效！如有需要请联系作者微信cclinux0730', appCode.LOGIC);\n\t\t}\n\t}\n\tconsole.error('事前处理, Method Not Find = ' + method);\n}\n\n// 展示当前输入数据\nfunction showEvent(event) {\n\tconsole.log(event);\n}\n\nmodule.exports = {\n\tapp\n}"
  },
  {
    "path": "cloudfunctions/mcloud/framework/database/db_util.js",
    "content": "/**\n * Notes: 数据库基本操作\n * Ver : CCMiniCloud Framework 2.9.1 ALL RIGHTS RESERVED BY CClinux0730 (wechat)\n * Date: 2020-09-05 04:00:00 \n */\n\nconst util = require('../utils/util.js');\nconst dataUtil = require('../utils/data_util.js');\n\nconst cloudBase = require('../cloud/cloud_base.js');\nconst MAX_RECORD_SIZE = 1000;\nconst DEFAULT_RECORD_SIZE = 20;\n\nconst cloud = cloudBase.getCloud();\nconst db = cloud.database();\nconst dbCmd = db.command;\nconst dbAggr = dbCmd.aggregate;\n\n\n// 获得一个命令操作\nfunction getCmd() {\n\treturn dbCmd;\n}\n\n\nasync function insertBatch(collectionName, data, size = 1000) {\n\n\tlet dataArr = dataUtil.spArr(data, size);\n\tfor (let k = 0; k < dataArr.length; k++) {\n\t\tawait db.collection(collectionName).add({\n\t\t\tdata: dataArr[k]\n\t\t});\n\t}\n\n\t//return query._id;\n}\n\nasync function insert(collectionName, data) {\n\n\tlet query = await db.collection(collectionName).add({\n\t\tdata\n\t});\n\treturn query._id;\n}\n\nasync function edit(collectionName, where, data) {\n\n\tlet query = await db.collection(collectionName);\n\n\t// 查询条件\n\tif (util.isDefined(where)) {\n\t\tif (typeof (where) == 'string' || typeof (where) == 'number')\n\t\t\tquery = await query.doc(where);\n\t\telse\n\t\t\tquery = await query.where(fmtWhere(where));\n\t}\n\n\tquery = await query.update({\n\t\tdata\n\t});\n\n\treturn query.stats.updated;\n}\n\nasync function inc(collectionName, where, field, val = 1) {\n\tlet query = await db.collection(collectionName);\n\n\t// 查询条件\n\tif (util.isDefined(where)) {\n\t\tif (typeof (where) == 'string' || typeof (where) == 'number')\n\t\t\tquery = await query.doc(where);\n\t\telse\n\t\t\tquery = await query.where(fmtWhere(where));\n\t}\n\n\tquery = await query.update({\n\t\tdata: {\n\t\t\t[field]: dbCmd.inc(val)\n\t\t}\n\t});\n\n\treturn query.stats.updated;\n}\n\nasync function mul(collectionName, where, field, val = 1) {\n\tlet query = await db.collection(collectionName);\n\n\t// 查询条件\n\tif (util.isDefined(where)) {\n\t\tif (typeof (where) == 'string' || typeof (where) == 'number')\n\t\t\tquery = await query.doc(where);\n\t\telse\n\t\t\tquery = await query.where(fmtWhere(where));\n\t}\n\n\tquery = await query.update({\n\t\tdata: {\n\t\t\t[field]: dbCmd.mul(val)\n\t\t}\n\t});\n\n\treturn query.stats.updated;\n}\n\nasync function del(collectionName, where) {\n\tlet query = await db.collection(collectionName);\n\n\t// 查询条件\n\tif (util.isDefined(where)) {\n\t\tif (typeof (where) == 'string' || typeof (where) == 'number')\n\t\t\tquery = await query.doc(where);\n\t\telse\n\t\t\tquery = await query.where(fmtWhere(where));\n\t}\n\n\tquery = await query.remove();\n\treturn query.stats.removed;\n}\n\nasync function count(collectionName, where) {\n\tlet query = await db.collection(collectionName);\n\n\t// 查询条件\n\tif (typeof (where) == 'string' || typeof (where) == 'number')\n\t\tquery = await query.doc(where);\n\telse\n\t\tquery = await query.where(fmtWhere(where));\n\n\tquery = await query.count();\n\treturn query.total;\n}\n\nasync function distinct(collectionName, where, field) {\n\tlet query = await db.collection(collectionName);\n\tquery = await query.aggregate();\n\n\t// 查询条件\n\tquery = await query.match(fmtWhere(where));\n\n\tquery = await query.group({\n\t\t_id: null,\n\t\t'uniqueValues': dbAggr.addToSet('$' + field)\n\n\t}).end();\n\n\tif (query && query.list && query.list[0] && query.list[0]['uniqueValues']) {\n\t\treturn query.list[0]['uniqueValues'];\n\t} else\n\t\treturn [];\n}\n\nasync function distinctCnt(collectionName, where, field) {\n\tlet data = await distinct(collectionName, where, field);\n\treturn data.length;\n}\n\nasync function groupSum(collectionName, where, groupField, fields) {\n\n\tlet query = await db.collection(collectionName);\n\tquery = await query.aggregate();\n\n\t// 查询条件\n\tquery = await query.match(fmtWhere(where));\n\n\tif (!Array.isArray(fields)) {\n\t\tfields = [fields];\n\t}\n\tlet node = {};\n\tfor (let k = 0; k < fields.length; k++) {\n\t\tnode[fields[k]] = dbAggr.sum('$' + fields[k]);\n\t}\n\n\tquery = await query.group({\n\t\t_id: {\n\t\t\t[groupField]: '$' + groupField\n\t\t},\n\t\t...node\n\n\t}).end();\n\n\tif (query && query.list) {\n\t\tlet list = query.list;\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tlist[k][groupField] = list[k]['_id'][groupField];\n\t\t\tdelete list[k]['_id'];\n\t\t}\n\t\treturn list;\n\t} else\n\t\treturn [];\n}\n\nasync function groupCount(collectionName, where, groupField) {\n\n\tlet query = await db.collection(collectionName);\n\tquery = await query.aggregate();\n\n\t// 查询条件\n\tquery = await query.match(fmtWhere(where));\n\n\tquery = await query.group({\n\t\t_id: '$' + groupField,\n\t\ttotal: dbAggr.sum(1)\n\n\t}).end();\n\n\tif (query && query.list) {\n\t\tlet list = query.list;\n\t\tlet ret = {};\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tret[groupField + '_' + list[k]['_id']] = list[k].total;\n\t\t}\n\t\treturn ret;\n\t} else\n\t\treturn null;\n}\n\nasync function sum(collectionName, where, field) {\n\t// TODO 可扩展为支持多个字段同时统计\n\tlet query = await db.collection(collectionName);\n\tquery = await query.aggregate();\n\n\t// 查询条件\n\tquery = await query.match(fmtWhere(where));\n\n\tquery = await query.group({\n\t\t_id: null,\n\t\t'summ': dbAggr.sum('$' + field)\n\n\t}).end();\n\n\tif (query && query.list && query.list[0] && query.list[0]['summ']) {\n\t\treturn query.list[0]['summ'];\n\t} else\n\t\treturn 0;\n}\n\nasync function max(collectionName, where, field) {\n\tlet query = await db.collection(collectionName);\n\tquery = await query.aggregate();\n\n\t// 查询条件\n\tquery = await query.match(fmtWhere(where));\n\n\tquery = await query.group({\n\t\t_id: null,\n\t\t'maxx': dbAggr.max('$' + field)\n\n\t}).end();\n\n\tif (query && query.list && query.list[0] && query.list[0]['maxx']) {\n\t\treturn query.list[0]['maxx'];\n\t} else\n\t\treturn 0;\n}\n\nasync function min(collectionName, where, field) {\n\tlet query = await db.collection(collectionName);\n\tquery = await query.aggregate();\n\n\t// 查询条件\n\tquery = await query.match(fmtWhere(where));\n\n\tquery = await query.group({\n\t\t_id: null,\n\t\t'minx': dbAggr.min('$' + field)\n\n\t}).end();\n\n\tif (query && query.list && query.list[0] && query.list[0]['minx']) {\n\t\treturn query.list[0]['minx'];\n\t} else\n\t\treturn 0;\n}\n\nasync function clear(collectionName) {\n\tawait db.collection(collectionName).where({\n\t\t_id: dbCmd.neq(1)\n\t}).remove().then(res => {\n\n\t});\n}\n\nasync function isExistCollection(collectionName) {\n\ttry {\n\t\tawait getOne(collectionName, {});\n\t\treturn true;\n\n\t} catch (err) {\n\t\treturn false;\n\t}\n}\n\nasync function createCollection(collectionName) {\n\ttry {\n\t\tawait db.createCollection(collectionName);\n\n\t\tconsole.log('>> Create New Collection [' + collectionName + '] Succ, OVER.');\n\t\treturn true;\n\n\t} catch (err) {\n\t\tconsole.error('>> Create New Collection [' + collectionName + '] Failed, Code=' + err.errCode + '|' + err.errMsg);\n\t\treturn false;\n\t}\n\n}\n\nasync function rand(collectionName, where = {}, fields = '*', size = 1) {\n\n\tsize = Number(size);\n\n\tif (size > MAX_RECORD_SIZE) size = MAX_RECORD_SIZE;\n\n\n\tlet query = await db.collection(collectionName)\n\t\t.aggregate();\n\n\tif (util.isDefined(where))\n\t\tquery = await query.match(fmtWhere(where));\n\n\tif (util.isDefined(fields) && fields != '*')\n\t\tquery = await query.project(fmtFields(fields));\n\n\n\tquery = await query.sample({\n\t\tsize\n\t});\n\n\tquery = await query.end();\n\n\tif (size == 1) {\n\t\tif (query.list.length == 1)\n\t\t\treturn query.list[0];\n\t\telse\n\t\t\treturn null;\n\t} else\n\t\treturn query.list;\n\n}\n\nasync function getListByArray(collectionName, arrField, where, fields, orderBy, page = 1, size = DEFAULT_RECORD_SIZE, isTotal = true, oldTotal = 0) {\n\n\tif (typeof (where) == 'string' || typeof (where) == 'number') {\n\t\twhere = {\n\t\t\t_id: where,\n\t\t};\n\t}\n\n\tpage = Number(page);\n\tsize = Number(size);\n\n\tif (size > MAX_RECORD_SIZE) size = MAX_RECORD_SIZE;\n\n\tdata = {\n\t\tpage: page,\n\t\tsize: size\n\t}\n\n\tlet offset = 0; //记录偏移量 防止新增数据列表重复 \n\n\t// 计算总页数\n\tif (isTotal) {\n\t\t// 联表\n\t\tlet queryCnt = await db.collection(collectionName)\n\t\t\t.aggregate();\n\n\t\t// 查询条件\n\t\tif (util.isDefined(where))\n\t\t\tqueryCnt = await queryCnt.match(fmtWhere(where));\n\n\t\tlet total = await queryCnt.count('total').end();\n\t\tif (!total.list.length)\n\t\t\ttotal = 0;\n\t\telse\n\t\t\ttotal = total.list[0].total;\n\n\t\tdata.total = total;\n\t\tdata.count = Math.ceil(total / size);\n\n\t\tif (page > 1 && oldTotal > 0) {\n\t\t\toffset = data.total - oldTotal\n\t\t\tif (offset < 0) offset = 0;\n\t\t}\n\t}\n\n\t// 拆分查询\n\tlet query = await db.collection(collectionName)\n\t\t.aggregate()\n\t\t.unwind('$' + arrField);\n\n\t// 查询条件\n\tif (util.isDefined(where))\n\t\tquery = await query.match(fmtWhere(where));\n\n\t// 取出特定字段\n\tif (util.isDefined(fields) && fields != '*')\n\t\tquery = await query.project(fmtFields(fields));\n\n\t// 排序   \n\tif (util.isDefined(orderBy)) {\n\t\tquery = await query.sort(fmtJoinSort(orderBy));\n\t}\n\n\t// 分页\n\tquery = await query.skip((page - 1) * size + offset).limit(size);\n\n\t// 取数据\n\tquery = await query.end();\n\tdata.list = query.list;\n\n\treturn data;\n}\n\nasync function getListJoin(collectionName, joinParams, where, fields, orderBy, page = 1, size = DEFAULT_RECORD_SIZE, isTotal = true, oldTotal = 0, is2Many = false) {\n\n\tif (typeof (where) == 'string' || typeof (where) == 'number') {\n\t\twhere = {\n\t\t\t_id: where,\n\t\t};\n\t}\n\n\tpage = Number(page);\n\tsize = Number(size);\n\n\tif (size > MAX_RECORD_SIZE) size = MAX_RECORD_SIZE;\n\n\tdata = {\n\t\tpage: page,\n\t\tsize: size\n\t}\n\n\tlet offset = 0; //记录偏移量 防止新增数据列表重复 \n\n\t// 计算总页数\n\tif (isTotal) {\n\t\t// 联表\n\t\tlet queryCnt = await db.collection(collectionName)\n\t\t\t.aggregate()\n\t\t\t.lookup(joinParams);\n\n\t\t// 查询条件\n\t\tif (util.isDefined(where))\n\t\t\tqueryCnt = await queryCnt.match(fmtWhere(where));\n\n\t\tlet total = await queryCnt.count('total').end();\n\t\tif (!total.list.length)\n\t\t\ttotal = 0;\n\t\telse\n\t\t\ttotal = total.list[0].total;\n\n\t\tdata.total = total;\n\t\tdata.count = Math.ceil(total / size);\n\n\t\tif (page > 1 && oldTotal > 0) {\n\t\t\toffset = data.total - oldTotal\n\t\t\tif (offset < 0) offset = 0;\n\t\t}\n\t}\n\n\t// 联表\n\tlet query = await db.collection(collectionName)\n\t\t.aggregate()\n\t\t.lookup(joinParams);\n\n\t/*\n\tquery = await query.replaceRoot({\n\tnewRoot: $.mergeObjects([ $.arrayElemAt(['$USER_DETAIL', 0]), '$$ROOT' ])\n\t})*/\n\n\t// 查询条件\n\tif (util.isDefined(where))\n\t\tquery = await query.match(fmtWhere(where));\n\n\t// 取出特定字段\n\tif (util.isDefined(fields) && fields != '*')\n\t\tquery = await query.project(fmtFields(fields));\n\n\t// 排序   \n\tif (util.isDefined(orderBy)) {\n\t\tquery = await query.sort(fmtJoinSort(orderBy));\n\t}\n\n\t// 分页\n\tquery = await query.skip((page - 1) * size + offset).limit(size);\n\n\n\t// 取数据\n\tquery = await query.end();\n\tdata.list = query.list;\n\n\tif (!is2Many) {\n\t\tfor (let k = 0; k < data.list.length; k++) {\n\t\t\tif (util.isDefined(data.list[k][joinParams.as])) {\n\t\t\t\tif (Array.isArray(data.list[k][joinParams.as]) &&\n\t\t\t\t\tdata.list[k][joinParams.as].length > 0)\n\t\t\t\t\tdata.list[k][joinParams.as] = data.list[k][joinParams.as][0];\n\t\t\t\telse {\n\t\t\t\t\tdata.list[k][joinParams.as] = {};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn data;\n}\n\nasync function getListJoinCount(collectionName, joinParams, where) {\n\n\tif (typeof (where) == 'string' || typeof (where) == 'number') {\n\t\twhere = {\n\t\t\t_id: where,\n\t\t};\n\t}\n\n\t// 联表\n\tlet queryCnt = await db.collection(collectionName)\n\t\t.aggregate()\n\t\t.lookup(joinParams);\n\n\t// 查询条件\n\tif (util.isDefined(where))\n\t\tqueryCnt = await queryCnt.match(fmtWhere(where));\n\n\tlet total = await queryCnt.count('total').end();\n\tif (!total.list.length)\n\t\ttotal = 0;\n\telse\n\t\ttotal = total.list[0].total;\n\n\treturn total;\n\n}\n\nasync function getList(collectionName, where, fields = '*', orderBy = {}, page = 1, size = DEFAULT_RECORD_SIZE, isTotal = true, oldTotal = 0) {\n\tpage = Number(page);\n\tsize = Number(size);\n\n\tif (size > MAX_RECORD_SIZE || size == 0) size = MAX_RECORD_SIZE;\n\n\tlet data = {\n\t\tpage: page,\n\t\tsize: size\n\t}\n\n\tlet offset = 0;\n\t// 计算总页数\n\tif (isTotal) {\n\t\tlet total = await count(collectionName, where);\n\t\tdata.total = total;\n\t\tdata.count = Math.ceil(total / size);\n\n\t\tif (page > 1 && oldTotal > 0) {\n\t\t\toffset = data.total - oldTotal\n\t\t\tif (offset < 0) offset = 0;\n\n\t\t}\n\t}\n\n\t// 分页 \n\tlet query = await db.collection(collectionName)\n\t\t.skip((page - 1) * size + offset)\n\t\t.limit(size);\n\n\t// 查询条件  \n\tif (util.isDefined(where) && where)\n\t\tquery = await query.where(fmtWhere(where));\n\n\t// 取出特定字段\n\tif (util.isDefined(fields) && fields != '*')\n\t\tquery = await query.field(fmtFields(fields));\n\n\t// 排序  \n\tif (util.isDefined(orderBy)) {\n\t\tquery = await fmtOrderBy(query, orderBy);\n\t}\n\n\t// 取数据\n\tquery = await query.get();\n\n\tdata.list = query.data;\n\n\treturn data;\n}\n\nasync function getAllBig(collectionName, where, fields = '*', orderBy, size = MAX_RECORD_SIZE) {\n\tsize = Number(size);\n\tif (size > MAX_RECORD_SIZE) size = MAX_RECORD_SIZE;\n\n\t// 计算总数\n\tlet total = await await count(collectionName, where);\n\n\t// 页数\n\tlet page = Math.ceil(total / size);\n\n\tlet list = [];\n\tfor (let i = 1; i <= page; i++) {\n\t\tlet data = await getList(collectionName, where, fields, orderBy, i, size, false);\n\n\t\tif (data && data.list)\n\t\t\tlist = list.concat(data.list);\n\t}\n\n\treturn list;\n}\n\n\nasync function getAll(collectionName, where, fields = '*', orderBy, size = MAX_RECORD_SIZE) {\n\tsize = Number(size);\n\tif (size > MAX_RECORD_SIZE) size = MAX_RECORD_SIZE;\n\n\tlet query = await db.collection(collectionName).limit(size);\n\n\t// 查询条件\n\tif (where)\n\t\tquery = await query.where(fmtWhere(where));\n\n\t// 取出特定字段\n\tif (fields && fields != '*')\n\t\tquery = await query.field(fmtFields(fields));\n\n\t// 排序 \n\tif (orderBy) {\n\t\tquery = await fmtOrderBy(query, orderBy);\n\t}\n\n\t// 取数据\n\tquery = await query.get();\n\treturn query.data;\n}\n\nasync function getAllByArray(collectionName, arrField, where, fields = '*', orderBy, size = MAX_RECORD_SIZE) {\n\tsize = Number(size);\n\tif (size > MAX_RECORD_SIZE) size = MAX_RECORD_SIZE;\n\n\t// 拆分\n\tlet query = await db.collection(collectionName).aggregate()\n\t\t.unwind('$' + arrField);\n\n\t// 查询条件\n\tif (util.isDefined(where))\n\t\tquery = await query.match(fmtWhere(where));\n\n\t// 取出特定字段\n\tif (util.isDefined(fields) && fields != '*')\n\t\tquery = await query.project(fmtFields(fields));\n\n\t// 排序 \n\tif (util.isDefined(orderBy)) {\n\t\tquery = await query.sort(fmtJoinSort(orderBy));\n\t}\n\n\t// 取数据\n\tquery = await query.limit(size).end();\n\treturn query.list;\n}\n\nasync function getOne(collectionName, where, fields = '*', orderBy = {}) {\n\tif (typeof (where) == 'string' || typeof (where) == 'number') {\n\t\twhere = {\n\t\t\t_id: where\n\t\t};\n\t}\n\n\t// 查询条件 \n\tlet query = await db.collection(collectionName)\n\t\t.where(fmtWhere(where))\n\t\t.limit(1);\n\n\t// 取出特定字段 \n\tif (fields != '*')\n\t\tquery = await query.field(fmtFields(fields));\n\n\t// 排序\n\tif (orderBy)\n\t\tquery = await fmtOrderBy(query, orderBy);\n\n\t// 取数据\n\tquery = await query.get();\n\n\tif (query && query.data.length > 0) {\n\t\treturn query.data[0];\n\t} else\n\t\treturn null;\n}\n\nasync function fmtOrderBy(query, orderBy) {\n\tfor (let key in orderBy) {\n\t\tquery = await query.orderBy(key, orderBy[key].toLowerCase())\n\t}\n\treturn query;\n}\n\nfunction fmtJoinSort(sort) {\n\tfor (let key in sort) {\n\t\tlet v = sort[key];\n\t\tif (typeof (v) == 'string') {\n\t\t\tv = v.toLowerCase();\n\t\t\tif (v === 'asc')\n\t\t\t\tv = 1;\n\t\t\telse\n\t\t\t\tv = -1;\n\t\t}\n\t\tsort[key] = v;\n\t}\n\treturn sort;\n}\n\n\nfunction fmtFields(fields) {\n\tif (typeof (fields) == 'string') {\n\t\tlet obj = {};\n\t\tfields = fields.replace(/，/g, \",\");\n\t\tlet arr = fields.split(',');\n\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\tif (arr[i].trim().length > 0)\n\t\t\t\tobj[arr[i].trim()] = true;\n\t\t}\n\t\treturn obj;\n\t}\n\n\treturn fields;\n}\n\n\nfunction fmtWhere(where) {\n\tif (util.isDefined(where.and) || util.isDefined(where.or)) {\n\t\tlet whereEx = null;\n\t\tif (util.isDefined(where.and))\n\t\t\twhereEx = dbCmd.and(fmtWhere(where.and));\n\n\t\tif (util.isDefined(where.or)) {\n\t\t\tif (whereEx)\n\t\t\t\twhereEx = whereEx.and(dbCmd.or(fmtWhere(where.or)));\n\t\t\telse\n\t\t\t\twhereEx = dbCmd.or(fmtWhere(where.or));\n\t\t}\n\t\t//console.log(whereEx);\n\t\treturn whereEx;\n\t}\n\n\tif (Array.isArray(where)) {\n\t\tfor (let i = 0; i < where.length; i++)\n\t\t\twhere[i] = fmtWhere(where[i]);\n\t}\n\n\tfor (let key in where) {\n\t\t/* 判断是否有条件数组  \n\t\t\tINFO_EXPIRE_TIME: [\n\t\t\t\t['>=', 3], \n\t\t\t\t['<=', 8],\n\t\t\t\t['<>', 5],\n\t\t\t\t['in', '6,7']\n\t\t\t\t],\n\t\t*/\n\t\tif (Array.isArray(where[key])) {\n\t\t\tlet w = null;\n\t\t\tif (!Array.isArray(where[key][0]) && where[key][0].toLowerCase().trim() == 'between') {\n\t\t\t\t// 条件查询特殊处理\n\t\t\t\twhere[key] = [\n\t\t\t\t\t['>=', where[key][1]],\n\t\t\t\t\t['<=', where[key][2]]\n\t\t\t\t];\n\t\t\t}\n\n\t\t\tif (!Array.isArray(where[key][0])) {\n\t\t\t\t// 一维数组 \n\t\t\t\tw = fmtWhereSimple(where[key]);\n\t\t\t} else {\n\t\t\t\t// 二维数组 \n\t\t\t\tfor (let i = 0; i < where[key].length; i++) {\n\t\t\t\t\tlet wTemp = fmtWhereSimple(where[key][i]);\n\t\t\t\t\tw = (w) ? w.and(wTemp) : wTemp;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\twhere[key] = w;\n\n\t\t}\n\t}\n\treturn where;\n}\n\nfunction fmtWhereSimple(arr) {\n\tlet sql = '';\n\n\tlet op = arr[0].toLowerCase().trim();\n\tlet val = arr[1];\n\tlet where = {};\n\tswitch (op) {\n\t\tcase '=':\n\t\t\twhere = dbCmd.eq(val);\n\t\t\tbreak;\n\t\tcase '!=':\n\t\tcase '<>':\n\t\t\twhere = dbCmd.neq(val);\n\t\t\tbreak;\n\t\tcase '<':\n\t\t\twhere = dbCmd.lt(val);\n\t\t\tbreak;\n\t\tcase '<=':\n\t\t\twhere = dbCmd.lte(val);\n\t\t\tbreak;\n\t\tcase '>':\n\t\t\twhere = dbCmd.gt(val);\n\t\t\tbreak;\n\t\tcase '>=':\n\t\t\twhere = dbCmd.gte(val);\n\t\t\tbreak;\n\t\tcase 'like':\n\t\t\tif (!util.isDefined(val) || !val) break; //无条件不搜索\n\t\t\twhere = {\n\t\t\t\t$regex: val,\n\t\t\t\t$options: 'i'\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'in':\n\t\t\tval = dataUtil.str2Arr(val);\n\t\t\twhere = dbCmd.in(val);\n\t\t\tbreak;\n\t\tcase 'not in':\n\t\t\tval = dataUtil.str2Arr(val);\n\t\t\twhere = dbCmd.nin(val);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tconsole.error('error where oprt=' + op);\n\t\t\tbreak;\n\t}\n\treturn where;\n}\n\nmodule.exports = {\n\tgetCmd,\n\n\tinsert,\n\tinsertBatch,\n\tedit,\n\tdel,\n\n\tcount,\n\tinc,\n\tsum,\n\tgroupCount,\n\tgroupSum,\n\tdistinct,\n\tdistinctCnt,\n\tmax,\n\tmin,\n\tmul,\n\n\tisExistCollection,\n\tcreateCollection,\n\tclear,\n\trand,\n\tgetOne,\n\tgetAll,\n\tgetAllBig,\n\n\tgetAllByArray,\n\tgetList,\n\tgetListJoin,\n\tgetListJoinCount,\n\tgetListByArray,\n\tMAX_RECORD_SIZE,\n\tDEFAULT_RECORD_SIZE\n}"
  },
  {
    "path": "cloudfunctions/mcloud/framework/database/model.js",
    "content": "/**\n * Notes: 数据持久化与操作模块\n * Ver : CCMiniCloud Framework 2.11.1 ALL RIGHTS RESERVED BY ccLinux0730 (wechat)\n * Date: 2020-09-04 04:00:00 \n */\n\nconst dbUtil = require('./db_util.js');\nconst util = require('../utils/util.js');\nconst timeUtil = require('../utils/time_util.js');\nconst dataUtil = require('../utils/data_util.js');\nconst AppError = require('../core/app_error.js');\nconst cloudBase = require('../cloud/cloud_base.js');\n\nclass Model {\n\n\tstatic async getOne(where, fields = '*', orderBy = {}) {\n\t\treturn await dbUtil.getOne(this.CL, where, fields, orderBy);\n\t}\n\n\tstatic async edit(where, data) {\n\n\t\tif (this.UPDATE_TIME) {\n\t\t\tlet editField = this.FIELD_PREFIX + 'EDIT_TIME';\n\t\t\tif (!util.isDefined(data[editField])) data[editField] = timeUtil.time();\n\t\t}\n\n\t\tif (this.UPDATE_IP) {\n\t\t\tlet cloud = cloudBase.getCloud();\n\t\t\tlet ip = cloud.getWXContext().CLIENTIP;\n\n\n\t\t\tlet editField = this.FIELD_PREFIX + 'EDIT_IP';\n\t\t\tif (!util.isDefined(data[editField])) data[editField] = ip;\n\t\t}\n\n\t\tdata = this.clearEditData(data);\n\n\t\treturn await dbUtil.edit(this.CL, where, data);\n\t}\n\n\tstatic async count(where) {\n\t\treturn await dbUtil.count(this.CL, where);\n\t}\n\n\tstatic async insert(data) {\n\t\t// 自动ID\n\t\tif (this.ADD_ID) {\n\t\t\tlet idField = this.FIELD_PREFIX + 'ID';\n\t\t\tif (!util.isDefined(data[idField])) data[idField] = dataUtil.makeID();\n\t\t}\n\n\t\t// 更新时间\n\t\tif (this.UPDATE_TIME) {\n\t\t\tlet timestamp = timeUtil.time();\n\t\t\tlet addField = this.FIELD_PREFIX + 'ADD_TIME';\n\t\t\tif (!util.isDefined(data[addField])) data[addField] = timestamp;\n\n\t\t\tlet editField = this.FIELD_PREFIX + 'EDIT_TIME';\n\t\t\tif (!util.isDefined(data[editField])) data[editField] = timestamp;\n\t\t}\n\n\t\t// 更新IP\n\t\tif (this.UPDATE_IP) {\n\t\t\tlet cloud = cloudBase.getCloud();\n\t\t\tlet ip = cloud.getWXContext().CLIENTIP;\n\n\t\t\tlet addField = this.FIELD_PREFIX + 'ADD_IP';\n\t\t\tif (!util.isDefined(data[addField])) data[addField] = ip;\n\n\t\t\tlet editField = this.FIELD_PREFIX + 'EDIT_IP';\n\t\t\tif (!util.isDefined(data[editField])) data[editField] = ip;\n\t\t}\n\n\t\t// 数据清洗\n\t\tdata = this.clearCreateData(data);\n\n\t\treturn await dbUtil.insert(this.CL, data);\n\t}\n\n\tstatic async insertOrUpdate(where, data) {\n\t\tlet model = await dbUtil.getOne(this.CL, where, '_id');\n\t\tif (model) {\n\t\t\tawait this.edit(model._id, data);\n\t\t\treturn model._id;\n\t\t} else {\n\t\t\treturn await this.insert(Object.assign(data, where));\n\t\t}\n\t}\n\n\tstatic async insertBatch(data = [], size = 1000) {\n\t\tif (this.ADD_ID) {\n\t\t\tlet idField = this.FIELD_PREFIX + 'ID';\n\t\t\tfor (let k = 0; k < data.length; k++) {\n\t\t\t\tif (!util.isDefined(data[k][idField])) data[k][idField] = dataUtil.makeID();\n\t\t\t}\n\t\t}\n\n\t\tif (this.UPDATE_TIME) {\n\t\t\tlet timestamp = timeUtil.time();\n\t\t\tlet addField = this.FIELD_PREFIX + 'ADD_TIME';\n\t\t\tlet editField = this.FIELD_PREFIX + 'EDIT_TIME';\n\n\t\t\tfor (let k = 0; k < data.length; k++) {\n\t\t\t\tif (!util.isDefined(data[k][addField])) data[k][addField] = timestamp;\n\t\t\t\tif (!util.isDefined(data[k][editField])) data[k][editField] = timestamp;\n\t\t\t}\n\n\t\t}\n\n\t\tif (this.UPDATE_IP) {\n\t\t\tlet cloud = cloudBase.getCloud();\n\t\t\tlet ip = cloud.getWXContext().CLIENTIP;\n\n\t\t\tlet addField = this.FIELD_PREFIX + 'ADD_IP';\n\t\t\tlet editField = this.FIELD_PREFIX + 'EDIT_IP';\n\n\t\t\tfor (let k = 0; k < data.length; k++) {\n\t\t\t\tif (!util.isDefined(data[k][addField])) data[k][addField] = ip;\n\t\t\t\tif (!util.isDefined(data[k][editField])) data[k][editField] = ip;\n\t\t\t}\n\n\t\t}\n\n\t\tfor (let k = 0; k < data.length; k++) {\n\t\t\tdata[k] = this.clearCreateData(data[k]);\n\t\t}\n\n\t\treturn await dbUtil.insertBatch(this.CL, data, size);\n\t}\n\n\tstatic async del(where) {\n\t\treturn await dbUtil.del(this.CL, where);\n\t}\n\n\tstatic async inc(where, field, val = 1) {\n\t\treturn await dbUtil.inc(this.CL, where, field, val);\n\t}\n\n\tstatic async mul(where, field, val = 1) {\n\t\treturn await dbUtil.mul(this.CL, where, field, val);\n\t}\n\n\tstatic async groupSum(where, groupField, field) {\n\t\treturn await dbUtil.groupSum(this.CL, where, groupField, field);\n\t}\n\n\tstatic async groupCount(where, groupField) {\n\t\treturn await dbUtil.groupCount(this.CL, where, groupField);\n\t}\n\n\tstatic async sum(where, field) {\n\t\treturn await dbUtil.sum(this.CL, where, field);\n\t}\n\n\tstatic async distinct(where, field) {\n\t\treturn await dbUtil.distinct(this.CL, where, field);\n\t}\n\n\tstatic async distinctCnt(where, field) {\n\t\treturn await dbUtil.distinctCnt(this.CL, where, field);\n\t}\n\n\tstatic async max(where, field) {\n\t\treturn await dbUtil.max(this.CL, where, field);\n\t}\n\n\tstatic async min(where, field) {\n\t\treturn await dbUtil.min(this.CL, where, field);\n\t}\n\n\tstatic async clear() {\n\t\treturn await dbUtil.clear(this.CL);\n\t}\n\n\tstatic async rand(where = {}, fields = '*', size = 1) {\n\t\treturn await dbUtil.rand(this.CL, where, fields, size);\n\t}\n\n\tstatic async getAll(where, fields, orderBy, size = 100) {\n\t\treturn await dbUtil.getAll(this.CL, where, fields, orderBy, size);\n\t}\n\n\tstatic async getAllBig(where, fields, orderBy, size = 1000) {\n\t\treturn await dbUtil.getAllBig(this.CL, where, fields, orderBy, size);\n\t}\n\n\tstatic async getAllByArray(arrField, where, fields, orderBy, size = 100) {\n\t\treturn await dbUtil.getAllByArray(this.CL, arrField, where, fields, orderBy, size);\n\t}\n\n\tstatic async getList(where, fields, orderBy, page, size, isTotal, oldTotal) {\n\t\treturn await dbUtil.getList(this.CL, where, fields, orderBy, page, size, isTotal, oldTotal);\n\t}\n\n\tstatic async getListJoin(joinParams, where, fields, orderBy, page = 1, size, isTotal = true, oldTotal = 0, is2Many = false) {\n\t\treturn await dbUtil.getListJoin(this.CL, joinParams, where, fields, orderBy, page, size, isTotal, oldTotal, is2Many);\n\t}\n\n\tstatic async getListJoinCount(joinParams, where) {\n\t\treturn await dbUtil.getListJoinCount(this.CL, joinParams, where);\n\t}\n\n\tstatic async getListByArray(arrField, where, fields, orderBy, page = 1, size, isTotal = true, oldTotal = 0) {\n\t\treturn await dbUtil.getListByArray(this.CL, arrField, where, fields, orderBy, page, size, isTotal, oldTotal);\n\t}\n\n\tstatic converDBStructure(stru) {\n\t\tlet newStru = {};\n\t\tfor (let key in stru) {\n\t\t\tnewStru[key] = {};\n\n\t\t\tlet arr = stru[key].split('|');\n\t\t\tfor (let k = 0; k < arr.length; k++) {\n\n\t\t\t\t// 类型\n\t\t\t\tlet val = arr[k].toLowerCase().trim();\n\t\t\t\tlet orginal = arr[k];\n\n\t\t\t\tlet type = 'string';\n\t\t\t\tif (val === 'float' || val === 'int' || val === 'string' || val === 'array' || val === 'object' || val === 'bool') {\n\t\t\t\t\ttype = val;\n\t\t\t\t\tnewStru[key]['type'] = type;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// 是否必填\n\t\t\t\tif (val === 'true' || val === 'false') {\n\t\t\t\t\tlet required = (val === 'true') ? true : false;\n\t\t\t\t\tnewStru[key]['required'] = required;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// 默认值\n\t\t\t\tif (val.startsWith('default=') && util.isDefined(newStru[key]['type'])) {\n\t\t\t\t\tlet defVal = orginal.replace('default=', '');\n\t\t\t\t\tswitch (newStru[key]['type']) {\n\t\t\t\t\t\tcase 'int':\n\t\t\t\t\t\tcase 'float':\n\t\t\t\t\t\t\tdefVal = Number(defVal);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'bool':\n\t\t\t\t\t\t\tdefVal = defVal.toLowerCase();\n\t\t\t\t\t\t\tdefVal = defVal == 'true' ? true : false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'object':\n\t\t\t\t\t\t\tdefVal = defVal.replace('{', '');\n\t\t\t\t\t\t\tdefVal = defVal.replace('}', '').trim();\n\t\t\t\t\t\t\tif (!defVal)\n\t\t\t\t\t\t\t\tdefVal = {};\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tlet arr = defVal.split(',');\n\t\t\t\t\t\t\t\tdefVal = {};\n\t\t\t\t\t\t\t\tfor (let m = 0; m < arr.length; m++) {\n\t\t\t\t\t\t\t\t\tif (arr[m]) defVal[arr[m]] = '';\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'array':\n\t\t\t\t\t\t\tdefVal = defVal.replace('[', '');\n\t\t\t\t\t\t\tdefVal = defVal.replace(']', '').trim();\n\t\t\t\t\t\t\tif (!defVal)\n\t\t\t\t\t\t\t\tdefVal = [];\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tdefVal = defVal.split(',');\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tdefVal = String(defVal);\n\t\t\t\t\t}\n\t\t\t\t\tnewStru[key]['defVal'] = defVal;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// 注释\n\t\t\t\tif (val.startsWith('comment=')) {\n\t\t\t\t\tlet comment = orginal.replace('comment=', '');\n\t\t\t\t\tnewStru[key]['comment'] = comment;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// 长度\n\t\t\t\tif (val.startsWith('length=')) {\n\t\t\t\t\tlet length = orginal.replace('length=', '');\n\t\t\t\t\tlength = Number(length);\n\t\t\t\t\tnewStru[key]['length'] = length;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// 如果非必填字段没有默认值，则主动赋予一个\n\t\t\tif (!newStru[key]['required'] && !util.isDefined(newStru[key]['defVal'])) {\n\t\t\t\tlet defVal = '';\n\t\t\t\tswitch (newStru[key]['type']) {\n\t\t\t\t\tcase 'bool':\n\t\t\t\t\t\tdefVal = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'int':\n\t\t\t\t\tcase 'float':\n\t\t\t\t\t\tdefVal = Number(0);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'array':\n\t\t\t\t\t\tdefVal = [];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'object':\n\t\t\t\t\t\tdefVal = {};\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tdefVal = String('');\n\t\t\t\t}\n\t\t\t\tnewStru[key]['defVal'] = defVal;\n\t\t\t}\n\n\t\t\t// 如果没有长度\n\t\t\tif (!util.isDefined(newStru[key]['length'])) {\n\t\t\t\tlet length = 20;\n\t\t\t\tswitch (newStru[key]['type']) {\n\t\t\t\t\tcase 'int':\n\t\t\t\t\tcase 'float':\n\t\t\t\t\t\tlength = 30;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'array':\n\t\t\t\t\tcase 'object':\n\t\t\t\t\t\tlength = 1500;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tlength = 300;\n\t\t\t\t}\n\t\t\t\tnewStru[key]['length'] = length;\n\t\t\t}\n\t\t}\n\t\treturn newStru;\n\t}\n\n\tstatic clearDirtyData(data) {\n\t\tfor (let key in data) {\n\t\t\tif (!this.DB_STRUCTURE.hasOwnProperty(key) && !key.includes('.')) {\n\t\t\t\tconsole.error('脏数据:' + key);\n\t\t\t\tthrow new AppError('脏数据');\n\t\t\t}\n\t\t}\n\t}\n\n\tstatic converDataType(data, dbStructure) {\n\t\tfor (let key in data) {\n\t\t\tif (dbStructure.hasOwnProperty(key)) {\n\t\t\t\tlet type = dbStructure[key].type.toLowerCase();\n\t\t\t\t// 字段类型转换\n\t\t\t\tswitch (type) {\n\t\t\t\t\tcase 'string':\n\t\t\t\t\t\tdata[key] = String(data[key]);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'bool':\n\t\t\t\t\t\t//data[key] = data[key];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'float':\n\t\t\t\t\tcase 'int':\n\t\t\t\t\t\tdata[key] = Number(data[key]);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'array':\n\t\t\t\t\t\tif (data[key].constructor != Array)\n\t\t\t\t\t\t\tdata[key] = [];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'object':\n\t\t\t\t\t\tif (data[key] === undefined || data[key] === null) {\n\t\t\t\t\t\t\tdata[key] = {};\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (data[key].constructor != Object)\n\t\t\t\t\t\t\tdata[key] = {};\n\n\t\t\t\t\t\t//data[key] = dbUtil.getCmd().set(data[key]); // 指定字段等于一个对象 TODO\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tconsole.error('字段类型错误：' + key + dbStructure[key].type);\n\t\t\t\t\t\tthrow new AppError(\"字段类型错误\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn data;\n\t}\n\n\n\tstatic clearCreateData(data) {\n\n\t\tlet dbStructure = Model.converDBStructure(this.DB_STRUCTURE);\n\n\t\tfor (let key in dbStructure) {\n\n\t\t\t// 数据类型\n\t\t\tif (!util.isDefined(dbStructure[key].type)) {\n\t\t\t\tconsole.log('[数据填写错误1]字段类型未定义：' + key);\n\t\t\t\tthrow new AppError('数据填写错误1');\n\t\t\t}\n\n\t\t\t// 是否定义必填 \n\t\t\tif (!util.isDefined(dbStructure[key].required)) {\n\t\t\t\tconsole.log('[数据填写错误2]required未定义：' + key);\n\t\t\t\tthrow new AppError('数据填写错误2');\n\t\t\t}\n\n\t\t\t//  键值未赋值情况\n\t\t\tif (!data.hasOwnProperty(key)) {\n\t\t\t\t// 必填\n\t\t\t\tif (dbStructure[key].required) {\n\t\t\t\t\tif (util.isDefined(dbStructure[key].defVal))\n\t\t\t\t\t\t// 必填且有缺省值\n\t\t\t\t\t\tdata[key] = dbStructure[key].defVal;\n\t\t\t\t\telse {\n\t\t\t\t\t\t// 必填且无缺省值 \n\t\t\t\t\t\tconsole.log('[数据填写错误3]字段未填写：' + key);\n\t\t\t\t\t\tthrow new AppError('数据填写错误3 ' + key);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// 非必填字段必须有缺省值\n\t\t\t\t\tif (!util.isDefined(dbStructure[key].defVal)) {\n\t\t\t\t\t\tconsole.log('[数据填写错误4]非必填字段必须有缺省值：' + key);\n\t\t\t\t\t\tthrow new AppError('数据填写错误4');\n\t\t\t\t\t}\n\t\t\t\t\tdata[key] = dbStructure[key].defVal;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// 去掉脏数据\n\t\tthis.clearDirtyData(data, dbStructure);\n\n\t\tdata = this.converDataType(data, dbStructure);\n\n\t\treturn data;\n\t}\n\n\tstatic clearEditData(data) {\n\t\tlet dbStructure = Model.converDBStructure(this.DB_STRUCTURE);\n\n\t\t// 去掉脏数据\n\t\tthis.clearDirtyData(data, dbStructure);\n\n\t\tdata = this.converDataType(data, dbStructure);\n\n\t\treturn data;\n\t}\n\n\tstatic getDesc(enumName, val) {\n\t\tlet baseEnum = this[enumName];\n\t\tlet descEnum = this[enumName + '_DESC']\n\t\tlet enumKey = '';\n\n\t\t// 先找出KEY\n\t\tfor (let key in baseEnum) {\n\t\t\tif (baseEnum[key] === val) {\n\t\t\t\tenumKey = key;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (enumKey == '') return 'unknown';\n\n\t\t// 再从Desc里找出描述\n\t\treturn descEnum[enumKey];\n\t}\n\n}\n\n// 集合名 collection\nModel.CL = 'no-collection';\n\n// 集合结构\nModel.DB_STRUCTURE = 'no-dbStructure';\n\n// 字段前缀\nModel.FIELD_PREFIX = 'NO_';\n\n// 开关自带更新ADD_TIME,EDIT_TIME,DEL_TIME的操作 \nModel.UPDATE_TIME = true;\n\n// 开关自带更新ADD_IP,EDIT_IP,DEL_IP的操作 \nModel.UPDATE_IP = true;\n\n// 开关添加ID\nModel.ADD_ID = true;\n\n// 默认排序\nModel.ORDER_BY = {\n\t_id: 'desc'\n}\n\nmodule.exports = Model;"
  },
  {
    "path": "cloudfunctions/mcloud/framework/database/multi_model.js",
    "content": "/**\n * Notes: 实体基类 \n * Date: 2021-03-15 19:20:00 \n * Ver : CCMiniCloud Framework 2.12.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n */\n\n\nconst Model = require('./model.js');\nconst util = require('../utils/util.js');\nconst dataUtil = require('../utils/data_util.js');\nconst config = require('../../config/config.js');\n\nclass MultiModel extends Model {\n\n\tstatic C(cl) {\n\t\treturn config.COLLECTION_PRFIX + cl;\n\t}\n\n\tstatic _getWhere(where, mustPID = true) {\n\t\tif (mustPID) {\n\t\t\tif (typeof (where) == 'string' || typeof (where) == 'number') {\n\t\t\t\twhere = {\n\t\t\t\t\t_id: where,\n\t\t\t\t\t_pid: util.getProjectId()\n\t\t\t\t};\n\t\t\t} else\n\t\t\t\twhere._pid = util.getProjectId();\n\t\t}\n\t\treturn where;\n\t}\n\n\tstatic async getOneField(where, field, mustPID = true) {\n\t\twhere = MultiModel._getWhere(where, mustPID);\n\t\tlet one = await super.getOne(where, field);\n\t\tif (!one)\n\t\t\treturn null;\n\t\telse {\n\t\t\tlet ret = one[field];\n\t\t\tif (ret === undefined)\n\t\t\t\treturn '';\n\t\t\telse\n\t\t\t\treturn one[field];\n\t\t}\n\t}\n\n\tstatic async getOne(where, fields = '*', orderBy = {}, mustPID = true) {\n\t\twhere = MultiModel._getWhere(where, mustPID);\n\t\treturn await super.getOne(where, fields, orderBy);\n\t}\n\n\tstatic async edit(where, data, mustPID = true) {\n\t\twhere = MultiModel._getWhere(where, mustPID);\n\t\treturn await super.edit(where, data);\n\t}\n\n\tstatic async editForms(where, formName, objName, hasImageForms, mustPID = true) {\n\t\twhere = MultiModel._getWhere(where, mustPID);\n\n\t\tlet forms = await this.getOneField(where, formName, mustPID);\n\t\tif (!forms) return;\n\n\n\t\t// 赋值\n\t\tfor (let k = 0; k < hasImageForms.length; k++) {\n\t\t\tfor (let j in forms) {\n\t\t\t\tif ((forms[j].type == 'image' || forms[j].type == 'content')\n\t\t\t\t\t&& forms[j].mark == hasImageForms[k].mark\n\t\t\t\t\t&& forms[j].type == hasImageForms[k].type) {\n\t\t\t\t\tforms[j].val = hasImageForms[k].val;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet data = {\n\t\t\t[formName]: forms,\n\t\t\t[objName]: dataUtil.dbForms2Obj(forms)\n\t\t};\n\n\t\treturn await super.edit(where, data);\n\t}\n\n\tstatic async count(where, mustPID = true) {\n\t\twhere = MultiModel._getWhere(where, mustPID);\n\t\treturn await super.count(where);\n\t}\n\n\tstatic async insert(data, mustPID = true) {\n\t\tif (mustPID) data._pid = util.getProjectId();\n\t\treturn await super.insert(data);\n\t}\n\n\tstatic async insertBatch(data = [], size = 1000, mustPID = true) {\n\t\tif (mustPID) {\n\t\t\tfor (let k = 0; k < data.length; k++) {\n\t\t\t\tdata[k]._pid = util.getProjectId();\n\t\t\t}\n\t\t}\n\n\t\treturn await super.insertBatch(data, size);\n\t}\n\n\tstatic async insertOrUpdate(where, data, mustPID = true) {\n\t\tif (mustPID) {\n\t\t\twhere._pid = util.getProjectId();\n\t\t}\n\t\treturn await super.insertOrUpdate(where, data);\n\t}\n\n\tstatic async del(where, mustPID = true) {\n\t\twhere = MultiModel._getWhere(where, mustPID);\n\t\treturn await super.del(where);\n\t}\n\n\tstatic async clear() {\n\t\treturn await super.clear();\n\t}\n\n\tstatic async inc(where, field, val = 1, mustPID = true) {\n\t\twhere = MultiModel._getWhere(where, mustPID);\n\t\treturn await super.inc(where, field, val);\n\t}\n\n\tstatic async mul(where, field, val = 1, mustPID = true) {\n\t\twhere = MultiModel._getWhere(where, mustPID);\n\t\treturn await super.mul(where, field, val);\n\t}\n\n\tstatic async groupSum(where, groupField, field, mustPID = true) {\n\t\tif (mustPID) where._pid = util.getProjectId();\n\t\treturn await super.groupSum(where, groupField, field);\n\t}\n\n\tstatic async groupCount(where, groupField, mustPID = true) {\n\t\twhere = MultiModel._getWhere(where, mustPID);\n\t\treturn await super.groupCount(where, groupField);\n\t}\n\n\tstatic async sum(where, field, mustPID = true) {\n\t\twhere = MultiModel._getWhere(where, mustPID);\n\t\treturn await super.sum(where, field);\n\t}\n\n\tstatic async distinct(where, field, mustPID = true) {\n\t\twhere = MultiModel._getWhere(where, mustPID);\n\t\treturn await super.distinct(where, field);\n\t}\n\n\tstatic async distinctCnt(where, field, mustPID = true) {\n\t\twhere = MultiModel._getWhere(where, mustPID);\n\t\treturn await super.distinctCnt(where, field);\n\t}\n\n\tstatic async max(where, field, mustPID = true) {\n\t\twhere = MultiModel._getWhere(where, mustPID);\n\t\treturn await super.max(where, field);\n\t}\n\n\tstatic async min(where, field, mustPID = true) {\n\t\twhere = MultiModel._getWhere(where, mustPID);\n\t\treturn await super.min(where, field);\n\t}\n\n\tstatic async rand(where, field, size = 1, mustPID = true) {\n\t\twhere = MultiModel._getWhere(where, mustPID);\n\t\treturn await super.rand(where, field, size);\n\t}\n\n\tstatic async getAll(where, fields, orderBy, size = 100, mustPID = true) {\n\t\twhere = MultiModel._getWhere(where, mustPID);\n\t\treturn await super.getAll(where, fields, orderBy, size);\n\t}\n\n\tstatic async getAllBig(where, fields, orderBy, size = 1000, mustPID = true) {\n\t\twhere = MultiModel._getWhere(where, mustPID);\n\t\treturn await super.getAllBig(where, fields, orderBy, size);\n\t}\n\n\tstatic async getAllByArray(arrField, where, fields, orderBy, size = 100, mustPID = true) {\n\t\twhere = MultiModel._getWhere(where, mustPID);\n\t\treturn await super.getAllByArray(arrField, where, fields, orderBy, size);\n\t}\n\n\tstatic async getList(where, fields, orderBy, page, size, isTotal, oldTotal, mustPID = true) {\n\t\twhere = MultiModel._getWhere(where, mustPID);\n\t\treturn await super.getList(where, fields, orderBy, page, size, isTotal, oldTotal);\n\t}\n\n\tstatic async getListJoin(joinParams, where, fields, orderBy, page = 1, size, isTotal = true, oldTotal = 0, is2Many = false, mustPID = true) {\n\t\twhere = MultiModel._getWhere(where, mustPID);\n\t\treturn await super.getListJoin(joinParams, where, fields, orderBy, page, size, isTotal, oldTotal, is2Many);\n\t}\n\n\tstatic async getListJoinCount(joinParams, where, mustPID = true) {\n\t\twhere = MultiModel._getWhere(where, mustPID);\n\t\treturn await super.getListJoinCount(joinParams, where);\n\t}\n\n}\n\nmodule.exports = MultiModel;"
  },
  {
    "path": "cloudfunctions/mcloud/framework/lib/faker_lib.js",
    "content": "/**\n * Notes: 测试数据构造类\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-05-26 14:00:00 \n */ \nconst timeUtil = require('../utils/time_util.js');\n\n\n/** 随机获取数据 */\nfunction getRnd(arr, isNullable = false, ex = '') {\n\n\tif (isNullable) { // 允许为空\n\t\tlet rd = getIntBetween(0, 1);\n\t\tif (rd % 2 == 0) return '';\n\t}\n\n\n\tif (!Array.isArray(arr)) {\n\t\tarr = arr.replace(/ /g, '').replace(/，/g, ',').split(',');\n\t}\n\n\tlet exArr = ex.replace(/ /g, '').replace(/，/g, ',').split(',');\n\tlet ret = '';\n\n\tlet i = 0;\n\twhile (true) {\n\t\ti++;\n\t\tif (i > 1000) return '';\n\n\t\tret = arr[Math.floor((Math.random() * arr.length))];\n\t\tif (!exArr.includes(ret))\n\t\t\treturn ret;\n\t}\n\n}\n\n/** 省份 */\nfunction getProvince(isNullable = false, ex = '') {\n\tlet data = ['北京市', '天津市', '河北省', '山西省',\n\t\t'内蒙古自治区', '辽宁省', '吉林省',\n\t\t'黑龙江省', '上海市', '江苏省',\n\t\t'浙江省', '安徽省', '福建省', '江西省',\n\t\t'山东省', '河南省', '湖北省', '湖南省',\n\t\t'广东省', '广西壮族自治区', '海南省',\n\t\t'重庆市', '四川省', '贵州省', '云南省',\n\t\t'西藏自治区', '陕西省', '甘肃省', '青海省',\n\t\t'宁夏回族自治区', '新疆维吾尔自治区',\n\t\t'香港特别行政区', '澳门特别行政区', '台湾省'\n\t];\n\treturn getRnd(data, isNullable, ex);\n}\n\n\nfunction getProvinceAbbr(isNullable = false, ex = '') {\n\tlet data = ['京', '皖', '渝', '闽',\n\t\t'甘', '粤', '桂', '黔',\n\t\t'琼', '冀', '豫', '黑',\n\t\t'鄂', '湘', '吉', '苏',\n\t\t'赣', '辽', '蒙', '宁',\n\t\t'青', '鲁', '晋', '陕',\n\t\t'沪', '川', '津', '藏',\n\t\t'新', '滇', '浙', '港',\n\t\t'澳', '台'\n\t];\n\treturn getRnd(data, isNullable, ex);\n}\n\n/** 城市 */\nfunction getCity(isNullable = false, ex = '') {\n\tlet data = ['北京', '上海', '天津', '重庆',\n\t\t'哈尔滨', '长春', '沈阳', '呼和浩特',\n\t\t'石家庄', '乌鲁木齐', '兰州', '西宁',\n\t\t'西安', '银川', '郑州', '济南',\n\t\t'太原', '合肥', '武汉', '长沙',\n\t\t'南京', '成都', '贵阳', '昆明',\n\t\t'南宁', '拉萨', '杭州', '南昌',\n\t\t'广州', '福州', '海口',\n\t\t'香港', '澳门'\n\t];\n\treturn getRnd(data, isNullable, ex);\n}\n\n/** 地区 */\nfunction getArea(isNullable = false, ex = '') {\n\tlet data = ['西夏区', '永川区', '秀英区', '高港区',\n\t\t'清城区', '兴山区', '锡山区', '清河区',\n\t\t'龙潭区', '华龙区', '海陵区', '滨城区',\n\t\t'东丽区', '高坪区', '沙湾区', '平山区',\n\t\t'城北区', '海港区', '沙市区', '双滦区',\n\t\t'长寿区', '山亭区', '南湖区', '浔阳区',\n\t\t'南长区', '友好区', '安次区', '翔安区',\n\t\t'沈河区', '魏都区', '西峰区', '萧山区',\n\t\t'金平区', '沈北新区', '孝南区', '上街区',\n\t\t'城东区', '牧野区', '大东区', '白云区',\n\t\t'花溪区', '吉利区', '新城区', '怀柔区',\n\t\t'六枝特区', '涪城区', '清浦区', '南溪区',\n\t\t'淄川区', '高明区', '金水区', '中原区',\n\t\t'高新开发区', '经济开发新区', '新区'\n\t];\n\treturn getRnd(data, isNullable, ex);\n}\n\n/** 街道 */\nfunction getStreet(isNullable = false, ex = '') {\n\tlet data = '朱雀大街,太乙路,太白路,太华路,长乐坊,长樱路,案板街,竹笆市,骡马市,东木头市,西木头市,安仁坊,端履门,德福巷,洒金桥,冰窖巷,菊花园,下马陵,粉巷,索罗巷,后宰门,书院门,炭市街,马厂子,景龙池,甜水井,柏树林,桃花坞,人民路,解放路,黄河路,长江路,中山路,抚顺街,天津街,上海路,胜利路,西安路,长春路,太原街,沈阳路,鞍山路,五四路,唐山街,武汉街,延安路,朝阳街,鲁迅路,八一路,东北路,华南路,华北路,山东路,松江路,东方路,南沙街';\n\treturn getRnd(data, isNullable, ex);\n}\n\n/**  门牌地址 */\nfunction getAddress() {\n\treturn getProvince() + '' + getCity() + '市' + getArea() + '' + getStreet() + getIntBetween(1, 100) + '号';\n}\n\n/** 国家 */\nfunction getCountry(isNullable = false, ex = '') {\n\tlet data = ['阿富汗', '阿拉斯加', '阿尔巴尼亚', '阿尔及利亚',\n\t\t'安道尔', '安哥拉', '安圭拉岛英', '安提瓜和巴布达',\n\t\t'阿根廷', '亚美尼亚', '阿鲁巴岛', '阿森松', '澳大利亚',\n\t\t'奥地利', '阿塞拜疆', '巴林', '孟加拉国', '巴巴多斯',\n\t\t'白俄罗斯', '比利时', '伯利兹', '贝宁', '百慕大群岛',\n\t\t'不丹', '玻利维亚', '波斯尼亚和黑塞哥维那', '博茨瓦纳',\n\t\t'巴西', '保加利亚', '布基纳法索', '布隆迪', '喀麦隆',\n\t\t'加拿大', '加那利群岛', '佛得角', '开曼群岛', '中非',\n\t\t'乍得', '智利', '圣诞岛', '科科斯岛', '哥伦比亚',\n\t\t'巴哈马国', '多米尼克国', '科摩罗', '刚果', '科克群岛',\n\t\t'哥斯达黎加', '克罗地亚', '古巴', '塞浦路斯', '捷克',\n\t\t'丹麦', '迪戈加西亚岛', '吉布提', '多米尼加共和国',\n\t\t'厄瓜多尔', '埃及', '萨尔瓦多', '赤道几内亚',\n\t\t'厄立特里亚', '爱沙尼亚', '埃塞俄比亚', '福克兰群岛',\n\t\t'法罗群岛', '斐济', '芬兰', '法国', '法属圭亚那',\n\t\t'法属波里尼西亚', '加蓬', '冈比亚', '格鲁吉亚', '德国',\n\t\t'加纳', '直布罗陀', '希腊', '格陵兰岛', '格林纳达',\n\t\t'瓜德罗普岛', '关岛', '危地马拉', '几内亚', '几内亚比绍',\n\t\t'圭亚那', '海地', '夏威夷', '洪都拉斯', '匈牙利', '冰岛',\n\t\t'印度', '印度尼西亚', '伊郎', '伊拉克', '爱尔兰', '以色列',\n\t\t'意大利', '科特迪瓦', '牙买加', '日本', '约旦', '柬埔塞',\n\t\t'哈萨克斯坦', '肯尼亚', '基里巴斯', '朝鲜', '韩国', '科威特',\n\t\t'吉尔吉斯斯坦', '老挝', '拉脱维亚', '黎巴嫩', '莱索托',\n\t\t'利比里亚', '利比亚', '列支敦士登', '立陶宛', '卢森堡',\n\t\t'马其顿', '马达加斯加', '马拉维', '马来西亚', '马尔代夫',\n\t\t'马里', '马耳他', '马里亚纳群岛', '马绍尔群岛', '马提尼克',\n\t\t'毛里塔尼亚', '毛里求斯', '马约特岛', '墨西哥', '密克罗尼西亚',\n\t\t'中途岛', '摩尔多瓦', '摩纳哥', '蒙古', '蒙特塞拉特岛',\n\t\t'摩洛哥', '莫桑比克', '缅甸', '纳米比亚', '瑙鲁', '尼泊尔',\n\t\t'荷兰', '荷属安的列斯群岛', '新喀里多尼亚群岛', '新西兰',\n\t\t'尼加拉瓜', '尼日尔', '尼日利亚', '纽埃岛', '诺福克岛',\n\t\t'挪威', '阿曼', '帕劳', '巴拿马', '巴布亚新几内亚', '巴拉圭',\n\t\t'秘鲁', '菲律宾', '波兰', '葡萄牙', '巴基斯坦', '波多黎各',\n\t\t'卡塔尔', '留尼汪岛', '罗马尼亚', '俄罗斯', '卢旺达',\n\t\t'东萨摩亚', '西萨摩亚', '圣马力诺', '圣皮埃尔岛及密克隆岛',\n\t\t'圣多美和普林西比', '沙特阿拉伯', '塞内加尔', '塞舌尔',\n\t\t'新加坡', '斯洛伐克', '斯洛文尼亚', '所罗门群岛', '索马里',\n\t\t'南非', '西班牙', '斯里兰卡', '圣克里斯托弗和尼维斯',\n\t\t'圣赫勒拿', '圣卢西亚', '圣文森特岛', '苏丹', '苏里南',\n\t\t'斯威士兰', '瑞典', '瑞士', '叙利亚', '塔吉克斯坦', '坦桑尼亚',\n\t\t'泰国', '阿拉伯联合酋长国', '多哥', '托克劳群岛', '汤加',\n\t\t'特立尼达和多巴哥', '突尼斯', '土耳其', '土库曼斯坦',\n\t\t'特克斯和凯科斯群岛(', '图瓦卢', '美国', '乌干达', '乌克兰',\n\t\t'英国', '乌拉圭', '乌兹别克斯坦', '瓦努阿图', '梵蒂冈',\n\t\t'委内瑞拉', '越南', '维尔京群岛', '维尔京群岛和圣罗克伊',\n\t\t'威克岛', '瓦里斯和富士那群岛', '西撒哈拉', '也门', '南斯拉夫',\n\t\t'扎伊尔', '赞比亚', '桑给巴尔', '津巴布韦', '中华人民共和国', '中国'\n\t];\n\treturn getRnd(data, isNullable, ex);\n}\n\n\n/** 公司简称 */\nfunction getCompanyPrefix(isNullable = false, ex = '') {\n\tlet data = ['超艺', '和泰', '九方', '鑫博腾飞', '戴硕电子',\n\t\t'济南亿次元', '海创', '创联世纪', '凌云', '泰麒麟',\n\t\t'彩虹', '兰金电子', '晖来计算机', '天益', '恒聪百汇',\n\t\t'菊风公司', '惠派国际公司', '创汇', '思优', '时空盒数字',\n\t\t'易动力', '飞海科技', '华泰通安', '盟新', '商软冠联',\n\t\t'图龙信息', '易动力', '华远软件', '创亿', '时刻',\n\t\t'开发区世创', '明腾', '良诺', '天开', '毕博诚', '快讯',\n\t\t'凌颖信息', '黄石金承', '恩悌', '雨林木风计算机',\n\t\t'双敏电子', '维旺明', '网新恒天', '数字100', '飞利信',\n\t\t'立信电子', '联通时科', '中建创业', '新格林耐特',\n\t\t'新宇龙信息', '浙大万朋', 'MBP软件', '昂歌信息',\n\t\t'万迅电脑', '方正科技', '联软', '七喜', '南康', '银嘉',\n\t\t'巨奥', '佳禾', '国讯', '信诚致远', '浦华众城', '迪摩',\n\t\t'太极', '群英', '合联电子', '同兴万点', '襄樊地球村',\n\t\t'精芯', '艾提科信', '昊嘉', '鸿睿思博', '四通', '富罳',\n\t\t'商软冠联', '诺依曼软件', '东方峻景', '华成育卓', '趋势',\n\t\t'维涛', '通际名联'\n\t];\n\treturn getRnd(data, isNullable, ex);\n}\n\n/** 公司类型 */\nfunction getCompanyType(isNullable = false, ex = '') {\n\tlet data = ['科技', '网络', '信息', '传媒', '集团', '控股', '投资', '制造'];\n\treturn getRnd(data, isNullable, ex);\n}\n\n/** 公司名 */\nfunction getCompany(isNullable = false, ex = '') {\n\tif (getNullable(isNullable)) return '';\n\n\treturn getCompanyPrefix(false, ex) + getCompanyType() + '有限公司';\n}\n\n/** 内容 */\nfunction getContent(size = 1, isNullable = false, ex = '') {\n\tif (getNullable(isNullable)) return '';\n\n\tlet data = [\n\t\t'燕舞，燕舞，一曲歌来一片情。',\n\t\t'康师傅方便面，好吃看得见。',\n\t\t'不要太潇洒！',\n\t\t'让一亿人先聪明起来。',\n\t\t'共创美的前程，共度美的人生。',\n\t\t'省优，部优，葛优？',\n\t\t'喝孔府宴酒，做天下文章。',\n\t\t'健康成就未来。',\n\t\t'牙好，胃口就好，身体倍儿棒，吃嘛嘛香。',\n\t\t'永远的绿色，永远的秦池。',\n\t\t'坐红旗车，走中国路。',\n\t\t'要想皮肤好，早晚用大宝。',\n\t\t'孔府家酒，叫人想家。',\n\t\t'补钙新观念，吸收是要害。',\n\t\t'喝汇源果汁，走健康之路。',\n\t\t'爱的就是你!',\n\t\t'一种可以世袭的古典浪漫',\n\t\t'实力创造价值',\n\t\t'爱生活，爱拉芳！',\n\t\t'人类失去联想，世界将会怎样？',\n\t\t'做女人挺好！',\n\t\t'世界在你眼中？',\n\t\t'今天你有否亿唐？',\n\t\t'只溶在口，不溶在手。',\n\t\t'三千烦恼丝，健康新开始。',\n\t\t'维维豆奶，欢乐开怀。',\n\t\t'我们的光彩来自你的风采。',\n\t\t'钻石恒久远，一颗永流传。',\n\t\t'放我的真心在你的手心。',\n\t\t'小身材，大味道。',\n\t\t'牛奶香浓，丝般感受。',\n\t\t'聆听并不代表沉默，有时安静也是一种力量。',\n\t\t'滴滴香浓，意犹未尽。',\n\t\t'水晶之恋，一生不变。',\n\t\t'中国移动通信，沟通从心开始！',\n\t\t'网易，网聚人的力量！',\n\t\t'科技以人为本，诺基亚',\n\t\t'我们一直在努力！',\n\t\t'阳光总在风雨后',\n\t\t'男人对西服的要求，就是女人对男人的要求',\n\t\t'晚报，不晚报',\n\t\t'原来生活可以更美的',\n\t\t'明天的明天，你还会送我“水晶之恋”吗？',\n\t\t'卫浴出出进进的快感',\n\t\t'有家就有联合利华',\n\t\t'减脂减肥，其实是一种生活态度',\n\t\t'人头马一开，好事自然来。',\n\t\t'假如五指一样长，怎能满足用户不同需求？',\n\t\t'新飞广告做的好，不好新飞冰箱好',\n\t\t'传奇品质，百年张裕',\n\t\t'李宁：把出色留给自己',\n\t\t'一旦拥有，别无选择',\n\t\t'科技让你更轻松',\n\t\t'情系中国结，联通四海心',\n\t\t'海尔，中国造',\n\t\t'SOHU：足迹生活每一天',\n\t\t'果冻我要喜之郎',\n\t\t'国宝大熊猫，心纯天自高',\n\t\t'世界因为不同',\n\t\t'放低偏见，你会有出色发现！',\n\t\t'Just',\n\t\t'创意似金，敬业如牛',\n\t\t'不要让男人一手把握',\n\t\t'如同情人的手',\n\t\t'金窝银窝，不如自己的安乐窝。',\n\t\t'没有什么大不了的',\n\t\t'时间因我存在',\n\t\t'只要有梦想',\n\t\t'南方周末',\n\t\t'时间改变一切',\n\t\t'地球人都知道了',\n\t\t'众里寻他千百度，想要几度就几度',\n\t\t'您身边的银行，可信赖的银行',\n\t\t'三叶钢琴：学琴的孩子不会变坏',\n\t\t'柯达：串起生活每一刻',\n\t\t'大众甲克虫汽车：想想还是小的好',\n\t\t'一直被模拟,从未被超越',\n\t\t'幸福生活',\n\t\t'朗讯的创造力科技的原动力',\n\t\t'事事因你而出色',\n\t\t'运动之美，世界共享',\n\t\t'鹤舞白沙',\n\t\t'想知道“清嘴”的味道吗？',\n\t\t'弹指一挥间，世界皆互联',\n\t\t'更多选择、更多欢笑',\n\t\t'方太，让家的感觉更好',\n\t\t'世上仅此一件，今生与你结缘！',\n\t\t'白里透红与众不同',\n\t\t'没有蛀牙-佳洁士',\n\t\t'有线的价值',\n\t\t'享受快乐科技',\n\t\t'四海一家的解决之道',\n\t\t'娃哈哈纯净水：爱你等于爱自己',\n\t\t'农民山泉：有点甜',\n\t\t'博大精深，西门子',\n\t\t'一切尽在把握',\n\t\t'声声百思特，遥遥两相知',\n\t\t'一呼天下应',\n\t\t'让我们做得更好！',\n\t\t'暖和亲情，金龙鱼的大家庭。',\n\t\t'自然最健康，绿色好心情',\n\t\t'支起网络世界',\n\t\t'立邦漆：处处放光彩！',\n\t\t'fm365:真情互动！',\n\t\t'庄重一生，吉祥一生。',\n\t\t'人人都为礼品愁，我送北极海狗油。',\n\t\t'假如说人生的离合是一场戏，那么百年的好合更是早有安排！',\n\t\t'一品黄山天高云淡',\n\t\t'上上下下的享受！',\n\t\t'我是、我行、我素',\n\t\t'让无力者有力，让悲观者前行',\n\t\t'金利来—-男人的世界！',\n\t\t'百衣百顺',\n\t\t'聪明何必绝顶，慧根长留',\n\t\t'水往高处流',\n\t\t'大石化小，小石化了！',\n\t\t'“闲”妻良母',\n\t\t'“口服”，“心服”！',\n\t\t'盛满青春的秘密！',\n\t\t'三十六计走为上',\n\t\t'为了她的节日，献上您纯金般的心！',\n\t\t'用我们的钓线，你可以在鱼儿发现你之前先找到它',\n\t\t'生活就是一场运动，喝下它。',\n\t\t'选择维聚阿尔，已经表明你心明眼亮。',\n\t\t'佳能，我们看得见你想表达什么。',\n\t\t'天天都是春天',\n\t\t'假如你不来，广告明星就是他',\n\t\t'享受黑夜中偷拍的快感！',\n\t\t'彩信发送动人一刻',\n\t\t'灵感点亮生活!',\n\t\t'聪明演绎，无处不在！',\n\t\t'事业我一定争取，对你我从未放弃!',\n\t\t'波导手机，手机中的战斗机',\n\t\t'鄂尔多斯羊绒衫暖和全世界',\n\t\t'洁婷245再大的动作也不要紧',\n\t\t'做光明的牛，产光明的奶',\n\t\t'假如你的汽车会游泳的话，请照直开，不必刹车。',\n\t\t'永远要让驾驶执照比你自己先到期。',\n\t\t'请记住，上帝并不是十全十美的，它给汽车预备了备件，而人没有。',\n\t\t'小别意酸酸，欢聚心甜甜。',\n\t\t'除钞票外，承印一切。',\n\t\t'更多欢乐，更多选择',\n\t\t'美由你做主',\n\t\t'由我天地宽',\n\t\t'Sun是太阳，Java是月亮。',\n\t\t'不断创新，因为专心',\n\t\t'趁早下『斑』，请勿『痘』留。',\n\t\t'创新就是生活',\n\t\t'有一个漂亮的地方，万科四季花城',\n\t\t'建筑无限生活',\n\t\t'臭名远扬，香飘万里',\n\t\t'尝尝欢笑，经常麦当劳',\n\t\t'深入成就深度',\n\t\t'出色湖南，红网了然！',\n\t\t'因为网络，地球如村！',\n\t\t'一种质感',\n\t\t'恒久期盼',\n\t\t'繁荣民族文化',\n\t\t'不信，死给你看！',\n\t\t'天生的，强生的',\n\t\t'雪津啤酒，真情的味道！',\n\t\t'听世界，打天下',\n\t\t'雅芳比女人更了解女人',\n\t\t'Sun是太阳，Java是月亮。',\n\t\t'中国网通',\n\t\t'无线你的无限',\n\t\t'家有三洋，冬暖夏凉',\n\t\t'倾诉冬日暖语',\n\t\t'谁让我心动？',\n\t\t'灵活，让篮球场不再是一个平面',\n\t\t'别吻我，我怕修。',\n\t\t'一呼四应！',\n\t\t'无所不包！',\n\t\t'当之无愧',\n\t\t'以帽取人！',\n\t\t'一毛不拔！',\n\t\t'自讨苦吃！',\n\t\t'成功与科技共辉映',\n\t\t'没有最',\n\t];\n\n\tif (size == 1)\n\t\treturn getRnd(data, false, ex);\n\telse {\n\t\tret = '';\n\t\tfor (let i = 0; i < size; i++) {\n\t\t\tret += getRnd(data, false, ex) + ', ';\n\t\t}\n\t\treturn ret;\n\t}\n}\n\n/** 获得一句话 */\nfunction getWord(isNullable = false, ex = '') {\n\tif (getNullable(isNullable)) return '';\n\n\tlet ret = getContent(1, false, ex);\n\tret = ret.replace('。', '').replace('！', '').replace('？', '').replace('“', '”').replace('：', '');\n\treturn ret;\n}\n\n/** 星期 */\nfunction getWeek(isNullable = false, ex = '') {\n\tlet data = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];\n\treturn getRnd(data, isNullable, ex);\n}\n\n/** 月份 */\nfunction getMonth(isNullable = false, ex = '') {\n\tlet data = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];\n\treturn getRnd(data, isNullable, ex);\n}\n\n/** 获得姓名 */\nfunction getFirstName(isNullable = false, ex = '') {\n\tlet data = ['李', '王', '张', '刘', '陈', '杨', '赵', '黄', '周', '吴',\n\t\t'徐', '孙', '胡', '朱', '高', '林', '何', '郭', '马', '罗',\n\t\t'梁', '宋', '郑', '谢', '韩', '唐', '冯', '于', '董', '萧',\n\t\t'程', '曹', '袁', '邓', '许', '傅', '沉', '曾', '彭', '吕',\n\t\t'苏', '卢', '蒋', '蔡', '贾', '丁', '林', '薛', '叶', '阎',\n\t\t'余', '潘', '杜', '戴', '夏', '钟', '汪', '田', '任', '姜',\n\t\t'范', '方', '石', '姚', '谭', '廖', '邹', '熊', '金', '陆',\n\t\t'郝', '孔', '白', '崔', '康', '毛', '邱', '秦', '江', '史',\n\t\t'顾', '侯', '邵', '孟', '龙', '万', '段', '雷', '钱', '汤',\n\t\t'尹', '黎', '易', '常', '武', '乔', '贺', '赖', '龚', '文',\n\t\t'庞', '樊', '兰', '殷', '施', '陶', '洪', '翟', '安', '颜',\n\t\t'倪', '严', '牛', '温', '芦', '季', '俞', '章', '鲁', '葛',\n\t\t'伍', '韦', '申', '尤', '毕', '聂', '丛', '焦', '向', '柳',\n\t\t'邢', '路', '岳', '齐', '沿', '梅', '莫', '庄', '辛', '管',\n\t\t'祝', '左', '涂', '谷', '祁', '时', '舒', '耿', '牟', '卜',\n\t\t'路', '詹', '关', '苗', '凌', '费', '纪', '靳', '盛', '童',\n\t\t'欧', '甄', '项', '曲', '成', '游', '阳', '裴', '席', '卫',\n\t\t'查', '屈', '鲍', '位', '覃', '霍', '翁', '隋', '植', '甘',\n\t\t'景', '薄', '单', '包', '司', '柏', '宁', '柯', '阮', '桂',\n\t\t'闵', '欧阳', '解', '强', '柴', '华', '车', '冉', '房', '边',\n\t\t'辜', '吉', '饶', '刁', '瞿', '戚', '丘', '古', '米', '池',\n\t\t'滕', '晋', '苑', '邬', '臧', '畅', '宫', '来', '嵺', '苟',\n\t\t'全', '褚', '廉', '简', '娄', '盖', '符', '奚', '木', '穆',\n\t\t'党', '燕', '郎', '邸', '冀', '谈', '姬', '屠', '连', '郜',\n\t\t'晏', '栾', '郁', '商', '蒙', '计', '喻', '揭', '窦', '迟',\n\t\t'宇', '敖', '糜', '鄢', '冷', '卓', '花', '仇', '艾', '蓝',\n\t\t'都', '巩', '稽', '井', '练', '仲', '乐', '虞', '卞', '封',\n\t\t'竺', '冼', '原', '官', '衣', '楚', '佟', '栗', '匡', '宗',\n\t\t'应', '台', '巫', '鞠', '僧', '桑', '荆', '谌', '银', '扬',\n\t\t'明', '沙', '薄', '伏', '岑', '习', '胥', '保', '和', '蔺'\n\t];\n\treturn getRnd(data, isNullable, ex);\n}\n\n\n/** 女生名 */\nfunction getFemaleName(isNullable = false, ex = '') {\n\tif (getNullable(isNullable)) return '';\n\n\tlet data = ['芳', '娜', '敏', '静', '敏静', '秀英', '丽', '洋', '艳', '娟',\n\t\t'文娟', '君', '文君', '珺', '霞', '明霞', '秀兰', '燕', '芬', '桂芬',\n\t\t'玲', '桂英', '丹', '萍', '华', '红', '玉兰', '桂兰', '英', '梅',\n\t\t'莉', '秀珍', '雪', '依琳', '旭', '宁', '婷', '馨予', '玉珍', '凤英',\n\t\t'晶', '欢', '玉英', '颖', '红梅', '佳', '倩', '琴', '兰英', '云',\n\t\t'洁', '爱华', '淑珍', '春梅', '海燕', '晨', '冬梅', '秀荣', '瑞', '桂珍',\n\t\t'莹', '秀云', '桂荣', '秀梅', '丽娟', '婷婷', '玉华', '琳', '雪梅', '淑兰',\n\t\t'丽丽', '玉', '秀芳', '欣', '淑英', '桂芳', '丽华', '丹丹', '桂香', '淑华',\n\t\t'秀华', '桂芝', '小红', '金凤', '文', '利', '楠', '红霞', '瑜', '桂花',\n\t\t'璐', '凤兰', '腊梅', '瑶', '嘉', '怡', '冰冰', '玉梅', '慧', '婕'\n\t];\n\treturn getFirstName(false, ex) + getRnd(data, false, ex);\n}\n\n/** 男生名 */\nfunction getMaleName(isNullable = false, ex = '') {\n\tif (getNullable(isNullable)) return '';\n\n\tlet data = ['伟', '强', '磊', '洋', '勇', '军', '杰', '涛', '超', '明',\n\t\t'刚', '平', '辉', '鹏', '华', '飞', '鑫', '波', '斌', '宇',\n\t\t'浩', '凯', '健', '俊', '帆', '帅', '旭', '宁', '龙', '林',\n\t\t'欢', '阳', '建华', '亮', '成', '畅', '建', '峰', '建国', '建军',\n\t\t'晨', '瑞', '志强', '兵', '雷', '东', '欣', '博', '彬', '坤',\n\t\t'全安', '荣', '岩', '杨', '文', '利', '楠', '建平', '嘉俊', '晧',\n\t\t'建明', '子安', '新华', '鹏程', '学明', '博涛', '捷', '文彬', '楼', '鹰',\n\t\t'松', '伦', '超', '钟', '瑜', '振国', '洪', '毅', '昱然', '哲',\n\t\t'翔', '翼', '祥', '国庆', '哲彦', '正诚', '正豪', '正平', '正业', '志诚',\n\t\t'志新', '志勇', '志明', '志强', '志文', '致远', '智明', '智勇', '智敏', '智渊'\n\t];\n\treturn getFirstName(false, ex) + getRnd(data, false, ex);\n}\n\n/** 随机获得姓名 */\nfunction getName(isNullable = false, ex = '') {\n\tif (getNullable(isNullable)) return '';\n\n\tlet rd = Math.round(Math.random());\n\treturn (rd % 2 == 0) ? getFemaleName(false, ex) : getMaleName(false, ex);\n}\n\n/** 身份证号码 */\nfunction getIdCard(birthday = '', isNullable = false) {\n\tif (getNullable(isNullable)) return '';\n\n\tlet coefficientArray = [\"7\", \"9\", \"10\", \"5\", \"8\", \"4\", \"2\", \"1\", \"6\", \"3\", \"7\", \"9\", \"10\", \"5\", \"8\", \"4\", \"2\"]; // 加权因子\n\tlet lastNumberArray = [\"1\", \"0\", \"X\", \"9\", \"8\", \"7\", \"6\", \"5\", \"4\", \"3\", \"2\"]; // 校验码\n\tlet address = \"420101\"; // 住址\n\n\tif (!birthday)\n\t\tbirthday = \"19810101\"; // 生日\n\n\tlet s = Math.floor(Math.random() * 10).toString() + Math.floor(Math.random() * 10).toString() + Math.floor(Math.random() * 10).toString();\n\tlet array = (address + birthday + s).split(\"\");\n\tlet total = 0;\n\tfor (i in array) {\n\t\ttotal = total + parseInt(array[i]) * parseInt(coefficientArray[i]);\n\t}\n\tlet lastNumber = lastNumberArray[parseInt(total % 11)];\n\tlet str = address + birthday + s + lastNumber;\n\treturn str;\n\n}\n\n/** 手机号码 */\nfunction getMobile(isNullable = false, ex = '') {\n\n\tif (getNullable(isNullable)) return '';\n\n\tlet data = ['133', '149', '153', '173', '177', '180', '181', '189', '190', '191', '193', '199', '130', '131', '132', '145', '155', '156', '166', '167', '171', '175', '176', '185', '186', '196', '134', '135', '136', '137', '138', '139', '147', '148', '150', '151', '152', '157', '158', '159', '172', '178', '182', '183', '184', '187', '188', '195', '197', '198'];\n\n\treturn getRnd(data, false, ex) + getInt(8);\n}\n\n/** 电话号码 */\nfunction getPhone(isNullable = false, ex = '') {\n\n\tif (getNullable(isNullable)) return '';\n\n\tlet data = ['010', '021', '022', '023', '020', '024', '025', '027', '028', '029', '0755', '0731', '0769'];\n\n\treturn getRnd(data, false, ex) + '-' + getInt(8);\n}\n\n/** 常用英文单词 */\nfunction getEnWord(isNullable = false, ex = '') {\n\tlet data = 'earthday,org,suggests,that,every,household,take,time,this,earth,day,to,perform,a,plastic,audit,which,involves,counting,how,many,plastic,containers,wraps,bottles,and,bags,are,purchased,for,at,home,use,it,may,surprise,you,how,many,you,use,until,you,start,counting,while,were,not,saying,that,you,have,to,get,rid,of,every,single,ounce,of,plastic,in,your,home,it,is,important,to,be,aware,of,your,familys,plastic,usage,and,to,take,time,to,research,more,sustainable,products,and,start,to,incorporate,them,into,your,daily,life,simple,swaps2,like,glass,containers,instead,of,plastic,or,stainless3,steel,bottles,instead,of,single,use,plastics,can,go,a,long,way,to,making,a,difference';\n\n\treturn getRnd(data, isNullable, ex);\n}\n\n/** 常用域名 */\nfunction getDomain(isNullable = false, ex = '') {\n\n\tif (getNullable(isNullable)) return '';\n\n\tlet data = 'com,net,org,cn,hk,us,uk,jp,kr';\n\n\treturn '.' + getRnd(data, false, ex);\n}\n\n/** 常用邮箱 */\nfunction getEmail(isNullable = false, ex = '') {\n\tif (getNullable(isNullable)) return '';\n\n\tlet data = 'qq.com,163.com,gmail.com,263.com,tom.com,163.net,189.cn,sina.com,sohu.com,360.com,tencent.com,china.com,netease.com,126.com,139.com';\n\n\treturn getEnWord() + '@' + getRnd(data, false, ex);\n}\n\n/** 获取时间戳 step 秒 */\nfunction getTimestamp(step = 0) {\n\treturn timeUtil.time() + step * 1000;\n}\n\n/**\n * 以当天为基点，获取随机时间戳，默认为当天\n * @param {*} min  起始天\n * @param {*} max  终止天\n */\nfunction getAddTimestamp(min = 0, max = 1) {\n\tlet now = timeUtil.timestamp2Time(timeUtil.time(), 'Y-M-D'); //转为当天0点\n\tnow = timeUtil.time2Timestamp(now);\n\treturn now + getIntBetween(min * 86400 * 1000, max * 86400 * 1000);\n}\n\n/** 生日 */\nfunction getDate(start = 1900, end = 2020) {\n\n\tstart = start + '-01-01 00:00:00';\n\tstart = timeUtil.time2Timestamp(start);\n\n\tend = end + '-12-31 23:59:59';\n\tend = timeUtil.time2Timestamp(end);\n\n\tlet time = getIntBetween(start, end);\n\n\treturn timeUtil.timestamp2Time(time, 'Y-M-D');\n}\n\n/** 整数 */\nfunction getInt(size) {\n\tlet t = '';\n\tfor (var i = 0; i < size; i++) {\n\t\tt += Math.floor(Math.random() * 10);\n\t}\n\treturn t;\n}\n\n/** 随机数组 */\nfunction getRdArr(arr) {\n\treturn getRnd(arr);\n}\n\n/** 随机数 */\nfunction getIntBetween(min, max) {\n\treturn min + Math.floor(Math.random() * (max - min + 1));\n}\n\n/** 随机字符串 */\nfunction getStr(size) {\n\n\tlet text = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n\tlet rdmIndex = text => Math.random() * text.length | 0;\n\tlet rdmString = '';\n\tfor (; rdmString.length < size; rdmString += text.charAt(rdmIndex(text)));\n\treturn rdmString;\n\n}\n\n/** 随机数字字符串 */\nfunction getIntStr(size) {\n\n\tlet text = '0123456789';\n\tlet rdmIndex = text => Math.random() * text.length | 0;\n\tlet rdmString = '';\n\tfor (; rdmString.length < size; rdmString += text.charAt(rdmIndex(text)));\n\treturn String(rdmString);\n\n}\n\n/** 随机字符串小写 */\nfunction getStrLower(size) {\n\treturn getStr(size).toLowerCase();\n}\n\n/** 随机字符串大写 */\nfunction getStrUpper(size) {\n\treturn getStr(size).toUpperCase();\n}\n\nfunction getUuid() {\n\tlet s = [];\n\tlet hexDigits = \"0123456789abcdef\";\n\tfor (var i = 0; i < 36; i++) {\n\t\ts[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);\n\t}\n\ts[14] = \"4\"; // bits 12-15 of the time_hi_and_version field to 0010\n\ts[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01\n\ts[8] = s[13] = s[18] = s[23] = \"-\";\n\n\tlet uuid = s.join(\"\");\n\treturn uuid;\n}\n\n/** 学院 */\nfunction getCollege(isNullable = false, ex = '') {\n\tlet data = '地球科学学院,环境科学与工程学院,化学与生物工程学院,材料科学与工程学院,土木与建筑工程学院,测绘地理信息学院,信息科学与工程学院,机械与控制工程学院,珠宝学院,马克思主义学院,公共管理与传媒学院,商学院,旅游与风景园林学院,艺术学院,外国语学院,理学院,文学与新闻传播学院,外国语学院,建筑与艺术学院,商学院,法学院,马克思主义学院,公共管理学院,数学与统计学院,物理与电子学院,化学化工学院,文学系,法学系,哲学系,医学系,力学系,理学系,数学系,物理系,化学系,计算机系,自动化系,口腔医学系,英语系,外语系,法语系,德语系,日语系,西班牙语系';\n\n\treturn getRnd(data, isNullable, ex);\n}\n\n/** 专业 */\nfunction getItem(isNullable = false, ex = '') {\n\tlet data = '音乐表演,音乐学,作曲与作曲技术理论,舞蹈表演,舞蹈学,舞蹈编导,舞蹈教育,航空服务艺术与管理,流行音乐,音乐治疗,流行舞蹈,表演,戏剧学,电影学,戏剧影视文学,广播电视编导,戏剧影视导演,戏剧影视美术设计,录音艺术,播音与主持艺术,动画,美术学,绘画,雕塑,摄影,书法学,中国画,实验艺术,跨媒体艺术,文物保护与修复,漫画,艺术设计学,视觉传达设计,环境设计,产品设计,服装与服饰设计,公共艺术,工艺美术,数字媒体艺术,艺术与科技,陶瓷艺术设计,新媒体设计,包装设计,教育学,科学教育,人文教育,教育技术学,艺术教育,学前教育,小学教育,特殊教育,华文教育,教育康复学,卫生教育,法学,知识产权,监狱学,信用风险管理与法律防控,国际经贸规则,司法警察学,社区矫正,工商管理,市场营销,会计学,财务管理,国际商务,人力资源管理,审计学,资产评估,物业管理,文化产业管理,劳动关系,体育经济与管理,财务会计教育,市场营销教育,零售业管理,农林经济管理,农村区域发展 ,公共事业管理,行政管理,劳动与社会保障,土地资源管理,城市管理,海关管理,交通管理,海事管理,公共关系学,健康服务与管理,海警后勤管理,数学与应用数学,信息与计算科学,数理基础科学,数据计算及应用 ,物理学,应用物理学,核物理,声学,系统科学与工程,地理科学,自然地理与资源环境,人文地理与城乡规划,地理信息科学 ,机械设计制造及其自动化,材料成型及控制工程,机械电子工程,工业设计,过程装备与控制工程,车辆工程,汽车服务工程,机械工艺技术,微机电系统工程,机电技术教育,汽车维修工程教育,智能制造工程,材料科学与工程材料物理,材料化学,冶金工程,金属材料工程,无机非金属材料工程,高分子材料与工程,复合材料与工程,粉体材料科学与工程,宝石及材料工艺学,焊接技术与工程,功能材料,纳米材料与技术,新能源材料与器件,材料设计科学与工程,光电信息科学与工程,信息工程,广播电视工程,水声工程,电子封装技术,集成电路设计与集成系统,医学信息工程,电磁场与无线技术,电波传播与天线,电子信息科学与技术,电信工程及管理,应用电子技术教育,数字媒体技术,智能科学与技术,空间信息与数字技术,电子与计算机工程,数据科学与大数据技术,网络空间安全,新媒体技术,电影制作,保密技术,服务科学与工程,虚拟现实技术,区块链工程,建筑环境与能源应用工程,给排水科学与工程,建筑电气与智能化,城市地下空间工程,道路桥梁与渡河工程,铁道工程,智能建造,土木、水利与海洋工程,土木、水利与交通工程,采矿工程,石油工程,矿物加工工程,油气储运工程,矿物资源工程,海洋油气工程 ,纺织工程,服装设计与工程,非织造材料与工程,服装设计与工艺教育,丝绸设计与工程';\n\n\treturn getRnd(data, isNullable, ex);\n}\n\n/** 行业 */\nfunction getTrade(isNullable = false, ex = '') {\n\tlet data = ['经营', '销售', '市场营销', '公关', '客户服务', '人力资源', '行政HR', '财务/审计/统计', '文职', '翻译', '计算机/IT', '电子/通讯', '设计', '工业/工厂', '金融/经济', '法律', '机械', '技工', '房地产/土建', '咨询/顾问', '医疗/护理/保健', '服务业', '政府机关', '事业单位', '学生/研究生', '化工', '冶金/地质'];\n\n\treturn getRnd(data, isNullable, ex);\n}\n\n/** 学历 */\nfunction getEdu(isNullable = false, ex = '') {\n\tlet data = '中学,高职,大专,本科,硕士,博士,博士后,其他';\n\n\treturn getRnd(data, isNullable, ex);\n}\n\n/** 职位 */\nfunction getDuty(isNullable = false, ex = '') {\n\tlet data = 'CTO,CEO,CFO,研发,销售,采购,董事长,老板,自由自由者,中层领导,部门经理,大区经理';\n\n\treturn getRnd(data, isNullable, ex);\n}\n\n/** 资源 */\nfunction getResource(isNullable = false, ex = '') {\n\tlet data = '法律咨询,管理咨询,企业辅导,上市辅导,创业交流,投资融资,医疗咨询,教育交流,开发技术交流,研发交流,未来探讨,大宗商品,销售网络共享,艺术品鉴赏,供应链共享,进修交流,财会督导,审计辅导,企业治理,工程监理,硬件生产,小商品生产,电商,二类电商,早教,公考,艺术设计,人力资源,地质勘探,招工招聘,游戏开发,销售采购,市场营销,电子通讯,经济探讨,机械制造,产业经理,轻工业,化工化学,海外电商,企业出海,翻译,心理咨询,餐饮酒店,民宿,旅游自驾,服务业,租车,自媒体新媒体行业,文职人员,军迷,学习共勉,体育活动,打球约饭,户外旅行,文艺青年,小镇青年,斜杠青年,交通运输,民航机票,系统集成,售前服务,维修';\n\n\treturn getRnd(data, isNullable, ex);\n}\n\n/** 自我介绍 */\nfunction getMotto(isNullable = false, ex = '') {\n\tlet data = '生无一锥土，常有四海心 ,志在山顶的人，不会贪念山腰的风景 ,人之所以能，是相信能 ,卒子过河，意在吃帅 ,心志要坚，意趣要乐 ,贫困教会贫困者一切 ,欲望以提升热忱，毅力以磨平高山 ,人生不得行胸怀，虽寿百岁犹为无也 ,人之所以异于禽者，唯志而已矣！,每一发奋努力的背后，必有加倍的赏赐 ,治天下者必先立其志 ,以天下为己任 ,一人立志，万夫莫敌 ,志高山峰矮，路从脚下伸 ,鹰爱高飞，鸦栖一枝 ,莫为一身之谋，而有天下之志 ,人之所以能，是相信能,励志短语,没有天生的信心，只有不断培养的信心 ,世上没有绝望的处境，只有对处境绝望的人 ,人格的完善是本，财富的确立是末 ,在年轻人的颈项上，没有什么东西能比事业心这颗灿烂的宝珠 ,壮志与毅力是事业的双翼 ,心有多大，舞台就有多大 ,志正则众邪不生 ,母鸡的理想不过是一把糠 ,死犹未肯输心去，贫亦其能奈我何！,鸟贵有翼，人贵有志 ,有志登山顶，无志站山脚 ,没有一种不通过蔑视忍受和奋斗就可以征服的命运 ,远大的希望造就伟大的人物 ,志不立，天下无可成之事 ,有志者能使石头长出青草来 ,莫找借口失败，只找理由成功 ,男子千年志，吾生未有涯 ,鱼跳龙门往上游 ,有志者，事竟成  ,强行者有志 ,心随朗月高，志与秋霜洁 ,与其当一辈子乌鸦，莫如当一次鹰 ,石看纹理山看脉，人看志气树看材 ,志当存高远 ,任何的限制，都是从自己的内心开始的 ,志，气之帅也 ,一个人如果胸无大志，既使再有壮丽的举动也称不上是伟人  ,立志是事业的大门，工作是登门入室的旅程 ,志气和贫困是患难兄弟，世人常见他们伴在一起 ,失败是成功之母 ,对的，坚持；错的，放弃！,丈夫志不大，何以佐乾坤 ,鸭仔无娘也长大，几多白手也成家  ,我走得很慢，但是我从来不会后退,面对太阳，阴影将落在你的背后,困境之中，饱含机遇,执着于理想，纯粹于当下,不要轻言放弃，否则对不起自己,含泪播种的人一定能含笑收获,日益努力，而后风生水起,若要梦想实现，先从梦中醒来,今天比昨天好，就是希望,希望叫醒你的不是闹钟而是理想,坚定信念的人都是英雄,欲戴皇冠，必承其重,昨日之深渊，来日之浅谈,天越黑，星星越亮,岂能尽如人意，但求无愧我心,世上没什么运气，只有努力去挑战,日出之美便在于它脱胎于最深的黑暗,不要等待机会，而要创造机会,成功的秘诀在于对目标的执着追求,我把苦难挫折当作自己生存的最好导师,黑夜无论怎样悠长，白昼总会到来,海到无边天作岸，山登绝顶我为峰,除了放弃尝试以外没有失败,有梦就别怕痛，想赢就别喊停, 与其羡慕别人，不如自己努力,努力就能成功，坚持确保胜利,永不言败，是成功者的最佳品格,人生没有彩排，每天都是现场直播,火把倒下，火焰依然向上,低头哭过别忘了抬头继续走,有种脾气叫不放弃,风乍起，合当奋意向人生,莫问收获，但问耕耘,即使身在生活，也要做你理想的卧底,我只身前行，却仿佛带着一万雄兵,熬过一切，星光璀璨,没有人帮你，说明你一个人可以,让理想生活的样子清晰可见,趁我们头脑发热，我们要不顾一切,念念不忘，必有回响,一生很短，你要大胆,容易走的路，一般都很拥挤,那些杀不死我们的，终将让我们更强大,你利用时间的方式，就是塑造自己的方式,每一个不曾起舞的日子，都是对生命的辜负,猛兽总是独行，牛羊才成群结队,你迷茫的原因在于读书太少而想的太多,对未来真正的慷慨，是把一切献给现在,没有一点儿疯狂，生活就不值得过,生活在阴沟里，但仍有人仰望星空,怕输的人已经输了,不要忘记人生是要战斗到死, 抱怨身处黑暗，不如提灯前行,患难困苦，是磨炼人格之高等学校,失败不是悲剧，放弃才是,画工须画云中龙，为人须为人中雄,博观而约取，厚积而薄发,志在山顶的人，不会贪恋山腰的风景,别为失败找理由，要为成功找方法,迷失的时候，选择更艰辛的那条路,命是弱者的借口，运是强者的谦词,如果今天不走的话，明天就要跑,今天度过的一天明天就找不回来了,生活绝不会因为你胆小怯懦而饶过你,最可怕的敌人，就是没有坚强的信念,梦想一旦被付诸行动，就会变得神圣,寄言燕雀莫相唣，自有云霄万里高,人若有志，万事可为,志不可一日坠，人不可一日放,苦难，是化了妆的祝福,没有实力的愤怒毫无意义,在避风的港湾里，找不到昂扬的帆,大胆的尝试只等于成功了一半,天才就是无止境刻苦勤奋的能力,你是自己人生的设计师,苦想没盼头，苦干有奔头,世界会向那些有目标和远见的人让路,挫折其实就是迈向成功所应缴的学费,欲望以提升热忱，毅力以磨平高山,用行动祈祷比用言语更能够使上帝了解,志不立，天下无可成之事,志向和热爱是伟大行为的双翼,水激石则鸣，人激志则宏,雄心壮志是茫茫黑夜中的北斗星,贫而懒惰乃真穷，贱而无志乃真贱,目标越接近，困难越增加,绳锯木断，水滴石穿,男儿不展风云志，空负天生八尺躯,天才就是无止境刻苦勤奋的能力,苦难是人生的老师,成功的秘诀，在永不改变既定的目的,平凡的脚步也可以走完伟大的行程,如果你有梦想的话，就要去捍卫它,永远要面对眼前的这些困境,如果我放弃，就是向那些错看我的人屈服,运气，就是机会碰巧撞到了你的努力,哪有什么胜利可言，挺住就意味着一切,过去属于死神，未来属于你自己,失败是坚忍的最后考验,流水在碰到底处时才会释放活力';\n\n\treturn getRnd(data, isNullable, ex);\n}\n\n/** 用户头像 */\nfunction getAvatar(isNullable) {\n\tif (getNullable(isNullable)) return '';\n\n\treturn 'https://7265-release-7g51ulsq6451a0a6-1304820041.tcb.qcloud.la/mini/user_pic/' + getIntBetween(1, 200) + '.jpg';\n}\n\n\n/** 是否为空 */\nfunction getNullable(isNullable) {\n\tif (!isNullable) return false;\n\n\tlet rd = getIntBetween(0, 1);\n\tif (rd % 2 == 0)\n\t\treturn true;\n\telse\n\t\treturn false;\n}\n\n\n\n\n\nmodule.exports = {\n\tgetUuid,\n\tgetRnd,\n\n\tgetIdCard,\n\n\tgetProvince,\n\tgetProvinceAbbr,\n\n\tgetCity,\n\tgetArea,\n\tgetCountry,\n\tgetStreet,\n\tgetAddress,\n\n\tgetCompany,\n\tgetCompanyPrefix,\n\tgetResource,\n\tgetMotto,\n\n\tgetContent,\n\tgetWord,\n\n\tgetWeek,\n\tgetMonth,\n\tgetTimestamp,\n\tgetAddTimestamp,\n\n\tgetFirstName,\n\tgetFemaleName,\n\tgetMaleName,\n\tgetName,\n\n\tgetInt,\n\tgetRdArr,\n\tgetIntBetween,\n\tgetIntStr,\n\tgetStr,\n\tgetStrLower,\n\tgetStrUpper,\n\n\tgetMobile,\n\tgetPhone,\n\n\tgetEnWord,\n\tgetEmail,\n\tgetDomain,\n\n\tgetDate,\n\n\tgetItem,\n\tgetCollege,\n\tgetTrade,\n\tgetEdu,\n\tgetDuty,\n\n\tgetAvatar\n}"
  },
  {
    "path": "cloudfunctions/mcloud/framework/lib/md5_lib.js",
    "content": "/**\n * Notes: MD5类库\n * Ver : CCMiniCloud Framework 2.15.1 ALL RIGHTS RESERVED BY cClinux0730 (wechat)\n * Date: 2021-03-01 14:00:00 \n */\n\nfunction safe_add(x, y) {\n\tvar lsw = (x & 0xFFFF) + (y & 0xFFFF)\n\tvar msw = (x >> 16) + (y >> 16) + (lsw >> 16)\n\treturn (msw << 16) | (lsw & 0xFFFF)\n}\n\n/*\n * Bitwise rotate a 32-bit number to the left.\n */\nfunction rol(num, cnt) {\n\treturn (num << cnt) | (num >>> (32 - cnt))\n}\n\n/*\n * These functions implement the four basic operations the algorithm uses.\n */\nfunction cmn(q, a, b, x, s, t) {\n\treturn safe_add(rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b)\n}\n\nfunction ff(a, b, c, d, x, s, t) {\n\treturn cmn((b & c) | ((~b) & d), a, b, x, s, t)\n}\n\nfunction gg(a, b, c, d, x, s, t) {\n\treturn cmn((b & d) | (c & (~d)), a, b, x, s, t)\n}\n\nfunction hh(a, b, c, d, x, s, t) {\n\treturn cmn(b ^ c ^ d, a, b, x, s, t)\n}\n\nfunction ii(a, b, c, d, x, s, t) {\n\treturn cmn(c ^ (b | (~d)), a, b, x, s, t)\n}\n\n/*\n * Calculate the MD5 of an array of little-endian words, producing an array\n * of little-endian words.\n */\nfunction coreMD5(x) {\n\tvar a = 1732584193\n\tvar b = -271733879\n\tvar c = -1732584194\n\tvar d = 271733878\n\n\tfor (var i = 0; i < x.length; i += 16) {\n\t\tvar olda = a\n\t\tvar oldb = b\n\t\tvar oldc = c\n\t\tvar oldd = d\n\n\t\ta = ff(a, b, c, d, x[i + 0], 7, -680876936)\n\t\td = ff(d, a, b, c, x[i + 1], 12, -389564586)\n\t\tc = ff(c, d, a, b, x[i + 2], 17, 606105819)\n\t\tb = ff(b, c, d, a, x[i + 3], 22, -1044525330)\n\t\ta = ff(a, b, c, d, x[i + 4], 7, -176418897)\n\t\td = ff(d, a, b, c, x[i + 5], 12, 1200080426)\n\t\tc = ff(c, d, a, b, x[i + 6], 17, -1473231341)\n\t\tb = ff(b, c, d, a, x[i + 7], 22, -45705983)\n\t\ta = ff(a, b, c, d, x[i + 8], 7, 1770035416)\n\t\td = ff(d, a, b, c, x[i + 9], 12, -1958414417)\n\t\tc = ff(c, d, a, b, x[i + 10], 17, -42063)\n\t\tb = ff(b, c, d, a, x[i + 11], 22, -1990404162)\n\t\ta = ff(a, b, c, d, x[i + 12], 7, 1804603682)\n\t\td = ff(d, a, b, c, x[i + 13], 12, -40341101)\n\t\tc = ff(c, d, a, b, x[i + 14], 17, -1502002290)\n\t\tb = ff(b, c, d, a, x[i + 15], 22, 1236535329)\n\n\t\ta = gg(a, b, c, d, x[i + 1], 5, -165796510)\n\t\td = gg(d, a, b, c, x[i + 6], 9, -1069501632)\n\t\tc = gg(c, d, a, b, x[i + 11], 14, 643717713)\n\t\tb = gg(b, c, d, a, x[i + 0], 20, -373897302)\n\t\ta = gg(a, b, c, d, x[i + 5], 5, -701558691)\n\t\td = gg(d, a, b, c, x[i + 10], 9, 38016083)\n\t\tc = gg(c, d, a, b, x[i + 15], 14, -660478335)\n\t\tb = gg(b, c, d, a, x[i + 4], 20, -405537848)\n\t\ta = gg(a, b, c, d, x[i + 9], 5, 568446438)\n\t\td = gg(d, a, b, c, x[i + 14], 9, -1019803690)\n\t\tc = gg(c, d, a, b, x[i + 3], 14, -187363961)\n\t\tb = gg(b, c, d, a, x[i + 8], 20, 1163531501)\n\t\ta = gg(a, b, c, d, x[i + 13], 5, -1444681467)\n\t\td = gg(d, a, b, c, x[i + 2], 9, -51403784)\n\t\tc = gg(c, d, a, b, x[i + 7], 14, 1735328473)\n\t\tb = gg(b, c, d, a, x[i + 12], 20, -1926607734)\n\n\t\ta = hh(a, b, c, d, x[i + 5], 4, -378558)\n\t\td = hh(d, a, b, c, x[i + 8], 11, -2022574463)\n\t\tc = hh(c, d, a, b, x[i + 11], 16, 1839030562)\n\t\tb = hh(b, c, d, a, x[i + 14], 23, -35309556)\n\t\ta = hh(a, b, c, d, x[i + 1], 4, -1530992060)\n\t\td = hh(d, a, b, c, x[i + 4], 11, 1272893353)\n\t\tc = hh(c, d, a, b, x[i + 7], 16, -155497632)\n\t\tb = hh(b, c, d, a, x[i + 10], 23, -1094730640)\n\t\ta = hh(a, b, c, d, x[i + 13], 4, 681279174)\n\t\td = hh(d, a, b, c, x[i + 0], 11, -358537222)\n\t\tc = hh(c, d, a, b, x[i + 3], 16, -722521979)\n\t\tb = hh(b, c, d, a, x[i + 6], 23, 76029189)\n\t\ta = hh(a, b, c, d, x[i + 9], 4, -640364487)\n\t\td = hh(d, a, b, c, x[i + 12], 11, -421815835)\n\t\tc = hh(c, d, a, b, x[i + 15], 16, 530742520)\n\t\tb = hh(b, c, d, a, x[i + 2], 23, -995338651)\n\n\t\ta = ii(a, b, c, d, x[i + 0], 6, -198630844)\n\t\td = ii(d, a, b, c, x[i + 7], 10, 1126891415)\n\t\tc = ii(c, d, a, b, x[i + 14], 15, -1416354905)\n\t\tb = ii(b, c, d, a, x[i + 5], 21, -57434055)\n\t\ta = ii(a, b, c, d, x[i + 12], 6, 1700485571)\n\t\td = ii(d, a, b, c, x[i + 3], 10, -1894986606)\n\t\tc = ii(c, d, a, b, x[i + 10], 15, -1051523)\n\t\tb = ii(b, c, d, a, x[i + 1], 21, -2054922799)\n\t\ta = ii(a, b, c, d, x[i + 8], 6, 1873313359)\n\t\td = ii(d, a, b, c, x[i + 15], 10, -30611744)\n\t\tc = ii(c, d, a, b, x[i + 6], 15, -1560198380)\n\t\tb = ii(b, c, d, a, x[i + 13], 21, 1309151649)\n\t\ta = ii(a, b, c, d, x[i + 4], 6, -145523070)\n\t\td = ii(d, a, b, c, x[i + 11], 10, -1120210379)\n\t\tc = ii(c, d, a, b, x[i + 2], 15, 718787259)\n\t\tb = ii(b, c, d, a, x[i + 9], 21, -343485551)\n\n\t\ta = safe_add(a, olda)\n\t\tb = safe_add(b, oldb)\n\t\tc = safe_add(c, oldc)\n\t\td = safe_add(d, oldd)\n\t}\n\treturn [a, b, c, d]\n}\n\n/*\n * Convert an array of little-endian words to a hex string.\n */\nfunction binl2hex(binarray) {\n\tvar hex_tab = \"0123456789abcdef\"\n\tvar str = \"\"\n\tfor (var i = 0; i < binarray.length * 4; i++) {\n\t\tstr += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF) +\n\t\t\thex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF)\n\t}\n\treturn str\n}\n\n/*\n * Convert an array of little-endian words to a base64 encoded string.\n */\nfunction binl2b64(binarray) {\n\tvar tab = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\"\n\tvar str = \"\"\n\tfor (var i = 0; i < binarray.length * 32; i += 6) {\n\t\tstr += tab.charAt(((binarray[i >> 5] << (i % 32)) & 0x3F) |\n\t\t\t((binarray[i >> 5 + 1] >> (32 - i % 32)) & 0x3F))\n\t}\n\treturn str\n}\n\n/*\n * Convert an 8-bit character string to a sequence of 16-word blocks, stored\n * as an array, and append appropriate padding for MD4/5 calculation.\n * If any of the characters are >255, the high byte is silently ignored.\n */\nfunction str2binl(str) {\n\tvar nblk = ((str.length + 8) >> 6) + 1 // number of 16-word blocks\n\tvar blks = new Array(nblk * 16)\n\tfor (var i = 0; i < nblk * 16; i++) blks[i] = 0\n\tfor (var i = 0; i < str.length; i++)\n\t\tblks[i >> 2] |= (str.charCodeAt(i) & 0xFF) << ((i % 4) * 8)\n\tblks[i >> 2] |= 0x80 << ((i % 4) * 8)\n\tblks[nblk * 16 - 2] = str.length * 8\n\treturn blks\n}\n\n/*\n * Convert a wide-character string to a sequence of 16-word blocks, stored as\n * an array, and append appropriate padding for MD4/5 calculation.\n */\nfunction strw2binl(str) {\n\tvar nblk = ((str.length + 4) >> 5) + 1 // number of 16-word blocks\n\tvar blks = new Array(nblk * 16)\n\tfor (var i = 0; i < nblk * 16; i++) blks[i] = 0\n\tfor (var i = 0; i < str.length; i++)\n\t\tblks[i >> 1] |= str.charCodeAt(i) << ((i % 2) * 16)\n\tblks[i >> 1] |= 0x80 << ((i % 2) * 16)\n\tblks[nblk * 16 - 2] = str.length * 16\n\treturn blks\n}\n\n/*\n * External interface\n */\nfunction hexMD5(str) {\n\treturn binl2hex(coreMD5(str2binl(str)))\n}\n\nfunction hexMD5w(str) {\n\treturn binl2hex(coreMD5(strw2binl(str)))\n}\n\nfunction b64MD5(str) {\n\treturn binl2b64(coreMD5(str2binl(str)))\n}\n\nfunction b64MD5w(str) {\n\treturn binl2b64(coreMD5(strw2binl(str)))\n}\n/* Backward compatibility */\nfunction calcMD5(str) {\n\treturn binl2hex(coreMD5(str2binl(str)))\n}\nmodule.exports = {\n\tmd5: hexMD5\n}"
  },
  {
    "path": "cloudfunctions/mcloud/framework/lib/mini_lib.js",
    "content": "/**\n * Notes: 小程序封装类库\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cClinux0730 (wechat)\n * Date: 2020-09-06 14:00:00 \n */\nconst cloudBase = require('../cloud/cloud_base.js');\nconst cloudUtil = require('../cloud/cloud_util.js');\nconst config = require('../../config/config');\n\n\n// 消息长度截取\nfunction fmtThing(str) { //20个以内字符,可汉字、数字、字母或符号组合\n\treturn str.substr(0, 20);\n}\n\nfunction fmtCharacterString(str) { //32位以内数字、字母或符号\n\treturn str.substr(0, 32);\n}\n\nfunction fmtPhrase(str) { //5个以内汉字\n\treturn str.substr(0, 5);\n} \n\n/**\n * 发送一次性消息\n * @param {*} body \n * @param {*} key \n */\nasync function sendMiniOnceTempMsg(body, key = '') {\n\t//\tconsole.log('##sendOnceTempMsg[' + key + ']', body);\n\tlet cloud = cloudBase.getCloud();\n\ttry {\n\t\t// 默认参数\n\t\tbody.lang = 'zh_CN';\n\t\tbody.miniprogramState = 'formal';\n\n\t\tawait cloud.openapi.subscribeMessage.send(body);\n\t} catch (err) {\n\t\tcloudUtil.log('##sendOnceTempMsg[' + key + ']', err);\n\t}\n}\nmodule.exports = {\n\tsendMiniOnceTempMsg,\n\n\tfmtThing,\n\tfmtCharacterString,\n\tfmtPhrase\n}"
  },
  {
    "path": "cloudfunctions/mcloud/framework/platform/controller/base_admin_controller.js",
    "content": "/**\n * Notes: 后台管理控制器模块\n * Ver : CCMiniCloud Framework 2.0.3 ALL RIGHTS RESERVED BY cclinuX0730 (wechat)\n * Date: 2022-05-26 19:20:00 \n */\n\nconst BaseController = require('./base_controller.js');\nconst BaseAdminService = require('../service/base_admin_service.js');\nconst LogModel = require('../model/log_model.js');\n\nconst timeUtil = require('../../../framework/utils/time_util.js');\n\nclass BaseAdminController extends BaseController {\n\n\tconstructor(route, openId, event) {\n\t\tsuper(route, openId, event);\n\n\t\t// 当前时间戳\n\t\tthis._timestamp = timeUtil.time();\n\n\t\tthis._admin = null;\n\t\tthis._adminId = '0';\n\n\t}\n\n\t/** 是否管理员  */\n\tasync isAdmin() {\n\t\t// 判断是否管理员\n\t\tlet service = new BaseAdminService();\n\t\tlet admin = await service.isAdmin(this._token);\n\t\tthis._admin = admin;\n\t\tthis._adminId = admin._id;\n\t}\n\n\t/** 是否超级管理员  */\n\tasync isSuperAdmin() {\n\t\t// 判断是否管理员\n\t\tlet service = new BaseAdminService();\n\t\tlet admin = await service.isSuperAdmin(this._token);\n\t\tthis._admin = admin;\n\t\tthis._adminId = admin._id;\n\t}\n\n\t/** 记录日志 */\n\tasync log(content, type) {\n\t\tlet service = new BaseAdminService();\n\t\tawait service.insertLog(content, this._admin, type);\n\t}\n\n\tasync logSys(content) {\n\t\tawait this.log(content, LogModel.TYPE.SYS);\n\t}\n\n\tasync logUser(content) {\n\t\tawait this.log(content, LogModel.TYPE.USER);\n\t}\n\n\tasync logOther(content) {\n\t\tawait this.log(content, LogModel.TYPE.OTHER);\n\t}\n\n\tasync logNews(content) {\n\t\tawait this.log(content, LogModel.TYPE.NEWS);\n\t}\n\n}\n\nmodule.exports = BaseAdminController;"
  },
  {
    "path": "cloudfunctions/mcloud/framework/platform/controller/base_controller.js",
    "content": "/**\n * Notes: 基础控制器\n * Ver : CCMiniCloud Framework 2.0.4 ALL RIGHTS RESERVED BY cclinUx0730 (wechat)\n * Date: 2020-09-05 04:00:00 \n */\n\nconst config = require('../../../config/config.js');\nconst timeUtil = require('../../utils/time_util.js');\nconst util = require('../../utils/util.js');\nconst dataCheck = require('../../validate/data_check.js');\n\nconst AppError = require('../../core/app_error.js');\nconst appCode = require('../../core/app_code.js');\n\nclass BaseController {\n\n\tconstructor(route, openId, event) {\n\n\t\tthis._route = route; // 路由\n\t\tthis._openId = openId; //用户身份\n\t\tthis._event = event; // 所有参数   \n\t\tthis._request = event.params; //数据参数\n\n\t\tif (!openId) {\n\t\t\tconsole.error('OPENID is unfined');\n\t\t\tthrow new AppError('OPENID is unfined', appCode.SVR);\n\t\t}\n\n\t\tlet userId = openId;\n\n\t\tthis._token = event.token || '';\n\t\tthis._userId = userId;\n\n\t\t// 当前时间戳\n\t\tthis._timestamp = timeUtil.time();\n\t\tlet time = timeUtil.time('Y-M-D h:m:s');\n\n\t\tconsole.log('------------------------');\n\t\tconsole.log(`【${time}】【Request -- ↘↘↘】\\n【↘Token = ${this._token}】\\n【↘USER-ID = ${userId}】\\n【↘↘IN DATA】=\\n`, JSON.stringify(this._request, null, 4));\n\n\t}\n\n\t/**\n\t * 数据校验\n\t * @param {*} rules \n\t */\n\tvalidateData(rules = {}) {\n\t\tlet input = this._request;\n\t\treturn dataCheck.check(input, rules);\n\t}\n\n\t// 取得某个具体的参数值\n\tgetParameter(name) {\n\t\tlet input = this._request;\n\t\tif (util.isDefined(input[name]))\n\t\t\treturn input[name];\n\t\telse\n\t\t\treturn '';\n\t}\n}\n\nmodule.exports = BaseController;"
  },
  {
    "path": "cloudfunctions/mcloud/framework/platform/model/admin_model.js",
    "content": "/**\n * Notes: 系统管理员实体 \n * Date: 2021-03-15 19:20:00 \n * Ver : CCMiniCloud Framework 2.0.5 ALL RIGHTS RESERVED BY CCLINUX0730 (wechat)\n */\n\n\nconst BaseModel = require('./base_model.js');\n\nclass AdminModel extends BaseModel {\n\n}\n\n// 集合名\nAdminModel.CL = BaseModel.C('admin');\n\nAdminModel.DB_STRUCTURE = {\n\t_pid: 'string|true',\n\tADMIN_ID: 'string|true',\n\tADMIN_NAME: 'string|true', \n\tADMIN_DESC: 'string|true',\n\tADMIN_PHONE: 'string|false|comment=手机',\n\tADMIN_PASSWORD: 'string|true|comment=密码',\n\tADMIN_STATUS: 'int|true|default=1|comment=状态：0=禁用 1=启用',\n\n\tADMIN_LOGIN_CNT: 'int|true|default=0|comment=登录次数',\n\tADMIN_LOGIN_TIME: 'int|true|default=0|comment=最后登录时间',\n\tADMIN_TYPE: 'int|true|default=0|comment=类型 0=普通管理员 1=超级管理员',\n\n\tADMIN_TOKEN: 'string|false|comment=当前登录token',\n\tADMIN_TOKEN_TIME: 'int|true|default=0|comment=当前登录token time',\n\n\tADMIN_ADD_TIME: 'int|true',\n\tADMIN_EDIT_TIME: 'int|true',\n\tADMIN_ADD_IP: 'string|false',\n\tADMIN_EDIT_IP: 'string|false',\n};\n\n// 字段前缀\nAdminModel.FIELD_PREFIX = \"ADMIN_\";\n\n\n\n\n\n\nmodule.exports = AdminModel;"
  },
  {
    "path": "cloudfunctions/mcloud/framework/platform/model/base_model.js",
    "content": "/**\n * Notes: 实体基类 \n * Date: 2021-03-15 19:20:00 \n * Ver : CCMiniCloud Framework 2.0.6 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n */\n\n\nconst MultiModel = require('../../../framework/database/multi_model.js');\n\nclass BaseModel extends MultiModel {\n\n}\n\nmodule.exports = BaseModel;"
  },
  {
    "path": "cloudfunctions/mcloud/framework/platform/model/log_model.js",
    "content": "/**\n * Notes: 后台操作日志实体\n * Ver : CCMiniCloud Framework 2.0.7 ALL RIGHTS RESERVED BY cclinuX0730 (wechat)\n * Date: 2020-10-16 19:20:00 \n */\n\n\nconst BaseModel = require('./base_model.js');\n\nclass LogModel extends BaseModel {\n\n}\n\n// 集合名\nLogModel.CL = BaseModel.C('log');\n\nLogModel.DB_STRUCTURE = {\n\t_pid: 'string|true',\n\tLOG_ID: 'string|true',\n\n\tLOG_ADMIN_ID: 'string|true|comment=管理员',\n\tLOG_ADMIN_DESC: 'string|false',\n\tLOG_ADMIN_NAME: 'string|true',\n\n\tLOG_CONTENT: 'string|true',\n\n\tLOG_TYPE: 'int|true|comment=日志类型 ',\n\n\tLOG_ADD_TIME: 'int|true',\n\tLOG_EDIT_TIME: 'int|true',\n\tLOG_ADD_IP: 'string|false',\n\tLOG_EDIT_IP: 'string|false',\n};\n\n// 字段前缀\nLogModel.FIELD_PREFIX = \"LOG_\";\n\nLogModel.TYPE = {\n\tSYS: 0,\n\tUSER: 1,\n\tNEWS: 2,\n\tOTHER: 99,\n\n}\nLogModel.TYPE_DESC = {\n\tSYS: '系统',\n\tUSER: '用户',\n\tNEWS: '文章',\n\tOTHER: '其他',\n}\n\nmodule.exports = LogModel;"
  },
  {
    "path": "cloudfunctions/mcloud/framework/platform/service/base_admin_service.js",
    "content": "/**\n * Notes: 后台管理模块业务基类\n * Date: 2021-03-15 07:48:00 \n * Ver : CCMiniCloud Framework 2.0.8 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n */\n\nconst BaseService = require('./base_service.js');\n\nconst timeUtil = require('../../../framework/utils/time_util.js');\nconst appCode = require('../../../framework/core/app_code.js');\n\nconst config = require('../../../config/config.js');\n\nconst AdminModel = require('../model/admin_model.js');\nconst LogModel = require('../model/log_model.js'); \n\nclass BaseAdminService extends BaseService {\n\n\n\t/** 是否管理员 */\n\tasync isAdmin(token) {\n\n\t\tif (config.IS_DEMO) { // 演示版本\n\t\t\tlet admin = {};\n\t\t\tadmin.ADMIN_NAME = 'demo-admin';\n\t\t\tadmin.ADMIN_DESC = '体验用户';\n\t\t\tadmin.ADMIN_ID = '1';\n\t\t\tadmin.ADMIN_PHONE = '13900000000';\n\t\t\tadmin.ADMIN_LOGIN_CNT = 0;\n\t\t\tadmin.ADMIN_LOGIN_TIME = '';\n\t\t\tadmin.ADMIN_TYPE = 0;\n\t\t\tadmin.ADMIN_STATUS = 1;\n\t\t\treturn admin;\n\t\t}\n\n\t\tlet where = {\n\t\t\tADMIN_TOKEN: token,\n\t\t\tADMIN_TOKEN_TIME: ['>', timeUtil.time() - config.ADMIN_LOGIN_EXPIRE * 1000], // token有效时间\n\t\t\tADMIN_STATUS: 1,\n\t\t}\n\t\tlet admin = await AdminModel.getOne(where, 'ADMIN_ID,ADMIN_PHONE,ADMIN_NAME,ADMIN_TYPE,ADMIN_DESC');\n\t\tif (!admin)\n\t\t\tthis.AppError('管理员不存在', appCode.ADMIN_ERROR);\n\n\t\treturn admin;\n\t}\n\n\t/** 是否超级管理员 */\n\tasync isSuperAdmin(token) {\n\n\t\tlet where = {\n\t\t\tADMIN_TOKEN: token,\n\t\t\tADMIN_TOKEN_TIME: ['>', timeUtil.time() - config.ADMIN_LOGIN_EXPIRE * 1000], // token有效时间\n\t\t\tADMIN_STATUS: 1,\n\t\t\tADMIN_TYPE: 1\n\t\t}\n\t\tlet admin = await AdminModel.getOne(where, 'ADMIN_ID,ADMIN_PHONE,ADMIN_NAME,ADMIN_TYPE');\n\t\tif (!admin)\n\t\t\tthis.AppError('超级管理员不存在', appCode.ADMIN_ERROR);\n\n\t\treturn admin;\n\t}\n\n\t/** 写入日志 */\n\tasync insertLog(content, admin, type) {\n\t\tif (!admin) return;\n\n\t\tlet data = {\n\t\t\tLOG_CONTENT: content,\n\t\t\tLOG_ADMIN_ID: admin._id,\n\t\t\tLOG_ADMIN_NAME: admin.ADMIN_NAME,\n\t\t\tLOG_ADMIN_DESC: admin.ADMIN_DESC,\n\t\t\tLOG_TYPE: type\n\t\t}\n\t\tawait LogModel.insert(data);\n\t} \n\n}\n\nmodule.exports = BaseAdminService;"
  },
  {
    "path": "cloudfunctions/mcloud/framework/platform/service/base_service.js",
    "content": "/**\n * Notes: 基础业务逻辑\n * Ver : CCMiniCloud Framework 2.0.9 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-04-24 04:00:00 \n */\n\nconst AppError = require('../../core/app_error.js');\nconst appCode = require('../../core/app_code.js');\nconst timeUtil = require('../../utils/time_util.js');\n\nclass BaseService {\n\tconstructor() {\n\t\t// 当前时间戳\n\t\tthis._timestamp = timeUtil.time();\n\n\t}\n\n\t/**\n\t * 抛出异常\n\t * @param {*} msg \n\t * @param {*} code \n\t */\n\tAppError(msg, code = appCode.LOGIC) {\n\t\tthrow new AppError(msg, code);\n\t}\n\n\t/** 时期范围处理 */\n\tfmtSearchDate(where, search, field) {\n\t\tif (!search || search.length != 21 || !search.includes('#')) return where;\n\n\t\tlet arr = search.split('#');\n\t\tlet start = arr[0];\n\t\tlet end = arr[1];\n\t\twhere[field] = ['between', start, end];\n\t\treturn where;\n\t}\n\n\t/* 数据库字段排序处理 */\n\tfmtOrderBySort(sortVal, defaultSort) {\n\t\tlet orderBy = {\n\t\t\t[defaultSort]: 'desc'\n\t\t};\n\n\t\tif (sortVal.includes('|')) {\n\t\t\tlet field = sortVal.split('|')[0];\n\t\t\tlet order = sortVal.split('|')[1];\n\t\t\torderBy = {\n\t\t\t\t[field]: order,\n\t\t\t};\n\t\t\tif (defaultSort != field) orderBy[defaultSort] = 'desc';\n\t\t}\n\t\treturn orderBy;\n\t}\n\n}\n\nmodule.exports = BaseService;"
  },
  {
    "path": "cloudfunctions/mcloud/framework/utils/constant.js",
    "content": " /**\n * Notes: 通用常量定义\n * Ver : CCMiniCloud Framework 2.32.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-09-05 04:00:00 \n */\nmodule.exports = {\n \n}"
  },
  {
    "path": "cloudfunctions/mcloud/framework/utils/data_util.js",
    "content": "/**\n * Notes: 字符相关操作函数\n* Ver : CCMiniCloud Framework 2.33.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-09-05 04:00:00 \n */\n\nconst timeUtil = require('./time_util.js');\n\n/**\n * 生成一个特定范围内的随机数\n */\nconst genRandomNum = (min, max) => (Math.random() * (max - min + 1) | 0) + min;\n\n// 生成一个随机的数字字母字符串\nconst genRandomString = len => {\n\tconst text = 'abcdefghijklmnopqrstuvwxyz0123456789';\n\tconst rdmIndex = text => Math.random() * text.length | 0;\n\tlet rdmString = '';\n\tfor (; rdmString.length < len; rdmString += text.charAt(rdmIndex(text)));\n\treturn rdmString;\n}\n\n// 生成一个随机的数字字符串\nconst genRandomIntString = len => {\n\tconst text = '0123456789';\n\tconst rdmIndex = text => Math.random() * text.length | 0;\n\tlet rdmString = '';\n\tfor (; rdmString.length < len; rdmString += text.charAt(rdmIndex(text)));\n\treturn rdmString;\n}\n\n// 生成一个随机的字母字符串\nconst genRandomAlpha = len => {\n\tconst text = 'abcdefghijklmnopqrstuvwxyz';\n\tconst rdmIndex = text => Math.random() * text.length | 0;\n\tlet rdmString = '';\n\tfor (; rdmString.length < len; rdmString += text.charAt(rdmIndex(text)));\n\treturn rdmString;\n}\n\n// 根据数据库自定义表单提取导出表格标题\nfunction getTitleByForm(arr) {\n\tlet formTitle = [];\n\tfor (let k = 0; k < arr.length; k++) {\n\t\tif (arr.type == 'image' || arr.type == 'content') continue;\n\n\t\tformTitle.push({\n\t\t\tcolumn: arr[k].title,\n\t\t\twch: 30\n\t\t});\n\t}\n\treturn formTitle;\n}\n\n\n// 根据数据库自定义表单提取数据\nfunction getValByForm(arr, mark, title) {\n\tfor (let k = 0; k < arr.length; k++) {\n\n\t\tif (arr[k].mark == mark || arr[k].title == title) {\n\t\t\tif (arr[k].type == 'image') return '图片';\n\t\t\tif (arr[k].type == 'content') return '图文内容';\n\n\t\t\tif (arr[k].type == 'switch') {\n\t\t\t\tif (arr[k].val === true)\n\t\t\t\t\treturn '是';\n\t\t\t\telse\n\t\t\t\t\treturn '否';\n\t\t\t}\n\n\t\t\treturn arr[k].val;\n\t\t}\n\n\t}\n\n\treturn '';\n}\n\n// 数据库自定义表单forms值修正\nfunction dbFormsFix(forms) {\n\tfor (let k = 0; k < forms.length; k++) {\n\t\tif (forms[k].type == 'number' || forms[k].type == 'digit') {\n\t\t\tforms[k].val = Number(forms[k].val);\n\t\t\tif (isNaN(forms[k].val)) forms[k].val = null;\n\t\t}\n\t}\n\treturn forms;\n}\n\n// 数据库自定义表单forms转为obj\nfunction dbForms2Obj(forms, excludeContent = false) {\n\tforms = dbFormsFix(forms); //数据类型修正\n\n\tif (forms.length == 0) return { 'no': 'none' };\n\n\tlet obj = {};\n\tfor (let k = 0; k < forms.length; k++) {\n\t\tif (excludeContent && forms[k].type == 'content') continue;\n\t\tobj[forms[k].mark] = forms[k].val;\n\t}\n\treturn obj;\n}\n\n// 构造当前ID \nfunction makeID() {\n\tlet id = timeUtil.time('YMDhms') + ''; //秒\n\n\t//毫秒3位\n\tlet miss = timeUtil.time() % 1000 + '';\n\tif (miss.length == 0)\n\t\tmiss = '000';\n\telse if (miss.length == 1)\n\t\tmiss = '00' + miss;\n\telse if (miss.length == 2)\n\t\tmiss = '0' + miss;\n\n\treturn id + miss;\n}\n\n// 拆分一维数组为二维数组\nfunction spArr(arr, size) {\n\tif (!arr || !Array.isArray(arr) || arr.length == 0) return arr;\n\n\tlet newArray = [];\n\tlet index = 0;\n\twhile (index < arr.length) {\n\t\tnewArray.push(arr.slice(index, index += size));\n\t}\n\treturn newArray;\n}\n\n/**\n * 把字符串格式化为数组\n * @param {*} str \n * @param {*} sp \n */\nfunction str2Arr(str, sp = ',') {\n\tif (str && Array.isArray(str)) return str;\n\n\tstr = str.replace(/，/g, sp);\n\tlet arr = str.split(sp);\n\tfor (let i = 0; i < arr.length; i++) {\n\t\tarr[i] = arr[i].trim();\n\n\t\tif (isNumber(arr[i])) {\n\t\t\tarr[i] = Number(arr[i]);\n\t\t}\n\n\t}\n\treturn arr;\n}\n\n/**\n *  校验只要是数字（包含正负整数，0以及正负浮点数）就返回true \n * @param {*} val \n * @returns bool\n */\nfunction isNumber(val) {\n\tvar reg = /^[0-9]+.?[0-9]*$/;\n\tif (reg.test(val)) {\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n}\n\n/**\n * 提取对象数组的某个属性数组,如[{'x':1},{'x':2}] 提取 x得到[1,2]\n * @param {*} arr \n * @param {*} key \n * @returns []\n */\nfunction getArrByKey(arr, key) {\n\tif (!Array.isArray(arr)) return;\n\treturn arr.map((item) => {\n\t\treturn item[key]\n\t});\n}\n\n/**\n * 提取对象数组的多个属性数组, \n * 如 [{'x':1,'y':11,'z':111},{'x':2,'y':22,'z':222}] \n * 提取 ['x','y'] 得到[{'x':1,'y':11},{'x':2,'y':22}]\n * @param {*} arr \n * @param {*} keys \n * @returns []\n */\nfunction getArrByKeyMulti(arr, keys = []) {\n\tif (!Array.isArray(arr)) return;\n\tif (!Array.isArray(keys)) return;\n\n\tlet ret = [];\n\tfor (let k = 0; k < arr.length; k++) {\n\t\tlet node = {};\n\t\tfor (let j in keys) {\n\t\t\tnode[keys[j]] = arr[k][keys[j]];\n\t\t}\n\t\tret.push(node);\n\t}\n\n\treturn ret;\n}\n\n/**\n * 提取对象数组某个键值等于某值的对象数据\n * @param {*} arr \n * @param {*} key  \n * @param {*} val \n * @returns object {}\n */\nfunction getDataByKey(arr, key, val) {\n\tif (!Array.isArray(arr)) return null;\n\n\tfor (let k = 0; k < arr.length; k++) {\n\t\tif (arr[k][key] == val)\n\t\t\treturn arr[k];\n\t}\n\n\treturn null;\n}\n\n/**\n * 文本内容格式化处理\n * @param {*} content \n * @param {*} len 截取长度 -1不截取\n */\nfunction fmtText(content, len = -1) {\n\tif (!content) return content;\n\tlet str = content.replace(/[\\r\\n]/g, \"\"); //去掉回车换行\n\tif (len > 0) {\n\t\tstr = str.substr(0, len);\n\t}\n\treturn str.trim();\n}\n\n// 下划线转换驼峰\nfunction toHump(name) {\n\tname = name.replace(/\\_(\\w)/g, function (all, letter) {\n\t\treturn letter.toUpperCase();\n\t});\n\n\t// 首字母大写 \n\tlet firstChar = name.charAt(0).toUpperCase();\n\treturn firstChar + name.slice(1);\n}\n\n// 驼峰转换下划线\nfunction toLine(name) {\n\tname = name.replace(/([A-Z])/g, \"_$1\").toLowerCase();\n\n\t//如果首字符为下划线，干掉\n\tif (name.charAt(0) === '_')\n\t\treturn name.slice(1);\n\telse\n\t\treturn name;\n}\n\n// 金额格式化 dot为金额每隔三位用\",\"或\" \"间隔\nfunction fmtMoney(s, dot = ',', prefix = '¥') {\n\tif (s === '' || s === null || s === undefined) s = 0;\n\n\ts = parseFloat((s + \"\").replace(/[^\\d\\.-]/g, \"\")).toFixed(2) + \"\";\n\tvar l = s.split(\".\")[0].split(\"\").reverse(),\n\t\tr = s.split(\".\")[1];\n\tt = \"\";\n\tfor (i = 0; i < l.length; i++) {\n\t\tt += l[i] + ((i + 1) % 3 == 0 && (i + 1) != l.length ? dot : \"\");\n\t}\n\treturn prefix + t.split(\"\").reverse().join(\"\") + \".\" + r;\n}\n/**\n *简单数组转对象数组\n * @param {*} arr [1,2,3]\n * @param {*} key [x1,x2,x3]\n * @returns [{x1:1,x2:1,x3:1},{x1:2,x2:2,x3:2},{x1:3,x2:3,x3:3}]\n */\nfunction arr2ObjectArr(arr, key1, key2, key3) {\n\tlet ret = [];\n\tfor (let k = 0; k < arr.length; k++) {\n\t\tlet obj = {};\n\t\tif (key1) obj[key1] = arr[k];\n\t\tif (key2) obj[key2] = arr[k];\n\t\tif (key3) obj[key3] = arr[k];\n\t\tret.push(obj);\n\t}\n\treturn ret;\n}\n\n/**\n * property\n * @param {*} property 排序属性\n * @returns 排序好的数组 \n * 用法 arr.sort(compare('age'))\n */\nfunction objArrSortAsc(property) {\n\treturn function (a, b) {\n\t\tvar value1 = a[property];\n\t\tvar value2 = b[property];\n\t\tif (value1 < value2)\n\t\t\treturn -1;\n\t\telse if (value1 > value2)\n\t\t\treturn 1;\n\t\telse return 0;\n\t}\n}\n\n/**\n * property\n * @param {*} property 排序属性\n * @returns 排序好的数组 \n * 用法 arr.sort(compare('age'))\n */\nfunction objArrSortDesc(property) {\n\treturn function (a, b) {\n\t\tvar value1 = a[property];\n\t\tvar value2 = b[property];\n\t\tif (value1 < value2)\n\t\t\treturn 1;\n\t\telse if (value1 > value2)\n\t\t\treturn -1;\n\t\telse return 0;\n\t}\n}\n\n/**\n * 数组有则减少，无则增加\n * @param {*} arr \n * @param {*} data \n * @param {*} sort 排序方式 asc/desc\n */\nfunction arrAddDel(arr, data, sort = 'asc') {\n\tif (!arr) return arr;\n\tif (!Array.isArray(arr)) return arr;\n\n\tlet idx = arr.indexOf(data);\n\tif (idx > -1)\n\t\tarr.splice(idx, 1);\n\telse\n\t\tarr.push(data)\n\n\tif (sort == 'asc')\n\t\treturn arr.sort();\n\telse\n\t\treturn arr.reverse();\n}  \n\n//数据深度拷贝\nfunction deepClone(data) {\n\tif (data === null || typeof data === 'string' || typeof data === 'number' || typeof data === 'boolean' || typeof data === 'undefined') {\n\t\treturn data;\n\t}\n\n\treturn JSON.parse(JSON.stringify(data));\n}\n\nfunction padLeft(str, len, charStr) {\n\tif (!str)\n\t\tstr = '';\n\telse\n\t\tstr = str + '';\n\treturn new Array(len - str.length + 1).join(charStr || '') + str;\n}\n\nfunction padRight(str, len, charStr) {\n\tif (!str)\n\t\tstr = '';\n\telse\n\t\tstr = str + '';\n\treturn str + new Array(len - str.length + 1).join(charStr || '');\n}\n\n\n// 选项表单处理\nfunction getSelectOptions(str) {\n\tif (!str)\n\t\treturn [];\n\telse if (str.includes('=')) {\n\t\tlet arr = str.split(',');\n\t\tfor (let k = 0; k < arr.length; k++) {\n\t\t\tlet node = arr[k].split('=');\n\t\t\tarr[k] = {};\n\t\t\tarr[k].label = node[1];\n\t\t\tarr[k].val = node[0];\n\t\t}\n\t\treturn arr;\n\t} else {\n\t\treturn str.split(',');\n\t}\n}\n\n// 数组元素交换位置 index1和index2分别是两个数组的索引值\nfunction arraySwap(arr, index1, index2) {\n\tarr[index1] = arr.splice(index2, 1, arr[index1])[0];\n\treturn arr;\n}\n\n// 数组置顶\nfunction arrayTop(arr, idx) {\n\tlet node = arr.splice(idx, 1)[0];\n\tarr.unshift(node);\n\treturn arr;\n}\n\n// 数组置底\nfunction arrayBottom(arr, idx) {\n\tlet node = arr.splice(idx, 1)[0];\n\tarr.push(node);\n\treturn arr;\n}\n\n/**\n * 把某个值/对象按key插到某个对象数组\n * @param {*} arr  目标数组\n * @param {*} key  键\n * @param {*} val  判断值\n * @param {*} obj  插入对象{}\n */\nfunction insertObjArrByKey(arr, key, val, obj) {\n\tif (!arr) return arr;\n\n\tfor (let k = 0; k < arr.length; k++) {\n\t\tif (arr[k][key] == val) {\n\t\t\t// 发现存在\n\t\t\tarr[k].list.push(obj);\n\t\t\treturn arr;\n\t\t}\n\t}\n\n\t// 不存在\n\tlet newObj = {\n\t\t[key]: val,\n\t\tlist: [obj]\n\t}\n\tarr.push(newObj);\n\treturn arr;\n}\n\n/**\n * 从对象数组中， 根据某个键值 获取满足的对象\n * @param {*} arr \n * @param {*} key \n * @param {*} val \n */\nfunction getValFromArr(arr, key = 'val', val = '') {\n\tif (!Array.isArray(arr)) return null;\n\tfor (let k = 0; k < arr.length; k++) {\n\t\tif (arr[k][key] == val)\n\t\t\treturn arr[k];\n\t}\n\n\treturn null;\n}\n\n// 把字符串按关键字转为数组\nfunction splitTextByKey(txt, key) {\n\tif (txt === null || txt === undefined) return [];\n\tif (key === null || key === undefined || key.trim() == '') return [String(txt)];\n\n\tkey = String(key).trim();\n\ttxt = String(txt);\n\tlet arr = txt.split(key);\n\tlet ret = [];\n\tfor (let i = 0; i < arr.length; i++) {\n\t\tif (arr[i] !== '') ret.push(arr[i]);\n\t\tif (i != (arr.length - 1)) ret.push(key);\n\t}\n\treturn ret;\n}\n\nmodule.exports = {\n\tarrayTop,\n\tarraySwap,\n\tarrayBottom,\n\n\tgetTitleByForm,\n\tgetValByForm,\n\tdbForms2Obj,\n\tdbFormsFix,\n\n\tgetValFromArr,\n\tgetArrByKey,\n\tgetArrByKeyMulti, //提取对象数组的多个属性数组\n\tspArr, //拆分一维数组为二维\n\tgetDataByKey,\n\tstr2Arr,\n\tarr2ObjectArr,\n\tinsertObjArrByKey,\n\tarrAddDel,\n\tobjArrSortAsc,\n\tobjArrSortDesc,\n\tsplitTextByKey,\n\n\tarrAddDel,\n\tisNumber,\n\n\tpadLeft,\n\tpadRight,\n\n\tmakeID,\n\n\tgenRandomString, // 随机字符串\n\tgenRandomIntString,\n\tgenRandomAlpha,\n\tgenRandomNum, // 随机数字 \n\tfmtText, // 文本内容格式化处理\n\tfmtMoney, //金额格式化\n\n\ttoHump,\n\ttoLine,\n\n\tgetSelectOptions, //选项表单处理\n\n\tdeepClone\n\n}"
  },
  {
    "path": "cloudfunctions/mcloud/framework/utils/export_util.js",
    "content": "/**\n * Notes: 导出相关函数\n * Ver : CCMiniCloud Framework 2.0.14 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-05-25 04:00:00 \n */\n\nconst cloudBase = require('../../framework/cloud/cloud_base.js');\nconst cloudUtil = require('../../framework/cloud/cloud_util.js');\nconst timeUtil = require('../../framework/utils/time_util.js');\nconst util = require('../../framework/utils/util.js');\nconst md5Lib = require('../../framework/lib/md5_lib.js');\nconst config = require('../../config/config.js');\nconst setupUtil = require('../utils/setup/setup_util.js');\n\n// 获得当前导出链接\nasync function getExportDataURL(key) {\n\n\tlet url = '';\n\tlet time = '';\n\tlet expData = await setupUtil.get(key);\n\tif (!expData)\n\t\turl = '';\n\telse {\n\t\turl = expData.EXPORT_CLOUD_ID;\n\t\turl = await cloudUtil.getTempFileURLOne(url) + '?rd=' + timeUtil.time();\n\t\ttime = timeUtil.timestamp2Time(expData.EXPORT_ADD_TIME);\n\t}\n\n\treturn {\n\t\turl,\n\t\ttime\n\t}\n}\n\n// 删除数据文件\nasync function deleteDataExcel(key) {\n\tconsole.log('[deleteExcel]  BEGIN... , key=' + key)\n\n\t// 取出数据  \n\tlet expData = await setupUtil.get(key);\n\tif (!expData) return;\n\n\t// 文件路径\n\tlet xlsPath = expData.EXPORT_CLOUD_ID;\n\n\tconsole.log('[deleteExcel]  path = ' + xlsPath);\n\n\tconst cloud = cloudBase.getCloud();\n\tawait cloud.deleteFile({\n\t\tfileList: [xlsPath],\n\t}).then(async res => {\n\t\tconsole.log(res.fileList);\n\t\tif (res.fileList && res.fileList[0] && res.fileList[0].status == -503003) {\n\t\t\tconsole.log('[deleteUserExcel]  ERROR = ', res.fileList[0].status + ' >> ' + res.fileList[0].errMsg);\n\t\t\tthis.AppError('文件不存在或者已经删除');\n\t\t}\n\n\t\t// 删除导出数据记录\n\t\tawait setupUtil.remove(key);\n\n\t\tconsole.log('[deleteExcel]  OVER.');\n\n\t}).catch(error => {\n\t\tif (error.name != 'AppError') {\n\t\t\tconsole.log('[deleteExcel]  ERROR = ', error);\n\t\t\tthis.AppError('操作失败，请重新删除');\n\t\t} else\n\t\t\tthrow error;\n\t});\n\n\n}\n\n// 导出数据  \nasync function exportDataExcel(key, title, total, data, options = {}) {\n\t// 删除导出表\n\n\tawait setupUtil.remove(key);\n\n\tlet fileName = key + '_' + md5Lib.md5(key + config.CLOUD_ID);\n\tlet xlsPath = util.getProjectId() + '/' + 'export/' + fileName + '.xlsx';\n\n\t// 操作excel用的类库\n\tconst xlsx = require('node-xlsx');\n\n\t// 把数据保存到excel里\n\tlet buffer = await xlsx.build([{\n\t\tname: title + timeUtil.time('Y-M-D'),\n\t\tdata,\n\t\toptions\n\t}]);\n\n\t// 把excel文件保存到云存储里\n\tconsole.log('[ExportData]  Save to ' + xlsPath);\n\tconst cloud = cloudBase.getCloud();\n\tlet upload = await cloud.uploadFile({\n\t\tcloudPath: xlsPath,\n\t\tfileContent: buffer, //excel二进制文件\n\t});\n\tif (!upload || !upload.fileID) return;\n\n\t// 入导出表 \n\tlet dataExport = {\n\t\tEXPORT_ADD_TIME: timeUtil.time(),\n\t\tEXPORT_KEY: key,\n\t\tEXPORT_CLOUD_ID: upload.fileID\n\t}\n\t//console.log(dataExport)\n\tawait setupUtil.set(key, dataExport, 'export');\n\n\tconsole.log('[ExportData]  OVER.')\n\n\treturn {\n\t\ttotal\n\t}\n}\n\nmodule.exports = {\n\tgetExportDataURL,\n\tdeleteDataExcel,\n\texportDataExcel\n}"
  },
  {
    "path": "cloudfunctions/mcloud/framework/utils/log_util.js",
    "content": " /**\n  * Notes: 日志操作函数\n  * Ver : CCMiniCloud Framework 2.34.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n  * Date: 2021-06-12 04:00:00 \n  */\n const timeUtil = require('./time_util.js');\n\n class LogUtil {\n\n \tconstructor(level = 'info') {\n \t\tthis.logOut = ''; // 输出日志内容\n\n \t\tlevel = level.toLowerCase();\n \t\tif (level == 'err') level = 'error';\n\n \t\tswitch (level) {\n \t\t\tcase 'debug':\n \t\t\t\tlevel = LogUtil.LEVEL.DEBUG;\n \t\t\t\tbreak;\n \t\t\tcase 'info':\n \t\t\t\tlevel = LogUtil.LEVEL.INFO;\n \t\t\t\tbreak;\n \t\t\tcase 'warn':\n \t\t\t\tlevel = LogUtil.LEVEL.WARN;\n \t\t\t\tbreak;\n \t\t\tcase 'error':\n \t\t\t\tlevel = LogUtil.LEVEL.ERROR;\n \t\t\t\tbreak;\n \t\t\tcase 'fatal':\n \t\t\t\tlevel = LogUtil.LEVEL.FATAL;\n \t\t\t\tbreak;\n \t\t\tcase 'none':\n \t\t\t\tlevel = LogUtil.LEVEL.NONE;\n \t\t\t\tbreak;\n \t\t\tdefault:\n \t\t\t\tlevel = LogUtil.LEVEL.INFO;\n \t\t}\n \t\tthis.level = level;\n \t}\n\n \tdebug(str, ex = '') {\n \t\tif (this.level > LogUtil.LEVEL.DEBUG) return;\n\n \t\tconsole.debug('[' + this._getTime() + '] DEBUG: ' + str, ex);\n \t\tthis.logOut += \"######\" + '[' + this._getTime() + '] DEBUG: ' + str + (ex ? JSON.stringify(ex) : '');\n \t}\n\n \tinfo(str, ex = '') {\n \t\tif (this.level > LogUtil.LEVEL.INFO) return;\n\n \t\tconsole.log('[' + this._getTime() + '] INFO: ' + str, ex);\n\n \t\tthis.logOut += \"######\" + '[' + this._getTime() + '] INFO: ' + str + (ex ? JSON.stringify(ex) : '');\n \t}\n\n \twarn(str, ex = '') {\n \t\tif (this.level > LogUtil.LEVEL.WARN) return;\n\n \t\tconsole.warn('[' + this._getTime() + '] WARN: ' + str, ex);\n \t\tthis.logOut += \"######\" + '[' + this._getTime() + '] WARN: ' + str + (ex ? JSON.stringify(ex) : '');\n \t}\n\n \terror(str, ex = '') {\n \t\tif (this.level > LogUtil.LEVEL.ERROR) return;\n\n \t\tconsole.error('[' + this._getTime() + '] ERROR: ' + str, ex);\n \t\tthis.logOut += \"######\" + '[' + this._getTime() + '] ERROR: ' + str + (ex ? JSON.stringify(ex) : '');\n \t}\n\n \tfatal(str, ex = '') {\n \t\tif (this.level > LogUtil.LEVEL.FATAL) return;\n \t\tconsole.error('[' + this._getTime() + '] FATAL: ' + str, ex);\n \t\tthis.logOut += \"######\" + '[' + this._getTime() + '] FATAL: ' + str + (ex ? JSON.stringify(ex) : '');\n \t}\n\n\n \t_getTime() {\n \t\treturn timeUtil.time('Y-M-D h:m:s');\n \t}\n\n \terr(str) {\n \t\terror(str);\n \t}\n\n \tgetLogOut() {\n \t\treturn this.logOut;\n \t}\n\n }\n\n LogUtil.LEVEL = {\n \tDEBUG: 10,\n \tINFO: 20,\n \tWARN: 30,\n \tERROR: 40,\n \tFATAL: 50,\n \tNONE: 100,\n };\n\n module.exports = LogUtil;"
  },
  {
    "path": "cloudfunctions/mcloud/framework/utils/math_util.js",
    "content": " /**\n  * Notes: 数学计算相关操作函数\n  * Ver : CCMiniCloud Framework 2.35.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n  * Date: 2021-10-04 04:00:00 \n  */\n\n\n /** 获取百分比, 保留2位小数 */\n function percent(num1, num2) {\n \treturn Math.round(num1 / num2 * 10000) / 100.00;\n }\n\n /** 数组对象排序 */\n function arrayObjecSortAsc(property) {\n \treturn function (a, b) {\n \t\tvar value1 = a[property];\n \t\tvar value2 = b[property];\n \t\treturn value1 - value2;\n \t}\n }\n\n /** 数组对象排序 */\n function arrayObjecSortDesc(property) {\n \treturn function (a, b) {\n \t\tvar value1 = a[property];\n \t\tvar value2 = b[property];\n \t\treturn value2 - value1;\n \t}\n }\n\n module.exports = {\n \tpercent, // 百分比，保留2位小数 \n \tarrayObjecSortAsc, // 数组对象排序\n \tarrayObjecSortDesc, // 数组对象排序\n }"
  },
  {
    "path": "cloudfunctions/mcloud/framework/utils/setup/setup_model.js",
    "content": "/**\n * Notes: 系统设置实体\n * Ver : CCMiniCloud Framework 2.0.15 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-11-05 19:20:00 \n */\n\n\nconst MultiModel = require('../../database/multi_model.js');\n\nclass SetupModel extends MultiModel {\n\n}\n\n// 集合名\nSetupModel.CL = MultiModel.C('setup');\n\nSetupModel.DB_STRUCTURE = {\n\t_pid: 'string|true',\n\tSETUP_ID: 'string|true',\n\n\tSETUP_TYPE: 'string|false', //content/cache/vouch\n\tSETUP_KEY: 'string|true',\n\tSETUP_VALUE: 'object|true', // {val:}\n \n\tSETUP_ADD_TIME: 'int|true',\n\tSETUP_EDIT_TIME: 'int|true',\n\tSETUP_ADD_IP: 'string|false',\n\tSETUP_EDIT_IP: 'string|false',\n};\n\n// 字段前缀\nSetupModel.FIELD_PREFIX = \"SETUP_\"; \n\n\nmodule.exports = SetupModel;\n\n/* \n### 富文本\n[{\"type\":\"text\",\"val\":\"xxx\"},{\"type\":\"img\",\"val\":\"cloudId://xxxx\"}]\n\n### 导出\n{\"EXPORT_CLOUD_ID\":\"\",\"EXPORT_EDIT_TIME\":\"\"}\n*/"
  },
  {
    "path": "cloudfunctions/mcloud/framework/utils/setup/setup_util.js",
    "content": "/**\n * Notes: 系统设置相关函数\n * Ver : CCMiniCloud Framework 2.31.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-05-25 04:00:00 \n */\n\nconst SetupModel = require('./setup_model.js');\n\n/**\n * 设置\n * key 键key\n * val 值value\n * t 秒\n */\nasync function set(key, val, type = '') {\n\tif (!key) return null;\n\n\tlet where = {\n\t\tSETUP_KEY: key\n\t}\n\n\tlet data = {\n\t\tSETUP_TYPE: type,\n\t\tSETUP_VALUE: {\n\t\t\tval\n\t\t}, \n\t}\n\t \n\tawait SetupModel.insertOrUpdate(where, data);\n\n}\n\n/**\n * 获取\n * k 键key\n * def 默认值\n */\nasync function get(key) {\n\n\tif (!key) return null;\n\n\tlet where = {\n\t\tSETUP_KEY: key\n\t}\n\n\tlet setup = await SetupModel.getOne(where, 'SETUP_VALUE');\n\tif (!setup) return null;\n\n\n\tlet res = setup.SETUP_VALUE.val;\n\n\tif (res === undefined) {\n\t\treturn null;\n\t} else {\n\t\treturn res;\n\t}\n}\n\nasync function get(key) {\n\n\tif (!key) return null;\n\n\tlet where = {\n\t\tSETUP_KEY: key\n\t}\n\n\tlet setup = await SetupModel.getOne(where, 'SETUP_VALUE');\n\tif (!setup) return null;\n\n\n\tlet res = setup.SETUP_VALUE.val;\n\n\tif (res === undefined) {\n\t\treturn null;\n\t} else {\n\t\treturn res;\n\t}\n}\n\nasync function remove(key, fuzzy = false) {\n\tif (!key) return;\n\n\tlet where = {\n\t\tSETUP_KEY: key\n\t}\n\n\tif (fuzzy) {\n\t\twhere.SETUP_KEY = {\n\t\t\t$regex: '.*' + key,\n\t\t\t$options: 'i'\n\t\t};\n\t}\n\n\tawait SetupModel.del(where);\n}\n\nmodule.exports = {\n\tset,\n\tget,\n\tremove\n}"
  },
  {
    "path": "cloudfunctions/mcloud/framework/utils/time_util.js",
    "content": "/**\n * Notes: 时间相关函数\n * Ver : CCMiniCloud Framework 2.36.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-09-05 04:00:00 \n */\n\nconst util = require('./util.js');\n\n/** 日期简化，去掉多余的前缀0 */\nfunction simpleDate(date) {\n\tlet arr = date.split('-');\n\tif (arr.length < 3) return date;\n\tlet month = arr[1];\n\tif (month.indexOf('0') == 0)\n\t\tmonth = month.replace('0', '');\n\n\tlet day = arr[2];\n\tif (day.indexOf('0') == 0)\n\t\tday = day.replace('0', '');\n\n\treturn arr[0] + '-' + month + '-' + day;\n}\n\n/** 时间格式化为年月日点分 */\nfunction fmtDateCHN(date, fmt = 'Y-M-D') {\n\tif (!date) return '';\n\tif (fmt == 'hh:mm' && date.includes(':')) {\n\t\tif (date.includes(' ')) date = date.split(' ')[1];\n\t\tlet arr = date.split(':');\n\t\treturn Number(arr[0]) + '点' + arr[1] + '分';\n\t} else if (fmt == 'Y-M-D hh:mm') {\n\t\tlet arr = date.split(' ');\n\t\tif (arr.length != 2) return date;\n\t\treturn fmtDateCHN(arr[0], 'Y-M-D') + fmtDateCHN(arr[1], 'hh:mm');\n\t} else if (fmt == 'M-D hh:mm') {\n\t\tlet arr = date.split(' ');\n\t\tif (arr.length != 2) return date;\n\t\treturn fmtDateCHN(arr[0], 'M-D') + ' ' + fmtDateCHN(arr[1], 'hh:mm');\n\t} else {\n\t\tif (date.includes(' ')) date = date.split(' ')[0];\n\n\t\tlet arr = date.split('-');\n\t\tif (fmt == 'Y-M') //年月\n\t\t\treturn arr[0] + '年' + Number(arr[1]) + '月';\n\t\telse if (fmt == 'M-D') //月日\n\t\t\treturn arr[1] + '月' + Number(arr[2]) + '日';\n\t\telse if (fmt == 'Y') //年\n\t\t\treturn arr[0] + '年';\n\t\telse\n\t\t\treturn arr[0] + '年' +Number(arr[1]) + '月' + Number(arr[2]) + '日';\n\t}\n\n\n}\n\n/**\n * 毫秒时间戳转时间格式\n * @param {*} unixtime  毫秒\n * @param {*} format  Y-M-D h:m:s\n * @param {*} diff  时区差异 毫秒\n */\nfunction timestamp2Time(unixtime, format = 'Y-M-D h:m:s', diff = 0) {\n\tunixtime = Number(unixtime);\n\tlet formateArr = ['Y', 'M', 'D', 'h', 'm', 's'];\n\tlet returnArr = [];\n\tlet date = new Date(unixtime + diff);\n\treturnArr.push(date.getFullYear());\n\treturnArr.push(formatNumber(date.getMonth() + 1));\n\treturnArr.push(formatNumber(date.getDate()));\n\treturnArr.push(formatNumber(date.getHours()));\n\treturnArr.push(formatNumber(date.getMinutes()));\n\treturnArr.push(formatNumber(date.getSeconds()));\n\tfor (let i in returnArr) {\n\t\tformat = format.replace(formateArr[i], returnArr[i]);\n\t}\n\treturn format;\n}\n\n\nfunction timestame2Ago(dateTimeStamp, fmt = 'Y-M-D', diff = 0) { //dateTimeStamp是一个时间毫秒，注意时间戳是秒的形式，在这个毫秒的基础上除以1000，就是十位数的时间戳。13位数的都是时间毫秒。\n\tlet minute = 1000 * 60; //把分，时，天，周，半个月，一个月用毫秒表示\n\tlet hour = minute * 60;\n\tlet day = hour * 24;\n\tlet week = day * 7;\n\tlet month = day * 30;\n\tlet now = new Date().getTime(); //获取当前时间毫秒\n\n\tlet diffValue = now - dateTimeStamp; //时间差\n\n\tif (diffValue < 0) {\n\t\treturn;\n\t}\n\tlet minC = diffValue / minute; //计算时间差的分，时，天，周，月\n\tlet hourC = diffValue / hour;\n\tlet dayC = diffValue / day;\n\n\tlet result = '';\n\n\tlet weekC = diffValue / week;\n\tlet monthC = diffValue / month;\n\tif (monthC >= 1 && monthC <= 3) {\n\t\tresult = ' ' + parseInt(monthC) + '月前'\n\t} else if (weekC >= 1 && weekC <= 3) {\n\t\tresult = ' ' + parseInt(weekC) + '周前'\n\t} else if (dayC >= 1 && dayC <= 6) {\n\t\tresult = ' ' + parseInt(dayC) + '天前'\n\t} else if (hourC >= 1 && hourC <= 23) {\n\t\tresult = ' ' + parseInt(hourC) + '小时前'\n\t} else if (minC >= 1 && minC <= 59) {\n\t\tresult = ' ' + parseInt(minC) + '分钟前'\n\t} else if (diffValue >= 0 && diffValue <= minute) {\n\t\tresult = '刚刚'\n\t} else {\n\t\tresult = timestamp2Time(dateTimeStamp, fmt, diff);\n\n\t}\n\treturn result;\n}\n\nfunction formatNumber(n) {\n\tn = n.toString()\n\treturn n[1] ? n : '0' + n\n}\n\n\n/**\n * 时间转时间戳 \n * @param {*} date  支持 Y-M-D h:m:s / Y-M-D  \n */\nfunction time2Timestamp(date) {\n\tif (date.length < 10) {\n\t\tlet arr = date.split('-');\n\t\tif (arr[1].length == 1) arr[1] = '0' + arr[1];\n\t\tif (arr[2].length == 1) arr[2] = '0' + arr[2];\n\t\tdate = arr[0] + '-' + arr[1] + '-' + arr[2];\n\t}\n\tif (date.length == 10) date = date + ' 00:00:00';\n\tlet d = new Date(date.replace(/-/g, '/'));\n\treturn d.getTime();\n}\n\n/**\n *  获取当前时间戳/时间Y-M-D h:m:s\n * @param {*} 时间格式 Y-M-D h:m:s\n * @param {int} 时间步长 (秒)\n */\nfunction time(fmt, step = 0) {\n\tlet t = 0;\n\tif (util.isDefined(fmt)) {\n\t\tlet t = new Date().getTime() + step * 1000;\n\t\treturn timestamp2Time(t, fmt);\n\t}\n\treturn new Date().getTime() + t * 1000;\n}\n\n// 获取某天0点\nfunction getDayFirstTimestamp(timestamp) {\n\tif (!timestamp) timestamp = time();\n\treturn time2Timestamp(timestamp2Time(timestamp, 'Y-M-D'));\n}\n\n/**\n * 根据出生日期计算年龄周岁 传参格式为1996-06-08\n * @param {*} birth \n */\nfunction getAge(birth, isMonth = false) {\n\tvar returnAge = '';\n\tvar mouthAge = '';\n\tvar arr = birth.split('-');\n\tvar birthYear = arr[0];\n\tvar birthMonth = arr[1];\n\tvar birthDay = arr[2];\n\tvar d = new Date();\n\tvar nowYear = d.getFullYear();\n\tvar nowMonth = d.getMonth() + 1;\n\tvar nowDay = d.getDate();\n\tif (nowYear == birthYear) {\n\t\t// returnAge = 0; //同年 则为0岁\n\t\tvar monthDiff = nowMonth - birthMonth; //月之差 \n\t\tif (monthDiff < 0) {} else {\n\t\t\tmouthAge = monthDiff + '个月';\n\t\t}\n\t} else {\n\t\tvar ageDiff = nowYear - birthYear; //年之差\n\t\tif (ageDiff > 0) {\n\t\t\tif (nowMonth == birthMonth) {\n\t\t\t\tvar dayDiff = nowDay - birthDay; //日之差 \n\t\t\t\tif (dayDiff < 0) {\n\t\t\t\t\treturnAge = ageDiff - 1 + '岁';\n\t\t\t\t} else {\n\t\t\t\t\treturnAge = ageDiff + '岁';\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tvar monthDiff = nowMonth - birthMonth; //月之差 \n\t\t\t\tif (monthDiff < 0) {\n\t\t\t\t\treturnAge = ageDiff - 1 + '岁';\n\t\t\t\t} else {\n\t\t\t\t\tmouthAge = monthDiff + '个月';\n\t\t\t\t\treturnAge = ageDiff + '岁';\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\treturnAge = -1; //返回-1 表示出生日期输入错误 晚于今天\n\t\t}\n\t}\n\tif (isMonth)\n\t\treturn returnAge + mouthAge; //返回周岁年龄+月份\n\telse\n\t\treturn returnAge;\n}\n\n/**\n * 日期计算周几\n * @param {*} day  日期为输入日期，格式为 2013-03-10\n */\nfunction week(day) { \n\tif (!day || !day.includes('-')) return '';\n\tlet arys1 = new Array();\n\tarys1 = day.split('-');\n\tlet ssdate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]);\n\tlet week1 = String(ssdate.getDay()).replace(\"0\", \"日\").replace(\"1\", \"一\").replace(\"2\", \"二\").replace(\"3\", \"三\").replace(\"4\", \"四\").replace(\"5\", \"五\").replace(\"6\", \"六\") //就是你要的星期几\n\treturn \"周\" + week1; //就是你要的星期几 \n}\n\n/** 获取某天所在某月第一天时间戳 */\nfunction getMonthFirstTimestamp(timestamp) {\n\tlet inDate = new Date(timestamp);\n\tlet year = inDate.getFullYear();\n\tlet month = inDate.getMonth();\n\treturn new Date(year, month, 1).getTime();\n}\n\n/** 获取某天所在某月最后一天时间戳 */\nfunction getMonthLastTimestamp(timestamp) {\n\tlet inDate = new Date(timestamp);\n\tlet year = inDate.getFullYear();\n\tlet month = inDate.getMonth();\n\treturn new Date(year, month + 1, 1).getTime() - 1;\n}\n\n// 取得分钟时间戳\nfunction getNowMinTimestamp() {\n\tlet min = time('Y-M-D h:m') + ':00';\n\tlet timestamp = time2Timestamp(min);\n\treturn {\n\t\tmin,\n\t\ttimestamp\n\t}\n}\n\n\n// 获取当前日期所在周一 输入和返回格式=yyyy-mm-dd\nfunction getFirstOfWeek(date) {\n\tlet now = new Date(date);\n\tlet nowTime = now.getTime();\n\tlet day = now.getDay();\n\tif (day == 0) day = 7;\n\tlet oneDayTime = 24 * 60 * 60 * 1000;\n\tlet mondayTime = nowTime - (day - 1) * oneDayTime;\n\treturn timestamp2Time(mondayTime, 'Y-M-D');\n}\n\n// 获取当前日期所在周一 输入和返回格式=yyyy-mm-dd\nfunction getLastOfWeek(date) {\n\tlet now = new Date(date);\n\tlet nowTime = now.getTime();\n\tlet day = now.getDay();\n\tif (day == 0) day = 7;\n\tlet oneDayTime = 24 * 60 * 60 * 1000;\n\tlet sundayTime = nowTime + (7 - day) * oneDayTime;\n\treturn timestamp2Time(sundayTime, 'Y-M-D');\n}\n\n// 获取当前日期所在月第一天 输入和返回格式=yyyy-mm-dd\nfunction getFirstOfMonth(date) {\n\tlet arr = date.split('-');\n\treturn arr[0] + '-' + arr[1] + '-01';\n}\n\n// 获取当前日期所在月最后一天 输入和返回格式=yyyy-mm-dd\nfunction getLastOfMonth(date) {\n\tlet now = new Date(date);\n\tlet y = now.getFullYear();\n\tlet m = now.getMonth();\n\tlet lastDay = new Date(y, m + 1, 0).getTime();\n\treturn timestamp2Time(lastDay, 'Y-M-D');\n}\n\n/**\n * 取倒计时（天时分秒） 支持时间戳或者Y-M-D/Y-M-D h:m:s\n * @param {*} datetimeTo \n * @param {*} flag 1=正 -1=负\n */\nfunction getTimeLeft(datetimeTo, flag = 1) {\n\tlet time1 = datetimeTo;\n\n\tif (String(datetimeTo).includes('-')) {\n\t\tdatetimeTo = String(datetimeTo);\n\t\tif (!datetimeTo.includes(':'))\n\t\t\tdatetimeTo += ' 00:00:00';\n\t\ttime1 = new Date(datetimeTo).getTime();\n\t}\n\n\tlet time2 = new Date().getTime();\n\tlet mss = time1 - time2;\n\n\t// 将时间差（毫秒）格式为：天时分秒\n\tlet days = parseInt(mss / (1000 * 60 * 60 * 24));\n\tlet hours = parseInt((mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));\n\tlet minutes = parseInt((mss % (1000 * 60 * 60)) / (1000 * 60));\n\tlet seconds = parseInt((mss % (1000 * 60)) / 1000);\n\n\tif (mss < 0 && mss < -86400 * 1000) {\n\t\t(days != 0) ? days = -flag * days + \"天\": days = '';\n\t\treturn days + \"前\";\n\t} else if (mss < 0) {\n\t\treturn \"今天\";\n\t} else {\n\t\t(days != 0) ? days = flag * days + \"天\": days = '';\n\t\t(hours != 0) ? hours = flag * hours + \"时\": hours = '';\n\t\t(minutes != 0) ? minutes = flag * minutes + \"分\": minutes = '';\n\t\treturn days + hours + minutes + flag * seconds + \"秒\"\n\t}\n\n}\n\n\nmodule.exports = {\n\tfmtDateCHN,\n\tsimpleDate,\n\n\tgetTimeLeft,\n\n\tgetNowMinTimestamp,\n\n\tgetMonthFirstTimestamp,\n\tgetMonthLastTimestamp,\n\n\tgetDayFirstTimestamp,\n\n\ttimestamp2Time,\n\ttimestame2Ago,\n\ttime2Timestamp,\n\ttime,\n\tgetAge,\n\tweek, //星期\n\n\tgetFirstOfWeek,\n\tgetLastOfWeek,\n\tgetFirstOfMonth,\n\tgetLastOfMonth\n}"
  },
  {
    "path": "cloudfunctions/mcloud/framework/utils/util.js",
    "content": "/**\n * Notes: 通用工具函数\n * Ver : CCMiniCloud Framework 2.38.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-09-05 04:00:00 \n */\n\nfunction getProjectId() {\n\tif (global.PID)\n\t\treturn global.PID;\n\telse\n\t\treturn 'ONE';\n}\n\n/**\n * 判断变量，参数，对象属性是否定义\n * @param {*} val \n */\nfunction isDefined(val) {\n\t// ==  不能判断是否为null\n\tif (val === undefined)\n\t\treturn false;\n\telse\n\t\treturn true;\n}\n\n/**\n * 判断对象是否为空\n * @param {*} obj \n */\nfunction isObjectNull(obj) {\n\treturn (Object.keys(obj).length == 0);\n}\n\n\n\n/**\n * 休眠时间，配合await使用 \n * @param {*} time 毫秒\n */\nfunction sleep(time) {\n\treturn new Promise((resolve) => setTimeout(resolve, time));\n};\n\n\n\n\nmodule.exports = {\n\tgetProjectId,\n\tisDefined, //判断变量，参数，对象属性是否定义  \n\tsleep,\n\tisObjectNull,\n\n}"
  },
  {
    "path": "cloudfunctions/mcloud/framework/validate/content_check.js",
    "content": "/**\n * Notes: 内容审核\n * Ver : CCMiniCloud Framework 2.39.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-09-05 04:00:00 \n */\n\nconst AppError = require('../core/app_error.js');\nconst cloudBase = require('../cloud/cloud_base.js');\nconst config = require('../../config/config.js');\n\n/**\n * 前台校验\n * @param {*} imgData \n * @param {*} mine \n */\nasync function checkImgClient(imgData, mine) {\n\tif (!config.CLIENT_CHECK_CONTENT) return;\n\treturn await checkImg(imgData, mine);\n}\n\n/**\n * 后台校验\n * @param {*} imgData \n * @param {*} mine \n */\nasync function checkImgAdmin(imgData, mine) {\n\tif (!config.ADMIN_CHECK_CONTENT) return;\n\treturn await checkImg(imgData, mine);\n}\n/**\n * 校验图片信息\n * @param {*} 图片流buffer \n */\nasync function checkImg(imgData, mine) {\n\n\n\tlet cloud = cloudBase.getCloud();\n\ttry {\n\t\tconst result = await cloud.openapi.security.imgSecCheck({\n\t\t\tmedia: {\n\t\t\t\tcontentType: 'image/' + mine,\n\t\t\t\tvalue: Buffer.from(imgData, 'base64') // 这里必须要将小程序端传过来的进行Buffer转化,否则就会报错,接口异常\n\t\t\t}\n\n\t\t})\n\t\tconsole.log('imgcheck', result);\n\t\tif (!result || result.errCode !== 0) {\n\t\t\tthrow new AppError('图片内容不合适，请修改');\n\t\t}\n\n\t} catch (err) {\n\t\tconsole.log('imgcheck ex', err);\n\t\tthrow new AppError('图片内容不合适，请修改');\n\t}\n\n}\n\n/**\n * 后台把输入数据里的文本数据提交内容审核\n * @param {*} input \n */\nasync function checkTextMultiAdmin(input) {\n\tif (!config.ADMIN_CHECK_CONTENT) return;\n\treturn checkTextMulti(input);\n}\n\n/**\n * 前台把输入数据里的文本数据提交内容审核\n * @param {*} input \n */\nasync function checkTextMultiClient(input) {\n\tif (!config.CLIENT_CHECK_CONTENT) return;\n\treturn checkTextMulti(input);\n}\n\n/**\n * 把输入数据里的文本数据提交内容审核\n * @param {*} input \n */\nasync function checkTextMulti(input) {\n\n\tlet txt = '';\n\tfor (let key in input) {\n\t\tif (typeof (input[key]) === 'string')\n\t\t\ttxt += input[key];\n\t\telse if (typeof (input[key]) === 'object') //包括数组和对象\n\t\t\ttxt += JSON.stringify(input[key]);\n\t}\n\n\tawait checkText(txt);\n}\n/**\n * 后台校验文字信息\n * @param {*}  \n */\nasync function checkTextAdmin(txt) {\n\tif (!config.ADMIN_CHECK_CONTENT) return;\n\treturn checkText(txt);\n}\n\n/**\n * 前台校验文字信息\n * @param {*}  \n */\nasync function checkTextClient(txt) {\n\tif (!config.CLIENT_CHECK_CONTENT) return;\n\treturn checkText(txt);\n}\n\n/**\n * 校验文字信息\n * @param {*}  \n */\nasync function checkText(txt) { \n\tif (!txt) return; \n\tlet cloud = cloudBase.getCloud();\n\ttry { \n\t\tconst result = await cloud.openapi.security.msgSecCheck({\n\t\t\tcontent: txt\n\n\t\t})\n\t\tif (!result || result.errCode !== 0) {\n\t\t\tthrow new AppError('文字内容不合适，请修改或者重试');\n\t\t}\n\n\t} catch (err) {\n\t\tconsole.log('checkText ex', err);\n\t\tthrow new AppError('文字内容不合适，请修改或者重试');\n\t}\n\n}\n\nmodule.exports = {\n\tcheckImg,\n\tcheckImgClient,\n\tcheckImgAdmin,\n\tcheckTextMulti,\n\tcheckTextMultiClient,\n\tcheckTextMultiAdmin,\n\tcheckText,\n\tcheckTextClient,\n\tcheckTextAdmin\n}"
  },
  {
    "path": "cloudfunctions/mcloud/framework/validate/data_check.js",
    "content": "/**\n  * Notes: 数据校验类库\n * Ver : CCMiniCloud Framework 2.21.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n  * Date: 2021-01-07 07:48:00 \n  *  \n */\nconst AppError = require('../core/app_error.js');\nconst appCode = require('../core/app_code.js');\n\nconst CHECK_OPEN = true;\nconst CHECK_SOURCE = 'admin'; //client/admin\n\n/**\n * 判断变量，参数，对象属性是否定义\n * @param {*} val \n */\nfunction isDefined(val) {\n\t// ==  不能判断是否为null\n\tif (val === undefined)\n\t\treturn false;\n\telse\n\t\treturn true;\n}\n\nfunction isNull(value) {\n\tif (value === null || value === undefined) return true;\n\tif (getDataType(value) == String && value === '') return true;\n\treturn false;\n}\n\nfunction isStrAndArrNull(value) {\n\tif (value === null || value === undefined) return true;\n\n\tlet type = getDataType(value);\n\tif (type == String && value === '') return true;\n\tif (type == Array && value.length == 0) return true;\n\n\treturn false;\n}\n\nfunction isRealNull(value) {\n\tif (value === null || value === undefined) return true;\n\n\tlet type = getDataType(value);\n\tif (type == String && value === '') return true;\n\tif (type == Array && value.length == 0) return true;\n\tif (type == Object && JSON.stringify(value) == '{}') return true;\n\n\treturn false;\n}\n\nfunction getDataType(value) {\n\tif (value === null || value === undefined) return value;\n\treturn value.constructor;\n}\n\n// 是否必填\nfunction checkRequired(value, desc = '') {\n\tswitch (getDataType(value)) {\n\t\tcase Object:\n\t\t\tif (JSON.stringify(value) == '{}')\n\t\t\t\treturn desc + '不能为空obj';\n\t\t\tbreak;\n\t\tcase Array:\n\t\t\tif (value.length == 0)\n\t\t\t\treturn desc + '不能为空arr';\n\t\t\tbreak;\n\t\tcase String:\n\t\t\tif (value.length == 0)\n\t\t\t\treturn desc + '不能为空';\n\t\t\tbreak;\n\t\tcase null:\n\t\tcase undefined:\n\t\t\treturn desc + '不能为空';\n\t}\n}\n\n// 校验字符/数组长度，校验数字大小\nfunction checkMin(value, min, desc = '') {\n\tif (isStrAndArrNull(value)) return;\n\n\tmin = Number(min);\n\tswitch (getDataType(value)) {\n\t\tcase Array:\n\t\t\tif (value.length < min)\n\t\t\t\treturn desc + '不能少于' + min + '项';\n\t\t\tbreak;\n\t\tcase String:\n\t\t\tif (value.length < min)\n\t\t\t\treturn desc + '不能少于' + min + '位';\n\t\t\tbreak;\n\t\tcase Number:\n\t\t\tif (value < min)\n\t\t\t\treturn desc + '不能小于' + min;\n\t\t\tbreak;\n\t}\n};\n\n// 校验字符/数组长度，校验数字大小\nfunction checkMax(value, max, desc = '') {\n\tif (isStrAndArrNull(value)) return;\n\n\tmax = Number(max);\n\tswitch (getDataType(value)) {\n\t\tcase Array:\n\t\t\tif (value.length > max)\n\t\t\t\treturn desc + '不能多于' + max + '项';\n\t\t\tbreak;\n\t\tcase String:\n\t\t\tif (value.length > max)\n\t\t\t\treturn desc + '不能多于' + max + '位';\n\t\t\tbreak;\n\t\tcase Number:\n\t\t\tif (value > max)\n\t\t\t\treturn desc + '不能大于' + max;\n\t\t\tbreak;\n\t}\n};\n\n// 校验字符/数组长度 \nfunction checkLen(value, len, desc = '') {\n\tif (isStrAndArrNull(value)) return;\n\n\tlen = Number(len);\n\tswitch (getDataType(value)) {\n\t\tcase Array:\n\t\t\tif (value.length != len)\n\t\t\t\treturn desc + '必须为' + len + '项';\n\t\t\tbreak;\n\t\tcase String:\n\t\t\tif (value.length != len)\n\t\t\t\treturn desc + '必须为' + len + '位';\n\t\t\tbreak;\n\t}\n};\n\nfunction checkMobile(value, desc = '') {\n\tif (isNull(value)) return;\n\n\tif (!/(^1[1|2|3|4|5|6|7|8|9][0-9]{9}$)/.test(value))\n\t\treturn desc + '格式不正确';\n}\n\nfunction checkInt(value, desc = '') {\n\tif (isNull(value)) return;\n\n\tif (!/^[0-9]+$/.test(value))\n\t\treturn desc + '必须为数字';\n}\n\nfunction checkDigit(value, desc = '') {\n\tif (isNull(value)) return;\n\n\tif (!/^\\d+(\\.\\d+)?$/.test(value))\n\t\treturn desc + '必须为数字或小数';\n}\n\nfunction checkLetter(value, desc = '') {\n\tif (isNull(value)) return;\n\n\tif (!/^[A-Za-z]+$/.test(value))\n\t\treturn desc + '必须为字母';\n}\n\nfunction checkMoney(value, desc = '') {\n\tif (isNull(value)) return;\n\n\tif (!/(^[1-9]([0-9]+)?(\\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\\.[0-9]([0-9])?$)/.test(value))\n\t\treturn desc + '必须为金额格式，例如2.00';\n}\n\n\nfunction checkLetterNum(value, desc = '') {\n\tif (isNull(value)) return;\n\n\tif (!/^\\w+$/.test(value))\n\t\treturn desc + '必须为字母，数字和下划线';\n}\n\nfunction checkId(value, desc = '', min = 1, max = 100) {\n\tif (isNull(value)) return;\n\n\tmin = Number(min);\n\tmax = Number(max);\n\n\tif (getDataType(value) != String) return desc + '必须为ID字符串格式';\n\n\tif (value.length < min || value.length > max) return desc + '必须为ID格式';\n\t/*if (!/^\\w+$/.test(value))\n\t\treturn desc + '必须为ID格式';*/\n}\n\n//  邮箱\nfunction checkEmail(value, desc = '') {\n\tif (isNull(value)) return;\n\n\tlet reg = /^[A-Za-z0-9+]+[A-Za-z0-9\\.\\_\\-+]*@([A-Za-z0-9\\-]+\\.)+[A-Za-z0-9]+$/;\n\tif (!reg.test(value)) return desc + '必须为邮箱格式';\n}\n\n// 短日期，形如 (yyyy-mm-dd 2008-07-22)\nfunction checkDate(value, desc = '') {\n\tif (isNull(value)) return;\n\n\tlet hint = '请选择' + desc;\n\tif (value.length != 10) return hint;\n\tlet r = value.match(/^(\\d{1,4})(-|\\/)(\\d{1,2})\\2(\\d{1,2})$/);\n\tif (r == null) return hint;\n\tlet d = new Date(r[1], r[3] - 1, r[4]);\n\tlet chk = d.getFullYear() == r[1] && (d.getMonth() + 1) == r[3] && d.getDate() == r[4];\n\tif (!chk) return hint;\n}\n\n// 年份，形如 (yyyy 2008)\nfunction checkYear(value, desc = '') {\n\tif (isNull(value)) return;\n\n\tlet hint = '请选择' + desc;\n\tif (value.length != 4) return hint;\n\tvalue += '-01-01';\n\treturn checkDate(value, desc);\n}\n\n// 年月，形如 (yyyy-mm 2008-01)\nfunction checkYearMonth(value, desc = '') {\n\tif (isNull(value)) return;\n\n\tlet hint = '请选择' + desc;\n\tif (value.length != 7) return hint;\n\n\tvalue += '-01';\n\treturn checkDate(value, desc);\n}\n\n// 短时间(时分秒)，形如 (13:04:06)\nfunction checkTime(value, desc = '') {\n\tif (isNull(value)) return;\n\n\tlet hint = desc + '必须为时间格式';\n\tif (value.length != 8) return hint;\n\n\tlet a = value.match(/^(\\d{1,2})(:)?(\\d{1,2})\\2(\\d{1,2})$/);\n\tif (a == null) return hint;\n\tif (a[1] > 23 || a[3] > 59 || a[4] > 59) return hint;\n}\n\n// 短时间(时分)，形如 (hh:mm 13:04)\nfunction checkHourMinute(value, desc = '') {\n\tif (isNull(value)) return;\n\n\tlet hint = desc + '必须为时分时间格式';\n\tif (value.length != 5) return hint;\n\n\tvalue += ':01';\n\treturn checkTime(value, desc);\n}\n\n// 长时间，形如 (2008-07-22 13:04:06)\nfunction checkDatimeTime(value, desc = '') {\n\tif (isNull(value)) return;\n\n\tlet hint = desc + '必须为完整时间格式';\n\tif (value.length != 19) return hint;\n\n\tvar reg = /^(\\d{1,4})(-|\\/)(\\d{1,2})\\2(\\d{1,2}) (\\d{1,2}):(\\d{1,2}):(\\d{1,2})$/;\n\tvar r = value.match(reg);\n\tif (r == null) return hint;\n\tvar d = new Date(r[1], r[3] - 1, r[4], r[5], r[6], r[7]);\n\tlet chk = d.getFullYear() == r[1] && (d.getMonth() + 1) == r[3] && d.getDate() == r[4] && d.getHours() == r[5] && d.getMinutes() == r[6] && d.getSeconds() == r[7];\n\tif (!chk) return hint;\n}\n\nfunction checkArray(value, desc = '') {\n\tif (!Array.isArray(value))\n\t\treturn desc + '填写错误arr';\n}\n\nfunction checkObject(value, desc = '') {\n\tif (value.constructor != Object)\n\t\treturn desc + '填写错误obj';\n}\n\nfunction checkBoolean(value, desc = '') {\n\tif (value.constructor != Boolean)\n\t\treturn desc + '填写错误bool';\n}\n\n// 枚举 ref=1,2,3,4格式\nfunction checkIn(value, ref, desc = '') {\n\tif (isNull(value)) return;\n\n\tlet type = getDataType(value);\n\tif (type != String && type != Number) return desc + '填写范围错误';\n\n\tlet arr = String(ref).split(',');\n\tif (!arr.includes(value) && !arr.includes(value + ''))\n\t\treturn desc + '填写范围错误';\n}\n\nfunction checkIds(value, desc) {}\n\nfunction checkString(value, desc) {\n\tif (value.constructor != String)\n\t\treturn desc + '填写错误';\n}\n\n\nfunction check(data, rules, that) {\n\tlet returnData = {};\n\tfor (let key in rules) {\n\t\tlet arr = rules[key].split('|');\n\n\t\tlet desc = key; // 字段说明\n\t\tlet defVal = undefined; // 缺省值\n\t\tlet dataType = 'String'; //数据类型   \n\n\t\tif (!CHECK_OPEN) { // 不校验\n\t\t\t// 取值\n\t\t\tlet val = data[formName];\n\t\t\treturnData[key] = val;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// 小循环获取规则\n\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\t// 数据项说明  \n\t\t\tif (arr[i].startsWith('name=')) {\n\t\t\t\tdesc = '「' + arr[i].replace('name=', '') + '」';\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// 缺省值 \n\t\t\tif (arr[i].startsWith('default=')) {\n\t\t\t\tdefVal = arr[i].replace('default=', '').trim();\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// 数据类型 \n\t\t\tswitch (arr[i].toLowerCase()) {\n\t\t\t\tcase 'int':\n\t\t\t\tcase 'digit':\n\t\t\t\t\tdataType = 'Number';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'array':\n\t\t\t\tcase 'arr':\n\t\t\t\t\tdataType = 'Array';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'object':\n\t\t\t\tcase 'obj':\n\t\t\t\t\tdataType = 'Object';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'bool':\n\t\t\t\tcase 'boolean':\n\t\t\t\t\tdataType = 'Boolean';\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// 校验 \n\t\tlet formName = (CHECK_SOURCE == 'admin') ? key : arr[0]; // 表单名  admin/client\n\n\t\t// 取值\n\t\tlet val = data[formName];\n\n\t\tswitch (dataType) {\n\t\t\tcase 'Array': {\n\t\t\t\tif (defVal !== undefined) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tdefVal = JSON.parse(defVal);\n\n\t\t\t\t\t\tif (getDataType(defVal) != Array)\n\t\t\t\t\t\t\treturn _showError(desc + '默认值数组格式错误', formName, that);\n\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\treturn _showError(desc + '默认值数组格式错误', formName, that);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (val === null || val === undefined) val = defVal;\n\n\t\t\t\tif (val !== undefined && getDataType(val) != Array)\n\t\t\t\t\treturn _showError(desc + '数组格式错误', formName, that);\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'Object': {\n\t\t\t\tif (defVal !== undefined) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tdefVal = JSON.parse(defVal);\n\n\t\t\t\t\t\tif (getDataType(defVal) != Object)\n\t\t\t\t\t\t\treturn _showError(desc + '默认值对象格式错误', formName, that);\n\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\treturn _showError(desc + '默认值对象格式错误', formName, that);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (val === null || val === undefined) val = defVal;\n\n\t\t\t\tif (val !== undefined && getDataType(val) != Object)\n\t\t\t\t\treturn _showError(desc + '对象格式错误', formName, that);\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'Boolean': {\n\t\t\t\tif (defVal !== undefined) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tdefVal = JSON.parse(defVal);\n\n\t\t\t\t\t\tif (getDataType(defVal) != Boolean)\n\t\t\t\t\t\t\treturn _showError(desc + '默认值布尔格式错误', formName, that);\n\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\treturn _showError(desc + '默认值布尔格式错误');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (val === null || val === undefined) val = defVal;\n\n\t\t\t\tif (val !== undefined && getDataType(val) != Boolean)\n\t\t\t\t\treturn _showError(desc + '布尔格式错误', formName, that);\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'Number': {\n\t\t\t\tif (checkDigit(defVal, desc + '默认值'))\n\t\t\t\t\treturn _showError(desc + '默认值格式错误', formName, that);\n\n\t\t\t\tif (val === null || val === undefined) val = defVal;\n\n\t\t\t\tif (val === undefined) break;\n\n\t\t\t\tif (val === '') //数字不能为空\n\t\t\t\t\treturn _showError(desc + '不能为空', formName, that);\n\n\t\t\t\tlet dataType = getDataType(val);\n\t\t\t\tif (dataType == Object || dataType == Boolean || dataType == Array)\n\t\t\t\t\treturn _showError(desc + '必须为数字格式', formName, that);\n\n\t\t\t\t// 数字格式校验\n\t\t\t\tlet result = checkDigit(val, desc);\n\t\t\t\tif (result) return _showError(result, formName, that);\n\n\t\t\t\tval = Number(val);\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'String': {\n\t\t\t\tlet dataType = getDataType(val);\n\t\t\t\tif (dataType == Object || dataType == Boolean || dataType == Array)\n\t\t\t\t\treturn _showError(desc + '必须为字符串格式', formName, that);\n\n\t\t\t\tif (val === null || val === undefined) val = defVal;\n\n\t\t\t\tif (val === undefined) break;\n\n\t\t\t\ttry {\n\t\t\t\t\tval = String(val).trim(); // 数字会被转为字符串\n\t\t\t\t} catch (ex) {\n\t\t\t\t\treturn _showError(desc + '必须为字符串格式', formName, that);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturnData[key] = val;\n\n\t\tlet fromStep = (CHECK_SOURCE == 'admin') ? 0 : 1; //admin/client\n\t\tfor (let i = fromStep; i < arr.length; i++) {\n\t\t\tlet result = '';\n\n\t\t\tlet rules = arr[i].split(':');\n\t\t\tlet ruleName = rules[0];\n\n\t\t\t// 空 且非必填的 不校验 \n\t\t\tif (ruleName != 'must' && val === undefined) continue;\n\n\t\t\tswitch (ruleName) {\n\t\t\t\tcase 'must':\n\t\t\t\t\tresult = checkRequired(val, desc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'str':\n\t\t\t\tcase 'string':\n\t\t\t\t\tresult = checkString(val, desc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'arr':\n\t\t\t\tcase 'array':\n\t\t\t\t\tresult = checkArray(val, desc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'obj':\n\t\t\t\tcase 'object':\n\t\t\t\t\tresult = checkObject(val, desc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'bool':\n\t\t\t\tcase 'boolean':\n\t\t\t\t\tresult = checkBoolean(val, desc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'money':\n\t\t\t\t\tresult = checkMoney(val, desc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'year':\n\t\t\t\t\tresult = checkYear(val, desc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'yearmonth':\n\t\t\t\t\tresult = checkYearMonth(val, desc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'date':\n\t\t\t\t\tresult = checkDate(val, desc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'time':\n\t\t\t\t\tresult = checkTime(val, desc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'hourminute':\n\t\t\t\t\tresult = checkHourMinute(val, desc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'datetime':\n\t\t\t\t\tresult = checkDatimeTime(val, desc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'min':\n\t\t\t\t\tresult = checkMin(val, Number(rules[1]), desc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'max':\n\t\t\t\t\tresult = checkMax(val, Number(rules[1]), desc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'len':\n\t\t\t\t\tresult = checkLen(val, Number(rules[1]), desc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'in':\n\t\t\t\t\tresult = checkIn(val, rules[1], desc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'email':\n\t\t\t\t\tresult = checkEmail(val, desc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'mobile':\n\t\t\t\t\tresult = checkMobile(val, desc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'int': // 正整数  \n\t\t\t\t\tresult = checkInt(val, desc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'digit': // 正小整数\n\t\t\t\t\tresult = checkDigit(val, desc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'id':\n\t\t\t\t\tresult = checkId(val, desc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'letter':\n\t\t\t\t\tresult = checkLetter(val, desc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'letter_num':\n\t\t\t\t\tresult = checkLetterNum(val, desc);\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (result) {\n\t\t\t\t_showError(result, formName, that);\n\t\t\t\treturn false;\n\t\t\t} else {\n\n\t\t\t\tif (that) {\n\t\t\t\t\tif (CHECK_SOURCE == 'client') {\n\t\t\t\t\t\t// 删除原有的自动聚焦 //admin/client\n\t\t\t\t\t\tif (isDefined(that.data[formName + 'Focus'])) {\n\t\t\t\t\t\t\tthat.setData({ //TODO delete?\n\t\t\t\t\t\t\t\t[formName + 'Focus']: false\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t}\n\treturn returnData;\n}\n\nfunction _showError(result, formName, that) { //admin/client\n\tif (CHECK_SOURCE == 'client') {\n\t\twx.showModal({\n\t\t\ttitle: '温馨提示',\n\t\t\tcontent: result,\n\t\t\tshowCancel: false,\n\t\t\tsuccess(res) {\n\t\t\t\t// 自动聚焦\n\t\t\t\tif (that) {\n\t\t\t\t\tpageHelper.anchor(formName, that);\n\n\t\t\t\t\tthat.setData({\n\t\t\t\t\t\t[formName + 'Focus']: result,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t}\n\t\t});\n\t} else {\n\t\tthrow new AppError(result, appCode.DATA);\n\t}\n\n}\n\nmodule.exports = {\n\tcheck,\n\n\tcheckString,\n\tcheckArray,\n\tcheckObject,\n\tcheckMoney,\n\tcheckYear,\n\tcheckYearMonth,\n\tcheckDate,\n\tcheckTime,\n\tcheckHourMinute,\n\tcheckDatimeTime,\n\tcheckMin,\n\tcheckMax,\n\tcheckLen,\n\tcheckIn,\n\tcheckEmail,\n\tcheckMobile,\n\tcheckInt, // 正小整数\n\tcheckDigit,\n\tcheckId,\n\tcheckLetter,\n\tcheckLetterNum,\n\n}"
  },
  {
    "path": "cloudfunctions/mcloud/index.js",
    "content": "const application = require('./framework/core/application.js');\n\n// 云函数入口函数\nexports.main = async (event, context) => {\n\treturn await application.app(event, context);\n}"
  },
  {
    "path": "cloudfunctions/mcloud/package.json",
    "content": "{\n    \"name\": \"cloud\",\n    \"version\": \"1.0.0\",\n    \"description\": \"\",\n    \"main\": \"index.js\",\n    \"scripts\": {\n        \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n    },\n    \"author\": \"\",\n    \"license\": \"ISC\",\n    \"dependencies\": {\n        \"date-utils\": \"^1.2.21\",\n        \"mysql\": \"^2.18.1\",\n        \"node-xlsx\": \"^0.16.1\",\n        \"wx-server-sdk\": \"~2.1.2\"\n    }\n}\n"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_album_controller.js",
    "content": "/**\n * Notes: 相册模块后台管理-控制器\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-07-11 10:20:00 \n */\n\nconst BaseProjectAdminController = require('./base_project_admin_controller.js');\n\nconst AdminAlbumService = require('../../service/admin/admin_album_service.js');\n\nconst timeUtil = require('../../../../framework/utils/time_util.js');\nconst contentCheck = require('../../../../framework/validate/content_check.js');\nconst AlbumModel = require('../../model/album_model.js');\n\nclass AdminAlbumController extends BaseProjectAdminController {\n\n\t/** 置顶与排序设定 */\n\tasync sortAlbum() {\n\t\tawait this.isAdmin();\n\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\tsort: 'must|int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminAlbumService();\n\t\tawait service.sortAlbum(input.id, input.sort);\n\t}\n\n\t/** 首页设定 */\n\tasync vouchAlbum() {\n\t\tawait this.isAdmin();\n\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\tvouch: 'must|int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminAlbumService();\n\t\tawait service.vouchAlbum(input.id, input.vouch);\n\t}\n\n\t/** 状态修改 */\n\tasync statusAlbum() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\tstatus: 'must|int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminAlbumService();\n\t\tawait service.statusAlbum(input.id, input.status);\n\n\t}\n\n\t/** 列表 */\n\tasync getAdminAlbumList() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tsearch: 'string|min:1|max:30|name=搜索条件',\n\t\t\tsortType: 'string|name=搜索类型',\n\t\t\tsortVal: 'name=搜索类型值',\n\t\t\torderBy: 'object|name=排序',\n\t\t\twhereEx: 'object|name=附加查询条件',\n\t\t\tpage: 'must|int|default=1',\n\t\t\tsize: 'int',\n\t\t\tisTotal: 'bool',\n\t\t\toldTotal: 'int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminAlbumService();\n\t\tlet result = await service.getAdminAlbumList(input);\n\n\t\t// 数据格式化\n\t\tlet list = result.list;\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tlist[k].ALBUM_ADD_TIME = timeUtil.timestamp2Time(list[k].ALBUM_ADD_TIME, 'Y-M-D h:m:s');\n\n\t\t\tif (list[k].ALBUM_OBJ && list[k].ALBUM_OBJ.detail)\n\t\t\t\tdelete list[k].ALBUM_OBJ.detail;\n\t\t}\n\t\tresult.list = list;\n\n\t\treturn result;\n\n\t}\n\n\n\t/** 发布 */\n\tasync insertAlbum() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验 \n\t\tlet rules = {\n\t\t\ttitle: 'must|string|min:2|max:50|name=标题',\n\t\t\tcateId: 'must|string|name=分类',\n\t\t\tcateName: 'must|string|name=分类名称',\n\t\t\torder: 'must|int|min:0|max:9999|name=排序号',\n\t\t\tforms: 'array|name=表单',\n\t\t};\n\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\t// 内容审核\n\t\tawait contentCheck.checkTextMultiAdmin(input);\n\n\t\tlet service = new AdminAlbumService();\n\t\tlet result = await service.insertAlbum(input);\n\n\t\tthis.logOther('添加了《' + input.title + '》');\n\n\t\treturn result;\n\n\t}\n\n\n\t/** 获取信息用于编辑修改 */\n\tasync getAlbumDetail() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminAlbumService();\n\t\treturn await service.getAlbumDetail(input.id);\n\n\t}\n\n\t/** 编辑 */\n\tasync editAlbum() {\n\t\tawait this.isAdmin();\n\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\ttitle: 'must|string|min:2|max:50|name=标题',\n\t\t\tcateId: 'must|string|name=分类',\n\t\t\tcateName: 'must|string|name=分类名称',\n\t\t\torder: 'must|int|min:0|max:9999|name=排序号',\n\t\t\tforms: 'array|name=表单',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\t// 内容审核\n\t\tawait contentCheck.checkTextMultiAdmin(input);\n\n\t\tlet service = new AdminAlbumService();\n\t\tlet result = service.editAlbum(input);\n\n\t\tthis.logOther('修改了《' + input.title + '》');\n\n\t\treturn result;\n\t}\n\n\t/** 删除 */\n\tasync delAlbum() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet title = await AlbumModel.getOneField(input.id, 'ALBUM_TITLE');\n\n\t\tlet service = new AdminAlbumService();\n\t\tawait service.delAlbum(input.id);\n\n\t\tif (title)\n\t\t\tthis.logOther('删除了《' + title + '》');\n\n\t}\n\n\t/** 更新图片信息 */\n\tasync updateAlbumForms() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\thasImageForms: 'array'\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\t// 内容审核\n\t\tawait contentCheck.checkTextMultiAdmin(input);\n\n\t\tlet service = new AdminAlbumService();\n\t\treturn await service.updateAlbumForms(input);\n\t}\n\n}\n\nmodule.exports = AdminAlbumController;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_home_controller.js",
    "content": "/**\n * Notes: 后台登录与首页模块\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-03-15 19:20:00 \n */\n\nconst BaseProjectAdminController = require('./base_project_admin_controller.js');\nconst AdminHomeService = require('../../service/admin/admin_home_service.js');\n\nclass AdminHomeController extends BaseProjectAdminController {\n\n\n\t// 管理首页 \n\tasync adminHome() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminHomeService();\n\t\treturn await service.adminHome();\n\t}\n\n\n\t// 清除首页推荐\n\tasync clearVouchData() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminHomeService();\n\t\treturn await service.clearVouchData();\n\t}\n\n}\n\nmodule.exports = AdminHomeController;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_meet_controller.js",
    "content": "/**\n * Notes: 预约模块后台管理-控制器\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-12-08 10:20:00 \n */\n\nconst BaseProjectAdminController = require('./base_project_admin_controller.js');\nconst AdminMeetService = require('../../service/admin/admin_meet_service.js');\nconst timeUtil = require('../../../../framework/utils/time_util.js');\nconst dataUtil = require('../../../../framework/utils/data_util.js'); \nconst MeetModel = require('../../model/meet_model.js');\nconst contentCheck = require('../../../../framework/validate/content_check.js');\n\nclass AdminMeetController extends BaseProjectAdminController {\n\n\t// 计算可约天数\n\t_getLeaveDay(days) {\n\t\tlet now = timeUtil.time('Y-M-D');\n\t\tlet count = 0;\n\t\tfor (let k = 0; k < days.length; k++) {\n\t\t\tif (days[k] >= now) count++;\n\t\t}\n\t\treturn count;\n\t}\n\n\tasync getDayList() {\n\t\tawait this.isAdmin();\n\n\t\tlet rules = {\n\t\t\tmeetId: 'must|id',\n\t\t\tstart: 'must|date',\n\t\t\tend: 'must|date',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMeetService();\n\t\treturn await service.getDayList(input.meetId, input.start, input.end);\n\t}\n\n\t/** 生成自助签到码 */\n\tasync genSelfCheckinQr() {\n\t\tawait this.isAdmin();\n\n\t\tlet rules = {\n\t\t\tpage: 'must|string',\n\t\t\ttimeMark: 'must|string',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMeetService();\n\t\treturn await service.genSelfCheckinQr(input.page, input.timeMark);\n\t}\n\n\t/** 管理员按钮核销 */\n\tasync checkinJoin() {\n\t\tawait this.isAdmin();\n\n\t\tlet rules = {\n\t\t\tjoinId: 'must|id',\n\t\t\tflag: 'must|in:0,1'\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMeetService();\n\t\tawait service.checkinJoin(input.joinId, input.flag);\n\t}\n\n\t/** 管理员扫码核验 */\n\tasync scanJoin() {\n\t\tawait this.isAdmin();\n\n\t\tlet rules = {\n\t\t\tmeetId: 'must|id',\n\t\t\tcode: 'must|string|len:15',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMeetService();\n\t\tawait service.scanJoin(input.meetId, input.code);\n\t}\n\n\t/** 预约排序 */\n\tasync sortMeet() { // 数据校验\n\t\tawait this.isAdmin();\n\n\t\tlet rules = {\n\t\t\tmeetId: 'must|id',\n\t\t\tsort: 'must|int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMeetService();\n\t\tawait service.sortMeet(input.meetId, input.sort);\n\t}\n\n\t/** 首页设定 */\n\tasync vouchMeet() {\n\t\tawait this.isAdmin();\n\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\tvouch: 'must|int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMeetService();\n\t\tawait service.vouchMeet(input.id, input.vouch);\n\t}\n\n\t/** 预约状态修改 */\n\tasync statusMeet() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tmeetId: 'must|id',\n\t\t\tstatus: 'must|int|in:0,1,9,10',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet title = await MeetModel.getOneField(input.meetId, 'MEET_TITLE');\n\n\t\tlet service = new AdminMeetService();\n\t\tawait service.statusMeet(input.meetId, input.status);\n\n\t\tif (title)\n\t\t\tthis.logOther('修改了预约《' + title + '》的状态为：' + MeetModel.getDesc('STATUS', input.status));\n\t}\n\n\n\t/** 报名状态修改 */\n\tasync statusJoin() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tjoinId: 'must|id',\n\t\t\tstatus: 'must|int|in:0,1,8,9,10,98,99',\n\t\t\treason: 'string|max:200',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMeetService();\n\t\treturn await service.statusJoin(this._admin, input.joinId, input.status, input.reason);\n\t}\n\n\t/** 报名删除 */\n\tasync delJoin() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tjoinId: 'must|id'\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMeetService();\n\t\treturn await service.delJoin(input.joinId);\n\t}\n\n\t/** 预约项目列表 */\n\tasync getAdminMeetList() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tsearch: 'string|min:1|max:30|name=搜索条件',\n\t\t\tsortType: 'string|name=搜索类型',\n\t\t\tsortVal: 'name=搜索类型值',\n\t\t\torderBy: 'object|name=排序',\n\t\t\twhereEx: 'object|name=附加查询条件',\n\t\t\tpage: 'must|int|default=1',\n\t\t\tsize: 'int|default=10',\n\t\t\tisTotal: 'bool',\n\t\t\toldTotal: 'int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMeetService();\n\t\tlet result = await service.getAdminMeetList(input);\n\n\t\t// 数据格式化\n\t\tlet list = result.list;\n\t\tfor (let k = 0; k < list.length; k++) {\n\n\t\t\tlist[k].MEET_ADD_TIME = timeUtil.timestamp2Time(list[k].MEET_ADD_TIME);\n\t\t\tlist[k].MEET_EDIT_TIME = timeUtil.timestamp2Time(list[k].MEET_EDIT_TIME);\n\t\t\tlist[k].leaveDay = this._getLeaveDay(list[k].MEET_DAYS);\n\n\t\t}\n\t\tresult.list = list;\n\n\t\treturn result;\n\n\t}\n\n\t/** 预约名单列表 */\n\tasync getJoinList() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tsearch: 'string|min:1|max:30|name=搜索条件',\n\t\t\tsortType: 'string|name=搜索类型',\n\t\t\tsortVal: 'name=搜索类型值',\n\t\t\torderBy: 'object|name=排序',\n\t\t\tmeetId: 'must|id',\n\t\t\tmark: 'must|string',\n\t\t\tpage: 'must|int|default=1',\n\t\t\tsize: 'int|default=10',\n\t\t\tisTotal: 'bool',\n\t\t\toldTotal: 'int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMeetService();\n\t\tlet result = await service.getJoinList(input);\n\n\t\t// 数据格式化\n\t\tlet list = result.list;\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tlist[k].JOIN_EDIT_TIME = timeUtil.timestamp2Time(list[k].JOIN_EDIT_TIME);\n\n\t\t\t//分解成数组，高亮显示\n\t\t\tlet forms = list[k].JOIN_FORMS;\n\t\t\tfor (let j in forms) {\n\t\t\t\tforms[j].valArr = dataUtil.splitTextByKey(forms[j].val, input.search);\n\t\t\t}\n\n\t\t}\n\t\tresult.list = list;\n\n\t\treturn result;\n\n\t}\n\n\t/** 发布 */\n\tasync insertMeet() {\n\t\tawait this.isAdmin();\n\n\t\tlet rules = {\n\t\t\ttitle: 'must|string|min:2|max:50|name=标题',\n\t\t\ttypeId: 'must|id|name=分类',\n\t\t\ttypeName: 'must|string|name=分类',\n\t\t\torder: 'must|int|min:0|max:9999|name=排序号',\n\t\t\tdaysSet: 'must|array|name=预约时间设置',\n\t\t\tisShowLimit: 'must|int|in:0,1|name=是否显示可预约人数',\n\n\t\t\tformSet: 'must|array|name=用户资料设置',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\t// 内容审核\n\t\tawait contentCheck.checkTextMultiAdmin(input);\n\n\t\tlet service = new AdminMeetService();\n\t\tlet result = await service.insertMeet(this._adminId, input);\n \n\n\t\tthis.logOther('创建了新预约《' + input.title + '》');\n\n\t\treturn result;\n\n\t}\n\n\n\t/** 获取预约信息用于编辑修改 */\n\tasync getMeetDetail() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMeetService();\n\t\tlet detail = await service.getMeetDetail(input.id);\n\t\treturn detail;\n\t}\n\n\t/** 编辑预约 */\n\tasync editMeet() {\n\t\tawait this.isAdmin();\n\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\ttitle: 'must|string|min:2|max:50|name=标题',\n\t\t\ttypeId: 'must|id|name=分类',\n\t\t\ttypeName: 'must|string|name=分类',\n\t\t\torder: 'must|int|min:0|max:9999|name=排序号',\n\t\t\tdaysSet: 'must|array|name=预约时间设置',\n\n\t\t\tisShowLimit: 'must|int|in:0,1|name=是否显示可预约人数',\n\n\t\t\tformSet: 'must|array|name=用户资料设置',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\t// 内容审核\n\t\tawait contentCheck.checkTextMultiAdmin(input);\n\n\t\tlet service = new AdminMeetService();\n\t\tlet result = service.editMeet(input);\n \n\n\t\tthis.logOther('修改了预约《' + input.title + '》');\n\n\t\treturn result;\n\t}\n\n\t/** 删除预约 */\n\tasync delMeet() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tmeetId: 'must|id',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet title = await MeetModel.getOneField(input.meetId, 'MEET_TITLE');\n\n\t\tlet service = new AdminMeetService();\n\t\tawait service.delMeet(input.meetId);\n \n\n\t\tif (title)\n\t\t\tthis.logOther('删除了预约《' + title + '》');\n\t}\n\n\t/**\n\t * 更新富文本信息\n\t * @returns 返回 urls数组 [url1, url2, url3, ...]\n\t */\n\tasync updateMeetContent() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\tcontent: 'array'\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\t// 内容审核\n\t\tawait contentCheck.checkTextMultiAdmin(input);\n\n\t\tlet service = new AdminMeetService();\n\t\treturn await service.updateMeetContent(input);\n\t}\n\n\n\t/**\n\t * 更新封面设置\n\t * @returns 返回 urls数组 [url1, url2, url3, ...]\n\t */\n\tasync updateMeetStyleSet() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tmeetId: 'must|id',\n\t\t\tstyleSet: 'object'\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\t// 内容审核\n\t\tawait contentCheck.checkTextMultiAdmin(input);\n \n\n\t\tlet service = new AdminMeetService();\n\t\treturn await service.updateMeetStyleSet(input);\n\t}\n\n\t// 删除某时段预约记录\n\tasync cancelJoinByTimeMark() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tmeetId: 'must|id',\n\t\t\ttimeMark: 'must|string',\n\t\t\treason: 'string'\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMeetService();\n\t\treturn await service.cancelJoinByTimeMark(this._admin, input.meetId, input.timeMark, input.reason);\n\t}\n\n\t/** 创建模板 */\n\tasync insertMeetTemp() {\n\t\tawait this.isAdmin();\n\n\t\tlet rules = {\n\t\t\tname: 'must|string|min:1|max:20|name=名称',\n\t\t\ttimes: 'must|array|name=模板时段',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMeetService();\n\t\tlet result = await service.insertMeetTemp(input);\n\n\t\treturn result;\n\n\t}\n\n\t/** 编辑模板 */\n\tasync editMeetTemp() {\n\t\tawait this.isAdmin();\n\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\tisLimit: 'must|bool|name=是否限制',\n\t\t\tlimit: 'must|int|name=人数上限',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMeetService();\n\t\tlet result = service.editMeetTemp(input);\n\n\t\treturn result;\n\t}\n\n\t/** 模板列表 */\n\tasync getMeetTempList() {\n\t\tawait this.isAdmin();\n\n\t\tlet service = new AdminMeetService();\n\t\tlet result = await service.getMeetTempList();\n\n\t\treturn result;\n\t}\n\n\t/** 删除模板 */\n\tasync delMeetTemp() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMeetService();\n\t\tawait service.delMeetTemp(input.id);\n\n\t}\n\n\n\t/**************报名数据导出 BEGIN ********************* */\n\t/** 当前是否有导出文件生成 */\n\tasync joinDataGet() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tisDel: 'int|must', //是否删除已有记录\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMeetService();\n\n\t\tif (input.isDel === 1)\n\t\t\tawait service.deleteJoinDataExcel(); //先删除\n\n\t\treturn await service.getJoinDataURL();\n\t}\n\n\t/** 导出数据 */\n\tasync joinDataExport() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tmeetId: 'id|must',\n\t\t\tstartDay: 'date|must',\n\t\t\tendDay: 'date|must',\n\t\t\tstatus: 'int|must|default=1'\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMeetService();\n\t\treturn await service.exportJoinDataExcel(input);\n\t}\n\n\t/** 删除导出的报名数据文件 */\n\tasync joinDataDel() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMeetService();\n\t\treturn await service.deleteJoinDataExcel();\n\t}\n\n\n}\n\nmodule.exports = AdminMeetController;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_mgr_controller.js",
    "content": "/**\n * Notes: 管理员控制模块\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-07-11 10:20:00 \n */\n\nconst BaseProjectAdminController = require('./base_project_admin_controller.js');\nconst LogModel = require('../../../../framework/platform/model/log_model.js');\n\nconst AdminMgrService = require('../../service/admin/admin_mgr_service.js');\nconst timeUtil = require('../../../../framework/utils/time_util.js');\nconst contentCheck = require('../../../../framework/validate/content_check.js');\n\nclass AdminMgrController extends BaseProjectAdminController {\n\t// 管理员登录  \n\tasync adminLogin() {\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tname: 'must|string|min:5|max:30|name=管理员名',\n\t\t\tpwd: 'must|string|min:5|max:30|name=密码',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMgrService();\n\t\treturn await service.adminLogin(input.name, input.pwd);\n\t}\n\n\t/** 删除管理员 */\n\tasync delMgr() {\n\t\tawait this.isSuperAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMgrService();\n\t\tawait service.delMgr(input.id, this._adminId);\n\n\t}\n\n\t/** 管理员状态修改 */\n\tasync statusMgr() {\n\t\tawait this.isSuperAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\tstatus: 'must|int|in:0,1',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMgrService();\n\t\tawait service.statusMgr(input.id, input.status, this._admin.ADMIN_PHONE);\n\t}\n\n\t/** 管理员列表 */\n\tasync getMgrList() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tsearch: 'string|min:1|max:30|name=搜索条件',\n\t\t\tsortType: 'string|name=搜索类型',\n\t\t\tsortVal: 'name=搜索类型值',\n\t\t\torderBy: 'object|name=排序',\n\t\t\twhereEx: 'object|name=附加查询条件',\n\t\t\tpage: 'must|int|default=1',\n\t\t\tsize: 'int|default=10',\n\t\t\tisTotal: 'bool',\n\t\t\toldTotal: 'int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMgrService();\n\t\tlet result = await service.getMgrList(input);\n\n\t\t// 数据格式化\n\t\tlet list = result.list;\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tlist[k].ADMIN_EDIT_TIME = timeUtil.timestamp2Time(list[k].ADMIN_EDIT_TIME);\n\t\t\tlist[k].ADMIN_LOGIN_TIME = (list[k].ADMIN_LOGIN_TIME == 0) ? '未登录' : timeUtil.timestamp2Time(list[k].ADMIN_LOGIN_TIME);\n\t\t}\n\t\tresult.list = list;\n\t\treturn result;\n\t}\n\n\t/** 添加管理员 */\n\tasync insertMgr() {\n\t\tawait this.isSuperAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tname: 'must|string|min:5|max:30|name=账号',\n\t\t\tdesc: 'must|string|max:30|name=姓名',\n\t\t\tphone: 'string|len:11|name=手机',\n\t\t\tpassword: 'must|string|min:6|max:30|name=密码',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\t// 内容审核\n\t\tawait contentCheck.checkTextMultiAdmin(input);\n\n\t\tlet service = new AdminMgrService();\n\t\tawait service.insertMgr(input);\n\t}\n\n\t/** 修改管理员 */\n\tasync editMgr() {\n\t\tawait this.isSuperAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id|name=id',\n\t\t\tname: 'must|string|min:5|max:30|name=账号',\n\t\t\tdesc: 'must|string|max:30|name=姓名',\n\t\t\tphone: 'string|len:11|name=手机',\n\t\t\tpassword: 'string|min:6|max:30|name=新密码',\n\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\t// 内容审核\n\t\tawait contentCheck.checkTextMultiAdmin(input);\n\n\t\tlet service = new AdminMgrService();\n\t\tawait service.editMgr(input.id, input);\n\t}\n\n\t/** 修改自己的密码 */\n\tasync pwdMgr() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\toldPassword: 'must|string|min:6|max:30|name=旧密码',\n\t\t\tpassword: 'must|string|min:6|max:30|name=新密码',\n\t\t\tpassword2: 'must|string|min:6|max:30|name=新密码再次填写',\n\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\t// 内容审核\n\t\tawait contentCheck.checkTextMultiAdmin(input);\n\n\t\tlet service = new AdminMgrService();\n\t\tawait service.pwdtMgr(this._adminId, input.oldPassword, input.password);\n\t}\n\n\t/** 获取管理员信息用于编辑修改 */\n\tasync getMgrDetail() {\n\t\tawait this.isSuperAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMgrService();\n\t\treturn await service.getMgrDetail(input.id);\n\n\t} \n\n\tasync clearLog() {\n\t\tawait this.isAdmin();\n\n\t\tlet service = new AdminMgrService();\n\t\treturn await service.clearLog();\n\n\t}\n\n\tasync getLogList() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tsearch: 'string|min:1|max:30|name=搜索条件',\n\t\t\tsortType: 'string|name=搜索类型',\n\t\t\tsortVal: 'name=搜索类型值',\n\t\t\torderBy: 'object|name=排序',\n\t\t\twhereEx: 'object|name=附加查询条件',\n\t\t\tpage: 'must|int|default=1',\n\t\t\tsize: 'int',\n\t\t\tisTotal: 'bool',\n\t\t\toldTotal: 'int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminMgrService();\n\t\tlet result = await service.getLogList(input);\n\n\t\t// 数据格式化\n\t\tlet list = result.list;\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tlist[k].LOG_TYPE_DESC = LogModel.getDesc('TYPE', list[k].LOG_TYPE);\n\t\t\tlist[k].LOG_ADD_TIME = timeUtil.timestamp2Time(list[k].LOG_ADD_TIME);\n\t\t}\n\t\tresult.list = list;\n\n\t\treturn result;\n\n\t}\n}\n\nmodule.exports = AdminMgrController;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_news_controller.js",
    "content": "/**\n * Notes: 资讯模块后台管理-控制器\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-07-11 10:20:00 \n */\n\nconst BaseProjectAdminController = require('./base_project_admin_controller.js');\n\nconst AdminNewsService = require('../../service/admin/admin_news_service.js');\n\nconst timeUtil = require('../../../../framework/utils/time_util.js');\nconst contentCheck = require('../../../../framework/validate/content_check.js');\nconst NewsModel = require('../../model/news_model.js');\n\nclass AdminNewsController extends BaseProjectAdminController {\n\n\t/** 置顶与排序设定 */\n\tasync sortNews() {\n\t\tawait this.isAdmin();\n\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\tsort: 'must|int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminNewsService();\n\t\tawait service.sortNews(input.id, input.sort);\n\t}\n\n\t/** 首页设定 */\n\tasync vouchNews() {\n\t\tawait this.isAdmin();\n\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\tvouch: 'must|int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminNewsService();\n\t\tawait service.vouchNews(input.id, input.vouch);\n\t}\n\n\t/** 资讯状态修改 */\n\tasync statusNews() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\tstatus: 'must|int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminNewsService();\n\t\tawait service.statusNews(input.id, input.status);\n\n\t}\n\n\t/** 资讯列表 */\n\tasync getAdminNewsList() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tsearch: 'string|min:1|max:30|name=搜索条件',\n\t\t\tsortType: 'string|name=搜索类型',\n\t\t\tsortVal: 'name=搜索类型值',\n\t\t\torderBy: 'object|name=排序',\n\t\t\twhereEx: 'object|name=附加查询条件',\n\t\t\tpage: 'must|int|default=1',\n\t\t\tsize: 'int',\n\t\t\tisTotal: 'bool',\n\t\t\toldTotal: 'int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminNewsService();\n\t\tlet result = await service.getAdminNewsList(input);\n\n\t\t// 数据格式化\n\t\tlet list = result.list;\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tlist[k].NEWS_ADD_TIME = timeUtil.timestamp2Time(list[k].NEWS_ADD_TIME, 'Y-M-D h:m');\n\t\t\tlist[k].NEWS_EDIT_TIME = timeUtil.timestamp2Time(list[k].NEWS_EDIT_TIME, 'Y-M-D h:m');\n\n\t\t\tif (list[k].NEWS_OBJ && list[k].NEWS_OBJ.desc)\n\t\t\t\tdelete list[k].NEWS_OBJ.desc;\n\t\t}\n\t\tresult.list = list;\n\n\t\treturn result;\n\n\t}\n\n\t/**\n\t * 更新富文本信息\n\t */\n\tasync updateNewsContent() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\tcontent: 'array'\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\t\t// 内容审核\n\t\t\tawait contentCheck.checkTextMultiAdmin(input);\n\n\t\tlet service = new AdminNewsService();\n\t\treturn await service.updateNewsContent(input);\n\t}\n\n\n\t/** 发布资讯信息 */\n\tasync insertNews() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验 \n\t\tlet rules = {\n\t\t\ttitle: 'must|string|min:4|max:50|name=标题',\n\t\t\tcateId: 'must|string|name=分类',\n\t\t\tcateName: 'must|string|name=分类名',\n\t\t\torder: 'must|int|min:0|max:9999|name=排序号',\n\t\t\tdesc: 'must|string|min:10|max:200|name=简介',\n\t\t\tforms: 'array|name=表单',\n\t\t};\n\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\t// 内容审核\n\t\tawait contentCheck.checkTextMultiAdmin(input);\n\n\t\tlet service = new AdminNewsService();\n\t\tlet result = await service.insertNews(input);\n\n\t\tthis.logNews('添加了文章《' + input.title + '》');\n\n\t\treturn result;\n\n\t}\n\n\n\t/** 获取资讯信息用于编辑修改 */\n\tasync getNewsDetail() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\t// 内容审核\n\t\tawait contentCheck.checkTextMultiAdmin(input);\n\n\t\tlet service = new AdminNewsService();\n\t\treturn await service.getNewsDetail(input.id);\n\n\t}\n\n\t/** 编辑资讯 */\n\tasync editNews() {\n\t\tawait this.isAdmin();\n\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\ttitle: 'must|string|min:4|max:50|name=标题',\n\t\t\tcateId: 'must|string|name=分类',\n\t\t\tcateName: 'must|string|name=分类',\n\t\t\torder: 'must|int|min:0|max:9999|name=排序号',\n\t\t\tdesc: 'string|min:10|max:200|name=简介',\n\t\t\tforms: 'array|name=表单',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\t// 内容审核\n\t\tawait contentCheck.checkTextMultiAdmin(input);\n\n\t\tlet service = new AdminNewsService();\n\t\tlet result = service.editNews(input);\n\n\t\tthis.logNews('修改了文章《' + input.title + '》');\n\n\t\treturn result;\n\t}\n\n\t/** 删除资讯 */\n\tasync delNews() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet title = await NewsModel.getOneField(input.id, 'NEWS_TITLE');\n\n\t\tlet service = new AdminNewsService();\n\t\tawait service.delNews(input.id);\n\n\t\tif (title)\n\t\t\tthis.logNews('删除了文章《' + title + '》');\n\n\t}\n\n\t/**\n\t * 更新图片信息\n\t * @returns 返回 urls数组 [url1, url2, url3, ...]\n\t */\n\tasync updateNewsPic() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\timgList: 'array'\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminNewsService();\n\t\treturn await service.updateNewsPic(input);\n\t}\n\n\t/** 更新图片信息 */\n\tasync updateNewsForms() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\thasImageForms: 'array'\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\t// 内容审核\n\t\tawait contentCheck.checkTextMultiAdmin(input);\n\n\t\tlet service = new AdminNewsService();\n\t\treturn await service.updateNewsForms(input);\n\t}\n\n}\n\nmodule.exports = AdminNewsController;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_product_controller.js",
    "content": "/**\n * Notes: 产品模块后台管理-控制器\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-07-11 10:20:00 \n */\n\nconst BaseProjectAdminController = require('./base_project_admin_controller.js');\n\nconst AdminProductService = require('../../service/admin/admin_product_service.js');\n\nconst timeUtil = require('../../../../framework/utils/time_util.js');\nconst dataUtil = require('../../../../framework/utils/data_util.js');\nconst contentCheck = require('../../../../framework/validate/content_check.js');\nconst ProductModel = require('../../model/product_model.js');\n\nclass AdminProductController extends BaseProjectAdminController {\n\n\t/** 置顶与排序设定 */\n\tasync sortProduct() {\n\t\tawait this.isAdmin();\n\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\tsort: 'must|int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminProductService();\n\t\tawait service.sortProduct(input.id, input.sort);\n\t}\n\n\t/** 首页设定 */\n\tasync vouchProduct() {\n\t\tawait this.isAdmin();\n\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\tvouch: 'must|int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminProductService();\n\t\tawait service.vouchProduct(input.id, input.vouch);\n\t}\n\n\t/** 状态修改 */\n\tasync statusProduct() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\tstatus: 'must|int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminProductService();\n\t\tawait service.statusProduct(input.id, input.status);\n\n\t}\n\n\t/** 列表 */\n\tasync getAdminProductList() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tsearch: 'string|min:1|max:30|name=搜索条件',\n\t\t\tsortType: 'string|name=搜索类型',\n\t\t\tsortVal: 'name=搜索类型值',\n\t\t\torderBy: 'object|name=排序',\n\t\t\twhereEx: 'object|name=附加查询条件',\n\t\t\tpage: 'must|int|default=1',\n\t\t\tsize: 'int',\n\t\t\tisTotal: 'bool',\n\t\t\toldTotal: 'int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminProductService();\n\t\tlet result = await service.getAdminProductList(input);\n\n\t\t// 数据格式化\n\t\tlet list = result.list;\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tlist[k].PRODUCT_ADD_TIME = timeUtil.timestamp2Time(list[k].PRODUCT_ADD_TIME, 'Y-M-D h:m:s');   \n\n\t\t\tif (list[k].PRODUCT_OBJ && list[k].PRODUCT_OBJ.desc)\n\t\t\t\tdelete list[k].PRODUCT_OBJ.desc;\n\t\t}\n\t\tresult.list = list;\n\n\t\treturn result;\n\n\t}\n\n\n\t/** 发布 */\n\tasync insertProduct() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验 \n\t\tlet rules = {\n\t\t\ttitle: 'must|string|min:2|max:50|name=标题',\n\t\t\tcateId: 'must|string|name=分类',\n\t\t\tcateName: 'must|string|name=分类名称',\n\t\t\torder: 'must|int|min:0|max:9999|name=排序号',\n\t\t\tforms: 'array|name=表单',\n\t\t};\n\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\t// 内容审核\n\t\tawait contentCheck.checkTextMultiAdmin(input);\n\n\t\tlet service = new AdminProductService();\n\t\tlet result = await service.insertProduct(input);\n\n\t\tthis.logOther('添加了《' + input.title + '》');\n\n\t\treturn result;\n\n\t}\n\n\n\t/** 获取信息用于编辑修改 */\n\tasync getProductDetail() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminProductService();\n\t\treturn await service.getProductDetail(input.id);\n\n\t}\n\n\t/** 编辑 */\n\tasync editProduct() {\n\t\tawait this.isAdmin();\n\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\ttitle: 'must|string|min:2|max:50|name=标题',\n\t\t\tcateId: 'must|string|name=分类',\n\t\t\tcateName: 'must|string|name=分类名称',\n\t\t\torder: 'must|int|min:0|max:9999|name=排序号',\n\t\t\tforms: 'array|name=表单',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\t// 内容审核\n\t\tawait contentCheck.checkTextMultiAdmin(input);\n\n\t\tlet service = new AdminProductService();\n\t\tlet result = service.editProduct(input);\n\n\t\tthis.logOther('修改了《' + input.title + '》');\n\n\t\treturn result;\n\t}\n\n\t/** 删除 */\n\tasync delProduct() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet title = await ProductModel.getOneField(input.id, 'PRODUCT_TITLE');\n\n\t\tlet service = new AdminProductService();\n\t\tawait service.delProduct(input.id);\n\n\t\tif (title)\n\t\t\tthis.logOther('删除了《' + title + '》');\n\n\t}\n\n\t/** 更新图片信息 */\n\tasync updateProductForms() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\thasImageForms: 'array'\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\t// 内容审核\n\t\tawait contentCheck.checkTextMultiAdmin(input);\n\n\t\tlet service = new AdminProductService();\n\t\treturn await service.updateProductForms(input);\n\t}\n\n}\n\nmodule.exports = AdminProductController;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_setup_controller.js",
    "content": "/**\n * Notes: 设置控制模块\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-07-11 10:20:00 \n */\n\nconst BaseProjectAdminController = require('./base_project_admin_controller.js');\nconst AdminSetupService = require('../../service/admin/admin_setup_service.js');\nconst contentCheck = require('../../../../framework/validate/content_check.js');\n\nclass AdminSetupController extends BaseProjectAdminController {\n\n\t// 通用setup\n\tasync setSetup() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tkey: 'must|string|name=KEY',\n\t\t\tcontent: 'name=内容',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\t// 内容审核\n\t\tawait contentCheck.checkTextMultiAdmin(input);\n\n\t\tlet service = new AdminSetupService();\n\t\tawait service.setSetup(input.key, input.content);\n\t}\n\n\t// 富文本setup\n\tasync setContentSetup() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|string|name=KEY',\n\t\t\tcontent: 'must|array|name=内容'\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\t// 内容审核\n\t\tawait contentCheck.checkTextMultiAdmin(input);\n\n\t\tlet service = new AdminSetupService();\n\t\tawait service.setSetup(input.id, input.content, 'content');\n\t}\n\n\tasync genMiniQr() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tpath: 'must|string',\n\t\t\tsc: 'string',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\n\t\tlet service = new AdminSetupService();\n\t\treturn await service.genMiniQr(input.path, input.sc);\n\t}\n}\n\nmodule.exports = AdminSetupController;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_user_controller.js",
    "content": "/**\n * Notes: 用户控制模块\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-01-22 10:20:00 \n */\n\nconst BaseProjectAdminController = require('./base_project_admin_controller.js');\n\nconst UserModel = require('../../model/user_model.js');\nconst AdminUserService = require('../../service/admin/admin_user_service.js');\nconst timeUtil = require('../../../../framework/utils/time_util.js');\n\nclass AdminUserController extends BaseProjectAdminController {\n\n\n\t/** 用户信息 */\n\tasync getUserDetail() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminUserService();\n\t\tlet user = await service.getUser({\n\t\t\tuserId: input.id\n\t\t});\n\n\t\tif (user) {\n\t\t\t// 显示转换  \n\t\t\tuser.USER_ADD_TIME = timeUtil.timestamp2Time(user.USER_ADD_TIME);\n\t\t\tuser.USER_LOGIN_TIME = user.USER_LOGIN_TIME ? timeUtil.timestamp2Time(user.USER_LOGIN_TIME) : '未登录';\n\t\t}\n\n\t\treturn user;\n\t}\n\n\n\t/** 用户列表 */\n\tasync getUserList() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tsearch: 'string|min:1|max:30|name=搜索条件',\n\t\t\tsortType: 'string|name=搜索类型',\n\t\t\tsortVal: 'name=搜索类型值',\n\t\t\torderBy: 'object|name=排序',\n\t\t\twhereEx: 'object|name=附加查询条件',\n\t\t\tpage: 'must|int|default=1',\n\t\t\tsize: 'int',\n\t\t\tisTotal: 'bool',\n\t\t\toldTotal: 'int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminUserService();\n\t\tlet result = await service.getUserList(input);\n\n\t\t// 数据格式化\n\t\tlet list = result.list;\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tlist[k].USER_STATUS_DESC = UserModel.getDesc('STATUS', list[k].USER_STATUS);\n\t\t\tlist[k].USER_ADD_TIME = timeUtil.timestamp2Time(list[k].USER_ADD_TIME);\n\t\t\tlist[k].USER_LOGIN_TIME = list[k].USER_LOGIN_TIME ? timeUtil.timestamp2Time(list[k].USER_LOGIN_TIME) : '未登录';\n\n\t\t}\n\t\tresult.list = list;\n\t\treturn result;\n\t}\n\n\t/** 删除用户 */\n\tasync delUser() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet title = await UserModel.getOneField({ USER_MINI_OPENID: input.id }, 'USER_NAME');\n\n\t\tlet service = new AdminUserService();\n\t\tawait service.delUser(input.id);\n\n\t\tif (title)\n\t\t\tthis.logUser('删除了用户「' + title + '」');\n\n\t}\n\n\tasync statusUser() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t\tstatus: 'must|int',\n\t\t\treason: 'string'\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminUserService();\n\t\tawait service.statusUser(input.id, input.status, input.reason);\n\t}\n\n\t/************** 用户数据导出 BEGIN ********************* */\n\t/** 当前是否有导出文件生成 */\n\tasync userDataGet() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tisDel: 'int|must', //是否删除已有记录\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminUserService();\n\n\t\tif (input.isDel === 1)\n\t\t\tawait service.deleteUserDataExcel(); //先删除 \n\n\t\treturn await service.getUserDataURL();\n\t}\n\n\t/** 导出数据 */\n\tasync userDataExport() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tcondition: 'string|name=导出条件',\n\t\t\tfields: 'array',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminUserService();\n\t\treturn await service.exportUserDataExcel(input.condition, input.fields);\n\t}\n\n\t/** 删除导出的用户数据 */\n\tasync userDataDel() {\n\t\tawait this.isAdmin();\n\n\t\t// 数据校验\n\t\tlet rules = {};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AdminUserService();\n\t\treturn await service.deleteUserDataExcel();\n\t}\n}\n\nmodule.exports = AdminUserController;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/admin/base_project_admin_controller.js",
    "content": "/**\n * Notes: 后台管理控制模块\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-03-15 19:20:00 \n */\n\nconst BaseAdminController = require('../../../../framework/platform/controller/base_admin_controller.js');\nconst BaseProjectService = require('../../service/base_project_service.js');\n\nclass BaseProjectAdminController extends BaseAdminController {\n\t// TODO\n\tasync initSetup() {\n\t\tlet service = new BaseProjectService();\n\t\tawait service.initSetup();\n\t}\n\n}\n\nmodule.exports = BaseProjectAdminController;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/album_controller.js",
    "content": "/**\n * Notes: 相册模块控制器\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-06-07 04:00:00 \n */\n\nconst BaseProjectController = require('./base_project_controller.js');\nconst AlbumService = require('../service/album_service.js');\nconst timeUtil = require('../../../framework/utils/time_util.js');\n\nclass AlbumController extends BaseProjectController { \n\n\t/** 列表 */\n\tasync getAlbumList() {\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tsearch: 'string|min:1|max:30|name=搜索条件',\n\t\t\tsortType: 'string|name=搜索类型',\n\t\t\tsortVal: 'name=搜索类型值',\n\t\t\torderBy: 'object|name=排序', \n\t\t\tpage: 'must|int|default=1',\n\t\t\tsize: 'int',\n\t\t\tisTotal: 'bool',\n\t\t\toldTotal: 'int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AlbumService();\n\t\tlet result = await service.getAlbumList(input);\n\n\t\t// 数据格式化\n\t\tlet list = result.list;\n\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tlist[k].ALBUM_ADD_TIME = timeUtil.timestamp2Time(list[k].ALBUM_ADD_TIME, 'Y-M-D');\n\n\t\t\tif (list[k].ALBUM_OBJ && list[k].ALBUM_OBJ.detail)\n\t\t\tdelete list[k].ALBUM_OBJ.detail;\n\t\t} \n\n\t\treturn result;\n\n\t}\n\n\n\t/** 浏览详细 */\n\tasync viewAlbum() {\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new AlbumService();\n\t\tlet album = await service.viewAlbum(input.id);\n\n\t\tif (album) {\n\t\t\t// 显示转换 \n\t\t\talbum.ALBUM_ADD_TIME = timeUtil.timestamp2Time(album.ALBUM_ADD_TIME, 'Y-M-D');\n\t\t}\n\n\t\treturn album;\n\t} \n\n}\n\nmodule.exports = AlbumController;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/base_project_controller.js",
    "content": "/**\n * Notes: 本业务基本控制器\n * Date: 2021-03-15 19:20:00 \n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n */\n\nconst BaseController = require('../../../framework/platform/controller/base_controller.js');\nconst BaseProjectService = require('../service/base_project_service.js');\n\nclass BaseProjectController extends BaseController {\n\n\t// TODO\n\tasync initSetup() {\n\t\tlet service = new BaseProjectService();\n\t\tawait service.initSetup();\n\t}\n}\n\nmodule.exports = BaseProjectController;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/check_controller.js",
    "content": "/**\n * Notes: 内容检测控制器\n * Date: 2021-03-15 19:20:00 \n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n */\n\nconst BaseProjectController = require('./base_project_controller.js');\nconst contentCheck = require('../../framework/validate/content_check.js');\n\nclass CheckController extends BaseProjectController {\n\n\t/**\n\t * 图片校验 \n\t */\n\tasync checkImg() {\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\timg: 'name=img',\n\t\t\tmine: 'must|default=jpg',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\treturn await contentCheck.checkImg(input.img, 'jpg');\n\n\t}\n\n}\n\nmodule.exports = CheckController;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/fav_controller.js",
    "content": "/**\n * Notes: 预约模块控制器\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-12-10 04:00:00 \n */\n\nconst BaseProjectController = require('./base_project_controller.js');\nconst FavService = require('../service/fav_service.js');\nconst timeUtil = require('../../../framework/utils/time_util.js');\n\nclass FavController extends BaseProjectController {\n\n\t/** 更新某人收藏 */\n\tasync updateFav() {\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\toid: 'id|must',\n\t\t\ttitle: 'string|must',\n\t\t\ttype: 'string|must',\n\t\t\tpath: 'string|must',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new FavService();\n\t\treturn await service.updateFav(this._userId, input.oid, input.title, input.type, input.path);\n\t}\n\n\n\t/** 删除收藏 */\n\tasync delFav() {\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\toid: 'id|must'\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new FavService();\n\t\treturn await service.updateFav(this._userId, input.oid);\n\t}\n\n\n\t/** 是否收藏 */\n\tasync isFav() {\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\toid: 'id|must',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new FavService();\n\t\treturn await service.isFav(this._userId, input.oid);\n\t}\n\n\t/** 我的收藏列表 */\n\tasync getMyFavList() {\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tsearch: 'string|min:1|max:30|name=搜索条件',\n\t\t\tsortType: 'string|name=搜索类型',\n\t\t\tsortVal: 'name=搜索类型值',\n\t\t\torderBy: 'object|name=排序',\n\t\t\tpage: 'must|int|default=1',\n\t\t\tsize: 'int',\n\t\t\tisTotal: 'bool',\n\t\t\toldTotal: 'int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new FavService();\n\t\tlet result = await service.getMyFavList(this._userId, input);\n\n\t\t// 数据格式化\n\t\tlet list = result.list;\n\t\t// 显示转换\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tlist[k].FAV_ADD_TIME = timeUtil.timestamp2Time(list[k].FAV_ADD_TIME);\n\t\t}\n\t\tresult.list = list;\n\n\t\treturn result;\n\n\t}\n\n}\n\nmodule.exports = FavController;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/home_controller.js",
    "content": "/**\n * Notes: 全局或者主页模块控制器 \n * Date: 2020-11-05 10:20:00 \n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n */\n\nconst BaseProjectController = require('./base_project_controller.js');\nconst HomeService = require('../service/home_service.js');\n\nclass HomeController extends BaseProjectController {\n\n\tasync getSetup() {\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tkey: 'must|string|name=KEY',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new HomeService();\n\t\treturn await service.getSetup(input.key);\n\n\t}\n\n\n\t/** 首页推荐列表 */\n\tasync getHomeList() {\n\t\tlet service = new HomeService();\n\t\treturn await service.getHomeList(); \n\t}\n\n}\n\nmodule.exports = HomeController;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/meet_controller.js",
    "content": "/**\n * Notes: 预约模块控制器\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-12-10 04:00:00 \n */\n\nconst BaseProjectController = require('./base_project_controller.js');\nconst MeetService = require('../service/meet_service.js');\nconst timeUtil = require('../../../framework/utils/time_util.js');\nconst JoinModel = require('../model/join_model.js');\n\nclass MeetController extends BaseProjectController {\n\n\n\t// 把列表转换为显示模式\n\ttransMeetList(list) {\n\t\tlet ret = [];\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tlet node = {};\n\t\t\tnode.type = 'meet';\n\t\t\tnode.id = list[k]._id;\n\t\t\tnode.title = list[k].MEET_TITLE;\n\t\t\tnode.desc = list[k].MEET_STYLE_SET.desc;\n\t\t\tnode.ext = list[k].openRule;\n\t\t\tnode.pic = list[k].MEET_STYLE_SET.pic;\n\t\t\tret.push(node);\n\t\t}\n\t\treturn ret;\n\t}\n\n\n\t/** 按天获取预约项目 */\n\tasync getMeetListByDay() {\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tday: 'must|date|name=日期',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new MeetService();\n\t\tlet list = await service.getMeetListByDay(input.day);\n\t\treturn list;\n\n\n\t}\n\n\t/** 获取从某天开始可预约的日期 */\n\tasync getHasDaysFromDay() {\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tday: 'must|date|name=日期',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\n\t\tlet service = new MeetService();\n\t\tlet list = await service.getHasDaysFromDay(input.day);\n\t\treturn list;\n\n\t}\n\n\t/** 预约列表 */\n\tasync getMeetList() {\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tsearch: 'string|min:1|max:30|name=搜索条件',\n\t\t\tsortType: 'string|name=搜索类型',\n\t\t\tsortVal: 'name=搜索类型值',\n\t\t\torderBy: 'object|name=排序',\n\t\t\ttypeId: 'string',\n\t\t\tpage: 'must|int|default=1',\n\t\t\tsize: 'int',\n\t\t\tisTotal: 'bool',\n\t\t\toldTotal: 'int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new MeetService();\n\t\tlet result = await service.getMeetList(input);\n\n\t\t// 数据格式化\n\t\tlet list = result.list;\n\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tlist[k].openRule = this._getLeaveDay(list[k].MEET_DAYS) + '天可预约';\n\t\t}\n\n\t\tresult.list = this.transMeetList(list);\n\n\t\treturn result;\n\n\t}\n\n\t/** 我的预约列表 */\n\tasync getMyJoinList() {\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tsearch: 'string|min:1|max:30|name=搜索条件',\n\t\t\tsortType: 'string|name=搜索类型',\n\t\t\tsortVal: 'name=搜索类型值',\n\t\t\torderBy: 'object|name=排序',\n\t\t\tpage: 'must|int|default=1',\n\t\t\tsize: 'int',\n\t\t\tisTotal: 'bool',\n\t\t\toldTotal: 'int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new MeetService();\n\t\tlet result = await service.getMyJoinList(this._userId, input);\n\n\t\t// 数据格式化\n\t\tlet list = result.list;\n\n\t\tlet now = timeUtil.time('Y-M-D h:m');\n\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tif (now > (list[k].JOIN_MEET_DAY + ' ' + list[k].JOIN_MEET_TIME_END))\n\t\t\t\tlist[k].isTimeout = 1;\n\t\t\telse\n\t\t\t\tlist[k].isTimeout = 0;\n\n\t\t\tlist[k].JOIN_MEET_DAY = timeUtil.fmtDateCHN(list[k].JOIN_MEET_DAY) + ' (' + timeUtil.week(list[k].JOIN_MEET_DAY) + ')';\n\n\t\t\tlist[k].JOIN_ADD_TIME = timeUtil.timestamp2Time(list[k].JOIN_ADD_TIME, 'Y-M-D h:m');\n\t\t}\n\n\t\tresult.list = list;\n\n\t\treturn result;\n\n\t}\n\n\t/** 我的某日预约列表 */\n\tasync getMyJoinSomeday() {\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tday: 'must|date|name=日期',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new MeetService();\n\t\tlet list = await service.getMyJoinSomeday(this._userId, input.day);\n\n\t\t// 数据格式化  \n\t\tfor (let k = 0; k < list.length; k++) {\n\n\t\t}\n\n\t\treturn list;\n\n\t}\n\n\t/** 我的预约详情 */\n\tasync getMyJoinDetail() {\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tjoinId: 'must|id',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new MeetService();\n\t\tlet join = await service.getMyJoinDetail(this._userId, input.joinId);\n\t\tif (join) {\n\t\t\tjoin.JOIN_STATUS_DESC = JoinModel.getDesc('STATUS', join.JOIN_STATUS);\n\t\t\tjoin.JOIN_ADD_TIME = timeUtil.timestamp2Time(join.JOIN_ADD_TIME);\n\t\t}\n\t\treturn join;\n\n\t}\n\n\t/** 用户预约取消 */\n\tasync cancelMyJoin() {\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tjoinId: 'must|id',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new MeetService();\n\t\treturn await service.cancelMyJoin(this._userId, input.joinId);\n\t}\n\n\t/** 用户自助签到 */\n\tasync userSelfCheckin() {\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\ttimeMark: 'must|string',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new MeetService();\n\t\treturn await service.userSelfCheckin(this._userId, input.timeMark);\n\t}\n\n\n\t/**  预约前获取关键信息 */\n\tasync detailForJoin() {\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tmeetId: 'must|meetId',\n\t\t\ttimeMark: 'must|string',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new MeetService();\n\t\tlet meet = await service.detailForJoin(this._userId, input.meetId, input.timeMark);\n\n\t\tif (meet) {\n\t\t\t// 显示转换  \n\t\t}\n\n\t\treturn meet;\n\t}\n\n\t/** 浏览预约信息 */\n\tasync viewMeet() {\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new MeetService();\n\t\tlet meet = await service.viewMeet(input.id);\n\n\t\tif (meet) {\n\t\t\t// 显示转换  \n\t\t}\n\n\t\treturn meet;\n\t}\n\n\t/** 预约前检测 */\n\tasync beforeJoin() {\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tmeetId: 'must|id',\n\t\t\ttimeMark: 'must|string',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new MeetService();\n\t\treturn await service.beforeJoin(this._userId, input.meetId, input.timeMark);\n\t}\n\n\t/** 预约提交 */\n\tasync join() {\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tmeetId: 'must|id',\n\t\t\ttimeMark: 'must|string',\n\t\t\tforms: 'must|array',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new MeetService();\n\t\treturn await service.join(this._userId, input.meetId, input.timeMark, input.forms);\n\t}\n\n\n\t// 计算可约天数\n\t_getLeaveDay(days) {\n\t\tlet now = timeUtil.time('Y-M-D');\n\t\tlet count = 0;\n\t\tfor (let k = 0; k < days.length; k++) {\n\t\t\tif (days[k] >= now) count++;\n\t\t}\n\t\treturn count;\n\t}\n\n}\n\nmodule.exports = MeetController;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/my_controller.js",
    "content": "/**\n * Notes: 用户中心模块控制器\n * Date: 2021-03-15 19:20:00 \n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n */\n\nconst BaseProjectController = require('./base_project_controller.js');\n\nclass MyController extends BaseProjectController { \n\n}\n\nmodule.exports = MyController;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/news_controller.js",
    "content": "/**\n * Notes: 资讯模块控制器\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-09-29 04:00:00 \n */\n\nconst BaseProjectController = require('./base_project_controller.js');\nconst NewsService = require('../service/news_service.js');\nconst timeUtil = require('../../../framework/utils/time_util.js');\n\nclass NewsController extends BaseProjectController {\n\n\t// 把列表转换为显示模式\n\ttransNewsList(list) {\n\t\tlet ret = [];\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tlet node = {};\n\t\t\tnode.type = 'news';\n\t\t\tnode.id = list[k]._id;\n\t\t\tnode.title = list[k].NEWS_TITLE;\n\t\t\tnode.desc = list[k].NEWS_DESC;\n\t\t\tnode.ext = list[k].NEWS_ADD_TIME;\n\t\t\tnode.pic = list[k].NEWS_PIC[0];\n\t\t\tret.push(node);\n\t\t}\n\t\treturn ret;\n\t} \n\n\t/** 资讯列表 */\n\tasync getNewsList() {\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tsearch: 'string|min:1|max:30|name=搜索条件',\n\t\t\tsortType: 'string|name=搜索类型',\n\t\t\tsortVal: 'name=搜索类型值',\n\t\t\torderBy: 'object|name=排序',\n\t\t\tcateId: 'string',\n\t\t\tpage: 'must|int|default=1',\n\t\t\tsize: 'int',\n\t\t\tisTotal: 'bool',\n\t\t\toldTotal: 'int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new NewsService();\n\t\tlet result = await service.getNewsList(input);\n\n\t\t// 数据格式化\n\t\tlet list = result.list;\n\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tlist[k].NEWS_ADD_TIME = timeUtil.timestamp2Time(list[k].NEWS_ADD_TIME, 'Y-M-D');\n\n\t\t\tif (list[k].NEWS_OBJ && list[k].NEWS_OBJ.desc)\n\t\t\t\tdelete list[k].NEWS_OBJ.desc;\n\t\t}\n\t\tresult.list = this.transNewsList(list);\n\n\t\treturn result;\n\n\t}\n\n\n\t/** 浏览资讯信息 */\n\tasync viewNews() {\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new NewsService();\n\t\tlet news = await service.viewNews(input.id);\n\n\t\tif (news) {\n\t\t\t// 显示转换 \n\t\t\tnews.NEWS_ADD_TIME = timeUtil.timestamp2Time(news.NEWS_ADD_TIME, 'Y-M-D');\n\t\t}\n\n\t\treturn news;\n\t}\n\n\n\n}\n\nmodule.exports = NewsController;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/passport_controller.js",
    "content": "/**\n * Notes: passport模块控制器\n * Date: 2021-03-15 19:20:00 \n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n */\n\nconst BaseProjectController = require('./base_project_controller.js');\nconst PassportService = require('../service/passport_service.js');\nconst contentCheck = require('../../../framework/validate/content_check.js');\n\nclass PassportController extends BaseProjectController {\n\n\t/** 取得我的用户信息 */\n\tasync getMyDetail() {\n\t\tlet service = new PassportService();\n\t\treturn await service.getMyDetail(this._userId);\n\t}\n\n\t/** 获取手机号码 */\n\tasync getPhone() {\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tcloudID: 'must|string|min:1|max:200|name=cloudID',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\n\t\tlet service = new PassportService();\n\t\treturn await service.getPhone(input.cloudID);\n\t}\n\n\n\t/** 注册 */\n\tasync register() {\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tname: 'must|string|min:1|max:30|name=昵称',\n\t\t\tmobile: 'must|mobile|name=手机',\n\t\t\tforms: 'array|name=表单',\n\t\t\tstatus: 'int|default=1'\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\t// 内容审核\n\t\tawait contentCheck.checkTextMultiClient(input);\n\n\t\tlet service = new PassportService();\n\t\treturn await service.register(this._userId, input);\n\t}\n\n\t/** 修改用户资料 */\n\tasync editBase() {\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tname: 'must|string|min:1|max:30|name=昵称',\n\t\t\tmobile: 'must|mobile|name=手机',\n\t\t\tforms: 'array|name=表单',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\t// 内容审核\n\t\tawait contentCheck.checkTextMultiClient(input);\n\n\t\tlet service = new PassportService();\n\t\treturn await service.editBase(this._userId, input);\n\t}\n\n\t/** 登录 */\n\tasync login() {\n\t\t// 数据校验\n\t\tlet rules = {};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new PassportService();\n\t\treturn await service.login(this._userId);\n\t}\n\n}\n\nmodule.exports = PassportController;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/product_controller.js",
    "content": "/**\n * Notes: 产品模块控制器\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-06-08 04:00:00 \n */\n\nconst BaseProjectController = require('./base_project_controller.js');\nconst ProductService = require('../service/product_service.js');\nconst timeUtil = require('../../../framework/utils/time_util.js');\nconst dataUtil = require('../../../framework/utils/data_util.js');\n\nclass ProductController extends BaseProjectController {\n\n\t/** 列表 */\n\tasync getProductList() {\n\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tsearch: 'string|min:1|max:30|name=搜索条件',\n\t\t\tsortType: 'string|name=搜索类型',\n\t\t\tsortVal: 'name=搜索类型值',\n\t\t\torderBy: 'object|name=排序',\n\t\t\tpage: 'must|int|default=1',\n\t\t\tsize: 'int',\n\t\t\tisTotal: 'bool',\n\t\t\toldTotal: 'int',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new ProductService();\n\t\tlet result = await service.getProductList(input);\n\n\t\t// 数据格式化\n\t\tlet list = result.list;\n\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tlist[k].PRODUCT_ADD_TIME = timeUtil.timestamp2Time(list[k].PRODUCT_ADD_TIME, 'Y-M-D');\n\t\t\tlist[k].PRODUCT_OBJ.desc = dataUtil.fmtText(list[k].PRODUCT_OBJ.desc, 100);\n\t\t\tlist[k].PRODUCT_OBJ.star =  (list[k].PRODUCT_OBJ.star);\n\t\t}\n\n\t\treturn result;\n\n\t}\n\n\n\t/** 浏览详细 */\n\tasync viewProduct() {\n\t\t// 数据校验\n\t\tlet rules = {\n\t\t\tid: 'must|id',\n\t\t};\n\n\t\t// 取得数据\n\t\tlet input = this.validateData(rules);\n\n\t\tlet service = new ProductService();\n\t\tlet product = await service.viewProduct(input.id);\n\n\t\tif (product) {\n\t\t\t// 显示转换 \n\t\t\tproduct.PRODUCT_ADD_TIME = timeUtil.timestamp2Time(product.PRODUCT_ADD_TIME, 'Y-M-D');\n\t\t}\n\n\t\treturn product;\n\t}\n\n}\n\nmodule.exports = ProductController;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/test/test_controller.js",
    "content": "/**\n * Notes: 测试模块控制器\n * Date: 2021-03-15 19:20:00 \n */\n\nconst BaseController = require('../../controller/base_project_controller.js');\nconst fakerLib = require('../../../../framework/lib/faker_lib.js');\n\nconst VoteModel = require('../../model/vote_model.js');\nconst VoteJoinModel = require('../../model/vote_join_model.js');\nconst VoteService = require('../../service/vote_service.js');\n\nconst EnrollModel = require('../../model/enroll_model.js');\nconst EnrollJoinModel = require('../../model/enroll_join_model.js');\n\nconst ActivityModel = require('../../model/activity_model.js');\nconst ActivityJoinModel = require('../../model/activity_join_model.js');\n\nclass TestController extends BaseController {\n\n\tasync test() {\n\t\tconsole.log('TEST>>>>>>>');\n\n\t\t//this.mockEnrollJoin();\n\t\t//this.mockActivityJoin();\n\t\tthis.mockVoteJoin();\n\n\t}\n\n\tasync mockEnrollJoin() {\n\t\tconsole.log('mockEnrollJoin >>>>>>> Begin....');\n\t\tlet ENROLL_ID = 'b69f67c062d7d46b0bc4d2985c084775';\n\n\t\tlet enroll = await EnrollModel.getOne(ENROLL_ID);\n\t\tif (!enroll) return console.error('no enroll');\n\n\t\tlet join = {};\n\t\tjoin.ENROLL_JOIN_ENROLL_ID = ENROLL_ID;\n\t\tjoin.ENROLL_JOIN_STATUS = 1;\n\n\t\tconsole.log('>>>>delete');\n\t\tlet delCnt = await EnrollJoinModel.del({ ENROLL_JOIN_ENROLL_ID: ENROLL_ID });\n\t\tconsole.log('>>>>delete=' + delCnt);\n\n\t\tfor (let k = 1; k <= 10; k++) {\n\t\t\tconsole.log('>>>>insert >' + k);\n\t\t\tjoin.ENROLL_JOIN_USER_ID = fakerLib.getUuid();\n\n\t\t\tjoin.ENROLL_JOIN_LAST_TIME = fakerLib.getAddTimestamp();\n\t\t\tjoin.ENROLL_JOIN_ADD_TIME = fakerLib.getAddTimestamp();\n\n\t\t\tjoin.ENROLL_JOIN_FORMS = [\n\t\t\t\t{ mark: 'name', title: '姓名', type: 'text', val: fakerLib.getName() },\n\t\t\t\t{ mark: 'phone', title: '手机', type: 'mobile', val: fakerLib.getMobile() }\n\t\t\t];\n\n\t\t\tawait EnrollJoinModel.insert(join);\n\t\t}\n\n\t\tconsole.log('>>>> STAT');\n\t\tlet cnt = await EnrollJoinModel.count({\n\t\t\tENROLL_JOIN_ENROLL_ID: ENROLL_ID\n\t\t});\n\n\t\tawait EnrollModel.edit(ENROLL_ID, { ENROLL_JOIN_CNT: cnt, ENROLL_MAX_CNT: cnt + 10 });\n\n\t\tconsole.log('mockEnrollJoin >>>>>>> END');\n\t}\n\n\tasync mockActivityJoin() {\n\t\tconsole.log('mockActivityJoin >>>>>>> Begin....');\n\t\tlet ACTIVITY_ID = '0a4ec1f962d867481158b94f6441f613';\n\n\t\tlet activity = await ActivityModel.getOne(ACTIVITY_ID);\n\t\tif (!activity) return console.error('no activity');\n\n\t\tlet join = {};\n\t\tjoin.ACTIVITY_JOIN_ACTIVITY_ID = ACTIVITY_ID;\n\t\tjoin.ACTIVITY_JOIN_STATUS = 1;\n\n\t\tconsole.log('>>>>delete');\n\t\tlet delCnt = await ActivityJoinModel.del({ ACTIVITY_JOIN_ACTIVITY_ID: ACTIVITY_ID });\n\t\tconsole.log('>>>>delete=' + delCnt);\n\n\t\tfor (let k = 1; k <= 10; k++) {\n\t\t\tconsole.log('>>>>insert >' + k);\n\t\t\tjoin.ACTIVITY_JOIN_USER_ID = fakerLib.getUuid();\n\n\t\t\tjoin.ACTIVITY_JOIN_CODE = fakerLib.getStr(15);\n\t\t\tjoin.ACTIVITY_JOIN_ADD_TIME = fakerLib.getAddTimestamp();\n\n\t\t\tjoin.ACTIVITY_JOIN_FORMS = [\n\t\t\t\t{ mark: 'name', title: '姓名', type: 'text', val: fakerLib.getName() },\n\t\t\t\t{ mark: 'phone', title: '手机', type: 'mobile', val: fakerLib.getMobile() }\n\t\t\t];\n\n\t\t\tawait ActivityJoinModel.insert(join);\n\t\t}\n\n\t\tconsole.log('>>>> STAT');\n\t\tlet cnt = await ActivityJoinModel.count({\n\t\t\tACTIVITY_JOIN_ACTIVITY_ID: ACTIVITY_ID\n\t\t});\n\n\t\tawait ActivityModel.edit(ACTIVITY_ID, { ACTIVITY_JOIN_CNT: cnt, ACTIVITY_MAX_CNT: cnt + 10 });\n\n\t\tconsole.log('mockActivityJoin >>>>>>> END');\n\t}\n\n\n\tasync mockVoteJoin() {\n\t\tconsole.log('mockVoteJoin >>>>>>> Begin....');\n\t\tlet VOTE_ID = 'b69f67c062c3a2b209da6ef133c9d874';\n\n\t\tlet vote = await VoteModel.getOne(VOTE_ID);\n\t\tif (!vote) return console.error('no vote');\n\n\t\tlet join = {};\n\t\tjoin.VOTE_JOIN_VOTE_ID = VOTE_ID;\n\n\t\tconsole.log('>>>>delete');\n\t\tlet delCnt = await VoteJoinModel.del({ VOTE_JOIN_VOTE_ID: VOTE_ID });\n\t\tconsole.log('>>>>delete=' + delCnt);\n\n\n\t\tfor (let k = 1; k <= 10; k++) {\n\t\t\tconsole.log('>>>>insert >' + k);\n\t\t\tjoin.VOTE_JOIN_USER_ID = fakerLib.getUuid(); \n\t\t\tjoin.VOTE_JOIN_ADD_TIME = fakerLib.getAddTimestamp();\n\n\t\t\t\n\t\t\tjoin.VOTE_JOIN_CNT = 1;\n\t\t\tjoin.VOTE_JOIN_SELECTED = [k % vote.VOTE_ITEM.length];\n\n\t\t\tawait VoteJoinModel.insert(join);\n\t\t}\n\n\t\tconsole.log('>>>> STAT');\n\t\tlet service = new VoteService();\n\t\tservice.statVoteItem(VOTE_ID);\n\n\t\tconsole.log('mockVoteJoin >>>>>>> END');\n\t}\n}\n\nmodule.exports = TestController;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/model/album_model.js",
    "content": "/**\n * Notes:  相册实体\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-06-05 19:20:00 \n */\n\n\nconst BaseProjectModel = require('./base_project_model.js');\n\nclass AlbumModel extends BaseProjectModel {\n\n}\n\n// 集合名\nAlbumModel.CL = BaseProjectModel.C('album');\n\nAlbumModel.DB_STRUCTURE = {\n    _pid: 'string|true',\n    ALBUM_ID: 'string|true',\n\n    ALBUM_TITLE: 'string|true|comment=标题', \n    ALBUM_STATUS: 'int|true|default=1|comment=状态 0=未启用,1=使用中',\n\n    ALBUM_CATE_ID: 'string|true|default=0|comment=分类',\n    ALBUM_CATE_NAME: 'string|false|comment=分类名冗余',\n\n    ALBUM_ORDER: 'int|true|default=9999',\n    ALBUM_VOUCH: 'int|true|default=0',\n\n    ALBUM_FORMS: 'array|true|default=[]',\n    ALBUM_OBJ: 'object|true|default={}',\n\n\tALBUM_QR: 'string|false',\n    ALBUM_VIEW_CNT: 'int|true|default=0',\n\n    ALBUM_ADD_TIME: 'int|true',\n    ALBUM_EDIT_TIME: 'int|true',\n    ALBUM_ADD_IP: 'string|false',\n    ALBUM_EDIT_IP: 'string|false',\n};\n\n// 字段前缀\nAlbumModel.FIELD_PREFIX = \"ALBUM_\";\n\n/**\n * 状态 0=未启用,1=使用中 \n */\nAlbumModel.STATUS = {\n    UNUSE: 0,\n    COMM: 1\n};\n\n\n\nmodule.exports = AlbumModel;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/model/base_project_model.js",
    "content": "/**\n * Notes: 实体ORM基类 \n * Date: 2022-03-15 19:20:00 \n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n */\n\n\nconst BaseModel = require('../../../framework/platform/model/base_model.js');\n\nclass BaseProjectModel extends BaseModel {\n\n\n}\n\nmodule.exports = BaseProjectModel;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/model/day_model.js",
    "content": "/**\n * Notes: 预约日期设置实体\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-01-25 19:20:00 \n */\n\n\nconst BaseProjectModel = require('./base_project_model.js');\n\nclass DayModel extends BaseProjectModel {\n\n}\n\n// 集合名\nDayModel.CL = BaseProjectModel.C('day');\n\nDayModel.DB_STRUCTURE = {\n\t_pid: 'string|true',\n\tDAY_ID: 'string|true',\n\tDAY_MEET_ID: 'string|true',\n\n\tday: 'string|true|comment=日期 yyyy-mm-dd',\n\tdayDesc: 'string|true|comment=描述',\n\ttimes: 'array|true|comment=具体时间段',\n\t/*\n\t\t{\n\t\t\t1. mark=唯一性标识,\n\t\t\t2. start=开始时间点hh:mm ～,  \n\t\t\t3. end=结束时间点hh:mm, \n\t\t\t4. isLimit=是否人数限制, \n\t\t\t5. limit=报名上限,  \n\t\t\t6. status=状态 0/1\n\t\t\t7. stat:{ //统计数据 \n\t\t\t\tsuccCnt=1预约成功*, \n\t\t\t\tcancelCnt=10已取消, \n\t\t\t\tadminCancelCnt=99后台取消\n\t\t\t}\n\t\t}', \n\t*/\n\n\tDAY_ADD_TIME: 'int|true',\n\tDAY_EDIT_TIME: 'int|true',\n\tDAY_ADD_IP: 'string|false',\n\tDAY_EDIT_IP: 'string|false',\n};\n\n// 字段前缀\nDayModel.FIELD_PREFIX = \"DAY_\";\n\n\n\nmodule.exports = DayModel;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/model/fav_model.js",
    "content": "/**\n * Notes: 收藏实体\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-05-24 19:20:00 \n */\n\n\nconst BaseProjectModel = require('./base_project_model.js');\n\nclass FavModel extends BaseProjectModel {\n\n}\n\n// 集合名\nFavModel.CL = BaseProjectModel.C('fav');\n\nFavModel.DB_STRUCTURE = {\n\t_pid: 'string|true',\n\tFAV_ID: 'string|true',\n\n\tFAV_USER_ID: 'string|true',\n\n\tFAV_TITLE: 'string|true|comment=标题',\n\tFAV_TYPE: 'string|true|comment=类型',\n\tFAV_OID: 'string|true|comment=相关表主键',\n\tFAV_PATH: 'string|true|comment=路径',\n\n\tFAV_ADD_TIME: 'int|true',\n\tFAV_EDIT_TIME: 'int|true',\n\tFAV_ADD_IP: 'string|false',\n\tFAV_EDIT_IP: 'string|false',\n};\n\n// 字段前缀\nFavModel.FIELD_PREFIX = \"FAV_\";\n\nmodule.exports = FavModel;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/model/join_model.js",
    "content": "/**\n * Notes: 报名实体\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-12-30 19:20:00 \n */\n\n\nconst BaseProjectModel = require('./base_project_model.js');\n\nclass JoinModel extends BaseProjectModel {\n\n}\n\n// 集合名\nJoinModel.CL = BaseProjectModel.C('join');\n\nJoinModel.DB_STRUCTURE = {\n\t_pid: 'string|true',\n\tJOIN_ID: 'string|true',\n\n\tJOIN_EDIT_ADMIN_ID: 'string|false|comment=最近修改的管理员ID',\n\tJOIN_EDIT_ADMIN_NAME: 'string|false|comment=最近修改的管理员名',\n\tJOIN_EDIT_ADMIN_TIME: 'int|true|default=0|comment=管理员最近修改的时间',\n\tJOIN_EDIT_ADMIN_STATUS: 'int|false|comment=最近管理员修改为的状态 ',\n\n\tJOIN_IS_ADMIN: 'int|true|default=0|comment=是否管理员添加 0/1',\n\n\tJOIN_CODE: 'string|true|comment=核验码15位',\n\tJOIN_IS_CHECKIN: 'int|true|default=0|comment=是否签到 0/1 ',\n\n\tJOIN_USER_ID: 'string|true|comment=用户ID',\n\tJOIN_MEET_ID: 'string|true|comment=预约PK',\n\tJOIN_MEET_TITLE: 'string|true|comment=项目',\n\tJOIN_MEET_DAY: 'string|true|comment=日期',\n\tJOIN_MEET_TIME_START: 'string|true|comment=时段开始',\n\tJOIN_MEET_TIME_END: 'string|true|comment=时段结束',\n\tJOIN_MEET_TIME_MARK: 'string|true|comment=时段标识',\n\n\tJOIN_START_TIME: 'int|true|comment=开始时间戳',\n\n\tJOIN_FORMS: 'array|true|default=[]|comment=表单',\n\t/* title:\n\t   mark:\n\t   type:\n\t   val:\n\t*/\n\n\tJOIN_STATUS: 'int|true|default=1|comment=状态 1=预约成功,10=已取消, 99=系统取消',\n\n\tJOIN_REASON: 'string|false|comment=审核拒绝或者取消理由',\n\n\tJOIN_ADD_TIME: 'int|true',\n\tJOIN_EDIT_TIME: 'int|true',\n\tJOIN_ADD_IP: 'string|false',\n\tJOIN_EDIT_IP: 'string|false',\n};\n\n// 字段前缀\nJoinModel.FIELD_PREFIX = \"JOIN_\";\n\n/**\n * 状态 1=预约成功,10=已取消, 99=后台取消 \n */\nJoinModel.STATUS = {\n\tSUCC: 1,\n\tCANCEL: 10,\n\tADMIN_CANCEL: 99\n};\n\nJoinModel.STATUS_DESC = {\n\tSUCC: '预约成功',\n\tCANCEL: '已取消',\n\tADMIN_CANCEL: '系统取消',\n};\n\n\n\nmodule.exports = JoinModel;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/model/meet_model.js",
    "content": "/**\n * Notes: 预约实体\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-12-07 19:20:00 \n */\n\n\nconst BaseProjectModel = require('./base_project_model.js');\n\nclass MeetModel extends BaseProjectModel {\n\n}\n\n// 集合名\nMeetModel.CL = BaseProjectModel.C('meet');\n\nMeetModel.DB_STRUCTURE = {\n\t_pid: 'string|true',\n\tMEET_ID: 'string|true',\n\tMEET_ADMIN_ID: 'string|true|comment=添加的管理员',\n\tMEET_TITLE: 'string|true|comment=标题',\n\n\tMEET_CONTENT: 'array|true|default=[]|comment=详细介绍',  \n \n\tMEET_DAYS: 'array|true|default=[]|comment=最近一次修改保存的可用日期',\n  \n\tMEET_TYPE_ID: 'string|true|comment=分类编号',\n\tMEET_TYPE_NAME: 'string|true|comment=分类冗余', \n\n\tMEET_IS_SHOW_LIMIT: 'int|true|default=1|comment=是否显示可预约人数',\n\n\tMEET_STYLE_SET: 'object|true|default={}|comment=样式设置', \n\n\tMEET_FORM_SET: 'array|true|default=[]|comment=表单字段设置',\n\n\n\tMEET_STATUS: 'int|true|default=1|comment=状态 0=未启用,1=使用中,9=停止预约,10=已关闭',\n\tMEET_ORDER: 'int|true|default=9999',\n\tMEET_VOUCH: 'int|true|default=0',\n\n\tMEET_QR: 'string|false',\n\n\tMEET_ADD_TIME: 'int|true',\n\tMEET_EDIT_TIME: 'int|true',\n\tMEET_ADD_IP: 'string|false',\n\tMEET_EDIT_IP: 'string|false',\n};\n\n// 字段前缀\nMeetModel.FIELD_PREFIX = \"MEET_\";\n\n/**\n * 状态 0=未启用,1=使用中,9=停止预约,10=已关闭 \n */\nMeetModel.STATUS = {\n\tUNUSE: 0,\n\tCOMM: 1,\n\tOVER: 9,\n\tCLOSE: 10\n};\n\nMeetModel.STATUS_DESC = {\n\tUNUSE: '未启用',\n\tCOMM: '使用中',\n\tOVER: '停止预约(可见)',\n\tCLOSE: '已关闭(不可见)'\n};\n\n\n\nmodule.exports = MeetModel;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/model/news_model.js",
    "content": "/**\n * Notes: 资讯实体\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-10-28 19:20:00 \n */\n\n\nconst BaseProjectModel = require('./base_project_model.js');\n\nclass NewsModel extends BaseProjectModel {\n\n}\n\n// 集合名\nNewsModel.CL = BaseProjectModel.C('news');\n\nNewsModel.DB_STRUCTURE = {\n\t_pid: 'string|true',\n\tNEWS_ID: 'string|true',  \n\n\tNEWS_TITLE: 'string|false|comment=标题',\n\tNEWS_DESC: 'string|false|comment=描述',\n\tNEWS_STATUS: 'int|true|default=1|comment=状态 0/1',\n\n\tNEWS_CATE_ID: 'string|true|comment=分类编号',\n\tNEWS_CATE_NAME: 'string|true|comment=分类冗余',\n\n\tNEWS_ORDER: 'int|true|default=9999', \n\tNEWS_VOUCH: 'int|true|default=0',\n\n\tNEWS_CONTENT: 'array|true|default=[]|comment=内容', \n\n\tNEWS_QR: 'string|false',\n\tNEWS_VIEW_CNT: 'int|true|default=0|comment=访问次数',  \n\n\tNEWS_PIC: 'array|false|default=[]|comment=封面图  [cloudId1,cloudId2,cloudId3...]',\n\n\tNEWS_FORMS: 'array|true|default=[]',\n\tNEWS_OBJ: 'object|true|default={}',\n\n\tNEWS_ADD_TIME: 'int|true',\n\tNEWS_EDIT_TIME: 'int|true',\n\tNEWS_ADD_IP: 'string|false',\n\tNEWS_EDIT_IP: 'string|false',\n};\n\n// 字段前缀\nNewsModel.FIELD_PREFIX = \"NEWS_\";\n\n\nmodule.exports = NewsModel;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/model/product_model.js",
    "content": "/**\n * Notes:  套系实体\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-06-08 19:20:00 \n */\n\n\nconst BaseProjectModel = require('./base_project_model.js');\n\nclass ProductModel extends BaseProjectModel {\n\n}\n\n// 集合名\nProductModel.CL = BaseProjectModel.C('product');\n\nProductModel.DB_STRUCTURE = {\n\t_pid: 'string|true',\n\tPRODUCT_ID: 'string|true',\n\n\tPRODUCT_TITLE: 'string|true|comment=标题', \n\tPRODUCT_STATUS: 'int|true|default=1|comment=状态 0=未启用,1=使用中',\n\n\tPRODUCT_CATE_ID: 'string|true|default=0|comment=分类',\n\tPRODUCT_CATE_NAME: 'string|false|comment=分类冗余',\n\n\tPRODUCT_ORDER: 'int|true|default=9999',\n\tPRODUCT_VOUCH: 'int|true|default=0',\n\n\tPRODUCT_FORMS: 'array|true|default=[]',\n\tPRODUCT_OBJ: 'object|true|default={}',\n\n\tPRODUCT_QR: 'string|false',\n\tPRODUCT_VIEW_CNT: 'int|true|default=0',\n\n\tPRODUCT_ADD_TIME: 'int|true',\n\tPRODUCT_EDIT_TIME: 'int|true',\n\tPRODUCT_ADD_IP: 'string|false',\n\tPRODUCT_EDIT_IP: 'string|false',\n};\n\n// 字段前缀\nProductModel.FIELD_PREFIX = \"PRODUCT_\";\n\n/**\n * 状态 0=未启用,1=使用中 \n */\nProductModel.STATUS = {\n\tUNUSE: 0,\n\tCOMM: 1\n};\n\n\n\nmodule.exports = ProductModel;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/model/user_model.js",
    "content": "/**\n * Notes: 用户实体\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-10-14 19:20:00 \n */\n\n\nconst BaseProjectModel = require('./base_project_model.js');\nclass UserModel extends BaseProjectModel { }\n\n// 集合名\nUserModel.CL = BaseProjectModel.C('user');\n\nUserModel.DB_STRUCTURE = {\n\t_pid: 'string|true',\n\tUSER_ID: 'string|true',\n\n\tUSER_MINI_OPENID: 'string|true|comment=小程序openid',\n\tUSER_STATUS: 'int|true|default=1|comment=状态 0=待审核,1=正常,8=审核未过,9=禁用',\n\tUSER_CHECK_REASON: 'string|false|comment=审核未过的理由',\n\n\tUSER_NAME: 'string|false|comment=用户昵称',\n\tUSER_MOBILE: 'string|false|comment=联系电话',\n\n\tUSER_FORMS: 'array|true|default=[]',\n\tUSER_OBJ: 'object|true|default={}',\n\n\tUSER_LOGIN_CNT: 'int|true|default=0|comment=登陆次数',\n\tUSER_LOGIN_TIME: 'int|false|comment=最近登录时间',\n\n\n\tUSER_ADD_TIME: 'int|true',\n\tUSER_ADD_IP: 'string|false',\n\n\tUSER_EDIT_TIME: 'int|true',\n\tUSER_EDIT_IP: 'string|false',\n}\n\n// 字段前缀\nUserModel.FIELD_PREFIX = \"USER_\";\n\n/**\n * 状态 0=待审核,1=正常,2=审核未过,9=禁用\n */\nUserModel.STATUS = {\n\tUNUSE: 0,\n\tCOMM: 1,\n\tUNCHECK: 8,\n\tFORBID: 9\n};\n\nUserModel.STATUS_DESC = {\n\tUNUSE: '待审核',\n\tCOMM: '正常',\n\tUNCHECK: '未通过审核',\n\tFORBID: '禁用'\n};\n\n\nmodule.exports = UserModel;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/public/constants.js",
    "content": "module.exports = {    \n\t// 首页推荐\n\tSETUP_HOME_VOUCH_KEY : 'SETUP_HOME_VOUCH_KEY',\n}"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/public/project_config.js",
    "content": "module.exports = {\n\t// ## 缓存相关  \n\tCACHE_CALENDAR_TIME: 60 * 30, //日历缓存      \n \n}"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/public/route.js",
    "content": "/**\n * Notes: 路由配置文件\n  * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * User: CC\n * Date: 2020-10-14 07:00:00\n */\n\nmodule.exports = {\n\t'test/test': 'test/test_controller@test',\n\n\t'home/setup_get': 'home_controller@getSetup',\n\n\t'passport/login': 'passport_controller@login',\n\t'passport/phone': 'passport_controller@getPhone',\n\t'passport/my_detail': 'passport_controller@getMyDetail',\n\t'passport/register': 'passport_controller@register',\n\t'passport/edit_base': 'passport_controller@editBase',\n\n\t// 收藏\n\t'fav/update': 'fav_controller@updateFav',\n\t'fav/del': 'fav_controller@delFav',\n\t'fav/is_fav': 'fav_controller@isFav',\n\t'fav/my_list': 'fav_controller@getMyFavList',\n\n\t'admin/home': 'admin/admin_home_controller@adminHome',\n\t'admin/clear_vouch': 'admin/admin_home_controller@clearVouchData',\n\n\t'admin/login': 'admin/admin_mgr_controller@adminLogin',\n\t'admin/mgr_list': 'admin/admin_mgr_controller@getMgrList',\n\t'admin/mgr_insert': 'admin/admin_mgr_controller@insertMgr#demo',\n\t'admin/mgr_del': 'admin/admin_mgr_controller@delMgr#demo',\n\t'admin/mgr_detail': 'admin/admin_mgr_controller@getMgrDetail',\n\t'admin/mgr_edit': 'admin/admin_mgr_controller@editMgr#demo',\n\t'admin/mgr_status': 'admin/admin_mgr_controller@statusMgr#demo',\n\t'admin/mgr_pwd': 'admin/admin_mgr_controller@pwdMgr#demo',\n\t'admin/log_list': 'admin/admin_mgr_controller@getLogList',\n\t'admin/log_clear': 'admin/admin_mgr_controller@clearLog#demo',\n\n\t'admin/setup_set': 'admin/admin_setup_controller@setSetup#demo',\n\t'admin/setup_set_content': 'admin/admin_setup_controller@setContentSetup#demo',\n\t'admin/setup_qr': 'admin/admin_setup_controller@genMiniQr',\n\n\t// 用户\n\t'admin/user_list': 'admin/admin_user_controller@getUserList',\n\t'admin/user_detail': 'admin/admin_user_controller@getUserDetail',\n\t'admin/user_del': 'admin/admin_user_controller@delUser#demo',\n\t'admin/user_status': 'admin/admin_user_controller@statusUser#demo',\n\n\t'admin/user_data_get': 'admin/admin_user_controller@userDataGet',\n\t'admin/user_data_export': 'admin/admin_user_controller@userDataExport',\n\t'admin/user_data_del': 'admin/admin_user_controller@userDataDel',\n\n\n\t// 内容  \n\t'home/list': 'home_controller@getHomeList',\n\t'news/list': 'news_controller@getNewsList',\n\t'news/view': 'news_controller@viewNews',\n\n\t'admin/news_list': 'admin/admin_news_controller@getAdminNewsList',\n\t'admin/news_insert': 'admin/admin_news_controller@insertNews#demo',\n\t'admin/news_detail': 'admin/admin_news_controller@getNewsDetail',\n\t'admin/news_edit': 'admin/admin_news_controller@editNews#demo',\n\t'admin/news_update_forms': 'admin/admin_news_controller@updateNewsForms#demo',\n\t'admin/news_update_pic': 'admin/admin_news_controller@updateNewsPic#demo',\n\t'admin/news_update_content': 'admin/admin_news_controller@updateNewsContent#demo',\n\t'admin/news_del': 'admin/admin_news_controller@delNews#demo',\n\t'admin/news_sort': 'admin/admin_news_controller@sortNews#demo',\n\t'admin/news_status': 'admin/admin_news_controller@statusNews#demo',\n\t'admin/news_vouch': 'admin/admin_news_controller@vouchNews#demo',\n\n\t// 相册\n\t'album/list': 'album_controller@getAlbumList',\n\t'album/view': 'album_controller@viewAlbum',\n\n\t'admin/album_list': 'admin/admin_album_controller@getAdminAlbumList',\n\t'admin/album_insert': 'admin/admin_album_controller@insertAlbum#demo',\n\t'admin/album_detail': 'admin/admin_album_controller@getAlbumDetail',\n\t'admin/album_edit': 'admin/admin_album_controller@editAlbum#demo#demo',\n\t'admin/album_update_forms': 'admin/admin_album_controller@updateAlbumForms#demo',\n\t'admin/album_del': 'admin/admin_album_controller@delAlbum#demo',\n\t'admin/album_sort': 'admin/admin_album_controller@sortAlbum#demo',\n\t'admin/album_vouch': 'admin/admin_album_controller@vouchAlbum#demo',\n\t'admin/album_status': 'admin/admin_album_controller@statusAlbum#demo',\n\n\t// 产品 \n\t'product/list': 'product_controller@getProductList',\n\t'product/view': 'product_controller@viewProduct',\n\n\t'admin/product_list': 'admin/admin_product_controller@getAdminProductList',\n\t'admin/product_insert': 'admin/admin_product_controller@insertProduct#demo',\n\t'admin/product_detail': 'admin/admin_product_controller@getProductDetail',\n\t'admin/product_edit': 'admin/admin_product_controller@editProduct#demo',\n\t'admin/product_update_forms': 'admin/admin_product_controller@updateProductForms#demo',\n\t'admin/product_del': 'admin/admin_product_controller@delProduct#demo',\n\t'admin/product_sort': 'admin/admin_product_controller@sortProduct#demo',\n\t'admin/product_vouch': 'admin/admin_product_controller@vouchProduct#demo',\n\t'admin/product_status': 'admin/admin_product_controller@statusProduct#demo',\n\n\t// 预约\n\t'meet/list': 'meet_controller@getMeetList',\n\t'meet/list_by_day': 'meet_controller@getMeetListByDay',\n\t'meet/list_has_day': 'meet_controller@getHasDaysFromDay',\n\t'meet/view': 'meet_controller@viewMeet',\n\t'meet/detail_for_join': 'meet_controller@detailForJoin',\n\t'meet/before_join': 'meet_controller@beforeJoin',\n\t'meet/join': 'meet_controller@join',\n\n\t'meet/my_join_list': 'meet_controller@getMyJoinList',\n\t'meet/my_join_cancel': 'meet_controller@cancelMyJoin',\n\t'meet/my_join_detail': 'meet_controller@getMyJoinDetail',\n\t'meet/my_join_someday': 'meet_controller@getMyJoinSomeday',\n\t'meet/my_join_checkin': 'meet_controller@userSelfCheckin',\n\n\t'admin/meet_list': 'admin/admin_meet_controller@getAdminMeetList',\n\t'admin/meet_join_list': 'admin/admin_meet_controller@getJoinList',\n\t'admin/join_status': 'admin/admin_meet_controller@statusJoin#demo',\n\t'admin/join_del': 'admin/admin_meet_controller@delJoin#demo',\n\t'admin/meet_insert': 'admin/admin_meet_controller@insertMeet#demo',\n\t'admin/meet_detail': 'admin/admin_meet_controller@getMeetDetail',\n\t'admin/meet_edit': 'admin/admin_meet_controller@editMeet#demo',\n\t'admin/meet_del': 'admin/admin_meet_controller@delMeet#demo',\n\t'admin/meet_update_content': 'admin/admin_meet_controller@updateMeetContent#demo',\n\t'admin/meet_update_style': 'admin/admin_meet_controller@updateMeetStyleSet#demo',\n\t'admin/meet_sort': 'admin/admin_meet_controller@sortMeet#demo',\n\t'admin/meet_vouch': 'admin/admin_meet_controller@vouchMeet#demo',\n\t'admin/meet_status': 'admin/admin_meet_controller@statusMeet#demo',\n\t'admin/meet_cancel_time_join': 'admin/admin_meet_controller@cancelJoinByTimeMark#demo',\n\t'admin/join_scan': 'admin/admin_meet_controller@scanJoin',\n\t'admin/join_checkin': 'admin/admin_meet_controller@checkinJoin',\n\t'admin/self_checkin_qr': 'admin/admin_meet_controller@genSelfCheckinQr',\n\t'admin/meet_day_list': 'admin/admin_meet_controller@getDayList',\n\n\t'admin/meet_temp_insert': 'admin/admin_meet_controller@insertMeetTemp#demo',\n\t'admin/meet_temp_list': 'admin/admin_meet_controller@getMeetTempList',\n\t'admin/meet_temp_del': 'admin/admin_meet_controller@delMeetTemp#demo',\n\t'admin/meet_temp_edit': 'admin/admin_meet_controller@editMeetTemp#demo',\n\n\t'admin/join_data_get': 'admin/admin_meet_controller@joinDataGet',\n\t'admin/join_data_export': 'admin/admin_meet_controller@joinDataExport',\n\t'admin/join_data_del': 'admin/admin_meet_controller@joinDataDel',  \n \n}"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/admin/admin_album_service.js",
    "content": "/**\n * Notes: 相册后台管理\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-07-11 07:48:00 \n */\n\nconst BaseProjectAdminService = require('./base_project_admin_service.js');\n\nconst dataUtil = require('../../../../framework/utils/data_util.js');\nconst util = require('../../../../framework/utils/util.js');\nconst cloudUtil = require('../../../../framework/cloud/cloud_util.js');\nconst timeUtil = require('../../../../framework/utils/time_util.js');\nconst AlbumModel = require('../../model/album_model.js');\nconst AdminHomeService = require('../admin/admin_home_service.js');\n\nclass AdminAlbumService extends BaseProjectAdminService {\n\n\t/** 推荐首页SETUP */\n\tasync vouchAlbumSetup(id, vouch) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**添加 */\n\tasync insertAlbum({\n\t\ttitle,\n\t\tcateId,\n\t\tcateName,\n\t\torder,\n\t\tforms\n\t}) {\n\n\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**删除数据 */\n\tasync delAlbum(id) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\n\t}\n\n\t/**获取信息 */\n\tasync getAlbumDetail(id) {\n\t\tlet fields = '*';\n\n\t\tlet where = {\n\t\t\t_id: id\n\t\t}\n\t\tlet album = await AlbumModel.getOne(where, fields);\n\t\tif (!album) return null;\n\n\t\treturn album;\n\t}\n\n\t// 更新forms信息\n\tasync updateAlbumForms({\n\t\tid,\n\t\thasImageForms\n\t}) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\n\t/**更新数据 */\n\tasync editAlbum({\n\t\tid,\n\t\ttitle,\n\t\tcateId, // 二级分类 \n\t\tcateName,\n\t\torder,\n\t\tforms,\n\t}) {\n\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**取得分页列表 */\n\tasync getAdminAlbumList({\n\t\tsearch, // 搜索条件\n\t\tsortType, // 搜索菜单\n\t\tsortVal, // 搜索菜单\n\t\torderBy, // 排序\n\t\twhereEx, //附加查询条件\n\t\tpage,\n\t\tsize,\n\t\tisTotal = true,\n\t\toldTotal\n\t}) {\n\n\t\torderBy = orderBy || {\n\t\t\t'ALBUM_ORDER': 'asc',\n\t\t\t'ALBUM_ADD_TIME': 'desc'\n\t\t};\n\t\tlet fields = 'ALBUM_TITLE,ALBUM_CATE_ID,ALBUM_CATE_NAME,ALBUM_EDIT_TIME,ALBUM_ADD_TIME,ALBUM_ORDER,ALBUM_STATUS,ALBUM_VOUCH,ALBUM_QR,ALBUM_OBJ';\n\n\t\tlet where = {};\n\t\twhere.and = {\n\t\t\t_pid: this.getProjectId() //复杂的查询在此处标注PID\n\t\t};\n\n\t\tif (util.isDefined(search) && search) {\n\t\t\twhere.or = [\n\t\t\t\t{ ALBUM_TITLE: ['like', search] },\n\t\t\t];\n\n\t\t} else if (sortType && util.isDefined(sortVal)) {\n\t\t\t// 搜索菜单\n\t\t\tswitch (sortType) {\n\t\t\t\tcase 'cateId': {\n\t\t\t\t\twhere.and.ALBUM_CATE_ID = String(sortVal);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'status': {\n\t\t\t\t\twhere.and.ALBUM_STATUS = Number(sortVal);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'vouch': {\n\t\t\t\t\twhere.and.ALBUM_VOUCH = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\tcase 'top': {\n\t\t\t\t\t\twhere.and.ALBUM_ORDER = 0;\n\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\tcase 'sort': {\n\t\t\t\t\torderBy = this.fmtOrderBySort(sortVal, 'ALBUM_ADD_TIME');\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn await AlbumModel.getList(where, fields, orderBy, page, size, isTotal, oldTotal);\n\t}\n\n\t/**修改状态 */\n\tasync statusAlbum(id, status) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**置顶与排序设定 */\n\tasync sortAlbum(id, sort) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**首页设定 */\n\tasync vouchAlbum(id, vouch) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n}\n\nmodule.exports = AdminAlbumService;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/admin/admin_home_service.js",
    "content": "/**\n * Notes: 后台HOME/登录模块 \n * Date: 2021-06-15 07:48:00 \n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n */\n\nconst BaseProjectAdminService = require('./base_project_admin_service.js');\nconst UserModel = require('../../model/user_model.js');\nconst MeetModel = require('../../model/meet_model.js');\nconst NewsModel = require('../../model/news_model.js');\nconst ProductModel = require('../../model/product_model.js');   \nconst AlbumModel = require('../../model/album_model.js');\nconst constants = require('../../public/constants.js');\nconst setupUtil = require('../../../../framework/utils/setup/setup_util.js');\n\nclass AdminHomeService extends BaseProjectAdminService {\n\n\t/**\n\t * 首页数据归集\n\t */\n\tasync adminHome() {\n\t\tlet where = {};\n\n\t\tlet userCnt = await UserModel.count(where);\n\t\tlet newsCnt = await NewsModel.count(where);\n\t\tlet meetCnt = await MeetModel.count(where);\n\t\tlet productCnt = await ProductModel.count(where);\n\t\tlet albumCnt = await AlbumModel.count(where);\n\t\treturn [\n\t\t\t{ title: '用户数', cnt: userCnt },\n\t\t\t{ title: '资讯数', cnt: newsCnt },\n\t\t\t{ title: '预约项目', cnt: meetCnt },\n\t\t\t{ title: '景点数', cnt: productCnt },\n\t\t\t{ title: '攻略数', cnt: albumCnt },\n\t\t]\n\t}\n\n\t// 用户数据清理  \n\tasync clearUserData(userId) {\n\n\t}\n\n\n\t//##################首页推荐\n\t// 首页推荐清理\n\tasync clearVouchData() {\n\t\tawait setupUtil.remove(constants.SETUP_HOME_VOUCH_KEY);\n\n\t\tNewsModel.edit({}, { NEWS_VOUCH: 0 }); \n\t\tMeetModel.edit({}, { MEET_VOUCH: 0 });\n\t\tAlbumModel.edit({}, { ALBUM_VOUCH: 0 });\n\t\tProductModel.edit({}, { PRODUCT_VOUCH: 0 }); \n\n\t}\n\n\n\t/**添加首页推荐 */\n\tasync updateHomeVouch(node) {\n\t\tif (node.ext) node.ext = '#' + node.ext;\n\t\tlet key = constants.SETUP_HOME_VOUCH_KEY;\n\t\tlet list = await setupUtil.get(key);\n\t\tif (!list || !Array.isArray(list)) list = [];\n\n\t\t// 重复性判断\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tif (list[k].id == node.id) {\n\t\t\t\t// 已存在\n\t\t\t\tlist[k] = node;\n\t\t\t\treturn await setupUtil.set(key, list, 'vouch');\n\t\t\t}\n\t\t}\n\n\t\t// 赋值 \n\t\tlet data = node;\n\t\tlist.unshift(data);\n\t\tawait setupUtil.set(key, list, 'vouch');\n\n\t}\n\n\t/**删除推荐数据 */\n\tasync delHomeVouch(id) {\n\t\tlet key = constants.SETUP_HOME_VOUCH_KEY;\n\t\tlet list = await setupUtil.get(key);\n\t\tif (!list || !Array.isArray(list)) return;\n\n\t\tlet newList = [];\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tif (list[k].id != id) {\n\t\t\t\tnewList.push(list[k]);\n\t\t\t}\n\t\t}\n\n\t\treturn await setupUtil.set(key, newList, 'vouch');\n\n\t}\n}\n\nmodule.exports = AdminHomeService;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/admin/admin_meet_service.js",
    "content": "/**\n * Notes: 预约后台管理\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-12-08 07:48:00 \n */\n\nconst BaseProjectAdminService = require('./base_project_admin_service.js');\nconst MeetService = require('../meet_service.js');\nconst AdminHomeService = require('../admin/admin_home_service.js');\nconst dataUtil = require('../../../../framework/utils/data_util.js');\nconst timeUtil = require('../../../../framework/utils/time_util.js');\nconst setupUtil = require('../../../../framework/utils/setup/setup_util.js');\nconst util = require('../../../../framework/utils/util.js');\nconst cloudUtil = require('../../../../framework/cloud/cloud_util.js');\nconst cloudBase = require('../../../../framework/cloud/cloud_base.js');\n\nconst MeetModel = require('../../model/meet_model.js');\nconst JoinModel = require('../../model/join_model.js');\nconst DayModel = require('../../model/day_model.js');\n\nconst exportUtil = require('../../../../framework/utils/export_util.js');\n\nconst SETUP_MEET_TEMP_KEY = 'SETUP_MEET_TEMP';\n\n// 导出报名数据KEY\nconst EXPORT_JOIN_DATA_KEY = 'EXPORT_JOIN_DATA';\n\nclass AdminMeetService extends BaseProjectAdminService {\n\n\t/** 推荐首页SETUP */\n\tasync vouchMeetSetup(id, vouch) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\n\t/** 预约数据列表 */\n\tasync getDayList(meetId, start, end) {\n\t\tlet where = {\n\t\t\tDAY_MEET_ID: meetId,\n\t\t\tday: ['between', start, end]\n\t\t}\n\t\tlet orderBy = {\n\t\t\tday: 'asc'\n\t\t}\n\t\treturn await DayModel.getAllBig(where, 'day,times,dayDesc', orderBy);\n\t}\n\n\t// 按项目统计人数\n\tasync statJoinCntByMeet(meetId) {\n\t\tlet today = timeUtil.time('Y-M-D');\n\t\tlet where = {\n\t\t\tday: ['>=', today],\n\t\t\tDAY_MEET_ID: meetId\n\t\t}\n\n\t\tlet meetService = new MeetService();\n\t\tlet list = await DayModel.getAllBig(where, 'DAY_MEET_ID,times', {}, 1000);\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tlet meetId = list[k].DAY_MEET_ID;\n\t\t\tlet times = list[k].times;\n\n\t\t\tfor (let j in times) {\n\t\t\t\tlet timeMark = times[j].mark;\n\t\t\t\tmeetService.statJoinCnt(meetId, timeMark);\n\t\t\t}\n\t\t}\n\t}\n\n\t/** 自助签到码 */\n\tasync genSelfCheckinQr(page, timeMark) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/** 管理员按钮核销 */\n\tasync checkinJoin(joinId, flag) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/** 管理员扫码核销 */\n\tasync scanJoin(meetId, code) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**\n\t * 判断本日是否有预约记录\n\t * @param {*} daySet daysSet的节点\n\t */\n\tcheckHasJoinCnt(times) {\n\t\tif (!times) return false;\n\t\tfor (let k = 0; k < times.length; k++) {\n\t\t\tif (times[k].stat.succCnt) return true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t// 判断含有预约的日期\n\tgetCanModifyDaysSet(daysSet) {\n\t\tlet now = timeUtil.time('Y-M-D');\n\n\t\tfor (let k = 0; k < daysSet.length; k++) {\n\t\t\tif (daysSet[k].day < now) continue;\n\t\t\tdaysSet[k].hasJoin = this.checkHasJoinCnt(daysSet[k].times);\n\t\t}\n\n\t\treturn daysSet;\n\t}\n\n\t/** 取消某个时间段的所有预约记录 */\n\tasync cancelJoinByTimeMark(admin, meetId, timeMark, reason) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\n\t}\n\n\n\t/**添加 */\n\tasync insertMeet(adminId, {\n\t\ttitle,\n\t\torder,\n\t\ttypeId,\n\t\ttypeName,\n\t\tdaysSet,\n\t\tisShowLimit,\n\t\tformSet,\n\t}) {\n\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**删除数据 */\n\tasync delMeet(id) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**获取信息 */\n\tasync getMeetDetail(id) {\n\t\tlet fields = '*';\n\n\t\tlet where = {\n\t\t\t_id: id\n\t\t}\n\t\tlet meet = await MeetModel.getOne(where, fields);\n\t\tif (!meet) return null;\n\n\t\tlet meetService = new MeetService();\n\t\tmeet.MEET_DAYS_SET = await meetService.getDaysSet(id, timeUtil.time('Y-M-D')); //今天及以后\n\n\t\treturn meet;\n\t}\n\n\t/**\n\t * 更新富文本详细的内容及图片信息\n\t * @returns 返回 urls数组 [url1, url2, url3, ...]\n\t */\n\tasync updateMeetContent({\n\t\tid,\n\t\tcontent // 富文本数组\n\t}) {\n\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\n\t}\n\n\t/**\n\t * 更新封面内容及图片信息\n\t * @returns 返回 urls数组 [url1, url2, url3, ...]\n\t */\n\tasync updateMeetStyleSet({\n\t\tmeetId,\n\t\tstyleSet\n\t}) {\n\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\n\t}\n\n\t/** 更新日期设置 */\n\tasync _editDays(meetId, nowDay, daysSetData) {\n\t\t// 删除指定日期之后的记录（含)\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**更新数据 */\n\tasync editMeet({\n\t\tid,\n\t\ttitle,\n\t\ttypeId,\n\t\ttypeName,\n\t\torder,\n\t\tdaysSet,\n\t\tisShowLimit,\n\t\tformSet\n\t}) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\n\t}\n\n\t/**预约名单分页列表 */\n\tasync getJoinList({\n\t\tsearch, // 搜索条件\n\t\tsortType, // 搜索菜单\n\t\tsortVal, // 搜索菜单\n\t\torderBy, // 排序\n\t\tmeetId,\n\t\tmark,\n\t\tpage,\n\t\tsize,\n\t\tisTotal = true,\n\t\toldTotal\n\t}) {\n\n\t\torderBy = orderBy || {\n\t\t\t'JOIN_EDIT_TIME': 'desc'\n\t\t};\n\t\tlet fields = 'JOIN_IS_CHECKIN,JOIN_CODE,JOIN_ID,JOIN_REASON,JOIN_USER_ID,JOIN_MEET_ID,JOIN_MEET_TITLE,JOIN_MEET_DAY,JOIN_MEET_TIME_START,JOIN_MEET_TIME_END,JOIN_MEET_TIME_MARK,JOIN_FORMS,JOIN_STATUS,JOIN_EDIT_TIME';\n\n\t\tlet where = {\n\t\t\tJOIN_MEET_ID: meetId,\n\t\t\tJOIN_MEET_TIME_MARK: mark\n\t\t};\n\t\tif (util.isDefined(search) && search) {\n\t\t\twhere['JOIN_FORMS.val'] = {\n\t\t\t\t$regex: '.*' + search,\n\t\t\t\t$options: 'i'\n\t\t\t};\n\t\t} else if (sortType && util.isDefined(sortVal)) {\n\t\t\t// 搜索菜单\n\t\t\tswitch (sortType) {\n\t\t\t\tcase 'status':\n\t\t\t\t\t// 按类型\n\t\t\t\t\tsortVal = Number(sortVal);\n\t\t\t\t\tif (sortVal == 1099) //取消的2种\n\t\t\t\t\t\twhere.JOIN_STATUS = ['in', [10, 99]]\n\t\t\t\t\telse\n\t\t\t\t\t\twhere.JOIN_STATUS = Number(sortVal);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'checkin':\n\t\t\t\t\t// 签到\n\t\t\t\t\twhere.JOIN_STATUS = JoinModel.STATUS.SUCC;\n\t\t\t\t\tif (sortVal == 1) {\n\t\t\t\t\t\twhere.JOIN_IS_CHECKIN = 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\twhere.JOIN_IS_CHECKIN = 0;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn await JoinModel.getList(where, fields, orderBy, page, size, isTotal, oldTotal);\n\t}\n\n\t/**预约项目分页列表 */\n\tasync getAdminMeetList({\n\t\tsearch, // 搜索条件\n\t\tsortType, // 搜索菜单\n\t\tsortVal, // 搜索菜单\n\t\torderBy, // 排序\n\t\twhereEx, //附加查询条件\n\t\tpage,\n\t\tsize,\n\t\tisTotal = true,\n\t\toldTotal\n\t}) {\n\n\t\torderBy = orderBy || {\n\t\t\t'MEET_ORDER': 'asc',\n\t\t\t'MEET_ADD_TIME': 'desc'\n\t\t};\n\t\tlet fields = 'MEET_TYPE,MEET_TYPE_NAME,MEET_TITLE,MEET_STATUS,MEET_DAYS,MEET_ADD_TIME,MEET_EDIT_TIME,MEET_ORDER,MEET_VOUCH,MEET_QR';\n\n\t\tlet where = {};\n\t\tif (util.isDefined(search) && search) {\n\t\t\twhere.MEET_TITLE = {\n\t\t\t\t$regex: '.*' + search,\n\t\t\t\t$options: 'i'\n\t\t\t};\n\t\t} else if (sortType && util.isDefined(sortVal)) {\n\t\t\t// 搜索菜单\n\t\t\tswitch (sortType) {\n\t\t\t\tcase 'status':\n\t\t\t\t\t// 按类型\n\t\t\t\t\twhere.MEET_STATUS = Number(sortVal);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'typeId':\n\t\t\t\t\t// 按类型\n\t\t\t\t\twhere.MEET_TYPE_ID = sortVal;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'sort':\n\t\t\t\t\t// 排序\n\t\t\t\t\tif (sortVal == 'view') {\n\t\t\t\t\t\torderBy = {\n\t\t\t\t\t\t\t'MEET_VIEW_CNT': 'desc',\n\t\t\t\t\t\t\t'MEET_ADD_TIME': 'desc'\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn await MeetModel.getList(where, fields, orderBy, page, size, isTotal, oldTotal);\n\t}\n\n\t/** 删除 */\n\tasync delJoin(joinId) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\n\t}\n\n\t/**修改报名状态 \n\t * 特殊约定 99=>正常取消 \n\t */\n\tasync statusJoin(admin, joinId, status, reason = '') {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**修改项目状态 */\n\tasync statusMeet(id, status) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**置顶排序设定 */\n\tasync sortMeet(id, sort) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**首页设定 */\n\tasync vouchMeet(id, vouch) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t//##################模板\n\t/**添加模板 */\n\tasync insertMeetTemp({\n\t\tname,\n\t\ttimes,\n\t}) {\n\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\n\t}\n\n\t/**更新数据 */\n\tasync editMeetTemp({\n\t\tid,\n\t\tlimit,\n\t\tisLimit\n\t}) {\n\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\n\t/**删除数据 */\n\tasync delMeetTemp(id) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\n\t}\n\n\n\t/**模板列表 */\n\tasync getMeetTempList() {\n\t\tlet list = await setupUtil.get(SETUP_MEET_TEMP_KEY);\n\t\tif (!list || !Array.isArray(list)) list = [];\n\t\treturn list;\n\t}\n\n\t// #####################导出报名数据\n\t/**获取报名数据 */\n\tasync getJoinDataURL() {\n\t\treturn await exportUtil.getExportDataURL(EXPORT_JOIN_DATA_KEY);\n\t}\n\n\t/**删除报名数据 */\n\tasync deleteJoinDataExcel() {\n\t\treturn await exportUtil.deleteDataExcel(EXPORT_JOIN_DATA_KEY);\n\t}\n\n\t/**导出报名数据 */\n\tasync exportJoinDataExcel({\n\t\tmeetId,\n\t\tstartDay,\n\t\tendDay,\n\t\tstatus\n\t}) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\n\t}\n\n}\n\nmodule.exports = AdminMeetService;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/admin/admin_mgr_service.js",
    "content": "/**\n * Notes: 管理员管理\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-07-11 07:48:00 \n */\n\nconst BaseProjectAdminService = require('./base_project_admin_service.js');\nconst util = require('../../../../framework/utils/util.js');\nconst dataUtil = require('../../../../framework/utils/data_util.js');\nconst timeUtil = require('../../../../framework/utils/time_util.js');\nconst AdminModel = require('../../../../framework/platform/model/admin_model.js');\nconst LogModel = require('../../../../framework/platform/model/log_model.js');\nconst md5Lib = require('../../../../framework/lib/md5_lib.js');\n\nclass AdminMgrService extends BaseProjectAdminService {\n\n\t//**管理员登录  */\n\tasync adminLogin(name, password) {\n\n\t\t// 判断是否存在\n\t\tlet where = {\n\t\t\tADMIN_STATUS: 1,\n\t\t\tADMIN_NAME: name,\n\t\t\tADMIN_PASSWORD: md5Lib.md5(password)\n\t\t}\n\t\tlet fields = 'ADMIN_ID,ADMIN_NAME,ADMIN_DESC,ADMIN_TYPE,ADMIN_LOGIN_TIME,ADMIN_LOGIN_CNT';\n\t\tlet admin = await AdminModel.getOne(where, fields);\n\t\tif (!admin)\n\t\t\tthis.AppError('管理员不存在或者已停用');\n\n\t\tlet cnt = admin.ADMIN_LOGIN_CNT;\n\n\t\t// 生成token\n\t\tlet token = dataUtil.genRandomString(32);\n\t\tlet tokenTime = timeUtil.time();\n\t\tlet data = {\n\t\t\tADMIN_TOKEN: token,\n\t\t\tADMIN_TOKEN_TIME: tokenTime,\n\t\t\tADMIN_LOGIN_TIME: timeUtil.time(),\n\t\t\tADMIN_LOGIN_CNT: cnt + 1\n\t\t}\n\t\tawait AdminModel.edit(where, data);\n\n\t\tlet type = admin.ADMIN_TYPE;\n\t\tlet last = (!admin.ADMIN_LOGIN_TIME) ? '尚未登录' : timeUtil.timestamp2Time(admin.ADMIN_LOGIN_TIME);\n\n\t\t// 写日志\n\t\tthis.insertLog('登录了系统', admin, LogModel.TYPE.SYS);\n\n\t\treturn {\n\t\t\ttoken,\n\t\t\tname: admin.ADMIN_NAME,\n\t\t\ttype,\n\t\t\tlast,\n\t\t\tcnt\n\t\t}\n\n\t}\n\n\tasync clearLog() {\n\t\tlet where = {}\n\t\tawait LogModel.del(where);\n\t}\n\n\t/** 取得日志分页列表 */\n\tasync getLogList({\n\t\tsearch, // 搜索条件\n\t\tsortType, // 搜索菜单\n\t\tsortVal, // 搜索菜单\n\t\torderBy, // 排序\n\t\twhereEx, //附加查询条件 \n\t\tpage,\n\t\tsize,\n\t\toldTotal = 0\n\t}) {\n\n\t\torderBy = orderBy || {\n\t\t\tLOG_ADD_TIME: 'desc'\n\t\t};\n\t\tlet fields = '*';\n\t\tlet where = {};\n\n\t\tif (util.isDefined(search) && search) {\n\t\t\twhere.or = [{\n\t\t\t\tLOG_CONTENT: ['like', search]\n\t\t\t}, {\n\t\t\t\tLOG_ADMIN_DESC: ['like', search]\n\t\t\t}, {\n\t\t\t\tLOG_ADMIN_NAME: ['like', search]\n\t\t\t}];\n\n\t\t} else if (sortType && util.isDefined(sortVal)) {\n\t\t\t// 搜索菜单\n\t\t\tswitch (sortType) {\n\t\t\t\tcase 'type':\n\t\t\t\t\t// 按类型\n\t\t\t\t\twhere.LOG_TYPE = Number(sortVal);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tlet result = await LogModel.getList(where, fields, orderBy, page, size, true, oldTotal);\n\n\n\t\treturn result;\n\t}\n\n\t/** 获取所有管理员 */\n\tasync getMgrList({\n\t\tsearch, // 搜索条件\n\t\tsortType, // 搜索菜单\n\t\tsortVal, // 搜索菜单\n\t\torderBy, // 排序\n\t\twhereEx, //附加查询条件\n\t\tpage,\n\t\tsize,\n\t\tisTotal = true,\n\t\toldTotal\n\t}) {\n\t\torderBy = {\n\t\t\tADMIN_ADD_TIME: 'desc'\n\t\t}\n\t\tlet fields = 'ADMIN_NAME,ADMIN_STATUS,ADMIN_PHONE,ADMIN_TYPE,ADMIN_LOGIN_CNT,ADMIN_LOGIN_TIME,ADMIN_DESC,ADMIN_EDIT_TIME,ADMIN_EDIT_IP';\n\n\t\tlet where = {};\n\t\twhere.and = {\n\t\t\t_pid: this.getProjectId() //复杂的查询在此处标注PID\n\t\t};\n\t\tif (util.isDefined(search) && search) {\n\t\t\twhere.or = [{\n\t\t\t\tADMIN_NAME: ['like', search]\n\t\t\t},\n\t\t\t{\n\t\t\t\tADMIN_PHONE: ['like', search]\n\t\t\t},\n\t\t\t{\n\t\t\t\tADMIN_DESC: ['like', search]\n\t\t\t}\n\t\t\t];\n\t\t} else if (sortType && util.isDefined(sortVal)) {\n\t\t\t// 搜索菜单\n\t\t\tswitch (sortType) {\n\t\t\t\tcase 'status':\n\t\t\t\t\t// 按类型\n\t\t\t\t\twhere.and.ADMIN_STATUS = Number(sortVal);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'type':\n\t\t\t\t\t// 按类型\n\t\t\t\t\twhere.and.ADMIN_TYPE = Number(sortVal);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn await AdminModel.getList(where, fields, orderBy, page, size, isTotal, oldTotal);\n\t}\n\n\t/** 删除管理员 */\n\tasync delMgr(id, myAdminId) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/** 添加新的管理员 */\n\tasync insertMgr({\n\t\tname,\n\t\tdesc,\n\t\tphone,\n\t\tpassword\n\t}) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\n\t}\n\n\t/** 修改状态 */\n\tasync statusMgr(id, status, myAdminId) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t} \n \n\n\t/** 获取管理员信息 */\n\tasync getMgrDetail(id) {\n\t\tlet fields = '*';\n\n\t\tlet where = {\n\t\t\t_id: id\n\t\t}\n\t\tlet mgr = await AdminModel.getOne(where, fields);\n\t\tif (!mgr) return null;\n\n\t\treturn mgr;\n\t}\n\n\t/** 修改管理员 */\n\tasync editMgr(id, {\n\t\tname,\n\t\tdesc,\n\t\tphone,\n\t\tpassword\n\t}) {\n\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/** 修改自身密码 */\n\tasync pwdtMgr(adminId, oldPassword, password) {\n\n\t\tlet where = {\n\t\t\t_id: adminId,\n\t\t\tADMIN_PASSWORD: md5Lib.md5(oldPassword),\n\t\t}\n\t\tlet admin = await AdminModel.getOne(where);\n\t\tif (!admin)\n\t\t\tthis.AppError('旧密码错误');\n\n\t\tlet data = {\n\t\t\tADMIN_PASSWORD: md5Lib.md5(password),\n\t\t}\n\t\treturn await AdminModel.edit(adminId, data);\n\t}\n}\n\nmodule.exports = AdminMgrService;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/admin/admin_news_service.js",
    "content": "/**\n * Notes: 资讯后台管理\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-07-11 07:48:00 \n */\n\nconst BaseProjectAdminService = require('./base_project_admin_service.js');\nconst AdminHomeService = require('../admin/admin_home_service.js');\nconst dataUtil = require('../../../../framework/utils/data_util.js');\nconst util = require('../../../../framework/utils/util.js');\nconst timeUtil = require('../../../../framework/utils/time_util.js');\nconst cloudUtil = require('../../../../framework/cloud/cloud_util.js');\n\nconst NewsModel = require('../../model/news_model.js');\n\nclass AdminNewsService extends BaseProjectAdminService {\n\n\t/** 推荐首页SETUP */\n\tasync vouchNewsSetup(id, vouch) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**添加资讯 */\n\tasync insertNews({\n\t\ttitle,\n\t\tcateId, //分类\n\t\tcateName,\n\t\torder,\n\t\tdesc = '',\n\t\tforms\n\t}) {\n\n\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**删除资讯数据 */\n\tasync delNews(id) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**获取资讯信息 */\n\tasync getNewsDetail(id) {\n\t\tlet fields = '*';\n\n\t\tlet where = {\n\t\t\t_id: id\n\t\t}\n\t\tlet news = await NewsModel.getOne(where, fields);\n\t\tif (!news) return null;\n\n\t\treturn news;\n\t}\n\n\t// 更新forms信息\n\tasync updateNewsForms({\n\t\tid,\n\t\thasImageForms\n\t}) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\n\t/**\n\t * 更新富文本详细的内容及图片信息\n\t * @returns 返回 urls数组 [url1, url2, url3, ...]\n\t */\n\tasync updateNewsContent({\n\t\tid,\n\t\tcontent // 富文本数组\n\t}) {\n\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\n\t}\n\n\t/**\n\t * 更新资讯图片信息\n\t * @returns 返回 urls数组 [url1, url2, url3, ...]\n\t */\n\tasync updateNewsPic({\n\t\tid,\n\t\timgList // 图片数组\n\t}) {\n\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\n\t}\n\n\n\t/**更新资讯数据 */\n\tasync editNews({\n\t\tid,\n\t\ttitle,\n\t\tcateId, //分类\n\t\tcateName,\n\t\torder,\n\t\tdesc = '',\n\t\tforms\n\t}) {\n\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**取得资讯分页列表 */\n\tasync getAdminNewsList({\n\t\tsearch, // 搜索条件\n\t\tsortType, // 搜索菜单\n\t\tsortVal, // 搜索菜单\n\t\torderBy, // 排序\n\t\twhereEx, //附加查询条件\n\t\tpage,\n\t\tsize,\n\t\tisTotal = true,\n\t\toldTotal\n\t}) {\n\n\t\torderBy = orderBy || {\n\t\t\t'NEWS_ORDER': 'asc',\n\t\t\t'NEWS_ADD_TIME': 'desc'\n\t\t};\n\t\tlet fields = 'NEWS_TITLE,NEWS_DESC,NEWS_CATE_ID,NEWS_CATE_NAME,NEWS_EDIT_TIME,NEWS_ADD_TIME,NEWS_ORDER,NEWS_STATUS,NEWS_CATE2_NAME,NEWS_VOUCH,NEWS_QR,NEWS_OBJ';\n\n\t\tlet where = {};\n\t\twhere.and = {\n\t\t\t_pid: this.getProjectId() //复杂的查询在此处标注PID\n\t\t};\n\n\t\tif (util.isDefined(search) && search) {\n\t\t\twhere.or = [\n\t\t\t\t{ NEWS_TITLE: ['like', search] },\n\t\t\t];\n\n\t\t} else if (sortType && util.isDefined(sortVal)) {\n\t\t\t// 搜索菜单\n\t\t\tswitch (sortType) {\n\t\t\t\tcase 'cateId': {\n\t\t\t\t\twhere.and.NEWS_CATE_ID = String(sortVal);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'status': {\n\t\t\t\t\twhere.and.NEWS_STATUS = Number(sortVal);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'vouch': {\n\t\t\t\t\twhere.and.NEWS_VOUCH = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'top': {\n\t\t\t\t\twhere.and.NEWS_ORDER = 0;\n\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\tcase 'sort': {\n\t\t\t\t\torderBy = this.fmtOrderBySort(sortVal, 'NEWS_ADD_TIME');\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t}\n\t\t}\n\n\t\treturn await NewsModel.getList(where, fields, orderBy, page, size, isTotal, oldTotal);\n\t}\n\n\t/**修改资讯状态 */\n\tasync statusNews(id, status) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**置顶与排序设定 */\n\tasync sortNews(id, sort) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**首页设定 */\n\tasync vouchNews(id, vouch) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n}\n\nmodule.exports = AdminNewsService;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/admin/admin_product_service.js",
    "content": "/**\n * Notes: 产品后台管理\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-06-08 07:48:00 \n */\n\nconst BaseProjectAdminService = require('./base_project_admin_service.js');\nconst AdminHomeService = require('../admin/admin_home_service.js');\nconst dataUtil = require('../../../../framework/utils/data_util.js');\nconst util = require('../../../../framework/utils/util.js');\nconst cloudUtil = require('../../../../framework/cloud/cloud_util.js');\nconst timeUtil = require('../../../../framework/utils/time_util.js');\nconst ProductModel = require('../../model/product_model.js');\n\nclass AdminProductService extends BaseProjectAdminService {\n\n\t/** 推荐首页SETUP */\n\tasync vouchProductSetup(id, vouch) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**添加 */\n\tasync insertProduct({\n\t\ttitle,\n\t\tcateId,\n\t\tcateName,\n\t\torder,\n\t\tforms\n\t}) {\n\n\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**删除数据 */\n\tasync delProduct(id) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\n\t}\n\n\t/**获取信息 */\n\tasync getProductDetail(id) {\n\t\tlet fields = '*';\n\n\t\tlet where = {\n\t\t\t_id: id\n\t\t}\n\t\tlet product = await ProductModel.getOne(where, fields);\n\t\tif (!product) return null;\n\n\t\treturn product;\n\t}\n\n\t// 更新forms信息\n\tasync updateProductForms({\n\t\tid,\n\t\thasImageForms\n\t}) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\n\t/**更新数据 */\n\tasync editProduct({\n\t\tid,\n\t\ttitle,\n\t\tcateId, // 二级分类 \n\t\tcateName,\n\t\torder,\n\t\tforms,\n\t}) {\n\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**取得分页列表 */\n\tasync getAdminProductList({\n\t\tsearch, // 搜索条件\n\t\tsortType, // 搜索菜单\n\t\tsortVal, // 搜索菜单\n\t\torderBy, // 排序\n\t\twhereEx, //附加查询条件\n\t\tpage,\n\t\tsize,\n\t\tisTotal = true,\n\t\toldTotal\n\t}) {\n\n\t\torderBy = orderBy || {\n\t\t\t'PRODUCT_ORDER': 'asc',\n\t\t\t'PRODUCT_ADD_TIME': 'desc'\n\t\t};\n\t\tlet fields = 'PRODUCT_TITLE,PRODUCT_CATE_ID,PRODUCT_CATE_NAME,PRODUCT_EDIT_TIME,PRODUCT_ADD_TIME,PRODUCT_ORDER,PRODUCT_STATUS,PRODUCT_VOUCH,,PRODUCT_QR,PRODUCT_OBJ';\n\n\t\tlet where = {};\n\t\twhere.and = {\n\t\t\t_pid: this.getProjectId() //复杂的查询在此处标注PID\n\t\t};\n\n\t\tif (util.isDefined(search) && search) {\n\t\t\twhere.or = [\n\t\t\t\t{ PRODUCT_TITLE: ['like', search] },\n\t\t\t];\n\n\t\t} else if (sortType && util.isDefined(sortVal)) {\n\t\t\t// 搜索菜单\n\t\t\tswitch (sortType) {\n\t\t\t\tcase 'cateId': {\n\t\t\t\t\twhere.and.PRODUCT_CATE_ID = String(sortVal);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'status': {\n\t\t\t\t\twhere.and.PRODUCT_STATUS = Number(sortVal);\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'vouch': {\n\t\t\t\t\t\twhere.and.PRODUCT_VOUCH = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\tcase 'top': {\n\t\t\t\t\t\twhere.and.PRODUCT_ORDER = 0;\n\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\tcase 'sort': {\n\t\t\t\t\torderBy = this.fmtOrderBySort(sortVal, 'PRODUCT_ADD_TIME');\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn await ProductModel.getList(where, fields, orderBy, page, size, isTotal, oldTotal);\n\t}\n\n\t/**修改状态 */\n\tasync statusProduct(id, status) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**置顶与排序设定 */\n\tasync sortProduct(id, sort) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\n\t}\n\n\t/**首页设定 */\n\tasync vouchProduct(id, vouch) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n}\n\nmodule.exports = AdminProductService;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/admin/admin_setup_service.js",
    "content": "/**\n * Notes: 设置管理\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-07-11 07:48:00 \n */\n\nconst BaseProjectAdminService = require('./base_project_admin_service.js');\nconst cloudBase = require('../../../../framework/cloud/cloud_base.js');\nconst cloudUtil = require('../../../../framework/cloud/cloud_util.js');\nconst setupUtil = require('../../../../framework/utils/setup/setup_util.js');\nconst config = require('../../../../config/config.js');\nconst md5Lib = require('../../../../framework/lib/md5_lib.js');\n\nclass AdminSetupService extends BaseProjectAdminService {\n\n\t// 通用setup\n\tasync setSetup(key, val, type = '') {\n\t\tawait setupUtil.set(key, val, type);\n\t}\n\n\t/** 小程序码 */\n\tasync genMiniQr(page, sc = 'qr') {\n\t\t//生成小程序qr buffer\n\t\tlet cloud = cloudBase.getCloud();\n\n\t\tif (page.startsWith('/')) page = page.substring(1);\n\t\tconsole.log('page=' + page, ', scene=' + sc);\n\n\t\tlet color = ['0', '0', '0'];\n\t\tif (config.TEST_MODE == true && page.includes('default/index/default_index')) {\n\t\t\t// 首页且测试模式\n\t\t\tlet rd = PID;\n\t\t\trd = rd.match(/\\d+/g).join('');\n\t\t\trd = Number(rd) % 20;\n\n\t\t\tlet colorArr = [];\n\t\t\tcolorArr.push('0 238 238');\n\t\t\tcolorArr.push('47 79 79');\n\t\t\tcolorArr.push('105 139 105');\n\t\t\tcolorArr.push('119 136 153');\n\t\t\tcolorArr.push('100 149 237');\n\t\t\tcolorArr.push('0 205 0');\n\t\t\tcolorArr.push('176 196 222');\n\t\t\tcolorArr.push('205 190 112');\n\t\t\tcolorArr.push('255 20 147');\n\t\t\tcolorArr.push('139 90 0');\n\t\t\tcolorArr.push('205 16 118');\n\t\t\tcolorArr.push('255 174 185');\n\t\t\tcolorArr.push('108 166 205');\n\t\t\tcolorArr.push('0 0 139');\n\t\t\tcolorArr.push('130 130 130');\n\t\t\tcolorArr.push('205 150 205');\n\t\t\tcolorArr.push('205 102 0');\n\t\t\tcolorArr.push('139 101 8');\n\t\t\tcolorArr.push('72 209 204');\n\t\t\tcolorArr.push('176 196 222');\n\t\t\tcolor = colorArr[rd].split(' ');\n\t\t}\n\n\n\t\tlet result = await cloud.openapi.wxacode.getUnlimited({\n\t\t\tscene: sc,\n\t\t\twidth: 280,\n\t\t\tlineColor: {\n\t\t\t\tr: color[0],\n\t\t\t\tg: color[1],\n\t\t\t\tb: color[2],\n\t\t\t},\n\t\t\tcheck_path: false,\n\t\t\t//env_version: 'trial', //release,trial,develop\n\t\t\tpage\n\t\t});\n\n\t\tlet cloudPath = PID + '/' + 'setup/' + md5Lib.md5(page) + '.png';\n\t\tlet upload = await cloud.uploadFile({\n\t\t\tcloudPath,\n\t\t\tfileContent: result.buffer,\n\t\t});\n\n\t\tif (!upload || !upload.fileID) return;\n\n\t\tlet ret = await cloudUtil.getTempFileURLOne(upload.fileID);\n\t\treturn ret + '?rd=' + this._timestamp;\n\t}\n\n}\n\nmodule.exports = AdminSetupService;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/admin/admin_user_service.js",
    "content": "/**\n * Notes: 用户管理\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-01-22  07:48:00 \n */\n\nconst BaseProjectAdminService = require('./base_project_admin_service.js');\n\nconst util = require('../../../../framework/utils/util.js');\nconst exportUtil = require('../../../../framework/utils/export_util.js');\nconst timeUtil = require('../../../../framework/utils/time_util.js');\nconst dataUtil = require('../../../../framework/utils/data_util.js');\nconst UserModel = require('../../model/user_model.js');\nconst AdminHomeService = require('./admin_home_service.js');\n\n// 导出用户数据KEY\nconst EXPORT_USER_DATA_KEY = 'EXPORT_USER_DATA';\n\nclass AdminUserService extends BaseProjectAdminService {\n\n\n\t/** 获得某个用户信息 */\n\tasync getUser({\n\t\tuserId,\n\t\tfields = '*'\n\t}) {\n\t\tlet where = {\n\t\t\tUSER_MINI_OPENID: userId,\n\t\t}\n\t\treturn await UserModel.getOne(where, fields);\n\t}\n\n\t/** 取得用户分页列表 */\n\tasync getUserList({\n\t\tsearch, // 搜索条件\n\t\tsortType, // 搜索菜单\n\t\tsortVal, // 搜索菜单\n\t\torderBy, // 排序\n\t\twhereEx, //附加查询条件 \n\t\tpage,\n\t\tsize,\n\t\toldTotal = 0\n\t}) {\n\n\t\torderBy = orderBy || {\n\t\t\tUSER_ADD_TIME: 'desc'\n\t\t};\n\t\tlet fields = '*';\n\n\n\t\tlet where = {};\n\t\twhere.and = {\n\t\t\t_pid: this.getProjectId() //复杂的查询在此处标注PID\n\t\t};\n\n\t\tif (util.isDefined(search) && search) {\n\t\t\twhere.or = [{\n\t\t\t\tUSER_NAME: ['like', search]\n\t\t\t},\n\t\t\t{\n\t\t\t\tUSER_MOBILE: ['like', search]\n\t\t\t},\n\t\t\t{\n\t\t\t\tUSER_MEMO: ['like', search]\n\t\t\t},\n\t\t\t];\n\n\t\t} else if (sortType && util.isDefined(sortVal)) {\n\t\t\t// 搜索菜单\n\t\t\tswitch (sortType) {\n\t\t\t\tcase 'status':\n\t\t\t\t\twhere.and.USER_STATUS = Number(sortVal);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'sort':\n\t\t\t\t\t// 排序\n\t\t\t\t\tif (sortVal == 'newdesc') { //最新\n\t\t\t\t\t\torderBy = {\n\t\t\t\t\t\t\t'USER_ADD_TIME': 'desc'\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tif (sortVal == 'newasc') {\n\t\t\t\t\t\torderBy = {\n\t\t\t\t\t\t\t'USER_ADD_TIME': 'asc'\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tlet result = await UserModel.getList(where, fields, orderBy, page, size, true, oldTotal, false);\n\n\n\t\t// 为导出增加一个参数condition\n\t\tresult.condition = encodeURIComponent(JSON.stringify(where));\n\n\t\treturn result;\n\t}\n\n\tasync statusUser(id, status, reason) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\t}\n\n\t/**删除用户 */\n\tasync delUser(id) {\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\n\t}\n\n\t// #####################导出用户数据\n\n\t/**获取用户数据 */\n\tasync getUserDataURL() {\n\t\treturn await exportUtil.getExportDataURL(EXPORT_USER_DATA_KEY);\n\t}\n\n\t/**删除用户数据 */\n\tasync deleteUserDataExcel() {\n\t\treturn await exportUtil.deleteDataExcel(EXPORT_USER_DATA_KEY);\n\t}\n\n\t/**导出用户数据 */\n\tasync exportUserDataExcel(condition, fields) {\n\n\t\tthis.AppError('该功能暂不开放，如有需要请加作者微信：cclinux0730');\n\n\t}\n\n}\n\nmodule.exports = AdminUserService;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/admin/base_project_admin_service.js",
    "content": "/**\n * Notes: 后台管理模块 基类\n * Date: 2021-03-15 07:48:00 \n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n */\n\nconst BaseAdminService = require('../../../../framework/platform/service/base_admin_service.js');\n;\nconst util = require('../../../../framework/utils/util.js');\nconst cloudBase = require('../../../../framework/cloud/cloud_base.js');\n\nclass BaseProjectAdminService extends BaseAdminService {\n\n\tgetProjectId() {\n\t\treturn util.getProjectId();\n\t}\n\n\tasync genDetailQr(type, id) {\n\t\tlet cloud = cloudBase.getCloud();\n\n\t\tlet page = `projects/${this.getProjectId()}/pages/${type}/detail/${type}_detail`;\n\t\tconsole.log('page=', page);\n\t\tlet result = await cloud.openapi.wxacode.getUnlimited({\n\t\t\tscene: id,\n\t\t\twidth: 280,\n\t\t\tcheck_path: false,\n\t\t\t//env_version: 'trial', //release,trial,develop\n\t\t\tpage\n\t\t});\n\n\t\tlet cloudPath = `${this.getProjectId()}/${type}/${id}/qr.png`;\n\t\tconsole.log('cloudPath=', cloudPath);\n\t\tlet upload = await cloud.uploadFile({\n\t\t\tcloudPath,\n\t\t\tfileContent: result.buffer,\n\t\t});\n\n\t\tif (!upload || !upload.fileID) return;\n\n\t\treturn upload.fileID;\n\t}\n}\n\nmodule.exports = BaseProjectAdminService;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/album_service.js",
    "content": "/**\n * Notes: 相册模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-06-07 07:48:00 \n */\n\nconst BaseProjectService = require('./base_project_service.js');\nconst util = require('../../../framework/utils/util.js');\nconst AlbumModel = require('../model/album_model.js');\n\nclass AlbumService extends BaseProjectService {\n\n\t/** 浏览资讯信息 */\n\tasync viewAlbum(id) {\n\n\t\tlet fields = '*';\n\n\t\tlet where = {\n\t\t\t_id: id,\n\t\t\tALBUM_STATUS: AlbumModel.STATUS.COMM\n\t\t}\n\t\tlet album = await AlbumModel.getOne(where, fields);\n\t\tif (!album) return null; \n\n\t\tAlbumModel.inc(id, 'ALBUM_VIEW_CNT', 1);\n\n\t\treturn album;\n\t}\n\n\n\t/** 取得分页列表 */\n\tasync getAlbumList({\n\t\tsearch, // 搜索条件\n\t\tsortType, // 搜索菜单\n\t\tsortVal, // 搜索菜单\n\t\torderBy, // 排序 \n\t\tpage,\n\t\tsize,\n\t\tisTotal = true,\n\t\toldTotal\n\t}) {\n\n\t\torderBy = orderBy || {\n\t\t\t'ALBUM_ORDER': 'asc',\n\t\t\t'ALBUM_ADD_TIME': 'desc'\n\t\t};\n\t\tlet fields = 'ALBUM_OBJ,ALBUM_VIEW_CNT,ALBUM_TITLE,ALBUM_CATE_ID,ALBUM_ADD_TIME,ALBUM_ORDER,ALBUM_STATUS,ALBUM_CATE_NAME';\n\n\t\tlet where = {};\n\t\twhere.and = {\n\t\t\t_pid: this.getProjectId() //复杂的查询在此处标注PID\n\t\t};\n\n\t\twhere.and.ALBUM_STATUS = AlbumModel.STATUS.COMM; // 状态  \n\n\n\t\tif (util.isDefined(search) && search) {\n\t\t\twhere.or = [\n\t\t\t\t{ ALBUM_TITLE: ['like', search] },\n\t\t\t];\n\t\t} else if (sortType && util.isDefined(sortVal)) {\n\t\t\t// 搜索菜单\n\t\t\tswitch (sortType) {\n\t\t\t\tcase 'cateId': {\n\t\t\t\t\tif (sortVal) where.and.ALBUM_CATE_ID = String(sortVal);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'sort': {\n\t\t\t\t\torderBy = this.fmtOrderBySort(sortVal, 'ALBUM_ADD_TIME');\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn await AlbumModel.getList(where, fields, orderBy, page, size, isTotal, oldTotal);\n\t}\n\n\n}\n\nmodule.exports = AlbumService;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/base_project_service.js",
    "content": "/**\n * Notes: 业务基类 \n * Date: 2021-03-15 04:00:00 \n */\n\nconst dbUtil = require('../../../framework/database/db_util.js');\nconst util = require('../../../framework/utils/util.js');\nconst AdminModel = require('../../../framework/platform/model/admin_model.js');\nconst NewsModel = require('../model/news_model.js');\nconst MeetModel = require('../model/meet_model.js');\nconst AlbumModel = require('../model/album_model.js');\nconst ProductModel = require('../model/product_model.js');\nconst BaseService = require('../../../framework/platform/service/base_service.js');\n\nclass BaseProjectService extends BaseService {\n\tgetProjectId() {\n\t\treturn util.getProjectId();\n\t}\n\n\tasync initSetup() {\n\n\t\tlet F = (c) => 'bx_' + c;\n\t\tconst INSTALL_CL = 'setup_trip1';\n\t\tconst COLLECTIONS = ['setup', 'admin', 'day', 'join', 'log', 'meet', 'news', 'product', 'album', 'fav', 'user'];\n\t\tconst CONST_PIC = '/images/cover.gif';\n\n\t\tconst NEWS_CATE = '1=本景区动态,2=美食,3=特产';\n\t\tconst MEET_TYPE = '1=景点预约,2=停车预约';\n\t\tconst ALBUM_CATE = '1=线路,2=吃喝,3=住宿,4=购物,5=其他';\n\t\tconst PRODUCT_CATE = '1=仙山贡水,2=伍家台,3=狮子关,4=其他景点';\n\n\n\t\tif (await dbUtil.isExistCollection(F(INSTALL_CL))) {\n\t\t\treturn;\n\t\t}\n\n\t\tconsole.log('### initSetup...');\n\n\t\tlet arr = COLLECTIONS;\n\t\tfor (let k = 0; k < arr.length; k++) {\n\t\t\tif (!await dbUtil.isExistCollection(F(arr[k]))) {\n\t\t\t\tawait dbUtil.createCollection(F(arr[k]));\n\t\t\t}\n\t\t}\n\n\t\tif (await dbUtil.isExistCollection(F('admin'))) {\n\t\t\tlet adminCnt = await AdminModel.count({});\n\t\t\tif (adminCnt == 0) {\n\t\t\t\tlet data = {};\n\t\t\t\tdata.ADMIN_NAME = 'admin';\n\t\t\t\tdata.ADMIN_PASSWORD = 'e10adc3949ba59abbe56e057f20f883e';\n\t\t\t\tdata.ADMIN_DESC = '超管';\n\t\t\t\tdata.ADMIN_TYPE = 1;\n\t\t\t\tawait AdminModel.insert(data);\n\t\t\t}\n\t\t}\n\n\n\t\tif (await dbUtil.isExistCollection(F('news'))) {\n\t\t\tlet newsCnt = await NewsModel.count({});\n\t\t\tif (newsCnt == 0) {\n\t\t\t\tlet newsArr = NEWS_CATE.split(',');\n\t\t\t\tfor (let j in newsArr) {\n\t\t\t\t\tlet title = newsArr[j].split('=')[1];\n\t\t\t\t\tlet cateId = newsArr[j].split('=')[0];\n\n\t\t\t\t\tlet data = {};\n\t\t\t\t\tdata.NEWS_TITLE = title + '标题1';\n\t\t\t\t\tdata.NEWS_DESC = title + '简介1';\n\t\t\t\t\tdata.NEWS_CATE_ID = cateId;\n\t\t\t\t\tdata.NEWS_CATE_NAME = title;\n\t\t\t\t\tdata.NEWS_CONTENT = [{ type: 'text', val: title + '内容1' }];\n\t\t\t\t\tdata.NEWS_PIC = [CONST_PIC];\n\n\t\t\t\t\tawait NewsModel.insert(data);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (await dbUtil.isExistCollection(F('meet'))) {\n\t\t\tlet meetCnt = await MeetModel.count({});\n\t\t\tif (meetCnt == 0) {\n\t\t\t\tlet meetArr = MEET_TYPE.split(',');\n\t\t\t\tfor (let j in meetArr) {\n\t\t\t\t\tlet title = meetArr[j].split('=')[1];\n\t\t\t\t\tlet typeId = meetArr[j].split('=')[0];\n\n\t\t\t\t\tlet data = {};\n\t\t\t\t\tdata.MEET_TITLE = title + '标题1';\n\t\t\t\t\tdata.MEET_STYLE_SET = {\n\t\t\t\t\t\tdesc: title + '简介1',\n\t\t\t\t\t\tpic: CONST_PIC\n\t\t\t\t\t};\n\t\t\t\t\tdata.MEET_ADMIN_ID = '1';\n\t\t\t\t\tdata.MEET_TYPE_ID = typeId;\n\t\t\t\t\tdata.MEET_TYPE_NAME = title;\n\t\t\t\t\tdata.MEET_CONTENT = [{ type: 'text', val: title + '内容1' }];\n\t\t\t\t\tdata.MEET_DAYS = [];\n\t\t\t\t\tdata.MEET_FORM_SET = [\n\t\t\t\t\t\t{ type: 'text', title: '姓名', must: true },\n\t\t\t\t\t\t{ type: 'mobile', title: '手机', must: true }\n\t\t\t\t\t];\n\n\t\t\t\t\tawait MeetModel.insert(data);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (await dbUtil.isExistCollection(F('album'))) {\n\t\t\tlet albumCnt = await AlbumModel.count({});\n\t\t\tif (albumCnt == 0) {\n\t\t\t\tlet albumArr = ALBUM_CATE.split(',');\n\t\t\t\tfor (let j in albumArr) {\n\t\t\t\t\tlet title = albumArr[j].split('=')[1];\n\t\t\t\t\tlet cateId = albumArr[j].split('=')[0];\n\n\t\t\t\t\tlet data = {};\n\t\t\t\t\tdata.ALBUM_TITLE = title + '标题1';\n\t\t\t\t\tdata.ALBUM_CATE_ID = cateId;\n\t\t\t\t\tdata.ALBUM_CATE_NAME = title;\n\t\t\t\t\tdata.ALBUM_OBJ = { cover: [CONST_PIC], detail: [{ type: 'text', val: title + '内容1' }] };\n\t\t\t\t\tawait AlbumModel.insert(data);\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\tif (await dbUtil.isExistCollection(F('product'))) {\n\t\t\tlet productCnt = await ProductModel.count({});\n\t\t\tif (productCnt == 0) {\n\t\t\t\tlet productArr = PRODUCT_CATE.split(',');\n\t\t\t\tfor (let j in productArr) {\n\t\t\t\t\tlet title = productArr[j].split('=')[1];\n\t\t\t\t\tlet cateId = productArr[j].split('=')[0];\n\n\t\t\t\t\tlet data = {};\n\t\t\t\t\tdata.PRODUCT_TITLE = title + '标题1';\n\t\t\t\t\tdata.PRODUCT_CATE_ID = cateId;\n\t\t\t\t\tdata.PRODUCT_CATE_NAME = title;\n\t\t\t\t\tdata.PRODUCT_OBJ = { cover: [CONST_PIC], price: 1999, origPrice: 999, adv: '产品亮点', album: [CONST_PIC] };\n\t\t\t\t\tawait ProductModel.insert(data);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!await dbUtil.isExistCollection(F(INSTALL_CL))) {\n\t\t\tawait dbUtil.createCollection(F(INSTALL_CL));\n\t\t}\n\t}\n\n}\n\nmodule.exports = BaseProjectService;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/fav_service.js",
    "content": "/**\n * Notes: 收藏模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-05-24 07:48:00 \n */\n\nconst BaseProjectService = require('./base_project_service.js');\nconst util = require('../../../framework/utils/util.js');\nconst FavModel = require('../model/fav_model.js'); \n\nclass FavService extends BaseProjectService {\n\n\t/** 是否收藏 */\n\tasync isFav(userId, oid) {\n\t\tlet where = {\n\t\t\tFAV_OID: oid,\n\t\t\tFAV_USER_ID: userId\n\t\t}\n\t\tlet isFav = await FavModel.count(where);\n\t\treturn {\n\t\t\tisFav\n\t\t};\n\t}\n\n\t/**\n\t * 更新某人收藏\n\t * @param {*} userId \n\t * @param {*} oid \n\t * @param {*} cancelIfExist  已收藏的情况下是否取消\n\t */\n\tasync updateFav(userId, oid, title, type, path, cancelIfExist = true) {\n\n\t\tlet {\n\t\t\tisFav\n\t\t} = await this.isFav(userId, oid);\n\t\tif (isFav > 0) {\n\t\t\tif (cancelIfExist) {\n\t\t\t\t// 取消\n\t\t\t\tawait this.delFav(userId, oid);\n\t\t\t\treturn {\n\t\t\t\t\tisFav: 0\n\t\t\t\t};\n\t\t\t} else\n\t\t\t\treturn {\n\t\t\t\t\tisFav: 1\n\t\t\t\t};\n\t\t}\n\n\n\t\t// 保存 \n\t\tlet data = {};\n\t\tdata.FAV_TITLE = title;\n\t\tdata.FAV_OID = oid;\n\t\tdata.FAV_TYPE = type;\n\t\tdata.FAV_PATH = path;\n\t\tdata.FAV_USER_ID = userId; \n\n\t\tawait FavModel.insert(data);\n \n\t\treturn {\n\t\t\tisFav: 1\n\t\t};\n\t}\n\n\t/** 删除收藏 */\n\tasync delFav(userId, oid) {\n\t\tlet where = {\n\t\t\tFAV_OID: oid,\n\t\t\tFAV_USER_ID: userId\n\t\t}\n\t\tlet effect = await FavModel.del(where);\n\n\t\treturn {\n\t\t\teffect\n\t\t};\n\t}\n\n\t/** 我的收藏列表 */\n\tasync getMyFavList(userId, {\n\t\tsearch, // 搜索条件 \n\t\tsortType, // 搜索菜单\n\t\tsortVal, // 搜索菜单\n\t\torderBy, // 排序  \n\t\tpage,\n\t\tsize,\n\t\tisTotal = true,\n\t\toldTotal = 0\n\t}) {\n\t\torderBy = orderBy || {\n\t\t\t'FAV_ADD_TIME': 'desc'\n\t\t};\n\t\tlet fields = 'FAV_TITLE,FAV_ADD_TIME,FAV_OID,FAV_TYPE,FAV_PATH';\n\n\t\tlet where = {};\n\t\tif (util.isDefined(search) && search) {\n\t\t\twhere.FAV_TITLE = {\n\t\t\t\t$regex: '.*' + search,\n\t\t\t\t$options: 'i'\n\t\t\t};\n\t\t}\n\t\twhere.FAV_USER_ID = userId;\n\n\t\treturn await FavModel.getList(where, fields, orderBy, page, size, isTotal, oldTotal);\n\n\t}\n\n}\n\nmodule.exports = FavService;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/home_service.js",
    "content": "/**\n * Notes: 全局/首页模块业务逻辑\n * Date: 2021-03-15 04:00:00 \n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n */\n\nconst BaseProjectService = require('./base_project_service.js');\nconst setupUtil = require('../../../framework/utils/setup/setup_util.js');\nconst constants = require('../public/constants.js');\nconst NewsModel = require('../model/news_model.js');\n\nclass HomeService extends BaseProjectService {\n\n\tasync getSetup(key) {\n\t\treturn await setupUtil.get(key);\n\t}\n\n\t/**首页列表 */\n\tasync getHomeList() {\n\t\tlet list = await setupUtil.get(constants.SETUP_HOME_VOUCH_KEY);\n\t\tif (!list || !Array.isArray(list)) list = [];\n\n\n\t\tif (list.length == 0) {\n\t\t\tlet orderBy = {\n\t\t\t\t'NEWS_ORDER': 'asc',\n\t\t\t\t'NEWS_ADD_TIME': 'desc'\n\t\t\t};\n\t\t\tlet fields = 'NEWS_PIC,NEWS_CATE_NAME,NEWS_TITLE,NEWS_DESC,NEWS_ADD_TIME';\n\n\t\t\tlet where = {};\n\t\t\twhere.NEWS_STATUS = 1; // 状态    \n\n\t\t\tlet retList = await NewsModel.getAll(where, fields, orderBy, 10);\n\t\t\tfor (let k = 0; k < retList.length; k++) {\n\t\t\t\tlist.push({\n\t\t\t\t\ttype: 'news',\n\t\t\t\t\text: retList[k].NEWS_CATE_NAME,\n\t\t\t\t\ttitle: retList[k].NEWS_TITLE,\n\t\t\t\t\tid: retList[k]._id,\n\t\t\t\t\tdesc: retList[k].NEWS_DESC,\n\t\t\t\t\tpic: retList[k].NEWS_PIC\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\treturn list;\n\t}\n}\n\nmodule.exports = HomeService;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/meet_service.js",
    "content": "/**\n * Notes: 预约模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-12-10 07:48:00 \n */\n\nconst BaseProjectService = require('./base_project_service.js');\nconst util = require('../../../framework/utils/util.js');\nconst MeetModel = require('../model/meet_model.js');\nconst JoinModel = require('../model/join_model.js');\nconst DayModel = require('../model/day_model.js');\nconst LogUtil = require('../../../framework/utils/log_util.js');\nconst timeUtil = require('../../../framework/utils/time_util.js');\nconst dataUtil = require('../../../framework/utils/data_util.js');\nconst projectConfig = require('../public/project_config.js');\nconst MEET_LOG_LEVEL = 'debug';\n\nclass MeetService extends BaseProjectService {\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis._log = new LogUtil(projectConfig.MEET_LOG_LEVEL);\n\t}\n\n\t/**\n\t * 抛出异常\n\t * @param {*} msg \n\t * @param {*} code \n\t */\n\tAppError(msg) {\n\t\tthis._log.error(msg);\n\t\tsuper.AppError(msg);\n\t}\n\n\t_meetLog(meet, func = '', msg = '') {\n\t\tlet str = '';\n\t\tstr = `[MEET=${meet.MEET_TITLE}][${func}] ${msg}`;\n\t\tthis._log.debug(str);\n\t}\n\n\t/** 统一获取Meet（某天) */\n\tasync getMeetOneDay(meetId, day, where, fields = '*') {\n\n\t\tlet meet = await MeetModel.getOne(where, fields);\n\t\tif (!meet) return meet;\n\n\t\tmeet.MEET_DAYS_SET = await this.getDaysSet(meetId, day, day);\n\t\treturn meet;\n\t}\n\n\t/** 获取日期设置 */\n\tasync getDaysSet(meetId, startDay, endDay = null) {\n\t\tlet where = {\n\t\t\tDAY_MEET_ID: meetId\n\t\t}\n\t\tif (startDay && endDay && endDay == startDay)\n\t\t\twhere.day = startDay;\n\t\telse if (startDay && endDay)\n\t\t\twhere.day = ['between', startDay, endDay];\n\t\telse if (!startDay && endDay)\n\t\t\twhere.day = ['<=', endDay];\n\t\telse if (startDay && !endDay)\n\t\t\twhere.day = ['>=', startDay];\n\n\t\tlet orderBy = {\n\t\t\t'day': 'asc'\n\t\t}\n\t\tlet list = await DayModel.getAllBig(where, 'day,dayDesc,times', orderBy, 1000);\n\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tdelete list[k]._id;\n\t\t}\n\n\t\treturn list;\n\t}\n\n\t// 按时段统计某时段报名情况\n\tasync statJoinCnt(meetId, timeMark) {\n\t\tlet whereJoin = {\n\t\t\tJOIN_MEET_TIME_MARK: timeMark,\n\t\t\tJOIN_MEET_ID: meetId\n\t\t};\n\t\tlet ret = await JoinModel.groupCount(whereJoin, 'JOIN_STATUS');\n\n\t\tlet stat = { //统计数据\n\t\t\tsuccCnt: ret['JOIN_STATUS_1'] || 0, //1=预约成功,\n\t\t\tcancelCnt: ret['JOIN_STATUS_10'] || 0, //10=已取消, \n\t\t\tadminCancelCnt: ret['JOIN_STATUS_99'] || 0, //99=后台取消\n\t\t};\n\n\t\tlet whereDay = {\n\t\t\tDAY_MEET_ID: meetId,\n\t\t\tday: this.getDayByTimeMark(timeMark)\n\t\t};\n\t\tlet day = await DayModel.getOne(whereDay, 'times');\n\t\tif (!day) return;\n\n\t\tlet times = day.times;\n\t\tfor (let j in times) {\n\t\t\tif (times[j].mark === timeMark) {\n\t\t\t\tlet data = {\n\t\t\t\t\t['times.' + j + '.stat']: stat\n\t\t\t\t}\n\t\t\t\tawait DayModel.edit(whereDay, data);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t}\n\n\n\t// 预约前检测\n\tasync beforeJoin(userId, meetId, timeMark) {\n\t\tawait this.checkMeetRules(userId, meetId, timeMark);\n\t}\n\n\t// 预约逻辑\n\tasync join(userId, meetId, timeMark, forms) {\n\t\t// 预约时段是否存在\n\t\tlet meetWhere = {\n\t\t\t_id: meetId\n\t\t};\n\t\tlet day = this.getDayByTimeMark(timeMark);\n\t\tlet meet = await this.getMeetOneDay(meetId, day, meetWhere);\n\n\t\tif (!meet) {\n\t\t\tthis.AppError('预约时段选择错误1，请重新选择');\n\t\t}\n\n\t\tlet daySet = this.getDaySetByTimeMark(meet, timeMark);\n\t\tif (!daySet)\n\t\t\tthis.AppError('预约时段选择错误2，请重新选择');\n\n\t\tlet timeSet = this.getTimeSetByTimeMark(meet, timeMark);\n\t\tif (!timeSet)\n\t\t\tthis.AppError('预约时段选择错误3，请重新选择');\n\n\t\t// 规则校验\n\t\tawait this.checkMeetRules(userId, meetId, timeMark);\n\n\n\t\tlet data = {};\n\n\t\tdata.JOIN_USER_ID = userId;\n\n\t\tdata.JOIN_MEET_ID = meetId;\n\t\tdata.JOIN_MEET_TITLE = meet.MEET_TITLE;\n\t\tdata.JOIN_MEET_DAY = daySet.day;\n\t\tdata.JOIN_MEET_TIME_START = timeSet.start;\n\t\tdata.JOIN_MEET_TIME_END = timeSet.end;\n\t\tdata.JOIN_MEET_TIME_MARK = timeMark;\n\n\t\tdata.JOIN_START_TIME = timeUtil.time2Timestamp(daySet.day + ' ' + timeSet.start + ':00');\n\n\t\tdata.JOIN_FORMS = forms;\n\n\t\tdata.JOIN_STATUS = JoinModel.STATUS.SUCC;\n\t\tdata.JOIN_CODE = dataUtil.genRandomIntString(15);\n\n\t\t// 入库\n\t\tlet joinId = await JoinModel.insert(data);\n\n\t\t// 若有手机号码 用户入库\n\t\tlet mobile = '';\n\t\tlet userName = '';\n\t\tfor (let k = 0; k < forms.length; k++) {\n\t\t\tif (!mobile && forms[k].type == 'mobile') {\n\t\t\t\tmobile = forms[k].val;\n\t\t\t\tcontinue;\n\t\t\t} else if (!userName && forms[k].title == '姓名') {\n\t\t\t\tuserName = forms[k].val;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t// 统计\n\t\tthis.statJoinCnt(meetId, timeMark);\n\n\t\treturn {\n\t\t\tresult: 'ok',\n\t\t\tjoinId\n\t\t}\n\t}\n\n\t// 根据日期获取其所在天设置\n\tgetDaySetByDay(meet, day) {\n\t\tfor (let k = 0; k < meet.MEET_DAYS_SET.length; k++) {\n\t\t\tif (meet.MEET_DAYS_SET[k].day == day)\n\t\t\t\treturn dataUtil.deepClone(meet.MEET_DAYS_SET[k]);\n\t\t}\n\t\treturn null;\n\t}\n\n\t// 根据时段标识获取其所在天 \n\tgetDayByTimeMark(timeMark) {\n\t\treturn timeMark.substr(1, 4) + '-' + timeMark.substr(5, 2) + '-' + timeMark.substr(7, 2);\n\t}\n\n\t// 根据时段标识获取其所在天设置\n\tgetDaySetByTimeMark(meet, timeMark) {\n\t\tlet day = this.getDayByTimeMark(timeMark);\n\n\t\tfor (let k = 0; k < meet.MEET_DAYS_SET.length; k++) {\n\t\t\tif (meet.MEET_DAYS_SET[k].day == day)\n\t\t\t\treturn dataUtil.deepClone(meet.MEET_DAYS_SET[k]);\n\t\t}\n\t\treturn null;\n\t}\n\n\t// 根据时段标识获取其所在时段设置\n\tgetTimeSetByTimeMark(meet, timeMark) {\n\t\tlet day = this.getDayByTimeMark(timeMark);\n\n\t\tfor (let k = 0; k < meet.MEET_DAYS_SET.length; k++) {\n\t\t\tif (meet.MEET_DAYS_SET[k].day != day) continue;\n\n\t\t\tfor (let j in meet.MEET_DAYS_SET[k].times) {\n\t\t\t\tif (meet.MEET_DAYS_SET[k].times[j].mark == timeMark)\n\t\t\t\t\treturn dataUtil.deepClone(meet.MEET_DAYS_SET[k].times[j]);\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\t// 预约时段人数和状态控制校验\n\tasync checkMeetTimeControll(meet, timeMark) {\n\t\tif (!meet) this.AppError('预约时段设置错误, 预约项目不存在');\n\n\t\tlet daySet = this.getDaySetByTimeMark(meet, timeMark); // 当天设置\n\t\tlet timeSet = this.getTimeSetByTimeMark(meet, timeMark); // 预约时段设置\n\n\t\tif (!daySet || !timeSet) this.AppError('预约时段设置错误day&time');\n\n\t\tlet statusDesc = timeSet.status == 1 ? '开启' : '关闭';\n\t\tlet limitDesc = '';\n\t\tif (timeSet.isLimit) {\n\t\t\tlimitDesc = '人数上限MAX=' + timeSet.limit;\n\t\t} else\n\t\t\tlimitDesc = '人数不限制NO';\n\n\t\tthis._meetLog(meet, `------------------------------`);\n\t\tthis._meetLog(meet, `#预约时段控制,预约日期=<${daySet.day}>`, `预约时段=[${timeSet.start}-${timeSet.end}],状态=${statusDesc}, ${limitDesc} 当前预约成功人数=${timeSet.stat.succCnt}`);\n\n\t\tif (timeSet.status == 0) this.AppError('该时段预约已经关闭，请选择其他');\n\n\t\t// 时段总人数限制\n\t\tif (timeSet.isLimit) {\n\t\t\tif (timeSet.stat.succCnt >= timeSet.limit) {\n\t\t\t\tthis.AppError('该时段预约人员已满，请选择其他');\n\t\t\t}\n\t\t}\n\t}\n\n\n\t/** 报名规则校验 */\n\tasync checkMeetRules(userId, meetId, timeMark) {\n\t\t// 预约时段是否存在\n\t\tlet meetWhere = {\n\t\t\t_id: meetId\n\t\t};\n\t\tlet day = this.getDayByTimeMark(timeMark);\n\t\tlet meet = await this.getMeetOneDay(meetId, day, meetWhere);\n\t\tif (!meet) {\n\t\t\tthis.AppError('预约时段选择错误，请重新选择');\n\t\t}\n\n\t\t// 预约时段人数和状态控制校验\n\t\tawait this.checkMeetTimeControll(meet, timeMark);\n\n\t\t// 截止规则\n\t\tawait this.checkMeetEndSet(meet, timeMark);\n\n\t\t// 针对用户的次数限制\n\t\tawait this.checkMeetLimitSet(userId, meet, timeMark);\n\n\t}\n\n\n\t// 预约次数限制校验\n\tasync checkMeetLimitSet(userId, meet, timeMark) {\n\t\tif (!meet) this.AppError('预约次数规则错误, 预约项目不存在');\n\t\tlet meetId = meet._id;\n\n\t\tlet daySet = this.getDaySetByTimeMark(meet, timeMark); // 当天设置\n\t\tlet timeSet = this.getTimeSetByTimeMark(meet, timeMark); // 预约时段设置\n\n\t\tthis._meetLog(meet, `------------------------------`);\n\t\tthis._meetLog(meet, `#预约次数规则,预约日期=<${daySet.day}>`, `预约时段=[${timeSet.start}～${timeSet.end}]`);\n\n\t\tlet where = {\n\t\t\tJOIN_MEET_ID: meetId,\n\t\t\tJOIN_MEET_TIME_MARK: timeMark,\n\t\t\tJOIN_USER_ID: userId,\n\t\t\tJOIN_STATUS: JoinModel.STATUS.SUCC\n\t\t}\n\t\tlet cnt = await JoinModel.count(where);\n\t\tthis._meetLog(meet, `预约次数规则,mode=本时段可预约1次`, `当前已预约=${cnt}次`);\n\t\tif (cnt >= 1) {\n\t\t\tthis.AppError(`您本时段已经预约，无须重复预约`);\n\t\t}\n\t}\n\n\n\n\t// 预约截止设置校验\n\tasync checkMeetEndSet(meet, timeMark) {\n\t\tif (!meet) this.AppError('预约截止规则错误, 预约项目不存在');\n\n\n\t\tthis._meetLog(meet, `------------------------------`);\n\t\tlet daySet = this.getDaySetByTimeMark(meet, timeMark); // 当天设置\n\t\tlet timeSet = this.getTimeSetByTimeMark(meet, timeMark); // 预约时段设置\n\n\t\tthis._meetLog(meet, `#预约截止规则,预约日期=<${daySet.day}>`, `预约时段=[${timeSet.start}-${timeSet.end}]`);\n\n\t\tlet nowTime = timeUtil.time('Y-M-D h:m:s');\n\n\t\tlet startTime = daySet.day + ' ' + timeSet.start + ':00';\n\t\tthis._meetLog(meet, `预约开始规则,mode=<时段过期判定>`, `预约开始时段=${startTime},当前时段=${nowTime}`);\n\t\tif (nowTime > startTime) {\n\t\t\tthis.AppError('该时段已开始，无法预约，请选择其他');\n\t\t}\n\n\t}\n\n\n\t/**  预约详情 */\n\tasync viewMeet(meetId) {\n\n\t\tlet fields = '*';\n\n\t\tlet where = {\n\t\t\t_id: meetId,\n\t\t\tMEET_STATUS: ['in', [MeetModel.STATUS.COMM, MeetModel.STATUS.OVER]]\n\t\t}\n\t\tlet meet = await MeetModel.getOne(where, fields);\n\t\tif (!meet) return null;\n\n\n\t\tlet getDaysSet = [];\n\t\tmeet.MEET_DAYS_SET = await this.getDaysSet(meetId, timeUtil.time('Y-M-D')); //今天及以后\n\t\tlet daysSet = meet.MEET_DAYS_SET;\n\n\t\tlet now = timeUtil.time('Y-M-D');\n\t\tfor (let k = 0; k < daysSet.length; k++) {\n\t\t\tlet dayNode = daysSet[k];\n\n\t\t\tif (dayNode.day < now) continue; // 排除过期\n\n\t\t\tlet getTimes = [];\n\n\t\t\tfor (let j in dayNode.times) {\n\t\t\t\tlet timeNode = dayNode.times[j];\n\n\t\t\t\t// 排除状态关闭的时段\n\t\t\t\tif (timeNode.status != 1) continue;\n\n\t\t\t\t// 判断数量是否已满\n\t\t\t\tif (timeNode.isLimit && timeNode.stat.succCnt >= timeNode.limit)\n\t\t\t\t\ttimeNode.error = '预约已满';\n\n\t\t\t\t// 截止规则\n\t\t\t\tif (!timeNode.error) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait this.checkMeetEndSet(meet, timeNode.mark);\n\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\tif (ex.name == 'AppError')\n\t\t\t\t\t\t\ttimeNode.error = '预约结束';\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tthrow ex;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tgetTimes.push(timeNode);\n\t\t\t}\n\t\t\tdayNode.times = getTimes;\n\n\t\t\tgetDaysSet.push(dayNode);\n\t\t}\n\n\t\t// 只返回需要的字段\n\t\tlet ret = {};\n\t\tret.MEET_DAYS_SET = getDaysSet;\n\n\t\tret.MEET_IS_SHOW_LIMIT = meet.MEET_IS_SHOW_LIMIT;\n\t\tret.MEET_TITLE = meet.MEET_TITLE;\n\t\tret.MEET_TYPE_NAME = meet.MEET_TYPE_NAME;\n\t\tret.MEET_CONTENT = meet.MEET_CONTENT;\n\n\n\t\treturn ret;\n\t}\n\n\t/** 用户自助签到 */\n\tasync userSelfCheckin(userId, timeMark) {\n\t\tlet day = this.getDayByTimeMark(timeMark);\n\n\t\tlet today = timeUtil.time('Y-M-D');\n\t\tif (day != today)\n\t\t\tthis.AppError('仅在预约当天可以签到，当前签到码的日期是' + day);\n\n\t\tlet whereSucc = {\n\t\t\tJOIN_MEET_DAY: day,\n\t\t\tJOIN_MEET_TIME_MARK: timeMark,\n\t\t\tJOIN_USER_ID: userId,\n\t\t\tJOIN_STATUS: JoinModel.STATUS.SUCC\n\t\t}\n\t\tlet cntSucc = await JoinModel.count(whereSucc);\n\n\t\tlet whereCheckin = {\n\t\t\tJOIN_MEET_DAY: day,\n\t\t\tJOIN_MEET_TIME_MARK: timeMark,\n\t\t\tJOIN_USER_ID: userId,\n\t\t\tJOIN_IS_CHECKIN: 1,\n\t\t\tJOIN_STATUS: JoinModel.STATUS.SUCC\n\t\t}\n\t\tlet cntCheckin = await JoinModel.count(whereCheckin);\n\n\t\tlet ret = '';\n\t\tif (cntSucc == 0) {\n\t\t\tret = '您没有本次报名的记录，请在「个人中心」查看详情~';\n\t\t} else if (cntSucc == cntCheckin) {\n\t\t\tret = '您已签到，无须重复签到，请在「个人中心」查看详情~';\n\t\t} else {\n\t\t\tlet where = {\n\t\t\t\tJOIN_MEET_DAY: day,\n\t\t\t\tJOIN_MEET_TIME_MARK: timeMark,\n\t\t\t\tJOIN_USER_ID: userId,\n\t\t\t\tJOIN_IS_CHECKIN: 0,\n\t\t\t\tJOIN_STATUS: JoinModel.STATUS.SUCC\n\t\t\t}\n\t\t\tlet data = {\n\t\t\t\tJOIN_IS_CHECKIN: 1\n\t\t\t}\n\t\t\tawait JoinModel.edit(where, data);\n\t\t\tret = '签到成功，请在「个人中心」查看详情~'\n\t\t}\n\t\treturn {\n\t\t\tret\n\t\t};\n\n\t}\n\n\n\t/**  预约前获取关键信息 */\n\tasync detailForJoin(userId, meetId, timeMark) {\n\n\t\tlet fields = 'MEET_DAYS_SET,MEET_FORM_SET, MEET_TITLE';\n\n\t\tlet where = {\n\t\t\t_id: meetId,\n\t\t\tMEET_STATUS: ['in', [MeetModel.STATUS.COMM, MeetModel.STATUS.OVER]]\n\t\t}\n\t\tlet day = this.getDayByTimeMark(timeMark);\n\t\tlet meet = await this.getMeetOneDay(meetId, day, where, fields);\n\t\tif (!meet) return null;\n\n\t\tlet dayDesc = timeUtil.fmtDateCHN(this.getDaySetByTimeMark(meet, timeMark).day);\n\n\t\tlet timeSet = this.getTimeSetByTimeMark(meet, timeMark);\n\t\tlet timeDesc = timeSet.start + '～' + timeSet.end;\n\t\tmeet.dayDesc = dayDesc + ' ' + timeDesc;\n\n\t\t// 取出本人最近一次本时段填写表单\n\t\tlet whereMy = {\n\t\t\tJOIN_USER_ID: userId,\n\t\t\tJOIN_MEET_ID: meetId,\n\t\t\tJOIN_MEET_TIME_MARK: timeMark\n\t\t}\n\t\tlet orderByMy = {\n\t\t\tJOIN_ADD_TIME: 'desc'\n\t\t}\n\t\tlet joinMy = await JoinModel.getOne(whereMy, 'JOIN_FORMS', orderByMy);\n\n\t\t// 取出本人最近一次本项目填写表单\n\t\tif (!joinMy) {\n\t\t\twhereMy = {\n\t\t\t\tJOIN_USER_ID: userId,\n\t\t\t\tJOIN_MEET_ID: meetId,\n\t\t\t}\n\t\t\tlet orderByMy = {\n\t\t\t\tJOIN_ADD_TIME: 'desc'\n\t\t\t}\n\t\t\tjoinMy = await JoinModel.getOne(whereMy, 'JOIN_FORMS', orderByMy);\n\t\t}\n\n\t\t// 取出本人最近一次的填写表单\n\t\tif (!joinMy) {\n\t\t\twhereMy = {\n\t\t\t\tJOIN_USER_ID: userId,\n\t\t\t}\n\t\t\tlet orderByMy = {\n\t\t\t\tJOIN_ADD_TIME: 'desc'\n\t\t\t}\n\t\t\tjoinMy = await JoinModel.getOne(whereMy, 'JOIN_FORMS', orderByMy);\n\t\t}\n\n\t\tlet myForms = joinMy ? joinMy.JOIN_FORMS : [];\n\t\tmeet.myForms = myForms;\n\n\t\treturn meet;\n\t}\n\n\t/** 获取某天可用时段 */\n\tasync getUsefulTimesByDaysSet(meetId, day) {\n\t\tlet where = {\n\t\t\tDAY_MEET_ID: meetId,\n\t\t\tday\n\t\t}\n\t\tlet daysSet = await DayModel.getAll(where, 'day,times');\n\t\tlet usefulTimes = [];\n\t\tfor (let k = 0; k < daysSet.length; k++) {\n\t\t\tif (daysSet[k].day != day)\n\t\t\t\tcontinue;\n\n\t\t\tlet times = daysSet[k].times;\n\t\t\tfor (let j in times) {\n\t\t\t\tif (times[j].status != 1) continue;\n\t\t\t\tusefulTimes.push(times[j]);\n\t\t\t}\n\t\t\tbreak;\n\n\t\t}\n\t\treturn usefulTimes;\n\t}\n\n\t/** 按天获取预约项目 */\n\tasync getMeetListByDay(day) {\n\t\tlet where = {\n\t\t\tMEET_STATUS: MeetModel.STATUS.COMM,\n\t\t};\n\n\t\tlet orderBy = {\n\t\t\t'MEET_ORDER': 'asc',\n\t\t\t'MEET_ADD_TIME': 'desc'\n\t\t};\n\n\t\tlet fields = 'MEET_TITLE,MEET_DAYS_SET,MEET_STYLE_SET';\n\n\t\tlet list = await MeetModel.getAll(where, fields, orderBy);\n\n\t\tlet retList = [];\n\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tlet usefulTimes = await this.getUsefulTimesByDaysSet(list[k]._id, day);\n\n\t\t\tif (usefulTimes.length == 0) continue;\n\n\t\t\tlet node = {};\n\t\t\tnode.timeDesc = usefulTimes.length > 1 ? usefulTimes.length + '个时段' : usefulTimes[0].start;\n\t\t\tnode.title = list[k].MEET_TITLE;\n\t\t\tnode.pic = list[k].MEET_STYLE_SET.pic;\n\t\t\tnode._id = list[k]._id;\n\t\t\tretList.push(node);\n\n\t\t}\n\t\treturn retList;\n\t}\n\n\t/** 获取从某天开始可预约的日期 */\n\tasync getHasDaysFromDay(day) {\n\t\tlet where = {\n\t\t\tday: ['>=', day],\n\t\t};\n\n\t\tlet fields = 'times,day';\n\t\tlet list = await DayModel.getAllBig(where, fields);\n\n\t\tlet retList = [];\n\t\tfor (let k = 0; k < list.length; k++) {\n\t\t\tfor (let n in list[k].times) {\n\t\t\t\tif (list[k].times[n].status == 1) {\n\t\t\t\t\tretList.push(list[k].day);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn retList;\n\t}\n\n\t/** 取得预约分页列表 */\n\tasync getMeetList({\n\t\tsearch, // 搜索条件\n\t\tsortType, // 搜索菜单\n\t\tsortVal, // 搜索菜单\n\t\torderBy, // 排序 \n\t\ttypeId, //附加查询条件\n\t\tpage,\n\t\tsize,\n\t\tisTotal = true,\n\t\toldTotal\n\t}) {\n\n\t\torderBy = orderBy || {\n\t\t\t'MEET_ORDER': 'asc',\n\t\t\t'MEET_ADD_TIME': 'desc'\n\t\t};\n\t\tlet fields = 'MEET_TITLE,MEET_STYLE_SET,MEET_DAYS';\n\n\t\tlet where = {};\n\t\tif (typeId && typeId !== '0') where.MEET_TYPE_ID = typeId;\n\t\tconsole.log(typeId)\n\t\twhere.MEET_STATUS = ['in', [MeetModel.STATUS.COMM, MeetModel.STATUS.OVER]]; // 状态  \n\n\t\tif (util.isDefined(search) && search) {\n\t\t\twhere.MEET_TITLE = {\n\t\t\t\t$regex: '.*' + search,\n\t\t\t\t$options: 'i'\n\t\t\t};\n\t\t} else if (sortType && util.isDefined(sortVal)) {\n\t\t\t// 搜索菜单\n\t\t\tswitch (sortType) {\n\t\t\t\tcase 'sort':\n\t\t\t\t\t// 排序\n\t\t\t\t\tif (sortVal == 'view') {\n\t\t\t\t\t\torderBy = {\n\t\t\t\t\t\t\t'MEET_VIEW_CNT': 'desc',\n\t\t\t\t\t\t\t'MEET_ADD_TIME': 'desc'\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tif (sortVal == 'new') {\n\t\t\t\t\t\torderBy = {\n\t\t\t\t\t\t\t'MEET_ADD_TIME': 'desc'\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tlet result = await MeetModel.getList(where, fields, orderBy, page, size, isTotal, oldTotal);\n\n\t\treturn result;\n\t}\n\n\n\n\t/** 取消我的预约 只有成功可以取消 */\n\tasync cancelMyJoin(userId, joinId) {\n\t\tlet where = {\n\t\t\tJOIN_USER_ID: userId,\n\t\t\t_id: joinId,\n\t\t\tJOIN_IS_CHECKIN: 0, // 签到不能取消\n\t\t\tJOIN_STATUS: JoinModel.STATUS.SUCC\n\t\t};\n\t\tlet join = await JoinModel.getOne(where);\n\n\t\tif (!join) {\n\t\t\tthis.AppError('未找到可取消的预约记录');\n\t\t}\n\n\t\t// 取消规则判定\n\t\tlet whereMeet = {\n\t\t\t_id: join.JOIN_MEET_ID,\n\t\t\tMEET_STATUS: ['in', [MeetModel.STATUS.COMM, MeetModel.STATUS.OVER]]\n\t\t}\n\t\tlet meet = await this.getMeetOneDay(join.JOIN_MEET_ID, join.JOIN_MEET_DAY, whereMeet);\n\t\tif (!meet) this.AppError('预约项目不存在或者已关闭');\n\n\t\tlet daySet = this.getDaySetByTimeMark(meet, join.JOIN_MEET_TIME_MARK);\n\t\tlet timeSet = this.getTimeSetByTimeMark(meet, join.JOIN_MEET_TIME_MARK);\n\t\tif (!timeSet) this.AppError('被取消的时段不存在');\n\n\t\tlet startT = daySet.day + ' ' + timeSet.start + ':00';\n\t\tlet startTime = timeUtil.time2Timestamp(startT);\n\n\t\tlet now = timeUtil.time();\n\n\t\tif (now > startTime)\n\t\t\tthis.AppError('该预约已经开始，无法取消');\n\n\n\t\tlet data = {\n\t\t\tJOIN_STATUS: JoinModel.STATUS.CANCEL,\n\t\t\tJOIN_REASON: '',\n\t\t\tJOIN_IS_CHECKIN: 0,\n\t\t}\n\t\tawait JoinModel.edit(where, data);\n\t\tthis.statJoinCnt(join.JOIN_MEET_ID, join.JOIN_MEET_TIME_MARK);\n\n\t}\n\n\t/** 取得我的预约详情 */\n\tasync getMyJoinDetail(userId, joinId) {\n\n\t\tlet fields = 'JOIN_IS_CHECKIN,JOIN_REASON,JOIN_MEET_ID,JOIN_MEET_TITLE,JOIN_MEET_DAY,JOIN_MEET_TIME_START,JOIN_MEET_TIME_END,JOIN_STATUS,JOIN_ADD_TIME,JOIN_CODE,JOIN_FORMS';\n\n\t\tlet where = {\n\t\t\t_id: joinId,\n\t\t\tJOIN_USER_ID: userId\n\t\t};\n\t\treturn await JoinModel.getOne(where, fields);\n\t}\n\n\t/** 取得我的预约分页列表 */\n\tasync getMyJoinList(userId, {\n\t\tsearch, // 搜索条件\n\t\tsortType, // 搜索菜单\n\t\tsortVal, // 搜索菜单\n\t\torderBy, // 排序 \n\t\tpage,\n\t\tsize,\n\t\tisTotal = true,\n\t\toldTotal\n\t}) {\n\t\torderBy = orderBy || {\n\t\t\t//\t'JOIN_MEET_DAY': 'desc',\n\t\t\t//\t'JOIN_MEET_TIME_START': 'desc',\n\t\t\t'JOIN_ADD_TIME': 'desc'\n\t\t};\n\t\tlet fields = 'JOIN_IS_CHECKIN,JOIN_REASON,JOIN_MEET_ID,JOIN_MEET_TITLE,JOIN_MEET_DAY,JOIN_MEET_TIME_START,JOIN_MEET_TIME_END,JOIN_STATUS,JOIN_ADD_TIME';\n\n\t\tlet where = {\n\t\t\tJOIN_USER_ID: userId\n\t\t};\n\t\t//where.MEET_STATUS = ['in', [MeetModel.STATUS.COMM, MeetModel.STATUS.OVER]]; // 状态  \n\n\t\tif (util.isDefined(search) && search) {\n\t\t\twhere.JOIN_MEET_TITLE = {\n\t\t\t\t$regex: '.*' + search,\n\t\t\t\t$options: 'i'\n\t\t\t};\n\t\t} else if (sortType) {\n\t\t\t// 搜索菜单\n\t\t\tswitch (sortType) {\n\t\t\t\tcase 'timedesc': { //按时间倒序\n\t\t\t\t\torderBy = {\n\t\t\t\t\t\t'JOIN_MEET_DAY': 'desc',\n\t\t\t\t\t\t'JOIN_MEET_TIME_START': 'desc',\n\t\t\t\t\t\t'JOIN_ADD_TIME': 'desc'\n\t\t\t\t\t};\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'timeasc': { //按时间正序\n\t\t\t\t\torderBy = {\n\t\t\t\t\t\t'JOIN_MEET_DAY': 'asc',\n\t\t\t\t\t\t'JOIN_MEET_TIME_START': 'asc',\n\t\t\t\t\t\t'JOIN_ADD_TIME': 'asc'\n\t\t\t\t\t};\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'today': { //今天\n\t\t\t\t\twhere.JOIN_MEET_DAY = timeUtil.time('Y-M-D');\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'tomorrow': { //明日\n\t\t\t\t\twhere.JOIN_MEET_DAY = timeUtil.time('Y-M-D', 86400);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'succ': { //预约成功\n\t\t\t\t\twhere.JOIN_STATUS = JoinModel.STATUS.SUCC;\n\t\t\t\t\t//where.JOIN_MEET_DAY = ['>=', timeUtil.time('Y-M-D')];\n\t\t\t\t\t//where.JOIN_MEET_TIME_START = ['>=', timeUtil.time('h:m')];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'cancel': { //已取消\n\t\t\t\t\twhere.JOIN_STATUS = ['in', [JoinModel.STATUS.CANCEL, JoinModel.STATUS.ADMIN_CANCEL]];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tlet result = await JoinModel.getList(where, fields, orderBy, page, size, isTotal, oldTotal);\n\n\t\treturn result;\n\t}\n\n\t/** 取得我的某日预约列表 */\n\tasync getMyJoinSomeday(userId, day) {\n\n\t\tlet fields = 'JOIN_IS_CHECKIN,JOIN_MEET_ID,JOIN_MEET_TITLE,JOIN_MEET_DAY,JOIN_MEET_TIME_START,JOIN_MEET_TIME_END,JOIN_STATUS,JOIN_ADD_TIME';\n\n\t\tlet where = {\n\t\t\tJOIN_USER_ID: userId,\n\t\t\tJOIN_MEET_DAY: day\n\t\t};\n\t\t//where.MEET_STATUS = ['in', [MeetModel.STATUS.COMM, MeetModel.STATUS.OVER]]; // 状态  \n\n\t\tlet orderBy = {\n\t\t\t'JOIN_MEET_TIME_START': 'asc',\n\t\t\t'JOIN_ADD_TIME': 'desc'\n\t\t}\n\n\t\treturn await JoinModel.getAll(where, fields, orderBy);\n\n\n\t}\n}\n\nmodule.exports = MeetService;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/news_service.js",
    "content": "/**\n * Notes: 资讯模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-10-29 07:48:00 \n */\n\nconst BaseProjectService = require('./base_project_service.js');\nconst util = require('../../../framework/utils/util.js');\nconst NewsModel = require('../model/news_model.js');\n\nclass NewsService extends BaseProjectService {\n\n\t/** 浏览资讯信息 */\n\tasync viewNews(id) {\n\n\t\tlet fields = '*';\n\n\t\tlet where = {\n\t\t\t_id: id,\n\t\t\tNEWS_STATUS: 1\n\t\t}\n\t\tlet news = await NewsModel.getOne(where, fields);\n\t\tif (!news) return null;\n\n\n\n\t\treturn news;\n\t}\n\n\n\t/** 取得分页列表 */\n\tasync getNewsList({\n\t\tsearch, // 搜索条件\n\t\tsortType, // 搜索菜单\n\t\tsortVal, // 搜索菜单\n\t\torderBy, // 排序\n\t\tcateId, //附加查询条件\n\t\tpage,\n\t\tsize,\n\t\tisTotal = true,\n\t\toldTotal\n\t}) {\n\n\t\torderBy = orderBy || {\n\t\t\t'NEWS_ORDER': 'asc',\n\t\t\t'NEWS_ADD_TIME': 'desc'\n\t\t};\n\t\tlet fields = 'NEWS_PIC,NEWS_VIEW_CNT,NEWS_TITLE,NEWS_DESC,NEWS_CATE_ID,NEWS_ADD_TIME,NEWS_ORDER,NEWS_STATUS,NEWS_CATE_NAME,NEWS_OBJ';\n\n\t\tlet where = {};\n\t\twhere.NEWS_STATUS = 1; // 状态 \n\n\t\tif (cateId && cateId !== '0') where.NEWS_CATE_ID = cateId;\n\n\t\tif (util.isDefined(search) && search) {\n\t\t\twhere.NEWS_TITLE = {\n\t\t\t\t$regex: '.*' + search,\n\t\t\t\t$options: 'i'\n\t\t\t};\n\t\t} else if (sortType && util.isDefined(sortVal)) {\n\t\t\t// 搜索菜单\n\t\t\tswitch (sortType) {\n\t\t\t\tcase 'sort': {\n\t\t\t\t\torderBy = this.fmtOrderBySort(sortVal, 'NEWS_ADD_TIME');\n\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn await NewsModel.getList(where, fields, orderBy, page, size, isTotal, oldTotal);\n\t}  \n\n}\n\nmodule.exports = NewsService;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/passport_service.js",
    "content": "/**\n * Notes: passport模块业务逻辑 \n * Date: 2020-10-14 07:48:00 \n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n */\n\nconst BaseProjectService = require('./base_project_service.js');\nconst cloudBase = require('../../../framework/cloud/cloud_base.js');\nconst UserModel = require('../model/user_model.js');\nconst dataUtil = require('../../../framework/utils/data_util.js');\n\nclass PassportService extends BaseProjectService {\n\n\t// 注册\n\tasync register(userId, {\n\t\tmobile,\n\t\tname,\n\t\tforms,\n\t\tstatus\n\t}) {\n\t\t// 判断是否存在\n\t\tlet where = {\n\t\t\tUSER_MINI_OPENID: userId\n\t\t}\n\t\tlet cnt = await UserModel.count(where);\n\t\tif (cnt > 0)\n\t\t\treturn await this.login(userId);\n\n\t\twhere = {\n\t\t\tUSER_MOBILE: mobile\n\t\t}\n\t\tcnt = await UserModel.count(where);\n\t\tif (cnt > 0) this.AppError('该手机已注册');\n\n\t\t// 入库\n\t\tlet data = {\n\t\t\tUSER_MINI_OPENID: userId,\n\t\t\tUSER_MOBILE: mobile,\n\t\t\tUSER_NAME: name,\n\t\t\tUSER_OBJ: dataUtil.dbForms2Obj(forms),\n\t\t\tUSER_FORMS: forms,\n\t\t\tUSER_STATUS: Number(status)\n\t\t}\n\t\tawait UserModel.insert(data);\n\n\t\treturn await this.login(userId);\n\t}\n\n\t/** 获取手机号码 */\n\tasync getPhone(cloudID) {\n\t\tlet cloud = cloudBase.getCloud();\n\t\tlet res = await cloud.getOpenData({\n\t\t\tlist: [cloudID], // 假设 event.openData.list 是一个 CloudID 字符串列表\n\t\t});\n\t\tif (res && res.list && res.list[0] && res.list[0].data) {\n\n\t\t\tlet phone = res.list[0].data.phoneNumber;\n\n\t\t\treturn phone;\n\t\t} else\n\t\t\treturn '';\n\t}\n\n\t/** 取得我的用户信息 */\n\tasync getMyDetail(userId) {\n\t\tlet where = {\n\t\t\tUSER_MINI_OPENID: userId\n\t\t}\n\t\tlet fields = 'USER_MOBILE,USER_NAME,USER_FORMS,USER_OBJ,USER_STATUS,USER_CHECK_REASON'\n\t\treturn await UserModel.getOne(where, fields);\n\t}\n\n\t/** 修改用户资料 */\n\tasync editBase(userId, {\n\t\tmobile,\n\t\tname,\n\t\tforms\n\t}) {\n\t\tlet whereMobile = {\n\t\t\tUSER_MOBILE: mobile,\n\t\t\tUSER_MINI_OPENID: ['<>', userId]\n\t\t}\n\t\tlet cnt = await UserModel.count(whereMobile);\n\t\tif (cnt > 0) this.AppError('该手机已注册');\n\n\t\tlet where = {\n\t\t\tUSER_MINI_OPENID: userId\n\t\t}\n\n\t\tlet user = await UserModel.getOne(where);\n\t\tif (!user) return;\n\n\t\tlet data = {\n\t\t\tUSER_MOBILE: mobile,\n\t\t\tUSER_NAME: name,\n\t\t\tUSER_OBJ: dataUtil.dbForms2Obj(forms),\n\t\t\tUSER_FORMS: forms,\n\t\t};\n\n\t\tif (user.USER_STATUS == UserModel.STATUS.UNCHECK)\n\t\t\tdata.USER_STATUS = UserModel.STATUS.UNUSE;\n\n\t\tawait UserModel.edit(where, data);\n\n\t}\n\n\t/** 登录 */\n\tasync login(userId) {\n\n\t\tlet where = {\n\t\t\t'USER_MINI_OPENID': userId\n\t\t};\n\t\tlet fields = 'USER_ID,USER_MINI_OPENID,USER_NAME,USER_PIC,USER_STATUS';\n\t\tlet user = await UserModel.getOne(where, fields);\n\t\tlet token = {};\n\t\tif (user) {\n\n\t\t\t// 正常用户\n\t\t\ttoken.id = user.USER_MINI_OPENID;\n\t\t\ttoken.key = user.USER_ID;\n\t\t\ttoken.name = user.USER_NAME;\n\t\t\ttoken.pic = user.USER_PIC;\n\t\t\ttoken.status = user.USER_STATUS;\n\n\t\t\t// 异步更新最近更新时间\n\t\t\tlet dataUpdate = {\n\t\t\t\tUSER_LOGIN_TIME: this._timestamp\n\t\t\t};\n\t\t\tUserModel.edit(where, dataUpdate);\n\t\t\tUserModel.inc(where, 'USER_LOGIN_CNT', 1);\n\n\t\t} else\n\t\t\ttoken = null;\n\n\t\treturn {\n\t\t\ttoken\n\t\t};\n\t}\n\n\n\n}\n\nmodule.exports = PassportService;"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/product_service.js",
    "content": "/**\n * Notes: 产品模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-06-08 07:48:00 \n */\n\nconst BaseProjectService = require('./base_project_service.js');\nconst util = require('../../../framework/utils/util.js');\nconst ProductModel = require('../model/product_model.js');\n\nclass ProductService extends BaseProjectService {\n\n\t/** 浏览资讯信息 */\n\tasync viewProduct(id) {\n\n\t\tlet fields = '*';\n\n\t\tlet where = {\n\t\t\t_id: id,\n\t\t\tPRODUCT_STATUS: ProductModel.STATUS.COMM\n\t\t}\n\t\tlet product = await ProductModel.getOne(where, fields);\n\t\tif (!product) return null; \n\n\t\tProductModel.inc(id, 'PRODUCT_VIEW_CNT', 1);\n\n\t\treturn product;\n\t}\n\n\n\t/** 取得分页列表 */\n\tasync getProductList({\n\t\tsearch, // 搜索条件\n\t\tsortType, // 搜索菜单\n\t\tsortVal, // 搜索菜单\n\t\torderBy, // 排序 \n\t\tpage,\n\t\tsize,\n\t\tisTotal = true,\n\t\toldTotal\n\t}) {\n\n\t\torderBy = orderBy || {\n\t\t\t'PRODUCT_ORDER': 'asc',\n\t\t\t'PRODUCT_ADD_TIME': 'desc'\n\t\t};\n\t\tlet fields = 'PRODUCT_VIEW_CNT,PRODUCT_TITLE,PRODUCT_CATE_ID,PRODUCT_ADD_TIME,PRODUCT_ORDER,PRODUCT_STATUS,PRODUCT_CATE_NAME,PRODUCT_OBJ';\n\n\t\tlet where = {};\n\t\twhere.and = {\n\t\t\t_pid: this.getProjectId() //复杂的查询在此处标注PID\n\t\t};\n\n\t\twhere.and.PRODUCT_STATUS = ProductModel.STATUS.COMM; // 状态  \n\n\n\t\tif (util.isDefined(search) && search) {\n\t\t\twhere.or = [\n\t\t\t\t{ PRODUCT_TITLE: ['like', search] },\n\t\t\t];\n\t\t} else if (sortType && util.isDefined(sortVal)) {\n\t\t\t// 搜索菜单\n\t\t\tswitch (sortType) {\n\t\t\t\tcase 'cateId': {\n\t\t\t\t\tif (sortVal) where.and.PRODUCT_CATE_ID = String(sortVal);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'sort': {\n\t\t\t\t\torderBy = this.fmtOrderBySort(sortVal, 'PRODUCT_ADD_TIME');\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn await ProductModel.getList(where, fields, orderBy, page, size, isTotal, oldTotal);\n\t}\n\n\n}\n\nmodule.exports = ProductService;"
  },
  {
    "path": "miniprogram/app.js",
    "content": "const setting = require('./setting/setting.js');\n\nApp({\n\tonLaunch: function (options) {\n\n\t\tif (!wx.cloud) {\n\t\t\tconsole.error('请使用 2.2.3 或以上的基础库以使用云能力')\n\t\t} else {\n\t\t\twx.cloud.init({\n\t\t\t\t// env 参数说明：\n\t\t\t\t//   env 参数决定接下来小程序发起的云开发调用（wx.cloud.xxx）会默认请求到哪个云环境的资源\n\t\t\t\t//   此处请填入环境 ID, 环境 ID 可打开云控制台查看\n\t\t\t\t//   如不填则使用默认环境（第一个创建的环境）\n\t\t\t\t// env: 'my-env-id',\n\t\t\t\tenv: setting.CLOUD_ID,\n\t\t\t\ttraceUser: true,\n\t\t\t})\n\t\t}\n\n\t\tthis.globalData = {};\n\n\t\t// 用于自定义导航栏\n\t\twx.getSystemInfo({\n\t\t\tsuccess: e => {\n\t\t\t\tthis.globalData.statusBar = e.statusBarHeight;\n\t\t\t\tlet capsule = wx.getMenuButtonBoundingClientRect();\n\t\t\t\tif (capsule) {\n\t\t\t\t\tthis.globalData.custom = capsule;\n\t\t\t\t\tthis.globalData.customBar = capsule.bottom + capsule.top - e.statusBarHeight;\n\t\t\t\t} else {\n\t\t\t\t\tthis.globalData.customBar = e.statusBarHeight + 50;\n\t\t\t\t} \n\t\t\t}\n\t\t});\n\t}, \n\t \n})"
  },
  {
    "path": "miniprogram/app.json",
    "content": "{\n\t\"pages\": [\n\t\t\"projects/TRIP1/pages/default/index/default_index\", \n\t\t\"projects/TRIP1/pages/about/index/about_index\",\n\t\t\"projects/TRIP1/pages/search/search\",\n\t\t\"projects/TRIP1/pages/my/index/my_index\",\n\t\t\"projects/TRIP1/pages/my/reg/my_reg\",\n\t\t\"projects/TRIP1/pages/my/edit/my_edit\",\n\t\t\"projects/TRIP1/pages/my/foot/my_foot\",\n\t\t\"projects/TRIP1/pages/my/fav/my_fav\",\n\t\t\"projects/TRIP1/pages/news/index/news_index\",\n\t\t\"projects/TRIP1/pages/news/detail/news_detail\",\n\t\t\"projects/TRIP1/pages/news/cate1/news_cate1\",\n\t\t\"projects/TRIP1/pages/news/cate2/news_cate2\",\n\t\t\"projects/TRIP1/pages/admin/news/list/admin_news_list\",\n\t\t\"projects/TRIP1/pages/admin/news/add/admin_news_add\",\n\t\t\"projects/TRIP1/pages/admin/news/edit/admin_news_edit\",\n\t\t\"projects/TRIP1/pages/admin/setup/about/admin_setup_about\",\n\t\t\"projects/TRIP1/pages/admin/setup/about_list/admin_setup_about_list\",\n\t\t\"projects/TRIP1/pages/admin/setup/qr/admin_setup_qr\",\n\t\t\"projects/TRIP1/pages/admin/index/home/admin_home\",\n\t\t\"projects/TRIP1/pages/admin/index/login/admin_login\",\n\t\t\"projects/TRIP1/pages/admin/content/admin_content\",\n\t\t\"projects/TRIP1/pages/admin/mgr/log/admin_log_list\",\n\t\t\"projects/TRIP1/pages/admin/mgr/edit/admin_mgr_edit\",\n\t\t\"projects/TRIP1/pages/admin/mgr/list/admin_mgr_list\",\n\t\t\"projects/TRIP1/pages/admin/mgr/add/admin_mgr_add\",\n\t\t\"projects/TRIP1/pages/admin/mgr/pwd/admin_mgr_pwd\",\n\t\t\"projects/TRIP1/pages/admin/user/list/admin_user_list\",\n\t\t\"projects/TRIP1/pages/admin/user/detail/admin_user_detail\",\n\t\t\"projects/TRIP1/pages/admin/user/export/admin_user_export\",\n\t\t\"projects/TRIP1/pages/meet/index/meet_index\",\n\t\t\"projects/TRIP1/pages/meet/calendar/meet_calendar\",\n\t\t\"projects/TRIP1/pages/meet/join/meet_join\",\n\t\t\"projects/TRIP1/pages/meet/detail/meet_detail\",\n\t\t\"projects/TRIP1/pages/meet/self/meet_self\",\n\t\t\"projects/TRIP1/pages/meet/my_join_list/meet_my_join_list\",\n\t\t\"projects/TRIP1/pages/meet/my_join_detail/meet_my_join_detail\",\n\t\t\"projects/TRIP1/pages/admin/meet/cover/admin_meet_cover\",\n\t\t\"projects/TRIP1/pages/admin/meet/edit/admin_meet_edit\",\n\t\t\"projects/TRIP1/pages/admin/meet/export/admin_join_export\",\n\t\t\"projects/TRIP1/pages/admin/meet/join/admin_meet_join\",\n\t\t\"projects/TRIP1/pages/admin/meet/list/admin_meet_list\",\n\t\t\"projects/TRIP1/pages/admin/meet/record/admin_record_list\",\n\t\t\"projects/TRIP1/pages/admin/meet/scan/admin_meet_scan\",\n\t\t\"projects/TRIP1/pages/admin/meet/self/admin_meet_self\",\n\t\t\"projects/TRIP1/pages/admin/meet/temp/admin_temp_select\",\n\t\t\"projects/TRIP1/pages/admin/meet/time/admin_meet_time\",\n\t\t\"projects/TRIP1/pages/album/detail/album_detail\",\n\t\t\"projects/TRIP1/pages/album/index/album_index\",\n\t\t\"projects/TRIP1/pages/admin/album/list/admin_album_list\",\n\t\t\"projects/TRIP1/pages/admin/album/add/admin_album_add\",\n\t\t\"projects/TRIP1/pages/admin/album/edit/admin_album_edit\",\n\t\t\"projects/TRIP1/pages/product/detail/product_detail\",\n\t\t\"projects/TRIP1/pages/product/index/product_index\",\n\t\t\"projects/TRIP1/pages/admin/product/list/admin_product_list\",\n\t\t\"projects/TRIP1/pages/admin/product/add/admin_product_add\",\n\t\t\"projects/TRIP1/pages/admin/product/edit/admin_product_edit\",\n\t\t\"projects/TRIP1/pages/about/service/about_service\",\n\t\t\"cmpts/public/form/form_set/field/form_set_field\",\n\t\t\"cmpts/public/form/form_show/content/form_show_content\",\n\t\t\"pages/test1/test1\"\n\t],\n\t\"window\": {\n\t\t\"backgroundColor\": \"#f1f1f1\",\n\t\t\"backgroundTextStyle\": \"dark\",\n\t\t\"navigationBarBackgroundColor\": \"#00C176\",\n\t\t\"navigationBarTitleText\": \"旅游景区门户小程序\",\n\t\t\"navigationBarTextStyle\": \"white\"\n\t},\n\t\"tabBar\": {\n\t\t\"custom\": false,\n\t\t\"backgroundColor\": \"#FFFFFF\",\n\t\t\"color\": \"#999999\",\n\t\t\"selectedColor\": \"#00C176\",\n\t\t\"list\": [\n\t\t\t{\n\t\t\t\t\"pagePath\": \"projects/TRIP1/pages/default/index/default_index\",\n\t\t\t\t\"text\": \"首页\",\n\t\t\t\t\"iconPath\": \"/projects/TRIP1/images/tabbar/home.png\",\n\t\t\t\t\"selectedIconPath\": \"/projects/TRIP1/images/tabbar/home_cur.png\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"pagePath\": \"projects/TRIP1/pages/product/index/product_index\",\n\t\t\t\t\"text\": \"景点\",\n\t\t\t\t\"iconPath\": \"/projects/TRIP1/images/tabbar/jing.png\",\n\t\t\t\t\"selectedIconPath\": \"/projects/TRIP1/images/tabbar/jing_cur.png\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"pagePath\": \"projects/TRIP1/pages/album/index/album_index\",\n\t\t\t\t\"text\": \"攻略\",\n\t\t\t\t\"iconPath\": \"/projects/TRIP1/images/tabbar/gong.png\",\n\t\t\t\t\"selectedIconPath\": \"/projects/TRIP1/images/tabbar/gong_cur.png\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"pagePath\": \"projects/TRIP1/pages/about/service/about_service\",\n\t\t\t\t\"text\": \"服务\",\n\t\t\t\t\"iconPath\": \"/projects/TRIP1/images/tabbar/service.png\",\n\t\t\t\t\"selectedIconPath\": \"/projects/TRIP1/images/tabbar/service_cur.png\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"pagePath\": \"projects/TRIP1/pages/my/index/my_index\",\n\t\t\t\t\"text\": \"我的\",\n\t\t\t\t\"iconPath\": \"/projects/TRIP1/images/tabbar/my.png\",\n\t\t\t\t\"selectedIconPath\": \"/projects/TRIP1/images/tabbar/my_cur.png\"\n\t\t\t}\n\t\t]\n\t}, \n\t\"permission\": {\n\t\t\"scope.userLocation\": {\n\t\t\t\"desc\": \"获取你当前位置信息用于小程序位置接口的效果展示\"\n\t\t}\n\t},\n\t\"usingComponents\": {\n\t\t\"cmpt-comm-list\": \"/cmpts/public/list/comm_list_cmpt\",\n\t\t\"cmpt-picker\": \"/cmpts/public/picker/picker_cmpt\",\n\t\t\"cmpt-modal\": \"/cmpts/public/modal/modal_cmpt\"\n\t},\n\t\"sitemapLocation\": \"sitemap.json\"\n}"
  },
  {
    "path": "miniprogram/app.wxss",
    "content": "@import \"style/base/comm.wxss\";\n@import \"style/public/project.wxss\"; \n"
  },
  {
    "path": "miniprogram/cmpts/biz/detail/detail_cmpt.js",
    "content": "const pageHelper = require('../../../helper/page_helper');\nconst posterCmptHelper = require('../../public/poster/poster_cmpt_helper.js');\nconst FavBiz = require('../../../comm/biz/fav_biz.js');\nconst FootBiz = require('../../../comm/biz/foot_biz.js');\n\nComponent({\n\toptions: {\n\t\taddGlobalClass: true\n\t},\n\n\t/**\n\t * 组件的属性列表\n\t */\n\tproperties: {\n\t\tmode: {\n\t\t\ttype: String,\n\t\t\tvalue: 'mode1'\n\t\t},\n\t\toid: {\n\t\t\ttype: String,\n\t\t\tvalue: ''\n\t\t},\n\t\tcate: {\n\t\t\ttype: String,\n\t\t\tvalue: ''\n\t\t},\n\t\ttitle: {\n\t\t\ttype: String,\n\t\t\tvalue: ''\n\t\t},\n\t\tcover: {\n\t\t\ttype: String,\n\t\t\tvalue: ''\n\t\t},\n\t\tdesc: {\n\t\t\ttype: String,\n\t\t\tvalue: '查看详情'\n\t\t},\n\t\tqr: {\n\t\t\ttype: String,\n\t\t\tvalue: ''\n\t\t},\n\t\tbg: {\n\t\t\ttype: String,\n\t\t\tvalue: ''\n\t\t},\n\t\ttag: {\n\t\t\ttype: String, //小角标\n\t\t\tvalue: ''\n\t\t},\n\t\tdoFav: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: true\n\t\t},\n\t\tdoFoot: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: true\n\t\t},\n\t\tdoShare: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: true\n\t\t},\n\t\tdoHome: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: true\n\t\t},\n\t\tdoPoster: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: true\n\t\t},\n\t\tdoFoot: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: true\n\t\t},\n\t\tdoTop: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: true\n\t\t},\n\t\tdoSlot: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: false\n\t\t},\n\t\ttopBtnBottom: {\n\t\t\ttype: Number,\n\t\t\tvalue: 190\n\t\t},\n\t\ttopBtnShow: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: false\n\t\t},\n\t},\n\n\t/**\n\t * 组件的初始数据\n\t */\n\tdata: {\n\t\tisFav: -1,\n\t\tshowPoster: false,\n\t\tposterConfig: null,\n\t},\n\n\tlifetimes: {\n\t\tcreated: function () {\n\n\t\t},\n\t\tattached: function () {\n\n\t\t},\n\t\tready: async function () {\n\t\t\tif (!this.data.oid || !this.data.title) return;\n\n\t\t\tif (this.data.doFav) {\n\t\t\t\tFavBiz.isFav(this, this.data.oid);\n\t\t\t}\n\n\t\t\tif (this.data.doFoot) {\n\t\t\t\tFootBiz.addFoot(this.data.cate, this.data.title);\n\t\t\t}\n\n\t\t\tif (this.data.doShare) {\n\n\t\t\t\tlet posterConfig = await posterCmptHelper.config1({\n\t\t\t\t\tcover: this.data.cover,\n\t\t\t\t\ttitle: this.data.title,\n\t\t\t\t\tdesc: this.data.desc,\n\t\t\t\t\tqr: this.data.qr,\n\t\t\t\t\tbg: this.data.bg\n\t\t\t\t})\n\t\t\t\tthis.setData({\n\t\t\t\t\tposterConfig\n\t\t\t\t});\n\n\t\t\t}\n\t\t},\n\t\tmove: function () {\n\n\t\t},\n\t\tdetached: function () {\n\n\t\t},\n\t},\n\n\t/**\n\t * 组件的方法列表\n\t */\n\tmethods: {\n\t\tbindShareTap: function () {\n\t\t\tthis.setData({\n\t\t\t\tshowPoster: true\n\t\t\t});\n\t\t},\n\t\tbindFavTap: async function () {\n\t\t\tif (this.data.isFav == -1) return;\n\t\t\t\n\t\t\tawait FavBiz.updateFav(this, this.data.oid, this.data.isFav, this.data.cate, this.data.title);\n\t\t},\n\t\turl: function (e) {\n\t\t\tpageHelper.url(e, this);\n\t\t},\n\t\tbindHomeTap: function (e) {\n\t\t\tlet url = pageHelper.fmtURLByPID('/pages/default/index/default_index');\n\t\t\twx.reLaunch({ url });\n\t\t}, \n\t\ttop: function (e) {\n\t\t\t// 回页首事件\n\t\t\tpageHelper.top();\n\t\t} \n\t}\n})"
  },
  {
    "path": "miniprogram/cmpts/biz/detail/detail_cmpt.json",
    "content": "{\n\t\"component\": true,\n\t\"usingComponents\": {\n\t\t\"cmpt-poster\": \"/cmpts/public/poster/poster_cmpt\"\n\t}\n}"
  },
  {
    "path": "miniprogram/cmpts/biz/detail/detail_cmpt.wxml",
    "content": "<view style=\"height:200rpx\"></view>\n\n<view wx:if=\"{{doHome&&mode!='right'}}\" bindtap=\"bindHomeTap\" class=\"cmpt-fixed-home-btn\"><text class=\"icon-home\"></text><text style=\"font-size:22rpx;\">首页</text></view>\n\n<!--回页首 begin-->\n<block wx:if=\"{{doTop}}\">\n\t<import src=\"../../../tpls/public/top_tpl.wxml\" />\n\t<template is=\"topTpl\" data=\"{{topBtnShow, bottom:topBtnBottom}}\" />\n</block>\n<!--回页首 end-->\n\n<!--mode1 BEGIN-->\n<view wx:if=\"{{mode=='mode1'}}\" class=\"cmpt-biz-detail-mode1 safe-bottom\">\n\t<view wx:if=\"{{tag}}\" class=\"has-tag\">{{tag}}</view>\n\t<view class=\"fav btn-inner\" bindtap=\"bindFavTap\" wx:if=\"{{doFav}}\">\n\t\t<block wx:if=\"{{isFav>0}}\">\n\t\t\t<text class=\"icon-favorfill margin-right-xxs text-project\" style=\"color:{{bg}}!important\"></text><text class=\"text-project\" style=\"color:{{bg}}!important\">已收藏</text>\n\t\t</block>\n\t\t<block wx:else>\n\t\t\t<text class=\"icon-favor margin-right-xxs\"></text>加入收藏\n\t\t</block>\n\t</view>\n\t<view class=\"btn-inner\" bindtap=\"bindShareTap\" wx:if=\"{{doShare&&doPoster}}\">\n\t\t<view class=\"share\"><text class=\"icon-forward margin-right-xxs\"></text>分享</view>\n\t</view>\n\t<view class=\"btn-inner\" wx:if=\"{{doShare&&!doPoster}}\">\n\t\t<button class=\"share clearbtn\" open-type=\"share\" style=\"margin-top:-10rpx\"><text class=\"icon-forward margin-right-xxs\"></text>分享</button>\n\t</view>\n\n\t<slot />\n\n</view>\n<!--mode1 end-->\n\n<!--mode2 BEGIN-->\n<view wx:if=\"{{mode=='mode2'}}\" class=\"cmpt-biz-detail-mode2 safe-bottom\">\n\t<view wx:if=\"{{tag}}\" class=\"has-tag\">{{tag}}</view>\n\t<view class=\"inner\">\n\t\t<button class=\"share clearbtn\" bindtap=\"bindShareTap\" wx:if=\"{{doShare&&doPoster}}\">\n\t\t\t<text class=\"icon-forward\"></text>\n\t\t\t<text class=\"text-s\">分享</text>\n\t\t</button>\n\t\t<button class=\"share clearbtn\" open-type=\"share\" wx:if=\"{{doShare&&!doPoster}}\">\n\t\t\t<text class=\"icon-forward\"></text>\n\t\t\t<text class=\"text-s\">分享</text>\n\t\t</button>\n\t\t<block wx:if=\"{{doFav}}\">\n\t\t\t<view bindtap=\"bindFavTap\" class=\"fav text-project\" wx:if=\"{{isFav>0}}\">\n\t\t\t\t<text class=\"icon-favorfill\"></text>\n\t\t\t\t<text class=\"text-s\">已收藏</text>\n\t\t\t</view>\n\t\t\t<view bindtap=\"bindFavTap\" class=\"fav\" wx:else>\n\t\t\t\t<text class=\"icon-favor\"></text>\n\t\t\t\t<text class=\"text-s\">收藏</text>\n\t\t\t</view>\n\t\t</block>\n\t\t<view class=\"slot-inner\">\n\t\t\t<slot />\n\t\t</view>\n\t</view>\n</view>\n<!--mode2 end-->\n\n<!--mode right BEGIN-->\n<view wx:if=\"{{mode=='right'}}\" class=\"cmpt-biz-detail-mode-right safe-bottom\"> \n\t<view class=\"inner\">\n\t\t<block wx:if=\"{{doHome}}\">\n\t\t\t<view bindtap=\"bindHomeTap\" class=\"fixed-btn\">\n\t\t\t\t<text class=\"icon-home\"></text> \n\t\t\t</view> \n\t\t</block>\n\t\t<button class=\"fixed-btn clearbtn\" bindtap=\"bindShareTap\" wx:if=\"{{doShare&&doPoster}}\">\n\t\t\t<text class=\"icon-forward\"></text> \n\t\t</button>\n\t\t<button class=\"fixed-btn clearbtn\" open-type=\"share\" wx:if=\"{{doShare&&!doPoster}}\">\n\t\t\t<text class=\"icon-forward\"></text> \n\t\t</button>\n\t\t<block wx:if=\"{{doFav}}\">\n\t\t\t<view bindtap=\"bindFavTap\" class=\"fixed-btn\" wx:if=\"{{isFav>0}}\">\n\t\t\t\t<text class=\"icon-favorfill\"></text> \n\t\t\t</view>\n\t\t\t<view bindtap=\"bindFavTap\" class=\"fixed-btn\" wx:else>\n\t\t\t\t<text class=\"icon-favor\"></text> \n\t\t\t</view>\n\t\t</block> \n\t\t<view class=\"slot-inner\">\n\t\t\t<slot />\n\t\t</view>\n\t</view>\n</view>\n<!--mode right end-->\n\n<cmpt-poster model:show=\"{{showPoster}}\" doPoster=\"{{doPoster}}\" wx:if=\"{{ posterConfig}}\" config=\"{{posterConfig}}\" />"
  },
  {
    "path": "miniprogram/cmpts/biz/detail/detail_cmpt.wxss",
    "content": ".cmpt-fixed-home-btn {\n\tposition: fixed;\n\tbottom: 180rpx;\n\tleft: 10rpx;\n\tfont-size: 45rpx;\n\theight: 80rpx;\n\twidth: 80rpx;\n\tbackground-color: rgba(0, 0, 0, 0.2);\n\tborder-radius: 50%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n\talign-items: center;\n\tcolor: #fff;\n\tz-index: 99999;\n\n}\n\n/*MODE1*/\n.cmpt-biz-detail-mode1 {\n\tbox-shadow: 0 -6rpx 8rpx rgba(114, 130, 138, 0.2);\n\twidth: 100%;\n\tposition: fixed;\n\tbottom: 0;\n\tbackground-color: #f2f2f2;\n\tz-index: 9999999;\n\tdisplay: flex;\n\talign-items: stretch;\n\tjustify-content: center;\n\tfont-size: 32rpx;\n\tcolor: #333; \n}\n\n.cmpt-biz-detail-mode1 .has-tag {\n\tposition: absolute;\n\ttop: 0rpx;\n\tright: 0rpx;\n\tz-index: 9999;\n\tfont-size: 22rpx; \n\tpadding: 0rpx 4rpx;\n\tborder-radius: 5rpx; \n\tcolor: #fff; \n\tbackground-color: rgba(0, 0, 0, 0.2);\n}\n\n.cmpt-biz-detail-mode1 .btn-inner {\n\tpadding: 30rpx 0rpx;\n\tflex: 1 1 0;\n\ttext-align: center;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.cmpt-biz-detail-mode1 .btn-inner {\n\tborder-right: 1rpx solid #ddd;\n}\n\n.cmpt-biz-detail-mode1 .btn-inner:last-child {\n\tborder-right: unset;\n}\n\n.cmpt-biz-detail-mode1 .btn-inner .fav {\n\tbackground: inherit;\n}\n\n.cmpt-biz-detail-mode1 .btn-inner .share {\n\tbackground: inherit;\n}\n\n/*MODE2*/\n.cmpt-biz-detail-mode2 {\n\twidth: 100%;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tposition: fixed;\n\tbottom: 0;\n\tbackground-color: #fff;\n\tbox-shadow: 0 -6rpx 8rpx rgba(114, 130, 138, 0.1);\n\tz-index: 999;\n}\n\n.cmpt-biz-detail-mode2 .has-tag {\n\tposition: absolute;\n\ttop: 5rpx;\n\tright: 10rpx;\n\tz-index: 9999;\n\tfont-size: 24rpx;\n\tbackground-color: #f8f8f8;\n\tpadding: 5rpx 10rpx;\n\tborder-radius: 10rpx;\n\tcolor: #666;\n\tborder: 1rpx solid #eee;\n}\n\n.cmpt-biz-detail-mode2 .inner {\n\twidth: 100%;\n\tpadding: 20rpx 20rpx;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n}\n\n.cmpt-biz-detail-mode2 .inner .slot-inner {\n\tflex: 1;\n\tpadding: 0 20rpx;\n}\n\n.cmpt-biz-detail-mode2 .share,\n.cmpt-biz-detail-mode2 .fav {\n\tfont-size: 35rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: center;\n\tpadding: 0 20rpx;\n\twidth: 120rpx;\n}\n\n.cmpt-biz-detail-mode2 .share .text-s,\n.cmpt-biz-detail-mode2 .fav .text-s {\n\tmargin-top: 0rpx;\n\tfont-size: 24rpx;\n}\n\n\n/*MODE RIGHT*/\n.cmpt-biz-detail-mode-right { \n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-start;\n\tflex-direction: column;\n\tposition: fixed;\n\tbottom: 90rpx;\n\tright:15rpx;  \n\tz-index: 99999; \n}\n \n.cmpt-biz-detail-mode-right .fixed-btn { \n\tfont-size: 35rpx;\n\theight: 60rpx;\n\twidth: 60rpx;\n\tbackground-color: rgba(0, 0, 0, 0.2);\n\tborder-radius: 50%;\n\tdisplay: flex; \n\tjustify-content: center;\n\talign-items: center;\n\tcolor: #fff;\n\tmargin-bottom: 15rpx;\n}\n\n.cmpt-biz-detail-mode-right .fixed-btn .text-t{ \n\tfont-size: 22rpx;  \n}"
  },
  {
    "path": "miniprogram/cmpts/biz/foot/foot_cmpt.js",
    "content": "const pageHelper = require('../../../helper/page_helper');\nconst setting = require('../../../setting/setting.js');\n\nComponent({\n\toptions: {\n\t\taddGlobalClass: true\n\t},\n\t\n\t/**\n\t * 组件的属性列表\n\t */\n\tproperties: {\n\t\tcolor: {  \n\t\t\ttype: String,\n\t\t\tvalue: ''\n\t\t},\n\t},\n\n\t/**\n\t * 组件的初始数据\n\t */\n\tdata: {\n\n\t},\n\n\tlifetimes: {\n\t\tcreated: function () {\n\t\t\t// 组件实例化，但节点树还未导入，因此这时不能用setData\n\t\t},\n\t\tattached: function () {\n\t\t\t// 在组件实例进入页面节点树时执行 \n\t\t\t// 节点树完成，可以用setData渲染节点，但无法操作节点 \n\t\t},\n\t\tready: async function () {\n\t\t\t// 组件布局完成，这时可以获取节点信息，也可以操作节点 \n\t\t\t// 当前用户，用于评论删除\n\t\t\tthis._loadDetail();\n\t\t},\n\t\tmove: function () {\n\t\t\t// 组件实例被移动到树的另一个位置\n\t\t},\n\t\tdetached: function () {\n\t\t\t// 在组件实例被从页面节点树移除时执行\n\t\t},\n\t},\n\n\t/**\n\t * 组件的方法列表\n\t */\n\tmethods: {\n\t\t_loadDetail: async function () {\n\t\t\tthis.setData({\n\t\t\t\tcompany: setting.COMPANY,\n\t\t\t\tver: setting.VER\n\t\t\t});\n\t\t},\n\t\turl: function (e) {\n\t\t\tpageHelper.url(e, this);\n\t\t}\n\t}\n})"
  },
  {
    "path": "miniprogram/cmpts/biz/foot/foot_cmpt.json",
    "content": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/biz/foot/foot_cmpt.wxml",
    "content": "<view class=\"site-footer\" bindtap=\"url\" data-type=\"mini\" data-app=\"wx1a3ad7903d85f33a\" data-url=\"/pages/home/index/home_index\">\n\t<view class=\"info {{color}}\"> © {{company}} </view>\n\t<view class=\"info margin-top-xs {{color}}\">{{ver}}</view>\n</view>"
  },
  {
    "path": "miniprogram/cmpts/biz/foot/foot_cmpt.wxss",
    "content": "@import \"../../../style/public/project.wxss\";\n\n.site-footer {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n\talign-items: center;\n\tfont-size: 24rpx;\n\tcolor: #aaa;\n\tmargin-top: 20rpx;\n\tmargin-bottom: 20rpx;\n}  "
  },
  {
    "path": "miniprogram/cmpts/public/calendar/calendar_comm/calendar_comm_cmpt.js",
    "content": "const timeHelper = require('../../../../helper/time_helper.js');\nconst pageHelper = require('../../../../helper/page_helper.js');\nconst calendarLib = require('../calendar_lib.js');\n\n/*#### 父组件日历颜色定义*/\n/* 整体颜色 */\n//--calendarPageColor: #F0F4FF;\n/* 加重颜色*/\n//--calendarMainColor: #388AFF;\n/* 加重的亮颜色 用于选中日期的数据小圆点 */\n//--calendarLightColor: #A2C7FF;\n\n\nComponent({\n\toptions: {\n\t\taddGlobalClass: true\n\t},\n\tproperties: {\n\t\tisLunar: { //是否开启农历\n\t\t\ttype: Boolean,\n\t\t\tvalue: true\n\t\t},\n\t\tmode: { // 模式 one/multi\n\t\t\ttype: String,\n\t\t\tvalue: 'one'\n\t\t},\n\n\t\tyear: { // 正在操作的年\n\t\t\ttype: Number,\n\t\t\tvalue: 0\n\t\t},\n\n\t\tmonth: { // 正在操作的月\n\t\t\ttype: Number,\n\t\t\tvalue: 0\n\t\t},\n\t\tfold: { //日历折叠\n\t\t\ttype: Boolean,\n\t\t\tvalue: false\n\t\t},\n\t\tselectTimeout: { //过期时间选择(mode=multi)\n\t\t\ttype: Boolean,\n\t\t\tvalue: true\n\t\t},\n\t\tselectTimeoutHint: { //过期时间选择提示(mode=multi)\n\t\t\ttype: String,\n\t\t\tvalue: '不能选择过去的日期'\n\t\t},\n\t\thasDays: { // 有数据的日期\n\t\t\ttype: Array,\n\t\t\tvalue: [],\n\t\t\tobserver: function (newVal, oldVal) {\n\t\t\t\tif (newVal.length != oldVal.length) {\n\t\t\t\t\t// TODO 引起加载的时候二次调用 \n\t\t\t\t\t//this._init();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\toneDoDay: { // 正在操作的天  string\n\t\t\ttype: String,\n\t\t\tvalue: null\n\t\t},\n\t\tmultiDoDay: { // 多选模式>正在操作的天 arrary[]\n\t\t\ttype: Array,\n\t\t\tvalue: [],\n\t\t},\n\t\tmultiOnlyOne: { //多选模式>只能选一个\n\t\t\ttype: Boolean,\n\t\t\tvalue: false\n\t\t}\n\t},\n\n\tdata: {\n\t\tweekNo: 0, // 正在操作的那天位于第几周 \n\t\tfullToday: 0, //今天 \n\t},\n\n\tlifetimes: {\n\t\tattached() {\n\t\t\tthis._init();\n\t\t}\n\t},\n\n\tmethods: {\n\t\t_init: function () {\n\t\t\tcalendarLib.getNowTime(this);\n\t\t\tcalendarLib.createDay(this);\n\t\t},\n\n\n\t\tbindFoldTap: function (e) { // 日历折叠\n\t\t\tcalendarLib.bindFoldTap(this);\n\t\t},\n\n\n\t\tbindNextTap(e) { // 下月\n\t\t\tcalendarLib.bindNextTap(this);\n\t\t},\n\n\t\tbindLastTap(e) { // 上月\n\t\t\tcalendarLib.bindLastTap(this);\n\t\t},\n\n\t\tbindDayOneTap(e) { // 单个天点击\n\t\t\tlet day = e.currentTarget.dataset.fullday;\n\t\t\tlet now = timeHelper.time('Y-M-D');\n\t\t\tif (day < now)\n\t\t\t\treturn pageHelper.showNoneToast('已过期', 1000);\n\n\t\t\tcalendarLib.bindDayOneTap(e, this);\n\t\t},\n\n\t\tbindDayMultiTap(e) { // 多选天点击\n\t\t\t// 过期时间判断\n\t\t\tif (!this.data.selectTimeout) {\n\t\t\t\tlet day = e.currentTarget.dataset.fullday;\n\t\t\t\tlet now = timeHelper.time('Y-M-D');\n\t\t\t\tif (day < now)\n\t\t\t\t\treturn pageHelper.showNoneToast(this.data.selectTimeoutHint);\n\t\t\t}\n\n\n\t\t\tcalendarLib.bindDayMultiTap(e, this);\n\t\t},\n\n\t\tbindToNowTap: function (e) { // 回本月\n\t\t\tcalendarLib.bindToNowTap(this);\n\t\t},\n\n\t\t// ListTouch触摸开始\n\t\tlistTouchStart(e) {\n\t\t\tpageHelper.listTouchStart(e, this);\n\t\t},\n\n\t\t// ListTouch计算方向\n\t\tlistTouchMove(e) {\n\t\t\tpageHelper.listTouchMove(e, this);\n\t\t},\n\n\t\t/** ListTouch计算滚动 */\n\t\tlistTouchEnd: function (e) {\n\t\t\tcalendarLib.listTouchEnd(this);\n\t\t}\n\t}\n})"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/calendar_comm/calendar_comm_cmpt.json",
    "content": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/calendar_comm/calendar_comm_cmpt.wxml",
    "content": "<wxs src=\"../../../../tpls/wxs/tools.wxs\" module=\"tools\" />\n<wxs module=\"utils\">\n\t// 比较操作日期所在月是否当前显示的月\n\tfunction compareYearMonth(oneDoDay, year, month) {\n\t\tvar arr = oneDoDay.split('-');\n\t\treturn arr[0] == year && arr[1] == month;\n\t}\n\n\tmodule.exports = {\n\t\tcompareYearMonth: compareYearMonth,\n\t};\n</wxs>\n<view class=\"cal-container\">\n\t<view class=\"cal-main\">\n\t\t<view class=\"text-center cal-nav\">\n\t\t\t<view class=\"to-now\" bindtap=\"bindToNowTap\">本月</view>\n\t\t\t<view class=\"select-item\">\n\t\t\t\t<view class=\"arrow\" bindtap=\"bindLastTap\"><text class=\"icon-back\" /></view>\n\t\t\t\t<view class=\"text-lg\">{{year}}年{{month}}月</view>\n\t\t\t\t<view class=\"arrow\" bindtap=\"bindNextTap\"><text class=\" icon-right\" /></view>\n\t\t\t</view>\n\t\t\t<block wx:if=\"{{mode=='one'}}\">\n\t\t\t\t<view wx:if=\"{{!fold}}\" class=\"fold\" bindtap=\"bindFoldTap\"><text class=\"icon-fold\"></text></view>\n\t\t\t\t<view wx:if=\"{{fold}}\" class=\"fold\" bindtap=\"bindFoldTap\"><text class=\"icon-unfold\"></text>\n\t\t\t\t</view>\n\t\t\t</block>\n\t\t</view>\n\n\t\t<view class=\"cal-title\">\n\t\t\t<view class=\"cal-title-view\">一</view>\n\t\t\t<view class=\"cal-title-view\">二</view>\n\t\t\t<view class=\"cal-title-view\">三</view>\n\t\t\t<view class=\"cal-title-view\">四</view>\n\t\t\t<view class=\"cal-title-view\">五</view>\n\t\t\t<view class=\"cal-title-view text-orange\">六</view>\n\t\t\t<view class=\"cal-title-view text-red\">日</view>\n\t\t</view>\n\t\t<view class=\"cal-center {{!fold?'cur':''}} \">\n\t\t\t<!--单击begin-->\n\t\t\t<view wx:for=\"{{dayArr}}\" wx:if=\"{{mode=='one' && (weekNo>0&&item.weekNo==weekNo&&utils.compareYearMonth(oneDoDay,year,month) || item.weekNo==1&&!utils.compareYearMonth(oneDoDay,year,month) || !fold)}}\" wx:key=\"key\" data-fullday=\"{{item.full}}\" class=\"cube {{isLunar?'lunar':''}} \" bindtap=\"bindDayOneTap\">\n\t\t\t\t<view class=\"num-grid  {{fullToday==item.full? 'now-day-cur' : ''}}  {{oneDoDay==item.full? 'calendar-bg text-white shadow ' : ''}} \">\n\t\t\t\t\t<view class=\"num  {{!item.curMonth? 'text-no-month' : ''}}\">\n\t\t\t\t\t\t<text class=\"dd\" wx:if=\"{{tools.includes(hasDays,item.full)}}\" class=\"data-has\">{{item.show}}</text>\n\t\t\t\t\t\t<text class=\"dd\" wx:else>{{item.show}}</text>\n\t\t\t\t\t\t<text wx:if=\"{{isLunar}}\" class=\"lunar {{oneDoDay==item.full? 'text-white' : ''}} {{item.holiday?'text-red':''}}\">{{item.lunar}}</text>\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\n\t\t\t</view>\n\t\t\t<!--单击END-->\n\n\t\t\t<!--多选begin-->\n\t\t\t<view wx:for=\"{{dayArr}}\" wx:if=\"{{mode=='multi'}}\" wx:key=\"key\" data-fullday=\"{{item.full}}\" class=\"cube {{isLunar?'lunar':''}}\" bindtap=\"bindDayMultiTap\">\n\t\t\t\t<view class=\"num-grid  {{fullToday==item.full? 'now-day-cur' : ''}}  {{tools.includes(multiDoDay,item.full)? 'calendar-bg text-white data-checked' : ''}} \">\n\t\t\t\t\t<view class=\"num  {{!item.curMonth? 'text-no-month' : ''}} \">\n\t\t\t\t\t\t<text class=\"dd\" wx:if=\"{{tools.includes(hasDays,item.full)}}\" class=\"data-has\">{{item.show}}</text>\n\t\t\t\t\t\t<text class=\"dd\" wx:else>{{item.show}}</text>\n\t\t\t\t\t\t<text wx:if=\"{{isLunar}}\" class=\"lunar {{tools.includes(multiDoDay,item.full)? 'text-white' : ''}} {{item.holiday?'text-red':''}}\">{{item.lunar}}</text>\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t\t<!--多选END-->\n\n\t\t</view>\n\n\t</view>\n</view>"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/calendar_comm/calendar_comm_cmpt.wxss",
    "content": "@import \"./din.wxss\";\n\npage {\n\t/*#### 父组件日历颜色定义*/\n\t/* 整体颜色 */\n\t--calendarPageColor: #fff;\n\t/* 加重颜色*/\n\t--calendarMainColor: #1F6ED4;\n\t/* 加重的亮颜色 用于选中日期的数据小圆点 */\n\t--calendarLightColor: #A2C7FF;\n}\n\n.calendar-text {\n\tcolor: var(--calendarMainColor) !important\n}\n\n.calendar-bg {\n\tbackground-color: var(--calendarMainColor) !important\n}\n\n.cal-container {\n\twidth: 100%;\n\tpadding-bottom: 10rpx;\n\tbackground-color: var(--calendarPageColor)\n}\n\n.cal-container .cal-nav {\n\tposition: relative;\n\twidth: 100%;\n\tmin-height: 80rpx;\n\tdisplay: flex;\n\tflex-direction: row;\n\tjustify-content: center;\n\talign-items: center;\n\tpadding: 0 20rpx;\n\tcolor: #666; \n\tfont-weight: bold;\n\tbackground-color: #f8f8f8;\n}\n\n.cal-container .cal-nav .select-item {\n\twidth: 500rpx;\n\tdisplay: flex;\n\tflex-direction: row;\n\tjustify-content: space-between;\n\talign-items: center;\n}\n\n.cal-container .cal-nav .arrow {\n\twidth: 150rpx;\n\tfont-size: 40rpx;\n}\n\n.cal-container .cal-nav .fold {\n\tposition: absolute;\n\tright: 0rpx;\n\twidth: 100rpx;\n\tfont-size: 40rpx;\n\tfont-weight: bold;\n}\n\n.cal-container .cal-nav .to-now {\n\tposition: absolute;\n\tleft: 5rpx;\n\twidth: 100rpx;\n\tfont-size: 28rpx; \n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.cal-main {\n\twidth: 100%;\n\tpadding: 0rpx 0rpx;\n}\n\n.cal-title {\n\tdisplay: flex;\n\twidth: 100%;\n\tborder-bottom: 2rpx dashed #ccc;\n\tbackground-color: #f8f8f8;\n}\n\n.cal-title .cal-title-view {\n\twidth: 14.28%;\n\theight: 70rpx;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tcolor: #333;\n\tfont-size: 32rpx;\n\tfont-weight: bold;\n}\n\n.cal-center {\n\tdisplay: flex;\n\tflex-direction: row;\n\tflex-wrap: wrap; \n\toverflow: hidden;\n\tjustify-content: center;\n\talign-items: center;\n}\n \n.cal-center .cube {\n\twidth: 14.28%;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n}\n\n.cal-center .cube.lunar {\n\tmargin-bottom: 0rpx;\n}\n\n.cal-center .num-grid {\n\tmin-width: 70rpx;\n\theight: 70rpx;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tcolor: #333;\n\tmargin-bottom: 2rpx;\n\tborder-radius: 10rpx;\n}\n\n.cal-center .cube.lunar .num-grid {\n\twidth: 70rpx;\n\theight: 90rpx;\n}\n\n.cal-center .num-grid.now-day-cur {\n\tbackground-color: #fadbd9;\n\tcolor: orangered;\n\tfont-weight: bold;\n}\n\n.cal-center .num-grid.now-day-cur.calendar-bg {\n\tcolor: #fbbd08 !important;\n}\n\n\n.cal-center .num {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n\talign-items: center;\n\tfont-size: 32rpx;\n\tfont-family: 'din';\n}\n\n.cal-center .num .lunar {\n\tfont-size: 20rpx;\n\tfont-weight: normal;\n\tcolor: #aaa;\n}\n\n.cal-center .text-no-month {\n\tcolor: #333;\n\topacity: .5;\n}\n\n.cal-center .calendar-bg .text-no-month {\n\tcolor: #ccc;\n\topacity: 1;\n}\n\n\n/* 当日有数据 */\n.data-has {\n\tposition: relative;\n\tborder-radius: 50%;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n}\n\n.data-has::before {\n\tposition: absolute;\n\tcontent: '';\n\twidth: 12rpx;\n\theight: 12rpx;\n\tborder-radius: 50%;\n\tbackground-color: var(--calendarMainColor);\n\tright: -16rpx;\n\ttop: 14rpx;\n}\n\n.calendar-bg .data-has::before {\n\tbackground-color: var(--calendarLightColor);\n}\n\n\n/* 选中某日 */\n.cube .data-checked {\n\tposition: relative;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n}\n\n.cube .data-checked::before {\n\tposition: absolute;\n\tcontent: '';\n\twidth: 17rpx;\n\theight: 17rpx;\n\ttransform: rotate(45deg);\n\tborder-right: 3rpx solid #fff;\n\tborder-bottom: 3rpx solid #fff;\n\tbottom: 13rpx;\n}\n\n.cube.lunar .data-checked::before {\n\tbottom: 38rpx;\n}"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/calendar_comm/din.wxss",
    "content": "@font-face {\n    font-family: 'din';\n    src: url('data:font/ttf;charset=utf-8;base64,AAEAAAAPAIAAAwBwRkZUTYgLMMEAAlaAAAAAHEdERUY15TphAAHagAAAAI5HUE9TXpiR2QAB9UgAAGE4R1NVQgGZl0kAAdsQAAAaNk9TLzJhprB7AAABeAAAAGBjbWFwlg4SlgAAEUAAAAVOZ2FzcP//AAMAAdp4AAAACGdseWZKMGmsAAAeVAABkBhoZWFkGyNVqwAAAPwAAAA2aGhlYRFbC3oAAAE0AAAAJGhtdHiGGBg+AAAB2AAAD2hsb2NhAkJmIgAAFpAAAAfEbWF4cAQqAFsAAAFYAAAAIG5hbWUcsXOaAAGubAAAB3Fwb3N0m0IygAABteAAACSWAAEAAAAEAAB/+YqcXw889QALCAAAAAAA1FMptQAAAADeE+AD/Zz9rgv+CUgAAAAIAAIAAAAAAAAAAQAAB779/gAADDv9nP1tC/4AAQAAAAAAAAAAAAAAAAAAA9MAAQAAA+EAWAAHAAAAAAACAAAAAQABAAAAQAAAAAAAAAAEBN0B9AAFAAAFMwTNAAAAmgUzBM0AAALNAGYCkQAAAAAGAAAAAAAAACAAAAcAAAABAAAAAAAAAABVTEEgAMAADfsCB779/gAACaQCuCAAAZMAAAAAAhcCvAAAACAABgSyAFIAAAAAAqoAAAAAAAACZgAAAmYAAAHGAHEDEAB7BdIAMQUGAC8H5wBMBVoAcwHAAHsCmwCWAsoAzwLZADMEAgBIAcQARgL1AHkBzABaArL/zQTvAFYE7wDTBO8ASgTvACUE7wBEBO8APwTvAF4E7wBcBO8ATgTvAEwBzABaAcgARgQCAEgEAgBIBAIARgObAAgHqQA/Bfn//gWsALAFkQA/Bi8AsAVJALAEqQCwBfkAPwZRALACcgCwBBL/+gXOALAEUwCwB14AsAZRALAGeAA/BWYAsAaHAD8FyACwBQYALwS0ABAGGACTBZsABAhiAAQFoQAbBTH//gVYAEgCzACwBCgAyQOyARcEYAA/BJEAAALMAGoEuABMBXIAsASDAEIFdgBCBLwAQgLXAEgFIgBCBWAAsAJTAJwCXv9QBNcAsAJqALAIUwCmBVMApgUGAEIFcgCwBXYAQgM5AKYD2wApA1EANwU/AIMES//+Bz3//gSLABcEWv/yBFMAVgKwAEICNwC2AzEA5QQCAIMCZgAAAcYAcwTMAEIEaABIBakAQgUzAAACNwC2BBYAKQMOAEgF6wA/AxgAOwPAACUEhwBIAvUAeQXrAD8CzABaAtQApgQCAEgDFAAzAt0AFALMAHUFagCwBQD//AHCAFoCzACYAh4AHwNFADcD1ACDBqwAHwbbAB8HKwAUA5sAPQX5//4F+f/+Bfn//gX5//4F+f/+Bfn//giF//4FkQA/BUkAsAVJALAFSQCwBUkAsAJy/+UCcgCmAnL/7AJy//wGXgAABlEAsAZ4AD8GeAA/BngAPwZ4AD8GeAA/BAIAiwZ4AD8GGACTBhgAkwYYAJMGGACTBTH//gVyALAFPwCWBLgATAS4AEwEuABMBLgATAS4AEwEuABMB8gATASDAEIEvABCBLwAQgS8AEIEvABCAlP/1wJTAJgCU//dAlP/7gTAAEQFUwCmBQYAQgUGAEIFBgBCBQYAQgUGAEIEAgBIBQYAQgU/AIMFPwCDBT8AgwU/AIMEWv/yBXIAsARa//IF+f/+BLgATAX5//4EuABMBfn//gTAAEwFkQA/BIMAQgWRAD8EgwBCBZEAPwSDAEIFkQA/BIMAQgYvALAGJABCBl4AAAV4AEIFSQCwBLwAQgVJALAEvABCBUkAsAS8AEIFWgCwBLwAQgVJALAEvABCBfkAPwUiAEIF+QA/BSIAQgX5AD8FIgBCBfkAPwUiAEIGUQCwBWD/4wbXAD0FYAAGAnL/5wJT/9kCcgArAlMAHwJyAAwCU//+AnIAnAIvAHkCcgCqAlMApgaFALAEsgCcBBL/+gJD/0YFzgCwBNcAsATKAKYEUwCoAmoApARTALACagCcBFMAsAMYALAEUwCwAv0AsARa//QCsP/2BlEAsAVTAKYGUQCwBVMApgZRALAFUwCmBjsALwZRALAFUwCmBngAPwUGAEIGeAA/BQYAQgZ4AD8FBgBCCM4APwhHAEIFyACwAzkApgXIALADOQCLBcgAsAM5AIEFBgAvA9sAKQUGAC8D2wApBQYALwPbACkFBgAvA9sAKQS0ABADUQA3BLQAEANaADcEtAAQA1EANwYYAJMFPwCDBhgAkwU/AIMGGACTBT8AgwYYAJMFPwCDBhgAkwU/AIMGGgCWBTMAgwhiAAQHPf/+BTH//gRa//IFMf/+BVgASARTAFYFWABIBFMAVgVYAEgEUwBWBkMAOwMO/xAGeAA/BQYAQgYYAJMFPwCDC4cAsAqDALAJygBCCGYAsAayALAEyACwCmQAsAiwALAHsgCmBfkAPwUiAEIGeAA/BQYAQgX5//4EuABMCIX//gfIAEwGeAA/BQYAQgX5//4EuABMBfn//gS4AEwFSQCwBLwAQgVJALAEvABCAnL/fwJT/3ECcgAMAlP//gZ4AD8FBgBCBngAPwUGAEIFyACwAzkAMQXIALADOQCmBhgAkwU/AIMGGACTBT8AgwUGAC8D2wApBLQAEANRADcGeAA/BQYAQgZ4AD8FBgBCBngAPwUGAEIFMf/+BFr/8gJD/0YEvAAtAAD/FAF8AC8CzAFmAswAcwLMABkCzAACAQ4AKQLMAFoCzAB1AswAagEOACkCzAA5AswA1wLMAHUCzACwAswAFALM//IAAP7LAAD/fQAA/rIAAP6uAAD+8gAA/tMAAP9xAAD+wQAA/xkAAP8OAAD+iwAA/pwAAP5GAAD+0wAA/30AAAAAAAD/cQAA/sEAAP9kAAD/BAAA/0YAAP7TAAD+8gAA/ZwF+f/+BwAAEAVqALAFzv/lBZEAPwSDAEIGLwCwBXYAQgYvALAFdgBCBUkAsAS8AEIFSQCwBLwAQgVJALAEvABCBfkAPwUiAEIGUQCwBWAAsAZRALAFYACwAnL/+gJT/+wEUwCwAmoAqARTALACagApB14AsAhTAKYGUQCwBVMApgZRALAFUwCmBlEAsAVTAKYGeAA/BQYAQgZ4AD8FBgBCBngAPwUGAEIGeAA/BQYAQgXIALADOQCYBcgAsAM5ABkFBgAvA9sAKQUGAC8D2wApBQYALwPbACkFBgAvA9sAKQUGAC8D2wApBLQAEANRADcEtAAQA1EANwYYAJMFPwCDBhgAkwU/AIMIYgAEBz3//ghiAAQHPf/+CGIABAc9//4FMf/+BFr/8gVYAEgEUwBWA1EAGQV8AJYF+f/+BLgATAX5//4EuABMBfn//gS4AEwF+f/+BLgATAX5//4EuABMBfn//gS4AEwF+f/+BLgATAX5//4EuABMBfn//gS4AEwF+f/+BLgATAX5//4EuABMBfn//gS4AEwFSQCwBLwAQgVJALAEvABCBUkAsAS8AEIFSQCwBLwAQgVJALAEvABCBUkAsAS8AEIFSQCwBLwAQgVJALAEvABCAnIAVAJTAEYCcgCqAlMAnAZ4AD8FBgBCBngAPwUGAEIGeAA/BQYAQgZ4AD8FBgBCBngAPwUGAEIGeAA/BQYAQgZ4AD8FBgBCBngAPwUGAEIGeAA/BQYAQgZ4AD8FBgBCBngAPwUGAEIGeAA/BQYAQgYYAJMFPwCDBhgAkwU/AIMGGACTBT8AgwYYAJMFPwCDBhgAkwU/AIMGGACTBT8AgwYYAJMFPwCDBTH//gRa//IFMf/+BFr/8gUx//4EWv/yBTH//gRa//IE7wAAAcwAAAGZAAAAzAAAAAAAAAL1AHkE7wAAAz8AAAVuAAAFbgAAAcQARgHEAEYBxABGAwoARgMKAEYDCgBGBF4AIQReACECWABaBQYAWgt+AEwBtgBSAxIAUgI3ACUCTQCDALj9ywOXAEwDMQA1AwoAKwM7AEwDBgA9A0UARAM7ADsDlwBMAh4AHwMUADMC3QAUAzEANQMKACsDOwBMAwYAPQNFAEQDOwA7BZEAPwS0AB8EaABIBiAAKQw7ALAH+wACBXgAQgZPAEgFbgAhBgIAKQXMAD8FkQA/BLoAPwWNAD0GAAA7BXIAIwPAACsJpwCwByD/9AcAABAGeACPBswAHwdLABQHbgArBy0APQTtAEYD8wAABYUAAAX7ALAE5QA/BAIASAKy/80CWABaBY0AEAbzAEIC1//pBAIAgwQCAEgEAgBIBAIARgQ5AEIFKwBIBVgASAYeAJMGHgCTBh4AkwYeAJMGHgCTBh4AkwYeAJMGHgCTBh4AkwYeAJMGHgCTBh4AkwYeAJMGHgCTBh4AkwYeAJMGHgCTBh4AkwYeAJMGHgCTBh4AkwYtAJMGHgCTBh4AkwYeAJMLhwCwCoMAsASyAE4EsgBOBLIATgSyAE4EsgBOBLIATgSyAE4EsgBOBLIATgSyAE4EsgBOBLIATgSyAE4EsgBOBLIATgSyAE4EsgBOBLIATgSyAE4EsgBOBLIATgS4AFQEsgBOBE8AkwX7AD8F+wA/BfsAPwX7AD8F+wA/BfsAPwX7AD8D6wBkB/0AZAPrAGQFPwACB/0AZAPrAGQD6wBkA+sAOwPrAGQD6wBkA+sAZAPrAGQD6wBkA+sAZAPrAGQD6wBkA+sAZAPrAGQEEv/6BBL/+ghmALAJhQCwCYUAsAYkALAKNwCwBiQAsAYkALAGJACwBiQAsAYkALAGJgCwCIMAsAYkALAGJACwBngAPwYeADMFSQAzBUkAMwVJADMFSQAzBUkAMwVJADMFSQAzBiQAkQYkAJEGJACRBiQAkQYkAJEGJACRBiQAkQYkAJEGJACRBiQAkQYkAJEGJACRBiQAkQYkAJEGJACRBiQAkQYkAJEGJACRBiQAkQYkAJEGJACRBiQAkQYkAJEJZgCTCWYAkwlmAJMJZgCTCWYAkwXrAJMF6wCTBesAkwXrAJMF6wCTBesAkwXrAJMF6wCTBesAkwXrAJMFWABIBVgASAVYAEgFWABIBVgASAVoAEIFaABCBWgAQgVoAEIFaABCBWgAQgVoAEIFaABCBWgAQgVoAEIFaABCBWgAQgVoAEIFaABCBWgAQgVoAEIFaABCBWgAQgVoAEIFaABCBWgAQgVoAEIFaABCBWgAQgVoAEIHuABMB7gATAnKAEIErABCBKwAQgSsAEIErABCBKwAQgSsAEIErABCBKwAQgSsAEIErABCBKwAQgSsAEIErABCBKwAQgSsAEIErABCBKwAQgSsAEIErABCBKwAQgSsAEIEzgBCBKwAQgSsADMCkQCTBKcAlgJTAJwCiwCTAosAhQMOAJMCiwCTAt8AkwKLAJME6QCTAosAOwLG//YIIgBCAwoAiwMKAIsDEgCLAwoAiwMKAIsDCv/RAwoAiwMKAIsHyACBB8gAgQfIAIEHyACBB8gAgQU9AIMFPQCDBT0AgwU9AIMFPQCDBT0AgwU9AIMFPQCDBT0AgwRTAFYEUwBWBFMAVgRTAFYEUwBWCAwASAeLAJMKYABICdQAkwg5AEgHsACTB4kASAdDAJME+QCTBXYASAWNAGADJgAXBLoAPQRaAAQE3QA7BKcALQT1AF4EnQBIBQoAVAUAAFAFjQBgAyYAFwRiAD0EWgAEBN0AOwSnAC8E9QBeBJ0ASgUKAFQE9QBQBO8ASATvAOkE7wBgBO8AJQTvAEQE7wA/BO8AXgTvAFwE7wBOBO8ATAOXAEwCHgAfAxQAMwLdABQDMQA1AwoAKwM7AEwDBgA9A0UARAM7ADsDlwBMAh4AHwMUADMC3QAUAzEANQMKACsDOwBMAwYAPQNFAEQDOwA7ATcAFAAAAAD/ff8n/sH+4/9xAAD+4/6W/uP+uv7B/sH+wf62AAAAAwAAAAMAAAAcAAEAAAAAA0QAAwABAAAAHAAEAygAAADGAIAABgBGAAAADQB+AX4BjwGSAaEBsAHMAecB6wIbAi0CMwI3AlkCvAK/AswC3QME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NREhERQWMz4BNwRGARL+qv7uqP66YH1N8HGm00bXher+2QETs46RwA4FmvvO/v7+wX1kxU1jvZWuanUBASzxAkD924qwAcGbAAIAk/8nBVgHZgADACMAAAEHIxMBIREQACEiJCc3HgEzMjY9AQ4BByIANREhERQWMz4BNwRC/uLZAQsBEv6q/u6o/rpgfU3wcabTRteF6v7ZAROzjpHADgb+0wE7/jT7zv7+/sF9ZMVNY72Vrmp1AQEs8QJA/duKsAHBmwACAJP/JwVYB1wABgAmAAABByMTMxMjFyEREAAhIiQnNx4BMzI2PQEOAQciADURIREUFjM+ATcC9n3R2ena0dMBEv6q/u6o/rpgfU3wcabTRteF6v7ZAROzjpHADgbnsgEn/tmb+87+/v7BfWTFTWO9la5qdQEBLPECQP3birABwZsAAAADAJP/JwVYB1oACwAXADcAAAEiJjU0NjMyFhUUBiEiJjU0NjMyFhUUBhchERAAISIkJzceATMyNj0BDgEHIgA1ESERFBYzPgE3Aj06S0o7OkxNATw6TUw7OE1NXAES/qr+7qj+umB9TfBxptNG14Xq/tkBE7OOkcAOBkZOOz1OTj06T047PU5OPTpPrPvO/v7+wX1kxU1jvZWuanUBASzxAkD924qwAcGbAAAAAgCT/ycFWAdkAAgAKAAAACImNTQ2MhYUFyEREAAhIiQnNx4BMzI2PQEOAQciADURIREUFjM+ATcDNX5RUX5QwQES/qr+7qj+umB9TfBxptNG14Xq/tkBE7OOkcAOBj1TQUBTUoL2+87+/v7BfWTFTWO9la5qdQEBLPECQP3birABwZsAAgCT/a4FWAWaAB8AKQAAASEREAAhIiQnNx4BMzI2PQEOAQciADURIREUFjM+ATcBMhYUBiImJzQ2BEYBEv6q/u6o/rpgfU3wcabTRteF6v7ZAROzjpHADv7APlJSfE8CUAWa+87+/v7BfWTFTWO9la5qdQEBLPECQP3birABwZv7OVN+UlFAP1MAAAACAJP/JwVYB2gAAwAjAAABIyclASEREAAhIiQnNx4BMzI2PQEOAQciADURIREUFjM+ATcDgeH+AQYBngES/qr+7qj+umB9TfBxptNG14Xq/tkBE7OOkcAOBi3TaP4y+87+/v7BfWTFTWO9la5qdQEBLPECQP3birABwZsAAgCT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ASMiBgceAQO2KjIGdw13WV5xPj92Ozks/tJ5xtHd0ceRAQv+9Xr06v7gARrm+33+y4CpDAypgIitAgKrBqwvKSlPWWpTPmM2Jy9MKyIs/t+qARf+6Zn7uK66ATj7+AEyAQO9/TuihU6ForuTlLoAAAAEAEL/9ATFBy8AEwAaACkANgAAASIGFSMQMzIeATMyNTMQIyIuAgczEyMnByMFIREhNQYjIgA1NAA3NhcBMjY3NS4BIyIGBx4BAkgiJJy5L1hHGUibuChJLTUc3dHHeXnGAkkBC/71evTq/uABGub7ff7LgKkMDKmAiK0CAqsGhS8rAQQ0NFz+/h8mH43+6aqqmfu4rroBOPv4ATIBA739O6KFToWiu5OUugAABABC//QExQYhAAMABwAWACMAAAEjJzcBIyc3EyERITUGIyIANTQANzYXATI2NzUuASMiBgceAQJ9y7zdAgzLvN2FAQv+9Xr06v7gARrm+33+y4CpDAypgIitAgKrBNnqXv646l7+J/u4rroBOPv4ATIBA739O6KFToWiu5OUugAEAEL/9ATFBggACwAXACYAMwAAASImNTQ2MzIWFRQGISImNTQ2MzIWFRQGFyERITUGIyIANTQANzYXATI2NzUuASMiBgceAQH4OktKOzlMTAE8Ok5NOzhNTRUBC/71evTq/uABGub7ff7LgKkMDKmAiK0CAqsE9E47PU5OPTtOTjs9Tk49Ok+s+7iuugE4+/gBMgEDvf07ooVOhaK7k5S6AAAAAAMAQv5xBMUEVQAOABsAJQAAASERITUGIyIANTQANzYXATI2NzUuASMiBgceARMyFhQGIiYnNDYDugEL/vV69Or+4AEa5vt9/suAqQwMqYCIrQICq68+UVF8TwJQBEj7uK66ATj7+AEyAQO9/TuihU6ForuTlLr+wFJ+UlFAP1IAAwBC//QExQYXAAMAEgAfAAABIyclASERITUGIyIANTQANzYXATI2NzUuASMiBgceAQM74f4BBgFYAQv+9Xr06v7gARrm+33+y4CpDAypgIitAgKrBNvTaf4x+7iuugE4+/gBMgEDvf07ooVOhaK7k5S6AAADAEL/9ATFBj8AEwAiAC8AAAEiBgcnPgEzMhYVFAYHJz4BNTQmEyERITUGIyIANTQANzYXATI2NzUuASMiBgceAQKsKzQFfQ17W2F2QD97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AAL+ugTXAT0HLwAUACAAAAEQIyIuAiMiBhUjEDMyHgIzMjUBHgEyNjczDgEiJicBPbYoSi01FSIknrslSC42Fkb+5QNDZkMDpASf9J8EByP+/iAmIDAsAQQgJiBa/ss2RUU2fZqafQAAAv7BBOECkwbTAAMACgAAARcHIyUzEyMnByMButnzt/6o3tDGeXnGBtNixUz+6aqqAAAAAAL+wQThAe4G0wADAAoAAAETIycHMxMjJwcjARvTt/Wx3tDGeXnGBtP+2cV5/umqqgAAAAAC/sEE4QHZByUAEwAaAAATPgEzMhYVFAYHJz4BNTQmIyIGBwUzEyMnByMtDXdZXnE+P3c7OiwoKjIG/u3e0MZ5ecYGfU9ZalM+YzYnL0wrIiwvKVz+6aqqAAAAAAL+tgThAT8HLwATABoAAAEQIyIuAiMiBhUjEDMyHgEzMjUBMxMjJwcjATm4KEktNRYiJJy5L1hHGUj+897Qxnl5xgcj/v4fJh8vKwEENDRc/tX+6aqqAAAAAB4BbgABAAAAAAAAAFIApgABAAAAAAABABEBHQABAAAAAAACAAcBPwABAAAAAAADABwBgQABAAAAAAAEABEBwgABAAAAAAAFADwCTgABAAAAAAAGABECrwABAAAAAAAIABEC5QABAAAAAAAJABEDGwABAAAAAAALABkDYQABAAAAAAAMABkDrwABAAAAAAANAJAE6wABAAAAAAAOABoFsgABAAAAAAAQAAoF4wABAAAAAAARAAYF/AADAAEECQAAAKQAAAADAAEECQABACIA+QADAAEECQACAA4BLwADAAEECQADADgBRwADAAEECQAEACIBngADAAEECQAFAHgB1AADAAEECQAGACICiwADAAEECQAIACICwQADAAEECQAJACIC9wADAAEECQALADIDLQADAAEECQAMADIDewADAAEECQANASADyQADAAEECQAOADQFfAADAAEECQAQABQFzQADAAEECQARAAwF7gBDAG8AcAB5AHIAaQBnAGgAdAAgADIAMAAxADEAIAAtACAAMgAwADEANgAgAFQAaABlACAATQBvAG4AdABzAGUAcgByAGEAdAAgAFAAcgBvAGoAZQBjAHQAIABBAHUAdABoAG8AcgBzACAAKABqAHUAbABpAGUAdABhAC4AdQBsAGEAbgBvAHYAcwBrAHkAQABn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AH0AfAC4AKEAfwB+AIAAgQDsAO4AugEKAQsBDAENAQ4BDwD9AP4BEAERARIBEwD/AQABFAEVARYBAQEXARgBGQEaARsBHAEdAR4BHwEgASEBIgD4APkBIwEkASUBJgEnASgBKQEqASsBLAEtAS4BLwEwATEBMgD6ANcBMwE0ATUBNgE3ATgBOQE6ATsBPAE9AT4BPwFAAUEA4gDjAUIBQwFEAUUBRgFHAUgBSQFKAUsBTAFNAU4BTwFQALAAsQFRAVIBUwFUAVUBVgFXAVgBWQFaAPsA/ADkAOUBWwFcAV0BXgFfAWABYQFiAWMBZAFlAWYBZwFoAWkBagFrAWwBbQFuAW8BcAC7AXEBcgFzAXQA5gDnAXUApgF2AXcBeAF5AXoBewF8AX0BfgF/AYABgQGCAYMBhAGFAYYBhwGIAYkBigGLAYwBjQGOAY8BkAGRAZIBkwGUAZUBlgGXAZgBmQGaAZsBnAGdAZ4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYA2ADhAbcBuAG5AboBuwDbANwA3QDgANkA3wG8Ab0BvgG/AcABwQHCAcMBxAHFAcYBxwHIAckBygHLAcwBzQHOAc8B0AHRAdIB0wHUAdUB1gCbAdcB2AHZAdoB2wHcAd0B3gHfAeAB4QHiAeMB5AHlAeYB5wHoAekB6gHrAewB7QHuAe8B8AHxAfIB8wH0AfUB9gH3AfgB+QH6AfsB/AH9Af4B/wIAAgECAgIDAgQCBQIGAgcCCAIJAgoCCwIMAg0CDgIPAhACEQISAhMCFAIVAhYCFwIYAhkCGgIbAhwCHQIeAh8CIAIhAiICIwIkAiUCJgInAigCKQIqAisCLAItAi4CLwIwAjECMgIzAjQCNQI2AjcCOAI5AjoCOwI8Aj0CPgI/AkACQQJCAkMCRAJFAkYCRwJIAkkCSgJLAkwCTQJOAk8CUAJRAlICUwJUAlUCVgJXAlgCWQJaAlsCXAJdAl4CXwJgAmECYgJjAmQCZQJmAmcCaAJpAmoCawJsAm0CbgJvAnACcQJyAnMCdAJ1AnYCdwJ4AnkCegJ7AnwCfQJ+An8CgAKBALIAswKCALYAtwDEALQAtQDFAIIAwgCHAKsAxgKDAoQAvgC/ALwChQKGAocCiAKJAooCiwKMAo0CjgKPApACkQKSApMClAKVApYA9wKXApgCmQKaApsCnAKdAp4CnwKgAqECogKjAqQCpQKmAIwCpwKoAqkCqgKrAqwAmAKtAq4AmgCZAO8CrwKwAKUAkgCcAKcAjwCUAJUAuQDAAMECsQKyArMCtAK1ArYCtwK4ArkCugK7ArwCvQK+Ar8CwALBAsICwwLEAsUCxgLHAsgCyQLKAssCzALNAs4CzwLQAtEC0gLTAtQC1QLWAtcC2ALZAtoC2wLcAt0C3gLfAuAC4QLiAuMC5ALlAuYC5wLoAukC6gLrAuwC7QLuAu8C8ALxAvIC8wL0AvUC9gL3AvgC+QL6AvsC/AL9Av4C/wMAAwEDAgMDAwQDBQMGAwcDCAMJAwoDCwMMAw0DDgMPAxADEQMSAxMDFAMVAxYDFwMYAxkDGgMbAxwDHQMeAx8DIAMhAyIDIwMkAyUDJgMnAygDKQMqAysDLAMtAy4DLwMwAzEDMgMzAzQDNQM2AzcDOAM5AzoDOwM8Az0DPgM/A0ADQQNCA0MDRANFA0YDRwNIA0kDSgNLA0wDTQNOA08DUANRA1IDUwNUA1UDVgNXA1gDWQNaA1sDXANdA14DXwNgA2EDYgNjA2QDZQNmA2cDaANpA2oDawNsA20DbgNvA3ADcQNyA3MDdAN1A3YDdwN4A3kDegN7A3wDfQN+A38DgAOBA4IDgwOEA4UDhgOHA4gDiQOKA4sDjAONA44DjwOQA5EDkgOTA5QDlQOWA5cDmAOZA5oDmwOcA50DngOfA6ADoQOiA6MDpAOlA6YDpwOoA6kDqgOrA6wDrQOuA68DsAOxA7IDswO0A7UDtgO3A7gDuQO6A7sDvAO9A74DvwPAA8EDwgPDA8QDxQPGA8cDyAPJA8oDywPMA80DzgPPA9AD0QPSA9MD1APVA9YD1wPYA9kD2gPbA9wD3QPeA98D4APhA+ID4wPkA+UD5gPnA+gETlVMTAJDUgd1bmkwMEEwB3VuaTAwQUQHdW5pMDBCMgd1bmkwMEIzB3VuaTAwQjUHdW5pMDBCOQdBbWFjcm9uB2FtYWNyb24GQWJyZXZlBmFicmV2ZQdBb2dvbmVrB2FvZ29uZWsLQ2NpcmN1bWZsZXgLY2NpcmN1bWZsZXgKQ2RvdGFjY2VudApjZG90YWNjZW50BkRjYXJvbgZkY2Fyb24GRGNyb2F0B0VtYWNyb24HZW1hY3JvbgZFYnJldmUGZWJyZXZlCkVkb3RhY2NlbnQKZWRvdGFjY2VudAdFb2dvbmVrB2VvZ29uZWsGRWNhcm9uBmVjYXJvbgtHY2lyY3VtZmxleAtnY2lyY3VtZmxleApHZG90YWNjZW50Cmdkb3RhY2NlbnQMR2NvbW1hYWNjZW50DGdjb21tYWFjY2VudAtIY2lyY3VtZmxleAtoY2lyY3VtZmxleARIYmFyBGhiYXIGSXRpbGRlBml0aWxkZQdJbWFjcm9uB2ltYWNyb24GSWJyZXZlBmlicmV2ZQdJb2dvbmVrB2lvZ29uZWsCSUoCaWoLSmNpcmN1bWZsZXgLamNpcmN1bWZsZXgMS2NvbW1hYWNjZW50DGtjb21tYWFjY2VudAxrZ3JlZW5sYW5kaWMGTGFjdXRlBmxhY3V0ZQxMY29tbWFhY2NlbnQMbGNvbW1hYWNjZW50BkxjYXJvbgZsY2Fyb24ETGRvdARsZG90Bk5hY3V0ZQZuYWN1dGUMTmNvbW1hYWNjZW50DG5jb21tYWFjY2VudAZOY2Fyb24GbmNhcm9uC25hcG9zdHJvcGhlA0VuZwNlbmcHT21hY3JvbgdvbWFjcm9uBk9icmV2ZQZvYnJldmUNT2h1bmdhcnVtbGF1dA1vaHVuZ2FydW1sYXV0BlJhY3V0ZQZyYWN1dGUMUmNvbW1hYWNjZW50DHJjb21tYWFjY2VudAZSY2Fyb24GcmNhcm9uBlNhY3V0ZQZzYWN1dGULU2NpcmN1bWZsZXgLc2NpcmN1bWZsZXgHdW5pMDE2Mgd1bmkwMTYzBlRjYXJvbgZ0Y2Fyb24EVGJhcgR0YmFyBlV0aWxkZQZ1dGlsZGUHVW1hY3Jvbgd1bWFjcm9uBlVicmV2ZQZ1YnJldmUFVXJpbmcFdXJpbmcNVWh1bmdhcnVtbGF1dA11aHVuZ2FydW1sYXV0B1VvZ29uZWsHdW9nb25lawtXY2lyY3VtZmxleAt3Y2lyY3VtZmxleAtZY2lyY3VtZmxleAt5Y2lyY3VtZmxleAZaYWN1dGUGemFjdXRlClpkb3RhY2NlbnQKemRvdGFjY2VudAd1bmkwMThGBU9ob3JuBW9ob3JuBVVob3JuBXVob3JuB3VuaTAxQzQHdW5pMDFDNQd1bmkwMUM2B3VuaTAxQzcHdW5pMDFDOAd1bmkwMUM5B3VuaTAxQ0EHdW5pMDFDQgd1bmkwMUNDBkdjYXJvbgZnY2Fyb24HdW5pMDFFQQd1bmkwMUVCCkFyaW5nYWN1dGUKYXJpbmdhY3V0ZQdBRWFjdXRlB2FlYWN1dGULT3NsYXNoYWN1dGULb3NsYXNoYWN1dGUHdW5pMDIwMAd1bmkwMjAxB3VuaTAyMDIHdW5pMDIwMwd1bmkwMjA0B3VuaTAyMDUHdW5pMDIwNgd1bmkwMjA3B3VuaTAyMDgHdW5pMDIwOQd1bmkwMjBBB3VuaTAyMEIHdW5pMDIwQwd1bmkwMjBEB3VuaTAyMEUHdW5pMDIwRgd1bmkwMjEwB3VuaTAyMTEHdW5pMDIxMgd1bmkwMjEzB3VuaTAyMTQHdW5pMDIxNQd1bmkwMjE2B3VuaTAyMTcMU2NvbW1hYWNjZW50DHNjb21tYWFjY2VudAd1bmkwMjFBB3VuaTAyMUIHdW5pMDIyQQd1bmkwMjJCB3VuaTAyMkMHdW5pMDIyRAd1bmkwMjMwB3VuaTAyMzEHdW5pMDIzMgd1bmkwMjMzB3VuaTAyMzcHdW5pMDI1OQd1bmkwMkJCB3VuaTAyQkMHdW5pMDJCRQd1bmkwMkJGB3VuaTAyQzgHdW5pMDJDOQd1bmkwMkNBB3VuaTAyQ0IHdW5pMDJDQwlncmF2ZWNvbWIJYWN1dGVjb21iB3VuaTAzMDIJdGlsZGVjb21iB3VuaTAzMDQHdW5pMDMwNgd1bmkwMzA3B3VuaTAzMDgNaG9va2Fib3ZlY29tYgd1bmkwMzBBB3VuaTAzMEIHdW5pMDMwQwd1bmkwMzBGB3VuaTAzMTEHdW5pMDMxMgd1bmkwMzFCDGRvdGJlbG93Y29tYgd1bmkwMzI0B3VuaTAzMjYHdW5pMDMyNwd1bmkwMzI4B3VuaTAzMkUHdW5pMDMzMQd1bmkwMzM1B3VuaTAzOTQHdW5pMDNBOQd1bmkwM0JDB3VuaTFFMDgHdW5pMUUwOQd1bmkxRTBDB3VuaTFFMEQHdW5pMUUwRQd1bmkxRTBGB3VuaTFFMTQHdW5pMUUxNQd1bmkxRTE2B3VuaTFFMTcHdW5pMUUxQwd1bmkxRTFEB3VuaTFFMjAHdW5pMUUyMQd1bmkxRTI0B3VuaTFFMjUHdW5pMUUyQQd1bmkxRTJCB3VuaTFFMkUHdW5pMUUyRgd1bmkxRTM2B3VuaTFFMzcHdW5pMUUzQQd1bmkxRTNCB3VuaTFFNDIHdW5pMUU0Mwd1bmkxRTQ0B3VuaTFFNDUHdW5pMUU0Ngd1bmkxRTQ3B3VuaTFFNDgHdW5pMUU0OQd1bmkxRTRDB3VuaTFFNEQHdW5pMUU0RQd1bmkxRTRGB3VuaTFFNTAHdW5pMUU1MQd1bmkxRTUyB3VuaTFFNTMHdW5pMUU1QQd1bmkxRTVCB3VuaTFFNUUHdW5pMUU1Rgd1bmkxRTYwB3VuaTFFNjEHdW5pMUU2Mgd1bmkxRTYzB3VuaTFFNjQHdW5pMUU2NQd1bmkxRTY2B3VuaTFFNjcHdW5pMUU2OAd1bmkxRTY5B3VuaTFFNkMHdW5pMUU2RAd1bmkxRTZFB3VuaTFFNkYHdW5pMUU3OAd1bmkxRTc5B3VuaTFFN0EHdW5pMUU3QgZXZ3JhdmUGd2dyYXZlBldhY3V0ZQZ3YWN1dGUJV2RpZXJlc2lzCXdkaWVyZXNpcwd1bmkxRThFB3VuaTFFOEYHdW5pMUU5Mgd1bmkxRTkzB3VuaTFFOTcHdW5pMUU5RQd1bmkxRUEwB3VuaTFFQTEHdW5pMUVBMgd1bmkxRUEzB3VuaTFFQTQHdW5pMUVBNQd1bmkxRUE2B3VuaTFFQTcHdW5pMUVBOAd1bmkxRUE5B3VuaTFFQUEHdW5pMUVBQgd1bmkxRUFDB3VuaTFFQUQHdW5pMUVBRQd1bmkxRUFGB3VuaTFFQjAHdW5pMUVCMQd1bmkxRUIyB3VuaTFFQjMHdW5pMUVCNAd1bmkxRUI1B3VuaTFFQjYHdW5pMUVCNwd1bmkxRUI4B3VuaTFFQjkHdW5pMUVCQQd1bmkxRUJCB3VuaTFFQkMHdW5pMUVCRAd1bmkxRUJFB3VuaTFFQkYHdW5pMUVDMAd1bmkxRUMxB3VuaTFFQzIHdW5pMUVDMwd1bmkxRUM0B3VuaTFFQzUHdW5pMUVDNgd1bmkxRUM3B3VuaTFFQzgHdW5pMUVDOQd1bmkxRUNBB3VuaTFFQ0IHdW5pMUVDQwd1bmkxRUNEB3VuaTFFQ0UHdW5pMUVDRgd1bmkxRUQwB3VuaTFFRDEHdW5pMUVEMgd1bmkxRUQzB3VuaTFFRDQHdW5pMUVENQd1bmkxRUQ2B3VuaTFFRDcHdW5pMUVEOAd1bmkxRUQ5B3VuaTFFREEHdW5pMUVEQgd1bmkxRURDB3VuaTFFREQHdW5pMUVERQd1bmkxRURGB3VuaTFFRTAHdW5pMUVFMQd1bmkxRUUyB3VuaTFFRTMHdW5pMUVFNAd1bmkxRUU1B3VuaTFFRTYHdW5pMUVFNwd1bmkxRUU4B3VuaTFFRTkHdW5pMUVFQQd1bmkxRUVCB3VuaTFFRUMHdW5pMUVFRAd1bmkxRUVFB3VuaTFFRUYHdW5pMUVGMAd1bmkxRUYxBllncmF2ZQZ5Z3JhdmUHdW5pMUVGNAd1bmkxRUY1B3VuaTFFRjYHdW5pMUVGNwd1bmkxRUY4B3VuaTFFRjkHdW5pMjAwNwd1bmkyMDA4B3VuaTIwMDkHdW5pMjAwQQd1bmkyMDBCB3VuaTIwMTAKZmlndXJlZGFzaAd1bmkyMDE1Bm1pbnV0ZQZzZWNvbmQHdW5pMjA3MAd1bmkyMDc0B3VuaTIwNzUHdW5pMjA3Ngd1bmkyMDc3B3VuaTIwNzgHdW5pMjA3OQd1bmkyMDgwB3VuaTIwODEHdW5pMjA4Mgd1bmkyMDgzB3VuaTIwODQHdW5pMjA4NQd1bmkyMDg2B3VuaTIwODcHdW5pMjA4OAd1bmkyMDg5DWNvbG9ubW9uZXRhcnkEbGlyYQd1bmkyMEE2BnBlc2V0YQd1bmkyMEE5BGRvbmcERXVybwd1bmkyMEFEB3VuaTIwQjEHdW5pMjBCMgd1bmkyMEI1B3VuaTIwQjkHdW5pMjBCQQd1bmkyMEJDB3VuaTIwQkQHdW5pMjExMwd1bmkyMTE2B3VuaTIxMjYJZXN0aW1hdGVkCW9uZWVpZ2h0aAx0aHJlZWVpZ2h0aHMLZml2ZWVpZ2h0aHMMc2V2ZW5laWdodGhzCGVtcHR5c2V0B3VuaTIyMDYHdW5pMjIxNQd1bmkyMjE5BkEuc3MwMQtBYWN1dGUuc3MwMQtBYnJldmUuc3MwMQx1bmkxRUFFLnNzMDEMdW5pMUVCNi5zczAxDHVuaTFFQjAuc3MwMQx1bmkxRUIyLnNzMDEMdW5pMUVCNC5zczAxEEFjaXJjdW1mbGV4LnNzMDEMdW5pMUVBNC5zczAxDHVuaTFFQUMuc3MwMQx1bmkxRUE2LnNzMDEMdW5pMUVBOC5zczAxDHVuaTFFQUEuc3MwMQx1bmkwMjAwLnNzMDEOQWRpZXJlc2lzLnNzMDEMdW5pMUVBMC5zczAxC0FncmF2ZS5zczAxDHVuaTFFQTIuc3MwMQx1bmkwMjAyLnNzMDEMQW1hY3Jvbi5zczAxDEFvZ29uZWsuc3MwMQpBcmluZy5zczAxD0FyaW5nYWN1dGUuc3MwMQtBdGlsZGUuc3MwMQx1bmkwMUM0LnNzMDEMdW5pMDFDNS5zczAxBkUuc3MwMQtFYWN1dGUuc3MwMQtFYnJldmUuc3MwMQtFY2Fyb24uc3MwMQx1bmkxRTFDLnNzMDEQRWNpcmN1bWZsZXguc3MwMQx1bmkxRUJFLnNzMDEMdW5pMUVDNi5zczAxDHVuaTFFQzAuc3MwMQx1bmkxRUMyLnNzMDEMdW5pMUVDNC5zczAxDHVuaTAyMDQuc3MwMQ5FZGllcmVzaXMuc3MwMQ9FZG90YWNjZW50LnNzMDEMdW5pMUVCOC5zczAxC0VncmF2ZS5zczAxDHVuaTFFQkEuc3MwMQx1bmkwMjA2LnNzMDEMRW1hY3Jvbi5zczAxDHVuaTFFMTYuc3MwMQx1bmkxRTE0LnNzMDEMRW9nb25lay5zczAxDHVuaTFFQkMuc3MwMQZGLnNzMDEGRy5zczAxC0dicmV2ZS5zczAxC0djYXJvbi5zczAxEEdjaXJjdW1mbGV4LnNzMDERR2NvbW1hYWNjZW50LnNzMDEPR2RvdGFjY2VudC5zczAxDHVuaTFFMjAuc3MwMQZJLnNzMDEHSUouc3MwMQtJYWN1dGUuc3MwMRBJYWN1dGVfSi5sb2NsTkxEFUlhY3V0ZV9KLmxvY2xOTEQuc3MwMQtJYnJldmUuc3MwMRBJY2lyY3VtZmxleC5zczAxDHVuaTAyMDguc3MwMQ5JZGllcmVzaXMuc3MwMQx1bmkxRTJFLnNzMDEPSWRvdGFjY2VudC5zczAxDHVuaTFFQ0Euc3MwMQtJZ3JhdmUuc3MwMQx1bmkxRUM4LnNzMDEMdW5pMDIwQS5zczAxDEltYWNyb24uc3MwMQxJb2dvbmVrLnNzMDELSXRpbGRlLnNzMDEGSi5zczAxEEpjaXJjdW1mbGV4LnNzMDEMdW5pMDFDNy5zczAxBk0uc3MwMQx1bmkxRTQyLnNzMDEGTi5zczAxDHVuaTAxQ0Euc3MwMQtOYWN1dGUuc3MwMQtOY2Fyb24uc3MwMRFOY29tbWFhY2NlbnQuc3MwMQx1bmkxRTQ0LnNzMDEMdW5pMUU0Ni5zczAxCEVuZy5zczAxDHVuaTAxQ0Iuc3MwMQx1bmkxRTQ4LnNzMDELTnRpbGRlLnNzMDEGUS5zczAxDHVuaTAxOEYuc3MwMQZULnNzMDEJVGJhci5zczAxC1RjYXJvbi5zczAxDHVuaTAxNjIuc3MwMQx1bmkwMjFBLnNzMDEMdW5pMUU2Qy5zczAxDHVuaTFFNkUuc3MwMQZVLnNzMDELVWFjdXRlLnNzMDELVWJyZXZlLnNzMDEQVWNpcmN1bWZsZXguc3MwMQx1bmkwMjE0LnNzMDEOVWRpZXJlc2lzLnNzMDEMdW5pMUVFNC5zczAxC1VncmF2ZS5zczAxDHVuaTFFRTYuc3MwMQpVaG9ybi5zczAxDHVuaTFFRTguc3MwMQx1bmkxRUYwLnNzMDEMdW5pMUVFQS5zczAxDHVuaTFFRUMuc3MwMQx1bmkxRUVFLnNzMDESVWh1bmdhcnVtbGF1dC5zczAxDHVuaTAyMTYuc3MwMQxVbWFjcm9uLnNzMDEMdW5pMUU3QS5zczAxDFVvZ29uZWsuc3MwMQpVcmluZy5zczAxC1V0aWxkZS5zczAxDHVuaTFFNzguc3MwMQZXLnNzMDELV2FjdXRlLnNzMDEQV2NpcmN1bWZsZXguc3MwMQ5XZGllcmVzaXMuc3MwMQtXZ3JhdmUuc3MwMQZZLnNzMDELWWFjdXRlLnNzMDEQWWNpcmN1bWZsZXguc3MwMQ5ZZGllcmVzaXMuc3MwMQx1bmkxRThFLnNzMDEMdW5pMUVGNC5zczAxC1lncmF2ZS5zczAxDHVuaTFFRjYuc3MwMQx1bmkwMjMyLnNzMDEMdW5pMUVGOC5zczAxBlouc3MwMQtaYWN1dGUuc3MwMQtaY2Fyb24uc3MwMQ9aZG90YWNjZW50LnNzMDEMdW5pMUU5Mi5zczAxBmEuc3MwMQthYWN1dGUuc3MwMQthYnJldmUuc3MwMQx1bmkxRUFGLnNzMDEMdW5pMUVCNy5zczAxDHVuaTFFQjEuc3MwMQx1bmkxRUIzLnNzMDEMdW5pMUVCNS5zczAxEGFjaXJjdW1mbGV4LnNzMDEMdW5pMUVBNS5zczAxDHVuaTFFQUQuc3MwMQx1bmkxRUE3LnNzMDEMdW5pMUVBOS5zczAxDHVuaTFFQUIuc3MwMQx1bmkwMjAxLnNzMDEOYWRpZXJlc2lzLnNzMDEMdW5pMUVBMS5zczAxC2FncmF2ZS5zczAxDHVuaTFFQTMuc3MwMQx1bmkwMjAzLnNzMDEMYW1hY3Jvbi5zczAxDGFvZ29uZWsuc3MwMQphcmluZy5zczAxD2FyaW5nYWN1dGUuc3MwMQthdGlsZGUuc3MwMQdhZS5zczAxDGFlYWN1dGUuc3MwMQx1bmkwMUM2LnNzMDEGZS5zczAxC2VhY3V0ZS5zczAxC2VicmV2ZS5zczAxC2VjYXJvbi5zczAxDHVuaTFFMUQuc3MwMRBlY2lyY3VtZmxleC5zczAxDHVuaTFFQkYuc3MwMQx1bmkxRUM3LnNzMDEMdW5pMUVDMS5zczAxDHVuaTFFQzMuc3MwMQx1bmkxRUM1LnNzMDEMdW5pMDIwNS5zczAxDmVkaWVyZXNpcy5zczAxD2Vkb3RhY2NlbnQuc3MwMQx1bmkxRUI5LnNzMDELZWdyYXZlLnNzMDEMdW5pMUVCQi5zczAxDHVuaTAyMDcuc3MwMQxlbWFjcm9uLnNzMDEMdW5pMUUxNy5zczAxDHVuaTFFMTUuc3MwMQxlb2dvbmVrLnNzMDEMdW5pMUVCRC5zczAxDHVuaTAyNTkuc3MwMQZmLnNzMDEQaWFjdXRlX2oubG9jbE5MRAlpLmxvY2xUUksGbC5zczAxC2xhY3V0ZS5zczAxC2xjYXJvbi5zczAxEWxjb21tYWFjY2VudC5zczAxCWxkb3Quc3MwMQx1bmkxRTM3LnNzMDEMdW5pMDFDOS5zczAxDHVuaTFFM0Iuc3MwMQtsc2xhc2guc3MwMQdvZS5zczAxBnQuc3MwMQl0YmFyLnNzMDELdGNhcm9uLnNzMDEMdW5pMDE2My5zczAxDHVuaTAyMUIuc3MwMQx1bmkxRTk3LnNzMDEMdW5pMUU2RC5zczAxDHVuaTFFNkYuc3MwMQZ3LnNzMDELd2FjdXRlLnNzMDEQd2NpcmN1bWZsZXguc3MwMQ53ZGllcmVzaXMuc3MwMQt3Z3JhdmUuc3MwMQZ5LnNzMDELeWFjdXRlLnNzMDEQeWNpcmN1bWZsZXguc3MwMQ55ZGllcmVzaXMuc3MwMQx1bmkxRUY1LnNzMDELeWdyYXZlLnNzMDEMdW5pMUVGNy5zczAxDHVuaTAyMzMuc3MwMQx1bmkxRUY5LnNzMDEGei5zczAxC3phY3V0ZS5zczAxC3pjYXJvbi5zczAxD3pkb3RhY2NlbnQuc3MwMQx1bmkxRTkzLnNzMDEFZl9mX2kKZl9mX2kuc3MwMQZmX2ZfaWoLZl9mX2lqLnNzMDEFZl9mX2wKZl9mX2wuc3MwMQRmX2lqCWZfaWouc3MwMQdmaS5zczAxB2ZsLnNzMDEHemVyby5sZgZvbmUubGYGdHdvLmxmCHRocmVlLmxmB2ZvdXIubGYHZml2ZS5sZgZzaXgubGYIc2V2ZW4ubGYIZWlnaHQubGYHbmluZS5sZgh6ZXJvLm9zZgdvbmUub3NmB3R3by5vc2YJdGhyZWUub3NmCGZvdXIub3NmCGZpdmUub3NmB3NpeC5vc2YJc2V2ZW4ub3NmCWVpZ2h0Lm9zZghuaW5lLm9zZgl6ZXJvLnRvc2YIb25lLnRvc2YIdHdvLnRvc2YKdGhyZWUudG9zZglmb3VyLnRvc2YJZml2ZS50b3NmCHNpeC50b3NmCnNldmVuLnRvc2YKZWlnaHQudG9zZgluaW5lLnRvc2YJemVyby5kbm9tCG9uZS5kbm9tCHR3by5kbm9tCnRocmVlLmRub20JZm91ci5kbm9tCWZpdmUuZG5vbQhzaXguZG5vbQpzZXZlbi5kbm9tCmVpZ2h0LmRub20JbmluZS5kbm9tCXplcm8ubnVtcghvbmUubnVtcgh0d28ubnVtcgp0aHJlZS5udW1yCWZvdXIubnVtcglmaXZlLm51bXIIc2l4Lm51bXIKc2V2ZW4ubnVtcgplaWdodC5udW1yCW5pbmUubnVtchZwZXJpb2RjZW50ZXJlZC5sb2NsQ0FUDWNhcm9uY29tYi5hbHQLdW5pMDMyNi5hbHQSaG9va2Fib3ZlY29tYi5jYXNlEHVuaTAzMDIubG9jbFZJRVQQdW5pMDMwNi5sb2NsVklFVBVkb3RiZWxvd2NvbWIubG9jbFZJRVQTY2Fyb25jb21iLmFsdC5zaG9ydAt1bmkwMzA2MDMwMQt1bmkwMzA2MDMwMAt1bmkwMzA2MDMwOQt1bmkwMzA2MDMwMwt1bmkwMzAyMDMwMQt1bmkwMzAyMDMwMAt1bmkwMzAyMDMwOQt1bmkwMzAyMDMwMwAAAAAAAf//AAIAAQAAAAwAAABkAHgAAgAOAAEBkgABAZMBqgADAasCpgABAqcCqAACAqkDlAABA5UDlQACA5YDlgABA5cDlwACA5gDmAABA5kDmQACA5oDmgABA5sDmwACA5wD0QABA9ID4AADAA4AAQAGAAEABAABAsEAAQABA54AAgADAZMBoQABA9MD1gABA9kD4AABAAAAAQAAAAoCIgN0AAJERkxUAA5sYXRuADoABAAAAAD//wARAAAAAQADAAQABQAGAAcAEQASABMAFAAVABYAFwAYABkAGgA6AAlBWkUgAGRDQVQgAI5DUlQgALhLQVogAOJNT0wgAQxOTEQgATZST00gAWBUQVQgAYpUUksgAbQAAP//ABIAAAABAAIAAwAEAAUABgAHABEAEgATABQAFQAWABcAGAAZABoAAP//ABIAAAABAAMABAAFAAYABwAIABEAEgATABQAFQAWABcAGAAZABoAAP//ABIAAAABAAMABAAFAAYABwAJABEAEgATABQAFQAWABcAGAAZABoAAP//ABIAAAABAAMABAAFAAYABwAKABEAEgATABQAFQAWABcAGAAZABoAAP//ABIAAAABAAMABAAFAAYABwALABEAEgATABQAFQAWABcAGAAZABoAAP//ABIAAAABAAMABAAFAAYABwAMABEAEgATABQAFQAWABcAGAAZABoAAP//ABIAAAABAAMABAAFAAYABwANABEAEgATABQAFQAWABcAGAAZABoAAP//ABIAAAABAAMABAAFAAYABwAOABEAEgATABQAFQAWABcAGAAZABoAAP//ABIAAAABAAMABAAFAAYABwAPABEAEgATABQAFQAWABcAGAAZABoAAP//ABIAAAABAAMABAAFAAYABwAQABEAEgATABQAFQAWABcAGAAZABoAG2FhbHQApGNhc2UArGNjbXAAsmRsaWcAvGRub20AwmZyYWMAyGxpZ2EA0mxudW0A2GxvY2wA3mxvY2wA5GxvY2wA6mxvY2wA8GxvY2wA9mxvY2wA/GxvY2wBAmxvY2wBCGxvY2wBDm51bXIBFG9udW0BGm9yZG4BIHBudW0BKHNhbHQBLnNpbmYBNHNzMDEBOnN1YnMBQHN1cHMBRnRudW0BTAAAAAIAAAABAAAAAQAbAAAAAwACAAMABAAAAAEAHAAAAAEAEQAAAAMAEgATABQAAAABAB0AAAABABcAAAABAA0AAAABAAYAAAABAAwAAAABAAkAAAABAAgAAAABAAUAAAABAAcAAAABAAoAAAABAAsAAAABABAAAAABABoAAAACABUAFgAAAAEAGAAAAAEAHgAAAAEAIAAAAAEAHwAAAAEADgAAAAEADwAAAAEAGQAiAEYATgBWAGQAbgB2AH4AiACQAJgAoACoALAAuADAAMgA0ADYAOAA6ADwAPoBBAEMARQBHAEkASwBNAE8AUQBTAFUAVwAAQAAAAEBHgADAAAAAQUUAAYAAAAEBvIHFgdMB2oABgAAAAIKbgqMAAQAAAABCqAABAAAAAEK7gAGAAAAAgsMCzIAAQAAAAELTgABAAAAAQtgAAEAAAABC3IAAQAAAAELdgABAAAAAQt6AAEAAAABC34AAQAAAAELggABAAAAAQuGAAEAAAABC44AAQAAAAELqgABAAAAAQuyAAEAAAABC7oAAQAAAAELvgAGAAAAAgvGC+gABgAAAAIMBAwoAAQAAAABDEIAAQAAAAEMVAABAAAAAQxcAAEAAAABDJIAAQAAAAEMwgABAAAAAQz4AAQAAAABDUoABAAAAAENZAABAAAAAQ2QAAEAAAABEU4AAQAAAAEVDAABAAAAARUUAAICAAD9AmwCxALbAtwC4wL1AvgC+gB+AwUDBwMOAyUDKgM0A1UDbQGAA3AAfgN6A4IDhwOQA9ECugKqArECwQK4Ar8C0wLFAskC0ALvAuUC6QLrAwQDFQMPAxEDEwMrA0oDOgNBA1EDSANPA1IDZANWA1oDYQOIA4oCvQNNAqsDOwK+A04C1gNnAsYDVwLRA2IC2QNqAscDWALfAt0C4QLgAvQC8gLoAvMC7QLkAvYDcQNzA3IDdAN4AvwC/gL9AwEDeQF0AXUDCQN8AwgDewMjAx8DEAMiAx0DIQMnA4QDLAOJAy0DNQORAzcDkwM2A5IDBgMXAsICwwNUAvcDdgL7AwIC3gLAA1ADUwK3A0cCvANMAs8DYALVA2YC6gLxAxIDHgMLA34DMgOOA2wD1ALYA2kC1wNoAsgDWQLiAuwDdQN3AvkC/wMAAwMDDAOAAw0DgQMkAyADKQOGAyYDgwMoA4UDLgM4A5QDfwK5A0kCuwNLArIDQgK0A0QCtQNFArYDRgKzA0MCrAM8Aq4DPgKvAz8CsANAAq0DPQLSA2MC1ANlAtoDawLKA1sCzANdAs0DXgLOA18CywNcAvAC7gMUAxYDGAMaAxsDHAMZAzADjAMvA4sDMQONAzMDjwOdA54C5wOWA5gDmgOcA70DvgO/A8ADwQPCA8MDxAPFA8YAAQD9ABQAKgArACwALgAvADIAMwA0ADYAOQA6ADwAPgA/AEoASwBPAFEAVABZAFwAXgBfAHsAhACFAIYAhwCIAIkAjACNAI4AjwCQAJEAkgCTAJUAnQCeAJ8AoAChAKQApQCmAKcAqACpAKoArACtAK4ArwDBAMMAxADFAMYAxwDIAMkA1gDXANgA2QDaANsA3ADdAN4A3wDgAOIA5ADmAOwA7gDwAPIA9AD2APgA/gEAAQIBBAEGAQcBCQELAQ4BFwEiASMBKAEpASoBKwEsAS4BMAEyATQBNgE4ATkBOgE7ATwBPQE+AT8BQAFBAUIBQwFHAUkBSgFLAUwBTgFPAVABUgFWAVcBWQFcAV0BXgFfAWABYQFiAWMBZAFmAXABcgF2AXcBfgF/AYEBmwG1AbYBtwG4AbkBugG7AcEBxAHGAccByQHLAc0B5QHmAecB6AHpAesB7QHuAe8B8AHxAfIB8wH1AfYB9wH5AfoB+wH8Af0B/gH/AgACAQICAgMCBAIFAgYCBwIIAgkCCgILAgwCDQIOAg8CEAIRAhICEwIUAhUCFgIXAhgCGQIaAhsCHAIdAh4CHwIgAiECIwI9Aj8CQQJDAkUCRwJJAksCTAJNAk4CTwJQAlECUgKnAqgC5gOVA5cDmQObA8cDyAPJA8oDywPMA80DzgPPA9AAAQG+AC0AYABuAHwAigCYAKYAtADCANAA3gDsAPIA+AD+AQQBCgEQARYBHAEiASgBLgE0AToBQAFGAUwBUgFYAV4BZAFqAXABdgF8AYIBiAGOAZQBmgGgAaYBrAGyAbgABgJ0Am0DxwO9A58DswAGAnUAfQPIA74DoAO0AAYCdgB2A8kDvwOhA7UABgJ3AHcDygPAA6IDtgAGAngCbgPLA8EDowO3AAYCeQJvA8wDwgOkA7gABgJ6AnADzQPDA6UDuQAGAnsCcQPOA8QDpgO6AAYCfAJyA88DxQOnA7sABgJ9AnMD0APGA6gDvAACAG4CqQACAG4DOQACAPUDbwACAXYDCgACAXcDfQACABUDqQACABYDqgACABcDqwACABgDrAACABkDrQACABoDrgACABsDrwACABwDsAACAB0DsQAC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AAoAAgAuABQAFQAWABcAGAAZABoAGwAcAB0AHgOzA7QDtQO2A7cDuAO5A7oDuwO8AAIAAQOfA7IAAAACAC4AFAOzA7QDtQO2A7cDuAO5A7oDuwO8A6kDqgOrA6wDrQOuA68DsAOxA7IAAgACABUAHgAAA58DqAAKAAIARAAfA58DoAOhA6IDowOkA6UDpgOnA6gD1AOfA6ADoQOiA6MDpAOlA6YDpwOoA58DoAOhA6IDowOkA6UDpgOnA6gAAgADABUAHgAAAZsBmwAKA6kDvAALAAEAHAABAAgAAgAGAA4DlwADAEsA9wObAAIA9wABAAEASwABAC4AAQAIAAQACgASABoAIAOZAAMASwBRA5UAAwBLAE4CqAACAFECpwACAE4AAQABAEsAAgHkAO8CqQLEAtsC3ALjAvUC+AL6AwUDBwMOAyUDKgM0AzkDVQNtA3ADegOCA4cDkAK6AqoCsQLBArgCvwLTAsUCyQLQAu8C5QLpAusDBAMVAw8DEQMTAysDSgM6A0EDUQNIA08DUgNkA1YDWgNhA4gDigK9A00CqwM7Ar4DTgLWA2cCxgNXAtEDYgLZA2oCxwNYAt8C3QLhAuAC9ALyAugC8wLtAuQC9gNxA3MDcgN0A3gC/AL+Av0DAQN5AwoDfQMJA3wDCAN7AyMDHwMQAyIDHQMhAycDhAMsA4kDLQM1A5EDNwOTAzYDkgMGAxcCwgLDA1QC9wN2AvsDAgLeAsADUANTArcDRwK8A0wCzwNgAtUDZgLqAvEDEgMeAwsDfgMyA44DbALYA2kC1wNoAsgDWQLiAuwDdQN3AvkC/wMAAwMDDAOAAw0DgQMkAyADKQOGAyYDgwMoA4UDLgM4A5QDfwK5A0kCuwNLArIDQgK0A0QCtQNFArYDRgKzA0MCrAM8Aq4DPgKvAz8CsANAAq0DPQLSA2MC1ANlAtoDawLKA1sCzANdAs0DXgLOA18CywNcAvAC7gMUAxYDGAMaAxsDHAMZAzADjAMvA4sDMQONAzMDjwOdA54C5wOWA5gDmgOcAAEA7wAmACoAKwAsAC4ALwAyADMANgA5ADoAPAA+AD8ARgBKAEsAUQBZAFwAXgBfAIQAhQCGAIcAiACJAIwAjQCOAI8AkACRAJIAkwCVAJ0AngCfAKAAoQCkAKUApgCnAKgAqQCqAKwArQCuAK8AwQDDAMQAxQDGAMcAyADJANYA1wDYANkA2gDbANwA3QDeAN8A4ADiAOQA5gDsAO4A8ADyAPQA9gD4AP4BAAECAQQBBgEHAQkBCwEOARcBJgEnASgBKQEqASsBLAEuATABMgE0ATYBOAE5AToBOwE8AT0BPgE/AUABQQFCAUMBRwFJAUoBSwFMAU4BTwFQAVIBVgFXAVkBXAFdAV4BXwFgAWEBYgFjAWQBZgFwAXIBdgF3AX4BfwGBAbUBtgG3AbgBuQG6AbsBwQHEAcYBxwHJAcsBzQHlAeYB5wHoAekB6wHtAe4B7wHwAfEB8gHzAfUB9gH3AfkB+gH7AfwB/QH+Af8CAAIBAgICAwIEAgUCBgIHAggCCQIKAgsCDAINAg4CDwIQAhECEgITAhQCFQIWAhcCGAIZAhoCGwIcAh0CHgIfAiACIQIjAj0CPwJBAkMCRQJHAkkCSwJMAk0CTgJPAlACUQJSAqcCqALmA5UDlwOZA5sAAgHkAO8CqQLEAtsC3ALjAvUC+AL6AwUDBwMOAyUDKgM0AzkDVQNtA3ADegOCA4cDkAK6AqoCsQLBArgCvwLTAsUCyQLQAu8C5QLpAusDBAMVAw8DEQMTAysDSgM6A0EDUQNIA08DUgNkA1YDWgNhA4gDigK9A00CqwM7Ar4DTgLWA2cCxgNXAtEDYgLZA2oCxwNYAt8C3QLhAuAC9ALyAugC8wLtAuQC9gNxA3MDcgN0A3gC/AL+Av0DAQN5AwoDfQMJA3wDCAN7AyMDHwMQAyIDHQMhAycDhAMsA4kDLQM1A5EDNwOTAzYDkgMGAxcCwgLDA1QC9wN2AvsDAgLeAsADUANTArcDRwK8A0wCzwNgAtUDZgLqAvEDEgMeAwsDfgMyA44DbALYA2kC1wNoAsgDWQLiAuwDdQN3AvkC/wMAAwMDDAOAAw0DgQMkAyADKQOGAyYDgwMoA4UDLgM4A5QDfwK5A0kCuwNLArIDQgK0A0QCtQNFArYDRgKzA0MCrAM8Aq4DPgKvAz8CsANAAq0DPQLSA2MC1ANlAtoDawLKA1sCzANdAs0DXgLOA18CywNcAvAC7gMUAxYDGAMaAxsDHAMZAzADjAMvA4sDMQONAzMDjwOdA54C5wOWA5gDmgOcAAEA7wAmACoAKwAsAC4ALwAyADMANgA5ADoAPAA+AD8ARgBKAEsAUQBZAFwAXgBfAIQAhQCG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AAIALwAvAAEA+AD4AAEAAQABApAAAQDiAM4AAwDyAAwACAAyADgAPgBEAEoAUABWAFwAYgBoAG4AdAB6AIAAhgCMAJIAmACeAKQAqgCwALYAvAABAo8AAAABApoFmgABAAAAAAABAlIAAAABAm0ESAABAAAAAAABAtUAAAABArwESAABBCUESAABAwwAAAABAwAFmgABAAAAAAABAtsAAAABAAAAAAABBVwF8AABAxsAAAABAx8FmgABAAAAAAABAwwAAAABAwAFmgABAAAAAAABAysAAAABAzsFmgABAAAAAAABAAgACQBmAHkCfgKEAogCiQKPAAIAAgGTAakAAAPSA+AAFwAmAAEAmgABAKAAAQCmAAEArAABALIAAQC4AAEAvgABAMQAAQDKAAEA0AABANYAAQDcAAEA4gABAOgAAQDuAAIA9AAAAPoAAAEAAAABBgAAAQwAAAESAAABGAAAAR4AAgEkAAEBKgABATAAAQE2AAEBPAAAAUIAAgFIAAEBTgABAVQAAQFaAAEBYAABAWYAAQFsAAEBcgABAXgAAQApBEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAf/+BEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAABZoAAQAABEgAAf/+BEgAAQAABEgAAQAABEgAAQAAAAAAAQAABZoAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAsACYAAwA8AAwAAQAIAA4AFAABAtUAAAABArwESAABBCUESAABAAEBrQACAAIBkwGpAAAD0gPgABcAJgABAJoAAQCgAAEApgABAKwAAQCyAAEAuAABAL4AAQDEAAEAygABANAAAQDWAAEA3AABAOIAAQDoAAEA7gACAPQAAAD6AAABAAAAAQYAAAEMAAABEgAAARgAAAEeAAIBJAABASoAAQEwAAEBNgABATwAAAFCAAIBSAABAU4AAQFUAAEBWgABAWAAAQFmAAEBbAABAXIAAQF4AAEAKQRIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAH//gRIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAAAAAAEAAAAAAAEAAAAAAAEAAAAAAAEAAAAAAAEAAAAAAAEAAAAAAAEAAAWaAAEAAARIAAH//gRIAAEAAARIAAEAAARIAAEAAAAAAAEAAAWaAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAE/rj7eAAM/vgAMAp4Ptg+8D8IPyA/OD9QP2g/gD+YP7A/yD/gP/hAEEAoQEBAWEBwQIhAoEC4QNBA6EEAQRhBMEFIQWBBeEGQQahBwEHYQfBCCEIgQjhCUEJoQoBCmEKwQshC4EL4QxBDKENAQ1hDcEOIQ6BDuEPQQ+hEAEQYRDBESERgRHhEkESoRMBE2ETwRQhFIEU4RVBFaEWARZhFsEXIReBF+EYQRihGQEZYRnBGiEagRrhG0EboRwBHGEcwR0hHYEd4R5BHqEfAR9hH8EgISCBIOEhQSGhIgEiYSLBIyEjgSPhJEEkoSUBJWElwSYhJoEm4SdBJ6EoAShhKMEpISmBKeEqQSqhKwErYSvBLCEsgSzhLUEtoS4BLmEuwS8hL4Ev4TBBMKExATFhMcEyITKBMuEzQTOhNAE0YTTBNSE1gTXhNkE2oTcBN2E3wTghOIE44TlBOaE6ATphOsE7ITuBO+E8QTyhPQE9YT3BPiE+gT7hP0E/oUABQGFAwUEhQYFB4UJBQqFDAUNhQ8FEIUSBROFFQUWhRgFGYUbBRyFHgUfhSEFIoUkBSWFJwUohSoFK4UtBS6FMAUxhTMFNIU2BTeFOQU6hTwFPYU/BUCFQgVDhUUFRoVIBUmFSwVMhU4FT4VRBVKFVAVVhVcFWIVaBVuFXQVehWAFYYVjBWSFZgVnhWkFaoVsBW2FbwVwhXIFc4V1BXaFeAV5hXsFfIV+BX+FgQWChYQFhYWHBYiFigWLhY0FjoWQBZGFkwWUhZYFl4WZBZqFnAWdhZ8FoIWiBaOFpQWmhagFqYWrBayFrgWvhbEFsoW0BbWFtwW4hboFu4W9Bb6FwAXBhcMFxIXGBceFyQXKhcwFzYXPBdCF0gXThdUF1oXYBdmF2wXchd4F34XhBeKF5AXlhecF6IXqBeuF7QXuhfAF8YXzBfSF9gX3hfkF+oX8Bf2F/wYAhgIGA4YFBgaGCAYJhgsGDIYOBg+GEQYShhQGFYYXBhiGGgYbhh0GHoYgBiGGIwYkhiYGJ4YpBiqGLAYthi8GMIYyBjOGNQY2hjgGOYY7BjyGPgY/hkEGQoZEBkWGRwZIhkoGS4ZNBk6GUAZRhlMGVIZWBleGWQZahlwGXYZfBmCGYgZjhmUGZoZoBmmGawZshm4Gb4ZxBnKGdAZ1hncGeIZ6BnuGfQZ+hoAGgYaDBoSGhgaHhokGioaMBo2GjwaQhpIGk4aVBpaGmAaZhpsGnIaeBp+GoQaihqQGpYanBqiGqgarhq0GroawBrGGswa0hrYGt4a5BrqGvAa9hr8GwIbCBsOGxQbGhsgGyYbLBsyGzgbPhtEG0obUBtWG1wbYhtoG24bdBt6G4AbhhuMG5IbmBueG6QbqhuwG7YbvBvCG8gbzhvUG9ob4BvmG+wb8hv4G/4cBBwKHBAcFhwcHCIcKBwuHDQcOhxAHEYcTBxSHFgcXhxkHGoccBx2HHwcghyIHI4clByaHKAcphysHLIcuBy+HMQcyhzQHNYc3BziHOgc7hz0HPodAB0GHQwdEh0YHR4dJB0qHTAdNh08HUIdSB1OHVQdWh1gHWYdbB1yHXgdfh2EHYodkB2WHZwdoh2oHa4dtB26HcAdxh3MHdId2B3eHeQd6h3wHfYd/B4CHggeDh4UHhoeIB4mHiweMh44Hj4eRB5KHlAeVh5cHmIeaB5uHnQeeh6AHoYejB6SHpgenh6kHqoesB62Hrwewh7IHs4e1B7aHuAe5h7sHvIe+B7+HwQfCh8QHxYfHB8iHygfLh80HzofQB9GH0wfUh9YH14fZB9qH3Afdh98H4IfiB+OH5Qfmh+gH6YfrB+yH7gfvh/EH8of0B/WH9wf4h/oH+4f9B/6IAAgBiAMIBIgGCAeICQgKiAwIDYgPCBCIEggTiBUIFogYCBmIGwgciB4IH4ghCCKIJAgliCcIKIgqCCuILQguiDAIMYgzCDSINgg3iDkIOog8CD2IPwhAiEIIQ4hFCEaISAhJiEsITIhOCE+IUQhSiFQIVYhXCFiIWghbiF0IXohgCGGIYwhkiGYIZ4hpCGqIbAhtiG8IcIhyCHOIdQh2iHgIeYh7CHyIfgh/iIEIgoiECIWIhwiIiIoIi4iNCI6IkAiRiJMIlIiWCJeImQiaiJwInYifCKCIogijiKUIpoioCKmIqwisiK4Ir4ixCLKItAi1iLcIuIi6CLuIvQi+iMAIwYjDCMSIxgjHiMkIyojMCM2IzwjQiNII04jVCNaI2AjZiNsI3IjeCN+I4QjiiOQI5YjnCOiI6gjriO0I7ojwCPGI8wj0iPYI94j5CPqI/Aj9iP8JAIkCCQOJBQkGiQgJCYkLCQyJDgkPiREJEokUCRWJFwkYiRoJG4kdCR6JIAkhiSMJJIkmCSeJKQkqiSwJLYkvCTCJMgkziTUJNok4CTmJOwk8iT4JP4lBCUKJRAlFiUcJSIlKCUuJTQlOiVAJUYlTCVSJVglXiVkJWolcCV2JXwlgiWIJY4llCWaJaAlpiWsJbIluCW+JcQlyiXQJdYl3CXiJegl7iX0JfomACYGJgwmEiYYJh4mJCYqJjAmNiY8JkImSCZOJlQmWiZgJmYmbCZyJngmfiaEJoomkCaWJpwmoiaoJq4mtCa6JsAmxibMJtIm2CbeJuQm6ibwJvYm/CcCJwgnDicUJxonICcmJywnMic4Jz4nRCdKJ1AnVidcJ2InaCduJ3QneieAJ4YnjCeSJ5gnniekJ6onsCe2J7wnwifIJ84n1CfaJ+An5ifsJ/In+Cf+KAQoCigQKBYoHCgiKCgoLig0KDooQChGKEwoUihYKF4oZChqKHAodih8KIIoiCiOKJQomiigKKYorCiyKLgovijEKMoo0CjWKNwo4ijoKO4o9Cj6KQApBikMKRIpGCkeKSQpKikwKTYpPClCKUgpTilUKVopYClmKWwpcil4KX4phCmKKZAplimcKaIpqCmuKbQpuinAKcYpzCnSKdgp3inkKeop8Cn2KfwqAioIKg4qFCoaKiAqJiosKjIqOCo+KkQqSipQKlYqXCpiKmgqbip0KnoqgCqGKowqkiqYKp4qpCqqKrAqtiq8KsIqyCrOKtQq2irgKuYq7CryKvgq/isEKworECsWKxwrIisoKy4rNCs6K0ArRitMK1IrWCteK2QraitwK3YrfCuCK4grjiuUK5oroCumK6wrsiu4K74rxCvKK9Ar1ivcK+Ir6CvuK/Qr+iwALAYsDCwSLBgsHiwkLCosMCw2LDwsQixILE4sVCxaLGAsZixsLHIseCx+LIQsiiyQLJYsnCyiLKgsriy0LLoswCzGLMws0izYLN4s5CzqLPAs9iz8LQItCC0OLRQtGi0gLSYtLC0yLTgtPi1ELUotUC1WLVwtYi1oLW4tdC16LYAthi2MLZItmC2eLaQtqi2wLbYtvC3CLcgtzi3ULdot4C3mLewt8i34Lf4uBC4KLhAuFi4cLiIuKC4uLjQuOi5ALkYuTC5SLlguXi5kLmoucC52Lnwugi6ILo4ulC6aLqAupi6sLrIuuC6+LsQuyi7QLtYu3C7iLugu7i70LvovAC8GLwwvEi8YLx4vJC8qLzAvNi88L0IvSC9OL1QvWi9gL2YvbC9yL3gvfi+EL4ovkC+WL5wvoi+oL64vtC+6L8Avxi/ML9Iv2C/eL+Qv6i/wL/Yv/DACMAgwDjAUMBowIDAmMCwwMjA4MD4wRDBKMFAwVjBcMGIwaDBuMHQwejCAMIYwjDCSMJgwnjCkMKowsDC2MLwwwjDIMM4w1DDaMOAw5jDsMPIw+DD+MQQxCjEQMRYxHDEiMSgxLjE0MToxQDFGMUwxUjFYMV4xZDFqMXAxdjF8MYIxiDGOMZQxmjGgMaYxrDGyMbgxvjHEMcox0DHWMdwx4jHoMe4x9DH6MgAyBjIMMhIyGDIeMiQyKjIwMjYyPDJCMkgyTjJUMloyYDJmMmwycjJ4Mn4yhDKKMpAyljKcMqIyqDKuMrQyujLAMsYyzDLSMtgy3jLkMuoy8DL2MvwzAjMIMw4zFDMaMyAzJjMsMzIzODM+M0QzSjNQM1YzXDNiM2gzbjN0M3ozgDOGM4wzkjOYM54zpDOqM7AztjO8M8IzyDPOM9Qz2jPgM+Yz7DPyM/gz/jQENAo0EDQWNBw0IjQoNC40NDQ6NEA0RjRMNFI0WDReNGQ0ajRwNHY0fDSCNIg0jjSUNJo0oDSmNKw0sjS4NL40xDTKNNA01jTcNOI06DTuNPQ0+jUANQY1DDUSNRg1HjUkNSo1MDU2NTw1QjVINU41VDVaNWA1ZjVsNXI1eDV+NYQ1ijWQNZY1nDWiNag1rjW0Nbo1wDXGNcw10jXYNd415DXqNfA19jX8NgI2CDYONhQ2GjYgNiY2LDYyNjg2PjZENko2UDZWNlw2YjZoNm42dDZ6NoA2hjaMNpI2mDaeNqQ2qjawNrY2vDbCNsg2zjbUNto24DbmNuw28jb4Nv43BDcKNxA3FjccNyI3KDcuNzQ3OjdAN0Y3TDdSN1g3XjdkN2o3cDd2N3w3gjeI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BZoAAQSgBbgAAQMQAAAAAQMOBZoAAQSgBbgAAQMQAAAAAQMOBZoAAQSgBbgAAQKeAAAAAQKYBZoAAQAAAAAAAQJIAAAAAQJYBEgAAQAAAAAAAQJIAAAAAQJYBEgAAQAAAAAAAQJIAAAAAQJYBEgAAQAAAAAAAQJIAAAAAQJYBEgAAQAAAAAAAQJIAAAAAQJYBEgAAQAAAAAAAQJIAAAAAQJYBEgAAQAAAAAAAQAAAAAAAQPlBEgAAQAAAAAAAQJSAAAAAQJtBEgAAQAAAAAAAQJoAAAAAQJkBEYAAQAAAAAAAQJoAAAAAQJkBEYAAQAAAAAAAQJoAAAAAQJkBEYAAQAAAAAAAQJoAAAAAQJkBEYAAQAAAAAAAQAAAAAAAQErBEgAAQAAAAAAAQAAAAAAAQErBEgAAQAAAAAAAQAAAAAAAQErBEgAAQAAAAAAAQAAAAAAAQErBEgAAQAAAAAAAQK0AAAAAQLJBEgAAQAAAAAAAQKFAAAAAQKDBEYAAQMbBEgAAQKFAAAAAQKDBEYAAQMbBEgAAQKFAAAAAQKDBEYAAQMbBEgAAQKFAAAAAQKDBEYAAQMbBEgAAQKFAAAAAQKDBEYAAQMbBEgAAQAAAAAAAQKDBEYAAQAAAAAAAQKoAAAAAQKPBEgAAQP4BEgAAQKoAAAAAQKPBEgAAQP4BEgAAQKoAAAAAQKPBEgAAQP4BEgAAQKoAAAAAQKPBEgAAQP4BEgAAQN/AAAAAQIxBEgAAQAAAAAAAQE3AAAAAQE3BfAAAQIvBEgAAQN/AAAAAQIxBEgAAQAAAAAAAQL0AAAAAQL+BZoAAQAAAAAAAQJIAAAAAQJYBEgAAQAAAAAAAQL0AAAAAQL+BZoAAQAAAAAAAQJIAAAAAQJYBEgAAQAAAAAAAQMMAAAAAQMABZoAAQAAAAAAAQJSAAAAAQJtBEgAAQAAAAAAAQMMAAAAAQMABZoAAQAAAAAAAQJSAAAAAQJtBEgAAQAAAAAAAQMMAAAAAQMABZoAAQAAAAAAAQJSAAAAAQJtBEgAAQAAAAAAAQMMAAAAAQMABZoAAQAAAAAAAQJSAAAAAQJtBEgAAQAAAAAAAQMZAAAAAQLnBZoAAQAAAAAAAQLbAAAAAQAAAAAAAQVcBfAAAQNIAAAAAQMXBZoAAQAAAAAAAQLbAAAAAQAAAAAAAQVcBfAAAQLJAAAAAQLPBZoAAQAAAAAAAQJoAAAAAQJkBEYAAQAAAAAAAQLJAAAAAQLPBZoAAQAAAAAAAQJoAAAAAQJkBEYAAQAAAAAAAQLJAAAAAQLPBZoAAQAAAAAAAQJoAAAAAQJkBEYAAQAAAAAAAQLJAAAAAQLPBZoAAQAAAAAAAQJoAAAAAQJkBEYAAQAAAAAAAQMbAAAAAQMfBZoAAQAAAAAAAQAAAAAAAQKRBEgAAQAAAAAAAQMbAAAAAQMfBZoAAQAAAAAAAQAAAAAAAQKRBEgAAQAAAAAAAQMbAAAAAQMfBZoAAQAAAAAAAQAAAAAAAQKRBEgAAQAAAAAAAQMbAAAAAQMfBZoAAQAAAAAAAQAAAAAAAQKRBEgAAQAAAAAAAQMnAAAAAQM1BZoAAQAAAAAAAQLFAAAAAQExBfAAAQInBEwAAQNqAAAAAQN5BZoAAQAAAAAAAQLFAAAAAQExBfAAAQInBEwAAQE5AAAAAQE5BZoAAQAAAAAAAQAAAAAAAQErBEgAAQAAAAAAAQE5AAAAAQE5BwYAAQAAAAAAAQAAAAAAAQErBEgAAQAAAAAAAQE5AAAAAQE5BZoAAQAAAAAAAQAAAAAAAQErBEgAAQAAAAAAAQE5AAAAAQE5BZoAAQAAAAAAAQAAAAAAAQErBEgAAQAAAAAAAQE5AAAAAQRqBZoAAQAAAAAAAQErAAAAAQErBEgAAQAAAAAAAQAAAAAAAQH4BZoAAQAAAAAAAQAAAAAAAQEhBEgAAQAAAAAAAQLXAAAAAQLXBZoAAQAAAAAAAQKWAAAAAQE3BfAAAQIvBEgAAQJgAAAAAQErBEgAAQAAAAAAAQJvAAAAAQE7BZoAAQNCBZoAAQE3AAAAAQE3BfAAAQJQBfAAAQJvAAAAAQE7BZoAAQNCBZoAAQE3AAAAAQE3BfAAAQJQBfAAAQJvAAAAAQE7BZoAAQNCBZoAAQE3AAAAAQE3BfAAAQJQBfAAAQJvAAAAAQE7BZoAAQNCBZoAAQE3AAAAAQE3BfAAAQJQBfAAAQJ1AAAAAQFCBZoAAQNIBZoAAQFeAAAAAQFeBfAAAQJ3BfAAAQMrAAAAAQM7BZoAAQAAAAAAAQK0AAAAAQLJBEgAAQAAAAAAAQMrAAAAAQM7BZoAAQAAAAAAAQK0AAAAAQLJBEgAAQAAAAAAAQMrAAAAAQM7BZoAAQAAAAAAAQK0AAAAAQLJBEgAAQAAAAAAAQOcAAAAAQOwBEgAAQAAAAAAAQMpAAAAAQMpBZoAAQAAAAAAAQK0AAAAAQLJBEgAAQAAAAAAAQM/AAAAAQMxBZoAAQPFBbgAAQKFAAAAAQKDBEYAAQMbBEgAAQM/AAAAAQMxBZoAAQPFBbgAAQKFAAAAAQKDBEYAAQMbBEgAAQM/AAAAAQMxBZoAAQPFBbgAAQKFAAAAAQKDBEYAAQMbBEgAAQYzAAAAAQRqBZoAAQAAAAAAAQAAAAAAAQQpBEYAAQAAAAAAAQLhAAAAAQLdBZoAAQAAAAAAAQEnAAAAAQHsBEgAAQAAAAAAAQLhAAAAAQLdBZoAAQAAAAAAAQEnAAAAAQHsBEgAAQAAAAAAAQLhAAAAAQLdBZoAAQAAAAAAAQEnAAAAAQHsBEgAAQAAAAAAAQKPAAAAAQKaBZoAAQAAAAAAAQHsAAAAAQH8BEgAAQAAAAAAAQKPAAAAAQKaBZoAAQAAAAAAAQHsAAAAAQH8BEgAAQAAAAAAAQKPAAAAAQKaBZoAAQAAAAAAAQHsAAAAAQH8BEgAAQAAAAAAAQKPAAAAAQKaBZoAAQAAAAAAAQHsAAAAAQH8BEgAAQAAAAAAAQJYAAAAAQJtBZoAAQAAAAAAAQH+AAAAAQFYBUgAAQJYBfAAAQJYAAAAAQJtBZoAAQAAAAAAAQH+AAAAAQFYBUgAAQJYBfAAAQH+AAAAAQAAAAAAAQAAAAAAAQMQAAAAAQMOBZoAAQSgBbgAAQKoAAAAAQKPBEgAAQP4BEgAAQMQAAAAAQMOBZoAAQSgBbgAAQKoAAAAAQKPBEgAAQP4BEgAAQMQAAAAAQMOBZoAAQSgBbgAAQKoAAAAAQKPBEgAAQP4BEgAAQMQAAAAAQMOBZoAAQSgBbgAAQKoAAAAAQKPBEgAAQP4BEgAAQMQAAAAAQMOBZoAAQSgBbgAAQKoAAAAAQKPBEgAAQP4BEgAAQQxAAAAAQQxBZoAAQAAAAAAAQAAAAAAAQOmBEgAAQAAAAAAAQKeAAAAAQKYBZoAAQAAAAAAAQN/AAAAAQIxBEgAAQAAAAAAAQKeAAAAAQKYBZoAAQAAAAAAAQKsAAAAAQK0BZoAAQAAAAAAAQIxAAAAAQIzBEgAAQAAAAAAAQKsAAAAAQK0BZoAAQAAAAAAAQIxAAAAAQIzBEgAAQAAAAAAAQKsAAAAAQK0BZoAAQAAAAAAAQIxAAAAAQIzBEgAAQAAAAAAAQM/AAAAAQMxBZoAAQPFBbgAAQKFAAAAAQKDBEYAAQMbBEgAAQMQAAAAAQMOBZoAAQSgBbgAAQKoAAAAAQKYBEgAAQP4BEgAAQjbAAAAAQjjBZoAAQAAAAAAAQhgAAAAAQhiBEgAAQAAAAAAAQeoAAAAAQeqBEgAAQVcBfAAAQJvAAAAAQZMBZoAAQNCBZoAAQJvAAAAAQE7BZoAAQNCBZoAAQE3AAAAAQE3BfAAAQJQBfAAAQMrAAAAAQhKBZoAAQAAAAAAAQMrAAAAAQM7BZoAAQAAAAAAAQK0AAAAAQLJBEgAAQAAAAAAAQMbAAAAAQMfBx8AAQAAAAAAAQAAAAAAAQKRBc0AAQAAAAAAAQM/AAAAAQMxBZoAAQPFBbgAAQKFAAAAAQKDBEYAAQMbBEgAAQL0AAAAAQL+CQIAAQAAAAAAAQJIAAAAAQJYB7AAAQAAAAAAAQXpAAAAAQUxByEAAQAAAAAAAQAAAAAAAQPlBc8AAQAAAAAAAQM/AAAAAQM7ByEAAQPFBbgAAQAAAAAAAQKDBc0AAQAAAAAAAQL0AAAAAQL+ByEAAQAAAAAAAQJIAAAAAQJYBc8AAQAAAAAAAQL0AAAAAQL+ByEAAQAAAAAAAQJIAAAAAQJYBc8AAQAAAAAAAQLJAAAAAQLPByEAAQAAAAAAAQJoAAAAAQJkBc0AAQAAAAAAAQLJAAAAAQLPByEAAQAAAAAAAQJoAAAAAQJkBc0AAQAAAAAAAQE5AAAAAQE5ByEAAQAAAAAAAQAAAAAAAQErBc8AAQAAAAAAAQE5AAAAAQE5ByEAAQAAAAAAAQAAAAAAAQErBc8AAQAAAAAAAQM/AAAAAQMxByEAAQPFBbgAAQKFAAAAAQKDBc0AAQMbBEgAAQM/AAAAAQMxByEAAQPFBbgAAQKFAAAAAQKDBc0AAQMbBEgAAQLhAAAAAQLdByEAAQAAAAAAAQEnAAAAAQHsBc8AAQAAAAAAAQLhAAAAAQLdByEAAQAAAAAAAQEnAAAAAQHsBc8AAQAAAAAAAQMQAAAAAQMOByEAAQSgBbgAAQKoAAAAAQKPBc8AAQP4BEgAAQMQAAAAAQMOByEAAQSgBbgAAQKoAAAAAQKPBc8AAQP4BEgAAQKPAAAAAQKaBZoAAQAAAAAAAQHsAAAAAQH8BEgAAQAAAAAAAQJYAAAAAQJtBZoAAQAAAAAAAQH+AAAAAQFYBUgAAQJYBfAAAQM/AAAAAQMxCKIAAQPFBbgAAQKFAAAAAQKDB04AAQMbBEgAAQM/AAAAAQMxCKIAAQPFBbgAAQKFAAAAAQKDB04AAQMbBEgAAQM/AAAAAQMxCIkAAQPFBbgAAQKFAAAAAQKDBzUAAQMbBEgAAQKeAAAAAQKYBwYAAQAAAAAAAQN/AAAAAQIxBbQAAQAAAAAAAQAAAAAAAQEhBEgAAQAAAAAAAQJYAAIAAQJUBEgAAQAAAAAAAQMMAAAAAQMAByEAAQAAAAAAAQJSAAAAAQJtBc8AAQAAAAAAAQMZAAAAAQLnBZoAAQAAAAAAAQLbAAAAAQAAAAAAAQVcBfAAAQMZAAAAAQLnBZoAAQAAAAAAAQLbAAAAAQAAAAAAAQVcBfAAAQLJAAAAAQLPCI0AAQAAAAAAAQJoAAAAAQJkBzkAAQAAAAAAAQLJAAAAAQLPCI0AAQAAAAAAAQJoAAAAAQJkBzkAAQAAAAAAAQLJAAAAAQLPByEAAQAAAAAAAQJoAAAAAQJkBc0AAQAAAAAAAQMbAAAAAQMfBwYAAQAAAAAAAQAAAAAAAQKRBbQAAQAAAAAAAQMnAAAAAQM1BZoAAQAAAAAAAQLFAAAAAQExBfAAAQInBEwAAQMnAAAAAQM1BZoAAQAAAAAAAQLFAAAAAQExBfAAAQInBEwAAQE5AAAAAQE5CLwAAQAAAAAAAQAAAAAAAQErB2oAAQAAAAAAAQJvAAAAAQE7BZoAAQNCBZoAAQE3AAAAAQE3BfAAAQJQBfAAAQJvAAAAAQE7BZoAAQNCBZoAAQE3AAAAAQE3BfAAAQJQBfAAAQOwAAAAAQAAAAAAAQAAAAAAAQQ7AAAAAQAAAAAAAQAAAAAAAQMrAAAAAQM7Bx0AAQAAAAAAAQK0AAAAAQLJBcsAAQAAAAAAAQMrAAAAAQM7BZoAAQAAAAAAAQK0AAAAAQLJBEgAAQAAAAAAAQMrAAAAAQM7BZoAAQAAAAAAAQK0AAAAAQLJBEgAAQAAAAAAAQM/AAAAAQMxCLwAAQPFBbgAAQKFAAAAAQKDB2gAAQMbBEgAAQM/AAAAAQMxCNEAAQPFBbgAAQKFAAAAAQKDB30AAQMbBEgAAQM/AAAAAQMxCI0AAQPFBbgAAQKFAAAAAQKDBzkAAQMbBEgAAQM/AAAAAQMxCI0AAQPFBbgAAQKFAAAAAQKDBzkAAQMbBEgAAQLhAAAAAQLdBZoAAQAAAAAAAQEnAAAAAQHsBEgAAQAAAAAAAQLhAAAAAQLdBZoAAQAAAAAAAQEnAAAAAQHsBEgAAQAAAAAAAQKPAAAAAQKaBx0AAQAAAAAAAQHsAAAAAQH8BcsAAQAAAAAAAQKPAAAAAQKaBZoAAQAAAAAAAQHsAAAAAQH8BEgAAQAAAAAAAQKPAAAAAQKaCKQAAQAAAAAAAQHsAAAAAQH8B1IAAQAAAAAAAQKPAAAAAQKaCKIAAQAAAAAAAQHsAAAAAQH8B1AAAQAAAAAAAQKPAAAAAQKaBx0AAQAAAAAAAQHsAAAAAQH8BcsAAQAAAAAAAQJYAAAAAQJtBZoAAQAAAAAAAQH+AAAAAQFYBUgAAQJYBfAAAQJYAAAAAQJtBZoAAQAAAAAAAQH+AAAAAQFYBUgAAQJYBfAAAQMQAAAAAQMOCLwAAQSgBbgAAQKoAAAAAQKPB2oAAQP4BEgAAQMQAAAAAQMOCKIAAQSgBbgAAQKoAAAAAQKPB1AAAQP4BEgAAQQxAAAAAQQxBZoAAQAAAAAAAQAAAAAAAQOmBEgAAQAAAAAAAQQxAAAAAQQxBZoAAQAAAAAAAQAAAAAAAQOmBEgAAQAAAAAAAQQxAAAAAQQxBZoAAQAAAAAAAQAAAAAAAQOmBEgAAQAAAAAAAQKeAAAAAQKYBx0AAQAAAAAAAQN/AAAAAQIxBcsAAQAAAAAAAQKsAAAAAQK0BZoAAQAAAAAAAQIxAAAAAQIzBEgAAQAAAAAAAQH+AAAAAQFYBuMAAQJYBfAAAQL0AAAAAQL+BZoAAQAAAAAAAQJIAAAAAQJYBEgAAQAAAAAAAQL0AAAAAQL6B1oAAQAAAAAAAQJIAAAAAQJUBggAAQAAAAAAAQL0AAAAAQL+BZoAAQAAAAAAAQJIAAAAAQJYBEgAAQAAAAAAAQL0AAAAAQL+BZoAAQAAAAAAAQJIAAAAAQJYBEgAAQAAAAAAAQL0AAAAAQL+BZoAAQAAAAAAAQJIAAAAAQJYBEgAAQAAAAAAAQL0AAAAAQL+BZoAAQAAAAAAAQJIAAAAAQJYBEgAAQAAAAAAAQL0AAAAAQL+BZoAAQAAAAAAAQJIAAAAAQJYBEgAAQAAAAAAAQL0AAAAAQL+BZoAAQAAAAAAAQJIAAAAAQJYBEgAAQAAAAAAAQL0AAAAAQL+BZoAAQAAAAAAAQJIAAAAAQJYBEgAAQAAAAAAAQL0AAAAAQL+BZoAAQAAAAAAAQJIAAAAAQJYBEgAAQAAAAAAAQL0AAAAAQL+BZoAAQAAAAAAAQJIAAAAAQJYBEgAAQAAAAAAAQL0AAAAAQL+BZoAAQAAAAAAAQJIAAAAAQJYBEgAAQAAAAAAAQLJAAAAAQLPBZoAAQAAAAAAAQJoAAAAAQJkBEYAAQAAAAAAAQLJAAAAAQLLB1oAAQAAAAAAAQJoAAAAAQJgBgYAAQAAAAAAAQLJAAAAAQLPBzUAAQAAAAAAAQJoAAAAAQJkBeEAAQAAAAAAAQLJAAAAAQLPBZoAAQAAAAAAAQJoAAAAAQJkBEYAAQAAAAAAAQLJAAAAAQLPBZoAAQAAAAAAAQJoAAAAAQJkBEYAAQAAAAAAAQLJAAAAAQLPBZoAAQAAAAAAAQJoAAAAAQJkBEYAAQAAAAAAAQLJAAAAAQLPBZoAAQAAAAAAAQJoAAAAAQJkBEYAAQAAAAAAAQLJAAAAAQLPBZoAAQAAAAAAAQJoAAAAAQJkBEYAAQAAAAAAAQE5AAAAAQE1B1oAAQAAAAAAAQAAAAAAAQEnBggAAQAAAAAAAQE5AAAAAQE5BZoAAQAAAAAAAQErAAAAAQErBEgAAQAAAAAAAQM/AAAAAQMxBZoAAQPFBbgAAQKFAAAAAQKDBEYAAQMbBEgAAQM/AAAAAQMtB1oAAQPFBbgAAQKFAAAAAQJ/BgYAAQMbBEgAAQM/AAAAAQMxBZoAAQPFBbgAAQKFAAAAAQKDBEYAAQMbBEgAAQM/AAAAAQMxBZoAAQPFBbgAAQKFAAAAAQKDBEYAAQMbBEgAAQM/AAAAAQMxBZoAAQPFBbgAAQKFAAAAAQKDBEYAAQMbBEgAAQM/AAAAAQMxBZoAAQPFBbgAAQKFAAAAAQKDBEYAAQMbBEgAAQM/AAAAAQMxBZoAAQPFBbgAAQKFAAAAAQKDBEYAAQMbBEgAAQM/AAAAAQMxByEAAQPFBbgAAQKFAAAAAQKDBc0AAQMbBEgAAQM/AAAAAQMxByEAAQPFBbgAAQKFAAAAAQKDBc0AAQMbBEgAAQM/AAAAAQMtB1oAAQPFBbgAAQKFAAAAAQJ/BgYAAQMbBEgAAQM/AAAAAQMxBzUAAQPFBbgAAQKFAAAAAQKDBeEAAQMbBEgAAQM/AAAAAQMxBZoAAQPFBbgAAQKFAAAAAQKDBEYAAQMbBEgAAQMQAAAAAQMOBZoAAQSgBbgAAQKoAAAAAQKPBEgAAQP4BEgAAQMQAAAAAQMKB1oAAQSgBbgAAQKoAAAAAQKLBggAAQP4BEgAAQMQAAAAAQMOByEAAQSgBbgAAQKoAAAAAQKYBc8AAQP4BEgAAQMQAAAAAQMOByEAAQSgBbgAAQKoAAAAAQKYBc8AAQP4BEgAAQMQAAAAAQMKB1oAAQSgBbgAAQKoAAAAAQKTBggAAQP4BEgAAQMQAAAAAQMOBzUAAQSgBbgAAQKoAAAAAQKYBeMAAQP4BEgAAQMQAAAAAQMOBZoAAQSgBbgAAQKoAAAAAQKYBEgAAQP4BEgAAQKeAAAAAQKYBZoAAQAAAAAAAQN/AAAAAQIxBEgAAQAAAAAAAQKeAAAAAQKYBZoAAQAAAAAAAQN/AAAAAQIxBEgAAQAAAAAAAQKeAAAAAQKTB1oAAQAAAAAAAQN/AAAAAQItBggAAQAAAAAAAQKeAAAAAQKYBzUAAQAAAAAAAQN/AAAAAQIxBeMAAQAAAAAAAQMQAAAAAQMQBZoAAQAAAAAAAQMQAAAAAQMQBZoAAQAAAAAAAQMQAAAAAQMQBZoAAQAAAAAAAQMQAAAAAQMQBZoAAQAAAAAAAQMQAAAAAQMQBZoAAQAAAAAAAQMQAAAAAQMQBZoAAQAAAAAAAQMQAAAAAQMQBZoAAQAAAAAAAQMQAAAAAQMQBZoAAQAAAAAAAQMQAAAAAQMQBZoAAQAAAAAAAQMQAAAAAQMQBZoAAQAAAAAAAQMQAAAAAQMQBZoAAQAAAAAAAQMQAAAAAQMQBZoAAQAAAAAAAQMQAAAAAQMQBZoAAQAAAAAAAQMQAAAAAQMQBZoAAQAAAAAAAQMQAAAAAQMQByEAAQAAAAAAAQMQAAAAAQMQBZoAAQAAAAAAAQMQAAAAAQMQBZoAAQAAAAAAAQMQAAAAAQMQBZoAAQAAAAAAAQMQAAAAAQMMB1oAAQAAAAAAAQMQAAAAAQMQByEAAQAAAAAAAQMQAAAAAQMQBZoAAQAAAAAAAQMQAAAAAQMQBZoAAQAAAAAAAQMQAAAAAQMQCQIAAQAAAAAAAQMQAAAAAQMQBZoAAQAAAAAAAQjbAAAAAQjjBZoAAQAAAAAAAQhgAAAAAQhqBEgAAQAAAAAAAQKRAAAAAQKgBZoAAQAAAAAAAQKRAAAAAQKgBZoAAQAAAAAAAQKRAAAAAQKgBZoAAQAAAAAAAQKRAAAAAQKgBZoAAQAAAAAAAQKRAAAAAQKgByEAAQAAAAAAAQKRAAAAAQKgBZoAAQAAAAAAAQKRAAAAAQKgBZoAAQAAAAAAAQKRAAAAAQKgBZoAAQAAAAAAAQKRAAAAAQKgBZoAAQAAAAAAAQKRAAAAAQKgBZoAAQAAAAAAAQKRAAAAAQKgBZoAAQAAAAAAAQKRAAAAAQKgByEAAQAAAAAAAQKRAAAAAQKgBZoAAQAAAAAAAQKRAAAAAQKgBZoAAQAAAAAAAQKRAAAAAQKgBZoAAQAAAAAAAQKRAAAAAQKgBZoAAQAAAAAAAQKRAAAAAQKcB1oAAQAAAAAAAQKRAAAAAQKgByEAAQAAAAAAAQKRAAAAAQKgBZoAAQAAAAAAAQKRAAAAAQKgCI0AAQAAAAAAAQKRAAAAAQKgCI0AAQAAAAAAAQKRAAAAAQKgBzUAAQAAAAAAAQMKAAAAAQMKBZoAAQAAAAAAAQMKAAAAAQMKBZoAAQAAAAAAAQMKAAAAAQMKBx8AAQAAAAAAAQMKAAAAAQMKBZoAAQAAAAAAAQMKAAAAAQMKBZoAAQAAAAAAAQMKAAAAAQMKBZoAAQAAAAAAAQMKAAAAAQMKBwYAAQAAAAAAAQH2AAAAAQH2BZoAAQAAAAAAAQH2AAAAAQX+BZoAAQAAAAAAAQH2AAAAAQH2BZoAAQAAAAAAAQE5AAAAAQCFBwoAAQAAAAAAAQH2AAAAAQX+ByEAAQAAAAAAAQH2AAAAAQH2BZoAAQAAAAAAAQH2AAAAAQH2BZoAAQAAAAAAAQH2AAAAAQH2ByEAAQAAAAAAAQH2AAAAAQH2BZoAAQAAAAAAAQH2AAAAAQH2CLwAAQAAAAAAAQH2AAAAAQH2BZoAAQAAAAAAAQH2AAAAAQH2BZoAAQAAAAAAAQH2AAAAAQH2BZoAAQAAAAAAAQH2AAAAAQHyB1oAAQAAAAAAAQH2AAAAAQH2ByEAAQAAAAAAAQH2AAAAAQH2BZoAAQAAAAAAAQH2AAAAAQH2BZoAAQAAAAAAAQH2AAAAAQH2BZoAAQAAAAAAAQAAAAAAAQISBZoAAQAAAAAAAQAAAAAAAQISByEAAQAAAAAAAQJvAAAAAQZmBZoAAQNCBZoAAQTPAAAAAQE5BZoAAQAAAAAAAQTPAAAAAQE5BZoAAQAAAAAAAQMfAAAAAQNtBZoAAQAAAAAAAQMfAAAAAQg3BZoAAQAAAAAAAQMfAAAAAQNtBZoAAQAAAAAAAQMfAAAAAQNtBZoAAQAAAAAAAQMfAAAAAQNtBZoAAQAAAAAAAQMfAAAAAQNtBx0AAQAAAAAAAQMfAAAAAQNtBZoAAQAAAAAAAQMSAAAAAQMZBZoAAQAAAAAAAQMfAAAAAQNtBZoAAQAAAAAAAQMfAAAAAQNtBZoAAQAAAAAAAQMfAAAAAQNtBZoAAQAAAAAAAQM/AAAAAQMxBZoAAQPFBbgAAQKgAAAAAQKmBZoAAQAAAAAAAQKgAAAAAQKmBZoAAQAAAAAAAQKgAAAAAQKmBZoAAQAAAAAAAQKgAAAAAQKmBZoAAQAAAAAAAQKgAAAAAQKmBZoAAQAAAAAAAQKgAAAAAQKmBZoAAQAAAAAAAQLsAAAAAQLTBZoAAQRvBbgAAQLsAAAAAQLTBZoAAQRvBbgAAQLsAAAAAQLTBZoAAQRvBbgAAQLsAAAAAQLTBZoAAQRvBbgAAQLsAAAAAQLTByEAAQRvBbgAAQLsAAAAAQLTBZoAAQRvBbgAAQLsAAAAAQLTBZoAAQRvBbgAAQLsAAAAAQLTBZoAAQRvBbgAAQLsAAAAAQLPB1oAAQRvBbgAAQLsAAAAAQLTBZoAAQRvBbgAAQLsAAAAAQLTByEAAQRvBbgAAQLsAAAAAQLTBZoAAQRvBbgAAQLsAAAAAQLTByEAAQRvBbgAAQLsAAAAAQLPB1oAAQRvBbgAAQLsAAAAAQLTBzUAAQRvBbgAAQLsAAAAAQLTBZoAAQRvBbgAAQLsAAAAAQLTByEAAQRvBbgAAQLsAAAAAQLTBZoAAQRvBbgAAQLsAAAAAQLTCKIAAQRvBbgAAQLsAAAAAQLTBZoAAQRvBbgAAQLsAAAAAQLTBZoAAQRvBbgAAQLsAAAAAQLTBZoAAQRvBbgAAQLsAAAAAQLTCLwAAQRvBbgAAQAAAAAAAQS0BZoAAQAAAAAAAQAAAAAAAQS0BZoAAQAAAAAAAQAAAAAAAQS0BZoAAQAAAAAAAQAAAAAAAQS0BZoAAQAAAAAAAQAAAAAAAQS0BZoAAQAAAAAAAQMG/z0AAQL2BZoAAQAAAAAAAQMG/z0AAQL2BZoAAQAAAAAAAQMG/z0AAQL2BZoAAQAAAAAAAQMG/z0AAQL2BZoAAQAAAAAAAQMG/z0AAQL2Bx0AAQAAAAAAAQMG/z0AAQL2BZoAAQAAAAAAAQMG/z0AAQL2BZoAAQAAAAAAAQMG/z0AAQLyB1oAAQAAAAAAAQMG/z0AAQL2BwYAAQAAAAAAAQMG/z0AAQL2BzUAAQAAAAAAAQKsAAAAAQK0BZoAAQAAAAAAAQKsAAAAAQK0BZoAAQAAAAAAAQKsAAAAAQK0BZoAAQAAAAAAAQKsAAAAAQK0BZoAAQAAAAAAAQKsAAAAAQK0BZoAAQAAAAAAAQKqAAAAAQKwBEgAAQAAAAAAAQKqAAAAAQKwBEgAAQAAAAAAAQKqAAAAAQKwBEgAAQAAAAAAAQKqAAAAAQKwBEgAAQAAAAAAAQKqAAAAAQKwBEgAAQAAAAAAAQKqAAAAAQKwBEgAAQAAAAAAAQKqAAAAAQKwBEgAAQAAAAAAAQKqAAAAAQKwBEgAAQAAAAAAAQKqAAAAAQKwBEgAAQAAAAAAAQKqAAAAAQKwBEgAAQAAAAAAAQKqAAAAAQKwBEgAAQAAAAAAAQKqAAAAAQKwBEgAAQAAAAAAAQKqAAAAAQKwBEgAAQAAAAAAAQKqAAAAAQKwBEgAAQAAAAAAAQKqAAAAAQKwBc8AAQAAAAAAAQKqAAAAAQKwBEgAAQAAAAAAAQKqAAAAAQKwBEgAAQAAAAAAAQKqAAAAAQKwBEgAAQAAAAAAAQKqAAAAAQKsBggAAQAAAAAAAQKqAAAAAQKwBc8AAQAAAAAAAQKqAAAAAQKwBEgAAQAAAAAAAQKqAAAAAQKwBEgAAQAAAAAAAQKqAAAAAQKwBEgAAQAAAAAAAQKqAAAAAQKwB7AAAQAAAAAAAQKqAAAAAQKwBEgAAQAAAAAAAQAAAAAAAQPRBEgAAQAAAAAAAQAAAAAAAQPRBc8AAQAAAAAAAQeoAAAAAQeyBEgAAQVcBfAAAQJvAAAAAQJtBEgAAQAAAAAAAQJvAAAAAQJtBEgAAQAAAAAAAQJvAAAAAQJtBEgAAQAAAAAAAQJvAAAAAQJtBEgAAQAAAAAAAQJvAAAAAQJtBc8AAQAAAAAAAQJvAAAAAQJtBEgAAQAAAAAAAQJvAAAAAQJtBEgAAQAAAAAAAQJvAAAAAQJtBEgAAQAAAAAAAQJvAAAAAQJtBEgAAQAAAAAAAQJvAAAAAQJtBEgAAQAAAAAAAQJvAAAAAQJtBEgAAQAAAAAAAQJvAAAAAQJtBc8AAQAAAAAAAQJvAAAAAQJtBEgAAQAAAAAAAQJvAAAAAQJtBEgAAQAAAAAAAQJvAAAAAQJtBEgAAQAAAAAAAQJvAAAAAQJtBEgAAQAAAAAAAQJvAAAAAQJoBggAAQAAAAAAAQJvAAAAAQJtBc8AAQAAAAAAAQJvAAAAAQJtBEgAAQAAAAAAAQJvAAAAAQJtBzsAAQAAAAAAAQJvAAAAAQJtBzsAAQAAAAAAAQJvAAAAAQJtBeMAAQAAAAAAAQI/AAAAAQI9BEgAAQAAAAAAAQAAAAAAAQNtBc8AAQAAAAAAAQAAAAAAAQErBcsAAQAAAAAAAQFKAAAAAQEZBfAAAQIxBfAAAQFKAAAAAQEZBfAAAQIxBfAAAQFKAAAAAQEZBfAAAQIxBfAAAQFKAAAAAQEZBfAAAQIxBfAAAQFKAAAAAQEZBfAAAQIxBfAAAQFKAAAAAQEZBfAAAQIxBfAAAQFKAAAAAQEZBfAAAQIxBfAAAQFKAAAAAQEZBfAAAQIxBfAAAQGFAAAAAQFUBfAAAQJtBfAAAQdzAAAAAQdzBEgAAQAAAAAAAQHLAAAAAQEQBUgAAQIQBfAAAQGeAAAAAQAAAAAAAQAAAAAAAQHLAAAAAQEQBUgAAQIQBfAAAQHLAAAAAQEQBUgAAQIQBfAAAQHLAAAAAQEQBUgAAQIQBfAAAQHLAAAAAQEQBuMAAQIQBfAAAQHLAAAAAQEQBUgAAQIQBfAAAQHLAAAAAQEQBUgAAQIQBfAAAQAAAAAAAQPlBEgAAQAAAAAAAQAAAAAAAQPlBEgAAQAAAAAAAQAAAAAAAQPlBEgAAQAAAAAAAQAAAAAAAQPlBEgAAQAAAAAAAQAAAAAAAQPlBEgAAQAAAAAAAQVMAAAAAQKYBEgAAQAAAAAAAQVMAAAAAQKYBEgAAQAAAAAAAQVMAAAAAQKYBEgAAQAAAAAAAQVMAAAAAQKYBEgAAQAAAAAAAQVMAAAAAQKYBEgAAQAAAAAAAQVMAAAAAQKYBEgAAQAAAAAAAQVMAAAAAQKTBggAAQAAAAAAAQVMAAAAAQKYBbQAAQAAAAAAAQVMAAAAAQKYBeMAAQAAAAAAAQIxAAAAAQI7BEgAAQAAAAAAAQIxAAAAAQI7BEgAAQAAAAAAAQIxAAAAAQI7BEgAAQAAAAAAAQIxAAAAAQI7BEgAAQAAAAAAAQIxAAAAAQI7BEgAAQAAAAAAAgAiACYAJgAAACgAKgABACwANAAEADYAOgANADwAPAASAD4APwATAEYARgAVAEgASgAWAEwATgAZAFAAVAAcAFcAWgAhAFwAXAAlAF4AXwAmAIQAmgAoAJwAoQA/AKQAswBFALUAugBVALwAxwBbAMoA2wBnAN4A8QB5APQBKQCNASsBNQDDATgBQgDOAUUBgQDZAa8B9wEWAfkCUgFfAqkCvQG5Ar8C2AHOAtoC2gHoAtwDBQHpAwcDBwITAwkDaQIUA2sDbAJ1A24DlAJ3AAIAAgGTAakAAAPSA+AAFwAmAAEAmgABAKAAAQCmAAEArAABALIAAQC4AAEAvgABAMQAAQDKAAEA0AABANYAAQDcAAEA4gABAOgAAQDuAAIA9AAAAPoAAAEAAAABBgAAAQwAAAESAAABGAAAAR4AAgEkAAEBKgABATAAAQE2AAEBPAAAAUIAAgFIAAEBTgABAVQAAQFaAAEBYAABAWYAAQFsAAEBcgABAXgAAQApBEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAf/+BEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAABZoAAQAABEgAAf/+BEgAAQAABEgAAQAABEgAAQAAAAAAAQAABZoAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQAABEgAAQCIAH4AAQCeAAwADgAeACQAKgAwADYAPABCAEgATgBUAFoAYABmAGwAAQApBc8AAQAABc8AAQAABc8AAQAABeMAAQAABbQAAQAABc8AAQAABcsAAQAABeMAAf/6BggAAQAABikAAQAABc8AAQAABc0AAQAABc8AAQAABc8AAgABAZMBoAAAAAIAAwGTAaEAAAPTA9YADwPZA+AAEwAbAAAAbgAAAHQAAAB6AAAAgAAAAIYAAACMAAAAkgAAAJgAAACeAAAApAAAAKoAAACwAAAAtgAAALwAAADCAAAAyAAAAM4AAADUAAAA2gAAAOAAAADmAAAA7AAAAPIAAAD4AAAA/gAAAQQAAAEKAAEAKQRIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAH//gRIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAH//gRIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAEAAARIAAAAAQAAAADVpCcIAAAAANRTKbUAAAAA3hPgAw==') format('truetype');\n    font-weight: 500;\n    font-style: normal;\n    font-display: swap;\n}\n\n"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/calendar_lib.js",
    "content": "/**\n * Notes: 日历组件通用方法\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux@qq.com\n * Date: 2021-01-01 07:48:00 \n */\nconst lunarLib = require('../../../lib/tools/lunar_lib.js');\nconst timeHelper = require('../../../helper/time_helper.js');\nconst dataHelper = require('../../../helper/data_helper.js');\nconst pageHelper = require('../../../helper/page_helper.js');\n\n// 是否节日\nfunction isHoliday(day) {\n\tif (!day) return false;\n\n\tlet arr = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '初', '廿'];\n\tfor (let k = 0; k < arr.length; k++) {\n\t\tif (day.includes(arr[k]))\n\t\t\treturn false;\n\t}\n\treturn true;\n}\n\n// 某天是某月的第几周\nfunction weekIndexInMonth(year = null, month = null, today = null) {\n\tlet time = new Date();\n\n\tif (year == null) { // 没有设定，则取当前\n\t\tyear = time.getFullYear();\n\t\tmonth = time.getMonth();\n\t\ttoday = time.getDate();\n\t} else {\n\t\tyear = Number(year);\n\t\tmonth = Number(month) - 1;\n\t\ttoday = Number(today);\n\t}\n\n\ttime = new Date(year, month, 1); //取第一天\n\n\tlet space = time.getDay() - 1; //获取当前星期X(0-6,0代表星期天)  \n\tif (space == -1) space = 6; //调整为周1-周7格式 \n\n\treturn Math.ceil((today + space) / 7); // 本月第几周\n\n}\n\n// 日期格式化，一位补2位\nfunction fmtDate(str) {\n\tstr = str + '';\n\tif (str.length == 1)\n\t\treturn '0' + str;\n\telse\n\t\treturn str;\n}\n\n// 获取当前时间，若定义了要操作的天, 则取得年份和月份，用以构造日历\nfunction getNowTime(that) {\n\tconst time = new Date();\n\tlet year = time.getFullYear();\n\tlet month = time.getMonth() + 1;\n\tlet week = time.getDay();\n\n\tlet today = time.getDate(); // 今天\n\tlet fullToday = year + '-' + fmtDate(month) + '-' + fmtDate(today); // 今天完整格式\n\n\t// 若定义了要操作的天, 则取得年份和月份，用以构造日历\n\tif (that.data.mode == 'one' && that.data.oneDoDay) {\n\t\tyear = Number(timeHelper.timestamp2Time(timeHelper.time2Timestamp(that.data.oneDoDay), 'Y'));\n\t\tmonth = Number(timeHelper.timestamp2Time(timeHelper.time2Timestamp(that.data.oneDoDay), 'M'));\n\t} else if (that.data.mode == 'multi' && that.data.multiDoDay && that.data.multiDoDay.length > 0 && that.data.multiDoDay[0]) {\n\t\tyear = Number(timeHelper.timestamp2Time(timeHelper.time2Timestamp(that.data.multiDoDay[0]), 'Y'));\n\t\tmonth = Number(timeHelper.timestamp2Time(timeHelper.time2Timestamp(that.data.multiDoDay[0]), 'M'));\n\t}\n\n\tlet oneDoDay = that.data.oneDoDay || fullToday; // 正在操作的天完整格式\n\t// let multiDoDay = that.data.multiDoDay || [oneDoDay];  // 多选默认选中一天\n\tlet multiDoDay = that.data.multiDoDay;\n\n\tthat.setData({\n\t\tyear,\n\t\tmonth,\n\n\t\tfullToday,\n\n\t\toneDoDay,\n\t\tmultiDoDay,\n\t\tweek\n\t});\n}\n//获得某月天数 \nfunction getMonthCnt(year, month) {\n\tlet baseMonthsDay = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; //各月天数\n\tif (month == 2 && year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))\n\t\treturn 29;\n\telse\n\t\treturn baseMonthsDay[month - 1];\n}\n\n//获得上月天数  \nfunction getLastMonthCnt(year, month) {\n\tif (month == 1) {\n\t\tmonth = 12;\n\t\t--year;\n\t} else\n\t\t--month;\n\treturn getMonthCnt(year, month);\n}\n\n//从上月补几天\nfunction getLastMonthArr(that, year, month) {\n\n\tlet time = new Date(year, month - 1, 1);\n\tlet space = time.getDay() - 1; //获取当前星期X(0-6,0代表星期天)  \n\tif (space == -1) space = 6; //调整为周1-周7格式 \n\n\t// 获取上个月天数\n\tlet lastMonthCnt = getLastMonthCnt(year, month);\n\tif (month == 1) {\n\t\tmonth = 12;\n\t\t--year;\n\t} else\n\t\t--month;\n\n\tlet dayArr = [];\n\tfor (let i = space; i >= 1; i--) {\n\t\tlet lunar = that.data.isLunar ? lunarLib.sloarToLunar(year, month, lastMonthCnt - i + 1) : '';\n\t\tlet holiday = isHoliday(lunar);\n\t\tlet full = year + '-' + fmtDate(month) + '-' + fmtDate(lastMonthCnt - i + 1);\n\t\tdayArr.push({\n\t\t\tlunar,\n\t\t\tholiday,\n\t\t\tshow: lastMonthCnt - i + 1,\n\t\t\tcurMonth: false,\n\t\t\tweekNo: 1, //必然第一周\n\t\t\tval: year + '-' + month + '-' + (lastMonthCnt - i + 1),\n\t\t\tfull\n\t\t});\n\t}\n\treturn dayArr;\n\n}\n\n/**\n * //从下月补几天\n * @param {*} year \n * @param {*} month \n * @param {*} hasDayLen  已有多少天\n */\nfunction getNextMonthArr(that, year, month, hasDayLen) {\n\n\tif (that.mode == 'multi') {\n\t\tif (month == 12) {\n\t\t\tmonth = 1;\n\t\t\t++year;\n\t\t} else\n\t\t\tmonth++;\n\n\t\t// 多选统一补成6行\n\t\tlet dayArr = [];\n\t\tfor (let i = 1; i <= (6 * 7 - hasDayLen); i++) {\n\t\t\tlet weekNo = Math.ceil((hasDayLen + i) / 7); // 计算当前是第几周 \n\n\t\t\tlet lunar = that.data.isLunar ? lunarLib.sloarToLunar(year, month, i) : '';\n\t\t\tlet holiday = isHoliday(lunar);\n\t\t\tlet full = year + '-' + fmtDate(month) + '-' + fmtDate(i);\n\t\t\tdayArr.push({\n\t\t\t\tlunar,\n\t\t\t\tholiday,\n\t\t\t\thas: false, //是否有数据\n\t\t\t\tshow: i,\n\t\t\t\tcurMonth: false,\n\t\t\t\tweekNo,\n\t\t\t\tval: year + '-' + month + '-' + i,\n\t\t\t\tfull\n\t\t\t});\n\t\t}\n\t} else {\n\t\t// 单选只把最后一行补齐\n\t\tlet endDay = getMonthCnt(year, month); //最后一天\n\n\t\tlet time = new Date(year, month - 1, endDay);\n\t\tlet space = time.getDay(); //获取当前星期X(0-6,0代表星期天)  \n\t\tspace = 7 - space;\n\t\tif (space == 7) space = 0;\n\n\t\tif (space <= 0) return [];\n\n\t\tif (month == 12) {\n\t\t\tmonth = 1;\n\t\t\t++year;\n\t\t} else\n\t\t\tmonth++;\n\n\t\tlet dayArr = [];\n\t\tfor (let i = 1; i <= space; i++) {\n\t\t\tlet lunar = that.data.isLunar ? lunarLib.sloarToLunar(year, month, i) : '';\n\t\t\tlet holiday = isHoliday(lunar);\n\t\t\tlet full = year + '-' + fmtDate(month) + '-' + fmtDate(i);\n\t\t\tdayArr.push({\n\t\t\t\tlunar,\n\t\t\t\tholiday,\n\t\t\t\tshow: i,\n\t\t\t\tcurMonth: false,\n\t\t\t\tweekNo: that.data.weekNo,\n\t\t\t\tval: year + '-' + month + '-' + i,\n\t\t\t\tfull\n\t\t\t});\n\t\t}\n\t\treturn dayArr;\n\t}\n\n\n\treturn dayArr;\n\n}\n\n\nfunction createDay(that) {\n\t// 创建日历\n\tlet month = that.data.month;\n\tlet year = that.data.year;\n\n\tlet dayArr = [];\n\tlet len = getMonthCnt(year, month);\n\tfor (let i = 1; i <= len; i++) {\n\t\tlet lunar = that.data.isLunar ? lunarLib.sloarToLunar(year, month, i) : '';\n\t\tlet holiday = isHoliday(lunar);\n\t\tlet full = year + '-' + fmtDate(month) + '-' + fmtDate(i) //实际日期(补位);\n\t\tdayArr.push({\n\t\t\tlunar,\n\t\t\tholiday,\n\t\t\thas: false, //是否有数据\n\t\t\tshow: i, // 显示\n\t\t\tcurMonth: true, //是否当前月\n\t\t\tweekNo: weekIndexInMonth(year, month, i), //第几周\n\t\t\tval: year + '-' + month + '-' + i, //实际日期(简化)\n\t\t\tfull\n\t\t});\n\t}\n\n\n\t// 前后补空 \n\tlet lastArr = getLastMonthArr(that, year, month);\n\tlet nextArr = getNextMonthArr(that, year, month, dayArr.length + lastArr.length);\n\n\tlet data = lastArr.concat(dayArr).concat(nextArr);\n\n\t/*\n\t// 数据循环处理\n\tlet hasDays = that.data.hasDays;\n\tif (hasDays.length > 0) {\n\t\tfor (let j in hasDays) {\n\t\t\tfor (let k = 0; k < data.length; k++) {\n\t\t\t\tif (data[k].full == hasDays[j]) {\n\t\t\t\t\tdata[k].has = true; //当日有数据\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}*/\n\n\t// 当前操作日为周几？ 仅针对单选模式\n\tlet weekNo = 0;\n\tif (that.data.mode == 'one') {\n\t\tif (!that.data.oneDoDay) {\n\t\t\tweekNo = weekIndexInMonth();\n\t\t} else {\n\t\t\tlet arr = that.data.oneDoDay.split('-');\n\t\t\tweekNo = weekIndexInMonth(arr[0], arr[1], arr[2]);\n\t\t}\n\t}\n\n\tthat.setData({\n\t\tweekNo,\n\t\tdayArr: data\n\t});\n}\n\n/** ListTouch计算滚动 */\nfunction listTouchEnd(that) {\n\tif (that.data.touchDirection == 'left') {\n\t\tthat.setData({\n\t\t\tanimation: 'slide-left'\n\t\t});\n\n\t\tsetTimeout(function () {\n\t\t\tthat.setData({\n\t\t\t\tanimation: ''\n\t\t\t})\n\t\t}, 200);\n\t\tthat.bindNextTap();\n\t} else if (that.data.touchDirection == 'right') {\n\t\tthat.setData({\n\t\t\tanimation: 'slide-right'\n\t\t});\n\n\t\tsetTimeout(function () {\n\t\t\tthat.setData({\n\t\t\t\tanimation: ''\n\t\t\t})\n\t\t}, 200);\n\t\tthat.bindLastTap();\n\t}\n\n\tthat.setData({\n\t\ttouchDirection: null\n\t});\n}\n\n// 回本月\nfunction bindToNowTap(that) {\n\tconst time = new Date();\n\tlet year = time.getFullYear();\n\tlet month = time.getMonth() + 1;\n\n\tthat.setData({\n\t\tmonth,\n\t\tyear,\n\t\tfold: false\n\t});\n\n\tthat.setData({\n\t\tanimation: 'fade'\n\t});\n\n\tsetTimeout(function () {\n\t\tthat.setData({\n\t\t\tanimation: ''\n\t\t})\n\t}, 300);\n\tcreateDay(that);\n\n\tif (that.data.mode == 'one') {\n\t\t//月份切换引起父组件变动 \n\t\tthat.triggerEvent('monthChange', {\n\t\t\tyearMonth: that.data.year + '-' + dataHelper.padLeft(that.data.month, 2, '0')\n\t\t});\n\t}\n}\n\n//多选天点击\nfunction bindDayMultiTap(e, that) {\n\n\t// 显示\n\tlet oneDoDay = e.currentTarget.dataset.fullday;\n\tlet multiDoDay = dataHelper.deepClone(that.data.multiDoDay);\n\n\tif (that.data.multiOnlyOne) {\n\t\t// 只能选一个\n\t\tmultiDoDay = [oneDoDay];\n\t} else {\n\t\tmultiDoDay = dataHelper.arrAddDel(multiDoDay, oneDoDay);\n\t}\n\tif (multiDoDay.length < that.data.multiDoDay.length) {\n\t\t// 有取消\n\t\tthat.triggerEvent('cancel', {\n\t\t\tday: oneDoDay\n\t\t});\n\t}\n\n\tthat.setData({\n\t\tmultiDoDay\n\t});\n\n\t// 传递给父组件\n\tthat.triggerEvent('click', {\n\t\tdays: multiDoDay\n\t});\n}\n\n//单个天点击\nfunction bindDayOneTap(e, that) {\n\t// 显示\n\tlet oneDoDay = e.currentTarget.dataset.fullday;\n\n\t// 当前周\n\tlet weekNo = 0;\n\tlet arr = oneDoDay.split('-');\n\tweekNo = weekIndexInMonth(arr[0], arr[1], arr[2]);\n\n\tthat.setData({\n\t\toneDoDay,\n\t\tweekNo\n\t});\n\n\t// 传递给父组件\n\tthat.triggerEvent('click', {\n\t\tday: oneDoDay\n\t});\n}\n\n//  下月\nfunction bindNextTap(that) {\n\tlet month = that.data.month;\n\tif (month == 12) {\n\t\tthat.setData({\n\t\t\tyear: that.data.year + 1,\n\t\t\tmonth: 1,\n\t\t\tfold: false //翻页不折叠\n\t\t})\n\t} else {\n\t\tthat.setData({\n\t\t\tmonth: month + 1,\n\t\t\tfold: false\n\t\t})\n\t}\n\tcreateDay(that);\n\n\tif (that.data.mode == 'one') {\n\t\t//月份切换引起父组件变动 \n\t\tthat.triggerEvent('monthChange', {\n\t\t\tyearMonth: that.data.year + '-' + dataHelper.padLeft(that.data.month, 2, '0')\n\t\t});\n\t}\n}\n\n// 上个月\nfunction bindLastTap(that) {\n\tlet month = that.data.month;\n\tif (month == 1) {\n\t\tthat.setData({\n\t\t\tyear: that.data.year - 1,\n\t\t\tmonth: 12,\n\t\t\tfold: false\n\t\t})\n\t} else {\n\t\tthat.setData({\n\t\t\tmonth: month - 1,\n\t\t\tfold: false\n\t\t})\n\t}\n\tcreateDay(that);\n\n\tif (that.data.mode == 'one') {\n\t\t//月份切换引起父组件变动 \n\t\tthat.triggerEvent('monthChange', {\n\t\t\tyearMonth: that.data.year + '-' + dataHelper.padLeft(that.data.month, 2, '0')\n\t\t});\n\t}\n}\n\n// 日历折叠\nfunction bindFoldTap(that) {\n\tif (that.data.fold)\n\t\tthat.setData({\n\t\t\tfold: false\n\t\t});\n\telse {\n\t\t//that._init(); //折叠回本月\n\t\tthat.setData({\n\t\t\tfold: true\n\t\t});\n\t}\n}\n\nmodule.exports = {\n\tisHoliday,\n\tweekIndexInMonth,\n\tfmtDate,\n\tgetNowTime,\n\tgetMonthCnt,\n\tgetLastMonthCnt,\n\tgetLastMonthArr,\n\tgetNextMonthArr,\n\tcreateDay,\n\tlistTouchEnd,\n\tbindToNowTap,\n\tbindDayMultiTap,\n\tbindDayOneTap,\n\tbindNextTap,\n\tbindLastTap,\n\tbindFoldTap\n}"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/calendar_meet/calendar_meet_cmpt.js",
    "content": "const timeHelper = require('../../../../helper/time_helper.js');\nconst pageHelper = require('../../../../helper/page_helper.js');\nconst calendarLib = require('../calendar_lib.js');\n\n/*#### 父组件日历颜色定义*/\n/* 整体颜色 */\n//--calendarPageColor: #F0F4FF;\n/* 加重颜色*/\n//--calendarMainColor: #388AFF;\n/* 加重的亮颜色 用于选中日期的数据小圆点 */\n//--calendarLightColor: #A2C7FF;\n\n\nComponent({\n\toptions: {\n\t\taddGlobalClass: true\n\t},\n\tproperties: {\n\t\tisLunar: { //是否开启农历\n\t\t\ttype: Boolean,\n\t\t\tvalue: false\n\t\t},\n\t\tmode: { // 模式 one/multi\n\t\t\ttype: String,\n\t\t\tvalue: 'one'\n\t\t},\n\n\t\tyear: { // 正在操作的年\n\t\t\ttype: Number,\n\t\t\tvalue: 0\n\t\t},\n\n\t\tmonth: { // 正在操作的月\n\t\t\ttype: Number,\n\t\t\tvalue: 0\n\t\t},\n\t\tfold: { //日历折叠\n\t\t\ttype: Boolean,\n\t\t\tvalue: false\n\t\t},\n\t\tselectTimeout: { //过期时间选择(mode=multi)\n\t\t\ttype: Boolean,\n\t\t\tvalue: true\n\t\t},\n\t\thasDays: { // 过期有数据的日期\n\t\t\ttype: Array,\n\t\t\tvalue: [],\n\t\t\tobserver: function (newVal, oldVal) {\n\t\t\t\tif (newVal.length != oldVal.length) {\n\t\t\t\t\t// TODO 引起加载的时候二次调用 \n\t\t\t\t\t//this._init();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\thasJoinDays: { // 未超期有预约的日期\n\t\t\ttype: Array,\n\t\t\tvalue: [],\n\t\t},\n\t\toneDoDay: { // 正在操作的天  string\n\t\t\ttype: String,\n\t\t\tvalue: null\n\t\t},\n\t\tmultiDoDay: { // 多选模式>正在操作的天 arrary[]\n\t\t\ttype: Array,\n\t\t\tvalue: null,\n\t\t},\n\t\tmultiOnlyOne: { //多选模式>只能选一个\n\t\t\ttype: Boolean,\n\t\t\tvalue: false\n\t\t}\n\t},\n\n\tdata: {\n\t\tweekNo: 0, // 正在操作的那天位于第几周 \n\t\tfullToday: 0, //今天  \n\t\tglow: '', //闪烁效果\n\t},\n\n\tlifetimes: {\n\t\tattached() {\n\t\t\tthis._init();\n\t\t}\n\t},\n\n\tmethods: {\n\t\t_init: function () {\n\t\t\tcalendarLib.getNowTime(this);\n\t\t\tcalendarLib.createDay(this);\n\t\t},\n\n\n\t\tbindFoldTap: function (e) { // 日历折叠\n\t\t\tcalendarLib.bindFoldTap(this);\n\t\t},\n\n\n\t\tbindNextTap(e) { // 下月\n\t\t\tcalendarLib.bindNextTap(this);\n\n\n\t\t\tthis.setData({\n\t\t\t\tglow: 'glow'\n\t\t\t});\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.setData({\n\t\t\t\t\tglow: ''\n\t\t\t\t});\n\t\t\t}, 800);\n\n\t\t},\n\n\t\tbindLastTap(e) { // 上月\n\t\t\tcalendarLib.bindLastTap(this);\n\n\t\t\tthis.setData({\n\t\t\t\tglow: 'glow'\n\t\t\t});\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.setData({\n\t\t\t\t\tglow: ''\n\t\t\t\t});\n\t\t\t}, 300);\n\n\t\t},\n\n\t\tbindDayOneTap(e) { // 单个天点击\n\t\t\tcalendarLib.bindDayOneTap(e, this);\n\t\t},\n\n\t\tbindDayMultiTap(e) { // 多选天点击\n\t\t\tlet day = e.currentTarget.dataset.fullday;\n\n\t\t\t// 过期时间判断\n\t\t\tif (!this.data.selectTimeout) {\n\t\t\t\tlet now = timeHelper.time('Y-M-D');\n\t\t\t\tif (day < now)\n\t\t\t\t\treturn pageHelper.showNoneToast('不能编辑过往的日期');\n\t\t\t}\n\n\t\t\t// 是否有预约判断\n\t\t\tif (this.data.hasJoinDays.includes(day)) {\n\t\t\t\treturn pageHelper.showModal('该日期已有用户预约/预约待审核，不可直接取消；如果确要取消，请先删除有预约的时段');\n\t\t\t}\n\n\n\t\t\tcalendarLib.bindDayMultiTap(e, this);\n\t\t},\n\n\t\tbindToNowTap: function (e) { // 回本月\n\t\t\tcalendarLib.bindToNowTap(this);\n\t\t},\n\n\t\t// ListTouch触摸开始\n\t\tlistTouchStart(e) {\n\t\t\tpageHelper.listTouchStart(e, this);\n\t\t},\n\n\t\t// ListTouch计算方向\n\t\tlistTouchMove(e) {\n\t\t\tpageHelper.listTouchMove(e, this);\n\t\t},\n\n\t\t/** ListTouch计算滚动 */\n\t\tlistTouchEnd: function (e) {\n\t\t\tcalendarLib.listTouchEnd(this);\n\t\t}\n\t}\n})"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/calendar_meet/calendar_meet_cmpt.json",
    "content": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/calendar_meet/calendar_meet_cmpt.wxml",
    "content": "<wxs src=\"../../../../tpls/wxs/tools.wxs\" module=\"tools\" />\n<wxs module=\"utils\">\n\t// 比较操作日期所在月是否当前显示的月\n\tfunction compareYearMonth(oneDoDay, year, month) {\n\t\tvar arr = oneDoDay.split('-');\n\t\treturn arr[0] == year && arr[1] == month;\n\t} \n\n\tmodule.exports = {\n\t\tcompareYearMonth: compareYearMonth,\n\t};\n</wxs>\n<view class=\"cal-container\">\n\t<view bindtap=\"bindLastTap\" class=\"left\"><text class=\"icon-back\"></text></view>\n\t<view class=\"cal-main\">\n\t\t<view class=\"text-center cal-nav\">\n\t\t\t<view class=\"to-now\" bindtap=\"bindToNowTap\">本月</view>\n\t\t\t<view class=\"select-item\">\n\t\t\t\t<!--<view class=\"arrow text-grey\" bindtap=\"bindLastTap\"><text class=\"icon-backwardfill\" /></view>-->\n\t\t\t\t<view class=\"text-lg\">{{year}}年{{month}}月</view>\n\t\t\t\t<!--<view class=\"arrow text-grey\" bindtap=\"bindNextTap\"><text class=\" icon-play_forward_fill\" /></view>-->\n\t\t\t</view>\n\t\t\t<block wx:if=\"{{mode=='one'}}\">\n\t\t\t\t<view wx:if=\"{{!fold}}\" class=\"fold text-grey\" bindtap=\"bindFoldTap\"><text\n\t\t\t\t\t\tclass=\"icon-fold calendar-text\"></text></view>\n\t\t\t\t<view wx:if=\"{{fold}}\" class=\"fold\" bindtap=\"bindFoldTap\"><text class=\"icon-unfold calendar-text\"></text>\n\t\t\t\t</view>\n\t\t\t</block>\n\t\t</view>\n\n\t\t<view class=\"cal-title\">\n\t\t\t<view>一</view>\n\t\t\t<view>二</view>\n\t\t\t<view>三</view>\n\t\t\t<view>四</view>\n\t\t\t<view>五</view>\n\t\t\t<view class=\"text-orange text-bold\">六</view>\n\t\t\t<view class=\"text-red text-bold\">日</view>\n\t\t</view>\n\t\t<view class=\"cal-center {{!fold?'cur':''}}\">\n\t\t\t \n\n\t\t\t<!--多选begin-->\n\t\t\t<view wx:for=\"{{dayArr}}\" wx:if=\"{{mode=='multi'}}\" wx:key=\"key\" data-fullday=\"{{item.full}}\" class=\"cube {{glow}} {{isLunar?'lunar':''}} {{item.full<fullToday?'timeout':''}} {{tools.includes(multiDoDay,item.full)? 'calendar-bg text-white data-checked' : ''}} {{tools.includes(hasDays,item.full)?'data-has':''}} {{tools.includes(hasJoinDays,item.full)?'join-has':''}}\"\n\t\t\t\tbindtap=\"bindDayMultiTap\">\n\t\t\t\t<view\n\t\t\t\t\tclass=\"num-grid {{fullToday==item.full? 'now-day-cur' : ''}} \">\n\t\t\t\t<view\n\t\t\t\t\tclass=\"num {{!item.curMonth? 'text-no-month' : ''}} \"> \n\t\t\t\t\t<text class=\"dd\">{{item.show}}</text>\n\t\t\t\t\t<text wx:if=\"{{isLunar}}\" class=\"lunar {{tools.includes(multiDoDay,item.full)? 'text-white' : ''}} {{item.holiday?'text-red':''}}\" >{{item.lunar}}</text>\n\t\t\t\t</view>\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t\t<!--多选END-->\n\n\t\t</view>\n\n\t</view>\n\t<view bindtap=\"bindNextTap\" class=\"left\"><text class=\"icon-right\"></text></view>\n</view> "
  },
  {
    "path": "miniprogram/cmpts/public/calendar/calendar_meet/calendar_meet_cmpt.wxss",
    "content": "page {\n\n\t/*#### 父组件日历颜色定义*/\n\t/* 整体颜色 */\n\t--calendarPageColor: #F0F4FF;\n\t/* 加重颜色*/\n\t--calendarMainColor: #1F6ED4;\n\t/* 加重的亮颜色 用于选中日期的数据小圆点 */\n\t--calendarLightColor: #A2C7FF;\n}\n\n.calendar-text {\n\tcolor: var(--calendarMainColor) !important\n}\n\n.calendar-bg {\n\tbackground-color: var(--calendarMainColor) !important\n}\n\n.cal-container {\n\twidth: 100%;\n\tpadding-top: 10rpx;\n\tpadding-bottom: 20rpx;\n\tbackground-color: #fff;\n\tdisplay: flex;\n\talign-items: center;\n}\n\n.cal-container .left,\n.cal-container .right {\n\twidth: 70rpx;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tfont-size: 80rpx;\n\theight: 400rpx;\n\tcolor: #888;\n}\n\n.cal-container .cal-nav {\n\tposition: relative;\n\twidth: 100%;\n\tmin-height: 60rpx;\n\tdisplay: flex;\n\tflex-direction: row;\n\tjustify-content: center;\n\talign-items: center;\n\tcolor: #000;\n\tborder-bottom-left-radius: 15rpx;\n\tborder-bottom-right-radius: 15rpx;\n\tfont-size: 32rpx;\n\tfont-weight: bold;\n}\n\n.cal-container .cal-nav .select-item {\n\twidth: 500rpx;\n\tdisplay: flex;\n\tflex-direction: row;\n\tjustify-content: space-around;\n\talign-items: center;\n}\n\n.cal-container .cal-nav .arrow {\n\twidth: 150rpx;\n\tfont-size: 40rpx;\n}\n\n.cal-container .cal-nav .fold {\n\tposition: absolute;\n\tright: 0rpx;\n\twidth: 100rpx;\n\tfont-size: 40rpx;\n\tfont-weight: bold;\n}\n\n.cal-container .cal-nav .to-now {\n\tposition: absolute;\n\tleft: 5rpx;\n\twidth: 100rpx;\n\tfont-size: 30rpx;\n\tcolor: var(--calendarMainColor);\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.cal-main {\n\tflex: 1;\n\tpadding: 10rpx 0rpx 20rpx;\n\tbackground-color: #fcfcfc;\n}\n\n.cal-title {\n\tdisplay: flex;\n\tjustify-content: center;\n}\n\n.cal-title view {\n\twidth: 80rpx;\n\theight: 80rpx;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tcolor: #666;\n}\n\n.cal-center {\n\tdisplay: flex;\n\tflex-direction: row;\n\tflex-wrap: wrap;\n\toverflow: hidden;\n\tjustify-content: center;\n\talign-items: center;\n}\n\n.cal-center.cur {\n\tborder-bottom-right-radius: 0rpx;\n\tborder-bottom-left-radius: 0rpx;\n}\n\n.cal-center .cube {\n\twidth: 80rpx;\n\theight: 80rpx;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tcolor: #333;\n\tborder: 1rpx solid #ccc;\n}\n\n.cal-center .cube.glow {\n\tanimation: glow 300ms linear 1 alternate;\n}\n\n@keyframes glow {\n\t0% {\n\t\tbackground-color: #ececec;\n\t}\n\n\t100% {\n\t\tbackground-color: inherit;\n\t}\n}\n\n.cal-center .cube.lunar {\n\tmargin-bottom: 8rpx;\n}\n\n.cal-center .num-grid {\n\twidth: 100%;\n\theight: 100%;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n}\n\n.cal-center .cube.lunar .num-grid {\n\twidth: 85rpx;\n\theight: 85rpx;\n}\n\n.cal-center .num-grid.now-day-cur {\n\tbackground-color: orange;\n\theight: 60rpx;\n\twidth: 60rpx;\n\tborder-radius: 50%;\n\tcolor: #fff;\n}\n\n.cal-center .num-grid.now-day-cur .text-no-month {\n\tcolor: #fff;\n}\n\n\n.cal-center .num {\n\twidth: 100%;\n\theight: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n\talign-items: center;\n\tfont-size: 30rpx;\n}\n\n.cal-center .num .lunar {\n\tfont-size: 20rpx;\n\tfont-weight: normal;\n\tcolor: #aaa;\n}\n\n.cal-center .text-no-month {\n\tcolor: #aaa;\n}\n\n.cal-center .timeout {\n\tbackground-color: #f2f2f2;\n}\n\n.cal-center .timeout .num-grid {\n\tcolor: #aaa;\n}\n\n/* 当日有数据 */\n.data-has {\n\tposition: relative;\n\tfont-family: \"icon\";\n\tfont-size: inherit;\n\tfont-style: normal;\n}\n\n.data-has::before {\n\tposition: absolute;\n\tcontent: '\\e699';\n\tright: 1rpx;\n\tbottom: 0rpx;\n\tcolor: #999;\n\tfont-size: 22rpx;\n}\n\n.cube.data-checked.data-has::before {\n\tcolor: #fff;\n}\n\n/* 当日有预约 */\n.join-has {\n\tposition: relative;\n\tfont-family: \"icon\";\n\tfont-size: inherit;\n\tfont-style: normal;\n}\n\n.join-has::before {\n\tposition: absolute;\n\tcontent: '\\e6c0';\n\tright: 1rpx;\n\tbottom: 0rpx;\n\tcolor: #999;\n\tfont-size: 24rpx;\n}\n\n.cube.data-checked.join-has::before {\n\tcolor: #fff;\n}\n\n\n\n/* 选中某日 */\n.cube.data-checked {\n\tposition: relative;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tcolor: #fff !important;\n}\n\n.cube.data-checked .text-no-month {\n\tcolor: #fff !important;\n}"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/date_select/date_select_cmpt.js",
    "content": "const dataHelper = require('../../../../helper/data_helper.js');\nconst pageHelper = require('../../../../helper/page_helper.js');\nconst timeHelper = require('../../../../helper/time_helper.js');\n\nComponent({\n\toptions: {\n\t\taddGlobalClass: true\n\t},\n\n\t/**\n\t * 组件的属性列表\n\t */\n\tproperties: {\n\t\tstart: { // 开始日期\n\t\t\ttype: String,\n\t\t\tvalue: '',\n\t\t},\n\t\tend: { // 结束日期\n\t\t\ttype: String,\n\t\t\tvalue: ''\n\t\t},\n\t\tselected: { // 当前选中日期\n\t\t\ttype: String,\n\t\t\tobserver: function (newVal, oldVal) {\n\t\t\t\tif (newVal != oldVal) {\n\t\t\t\t\tlet month = timeHelper.timestamp2Time(timeHelper.time2Timestamp(newVal), 'Y年M月');\n\t\t\t\t\tthis.setData({ month });\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ttoView: {  //跳转到的view\n\t\t\ttype: String,\n\t\t\tval: '',\n\t\t}\n\t},\n\n\t/**\n\t * 组件的初始数据\n\t */\n\tdata: {\n\t\trange: [],\n\t\tmonth: '',\n\t},\n\n\t/**\n\t   * 生命周期方法\n\t   */\n\tlifetimes: {\n\t\tattached: function () { },\n\n\t\tready: function () {\n\t\t\tif (!this.data.selected)\n\t\t\t\tthis.setData({ selected: timeHelper.time('Y-M-D') });\n\t\t\telse\n\t\t\t\tthis.setData({ toView: 'day-' + this.data.selected });\n\t\t\tthis.init();\n\t\t},\n\n\t\tdetached: function () {\n\t\t\t// 在组件实例被从页面节点树移除时执行\n\t\t},\n\n\t},\n\n\t/**\n\t * 组件的方法列表\n\t */\n\tmethods: {\n\t\tinit: function () {\n\t\t\tlet start = this.data.start;\n\t\t\tlet end = this.data.end;\n\t\t\tif (!start) start = timeHelper.time('Y-M-D');\n\t\t\tif (!end) end = timeHelper.time('Y-M-D', 86400 * 15);\n\n\t\t\tlet range = [];\n\t\t\tlet startTime = timeHelper.time2Timestamp(start);\n\t\t\tlet endTime = timeHelper.time2Timestamp(end);\n\n\t\t\tfor (let k = startTime; k <= endTime;) {\n\t\t\t\tlet day = timeHelper.timestamp2Time(k, 'Y-M-D');\n\t\t\t\tlet month = timeHelper.timestamp2Time(k, 'Y年M月');\n\n\t\t\t\tlet node = {\n\t\t\t\t\tday,\n\t\t\t\t\tshow: this._fmtShow(day),\n\t\t\t\t\tweek: this._fmtWeek(day),\n\t\t\t\t\tmonth\n\t\t\t\t}\n\t\t\t\trange.push(node)\n\t\t\t\tk += 86400 * 1000\n\t\t\t}\n\n\t\t\tthis.setData({ range });\n\t\t},\n\n\t\tbindTap: function (e) {\n\n\t\t},\n\t\t_fmtShow: function (day) {\n\t\t\treturn day.split('-')[2];\n\t\t},\n\t\t_fmtWeek: function (day) {\n\t\t\tif (day == timeHelper.time('Y-M-D')) return '今天';\n\t\t\tday = timeHelper.week(day);\n\t\t\tday = day.replace('周', '');\n\t\t\treturn day;\n\t\t},\n\t\tbindTap: function (e) {\n\t\t\tlet selected = pageHelper.dataset(e, 'day');\n\t\t\tlet month = pageHelper.dataset(e, 'month');\n\t\t\tthis.setData({ selected, month });\n\t\t\tthis.triggerEvent('select', selected);\n\t\t}\n\t},\n\n\n})\n"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/date_select/date_select_cmpt.json",
    "content": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/date_select/date_select_cmpt.wxml",
    "content": "<view class=\"date-cmpt\">\n\t<view class=\"month\">{{month||'2022年'}}</view>\n\t<scroll-view scroll-x class=\"date-select\" scroll-into-view=\"{{toView}}\" enable-flex=\"{{true}}\" >\n\t\t<view id=\"day-{{item.day}}\" class=\"item {{item.day == selected ? 'cur' : ''}}\" wx:for=\"{{range}}\" wx:key=\"key\" bindtap='bindTap' data-day=\"{{item.day}}\" data-month=\"{{item.month}}\">\n\t\t\t<view class=\"week\">{{item.week}}</view>\n\t\t\t<view class=\"date\">{{item.show}}</view> \n\t\t</view>\n\t</scroll-view>\n</view>"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/date_select/date_select_cmpt.wxss",
    "content": "@import \"../calendar_comm/din.wxss\";\n\n.date-cmpt {\n\twidth: 100%;\n}\n\n.date-cmpt .month {\n\twidth: 100%;\n\tpadding: 10rpx 15rpx;\n\tfont-size: 32rpx;\n\tcolor: #000;\n\tfont-weight: bold;\n\tfont-family: 'din';\n}\n\n.date-select {\n\twhite-space: nowrap;\n}\n\n.date-select .item {\n\tmargin: 10rpx 10rpx 10rpx 0rpx;\n\ttext-align: center;\n\tfont-size: 24rpx;\n\tline-height: 55rpx;\n\theight: 110rpx;\n\twidth: 85rpx;\n\tborder: 1rpx solid #ddd;\n\tborder-radius: 17rpx;\n\tdisplay: inline-block;\n}\n\n.date-select .item:first-child {\n\tmargin-left: 5rpx;\n}\n\n.date-select .item .date {\n\tfont-size: 32rpx;\n\tcolor: #000;\n\tfont-family: 'din';\n}\n\n.date-select .item .week {\n\tfont-size: 24rpx;\n\tcolor: #666;\n}\n\n.date-select .item.cur {\n\tbackground-color: #f37445;\n}\n\n.date-select .item.cur .week,\n.date-select .item.cur .date {\n\tcolor: #fff;\n}"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/time_select/time_select_cmpt.js",
    "content": "const dataHelper = require('../../../../helper/data_helper.js');\nconst pageHelper = require('../../../../helper/page_helper.js');\nconst timeHelper = require('../../../../helper/time_helper.js');\nComponent({\n\toptions: {\n\t\taddGlobalClass: true\n\t},\n\n\t/**\n\t * 组件的属性列表\n\t */\n\tproperties: {\n\t\tday: {\n\t\t\ttype: String,\n\t\t\tvalue: '',  // 当前日期\n\t\t},\n\t\tstartTimeStep: {\n\t\t\ttype: Number,\n\t\t\tvalue: 0,  // 开始时间，把每天划分为48个时间段\n\t\t},\n\t\tendTimeStep: {\n\t\t\ttype: String,\n\t\t\tvalue: 47,  // 结束时间，把每天划分为48个时间段\n\t\t},\n\t\tused: { // 已选择\n\t\t\ttype: Array,\n\t\t\tvalue: [], // {title,start,end,url=支持true或者跳转地址}\n\t\t},\n\t\tusedPos: { // 已约的标题位置 first / mid\n\t\t\ttype: String,\n\t\t\tvalue: 'first'\n\t\t},\n\t},\n\n\t/**\n\t * 组件的初始数据\n\t */\n\tdata: {\n\t\ttimes: [],  //时间段 48个\n\n\t\tselectedStart: '',\n\t\tselectedEnd: '',\n\t\tselectedEndPoint: '',\n\t},\n\n\t/**\n\t   * 生命周期方法\n\t   */\n\tlifetimes: {\n\t\tattached: function () { },\n\n\t\tready: function () {\n\t\t\tthis.init();\n\t\t},\n\n\t\tdetached: function () {\n\t\t\t// 在组件实例被从页面节点树移除时执行\n\t\t},\n\n\t},\n\n\t/**\n\t * 组件的方法列表\n\t */\n\tmethods: {\n\t\tinit: function () {\n\t\t\tlet now = timeHelper.time('Y-M-D h:m');\n\n\t\t\tlet times = this.data.times;\n\n\t\t\tlet day = this.data.day;\n\t\t\tif (!day) day = timeHelper.time('Y-M-D');\n\t\t\tthis.setData({\n\t\t\t\tday\n\t\t\t});\n\n\n\t\t\t// 初始化\n\t\t\tif (times == 0) {\n\t\t\t\tfor (let k = this.data.startTimeStep; k <= this.data.endTimeStep; k++) {\n\t\t\t\t\tlet start = '';\n\t\t\t\t\tlet end = '';\n\t\t\t\t\tlet title = '';\n\n\t\t\t\t\tlet clock = Math.trunc(k / 2);\n\t\t\t\t\tif (k % 2 == 0) {\n\t\t\t\t\t\tstart = dataHelper.padLeft(clock, 2, '0') + ':00';\n\t\t\t\t\t\tend = dataHelper.padLeft(clock, 2, '0') + ':30';\n\t\t\t\t\t\ttitle = start;\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tstart = dataHelper.padLeft(clock, 2, '0') + ':30';\n\t\t\t\t\t\tend = dataHelper.padLeft(clock + 1, 2, '0') + ':00';\n\t\t\t\t\t\ttitle = '';\n\t\t\t\t\t}\n\t\t\t\t\tif (end == '24:00') end = '23:59';\n\n\t\t\t\t\tlet node = {\n\t\t\t\t\t\tidx: k,\n\t\t\t\t\t\ttitle,\n\t\t\t\t\t\tstart,\n\t\t\t\t\t\tend,\n\t\t\t\t\t\tused: false,\n\t\t\t\t\t\tselected: false,\n\t\t\t\t\t\texpire: (day + ' ' + start < now), //过期时间 \n\t\t\t\t\t}\n\t\t\t\t\ttimes.push(node);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 已约时间段\n\t\t\tfor (let k = 0; k < this.data.used.length; k++) {\n\t\t\t\tlet usedNode = this.data.used[k];\n\n\t\t\t\t// 计算有占有几个时间段\n\t\t\t\tlet usedlen = 0;\n\t\t\t\tfor (let j = 0; j < times.length; j++) {\n\t\t\t\t\tlet node = times[j];\n\t\t\t\t\tif (node.start >= usedNode.start && node.start <= usedNode.end) {\n\t\t\t\t\t\tusedlen++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (usedlen <= 1) usedlen = 2;\n\t\t\t\tusedlen = Math.round(usedlen / 2);\n\n\t\t\t\tif (this.data.usedPos == 'first') usedlen = 1;\n\n\t\t\t\tlet curLen = 0;\n\t\t\t\tfor (let j = 0; j < times.length; j++) {\n\t\t\t\t\tlet node = times[j];\n\t\t\t\t\tif (node.start == usedNode.start) {\n\t\t\t\t\t\tnode.used = usedNode.url || 'no';\n\t\t\t\t\t\tnode.usedFirst = true;\n\n\t\t\t\t\t\tcurLen++;\n\t\t\t\t\t\tif (curLen == usedlen) node.usedText = usedNode.title;\n\t\t\t\t\t}\n\t\t\t\t\telse if (node.start >= usedNode.start && node.start <= usedNode.end) {\n\t\t\t\t\t\tnode.used = usedNode.url || 'no';\n\t\t\t\t\t\tnode.usedFirst = false;\n\n\t\t\t\t\t\tcurLen++;\n\t\t\t\t\t\tif (curLen == usedlen) node.usedText = usedNode.title;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.setData({ times });\n\t\t},\n\n\t\tbindSelectTap: function (e) {\n\t\t\t//  选择\n\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\tlet timeNode = this.data.times[idx];\n\n\t\t\tlet selected = timeNode.start;\n\n\t\t\t// 已选择\n\t\t\tlet used = timeNode.used;\n\t\t\tif (used) {\n\t\t\t\tif (used === true)\n\t\t\t\t\treturn;\n\t\t\t\telse {\n\t\t\t\t\treturn wx.navigateTo({\n\t\t\t\t\t\turl: used,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 过期\n\t\t\tlet expire = timeNode.expire;\n\t\t\tif (expire) return;\n\n\n\t\t\tlet selectedStart = this.data.selectedStart;\n\t\t\tlet selectedEnd = this.data.selectedEnd;\n\n\n\t\t\tlet times = this.data.times;\n\n\t\t\t// 区间内直接干掉\n\t\t\tif (selected >= selectedStart && selected <= selectedEnd) {\n\t\t\t\tselectedStart = '';\n\t\t\t\tselectedEnd = '';\n\t\t\t\tfor (let k = 0; k < times.length; k++) {\n\t\t\t\t\ttimes[k].selected = false;\n\t\t\t\t}\n\t\t\t\tthis.setData({ times, selectedStart, selectedEnd });\n\t\t\t\treturn;\n\t\t\t}\n\n\n\t\t\tif (!selectedStart && !selectedEnd) {\n\t\t\t\tselectedStart = selected;\n\t\t\t\tselectedEnd = selected;\n\t\t\t}\n\n\t\t\tif (selected < selectedStart) selectedStart = selected;\n\t\t\tif (selected > selectedEnd) selectedEnd = selected;\n\n\n\n\t\t\t// 选中 \n\t\t\tfor (let k = 0; k < times.length; k++) {\n\t\t\t\tif (times[k].start >= selectedStart && times[k].start <= selectedEnd) {\n\t\t\t\t\ttimes[k].selected = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 取得结束时间点\n\t\t\tlet selectedEndPoint = '';\n\t\t\tfor (let k = 0; k < times.length; k++) {\n\t\t\t\tif (times[k].start == selectedEnd) {\n\t\t\t\t\tselectedEndPoint = times[k].end;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.setData({ times, selectedStart, selectedEnd, selectedEndPoint });\n\n\t\t},\n\n\t\tbindSumbitTap: function (e) {\n\t\t\tlet start = this.data.selectedStart;\n\t\t\tlet end = this.data.selectedEnd;\n\t\t\tlet endPoint = this.data.selectedEndPoint;\n\t\t\tif (!start || !end || !endPoint) return;\n\n\t\t\tthis.triggerEvent('select', { start, end, endPoint });\n\t\t}\n\t}\n})\n"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/time_select/time_select_cmpt.json",
    "content": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/time_select/time_select_cmpt.wxml",
    "content": "<view class=\"time-table\">\n\t<view class=\"table-inner\">\n\t\t<view class=\"list\">\n\t\t\t<view bindtap=\"bindSelectTap\" class=\"item\" wx:for=\"{{times}}\" wx:key=\"key\" data-idx=\"{{index}}\">\n\t\t\t\t<view class=\"left {{item.title?'top':''}}\">{{item.title}}</view>\n\t\t\t\t<view class=\"right {{item.selected?'selected':''}}  {{item.start==selectedStart?'selected-first':''}} {{item.expire?'expire':''}} {{item.used?'used':''}}  {{item.usedFirst?'used-first':''}} text-cut\">{{item.usedText}}</view>\n\t\t\t</view>\n\t\t</view>\n\t</view>\n</view>\n<view style=\"height: 150rpx;\"></view>\n<view bindtap=\"bindSumbitTap\" wx:if=\"{{selectedStart&&selectedEnd&&selectedEndPoint}}\" class=\"time-submit safe-bottom \">\n\t<view class=\"inner bg-project\">确认预约 ({{selectedStart}}~{{selectedEndPoint}})</view>\n</view>"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/time_select/time_select_cmpt.wxss",
    "content": "@import \"../calendar_comm/din.wxss\";\n\n.time-table {\n\twidth: 100%;\n\tpadding: 0 5rpx;\n}\n\n.time-table .table-inner {\n\twidth: 100%;\n\tfont-size: 28rpx;\n}\n\n\n.time-table .list {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: flex-start;\n\talign-items: flex-start;\n}\n\n.time-table .list .item {\n\tcolor: #000;\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: flex-start;\n\theight: 42rpx;\n\tpadding: 0\n}\n\n.time-table .list .item .left {\n\tbackground-color: #f5fafe;\n\theight: inherit;\n\twidth: 140rpx;\n\ttext-align: center;\n\tpadding-top: 4rpx;\n\tborder-right: 1rpx solid #ddd;\n\tborder-left: 1rpx solid #ddd;\n\tfont-size: 30rpx;\n\tfont-weight: normal !important;\n\tfont-family: 'din';\n}\n\n.time-table .list .item:last-child .left {\n\tborder-bottom: 1rpx solid #ddd;\n}\n\n.time-table .list .item .left.top {\n\tborder-top: 1rpx solid #ddd !important;\n\tborder-bottom: 0 !important;\n}\n\n\n.time-table .list .item .right {\n\tflex: 1;\n\theight: inherit;\n\tborder-right: 1rpx solid #ddd;\n\tborder-top: 1rpx solid #ddd;\n\tbackground-color: #fff;\n\tcolor: #444;\n\tpadding: 0 10rpx;\n\twidth: 100%;\n\ttext-align: center;\n}\n\n.time-table .list .item:last-child .right {\n\tborder-bottom: 1rpx solid #ddd !important;\n}\n\n.time-table .list .item:first-child .right {\n\tborder-top: 1rpx solid #ddd !important;\n}\n\n.time-table .list .item .right.selected {\n\tborder-top: 1rpx solid #dfffd8;\n\tbackground-color: #dfffd8;\n}\n\n.time-table .list .item .right.selected-first {\n\tborder-top: 1rpx solid #ddd !important;\n}\n\n.time-table .list .item .right.expire {\n\tbackground-color: #f5f5f5;\n\tcolor: #999;\n}\n\n.time-table .list .item .right.used,\n.time-table .list .item .right.used-first {\n\tborder-top: 0rpx solid #E0EBFE;\n\tbackground-color: #E0EBFE;\n\tcolor: #f37445;\n\tfont-size: 28rpx;\n\tborder-left: 6rpx solid #1A65FF;\n\ttext-align: left;\n}\n\n.time-table .list .item .right.used-first {\n\tborder-top: 1rpx solid #ddd !important;\n}\n\n.time-submit {\n\twidth: 100%;\n\tposition: fixed;\n\tbottom: 15rpx;\n\tpadding: 20rpx 30rpx;\n\tz-index: 999999;\n}\n\n.time-submit .inner {\n\twidth: 100%;\n\tbackground-color: #999;\n\tfont-size: 36rpx;\n\tborder-radius: 15rpx;\n\tpadding: 15rpx 0;\n\ttext-align: center;\n\tcolor: #fff;\n}"
  },
  {
    "path": "miniprogram/cmpts/public/checkbox/checkbox_cmpt.js",
    "content": "Component({\n\texternalClasses: ['outside-picker-multi-class'],\n\n\t/**\n\t * 组件的属性列表\n\t */\n\tproperties: {\n\t\tsourceData: { //源数组 \n\t\t\ttype: Array,\n\t\t\tvalue: [],\n\t\t},\n\t\t// 默认选中项的值数组  \n\t\titemMulti: {\n\t\t\ttype: Array,\n\t\t\tvalue: [],\n\t\t\tobserver: function (newVal, oldVal) {\n\t\t\t\tif (Array.isArray(newVal) && Array.isArray(oldVal) && JSON.stringify(newVal) != JSON.stringify(oldVal)) {\n\t\t\t\t\tconsole.log('checkbox observer');\n\t\t\t\t\tthis._fixDefaultVal();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tdisabled: { // 是否禁用\n\t\t\ttype: Boolean,\n\t\t\tvalue: false,\n\t\t},\n\t},\n\n\t/**\n\t * 生命周期方法\n\t */\n\tlifetimes: {\n\t\tattached: function () { },\n\n\t\tready: function () {\n\t\t\tthis._fixDefaultVal();\n\t\t},\n\n\t\tdetached: function () {\n\t\t\t// 在组件实例被从页面节点树移除时执行\n\t\t},\n\n\t},\n\n\t/**\n\t * 组件的初始数据\n\t */\n\tdata: {\n\n\t},\n\n\t/**\n\t * 组件的方法列表\n\t */\n\tmethods: {\n\t\tbindChange: function (e) {\n\t\t\tthis.triggerEvent('select', e.detail.value);\n\t\t},\n\n\t\t_fixDefaultVal() { //传入数据不匹配的时候，修正父页面传入的的数组默认值\n\t\t\tif (!Array.isArray(this.data.itemMulti)) {\n\t\t\t\tthis.triggerEvent('select', []);\n\t\t\t}\n\n\t\t\tif (this.data.itemMulti.length == 0) return;\n\n\t\t\tlet ret = [];\n\t\t\tlet sourceData = this.data.sourceData;\n\t\t\tlet itemMulti = this.data.itemMulti;\n\t\t\tfor (let k = 0; k < sourceData.length; k++) {\n\t\t\t\tfor (let j in itemMulti) {\n\t\t\t\t\tif (sourceData[k] == itemMulti[j])\n\t\t\t\t\t\tret.push(itemMulti[j]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.triggerEvent('select', ret);\n\t\t}\n\t}\n})"
  },
  {
    "path": "miniprogram/cmpts/public/checkbox/checkbox_cmpt.json",
    "content": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/checkbox/checkbox_cmpt.wxml",
    "content": "<wxs src=\"../../../tpls/wxs/tools.wxs\" module=\"tools\" /> \n<checkbox-group bindchange=\"bindChange\" class=\"checkbox-group\">\n\t<view class=\"item\" wx:for=\"{{sourceData}}\" wx:key=\"key\"> \n\t\t<label class=\"item-label\">\n\t\t\t<checkbox class=\"item-checkbox\" disabled=\"{{disabled}}\" value=\"{{item}}\" checked=\"{{tools.includes(itemMulti,item)}}\" />\n\t\t\t<text>{{item}}</text>\n\t\t</label>\n\t</view>\n</checkbox-group>"
  },
  {
    "path": "miniprogram/cmpts/public/checkbox/checkbox_cmpt.wxss",
    "content": ".checkbox-group {\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: center;\n\tflex-direction: column;\n\talign-items: center;\n\tpadding: 0rpx 10rpx;\n}\n\n.checkbox-group .item {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: row;\n\tjustify-content: flex-start;\n\talign-items: center;\n\tline-height: 2.1;\n\tmin-height: 70rpx;\n\tborder-bottom: 1rpx solid #eee;\n\tfont-size: 28rpx;\n}\n\n.checkbox-group .item .item-label{\n\twidth: 100%; \n\tdisplay: flex;\n\tflex-direction: row;\n\tjustify-content: flex-start;\n\talign-items: center;\n}\n \n\n.checkbox-group .item:last-child {\n\tborder-bottom: 0;\n}\n\n.checkbox-group .item:nth-child(odd) {\n\tbackground-color: #fcfcfc;\n}\n\n\n.checkbox-group .item .item-checkbox {\n\tmargin-right: 20rpx;\n\tpadding-left: 10rpx; \n} \n"
  },
  {
    "path": "miniprogram/cmpts/public/editor/editor_cmpt.js",
    "content": "const pageHelper = require('../../../helper/page_helper.js');\nconst dataHelper = require('../../../helper/data_helper.js');\nconst cloudHelper = require('../../../helper/cloud_helper.js');\nconst contentCheckHelper = require('../../../helper/content_check_helper.js');\nconst projectSetting = require('../../../setting/setting.js');\n\nComponent({\n\toptions: {\n\t\taddGlobalClass: true\n\t},\n\n\t/**\n\t * 组件的属性列表\n\t */\n\tproperties: {\n\t\tnodeList: { // [{type:'text/img',val:'txt/cloudId'}]\n\t\t\ttype: Array,\n\t\t\tvalue: [{\n\t\t\t\ttype: 'text',\n\t\t\t\tval: ''\n\t\t\t}]\n\t\t},\n\t\tviewMode: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: false,\n\t\t},\n\t\tisView: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: false,\n\t\t},\n\t\tupDirectDir: {\n\t\t\ttype: String,\n\t\t\tvalue: '',\n\t\t}\n\t},\n\n\t/**\n\t * 组件的初始数据\n\t */\n\tdata: {\n\t\tcur: -1,\n\t},\n\n\tlifetimes: {\n\t\tattached: function () { },\n\n\t\tready: function () {\n\n\t\t},\n\n\t\tdetached: function () {\n\t\t\t// 在组件实例被从页面节点树移除时执行\n\t\t},\n\t},\n\n\t/**\n\t * 组件的方法列表\n\t */\n\tmethods: {\n\t\turl: function (e) {\n\t\t\tpageHelper.url(e, this);\n\t\t},\n\t\tsetGlow(cur) {\n\t\t\tthis.setData({\n\t\t\t\tcur\n\t\t\t});\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.setData({\n\t\t\t\t\tcur: -1\n\t\t\t\t});\n\t\t\t}, 1000);\n\t\t},\n\t\tbindAddTextTap: function (e) {\n\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\tlet node = {\n\t\t\t\ttype: 'text',\n\t\t\t\tval: ''\n\t\t\t}\n\t\t\tlet nodeList = this.data.nodeList;\n\t\t\tnodeList.splice(idx + 1, 0, node);\n\t\t\tthis.setData({\n\t\t\t\tnodeList\n\t\t\t});\n\n\t\t\tthis.setGlow(idx + 1);\n\t\t},\n\t\tbindAddImageTap: function (e) {\n\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\tlet that = this;\n\t\t\twx.chooseMedia({\n\t\t\t\tcount: 8,\n\t\t\t\tmediaType: ['image'],\n\t\t\t\tsizeType: ['compressed'],\n\t\t\t\tsourceType: ['album', 'camera'],\n\t\t\t\tsuccess: async res => {\n\t\t\t\t\tlet nodeList = that.data.nodeList;\n\t\t\t\t\tfor (let k = 0; k < res.tempFiles.length; k++) {\n\t\t\t\t\t\tlet path = res.tempFiles[k].tempFilePath;\n\t\t\t\t\t\tlet size = res.tempFiles[k].size;\n\n\t\t\t\t\t\tif (!contentCheckHelper.imgTypeCheck(path)) {\n\t\t\t\t\t\t\twx.hideLoading();\n\t\t\t\t\t\t\treturn pageHelper.showNoneToast('只能上传png、jpg、jpeg格式', 3000);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlet maxSize = 20; //TODO setting\n\t\t\t\t\t\tlet imageMaxSize = 1024 * 1000 * maxSize;\n\t\t\t\t\t\tconsole.log('IMGX SIZE=' + size + 'Byte,' + size / 1024 + 'K');\n\t\t\t\t\t\tif (!contentCheckHelper.imgSizeCheck(size, imageMaxSize)) {\n\t\t\t\t\t\t\twx.hideLoading();\n\t\t\t\t\t\t\treturn pageHelper.showModal('图片大小不能超过 ' + maxSize + '兆');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (!projectSetting.IS_DEMO && this.data.upDirectDir) {\n\t\t\t\t\t\t\twx.showLoading({ title: '上传中' });\n\t\t\t\t\t\t\tpath = await cloudHelper.transTempPicOne(path, this.data.upDirectDir, '', false);\n\t\t\t\t\t\t\twx.hideLoading();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlet node = {\n\t\t\t\t\t\t\ttype: 'img',\n\t\t\t\t\t\t\tval: path\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tnodeList.splice(idx + 1, 0, node);\n\t\t\t\t\t}\n\n\t\t\t\t\tthat.setData({\n\t\t\t\t\t\tnodeList\n\t\t\t\t\t});\n\t\t\t\t\t//that.setGlow(idx + 1);\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\n\t\tbidnDeleteNodeTap: function (e) {\n\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\tlet nodeList = this.data.nodeList;\n\t\t\tif (this.data.nodeList.length == 1) return pageHelper.showNoneToast('至少需要一个内容框');\n\t\t\tnodeList.splice(idx, 1);\n\t\t\tthis.setData({\n\t\t\t\tnodeList\n\t\t\t});\n\t\t},\n\t\tbindUpTap: function (e) {\n\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\tlet nodeList = this.data.nodeList;\n\t\t\tnodeList = dataHelper.arraySwap(nodeList, idx, idx - 1);\n\t\t\tthis.setData({\n\t\t\t\tnodeList\n\t\t\t});\n\t\t\tpageHelper.anchor('editor-node-' + (idx - 1), this);\n\t\t\tthis.setGlow(idx - 1);\n\t\t},\n\t\tbindTopTap: function (e) {\n\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\tlet nodeList = this.data.nodeList;\n\t\t\tnodeList = dataHelper.arrayTop(nodeList, idx);\n\t\t\tthis.setData({\n\t\t\t\tnodeList\n\t\t\t});\n\t\t\tpageHelper.anchor('editor-node-0', this);\n\t\t\tthis.setGlow(0);\n\t\t},\n\t\tbindBottomTap: function (e) {\n\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\tlet nodeList = this.data.nodeList;\n\t\t\tnodeList = dataHelper.arrayBottom(nodeList, idx);\n\t\t\tthis.setData({\n\t\t\t\tnodeList\n\t\t\t});\n\t\t\tpageHelper.anchor('editor-node-' + (nodeList.length - 1), this);\n\t\t\tthis.setGlow(nodeList.length - 1);\n\t\t},\n\t\tbindDownTap: function (e) {\n\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\tlet nodeList = this.data.nodeList;\n\t\t\tnodeList = dataHelper.arraySwap(nodeList, idx, idx + 1);\n\t\t\tthis.setData({\n\t\t\t\tnodeList\n\t\t\t});\n\t\t\tpageHelper.anchor('editor-node-' + (idx + 1), this);\n\t\t\tthis.setGlow(idx + 1);\n\t\t},\n\n\t\tbindTextareaInput: function (e) {\n\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\tlet nodeList = this.data.nodeList;\n\t\t\tlet node = nodeList[idx];\n\t\t\tif (node.type == 'text') {\n\t\t\t\tnode.val = e.detail.value;\n\t\t\t\tnodeList[idx] = node;\n\t\t\t\t/*\n\t\t\t\tthis.setData({\n\t\t\t\t\tnodeList\n\t\t\t\t});*/\n\t\t\t}\n\t\t},\n\t\tgetNodeList: function (e) {\n\t\t\tlet nodeList = this.data.nodeList;\n\n\t\t\t// 校验是否填写了内容\n\t\t\tlet imgCnt = 0;\n\t\t\tlet textCnt = 0;\n\t\t\tfor (let k = 0; k < nodeList.length; k++) {\n\t\t\t\tif (nodeList[k].type == 'img' && nodeList[k].val.trim() != '') imgCnt++;\n\t\t\t\tif (nodeList[k].type == 'text' && nodeList[k].val.trim() != '') textCnt++;\n\t\t\t}\n\t\t\tif ((imgCnt + textCnt) == 0) {\n\t\t\t\treturn [];\n\t\t\t}\n\n\t\t\treturn this.data.nodeList;\n\t\t},\n\t}\n})"
  },
  {
    "path": "miniprogram/cmpts/public/editor/editor_cmpt.json",
    "content": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/editor/editor_cmpt.wxml",
    "content": "<view class=\"editor-tab\" wx:if=\"{{viewMode}}\">\n\t<button catchtap=\"url\" data-type=\"bool\" data-url=\"isView\" class=\"btn round {{!isView?'bg-blue':'bg-grey light'}}  margin-right-xs\">编辑</button>\n\t<button catchtap=\"url\" data-type=\"bool\" data-url=\"isView\" class=\"btn {{isView?'bg-blue':'bg-grey light'}} round\">预览</button>\n</view>\n\n<view enableBackToTop scrollY class=\"editor-wrapper\" style=\"min-height: 400px;{{viewMode?'margin-top:50rpx':''}}\">\n\t<block wx:for=\"{{nodeList}}\" wx:for-item=\"node\" wx:key=\"index\">\n\t\t<view class=\"editor-node-wrapper {{cur==index?'cur':''}} {{isView?'is-view':''}}\">\n\t\t\t<textarea disabled=\"{{isView}}\" id=\"editor-node-{{index}}\" wx:if=\"{{node.type==='text'}}\" auto-height=\"true\" cursor-spacing=\"60\" bindinput=\"bindTextareaInput\" class=\"editor-textarea\" data-idx=\"{{index}}\" maxlength=\"-1\" value=\"{{node.val}}\"></textarea>\n\t\t\t<image bindtap=\"url\" data-type=\"image\" data-url=\"{{node.val}}\"  id=\"editor-node-{{index}}\" wx:if=\"{{node.type==='img'}}\" mode=\"widthFix\" class=\"loading editor-image\" src=\"{{node.val}}\" lazy-load=\"true\"></image>\n\n\t\t\t<view class=\"editor-delete\" wx:if=\"{{!isView}}\">\n\t\t\t\t<!--<view bindtap=\"bindTopTap\" class=\"iconfont icon-top\" data-idx=\"{{index}}\" wx:if=\"{{index>1}}\"></view>-->\n\t\t\t\t<view bindtap=\"bindUpTap\" class=\"iconfont icon-refresharrow up\" data-idx=\"{{index}}\" wx:if=\"{{index>0}}\"></view>\n\t\t\t\t<view bindtap=\"bindDownTap\" class=\"iconfont icon-refresharrow\" data-idx=\"{{index}}\" wx:if=\"{{index<nodeList.length-1}}\"></view>\n\t\t\t\t<!--<view bindtap=\"bindBottomTap\" class=\"iconfont icon-down\" data-idx=\"{{index}}\" wx:if=\"{{index<(nodeList.length-2)}}\"></view>-->\n\t\t\t\t<view bindtap=\"bidnDeleteNodeTap\" class=\"iconfont icon-delete\" data-idx=\"{{index}}\"></view>\n\t\t\t</view>\n\t\t</view>\n\t\t<view class=\"editor-add-wrapper\" wx:if=\"{{!isView}}\">\n\t\t\t<view bindtap=\"bindAddTextTap\" data-idx=\"{{index}}\" class=\"editor-add-wrapper-view\"><text class=\"icon-roundadd margin-right-xs\"></text>添加文本</view>\n\t\t\t<view bindtap=\"bindAddImageTap\" data-idx=\"{{index}}\" class=\"editor-add-wrapper-view\"><text class=\"icon-pic margin-right-xs\"></text>添加图片</view>\n\t\t</view>\n\t</block>\n</view>"
  },
  {
    "path": "miniprogram/cmpts/public/editor/editor_cmpt.wxss",
    "content": ".editor-tab {\n\twidth: 100%;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tposition: fixed;\n\ttop: 0;\n\tz-index: 999;\n\tline-height: 3;\n\theight: 70rpx;\n\tmargin-top: 40rpx;\n}\n\n\n.editor-tab .item.cur::after {\n\twidth: 100%;\n\tposition: absolute;\n\tbottom: 10rpx;\n\tleft: 0rpx;\n\theight: 6rpx;\n\tcontent: '';\n\tbackground-color: #ff5858;\n}\n\n.iconfont {\n\tfont-size: 32rpx;\n\tfont-style: normal;\n}\n\n.editor-wrapper {\n\tpadding: 30rpx;\n\tbox-sizing: border-box;\n}\n\n.editor-add-wrapper {\n\tdisplay: flex;\n\tflex-direction: row;\n\talign-items: center;\n\tmargin: 0 auto;\n\tfont-size: 30rpx;\n\twidth: 100%;\n\tjustify-content: center;\n}\n\n.editor-add-wrapper .editor-add-wrapper-view {\n\twidth: 250rpx;\n\tline-height: 2;\n\ttext-align: center;\n}\n\n.editor-add-wrapper .iconfont {\n\tpadding: 20rpx;\n\tcolor: #666;\n\tfont-size: 48rpx;\n\tbox-sizing: border-box;\n}\n\n.editor-node-wrapper {\n\tposition: relative;\n\twidth: 100%;\n\tmargin-top: 10rpx;\n\tmargin-bottom: 10rpx;\n\tborder: 1rpx dashed #999;\n\tbackground: #fff;\n}\n\n.editor-node-wrapper.is-view {\n\tborder: 1rpx solid #fff;\n\tborder-radius: 10rpx;\n}\n\n.editor-node-wrapper.cur {\n\tanimation: glow 800ms ease-out infinite alternate;\n}\n\n@keyframes glow {\n\t0% {\n\t\tbox-shadow: 0 0 5px rgba(252, 94, 94, .2), inset 0 0 5px rgba(252, 94, 94, .1), 0 0px 0 #d70c19;\n\t}\n\n\t100% {\n\t\tborder-color: #d70c19;\n\t\tbox-shadow: 0 0 20px rgba(252, 94, 94, .6), inset 0 0 10px rgba(252, 94, 94, .4), 0 0px 0 #d70c19;\n\t}\n}\n\n.editor-delete {\n\tposition: absolute;\n\tz-index: 999;\n\tdisplay: flex;\n\ttext-align: center;\n\talign-items: center;\n\tjustify-content: center;\n\ttop: -30rpx;\n\tright: 0rpx;\n\tcolor: #999;\n\tbackground: hsla(0, 0%, 100%, .95);\n\tborder-radius: 40rpx;\n\tpadding: 15rpx;\n\tbox-shadow: 0 0 5px rgba(0, 0, 0, .1);\n}\n\n.editor-delete .iconfont {\n\tpadding: 0 20rpx;\n}\n\n.editor-wrapper .editor-node-wrapper .editor-textarea {\n\tmargin: 0;\n\tdisplay: block;\n\twidth: 100%;\n\tline-height: 1.5;\n\tpadding: 35rpx 20rpx 20rpx;\n\tmin-height: 240rpx;\n\tfont-size: 32rpx;\n}\n\n.editor-images {\n\tdisplay: flex;\n\tflex-direction: row;\n\tflex-wrap: wrap;\n\twidth: 656rpx;\n\tborder: 2rpx solid #e4e7ed;\n\tbackground: #fff;\n\tpadding: 20rpx;\n\tmin-height: 2.5em;\n}\n\n.editor-images .item-image {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tmargin: 5rpx;\n\twidth: 150rpx;\n\theight: 150rpx;\n\tbox-sizing: border-box;\n}\n\n.editor-images .editor-images-add {\n\tborder: 4rpx dashed #c0c4cc;\n\tcolor: #c0c4cc;\n}\n\n.editor-image {\n\tdisplay: block;\n\twidth: 100%;\n}"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_set/field/form_set_field.js",
    "content": "const pageHelper = require('../../../../../helper/page_helper.js');\nconst dataHelper = require('../../../../../helper/data_helper.js');\nconst helper = require('../../../../../helper/helper.js');\nconst formSetHelper = require('../../form_set_helper.js');\n\nlet _parentFormSet = null;\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tindex: -1, // 父页面索引 -1则为新加\n\n\t\ttypeOptions: formSetHelper.getTypeOptions(),\n\t\tonlySetOptions: formSetHelper.getOnlySetOptions(),\n\t\tmaxOptions: dataHelper.getSelectOptions('0=0个字,1=1个字,2=2个字,3=3个字,4=4个字,5=5个字,6=6个字,7=7个字,8=8个字,9=9个字,10=10个字,11=11个字,12=12个字,13=13个字,14=14个字,15=15个字,15=15个字,16=16个字,17=17个字,18=18个字,19=19个字,20=20个字,25=25个字,30=30个字,40=40个字,50=50个字,100=100个字,200=200个字,500=500个字,1000=1000个字,2000=2000个字'),\n\t\tminOptions: dataHelper.getSelectOptions('0=0个字,1=1个字,2=2个字,3=3个字,4=4个字,5=5个字,6=6个字,7=7个字,8=8个字,9=9个字,10=10个字,11=11个字,12=12个字,13=13个字,14=14个字,15=15个字,15=15个字,16=16个字,17=17个字,18=18个字,19=19个字,20=20个字,25=25个字,30=30个字,40=40个字,50=50个字,100=100个字,200=200个字,500=500个字'),\n\n\t\tcheckBoxLimitOptions: dataHelper.getSelectOptions('0=0项,1=1项,2=2项,3=3项,4=4项,5=5项,6=6项,7=7项,8=8项,9=9项,10=10项,11=11项,12=12项,13=13项,14=14项,15=15项,16=16项,17=17项,18=18项,19=19项,20=20项'),\n\n\t\tonlySetDesc: '',\n\n\t\t// 基本属性\n\t\tformMark: '',\n\t\tformType: 'text',\n\t\tformTitle: '',\n\t\tformDesc: '',\n\t\tformMust: true,\n\t\tformMax: 50,\n\t\tformMin: 0,\n\t\tformOnlySet: {\n\t\t\tmode: 'all',\n\t\t\tcnt: -1\n\t\t},\n\n\t\t// type=select\n\t\tformSelectOptions: ['', ''],\n\n\n\t\t// type=checkbox\n\t\tformCheckBoxLimit: 2,\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: function (options) {\n\t\tthis.setData({\n\t\t\tformMark: formSetHelper.mark(),\n\t\t\tonlySetDesc: formSetHelper.getOnlySetDesc(this.data.formOnlySet)\n\t\t});\n\n\t\tlet parent = pageHelper.getPrevPage(2);\n\t\tif (!parent) return;\n\t\t_parentFormSet = parent.selectComponent(\"#form-set\");\n\n\t\tif (options && helper.isDefined(options.idx)) {\n\t\t\tlet index = options.idx;\n\n\t\t\tlet fields = _parentFormSet.get();\n\t\t\tlet node = fields[index];\n\n\t\t\tif (!node.mark) node.mark = formSetHelper.mark();\n\n\t\t\tthis.setData({\n\t\t\t\tindex,\n\t\t\t\tformMark: node.mark,\n\t\t\t\tformType: node.type,\n\t\t\t\tformTitle: node.title,\n\t\t\t\tformDesc: node.desc,\n\t\t\t\tformMust: node.must,\n\t\t\t\tformMax: node.max,\n\t\t\t\tformMin: node.min,\n\t\t\t\tformOnlySet: node.onlySet,\n\t\t\t\tformSelectOptions: node.selectOptions,\n\t\t\t\tformCheckBoxLimit: node.checkBoxLimit,\n\n\t\t\t\tonlySetDesc: formSetHelper.getOnlySetDesc(node.onlySet)\n\t\t\t});\n\n\t\t\twx.setNavigationBarTitle({\n\t\t\t\ttitle: '字段编辑',\n\t\t\t});\n\n\t\t}\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t// 重复次数\n\tbindOnlySetCmpt: function (e) {\n\t\tlet formOnlySet = {};\n\t\tformOnlySet.mode = e.detail[0];\n\t\tformOnlySet.cnt = e.detail[1];\n\t\tthis.setData({\n\t\t\tformOnlySet,\n\t\t\tonlySetDesc: formSetHelper.getOnlySetDesc(formOnlySet)\n\t\t});\n\t},\n\n\tbindDelTap: function (e) {\n\t\tif (this.data.index == -1) return;\n\n\t\tlet callback = () => {\n\t\t\tlet fields = _parentFormSet.get();\n\t\t\tfields.splice(this.data.index, 1);\n\t\t\t_parentFormSet.set(fields);\n\t\t\twx.navigateBack();\n\t\t}\n\n\t\tpageHelper.showConfirm('确定要删除当前字段吗？', callback);\n\t},\n\n\tbindSubmitTap: function (e) {\n\t\tif (this.data.formTitle.length < 1) return pageHelper.showModal('字段名称必填哦');\n\t\tif (this.data.formTitle.length > 60) return pageHelper.showModal('字段名称必不能超过60个字');\n\n\t\tif (this.data.formDesc.length > 30) return pageHelper.showModal('填写说明不能超过30个字');\n\n\t\tif (this.data.formType.length < 1) return pageHelper.showModal('字段填写类型必须选择哦');\n\t\tlet formType = this.data.formType;\n\n\t\tif (formType == 'select' || formType == 'checkbox') {\n\t\t\t// 下拉框\n\t\t\tlet formSelectOptions = this.data.formSelectOptions;\n\n\t\t\tfor (let k = 0; k < formSelectOptions.length; k++) {\n\t\t\t\tif (formSelectOptions[k].length < 1) {\n\t\t\t\t\treturn pageHelper.showModal('选项' + (Number(k) + 1) + '还没填哦');\n\t\t\t\t}\n\n\t\t\t\tif (formSelectOptions[k].length > 30) {\n\t\t\t\t\treturn pageHelper.showModal('选项' + (Number(k) + 1) + '不能超过30个字，精简一点!');\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.data.formMax = 50;\n\t\t\tthis.data.formMin = 0;\n\n\t\t\tif (formType == 'select') this.data.formCheckBoxLimit = 2;\n\n\t\t} else if (formType == 'mobile') {\n\t\t\t//非本类型的排除\n\t\t\tthis.data.formSelectOptions = ['', ''];\n\t\t\tthis.data.formCheckBoxLimit = 2;\n\t\t\tthis.data.formMax = 11;\n\t\t\tthis.data.formMin = 11;\n\t\t} else {\n\t\t\t//非本类型的排除\n\t\t\tthis.data.formSelectOptions = ['', ''];\n\t\t\tthis.data.formCheckBoxLimit = 2;\n\n\t\t\tif (formType != 'text' && formType != 'textarea' && formType != 'int' && formType != 'digit') {\n\t\t\t\tthis.data.formMax = 50;\n\t\t\t\tthis.data.formMin = 0;\n\t\t\t}\n\t\t}\n\n\t\tlet parent = pageHelper.getPrevPage(2);\n\t\tif (!parent) return;\n\n\t\tlet fields = _parentFormSet.get();\n\n\n\t\tlet node = {\n\t\t\tmark: this.data.formMark,\n\t\t\ttitle: this.data.formTitle,\n\t\t\tdesc: this.data.formDesc,\n\t\t\ttype: this.data.formType,\n\t\t\tmust: this.data.formMust,\n\t\t\tmax: Number(this.data.formMax),\n\t\t\tmin: Number(this.data.formMin),\n\t\t\tonlySet: this.data.formOnlySet,\n\t\t\tselectOptions: this.data.formSelectOptions,\n\t\t\tcheckBoxLimit: Number(this.data.formCheckBoxLimit),\n\t\t};\n\n\n\t\tnode = formSetHelper.initFieldOne(node);\n\t\tif (this.data.index == -1) {\n\t\t\tfields.push(node); //新的\n\t\t} else {\n\t\t\tfields[this.data.index] = node; //修改的\n\t\t}\n\n\t\t_parentFormSet.set(fields);\n\t\twx.navigateBack();\n\t},\n\n\tswitchModel: function (e) {\n\t\tpageHelper.switchModel(this, e, 'bool');\n\t},\n\n\tbindSelectOptionsBlur: function (e) {\n\t\t// 多选项目的输入\n\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\tlet val = e.detail.value.trim();\n\t\tlet formSelectOptions = this.data.formSelectOptions;\n\t\tformSelectOptions[idx] = val;\n\t\t/*\n\t\tthis.setData({\n\t\t\tformSelectOptions\n\t\t});*/\n\t},\n\n\tbindDelSelectOptionsTap: function (e) {\n\t\tlet formSelectOptions = this.data.formSelectOptions;\n\t\tif (formSelectOptions.length <= 2) return pageHelper.showModal('至少2个选项');\n\n\n\t\tlet callback = () => {\n\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\tformSelectOptions.splice(idx, 1);\n\t\t\tthis.setData({\n\t\t\t\tformSelectOptions\n\t\t\t});\n\t\t}\n\n\t\tpageHelper.showConfirm('确定删除该项吗？', callback);\n\t},\n\n\tbindAddSelectOptionsTap: function (e) {\n\t\tlet formSelectOptions = this.data.formSelectOptions;\n\t\tif (formSelectOptions.length >= 20) return pageHelper.showModal('最多可以添加20个选项');\n\n\t\tformSelectOptions.push('');\n\t\tthis.setData({\n\t\t\tformSelectOptions\n\t\t});\n\t}\n\n})"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_set/field/form_set_field.json",
    "content": "{\n\t\"usingComponents\": { \n\t\t\"cmpt-picker-multi\": \"/cmpts/public/picker_multi/picker_multi_cmpt\"\n\t},\n\t\"navigationBarBackgroundColor\": \"#ffffff\",\n\t\"navigationBarTextStyle\": \"black\",\n\t\"enablePullDownRefresh\": true,\n\t\"backgroundTextStyle\": \"dark\",\n\t\"navigationBarTitleText\": \"后台-字段添加\"\n}"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_set/field/form_set_field.wxml",
    "content": "<view class=\"main\">\n\t<form>\n\t\t<view class=\"form-box shadow\">\n\t\t\t<view class=\"form-group\">\n\t\t\t\t<view class=\"title must\">字段名称</view>\n\t\t\t\t<input placeholder=\"请输入字段名称 (必填，60字以内)\" maxlength=\"60\" placeholder-class=\"phc\" model:value=\"{{formTitle}}\"></input>\n\t\t\t</view>\n\n\t\t</view>\n\n\t\t<view class=\"form-box shadow\">\n\t\t\t<view class=\"form-group\">\n\t\t\t\t<view class=\"title must\">是否必填<text class=\"title-info\">(为空时不能提交)</text></view>\n\t\t\t\t<switch wx:if=\"{{formMust}}\" bindchange=\"switchModel\" data-item=\"formMust\" class=\"green sm\" checked=\"true\">\n\t\t\t\t</switch>\n\t\t\t\t<switch wx:elif=\"{{!formMust}}\" bindchange=\"switchModel\" data-item=\"formMust\" class=\"green sm\"></switch>\n\t\t\t</view>\n\n\t\t\t<view class=\"form-group\">\n\t\t\t\t<view class=\"title must\">字段填写类型</view>\n\t\t\t\t<cmpt-picker style=\"flex:1\" model:item=\"{{formType}}\" sourceData=\"{{typeOptions}}\" />\n\t\t\t</view>\n\n\t\t\t<block wx:if=\"{{formType=='text'||formType=='textarea'||formType=='int'||formType=='digit'}}\">\n\t\t\t\t<view class=\"form-group\">\n\t\t\t\t\t<view class=\"title must\">最小需填字数</view>\n\t\t\t\t\t<cmpt-picker style=\"flex:1\" model:item=\"{{formMin}}\" sourceData=\"{{minOptions}}\" />\n\t\t\t\t</view>\n\t\t\t\t<view class=\"form-group\">\n\t\t\t\t\t<view class=\"title must\">最大可填字数</view>\n\t\t\t\t\t<cmpt-picker style=\"flex:1\" model:item=\"{{formMax}}\" sourceData=\"{{maxOptions}}\" />\n\t\t\t\t</view>\n\t\t\t</block>\n\n\n\t\t\t<!-- select begin -->\n\t\t\t<block wx:if=\"{{formType=='select'||formType=='checkbox'}}\">\n\t\t\t\t<view class=\"form-group\">\n\t\t\t\t\t<view class=\"title must\" wx:if=\"{{formType=='select'}}\">单项选择-选项配置</view>\n\t\t\t\t\t<view class=\"title must\" wx:if=\"{{formType=='checkbox'}}\">多项选择-选项配置</view>\n\t\t\t\t</view>\n\n\t\t\t\t<view class=\"form-group\" wx:for=\"{{formSelectOptions}}\" wx:key=\"key\">\n\t\t\t\t\t<input bindinput='bindSelectOptionsBlur' data-idx=\"{{index}}\" placeholder=\"请输入选项{{index+1}} （30字以内)\" maxlength=\"30\" placeholder-class=\"phc\" value=\"{{item}}\"></input><text bindtap=\"bindDelSelectOptionsTap\" data-idx=\"{{index}}\" class=\"icon-roundclose margin-left-xs text-red select-close\"></text>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"form-group\" bindtap=\"bindAddSelectOptionsTap\">\n\t\t\t\t\t<view class=\"title text-blue\" style=\"font-weight:normal;font-size:30rpx;\"> <text class=\"icon-roundadd margin-right-s  select-close\" style=\"font-size:35rpx;\"></text>添加新选项\n\t\t\t\t\t</view>\n\n\t\t\t\t</view>\n\t\t\t</block>\n\n\t\t\t<view wx:if=\"{{formType=='checkbox'}}\" class=\"form-group\">\n\t\t\t\t<view class=\"title must\">多项选择-最少选中项数</view>\n\t\t\t\t<cmpt-picker style=\"flex:1\" model:item=\"{{formCheckBoxLimit}}\" sourceData=\"{{checkBoxLimitOptions}}\" />\n\t\t\t</view>\n\t\t\t<!-- select END -->\n\n\n\t\t</view>\n\n\t\t<view class=\"form-box shadow\">\n\t\t\t<view class=\"form-group\">\n\t\t\t\t<view class=\"title\">填写说明 <text class=\"text-grey text-normal\">(选填)</text></view>\n\t\t\t</view>\n\t\t\t<view class=\"form-group\">\n\t\t\t\t<input placeholder=\"提示用户该字段如何填写 (选填，30字以内)\" maxlength=\"30\" placeholder-class=\"phc\" model:value=\"{{formDesc}}\"></input>\n\t\t\t</view>\n\t\t\t<view wx:if=\"{{formDescFocus}}\" class=\"hint-desc error\">{{formDescFocus}}</view>\n\n\t\t</view>\n\n\t\t<view class=\"padding-bottom flex  {{index==-1?'flex-direction':'oprt'}}\">\n\t\t\t<button wx:if=\"{{index>-1}}\" bindtap=\"bindDelTap\" class=\"btn bg-red margin-top-s text-bold large\">删除</button>\n\t\t\t<button bindtap=\"bindSubmitTap\" class=\"btn bg-blue text-white margin-top-s text-bold large\">保存</button>\n\t\t</view>\n\n\n\t</form>\n\n</view>"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_set/field/form_set_field.wxss",
    "content": ".main {\n\tmargin-bottom: 150rpx;\n}\n\n.oprt {\n\tdisplay: flex;\n\twidth: 100%;\n\tjustify-content: space-around;\n}\n\n.oprt button {\n\twidth: 45%;\n}\n\n.select-close {\n\twidth: 60rpx;\n\tfont-size: 40rpx !important;\n\tfont-weight: bold;\n\ttext-align: right;\n}\n\n.title-desc {\n\tpadding-left: 24rpx;\n\tcolor: #aaa;\n\tpadding-bottom: 30rpx;\n\tborder-bottom: 1rpx solid #eee;\n}\n\n.title-info {\n\tmargin-left: 4rpx;\n\tcolor: #aaa;\n\tfont-weight: normal;\n\tfont-size: 24rpx;\n}"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_set/form_set_cmpt.js",
    "content": "const pageHelper = require('../../../../helper/page_helper.js');\nconst dataHelper = require('../../../../helper/data_helper.js');\n\nComponent({\n\toptions: {\n\t\taddGlobalClass: true\n\t},\n\n\t/**\n\t * 组件的属性列表\n\t */\n\tproperties: {\n\t\tfields: {\n\t\t\ttype: Array,\n\t\t\tvalue: [],\n\t\t},\n\t},\n\n\t/**\n\t * 组件的初始数据\n\t */\n\tdata: {\n\t\tcur: -1,\n\t},\n\n\t/**\n\t * 生命周期方法\n\t */\n\tlifetimes: {\n\t\tattached: function () {\n\n\t\t},\n\n\t\tready: function () {\n\n\n\t\t},\n\n\t\tdetached: function () {\n\t\t\t// 在组件实例被从页面节点树移除时执行\n\t\t},\n\t},\n\n\t/**\n\t * 组件的方法列表\n\t */\n\tmethods: {\n\t\tsetGlow(cur) {\n\t\t\tthis.setData({\n\t\t\t\tcur\n\t\t\t});\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.setData({\n\t\t\t\t\tcur: -1\n\t\t\t\t});\n\t\t\t}, 800);\n\t\t},\n\n\t\turl: function (e) {\n\t\t\tpageHelper.url(e, this);\n\t\t},\n\n\t\tset: function (fields) {\n\t\t\tthis.setData({\n\t\t\t\tfields\n\t\t\t});\n\t\t\tthis.triggerEvent('formset', fields);\n\t\t},\n\n\t\tget: function () {\n\t\t\treturn this.data.fields;\n\t\t},\n\n\t\tbindEditTap: function (e) {\n\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\tlet edit = pageHelper.dataset(e, 'edit'); \n\t\t\tif (!edit) {\n\t\t\t\treturn pageHelper.showNoneToast('该字段不可编辑和删除');\n\t\t\t}\n\t\t\twx.navigateTo({\n\t\t\t\turl: '/cmpts/public/form/form_set/field/form_set_field?idx=' + idx,\n\t\t\t});\n\t\t},\n\t\tbindUpTap: function (e) {\n\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\tlet fields = this.data.fields;\n\t\t\tdataHelper.arraySwap(fields, idx, idx - 1);\n\t\t\tthis.setData({\n\t\t\t\tfields\n\t\t\t});\n\t\t\tthis.setGlow(idx - 1);\n\t\t\tthis.triggerEvent('formset', fields);\n\t\t},\n\n\t\tbindDownTap: function (e) {\n\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\tlet fields = this.data.fields;\n\t\t\tdataHelper.arraySwap(fields, idx, idx + 1);\n\t\t\tthis.setData({\n\t\t\t\tfields\n\t\t\t});\n\t\t\tthis.setGlow(idx + 1);\n\t\t\tthis.triggerEvent('formset', fields);\n\t\t}\n\t}\n})"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_set/form_set_cmpt.json",
    "content": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_set/form_set_cmpt.wxml",
    "content": "<view class=\"form-group arrow {{cur==index?'cur':''}}\" hoverClass=\"form-group-active\" wx:for=\"{{fields}}\" wx:key=\"key\" style=\"padding-left:10rpx\">\n\t<view class=\"field-oprt\">\n\t\t<view bindtap=\"bindUpTap\" wx:if=\"{{index>0}}\" data-idx=\"{{index}}\"><text class=\"icon-refresharrow up\"></text></view>\n\t\t<view bindtap=\"bindDownTap\" wx:if=\"{{index<fields.length-1}}\" data-idx=\"{{index}}\"><text class=\"icon-refresharrow\"></text></view>  \n\t</view>\n\t\t\t\t\t\t\t\n\t<view class=\"title text-cut\" bindtap=\"bindEditTap\"  data-edit=\"{{item.edit}}\" data-idx=\"{{index}}\"> \n\t\t{{item.title}}\n\t</view>\n\t<view class=\"picker-set text-cut\" bindtap=\"bindEditTap\" data-edit=\"{{item.edit}}\" data-idx=\"{{index}}\">\n\t \n\t\t<text wx:if=\"{{item.type=='text'}}\">单行文本，</text>\n\t\t<text wx:elif=\"{{item.type=='date'}}\">日期，</text>\n\t\t<text wx:elif=\"{{item.type=='hourminute'}}\">时间点，</text>\n\t\t<text wx:elif=\"{{item.type=='select'}}\">单项选择，</text>\n\t\t<text wx:elif=\"{{item.type=='checkbox'}}\">多项选择，</text>\n\t\t<text wx:elif=\"{{item.type=='switch'}}\">开关选择，</text>  \n\t\t<text wx:elif=\"{{item.type=='area'}}\">省市区，</text> \n\t\t<text wx:elif=\"{{item.type=='textarea'}}\">多行文本，</text> \n\t\t<text wx:elif=\"{{item.type=='year'}}\">年份，</text> \n\t\t<text wx:elif=\"{{item.type=='month'}}\">月份，</text> \n\t\t<text wx:elif=\"{{item.type=='int'}}\">整数数字，</text> \n\t\t<text wx:elif=\"{{item.type=='digit'}}\">小数数字，</text> \n\t\t<text wx:elif=\"{{item.type=='idcard'}}\">身份证，</text> \n\t\t<text wx:elif=\"{{item.type=='mobile'}}\">手机，</text> \n\t\t\n\t\t<text wx:if=\"{{item.must}}\">必填</text>\n\t\t<text wx:else>选填</text>\n\t</view>\n</view>\n\n<view class=\"form-group\" bindtap=\"url\" data-url=\"/cmpts/public/form/form_set/field/form_set_field\">\n\t<view class=\"title text-cut text-blue text-bold\">\n\t\t<text class=\"icon-roundadd margin-right-xs\"></text>添加新字段\n\t</view>\n</view>"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_set/form_set_cmpt.wxss",
    "content": ".picker-set {\n\tline-height: 100rpx;\n\tfont-size: 24rpx;\n\twidth: 100%;\n\ttext-align: right;\n\tcolor: #999;\n\twidth: 210rpx;\n}\n \n.form-group .picker-set {\n\tpadding-right: 40rpx;\n\toverflow: hidden;\n\tposition: relative;\n}\n\n.form-group.cur {\n\tanimation: glow 800ms linear 1 alternate;\n} \n \n@keyframes glow { \n\t0% {\n\t\tbackground-color: #ececec;\n\t} \n\t100% {\n\t\tbackground-color: #fff;\n\t}\n}\n\n.form-group-active{\n\tbackground-color: #ececec;\n}\n\n.form-group .title {\n\tfont-weight: normal;\n\tcolor: #333;\n\tflex: 1;\n\tpadding-right: 10rpx;\n}\n\n.form-group .field-oprt {\n\tcolor: #777;\n\tbackground: hsla(0, 0%, 100%, .95);\n\tborder-radius: 5rpx; \n\tbox-shadow: 0 0 5px rgba(0, 0, 0, .1); \n\tdisplay: flex;\n\ttext-align: center;\n\talign-items: center;\n\tjustify-content: center;\n\tmargin-right: 15rpx; \n}\n\n.form-group .field-oprt>view{\n\twidth:70rpx;\n\theight:55rpx;\n\tdisplay: flex;\n\ttext-align: center;\n\talign-items: center;\n\tjustify-content: center;\n\tfont-size:36rpx;\n} \n"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_set_helper.js",
    "content": "/**\n * 配置格式\n * mark\n * title:\n * type:\n * desc: \n * min:\n * max:\n * must:\n * checkBoxLimit:2\n * onlySet:{mode:'all',cnt:-1}\n * selectOptions:['',''] \n * def\n */\nconst dataHelper = require('../../../helper/data_helper.js');\nconst pageHelper = require('../../../helper/page_helper.js');\nconst helper = require('../../../helper/helper.js');\nconst validate = require('../../../helper/validate.js');\n\nfunction initFieldOne(field) {\n\treturn initFields([field])[0];\n}\n\nfunction initFields(defaultFields = null) {\n\tlet fields = dataHelper.deepClone(defaultFields);\n\tif (fields && Array.isArray(fields)) {\n\t\tfor (let k = 0; k < fields.length; k++) {\n\t\t\tlet curForm = fields[k];\n\t\t\t// 补充编号\n\t\t\tif (!curForm['mark']) curForm['mark'] = mark();\n \n\t\t\tif (!helper.isDefined(curForm['type'])) curForm['type'] = 'text';\n\t\t\tif (!helper.isDefined(curForm['title'])) curForm['title'] = '姓名';\n\t\t\tif (!helper.isDefined(curForm['desc'])) curForm['desc'] = '';\n\t\t\tif (!helper.isDefined(curForm['must'])) curForm['must'] = false;\n\t\t\tif (!helper.isDefined(curForm['def'])) curForm['def'] = null; //默认值\n\t\t\tif (!helper.isDefined(curForm['edit'])) curForm['edit'] = true; //是否可编辑删除\n \n\t\t\t// 默认长度\n\t\t\tlet max = 50;\n\t\t\tlet min = 0;\n\t\t\tswitch (fields[k].type) {\n\t\t\t\tcase 'textarea':\n\t\t\t\t\tmax = 500;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'image':\n\t\t\t\t\tmax = 8;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'digit':\n\t\t\t\tcase 'int':\n\t\t\t\t\tmax = 10;\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// 长度\n\t\t\tif (!helper.isDefined(curForm['max'])) curForm['max'] = max;\n\t\t\tif (!helper.isDefined(curForm['min'])) curForm['min'] = min;\n\n\t\t\t// 固定长度\n\t\t\tif (helper.isDefined(curForm['len'])) {\n\t\t\t\tcurForm['max'] = curForm['len'];\n\t\t\t\tcurForm['min'] = curForm['len'];\n\t\t\t\tdelete curForm['len'];\n\t\t\t}\n\n\t\t\t// 图片张数不超过8\n\t\t\tif (fields[k].type == 'image') {\n\t\t\t\tif (curForm['max'] > 8) curForm['max'] = 8;\n\t\t\t\tif (curForm['min'] > 8) curForm['min'] = 8;\n\t\t\t}\n\n\t\t\tif (fields[k].type == 'mobile') {\n\t\t\t\tcurForm['max'] = 11;\n\t\t\t\tcurForm['min'] = 11;\n\t\t\t}\n\n\t\t\t// 唯一性\n\t\t\tif (!helper.isDefined(curForm['onlySet'])) curForm['onlySet'] = {\n\t\t\t\tmode: 'all',\n\t\t\t\tcnt: -1\n\t\t\t};\n\n\t\t\t// 可选项\n\t\t\tif (!helper.isDefined(curForm['selectOptions'])) {\n\t\t\t\tif (fields[k].type == 'select' || fields[k].type == 'checkbox' || fields[k].type == 'radio')\n\t\t\t\t\tcurForm['selectOptions'] = ['是', '否'];\n\t\t\t\telse\n\t\t\t\t\tcurForm['selectOptions'] = ['', ''];\n\t\t\t} \n\t\t\t \n\t\t\t\n\t\t\tif (!helper.isDefined(curForm['checkBoxLimit'])) curForm['checkBoxLimit'] = 2;\n\t\t}\n\t}\n\n\treturn fields || [\n\t\t{\n\t\t\tmark: mark(),\n\t\t\ttype: 'text',\n\t\t\ttitle: '姓名',\n\t\t\tdesc: '您的姓名',\n\t\t\tmust: true,\n\t\t\tmin: 0,\n\t\t\tmax: 30,\n\t\t\tonlySet: {\n\t\t\t\tmode: 'all',\n\t\t\t\tcnt: -1\n\t\t\t},\n\t\t\tselectOptions: ['', ''], \n\t\t\tcheckBoxLimit: 2,\n\t\t\tdef: null,\n\t\t\tedit:false\n\t\t},\n\t];\n}\n\n\n// 函数参数必须是字符串，因为二代身份证号码是十八位，而在javascript中，十八位的数值会超出计算范围，造成不精确的结果，导致最后两位和计算的值不一致，从而该函数出现错误。\n// 详情查看javascript的数值范围\nfunction checkIDCard(idcode) {\n\tif (idcode.length != 18) return false;\n\n\t// 加权因子\n\tvar weight_factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];\n\t// 校验码\n\tvar check_code = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];\n\n\tvar code = idcode + \"\";\n\tvar last = idcode[17]; //最后一位\n\n\tvar seventeen = code.substring(0, 17);\n\n\t// ISO 7064:1983.MOD 11-2\n\t// 判断最后一位校验码是否正确\n\tvar arr = seventeen.split(\"\");\n\tvar len = arr.length;\n\tvar num = 0;\n\tfor (var i = 0; i < len; i++) {\n\t\tnum = num + arr[i] * weight_factor[i];\n\t}\n\n\t// 获取余数\n\tvar resisue = num % 11;\n\tvar last_no = check_code[resisue];\n\n\t// 格式的正则\n\t// 正则思路\n\t/*\n\t第一位不可能是0\n\t第二位到第六位可以是0-9\n\t第七位到第十位是年份，所以七八位为19或者20\n\t十一位和十二位是月份，这两位是01-12之间的数值\n\t十三位和十四位是日期，是从01-31之间的数值\n\t十五，十六，十七都是数字0-9\n\t十八位可能是数字0-9，也可能是X\n\t*/\n\tvar idcard_patter = /^[1-9][0-9]{5}([1][9][0-9]{2}|[2][0][0|1][0-9])([0][1-9]|[1][0|1|2])([0][1-9]|[1|2][0-9]|[3][0|1])[0-9]{3}([0-9]|[X])$/;\n\n\t// 判断格式是否正确\n\tvar format = idcard_patter.test(idcode);\n\n\t// 返回验证结果，校验码和格式同时正确才算是合法的身份证号码\n\treturn last === last_no && format ? true : false;\n}\n\n// 必填提示\nfunction getMustHint(type) {\n\tif (type == 'image') return '请上传';\n\n\tlet arr = ['select', 'date', 'month', 'hourminute', 'time', 'checkbox', 'radio','switch', 'area'];\n\tif (arr.includes(type))\n\t\treturn '请选择';\n\telse\n\t\treturn '请填写';\n}\n\n// form 数据校验\nfunction checkForm(fields, forms, that) {\n\tfor (let k = 0; k < fields.length; k++) {\n\t\tdelete fields[k].focus;\n\t}\n\n\tfor (let k = 0; k < fields.length; k++) {\n\t\tlet type = fields[k].type;\n\t\tlet title = '「' + fields[k].title + '」';\n\t\tlet val = forms[k].val;\n\n\t\t// 必填\n\t\tlet hintOprt = getMustHint(type); //提示动作\n\n\t\tif (fields[k].must && type != 'switch' && (!helper.isDefined(val) || val.length == 0)) {\n\t\t\tfields[k].focus = hintOprt + title;\n\t\t\tpageHelper.anchor('form' + forms[k].mark, that);\n\t\t\treturn pageHelper.showModal(hintOprt + '' + title);\n\t\t}\n\n\t\t// 填写后，字符串最大长度 \n\t\tif (val.length > 0 && (type == 'text' || type == 'textarea' || type == 'int' || type == 'digit')) {\n\t\t\tif (fields[k].max == fields[k].min) {\n\t\t\t\tlet len = fields[k].max;\n\t\t\t\tif (val.length != len) {\n\t\t\t\t\tfields[k].focus = title + ' 字数必须为' + len + '位';\n\t\t\t\t\tpageHelper.anchor('form' + forms[k].mark, that);\n\t\t\t\t\treturn pageHelper.showModal(title + ' 字数必须为' + len + '位');\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif (val.length > fields[k].max) {\n\t\t\t\t\tfields[k].focus = title + ' 字数不能多于' + fields[k].max + '位';\n\t\t\t\t\tpageHelper.anchor('form' + forms[k].mark, that);\n\t\t\t\t\treturn pageHelper.showModal(title + ' 字数不能多于' + fields[k].max + '位');\n\t\t\t\t}\n\n\t\t\t\tif (val.length < fields[k].min) {\n\t\t\t\t\tfields[k].focus = title + ' 字数不能少于' + fields[k].min + '位';\n\t\t\t\t\tpageHelper.anchor('form' + forms[k].mark, that);\n\t\t\t\t\treturn pageHelper.showModal(title + ' 字数不能少于' + fields[k].min + '位');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// 传图后，字符串最大长度 \n\t\tif (val.length > 0 && (type == 'image')) {\n\t\t\tif (fields[k].max == fields[k].min) {\n\t\t\t\tlet len = fields[k].max;\n\t\t\t\tif (val.length != len) {\n\t\t\t\t\tfields[k].focus = title + ' 张数必须为' + len + '张';\n\t\t\t\t\tpageHelper.anchor('form' + forms[k].mark, that);\n\t\t\t\t\treturn pageHelper.showModal(title + ' 张数必须为' + len + '张');\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif (val.length > fields[k].max) {\n\t\t\t\t\tfields[k].focus = title + ' 张数不能多于' + fields[k].max + '张';\n\t\t\t\t\tpageHelper.anchor('form' + forms[k].mark, that);\n\t\t\t\t\treturn pageHelper.showModal(title + ' 张数不能多于' + fields[k].max + '张');\n\t\t\t\t}\n\n\t\t\t\tif (val.length < fields[k].min) {\n\t\t\t\t\tfields[k].focus = title + ' 张数不能少于' + fields[k].min + '张';\n\t\t\t\t\tpageHelper.anchor('form' + forms[k].mark, that);\n\t\t\t\t\treturn pageHelper.showModal(title + ' 张数不能少于' + fields[k].min + '张');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\n\t\tswitch (type) {\n\t\t\tcase 'tag': { // 标签格式化\n\t\t\t\tforms[k].val = dataHelper.fmtTag(val);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'mobile': {\n\t\t\t\tif (val.length > 0 && val.length != 11) {\n\t\t\t\t\tfields[k].focus = '请填写正确的 ' + title;\n\t\t\t\t\tpageHelper.anchor('form' + forms[k].mark, that);\n\t\t\t\t\treturn pageHelper.showModal('请填写正确的 ' + title);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'switch': {\n\t\t\t\t// TODO 是否要做判断\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'idcard': {\n\t\t\t\tif (val.length > 0 && !checkIDCard(val)) {\n\t\t\t\t\tfields[k].focus = '请填写正确的 ' + title;\n\t\t\t\t\tpageHelper.anchor('form' + forms[k].mark, that);\n\t\t\t\t\treturn pageHelper.showModal('请填写正确的 ' + title);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'checkbox': {\n\t\t\t\tif (val.length > 0 && val.length < fields[k].checkBoxLimit) {\n\t\t\t\t\tfields[k].focus = title + ' 至少选中' + fields[k].checkBoxLimit + '项';\n\t\t\t\t\tpageHelper.anchor('form' + forms[k].mark, that);\n\t\t\t\t\treturn pageHelper.showModal(title + ' 至少选中' + fields[k].checkBoxLimit + '项');\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'date': {\n\t\t\t\tif (validate.checkDate(val)) {\n\t\t\t\t\tfields[k].focus = '请填写正确的 ' + title;\n\t\t\t\t\tpageHelper.anchor('form' + forms[k].mark, that);\n\t\t\t\t\treturn pageHelper.showModal('请填写正确的 ' + title);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'year': {\n\t\t\t\tif (validate.checkYear(val)) {\n\t\t\t\t\tfields[k].focus = '请填写正确的 ' + title;\n\t\t\t\t\tpageHelper.anchor('form' + forms[k].mark, that);\n\t\t\t\t\treturn pageHelper.showModal('请填写正确的 ' + title);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'month': {\n\t\t\t\tif (validate.checkYearMonth(val)) {\n\t\t\t\t\tfields[k].focus = '请填写正确的 ' + title;\n\t\t\t\t\tpageHelper.anchor('form' + forms[k].mark, that);\n\t\t\t\t\treturn pageHelper.showModal('请填写正确的 ' + title);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'hourminute': {\n\t\t\t\tif (validate.checkHourMinute(val)) {\n\t\t\t\t\tfields[k].focus = '请填写正确的 ' + title;\n\t\t\t\t\tpageHelper.anchor('form' + forms[k].mark, that);\n\t\t\t\t\treturn pageHelper.showModal('请填写正确的 ' + title);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'int': {\n\t\t\t\tif (validate.checkInt(val)) {\n\t\t\t\t\tfields[k].focus = title + '必须为数字';\n\t\t\t\t\treturn pageHelper.showModal(title + '必须为数字');\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'digit': {\n\t\t\t\tif (validate.checkDigit(val)) {\n\t\t\t\t\tfields[k].focus = title + '必须为数字或小数';\n\t\t\t\t\treturn pageHelper.showModal(title + '必须为数字或小数');\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t}\n\treturn true;\n}\n\nfunction mark() {\n\treturn dataHelper.genRandomAlpha(10).toUpperCase();\n};\n\nfunction getTypeOptions() {\n\t//return dataHelper.getSelectOptions('text=单行文本,select=单项选择,checkbox=多项选择,switch=开关选择,textarea=多行文本,idcard=身份证号码,mobile=手机号码,date=日期 (年 月 日),month=月份,year=年份,hourminute=时间点,area=省市区,int=整数数字,digit=带小数点的数字');\n\n\treturn dataHelper.getSelectOptions('text=单行文本,select=单项选择,checkbox=多项选择,switch=开关选择,textarea=多行文本,idcard=身份证号码,date=日期 (年 月 日),month=月份,year=年份,hourminute=时间点,area=省市区,int=整数数字,digit=带小数点的数字');\n}\n\n// 重复性规则\nfunction getOnlySetOptions() {\n\tlet mode = dataHelper.getSelectOptions('all=本项目全程重复次数,clock=按每一时段限制重复次数,day=按每天限制重复次数');\n\n\tlet list = [];\n\tfor (let k = 0; k < mode.length; k++) {\n\t\tlet node = {};\n\t\tnode.label = mode[k].label;\n\t\tnode.val = mode[k].val;\n\n\t\tlet children = [];\n\t\tif (k == 0) {\n\t\t\tchildren.push({\n\t\t\t\tlabel: '不限制重复次数',\n\t\t\t\tval: -1\n\t\t\t});\n\t\t}\n\t\tfor (let j = 1; j <= 30; j++) {\n\t\t\tlet childNode = {};\n\t\t\tif (j == 1)\n\t\t\t\tchildNode.label = '仅可填写' + j + '次';\n\t\t\telse\n\t\t\t\tchildNode.label = '可重复' + j + '次';\n\t\t\tchildNode.val = j\n\t\t\tchildren.push(childNode);\n\t\t}\n\n\t\tnode.children = children;\n\n\t\tlist.push(node);\n\t}\n\n\treturn list;\n}\n\n// 重复性规则的表述\nfunction getOnlySetDesc(rule) {\n\tlet ret = '';\n\tswitch (rule.mode) {\n\t\tcase 'all':\n\t\t\tret = rule.cnt > 0 ? '本项目全程可重复' + rule.cnt + '次' : '本项目全程不限制重复次数';\n\t\t\tbreak;\n\t\tcase 'day':\n\t\t\tret = '每天可重复' + rule.cnt + '次';\n\t\t\tbreak;\n\t\tcase 'clock':\n\t\t\tret = '每一时段可重复' + rule.cnt + '次';\n\t\t\tbreak;\n\t}\n\tif (rule.cnt == 1) ret = ret.replace(/可重复/g, '仅可填写');\n\treturn ret;\n}\n\nmodule.exports = {\n\tcheckForm,\n\tmark,\n\n\tinitFieldOne,\n\tinitFields,\n\n\tgetTypeOptions,\n\n\tgetOnlySetOptions,\n\tgetOnlySetDesc\n}"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_show/content/form_show_content.js",
    "content": "const pageHelper = require('../../../../../helper/page_helper.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tformContent: [{\n\t\t\ttype: 'text',\n\t\t\tval: '',\n\t\t}]\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\n\t\tlet parent = pageHelper.getPrevPage(2);\n\t\tif (!parent) return;\n\n\t\tif (!options) return;\n\n\t\tif (!options.cmptId || !options.cmptFormName) return;\n\t\tlet cmptId = '#' + options.cmptId;\n\t\tlet cmptFormName = options.cmptFormName;\n\n\t\tlet formContent = parent.selectComponent(cmptId).getOneFormVal(cmptFormName);\n\n\t\tif (formContent.length == 0) {\n\t\t\tformContent = [{ type: 'text', val: '' }];\n\t\t}\n\n\t\tthis.setData({\n\t\t\tcmptId,\n\t\t\tcmptFormName,\n\n\t\t\tformContent\n\t\t});\n\n\t\tlet curPage = pageHelper.getPrevPage(1);\n\t\tif (!curPage) return;\n\t\tif (curPage.options && curPage.options.source == 'admin') {\n\t\t\twx.setNavigationBarColor({ //管理端顶部\n\t\t\t\tbackgroundColor: '#2499f2',\n\t\t\t\tfrontColor: '#ffffff',\n\t\t\t});\n\t\t}\n\n\t},\n\n\n\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\n\t},\n\n\tmodel: function (e) {\n\t\tpageHelper.model(this, e);\n\t},\n\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tbindSaveTap: function (e) {\n\t\t// 获取富文本，如果没填写则为[]\n\t\tlet formContent = this.selectComponent(\"#contentEditor\").getNodeList();\n\n\t\tlet parent = pageHelper.getPrevPage(2);\n\t\tif (!parent) return;\n\n\t\tparent.selectComponent(this.data.cmptId).setOneFormVal(this.data.cmptFormName, formContent);\n\n\t\twx.navigateBack();\n\t}\n})"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_show/content/form_show_content.json",
    "content": "{\n\t\"usingComponents\": { \n\t\t\"cmpt-editor\": \"/cmpts/public/editor/editor_cmpt\"\n\t}, \n\t\"navigationBarTitleText\": \"详细内容\"\n}"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_show/content/form_show_content.wxml",
    "content": "<view class=\"main-admin\">\n\t<view class=\"form-box shadow\">\n\t\t<view class=\"form-group\" style=\"width: 100%;\">\n\t\t\t<cmpt-editor nodeList=\"{{formContent}}\" viewMode=\"{{true}}\" style=\"width: 100%;\" id=\"contentEditor\"></cmpt-editor>\n\t\t</view>\n\t</view>\n</view>\n\n<view class=\"btn-bottom-admin\">\n\t<view bindtap=\"url\" data-type=\"back\" class=\"return\">不保存,返回</view>\n\t<view bindtap=\"bindSaveTap\" class=\"save\">保存</view>\n</view>"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_show/content/form_show_content.wxss",
    "content": "@import '../../../../../style/public/admin.wxss';\n\n.main-admin {\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tpadding: 30rpx 20rpx;\n\tpadding-bottom: 200rpx;\n}\n\n.form-group {\n\tpadding: 1rpx 1rpx;\n\toverflow: hidden;\n}\n\n.oprt {\n\tdisplay: flex;\n\twidth: 100%;\n\tjustify-content: space-around;\n}\n\n.oprt button {\n\twidth: 45%;\n}\n\n.bottom-oprt {\n\tposition: fixed;\n\tbottom: 0;\n\theight: 130rpx;\n\tbackground-color: #f8f8f8;\n\tdisplay: flex;\n\tjustify-content: space-around;\n\talign-items: center;\n\tborder-top: 1rpx solid #ccc;\n\tz-index: 99999;\n}"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_show/form_show_cmpt.js",
    "content": "const pageHelper = require('../../../../helper/page_helper.js');\nconst helper = require('../../../../helper/helper.js');\nconst cloudHelper = require('../../../../helper/cloud_helper.js');\nconst cacheHelper = require('../../../../helper/cache_helper.js');\nconst formSetHelper = require('../form_set_helper.js');\nconst validate = require('../../../../helper/validate.js');\nconst setting = require('../../../../setting/setting.js');\n\nconst CACHE_FORM_SHOW_KEY = 'FORM_SHOW_CMPT';\nconst CACHE_FORM_SHOW_TIME = 86400 * 365;\n\nComponent({\n\toptions: {\n\t\taddGlobalClass: true\n\t},\n\n\t/**\n\t * 组件的属性列表\n\t */\n\tproperties: {\n\t\tmark: { // 组件标识，用于区分缓存\n\t\t\ttype: String,\n\t\t\tvalue: '',\n\t\t},\n\t\tsource: { // 来源 admin /user\n\t\t\ttype: String,\n\t\t\tvalue: 'user',\n\t\t},\n\t\tfields: { // 表单字段属性{mark,val,type,must,selectOptions,desc,title}\n\t\t\ttype: Array,\n\t\t\tvalue: [],\n\t\t},\n\t\tforms: { // 表单值\n\t\t\ttype: Array,\n\t\t\tvalue: [], // {mark,title,val,type}\n\t\t},\n\t\tdoShow: { //仅仅显示\n\t\t\ttype: Boolean,\n\t\t\tvalue: false,\n\t\t},\n\t\tisConfirm: { //是否显示核对信息modal\n\t\t\ttype: Boolean,\n\t\t\tvalue: true,\n\t\t},\n\t\tisCacheMatch: { //是否开启缓存匹配\n\t\t\ttype: Boolean,\n\t\t\tvalue: true,\n\t\t},\n\t\tisDefMatch: { //是否开启缺省值匹配\n\t\t\ttype: Boolean,\n\t\t\tvalue: true,\n\t\t},\n\t},\n\n\t/**\n\t * 组件的初始数据\n\t */\n\tdata: {\n\t\tcacheName: '',\n\t\tisLoad: false,\n\t\tshowCheckModal: false,\n\t\tmobileCheck: setting.MOBILE_CHECK\n\t},\n\n\t/**\n\t * 生命周期方法\n\t */\n\tlifetimes: {\n\t\tattached: function () {\n\n\t\t},\n\n\t\tready: function () {\n\t\t\tif (this.data.isCacheMatch) {\n\t\t\t\tlet cacheName = CACHE_FORM_SHOW_KEY + '_' + this.data.mark;\n\t\t\t\tthis.setData({\n\t\t\t\t\tcacheName\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthis._init();\n\n\t\t},\n\n\t\tdetached: function () {\n\t\t\t// 在组件实例被从页面节点树移除时执行\n\t\t},\n\t},\n\n\t/**\n\t * 组件的方法列表\n\t */\n\tmethods: {\n\t\treload: function () {\n\t\t\t// 重新加载，如果没有设置扩展字段，则全部form属性清空\n\t\t\tthis._init();\n\t\t},\n\t\t_init: function () {\n\t\t\tlet fields = formSetHelper.initFields(this.data.fields);\n\t\t\tlet newForms = [];\n\n\t\t\tfor (let k = 0; k < fields.length; k++) {\n\t\t\t\tlet node = {};\n\t\t\t\tnode.mark = fields[k].mark;\n\t\t\t\tnode.title = fields[k].title;\n\t\t\t\tnode.type = fields[k].type;\n\n\t\t\t\t// 判断是否有表单值（依次从表单值，缓存，默认值）\n\t\t\t\tlet val = this._getOneValForm(fields[k].mark, fields[k].title, fields[k].type);\n\t\t\t\tif (val === null) val = '';\n\n\n\t\t\t\t// 数据类型修正\n\t\t\t\tval = this._fixType(fields[k].type, val);\n\t\t\t\tnode.val = val;\n\t\t\t\tfields[k].val = val;\n\n\t\t\t\tnewForms.push(node);\n\t\t\t}\n\n\t\t\tthis.setData({\n\t\t\t\tforms: newForms,\n\t\t\t\tfields,\n\t\t\t\tisLoad: true\n\t\t\t});\n\t\t\t//this.triggerEvent('forms', newForms);\n\t\t},\n\n\t\t// 根据mark和type获取上次值或者缓存值或者缺省值\n\t\t_getOneValForm: function (mark, title, type) {\n\t\t\tif (type == 'line') return title;\n\n\t\t\tlet ret = null;\n\n\t\t\t// **** 对传入的默认值匹配\n\t\t\tlet forms = this.data.forms;\n\n\t\t\tif (!forms || !Array.isArray(forms)) forms = [];\n\t\t\tfor (let k = 0; k < forms.length; k++) {\n\t\t\t\tif (forms[k].mark == mark && forms[k].type == type) { // 优先匹配mark\n\t\t\t\t\tret = forms[k].val;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (forms[k].title == title && forms[k].type == type) { // 再则匹配名称\n\t\t\t\t\tret = forms[k].val;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (type == 'mobile' && forms[k].type == 'mobile') {\n\t\t\t\t\tret = forms[k].val;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (type == 'idcard' && forms[k].type == 'idcard') {\n\t\t\t\t\tret = forms[k].val;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\n\t\t\t// **** 对缓存匹配 图片和富文本不读取缓存 \n\t\t\tif (ret === null && this.data.isCacheMatch\n\t\t\t\t&& (type != 'image' && type != 'content')) {\n\t\t\t\tlet caches = cacheHelper.get(this.data.cacheName);\n\t\t\t\tif (caches && Array.isArray(caches)) {\n\t\t\t\t\tfor (let k = 0; k < caches.length; k++) {\n\t\t\t\t\t\tif (caches[k].mark == mark && caches[k].type == type) { // 优先匹配mark\n\t\t\t\t\t\t\tret = caches[k].val;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (caches[k].title == title && caches[k].type == type) { // 再则匹配名称\n\t\t\t\t\t\t\tret = caches[k].val;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (type == 'mobile' && caches[k].type == 'mobile') {\n\t\t\t\t\t\t\tret = caches[k].val;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (type == 'idcard' && caches[k].type == 'idcard') {\n\t\t\t\t\t\t\tret = caches[k].val;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 缺省值匹配\n\t\t\tif (ret === null && this.data.isDefMatch) {\n\t\t\t\tlet fields = this.data.fields;\n\t\t\t\tfor (let k = 0; k < fields.length; k++) {\n\t\t\t\t\tif (fields[k].mark == mark\n\t\t\t\t\t\t&& helper.isDefined(fields[k].def)\n\t\t\t\t\t\t&& fields[k].def != null // 默认值为空\n\t\t\t\t\t) {\n\t\t\t\t\t\tret = fields[k].def;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn ret;\n\t\t},\n\n\t\t// 原始form没有对应值, 给予默认值; 或者类型不对，修正\n\t\t_fixType: function (type, val) {\n\t\t\tif (type == 'line') return val;\n\n\t\t\tif (type != 'switch' && type != 'checkbox' && type != 'area' && type != 'content' && type != 'image') {\n\t\t\t\t// switch(bool),checkbox(array), area(array), content(array) 不处理，其他做类型处理\n\n\t\t\t\tif (typeof val === 'object' && !Array.isArray(val)) {\n\t\t\t\t\t// 对象要被处理为空串，数组做trim不处理(typeof数组也是object)\n\t\t\t\t\tval = '';\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tval = String(val).trim(); // 前后去空格\n\t\t\t}\n\n\n\t\t\t// 原始form 有对应值，但是类型不正确\n\t\t\tswitch (type) {\n\t\t\t\tcase 'image': {\n\t\t\t\t\t// 不支持字符串缺省值 \n\t\t\t\t\tif (!Array.isArray(val)) return [];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'content': {\n\t\t\t\t\t// 支持字符串缺省值\n\t\t\t\t\tif (typeof val === 'string') {\n\t\t\t\t\t\tif (val)\n\t\t\t\t\t\t\treturn [{ type: 'text', val: val.trim() }];\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\treturn [];\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!Array.isArray(val)) return [];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'area': {\n\t\t\t\t\tif (!Array.isArray(val) || val.length != 3) return ''; //TODO?\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'switch': {\n\t\t\t\t\tif (typeof (val) != 'boolean') return true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'checkbox': {\n\t\t\t\t\tif (!Array.isArray(val)) return [String(val).trim()]; //尝试转为数组来匹配\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'year': {\n\t\t\t\t\tif (!val || validate.checkYear(val)) return '';\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'month': {\n\t\t\t\t\tif (!val || validate.checkYearMonth(val)) return '';\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'date': {\n\t\t\t\t\tif (!val || validate.checkDate(val)) return '';\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'hourminute': {\n\t\t\t\t\tif (!val || validate.checkHourMinute(val)) return '';\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'int': { // 整数(字符形式) \n\t\t\t\t\tif (!val || validate.checkInt(val)) return '';\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'digit': { // 小数(字符形式) \n\t\t\t\t\tif (!val || validate.checkDigit(val)) return '';\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn val;\n\t\t},\n\n\t\t_setForm: function (idx, val) {\n\t\t\tlet forms = this.data.forms;\n\t\t\tlet fields = this.data.fields;\n\t\t\tfields[idx].val = val;\n\t\t\tforms[idx].val = val;\n\n\t\t\t// TODO是否需要，影响性能 \n\t\t\tlet typeArr = ['text', 'textarea', 'digit', 'idcard', 'int', 'tag'];\n\n\t\t\t// 去掉focus\n\t\t\tfor (let k = 0; k < fields.length; k++) {\n\t\t\t\tif (helper.isDefined(fields[k].focus)) {\n\t\t\t\t\tdelete fields[k].focus;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 提高性能\n\t\t\tlet formsName = 'forms[' + idx + '].val';\n\t\t\tlet fieldsName = 'fields[' + idx + '].val';\n\t\t\tthis.setData({\n\t\t\t\t[formsName]: val,\n\t\t\t\t[fieldsName]: val,\n\t\t\t});\n\n\t\t\t//this.triggerEvent('forms', forms);\n\t\t},\n\n\n\t\tbindImgUploadCmpt: function (e) {\n\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\tlet val = e.detail;\n\t\t\tthis._setForm(idx, val);\n\t\t},\n\n\t\tbindLineBlur: function (e) {\n\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\tlet val = e.detail.value.trim();\n\t\t\tthis._setForm(idx, val);\n\t\t},\n\n\t\tbindMultiBlur: function (e) {\n\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\tlet val = e.detail.value;\n\t\t\tthis._setForm(idx, val);\n\t\t},\n\n\t\tbindDayChange: function (e) {\n\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\tlet val = e.detail.value.trim();\n\t\t\tthis._setForm(idx, val);\n\t\t},\n\n\t\tbindAreaChange: function (e) {\n\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\tlet val = e.detail.value;\n\t\t\tthis._setForm(idx, val);\n\t\t},\n\n\t\tbindSelectCmpt: function (e) {\n\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\tlet val = e.detail.trim();\n\t\t\tthis._setForm(idx, val);\n\t\t},\n\n\t\tbindCheckBoxCmpt: function (e) {\n\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\tlet val = e.detail;\n\t\t\tthis._setForm(idx, val);\n\t\t},\n\n\t\tbindRadioCmpt: function (e) {\n\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\tlet val = e.detail;\n\t\t\tthis._setForm(idx, val);\n\t\t},\n\n\t\tswitchModel: function (e) {\n\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\tlet val = e.detail.value;\n\t\t\tthis._setForm(idx, val);\n\t\t},\n\n\t\tbindGetPhoneNumber: async function (e) {\n\t\t\tif (e.detail.errMsg == \"getPhoneNumber:ok\") {\n\n\t\t\t\tlet cloudID = e.detail.cloudID;\n\t\t\t\tlet params = {\n\t\t\t\t\tcloudID\n\t\t\t\t};\n\t\t\t\tlet opt = {\n\t\t\t\t\ttitle: '手机验证中'\n\t\t\t\t};\n\t\t\t\tawait cloudHelper.callCloudSumbit('passport/phone', params, opt).then(res => {\n\t\t\t\t\tlet phone = res.data;\n\t\t\t\t\tif (!phone || phone.length < 11)\n\t\t\t\t\t\twx.showToast({\n\t\t\t\t\t\t\ttitle: '手机号码获取失败，请重新绑定手机号码',\n\t\t\t\t\t\t\ticon: 'none',\n\t\t\t\t\t\t\tduration: 2000\n\t\t\t\t\t\t});\n\t\t\t\t\telse {\n\t\t\t\t\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\t\t\t\t\tthis._setForm(idx, phone);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else\n\t\t\t\twx.showToast({\n\t\t\t\t\ttitle: '手机号码获取失败，请重新绑定手机号码',\n\t\t\t\t\ticon: 'none'\n\t\t\t\t});\n\t\t},\n\n\t\tcheckForms: function () {\n\t\t\t// 写缓存\n\t\t\tif (this.data.isCacheMatch) {\n\t\t\t\tcacheHelper.set(this.data.cacheName, this.data.forms, CACHE_FORM_SHOW_TIME);\n\t\t\t}\n\n\t\t\tlet ret = formSetHelper.checkForm(this.data.fields, this.data.forms, this);\n\n\t\t\tthis.setData({\n\t\t\t\tfields: this.data.fields\n\t\t\t});\n\n\t\t\tif (!ret) return;\n\n\t\t\tif (this.data.isConfirm) { //是否显示确认信息\n\t\t\t\tthis.setData({\n\t\t\t\t\tshowCheckModal: true\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tcacheHelper.remove(this.data.cacheName);\n\t\t\t\tthis.triggerEvent('submit', this.data.forms);\n\t\t\t}\n\n\t\t},\n\n\t\tbindSubmitCmpt: function () {\n\t\t\tthis.setData({\n\t\t\t\tshowCheckModal: false\n\t\t\t});\n\t\t\tcacheHelper.remove(this.data.cacheName);\n\t\t\tthis.triggerEvent('submit', this.data.forms);\n\t\t},\n\n\t\turl: function (e) {\n\t\t\tpageHelper.url(e, this);\n\t\t},\n\n\t\tgetForms: function (isCheckForm = false) {\n\t\t\tif (isCheckForm) {\n\t\t\t\t// 是否数据校验\n\t\t\t\tlet ret = formSetHelper.checkForm(this.data.fields, this.data.forms, this);\n\n\t\t\t\tthis.setData({\n\t\t\t\t\tfields: this.data.fields\n\t\t\t\t});\n\n\t\t\t\tif (!ret) return false;\n\t\t\t}\n\n\t\t\t// 写缓存\n\t\t\tif (this.data.isCacheMatch) {\n\t\t\t\tcacheHelper.set(this.data.cacheName, this.data.forms, CACHE_FORM_SHOW_TIME);\n\t\t\t}\n\n\t\t\treturn this.data.forms;\n\t\t},\n\n\t\tgetOneFormVal(formName) {\n\t\t\t// 取某个表单值\n\t\t\tlet forms = this.data.forms;\n\t\t\tfor (let k = 0; k < forms.length; k++) {\n\t\t\t\tif (formName == forms[k].mark) {\n\t\t\t\t\treturn forms[k].val;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\t\t},\n\n\t\tsetOneFormVal(formName, val) {\n\t\t\t// 设定某个表单值\n\t\t\tlet forms = this.data.forms;\n\t\t\tlet fields = this.data.fields;\n\t\t\tfor (let k = 0; k < forms.length; k++) {\n\t\t\t\tif (formName == forms[k].mark) {\n\t\t\t\t\tforms[k].val = val;\n\t\t\t\t\tfields[k].val = val;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.setData({\n\t\t\t\tfields,\n\t\t\t\tforms\n\t\t\t});\n\t\t}\n\t},\n\n})"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_show/form_show_cmpt.json",
    "content": "{\n\t\"component\": true,\n\t\"usingComponents\": {\n\t\t\"cmpt-checkbox\": \"/cmpts/public/checkbox/checkbox_cmpt\",\n\t\t\"cmpt-radio\": \"/cmpts/public/radio/radio_cmpt\",\n\t\t\"cmpt-img-upload\": \"/cmpts/public/img/img_upload_cmpt\"\n\t}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_show/form_show_cmpt.wxml",
    "content": "<view wx:if=\"{{isLoad===null}}\" class=\"margin-top load notexist text-l text-darkgreen load-project\"></view>\n<view wx:if=\"{{isLoad===false}}\" class=\"margin-top load loading text-l text-darkgreen load-project\"></view>\n\n<wxs module=\"wxs\">\n\tfunction calContent(content) {\n\t\tvar imgCnt = 0;\n\t\tvar textCnt = 0;\n\t\tfor (var k = 0; k < content.length; k++) {\n\t\t\tif (content[k].type == 'img') imgCnt++;\n\t\t\tif (content[k].type == 'text') textCnt++;\n\t\t}\n\t\tif (imgCnt || textCnt) {\n\t\t\treturn textCnt + '段文字，' + imgCnt + '张图片';\n\t\t}\n\t\telse\n\t\t\treturn '未填写';\n\t}\n\n\tmodule.exports = {\n\t\tcalContent: calContent,\n\t};\n</wxs>\n\n<block wx:if=\"{{isLoad}}\" wx:for=\"{{fields}}\" wx:key=\"key\">\n\t<block wx:if=\"{{doShow}}\">\n\t\t<view class=\"form-group padding-s form-group-show\">\n\t\t\t<view class=\"title\">{{item.title}}:</view>\n\t\t\t<view wx:if=\"{{item.type=='image'}}\" class=\"form-group-show-text\">\n\t\t\t\t<image bindtap=\"url\" data-type=\"image\" data-url=\"{{itm}}\" wx:for=\"{{item.val}}\" lazy-load=\"{{true}}\" wx:key=\"key1\" wx:for-item=\"itm\" src=\"{{itm}}\" class=\"loading form-group-show-img\" show-menu-by-longpress=\"{{true}}\" />\n\t\t\t</view>\n\t\t\t<view wx:elif=\"{{item.type=='switch'}}\" class=\"form-group-show-text\">{{item.val===true?'是':'否'}}</view>\n\t\t\t<view wx:elif=\"{{item.type=='content'}}\" class=\"form-group-show-text\">[图文]</view>\n\t\t\t<view wx:else class=\"form-group-show-text\">{{item.val}}</view>\n\t\t</view>\n\t</block>\n\n\t<block wx:else>\n\t<view wx:if=\"{{item.type=='line'}}\" class=\"form-group-line\"><text>{{item.title}}</text></view>\n\n\n\n\t<block wx:elif=\"{{item.type=='text'}}\">\n\t\t<view class=\"form-group\" id=\"form{{item.mark}}\">\n\t\t\t<view class=\"title {{item.must?'must':''}}\">{{item.title}}:</view>\n\t\t\t<input placeholder=\"{{item.desc||'请填写'+item.title}}\" placeholder-class=\"phc\" maxlength=\"{{item.max}}\" bindinput=\"bindLineBlur\" data-idx=\"{{index}}\" value=\"{{item.val}}\" focus=\"{{item.focus}}\"></input>\n\t\t</view>\n\t\t<view wx:if=\"{{item.focus}}\" class=\"hint-desc error\">{{item.focus}}</view>\n\t</block>\n\n\t<block wx:elif=\"{{item.type=='int'}}\">\n\t\t<view class=\"form-group\" id=\"form{{item.mark}}\">\n\t\t\t<view class=\"title {{item.must?'must':''}}\">{{item.title}}:</view>\n\t\t\t<input type=\"number\" placeholder=\"{{item.desc||'请填写'+item.title}}\" placeholder-class=\"phc\" maxlength=\"{{item.max}}\" bindinput=\"bindLineBlur\" data-idx=\"{{index}}\" value=\"{{item.val}}\" focus=\"{{item.focus}}\"></input>\n\t\t</view>\n\t\t<view wx:if=\"{{item.focus}}\" class=\"hint-desc error\">{{item.focus}}</view>\n\t</block>\n\n\t<block wx:elif=\"{{item.type=='digit'}}\">\n\t\t<view class=\"form-group\" id=\"form{{item.mark}}\">\n\t\t\t<view class=\"title {{item.must?'must':''}}\">{{item.title}}:</view>\n\t\t\t<input type=\"digit\" placeholder=\"{{item.desc||'请填写'+item.title}}\" placeholder-class=\"phc\" maxlength=\"{{item.max}}\" bindinput=\"bindLineBlur\" data-idx=\"{{index}}\" value=\"{{item.val}}\" focus=\"{{item.focus}}\"></input>\n\t\t</view>\n\t\t<view wx:if=\"{{item.focus}}\" class=\"hint-desc error\">{{item.focus}}</view>\n\t</block>\n\n\t<block wx:elif=\"{{item.type=='select'}}\">\n\t\t<view class=\"form-group\" id=\"form{{item.mark}}\">\n\t\t\t<view class=\"title {{item.must?'must':''}}\">{{item.title}}</view>\n\t\t\t<cmpt-picker sourceData=\"{{item.selectOptions}}\" data-idx=\"{{index}}\" bind:select=\"bindSelectCmpt\" item=\"{{item.val}}\" />\n\t\t</view>\n\t\t<view class=\"hint-desc\" wx:if=\"{{item.desc}}\">{{item.desc}}</view>\n\t\t<view wx:if=\"{{item.focus}}\" class=\"hint-desc error\">{{item.focus}}</view>\n\t</block>\n\n\t<block wx:elif=\"{{item.type=='checkbox'}}\">\n\t\t<view class=\"form-group\" id=\"form{{item.mark}}\">\n\t\t\t<view class=\"action text-bold text-l\"><text class=\"text-red\" wx:if=\"{{item.must}}\">*</text>{{item.title}}\n\t\t\t</view>\n\t\t\t<view class=\"action\">至少选择{{item.checkBoxLimit}}项</view>\n\t\t</view>\n\t\t<view class=\"form-group align-start\" style=\"flex:1;padding-left:0;padding-right:20rpx;\">\n\t\t\t<cmpt-checkbox sourceData=\"{{item.selectOptions}}\" data-idx=\"{{index}}\" bind:select=\"bindCheckBoxCmpt\" itemMulti=\"{{item.val}}\" style=\"flex:1\" />\n\t\t</view>\n\t\t<view wx:if=\"{{item.focus}}\" class=\"hint-desc error\">{{item.focus}}</view>\n\t</block>\n\n\t<block wx:elif=\"{{item.type=='radio'}}\">\n\t\t<view class=\"form-group\" id=\"form{{item.mark}}\">\n\t\t\t<view class=\"action text-bold text-l\"><text class=\"text-red\" wx:if=\"{{item.must}}\">*</text>{{item.title}}\n\t\t\t</view>\n\t\t\t<view class=\"action\"></view>\n\t\t</view>\n\t\t<view class=\"form-group align-start\" style=\"flex:1;padding-left:0;padding-right:20rpx;\">\n\t\t\t<cmpt-radio sourceData=\"{{item.selectOptions}}\" data-idx=\"{{index}}\" bind:select=\"bindRadioCmpt\" itemSelected=\"{{item.val}}\" style=\"flex:1\" />\n\t\t</view>\n\t\t<view wx:if=\"{{item.focus}}\" class=\"hint-desc error\">{{item.focus}}</view>\n\t</block>\n\n\t<block wx:elif=\"{{item.type=='date'}}\">\n\t\t<view class=\"form-group arrow\" id=\"form{{item.mark}}\">\n\t\t\t<view class=\"title {{item.must?'must':''}}\">{{item.title}}</view>\n\t\t\t<picker class=\"picker-base\" data-idx=\"{{index}}\" mode=\"date\" bindchange=\"bindDayChange\" value=\"{{item.val}}\">\n\t\t\t\t<view class=\"picker-select\">\n\t\t\t\t\t{{item.val || '年,月,日'}}\n\t\t\t\t</view>\n\t\t\t</picker>\n\t\t</view>\n\t\t<view class=\"hint-desc\" wx:if=\"{{item.desc}}\">{{item.desc}}</view>\n\t\t<view wx:if=\"{{item.focus}}\" class=\"hint-desc error\">{{item.focus}}</view>\n\t</block>\n\n\t<block wx:elif=\"{{item.type=='year'}}\">\n\t\t<view class=\"form-group arrow\" id=\"form{{item.mark}}\">\n\t\t\t<view class=\"title {{item.must?'must':''}}\">{{item.title}}</view>\n\t\t\t<picker class=\"picker-base\" data-idx=\"{{index}}\" mode=\"date\" fields=\"year\" bindchange=\"bindDayChange\" value=\"{{item.val}}\">\n\t\t\t\t<view class=\"picker-select\">\n\t\t\t\t\t{{item.val || '年份'}}\n\t\t\t\t</view>\n\t\t\t</picker>\n\t\t</view>\n\t\t<view class=\"hint-desc\" wx:if=\"{{item.desc}}\">{{item.desc}}</view>\n\t\t<view wx:if=\"{{item.focus}}\" class=\"hint-desc error\">{{item.focus}}</view>\n\t</block>\n\n\t<block wx:elif=\"{{item.type=='month'}}\">\n\t\t<view class=\"form-group arrow\" id=\"form{{item.mark}}\">\n\t\t\t<view class=\"title {{item.must?'must':''}}\">{{item.title}}</view>\n\t\t\t<picker class=\"picker-base\" data-idx=\"{{index}}\" mode=\"date\" fields=\"month\" bindchange=\"bindDayChange\" value=\"{{item.val}}\">\n\t\t\t\t<view class=\"picker-select\">\n\t\t\t\t\t{{item.val || '月份'}}\n\t\t\t\t</view>\n\t\t\t</picker>\n\t\t</view>\n\t\t<view class=\"hint-desc\" wx:if=\"{{item.desc}}\">{{item.desc}}</view>\n\t\t<view wx:if=\"{{item.focus}}\" class=\"hint-desc error\">{{item.focus}}</view>\n\t</block>\n\n\t<block wx:elif=\"{{item.type=='hourminute'}}\">\n\t\t<view class=\"form-group arrow\" id=\"form{{item.mark}}\">\n\t\t\t<view class=\"title {{item.must?'must':''}}\">{{item.title}}</view>\n\t\t\t<picker class=\"picker-base\" data-idx=\"{{index}}\" mode=\"time\" bindchange=\"bindDayChange\" value=\"{{item.val}}\">\n\t\t\t\t<view class=\"picker-select\">\n\t\t\t\t\t{{item.val || '时间点'}}\n\t\t\t\t</view>\n\t\t\t</picker>\n\t\t</view>\n\t\t<view class=\"hint-desc\" wx:if=\"{{item.desc}}\">{{item.desc}}</view>\n\t\t<view wx:if=\"{{item.focus}}\" class=\"hint-desc error\">{{item.focus}}</view>\n\t</block>\n\n\t<block wx:elif=\"{{item.type=='area'}}\">\n\t\t<view class=\"form-group arrow\" id=\"form{{item.mark}}\">\n\t\t\t<view class=\"title {{item.must?'must':''}}\">{{item.title}}</view>\n\t\t\t<picker class=\"picker-base\" data-idx=\"{{index}}\" mode=\"region\" bindchange=\"bindAreaChange\" value=\"{{item.val}}\">\n\t\t\t\t<view wx:if=\"{{item.val && item.val.length==3}}\" class=\"picker-select\">\n\t\t\t\t\t{{item.val}}\n\t\t\t\t</view>\n\t\t\t\t<view wx:else class=\"picker-select\">\n\t\t\t\t\t省,区,市\n\t\t\t\t</view>\n\t\t\t</picker>\n\t\t</view>\n\t\t<view class=\"hint-desc\" wx:if=\"{{item.desc}}\">{{item.desc}}</view>\n\t\t<view wx:if=\"{{item.focus}}\" class=\"hint-desc error\">{{item.focus}}</view>\n\t</block>\n\n\t<block wx:elif=\"{{item.type=='switch'}}\">\n\t\t<view class=\"form-group\" id=\"form{{item.mark}}\">\n\t\t\t<view class=\"title {{item.must?'must':''}}\">{{item.title}}</view>\n\t\t\t<switch wx:if=\"{{item.val}}\" bindchange=\"switchModel\" data-idx=\"{{index}}\" class=\"green sm\" checked=\"true\">\n\t\t\t</switch>\n\t\t\t<switch wx:elif=\"{{!item.val}}\" bindchange=\"switchModel\" data-idx=\"{{index}}\" class=\"green sm\">\n\t\t\t</switch>\n\t\t</view>\n\t\t<view class=\"hint-desc\" wx:if=\"{{item.desc}}\">{{item.desc}}</view>\n\t\t<view wx:if=\"{{item.focus}}\" class=\"hint-desc error\">{{item.focus}}</view>\n\t</block>\n\n\t<block wx:elif=\"{{item.type=='textarea'}}\">\n\t\t<view class=\"form-group\" id=\"form{{item.mark}}\">\n\t\t\t<view class=\"action text-bold text-l\"><text class=\"text-red\" wx:if=\"{{item.must}}\">*</text>{{item.title}}\n\t\t\t</view>\n\t\t\t<view class=\"action\">{{item.val.length}}/{{item.max}}</view>\n\t\t</view>\n\n\t\t<view class=\"form-group align-start\">\n\t\t\t\t<textarea bindinput=\"bindMultiBlur\" data-idx=\"{{index}}\" value=\"{{item.val}}\" placeholder-class=\"phc\" placeholder=\"{{item.desc||'请填写'+item.title}}\" style=\"min-height:{{item.max<300?'100':''}}{{item.max>=300&&item.max<1000?(item.max/100)*40:''}}{{item.max>=1000?'400':''}}rpx\" auto-height=\"true\" maxlength=\"{{item.max}}\" focus=\"{{item.focus}}\" cursor-spacing=\"80\"></textarea>\n\t\t</view>\n\t\t<view wx:if=\"{{item.focus}}\" class=\"hint-desc error\">{{item.focus}}</view>\n\t</block>\n\n\t<block wx:if=\"{{item.type=='tag'}}\">\n\t\t<view class=\"form-group\" id=\"form{{item.mark}}\">\n\t\t\t<view class=\"action text-bold text-l\"><text class=\"text-red\" wx:if=\"{{item.must}}\">*</text>{{item.title}}\n\t\t\t</view>\n\t\t\t<view class=\"action\"></view>\n\t\t</view>\n\n\t\t<view class=\"form-group align-start\">\n\t\t\t<textarea bindinput=\"bindLineBlur\" data-idx=\"{{index}}\" value=\"{{item.val}}\" placeholder-class=\"phc\" placeholder=\"{{item.desc||'请填写'+item.title}}\" style=\"min-height:100rpx\" auto-height=\"true\" maxlength=\"{{item.max}}\" cursor-spacing=\"80\"></textarea>\n\t\t</view>\n\t\t<view class=\"hint-desc\"><text class=\"icon-tag\"></text>多个标签请用逗号分隔</view>\n\t\t<view wx:if=\"{{item.focus}}\" class=\"hint-desc error\">{{item.focus}}</view>\n\t</block>\n\n\t<block wx:elif=\"{{item.type=='idcard'}}\">\n\t\t<view class=\"form-group\" id=\"form{{item.mark}}\">\n\t\t\t<view class=\"title {{item.must?'must':''}}\">{{item.title}}:</view>\n\t\t\t<input type=\"idcard\" placeholder=\"{{item.desc||'请填写'+item.title}}\" placeholder-class=\"phc\" maxlength=\"18\" bindinput=\"bindLineBlur\" data-idx=\"{{index}}\" value=\"{{item.val}}\"></input>\n\t\t</view>\n\t\t<view wx:if=\"{{item.focus}}\" class=\"hint-desc error\">{{item.focus}}</view>\n\t</block>\n\n\t<block wx:elif=\"{{item.type=='content'}}\">\n\t\t<view id=\"form{{item.mark}}\" class=\"form-group arrow\" bindtap=\"url\" data-url=\"/cmpts/public/form/form_show/content/form_show_content?source={{source}}&cmptId={{mark}}&cmptFormName={{item.mark}}\">\n\t\t\t<view class=\"title {{item.must?'must':''}}\">{{item.title}}:<text class=\"text-grey text-normal margin-left-xs\">{{item.must?'(必填)':''}}</text></view>\n\t\t\t<view wx:if=\"{{item.val.length==0}}\" class=\"form-text text-orange\">「{{item.title}}」未填写</view>\n\t\t\t<view wx:else class=\"form-text\">{{wxs.calContent(item.val)}}</view>\n\t\t</view>\n\t\t<view wx:if=\"{{item.focus}}\" class=\"hint-desc error\">{{item.focus}}</view>\n\t</block>\n\n\t<block wx:elif=\"{{item.type=='image'}}\">\n\t\t<cmpt-img-upload id=\"form{{item.mark}}\" data-idx=\"{{index}}\" must=\"{{item.must}}\" imgMax=\"{{item.max}}\" title=\"{{item.title}}上传 {{item.must?'(必填)':''}}\" isCheck=\"{{false}}\" imgUploadSize=\"{{10}}\" imgList=\"{{item.val}}\" bind:upload=\"bindImgUploadCmpt\" />\n\t\t<view wx:if=\"{{item.focus}}\" class=\"hint-desc error\">{{item.focus}}</view>\n\t</block>\n\n\t<block wx:elif=\"{{item.type=='mobile' && mobileCheck}}\">\n\t\t<view class=\"form-group\" id=\"form{{item.mark}}\">\n\t\t\t<view class=\"title {{item.must?'must':''}}\">{{item.title}}:</view>\n\t\t\t<text class=\"phone-text\">{{item.val||'未填写'}}</text>\n\t\t\t<button open-type=\"getPhoneNumber\" bindgetphonenumber=\"bindGetPhoneNumber\" class=\"btn   phone-button\" data-idx=\"{{index}}\">{{item.val?'一键修改手机号':'一键填写手机号'}}</button>\n\t\t</view>\n\t\t<view wx:if=\"{{item.focus}}\" class=\"hint-desc error\">{{item.focus}}</view>\n\t</block>\n\n\t<block wx:elif=\"{{item.type=='mobile' && !mobileCheck}}\">\n\t\t<view class=\"form-group\" id=\"form{{item.mark}}\">\n\t\t\t<view class=\"title {{item.must?'must':''}}\">{{item.title}}:</view>\n\t\t\t<input placeholder=\"{{item.desc||'请填写'+item.title}}\" placeholder-class=\"phc\" maxlength=\"11\" bindinput=\"bindLineBlur\" data-idx=\"{{index}}\" value=\"{{item.val}}\"></input>\n\t\t</view>\n\t\t<view wx:if=\"{{item.focus}}\" class=\"hint-desc error\">{{item.focus}}</view>\n\t</block>\n\n\t</block>\n</block>\n\n<cmpt-modal model:show=\"{{showCheckModal}}\" type=\"longdialog\" title=\"请核对填写的信息\" bind:click=\"bindSubmitCmpt\" class=\"modal-check-info\" slot-class=\"slot-class\" cancelText=\"返回修改\" confirmText=\"确认提交\">\n\n\t<view class=\"item\" wx:for=\"{{forms}}\" wx:key=\"key\">\n\t\t<view class=\"title\">{{item.title}}：</view>\n\t\t<view class=\"content\" wx:if=\"{{item.val===true|| item.val===false}}\">{{item.val?'是':'否'}}</view>\n\t\t<view class=\"content\" wx:else>{{item.val}}</view>\n\t</view>\n</cmpt-modal>"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_show/form_show_cmpt.wxss",
    "content": ".form-group .picker-base {\n\tflex: 1;\n\ttext-align: right;\n\theight: 60rpx;\n\tline-height: 60rpx;\n}\n\n.form-group .picker-select {\n\tpadding-right: 40rpx;\n\toverflow: hidden;\n\tposition: relative;\n}\n\n.form-group .phone-text {\n\tfont-size: 30rpx;\n\tcolor: #555;\n\tflex: 1;\n\ttext-align: left;\n}\n\n.form-group .title {\n\theight: unset !important;\n\tmin-height: 60rpx;\n}\n\n.form-group-line {\n\twidth: 100%;\n\tpadding: 1rpx 30rpx;\n\tdisplay: flex;\n\talign-items: center;\n\tmin-height: 100rpx;\n\tjustify-content: center;\n\tposition: relative;\n\tcolor: #888;\n\tfont-size: 28rpx;\n\tmargin-top: 10rpx;\n}\n\n/* 展示型 */\n.form-group-show {\n\tdisplay: flex;\n\talign-items: flex-start;\n}\n\n.form-group-show .form-group-show-text {\n\tflex: 1;\n\tpadding: 0rpx 0rpx;\n\ttext-align: left;\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tmin-height: 60rpx;\n\talign-items: center;\n}\n\n.form-group-show .form-group-show-img {\n\twidth: 100rpx;\n\theight: 100rpx;\n\tmargin-right: 10rpx;\n\tmargin-bottom: 10rpx;\n\tborder-radius: 5rpx;\n}\n\n\n\n\n/* 核对信息窗口 */\n.modal-check-info {\n\twidth: 100%;\n}\n\n.slot-class {\n\tpadding: 0 20rpx 30rpx;\n}\n\n.modal-check-info .item {\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: flex-start;\n\tline-height: 1.8;\n\tfont-size: 30rpx;\n\tborder-bottom: 1rpx dotted #ddd;\n\tcolor: #000;\n\tpadding: 10rpx 10rpx;\n}\n\n.modal-check-info .item:nth-child(odd) {\n\tbackground-color: #f8f8f8;\n}\n\n.modal-check-info .item:last-child {\n\tborder-bottom: 0rpx;\n}\n\n.modal-check-info .item .title {\n\tfont-weight: bold;\n\tmax-width: 150rpx;\n\tmargin-right: 20rpx;\n\ttext-align: left;\n}\n\n.modal-check-info .item .content {\n\tflex: 1;\n\tcolor: #333;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: flex-start;\n\ttext-align: left;\n}"
  },
  {
    "path": "miniprogram/cmpts/public/img/img_upload_cmpt.js",
    "content": "const pageHelper = require('../../../helper/page_helper.js');\nconst contentCheckHelper = require('../../../helper/content_check_helper.js');\nconst setting = require('../../../setting/setting.js');\n\nComponent({\n\t/**\n\t * 组件的属性列表\n\t */\n\tproperties: {\n\t\timgList: {\n\t\t\ttype: Array,\n\t\t\tvalue: []\n\n\t\t},\n\t\timgMax: {\n\t\t\ttype: Number,\n\t\t\tvalue: 4,\n\t\t},\n\t\ttitle: {\n\t\t\ttype: String,\n\t\t\tvalue: '图片上传',\n\t\t},\n\t\tmust: { //是否必填\n\t\t\ttype: Boolean,\n\t\t\tvalue: true,\n\t\t},\n\t\tisCheck: { //是否做图片内容校验\n\t\t\ttype: Boolean,\n\t\t\tvalue: true,\n\t\t},\n\t\tisShowNo: { //是否显示序号\n\t\t\ttype: Boolean,\n\t\t\tvalue: false,\n\t\t},\n\t\timgUploadSize: { //图片最大大小\n\t\t\ttype: Number,\n\t\t\tvalue: setting.IMG_UPLOAD_SIZE,\n\t\t},\n\t\tisShowSize: { //是否提示图片尺寸\n\t\t\ttype: Boolean,\n\t\t\tvalue: true,\n\t\t}\n\t},\n\n\t/**\n\t * 组件的初始数据\n\t */\n\tdata: {\n\t\t//imgList:[]\n\t},\n\n\n\t/**\n\t * 生命周期方法\n\t */\n\tlifetimes: {\n\t\tattached: function () {\n\n\t\t},\n\n\t\tready: function () {\n\n\t\t},\n\t\tdetached: function () {\n\t\t\t// 在组件实例被从页面节点树移除时执行\n\t\t},\n\t},\n\n\t/**\n\t * 组件的方法列表\n\t */\n\tmethods: {\n\t\t/**\n\t\t * 选择上传图片 \n\t\t */\n\t\tbindChooseImgTap: function (e) {\n\t\t\twx.chooseMedia({\n\t\t\t\tcount: this.data.imgMax - this.data.imgList.length, //默认9\n\t\t\t\tmediaType: ['image'],\n\t\t\t\tsizeType: ['compressed'], //可以指定是原图还是压缩图，默认二者都有\n\t\t\t\tsourceType: ['album', 'camera'], //从相册选择\n\t\t\t\tsuccess: async (res) => {\n\t\t\t\t\twx.showLoading({\n\t\t\t\t\t\ttitle: '图片校验中',\n\t\t\t\t\t\tmask: true\n\t\t\t\t\t});\n\n\t\t\t\t\tfor (let k = 0; k < res.tempFiles.length; k++) {\n\t\t\t\t\t\tlet size = res.tempFiles[k].size;\n\t\t\t\t\t\tlet path = res.tempFiles[k].tempFilePath;\n\t\t\t\t\t\tif (!contentCheckHelper.imgTypeCheck(path)) {\n\t\t\t\t\t\t\twx.hideLoading();\n\t\t\t\t\t\t\treturn pageHelper.showNoneToast('只能上传png、jpg、jpeg格式', 3000);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlet imageMaxSize = 1024 * 1000 * this.data.imgUploadSize;\n\t\t\t\t\t\tif (!contentCheckHelper.imgSizeCheck(size, imageMaxSize)) {\n\t\t\t\t\t\t\twx.hideLoading();\n\t\t\t\t\t\t\treturn pageHelper.showNoneToast('单张图片大小不能超过 ' + this.data.imgUploadSize + 'M', 3000);\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\t//  读取文件流，云校验 \n\t\t\t\t\t\t//let imgData = wx.getFileSystemManager().readFileSync(path, 'base64');\n\n\t\t\t\t\t\t//console.log('imgData size=' + imgData.length);\n\n\t\t\t\t\t\tif (this.data.isCheck) {\n\t\t\t\t\t\t\tlet check = await contentCheckHelper.imgCheck(path);\n\t\t\t\t\t\t\tif (!check) {\n\t\t\t\t\t\t\t\twx.hideLoading();\n\t\t\t\t\t\t\t\treturn pageHelper.showNoneToast('存在不合适的图片, 已屏蔽', 3000);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tthis.setData({\n\t\t\t\t\t\t\timgList: this.data.imgList.concat(path)\n\t\t\t\t\t\t});\n\t\t\t\t\t\tthis.triggerEvent('upload', this.data.imgList);\n\n\t\t\t\t\t}\n\n\t\t\t\t\twx.hideLoading();\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\tbindPreviewImgTap: function (e) {\n\t\t\twx.previewImage({\n\t\t\t\turls: this.data.imgList,\n\t\t\t\tcurrent: e.currentTarget.dataset.url\n\t\t\t});\n\t\t},\n\n\t\t/**\n\t\t * \t删除图片 \n\t\t */\n\t\tcatchDelImgTap: function (e) {\n\t\t\tlet that = this;\n\t\t\tlet callback = function () {\n\t\t\t\tthat.data.imgList.splice(e.currentTarget.dataset.index, 1);\n\t\t\t\tthat.setData({\n\t\t\t\t\timgList: that.data.imgList\n\t\t\t\t});\n\t\t\t\tthat.triggerEvent('upload', that.data.imgList);\n\t\t\t}\n\t\t\tpageHelper.showConfirm('确定要删除该图片吗？', callback);\n\t\t},\n\n\t}\n})"
  },
  {
    "path": "miniprogram/cmpts/public/img/img_upload_cmpt.json",
    "content": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/img/img_upload_cmpt.wxml",
    "content": "<view class=\"form-group\">\n\t<view class=\"title\"><text wx:if=\"{{must}}\" class=\"text-red\">*</text>{{title}} <text wx:if=\"{{isShowSize}}\" class=\"text-gray text-normal\">(每张不超过{{imgUploadSize}}M)</text>\n\t</view>\n\t<view class=\"action\" wx:if=\"{{isShowSize&&imgMax>1}}\">\n\t\t{{imgList.length}}/{{imgMax}}\n\t</view>\n</view>\n<view class=\"form-group padding\">\n\t\t<view class=\"upload-img\">\n\t\t<view class=\"bg-img\" wx:for=\"{{imgList}}\" wx:key=\"index\" bindtap=\"bindPreviewImgTap\" data-url=\"{{imgList[index]}}\">\n\t\t\t<image src='{{imgList[index]}}' mode='aspectFill'></image>\n\t\t\t<view class=\"tag bg-red\" catchtap=\"catchDelImgTap\" data-index=\"{{index}}\">\n\t\t\t\t<text class=\"icon-close\"></text>\n\t\t\t</view>\n\n\t\t\t<view wx:if=\"{{isShowNo}}\" class=\"bg-olive img-no\">\n\t\t\t\t<text>#{{index}}</text>\n\t\t\t</view>\n\t\t</view>\n\t\t<view class=\"solid\" bindtap=\"bindChooseImgTap\" wx:if=\"{{imgList.length < imgMax}}\">\n\t\t\t<text class=\"icon-cameraadd\"></text>\n\t\t</view>\n\t</view>\n</view>"
  },
  {
    "path": "miniprogram/cmpts/public/img/img_upload_cmpt.wxss",
    "content": "@import \"../../../style/base/comm.wxss\"; \n@import \"../../../style/public/project.wxss\";  \n\n.form-group .upload-img .img-no {\n    position: absolute;\n    right: 0;\n    bottom: 0;\n    border-top-left-radius: 6rpx;\n    padding: 6rpx 12rpx;\n    height: 35rpx;\n    opacity: .9;\n}"
  },
  {
    "path": "miniprogram/cmpts/public/list/comm_list_cmpt.js",
    "content": "const cloudHelper = require('../../../helper/cloud_helper.js');\nconst helper = require('../../../helper/helper.js');\nconst PublicBiz = require('../../../comm/biz/public_biz.js');\nconst pageHelper = require('../../../helper/page_helper.js');\n\nComponent({\n\toptions: {\n\t\taddGlobalClass: true,\n\t\tpureDataPattern: /^_dataList/, // 指定所有 _ 开头的数据字段为纯数据字段\n\t\tmultipleSlots: true // 在组件定义时的选项中启用多slot支持\n\t},\n\n\t/**\n\t * 组件的属性列表\n\t */\n\tproperties: {\n\t\tdoDate: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: false\n\t\t},\n\t\tlistHeight: { // 列表区高度\n\t\t\ttype: String,\n\t\t\tvalue: ''\n\t\t},\n\n\t\troute: { // 业务路由\n\t\t\ttype: String,\n\t\t\tvalue: ''\n\t\t},\n\n\t\tsource: { // 来源 admin/user\n\t\t\ttype: String,\n\t\t\tvalue: 'user'\n\t\t},\n\n\t\t_params: { // 路由的附加参数\n\t\t\ttype: Object,\n\t\t\tvalue: null,\n\t\t\tobserver: function (newVal, oldVal) { //TODO????\n\t\t\t\tif (!oldVal || !newVal) return; //页面data里赋值会引起触发，除非在组件标签里直接赋值,或者提前赋值\n\n\t\t\t\t// 清空当前选择\n\t\t\t\tif (newVal) {\n\t\t\t\t\tthis.setData({\n\t\t\t\t\t\tpulldownMaskShow: false //返回去遮罩\n\t\t\t\t\t});\n\t\t\t\t\tthis._fmtSearchData();\n\t\t\t\t}\n\n\t\t\t\tthis.data._dataList = null;\n\t\t\t\tthis.triggerEvent('list', { //TODO 考虑改为双向数据绑定model \n\t\t\t\t\tdataList: this.data._dataList\n\t\t\t\t});\n\t\t\t\tthis._getList(1);\n\t\t\t}\n\t\t},\n\t\tisTotalMenu: {\n\t\t\ttype: Boolean, //是否整个搜索菜单显示\n\t\t\tvalue: true\n\t\t},\n\t\t_items: { // 下拉菜单基础数据\n\t\t\ttype: Array,\n\t\t\tvalue: [],\n\t\t\tobserver: function (newVal, oldVal) {\n\t\t\t\tif (newVal) this._fmtSearchData();\n\t\t\t}\n\t\t},\n\t\t_menus: { // 非下拉菜单基础数据 \n\t\t\ttype: Array,\n\t\t\tvalue: [],\n\t\t\tobserver: function (newVal, oldVal) {\n\t\t\t\tif (newVal) this._fmtSearchData(); //置为纯数据字段则不触发\n\t\t\t}\n\t\t},\n\t\t_dataList: {\n\t\t\ttype: Object,\n\t\t\tvalue: null\n\t\t},\n\t\ttype: {\n\t\t\ttype: String, //业务类型 info,user,well\n\t\t\tvalue: ''\n\t\t},\n\t\tplaceholder: {\n\t\t\ttype: String,\n\t\t\tvalue: '搜索关键字'\n\t\t},\n\t\tsortMenusDefaultIndex: {\n\t\t\ttype: Number,\n\t\t\tvalue: -1 //横菜单默认选中的\n\t\t},\n\t\tsearch: {\n\t\t\ttype: String, //搜索框关键字\n\t\t\tvalue: '',\n\t\t\tobserver: function (newVal, oldVal) {\n\t\t\t\t// 清空当前选择\n\t\t\t\tif (newVal) {\n\t\t\t\t\tthis.setData({\n\t\t\t\t\t\tpulldownMaskShow: false //返回去遮罩\n\t\t\t\t\t});\n\t\t\t\t\tthis._fmtSearchData();\n\t\t\t\t}\n\n\t\t\t\tthis.data._dataList = null;\n\t\t\t\tthis.triggerEvent('list', { //TODO 考虑改为双向数据绑定model \n\t\t\t\t\tdataList: this.data._dataList\n\t\t\t\t});\n\t\t\t\tthis._getList(1);\n\t\t\t}\n\t\t},\n\t\twhereEx: {\n\t\t\ttype: Object, // 附加查询条件\n\t\t\tvalue: null,\n\t\t},\n\t\treturnUrl: {\n\t\t\ttype: String, // 搜索完返回页面\n\t\t\tvalue: '',\n\t\t},\n\t\ttopBottom: {\n\t\t\ttype: String, // 回顶部按钮的位置\n\t\t\tvalue: '50'\n\t\t},\n\t\tisCache: { // 非缓存状态下或者list缓存过期下onshow加载, 缓存下onload加载\n\t\t\ttype: Boolean, //是否cache\n\t\t\tvalue: true\n\t\t},\n\t\tpulldownType: {\n\t\t\ttype: Array, // 下拉菜单展示模式 list/modal 每个菜单一个\n\t\t\tvalue: ['list', 'list', 'list', 'list', 'list', 'list']\n\t\t},\n\n\t},\n\n\t/**\n\t * 组件的初始数据\n\t */\n\tdata: {\n\t\trefresherTriggered: false, //下拉刷新是否完成\n\n\t\tsortItems: [], //下拉\n\t\tsortMenus: [], //一级菜单非下拉\n\n\t\tsortType: '', //回传的类型\n\t\tsortVal: '', //\t回传的值\n\n\t\tsortItemIndex: -1,\n\t\tsortIndex: -1,\n\n\t\ttopNum: 0, //回顶部\n\t\ttopShow: false,\n\n\t\tpulldownMaskShow: false, //下拉菜单遮罩\n\n\t\tstartDate: '',//默认起始时间  \n\t\tendDate: '',//默认结束时间 \n\t},\n\n\tlifetimes: {\n\t\tcreated: function () {\n\t\t\t// 组件实例化，但节点树还未导入，因此这时不能用setData\n\t\t},\n\t\tattached: function () {\n\t\t\t// 在组件实例进入页面节点树时执行 \n\t\t\t// 节点树完成，可以用setData渲染节点，但无法操作节点 \n\t\t},\n\t\tready: async function () {\n\n\t\t\t// 组件布局完成，这时可以获取节点信息，也可以操作节点\n\t\t\tthis._fmtSearchData();\n\n\t\t\tif (this.data.isCache) //缓存状态下加载\n\t\t\t\tawait this._getList(1);\n\n\t\t\t//取得预置参数_params的选中状态 \n\t\t\tlet params = this.data._params;\n\t\t\tif (params && params.sortType && helper.isDefined(params.sortVal)) { \n\t\t\t\tlet sortMenus = this.data._menus;\n\t\t\t\tfor (let k = 0; k < sortMenus.length; k++) {\n\t\t\t\t\tif (params.sortType == sortMenus[k].type && params.sortVal == sortMenus[k].value) {\n\t\t\t\t\t\tthis.setData({\n\t\t\t\t\t\t\t//sortType: sortMenus[k].type,\n\t\t\t\t\t\t\t//sortVal: sortMenus[k].value,\n\t\t\t\t\t\t\tsortMenusDefaultIndex: k\n\t\t\t\t\t\t});\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} \n\t\t\t\t}\n\t\t\t}\n\n\t\t},\n\t\tmove: function () {\n\t\t\t// 组件实例被移动到树的另一个位置\n\t\t},\n\t\tdetached: function () {\n\t\t\t// 在组件实例被从页面节点树移除时执行\n\t\t},\n\t},\n\n\tpageLifetimes: {\n\t\tasync show() {\n\t\t\t// 页面被展示   \n\t\t\tif (!this.data.isCache || !PublicBiz.isCacheList(this.data.type)) {\n\t\t\t\t// 非缓存状态下或者 list缓存过期下加载\n\t\t\t\tawait this._getList(1);\n\t\t\t}\n\n\t\t},\n\t\thide() {\n\t\t\t// 页面被隐藏\n\t\t},\n\t\tresize(size) {\n\t\t\t// 页面尺寸变化\n\t\t}\n\t},\n\n\t/**\n\t * 组件的方法列表\n\t */\n\tmethods: {\n\t\treload: async function () {\n\t\t\tawait this._getList(1);\n\t\t},\n\t\t// 数据列表\n\t\t_getList: async function (page) {\n\t\t\tlet params = {\n\t\t\t\tpage: page,\n\t\t\t\t...this.data._params\n\t\t\t};\n\t\t\tif (this.data.whereEx) params.whereEx = this.data.whereEx;\n\n\t\t\t// 搜索关键字\n\t\t\tif (this.data.search)\n\t\t\t\tparams.search = this.data.search;\n\n\t\t\t// 搜索菜单\n\t\t\tif (this.data.sortType && helper.isDefined(this.data.sortVal)) {\n\t\t\t\tparams.sortType = this.data.sortType;\n\t\t\t\tparams.sortVal = this.data.sortVal;\n\t\t\t}\n\n\t\t\t//if (page == 1 && !this.data._dataList) { TODO???\n\t\t\tif (page == 1) {\n\t\t\t\tthis.triggerEvent('list', {\n\t\t\t\t\tdataList: null //第一页面且没有数据提示加载中\n\t\t\t\t});\n\t\t\t}\n\n\n\t\t\tlet opt = {};\n\t\t\t//if (this.data._dataList && this.data._dataList.list && this.data._dataList.list.length > 0)\n\t\t\topt.title = 'bar';\n\t\t\tawait cloudHelper.dataList(this, '_dataList', this.data.route, params, opt);\n\n\t\t\tthis.triggerEvent('list', { //TODO 考虑改为双向数据绑定model\n\t\t\t\tsortType: this.data.sortType,\n\t\t\t\tdataList: this.data._dataList\n\t\t\t});\n\n\t\t\tif (this.data.isCache)\n\t\t\t\tPublicBiz.setCacheList(this.data.type);\n\t\t\tif (page == 1) this.bindTopTap();\n\n\n\t\t},\n\n\t\tbindReachBottom: function () {\n\t\t\t// 上拉触底 \n\t\t\tthis._getList(this.data._dataList.page + 1);\n\t\t},\n\n\t\tbindPullDownRefresh: async function () {\n\t\t\t// 下拉刷新\n\t\t\tthis.setData({\n\t\t\t\trefresherTriggered: true\n\t\t\t});\n\t\t\tawait this._getList(1);\n\t\t\tthis.setData({\n\t\t\t\trefresherTriggered: false\n\t\t\t});\n\n\t\t},\n\n\t\t/**\n\t\t * 顶部位置\n\t\t * @param {*} e \n\t\t */\n\t\tbindScrollTop: function (e) {\n\t\t\tif (e.detail.scrollTop > 100) {\n\t\t\t\tthis.setData({\n\t\t\t\t\ttopShow: true\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.setData({\n\t\t\t\t\ttopShow: false\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * 一键回到顶部\n\t\t */\n\t\tbindTopTap: function () {\n\t\t\tthis.setData({\n\t\t\t\ttopNum: 0\n\t\t\t});\n\t\t},\n\n\t\t// 初始化搜索\n\t\t_fmtSearchData: function () {\n\t\t\tlet data = {};\n\t\t\tlet sortItems = [];\n\t\t\tlet items = this.data._items;\n\t\t\tfor (let k = 0; k < items.length; k++) {\n\t\t\t\tlet item = {\n\t\t\t\t\tshow: false,\n\t\t\t\t\titems: items[k]\n\t\t\t\t};\n\t\t\t\tsortItems.push(item);\n\t\t\t}\n\t\t\tdata.sortItems = sortItems;\n\t\t\tdata.sortMenus = this.data._menus;\n\n\t\t\tdata.sortItemIndex = -1;\n\t\t\tdata.sortIndex = -1;\n\n\t\t\tdata.sortType = '';\n\t\t\tdata.sortVal = '';\n\t\t\tthis.setData(data);\n\n\t\t},\n\n\t\t/**\n\t\t * 清除搜索条件\n\t\t */\n\t\tbindSearchClearTap: function () {\n\t\t\t// 请求父页面清空搜索\n\t\t\tif (this.data.search) {\n\t\t\t\tthis.triggerEvent('list', {\n\t\t\t\t\tsearch: ''\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\n\n\t\t// 分类&排序一级菜单选择  \n\t\tbindSortTap: function (e) {\n\t\t\tlet sortIndex = e.currentTarget.dataset.index;\n\t\t\tlet sortItems = this.data.sortItems;\n\n\t\t\t// 横菜单默认选中取消 TODO\n\t\t\t/*\n\t\t\tthis.setData({\n\t\t\t\tsortMenusDefaultIndex: -1\n\t\t\t});*/\n\n\t\t\t// 换了下拉菜单\n\t\t\tlet sortItemIndex = (sortIndex != this.data.sortIndex) ? -1 : this.data.sortItemIndex;\n\n\t\t\tif (sortIndex < 5) {\n\t\t\t\tlet pulldownMaskShow = this.data.pulldownMaskShow;\n\n\t\t\t\t// 有下拉\n\t\t\t\tfor (let i = 0; i < sortItems.length; i++) {\n\t\t\t\t\tif (i != sortIndex)\n\t\t\t\t\t\tsortItems[i].show = false;\n\t\t\t\t\telse {\n\t\t\t\t\t\tsortItems[i].show = !sortItems[i].show;\n\t\t\t\t\t\tpulldownMaskShow = sortItems[i].show;\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t\tthis.setData({\n\t\t\t\t\tpulldownMaskShow, //遮罩\n\n\t\t\t\t\tsortItems,\n\t\t\t\t\tsortIndex,\n\t\t\t\t\tsortItemIndex\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\t//无下拉\n\t\t\t\tfor (let i = 0; i < sortItems.length; i++) {\n\t\t\t\t\tsortItems[i].show = false;\n\t\t\t\t}\n\t\t\t\tthis.setData({\n\t\t\t\t\tpulldownMaskShow: false,\n\t\t\t\t\tsortItems,\n\t\t\t\t\tsortIndex,\n\t\t\t\t\tsortItemIndex\n\t\t\t\t});\n\n\t\t\t\tthis._getSortKey();\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * 下拉菜单选择\n\t\t */\n\t\tbindSortItemTap: function (e) {\n\t\t\tlet sortItemIndex = e.target.dataset.idx;\n\t\t\tif (!sortItemIndex) sortItemIndex = 0; // #46\n\t\t\tlet sortItems = this.data.sortItems;\n\t\t\tfor (let i = 0; i < sortItems.length; i++) {\n\t\t\t\tsortItems[i].show = false;\n\t\t\t}\n\t\t\tthis.setData({\n\t\t\t\tpulldownMaskShow: false,\n\t\t\t\tsortItemIndex,\n\t\t\t\tsortItems\n\t\t\t});\n\t\t\tthis._getSortKey();\n\n\t\t},\n\n\t\t// 获得排序关键字\n\t\t_getSortKey: function () {\n\t\t\tlet sortVal = '';\n\t\t\tlet sortType = '';\n\n\t\t\tlet oldSortVal = this.data.sortVal;\n\t\t\tlet oldSortType = this.data.sortType;\n\n\t\t\tif (this.data.sortIndex < 5) {\n\t\t\t\tsortVal = this.data.sortItems[this.data.sortIndex].items[this.data.sortItemIndex].value;\n\t\t\t\tsortType = this.data.sortItems[this.data.sortIndex].items[this.data.sortItemIndex].type;\n\t\t\t} else {\n\t\t\t\tsortVal = this.data.sortMenus[this.data.sortIndex - 5].value;\n\t\t\t\tsortType = this.data.sortMenus[this.data.sortIndex - 5].type;\n\t\t\t}\n\t\t\tthis.setData({\n\t\t\t\tsortVal,\n\t\t\t\tsortType\n\t\t\t});\n\n\t\t\tif (sortVal != oldSortVal || sortType != oldSortType) {\n\t\t\t\t// 点击分类 \n\n\t\t\t\tif (this.data.startDate || this.data.endDate) {\n\t\t\t\t\tthis.setData({\n\t\t\t\t\t\tstartDate: '',\n\t\t\t\t\t\tendDate: ''\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif (this.data.search) {\n\t\t\t\t\t//清空搜索\n\t\t\t\t\tthis.triggerEvent('list', {\n\t\t\t\t\t\tsearch: ''\n\t\t\t\t\t});\n\t\t\t\t} else\n\t\t\t\t\tthis._getList(1);\n\n\t\t\t}\n\n\t\t},\n\n\t\t// 搜索跳转\n\t\tbindSearchTap: function (e) {\n\t\t\twx.navigateTo({\n\t\t\t\turl: pageHelper.fmtURLByPID('/pages/search/search?source=' + this.data.source + '&type=' + this.data.type + '&returnUrl=' + this.data.returnUrl)\n\t\t\t});\n\t\t},\n\n\t\tgetSortIndex: function () { //获得横向菜单\n\t\t\treturn this.data.sortIndex;\n\t\t},\n\t\tsetSortIndex: function (sortIndex) { //设置横向菜单\n\t\t\tthis.setData({\n\t\t\t\tsortIndex\n\t\t\t});\n\t\t},\n\n\t\tbindDateStartChange(e) {\n\t\t\tthis.setData({\n\t\t\t\tstartDate: e.detail.value,\n\t\t\t});\n\t\t},\n\t\tbindDateEndChange(e) {\n\t\t\tthis.setData({\n\t\t\t\tendDate: e.detail.value,\n\t\t\t});\n\t\t},\n\t\tbindDateSearchTap: function (e) {\n\t\t\tif (!this.data.startDate.includes('-')) return pageHelper.showNoneToast('请选择开始日期');\n\t\t\tif (!this.data.endDate.includes('-')) return pageHelper.showNoneToast('请选择结束日期');\n\n\t\t\tlet search = this.data.startDate + '#' + this.data.endDate;\n\t\t\tthis.setData({\n\t\t\t\tsearch\n\t\t\t})\n\t\t\tthis._getList(1);\n\t\t},\n\t\tbindDateClearTap: function (e) {\n\t\t\tthis.setData({\n\t\t\t\tstartDate: '',\n\t\t\t\tendDate: '',\n\t\t\t});\n\t\t\tif (this.data.search) {\n\t\t\t\tthis.setData({\n\t\t\t\t\tsearch: ''\n\t\t\t\t});\n\t\t\t}\n\n\t\t}\n\n\t}\n})"
  },
  {
    "path": "miniprogram/cmpts/public/list/comm_list_cmpt.json",
    "content": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/list/comm_list_cmpt.wxml",
    "content": "<view class=\"top_bar bar search fixed flex-direction\" wx:if=\"{{isTotalMenu}}\">\n\t<!-- search form BEGIN -->\n\t<view class=\"bar search bg-white \" style=\"width:100%\">\n\t\t<view class=\"search-date\" wx:if=\"{{doDate}}\">\n\t\t\t<!--<view class=\"date-title\">日期:</view>-->\n\t\t\t<!-- 时间段 -->\n\t\t\t<view class=\"date-group\">\n\t\t\t\t<picker mode=\"date\" model:value=\"{{startDate}}\" class=\"search-date-picker\">\n\t\t\t\t\t<view class=\"picker\">\n\t\t\t\t\t\t<text class=\"{{!startDate?'text-line1':'text-line2'}}\">{{startDate||'开始日期'}}</text>\n\t\t\t\t\t</view>\n\t\t\t\t</picker>\n\t\t\t\t<text class=\"text-line1\">~</text>\n\t\t\t\t<picker mode=\"date\" model:value=\"{{endDate}}\">\n\t\t\t\t\t<view class=\"picker\">\n\t\t\t\t\t\t<text class=\"{{!endDate ?'text-line1':'text-line2'}}\">{{endDate||'结束日期'}}</text>\n\t\t\t\t\t</view>\n\t\t\t\t</picker>\n\t\t\t</view>\n\t\t\t<view bindtap=\"bindDateSearchTap\" class=\"date-btn btn mid bg-gray margin-left-xs\" style=\"width:130rpx\">搜索</view>\n\t\t\t<view bindtap=\"bindDateClearTap\" class=\"date-btn btn mid bg-grey light margin-left-xs\" style=\"width:130rpx\">清空</view>\n\t\t</view>\n\t\t \n\t\t<view class=\"search-form round\" wx:if=\"{{!doDate}}\">\n\t\t\t<text class=\"icon-search text-l text-grey\"></text>\n\t\t\t<input type=\"text\" maxlength=\"30\" value=\"{{search}}\" placeholder=\"{{placeholder}}\" disabled='true' bindtap=\"bindSearchTap\"></input>\n\t\t\t<view wx:if=\"{{search}}\" class=\"text-xl\" bindtap=\"bindSearchClearTap\">\n\t\t\t\t<text class=\"icon-roundclose text-right  text-gray\"></text>\n\t\t\t</view>\n\t\t</view>\n\t\t<slot name=\"searchEnd\" />\n\t</view>\n\t<!-- search form END-->\n\n\t<!-- sort begin-->\n\t<view class='tabs bg-white' style=\"width:100%;padding:0 20rpx;\" wx:if=\"{{sortItems.length || sortMenus.length}}\">\n\t\t<!-- pulldown menu begin-->\n\t\t<view wx:for=\"{{sortItems}}\" wx:key=\"key\" bindtap='bindSortTap' class=\"tab {{sortIndex == index ? 'text-orange cur  ' : ''}} \" data-index=\"{{index}}\">\n\t\t\t<text class=\"pulldown-text\">{{ index==sortIndex && item.items[sortItemIndex] ? item.items[sortItemIndex].label: item.items[0].label}}</text>\n\t\t\t<text class=\"icon-{{item.show?'fold':'unfold'}} large text-black\"></text>\n\t\t</view>\n\t\t<!-- pulldown menu end-->\n\n\t\t<!-- sort menu begin-->\n\t\t<scroll-view scroll-left=\"0\" scroll-x=\"true\"  style=\"white-space: nowrap;width:100%;overflow:scroll\">\n\t\t\t<view  bindtap=\"bindSortTap\"  wx:for=\"{{sortMenus}}\" wx:key=\"key\" class=\"list-scroll-view tab tab-menu {{sortIndex == index+5 ||(sortMenusDefaultIndex == index && !search && sortIndex == -1) ? 'text-orange cur ' : ''}}  \" data-index=\"{{index+5}}\">{{item.label}}</view>\n\t\t</scroll-view>\n\t\t<!-- sort menu end-->\n\n\t\t<slot name=\"menuEnd\" />\n\n\t\t<!-- pulldown detail [LIST] begin-->  \n\t\t<block wx:if=\"{{pulldownType[index]=='list'}}\" wx:for=\"{{sortItems}}\" wx:for-index=\"index\" wx:key=\"key\"> \n\t\t\t<view class='sort' catchtouchmove=\"move\" bindtap='bindSortItemTap' wx:if=\"{{item.show}}\">\n\t\t\t\t<scroll-view class=\"pulldown-scroll-view\"  scroll-y=\"{{true}}\" scroll-into-view=\"pulldown-{{sortIndex}}-{{sortItemIndex-9}}\">\n\t\t\t\t\t<view id=\"pulldown-{{index}}-{{idx}}\" class=\"sort-item  {{idx == sortItemIndex && index == sortIndex ? 'text-orange cur' : ''}}  \" wx:for=\"{{item.items}}\" wx:key=\"key\" wx:for-item=\"its\" data-idx=\"{{idx}}\" wx:key=\"key\" wx:for-index=\"idx\"><text wx:if=\"{{idx==0}}\">全部</text>{{its.label}}</view>\n\t\t\t\t</scroll-view>\n\t\t\t</view> \n\t\t</block>  \n\t\t<!-- pulldown detail [LIST] end-->\n\n\t</view>\n\t<!-- sort end -->\n\n</view>\n\n<!-- content begin -->\n<view wx:if=\"{{!isTotalMenu}}\" class=\"box-list\" style=\"height:{{listHeight?listHeight:'(100vh)'}};margin-top:0rpx;\">\n\t<scroll-view    refresher-enabled=\"true\" refresher-triggered=\"{{refresherTriggered}}\" scroll-y=\"true\" class=\"box-list-scroll\" bindrefresherrefresh='bindPullDownRefresh' bindscrolltolower='bindReachBottom' scroll-top='{{topNum}}' bindscroll=\"bindScrollTop\">\n\t\t<slot  />  \n\t</scroll-view>\n</view>\n\n<view wx:if=\"{{isTotalMenu}}\" class=\"box-list\" style=\"height:calc(100vh - {{(!sortItems.length && !sortMenus.length)? '110' : '190'}}rpx);margin-top:{{(!sortItems.length && !sortMenus.length)? '110' : '190'}}rpx\">\n\t<scroll-view  refresher-enabled=\"true\" refresher-triggered=\"{{refresherTriggered}}\" scroll-y=\"true\" class=\"box-list-scroll\" bindrefresherrefresh='bindPullDownRefresh' bindscrolltolower='bindReachBottom' scroll-top='{{topNum}}' bindscroll=\"bindScrollTop\">\n\t\t<slot  />    \n\t</scroll-view>\n</view>\n<!-- content END -->\n  \n<!-- top begin -->\n<button wx:if=\"{{topShow}}\"  class=\"btn-fixed bg-gray text-gray btn-top\" bindtap=\"bindTopTap\" style=\"bottom:{{topBottom}}rpx;margin-bottom: constant(safe-area-inset-bottom);margin-bottom: env(safe-area-inset-bottom);\"><text class=\"icon-top\"></text></button>\n<!-- top END. -->\n\n<!-- pulldown detail [modal] begin-->  \n<block wx:if=\"{{pulldownType[index]=='modal'}}\" wx:for=\"{{sortItems}}\" wx:for-index=\"index\" wx:key=\"key\">\n<view class=\"modal bottom-modal show\"   wx:if=\"{{item.show}}\" >\n  <view class=\"dialog\" >\n    <view class=\"bar bg-white\">\n      <view class=\"action text-blue\" bindtap=\"bindSortTap\" data-index=\"{{index}}\" >取消</view>\n\t\t\t\t<view class=\"action text-green\" style=\"font-size:30rpx;\" bindtap=\"bindSortTap\" data-index=\"{{index}}\">确定</view>\n    </view>\n    <view class=\"grid col-3 padding-sm\" style=\"margin-bottom:120rpx;\">\n      <view wx:for=\"{{item.items}}\" wx:key=\"key\" wx:for-item=\"its\"  wx:key=\"key\" wx:for-index=\"idx\" class=\"padding-xs\">\n        <button  bindtap='bindSortItemTap' data-idx=\"{{idx}}\" class=\"pulldown-btn btn lg block {{idx == sortItemIndex && index == sortIndex?'bg-orange light border-orange':''}}\"   data-value=\"{{item.value}}\"> <text wx:if=\"{{idx==0}}\">全部</text>{{its.label}}  \n        </button>\n      </view>\n    </view>\n  </view>\n</view>\n</block>\n<!-- pulldown detail [modal] END-->  \n\n<!--### MASK ###-->\n<view class=\"pulldown-mask\" hidden=\"{{!pulldownMaskShow}}\"></view>"
  },
  {
    "path": "miniprogram/cmpts/public/list/comm_list_cmpt.wxss",
    "content": "/*sort*/\n.tabs {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-start;\n\tfont-size: 28rpx;\n\tcolor: #aaa;\n\theight: 80rpx;\n\tline-height: 80rpx;\n}\n\n.tabs .tab {\n\tflex-grow: 1;\n\ttext-align: center;\n\tposition: relative;\n\tmargin-right: 10rpx;\n\tfont-size: 28rpx;\n\tcolor: #000;\n}\n\n.tabs .cur {\n\tfont-weight: bold;\n}\n\n.tabs .tab-menu.cur:after {\n\tcontent: \" \";\n\tposition: absolute;\n\tleft: 50%;\n\tbottom: 0rpx;\n\twidth: 50%;\n\theight: 6rpx;\n\tborder-radius: 2rpx;\n\tbackground-color: orange;\n\ttransform: translateX(-50%)\n}\n\n.tabs .icon {\n\tcolor: #000;\n}\n\n\n.sort {\n\tposition: absolute;\n\ttop: 178rpx;\n\tbottom: 0;\n\twidth: 100%;\n\tbackground-color: rgba(188, 188, 188, 0.3);\n\tz-index: 999;\n\tleft: 0\n}\n\n.sort .sort-item {\n\tborder-top: 1px solid #eee;\n\theight: 80rpx;\n\tline-height: 80rpx;\n\tpadding-left: 50rpx;\n\tbackground-color: #fff;\n}\n\n\n/**头部*/\n.top_bar {\n\twidth: 100%;\n}\n\n.top_bar_scroll {\n\tposition: fixed;\n\ttop: 0rpx;\n\tleft: 0;\n\tz-index: 99;\n\tbackground: #fff;\n\n\tz-index: 999;\n}\n\n\n.box-list {\n\tdisplay: flex;\n\tflex-direction: column;\n\theight: 100vh;\n\toverflow: hidden;\n}\n\n.box-list-scroll {\n\tflex: 1;\n\theight: 1px;\n}\n\n\n.top-button {\n\tposition: fixed;\n\tbottom: 50rpx;\n\tright: 30rpx;\n\topacity: .8;\n}\n\n.list-scroll-view {\n\tdisplay: inline-block;\n\tpadding: 0 10rpx;\n}\n\n.pulldown-mask {\n\twidth: 100%;\n\theight: 100%;\n\tposition: fixed;\n\tbackground-color: #999;\n\ttop: 0;\n\tleft: 0;\n\topacity: 0.5;\n}\n\n.pulldown-scroll-view {\n\theight: 840rpx;\n\twidth: 100%;\n}\n\n.pulldown-btn {\n\tfont-size: 28rpx;\n\tcolor: #333 !important;\n\theight: 100rpx;\n\twidth: 200rpx;\n\tline-height: 1.3;\n\tpadding: 0 15rpx;\n}\n\n/* date */\n.search-date {\n\twidth:100%;\n\tdisplay: flex;\n\talign-items: center;\n\tpadding: 0 20rpx;\n}\n\n.search-date .date-title {\n\tfont-size: 28rpx;\n\tmargin-right: 8rpx;\n}\n\n.search-date .date-group {\n\tcolor: #888;\n\tborder: 1rpx solid #A4A6AE;\n\tborder-radius: 10rpx;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tpadding: 5rpx 20rpx;\n\tfont-size: 29rpx;\n}\n\n.search-date .text-line1 {\n\tcolor: #A4A6AE;\n\tmargin: 0 18rpx;\n}\n\n.search-date .text-line2 {\n\tcolor: rgb(0, 0, 0, 0.8);\n}\n\n.search-date .search-date-picker {\n\twidth: 150rpx;\n}"
  },
  {
    "path": "miniprogram/cmpts/public/modal/modal_cmpt.js",
    "content": "// cmpts/public/modal/modal.js\nComponent({\n\toptions: {\n\t\taddGlobalClass: true,\n\t\tmultipleSlots: true\n\t},\n\n\texternalClasses: ['slot-class'],\n\n\t/**\n\t * 组件的属性列表\n\t */\n\tproperties: {\n\t\ttype: { // 类型 comm/bottom/dialog/image\n\t\t\ttype: String,\n\t\t\tvalue: 'comm'\n\t\t},\n\t\ttitle: {\n\t\t\ttype: String,\n\t\t\tvalue: '温馨提示'\n\t\t},\n\t\tsubtitle: {\n\t\t\ttype: String,\n\t\t\tvalue: ''\n\t\t},\n\t\tsubtitleAlign: {\n\t\t\ttype: String,\n\t\t\tvalue: 'center'\n\t\t},\n\t\tshow: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: true\n\t\t},\n\t\tcancelText: {\n\t\t\ttype: String,\n\t\t\tvalue: '取消'\n\t\t},\n\t\tconfirmText: {\n\t\t\ttype: String,\n\t\t\tvalue: '确定'\n\t\t},\n\t\tshowConfirm: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: true\n\t\t},\n\t\timgURL: {\n\t\t\ttype: String,\n\t\t\tvalue: ''\n\t\t},\n\n\t\theight: {\n\t\t\ttype: Number,\n\t\t\tvalue: 600\n\t\t},\n\t},\n\n\t/**\n\t * 组件的初始数据\n\t */\n\tdata: {\n\n\t},\n\n\t/**\n\t * 组件的方法列表\n\t */\n\tmethods: {\n\t\tbindHideModalTap: function (e) {\n\t\t\tthis.setData({\n\t\t\t\tshow: ''\n\t\t\t})\n\t\t},\n\n\t\tnomove: function () {},\n\n\t\tbindComfirmTap: function (e) {\n\t\t\tthis.triggerEvent('click', {});\n\t\t}\n\t}\n})"
  },
  {
    "path": "miniprogram/cmpts/public/modal/modal_cmpt.json",
    "content": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/modal/modal_cmpt.wxml",
    "content": "<!-- 普通窗口 begin -->\n<view wx:if=\"{{type=='comm'}}\" class=\"modal {{show?'show':''}}\">\n\t<view class=\"dialog\">\n\t\t<view class=\"bar bg-white justify-end\">\n\t\t\t<view class=\"content\">{{title}}</view>\n\t\t\t<view class=\"action\" bindtap=\"bindHideModalTap\">\n\t\t\t\t<text class=\"icon-close text-red\"></text>\n\t\t\t</view>\n\t\t</view>\n\t\t<view class=\"padding-xl\">\n\t\t\t<slot />\n\t\t</view>\n\t</view>\n</view>\n<!-- 普通窗口 end -->\n\n<!--底部窗口 begin-->\n<view wx:if=\"{{type=='bottom'}}\" class=\"modal bottom-modal {{show?'show':''}}\">\n\t<view class=\"dialog\">\n\t\t<view class=\"bar bg-white\">\n\t\t\t<view class=\"action text-gray text-xl\" bindtap=\"bindHideModalTap\">取消</view>\n\t\t\t<view class=\"action text-green text-modal text-xl\" bindtap=\"bindComfirmTap\">确定</view>\n\t\t</view>\n\t\t<view class=\"padding-xl \">\n\t\t\t<slot />\n\t\t</view>\n\t</view>\n</view>\n<!--底部窗口 end-->\n\n\n<!-- 对话窗口 begin -->\n<view wx:if=\"{{type=='dialog'}}\" class=\"modal {{show?'show':''}}\" catchtouchmove=\"nomove\">\n\t<view class=\"dialog modal-dialog\">\n\t\t<view class=\"bar bg-white justify-end\" wx:if=\"{{title}}\">\n\t\t\t<view class=\"content\">{{title}}</view> \n\t\t</view>\n\n\t\t<view wx:if=\"{{subtitle}}\" class=\"subtitle\" style=\"text-align:{{subtitleAlign}}\">{{subtitle}}</view> \n\n\t\t<view class=\"padding-xl slot-class\" style=\"padding-top:0\">\n\t\t\t<slot />\n\t\t</view>\n\t\t<view class=\"modal-bar\"> \n\t\t\t<view class=\"modal-bar-view\" bindtap=\"bindHideModalTap\">{{cancelText}}</view>\n\t\t\t<view wx:if=\"{{showConfirm}}\" class=\"modal-bar-view modal-bar-comfirm\" bindtap=\"bindComfirmTap\">{{confirmText}}</view> \n\t\t</view>\n\t</view>\n</view>\n<!-- 对话窗口 end -->\n\n<!-- 可能超长的对话窗口 begin -->\n<view wx:if=\"{{type=='longdialog'}}\" class=\"modal {{show?'show':''}}\" >\n\t<view class=\"dialog modal-dialog\">\n\t\t<view class=\"bar bg-white justify-end\" wx:if=\"{{title}}\">\n\t\t\t<view class=\"content\">{{title}}</view> \n\t\t</view>\n\n\t\t<view wx:if=\"{{subtitle}}\" class=\"subtitle\" style=\"text-align:{{subtitleAlign}}\">{{subtitle}}</view> \n\n\t\t<view class=\"padding-xl slot-class\" style=\"padding-top:0\">\n\t\t\t<slot />\n\t\t</view>\n\t\t<view class=\"modal-bar\"> \n\t\t\t<view class=\"modal-bar-view\" bindtap=\"bindHideModalTap\">{{cancelText}}</view>\n\t\t\t<view wx:if=\"{{showConfirm}}\" class=\"modal-bar-view modal-bar-comfirm\" bindtap=\"bindComfirmTap\">{{confirmText}}</view> \n\t\t</view>\n\t</view>\n</view>\n<!-- 可能超长的对话窗口 end -->\n\n\n<!-- 图片窗口 begin -->\n<view wx:if=\"{{type=='image'}}\" class=\"modal  {{show?'show':''}}\">\n\t<view class=\"dialog\">\n\t\t<view class=\"bg-img\" style=\"height:{{height}}rpx;\">\n\t\t\t<image class=\"bg-img-image\" mode=\"aspectFill\" src=\"{{imgURL}}\"></image>\n\t\t\t<view class=\"bar justify-end text-white\">\n\t\t\t\t<view class=\"action\" bindtap=\"bindHideModalTap\">\n\t\t\t\t\t<text class=\"icon-close\"></text>\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t</view>\n\t\t<view class=\"bar bg-white\" wx:if=\"{{title}}\">\n\t\t\t<view class=\"action margin-0 flex-sub\">{{title}}</view>\n\t\t</view>\n\t</view>\n</view>\n<!-- 图片窗口 end -->"
  },
  {
    "path": "miniprogram/cmpts/public/modal/modal_cmpt.wxss",
    "content": ".bg-img {\n\twidth: 100%;\n\theight: 100%;\n\tposition: relative;\n}\n\n.bg-img .bg-img-image {\n\ttop: 0;\n\tleft: 0;\n\tposition: absolute;\n\twidth: 100%;\n\theight: 100%;\n}\n\n.bg-img .action .icon-close {\n\tfont-size: 50rpx !important;\n\tfont-weight: bold;\n} \n\n.modal .dialog {\n\tpadding: 20rpx 0rpx; \n\tmargin-top:30rpx; \n}\n\n.modal .dialog .bar {\n\tbackground-color: #f8f8f8;\n}\n\n.modal .dialog .bar .content {\n\tcolor: #333;\n\tfont-size: 36rpx; \n}\n\n.modal-bar {\n\twidth: 100%;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tborder-top: 1rpx solid #ccc;\n\tline-height: 3;\n}\n\n.modal-bar .modal-bar-view {\n\twidth: 50%;\n\tfont-size: 36rpx;\n\tfont-weight: bold;\n}\n\n.modal-bar .modal-bar-comfirm {\n\tcolor: #576B95;\n\tborder-left: 1rpx solid #ccc;\n}\n\n.modal .modal-dialog {\n\tpadding: 10rpx 0rpx 0;\n}\n\n.modal .modal-dialog .subtitle {\n\twidth:100%;\n\ttext-align: center;\n\tfont-size:30rpx;\n\tcolor:#777;\n\tpadding:0 60rpx;\n\tmargin-top:10rpx;\n\tmargin-bottom:20rpx;\n}"
  },
  {
    "path": "miniprogram/cmpts/public/picker/picker_cmpt.js",
    "content": "const helper = require('../../../helper/helper.js');\nconst dataHelper = require('../../../helper/data_helper.js');\nconst pageHelper = require('../../../helper/page_helper.js');\n\nComponent({\n\texternalClasses: ['outside-picker-class'],\n\n\toptions: {\n\t\t//addGlobalClass: true\n\t},\n\n\t/**\n\t * 一维格式： 可以通过model返回\n\t * 对象格式： {label:'对象A',val:'5'}, {label:'对象B',val:'12'}, {label:'对象C',val:'99'}\n\t * 简单形式：['形式1','形式2','形式33'] \n\t * 字符串形式\n\t */\n\n\t/**\n\t * N维格式： 只能通过trigger返回\n\t * 对象格式： {label:'对象A',val:'5'}, {label:'对象B',val:'12'}, {label:'对象C',val:'99'}\n\t * 简单形式：['形式1','形式2','形式33'] \n\t * \n\t */\n\tproperties: {\n\t\tmark: {\n\t\t\ttype: String,\n\t\t\tvalue: '',\n\t\t},\n\t\tisSlot: { //是否开启slot\n\t\t\ttype: Boolean,\n\t\t\tvalue: false,\n\t\t},\n\t\tsourceData: { //源数组，sourceData有几维，Picker就可以有几阶 简单形式待选项,,,\n\t\t\ttype: Array,\n\t\t\tvalue: [],\n\t\t},\n\n\t\tsourceDataStr: { //源数组，sourceData有几维，Picker就可以有几阶 简单形式待选项,,,\n\t\t\ttype: String,\n\t\t\tvalue: '',\n\t\t},\n\n\t\t// key\n\t\tlabelKey: {\n\t\t\ttype: String,\n\t\t\tvalue: ''\n\t\t},\n\n\t\t// 阶数\n\t\tsteps: {\n\t\t\ttype: Number,\n\t\t\tvalue: 1\n\t\t},\n\n\t\tnoDataHint: { // 无数据的提示语\n\t\t\ttype: String,\n\t\t\tvalue: '请选择',\n\t\t},\n\n\t\t// 选中项的下标数组 1维\n\t\tindex: {\n\t\t\ttype: Number,\n\t\t\tvalue: 0\n\t\t},\n\t\t// 选中项的下标数组 N维\n\t\tindexMulti: {\n\t\t\ttype: Array,\n\t\t\tvalue: []\n\t\t},\n\t\t// 默认选中项的值数组 1维\n\t\titem: {\n\t\t\ttype: String,\n\t\t\tvalue: '',\n\t\t\tobserver: function (newVal, oldVal) {\n\t\t\t\t//\tconsole.log('one observer', this.data.mark);\n\t\t\t\tif (newVal != oldVal) {\n\t\t\t\t\tlet options = this.data.options;\n\t\t\t\t\tif (!options || options.length == 0) this._init();\n\t\t\t\t\tif (options && options.length > 0) this.selected(newVal);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t// 默认选中项的值数组 N维\n\t\titemMulti: {\n\t\t\ttype: Array,\n\t\t\tvalue: [],\n\t\t\tobserver: function (newVal, oldVal) {\n\t\t\t\t//\tconsole.log('multi observer', this.data.mark);\n\t\t\t\tif (JSON.stringify(newVal) != JSON.stringify(oldVal)) {\n\t\t\t\t\tlet options = this.data.options;\n\t\t\t\t\tif (!options || options.length == 0) this._init();\n\t\t\t\t\tif (options && options.length > 0) this.selected(newVal);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t// 是否禁用\n\t\tdisabled: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: false,\n\t\t},\n\n\t\tdisabledHint: { //  禁用提示\n\t\t\ttype: String,\n\t\t\tvalue: '',\n\t\t},\n\t},\n\n\t/**\n\t * 组件的初始数据\n\t */\n\tdata: {\n\t\toptions: null,\n\t\tidx: 0,\n\t\tmultiDesc: '', // 多选的显示文字\n\t},\n\n\t/**\n\t * 生命周期方法\n\t */\n\tlifetimes: {\n\t\tattached: function () { },\n\n\t\tready: function () {\n\t\t\tif (!this.data.options || this.data.options.length == 0) this._init();\n\t\t},\n\n\t\tdetached: function () {\n\t\t\t// 在组件实例被从页面节点树移除时执行\n\t\t},\n\n\t},\n\n\t/**\n\t * 组件的方法列表\n\t */\n\tmethods: {\n\t\t_init: function () {\n\t\t\tlet sourceData = this.data.sourceData;\n\t\t\tlet labelKey = this.data.labelKey;\n\t\t\tlet idx = this.data.idx;\n\n\t\t\t// 字符串形式\n\t\t\tif (this.data.steps == 1 &&\n\t\t\t\tthis.data.sourceDataStr &&\n\t\t\t\t(!sourceData || sourceData.length == 0)\n\t\t\t) {\n\t\t\t\tsourceData = dataHelper.getSelectOptions(this.data.sourceDataStr);\n\t\t\t\tthis.setData({\n\t\t\t\t\tsourceData\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (!sourceData || sourceData.length == 0) return;\n\n\t\t\tif (this.data.steps == 1) {\n\t\t\t\tif (sourceData.length > 0 && helper.isDefined(sourceData[0]['label'])) {\n\t\t\t\t\tlabelKey = 'label';\n\t\t\t\t}\n\t\t\t\tidx = this.data.index;\n\t\t\t} else if (this.data.steps > 1) {\n\t\t\t\tif (sourceData.length > 0 && helper.isDefined(sourceData[0][0]['label'])) {\n\t\t\t\t\tlabelKey = 'label';\n\t\t\t\t}\n\t\t\t\tidx = this.data.indexMulti;\n\t\t\t}\n\n\t\t\tthis.setData({\n\t\t\t\tidx,\n\t\t\t\tlabelKey,\n\t\t\t\toptions: sourceData\n\t\t\t});\n\t\t\tthis._getMultiDesc();\n\n\t\t\tif (this.data.steps == 1)\n\t\t\t\tthis.selected(this.data.item);\n\t\t\telse\n\t\t\t\tthis.selected(this.data.itemMulti);\n\t\t},\n\n\t\t_getMultiDesc: function () {\n\t\t\tlet idx = this.data.idx;\n\t\t\tlet options = this.data.options;\n\t\t\tif (idx.length != options.length) return;\n\n\t\t\tlet multiDesc = [];\n\t\t\tif (this.data.labelKey) {\n\t\t\t\tfor (let k = 0; k < options.length; k++) {\n\t\t\t\t\tmultiDesc[k] = options[k][idx[k]].label;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (let k = 0; k < options.length; k++) {\n\t\t\t\t\tmultiDesc[k] = options[k][idx[k]];\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.setData({\n\t\t\t\tmultiDesc\n\t\t\t});\n\t\t},\n\n\t\tbindTap: function (e) { // 点击行为\n\t\t\tif (this.data.disabled && this.data.disabledHint) {\n\t\t\t\tpageHelper.showModal(this.data.disabledHint, '提示', null, '知道了');\n\t\t\t}\n\t\t},\n\n\t\t// 触发改变\n\t\tbindChange: function (e) {\n\t\t\tlet idx = e.detail.value;\n\t\t\tlet val = null;\n\n\t\t\tif (this.data.steps == 1) {\n\t\t\t\tval = this.data.labelKey ? this.data.options[idx].val : this.data.options[idx];\n\t\t\t\tthis.setData({\n\t\t\t\t\titem: val,\n\t\t\t\t\tindex: idx\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tval = [];\n\t\t\t\tlet options = this.data.options;\n\t\t\t\tif (this.data.labelKey) {\n\t\t\t\t\tfor (let k = 0; k < options.length; k++) {\n\t\t\t\t\t\tval[k] = options[k][idx[k]].val;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfor (let k = 0; k < options.length; k++) {\n\t\t\t\t\t\tval[k] = options[k][idx[k]];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis._getMultiDesc();\n\t\t\t}\n\n\t\t\tthis.triggerEvent('select', val);\n\t\t},\n\n\t\t// 一维数组根据val获取lable\n\t\tgetLabelOneStep: function (val) {\n\t\t\tfor (let k = 0; k < this.data.sourceData.length; k++) {\n\t\t\t\tif (this.data.sourceData[k].val == val) return this.data.sourceData[k].label;\n\t\t\t}\n\t\t\treturn 'unknown';\n\t\t},\n\n\t\t// 选中值 \n\t\tselected: function (val) {\n\t\t\tlet options = this.data.options;\n\t\t\tlet labelKey = this.data.labelKey;\n\t\t\tif (this.data.steps == 1) {\n\t\t\t\tfor (let k = 0; k < options.length; k++) {\n\t\t\t\t\tif (labelKey && val == options[k].val) {\n\t\t\t\t\t\tthis.setData({\n\t\t\t\t\t\t\tidx: k\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else if (!labelKey && val == options[k]) {\n\n\t\t\t\t\t\tthis.setData({\n\t\t\t\t\t\t\tidx: k\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis.setData({\n\t\t\t\t\tidx: -1\n\t\t\t\t});\n\n\t\t\t\t//传入数据不匹配的时候，修正父页面传入的的默认值\n\t\t\t\tthis.triggerEvent('select', '');\n\n\t\t\t} else if (this.data.steps > 1) {\n\t\t\t\tlet idx = [];\n\t\t\t\tfor (let k = 0; k < options.length; k++) {\n\t\t\t\t\tlet levelTwo = options[k];\n\t\t\t\t\tfor (let j in levelTwo) {\n\t\t\t\t\t\tif (labelKey && val[k] == options[k][j].val) {\n\t\t\t\t\t\t\tidx.push(j);\n\t\t\t\t\t\t} else if (!labelKey && val[k] == options[k][j]) {\n\t\t\t\t\t\t\tidx.push(j);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (idx.length != options.length) idx = [];\n\t\t\t\tthis.setData({\n\t\t\t\t\tidx\n\t\t\t\t});\n\t\t\t\tthis._getMultiDesc();\n\n\t\t\t\t//传入数据不匹配的时候，修正父页面传入的的数组默认值 TODO\n\t\t\t}\n\n\n\t\t}\n\t}\n})"
  },
  {
    "path": "miniprogram/cmpts/public/picker/picker_cmpt.json",
    "content": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/picker/picker_cmpt.wxml",
    "content": "<picker class=\"{{disabled?'disabled':''}}\" wx:if=\"{{steps==1}}\" mode=\"selector\" value=\"{{idx==-1?0:idx}}\" range=\"{{options}}\" range-key=\"{{labelKey}}\" bindchange=\"bindChange\" disabled=\"{{disabled}}\">\n\t<view wx:if=\"{{!isSlot}}\" class=\"picker-cmpt outside-picker-class\">\n\t\t<block wx:if=\"{{labelKey}}\">{{options[idx].label || noDataHint}}</block>\n\t\t<block wx:else>{{options[idx] || noDataHint}}</block>\n\t</view>\n\t<slot wx:else />\n</picker>\n\n<picker class=\"{{disabled?'disabled':''}}\" wx:if=\"{{steps>1}}\" mode=\"multiSelector\" value=\"{{idx}}\" range=\"{{options}}\" range-key=\"{{labelKey}}\" bindtap=\"bindTap\" bindchange=\"bindChange\" disabled=\"{{disabled}}\">\n\t<view wx:if=\"{{!isSlot}}\" class=\"picker-cmpt outside-picker-class\">\n\t\t{{multiDesc || noDataHint}}\n\t</view>\n\t<slot wx:else />\n</picker>"
  },
  {
    "path": "miniprogram/cmpts/public/picker/picker_cmpt.wxss",
    "content": ".picker-cmpt {\n\tline-height: 100rpx;\n\tfont-size: 28rpx;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n\toverflow: hidden;\n\twidth: 100%;\n\ttext-align: right;\n\tpadding-right: 40rpx;\n}\n\n.disabled {\n\tbackground-color: #eee;\n\tcolor:#999; \n}\n\n.picker-cmpt::before {\n\tposition: absolute;\n\ttop: 0;\n\tright: 30rpx;\n\tbottom: 0;\n\tdisplay: block;\n\tmargin: auto;\n\twidth: 30rpx;\n\theight: 30rpx;\n\tcolor: var(--grey);\n\tcontent: \"\\e6a3\";\n\ttext-align: center;\n\tfont-size: 34rpx;\n\tfont-family: \"icon\";\n\tline-height: 30rpx;\n\tmargin-top: auto;\n\tmargin-right: auto;\n\tmargin-bottom: auto;\n\tmargin-left: auto;\n}"
  },
  {
    "path": "miniprogram/cmpts/public/picker_multi/picker_multi_cmpt.js",
    "content": "/* 参考文档: https://github.com/IceApriler/miniprogram-picker */\n/*\n[{\n\tlabel:'ddd' // 展示数据的字段名称\n\tval:'v1',\n},\n{\n\tlabel:'cccc',\n\tval:'v2'\n}]\n*/\nconst dataHelper = require('../../../helper/data_helper.js');\n\nfunction isExist(field) {\n\treturn field !== null && field !== undefined\n}\n\nComponent({\n\texternalClasses: ['outside-picker-multi-class'],\n\t/**\n\t * 组件的属性列表\n\t */\n\tproperties: {\n\t\t// 特定类型 time\n\t\tmode: { // minute\n\t\t\ttype: String,\n\t\t\tvalue: ''\n\t\t},\n\n\t\t// time特定类型 对应的分钟步长\n\t\ttimeModeStep: {\n\t\t\ttype: Number,\n\t\t\tvalue: 1\n\t\t},\n\n\t\t// 初始化时，是否需要自动返回结果给开发者\n\t\tautoSelect: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: false\n\t\t},\n\t\t// 源数组，sourceData有几维，Picker就可以有几阶\n\t\tsourceData: {\n\t\t\ttype: Array,\n\t\t\tvalue: [],\n\t\t\tobserver: 'sourceDataChange'\n\t\t},\n\t\t// 阶数\n\t\tsteps: {\n\t\t\ttype: Number,\n\t\t\tvalue: 1\n\t\t},\n\n\t\t// 选择了第n列后，是否将大于n的列的选择值自动初始化为0\n\t\tinitColumnSelectedIndex: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: false,\n\t\t},\n\t\t// 默认选中项的下标数组\n\t\titemIndex: {\n\t\t\ttype: Array,\n\t\t\tvalue: []\n\t\t},\n\t\t// 默认选中项的值数组\n\t\titemMulti: {\n\t\t\ttype: Array,\n\t\t\tvalue: [],\n\t\t\tobserver: function (newVal, oldVal) {  \n\t\t\t\tif (JSON.stringify(newVal) != JSON.stringify(oldVal)) { \n\t\t\t\t\tthis.sourceDataChange(this.data.sourceData);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t// 是否禁用\n\t\tdisabled: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: false,\n\t\t},\n\t\tisSlot: { //是否开启slot\n\t\t\ttype: Boolean,\n\t\t\tvalue: true,\n\t\t},\n\t},\n\n\t/**\n\t * 组件的初始数据\n\t */\n\tdata: {\n\n\t\t// Picker当前所选择的索引数组 => 比如:[0, 0, 2]，表示第一列选择第0项，第二列选择第0项，第三列选择第2项。\n\t\tmultiIndex: {\n\t\t\ttype: Array,\n\t\t\tvalue: [],\n\t\t},\n\t\t// Picker当前所展示的数组 => 比如:[['河北', '山东'], ['石家庄', '保定'], ['桥西区', '裕华区', '长安区']]。\n\t\tmultiArray: {\n\t\t\ttype: Array,\n\t\t\tvalue: [],\n\t\t},\n\t\t// 用户点击确定后，所选择的值数组 => 比如:\n\t\t// [{name: '河北', id: '3110'}, {name: '石家庄', id: '3110xx'}, {name: '长安区', id: '3110xxx'}]。\n\t\tselectedArray: {\n\t\t\ttype: Array,\n\t\t\tvalue: [],\n\t\t},\n\n\t},\n\t/**\n\t * 生命周期方法\n\t */\n\tlifetimes: {\n\t\tcreated: function () {},\n\t\tattached: function () {\n\n\t\t\tif (this.data.autoSelect) {\n\t\t\t\tthis.processData();\n\t\t\t}\n\t\t},\n\n\t\tready: function () {\n\n\t\t},\n\n\t\tdetached: function () {\n\t\t\t// 在组件实例被从页面节点树移除时执行\n\t\t},\n\t},\n\n\tpageLifetimes: {\n\t\tshow: function () {\n\n\t\t},\n\t\thide: function () {\n\t\t\t// 页面被隐藏\n\t\t},\n\t\tresize: function (size) {\n\t\t\t// 页面尺寸变化\n\t\t}\n\t},\n\n\t/**\n\t * 组件的方法列表\n\t */\n\tmethods: {\n\t\t/**\n\t\t * 监听源数组更新变化\n\t\t *\n\t\t * @param {Array} newSourceData 源数组，newSourceData有几维，Picker就可以有几阶。\n\t\t */\n\t\tsourceDataChange: function (newSourceData) {\n\t\t\tconst {\n\t\t\t\tsteps\n\t\t\t} = this.data;\n\t\t\t// 源数组更新，则需要更新multiIndex、multiArray\n\t\t\tconst multiIndex = [];\n\t\t\tconst multiArray = [];\n\t\t\tnewSourceData = this.checkSourceData(newSourceData);\n\n\t\t\t// console.warn(newSourceData) \n\t\t\tconst itemIndex = this.getDefaultIndex(newSourceData);\n\t\t\tconst handle = (source = [], columnIndex = 0) => {\n\t\t\t\t// 当前遍历Picker的第columnIndex列，\n\t\t\t\t// 当columnIndex = 0时，source表示sourceData，其它则表示子集subset\n\t\t\t\tconst _multiArrayColumn0 = [];\n\n\t\t\t\tsource.forEach((item, index) => {\n\t\t\t\t\tif (columnIndex === 0) {\n\t\t\t\t\t\t// newSourceData的第0维要单独处理，最后unshift到multiArray中\n\t\t\t\t\t\t_multiArrayColumn0.push(item.label)\n\t\t\t\t\t}\n\n\t\t\t\t\tif (isExist(item.label) && index === (itemIndex[columnIndex] || 0)) {\n\t\t\t\t\t\t// 选中的索引和值，默认取每列的第0个\n\t\t\t\t\t\tmultiIndex.push(index);\n\n\t\t\t\t\t\tif (columnIndex < steps - 1) {\n\t\t\t\t\t\t\tif (isExist(item.children)) {\n\t\t\t\t\t\t\t\t// 开始处理下一维的数据\n\t\t\t\t\t\t\t\tconst _subsetArr = item.children.map(sub => sub.label);\n\t\t\t\t\t\t\t\tmultiArray.push(_subsetArr);\n\t\t\t\t\t\t\t\thandle(item.children, columnIndex + 1);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t})\n\n\t\t\t\tif (columnIndex === 0) {\n\t\t\t\t\tmultiArray.unshift(_multiArrayColumn0);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\thandle(newSourceData);\n\n\t\t\tthis.setData({\n\t\t\t\tmultiIndex,\n\t\t\t\tmultiArray\n\t\t\t})\n\n\t\t\tif (this.data.autoSelect) {\n\t\t\t\tthis.processData();\n\t\t\t} \n \n\t\t},\n\t\t/**\n\t\t * 获取默认值index\n\t\t * @param {Array} newSourceData 源数组\n\t\t */\n\t\tgetDefaultIndex: function (newSourceData) {\n\t\t\tconst {\n\t\t\t\titemIndex,\n\t\t\t\titemMulti,\n\t\t\t\tsteps,\n\t\t\t} = this.data;\n\t\t\tif (itemIndex.length) {\n\t\t\t\treturn itemIndex; // 返回默认选中的下标数据\n\t\t\t} else if (itemMulti.length) {\n\t\t\t\tif (itemMulti.length !== steps) {\n\t\t\t\t\tthis.consoleError(new Error('你设置的\"itemMulti\"字段阶数与\"steps\"不符，请修改后再试。'));\n\t\t\t\t\treturn [];\n\t\t\t\t} else {\n\t\t\t\t\tconst _defaultIndex = [];\n\t\t\t\t\tconst handle = (source = [], columnIndex = 0) => {\n\t\t\t\t\t\t// 默认值\n\t\t\t\t\t\t_defaultIndex[columnIndex] = 0;\n\t\t\t\t\t\tsource.forEach((item, index) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t(itemMulti[columnIndex]) ===\n\t\t\t\t\t\t\t\t(item.val)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t_defaultIndex[columnIndex] = index;\n\n\t\t\t\t\t\t\t\tif (columnIndex < steps - 1) {\n\t\t\t\t\t\t\t\t\tif (item.children) {\n\t\t\t\t\t\t\t\t\t\t// 开始处理下一维的数据\n\t\t\t\t\t\t\t\t\t\thandle(item.children, columnIndex + 1);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\thandle(newSourceData);\n\t\t\t\t\treturn _defaultIndex;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * 校验源数组是否正确\n\t\t *\n\t\t * @param {Array} sourceData 源数组\n\t\t */\n\t\tcheckSourceData: function (sourceData) {\n\t\t\tconst {\n\t\t\t\tsteps\n\t\t\t} = this.data;\n\t\t\tconst handle = (source = [], columnIndex = 0) => {\n\t\t\t\t// 当前遍历Picker的第columnIndex列，\n\t\t\t\t// 当columnIndex = 0时，source表示sourceData，其它则表示子集subset\n\t\t\t\tif (!source.length) {\n\t\t\t\t\tconst temp = {};\n\t\t\t\t\ttemp.label = '';\n\t\t\t\t\ttemp.children = [];\n\t\t\t\t\tsource.push(temp);\n\t\t\t\t}\n\t\t\t\treturn source.map((item) => {\n\t\t\t\t\t// 有label字段才会去遍历children字段\n\t\t\t\t\tif (columnIndex < steps - 1) {\n\t\t\t\t\t\t// 开始处理下一维的数据\n\t\t\t\t\t\titem.children = handle(item.children, columnIndex + 1);\n\t\t\t\t\t}\n\t\t\t\t\treturn item;\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn handle(sourceData);\n\t\t},\n\n\t\t/**\n\t\t * 用户点击了确认。\n\t\t *\n\t\t * @param {Object} e 事件对象，具体参考微信小程序api。\n\t\t * @param {Array} e.detail.value 用户选择的下标数组。\n\t\t */\n\t\tpickerChange: function (e) {\n\t\t\t// console.log('picker发送选择改变，携带值为', e.detail.value)\n\n\t\t\tthis.setData({\n\t\t\t\tmultiIndex: e.detail.value\n\t\t\t})\n\t\t\tthis.processData();\n\t\t},\n\n\t\t/**\n\t\t * 处理最终数据，将返回给开发者。\n\t\t *\n\t\t */\n\t\tprocessData: function () {\n\t\t\tconst {\n\t\t\t\tsourceData,\n\t\t\t\tmultiIndex\n\t\t\t} = this.data;\n\t\t\tlet selectedArray = [];\n\n\t\t\tconst handle = (source = [], columnIndex = 0) => {\n\t\t\t\tsource.forEach((item, index) => {\n\t\t\t\t\tif (index === multiIndex[columnIndex]) {\n\t\t\t\t\t\tlet node = dataHelper.deepClone(item);\n\t\t\t\t\t\tdelete node.children;\n\t\t\t\t\t\tselectedArray.push(node);\n\t\t\t\t\t\tif (columnIndex < this.data.steps - 1) {\n\t\t\t\t\t\t\thandle(item.children, columnIndex + 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t\thandle(sourceData);\n\n\t\t\tthis.setData({\n\t\t\t\tselectedArray\n\t\t\t});\n\n\t\t\t/*\n\t\t\tconst detail = {\n\t\t\t\tselectedIndex: this.data.multiIndex,\n\t\t\t\tselectedArray: this.data.selectedArray\n\t\t\t}*/\n\n\t\t\tlet ret = dataHelper.getArrByKey(selectedArray, 'val');\n\n\t\t\tthis.triggerEvent('select', ret);\n\t\t},\n\n\t\t/**\n\t\t * 用户滚动了某一列。\n\t\t *\n\t\t * @param {Object} e 事件对象，具体参考微信小程序api。\n\t\t */\n\t\tpickerColumnChange: function (e) {\n\t\t\tconst {\n\t\t\t\tmultiArray,\n\t\t\t\tsourceData,\n\t\t\t\tsteps,\n\t\t\t\tinitColumnSelectedIndex\n\t\t\t} = this.data;\n\t\t\tlet {\n\t\t\t\tmultiIndex\n\t\t\t} = this.data;\n\t\t\tconst {\n\t\t\t\tcolumn,\n\t\t\t\tvalue: changeIndex\n\t\t\t} = e.detail;\n\n\t\t\t// console.log(`修改了Picker的第${column}列(从0开始计算)，选中了第${changeIndex}个值(从0开始计算)`)\n\n\t\t\t// multiIndex变化了，所以也要同步更新multiArray\n\t\t\tmultiIndex[column] = changeIndex;\n\n\t\t\tif (initColumnSelectedIndex) {\n\t\t\t\t// 每次重置之后的index为0，但是有bug，待定。 => 经检查，是编辑器的问题，真机上是没有问题的。\n\t\t\t\tconst _multiIndex = multiIndex.map((item, index) => {\n\t\t\t\t\tif (column >= index) {\n\t\t\t\t\t\treturn item;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn 0;\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\tmultiIndex = _multiIndex;\n\t\t\t}\n\n\t\t\tconst handle = (source = [], columnIndex = 0) => {\n\t\t\t\t// 当前遍历第 columnIndex 列\n\t\t\t\tsource.forEach((item, index) => {\n\t\t\t\t\tif (index === multiIndex[columnIndex]) {\n\t\t\t\t\t\tif (columnIndex < steps - 1) {\n\t\t\t\t\t\t\tif (!item.children) {\n\t\t\t\t\t\t\t\titem.children = [];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst multiArrayItem = item.children.map((sub) => sub.label);\n\t\t\t\t\t\t\t// 从第1列开始，才有可能变化\n\t\t\t\t\t\t\tmultiArray[columnIndex + 1] = multiArrayItem;\n\n\t\t\t\t\t\t\thandle(item.children, columnIndex + 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t\thandle(sourceData);\n\n\t\t\tthis.setData({\n\t\t\t\tmultiArray,\n\t\t\t\tmultiIndex,\n\t\t\t})\n\t\t\tthis.triggerEvent('columnchange', e);\n\t\t},\n\t\t/**\n\t\t * 用户点击了取消触发\n\t\t * @param {Object} e 事件对象\n\t\t */\n\t\tpickerCancel: function (e) {\n\t\t\tthis.triggerEvent('cancel', e);\n\t\t},\n\t\t/**\n\t\t * 绑定console.error\n\t\t * @param  {...any} arg 打印参数\n\t\t */\n\t\tconsoleError: function (...arg) {\n\t\t\tconsole.error(...arg);\n\t\t},\n\n\n\t},\n\n})"
  },
  {
    "path": "miniprogram/cmpts/public/picker_multi/picker_multi_cmpt.json",
    "content": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/picker_multi/picker_multi_cmpt.wxml",
    "content": "<picker class=\"multi-picker picker-class\" mode=\"multiSelector\" bindchange=\"pickerChange\" bindcolumnchange=\"pickerColumnChange\" bindcancel=\"pickerCancel\" disabled=\"{{disabled}}\" value=\"{{multiIndex}}\" range=\"{{multiArray}}\">\n\t<slot wx:if=\"{{isSlot}}\" />\n\t<block wx:else>\n\t\t<block wx:if=\"{{multiIndex.length==2}}\">\n\t\t\t{{multiArray[0][multiIndex[0]]}}，{{multiArray[1][multiIndex[1]]}}\n\t\t</block>\n\t\t<block wx:if=\"{{multiIndex.length==3}}\">\n\t\t\t{{multiArray[0][multiIndex[0]]}}，{{multiArray[1][multiIndex[1]]}}，{{multiArray[2][multiIndex[2]]}}\n\t\t</block>\n\t\t<block wx:if=\"{{multiIndex.length==4}}\">\n\t\t\t{{multiArray[0][multiIndex[0]]}}，{{multiArray[1][multiIndex[1]]}}，{{multiArray[2][multiIndex[2]]}}，{{multiArray[3][multiIndex[3]]}}\n\t\t</block>\n\t\t<block wx:if=\"{{multiIndex.length==5}}\">\n\t\t\t{{multiArray[0][multiIndex[0]]}}，{{multiArray[1][multiIndex[1]]}}，{{multiArray[2][multiIndex[2]]}}，{{multiArray[3][multiIndex[3]]}}，{{multiArray[4][multiIndex[4]]}}\n\t\t</block>\n\t</block>\n</picker>"
  },
  {
    "path": "miniprogram/cmpts/public/picker_multi/picker_multi_cmpt.wxss",
    "content": ".picker-cmpt {\n\tline-height: 100rpx;\n\tfont-size: 28rpx;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n\toverflow: hidden;\n\twidth: 100%;\n\ttext-align: right;\n}"
  },
  {
    "path": "miniprogram/cmpts/public/picker_time/datetime_picker.js",
    "content": "const timeHelper = require('../../../helper/time_helper.js');\n\nfunction withData(param, unit = '') {\n\tif (unit) return param;\n\treturn param < 10 ? '0' + param : '' + param;\n}\n\nfunction getLoopArray(start, end, unit = '', step = 1) {\n\tstart = start || 0;\n\tend = end || 1;\n\tstart = parseInt(start);\n\tend = parseInt(end);\n\n\tlet array = [];\n\tlet i = 0;\n\tfor (i = start; i <= end;) {\n\t\tarray.push(withData(i, unit) + unit);\n\t\ti += step;\n\t}\n\n\tif (step > 1 && i != 59) {\n\t\tarray.push(withData(59, unit) + unit);\n\t}\n\n\treturn array;\n}\n\nfunction getMonthDay(year, month, unit = '') {\n\tlet flag = year % 400 == 0 || (year % 4 == 0 && year % 100 != 0),\n\t\tarray = null;\n\tmonth = withData(parseInt(month));\n\tswitch (month) {\n\t\tcase '01':\n\t\tcase '03':\n\t\tcase '05':\n\t\tcase '07':\n\t\tcase '08':\n\t\tcase '10':\n\t\tcase '12':\n\t\t\tarray = getLoopArray(1, 31, unit);\n\t\t\tbreak;\n\t\tcase '04':\n\t\tcase '06':\n\t\tcase '09':\n\t\tcase '11':\n\t\t\tarray = getLoopArray(1, 30, unit);\n\t\t\tbreak;\n\t\tcase '02':\n\t\t\tarray = flag ? getLoopArray(1, 29, unit) : getLoopArray(1, 28, unit);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tarray = '月份格式不正确，请重新输入！'\n\t}\n\treturn array;\n}\n\nfunction getNewDateArry() {\n\t// 当前时间的处理\n\tlet newDate = new Date();\n\tlet year = withData(newDate.getFullYear()),\n\t\tmont = withData(newDate.getMonth() + 1),\n\t\tdate = withData(newDate.getDate()),\n\t\thour = withData(newDate.getHours()),\n\t\tminu = withData(newDate.getMinutes()),\n\t\tseco = withData(newDate.getSeconds());\n\n\treturn [year, mont, date, hour, minu, seco];\n}\n\nfunction dateTimePicker(startYear, endYear, date, minuStep = 1) {\n\t// 返回默认显示的数组和联动数组的声明\n\tlet dateTimeIndex = [],\n\t\tdateTimeArray = [\n\t\t\t[],\n\t\t\t[],\n\t\t\t[],\n\t\t\t[],\n\t\t\t[],\n\t\t\t[]\n\t\t];\n\tlet dateTimeArrayPure = [\n\t\t[],\n\t\t[],\n\t\t[],\n\t\t[],\n\t\t[],\n\t\t[]\n\t];\n\n\tlet start = startYear || 1978;\n\tlet end = endYear || 2100;\n\n\tif (date && date.length == 4) date += '-01-01 00:00:00';\n\tif (date && date.length == 7) date += '-01 00:00:00';\n\tif (date && date.length == 10) date += ' 00:00:00';\n\tif (date && date.length == 13) date += ':00:00';\n\tif (date && date.length == 16) date += ':00';\n\n\t// 默认开始显示数据\n\tlet defaultDate = date ? [...date.split(' ')[0].split('-'), ...date.split(' ')[1].split(':')] : getNewDateArry();\n\n\t// 处理联动列表数据\n\t/*年月日 时分秒*/\n\tdateTimeArray[0] = getLoopArray(start, end, '年');\n\tdateTimeArray[1] = getLoopArray(1, 12, '月');\n\tdateTimeArray[2] = getMonthDay(defaultDate[0], defaultDate[1], '日');\n\tdateTimeArray[3] = getLoopArray(0, 23, '点');\n\tdateTimeArray[4] = getLoopArray(0, 59, '分', minuStep);\n\tdateTimeArray[5] = getLoopArray(0, 59, '秒');\n\n\tdateTimeArrayPure[0] = getLoopArray(start, end);\n\tdateTimeArrayPure[1] = getLoopArray(1, 12);\n\tdateTimeArrayPure[2] = getMonthDay(defaultDate[0], defaultDate[1]);\n\tdateTimeArrayPure[3] = getLoopArray(0, 23);\n\tdateTimeArrayPure[4] = getLoopArray(0, 59, '', minuStep);\n\tdateTimeArrayPure[5] = getLoopArray(0, 59);\n\n\tdateTimeArrayPure.forEach((current, index) => {\n\t\tlet idx = current.indexOf(defaultDate[index]);\n\t\tif (idx < 0) idx = 0;\n\t\tdateTimeIndex.push(idx);\n\t});\n\n\treturn {\n\t\tdateTimeArray,\n\t\tdateTimeIndex\n\t}\n}\nmodule.exports = {\n\tdateTimePicker,\n\tgetMonthDay\n}"
  },
  {
    "path": "miniprogram/cmpts/public/picker_time/picker_time_cmpt.js",
    "content": "const timeHelper = require('../../../helper/time_helper.js');\nconst dateTimePicker = require('./datetime_picker.js');\n\nComponent({\n\texternalClasses: ['picker-class'],\n\n\t/**\n\t * 组件的属性列表\n\t */\n\tproperties: {\n\t\tmark: {\n\t\t\ttype: String,\n\t\t\tvalue: ''\n\t\t},\n\n\t\t// 特定类型 time  minute=单纯时间分钟选择\n\t\tmode: { // year/month/day/hour/minute/fullminute/second\n\t\t\ttype: String,\n\t\t\tvalue: 'second'\n\t\t},\n\n\t\t// time特定类型 对应的分钟步长\n\t\ttimeModeStep: {\n\t\t\ttype: Number,\n\t\t\tvalue: 5\n\t\t},\n\n\t\tstartYear: {\n\t\t\ttype: Number,\n\t\t\tvalue: 0\n\t\t},\n\t\tendYear: {\n\t\t\ttype: Number,\n\t\t\tvalue: 2030\n\t\t},\n\t\titem: {\n\t\t\ttype: String,\n\t\t\tvalue: '',\n\t\t\tobserver: function (newVal, oldVal) {\n\t\t\t\tif (newVal != oldVal) {\n\t\t\t\t\tthis._init();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t},\n\n\t/**\n\t * 组件的初始数据\n\t */\n\tdata: {\n\t\tmultiIndex: [], //  Picker当前所选择的索引数组\n\t\tmultiArray: [], // Picker当前所展示的数组 \n\t},\n\n\tlifetimes: {\n\t\tcreated: function () { },\n\t\tattached: function () { },\n\n\t\tready: function () {\n\t\t\t// 当前年份\n\t\t\tif (this.data.startYear == 0) this.data.startYear = timeHelper.time('Y');\n\n\t\t\t// 单纯分钟选择\n\t\t\tif (this.data.mode == 'minute') {\n\t\t\t\tthis.data.startYear = 2021;\n\t\t\t\tthis.data.endYear = 2021;\n\t\t\t\tif (this.data.item) {\n\t\t\t\t\tthis.data.item = '2021-01-01 ' + this.data.item;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis._init();\n\t\t},\n\n\t\tdetached: function () {\n\t\t\t// 在组件实例被从页面节点树移除时执行\n\t\t},\n\t},\n\n\t/**\n\t * 组件的方法列表\n\t */\n\tmethods: {\n\t\t_fmtTime: function (str) {\n\t\t\tstr = str.replace(/[^0-9]/ig, '');\n\t\t\tstr = parseInt(str);\n\t\t\treturn str < 10 ? '0' + str : '' + str;\n\t\t},\n\t\t// 根据选择获取时间字符串\n\t\t_getTimeStr: function (selIdex) {\n\t\t\tlet arr = [];\n\t\t\tlet multiArray = this.data.multiArray;\n\t\t\tfor (let k = 0; k < selIdex.length; k++) {\n\t\t\t\tlet str = this._fmtTime(multiArray[k][selIdex[k]]);\n\t\t\t\tarr.push(str);\n\t\t\t}\n\n\t\t\tlet mode = this.data.mode;\n\t\t\tswitch (mode) {\n\t\t\t\tcase 'year':\n\t\t\t\t\tarr = arr[0];\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'month':\n\t\t\t\t\tarr = arr[0] + '-' + arr[1];\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'day':\n\t\t\t\t\tarr = arr[0] + '-' + arr[1] + '-' + arr[2];\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'hour':\n\t\t\t\t\tarr = arr[0] + '-' + arr[1] + '-' + arr[2] + ' ' + arr[3] + ':00';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'fullminute':\n\t\t\t\t\tarr = arr[0] + '-' + arr[1] + '-' + arr[2] + ' ' + arr[3] + ':' + arr[4];\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'minute':\n\t\t\t\t\tarr = arr[0] + ':' + arr[1];\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'second':\n\t\t\t\t\tarr = arr[0] + '-' + arr[1] + '-' + arr[2] + ' ' + arr[3] + ':' + arr[4] + ':' + arr[5];\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\treturn arr;\n\t\t},\n\n\t\t_init: function () {\n\t\t\tlet multiIndex = [];\n\t\t\tlet multiArray = [];\n\n\t\t\tlet mode = this.data.mode;\n\n\t\t\tlet obj = dateTimePicker.dateTimePicker(this.data.startYear, this.data.endYear, this.data.item, this.data.timeModeStep);\n\t\t\tlet idx = obj.dateTimeIndex;\n\t\t\tlet arr = obj.dateTimeArray;\n\n\t\t\tswitch (mode) {\n\t\t\t\tcase 'year':\n\t\t\t\t\tmultiIndex = [idx[0]];\n\t\t\t\t\tmultiArray = [arr[0]];\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'month':\n\t\t\t\t\tmultiIndex = [idx[0], idx[1]];\n\t\t\t\t\tmultiArray = [arr[0], arr[1]];\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'day':\n\t\t\t\t\tmultiIndex = [idx[0], idx[1], idx[2]];\n\t\t\t\t\tmultiArray = [arr[0], arr[1], arr[2]];\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'hour':\n\t\t\t\t\tmultiIndex = [idx[0], idx[1], idx[2], idx[3]];\n\t\t\t\t\tmultiArray = [arr[0], arr[1], arr[2], arr[3]];\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'fullminute':\n\t\t\t\t\tidx.pop();\n\t\t\t\t\tarr.pop();\n\t\t\t\t\tmultiIndex = idx;\n\t\t\t\t\tmultiArray = arr;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'minute':\n\t\t\t\t\tmultiIndex = [idx[3], idx[4]];\n\t\t\t\t\tmultiArray = [arr[3], arr[4]];\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'second':\n\t\t\t\t\tmultiIndex = idx;\n\t\t\t\t\tmultiArray = arr;\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tthis.setData({\n\t\t\t\tmultiIndex,\n\t\t\t\tmultiArray\n\t\t\t});\n\t\t},\n\n\t\tpickerCancel: function (e) {\n\n\t\t},\n\t\t// 用户点击了确认\n\t\tpickerChange: function (e) {\n\t\t\tlet time = this._getTimeStr(e.detail.value);\n\t\t\tthis.triggerEvent('select', time);\n\t\t},\n\n\t\t// 用户点击了列选择\n\t\tpickerColumnChange: function (e) {\n\t\t\tlet multiArray = this.data.multiArray;\n\t\t\tlet multiIndex = this.data.multiIndex;\n\n\t\t\tmultiIndex[e.detail.column] = e.detail.value;\n\n\t\t\tlet mode = this.data.mode;\n\n\t\t\tif (mode != 'year' && mode != 'month' && mode != 'minute') {\n\t\t\t\tlet year = (multiArray[0][multiIndex[0]]).replace('年', '');\n\t\t\t\tlet month = (multiArray[1][multiIndex[1]]).replace('月', '');\n\t\t\t\tmultiArray[2] = dateTimePicker.getMonthDay(year, month, '日');\n\t\t\t}\n\n\n\t\t\tthis.setData({\n\t\t\t\tmultiArray,\n\t\t\t\tmultiIndex\n\t\t\t});\n\t\t}\n\t}\n})"
  },
  {
    "path": "miniprogram/cmpts/public/picker_time/picker_time_cmpt.json",
    "content": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/picker_time/picker_time_cmpt.wxml",
    "content": "<picker \n  class=\"multi-picker picker-class\"\n  mode=\"multiSelector\"\n  bindchange=\"pickerChange\"\n  bindcolumnchange=\"pickerColumnChange\"\n  bindcancel=\"pickerCancel\"\n  disabled=\"{{disabled}}\"\n  value=\"{{multiIndex}}\"\n  range=\"{{multiArray}}\">\n  <slot/>\n</picker>"
  },
  {
    "path": "miniprogram/cmpts/public/picker_time/picker_time_cmpt.wxss",
    "content": "/* cmpts/public/picker_time/picker_time_cmpt.wxss */"
  },
  {
    "path": "miniprogram/cmpts/public/poster/poster_cmpt.js",
    "content": "/*\nhttps://github.com/jasondu/wxa-plugin-canvas\n### 标准尺寸：\nwidth: 375, // rpx\nheight: 670,\n\n### 父页面分享按钮取值\nonShareAppMessage: function (e) {\n\tlet img = e.target.dataset.img;\n\treturn {\n\t\ttitle: 'xxx',\n\t\timageUrl: img,\n\t\tpath: 'xxxx',\n\t}\n}\n*/\nimport Poster from '../../../cmpts/public/poster/wxa-plugin-canvas/poster/poster.js'\nconst pageHelper = require('../../../helper/page_helper.js');\nconst picHelper = require('../../../helper/pic_helper.js');\nconst helper = require('../../../helper/helper.js');\n\nComponent({\n\texternalClasses: ['poster-class'],\n\n\toptions: {\n\t\taddGlobalClass: true,\n\t\tmultipleSlots: true\n\t},\n\n\t/**\n\t * 组件的属性列表\n\t */\n\tproperties: {\n\t\tconfig: { // 图形参数\n\t\t\ttype: Object,\n\t\t\tvalue: null,\n\t\t},\n\t\tisQr: { // 是否叠加小程序码\n\t\t\ttype: Boolean,\n\t\t\tvalue: false\n\t\t},\n\t\tisFace: { // 是否叠加头像\n\t\t\ttype: Boolean,\n\t\t\tvalue: false\n\t\t},\n\t\tdoPoster: {  \n\t\t\ttype: Boolean,\n\t\t\tvalue: true\n\t\t},\n\t\tshow: { // 显示\n\t\t\ttype: Boolean,\n\t\t\tvalue: false\n\t\t},\n\t\timg: { //图片文件\n\t\t\ttype: String,\n\t\t\tvalue: ''\n\t\t}\n\t},\n\n\t/**\n\t * 组件的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false,\n\t},\n\n\tlifetimes: {\n\t\tattached: function () {\n\n\t\t},\n\t\tready: function () {\n\t\t\tthis._init();\n\t\t},\n\t\tdetached: function () {\n\t\t\t// 在组件实例被从页面节点树移除时执行\n\t\t},\n\t},\n\n\t/**\n\t * 组件的方法列表 \n\t */\n\tmethods: {\n\t\t_init: async function () {\n\n\t\t},\n\n\t\tbindPosterTap: function (e) {\n\t\t\tthis.setData({\n\t\t\t\tisCreate:true,\n\t\t\t\tisLoad: false,\n\t\t\t}, async () => {\n\t\t\t\tawait this.createPoster();\n\t\t\t});\n\t\t},\n\t\tbindCloseTap: function () {\n\t\t\tthis.setData({\n\t\t\t\tshow: false\n\t\t\t});\n\t\t},\n\n\t\t/**\n\t\t * 异步生成海报\n\t\t */\n\t\tcreatePoster: async function () {\n\t\t\t// TODO:根据屏幕大小来生成，但是没有负定位\n\n\t\t\tlet posterConfig = {\n\t\t\t\twidth: 480, // rpx\n\t\t\t\theight: 650,\n\t\t\t\tpixelRatio: 2, // 2 为原始大小\n\t\t\t\tbackgroundColor: '#345678',\n\t\t\t\tdebug: false,\n\t\t\t}\n\n\t\t\tlet config = this.data.config;\n\t\t\tif (!helper.isDefined(config['width']))\n\t\t\t\tconfig.width = posterConfig.width;\n\n\t\t\tif (!helper.isDefined(config['height']))\n\t\t\t\tconfig.height = posterConfig.height;\n\n\t\t\tif (!helper.isDefined(config['pixelRatio']))\n\t\t\t\tconfig.pixelRatio = posterConfig.pixelRatio;\n\n\t\t\tif (!helper.isDefined(config['backgroundColor']))\n\t\t\t\tconfig.backgroundColor = posterConfig.backgroundColor;\n\n\t\t\tif (!helper.isDefined(config['debug']))\n\t\t\t\tconfig.debug = posterConfig.debug;\n\n\t\t\t//Object.assign(posterConfig, this.data.config); // TODO有问题\n\n\t\t\tthis.setData({\n\t\t\t\tposterConfig: config\n\t\t\t}, async () => {\n\t\t\t\tawait Poster.create(true, this);\n\t\t\t});\n\n\t\t},\n\n\t\tonPosterFail: function (e) {\n\t\t\tconsole.log(e)\n\t\t},\n\n\t\tbindPosterSuccessListener(e) {\n\t\t\tlet img = e.detail;\n\t\t\tthis.setData({\n\t\t\t\timg,\n\t\t\t\tisLoad: true\n\t\t\t});\n\n\t\t},\n\n\t\turl: function (e) {\n\t\t\tpageHelper.url(e, this);\n\t\t},\n\n\t\tbindPosterFailListener(e) {\n\t\t\tconsole.log(e);\n\t\t},\n\n\t\tbindSaveTap: function (e) {\n\t\t\tlet that = this;\n\t\t\tlet callback = function () {\n\t\t\t\twx.saveImageToPhotosAlbum({\n\t\t\t\t\tfilePath: that.data.img,\n\t\t\t\t\tsuccess: function (data) {\n\t\t\t\t\t\twx.showToast({\n\t\t\t\t\t\t\ttitle: '保存成功',\n\t\t\t\t\t\t\ticon: 'success',\n\t\t\t\t\t\t\tduration: 1000\n\t\t\t\t\t\t})\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tpicHelper.getWritePhotosAlbum(callback);\n\t\t}\n\n\n\t}\n})"
  },
  {
    "path": "miniprogram/cmpts/public/poster/poster_cmpt.json",
    "content": "{\n\t\"component\": true,\n\t\"usingComponents\": {\n\t\t\"poster\": \"./wxa-plugin-canvas/poster\"\n\t}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/poster/poster_cmpt.wxml",
    "content": "<poster wx:if=\"{{posterConfig}}\" id=\"poster\" hide-loading=\"{{true}}\" preload=\"{{false}}\" config=\"{{posterConfig}}\" bind:success=\"bindPosterSuccessListener\" bind:fail=\"bindPosterFailListener\"></poster>\n\n<view catchtouchmove=\"true\" style=\"z-index: 9999999999;\" class=\"main-poster modal bottom-modal {{show?'show':''}}\">\n\t<view class=\"dialog\">\n\t\t<view class=\"poster-img\" wx:if=\"{{isCreate}}\">\n\t\t\t<image bindtap=\"url\" data-type=\"img\" data-url=\"{{img}}\" show-menu-by-longpress=\"{{true}}\" wx:if=\"{{isLoad}}\" mode=\"widthFix\" src=\"{{img}}\" class=\"shadow loading\"></image>\n\n\t\t\t<view wx:else class=\"load loading text-l\"></view>\n\n\t\t\t<view class=\"save-hint text-project\" wx:if=\"{{isLoad}}\">长按图片保存或者转发</view>\n\n\t\t</view>\n\t\t<view class=\"poster-share\">\n\t\t\t<button class=\"item item-share clearbtn\" open-type=\"share\" data-img=\"{{img}}\">\n\t\t\t\t<view class=\"pic\">\n\t\t\t\t\t<image src=\"images/wechat.png\" />\n\t\t\t\t</view>\n\t\t\t\t<text>转发给朋友</text>\n\t\t\t</button>\n\n\t\t\t<view wx:if=\"{{doPoster}}\" class=\"item\" bindtap=\"bindPosterTap\" style=\"padding-top:12rpx\">\n\t\t\t\t<view class=\"pic\">\n\t\t\t\t\t<image class='friend' src=\"images/friend.png\" />\n\t\t\t\t</view>\n\t\t\t\t<text>生成海报</text>\n\t\t\t</view>\n\t\t</view>\n\n\t\t<view class=\"line\" bindtap=\"bindCloseTap\">\n\t\t\t<view>关闭</view>\n\t\t</view>\n\n\t</view>\n</view>"
  },
  {
    "path": "miniprogram/cmpts/public/poster/poster_cmpt.wxss",
    "content": ".main-poster .poster-share {\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: space-around;\n\talign-items: center;\n\tpadding: 30rpx 50rpx 10rpx;\n}\n\n.main-poster .poster-share .item {\n\tflex: 1 0 0;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: flex-start;\n\talign-items: center;\n\tcolor: #333;\n}\n\n.main-poster .poster-share .item .pic {\n\theight: 100rpx;\n\twidth: 100rpx;\n\tbackground-color: #f2f2f2;\n\tborder-radius: 50%;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n}\n\n.main-poster .poster-share .item-share {\n\tmargin-top: 15rpx;\n}\n\n.main-poster .poster-share .item-share>text {\n\tmargin-top: 15rpx !important;\n}\n\n.main-poster .poster-share .item .pic image {\n\theight: 50rpx;\n\twidth: 50rpx;\n}\n\n.main-poster .poster-share .item .pic .friend {\n\theight: 60rpx;\n\twidth: 60rpx;\n}\n\n.main-poster .poster-share .item>text {\n\tmargin-top: 15rpx;\n\tfont-size: 30rpx;\n\ttext-align: center;\n}\n\n.main-poster .poster-img {\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tpadding-top: 0rpx;\n\tpadding-bottom: 0rpx;\n\tmin-height: 600rpx;\n\tmargin-top: 30rpx;\n\tflex-direction: column;\n}\n\n.main-poster .poster-img .save-hint {\n\tfont-size: 30rpx;\n\tcolor: #555;\n\tmargin-top: 10rpx;\n}\n\n.load.loading::after {\n\tcontent: \"海报生成中...\";\n}\n\n.main-poster .poster-img image {\n\twidth: 375rpx;\n\tborder-radius: 15rpx;\n}\n\n.main-poster .line {\n\twidth: 100%;\n\tmargin: 30rpx 0 30rpx;\n\tborder-top: 1rpx solid #ddd;\n\tpadding: 30rpx 0 20rpx;\n\tfont-size: 32rpx;\n}"
  },
  {
    "path": "miniprogram/cmpts/public/poster/poster_cmpt_helper.js",
    "content": "const cloudHelper = require('../../../helper/cloud_helper.js');\n\nasync function config1({\n\tcover,\n\ttitle,\n\tdesc,\n\tqr,\n\tbg = ''\n}) {\n\tif (cover.startsWith('cloud'))\n\t\tcover = await cloudHelper.getTempFileURLOne(cover);\n\n\tif (qr.startsWith('cloud'))\n\t\tqr = await cloudHelper.getTempFileURLOne(qr);\n\n\tlet posterConfig = {\n\t\twidth: 480, // rpx\n\t\theight: 650,\n\t\tbackgroundColor: '#eeeeee'\n\t};\n\tif (bg) posterConfig.backgroundColor = bg;\n\n\n\tlet blocks = [];\n\tblocks = [{\n\t\tx: 30,\n\t\ty: 30,\n\t\tbackgroundColor: '#ffffff',\n\t\twidth: 420,\n\t\theight: 590,\n\t\tborderRadius: 20\n\t}];\n\n\tlet texts = [];\n\ttexts = [{\n\t\tx: 50,\n\t\ty: 350,\n\t\ttext: title,\n\t\twidth: 360,\n\t\tlineNum: 2,\n\t\tlineHeight: 40,\n\t\tfontSize: 26,\n\t\tcolor: '#000000',\n\t\ttextAlign: 'left',\n\t\tzIndex: 9999\n\t},\n\t{\n\t\tx: 55,\n\t\ty: 510,\n\t\ttext: '长按识别小程序码',\n\t\tfontSize: 18,\n\t\tcolor: '#aaaaaa',\n\t\tzIndex: 9999\n\t}, {\n\t\tx: 55,\n\t\ty: 540,\n\t\ttext: desc,\n\t\tfontSize: 18,\n\t\tcolor: '#aaaaaa',\n\t\tzIndex: 9999\n\t}];\n\n\tlet images = [];\n\tif (cover) {\n\t\timages.push({ // 底图\n\t\t\tx: 40,\n\t\t\ty: 40,\n\t\t\turl: cover,\n\t\t\twidth: 400,\n\t\t\theight: 260,\n\t\t\tzIndex: 999\n\t\t});\n\t}\n\n\tif (qr) {\n\t\timages.push({ // 小程序码\n\t\t\tx: 310,\n\t\t\ty: 460,\n\t\t\turl: qr,\n\t\t\twidth: 120,\n\t\t\theight: 120\n\t\t});\n\t}\n\n\tposterConfig.texts = texts;\n\tposterConfig.blocks = blocks\n\tposterConfig.images = images;\n\n\treturn posterConfig;\n}\n\n\nmodule.exports = {\n\tconfig1\n}"
  },
  {
    "path": "miniprogram/cmpts/public/poster/wxa-plugin-canvas/index/index.js",
    "content": "const main = {\n\t/**\n\t * 渲染块\n\t * @param {Object} params\n\t */\n\tdrawBlock({\n\t\ttext,\n\t\twidth = 0,\n\t\theight,\n\t\tx,\n\t\ty,\n\t\tpaddingLeft = 0,\n\t\tpaddingRight = 0,\n\t\tborderWidth,\n\t\tbackgroundColor,\n\t\tborderColor,\n\t\tborderRadius = 0,\n\t\topacity = 1,\n\t}) {\n\t\t// 判断是否块内有文字\n\t\tlet blockWidth = 0; // 块的宽度\n\t\tlet textX = 0;\n\t\tlet textY = 0;\n\t\tif (typeof text !== \"undefined\") {\n\t\t\t// 如果有文字并且块的宽度小于文字宽度，块的宽度为 文字的宽度 + 内边距\n\t\t\tconst textWidth = this._getTextWidth(typeof text.text === \"string\" ? text : text.text);\n\t\t\tblockWidth = textWidth > width ? textWidth : width;\n\t\t\tblockWidth += paddingLeft + paddingLeft;\n\n\t\t\tconst {\n\t\t\t\ttextAlign = \"left\", text: textCon\n\t\t\t} = text;\n\t\t\ttextY = height / 2 + y; // 文字的y轴坐标在块中线\n\t\t\tif (textAlign === \"left\") {\n\t\t\t\t// 如果是右对齐，那x轴在块的最左边\n\t\t\t\ttextX = x + paddingLeft;\n\t\t\t} else if (textAlign === \"center\") {\n\t\t\t\ttextX = blockWidth / 2 + x;\n\t\t\t} else {\n\t\t\t\ttextX = x + blockWidth - paddingRight;\n\t\t\t}\n\t\t} else {\n\t\t\tblockWidth = width;\n\t\t}\n\n\t\tif (backgroundColor) {\n\t\t\t// 画面\n\t\t\tthis.ctx.save();\n\t\t\tthis.ctx.globalAlpha = opacity;\n\t\t\tthis.ctx.fillStyle = backgroundColor;\n\t\t\tif (borderRadius > 0) {\n\t\t\t\t// 画圆角矩形\n\t\t\t\tthis._drawRadiusRect(x, y, blockWidth, height, borderRadius);\n\t\t\t\tthis.ctx.fill();\n\t\t\t} else {\n\t\t\t\tthis.ctx.fillRect(this.toPx(x), this.toPx(y), this.toPx(blockWidth), this.toPx(height));\n\t\t\t}\n\t\t\tthis.ctx.restore();\n\t\t}\n\t\tif (borderWidth) {\n\t\t\t// 画线\n\t\t\tthis.ctx.save();\n\t\t\tthis.ctx.globalAlpha = opacity;\n\t\t\tthis.ctx.strokeStyle = borderColor;\n\t\t\tthis.ctx.lineWidth = this.toPx(borderWidth);\n\t\t\tif (borderRadius > 0) {\n\t\t\t\t// 画圆角矩形边框\n\t\t\t\tthis._drawRadiusRect(x, y, blockWidth, height, borderRadius);\n\t\t\t\tthis.ctx.stroke();\n\t\t\t} else {\n\t\t\t\tthis.ctx.strokeRect(this.toPx(x), this.toPx(y), this.toPx(blockWidth), this.toPx(height));\n\t\t\t}\n\t\t\tthis.ctx.restore();\n\t\t}\n\n\t\tif (text) {\n\t\t\tthis.drawText(Object.assign(text, {\n\t\t\t\tx: textX,\n\t\t\t\ty: textY\n\t\t\t}));\n\t\t}\n\t},\n\n\t/**\n\t * 渲染文字\n\t * @param {Object} params\n\t */\n\tdrawText(params) {\n\t\tconst {\n\t\t\tx,\n\t\t\ty,\n\t\t\tfontSize,\n\t\t\tcolor,\n\t\t\tbaseLine,\n\t\t\ttextAlign,\n\t\t\ttext,\n\t\t\topacity = 1,\n\t\t\twidth,\n\t\t\tlineNum,\n\t\t\tlineHeight\n\t\t} = params;\n\t\tif (Object.prototype.toString.call(text) === \"[object Array]\") {\n\t\t\tlet preText = {\n\t\t\t\tx,\n\t\t\t\ty,\n\t\t\t\tbaseLine\n\t\t\t};\n\t\t\ttext.forEach((item) => {\n\t\t\t\tpreText.x += this.toPx(item.marginLeft || 0);\n\t\t\t\tconst textWidth = this._drawSingleText(\n\t\t\t\t\tObject.assign(item, {\n\t\t\t\t\t\t...preText,\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tpreText.x += textWidth + this.toPx(item.marginRight || 0); // 下一段字的x轴为上一段字x + 上一段字宽度\n\t\t\t});\n\t\t} else {\n\t\t\tthis._drawSingleText(params);\n\t\t}\n\t},\n\n\t/**\n\t * 渲染图片\n\t * @param {Object} params\n\t */\n\tdrawImage({\n\t\timgPath,\n\t\tx,\n\t\ty,\n\t\tw,\n\t\th,\n\t\tsx,\n\t\tsy,\n\t\tsw,\n\t\tsh,\n\t\tborderRadius = 0,\n\t\tborderWidth = 0,\n\t\tborderColor\n\t}) {\n\t\treturn new Promise((resolve) => {\n\t\t\tconst img = this.node.createImage();\n\t\t\timg.onload = () => {\n\t\t\t\tthis.ctx.save();\n\t\t\t\tif (borderRadius > 0) {\n\t\t\t\t\tthis._drawRadiusRect(x, y, w, h, borderRadius);\n\t\t\t\t\tthis.ctx.strokeStyle = \"rgba(255,255,255,0)\";\n\t\t\t\t\tthis.ctx.stroke();\n\t\t\t\t\tthis.ctx.clip();\n\t\t\t\t\tthis.ctx.drawImage(\n\t\t\t\t\t\timg,\n\t\t\t\t\t\tthis.toPx(sx),\n\t\t\t\t\t\tthis.toPx(sy),\n\t\t\t\t\t\tthis.toPx(sw),\n\t\t\t\t\t\tthis.toPx(sh),\n\t\t\t\t\t\tthis.toPx(x),\n\t\t\t\t\t\tthis.toPx(y),\n\t\t\t\t\t\tthis.toPx(w),\n\t\t\t\t\t\tthis.toPx(h)\n\t\t\t\t\t);\n\t\t\t\t\tif (borderWidth > 0) {\n\t\t\t\t\t\tthis.ctx.strokeStyle = borderColor;\n\t\t\t\t\t\tthis.ctx.lineWidth = this.toPx(borderWidth);\n\t\t\t\t\t\tthis.ctx.stroke();\n\t\t\t\t\t}\n\t\t\t\t} else { \n\t\t\t\t\tthis.ctx.drawImage(\n\t\t\t\t\t\timg,\n\t\t\t\t\t\tthis.toPx(sx),\n\t\t\t\t\t\tthis.toPx(sy),\n\t\t\t\t\t\tthis.toPx(sw),\n\t\t\t\t\t\tthis.toPx(sh),\n\t\t\t\t\t\tthis.toPx(x),\n\t\t\t\t\t\tthis.toPx(y),\n\t\t\t\t\t\tthis.toPx(w),\n\t\t\t\t\t\tthis.toPx(h)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthis.ctx.restore();\n\t\t\t\tresolve();\n\t\t\t};\n\t\t\timg.src = imgPath;\n\t\t});\n\t},\n\t/**\n\t * 渲染线\n\t * @param {Object} param\n\t */\n\tdrawLine({\n\t\tstartX,\n\t\tstartY,\n\t\tendX,\n\t\tendY,\n\t\tcolor,\n\t\twidth\n\t}) {\n\t\tthis.ctx.save();\n\t\tthis.ctx.beginPath();\n\t\tthis.ctx.strokeStyle = color;\n\t\tthis.ctx.lineWidth = this.toPx(width);\n\t\tthis.ctx.moveTo(this.toPx(startX), this.toPx(startY));\n\t\tthis.ctx.lineTo(this.toPx(endX), this.toPx(endY));\n\t\tthis.ctx.stroke();\n\t\tthis.ctx.closePath();\n\t\tthis.ctx.restore();\n\t},\n\tdownloadResource({\n\t\timages = [],\n\t\tpixelRatio\n\t}) {\n\n\t\t// 本方法比create早执行，所以要预先设定ratio by cc 2021/10/25\n\t\tthis.pixelRatio = pixelRatio || this.pixelRatio;\n\n\t\tconst drawList = [];\n\t\timages.forEach((image, index) => drawList.push(this._downloadImageAndInfo(image, index)));\n\t\treturn Promise.all(drawList);\n\t},\n\tinitCanvas(w, h, debug) {\n\t\tconst {\n\t\t\tplatform\n\t\t} = wx.getSystemInfoSync();\n\n\t\treturn new Promise((resolve) => {\n\t\t\tif (platform === \"ios\") {\n\t\t\t\tthis.setData({\n\t\t\t\t\tpxWidth: this.toPx(w),\n\t\t\t\t\tpxHeight: this.toPx(h),\n\t\t\t\t\tdebug,\n\t\t\t\t});\n\t\t\t\t// ios系统动态设置canvas宽高后立即绘制canvas会偶现变形的BUG\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tresolve();\n\t\t\t\t}, 100);\n\t\t\t} else {\n\t\t\t\tthis.setData({\n\t\t\t\t\t\tpxWidth: this.toPx(w),\n\t\t\t\t\t\tpxHeight: this.toPx(h),\n\t\t\t\t\t\tdebug,\n\t\t\t\t\t},\n\t\t\t\t\tresolve\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t},\n};\nconst handle = {\n\t/**\n\t * 画圆角矩形\n\t */\n\t_drawRadiusRect(x, y, w, h, r) {\n\t\tconst br = r / 2;\n\t\tthis.ctx.beginPath();\n\t\tthis.ctx.moveTo(this.toPx(x + br), this.toPx(y)); // 移动到左上角的点\n\t\tthis.ctx.lineTo(this.toPx(x + w - br), this.toPx(y));\n\t\tthis.ctx.arc(\n\t\t\tthis.toPx(x + w - br),\n\t\t\tthis.toPx(y + br),\n\t\t\tthis.toPx(br),\n\t\t\t2 * Math.PI * (3 / 4),\n\t\t\t2 * Math.PI * (4 / 4)\n\t\t);\n\t\tthis.ctx.lineTo(this.toPx(x + w), this.toPx(y + h - br));\n\t\tthis.ctx.arc(this.toPx(x + w - br), this.toPx(y + h - br), this.toPx(br), 0, 2 * Math.PI * (1 / 4));\n\t\tthis.ctx.lineTo(this.toPx(x + br), this.toPx(y + h));\n\t\tthis.ctx.arc(\n\t\t\tthis.toPx(x + br),\n\t\t\tthis.toPx(y + h - br),\n\t\t\tthis.toPx(br),\n\t\t\t2 * Math.PI * (1 / 4),\n\t\t\t2 * Math.PI * (2 / 4)\n\t\t);\n\t\tthis.ctx.lineTo(this.toPx(x), this.toPx(y + br));\n\t\tthis.ctx.arc(this.toPx(x + br), this.toPx(y + br), this.toPx(br), 2 * Math.PI * (2 / 4), 2 * Math.PI * (3 / 4));\n\t},\n\t/**\n\t * 计算文本长度\n\t * @param {Array|Object}} text 数组 或者 对象\n\t */\n\t_getTextWidth(text) {\n\t\tlet texts = [];\n\t\tif (Object.prototype.toString.call(text) === \"[object Object]\") {\n\t\t\ttexts.push(text);\n\t\t} else {\n\t\t\ttexts = text;\n\t\t}\n\t\tlet width = 0;\n\t\ttexts.forEach(({\n\t\t\tfontSize,\n\t\t\ttext,\n\t\t\tmarginLeft = 0,\n\t\t\tmarginRight = 0\n\t\t}) => {\n\t\t\tthis.ctx.fontSize = this.toPx(fontSize);\n\t\t\twidth += this.ctx.measureText(text).width + marginLeft + marginRight;\n\t\t});\n\n\t\treturn this.toRpx(width);\n\t},\n\t/**\n\t * 渲染一段文字\n\t */\n\t_drawSingleText({\n\t\tx,\n\t\ty,\n\t\tfontSize,\n\t\tcolor,\n\t\tbaseLine,\n\t\ttextAlign = \"left\",\n\t\ttext,\n\t\topacity = 1,\n\t\ttextDecoration = \"none\",\n\t\twidth,\n\t\tlineNum = 1,\n\t\tlineHeight = 0,\n\t\tfontWeight = \"normal\",\n\t\tfontStyle = \"normal\",\n\t\tfontFamily = \"sans-serif\",\n\t}) {\n\t\tthis.ctx.save();\n\t\tthis.ctx.beginPath();\n\t\tthis.ctx.font = fontStyle + \" \" + fontWeight + \" \" + this.toPx(fontSize, true) + \"px \" + fontFamily;\n\t\tthis.ctx.globalAlpha = opacity;\n\t\tthis.ctx.fillStyle = color;\n\t\tthis.ctx.textBaseline = baseLine;\n\t\tthis.ctx.textAlign = textAlign; \n\t\tlet textWidth = this.toRpx(this.ctx.measureText(text).width);\n\t\t \n\t\tconst textArr = [];\n\t\tif (textWidth > width) {\n\t\t\t// 文本宽度 大于 渲染宽度\n\t\t\tlet fillText = \"\";\n\t\t\tlet line = 1;\n\t\t\tfor (let i = 0; i <= text.length - 1; i++) {\n\t\t\t\t// 将文字转为数组，一行文字一个元素\n\t\t\t\tfillText = fillText + text[i];\n\t\t\t\tif (this.toRpx(this.ctx.measureText(fillText).width) >= width) {\n\t\t\t\t\tif (line === lineNum) {\n\t\t\t\t\t\tif (i !== text.length - 1) {\n\t\t\t\t\t\t\tfillText = fillText.substring(0, fillText.length - 1) + \"...\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (line <= lineNum) {\n\t\t\t\t\t\ttextArr.push(fillText);\n\t\t\t\t\t}\n\t\t\t\t\tfillText = \"\";\n\t\t\t\t\tline++;\n\t\t\t\t} else {\n\t\t\t\t\tif (line <= lineNum) {\n\t\t\t\t\t\tif (i === text.length - 1) {\n\t\t\t\t\t\t\ttextArr.push(fillText);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\ttextWidth = width;\n\t\t} else {\n\t\t\ttextArr.push(text);\n\t\t}\n\n\t\ttextArr.forEach((item, index) => { \n\t\t\tthis.ctx.fillText(item, this.toPx(x), this.toPx(y + (lineHeight || fontSize) * index));\n\t\t});\n\n\t\tthis.ctx.restore();\n\n\t\t// textDecoration\n\t\tif (textDecoration !== \"none\") {\n\t\t\tlet lineY = y;\n\t\t\tif (textDecoration === \"line-through\") {\n\t\t\t\t// 目前只支持贯穿线\n\t\t\t\tlineY = y;\n\n\t\t\t\t// 小程序画布baseLine偏移阈值\n\t\t\t\tlet threshold = 5;\n\n\t\t\t\t// 根据baseLine的不同对贯穿线的Y坐标做相应调整\n\t\t\t\tswitch (baseLine) {\n\t\t\t\t\tcase \"top\":\n\t\t\t\t\t\tlineY += fontSize / 2 + threshold;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"middle\":\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"bottom\":\n\t\t\t\t\t\tlineY -= fontSize / 2 + threshold;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tlineY -= fontSize / 2 - threshold;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.ctx.save();\n\t\t\tthis.ctx.moveTo(this.toPx(x), this.toPx(lineY));\n\t\t\tthis.ctx.lineTo(this.toPx(x) + this.toPx(textWidth), this.toPx(lineY));\n\t\t\tthis.ctx.strokeStyle = color;\n\t\t\tthis.ctx.stroke();\n\t\t\tthis.ctx.restore();\n\t\t}\n\n\t\treturn textWidth;\n\t},\n};\nconst helper = {\n\t/**\n\t * 下载图片并获取图片信息\n\t */\n\t_downloadImageAndInfo(image, index) {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst {\n\t\t\t\tx,\n\t\t\t\ty,\n\t\t\t\turl,\n\t\t\t\tzIndex\n\t\t\t} = image;\n\t\t\tconst imageUrl = url;\n\t\t\t// 下载图片\n\t\t\tthis._downImage(imageUrl, index)\n\t\t\t\t// 获取图片信息\n\t\t\t\t.then((imgPath) => this._getImageInfo(imgPath, index))\n\t\t\t\t.then(({\n\t\t\t\t\timgPath,\n\t\t\t\t\timgInfo\n\t\t\t\t}) => {\n\t\t\t\t\tconsole.log();\n\t\t\t\t\t// 根据画布的宽高计算出图片绘制的大小，这里会保证图片绘制不变形\n\t\t\t\t\tlet sx;\n\t\t\t\t\tlet sy;\n\t\t\t\t\tconst borderRadius = image.borderRadius || 0;\n\t\t\t\t\tconst setWidth = image.width;\n\t\t\t\t\tconst setHeight = image.height;\n\t\t\t\t\tconst width = this.toRpx(imgInfo.width);\n\t\t\t\t\tconst height = this.toRpx(imgInfo.height);\n\n\t\t\t\t\tif (width / height <= setWidth / setHeight) {\n\t\t\t\t\t\tsx = 0;\n\t\t\t\t\t\tsy = (height - (width / setWidth) * setHeight) / 2;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsy = 0;\n\t\t\t\t\t\tsx = (width - (height / setHeight) * setWidth) / 2;\n\t\t\t\t\t}\n\t\t\t\t\tif (!this.drawArr) this.drawArr = [];\n\t\t\t\t\tthis.drawArr.push({\n\t\t\t\t\t\ttype: \"image\",\n\t\t\t\t\t\tborderRadius,\n\t\t\t\t\t\tborderWidth: image.borderWidth,\n\t\t\t\t\t\tborderColor: image.borderColor,\n\t\t\t\t\t\tzIndex: typeof zIndex !== \"undefined\" ? zIndex : index,\n\t\t\t\t\t\timgPath,\n\t\t\t\t\t\tsx,\n\t\t\t\t\t\tsy,\n\t\t\t\t\t\tsw: width - sx * 2,\n\t\t\t\t\t\tsh: height - sy * 2,\n\t\t\t\t\t\tx,\n\t\t\t\t\t\ty,\n\t\t\t\t\t\tw: setWidth,\n\t\t\t\t\t\th: setHeight,\n\t\t\t\t\t});\n\t\t\t\t\tresolve();\n\t\t\t\t})\n\t\t\t\t.catch((err) => reject(err));\n\t\t});\n\t},\n\t/**\n\t * 下载图片资源\n\t * @param {*} imageUrl\n\t */\n\t_downImage(imageUrl) {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tif (imageUrl.includes('tmp') || imageUrl.includes('temp') || imageUrl.includes('wxfile')) {\n\t\t\t\t// 支持本地地址\n\t\t\t\tresolve(imageUrl); //2021/2/17 by cc\n\t\t\t}\n\n\t\t\tif (/^http/.test(imageUrl) && !new RegExp(wx.env.USER_DATA_PATH).test(imageUrl)) {\n\t\t\t\twx.downloadFile({\n\t\t\t\t\turl: this._mapHttpToHttps(imageUrl),\n\t\t\t\t\tsuccess: (res) => {\n\t\t\t\t\t\tif (res.statusCode === 200) {\n\t\t\t\t\t\t\tresolve(res.tempFilePath);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treject(res.errMsg);\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tfail(err) {\n\t\t\t\t\t\treject(err);\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\t// 支持本地地址\n\t\t\t\tresolve(imageUrl);\n\t\t\t}\n\t\t});\n\t},\n\t/**\n\t * 获取图片信息\n\t * @param {*} imgPath\n\t * @param {*} index\n\t */\n\t_getImageInfo(imgPath, index) {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\twx.getImageInfo({\n\t\t\t\tsrc: imgPath,\n\t\t\t\tsuccess(res) {\n\t\t\t\t\tresolve({\n\t\t\t\t\t\timgPath,\n\t\t\t\t\t\timgInfo: res,\n\t\t\t\t\t\tindex\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tfail(err) {\n\t\t\t\t\treject(err);\n\t\t\t\t},\n\t\t\t});\n\t\t});\n\t},\n\ttoPx(rpx, int) {\n\t\tif (int) {\n\t\t\treturn parseInt(rpx * this.factor * this.pixelRatio);\n\t\t}\n\t\treturn rpx * this.factor * this.pixelRatio;\n\t},\n\ttoRpx(px, int) {\n\t\tif (int) {\n\t\t\treturn parseInt(px / (this.factor * this.pixelRatio));\n\t\t}\n\t\treturn px / (this.factor * this.pixelRatio);\n\t},\n\t/**\n\t * 将http转为https\n\t * @param {String}} rawUrl 图片资源url\n\t */\n\t_mapHttpToHttps(rawUrl) {\n\t\tif (rawUrl.indexOf(\":\") < 0) {\n\t\t\treturn rawUrl;\n\t\t}\n\t\tconst urlComponent = rawUrl.split(\":\");\n\t\tif (urlComponent.length === 2) {\n\t\t\tif (urlComponent[0] === \"http\") {\n\t\t\t\turlComponent[0] = \"https\";\n\t\t\t\treturn `${urlComponent[0]}:${urlComponent[1]}`;\n\t\t\t}\n\t\t}\n\t\treturn rawUrl;\n\t},\n};\nComponent({\n\tproperties: {},\n\tcreated() {\n\t\tconst sysInfo = wx.getSystemInfoSync();\n\t\tconst {\n\t\t\tpixelRatio,\n\t\t\tscreenWidth\n\t\t} = sysInfo;\n\t\tthis.factor = screenWidth / 750;\n\t\tthis.pixelRatio = pixelRatio;\n\t},\n\tmethods: Object.assign({\n\t\t\t/**\n\t\t\t * 计算画布的高度\n\t\t\t * @param {*} config\n\t\t\t */\n\t\t\tgetHeight(config) {\n\t\t\t\tconst getTextHeight = (text) => {\n\t\t\t\t\tlet fontHeight = text.lineHeight || text.fontSize;\n\t\t\t\t\tlet height = 0;\n\t\t\t\t\tif (text.baseLine === \"top\") {\n\t\t\t\t\t\theight = fontHeight;\n\t\t\t\t\t} else if (text.baseLine === \"middle\") {\n\t\t\t\t\t\theight = fontHeight / 2;\n\t\t\t\t\t} else {\n\t\t\t\t\t\theight = 0;\n\t\t\t\t\t}\n\t\t\t\t\treturn height;\n\t\t\t\t};\n\t\t\t\tconst heightArr = [];\n\t\t\t\t(config.blocks || []).forEach((item) => {\n\t\t\t\t\theightArr.push(item.y + item.height);\n\t\t\t\t});\n\t\t\t\t(config.texts || []).forEach((item) => {\n\t\t\t\t\tlet height;\n\t\t\t\t\tif (Object.prototype.toString.call(item.text) === \"[object Array]\") {\n\t\t\t\t\t\titem.text.forEach((i) => {\n\t\t\t\t\t\t\theight = getTextHeight({\n\t\t\t\t\t\t\t\t...i,\n\t\t\t\t\t\t\t\tbaseLine: item.baseLine,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\theightArr.push(item.y + height);\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\theight = getTextHeight(item);\n\t\t\t\t\t\theightArr.push(item.y + height);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t(config.images || []).forEach((item) => {\n\t\t\t\t\theightArr.push(item.y + item.height);\n\t\t\t\t});\n\t\t\t\t(config.lines || []).forEach((item) => {\n\t\t\t\t\theightArr.push(item.startY);\n\t\t\t\t\theightArr.push(item.endY);\n\t\t\t\t});\n\t\t\t\tconst sortRes = heightArr.sort((a, b) => b - a);\n\t\t\t\tlet canvasHeight = 0;\n\t\t\t\tif (sortRes.length > 0) {\n\t\t\t\t\tcanvasHeight = sortRes[0];\n\t\t\t\t}\n\t\t\t\tif (config.height < canvasHeight || !config.height) {\n\t\t\t\t\treturn canvasHeight;\n\t\t\t\t} else {\n\t\t\t\t\treturn config.height;\n\t\t\t\t}\n\t\t\t},\n\t\t\tasync create(config) {\n\t\t\t\tawait this.initCtx();\n\n\t\t\t\tthis.pixelRatio = config.pixelRatio || this.pixelRatio;\n\t\t\t\tconst height = this.getHeight(config);\n\t\t\t\tthis.initCanvas(config.width, height, config.debug)\n\t\t\t\t\t.then(async () => {\n\t\t\t\t\t\tthis.node.width = this.data.pxWidth * this.pixelRatio;\n\t\t\t\t\t\tthis.node.height = this.data.pxHeight * this.pixelRatio;\n\n\t\t\t\t\t\tthis.ctx.scale(this.pixelRatio, this.pixelRatio);\n\n\t\t\t\t\t\t// 设置画布底色\n\t\t\t\t\t\tif (config.backgroundColor) {\n\t\t\t\t\t\t\tthis.ctx.save();\n\t\t\t\t\t\t\tthis.ctx.fillStyle = config.backgroundColor;\n\t\t\t\t\t\t\tthis.ctx.fillRect(0, 0, this.toPx(config.width), this.toPx(height));\n\t\t\t\t\t\t\tthis.ctx.restore();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst {\n\t\t\t\t\t\t\ttexts = [], blocks = [], lines = []\n\t\t\t\t\t\t} = config;\n\t\t\t\t\t\tif (!this.drawArr) this.drawArr = [];\n\t\t\t\t\t\tconst queue = this.drawArr\n\t\t\t\t\t\t\t.concat(\n\t\t\t\t\t\t\t\ttexts.map((item) => {\n\t\t\t\t\t\t\t\t\titem.type = \"text\";\n\t\t\t\t\t\t\t\t\titem.zIndex = item.zIndex || 0;\n\t\t\t\t\t\t\t\t\treturn item;\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.concat(\n\t\t\t\t\t\t\t\tblocks.map((item) => {\n\t\t\t\t\t\t\t\t\titem.type = \"block\";\n\t\t\t\t\t\t\t\t\titem.zIndex = item.zIndex || 0;\n\t\t\t\t\t\t\t\t\treturn item;\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.concat(\n\t\t\t\t\t\t\t\tlines.map((item) => {\n\t\t\t\t\t\t\t\t\titem.type = \"line\";\n\t\t\t\t\t\t\t\t\titem.zIndex = item.zIndex || 0;\n\t\t\t\t\t\t\t\t\treturn item;\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t// 按照顺序排序\n\t\t\t\t\t\tqueue.sort((a, b) => a.zIndex - b.zIndex);\n\n\t\t\t\t\t\tfor (let i = 0, len = queue.length; i < len; i++) {\n\t\t\t\t\t\t\tconst item = queue[i];\n\t\t\t\t\t\t\tif (item.type === \"image\") {\n\t\t\t\t\t\t\t\tawait this.drawImage(item);\n\t\t\t\t\t\t\t} else if (item.type === \"text\") {\n\t\t\t\t\t\t\t\tthis.drawText(item);\n\t\t\t\t\t\t\t} else if (item.type === \"block\") {\n\t\t\t\t\t\t\t\tthis.drawBlock(item);\n\t\t\t\t\t\t\t} else if (item.type === \"line\") {\n\t\t\t\t\t\t\t\tthis.drawLine(item);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\twx.canvasToTempFilePath({\n\t\t\t\t\t\t\t\tcanvas: this.node,\n\t\t\t\t\t\t\t\tsuccess: (res) => {\n\t\t\t\t\t\t\t\t\tthis.triggerEvent(\"success\", res.tempFilePath);\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tfail: (err) => {\n\t\t\t\t\t\t\t\t\tthis.triggerEvent(\"fail\", err);\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tthis\n\t\t\t\t\t\t);\n\t\t\t\t\t})\n\t\t\t\t\t.catch((err) => {\n\t\t\t\t\t\twx.showToast({\n\t\t\t\t\t\t\ticon: \"none\",\n\t\t\t\t\t\t\ttitle: err.errMsg || \"生成失败\",\n\t\t\t\t\t\t});\n\t\t\t\t\t\tconsole.error(err);\n\t\t\t\t\t});\n\t\t\t},\n\t\t\tinitCtx() {\n\t\t\t\treturn new Promise((resolve) => {\n\t\t\t\t\twx.createSelectorQuery()\n\t\t\t\t\t\t.in(this)\n\t\t\t\t\t\t.select(\"#canvasid\")\n\t\t\t\t\t\t.fields({\n\t\t\t\t\t\t\tnode: true,\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.exec((res) => {\n\t\t\t\t\t\t\tthis.node = res[0].node;\n\t\t\t\t\t\t\tthis.ctx = this.node.getContext(\"2d\");\n\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t},\n\t\tmain,\n\t\thandle,\n\t\thelper\n\t),\n});"
  },
  {
    "path": "miniprogram/cmpts/public/poster/wxa-plugin-canvas/index/index.json",
    "content": "{\n    \"component\": true\n}"
  },
  {
    "path": "miniprogram/cmpts/public/poster/wxa-plugin-canvas/index/index.wxml",
    "content": "<!--index.wxml-->\n<view class=\"container\">\n  <canvas id='canvasid' type=\"2d\" class=\"canvas {{debug ? 'debug' : 'pro'}}\" style='width: {{pxWidth}}px; height: {{pxHeight}}px;'></canvas>\n</view>"
  },
  {
    "path": "miniprogram/cmpts/public/poster/wxa-plugin-canvas/index/index.wxss",
    "content": ".canvas {\n    width: 750rpx;\n    height: 750rpx;\n}\n.canvas.pro {\n    position: absolute;\n    bottom: 0;\n    left: 0;\n    transform: translate3d(-9999rpx, 0, 0);\n}\n.canvas.debug {\n    position: absolute;\n    bottom: 0;\n    left: 0;\n    border: 1rpx solid #ccc;\n}"
  },
  {
    "path": "miniprogram/cmpts/public/poster/wxa-plugin-canvas/poster/index.js",
    "content": "Component({\n\tproperties: {\n\t\tconfig: {\n\t\t\ttype: Object,\n\t\t\tvalue: {},\n\t\t},\n\t\tpreload: { // 是否预下载图片资源\n\t\t\ttype: Boolean,\n\t\t\tvalue: false,\n\t\t},\n\t\thideLoading: { // 是否隐藏loading\n\t\t\ttype: Boolean,\n\t\t\tvalue: false,\n\t\t}\n\t},\n\tready() {\n\t\tif (this.data.preload) {\n\t\t\tconst poster = this.selectComponent('#poster');\n\t\t\tthis.downloadStatus = 'doing'; \n\t\t\tposter.downloadResource(this.data.config).then(() => {\n\t\t\t\tthis.downloadStatus = 'success';\n\t\t\t\tthis.trigger('downloadSuccess');\n\t\t\t}).catch((e) => {\n\t\t\t\tthis.downloadStatus = 'fail';\n\t\t\t\tthis.trigger('downloadFail', e);\n\t\t\t});\n\t\t}\n\t},\n\tmethods: {\n\t\ttrigger(event, data) {\n\t\t\tif (this.listener && typeof this.listener[event] === 'function') {\n\t\t\t\tthis.listener[event](data);\n\t\t\t}\n\t\t},\n\t\tonce(event, fun) {\n\t\t\tif (typeof this.listener === 'undefined') {\n\t\t\t\tthis.listener = {};\n\t\t\t}\n\t\t\tthis.listener[event] = fun;\n\t\t},\n\t\tdownloadResource(reset) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tif (reset) {\n\t\t\t\t\tthis.downloadStatus = null;\n\t\t\t\t}\n\t\t\t\tconst poster = this.selectComponent('#poster');\n\t\t\t\tif (this.downloadStatus && this.downloadStatus !== 'fail') {\n\t\t\t\t\tif (this.downloadStatus === 'success') {\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.once('downloadSuccess', () => resolve());\n\t\t\t\t\t\tthis.once('downloadFail', (e) => reject(e));\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tposter.downloadResource(this.data.config)\n\t\t\t\t\t\t.then(() => {\n\t\t\t\t\t\t\tthis.downloadStatus = 'success';\n\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch((e) => reject(e));\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\t\tonCreate(reset = false) {\n\t\t\t!this.data.hideLoading && wx.showLoading({\n\t\t\t\tmask: true,\n\t\t\t\ttitle: '生成中'\n\t\t\t});\n\t\t\treturn this.downloadResource(typeof reset === 'boolean' && reset).then(() => {\n\t\t\t\t\t!this.data.hideLoading && wx.hideLoading();\n\t\t\t\t\tconst poster = this.selectComponent('#poster');\n\t\t\t\t\tposter.create(this.data.config);\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\t!this.data.hideLoading && wx.hideLoading();\n\t\t\t\t\twx.showToast({\n\t\t\t\t\t\ticon: 'none',\n\t\t\t\t\t\ttitle: err.errMsg || '生成失败'\n\t\t\t\t\t});\n\t\t\t\t\tconsole.error(err);\n\t\t\t\t\tthis.triggerEvent('fail', err);\n\t\t\t\t})\n\t\t},\n\t\tonCreateSuccess(e) {\n\t\t\tconst {\n\t\t\t\tdetail\n\t\t\t} = e;\n\t\t\tthis.triggerEvent('success', detail);\n\t\t},\n\t\tonCreateFail(err) {\n\t\t\tconsole.error(err);\n\t\t\tthis.triggerEvent('fail', err);\n\t\t}\n\t}\n})"
  },
  {
    "path": "miniprogram/cmpts/public/poster/wxa-plugin-canvas/poster/index.json",
    "content": "{\n    \"component\": true,\n    \"usingComponents\": {\n        \"we-canvas\": \"../index/index\"\n    }\n}"
  },
  {
    "path": "miniprogram/cmpts/public/poster/wxa-plugin-canvas/poster/index.wxml",
    "content": "<view bindtap='onCreate'>\n    <slot/>\n</view>\n<we-canvas id=\"poster\" bind:success=\"onCreateSuccess\" bind:fail=\"onCreateFail\"/>"
  },
  {
    "path": "miniprogram/cmpts/public/poster/wxa-plugin-canvas/poster/index.wxss",
    "content": ""
  },
  {
    "path": "miniprogram/cmpts/public/poster/wxa-plugin-canvas/poster/poster.js",
    "content": "const defaultOptions = {\n    selector: '#poster'\n};\n\nfunction Poster(options = {}, that) {\n    options = {\n        ...defaultOptions,\n        ...options,\n    };\n\n    const pages = getCurrentPages();\n    let ctx = pages[pages.length - 1];\n    if (that) ctx = that\n    const poster = ctx.selectComponent(options.selector);\n    delete options.selector;\n\n    return poster;\n};\n\nPoster.create = (reset = false, that) => {\n    const poster  = Poster({}, that);\n    if (!poster) {\n        console.error('请设置组件的id=\"poster\"!!!');\n    } else {\n        return Poster({}, that).onCreate(reset);\n    }\n}\n\nexport default Poster;\n"
  },
  {
    "path": "miniprogram/cmpts/public/radio/radio_cmpt.js",
    "content": "Component({\n\texternalClasses: ['outside-picker-multi-class'],\n\n\t/**\n\t * 组件的属性列表\n\t */\n\tproperties: {\n\t\tsourceData: { //源数组 \n\t\t\ttype: Array,\n\t\t\tvalue: [],\n\t\t},\n\t\tsourceDataStr: { //源字符串 支持 x,y,z;;; 1=x,2=y,3=z \n\t\t\ttype: String,\n\t\t\tvalue: '',\n\t\t},\n\t\t// 默认选中项 \n\t\titemSelected: {\n\t\t\ttype: String,\n\t\t\tvalue: '',\n\t\t},\n\t\tdisabled: { // 是否禁用\n\t\t\ttype: Boolean,\n\t\t\tvalue: false,\n\t\t},\n\t},\n\n\t/**\n\t * 生命周期方法\n\t */\n\tlifetimes: {\n\t\tattached: function () { },\n\n\t\tready: function () {\n\t\t\tlet sourceDataStr = this.data.sourceDataStr;\n\t\t\tif (sourceDataStr) {\n\t\t\t\tlet options = [];\n\t\t\t\tlet arr = sourceDataStr.split(',');\n\t\t\t\tfor (let k = 0; k < arr.length; k++) {\n\t\t\t\t\tlet node = {};\n\t\t\t\t\tif (arr[k].includes('=')) {\n\t\t\t\t\t\tnode.label = arr[k].split('=')[1];\n\t\t\t\t\t\tnode.value = arr[k].split('=')[0];\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tnode.label = arr[k];\n\t\t\t\t\t\tnode.value = arr[k];\n\t\t\t\t\t}\n\t\t\t\t\toptions.push(node);\n\t\t\t\t}\n\t\t\t\tthis.setData({\n\t\t\t\t\toptions\n\t\t\t\t});\n\t\t\t}\n\t\t\telse {\n\t\t\t\tlet sourceData = this.data.sourceData;\n\t\t\t\tlet options = [];\n\t\t\t\tfor (let k = 0; k < sourceData.length; k++) {\n\t\t\t\t\tlet node = {\n\t\t\t\t\t\tlabel: sourceData[k],\n\t\t\t\t\t\tvalue: sourceData[k]\n\t\t\t\t\t};\n\t\t\t\t\toptions.push(node);\n\t\t\t\t}\n\t\t\t\tthis.setData({\n\t\t\t\t\toptions \n\t\t\t\t});\n\t\t\t}\n\n\t\t},\n\n\t\tdetached: function () {\n\t\t\t// 在组件实例被从页面节点树移除时执行\n\t\t},\n\n\t},\n\n\t/**\n\t * 组件的初始数据\n\t */\n\tdata: {\n\t\toptions: []\n\t},\n\n\t/**\n\t * 组件的方法列表\n\t */\n\tmethods: {\n\t\tbindChange: function (e) { \n\t\t\tthis.triggerEvent('select', e.detail.value);\n\t\t},\n\t}\n})"
  },
  {
    "path": "miniprogram/cmpts/public/radio/radio_cmpt.json",
    "content": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/radio/radio_cmpt.wxml",
    "content": "<radio-group bindchange=\"bindChange\" class=\"radio-group\">\n\t<view class=\"item\" wx:for=\"{{options}}\" wx:key=\"key\"> \n\t\t<label class=\"item-label\">\n\t\t\t<radio class=\"item-radio\" disabled=\"{{disabled}}\" value=\"{{item.value}}\" checked=\"{{itemSelected==item.value}}\" />\n\t\t\t<text>{{item.label}}</text>\n\t\t</label>\n\t</view>\n</radio-group>"
  },
  {
    "path": "miniprogram/cmpts/public/radio/radio_cmpt.wxss",
    "content": ".radio-group {\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: center;\n\tflex-direction: column;\n\talign-items: center;\n\tpadding: 0rpx 10rpx;\n}\n\n.radio-group .item {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: row;\n\tjustify-content: flex-start;\n\talign-items: center;\n\tline-height: 2.1;\n\tmin-height: 70rpx;\n\tborder-bottom: 1rpx solid #eee;\n\tfont-size: 28rpx;\n}\n\n.radio-group .item .item-label{\n\twidth: 100%; \n\tdisplay: flex;\n\tflex-direction: row;\n\tjustify-content: flex-start;\n\talign-items: center;\n}\n \n\n.radio-group .item:last-child {\n\tborder-bottom: 0;\n}\n\n.radio-group .item:nth-child(odd) {\n\tbackground-color: #fcfcfc;\n}\n\n\n.radio-group .item .item-radio {\n\tmargin-right: 20rpx;\n\tpadding-left: 10rpx; \n} \n"
  },
  {
    "path": "miniprogram/cmpts/public/swiper/swiper_cmpt.js",
    "content": "const pageHelper = require('../../../helper/page_helper.js');\nComponent({\n\toptions: {\n\t\taddGlobalClass: true,\n\t},\n\n\t/**\n\t * 组件的属性列表\n\t */\n\tproperties: {\n\t\timages: {\n\t\t\ttype: Array,\n\t\t\tvalue: []\n\t\t},\n\t\theight: {\n\t\t\ttype: Number,\n\t\t\tvalue: 350\n\t\t},\n\t\tmode: {\n\t\t\ttype: String,\n\t\t\tvalue: 'aspectFill'\n\t\t},\n\t\tindicatorActiveColor: {\n\t\t\ttype: String,\n\t\t\tvalue: '#000000'\n\t\t},\n\t\tinterval: {\n\t\t\ttype: Number,\n\t\t\tvalue: 3000\n\t\t},\n\t\tduration: {\n\t\t\ttype: Number,\n\t\t\tvalue: 500\n\t\t},\n\t\tpreviousMargin: {\n\t\t\ttype: Number,\n\t\t\tvalue: 0\n\t\t},\n\t\tnextMargin: {\n\t\t\ttype: Number,\n\t\t\tvalue: 0\n\t\t},\n\t\tindicatorDots: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: true\n\t\t},\n\t\tautoplay: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: true\n\t\t},\n\t\tcircular: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: true\n\t\t},\n\t\tvertical: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: false\n\t\t},\n\t},\n\n\t/**\n\t * 组件的初始数据\n\t */\n\tdata: {\n\n\t},\n\n\t/**\n\t * 组件的方法列表\n\t */\n\tmethods: {\n\t\turl: function (e) {\n\t\t\tpageHelper.url(e, this);\n\t\t}\n\t}\n})"
  },
  {
    "path": "miniprogram/cmpts/public/swiper/swiper_cmpt.json",
    "content": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/swiper/swiper_cmpt.wxml",
    "content": "<swiper wx:if=\"{{images.length>0}}\" class=\"swiper\" style=\"height:{{height}}rpx\" indicator-active-color=\"{{indicatorActiveColor}}\" indicator-dots=\"{{indicatorDots}}\" autoplay=\"{{autoplay}}\" circular=\"{{circular}}\" vertical=\"{{vertical}}\" interval=\"{{interval}}\" duration=\"{{duration}}\" previous-margin=\"{{previousMargin}}rpx\" next-margin=\"{{nextMargin}}rpx\">\n\t<swiper-item wx:for=\"{{images}}\" wx:key=\"key\">\n\t\t<image show-menu-by-longpress bindtap=\"url\" style=\"height:{{height}}rpx\" lazy-load=\"{{true}}\" data-type=\"image\" data-url=\"{{item}}\" src='{{item}}' mode='{{mode}}' class=\"swiper-item-images loading\" />\n\t</swiper-item>\n</swiper>"
  },
  {
    "path": "miniprogram/cmpts/public/swiper/swiper_cmpt.wxss",
    "content": ".swiper {\n\twidth: 100%; \n}\n.swiper-item-images {\n\twidth: 100%; \n} "
  },
  {
    "path": "miniprogram/cmpts/public/table/table_cmpt.js",
    "content": "/**\n * \n */\nComponent({\n\t/**\n\t * 外部样式类\n\t */\n\texternalClasses: ['header-row-class-name', 'row-class-name', 'cell-class-name'],\n\n\t/**\n\t * 组件样式隔离\n\t */\n\toptions: {\n\t\tstyleIsolation: \"isolated\",\n\t\tmultipleSlots: true // 支持多个slot\n\t},\n\n\t/**\n\t * 组件的属性列表\n\t */\n\tproperties: {\n\t\tdata: {\n\t\t\ttype: Array,\n\t\t\tvalue: []\n\t\t},\n\t\theaders: {\n\t\t\ttype: Array,\n\t\t\tvalue: []\n\t\t},\n\t\t// table的高度, 溢出可滚动\n\t\theight: {\n\t\t\ttype: String,\n\t\t\tvalue: 'auto'\n\t\t},\n\t\twidth: {\n\t\t\ttype: Number || String,\n\t\t\tvalue: '100%'\n\t\t},\n\t\t// 单元格的宽度\n\t\ttdWidth: {\n\t\t\ttype: Number,\n\t\t\tvalue: 35\n\t\t},\n\t\t// 固定表头 thead达到Header的位置时就应该被fixed了\n\t\toffsetTop: {\n\t\t\ttype: Number,\n\t\t\tvalue: 150\n\t\t},\n\t\t// 是否带有纵向边框\n\t\tstripe: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: false\n\t\t},\n\t\t// 是否带有纵向边框\n\t\tborder: {\n\t\t\ttype: Boolean,\n\t\t\tvalue: false\n\t\t},\n\t\tmsg: {\n\t\t\ttype: String,\n\t\t\tvalue: '暂无数据~'\n\t\t}\n\t},\n\n\t/**\n\t * 组件的初始数据\n\t */\n\tdata: {\n\t\tscrolWidth: '20%'\n\t},\n\n\tlifetimes: {\n\t\tattached: function () {\n\n\t\t},\n\t\tready: function () {\n\n\t\t},\n\t\tdetached: function () {\n\t\t\t// 在组件实例被从页面节点树移除时执行\n\t\t},\n\t},\n\n\t/**\n\t * 组件的方法列表\n\t */\n\tmethods: {\n\n\t}\n})"
  },
  {
    "path": "miniprogram/cmpts/public/table/table_cmpt.json",
    "content": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/table/table_cmpt.wxml",
    "content": "<view scroll-x=\"{{true}}\" scroll-y=\"{{true}}\" scroll-anchoring=\"{{true}}\" enhanced=\"{{true}}\" bounces=\"{{false}}\" class=\"table table-border\">\n\t<!-- 表格头 start -->\n\t<view class=\"thead thead-border\"  >\n\t\t<view wx:for=\"{{ headers }}\" wx:key=\"*this\" class=\"td\" style=\"width:200rpx;\">\n\t\t\t{{ item.label }}\n\t\t</view>\n\t</view>\n\t<!-- 表格头 end -->\n\n\t<!-- 表格体 start -->\n\t<view   class=\"tbody\"  >\n\t\t<block wx:if=\"{{ data.length > 0 }}\" wx:for-item=\"it\" wx:for=\"{{ data }}\" wx:key=\"*this\" wx:for-index=\"idx\">\n\t\t\t<view class=\"tbody-tr tbody-tr-stripe1  tbody-tr-border\">\n\t\t\t\t<view wx:for-item=\"head\" wx:for=\"{{ headers }}\" wx:key=\"*this\" class=\"td\" style=\"width:200rpx; \">\n\t\t\t\t\t{{it[head[\"prop\"]]}}\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t</block>\n\t\t<!-- 列表无数据处理 -->\n\t\t<block wx:if=\"{{ data.length === 0 }}\">\n\t\t\t<view class=\"no-data\">{{ msg }}</view>\n\t\t</block>\n\t</view>\n\t<!-- 表格体 end -->\n</view>"
  },
  {
    "path": "miniprogram/cmpts/public/table/table_cmpt.wxss",
    "content": ".reset {\n    background: white;\n} \n\n.other {\n    font-size: 20px;\n} \n\n.table {\n  position: relative;\n  font-size: 28rpx;\n  background: #fff;  \n  border-right:none;\n  border-radius: 8rpx;  \n  overflow: hidden;\n}\n.thead{\n  border-bottom: none;\n  display: flex;\n  justify-content: flex-start;\n  border-top-right-radius: 8rpx;\n  border-top-left-radius: 8rpx;\n  overflow: visible;\n  color: #909399;\n  border: 1px solid #ebeef5;\n  box-sizing: border-box;\n}\n.thead .td {\n  padding: 20rpx 10rpx;\n  font-weight: bold;\n  display: inline-block;   \n  white-space:nowrap; \n  text-align: center;\n  border-right: 1rpx solid #fff;\n}\n.thead .td:last-child {\n  border-right: none;\n}\n.thead-border .td {\n  border-right: 1rpx solid #ebeef5;\n}\n.thead-border .td:last-child {\n  border-right: none;\n}\n/* .tr{\n  display: flex;\n  white-space:nowrap; \n} */\n.tbody {\n  box-sizing: border-box;\n  font-size: 28rpx;\n  color: #666;\n  border: 1px solid #ebeef5;\n  border-top: none;\n  border-bottom-left-radius: 8rpx;\n  border-bottom-right-radius: 8rpx;\n}\n.tbody-tr {\n  display: flex;\n  border-bottom: 1px solid #ebeef5;\n}\n.tbody-tr:last-child {\n  border-bottom-left-radius: 8rpx;\n  border-bottom-right-radius: 8rpx;\n}\n\n.tbody-tr-stripe {\n  background: #fff;\n  border-bottom: none;\n}\n.tbody-tr-stripe:nth-child(2n) {\n  background: #F6F6F6;\n}\n.tbody-tr .td {\n  white-space: wrap;\n  padding:20rpx 10rpx;\n  text-align: center;\n}\n\n.tbody-tr-border .td {\n  border-right: 1rpx solid #F6F6F6;\n}\n.tbody-tr-border .td:last-child {  \n  border-right: none;\n}\n.no-data {\n  display: flex;\n  padding: 50rpx;\n  color: #666;\n  justify-content: center;\n}"
  },
  {
    "path": "miniprogram/comm/behavior/about_bh.js",
    "content": "const pageHelper = require('../../helper/page_helper.js');\nconst cloudHelper = require('../../helper/cloud_helper.js'); \n\nmodule.exports = Behavior({\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false\n\t},\n\n\tmethods: { \n\n\t\t_loadDetail: async function (key,items) { \n\t\t\tlet title = '';\n\t\t\tfor (let k = 0; k < items.length; k++) {\n\t\t\t\tif (items[k].key == key) {\n\t\t\t\t\ttitle = items[k].title;\n\t\t\t\t\twx.setNavigationBarTitle({\n\t\t\t\t\t\ttitle\n\t\t\t\t\t});\n\n\t\t\t\t\tif (key == 'SETUP_CONTENT_ABOUT') {\n\t\t\t\t\t\tthis.setData({\n\t\t\t\t\t\t\taccountInfo: wx.getAccountInfoSync()\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tlet opts = {\n\t\t\t\ttitle: 'bar'\n\t\t\t}\n\t\t\tlet params = {\n\t\t\t\tkey\n\t\t\t}\n\t\t\tlet about = await cloudHelper.callCloudData('home/setup_get', params, opts);\n\t\t\tif (!about) {\n\t\t\t\tabout = [{ 'type': 'text', 'val': title }];\n\t\t\t}\n\n\t\t\tif (about) this.setData({\n\t\t\t\tabout,\n\t\t\t\tisLoad: true\n\t\t\t});\n\t\t},\n\n\t\t/**\n\t\t * 生命周期函数--监听页面初次渲染完成\n\t\t */\n\t\tonReady: function () {\n\n\t\t},\n\n\t\t/**\n\t\t * 生命周期函数--监听页面显示\n\t\t */\n\t\tonShow: function () {\n\n\t\t},\n\n\t\t/**\n\t\t * 生命周期函数--监听页面隐藏\n\t\t */\n\t\tonHide: function () {\n\n\t\t},\n\n\t\t/**\n\t\t * 生命周期函数--监听页面卸载\n\t\t */\n\t\tonUnload: function () {\n\n\t\t},\n\n\t\t/**\n\t\t * 页面相关事件处理函数--监听用户下拉动作\n\t\t */\n\t\tonPullDownRefresh: function () {\n\t\t\tthis._loadDetail();\n\t\t\twx.stopPullDownRefresh();\n\t\t},\n\n\n\t\t/**\n\t\t * 用户点击右上角分享\n\t\t */\n\t\tonShareAppMessage: function () {\n\n\t\t},\n\n\t\turl: function (e) {\n\t\t\tpageHelper.url(e, this);\n\t\t}\n\t}\n})"
  },
  {
    "path": "miniprogram/comm/behavior/my_fav_bh.js",
    "content": "const pageHelper = require('../../helper/page_helper.js');\nconst cloudHelper = require('../../helper/cloud_helper.js');\n\nmodule.exports = Behavior({\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * 生命周期函数--监听页面加载\n\t\t */\n\t\tonLoad: async function (options) {\n\t\t},\n\n\t\tmyCommListListener: function (e) {\n\t\t\tpageHelper.commListListener(this, e);\n\t\t},\n\n\t\t/**\n\t\t * 生命周期函数--监听页面初次渲染完成\n\t\t */\n\t\tonReady: function () {\n\n\t\t},\n\n\t\t/**\n\t\t * 生命周期函数--监听页面显示\n\t\t */\n\t\tonShow: function () {\n\n\t\t},\n\n\t\t/**\n\t\t * 生命周期函数--监听页面隐藏\n\t\t */\n\t\tonHide: function () {\n\n\t\t},\n\n\t\t/**\n\t\t * 生命周期函数--监听页面卸载\n\t\t */\n\t\tonUnload: function () {\n\n\t\t},\n\n\n\t\t/**\n\t\t * 页面上拉触底事件的处理函数\n\t\t */\n\t\tonReachBottom: function () {\n\n\t\t},\n\n\t\turl: function (e) {\n\t\t\tpageHelper.url(e, this);\n\t\t},\n\n\t\tbindDelTap: async function (e) {\n\n\t\t\tlet oid = e.currentTarget.dataset.oid;\n\t\t\tif (!oid) return;\n\t\t\tlet that = this;\n\t\t\tlet callback = async function () {\n\t\t\t\tawait cloudHelper.callCloudSumbit('fav/del', {\n\t\t\t\t\toid\n\t\t\t\t}).then(res => {\n\t\t\t\t\tpageHelper.delListNode(oid, that.data.dataList.list, 'FAV_OID');\n\t\t\t\t\tthat.data.dataList.total--;\n\t\t\t\t\tthat.setData({\n\t\t\t\t\t\tdataList: that.data.dataList\n\t\t\t\t\t});\n\t\t\t\t\tpageHelper.showSuccToast('删除成功');\n\t\t\t\t}).catch(err => {\n\t\t\t\t\tconsole.log(err);\n\t\t\t\t });\n\t\t\t}\n\t\t\tpageHelper.showConfirm('您确认删除？', callback);\n\t\t}\n\t}\n})"
  },
  {
    "path": "miniprogram/comm/behavior/my_foot_bh.js",
    "content": "const FootBiz = require('../biz/foot_biz.js');\nconst pageHelper = require('../../helper/page_helper.js');\n\nmodule.exports = Behavior({\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * 生命周期函数--监听页面加载\n\t\t */\n\t\tonLoad: async function (options) {\n\t\t\tthis._loadList();\n\t\t},\n\n\t\t_loadList: async function (e) {\n\t\t\tlet footList = FootBiz.getFootList();\n\t\t\tthis.setData({\n\t\t\t\tfootList\n\t\t\t});\n\t\t},\n\t\t/**\n\t\t * 生命周期函数--监听页面初次渲染完成\n\t\t */\n\t\tonReady: function () {\n\n\t\t},\n\n\t\t/**\n\t\t * 生命周期函数--监听页面显示\n\t\t */\n\t\tonShow: function () {\n\n\t\t},\n\n\t\t/**\n\t\t * 生命周期函数--监听页面隐藏\n\t\t */\n\t\tonHide: function () {\n\n\t\t},\n\n\t\t/**\n\t\t * 生命周期函数--监听页面卸载\n\t\t */\n\t\tonUnload: function () {\n\n\t\t},\n\n\t\t/**\n\t\t * 页面相关事件处理函数--监听用户下拉动作\n\t\t */\n\t\tonPullDownRefresh: async function () {\n\t\t\tawait this._loadList();\n\t\t\twx.stopPullDownRefresh();\n\t\t},\n\n\t\t/**\n\t\t * 页面上拉触底事件的处理函数\n\t\t */\n\t\tonReachBottom: function () {\n\n\t\t},\n\n\t\turl: function (e) {\n\t\t\tpageHelper.url(e, this);\n\t\t}\n\t}\n})"
  },
  {
    "path": "miniprogram/comm/behavior/news_index_bh.js",
    "content": "const pageHelper = require('../../helper/page_helper.js');\nmodule.exports = Behavior({\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t\t* 生命周期函数--监听页面加载\n\t\t\t*/\n\t\tonLoad: async function (options) {\n\n\t\t},\n\n\t\t/**\n\t\t * 生命周期函数--监听页面初次渲染完成\n\t\t */\n\t\tonReady: function () { },\n\n\t\t/**\n\t\t * 生命周期函数--监听页面显示\n\t\t */\n\t\tonShow: async function () {\n\n\t\t},\n\n\t\t/**\n\t\t * 生命周期函数--监听页面隐藏\n\t\t */\n\t\tonHide: function () {\n\n\t\t},\n\n\t\t/**\n\t\t * 生命周期函数--监听页面卸载\n\t\t */\n\t\tonUnload: function () {\n\n\t\t},\n\n\t\turl: async function (e) {\n\t\t\tpageHelper.url(e, this);\n\t\t},\n\n\t\tbindCommListCmpt: function (e) {\n\t\t\tpageHelper.commListListener(this, e);\n\t\t},\n\n\t\t/**\n\t\t * 用户点击右上角分享\n\t\t */\n\t\tonShareAppMessage: function () {\n\n\t\t},\n\n\t\t_setCate(cateList, options, cateId = 0) {\n\t\t\tif (!cateId) {\n\t\t\t\tif (options && options.id) {\n\t\t\t\t\tcateId = options.id;\n\t\t\t\t}\n\t\t\t} \n\n\t\t\tthis.setData({\n\t\t\t\t_params: {\n\t\t\t\t\tcateId,\n\t\t\t\t}\n\t\t\t});\n\n\n\n\t\t\tfor (let k = 0; k < cateList.length; k++) {\n\t\t\t\tif (cateList[k].id == cateId) {\n\t\t\t\t\twx.setNavigationBarTitle({\n\t\t\t\t\t\ttitle: cateList[k].title\n\t\t\t\t\t});\n\n\t\t\t\t\tif (cateList[k].style) { //样式\n\t\t\t\t\t\tthis.setData({\n\t\t\t\t\t\t\tlistMode: cateList[k].style\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.setData({\n\t\t\t\t\t\t\tlistMode: 'leftbig1'\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t}\n})"
  },
  {
    "path": "miniprogram/comm/behavior/search_bh.js",
    "content": "const SearchBiz = require('../../comm/biz/search_biz.js');\nconst pageHelper = require('../../helper/page_helper.js');\n\nmodule.exports = Behavior({\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\ttype: '', // 来自哪个业务标识\n\t\treturnUrl: '', //搜索完返回哪个地址\n\t\tcacheName: '', //本业务搜索历史缓存\n\t\tsearch: '', //搜索关键字\n\n\t\thisKeys: []\n\t},\n\n\tmethods: {\n\t\t/**\n * 生命周期函数--监听页面加载\n */\n\t\tonLoad: async function (options) {\n\t\t\tlet type = options.type;\n\t\t\tlet returnUrl = options.returnUrl;\n\n\t\t\tlet cacheName = 'SERACH_HIS_' + type;\n\n\t\t\tlet hisKeys = SearchBiz.getHistory(cacheName);\n\t\t\tif (hisKeys)\n\t\t\t\tthis.setData({\n\t\t\t\t\thisKeys\n\t\t\t\t});\n\n\t\t\tthis.setData({\n\t\t\t\thisKeys,\n\t\t\t\ttype,\n\t\t\t\tcacheName,\n\t\t\t\treturnUrl\n\t\t\t});\n\n\t\t\tif (options && options.source)\n\t\t\t\tthis.setData({\n\t\t\t\t\tsource: options.source,\n\t\t\t\t});\n\n\t\t},\n\n\t\t/**\n\t\t * 生命周期函数--监听页面初次渲染完成\n\t\t */\n\t\tonReady: function () {\n\n\t\t},\n\n\t\t/**\n\t\t * 生命周期函数--监听页面显示\n\t\t */\n\t\tonShow: function () {\n\n\t\t},\n\n\t\t/**\n\t\t * 生命周期函数--监听页面隐藏\n\t\t */\n\t\tonHide: function () {\n\n\t\t},\n\n\t\t/**\n\t\t * 生命周期函数--监听页面卸载\n\t\t */\n\t\tonUnload: function () {\n\n\t\t},\n\n\t\turl: function (e) {\n\t\t\tpageHelper.url(e, this);\n\t\t},\n\n\n\t\t/**\n\t\t *  点击确认搜索\n\t\t */\n\t\tbindSearchConfirm: function (e) {\n\n\t\t\tif (!this.data.type) return;\n\n\t\t\tlet search = this.data.search.trim();\n\t\t\tif (!search) return;\n\n\t\t\t// 历史记录\n\t\t\tlet hisKeys = SearchBiz.addHistory(this.data.cacheName, search);\n\t\t\tthis.setData({\n\t\t\t\tsearch,\n\t\t\t\thisKeys\n\t\t\t});\n\n\t\t\tlet prevPage = pageHelper.getPrevPage();\n\t\t\t// 直接调用上一个页面的setData()方法，把数据存到上一个页面中去\n\t\t\tprevPage.setData({\n\t\t\t\tsearch,\n\t\t\t})\n\t\t\twx.navigateBack();\n\n\t\t},\n\n\t\t// 清空搜索记录\n\t\tbindDelHisTap: function (e) {\n\t\t\tSearchBiz.clearHistory(this.data.cacheName);\n\t\t\tthis.setData({\n\t\t\t\thisKeys: []\n\t\t\t});\n\t\t},\n\n\t\t//清除关键字\n\t\tbindClearKeyTap: function (e) {\n\t\t\tthis.setData({\n\t\t\t\tsearch: ''\n\t\t\t});\n\t\t},\n\n\t\t// 点击历史\n\t\tbindKeyTap: function (e) {\n\t\t\tlet search = e.currentTarget.dataset.key.trim();\n\t\t\tif (search) {\n\t\t\t\tthis.setData({\n\t\t\t\t\tsearch\n\t\t\t\t});\n\t\t\t\tthis.bindSearchConfirm(e);\n\t\t\t}\n\t\t}\n\t}\n})"
  },
  {
    "path": "miniprogram/comm/biz/admin_biz.js",
    "content": "/**\n * Notes: 后台管理模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-11-14 07:48:00 \n */\n\nconst BaseBiz = require('./base_biz.js');\nconst cacheHelper = require('../../helper/cache_helper.js');\nconst cloudHelper = require('../../helper/cloud_helper.js');\nconst pageHelper = require('../../helper/page_helper.js');\nconst constants = require('../constants.js');\nconst setting = require('../../setting/setting.js');\n\nclass AdminBiz extends BaseBiz {\n\n\t// 文章内容\n\tstatic setContentDesc(that) {\n\t\tlet contentDesc = '未填写';\n\t\tlet content = that.data.formContent;\n\t\tlet imgCnt = 0;\n\t\tlet textCnt = 0;\n\t\tfor (let k = 0; k < content.length; k++) {\n\t\t\tif (content[k].type == 'img') imgCnt++;\n\t\t\tif (content[k].type == 'text') textCnt++;\n\t\t}\n\n\t\tif (imgCnt || textCnt) {\n\t\t\tcontentDesc = textCnt + '段文字，' + imgCnt + '张图片';\n\t\t}\n\t\tthat.setData({\n\t\t\tcontentDesc\n\t\t});\n\t}\n\n\tstatic async adminLogin(that, name, pwd) {\n\t\tif (name.length < 5 || name.length > 30) {\n\t\t\twx.showToast({\n\t\t\t\ttitle: '账号输入错误(5-30位)',\n\t\t\t\ticon: 'none'\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tif (pwd.length < 5 || pwd.length > 30) {\n\t\t\twx.showToast({\n\t\t\t\ttitle: '密码输入错误(5-30位)',\n\t\t\t\ticon: 'none'\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tlet params = {\n\t\t\tname,\n\t\t\tpwd\n\t\t};\n\t\tlet opt = {\n\t\t\ttitle: '登录中'\n\t\t};\n\n\t\ttry {\n\t\t\tawait cloudHelper.callCloudSumbit('admin/login', params, opt).then(res => {\n\t\t\t\tif (res && res.data && res.data.name)\n\t\t\t\t\tcacheHelper.set(constants.CACHE_ADMIN, res.data, constants.ADMIN_TOKEN_EXPIRE);\n\n\t\t\t\twx.reLaunch({\n\t\t\t\t\turl: pageHelper.fmtURLByPID('/pages/admin/index/home/admin_home'),\n\t\t\t\t});\n\t\t\t});\n\t\t} catch (e) {\n\t\t\tconsole.log(e);\n\t\t}\n\n\t}\n\n\n\t/**\n\t * 清空管理员登录\n\t */\n\tstatic clearAdminToken() {\n\t\tcacheHelper.remove(constants.CACHE_ADMIN);\n\t}\n\n\t/**\n\t * 获取管理员信息\n\t */\n\tstatic getAdminToken() {\n\t\treturn cacheHelper.get(constants.CACHE_ADMIN);\n\t}\n\n\t/**\n\t * 获取管理员电话\n\t */\n\tstatic getAdminName() {\n\t\tlet admin = cacheHelper.get(constants.CACHE_ADMIN);\n\t\tif (!admin) return '';\n\t\treturn admin.name;\n\t}\n\n\t/**\n\t * 是否超级管理员\n\t */\n\tstatic isSuperAdmin() {\n\t\tlet admin = cacheHelper.get(constants.CACHE_ADMIN);\n\t\tif (!admin) return false;\n\t\treturn (admin.type == 1);\n\t}\n\n\t//  登录状态判定\n\tstatic isAdmin(that, isSuper = false) {\n\t\twx.setNavigationBarColor({ //顶部\n\t\t\tbackgroundColor: '#2499f2',\n\t\t\tfrontColor: '#ffffff',\n\t\t});\n\n\t\tif (setting.IS_SUB) wx.hideHomeButton();\n\n\t\tlet admin = cacheHelper.get(constants.CACHE_ADMIN);\n\t\tif (!admin) {\n\t\t\treturn wx.showModal({\n\t\t\t\ttitle: '',\n\t\t\t\tcontent: '登录已过期，请重新登录',\n\t\t\t\tshowCancel: false,\n\t\t\t\tconfirmText: '确定',\n\t\t\t\tsuccess: res => {\n\t\t\t\t\twx.reLaunch({\n\t\t\t\t\t\turl: pageHelper.fmtURLByPID('/pages/admin/index/login/admin_login'),\n\t\t\t\t\t});\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\n\t\t}\n\n\t\tif (isSuper && admin.type != 1) {\n\t\t\treturn wx.showModal({\n\t\t\t\ttitle: '',\n\t\t\t\tcontent: '此功能需要超级管理员操作',\n\t\t\t\tshowCancel: false,\n\t\t\t\tconfirmText: '确定',\n\t\t\t\tsuccess: res => {\n\t\t\t\t\twx.reLaunch({\n\t\t\t\t\t\turl: pageHelper.fmtURLByPID('/pages/admin/index/home/admin_home'),\n\t\t\t\t\t});\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tthat.setData({\n\t\t\tisAdmin: true,\n\t\t\tisSuperAdmin: this.isSuperAdmin()\n\t\t});\n\t\treturn true;\n\t}\n\n}\n\nAdminBiz.CHECK_FORM_MGR_ADD = {\n\tname: 'formName|must|string|min:5|max:30|name=账号',\n\tdesc: 'formDesc|must|string|max:30|name=姓名',\n\tphone: 'formPhone|string|len:11|name=手机',\n\tpassword: 'formPassword|must|string|min:6|max:30|name=密码',\n};\n\nAdminBiz.CHECK_FORM_MGR_EDIT = {\n\tname: 'formName|must|string|min:5|max:30|name=账号',\n\tdesc: 'formDesc|must|string|max:30|name=姓名',\n\tphone: 'formPhone|string|len:11|name=手机',\n\tpassword: 'formPassword|string|min:6|max:30|name=新密码',\n};\n\nAdminBiz.CHECK_FORM_MGR_PWD = {\n\toldPassword: 'formOldPassword|must|string|min:6|max:30|name=旧密码',\n\tpassword: 'formPassword|must|string|min:6|max:30|name=新密码',\n\tpassword2: 'formPassword2|must|string|min:6|max:30|name=新密码再次填写',\n};\n\n\nmodule.exports = AdminBiz;"
  },
  {
    "path": "miniprogram/comm/biz/base_biz.js",
    "content": "/**\n * Notes: 基础模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-11-14 07:48:00 \n */\n\nconst pageHelper = require('../../helper/page_helper.js');\n\nclass BaseBiz {\n\n\tstatic getCateName(cateId, cateList) {\n\t\tfor (let k = 0; k < cateList.length; k++) {\n\t\t\tif (cateList[k].id == cateId) {\n\t\t\t\treturn cateList[k].title;\n\t\t\t}\n\t\t}\n\t\treturn '';\n\t}\n\n\tstatic getCateList(cateList) {\n\n\t\tlet arr = [];\n\t\tfor (let k = 0; k < cateList.length; k++) {\n\t\t\tarr.push({\n\t\t\t\tlabel: cateList[k].title,\n\t\t\t\ttype: 'cateId',\n\t\t\t\tval: cateList[k].id, //for options form\n\t\t\t\tvalue: cateList[k].id, //for list menu\n\t\t\t})\n\t\t}\n\n\t\treturn arr;\n\t}\n\n\tstatic setCateTitle(cateList) {\n\n\t\tlet curPage = pageHelper.getPrevPage(1);\n\t\tif (!curPage) return;\n\n\t\tlet cateId = null;\n\t\tif (curPage.options && curPage.options.id) {\n\t\t\tcateId = curPage.options.id;\n\t\t}\n\n\t\tfor (let k = 0; k < cateList.length; k++) {\n\t\t\tif (cateList[k].id == cateId) {\n\t\t\t\twx.setNavigationBarTitle({\n\t\t\t\t\ttitle: cateList[k].title\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t}\n}\n\nmodule.exports = BaseBiz;"
  },
  {
    "path": "miniprogram/comm/biz/fav_biz.js",
    "content": "/**\n * Notes: 预约模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-12-10 07:48:00 \n */\n\nconst BaseBiz = require('./base_biz.js');\nconst cloudHelper = require('../../helper/cloud_helper.js');\nconst pageHelper = require('../../helper/page_helper.js');\n\nclass FavBiz extends BaseBiz {\n\n\tstatic async isFav(that, oid) {\n\t\tif (!oid) return;\n\n\t\tthat.setData({\n\t\t\tisFav: -1\n\t\t});\n\n\t\t// 异步获取是否收藏\n\t\tlet params = {\n\t\t\toid\n\t\t};\n\t\tcloudHelper.callCloudSumbit('fav/is_fav', params, { title: 'bar' }).then(result => {\n\t\t\tthat.setData({\n\t\t\t\tisFav: result.data.isFav\n\t\t\t});\n\t\t}).catch(error => { })\n\t}\n\n\tstatic async updateFav(that, oid, isFav, type, title) {\n\t\tlet path = pageHelper.getCurrentPageUrlWithArgs();\n\t\tif (!oid || !path || !title || !type) return;\n\n\t\tlet params = {\n\t\t\toid,\n\t\t\ttitle,\n\t\t\ttype,\n\t\t\tpath\n\t\t}\n\t\tlet opts = {\n\t\t\ttitle: (isFav == 0) ? '收藏中' : '取消中'\n\t\t}\n\t\ttry {\n\t\t\tlet result = await cloudHelper.callCloudSumbit('fav/update', params, opts);\n\t\t\tthat.setData({\n\t\t\t\tisFav: result.data.isFav,\n\t\t\t});\n\t\t} catch (e) {\n\t\t\tconsole.log(e);\n\t\t}\n\t}\n\n}\n\nmodule.exports = FavBiz;"
  },
  {
    "path": "miniprogram/comm/biz/foot_biz.js",
    "content": "/**\n * Notes: 足迹模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY www.code942.com\n * Date: 2020-11-14 07:48:00 \n */\n\nconst BaseBiz = require('./base_biz.js');\nconst cacheHelper = require('../../helper/cache_helper.js');\nconst timeHelper = require('../../helper/time_helper.js');\nconst pageHelper = require('../../helper/page_helper.js');\nconst CACHE_FOOT = 'CACHE_FOOT';\n\nclass FootBiz extends BaseBiz {\n\n\tstatic getFootList() {\n\t\tlet foot = cacheHelper.get(CACHE_FOOT);\n\t\tif (foot) {\n\t\t\tfor (let i = 0; i < foot.length; i++) {\n\t\t\t\tfoot[i].time = timeHelper.timestamp2Time(foot[i].time);\n\t\t\t}\n\t\t}\n\n\t\treturn foot;\n\t}\n\n\t/**添加足迹缓存\n\t * \n\t * @param {*} key 键\n\t * @param {*} val 值 \n\t * 格式 key:{ \n\t *  type:类型  \n\t *  title:标题\n\t *  time:加入时间\n\t * }\n\t * @param {*} size 最大个数\n\t * @param {*} expire 过期时间\n\t */\n\tstatic addFoot(type, title, size = 60, expire = 86400 * 365 * 3) {\n\t\tlet path = pageHelper.getCurrentPageUrlWithArgs();\n\t\tif (!path || !title || !type) return [];\n\n\t\tlet foot = cacheHelper.get(CACHE_FOOT, []);\n\n\t\t//查询是否存在 并删除\n\t\tfor (let k = 0; k < foot.length; k++) {\n\t\t\tif (path == foot[k].path)\n\t\t\t\tfoot.splice(k, 1);\n\t\t}\n\n\t\t// 加到头部\n\t\tlet val = {\n\t\t\tpath,\n\t\t\ttype,\n\t\t\ttitle,\n\t\t\ttime: timeHelper.time()\n\t\t}\n\t\tfoot.unshift(val);\n\n\t\t// 判断个数， 多的删除\n\t\tif (foot.length > size)\n\t\t\tfoot.splice(foot.length - 1, 1);\n\n\t\t// 存缓存\n\t\tcacheHelper.set(CACHE_FOOT, foot, expire);\n\n\t\treturn foot;\n\t}\n}\n\nmodule.exports = FootBiz;"
  },
  {
    "path": "miniprogram/comm/biz/passport_biz.js",
    "content": "/**\n * Notes: 注册登录模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-11-14 07:48:00 \n */\n\nconst BaseBiz = require('./base_biz.js');\nconst cacheHelper = require('../../helper/cache_helper.js');\nconst cloudHelper = require('../../helper/cloud_helper.js');\nconst pageHelper = require('../../helper/page_helper.js');\nconst helper = require('../../helper/helper.js');\nconst constants = require('../constants.js');\n\nclass PassportBiz extends BaseBiz {\n\n\t// 静默登录(有登录状态则不登录)  \n\tstatic async loginSilence(that) {\n\t\treturn await PassportBiz.loginCheck(false, 'slience', 'bar', that);\n\t}\n\n\t// 强制静默登录(有不论是否有登录状态)  \n\tstatic async loginSilenceMust(that) {\n\t\treturn await PassportBiz.loginCheck(false, 'must', 'bar', that);\n\t}\n\n\t// 必须登陆 可以取消(窗口形式) \n\tstatic async loginMustCancelWin(that) {\n\t\treturn await PassportBiz.loginCheck(true, 'cancel', '', that);\n\t}\n\n\t// 必须登陆 只能强制注册或者回上页(窗口形式)  \n\tstatic async loginMustBackWin(that) {\n\t\treturn await PassportBiz.loginCheck(true, 'back', '', that);\n\t}\n\n\t// 获取token  \n\tstatic getToken() {\n\t\tlet token = cacheHelper.get(constants.CACHE_TOKEN);\n\t\treturn token || null;\n\t}\n\n\t// 设置token\n\tstatic setToken(token) {\n\t\tif (!token) return;\n\t\tcacheHelper.set(constants.CACHE_TOKEN, token, constants.CACHE_TOKEN_EXPIRE);\n\t}\n\n\t//  获取user id \n\tstatic getUserId() {\n\t\tlet token = cacheHelper.get(constants.CACHE_TOKEN);\n\t\tif (!token) return '';\n\t\treturn token.id || '';\n\t}\n\n\t// 获取user name \n\tstatic getUserName() {\n\t\tlet token = cacheHelper.get(constants.CACHE_TOKEN);\n\t\tif (!token) return '';\n\t\treturn token.name || '';\n\t}\n\n\tstatic getStatus() {\n\t\tlet token = cacheHelper.get(constants.CACHE_TOKEN);\n\t\tif (!token) return -1;\n\t\treturn token.status || -1;\n\t}\n\n\t// 是否登录 \n\tstatic isLogin() {\n\t\tlet id = PassportBiz.getUserId();\n\t\treturn (id.length > 0) ? true : false;\n\t}\n\n\tstatic loginStatusHandler(method, status) {\n\t\tlet content = '';\n\t\tif (status == 0) content = '您的注册正在审核中，暂时无法使用此功能！';\n\t\telse if (status == 8) content = '您的注册审核未通过，暂时无法使用此功能；请在个人中心修改资料，再次提交审核！';\n\t\telse if (status == 9) content = '您的账号已经禁用, 无法使用此功能！';\n\t\tif (method == 'cancel') {\n\t\t\twx.showModal({\n\t\t\t\ttitle: '温馨提示',\n\t\t\t\tcontent,\n\t\t\t\tconfirmText: '取消',\n\t\t\t\tshowCancel: false\n\t\t\t});\n\t\t}\n\t\telse if (method == 'back') {\n\t\t\twx.showModal({\n\t\t\t\ttitle: '温馨提示',\n\t\t\t\tcontent,\n\t\t\t\tconfirmText: '返回',\n\t\t\t\tshowCancel: false,\n\t\t\t\tsuccess(result) {\n\t\t\t\t\twx.navigateBack();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\treturn false;\n\t}\n\n\t// 登录判断及处理\n\tstatic async loginCheck(mustLogin = false, method = 'back', title = '', that = null) {\n\t\tlet token = cacheHelper.get(constants.CACHE_TOKEN);\n\t\tif (token && method != 'must') {\n\t\t\tif (that)\n\t\t\t\tthat.setData({\n\t\t\t\t\tisLogin: true\n\t\t\t\t});\n\t\t\treturn true;\n\t\t} else {\n\t\t\tif (that) that.setData({\n\t\t\t\tisLogin: false\n\t\t\t});\n\t\t}\n\n\t\tlet opt = {\n\t\t\ttitle: title || '登录中',\n\t\t};\n\n\t\tlet res = await cloudHelper.callCloudSumbit('passport/login', {}, opt).then(result => {\n\t\t\tPassportBiz.clearToken();\n\t\t\tif (result && helper.isDefined(result.data.token) && result.data.token && result.data.token.status == 1) {\n\t\t\t\tPassportBiz.setToken(result.data.token);\n\n\t\t\t\tif (that) that.setData({\n\t\t\t\t\tisLogin: true\n\t\t\t\t});\n\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (mustLogin && result && helper.isDefined(result.data.token) && result.data.token && (result.data.token.status == 0 || result.data.token.status == 8 || result.data.token.status == 9)) {\n\t\t\t\tlet status = result.data.token.status;\n\t\t\t\treturn PassportBiz.loginStatusHandler(method, status);\n\t\t\t}\n\t\t\telse if (mustLogin && method == 'cancel') {\n\t\t\t\twx.showModal({\n\t\t\t\t\ttitle: '温馨提示',\n\t\t\t\t\tcontent: '此功能仅限注册用户',\n\t\t\t\t\tconfirmText: '马上注册',\n\t\t\t\t\tcancelText: '取消',\n\t\t\t\t\tsuccess(result) {\n\t\t\t\t\t\tif (result.confirm) {\n\t\t\t\t\t\t\tlet url = pageHelper.fmtURLByPID('/pages/my/reg/my_reg') + '?retUrl=back';\n\t\t\t\t\t\t\twx.navigateTo({ url });\n\n\t\t\t\t\t\t} else if (result.cancel) {\n\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (mustLogin && method == 'back') {\n\t\t\t\twx.showModal({\n\t\t\t\t\ttitle: '温馨提示',\n\t\t\t\t\tcontent: '此功能仅限注册用户',\n\t\t\t\t\tconfirmText: '马上注册',\n\t\t\t\t\tcancelText: '返回',\n\t\t\t\t\tsuccess(result) {\n\t\t\t\t\t\tif (result.confirm) {\n\t\t\t\t\t\t\tlet retUrl = encodeURIComponent(pageHelper.getCurrentPageUrlWithArgs());\n\t\t\t\t\t\t\tlet url = pageHelper.fmtURLByPID('/pages/my/reg/my_reg') + '?retUrl=' + retUrl;\n\t\t\t\t\t\t\twx.redirectTo({ url });\n\t\t\t\t\t\t} else if (result.cancel) {\n\t\t\t\t\t\t\tlet len = getCurrentPages().length;\n\t\t\t\t\t\t\tif (len == 1) {\n\t\t\t\t\t\t\t\tlet url = pageHelper.fmtURLByPID('/pages/default/index/default_index');\n\t\t\t\t\t\t\t\twx.reLaunch({ url });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\twx.navigateBack();\n\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (mustLogin && method == 'back') {\n\t\t\t\twx.showModal({\n\t\t\t\t\ttitle: '温馨提示',\n\t\t\t\t\tcontent: '此功能仅限注册用户',\n\t\t\t\t\tconfirmText: '马上注册',\n\t\t\t\t\tcancelText: '返回',\n\t\t\t\t\tsuccess(result) {\n\t\t\t\t\t\tif (result.confirm) {\n\t\t\t\t\t\t\tlet url = pageHelper.fmtURLByPID('/pages/my/reg/my_reg');\n\t\t\t\t\t\t\twx.reLaunch({ url });\n\t\t\t\t\t\t} else if (result.cancel) {\n\t\t\t\t\t\t\twx.navigateBack();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t}).catch(err => {\n\t\t\tconsole.log(err);\n\t\t\tPassportBiz.clearToken();\n\t\t\treturn false;\n\t\t});\n\n\t\treturn res;\n\t}\n\n\t// 清除登录缓存\n\tstatic clearToken() {\n\t\tcacheHelper.remove(constants.CACHE_TOKEN);\n\t}\n\n\t// 手机号码\n\tstatic async getPhone(e, that) {\n\t\tif (e.detail.errMsg == \"getPhoneNumber:ok\") {\n\n\t\t\tlet cloudID = e.detail.cloudID;\n\t\t\tlet params = {\n\t\t\t\tcloudID\n\t\t\t};\n\t\t\tlet opt = {\n\t\t\t\ttitle: '手机验证中'\n\t\t\t};\n\t\t\tawait cloudHelper.callCloudSumbit('passport/phone', params, opt).then(res => {\n\t\t\t\tlet phone = res.data;\n\t\t\t\tif (!phone || phone.length < 11)\n\t\t\t\t\twx.showToast({\n\t\t\t\t\t\ttitle: '手机号码获取失败，请重新填写手机号码',\n\t\t\t\t\t\ticon: 'none',\n\t\t\t\t\t\tduration: 2000\n\t\t\t\t\t});\n\t\t\t\telse {\n\t\t\t\t\tthat.setData({\n\t\t\t\t\t\tformMobile: phone\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t} else\n\t\t\twx.showToast({\n\t\t\t\ttitle: '手机号码获取失败，请重新填写手机号码',\n\t\t\t\ticon: 'none'\n\t\t\t});\n\t}\n}\n\n\n\n/** 表单校验    */\nPassportBiz.CHECK_FORM = {\n\tname: 'formName|must|string|min:1|max:30|name=昵称',\n\tmobile: 'formMobile|must|len:11|name=手机',\n\tforms: 'formForms|array'\n};\n\n\nmodule.exports = PassportBiz;"
  },
  {
    "path": "miniprogram/comm/biz/public_biz.js",
    "content": "/**\n * Notes: 通用业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-05-22 07:48:00 \n */\n\nconst BaseBiz = require('./base_biz.js');\nconst setting = require('../../setting/setting.js');\nconst cacheHelper = require('../../helper/cache_helper.js');\nconst dataHelper = require('../../helper/data_helper.js');\n\nclass PublicBiz extends BaseBiz {\n\t/**\n\t * 页面初始化   \n\t * @param {*} skin   \n\t * @param {*} that  \n\t */\n\tstatic initPageBase(that, { skin, isSetNavColor = true }) {\n\t\tif (skin) {\n\t\t\tskin.IS_SUB = setting.IS_SUB;\n\n\t\t\tif ((setting.IS_SUB)) {\n\n\t\t\t\twx.hideHomeButton();\n\n\t\t\t\t// 顶部\n\t\t\t\tif (isSetNavColor)\n\t\t\t\t\twx.setNavigationBarColor({\n\t\t\t\t\t\tbackgroundColor: skin.NAV_BG,\n\t\t\t\t\t\tfrontColor: skin.NAV_COLOR,\n\t\t\t\t\t});\n\t\t\t}\n\n\t\t\tthat.setData({\n\t\t\t\tskin\n\t\t\t})\n\t\t}\n\n\t}\n\n\t// 从富文本提取简介\n\tstatic getRichEditorDesc(desc, content) {\n\t\tif (desc) return dataHelper.fmtText(desc, 100);\n\t\tif (!Array.isArray(content)) return desc;\n\n\t\tfor (let k = 0; k < content.length; k++) {\n\t\t\tif (content[k].type == 'text') return dataHelper.fmtText(content[k].val, 100);\n\t\t}\n\t\treturn desc;\n\t}\n\n\tstatic isCacheList(key) {\n\t\tkey = key.toUpperCase();\n\t\tif (setting.CACHE_IS_LIST)\n\t\t\treturn cacheHelper.get(key + '_LIST');\n\t\telse\n\t\t\treturn false;\n\t}\n\n\tstatic removeCacheList(key) {\n\t\tkey = key.toUpperCase();\n\t\tif (setting.CACHE_IS_LIST)\n\t\t\tcacheHelper.remove(key + '_LIST');\n\t}\n\n\tstatic setCacheList(key, time = setting.CACHE_LIST_TIME) {\n\t\tkey = key.toUpperCase();\n\t\tif (setting.CACHE_IS_LIST)\n\t\t\tcacheHelper.set(key + '_LIST', 'TRUE', time);\n\t}\n\n}\n\nmodule.exports = PublicBiz;"
  },
  {
    "path": "miniprogram/comm/biz/search_biz.js",
    "content": "/**\n * Notes: 搜索模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-11-14 07:48:00 \n */\n\nconst BaseBiz = require('./base_biz.js');\nconst cacheHelper = require('../../helper/cache_helper.js');\n\n/**\n * \n */\nclass SearchBiz extends BaseBiz {\n\t\n\tstatic clearHistory(key){\n\t\tcacheHelper.remove(key);\n\t}\n\n\tstatic getHistory(key)\n\t{ \n\t\treturn cacheHelper.get(key, []);\n\n\t}\n\n\t/**添加关键字缓存\n\t * \n\t * @param {*} key \n\t * @param {*} val \n\t * @param {*} size 个数\n\t * @param {*} expire 过期时间\n\t */\n\tstatic addHistory(key, val, size = 20, expire = 86400 * 30)  {\n\t\tif (!val || val.length == 0) return [];\n\t\t\n\t\tlet his = cacheHelper.get(key, []);\n\t\t\n\t\t//查询是否存在 并删除\n\t\tlet pos = his.indexOf(val);\t \n\t\tif (pos > -1) his.splice(pos, 1);\n \n\t\t// 加到头部\n\t\this.unshift(val);\n \n\t\t// 判断个数， 多的删除\n\t\tif (his.length > size)\n\t\t\this.splice(his.length - 1, 1);\n\t\t\t\n\t\t// 存缓存\n\t\tcacheHelper.set(key, his, expire);\n\n\t\treturn his;\n\t}\n\n}\n\nmodule.exports = SearchBiz;"
  },
  {
    "path": "miniprogram/comm/constants.js",
    "content": "/**\n * Notes: 通用常量\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-11-14 07:48:00 \n */\n\nmodule.exports = {\n\tCACHE_TOKEN: 'CACHE_TOKEN', // 登录 \n\tCACHE_TOKEN_EXPIRE: 86400, //登录有效时间 秒 \n\n\tCACHE_ADMIN: 'ADMIN_TOKEN', // 管理员登录   \n\tADMIN_TOKEN_EXPIRE: 3600 * 2, //管理员过期时间2小时有效 秒  \n\n}"
  },
  {
    "path": "miniprogram/helper/cache_helper.js",
    "content": "/**\n * Notes: 微信缓存二次封装，有设置时效性的封装\n * Ver : CCMiniCloud Framework 3.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-11-14 07:48:00 \n */\nconst helper = require('./helper.js');\n\nconst TIME_SUFFIX = \"_deadtime\"\n\n/**\n * 设置\n * k 键key\n * v 值value\n * t 秒\n */\nfunction set(k, v, t = 86400 * 30) {\n\tif (!k) return null;\n\n\twx.setStorageSync(k, v);\n\tlet seconds = parseInt(t);\n\tif (seconds > 0) {\n\t\tlet newtime = Date.parse(new Date());\n\t\tnewtime = newtime / 1000 + seconds;\n\t\twx.setStorageSync(k + TIME_SUFFIX, newtime + \"\");\n\t} else {\n\t\twx.removeStorageSync(k + TIME_SUFFIX);\n\t}\n}\n \n\n/**\n * 获取\n * k 键key\n * def 默认值\n */\nfunction get(k, def = null) {\n\tif (!k) return null;\n\n\tlet deadtime = wx.getStorageSync(k + TIME_SUFFIX); \n\tif (!deadtime) return def;\n \n\tdeadtime = parseInt(deadtime); \n\tif (!deadtime) return def;\n\t\n\tif (deadtime) {\n\t\tif (parseInt(deadtime) < Date.parse(new Date()) / 1000) {\n\t\t\twx.removeStorageSync(k); \n\t\t\twx.removeStorageSync(k + TIME_SUFFIX); \n\t\t\treturn def;\n\t\t}\n\t} \n\n\tlet res = wx.getStorageSync(k);\n \n\tif (helper.isDefined(res)) {\n\t\treturn res;\n\t} else {\n\t\treturn def;\n\t}\n}\n\n/**\n * 删除\n */\nfunction remove(k) {\n\tif (!k) return null;\n\t\n\twx.removeStorageSync(k);\n\twx.removeStorageSync(k + TIME_SUFFIX);\n}\n\n/**\n * 清除所有key\n */\nfunction clear() {\n\twx.clearStorageSync();\n}\n\nmodule.exports = {\n\tset,\n\tget,\n\tremove,\n\tclear\n}"
  },
  {
    "path": "miniprogram/helper/cloud_helper.js",
    "content": "/**\n * Notes: 云操作类库\n * Ver : CCMiniCloud Framework 2.3.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2023-11-14 07:48:00 \n */\n\nconst helper = require('./helper.js');\nconst dataHelper = require('./data_helper.js');\nconst cacheHelper = require('./cache_helper.js');\nconst constants = require('../comm/constants.js');\nconst contentCheckHelper = require('../helper/content_check_helper.js');\nconst pageHelper = require('../helper/page_helper.js');\nconst timeHelper = require('../helper/time_helper.js');\nconst setting = require('../setting/setting.js');\n\nconst CODE = {\n\tSUCC: 200,\n\tSVR: 500, //服务器错误  \n\tLOGIC: 1600, //逻辑错误 \n\tDATA: 1301, // 数据校验错误 \n\tHEADER: 1302, // header 校验错误  \n\n\tADMIN_ERROR: 2401 //管理员错误\n};\n\nfunction callCloudSumbitAsync(route, params = {}, options) {\n\tif (!helper.isDefined(options)) options = {\n\t\thint: false\n\t}\n\tif (!helper.isDefined(options.hint)) options.hint = false;\n\treturn callCloud(route, params, options)\n}\n\nasync function callCloudSumbit(route, params = {}, options = { title: '提交中...' }) {\n\tif (!helper.isDefined(options)) options = {\n\t\ttitle: '提交中..'\n\t}\n\tif (!helper.isDefined(options.title)) options.title = '提交中..';\n\treturn await callCloud(route, params, options);\n}\n\nasync function callCloudData(route, params = {}, options) {\n\tif (!helper.isDefined(options)) options = {\n\t\ttitle: '加载中..'\n\t}\n\n\tif (!helper.isDefined(options.title)) options.title = '加载中..';\n\tlet result = await callCloud(route, params, options).catch(err => {\n\t\treturn null;\n\t});\n\n\tif (result && helper.isDefined(result.data)) {\n\t\tresult = result.data;\n\t\tif (Array.isArray(result)) {\n\t\t\t// 数组处理\n\t\t} else if (Object.keys(result).length == 0) {\n\t\t\tresult = null; //对象处理\n\t\t}\n\n\t}\n\treturn result;\n}\n\nfunction callCloud(route, params = {}, options) {\n\n\tlet title = '加载中';\n\tlet hint = true;\n\n\t// 标题\n\tif (helper.isDefined(options) && helper.isDefined(options.title))\n\t\ttitle = options.title;\n\n\tif (helper.isDefined(options) && helper.isDefined(options.hint))\n\t\thint = options.hint;\n\n\tif (helper.isDefined(options) && helper.isDefined(options.doFail))\n\t\tdoFail = options.doFail;\n\n\tif (hint) {\n\t\tif (title == 'bar')\n\t\t\twx.showNavigationBarLoading();\n\t\telse\n\t\t\twx.showLoading({\n\t\t\t\ttitle: title,\n\t\t\t\tmask: true\n\t\t\t})\n\t}\n\n\tlet token = '';\n\t// 管理员token\n\tif (route.indexOf('admin/') > -1) {\n\t\tlet admin = cacheHelper.get(constants.CACHE_ADMIN);\n\t\tif (admin && admin.token) token = admin.token;\n\t} else {\n\t\t//正常用户\n\t\tlet user = cacheHelper.get(constants.CACHE_TOKEN);\n\t\tif (user && user.id) token = user.id;\n\t}\n\n\treturn new Promise(function (resolve, reject) {\n\n\t\tlet PID = pageHelper.getPID();\n\n\t\twx.cloud.callFunction({\n\t\t\tname: 'mcloud',\n\t\t\tdata: {\n\t\t\t\troute: route,\n\t\t\t\ttoken,\n\t\t\t\tPID,\n\t\t\t\tparams\n\t\t\t},\n\t\t\tsuccess: function (res) {\n\t\t\t\tif (res.result.code == CODE.LOGIC || res.result.code == CODE.DATA) {\n\t\t\t\t\tconsole.log(res)\n\t\t\t\t\t// 逻辑错误&数据校验错误 \n\t\t\t\t\tif (hint) {\n\t\t\t\t\t\twx.showModal({\n\t\t\t\t\t\t\ttitle: '温馨提示',\n\t\t\t\t\t\t\tcontent: res.result.msg,\n\t\t\t\t\t\t\tshowCancel: false\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\treject(res.result);\n\t\t\t\t\treturn;\n\t\t\t\t} else if (res.result.code == CODE.ADMIN_ERROR) {\n\t\t\t\t\t// 后台登录错误\n\t\t\t\t\twx.reLaunch({\n\t\t\t\t\t\turl: pageHelper.fmtURLByPID('/pages/admin/index/login/admin_login'),\n\t\t\t\t\t});\n\t\t\t\t\t//reject(res.result);\n\t\t\t\t\treturn;\n\t\t\t\t} else if (res.result.code != CODE.SUCC) {\n\t\t\t\t\tif (hint) {\n\t\t\t\t\t\twx.showModal({\n\t\t\t\t\t\t\ttitle: '温馨提示',\n\t\t\t\t\t\t\tcontent: '系统开小差了，请稍后重试',\n\t\t\t\t\t\t\tshowCancel: false\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treject(res.result);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tresolve(res.result);\n\t\t\t},\n\t\t\tfail: function (err) {\n\t\t\t\tif (hint) {\n\t\t\t\t\tconsole.log(err)\n\t\t\t\t\tif (err && err.errMsg && err.errMsg.includes('-501000') && err.errMsg.includes('Environment not found')) {\n\t\t\t\t\t\twx.showModal({\n\t\t\t\t\t\t\ttitle: '',\n\t\t\t\t\t\t\tcontent: '未找到云环境ID，请按手册检查前端配置文件setting.js的配置项【CLOUD_ID】或咨询作者微信cclinux0730',\n\t\t\t\t\t\t\tshowCancel: false\n\t\t\t\t\t\t});\n\n\t\t\t\t\t} else if (err && err.errMsg && err.errMsg.includes('-501000') && err.errMsg.includes('FunctionName')) {\n\t\t\t\t\t\twx.showModal({\n\t\t\t\t\t\t\ttitle: '',\n\t\t\t\t\t\t\tcontent: '云函数未创建或者未上传，请参考手册或咨询作者微信cclinux0730',\n\t\t\t\t\t\t\tshowCancel: false\n\t\t\t\t\t\t});\n\n\t\t\t\t\t} else if (err && err.errMsg && err.errMsg.includes('-501000') && err.errMsg.includes('performed in the current function state')) {\n\t\t\t\t\t\twx.showModal({\n\t\t\t\t\t\t\ttitle: '',\n\t\t\t\t\t\t\tcontent: '云函数正在上传中或者上传有误，请稍候',\n\t\t\t\t\t\t\tshowCancel: false\n\t\t\t\t\t\t});\n\t\t\t\t\t} else\n\t\t\t\t\t\twx.showModal({\n\t\t\t\t\t\t\ttitle: '',\n\t\t\t\t\t\t\tcontent: '网络故障，请稍后重试',\n\t\t\t\t\t\t\tshowCancel: false\n\t\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treject(err.result);\n\t\t\t\treturn;\n\t\t\t},\n\t\t\tcomplete: function (res) {\n\t\t\t\tif (hint) {\n\t\t\t\t\tif (title == 'bar')\n\t\t\t\t\t\twx.hideNavigationBarLoading();\n\t\t\t\t\telse\n\t\t\t\t\t\twx.hideLoading();\n\t\t\t\t}\n\t\t\t\t// complete\n\t\t\t}\n\t\t});\n\t});\n}\n\nasync function dataList(that, listName, route, params, options, isReverse = false) {\n\n\tconsole.log('dataList begin');\n\n\tif (!helper.isDefined(that.data[listName]) || !that.data[listName]) {\n\t\tlet data = {};\n\t\tdata[listName] = {\n\t\t\tpage: 1,\n\t\t\tsize: 20,\n\t\t\tlist: [],\n\t\t\tcount: 0,\n\t\t\ttotal: 0,\n\t\t\toldTotal: 0\n\t\t};\n\t\tthat.setData(data);\n\t}\n\n\t//改为后台默认控制\n\t//if (!helper.isDefined(params.size))\n\t//\tparams.size = 20;\n\n\tif (!helper.isDefined(params.isTotal))\n\t\tparams.isTotal = true;\n\n\tlet page = params.page;\n\tlet count = that.data[listName].count;\n\tif (page > 1 && page > count) {\n\t\twx.showToast({\n\t\t\tduration: 500,\n\t\t\ticon: 'none',\n\t\t\ttitle: '没有更多数据了',\n\t\t});\n\t\treturn;\n\t}\n\n\tfor (let key in params) {\n\t\tif (!helper.isDefined(params[key]))\n\t\t\tdelete params[key];\n\t}\n\n\tlet oldTotal = 0;\n\tif (that.data[listName] && that.data[listName].total)\n\t\toldTotal = that.data[listName].total;\n\tparams.oldTotal = oldTotal;\n\n\t// 云函数调用 \n\tawait callCloud(route, params, options).then(function (res) {\n\t\tconsole.log('cloud begin');\n\n\t\tlet dataList = res.data;\n\t\tlet tList = that.data[listName].list;\n\n\t\tif (dataList.page == 1) {\n\t\t\ttList = res.data.list;\n\t\t} else if (dataList.page > that.data[listName].page) {\n\t\t\tif (isReverse)\n\t\t\t\ttList = res.data.list.concat(tList);\n\t\t\telse\n\t\t\t\ttList = tList.concat(res.data.list);\n\t\t} else\n\t\t\treturn;\n\n\t\tdataList.list = tList;\n\t\tlet listData = {};\n\t\tlistData[listName] = dataList;\n\n\t\tthat.setData(listData);\n\n\t\tconsole.log('cloud END');\n\t}).catch(err => {\n\t\tconsole.log(err)\n\t});\n\n\tconsole.log('dataList END');\n\n}\n\nasync function getTempFileURLOne(fileID) {\n\tif (!fileID) return '';\n\n\tlet result = await wx.cloud.getTempFileURL({\n\t\tfileList: [fileID],\n\t})\n\tif (result && result.fileList && result.fileList[0] && result.fileList[0].tempFileURL)\n\t\treturn result.fileList[0].tempFileURL;\n\treturn '';\n}\n\nasync function transTempPics(imgList, dir, id, prefix = '') {\n\tif (setting.IS_DEMO) return imgList; \n\n\tif (prefix && !prefix.endsWith('_')) prefix += '_';\n\tif (!id) id = timeHelper.time('YMD');\n\n\tfor (let i = 0; i < imgList.length; i++) {\n\n\t\tlet filePath = imgList[i];\n\t\tlet ext = filePath.match(/\\.[^.]+?$/)[0];\n\n\t\t// 是否为临时文件\n\t\tif (filePath.includes('tmp') || filePath.includes('temp') || filePath.includes('wxfile')) {\n\n\t\t\tlet rd = prefix + dataHelper.genRandomNum(1000000, 9999999);\n\t\t\tlet cloudPath = id ? dir + id + '/' + rd + ext : dir + rd + ext;\n\t\t\tcloudPath = pageHelper.getPID() + '/' + cloudPath;\n\n\t\t\tawait wx.cloud.uploadFile({\n\t\t\t\tcloudPath,\n\t\t\t\tfilePath: filePath, // 文件路径\n\t\t\t}).then(res => {\n\t\t\t\timgList[i] = res.fileID;\n\t\t\t}).catch(error => {\n\t\t\t\t// handle error TODO:剔除图片\n\t\t\t\tconsole.error(error);\n\t\t\t})\n\t\t}\n\t}\n\n\treturn imgList;\n}\n\nasync function transRichEditorTempPics(content, dir, id, route) {\n\n\tlet imgList = [];\n\tfor (let k = 0; k < content.length; k++) {\n\t\tif (content[k].type == 'img') {\n\t\t\timgList.push(content[k].val);\n\t\t}\n\t}\n\n\t// 图片上传到云空间\n\timgList = await transTempPics(imgList, dir, id, 'rich');\n\n\t// 更新图片地址\n\tlet imgIdx = 0;\n\tfor (let k = 0; k < content.length; k++) {\n\t\tif (content[k].type == 'img') {\n\t\t\tcontent[k].val = imgList[imgIdx];\n\t\t\timgIdx++;\n\t\t}\n\t}\n\n\t// 更新本记录的图片信息\n\tlet params = {\n\t\tid,\n\t\tcontent\n\t}\n\n\ttry {\n\t\tawait callCloudSumbit(route, params);\n\t\treturn content;\n\t} catch (e) {\n\t\tconsole.error(e);\n\t}\n\n\treturn [];\n}\n\nasync function transCoverTempPics(imgList, dir, id, route) {\n\t// 图片上传到云空间\n\timgList = await transTempPics(imgList, dir, id, 'cover');\n\n\t// 更新本记录的图片信息\n\tlet params = {\n\t\tid,\n\t\timgList: imgList\n\t}\n\n\ttry {\n\t\tlet res = await callCloudSumbit(route, params);\n\t\treturn res.data.urls;\n\t} catch (err) {\n\t\tconsole.error(err);\n\t}\n}\n\nasync function transFormsTempPics(forms, dir, id, route) {\n\twx.showLoading({\n\t\ttitle: '提交中...',\n\t\tmask: true\n\t});\n\n\tlet hasImageForms = [];\n\tfor (let k = 0; k < forms.length; k++) {\n\t\tif (forms[k].type == 'image') {\n\t\t\tforms[k].val = await transTempPics(forms[k].val, dir, id, 'image');\n\t\t\thasImageForms.push(forms[k]);\n\t\t}\n\t\telse if (forms[k].type == 'content') {\n\t\t\tlet contentVal = forms[k].val;\n\t\t\tfor (let j in contentVal) {\n\t\t\t\tif (contentVal[j].type == 'img') {\n\t\t\t\t\tlet ret = await transTempPics([contentVal[j].val], dir, id, 'content');\n\t\t\t\t\tcontentVal[j].val = ret[0];\n\t\t\t\t}\n\t\t\t}\n\t\t\thasImageForms.push(forms[k]);\n\t\t}\n\t}\n\n\tif (hasImageForms.length == 0) return;\n\n\tlet params = {\n\t\tid,\n\t\thasImageForms\n\t}\n\n\ttry {\n\t\tawait callCloudSumbit(route, params);\n\t} catch (err) {\n\t\tconsole.error(err);\n\t}\n}\n\nasync function transTempPicOne(img, dir, id, isCheck = true) {\n\n\tif (isCheck) {\n\t\twx.showLoading({\n\t\t\ttitle: '图片校验中',\n\t\t\tmask: true\n\t\t});\n\t\tlet check = await contentCheckHelper.imgCheck(img);\n\t\tif (!check) {\n\t\t\twx.hideLoading();\n\t\t\treturn pageHelper.showModal('不合适的图片, 请重新上传', '温馨提示');\n\t\t}\n\t\twx.hideLoading();\n\t}\n\n\tlet imgList = [img];\n\timgList = await transTempPics(imgList, dir, id);\n\n\tif (imgList.length == 0)\n\t\treturn '';\n\telse {\n\t\treturn imgList[0];\n\t}\n\n\n}\n\nmodule.exports = {\n\tCODE,\n\tdataList,\n\tcallCloud,\n\tcallCloudSumbit,\n\tcallCloudData,\n\tcallCloudSumbitAsync,\n\ttransTempPics,\n\ttransRichEditorTempPics,\n\ttransCoverTempPics,\n\ttransFormsTempPics,\n\tgetTempFileURLOne,\n\ttransTempPicOne\n}\n"
  },
  {
    "path": "miniprogram/helper/content_check_helper.js",
    "content": " /**\n * Notes: UGC内容校验\n * Ver : CCMiniCloud Framework 2.4.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2023-11-14 07:48:00 \n */\n\nconst cloudHelper = require('../helper/cloud_helper.js');\nconst pageHelper = require('../helper/page_helper.js');\nconst setting = require('../setting/setting.js');\n\n/**\n * 图片类型校验\n * @param {*} fileName \n * @param {*} type \n */\nfunction imgTypeCheck(path, type = ['jpg', 'jpeg', 'png','JPG','JPEG','PNG']) {\n\tlet fmt = path.split(\".\")[(path.split(\".\")).length - 1];\n\tif (type.indexOf(fmt) > -1)\n\t\treturn true;\n\telse\n\t\treturn false;\n}\n\n/**\n * 图片大小校验\n * @param {*} size \n * @param {*} maxSize \n */\nfunction imgSizeCheck(size, maxSize) {\n\treturn size < maxSize;\n}\n\nasync function imgCheckCloud(path, opt) {\n \n\t\n\t/*\n\tlet result = await cloudHelper.callCloudSumbit('check/img', params, opt).then(res => {\n\t\treturn true;\n\t}).catch(err => {\n\t\treturn false;\n\t}); \n\t\t*/\n\n\tlet result = await wx.cloud.callFunction({\n\t\tname: 'cloud',\n\t\tdata: {\n\t\t\troute: 'check/img',\n\t\t\ttoken : '',\n\t\t\tparams:{img: wx.cloud.CDN( {\n\t\t\t\ttype: 'filePath',\n\t\t\t\tfilePath: path,\n\t\t\t})\n\t\t}\n\t\t},\n\t\tsuccess: function (res) { \n\t\t\tconsole.log(res)\n\t\t\tconsole.log('succ')\n\t\t\treturn true;\n\t\t},\n\t\tfail: function (res) {\n\t\t\tconsole.log(res)\n\t\t\treturn false;\n\t\t},\n\t\tcomplete: function (res) {\n\t\t\t \n\t\t}\n\t});\n\treturn result;\n}\n\n/**\n * 图像校验\n * @param {*} imgData \n */\nasync function imgCheck(imgData) { \n\n\tlet result = await wx.serviceMarket.invokeService({\n\t\tservice: 'wxee446d7507c68b11',\n\t\tapi: 'imgSecCheck',\n\t\tdata: {\n\t\t\t\"Action\": \"ImageModeration\",\n\t\t\t\"Scenes\": [\"PORN\", \"POLITICS\", \"TERRORISM\"],\n\t\t\t\"ImageUrl\":  new wx.serviceMarket.CDN({\n\t\t\t\ttype: 'filePath',\n\t\t\t\tfilePath: imgData,\n\t\t\t}),\n\t\t\t\"ImageBase64\": '',\n\t\t\t\"Config\": \"\",\n\t\t\t\"Extra\": \"\"\n\t\t},\n\t}).then(res => {\n\t\tif (res && res.data && res.data.Response &&\n\t\t\tres.data.Response.PornResult && res.data.Response.PornResult.Suggestion === 'PASS' &&\n\t\t\tres.data.Response.PoliticsResult && res.data.Response.PoliticsResult.Suggestion === 'PASS' &&\n\t\t\tres.data.Response.TerrorismResult && res.data.Response.TerrorismResult.Suggestion === 'PASS')\n\t\t\treturn true;\n\t\telse\n\t\t\treturn false;\n\t}).catch(err => {\n\t\tconsole.log(err);\n\t\treturn false;\n\t});\n\n\treturn result;\n}\n\n\nmodule.exports = {\n\timgCheck,\n\timgCheckCloud,\n\timgTypeCheck,\n\timgSizeCheck\n}\n"
  },
  {
    "path": "miniprogram/helper/data_helper.js",
    "content": "/**\n * Notes: 字符相关操作函数\n * Ver : CCMiniCloud Framework 2.5.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-09-05 04:00:00 \n */\n\n\n/**\n * 生成一个特定范围内的随机数\n */\nconst genRandomNum = (min, max) => (Math.random() * (max - min + 1) | 0) + min;\n\n/**\n * 生成一个随机的数字字母字符串 \n */\nconst genRandomString = len => {\n\tconst text = 'abcdefghijklmnopqrstuvwxyz0123456789';\n\tconst rdmIndex = text => Math.random() * text.length | 0;\n\tlet rdmString = '';\n\tfor (; rdmString.length < len; rdmString += text.charAt(rdmIndex(text)));\n\treturn rdmString;\n}\n\n/**\n * 生成一个随机的字母字符串 \n */\nconst genRandomAlpha = len => {\n\tconst text = 'abcdefghijklmnopqrstuvwxyz';\n\tconst rdmIndex = text => Math.random() * text.length | 0;\n\tlet rdmString = '';\n\tfor (; rdmString.length < len; rdmString += text.charAt(rdmIndex(text)));\n\treturn rdmString;\n}\n\n// 标签格式化\nfunction fmtTag(tag) {\n\tif (!tag || tag.constructor != String) return '';\n\ttag = tag.trim();\n\ttag = tag.replace(/，/g, ',');\n\n\tlet arr = tag.split(',');\n\tlet newArr = [];\n\tfor (let k = 0; k < arr.length; k++) {\n\t\tarr[k] = arr[k].trim();\n\t\tif (arr[k].length > 0) newArr.push(arr[k]);\n\t}\n\treturn newArr.join(',');\n}\n\n// 拆分一维数组为二维数组\nfunction spArr(arr, size) {\n\tif (!arr || !Array.isArray(arr) || arr.length == 0) return arr;\n\n\tlet newArray = [];\n\tlet index = 0;\n\twhile (index < arr.length) {\n\t\tnewArray.push(arr.slice(index, index += size));\n\t}\n\treturn newArray;\n}\n\n/**\n * 把字符串格式化为数组\n * @param {*} str \n * @param {*} sp \n */\nfunction str2Arr(str, sp = ',') {\n\tif (str && Array.isArray(str)) return str;\n\n\tstr = str.replace(/，/g, sp);\n\tlet arr = str.split(sp);\n\tfor (let i = 0; i < arr.length; i++) {\n\t\tarr[i] = arr[i].trim();\n\n\t\tif (isNumber(arr[i])) {\n\t\t\tarr[i] = Number(arr[i]);\n\t\t}\n\n\t}\n\treturn arr;\n}\n\n/**\n *  校验只要是数字（包含正负整数，0以及正负浮点数）就返回true \n * @param {*} val \n * @returns bool\n */\nfunction isNumber(val) {\n\tvar reg = /^[0-9]+.?[0-9]*$/;\n\tif (reg.test(val)) {\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n}\n\n/**\n * 提取对象数组的某个属性数组,如[{'x':1},{'x':2}] 提取 x得到[1,2]\n * @param {*} arr \n * @param {*} key \n * @returns []\n */\nfunction getArrByKey(arr, key) {\n\tif (!Array.isArray(arr)) return;\n\treturn arr.map((item) => {\n\t\treturn item[key]\n\t});\n}\n\n/**\n * 提取对象数组的多个属性数组, \n * 如 [{'x':1,'y':11,'z':111},{'x':2,'y':22,'z':222}] \n * 提取 ['x','y'] 得到[{'x':1,'y':11},{'x':2,'y':22}]\n * @param {*} arr \n * @param {*} keys \n * @returns []\n */\nfunction getArrByKeyMulti(arr, keys = []) {\n\tif (!Array.isArray(arr)) return;\n\tif (!Array.isArray(keys)) return;\n\n\tlet ret = [];\n\tfor (let k = 0; k < arr.length; k++) {\n\t\tlet node = {};\n\t\tfor (let j in keys) {\n\t\t\tnode[keys[j]] = arr[k][keys[j]];\n\t\t}\n\t\tret.push(node);\n\t}\n\n\treturn ret;\n}\n\n/**\n * 提取对象数组某个键值等于某值的对象数据\n * @param {*} arr \n * @param {*} key  \n * @param {*} val \n * @returns object {}\n */\nfunction getDataByKey(arr, key, val) { \n\tif (!Array.isArray(arr)) return null;\n\n\tfor (let k = 0; k < arr.length; k++) {\n\t\tif (arr[k][key] == val)\n\t\t\treturn arr[k];\n\t}\n\n\treturn null;\n}\n\n/**\n * 文本内容格式化处理\n * @param {*} content \n * @param {*} len 截取长度 -1不截取\n */\nfunction fmtText(content, len = -1) {\n\tif (!content) return content;\n\t\n\tlet str = content.replace(/[\\r\\n]/g, \"\"); //去掉回车换行\n\tif (len > 0) {\n\t\tstr = str.substr(0, len);\n\t}\n\treturn str.trim();\n}\n\n// 下划线转换驼峰\nfunction toHump(name) {\n\tname = name.replace(/\\_(\\w)/g, function (all, letter) {\n\t\treturn letter.toUpperCase();\n\t});\n\n\t// 首字母大写 \n\tlet firstChar = name.charAt(0).toUpperCase();\n\treturn firstChar + name.slice(1);\n}\n\n// 驼峰转换下划线\nfunction toLine(name) {\n\tname = name.replace(/([A-Z])/g, \"_$1\").toLowerCase();\n\n\t//如果首字符为下划线，干掉\n\tif (name.charAt(0) === '_')\n\t\treturn name.slice(1);\n\telse\n\t\treturn name;\n}\n\n// 金额格式化 dot为金额每隔三位用\",\"或\" \"间隔\nfunction fmtMoney(s, dot = ',', prefix = '¥') {\n\tif (s === '' || s === null || s === undefined) s = 0;\n\t\n\ts = parseFloat((s + \"\").replace(/[^\\d\\.-]/g, \"\")).toFixed(2) + \"\";\n\tvar l = s.split(\".\")[0].split(\"\").reverse(),\n\t\tr = s.split(\".\")[1];\n\tt = \"\";\n\tfor (i = 0; i < l.length; i++) {\n\t\tt += l[i] + ((i + 1) % 3 == 0 && (i + 1) != l.length ? dot : \"\");\n\t}\n\treturn prefix + t.split(\"\").reverse().join(\"\") + \".\" + r;\n}\n\n/**\n *简单数组转对象数组\n * @param {*} arr [1,2,3]\n * @param {*} key [x1,x2,x3]\n * @returns [{x1:1,x2:1,x3:1},{x1:2,x2:2,x3:2},{x1:3,x2:3,x3:3}]\n */\nfunction arr2ObjectArr(arr, key1, key2, key3) {\n\tlet ret = [];\n\tfor (let k = 0; k < arr.length; k++) {\n\t\tlet obj = {};\n\t\tif (key1) obj[key1] = arr[k];\n\t\tif (key2) obj[key2] = arr[k];\n\t\tif (key3) obj[key3] = arr[k];\n\t\tret.push(obj);\n\t}\n\treturn ret;\n}\n\n/**\n * property\n * @param {*} property 排序属性\n * @returns 排序好的数组 \n * 用法 arr.sort(compare('age'))\n */\nfunction objArrSortAsc(property) {\n\treturn function (a, b) {\n\t\tvar value1 = a[property];\n\t\tvar value2 = b[property];\n\t\tif (value1 < value2)\n\t\t\treturn -1;\n\t\telse if (value1 > value2)\n\t\t\treturn 1;\n\t\telse return 0;\n\t}\n}\n\n/**\n * property\n * @param {*} property 排序属性\n * @returns 排序好的数组 \n * 用法 arr.sort(compare('age'))\n */\nfunction objArrSortDesc(property) {\n\treturn function (a, b) {\n\t\tvar value1 = a[property];\n\t\tvar value2 = b[property];\n\t\tif (value1 < value2)\n\t\t\treturn 1;\n\t\telse if (value1 > value2)\n\t\t\treturn -1;\n\t\telse return 0;\n\t}\n}\n\n/**\n * 数组有则减少，无则增加\n * @param {*} arr \n * @param {*} data \n * @param {*} sort 排序方式 asc/desc\n */\nfunction arrAddDel(arr, data, sort = 'asc') {\n\tif (!arr) return arr;\n\tif (!Array.isArray(arr)) return arr;\n\n\tlet idx = arr.indexOf(data);\n\tif (idx > -1)\n\t\tarr.splice(idx, 1);\n\telse\n\t\tarr.push(data)\n\n\tif (sort == 'asc')\n\t\treturn arr.sort();\n\telse\n\t\treturn arr.reverse();\n} \n\n//数据深度拷贝\nfunction deepClone(data) {\n\tif (data === null || typeof data === 'string' || typeof data === 'number' || typeof data === 'boolean' || typeof data === 'undefined') {\n\t\treturn data;\n\t}\n\n\treturn JSON.parse(JSON.stringify(data));\n}\n\nfunction padLeft(str, len, charStr) {\n\tif (!str)\n\t\tstr = '';\n\telse\n\t\tstr = str + '';\n\treturn new Array(len - str.length + 1).join(charStr || '') + str;\n}\n\nfunction padRight(str, len, charStr) {\n\tif (!str)\n\t\tstr = '';\n\telse\n\t\tstr = str + '';\n\treturn str + new Array(len - str.length + 1).join(charStr || '');\n}\n\n\n// 选项表单处理\nfunction getSelectOptions(str) {\n\tif (!str)\n\t\treturn [];\n\telse if (str.includes('=')) {\n\t\tlet arr = str.split(',');\n\t\tfor (let k = 0; k < arr.length; k++) {\n\t\t\tlet node = arr[k].split('=');\n\t\t\tarr[k] = {};\n\n\t\t\tlet labelArr = node[1].split('|');\n\t\t\tarr[k].label = labelArr[0];\n\t\t\tif (labelArr.length > 1) { //扩展属性\n\t\t\t\tarr[k].ext = labelArr[1];\n\t\t\t}\n\t\t\tarr[k].val = node[0];\n\t\t}\n\t\treturn arr;\n\t} else {\n\t\treturn str.split(',');\n\t}\n}\n\n// 数组元素交换位置 index1和index2分别是两个数组的索引值\nfunction arraySwap(arr, index1, index2) {\n\tarr[index1] = arr.splice(index2, 1, arr[index1])[0];\n\treturn arr;\n}\n\n// 数组置顶\nfunction arrayTop(arr, idx) {\n\tlet node = arr.splice(idx, 1)[0];\n\tarr.unshift(node);\n\treturn arr;\n}\n\n// 数组置底\nfunction arrayBottom(arr, idx) {\n\tlet node = arr.splice(idx, 1)[0];\n\tarr.push(node);\n\treturn arr;\n}\n\n/**\n * 把某个值/对象按key插到某个对象数组\n * @param {*} arr  目标数组\n * @param {*} key  键\n * @param {*} val  判断值\n * @param {*} obj  插入对象{}\n */\nfunction insertObjArrByKey(arr, key, val, obj) {\n\tif (!arr) return arr;\n\n\tfor (let k = 0; k < arr.length; k++) {\n\t\tif (arr[k][key] == val) {\n\t\t\t// 发现存在\n\t\t\tarr[k].list.push(obj);\n\t\t\treturn arr;\n\t\t}\n\t}\n\n\t// 不存在\n\tlet newObj = {\n\t\t[key]: val,\n\t\tlist: [obj]\n\t}\n\tarr.push(newObj);\n\treturn arr;\n}\n\n/**\n * 从对象数组中， 根据某个键值 获取满足的对象\n * @param {*} arr \n * @param {*} key \n * @param {*} val \n */\nfunction getValFromArr(arr, key = 'val', val = '') {\n\tif (!Array.isArray(arr)) return null;\n\tfor (let k = 0; k < arr.length; k++) {\n\t\tif (arr[k][key] == val)\n\t\t\treturn arr[k];\n\t}\n\n\treturn null;\n}\n\n\nmodule.exports = {\n\tarrayTop,\n\tarraySwap,\n\tarrayBottom,\n\n\tfmtTag,\n\n\tgetValFromArr,\n\tgetArrByKey,\n\tgetArrByKeyMulti, //提取对象数组的多个属性数组\n\tspArr, //拆分一维数组为二维\n\tgetDataByKey,\n\tstr2Arr,\n\tarr2ObjectArr,\n\tinsertObjArrByKey,\n\tarrAddDel,\n\tobjArrSortAsc,\n\tobjArrSortDesc,\n\n\tarrAddDel,\n\tisNumber,\n\n\tpadLeft,\n\tpadRight,\n\n\tgenRandomString, // 随机字符串\n\tgenRandomAlpha,\n\tgenRandomNum, // 随机数字 \n\tfmtText, // 文本内容格式化处理\n\tfmtMoney, //金额格式化\n\n\ttoHump,\n\ttoLine,\n\n\tgetSelectOptions, //选项表单处理\n\n\tdeepClone\n\n}"
  },
  {
    "path": "miniprogram/helper/file_helper.js",
    "content": "/**\n * Notes: 文件处理相关函数\n * Ver : CCMiniCloud Framework 2.7.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-02-05 04:00:00 \n */\nconst pageHelper = require('./page_helper.js');\nconst timeHelper = require('./time_helper.js');\n\nfunction openDoc(name, url, ext = '.xlsx') {\n\n\twx.showLoading({\n\t\ttitle: '文件下载中',\n\t});\n\n\twx.downloadFile({\n\t\turl,\n\t\t//fileID:' ',\n\t\tfilePath: wx.env.USER_DATA_PATH + '/' + name + timeHelper.time('YMDhms') + ext,\n\t\tsuccess: function (res) {\n\t\t\twx.hideLoading();\n\t\t\tif (res.statusCode != 200)\n\t\t\t\treturn pageHelper.showModal('打开文件失败，请重试或者采取别的下载方式');\n\n\t\t\tconst filePath = res.filePath;\n\t\t\twx.openDocument({\n\t\t\t\tshowMenu: true,\n\t\t\t\tfilePath: filePath,\n\t\t\t\tsuccess: function (res) {\n\t\t\t\t\tconsole.log('打开文档成功');\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\t\tfail: function (err) {\n\t\t\twx.hideLoading();\n\t\t\tconsole.log(err);\n\t\t\tpageHelper.showModal('打开文件失败，请重试或者采取别的下载方式');\n\t\t}\n\t})\n}\n\nmodule.exports = {\n\topenDoc\n}"
  },
  {
    "path": "miniprogram/helper/form_helper.js",
    "content": " /**\n  * Notes: 表单通用类库\n  * Ver : CCMiniCloud Framework 2.8.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n  * Date: 2021-02-28 07:48:00 \n  */\n\n\n /**\n  * model变表单\n  * @param {*} model \n  */\n function model2Form(model) {\n \tlet newModel = {};\n \tfor (let key in model) {\n \t\tlet arr = key.split('_');\n \t\tlet result = '';\n \t\tfor (let i = 1; i < arr.length; i++) {\n \t\t\tlet name = arr[i].toLowerCase();\n \t\t\tname = name.charAt(0).toUpperCase() + name.slice(1);\n \t\t\tresult = result + name;\n \t\t}\n\n \t\tnewModel['form' + result] = model[key];\n \t}\n \treturn newModel;\n }\n\n // picker表单赋值到页面data\n function setOptions(that, options, name, val) {\n \tlet idx = options.indexOf(val);\n \tidx = (idx < 0) ? 0 : idx;\n \tthat.setData({\n \t\t[name]: idx\n \t})\n }\n\n module.exports = {\n \tmodel2Form,\n \tsetOptions\n }"
  },
  {
    "path": "miniprogram/helper/helper.js",
    "content": " /**\n  * Notes: 通用类库\n  * Ver : CCMiniCloud Framework 2.9.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n  * Date: 2020-11-14 07:48:00 \n  */\n\n /**\n  * 判断变量，参数，对象属性是否定义\n  * @param {*} val \n  */\n function isDefined(val) {\n \t// ==  不能判断是否为null\n \tif (val === undefined)\n \t\treturn false;\n \telse\n \t\treturn true;\n }\n\n /**\n  * 判断对象是否为空\n  * @param {*} obj \n  */\n function isObjectNull(obj) {\n \treturn (Object.keys(obj).length == 0);\n }\n\n\n function sleep(time) {\n \treturn new Promise((resolve) => setTimeout(resolve, time));\n };\n\n\n function formatNumber(n) {\n \tn = n.toString()\n \treturn n[1] ? n : '0' + n\n }\n\n /**\n  * 从picker options中 获取索引值\n  * @param {*} options \n  * [{\n \t\tvalue: 0,\n \t\tlabel: '猎头'\n \t}]\n  * @param {*} val \n  */\n function getOptionsIdx(options, val) {\n \tfor (let i = 0; i < options.length; i++) {\n \t\tif (options[i].value === val)\n \t\t\treturn i;\n \t}\n \treturn 0;\n }\n  \n \n\n module.exports = {\n \tisDefined,\n \tisObjectNull,  \n \tsleep,\n     \n\n \tgetOptionsIdx,    \n \n }"
  },
  {
    "path": "miniprogram/helper/mini_helper.js",
    "content": "/**\n * Notes: 软硬件系统相关函数\n * Ver : CCMiniCloud Framework 2.11.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-01-25 29:00:00 \n */\n\n\nfunction getAuth(auth, authName, callback) {\n\tauth = 'scope.' + auth;\n\twx.getSetting({\n\t\tsuccess: res => {\n\t\t\tconsole.log(res)\n\t\t\tif (res.authSetting[auth]) {\n\t\t\t\tconsole.log('true');\n\t\t\t\tcallback && callback();\n\t\t\t} else if (res.authSetting[auth] === undefined) {\n\t\t\t\t// 未做任何授权\n\t\t\t\twx.showModal({\n\t\t\t\t\ttitle: '提示',\n\t\t\t\t\tmask: true,\n\t\t\t\t\tcontent: '您尚未开启' + authName + '的权限，请点击确定去开启权限！',\n\t\t\t\t\tsuccess: (res) => {\n\t\t\t\t\t\tif (res.confirm) {\n\t\t\t\t\t\t\twx.authorize({\n\t\t\t\t\t\t\t\tscope: auth,\n\t\t\t\t\t\t\t\tsuccess: (res) => {\n\t\t\t\t\t\t\t\t\tconsole.log('授权成功', res);\n\t\t\t\t\t\t\t\t\tcallback && callback();\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tfail: (res) => {\n\t\t\t\t\t\t\t\t\tconsole.log('您没有授权 fail=', res);\n\t\t\t\t\t\t\t\t\twx.showToast({\n\t\t\t\t\t\t\t\t\t\tmask: true,\n\t\t\t\t\t\t\t\t\t\ttitle: '您没有授权，无法' + authName,\n\t\t\t\t\t\t\t\t\t\ticon: 'none'\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\twx.showToast({\n\t\t\t\t\t\t\t\tmask: true,\n\t\t\t\t\t\t\t\ttitle: '您没有授权，无法' + authName,\n\t\t\t\t\t\t\t\ticon: 'none'\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\t// 已经禁止\n\t\t\t\twx.showModal({\n\t\t\t\t\ttitle: '提示',\n\t\t\t\t\tcontent: '您未开启' + authName + '的权限，请点击确定去开启权限！',\n\t\t\t\t\tsuccess: (res) => {\n\t\t\t\t\t\tif (res.confirm) {\n\t\t\t\t\t\t\twx.openSetting({\n\t\t\t\t\t\t\t\tsuccess: (res) => {\n\t\t\t\t\t\t\t\t\twx.showToast({\n\t\t\t\t\t\t\t\t\t\tmask: true,\n\t\t\t\t\t\t\t\t\t\ticon: 'none',\n\t\t\t\t\t\t\t\t\t\ttitle: '正在' + authName,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\tif (res.authSetting[auth]) {\n\t\t\t\t\t\t\t\t\t\tconsole.log('false success res=', res);\n\t\t\t\t\t\t\t\t\t\tcallback && callback();\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\twx.showToast({\n\t\t\t\t\t\t\t\t\t\t\tmask: true,\n\t\t\t\t\t\t\t\t\t\t\ttitle: '您没有授权，无法' + authName + '！',\n\t\t\t\t\t\t\t\t\t\t\ticon: 'none'\n\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tfail: (res) => {\n\t\t\t\t\t\t\t\t\tconsole.log('false file res=', res);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\twx.showToast({\n\t\t\t\t\t\t\t\tmask: true,\n\t\t\t\t\t\t\t\ttitle: '您没有授权，无法' + authName,\n\t\t\t\t\t\t\t\ticon: 'none'\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t});\n}\n\nmodule.exports = {\n\tgetAuth\n}"
  },
  {
    "path": "miniprogram/helper/page_helper.js",
    "content": "/**\n * Notes: 通用页面操作类库\n * Ver : CCMiniCloud Framework 2.0.11 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-11-14 07:48:00 \n */\n\nconst helper = require('./helper.js');\nconst setting = require('../setting/setting.js');\nconst cacheHelper = require('./cache_helper.js');\nconst picHelper = require('./pic_helper.js');\n\n// 加入手机日程 单位秒\nfunction addPhoneCalendar(title, startTime, endTime, alarmOffset = 3600) {\n\twx.addPhoneCalendar({\n\t\ttitle,\n\t\tstartTime,\n\t\tendTime,\n\t\t//\tdescription: \"这是日程内容\", \n\t\talarm: 'true',\n\t\talarmOffset, //提前时间，秒\n\t\tsuccess: () => {\n\t\t\tpageHelper.showSuccToast('添加成功');\n\t\t},\n\t\tfail: (res) => {\n\t\t\tif (res && res.errMsg && res.errMsg.includes('refuesed')) {\n\t\t\t\tpageHelper.showModal('请在手机的\"设置›微信\" 选项中，允许微信访问你的日历', '日历权限未开启')\n\t\t\t}\n\t\t},\n\t\tcomplete: (res) => {\n\t\t\tconsole.log(res)\n\t\t}\n\n\t});\n}\n\n// 自定义导航高度\nfunction getCustomNavHeight() {\n\tlet sysInfo = wx.getSystemInfoSync();\n\tlet menuInfo = wx.getMenuButtonBoundingClientRect();\n\tlet navigationBarHeight = menuInfo.top + menuInfo.bottom - sysInfo.statusBarHeight;\n\treturn navigationBarHeight;\n}\n\nfunction getCurrentPageURL() {\n\tconst pages = getCurrentPages();\n\tconst currentPage = pages[pages.length - 1];\n\tconst url = `/${currentPage.route}`;\n\treturn url;\n}\n\nfunction getCurrentPageUrlWithArgs() {\n\tlet pages = getCurrentPages();\n\tlet currentPage = pages[pages.length - 1];\n\tlet url = currentPage.route;\n\tlet options = currentPage.options;\n\n\tlet urlWithArgs = url + '?';\n\tfor (let key in options) {\n\t\tlet value = options[key];\n\t\turlWithArgs += key + '=' + value + '&';\n\t}\n\turlWithArgs = urlWithArgs.substring(0, urlWithArgs.length - 1);\n\treturn '/' + urlWithArgs;\n}\n\n\nfunction getPID() {\n\tlet route = getCurrentPageURL();\n\n\tlet PID = route.replace('/projects/', '');\n\tPID = PID.split('/')[0];\n\treturn PID;\n}\n\nfunction fmtURLByPID(url, PID = '') {\n\tif (!PID) PID = getPID();\n\tif (url.startsWith('/pages/')) {\n\t\turl = url.replace('/pages/', '/projects/' + PID + '/pages/');\n\t} else {\n\t\turl = '/projects/' + PID + '/' + url;\n\t} \n\treturn url;\n}\n\n/** 定时器销毁 */\nfunction clearTimer(that, timerName = 'timer') {\n\tif (helper.isDefined(that.data[timerName])) {\n\t\tclearInterval(that.data[timerName]);\n\t}\n}\n\n/**\n *  获取父页面\n * @param {*} deep  1=当前 2=父页 3=父父页\n */\nfunction getPrevPage(deep = 2) {\n\tlet pages = getCurrentPages();\n\tlet prevPage = pages[pages.length - deep]; //上一个页面 \n\treturn prevPage;\n}\n\n/**\n * 修改当前/父页面的某个列表节点\n * @param {*} id 主键\n * @param {*} valName 被修改的字段名\n * @param {*} val  被修改的值 \n * @param {*} list   数据集\n * @param {*} idName 主键名\n */\nfunction modifyListNode(id, list, valName, val, idName = '_id') {\n\n\tif (!list || !Array.isArray(list)) return false;\n\tlet pos = list.findIndex(item => item[idName] === id);\n\tif (pos > -1) {\n\t\tlist[pos][valName] = val;\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n/**\n * 修改当前/父页面的某个列表节点(单个值)\n * @param {*} id 主键\n * @param {*} valName 被修改的字段名\n * @param {*} val  被修改的值\n * @param {*} deep  1=当前 2=父页 3=父父页\n * @param {*} listName   数据集名\n * @param {*} idName 主键名\n */\nfunction modifyPrevPageListNode(id, valName, val, deep = 2, listName = 'dataList', idName = '_id') {\n\tlet prevPage = getPrevPage(deep);\n\tif (!prevPage) return;\n\n\tlet dataList = prevPage.data[listName];\n\tif (!dataList) return;\n\n\tlet list = dataList['list'];\n\tif (modifyListNode(id, list, valName, val, idName)) {\n\t\tprevPage.setData({\n\t\t\t[listName + '.list']: list\n\t\t});\n\t}\n}\n\n/**\n * 修改当前/父页面的某个列表节点(一组值)\n * @param {*} id 主键\n * @param {*} valName 被修改的字段名\n * @param {*} val  被修改的值\n * @param {*} deep  1=当前 2=父页 3=父父页\n * @param {*} listName   数据集名\n * @param {*} idName 主键名\n */\nfunction modifyPrevPageListNodeObject(id, vals, deep = 2, listName = 'dataList', idName = '_id') {\n\tlet prevPage = getPrevPage(deep);\n\tif (!prevPage) return;\n\n\tlet dataList = prevPage.data[listName];\n\tif (!dataList) return;\n\n\tlet list = dataList['list'];\n\n\tfor (let key in vals) {\n\t\tmodifyListNode(id, list, key, vals[key], idName)\n\t}\n\n\tprevPage.setData({\n\t\t[listName + '.list']: list\n\t});\n}\n\n/**\n * 从记录数组里删除某个节点\n * @param {*} id \n * @param {*} list \n * @param {*} idName \n */\nfunction delListNode(id, list, idName = '_id') {\n\tif (!list || !Array.isArray(list)) return false;\n\tlet pos = list.findIndex(item => item[idName] === id);\n\tif (pos > -1) {\n\t\tlist.splice(pos, 1);\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n\n/**\n * 删除当前/父页面的某个列表节点\n * @param {*} id 主键\n * @param {*} deep 1=当前 2=父页 3=父父页\n * @param {*} listName  数据集名\n * @param {*} idName  主键名\n */\nfunction delPrevPageListNode(id, deep = 2, listName = 'dataList', idName = '_id') {\n\tlet prevPage = getPrevPage(deep);\n\tlet dataList = prevPage.data[listName];\n\tif (!dataList) return;\n\n\tlet list = dataList['list'];\n\tlet total = dataList['total'] - 1;\n\tif (delListNode(id, list, idName)) {\n\t\tprevPage.setData({\n\t\t\t[listName + '.list']: list,\n\t\t\t[listName + '.total']: total\n\t\t});\n\t}\n\n}\n\n/**\n * 刷新当前/父页面的某个列表节点\n * @param {*} deep  1=当前 2=父页 3=父父页\n * @param {*} listName  数据集名\n * @param {*} listFunc  翻页函数名\n */\nasync function refreshPrevListNode(deep = 2, listName = 'dataList', listFunc = '_getList') {\n\tlet prevPage = getPrevPage(deep);\n\tlet dataList = prevPage.data[listName];\n\tif (!dataList) return;\n\tawait prevPage[listFunc]();\n}\n\n/**\n * 回到顶部测算\n */\nfunction scrollTop(e, that) {\n\tif (e.scrollTop > 100) {\n\t\tthat.setData({\n\t\t\ttopShow: true\n\t\t});\n\t} else {\n\t\tthat.setData({\n\t\t\ttopShow: false\n\t\t});\n\t}\n}\n\n\n/**\n * 删除图片\n * @param {*} that \n * @param {*} idx  被删除图片索引\n * @param {*} imgListName  图片数组名\n */\nfunction delImage(that, idx, imgListName = 'imgList') {\n\tlet callback = function () {\n\t\tthat.data[imgListName].splice(idx, 1);\n\t\tthat.setData({\n\t\t\t[imgListName]: that.data[imgListName]\n\t\t})\n\t}\n\tshowConfirm('确定要删除该图片吗？', callback);\n}\n\n/**\n * 图片预览\n * @param {*} that \n * @param {*} url \n * @param {*} imgListName  图片数组名\n */\nfunction previewImage(that, url, imgListName = 'imgList') {\n\t// 图片预览\n\twx.previewImage({\n\t\turls: that.data[imgListName],\n\t\tcurrent: url\n\t});\n}\n\n/**\n * 取得data-数据 去掉驼峰式命名，改成纯小写式命名\n * @param {*} e \n * @param {*} name \n * @param {*} child  是否获取穿透子元素的data-\n */\nfunction dataset(e, name, child = false) {\n\tif (!child)\n\t\treturn e.currentTarget.dataset[name];\n\telse\n\t\treturn e.target.dataset[name];\n}\n\n// 表单的双向数据绑定 \nfunction model(that, e) {\n\tlet item = e.currentTarget.dataset.item;\n\tthat.setData({\n\t\t[item]: e.detail.value\n\t})\n}\n\n// 表单的开关按钮数据绑定 mode=int/bool\nfunction switchModel(that, e, mode = 'int') {\n\tlet item = e.currentTarget.dataset.item;\n\tlet sel = (e.detail.value) ? 1 : 0;\n\n\tif (mode == 'bool') {\n\t\tsel = (e.detail.value) ? true : false;\n\t}\n\n\tthat.setData({\n\t\t[item]: sel\n\t})\n}\n\n// 无提示成功，同时做后续处理, 最多可显示两行\nfunction showNoneToast(title = '操作完成', duration = 1500, callback) {\n\treturn wx.showToast({\n\t\ttitle: title,\n\t\ticon: 'none',\n\t\tduration: duration,\n\t\tmask: true,\n\t\tsuccess: function () {\n\t\t\tcallback && (setTimeout(() => {\n\t\t\t\tcallback();\n\t\t\t}, duration));\n\t\t}\n\t});\n}\n\n// 无提示成功，返回 \nfunction showNoneToastReturn(title = '操作完成', duration = 2000) {\n\tlet callback = function () {\n\t\twx.navigateBack();\n\t}\n\treturn showNoneToast(title, duration, callback);\n}\n\n// 错误提示成功，同时做后续处理, 最多显示7个汉字长度\nfunction showErrToast(title = '操作失败', duration = 1500, callback) {\n\treturn wx.showToast({\n\t\ttitle: title,\n\t\ticon: 'error',\n\t\tduration: duration,\n\t\tmask: true,\n\t\tsuccess: function () {\n\t\t\tcallback && (setTimeout(() => {\n\t\t\t\tcallback();\n\t\t\t}, duration));\n\t\t}\n\t});\n}\n\n// 加载中，同时做后续处理, 最多显示7个汉字长度\nfunction showLoadingToast(title = '加载中', duration = 1500, callback) {\n\treturn wx.showToast({\n\t\ttitle: title,\n\t\ticon: 'loading',\n\t\tduration: duration,\n\t\tmask: true,\n\t\tsuccess: function () {\n\t\t\tcallback && (setTimeout(() => {\n\t\t\t\tcallback();\n\t\t\t}, duration));\n\t\t}\n\t});\n}\n\n// 提示成功，同时做后续处理, 最多显示7个汉字长度\nfunction showSuccToast(title = '操作成功', duration = 1500, callback) {\n\treturn wx.showToast({\n\t\ttitle: title,\n\t\ticon: 'success',\n\t\tduration: duration,\n\t\tmask: true,\n\t\tsuccess: function () {\n\t\t\tcallback && (setTimeout(() => {\n\t\t\t\tcallback();\n\t\t\t}, duration));\n\t\t}\n\t});\n}\n\n// 提示成功，同时返回\nfunction showSuccToastReturn(title = '操作成功', duration = 1500) {\n\tlet callback = function () {\n\t\twx.navigateBack();\n\t}\n\treturn showSuccToast(title, duration, callback);\n}\n\n// 清理提示焦点\nfunction formClearFocus(that) {\n\tlet data = that.data;\n\tlet focus = {};\n\tfor (let key in data) {\n\t\tif (key.startsWith('form') && !key.endsWith('Focus'))\n\t\t\tfocus[key + 'Focus'] = null;\n\t}\n\tthat.setData({\n\t\t...focus\n\t});\n}\n\n// 焦点提示\nfunction formHint(that, formName, hint) {\n\tthat.setData({\n\t\t[formName + 'Focus']: hint\n\t});\n\treturn showModal(hint);\n}\n\n// 二次确认操作 \nfunction showConfirm(title = '确定要删除吗？', yes, no) {\n\treturn wx.showModal({\n\t\ttitle: '',\n\t\tcontent: title,\n\t\tcancelText: '取消',\n\t\tconfirmText: '确定',\n\t\tsuccess: res => {\n\t\t\tif (res.confirm) {\n\t\t\t\tyes && yes();\n\t\t\t} else if (res.cancel) {\n\t\t\t\tno && no();\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunction showModal(content, title = '温馨提示', callback = null, confirmText = null) {\n\treturn wx.showModal({\n\t\ttitle,\n\t\tcontent: content,\n\t\tconfirmText: confirmText || '确定',\n\t\tshowCancel: false,\n\t\tsuccess(res) {\n\t\t\tcallback && callback();\n\t\t}\n\t});\n}\n\n/**\n * 页面赋值\n * @param {*} that \n * @param {*} data \n */\nfunction setPageData(that, data) {\n\t// 删除页面保留数据\n\tif (helper.isDefined(data['__webviewId__']))\n\t\tdelete data['__webviewId__'];\n\n\tthat.setData(data);\n}\n/**\n * 配合搜索列表响应监听\n * @param {*} that \n */\nfunction commListListener(that, e) {\n\tif (helper.isDefined(e.detail.search))\n\t\tthat.setData({\n\t\t\tsearch: '',\n\t\t\tsortType: '',\n\t\t});\n\telse {\n\t\tthat.setData({\n\t\t\tdataList: e.detail.dataList,\n\t\t});\n\t\tif (e.detail.sortType)\n\t\t\tthat.setData({\n\t\t\t\tsortType: e.detail.sortType,\n\t\t\t});\n\t}\n\n}\n\nfunction bindShowModalTap(e) {\n\tthis.setData({\n\t\tmodalName: e.currentTarget.dataset.modal\n\t})\n}\n\nfunction bindHideModalTap(e) {\n\tthis.setData({\n\t\tmodalName: null\n\t})\n}\n\n\n/**\n * 控制回页首按钮\n * @param {*} e \n */\nfunction showTopBtn(e, that) {\n\tif (e.scrollTop > 100) {\n\t\tthat.setData({\n\t\t\ttopBtnShow: true\n\t\t});\n\t} else {\n\t\tthat.setData({\n\t\t\ttopBtnShow: false\n\t\t});\n\t}\n}\n\n/**\n * 回到顶部\n */\nfunction top() {\n\twx.pageScrollTo({\n\t\tscrollTop: 0\n\t})\n}\n\n// 跳到锚点\nfunction anchor(id, that) {\n\ttry {\n\t\tlet query = wx.createSelectorQuery().in(that);\n\t\tquery.selectViewport().scrollOffset()\n\t\t//#comm 跳转到指定id位置\n\t\tquery.select('#' + id).boundingClientRect();\n\n\t\tquery.exec(function (res) {\n\t\t\tif (!res || res.length != 2 || !res[0] || !res[1]) return;\n\t\t\t//第一个为视图，第二个为当前id\n\n\t\t\tlet miss = res[0].scrollTop + res[1].top - 10;\n\t\t\twx.pageScrollTo({\n\t\t\t\tscrollTop: miss,\n\t\t\t\tduration: 300\n\t\t\t});\n\t\t});\n\t}\n\tcatch (err) {\n\t\tconsole.error(err);\n\t}\n}\n\n// 页面跳转/图片预览 \nfunction url(e, that) {\n\tlet url = e.currentTarget.dataset.url;\n\tlet type = e.currentTarget.dataset.type;\n\tif (!type) type = 'url';\n\n\tswitch (type) {\n\t\tcase 'picker': {\n\t\t\t//picker 选择trigger \t\n\t\t\tlet item = e.currentTarget.dataset.item;\n\t\t\tthat.setData({\n\t\t\t\t[item]: e.detail\n\t\t\t})\n\t\t\tbreak;\n\t\t}\n\t\tcase 'top': {\n\t\t\ttop();\n\t\t\tbreak;\n\t\t}\n\t\tcase 'mini': {\n\t\t\twx.navigateToMiniProgram({\n\t\t\t\tappId: e.currentTarget.dataset.app,\n\t\t\t\tpath: url,\n\t\t\t\tenvVersion: 'release'\n\t\t\t});\n\t\t\tbreak;\n\t\t}\n\t\tcase 'redirect': {\n\t\t\tif (!url) return;\n\t\t\twx.redirectTo({\n\t\t\t\turl\n\t\t\t});\n\t\t\tbreak;\n\t\t}\n\t\tcase 'reLaunch':\n\t\tcase 'relaunch': {\n\t\t\tif (!url) return;\n\t\t\twx.reLaunch({\n\t\t\t\turl\n\t\t\t})\n\t\t\tbreak;\n\t\t}\n\t\tcase 'copy': {\n\t\t\twx.setClipboardData({\n\t\t\t\tdata: url,\n\t\t\t\tsuccess(res) {\n\t\t\t\t\twx.getClipboardData({\n\t\t\t\t\t\tsuccess(res) {\n\t\t\t\t\t\t\tshowNoneToast('已复制到剪贴板');\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t});\n\t\t\tbreak;\n\t\t}\n\t\tcase 'hint': {\n\t\t\tif (!url) return;\n\t\t\tshowModal(url);\n\t\t\tbreak;\n\t\t}\n\t\tcase 'switch': {\n\t\t\tif (!url) return;\n\t\t\twx.switchTab({\n\t\t\t\turl\n\t\t\t});\n\t\t\tbreak;\n\t\t}\n\t\tcase 'back': {\n\t\t\twx.navigateBack();\n\t\t\tbreak;\n\t\t}\n\t\tcase 'toURL': {\n\t\t\ttoURL(url);\n\t\t\tbreak;\n\t\t}\n\t\tcase 'phone': {\n\t\t\twx.makePhoneCall({\n\t\t\t\tphoneNumber: url\n\t\t\t});\n\t\t\tbreak;\n\t\t}\n\t\tcase 'anchor': {\n\t\t\tanchor(url, that);\n\t\t\tbreak;\n\t\t}\n\t\tcase 'saveimg':\n\t\tcase 'saveimage': {\n\t\t\tlet callback = function () {\n\t\t\t\twx.saveImageToPhotosAlbum({ //成功之后保存到本地 \n\t\t\t\t\tfilePath: url, //生成的图片的本地路径\n\t\t\t\t\tsuccess: function (res) {\n\t\t\t\t\t\twx.showToast({\n\t\t\t\t\t\t\ttitle: e.currentTarget.dataset.hint || '保存成功',\n\t\t\t\t\t\t\ticon: 'none',\n\t\t\t\t\t\t\tduration: 2000\n\t\t\t\t\t\t})\n\t\t\t\t\t},\n\t\t\t\t\tfail: function (err) {\n\t\t\t\t\t\tconsole.log(err);\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tpicHelper.getWritePhotosAlbum(callback);\n\t\t\tbreak;\n\t\t}\n\t\tcase 'bool': //正反 \n\t\t\t{\n\t\t\t\tthat.setData({\n\t\t\t\t\t[url]: !that.data[url]\n\t\t\t\t})\n\t\t\t\tbreak;\n\t\t\t}\n\t\tcase 'img':\n\t\tcase 'image': {\n\t\t\tif (url.indexOf('qlogo') > -1) { //微信大图\n\t\t\t\turl = url.replace('/132', '/0');\n\t\t\t}\n\t\t\tlet urls = [url];\n\n\t\t\tif (helper.isDefined(e.currentTarget.dataset.imgs))\n\t\t\t\turls = e.currentTarget.dataset.imgs;\n\n\t\t\twx.previewImage({\n\t\t\t\tcurrent: url, // 当前显示图片的http链接\n\t\t\t\turls\n\t\t\t})\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tif (!url) return;\n\t\t\twx.navigateTo({\n\t\t\t\turl\n\t\t\t})\n\n\t}\n\n}\n\nfunction getOptions(that, options, idName = 'id') {\n\tlet id = options[idName];\n\n\tif (!id) id = options['scene']; // 二维码扫入\n\n\tif (!id) return false;\n\n\tthat.setData({\n\t\t[idName]: id\n\t});\n\treturn true;\n\n}\n\n// 页面提示\nfunction hint(msg, type = 'redirect') {\n\tif (type == 'reLaunch')\n\t\twx.reLaunch({\n\t\t\turl: fmtURLByPID('/pages/public/hint?type=9&msg=' + encodeURIComponent(msg)),\n\t\t});\n\telse\n\t\twx.redirectTo({\n\t\t\turl: fmtURLByPID('/pages/public/hint?type=9&msg=' + encodeURIComponent(msg)),\n\t\t});\n}\n\n\n// 跳转操作，找到页面中的目标，出栈后面的 delta=1为上一页面\nfunction toURL(url) {\n\tlet pages = getCurrentPages();\n\tfor (let k = 0; k < pages.length; k++) {\n\t\tif (pages[k].route.includes(url)) {\n\t\t\twx.navigateBack({\n\t\t\t\tdelta: pages.length - k - 1\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t}\n\n\twx.redirectTo({\n\t\turl,\n\t});\n\n}\n\n/** ListTouch触摸开始 */\nfunction listTouchStart(e, that) {\n\tthat.setData({\n\t\ttouchX: e.touches[0].pageX\n\t})\n}\n\n/** ListTouch计算方向 */\nfunction listTouchMove(e, that, precision = 50) {\n\tif (that.data.touchX - e.touches[0].pageX > precision) {\n\t\tthat.setData({\n\t\t\ttouchDirection: 'left'\n\t\t});\n\t} else if (that.data.touchX - e.touches[0].pageX < -precision) {\n\t\tthat.setData({\n\t\t\ttouchDirection: 'right'\n\t\t});\n\t}\n\n}\n\n/** ListTouch计算滚动 */\nfunction listTouchEnd(e, that) {\n\tif (that.data.touchDirection == 'left') {\n\t\tthat.setData({\n\t\t\ttouchCur: e.currentTarget.dataset.idx\n\t\t})\n\t} else {\n\t\tthat.setData({\n\t\t\ttouchCur: null\n\t\t})\n\t}\n\n\tthat.setData({\n\t\ttouchDirection: null\n\t});\n}\n\n\n\n/**\n * 多条件复合查询条件\n * @param {*} e \n * @param {*} key 查询键值\n * @param {*} val  查询值\n * @param {*} def  键值的数据类型(int,str,float)\n */\nfunction queryMulti(that, e, key, val, def) {\n\tkey = helper.isDefined(key) ? key : dataset(e, 'key');\n\tval = helper.isDefined(val) ? val : dataset(e, 'val');\n\tdef = helper.isDefined(def) ? def : dataset(e, 'def');\n\n\t// 类型转换\n\tif (def == 'int') {\n\t\tval = parseInt(val);\n\t} else if (def == 'float') {\n\t\tval = parseFloat(val);\n\t} else if (def == 'str') {\n\t\tval = val.toString();\n\t}\n\n\tlet _params = that.data._params;\n\t_params.query[key] = val;\n\tthat.setData({\n\t\t_params\n\t})\n}\n\n/**\n * 页面缓存\n * @param {*} key  \n * @param {*} that \n * @param {*} listKey  数据项KEY\n */\nfunction cacheListExist(key, that, listKey = 'list') {\n\tkey = key.toUpperCase();\n\tif (setting.CACHE_IS_LIST)\n\t\treturn cacheHelper.get(key + '_LIST') && that.data && that.data[listKey];\n\telse\n\t\treturn false;\n}\n\nfunction cacheListRemove(key) {\n\tkey = key.toUpperCase();\n\tif (setting.CACHE_IS_LIST)\n\t\tcacheHelper.remove(key + '_LIST');\n}\n\nfunction cacheListSet(key, time = setting.CACHE_LIST_TIME) {\n\tkey = key.toUpperCase();\n\tif (setting.CACHE_IS_LIST)\n\t\tcacheHelper.set(key + '_LIST', 'TRUE', time);\n}\n\n\nmodule.exports = {\n\taddPhoneCalendar,\n\n\tgetCustomNavHeight,\n\n\tgetPID,\n\tgetCurrentPageURL,\n\tgetCurrentPageUrlWithArgs,\n\tfmtURLByPID,\n\n\t//### form\n\tformClearFocus,\n\tformHint,\n\n\t//### \n\tdataset, //节点数据data-\n\n\t//### 节点操作\n\tgetPrevPage,\n\tmodifyListNode,\n\tmodifyPrevPageListNode, //单个\n\tmodifyPrevPageListNodeObject, //一组\n\tdelListNode,\n\tdelPrevPageListNode,\n\trefreshPrevListNode,\n\n\tscrollTop, //### 回顶部\n\n\t// ### 图片 \n\tpreviewImage,\n\tdelImage,\n\n\t//## 提示窗口\n\tshowSuccToastReturn,\n\tshowSuccToast,\n\tshowErrToast,\n\tshowNoneToast,\n\tshowNoneToastReturn,\n\tshowLoadingToast,\n\tshowConfirm,\n\tshowModal,\n\tsetPageData,\n\n\thint, //单独提示页\n\n\tcommListListener, //组件监听\n\n\tbindShowModalTap,\n\tbindHideModalTap,\n\tshowTopBtn,\n\n\tgetOptions, //获取id或者其他参数\n\n\tmodel, // 双向数据绑定\n\tswitchModel, //开关控件数据绑定\n\n\ttop, // 回顶部事件\n\turl, // 跳转事件\n\tanchor, //锚点跳转事件  \n\n\ttoURL, //跳转操作\n\n\t//### 列表横向滑动\n\tlistTouchStart,\n\tlistTouchMove,\n\tlistTouchEnd,\n\n\t//### 多条件复合查询\n\tqueryMulti,\n\n\tclearTimer, //定时器销毁\n\n\t//LIST数据缓存\n\tcacheListExist,\n\tcacheListRemove,\n\tcacheListSet,\n\n}"
  },
  {
    "path": "miniprogram/helper/pic_helper.js",
    "content": "/**\n * Notes: 图片处理相关函数\n * Ver : CCMiniCloud Framework 2.0.13 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-10-25 04:00:00 \n */\n\n\nfunction getWritePhotosAlbum(callback) {\n\twx.getSetting({\n\t\tsuccess: res => {\n\t\t\tconsole.log('res=', res);\n\t\t\tif (res.authSetting['scope.writePhotosAlbum']) {\n\t\t\t\tconsole.log('true');\n\t\t\t\tcallback && callback();\n\t\t\t} else if (res.authSetting['scope.writePhotosAlbum'] === undefined) {\n\t\t\t\twx.showModal({\n\t\t\t\t\ttitle: '提示',\n\t\t\t\t\tcontent: '您未开启保存图片到相册的权限，请点击确定去开启权限！',\n\t\t\t\t\tsuccess: (res) => {\n\t\t\t\t\t\tif (res.confirm) {\n\t\t\t\t\t\t\twx.authorize({\n\t\t\t\t\t\t\t\tscope: 'scope.writePhotosAlbum',\n\t\t\t\t\t\t\t\tsuccess: (res) => {\n\t\t\t\t\t\t\t\t\tcallback && callback()\n\t\t\t\t\t\t\t\t\tconsole.log('授权下载成功', res);\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tfail: (res) => {\n\t\t\t\t\t\t\t\t\tconsole.log('您没有授权 fail=', res);\n\t\t\t\t\t\t\t\t\twx.showToast({\n\t\t\t\t\t\t\t\t\t\ttitle: '您没有授权，无法保存到相册',\n\t\t\t\t\t\t\t\t\t\ticon: 'none'\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconsole.log('取消了');\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\twx.showModal({\n\t\t\t\t\ttitle: '提示',\n\t\t\t\t\tcontent: '您未开启保存图片到相册的权限，请点击确定去开启权限！',\n\t\t\t\t\tsuccess: (res) => {\n\t\t\t\t\t\tif (res.confirm) {\n\t\t\t\t\t\t\twx.openSetting({\n\t\t\t\t\t\t\t\tsuccess: (res) => {\n\t\t\t\t\t\t\t\t\twx.showToast({\n\t\t\t\t\t\t\t\t\t\ticon: 'none',\n\t\t\t\t\t\t\t\t\t\ttitle: '正在保存图片',\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\tif (res.authSetting['scope.writePhotosAlbum']) {\n\t\t\t\t\t\t\t\t\t\tconsole.log('false success res=', res);\n\t\t\t\t\t\t\t\t\t\tcallback && callback();\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\twx.showToast({\n\t\t\t\t\t\t\t\t\t\t\ttitle: '您没有授权，无法保存到相册！',\n\t\t\t\t\t\t\t\t\t\t\ticon: 'none'\n\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tfail: (res) => {\n\t\t\t\t\t\t\t\t\tconsole.log('false file res=', res);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\twx.showToast({\n\t\t\t\t\t\t\t\ttitle: '您没有授权，无法保存到相册',\n\t\t\t\t\t\t\t\ticon: 'none'\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t});\n}\n\nmodule.exports = {\n\tgetWritePhotosAlbum\n}"
  },
  {
    "path": "miniprogram/helper/time_helper.js",
    "content": "/**\n * Notes: 时间相关函数\n * Ver : CCMiniCloud Framework 2.0.14 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-09-05 04:00:00 \n */\n\nconst util = require('./helper.js');\n\n\n/** 日期简化，去掉多余的前缀0 */\nfunction simpleDate(date) {\n\tlet arr = date.split('-');\n\tif (arr.length < 3) return date;\n\tlet month = arr[1];\n\tif (month.indexOf('0') == 0)\n\t\tmonth = month.replace('0', '');\n\n\tlet day = arr[2];\n\tif (day.indexOf('0') == 0)\n\t\tday = day.replace('0', '');\n\n\treturn arr[0] + '-' + month + '-' + day;\n}\n\n/** 时间格式化为年月日点分 */\nfunction fmtDateCHN(date, fmt = 'Y-M-D') {\n\tif (!date) return '';\n\tif (fmt == 'hh:mm' && date.includes(':')) {\n\t\tif (date.includes(' ')) date = date.split(' ')[1];\n\t\tlet arr = date.split(':');\n\t\treturn Number(arr[0]) + '点' + arr[1] + '分';\n\t} else if (fmt == 'Y-M-D hh:mm') {\n\t\tlet arr = date.split(' ');\n\t\tif (arr.length != 2) return date;\n\t\treturn fmtDateCHN(arr[0], 'Y-M-D') + fmtDateCHN(arr[1], 'hh:mm');\n\t} else if (fmt == 'M-D hh:mm') {\n\t\tlet arr = date.split(' ');\n\t\tif (arr.length != 2) return date;\n\t\treturn fmtDateCHN(arr[0], 'M-D') + ' ' + fmtDateCHN(arr[1], 'hh:mm');\n\t} else {\n\t\tif (date.includes(' ')) date = date.split(' ')[0];\n\n\t\tlet arr = date.split('-');\n\t\tif (fmt == 'Y-M') //年月\n\t\t\treturn arr[0] + '年' + Number(arr[1]) + '月';\n\t\telse if (fmt == 'M-D') //月日\n\t\t\treturn arr[1] + '月' + Number(arr[2]) + '日';\n\t\telse if (fmt == 'Y') //年\n\t\t\treturn arr[0] + '年';\n\t\telse\n\t\t\treturn arr[0] + '年' + Number(arr[1]) + '月' + Number(arr[2]) + '日';\n\t}\n\n\n}\n\n/**\n * 毫秒时间戳转时间格式\n * @param {*} unixtime  毫秒\n * @param {*} format  Y-M-D h:m:s\n * @param {*} diff  时区差异 毫秒\n */\nfunction timestamp2Time(unixtime, format = 'Y-M-D h:m:s', diff = 0) {\n\tlet formateArr = ['Y', 'M', 'D', 'h', 'm', 's'];\n\tlet returnArr = [];\n\tlet date = new Date(unixtime + diff);\n\treturnArr.push(date.getFullYear());\n\treturnArr.push(formatNumber(date.getMonth() + 1));\n\treturnArr.push(formatNumber(date.getDate()));\n\treturnArr.push(formatNumber(date.getHours()));\n\treturnArr.push(formatNumber(date.getMinutes()));\n\treturnArr.push(formatNumber(date.getSeconds()));\n\tfor (let i in returnArr) {\n\t\tformat = format.replace(formateArr[i], returnArr[i]);\n\t}\n\treturn format;\n}\n\n\nfunction timestame2Ago(dateTimeStamp, fmt = 'Y-M-D', diff = 0) { //dateTimeStamp是一个时间毫秒，注意时间戳是秒的形式，在这个毫秒的基础上除以1000，就是十位数的时间戳。13位数的都是时间毫秒。\n\tlet minute = 1000 * 60; //把分，时，天，周，半个月，一个月用毫秒表示\n\tlet hour = minute * 60;\n\tlet day = hour * 24;\n\tlet week = day * 7;\n\tlet month = day * 30;\n\tlet now = new Date().getTime(); //获取当前时间毫秒\n\n\tlet diffValue = now - dateTimeStamp; //时间差\n\n\tif (diffValue < 0) {\n\t\treturn;\n\t}\n\tlet minC = diffValue / minute; //计算时间差的分，时，天，周，月\n\tlet hourC = diffValue / hour;\n\tlet dayC = diffValue / day;\n\n\tlet result = '';\n\n\tlet weekC = diffValue / week;\n\tlet monthC = diffValue / month;\n\tif (monthC >= 1 && monthC <= 3) {\n\t\tresult = ' ' + parseInt(monthC) + '月前'\n\t} else if (weekC >= 1 && weekC <= 3) {\n\t\tresult = ' ' + parseInt(weekC) + '周前'\n\t} else if (dayC >= 1 && dayC <= 6) {\n\t\tresult = ' ' + parseInt(dayC) + '天前'\n\t} else if (hourC >= 1 && hourC <= 23) {\n\t\tresult = ' ' + parseInt(hourC) + '小时前'\n\t} else if (minC >= 1 && minC <= 59) {\n\t\tresult = ' ' + parseInt(minC) + '分钟前'\n\t} else if (diffValue >= 0 && diffValue <= minute) {\n\t\tresult = '刚刚'\n\t} else {\n\t\tresult = timestamp2Time(dateTimeStamp, fmt, diff);\n\n\t}\n\treturn result;\n}\n\nfunction formatNumber(n) {\n\tn = n.toString()\n\treturn n[1] ? n : '0' + n\n}\n\n\n/**\n * 时间转时间戳 \n * @param {*} date  支持 Y-M-D h:m:s / Y-M-D\n */\nfunction time2Timestamp(date) {\n\tif (date.length < 10) {\n\t\tlet arr = date.split('-');\n\t\tif (arr[1].length == 1) arr[1] = '0' + arr[1];\n\t\tif (arr[2].length == 1) arr[2] = '0' + arr[2];\n\t\tdate = arr[0] + '-' + arr[1] + '-' + arr[2];\n\t}\n\tif (date.length == 10) date = date + ' 00:00:00';\n\tlet d = new Date(date.replace(/-/g, '/'));\n\treturn d.getTime();\n}\n\n/**\n *  获取当前时间戳/时间Y-M-D h:m:s\n * @param {*} 时间格式 Y-M-D h:m:s\n * @param {int} 时间步长 (秒)\n */\nfunction time(fmt, step = 0) {\n\tlet t = 0;\n\tif (util.isDefined(fmt)) {\n\t\tlet t = new Date().getTime() + step * 1000;\n\t\treturn timestamp2Time(t, fmt);\n\t}\n\treturn new Date().getTime() + t * 1000;\n}\n\n// 获取某天0点\nfunction getDayFirstTimestamp(timestamp) {\n\tif (!timestamp) timestamp = time();\n\treturn time2Timestamp(timestamp2Time(timestamp, 'Y-M-D'));\n}\n\n/**\n * 根据出生日期计算年龄周岁 传参格式为1996-06-08\n * @param {*} birth \n */\nfunction getAge(birth, isMonth = false) {\n\tvar returnAge = '';\n\tvar mouthAge = '';\n\tvar arr = birth.split('-');\n\tvar birthYear = arr[0];\n\tvar birthMonth = arr[1];\n\tvar birthDay = arr[2];\n\tvar d = new Date();\n\tvar nowYear = d.getFullYear();\n\tvar nowMonth = d.getMonth() + 1;\n\tvar nowDay = d.getDate();\n\tif (nowYear == birthYear) {\n\t\t// returnAge = 0; //同年 则为0岁\n\t\tvar monthDiff = nowMonth - birthMonth; //月之差 \n\t\tif (monthDiff < 0) { } else {\n\t\t\tmouthAge = monthDiff + '个月';\n\t\t}\n\t} else {\n\t\tvar ageDiff = nowYear - birthYear; //年之差\n\t\tif (ageDiff > 0) {\n\t\t\tif (nowMonth == birthMonth) {\n\t\t\t\tvar dayDiff = nowDay - birthDay; //日之差 \n\t\t\t\tif (dayDiff < 0) {\n\t\t\t\t\treturnAge = ageDiff - 1 + '岁';\n\t\t\t\t} else {\n\t\t\t\t\treturnAge = ageDiff + '岁';\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tvar monthDiff = nowMonth - birthMonth; //月之差 \n\t\t\t\tif (monthDiff < 0) {\n\t\t\t\t\treturnAge = ageDiff - 1 + '岁';\n\t\t\t\t} else {\n\t\t\t\t\tmouthAge = monthDiff + '个月';\n\t\t\t\t\treturnAge = ageDiff + '岁';\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\treturnAge = -1; //返回-1 表示出生日期输入错误 晚于今天\n\t\t}\n\t}\n\tif (isMonth)\n\t\treturn returnAge + mouthAge; //返回周岁年龄+月份\n\telse\n\t\treturn returnAge;\n}\n\n/**\n * 日期计算周几\n * @param {*} day  日期为输入日期，格式为 2013-03-10\n */\nfunction week(day) {\n\tlet arys1 = new Array();\n\tarys1 = day.split('-');\n\tlet ssdate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]);\n\tlet week1 = String(ssdate.getDay()).replace(\"0\", \"日\").replace(\"1\", \"一\").replace(\"2\", \"二\").replace(\"3\", \"三\").replace(\"4\", \"四\").replace(\"5\", \"五\").replace(\"6\", \"六\") //就是你要的星期几\n\treturn \"周\" + week1; //就是你要的星期几 \n}\n\n/** 获取某天所在某月第一天时间戳 */\nfunction getMonthFirstTimestamp(timestamp) {\n\tlet inDate = new Date(timestamp);\n\tlet year = inDate.getFullYear();\n\tlet month = inDate.getMonth();\n\treturn new Date(year, month, 1).getTime();\n}\n\n/** 获取某天所在某月最后一天时间戳 */\nfunction getMonthLastTimestamp(timestamp) {\n\tlet inDate = new Date(timestamp);\n\tlet year = inDate.getFullYear();\n\tlet month = inDate.getMonth();\n\treturn new Date(year, month + 1, 1).getTime() - 1;\n}\n\n// 取得分钟时间戳\nfunction getNowMinTimestamp() {\n\tlet min = time('Y-M-D h:m') + ':00';\n\tlet timestamp = time2Timestamp(min);\n\treturn {\n\t\tmin,\n\t\ttimestamp\n\t}\n}\n\n\n// 获取当前日期所在周一 输入和返回格式=yyyy-mm-dd\nfunction getFirstOfWeek(date) {\n\tlet now = new Date(date);\n\tlet nowTime = now.getTime();\n\tlet day = now.getDay();\n\tif (day == 0) day = 7;\n\tlet oneDayTime = 24 * 60 * 60 * 1000;\n\tlet mondayTime = nowTime - (day - 1) * oneDayTime;\n\treturn timestamp2Time(mondayTime, 'Y-M-D');\n}\n\n// 获取当前日期所在周一 输入和返回格式=yyyy-mm-dd\nfunction getLastOfWeek(date) {\n\tlet now = new Date(date);\n\tlet nowTime = now.getTime();\n\tlet day = now.getDay();\n\tif (day == 0) day = 7;\n\tlet oneDayTime = 24 * 60 * 60 * 1000;\n\tlet sundayTime = nowTime + (7 - day) * oneDayTime;\n\treturn timestamp2Time(sundayTime, 'Y-M-D');\n}\n\n// 获取当前日期所在月第一天 输入和返回格式=yyyy-mm-dd\nfunction getFirstOfMonth(date) {\n\tlet arr = date.split('-');\n\treturn arr[0] + '-' + arr[1] + '-01';\n}\n\n// 获取当前日期所在月最后一天 输入和返回格式=yyyy-mm-dd\nfunction getLastOfMonth(date) {\n\tlet now = new Date(date);\n\tlet y = now.getFullYear();\n\tlet m = now.getMonth();\n\tlet lastDay = new Date(y, m + 1, 0).getTime();\n\treturn timestamp2Time(lastDay, 'Y-M-D');\n}\n\n/**\n * 取倒计时（天时分秒） 支持时间戳或者Y-M-D/Y-M-D h:m:s\n * @param {*} datetimeTo \n * @param {*} flag 1=正 -1=负\n */\nfunction getTimeLeft(datetimeTo, flag = 1) {\n\tlet time1 = datetimeTo;\n\n\tif (String(datetimeTo).includes('-')) {\n\t\tdatetimeTo = String(datetimeTo);\n\t\tif (!datetimeTo.includes(':'))\n\t\t\tdatetimeTo += ' 00:00:00';\n\t\ttime1 = new Date(datetimeTo).getTime();\n\t}\n\n\tlet time2 = new Date().getTime();\n\tlet mss = time1 - time2;\n\n\t// 将时间差（毫秒）格式为：天时分秒\n\tlet days = parseInt(mss / (1000 * 60 * 60 * 24));\n\tlet hours = parseInt((mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));\n\tlet minutes = parseInt((mss % (1000 * 60 * 60)) / (1000 * 60));\n\tlet seconds = parseInt((mss % (1000 * 60)) / 1000);\n\n\treturn [flag * days, flag * hours, flag * minutes, flag * seconds];\n\n}\n\n\nmodule.exports = {\n\tfmtDateCHN,\n\tsimpleDate,\n\n\tgetTimeLeft,\n\n\tgetNowMinTimestamp,\n\n\tgetMonthFirstTimestamp,\n\tgetMonthLastTimestamp,\n\n\tgetDayFirstTimestamp,\n\n\ttimestamp2Time,\n\ttimestame2Ago,\n\ttime2Timestamp,\n\ttime,\n\tgetAge,\n\tweek, //星期\n\n\tgetFirstOfWeek,\n\tgetLastOfWeek,\n\tgetFirstOfMonth,\n\tgetLastOfMonth\n}"
  },
  {
    "path": "miniprogram/helper/validate.js",
    "content": " /**\n  * Notes: 数据校验类库\n  * Ver : CCMiniCloud Framework 2.0.15 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n  * Date: 2021-01-07 07:48:00 \n  *  \n  */\n const pageHelper = require('./page_helper.js');\n\n const CHECK_OPEN = true;\n const CHECK_SOURCE = 'client'; //client/admin \n\n /**\n  * 判断变量，参数，对象属性是否定义\n  * @param {*} val \n  */\n function isDefined(val) {\n \t// ==  不能判断是否为null\n \tif (val === undefined)\n \t\treturn false;\n \telse\n \t\treturn true;\n }\n\n function isNull(value) {\n \tif (value === null || value === undefined) return true;\n \tif (getDataType(value) == String && value === '') return true;\n \treturn false;\n }\n\n function isStrAndArrNull(value) {\n \tif (value === null || value === undefined) return true;\n\n \tlet type = getDataType(value);\n \tif (type == String && value === '') return true;\n \tif (type == Array && value.length == 0) return true;\n\n \treturn false;\n }\n\n function isRealNull(value) {\n \tif (value === null || value === undefined) return true;\n\n \tlet type = getDataType(value);\n \tif (type == String && value === '') return true;\n \tif (type == Array && value.length == 0) return true;\n \tif (type == Object && JSON.stringify(value) == '{}') return true;\n\n \treturn false;\n }\n\n function getDataType(value) {\n \tif (value === null || value === undefined) return value;\n \treturn value.constructor;\n }\n\n // 是否必填\n function checkRequired(value, desc = '') {\n \tswitch (getDataType(value)) {\n \t\tcase Object:\n \t\t\tif (JSON.stringify(value) == '{}')\n \t\t\t\treturn desc + '不能为空obj';\n \t\t\tbreak;\n \t\tcase Array:\n \t\t\tif (value.length == 0)\n \t\t\t\treturn desc + '不能为空arr';\n \t\t\tbreak;\n \t\tcase String:\n \t\t\tif (value.length == 0)\n \t\t\t\treturn desc + '不能为空';\n \t\t\tbreak;\n \t\tcase null:\n \t\tcase undefined:\n \t\t\treturn desc + '不能为空';\n \t}\n }\n\n // 校验字符/数组长度，校验数字大小\n function checkMin(value, min, desc = '') {\n \tif (isStrAndArrNull(value)) return;\n\n \tmin = Number(min);\n \tswitch (getDataType(value)) {\n \t\tcase Array:\n \t\t\tif (value.length < min)\n \t\t\t\treturn desc + '不能少于' + min + '项';\n \t\t\tbreak;\n \t\tcase String:\n \t\t\tif (value.length < min)\n \t\t\t\treturn desc + '不能少于' + min + '位';\n \t\t\tbreak;\n \t\tcase Number:\n \t\t\tif (value < min)\n \t\t\t\treturn desc + '不能小于' + min;\n \t\t\tbreak;\n \t}\n };\n\n // 校验字符/数组长度，校验数字大小\n function checkMax(value, max, desc = '') {\n \tif (isStrAndArrNull(value)) return;\n\n \tmax = Number(max);\n \tswitch (getDataType(value)) {\n \t\tcase Array:\n \t\t\tif (value.length > max)\n \t\t\t\treturn desc + '不能多于' + max + '项';\n \t\t\tbreak;\n \t\tcase String:\n \t\t\tif (value.length > max)\n \t\t\t\treturn desc + '不能多于' + max + '位';\n \t\t\tbreak;\n \t\tcase Number:\n \t\t\tif (value > max)\n \t\t\t\treturn desc + '不能大于' + max;\n \t\t\tbreak;\n \t}\n };\n\n // 校验字符/数组长度 \n function checkLen(value, len, desc = '') {\n \tif (isStrAndArrNull(value)) return;\n\n \tlen = Number(len);\n \tswitch (getDataType(value)) {\n \t\tcase Array:\n \t\t\tif (value.length != len)\n \t\t\t\treturn desc + '必须为' + len + '项';\n \t\t\tbreak;\n \t\tcase String:\n \t\t\tif (value.length != len)\n \t\t\t\treturn desc + '必须为' + len + '位';\n \t\t\tbreak;\n \t}\n };\n\n function checkMobile(value, desc = '') {\n \tif (isNull(value)) return;\n\n \tif (!/(^1[1|2|3|4|5|6|7|8|9][0-9]{9}$)/.test(value))\n \t\treturn desc + '格式不正确';\n }\n\n function checkInt(value, desc = '') {\n \tif (isNull(value)) return;\n\n \tif (!/^[0-9]+$/.test(value))\n \t\treturn desc + '必须为数字';\n }\n\n function checkDigit(value, desc = '') {\n \tif (isNull(value)) return;\n\n \tif (!/^\\d+(\\.\\d+)?$/.test(value))\n \t\treturn desc + '必须为数字或小数';\n }\n\n function checkLetter(value, desc = '') {\n \tif (isNull(value)) return;\n\n \tif (!/^[A-Za-z]+$/.test(value))\n \t\treturn desc + '必须为字母';\n }\n\n function checkMoney(value, desc = '') {\n \tif (isNull(value)) return;\n\n \tif (!/(^[1-9]([0-9]+)?(\\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\\.[0-9]([0-9])?$)/.test(value))\n \t\treturn desc + '必须为金额格式，例如2.00';\n }\n\n\n function checkLetterNum(value, desc = '') {\n \tif (isNull(value)) return;\n\n \tif (!/^\\w+$/.test(value))\n \t\treturn desc + '必须为字母，数字和下划线';\n }\n\n function checkId(value, desc = '', min = 1, max = 100) {\n \tif (isNull(value)) return;\n\n \tmin = Number(min);\n \tmax = Number(max);\n\n \tif (getDataType(value) != String) return desc + '必须为ID字符串格式';\n\n \tif (value.length < min || value.length > max) return desc + '必须为ID格式';\n\t/*if (!/^\\w+$/.test(value))\n\t\treturn desc + '必须为ID格式';*/\n }\n\n //  邮箱\n function checkEmail(value, desc = '') {\n \tif (isNull(value)) return;\n\n \tlet reg = /^[A-Za-z0-9+]+[A-Za-z0-9\\.\\_\\-+]*@([A-Za-z0-9\\-]+\\.)+[A-Za-z0-9]+$/;\n \tif (!reg.test(value)) return desc + '必须为邮箱格式';\n }\n\n // 短日期，形如 (yyyy-mm-dd 2008-07-22)\n function checkDate(value, desc = '') {\n \tif (isNull(value)) return;\n\n \tlet hint = '请选择' + desc;\n \tif (value.length != 10) return hint;\n \tlet r = value.match(/^(\\d{1,4})(-|\\/)(\\d{1,2})\\2(\\d{1,2})$/);\n \tif (r == null) return hint;\n \tlet d = new Date(r[1], r[3] - 1, r[4]);\n \tlet chk = d.getFullYear() == r[1] && (d.getMonth() + 1) == r[3] && d.getDate() == r[4];\n \tif (!chk) return hint;\n }\n\n // 年份，形如 (yyyy 2008)\n function checkYear(value, desc = '') {\n \tif (isNull(value)) return;\n\n \tlet hint = '请选择' + desc;\n \tif (value.length != 4) return hint;\n \tvalue += '-01-01';\n \treturn checkDate(value, desc);\n }\n\n // 年月，形如 (yyyy-mm 2008-01)\n function checkYearMonth(value, desc = '') {\n \tif (isNull(value)) return;\n\n \tlet hint = '请选择' + desc;\n \tif (value.length != 7) return hint;\n\n \tvalue += '-01';\n \treturn checkDate(value, desc);\n }\n\n // 短时间(时分秒)，形如 (13:04:06)\n function checkTime(value, desc = '') {\n \tif (isNull(value)) return;\n\n \tlet hint = desc + '必须为时间格式';\n \tif (value.length != 8) return hint;\n\n \tlet a = value.match(/^(\\d{1,2})(:)?(\\d{1,2})\\2(\\d{1,2})$/);\n \tif (a == null) return hint;\n \tif (a[1] > 23 || a[3] > 59 || a[4] > 59) return hint;\n }\n\n // 短时间(时分)，形如 (hh:mm 13:04)\n function checkHourMinute(value, desc = '') {\n \tif (isNull(value)) return;\n\n \tlet hint = desc + '必须为时分时间格式';\n \tif (value.length != 5) return hint;\n\n \tvalue += ':01';\n \treturn checkTime(value, desc);\n }\n\n // 长时间，形如 (2008-07-22 13:04:06)\n function checkDatimeTime(value, desc = '') {\n \tif (isNull(value)) return;\n\n \tlet hint = desc + '必须为完整时间格式';\n \tif (value.length != 19) return hint;\n\n \tvar reg = /^(\\d{1,4})(-|\\/)(\\d{1,2})\\2(\\d{1,2}) (\\d{1,2}):(\\d{1,2}):(\\d{1,2})$/;\n \tvar r = value.match(reg);\n \tif (r == null) return hint;\n \tvar d = new Date(r[1], r[3] - 1, r[4], r[5], r[6], r[7]);\n \tlet chk = d.getFullYear() == r[1] && (d.getMonth() + 1) == r[3] && d.getDate() == r[4] && d.getHours() == r[5] && d.getMinutes() == r[6] && d.getSeconds() == r[7];\n \tif (!chk) return hint;\n }\n\n function checkArray(value, desc = '') {\n \tif (!Array.isArray(value))\n \t\treturn desc + '填写错误arr';\n }\n\n function checkObject(value, desc = '') {\n \tif (value.constructor != Object)\n \t\treturn desc + '填写错误obj';\n }\n\n function checkBoolean(value, desc = '') {\n \tif (value.constructor != Boolean)\n \t\treturn desc + '填写错误bool';\n }\n\n // 枚举 ref=1,2,3,4格式\n function checkIn(value, ref, desc = '') {\n \tif (isNull(value)) return;\n\n \tlet type = getDataType(value);\n \tif (type != String && type != Number) return desc + '填写范围错误';\n\n \tlet arr = String(ref).split(',');\n \tif (!arr.includes(value) && !arr.includes(value + ''))\n \t\treturn desc + '填写范围错误';\n }\n\n function checkIds(value, desc) {}\n\n function checkString(value, desc) {\n \tif (value.constructor != String)\n \t\treturn desc + '填写错误';\n }\n\n\n function check(data, rules, that) {\n \tlet returnData = {};\n \tfor (let key in rules) {\n \t\tlet arr = rules[key].split('|');\n\n \t\tlet desc = key; // 字段说明\n \t\tlet defVal = undefined; // 缺省值\n \t\tlet dataType = 'String'; //数据类型   \n\n \t\tif (!CHECK_OPEN) { // 不校验\n \t\t\t// 取值\n \t\t\tlet val = data[formName];\n \t\t\treturnData[key] = val;\n \t\t\tcontinue;\n \t\t}\n\n \t\t// 小循环获取规则\n \t\tfor (let i = 0; i < arr.length; i++) {\n \t\t\t// 数据项说明  \n\t\t\tif (arr[i].startsWith('name=')) {\n\t\t\t\tdesc = '「' + arr[i].replace('name=', '') + '」';\n \t\t\t\tcontinue;\n\t\t\t } \n\n \t\t\t// 缺省值 \n \t\t\tif (arr[i].startsWith('default=')) {\n \t\t\t\tdefVal = arr[i].replace('default=', '').trim();\n \t\t\t\tcontinue;\n \t\t\t}\n\n \t\t\t// 数据类型 \n \t\t\tswitch (arr[i].toLowerCase()) {\n \t\t\t\tcase 'int':\n \t\t\t\tcase 'digit':\n \t\t\t\t\tdataType = 'Number';\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'array':\n \t\t\t\tcase 'arr':\n \t\t\t\t\tdataType = 'Array';\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'object':\n \t\t\t\tcase 'obj':\n \t\t\t\t\tdataType = 'Object';\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'bool':\n \t\t\t\tcase 'boolean':\n \t\t\t\t\tdataType = 'Boolean';\n \t\t\t\t\tbreak;\n \t\t\t}\n \t\t}\n\n \t\t// 校验 \n \t\tlet formName = (CHECK_SOURCE == 'admin') ? k : arr[0]; // 表单名  admin/client\n\n \t\t// 取值\n \t\tlet val = data[formName];\n\n \t\tswitch (dataType) {\n \t\t\tcase 'Array': {\n\t\t\t\tif (defVal !== undefined) {\n \t\t\t\t\ttry {\n \t\t\t\t\t\tdefVal = JSON.parse(defVal);\n\n \t\t\t\t\t\tif (getDataType(defVal) != Array)\n \t\t\t\t\t\t\treturn _showError(desc + '默认值数组格式错误', formName, that);\n \t\t\t\t\t} catch (ex) {\n \t\t\t\t\t\treturn _showError(desc + '默认值数组格式错误', formName, that);\n \t\t\t\t\t}\n \t\t\t\t}\n \t\t\t\tif (val === null || val === undefined) val = defVal;\n\n\t\t\t\tif (val !== undefined && getDataType(val) != Array)\n \t\t\t\t\treturn _showError(desc + '数组格式错误', formName, that);\n\n \t\t\t\tbreak;\n \t\t\t}\n \t\t\tcase 'Object': {\n\t\t\t\tif (defVal !== undefined) {\n \t\t\t\t\ttry {\n \t\t\t\t\t\tdefVal = JSON.parse(defVal);\n\n \t\t\t\t\t\tif (getDataType(defVal) != Object)\n \t\t\t\t\t\t\treturn _showError(desc + '默认值对象格式错误', formName, that);\n \t\t\t\t\t} catch (ex) {\n \t\t\t\t\t\treturn _showError(desc + '默认值对象格式错误', formName, that);\n \t\t\t\t\t}\n \t\t\t\t}\n \t\t\t\tif (val === null || val === undefined) val = defVal;\n\n\t\t\t\tif (val !== undefined && getDataType(val) != Object)\n \t\t\t\t\treturn _showError(desc + '对象格式错误', formName, that);\n\n \t\t\t\tbreak;\n \t\t\t}\n \t\t\tcase 'Boolean': {\n\t\t\t\tif (defVal !== undefined) {\n \t\t\t\t\ttry {\n \t\t\t\t\t\tdefVal = JSON.parse(defVal);\n\n \t\t\t\t\t\tif (getDataType(defVal) != Boolean)\n \t\t\t\t\t\t\treturn _showError(desc + '默认值布尔格式错误', formName, that);\n \t\t\t\t\t} catch (ex) {\n \t\t\t\t\t\treturn _showError(desc + '默认值布尔格式错误');\n \t\t\t\t\t}\n \t\t\t\t}\n \t\t\t\tif (val === null || val === undefined) val = defVal;\n\n\t\t\t\tif (val !== undefined && getDataType(val) != Boolean)\n \t\t\t\t\treturn _showError(desc + '布尔格式错误', formName, that);\n\n \t\t\t\tbreak;\n \t\t\t}\n \t\t\tcase 'Number': {\n \t\t\t\tif (checkDigit(defVal, desc + '默认值'))\n \t\t\t\t\treturn _showError(desc + '默认值格式错误', formName, that);\n\n\t\t\t\tif (val === null || val === undefined) val = defVal;\n\n\t\t\t\tif (val === undefined) break;\n\n \t\t\t\tif (val === '') //数字不能为空\n \t\t\t\t\treturn _showError(desc + '不能为空', formName, that);\n\n \t\t\t\tlet dataType = getDataType(val);\n \t\t\t\tif (dataType == Object || dataType == Boolean || dataType == Array)\n \t\t\t\t\treturn _showError(desc + '必须为数字格式', formName, that);\n\n \t\t\t\t// 数字格式校验\n \t\t\t\tlet result = checkDigit(val, desc);\n \t\t\t\tif (result) return _showError(result, formName, that);\n\n \t\t\t\tval = Number(val);\n\n \t\t\t\tbreak;\n \t\t\t}\n \t\t\tcase 'String': {\n \t\t\t\tlet dataType = getDataType(val);\n \t\t\t\tif (dataType == Object || dataType == Boolean || dataType == Array)\n \t\t\t\t\treturn _showError(desc + '必须为字符串格式', formName, that);\n\n \t\t\t\tif (val === null || val === undefined) val = defVal;\n\n\t\t\t\tif (val === undefined) break;\n\n \t\t\t\ttry {\n\t\t\t\t\tval = String(val).trim(); // 数字会被转为字符串\n \t\t\t\t} catch (ex) {\n \t\t\t\t\treturn _showError(desc + '必须为字符串格式', formName, that);\n \t\t\t\t}\n \t\t\t\tbreak;\n \t\t\t}\n \t\t}\n\n \t\treturnData[key] = val;\n\n \t\tlet fromStep = (CHECK_SOURCE == 'admin') ? 0 : 1; //admin/client\n \t\tfor (let i = fromStep; i < arr.length; i++) {\n \t\t\tlet result = '';\n\n \t\t\tlet rules = arr[i].split(':');\n \t\t\tlet ruleName = rules[0];\n\n\t\t\t// 空 且非必填的 不校验 \n\t\t\tif (ruleName != 'must' && val === undefined) continue;\n\n \t\t\tswitch (ruleName) {\n \t\t\t\tcase 'must':\n \t\t\t\t\tresult = checkRequired(val, desc);\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'str':\n \t\t\t\tcase 'string':\n \t\t\t\t\tresult = checkString(val, desc);\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'arr':\n \t\t\t\tcase 'array':\n \t\t\t\t\tresult = checkArray(val, desc);\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'obj':\n \t\t\t\tcase 'object':\n \t\t\t\t\tresult = checkObject(val, desc);\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'bool':\n \t\t\t\tcase 'boolean':\n \t\t\t\t\tresult = checkBoolean(val, desc);\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'money':\n \t\t\t\t\tresult = checkMoney(val, desc);\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'year':\n \t\t\t\t\tresult = checkYear(val, desc);\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'yearmonth':\n \t\t\t\t\tresult = checkYearMonth(val, desc);\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'date':\n \t\t\t\t\tresult = checkDate(val, desc);\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'time':\n \t\t\t\t\tresult = checkTime(val, desc);\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'hourminute':\n \t\t\t\t\tresult = checkHourMinute(val, desc);\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'datetime':\n \t\t\t\t\tresult = checkDatimeTime(val, desc);\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'min':\n \t\t\t\t\tresult = checkMin(val, Number(rules[1]), desc);\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'max':\n \t\t\t\t\tresult = checkMax(val, Number(rules[1]), desc);\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'len':\n \t\t\t\t\tresult = checkLen(val, Number(rules[1]), desc);\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'in':\n \t\t\t\t\tresult = checkIn(val, rules[1], desc);\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'email':\n \t\t\t\t\tresult = checkEmail(val, desc);\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'mobile':\n \t\t\t\t\tresult = checkMobile(val, desc);\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'int': // 正整数\n \t\t\t\t\tresult = checkInt(val, desc);\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'digit': // 正小整数\n \t\t\t\t\tresult = checkDigit(val, desc);\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'id':\n \t\t\t\t\tresult = checkId(val, desc);\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'letter':\n \t\t\t\t\tresult = checkLetter(val, desc);\n \t\t\t\t\tbreak;\n \t\t\t\tcase 'letter_num':\n \t\t\t\t\tresult = checkLetterNum(val, desc);\n \t\t\t\t\tbreak;\n \t\t\t}\n\n \t\t\tif (result) {\n \t\t\t\t_showError(result, formName, that);\n \t\t\t\treturn false;\n \t\t\t} else {\n\n \t\t\t\tif (that) {\n \t\t\t\t\tif (CHECK_SOURCE == 'client') {\n \t\t\t\t\t\t// 删除原有的自动聚焦 //admin/client\n \t\t\t\t\t\tif (isDefined(that.data[formName + 'Focus'])) {\n \t\t\t\t\t\t\tthat.setData({ //TODO delete?\n \t\t\t\t\t\t\t\t[formName + 'Focus']: false\n \t\t\t\t\t\t\t});\n \t\t\t\t\t\t}\n \t\t\t\t\t}\n \t\t\t\t}\n \t\t\t}\n\n \t\t}\n \t}\n \treturn returnData;\n }\n\n function _showError(result, formName, that) { //admin/client\n \tif (CHECK_SOURCE == 'client') {\n \t\twx.showModal({\n \t\t\ttitle: '温馨提示',\n \t\t\tcontent: result,\n \t\t\tshowCancel: false,\n \t\t\tsuccess(res) {\n \t\t\t\t// 自动聚焦\n \t\t\t\tif (that) {\n \t\t\t\t\tpageHelper.anchor(formName, that);\n\n \t\t\t\t\tthat.setData({\n \t\t\t\t\t\t[formName + 'Focus']: result,\n \t\t\t\t\t});\n \t\t\t\t}\n\n \t\t\t}\n \t\t});\n \t} else {\n \t\tthrow new AppError(result, appCode.DATA);\n \t}\n\n }\n\n module.exports = {\n \tcheck,\n\n \tcheckString,\n \tcheckArray,\n \tcheckObject,\n \tcheckMoney,\n \tcheckYear,\n \tcheckYearMonth,\n \tcheckDate,\n \tcheckTime,\n \tcheckHourMinute,\n \tcheckDatimeTime,\n \tcheckMin,\n \tcheckMax,\n \tcheckLen,\n \tcheckIn,\n \tcheckEmail,\n \tcheckMobile,\n \tcheckInt, // 正小整数\n \tcheckDigit,\n \tcheckId,\n \tcheckLetter,\n \tcheckLetterNum,\n\n }"
  },
  {
    "path": "miniprogram/lib/tools/base64_lib.js",
    "content": "/**\n * Notes:  \n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-10-25 04:00:00 \n */\n\nfunction Base64() {\n\n\t// private property\n\tvar _keyStr = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";\n\n\t// public method for encoding\n\tthis.encode = function (input) {\n\t\tvar output = \"\";\n\t\tvar chr1, chr2, chr3, enc1, enc2, enc3, enc4;\n\t\tvar i = 0;\n\t\tinput = _utf8_encode(input);\n\t\twhile (i < input.length) {\n\t\t\tchr1 = input.charCodeAt(i++);\n\t\t\tchr2 = input.charCodeAt(i++);\n\t\t\tchr3 = input.charCodeAt(i++);\n\t\t\tenc1 = chr1 >> 2;\n\t\t\tenc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n\t\t\tenc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n\t\t\tenc4 = chr3 & 63;\n\t\t\tif (isNaN(chr2)) {\n\t\t\t\tenc3 = enc4 = 64;\n\t\t\t} else if (isNaN(chr3)) {\n\t\t\t\tenc4 = 64;\n\t\t\t}\n\t\t\toutput = output +\n\t\t\t\t_keyStr.charAt(enc1) + _keyStr.charAt(enc2) +\n\t\t\t\t_keyStr.charAt(enc3) + _keyStr.charAt(enc4);\n\t\t}\n\t\treturn output;\n\t}\n\n\t// public method for decoding\n\tthis.decode = function (input) {\n\t\tvar output = \"\";\n\t\tvar chr1, chr2, chr3;\n\t\tvar enc1, enc2, enc3, enc4;\n\t\tvar i = 0;\n\t\tinput = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n\t\twhile (i < input.length) {\n\t\t\tenc1 = _keyStr.indexOf(input.charAt(i++));\n\t\t\tenc2 = _keyStr.indexOf(input.charAt(i++));\n\t\t\tenc3 = _keyStr.indexOf(input.charAt(i++));\n\t\t\tenc4 = _keyStr.indexOf(input.charAt(i++));\n\t\t\tchr1 = (enc1 << 2) | (enc2 >> 4);\n\t\t\tchr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n\t\t\tchr3 = ((enc3 & 3) << 6) | enc4;\n\t\t\toutput = output + String.fromCharCode(chr1);\n\t\t\tif (enc3 != 64) {\n\t\t\t\toutput = output + String.fromCharCode(chr2);\n\t\t\t}\n\t\t\tif (enc4 != 64) {\n\t\t\t\toutput = output + String.fromCharCode(chr3);\n\t\t\t}\n\t\t}\n\t\toutput = _utf8_decode(output);\n\t\treturn output;\n\t}\n\n\t// private method for UTF-8 encoding\n\tvar _utf8_encode = function (string) {\n\t\tstring = string.replace(/\\r\\n/g, \"\\n\");\n\t\tvar utftext = \"\";\n\t\tfor (var n = 0; n < string.length; n++) {\n\t\t\tvar c = string.charCodeAt(n);\n\t\t\tif (c < 128) {\n\t\t\t\tutftext += String.fromCharCode(c);\n\t\t\t} else if ((c > 127) && (c < 2048)) {\n\t\t\t\tutftext += String.fromCharCode((c >> 6) | 192);\n\t\t\t\tutftext += String.fromCharCode((c & 63) | 128);\n\t\t\t} else {\n\t\t\t\tutftext += String.fromCharCode((c >> 12) | 224);\n\t\t\t\tutftext += String.fromCharCode(((c >> 6) & 63) | 128);\n\t\t\t\tutftext += String.fromCharCode((c & 63) | 128);\n\t\t\t}\n\n\t\t}\n\t\treturn utftext;\n\t}\n\n\t// private method for UTF-8 decoding\n\tvar _utf8_decode = function (utftext) {\n\t\tvar string = \"\";\n\t\tvar i = 0;\n\t\tvar c = c1 = c2 = 0;\n\t\twhile (i < utftext.length) {\n\t\t\tc = utftext.charCodeAt(i);\n\t\t\tif (c < 128) {\n\t\t\t\tstring += String.fromCharCode(c);\n\t\t\t\ti++;\n\t\t\t} else if ((c > 191) && (c < 224)) {\n\t\t\t\tc2 = utftext.charCodeAt(i + 1);\n\t\t\t\tstring += String.fromCharCode(((c & 31) << 6) | (c2 & 63));\n\t\t\t\ti += 2;\n\t\t\t} else {\n\t\t\t\tc2 = utftext.charCodeAt(i + 1);\n\t\t\t\tc3 = utftext.charCodeAt(i + 2);\n\t\t\t\tstring += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));\n\t\t\t\ti += 3;\n\t\t\t}\n\t\t}\n\t\treturn string;\n\t}\n}\n\n\nvar base = new Base64();\n\nfunction encode(str) {\n\treturn base.encode(str);\n}\n\nfunction decode(str) {\n\treturn base.decode(str);\n}\n\nfunction safeEncode(str) { \n\n\treturn encode(str).replace(/[\\+=\\/]/g, function (c) {\n\t\tswitch (c) {\n\t\t\tcase '+':\n\t\t\t\treturn '-';\n\t\t\tcase '=':\n\t\t\t\treturn '';\n\t\t\tcase '/':\n\t\t\t\treturn '_';\n\t\t}\n\t})\n}\n\n\nexport {\n\tencode,\n\tdecode,\n\tsafeEncode\n}"
  },
  {
    "path": "miniprogram/lib/tools/lunar_lib.js",
    "content": "/* 公历转农历代码思路：\n1、建立农历年份查询表\n2、计算输入公历日期与公历基准的相差天数\n3、从农历基准开始遍历农历查询表，计算自农历基准之后每一年的天数，并用相差天数依次相减，确定农历年份\n4、利用剩余相差天数以及农历每个月的天数确定农历月份\n5、利用剩余相差天数确定农历哪一天\nhttps://github.com/xm2by/fragment\n */\n\n//农历节日\nconst LUNAR_HOLIDAY = {\n\t'0101': '春节',\n\t'0115': '元宵节',\n\t'0505': '端午节',\n\t'0707': '七夕',\n\t'0715': '中元节',\n\t'0815': '中秋节',\n\t'0909': '重阳节',\n\t'1208': '腊八节',\n\t'1224': '小年'\n};\n\n// 公历节日\nconst PUBLIC_HOLIDAY = {\n\t'0101': '元旦',\n\t'0214': '情人节',\n\t'0307': '女生节',\n\t'0308': '妇女节',\n\t'0312': '植树节',\n\t'0314': '白色情人',\n\t'0315': '消费者日',\n\t'0401': '愚人节',\n\t'0404': '复活节',\n\t'0501': '劳动节',\n\t'0504': '青年节',\n\t'0510': '母亲节',\n\t'0512': '护士节',\n\t'0601': '儿童节',\n\t'0620': '父亲节',\n\t'0701': '建党节',\n\t'0801': '建军节',\n\t'0910': '教师节',\n\t'0928': '孔子诞辰',\n\t'1001': '国庆节',\n\t'1006': '老人节',\n\t'1024': '联合国日',\n\t'1101': '万圣节',\n\t'1125': '感恩节',\n\t'1224': '平安夜',\n\t'1225': '圣诞节'\n};\n\nconst SOLAR_STERM = ['小寒', '大寒', '立春', '雨水', '惊蛰', '春分', '清明', '谷雨', '立夏', '小满', '芒种', '夏至', '小暑', '大暑', '立秋', '处暑', '白露', '秋分', '寒露', '霜降', '立冬', '小雪', '大雪', '冬至'];\n\n\nconst SOLAR_STERM_INFO = [0, 1272480000, 2548020000, 3830160000, 5120220000, 6420840000,\n\t7732020000, 9055260000, 10388940000, 11733060000, 13084320000, 14441580000,\n\t15800580000, 17159340000, 18513780000, 19861980000, 21201000000, 22529640000,\n\t23846820000, 25152600000, 26447700000, 27733440000, 29011920000, 30285480000\n];\n\n// 农历1949-2100年查询表\nconst LUNAR_YEAR_ARR = [\n\t0x0b557, //1949\n\t0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, //1950-1959\n\t0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, //1960-1969\n\t0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, //1970-1979\n\t0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, //1980-1989\n\t0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, //1990-1999\n\t0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, //2000-2009\n\t0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, //2010-2019\n\t0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, //2020-2029\n\t0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, //2030-2039\n\t0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, //2040-2049\n\t0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, //2050-2059\n\t0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, //2060-2069\n\t0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, //2070-2079\n\t0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, //2080-2089\n\t0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, //2090-2099\n\t0x0d520 //2100\n];\nconst LUNAR_MONTH = ['正', '二', '三', '四', '五', '六', '七', '八', '九', '十', '冬', '腊'];\nconst LUNAR_DAY = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '初', '廿'];\nconst TIAN_GAN = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸'];\nconst DIZHI = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥'];\n\n\n// 公历转农历函数\nfunction sloarToLunar(sy, sm, sd) {\n\tif (typeof (sy) == 'string') {\n\t\tlet arr = sy.split('-');\n\t\tsy = Number(arr[0]);\n\t\tsm = Number(arr[1]);\n\t\tsd = Number(arr[2]);\n\t}\n\n\t// 公历节日\n\tlet publicHoliday = (sm > 9 ? sm : '0' + sm) + '' + (sd > 9 ? sd : '0' + sd);\n\tif (PUBLIC_HOLIDAY.hasOwnProperty(publicHoliday)) {\n\t\treturn PUBLIC_HOLIDAY[publicHoliday];\n\t}\n\n\t// 输入的月份减1处理\n\tsm -= 1;\n\n\t// 计算与公历基准的相差天数\n\t// Date.UTC()返回的是距离公历1970年1月1日的毫秒数,传入的月份需要减1\n\tlet daySpan = (Date.UTC(sy, sm, sd) - Date.UTC(1949, 0, 29)) / (24 * 60 * 60 * 1000) + 1;\n\tlet ly, lm, ld;\n\t// 确定输出的农历年份\n\tfor (let j = 0; j < LUNAR_YEAR_ARR.length; j++) {\n\t\tdaySpan -= lunarYearDays(LUNAR_YEAR_ARR[j]);\n\t\tif (daySpan <= 0) {\n\t\t\tly = 1949 + j;\n\t\t\t// 获取农历年份确定后的剩余天数\n\t\t\tdaySpan += lunarYearDays(LUNAR_YEAR_ARR[j]);\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// 确定输出的农历月份\n\tfor (let k = 0; k < lunarYearMonths(LUNAR_YEAR_ARR[ly - 1949]).length; k++) {\n\t\tdaySpan -= lunarYearMonths(LUNAR_YEAR_ARR[ly - 1949])[k];\n\t\tif (daySpan <= 0) {\n\t\t\t// 有闰月时，月份的数组长度会变成13，因此，当闰月月份小于等于k时，lm不需要加1\n\t\t\tif (hasLeapMonth(LUNAR_YEAR_ARR[ly - 1949]) && hasLeapMonth(LUNAR_YEAR_ARR[ly - 1949]) <= k) {\n\t\t\t\tif (hasLeapMonth(LUNAR_YEAR_ARR[ly - 1949]) < k) {\n\t\t\t\t\tlm = k;\n\t\t\t\t} else if (hasLeapMonth(LUNAR_YEAR_ARR[ly - 1949]) === k) {\n\t\t\t\t\tlm = '闰' + k;\n\t\t\t\t} else {\n\t\t\t\t\tlm = k + 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlm = k + 1;\n\t\t\t}\n\t\t\t// 获取农历月份确定后的剩余天数\n\t\t\tdaySpan += lunarYearMonths(LUNAR_YEAR_ARR[ly - 1949])[k];\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// 确定输出农历哪一天\n\tld = daySpan;\n\n\t//农历节日\n\tlet paraHoliday = (lm > 9 ? lm : '0' + lm) + '' + (ld > 9 ? ld : '0' + ld);\n\tif (LUNAR_HOLIDAY.hasOwnProperty(paraHoliday)) {\n\t\treturn LUNAR_HOLIDAY[paraHoliday];\n\t}\n\n\t// TODO:除夕\n\t/*\n\tif (lm == 12) {\n\t\tvar theLastDay = lDate.isLeap ? leapDays(y) : monthDays(y, m); //农历当月最後一天\n\t\tif (theLastDay == ld) {\n\t\t\treturn \"除夕\";\n\t\t}\n\t}*/\n\n\t// 农历节气 \n\tlet temp = getSolarTerm(sy, sm + 1, sd)\n\tif (temp) return temp;\n\n\n\t// 将计算出来的农历月份转换成汉字月份，闰月需要在前面加上闰字\n\tif (hasLeapMonth(LUNAR_YEAR_ARR[ly - 1949]) && (typeof (lm) === 'string' && lm.indexOf('闰') > -1)) {\n\t\tlm = `闰${LUNAR_MONTH[/\\d/.exec(lm) - 1]}`\n\t} else {\n\t\tlm = LUNAR_MONTH[lm - 1];\n\t}\n\n\t// 将计算出来的农历年份转换为天干地支年\n\t//ly = getTianGan(ly) + getDiZhi(ly);\n\tly = '';\n\n\t// 将计算出来的农历天数转换成汉字\n\tif (ld < 11) {\n\t\tld = `${LUNAR_DAY[10]}${LUNAR_DAY[ld-1]}`\n\t} else if (ld > 10 && ld < 20) {\n\t\tld = `${LUNAR_DAY[9]}${LUNAR_DAY[ld-11]}`\n\t} else if (ld === 20) {\n\t\tld = `${LUNAR_DAY[1]}${LUNAR_DAY[9]}`\n\t} else if (ld > 20 && ld < 30) {\n\t\tld = `${LUNAR_DAY[11]}${LUNAR_DAY[ld-21]}`\n\t} else if (ld === 30) {\n\t\tld = `${LUNAR_DAY[2]}${LUNAR_DAY[9]}`\n\t}\n\n\t//console.log(ly, lm, ld);\n\tif (ld == '初一') ld = lm + '月';\n\n\t/*\n\treturn {\n\t\tlunarYear: ly,\n\t\tLUNAR_MONTH: lm,\n\t\tLUNAR_DAY: ld,\n\t}*/\n\treturn ld;\n}\n\n// 计算农历年是否有闰月，参数为存储农历年的16进制\n// 农历年份信息用16进制存储，其中16进制的最后1位可以用于判断是否有闰月\nfunction hasLeapMonth(ly) {\n\t// 获取16进制的最后1位，需要用到&与运算符\n\tif (ly & 0xf) {\n\t\treturn ly & 0xf\n\t} else {\n\t\treturn false\n\t}\n}\n\n// 如果有闰月，计算农历闰月天数，参数为存储农历年的16进制\n// 农历年份信息用16进制存储，其中16进制的第1位（0x除外）可以用于表示闰月是大月还是小月\nfunction leapMonthDays(ly) {\n\tif (hasLeapMonth(ly)) {\n\t\t// 获取16进制的第1位（0x除外）\n\t\treturn (ly & 0xf0000) ? 30 : 29\n\t} else {\n\t\treturn 0\n\t}\n}\n\n// 计算农历一年的总天数，参数为存储农历年的16进制\n// 农历年份信息用16进制存储，其中16进制的第2-4位（0x除外）可以用于表示正常月是大月还是小月\nfunction lunarYearDays(ly) {\n\tlet totalDays = 0;\n\n\t// 获取正常月的天数，并累加\n\t// 获取16进制的第2-4位，需要用到>>移位运算符\n\tfor (let i = 0x8000; i > 0x8; i >>= 1) {\n\t\tlet monthDays = (ly & i) ? 30 : 29;\n\t\ttotalDays += monthDays;\n\t}\n\t// 如果有闰月，需要把闰月的天数加上\n\tif (hasLeapMonth(ly)) {\n\t\ttotalDays += leapMonthDays(ly);\n\t}\n\n\treturn totalDays\n}\n\n// 获取农历每个月的天数\n// 参数需传入16进制数值\nfunction lunarYearMonths(ly) {\n\tlet monthArr = [];\n\n\t// 获取正常月的天数，并添加到monthArr数组中\n\t// 获取16进制的第2-4位，需要用到>>移位运算符\n\tfor (let i = 0x8000; i > 0x8; i >>= 1) {\n\t\tmonthArr.push((ly & i) ? 30 : 29);\n\t}\n\t// 如果有闰月，需要把闰月的天数加上\n\tif (hasLeapMonth(ly)) {\n\t\tmonthArr.splice(hasLeapMonth(ly), 0, leapMonthDays(ly));\n\t}\n\n\treturn monthArr\n}\n\n// 将农历年转换为天干，参数为农历年\nfunction getTianGan(ly) {\n\tlet tianGanKey = (ly - 3) % 10;\n\tif (tianGanKey === 0) tianGanKey = 10;\n\treturn TIAN_GAN[tianGanKey - 1]\n}\n\n// 将农历年转换为地支，参数为农历年\nfunction getDiZhi(ly) {\n\tlet diZhiKey = (ly - 3) % 12;\n\tif (diZhiKey === 0) diZhiKey = 12;\n\treturn DIZHI[diZhiKey - 1]\n}\n\n/**\n * 节气（参数为公历)\n * @param {*} sy \n * @param {*} sm \n * @param {*} sd \n */\nfunction getSolarTerm(sy, sm, sd) {\n\tsm -= 1;\n\tlet solarTermStr = \"\";\n\t//月份乘2是因为每月平均2节气对应二十四节气加一考虑存在闰月\n\tlet tmp1 = new Date((31556925974.7 * (sy - 1900) + SOLAR_STERM_INFO[sm * 2 + 1]) + Date.UTC(1900, 0, 6, 2, 5));\n\tlet tmp2 = tmp1.getUTCDate();\n\tif (tmp2 == sd) solarTermStr = SOLAR_STERM[sm * 2 + 1];\n\ttmp1 = new Date((31556925974.7 * (sy - 1900) + SOLAR_STERM_INFO[sm * 2]) + Date.UTC(1900, 0, 6, 2, 5));\n\ttmp2 = tmp1.getUTCDate();\n\tif (tmp2 == sd) solarTermStr = SOLAR_STERM[sm * 2];\n\tif (sd > 1) {\n\t\tsd -= 1;\n\t} else {\n\t\tsm -= 1;\n\t\tsd = 31;\n\t\tif (sm < 0) {\n\t\t\tsy -= 1;\n\t\t\tsm = 11;\n\t\t}\n\t}\n\treturn solarTermStr;\n}\n\nmodule.exports = {\n\tsloarToLunar\n}"
  },
  {
    "path": "miniprogram/lib/tools/qrcode_lib.js",
    "content": "//---------------------------------------------------------------------\n/*\n * @demoURL: https://github.com/Pudon/weapp-qrcode \n */\n//---------------------------------------------------------------------\n\n/**\n * qrcode\n * @param typeNumber 1 to 40 Version\n * @param errorCorrectLevel 'L','M','Q','H'\n */\nvar qrcode = function(typeNumber, errorCorrectLevel) {\n\n    var PAD0 = 0xEC;\n    var PAD1 = 0x11;\n\n    var _typeNumber = typeNumber;\n    var _errorCorrectLevel = QRErrorCorrectLevel[errorCorrectLevel];\n    var _modules = null;\n    var _moduleCount = 0;\n    var _dataCache = null;\n    var _dataList = new Array();\n\n    var _this = {};\n\n    var makeImpl = function(test, maskPattern) {\n\n\t_moduleCount = _typeNumber * 4 + 17;\n\t_modules = function(moduleCount) {\n\t    var modules = new Array(moduleCount);\n\t    for (var row = 0; row < moduleCount; row += 1) {\n\t\tmodules[row] = new Array(moduleCount);\n\t\tfor (var col = 0; col < moduleCount; col += 1) {\n\t\t    modules[row][col] = null;\n\t\t}\n\t    }\n\t    return modules;\n\t}(_moduleCount);\n\n\tsetupPositionProbePattern(0, 0);\n\tsetupPositionProbePattern(_moduleCount - 7, 0);\n\tsetupPositionProbePattern(0, _moduleCount - 7);\n\tsetupPositionAdjustPattern();\n\tsetupTimingPattern();\n\tsetupTypeInfo(test, maskPattern);\n\n\tif (_typeNumber >= 7) {\n\t    setupTypeNumber(test);\n\t}\n\n\tif (_dataCache == null) {\n\t    _dataCache = createData(_typeNumber, _errorCorrectLevel, _dataList);\n\t}\n\n\tmapData(_dataCache, maskPattern);\n    };\n\n    var setupPositionProbePattern = function(row, col) {\n\n\tfor (var r = -1; r <= 7; r += 1) {\n\n\t    if (row + r <= -1 || _moduleCount <= row + r) continue;\n\n\t    for (var c = -1; c <= 7; c += 1) {\n\n\t\tif (col + c <= -1 || _moduleCount <= col + c) continue;\n\n\t\tif ( (0 <= r && r <= 6 && (c == 0 || c == 6) )\n\t\t     || (0 <= c && c <= 6 && (r == 0 || r == 6) )\n\t\t     || (2 <= r && r <= 4 && 2 <= c && c <= 4) ) {\n\t\t    _modules[row + r][col + c] = true;\n\t\t} else {\n\t\t    _modules[row + r][col + c] = false;\n\t\t}\n\t    }\n\t}\n    };\n\n    var getBestMaskPattern = function() {\n\n\tvar minLostPoint = 0;\n\tvar pattern = 0;\n\n\tfor (var i = 0; i < 8; i += 1) {\n\n\t    makeImpl(true, i);\n\n\t    var lostPoint = QRUtil.getLostPoint(_this);\n\n\t    if (i == 0 || minLostPoint > lostPoint) {\n\t\tminLostPoint = lostPoint;\n\t\tpattern = i;\n\t    }\n\t}\n\n\treturn pattern;\n    };\n\n    var setupTimingPattern = function() {\n\n\tfor (var r = 8; r < _moduleCount - 8; r += 1) {\n\t    if (_modules[r][6] != null) {\n\t\tcontinue;\n\t    }\n\t    _modules[r][6] = (r % 2 == 0);\n\t}\n\n\tfor (var c = 8; c < _moduleCount - 8; c += 1) {\n\t    if (_modules[6][c] != null) {\n\t\tcontinue;\n\t    }\n\t    _modules[6][c] = (c % 2 == 0);\n\t}\n    };\n\n    var setupPositionAdjustPattern = function() {\n\n\tvar pos = QRUtil.getPatternPosition(_typeNumber);\n\n\tfor (var i = 0; i < pos.length; i += 1) {\n\n\t    for (var j = 0; j < pos.length; j += 1) {\n\n\t\tvar row = pos[i];\n\t\tvar col = pos[j];\n\n\t\tif (_modules[row][col] != null) {\n\t\t    continue;\n\t\t}\n\n\t\tfor (var r = -2; r <= 2; r += 1) {\n\n\t\t    for (var c = -2; c <= 2; c += 1) {\n\n\t\t\tif (r == -2 || r == 2 || c == -2 || c == 2\n\t\t\t    || (r == 0 && c == 0) ) {\n\t\t\t    _modules[row + r][col + c] = true;\n\t\t\t} else {\n\t\t\t    _modules[row + r][col + c] = false;\n\t\t\t}\n\t\t    }\n\t\t}\n\t    }\n\t}\n    };\n\n    var setupTypeNumber = function(test) {\n\n\tvar bits = QRUtil.getBCHTypeNumber(_typeNumber);\n\n\tfor (var i = 0; i < 18; i += 1) {\n\t    var mod = (!test && ( (bits >> i) & 1) == 1);\n\t    _modules[Math.floor(i / 3)][i % 3 + _moduleCount - 8 - 3] = mod;\n\t}\n\n\tfor (var i = 0; i < 18; i += 1) {\n\t    var mod = (!test && ( (bits >> i) & 1) == 1);\n\t    _modules[i % 3 + _moduleCount - 8 - 3][Math.floor(i / 3)] = mod;\n\t}\n    };\n\n    var setupTypeInfo = function(test, maskPattern) {\n\n\tvar data = (_errorCorrectLevel << 3) | maskPattern;\n\tvar bits = QRUtil.getBCHTypeInfo(data);\n\n\t// vertical\n\tfor (var i = 0; i < 15; i += 1) {\n\n\t    var mod = (!test && ( (bits >> i) & 1) == 1);\n\n\t    if (i < 6) {\n\t\t_modules[i][8] = mod;\n\t    } else if (i < 8) {\n\t\t_modules[i + 1][8] = mod;\n\t    } else {\n\t\t_modules[_moduleCount - 15 + i][8] = mod;\n\t    }\n\t}\n\n\t// horizontal\n\tfor (var i = 0; i < 15; i += 1) {\n\n\t    var mod = (!test && ( (bits >> i) & 1) == 1);\n\n\t    if (i < 8) {\n\t\t_modules[8][_moduleCount - i - 1] = mod;\n\t    } else if (i < 9) {\n\t\t_modules[8][15 - i - 1 + 1] = mod;\n\t    } else {\n\t\t_modules[8][15 - i - 1] = mod;\n\t    }\n\t}\n\n\t// fixed module\n\t_modules[_moduleCount - 8][8] = (!test);\n    };\n\n    var mapData = function(data, maskPattern) {\n\n\tvar inc = -1;\n\tvar row = _moduleCount - 1;\n\tvar bitIndex = 7;\n\tvar byteIndex = 0;\n\tvar maskFunc = QRUtil.getMaskFunction(maskPattern);\n\n\tfor (var col = _moduleCount - 1; col > 0; col -= 2) {\n\n\t    if (col == 6) col -= 1;\n\n\t    while (true) {\n\n\t\tfor (var c = 0; c < 2; c += 1) {\n\n\t\t    if (_modules[row][col - c] == null) {\n\n\t\t\tvar dark = false;\n\n\t\t\tif (byteIndex < data.length) {\n\t\t\t    dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1);\n\t\t\t}\n\n\t\t\tvar mask = maskFunc(row, col - c);\n\n\t\t\tif (mask) {\n\t\t\t    dark = !dark;\n\t\t\t}\n\n\t\t\t_modules[row][col - c] = dark;\n\t\t\tbitIndex -= 1;\n\n\t\t\tif (bitIndex == -1) {\n\t\t\t    byteIndex += 1;\n\t\t\t    bitIndex = 7;\n\t\t\t}\n\t\t    }\n\t\t}\n\n\t\trow += inc;\n\n\t\tif (row < 0 || _moduleCount <= row) {\n\t\t    row -= inc;\n\t\t    inc = -inc;\n\t\t    break;\n\t\t}\n\t    }\n\t}\n    };\n\n    var createBytes = function(buffer, rsBlocks) {\n\n\tvar offset = 0;\n\n\tvar maxDcCount = 0;\n\tvar maxEcCount = 0;\n\n\tvar dcdata = new Array(rsBlocks.length);\n\tvar ecdata = new Array(rsBlocks.length);\n\n\tfor (var r = 0; r < rsBlocks.length; r += 1) {\n\n\t    var dcCount = rsBlocks[r].dataCount;\n\t    var ecCount = rsBlocks[r].totalCount - dcCount;\n\n\t    maxDcCount = Math.max(maxDcCount, dcCount);\n\t    maxEcCount = Math.max(maxEcCount, ecCount);\n\n\t    dcdata[r] = new Array(dcCount);\n\n\t    for (var i = 0; i < dcdata[r].length; i += 1) {\n\t\tdcdata[r][i] = 0xff & buffer.getBuffer()[i + offset];\n\t    }\n\t    offset += dcCount;\n\n\t    var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);\n\t    var rawPoly = qrPolynomial(dcdata[r], rsPoly.getLength() - 1);\n\n\t    var modPoly = rawPoly.mod(rsPoly);\n\t    ecdata[r] = new Array(rsPoly.getLength() - 1);\n\t    for (var i = 0; i < ecdata[r].length; i += 1) {\n\t\tvar modIndex = i + modPoly.getLength() - ecdata[r].length;\n\t\tecdata[r][i] = (modIndex >= 0)? modPoly.getAt(modIndex) : 0;\n\t    }\n\t}\n\n\tvar totalCodeCount = 0;\n\tfor (var i = 0; i < rsBlocks.length; i += 1) {\n\t    totalCodeCount += rsBlocks[i].totalCount;\n\t}\n\n\tvar data = new Array(totalCodeCount);\n\tvar index = 0;\n\n\tfor (var i = 0; i < maxDcCount; i += 1) {\n\t    for (var r = 0; r < rsBlocks.length; r += 1) {\n\t\tif (i < dcdata[r].length) {\n\t\t    data[index] = dcdata[r][i];\n\t\t    index += 1;\n\t\t}\n\t    }\n\t}\n\n\tfor (var i = 0; i < maxEcCount; i += 1) {\n\t    for (var r = 0; r < rsBlocks.length; r += 1) {\n\t\tif (i < ecdata[r].length) {\n\t\t    data[index] = ecdata[r][i];\n\t\t    index += 1;\n\t\t}\n\t    }\n\t}\n\n\treturn data;\n    };\n\n    var createData = function(typeNumber, errorCorrectLevel, dataList) {\n\n\tvar rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel);\n\n\tvar buffer = qrBitBuffer();\n\n\tfor (var i = 0; i < dataList.length; i += 1) {\n\t    var data = dataList[i];\n\t    buffer.put(data.getMode(), 4);\n\t    buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) );\n\t    data.write(buffer);\n\t}\n\n\t// calc num max data.\n\tvar totalDataCount = 0;\n\tfor (var i = 0; i < rsBlocks.length; i += 1) {\n\t    totalDataCount += rsBlocks[i].dataCount;\n\t}\n\n\tif (buffer.getLengthInBits() > totalDataCount * 8) {\n\t    throw new Error('code length overflow. ('\n\t\t\t    + buffer.getLengthInBits()\n\t\t\t    + '>'\n\t\t\t    + totalDataCount * 8\n\t\t\t    + ')');\n\t}\n\n\t// end code\n\tif (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {\n\t    buffer.put(0, 4);\n\t}\n\n\t// padding\n\twhile (buffer.getLengthInBits() % 8 != 0) {\n\t    buffer.putBit(false);\n\t}\n\n\t// padding\n\twhile (true) {\n\n\t    if (buffer.getLengthInBits() >= totalDataCount * 8) {\n\t\tbreak;\n\t    }\n\t    buffer.put(PAD0, 8);\n\n\t    if (buffer.getLengthInBits() >= totalDataCount * 8) {\n\t\tbreak;\n\t    }\n\t    buffer.put(PAD1, 8);\n\t}\n\n\treturn createBytes(buffer, rsBlocks);\n    };\n\n    _this.addData = function(data) {\n\tvar newData = qr8BitByte(data);\n\t_dataList.push(newData);\n\t_dataCache = null;\n    };\n\n    _this.isDark = function(row, col) {\n\tif (row < 0 || _moduleCount <= row || col < 0 || _moduleCount <= col) {\n\t    throw new Error(row + ',' + col);\n\t}\n\treturn _modules[row][col];\n    };\n\n    _this.getModuleCount = function() {\n\treturn _moduleCount;\n    };\n\n    _this.make = function() {\n\tmakeImpl(false, getBestMaskPattern() );\n    };\n\n    _this.createTableTag = function(cellSize, margin) {\n\n\tcellSize = cellSize || 2;\n\tmargin = (typeof margin == 'undefined')? cellSize * 4 : margin;\n\n\tvar qrHtml = '';\n\n\tqrHtml += '<table style=\"';\n\tqrHtml += ' border-width: 0px; border-style: none;';\n\tqrHtml += ' border-collapse: collapse;';\n\tqrHtml += ' padding: 0px; margin: ' + margin + 'px;';\n\tqrHtml += '\">';\n\tqrHtml += '<tbody>';\n\n\tfor (var r = 0; r < _this.getModuleCount(); r += 1) {\n\n\t    qrHtml += '<tr>';\n\n\t    for (var c = 0; c < _this.getModuleCount(); c += 1) {\n\t\tqrHtml += '<td style=\"';\n\t\tqrHtml += ' border-width: 0px; border-style: none;';\n\t\tqrHtml += ' border-collapse: collapse;';\n\t\tqrHtml += ' padding: 0px; margin: 0px;';\n\t\tqrHtml += ' width: ' + cellSize + 'px;';\n\t\tqrHtml += ' height: ' + cellSize + 'px;';\n\t\tqrHtml += ' background-color: ';\n\t\tqrHtml += _this.isDark(r, c)? '#000000' : '#ffffff';\n\t\tqrHtml += ';';\n\t\tqrHtml += '\"/>';\n\t    }\n\n\t    qrHtml += '</tr>';\n\t}\n\n\tqrHtml += '</tbody>';\n\tqrHtml += '</table>';\n\n\treturn qrHtml;\n    };\n\n    _this.createImgTag = function(cellSize, margin, size) {\n\n\tcellSize = cellSize || 2;\n\tmargin = (typeof margin == 'undefined')? cellSize * 4 : margin;\n\n\tvar min = margin;\n\tvar max = _this.getModuleCount() * cellSize + margin;\n\n\treturn createImgTag(size, size, function(x, y) {\n\t    if (min <= x && x < max && min <= y && y < max) {\n\t\tvar c = Math.floor( (x - min) / cellSize);\n\t\tvar r = Math.floor( (y - min) / cellSize);\n\t\treturn _this.isDark(r, c)? 0 : 1;\n\t    } else {\n\t\treturn 1;\n\t    }\n\t} );\n    };\n\n    return _this;\n};\n\n//---------------------------------------------------------------------\n// qrcode.stringToBytes\n//---------------------------------------------------------------------\n\nqrcode.stringToBytes = function(s) {\n    var bytes = new Array();\n    for (var i = 0; i < s.length; i += 1) {\n\tvar c = s.charCodeAt(i);\n\tbytes.push(c & 0xff);\n    }\n    return bytes;\n};\n\n//---------------------------------------------------------------------\n// qrcode.createStringToBytes\n//---------------------------------------------------------------------\n\n/**\n * @param unicodeData base64 string of byte array.\n * [16bit Unicode],[16bit Bytes], ...\n * @param numChars\n */\nqrcode.createStringToBytes = function(unicodeData, numChars) {\n\n    // create conversion map.\n\n    var unicodeMap = function() {\n\n\tvar bin = base64DecodeInputStream(unicodeData);\n\tvar read = function() {\n\t    var b = bin.read();\n\t    if (b == -1) throw new Error();\n\t    return b;\n\t};\n\n\tvar count = 0;\n\tvar unicodeMap = {};\n\twhile (true) {\n\t    var b0 = bin.read();\n\t    if (b0 == -1) break;\n\t    var b1 = read();\n\t    var b2 = read();\n\t    var b3 = read();\n\t    var k = String.fromCharCode( (b0 << 8) | b1);\n\t    var v = (b2 << 8) | b3;\n\t    unicodeMap[k] = v;\n\t    count += 1;\n\t}\n\tif (count != numChars) {\n\t    throw new Error(count + ' != ' + numChars);\n\t}\n\n\treturn unicodeMap;\n    }();\n\n    var unknownChar = '?'.charCodeAt(0);\n\n    return function(s) {\n\tvar bytes = new Array();\n\tfor (var i = 0; i < s.length; i += 1) {\n\t    var c = s.charCodeAt(i);\n\t    if (c < 128) {\n\t\tbytes.push(c);\n\t    } else {\n\t\tvar b = unicodeMap[s.charAt(i)];\n\t\tif (typeof b == 'number') {\n\t\t    if ( (b & 0xff) == b) {\n\t\t\t// 1byte\n\t\t\tbytes.push(b);\n\t\t    } else {\n\t\t\t// 2bytes\n\t\t\tbytes.push(b >>> 8);\n\t\t\tbytes.push(b & 0xff);\n\t\t    }\n\t\t} else {\n\t\t    bytes.push(unknownChar);\n\t\t}\n\t    }\n\t}\n\treturn bytes;\n    };\n};\n\n//---------------------------------------------------------------------\n// QRMode\n//---------------------------------------------------------------------\n\nvar QRMode = {\n    MODE_NUMBER :\t\t1 << 0,\n    MODE_ALPHA_NUM : \t1 << 1,\n    MODE_8BIT_BYTE : \t1 << 2,\n    MODE_KANJI :\t\t1 << 3\n};\n\n//---------------------------------------------------------------------\n// QRErrorCorrectLevel\n//---------------------------------------------------------------------\n\nvar QRErrorCorrectLevel = {\n    L : 1,\n    M : 0,\n    Q : 3,\n    H : 2\n};\n\n//---------------------------------------------------------------------\n// QRMaskPattern\n//---------------------------------------------------------------------\n\nvar QRMaskPattern = {\n    PATTERN000 : 0,\n    PATTERN001 : 1,\n    PATTERN010 : 2,\n    PATTERN011 : 3,\n    PATTERN100 : 4,\n    PATTERN101 : 5,\n    PATTERN110 : 6,\n    PATTERN111 : 7\n};\n\n//---------------------------------------------------------------------\n// QRUtil\n//---------------------------------------------------------------------\n\nvar QRUtil = function() {\n\n    var PATTERN_POSITION_TABLE = [\n\t[],\n\t[6, 18],\n\t[6, 22],\n\t[6, 26],\n\t[6, 30],\n\t[6, 34],\n\t[6, 22, 38],\n\t[6, 24, 42],\n\t[6, 26, 46],\n\t[6, 28, 50],\n\t[6, 30, 54],\n\t[6, 32, 58],\n\t[6, 34, 62],\n\t[6, 26, 46, 66],\n\t[6, 26, 48, 70],\n\t[6, 26, 50, 74],\n\t[6, 30, 54, 78],\n\t[6, 30, 56, 82],\n\t[6, 30, 58, 86],\n\t[6, 34, 62, 90],\n\t[6, 28, 50, 72, 94],\n\t[6, 26, 50, 74, 98],\n\t[6, 30, 54, 78, 102],\n\t[6, 28, 54, 80, 106],\n\t[6, 32, 58, 84, 110],\n\t[6, 30, 58, 86, 114],\n\t[6, 34, 62, 90, 118],\n\t[6, 26, 50, 74, 98, 122],\n\t[6, 30, 54, 78, 102, 126],\n\t[6, 26, 52, 78, 104, 130],\n\t[6, 30, 56, 82, 108, 134],\n\t[6, 34, 60, 86, 112, 138],\n\t[6, 30, 58, 86, 114, 142],\n\t[6, 34, 62, 90, 118, 146],\n\t[6, 30, 54, 78, 102, 126, 150],\n\t[6, 24, 50, 76, 102, 128, 154],\n\t[6, 28, 54, 80, 106, 132, 158],\n\t[6, 32, 58, 84, 110, 136, 162],\n\t[6, 26, 54, 82, 110, 138, 166],\n\t[6, 30, 58, 86, 114, 142, 170]\n    ];\n    var G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0);\n    var G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0);\n    var G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1);\n\n    var _this = {};\n\n    var getBCHDigit = function(data) {\n\tvar digit = 0;\n\twhile (data != 0) {\n\t    digit += 1;\n\t    data >>>= 1;\n\t}\n\treturn digit;\n    };\n\n    _this.getBCHTypeInfo = function(data) {\n\tvar d = data << 10;\n\twhile (getBCHDigit(d) - getBCHDigit(G15) >= 0) {\n\t    d ^= (G15 << (getBCHDigit(d) - getBCHDigit(G15) ) );\n\t}\n\treturn ( (data << 10) | d) ^ G15_MASK;\n    };\n\n    _this.getBCHTypeNumber = function(data) {\n\tvar d = data << 12;\n\twhile (getBCHDigit(d) - getBCHDigit(G18) >= 0) {\n\t    d ^= (G18 << (getBCHDigit(d) - getBCHDigit(G18) ) );\n\t}\n\treturn (data << 12) | d;\n    };\n\n    _this.getPatternPosition = function(typeNumber) {\n\treturn PATTERN_POSITION_TABLE[typeNumber - 1];\n    };\n\n    _this.getMaskFunction = function(maskPattern) {\n\n\tswitch (maskPattern) {\n\n\t    case QRMaskPattern.PATTERN000 :\n\t\treturn function(i, j) { return (i + j) % 2 == 0; };\n\t    case QRMaskPattern.PATTERN001 :\n\t\treturn function(i, j) { return i % 2 == 0; };\n\t    case QRMaskPattern.PATTERN010 :\n\t\treturn function(i, j) { return j % 3 == 0; };\n\t    case QRMaskPattern.PATTERN011 :\n\t\treturn function(i, j) { return (i + j) % 3 == 0; };\n\t    case QRMaskPattern.PATTERN100 :\n\t\treturn function(i, j) { return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0; };\n\t    case QRMaskPattern.PATTERN101 :\n\t\treturn function(i, j) { return (i * j) % 2 + (i * j) % 3 == 0; };\n\t    case QRMaskPattern.PATTERN110 :\n\t\treturn function(i, j) { return ( (i * j) % 2 + (i * j) % 3) % 2 == 0; };\n\t    case QRMaskPattern.PATTERN111 :\n\t\treturn function(i, j) { return ( (i * j) % 3 + (i + j) % 2) % 2 == 0; };\n\n\t\tdefault :\n\t\tthrow new Error('bad maskPattern:' + maskPattern);\n\t}\n    };\n\n    _this.getErrorCorrectPolynomial = function(errorCorrectLength) {\n\tvar a = qrPolynomial([1], 0);\n\tfor (var i = 0; i < errorCorrectLength; i += 1) {\n\t    a = a.multiply(qrPolynomial([1, QRMath.gexp(i)], 0) );\n\t}\n\treturn a;\n    };\n\n    _this.getLengthInBits = function(mode, type) {\n\n\tif (1 <= type && type < 10) {\n\n\t    // 1 - 9\n\n\t    switch(mode) {\n\t\tcase QRMode.MODE_NUMBER \t: return 10;\n\t\tcase QRMode.MODE_ALPHA_NUM \t: return 9;\n\t\tcase QRMode.MODE_8BIT_BYTE\t: return 8;\n\t\tcase QRMode.MODE_KANJI\t\t: return 8;\n\t\t    default :\n\t\t    throw new Error('mode:' + mode);\n\t    }\n\n\t} else if (type < 27) {\n\n\t    // 10 - 26\n\n\t    switch(mode) {\n\t\tcase QRMode.MODE_NUMBER \t: return 12;\n\t\tcase QRMode.MODE_ALPHA_NUM \t: return 11;\n\t\tcase QRMode.MODE_8BIT_BYTE\t: return 16;\n\t\tcase QRMode.MODE_KANJI\t\t: return 10;\n\t\t    default :\n\t\t    throw new Error('mode:' + mode);\n\t    }\n\n\t} else if (type < 41) {\n\n\t    // 27 - 40\n\n\t    switch(mode) {\n\t\tcase QRMode.MODE_NUMBER \t: return 14;\n\t\tcase QRMode.MODE_ALPHA_NUM\t: return 13;\n\t\tcase QRMode.MODE_8BIT_BYTE\t: return 16;\n\t\tcase QRMode.MODE_KANJI\t\t: return 12;\n\t\t    default :\n\t\t    throw new Error('mode:' + mode);\n\t    }\n\n\t} else {\n\t    throw new Error('type:' + type);\n\t}\n    };\n\n    _this.getLostPoint = function(qrcode) {\n\n\tvar moduleCount = qrcode.getModuleCount();\n\n\tvar lostPoint = 0;\n\n\t// LEVEL1\n\n\tfor (var row = 0; row < moduleCount; row += 1) {\n\t    for (var col = 0; col < moduleCount; col += 1) {\n\n\t\tvar sameCount = 0;\n\t\tvar dark = qrcode.isDark(row, col);\n\n\t\tfor (var r = -1; r <= 1; r += 1) {\n\n\t\t    if (row + r < 0 || moduleCount <= row + r) {\n\t\t\tcontinue;\n\t\t    }\n\n\t\t    for (var c = -1; c <= 1; c += 1) {\n\n\t\t\tif (col + c < 0 || moduleCount <= col + c) {\n\t\t\t    continue;\n\t\t\t}\n\n\t\t\tif (r == 0 && c == 0) {\n\t\t\t    continue;\n\t\t\t}\n\n\t\t\tif (dark == qrcode.isDark(row + r, col + c) ) {\n\t\t\t    sameCount += 1;\n\t\t\t}\n\t\t    }\n\t\t}\n\n\t\tif (sameCount > 5) {\n\t\t    lostPoint += (3 + sameCount - 5);\n\t\t}\n\t    }\n\t};\n\n\t// LEVEL2\n\n\tfor (var row = 0; row < moduleCount - 1; row += 1) {\n\t    for (var col = 0; col < moduleCount - 1; col += 1) {\n\t\tvar count = 0;\n\t\tif (qrcode.isDark(row, col) ) count += 1;\n\t\tif (qrcode.isDark(row + 1, col) ) count += 1;\n\t\tif (qrcode.isDark(row, col + 1) ) count += 1;\n\t\tif (qrcode.isDark(row + 1, col + 1) ) count += 1;\n\t\tif (count == 0 || count == 4) {\n\t\t    lostPoint += 3;\n\t\t}\n\t    }\n\t}\n\n\t// LEVEL3\n\n\tfor (var row = 0; row < moduleCount; row += 1) {\n\t    for (var col = 0; col < moduleCount - 6; col += 1) {\n\t\tif (qrcode.isDark(row, col)\n\t\t    && !qrcode.isDark(row, col + 1)\n\t\t    &&  qrcode.isDark(row, col + 2)\n\t\t    &&  qrcode.isDark(row, col + 3)\n\t\t    &&  qrcode.isDark(row, col + 4)\n\t\t    && !qrcode.isDark(row, col + 5)\n\t\t    &&  qrcode.isDark(row, col + 6) ) {\n\t\t    lostPoint += 40;\n\t\t}\n\t    }\n\t}\n\n\tfor (var col = 0; col < moduleCount; col += 1) {\n\t    for (var row = 0; row < moduleCount - 6; row += 1) {\n\t\tif (qrcode.isDark(row, col)\n\t\t    && !qrcode.isDark(row + 1, col)\n\t\t    &&  qrcode.isDark(row + 2, col)\n\t\t    &&  qrcode.isDark(row + 3, col)\n\t\t    &&  qrcode.isDark(row + 4, col)\n\t\t    && !qrcode.isDark(row + 5, col)\n\t\t    &&  qrcode.isDark(row + 6, col) ) {\n\t\t    lostPoint += 40;\n\t\t}\n\t    }\n\t}\n\n\t// LEVEL4\n\n\tvar darkCount = 0;\n\n\tfor (var col = 0; col < moduleCount; col += 1) {\n\t    for (var row = 0; row < moduleCount; row += 1) {\n\t\tif (qrcode.isDark(row, col) ) {\n\t\t    darkCount += 1;\n\t\t}\n\t    }\n\t}\n\n\tvar ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;\n\tlostPoint += ratio * 10;\n\n\treturn lostPoint;\n    };\n\n    return _this;\n}();\n\n//---------------------------------------------------------------------\n// QRMath\n//---------------------------------------------------------------------\n\nvar QRMath = function() {\n\n    var EXP_TABLE = new Array(256);\n    var LOG_TABLE = new Array(256);\n\n    // initialize tables\n    for (var i = 0; i < 8; i += 1) {\n\tEXP_TABLE[i] = 1 << i;\n    }\n    for (var i = 8; i < 256; i += 1) {\n\tEXP_TABLE[i] = EXP_TABLE[i - 4]\n\t    ^ EXP_TABLE[i - 5]\n\t    ^ EXP_TABLE[i - 6]\n\t    ^ EXP_TABLE[i - 8];\n    }\n    for (var i = 0; i < 255; i += 1) {\n\tLOG_TABLE[EXP_TABLE[i] ] = i;\n    }\n\n    var _this = {};\n\n    _this.glog = function(n) {\n\n\tif (n < 1) {\n\t    throw new Error('glog(' + n + ')');\n\t}\n\n\treturn LOG_TABLE[n];\n    };\n\n    _this.gexp = function(n) {\n\n\twhile (n < 0) {\n\t    n += 255;\n\t}\n\n\twhile (n >= 256) {\n\t    n -= 255;\n\t}\n\n\treturn EXP_TABLE[n];\n    };\n\n    return _this;\n}();\n\n//---------------------------------------------------------------------\n// qrPolynomial\n//---------------------------------------------------------------------\n\nfunction qrPolynomial(num, shift) {\n\n    if (typeof num.length == 'undefined') {\n\tthrow new Error(num.length + '/' + shift);\n    }\n\n    var _num = function() {\n\tvar offset = 0;\n\twhile (offset < num.length && num[offset] == 0) {\n\t    offset += 1;\n\t}\n\tvar _num = new Array(num.length - offset + shift);\n\tfor (var i = 0; i < num.length - offset; i += 1) {\n\t    _num[i] = num[i + offset];\n\t}\n\treturn _num;\n    }();\n\n    var _this = {};\n\n    _this.getAt = function(index) {\n\treturn _num[index];\n    };\n\n    _this.getLength = function() {\n\treturn _num.length;\n    };\n\n    _this.multiply = function(e) {\n\n\tvar num = new Array(_this.getLength() + e.getLength() - 1);\n\n\tfor (var i = 0; i < _this.getLength(); i += 1) {\n\t    for (var j = 0; j < e.getLength(); j += 1) {\n\t\tnum[i + j] ^= QRMath.gexp(QRMath.glog(_this.getAt(i) ) + QRMath.glog(e.getAt(j) ) );\n\t    }\n\t}\n\n\treturn qrPolynomial(num, 0);\n    };\n\n    _this.mod = function(e) {\n\n\tif (_this.getLength() - e.getLength() < 0) {\n\t    return _this;\n\t}\n\n\tvar ratio = QRMath.glog(_this.getAt(0) ) - QRMath.glog(e.getAt(0) );\n\n\tvar num = new Array(_this.getLength() );\n\tfor (var i = 0; i < _this.getLength(); i += 1) {\n\t    num[i] = _this.getAt(i);\n\t}\n\n\tfor (var i = 0; i < e.getLength(); i += 1) {\n\t    num[i] ^= QRMath.gexp(QRMath.glog(e.getAt(i) ) + ratio);\n\t}\n\n\t// recursive call\n\treturn qrPolynomial(num, 0).mod(e);\n    };\n\n    return _this;\n};\n\n//---------------------------------------------------------------------\n// QRRSBlock\n//---------------------------------------------------------------------\n\nvar QRRSBlock = function() {\n\n\n    // [1: [L, M, Q, H], ..]\n    var RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];\n\n    var qrRSBlock = function(totalCount, dataCount) {\n\tvar _this = {};\n\t_this.totalCount = totalCount;\n\t_this.dataCount = dataCount;\n\treturn _this;\n    };\n\n    var _this = {};\n\n    var getRsBlockTable = function(typeNumber, errorCorrectLevel) {\n\n\tswitch(errorCorrectLevel) {\n\t    case QRErrorCorrectLevel.L :\n\t\treturn RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];\n\t    case QRErrorCorrectLevel.M :\n\t\treturn RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];\n\t    case QRErrorCorrectLevel.Q :\n\t\treturn RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];\n\t    case QRErrorCorrectLevel.H :\n\t\treturn RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];\n\t\tdefault :\n\t\treturn undefined;\n\t}\n    };\n\n    _this.getRSBlocks = function(typeNumber, errorCorrectLevel) {\n\n\tvar rsBlock = getRsBlockTable(typeNumber, errorCorrectLevel);\n\n\tif (typeof rsBlock == 'undefined') {\n\t    throw new Error('bad rs block @ typeNumber:' + typeNumber +\n\t\t\t    '/errorCorrectLevel:' + errorCorrectLevel);\n\t}\n\n\tvar length = rsBlock.length / 3;\n\n\tvar list = new Array();\n\n\tfor (var i = 0; i < length; i += 1) {\n\n\t    var count = rsBlock[i * 3 + 0];\n\t    var totalCount = rsBlock[i * 3 + 1];\n\t    var dataCount = rsBlock[i * 3 + 2];\n\n\t    for (var j = 0; j < count; j += 1) {\n\t\tlist.push(qrRSBlock(totalCount, dataCount) );\n\t    }\n\t}\n\n\treturn list;\n    };\n\n    return _this;\n}();\n\n//---------------------------------------------------------------------\n// qrBitBuffer\n//---------------------------------------------------------------------\n\nvar qrBitBuffer = function() {\n\n    var _buffer = new Array();\n    var _length = 0;\n\n    var _this = {};\n\n    _this.getBuffer = function() {\n\treturn _buffer;\n    };\n\n    _this.getAt = function(index) {\n\tvar bufIndex = Math.floor(index / 8);\n\treturn ( (_buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1;\n    };\n\n    _this.put = function(num, length) {\n\tfor (var i = 0; i < length; i += 1) {\n\t    _this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1);\n\t}\n    };\n\n    _this.getLengthInBits = function() {\n\treturn _length;\n    };\n\n    _this.putBit = function(bit) {\n\n\tvar bufIndex = Math.floor(_length / 8);\n\tif (_buffer.length <= bufIndex) {\n\t    _buffer.push(0);\n\t}\n\n\tif (bit) {\n\t    _buffer[bufIndex] |= (0x80 >>> (_length % 8) );\n\t}\n\n\t_length += 1;\n    };\n\n    return _this;\n};\n\n//---------------------------------------------------------------------\n// qr8BitByte\n//---------------------------------------------------------------------\n\nvar qr8BitByte = function(data) {\n\n    var _mode = QRMode.MODE_8BIT_BYTE;\n    var _data = data;\n    var _parsedData = [];\n\n    var _this = {};\n\n\n    // Added to support UTF-8 Characters\n    for (var i = 0, l = _data.length; i < l; i++) {\n\tvar byteArray = [];\n\tvar code = _data.charCodeAt(i);\n\n\tif (code > 0x10000) {\n\t    byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18);\n\t    byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12);\n\t    byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6);\n\t    byteArray[3] = 0x80 | (code & 0x3F);\n\t} else if (code > 0x800) {\n\t    byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12);\n\t    byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6);\n\t    byteArray[2] = 0x80 | (code & 0x3F);\n\t} else if (code > 0x80) {\n\t    byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6);\n\t    byteArray[1] = 0x80 | (code & 0x3F);\n\t} else {\n\t    byteArray[0] = code;\n\t}\n\n        // Fix Unicode corruption bug\n        _parsedData.push(byteArray);\n    }\n\n    _parsedData = Array.prototype.concat.apply([], _parsedData);\n\n    if (_parsedData.length != _data.length) {\n\t_parsedData.unshift(191);\n\t_parsedData.unshift(187);\n\t_parsedData.unshift(239);\n    }\n\n    var _bytes = _parsedData;\n\n    _this.getMode = function() {\n\treturn _mode;\n    };\n\n    _this.getLength = function(buffer) {\n\treturn _bytes.length;\n    };\n\n    _this.write = function(buffer) {\n\tfor (var i = 0; i < _bytes.length; i += 1) {\n\t    buffer.put(_bytes[i], 8);\n\t}\n    };\n\n    return _this;\n};\n\n//=====================================================================\n// GIF Support etc.\n//\n\n//---------------------------------------------------------------------\n// byteArrayOutputStream\n//---------------------------------------------------------------------\n\nvar byteArrayOutputStream = function() {\n\n    var _bytes = new Array();\n\n    var _this = {};\n\n    _this.writeByte = function(b) {\n\t_bytes.push(b & 0xff);\n    };\n\n    _this.writeShort = function(i) {\n\t_this.writeByte(i);\n\t_this.writeByte(i >>> 8);\n    };\n\n    _this.writeBytes = function(b, off, len) {\n\toff = off || 0;\n\tlen = len || b.length;\n\tfor (var i = 0; i < len; i += 1) {\n\t    _this.writeByte(b[i + off]);\n\t}\n    };\n\n    _this.writeString = function(s) {\n\tfor (var i = 0; i < s.length; i += 1) {\n\t    _this.writeByte(s.charCodeAt(i) );\n\t}\n    };\n\n    _this.toByteArray = function() {\n\treturn _bytes;\n    };\n\n    _this.toString = function() {\n\tvar s = '';\n\ts += '[';\n\tfor (var i = 0; i < _bytes.length; i += 1) {\n\t    if (i > 0) {\n\t\ts += ',';\n\t    }\n\t    s += _bytes[i];\n\t}\n\ts += ']';\n\treturn s;\n    };\n\n    return _this;\n};\n\n//---------------------------------------------------------------------\n// base64EncodeOutputStream\n//---------------------------------------------------------------------\n\nvar base64EncodeOutputStream = function() {\n\n    var _buffer = 0;\n    var _buflen = 0;\n    var _length = 0;\n    var _base64 = '';\n\n    var _this = {};\n\n    var writeEncoded = function(b) {\n\t_base64 += String.fromCharCode(encode(b & 0x3f) );\n    };\n\n    var encode = function(n) {\n\tif (n < 0) {\n\t    // error.\n\t} else if (n < 26) {\n\t    return 0x41 + n;\n\t} else if (n < 52) {\n\t    return 0x61 + (n - 26);\n\t} else if (n < 62) {\n\t    return 0x30 + (n - 52);\n\t} else if (n == 62) {\n\t    return 0x2b;\n\t} else if (n == 63) {\n\t    return 0x2f;\n\t}\n\tthrow new Error('n:' + n);\n    };\n\n    _this.writeByte = function(n) {\n\n\t_buffer = (_buffer << 8) | (n & 0xff);\n\t_buflen += 8;\n\t_length += 1;\n\n\twhile (_buflen >= 6) {\n\t    writeEncoded(_buffer >>> (_buflen - 6) );\n\t    _buflen -= 6;\n\t}\n    };\n\n    _this.flush = function() {\n\n\tif (_buflen > 0) {\n\t    writeEncoded(_buffer << (6 - _buflen) );\n\t    _buffer = 0;\n\t    _buflen = 0;\n\t}\n\n\tif (_length % 3 != 0) {\n\t    // padding\n\t    var padlen = 3 - _length % 3;\n\t    for (var i = 0; i < padlen; i += 1) {\n\t\t_base64 += '=';\n\t    }\n\t}\n    };\n\n    _this.toString = function() {\n\treturn _base64;\n    };\n\n    return _this;\n};\n\n//---------------------------------------------------------------------\n// base64DecodeInputStream\n//---------------------------------------------------------------------\n\nvar base64DecodeInputStream = function(str) {\n\n    var _str = str;\n    var _pos = 0;\n    var _buffer = 0;\n    var _buflen = 0;\n\n    var _this = {};\n\n    _this.read = function() {\n\n\twhile (_buflen < 8) {\n\n\t    if (_pos >= _str.length) {\n\t\tif (_buflen == 0) {\n\t\t    return -1;\n\t\t}\n\t\tthrow new Error('unexpected end of file./' + _buflen);\n\t    }\n\n\t    var c = _str.charAt(_pos);\n\t    _pos += 1;\n\n\t    if (c == '=') {\n\t\t_buflen = 0;\n\t\treturn -1;\n\t    } else if (c.match(/^\\s$/) ) {\n\t\t// ignore if whitespace.\n\t\tcontinue;\n\t    }\n\n\t    _buffer = (_buffer << 6) | decode(c.charCodeAt(0) );\n\t    _buflen += 6;\n\t}\n\n\tvar n = (_buffer >>> (_buflen - 8) ) & 0xff;\n\t_buflen -= 8;\n\treturn n;\n    };\n\n    var decode = function(c) {\n\tif (0x41 <= c && c <= 0x5a) {\n\t    return c - 0x41;\n\t} else if (0x61 <= c && c <= 0x7a) {\n\t    return c - 0x61 + 26;\n\t} else if (0x30 <= c && c <= 0x39) {\n\t    return c - 0x30 + 52;\n\t} else if (c == 0x2b) {\n\t    return 62;\n\t} else if (c == 0x2f) {\n\t    return 63;\n\t} else {\n\t    throw new Error('c:' + c);\n\t}\n    };\n\n    return _this;\n};\n\n//---------------------------------------------------------------------\n// gifImage (B/W)\n//---------------------------------------------------------------------\n\nvar gifImage = function(width, height) {\n\n    var _width = width;\n    var _height = height;\n    var _data = new Array(width * height);\n\n    var _this = {};\n\n    _this.setPixel = function(x, y, pixel) {\n\t_data[y * _width + x] = pixel;\n    };\n\n    _this.write = function(out) {\n\n\t//---------------------------------\n\t// GIF Signature\n\n\tout.writeString('GIF87a');\n\n\t//---------------------------------\n\t// Screen Descriptor\n\n\tout.writeShort(_width);\n\tout.writeShort(_height);\n\n\tout.writeByte(0x80); // 2bit\n\tout.writeByte(0);\n\tout.writeByte(0);\n\n\t//---------------------------------\n\t// Global Color Map\n\n\t// black\n\tout.writeByte(0x00);\n\tout.writeByte(0x00);\n\tout.writeByte(0x00);\n\n\t// white\n\tout.writeByte(0xff);\n\tout.writeByte(0xff);\n\tout.writeByte(0xff);\n\n\t//---------------------------------\n\t// Image Descriptor\n\n\tout.writeString(',');\n\tout.writeShort(0);\n\tout.writeShort(0);\n\tout.writeShort(_width);\n\tout.writeShort(_height);\n\tout.writeByte(0);\n\n\t//---------------------------------\n\t// Local Color Map\n\n\t//---------------------------------\n\t// Raster Data\n\n\tvar lzwMinCodeSize = 2;\n\tvar raster = getLZWRaster(lzwMinCodeSize);\n\n\tout.writeByte(lzwMinCodeSize);\n\n\tvar offset = 0;\n\n\twhile (raster.length - offset > 255) {\n\t    out.writeByte(255);\n\t    out.writeBytes(raster, offset, 255);\n\t    offset += 255;\n\t}\n\n\tout.writeByte(raster.length - offset);\n\tout.writeBytes(raster, offset, raster.length - offset);\n\tout.writeByte(0x00);\n\n\t//---------------------------------\n\t// GIF Terminator\n\tout.writeString(';');\n    };\n\n    var bitOutputStream = function(out) {\n\n\tvar _out = out;\n\tvar _bitLength = 0;\n\tvar _bitBuffer = 0;\n\n\tvar _this = {};\n\n\t_this.write = function(data, length) {\n\n\t    if ( (data >>> length) != 0) {\n\t\tthrow new Error('length over');\n\t    }\n\n\t    while (_bitLength + length >= 8) {\n\t\t_out.writeByte(0xff & ( (data << _bitLength) | _bitBuffer) );\n\t\tlength -= (8 - _bitLength);\n\t\tdata >>>= (8 - _bitLength);\n\t\t_bitBuffer = 0;\n\t\t_bitLength = 0;\n\t    }\n\n\t    _bitBuffer = (data << _bitLength) | _bitBuffer;\n\t    _bitLength = _bitLength + length;\n\t};\n\n\t_this.flush = function() {\n\t    if (_bitLength > 0) {\n\t\t_out.writeByte(_bitBuffer);\n\t    }\n\t};\n\n\treturn _this;\n    };\n\n    var getLZWRaster = function(lzwMinCodeSize) {\n\n\tvar clearCode = 1 << lzwMinCodeSize;\n\tvar endCode = (1 << lzwMinCodeSize) + 1;\n\tvar bitLength = lzwMinCodeSize + 1;\n\n\t// Setup LZWTable\n\tvar table = lzwTable();\n\n\tfor (var i = 0; i < clearCode; i += 1) {\n\t    table.add(String.fromCharCode(i) );\n\t}\n\ttable.add(String.fromCharCode(clearCode) );\n\ttable.add(String.fromCharCode(endCode) );\n\n\tvar byteOut = byteArrayOutputStream();\n\tvar bitOut = bitOutputStream(byteOut);\n\n\t// clear code\n\tbitOut.write(clearCode, bitLength);\n\n\tvar dataIndex = 0;\n\n\tvar s = String.fromCharCode(_data[dataIndex]);\n\tdataIndex += 1;\n\n\twhile (dataIndex < _data.length) {\n\n\t    var c = String.fromCharCode(_data[dataIndex]);\n\t    dataIndex += 1;\n\n\t    if (table.contains(s + c) ) {\n\n\t\ts = s + c;\n\n\t    } else {\n\n\t\tbitOut.write(table.indexOf(s), bitLength);\n\n\t\tif (table.size() < 0xfff) {\n\n\t\t    if (table.size() == (1 << bitLength) ) {\n\t\t\tbitLength += 1;\n\t\t    }\n\n\t\t    table.add(s + c);\n\t\t}\n\n\t\ts = c;\n\t    }\n\t}\n\n\tbitOut.write(table.indexOf(s), bitLength);\n\n\t// end code\n\tbitOut.write(endCode, bitLength);\n\n\tbitOut.flush();\n\n\treturn byteOut.toByteArray();\n    };\n\n    var lzwTable = function() {\n\n\tvar _map = {};\n\tvar _size = 0;\n\n\tvar _this = {};\n\n\t_this.add = function(key) {\n\t    if (_this.contains(key) ) {\n\t\tthrow new Error('dup key:' + key);\n\t    }\n\t    _map[key] = _size;\n\t    _size += 1;\n\t};\n\n\t_this.size = function() {\n\t    return _size;\n\t};\n\n\t_this.indexOf = function(key) {\n\t    return _map[key];\n\t};\n\n\t_this.contains = function(key) {\n\t    return typeof _map[key] != 'undefined';\n\t};\n\n\treturn _this;\n    };\n\n    return _this;\n};\n\nvar createImgTag = function(width, height, getPixel, alt) {\n\n    var gif = gifImage(width, height);\n    for (var y = 0; y < height; y += 1) {\n\tfor (var x = 0; x < width; x += 1) {\n\t    gif.setPixel(x, y, getPixel(x, y) );\n\t}\n    }\n\n    var b = byteArrayOutputStream();\n    gif.write(b);\n\n    var base64 = base64EncodeOutputStream();\n    var bytes = b.toByteArray();\n    for (var i = 0; i < bytes.length; i += 1) {\n\tbase64.writeByte(bytes[i]);\n    }\n    base64.flush();\n\n    var img = '';\n    img += 'data:image/gif;base64,';\n    img += base64;\n\n    return img;\n};\n\n//---------------------------------------------------------------------\n// returns qrcode function.\n\nvar drawImg = function(text, options) {\n    options = options || {};\n    var typeNumber = options.typeNumber || 4;\n    var errorCorrectLevel = options.errorCorrectLevel || 'M';\n    var size = options.size || 500;\n\n    var qr;\n\n    try {\n        qr = qrcode(typeNumber, errorCorrectLevel || 'M');\n        qr.addData(text);\n        qr.make();\n    } catch (e) {\n        if(typeNumber >= 40) {\n            throw new Error('Text too long to encode');\n        } else {\n            return drawImg(text, {\n                size: size,\n                errorCorrectLevel: errorCorrectLevel,\n                typeNumber: typeNumber + 1\n            });\n        }\n    }\n\n    // calc cellsize and margin\n    var cellsize = parseInt(size / qr.getModuleCount());\n    var margin = parseInt((size - qr.getModuleCount() * cellsize) / 2);\n\n    return qr.createImgTag(cellsize, margin, size);\n};\nmodule.exports = {\n\tdrawImg: drawImg\n};"
  },
  {
    "path": "miniprogram/pages/test1/test1.js",
    "content": "// pages/test1/test1.js\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad(options) {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady() {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow() {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide() {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload() {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh() {\n\n\t},\n\n\t/**\n\t * 页面上拉触底事件的处理函数\n\t */\n\tonReachBottom() {\n\n\t},\n\n\t/**\n\t * 用户点击右上角分享\n\t */\n\tonShareAppMessage() {\n\n\t}\n})"
  },
  {
    "path": "miniprogram/pages/test1/test1.wxml",
    "content": "<!--pages/test1/test1.wxml-->\n<text>pages/test1/test1.wxml</text>\n"
  },
  {
    "path": "miniprogram/projects/TRIP1/biz/admin_album_biz.js",
    "content": "/**\n * Notes: 相册后台管理模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-06-05 07:48:00 \n */\n\nconst BaseBiz = require('../../../comm/biz/base_biz.js');\nconst AlbumBiz = require('./album_biz.js');\nconst projectSetting = require('../public/project_setting.js');\n\nclass AdminAlbumBiz extends BaseBiz {\n\n\tstatic initFormData(id = '') {\n\t\tlet cateIdOptions = AlbumBiz.getCateList();\n\n\t\treturn {\n\t\t\tid,\n\n\t\t\tcateIdOptions,\n\t\t\tfields: projectSetting.ALBUM_FIELDS, \n\t\t\n\t\t\tformTitle: '',\n\t\t\tformCateId: (cateIdOptions.length == 1) ? cateIdOptions[0].val : '',\n\t\t\tformOrder: 9999,\n\t\t\t\n\t\t\tformForms: [],\n\t\t}\n\n\t}\n\n}\n\nAdminAlbumBiz.CHECK_FORM = {\n\ttitle: 'formTitle|must|string|min:2|max:50|name=标题',\n\tcateId: 'formCateId|must|id|name=分类',\n\torder: 'formOrder|must|int|min:0|max:9999|name=排序号',\n\tforms: 'formForms|array',\n};\n\n\nmodule.exports = AdminAlbumBiz;"
  },
  {
    "path": "miniprogram/projects/TRIP1/biz/admin_meet_biz.js",
    "content": "/**\n * Notes:预约后台管理模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-11-14 07:48:00 \n */\n\nconst BaseBiz = require('../../../comm/biz/base_biz.js');\nconst cloudHelper = require('../../../helper/cloud_helper.js');\nconst dataHelper = require('../../../helper/data_helper.js');\nconst timeHelper = require('../../../helper/time_helper.js');\nconst projectSetting = require('../public/project_setting.js');\nconst formSetHelper = require('../../../cmpts/public/form/form_set_helper.js');\n\nconst TIME_NODE = {\n\tmark: 'mark-no',\n\tstart: '09:00', //开始\n\tend: '21:30', // 结束\n\tlimit: 50, //人数限制\n\tisLimit: false,\n\tstatus: 1,\n\tstat: { //统计数据 \n\t\tsuccCnt: 0,\n\t\tcancelCnt: 0,\n\t\tadminCancelCnt: 0,\n\t}\n};\n\n\nclass AdminMeetBiz extends BaseBiz {\n\n\t/** 取得分类 */\n\tstatic getTypeList() {\n\t\tlet typeList = projectSetting.MEET_TYPE;\n\t\tlet arr = [];\n\t\tfor (let k = 0; k < typeList.length; k++) {\n\t\t\tarr.push({\n\t\t\t\tlabel: typeList[k].title,\n\t\t\t\ttype: 'typeId',\n\t\t\t\tval: typeList[k].id, //for options\n\t\t\t\tvalue: typeList[k].id, //for list\n\t\t\t})\n\t\t}\n\t\treturn arr;\n\t}\n\n\tstatic getTypeName(typeId) {\n\t\tlet typeList = projectSetting.MEET_TYPE;\n\n\t\tfor (let k = 0; k < typeList.length; k++) {\n\t\t\tif (typeList[k].id == typeId) return typeList[k].title;\n\t\t}\n\t\treturn '';\n\t}\n\n\t// 计算剩余天数\n\tstatic getLeaveDay(days) {\n\t\tlet now = timeHelper.time('Y-M-D');\n\t\tlet count = 0;\n\t\tfor (let k = 0; k < days.length; k++) {\n\t\t\tif (days[k].day >= now) count++;\n\t\t}\n\t\treturn count;\n\t}\n\n\tstatic getNewTimeNode(day) {\n\t\tlet node = dataHelper.deepClone(TIME_NODE);\n\t\tday = day.replace(/-/g, '');\n\t\tnode.mark = 'T' + day + 'AAA' + dataHelper.genRandomAlpha(10).toUpperCase();\n\t\treturn node;\n\t}\n\n\tstatic getDaysTimeOptions() {\n\t\tlet HourArr = [];\n\t\tlet clockArr = [];\n\t\tlet k = 0;\n\n\t\tfor (k = 0; k <= 23; k++) {\n\t\t\tlet node = {};\n\t\t\tnode.label = k + '点';\n\t\t\tnode.val = k < 10 ? '0' + k : k;\n\t\t\tHourArr.push(node);\n\t\t}\n\n\t\tfor (k = 0; k < 59;) {\n\t\t\tlet node = {};\n\t\t\tnode.label = k + '分';\n\t\t\tnode.val = k < 10 ? '0' + k : k;\n\t\t\tclockArr.push(node);\n\t\t\tk += 5;\n\n\t\t\tif (k == 60) {\n\t\t\t\tnode = {};\n\t\t\t\tnode.label = '59分';\n\t\t\t\tnode.val = '59';\n\t\t\t\tclockArr.push(node);\n\t\t\t}\n\t\t}\n\n\t\treturn [HourArr, clockArr];\n\t}\n\n\tstatic getEndBeforeSetOptions() {\n\t\tlet ret = '';\n\t\tlet k = 0;\n\t\tfor (k = 0; k < 60;) {\n\t\t\tret += ',' + k + '=预约时段开始前' + k + '分钟截止';\n\t\t\tk += 10;\n\t\t}\n\n\t\tfor (k = 60; k < 360;) {\n\t\t\tret += ',' + k + '=预约时段开始前' + k / 60 + '小时截止';\n\t\t\tk += 30;\n\t\t}\n\n\t\tfor (k = 360; k <= 48 * 60;) {\n\t\t\tret += ',' + k + '=预约时段开始前' + k / 60 + '小时截止';\n\t\t\tk += 60;\n\t\t}\n\n\t\tif (ret.startsWith(',')) ret = ret.substring(1);\n\n\t\treturn dataHelper.getSelectOptions(ret);\n\t}\n\n\tstatic getEndYesterdaySetOptions() {\n\t\tlet ret = '';\n\t\tlet k = 0;\n\t\tfor (k = 0; k < 24; k++) {\n\t\t\tret += ',' + (k < 10 ? '0' + k : k) + ':00=前一天' + k + '点00分' + '截止';\n\t\t\tret += ',' + (k < 10 ? '0' + k : k) + ':30=前一天' + k + '点30分' + '截止';\n\t\t}\n\n\t\tret += ',23:59=前一天23点59分截止';\n\t\tif (ret.startsWith(',')) ret = ret.substring(1);\n\n\t\treturn dataHelper.getSelectOptions(ret);\n\t}\n\n\tstatic getEndTodaySetOptions() {\n\t\tlet ret = '';\n\t\tlet k = 0;\n\t\tfor (k = 0; k < 24; k++) {\n\t\t\tret += ',' + (k < 10 ? '0' + k : k) + ':00=当天' + k + '点00分' + '截止';\n\t\t\tret += ',' + (k < 10 ? '0' + k : k) + ':30=当天' + k + '点30分' + '截止';\n\t\t}\n\n\t\tret += ',23:59=当天23点59分截止';\n\t\tif (ret.startsWith(',')) ret = ret.substring(1);\n\n\t\treturn dataHelper.getSelectOptions(ret);\n\t}\n\n\tstatic getEndAfterSetOptions() {\n\t\tlet ret = '';\n\t\tlet k = 0;\n\t\tfor (k = 0; k < 60;) {\n\t\t\tret += ',' + k + '=预约时段开始后' + k + '分钟截止';\n\t\t\tk += 5;\n\t\t}\n\n\t\tfor (k = 60; k <= 3 * 60;) {\n\t\t\tret += ',' + k + '=预约时段开始后' + k / 60 + '小时截止';\n\t\t\tk += 30;\n\t\t}\n\n\t\tif (ret.startsWith(',')) ret = ret.substring(1);\n\n\t\treturn dataHelper.getSelectOptions(ret);\n\t}\n\n\tstatic getBeginDaySetOptions() {\n\t\tlet dayArr = [];\n\t\tlet clockArr = [];\n\t\tlet k = 0;\n\n\t\tlet nodeCur = {};\n\t\tnodeCur.label = '当天';\n\t\tnodeCur.val = 0;\n\t\tdayArr.push(nodeCur);\n\n\t\tfor (k = 1; k <= 180; k++) {\n\t\t\tlet node = {};\n\t\t\tnode.label = '提前' + k + '天';\n\t\t\tnode.val = k;\n\t\t\tdayArr.push(node);\n\t\t}\n\n\t\tfor (k = 0; k < 24; k++) {\n\t\t\tlet node = {};\n\t\t\tnode.label = k + '点00分' + '开始';\n\t\t\tnode.val = (k < 10 ? '0' + k : k) + ':00';\n\t\t\tclockArr.push(node);\n\n\t\t\tnode = {};\n\t\t\tnode.label = k + '点30分' + '开始';\n\t\t\tnode.val = (k < 10 ? '0' + k : k) + ':30';\n\t\t\tclockArr.push(node);\n\n\t\t}\n\n\t\treturn [dayArr, clockArr];\n\n\t}\n\n\tstatic getCancelSetOptions() {\n\t\tlet modeArr = [{\n\t\t\tlabel: '取消后无须后台审核',\n\t\t\tval: 'no'\n\t\t}\n\t\t\t/*, {\n\t\t\t\t\t\tlabel: '取消后须后台审核',\n\t\t\t\t\t\tval: 'check'\n\t\t\t\t\t}*/\n\t\t];\n\t\tlet timeArr = [];\n\n\t\tlet k = 0;\n\t\tfor (k = -60; k < 0;) {\n\t\t\tlet node = {};\n\t\t\tnode.label = '开始后' + (-k) + '分钟内可取消';\n\t\t\tnode.val = k;\n\t\t\ttimeArr.push(node);\n\t\t\tk += 10;\n\t\t}\n\n\t\tfor (k = 0; k < 60;) {\n\t\t\tlet node = {};\n\t\t\tnode.label = '开始前' + k + '分钟可取消';\n\t\t\tnode.val = k;\n\t\t\ttimeArr.push(node);\n\t\t\tk += 10;\n\t\t}\n\n\t\tfor (k = 60; k < 60 * 24;) {\n\t\t\tlet node = {};\n\t\t\tnode.label = '开始前' + k / 60 + '小时可取消';\n\t\t\tnode.val = k;\n\t\t\ttimeArr.push(node);\n\t\t\tk += 60;\n\t\t}\n\n\t\tfor (k = 60 * 24; k <= 60 * 24 * 10;) {\n\t\t\tlet node = {};\n\t\t\tnode.label = '开始前' + k / (60 * 24) + '天可取消';\n\t\t\tnode.val = k;\n\t\t\ttimeArr.push(node);\n\t\t\tk += 60 * 24;\n\t\t}\n\n\t\treturn [timeArr, modeArr];\n\n\t}\n\n\tstatic getLimitSetOptions() {\n\t\tlet mode = dataHelper.getSelectOptions('all=本项目全程限制次数,clock=按每一时段限制次数,day=按每天限制次数,week=按自然周限制次数,month=按自然月限制次数');\n\n\t\tlet list = [];\n\t\tfor (let k = 0; k < mode.length; k++) {\n\t\t\tlet node = {};\n\t\t\tnode.label = mode[k].label;\n\t\t\tnode.val = mode[k].val;\n\n\t\t\tlet children = [];\n\t\t\tif (k == 0) {\n\t\t\t\tchildren.push({\n\t\t\t\t\tlabel: '不限制预约次数',\n\t\t\t\t\tval: -1\n\t\t\t\t});\n\t\t\t}\n\t\t\tfor (let j = 1; j <= 30; j++) {\n\t\t\t\tlet childNode = {};\n\t\t\t\tchildNode.label = '可预约' + j + '次';\n\t\t\t\tchildNode.val = j\n\t\t\t\tchildren.push(childNode);\n\t\t\t}\n\n\t\t\tnode.children = children;\n\n\t\t\tlist.push(node);\n\t\t}\n\n\t\treturn list;\n\n\t}\n\n\t// 上限规则的表述\n\tstatic getLimitSetDesc(rule) {\n\t\tlet ret = '';\n\t\tswitch (rule.mode) {\n\t\t\tcase 'all':\n\t\t\t\tret = rule.cnt > 0 ? '本项目全程可预约' + rule.cnt + '次' : '本项目全程不限制次数';\n\t\t\t\tbreak;\n\t\t\tcase 'month':\n\t\t\t\tret = '自然月内可预约' + rule.cnt + '次';\n\t\t\t\tbreak;\n\t\t\tcase 'week':\n\t\t\t\tret = '自然周内可预约' + rule.cnt + '次';\n\t\t\t\tbreak;\n\t\t\tcase 'day':\n\t\t\t\tret = '每天可预约' + rule.cnt + '次';\n\t\t\t\tbreak;\n\t\t\tcase 'clock':\n\t\t\t\tret = '每一时段可预约' + rule.cnt + '次';\n\t\t\t\tbreak;\n\t\t}\n\t\treturn ret;\n\t}\n\n\t// 截止规则的表述\n\tstatic getEndSetDesc(rule) {\n\t\tlet ret = '';\n\t\tswitch (rule.mode) {\n\t\t\tcase 'no':\n\t\t\t\tret = '不限制';\n\t\t\t\tbreak;\n\t\t\tcase 'yesterday':\n\t\t\t\tret = '前一天' + rule.time + '预约截止';\n\t\t\t\tbreak;\n\t\t\tcase 'today':\n\t\t\t\tret = '当天' + rule.time + '预约截止';\n\t\t\t\tbreak;\n\t\t\tcase 'clock':\n\t\t\t\tret = rule.time + '预约截止';\n\t\t\t\tbreak;\n\t\t\tcase 'before':\n\t\t\t\tif (rule.time < 60)\n\t\t\t\t\tret = '开始前' + rule.time + '分钟预约截止';\n\t\t\t\telse\n\t\t\t\t\tret = '开始前' + rule.time / 60 + '小时预约截止';\n\t\t\t\tbreak;\n\t\t\tcase 'after':\n\t\t\t\tif (rule.time < 60)\n\t\t\t\t\tret = '开始后' + rule.time + '分钟预约截止';\n\t\t\t\telse\n\t\t\t\t\tret = '开始后' + rule.time / 60 + '小时预约截止';\n\t\t\t\tbreak;\n\t\t}\n\t\treturn ret;\n\t}\n\n\t// 取消规则的表述\n\tstatic getCancelSetDesc(rule) {\n\t\tlet ret = '';\n\t\tswitch (rule.mode) {\n\t\t\tcase 'no':\n\t\t\t\tif (rule.time < 0)\n\t\t\t\t\tret = '开始后' + (-rule.time) + '分钟可取消,无须审核';\n\t\t\t\telse if (rule.time == 0)\n\t\t\t\t\tret = '开始前均可取消,无须审核';\n\t\t\t\telse if (rule.time < 60)\n\t\t\t\t\tret = '开始前' + rule.time + '分钟可取消,无须审核';\n\t\t\t\telse if (rule.time < 1440)\n\t\t\t\t\tret = '开始前' + rule.time / 60 + '小时可取消,无须审核';\n\t\t\t\telse\n\t\t\t\t\tret = '开始前' + rule.time / (60 * 24) + '天可取消,无须审核';\n\t\t\t\tbreak;\n\t\t\tcase 'check':\n\t\t\t\tif (rule.time == 60)\n\t\t\t\t\tret = '开始前均可取消,须审核';\n\t\t\t\telse if (rule.time < 60)\n\t\t\t\t\tret = '开始前' + rule.time + '分钟可取消,须审核';\n\t\t\t\telse if (rule.time < 1440)\n\t\t\t\t\tret = '开始前' + rule.time / 60 + '小时可取消,无须审核';\n\t\t\t\telse\n\t\t\t\t\tret = '开始前' + rule.time / (60 * 24) + '天可取消,须审核';\n\t\t\t\tbreak;\n\t\t}\n\n\t\tret = ret.replace(',无须审核', '');\n\t\treturn ret;\n\t}\n\n\n\t// 开放规则的表述\n\tstatic getBeginSetDesc(rule) {\n\t\tlet ret = '';\n\t\tswitch (rule.mode) {\n\t\t\tcase 'no':\n\t\t\t\tret = '随时可预约';\n\t\t\t\tbreak;\n\t\t\tcase 'day':\n\t\t\t\tif (rule.day == 0)\n\t\t\t\t\tret = '当天 ' + rule.time + '开放预约';\n\t\t\t\telse\n\t\t\t\t\tret = '提前' + rule.day + '天 ' + rule.time + '开放预约';\n\t\t\t\tbreak;\n\t\t\tcase 'clock':\n\t\t\t\tret = rule.time + '起开放预约';\n\t\t\t\tbreak;\n\t\t}\n\t\treturn ret;\n\t}\n\n\t/** 表单初始化相关数据 */\n\tstatic async initFormData() {\n\t\tlet typeIdOptions = AdminMeetBiz.getTypeList();\n\t\treturn {\n\n\t\t\t// 选项数据  \n\t\t\ttypeIdOptions,\n\t\t\tbeginDaySetOptions: AdminMeetBiz.getBeginDaySetOptions(),\n\n\t\t\t// 表单数据  \n\t\t\tformTitle: '',\n\t\t\tformTypeId: (typeIdOptions.length == 1) ? typeIdOptions[0].val : '',\n\t\t\tformContent: '',\n\t\t\tformOrder: 9999,\n\t\t\tformStyleSet: {\n\t\t\t\tpic: '',\n\t\t\t\tdesc: ''\n\t\t\t},\n\n\t\t\tformDaysSet: [], // 时间设置 \n\n\n\t\t\tformIsShowLimit: 1, //是否显示可预约数量\n\n\t\t\tformFormSet: formSetHelper.initFields(projectSetting.MEET_JOIN_FIELDS)\n\t\t}\n\n\t}\n\n\t/** \n\t * 样式更新\n\t * @param {string} meetId \n\t * @param {Array} content  富文本数组\n\t */\n\tstatic async updateMeetStyleSet(that, meetId, styleSet) {\n\t\tlet pic = styleSet.pic;\n\n\t\t// 图片上传到云空间\n\t\tif (styleSet.pic)\n\t\t\tpic = await cloudHelper.transTempPicOne(pic, 'meet/', meetId, false);\n\n\t\tstyleSet.pic = pic;\n\n\t\t// 更新本记录的图片信息\n\t\tlet params = {\n\t\t\tmeetId,\n\t\t\tstyleSet\n\t\t}\n\n\t\ttry {\n\t\t\t// 更新数据 从promise 里直接同步返回\n\t\t\tawait cloudHelper.callCloudSumbit('admin/meet_update_style', params);\n\t\t\tthat.setData({\n\t\t\t\tformStyleSet: styleSet\n\t\t\t});\n\t\t} catch (e) {\n\t\t\tconsole.error(e);\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/** \n\t * 富文本中的图片上传\n\t * @param {string} meetId \n\t * @param {Array} content  富文本数组\n\t */\n\tstatic async updateMeetCotnentPic(that, meetId, content) {\n\t\tlet imgList = [];\n\t\tfor (let k = 0; k < content.length; k++) {\n\t\t\tif (content[k].type == 'img') {\n\t\t\t\timgList.push(content[k].val);\n\t\t\t}\n\t\t}\n\n\t\t// 图片上传到云空间\n\t\timgList = await cloudHelper.transTempPics(imgList, 'meet/', meetId);\n\n\t\t// 更新图片地址\n\t\tlet imgIdx = 0;\n\t\tfor (let k = 0; k < content.length; k++) {\n\t\t\tif (content[k].type == 'img') {\n\t\t\t\tcontent[k].val = imgList[imgIdx];\n\t\t\t\timgIdx++;\n\t\t\t}\n\t\t}\n\n\t\t// 更新本记录的图片信息\n\t\tlet params = {\n\t\t\tmeetId,\n\t\t\tcontent\n\t\t}\n\n\t\ttry {\n\t\t\t// 更新数据 从promise 里直接同步返回\n\t\t\tawait cloudHelper.callCloudSumbit('admin/meet_update_content', params);\n\t\t\tthat.setData({\n\t\t\t\tformContent: content\n\t\t\t});\n\t\t} catch (e) {\n\t\t\tconsole.error(e);\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n}\n\n\n/** 表单校验  */\nAdminMeetBiz.CHECK_FORM = {\n\ttitle: 'formTitle|must|string|min:2|max:50|name=标题',\n\ttypeId: 'formTypeId|must|id|name=分类',\n\torder: 'formOrder|must|int|min:0|max:9999|name=排序号',\n\n\tdaysSet: 'formDaysSet|must|array|name=预约时间设置',\n\tisShowLimit: 'formIsShowLimit|must|int|in:0,1|name=是否显示可预约人数',\n\n\tformSet: 'formFormSet|must|array|name=用户资料设置',\n};\n\n\nmodule.exports = AdminMeetBiz;"
  },
  {
    "path": "miniprogram/projects/TRIP1/biz/admin_news_biz.js",
    "content": "/**\n * Notes: 资讯后台管理模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-11-14 07:48:00 \n */\n\nconst BaseBiz = require('../../../comm/biz/base_biz.js');\nconst NewsBiz = require('./news_biz.js');\nconst projectSetting = require('../public/project_setting.js');\n\nclass AdminNewsBiz extends BaseBiz {\n\n\n\t/** 表单初始化相关数据 */\n\tstatic initFormData(id = '') {\n\t\tlet cateIdOptions = NewsBiz.getCateList();\n\n\t\treturn {\n\t\t\tid,\n\n\t\t\tcontentDesc: '',\n\n\t\t\t// 分类\n\t\t\tcateIdOptions,\n\n\t\t\tfields: projectSetting.NEWS_FIELDS,\n\n\t\t\t// 图片数据 \n\t\t\timgList: [],\n\n\n\t\t\t// 表单数据  \n\t\t\tformOrder: 9999,\n\t\t\tformTitle: '',\n\t\t\tformDesc: '',\n\t\t\tformContent: [],\n\t\t\tformCateId: (cateIdOptions.length == 1) ? cateIdOptions[0].val : '',\n\t\t\tformForms:[],\n\t\t}\n\n\t}\n\n\tstatic getCateName(cateId) {\n\t\tlet cateList = projectSetting.NEWS_CATE;\n\n\t\tfor (let k = 0; k < cateList.length; k++) {\n\t\t\tif (cateList[k].id == cateId) return cateList[k].title;\n\t\t}\n\t\treturn '';\n\t}\n\n}\n\n\n/** 表单校验  本地 */\nAdminNewsBiz.CHECK_FORM = {\n\ttitle: 'formTitle|must|string|min:4|max:50|name=标题',\n\tcateId: 'formCateId|must|id|name=分类',\n\torder: 'formOrder|must|int|min:0|max:9999|name=排序号',\n\tdesc: 'formDesc|string|min:10|max:200|name=简介',\n\tforms: 'formForms|array',\n};\n\n\nmodule.exports = AdminNewsBiz;"
  },
  {
    "path": "miniprogram/projects/TRIP1/biz/admin_product_biz.js",
    "content": "/**\n * Notes: 相册后台管理模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-06-05 07:48:00 \n */\n\nconst BaseBiz = require('../../../comm/biz/base_biz.js');\nconst ProductBiz = require('./product_biz.js');\nconst projectSetting = require('../public/project_setting.js');\n\nclass AdminProductBiz extends BaseBiz {\n\n\tstatic initFormData(id = '') {\n\t\tlet cateIdOptions = ProductBiz.getCateList();\n\n\t\treturn {\n\t\t\tid,\n\n\t\t\tcateIdOptions,\n\t\t\tfields: projectSetting.PRODUCT_FIELDS, \n\t\t\t\n\t\t\tformTitle: '',\n\t\t\tformCateId: (cateIdOptions.length == 1) ? cateIdOptions[0].val : '',\n\t\t\tformOrder: 9999,\n\n\t\t\tformForms: [],\n\t\t}\n\n\t}\n\n}\n\nAdminProductBiz.CHECK_FORM = {\n\ttitle: 'formTitle|must|string|min:2|max:50|name=标题',\n\tcateId: 'formCateId|must|id|name=分类',\n\torder: 'formOrder|must|int|min:0|max:9999|name=排序号',\n\tforms: 'formForms|array',\n};\n\n\nmodule.exports = AdminProductBiz;"
  },
  {
    "path": "miniprogram/projects/TRIP1/biz/album_biz.js",
    "content": "/**\n * Notes: 相册模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-11-14 07:48:00 \n */\n\nconst BaseBiz = require('../../../comm/biz/base_biz.js');\nconst projectSetting = require('../public/project_setting.js');\n\nclass AlbumBiz extends BaseBiz {\n \n\n\tstatic getCateName(cateId) {\n\t\treturn BaseBiz.getCateName(cateId, projectSetting.ALBUM_CATE);\n\t}\n\n\tstatic getCateList() {\n\t\treturn BaseBiz.getCateList(projectSetting.ALBUM_CATE);\n\t}\n\n\tstatic setCateTitle() {\n\t\treturn BaseBiz.setCateTitle(projectSetting.ALBUM_CATE);\n\t}\n\n\n\t/** 搜索菜单设置 */\n\tstatic async getSearchMenu() {\n\t\tlet sortMenus = [{\n\t\t\tlabel: '全部',\n\t\t\ttype: '',\n\t\t\tvalue: ''\n\t\t}];\n\t\tlet sortMenusAfter = [{\n\t\t\tlabel: '最新',\n\t\t\ttype: 'sort',\n\t\t\tvalue: 'new'\n\t\t},];\n\t\tlet sortItems = [];\n\n\t\tsortMenus = sortMenus.concat(sortMenusAfter);\n\n\t\treturn {\n\t\t\tsortItems,\n\t\t\tsortMenus\n\t\t}\n\t}\n}\n\nmodule.exports = AlbumBiz;"
  },
  {
    "path": "miniprogram/projects/TRIP1/biz/meet_biz.js",
    "content": "/**\n * Notes: 预约模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-12-10 07:48:00 \n */\n\nconst BaseBiz = require('../../../comm/biz/base_biz.js');\nconst pageHelper = require('../../../helper/page_helper.js');\nconst dataHelper = require('../../../helper/data_helper.js');\nconst projectSetting = require('../public/project_setting.js');\n\nclass MeetBiz extends BaseBiz { \n\n\tstatic async subscribeMessageMeet(callback) {\n\t\tcallback && await callback();\n\t}\n\n\tstatic setTypeTitle(that, typeId = null) { \n\t \n\t\tlet typeList =   projectSetting.MEET_TYPE ;\n\t\tfor (let k = 0; k < typeList.length; k++) {\n\t\t\tif (typeList[k].id == typeId) {\n\t\t\t\twx.setNavigationBarTitle({\n\t\t\t\t\ttitle: typeList[k].title\n\t\t\t\t});\n\n\t\t\t\tif (typeList[k].style) { //样式\n\t\t\t\t\tthat.setData({\n\t\t\t\t\t\tlistMode: typeList[k].style\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tthat.setData({\n\t\t\t\t\t\tlistMode: 'leftpic'\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn '';\n\n\t} \n\n}\n\nmodule.exports = MeetBiz;"
  },
  {
    "path": "miniprogram/projects/TRIP1/biz/news_biz.js",
    "content": "/**\n * Notes: 资讯模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-11-14 07:48:00 \n */\n\nconst BaseBiz = require('../../../comm/biz/base_biz.js');\nconst dataHelper = require('../../../helper/data_helper.js');\nconst projectSetting = require('../public/project_setting.js');\n\nclass NewsBiz extends BaseBiz {   \n\n\t/** 取得分类 */\n\tstatic getCateList() {\n\t\tlet cateList = projectSetting.NEWS_CATE; \n\n\t\tlet arr = [];\n\t\tfor (let k = 0; k < cateList.length; k++) {\n\t\t\tarr.push({\n\t\t\t\tlabel: cateList[k].title,\n\t\t\t\ttype: 'cateId',\n\t\t\t\tval: cateList[k].id, //for options\n\t\t\t\tvalue: cateList[k].id, //for list\n\t\t\t})\n\t\t}\n\t\treturn arr;\n\t}\n\n\n\tstatic setCateTitle(cateId = null, that) {\n\n\t\t// 获取当前小程序的页面栈\n\t\tlet pages = getCurrentPages();\n\t\t// 数组中索引最大的页面--当前页面\n\t\tlet currentPage = pages[pages.length - 1];\n\t\t// 附加参数 \n\t\tif (currentPage.options && currentPage.options.id) {\n\t\t\tcateId = currentPage.options.id;\n\t\t}\n\t\tlet cateList = dataHelper.getSelectOptions(projectSetting.NEWS_CATE);\n\t\tfor (let k = 0; k < cateList.length; k++) {\n\t\t\tif (cateList[k].val == cateId) {\n\t\t\t\twx.setNavigationBarTitle({\n\t\t\t\t\ttitle: cateList[k].label\n\t\t\t\t});\n\n\t\t\t\tif (cateList[k].ext) { //样式\n\t\t\t\t\tthat.setData({\n\t\t\t\t\t\tlistMode: cateList[k].ext\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tthat.setData({\n\t\t\t\t\t\tlistMode: 'leftbig'\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/** 搜索菜单设置 */\n\tstatic async getSearchMenu() {\n\t\tlet sortMenus = [{\n\t\t\tlabel: '全部',\n\t\t\ttype: '',\n\t\t\tvalue: ''\n\t\t}];\n\t\tlet sortMenusAfter = [{\n\t\t\tlabel: '最新',\n\t\t\ttype: 'sort',\n\t\t\tvalue: 'new'\n\t\t},];\n\t\tlet sortItems = [];\n\n\t\tsortMenus = sortMenus.concat(sortMenusAfter);\n\n\t\treturn {\n\t\t\tsortItems,\n\t\t\tsortMenus\n\t\t}\n\t}\n}\n\nmodule.exports = NewsBiz;"
  },
  {
    "path": "miniprogram/projects/TRIP1/biz/product_biz.js",
    "content": "/**\n * Notes: 产品模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-11-14 07:48:00 \n */\n\nconst BaseBiz = require('../../../comm/biz/base_biz.js'); \nconst projectSetting = require('../public/project_setting.js');\n\nclass ProductBiz extends BaseBiz { \n\n\tstatic getCateName(cateId) {\n\t\treturn BaseBiz.getCateName(cateId, projectSetting.PRODUCT_CATE);\n\t}\n\n\tstatic getCateList() {\n\t\treturn BaseBiz.getCateList(projectSetting.PRODUCT_CATE);\n\t}\n\n\tstatic setCateTitle() {\n\t\treturn BaseBiz.setCateTitle(projectSetting.PRODUCT_CATE);\n\t}\n\n\n\t/** 搜索菜单设置 */\n\tstatic async getSearchMenu() {\n\t\tlet sortMenus = [{\n\t\t\tlabel: '全部',\n\t\t\ttype: '',\n\t\t\tvalue: ''\n\t\t}];\n\t\tlet sortMenusAfter = [{\n\t\t\tlabel: '最新',\n\t\t\ttype: 'sort',\n\t\t\tvalue: 'new'\n\t\t},];\n\t\tlet sortItems = [];\n\n\t\tsortMenus = sortMenus.concat(sortMenusAfter);\n\n\t\treturn {\n\t\t\tsortItems,\n\t\t\tsortMenus\n\t\t}\n\t}\n}\n\nmodule.exports = ProductBiz;"
  },
  {
    "path": "miniprogram/projects/TRIP1/biz/project_biz.js",
    "content": "/**\n * Notes: 项目通用业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-05-22 07:48:00 \n */\n\nconst BaseBiz = require('../../../comm/biz/base_biz.js'); \nconst projectSetting = require('../public/project_setting.js');\nconst PubilcBiz = require('../../../comm/biz/public_biz.js');\nconst PassportBiz = require('../../../comm/biz/passport_biz.js'); \n\nclass ProjectBiz extends BaseBiz {\n\n\t/**\n\t * 页面初始化    \n\t * @param {*} that  \n\t */\n\tstatic initPage(that, { isSetNavColor = true } = {}) {    \n\n\t\tlet skin = {};\n\t\tskin.NAV_BG = projectSetting.NAV_BG;\n\t\tskin.NAV_COLOR = projectSetting.NAV_COLOR;\n\t\tskin.PROJECT_COLOR = projectSetting.PROJECT_COLOR;\n\t\t\n\t\tPubilcBiz.initPageBase(that, { skin, isSetNavColor });\n\t}\n\n}\n\nmodule.exports = ProjectBiz;"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/about/index/about_index.js",
    "content": "const behavior = require('../../../../../comm/behavior/about_bh.js');\nconst ProjectBiz = require('../../../biz/project_biz.js');\nconst projectSetting = require('../../../public/project_setting.js');\n\nPage({\n\n\tbehaviors: [behavior],\n\n\t/**\n\t\t* 生命周期函数--监听页面加载\n\t\t*/\n\tonLoad: async function (options) {\n\t\tProjectBiz.initPage(this);\n\n\t\tif (options && options.key)\n\t\t\tthis._loadDetail(options.key, projectSetting.SETUP_CONTENT_ITEMS);\n\t},\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/about/index/about_index.json",
    "content": "{\n\t\"usingComponents\": { \n\t  },\n\t\"enablePullDownRefresh\": true \n  }"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/about/index/about_index.wxml",
    "content": "<include src=\"../../../../../tpls/project/about_tpl.wxml\" />"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/about/index/about_index.wxss",
    "content": "@import \"../../../../../style/public/detail.wxss\"; \n@import \"../../../style/skin.wxss\"; \n  "
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/about/service/about_service.js",
    "content": "const pageHelper = require('../../../../../helper/page_helper.js');\nconst ProjectBiz = require('../../../biz/project_biz.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad(options) {\n\t\tProjectBiz.initPage(this); \n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady() {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow() {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide() {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload() {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh() {\n\n\t},\n\n\t/**\n\t * 页面上拉触底事件的处理函数\n\t */\n\tonReachBottom() {\n\n\t},\n\n\t/**\n\t * 用户点击右上角分享\n\t */\n\tonShareAppMessage() {\n\n\t},\n\n\turl:function(e) {\n\t\tpageHelper.url(e, this);\n\t}\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/about/service/about_service.json",
    "content": "{\n\t\"usingComponents\": {},\n\t\"navigationBarTitleText\": \"服务\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/about/service/about_service.wxml",
    "content": "<view class=\"main-service\">\n\t<view class=\"pic\"><image src=\"../../../images/home/b5.jpg\" mode=\"aspectFill\" /></view>\n\t<view class=\"service-title\">游玩保障服务</view>\n\t<view class=\"service-list\">\n\t\t<view class=\"item\"  bindtap=\"url\" data-type=\"phone\" data-url=\"12301\">\n\t\t\t<view class=\"item-inner bg1\">\n\t\t\t\t<view class=\"left\">\n\t\t\t\t\t<view class=\"line1\">旅游咨询</view>\n\t\t\t\t\t<view class=\"line2\">12301</view>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"right\"><text class=\"icon-phone\"></text></view>\n\t\t\t</view>\n\t\t</view>\n\t\t<view class=\"item\" bindtap=\"url\" data-type=\"phone\" data-url=\"12315\">\n\t\t\t<view class=\"item-inner bg5\">\n\t\t\t\t<view class=\"left\">\n\t\t\t\t\t<view class=\"line1\">投诉求助</view>\n\t\t\t\t\t<view class=\"line2\">投诉有门 实时高效</view>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"right\"><text class=\"icon-edit\"></text></view>\n\t\t\t</view>\n\t\t</view>\n\t</view>\n\n\t<view class=\"service-title\">旅游公共服务</view>\n\t<view class=\"service-list\">\n\t\t<view class=\"item\"  bindtap=\"url\" data-url=\"../../about/index/about_index?key=SETUP_CONTENT_BUS\">\n\t\t\t<view class=\"item-inner bg6\">\n\t\t\t\t<view class=\"left\">\n\t\t\t\t\t<view class=\"line1\">公交信息</view>\n\t\t\t\t\t<view class=\"line2\">智慧公交 智慧旅游</view>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"right\"><image src=\"../../../images/service/bus.png\" /></view>\n\t\t\t</view>\n\t\t</view>\n\t\t<view class=\"item\" bindtap=\"url\" data-url=\"../../about/index/about_index?key=SETUP_CONTENT_PARKING\">\n\t\t\t<view class=\"item-inner bg3\">\n\t\t\t\t<view class=\"left\">\n\t\t\t\t\t<view class=\"line1\">停车场</view>\n\t\t\t\t\t<view class=\"line2\">合理分配 高质高效</view>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"right\"><image src=\"../../../images/service/p.png\" /></view>\n\t\t\t</view>\n\t\t</view>\n\t\t<view class=\"item\" bindtap=\"url\" data-url=\"../../about/index/about_index?key=SETUP_CONTENT_TOLIET\">\n\t\t\t<view class=\"item-inner bg4\">\n\t\t\t\t<view class=\"left\">\n\t\t\t\t\t<view class=\"line1\">找厕所</view>\n\t\t\t\t\t<view class=\"line2\">便民信息 方便你我</view>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"right\"><image src=\"../../../images/service/t.png\" /></view>\n\t\t\t</view>\n\t\t</view>\n\t\t<view class=\"item\" bindtap=\"url\" data-url=\"../../about/index/about_index?key=SETUP_CONTENT_LXS\">\n\t\t\t<view class=\"item-inner bg5\">\n\t\t\t\t<view class=\"left\">\n\t\t\t\t\t<view class=\"line1\">星级旅行社</view>\n\t\t\t\t\t<view class=\"line2\">星级服务 星级品质</view>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"right\"><image src=\"../../../images/service/l.png\" /></view>\n\t\t\t</view>\n\t\t</view>\n\t\t<view class=\"item\" bindtap=\"url\" data-url=\"../../about/index/about_index?key=SETUP_CONTENT_DY\">\n\t\t\t<view class=\"item-inner bg2\">\n\t\t\t\t<view class=\"left\">\n\t\t\t\t\t<view class=\"line1\">星级导游</view>\n\t\t\t\t\t<view class=\"line2\">服务标兵 宾至如归</view>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"right\"><image src=\"../../../images/service/d.png\" /></view>\n\t\t\t</view>\n\t\t</view>\n\t\t<view class=\"item\" bindtap=\"url\" data-url=\"../../about/index/about_index?key=SETUP_CONTENT_WEATHER\">\n\t\t\t<view class=\"item-inner bg6\">\n\t\t\t\t<view class=\"left\">\n\t\t\t\t\t<view class=\"line1\">一周天气</view>\n\t\t\t\t\t<view class=\"line2\">一手天气 尽在掌握</view>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"right\"><image src=\"../../../images/service/tt.png\" /></view>\n\t\t\t</view>\n\t\t</view>\n\t</view>\n</view>\n\n<block wx:if=\"{{skin.IS_SUB}}\">\n\t\t<import src=\"../../tpls/menu_tpl.wxml\" />\n\t\t<template is=\"menuTpl\" data=\"{{curMenu:'service',returnHome:false}}\" />\n\t</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/about/service/about_service.wxss",
    "content": "@import \"../../../style/skin.wxss\";\n\npage {\n\tbackground-color: #fff;\n}\n\n.main-service {\n\tbackground-color: #fff;\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tpadding: 10rpx 0rpx 100rpx;\n}\n\n.main-service .pic {\n\twidth: 100%;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tpadding: 20rpx 20rpx;\n}\n\n.main-service .pic image {\n\twidth: 100%;\n\theight: 260rpx;\n\tborder-radius: 20rpx;\n}\n\n.service-title {\n\tfont-size: 36rpx;\n\tpadding: 20rpx 30rpx;\n\tfont-weight: bold;\n\tcolor: #000;\n}\n\n.service-list {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tpadding: 0 10rpx;\n}\n\n.service-list .item {\n\twidth: 50%;\n\tpadding: 15rpx 15rpx;\n}\n\n.service-list .item .item-inner {\n\twidth: 100%;\n\tbackground-color: #06B2DE;\n\tcolor: #fff;\n\theight: 130rpx;\n\tborder-radius: 10rpx;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.service-list .item .bg1 {\n\tbackground-image: linear-gradient(45deg, #06B2DE, #01DBC6);\n}\n\n.service-list .item .item-inner .bg2 {\n\tbackground-image: linear-gradient(45deg, #276eb0, #2B97FF);\n}\n\n.service-list .item .bg3 {\n\tbackground-image: linear-gradient(45deg, #10CB61, #7EE263);\n}\n\n.service-list .item .bg4 {\n\tbackground-image: linear-gradient(45deg, #FE753B, #F8BF1B);\n}\n\n.service-list .item .bg5 {\n\tbackground-image: linear-gradient(45deg, #8467FE, #DB81F1);\n}\n\n.service-list .item .bg6 {\n\tbackground-image: linear-gradient(45deg, #FD5589, #FC8563);\n}\n\n.service-list .item .left {\n\tflex: 1;\n\tdisplay: flex;\n\tflex-direction: column;\n\twidth: 100%;\n\tpadding: 0 10rpx 0 20rpx;\n}\n\n.service-list .item .item-inner .left .line1 {\n\tfont-size: 32rpx;\n}\n\n.service-list .item .item-inner .left .line2 {\n\tfont-size: 24rpx;\n}\n\n.service-list .item .item-inner .right {\n\tfont-size: 50rpx;\n\twidth: 80rpx;\n\theight: 80rpx;\n\tbackground-color: rgba(255, 255, 255, .2);\n\tborder-radius: 50%;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tmargin-right: 20rpx;\n}\n\n.service-list .item .item-inner .right image {\n\twidth: 50rpx;\n\theight: 50rpx;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/album/add/admin_album_add.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst PublicBiz = require('../../../../../../comm/biz/public_biz.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\nconst validate = require('../../../../../../helper/validate.js');\nconst AdminAlbumBiz = require('../../../../biz/admin_album_biz.js');\nconst AlbumBiz = require('../../../../biz/album_biz.js'); \n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return; \n\n\t\tthis.setData(AdminAlbumBiz.initFormData());\n\t\tthis.setData({\n\t\t\tisLoad: true\n\t\t});  \n\t\n\t},\n\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () { },\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tbindFormSubmit: async function () {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet data = this.data;\n\t\tdata = validate.check(data, AdminAlbumBiz.CHECK_FORM, this);\n\t\tif (!data) return;\n\n\t\tlet forms = this.selectComponent(\"#cmpt-form\").getForms(true);\n\t\tif (!forms) return;\n\t\tdata.forms = forms;\n\n\t\tdata.cateName = AlbumBiz.getCateName(data.cateId);\n\n\t\ttry {\n\n\t\t\t// 创建\n\t\t\tlet result = await cloudHelper.callCloudSumbit('admin/album_insert', data);\n\t\t\tlet albumId = result.data.id;\n\n\t\t\t// 图片\n\t\t\tawait cloudHelper.transFormsTempPics(forms, 'album/', albumId, 'admin/album_update_forms');\n\n\n\t\t\tlet callback = async function () {\n\t\t\t\tPublicBiz.removeCacheList('admin-album-list');\n\t\t\t\tPublicBiz.removeCacheList('album-list');\n\t\t\t\twx.navigateBack();\n\n\t\t\t}\n\t\t\tpageHelper.showSuccToast('添加成功', 2000, callback);\n\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t}\n\n\t},\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/album/add/admin_album_add.json",
    "content": "{\n\t\"usingComponents\": {\n\t\t\"cmpt-img-upload\": \"/cmpts/public/img/img_upload_cmpt\",\n\t\t\"cmpt-form-show\": \"/cmpts/public/form/form_show/form_show_cmpt\"  \n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\",\n\t\"enablePullDownRefresh\": true, \n\t\"navigationBarTitleText\": \"后台-攻略添加\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/album/add/admin_album_add.wxml",
    "content": "<view wx:if=\"{{!isLoad}}\" class=\"margin-top load loading text-l text-grey\"></view>\n<view class=\"main-admin\" wx:if=\"{{isAdmin&&isLoad}}\">\n\t<include src=\"../admin_album_form_tpl.wxml\" /> \n</view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/album/add/admin_album_add.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n "
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/album/admin_album_form_tpl.wxml",
    "content": "<view class=\"form-box shadow\">\n\t<view class=\"form-group\">\n\t\t<view class=\"title must\">标题</view>\n\t</view>\n\n\t<view class=\"form-group\">\n\t\t<input placeholder=\"简短的标题\" placeholder-class=\"phc\" model:value=\"{{formTitle}}\" focus=\"{{formTitleFocus}}\" maxlength=\"50\"></input>\n\t</view>\n\t<view wx:if=\"{{formTitleFocus}}\" class=\"hint-desc error\">{{formTitleFocus}}</view>\n\n\t<view wx:if=\"{{cateIdOptions.length>1}}\"  class=\"form-group arrow\" id=\"formCateId\">\n\t\t<view class=\"title must\">分类</view>\n\t\t<cmpt-picker id=\"cate-picker\" sourceData=\"{{cateIdOptions}}\" bind:select=\"url\" data-type=\"picker\" data-item=\"formCateId\" item=\"{{formCateId}}\"> </cmpt-picker>\n\t</view>\n\t<view wx:if=\"{{formCateIdFocus}}\" class=\"hint-desc error\">{{formCateIdFocus}}</view>\n\n\t<view class=\"form-group\">\n\t\t<view class=\"title must\">排序号<text class=\"text-grey text-normal margin-left-xs\">(小的先显示)</text></view>\n\t\t<input placeholder=\"排序号，小的先显示\" type=\"number\" placeholder-class=\"phc\" model:value=\"{{formOrder}}\" focus=\"{{formOrderFocus}}\" maxlength=\"4\"></input>\n\t</view>\n\t<view wx:if=\"{{formOrderFocus}}\" class=\"hint-desc error\">{{formOrderFocus}}</view>\n\n\n</view>\n\n<view class=\"form-box shadow margin-top-xs\">\n\t<cmpt-form-show id=\"cmpt-form\" mark=\"cmpt-form\" source=\"admin\" isCacheMatch=\"{{false}}\" fields=\"{{fields}}\" forms=\"{{formForms}}\" isDefMatch=\"{{id?false:true}}\">\n\t</cmpt-form-show>\n</view>\n\n\n<button bindtap=\"bindFormSubmit\" class=\"btn-admin margin-top-xs\">提交</button>\n\n<view style=\"height:200rpx\"></view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/album/edit/admin_album_edit.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\nconst validate = require('../../../../../../helper/validate.js');\nconst AdminAlbumBiz = require('../../../../biz/admin_album_biz.js');\nconst AlbumBiz = require('../../../../biz/album_biz.js'); \n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false,\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tif (!pageHelper.getOptions(this, options)) return; \n\n\t\tthis._loadDetail(); \n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () { },\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\t\tawait this._loadDetail();\n\t\tthis.selectComponent(\"#cmpt-form\").reload();\n\t\twx.stopPullDownRefresh();\n\t},\n\n\tmodel: function (e) {\n\t\tpageHelper.model(this, e);\n\t},\n\n\t_loadDetail: async function () {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet id = this.data.id;\n\t\tif (!id) return;\n\n\t\tif (!this.data.isLoad) this.setData(AdminAlbumBiz.initFormData(id)); // 初始化表单数据\n\n\t\tlet params = {\n\t\t\tid\n\t\t};\n\t\tlet opt = {\n\t\t\ttitle: 'bar'\n\t\t};\n\t\tlet album = await cloudHelper.callCloudData('admin/album_detail', params, opt);\n\t\tif (!album) {\n\t\t\tthis.setData({\n\t\t\t\tisLoad: null\n\t\t\t})\n\t\t\treturn;\n\t\t};\n\n\t\tthis.setData({\n\t\t\tisLoad: true,\n\n\t\t\tformTitle: album.ALBUM_TITLE,\n\t\t\tformCateId: album.ALBUM_CATE_ID,\n\t\t\tformOrder: album.ALBUM_ORDER,\n\t\t\n\t\t\tformForms: album.ALBUM_FORMS,\n\t\t});\n\t},\n\n\tbindFormSubmit: async function () {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\t// 数据校验\n\t\tlet data = this.data;\n\t\tdata = validate.check(data, AdminAlbumBiz.CHECK_FORM, this);\n\t\tif (!data) return;\n\n\t\tlet forms = this.selectComponent(\"#cmpt-form\").getForms(true);\n\t\tif (!forms) return;\n\t\tdata.forms = forms;\n\n\t\tdata.cateName = AlbumBiz.getCateName(data.cateId);\n\n\t\ttry {\n\t\t\tlet albumId = this.data.id;\n\t\t\tdata.id = albumId;\n\n\t\t\t// 先修改，再上传 \n\t\t\tawait cloudHelper.callCloudSumbit('admin/album_edit', data);\n\n\t\t\tawait cloudHelper.transFormsTempPics(forms, 'album/', albumId, 'admin/album_update_forms');\n\n\t\t\tlet callback = async () => {\n\n\t\t\t\t// 更新列表页面数据\n\t\t\t\tlet node = {\n\t\t\t\t\t'ALBUM_TITLE': data.title,\n\t\t\t\t\t'ALBUM_CATE_NAME': data.cateName,\n\t\t\t\t\t'ALBUM_ORDER': data.order,\n\t\t\t\t}\n\t\t\t\tpageHelper.modifyPrevPageListNodeObject(albumId, node);\n\n\t\t\t\twx.navigateBack();\n\n\t\t\t}\n\t\t\tpageHelper.showSuccToast('修改成功', 2000, callback);\n\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t}\n\n\t},\n\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t}\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/album/edit/admin_album_edit.json",
    "content": "{\n\t\"usingComponents\": {\n\t\t\"cmpt-img-upload\": \"/cmpts/public/img/img_upload_cmpt\",\n\t\t\"cmpt-form-show\": \"/cmpts/public/form/form_show/form_show_cmpt\"\n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\",\n\t\"enablePullDownRefresh\": true,\n\t\"navigationBarTitleText\": \"后台-攻略修改\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/album/edit/admin_album_edit.wxml",
    "content": "<view wx:if=\"{{isLoad===null}}\" class=\"margin-top load notexist text-l text-grey\"></view>\n<view wx:if=\"{{isLoad===false}}\" class=\"margin-top load loading text-l text-grey\"></view>\n\n<view class=\"main-admin\" wx:if=\"{{isAdmin&&isLoad}}\">\n\t<include src=\"../admin_album_form_tpl.wxml\" /> \n</view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/album/edit/admin_album_edit.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss'; "
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/album/list/admin_album_list.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst AlbumBiz = require('../../../../biz/album_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false,\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return; \n\n\t\t//设置搜索菜单\n\t\tthis._getSearchMenu();  \n\t\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: async function () { },\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () { },\n\n\turl: async function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tbindCommListCmpt: function (e) {\n\t\tpageHelper.commListListener(this, e);\n\t},\n\n\tbindStatusMoreTap: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tlet itemList = ['启用', '停用 (不显示)', '删除'];\n\t\twx.showActionSheet({\n\t\t\titemList,\n\t\t\tsuccess: async res => {\n\t\t\t\tswitch (res.tapIndex) {\n\t\t\t\t\tcase 0: { //启用\n\t\t\t\t\t\te.currentTarget.dataset['status'] = 1;\n\t\t\t\t\t\tawait this._setStatus(e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 1: { //停止 \n\t\t\t\t\t\te.currentTarget.dataset['status'] = 0;\n\t\t\t\t\t\tawait this._setStatus(e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 2: { //删除\n\t\t\t\t\t\tawait this._del(e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tfail: function (res) { }\n\t\t})\n\t},\n\n\tbindMoreTap: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tlet idx = pageHelper.dataset(e, 'idx');\n\n\t\tlet order = this.data.dataList.list[idx].ALBUM_ORDER;\n\t\tlet orderDesc = (order == 0) ? '取消置顶' : '置顶';\n\n\t\tlet vouch = this.data.dataList.list[idx].ALBUM_VOUCH;\n\t\tlet vouchDesc = (vouch == 0) ? '推荐到首页' : '取消首页推荐';\n\n\t\tlet itemList = ['预览', orderDesc, vouchDesc, '生成专属二维码'];\n\n\t\twx.showActionSheet({\n\t\t\titemList,\n\t\t\tsuccess: async res => {\n\t\t\t\tswitch (res.tapIndex) {\n\t\t\t\t\tcase 0: { //预览\n\t\t\t\t\t\tlet id = pageHelper.dataset(e, 'id');\n\t\t\t\t\t\twx.navigateTo({\n\t\t\t\t\t\t\turl: '../../../album/detail/album_detail?id=' + id,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 1: { //置顶 \n\t\t\t\t\t\tlet sort = (order == 0) ? 9999 : 0;\n\t\t\t\t\t\te.currentTarget.dataset['sort'] = sort;\n\t\t\t\t\t\tawait this._setSort(e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 2: { //上首页 \n\t\t\t\t\t\tvouch = (vouch == 0) ? 1 : 0;\n\t\t\t\t\t\te.currentTarget.dataset['vouch'] = vouch;\n\t\t\t\t\t\tawait this._setVouch(e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 3: { //二维码 \n\t\t\t\t\t\tlet title = encodeURIComponent(pageHelper.dataset(e, 'title'));\n\t\t\t\t\t\tlet qr = encodeURIComponent(pageHelper.dataset(e, 'qr')); \n\t\t\t\t\t\twx.navigateTo({\n\t\t\t\t\t\t\turl: `../../setup/qr/admin_setup_qr?title=${title}&qr=${qr}`,\n\t\t\t\t\t\t})\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\n\t\t\t},\n\t\t\tfail: function (res) { }\n\t\t})\n\t},\n\n\t_setSort: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet id = pageHelper.dataset(e, 'id');\n\t\tlet sort = pageHelper.dataset(e, 'sort');\n\t\tif (!id) return;\n\n\t\tlet params = {\n\t\t\tid,\n\t\t\tsort\n\t\t}\n\n\t\ttry {\n\t\t\tawait cloudHelper.callCloudSumbit('admin/album_sort', params).then(res => {\n\t\t\t\tpageHelper.modifyListNode(id, this.data.dataList.list, 'ALBUM_ORDER', sort);\n\t\t\t\tthis.setData({\n\t\t\t\t\tdataList: this.data.dataList\n\t\t\t\t});\n\t\t\t\tpageHelper.showSuccToast('设置成功');\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t}\n\t},\n\n\t_setVouch: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet id = pageHelper.dataset(e, 'id');\n\t\tlet vouch = pageHelper.dataset(e, 'vouch');\n\t\tif (!id) return;\n\n\t\tlet params = {\n\t\t\tid,\n\t\t\tvouch\n\t\t}\n\n\t\ttry {\n\t\t\tawait cloudHelper.callCloudSumbit('admin/album_vouch', params).then(res => {\n\t\t\t\tpageHelper.modifyListNode(id, this.data.dataList.list, 'ALBUM_VOUCH', vouch);\n\t\t\t\tthis.setData({\n\t\t\t\t\tdataList: this.data.dataList\n\t\t\t\t}); \n\t\t\t\tpageHelper.showSuccToast('设置成功');\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t}\n\t},\n\n\t_del: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tlet id = pageHelper.dataset(e, 'id');\n\n\t\tlet params = {\n\t\t\tid\n\t\t}\n\n\t\tlet callback = async () => {\n\t\t\ttry {\n\t\t\t\tlet opts = {\n\t\t\t\t\ttitle: '删除中'\n\t\t\t\t}\n\t\t\t\tawait cloudHelper.callCloudSumbit('admin/album_del', params, opts).then(res => {\n\t\t\t\t\tpageHelper.delListNode(id, this.data.dataList.list, '_id');\n\t\t\t\t\tthis.data.dataList.total--;\n\t\t\t\t\tthis.setData({\n\t\t\t\t\t\tdataList: this.data.dataList\n\t\t\t\t\t});\n\t\t\t\t\tpageHelper.showSuccToast('删除成功');\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tconsole.log(err);\n\t\t\t}\n\t\t}\n\t\tpageHelper.showConfirm('确认删除？删除不可恢复', callback);\n\n\t},\n\n\t_setStatus: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tlet id = pageHelper.dataset(e, 'id');\n\t\tlet status = Number(pageHelper.dataset(e, 'status'));\n\t\tlet params = {\n\t\t\tid,\n\t\t\tstatus\n\t\t}\n\n\t\ttry {\n\t\t\tawait cloudHelper.callCloudSumbit('admin/album_status', params).then(res => {\n\t\t\t\tpageHelper.modifyListNode(id, this.data.dataList.list, 'ALBUM_STATUS', status, '_id');\n\t\t\t\tthis.setData({\n\t\t\t\t\tdataList: this.data.dataList\n\t\t\t\t});\n\t\t\t\tpageHelper.showSuccToast('设置成功');\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t}\n\t},\n\n\t_getSearchMenu: function () {\n\t\tlet cateIdOptions = AlbumBiz.getCateList();\n\n\t\tlet sortItem1 = [{ label: '分类', type: '', value: 0 }]; \n\t\tsortItem1 = sortItem1.concat(cateIdOptions);\n\n\t\tlet sortItem2 = [\n\t\t\t{ label: '排序', type: '', value: 0 }\n\t\t];\n\n\t\tlet sortItems = [];\n\t\tif (sortItem1.length > 2) sortItems.push(sortItem1);\n\n\t\tlet sortMenus = [\n\t\t\t{ label: '全部', type: '', value: '' },\n\t\t\t{ label: '正常', type: 'status', value: 1 },\n\t\t\t{ label: '停用', type: 'status', value: 0 },\n\t\t\t{ label: '最新', type: 'sort', value: 'new' },\n\t\t\t{ label: '首页推荐', type: 'vouch', value: 'vouch' },\n\t\t\t{ label: '置顶', type: 'top', value: 'top' },\n\t\t]\n\t\tthis.setData({\n\t\t\tcateIdOptions,\n\t\t\tsortItems,\n\t\t\tsortMenus\n\t\t})\n\n\t}\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/album/list/admin_album_list.json",
    "content": "{\n\t\"usingComponents\": { \n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\", \n\t\"disableScroll\": true, \n\t\"navigationBarTitleText\": \"后台-攻略\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/album/list/admin_album_list.wxml",
    "content": "<block wx:if=\"{{isAdmin}}\">\n    <cmpt-comm-list source='admin' type=\"admin-album-list\" search=\"{{search}}\" _menus=\"{{sortMenus}}\" _items=\"{{sortItems}}\" route=\"admin/album_list\" sortMenusDefaultIndex=\"0\" topBottom=\"50\" placeholder=\"搜索标题\" bind:list=\"bindCommListCmpt\"> \n\n        <view slot=\"searchEnd\">\n            <button bindtap=\"url\" data-url=\"../add/admin_album_add\" class=\"btn radius bg-admin text-white margin-right-s\"><text class=\"icon-roundadd margin-right-xxs\"></text>添加新攻略</button>\n        </view>\n        <!-- List Begin -->\n        <view class=\"admin-comm-list\">\n            <view wx:if=\"{{dataList && dataList.total }}\" class=\"load text-grey\">共有{{dataList.total}}条符合条件记录</view>\n\n            <view class=\"item\" wx:for=\"{{dataList.list}}\" wx:key=\"key\">\n\t\t\t\t<view class=\"no\">{{index+1}}</view>\n                <view class=\"header\">\n                    <view class=\"left text-cut\"><text wx:if=\"{{item.ALBUM_ORDER==0}}\" class=\"text-black margin-right-xxs\" style=\"font-weight:normal;font-size:24rpx\">[置顶]</text><text wx:if=\"{{item.ALBUM_VOUCH==1}}\" class=\"text-black margin-right-xxs\" style=\"font-weight:normal;font-size:24rpx\">[首页推荐]</text> {{item.ALBUM_TITLE}}\n                    </view>\n                    <view class=\"right\">\n                        <text wx:if=\"{{item.ALBUM_STATUS==1}}\" class=\"text-black\">「正常」</text>\n                        <text wx:elif=\"{{item.ALBUM_STATUS==0}}\" class=\"text-orange\">「停用」</text>\n                    </view>\n                </view>\n\n                <view class=\"info\">\n                    <view wx:if=\"{{cateIdOptions.length>1}}\" class=\"info-item\">\n                        <view class=\"title\">分类</view>\n                        <view class=\"mao\">：</view>\n                        <view class=\"content\">『{{item.ALBUM_CATE_NAME}}』</view>\n                    </view>\n\n                    <view class=\"info-item\">\n                        <view class=\"title\">排序号</view>\n                        <view class=\"mao\">：</view>\n                        <view class=\"content\">{{item.ALBUM_ORDER}} <text class=\"margin-left-xxs text-grey\">(小的先显示)</text></view>\n                    </view> \n\n                    <view class=\"info-item\">\n                        <view class=\"title\">创建</view>\n                        <view class=\"mao\">：</view>\n                        <view class=\"content\">{{item.ALBUM_ADD_TIME}}</view>\n                    </view>\n  \n                    <view class=\"oprt\">\n                        <view bindtap=\"url\" data-url=\"../edit/admin_album_edit?id={{item._id}}\" class=\"btn round margin-right-s\"><text class=\"icon-edit margin-right-xxs\"></text>编辑</view> \n\n                        <view bindtap=\"bindStatusMoreTap\" data-id=\"{{item._id}}\" class=\"btn margin-right-s\">状态管理..</view>  \n\n                        <view bindtap=\"bindMoreTap\" data-id=\"{{item._id}}\" data-idx=\"{{index}}\" data-qr=\"{{item.ALBUM_QR}}\" data-title=\"{{item.ALBUM_TITLE}}\" class=\"btn margin-right-s\">更多...</view> \n\n\t\t\t\t\t\t<view bindtap=\"url\" data-url=\"../../../album/detail/album_detail?id={{item._id}}\" class=\"btn margin-right-s\">预览</view> \n\n                    </view>\n                </view>\n            </view>\n\n        </view>\n        <!-- List END -->\n\n        <!--load begin-->\n        <import src=\"../../../../../../tpls/public/list_load_tpl.wxml\" />\n        <template is=\"listLoadTpl\" data=\"{{dataList,skin:'text-grey'}}\" />\n        <!--load end-->\n\n\n    </cmpt-comm-list>\n\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/album/list/admin_album_list.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n\npage {\n\tbackground-color: #f8f8f8;\n}\n\n"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/content/admin_content.js",
    "content": "const AdminBiz = require('../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../helper/page_helper.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tformContent: [{\n\t\t\ttype: 'text',\n\t\t\tval: '',\n\t\t}]\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet parent = pageHelper.getPrevPage(2);\n\t\tif (!parent) return;\n\n\t\tlet formContent = parent.data.formContent;\n\t\tif (formContent && formContent.length > 0)\n\t\t\tthis.setData({\n\t\t\t\tformContent\n\t\t\t});\n\t},\n\n\n\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\n\t},\n\n\tmodel: function (e) {\n\t\tpageHelper.model(this, e);\n\t},\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tbindSaveTap: function (e) {\n\t\tlet formContent = this.selectComponent(\"#contentEditor\").getNodeList();\n\n\t\tlet parent = pageHelper.getPrevPage(2);\n\t\tif (!parent) return;\n\n\t\tparent.setData({\n\t\t\tformContent\n\t\t}, () => {\n\t\t\tparent._setContentDesc();\n\t\t});\n\n\t\twx.navigateBack();\n\t}\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/content/admin_content.json",
    "content": "{\n\t\"usingComponents\": { \n\t\t\"cmpt-editor\": \"/cmpts/public/editor/editor_cmpt\"\n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\", \n\t\"navigationBarTitleText\": \"后台-详细内容编辑\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/content/admin_content.wxml",
    "content": "<block wx:if=\"{{isAdmin}}\">\n\t<view class=\"main-admin\"> \n\t\t<view class=\"form-box shadow\">\n\t\t\t<view class=\"form-group\" style=\"width: 100%;\">\n\t\t\t\t<cmpt-editor nodeList=\"{{formContent}}\" viewMode=\"{{true}}\" style=\"width: 100%;\" id=\"contentEditor\"></cmpt-editor>\n\t\t\t</view>\n\t\t</view>   \n\t</view> \n\t\n\t<view class=\"btn-bottom-admin\">\n\t\t<view bindtap=\"url\" data-type=\"back\" class=\"return\">不保存,返回</view>\n\t\t<view bindtap=\"bindSaveTap\" class=\"save\">保存</view>\n\t</view>\n\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/content/admin_content.wxss",
    "content": "@import '../../../../../style/public/admin.wxss';\n\n.main-admin {\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tpadding: 30rpx 20rpx;\n\tpadding-bottom: 200rpx;\n}\n\n.form-group {\n\tpadding: 1rpx 1rpx;\n\toverflow: hidden;\n}\n\n.oprt {\n\tdisplay: flex;\n\twidth: 100%;\n\tjustify-content: space-around;\n}\n\n.oprt button {\n\twidth: 45%;\n}\n\n.bottom-oprt {\n\tposition: fixed;\n\tbottom: 0;\n\theight: 130rpx;\n\tbackground-color: #f8f8f8;\n\tdisplay: flex;\n\tjustify-content: space-around;\n\talign-items: center;\n\tborder-top: 1rpx solid #ccc;\n\tz-index: 99999;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/index/home/admin_home.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tthis._loadDetail();\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\t\tawait this._loadDetail();\n\t\twx.stopPullDownRefresh();\n\t},\n\n\t_loadDetail: async function () {\n\n\t\tlet admin = AdminBiz.getAdminToken();\n\t\tthis.setData({\n\t\t\tisLoad: true,\n\t\t\tadmin\n\t\t});\n\n\t\ttry {\n\t\t\tlet opts = {\n\t\t\t\ttitle: 'bar'\n\t\t\t}\n\t\t\tlet res = await cloudHelper.callCloudData('admin/home', {}, opts);\n\t\t\tthis.setData({\n\t\t\t\tstat: res\n\t\t\t});\n\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t}\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tbindMoreTap: function (e) {\n\t\tlet itemList = ['取消所有首页推荐'];\n\t\twx.showActionSheet({\n\t\t\titemList,\n\t\t\tsuccess: async res => {\n\t\t\t\tlet idx = res.tapIndex;\n\n\t\t\t\tif (idx == 0) {\n\t\t\t\t\tthis._clearVouch();\n\t\t\t\t}\n\n\t\t\t},\n\t\t\tfail: function (res) { }\n\t\t})\n\t},\n\n\t_clearVouch: async function (e) {\n\t\tlet cb = async () => {\n\t\t\ttry {\n\t\t\t\tawait cloudHelper.callCloudSumbit('admin/clear_vouch').then(res => {\n\t\t\t\t\tpageHelper.showSuccToast('操作成功');\n\t\t\t\t})\n\t\t\t} catch (err) {\n\t\t\t\tconsole.log(err);\n\t\t\t}\n\t\t};\n\t\tpageHelper.showConfirm('您确认清除所有首页推荐？', cb)\n\t},\n\n\tbindExitTap: function (e) {\n\n\t\tlet callback = function () {\n\t\t\tAdminBiz.clearAdminToken();\n\t\t\twx.reLaunch({\n\t\t\t\turl: pageHelper.fmtURLByPID('/pages/my/index/my_index'),\n\t\t\t});\n\t\t}\n\t\tpageHelper.showConfirm('您确认退出?', callback);\n\t},\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/index/home/admin_home.json",
    "content": "{\n\t\"usingComponents\": {\n\t\t\"cmpt-foot\": \"/cmpts/biz/foot/foot_cmpt\"\n\t},\n\t\"enablePullDownRefresh\": true,\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\",\n\t\"navigationBarTitleText\": \"后台管理\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/index/home/admin_home.wxml",
    "content": "<view wx:if=\"{{!isLoad}}\" class=\"margin-top load loading text-l text-admin\"></view>\n\n<view class=\"main-admin\" wx:if=\"{{isLoad && isAdmin}}\">\n\n\t<view class=\"admin-info bg-admin\">\n\t\t<view class=\"pic\"><text class=\"icon-profilefill\"></text></view>\n\t\t<view class=\"right\">\n\t\t\t<view class=\"name\">\n\t\t\t\t<text class=\"text-xl\">{{admin.name}}</text>\n\n\t\t\t\t<text wx:if=\"{{admin.type==1}}\" class=\"tag small bg-orange light radius margin-left-s\">超级管理员</text>\n\t\t\t\t<text wx:if=\"{{admin.type==0}}\" class=\"tag small bg-green radius margin-left-s\">一般管理员</text>\n\n\t\t\t</view>\n\t\t\t<view class=\"desc text-s\">共登录{{admin.cnt}}次，上次{{admin.last}}</view>\n\t\t</view>\n\t\t<view class=\"exit-admin\" bindtap=\"bindExitTap\"><text class=\"icon-exit\"></text></view>\n\t</view>\n\n\n\t<view class=\"comm-list grid col-{{stat.length}}\">\n\t\t<view wx:for=\"{{stat}}\" wx:key=\"key\" class=\"item\">{{item.cnt||'0'}}<text class=\"text-black\">{{item.title}}</text></view>\n\n\t</view>\n\n\t<view class=\"bar bg-white solid-bottom margin-top-s \">\n\t\t<view class=\"action\">\n\t\t\t<text class=\"icon-title\"></text>功能管理\n\t\t</view>\n\t</view>\n\n\t<view class=\"comm-list grid col-3\">\n\t\t<view class=\"item\" bindtap=\"url\" data-url=\"../../user/list/admin_user_list\"> <text class=\"icon-group_fill text-green\"></text> <text class=\"text-black\">用户管理</text>\n\t\t</view>\n\n\t\t<view class=\"item\" bindtap=\"url\" data-url=\"../../news/list/admin_news_list\"> <text class=\"icon-form text-darkgreen\"></text> <text class=\"text-black\">内容管理</text>\n\t\t</view>\n\n\t\t<view class=\"item\" bindtap=\"url\" data-url=\"../../meet/list/admin_meet_list\"> <text class=\"icon-activityfill text-blue\"></text> <text class=\"text-black\">预约管理</text>\n\t\t</view>\n\n\n\t\t<view class=\"item\" bindtap=\"url\" data-url=\"../../album/list/admin_album_list\"> <text class=\"icon-picfill text-red\"></text> <text class=\"text-black\">攻略管理</text>\n\t\t</view>\n\t\t<view class=\"item\" bindtap=\"url\" data-url=\"../../product/list/admin_product_list\"> <text class=\"icon-album text-cyan\"></text> <text class=\"text-black\">景点管理</text>\n\t\t</view>\n\t   \n\t</view>\n\n\n\t<!-- BOTTOM begin -->\n\t<view class=\"comm-list menu  margin-top\">\n\n\t\t<view class=\"item arrow\" bindtap=\"url\" data-url=\"../../setup/about_list/admin_setup_about_list\">\n\t\t\t<view class=\"content\">\n\t\t\t\t<text class=\"icon-edit text-darkgreen\"></text>\n\t\t\t\t<text class=\"text-black\">编辑 - 景区介绍</text>\n\t\t\t</view>\n\t\t</view>\n\n\n\t\t<view class=\"item arrow\" bindtap=\"url\" data-url=\"../../setup/qr/admin_setup_qr\">\n\t\t\t<view class=\"content\">\n\t\t\t\t<text class=\"icon-qr_code text-mauve\"></text>\n\t\t\t\t<text class=\"text-black\">小程序二维码</text>\n\t\t\t</view>\n\t\t</view>\n\t</view>\n\n\t<view class=\"comm-list menu\">\n\t\t<view wx:if=\"{{isSuperAdmin}}\" class=\"item arrow\" bindtap=\"url\" data-url=\"../../mgr/list/admin_mgr_list\">\n\t\t\t<view class=\"content\">\n\t\t\t\t<text class=\"icon-profile text-red\"></text>\n\t\t\t\t<text class=\"text-black\">系统管理员管理</text>\n\t\t\t</view>\n\t\t</view>\n\t\t<view class=\"item arrow\" bindtap=\"url\" data-url=\"../../mgr/pwd/admin_mgr_pwd\">\n\t\t\t<view class=\"content\">\n\t\t\t\t<text class=\"icon-lock text-orange\"></text>\n\t\t\t\t<text class=\"text-black\">修改我的管理员密码</text>\n\t\t\t</view>\n\t\t</view>\n\t\t<view class=\"item arrow\" bindtap=\"url\" data-url=\"../../mgr/log/admin_log_list\">\n\t\t\t<view class=\"content\">\n\t\t\t\t<text class=\"icon-footprint text-brown\"></text>\n\t\t\t\t<text class=\"text-black\">管理员操作日志</text>\n\t\t\t</view>\n\t\t</view> \n\n\t</view>\n\n\t<view class=\"comm-list menu margin-bottom-xl\">\n\t\t<view   class=\"item arrow\" bindtap=\"bindMoreTap\">\n\t\t\t<view class=\"content\">\n\t\t\t\t<text class=\"icon-settings text-grey\"></text>\n\t\t\t\t<text class=\"text-black\">更多设置</text>\n\t\t\t</view>\n\t\t</view>\n\t\t</view>\n\n\t<!-- BOTTOM END -->\n\t<button bindtap=\"bindExitTap\" class=\"btn-admin\">退出登录</button>\n\n\t<view class=\"foot-bottom\">\n\t\t<cmpt-foot />\n\t</view>\n\n</view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/index/home/admin_home.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n\n.main-admin {\n\tpadding: 0;\n}\n\n.admin-info {\n\theight: 200rpx;\n\twidth: 100%;\n\tcolor: #fff;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: center;\n\tposition: relative;\n}\n\n.admin-info .pic {\n\twidth: 100rpx;\n\theight: 100rpx;\n\tfont-size: 70rpx;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tmargin-right: 20rpx; \n\tborder-radius:20rpx;\n\tmargin-left:20rpx;\n}\n\n.admin-info .right {\n\tflex: 1;\n\tdisplay: flex;\n\tflex-direction: column;\n}\n\n.admin-info .right .name {\n\tfont-size: 32rpx;\n\tline-height: 1.8;\n}\n\n.admin-info .right .desc {\n\tfont-size: 24rpx;\n\tline-height: 1.3;\n}\n\n.admin-info .exit-admin {\n\tposition: absolute;\n\ttop: 12rpx;\n\tright: 12rpx;\n\tfont-size: 45rpx;\n}\n\n\n.main-admin .comm-list,\n.main-admin .bar {\n\tbackground-color: #fff;\n\twidth: 100%;\n}\n\n.main-admin .exit {\n\twidth: 100%;\n\tpadding: 0 20rpx;\n\tmargin-bottom: 50rpx;\n}\n\n.main-admin .exit button {\n\twidth: 100%;\n\tcolor: #fff;\n\theight: 70rpx;\n}\n\n.grid.col-6>view {\n\twidth: 16.66%;\n}\n\n.foot-bottom {\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tbottom: 50rpx;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/index/login/admin_login.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');  \n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tname: '',\n\t\tpwd: '',\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: function (options) {\n\t\tAdminBiz.clearAdminToken();\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tbindBackTap: function (e) {\n\t\twx.reLaunch({\n\t\t\turl: pageHelper.fmtURLByPID('/pages/my/index/my_index'),\n\t\t});\n\t},\n\n\tbindLoginTap: async function (e) {\n\t\treturn AdminBiz.adminLogin(this, this.data.name, this.data.pwd);\n\t}\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/index/login/admin_login.json",
    "content": "{\n\t\"usingComponents\": {\n\t\t\"cmpt-foot\": \"/cmpts/biz/foot/foot_cmpt\"\n\t},\n\t\"disableScroll\": true,\n\t\"navigationBarBackgroundColor\": \"#ffffff\",\n\t\"navigationBarTextStyle\": \"black\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/index/login/admin_login.wxml",
    "content": "<view class=\"main-admin bg-admin\">\n\n\t<view class=\"login shadow\">\n\n\t\t<view class=pic\"><text class=\"icon-settingsfill text-green\"></text></view>\n\t\t<view class=\"hint\">后台管理系统</view>\n\n\t\t<view class=\"form-group margin-top\">\n\t\t\t<view class=\"title\">账号：</view>\n\t\t\t<input placeholder=\"请输入管理员账号\" maxlength=\"30\" placeholder-class=\"phc\" model:value=\"{{name}}\"></input>\n\t\t</view>\n\n\t\t<view class=\"form-group\">\n\t\t\t<view class=\"title\">密码：</view>\n\t\t\t<input placeholder=\"请输入管理员密码\" maxlength=\"30\" type=\"password\" placeholder-class=\"phc\" model:value=\"{{pwd}}\"></input>\n\t\t</view>\n\n\t\t<button class=\"btn bg-admin margin-bottom\" bindtap=\"bindLoginTap\">点击登录</button>\n\t\t<view class=\"return text-grey\">本系统仅限于系统管理员登录</view>\n\t\t<view bindtap=\"bindBackTap\" class=\"return text-grey\"><text class=\"icon-back\"></text>返回用户端</view>\n\n\n\t</view>\n\n\t<view class=\"foot-bottom\">\n\t \n\t</view>\n\n</view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/index/login/admin_login.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n\n.main-admin {\n\twidth: 100%;\n\tmin-height: 100vh;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: center;\n\tposition: relative; \n}\n\n.login {\n\twidth: 500rpx;\n\tbackground-color: #fff;\n\tmin-height: 550rpx;\n\tborder-radius: 20rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: space-between;\n\talign-items: center;\n\tpadding: 50rpx 20rpx;\n\tmargin-top: -100rpx;\n}\n\n.login button {\n\twidth: 85%;\n\tcolor: #fff;\n\tfont-size: 32rpx;\n}\n\n.login .hint {\n\twidth: 100%;\n\tcolor: #000;\n\tfont-weight: bold;\n\tfont-size: 36rpx;\n\ttext-align: center;\n}\n\n.login .return {\n\twidth: 100%;\n\tfont-size: 30rpx;\n\ttext-align: center;\n\tfont-size: 26rpx;\n}\n\n.pic {\n\twidth: 180rpx;\n\theight: 180rpx;\n\tfont-size: 130rpx;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n}\n\n.foot-bottom {\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tposition: absolute;\n\tbottom: 50rpx;\n}\n\n.site-footer {\n\tcolor: #fff !important;\n}\n\n.form-group .title {\n    color:#333;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/cover/admin_meet_cover.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst dataHelper = require('../../../../../../helper/data_helper.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\n\t\ttitle: '',\n\t\tstatus: '',\n\n\t\tmode: '',\n\t\tdesc: '',\n\t\tpic: '',\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet parent = pageHelper.getPrevPage(2);\n\t\tif (!parent) return; \n\n\t\tlet formStyleSet = parent.data.formStyleSet;\n\t\tlet title = parent.data.formTitle;\n\t\tlet status = parent.data.beginSetDesc;\n\t\tthis.setData({ \n\t\t\ttitle,\n\t\t\tstatus,\n\t\t\t...formStyleSet\n\t\t});\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: function () {\n\n\t},\n\n\t/**\n\t * 页面上拉触底事件的处理函数\n\t */\n\tonReachBottom: function () {\n\n\t},\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tbindChooseImgTap: function (e) {\n\t\tlet that = this;\n\t\twx.chooseMedia({\n\t\t\tcount: 1,\n\t\t\tmediaType: ['image'],\n\t\t\tsizeType: ['compressed'], //可以指定是原图还是压缩图，默认二者都有\n\t\t\tsourceType: ['album', 'camera'], //从相册选择\n\t\t\tsuccess: async (res) => {\n\t\t\t\tlet pic = res.tempFiles[0].tempFilePath;\n\t\t\t\tthat.setData({\n\t\t\t\t\tpic\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t},\n\tcatchDelImgTap: function (e) {\n\t\tlet that = this;\n\t\tlet callback = function () {\n\t\t\tthat.setData({\n\t\t\t\tpic: ''\n\t\t\t});\n\t\t}\n\t\tpageHelper.showConfirm('确定要删除该图片吗？', callback);\n\t},\n\n\tbindSaveTap: function (e) {\n\t\tlet parent = pageHelper.getPrevPage(2);\n\t\tif (!parent) return;\n\n\t\tif (!this.data.pic) return pageHelper.showModal('请上传封面图片');\n\n\t\tparent.setData({\n\t\t\tformStyleSet: {\n\t\t\t\tdesc: dataHelper.fmtText(this.data.desc),\n\t\t\t\tpic: this.data.pic\n\t\t\t}\n\t\t});\n\n\t\twx.navigateBack();\n\n\t}\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/cover/admin_meet_cover.json",
    "content": "{\n\t\"usingComponents\": {  \n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\", \n\t\"navigationBarTitleText\": \"后台-预约封面设置\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/cover/admin_meet_cover.wxml",
    "content": "<view class=\"main-admin\">\n\t<view class=\"form-box-main\">\n\t\t<view class=\"form-box shadow\">\n\t\t\t<!--\n\t\t\t<view class=\"form-group\">\n\t\t\t\t<view class=\"title must\">样式</view>\n\t\t\t\t<cmpt-picker mark=\"cover\" style=\"flex:1\" model:item=\"{{mode}}\" sourceDataStr=\"upimg=上图下文样式,leftbig=左图右文样式,bigtext=大标题样式\" />\n\t\t\t</view> \n\t\t\t -->\n\n\t\t\t<view class=\"form-group\">\n\t\t\t\t<view class=\"action text-bold text-l\">\n\t\t\t\t\t简要描述\n\t\t\t\t</view>\n\t\t\t\t<view class=\"action\">\n\t\t\t\t\t{{desc.length}}/100\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t\t<view class=\"form-group align-start\">\n\t\t\t\t<textarea name=\"content\" placeholder-class=\"phc\" placeholder=\"填写简要描述\" style=\"height:150rpx\" model:value=\"{{desc}}\" maxlength=\"100\" auto-height=\"{{false}}\"></textarea>\n\t\t\t</view>\n\n\t\t\t<view class=\"form-group\">\n\t\t\t\t<view class=\"title must\">\n\t\t\t\t\t封面图 <text class=\"text-normal\">（必填）</text>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"cover-img\">\n\t\t\t\t\t<image lazy-load=\"{{true}}\" class=\"loading\" mode='aspectFill' wx:if=\"{{pic}}\" src=\"{{pic}}\" bindtap=\"url\" data-type='img' data-url=\"{{pic}}\"></image>\n\t\t\t\t\t<view wx:if=\"{{pic}}\" class=\"close-img\" catchtap=\"catchDelImgTap\"><text class=\"icon-refresh margin-left-xs\"></text><text class=\"test-admin margin-left-xs\" style=\"font-size:32rpx\">更换图片</text></view>\n\t\t\t\t\t<view class=\"upload-img\"  wx:if=\"{{!pic}}\" catchtap=\"bindChooseImgTap\"><text class=\"icon-cameraadd\"></text><text class=\"test-admin\" style=\"font-size:32rpx\">上传图片</text></view>\n\t\t\t\t</view>\n\t\t\t</view> \n\t\t</view>\n\t</view>\n\n\t<view class=\"demo\">\n\t\t<view class=\"demo-title\">效果图</view>\n\n\t\t<view class=\"comm-list-box\"> \n\n\t\t\t<!--左大图 Begin-->\n\t\t\t<view class=\"item shadow item-leftbig {{!pic?'nopic':''}} margin-top-xs\">\n\t\t\t\t<image wx:if=\"{{pic}}\" mode=\"aspectFill\" lazy-load=\"{{true}}\" class=\"leftbig-left loading\" src=\"{{pic}}\">\n\t\t\t\t</image>\n\t\t\t\t<view class=\"leftbig-right\">\n\t\t\t\t\t<view class=\"leftbig-title content-cut-one\">{{title||'演示标题'}}</view>\n\t\t\t\t\t<view class=\"leftbig-desc\">\n\t\t\t\t\t\t<text class=\"content-cut-three\">{{desc||'简要描述未填写'}}</text>\n\t\t\t\t\t</view>\n\t\t\t\t\t<view class=\"data\"> \n\t\t\t\t\t\t<view class=\"bottom-status\"><text class=\"icon-remind margin-right-xxs\"></text>{{status||'9天可预约'}}</view>\n\t\t\t\t\t</view>\n\n\t\t\t\t</view>\n\n\n\t\t\t</view>\n\t\t\t<!--左大图 END--> \n\t \n\t\t</view>\n\n\t</view>\n</view>\n\n\n<view class=\"btn-bottom-admin\">\n\t<view bindtap=\"url\" data-type=\"back\" class=\"return\">不保存,返回</view>\n\t<view bindtap=\"bindSaveTap\" class=\"save\">保存封面设置</view>\n</view>\n\n"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/cover/admin_meet_cover.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n@import '../../../../../../style/public/comm_box_list.wxss';\n\n.form-box-main {\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tpadding: 0rpx 20rpx;\n}\n\n.demo {\n\tbackground-color: #ffff;\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: row;\n\tjustify-content: flex-start;\n\talign-items: center;\n}\n\n.demo {\n\tbackground-color: #f2f2f2;\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: flex-start;\n\talign-items: center;\n\tpadding: 0 20rpx;\n}\n\n.demo .demo-title {\n\twidth: 100%;\n\tbackground-color: #fff;\n\tpadding: 10rpx 20rpx;\n\tfont-size: 32rpx;\n\tcolor: #333;\n\ttext-align: center;\n} \n \n\n.form-group .upload-img {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\toverflow: hidden;\n\tflex: 1;\n}\n\n.form-group .cover-img {\n\tflex: 1;\n\twidth: 100%;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-end;\n}\n\n.form-group .cover-img image {\n\twidth: 60rpx;\n\theight: 60rpx;\n\tborder-radius: 5rpx;\n}\n\n.form-group .cover-img .close-img,\n.form-group .cover-img .upload-img { \n\theight: 60rpx;\n\tborder-radius: 5rpx;\n\ttext-align: center;\n\tdisplay: flex;\n\tjustify-content: flex-end;\n\talign-items: center;\n\tfont-size: 50rpx;\n\tcolor: orange; \n\tmin-width: 80rpx;\n} \n \n.form-group .cover-img .upload-img {\n\tcolor: #999;\n\tfont-weight: normal; \n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/edit/admin_meet_edit.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst PublicBiz = require('../../../../../../comm/biz/public_biz.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\nconst timeHelper = require('../../../../../../helper/time_helper.js');\nconst validate = require('../../../../../../helper/validate.js');\nconst AdminMeetBiz = require('../../../../biz/admin_meet_biz.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false,\n\t\tid: null,\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tpageHelper.getOptions(this, options);\n\n\t\tthis.setData(await AdminMeetBiz.initFormData()); // 初始化表单数据   \n\n\t\tawait this._loadDetail();\n\n\t\tthis._setContentDesc();\n\t},\n\n\t_loadDetail: async function () {\n\t\tlet id = this.data.id;\n\t\tif (!id) return;\n\n\t\tthis.formSetBarTitleByAddEdit(id, '后台-预约');\n\n\t\tlet params = {\n\t\t\tid\n\t\t};\n\t\tlet opt = {\n\t\t\ttitle: 'bar'\n\t\t};\n\t\tlet meet = await cloudHelper.callCloudData('admin/meet_detail', params, opt);\n\n\t\tif (!meet) {\n\t\t\tthis.setData({\n\t\t\t\tisLoad: null\n\t\t\t})\n\t\t\treturn;\n\t\t}\n\n\t\tthis.setData({\n\t\t\tisLoad: true,\n\n\n\t\t\t// 表单数据   \n\t\t\tformTitle: meet.MEET_TITLE,\n\t\t\tformTypeId: meet.MEET_TYPE_ID,\n\t\t\tformContent: meet.MEET_CONTENT,\n\t\t\tformOrder: meet.MEET_ORDER,\n\t\t\tformStyleSet: meet.MEET_STYLE_SET,\n\n\t\t\tformDaysSet: meet.MEET_DAYS_SET,\n\n\t\t\tformIsShowLimit: meet.MEET_IS_SHOW_LIMIT,\n\n\t\t\tformFormSet: meet.MEET_FORM_SET,\n\t\t});\n\t},\n\n\t// 编辑或者添加设置标题\n\tformSetBarTitleByAddEdit(id, title) {\n\t\ttitle = id ? title + '编辑' : title + '添加',\n\t\t\twx.setNavigationBarTitle({\n\t\t\t\ttitle\n\t\t\t});\n\t}, \n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\t\tawait this._loadDetail();\n\t\twx.stopPullDownRefresh();\n\t},\n\n\tmodel: function (e) {\n\t\tpageHelper.model(this, e);\n\t},\n\n\tbindFormSetCmpt: function (e) {\n\t\tthis.setData({\n\t\t\tformFormSet: e.detail,\n\t\t});\n\t},\n\n\tbindFormAddSubmit: async function () {\n\t\tpageHelper.formClearFocus(this);\n\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet data = this.data;\n\t\tif (data.formTitle.length <= 0) return pageHelper.formHint(this, 'formTitle', '请填写「标题」');\n\n\t\tif (data.formTypeId.length <= 0) return pageHelper.formHint(this, 'formTypeId', '请选择「分类」');\n\n\t\tif (data.formStyleSet.pic.length <= 0) {\n\t\t\tpageHelper.anchor('formStyleSet', this);\n\t\t\treturn pageHelper.formHint(this, 'formStyleSet', '封面图片未设置');\n\t\t}\n\t\tif (data.formDaysSet.length <= 0) {\n\t\t\tpageHelper.anchor('formDaysSet', this);\n\t\t\treturn pageHelper.formHint(this, 'formDaysSet', '请配置「可预约时段」');\n\t\t}\n\t\tif (data.formFormSet.length <= 0) return pageHelper.showModal('请至少设置一项「用户填写资料」');\n\n\t\tif (data.contentDesc.includes('未填写'))\n\t\t\treturn pageHelper.formHint(this, 'formContent', '请填写「详细介绍」');\n\n\t\tdata = validate.check(data, AdminMeetBiz.CHECK_FORM, this);\n\t\tif (!data) return;\n\t\tdata.typeName = AdminMeetBiz.getTypeName(data.typeId);\n\n\t\ttry {\n\t\t\t// 先创建，再上传 \n\t\t\tlet result = await cloudHelper.callCloudSumbit('admin/meet_insert', data);\n\t\t\tlet meetId = result.data.id;\n\n\t\t\tlet formContent = this.data.formContent;\n\t\t\tif (formContent && formContent.length > 0) {\n\t\t\t\twx.showLoading({\n\t\t\t\t\ttitle: '提交中...',\n\t\t\t\t\tmask: true\n\t\t\t\t});\n\n\t\t\t\tlet content = await cloudHelper.transRichEditorTempPics(formContent, 'meet/', meetId, 'admin/meet_update_content');\n\t\t\t\tthis.setData({\n\t\t\t\t\tformContent: content\n\t\t\t\t});\n\n\t\t\t}\n\n\t\t\t// 样式 提交处理\n\t\t\tlet formStyleSet = this.data.formStyleSet;\n\t\t\twx.showLoading({\n\t\t\t\ttitle: '提交中...',\n\t\t\t\tmask: true\n\t\t\t});\n\t\t\tif (!await AdminMeetBiz.updateMeetStyleSet(this, meetId, formStyleSet)) return;\n\n\t\t\tlet callback = async function () {\n\t\t\t\tPublicBiz.removeCacheList('admin-meet');\n\t\t\t\tPublicBiz.removeCacheList('meet-list');\n\t\t\t\twx.navigateBack();\n\n\t\t\t}\n\t\t\tpageHelper.showSuccToast('添加成功', 2000, callback);\n\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t}\n\n\t},\n\n\tbindFormEditSubmit: async function () {\n\t\tpageHelper.formClearFocus(this);\n\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet data = this.data;\n\t\tif (data.formTitle.length <= 0) return pageHelper.formHint(this, 'formTitle', '请填写「标题」');\n\n\t\tif (data.formTypeId.length <= 0) return pageHelper.formHint(this, 'formTypeId', '请选择「分类」');\n\n\t\tif (data.formStyleSet.pic.length <= 0) {\n\t\t\tpageHelper.anchor('formStyleSet', this);\n\t\t\treturn pageHelper.formHint(this, 'formStyleSet', '封面图片未设置');\n\t\t}\n\t\tif (data.formDaysSet.length <= 0) {\n\t\t\tpageHelper.anchor('formDaysSet', this);\n\t\t\treturn pageHelper.formHint(this, 'formDaysSet', '请配置「可预约时段」');\n\t\t}\n\t\tif (data.formFormSet.length <= 0) return pageHelper.showModal('请至少设置一项「用户填写资料」');\n\n\t\tdata = validate.check(data, AdminMeetBiz.CHECK_FORM, this);\n\t\tif (!data) return;\n\t\tdata.typeName = AdminMeetBiz.getTypeName(data.typeId);\n\n\t\ttry {\n\t\t\tlet meetId = this.data.id;\n\t\t\tdata.id = meetId;\n\n\t\t\t// 先修改，再上传 \n\t\t\tawait cloudHelper.callCloudSumbit('admin/meet_edit', data);\n\n\t\t\t// 富文本 提交处理\n\t\t\tlet formContent = this.data.formContent;\n\t\t\twx.showLoading({\n\t\t\t\ttitle: '提交中...',\n\t\t\t\tmask: true\n\t\t\t});\n\t\t\tlet content = await cloudHelper.transRichEditorTempPics(formContent, 'meet/', meetId, 'admin/meet_update_content');\n\t\t\tthis.setData({\n\t\t\t\tformContent: content\n\t\t\t});\n\n\n\t\t\t// 样式 提交处理\n\t\t\tlet formStyleSet = this.data.formStyleSet;\n\t\t\twx.showLoading({\n\t\t\t\ttitle: '提交中...',\n\t\t\t\tmask: true\n\t\t\t});\n\t\t\tif (!await AdminMeetBiz.updateMeetStyleSet(this, meetId, formStyleSet)) return;\n\n\n\t\t\tlet callback = async function () {\n\t\t\t\t// 更新列表页面数据\n\t\t\t\tlet node = {\n\t\t\t\t\t'MEET_TITLE': data.title,\n\t\t\t\t\t'MEET_TYPE_NAME': data.typeName,\n\t\t\t\t\t'MEET_DAYS_SET': data.daysSet,\n\t\t\t\t\t'MEET_FORM_SET': data.formSet,\n\t\t\t\t\t'MEET_EDIT_TIME': timeHelper.time('Y-M-D h:m:s'),\n\t\t\t\t\t'leaveDay': AdminMeetBiz.getLeaveDay(data.daysSet)\n\t\t\t\t}\n\t\t\t\tpageHelper.modifyPrevPageListNodeObject(meetId, node);\n\t\t\t\twx.navigateBack();\n\n\t\t\t}\n\t\t\tpageHelper.showSuccToast('编辑成功', 2000, callback);\n\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t}\n\n\t},\n\n\n\tbindMyImgUploadListener: function (e) {\n\t\tthis.setData({\n\t\t\timgList: e.detail\n\t\t});\n\t},\n\n\tswitchModel: function (e) {\n\t\tpageHelper.switchModel(this, e);\n\t},\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\t_setContentDesc: function () {\n\t\tlet contentDesc = '未填写';\n\t\tlet content = this.data.formContent;\n\t\tlet imgCnt = 0;\n\t\tlet textCnt = 0;\n\t\tfor (let k = 0; k < content.length; k++) {\n\t\t\tif (content[k].type == 'img') imgCnt++;\n\t\t\tif (content[k].type == 'text') textCnt++;\n\t\t}\n\n\t\tif (imgCnt || textCnt) {\n\t\t\tcontentDesc = textCnt + '段文字，' + imgCnt + '张图片';\n\t\t}\n\t\tthis.setData({\n\t\t\tcontentDesc\n\t\t});\n\t}\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/edit/admin_meet_edit.json",
    "content": "{\n\t\"usingComponents\": { \n\t\t\"cmpt-form-set\": \"/cmpts/public/form/form_set/form_set_cmpt\",\n\t\t\"cmpt-picker-time\": \"/cmpts/public/picker_time/picker_time_cmpt\",\n\t\t\"cmpt-picker-multi\": \"/cmpts/public/picker_multi/picker_multi_cmpt\"\n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\",\n\t\"enablePullDownRefresh\": true, \n\t\"navigationBarTitleText\": \"后台-预约添加\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/edit/admin_meet_edit.wxml",
    "content": "<view wx:if=\"{{id&&isLoad===null}}\" class=\"margin-top load notexist text-l text-grey\"></view>\n<view wx:if=\"{{id&&isLoad===false}}\" class=\"margin-top load loading text-l text-grey\"></view>\n<block wx:if=\"{{isAdmin&& (id&&isLoad || !id)}}\">\n\t<view class=\"main-admin\">\n\n\t\t<view class=\"form-box shadow\">\n\t\t\t<view class=\"form-group\">\n\t\t\t\t<view class=\"title must\">标题</view>\n\t\t\t\t<input placeholder=\"简短的标题\" placeholder-class=\"phc\" model:value=\"{{formTitle}}\" focus=\"{{formTitleFocus}}\" maxlength=\"50\"></input>\n\t\t\t</view>\n\t\t\t<view wx:if=\"{{formTitleFocus}}\" class=\"hint-desc error\">{{formTitleFocus}}</view>\n\n\t\t\t<view class=\"form-group arrow\" id=\"formTypeId\">\n\t\t\t\t<view class=\"title must\">分类</view>\n\t\t\t\t<cmpt-picker id=\"cate-picker\" sourceData=\"{{typeIdOptions}}\" bind:select=\"url\" data-type=\"picker\" data-item=\"formTypeId\" item=\"{{formTypeId}}\"> </cmpt-picker>\n\t\t\t</view>\n\t\t\t<view wx:if=\"{{formTypeIdFocus}}\" class=\"hint-desc error\">{{formTypeIdFocus}}</view>\n\n\t\t\t<view id=\"formStyleSet\" class=\"form-group arrow\" bindtap=\"url\" data-url=\"../cover/admin_meet_cover\">\n\t\t\t\t<view class=\"title must\">封面设置<text class=\"text-grey text-normal margin-left-xs\">(必填)</text></view>\n\t\t\t\t<view wx:if=\"{{formStyleSet.pic}}\" class=\"form-text\"></view>\n\t\t\t\t<view wx:else class=\"form-text text-orange\">封面图片未设置</view>\n\t\t\t</view>\n\t\t\t<view wx:if=\"{{formStyleSetFocus}}\" class=\"hint-desc error\">{{formStyleSetFocus}}</view>\n\n\t\t\t<view class=\"form-group arrow\" bindtap=\"url\" data-url=\"../../content/admin_content\">\n\t\t\t\t<view class=\"title must\">详细介绍<text class=\"text-grey text-normal margin-left-xs\">(必填)</text></view>\n\t\t\t\t<view wx:if=\"{{contentDesc==='未填写'}}\" class=\"form-text text-orange\">详细介绍未填写</view>\n\t\t\t\t<view wx:else class=\"form-text\">{{contentDesc}}</view>\n\t\t\t</view>\n\t\t\t<view wx:if=\"{{formContentFocus}}\" class=\"hint-desc error\">{{formContentFocus}}</view>\n\n\t\t\t<view class=\"form-group\">\n\t\t\t\t<view class=\"title must\" bindtap=\"url\" data-type=\"hint\" data-url=\"用户看到的预约列表排序，小的先显示\">排序号<text class=\"icon-question margin-left-xxs text-normal\"></text></view>\n\t\t\t\t<input placeholder=\"排序号，小的先显示\" type=\"number\" placeholder-class=\"phc\" model:value=\"{{formOrder}}\" focus=\"{{formOrderFocus}}\" maxlength=\"4\"></input>\n\t\t\t</view>\n\t\t\t<view wx:if=\"{{formOrderFocus}}\" class=\"hint-desc error\">{{formOrderFocus}}</view>\n\n\t\t</view>\n\n\t\t<view id=\"formDaysSet\" class=\"form-box shadow\">\n\t\t\t<view bindtap=\"url\" data-url=\"../time/admin_meet_time\" class=\"form-group arrow\">\n\t\t\t\t<view class=\"title must\">预约时间设置</view>\n\t\t\t\t<view wx:if=\"{{formDaysSet.length}}\" class=\"form-text text-admin\">{{formDaysSet.length}}天可约</view>\n\t\t\t\t<view wx:else class=\"form-text text-orange\">请配置可预约时段</view>\n\t\t\t</view>\n\t\t\t<view wx:if=\"{{formDaysSetFocus}}\" class=\"hint-desc error\">{{formDaysSetFocus}}</view>\n\n\n\t\t\t<view class=\"form-group\">\n\t\t\t\t<view class=\"title must\">是否显示可预约人数</view>\n\t\t\t\t<cmpt-picker mark=\"isShowLimit\" style=\"flex:1\" model:item=\"{{formIsShowLimit}}\" sourceDataStr=\"0=不显示给用户,1=显示给用户\" />\n\t\t\t</view>\n\t\t\t<view wx:if=\"{{formIsShowLimitFocus}}\" class=\"hint-desc error\">{{formIsShowLimitFocus}}</view>\n\n\n\t\t</view>\n\n\t\t<view class=\"form-box shadow\">\n\t\t\t<view class=\"form-group\">\n\t\t\t\t<view class=\"title must\">用户填写资料项目设置 <text class=\"text-grey text-normal\">(共{{formFormSet.length}}个字段)</text></view>\n\t\t\t</view>\n\t\t\t<cmpt-form-set id=\"form-set\" bind:formset=\"bindFormSetCmpt\" fields=\"{{formFormSet}}\" />\n\t\t</view>\n\n\t\t<button wx:if=\"{{!id}}\" bindtap=\"bindFormAddSubmit\" class=\"btn-admin margin-top-l\">创建</button>\n\t\t<button wx:else bindtap=\"bindFormEditSubmit\" class=\"btn-admin margin-top-l\">保存</button>\n\n\t</view>\n\n\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/edit/admin_meet_edit.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n\n\n.main-admin {\n\tpadding: 20rpx 0rpx;\n\n}\n\n.form-box {\n\tborder-radius: 0;\n}\n\n.modal-rules {\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: center;\n\tpadding: 0;\n}\n\n.modal-rules .padding-xl {\n\tpadding: 0;\n}\n\n.modal-rules .item {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: center;\n\tborder-bottom: 2rpx solid #ddd;\n\tpadding: 20rpx 0;\n\tposition: relative;\n}\n\n.modal-rules .item.cur {\n\tbackground-color: #f2f2f2; \n\tfont-weight: bold;\n}\n\n.modal-rules .item.cur .icon-right {\n\tcolor: var(--adminColor)!important;\n}\n\n.modal-rules .item .icon-right {\n\tright: 10rpx;\n\tposition: absolute;\n\ttop: 50rpx;\n}\n\n.modal-rules .item.item-last {\n\tborder-bottom: 0;\n}\n\n.modal-rules .item .title {\n\tfont-size: 36rpx;\n\tcolor: #111;\n}\n\n.modal-rules .item .desc {\n\tfont-size: 28rpx;\n\tcolor: #777;\n\tmargin-top: 10rpx;\n}\n\ncmpt-picker-multi {\n\tflex: 1;\n}\n\n.form-group .desc-textarea {\n\theight: 100rpx;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/export/admin_join_export.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js'); \nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\nconst timeHelper = require('../../../../../../helper/time_helper.js');\nconst fileHelper = require('../../../../../../helper/file_helper.js'); \n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\ttitle: '',\n\n\t\turl: '',\n\t\ttime: '',\n\n\t\tstartDay: timeHelper.time('Y-M-D'),\n\t\tendDay: timeHelper.time('Y-M-D'),\n\t\tstatus: 1\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tif (!pageHelper.getOptions(this, options, 'meetId')) return;\n\n\t\tif (options && options.title) {\n\t\t\tlet title = decodeURIComponent(options.title);\n\t\t\tthis.setData({\n\t\t\t\ttitle\n\t\t\t});\n\t\t}\n\n\t\tthis._loadDetail(1);\n\t},\n\n\t_loadDetail: async function (isDel) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet params = {\n\t\t\tisDel\n\t\t}\n\t\tlet options = {\n\t\t\ttitle: 'bar'\n\t\t}\n\t\tlet data = await cloudHelper.callCloudData('admin/join_data_get', params, options);\n\n\t\tif (!data) return;\n\n\t\tthis.setData({\n\t\t\tisLoad: true,\n\t\t\turl: data.url,\n\t\t\ttime: data.time\n\t\t})\n\n\t},\n\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\t\tawait this._loadDetail(1);\n\t\twx.stopPullDownRefresh();\n\t},\n\n\tbindOpenTap:function(e) {\n\t\tfileHelper.openDoc('预约名单', this.data.url);\n\t},\n\n\turl: async function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\t/**\n\t * 页面上拉触底事件的处理函数\n\t */\n\tonReachBottom: function () {\n\n\t},\n\n\tbindExportTap: async function (e) {\n\t\ttry {\n\t\t\tlet options = {\n\t\t\t\ttitle: '数据生成中'\n\t\t\t}\n\n\t\t\tlet params = {\n\t\t\t\tmeetId: this.data.meetId,\n\t\t\t\tstartDay: this.data.startDay,\n\t\t\t\tendDay: this.data.endDay,\n\t\t\t\tstatus: this.data.status\n\t\t\t}\n\n\t\t\tawait cloudHelper.callCloudData('admin/join_data_export', params, options).then(res => {  \n\t\t\t\tthis._loadDetail(0);\n\t\t\t\tpageHelper.showModal('数据文件生成成功(' + res.total + '条记录), 请点击「直接打开」按钮或者复制文件地址下载');\n\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t\tpageHelper.showNoneToast('导出失败，请重试');\n\t\t}\n\n\t},\n\n\tbindDelTap: async function (e) {\n\t\ttry {\n\t\t\tlet options = {\n\t\t\t\ttitle: '数据删除中'\n\t\t\t}\n\t\t\tawait cloudHelper.callCloudData('admin/join_data_del', {}, options).then(res => {\n\t\t\t\tthis.setData({\n\t\t\t\t\turl: '',\n\t\t\t\t\ttime: ''\n\t\t\t\t});\n\t\t\t\tpageHelper.showSuccToast('删除成功');\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t\tpageHelper.showNoneToast('删除失败，请重试');\n\t\t}\n\n\t},\n\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/export/admin_join_export.json",
    "content": "{\n\t\"usingComponents\": {\n\t\t\"cmpt-picker-time\": \"/cmpts/public/picker_time/picker_time_cmpt\"\n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\", \n\t\"enablePullDownRefresh\": true,  \n\t\"navigationBarTitleText\": \"预约名单导出\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/export/admin_join_export.wxml",
    "content": "<view wx:if=\"{{!isLoad}}\" class=\"margin-top load loading text-l text-grey\"></view>\n\n\n<view class=\"main-admin\" wx:if=\"{{isAdmin&&isLoad}}\">\n\t<view class=\"form-box shadow\">\n\t\t<view class=\"form-group\">\n\t\t\t<view class=\"title text-cut\">{{title}}</view>\n\t\t</view>\n\t\t<view class=\"form-group arrow\">\n\t\t\t<view class=\"title must\">起始日期</view>\n\t\t\t<cmpt-picker-time mark=\"startDay\" mode=\"day\" bind:select=\"url\" data-type=\"picker\" data-item=\"startDay\" startYear=\"2021\" endYear=\"2025\" item=\"{{startDay}}\">\n\t\t\t\t<view class=\"form-text\">{{startDay||'请选择'}}</view>\n\t\t\t</cmpt-picker-time>\n\t\t</view>\n\n\t\t<view class=\"form-group arrow\">\n\t\t\t<view class=\"title must\">终止日期</view>\n\t\t\t<cmpt-picker-time mark=\"endDay\" mode=\"day\" bind:select=\"url\" data-type=\"picker\" data-item=\"endDay\" startYear=\"2021\" endYear=\"2025\" item=\"{{endDay}}\">\n\t\t\t\t<view class=\"form-text\">{{endDay||'请选择'}}</view>\n\t\t\t</cmpt-picker-time>\n\t\t</view>\n\n\t\t<view class=\"form-group\">\n\t\t\t<view class=\"title must\">数据类型</view>\n\t\t\t<cmpt-picker mark=\"status\" style=\"flex:1\" model:item=\"{{status}}\" sourceDataStr=\"1=预约成功名单,10=用户已取消名单,99=系统取消名单,999=所有名单\" />\n\t\t</view>\n\n\t</view>\n\n\t<view class=\"form-box shadow margin-top-xs\">\n\t\t<view class=\"form-group\">\n\t\t\t<view class=\"title\"  style=\"font-size:30rpx\">数据下载链接<text wx:if=\"{{time}}\" class=\"text-gray text-s margin-left-s\">({{time}} 生成)</text> </view>\n\n\t\t\t<button hover-class=\"button-hover\" class=\"btn bg-admin text-white shadow\" bindtap=\"url\" data-type=\"copy\" data-url=\"{{url}}\">复制</button>\n\t\t</view>\n\t\t<view class=\"form-group align-start\" bindtap=\"url\" data-type=\"copy\" data-url=\"{{url}}\">\n\t\t\t<textarea maxlength=\"500\" placeholder=\"数据文件尚未生成，点击下方按钮生成\" placeholder-class=\"phc\" value=\"{{url}}\" style=\"height:50rpx\"></textarea>\n\t\t</view>\n\n\t\t<block wx:if=\"{{url}}\">\n\t\t\t<view class=\"form-group\" style=\"padding:20rpx 15rpx 20rpx;\">\n\t\t\t\t<view class=\"title-desc\">\n\t\t\t\t\t<text user-select=\"true\">※ <text class=\"text-black\">链接使用说明</text>\n\t\t\t\t\t\t1. 复制以上链接地址，建议在电脑浏览器中打开链接下载数据文件\n\t\t\t\t\t\t2. 为保障信息安全，请勿外传数据链接\n\t\t\t\t\t\t3. 为了防止隐私数据泄露，请在下载后及时点击下方按钮删除\n\t\t\t\t\t</text>\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t</block>\n\t</view>\n\n\t<button bindtap=\"bindExportTap\" class=\"btn-admin margin-top\">{{url?'重新生成名单数据':'生成名单数据'}} (Excel文件)</button> \n\n\t<button wx:if=\"{{url}}\" bindtap=\"bindOpenTap\" class=\"btn-admin bg-purple light\">直接打开数据文件</button>   \n\n\t<button wx:if=\"{{url}}\" bindtap=\"bindDelTap\" class=\"btn-admin bg-orange light\">删除数据文件</button> \n\n\t<view class=\"form-group\" wx:if=\"{{url}}\">\n\t\t<view class=\"title-desc text-red\"><text class=\"icon-info margin-right-xs\"></text>为了防止隐私数据泄露，请在下载上述文件后及时点击按钮删除\n\t\t</view>\n\t</view>\n</view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/export/admin_join_export.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss'; \n\n.form-box .title-desc {\n\tpadding-bottom: 10rpx;\n\tborder: 0;\n\tfont-size: 29rpx;\n\tcolor: #888;\n}\n\n.btn-admin{\n\tmargin-bottom: 20rpx;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/join/admin_meet_join.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst cacheHelper = require('../../../../../../helper/cache_helper.js');\nconst helper = require('../../../../../../helper/helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\n\nconst CACHE_CANCEL_REASON = 'JOIN_CANCEL_REASON';\nconst CACHE_REFUSE_REASON = 'JOIN_REFUSE_REASON';\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false,\n\t\tisAllFold: true,\n\n\t\tparentDayIdx: 0,\n\t\tparentTimeIdx: 0,\n\n\t\tmenuIdx: 0,\n\n\t\tmeetId: '',\n\t\tmark: '',\n\n\t\ttitle: '',\n\t\ttitleEn: '',\n\n\t\tcancelModalShow: false,\n\t\tcancelAllModalShow: false,\n\t\trefuseModalShow: false,\n\t\tformReason: '',\n\t\tcurIdx: -1\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\t// 附加参数 \n\t\tif (options && options.meetId && options.mark) {\n\t\t\t//设置搜索菜单 \n\t\t\tthis._getSearchMenu();\n\n\t\t\tthis.setData({\n\t\t\t\tmeetId: options.meetId,\n\t\t\t\tmark: options.mark,\n\t\t\t\tparentDayIdx: options.dayidx,\n\t\t\t\tparentTimeIdx: options.timeidx,\n\t\t\t\ttime: options.time,\n\n\t\t\t\t_params: {\n\t\t\t\t\tmeetId: options.meetId,\n\t\t\t\t\tmark: options.mark,\n\t\t\t\t}\n\t\t\t}, () => (\n\t\t\t\tthis.setData({\n\t\t\t\t\tisLoad: true\n\t\t\t\t})\n\t\t\t));\n\t\t}\n\n\t\tif (options && options.title) {\n\t\t\tlet title = decodeURIComponent(options.title);\n\t\t\tthis.setData({\n\t\t\t\ttitle,\n\t\t\t\ttitleEn: options.title\n\t\t\t});\n\t\t\twx.setNavigationBarTitle({\n\t\t\t\ttitle: '分时段预约名单 - ' + title\n\t\t\t});\n\t\t}\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\turl: async function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tbindUnFoldTap: function (e) {\n\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\tlet dataList = this.data.dataList;\n\t\tdataList.list[idx].fold = false;\n\t\tthis.setData({\n\t\t\tdataList\n\t\t});\n\t},\n\n\tbindFoldTap: function (e) {\n\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\tlet dataList = this.data.dataList;\n\t\tdataList.list[idx].fold = true;\n\t\tthis.setData({\n\t\t\tdataList\n\t\t});\n\t},\n\n\tbindFoldAllTap: function (e) {\n\t\tlet dataList = this.data.dataList;\n\t\tfor (let k = 0; k < dataList.list.length; k++) {\n\t\t\tdataList.list[k].fold = true;\n\t\t}\n\t\tthis.setData({\n\t\t\tisAllFold: true,\n\t\t\tdataList\n\t\t});\n\t},\n\n\tbindUnFoldAllTap: function (e) {\n\t\tlet dataList = this.data.dataList;\n\t\tfor (let k = 0; k < dataList.list.length; k++) {\n\t\t\tdataList.list[k].fold = false;\n\t\t}\n\t\tthis.setData({\n\t\t\tisAllFold: false,\n\t\t\tdataList\n\t\t});\n\t},\n\n\tbindCopyTap: function (e) {\n\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\tlet forms = this.data.dataList.list[idx].JOIN_FORMS;\n\n\t\tlet ret = '';\n\n\t\tret += `项目：${this.data.dataList.list[idx].JOIN_MEET_TITLE}\\r`;\n\n\t\tret += `时段：${this.data.dataList.list[idx].JOIN_MEET_DAY} ${this.data.dataList.list[idx].JOIN_MEET_TIME_START}～${this.data.dataList.list[idx].JOIN_MEET_TIME_END}\\r`;\n\t\tfor (let k = 0; k < forms.length; k++) {\n\t\t\tret += forms[k].title + '：' + forms[k].val + '\\r';\n\t\t}\n\t\twx.setClipboardData({\n\t\t\tdata: ret,\n\t\t\tsuccess(res) {\n\t\t\t\twx.getClipboardData({\n\t\t\t\t\tsuccess(res) {\n\t\t\t\t\t\tpageHelper.showSuccToast('已复制到剪贴板');\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t});\n\n\t},\n\n\tbindCancelTap: function (e) {\n\t\tthis.setData({\n\t\t\tformReason: cacheHelper.get(CACHE_CANCEL_REASON) || '',\n\t\t\tcurIdx: pageHelper.dataset(e, 'idx'),\n\t\t\tcancelModalShow: true\n\t\t});\n\t},\n\n\tbindCancelAllTap: function (e) {\n\t\tthis.setData({\n\t\t\tformReason: '',\n\t\t\tcancelAllModalShow: true\n\t\t});\n\t},\n\n\tbindRefuseTap: function (e) {\n\t\tthis.setData({\n\t\t\tformReason: cacheHelper.get(CACHE_REFUSE_REASON) || '',\n\t\t\tcurIdx: pageHelper.dataset(e, 'idx'),\n\t\t\trefuseModalShow: true\n\t\t});\n\t},\n\n\tbindCancelCmpt: async function () {\n\t\tlet e = {\n\t\t\tcurrentTarget: {\n\t\t\t\tdataset: {\n\t\t\t\t\tstatus: 99,\n\t\t\t\t\tidx: this.data.curIdx\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcacheHelper.set(CACHE_CANCEL_REASON, this.data.formReason, 86400 * 365);\n\t\tawait this.bindStatusTap(e);\n\t},\n\n\tbindCancelAllCmpt: async function () {\n\t\ttry {\n\t\t\tlet params = {\n\t\t\t\treason: this.data.formReason,\n\t\t\t\tmeetId: this.data.meetId,\n\t\t\t\ttimeMark: this.data.mark\n\t\t\t}\n\t\t\tlet opt = {\n\t\t\t\ttitle: '预约记录取消中'\n\t\t\t}\n\t\t\tawait cloudHelper.callCloudSumbit('admin/meet_cancel_time_join', params, opt).then(res => {\n\t\t\t\tlet callback = () => {\n\t\t\t\t\tlet parent = pageHelper.getPrevPage(2);\n\t\t\t\t\tif (parent) {\n\t\t\t\t\t\tlet daysSet = parent.data.daysSet;\n\t\t\t\t\t\tdaysSet[this.data.parentDayIdx].times[this.data.parentTimeIdx].stat = res.data;\n\t\t\t\t\t\tparent.setData({\n\t\t\t\t\t\t\tdaysSet\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\twx.redirectTo({\n\t\t\t\t\t\turl: `admin_meet_join?meetId=${this.data.meetId}&mark=${this.data.mark}&title=${this.data.titleEn}&time=${this.data.time}&dayidx=${this.data.parentDayIdx}&timeidx=${this.data.parentTimeIdx}`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tpageHelper.showSuccToast('取消成功', 1500, callback);\n\t\t\t})\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t};\n\t},\n\n\tbindRefuseCmpt: async function () {\n\t\tlet e = {\n\t\t\tcurrentTarget: {\n\t\t\t\tdataset: {\n\t\t\t\t\tstatus: 8,\n\t\t\t\t\tidx: this.data.curIdx\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcacheHelper.set(CACHE_REFUSE_REASON, this.data.formReason, 86400 * 365);\n\t\tawait this.bindStatusTap(e);\n\t},\n\n\tbindCheckinTap: async function (e) {\n\t\tlet flag = Number(pageHelper.dataset(e, 'flag'));\n\n\t\tlet callback = async () => {\n\t\t\tlet idx = Number(pageHelper.dataset(e, 'idx'));\n\t\t\tlet dataList = this.data.dataList;\n\t\t\tlet joinId = dataList.list[idx]._id;\n\t\t\tlet params = {\n\t\t\t\tjoinId,\n\t\t\t\tflag,\n\t\t\t}\n\t\t\tlet opts = {\n\t\t\t\ttitle: '处理中'\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait cloudHelper.callCloudSumbit('admin/join_checkin', params, opts).then(res => {\n\t\t\t\t\tlet cb = () => {\n\t\t\t\t\t\tlet sortIndex = this.selectComponent('#cmpt-comm-list').getSortIndex();\n\t\t\t\t\t\tif (sortIndex >= 10 && !this.data.search) { // 全部或者检索的结果\n\t\t\t\t\t\t\tdataList.list.splice(idx, 1);\n\t\t\t\t\t\t\tdataList.total--;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdataList.list[idx].JOIN_IS_CHECKIN = flag;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.setData({\n\t\t\t\t\t\t\tdataList\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tpageHelper.showSuccToast('操作成功', 1000, cb);\n\n\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(err);\n\t\t\t}\n\t\t}\n\t\tif (flag == 1)\n\t\t\tpageHelper.showConfirm('确认「签到核销」？', callback);\n\t\telse if (flag == 0)\n\t\t\tpageHelper.showConfirm('确认「取消签到」？', callback);\n\n\t},\n\n\tbindDelTap: async function (e) {\n\n\t\tlet callback = async () => {\n\t\t\tlet idx = Number(pageHelper.dataset(e, 'idx'));\n\t\t\tlet dataList = this.data.dataList;\n\t\t\tlet joinId = dataList.list[idx]._id;\n\t\t\tlet params = {\n\t\t\t\tjoinId\n\t\t\t}\n\t\t\tlet opts = {\n\t\t\t\ttitle: '删除中'\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait cloudHelper.callCloudSumbit('admin/join_del', params, opts).then(res => {\n\n\t\t\t\t\tlet cb = () => {\n\t\t\t\t\t\tlet dataList = this.data.dataList;\n\t\t\t\t\t\tdataList.list.splice(idx, 1);\n\t\t\t\t\t\tdataList.total--;\n\t\t\t\t\t\tthis.setData({\n\t\t\t\t\t\t\tdataList\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tlet parent = pageHelper.getPrevPage(2);\n\t\t\t\t\t\tif (parent) {\n\t\t\t\t\t\t\tlet daysSet = parent.data.daysSet;\n\t\t\t\t\t\t\tdaysSet[this.data.parentDayIdx].times[this.data.parentTimeIdx].stat = res.data;\n\t\t\t\t\t\t\tparent.setData({\n\t\t\t\t\t\t\t\tdaysSet\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tpageHelper.showSuccToast('删除成功', 1000, cb);\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(err);\n\t\t\t}\n\t\t}\n\n\t\tpageHelper.showConfirm('确认删除该预约记录？ 删除后用户将无法查询到本预约记录', callback);\n\n\n\t},\n\n\tbindStatusTap: async function (e) {\n\t\tlet status = Number(pageHelper.dataset(e, 'status'));\n\t\tlet oldStatus = Number(pageHelper.dataset(e, 'old'));\n\n\t\tlet callback = async () => {\n\t\t\tlet idx = Number(pageHelper.dataset(e, 'idx'));\n\t\t\tlet dataList = this.data.dataList;\n\t\t\tlet joinId = dataList.list[idx]._id;\n\t\t\tlet params = {\n\t\t\t\tjoinId,\n\t\t\t\tstatus,\n\t\t\t\treason: this.data.formReason\n\t\t\t}\n\t\t\tlet opts = {\n\t\t\t\ttitle: '处理中'\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait cloudHelper.callCloudSumbit('admin/join_status', params, opts).then(res => {\n\t\t\t\t\tpageHelper.showSuccToast('操作成功', 1000);\n\t\t\t\t\tlet sortIndex = this.selectComponent('#cmpt-comm-list').getSortIndex();\n\n\t\t\t\t\tif (sortIndex != -1 && sortIndex != 5 && !this.data.search) { // 全部或者检索的结果\n\t\t\t\t\t\tdataList.list.splice(idx, 1);\n\t\t\t\t\t\tdataList.total--;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdataList.list[idx].JOIN_REASON = this.data.formReason;\n\t\t\t\t\t\tdataList.list[idx].JOIN_STATUS = status;\n\t\t\t\t\t\tdataList.list[idx].JOIN_IS_CHECKIN = 0;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.setData({\n\t\t\t\t\t\tcancelModalShow: false,\n\t\t\t\t\t\trefuseModalShow: false,\n\t\t\t\t\t\tformReason: '',\n\t\t\t\t\t\tcurIdx: -1,\n\t\t\t\t\t\tdataList\n\t\t\t\t\t});\n\n\t\t\t\t\tlet parent = pageHelper.getPrevPage(2);\n\t\t\t\t\tif (parent) {\n\t\t\t\t\t\tlet daysSet = parent.data.daysSet;\n\t\t\t\t\t\tdaysSet[this.data.parentDayIdx].times[this.data.parentTimeIdx].stat = res.data;\n\t\t\t\t\t\tparent.setData({\n\t\t\t\t\t\t\tdaysSet\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(err);\n\t\t\t}\n\t\t}\n\n\t\tswitch (status) {\n\t\t\tcase 99: //直接取消\n\t\t\t\tawait callback();\n\t\t\t\tbreak;\n\t\t\tcase 1: {\n\n\t\t\t\tif (oldStatus == 10)\n\t\t\t\t\tpageHelper.showConfirm('确认变更为「预约成功」？', callback);\n\t\t\t\telse if (oldStatus == 99)\n\t\t\t\t\tpageHelper.showConfirm('确认恢复为「预约成功」状态？', callback);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t},\n\n\tbindCommListCmpt: function (e) {\n\n\t\tif (helper.isDefined(e.detail.search))\n\t\t\tthis.setData({\n\t\t\t\tsearch: '',\n\t\t\t\tsortType: '',\n\t\t\t});\n\t\telse {\n\t\t\tlet dataList = e.detail.dataList;\n\t\t\tif (dataList) {\n\t\t\t\tfor (let k = 0; k < dataList.list.length; k++) {\n\t\t\t\t\tdataList.list[k].fold = this.data.isAllFold;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.setData({\n\t\t\t\tdataList,\n\t\t\t});\n\t\t\tif (e.detail.sortType)\n\t\t\t\tthis.setData({\n\t\t\t\t\tsortType: e.detail.sortType,\n\t\t\t\t});\n\t\t}\n\n\t},\n\n\t// 修改与展示状态菜单\n\t_getSearchMenu: function () {\n\n\t\tlet sortItems = [];\n\t\tlet sortMenus = [{\n\t\t\t\tlabel: '全部',\n\t\t\t\ttype: '',\n\t\t\t\tvalue: ''\n\t\t\t}, {\n\t\t\t\tlabel: `成功`,\n\t\t\t\ttype: 'status',\n\t\t\t\tvalue: 1\n\t\t\t}, \n\t\t\t \n\t\t\t{\n\t\t\t\tlabel: `已取消`,\n\t\t\t\ttype: 'status',\n\t\t\t\tvalue: 1099\n\t\t\t}, \n\t\t\t{\n\t\t\t\tlabel: `已签到`,\n\t\t\t\ttype: 'checkin',\n\t\t\t\tvalue: 1\n\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: `未签到`,\n\t\t\t\ttype: 'checkin',\n\t\t\t\tvalue: 0\n\t\t\t}\n\n\t\t]\n\t\tthis.setData({\n\t\t\tsortItems,\n\t\t\tsortMenus\n\t\t})\n\n\n\t},\n\n\tbindClearReasonTap: function (e) {\n\t\tthis.setData({\n\t\t\tformReason: ''\n\t\t})\n\t}\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/join/admin_meet_join.json",
    "content": "{\n\t\"usingComponents\": {\n\t\t \n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\",   \n\t\"navigationBarTitleText\": \"分时段预约名单\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/join/admin_meet_join.wxml",
    "content": "<view wx:if=\"{{isLoad===null}}\" class=\"margin-top load notexist text-l text-grey\"></view>\n<view wx:if=\"{{isLoad===false}}\" class=\"margin-top load loading text-l text-grey\"></view>\n\n<block wx:if=\"{{isAdmin&&isLoad}}\">\n\n\t<cmpt-comm-list source='admin' id=\"cmpt-comm-list\" type=\"admin-meet-join-list\" search=\"{{search}}\" _params=\"{{_params}}\" _menus=\"{{sortMenus}}\" _items=\"{{sortItems}}\" route=\"admin/meet_join_list\" topBottom=\"50\" placeholder=\"搜索\" sortMenusDefaultIndex=\"0\" bind:list=\"bindCommListCmpt\">\n\n\t\t<view slot=\"searchEnd\">\n\t\t\t<button bindtap=\"url\" data-url=\"../self/admin_meet_self?mark={{mark}}&title={{titleEn}}\" class=\"btn radius mid bg-blue margin-right-xs\">自助签到码</button>\n\t\t\t<button bindtap=\"bindCancelAllTap\" class=\"btn mid radius bg-orange margin-right-xs\">取消所有</button> \n\t\t</view>\n\n\t\t<!-- List Begin -->\n\t\t<view class=\"join-list\">\n\t\t\t<view class=\"time-line text-grey\">({{time}})</view>\n\t\t\t<view wx:if=\"{{dataList && dataList.total }}\" class=\"load text-grey\">共有{{dataList.total}}条符合条件记录\n\t\t\t\t<text wx:if=\"{{isAllFold}}\" bindtap=\"bindUnFoldAllTap\" class=\"margin-left-xs icon-unfold  text-admin\">全部展开</text>\n\t\t\t\t<text wx:else bindtap=\"bindFoldAllTap\" class=\"margin-left-xs icon-fold  text-admin\">全部收起</text>\n\t\t\t</view>\n\n\t\t\t<view class=\"item\" wx:for=\"{{dataList.list}}\" wx:key=\"key\">\n\t\t\t\t<view class=\"header\">\n\t\t\t\t\t<view class=\"left\">\n\t\t\t\t\t\t<text class=\"icon-calendar margin-right-xxs\"></text><text class=\"\">{{item.JOIN_MEET_DAY}} ({{item.JOIN_MEET_TIME_START}}～{{item.JOIN_MEET_TIME_END}})</text>\n\t\t\t\t\t</view>\n\t\t\t\t\t<view class=\"right\" bindtap=\"bindCopyTap\" data-idx=\"{{index}}\">\n\t\t\t\t\t\t<text class=\"icon-copy margin-right-xxs\"></text>复制资料\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\n\t\t\t\t<view class=\"info\">\n\n\t\t\t\t\t<view class=\"info-item\">\n\t\t\t\t\t\t<view class=\"title text-admin\">状态</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view class=\"content\"> \n\t\t\t\t\t\t\t<view wx:if=\"{{item.JOIN_STATUS==1}}\" class=\"text-black\"><text class=\"icon-roundcheck margin-right-xxs\"></text>预约成功\n\t\t\t\t\t\t\t\t<text wx:if=\"{{item.JOIN_IS_CHECKIN==1}}\">，已签到</text>\n\t\t\t\t\t\t\t\t<text class=\"text-grey\" wx:else>，未签到</text>\n\t\t\t\t\t\t\t</view> \n\t\t\t\t\t\t\t<view wx:elif=\"{{item.JOIN_STATUS==10}}\">用户取消</view>\n\t\t\t\t\t\t\t<view wx:elif=\"{{item.JOIN_STATUS==99}}\">系统取消</view>\n\t\t\t\t\t\t</view>\n\t\t\t\t\t</view>\n\n\t\t\t\t\t<view class=\"info-item\" wx:if=\"{{item.JOIN_STATUS==99}}\">\n\t\t\t\t\t\t<view class=\"title text-admin\">取消原因</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view class=\"content\">{{item.JOIN_REASON||'未填'}}</view>\n\t\t\t\t\t</view>\n\t\t\t\t\t<view class=\"info-item\" wx:if=\"{{item.JOIN_STATUS==8}}\">\n\t\t\t\t\t\t<view class=\"title text-orange\">未通过原因</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view class=\"content\">{{item.JOIN_REASON||'未填'}}</view>\n\t\t\t\t\t</view>\n\n\t\t\t\t\t<view class=\"info-item\" wx:for=\"{{item.JOIN_FORMS}}\" wx:key=\"key1\" wx:for-item=\"form\" wx:for-index=\"formindex\" wx:if=\"{{formindex<3||!item.fold}}\">\n\t\t\t\t\t\t<view class=\"title\">{{form.title}}</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view wx:if=\"{{form.type=='mobile'}}\" class=\"content\" bindtap=\"url\" data-type=\"phone\" data-url=\"{{form.val}}\"><text wx:for=\"{{form.valArr}}\" wx:key=\"key2\" wx:for-item=\"valItem\" class=\"{{valItem===search?'text-red text-bold':''}}\">{{valItem}}</text><text class=\" margin-left-xs icon-phone text-black text-normal\"></text></view>\n\t\t\t\t\t\t<view wx:else class=\"content\" bindtap=\"url\" data-type=\"copy\" data-url=\"{{form.title+'：'+form.val}}\"><text wx:for=\"{{form.valArr}}\" wx:key=\"key2\" wx:for-item=\"valItem\" class=\"{{valItem===search?'text-red text-bold':''}}\">{{valItem}}</text></view>\n\t\t\t\t\t</view>\n\t\t\t\t\t<view bindtap=\"bindUnFoldTap\" data-idx=\"{{index}}\" wx:if=\"{{item.fold && item.JOIN_FORMS.length>3}}\" class=\"fold\"><text class=\"icon-unfold margin-right-xs\"></text>更多资料...</view>\n\n\t\t\t\t\t<view bindtap=\"bindFoldTap\" data-idx=\"{{index}}\" wx:if=\"{{!item.fold && item.JOIN_FORMS.length>3}}\" class=\"fold\"><text class=\"icon-fold margin-right-xs\"></text>收起</view>\n\n\t\t\t\t\t<view class=\"info-item add-time\">\n\t\t\t\t\t\t<view class=\"title text-grey\">提交/变更</view>\n\t\t\t\t\t\t<view class=\"mao text-grey\">：</view>\n\t\t\t\t\t\t<view class=\"content text-grey\">{{item.JOIN_EDIT_TIME}}</view>\n\t\t\t\t\t</view>\n\n\t\t\t\t\t<view class=\"oprt\">\n\t\t\t\t\t\t<block wx:if=\"{{item.JOIN_STATUS==1}}\">\n\t\t\t\t\t\t\t<view wx:if=\"{{item.JOIN_IS_CHECKIN==0}}\" bindtap=\"bindCheckinTap\" data-idx=\"{{index}}\" data-flag=\"1\" class=\"btn bg-purple margin-right-s light\">签到核销</view>\n\n\t\t\t\t\t\t\t<view wx:else bindtap=\"bindCheckinTap\" data-idx=\"{{index}}\" data-flag=\"0\" class=\"btn bg-grey light margin-right-s\">取消签到</view>\n\t\t\t\t\t\t</block>\n\n\t\t\t\t\t\t<block wx:if=\"{{item.JOIN_STATUS==1}}\">\n\t\t\t\t\t\t\t<view bindtap=\"bindCancelTap\" data-idx=\"{{index}}\" data-status=\"99\" data-old=\"{{item.JOIN_STATUS}}\" class=\"btn bg-grey light  margin-right-s\">取消预约</view>\n\t\t\t\t\t\t</block>   \n\n\t\t\t\t\t\t<block wx:if=\"{{item.JOIN_STATUS==10 || item.JOIN_STATUS==99}}\">\n\t\t\t\t\t\t\t<view bindtap=\"bindStatusTap\" data-idx=\"{{index}}\" data-status=\"1\" data-old=\"{{item.JOIN_STATUS}}\" class=\"btn bg-olive light margin-right-s\">恢复预约</view>\n\t\t\t\t\t\t</block>\n\n\t\t\t\t\t\t<view bindtap=\"bindDelTap\" data-idx=\"{{index}}\" class=\"btn bg-orange light margin-right-s\">删除</view>\n\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\n\t\t\t\t<view class=\"no\">{{index+1}}</view>\n\t\t\t</view>\n\t\t</view>\n\t\t<!-- List END -->\n\n\t\t<!--load begin-->\n\t\t<import src=\"../../../../../../tpls/public/list_load_tpl.wxml\" />\n\t\t<template is=\"listLoadTpl\" data=\"{{dataList,skin:'text-grey',noHint:'暂无记录'}}\" />\n\t\t<!--load end-->\n \n\n\t</cmpt-comm-list>\n\n\t<cmpt-modal wx:if=\"{{cancelAllModalShow}}\" model:show=\"{{cancelAllModalShow}}\" type=\"dialog\" title=\"取消所有预约\" bind:click=\"bindCancelAllCmpt\" class=\"modal-form\" cancelText=\"返回\" confirmText=\"确定取消\">\n\t\t<view class=\"form-group\" style=\"padding:0 10rpx\">\n\t\t\t<view class=\"title\">取消理由 <text class=\"text-grey text-mid\">(选填)</text>：</view>\n\t\t\t<view bindtap=\"bindClearReasonTap\" style=\"width:150rpx;text-align: right;\" class=\"text-grey\"><text class=\"icon-roundclose\"></text>清空</view>\n\t\t</view>\n\n\t\t<view class=\"form-group cancel-area\">\n\t\t\t<textarea placeholder-class=\"phc\" placeholder=\"请输入取消理由 (非必填)\" style=\"height:110rpx\" model:value=\"{{formReason}}\" maxlength=\"100\"></textarea>\n\t\t</view>\n\t</cmpt-modal>\n\n\t<cmpt-modal wx:if=\"{{cancelModalShow}}\" model:show=\"{{cancelModalShow}}\" type=\"dialog\" title=\"取消预约\" bind:click=\"bindCancelCmpt\" class=\"modal-form\" cancelText=\"返回\" confirmText=\"确定取消\">\n\t\t<view class=\"form-group\" style=\"padding:0 10rpx\">\n\t\t\t<view class=\"title\">取消理由 <text class=\"text-grey text-mid\">(选填)</text>：</view>\n\t\t\t<view bindtap=\"bindClearReasonTap\" style=\"width:150rpx;text-align: right;\" class=\"text-grey\"><text class=\"icon-roundclose\"></text>清空</view>\n\t\t</view>\n\n\t\t<view class=\"form-group cancel-area\">\n\t\t\t<textarea placeholder-class=\"phc\" placeholder=\"请输入取消理由 (非必填)\" style=\"height:110rpx\" model:value=\"{{formReason}}\" maxlength=\"100\"></textarea>\n\t\t</view>\n\t</cmpt-modal>\n\n\t<cmpt-modal wx:if=\"{{refuseModalShow}}\" model:show=\"{{refuseModalShow}}\" type=\"dialog\" title=\"审核不通过\" bind:click=\"bindRefuseCmpt\" class=\"modal-form\" cancelText=\"返回\" confirmText=\"确定\">\n\t\t<view class=\"form-group\" style=\"padding:0 10rpx\">\n\t\t\t<view class=\"title\">不通过理由 <text class=\"text-grey text-mid\">(选填)</text>：</view>\n\t\t\t<view bindtap=\"bindClearReasonTap\" style=\"width:150rpx;text-align: right;\" class=\"text-grey\"><text class=\"icon-roundclose\"></text>清空</view>\n\t\t</view>\n\n\t\t<view class=\"form-group cancel-area\">\n\t\t\t<textarea placeholder-class=\"phc\" placeholder=\"请输入审核不通过理由 (非必填)，将通知给用户\" style=\"height:110rpx\" model:value=\"{{formReason}}\" maxlength=\"100\"></textarea>\n\t\t</view>\n\t</cmpt-modal>\n\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/join/admin_meet_join.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n\npage {\n\tbackground-color: #f8f8f8;\n}\n\n.join-list {\n\twidth: 100%;\n\tpadding: 0rpx 20rpx 20rpx;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: flex-start;\n\tposition: relative;\n}\n\n.join-list .item {\n\twidth: 100%;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: flex-start;\n\tbackground-color: #fff;\n\tborder-radius: 5rpx;\n\toverflow: hidden;\n\tmargin-bottom: 30rpx;\n\tposition: relative;\n\tborder: 1rpx solid #ddd;\n}\n\n.join-list .item .no {\n\tposition: absolute;\n\tright: 0;\n\tbottom: 0;\n\tfont-size: 25rpx;\n\tcolor: #999;\n\tline-height: 2;\n\tpadding: 0rpx 15rpx 0rpx 15rpx;\n\tbackground-color: #eee;\n\tborder-top-left-radius: 15rpx;\n}\n\n.join-list .item .header {\n\twidth: 100%;\n\tfont-size: 26rpx;\n\ttext-align: left;\n\tline-height: 2.6;\n\tbackground-color: #f2f2f2;\n\tpadding: 0 15rpx;\n\tdisplay: flex;\n\tjustify-content: space-between;\n\talign-items: center;\n}\n\n.join-list .item .header .left {\n\tcolor: #333;\n}\n\n.join-list .item .header .right {\n\tfont-size: 25rpx;\n\tcolor: #666;\n}\n\n.join-list .item .info {\n\twidth: 100%;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: flex-start;\n\tbackground-color: #fff;\n\tmin-height: 150rpx;\n\tpadding: 15rpx 20rpx 20rpx;\n\tposition: relative;\n}\n\n.join-list .item .info .right-corner {\n\tposition: absolute;\n\tleft: 10rpx;\n\ttop: 0;\n\twidth: 100rpx;\n\theight: 50rpx;\n}\n\n.join-list .item .info .fold {\n\twidth: 100%;\n\ttext-align: center;\n\tfont-size: 24rpx;\n\tcolor: #999;\n\tpadding: 0 20rpx 10rpx;\n}\n\n.join-list .item .info .info-item {\n\twidth: 100%;\n\tdisplay: flex;\n\talign-items: flex-start;\n\tjustify-content: flex-start;\n\tbackground-color: #fff;\n\tline-height: 1.5;\n\tfont-size: 25rpx;\n\tfont-weight: bold;\n\tmargin-bottom: 20rpx;\n}\n\n.join-list .item .info .info-item .title {\n\twidth: 160rpx;\n\tcolor: #777;\n\ttext-align: right;\n}\n\n.join-list .item .info .info-item .mao {\n\tcolor: #777;\n\ttext-align: left;\n\tmargin-right: 10rpx;\n}\n\n.join-list .item .info .info-item .content {\n\tflex: 1;\n\tcolor: #333;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: flex-start;\n}\n\n.join-list .item .info .info-item.add-time {\n\tfont-size: 24rpx !important;\n\tfont-weight: normal !important;\n\tborder-top: 1rpx dashed #ccc;\n\tpadding-top: 15rpx;\n}\n\n.join-list .item .info .oprt {\n\twidth: 100%;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tpadding: 0rpx 0 0rpx;\n}\n\n.join-list .item .info .oprt .btn {\n\tpadding: 0 30rpx;\n\tfont-size: 26rpx;\n\tborder-radius: 10rpx !important;\n}\n\n.cancel-area {\n\tborder: 1rpx solid #ddd;\n}\n\n.time-line {\n\twidth: 100%;\n\ttext-align: right;\n\tfont-size: 24rpx;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/list/admin_meet_list.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst AdminMeetBiz = require('../../../../biz/admin_meet_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\t//设置搜索菜单\n\t\tawait this._getSearchMenu();\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: async function () { },\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\turl: async function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\n\tbindCommListCmpt: function (e) {\n\t\tpageHelper.commListListener(this, e);\n\t},\n\n\tbindScanTap: function (e) {\n\t\tlet meetId = pageHelper.dataset(e, 'id');\n\t\tlet title = encodeURIComponent(pageHelper.dataset(e, 'title'));\n\t\twx.navigateTo({\n\t\t\turl: '../scan/admin_meet_scan?meetId=' + meetId + '&title=' + title,\n\t\t});\n\t},\n\n\tbindRecordSelectTap: async function (e) {\n\t\tlet itemList = ['预约名单', '导出名单Excel文件', '管理员核销预约码', '用户自助签到码'];\n\t\tlet meetId = pageHelper.dataset(e, 'id');\n\t\tlet title = encodeURIComponent(pageHelper.dataset(e, 'title'));\n\n\t\twx.showActionSheet({\n\t\t\titemList,\n\t\t\tsuccess: async res => {\n\t\t\t\tswitch (res.tapIndex) {\n\t\t\t\t\tcase 0: { //预约名单 \n\t\t\t\t\t\twx.navigateTo({\n\t\t\t\t\t\t\turl: '../record/admin_record_list?meetId=' + meetId + '&title=' + title,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 1: { //导出 \n\t\t\t\t\t\twx.navigateTo({\n\t\t\t\t\t\t\turl: '../export/admin_join_export?meetId=' + meetId + '&title=' + title,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 2: { //核验 \n\t\t\t\t\t\tthis.bindScanTap(e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 3: { //自助签到码 \n\t\t\t\t\t\tpageHelper.showModal('请进入「名单与核销->预约名单->名单」， 查看某一时段的「用户自助签到码」');\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\n\t\t\t},\n\t\t\tfail: function (res) { }\n\t\t})\n\t},\n\n\t_setSort: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet meetId = pageHelper.dataset(e, 'id');\n\t\tlet sort = pageHelper.dataset(e, 'sort');\n\t\tif (!meetId) return;\n\n\t\tlet params = {\n\t\t\tmeetId,\n\t\t\tsort\n\t\t}\n\n\t\ttry {\n\t\t\tawait cloudHelper.callCloudSumbit('admin/meet_sort', params).then(res => {\n\t\t\t\tpageHelper.modifyListNode(meetId, this.data.dataList.list, 'MEET_ORDER', sort);\n\t\t\t\tthis.setData({\n\t\t\t\t\tdataList: this.data.dataList\n\t\t\t\t});\n\t\t\t\tpageHelper.showSuccToast('设置成功');\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t}\n\t},\n\n\t_setVouch: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet id = pageHelper.dataset(e, 'id');\n\t\tlet vouch = pageHelper.dataset(e, 'vouch');\n\t\tif (!id) return;\n\n\t\tlet params = {\n\t\t\tid,\n\t\t\tvouch\n\t\t}\n\n\t\ttry {\n\t\t\tawait cloudHelper.callCloudSumbit('admin/meet_vouch', params).then(res => {\n\t\t\t\tpageHelper.modifyListNode(id, this.data.dataList.list, 'MEET_VOUCH', vouch);\n\t\t\t\tthis.setData({\n\t\t\t\t\tdataList: this.data.dataList\n\t\t\t\t});\n\t\t\t\tpageHelper.showSuccToast('设置成功');\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t}\n\t},\n\n\tbindMoreSelectTap: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tlet idx = pageHelper.dataset(e, 'idx');\n\n\t\tlet order = this.data.dataList.list[idx].MEET_ORDER;\n\t\tlet orderDesc = (order == 0) ? '取消置顶' : '置顶';\n\n\t\tlet vouch = this.data.dataList.list[idx].MEET_VOUCH;\n\t\tlet vouchDesc = (vouch == 0) ? '推荐到首页' : '取消首页推荐';\n\n\t\tlet itemList = ['预览', orderDesc, vouchDesc, '生成专属二维码']; \n\t\n\t\twx.showActionSheet({\n\t\t\titemList,\n\t\t\tsuccess: async res => {\n\t\t\t\tswitch (res.tapIndex) {\n\t\t\t\t\tcase 0: { //预览\n\t\t\t\t\t\tlet meetId = pageHelper.dataset(e, 'id');\n\t\t\t\t\t\twx.navigateTo({\n\t\t\t\t\t\t\turl: pageHelper.fmtURLByPID('/pages/meet/detail/meet_detail?id=' + meetId),\n\t\t\t\t\t\t});\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 1: { //置顶 \n\t\t\t\t\t\tlet sort = (order == 0) ? 9999 : 0;\n\t\t\t\t\t\te.currentTarget.dataset['sort'] = sort;\n\t\t\t\t\t\tawait this._setSort(e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 2: { //上首页 \n\t\t\t\t\t\tvouch = (vouch == 0) ? 1 : 0;\n\t\t\t\t\t\te.currentTarget.dataset['vouch'] = vouch;\n\t\t\t\t\t\tawait this._setVouch(e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 3: { //二维码 \n\t\t\t\t\t\tlet title = encodeURIComponent(pageHelper.dataset(e, 'title'));\n\t\t\t\t\t\tlet qr = encodeURIComponent(pageHelper.dataset(e, 'qr')); \n\t\t\t\t\t\twx.navigateTo({\n\t\t\t\t\t\t\turl: `../../setup/qr/admin_setup_qr?title=${title}&qr=${qr}`,\n\t\t\t\t\t\t})\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\n\t\t\t},\n\t\t\tfail: function (res) { }\n\t\t})\n\t},\n\n\tbindStatusSelectTap: async function (e) {\n\t\tlet itemList = ['启用', '停止预约 (用户可见)', '关闭 (用户不可见)', '删除'];\n\t\tlet meetId = pageHelper.dataset(e, 'id');\n\t\twx.showActionSheet({\n\t\t\titemList,\n\t\t\tsuccess: async res => {\n\t\t\t\tswitch (res.tapIndex) {\n\t\t\t\t\tcase 0: { //启用\n\t\t\t\t\t\tawait this._setStatus(this, meetId, 1);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 1: { //停止预约\n\t\t\t\t\t\tawait this._setStatus(this, meetId, 9);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 2: { //关闭\n\t\t\t\t\t\tawait this._setStatus(this, meetId, 10);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 3: { //删除\n\t\t\t\t\t\tawait this._del(this, meetId);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} \n\n\t\t\t\t}\n\n\n\t\t\t},\n\t\t\tfail: function (res) { }\n\t\t})\n\t}, \n \n\n\t_del: async function (that, meetId) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tif (!meetId) return;\n\n\t\tlet params = {\n\t\t\tmeetId\n\t\t}\n\n\t\tlet callback = async function () {\n\t\t\ttry {\n\t\t\t\tlet opts = {\n\t\t\t\t\ttitle: '删除中'\n\t\t\t\t}\n\t\t\t\tawait cloudHelper.callCloudSumbit('admin/meet_del', params, opts).then(res => {\n\t\t\t\t\tpageHelper.delListNode(meetId, that.data.dataList.list, '_id');\n\t\t\t\t\tthat.data.dataList.total--;\n\t\t\t\t\tthat.setData({\n\t\t\t\t\t\tdataList: that.data.dataList\n\t\t\t\t\t});\n\t\t\t\t\tpageHelper.showSuccToast('删除成功');\n\t\t\t\t});\n\t\t\t} catch (e) {\n\t\t\t\tconsole.log(e);\n\t\t\t}\n\t\t}\n\t\tpageHelper.showConfirm('确认删除？删除不可恢复', callback);\n\n\t},\n\n\t_setStatus: async function (that, meetId, status) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tif (!meetId) return;\n\n\t\tlet params = {\n\t\t\tmeetId,\n\t\t\tstatus\n\t\t}\n\t\ttry {\n\t\t\tawait cloudHelper.callCloudSumbit('admin/meet_status', params).then(res => {\n\t\t\t\tpageHelper.modifyListNode(meetId, that.data.dataList.list, 'MEET_STATUS', status, '_id');\n\t\t\t\tthat.setData({\n\t\t\t\t\tdataList: that.data.dataList\n\t\t\t\t});\n\t\t\t\tpageHelper.showSuccToast('设置成功');\n\t\t\t});\n\t\t} catch (e) {\n\t\t\tconsole.log(e);\n\t\t}\n\t},\n\n\t_getSearchMenu: async function () {\n\t\tlet sortItem1 = [{ label: '分类', type: '', value: '' }];\n\t\tsortItem1 = sortItem1.concat(AdminMeetBiz.getTypeList()); \n\n\t\tlet sortItems = [sortItem1];\n\n\t\tlet sortMenus = [{\n\t\t\tlabel: '全部',\n\t\t\ttype: '',\n\t\t\tvalue: ''\n\t\t}, {\n\t\t\tlabel: '使用中',\n\t\t\ttype: 'status',\n\t\t\tvalue: 1\n\t\t},\n\t\t{\n\t\t\tlabel: '已停止',\n\t\t\ttype: 'status',\n\t\t\tvalue: 9\n\t\t},\n\t\t{\n\t\t\tlabel: '已关闭',\n\t\t\ttype: 'status',\n\t\t\tvalue: 10\n\t\t},\n\n\t\t]; \n\t\tthis.setData({\n\t\t\tsortItems,\n\t\t\tsortMenus\n\t\t})\n\n\n\t}\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/list/admin_meet_list.json",
    "content": "{\n\t\"usingComponents\": {\n\n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\", \n\t\"disableScroll\": true, \n\t\"navigationBarTitleText\": \"预约管理\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/list/admin_meet_list.wxml",
    "content": "<block wx:if=\"{{isAdmin}}\">\n\t<cmpt-comm-list source='admin' type=\"admin-meet\" search=\"{{search}}\" _menus=\"{{sortMenus}}\" _items=\"{{sortItems}}\" route=\"admin/meet_list\" sortMenusDefaultIndex=\"0\" topBottom=\"50\" placeholder=\"搜索标题\" bind:list=\"bindCommListCmpt\">\n\n\t\t<view slot=\"searchEnd\">\n\t\t\t<button bindtap=\"url\" data-url=\"../edit/admin_meet_edit\" class=\"btn radius bg-admin text-white  margin-right-s\"><text class=\"icon-roundadd margin-right-xxs\"></text>创建预约</button>\n\t\t</view>\n\n\t\t<!-- List Begin -->\n\t\t<view class=\"admin-comm-list\">\n\t\t\t<view wx:if=\"{{dataList && dataList.total }}\" class=\"load text-grey\">共有{{dataList.total}}条符合条件记录 </view>\n\n\t\t\t<view class=\"item\" wx:for=\"{{dataList.list}}\" wx:key=\"key\">\n\t\t\t\t<view class=\"no\">{{index+1}}</view>\n\t\t\t\t<view class=\"header\">\n\t\t\t\t\t<view class=\"left text-cut\"><text wx:if=\"{{item.MEET_ORDER==0}}\" class=\"text-black\" style=\"font-weight:normal;font-size:24rpx\">[置顶]</text><text wx:if=\"{{item.MEET_VOUCH==1}}\" class=\"text-black margin-right-xxs\" style=\"font-weight:normal;font-size:24rpx\">[首页推荐]</text> {{item.MEET_TITLE}}\n\t\t\t\t\t</view>\n\t\t\t\t\t<view class=\"right\" bindtap=\"bindScanTap\" data-id=\"{{item._id}}\" data-title=\"{{item.MEET_TITLE}}\">\n\t\t\t\t\t\t<text class=\"icon-scan\"></text>\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\n\t\t\t\t<view class=\"info\">\n\t\t\t\t\t<view class=\"info-item\">\n\t\t\t\t\t\t<view class=\"title\">状态</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view class=\"content\">\n\t\t\t\t\t\t\t<text wx:if=\"{{item.MEET_STATUS==0}}\" class=\"text-grey\">未启用</text>\n\t\t\t\t\t\t\t<text wx:elif=\"{{item.MEET_STATUS==1}}\" class=\"text-black\">使用中</text>\n\t\t\t\t\t\t\t<text wx:elif=\"{{item.MEET_STATUS==9}}\" class=\"text-grey\">停止 (用户可见)</text>\n\t\t\t\t\t\t\t<text wx:elif=\"{{item.MEET_STATUS==10}}\" class=\"text-grey\">已关闭 (用户不可见)</text>\n\t\t\t\t\t\t</view>\n\t\t\t\t\t</view>\n\n\t\t\t\t\t<view class=\"info-item\">\n\t\t\t\t\t\t<view class=\"title\">分类</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view class=\"content\">【{{item.MEET_TYPE_NAME}}】</view>\n\t\t\t\t\t</view>\n\n\t\t\t\t\t<view class=\"info-item\">\n\t\t\t\t\t\t<view class=\"title\">时段</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view class=\"content {{item.leaveDay==0?'text-grey':''}}\">{{item.leaveDay}}天可用</view>\n\t\t\t\t\t</view>\n\n\t\t\t\t\t<view class=\"info-item\">\n\t\t\t\t\t\t<view class=\"title\">变更</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view class=\"content\">{{item.MEET_EDIT_TIME}}</view>\n\t\t\t\t\t</view>\n\n\t\t\t\t\t<view class=\"oprt\">\n\t\t\t\t\t\t<view bindtap=\"url\" data-url=\"../edit/admin_meet_edit?id={{item._id}}\" class=\"btn margin-right-s\"><text class=\"icon-settings margin-right-xxs text-blue\"></text>设置</view>\n\n\t\t\t\t\t\t<view bindtap=\"bindRecordSelectTap\" data-id=\"{{item._id}}\" data-title=\"{{item.MEET_TITLE}}\" class=\"btn margin-right-s\">名单与核销</view>\n\n\t\t\t\t\t\t<view bindtap=\"bindStatusSelectTap\" data-id=\"{{item._id}}\" class=\"btn   margin-right-s\"><text class=\"icon-cascades margin-right-xxs text-orange\"></text>状态</view>\n\n\t\t\t\t\t\t<view bindtap=\"bindMoreSelectTap\" data-id=\"{{item._id}}\" data-idx=\"{{index}}\" data-qr=\"{{item.MEET_QR}}\" data-title=\"{{item.MEET_TITLE}}\" class=\"btn\">更多..</view>\n\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t</view>\n\t\t<!-- List END -->\n\n\t\t<!--load begin-->\n\t\t<import src=\"../../../../../../tpls/public/list_load_tpl.wxml\" />\n\t\t<template is=\"listLoadTpl\" data=\"{{skin:'text-grey',dataList}}\" />\n\t\t<!--load end-->\n \n\n\t</cmpt-comm-list>\n\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/list/admin_meet_list.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n@import '../../../../../../style/project/admin_list_style.wxss';\n\npage {\n\tbackground-color: #f8f8f8;\n}\n "
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/record/admin_record_list.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\nconst timeHelper = require('../../../../../../helper/time_helper.js');\n\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false,\n\n\t\tnow: timeHelper.time('Y-M-D'),\n\n\t\tsearchDayStart: '',\n\t\tsearchDayEnd: '',\n\n\t\tdaysSet: null,\n\n\t\ttitle: '',\n\t\ttitleEn: '',\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tif (!pageHelper.getOptions(this, options, 'meetId')) return;\n\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet searchDayStart = timeHelper.time('Y-M-D');\n\t\tlet searchDayEnd = timeHelper.time('Y-M-D');\n\t\tthis.setData({\n\t\t\tsearchDayStart,\n\t\t\tsearchDayEnd\n\t\t}, () => {\n\t\t\tthis._loadDetail();\n\t\t});\n\n\t\tif (options && options.title) {\n\t\t\tlet title = decodeURIComponent(options.title);\n\t\t\tthis.setData({\n\t\t\t\ttitle,\n\t\t\t\ttitleEn: options.title\n\t\t\t});\n\t\t\twx.setNavigationBarTitle({\n\t\t\t\ttitle: '预约名单统计 - ' + title\n\t\t\t});\n\t\t}\n\n\t},\n\n\t_loadDetail: async function () {\n\t\tlet meetId = this.data.meetId;\n\t\tif (!meetId) return;\n\n\t\tlet params = {\n\t\t\tmeetId,\n\t\t\tstart: this.data.searchDayStart,\n\t\t\tend: this.data.searchDayEnd\n\t\t};\n\t\tlet opt = {\n\t\t\ttitle: 'bar'\n\t\t};\n\t\ttry {\n\t\t\tthis.setData({\n\t\t\t\tdaysSet: null\n\t\t\t});\n\t\t\tawait cloudHelper.callCloudSumbit('admin/meet_day_list', params, opt).then(res => {\n\t\t\t\tthis.setData({\n\t\t\t\t\tisLoad: true,\n\t\t\t\t\tdaysSet: res.data\n\t\t\t\t}); \n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.error(err); \n\t\t}\n\n\n\t},\n\n\tbindSearchTomorrowTap: function (e) {\n\t\tthis.setData({\n\t\t\tsearchDayStart: timeHelper.time('Y-M-D', 86400),\n\t\t\tsearchDayEnd: timeHelper.time('Y-M-D', 86400),\n\t\t}, () => {\n\t\t\tthis._loadDetail();\n\t\t});\n\t},\n\n\tbindSearchYesterdayTap: function (e) {\n\t\tthis.setData({\n\t\t\tsearchDayStart: timeHelper.time('Y-M-D', -86400),\n\t\t\tsearchDayEnd: timeHelper.time('Y-M-D', -86400),\n\t\t}, () => {\n\t\t\tthis._loadDetail();\n\t\t});\n\t},\n\n\n\tbindSearchTodayTap: function (e) {\n\t\tthis.setData({\n\t\t\tsearchDayStart: timeHelper.time('Y-M-D'),\n\t\t\tsearchDayEnd: timeHelper.time('Y-M-D'),\n\t\t}, () => {\n\t\t\tthis._loadDetail();\n\t\t});\n\t},\n\n\tonPageScroll: function (e) {\n\t\tif (e.scrollTop > 100) {\n\t\t\tthis.setData({\n\t\t\t\ttopShow: true\n\t\t\t});\n\t\t} else {\n\t\t\tthis.setData({\n\t\t\t\ttopShow: false\n\t\t\t});\n\t\t}\n\t},\n\n\tbindTopTap: function () {\n\t\twx.pageScrollTo({\n\t\t\tscrollTop: 0\n\t\t})\n\t},\n\n\tbindSearchTap: function (e) {\n\t\tthis._loadDetail();\n\t},\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\t\tawait this._loadDetail();\n\t\twx.stopPullDownRefresh();\n\t},\n\n\t/**\n\t * 页面上拉触底事件的处理函数\n\t */\n\tonReachBottom: function () {\n\n\t},\n\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/record/admin_record_list.json",
    "content": "{\n\t\"usingComponents\": { \n\t\t\"cmpt-picker-time\": \"/cmpts/public/picker_time/picker_time_cmpt\"\n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\",\n\t\"enablePullDownRefresh\": true, \n\t\"navigationBarTitleText\": \"预约名单统计\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/record/admin_record_list.wxml",
    "content": "<view wx:if=\"{{isLoad===null}}\" class=\"margin-top load notexist text-l text-grey\"></view>\n<view wx:if=\"{{isLoad===false}}\" class=\"margin-top load loading text-l text-grey\"></view>\n\n<block wx:if=\"{{isAdmin&&isLoad}}\">\n\t<view class=\"main-admin\">\n\t\t<view class=\"table margin-bottom sticky1\" style=\"width:100%\">\n\t\t\t<view class=\"table-top\">\n\t\t\t\t<view class=\"table-form\">\n\t\t\t\t\t<view class=\"item\">\n\t\t\t\t\t\t<view class=\"title\">起始日期：</view>\n\t\t\t\t\t\t<cmpt-picker-time mode=\"day\" style=\"flex:1\" startYear=\"2022\" endYear=\"2025\" item=\"{{searchDayStart}}\" bind:select=\"url\" data-type='picker' data-item=\"searchDayStart\">\n\t\t\t\t\t\t\t<view class=\"content\">{{searchDayStart}}<text wx:if=\"{{!searchDayStart}}\" class=\"margin-left-xxs icon-calendar\"></text></view>\n\t\t\t\t\t\t</cmpt-picker-time>\n\t\t\t\t\t</view>\n\n\t\t\t\t\t<view class=\"item\">\n\t\t\t\t\t\t<view class=\"title\">结束日期：</view>\n\t\t\t\t\t\t<cmpt-picker-time mode=\"day\" style=\"flex:1\" startYear=\"2022\" endYear=\"2025\" item=\"{{searchDayEnd}}\" bind:select=\"url\" data-type='picker' data-item=\"searchDayEnd\">\n\t\t\t\t\t\t\t<view class=\"content\">{{searchDayEnd}}<text wx:if=\"{{!searchDayEnd}}\" class=\"margin-left-xxs icon-calendar\"></text></view>\n\t\t\t\t\t\t</cmpt-picker-time>\n\t\t\t\t\t</view>\n\t\t\t\t\t<view class=\"oprt\"> \n\t\t\t\t\t\t<view bindtap=\"bindSearchYesterdayTap\" hover-class=\"button-hover\" class=\"min-btn margin-right-xs\">昨日</view>\n\t\t\t\t\t\t<view bindtap=\"bindSearchTodayTap\" hover-class=\"button-hover\" class=\"min-btn margin-right-xs\">今日</view>\n\t\t\t\t\t\t<view bindtap=\"bindSearchTomorrowTap\" hover-class=\"button-hover\" class=\"min-btn margin-right-xs\">明日</view>\n\t\t\t\t\t\t<!--<view bindtap=\"bindSearchClearTap\" hover-class=\"button-hover\" class=\"margin-right-xs\">清空</view>-->\n\t\t\t\t\t\t<view bindtap=\"bindSearchTap\" hover-class=\"button-hover\" class=\"submit margin-right-xs\">搜索</view>\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\t\t\t\t<!-- 表格头 start -->\n\t\t\t\t<view class=\"thead border\">\n\t\t\t\t\t<view class=\"td\" style=\"width:220rpx;\">时段</view>\n\t\t\t\t\t<view class=\"td\" style=\"width:230rpx;\">已预约/名额</view>\n\t\t\t\t\t<view class=\"td\" style=\"width:150rpx;\">取消</view>\n\t\t\t\t\t<view class=\"td full\">查看</view>\n\t\t\t\t</view>\n\t\t\t\t<!-- 表格头 end -->\n\t\t\t</view>\n\n\t\t\t<!-- 表格体 start -->\n\t\t\t<view class=\"tbody\" wx:for=\"{{daysSet}}\" wx:key=\"key\">\n\n\t\t\t\t<view class=\"line\"><text class=\"{{item.day<now?'text-grey':''}} {{item.day==now?'text-blue text-bold':''}}\">{{item.day}}<text wx:if=\"{{item.day<now}}\" class=\"margin-left-xxs\">(已过期)</text><text wx:if=\"{{item.day==now}}\" class=\"margin-left-xxs\">(今日)</text></text></view>\n\n\t\t\t\t<view class=\"tr stripe border\" wx:for=\"{{item.times}}\" wx:key=\"key1\" wx:for-item=\"itm\" wx:for-index=\"idx\">\n\t\t\t\t\t<view class=\"td\" style=\"width:220rpx\">{{itm.start}}～{{itm.end}}</view>\n\n\t\t\t\t\t<view class=\"td\" style=\"width:230rpx\"><text class=\"{{itm.stat.succCnt?'text-bold':''}}\">{{itm.stat.succCnt}}</text><text class=\"margin-right-xxxs margin-left-xxxs\">/</text>{{itm.isLimit?itm.limit:'不限'}}</view>\n\n\t\t\t\t\t<view class=\"td text-grey\" style=\"width:150rpx\">{{itm.stat.cancelCnt+itm.stat.adminCancelCnt}}</view>\n\t\t\t\t\t\n\t\t\t\t\t<view bindtap=\"url\" data-url=\"../join/admin_meet_join?meetId={{meetId}}&mark={{itm.mark}}&dayidx={{index}}&timeidx={{idx}}&title={{titleEn}}&time={{(item.day+' ' + itm.start + '-' + itm.end)}}\" class=\"td full\">名单<text class=\"icon-right\"></text></view>\n\t\t\t\t</view>\n\t\t\t</view>\n\n\t\t\t<view wx:if=\"{{daysSet===null}}\" class=\"no-data\">数据加载中...</view>\n\t\t\t<view wx:if=\"{{daysSet.length==0}}\" class=\"no-data\">没有数据哦~</view>\n\n\t\t</view>\n\n\t</view>\n\n\t<!-- top begin -->\n\t<button wx:if=\"{{topShow}}\" class=\"btn-fixed bg-gray text-gray btn-top\" bindtap=\"bindTopTap\" style=\"bottom:100rpx\"><text class=\"icon-top\"></text></button>\n\t<!-- top END. -->\n\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/record/admin_record_list.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n@import '../../../../../../style/base/table.wxss';\n\n.main-admin {\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tpadding: 0rpx 0rpx 30rpx; \n}\n\n.table .table-form .oprt .min-btn {\n\tpadding: 5rpx 30rpx;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/scan/admin_meet_scan.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js'); \nconst cloudHelper = require('../../../../../../helper/cloud_helper.js'); \n\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: true,\n\t\ttitle: '',\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tif (!pageHelper.getOptions(this, options, 'meetId')) return;\n\n\t\tif (options && options.title) {\n\t\t\tlet title = decodeURIComponent(options.title);\n\t\t\tthis.setData({\n\t\t\t\ttitle\n\t\t\t});\n\t\t}\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\tbindScanTap: function (e) {\n\t\tlet meetId = this.data.meetId;\n\t\twx.scanCode({\n\t\t\tasync success(res) {\n\t\t\t\tconsole.log(res)\n\t\t\t\tif (!res ||\n\t\t\t\t\t!res.result ||\n\t\t\t\t\t!res.result.includes('meet=') ||\n\t\t\t\t\tres.result.length != 20) {\n\t\t\t\t\tpageHelper.showModal('错误的预约码，请重新扫码');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tlet code = res.result.replace('meet=', '');\n\t\t\t\tlet params = {\n\t\t\t\t\tmeetId,\n\t\t\t\t\tcode\n\t\t\t\t};\n\t\t\t\tlet options = {\n\t\t\t\t\ttitle: '预约码核销中'\n\t\t\t\t}\n\t\t\t\tawait cloudHelper.callCloudSumbit('admin/join_scan', params, options).then(res => {\n\t\t\t\t\tpageHelper.showModal('核销成功');\n\n\t\t\t\t}).catch(err => {\n\t\t\t\t\tconsole.log(err);\n\t\t\t\t});\n\t\t\t},\n\t\t\tfail(err) {\n\t\t\t\tif (err && err.errMsg == 'scanCode:fail')\n\t\t\t\t\tpageHelper.showModal('预约码核销错误，请重新扫码');\n\t\t\t}\n\t\t});\n\t}\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/scan/admin_meet_scan.json",
    "content": "{\n\t\"usingComponents\": {\n\t\t\"cmpt-picker-time\": \"/cmpts/public/picker_time/picker_time_cmpt\"\n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\", \n\t\"enablePullDownRefresh\": true,  \n\t\"navigationBarTitleText\": \"管理员扫码核销\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/scan/admin_meet_scan.wxml",
    "content": "<view wx:if=\"{{!isLoad}}\" class=\"margin-top load loading text-l text-admin\"></view>\n\n\n<view class=\"main-admin\" wx:if=\"{{isAdmin&&isLoad}}\">\n\t<view class=\"form-box shadow\">\n\t\t<view class=\"form-group\">\n\t\t\t<view class=\"title text-cut\">{{title}}</view>\n\t\t</view>\n\n\t</view>\n\n\t<view class=\"form-box shadow margin-top-xs\">\n\n\t\t<view class=\"checkin\" bindtap=\"bindScanTap\">\n\t\t\t<view class=\"notice\"><text class=\"icon-scan margin-right-s text-bold\"></text>扫码核销</view>\n\t\t\t<view class=\"desc\">管理员扫描用户预约码进行签到核销</view>\n\t\t\t<view class=\"oprt\">立即核销</view>\n\t\t</view>\n\n\t</view>\n\n</view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/scan/admin_meet_scan.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss'; \n\n.form-box .checkin {\n\twidth: 100%;\n\tpadding: 40rpx 40rpx 80rpx;\n\tpadding-bottom: 150rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: flex-start;\n\talign-items: center;\n}\n\n.form-box .checkin .notice {\n\twidth: 100%;\n\tfont-size: 46rpx;\n\ttext-align: center;\n\tcolor: #000;\n\tmargin-bottom: 30rpx;\n}\n\n.form-box .checkin .desc {\n\twidth: 100%;\n\tfont-size: 32rpx;\n\ttext-align: center;\n\tcolor: #666;\n}\n\n.form-box .checkin .oprt {\n\twidth: 600rpx;\n\tmargin-top: 40rpx;\n\ttext-align: center;\n\tfont-size: 34rpx;\n\tcolor: var(--adminColor);\n\tborder: 2rpx solid var(--adminColor);\n\tpadding: 30rpx 20rpx;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/self/admin_meet_self.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false,\n\t\tqrUrl: '',\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return; \n\t\tif (!pageHelper.getOptions(this, options, 'mark'));\n\n\t\tif (options && options.title) {\n\t\t\tlet title = decodeURIComponent(options.title);\n\t\t\tthis.setData({\n\t\t\t\ttitle\n\t\t\t});\n\t\t}\n\n\t\tawait this._loadDetail();\n\t},\n\n\t_loadDetail: async function () { \n\t\tlet timeMark = this.data.mark;\n\n\t\tlet page = pageHelper.fmtURLByPID(\"/pages/meet/self/meet_self\");\n\n\t\tlet params = { \n\t\t\ttimeMark,\n\t\t\tpage\n\t\t};\n\t\tlet opt = {\n\t\t\ttitle: 'bar'\n\t\t};\n\t\ttry {\n\t\t\tawait cloudHelper.callCloudSumbit('admin/self_checkin_qr', params, opt).then(res => {\n\t\t\t\tthis.setData({\n\t\t\t\t\tqrUrl: res.data,\n\t\t\t\t\tisLoad: true\n\t\t\t\t})\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.error(err);\n\t\t}\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\t\tawait this._loadDetail();\n\t\twx.stopPullDownRefresh();\n\t},\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t}\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/self/admin_meet_self.json",
    "content": "{\n\t\"usingComponents\": {\n\t \n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\", \n\t\"enablePullDownRefresh\": true,  \n\t\"navigationBarTitleText\": \"用户自助签到码\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/self/admin_meet_self.wxml",
    "content": "<view wx:if=\"{{!isLoad}}\" class=\"margin-top load loading text-l text-grey\"></view>\n\n\n<view class=\"main-admin\" wx:if=\"{{isAdmin&&isLoad}}\">\n\t<view class=\"form-box shadow\">\n\t\t<view class=\"form-group\">\n\t\t\t<view class=\"title text-cut\">{{title}}</view>\n\t\t</view>\n\n\t</view>\n\n\t<view class=\"form-box shadow margin-top-xs\">\n\n\t\t<view class=\"checkin\">\n\t\t\t<view class=\"notice\"><text class=\"icon-scan margin-right-s text-bold\"></text>用户自助核销/签到</view>\n\t\t\t<view class=\"desc\">\n\t\t\t\t<text class=\"text-black text-bold\">※ 签到规则</text>\n\t\t\t\t<text user-select=\"true\">1. 预约用户自行扫描下方小程序码完成核销/签到\n\t\t\t\t\t2. 用户在预约当天扫码有效，不可提前核销\n\t\t\t\t\t3. 在预约结束时间未到情况下，用户可自行扫码完成核销\n\t\t\t\t\t4. 若结束时间已到，需要管理员进行人工扫码核销或者在后台核销</text></view>\n\t\t\t<image bindtap=\"url\" data-type=\"img\" data-url=\"{{qrUrl}}\" mode=\"aspectFill\" class=\"loading\" show-menu-by-longpress=\"true\" src=\"{{qrUrl}}\"></image>\n\t\t\t<view class=\"oprt\">长按图片保存小程序码</view>\n\t\t</view>\n\n\t</view>\n\n</view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/self/admin_meet_self.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n \n.form-box .checkin {\n\twidth: 100%;\n\tpadding: 40rpx 40rpx 80rpx;\n\tpadding-bottom: 150rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: flex-start;\n\talign-items: center;\n}\n\n.form-box .checkin .notice {\n\twidth: 100%;\n\tfont-size: 46rpx;\n\ttext-align: center;\n\tcolor: #000;\n\tmargin-bottom: 30rpx;\n}\n\n.form-box .checkin .desc {\n\twidth: 100%;\n\tfont-size: 28rpx;\n\ttext-align: left;\n\tcolor: #666;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: flex-start;\n\tjustify-content: flex-start;\n}\n\n.form-box .checkin image {\n\twidth: 500rpx;\n\theight: 500rpx;\n\tmargin: 30rpx 0rpx;\n}\n\n.form-box .checkin .oprt { \n\tmargin-top: 0rpx;\n\ttext-align: center;\n\tfont-size: 30rpx;\n\tcolor: var(--adminColor); \n\tpadding: 20rpx 10rpx; \n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/temp/admin_temp_select.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\nconst AdminMeetBiz = require('../../../../biz/admin_meet_biz.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false,\n\n\t\ttemps: [],\n\n\t\tcurIdx: -1,\n\n\t\tcurTimeModalShow: false,\n\t\tcurTimeIsLimit: false, // 当前操作是否限制人数\n\t\tcurTimeLimit: 50, // 当前时段人数限制\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tawait this._loadList();\n\t},\n\n\tswitchModel: function (e) {\n\t\tpageHelper.switchModel(this, e, 'bool');\n\t},\n\n\tbindAllLimitSetCmpt: async function (e) {\n\t\tif (this.data.curIdx <= -1) return;\n\t\tlet temp = this.data.temps[this.data.curIdx];\n\n\t\ttry {\n\t\t\tlet opts = {\n\t\t\t\ttitle: '批量修改中'\n\t\t\t}\n\t\t\tlet params = {\n\t\t\t\tid: temp._id,\n\t\t\t\tlimit: this.data.curTimeLimit,\n\t\t\t\tisLimit: this.data.curTimeIsLimit\n\t\t\t}\n\t\t\tawait cloudHelper.callCloudSumbit('admin/meet_temp_edit', params, opts).then(res => {\n\t\t\t\tthis.setData({\n\t\t\t\t\ttemps: res.data,\n\t\t\t\t\tcurTimeModalShow: false,\n\t\t\t\t\tcurTimeIsLimit: false,\n\t\t\t\t\tcurTimeLimit: 50,\n\t\t\t\t});\n\t\t\t\tpageHelper.showSuccToast('修改成功');\n\t\t\t})\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t};\n\n\t},\n\n\t_loadList: async function () {\n\t\ttry {\n\t\t\tlet opts = {\n\t\t\t\ttitle: 'bar'\n\t\t\t}\n\t\t\tawait cloudHelper.callCloudSumbit('admin/meet_temp_list', {}, opts).then(res => {\n\t\t\t\tthis.setData({\n\t\t\t\t\tisLoad: res.data.length == 0 ? null : true,\n\t\t\t\t\ttemps: res.data\n\t\t\t\t})\n\t\t\t})\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t};\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\tonPullDownRefresh: async function () {\n\t\tawait this._loadList();\n\t\twx.stopPullDownRefresh();\n\t},\n\n\tbindSelectTap: function (e) {\n\t\tlet curIdx = pageHelper.dataset(e, 'idx');\n\t\tlet temps = this.data.temps[curIdx].TEMP_TIMES;\n\t\tlet name = this.data.temps[curIdx].TEMP_NAME;\n\n\t\tlet parent = pageHelper.getPrevPage(2);\n\t\tif (!parent) return;\n\t\tlet days = parent.data.days;\n\t\tlet day = days[parent.data.curIdx].day;\n\n\t\tlet callback = () => {\n\t\t\tlet times = [];\n\t\t\tfor (let k = 0; k < temps.length; k++) {\n\t\t\t\tlet node = AdminMeetBiz.getNewTimeNode(day);\n\t\t\t\tnode.start = temps[k].start;\n\t\t\t\tnode.end = temps[k].end;\n\t\t\t\tnode.limit = temps[k].limit;\n\t\t\t\tnode.isLimit = temps[k].isLimit;\n\t\t\t\ttimes.push(node);\n\t\t\t}\n\t\t\tdays[parent.data.curIdx].times = times;\n\t\t\tparent.setData({\n\t\t\t\tdays\n\t\t\t});\n\t\t\twx.navigateBack();\n\t\t}\n\n\t\tpageHelper.showConfirm('确认要选用模板 「' + name + '」配置到日期 「' + day + '」下吗?', callback);\n\t},\n\n\t_delTemp: async function (curIdx, id) {\n\t\ttry {\n\t\t\tlet opts = {\n\t\t\t\ttitle: '删除中'\n\t\t\t}\n\t\t\tlet params = {\n\t\t\t\tid\n\t\t\t}\n\t\t\tawait cloudHelper.callCloudSumbit('admin/meet_temp_del', params, opts).then(res => {\n\t\t\t\tlet temps = this.data.temps;\n\t\t\t\ttemps.splice(curIdx, 1);\n\t\t\t\tthis.setData({\n\t\t\t\t\ttemps\n\t\t\t\t});\n\t\t\t\tif (temps.length == 0) {\n\t\t\t\t\tthis.setData({\n\t\t\t\t\t\tisLoad: null\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t})\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t};\n\t},\n\n\tbindOprtTap: function (e) {\n\t\tlet curIdx = pageHelper.dataset(e, 'idx');\n\n\t\tlet itemList = ['删除模板', '批量设置人数上限'];\n\t\twx.showActionSheet({\n\t\t\titemList,\n\t\t\tsuccess: async res => {\n\t\t\t\tlet idx = res.tapIndex;\n\t\t\t\tif (idx == 0) { // 删除\n\t\t\t\t\tlet temps = this.data.temps;\n\t\t\t\t\tlet name = temps[curIdx].TEMP_NAME;\n\t\t\t\t\tlet callback = () => {\n\t\t\t\t\t\tthis._delTemp(curIdx, temps[curIdx]._id);\n\t\t\t\t\t}\n\n\t\t\t\t\tpageHelper.showConfirm('确认要删除模板 「' + name + '」吗?', callback);\n\t\t\t\t}\n\t\t\t\tif (idx == 1) {\n\t\t\t\t\tthis.setData({\n\t\t\t\t\t\tcurIdx,\n\t\t\t\t\t\tcurTimeModalShow: true\n\t\t\t\t\t});\n\t\t\t\t}\n\n\n\t\t\t},\n\t\t\tfail: function (res) { }\n\t\t})\n\t}\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/temp/admin_temp_select.json",
    "content": "{\n\t\"usingComponents\": { \n\t \n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\",\n\t\"enablePullDownRefresh\": true, \n\t\"navigationBarTitleText\": \"时间模板选择\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/temp/admin_temp_select.wxml",
    "content": "<view wx:if=\"{{isLoad===null}}\" class=\"margin-top load notexist text-l text-grey\"></view>\n<view wx:if=\"{{isLoad===false}}\" class=\"margin-top load loading text-l text-grey\"></view>\n\n<block wx:if=\"{{isAdmin}}\">\n\t<view class=\"main-admin\">\n\t\t<view class=\"text-pic-list-box\">\n\t\t\t<view class=\"item shadow\" wx:for=\"{{temps}}\" wx:key=\"key\">\n\t\t\t\t<view class=\"title\">\n\t\t\t\t\t<text bindtap=\"bindSelectTap\" data-idx=\"{{index}}\" class=\"temp-name text-cut\">{{item.TEMP_NAME}}</text>\n\t\t\t\t\t<button bindtap=\"bindSelectTap\" data-idx=\"{{index}}\" class=\"btn mid bg-admin text-white margin-right-s\" style=\"font-weight: normal;\">选用</button>\n\t\t\t\t\t<text bindtap=\"bindOprtTap\" data-idx=\"{{index}}\" class=\"icon-moreandroid more\"></text>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"time-list\">\n\t\t\t\t\t<view wx:for=\"{{item.TEMP_TIMES}}\" wx-for wx:key=\"key1\" wx:for-item=\"timesItem\" wx:for-index=\"timesIndex\" class=\"time-item\">\n\t\t\t\t\t\t<view class=\"detail\">\n\t\t\t\t\t\t\t<text class=\"up\">{{timesItem.start}}～{{timesItem.end}}</text>\n\t\t\t\t\t\t\t<text wx:if=\"{{timesItem.isLimit}}\" class=\"text-admin\">{{timesItem.limit}}人</text>\n\t\t\t\t\t\t\t<text wx:else class=\"text-admin\">不限人数</text>\n\t\t\t\t\t\t</view>\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t</view>\n\t</view>\n\n\t<cmpt-modal model:show=\"{{curTimeModalShow}}\" type=\"dialog\" title=\"批量设置人数上限\" bind:click=\"bindAllLimitSetCmpt\" class=\"modal-form\">\n\t\t<view class=\"modal-desc text-green\">统一设置该模板下各时段可约人数</view>\n\n\t\t<view class=\"form-group\">\n\t\t\t<view class=\"title\">是否限制人数</view>\n\t\t\t<switch wx:if=\"{{curTimeIsLimit}}\" bindchange=\"switchModel\" data-item=\"curTimeIsLimit\" class=\"green sm\" checked=\"true\">\n\t\t\t</switch>\n\t\t\t<switch wx:elif=\"{{!curTimeIsLimit}}\" bindchange=\"switchModel\" data-item=\"curTimeIsLimit\" class=\"green sm\">\n\t\t\t</switch>\n\t\t</view>\n\t\t<view class=\"form-group\">\n\t\t\t<view class=\"title\">人数上限</view>\n\t\t\t<block wx:if=\"{{curTimeIsLimit}}\">\n\t\t\t\t<input type=\"number\" maxlength=\"4\" placeholder=\"请输入本时段人数上限\" model:value=\"{{curTimeLimit}}\" class=\"text-red margin-right-xs\"></input>人\n\t\t\t</block>\n\t\t\t<text wx:else>不限制人数</text>\n\t\t</view>\n\t</cmpt-modal>\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/temp/admin_temp_select.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n@import \"../../../../../../style/public/article_list.wxss\";\n\n.load.notexist::after {\n    content: \"您还没有可选用的模板哦\";\n} \n\n.text-pic-list-box .item {\n\tpadding: 18rpx 30rpx; \n\tposition: relative;\n}\n\n.item .time-list {\n\twidth: 100%;\n\tdisplay: flex;\n\talign-items: flex-start;\n\tjustify-content: flex-start;\n\tflex-wrap: wrap;\n\tmargin-top: 20rpx;\n}\n\n.item .time-list .time-item {\n\twidth: 33.33%;\n\tpadding: 10rpx;\n} \n\n.item .time-list .time-item .detail {\n\twidth: 100%;\n\tborder: 1rpx solid #ccc;\n\tborder-radius: 1rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n\talign-items: center;\n\tpadding: 13rpx 0;\n\theight: 130rpx;\n}\n\n.item .time-list .time-item .detail>text {\n\tfont-size: 30rpx;\n\tcolor: #555;\n\twidth: 100%;\n\ttext-align: center;\n}\n\n.item .time-list .time-item .detail .up {\n\tfont-size: 29rpx;\n}\n\n.item .detail.select {\n\tfont-size: 35rpx;\n\tbackground-color: #f8f8f8;  \n\tcolor:#777;\n} \n\n.item .title {\n\twidth: 100%;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tposition: relative;\n\tcolor:#333!important;\n\tmargin-left:15rpx;\n}\n\n.item .title .temp-name {\n\tflex: 1;  \n} \n\n.item .title .more{\n\tcolor:#777;\n\twidth:60rpx;\n\ttext-align: right;\n\tfont-size:40rpx;\n\tfont-weight: normal; \n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/time/admin_meet_time.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst dataHelper = require('../../../../../../helper/data_helper.js');\nconst timeHelper = require('../../../../../../helper/time_helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\nconst AdminMeetBiz = require('../../../../biz/admin_meet_biz.js');\nconst projectSetting = require('../../../../public/project_setting.js');\n\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tdaysTimeOptions: AdminMeetBiz.getDaysTimeOptions(),\n\n\t\tmultiDoDay: [], //当前选择\n\n\t\thasDays: [], //超时有数据(simple)\n\t\tlastHasDays: [], //超时有数据(full)\n\t\thasJoinDays: [], //未超时有预约\n\n\t\tdays: [\n\t\t\t/*{\n\t\t\t\t\t\tday: '2021-12-11',\n\t\t\t\t\t\tdayDesc: '12月11日 (周五)', \n\t\t\t\t\t\ttimes: [{ \n\t\t\t\t\t\t\tmark: '',\n\t\t\t\t\t\t\tstart: '10:15', //开始\n\t\t\t\t\t\t\tend: '23:59', // 结束\n\t\t\t\t\t\t\tlimit: 50, //人数限制\n\t\t\t\t\t\t\tisLimit: false,\n\t\t\t\t\t\t}]\n\t\t\t\t\t}, {\n\t\t\t\t\t\tday: '2022-01-11',\n\t\t\t\t\t\tdayDesc: '1月11日 (周日)', \n\t\t\t\t\t\ttimes: [{ \n\t\t\t\t\t\t\tmark: '',\n\t\t\t\t\t\t\tstart: '00:00', //开始\n\t\t\t\t\t\t\tend: '23:59', // 结束\n\t\t\t\t\t\t\tlimit: 89, //人数限制\n\t\t\t\t\t\t\tisLimit: true\n\t\t\t\t\t\t}]\n\t\t\t\t\t}*/\n\t\t],\n\n\t\tcurIdx: -1, // 当前操作的日子索引\n\t\tcurTimesIdx: -1, // 当前操作的时段索引\n\n\t\tcurTimeLimitModalShow: false,\n\t\tcurTimeIsLimit: false, // 当前操作是否限制人数\n\t\tcurTimeLimit: 50, // 当前时段人数限制\n\n\t\tsaveTempModalShow: false,\n\t\tformTempName: '',\n\n\t\tcancelModalShow: false, //删除对话框 \n\t\tformReason: '', //取消理由 \n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet parent = pageHelper.getPrevPage(2);\n\t\tif (parent) {\n\t\t\tlet formDaysSet = parent.data.formDaysSet;\n\n\t\t\tlet days = [];\n\t\t\tlet lastHasDays = [];\n\t\t\tlet hasJoinDays = [];\n\t\t\tlet now = timeHelper.time('Y-M-D');\n\n\t\t\tfor (let k = 0; k < formDaysSet.length; k++)  { //已超时无法编辑, 有数据显示form\n\t\t\t\tif (formDaysSet[k].day < now)\n\t\t\t\t\tlastHasDays.push(formDaysSet[k]);\n\t\t\t\telse {\n\t\t\t\t\tdays.push(formDaysSet[k]);\n\t\t\t\t\tif (this._checkHasJoinCnt(formDaysSet[k].times))\n\t\t\t\t\t\thasJoinDays.push(formDaysSet[k].day);\n\t\t\t\t}\n\n\t\t\t}\n\t\t\tthis.setData({\n\t\t\t\thasDays: dataHelper.getArrByKey(lastHasDays, 'day'),\n\t\t\t\tlastHasDays,\n\t\t\t\thasJoinDays,\n\t\t\t\tdays\n\t\t\t});\n\t\t\tthis._syncCalData();\n\n\t\t}\n\t},\n\n\t_setHasJoinDays: function () {\n\t\tlet days = this.data.days;\n\t\tlet now = timeHelper.time('Y-M-D');\n\t\tlet hasJoinDays = [];\n\n\t\tfor (let k = 0; k < days.length; k++)  {\n\t\t\tif (days[k].day < now)\n\t\t\t\tcontinue;\n\t\t\telse {\n\t\t\t\tif (this._checkHasJoinCnt(days[k].times))\n\t\t\t\t\thasJoinDays.push(days[k].day);\n\t\t\t}\n\t\t}\n\t\tthis.setData({\n\t\t\thasJoinDays\n\t\t});\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {},\n\n\tmodel: function (e) {\n\t\tpageHelper.model(this, e);\n\t},\n\n\t// 判断含有预约的日期\n\t_checkHasJoinCnt: function (times) {\n\t\tif (!times) return false;\n\t\tfor (let k = 0; k < times.length; k++)  {\n\t\t\tif (times[k].stat.succCnt || times[k].stat.waitCheckCnt) return true;\n\t\t}\n\t\treturn false;\n\t},\n\n\t_syncCalData: function (e) { // 同步日历选中 \n\t\tlet days = this.data.days;\n\t\tlet multiDoDay = dataHelper.getArrByKey(days, 'day');\n\t\tthis.setData({\n\t\t\tmultiDoDay,\n\t\t});\n\t},\n\n\tbindTimeAddTap: function (e) {\n\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\tlet days = this.data.days;\n\n\t\tif (days[idx].times.length >= 20) return pageHelper.showModal('最多可以添加20个时段');\n\n\t\tdays[idx].times.push(AdminMeetBiz.getNewTimeNode(days[idx].day));\n\n\t\tthis.setData({\n\t\t\tdays\n\t\t});\n\t},\n\n\tbindCancelMeetJoinCmpt: async function (e) { //取消已有预约\n\t\tlet curIdx = this.data.curIdx;\n\t\tlet curTimesIdx = this.data.curTimesIdx;\n\t\tlet days = this.data.days;\n\n\t\ttry {\n\t\t\tlet parent = pageHelper.getPrevPage(2);\n\t\t\tif (!parent) return;\n\t\t\tlet params = {\n\t\t\t\treason: this.data.formReason,\n\t\t\t\tmeetId: parent.data.id,\n\t\t\t\ttimeMark: days[curIdx].times[curTimesIdx].mark\n\t\t\t}\n\t\t\tlet opt = {\n\t\t\t\ttitle: '预约记录取消中'\n\t\t\t}\n\t\t\tawait cloudHelper.callCloudSumbit('admin/meet_cancel_time_join', params, opt).then(res => {\n\t\t\t\tlet callback = () => {\n\t\t\t\t\tdays[curIdx].times.splice(curTimesIdx, 1);\n\t\t\t\t\tthis.setData({\n\t\t\t\t\t\tdays,\n\t\t\t\t\t\tcancelModalShow: false,\n\t\t\t\t\t\tformReason: ''\n\t\t\t\t\t});\n\t\t\t\t\tthis._setHasJoinDays();\n\t\t\t\t}\n\t\t\t\tpageHelper.showSuccToast('取消成功', 1500, callback);\n\t\t\t})\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t};\n\t},\n\n\tbindTimeDelTap: function (e) {\n\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\tlet timesIdx = pageHelper.dataset(e, 'timesidx');\n\t\tlet days = this.data.days;\n\t\tlet node = days[idx].times[timesIdx];\n\n\t\tif (node.stat.succCnt || node.stat.waitCheckCnt) {\n\t\t\tlet callback = async () => {\n\t\t\t\tthis.setData({\n\t\t\t\t\tformReason: '',\n\t\t\t\t\tcurIdx: idx,\n\t\t\t\t\tcurTimesIdx: timesIdx,\n\t\t\t\t\tcancelModalShow: true //显示对话框\n\t\t\t\t});\n\t\t\t};\n\t\t\tpageHelper.showConfirm('该时段已有「' + (node.stat.succCnt + node.stat.waitCheckCnt) + '人」预约/预约待审核，若选择删除则将取消所有预约，请仔细确认！ 若不想取消，可以选择停止该时段', callback);\n\t\t} else {\n\t\t\tlet callback = () => {\n\t\t\t\tdays[idx].times.splice(timesIdx, 1);\n\t\t\t\tthis.setData({\n\t\t\t\t\tdays\n\t\t\t\t});\n\t\t\t};\n\t\t\tpageHelper.showConfirm('是否要删除该时间段？', callback);\n\t\t}\n\t},\n\n\tbindTimeStatusSwitch: function (e) {\n\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\tlet timesIdx = pageHelper.dataset(e, 'timesidx');\n\t\tlet days = this.data.days;\n\t\tlet status = days[idx].times[timesIdx].status;\n\n\t\tif (status == 0) {\n\t\t\tdays[idx].times[timesIdx].status = 1;\n\t\t\tthis.setData({\n\t\t\t\tdays\n\t\t\t});\n\t\t} else {\n\t\t\tlet yes = () => {\n\t\t\t\tdays[idx].times[timesIdx].status = 0;\n\t\t\t\tthis.setData({\n\t\t\t\t\tdays\n\t\t\t\t});\n\t\t\t};\n\t\t\tpageHelper.showConfirm('是否要停止该时间段的预约？停止后，已有预约记录仍将保留', yes);\n\t\t}\n\n\t},\n\n\tbindDaysTimeStartCmpt: function (e) {\n\t\tlet start = e.detail.join(':');\n\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\tlet timesIdx = pageHelper.dataset(e, 'timesidx');\n\n\t\tlet days = this.data.days;\n\n\t\tlet end = days[idx].times[timesIdx].end;\n\t\tif (start >= end) return pageHelper.showModal('开始时间不能大于等于结束时间');\n\n\t\tdays[idx].times[timesIdx].start = start;\n\t\tthis.setData({\n\t\t\tdays\n\t\t});\n\t},\n\n\tbindDaysTimeEndCmpt: function (e) {\n\t\tlet end = e.detail.join(':');\n\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\tlet timesIdx = pageHelper.dataset(e, 'timesidx');\n\n\t\tlet days = this.data.days;\n\n\t\tlet start = days[idx].times[timesIdx].start;\n\t\tif (start >= end) return pageHelper.showModal('开始时间不能大于等于结束时间');\n\n\t\tdays[idx].times[timesIdx].end = end;\n\t\tthis.setData({\n\t\t\tdays\n\t\t});\n\t},\n\n\tswitchModel: function (e) {\n\t\tpageHelper.switchModel(this, e, 'bool');\n\t},\n\n\tbindSaveTempCmpt: async function (e) {\n\t\ttry {\n\t\t\tlet name = this.data.formTempName;\n\t\t\tif (name.length <= 0) return pageHelper.showNoneToast('请填写模板名称');\n\t\t\tif (name.length > 20) return pageHelper.showNoneToast('模板名称不能超过20个字哦');\n\n\t\t\tlet days = this.data.days;\n\t\t\tlet times = days[this.data.curIdx].times;\n\t\t\tif (times.length <= 0) return pageHelper.showNoneToast('至少需要包含一个时段');\n\t\t\tif (times.length > 20) return pageHelper.showNoneToast('时段不能超过20个');\n\n\t\t\tlet temps = [];\n\t\t\tfor (let k = 0; k < times.length; k++)  {\n\t\t\t\tlet node = {};\n\t\t\t\tnode.start = times[k].start;\n\t\t\t\tnode.end = times[k].end;\n\t\t\t\tnode.isLimit = times[k].isLimit;\n\t\t\t\tnode.limit = times[k].limit;\n\t\t\t\ttemps.push(node);\n\t\t\t}\n\t\t\tlet opt = {\n\t\t\t\ttitle: '模板保存中'\n\t\t\t}\n\t\t\tlet params = {\n\t\t\t\tname,\n\t\t\t\ttimes: temps\n\t\t\t}\n\t\t\tawait cloudHelper.callCloudSumbit('admin/meet_temp_insert', params, opt).then(res => {\n\t\t\t\tpageHelper.showSuccToast('保存成功');\n\t\t\t\tthis.setData({\n\t\t\t\t\tsaveTempModalShow: false,\n\t\t\t\t\tformTempName: '',\n\t\t\t\t});\n\t\t\t})\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t};\n\t},\n\n\tbindTimeLimitSetCmpt: function (e) {\n\t\tlet days = this.data.days;\n\t\tlet idx = this.data.curIdx;\n\t\tlet timesIdx = this.data.curTimesIdx;\n\n\t\tif (this.data.curTimesIdx == -1) {\n\t\t\t// 全天\n\t\t\tfor (let k = 0; k < days[idx].times.length; k++)  { \n\t\t\t\tdays[idx].times[k].isLimit = this.data.curTimeIsLimit;\n\t\t\t\tdays[idx].times[k].limit = this.data.curTimeLimit;\n\t\t\t}\n\t\t} else {\n\n\t\t\t// 某时间段\n\t\t\tlet node = days[idx].times[timesIdx];\n\t\t\tnode.isLimit = this.data.curTimeIsLimit;\n\t\t\tnode.limit = this.data.curTimeLimit;\n\t\t\tdays[idx].times[timesIdx] = node;\n\t\t}\n\n\t\tthis.setData({\n\t\t\tdays,\n\t\t\tcurTimeLimitModalShow: false\n\t\t});\n\t},\n\n\tbindShowTimeLimitModalTap: function (e) {\n\t\tlet curIdx = pageHelper.dataset(e, 'idx');\n\t\tlet curTimesIdx = pageHelper.dataset(e, 'timesidx');\n\n\t\tlet days = this.data.days;\n\n\t\tif (curTimesIdx == -1) {\n\t\t\t// 全天\n\t\t\tthis.setData({\n\t\t\t\tcurIdx,\n\t\t\t\tcurTimesIdx: -1,\n\t\t\t\tcurTimeIsLimit: false,\n\t\t\t\tcurTimeLimit: 50,\n\t\t\t\tcurTimeLimitModalShow: true\n\t\t\t});\n\t\t} else {\n\t\t\t// 时间段\n\t\t\tlet node = days[curIdx].times[curTimesIdx];\n\t\t\tlet curTimeIsLimit = node.isLimit;\n\t\t\tlet curTimeLimit = node.limit;\n\t\t\tthis.setData({\n\t\t\t\tcurIdx,\n\t\t\t\tcurTimesIdx,\n\t\t\t\tcurTimeIsLimit,\n\t\t\t\tcurTimeLimit,\n\t\t\t\tcurTimeLimitModalShow: true\n\t\t\t});\n\t\t}\n\t},\n\n\t_selectTemp: function (e) {\n\t\tlet curIdx = pageHelper.dataset(e, 'idx');\n\n\t\tif (this._checkHasJoinCnt(this.data.days[curIdx].times)) {\n\t\t\treturn pageHelper.showModal('该日已有用户预约/预约待审核，不能选用模板。若确定要选用模板，请先删除有预约的时段');\n\t\t}\n\n\t\tthis.setData({\n\t\t\tcurIdx\n\t\t});\n\t\twx.navigateTo({\n\t\t\turl: '../temp/admin_temp_select',\n\t\t});\n\t},\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\t_saveTempModal: function (e) {\n\t\tlet curIdx = pageHelper.dataset(e, 'idx');\n\t\tlet days = this.data.days;\n\t\tif (days[curIdx].times.length <= 0) return pageHelper.showModal('该日期下没有设置时段，无法保存为模板，请先添加时段');\n\t\tthis.setData({\n\t\t\tsaveTempModalShow: true,\n\t\t\tcurIdx\n\t\t});\n\t},\n\n\t_copyDaySetToAll: function (e) { //  复制到所有\n\t\tlet curIdx = pageHelper.dataset(e, 'idx');\n\t\tlet days = this.data.days;\n\t\tlet day = days[curIdx].day;\n\t\tlet temps = days[curIdx].times;\n\n\t\tlet callback = () => {\n\t\t\tfor (let k = 0; k < days.length; k++)  { \n\t\t\t\tif (this._checkHasJoinCnt(days[k].times)) continue; //自己和有记录不复制\n\n\t\t\t\tlet times = [];\n\t\t\t\tfor (let j in temps) {\n\t\t\t\t\tlet node = AdminMeetBiz.getNewTimeNode(days[k].day);\n\t\t\t\t\tnode.start = temps[j].start;\n\t\t\t\t\tnode.end = temps[j].end;\n\t\t\t\t\tnode.limit = temps[j].limit;\n\t\t\t\t\tnode.isLimit = temps[j].isLimit;\n\t\t\t\t\ttimes.push(node);\n\t\t\t\t}\n\t\t\t\tdays[k].times = times;\n\t\t\t}\n\t\t\tthis.setData({\n\t\t\t\tdays\n\t\t\t});\n\t\t}\n\n\t\tpageHelper.showConfirm('确认将「' + day + '」下的时段设置复制到其他日期下吗? (原有时段将被清除，如已有预约记录则该日的所有时段将不被修改)', callback);\n\t},\n\n\tbindDaySetTap: async function (e) {\n\t\tlet itemList = ['选用模板配置', '保存为模板', '删除该日期', '复制到所有日期'];\n\t\twx.showActionSheet({\n\t\t\titemList,\n\t\t\tsuccess: async res => {\n\t\t\t\tlet idx = res.tapIndex;\n\t\t\t\tif (idx == 0) { // 选用模板配置\n\t\t\t\t\tthis._selectTemp(e);\n\t\t\t\t}\n\t\t\t\tif (idx == 1) { // 保存为模板 \n\t\t\t\t\tthis._saveTempModal(e);\n\t\t\t\t}\n\t\t\t\tif (idx == 2) { //  删除\n\t\t\t\t\tlet curIdx = pageHelper.dataset(e, 'idx');\n\t\t\t\t\tif (this._checkHasJoinCnt(this.data.days[curIdx].times)) {\n\t\t\t\t\t\treturn pageHelper.showModal('该日已有用户预约/预约待审核，不能直接删除。若确定要删除，请先删除有预约的时段')\n\t\t\t\t\t}\n\t\t\t\t\tlet callback = () => {\n\t\t\t\t\t\tlet days = this.data.days;\n\t\t\t\t\t\tdays.splice(curIdx, 1);\n\t\t\t\t\t\tthis.setData({\n\t\t\t\t\t\t\tdays\n\t\t\t\t\t\t});\n\t\t\t\t\t\tthis._syncCalData();\n\t\t\t\t\t}\n\t\t\t\t\tpageHelper.showConfirm('确认删除该日期吗?', callback);\n\t\t\t\t}\n\n\t\t\t\tif (idx == 3) { //复制到所有\n\t\t\t\t\tthis._copyDaySetToAll(e);\n\t\t\t\t}\n\t\t\t},\n\t\t\tfail: function (res) {}\n\t\t})\n\t},\n\n\tbindTimeSetTap: async function (e) {\n\t\tlet itemList = ['复制到所有日期', '选用模板配置', '保存为模板'];\n\t\twx.showActionSheet({\n\t\t\titemList,\n\t\t\tsuccess: async res => {\n\t\t\t\tlet idx = res.tapIndex;\n\t\t\t\tif (idx == 0) { // 复制到所有\n\t\t\t\t\tthis._copyDaySetToAll(e);\n\t\t\t\t}\n\t\t\t\tif (idx == 1) { // 选用模板配置\n\t\t\t\t\tthis._selectTemp(e);\n\t\t\t\t}\n\t\t\t\tif (idx == 2) { // 保存为模板 \n\t\t\t\t\tthis._saveTempModal(e);\n\t\t\t\t}\n\n\t\t\t},\n\t\t\tfail: function (res) {}\n\t\t})\n\t},\n\n\tbindDataCalendarClickCmpt: function (e) {\n\t\t// 数据日历点击\n\t\tlet clickDays = e.detail.days;\n\t\tif (!clickDays) return;\n\t\tlet days = this.data.days;\n\n\t\tlet retDays = [];\n\t\tfor (let k = 0; k < clickDays.length; k++)  { \n\t\t\tlet dayExist = false;\n\t\t\tfor (let j in days) {\n\t\t\t\tif (days[j].day == clickDays[k]) {\n\t\t\t\t\t// 节点存在\n\t\t\t\t\tretDays.push(days[j]);\n\t\t\t\t\tdayExist = true;\n\t\t\t\t\tbreak;\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// 节点不存在\n\t\t\tif (!dayExist) {\n\t\t\t\tlet dayDesc = timeHelper.fmtDateCHN(clickDays[k]) + ' (' + timeHelper.week(clickDays[k]) + ')';\n\t\t\t\tlet times = [AdminMeetBiz.getNewTimeNode(clickDays[k])];\n\t\t\t\tlet node = {\n\t\t\t\t\tday: clickDays[k],\n\t\t\t\t\tdayDesc,\n\t\t\t\t\ttimes\n\t\t\t\t};\n\t\t\t\tretDays.push(node);\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setData({\n\t\t\tdays: retDays\n\t\t});\n\t},\n\n\tonPageScroll: function (e) {\n\t\tif (e.scrollTop > 100) {\n\t\t\tthis.setData({\n\t\t\t\ttopShow: true\n\t\t\t});\n\t\t} else {\n\t\t\tthis.setData({\n\t\t\t\ttopShow: false\n\t\t\t});\n\t\t}\n\t},\n\n\tbindClearReasonTap: function (e) {\n\t\tthis.setData({\n\t\t\tformReason: ''\n\t\t})\n\t},\n\n\tbindTopTap: function () {\n\t\twx.pageScrollTo({\n\t\t\tscrollTop: 0\n\t\t})\n\t},\n\n\tbindSaveTap: function () {\n\t\tlet parent = pageHelper.getPrevPage(2);\n\t\tif (!parent) {\n\t\t\tpageHelper.showNoneToast('前序页面不存在');\n\t\t\treturn;\n\t\t}\n\n\t\tlet days = this.data.days;\n\t\tlet getDays = [];\n\t\tif (!projectSetting.MEET_CAN_NULL_TIME) { // 是否允许无时段日期\n\t\t\tfor (let k = 0; k < days.length; k++)  { \n\t\t\t\tif (days[k].times.length > 0) getDays.push(days[k]);\n\t\t\t}\n\t\t} else\n\t\t\tgetDays = days;\n\n\n\t\tlet formDaysSet = this.data.lastHasDays.concat(getDays);\n\t\tparent.setData({\n\t\t\tformDaysSet\n\t\t});\n\n\t\twx.navigateBack();\n\t}\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/time/admin_meet_time.json",
    "content": "{\n\t\"usingComponents\": { \n\t\t\"cmpt-picker-multi\": \"/cmpts/public/picker_multi/picker_multi_cmpt\",\n\t\t\"cmpt-calendar\": \"/cmpts/public/calendar/calendar_meet/calendar_meet_cmpt\"\n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\", \n\t\"navigationBarTitleText\": \"时间设置\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/time/admin_meet_time.wxml",
    "content": "<wxs src=\"../../../../../../tpls/wxs/tools.wxs\" module=\"tools\" />\n\n<block wx:if=\"{{isAdmin}}\">\n\t<view class=\"main-admin\">\n\n\t\t<view class=\"select-date\">\n\t\t\t<cmpt-calendar mode=\"multi\" hasDays=\"{{hasDays}}\" hasJoinDays=\"{{hasJoinDays}}\" multiDoDay=\"{{multiDoDay}}\" fold=\"{{false}}\" selectTimeout=\"{{false}}\" bind:click=\"bindDataCalendarClickCmpt\" />\n\t\t</view>\n\n\t\t<view wx:if=\"{{days.length}}\" class=\"data-hint\"><text>时段设置 <text class=\"text-grey text-day\">(共{{days.length+lastHasDays.length}}天可约)</text></text></view>\n\n\t\t<view wx:else class=\"data-hint\"><text>时段设置：<text class=\"text-orange text-day\">请先选择以上日期</text></text></view>\n\n\t\t<view class=\"form-area\">\n\t\t\t<view class=\"form-box\" wx:for=\"{{days}}\" wx:key=\"key\">\n\t\t\t\t<view class=\"time-group\">\n\t\t\t\t\t<view class=\"time-title\">\n\t\t\t\t\t\t<text>{{item.dayDesc}}</text>\n\t\t\t\t\t\t<text bindtap=\"bindDaySetTap\" data-idx=\"{{index}}\" class=\"icon-moreandroid\"></text>\n\t\t\t\t\t</view>\n\t\t\t\t\t<view bindtap=\"bindTimeAddTap\" data-idx=\"{{index}}\" wx:if=\"{{item.times.length==0}}\" class=\"time-line text-orange time-line-hint\"><text class=\"icon-info margin-right-xs\"></text>尚未添加时段，请设置</view>\n\t\t\t\t\t<view class=\"time-line\" wx:for=\"{{item.times}}\" wx:key=\"key1\" wx:for-item=\"timesItem\" wx:for-index=\"timesIndex\">\n\t\t\t\t\t\t<text wx:if=\"{{timesItem.stat.succCnt||timesItem.stat.waitCheckCnt}}\" class=\"x-lock icon-profilefill text-grey margin-right-xs\"></text>\n\t\t\t\t\t\t<cmpt-picker disabled=\"{{timesItem.stat.succCnt||timesItem.stat.waitCheckCnt}}\" disabledHint=\"该时段已有用户预约/预约待审核，处于锁定状态，不可更改起止时间点（上限人数可更改）\" steps=\"2\" isSlot=\"{{true}}\" sourceData=\"{{daysTimeOptions}}\" bind:select=\"bindDaysTimeStartCmpt\" itemMulti=\"{{[tools.split(timesItem.start,':')[0],  tools.split(timesItem.start,':')[1]]}}\" data-idx=\"{{index}}\" data-timesidx=\"{{timesIndex}}\">\n\t\t\t\t\t\t\t<view class=\"clock box\">{{timesItem.start}} <text class=\"icon-right text-arrow\"></text>\n\t\t\t\t\t\t\t</view>\n\t\t\t\t\t\t</cmpt-picker>\n\t\t\t\t\t\t<view class=\"clock-line\">～</view>\n\t\t\t\t\t\t<cmpt-picker disabled=\"{{timesItem.stat.succCnt||timesItem.stat.waitCheckCnt}}\" disabledHint=\"该时段已有用户预约/预约待审核，处于锁定状态，不可更改起止时间点（上限人数可更改）\" steps=\"2\" isSlot=\"{{true}}\" sourceData=\"{{daysTimeOptions}}\" bind:select=\"bindDaysTimeEndCmpt\" itemMulti=\"{{[tools.split(timesItem.end,':')[0], tools.split(timesItem.end,':')[1]]}}\" data-idx=\"{{index}}\" data-timesidx=\"{{timesIndex}}\">\n\t\t\t\t\t\t\t<view class=\"clock box\">{{timesItem.end}} <text class=\"icon-right text-arrow\"></text></view>\n\t\t\t\t\t\t</cmpt-picker>\n\n\n\t\t\t\t\t\t<view class=\"limit box\" bindtap=\"bindShowTimeLimitModalTap\" data-idx=\"{{index}}\" data-timesidx=\"{{timesIndex}}\">{{!timesItem.isLimit?'不限人数':timesItem.limit+'人'}}<text class=\"icon-right\"></text></view>\n\t\t\t\t\t\t<view class=\"box close\" bindtap=\"bindTimeDelTap\" data-idx=\"{{index}}\" data-timesidx=\"{{timesIndex}}\" data-mark=\"{{timesItem.mark}}\">\n\t\t\t\t\t\t\t<text class=\"icon-delete\"></text>\n\t\t\t\t\t\t</view>\n\n\t\t\t\t\t\t<switch bindtap=\"bindTimeStatusSwitch\" disabled=\"{{true}}\" data-idx=\"{{index}}\" data-timesidx=\"{{timesIndex}}\" class=\"limit-status green sm\" checked=\"{{timesItem.status==1}}\">\n\t\t\t\t\t\t</switch>\n\t\t\t\t\t</view>\n\t\t\t\t\t<view class=\"time-oprt\">\n\t\t\t\t\t\t<view class=\"op\" bindtap=\"bindTimeAddTap\" data-idx=\"{{index}}\"><text class=\"icon-add margin-right-xxs\"></text>添加时段</view>\n\t\t\t\t\t\t<view class=\"vline\"></view>\n\t\t\t\t\t\t<view class=\"op\" bindtap=\"bindShowTimeLimitModalTap\" data-idx=\"{{index}}\" data-timesidx=\"{{-1}}\">\n\t\t\t\t\t\t\t<text class=\"icon-friend margin-right-xxs\"></text>人数上限\n\t\t\t\t\t\t</view>\n\t\t\t\t\t\t<view class=\"vline\"></view>\n\t\t\t\t\t\t<view class=\"op\" bindtap=\"bindTimeSetTap\" data-idx=\"{{index}}\"><text class=\"icon-copy margin-right-xxs\"></text>复制/模板</view>\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\n\n\t\t\t</view>\n\t\t</view>\n\t</view>\n\n\t<view class=\"btn-bottom-admin\">\n\t\t<view bindtap=\"url\" data-type=\"back\" class=\"return\">不保存,返回</view>\n\t\t<view bindtap=\"bindSaveTap\" class=\"save\">保存时间设置</view>\n\t</view>\n\n\n\n\t<cmpt-modal wx:if=\"{{curTimeLimitModalShow}}\" model:show=\"{{curTimeLimitModalShow}}\" type=\"dialog\" title=\"时段人数上限\" bind:click=\"bindTimeLimitSetCmpt\" class=\"modal-form\">\n\t\t<view wx:if=\"{{curTimesIdx>-1}}\" class=\"modal-desc text-admin\">{{days[curIdx].day}} {{days[curIdx].times[curTimesIdx].start}}～{{days[curIdx].times[curTimesIdx].end}}\n\t\t\t可约人数上限为</view>\n\t\t<view wx:else class=\"modal-desc\">{{days[curIdx].day}} 全天 可约人数上限为</view>\n\n\t\t<view class=\"form-group\">\n\t\t\t<view class=\"title\">是否限制人数</view>\n\t\t\t<switch wx:if=\"{{curTimeIsLimit}}\" bindchange=\"switchModel\" data-item=\"curTimeIsLimit\" class=\"green sm\" checked=\"true\">\n\t\t\t</switch>\n\t\t\t<switch wx:elif=\"{{!curTimeIsLimit}}\" bindchange=\"switchModel\" data-item=\"curTimeIsLimit\" class=\"green sm\">\n\t\t\t</switch>\n\t\t</view>\n\t\t<view class=\"form-group\">\n\t\t\t<view class=\"title\">人数上限</view>\n\t\t\t<block wx:if=\"{{curTimeIsLimit}}\">\n\t\t\t\t<input type=\"number\" maxlength=\"4\" placeholder=\"请输入本时段人数上限\" model:value=\"{{curTimeLimit}}\" class=\"text-red margin-right-xs\"></input>人\n\t\t\t</block>\n\t\t\t<text wx:else>不限制人数</text>\n\t\t</view>\n\t</cmpt-modal>\n\n\n\t<cmpt-modal wx:if=\"{{saveTempModalShow}}\" model:show=\"{{saveTempModalShow}}\" type=\"dialog\" title=\"保存为模板\" bind:click=\"bindSaveTempCmpt\" class=\"modal-form\" subtitle=\"将当前该日期下的配置的 「{{days[curIdx].times.length}}项」 时段保存为模板，以便于后续快速调用 :\" subtitleAlign=\"left\">\n\n\t\t<view class=\"form-group\">\n\t\t\t<input maxlength=\"20\" placeholder=\"请输入模板名称\" model:value=\"{{formTempName}}\" class=\"input-temp\"></input>\n\t\t</view>\n\t</cmpt-modal>\n\n\n\n\t<!-- top begin -->\n\t<button wx:if=\"{{topShow}}\" class=\"btn-fixed bg-gray text-gray btn-top\" bindtap=\"bindTopTap\" style=\"bottom:160rpx\"><text class=\"icon-top\"></text></button>\n\t<!-- top END. -->\n\n\t<cmpt-modal wx:if=\"{{cancelModalShow}}\" model:show=\"{{cancelModalShow}}\" type=\"dialog\" title=\"取消该时段所有预约\" bind:click=\"bindCancelMeetJoinCmpt\" class=\"modal-form\" cancelText=\"返回\" confirmText=\"确定取消\">\n\t\t<view class=\"form-group\" style=\"padding:0 10rpx\">\n\t\t\t<view class=\"title\">取消理由 <text class=\"text-grey text-mid\">(选填)</text>：</view>\n\t\t\t<view bindtap=\"bindClearReasonTap\" style=\"width:150rpx;text-align: right;\" class=\"text-grey\"><text class=\"icon-roundclose\"></text>清空</view>\n\t\t</view>\n\n\t\t<view class=\"form-group cancel-area\">\n\t\t\t<textarea placeholder-class=\"phc\" placeholder=\"请输入取消理由 (非必填)，将通知给用户\" style=\"height:110rpx\" model:value=\"{{formReason}}\" maxlength=\"100\"></textarea>\n\t\t</view>\n\t</cmpt-modal>\n\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/meet/time/admin_meet_time.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n\n\n.main-admin {\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tpadding: 10rpx 0;\n\tpadding-bottom: 150rpx;\n}\n\n.form-box {\n\tborder-radius: 0;\n}\n\n.form-area {\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tpadding: 30rpx 0rpx;\n}\n\n.data-hint {\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tline-height: 2.5;\n\tbackground-color: #fff;\n\ttext-align: center;\n\tcolor: #333;\n\tfont-size: 36rpx;\n}\n\n.data-hint .text-day {\n\tfont-size: 30rpx;\n}\n\n.select-date {\n\tbackground-color: #fff;\n\twidth: 100%;\n\tz-index: 999;\n\tmargin-bottom: 20rpx;\n}\n\n.time-group {\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\twidth: 100%;\n\tflex-direction: column;\n\talign-items: center;\n\tpadding: 20rpx 0rpx 30rpx;\n}\n\n.time-title {\n\tposition: relative;\n\twidth: 100%;\n\tfont-size: 36rpx;\n\tcolor: #333;\n\tdisplay: flex;\n\tjustify-content: center;\n\tmargin-bottom: 30rpx;\n}\n\n.time-title .icon-moreandroid {\n\tposition: absolute;\n\tright: 0rpx;\n\tcolor: #888;\n\twidth: 100rpx;\n\ttext-align: right;\n\tpadding-right: 20rpx;\n}\n\n.time-line {\n\twidth: 100%;\n\tcolor: #333;\n\tdisplay: flex;\n\tjustify-content: center;\n\tpadding: 15rpx 0;\n\tposition: relative;\n}\n\n.time-line.time-line-hint {\n\tfont-size: 28rpx;\n\tpadding: 5rpx 0;\n}\n\n.time-line .box {\n\tline-height: 65rpx;\n\tfont-size: 32rpx;\n\ttext-align: center;\n\tborder: 2rpx solid #ddd;\n\tposition: relative;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n}\n\n.time-line .box.close {\n\tborder: 0;\n\tcolor: #888;\n\tmin-width: 90rpx;\n\tmargin-left: 10rpx;\n\tfont-size: 40rpx;\n}\n\n.time-line .limit-status {\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n}\n\n.time-line .x-lock {\n\tposition: absolute;\n\tleft: 10rpx;\n}\n\n.time-line .all {\n\twidth: 320rpx;\n}\n\n.time-line .clock {\n\twidth: 135rpx;\n}\n\n.time-line .clock-line {\n\twidth: 40rpx;\n\ttext-align: center;\n\tcolor: #888;\n}\n\n.time-line .limit {\n\twidth: 150rpx;\n\tmargin-left: 16rpx;\n\tcolor: #888;\n\tfont-size: 28rpx;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.time-line .limit .icon-right {\n\tposition: absolute;\n\tcolor: #ccc;\n\tright: 0rpx;\n\tfont-size: 24rpx;\n}\n\n.time-oprt {\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tline-height: 3;\n\tfont-size: 32rpx;\n\tmargin-top: 10rpx;\n\tcolor: var(--adminColor);\n}\n\n.time-oprt .op {\n\tpadding: 0 15rpx;\n}\n\n.time-oprt .vline {\n\theight: 35rpx;\n\twidth: 1rpx;\n\tborder-left: 2rpx dotted #aaa;\n}\n\n.text-arrow {\n\tfont-size: 24rpx;\n\tposition: absolute;\n\tright: 1rpx;\n\tcolor: #ccc;\n}\n\n\n.modal-form .form-group .input-temp {\n\theight: 100rpx;\n\ttext-align: center;\n\tborder: 1rpx solid #ccc;\n\tbackground-color: #fff;\n}\n\n.bottom-btn {\n\twidth: 100%;\n\tposition: fixed;\n\tbottom: 0;\n\ttext-align: center;\n\tcolor: #fff;\n\tline-height: 2.6;\n\tfont-size: 36rpx;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/mgr/add/admin_mgr_add.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst PublicBiz = require('../../../../../../comm/biz/public_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\nconst validate = require('../../../../../../helper/validate.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tformName: '',\n\t\tformDesc: '',\n\t\tformPhone: '',\n\t\tformPassword: '',\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: function (options) {\n\t\tif (!AdminBiz.isAdmin(this, true)) return;\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\n\n\t/** \n\t * 数据提交\n\t */\n\tbindFormSubmit: async function () {\n\t\tif (!AdminBiz.isAdmin(this, true)) return;\n\n\t\tlet data = this.data;\n\n\t\t// 数据校验 \n\t\tdata = validate.check(data, AdminBiz.CHECK_FORM_MGR_ADD, this);\n\t\tif (!data) return;\n\n\t\ttry {\n\t\t\tlet adminId = this.data.id;\n\t\t\tdata.id = adminId;\n\n\t\t\tawait cloudHelper.callCloudSumbit('admin/mgr_insert', data).then(res => {\n\n\t\t\t\tlet callback = async function () {\n\t\t\t\t\tPublicBiz.removeCacheList('admin-mgr');\n\t\t\t\t\twx.navigateBack();\n\n\t\t\t\t}\n\t\t\t\tpageHelper.showSuccToast('添加成功', 1500, callback);\n\t\t\t});\n\n\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t}\n\n\t},\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/mgr/add/admin_mgr_add.json",
    "content": "{\n\t\"usingComponents\": {},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\", \n\t\"navigationBarTitleText\": \"添加管理员\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/mgr/add/admin_mgr_add.wxml",
    "content": " <view class=\"main-admin\" wx:if=\"{{isAdmin}}\">\n\t<!-- edit form begin -->\n\t<view class=\"form-box shadow\">\n\t\t<view class=\"form-group\">\n\t\t\t<view class=\"title must\">登录账号</view>\n\t\t\t<input maxlength=\"30\" placeholder=\"请填写登录账号\" placeholder-class=\"phc\" model:value=\"{{formName}}\" focus=\"{{formNameFocus}}\"></input>\n\t\t</view>\n\t\t<view wx:if=\"{{formNameFocus}}\" class=\"hint-desc error\">{{formNameFocus}}</view>\n\n\t\t<view class=\"form-group\">\n\t\t\t<view class=\"title must\">姓名</view>\n\t\t\t<input maxlength=\"30\" placeholder=\"请填写管理员姓名\" model:value=\"{{formDesc}}\" focus=\"{{formDescFocus}}\"></input>\n\t\t</view>\n\t\t<view wx:if=\"{{formDescFocus}}\" class=\"hint-desc error\">{{formDescFocus}}</view>\n\n\t\t<view class=\"form-group\">\n\t\t\t<view class=\"title\">手机</view>\n\t\t\t<input maxlength=\"11\" placeholder=\"请填写手机号码\" model:value=\"{{formPhone}}\" focus=\"{{formPhoneFocus}}\"></input>\n\t\t</view>\n\t\t<view wx:if=\"{{formPhoneFocus}}\" class=\"hint-desc error\">{{formPhoneFocus}}</view>\n\n\t\t<view class=\"form-group\">\n\t\t\t<view class=\"title must\">密码</view>\n\t\t\t<input maxlength=\"30\" type=\"password\" placeholder=\"请填写密码\" model:value=\"{{formPassword}}\" focus=\"{{formPasswordFocus}}\"></input>\n\t\t</view>\n\t\t<view wx:if=\"{{formPasswordFocus}}\" class=\"hint-desc error\">{{formPasswordFocus}}</view>\n\n\t</view> \n\n\t<button bindtap=\"bindFormSubmit\" class=\"btn-admin margin-top\">确定添加</button>\n\n</view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/mgr/add/admin_mgr_add.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/mgr/edit/admin_mgr_edit.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\nconst validate = require('../../../../../../helper/validate.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: function (options) {\n\t\tif (!AdminBiz.isAdmin(this, true)) return;\n\t\tif (!pageHelper.getOptions(this, options)) return;\n\n\t\tthis._loadDetail();\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\t\tawait this._loadDetail();\n\t\twx.stopPullDownRefresh();\n\t},\n\n\t_loadDetail: async function () {\n\t\tif (!AdminBiz.isAdmin(this, true)) return;\n\n\t\tlet id = this.data.id;\n\t\tif (!id) return;\n\n\t\tlet params = {\n\t\t\tid\n\t\t};\n\t\tlet opt = {\n\t\t\ttitle: 'bar'\n\t\t};\n\t\tlet mgr = await cloudHelper.callCloudData('admin/mgr_detail', params, opt);\n\t\tif (!mgr) {\n\t\t\tthis.setData({\n\t\t\t\tisLoad: null\n\t\t\t})\n\t\t\treturn;\n\t\t};\n\n\t\tthis.setData({\n\t\t\tisLoad: true,\n\n\t\t\t// 表单数据 \n\t\t\tformName: mgr.ADMIN_NAME,\n\t\t\tformDesc: mgr.ADMIN_DESC,\n\t\t\tformPhone: mgr.ADMIN_PHONE,\n \n\t\t\tformPassword: ''\n\n\t\t});\n\t},\n\n\t/** \n\t * 数据提交\n\t */\n\tbindFormSubmit: async function () {\n\t\tif (!AdminBiz.isAdmin(this, true)) return;\n\n\t\tlet data = this.data;\n\n\t\t// 数据校验 \n\t\tdata = validate.check(data, AdminBiz.CHECK_FORM_MGR_EDIT, this);\n\t\tif (!data) return; \n\n\t\ttry {\n\t\t\tlet adminId = this.data.id;\n\t\t\tdata.id = adminId;\n\n\t\t\tawait cloudHelper.callCloudSumbit('admin/mgr_edit', data).then(res => {\n\n\t\t\t\tlet callback = () => {\n\t\t\t\t\t// 更新列表页面数据\n\t\t\t\t\tlet node = {\n\t\t\t\t\t\t'ADMIN_NAME': data.name,\n\t\t\t\t\t\t'ADMIN_DESC': data.desc,\n\t\t\t\t\t\t'ADMIN_PHONE': data.phone,\n\t\t\t\t\t}\n\t\t\t\t\tpageHelper.modifyPrevPageListNodeObject(adminId, node);\n\n\t\t\t\t\twx.navigateBack();\n\t\t\t\t}\n\t\t\t\tpageHelper.showSuccToast('修改成功', 1500, callback);\n\t\t\t});\n\n\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t}\n\n\t},\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/mgr/edit/admin_mgr_edit.json",
    "content": "{\n\t\"usingComponents\": {},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\",\n\t\"enablePullDownRefresh\": true, \n\t\"navigationBarTitleText\": \"修改管理员\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/mgr/edit/admin_mgr_edit.wxml",
    "content": "<view wx:if=\"{{isLoad===null}}\" class=\"margin-top load notexist text-l text-admin\"></view>\n<view wx:if=\"{{isLoad===false}}\" class=\"margin-top load loading text-l text-admin\"></view>\n\n<view class=\"main-admin\" wx:if=\"{{isLoad&&isAdmin}}\">\n\t<!-- edit form begin -->\n\t<view class=\"form-box shadow\">\n\t\t<view class=\"form-group\">\n\t\t\t<view class=\"title must\">登录账号</view>\n\t\t\t<input maxlength=\"30\" placeholder=\"请填写登录账号\" placeholder-class=\"phc\" model:value=\"{{formName}}\" focus=\"{{formNameFocus}}\"></input>\n\t\t</view>\n\t\t<view wx:if=\"{{formNameFocus}}\" class=\"hint-desc error\">{{formNameFocus}}</view>\n\n\t\t<view class=\"form-group\">\n\t\t\t<view class=\"title must\">姓名</view>\n\t\t\t<input maxlength=\"30\" placeholder=\"请填写管理员姓名\" model:value=\"{{formDesc}}\" focus=\"{{formDescFocus}}\"></input>\n\t\t</view>\n\t\t<view wx:if=\"{{formDescFocus}}\" class=\"hint-desc error\">{{formDescFocus}}</view>\n\n\t\t<view class=\"form-group\">\n\t\t\t<view class=\"title\">手机</view>\n\t\t\t<input maxlength=\"11\" placeholder=\"请填写手机号码\" model:value=\"{{formPhone}}\" focus=\"{{formPhoneFocus}}\"></input>\n\t\t</view>\n\t\t<view wx:if=\"{{formPhoneFocus}}\" class=\"hint-desc error\">{{formPhoneFocus}}</view>\n\n\t</view>\n\t<view class=\"form-box shadow\">\n\t\t<view class=\"form-group text-orange\">\n\t\t\t<text class=\"icon-info\">不修改密码则保持以下为空</text>\n\t\t</view>  \n\t\t<view class=\"form-group\">\n\t\t\t<view class=\"title must\">新密码</view>\n\t\t\t<input maxlength=\"30\" type=\"password\" placeholder=\"请填写密码\" model:value=\"{{formPassword}}\" focus=\"{{formPasswordFocus}}\"></input>\n\t\t</view>\n\t\t<view wx:if=\"{{formPasswordFocus}}\" class=\"hint-desc error\">{{formPasswordFocus}}</view>\n\n\t</view>\n\n\t<button bindtap=\"bindFormSubmit\" class=\"btn-admin margin-top\">确定修改</button>\n\n</view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/mgr/edit/admin_mgr_edit.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/mgr/list/admin_mgr_list.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\n\t\tisSuperAdmin: false,\n\t\tdataList: {\n\t\t\tlist: []\n\t\t}\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tif (!AdminBiz.isAdmin(this, true)) return;\n\n\t\t//设置搜索菜单\n\t\tthis.setData(this._getSearchMenu());\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\tbindStatusTap: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this, true)) return;\n\n\t\tlet id = pageHelper.dataset(e, 'id');\n\t\tlet status = pageHelper.dataset(e, 'status');\n\t\tif (!id || !status) return;\n\t\tstatus = Number(status);\n\n\t\tlet params = {\n\t\t\tid,\n\t\t\tstatus\n\t\t}\n\n\t\tlet that = this;\n\t\ttry {\n\t\t\tawait cloudHelper.callCloudSumbit('admin/mgr_status', params).then(res => {\n\t\t\t\tpageHelper.modifyListNode(id, that.data.dataList.list, 'ADMIN_STATUS', status, '_id');\n\t\t\t\tthat.setData({\n\t\t\t\t\tdataList: that.data.dataList,\n\t\t\t\t});\n\t\t\t\tpageHelper.showSuccToast('设置成功');\n\t\t\t});\n\t\t} catch (e) {\n\t\t\tconsole.log(e);\n\t\t}\n\t},\n\n\tbindDelTap: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this, true)) return;\n\n\t\tlet id = e.currentTarget.dataset.id;\n\t\tif (!id) return;\n\n\t\tlet params = {\n\t\t\tid,\n\t\t}\n\n\t\tlet callback = async () => {\n\t\t\ttry {\n\t\t\t\tawait cloudHelper.callCloudSumbit('admin/mgr_del', params).then(res => {\n\t\t\t\t\tpageHelper.delListNode(id, this.data.dataList.list, '_id');\n\t\t\t\t\tthis.data.dataList.total--;\n\t\t\t\t\tthis.setData({\n\t\t\t\t\t\tdataList: this.data.dataList\n\t\t\t\t\t});\n\t\t\t\t\tpageHelper.showSuccToast('删除成功', 2000);\n\n\t\t\t\t});\n\n\t\t\t} catch (e) {\n\t\t\t\tconsole.log(e);\n\t\t\t}\n\t\t}\n\n\t\tpageHelper.showConfirm('确认删除？删除不可恢复', callback);\n\t},\n\n\tbindCommListCmpt: function (e) {\n\t\tif (!AdminBiz.isAdmin(this, true)) return;\n\t\tpageHelper.commListListener(this, e);\n\t},\n\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\t_getSearchMenu: function () {\n\n\t\tlet sortItems = [];\n\t\tlet sortMenus = [{\n\t\t\tlabel: '全部',\n\t\t\ttype: '',\n\t\t\tvalue: ''\n\t\t}, {\n\t\t\tlabel: '超管',\n\t\t\ttype: 'type',\n\t\t\tvalue: 1\n\t\t},\n\t\t{\n\t\t\tlabel: '普通',\n\t\t\ttype: 'type',\n\t\t\tvalue: 0\n\t\t},\n\t\t{\n\t\t\tlabel: '正常',\n\t\t\ttype: 'status',\n\t\t\tvalue: 1\n\t\t},\n\t\t{\n\t\t\tlabel: '停用',\n\t\t\ttype: 'type',\n\t\t\tvalue: 0\n\t\t}\n\t\t]\n\n\t\treturn {\n\t\t\tsortItems,\n\t\t\tsortMenus\n\t\t}\n\n\t}\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/mgr/list/admin_mgr_list.json",
    "content": "{\n\t\"usingComponents\": {},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\", \n\t\"navigationBarTitleText\": \"管理员管理\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/mgr/list/admin_mgr_list.wxml",
    "content": "<block wx:if=\"{{isAdmin}}\">\n\t<cmpt-comm-list source='admin' type=\"admin-mgr\" search=\"{{search}}\" _menus=\"{{sortMenus}}\" _items=\"{{sortItems}}\" route=\"admin/mgr_list\" sortMenusDefaultIndex=\"0\" topBottom=\"50\" placeholder=\"搜索账号，姓名，手机\" bind:list=\"bindCommListCmpt\">\n\n\t\t<view slot=\"searchEnd\">\n\t\t\t<button bindtap=\"url\" data-url=\"../add/admin_mgr_add\" class=\"btn radius bg-admin text-white  margin-right-s\"><text class=\"icon-roundadd margin-right-xxs\"></text>添加管理员</button>\n\t\t</view>\n\n\t\t<!-- List Begin -->\n\t\t<view class=\"admin-comm-list\">\n\n\t\t\t<view wx:if=\"{{dataList && dataList.total }}\" class=\"load text-grey\">共有{{dataList.total}}条符合条件记录 </view>\n\n\t\t\t<view class=\"item\" wx:for=\"{{dataList.list}}\" wx:key=\"key\">\n\t\t\t\t<view class=\"no\">{{index+1}}</view>\n\t\t\t\t<view class=\"header\">\n\t\t\t\t\t<view class=\"left text-cut\">{{item.ADMIN_NAME}}\n\t\t\t\t\t</view>\n\t\t\t\t\t<view class=\"right\">\n\t\t\t\t\t\t<text class=\"text-green\" wx:if=\"{{item.ADMIN_STATUS==1}}\">正常</text>\n\t\t\t\t\t\t<text class=\"text-red\" wx:if=\"{{item.ADMIN_STATUS==0}}\">停用</text>\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\n\t\t\t\t<view class=\"info title-mid\">\n\t\t\t\t\t<view class=\"info-item\">\n\t\t\t\t\t\t<view class=\"title\">管理员身份</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view wx:if=\"{{item.ADMIN_TYPE==1}}\" class=\"content text-bold text-red\">超级管理员</view>\n\t\t\t\t\t\t<view wx:else class=\"content\">普通管理员</view>\n\t\t\t\t\t</view>\n\n\t\t\t\t\t<view class=\"info-item\">\n\t\t\t\t\t\t<view class=\"title\">登录账号</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view class=\"content\">{{item.ADMIN_NAME}}</view>\n\t\t\t\t\t</view>\n\n\t\t\t\t\t<view class=\"info-item\">\n\t\t\t\t\t\t<view class=\"title\">姓名</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view class=\"content\">{{item.ADMIN_DESC||'未填写'}}</view>\n\t\t\t\t\t</view>\n\n\t\t\t\t\t<view class=\"info-item\">\n\t\t\t\t\t\t<view class=\"title\">手机</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view class=\"content\">{{item.ADMIN_PHONE}}</view>\n\t\t\t\t\t</view>\n\n\t\t\t\t\t<view class=\"info-item\">\n\t\t\t\t\t\t<view class=\"title\">最近登录</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view class=\"content\">{{item.ADMIN_LOGIN_CNT}}次 / {{item.ADMIN_LOGIN_TIME}}</view>\n\t\t\t\t\t</view> \n\t\t\t\t\t \n\n\t\t\t\t\t<view class=\"oprt\">\n\t\t\t\t\t\t<view bindtap=\"url\" data-url=\"../edit/admin_mgr_edit?id={{item._id}}\" class=\"btn  margin-right-s\"><text class=\"icon-edit margin-right-xxs\"></text>编辑</view>\n\n\t\t\t\t\t\t<block wx:if=\"{{item.ADMIN_TYPE!=1}}\">\n\t\t\t\t\t\t\t<view wx:if=\"{{item.ADMIN_STATUS==0}}\" class=\"btn text-green\" bindtap=\"bindStatusTap\" data-id=\"{{item._id}}\" data-status=\"1\" class=\"btn  margin-right-s\"><text class=\"icon-delete margin-right-xxs\"></text>启用</view>\n\n\t\t\t\t\t\t\t<view wx:if=\"{{item.ADMIN_STATUS==1}}\" class=\"btn margin-left-s text-orange\" bindtap=\"bindStatusTap\" data-id=\"{{item._id}}\" data-status=\"0\" class=\"btn margin-right-s\"><text class=\"icon-roundclose margin-right-xxs text-red\"></text>停用</view>\n\n\t\t\t\t\t\t\t<view bindtap=\"bindDelTap\" data-id=\"{{item._id}}\" class=\"btn margin-right-s\"><text class=\"icon-delete margin-right-xxs text-orange\"></text>删除</view>\n\n\t\t\t\t\t\t</block>\n\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\t\t\t</view>\n\n\t\t</view>\n\t\t<!-- List END -->\n\n\t\t<!--load begin-->\n\t\t<import src=\"../../../../../../tpls/public/list_load_tpl.wxml\" />\n\t\t<template is=\"listLoadTpl\" data=\"{{dataList, skin:'text-grey'}}\" />\n\t\t<!--load end--> \n\n\t</cmpt-comm-list>\n\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/mgr/list/admin_mgr_list.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n "
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/mgr/log/admin_log_list.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\t//设置搜索菜单\n\t\tthis.setData(this._getSearchMenu());\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: async function () { },\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\turl: async function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tbindCommListCmpt: function (e) {\n\t\tpageHelper.commListListener(this, e);\n\t},\n\n\tbindClearTap: async function (e) {\n\t\tlet cb = async () => {\n\n\t\t\ttry {\n\t\t\t\tawait cloudHelper.callCloudSumbit('admin/log_clear').then(res => {\n\t\t\t\t\tlet cb = () =>{\n\t\t\t\t\t\twx.redirectTo({\n\t\t\t\t\t\t  url: 'admin_log_list',\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\tpageHelper.showSuccToast('清空完成', 1500, cb);\n\t\t\t\t})\n\t\t\t}\n\t\t\tcatch (err) {\n\t\t\t\tconsole.log(err);\n\t\t\t}\n\t\t}\n\n\t\tpageHelper.showConfirm('确认清空？清空不可恢复', cb);\n\t},\n\n\t_getSearchMenu: function () {\n\n\t\tlet sortItems = [];\n\t\tlet sortMenus = [{\n\t\t\tlabel: '全部',\n\t\t\ttype: '',\n\t\t\tvalue: ''\n\t\t}, {\n\t\t\tlabel: '系统',\n\t\t\ttype: 'type',\n\t\t\tvalue: 0\n\t\t},\n\t\t{\n\t\t\tlabel: '用户',\n\t\t\ttype: 'type',\n\t\t\tvalue: 1\n\t\t},\n\t\t{\n\t\t\tlabel: '文章',\n\t\t\ttype: 'type',\n\t\t\tvalue: 2\n\t\t},\n\t\t{\n\t\t\tlabel: '其他',\n\t\t\ttype: 'type',\n\t\t\tvalue: 99\n\t\t}\n\t\t]\n\n\t\treturn {\n\t\t\tsortItems,\n\t\t\tsortMenus\n\t\t}\n\n\t}\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/mgr/log/admin_log_list.json",
    "content": "{\n\t\"usingComponents\": { \n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\", \n\t\"disableScroll\": true, \n\t\"navigationBarTitleText\": \"后台-操作日志\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/mgr/log/admin_log_list.wxml",
    "content": "<block wx:if=\"{{isAdmin}}\">\n\t<cmpt-comm-list source='admin' type=\"admin_log_list\" search=\"{{search}}\" _menus=\"{{sortMenus}}\" _items=\"{{sortItems}}\" sortMenusDefaultIndex=\"0\" route=\"admin/log_list\" topBottom=\"50\" placeholder=\"搜索内容，管理员账号，姓名\" bind:list=\"bindCommListCmpt\">\n\n\t\t<view slot=\"searchEnd\">\n\t\t\t<button bindtap=\"bindClearTap\" class=\"btn radius bg-admin text-white  margin-right-s\"><text class=\"icon-delete margin-right-xxs\"></text>清空日志</button>\n\t\t</view>\n\n\t\t<!-- List Begin -->\n\t\t<view class=\"admin-comm-list\">\n\t\t\t<view wx:if=\"{{dataList && dataList.total }}\" class=\"load text-black\">共有{{dataList.total}}条符合条件记录 </view>\n\n\t\t\t<view class=\"item\" wx:for=\"{{dataList.list}}\" wx:key=\"key\">\n\t\t\t\t<view class=\"no\">{{index+1}}</view>\n\t\t\t\t<view class=\"header\">\n\t\t\t\t\t<view class=\"left text-cut\">{{item.LOG_TYPE_DESC}}操作</view>\n\t\t\t\t\t<view class=\"right\"></view>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"info\">\n\t\t\t\t\t<view class=\"info-item\">\n\t\t\t\t\t\t<view class=\"title\">操作人</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view class=\"content\">{{item.LOG_ADMIN_NAME}} ({{item.LOG_ADMIN_DESC}})</view>\n\t\t\t\t\t</view>\n\t\t\t\t\t<view class=\"info-item\">\n\t\t\t\t\t\t<view class=\"title\">操作时间</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view class=\"content\">{{item.LOG_ADD_TIME}}</view>\n\t\t\t\t\t</view>\n\t\t\t\t\t<view class=\"info-item\">\n\t\t\t\t\t\t<view class=\"title\">操作内容</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view class=\"content\">{{item.LOG_CONTENT}}</view>\n\t\t\t\t\t</view>\n\t\t\t\t\t<view class=\"info-item\">\n\t\t\t\t\t\t<view class=\"title\">IP地址</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view class=\"content\">{{item.LOG_ADD_IP}}</view>\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t</view>\n\t\t<!-- List END --> \n\n\t\t<!--load begin-->\n\t\t<import src=\"../../../../../../tpls/public/list_load_tpl.wxml\" />\n\t\t<template is=\"listLoadTpl\" data=\"{{dataList, skin:'text-grey'}}\" />\n\t\t<!--load end--> \n\n\t</cmpt-comm-list>\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/mgr/log/admin_log_list.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n\npage {\n\tbackground-color: #f8f8f8;\n}\n \n.admin-comm-list .item .info { \n\tpadding: 15rpx 20rpx 0rpx; \n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/mgr/pwd/admin_mgr_pwd.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\nconst validate = require('../../../../../../helper/validate.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tformOldPassword: '',\n\t\tformPassword: '',\n\t\tformPassword2: '',\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t/** \n\t * 数据提交\n\t */\n\tbindFormSubmit: async function () {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet data = this.data;\n\n\t\t// 数据校验 \n\t\tdata = validate.check(data, AdminBiz.CHECK_FORM_MGR_PWD, this);\n\t\tif (!data) return;\n\n\t\tif (data.password != data.password2) {\n\t\t\treturn pageHelper.showModal('两次输入的新密码不一致');\n\t\t}\n\n\t\ttry {\n\t\t\tawait cloudHelper.callCloudSumbit('admin/mgr_pwd', data).then(res => {\n\t\t\t\tlet callback = () => {\n\t\t\t\t\twx.navigateBack();\n\t\t\t\t}\n\t\t\t\tpageHelper.showSuccToast('修改成功', 1500, callback);\n\t\t\t});\n\n\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t}\n\n\t},\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/mgr/pwd/admin_mgr_pwd.json",
    "content": "{\n\t\"usingComponents\": {},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\", \n\t\"navigationBarTitleText\": \"管理员密码修改\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/mgr/pwd/admin_mgr_pwd.wxml",
    "content": "<view class=\"main-admin\" wx:if=\"{{isAdmin}}\"> \n\t \n\t<view class=\"form-box shadow\"> \n\t\t<view class=\"form-group\">\n\t\t\t<view class=\"title must\">旧密码</view>\n\t\t\t<input maxlength=\"30\" type=\"password\" placeholder=\"请填写旧密码\" model:value=\"{{formOldPassword}}\" focus=\"{{formOldPasswordFocus}}\"></input>\n\t\t</view>\n\t\t<view wx:if=\"{{formOldPasswordFocus}}\" class=\"hint-desc error\">{{formOldPasswordFocus}}</view>\n\n\t\t<view class=\"form-group\">\n\t\t\t<view class=\"title must\">新密码</view>\n\t\t\t<input maxlength=\"30\" type=\"password\" placeholder=\"请填写新密码\" model:value=\"{{formPassword}}\" focus=\"{{formPasswordFocus}}\"></input>\n\t\t</view>\n\t\t<view wx:if=\"{{formPasswordFocus}}\" class=\"hint-desc error\">{{formPasswordFocus}}</view>\n\n\t\t<view class=\"form-group\">\n\t\t\t<view class=\"title must\">新密码再次填写</view>\n\t\t\t<input maxlength=\"30\" type=\"password\" placeholder=\"请再次填写新密码\" model:value=\"{{formPassword2}}\" focus=\"{{formPassword2Focus}}\"></input>\n\t\t</view>\n\t\t<view wx:if=\"{{formPassword2Focus}}\" class=\"hint-desc error\">{{formPassword2Focus}}</view>\n\n\t</view>\n\n\t<button bindtap=\"bindFormSubmit\" class=\"btn-admin margin-top\">提交修改</button>\n\n</view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/mgr/pwd/admin_mgr_pwd.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/news/add/admin_news_add.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst PublicBiz = require('../../../../../../comm/biz/public_biz.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\nconst validate = require('../../../../../../helper/validate.js');\nconst AdminNewsBiz = require('../../../../biz/admin_news_biz.js');\nconst projectSetting = require('../../../../public/project_setting.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\twx.setNavigationBarTitle({\n\t\t\ttitle: projectSetting.NEWS_NAME + '-添加',\n\t\t});\n\n\t\tthis.setData(AdminNewsBiz.initFormData()); // 初始化表单数据\n\t\tthis.setData({\n\t\t\tisLoad: true\n\t\t});\n\n\t\tthis._setContentDesc();\n\n\t},\n\n\t_setContentDesc: function () {\n\t\tAdminBiz.setContentDesc(this);\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\tmodel: function (e) {\n\t\tpageHelper.model(this, e);\n\t}, \n \n\n\t/** \n\t * 数据提交\n\t */\n\tbindFormSubmit: async function () {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet data = this.data;\n\t\tif (this.data.formContent.length == 0) {\n\t\t\treturn pageHelper.showModal('详细内容不能为空');\n\t\t}\n\t\tdata = validate.check(data, AdminNewsBiz.CHECK_FORM, this);\n\t\tif (!data) return; \n\n\t\tlet forms = this.selectComponent(\"#cmpt-form\").getForms(true);\n\t\tif (!forms) return;\n\t\tdata.forms = forms;\n\n\t\tdata.cateName = AdminNewsBiz.getCateName(data.cateId);\n\n\t\ttry {\n\t\t\tif (this.data.imgList.length == 0) {\n\t\t\t\treturn pageHelper.showModal('请上传封面图');\n\t\t\t}\n\n\t\t\t// 提取简介\n\t\t\tdata.desc = PublicBiz.getRichEditorDesc(data.desc, this.data.formContent);\n\n\t\t\t// 先创建，再上传 \n\t\t\tlet result = await cloudHelper.callCloudSumbit('admin/news_insert', data);\n\t\t\tlet newsId = result.data.id;\n\n\t\t\t// 封面图片 提交处理 \n\t\t\twx.showLoading({\n\t\t\t\ttitle: '提交中...',\n\t\t\t\tmask: true\n\t\t\t});\n\t\t\tawait cloudHelper.transCoverTempPics(this.data.imgList, 'news/', newsId, 'admin/news_update_pic');\n\n\t\t\t// 富文本\n\t\t\tlet formContent = this.data.formContent;\n\t\t\tif (formContent && formContent.length > 0) {\n\t\t\t\twx.showLoading({\n\t\t\t\t\ttitle: '提交中...',\n\t\t\t\t\tmask: true\n\t\t\t\t});\n\t\t\t\tlet content = await cloudHelper.transRichEditorTempPics(formContent, 'news/', newsId, 'admin/news_update_content');\n\t\t\t\tthis.setData({\n\t\t\t\t\tformContent: content\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tawait cloudHelper.transFormsTempPics(forms, 'news/', newsId, 'admin/news_update_forms');\n\n\t\t\tlet callback = async function () {\n\t\t\t\tPublicBiz.removeCacheList('admin-news-list');\n\t\t\t\tPublicBiz.removeCacheList('news-list');\n\t\t\t\twx.navigateBack();\n\n\t\t\t}\n\t\t\tpageHelper.showSuccToast('添加成功', 2000, callback);\n\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t}\n\n\t},\n\n\n\tbindImgUploadCmpt: function (e) {\n\t\tthis.setData({\n\t\t\timgList: e.detail\n\t\t});\n\t}, \n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t}\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/news/add/admin_news_add.json",
    "content": "{\n\t\"usingComponents\": {\n\t\t\"cmpt-img-upload\": \"/cmpts/public/img/img_upload_cmpt\",\n\t\t\"cmpt-form-show\": \"/cmpts/public/form/form_show/form_show_cmpt\"  \n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\",\n\t\"enablePullDownRefresh\": true\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/news/add/admin_news_add.wxml",
    "content": "<view wx:if=\"{{!isLoad}}\" class=\"margin-top load loading text-l text-grey\"></view>\n<view class=\"main-admin\" wx:if=\"{{isAdmin&&isLoad}}\">\n\t<include src=\"../admin_news_form_tpl.wxml\" /> \n</view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/news/add/admin_news_add.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n "
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/news/admin_news_form_tpl.wxml",
    "content": "<view class=\"form-box shadow\">\n\t<view class=\"form-group\">\n\t\t<view class=\"title must\">标题</view>\n\t</view>\n\n\t<view class=\"form-group\">\n\t\t<input placeholder=\"简短的标题\" placeholder-class=\"phc\" model:value=\"{{formTitle}}\" focus=\"{{formTitleFocus}}\" maxlength=\"50\"></input>\n\t</view>\n\t<view wx:if=\"{{formTitleFocus}}\" class=\"hint-desc error\">{{formTitleFocus}}</view>\n\n\t<view wx:if=\"{{cateIdOptions.length>1}}\" class=\"form-group arrow\" id=\"formCateId\">\n\t\t\t<view class=\"title must\">分类</view>\n\t\t\t<cmpt-picker id=\"cate-picker\" sourceData=\"{{cateIdOptions}}\" bind:select=\"url\" data-type=\"picker\" data-item=\"formCateId\" item=\"{{formCateId}}\"> </cmpt-picker>\n\t\t</view>\n\t\t<view wx:if=\"{{formCateIdFocus}}\" class=\"hint-desc error\">{{formCateIdFocus}}</view>\n\n\t<view class=\"form-group\">\n\t\t<view class=\"title must\">排序号<text class=\"text-grey text-normal margin-left-xs\">(小的先显示)</text></view>\n\t\t<input placeholder=\"排序号，小的先显示\" type=\"number\" placeholder-class=\"phc\" model:value=\"{{formOrder}}\" focus=\"{{formOrderFocus}}\" maxlength=\"4\"></input>\n\t</view>\n\t<view wx:if=\"{{formOrderFocus}}\" class=\"hint-desc error\">{{formOrderFocus}}</view>\n\n\t<view class=\"form-group\">\n\t\t<view class=\"action text-bold text-l\">简介</view>\n\t\t<view class=\"action\">{{formDesc.length}}/100</view>\n\t</view>\n\n\t<view class=\"form-group align-start\">\n\t\t<textarea name=\"content\" placeholder-class=\"phc\" placeholder=\"请输入本文简介，若不填写则直接取内容前100个字作为简介\" style=\"min-height:150rpx\" model:value=\"{{formDesc}}\" maxlength=\"100\" focus=\"{{formDescFocus}}\" auto-height=\"true\"></textarea>\n\t</view>\n\t<view wx:if=\"{{formDescFocus}}\" class=\"hint-desc error\">{{formDescFocus}}</view> \n  \n\t<view class=\"form-group arrow\" bindtap=\"url\" data-url=\"../../content/admin_content\">\n\t\t<view class=\"title must\">详细内容<text class=\"text-grey text-normal margin-left-xs\">(必填)</text></view>\n\t\t<view class=\"form-text {{contentDesc=='未填写'?'text-orange':''}}\">{{contentDesc}}</view>\n\t</view>\n\t<view wx:if=\"{{formContentFocus}}\" class=\"hint-desc error\">{{formContentFocus}}</view>\n\n\n</view> \n \n\n<view class=\"form-box shadow\">\n\t<!-- img upload begin -->\n\t<cmpt-img-upload imgMax=\"{{1}}\" title=\"封面图上传 (必填)\" isCheck=\"{{false}}\" imgUploadSize=\"{{10}}\" imgList=\"{{imgList}}\" bind:upload=\"bindImgUploadCmpt\" />\n\t<!-- img upload end -->\n</view>\n\n<view class=\"form-box shadow margin-top-xs\">\n\t<cmpt-form-show id=\"cmpt-form\" mark=\"cmpt-form\" source=\"admin\" isCacheMatch=\"{{false}}\" fields=\"{{fields}}\" forms=\"{{formForms}}\" isDefMatch=\"{{id?false:true}}\">\n\t</cmpt-form-show>\n</view>\n\n\n<button bindtap=\"bindFormSubmit\" class=\"btn-admin margin-top-xs\">提交</button>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/news/edit/admin_news_edit.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\nconst validate = require('../../../../../../helper/validate.js');\nconst AdminNewsBiz = require('../../../../biz/admin_news_biz.js');\nconst PublicBiz = require('../../../../../../comm/biz/public_biz.js');\nconst projectSetting = require('../../../../public/project_setting.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false,\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tif (!pageHelper.getOptions(this, options)) return;\n\n\t\twx.setNavigationBarTitle({\n\t\t\ttitle: projectSetting.NEWS_NAME + '-修改',\n\t\t});\n\n\t\tthis._loadDetail();\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\t\tawait this._loadDetail();\n\t\twx.stopPullDownRefresh();\n\t},\n\n\tmodel: function (e) {\n\t\tpageHelper.model(this, e);\n\t},\n\n\t_loadDetail: async function () {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet id = this.data.id;\n\t\tif (!id) return;\n\n\t\tif (!this.data.isLoad) this.setData(AdminNewsBiz.initFormData(id)); // 初始化表单数据\n\n\t\tlet params = {\n\t\t\tid\n\t\t};\n\t\tlet opt = {\n\t\t\ttitle: 'bar'\n\t\t};\n\t\tlet news = await cloudHelper.callCloudData('admin/news_detail', params, opt);\n\t\tif (!news) {\n\t\t\tthis.setData({\n\t\t\t\tisLoad: null\n\t\t\t})\n\t\t\treturn;\n\t\t};\n\n\t\tthis.setData({\n\t\t\tisLoad: true,\n\n\t\t\timgList: news.NEWS_PIC,\n\n\t\t\t// 表单数据  \n\t\t\tformCateId: news.NEWS_CATE_ID,\n\t\t\tformOrder: news.NEWS_ORDER,\n\n\t\t\tformTitle: news.NEWS_TITLE,\n\t\t\tformContent: news.NEWS_CONTENT,\n\n\t\t\tformDesc: news.NEWS_DESC,\n\n\t\t\tformForms: news.NEWS_FORMS,\n\n\t\t}, () => {\n\t\t\tthis._setContentDesc();\n\n\t\t});\n\t},\n\n\t_setContentDesc: function () {\n\t\tAdminBiz.setContentDesc(this);\n\t},\n\n\t/** \n\t * 数据提交\n\t */\n\tbindFormSubmit: async function () {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\t// 数据校验\n\t\tlet data = this.data;\n\t\tif (this.data.formContent.length == 0) {\n\t\t\treturn pageHelper.showModal('详细内容不能为空');\n\t\t}\n\t\tdata = validate.check(data, AdminNewsBiz.CHECK_FORM, this);\n\t\tif (!data) return;\n\n\t\tlet forms = this.selectComponent(\"#cmpt-form\").getForms(true);\n\t\tif (!forms) return;\n\t\tdata.forms = forms; \n\n\t\tdata.cateName = AdminNewsBiz.getCateName(data.cateId);\n\n\t\ttry {\n\t\t\tlet newsId = this.data.id;\n\t\t\tdata.id = newsId;\n\n\t\t\tif (this.data.imgList.length == 0) {\n\t\t\t\treturn pageHelper.showModal('请上传封面图');\n\t\t\t}\n\n\t\t\t// 提取简介  \n\t\t\tdata.desc = PublicBiz.getRichEditorDesc(data.desc, this.data.formContent);\n\n\t\t\t// 先修改，再上传 \n\t\t\tawait cloudHelper.callCloudSumbit('admin/news_edit', data);\n\n\t\t\t// 封面图片 提交处理 \n\t\t\twx.showLoading({\n\t\t\t\ttitle: '提交中...',\n\t\t\t\tmask: true\n\t\t\t});\n\t\t\tawait cloudHelper.transCoverTempPics(this.data.imgList, 'news/', newsId, 'admin/news_update_pic');\n\n\t\t\t// 富文本图片\n\t\t\tlet formContent = this.data.formContent;\n\t\t\twx.showLoading({\n\t\t\t\ttitle: '提交中...',\n\t\t\t\tmask: true\n\t\t\t});\n\t\t\tlet content = await cloudHelper.transRichEditorTempPics(formContent, 'news/', newsId, 'admin/news_update_content');\n\t\t\tthis.setData({\n\t\t\t\tformContent: content\n\t\t\t});\n\n\t\t\tawait cloudHelper.transFormsTempPics(forms, 'news/', newsId, 'admin/news_update_forms');\n\n\t\t\tlet callback = async () => {\n\n\t\t\t\t// 更新列表页面数据\n\t\t\t\tlet node = {\n\t\t\t\t\t'NEWS_TITLE': data.title,\n\t\t\t\t\t'NEWS_CATE_NAME': data.cateName,\n\t\t\t\t\t'NEWS_ORDER': data.order,\n\t\t\t\t}\n\t\t\t\tpageHelper.modifyPrevPageListNodeObject(newsId, node);\n\n\t\t\t\twx.navigateBack();\n\n\t\t\t}\n\t\t\tpageHelper.showSuccToast('修改成功', 2000, callback);\n\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t}\n\n\t},\n\n\n\tbindImgUploadCmpt: function (e) {\n\t\tthis.setData({\n\t\t\timgList: e.detail\n\t\t});\n\t},\n\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t}\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/news/edit/admin_news_edit.json",
    "content": "{\n\t\"usingComponents\": {\n\t\t\"cmpt-img-upload\": \"/cmpts/public/img/img_upload_cmpt\",\n\t\t\"cmpt-form-show\": \"/cmpts/public/form/form_show/form_show_cmpt\"  \n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\",\n\t\"enablePullDownRefresh\": true\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/news/edit/admin_news_edit.wxml",
    "content": "<view wx:if=\"{{isLoad===null}}\" class=\"margin-top load notexist text-l text-grey\"></view>\n<view wx:if=\"{{isLoad===false}}\" class=\"margin-top load loading text-l text-grey\"></view>\n\n<view class=\"main-admin\" wx:if=\"{{isAdmin&&isLoad}}\">\n\t<include src=\"../admin_news_form_tpl.wxml\" /> \n</view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/news/edit/admin_news_edit.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss'; "
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/news/list/admin_news_list.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst NewsBiz = require('../../../../biz/news_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\nconst projectSetting = require('../../../../public/project_setting.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\twx.setNavigationBarTitle({\n\t\t\ttitle: projectSetting.NEWS_NAME + '-管理',\n\t\t});\n\t\tthis.setData({\n\t\t\tNEWS_NAME: projectSetting.NEWS_NAME\n\t\t});\n\n\t\t//设置搜索菜单\n\t\tthis._getSearchMenu();\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: async function () { },\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\turl: async function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tbindCommListCmpt: function (e) {\n\t\tpageHelper.commListListener(this, e);\n\t},\n\n\t_setSort: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tlet id = e.currentTarget.dataset.id;\n\t\tlet sort = e.currentTarget.dataset.sort;\n\t\tif (!id) return;\n\n\t\tlet params = {\n\t\t\tid,\n\t\t\tsort\n\t\t}\n\n\t\ttry {\n\t\t\tawait cloudHelper.callCloudSumbit('admin/news_sort', params).then(res => {\n\t\t\t\tpageHelper.modifyListNode(id, this.data.dataList.list, 'NEWS_ORDER', sort);\n\t\t\t\tthis.setData({\n\t\t\t\t\tdataList: this.data.dataList\n\t\t\t\t});\n\t\t\t\tpageHelper.showSuccToast('设置成功');\n\t\t\t});\n\t\t} catch (e) {\n\t\t\tconsole.log(e);\n\t\t}\n\t},\n\n\t_setVouch: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet id = pageHelper.dataset(e, 'id');\n\t\tlet vouch = pageHelper.dataset(e, 'vouch');\n\t\tif (!id) return;\n\n\t\tlet params = {\n\t\t\tid,\n\t\t\tvouch\n\t\t}\n\n\t\ttry {\n\t\t\tawait cloudHelper.callCloudSumbit('admin/news_vouch', params).then(res => {\n\t\t\t\tpageHelper.modifyListNode(id, this.data.dataList.list, 'NEWS_VOUCH', vouch);\n\t\t\t\tthis.setData({\n\t\t\t\t\tdataList: this.data.dataList\n\t\t\t\t});\n\t\t\t\tpageHelper.showSuccToast('设置成功');\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t}\n\t},\n\n\t_del: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tlet id = pageHelper.dataset(e, 'id');\n\n\t\tlet params = {\n\t\t\tid\n\t\t}\n\n\t\tlet callback = async () => {\n\t\t\ttry {\n\t\t\t\tlet opts = {\n\t\t\t\t\ttitle: '删除中'\n\t\t\t\t}\n\t\t\t\tawait cloudHelper.callCloudSumbit('admin/news_del', params, opts).then(res => {\n\t\t\t\t\tpageHelper.delListNode(id, this.data.dataList.list, '_id');\n\t\t\t\t\tthis.data.dataList.total--;\n\t\t\t\t\tthis.setData({\n\t\t\t\t\t\tdataList: this.data.dataList\n\t\t\t\t\t});\n\t\t\t\t\tpageHelper.showSuccToast('删除成功');\n\t\t\t\t});\n\t\t\t} catch (e) {\n\t\t\t\tconsole.log(e);\n\t\t\t}\n\t\t}\n\t\tpageHelper.showConfirm('确认删除？删除不可恢复', callback);\n\n\t},\n\n\tbindMoreTap: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tlet idx = pageHelper.dataset(e, 'idx');\n\n\t\tlet order = this.data.dataList.list[idx].NEWS_ORDER;\n\t\tlet orderDesc = (order == 0) ? '取消置顶' : '置顶';\n\n\t\tlet vouch = this.data.dataList.list[idx].NEWS_VOUCH;\n\t\tlet vouchDesc = (vouch == 0) ? '推荐到首页' : '取消首页推荐';\n\n\t\tlet itemList = ['预览', orderDesc, vouchDesc, '生成专属二维码'];\n\n\t\twx.showActionSheet({\n\t\t\titemList,\n\t\t\tsuccess: async res => {\n\t\t\t\tswitch (res.tapIndex) {\n\t\t\t\t\tcase 0: { //预览\n\t\t\t\t\t\tlet id = pageHelper.dataset(e, 'id');\n\t\t\t\t\t\twx.navigateTo({\n\t\t\t\t\t\t\turl: '../../../news/detail/news_detail?id=' + id,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 1: { //置顶 \n\t\t\t\t\t\tlet sort = (order == 0) ? 9999 : 0;\n\t\t\t\t\t\te.currentTarget.dataset['sort'] = sort;\n\t\t\t\t\t\tawait this._setSort(e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 2: { //上首页 \n\t\t\t\t\t\tvouch = (vouch == 0) ? 1 : 0;\n\t\t\t\t\t\te.currentTarget.dataset['vouch'] = vouch;\n\t\t\t\t\t\tawait this._setVouch(e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 3: { //二维码 \n\t\t\t\t\t\tlet title = encodeURIComponent(pageHelper.dataset(e, 'title'));\n\t\t\t\t\t\tlet qr = encodeURIComponent(pageHelper.dataset(e, 'qr')); \n\t\t\t\t\t\twx.navigateTo({\n\t\t\t\t\t\t\turl: `../../setup/qr/admin_setup_qr?title=${title}&qr=${qr}`,\n\t\t\t\t\t\t})\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\n\t\t\t},\n\t\t\tfail: function (res) { }\n\t\t})\n\t},\n\n\tbindStatusMoreTap: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tlet itemList = ['启用', '停用 (不可见)', '删除'];\n\t\twx.showActionSheet({\n\t\t\titemList,\n\t\t\tsuccess: async res => {\n\t\t\t\tswitch (res.tapIndex) {\n\t\t\t\t\tcase 0: { //启用\n\t\t\t\t\t\te.currentTarget.dataset['status'] = 1;\n\t\t\t\t\t\tawait this._setStatus(e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 1: { //停止 \n\t\t\t\t\t\te.currentTarget.dataset['status'] = 0;\n\t\t\t\t\t\tawait this._setStatus(e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 2: { //删除\n\t\t\t\t\t\tawait this._del(e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\n\t\t\t},\n\t\t\tfail: function (res) { }\n\t\t})\n\t},\n\n\n\t_setStatus: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tlet id = pageHelper.dataset(e, 'id');\n\t\tlet status = Number(pageHelper.dataset(e, 'status'));\n\t\tlet params = {\n\t\t\tid,\n\t\t\tstatus\n\t\t}\n\n\t\ttry {\n\t\t\tawait cloudHelper.callCloudSumbit('admin/news_status', params).then(res => {\n\t\t\t\tpageHelper.modifyListNode(id, this.data.dataList.list, 'NEWS_STATUS', status, '_id');\n\t\t\t\tthis.setData({\n\t\t\t\t\tdataList: this.data.dataList\n\t\t\t\t});\n\t\t\t\tpageHelper.showSuccToast('设置成功');\n\t\t\t});\n\t\t} catch (e) {\n\t\t\tconsole.log(e);\n\t\t}\n\t},\n\n\t_getSearchMenu: function () {\n\t\tlet cateIdOptions = NewsBiz.getCateList();\n\n\t\tlet sortItem1 = [{ label: '分类', type: '', value: 0 }];\n\t\tsortItem1 = sortItem1.concat(NewsBiz.getCateList());\n\t\tlet sortItems = [sortItem1];\n\n\t\tlet sortMenus = [\n\t\t\t{ label: '全部', type: '', value: '' },\n\t\t\t{ label: '正常', type: 'status', value: 1 },\n\t\t\t{ label: '停用', type: 'status', value: 0 },\n\t\t\t{ label: '最新', type: 'sort', value: 'new' },\n\t\t\t{ label: '首页推荐', type: 'vouch', value: 'vouch' },\n\t\t\t{ label: '置顶', type: 'top', value: 'top' },\n\t\t];\n\n\t\tthis.setData({\n\t\t\tsearch: '',\n\t\t\tcateIdOptions,\n\t\t\tsortItems,\n\t\t\tsortMenus,\n\t\t\tisLoad: true\n\t\t})\n\n\n\t}\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/news/list/admin_news_list.json",
    "content": "{\n\t\"usingComponents\": { \n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\", \n\t\"disableScroll\": true\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/news/list/admin_news_list.wxml",
    "content": "<block wx:if=\"{{isAdmin&&isLoad}}\">\n\t<cmpt-comm-list source='admin' type=\"admin-news-list\" search=\"{{search||''}}\" _menus=\"{{sortMenus}}\" _items=\"{{sortItems}}\" route=\"admin/news_list\" sortMenusDefaultIndex=\"0\" topBottom=\"50\" placeholder=\"搜索标题\" bind:list=\"bindCommListCmpt\">\n\n\t\t<view slot=\"searchEnd\">\n\t\t\t<button bindtap=\"url\" data-url=\"../add/admin_news_add\" class=\"btn radius bg-admin text-white margin-right-s\"><text class=\"icon-roundadd margin-right-xxs\"></text>添加{{NEWS_NAME}}</button>\n\t\t</view>\n\t\t<!-- List Begin -->\n\t\t<view class=\"admin-comm-list\">\n\t\t\t<view wx:if=\"{{dataList && dataList.total }}\" class=\"load text-grey\">共有{{dataList.total}}条符合条件记录</view>\n\n\t\t\t<view class=\"item\" wx:for=\"{{dataList.list}}\" wx:key=\"key\">\n\t\t\t\t<view class=\"no\">{{index+1}}</view>\n\t\t\t\t<view class=\"header\">\n\t\t\t\t\t<view class=\"left text-cut\"><text wx:if=\"{{item.NEWS_ORDER==0}}\" class=\"text-black margin-right-xxs\" style=\"font-weight:normal;font-size:24rpx\">[置顶]</text><text wx:if=\"{{item.NEWS_VOUCH==1}}\" class=\"text-black margin-right-xxs\" style=\"font-weight:normal;font-size:24rpx\">[首页推荐]</text> {{item.NEWS_TITLE}}\n\t\t\t\t\t</view>\n\t\t\t\t\t<view class=\"right\">\n\t\t\t\t\t\t<text wx:if=\"{{item.NEWS_STATUS==1}}\" class=\"text-black\">「正常」</text>\n\t\t\t\t\t\t<text wx:elif=\"{{item.NEWS_STATUS==0}}\" class=\"text-orange\">「停用」</text>\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\n\t\t\t\t<view class=\"info\">\n\t\t\t\t\t<view wx:if=\"{{cateIdOptions.length>1}}\" class=\"info-item\">\n\t\t\t\t\t\t<view class=\"title\">分类</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view class=\"content\">『{{item.NEWS_CATE_NAME}}』</view>\n\t\t\t\t\t</view>\n\n\t\t\t\t\t<view class=\"info-item\">\n\t\t\t\t\t\t<view class=\"title\">排序号</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view class=\"content\">{{item.NEWS_ORDER}} <text class=\"margin-left-xxs text-grey\">(小的先显示)</text></view>\n\t\t\t\t\t</view>\n\n\t\t\t\t\t<view class=\"info-item\">\n\t\t\t\t\t\t<view class=\"title\">创建</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view class=\"content\">{{item.NEWS_ADD_TIME}}</view>\n\t\t\t\t\t</view>\n\n\t\t\t\t\t<view class=\"oprt\">\n\t\t\t\t\t\t<view bindtap=\"url\" data-url=\"../edit/admin_news_edit?id={{item._id}}\" class=\"btn round margin-right-s\"><text class=\"icon-edit margin-right-xxs\"></text>编辑</view> \n\n\t\t\t\t\t\t<view bindtap=\"bindStatusMoreTap\" data-id=\"{{item._id}}\" class=\"btn margin-right-s\">状态管理</view>\n\n\t\t\t\t\t\t<view data-idx=\"{{index}}\"  bindtap=\"bindMoreTap\" data-id=\"{{item._id}}\" data-idx=\"{{index}}\" data-qr=\"{{item.NEWS_QR}}\" data-title=\"{{item.NEWS_TITLE}}\" class=\"btn margin-right-s\">更多操作</view> \n\n\t\t\t\t\t\t<view bindtap=\"url\"  data-url=\"../../../news/detail/news_detail?id={{item._id}}\" class=\"btn margin-right-s\">预览</view>\n\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\t\t\t</view>\n\n\t\t</view>\n\t\t<!-- List END -->\n\n\t\t<!--load begin-->\n\t\t<import src=\"../../../../../../tpls/public/list_load_tpl.wxml\" />\n\t\t<template is=\"listLoadTpl\" data=\"{{dataList,skin:'text-grey'}}\" />\n\t\t<!--load end-->\n\n\n\t</cmpt-comm-list>\n\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/news/list/admin_news_list.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n@import '../../../../../../style/project/admin_list_style.wxss';\n\npage {\n\tbackground-color: #f8f8f8;\n}\n\n "
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/product/add/admin_product_add.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst PublicBiz = require('../../../../../../comm/biz/public_biz.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\nconst validate = require('../../../../../../helper/validate.js');\nconst AdminProductBiz = require('../../../../biz/admin_product_biz.js');\nconst ProductBiz = require('../../../../biz/product_biz.js'); \n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tthis.setData(AdminProductBiz.initFormData());\n\t\tthis.setData({\n\t\t\tisLoad: true\n\t\t});\n\t},\n\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () { },\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tbindFormSubmit: async function () {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet data = this.data;\n\t\tdata = validate.check(data, AdminProductBiz.CHECK_FORM, this);\n\t\tif (!data) return;\n\n\t\tlet forms = this.selectComponent(\"#cmpt-form\").getForms(true);\n\t\tif (!forms) return;\n\t\tdata.forms = forms;\n\n\t\tdata.cateName = ProductBiz.getCateName(data.cateId);\n\n\t\ttry {\n\n\t\t\t// 创建\n\t\t\tlet result = await cloudHelper.callCloudSumbit('admin/product_insert', data);\n\t\t\tlet productId = result.data.id;\n\n\t\t\t// 图片\n\t\t\tawait cloudHelper.transFormsTempPics(forms, 'product/', productId, 'admin/product_update_forms');\n\n\n\t\t\tlet callback = async function () {\n\t\t\t\tPublicBiz.removeCacheList('admin-product-list');\n\t\t\t\tPublicBiz.removeCacheList('product-list');\n\t\t\t\twx.navigateBack();\n\n\t\t\t}\n\t\t\tpageHelper.showSuccToast('添加成功', 2000, callback);\n\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t}\n\n\t},\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/product/add/admin_product_add.json",
    "content": "{\n\t\"usingComponents\": {\n\t\t\"cmpt-img-upload\": \"/cmpts/public/img/img_upload_cmpt\",\n\t\t\"cmpt-form-show\": \"/cmpts/public/form/form_show/form_show_cmpt\"  \n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\",\n\t\"enablePullDownRefresh\": true, \n\t\"navigationBarTitleText\": \"后台-景点添加\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/product/add/admin_product_add.wxml",
    "content": "<view wx:if=\"{{!isLoad}}\" class=\"margin-top load loading text-l text-grey\"></view>\n<view class=\"main-admin\" wx:if=\"{{isAdmin&&isLoad}}\">\n\t<include src=\"../admin_product_form_tpl.wxml\" /> \n</view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/product/add/admin_product_add.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n "
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/product/admin_product_form_tpl.wxml",
    "content": "<view class=\"form-box shadow\">\n\t<view class=\"form-group\">\n\t\t<view class=\"title must\">标题</view>\n\t</view>\n\n\t<view class=\"form-group\">\n\t\t<input placeholder=\"简短的标题\" placeholder-class=\"phc\" model:value=\"{{formTitle}}\" focus=\"{{formTitleFocus}}\" maxlength=\"50\"></input>\n\t</view>\n\t<view wx:if=\"{{formTitleFocus}}\" class=\"hint-desc error\">{{formTitleFocus}}</view>\n\n  \n\t<view wx:if=\"{{cateIdOptions.length>1}}\" class=\"form-group arrow\" id=\"formCateId\">\n\t\t<view class=\"title must\">分类</view>\n\t\t<cmpt-picker id=\"cate-picker\" sourceData=\"{{cateIdOptions}}\" bind:select=\"url\" data-type=\"picker\" data-item=\"formCateId\" item=\"{{formCateId}}\"> </cmpt-picker>\n\t</view>\n\t<view wx:if=\"{{formCateIdFocus}}\" class=\"hint-desc error\">{{formCateIdFocus}}</view> \n\n\t<view class=\"form-group\">\n\t\t<view class=\"title must\">排序号<text class=\"text-grey text-normal margin-left-xs\">(小的先显示)</text></view>\n\t\t<input placeholder=\"排序号，小的先显示\" type=\"number\" placeholder-class=\"phc\" model:value=\"{{formOrder}}\" focus=\"{{formOrderFocus}}\" maxlength=\"4\"></input>\n\t</view>\n\t<view wx:if=\"{{formOrderFocus}}\" class=\"hint-desc error\">{{formOrderFocus}}</view>\n\n\n</view>\n\n<view class=\"form-box shadow margin-top-xs\">\n\t<cmpt-form-show id=\"cmpt-form\" mark=\"cmpt-form\" source=\"admin\" isCacheMatch=\"{{false}}\" fields=\"{{fields}}\" forms=\"{{formForms}}\" isDefMatch=\"{{id?false:true}}\">\n\t</cmpt-form-show>\n</view>\n\n\n<button bindtap=\"bindFormSubmit\" class=\"btn-admin margin-top-xs\">提交</button>\n\n<view style=\"height:200rpx\"></view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/product/edit/admin_product_edit.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\nconst dataHelper = require('../../../../../../helper/data_helper.js');\nconst validate = require('../../../../../../helper/validate.js');\nconst AdminProductBiz = require('../../../../biz/admin_product_biz.js');\nconst ProductBiz = require('../../../../biz/product_biz.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false,\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tif (!pageHelper.getOptions(this, options)) return;\n\n\t\tthis._loadDetail();\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () { },\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\t\tawait this._loadDetail();\n\t\tthis.selectComponent(\"#cmpt-form\").reload();\n\t\twx.stopPullDownRefresh();\n\t},\n\n\tmodel: function (e) {\n\t\tpageHelper.model(this, e);\n\t},\n\n\t_loadDetail: async function () {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet id = this.data.id;\n\t\tif (!id) return;\n\n\t\tif (!this.data.isLoad) this.setData(AdminProductBiz.initFormData(id)); // 初始化表单数据\n\n\t\tlet params = {\n\t\t\tid\n\t\t};\n\t\tlet opt = {\n\t\t\ttitle: 'bar'\n\t\t};\n\t\tlet product = await cloudHelper.callCloudData('admin/product_detail', params, opt);\n\t\tif (!product) {\n\t\t\tthis.setData({\n\t\t\t\tisLoad: null\n\t\t\t})\n\t\t\treturn;\n\t\t};\n\n\t\tthis.setData({\n\t\t\tisLoad: true,\n\n\t\t\tformTitle: product.PRODUCT_TITLE,\n\t\t\tformCateId: product.PRODUCT_CATE_ID,\n\t\t\tformOrder: product.PRODUCT_ORDER,\n\t\t\t\n\t\t\tformForms: product.PRODUCT_FORMS,\n\t\t});\n\t},\n\n\tbindFormSubmit: async function () {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\t// 数据校验\n\t\tlet data = this.data;\n\t\tdata = validate.check(data, AdminProductBiz.CHECK_FORM, this);\n\t\tif (!data) return;\n\n\t\tlet forms = this.selectComponent(\"#cmpt-form\").getForms(true);\n\t\tif (!forms) return;\n\t\tdata.forms = forms;\n\n\t\tdata.cateName = ProductBiz.getCateName(data.cateId);\n\n\t\ttry {\n\t\t\tlet productId = this.data.id;\n\t\t\tdata.id = productId;\n\n\t\t\t// 先修改，再上传 \n\t\t\tawait cloudHelper.callCloudSumbit('admin/product_edit', data);\n\n\t\t\tawait cloudHelper.transFormsTempPics(forms, 'product/', productId, 'admin/product_update_forms');\n\n\t\t\tlet callback = () => { \n\t\t\t\t// 更新列表页面数据\n\t\t\t\tlet node = {\n\t\t\t\t\t'PRODUCT_TITLE': data.title,\n\t\t\t\t\t'PRODUCT_CATE_NAME': data.cateName,\n\t\t\t\t\t'PRODUCT_ORDER': data.order, \n\t\t\t\t}\n\t\t\t\tpageHelper.modifyPrevPageListNodeObject(productId, node);\n\n\t\t\t\twx.navigateBack();\n\n\t\t\t}\n\t\t\tpageHelper.showSuccToast('修改成功', 2000, callback);\n\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t}\n\n\t},\n\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t}\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/product/edit/admin_product_edit.json",
    "content": "{\n\t\"usingComponents\": {\n\t\t\"cmpt-img-upload\": \"/cmpts/public/img/img_upload_cmpt\",\n\t\t\"cmpt-form-show\": \"/cmpts/public/form/form_show/form_show_cmpt\"\n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\",\n\t\"enablePullDownRefresh\": true,\n\t\"navigationBarTitleText\": \"后台-景点修改\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/product/edit/admin_product_edit.wxml",
    "content": "<view wx:if=\"{{isLoad===null}}\" class=\"margin-top load notexist text-l text-grey\"></view>\n<view wx:if=\"{{isLoad===false}}\" class=\"margin-top load loading text-l text-grey\"></view>\n\n<view class=\"main-admin\" wx:if=\"{{isAdmin&&isLoad}}\">\n\t<include src=\"../admin_product_form_tpl.wxml\" /> \n</view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/product/edit/admin_product_edit.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss'; "
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/product/list/admin_product_list.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst ProductBiz = require('../../../../biz/product_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false,\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\t//设置搜索菜单\n\t\tthis._getSearchMenu();\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: async function () { },\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () { },\n\n\turl: async function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tbindCommListCmpt: function (e) {\n\t\tpageHelper.commListListener(this, e);\n\t},\n\n\tbindStatusMoreTap: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tlet itemList = ['启用', '停用 (不显示)', '删除'];\n\t\twx.showActionSheet({\n\t\t\titemList,\n\t\t\tsuccess: async res => {\n\t\t\t\tswitch (res.tapIndex) {\n\t\t\t\t\tcase 0: { //启用\n\t\t\t\t\t\te.currentTarget.dataset['status'] = 1;\n\t\t\t\t\t\tawait this._setStatus(e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 1: { //停止 \n\t\t\t\t\t\te.currentTarget.dataset['status'] = 0;\n\t\t\t\t\t\tawait this._setStatus(e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 2: { //删除\n\t\t\t\t\t\tawait this._del(e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tfail: function (res) { }\n\t\t})\n\t},\n\n\tbindMoreTap: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tlet idx = pageHelper.dataset(e, 'idx');\n\n\t\tlet order = this.data.dataList.list[idx].PRODUCT_ORDER;\n\t\tlet orderDesc = (order == 0) ? '取消置顶' : '置顶';\n\n\t\tlet vouch = this.data.dataList.list[idx].PRODUCT_VOUCH;\n\t\tlet vouchDesc = (vouch == 0) ? '推荐到首页' : '取消首页推荐';\n\n\t\tlet itemList = ['预览', orderDesc, vouchDesc, '生成专属二维码'];\n\n\t\twx.showActionSheet({\n\t\t\titemList,\n\t\t\tsuccess: async res => {\n\t\t\t\tswitch (res.tapIndex) {\n\t\t\t\t\tcase 0: { //预览\n\t\t\t\t\t\tlet id = pageHelper.dataset(e, 'id');\n\t\t\t\t\t\twx.navigateTo({\n\t\t\t\t\t\t\turl: '../../../product/detail/product_detail?id=' + id,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 1: { //置顶 \n\t\t\t\t\t\tlet sort = (order == 0) ? 9999 : 0;\n\t\t\t\t\t\te.currentTarget.dataset['sort'] = sort;\n\t\t\t\t\t\tawait this._setSort(e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 2: { //上首页 \n\t\t\t\t\t\tvouch = (vouch == 0) ? 1 : 0;\n\t\t\t\t\t\te.currentTarget.dataset['vouch'] = vouch;\n\t\t\t\t\t\tawait this._setVouch(e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 3: { //二维码 \n\t\t\t\t\t\tlet title = encodeURIComponent(pageHelper.dataset(e, 'title'));\n\t\t\t\t\t\tlet qr = encodeURIComponent(pageHelper.dataset(e, 'qr'));\n\t\t\t\t\t\twx.navigateTo({\n\t\t\t\t\t\t\turl: `../../setup/qr/admin_setup_qr?title=${title}&qr=${qr}`,\n\t\t\t\t\t\t})\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\n\t\t\t},\n\t\t\tfail: function (res) { }\n\t\t})\n\t},\n\n\t_setSort: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet id = pageHelper.dataset(e, 'id');\n\t\tlet sort = pageHelper.dataset(e, 'sort');\n\t\tif (!id) return;\n\n\t\tlet params = {\n\t\t\tid,\n\t\t\tsort\n\t\t}\n\n\t\ttry {\n\t\t\tawait cloudHelper.callCloudSumbit('admin/product_sort', params).then(res => {\n\t\t\t\tpageHelper.modifyListNode(id, this.data.dataList.list, 'PRODUCT_ORDER', sort);\n\t\t\t\tthis.setData({\n\t\t\t\t\tdataList: this.data.dataList\n\t\t\t\t});\n\t\t\t\tpageHelper.showSuccToast('设置成功');\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t}\n\t},\n\n\t_setVouch: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet id = pageHelper.dataset(e, 'id');\n\t\tlet vouch = pageHelper.dataset(e, 'vouch');\n\t\tif (!id) return;\n\n\t\tlet params = {\n\t\t\tid,\n\t\t\tvouch\n\t\t}\n\n\t\ttry {\n\t\t\tawait cloudHelper.callCloudSumbit('admin/product_vouch', params).then(res => {\n\t\t\t\tpageHelper.modifyListNode(id, this.data.dataList.list, 'PRODUCT_VOUCH', vouch);\n\t\t\t\tthis.setData({\n\t\t\t\t\tdataList: this.data.dataList\n\t\t\t\t});\n\t\t\t\tpageHelper.showSuccToast('设置成功');\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t}\n\t},\n\n\t_del: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tlet id = pageHelper.dataset(e, 'id');\n\n\t\tlet params = {\n\t\t\tid\n\t\t}\n\n\t\tlet callback = async () => {\n\t\t\ttry {\n\t\t\t\tlet opts = {\n\t\t\t\t\ttitle: '删除中'\n\t\t\t\t}\n\t\t\t\tawait cloudHelper.callCloudSumbit('admin/product_del', params, opts).then(res => {\n\t\t\t\t\tpageHelper.delListNode(id, this.data.dataList.list, '_id');\n\t\t\t\t\tthis.data.dataList.total--;\n\t\t\t\t\tthis.setData({\n\t\t\t\t\t\tdataList: this.data.dataList\n\t\t\t\t\t});\n\t\t\t\t\tpageHelper.showSuccToast('删除成功');\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tconsole.log(err);\n\t\t\t}\n\t\t}\n\t\tpageHelper.showConfirm('确认删除？删除不可恢复', callback);\n\n\t},\n\n\t_setStatus: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tlet id = pageHelper.dataset(e, 'id');\n\t\tlet status = Number(pageHelper.dataset(e, 'status'));\n\t\tlet params = {\n\t\t\tid,\n\t\t\tstatus\n\t\t}\n\n\t\ttry {\n\t\t\tawait cloudHelper.callCloudSumbit('admin/product_status', params).then(res => {\n\t\t\t\tpageHelper.modifyListNode(id, this.data.dataList.list, 'PRODUCT_STATUS', status, '_id');\n\t\t\t\tthis.setData({\n\t\t\t\t\tdataList: this.data.dataList\n\t\t\t\t});\n\t\t\t\tpageHelper.showSuccToast('设置成功');\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t}\n\t},\n\n\t_getSearchMenu: function () {\n\t\tlet cateIdOptions = ProductBiz.getCateList();\n\n\t\tlet sortItem1 = [{ label: '分类', type: '', value: 0 }];\n\t\tsortItem1 = sortItem1.concat(cateIdOptions);\n\n\t\tlet sortItem2 = [\n\t\t\t{ label: '排序', type: '', value: 0 },\n\t\t\t{ label: '推荐指数从高到底', type: 'sort', value: 'PRODUCT_OBJ.star|desc' },\n\t\t\t{ label: '推荐指数从低到高', type: 'sort', value: 'PRODUCT_OBJ.star|asc' },\n\t\t];\n\n\t\tlet sortItems = [];\n\t\tif (sortItem1.length > 2) sortItems.push(sortItem1);\n\t\tsortItems.push(sortItem2);\n\n\t\tlet sortMenus = [\n\t\t\t{ label: '全部', type: '', value: '' },\n\t\t\t{ label: '正常', type: 'status', value: 1 },\n\t\t\t{ label: '停用', type: 'status', value: 0 },\n\t\t\t{ label: '最新', type: 'sort', value: 'new' },\n\t\t\t{ label: '首页推荐', type: 'vouch', value: 'vouch' },\n\t\t\t{ label: '置顶', type: 'top', value: 'top' },\n\t\t]\n\t\tthis.setData({\n\t\t\tcateIdOptions,\n\t\t\tsortItems,\n\t\t\tsortMenus\n\t\t})\n\t}\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/product/list/admin_product_list.json",
    "content": "{\n\t\"usingComponents\": { \n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\", \n\t\"disableScroll\": true, \n\t\"navigationBarTitleText\": \"后台-景点管理\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/product/list/admin_product_list.wxml",
    "content": "<block wx:if=\"{{isAdmin}}\">\n    <cmpt-comm-list source='admin' type=\"admin-product-list\" search=\"{{search}}\" _menus=\"{{sortMenus}}\" _items=\"{{sortItems}}\" route=\"admin/product_list\" sortMenusDefaultIndex=\"0\" topBottom=\"50\" placeholder=\"搜索标题\" bind:list=\"bindCommListCmpt\"> \n\n        <view slot=\"searchEnd\">\n            <button bindtap=\"url\" data-url=\"../add/admin_product_add\" class=\"btn radius bg-admin text-white margin-right-s\"><text class=\"icon-roundadd margin-right-xxs\"></text>添加新景点</button>\n        </view>\n        <!-- List Begin -->\n        <view class=\"admin-comm-list\">\n            <view wx:if=\"{{dataList && dataList.total }}\" class=\"load text-grey\">共有{{dataList.total}}条符合条件记录</view>\n\n            <view class=\"item\" wx:for=\"{{dataList.list}}\" wx:key=\"key\">\n\t\t\t\t<view class=\"no\">{{index+1}}</view>\n                <view class=\"header\">\n                    <view class=\"left text-cut\"><text wx:if=\"{{item.PRODUCT_ORDER==0}}\" class=\"text-black margin-right-xxs\" style=\"font-weight:normal;font-size:24rpx\">[置顶]</text><text wx:if=\"{{item.PRODUCT_VOUCH==1}}\" class=\"text-black margin-right-xxs\" style=\"font-weight:normal;font-size:24rpx\">[首页推荐]</text> {{item.PRODUCT_TITLE}}\n                    </view>\n                    <view class=\"right\">\n                        <text wx:if=\"{{item.PRODUCT_STATUS==1}}\" class=\"text-black\">「正常」</text>\n                        <text wx:elif=\"{{item.PRODUCT_STATUS==0}}\" class=\"text-orange\">「停用」</text>\n                    </view>\n                </view>\n\n                <view class=\"info\"> \n                    <view wx:if=\"{{cateIdOptions.length>1}}\" class=\"info-item\">\n                        <view class=\"title\">分类</view>\n                        <view class=\"mao\">：</view>\n                        <view class=\"content\">『{{item.PRODUCT_CATE_NAME}}』</view>\n                    </view> \n\n                    <view class=\"info-item\">\n                        <view class=\"title\">排序号</view>\n                        <view class=\"mao\">：</view>\n                        <view class=\"content\">{{item.PRODUCT_ORDER}} <text class=\"margin-left-xxs text-grey\">(小的先显示)</text></view>\n                    </view>\n\n                    <view class=\"info-item\">\n                        <view class=\"title\">推荐指数</view>\n                        <view class=\"mao\">：</view>\n                        <view class=\"content text-admin\" style=\"font-size:28rpx;\">{{item.PRODUCT_OBJ.star}}颗星 </view>\n                    </view> \n\n                    <view class=\"info-item\">\n                        <view class=\"title\">创建</view>\n                        <view class=\"mao\">：</view>\n                        <view class=\"content\">{{item.PRODUCT_ADD_TIME}}</view>\n                    </view> \n\n                    <view class=\"oprt\">\n                        <view bindtap=\"url\" data-url=\"../edit/admin_product_edit?id={{item._id}}\" class=\"btn round margin-right-s\"><text class=\"icon-edit margin-right-xxs\"></text>编辑</view> \n\n                        <view bindtap=\"bindStatusMoreTap\" data-id=\"{{item._id}}\" class=\"btn margin-right-s\">状态管理..</view>  \n\n                        <view bindtap=\"bindMoreTap\" data-id=\"{{item._id}}\" data-idx=\"{{index}}\" data-qr=\"{{item.PRODUCT_QR}}\" data-title=\"{{item.PRODUCT_TITLE}}\" class=\"btn margin-right-s\">更多...</view> \n\n\t\t\t\t\t\t<view bindtap=\"url\" data-url=\"../../../product/detail/product_detail?id={{item._id}}\" class=\"btn margin-right-s\">预览</view> \n\n                    </view>\n                </view>\n            </view>\n\n        </view>\n        <!-- List END -->\n\n        <!--load begin-->\n        <import src=\"../../../../../../tpls/public/list_load_tpl.wxml\" />\n        <template is=\"listLoadTpl\" data=\"{{dataList,skin:'text-grey'}}\" />\n        <!--load end-->\n\n\n    </cmpt-comm-list>\n\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/product/list/admin_product_list.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n@import '../../../../../../style/project/admin_list_style.wxss';\n\npage {\n\tbackground-color: #f8f8f8;\n}\n\n"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/setup/about/admin_setup_about.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\nconst projectSetting = require('../../../../public/project_setting.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false,\n\t\tkey: '',\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tif (options && options.key) {\n\t\t\tlet key = options.key;\n\t\t\tfor (let k = 0; k < projectSetting.SETUP_CONTENT_ITEMS.length; k++) {\n\t\t\t\tlet item = projectSetting.SETUP_CONTENT_ITEMS[k];\n\t\t\t\tif (item.key == key) {\n\t\t\t\t\tthis._loadDetail(item);\n\t\t\t\t\twx.setNavigationBarTitle({\n\t\t\t\t\t\ttitle: '编辑' + item.title,\n\t\t\t\t\t});\n\t\t\t\t\tthis.setData({ key: item.key });\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\t\tawait this._loadDetail();\n\t\twx.stopPullDownRefresh();\n\t},\n\n\t_loadDetail: async function (item) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet opts = {\n\t\t\t'title': 'bar'\n\t\t};\n\t\tlet params = {\n\t\t\tkey: item.key\n\t\t}\n\n\t\ttry {\n\t\t\tawait cloudHelper.callCloudSumbit('home/setup_get', params, opts).then(res => {\n\t\t\t\tlet formContent = [{ type: 'text', val: item.title }];\n\t\t\t\tlet content = res.data;\n\t\t\t\tif (content && Array.isArray(content)) {\n\t\t\t\t\tformContent = content;\n\t\t\t\t}\n\t\t\t\tthis.setData({\n\t\t\t\t\tisLoad: true,\n\n\t\t\t\t\t// 表单数据   \n\t\t\t\t\tformContent\n\n\t\t\t\t});\n\n\n\t\t\t});\n\t\t}\n\t\tcatch (err) {\n\t\t\tconsole.log(err);\n\t\t}\n\n\n\t},\n\n\n\t/** \n\t * 数据提交\n\t */\n\tbindFormSubmit: async function () {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet formContent = this.selectComponent(\"#contentEditor\").getNodeList();\n\n\t\tawait cloudHelper.transRichEditorTempPics(formContent, 'setup/', this.data.key, 'admin/setup_set_content');\n\n\t\tlet callback = () => {\n\t\t\twx.navigateBack();\n\t\t}\n\t\tpageHelper.showSuccToast('修改成功', 1500, callback);\n\n\t},\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/setup/about/admin_setup_about.json",
    "content": "{\n\t\"usingComponents\": {\n\t\t\"cmpt-editor\": \"/cmpts/public/editor/editor_cmpt\"\n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\",\n\t\"enablePullDownRefresh\": true, \n\t\"navigationBarTitleText\": \"编辑\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/setup/about/admin_setup_about.wxml",
    "content": "<view wx:if=\"{{!isLoad}}\" class=\"margin-top load loading text-l text-grey\"></view>\n\n<block wx:if=\"{{isAdmin&&isLoad}}\">\n\t<view class=\"main-admin\">\n\t\t<view class=\"form-box shadow\">\n\t\t\t<view class=\"form-group\" style=\"width: 100%;\">\n\t\t\t\t<cmpt-editor nodeList=\"{{formContent}}\" viewMode=\"{{true}}\" style=\"width: 100%;\" id=\"contentEditor\"></cmpt-editor>\n\t\t\t</view>\n\t\t</view>\n\t</view>\n\t<view class=\"btn-bottom-admin\"> \n\t\t<view bindtap=\"bindFormSubmit\" class=\"save\">保存修改</view>\n\t</view>\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/setup/about/admin_setup_about.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n \n.main-admin {\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tpadding: 30rpx 20rpx;\n\tpadding-bottom: 200rpx;\n}\n\n.form-group {\n\tpadding: 1rpx 1rpx;\n\toverflow: hidden;\n}\n  \n.btn-bottom-admin>view {\n    width: 100%;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/setup/about_list/admin_setup_about_list.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst projectSetting = require('../../../../public/project_setting.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad(options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tthis.setData({\n\t\t\tlist: projectSetting.SETUP_CONTENT_ITEMS\n\t\t});\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady() {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow() {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide() {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload() {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh() {\n\n\t},\n\n\t/**\n\t * 页面上拉触底事件的处理函数\n\t */\n\tonReachBottom() {\n\n\t},\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t}\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/setup/about_list/admin_setup_about_list.json",
    "content": "{\n\t\"usingComponents\": {\n\t\t \n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\",\n\t\"enablePullDownRefresh\": true, \n\t\"navigationBarTitleText\": \"单页文章\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/setup/about_list/admin_setup_about_list.wxml",
    "content": "<!-- List Begin -->\n<view class=\"main-admin\" wx:if=\"{{isAdmin}}\">\n\t<view class=\"admin-comm-list\">\n\t\t<view class=\"item\" wx:for=\"{{list}}\" wx:key=\"key\" bindtap=\"url\" data-url=\"../about/admin_setup_about?key={{item.key}}\">\n\t\t\t<view class=\"header\">\n\t\t\t\t<view class=\"left text-cut\">《{{item.title}}》</view>\n\t\t\t\t<view class=\"right\">\n\t\t\t\t\t<view class=\"btn round margin-right-s\"><text class=\"icon-edit margin-right-xxs\"></text>编辑</view>\n\n\t\t\t\t\t<view catchtap=\"url\" data-url=\"../../../about/index/about_index?key={{item.key}}\" class=\"btn round margin-right-s\"><text class=\"icon-attention margin-right-xxs\"></text>预览</view>\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t</view>\n\n\t</view>\n\t<!-- List END -->\n</view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/setup/about_list/admin_setup_about_list.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n\npage {\n\tbackground-color: #f8f8f8;\n}\n\n.main-admin {\n\tpadding: 40rpx 0;\n}\n\n.admin-comm-list .item {\n\tmargin-bottom: 40rpx;\n}\n\n.admin-comm-list .item .header .left {\n\tfont-size: 32rpx !important;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/setup/qr/admin_setup_qr.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false,\n\t\tqrUrl: '',\n\n\t\ttitle: '',\n\n\t\tpath: '',\n\t\tsc: '',\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tif (options && options.qr && options.title) {\n\t\t\tthis.setData({\n\t\t\t\tqr: decodeURIComponent(options.qr),\n\t\t\t\ttitle: decodeURIComponent(options.title),\n\t\t\t}, () => {\n\t\t\t\tthis._loadDetail();\n\t\t\t});\n\t\t}\n\t\telse\n\t\t\tthis._loadDetail();\n\t},\n\n\t_loadDetail: async function () {\n\t\tif (this.data.qr) {\n\t\t\tthis.setData({\n\t\t\t\tqrUrl: this.data.qr,\n\t\t\t\tisLoad: true\n\t\t\t})\n\t\t\treturn;\n\t\t}\n\n\t\tlet path = pageHelper.fmtURLByPID('/pages/default/index/default_index');\n\t\tlet params = {\n\t\t\tpath \n\t\t};\n\t\tlet opt = {\n\t\t\ttitle: 'bar'\n\t\t};\n\t\ttry {\n\t\t\tawait cloudHelper.callCloudSumbit('admin/setup_qr', params, opt).then(res => {\n\n\t\t\t\tthis.setData({\n\t\t\t\t\tqrUrl: res.data,\n\t\t\t\t\tisLoad: true\n\t\t\t\t});\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.error(err);\n\t\t}\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\t\tawait this._loadDetail();\n\t\twx.stopPullDownRefresh();\n\t},\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t}\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/setup/qr/admin_setup_qr.json",
    "content": "{\n\t\"usingComponents\": {\n\t \n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\", \n\t\"enablePullDownRefresh\": true,  \n\t\"navigationBarTitleText\": \"小程序码\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/setup/qr/admin_setup_qr.wxml",
    "content": "<view wx:if=\"{{!isLoad}}\" class=\"margin-top load loading text-l text-grey\"></view>\n\n\n<view class=\"main-admin\" wx:if=\"{{isAdmin&&isLoad}}\">\n\n\t<view class=\"form-box shadow margin-top-xs\">\n\n\t\t<view class=\"checkin\">\n\t\t\t<view class=\"notice\"><text class=\"icon-scan margin-right-s text-bold\"></text>放在推广的地方展示</view>\n\n\t\t\t<image bindtap=\"url\" data-type=\"img\" data-url=\"{{qrUrl}}\" mode=\"aspectFill\" class=\"loading\" show-menu-by-longpress=\"{{true}}\" src=\"{{qrUrl}}\"></image>\n\t\t\t<view class=\"oprt text-l\">长按图片保存小程序码</view>\n\n\t\t\t<view wx:if=\"{{title}}\" class=\"oprt text-black text-normal\">《{{title}}》小程序码</view>\n\t\t</view>\n\n\t</view>\n\n</view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/setup/qr/admin_setup_qr.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n\n.load.loading::after {\n\tcontent: \"小程序码生成中...\";\n}\n\n.form-box .checkin {\n\twidth: 100%;\n\tpadding: 40rpx 40rpx 80rpx;\n\tpadding-bottom: 150rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: flex-start;\n\talign-items: center;\n}\n\n.form-box .checkin .notice {\n\twidth: 100%;\n\tfont-size: 36rpx;\n\ttext-align: center;\n\tcolor: #000;\n\tmargin-bottom: 30rpx;\n}\n\n.form-box .checkin image {\n\twidth: 500rpx;\n\theight: 500rpx;\n\tmargin: 30rpx 0rpx;\n}\n\n.form-box .checkin .oprt {\n\tmargin-top: 0rpx;\n\ttext-align: center;\n\tfont-size: 30rpx;\n\tcolor: var(--adminColor);\n\tpadding: 20rpx 10rpx;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/user/detail/admin_user_detail.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false,\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tasync onLoad(options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tif (!pageHelper.getOptions(this, options)) return;\n\n\t\tthis._loadDetail();\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady() {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow() {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide() {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload() {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tasync onPullDownRefresh() {\n\t\tawait this._loadDetail();\n\t\twx.stopPullDownRefresh();\n\t},\n\n\t/**\n\t * 页面上拉触底事件的处理函数\n\t */\n\tonReachBottom() {\n\n\t},\n\n\t/**\n\t * 用户点击右上角分享\n\t */\n\tonShareAppMessage() {\n\n\t},\n\n\t_loadDetail: async function () {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet id = this.data.id;\n\t\tif (!id) return;\n\n\t\tlet params = {\n\t\t\tid\n\t\t}\n\t\tlet opts = {\n\t\t\thint: false\n\t\t}\n\t\tlet user = await cloudHelper.callCloudData('admin/user_detail', params, opts);\n\t\tif (!user) {\n\t\t\tthis.setData({\n\t\t\t\tisLoad: null,\n\t\t\t})\n\t\t\treturn;\n\t\t};\n\n\t\tthis.setData({\n\t\t\tisLoad: true,\n\t\t\tuser\n\t\t})\n\t},\n\turl(e) {\n\t\tpageHelper.url(e, this);\n\t}\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/user/detail/admin_user_detail.json",
    "content": "{\n\t\"usingComponents\": {\n\n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\",  \n\t\"enablePullDownRefresh\": true,  \n\t\"navigationBarTitleText\": \"用户详情\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/user/detail/admin_user_detail.wxml",
    "content": "<view wx:if=\"{{isLoad===null}}\" class=\"margin-top load notexist text-l text-grey\"></view>\n<view wx:if=\"{{isLoad===false}}\" class=\"margin-top load loading text-l text-grey\"></view>\n\n<view wx:if=\"{{isLoad && isAdmin}}\" class=\"main-admin\">\n\t<view class=\"admin-comm-list\">\n\t\t<view class=\"item\">\n\t\t\t<view class=\"info\">\n\t\t\t\t<view class=\"info-item\">\n\t\t\t\t\t<view class=\"title\">用户昵称</view>\n\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t<view class=\"content text-admin  text-l\">{{user.USER_NAME}} </view>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"info-item\" bindtap=\"url\" data-type=\"phone\" data-url=\"{{user.USER_MOBILE}}\">\n\t\t\t\t\t<view class=\"title\">手机号码</view>\n\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t<view class=\"content\">{{user.USER_MOBILE}} <text class=\"icon-phone text-l margin-left-xs\"></text></view>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"info-item\">\n\t\t\t\t\t<view class=\"title\">注册时间</view>\n\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t<view class=\"content\">{{user.USER_ADD_TIME}} </view>\n\t\t\t\t</view>\n\n\t\t\t\t<view class=\"info-item\" wx:key=\"key\" wx:for=\"{{user.USER_FORMS}}\">\n\t\t\t\t\t<view class=\"title\">{{item.title}}</view>\n\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t<view class=\"content\">{{item.val}} </view>\n\t\t\t\t</view>\n\t\t\t</view>\n\n\t\t</view>\n\n\t</view>\n</view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/user/detail/admin_user_detail.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n\n.main-admin {\n\tpadding: 30rpx 0rpx;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/user/export/admin_user_export.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\nconst fileHelper = require('../../../../../../helper/file_helper.js');\nconst projectSetting = require('../../../../public/project_setting.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\turl: '',\n\t\ttime: '',\n\t\tcondition: '',\n\n\t\tisLoad: false,\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tif (options && options.condition) {\n\t\t\tthis.setData({\n\t\t\t\tcondition: options.condition\n\t\t\t})\n\t\t}\n\n\t\tthis._loadDetail(1);\n\t},\n\n\t_loadDetail: async function (isDel) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\tlet params = {\n\t\t\tisDel\n\t\t}\n\t\tlet options = {\n\t\t\ttitle: 'bar'\n\t\t}\n\t\tlet data = await cloudHelper.callCloudData('admin/user_data_get', params, options);\n\n\t\tif (!data) return;\n\n\t\tthis.setData({\n\t\t\tisLoad: true,\n\t\t\turl: data.url,\n\t\t\ttime: data.time\n\t\t})\n\n\t},\n\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\t\tawait this._loadDetail(1);\n\t\twx.stopPullDownRefresh();\n\t},\n\n\tbindOpenTap: function (e) {\n\t\tfileHelper.openDoc('客户数据', this.data.url);\n\t},\n\n\turl: async function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\t/**\n\t * 页面上拉触底事件的处理函数\n\t */\n\tonReachBottom: function () {\n\n\t},\n\n\tbindExportTap: async function (e) {\n\t\ttry {\n\t\t\tlet options = {\n\t\t\t\ttitle: '数据生成中'\n\t\t\t}\n\n\t\t\tlet params = {\n\t\t\t\tcondition: this.data.condition,\n\t\t\t\tfields: projectSetting.USER_FIELDS\n\t\t\t}\n\n\t\t\tawait cloudHelper.callCloudData('admin/user_data_export', params, options).then(res => {\n\n\t\t\t\tthis._loadDetail(0);\n\t\t\t\tpageHelper.showModal('数据文件生成成功(' + res.total + '条记录), 请点击「直接打开」按钮或者复制文件地址下载');\n\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t\tpageHelper.showNoneToast('导出失败，请重试');\n\t\t}\n\n\t},\n\n\tbindDelTap: async function (e) {\n\t\ttry {\n\t\t\tlet options = {\n\t\t\t\ttitle: '数据删除中'\n\t\t\t}\n\t\t\tawait cloudHelper.callCloudData('admin/user_data_del', {}, options).then(res => {\n\t\t\t\tthis.setData({\n\t\t\t\t\turl: '',\n\t\t\t\t\ttime: ''\n\t\t\t\t});\n\t\t\t\tpageHelper.showSuccToast('删除成功');\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.log(err);\n\t\t\tpageHelper.showNoneToast('删除失败，请重试');\n\t\t}\n\n\t},\n\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/user/export/admin_user_export.json",
    "content": "{\n\t\"usingComponents\": {\n\n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\",  \n\t\"enablePullDownRefresh\": true,  \n\t\"navigationBarTitleText\": \"用户资料导出\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/user/export/admin_user_export.wxml",
    "content": "<view wx:if=\"{{!isLoad}}\" class=\"margin-top load loading text-l text-grey\"></view> \n\n<view class=\"main-admin\" wx:if=\"{{isAdmin&&isLoad}}\">\n\t<view class=\"form-box shadow\">\n\t\t<view class=\"form-group\" style=\"padding:20rpx 15rpx 20rpx;\">\n\t\t\t<view class=\"title-desc\">\n\t\t\t\t※ 数据说明： 针对本次查询结果导出全部数据\n\t\t\t</view>\n\t\t</view>\n\t\t<view class=\"form-group\">\n\t\t\t<view class=\"title\" style=\"font-size:30rpx\">数据下载链接<text wx:if=\"{{time}}\" class=\"text-gray text-s margin-left-s\">({{time}} 生成)</text> </view>\n\t\t\t<button hover-class=\"button-hover\" class=\"btn bg-admin text-white shadow\" bindtap=\"url\" data-type=\"copy\" data-url=\"{{url}}\">复制</button>\n\t\t</view>\n\t\t<view class=\"form-group align-start\" bindtap=\"url\" data-type=\"copy\" data-url=\"{{url}}\">\n\t\t\t<textarea maxlength=\"500\" placeholder=\"数据文件尚未生成，点击下方按钮生成\" placeholder-class=\"phc\" value=\"{{url}}\" style=\"height:50rpx\"></textarea>\n\t\t</view>\n\n\t\t<block wx:if=\"{{url}}\">\n\t\t\t<view class=\"form-group\" style=\"padding:20rpx 15rpx 20rpx;\">\n\t\t\t\t<view class=\"title-desc\">\n\t\t\t\t\t<text user-select=\"true\">※ <text class=\"text-black\">链接使用说明</text>\n\t\t\t\t\t\t1. 复制以上链接地址，建议在电脑浏览器中打开链接下载数据文件\n\t\t\t\t\t\t2. 为保障信息安全，请勿外传数据链接\n\t\t\t\t\t\t3. 为了防止隐私数据泄露，请在下载后及时点击下方按钮删除\n\t\t\t\t\t</text>\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t</block>\n\t</view>\n\n\t<button bindtap=\"bindExportTap\" class=\"btn-admin margin-top\">{{url?'重新生成数据':'生成数据'}} (Excel文件)</button> \n\n\t<button wx:if=\"{{url}}\" bindtap=\"bindOpenTap\" class=\"btn-admin bg-purple light\">直接打开数据文件</button>  \n\n\t<button wx:if=\"{{url}}\" bindtap=\"bindDelTap\" class=\"btn-admin margin-bottom-s bg-red light\">删除数据文件</button>  \n\n\t<view class=\"form-group\" wx:if=\"{{url}}\">\n\t\t<view class=\"title-desc text-red\"><text class=\"icon-info margin-right-xs\"></text>为了防止隐私数据泄露，请在下载上述文件后及时点击按钮删除\n\t\t</view>\n\t</view>\n</view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/user/export/admin_user_export.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n \n.form-box .title-desc {\n\tpadding-bottom: 10rpx;\n\tborder: 0;\n\tfont-size: 29rpx;\n\tcolor: #888;\n}\n\n.btn-admin{\n\tmargin-bottom: 20rpx;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/user/list/admin_user_list.js",
    "content": "const AdminBiz = require('../../../../../../comm/biz/admin_biz.js');\nconst pageHelper = require('../../../../../../helper/page_helper.js');\nconst cacheHelper = require('../../../../../../helper/cache_helper.js');\nconst cloudHelper = require('../../../../../../helper/cloud_helper.js');\nconst projectSetting = require('../../../../public/project_setting.js');\n\nconst CACHE_USER_CHECK_REASON = 'CACHE_USER_CHECK_REASON';\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tuserRegCheck: projectSetting.USER_REG_CHECK,\n\t\tcheckModalShow: false,\n\n\t\tformReason: '',\n\t\tcurIdx: -1,\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\n\t\t//设置搜索菜单\n\t\tawait this._getSearchMenu();\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: async function () { },\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\turl: async function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\n\tbindCommListCmpt: function (e) {\n\t\tpageHelper.commListListener(this, e);\n\t},\n\n\tbindDelTap: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tlet id = pageHelper.dataset(e, 'id');\n\n\t\tlet params = {\n\t\t\tid\n\t\t}\n\n\t\tlet callback = async () => {\n\t\t\ttry {\n\t\t\t\tlet opts = {\n\t\t\t\t\ttitle: '删除中'\n\t\t\t\t}\n\t\t\t\tawait cloudHelper.callCloudSumbit('admin/user_del', params, opts).then(res => {\n\n\t\t\t\t\tpageHelper.delListNode(id, this.data.dataList.list, 'USER_MINI_OPENID');\n\t\t\t\t\tthis.data.dataList.total--;\n\t\t\t\t\tthis.setData({\n\t\t\t\t\t\tdataList: this.data.dataList\n\t\t\t\t\t});\n\t\t\t\t\tpageHelper.showSuccToast('删除成功');\n\t\t\t\t});\n\t\t\t} catch (e) {\n\t\t\t\tconsole.log(e);\n\t\t\t}\n\t\t}\n\t\tpageHelper.showConfirm('确认删除？删除不可恢复', callback);\n\n\t},\n\n\n\tbindClearReasonTap: function (e) {\n\t\tthis.setData({\n\t\t\tformReason: ''\n\t\t})\n\t},\n\n\tbindCheckTap: function (e) {\n\t\tlet curIdx = pageHelper.dataset(e, 'idx');\n\t\tthis.setData({\n\t\t\tformReason: cacheHelper.get(CACHE_USER_CHECK_REASON) || '',\n\t\t\tcurIdx,\n\t\t\tcheckModalShow: true,\n\t\t});\n\t},\n\n\tbindCheckCmpt: async function () {\n\t\tlet e = {\n\t\t\tcurrentTarget: {\n\t\t\t\tdataset: {\n\t\t\t\t\tstatus: 8,\n\t\t\t\t\tidx: this.data.curIdx\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcacheHelper.set(CACHE_USER_CHECK_REASON, this.data.formReason, 86400 * 365);\n\t\tawait this.bindStatusTap(e);\n\t},\n\n\tbindStatusTap: async function (e) {\n\t\tif (!AdminBiz.isAdmin(this)) return;\n\t\tlet status = pageHelper.dataset(e, 'status');\n\n\t\tlet idx = Number(pageHelper.dataset(e, 'idx'));\n\n\t\tlet dataList = this.data.dataList;\n\t\tlet id = dataList.list[idx].USER_MINI_OPENID;\n\n\t\tlet params = {\n\t\t\tid,\n\t\t\tstatus,\n\t\t\treason: this.data.formReason\n\t\t}\n\n\t\tlet cb = async () => {\n\t\t\ttry {\n\t\t\t\tawait cloudHelper.callCloudSumbit('admin/user_status', params).then(res => {\n\t\t\t\t\tlet sortIndex = this.selectComponent('#cmpt-comm-list').getSortIndex();\n \n\t\t\t\t\tif (sortIndex != -1 && sortIndex != 5 && !this.data.search) { // 全部或者检索的结果\n\t\t\t\t\t\tdataList.list.splice(idx, 1);\n\t\t\t\t\t\tdataList.total--;\n\t\t\t\t\t\tthis.setData({\n\t\t\t\t\t\t\tdataList: this.data.dataList\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlet data1Name = 'dataList.list[' + idx + '].USER_CHECK_REASON';\n\t\t\t\t\t\tlet data2Name = 'dataList.list[' + idx + '].USER_STATUS';\n\t\t\t\t\t\tthis.setData({\n\t\t\t\t\t\t\t[data1Name]: this.data.formReason,\n\t\t\t\t\t\t\t[data2Name]: status\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.setData({\n\t\t\t\t\t\tcheckModalShow: false,\n\t\t\t\t\t\tformReason: '',\n\t\t\t\t\t\tcurIdx: -1,\n\t\t\t\t\t});\n\t\t\t\t\tpageHelper.showSuccToast('操作成功');\n\t\t\t\t});\n\t\t\t} catch (e) {\n\t\t\t\tconsole.log(e);\n\t\t\t}\n\t\t}\n\n\t\tif (status == 8) {\n\t\t\tpageHelper.showConfirm('该用户审核不通过，用户修改资料后可重新提交审核', cb)\n\t\t}\n\t\telse\n\t\t\tpageHelper.showConfirm('确认执行此操作?', cb);\n\t},\n\n\t_getSearchMenu: async function () {\n\n\t\tlet sortItems1 = [\n\t\t\t{ label: '全部', type: '', value: '' },\n\t\t\t{ label: '注册时间从早到晚', type: 'sort', value: 'newasc' },\n\t\t\t{ label: '注册时间从晚到早', type: 'sort', value: 'newdesc' },\n\t\t];\n\t\tlet sortMenus = [\n\t\t\t{ label: '全部', type: '', value: '' },\n\t\t\t{ label: '正常', type: 'status', value: 1 },\n\t\t\t{ label: '禁用', type: 'status', value: 9 }\n\n\t\t]\n\n\t\tif (projectSetting.USER_REG_CHECK) {\n\t\t\tsortMenus = sortMenus.concat([\n\t\t\t\t{ label: '待审核', type: 'status', value: 0 },\n\t\t\t\t{ label: '审核未过', type: 'status', value: 8 }\n\t\t\t]);\n\t\t}\n\t\tthis.setData({\n\t\t\tsortItems: [sortItems1],\n\t\t\tsortMenus\n\t\t})\n\n\n\t}\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/user/list/admin_user_list.json",
    "content": "{\n\t\"usingComponents\": {\n\n\t},\n\t\"navigationBarBackgroundColor\": \"#2499f2\",\n\t\"navigationBarTextStyle\": \"white\", \n\t\"disableScroll\": true, \n\t\"navigationBarTitleText\": \"用户管理\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/user/list/admin_user_list.wxml",
    "content": "<block wx:if=\"{{isAdmin}}\">\n\t<cmpt-comm-list id=\"cmpt-comm-list\" source='admin' type=\"admin-meet\" search=\"{{search}}\" _menus=\"{{sortMenus}}\" _items=\"{{sortItems}}\" route=\"admin/user_list\" sortMenusDefaultIndex=\"0\" topBottom=\"50\" placeholder=\"搜索\" bind:list=\"bindCommListCmpt\">\n\n\t\t<view slot=\"searchEnd\">\n\t\t\t<button bindtap=\"url\" data-url=\"../export/admin_user_export?condition={{dataList.condition}}\" class=\"btn mid radius bg-admin text-white margin-right-s\"><text class=\"icon-down margin-right-xxs\"></text>导出用户资料</button>\n\t\t</view>\n\n\t\t<!-- List Begin -->\n\t\t<view class=\"admin-comm-list\">\n\t\t\t<view wx:if=\"{{dataList && dataList.total }}\" class=\"load text-grey\">共有{{dataList.total}}条符合条件记录 </view>\n\n\t\t\t<view class=\"item\" wx:for=\"{{dataList.list}}\" wx:key=\"key\">\n\t\t\t\t<view class=\"no\">{{index+1}}</view>\n\t\t\t\t<view class=\"header\">\n\t\t\t\t\t<view class=\"left text-cut\">{{item.USER_NAME}}\n\t\t\t\t\t</view>\n\t\t\t\t\t<view class=\"right\">\n\t\t\t\t\t\t<text wx:if=\"{{item.USER_STATUS==1}}\" class=\"text-black\">「正常」</text>\n\t\t\t\t\t\t<text wx:elif=\"{{item.USER_STATUS==0}}\" class=\"text-orange\">「待审核」</text>\n\t\t\t\t\t\t<text wx:elif=\"{{item.USER_STATUS==8}}\" class=\"text-red\">「审核未过」</text>\n\t\t\t\t\t\t<text wx:elif=\"{{item.USER_STATUS==9}}\" class=\"text-purple\">「禁用」</text>\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\n\t\t\t\t<view class=\"info\">\n\t\t\t\t\t<view wx:if=\"{{item.USER_STATUS==8}}\" class=\"info-item\">\n\t\t\t\t\t\t<view class=\"title\">审核理由</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view class=\"content\">{{item.USER_CHECK_REASON||'未填写'}}</view>\n\t\t\t\t\t</view>\n\t\t\t\t\t<view class=\"info-item\" bindtap=\"url\" data-type=\"phone\" data-url=\"{{item.USER_MOBILE}}\">\n\t\t\t\t\t\t<view class=\"title\">手机</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view class=\"content\">{{item.USER_MOBILE||'未填写'}} <text wx:if=\"{{item.USER_MOBILE}}\" class=\"icon-phone margin-left-s\"></text></view>\n\t\t\t\t\t</view>\n\n\t\t\t\t\t<view class=\"info-item\">\n\t\t\t\t\t\t<view class=\"title\">注册</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view class=\"content\">{{item.USER_ADD_TIME}}</view>\n\t\t\t\t\t</view>\n\n\t\t\t\t\t<view class=\"info-item\" bindtap=\"url\" data-url=\"../detail/admin_user_detail?id={{item.USER_MINI_OPENID}}\">\n\t\t\t\t\t\t<view class=\"title\">详情</view>\n\t\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t\t<view class=\"content text-blue\">查看更多用户资料...</view>\n\t\t\t\t\t</view>\n\n\t\t\t\t\t<view class=\"oprt\">\n\n\t\t\t\t\t\t<block wx:if=\"{{userRegCheck}}\">\n\t\t\t\t\t\t\t<view wx:if=\"{{item.USER_STATUS==0}}\" bindtap=\"bindStatusTap\" data-status=\"1\" data-idx=\"{{index}}\" class=\"btn  margin-right-s text-green\">审核通过</view>\n\n\t\t\t\t\t\t\t<view wx:if=\"{{item.USER_STATUS==9}}\" bindtap=\"bindStatusTap\" data-status=\"1\" data-idx=\"{{index}}\" class=\"btn  margin-right-s\"><text class=\"icon-check margin-right-xxs text-green\"></text>恢复正常</view>\n\n\t\t\t\t\t\t\t<view wx:if=\"{{item.USER_STATUS==0}}\" bindtap=\"bindCheckTap\" data-status=\"8\" data-idx=\"{{index}}\" class=\"btn  margin-right-s text-red\">审核不过</view>\n\t\t\t\t\t\t</block>\n\n\t\t\t\t\t\t<view wx:if=\"{{item.USER_STATUS!=9}}\" bindtap=\"bindStatusTap\" data-status=\"9\" data-idx=\"{{index}}\" class=\"btn  margin-right-s\"><text class=\"icon-delete margin-right-xxs text-purple\"></text>禁用</view>\n\n\t\t\t\t\t\t<view bindtap=\"bindDelTap\" data-id=\"{{item.USER_MINI_OPENID}}\" class=\"btn  margin-right-s\"><text class=\"icon-delete margin-right-xxs text-orange\"></text>删除</view>\n\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t</view>\n\t\t<!-- List END -->\n\n\t\t<!--load begin-->\n\t\t<import src=\"../../../../../../tpls/public/list_load_tpl.wxml\" />\n\t\t<template is=\"listLoadTpl\" data=\"{{skin:'text-grey',dataList}}\" />\n\t\t<!--load end-->\n\n\n\t</cmpt-comm-list>\n\n\n\t<cmpt-modal wx:if=\"{{checkModalShow}}\" model:show=\"{{checkModalShow}}\" type=\"dialog\" title=\"审核不过\" bind:click=\"bindCheckCmpt\" class=\"modal-form\" cancelText=\"返回\" confirmText=\"确定\">\n\t\t<view class=\"form-group\" style=\"padding:0 10rpx\">\n\t\t\t<view class=\"title\">审核不过理由 <text class=\"text-grey text-mid\">(选填)</text>：</view>\n\t\t\t<view bindtap=\"bindClearReasonTap\" style=\"width:150rpx;text-align: right;\" class=\"text-grey\"><text class=\"icon-roundclose\"></text>清空</view>\n\t\t</view>\n\n\t\t<view class=\"form-group cancel-area\">\n\t\t\t<textarea placeholder-class=\"phc\" placeholder=\"请输入审核不过理由 (非必填)\" style=\"height:110rpx\" model:value=\"{{formReason}}\" maxlength=\"100\"></textarea>\n\t\t</view>\n\t</cmpt-modal>\n\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/admin/user/list/admin_user_list.wxss",
    "content": "@import '../../../../../../style/public/admin.wxss';\n\npage {\n\tbackground-color: #f8f8f8;\n} \n\n.admin-comm-list .item .info .oprt { \n    padding: 0rpx 0rpx;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/album/detail/album_detail.js",
    "content": "const cloudHelper = require('../../../../../helper/cloud_helper.js');\nconst pageHelper = require('../../../../../helper/page_helper.js');\nconst ProjectBiz = require('../../../biz/project_biz.js');\n\nPage({\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false,\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tProjectBiz.initPage(this);\n\n\t\tif (!pageHelper.getOptions(this, options)) return;\n\n\t\tthis._loadDetail();\n\n\t},\n\n\t_loadDetail: async function () {\n\t\tlet id = this.data.id;\n\t\tif (!id) return;\n\n\t\tlet params = {\n\t\t\tid,\n\t\t};\n\t\tlet opt = {\n\t\t\ttitle: 'bar'\n\t\t};\n\t\tlet album = await cloudHelper.callCloudData('album/view', params, opt);\n\t\tif (!album) {\n\t\t\tthis.setData({\n\t\t\t\tisLoad: null\n\t\t\t})\n\t\t\treturn;\n\t\t}\n\n\t\tthis.setData({\n\t\t\tisLoad: true,\n\t\t\talbum,\n\t\t});\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () { },\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\t\tawait this._loadDetail();\n\t\twx.stopPullDownRefresh();\n\t},\n\n\t/**\n\t * 页面上拉触底事件的处理函数\n\t */\n\tonReachBottom: function () { },\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tonPageScroll: function (e) {\n\t\t// 回页首按钮\n\t\tpageHelper.showTopBtn(e, this);\n\n\t},\n\n\tonShareAppMessage: function (res) {\n\t\treturn {\n\t\t\ttitle: this.data.album.ALBUM_TITLE,\n\t\t\timageUrl: this.data.album.ALBUM_OBJ.cover[0]\n\t\t}\n\t}\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/album/detail/album_detail.json",
    "content": "{\n\t\"usingComponents\": { \n\t\t\"cmpt-detail\": \"/cmpts/biz/detail/detail_cmpt\"\n\t},\n\t\"enablePullDownRefresh\": true, \n\t\"navigationBarTitleText\": \"攻略详情\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/album/detail/album_detail.wxml",
    "content": "<view wx:if=\"{{isLoad===null}}\" class=\"margin-top load notexist text-l load-project\"></view>\n<view wx:if=\"{{isLoad===false}}\" class=\"margin-top load loading text-l load-project\"></view>\n\n<block wx:if=\"{{isLoad}}\">\n\t<view class=\"main padding-project\">\n\n\t\t<view class=\"article-box margin-top-xs\">\n\t\t\t<!-- article content begin -->\n\t\t\t<view class=\"article card-project shadow-project\">\n\t\t\t\t<view class=\"title\"><text user-select=\"true\">{{album.ALBUM_TITLE}}</text></view>\n\t\t\t\t<view class=\"time\"> {{album.ALBUM_CATE_NAME}} {{album.ALBUM_ADD_TIME}}</view> \n\n\n\t\t\t\t<block wx:for=\"{{album.ALBUM_OBJ.detail}}\" wx:key=\"key\">\n\t\t\t\t\t<view class=\"content\" wx:if=\"{{item.type=='text'}}\">\n\t\t\t\t\t\t<text user-select=\"{{true}}\">{{item.val}}</text>\n\t\t\t\t\t</view>\n\n\t\t\t\t\t<view class=\"pics\" wx:if=\"{{item.type=='img'}}\">\n\t\t\t\t\t\t<image bindtap=\"url\" data-type='img' data-url=\"{{item.val}}\" show-menu-by-longpress=\"{{true}}\" class=\"loading\" mode='widthFix' lazy-load=\"true\" src=\"{{item.val}}\">\n\t\t\t\t\t\t</image>\n\t\t\t\t\t</view>\n\t\t\t\t</block>\n\t\t\t\t<!-- article content end -->\n\n\n\n\n\t\t\t</view>\n\t\t\t<!-- article content end -->\n\n\t\t</view>\n\t</view>  \n\n\t<cmpt-detail mode=\"mode1\" topBtnShow=\"{{topBtnShow}}\" oid=\"{{album._id}}\" cate=\"{{album.ALBUM_CATE_NAME}}\" title=\"{{album.ALBUM_TITLE}}\" cover=\"{{album.ALBUM_OBJ.cover[0]}}\" qr=\"{{album.ALBUM_QR}}\" desc=\"查看攻略详情\"  bg=\"{{skin.PROJECT_COLOR}}\"></cmpt-detail>\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/album/detail/album_detail.wxss",
    "content": "@import \"../../../../../style/public/detail.wxss\"; \n@import \"../../../style/skin.wxss\"; "
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/album/index/album_index.js",
    "content": "const ProjectBiz = require('../../../biz/project_biz.js');\nconst pageHelper = require('../../../../../helper/page_helper.js');\nconst AlbumBiz = require('../../../biz/album_biz.js');\n\nPage({\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\n\t},\n\n\t/**\n\t\t * 生命周期函数--监听页面加载\n\t\t */\n\tonLoad: async function (options) {\n\t\tProjectBiz.initPage(this); \n\n\t\tthis._getSearchMenu();\n\n\t\tif (options && options.id) {\n\t\t\tthis.setData({\n\t\t\t\t_params: {\n\t\t\t\t\tsortType: 'cateId',\n\t\t\t\t\tsortVal: options.id,\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tthis.setData({\n\n\t\t\t\t_params: {\n\t\t\t\t\tsortType: 'cateId',\n\t\t\t\t\tsortVal: '',\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: async function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\turl: async function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tbindCommListCmpt: function (e) {\n\t\tpageHelper.commListListener(this, e);\n\t},\n\n\n\tonShareAppMessage: function () {\n\n\t},\n\n\t_getSearchMenu: function () {\n\t\tAlbumBiz.setCateTitle();\n\n\t\tlet sortItem1 = [{\n\t\t\tlabel: '全部',\n\t\t\ttype: 'cateId',\n\t\t\tvalue: ''\n\t\t}];\n\n\t\tsortItem1 = sortItem1.concat(AlbumBiz.getCateList());\n\n\t\tlet sortItems = [];\n\t\tlet sortMenus = sortItem1;\n\t\tthis.setData({\n\t\t\tsortItems,\n\t\t\tsortMenus\n\t\t})\n\n\t}\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/album/index/album_index.json",
    "content": "{\n\t\"usingComponents\": { \n\t}, \n\t\"disableScroll\": true,\n\t\"navigationBarTitleText\": \"攻略\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/album/index/album_index.wxml",
    "content": "<view wx:if=\"{{!_params}}\" class=\"margin-top load loading text-l load-project\"></view>\n<block wx:else>\n\t<cmpt-comm-list type=\"album-list\" sortMenusDefaultIndex=\"0\" _params=\"{{_params}}\" search=\"{{search}}\" _menus=\"{{sortMenus}}\" _items=\"{{sortItems}}\" route=\"album/list\" topBottom=\"120\" placeholder=\"搜索\" bind:list=\"bindCommListCmpt\">\n\n\t\t<view class=\"album-list\">\n\t\t\t<view class=\"item\" wx:for=\"{{dataList.list}}\" wx:key=\"key\" bindtap=\"url\" data-url=\"../detail/album_detail?id={{item._id}}\">\n\t\t\t\t<view class=\"item-inner shadow\">\n\t\t\t\t\t<image mode=\"aspectFill\" class=\"loading\" lazy-load=\"{{true}}\" src=\"{{item.ALBUM_OBJ.cover[0]}}\">\n\t\t\t\t\t\t<view wx:if=\"{{item.ALBUM_VIEW_CNT}}\" class=\"attention\"><text class=\"icon-attention margin-right-xxs\"></text>{{item.ALBUM_VIEW_CNT}}</view>\n\t\t\t\t\t</image>\n\t\t\t\t\t<view class=\"detail\">\n\t\t\t\t\t\t<view class=\"title content-cut-one\">\n\t\t\t\t\t\t<text wx:if=\"{{item.ALBUM_CATE_ID==1}}\" class=\"icon-locationfill ticon\"></text>\n\t\t\t\t\t\t<text wx:if=\"{{item.ALBUM_CATE_ID==2}}\" class=\"icon-emoji ticon\"></text>\n\t\t\t\t\t\t<text wx:if=\"{{item.ALBUM_CATE_ID==3}}\" class=\"icon-home ticon\"></text>\n\t\t\t\t\t\t<text wx:if=\"{{item.ALBUM_CATE_ID==4}}\" class=\"icon-goodsnew ticon\"></text>\n\t\t\t\t\t\t<text wx:if=\"{{item.ALBUM_CATE_ID==5}}\" class=\"icon-footprint ticon\"></text>\n\t\t\t\t\t\t{{item.ALBUM_TITLE}}\n\t\t\t\t\t\t</view>\n\t\t\t\t\t\t<view class=\"desc content-cut-two\">{{item.ALBUM_OBJ.desc}}</view>\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\n\t\t\t</view>\n\n\t\t</view>\n\n\t\t<!--load begin-->\n\t\t<import src=\"../../../../../tpls/public/list_load_tpl.wxml\" />\n\t\t<template is=\"listLoadTpl\" data=\"{{skin:'load-project',dataList}}\" />\n\t\t<!--load end-->\n\n\t</cmpt-comm-list>\n\n\n\t<block wx:if=\"{{skin.IS_SUB}}\">\n\t\t<import src=\"../../tpls/menu_tpl.wxml\" />\n\t\t<template is=\"menuTpl\" data=\"{{curMenu:'album_index',returnHome:false}}\" />\n\t</block>\n\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/album/index/album_index.wxss",
    "content": "@import \"../../../style/skin.wxss\";\n\npage {\n\tbackground-color: #fff;\n}\n\n.album-list {\n\tmargin-top: 10rpx;\n\tbackground-color: #fff;\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: center;\n\tflex-wrap: wrap;\n\tpadding: 0 20rpx;\n}\n\n.album-list .item {\n\twidth: 50%;\n\tpadding: 10rpx 15rpx 20rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n}\n\n.album-list .item .item-inner {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n\talign-items: center;\n\tborder-radius: 10rpx;\n}\n\n.album-list .item .item-inner image {\n\twidth: 100%;\n\theight: 420rpx;\n\tborder-top-left-radius: 10rpx;\n\tborder-top-right-radius: 10rpx;\n\tborder: 1rpx solid #ddd;\n\tposition: relative;\n}\n\n.album-list .item .item-inner .attention {\n\tpadding: 10rpx 20rpx;\n\tbackground-color: rgba(0, 0, 0, .4);\n\tposition: absolute;\n\tright: 10rpx;\n\tbottom: 10rpx;\n\tcolor: #fff;\n\tborder-radius: 40rpx;\n}\n\n\n.album-list .item .item-inner .detail {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: flex-start;\n\talign-items: flex-start;\n\tpadding: 0 10rpx 20rpx;\n}\n\n.album-list .item .item-inner .detail .title {\n\twidth: 100%;\n\ttext-align: left;\n\tcolor: #000;\n\tfont-size: 32rpx;\n\tfont-weight: bold;\n\tmargin-top: 20rpx;\n}\n\n.album-list .item .item-inner .detail .title .ticon {\n\tfont-size: 30rpx;\n\tfont-weight: bold;\n\tmargin-right: 0rpx;\n}\n\n.album-list .item .item-inner .detail .desc {\n\twidth: 100%;\n\ttext-align: left;\n\tcolor: #777;\n\tfont-size: 24rpx;\n\tmargin-top: 20rpx;\n\theight:60rpx;\n}\n\n.shadow {\n\tbox-shadow: 6rpx 9rpx 8rpx #eee;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/default/index/default_index.js",
    "content": "const pageHelper = require('../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../helper/cloud_helper.js');\nconst ProjectBiz = require('../../../biz/project_biz.js');\n\nPage({\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\talbum: [\n\t\t\t'/projects/TRIP1/images/home/b1.jpg',\n\t\t\t'/projects/TRIP1/images/home/b3.jpg',\n\t\t\t'/projects/TRIP1/images/home/b4.jpg',\n\t\t\t'/projects/TRIP1/images/home/b5.jpg',\n\t\t]\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tProjectBiz.initPage(this);\n\t},\n\n\t_loadList: async function () {\n\t\tlet opts = {\n\t\t\ttitle: 'bar'\n\t\t}\n\t\tawait cloudHelper.callCloudSumbit('home/list', {}, opts).then(res => {\n\n\t\t\tlet dataList = res.data;\n\n\t\t\tlet hot1List = [];\n\t\t\tlet hot2List = [];\n\t\t\tfor (let k = 0; k < dataList.length; k++) {\n\t\t\t\tlet item = dataList[k];\n\t\t\t\tif (item.type == 'product') hot1List.push(item);\n\t\t\t\telse if (item.type == 'album')\n\t\t\t\t\thot2List.push(item);\n\t\t\t}\n\t\t\tthis.setData({\n\t\t\t\thot1List,\n\t\t\t\thot2List\n\t\t\t})\n\t\t})\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: async function () {\n\t\tthis._loadList();\n\t},\n\n\tonPullDownRefresh: async function () {\n\t\tawait this._loadList();\n\t\twx.stopPullDownRefresh();\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\turl: async function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\n\t/**\n\t * 用户点击右上角分享\n\t */\n\tonShareAppMessage: function () {\n\n\t},\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/default/index/default_index.json",
    "content": "{\n\t\"usingComponents\": { \n\t\t\"cmpt-swiper\": \"/cmpts/public/swiper/swiper_cmpt\"\n\t},  \n\t\"enablePullDownRefresh\": true, \n\t\"navigationStyle\": \"custom\",\n\t\"navigationBarTitleText\": \"首页\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/default/index/default_index.wxml",
    "content": "<view class=\"main\">\n\t<view class=\"swipper\">\n\t\t<cmpt-swiper mode=\"widthFix\" indicatorActiveColor=\"#00C176\" height=\"400\" images=\"{{album}}\" />\n\t</view>\n\n\t<!--menu begin -->\n\t<view class=\"menu\">\n\t\t<view bindtap=\"url\" data-url=\"../../news/index/news_index?id=1\" class=\"item\">\n\t\t\t<view class=\"item-inner\">\n\t\t\t\t<view class=\"img\">\n\t\t\t\t\t<image src=\"../../../images/menu/news_1.png\" />\n\t\t\t\t</view>\n\t\t\t\t<view class=\"title\">景区动态</view>\n\t\t\t</view>\n\t\t</view>\n\t\t<view bindtap=\"url\" data-url=\"../../meet/index/meet_index?id=1\" class=\"item\">\n\t\t\t<view class=\"item-inner\">\n\t\t\t\t<view class=\"img\">\n\t\t\t\t\t<image src=\"../../../images/menu/news_2.png\" />\n\t\t\t\t</view>\n\t\t\t\t<view class=\"title\">景点预约</view>\n\t\t\t</view>\n\t\t</view>\n\t\t<view bindtap=\"url\" data-url=\"../../news/index/news_index?id=2\" class=\"item\">\n\t\t\t<view class=\"item-inner\">\n\t\t\t\t<view class=\"img\">\n\t\t\t\t\t<image src=\"../../../images/menu/news_3.png\" />\n\t\t\t\t</view>\n\t\t\t\t<view class=\"title\">美食</view>\n\t\t\t</view>\n\t\t</view>\n\t\t<view bindtap=\"url\" data-url=\"../../news/index/news_index?id=3\" class=\"item\">\n\t\t\t<view class=\"item-inner\">\n\t\t\t\t<view class=\"img\">\n\t\t\t\t\t<image src=\"../../../images/menu/news_4.png\" />\n\t\t\t\t</view>\n\t\t\t\t<view class=\"title\">特产</view>\n\t\t\t</view>\n\t\t</view>\n\t</view>\n\t<!--menu END -->\n\n\n\t<!--guide begin -->\n\t<view class=\"guide\">\n\t\t<view class=\"title\">游玩指南</view>\n\t\t<view class=\"item\">\n\t\t\t<view class=\"left\" bindtap=\"url\" data-url=\"../../about/index/about_index?key=SETUP_CONTENT_ABOUT\">\n\t\t\t\t<image src=\"../../../images/home/1.jpg\" class=\"loading\" mode=\"aspectFill\" lazy-load=\"{{true}}\" />\n\t\t\t\t<view class=\"line1\">景区概况</view>\n\t\t\t\t<view class=\"line2\">服务游客 助力旅游 </view>\n\t\t\t</view>\n\t\t\t<view class=\"right\">\n\t\t\t\t<view class=\"line\" bindtap=\"url\" data-url=\"../../album/index/album_index\" data-type=\"relaunch\">\n\t\t\t\t\t<image src=\"../../../images/home/2.jpg\" class=\"loading\" mode=\"aspectFill\" lazy-load=\"{{true}}\" />\n\t\t\t\t\t<view class=\"txt1\">官方攻略</view>\n\t\t\t\t\t<view class=\"txt2\">最具代表性的玩法</view>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"line\" bindtap=\"url\" data-url=\"../../meet/index/meet_index?id=2\">\n\t\t\t\t\t<view class=\"txt1\">停车预约</view>\n\t\t\t\t\t<view class=\"txt2\">景区停车更便捷</view>\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t</view>\n\t</view>\n\t<!--guide END -->\n\n\t<!--hot begin -->\n\t<view class=\"hot\">\n\t\t<view class=\"title\">旅游人气榜</view>\n\t\t<view class=\"item\">\n\t\t\t<view class=\"left bg1\">\n\t\t\t\t<view class=\"line1\">景点</view>\n\t\t\t\t<view class=\"line2\">人气榜</view>\n\t\t\t</view>\n\t\t\t<view class=\"right\">\n\t\t\t\t<view wx:for=\"{{hot1List}}\" wx:key=\"key\" bindtap=\"url\" data-url=\"../../{{item.type}}/detail/{{item.type}}_detail?id={{item.id}}\" class=\"line text-cut\"><text class=\"no\">{{index+1}}</text> {{item.title}}</view>\n\t\t\t</view>\n\t\t</view>\n\n\t\t<view class=\"item margin-top-s\">\n\t\t\t<view class=\"left bg2\">\n\t\t\t\t<view class=\"line1\">攻略</view>\n\t\t\t\t<view class=\"line2\">人气榜</view>\n\t\t\t</view>\n\t\t\t<view class=\"right\">\n\t\t\t\t<view wx:for=\"{{hot2List}}\" wx:key=\"key\" bindtap=\"url\" data-url=\"../../{{item.type}}/detail/{{item.type}}_detail?id={{item.id}}\" class=\"line text-cut\"><text class=\"no\">{{index+1}}</text> {{item.title}}</view>\n\t\t\t</view>\n\t\t</view>\n\t</view>\n\t<!--hot END -->\n</view>\n\n<block wx:if=\"{{skin.IS_SUB}}\">\n\t<import src=\"../../tpls/menu_tpl.wxml\" />\n\t<template is=\"menuTpl\" data=\"{{curMenu:'default_index',returnHome:false}}\" />\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/default/index/default_index.wxss",
    "content": "@import \"../../../style/skin.wxss\";\n\n.main {\n\tpadding: 0rpx 0rpx 100rpx;\n}\n\n.swipper {\n\twidth: 100%;\n\tbackground-color: #4f5368;\n}\n\n.swipper image {\n\theight: inherit;\n\twidth: inherit;\n}\n\n.menu {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tbackground-color: #fff;\n\tpadding: 20rpx 10rpx;\n\tmargin-top: -40rpx;\n\tz-index: 99999;\n\tborder-top-left-radius: 40rpx;\n\tborder-top-right-radius: 40rpx;\n}\n\n.menu .item {\n\twidth: 25%;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\theight: 180rpx;\n\n}\n\n.menu .item .item-inner {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: center;\n\n}\n\n.menu .item-inner .img {\n\twidth: 105rpx;\n\theight: 105rpx;\n\tdisplay: flex;\n\tbackground-color: #ccc;\n\tjustify-content: center;\n\talign-items: center;\n\tborder-radius: 50%;\n}\n\n.menu .item:nth-child(1) .item-inner .img {\n\tbackground-image: linear-gradient(45deg, #10CB61, #7EE263);\n}\n\n.menu .item:nth-child(2) .item-inner .img {\n\tbackground-image: linear-gradient(#68ebe4, #1cbbb4);\n}\n\n.menu .item:nth-child(3) .item-inner .img {\n\tbackground-image: linear-gradient(45deg, #FE753B, #F8BF1B);\n}\n\n.menu .item:nth-child(4) .item-inner .img {\n\tbackground-image: linear-gradient(#f5bedd, #e03997);\n}\n\n.menu .item-inner .img image {\n\twidth: 59rpx;\n\theight: 59rpx;\n}\n\n.menu .item-inner .title {\n\tmargin-top: 20rpx;\n\tfont-size: 26rpx;\n\tcolor: #4f5368;\n}\n\n.guide {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tpadding: 0rpx 20rpx 20rpx;\n\tbackground-color: #fff;\n\tmargin-top: 20rpx;\n}\n\n.guide .title {\n\twidth: 100%;\n\tfont-size: 32rpx;\n\tfont-weight: bold;\n\tpadding: 30rpx 0rpx;\n\tletter-spacing: 3rpx;\n}\n\n.guide .item {\n\twidth: 100%;\n\tdisplay: flex;\n\tcolor: #fff;\n}\n\n.guide .item .left {\n\twidth: 350rpx;\n\tbackground-image: linear-gradient(#6dab3f, #7BC541);\n\theight: 350rpx;\n\tborder-radius: 20rpx;\n\tpadding: 30rpx 20rpx;\n\tmargin-right: 20rpx;\n\tposition: relative;\n}\n\n.guide .item .left image {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\twidth: inherit;\n\theight: inherit;\n\tborder-radius: inherit;\n\tz-index: 1;\n}\n\n.guide .item .left .line1 {\n\tfont-size: 38rpx;\n\tmargin-bottom: 20rpx;\n\tz-index: 9;\n\tposition: relative;\n}\n\n.guide .item .left .line2 {\n\tfont-size: 28rpx;\n\tz-index: 9;\n\tposition: relative;\n}\n\n.guide .item .right {\n\tflex: 1;\n\tdisplay: flex;\n\tflex-direction: column;\n}\n\n.guide .item .right .line {\n\twidth: 100%;\n\tbackground-image: linear-gradient(45deg, #276eb0, #2B97FF);\n\tborder-radius: 20rpx;\n\tpadding: 20rpx 20rpx;\n\theight: 165rpx;\n\tposition: relative;\n}\n\n.guide .item .right image {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\twidth: inherit;\n\theight: inherit;\n\tborder-radius: inherit;\n\tz-index: 1;\n}\n\n.guide .item .right .line:first-child {\n\tmargin-bottom: 20rpx;\n}\n\n.guide .item .right .line:last-child {\n\tbackground-image: linear-gradient(-45deg, #c7771b, #F18E1B);\n}\n\n.guide .item .right .line .txt1 {\n\tfont-size: 32rpx;\n\tmargin-bottom: 10rpx;\n\tz-index: 9;\n\tposition: relative;\n}\n\n.guide .item .right .line .txt2 {\n\tfont-size: 28rpx;\n\tz-index: 9;\n\tposition: relative;\n}\n\n\n.hot {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tpadding: 0rpx 20rpx 20rpx;\n\tbackground-color: #fff;\n\tmargin-top: 20rpx;\n}\n\n.hot .title {\n\twidth: 100%;\n\tfont-size: 32rpx;\n\tfont-weight: bold;\n\tpadding: 30rpx 0rpx;\n\tletter-spacing: 3rpx;\n}\n\n.hot .item {\n\twidth: 100%;\n\tdisplay: flex;\n\talign-items: flex-start;\n}\n\n.hot .item .left {\n\twidth: 150rpx;\n\tdisplay: flex;\n\tbackground-color: #6dab3f;\n\theight: 150rpx;\n\tborder-radius: 20rpx;\n\tmargin-right: 30rpx;\n\talign-items: center;\n\tjustify-content: center;\n\tflex-direction: column;\n\tcolor: #fff;\n\tposition: relative;\n}\n\n.hot .item .left.bg1 {\n\tbackground-image: linear-gradient(45deg, #276eb0, #2B97FF);\n}\n\n.hot .item .left.bg2 {\n\tbackground-image: linear-gradient(#f5bedd, #e03997);\n}\n\n.hot .item .left image {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\twidth: inherit;\n\theight: inherit;\n\tborder-radius: inherit;\n\topacity: .8;\n}\n\n.hot .item .left .line1 {\n\tfont-size: 32rpx;\n\tz-index: 9;\n}\n\n.hot .item .left .line2 {\n\tfont-size: 28rpx;\n\tmargin-top: 10rpx;\n\tz-index: 9;\n}\n\n.hot .item .right {\n\tdisplay: flex;\n\tflex: 1;\n\tflex-direction: column;\n\tfont-size: 30rpx;\n\tcolor: #000;\n\tjustify-content: flex-start;\n\talign-items: flex-start;\n}\n\n.hot .item .right .line {\n\twidth: 500rpx;\n\tpadding: 0rpx 0 14rpx; \n\theight: 56rpx;\n}\n\n.hot .item .right .line .no {\n\tmargin-right: 10rpx;\n\tfont-weight: bold;\n}\n\n.hot .item .right .line:nth-child(1) .no {\n\tcolor: #FEB361;\n}\n\n.hot .item .right .line:nth-child(2) .no {\n\tcolor: #5DDE49;\n}\n\n.hot .item .right .line:nth-child(3) .no {\n\tcolor: #70C6FE;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/calendar/meet_calendar.js",
    "content": "const cloudHelper = require('../../../../../helper/cloud_helper.js');\nconst pageHelper = require('../../../../../helper/page_helper.js');\nconst timeHelper = require('../../../../../helper/time_helper.js'); \nconst ProjectBiz = require('../../../biz/project_biz.js');\n\nPage({\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false,\n\t\tlist: [],\n\n\t\tday: '',\n\t\thasDays: []\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tProjectBiz.initPage(this);\n\t},\n\n\t_loadList: async function () {\n\t\tlet params = {\n\t\t\tday: this.data.day\n\t\t}\n\t\tlet opts = {\n\t\t\ttitle: this.data.isLoad ? 'bar' : 'bar'\n\t\t}\n\t\ttry {\n\t\t\tthis.setData({\n\t\t\t\tlist: null\n\t\t\t});\n\t\t\tawait cloudHelper.callCloudSumbit('meet/list_by_day', params, opts).then(res => {\n\t\t\t\tthis.setData({\n\t\t\t\t\tlist: res.data,\n\t\t\t\t\tisLoad: true\n\t\t\t\t});\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.error(err);\n\t\t}\n\t},\n\n\t_loadHasList: async function () {\n\t\tlet params = {\n\t\t\tday: timeHelper.time('Y-M-D')\n\t\t}\n\t\tlet opts = {\n\t\t\ttitle: 'bar'\n\t\t}\n\t\ttry {\n\t\t\tawait cloudHelper.callCloudSumbit('meet/list_has_day', params, opts).then(res => {\n\t\t\t\tthis.setData({\n\t\t\t\t\thasDays: res.data,\n\t\t\t\t});\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.error(err);\n\t\t}\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: async function () {\n\t\tthis.setData({\n\t\t\tday: timeHelper.time('Y-M-D')\n\t\t}, async () => {\n\t\t\tawait this._loadHasList();\n\t\t\tawait this._loadList();\n\t\t});\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\t\tawait this._loadHasList();\n\t\tawait this._loadList();\n\t\twx.stopPullDownRefresh();\n\t},\n\n\t/**\n\t * 用户点击右上角分享\n\t */\n\tonShareAppMessage: function () {\n\n\t},\n\n\tbindClickCmpt: async function (e) {\n\t\tlet day = e.detail.day;\n\t\tthis.setData({\n\t\t\tday\n\t\t}, async () => {\n\t\t\tawait this._loadList();\n\t\t})\n\n\t},\n\n\tbindMonthChangeCmpt: function (e) { \n\t},\n\n\turl: async function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/calendar/meet_calendar.json",
    "content": "{\n\t\"usingComponents\": {\n\t\t\"cmpt-calendar\": \"/cmpts/public/calendar/calendar_comm/calendar_comm_cmpt\"\n\t},\n\t\"enablePullDownRefresh\": true,\n\t\"navigationBarTitleText\": \"预约日历\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/calendar/meet_calendar.wxml",
    "content": "<view wx:if=\"{{isLoad===null}}\" class=\"margin-top load notexist text-l load-project\"></view>\n<view wx:if=\"{{isLoad===false}}\" class=\"margin-top load loading text-l load-project\"></view>\n\n<view class=\"main {{skin.IS_SUB?'sub-margin-bottom':''}}\" wx:if=\"{{isLoad}}\">\n\t<view class=\"plan-date\">\n\t\t<cmpt-calendar mode=\"one\" hasDays=\"{{hasDays}}\" bind:click=\"bindClickCmpt\" bind:monthChange=\"bindMonthChangeCmpt\" />\n\t</view>\n\n\t<view class=\"list padding-project\">\n\t\t<view wx:if=\"{{list===null}}\" class=\"load loading text-l text-grey\"></view>\n\t\t<text wx:elif=\"{{list.length==0}}\" class=\"no-project icon-emoji text-l text-grey\"> 本日没有可预约的项目哦~</text>\n\t\t<view class=\"item card-project shadow-project\" wx:for=\"{{list}}\" wx:key=\"key\" bindtap=\"url\" data-url=\"../detail/meet_detail?id={{item._id}}\">\n\t\t\t<view wx:if=\"{{index%4==0}}\" class=\"left bg-blue bg-project\"></view>\n\t\t\t<view wx:elif=\"{{index%4==1}}\" class=\"left bg-green\"></view>\n\t\t\t<view wx:elif=\"{{index%4==2}}\" class=\"left bg-orange\"></view>\n\t\t\t<view wx:else class=\"left bg-cyan\"></view>\n\t\t\t<block wx:if=\"{{item.pic}}\">\n\t\t\t\t<image class=\"img loading\" src=\"{{item.pic}}\" lazy-load=\"{{true}}\" mode=\"aspectFill\" />\n\t\t\t</block>\n\t\t\t<view class=\"title text-cut\">{{item.title}}</view>\n\t\t\t<view class=\"time\"><text class=\"icon-time margin-right-xxs\"></text>{{item.timeDesc}}</view>\n\t\t</view>\n\n\t</view>\n</view>\n \n<view style=\"height: 150rpx;\"></view>\n\n<block wx:if=\"{{skin.IS_SUB}}\">\n\t<import src=\"../../tpls/menu_tpl.wxml\" />\n\t<template is=\"menuTpl\" data=\"{{curMenu:'meet_calendar',returnHome:false}}\" />\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/calendar/meet_calendar.wxss",
    "content": "@import \"../../../style/skin.wxss\";  \n \n\n.main {\n\tpadding: 0 0 20rpx;\n}\n\n.main .plan-date {\n\twidth: 100%;\n\tposition: sticky;\n\ttop: 0;\n\tz-index: 999;\n\tbox-shadow: var(--ShadowSize) var(--greyShadow);\n}\n\n.main .list {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: flex-start;\n\talign-items: center;\n\tpadding: 30rpx 20rpx;\n}\n\n.main .list .item {\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: space-between;\n\talign-items: center;\n\theight: 100rpx;\n\tpadding: 0 30rpx 0 0;\n\tbackground-color: #fff;\n\tmargin-bottom: 30rpx;\n\tborder-radius: 10rpx;\n\toverflow: hidden;\n}\n\n.main .list .item .left {\n\twidth: 8rpx;\n\theight: 100rpx;\n\tmargin-right: 15rpx;\n\n}\n\n.main .list .item .img {\n\twidth: 65rpx;\n\theight: 65rpx;\n\tborder-radius: 10rpx;\n\tposition: relative; \n}\n\n.main .list .item .title {\n\tflex: 1;\n\ttext-align: left;\n\tfont-size: 28rpx;\n\tfont-weight: bold;\n\tcolor: #333;\n\tmargin-left: 20rpx;\n}\n\n.main .list .item .time {\n\twidth: 140rpx;\n\ttext-align: right;\n\tfont-size: 26rpx;\n\tcolor: #999;\n}\n\n.main .list .no-project {\n\tpadding: 30rpx 30rpx;\n\tfont-size: 28rpx;\n}\n\n "
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/detail/meet_detail.js",
    "content": "const cloudHelper = require('../../../../../helper/cloud_helper.js');\nconst pageHelper = require('../../../../../helper/page_helper.js');\nconst MeetBiz = require('../../../biz/meet_biz.js');\nconst projectSetting = require('../../../public/project_setting.js');\nconst ProjectBiz = require('../../../biz/project_biz.js'); \nconst PassportBiz = require('../../../../../comm/biz/passport_biz.js');\n\nPage({\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false,\n\n\n\t\ttabCur: 0,\n\t\tmainCur: 0,\n\t\tverticalNavTop: 0,\n\n\t\tshowMind: true,\n\t\tshowTime: false,\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: function (options) {\n\t\tProjectBiz.initPage(this); \n\n\t\tif (!pageHelper.getOptions(this, options)) return;\n\n\t\tthis._loadDetail();\n\t},\n\n\t_loadDetail: async function () {\n\t\tlet id = this.data.id;\n\t\tif (!id) return;\n\n\t\tlet params = {\n\t\t\tid,\n\t\t};\n\t\tlet opt = {\n\t\t\ttitle: 'bar'\n\t\t};\n\t\tlet meet = await cloudHelper.callCloudData('meet/view', params, opt);\n\t\tif (!meet) {\n\t\t\tthis.setData({\n\t\t\t\tisLoad: null\n\t\t\t})\n\t\t\treturn;\n\t\t}\n\n\n\t\tthis.setData({\n\t\t\tisLoad: true,\n\t\t\tmeet,\n\t\t\tcanNullTime: projectSetting.MEET_CAN_NULL_TIME\n\t\t}); \n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\t\tawait this._loadDetail();\n\t\twx.stopPullDownRefresh();\n\t},\n\n\t/**\n\t * 页面上拉触底事件的处理函数\n\t */\n\tonReachBottom: function () {\n\n\t},\n\n\t/**\n\t * 用户点击右上角分享\n\t */\n\tonShareAppMessage: function () {\n\n\t},\n\n\tbindJoinTap: async function (e) {\n\t\tif (!await PassportBiz.loginMustCancelWin(this)) return;\n\n\t\tlet dayIdx = pageHelper.dataset(e, 'dayidx');\n\t\tlet timeIdx = pageHelper.dataset(e, 'timeidx');\n\n\t\tlet time = this.data.meet.MEET_DAYS_SET[dayIdx].times[timeIdx];\n\n\n\t\tif (time.error) {\n\t\t\tif (time.error.includes('预约'))\n\t\t\t\treturn pageHelper.showModal('该时段' + time.error + '，换一个时段试试吧！');\n\t\t\telse\n\t\t\t\treturn pageHelper.showModal('该时段预约' + time.error + '，换一个时段试试吧！');\n\t\t}\n\n\t\tlet meetId = this.data.id;\n\t\tlet timeMark = time.mark;\n\n\t\tlet callback = async () => {\n\t\t\ttry {\n\t\t\t\tlet opts = {\n\t\t\t\t\ttitle: '请稍候',\n\t\t\t\t}\n\t\t\t\tlet params = {\n\t\t\t\t\tmeetId,\n\t\t\t\t\ttimeMark\n\t\t\t\t}\n\t\t\t\tawait cloudHelper.callCloudSumbit('meet/before_join', params, opts).then(res => {\n\t\t\t\t\twx.navigateTo({\n\t\t\t\t\t\turl: `../join/meet_join?id=${meetId}&timeMark=${timeMark}`,\n\t\t\t\t\t})\n\t\t\t\t});\n\t\t\t} catch (ex) {\n\t\t\t\tconsole.log(ex);\n\t\t\t}\n\t\t}\n\t\tMeetBiz.subscribeMessageMeet(callback);\n\n\t},\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tonPageScroll: function (e) { \n\t\tif (e.scrollTop > 100) {\n\t\t\tthis.setData({\n\t\t\t\ttopShow: true\n\t\t\t});\n\t\t} else {\n\t\t\tthis.setData({\n\t\t\t\ttopShow: false\n\t\t\t});\n\t\t}\n\t},\n\n\tbindTopTap: function () {\n\t\twx.pageScrollTo({\n\t\t\tscrollTop: 0\n\t\t})\n\t},\n\n\tbindVerticalMainScroll: function (e) {\n\t\tif (!this.data.isLoad) return;\n\n\t\tlet list = this.data.meet.MEET_DAYS_SET;\n\t\tlet tabHeight = 0;\n\n\t\tfor (let i = 0; i < list.length; i++) {\n\t\t\tlet view = wx.createSelectorQuery().in(this).select(\"#main-\" + i);\n\t\t\tview.fields({\n\t\t\t\tsize: true\n\t\t\t}, data => {\n\t\t\t\tlist[i].top = tabHeight;\n\t\t\t\ttabHeight = tabHeight + data.height;\n\t\t\t\tlist[i].bottom = tabHeight;\n\t\t\t}).exec();\n\t\t}\n\n\t\tlet scrollTop = e.detail.scrollTop + 20; // + i*0.5; //TODO\n\t\tfor (let i = 0; i < list.length; i++) {\n\n\t\t\tif (scrollTop > list[i].top && scrollTop < list[i].bottom) {\n\n\t\t\t\tthis.setData({\n\t\t\t\t\tverticalNavTop: (i - 1) * 50,\n\t\t\t\t\ttabCur: i\n\t\t\t\t})\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t},\n\n\tbindTabSelectTap: function (e) {\n\t\tlet idx = pageHelper.dataset(e, 'idx');\n\t\tthis.setData({\n\t\t\ttabCur: idx,\n\t\t\tmainCur: idx,\n\t\t\tverticalNavTop: (idx - 1) * 50\n\t\t})\n\t},\n\n\tbindShowMindTap: function (e) {\n\t\tthis.setData({\n\t\t\tshowMind: true,\n\t\t\tshowTime: false\n\t\t});\n\t},\n\n\tbindShowTimeTap: function (e) {\n\t\tthis.setData({\n\t\t\tshowMind: false,\n\t\t\tshowTime: true\n\t\t});\n\t}\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/detail/meet_detail.json",
    "content": "{\n\t\"usingComponents\": {  \n\t\t\"cmpt-detail\": \"/cmpts/biz/detail/detail_cmpt\"\n\t},\n\t\"enablePullDownRefresh\": true, \n\t\"navigationBarTitleText\": \"预约详情\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/detail/meet_detail.wxml",
    "content": "<view wx:if=\"{{isLoad===null}}\" class=\"margin-top load notexist text-l load-project\"></view>\n<view wx:if=\"{{isLoad===false}}\" class=\"margin-top load loading text-l load-project\"></view>\n<block wx:if=\"{{isLoad}}\">\n\t<view class=\"main\">\n\n\t\t<view class=\"top-area\">\n\t\t\t<view class=\"top-title text-cut\">{{meet.MEET_TITLE}}</view>\n\t\t\t<view class=\"top-menu\">\n\t\t\t\t<view bindtap=\"bindShowMindTap\" class=\"item {{showMind?'cur text-project':''}}\"><text class=\"icon-friend margin-right-xxs\"></text>预约须知</view>\n\t\t\t\t<view bindtap=\"bindShowTimeTap\" class=\"item {{showTime?'cur text-project':''}}\"><text class=\"icon-remind margin-right-xxs\"></text>可预约时段</view>\n\t\t\t</view>\n\t\t</view>\n\n\t\t<view class=\"big-box\">\n\t\t\t<block wx:if=\"{{showMind}}\">\n\t\t\t\t<view class=\"article-box padding-project\">\n\n\t\t\t\t\t<view class=\"article card-project shadow-project margin-top\" wx:if=\"{{meet.MEET_CONTENT && meet.MEET_CONTENT.length>0}}\">\n\t\t\t\t\t\t<block wx:for=\"{{meet.MEET_CONTENT}}\" wx:key=\"key\">\n\t\t\t\t\t\t\t<view class=\"content\" wx:if=\"{{item.type=='text'}}\">\n\t\t\t\t\t\t\t\t<text user-select=\"{{true}}\">{{item.val}}</text>\n\t\t\t\t\t\t\t</view>\n\n\t\t\t\t\t\t\t<view class=\"pics\" wx:if=\"{{item.type=='img'}}\">\n\t\t\t\t\t\t\t\t<image bindtap=\"url\" data-type='img' data-url=\"{{item.val}}\" show-menu-by-longpress=\"{{true}}\" class=\"loading\" mode='widthFix' lazy-load=\"true\" src=\"{{item.val}}\">\n\t\t\t\t\t\t\t\t</image>\n\t\t\t\t\t\t\t</view>\n\t\t\t\t\t\t</block>\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\t\t\t</block>\n\n\t\t\t<block wx:if=\"{{showTime}}\">\n\t\t\t\t<view wx:if=\"{{!meet.MEET_DAYS_SET || meet.MEET_DAYS_SET.length == 0}}\" class=\"meet-no-time text-grey\">\n\t\t\t\t\t<text class=\"icon-emoji\"></text>\n\t\t\t\t\t<view>暂无可预约时段，请选择其他</view>\n\t\t\t\t</view>\n\n\t\t\t\t<view wx:if=\"{{meet.MEET_DAYS_SET && meet.MEET_DAYS_SET.length > 0}}\" class=\"vertical-box\">\n\t\t\t\t\t<!-- left begin -->\n\t\t\t\t\t<scroll-view class=\"vertical-nav nav\" scroll-y scroll-with-animation scroll-top=\"{{verticalNavTop}}\" style=\"height:calc(100vh - 193rpx);\">\n\t\t\t\t\t\t<view class=\"item text-cut  {{index==tabCur?'cur text-project':''}}\" wx:for=\"{{meet.MEET_DAYS_SET}}\" wx:key=\"key\" bindtap='bindTabSelectTap' data-idx=\"{{index}}\" wx:if=\"{{item.times.length>0||canNullTime}}\">\n\t\t\t\t\t\t\t{{item.day}}\n\t\t\t\t\t\t</view>\n\t\t\t\t\t</scroll-view>\n\t\t\t\t\t<!-- left END -->\n\n\t\t\t\t\t<!-- right begin -->\n\t\t\t\t\t<scroll-view class=\"vertical-main\" scroll-y scroll-with-animation style=\"height:calc(100vh - 193rpx)\" scroll-into-view=\"main-{{mainCur}}\" bindscroll=\"bindVerticalMainScroll\">\n\n\n\t\t\t\t\t\t<view class=\"vertical-main-box\" wx:for=\"{{meet.MEET_DAYS_SET}}\" wx:if=\"{{item.times.length>0||canNullTime}}\" wx:key=\"key\" id=\"main-{{index}}\">\n\n\t\t\t\t\t\t\t<view class=\"bar solid-bottom bg-white righ-tab-bar\">\n\t\t\t\t\t\t\t\t<view class=\"action right-tab-tilte text-black\">\n\t\t\t\t\t\t\t\t\t{{item.dayDesc}}\n\t\t\t\t\t\t\t\t</view>\n\t\t\t\t\t\t\t</view>\n\n\t\t\t\t\t\t\t<!-- 时段列表 begin -->\n\t\t\t\t\t\t\t<view class=\"text-list\">\n\t\t\t\t\t\t\t\t<view class=\"item text-grey\" wx:if=\"{{item.times.length==0&&canNullTime}}\">暂无可预约时段</view>\n\n\t\t\t\t\t\t\t\t<view class=\"item\" bindtap=\"bindJoinTap\" data-dayidx=\"{{index}}\" data-timeidx=\"{{idx}}\" wx:for=\"{{item.times}}\" wx:key=\"key\" wx:for-item=\"itm\" wx:for-index=\"idx\">\n\t\t\t\t\t\t\t\t\t<view class=\"time-text limit {{itm.error?'error':''}}\">\n\t\t\t\t\t\t\t\t\t\t<text>{{itm.start}}～{{itm.end}}</text>\n\t\t\t\t\t\t\t\t\t\t<block wx:if=\"{{!itm.error}}\">\n\t\t\t\t\t\t\t\t\t\t\t<text wx:if=\"{{meet.MEET_IS_SHOW_LIMIT==1&&itm.isLimit}}\" class=\"limit-text\">({{itm.stat.succCnt}}<text style=\"margin:0 5rpx\">/</text>{{itm.limit}})</text>\n\t\t\t\t\t\t\t\t\t\t\t<text wx:if=\"{{meet.MEET_IS_SHOW_LIMIT==1&&!itm.isLimit}}\" class='limit-text'>(人数不限)</text>\n\t\t\t\t\t\t\t\t\t\t\t<text wx:if=\"{{meet.MEET_IS_SHOW_LIMIT==0}}\" class='limit-text'>(可预约)</text>\n\t\t\t\t\t\t\t\t\t\t</block>\n\t\t\t\t\t\t\t\t\t\t<block wx:else><text class=\"limit-text\">({{itm.error}})</text></block>\n\t\t\t\t\t\t\t\t\t</view>\n\n\t\t\t\t\t\t\t\t</view>\n\t\t\t\t\t\t\t</view>\n\t\t\t\t\t\t\t<!-- 时段列表 END -->\n\n\t\t\t\t\t\t</view>\n\n\t\t\t\t\t</scroll-view>\n\t\t\t\t\t<!-- right END -->\n\t\t\t\t</view>\n\t\t\t</block>\n\t\t</view>\n\n\t</view>\n</block>\n<!-- top begin -->\n<button wx:if=\"{{topShow}}\" class=\"btn-fixed bg-gray text-gray btn-top\" bindtap=\"bindTopTap\" style=\"bottom:60rpx\"><text class=\"icon-top\"></text></button>\n<!-- top END. -->"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/detail/meet_detail.wxss",
    "content": "@import \"../../../../../style/public/comm_box_list.wxss\";\n@import \"../../../style/skin.wxss\";  \n\n\n.main {\n\tpadding: 0rpx 0rpx !important;\n}\n\n.meet-no-time {\n\twidth: 100%;\n\tbackground-color: #fff;\n\tpadding: 30rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: center;\n\tfont-size: 30rpx;\n}\n\n.meet-no-time {\n\twidth: 100%;\n\theight: 100vh;\n\tbackground-color: #fff;\n\tpadding: 80rpx 30rpx 30rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: flex-start;\n\tfont-size: 30rpx;\n}\n\n.meet-no-time text {\n\tfont-size: 90rpx;\n}\n\n/* 顶部区域 */\n.top-area {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n\talign-items: flex-start;\n\tbackground-color: #fff;\n\tborder-bottom: 2rpx solid #ccc;\n\tposition: fixed;\n\ttop: 0;\n\tz-index: 999;\n}\n\n.top-area .top-title {\n\twidth: 100%;\n\tfont-size: 38rpx;\n\tcolor: #000;\n\tline-height: 110rpx;\n\tpadding: 0 20rpx;\n\tfont-weight: bold;\n}\n\n.top-area .top-menu {\n\twidth: 100%;\n\tfont-size: 28rpx;\n\tcolor: #000;\n\tline-height: 80rpx;\n\tpadding: 0;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tfont-weight: bold;\n\tbackground-color: #f8f8f8;\n}\n\n.top-area .top-menu .item {\n\tpadding: 0 20rpx;\n\tposition: relative;\n} \n\n.top-area .top-menu .item.cur::after {\n\tposition: absolute;\n\tbottom: 0;\n\tleft: 76rpx;\n\twidth: 60rpx;\n\ttext-align: center;\n\theight: 5rpx;\n\tbackground-color: var(--projectColor);\n\tcontent: \" \";\n\tanimation: hightlightning_in 0.3s ease-out;\n\ttransform-origin: left;\n}\n\n@keyframes hightlightning_in {\n\tfrom {\n\t\ttransform: scaleX(0);\n\t}\n\n\tto {\n\t\ttransform: scaleX(1);\n\t}\n}\n\n.big-box {\n\twidth: 100%;\n\tpadding: 0;\n\tmargin-top: 193rpx;\n\tdisplay: flex; \n}\n\n/*** 详情盒子 ***/\n.article-box {\n\tbox-sizing: border-box;\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tpadding: 30rpx 20rpx;\n}\n\n.article-box .article {\n\tbackground-color: #fff;\n\tpadding: 10rpx 30rpx;\n\tborder-radius: 20rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n\tposition: relative;\n}\n\n.article-box .article .info {\n\tcolor: #333;\n\tmargin: 0rpx 0rpx;\n\tbox-sizing: border-box;\n\twidth: 100%;\n\tline-height: 1.6;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: flex-start;\n\tpadding: 10rpx 0rpx 10rpx;\n}\n\n.article-box .article .info .info-left {\n\twidth: 50rpx;\n\theight: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: flex-start;\n\talign-items: center;\n}\n\n.article-box .article .info .info-right {\n\theight: 100%;\n\tflex: 1;\n\tfont-size: 26rpx;\n}\n\n.article-box .article .info .info-end {\n\theight: 100%;\n\twidth: 40rpx;\n\tfont-size: 26rpx;\n\tcolor: #ccc;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: center;\n}\n\n\n.article-box .article .content {\n\tmargin-top: 24rpx;\n\tcolor: #333;\n\tfont-size: 28rpx;\n\ttext-align: justify;\n\tline-height: 1.6;\n}\n\n.article-box .article .pics {\n\tmargin-top: 30rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n\talign-items: center;\n}\n\n.article-box .article .pics image {\n\twidth:100%; \n\tborder-radius: 10rpx;\n\tmargin-bottom: 20rpx;\n}\n\n\n\n\n/* 垂直导航 */\n.nav {\n\twhite-space: nowrap;\n}\n\n::-webkit-scrollbar {\n\tdisplay: none;\n}\n\n.nav .item {\n\tdisplay: inline-block;\n\tmargin: 0 10rpx;\n\tpadding: 0 20rpx;\n}\n\n.nav .item.cur {\n\tborder-bottom: 4rpx solid;\n}\n\n.vertical-nav.nav {\n\twidth: 200rpx;\n\twhite-space: initial;\n}\n\n.vertical-nav.nav .item {\n\twidth: 100%;\n\ttext-align: center; \n\tmargin: 0;\n\tborder: none;\n\theight: 50px;\n\tline-height: 50px;\n\tposition: relative;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.vertical-nav.nav .item.cur {\n\tbackground-color: #f1f1f1;\n\tfont-weight: bold; \n}\n\n.vertical-nav.nav .item.cur::after {\n\tcontent: \"\";\n\twidth: 8rpx;\n\theight: 30rpx;\n\tborder-radius: 10rpx 0 0 10rpx;\n\tposition: absolute;\n\tbackground-color: currentColor;\n\ttop: 0;\n\tright: 0rpx;\n\tbottom: 0;\n\tmargin: auto;\n}\n\n.vertical-box {\n\tdisplay: flex;\n\twidth: 100%;\n\tbackground-color: #fff;\n}\n\n.vertical-main {\n\tbackground-color: #f1f1f1;\n\tflex: 1;\n}\n\n.vertical-main .vertical-main-box {\n\tpadding: 30rpx 30rpx 0rpx 30rpx;\n\twidth: 100%;\n}\n\n.vertical-main .righ-tab-bar {\n\twidth: 100%;\n\ttext-align: left;\n}\n\n.vertical-main .right-tab-tilte {\n\tfont-weight: bold;\n}\n\n\n.vertical-main .text-list {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tjustify-content: flex-start;\n\talign-items: center;\n\tbackground-color: #fff;\n\tpadding-bottom: 20rpx;\n\tpadding: 0rpx 10rpx 20rpx 10rpx;\n\tpadding-top: 10rpx;\n}\n\n.vertical-main .text-list .item {\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n\talign-items: center;\n\tfont-size: 28rpx;\n\tcolor: #333; \n\twidth: 50%;\n\ttext-align: center;\n\tpadding: 10rpx 10rpx;\n}\n\n.vertical-main .text-list .item .time-text {\n\twidth:100%;  \n\tborder-radius: 15rpx;\n\tborder: 1rpx solid #ccc;\n\tbackground-color: #f8f8f8;\n\theight: 65rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: center; \n\tfont-size: 28rpx;\n\tcolor:#000;\n}\n\n.vertical-main .text-list .item .time-text.error {\n\tbackground-color: #f1f1f1;\n\tcolor: #aaa;\n}\n\n.vertical-main .text-list .item .time-text.limit {\n\theight: 95rpx;\n}\n\n.vertical-main .text-list .item .time-text .limit-text {\n\twidth: 100%;\n\tfont-size: 24rpx;\n\tcolor: #999;\n}\n "
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/index/meet_index.js",
    "content": "const pageHelper = require('../../../../../helper/page_helper.js');\nconst ProjectBiz = require('../../../biz/project_biz.js');\nconst MeetBiz = require('../../../biz/meet_biz.js');\n\nPage({\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tProjectBiz.initPage(this);\n\n\t\tif (options && options.id) {\n\t\t\tthis.setData({\n\t\t\t\t_params: {\n\t\t\t\t\ttypeId: options.id,\n\t\t\t\t}\n\t\t\t});\n\t\t\tMeetBiz.setTypeTitle(this, options.id);\n\t\t} else {\n\t\t\t// 默认1\n\t\t\tthis.setData({\n\t\t\t\t_params: {\n\t\t\t\t\ttypeId: 1,\n\t\t\t\t}\n\t\t\t});\n\t\t\tMeetBiz.setTypeTitle(this, 1);\n\t\t}\n \n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: async function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\turl: async function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tbindCommListCmpt: function (e) {\n\t\tpageHelper.commListListener(this, e);\n\t},\n\n\t/**\n\t * 用户点击右上角分享\n\t */\n\tonShareAppMessage: function () {\n\n\t},\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/index/meet_index.json",
    "content": "{\n\t\"usingComponents\": { \n\t}, \n\t\"disableScroll\": true, \n\t\"navigationBarTitleText\": \"预约列表\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/index/meet_index.wxml",
    "content": "<view wx:if=\"{{!_params}}\" class=\"margin-top load loading text-l load-project\"></view>\n<block wx:else> \n\n\t<cmpt-comm-list type=\"meet-list\" _params=\"{{_params}}\" search=\"{{search}}\" _menus=\"{{}}\" _items=\"{{}}\" route=\"meet/list\" topBottom=\"120\" isTotalMenu=\"{{true}}\" placeholder=\"搜索\" bind:list=\"bindCommListCmpt\">\n\t\t<view class=\"up-project\" wx:if=\"{{showUp}}\">\n\t\t\t<image wx:if=\"{{upImg}}\" mode=\"widthFix\" lazy-load src=\"{{upImg}}\" />\n\t\t</view>\n\t\t<!-- List Begin -->\n\t\t<import src=\"../../../../../tpls/public/base_list_tpl.wxml\" />\n\t\t<template is=\"baseListTpl\" data=\"{{skin,dataList:dataList.list,listMode}}\" />\n\t\t<!-- List END -->\n\n\t\t<!--load begin-->\n\t\t<import src=\"../../../../../tpls/public/list_load_tpl.wxml\" />\n\t\t<template is=\"listLoadTpl\" data=\"{{skin:'load-project',dataList}}\" />\n\t\t<!--load end-->\n\n\t</cmpt-comm-list>\n\n\t<block wx:if=\"{{skin.IS_SUB}}\">\n\t\t<import src=\"../../tpls/menu_tpl.wxml\" />\n\t\t<template is=\"menuTpl\" data=\"{{skin,curMenu:'meet_index',returnHome}}\" />\n\t</block>\n\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/index/meet_index.wxss",
    "content": "@import \"../../../../../style/public/comm_box_list.wxss\";\n@import \"../../../style/skin.wxss\"; "
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/join/meet_join.js",
    "content": "const cloudHelper = require('../../../../../helper/cloud_helper.js');\nconst pageHelper = require('../../../../../helper/page_helper.js');\nconst MeetBiz = require('../../../biz/meet_biz.js');\nconst ProjectBiz = require('../../../biz/project_biz.js');\nconst PassportBiz = require('../../../../../comm/biz/passport_biz.js');\nconst projectSetting = require('../../../public/project_setting.js');\n\nPage({\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false,  \n\t\tforms: [],\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tProjectBiz.initPage(this);\n\t\tif (!pageHelper.getOptions(this, options)) return;\n\t\tif (!pageHelper.getOptions(this, options, 'timeMark')) return;\n\n\t\tif (!await PassportBiz.loginMustBackWin(this)) return;\n\n\t\tthis._loadDetail();\n\n\t},\n\n\t_loadDetail: async function () {\n\t\tlet id = this.data.id;\n\t\tif (!id) return;\n\n\t\tlet timeMark = this.data.timeMark;\n\t\tif (!timeMark) return;\n\n\t\tlet params = {\n\t\t\tmeetId: id,\n\t\t\ttimeMark\n\t\t};\n\t\tlet opt = {\n\t\t\ttitle: 'bar'\n\t\t};\n\t\tlet meet = await cloudHelper.callCloudData('meet/detail_for_join', params, opt);\n\t\tif (!meet) {\n\t\t\tthis.setData({\n\t\t\t\tisLoad: null\n\t\t\t})\n\t\t\treturn;\n\t\t}\n\n\n\t\tthis.setData({\n\t\t\tisLoad: true,\n\t\t\tmeet,\n\t\t});\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\t\tawait this._loadDetail();\n\t\twx.stopPullDownRefresh();\n\t},\n\n\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tonPageScroll: function (e) {\n\t\t// 回页首按钮\n\t\tpageHelper.showTopBtn(e, this);\n\n\t},\n\n\tbindCheckTap: async function (e) {\n\t\tthis.selectComponent(\"#form-show\").checkForms();\n\t},\n\n\tbindSubmitCmpt: async function (e) {\n\t\tlet forms = e.detail;\n\n\t\tlet callback = async () => {\n\t\t\ttry {\n\t\t\t\tlet opts = {\n\t\t\t\t\ttitle: '提交中'\n\t\t\t\t}\n\t\t\t\tlet params = {\n\t\t\t\t\tmeetId: this.data.id,\n\t\t\t\t\ttimeMark: this.data.timeMark,\n\t\t\t\t\tforms\n\t\t\t\t}\n\t\t\t\tawait cloudHelper.callCloudSumbit('meet/join', params, opts).then(res => {\n\t\t\t\t\tlet content = '预约成功！'\n\n\t\t\t\t\tlet joinId = res.data.joinId;\n\t\t\t\t\twx.showModal({\n\t\t\t\t\t\ttitle: '温馨提示',\n\t\t\t\t\t\tshowCancel: false,\n\t\t\t\t\t\tcontent,\n\t\t\t\t\t\tsuccess() {\n\t\t\t\t\t\t\tlet ck = () => {\n\t\t\t\t\t\t\t\twx.reLaunch({\n\t\t\t\t\t\t\t\t\turl: pageHelper.fmtURLByPID('/pages/meet/my_join_detail/meet_my_join_detail?flag=home&id=' + joinId),\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tck();\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t} catch (err) {\n\t\t\t\tconsole.log(err);\n\t\t\t};\n\t\t}\n\n\t\t// 消息订阅\n\t\tawait MeetBiz.subscribeMessageMeet(callback);\n\n\t}\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/join/meet_join.json",
    "content": "{\n\t\"usingComponents\": { \n\t\t\"cmpt-form-show\": \"/cmpts/public/form/form_show/form_show_cmpt\"  \n\t},\n\t\"enablePullDownRefresh\": true, \n\t\"navigationBarTitleText\": \"预约登记\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/join/meet_join.wxml",
    "content": "<view wx:if=\"{{isLoad===null}}\" class=\"margin-top load notexist text-l load-project\"></view>\n<view wx:if=\"{{isLoad===false}}\" class=\"margin-top load loading text-l load-project\"></view>\n\n<view wx:if=\"{{isLoad&&isLogin}}\" class=\"main padding-project\">\n\n\t<view class=\"article-box\">\n\t\t<view class=\"form-box card-project shadow-project\">\n\t\t\t<view class=\"form-group\">\n\t\t\t\t<view class=\"title text-cut\">{{meet.MEET_TITLE}}</view>\n\t\t\t</view>\n\t\t\t<view class=\"form-group\" bindtap=\"url\" data-type=\"back\">\n\t\t\t\t<view class=\"title text-cut\" style=\"padding-right:0\"><text class=\"icon-calendar margin-right-xxs\"></text>{{meet.dayDesc}} <text class=\"tag mid bg-orange light round margin-right\">更改时段</text></view>\n\t\t\t</view>\n\n\t\t</view>\n\n\t\t<!-- form content begin -->\n\t\t<view class=\"form-box card-project shadow-project margin-top\">\n\t\t\t<view class=\"form-group\">\n\t\t\t\t<view class=\"line-desc\">请您填写资料，带<text class=\"text-red text-bold\">*</text>号为必填项</view>\n\t\t\t</view>\n\t\t\t<cmpt-form-show isConfirm=\"{{true}}\" id=\"form-show\" mark=\"form-show\" forms=\"{{meet.myForms}}\" fields=\"{{meet.MEET_FORM_SET}}\" bind:submit=\"bindSubmitCmpt\" />\n\t\t</view>\n\t\t<!-- form content end -->\n\n\t</view>\n\n\t<button bindtap=\"bindCheckTap\" class=\"btn-base btn-project\" style=\"margin-bottom:100rpx;\">提交</button>\n\n\n</view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/join/meet_join.wxss",
    "content": "@import \"../../../../../style/public/detail.wxss\";\n@import \"../../../style/skin.wxss\"; \n\n.form-group .line-desc {\n\tfont-size: 28rpx;\n\ttext-align: center;\n\twidth: 100%;\n\tcolor: #666;\n}\n\n.submit-line {\n\twidth: 100%;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/my_join_detail/meet_my_join_detail.js",
    "content": "const pageHelper = require('../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../helper/cloud_helper.js');\nconst timeHelper = require('../../../../../helper/time_helper.js');\nconst qrcodeLib = require('../../../../../lib/tools/qrcode_lib.js');\nconst MeetBiz = require('../../../biz/meet_biz.js');\nconst ProjectBiz = require('../../../biz/project_biz.js');\n\nPage({\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false,\n\n\t\tisShowHome: false,\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: function (options) {\n\t\tProjectBiz.initPage(this);\n\t\tif (!pageHelper.getOptions(this, options)) return;\n\t\tthis._loadDetail();\n\n\t\tif (options && options.flag == 'home') {\n\t\t\tthis.setData({\n\t\t\t\tisShowHome: true\n\t\t\t});\n\t\t}\n\t},\n\n\t_loadDetail: async function (e) {\n\t\tlet id = this.data.id;\n\t\tif (!id) return;\n\n\t\tlet params = {\n\t\t\tjoinId: id\n\t\t}\n\t\tlet opts = {\n\t\t\ttitle: 'bar'\n\t\t}\n\t\ttry {\n\t\t\tlet join = await cloudHelper.callCloudData('meet/my_join_detail', params, opts);\n\t\t\tif (!join) {\n\t\t\t\tthis.setData({\n\t\t\t\t\tisLoad: null\n\t\t\t\t})\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet qrImageData = qrcodeLib.drawImg('meet=' + join.JOIN_CODE, {\n\t\t\t\ttypeNumber: 1,\n\t\t\t\terrorCorrectLevel: 'L',\n\t\t\t\tsize: 100\n\t\t\t});\n\n\t\t\tthis.setData({\n\t\t\t\tisLoad: true,\n\t\t\t\tjoin,\n\t\t\t\tqrImageData\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.error(err);\n\t\t}\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\t\tawait this._loadDetail();\n\t\twx.stopPullDownRefresh();\n\t},\n\n\t/**\n\t * 用户点击右上角分享\n\t */\n\tonShareAppMessage: function () {\n\n\t},\n\n\tbindCancelTap: async function (e) {\n\t\tlet callback = async () => {\n\t\t\ttry {\n\t\t\t\tlet params = {\n\t\t\t\t\tjoinId: this.data.id\n\t\t\t\t}\n\t\t\t\tlet opts = {\n\t\t\t\t\ttitle: '取消中'\n\t\t\t\t}\n\n\t\t\t\tawait cloudHelper.callCloudSumbit('meet/my_join_cancel', params, opts).then(res => {\n\t\t\t\t\tlet join = this.data.join;\n\t\t\t\t\tjoin.JOIN_STATUS = 10;\n\t\t\t\t\tthis.setData({\n\t\t\t\t\t\tjoin\n\t\t\t\t\t});\n\t\t\t\t\tpageHelper.showNoneToast('已取消');\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tconsole.log(err);\n\t\t\t}\n\t\t}\n\n\t\tpageHelper.showConfirm('确认取消该预约?', callback);\n\t},\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tbindNoticeTap: function (e) {\n\t\tlet callback = () => {\n\t\t\tpageHelper.showSuccToast('开启成功');\n\t\t}\n\t\tMeetBiz.subscribeMessageMeet(callback);\n\t},\n\n\tbindCalendarTap: function (e) {\n\t\tlet join = this.data.join;\n\t\tlet title = join.JOIN_MEET_TITLE;\n\n\t\tlet startTime = timeHelper.time2Timestamp(join.JOIN_MEET_DAY + ' ' + join.JOIN_MEET_TIME_START + ':00') / 1000;\n\t\tlet endTime = timeHelper.time2Timestamp(join.JOIN_MEET_DAY + ' ' + join.JOIN_MEET_TIME_END + ':00') / 1000;\n\n\t\tpageHelper.addPhoneCalendar(title, startTime, endTime);\n\t}\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/my_join_detail/meet_my_join_detail.json",
    "content": "{\n\t\"usingComponents\": { \n\t},  \n\t\"enablePullDownRefresh\": true, \n\t\"navigationBarTitleText\": \"我的预约详情\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/my_join_detail/meet_my_join_detail.wxml",
    "content": "<view wx:if=\"{{isLoad===null}}\" class=\"margin-top load notexist text-l load-project\"></view>\n<view wx:if=\"{{isLoad===false}}\" class=\"margin-top load loading text-l load-project\"></view>\n\n<block wx:if=\"{{isLoad}}\">\n\t<view class=\"main padding-project\">\n\t\t<view class=\"text-pic-list-box margin-top-xs\">\n\t\t\t<view class=\"item card-project shadow-project\">\n\t\t\t\t<view class=\"title-line\" bindtap=\"url\" data-url=\"../detail/meet_detail?id={{join.JOIN_MEET_ID}}\">\n\t\t\t\t\t<view class=\"title content-cut-two\">{{join.JOIN_MEET_TITLE}} </view>\n\t\t\t\t\t<view class=\"arrow\"><text class=\"icon-right\"></text></view>\n\t\t\t\t</view>\n\n\t\t\t\t<view class=\"author\">\n\t\t\t\t\t<text class=\"icon-remind margin-right-xs text-s\"></text><text class=\"text-cut\">{{join.JOIN_MEET_DAY}} {{join.JOIN_MEET_TIME_START}}～{{join.JOIN_MEET_TIME_END}}</text>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"data\">\n\t\t\t\t\t<text wx:if=\"{{join.JOIN_STATUS==1}}\" class=\"text-green\"><text class=\"icon-newshot margin-right-xxs\"></text>预约成功{{join.JOIN_IS_CHECKIN==1?'，已签到':''}}</text>\n\n\t\t\t\t\t<button wx:if=\"{{(join.JOIN_STATUS==1||join.JOIN_STATUS==0) && join.JOIN_IS_CHECKIN==0}}\" bindtap=\"bindCancelTap\" class=\"btn mid bg-grey light  margin-left-s\"><text class=\"icon-close\"></text>取消预约</button>\n\n\t\t\t\t\t<text wx:if=\"{{join.JOIN_STATUS==10}}\" class=\"text-grey\"><text class=\"icon-bad margin-right-xxs\"></text>已取消</text>\n\n\t\t\t\t\t<block wx:if=\"{{join.JOIN_STATUS==99}}\">\n\t\t\t\t\t\t<text class=\"text-orange\"><text class=\"icon-bad margin-right-xxs\"></text>系统取消<text class=\"text-grey\" wx:if=\"{{join.JOIN_REASON}}\">：{{join.JOIN_REASON}}</text></text>\n\t\t\t\t\t</block>\n\t\t\t\t</view>\n\n\t\t\t\t<view class=\"oprt\" wx:if=\"{{join.JOIN_STATUS==0 || join.JOIN_STATUS==1}}\">\n\t\t\t\t\t<view bindtap=\"url\" data-url=\"../../my/index/my_index\" data-type=\"relaunch\" wx:if=\"{{isShowHome}}\" class=\"btn margin-right-s\">返回首页</view>\n\t\t\t\t\t<view bindtap=\"bindCalendarTap\" class=\"btn\">加入手机日程</view>\n\t\t\t\t</view>\n\n\t\t\t</view>\n\n\t\t</view>\n\n\t\t<view class=\"info-list-box\" wx:if=\"{{join.JOIN_STATUS==1}}\">\n\t\t\t<view class=\"item card-project shadow-project\">\n\t\t\t\t<view class=\"info\">\n\t\t\t\t\t<view class=\"center\"><text class=\"text-bold margin-right-s\">预约码</text> (向工作人员出示进行核销)</view>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"info\">\n\t\t\t\t\t<view class=\"center\">\n\t\t\t\t\t\t<image show-menu-by-longpress=\"{{true}}\" src=\"{{qrImageData}}\" class=\"loading\" />\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t</view>\n\n\t\t<view class=\"info-list-box margin-bottom-xxl\">\n\t\t\t<view class=\"item card-project shadow-project\">\n\t\t\t\t<view class=\"info margin-bottom-s\">\n\t\t\t\t\t<view class=\"center text-bold\">预约信息</view>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"info\" wx:for=\"{{join.JOIN_FORMS}}\" wx:key=\"key\">\n\t\t\t\t\t<view class=\"title\">{{item.title}}：</view>\n\t\t\t\t\t<view class=\"content\">{{item.val}}</view>\n\t\t\t\t</view>\n\n\t\t\t\t<view class=\"info text-grey margin-top-xs text-s\">提交时间：{{join.JOIN_ADD_TIME}}</view>\n\t\t\t</view>\n\t\t</view>\n\t</view>\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/my_join_detail/meet_my_join_detail.wxss",
    "content": "@import \"../../../../../style/public/article_list.wxss\";\n@import \"../../../style/skin.wxss\"; \n.main {\n\tpadding: 0; \n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: flex-start; \n}\n\n.text-pic-list-box {\n\tpadding: 20rpx 0rpx 10rpx;\n}\n\n\n.text-pic-list-box .item {\n\tpadding: 20rpx 30rpx 20rpx 30rpx;\n}\n\n.text-pic-list-box .title-line {\n\twidth: 100%;\n\tjustify-content: space-between;\n\tdisplay: flex;\n\talign-items: flex-start;\n}\n\n.text-pic-list-box .title-line .arrow {\n\twidth: 100rpx;\n\tcolor: #666;\n\ttext-align: right;\n}\n\n.text-pic-list-box .item .oprt {\n\tline-height: 1.5;\n\tfont-size: 27rpx; \n\tmargin: 30rpx 0 10rpx;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tcolor: var(--projectColor)\n}\n\n.text-pic-list-box .item .oprt .btn {\n\tpadding: 0 20rpx;\n}\n\n.info-list-box {\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tpadding: 0rpx 0rpx 10rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center; \n}\n\n.info-list-box .item {\n\tpadding: 20rpx 30rpx 20rpx 40rpx;\n\tbackground-color: #fff;\n\tdisplay: flex;\n\tflex-direction: column;\n\tbackground-color: #fff;\n\tborder-radius: 20rpx;\n\tmargin-bottom: 20rpx;\n\tposition: relative;\n}\n\n.info-list-box .item .info {\n\twidth: 100%;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-start;\n\tfont-size: 28rpx;\n\tline-height: 1.5;\n\tcolor: #333;\n\tborder-bottom: 2rpx dotted #ccc;\n\tpadding: 10rpx 0;\n}\n\n.info-list-box .item .info:last-child,\n.info-list-box .item .info:first-child {\n\tborder-bottom: 0;\n}\n\n.info-list-box .item .info .title {\n\tfont-weight: bold;\n\twidth: 150rpx;\n\tmargin-right: 10rpx;\n\talign-self: start;\n\tposition: relative;\n}\n\n.info-list-box .item .info .content {\n\tflex: 1;\n\tdisplay: flex;\n\talign-items: flex-start;\n\tjustify-content: flex-start;\n\talign-self: start;\n}\n\n.info-list-box .item .info .center {\n\twidth: 100%;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.info-list-box .item .info .center image {\n\twidth: 400rpx;\n\theight: 400rpx;\n\tmargin: 30rpx;\n}\n\n"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/my_join_list/meet_my_join_list.js",
    "content": "\nconst pageHelper = require('../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../helper/cloud_helper.js');\nconst ProjectBiz = require('../../../biz/project_biz.js'); \n\nPage({\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLogin: true\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: function (options) {\n\t\tProjectBiz.initPage(this); \n\n\t\tthis._getSearchMenu();\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: function () {\n\n\t},\n\n\t/**\n\t * 页面上拉触底事件的处理函数\n\t */\n\tonReachBottom: function () {\n\n\t},\n\n\t/**\n\t * 用户点击右上角分享\n\t */\n\tonShareAppMessage: function () {\n\n\t},\n\n\turl: async function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tbindCommListCmpt: function (e) {\n\t\tpageHelper.commListListener(this, e);\n\t},\n\n\t/** 搜索菜单设置 */\n\t_getSearchMenu: function () {\n\t\tlet sortItem1 = [{\n\t\t\tlabel: '排序',\n\t\t\ttype: '',\n\t\t\tvalue: ''\n\t\t}, {\n\t\t\tlabel: '按时间倒序',\n\t\t\ttype: 'timedesc',\n\t\t\tvalue: ''\n\t\t}, {\n\t\t\tlabel: '按时间正序',\n\t\t\ttype: 'timeasc',\n\t\t\tvalue: ''\n\t\t}];\n\n\t\tlet sortItems = [sortItem1];\n\t\tlet sortMenus = [{\n\t\t\tlabel: '全部',\n\t\t\ttype: '',\n\t\t\tvalue: ''\n\t\t}, {\n\t\t\tlabel: '今日',\n\t\t\ttype: 'today',\n\t\t\tvalue: ''\n\t\t}, {\n\t\t\tlabel: '明日',\n\t\t\ttype: 'tomorrow',\n\t\t\tvalue: ''\n\t\t}, {\n\t\t\tlabel: '已预约',\n\t\t\ttype: 'succ',\n\t\t\tvalue: ''\n\t\t},\n\t\t{\n\t\t\tlabel: '已取消',\n\t\t\ttype: 'cancel',\n\t\t\tvalue: ''\n\t\t}\n\t\t]\n\n\t\tthis.setData({\n\t\t\tsortItems,\n\t\t\tsortMenus\n\t\t});\n\n\t},\n\tbindCancelTap: async function (e) {\n\t\tlet callback = async () => {\n\t\t\tlet joinId = pageHelper.dataset(e, 'id');\n\t\t\ttry {\n\t\t\t\tlet params = {\n\t\t\t\t\tjoinId\n\t\t\t\t}\n\t\t\t\tlet opts = {\n\t\t\t\t\ttitle: '取消中'\n\t\t\t\t}\n\n\t\t\t\tawait cloudHelper.callCloudSumbit('meet/my_join_cancel', params, opts).then(res => {\n\t\t\t\t\tpageHelper.modifyListNode(joinId, this.data.dataList.list, 'JOIN_STATUS', 10, '_id');\n\t\t\t\t\tthis.setData({\n\t\t\t\t\t\tdataList: this.data.dataList\n\t\t\t\t\t});\n\t\t\t\t\tpageHelper.showNoneToast('已取消');\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tconsole.log(err);\n\t\t\t}\n\t\t}\n\n\t\tpageHelper.showConfirm('确认取消该预约?', callback);\n\t}\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/my_join_list/meet_my_join_list.json",
    "content": "{\n\t\"usingComponents\": { \n\t}, \n\t\"disableScroll\": true, \n\t\"navigationBarTitleText\": \"我的预约\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/my_join_list/meet_my_join_list.wxml",
    "content": "<block>\n\t<cmpt-comm-list type=\"my_join\" search=\"{{search}}\" _menus=\"{{sortMenus}}\" _items=\"{{sortItems}}\" route=\"meet/my_join_list\" isTotalMenu=\"{{true}}\" sortMenusDefaultIndex=\"0\" topBottom=\"120\" placeholder=\"搜索标题\" bind:list=\"bindCommListCmpt\">\n\n\t\t<view slot=\"searchEnd\">\n\n\t\t</view>\n\n\t\t<!-- List Begin -->\n\t\t<view class=\"text-pic-list-box padding-project\">\n\n\t\t\t<view class=\"item card-project shadow-project\" wx:for=\"{{dataList.list}}\" wx:key=\"index\">\n\t\t\t\t<view wx:if=\"{{item.isTimeout}}\" class=\"status\">已结束</view>\n\t\t\t\t<view bindtap=\"url\" data-url=\"../my_join_detail/meet_my_join_detail?id={{item._id}}\" wx:elif=\"{{item.JOIN_STATUS==1}}\" class=\"qr\"><text class=\"icon-qrcode\"></text></view>\n\t\t\t\t<view class=\"title content-cut-two\" bindtap=\"url\" data-url=\"../my_join_detail/meet_my_join_detail?id={{item._id}}\">{{item.JOIN_MEET_TITLE}}</view>\n\t\t\t\t<view class=\"author\" bindtap=\"url\" data-url=\"../my_join_detail/meet_my_join_detail?id={{item._id}}\">\n\t\t\t\t\t<text class=\"icon-time margin-right-xs text-s\"></text><text class=\"text-cut\">{{item.JOIN_MEET_DAY}} {{item.JOIN_MEET_TIME_START}}～{{item.JOIN_MEET_TIME_END}}</text>\n\t\t\t\t</view>\n\n\t\t\t\t<view class=\"data\" bindtap=\"url\" data-url=\"../my_join_detail/meet_my_join_detail?id={{item._id}}\">\n\t\t\t\t\t<text wx:if=\"{{item.JOIN_STATUS==1}}\" class=\"text-green\"><text class=\"icon-newshot margin-right-xxs\"></text>预约成功{{item.JOIN_IS_CHECKIN==1?'，已签到':''}}</text>\n\n\t\t\t\t\t<text wx:elif=\"{{item.JOIN_STATUS==10}}\" class=\"text-grey\"><text class=\"icon-bad margin-right-xxs\"></text>已取消</text>\n\n\t\t\t\t\t<block wx:elif=\"{{item.JOIN_STATUS==99}}\">\n\t\t\t\t\t\t<text class=\"text-orange\"><text class=\"icon-bad margin-right-xxs\"></text>系统取消<text class=\"text-grey\" wx:if=\"{{item.JOIN_REASON}}\">：{{item.JOIN_REASON}}</text></text>\n\t\t\t\t\t</block>\n\n\t\t\t\t</view>\n\n\t\t\t\t<view class=\"data data-button\">\n\t\t\t\t\t<button bindtap=\"url\" data-url=\"../my_join_detail/meet_my_join_detail?id={{item._id}}\" class=\"btn mid bg-gray text-black\">查看详情</button>\n\t\t\t\t\t<button wx:if=\"{{(item.JOIN_STATUS==1||item.JOIN_STATUS==0) && item.JOIN_IS_CHECKIN==0}}\" bindtap=\"bindCancelTap\" data-id=\"{{item._id}}\" class=\"btn mid bg-grey light\"><text class=\"icon-close\"></text>取消</button>\n\t\t\t\t</view>\n\n\t\t\t</view>\n\n\t\t\t<!--load begin-->\n\t\t\t<import src=\"../../../../../tpls/public/list_load_tpl.wxml\" />\n\t\t\t<template is=\"listLoadTpl\" data=\"{{skin:'load-project',dataList}}\" />\n\t\t\t<!--load end-->\n\n\t\t</view>\n\t\t<!-- List END -->\n\n\t</cmpt-comm-list>\n\n\t<!--  button Begin -->\n\t<!--  button END -->\n\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/my_join_list/meet_my_join_list.wxss",
    "content": "@import \"../../../../../style/public/article_list.wxss\";\n@import \"../../../style/skin.wxss\"; \n\n.text-pic-list-box .item {\n\tpadding: 20rpx 30rpx 20rpx 40rpx;\n\tposition: relative;\n\toverflow: hidden;\n}\n\n.text-pic-list-box .item .status {\n\tz-index: 9999;\n\tposition: absolute;\n\ttop: 0;\n\tright: 0;\n\tfont-size: 24rpx;\n\tborder-bottom-left-radius: 10rpx;\n\tbackground-color: #f8f8f8;\n\tpadding: 0rpx 10rpx 0rpx;\n\tcolor: #bbb;\n}\n\n.text-pic-list-box .item .qr {\n\tz-index: 9999;\n\tposition: absolute;\n\ttop: 0;\n\tright: 0;\n\tfont-size: 24rpx;\n\tborder-bottom-left-radius: 10rpx;\n\tbackground-color: #f2f2f2;\n\tpadding: 0rpx 10rpx 0rpx;\n\tcolor: #666;\n\tfont-size:40rpx;\n}\n\n.btn.mid {\n\tpadding: 0 30rpx;  \n}\n\n.text-pic-list-box .item .author {\n\tfont-size: 28rpx;\n\tcolor: #999;\n}\n\n.text-pic-list-box .item .title {\n\tposition: relative;\n\tpadding-right: 20rpx;\n}\n\n.text-pic-list-box .item .data {\n\tline-height: 1.5;\n\tfont-size: 26rpx;\n\tcolor: #666;\n\tmargin-top: 10rpx;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: center;\n}\n\n.text-time {\n\tcolor: #ccc;\n}\n\n"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/self/meet_self.js",
    "content": "const pageHelper = require('../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../helper/cloud_helper.js');\nconst ProjectBiz = require('../../../biz/project_biz.js');\n\nPage({\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tProjectBiz.initPage(this);\n\t\t\n\t\tif (options && options.scene) {\n\t\t\tlet params = {\n\t\t\t\ttimeMark: options.scene\n\t\t\t};\n\t\t\tlet opts = {\n\t\t\t\ttitle: 'bar'\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait cloudHelper.callCloudSumbit('meet/my_join_checkin', params, opts).then(res => {\n\t\t\t\t\tlet cb = () => {\n\t\t\t\t\t\twx.reLaunch({\n\t\t\t\t\t\t\turl: pageHelper.fmtURLByPID('/pages/my/index/my_index'),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tpageHelper.showModal(res.data.ret, '温馨提示', cb);\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(err);\n\t\t\t}\n\t\t} else {\n\t\t\tpageHelper.showModal('签到码扫描错误，请关闭本小程序，使用「微信›扫一扫」重新扫码');\n\t\t}\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: function () {\n\n\t},\n\n\t/**\n\t * 页面上拉触底事件的处理函数\n\t */\n\tonReachBottom: function () {\n\n\t},\n\n\t/**\n\t * 用户点击右上角分享\n\t */\n\tonShareAppMessage: function () {\n\n\t}\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/self/meet_self.json",
    "content": "{\n\t\"usingComponents\": {  \n\t}, \n\t\"navigationBarTitleText\": \"自助签到\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/self/meet_self.wxml",
    "content": "<view class=\"margin-top load loading text-l text-grey\"></view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/meet/self/meet_self.wxss",
    "content": "@import \"../../../style/skin.wxss\"; \n.load.loading::after {\n    content: \"自助签到中，请稍候...\";\n}\n "
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/my/edit/my_edit.js",
    "content": "const pageHelper = require('../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../helper/cloud_helper.js');\nconst validate = require('../../../../../helper/validate.js');\nconst ProjectBiz = require('../../../biz/project_biz.js');\nconst projectSetting = require('../../../public/project_setting.js');\nconst setting = require('../../../../../setting/setting.js');\nconst PassportBiz = require('../../../../../comm/biz/passport_biz.js');\n\nPage({\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false,\n\t\tisEdit: true,\n\n\t\tuserRegCheck: projectSetting.USER_REG_CHECK,\n\t\tmobileCheck: setting.MOBILE_CHECK\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tProjectBiz.initPage(this);\n\t\tawait this._loadDetail();\n\t},\n\n\t_loadDetail: async function (e) {\n\n\t\tlet opts = {\n\t\t\ttitle: 'bar'\n\t\t}\n\t\tlet user = await cloudHelper.callCloudData('passport/my_detail', {}, opts);\n\t\tif (!user)\n\t\t\treturn wx.redirectTo({ url: '../reg/my_reg' });\n\n\t\tthis.setData({\n\t\t\tisLoad: true,\n\t\t\tisEdit: true,\n\n\t\t\tuser,\n\n\t\t\tfields: projectSetting.USER_FIELDS,\n\n\t\t\tformName: user.USER_NAME,\n\t\t\tformMobile: user.USER_MOBILE,\n\t\t\tformForms: user.USER_FORMS\n\t\t})\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\t\tawait this._loadDetail();\n\t\twx.stopPullDownRefresh();\n\t},\n\n\t/**\n\t * 页面上拉触底事件的处理函数\n\t */\n\tonReachBottom: function () {\n\n\t},\n\n\tbindGetPhoneNumber: async function (e) {\n\t\tawait PassportBiz.getPhone(e, this);\n\t},\n\n\n\tbindSubmitTap: async function (e) {\n\t\ttry {\n\t\t\tlet data = this.data;\n\t\t\t// 数据校验 \n\t\t\tdata = validate.check(data, PassportBiz.CHECK_FORM, this);\n\t\t\tif (!data) return;\n\n\t\t\tlet forms = this.selectComponent(\"#cmpt-form\").getForms(true);\n\t\t\tif (!forms) return;\n\t\t\tdata.forms = forms;\n\n\t\t\tlet opts = {\n\t\t\t\ttitle: '提交中'\n\t\t\t}\n\t\t\tawait cloudHelper.callCloudSumbit('passport/edit_base', data, opts).then(res => {\n\t\t\t\tlet callback = () => {\n\t\t\t\t\twx.reLaunch({ url: '../index/my_index' });\n\t\t\t\t}\n\t\t\t\tpageHelper.showSuccToast('修改成功', 1500, callback);\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.error(err);\n\t\t}\n\t}\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/my/edit/my_edit.json",
    "content": "{\n\t\"usingComponents\": { \n\t\t\"cmpt-form-show\": \"/cmpts/public/form/form_show/form_show_cmpt\"  \n\t},\n\t\"enablePullDownRefresh\": true, \n\t\"navigationBarTitleText\": \"个人资料\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/my/edit/my_edit.wxml",
    "content": "<view wx:if=\"{{isLoad===null}}\" class=\"margin-top load notexist text-l load-project\"></view>\n<view wx:if=\"{{isLoad===false}}\" class=\"margin-top load loading text-l load-project\"></view>\n\n<view wx:if=\"{{isLoad}}\" class=\"main padding-project\">  \n\t<include src=\"user_form.wxml\" />\n\t<button bindtap=\"bindSubmitTap\" class=\"btn-base btn-project\">修改资料</button>\n</view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/my/edit/my_edit.wxss",
    "content": "@import \"../../../style/skin.wxss\"; \n.submit-line {\n\twidth: 100%;\n}\n\n.form-group .mobile {\n\tflex: 1;\n\ttext-align: left;\n}\n\n.submit-line {\n\twidth: 100%;\n}\n\n.form-group .mobile {\n\tflex: 1;\n\ttext-align: left;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/my/edit/user_form.wxml",
    "content": "<view class=\"form-box shadow-project card-project\">\n\t<view class=\"form-group padding-top-s\" wx:if=\"{{userRegCheck && user.USER_STATUS==8}}\">\n\t\t<view wx:if=\"{{!user.USER_CHECK_REASON}}\" class=\"hint-desc text-red\"><text class=\"icon-notice\"></text>审核未通过：请修改资料后重新提交</view>\n\t\t<view wx:else class=\"hint-desc text-red\"><text class=\"icon-notice\"></text>审核未通过：{{user.USER_CHECK_REASON}}。请修改资料后重新提交</view> \n\t</view>\n\n\t<view class=\"form-group padding-top-s\" wx:elif=\"{{userRegCheck && user.USER_STATUS==0}}\">\n\t\t<view class=\"hint-desc text-orange\"><text class=\"icon-notice\"></text>您的注册资料已经提交，请耐心等待审核~</view> \n\t</view>\n\t\n\t<view class=\"form-group\">\n\t\t<view class=\"title must\">昵称</view>\n\t\t<input type=\"nickname\" placeholder=\"填写您的昵称\" placeholder-class=\"phc\" model:value=\"{{formName}}\" maxlength=\"30\"></input>\n\t</view>\n\t<view wx:if=\"{{formNameFocus}}\" class=\"hint-desc error\">{{formNameFocus}}</view>\n\n\t<view class=\"form-group\">\n\t\t<view class=\"title must\">手机</view>\n\t\t<input wx:if=\"{{!mobileCheck}}\" placeholder=\"填写您的手机号码\" placeholder-class=\"phc\" model:value=\"{{formMobile}}\" maxlength=\"11\"></input>\n\n\t\t<block wx:else>\n\t\t\t<view class=\"mobile\">{{formMobile||'未填写'}}</view>\n\t\t\t<button open-type=\"getPhoneNumber\" bindgetphonenumber=\"bindGetPhoneNumber\" class=\"btn phone-button\"><text wx:if=\"{{!formMobile}}\">一键填写手机号</text><text wx:else>一键修改手机号</text></button>\n\t\t</block>\n\t</view>\n\t<view wx:if=\"{{formMobileFocus}}\" class=\"hint-desc error\">{{formMobileFocus}}</view>\n\n</view>\n\n<view class=\"form-box shadow margin-top-xs\">\n\t<cmpt-form-show id=\"cmpt-form\" mark=\"cmpt-form\" isCacheMatch=\"{{false}}\" fields=\"{{fields}}\" forms=\"{{formForms}}\" isDefMatch=\"{{isEdit?false:true}}\">\n\t</cmpt-form-show>\n</view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/my/fav/my_fav.js",
    "content": "const behavior = require('../../../../../comm/behavior/my_fav_bh.js');\nconst ProjectBiz = require('../../../biz/project_biz.js');\n\nPage({\n\n\tbehaviors: [behavior],\n\n\tonReady: function () { \n\t\tProjectBiz.initPage(this);\n\t},\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/my/fav/my_fav.json",
    "content": "{\n\t\"usingComponents\": {},\n\t\"enablePullDownRefresh\": true,\n\t\"navigationBarTitleText\": \"我的收藏\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/my/fav/my_fav.wxml",
    "content": "<include src=\"../../../../../tpls/project/my_fav_tpl.wxml\" />"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/my/fav/my_fav.wxss",
    "content": "@import \"../../../../../style/public/article_list.wxss\";\n@import \"../../../style/skin.wxss\";  \n@import \"../../../../../style/project/my_fav_style.wxss\";"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/my/foot/my_foot.js",
    "content": "const behavior = require('../../../../../comm/behavior/my_foot_bh.js');\nconst ProjectBiz = require('../../../biz/project_biz.js');\n\nPage({\n\n\tbehaviors: [behavior],\n\n\tonReady: function () { \n\t\tProjectBiz.initPage(this);\n\t},\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/my/foot/my_foot.json",
    "content": "{\n\t\"usingComponents\": {},\n\t\"enablePullDownRefresh\": true,\n\t\"navigationBarTitleText\": \"历史浏览\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/my/foot/my_foot.wxml",
    "content": "<include src=\"../../../../../tpls/project/my_foot_tpl.wxml\" />"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/my/foot/my_foot.wxss",
    "content": "@import \"../../../../../style/public/article_list.wxss\";\n@import \"../../../style/skin.wxss\";  \n@import \"../../../../../style/project/my_foot_style.wxss\";"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/my/index/my_index.js",
    "content": "/** \n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-10-29 07:48:00 \n */\n\nconst cacheHelper = require('../../../../../helper/cache_helper.js');\nconst pageHelper = require('../../../../../helper/page_helper.js');\nconst cloudHelper = require('../../../../../helper/cloud_helper.js'); \nconst ProjectBiz = require('../../../biz/project_biz.js'); \nconst AdminBiz = require('../../../../../comm/biz/admin_biz.js');\nconst setting = require('../../../../../setting/setting.js');\nconst PassportBiz = require('../../../../../comm/biz/passport_biz.js');\n\nPage({\n\tdata: { \n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tif (PassportBiz.isLogin()) {\n\t\t\tlet user = {};\n\t\t\tuser.USER_NAME = PassportBiz.getUserName();\n\t\t\tthis.setData({ user });\n\t\t} \n\n\t\tProjectBiz.initPage(this);\n\n\t}, \n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: async function () { \n\t\tPassportBiz.clearToken();\n\t\tPassportBiz.loginSilence(this);\n\t\t\n\t\tthis._loadUser();\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t_loadUser: async function (e) {\n\n\t\tlet opts = {\n\t\t\ttitle: 'bar'\n\t\t}\n\t\tlet user = await cloudHelper.callCloudData('passport/my_detail', {}, opts);\n\t\tif (!user) {\n\t\t\tthis.setData({\n\t\t\t\tuser: null\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tthis.setData({\n\t\t\tuser\n\t\t})\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () { \n\t\tawait this._loadUser();\n\t\twx.stopPullDownRefresh();\n\t},\n\n\t/**\n\t * 页面上拉触底事件的处理函数\n\t */\n\tonReachBottom: function () {\n\n\t},\n\n\n\t/**\n\t * 用户点击右上角分享\n\t */\n\tonShareAppMessage: function () { },\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tbindSetTap: function (e, skin) {\n\t\tlet itemList = ['清除缓存', '后台管理'];\n\t\twx.showActionSheet({\n\t\t\titemList,\n\t\t\tsuccess: async res => {\n\t\t\t\tlet idx = res.tapIndex;\n\t\t\t\tif (idx == 0) {\n\t\t\t\t\tcacheHelper.clear();\n\t\t\t\t\tpageHelper.showNoneToast('清除缓存成功');\n\t\t\t\t}\n\n\t\t\t\tif (idx == 1) {\n\t\t\t\t\tif (setting.IS_SUB) {\n\t\t\t\t\t\tAdminBiz.adminLogin(this, 'admin', '123456');\n\t\t\t\t\t} else {\n\t\t\t\t\t\twx.reLaunch({\n\t\t\t\t\t\t\turl: '../../admin/index/login/admin_login',\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t},\n\t\t\tfail: function (res) { }\n\t\t})\n\t}\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/my/index/my_index.json",
    "content": "{\n\t\"usingComponents\": {\n\n\t},\n\t\"enablePullDownRefresh\": true,\n\t\"navigationBarTitleText\": \"我的\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/my/index/my_index.wxml",
    "content": "<view class=\"main {{skin.IS_SUB?'sub-margin-bottom':''}}\">\n\n\t<!--top area begin-->\n\t<view class=\"upside upside-shadow\"  bindtap=\"url\" data-url=\"{{user?'../edit/my_edit':'../reg/my_reg'}}\"> \n\t\t<view class=\"user-bar\">\n\t\t\t<view class=\"detail\">\n\t\t\t\t<view class=\"name text-cut\">{{user?user.USER_NAME:'欢迎回来~~~'}}</view>\n\t\t\t\t<view class=\"desc\"> \n\t\t\t\t\t<view wx:if=\"{{user&&user.USER_STATUS==9}}\" class=\"tag small radius bg-purple light\">已禁用</view>\n\t\t\t\t\t<view wx:elif=\"{{user&&user.USER_STATUS==0}}\" class=\"tag small radius bg-orange light\">已注册，待审核</view>\n\t\t\t\t\t<view wx:elif=\"{{user&&user.USER_STATUS==8}}\" class=\"tag small radius bg-red light\">审核未通过，请修改资料</view>\n\t\t\t\t\t<view wx:else class=\"text-cut\">{{user?'欢迎回来~~~':'马上注册，使用更多功能'}}</view>\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t\t<view class=\"avatar\">\n\t\t\t\t<image mode=\"aspectFit\" src=\"../../../images/tabbar/my_cur.png\" />\n\t\t\t</view>\n\t\t</view>\n\t</view>\n\t<!--top area end-->\n\n\t<!--down area begin-->\n\t<view class=\"down padding-project\"> \n\t\t \n\t\t<!--base begin -->\n\t\t<view class=\"comm-list menu card-project shadow-project\">\n\t\t\t<view wx:if=\"{{user&&user.USER_STATUS!=9}}\" class=\"item arrow\" bindtap=\"url\" data-url=\"../edit/my_edit\">\n\t\t\t\t<view class=\"content\">\n\t\t\t\t\t<text class=\"icon-edit my-icon-project text-green\"></text> \n\t\t\t\t\t<text class=\"text-black\">修改我的个人资料</text>\n\t\t\t\t</view>\n\t\t\t</view>\n\n\t\t\t<view class=\"item arrow\" bindtap=\"url\" data-url=\"../../meet/my_join_list/meet_my_join_list\">\n\t\t\t\t<view class=\"content\">\n\t\t\t\t\t<text class=\"icon-remind text-red\"></text>\n\t\t\t\t\t<text class=\"text-black\">我的预约</text>\n\t\t\t\t</view>\n\t\t\t</view> \n\n\t\t\t<view class=\"item arrow\" bindtap=\"url\" data-url=\"../fav/my_fav\">\n\t\t\t\t<view class=\"content\">\n\t\t\t\t\t<text class=\"icon-favor my-icon-project text-olive\"></text>\n\t\t\t\t\t<text class=\"text-black\">我的收藏</text>\n\t\t\t\t</view>\n\t\t\t</view>\n\n\t\t\t<view class=\"item arrow\" bindtap=\"url\" data-url=\"../foot/my_foot\">\n\t\t\t\t<view class=\"content\">\n\t\t\t\t\t<text class=\"icon-footprint my-icon-project text-orange\"></text>\n\t\t\t\t\t<text class=\"text-black\">历史浏览</text>\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t</view>\n\t\t<!--base end -->\n\n\t\t<!--sys begin -->\n\t\t<view class=\"comm-list menu card-project shadow-project\">\n\n\t\t\t<view wx:if=\"{{skin.IS_SUB}}\" class=\"item arrow\" bindtap=\"bindSetTap\">\n\t\t\t\t<view class=\"content\">\n\t\t\t\t\t<text class=\"icon-settings my-icon-project text-grey\"></text>\n\t\t\t\t\t<text class=\"text-red text-bold \">系统后台管理<text class=\"text-grey text-normal\">（点击试用）</text></text>\n\t\t\t\t</view>\n\t\t\t</view>\n\n\t\t\t<view class=\"item arrow\" bindtap=\"url\" data-url=\"../../about/index/about_index?key=SETUP_CONTENT_ABOUT\">\n\t\t\t\t<view class=\"content\">\n\t\t\t\t\t<text class=\"icon-service my-icon-project text-purple\"></text>\n\t\t\t\t\t<text class=\"text-black\">关于我们</text>\n\t\t\t\t</view>\n\t\t\t</view> \n \n\t\t\t<view wx:if=\"{{skin.IS_SUB}}\" class=\"item arrow\" bindtap=\"url\" data-url=\"/pages/home/about/home_about\">\n\t\t\t\t<view class=\"content\">\n\t\t\t\t\t<text class=\"icon-phone my-icon-project text-cyan\"></text>\n\t\t\t\t\t<text class=\"text-orange\">联系作者了解更多详情</text>\n\t\t\t\t</view>\n\t\t\t</view> \n\n\n\t\t\t<view wx:if=\"{{!skin.IS_SUB}}\" class=\"item arrow\" bindtap=\"bindSetTap\">\n\t\t\t\t<view class=\"content\">\n\t\t\t\t\t<text class=\"icon-settings my-icon-project text-grey\"></text>\n\t\t\t\t\t<text class=\"text-black\">设置</text>\n\t\t\t\t</view>\n\t\t\t</view>\n\n\t\t</view>\n\t\t<!--sys end -->\n\n\t</view>\n\t<!--down area end-->\n\n</view>\n<view style=\"height:100rpx\"></view>\n\n\n\n<block wx:if=\"{{skin.IS_SUB}}\">\n\t<import src=\"../../tpls/menu_tpl.wxml\" />\n\t<template is=\"menuTpl\" data=\"{{curMenu:'my_index',returnHome:false}}\" />\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/my/index/my_index.wxss",
    "content": "@import \"../../../style/skin.wxss\";\n\n\n\n.main {\n\tpadding: 0;\n}\n\n.main .upside {\n\tbackground-image: linear-gradient( #00C176, #08dc64);\n\theight: 250rpx;\n\twidth: 100%;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tposition: relative;\n\toverflow: hidden; \n\tborder-bottom-left-radius: 80rpx;\n}\n\n.main .upside .upImg {\n\theight: inherit;\n\twidth: 100%;\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n}\n\n.main .upside .user-bar {\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: flex-start;\n\tpadding-left: 40rpx;\n\tz-index: 9999;\n}\n\n.main .upside .user-bar .avatar {\n\theight: 120rpx;\n\twidth: 120rpx;\n\tborder: 0rpx;\n\tfont-size: 80rpx;\n\tborder-radius: 50%;\n\tbackground-color: #f8f8f8;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.main .upside .user-bar .avatar image {\n\theight: 70rpx;\n\twidth: 70rpx;\n}\n\n.main .upside .user-bar .detail {\n\twidth: 500rpx;\n\tmargin-left: 0rpx;\n\tmargin-right: 40rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: flex-start;\n\talign-items: flex-start;\n\tcolor: #fff;\n\tbox-sizing: border-box;\n}\n\n.main .upside .user-bar .detail .name {\n\twidth: 100%;\n\tfont-size: 36rpx;\n\tfont-weight: bold;\n\tcolor: #fff;\n}\n\n.main .upside .user-bar .detail .desc {\n\twidth: 100%;\n\tfont-size: 26rpx;\n\tmargin-top: 15rpx;\n\tcolor: #fff;\n}\n\n.main .down {\n\tbox-sizing: border-box;\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n\tpadding: 20rpx 0rpx !important;\n\tmargin-top: 20rpx;\n}\n\n\n.main .down .data {\n\tdisplay: flex;\n\tjustify-content: space-between;\n\talign-items: center;\n\theight: 150rpx;\n\tpadding: 0rpx 40rpx 0rpx 40rpx;\n\twidth: 100%;\n\tbackground-color: #fff;\n}\n\n.main .down .data view {\n\twidth: 150rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.main .down .data view .num {\n\tfont-size: 32rpx;\n\tfont-weight: bold;\n}\n\n.main .down .data view .txt {\n\tfont-size: 24rpx;\n\tcolor: #aaa;\n}\n\n.main .comm-list .item.arrow::before,\n.main .comm-list .item .content .item-icon {\n\tcolor: #0E9489;\n}\n\n.main .down .today {\n\twidth: 100%;\n\tpadding: 30rpx 30rpx 20rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: center;\n\tbackground-color: #fff;\n}\n\n.main .down .today .title {\n\twidth: 100%;\n\ttext-align: left;\n\tfont-size: 32rpx;\n\tfont-weight: bold;\n\tline-height: 1.2;\n\tmargin-bottom: 30rpx;\n}\n\n.main .down .today .list {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: flex-start;\n\tjustify-content: flex-start;\n}\n\n.main .down .today .list .item {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: flex-start;\n\tjustify-content: center;\n\tpadding: 15rpx 0;\n\tborder-bottom: 1rpx dashed #ccc;\n}\n\n.main .down .today .list .item:last-child {\n\tmargin-bottom: 0rpx;\n\tborder: 0;\n}\n\n.main .down .today .list .item .time {\n\tfont-size: 28rpx;\n\twidth: 100%;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tline-height: 2;\n\tfont-weight: bold;\n}\n\n.main .down .today .list .item .time .status {\n\tfont-weight: normal;\n\tfont-size: 27rpx;\n}\n\n.main .down .today .list .item .project {\n\tcolor: #666;\n\tfont-size: 24rpx;\n\twidth: 100%;\n\ttext-align: left;\n}\n\n.main .site-footer {\n\twidth: 100%;\n\talign-self: flex-end;\n}\n \n.main .upside-shadow {\n\tbox-shadow: unset;\n}\n\n.main .upside-shadow:before,\n.main .upside-shadow:after {\n\tposition: absolute;\n\tcontent: \"\";\n\ttop: 20rpx;\n\tbottom: 30rpx;\n\tleft: 20rpx;\n\twidth: 50%;\n\tbox-shadow: 0 30rpx 20rpx rgba(0, 0, 0, 0.2);\n\ttransform: rotate(-3deg);\n\tz-index: -1;\n}\n\n.main .upside-shadow:after {\n\tright: 20rpx;\n\tleft: auto;\n\ttransform: rotate(3deg);\n}\n\n.down .comm-list.menu.card-project {\n\tborder-radius: 0rpx !important;\n}\n\n.shadow-project {\n\tbox-shadow: unset;\n}\n "
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/my/reg/my_reg.js",
    "content": "const pageHelper = require('../../../../../helper/page_helper.js');\nconst helper = require('../../../../../helper/helper.js');\nconst cloudHelper = require('../../../../../helper/cloud_helper.js');\nconst validate = require('../../../../../helper/validate.js');\nconst ProjectBiz = require('../../../biz/project_biz.js');\nconst projectSetting = require('../../../public/project_setting.js');\nconst setting = require('../../../../../setting/setting.js');\nconst PassportBiz = require('../../../../../comm/biz/passport_biz.js');\n\nPage({\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false,\n\t\tisEdit: false,\n\n\t\tmobileCheck: setting.MOBILE_CHECK\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tProjectBiz.initPage(this);\n\n\t\tif (options && options.retUrl)\n\t\t\tthis.data.retUrl = decodeURIComponent(options.retUrl);\n\n\t\tawait this._loadDetail();\n\t},\n\n\t_loadDetail: async function (e) {\n\t\tlet opts = {\n\t\t\ttitle: 'bar'\n\t\t}\n\t\tlet user = await cloudHelper.callCloudData('passport/my_detail', {}, opts);\n\t\tif (user) {\n\t\t\treturn wx.redirectTo({ url: '../index/my_index' });\n\t\t}\n\n\t\tthis.setData({\n\t\t\tisLoad: true,\n\n\t\t\tfields: projectSetting.USER_FIELDS,\n\n\t\t\tformName: '',\n\t\t\tformMobile: '',\n\t\t\tformForms: []\n\t\t});\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\t},\n\n\t/**\n\t * 页面上拉触底事件的处理函数\n\t */\n\tonReachBottom: function () {\n\n\t},\n\n\tbindGetPhoneNumber: async function (e) {\n\t\tPassportBiz.getPhone(e, this);\n\t},\n\n\n\tbindSubmitTap: async function (e) {\n\t\ttry {\n\t\t\tlet data = this.data;\n\n\t\t\t// 数据校验 \n\t\t\tdata = validate.check(data, PassportBiz.CHECK_FORM, this);\n\t\t\tif (!data) return;\n\n\t\t\tlet forms = this.selectComponent(\"#cmpt-form\").getForms(true);\n\t\t\tif (!forms) return;\n\t\t\tdata.forms = forms;\n\n\t\t\tdata.status = projectSetting.USER_REG_CHECK ? 0 : 1;\n\n\t\t\tlet opts = {\n\t\t\t\ttitle: '提交中'\n\t\t\t}\n\t\t\tawait cloudHelper.callCloudSumbit('passport/register', data, opts).then(result => {\n\t\t\t\tif (result && helper.isDefined(result.data.token) && result.data.token) {\n\n\t\t\t\t\t// 用户需要审核，不能登录\n\t\t\t\t\tif (!projectSetting.USER_REG_CHECK) PassportBiz.setToken(result.data.token);\n\n\t\t\t\t\tlet callback = () => {\n\t\t\t\t\t\tif (this.data.retUrl == 'back')\n\t\t\t\t\t\t\twx.navigateBack();\n\t\t\t\t\t\telse if (this.data.retUrl)\n\t\t\t\t\t\t\twx.redirectTo({\n\t\t\t\t\t\t\t\turl: this.data.retUrl,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\twx.reLaunch({ url: '../index/my_index' });\n\t\t\t\t\t}\n\n\t\t\t\t\tif (projectSetting.USER_REG_CHECK)\n\t\t\t\t\t\tpageHelper.showModal('注册完成，等待系统审核', '温馨提示', callback);\n\t\t\t\t\telse\n\t\t\t\t\t\tpageHelper.showSuccToast('注册成功', 1500, callback);\n\t\t\t\t}\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.error(err);\n\t\t}\n\t}\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/my/reg/my_reg.json",
    "content": "{\n\t\"usingComponents\": { \n\t\t\"cmpt-form-show\": \"/cmpts/public/form/form_show/form_show_cmpt\"  \n\t},\n\t\"enablePullDownRefresh\": true, \n\t\"navigationBarTitleText\": \"注册\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/my/reg/my_reg.wxml",
    "content": "<view wx:if=\"{{isLoad===null}}\" class=\"margin-top load notexist text-l load-project\"></view>\n<view wx:if=\"{{isLoad===false}}\" class=\"margin-top load loading text-l load-project\"></view>\n\n<view wx:if=\"{{isLoad}}\" class=\"main padding-project\">\n\t<include src=\"../edit/user_form.wxml\" /> \n\t<button bindtap=\"bindSubmitTap\" class=\"btn-base btn-project\">提交注册</button>\n</view>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/my/reg/my_reg.wxss",
    "content": "@import \"../../../style/skin.wxss\"; \n.submit-line {\n\twidth: 100%;\n}\n\n.form-group .mobile {\n\tflex: 1;\n\ttext-align: left;\n}\n\n.submit-line {\n\twidth: 100%;\n}\n\n.form-group .mobile {\n\tflex: 1;\n\ttext-align: left;\n\tfont-size:28rpx;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/news/cate1/news_cate1.js",
    "content": "let behavior = require('../../../../../comm/behavior/news_index_bh.js');\nconst ProjectBiz = require('../../../biz/project_biz.js');\nconst projectSetting = require('../../../public/project_setting.js');\n\n\nPage({\n\tbehaviors: [behavior],\n\n\tonLoad: function (options) {\n\t\tProjectBiz.initPage(this);\n\t\tthis._setCate(projectSetting.NEWS_CATE, options, 1);\n\n\t},\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/news/cate1/news_cate1.json",
    "content": "{\n\t\"usingComponents\": { \n\t}, \n\t\"disableScroll\": true, \n\t\"navigationBarTitleText\": \"资讯\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/news/cate1/news_cate1.wxml",
    "content": "<import src=\"../../../../../tpls/project/news_index_tpl.wxml\" />\n<template is=\"newsIndexTpl\" data=\"{{showUp:false,upImg:'',dataList,_params,search:search||'',listMode:listMode,isTotalMenu:true,sortMenus:sortMenus||[],sortItems:sortItems||[]}}\" />\n\n<block wx:if=\"{{skin.IS_SUB}}\">\n\t<import src=\"../../tpls/menu_tpl.wxml\" />\n\t<template is=\"menuTpl\" data=\"{{curMenu:'news_cate1',returnHome:false}}\" />\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/news/cate1/news_cate1.wxss",
    "content": "@import \"../../../../../style/public/comm_box_list.wxss\";\n@import \"../../../style/skin.wxss\"; "
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/news/cate2/news_cate2.js",
    "content": "let behavior = require('../../../../../comm/behavior/news_index_bh.js');\nconst ProjectBiz = require('../../../biz/project_biz.js');\nconst projectSetting = require('../../../public/project_setting.js');\n\n\nPage({\n\tbehaviors: [behavior],\n\n\tonLoad: function (options) {\n\t\tProjectBiz.initPage(this);\n\t\tthis._setCate(projectSetting.NEWS_CATE, options, 3);\n\n\t},\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/news/cate2/news_cate2.json",
    "content": "{\n\t\"usingComponents\": { \n\t}, \n\t\"disableScroll\": true, \n\t\"navigationBarTitleText\": \"资讯\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/news/cate2/news_cate2.wxml",
    "content": "<import src=\"../../../../../tpls/project/news_index_tpl.wxml\" />\n<template is=\"newsIndexTpl\" data=\"{{showUp:false,upImg:'',dataList,_params,search:search||'',listMode:listMode,isTotalMenu:true}}\" />\n\n<block wx:if=\"{{skin.IS_SUB}}\">\n\t<import src=\"../../tpls/menu_tpl.wxml\" />\n\t<template is=\"menuTpl\" data=\"{{curMenu:'news_cate1',returnHome:false}}\" />\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/news/cate2/news_cate2.wxss",
    "content": "@import \"../../../../../style/public/comm_box_list.wxss\";\n@import \"../../../style/skin.wxss\";  "
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/news/detail/news_detail.js",
    "content": "const cloudHelper = require('../../../../../helper/cloud_helper.js');\nconst pageHelper = require('../../../../../helper/page_helper.js');\nconst ProjectBiz = require('../../../biz/project_biz.js'); \n\nPage({\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false, \n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tProjectBiz.initPage(this);\n\n\t\tif (!pageHelper.getOptions(this, options)) return;\n\n\t\tthis._loadDetail();\n\n\t},\n\n\t_loadDetail: async function () {\n\t\tlet id = this.data.id;\n\t\tif (!id) return;\n\n\t\tlet params = {\n\t\t\tid,\n\t\t};\n\t\tlet opt = {\n\t\t\ttitle: 'bar'\n\t\t};\n\t\tlet news = await cloudHelper.callCloudData('news/view', params, opt);\n\t\tif (!news) {\n\t\t\tthis.setData({\n\t\t\t\tisLoad: null\n\t\t\t})\n\t\t\treturn;\n\t\t}\n\n\t\tthis.setData({\n\t\t\tisLoad: true,\n\t\t\tnews,\n\t\t}); \n\n\t}, \n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\t\tawait this._loadDetail();\n\t\twx.stopPullDownRefresh();\n\t},\n\n\t/**\n\t * 页面上拉触底事件的处理函数\n\t */\n\tonReachBottom: function () {\n\n\t},\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tonPageScroll: function (e) {\n\t\t// 回页首按钮\n\t\tpageHelper.showTopBtn(e, this);\n\n\t},\n\n\t/**\n\t * 用户点击右上角分享\n\t */\n\tonShareAppMessage: function (res) {\n\t\treturn {\n\t\t\ttitle: this.data.news.NEWS_TITLE,\n\t\t\timageUrl: this.data.news.NEWS_PIC[0]\n\t\t} \n\t}\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/news/detail/news_detail.json",
    "content": "{\n\t\"usingComponents\": { \n\t\t\"cmpt-detail\": \"/cmpts/biz/detail/detail_cmpt\"\n\t},\n\t\"enablePullDownRefresh\": true, \n\t\"navigationBarTitleText\": \"详细内容\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/news/detail/news_detail.wxml",
    "content": "<view wx:if=\"{{isLoad===null}}\" class=\"margin-top load notexist text-l load-project\"></view>\n<view wx:if=\"{{isLoad===false}}\" class=\"margin-top load loading text-l load-project\"></view>\n\n<block wx:if=\"{{isLoad}}\">\n\t<view class=\"main padding-project\">\n\t\t<view class=\"article-box margin-top-xs\">\n\t\t\t<!-- article content begin -->\n\t\t\t<view class=\"article card-project shadow-project\">\n\t\t\t\t<view class=\"title\"><text user-select=\"true\">{{news.NEWS_TITLE}}</text></view>\n\t\t\t\t<view class=\"time\"> {{news.NEWS_ADD_TIME}} {{news.NEWS_CATE_NAME}} </view> \n\n\n\t\t\t\t<block wx:for=\"{{news.NEWS_CONTENT}}\" wx:key=\"key\">\n\t\t\t\t\t<view class=\"content\" wx:if=\"{{item.type=='text'}}\">\n\t\t\t\t\t\t<text user-select=\"{{true}}\">{{item.val}}</text>\n\t\t\t\t\t</view>\n\n\t\t\t\t\t<view class=\"pics\" wx:if=\"{{item.type=='img'}}\">\n\t\t\t\t\t\t<image bindtap=\"url\" data-type='img' data-url=\"{{item.val}}\" show-menu-by-longpress=\"{{true}}\" class=\"loading\" mode='widthFix' lazy-load=\"true\" src=\"{{item.val}}\">\n\t\t\t\t\t\t</image>\n\t\t\t\t\t</view>\n\t\t\t\t</block>\n\t\t\t\t<!-- article content end -->\n\n\t\t\t</view>\n\t\t\t<!-- article content end -->\n\n\t\t</view>\n\n\t</view> \n\n\t<cmpt-detail mode=\"mode1\" topBtnShow=\"{{topBtnShow}}\" oid=\"{{news._id}}\" cate=\"{{news.NEWS_CATE_NAME}}\" title=\"{{news.NEWS_TITLE}}\" cover=\"{{news.NEWS_PIC[0]}}\" qr=\"{{news.NEWS_QR}}\" desc=\"查看详情\"  bg=\"{{skin.PROJECT_COLOR}}\"></cmpt-detail>\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/news/detail/news_detail.wxss",
    "content": "@import \"../../../../../style/public/detail.wxss\"; \n@import \"../../../style/skin.wxss\"; "
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/news/index/news_index.js",
    "content": "let behavior = require('../../../../../comm/behavior/news_index_bh.js');\nconst ProjectBiz = require('../../../biz/project_biz.js');\nconst projectSetting = require('../../../public/project_setting.js');\n\nPage({\n\n\tbehaviors: [behavior], \n\n\tonLoad: function (options) {\n\t\tProjectBiz.initPage(this);\n\t\tthis._setCate(projectSetting.NEWS_CATE, options);\n\n\t},\n\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/news/index/news_index.json",
    "content": "{\n\t\"usingComponents\": { \n\t}, \n\t\"disableScroll\": true, \n\t\"navigationBarTitleText\": \"资讯\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/news/index/news_index.wxml",
    "content": "<import src=\"../../../../../tpls/project/news_index_tpl.wxml\" />\n<template is=\"newsIndexTpl\" data=\"{{showUp:false,upImg:'',dataList,_params,search,listMode:listMode,isTotalMenu:true}}\" />"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/news/index/news_index.wxss",
    "content": "@import \"../../../../../style/public/comm_box_list.wxss\";\n@import \"../../../style/skin.wxss\"; "
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/product/detail/product_detail.js",
    "content": "const cloudHelper = require('../../../../../helper/cloud_helper.js');\nconst pageHelper = require('../../../../../helper/page_helper.js');\nconst ProjectBiz = require('../../../biz/project_biz.js');\n\nPage({\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tisLoad: false,\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面加载\n\t */\n\tonLoad: async function (options) {\n\t\tProjectBiz.initPage(this);\n\n\t\tif (!pageHelper.getOptions(this, options)) return;\n\n\t\tthis._loadDetail();\n\n\t},\n\n\t_loadDetail: async function () {\n\t\tlet id = this.data.id;\n\t\tif (!id) return;\n\n\t\tlet params = {\n\t\t\tid,\n\t\t};\n\t\tlet opt = {\n\t\t\ttitle: 'bar'\n\t\t};\n\t\tlet product = await cloudHelper.callCloudData('product/view', params, opt);\n\t\tif (!product) {\n\t\t\tthis.setData({\n\t\t\t\tisLoad: null\n\t\t\t})\n\t\t\treturn;\n\t\t}\n\n\t\tthis.setData({\n\t\t\tisLoad: true,\n\t\t\tproduct,\n\t\t});\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () { },\n\n\t/**\n\t * 页面相关事件处理函数--监听用户下拉动作\n\t */\n\tonPullDownRefresh: async function () {\n\t\tawait this._loadDetail();\n\t\twx.stopPullDownRefresh();\n\t},\n\n\t/**\n\t * 页面上拉触底事件的处理函数\n\t */\n\tonReachBottom: function () { },\n\n\turl: function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tonPageScroll: function (e) {\n\t\t// 回页首按钮\n\t\tpageHelper.showTopBtn(e, this);\n\n\t},\n\n\tonShareAppMessage: function (res) {\n\t\treturn {\n\t\t\ttitle: this.data.product.PRODUCT_TITLE,\n\t\t\timageUrl: this.data.product.PRODUCT_OBJ.cover[0]\n\t\t}\n\t}\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/product/detail/product_detail.json",
    "content": "{\n\t\"usingComponents\": { \n\t\t\"cmpt-swiper\": \"/cmpts/public/swiper/swiper_cmpt\",\n\t\t\"cmpt-detail\": \"/cmpts/biz/detail/detail_cmpt\"\n\t},\n\t\"enablePullDownRefresh\": true, \n\t\"navigationBarTitleText\": \"景点详情\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/product/detail/product_detail.wxml",
    "content": "<view wx:if=\"{{isLoad===null}}\" class=\"margin-top load notexist text-l load-project\"></view>\n<view wx:if=\"{{isLoad===false}}\" class=\"margin-top load loading text-l load-project\"></view>\n\n<block wx:if=\"{{isLoad}}\">\n\t<cmpt-swiper mode=\"aspectFill\" indicatorActiveColor=\"#00C176\" height=\"420\" images=\"{{product.PRODUCT_OBJ.album}}\" />\n\t<view class=\"main\">\n\t\t<view class=\"header shadow-project\">\n\t\t\t<view class=\"line1\">{{product.PRODUCT_TITLE}}</view>\n\t\t\t<view class=\"line2\" wx:if=\"{{product.PRODUCT_OBJ.time}}\"><text class=\"icon-time margin-right-xxs\"></text>{{product.PRODUCT_OBJ.time}}</view>\n\t\t\t<view class=\"line3\" wx:if=\"{{product.PRODUCT_OBJ.address}}\"><text class=\"icon-location margin-right-xxs\"></text>{{product.PRODUCT_OBJ.address}}</view>\n\t\t</view>\n\t\t<view class=\"content shadow-project\">\n\t\t\t<view class=\"item\">\n\t\t\t\t<view class=\"title\">简介</view>\n\t\t\t\t<view class=\"desc\"><text user-select>{{product.PRODUCT_OBJ.desc}}</text>\n\t\t\t\t</view>\n\t\t\t</view>\n\n\t\t\t<view class=\"item\" wx:if=\"{{product.PRODUCT_OBJ.traffic}}\">\n\t\t\t\t<view class=\"title\">交通攻略</view>\n\t\t\t\t<view class=\"desc\"><text user-select>{{product.PRODUCT_OBJ.traffic}}</text>\n\t\t\t\t</view>\n\t\t\t</view>\n\n\t\t\t<view class=\"item\" wx:if=\"{{product.PRODUCT_OBJ.ticket}}\">\n\t\t\t\t<view class=\"title\">门票攻略</view>\n\t\t\t\t<view class=\"desc\"><text user-select>{{product.PRODUCT_OBJ.ticket}}</text>\n\t\t\t\t</view>\n\t\t\t</view>\n\n\n\t\t\t<view class=\"item\" wx:if=\"{{product.PRODUCT_OBJ.other}}\">\n\t\t\t\t<view class=\"title\">其他信息</view>\n\t\t\t\t<view class=\"desc\"><text user-select>{{product.PRODUCT_OBJ.other}}</text>\n\t\t\t\t</view>\n\t\t\t</view>\n\n\n\t\t</view>\n\t</view>\n\n\t<cmpt-detail mode=\"mode1\" topBtnShow=\"{{topBtnShow}}\" oid=\"{{product._id}}\" cate=\"{{product.PRODUCT_CATE_NAME}}\" title=\"{{product.PRODUCT_TITLE}}\" cover=\"{{product.PRODUCT_OBJ.cover[0]}}\" qr=\"{{product.PRODUCT_QR}}\" desc=\"查看景点详情\" bg=\"{{skin.PROJECT_COLOR}}\">\n\t<!--\t<button open-type=\"contact\" show-message-card=\"{{true}}\" send-message-title=\"景点咨询-{{product.PRODUCT_TITLE}}\" class=\"clearbtn cmpt-biz-detail-mode2-btn\">立即咨询</button>-->\n\t</cmpt-detail>\n\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/product/detail/product_detail.wxss",
    "content": "@import \"../../../style/skin.wxss\";\n\n.main {\n\twidth: 100%;\n\tpadding: 0;\n}\n\n.header {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tbackground-color: #fff;\n\tpadding: 20rpx 30rpx;\n}\n\n.header .line1 {\n\twidth: 100%;\n\tfont-weight: bold;\n\tfont-size: 36rpx;\n\tcolor: #000;\n\tmargin-bottom: 15rpx;\n}\n\n.header .line2,\n.header .line3 {\n\twidth: 100%;\n\tfont-size: 28rpx;\n\tcolor: #333;\n\tmargin-bottom: 10rpx;\n\tpadding: 10rpx 0rpx;\n}\n\n.header .line2 {\n\tborder-bottom: 1rpx solid #eee;\n}\n\n\n.content {\n\tmargin-top: 20rpx;\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tbackground-color: #fff;\n\tpadding: 20rpx 30rpx;\n\tmargin-bottom: 200rpx;\n}\n\n.content .item {\n\tpadding: 0rpx 0;\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n}\n\n\n.content .item .title {\n\twidth: 100%;\n\tfont-size: 30rpx;\n\tcolor: #000;\n\tfont-weight: bold;\n\tborder-bottom: 1rpx solid #eee;\n\tpadding: 20rpx 0;\n\tmargin-bottom: 20rpx;\n}\n\n.content .item .desc {\n\twidth: 100%;\n\tfont-size: 28rpx;\n\tcolor: #666;\n\tmargin-bottom: 40rpx;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/product/index/product_index.js",
    "content": "const ProjectBiz = require('../../../biz/project_biz.js');\nconst pageHelper = require('../../../../../helper/page_helper.js');\nconst ProductBiz = require('../../../biz/product_biz.js');\n\nPage({\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\n\t},\n\n\t/**\n\t\t * 生命周期函数--监听页面加载\n\t\t */\n\tonLoad: async function (options) {\n\t\tProjectBiz.initPage(this);\n\n\t\tthis._getSearchMenu();\n\n\t\tif (options && options.id) {\n\t\t\tthis.setData({\n\t\t\t\t_params: {\n\t\t\t\t\tsortType: 'cateId',\n\t\t\t\t\tsortVal: options.id,\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tthis.setData({\n\n\t\t\t\t_params: {\n\t\t\t\t\tsortType: 'cateId',\n\t\t\t\t\tsortVal: '',\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面初次渲染完成\n\t */\n\tonReady: function () { },\n\n\t/**\n\t * 生命周期函数--监听页面显示\n\t */\n\tonShow: async function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面隐藏\n\t */\n\tonHide: function () {\n\n\t},\n\n\t/**\n\t * 生命周期函数--监听页面卸载\n\t */\n\tonUnload: function () {\n\n\t},\n\n\turl: async function (e) {\n\t\tpageHelper.url(e, this);\n\t},\n\n\tbindCommListCmpt: function (e) {\n\t\tpageHelper.commListListener(this, e);\n\t},\n\n\n\tonShareAppMessage: function () {\n\n\t},\n\n\t_getSearchMenu: function () {\n\t\tProductBiz.setCateTitle();\n\n\t\tlet sortItem1 = [{ label: '全部', type: 'cateId', value: '' }];\n\n\t\tsortItem1 = sortItem1.concat(ProductBiz.getCateList());\n\n\t\tlet sortItems = [\n\t\t\t{ label: '排序', type: '', value: '' },\n\t\t\t{ label: '最新', type: 'sort', value: 'PRODUCT_ADD_TIME|desc' },\n\t\t\t{ label: '最热', type: 'sort', value: 'PRODUCT_VIEW_CNT|desc' },\n\t\t\t{ label: '推荐指数', type: 'sort', value: 'PRODUCT_OBJ.star|desc' },\n\t\t];\n\t\tlet sortMenus = sortItem1;\n\n\t\tthis.setData({\n\t\t\tsortItems: [sortItems],\n\t\t\tsortMenus\n\t\t})\n\n\t}\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/product/index/product_index.json",
    "content": "{\n\t\"usingComponents\": { \n\t}, \n\t\"disableScroll\": true, \n\t\"navigationBarTitleText\": \"景点\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/product/index/product_index.wxml",
    "content": "<wxs module=\"tools\"> \n\tmodule.exports = {\n\t\tparseInt: parseInt,\n\t}\n</wxs>\n\n<view wx:if=\"{{!_params}}\" class=\"margin-top load loading text-l load-project\"></view>\n<block wx:else>\n\t<cmpt-comm-list type=\"product-list\" sortMenusDefaultIndex=\"0\" _params=\"{{_params}}\" search=\"{{search}}\" _menus=\"{{sortMenus}}\" _items=\"{{sortItems}}\" route=\"product/list\" topBottom=\"120\" placeholder=\"搜索\" bind:list=\"bindCommListCmpt\">\n\n\t\t<view class=\"product-list\">\n\t\t\t<view class=\"item\" wx:for=\"{{dataList.list}}\" wx:key=\"key\" bindtap=\"url\" data-url=\"../detail/product_detail?id={{item._id}}\">\n\t\t\t\t<image mode=\"aspectFill\" lazy-load=\"{{true}}\" class=\"loading\" src=\"{{item.PRODUCT_OBJ.cover[0]}}\"> <text class=\"star\"><text wx:key=\"key1\" wx:for=\"{{tools.parseInt(item.PRODUCT_OBJ.star)}}\" class=\"icon-favorfill\" /></text></image>\n\t\t\t\t<view class=\"right\">\n\t\t\t\t\t<view class=\"line1 content-cut-one\">{{item.PRODUCT_TITLE}}</view>\n\t\t\t\t\t<view class=\"line3 content-cut-two\">{{item.PRODUCT_OBJ.desc}}</view>\n\t\t\t\t</view>\n\n\t\t\t</view>\n\t\t</view>\n\n\t\t<!--load begin-->\n\t\t<import src=\"../../../../../tpls/public/list_load_tpl.wxml\" />\n\t\t<template is=\"listLoadTpl\" data=\"{{skin:'load-project',dataList}}\" />\n\t\t<!--load end-->\n\n\t</cmpt-comm-list>\n\n\n\t<block wx:if=\"{{skin.IS_SUB}}\">\n\t\t<import src=\"../../tpls/menu_tpl.wxml\" />\n\t\t<template is=\"menuTpl\" data=\"{{curMenu:'product_index',returnHome:false}}\" />\n\t</block>\n\n</block>"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/product/index/product_index.wxss",
    "content": "@import \"../../../style/skin.wxss\";\n\n\n\n.product-list {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: flex-start;\n\tjustify-content: flex-start;\n\tpadding: 10rpx 0rpx;\n}\n\n.product-list .item {\n\twidth: 100%;\n\tdisplay: flex;\n\talign-items: flex-start;\n\tjustify-content: flex-start;\n\tposition: relative;\n\tpadding: 15rpx 0;\n\tbackground-color: #fff;\n\tmargin-bottom: 10rpx;\n}\n\n.product-list .item image {\n\twidth: 200rpx;\n\theight: 150rpx;\n\tborder-radius: 10rpx;\n\tmargin-right: 20rpx;\n\tmargin-left: 20rpx;\n\tposition: relative;\n\toverflow: hidden;\n}\n\n.product-list .item .star {\n\tposition: absolute;\n\ttop: 5rpx;\n\tleft: 5rpx;\n\tcolor: #fbbd08;  \n\tfont-size: 22rpx;\n}\n\n\n.product-list .item .right {\n\tflex: 1;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: flex-start;\n\tjustify-content: flex-start;\n\theight: 160rpx;\n}\n\n.product-list .item .right .line1 {\n\twidth: 100%;\n\tfont-size: 32rpx;\n\tcolor: #000;\n\tfont-weight: bold;\n\tmargin-bottom: 10rpx;\n}\n\n.product-list .item .right .line2 {\n\twidth: 100%;\n\tfont-size: 34rpx;\n\tcolor: var(--projectColor);\n\tfont-weight: bold;\n\tflex: 1;\n\tpadding-top: 10rpx;\n}\n\n\n.product-list .item .right .line3 {\n\tfont-size: 28rpx;\n\tfont-weight: normal;\n\tcolor: #666;\n\tline-height: 1.5;\n\twidth: 90%;\n}\n\n\n.product-list .item .appt {\n\tposition: absolute;\n\tbottom: 20rpx;\n\tright: 15rpx;\n\twidth: 130rpx;\n\tbackground-color: var(--projectColor);\n\tline-height: 2.1;\n\tborder-radius: 25rpx;\n\ttext-align: center;\n\tcolor: #fff;\n\tfont-size: 24rpx;\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/search/search.js",
    "content": "const behavior = require('../../../../comm/behavior/search_bh.js');\nconst ProjectBiz = require('../../biz/project_biz.js');\nconst pageHelper = require('../../../../helper/page_helper.js');\n\nPage({\n\n\tbehaviors: [behavior],\n\n\tonReady: function () {\n\t\tProjectBiz.initPage(this);\n\n\n\t\tlet curPage = pageHelper.getPrevPage(1);\n\t\tif (!curPage) return;\n\t\tif (curPage.options && curPage.options.source == 'admin') {\n\t\t\twx.setNavigationBarColor({ //管理端顶部\n\t\t\t\tbackgroundColor: '#2499f2',\n\t\t\t\tfrontColor: '#ffffff',\n\t\t\t});\n\t\t}\n\n\t},\n\n})"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/search/search.json",
    "content": "{\n\t\"usingComponents\": { \n\t},  \n\t\"navigationBarTitleText\": \"搜索\"\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/search/search.wxml",
    "content": "<include src=\"../../../../tpls/project/search_tpl.wxml\" />"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/search/search.wxss",
    "content": "@import \"../../style/skin.wxss\"; \n@import \"../../../../style/project/search_style.wxss\";"
  },
  {
    "path": "miniprogram/projects/TRIP1/pages/tpls/menu_tpl.wxml",
    "content": "<template name=\"menuTpl\"> \n\t<view class=\"tab-bar\" >   \n\t\t<view wx:if=\"{{returnHome}}\" class=\"tab-bar-home\" bindtap=\"url\" data-type=\"relaunch\"\n\t\t\tdata-url=\"/pages/home/index/home_index\">\n\t\t\t<text class=\"tab-bar-home-text icon-homefill text-grey\"></text>\n\t\t</view>\n\n\t\t<view class=\"tab-bar-border\"></view>\n\t\t<view class=\"tab-bar-item\" bindtap=\"url\" data-type=\"relaunch\" data-url=\"/projects/TRIP1/pages/default/index/default_index\">\n\t\t\t<image class=\"tab-icon\" src=\"/projects/TRIP1/images/tabbar/home{{curMenu=='home_index'?'_cur':''}}.png\"></image>\n\t\t\t<view class=\"tab-text {{curMenu=='home_index'?'menu-project':''}}\">首页</view>\n\t\t</view>\n\n\t\t<view class=\"tab-bar-item\" bindtap=\"url\" data-type=\"relaunch\" data-url=\"/projects/TRIP1/pages/product/index/product_index\">\n\t\t\t<image class=\"tab-icon\" src=\"/projects/TRIP1/images/tabbar/jing{{curMenu=='product_index'?'_cur':''}}.png\"></image>\n\t\t\t<view class=\"tab-text {{curMenu=='product_index'?'menu-project':''}}\">景点</view>\n\t\t</view>\n\n\t\t<view wx:if=\"{{skin.cate2!==false}}\" class=\"tab-bar-item\" bindtap=\"url\" data-type=\"relaunch\" data-url=\"/projects/TRIP1/pages/album/index/album_index\">\n\t\t\t<image class=\"tab-icon\" src=\"/projects/TRIP1/images/tabbar/gong{{curMenu=='album_index'?'_cur':''}}.png\"></image>\n\t\t\t<view class=\"tab-text {{curMenu=='album_index'?'menu-project':''}}\">攻略</view>\n\t\t</view>\n\t\t \n\t\t<view class=\"tab-bar-item\" bindtap=\"url\" data-type=\"relaunch\" data-url=\"/projects/TRIP1/pages/about/service/about_service\">\n\t\t\t<image class=\"tab-icon\" src=\"/projects/TRIP1/images/tabbar/service{{curMenu=='service'?'_cur':''}}.png\"></image>\n\t\t\t<view class=\"tab-text {{curMenu=='service'?'menu-project':''}}\">服务</view>\n\t\t</view>\n\t\t<view class=\"tab-bar-item\" bindtap=\"url\" data-type=\"relaunch\" data-url=\"/projects/TRIP1/pages/my/index/my_index\">\n\t\t\t<image class=\"tab-icon\" src=\"/projects/TRIP1/images/tabbar/my{{curMenu=='my_index'?'_cur':''}}.png\"></image>\n\t\t\t<view class=\"tab-text {{curMenu=='my_index'?'menu-project':''}}\">我的</view>\n\t\t</view>\n\n\n\t</view>\n</template>"
  },
  {
    "path": "miniprogram/projects/TRIP1/public/project_setting.js",
    "content": "module.exports = {\n\tPROJECT_COLOR: '#00C176',\n\tNAV_COLOR: '#ffffff',\n\tNAV_BG: '#00C176',\n\n\t// setup\n\tSETUP_CONTENT_ITEMS: [\n\t\t{ title: '景区概况', key: 'SETUP_CONTENT_ABOUT' },\n\t\t{ title: '公交信息', key: 'SETUP_CONTENT_BUS' },\n\t\t{ title: '停车场', key: 'SETUP_CONTENT_PARKING' },\n\t\t{ title: '找厕所', key: 'SETUP_CONTENT_TOLIET' },\n\t\t{ title: '星级旅行社', key: 'SETUP_CONTENT_LXS' },\n\t\t{ title: '星级导游', key: 'SETUP_CONTENT_DY' },\n\t\t{ title: '一周天气', key: 'SETUP_CONTENT_WEATHER' },\n\t],\n\n\t// 用户\n\tUSER_REG_CHECK: false,\n\tUSER_FIELDS: [\n\t\t{ mark: 'sex', title: '性别', type: 'select', selectOptions: ['男', '女'], must: true },\n\t\t{ mark: 'area', title: '所在地区', type: 'area' }\n\t],\n\n\n\tNEWS_NAME: '内容',\n\tNEWS_CATE: [\n\t\t{ id: 1, title: '景区动态', style: 'upimg' },\n\t\t{ id: 2, title: '美食', style: 'leftbig1' },\n\t\t{ id: 3, title: '特产', style: 'leftbig3' },\n\t],\n\n\t// ### 预约相关  \n\tMEET_NAME: '预约',\n\tMEET_TYPE: [\n\t\t{ id: 1, title: '景点预约', style: 'leftbig2' },\n\t\t{ id: 2, title: '停车预约', style: 'leftbig3' }\n\t],\n\tMEET_CAN_NULL_TIME: false, // 是否允许有无时段的日期保存和展示   \n\n\tMEET_JOIN_FIELDS: [\n\t\t{ mark: 'name', type: 'text', title: '姓名', must: true, max: 30 },\n\t\t{ mark: 'phone', type: 'mobile', title: '手机', must: true }\n\t],\n\n\tALBUM_NAME: '攻略',\n\tALBUM_CATE: [\n\t\t{ id: 1, title: '线路' },\n\t\t{ id: 2, title: '吃喝' },\n\t\t{ id: 3, title: '住宿' },\n\t\t{ id: 4, title: '购物' },\n\t\t{ id: 5, title: '其他' },\n\t],\n\tALBUM_FIELDS: [\n\t\t{ mark: 'cover', title: '封面图片', type: 'image', min: 1, max: 1, must: true },\n\t\t{ mark: 'desc', title: '简介', type: 'textarea', max: 100, must: true },\n\t\t{ mark: 'detail', title: '详细介绍', type: 'content', must: true },\n\t],\n\n\tPRODUCT_NAME: '景点',\n\tPRODUCT_CATE: [\n\t\t{ id: 1, title: '仙山贡水' },\n\t\t{ id: 2, title: '伍家台' },\n\t\t{ id: 3, title: '狮子关' },\n\t\t{ id: 4, title: '其他景点' }\n\t],\n\tPRODUCT_FIELDS: [\n\t\t{ mark: 'cover', title: '封面图片', type: 'image', min: 1, max: 1, must: true },\n\t\t{ mark: 'star', title: '推荐指数(星级)', type: 'select', selectOptions: ['1', '2', '3', '4', '5'], def: 1, must: true },\n\t\t{ mark: 'time', title: '开放时间', type: 'textarea', must: false },\n\t\t{ mark: 'address', title: '地址', type: 'textarea', must: false },\n\t\t{ mark: 'desc', title: '简介', type: 'textarea', max: 10000, must: true },\n\t\t{ mark: 'traffic', title: '交通攻略', type: 'textarea', max: 500, must: false },\n\t\t{ mark: 'ticket', title: '门票攻略', type: 'textarea', max: 500, must: false },\n\t\t{ mark: 'other', title: '其他信息', type: 'textarea', max: 10000, must: false },\n\t\t{ mark: 'album', title: '景点图集', type: 'image', min: 1, max: 10, must: true },\n\t],\n}"
  },
  {
    "path": "miniprogram/projects/TRIP1/style/skin.wxss",
    "content": "page {\n\tbackground-color: #f8f8f8;\n\n\t--projectColor: #00C176;\n\t--projectColorLight: #FEBA00;\n\t--projectCompareColor: #FF473C;\n\n\t/*#### 父组件日历颜色定义*/\n\t/* 整体颜色 */\n\t--calendarPageColor: #fff;\n\t/* 加重颜色*/\n\t--calendarMainColor: #00C176 !important;\n\t/* 加重的亮颜色 用于选中日期的数据小圆点 */\n\t--calendarLightColor: #FEBA00;\n}\n\n.bg-admin {\n\tbackground-color: #2499f2;\n}\n\n.text-project {\n\tcolor: var(--projectColor) !important;\n}\n\n.bg-project {\n\tbackground-color: var(--projectColor) !important;\n}\n\n.bg-project.light {\n\tcolor: var(--projectColor) !important;\n\tbackground-color: var(--projectColorLight) !important;\n}\n\n.border-project {\n\tborder-color: var(--projectColor) !important;\n}\n\n.menu-project {\n\tcolor: var(--projectColor) !important;\n}\n\n.tabs .tab {\n\tfont-size: 28rpx !important;\n}\n\n.tabs .cur {\n\tcolor: var(--projectColor) !important;\n}\n\n.tabs .tab-menu.cur:after {\n\tbackground-color: var(--projectColor) !important;\n}\n\n.load-project {\n\tcolor: #8799a3 !important;\n}\n\n.padding-project {\n\tpadding-left: 25rpx !important;\n\tpadding-right: 25rpx !important;\n}\n\n.btn-project {\n\tline-height: 80rpx;\n\theight: 80rpx;\n\tcolor: #fff;\n\tbackground-color: var(--projectColor);\n}\n\n.phone-button {\n\tcolor: var(--projectColor) !important;\n}\n\n.shadow-project {\n\tbox-shadow: 6rpx 6rpx 8rpx rgba(216, 220, 223, 0.5);\n}\n\n.card-project,\n.main .list .item.card-project,\n.down .comm-list.menu.card-project,\n.article-box .article.card-project,\n.text-pic-list-box .item.card-project,\n.info-list-box .item.card-project,\n.main-content .content.card-project,\n.comm-list-box .item.card-project,\n.form-box.card-project,\n.bar .search-form {\n\tborder-radius: 10rpx !important;\n}\n\n.up-project {\n\twidth: 100%;\n\tpadding: 0;\n\tmargin: 0;\n}\n\n.up-project image {\n\tpadding: 0;\n\twidth: 100%;\n\tmargin: 0;\n}\n\n.my-icon-project { \n\tfont-weight: bold;\n\tfont-size: 34rpx;\n}\n\n\n.comm-list-box {\n\tpadding: 20rpx 30rpx 30rpx 30rpx;\n}"
  },
  {
    "path": "miniprogram/setting/setting.js",
    "content": "module.exports = {\n\t//### 环境相关 \n\tCLOUD_ID: 'init-5go8b8pdc98ea814', //云服务id ,本地测试环境 \n\n\t// #### 版本信息 \n\tVER: 'build 2022.08.14',\n\tCOMPANY: '联系作者',\n\n\t// #### 系统参数 \n\tIS_SUB: false, //分包模式 \n\tIS_DEMO: false, //是否演示版  \n\n\tMOBILE_CHECK: false, //手机号码是否真实性校验\n\n\n\t//#################     \n\tIMG_UPLOAD_SIZE: 20, //图片上传大小M兆    \n\n\t// #### 缓存相关\n\tCACHE_IS_LIST: true, //列表是否缓存\n\tCACHE_LIST_TIME: 60 * 30, //列表缓存时间秒    \n\n}"
  },
  {
    "path": "miniprogram/sitemap.json",
    "content": "{\n  \"desc\": \"关于本文件的更多信息，请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html\",\n  \"rules\": [{\n    \"action\": \"disallow\",\n    \"page\": \"*\"\n  }]\n}"
  },
  {
    "path": "miniprogram/style/base/animation.wxss",
    "content": " \n\n/* css 滤镜 控制黑白底色gif的 */\n.gif-black{  \n\tmix-blend-mode: screen;  \n  }\n  .gif-white{  \n\tmix-blend-mode: multiply; \n  }\n  \n  \n  /* Animation css */\n  [class*=animation-] {\n\t  animation-duration: .5s;\n\t  animation-timing-function: ease-out;\n\t  animation-fill-mode: both\n  }\n  \n  .animation-fade {\n\t  animation-name: fade;\n\t  animation-duration: .8s;\n\t  animation-timing-function: linear\n  }\n  \n  .animation-scale-up {\n\t  animation-name: scale-up\n  }\n  \n  .animation-scale-down {\n\t  animation-name: scale-down\n  }\n  \n  .animation-slide-top {\n\t  animation-name: slide-top\n  }\n  \n  .animation-slide-bottom {\n\t  animation-name: slide-bottom\n  }\n  \n  .animation-slide-left {\n\t  animation-name: slide-left\n  }\n  \n  .animation-slide-right {\n\t  animation-name: slide-right\n  }\n  \n  .animation-shake {\n\t  animation-name: shake\n  }\n  \n  .animation-reverse {\n\t  animation-direction: reverse\n  }\n  \n  @keyframes fade {\n\t  0% {\n\t\t  opacity: 0\n\t  }\n  \n\t  100% {\n\t\t  opacity: 1\n\t  }\n  }\n  \n  @keyframes scale-up {\n\t  0% {\n\t\t  opacity: 0;\n\t\t  transform: scale(.2)\n\t  }\n  \n\t  100% {\n\t\t  opacity: 1;\n\t\t  transform: scale(1)\n\t  }\n  }\n  \n  @keyframes scale-down {\n\t  0% {\n\t\t  opacity: 0;\n\t\t  transform: scale(1.8)\n\t  }\n  \n\t  100% {\n\t\t  opacity: 1;\n\t\t  transform: scale(1)\n\t  }\n  }\n  \n  @keyframes slide-top {\n\t  0% {\n\t\t  opacity: 0;\n\t\t  transform: translateY(-100%)\n\t  }\n  \n\t  100% {\n\t\t  opacity: 1;\n\t\t  transform: translateY(0)\n\t  }\n  }\n  \n  @keyframes slide-bottom {\n\t  0% {\n\t\t  opacity: 0;\n\t\t  transform: translateY(100%)\n\t  }\n  \n\t  100% {\n\t\t  opacity: 1;\n\t\t  transform: translateY(0)\n\t  }\n  }\n  \n  @keyframes shake {\n  \n\t  0%,\n\t  100% {\n\t\t  transform: translateX(0)\n\t  }\n  \n\t  10% {\n\t\t  transform: translateX(-9px)\n\t  }\n  \n\t  20% {\n\t\t  transform: translateX(8px)\n\t  }\n  \n\t  30% {\n\t\t  transform: translateX(-7px)\n\t  }\n  \n\t  40% {\n\t\t  transform: translateX(6px)\n\t  }\n  \n\t  50% {\n\t\t  transform: translateX(-5px)\n\t  }\n  \n\t  60% {\n\t\t  transform: translateX(4px)\n\t  }\n  \n\t  70% {\n\t\t  transform: translateX(-3px)\n\t  }\n  \n\t  80% {\n\t\t  transform: translateX(2px)\n\t  }\n  \n\t  90% {\n\t\t  transform: translateX(-1px)\n\t  }\n  }\n  \n  @keyframes slide-left {\n\t  0% {\n\t\t  opacity: 0;\n\t\t  transform: translateX(-100%)\n\t  }\n  \n\t  100% {\n\t\t  opacity: 1;\n\t\t  transform: translateX(0)\n\t  }\n  }\n  \n  @keyframes slide-right {\n\t  0% {\n\t\t  opacity: 0;\n\t\t  transform: translateX(100%)\n\t  }\n  \n\t  100% {\n\t\t  opacity: 1;\n\t\t  transform: translateX(0)\n\t  }\n  }"
  },
  {
    "path": "miniprogram/style/base/avatar.wxss",
    "content": "\n/* ==================\n          头像\n ==================== */ \n .avatar {\n\tfont-variant: small-caps;\n\tmargin: 0;\n\tpadding: 0;\n\tdisplay: inline-flex;\n\ttext-align: center;\n\tjustify-content: center;\n\talign-items: center; \n\tcolor: var(--white);\n\twhite-space: nowrap;\n\tposition: relative;\n\twidth: 64rpx;\n\theight: 64rpx;\n\tbackground-size: cover;\n\tbackground-position: center;\n\tvertical-align: middle;\n\tfont-size: 1.5em;\n}\n\n.avatar:not([class*=\"bg-\"]) {\n\tbackground-color: #ccc;\n}\n\n.avatar.xs {\n\twidth: 32rpx;\n\theight: 32rpx;\n\tfont-size: 1em;\n}\n\n.avatar.small {\n\twidth: 48rpx;\n\theight: 48rpx;\n\tfont-size: 1em;\n}\n\n.avatar.large {\n\twidth: 96rpx;\n\theight: 96rpx;\n\tfont-size: 2em;\n}\n\n.avatar.xl {\n\twidth: 128rpx;\n\theight: 128rpx;\n\tfont-size: 2.5em;\n}\n\n.avatar .avatar-text {\n\tfont-size: 0.4em;\n}\n\n.avatar-group {\n\tdirection: rtl;\n\tunicode-bidi: bidi-override;\n\tpadding: 0 10rpx 0 40rpx;\n\tdisplay: inline-block;\n}\n\n.avatar-group .avatar {\n\tmargin-left: -30rpx;\n\tborder: 4rpx solid var(--ghostWhite);\n\tvertical-align: middle;\n}\n\n.avatar-group .avatar.small {\n\tmargin-left: -20rpx;\n\tborder: 1rpx solid var(--ghostWhite);\n}\n"
  },
  {
    "path": "miniprogram/style/base/background.wxss",
    "content": "\n/* ==================\n          背景\n ==================== */\n\n .bg-red {\n\tbackground-color: var(--red)!important;\n\tcolor: var(--white)!important;\n}\n\n.bg-orange {\n\tbackground-color: var(--orange)!important;\n\tcolor: var(--white)!important;\n}\n\n.bg-yellow {\n\tbackground-color: var(--yellow)!important;\n\tcolor: var(--black)!important;\n}\n\n.bg-olive {\n\tbackground-color: var(--olive)!important;\n\tcolor: var(--white)!important;\n}\n\n.bg-green {\n\tbackground-color: var(--green)!important;\n\tcolor: var(--white)!important;\n}\n\n.bg-darkgreen {\n\tbackground-color: var(--darkgreen)!important;\n\tcolor: var(--white)!important;\n}\n\n.bg-cyan {\n\tbackground-color: var(--cyan)!important;\n\tcolor: var(--white)!important;\n}\n\n.bg-blue {\n\tbackground-color: var(--blue)!important;\n\tcolor: var(--white)!important;\n}\n\n.bg-purple {\n\tbackground-color: var(--purple)!important;\n\tcolor: var(--white)!important;\n}\n\n.bg-mauve {\n\tbackground-color: var(--mauve)!important;\n\tcolor: var(--white)!important;\n}\n\n.bg-pink {\n\tbackground-color: var(--pink)!important;\n\tcolor: var(--white)!important;\n}\n\n.bg-brown {\n\tbackground-color: var(--brown)!important;\n\tcolor: var(--white)!important;\n}\n\n.bg-grey {\n\tbackground-color: var(--grey)!important;\n\tcolor: var(--white)!important;\n}\n\n.bg-gray {\n\tbackground-color: #f0f0f0!important;\n\tcolor: var(--black)!important;\n}\n\n.bg-black {\n\tbackground-color: var(--black)!important;\n\tcolor: var(--white)!important;\n}\n\n.bg-white {\n\tbackground-color: var(--white)!important;\n\tcolor: var(--darkGray)!important;\n}\n\n.bg-shadeTop {\n\tbackground-image: linear-gradient(rgba(0, 0, 0, 1), rgba(0, 0, 0, 0.01))!important;\n\tcolor: var(--white)!important;\n}\n\n.bg-shadeBottom {\n\tbackground-image: linear-gradient(rgba(0, 0, 0, 0.01), rgba(0, 0, 0, 1))!important;\n\tcolor: var(--white)!important;\n}\n\n.bg-red.light {\n\tcolor: var(--red)!important;\n\tbackground-color: var(--redLight)!important;\n}\n\n.bg-orange.light {\n\tcolor: var(--orange)!important;\n\tbackground-color: var(--orangeLight)!important;\n}\n\n.bg-yellow.light {\n\tcolor: var(--yellow)!important;\n\tbackground-color: var(--yellowLight)!important;\n}\n\n.bg-olive.light {\n\tcolor: var(--olive)!important;\n\tbackground-color: var(--oliveLight)!important;\n}\n\n.bg-green.light {\n\tcolor: var(--green)!important;\n\tbackground-color: var(--greenLight)!important;\n}\n\n.bg-cyan.light {\n\tcolor: var(--cyan)!important;\n\tbackground-color: var(--cyanLight)!important;\n}\n\n.bg-blue.light {\n\tcolor: var(--blue)!important;\n\tbackground-color: var(--blueLight)!important;\n}\n\n.bg-purple.light {\n\tcolor: var(--purple)!important;\n\tbackground-color: var(--purpleLight)!important;\n}\n\n.bg-mauve.light {\n\tcolor: var(--mauve)!important;\n\tbackground-color: var(--mauveLight)!important;\n}\n\n.bg-pink.light {\n\tcolor: var(--pink)!important;\n\tbackground-color: var(--pinkLight)!important;\n}\n\n.bg-brown.light {\n\tcolor: var(--brown)!important;\n\tbackground-color: var(--brownLight)!important;\n}\n\n.bg-grey.light {\n\tcolor: var(--grey)!important;\n\tbackground-color: var(--greyLight)!important;\n}\n\n.bg-gradual-red {\n\tbackground-image: var(--gradualRed)!important;\n\tcolor: var(--white)!important;\n}\n\n.bg-gradual-orange {\n\tbackground-image: var(--gradualOrange)!important;\n\tcolor: var(--white)!important;\n}\n\n.bg-gradual-green {\n\tbackground-image: var(--gradualGreen)!important;\n\tcolor: var(--white)!important;\n}\n\n.bg-gradual-purple {\n\tbackground-image: var(--gradualPurple)!important;\n\tcolor: var(--white)!important;\n}\n\n.bg-gradual-pink {\n\tbackground-image: var(--gradualPink)!important;\n\tcolor: var(--white)!important;\n}\n\n.bg-gradual-blue {\n\tbackground-image: var(--gradualBlue)!important;\n\tcolor: var(--white)!important;\n}\n"
  },
  {
    "path": "miniprogram/style/base/bar.wxss",
    "content": "\n/* ==================\n          操作条\n ==================== */\n\n .bar {\n\tdisplay: flex;\n\tposition: relative;\n\talign-items: center;\n\tmin-height: 100rpx;\n\tjustify-content: space-between;\n}\n\n.bar .action {\n\tdisplay: flex;\n\talign-items: center;\n\theight: 100%;\n\tjustify-content: center;\n\tmax-width: 100%;\n}\n\n\n.bar .content {\n\tposition: absolute;\n\ttext-align: center;\n\twidth: calc(100% - 340rpx);\n\tleft: 0;\n\tright: 0;\n\tbottom: 0;\n\ttop: 0;\n\tmargin: auto;\n\theight: 60rpx;\n\tfont-size: 32rpx;\n\tline-height: 60rpx;\n\tcursor: none;\n\tpointer-events: none;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n\toverflow: hidden;\n}\n\n.bar.ios .content {\n\tbottom: 7px;\n\theight: 30px;\n\tfont-size: 32rpx;\n\tline-height: 30px;\n}\n\n.bar .action:first-child {\n    margin-left: 30rpx;\n    font-size: 30rpx;\n}\n\n.bar .action:first-child>text[class*=\"icon-\"] {\n\tmargin-left: -0.3em;\n\tmargin-right: 0.3em;\n}\n\n\n.bar .action:last-child {\n    margin-right: 30rpx;\n} \n\n\n\n.bar .action>text[class*=\"icon-\"],\n.bar .action>view[class*=\"icon-\"] {\n\tfont-size: 36rpx;\n}\n\n.bar .action>text[class*=\"icon-\"]+text[class*=\"icon-\"] {\n\tmargin-left: 0.5em;\n}\n\n.bar .content {\n\tposition: absolute;\n\ttext-align: center;\n\twidth: calc(100% - 340rpx);\n\tleft: 0;\n\tright: 0;\n\tbottom: 0;\n\ttop: 0;\n\tmargin: auto;\n\theight: 60rpx;\n\tfont-size: 32rpx;\n\tline-height: 60rpx;\n\tcursor: none;\n\tpointer-events: none;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n\toverflow: hidden;\n}\n\n.bar.ios .content {\n\tbottom: 7px;\n\theight: 30px;\n\tfont-size: 32rpx;\n\tline-height: 30px;\n}\n\n.bar.btn-group {\n\tjustify-content: space-around;\n}\n\n.bar.btn-group button {\n\tpadding: 20rpx 32rpx;\n}\n\n.bar.btn-group button {\n\tflex: 1;\n\tmargin: 0 20rpx;\n\tmax-width: 50%;\n}\n\n.bar .search-form {\n\tbackground-color: #f5f5f5;\n\tline-height: 64rpx;\n\theight: 64rpx;\n\tfont-size: 24rpx;\n\tcolor: var(--black);\n\tflex: 1;\n\tdisplay: flex;\n\talign-items: center;\n\tmargin: 0 30rpx;\n}\n\n.bar .search-form+.action {\n\tmargin-right: 30rpx;\n}\n\n.bar .search-form input {\n\tflex: 1;\n\tpadding-right: 30rpx;\n\theight: 64rpx;\n\tline-height: 64rpx;\n\tfont-size: 26rpx;\n\tbackground-color: transparent;\n}\n\n.bar .search-form [class*=\"icon-\"] {\n\tmargin: 0 0.5em 0 0.8em;\n}\n\n.bar .search-form [class*=\"icon-\"]::before {\n\ttop: 0rpx;\n}\n\n.bar.fixed,\n.nav.fixed {\n\tposition: fixed;\n\twidth: 100%;\n\ttop: 0;\n\tz-index: 1024;\n\tbox-shadow: 0 1rpx 6rpx rgba(0, 0, 0, 0.1);\n}\n\n.bar.foot {\n\tposition: fixed;\n\twidth: 100%;\n\tbottom: 0;\n\tz-index: 1024;\n\tbox-shadow: 0 -1rpx 6rpx rgba(0, 0, 0, 0.1);\n}\n\n.bar.tabbar {\n\tpadding: 0;\n\theight: calc(100rpx + constant(safe-area-inset-bottom) / 2);\n\theight: calc(100rpx + env(safe-area-inset-bottom) / 2);\n\tpadding-bottom: calc(constant(safe-area-inset-bottom) / 2);\n\tpadding-bottom: calc(env(safe-area-inset-bottom) / 2);\n}\n\n.tabbar-height {\n\tmin-height: 100rpx;\n\theight: calc(100rpx + constant(safe-area-inset-bottom) / 2);\n\theight: calc(100rpx + env(safe-area-inset-bottom) / 2);\n}\n\n.bar.tabbar.shadow {\n\tbox-shadow: 0 -1rpx 6rpx rgba(0, 0, 0, 0.1);\n}\n\n.bar.tabbar .action {\n\tfont-size: 22rpx;\n\tposition: relative;\n\tflex: 1;\n\ttext-align: center;\n\tpadding: 0;\n\tdisplay: block;\n\theight: auto;\n\tline-height: 1;\n\tmargin: 0;\n\toverflow: initial;\n}\n\n.bar.tabbar.shop .action {\n\twidth: 140rpx;\n\tflex: initial;\n}\n\n.bar.tabbar .action.add-action {\n\tposition: relative;\n\tz-index: 2;\n\tpadding-top: 50rpx;\n\tbackground-color: inherit;\n}\n\n.bar.tabbar .action.add-action [class*=\"icon-\"] {\n\tposition: absolute;\n\twidth: 70rpx;\n\tz-index: 2;\n\theight: 70rpx;\n\tborder-radius: 50%;\n\tline-height: 70rpx;\n\tfont-size: 50rpx;\n\ttop: -35rpx;\n\tleft: 0;\n\tright: 0;\n\tmargin: auto;\n\tpadding: 0;\n}\n\n.bar.tabbar .action.add-action::after {\n\tcontent: \"\";\n\tposition: absolute;\n\twidth: 100rpx;\n\theight: 100rpx;\n\ttop: -50rpx;\n\tleft: 0;\n\tright: 0;\n\tmargin: auto;\n\tbox-shadow: 0 -3rpx 8rpx rgba(0, 0, 0, 0.08);\n\tborder-radius: 50rpx;\n\tbackground-color: inherit;\n\tz-index: 0;\n}\n\n.bar.tabbar .action.add-action::before {\n\tcontent: \"\";\n\tposition: absolute;\n\twidth: 100rpx;\n\theight: 30rpx;\n\tbottom: 30rpx;\n\tleft: 0;\n\tright: 0;\n\tmargin: auto;\n\tbackground-color: inherit;\n\tz-index: 1;\n}\n\n.bar.tabbar .btn-group {\n\tflex: 1;\n\tdisplay: flex;\n\tjustify-content: space-around;\n\talign-items: center;\n\tpadding: 0 10rpx;\n}\n\n.bar.tabbar button.action::after {\n\tborder: 0;\n}\n\n.bar.tabbar .action [class*=\"icon-\"] {\n\twidth: 100rpx;\n\tposition: relative;\n\tdisplay: block;\n\theight: auto;\n\tmargin: 0 auto 10rpx;\n\ttext-align: center;\n\tfont-size: 40rpx;\n}\n\n.bar.tabbar .action .icon-cu-image {\n\tmargin: 0 auto;\n}\n\n.bar.tabbar .action .icon-cu-image image {\n\twidth: 50rpx;\n\theight: 50rpx;\n\tdisplay: inline-block;\n}\n\n.bar.tabbar .submit {\n\talign-items: center;\n\tdisplay: flex;\n\tjustify-content: center;\n\ttext-align: center;\n\tposition: relative;\n\tflex: 2;\n\talign-self: stretch;\n}\n\n.bar.tabbar .submit:last-child {\n\tflex: 2.6;\n}\n\n.bar.tabbar .submit+.submit {\n\tflex: 2;\n}\n\n.bar.tabbar.border .action::before {\n\tcontent: \" \";\n\twidth: 200%;\n\theight: 200%;\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\ttransform: scale(0.5);\n\ttransform-origin: 0 0;\n\tborder-right: 1rpx solid rgba(0, 0, 0, 0.1);\n\tz-index: 3;\n}\n\n.bar.tabbar.border .action:last-child:before {\n\tdisplay: none;\n}\n\n.bar.input {\n\tpadding-right: 20rpx;\n\tbackground-color: var(--white);\n}\n\n.bar.input input {\n\toverflow: initial;\n\tline-height: 64rpx;\n\theight: 64rpx;\n\tmin-height: 64rpx;\n\tflex: 1;\n\tfont-size: 30rpx;\n\tmargin: 0 20rpx;\n}\n\n.bar.input .action {\n\tmargin-left: 20rpx;\n}\n\n.bar.input .action [class*=\"icon-\"] {\n\tfont-size: 48rpx;\n}\n\n.bar.input input+.action {\n\tmargin-right: 20rpx;\n\tmargin-left: 0rpx;\n}\n\n.bar.input .action:first-child [class*=\"icon-\"] {\n\tmargin-left: 0rpx;\n} "
  },
  {
    "path": "miniprogram/style/base/base.wxss",
    "content": "/* ==================\n        初始化\n ==================== */\n page {\n\t/* Color 可以自定义相关配色 */\n\t/* var属性兼容性 --> https://www.caniuse.com/#feat=css-variables */\n\t/* 标准色 */\n\t--red: #e54d42;\n\t--orange: #f37b1d;\n\t--yellow: #fbbd08;\n\t--olive: #8dc63f;\n\t--green: #39b54a;\n\t--darkgreen: #0E9489;\n\t--cyan: #1cbbb4;\n\t--blue: #347DFF;\n\t--purple: #6739b6;\n\t--mauve: #9c26b0;\n\t--pink: #e03997;\n\t--brown: #a5673f;\n\t--grey: #8799a3;\n\t--black: #333333;\n\t--darkGray: #666666;\n\t--gray: #aaaaaa;\n\t--ghostWhite: #f1f1f1;\n\t--white: #ffffff;\n\t/* 浅色 */\n\t--redLight: #fadbd9;\n\t--orangeLight: #fde6d2;\n\t--yellowLight: #fef2ce;\n\t--oliveLight: #e8f4d9;\n\t--greenLight: #d7f0db;\n\t--cyanLight: #d2f1f0;\n\t--blueLight: #cce6ff;\n\t--purpleLight: #e1d7f0;\n\t--mauveLight: #ebd4ef;\n\t--pinkLight: #f9d7ea;\n\t--brownLight: #ede1d9;\n\t--greyLight: #e7ebed;\n\n\t/* 阴影透明色 */\n\t--ShadowSize: 6rpx 6rpx 8rpx;\n\t--redShadow: rgba(204, 69, 59, 0.2);\n\t--orangeShadow: rgba(217, 109, 26, 0.2);\n\t--yellowShadow: rgba(224, 170, 7, 0.2);\n\t--oliveShadow: rgba(124, 173, 55, 0.2);\n\t--greenShadow: rgba(48, 156, 63, 0.2);\n\t--darkgreenShadow: rgba(48, 156, 63, 0.2);\n\t--cyanShadow: rgba(28, 187, 180, 0.2);\n\t--blueShadow: rgba(0, 102, 204, 0.2);\n\t--purpleShadow: rgba(88, 48, 156, 0.2);\n\t--mauveShadow: rgba(133, 33, 150, 0.2);\n\t--pinkShadow: rgba(199, 50, 134, 0.2);\n\t--brownShadow: rgba(140, 88, 53, 0.2);\n\t--greyShadow: rgba(114, 130, 138, 0.2);\n\t--grayShadow: rgba(114, 130, 138, 0.2);\n\t--blackShadow: rgba(26, 26, 26, 0.2);\n\n\tbackground-color: var(--ghostWhite);\n\tfont-size: 28rpx;\n\tcolor: var(--black);\n\tfont-family: Helvetica Neue, Helvetica, sans-serif;\n\n\t/*苹果手机安全区域*/\n\tpadding-bottom: constant(safe-area-inset-bottom);\n\tpadding-bottom: env(safe-area-inset-bottom);\n  \n}\n\nview,\nscroll-view,\nswiper,\nbutton,\ninput,\ntextarea,\nlabel,\nnavigator,\nimage {\n\tbox-sizing: border-box;\n} \n\n.hide {\n\tdisplay: none;\n}\n\n.round {\n\tborder-radius: 5000rpx;\n}\n\n.radius {\n\tborder-radius: 6rpx;\n}\n\n.block {\n\tdisplay: block;\n} \n\n/* 多行文本 */\n.text-content{ \n\tline-height: 1.6;\n\ttable-layout:fixed; word-break: break-all; overflow:hidden;\n}\n"
  },
  {
    "path": "miniprogram/style/base/border.wxss",
    "content": "\n/* ==================\n          边框 line为伪元素\n ==================== */\n\n .border-red::after {\n\tborder-color: var(--red);\n}\n\n.border-orange::after {\n\tborder-color: var(--orange);\n}\n\n.border-yellow::after {\n\tborder-color: var(--yellow);\n}\n\n.border-olive::after {\n\tborder-color: var(--olive);\n}\n\n.border-green::after {\n\tborder-color: var(--green);\n}\n\n.border-darkgreen::after {\n\tborder-color: var(--darkgreen);\n}\n \n.border-cyan::after {\n\tborder-color: var(--cyan);\n}\n\n.border-blue::after {\n\tborder-color: var(--blue);\n}\n\n.border-purple::after {\n\tborder-color: var(--purple);\n}\n\n.border-mauve::after {\n\tborder-color: var(--mauve);\n}\n\n.border-pink::after {\n\tborder-color: var(--pink);\n}\n\n.border-brown::after {\n\tborder-color: var(--brown);\n}\n\n.border-grey::after {\n\tborder-color: var(--grey);\n}\n\n.border-gray::after {\n\tborder-color: var(--gray);\n}\n\n.border-black::after {\n\tborder-color: var(--black);\n}\n\n.border-white::after {\n\tborder-color: var(--white);\n}\n\n\n\n/* ==================\n          边框\n ==================== */\n\n/* -- 实线 -- */\n\n.solid,\n.solid-top,\n.solid-right,\n.solid-bottom,\n.solid-left,\n.solid-bold,\n.solid-bold-top,\n.solid-bold-right,\n.solid-bold-bottom,\n.solid-bold-left {\n\tposition: relative;\n}\n\n.solid::after,\n.solid-top::after,\n.solid-right::after,\n.solid-bottom::after,\n.solid-left::after,\n.solid-bold::after,\n.solid-bold-top::after,\n.solid-bold-right::after,\n.solid-bold-bottom::after,\n.solid-bold-left::after {\n\tcontent: \" \";\n\twidth: 200%;\n\theight: 200%;\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tborder-radius: inherit;\n\ttransform: scale(0.5);\n\ttransform-origin: 0 0;\n\tpointer-events: none;\n\tbox-sizing: border-box;\n}\n\n.solid::after {\n\tborder: 4rpx solid rgba(0, 0, 0, 0.1);\n}\n\n.solid-top::after {\n\tborder-top: 4rpx solid rgba(0, 0, 0, 0.1);\n}\n\n.solid-right::after {\n\tborder-right: 4rpx solid rgba(0, 0, 0, 0.1);\n}\n\n.solid-bottom::after {\n\tborder-bottom: 4rpx solid rgba(0, 0, 0, 0.1);\n}\n\n.solid-left::after {\n\tborder-left: 4rpx solid rgba(0, 0, 0, 0.1);\n}\n\n.solid-bold::after {\n\tborder: 8rpx solid #eee;\n}\n\n.solid-bold-top::after {\n\tborder-top: 8rpx solid #eee;\n}\n\n.solid-bold-right::after {\n\tborder-right: 8rpx solid #eee;\n}\n\n.solid-bold-bottom::after {\n\tborder-bottom: 8rpx solid #eee;\n}\n\n.solid-bold-left::after {\n\tborder-left: 8rpx solid #eee;\n}"
  },
  {
    "path": "miniprogram/style/base/button.wxss",
    "content": "/* ==================\n          按钮\n ==================== */\n\n .btn {\n\tborder: 0rpx;\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tbox-sizing: border-box;\n\tpadding: 0 30rpx;\n\tfont-size: 28rpx;\n\theight: 64rpx;\n\tline-height: 1;\n\ttext-align: center;\n\ttext-decoration: none;\n\toverflow: visible;\n\tmargin-left: initial;\n\ttransform: translate(0rpx, 0rpx);\n\tmargin-right: initial;\n\tborder-radius: 12rpx;\n}\n\n.btn::after {\n\tdisplay: none;\n}\n\n.btn:not([class*=\"bg-\"]) {\n\tbackground-color: #f0f0f0;\n}\n\n.btn[class*=\"border\"] {\n\tbackground-color: transparent;\n}\n\n/* 伪元素边框 */\n.btn[class*=\"border\"]::after {\n\tcontent: \" \";\n\tdisplay: block;\n\twidth: 200%;\n\theight: 200%;\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tborder: 1rpx solid currentColor;\n\ttransform: scale(0.5);\n\ttransform-origin: 0 0;\n\tbox-sizing: border-box;\n\tz-index: 1;\n\tpointer-events: none;\n\tborder-radius: 12rpx;\n}\n\n.btn[class*=\"bg-\"]::after {\n\tdisplay: none;\n}\n\n.btn.small {\n\tpadding: 0 20rpx;\n\tfont-size: 20rpx;\n\theight: 48rpx;\n\tborder-radius: 10rpx;\n}\n\n.btn.mid {\n\tpadding: 0 20rpx;\n\tfont-size: 24rpx;\n\theight: 50rpx;\n\tborder-radius: 10rpx;\n}\n\n.btn.large {\n\tpadding: 0 40rpx;\n\tfont-size: 32rpx;\n\theight: 80rpx;\n\tborder-radius: 14rpx;\n}\n\n.btn.btn-icon.small {\n\twidth: 48rpx;\n\theight: 48rpx;\n}\n\n.btn.btn-icon {\n\twidth: 64rpx;\n\theight: 64rpx;\n\tborder-radius: 500rpx;\n\tpadding: 0;\n}\n\nbutton.btn-icon.large {\n\twidth: 80rpx;\n\theight: 80rpx;\n}\n\n.btn.shadow-blur::before {\n\ttop: 4rpx;\n\tleft: 4rpx;\n\tfilter: blur(6rpx);\n\topacity: 0.6;\n}\n\n.btn.button-hover {\n\topacity: .9;\n\ttransform: scale(0.95, 0.95);\n\tposition: relative;\n\ttop: 3rpx;\n\tleft: 3rpx;\n\tbox-shadow: 0px 0px 8px rgba(0, 0, 0, .1) inset;\n}\n\n.btn[disabled] {\n\topacity: 0.6;\n\tcolor: var(--white);\n}\n\n\n.btn.round {\n\tborder-radius: 5000rpx;\n}\n\n.btn.round[class*=\"border\"]::after {\n\tborder-radius: 1000rpx;\n}\n\n.btn.border-bold::after {\n\tborder: 6rpx solid currentColor;\n} "
  },
  {
    "path": "miniprogram/style/base/comm.wxss",
    "content": "@import \"base.wxss\"; \n\n@import \"avatar.wxss\"; \n@import \"background.wxss\"; \n@import \"bar.wxss\";  \n@import \"border.wxss\"; \n@import \"button.wxss\"; \n@import \"image.wxss\";  \n@import \"modal.wxss\"; \n@import \"nav.wxss\"; \n@import \"shadow.wxss\"; \n@import \"tag.wxss\";  \n@import \"icon.wxss\";  \n@import \"form.wxss\";  \n@import \"text.wxss\"; \n@import \"list.wxss\";\n@import \"load.wxss\";\n@import \"layout.wxss\"; \n@import \"animation.wxss\"; "
  },
  {
    "path": "miniprogram/style/base/form.wxss",
    "content": "/* ==================\n         表单\n ==================== */\n\n.form-group {\n\t/*background-color: var(--white);影响圆角*/\n\tpadding: 1rpx 30rpx;\n\tdisplay: flex;\n\talign-items: center;\n\tmin-height: 100rpx;\n\tjustify-content: space-between;\n\tposition: relative;\n\tborder-bottom: 1rpx solid #eee;\n}\n\n.form-group:last-child {\n\tborder-bottom: 0rpx solid #eee;\n}\n\n.form-group .title {\n\ttext-align: justify;\n\tpadding-right: 30rpx;\n\tfont-size: 30rpx;\n\tposition: relative;\n\theight: 60rpx;\n\tline-height: 60rpx;\n}\n\n.form-group.form-detail {\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: flex-start;\n}\n\n.form-group.form-detail .title {\n\tmargin-top: 16rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n}\n\n.form-group.form-detail text {\n\tfont-size: 24rpx;\n\tfont-weight: normal;\n}\n\n.form-group input {\n\tflex: 1;\n\tfont-size: 30rpx;\n\tcolor: #555;\n\tpadding-right: 20rpx;\n\theight: 60rpx;\n}\n\n.modal-form .form-group input {\n\theight: 70rpx;\n\ttext-align: right;\n\tbackground-color: #f8f8f8;\n\tborder-radius: 5rpx;\n\tcolor: #333;\n}\n\n.modal-form .form-group .title {\n\tfont-weight: normal;\n}\n\n.form-group>text[class*=\"icon-\"] {\n\tfont-size: 36rpx;\n\tpadding: 0;\n\tbox-sizing: border-box;\n}\n\n.form-group textarea {\n\tmargin: 32rpx 0 30rpx;\n\theight: 4.6em;\n\twidth: 100%;\n\tline-height: 1.2em;\n\tflex: 1;\n\tfont-size: 30rpx;\n\tpadding: 0;\n\ttext-align: left;\n\tline-height: 1.8;\n}\n\n.form-group.arrow::before {\n\tposition: absolute;\n\ttop: 0;\n\tright: 30rpx;\n\tbottom: 0;\n\tdisplay: block;\n\tmargin: auto;\n\twidth: 30rpx;\n\theight: 30rpx;\n\tcolor: var(--grey);\n\tcontent: \"\\e6a3\";\n\ttext-align: center;\n\tfont-size: 34rpx;\n\tfont-family: \"icon\";\n\tline-height: 30rpx;\n\tmargin-top: auto;\n\tmargin-right: auto;\n\tmargin-bottom: auto;\n\tmargin-left: auto;\n}\n\n.form-group .form-text {\n\tpadding-right: 40rpx;\n\tflex: 1;\n\ttext-align: right;\n\theight: 60rpx;\n\tline-height: 60rpx;\n}\n\n.form-group.align-start .title {\n\theight: 1em;\n\tmargin-top: 32rpx;\n\tline-height: 1em;\n}\n\n.form-group .picker,\n.form-group .picker-null {\n\tflex: 1;\n\tpadding-right: 40rpx;\n\toverflow: hidden;\n\tposition: relative;\n}\n\n.form-group .picker .picker,\n.form-group .picker-null .picker {\n\tline-height: 100rpx;\n\tfont-size: 28rpx;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n\toverflow: hidden;\n\twidth: 100%;\n\ttext-align: right;\n}\n\n.form-group .picker::after,\n.form-group .picker-null::after {\n\tfont-family: \"icon\";\n\tdisplay: block;\n\tcontent: \"\\e6a3\";\n\tposition: absolute;\n\tfont-size: 34rpx;\n\tcolor: var(--grey);\n\tline-height: 100rpx;\n\twidth: 60rpx;\n\ttext-align: center;\n\ttop: 0;\n\tbottom: 0;\n\tright: -20rpx;\n\tmargin: auto;\n}\n\n/* ==================\n         开关\n ==================== */\n\nswitch,\ncheckbox,\nradio {\n\tposition: relative;\n}\n\nswitch::after,\nswitch::before {\n\tfont-family: \"icon\";\n\tcontent: \"\\e645\";\n\tposition: absolute;\n\tcolor: var(--white) !important;\n\ttop: 0%;\n\tleft: 0rpx;\n\tfont-size: 26rpx;\n\tline-height: 26px;\n\twidth: 50%;\n\ttext-align: center;\n\tpointer-events: none;\n\ttransform: scale(0, 0);\n\ttransition: all 0.3s ease-in-out 0s;\n\tz-index: 9;\n\tbottom: 0;\n\theight: 26px;\n\tmargin: auto;\n}\n\nswitch::before {\n\tcontent: \"\\e646\";\n\tright: 0;\n\ttransform: scale(1, 1);\n\tleft: auto;\n}\n\nswitch[checked]::after,\nswitch.checked::after {\n\ttransform: scale(1, 1);\n}\n\nswitch[checked]::before,\nswitch.checked::before {\n\ttransform: scale(0, 0);\n}\n\nswitch[checked]::before {\n\ttransform: scale(0, 0);\n}\n\nradio::before,\ncheckbox::before {\n\tfont-family: \"icon\";\n\tcontent: \"\\e645\";\n\tposition: absolute;\n\tcolor: var(--white) !important;\n\ttop: 50%;\n\tmargin-top: -8px;\n\tright: 5px;\n\tfont-size: 32rpx;\n\tline-height: 16px;\n\tpointer-events: none;\n\ttransform: scale(1, 1);\n\ttransition: all 0.3s ease-in-out 0s;\n\tz-index: 9;\n}\n\nradio .wx-radio-input,\ncheckbox .wx-checkbox-input {\n\tmargin: 0;\n\twidth: 24px;\n\theight: 24px;\n}\n\ncheckbox.round .wx-checkbox-input {\n\tborder-radius: 100rpx;\n}\n\nswitch .wx-switch-input {\n\tborder: none;\n\tpadding: 0 24px;\n\twidth: 48px;\n\theight: 26px;\n\tmargin: 0;\n\tborder-radius: 100rpx;\n}\n\nswitch .wx-switch-input:not([class*=\"bg-\"]) {\n\tbackground: var(--grey) !important;\n}\n\nswitch .wx-switch-input::after {\n\tmargin: auto;\n\twidth: 26px;\n\theight: 26px;\n\tborder-radius: 100rpx;\n\tleft: 0rpx;\n\ttop: 0rpx;\n\tbottom: 0rpx;\n\tposition: absolute;\n\ttransform: scale(0.9, 0.9);\n\ttransition: all 0.1s ease-in-out 0s;\n}\n\nswitch .wx-switch-input.wx-switch-input-checked::after {\n\tmargin: auto;\n\tleft: 22px;\n\tbox-shadow: none;\n\ttransform: scale(0.9, 0.9);\n}\n\nradio-group {\n\tdisplay: inline-block;\n}\n\n\n\nswitch.radius .wx-switch-input::after,\nswitch.radius .wx-switch-input,\nswitch.radius .wx-switch-input::before {\n\tborder-radius: 10rpx;\n}\n\nswitch .wx-switch-input::before,\nradio.radio::before,\ncheckbox .wx-checkbox-input::before,\nradio .wx-radio-input::before,\nradio.radio::before {\n\tdisplay: none;\n}\n\nradio.radio[checked]::after {\n\tcontent: \"\";\n\tbackground-color: transparent;\n\tdisplay: block;\n\tposition: absolute;\n\twidth: 8px;\n\theight: 8px;\n\tz-index: 999;\n\ttop: 0rpx;\n\tleft: 0rpx;\n\tright: 0;\n\tbottom: 0;\n\tmargin: auto;\n\tborder-radius: 200rpx;\n\tborder: 8px solid var(--white) !important;\n}\n\n.switch-sex::after {\n\tcontent: \"\\e71c\";\n}\n\n.switch-sex::before {\n\tcontent: \"\\e71a\";\n}\n\n.switch-sex .wx-switch-input {\n\tbackground: var(--red) !important;\n\tborder-color: var(--red) !important;\n}\n\n.switch-sex[checked] .wx-switch-input {\n\tbackground: var(--blue) !important;\n\tborder-color: var(--blue) !important;\n}\n\nswitch.red[checked] .wx-switch-input,\ncheckbox.red[checked] .wx-checkbox-input,\nradio.red[checked] .wx-radio-input {\n\tborder-color: var(--red) !important;\n}\n\nswitch.orange[checked] .wx-switch-input,\ncheckbox.orange[checked] .wx-checkbox-input,\nradio.orange[checked] .wx-radio-input {\n\tborder-color: var(--orange) !important;\n}\n\nswitch.yellow[checked] .wx-switch-input,\ncheckbox.yellow[checked] .wx-checkbox-input,\nradio.yellow[checked] .wx-radio-input {\n\tborder-color: var(--yellow) !important;\n}\n\nswitch.olive[checked] .wx-switch-input,\ncheckbox.olive[checked] .wx-checkbox-input,\nradio.olive[checked] .wx-radio-input {\n\tborder-color: var(--olive) !important;\n}\n\nswitch.green[checked] .wx-switch-input,\ncheckbox.green[checked] .wx-checkbox-input,\ncheckbox[checked] .wx-checkbox-input,\nradio.green[checked] .wx-radio-input {\n\tborder-color: var(--green) !important;\n}\n\nswitch.cyan[checked] .wx-switch-input,\ncheckbox.cyan[checked] .wx-checkbox-input,\nradio.cyan[checked] .wx-radio-input {\n\tborder-color: var(--cyan) !important;\n}\n\nswitch.blue[checked] .wx-switch-input,\ncheckbox.blue[checked] .wx-checkbox-input,\nradio.blue[checked] .wx-radio-input {\n\tborder-color: var(--blue) !important;\n}\n\nswitch.purple[checked] .wx-switch-input,\ncheckbox.purple[checked] .wx-checkbox-input,\nradio.purple[checked] .wx-radio-input {\n\tborder-color: var(--purple) !important;\n}\n\nswitch.mauve[checked] .wx-switch-input,\ncheckbox.mauve[checked] .wx-checkbox-input,\nradio.mauve[checked] .wx-radio-input {\n\tborder-color: var(--mauve) !important;\n}\n\nswitch.pink[checked] .wx-switch-input,\ncheckbox.pink[checked] .wx-checkbox-input,\nradio.pink[checked] .wx-radio-input {\n\tborder-color: var(--pink) !important;\n}\n\nswitch.brown[checked] .wx-switch-input,\ncheckbox.brown[checked] .wx-checkbox-input,\nradio.brown[checked] .wx-radio-input {\n\tborder-color: var(--brown) !important;\n}\n\nswitch.grey[checked] .wx-switch-input,\ncheckbox.grey[checked] .wx-checkbox-input,\nradio.grey[checked] .wx-radio-input {\n\tborder-color: var(--grey) !important;\n}\n\nswitch.gray[checked] .wx-switch-input,\ncheckbox.gray[checked] .wx-checkbox-input,\nradio.gray[checked] .wx-radio-input {\n\tborder-color: var(--grey) !important;\n}\n\nswitch.black[checked] .wx-switch-input,\ncheckbox.black[checked] .wx-checkbox-input,\nradio.black[checked] .wx-radio-input {\n\tborder-color: var(--black) !important;\n}\n\nswitch.white[checked] .wx-switch-input,\ncheckbox.white[checked] .wx-checkbox-input,\nradio.white[checked] .wx-radio-input {\n\tborder-color: var(--white) !important;\n}\n\nswitch.red[checked] .wx-switch-input.wx-switch-input-checked,\ncheckbox.red[checked] .wx-checkbox-input,\nradio.red[checked] .wx-radio-input {\n\tbackground-color: var(--red) !important;\n\tcolor: var(--white) !important;\n}\n\nswitch.orange[checked] .wx-switch-input,\ncheckbox.orange[checked] .wx-checkbox-input,\nradio.orange[checked] .wx-radio-input {\n\tbackground-color: var(--orange) !important;\n\tcolor: var(--white) !important;\n}\n\nswitch.yellow[checked] .wx-switch-input,\ncheckbox.yellow[checked] .wx-checkbox-input,\nradio.yellow[checked] .wx-radio-input {\n\tbackground-color: var(--yellow) !important;\n\tcolor: var(--black) !important;\n}\n\nswitch.olive[checked] .wx-switch-input,\ncheckbox.olive[checked] .wx-checkbox-input,\nradio.olive[checked] .wx-radio-input {\n\tbackground-color: var(--olive) !important;\n\tcolor: var(--white) !important;\n}\n\nswitch.green[checked] .wx-switch-input,\nswitch[checked] .wx-switch-input,\ncheckbox.green[checked] .wx-checkbox-input,\ncheckbox[checked] .wx-checkbox-input,\nradio.green[checked] .wx-radio-input,\nradio[checked] .wx-radio-input {\n\tbackground-color: var(--green) !important;\n\tcolor: var(--white) !important;\n}\n\nswitch.cyan[checked] .wx-switch-input,\ncheckbox.cyan[checked] .wx-checkbox-input,\nradio.cyan[checked] .wx-radio-input {\n\tbackground-color: var(--cyan) !important;\n\tcolor: var(--white) !important;\n}\n\nswitch.blue[checked] .wx-switch-input,\ncheckbox.blue[checked] .wx-checkbox-input,\nradio.blue[checked] .wx-radio-input {\n\tbackground-color: var(--blue) !important;\n\tcolor: var(--white) !important;\n}\n\nswitch.purple[checked] .wx-switch-input,\ncheckbox.purple[checked] .wx-checkbox-input,\nradio.purple[checked] .wx-radio-input {\n\tbackground-color: var(--purple) !important;\n\tcolor: var(--white) !important;\n}\n\nswitch.mauve[checked] .wx-switch-input,\ncheckbox.mauve[checked] .wx-checkbox-input,\nradio.mauve[checked] .wx-radio-input {\n\tbackground-color: var(--mauve) !important;\n\tcolor: var(--white) !important;\n}\n\nswitch.pink[checked] .wx-switch-input,\ncheckbox.pink[checked] .wx-checkbox-input,\nradio.pink[checked] .wx-radio-input {\n\tbackground-color: var(--pink) !important;\n\tcolor: var(--white) !important;\n}\n\nswitch.brown[checked] .wx-switch-input,\ncheckbox.brown[checked] .wx-checkbox-input,\nradio.brown[checked] .wx-radio-input {\n\tbackground-color: var(--brown) !important;\n\tcolor: var(--white) !important;\n}\n\nswitch.grey[checked] .wx-switch-input,\ncheckbox.grey[checked] .wx-checkbox-input,\nradio.grey[checked] .wx-radio-input {\n\tbackground-color: var(--grey) !important;\n\tcolor: var(--white) !important;\n}\n\nswitch.gray[checked] .wx-switch-input,\ncheckbox.gray[checked] .wx-checkbox-input,\nradio.gray[checked] .wx-radio-input {\n\tbackground-color: #f0f0f0 !important;\n\tcolor: var(--black) !important;\n}\n\nswitch.black[checked] .wx-switch-input,\ncheckbox.black[checked] .wx-checkbox-input,\nradio.black[checked] .wx-radio-input {\n\tbackground-color: var(--black) !important;\n\tcolor: var(--white) !important;\n}\n\nswitch.white[checked] .wx-switch-input,\ncheckbox.white[checked] .wx-checkbox-input,\nradio.white[checked] .wx-radio-input {\n\tbackground-color: var(--white) !important;\n\tcolor: var(--black) !important;\n}\n\n.form-group .upload-img {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\toverflow: hidden;\n\tflex: 1;\n}\n\n.form-group .upload-img>view {\n\twidth: 25%;\n\tpadding-bottom: calc((100% - 60rpx)/4);\n\theight: 0;\n\twidth: calc((100% - 60rpx)/4);\n\tmargin-right: 12rpx;\n\tmargin-bottom: 20rpx;\n\tborder-radius: 6rpx;\n\tposition: relative;\n\toverflow: hidden;\n}\n\n.form-group .upload-img .bg-img {\n\tbackground-size: cover;\n\tbackground-position: center;\n\tbackground-repeat: no-repeat;\n}\n\n.form-group .upload-img .bg-img image {\n\twidth: 100%;\n\theight: 100%;\n\tposition: absolute;\n}\n\n.form-group .upload-img>view>text[class*=\"icon-\"] {\n\tfont-size: 52rpx;\n\tposition: absolute;\n\tcolor: var(--grey);\n\tmargin: auto;\n\ttop: 0;\n\tbottom: 0;\n\tleft: 0;\n\tright: 0;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tflex-direction: column;\n}\n\n.form-group .upload-img .tag {\n\tposition: absolute;\n\tright: 0;\n\ttop: 0;\n\tborder-bottom-left-radius: 6rpx;\n\tpadding: 6rpx 12rpx;\n\theight: auto;\n\tbackground-color: rgba(0, 0, 0, 0.5);\n}\n\n.form-box .hint-desc {\n\twidth: 100%;\n\tcolor: #999;\n\tpadding: 0rpx 24rpx 12rpx 24rpx;\n}\n\n.form-box .hint-desc.error {\n\tcolor: #e54d42;\n\tfont-size: 24rpx;\n}\n\n.form-box .hint-desc.error::before {\n\tfont-family: \"icon\";\n\tfont-size: 24rpx !important;\n\tdisplay: inline-block;\n\tcontent: \"\\e659\";\n\tmargin-right: 2rpx; \n}\n\n.form-box .hint-desc.error::before {\n\tfont-size: 32rpx;\n}\n\n.phc {\n\tcolor: #999;\n}"
  },
  {
    "path": "miniprogram/style/base/icon.wxss",
    "content": "@keyframes icon-spin {\n\t0% {\n\t\t-webkit-transform: rotate(0);\n\t\ttransform: rotate(0);\n\t}\n\n\t100% {\n\t\t-webkit-transform: rotate(359deg);\n\t\ttransform: rotate(359deg);\n\t}\n}\n\n.iconfont-spin {\n\t-webkit-animation: icon-spin 2s infinite linear;\n\tanimation: icon-spin 2s infinite linear;\n\tdisplay: inline-block;\n}\n\n.iconfont-pulse {\n\t-webkit-animation: icon-spin 1s infinite steps(8);\n\tanimation: icon-spin 1s infinite steps(8);\n\tdisplay: inline-block;\n}\n\n[class*=\"icon-\"] {\n\tfont-family: \"icon\";\n\tfont-size: inherit;\n\tfont-style: normal;\n}\n\n@font-face {\n\tfont-family: \"icon\"; \n\t/* IE9*/\n\tsrc:  \n\t\turl('data:application/x-font-woff;charset=utf-8;base64,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') format('woff') \n}\n\n.icon-appreciate:before {\n\tcontent: \"\\e644\";\n}\n\n.icon-check:before {\n\tcontent: \"\\e645\";\n}\n\n.icon-close:before {\n\tcontent: \"\\e646\";\n}\n\n.icon-edit:before {\n\tcontent: \"\\e649\";\n}\n\n.icon-emoji:before {\n\tcontent: \"\\e64a\";\n}\n\n.icon-favorfill:before {\n\tcontent: \"\\e64b\";\n}\n\n.icon-favor:before {\n\tcontent: \"\\e64c\";\n}\n\n.icon-loading:before {\n\tcontent: \"\\e64f\";\n}\n\n.icon-locationfill:before {\n\tcontent: \"\\e650\";\n}\n\n.icon-location:before {\n\tcontent: \"\\e651\";\n}\n\n.icon-phone:before {\n\tcontent: \"\\e652\";\n}\n\n.icon-roundcheckfill:before {\n\tcontent: \"\\e656\";\n}\n\n.icon-roundcheck:before {\n\tcontent: \"\\e657\";\n}\n\n.icon-roundclosefill:before {\n\tcontent: \"\\e658\";\n}\n\n.icon-roundclose:before {\n\tcontent: \"\\e659\";\n}\n\n.icon-roundrightfill:before {\n\tcontent: \"\\e65a\";\n}\n\n.icon-roundright:before {\n\tcontent: \"\\e65b\";\n}\n\n.icon-search:before {\n\tcontent: \"\\e65c\";\n}\n\n.icon-taxi:before {\n\tcontent: \"\\e65d\";\n}\n\n.icon-timefill:before {\n\tcontent: \"\\e65e\";\n}\n\n.icon-time:before {\n\tcontent: \"\\e65f\";\n}\n\n.icon-unfold:before {\n\tcontent: \"\\e661\";\n}\n\n.icon-warnfill:before {\n\tcontent: \"\\e662\";\n}\n\n.icon-warn:before {\n\tcontent: \"\\e663\";\n}\n\n.icon-camerafill:before {\n\tcontent: \"\\e664\";\n}\n\n.icon-camera:before {\n\tcontent: \"\\e665\";\n}\n\n.icon-commentfill:before {\n\tcontent: \"\\e666\";\n}\n\n.icon-comment:before {\n\tcontent: \"\\e667\";\n}\n\n.icon-likefill:before {\n\tcontent: \"\\e668\";\n}\n\n.icon-like:before {\n\tcontent: \"\\e669\";\n}\n\n.icon-notificationfill:before {\n\tcontent: \"\\e66a\";\n}\n\n.icon-notification:before {\n\tcontent: \"\\e66b\";\n}\n\n.icon-order:before {\n\tcontent: \"\\e66c\";\n}\n\n.icon-samefill:before {\n\tcontent: \"\\e66d\";\n}\n\n.icon-same:before {\n\tcontent: \"\\e66e\";\n}\n\n.icon-deliver:before {\n\tcontent: \"\\e671\";\n}\n\n.icon-evaluate:before {\n\tcontent: \"\\e672\";\n}\n\n.icon-pay:before {\n\tcontent: \"\\e673\";\n}\n\n.icon-send:before {\n\tcontent: \"\\e675\";\n}\n\n.icon-shop:before {\n\tcontent: \"\\e676\";\n}\n\n.icon-ticket:before {\n\tcontent: \"\\e677\";\n}\n\n.icon-back:before {\n\tcontent: \"\\e679\";\n}\n\n.icon-cascades:before {\n\tcontent: \"\\e67c\";\n}\n\n.icon-discover:before {\n\tcontent: \"\\e67e\";\n}\n\n.icon-list:before {\n\tcontent: \"\\e682\";\n}\n\n.icon-more:before {\n\tcontent: \"\\e684\";\n}\n\n.icon-scan:before {\n\tcontent: \"\\e689\";\n}\n\n.icon-settings:before {\n\tcontent: \"\\e68a\";\n}\n\n.icon-questionfill:before {\n\tcontent: \"\\e690\";\n}\n\n.icon-question:before {\n\tcontent: \"\\e691\";\n}\n\n.icon-shopfill:before {\n\tcontent: \"\\e697\";\n}\n\n.icon-form:before {\n\tcontent: \"\\e699\";\n}\n\n.icon-pic:before {\n\tcontent: \"\\e69b\";\n}\n\n.icon-filter:before {\n\tcontent: \"\\e69c\";\n}\n\n.icon-footprint:before {\n\tcontent: \"\\e69d\";\n}\n\n.icon-top:before {\n\tcontent: \"\\e69e\";\n}\n\n.icon-pulldown:before {\n\tcontent: \"\\e69f\";\n}\n\n.icon-pullup:before {\n\tcontent: \"\\e6a0\";\n}\n\n.icon-right:before {\n\tcontent: \"\\e6a3\";\n}\n\n.icon-refresh:before {\n\tcontent: \"\\e6a4\";\n}\n\n.icon-moreandroid:before {\n\tcontent: \"\\e6a5\";\n}\n\n.icon-deletefill:before {\n\tcontent: \"\\e6a6\";\n}\n\n.icon-refund:before {\n\tcontent: \"\\e6ac\";\n}\n\n.icon-cart:before {\n\tcontent: \"\\e6af\";\n}\n\n.icon-qrcode:before {\n\tcontent: \"\\e6b0\";\n}\n\n.icon-remind:before {\n\tcontent: \"\\e6b2\";\n}\n\n.icon-delete:before {\n\tcontent: \"\\e6b4\";\n}\n\n.icon-profile:before {\n\tcontent: \"\\e6b7\";\n}\n\n.icon-home:before {\n\tcontent: \"\\e6b8\";\n}\n\n.icon-cartfill:before {\n\tcontent: \"\\e6b9\";\n}\n\n.icon-discoverfill:before {\n\tcontent: \"\\e6ba\";\n}\n\n.icon-homefill:before {\n\tcontent: \"\\e6bb\";\n}\n\n.icon-message:before {\n\tcontent: \"\\e6bc\";\n}\n\n.icon-addressbook:before {\n\tcontent: \"\\e6bd\";\n}\n\n.icon-link:before {\n\tcontent: \"\\e6bf\";\n}\n\n.icon-lock:before {\n\tcontent: \"\\e6c0\";\n}\n\n.icon-unlock:before {\n\tcontent: \"\\e6c2\";\n}\n\n.icon-vip:before {\n\tcontent: \"\\e6c3\";\n}\n\n.icon-weibo:before {\n\tcontent: \"\\e6c4\";\n}\n\n.icon-activity:before {\n\tcontent: \"\\e6c5\";\n}\n\n.icon-friendaddfill:before {\n\tcontent: \"\\e6c9\";\n}\n\n.icon-friendadd:before {\n\tcontent: \"\\e6ca\";\n}\n\n.icon-friendfamous:before {\n\tcontent: \"\\e6cb\";\n}\n\n.icon-friend:before {\n\tcontent: \"\\e6cc\";\n}\n\n.icon-goods:before {\n\tcontent: \"\\e6cd\";\n}\n\n.icon-selection:before {\n\tcontent: \"\\e6ce\";\n}\n\n.icon-explore:before {\n\tcontent: \"\\e6d2\";\n}\n\n.icon-present:before {\n\tcontent: \"\\e6d3\";\n}\n\n.icon-squarecheckfill:before {\n\tcontent: \"\\e6d4\";\n}\n\n.icon-square:before {\n\tcontent: \"\\e6d5\";\n}\n\n.icon-squarecheck:before {\n\tcontent: \"\\e6d6\";\n}\n\n.icon-round:before {\n\tcontent: \"\\e6d7\";\n}\n\n.icon-roundaddfill:before {\n\tcontent: \"\\e6d8\";\n}\n\n.icon-roundadd:before {\n\tcontent: \"\\e6d9\";\n}\n\n.icon-add:before {\n\tcontent: \"\\e6da\";\n}\n\n.icon-notificationforbidfill:before {\n\tcontent: \"\\e6db\";\n}\n\n.icon-explorefill:before {\n\tcontent: \"\\e6dd\";\n}\n\n.icon-fold:before {\n\tcontent: \"\\e6de\";\n}\n\n.icon-game:before {\n\tcontent: \"\\e6df\";\n}\n\n.icon-redpacket:before {\n\tcontent: \"\\e6e0\";\n}\n\n.icon-selectionfill:before {\n\tcontent: \"\\e6e1\";\n}\n\n.icon-similar:before {\n\tcontent: \"\\e6e2\";\n}\n\n.icon-appreciatefill:before {\n\tcontent: \"\\e6e3\";\n}\n\n.icon-infofill:before {\n\tcontent: \"\\e6e4\";\n}\n\n.icon-info:before {\n\tcontent: \"\\e6e5\";\n}\n\n.icon-forwardfill:before {\n\tcontent: \"\\e6ea\";\n}\n\n.icon-forward:before {\n\tcontent: \"\\e6eb\";\n}\n\n.icon-rechargefill:before {\n\tcontent: \"\\e6ec\";\n}\n\n.icon-recharge:before {\n\tcontent: \"\\e6ed\";\n}\n\n.icon-vipcard:before {\n\tcontent: \"\\e6ee\";\n}\n\n.icon-voice:before {\n\tcontent: \"\\e6ef\";\n}\n\n.icon-voicefill:before {\n\tcontent: \"\\e6f0\";\n}\n\n.icon-friendfavor:before {\n\tcontent: \"\\e6f1\";\n}\n\n.icon-wifi:before {\n\tcontent: \"\\e6f2\";\n}\n\n.icon-share:before {\n\tcontent: \"\\e6f3\";\n}\n\n.icon-wefill:before {\n\tcontent: \"\\e6f4\";\n}\n\n.icon-we:before {\n\tcontent: \"\\e6f5\";\n}\n\n.icon-lightauto:before {\n\tcontent: \"\\e6f6\";\n}\n\n.icon-lightforbid:before {\n\tcontent: \"\\e6f7\";\n}\n\n.icon-lightfill:before {\n\tcontent: \"\\e6f8\";\n}\n\n.icon-camerarotate:before {\n\tcontent: \"\\e6f9\";\n}\n\n.icon-light:before {\n\tcontent: \"\\e6fa\";\n}\n\n.icon-barcode:before {\n\tcontent: \"\\e6fb\";\n}\n\n.icon-flashlightclose:before {\n\tcontent: \"\\e6fc\";\n}\n\n.icon-flashlightopen:before {\n\tcontent: \"\\e6fd\";\n}\n\n.icon-searchlist:before {\n\tcontent: \"\\e6fe\";\n}\n\n.icon-service:before {\n\tcontent: \"\\e6ff\";\n}\n\n.icon-sort:before {\n\tcontent: \"\\e700\";\n}\n\n.icon-down:before {\n\tcontent: \"\\e703\";\n}\n\n.icon-mobile:before {\n\tcontent: \"\\e704\";\n}\n\n.icon-mobilefill:before {\n\tcontent: \"\\e705\";\n}\n\n.icon-copy:before {\n\tcontent: \"\\e706\";\n}\n\n.icon-countdownfill:before {\n\tcontent: \"\\e707\";\n}\n\n.icon-countdown:before {\n\tcontent: \"\\e708\";\n}\n\n.icon-noticefill:before {\n\tcontent: \"\\e709\";\n}\n\n.icon-notice:before {\n\tcontent: \"\\e70a\";\n}\n\n.icon-upstagefill:before {\n\tcontent: \"\\e70e\";\n}\n\n.icon-upstage:before {\n\tcontent: \"\\e70f\";\n}\n\n.icon-babyfill:before {\n\tcontent: \"\\e710\";\n}\n\n.icon-baby:before {\n\tcontent: \"\\e711\";\n}\n\n.icon-brandfill:before {\n\tcontent: \"\\e712\";\n}\n\n.icon-brand:before {\n\tcontent: \"\\e713\";\n}\n\n.icon-choicenessfill:before {\n\tcontent: \"\\e714\";\n}\n\n.icon-choiceness:before {\n\tcontent: \"\\e715\";\n}\n\n.icon-clothesfill:before {\n\tcontent: \"\\e716\";\n}\n\n.icon-clothes:before {\n\tcontent: \"\\e717\";\n}\n\n.icon-creativefill:before {\n\tcontent: \"\\e718\";\n}\n\n.icon-creative:before {\n\tcontent: \"\\e719\";\n}\n\n.icon-female:before {\n\tcontent: \"\\e71a\";\n}\n\n.icon-keyboard:before {\n\tcontent: \"\\e71b\";\n}\n\n.icon-male:before {\n\tcontent: \"\\e71c\";\n}\n\n.icon-newfill:before {\n\tcontent: \"\\e71d\";\n}\n\n.icon-new:before {\n\tcontent: \"\\e71e\";\n}\n\n.icon-pullleft:before {\n\tcontent: \"\\e71f\";\n}\n\n.icon-pullright:before {\n\tcontent: \"\\e720\";\n}\n\n.icon-rankfill:before {\n\tcontent: \"\\e721\";\n}\n\n.icon-rank:before {\n\tcontent: \"\\e722\";\n}\n\n.icon-bad:before {\n\tcontent: \"\\e723\";\n}\n\n.icon-cameraadd:before {\n\tcontent: \"\\e724\";\n}\n\n.icon-focus:before {\n\tcontent: \"\\e725\";\n}\n\n.icon-friendfill:before {\n\tcontent: \"\\e726\";\n}\n\n.icon-cameraaddfill:before {\n\tcontent: \"\\e727\";\n}\n\n.icon-apps:before {\n\tcontent: \"\\e729\";\n}\n\n.icon-paintfill:before {\n\tcontent: \"\\e72a\";\n}\n\n.icon-paint:before {\n\tcontent: \"\\e72b\";\n}\n\n.icon-picfill:before {\n\tcontent: \"\\e72c\";\n}\n\n.icon-refresharrow:before {\n\tcontent: \"\\e72d\";\n}\n\n.icon-refresharrow.up {\n\ttransform: rotateX(180deg);\n}\n\n.icon-colorlens:before {\n\tcontent: \"\\e6e6\";\n}\n\n.icon-markfill:before {\n\tcontent: \"\\e730\";\n}\n\n.icon-mark:before {\n\tcontent: \"\\e731\";\n}\n\n.icon-presentfill:before {\n\tcontent: \"\\e732\";\n}\n\n.icon-repeal:before {\n\tcontent: \"\\e733\";\n}\n\n.icon-album:before {\n\tcontent: \"\\e734\";\n}\n\n.icon-peoplefill:before {\n\tcontent: \"\\e735\";\n}\n\n.icon-people:before {\n\tcontent: \"\\e736\";\n}\n\n.icon-servicefill:before {\n\tcontent: \"\\e737\";\n}\n\n.icon-repair:before {\n\tcontent: \"\\e738\";\n}\n\n.icon-file:before {\n\tcontent: \"\\e739\";\n}\n\n.icon-repairfill:before {\n\tcontent: \"\\e73a\";\n}\n\n.icon-taoxiaopu:before {\n\tcontent: \"\\e73b\";\n}\n\n.icon-weixin:before {\n\tcontent: \"\\e612\";\n}\n\n.icon-attentionfill:before {\n\tcontent: \"\\e73c\";\n}\n\n.icon-attention:before {\n\tcontent: \"\\e73d\";\n}\n\n.icon-commandfill:before {\n\tcontent: \"\\e73e\";\n}\n\n.icon-command:before {\n\tcontent: \"\\e73f\";\n}\n\n.icon-communityfill:before {\n\tcontent: \"\\e740\";\n}\n\n.icon-community:before {\n\tcontent: \"\\e741\";\n}\n\n.icon-read:before {\n\tcontent: \"\\e742\";\n}\n\n.icon-calendar:before {\n\tcontent: \"\\e74a\";\n}\n\n.icon-cut:before {\n\tcontent: \"\\e74b\";\n}\n\n.icon-magic:before {\n\tcontent: \"\\e74c\";\n}\n\n.icon-backwardfill:before {\n\tcontent: \"\\e74d\";\n}\n\n.icon-playfill:before {\n\tcontent: \"\\e74f\";\n}\n\n.icon-stop:before {\n\tcontent: \"\\e750\";\n}\n\n.icon-tagfill:before {\n\tcontent: \"\\e751\";\n}\n\n.icon-tag:before {\n\tcontent: \"\\e752\";\n}\n\n.icon-group:before {\n\tcontent: \"\\e753\";\n}\n\n.icon-all:before {\n\tcontent: \"\\e755\";\n}\n\n.icon-backdelete:before {\n\tcontent: \"\\e756\";\n}\n\n.icon-hotfill:before {\n\tcontent: \"\\e757\";\n}\n\n.icon-hot:before {\n\tcontent: \"\\e758\";\n}\n\n.icon-post:before {\n\tcontent: \"\\e759\";\n}\n\n.icon-radiobox:before {\n\tcontent: \"\\e75b\";\n}\n\n.icon-rounddown:before {\n\tcontent: \"\\e75c\";\n}\n\n.icon-upload:before {\n\tcontent: \"\\e75d\";\n}\n\n.icon-writefill:before {\n\tcontent: \"\\e760\";\n}\n\n.icon-write:before {\n\tcontent: \"\\e761\";\n}\n\n.icon-radioboxfill:before {\n\tcontent: \"\\e763\";\n}\n\n.icon-punch:before {\n\tcontent: \"\\e764\";\n}\n\n.icon-shake:before {\n\tcontent: \"\\e765\";\n}\n\n.icon-move:before {\n\tcontent: \"\\e768\";\n}\n\n.icon-safe:before {\n\tcontent: \"\\e769\";\n}\n\n.icon-activityfill:before {\n\tcontent: \"\\e775\";\n}\n\n.icon-crownfill:before {\n\tcontent: \"\\e776\";\n}\n\n.icon-crown:before {\n\tcontent: \"\\e777\";\n}\n\n.icon-goodsfill:before {\n\tcontent: \"\\e778\";\n}\n\n.icon-messagefill:before {\n\tcontent: \"\\e779\";\n}\n\n.icon-profilefill:before {\n\tcontent: \"\\e77a\";\n}\n\n.icon-sound:before {\n\tcontent: \"\\e77b\";\n}\n\n.icon-sponsorfill:before {\n\tcontent: \"\\e77c\";\n}\n\n.icon-sponsor:before {\n\tcontent: \"\\e77d\";\n}\n\n.icon-upblock:before {\n\tcontent: \"\\e77e\";\n}\n\n.icon-weblock:before {\n\tcontent: \"\\e77f\";\n}\n\n.icon-weunblock:before {\n\tcontent: \"\\e780\";\n}\n\n.icon-my:before {\n\tcontent: \"\\e78b\";\n}\n\n.icon-myfill:before {\n\tcontent: \"\\e78c\";\n}\n\n.icon-emojifill:before {\n\tcontent: \"\\e78d\";\n}\n\n.icon-emojiflashfill:before {\n\tcontent: \"\\e78e\";\n}\n\n.icon-flashbuyfill:before {\n\tcontent: \"\\e78f\";\n}\n\n.icon-text:before {\n\tcontent: \"\\e791\";\n}\n\n.icon-goodsfavor:before {\n\tcontent: \"\\e794\";\n}\n\n.icon-musicfill:before {\n\tcontent: \"\\e795\";\n}\n\n.icon-musicforbidfill:before {\n\tcontent: \"\\e796\";\n}\n\n.icon-card:before {\n\tcontent: \"\\e624\";\n}\n\n.icon-triangledownfill:before {\n\tcontent: \"\\e79b\";\n}\n\n.icon-triangleupfill:before {\n\tcontent: \"\\e79c\";\n}\n\n.icon-roundleftfill-copy:before {\n\tcontent: \"\\e79e\";\n}\n\n.icon-font:before {\n\tcontent: \"\\e76a\";\n}\n\n.icon-title:before {\n\tcontent: \"\\e82f\";\n}\n\n.icon-recordfill:before {\n\tcontent: \"\\e7a4\";\n}\n\n.icon-record:before {\n\tcontent: \"\\e7a6\";\n}\n\n.icon-cardboardfill:before {\n\tcontent: \"\\e7a9\";\n}\n\n.icon-cardboard:before {\n\tcontent: \"\\e7aa\";\n}\n\n.icon-formfill:before {\n\tcontent: \"\\e7ab\";\n}\n\n.icon-coin:before {\n\tcontent: \"\\e7ac\";\n}\n\n.icon-cardboardforbid:before {\n\tcontent: \"\\e7af\";\n}\n\n.icon-circlefill:before {\n\tcontent: \"\\e7b0\";\n}\n\n.icon-circle:before {\n\tcontent: \"\\e7b1\";\n}\n\n.icon-attentionforbid:before {\n\tcontent: \"\\e7b2\";\n}\n\n.icon-attentionforbidfill:before {\n\tcontent: \"\\e7b3\";\n}\n\n.icon-attentionfavorfill:before {\n\tcontent: \"\\e7b4\";\n}\n\n.icon-attentionfavor:before {\n\tcontent: \"\\e7b5\";\n}\n\n.icon-titles:before {\n\tcontent: \"\\e701\";\n}\n\n.icon-icloading:before {\n\tcontent: \"\\e67a\";\n}\n\n.icon-full:before {\n\tcontent: \"\\e7bc\";\n}\n\n.icon-mail:before {\n\tcontent: \"\\e7bd\";\n}\n\n.icon-peoplelist:before {\n\tcontent: \"\\e7be\";\n}\n\n.icon-goodsnewfill:before {\n\tcontent: \"\\e7bf\";\n}\n\n.icon-goodsnew:before {\n\tcontent: \"\\e7c0\";\n}\n\n.icon-medalfill:before {\n\tcontent: \"\\e7c1\";\n}\n\n.icon-medal:before {\n\tcontent: \"\\e7c2\";\n}\n\n.icon-newsfill:before {\n\tcontent: \"\\e7c3\";\n}\n\n.icon-newshotfill:before {\n\tcontent: \"\\e7c4\";\n}\n\n.icon-newshot:before {\n\tcontent: \"\\e7c5\";\n}\n\n.icon-news:before {\n\tcontent: \"\\e7c6\";\n}\n\n.icon-videofill:before {\n\tcontent: \"\\e7c7\";\n}\n\n.icon-video:before {\n\tcontent: \"\\e7c8\";\n}\n\n.icon-exit:before {\n\tcontent: \"\\e7cb\";\n}\n\n.icon-skinfill:before {\n\tcontent: \"\\e7cc\";\n}\n\n.icon-skin:before {\n\tcontent: \"\\e7cd\";\n}\n\n.icon-moneybagfill:before {\n\tcontent: \"\\e7ce\";\n}\n\n.icon-usefullfill:before {\n\tcontent: \"\\e7cf\";\n}\n\n.icon-usefull:before {\n\tcontent: \"\\e7d0\";\n}\n\n.icon-moneybag:before {\n\tcontent: \"\\e7d1\";\n}\n\n.icon-redpacket_fill:before {\n\tcontent: \"\\e7d3\";\n}\n\n.icon-subscription:before {\n\tcontent: \"\\e7d4\";\n}\n\n.icon-loading1:before {\n\tcontent: \"\\e633\";\n}\n\n.icon-github:before {\n\tcontent: \"\\e692\";\n}\n\n.icon-global:before {\n\tcontent: \"\\e7eb\";\n}\n\n.icon-settingsfill:before {\n\tcontent: \"\\e6ab\";\n}\n\n.icon-back_android:before {\n\tcontent: \"\\e7ed\";\n}\n\n.icon-expressman:before {\n\tcontent: \"\\e7ef\";\n}\n\n.icon-evaluate_fill:before {\n\tcontent: \"\\e7f0\";\n}\n\n.icon-group_fill:before {\n\tcontent: \"\\e7f5\";\n}\n\n.icon-play_forward_fill:before {\n\tcontent: \"\\e7f6\";\n}\n\n.icon-deliver_fill:before {\n\tcontent: \"\\e7f7\";\n}\n\n.icon-notice_forbid_fill:before {\n\tcontent: \"\\e7f8\";\n}\n\n.icon-fork:before {\n\tcontent: \"\\e60c\";\n}\n\n.icon-pick:before {\n\tcontent: \"\\e7fa\";\n}\n\n.icon-wenzi:before {\n\tcontent: \"\\e6a7\";\n}\n\n.icon-ellipse:before {\n\tcontent: \"\\e600\";\n}\n\n.icon-qr_code:before {\n\tcontent: \"\\e61b\";\n}\n\n.icon-dianhua:before {\n\tcontent: \"\\e64d\";\n}\n\n.icon-icon:before {\n\tcontent: \"\\e602\";\n}\n\n.icon-loading2:before {\n\tcontent: \"\\e7f1\";\n}\n\n.icon-btn:before {\n\tcontent: \"\\e601\";\n}\n"
  },
  {
    "path": "miniprogram/style/base/image.wxss",
    "content": "\n/* ==================\n          图片\n ==================== */\n\n image {\n\tmax-width: 100%;\n\tdisplay: inline-block;\n\tposition: relative;\n\tz-index: 0;\n}\n\nimage.loading::before {\n\tcontent: \"\";\n\tbackground-color: #f5f5f5;\n\tdisplay: block;\n\tposition: absolute;\n\twidth: 100%;\n\theight: 100%;\n\tz-index: -2;\n}\n\nimage.loading::after {\n\tcontent: \"\\e7f1\";\n\tfont-family: \"icon\";\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\twidth: 32rpx;\n\theight: 32rpx;\n\tline-height: 32rpx;\n\tright: 0;\n\tbottom: 0;\n\tz-index: -1;\n\tfont-size: 32rpx;\n\tmargin: auto;\n\tcolor: #ccc;\n\t-webkit-animation: icon-spin 2s infinite linear;\n\tanimation: icon-spin 2s infinite linear;\n\tdisplay: block;\n}"
  },
  {
    "path": "miniprogram/style/base/layout.wxss",
    "content": "/* ==================\n          布局\n ==================== */\n\n/*  -- flex弹性布局 -- */\n\n.flex {\n\tdisplay: flex;\n}\n\n.flex-row {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: row;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.flex-column {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.basis-xs {\n\tflex-basis: 20%;\n}\n\n.basis-sm {\n\tflex-basis: 40%;\n}\n\n.basis-df {\n\tflex-basis: 50%;\n}\n\n.basis-lg {\n\tflex-basis: 60%;\n}\n\n.basis-xl {\n\tflex-basis: 80%;\n}\n\n.flex-sub {\n\tflex: 1;\n}\n\n.flex-twice {\n\tflex: 2;\n}\n\n.flex-treble {\n\tflex: 3;\n}\n\n.flex-direction {\n\tflex-direction: column;\n}\n\n.flex-wrap {\n\tflex-wrap: wrap;\n}\n\n.align-start {\n\talign-items: flex-start;\n}\n\n.align-end {\n\talign-items: flex-end;\n}\n\n.align-center {\n\talign-items: center;\n}\n\n.align-stretch {\n\talign-items: stretch;\n}\n\n.self-start {\n\talign-self: flex-start;\n}\n\n.self-center {\n\talign-self: flex-center;\n}\n\n.self-end {\n\talign-self: flex-end;\n}\n\n.self-stretch {\n\talign-self: stretch;\n}\n\n.align-stretch {\n\talign-items: stretch;\n}\n\n.justify-start {\n\tjustify-content: flex-start;\n}\n\n.justify-end {\n\tjustify-content: flex-end;\n}\n\n.justify-center {\n\tjustify-content: center;\n}\n\n.justify-between {\n\tjustify-content: space-between;\n}\n\n.justify-around {\n\tjustify-content: space-around;\n}\n\n/*  -- 内外边距 -- */\n\n.margin-0 {\n\tmargin: 0;\n}\n\n.margin-xxs {\n\tmargin: 5rpx;\n}\n\n.margin-xs {\n\tmargin: 10rpx;\n}\n\n.margin-s {\n\tmargin: 20rpx;\n}\n\n.margin {\n\tmargin: 30rpx;\n}\n\n.margin-lg {\n\tmargin: 40rpx;\n}\n\n.margin-xl {\n\tmargin: 50rpx;\n}\n\n.margin-xxl {\n\tmargin: 60rpx;\n}\n\n.margin-top-xxxs {\n\tmargin-top: 5rpx;\n}\n\n.margin-top-xxs {\n\tmargin-top: 5rpx;\n}\n\n.margin-top-xs {\n\tmargin-top: 10rpx;\n}\n\n.margin-top-s {\n\tmargin-top: 20rpx;\n}\n\n.margin-top {\n\tmargin-top: 30rpx;\n}\n\n.margin-top-l {\n\tmargin-top: 40rpx;\n}\n\n.margin-top-xl {\n\tmargin-top: 50rpx;\n}\n\n.margin-top-xxl {\n\tmargin-top: 60rpx;\n}\n\n.margin-right-xxxs {\n\tmargin-right: 3rpx;\n}\n\n.margin-right-xxs {\n\tmargin-right: 5rpx;\n}\n\n.margin-right-xs {\n\tmargin-right: 10rpx;\n}\n\n.margin-right-s {\n\tmargin-right: 20rpx;\n}\n\n.margin-right {\n\tmargin-right: 30rpx;\n}\n\n.margin-right-l {\n\tmargin-right: 40rpx;\n}\n\n.margin-right-xl {\n\tmargin-right: 50rpx;\n}\n\n.margin-right-xxl {\n\tmargin-right: 60rpx;\n}\n\n.margin-bottom-xxs {\n\tmargin-bottom: 5rpx;\n}\n\n.margin-bottom-xxxs {\n\tmargin-bottom: 3rpx;\n}\n\n.margin-bottom-xs {\n\tmargin-bottom: 10rpx;\n}\n\n.margin-bottom-s {\n\tmargin-bottom: 20rpx;\n}\n\n.margin-bottom {\n\tmargin-bottom: 30rpx;\n}\n\n.margin-bottom-l {\n\tmargin-bottom: 40rpx;\n}\n\n.margin-bottom-xl {\n\tmargin-bottom: 50rpx;\n}\n\n.margin-bottom-xxl {\n\tmargin-bottom: 60rpx;\n}\n\n.margin-bottom-xxxl {\n\tmargin-bottom: 70rpx;\n}\n\n.safe-bottom {\n\tpadding-bottom: constant(safe-area-inset-bottom) !important;\n\tpadding-bottom: env(safe-area-inset-bottom) !important;\n}   \n\n.margin-left-xxxs {\n\tmargin-left: 3rpx;\n}\n\n.margin-left-xxs {\n\tmargin-left: 5rpx;\n}\n\n.margin-left-xs {\n\tmargin-left: 10rpx;\n}\n\n.margin-left-s {\n\tmargin-left: 20rpx;\n}\n\n.margin-left {\n\tmargin-left: 30rpx;\n}\n\n.margin-left-l {\n\tmargin-left: 40rpx;\n}\n\n.margin-left-xl {\n\tmargin-left: 50rpx;\n}\n\n.margin-left-xxl {\n\tmargin-left: 60rpx;\n}\n\n\n.padding-0 {\n\tpadding: 0;\n}\n\n.padding-xs {\n\tpadding: 10rpx;\n}\n\n.padding-s {\n\tpadding: 20rpx;\n}\n\n.padding {\n\tpadding: 30rpx;\n}\n\n.padding-l {\n\tpadding: 40rpx;\n}\n\n.padding-xl {\n\tpadding: 50rpx;\n}\n\n.padding-top-xs {\n\tpadding-top: 10rpx;\n}\n\n.padding-top-s {\n\tpadding-top: 20rpx;\n}\n\n.padding-top {\n\tpadding-top: 30rpx;\n}\n\n.padding-top-l {\n\tpadding-top: 40rpx;\n}\n\n.padding-top-xl {\n\tpadding-top: 50rpx;\n}\n\n.padding-right-xs {\n\tpadding-right: 10rpx;\n}\n\n.padding-right-s {\n\tpadding-right: 20rpx;\n}\n\n.padding-right {\n\tpadding-right: 30rpx;\n}\n\n.padding-right-l {\n\tpadding-right: 40rpx;\n}\n\n.padding-right-xl {\n\tpadding-right: 50rpx;\n}\n\n.padding-bottom-xs {\n\tpadding-bottom: 10rpx;\n}\n\n.padding-bottom-s {\n\tpadding-bottom: 20rpx;\n}\n\n.padding-bottom {\n\tpadding-bottom: 30rpx;\n}\n\n.padding-bottom-l {\n\tpadding-bottom: 40rpx;\n}\n\n.padding-bottom-xl {\n\tpadding-bottom: 50rpx;\n}\n\n.padding-left-xs {\n\tpadding-left: 10rpx;\n}\n\n.padding-left-s {\n\tpadding-left: 20rpx;\n}\n\n.padding-left {\n\tpadding-left: 30rpx;\n}\n\n.padding-left-l {\n\tpadding-left: 40rpx;\n}\n\n.padding-left-xl {\n\tpadding-left: 50rpx;\n}\n\n.padding-lr-xs {\n\tpadding-left: 10rpx;\n\tpadding-right: 10rpx;\n}\n\n.padding-lr-s {\n\tpadding-left: 20rpx;\n\tpadding-right: 20rpx;\n}\n\n.padding-lr {\n\tpadding-left: 30rpx;\n\tpadding-right: 30rpx;\n}\n\n.padding-lr-l {\n\tpadding-left: 40rpx;\n\tpadding-right: 40rpx;\n}\n\n.padding-lr-xl {\n\tpadding-left: 50rpx;\n\tpadding-right: 50rpx;\n}\n\n\n/* grid布局 */\n\n.grid {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n}\n\n.grid.grid-square {\n\toverflow: hidden;\n}\n\n.grid.grid-square .cu-tag {\n\tposition: absolute;\n\tright: 0;\n\ttop: 0;\n\tborder-bottom-left-radius: 6rpx;\n\tpadding: 6rpx 12rpx;\n\theight: auto;\n\tbackground-color: rgba(0, 0, 0, 0.5);\n}\n\n.grid.grid-square>view>text[class*=\"cuIcon-\"] {\n\tfont-size: 52rpx;\n\tposition: absolute;\n\tcolor: var(--grey);\n\tmargin: auto;\n\ttop: 0;\n\tbottom: 0;\n\tleft: 0;\n\tright: 0;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tflex-direction: column;\n}\n\n.grid.grid-square>view {\n\tmargin-right: 20rpx;\n\tmargin-bottom: 20rpx;\n\tborder-radius: 6rpx;\n\tposition: relative;\n\toverflow: hidden;\n}\n\n.grid.grid-square>view.bg-img image {\n\twidth: 100%;\n\theight: 100%;\n\tposition: absolute;\n}\n\n.grid.col-1.grid-square>view {\n\tpadding-bottom: 100%;\n\theight: 0;\n\tmargin-right: 0;\n}\n\n.grid.col-2.grid-square>view {\n\tpadding-bottom: calc((100% - 20rpx)/2);\n\theight: 0;\n\twidth: calc((100% - 20rpx)/2);\n}\n\n.grid.col-3.grid-square>view {\n\tpadding-bottom: calc((100% - 40rpx)/3);\n\theight: 0;\n\twidth: calc((100% - 40rpx)/3);\n}\n\n.grid.col-4.grid-square>view {\n\tpadding-bottom: calc((100% - 60rpx)/4);\n\theight: 0;\n\twidth: calc((100% - 60rpx)/4);\n}\n\n.grid.col-5.grid-square>view {\n\tpadding-bottom: calc((100% - 80rpx)/5);\n\theight: 0;\n\twidth: calc((100% - 80rpx)/5);\n}\n\n.grid.col-2.grid-square>view:nth-child(2n),\n.grid.col-3.grid-square>view:nth-child(3n),\n.grid.col-4.grid-square>view:nth-child(4n),\n.grid.col-5.grid-square>view:nth-child(5n) {\n\tmargin-right: 0;\n}\n\n.grid.col-1>view {\n\twidth: 100%;\n}\n\n.grid.col-2>view {\n\twidth: 50%;\n}\n\n.grid.col-3>view {\n\twidth: 33.33%;\n}\n\n.grid.col-4>view {\n\twidth: 25%;\n}\n\n.grid.col-5>view {\n\twidth: 20%;\n}"
  },
  {
    "path": "miniprogram/style/base/list.wxss",
    "content": "/* ==================\n          列表\n ==================== */\n.grayscale {\n\tfilter: grayscale(1);\n}\n\n.comm-list+.comm-list {\n\tmargin-top: 30rpx\n}\n\n.comm-list>.item {\n\ttransition: all .6s ease-in-out 0s;\n\ttransform: translateX(0rpx)\n}\n\n.comm-list>.item.move-cur {\n\ttransform: translateX(-260rpx)\n}\n\n.comm-list>.item .move {\n\tposition: absolute;\n\tright: 0;\n\tdisplay: flex;\n\twidth: 260rpx;\n\theight: 100%;\n\ttransform: translateX(100%)\n}\n\n.comm-list>.item .move view {\n\tdisplay: flex;\n\tflex: 1;\n\tjustify-content: center;\n\talign-items: center\n}\n\n.comm-list.menu-avatar {\n\toverflow: hidden;\n}\n\n.comm-list.menu-avatar>.item {\n\tposition: relative;\n\tdisplay: flex;\n\tpadding-right: 10rpx;\n\theight: 140rpx;\n\tbackground-color: var(--white);\n\tjustify-content: flex-end;\n\talign-items: center\n}\n\n.comm-list.menu-avatar>.item>.avatar {\n\tposition: absolute;\n\tleft: 30rpx\n}\n\n.comm-list.menu-avatar>.item .flex .text-cut {\n\tmax-width: 510rpx\n}\n\n.comm-list.menu-avatar>.item .content {\n\tposition: absolute;\n\tleft: 146rpx;\n\twidth: calc(100% - 96rpx - 60rpx - 120rpx - 20rpx);\n\tline-height: 1.6em;\n}\n\n.comm-list.menu-avatar>.item .content.flex-sub {\n\twidth: calc(100% - 96rpx - 60rpx - 20rpx);\n}\n\n.comm-list.menu-avatar>.item .content>view:first-child {\n\tfont-size: 30rpx;\n\tdisplay: flex;\n\talign-items: center\n}\n\n.comm-list.menu-avatar>.item .content .tag.small {\n\tdisplay: inline-block;\n\tmargin-left: 10rpx;\n\theight: 28rpx;\n\tfont-size: 16rpx;\n\tline-height: 32rpx\n}\n\n.comm-list.menu-avatar>.item .action {\n\twidth: 100rpx;\n\ttext-align: center\n}\n\n.comm-list.menu-avatar>.item .action view+view {\n\tmargin-top: 10rpx\n}\n\n.comm-list.menu-avatar.comment>.item .content {\n\tposition: relative;\n\tleft: 0;\n\twidth: auto;\n\tflex: 1;\n}\n\n.comm-list.menu-avatar.comment>.item {\n\tpadding: 30rpx 30rpx 30rpx 120rpx;\n\theight: auto\n}\n\n.comm-list.menu-avatar.comment .avatar {\n\talign-self: flex-start\n}\n\n.comm-list.menu>.item {\n\tposition: relative;\n\tdisplay: flex;\n\tpadding: 0 30rpx;\n\tmin-height: 100rpx;\n\tbackground-color: var(--white);\n\tjustify-content: space-between;\n\talign-items: center\n}\n\n.comm-list.menu>.item:last-child:after {\n\tborder: none\n}\n\n.comm-list.menu>.item:after {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbox-sizing: border-box;\n\twidth: 200%;\n\theight: 200%;\n\tborder-bottom: 1rpx solid #ddd;\n\tborder-radius: inherit;\n\tcontent: \" \";\n\ttransform: scale(.5);\n\ttransform-origin: 0 0;\n\tpointer-events: none\n}\n\n.comm-list.menu>.item.grayscale {\n\tbackground-color: #f5f5f5\n}\n\n.comm-list.menu>.item.cur {\n\tbackground-color: #fcf7e9\n}\n\n.comm-list.menu>.item.arrow {\n\tpadding-right: 90rpx\n}\n\n.comm-list.menu>.item.arrow:before {\n\tposition: absolute;\n\ttop: 0;\n\tright: 30rpx;\n\tbottom: 0;\n\tdisplay: block;\n\tmargin: auto;\n\twidth: 30rpx;\n\theight: 30rpx;\n\tcolor: var(--grey);\n\tcontent: \"\\e6a3\";\n\ttext-align: center;\n\tfont-size: 34rpx;\n\tfont-family: \"icon\";\n\tline-height: 30rpx\n}\n\n.comm-list.menu>.item button.content {\n\tpadding: 0;\n\tbackground-color: transparent;\n\tjustify-content: flex-start\n}\n\n.comm-list.menu>.item button.content:after {\n\tdisplay: none\n}\n\n.comm-list.menu>.item .avatar-group .avatar {\n\tborder-color: var(--white)\n}\n\n.comm-list.menu>.item .content>view:first-child {\n\tdisplay: flex;\n\talign-items: center\n}\n\n.comm-list.menu>.item .content>text[class*=icon] {\n\tdisplay: inline-block;\n\tmargin-right: 10rpx;\n\twidth: 1.6em;\n\ttext-align: center\n}\n\n.comm-list.menu>.item .content>image {\n\tdisplay: inline-block;\n\tmargin-right: 10rpx;\n\twidth: 1.6em;\n\theight: 1.6em;\n\tvertical-align: middle\n}\n\n.comm-list.menu>.item .content {\n\tfont-size: 30rpx;\n\tline-height: 1.6em;\n\tflex: 1\n}\n\n.comm-list.menu>.item .content .tag.small {\n\tdisplay: inline-block;\n\tmargin-left: 10rpx;\n\theight: 28rpx;\n\tfont-size: 16rpx;\n\tline-height: 32rpx\n}\n\n.comm-list.menu>.item .action .tag:empty {\n\tright: 10rpx\n}\n\n.comm-list.menu {\n\tdisplay: block;\n\toverflow: hidden\n}\n\n.comm-list.menu.small-border>.item:after {\n\tleft: 30rpx;\n\twidth: calc(200% - 120rpx)\n}\n\n.comm-list.grid>.item {\n\tposition: relative;\n\tdisplay: flex;\n\tpadding: 20rpx 0 30rpx;\n\ttransition-duration: 0s;\n\tflex-direction: column\n}\n\n.comm-list.grid>.item:after {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbox-sizing: border-box;\n\twidth: 200%;\n\theight: 200%;\n\tborder-right: 1px solid rgba(0, 0, 0, .1);\n\tborder-bottom: 1px solid rgba(0, 0, 0, .1);\n\tborder-radius: inherit;\n\tcontent: \" \";\n\ttransform: scale(.5);\n\ttransform-origin: 0 0;\n\tpointer-events: none\n}\n\n.comm-list.grid>.item text {\n\tdisplay: block;\n\tmargin-top: 10rpx;\n\tcolor: #888;\n\tfont-size: 26rpx;\n\tline-height: 40rpx\n}\n\n.comm-list.grid>.item [class*=icon] {\n\tposition: relative;\n\tdisplay: block;\n\tmargin-top: 20rpx;\n\twidth: 100%;\n\tfont-size: 48rpx\n}\n\n.comm-list.grid>.item .tag {\n\tright: auto;\n\tleft: 50%;\n\tmargin-left: 20rpx\n}\n\n.comm-list.grid {\n\tbackground-color: var(--white);\n\ttext-align: center\n}\n\n.comm-list.grid.no-border>.item {\n\tpadding-top: 10rpx;\n\tpadding-bottom: 20rpx\n}\n\n.comm-list.grid.no-border>.item:after {\n\tborder: none\n}\n\n.comm-list.grid.no-border {\n\tpadding: 20rpx 10rpx\n}\n\n.comm-list.grid.col-3>.item:nth-child(3n):after,\n.comm-list.grid.col-4>.item:nth-child(4n):after,\n.comm-list.grid.col-5>.item:nth-child(5n):after {\n\tborder-right-width: 0\n}\n\n.comm-list.card-menu {\n\toverflow: hidden;\n\tmargin-right: 30rpx;\n\tmargin-left: 30rpx;\n\tborder-radius: 20rpx\n}"
  },
  {
    "path": "miniprogram/style/base/load.wxss",
    "content": "/* ==================\n          加载\n ==================== */\n\n .load {\n\tdisplay: block;\n\tline-height: 3em;\n\ttext-align: center;\n\tz-index: 99999;\n}\n\n.load::before {\n\tfont-family: \"icon\";\n\tdisplay: inline-block;\n\tmargin-right: 6rpx;\n}\n\n.load.loading::before, .load.loading-none::before {\n\tcontent: \"\\e67a\";\n\tanimation: icon-spin 2s infinite linear;\n}\n\n.load.loading::after {\n\tcontent: \"加载中...\";\n}\n\n.load.over::before {\n\tcontent: \"\\e64a\";\n}\n\n.load.over::after {\n\tcontent: \"没有更多了\";\n}\n\n.load.error::before {\n\tcontent: \"\\e658\";\n}\n/*\n.load.error::after {\n\tcontent: \"加载失败\";\n}*/\n\n.load.notexist::before {\n\tcontent: \"\\e658\";\n}\n\n.load.notexist::after {\n\tcontent: \"数据不存在或者已删除\";\n}\n\n.load.load-icon::before {\n\tfont-size: 32rpx;\n}\n\n.load.load-icon::after {\n\tdisplay: none;\n}\n\n.load.load-icon.over {\n\tdisplay: none;\n}\n\n.load.load-modal {\n\tposition: fixed;\n\ttop: 0;\n\tright: 0;\n\tbottom: 140rpx;\n\tleft: 0;\n\tmargin: auto;\n\twidth: 260rpx;\n\theight: 260rpx;\n\tbackground-color: var(--white);\n\tborder-radius: 10rpx;\n\tbox-shadow: 0 0 0rpx 2000rpx rgba(0, 0, 0, 0.5);\n\tdisplay: flex;\n\talign-items: center;\n\tflex-direction: column;\n\tjustify-content: center;\n\tfont-size: 28rpx;\n\tz-index: 9999;\n\tline-height: 2.4em;\n}\n\n.load.load-modal [class*=\"icon-\"] {\n\tfont-size: 60rpx;\n}\n\n.load.load-modal image {\n\twidth: 70rpx;\n\theight: 70rpx;\n}\n\n.load.load-modal::after {\n\tcontent: \"\";\n\tposition: absolute;\n\tbackground-color: var(--white);\n\tborder-radius: 50%;\n\twidth: 200rpx;\n\theight: 200rpx;\n\tfont-size: 10px;\n\tborder-top: 6rpx solid rgba(0, 0, 0, 0.05);\n\tborder-right: 6rpx solid rgba(0, 0, 0, 0.05);\n\tborder-bottom: 6rpx solid rgba(0, 0, 0, 0.05);\n\tborder-left: 6rpx solid var(--orange);\n\tanimation: icon-spin 1s infinite linear;\n\tz-index: -1;\n}\n\n.load-progress {\n\tpointer-events: none;\n\ttop: 0;\n\tposition: fixed;\n\twidth: 100%;\n\tleft: 0;\n\tz-index: 2000;\n}\n\n.load-progress.hide {\n\tdisplay: none;\n}\n\n.load-progress .load-progress-bar {\n\tposition: relative;\n\twidth: 100%;\n\theight: 4rpx;\n\toverflow: hidden;\n\ttransition: all 200ms ease 0s;\n}\n\n.load-progress .load-progress-spinner {\n\tposition: absolute;\n\ttop: 10rpx;\n\tright: 10rpx;\n\tz-index: 2000;\n\tdisplay: block;\n}\n\n.load-progress .load-progress-spinner::after {\n\tcontent: \"\";\n\tdisplay: block;\n\twidth: 24rpx;\n\theight: 24rpx;\n\t-webkit-box-sizing: border-box;\n\tbox-sizing: border-box;\n\tborder: solid 4rpx transparent;\n\tborder-top-color: inherit;\n\tborder-left-color: inherit;\n\tborder-radius: 50%;\n\t-webkit-animation: load-progress-spinner 0.4s linear infinite;\n\tanimation: load-progress-spinner 0.4s linear infinite;\n}\n\n@-webkit-keyframes load-progress-spinner {\n\t0% {\n\t\t-webkit-transform: rotate(0);\n\t\ttransform: rotate(0);\n\t}\n\n\t100% {\n\t\t-webkit-transform: rotate(360deg);\n\t\ttransform: rotate(360deg);\n\t}\n}\n\n@keyframes load-progress-spinner {\n\t0% {\n\t\t-webkit-transform: rotate(0);\n\t\ttransform: rotate(0);\n\t}\n\n\t100% {\n\t\t-webkit-transform: rotate(360deg);\n\t\ttransform: rotate(360deg);\n\t}\n}\n\n\n/* ==================\n         进度条\n ==================== */\n\n.progress {\n\toverflow: hidden;\n\theight: 28rpx;\n\tbackground-color: #ebeef5;\n\tdisplay: inline-flex;\n\talign-items: center;\n\twidth: 100%;\n}\n\n.progress+view,\n.progress+text {\n\tline-height: 1;\n}\n\n.progress.xs {\n\theight: 10rpx;\n}\n\n.progress.sm {\n\theight: 20rpx;\n}\n\n.progress view {\n\twidth: 0;\n\theight: 100%;\n\talign-items: center;\n\tdisplay: flex;\n\tjustify-items: flex-end;\n\tjustify-content: space-around;\n\tfont-size: 20rpx;\n\tcolor: var(--white);\n\ttransition: width 0.6s ease;\n}\n\n.progress text {\n\talign-items: center;\n\tdisplay: flex;\n\tfont-size: 20rpx;\n\tcolor: var(--black);\n\ttext-indent: 10rpx;\n}\n\n.progress.text-progress {\n\tpadding-right: 60rpx;\n}\n\n.progress.striped view {\n\tbackground-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n\tbackground-size: 72rpx 72rpx;\n}\n\n.progress.active view {\n\tanimation: progress-stripes 2s linear infinite;\n}\n\n@keyframes progress-stripes {\n\tfrom {\n\t\tbackground-position: 72rpx 0;\n\t}\n\n\tto {\n\t\tbackground-position: 0 0;\n\t}\n}"
  },
  {
    "path": "miniprogram/style/base/modal.wxss",
    "content": "\n\n/* ==================\n         模态窗口\n ==================== */\n\n .modal {\n\tposition: fixed;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n\tz-index: 1110;\n\topacity: 0;\n\toutline: 0;\n\ttext-align: center;\n\t-ms-transform: scale(1.185);\n\ttransform: scale(1.185);\n\tbackface-visibility: hidden;\n\tperspective: 2000rpx;\n\tbackground: rgba(0, 0, 0, 0.6);\n\ttransition: all 0.3s ease-in-out 0s;\n\tpointer-events: none;\n}\n\n.modal::before {\n\tcontent: \"\\200B\";\n\tdisplay: inline-block;\n\theight: 100%;\n\tvertical-align: middle;\n}\n\n.modal.show {\n\topacity: 1;\n\ttransition-duration: 0.3s;\n\t-ms-transform: scale(1);\n\ttransform: scale(1);\n\toverflow-x: hidden;\n\toverflow-y: auto;\n\tpointer-events: auto;\n}\n\n.modal .dialog {\n\tposition: relative;\n\tdisplay: inline-block;\n\tvertical-align: middle;\n\tmargin-left: auto;\n\tmargin-right: auto;\n\twidth: 680rpx;\n\tmax-width: 100%;\n\tbackground-color: #fff;\n\tborder-radius: 10rpx;\n\toverflow: hidden;\n}\n\n.modal.bottom-modal::before {\n\tvertical-align: bottom;\n}\n\n.modal.bottom-modal .dialog {\n\twidth: 100%;\n\tborder-radius: 20rpx 20rpx 0 0;\n\tbackground-color: #fff;\n}\n\n.modal.bottom-modal .dialog {\n\twidth: 100%;\n\tborder-radius: 20rpx 20rpx 0 0;\n\tbackground-color: #fff;\n}\n\n.modal.bottom-modal {\n\tmargin-bottom: -1000rpx;\n}\n\n.modal.bottom-modal.show {\n\tmargin-bottom: 0;\n}\n\n.modal.drawer-modal {\n\ttransform: scale(1);\n\tdisplay: flex;\n}\n\n.modal.drawer-modal .dialog {\n\theight: 100%;\n\tmin-width: 200rpx;\n\tborder-radius: 0;\n\tmargin: initial;\n\ttransition-duration: 0.3s;\n}\n\n.modal.drawer-modal.justify-start .dialog {\n\ttransform: translateX(-100%);\n}\n\n.modal.drawer-modal.justify-end .dialog {\n\ttransform: translateX(100%);\n}\n\n.modal.drawer-modal.show .dialog {\n\ttransform: translateX(0%);\n}\n.modal .dialog>.bar:first-child .action{\n  min-width: 100rpx;\n  /*margin-right: 0;*/\n  min-height: 100rpx;\n}\n\n\n.dialog-list+.dialog-list {\n\tmargin-top: 30rpx\n}\n\n.dialog-list>.dialog-list-item {\n\ttransition: all .6s ease-in-out 0s;\n\ttransform: translateX(0rpx)\n}\n\n.dialog-list.menu>.dialog-list-item {\n\tposition: relative;\n\tdisplay: flex;\n\tpadding: 0 30rpx;\n\tmin-height: 100rpx;\n\tbackground-color: var(--white);\n\tjustify-content: space-between;\n\talign-items: center\n}\n\n.dialog-list.menu>.dialog-list-item:last-child:after {\n\tborder: none\n}\n\n.dialog-list.menu>.dialog-list-item:after {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbox-sizing: border-box;\n\twidth: 200%;\n\theight: 200%;\n\tborder-bottom: 1rpx solid #ddd;\n\tborder-radius: inherit;\n\tcontent: \" \";\n\ttransform: scale(.5);\n\ttransform-origin: 0 0;\n\tpointer-events: none\n}\n\n.dialog-list.menu>.dialog-list-item.grayscale {\n\tbackground-color: #f5f5f5\n}\n\n.dialog-list.menu>.dialog-list-item.cur {\n\tbackground-color: #fcf7e9\n}\n\n.dialog-list.menu>.dialog-list-item.arrow {\n\tpadding-right: 90rpx\n}\n\n.dialog-list.menu>.dialog-list-item.arrow:before {\n\tposition: absolute;\n\ttop: 0;\n\tright: 30rpx;\n\tbottom: 0;\n\tdisplay: block;\n\tmargin: auto;\n\twidth: 30rpx;\n\theight: 30rpx;\n\tcolor: var(--grey);\n\tcontent: \"\\e6a3\";\n\ttext-align: center;\n\tfont-size: 34rpx;\n\tfont-family: \"icon\";\n\tline-height: 30rpx\n}\n\n.dialog-list.menu>.dialog-list-item button.content {\n\tpadding: 0;\n\tbackground-color: transparent;\n\tjustify-content: flex-start\n}\n\n.dialog-list.menu>.dialog-list-item button.content:after {\n\tdisplay: none\n}\n  \n.dialog-list.menu>.dialog-list-item .content>view:first-child {\n\tdisplay: flex;\n\talign-items: center\n}\n\n.dialog-list.menu>.dialog-list-item .content>text[class*=icon] {\n\tdisplay: inline-block;\n\tmargin-right: 10rpx;\n\twidth: 1.6em;\n\ttext-align: center\n}\n\n.dialog-list.menu>.dialog-list-item .content>image {\n\tdisplay: inline-block;\n\tmargin-right: 10rpx;\n\twidth: 1.6em;\n\theight: 1.6em;\n\tvertical-align: middle\n}\n\n.dialog-list.menu>.dialog-list-item .content {\n\tfont-size: 30rpx;\n\tline-height: 1.6em;\n\tflex: 1\n}\n\n"
  },
  {
    "path": "miniprogram/style/base/nav.wxss",
    "content": "\n/* ==================\n         导航栏\n ==================== */\n\n .tab {\n\twhite-space: nowrap;\n}\n\n::-webkit-scrollbar {\n\tdisplay: none;\n}\n\n.tab .item {\n\theight: 90rpx;\n\tdisplay: inline-block;\n\tline-height: 90rpx;\n\tmargin: 0 10rpx;\n\tpadding: 0 20rpx;\n}\n\n.tab .item.cur {\n\tborder-bottom: 4rpx solid;\n}\n\n"
  },
  {
    "path": "miniprogram/style/base/shadow.wxss",
    "content": "\n/* ==================\n          阴影\n ==================== */\n/* -- 形状阴影 -- */\n.shadow[class*='white'] {\n\t--ShadowSize: 0 1rpx 6rpx;\n}\n\n.shadow-large {\n\t--ShadowSize: 0rpx 40rpx 100rpx 0rpx;\n}\n\n.shadow-warp {\n\tposition: relative;\n\tbox-shadow: 0 0 10rpx rgba(0, 0, 0, 0.1);\n}\n\n.shadow-warp:before,\n.shadow-warp:after {\n\tposition: absolute;\n\tcontent: \"\";\n\ttop: 20rpx;\n\tbottom: 30rpx;\n\tleft: 20rpx;\n\twidth: 50%;\n\tbox-shadow: 0 30rpx 20rpx rgba(0, 0, 0, 0.2);\n\ttransform: rotate(-3deg);\n\tz-index: -1;\n}\n\n.shadow-warp:after {\n\tright: 20rpx;\n\tleft: auto;\n\ttransform: rotate(3deg);\n}\n\n.shadow-blur {\n\tposition: relative;\n}\n\n.shadow-blur::before {\n\tcontent: \"\";\n\tdisplay: block;\n\tbackground: inherit;\n\tfilter: blur(10rpx);\n\tposition: absolute;\n\twidth: 100%;\n\theight: 100%;\n\ttop: 10rpx;\n\tleft: 10rpx;\n\tz-index: -1;\n\topacity: 0.4;\n\ttransform-origin: 0 0;\n\tborder-radius: inherit;\n\ttransform: scale(1, 1);\n}\n\n\n.shadow {\n\tbox-shadow: var(--ShadowSize) var(--greyShadow);\n}\n\n.shadow[class*=\"-red\"] {\n\tbox-shadow: var(--ShadowSize) var(--redShadow);\n}\n\n.shadow[class*=\"-orange\"] {\n\tbox-shadow: var(--ShadowSize) var(--orangeShadow);\n}\n\n.shadow[class*=\"-yellow\"] {\n\tbox-shadow: var(--ShadowSize) var(--yellowShadow);\n}\n\n.shadow[class*=\"-olive\"] {\n\tbox-shadow: var(--ShadowSize) var(--oliveShadow);\n}\n\n.shadow[class*=\"-green\"] {\n\tbox-shadow: var(--ShadowSize) var(--greenShadow);\n}\n\n.shadow[class*=\"-darkgreen\"] {\n\tbox-shadow: var(--ShadowSize) var(--darkgreenShadow);\n}\n\n.shadow[class*=\"-cyan\"] {\n\tbox-shadow: var(--ShadowSize) var(--cyanShadow);\n}\n\n.shadow[class*=\"-blue\"] {\n\tbox-shadow: var(--ShadowSize) var(--blueShadow);\n}\n\n.shadow[class*=\"-purple\"] {\n\tbox-shadow: var(--ShadowSize) var(--purpleShadow);\n}\n\n.shadow[class*=\"-mauve\"] {\n\tbox-shadow: var(--ShadowSize) var(--mauveShadow);\n}\n\n.shadow[class*=\"-pink\"] {\n\tbox-shadow: var(--ShadowSize) var(--pinkShadow);\n}\n\n.shadow[class*=\"-brown\"] {\n\tbox-shadow: var(--ShadowSize) var(--brownShadow);\n}\n\n.shadow[class*=\"-grey\"] {\n\tbox-shadow: var(--ShadowSize) var(--greyShadow);\n}\n\n.shadow[class*=\"-gray\"] {\n\tbox-shadow: var(--ShadowSize) var(--grayShadow);\n}\n\n.shadow[class*=\"-black\"] {\n\tbox-shadow: var(--ShadowSize) var(--blackShadow);\n}\n\n.shadow[class*=\"-white\"] {\n\tbox-shadow: var(--ShadowSize) var(--blackShadow);\n}\n\n"
  },
  {
    "path": "miniprogram/style/base/table.wxss",
    "content": "page {\n\t--borderColor: #ccc;\n}\n\n.table {\n\tposition: relative;\n\tfont-size: 28rpx;\n\tbackground: #fff;\n\tborder-right: none;\n\toverflow: hidden;\n}\n\n.table.sticky {\n\toverflow: visible;\n}\n\n.table .table-top {\n\twidth: 100%;\n\tbackground-color: #fff;\n}\n\n.table.sticky .table-top {\n\twidth: 100%;\n\tposition: sticky;\n\ttop: 0;\n\tz-index: 9999999;\n}\n\n.table .full {\n\tflex-grow: 1\n}\n\n.thead {\n\tborder-bottom: none;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\toverflow: visible;\n\tcolor: #333;\n\tborder: 1px solid var(--borderColor);\n\tbox-sizing: border-box;\n\tbackground-color: #f2f2f2;\n}\n\n.thead .td {\n\tpadding: 20rpx 10rpx;\n\tfont-weight: bold;\n\tdisplay: inline-block;\n\twhite-space: nowrap;\n\ttext-align: center;\n\tborder-right: 1rpx solid #fff;\n}\n\n.thead .td:last-child {\n\tborder-right: none;\n}\n\n.thead.border .td {\n\tborder-right: 1rpx solid var(--borderColor);\n}\n\n.thead.border .td:last-child {\n\tborder-right: none;\n}\n\n/* .tr{\n  display: flex;\n  white-space:nowrap; \n} */\n.tbody {\n\tbox-sizing: border-box;\n\tfont-size: 28rpx;\n\tcolor: #444;\n\tborder: 1px solid var(--borderColor);\n\tborder-top: none;\n}\n\n.tbody .line {\n\tpadding: 25rpx 20rpx 10rpx;\n\ttext-align: center;\n\tfont-size: 28rpx;\n\tborder-bottom: 1rpx solid var(--borderColor);\n}\n\n.tbody .line>text {\n\tposition: relative;\n}\n\n.tbody .line>text::before {\n\tcontent: '';\n\tposition: absolute;\n\tright: 130%;\n\ttop: 50%;\n\twidth: 150rpx;\n\tborder-bottom: 1rpx dashed var(--borderColor);\n}\n\n.tbody .line>text::after {\n\tcontent: '';\n\tposition: absolute;\n\tleft: 130%;\n\ttop: 50%;\n\twidth: 150rpx;\n\tborder-bottom: 1rpx dashed var(--borderColor);\n}\n\n\n\n\n.tbody .tr {\n\tdisplay: flex;\n\tborder-bottom: 1px solid var(--borderColor);\n}\n\n.tbody .tr:last-child {\n\tborder-bottom: none;\n}\n\n.tbody .tr:last-child {\n\tborder-bottom-left-radius: 8rpx;\n\tborder-bottom-right-radius: 8rpx;\n}\n\n.tbody .tr.stripe {\n\tbackground: #fff;\n\tborder-bottom: none;\n}\n\n.tbody .tr.stripe:nth-child(2n) {\n\tbackground: #F6F6F6;\n}\n\n.tbody .tr .td {\n\twhite-space: wrap;\n\tpadding: 20rpx 10rpx;\n\ttext-align: center;\n}\n\n.tbody .tr.border .td {\n\tborder-right: 1rpx solid var(--borderColor);\n}\n\n.tbody .tr.border .td:last-child {\n\tborder-right: none;\n}\n\n.table .no-data {\n\tdisplay: flex;\n\tpadding: 50rpx;\n\tcolor: #666;\n\tjustify-content: center;\n}\n\n.table .table-form {\n\tpadding: 20rpx;\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: center;\n\tflex-wrap: wrap;\n}\n\n.table .table-form .item {\n\twidth: 50%;\n\tpadding: 10rpx 5rpx;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: center;\n}\n\n.table .table-form .item .title {\n\tfont-weight: bold;\n}\n\n.table .table-form .item .content {\n\tflex: 1;\n\tborder-bottom: 1rpx solid #ccc;\n\tmargin: 0 10rpx 0rpx 0;\n\tpadding: 0 0 0 5rpx;\n\theight: 50rpx;\n}\n\n.table .table-form .item .content input {\n\twidth: 100%;\n}\n\n.table .table-form .oprt {\n\tmargin-top: 10rpx;\n\twidth: 100%;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-end;\n}\n\n.table .table-form .oprt>view {\n\tpadding: 5rpx 40rpx;\n\tbackground-color: #f2f2f2;\n\tborder-radius: 10rpx;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.table .table-form .button-hover {\n\topacity: .9;\n\ttransform: scale(0.95, 0.95);\n\tposition: relative;\n\ttop: 3rpx;\n\tleft: 3rpx;\n\tbox-shadow: 0px 0px 8px rgba(0, 0, 0, .1) inset;\n}\n\n.table .table-form .oprt .submit {\n\tbackground-color: var(--adminColor);\n\tcolor: #fff;\n}"
  },
  {
    "path": "miniprogram/style/base/tag.wxss",
    "content": "\n/* ==================\n          标签\n ==================== */\n\n .tag {\n\tfont-size: 24rpx;\n\tvertical-align: middle;\n\tposition: relative;\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tbox-sizing: border-box;\n\tpadding: 0rpx 16rpx;\n\theight: 48rpx;\n\tfont-family: Helvetica Neue, Helvetica, sans-serif;\n\twhite-space: nowrap;\n}\n\n.tag:not([class*=\"bg\"]):not([class*=\"border\"]) {\n\tbackground-color: var(--ghostWhite);\n}\n\n.tag[class*=\"border-\"]::after {\n\tcontent: \" \";\n\twidth: 200%;\n\theight: 200%;\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tborder: 1rpx solid currentColor;\n\ttransform: scale(0.5);\n\ttransform-origin: 0 0;\n\tbox-sizing: border-box;\n\tborder-radius: inherit;\n\tz-index: 1;\n\tpointer-events: none;\n}\n\n.tag.radius[class*=\"border\"]::after {\n\tborder-radius: 12rpx;\n}\n\n.tag.round[class*=\"border\"]::after {\n\tborder-radius: 1000rpx;\n}\n\n.tag[class*=\"border-\"]::after {\n\tborder-radius: 0;\n} \n\n.tag.border-bold::after {\n\tborder: 6rpx solid currentColor;\n} \n\n.tag+.tag {\n\tmargin-left: 10rpx;\n}\n\n.tag.small {\n\tfont-size: 20rpx;\n\tpadding: 0rpx 12rpx;\n\theight: 32rpx;\n}\n\n.capsule {\n\tdisplay: inline-flex;\n\tvertical-align: middle;\n}\n\n.capsule+.capsule {\n\tmargin-left: 10rpx;\n}\n\n.capsule .tag {\n\tmargin: 0;\n}\n\n.capsule .tag[class*=\"border-\"]:last-child::after {\n\tborder-left: 0rpx solid transparent;\n}\n\n.capsule .tag[class*=\"border-\"]:first-child::after {\n\tborder-right: 0rpx solid transparent;\n}\n\n.capsule.radius .tag:first-child {\n\tborder-top-left-radius: 6rpx;\n\tborder-bottom-left-radius: 6rpx;\n}\n\n.capsule.radius .tag:last-child::after,\n.capsule.radius .tag[class*=\"border-\"] {\n\tborder-top-right-radius: 12rpx;\n\tborder-bottom-right-radius: 12rpx;\n}\n\n.capsule.round .tag:first-child {\n\tborder-top-left-radius: 200rpx;\n\tborder-bottom-left-radius: 200rpx;\n\ttext-indent: 4rpx;\n}\n\n.capsule.round .tag:last-child::after,\n.capsule.round .tag:last-child {\n\tborder-top-right-radius: 200rpx;\n\tborder-bottom-right-radius: 200rpx;\n\ttext-indent: -4rpx;\n}\n\n.tag.badge {\n\tborder-radius: 200rpx;\n\tposition: absolute;\n\ttop: -10rpx;\n\tright: -10rpx;\n\tfont-size: 20rpx;\n\tpadding: 0rpx 10rpx;\n\theight: 28rpx;\n\tcolor: var(--white);\n}\n\n.tag.badge:not([class*=\"bg-\"]) {\n\tbackground-color: #dd514c;\n}\n\n.tag:empty:not([class*=\"icon-\"]) {\n\tpadding: 0rpx;\n\twidth: 16rpx;\n\theight: 16rpx;\n\ttop: -4rpx;\n\tright: -4rpx;\n}\n\n.tag[class*=\"icon-\"] {\n\twidth: 32rpx;\n\theight: 32rpx;\n\ttop: -4rpx;\n\tright: -4rpx;\n}\n"
  },
  {
    "path": "miniprogram/style/base/text.wxss",
    "content": "\n\n/* ==================\n          文本\n ==================== */ \n .text-xs,\n [class*=\"icon-\"].text-xs {\n\t font-size: 20rpx!important;\n }\n \n .text-s,\n [class*=\"icon-\"].text-s {\n\t font-size: 24rpx!important;\n }\n \n .text-normal,\n [class*=\"icon-\"].text-normal {\n\t font-size: 28rpx!important;\n\t font-weight:normal;\n }\n \n .text-l,\n [class*=\"icon-\"].text-l {\n\t font-size: 32rpx!important;\n }\n \n .text-xl,\n [class*=\"icon-\"].text-xl {\n\t font-size: 36rpx!important;\n }\n \n .text-xxl,\n [class*=\"icon-\"].text-xxl {\n\t font-size: 44rpx!important;\n }\n \n .text-xxxl,\n [class*=\"icon-\"].text-xxxl {\n\t font-size: 80rpx!important;\n }\n \n .text-xxxxl,\n [class*=\"icon-\"].text-xxxxl {\n\t font-size: 120rpx!important;\n }\n \n \n .text-cut {\n\t text-overflow: ellipsis;\n\t white-space: nowrap;\n\t overflow: hidden;\n }\n \n .content-cut { \n\t text-overflow: ellipsis;\n\t overflow: hidden; \n }\n .content-cut-one { \n\ttext-overflow: ellipsis;\n\toverflow: hidden;\n\tdisplay: -webkit-box;\n\tword-break: break-all;\n\t-webkit-box-orient: vertical; \n\t-webkit-line-clamp: 1; \n}\n .content-cut-two { \n\t text-overflow: ellipsis;\n\t overflow: hidden;\n\t display: -webkit-box;\n\t word-break: break-all;\n\t -webkit-box-orient: vertical; \n\t -webkit-line-clamp: 2; \n }\n \n .content-cut-three { \n\t text-overflow: ellipsis;\n\t overflow: hidden;\n\t display: -webkit-box;\n\t word-break: break-all;\n\t -webkit-box-orient: vertical;\n\t -webkit-line-clamp: 3; \n }\n\n .content-cut-four { \n\ttext-overflow: ellipsis;\n\toverflow: hidden;\n\tdisplay: -webkit-box;\n\tword-break: break-all;\n\t-webkit-box-orient: vertical;\n\t-webkit-line-clamp: 4; \n}\n\n.content-cut-five { \n\ttext-overflow: ellipsis;\n\toverflow: hidden;\n\tdisplay: -webkit-box;\n\tword-break: break-all;\n\t-webkit-box-orient: vertical;\n\t-webkit-line-clamp: 5; \n}\n \n .text-bold {\n\t font-weight: bold!important;\n }\n \n .text-center {\n\t text-align: center!important;\n }\n \n .text-content {\n\t line-height: 1.6!important;\n }\n \n .text-left {\n\t text-align: left!important;\n }\n \n .text-right {\n\t text-align: right!important;\n }\n \n .text-red,\n .border-red {\n\t color: var(--red)!important;\n }\n \n .text-orange,\n .border-orange {\n\t color: var(--orange)!important;\n }\n \n .text-yellow,\n .border-yellow {\n\t color: var(--yellow)!important;\n }\n \n .text-olive,\n .border-olive {\n\t color: var(--olive)!important;\n }\n \n .text-green,\n .border-green {\n\t color: var(--green)!important;\n }\n \n .text-darkgreen,\n .border-darkgreen {\n\t color: var(--darkgreen)!important;\n }\n\n .text-cyan,\n .border-cyan {\n\t color: var(--cyan)!important;\n }\n \n .text-blue,\n .border-blue {\n\t color: var(--blue)!important;\n }\n \n .text-purple,\n .border-purple {\n\t color: var(--purple)!important;\n }\n \n .text-mauve,\n .border-mauve {\n\t color: var(--mauve)!important;\n }\n \n .text-pink,\n .border-pink {\n\t color: var(--pink)!important;\n }\n \n .text-brown,\n .border-brown {\n\t color: var(--brown)!important;\n }\n \n .text-grey,\n .border-grey {\n\t color: var(--grey)!important;\n }\n \n .text-gray,\n .border-gray {\n\t color: var(--gray)!important;\n }\n \n .text-black,\n .border-black {\n\t color: var(--black)!important;\n }\n \n .text-white,\n .border-white {\n\t color: var(--white)!important;\n }  \n "
  },
  {
    "path": "miniprogram/style/project/admin_list_style.wxss",
    "content": "\n.admin-comm-list .item .info .oprt {\n\tpadding: 0rpx 0rpx;\n\tdisplay: flex;\n\tjustify-content: space-between;\n}\n\n.admin-comm-list .item .info .oprt .btn {\n\twidth: 155rpx;\n\tmargin-right: 0rpx !important;\n\theight: 60rpx !important;\n\tpadding: 0 0rpx;\n}"
  },
  {
    "path": "miniprogram/style/project/my_fav_style.wxss",
    "content": ".text-pic-list-box .item .simple .simple-title { \n    width: 100%;\n}"
  },
  {
    "path": "miniprogram/style/project/my_foot_style.wxss",
    "content": ".text-pic-list-box .item .simple .simple-title { \n    width: 100%;\n}"
  },
  {
    "path": "miniprogram/style/project/search_style.wxss",
    "content": ".main-search {\n\tbox-sizing: border-box;\n\twidth: 100%;\n\theight: 100vh;\n\tdisplay: flex;\n\tpadding: 0;\n\tflex-direction: column;\n\tjustify-content: center;\n\talign-items: center;\n}\n\n.main-search .search {\n\twidth: 100%;\n}\n\n.main-search .his {\n\tflex: 1;\n\tmargin-top: 2rpx;\n\twidth: 100%;\n\tbackground-color: #fff;\n\tdisplay: flex;\n\tflex-direction: column;\n\tpadding: 30rpx;\n}\n\n.main-search .his .title {\n\twidth: 100%;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-start;\n}\n\n.main-search .his .title .tit {\n\tfont-size: 34rpx;\n\tfont-weight: bold;\n\tflex: 1;\n}\n\n.main-search .his .title .del {\n\tfont-size: 32rpx;\n\tcolor: #aaa;\n\tmargin-left: auto;\n}\n\n.main-search .his .search-content {\n\twidth: 100%;\n\tdisplay: flex;\n\talign-items: center;\n\tflex-wrap: wrap;\n\tmargin-top: 40rpx;\n}\n\n.main-search .his .search-content .btn {\n\tmargin-right: 30rpx;\n\tmargin-top: 30rpx;\n\tfont-size: 28rpx;\n\tpadding: 35rpx 45rpx;\n\tbackground-color: #f2f2f2;\n}"
  },
  {
    "path": "miniprogram/style/public/admin.wxss",
    "content": "page {\n\t--adminColor: #2499f2;\n\t--adminRedColor: #FF6666;\n}\n\n.main-admin {\n\twidth: 100%;\n\tpadding: 30rpx 20rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: flex-start;\n\talign-items: flex-start;\n\tbox-sizing: border-box;\n\tmargin-bottom: 100rpx;\n}\n\n\n.main-admin form {\n\twidth: 100%;\n}\n\n.text-admin,\n.text-blue {\n\tcolor: var(--adminColor) !important;\n}\n\n.text-red {\n\tcolor: var(--adminRedColor) !important;\n}\n\n.bg-admin,\n.bg-blue {\n\tbackground-color: var(--adminColor) !important;\n\tcolor: #fff;\n}\n\n.bg-admin.light,\n.bg-blue.light {\n\tcolor: var(--adminColor) !important;\n\tbackground-color: #cce6ff !important;\n}\n\n.border-admin,\n.border-blue {\n\tborder-color: var(--adminColor) !important;\n}\n\n.form-box {\n\tborder-radius: 10rpx;\n}\n\n.btn {\n\tborder-radius: 10rpx;\n}\n\n.search-form.round {\n\tborder-radius: 10rpx;\n}\n\n.load.text-grey {\n\tcolor: #999 !important;\n}\n\n.tabs {\n\tcolor: #333 !important;\n\tfont-weight: bold;\n}\n\n.tabs .tab-menu.cur:after {\n\tbackground-color: var(--adminColor) !important;\n}\n\n.tabs .cur {\n\tcolor: var(--adminColor) !important;\n}\n\n.tabs .tab-menu.cur:after {\n\twidth: 80% !important;\n}\n\n.modal-admin .modal-content text {\n\ttext-align: left;\n\tdisplay: block;\n}\n\n.modal-admin .modal-content .pics {\n\tmargin-top: 30rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n\talign-items: center;\n}\n\n.modal-admin .modal-content .pics image {\n\tflex: 1;\n\tborder-radius: 10rpx;\n\tmargin-bottom: 20rpx;\n}\n\n.modal-admin .modal-content .modal-list {\n\tflex: 1;\n\tborder-radius: 10rpx;\n\tmargin: 20rpx 0;\n\tpadding: 20rpx 0;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n\talign-items: center;\n\twidth: 100%;\n}\n\n.modal-admin .modal-content .modal-list .modal-list-item {\n\tfont-size: 26rpx;\n\tline-height: 1.6;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: flex-start;\n\twidth: 100%;\n\tmargin-bottom: 10rpx;\n\tpadding: 10rpx 0;\n\tborder-bottom: 2rpx dashed #ccc;\n\tpadding: 20rpx 40rpx;\n}\n\n.modal-admin .modal-content .modal-list .modal-list-item .item-title {\n\twidth: 100%;\n\ttext-align: left;\n\tdisplay: flex;\n\tfont-size: 32rpx;\n\tline-height: 1.6;\n\tmargin-bottom: 10rpx;\n}\n\n.modal-admin .modal-content .item-content {\n\twidth: 100%;\n\ttext-align: left;\n\tdisplay: flex;\n\tflex-direction: row;\n\tjustify-content: flex-start;\n\talign-items: flex-start;\n\tline-height: 50rpx;\n\tborder-bottom: 2rpx dashed #ccc;\n\tmargin-bottom: 10rpx;\n}\n\n.modal-admin .modal-content .item-content text {\n\tdisplay: block;\n}\n\n.form-box .title-desc {\n\tpadding-left: 24rpx;\n\tcolor: #666;\n\tpadding-bottom: 30rpx;\n\tborder-bottom: 1rpx solid #eee;\n}\n\n.form-group .title {\n\tfont-size: 32rpx;\n}\n\n/** 通用列表 **/\n.admin-comm-list {\n\twidth: 100%;\n\tpadding: 0rpx 20rpx 0rpx;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: flex-start;\n}\n\n.admin-comm-list .item {\n\twidth: 100%;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: flex-start;\n\tbackground-color: #fff;\n\tborder-radius: 5rpx;\n\toverflow: hidden;\n\tmargin-bottom: 30rpx;\n\tposition: relative;\n\tborder: 1rpx solid #ccc;\n}\n\n.admin-comm-list .item .no {\n\tposition: absolute;\n\tbottom: 0;\n\tright: 10rpx;\n\tz-index: 99999;\n\tfont-size: 38rpx;\n\tfont-weight: bold;\n\tcolor: #ccc;\n\topacity: .5;\n}\n\n.admin-comm-list .item:last-child {\n\tmargin-bottom: 0;\n}\n\n.admin-comm-list .item .header {\n\twidth: 100%;\n\tfont-size: 28rpx;\n\ttext-align: left;\n\tline-height: 2.6;\n\tpadding: 0 15rpx;\n\tdisplay: flex;\n\tbackground-color: #f2f2f2;\n\tjustify-content: space-between;\n\talign-items: center;\n}\n\n.admin-comm-list .item .header .left {\n\tflex: 1;\n\tfont-size: 29rpx;\n\ttext-align: left;\n\tline-height: 2.6;\n\tpadding: 0 5rpx;\n\ttext-align: left;\n\tfont-weight: bold;\n}\n\n.admin-comm-list .item .header .right {\n\tmin-width: 100rpx;\n\ttext-align: right;\n}\n\n.admin-comm-list .item .info {\n\twidth: 100%;\n\tflex-direction: column;\n\talign-items: flex-start;\n\tjustify-content: flex-start;\n\tbackground-color: #fff;\n\tmin-height: 150rpx;\n\tpadding: 15rpx 20rpx 30rpx;\n\tposition: relative;\n}\n\n.admin-comm-list .item .info .info-item {\n\twidth: 100%;\n\tdisplay: flex;\n\talign-items: flex-start;\n\tjustify-content: flex-start;\n\tbackground-color: #fff;\n\tline-height: 1.5;\n\tfont-size: 26rpx;\n\tmargin-bottom: 20rpx;\n}\n\n.admin-comm-list .item .info .info-item.info-item-solid {\n\tborder-bottom: 1rpx dashed #ddd;\n\tpadding: 10rpx 0;\n}\n\n.admin-comm-list .item .info .info-item .title {\n\twidth: 110rpx;\n\tcolor: #333;\n\ttext-align: right;\n\tfont-weight: bold;\n}\n\n.admin-comm-list .item .info.title-mid .info-item .title {\n\twidth: 150rpx;\n\tdisplay: flex;\n}\n\n.admin-comm-list .item .info.title-long .info-item .title {\n\twidth: 200rpx;\n}\n\n\n.admin-comm-list .item .info .info-item .mao {\n\tcolor: #333;\n\ttext-align: left;\n\tmargin-right: 10rpx;\n}\n\n.admin-comm-list .item .info .info-item .content {\n\tflex: 1;\n\tcolor: #555;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: flex-start;\n\tdisplay: flex;\n\tflex-wrap: wrap;\n}\n\n.admin-comm-list .item .info .info-item .content image {\n\twidth: 150rpx;\n\theight: 150rpx;\n\tmargin-right: 10rpx;\n\tmargin-bottom: 10rpx;\n}\n\n.admin-comm-list .item .info .oprt {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\talign-items: center;\n\tjustify-content: center;\n\tpadding: 0rpx 20rpx;\n}\n\n.admin-comm-list .item .info .oprt .btn {\n\tpadding: 0 25rpx;\n\tfont-size: 26rpx;\n\tborder-radius: 8rpx !important;\n\tline-height: unset;\n\theight: 55rpx !important;\n\tbackground-color: #eee !important;\n\tmargin-bottom: 20rpx;\n}\n\n.admin-comm-list .btn-more {\n\tbackground-color: #fadbd9 !important;\n\tcolor: #e54d42;\n}\n\n.btn-admin {\n\twidth: 90%;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tbox-sizing: border-box;\n\tfont-size: 32rpx;\n\tline-height: 2.5;\n\tbackground-color: var(--adminColor) !important;\n\tcolor: #fff;\n\tborder-radius: 40rpx;\n\tmargin-bottom: 60rpx;\n}\n\n.btn-admin.button-hover {\n\topacity: .9;\n\ttransform: scale(0.95, 0.95);\n\tposition: relative;\n\ttop: 3rpx;\n\tleft: 3rpx;\n\tbox-shadow: 0px 0px 8px rgba(0, 0, 0, .1) inset;\n}\n\n.btn-bottom-admin {\n\twidth: 100%;\n\tposition: fixed;\n\tbottom: 0;\n\ttext-align: center;\n\tcolor: #fff;\n\tline-height: 2.6;\n\tfont-size: 36rpx;\n\tbackground-color: inherit;\n\tpadding-bottom: 0rpx;\n\t/*没有安全区域的手机 */\n\tpadding-bottom: constant(safe-area-inset-bottom);\n\t/*兼容有安全区域的手机*/\n\tpadding-bottom: env(safe-area-inset-bottom);\n\tdisplay: flex;\n\tz-index: 99999;\n}\n\n.btn-bottom-admin>view {\n\twidth: 50%;\n}\n\n.btn-bottom-admin .return {\n\tbackground-color: var(--adminRedColor);\n}\n\n.btn-bottom-admin .save {\n\tbackground-color: var(--adminColor);\n}"
  },
  {
    "path": "miniprogram/style/public/article_list.wxss",
    "content": "/*** 图文列表盒子 ***/\n.text-pic-list-box {\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tpadding: 20rpx 20rpx 30rpx 20rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n}\n\n.text-pic-list-box .item {\n\tpadding: 40rpx 30rpx 16rpx 40rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\tbackground-color: #fff;\n\tborder-radius: 20rpx;\n\tmargin-bottom: 30rpx;\n\tposition: relative;\n}\n\n/*扇形角标*/\n.text-pic-list-box .item .corner {\n\tposition: absolute;\n\ttop: 0;\n\tright: 0;\n\twidth: 80rpx;\n\theight: 80rpx;\n\tborder-radius: 0 0rpx 0rpx 80rpx;\n\tbackground-color: #EAEAEA;\n\tfont-size: 45rpx;\n\tfont-weight: bold;\n\tcolor: #fff;\n\tfont-style: italic;\n\tpadding-top: 10rpx;\n\tpadding-left: 36rpx;\n}\n\n/*倾斜角标*/\n.text-pic-list-box .item .lean-corner-box {\n\tposition: absolute;\n\twidth: 100%;\n\theight: 100%;\n\tright: 0;\n\ttop: 0;\n\toverflow: hidden;\n}\n\n.text-pic-list-box .item .lean-corner-right-top {\n\tbackground-color: green;\n\tcolor: white;\n\twidth: 50%;\n\theight: 40rpx;\n\tline-height: 40rpx;\n\ttext-align: center;\n\tmargin-left: 70%;\n\tmargin-top: 18rpx;\n\tposition: absolute;\n\ttransform: rotate(45deg);\n\tz-index: 1999;\n\tfont-size: 24rpx;\n\topacity: .6;\n}\n\n.text-pic-list-box .item .lean-corner-right-bottom {\n\tbackground-color: green;\n\tcolor: white;\n\twidth: 50%;\n\theight: 40rpx;\n\tline-height: 40rpx;\n\ttext-align: center;\n\tmargin-left: 70%;\n\tmargin-bottom: 18rpx;\n\tposition: absolute;\n\tbottom: 0;\n\ttransform: rotate(-45deg);\n\tz-index: 1999;\n\tfont-size: 24rpx;\n\topacity: .8;\n}\n\n.text-pic-list-box .item .status-right-top,\n.text-pic-list-box .item .status-right-bottom {\n\tposition: absolute;\n\tpadding:0 20rpx;\n\theight: 40rpx;\n\tbackground-color: #f8f8f8;\n\tfont-size: 24rpx;\n\tcolor: #aaa;\n\tline-height: 40rpx;\n\ttext-align: center;\n}\n\n.text-pic-list-box .item .status-right-top {\n\ttop: 0;\n\tright: 0;\n\tborder-top-right-radius: inherit;\n\tborder-bottom-left-radius: inherit;\n}\n\n.text-pic-list-box .item .status-right-bottom {\n\tright: 0;\n\tbottom: 0;\n\tborder-top-left-radius: inherit;\n\tborder-bottom-right-radius: inherit;\n}\n\n.text-pic-list-box .item .title {\n\tmax-height: 88rpx;\n\tline-height: 44rpx;\n\tfont-size: 32rpx;\n\tcolor: #000;\n\tfont-weight: bold;\n\tz-index: 999;\n}\n\n.text-pic-list-box .item .title .tag {\n\tfont-size: 20rpx;\n\tpadding: 0rpx 8rpx;\n\theight: 30rpx;\n\tline-height: 30rpx;\n\topacity: .8;\n}\n\n.text-pic-list-box .item .author {\n\tmargin-top: 20rpx;\n\tfont-size: 24rpx;\n\tdisplay: flex;\n\tjustify-self: center;\n\talign-items: center;\n\tz-index: 999;\n}\n\n.text-pic-list-box .item .author .av {\n\tmargin-right: 5rpx;\n\twidth: 40rpx;\n}\n\n.text-pic-list-box .item .desc {\n\tmargin-top: 15rpx;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: flex-start;\n}\n\n.text-pic-list-box .item .desc text {\n\tmax-height: 120rpx;\n\tline-height: 40rpx;\n\tfont-size: 28rpx;\n\tcolor: #777;\n\tflex: 1;\n}\n\n.text-pic-list-box .item .desc .pic {\n\tmargin-left: 10rpx;\n\twidth: 200rpx;\n\theight: 122rpx;\n\tborder-radius: 10rpx;\n}\n\n.text-pic-list-box .item .desc .pic.pic-left {\n\tmargin-left: 0rpx;\n\tmargin-right: 10rpx;\n}\n\n.text-pic-list-box .item .desc.pic-list {\n\tjustify-content: space-between;\n}\n\n.text-pic-list-box .item .desc.pic-list .pic {\n\tmargin-left: 0rpx;\n}\n\n.text-pic-list-box .item .data {\n\tline-height: 1.5;\n\tfont-size: 28rpx;\n\tcolor: #666;\n\tmargin-top: 10rpx;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: center;\n}\n\n.text-pic-list-box .item .data.data-button {\n\twidth: 100%;\n\tjustify-content: flex-end;\n\tmargin-bottom: 10rpx;\n}\n\n.text-pic-list-box .item .data.data-button button {\n\tmargin-left: 10rpx;\n}\n\n/*简约模式*/\n.text-pic-list-box .item.item-simple {\n\tpadding: 24rpx;\n}\n\n.text-pic-list-box .item .simple {\n\twidth: 100%;\n\tdisplay: flex;\n}\n\n.text-pic-list-box .item .simple .simple-left {\n\twidth: 100rpx;\n\theight: 100rpx;\n\tbackground-color: #E4DACE;\n\tborder-radius: 20rpx;\n\tmargin-right: 52rpx;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tfont-size: 36rpx;\n}\n\n.text-pic-list-box .item .simple .simple-right {\n\tflex: 1;\n\tdisplay: flex;\n\tflex-direction: column;\n}\n\n.text-pic-list-box .item .simple .simple-title {\n\tfont-size: 32rpx;\n\tcolor: #000;\n\tline-height: 1.5;\n\tmargin-top: 10rpx;\n\twidth: 450rpx;\n}\n\n.text-pic-list-box .item .simple .simple-desc {\n\tmargin-top: 20rpx;\n\tfont-size: 24rpx;\n\tcolor: #999;\n}\n\n/**snake接龙**/\n.text-pic-list-box .item.item-snake {\n\tpadding: 14rpx;\n\tborder-radius: 0rpx;\n\tmargin-bottom: 0;\n\tborder-bottom: 2rpx dashed #f2f2f2;\n}\n\n.text-pic-list-box .item .snake {\n\twidth: 100%;\n\tdisplay: flex;\n}\n\n.text-pic-list-box .item .snake .snake-left {\n\twidth: 40rpx;\n\theight: 40rpx;\n\tbackground-color: #E4DACE;\n\tborder-radius: 50%;\n\tmargin-right: 32rpx;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tfont-size: 36rpx;\n}\n\n.text-pic-list-box .item .snake .snake-right {\n\tflex: 1;\n\tdisplay: flex;\n\tflex-direction: column;\n}\n\n.text-pic-list-box .item .snake .snake-title {\n\tfont-size: 28rpx;\n\tcolor: #000;\n\tline-height: 1.3;\n\tmargin-top: 5rpx;\n\twidth: 450rpx;\n}\n\n.text-pic-list-box .item .snake .snake-desc {\n\tfont-size: 24rpx;\n\tcolor: rgb(203, 203, 203);\n}\n\n/* 左大图模式 */\n.text-pic-list-box .item.item-leftbig {\n\tpadding: 0;\n\tmax-height: 230rpx;\n}\n\n.text-pic-list-box .item-leftbig .leftbig-card {\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: flex-start;\n}\n\n.text-pic-list-box .item-leftbig .leftbig-card .leftbig-left {\n\twidth: 180rpx;\n\theight: 230rpx;\n\tborder-top-left-radius: 20rpx;\n\tborder-bottom-left-radius: 20rpx;\n}\n\n.text-pic-list-box .item-leftbig .leftbig-card .leftbig-right {\n\tflex: 1;\n\tdisplay: flex;\n\tflex-direction: column;\n\tmargin-left: 20rpx;\n\tmargin-right: 20rpx;\n}\n\n.text-pic-list-box .item-leftbig .leftbig-card .leftbig-title {\n\tfont-size: 32rpx;\n\tcolor: #000;\n\tline-height: 1.5;\n\tmargin-top: 10rpx;\n\twidth: 500rpx;\n\tfont-weight: bold;\n}\n\n.text-pic-list-box .item-leftbig .leftbig-card .leftbig-title.long {\n\twidth: 650rpx;\n}\n\n.text-pic-list-box .item-leftbig .leftbig-card .leftbig-desc {\n\tmargin-top: 20rpx;\n\tfont-size: 24rpx;\n\tcolor: #aaa;\n}\n\n.text-pic-list-box .item-leftbig .leftbig-card .data {\n\tmargin-top: 30rpx;\n\tcolor: #888;\n\tpadding-bottom: 25rpx;\n}"
  },
  {
    "path": "miniprogram/style/public/comm_box_list.wxss",
    "content": "/*** 图文列表盒子 ***/\n.comm-list-box {\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tpadding: 20rpx 30rpx 30rpx 30rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n\toverflow: hidden;\n}\n\n.comm-list-box .item {\n\tpadding: 0rpx 0rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\tbackground-color: #fff;\n\tborder-radius: 20rpx;\n\tmargin-bottom: 30rpx;\n\tposition: relative;\n}\n\n.comm-list-box .bottom-tag {\n\tbackground-color: #f2f2f2;\n\tpadding: 6rpx 15rpx;\n\tborder-radius: 8rpx;\n}\n\n/* 左大图模式  */\n.comm-list-box .item.item-leftbig {\n\tmax-height: 230rpx;\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: flex-start;\n\tflex-direction: row;\n}\n\n.comm-list-box .item-leftbig .leftbig-left {\n\twidth: 200rpx;\n\theight: 230rpx;\n\tborder-top-left-radius: inherit;\n\tborder-bottom-left-radius: inherit;\n}\n\n.comm-list-box .item-leftbig .leftbig-right {\n\tflex: 1;\n\tdisplay: flex;\n\tflex-direction: column;\n\tmargin-left: 20rpx;\n\tmargin-right: 20rpx;\n\tjustify-content: center;\n\talign-items: flex-start;\n\tposition: relative;\n\tpadding: 15rpx 10rpx;\n}\n\n.comm-list-box .item-leftbig .leftbig-right .leftbig-title {\n\twidth: 100%;\n\tfont-size: 34rpx;\n\tcolor: #000;\n\tline-height: 1.5;\n\tmargin-top: 0rpx;\n\tfont-weight: bold;\n}\n\n.comm-list-box .item-leftbig .leftbig-desc {\n\tmargin-top: 5rpx;\n\tfont-size: 26rpx;\n\tcolor: #666;\n\tline-height: 1.4;\n\theight: 107rpx;\n\tmargin-bottom: 10rpx;\n}\n\n\n.comm-list-box .item-leftbig .data { \n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: flex-end;\n\talign-items: center;\n\tmargin-top: 0rpx;\n\tcolor: #bbb;\n\tfont-size: 24rpx;\n\tposition: relative;\n\tmin-height: 40rpx;\n}\n\n.comm-list-box .item-leftbig .data .bottom-tag-list {\n\tmargin-top: 0rpx;\n\tfont-size: 24rpx;\n}\n\n.comm-list-box .item-leftbig .leftbig-right .bottom-status {\n\tfont-size: 24rpx;\n}\n\n/* 大文字模式  */\n.comm-list-box .item.item-bigtext {\n\theight: 220rpx;\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: row;\n\tjustify-content: center;\n\talign-items: center;\n\tposition: relative;\n\tbackground: #fff;\n\tcolor: #333;\n\tpadding: 0 40rpx;\n}\n\n.comm-list-box .item-bigtext .left {\n\tmargin-right: 20rpx;\n\twidth: 100rpx;\n\theight: 100rpx;\n\tbackground-color: #fff;\n\tborder-radius: 50%;\n}\n\n.comm-list-box .item-bigtext .left image {\n\tborder-radius: 50%;\n\twidth: 100rpx;\n\theight: 100rpx;\n}\n\n.comm-list-box .item-bigtext .right {\n\tflex: 1;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: flex-start;\n\tjustify-content: center;\n}\n\n.comm-list-box .item-bigtext .right .bigtext-title {\n\twidth: 100%;\n\tfont-size: 36rpx;\n\tfont-weight: bold;\n\ttext-align: left;\n}\n\n.comm-list-box .item-bigtext .right .data-desc {\n\twidth: 100%;\n\tfont-size: 28rpx;\n\topacity: .7;\n}\n\n.comm-list-box .item-bigtext .data-status {\n\tfont-size: 24rpx;\n\tposition: absolute;\n\tbottom: 10rpx;\n\tright: 40rpx;\n\topacity: .8;\n}\n\n/* 上下图模式  */\n.comm-list-box .item.item-upimg {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n\talign-items: center;\n\tposition: relative;\n\tbackground: #fff;\n\tcolor: #000;\n\tpadding: 0 0rpx 10rpx;\n\toverflow: hidden;\n}\n\n\n.comm-list-box .item-upimg .upimg-title {\n\twidth: 100%;\n\tfont-size: 38rpx;\n\tfont-weight: bold;\n\ttext-align: left;\n\tpadding: 10rpx 20rpx;\n}\n\n\n.comm-list-box .item-upimg image {\n\twidth: 100%;\n\tborder-top-left-radius: inherit;\n\tborder-top-right-radius: inherit;\n}\n\n.comm-list-box .item-upimg .data-desc {\n\twidth: 100%;\n\tfont-size: 28rpx;\n\tcolor: #666;\n\tpadding: 10rpx 20rpx;\n\tmax-height: 90rpx;\n}\n\n.comm-list-box .item-upimg .data-status {\n\twidth: 100%;\n\tfont-size: 24rpx;\n\tcolor: #bbb;\n\tpadding-right: 20rpx;\n\ttext-align: right;\n}\n\n/* 左大图模式1  */\n.comm-list-box .item.item-leftbig1 {\n\tmax-height: 200rpx;\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: center;\n\tflex-direction: row;\n\tmargin-bottom: 20rpx;\n\tpadding: 20rpx;\n}\n\n.comm-list-box .item-leftbig1 .leftbig-left {\n\twidth: 240rpx;\n\theight: 160rpx;\n\tborder-radius: 10rpx !important;\n\toverflow: hidden;\n}\n\n.comm-list-box .item-leftbig1 .leftbig-right {\n\tflex: 1;\n\tdisplay: flex;\n\tflex-direction: column;\n\tmargin-left: 20rpx;\n\tjustify-content: flex-start;\n\talign-items: flex-start;\n\tposition: relative;\n\theight: 160rpx;\n}\n\n.comm-list-box .item-leftbig1 .leftbig-right .leftbig-title {\n\twidth: 100%;\n\tfont-size: 34rpx;\n\tcolor: #000;\n\tfont-weight: bold;\n}\n\n.comm-list-box .item-leftbig1 .leftbig-desc {\n\tmargin-top: 5rpx;\n\tfont-size: 27rpx;\n\tcolor: #666; \n}\n\n\n.comm-list-box .item-leftbig1 .data { \n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: flex-end;\n\talign-items: center;\n\tcolor: #bbb;\n\tfont-size: 24rpx;\n\tposition: absolute;\n\tbottom: 0;\n\tleft: 0;\n}\n\n.comm-list-box .item-leftbig1 .data .bottom-tag-list {\n\tmargin-top: 0rpx;\n\tfont-size: 24rpx;\n}\n\n.comm-list-box .item-leftbig1 .leftbig-right .bottom-status {\n\tfont-size: 24rpx;\n}\n\n\n/* 左大图模式2  */\n.comm-list-box .item.item-leftbig2:first-child {\n\tmargin-top: 60rpx;\n}\n\n.comm-list-box .item.item-leftbig2 {\n\tmax-height: 230rpx;\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: flex-start;\n\tflex-direction: row;\n\tmargin-bottom: 70rpx;\n}\n\n.comm-list-box .item-leftbig2 .leftbig-left {\n\twidth: 200rpx;\n\theight: 250rpx;\n\tmargin-left: 25rpx;\n\tmargin-top: -45rpx;\n\tborder-radius: 10rpx !important;\n\toverflow: hidden;\n}\n\n.comm-list-box .item-leftbig2 .leftbig-right {\n\tflex: 1;\n\tdisplay: flex;\n\tflex-direction: column;\n\tmargin-left: 20rpx;\n\tmargin-right: 20rpx;\n\tjustify-content: center;\n\talign-items: flex-start;\n\tposition: relative;\n\tpadding: 15rpx 10rpx;\n}\n\n.comm-list-box .item-leftbig2 .leftbig-right .leftbig-title {\n\twidth: 100%;\n\tfont-size: 34rpx;\n\tcolor: #000;\n\tline-height: 1.5;\n\tmargin-top: 0rpx;\n\tfont-weight: bold;\n}\n\n.comm-list-box .item-leftbig2 .leftbig-desc {\n\tmargin-top: 5rpx;\n\tfont-size: 28rpx;\n\tcolor: #666;\n\tline-height: 1.4;\n\theight: 107rpx;\n\tmargin-bottom: 10rpx;\n}\n\n\n.comm-list-box .item-leftbig2 .data {\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: flex-end;\n\talign-items: center;\n\tmargin-top: 0rpx;\n\tcolor: #999;\n\tfont-size: 24rpx;\n\tposition: relative;\n\tmin-height: 40rpx;\n}\n\n.comm-list-box .item-leftbig2 .data .bottom-tag-list {\n\tmargin-top: 0rpx;\n\tfont-size: 24rpx;\n}\n\n.comm-list-box .item-leftbig2 .leftbig-right .bottom-status {\n\tfont-size: 24rpx;\n}\n\n/* 左大图模式3  */\n.comm-list-box .item.item-leftbig3:first-child {\n\tmargin-top: 60rpx;\n}\n\n.comm-list-box .item.item-leftbig3 {\n\tmax-height: 180rpx;\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: flex-start;\n\tflex-direction: row;\n\tmargin-bottom: 70rpx;\n}\n\n.comm-list-box .item-leftbig3 .leftbig-left {\n\twidth: 190rpx;\n\theight: 210rpx;\n\tmargin-left: 0rpx;\n\tmargin-top: -30rpx;\n\tborder-radius: 15rpx !important;\n\toverflow: hidden;\n\tbox-shadow: var(--ShadowSize) var(--greyShadow);\n}\n\n.comm-list-box .item-leftbig3 .leftbig-right {\n\tflex: 1;\n\tdisplay: flex;\n\tflex-direction: column;\n\tmargin-left: 20rpx;\n\tmargin-right: 20rpx;\n\tjustify-content: center;\n\talign-items: flex-start;\n\tposition: relative;\n\tpadding: 15rpx 10rpx;\n}\n\n.comm-list-box .item-leftbig3 .leftbig-right .leftbig-title {\n\twidth: 100%;\n\tfont-size: 34rpx;\n\tcolor: #000;\n\tline-height: 1.5;\n\tmargin-top: 0rpx;\n\tfont-weight: bold;\n}\n\n.comm-list-box .item-leftbig3 .leftbig-desc {\n\tmargin-top: 5rpx;\n\tfont-size: 28rpx;\n\tcolor: #666;\n\tline-height: 1.4;\n\theight: 60rpx;\n\tmargin-bottom: 10rpx;\n}\n\n\n.comm-list-box .item-leftbig3 .data {\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: flex-end;\n\talign-items: center;\n\tmargin-top: 0rpx;\n\tcolor: #999;\n\tfont-size: 24rpx;\n\tposition: relative;\n\tmin-height: 40rpx;\n}\n\n.comm-list-box .item-leftbig3 .data .bottom-tag-list {\n\tmargin-top: 0rpx;\n\tfont-size: 24rpx;\n}\n\n.comm-list-box .item-leftbig3 .leftbig-right .bottom-status {\n\tfont-size: 24rpx;\n}\n\n/*右边/左边图*/\n.comm-list-box .item.item-rightpic,\n.comm-list-box .item.item-leftpic {\n\tpadding: 40rpx 30rpx 16rpx 40rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\tbackground-color: #fff;\n\tborder-radius: 20rpx;\n\tmargin-bottom: 20rpx;\n\tposition: relative;\n}\n\n.comm-list-box .item-rightpic .title,\n.comm-list-box .item-leftpic .title {\n\tmax-height: 88rpx;\n\tline-height: 44rpx;\n\tfont-size: 34rpx;\n\tcolor: #000;\n\tfont-weight: bold;\n\tz-index: 999;\n}\n\n.comm-list-box .item-rightpic .desc,\n.comm-list-box .item-leftpic .desc {\n\tmargin-top: 32rpx;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: flex-start;\n\n}\n\n.comm-list-box .item-rightpic .desc text,\n.comm-list-box .item-leftpic .desc text {\n\tmax-height: 120rpx;\n\tline-height: 40rpx;\n\tfont-size: 28rpx;\n\tcolor: #666;\n\tflex: 1;\n}\n\n.comm-list-box .item-rightpic .desc .pic {\n\tmargin-left: 15rpx;\n\twidth: 180rpx;\n\theight: 122rpx;\n\tborder-radius: 10rpx;\n}\n\n\n.comm-list-box .item-leftpic .desc .pic {\n\tmargin-left: 0rpx;\n\tmargin-right: 15rpx;\n\twidth: 180rpx;\n\theight: 122rpx;\n\tborder-radius: 10rpx;\n}\n\n.comm-list-box .item-rightpic .data,\n.comm-list-box .item-leftpic .data {\n\theight: 24rpx;\n\tline-height: 24rpx;\n\tfont-size: 24rpx;\n\tcolor: #bbb;\n\tmargin-top: 30rpx;\n\tdisplay: flex;\n\tjustify-self: center;\n\talign-items: center;\n}\n\n/*横向*/\n.comm-list-scroll {\n\twidth: 100%;\n\tmargin-top: 10rpx;\n\tbackground-color: #fff;\n\twhite-space: nowrap;\n}\n\n.comm-list-scroll .item-scroll {\n\tdisplay: inline-block;\n\tpadding: 10rpx 25rpx 10rpx 0rpx;\n}\n\n.comm-list-scroll .item-scroll image {\n\twidth: 300rpx;\n\theight: 185rpx;\n\tborder-radius: 10rpx;\n}\n\n.comm-list-scroll .item-scroll .title {\n\tfont-size: 28rpx;\n\twidth: 300rpx;\n\theight: 40rpx;\n\tcolor:#000;\n}\n\n\n/*瀑布流*/\n.comm-list-flow {\n\tmargin-top: 10rpx;\n\tbackground-color: #fff;\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: center;\n\tflex-wrap: wrap;\n\tpadding: 0 20rpx;\n}\n\n.comm-list-flow .item-flow {\n\twidth: 50%;\n\tpadding: 10rpx 15rpx 20rpx;\n}\n\n.comm-list-flow .item-flow .item-flow-inner {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n\talign-items: center;\n}\n\n.comm-list-flow .item-flow .item-flow-inner image {\n\twidth: 100%;\n\theight: 420rpx;\n\tborder-radius: 10rpx;\n\tborder: 1rpx solid #ddd;\n}\n\n.comm-list-flow .item-flow .item-flow-inner .title-flow {\n\twidth: 100%;\n\ttext-align: left;\n\tcolor: #333;\n\tfont-size: 28rpx;\n\tfont-weight: bold;\n\tmargin-top: 20rpx;\n}\n\n/*文字条目*/\n.comm-list-box .item-line {\n\twidth: 100%;\n\tbackground-color: #fff;\n\tpadding: 30rpx 20rpx;\n\tdisplay: flex;\n\tborder-bottom: 1rpx solid #ddd;\n\tjustify-content: center;\n}\n\n.comm-list-box .item-line:last-child {\n\tborder-bottom: unset;\n}\n\n.comm-list-box .item-line .left {\n\tflex: 1;\n\tdisplay: flex;\n\talign-items: center;\n}\n\n.comm-list-box .item-line .left .order {\n\tmin-width: 50rpx;\n\tpadding: 0 10rpx;\n\theight: 35rpx;\n\tdisplay: flex;\n\tmargin-right: 10rpx;\n\talign-items: center;\n\tjustify-content: center;\n\tfont-size: 24rpx;\n\tborder-bottom-left-radius: 10rpx;\n\tborder-top-right-radius: 10rpx;\n}\n\n.comm-list-box .item-line .left .title {\n\tflex: 1;\n\tfont-size: 34rpx;\n\tcolor: #000;\n}\n\n.comm-list-box .item-line .right {\n\twidth: 40rpx;\n\tfont-size: 26rpx;\n\ttext-align: right;\n\tcolor: #999;\n} "
  },
  {
    "path": "miniprogram/style/public/detail.wxss",
    "content": "/*** 详情盒子 ***/\n.article-box {\n\tpadding: 0;\n\tbox-sizing: border-box;\n\twidth: 100%;\n}\n\n.article-box .article {\n\tbackground-color: #fff;\n\tpadding: 36rpx 26rpx;\n\tborder-radius: 20rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n\tposition: relative;\n}\n\n\n.article-box .article.join {\n\tdisplay: flex;\n\tflex-direction: row;\n\talign-items: center;\n\twidth: 100%;\n}\n\n.article-box .article.join .left {\n\tflex: 1;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.article-box .article.join .right {\n\twidth: 30rpx;\n}\n\n.article-box .article.join .left .btn {\n\twidth: 100%;\n}\n\n.article-box .article.join .avatar-group {\n\tdirection: unset;\n\tdisplay: flex;\n\tjustify-content: flex-end;\n\talign-items: center;\n}\n\n.article-box .article .title {\n\tfont-size: 38rpx;\n\tline-height: 1.5;\n\tcolor: #000;\n\tfont-weight: bold;\n\tz-index: 999;\n}\n\n.article-box .article .title-sub {\n\tfont-size: 32rpx;\n\tline-height: 1.5;\n\tcolor: #000;\n\tfont-weight: bold;\n\tz-index: 999;\n}\n\n.article-box .article .time {\n\tfont-size: 24rpx;\n\tline-height: 1.5;\n\tcolor: #999;\n\tmargin-top: 20rpx;\n}\n\n.article-box .article .hint {\n\tbox-sizing: border-box;\n\twidth: 100%;\n\tline-height: 1.8;\n\tbackground-color: #f8f8f8;\n\tborder-radius: 20rpx;\n\tcolor: #aaa;\n\tpadding: 10rpx 20rpx;\n\tfont-size: 24rpx;\n}\n\n.article-box .article .address {\n\tmargin: 20rpx 0rpx;\n\tbox-sizing: border-box;\n\twidth: 100%;\n\tline-height: 1.6;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: flex-start;\n\tpadding: 10rpx 0rpx 10rpx;\n\tbackground-color: #f8f8f8;\n\tborder-radius: 10rpx;\n}\n\n.article-box .article .address .address-left {\n\twidth: 50rpx;\n\theight: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: flex-start;\n\talign-items: center;\n}\n\n.article-box .article .address .address-left .icon-location {\n\tfont-size: 26rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: flex-start;\n\talign-items: center;\n}\n\n.article-box .article .address .address-right {\n\theight: 100%;\n\tflex: 1;\n\tfont-size: 26rpx;\n\tfont-weight: bold;\n\tcolor: #666;\n}\n\n.article-box .article .address .address-end {\n\theight: 100%;\n\twidth: 40rpx;\n\tfont-size: 26rpx;\n\tcolor: #ccc;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: center;\n}\n\n\n\n.article-box .article .user-card {\n\tmargin-top: 50rpx;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n}\n\n.article-box .article .user-card .avatar {\n\twidth: 100rpx;\n\theight: 100rpx;\n}\n\n.article-box .article .user-card .detail {\n\tmargin-left: 30rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\tflex: 1;\n}\n\n.article-box .article .user-card .detail .name {\n\theight: 1;\n\tfont-size: 30rpx;\n\twidth: 350rpx;\n\tfont-weight: bold;\n}\n\n.article-box .article .user-card .detail .last {\n\tmargin-top: 15rpx;\n\theight: 1;\n\twidth: 350rpx;\n\tfont-size: 26rpx;\n\tcolor: #aaa;\n}\n\n.article-box .article .user-card .view-btn {\n\twidth: 120rpx;\n\tdisplay: flex;\n\tjustify-content: flex-end;\n\talign-items: center;\n}\n\n.article-box .article .content {\n\tmargin-top: 24rpx;\n\tcolor: #101010;\n\tfont-size: 30rpx;\n\ttext-align: justify;\n\tline-height: 1.6;\n}\n\n.article-box .article .pics {\n\tmargin-top: 30rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n\talign-items: center;\n}\n\n.article-box .article .pics image {\n\twidth: 100%;\n\tborder-radius: 10rpx;\n\tmargin-bottom: 0rpx;\n}\n\n.article-box .comment {\n\tmargin-top: 24rpx;\n\tmargin-bottom: 150rpx;\n\tbackground-color: #fff;\n\tpadding: 10rpx 36rpx 36rpx;\n\tborder-radius: 20rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n}\n\n.article-box .comment .title {\n\tfont-size: 28rpx;\n\tline-height: 2.4;\n\tfont-weight: bold;\n\tborder-bottom: 4rpx solid #eee;\n\tdisplay: flex;\n\tjustify-content: space-between;\n\talign-items: center;\n}\n\n.article-box .comment .list {\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tpadding: 20rpx 0rpx 20rpx 0rpx;\n\tmargin-bottom: 20rpx;\n\tborder-bottom: 2rpx solid #eee;\n}\n\n.article-box .comment .list .avatar {\n\tmargin-right: 20rpx;\n\talign-self: start;\n}\n\n.article-box .comment .list .detail {\n\tflex: 1;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n}\n\n.article-box .comment .list .detail .name {\n\theight: 36rpx;\n\tfont-size: 30rpx;\n\tfont-weight: bold;\n\tdisplay: flex;\n\talign-items: flex-end;\n}\n\n.article-box .comment .list .detail .name .name-real {\n\tmax-width: 200rpx;\n}\n\n.article-box .comment .list .detail .name .classmate {\n\tmargin-left: 20rpx;\n\tmax-width: 250rpx;\n\tfont-size: 24rpx;\n\tcolor: #ccc;\n}\n\n.article-box .comment .list .detail .comment-content {\n\tfont-size: 28rpx;\n\tmargin-top: 30rpx;\n\tline-height: 1.6;\n}\n\n.article-box .comment .list .detail .last {\n\tfont-size: 26rpx;\n\tmargin-top: 16rpx;\n\tcolor: #aaa;\n\tdisplay: flex;\n\tjustify-content: space-between;\n\talign-items: baseline;\n}\n\n.article-box .comment .list .detail .last .time {\n\tfont-size: 24rpx;\n\tmargin-top: 16rpx;\n\tcolor: #aaa;\n}\n\n.article-box .article-bottom {\n\tposition: fixed;\n\theight: 120rpx;\n\tbackground-color: #fff;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tdisplay: flex;\n\tpadding: 22rpx 28rpx;\n\tjustify-content: center;\n\talign-items: center;\n\tborder-top: 6rpx solid #eee;\n}\n\n.article-box .article-bottom .input-comment {\n\tflex: 1;\n\theight: 62rpx;\n\tbackground-color: #f8f8f8;\n\tborder-radius: 100rpx;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: center;\n\tfont-size: 30rpx;\n}\n\n.article-box .article-bottom .data {\n\tmargin-left: 10rpx;\n\twidth: 500rpx;\n\tfont-size: 32rpx;\n\tcolor: #ccc;\n\tdisplay: flex;\n\tjustify-content: flex-end;\n\talign-items: center;\n}\n\n.article-box .article-bottom .share-btn {\n\tbackground-color: transparent !important;\n\tpadding: 0 !important;\n\tline-height: inherit !important;\n\tmargin: 0 0 0 30rpx;\n\twidth: auto !important;\n\tfont-weight: 500 !important;\n\tborder-radius: none !important;\n\tfont-size: 32rpx;\n\tcolor: #333;\n}\n\n.article-box .article-bottom .share-btn::after {\n\tborder: none !important;\n\tpadding: 0 !important;\n\tmargin: 0 !important;\n}\n\n.article-box .comment-modal .bar {\n\tdisplay: flex;\n\talign-items: baseline\n}\n\n.article-box .comment-modal .comment-textarea .form-group textarea {\n\tmargin: 2rpx 0 30rpx;\n}\n\n.article-box .article .corner-right-top {\n\tposition: absolute;\n\ttop: 0;\n\tright: 0;\n\twidth: 150rpx;\n\theight: 60rpx;\n\tborder-radius: 0 20rpx 0 20rpx;\n\tbackground-color: #f8f8f8;\n\tfont-size: 28rpx;\n\tcolor: #aaa;\n\tline-height: 60rpx;\n\ttext-align: center;\n}\n\n/*倾斜角标*/\n.article-box .article .lean-corner-box {\n\tposition: absolute;\n\twidth: 100%;\n\theight: 100rpx;\n\tright: 0;\n\ttop: 0;\n\toverflow: hidden;\n\tz-index: 1;\n}\n\n.article-box .article .lean-corner-right-top {\n\tbackground-color: green;\n\tcolor: white;\n\twidth: 50%;\n\theight: 40rpx;\n\tline-height: 40rpx;\n\ttext-align: center;\n\tmargin-left: 70%;\n\tmargin-top: 18rpx;\n\tposition: absolute;\n\ttransform: rotate(45deg);\n\tz-index: 1999;\n\tfont-size: 24rpx;\n\topacity: .8;\n}\n\n\n.article-box .article .lean-corner-right-bottom {\n\tbackground-color: green;\n\tcolor: white;\n\twidth: 50%;\n\theight: 40rpx;\n\tline-height: 40rpx;\n\ttext-align: center;\n\tmargin-left: 70%;\n\tmargin-bottom: 18rpx;\n\tposition: absolute;\n\tbottom: 0;\n\ttransform: rotate(-45deg);\n\tz-index: 1999;\n\tfont-size: 24rpx;\n\topacity: .8;\n}"
  },
  {
    "path": "miniprogram/style/public/project.wxss",
    "content": " /* 主框架 */\n .main {\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tpadding: 20rpx 20rpx;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n\talign-items: center;\n\tmargin-bottom: 70rpx;\n}\n\n/*表单*/\n.main form {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n}\n\n.form-group .title {\n\tfont-weight: bold;\n}\n\n.form-group .title.must::before {\n\tcolor: red;\n\tcontent: \"*\";\n}\n\n.form-box {\n\tbackground-color: #fff;\n\tborder-radius: 20rpx;\n\tmargin-bottom: 24rpx;\n\tbox-sizing: border-box;\n\twidth: 100%;\n}\n\n\n/* 固定按钮 */\n.btn-fixed {\n\tposition: fixed;\n\tbottom: 130rpx;\n\tright: 12rpx;\n\tcolor: #fff;\n\tfont-size: 40rpx;\n\tfont-weight: bold;\n\tborder-radius: 50%;\n\tbackground-color: #ccc;\n\twidth: 60rpx;\n\theight: 60rpx;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n/*回顶部按钮*/\n.btn-top {\n\tborder: 1rpx solid #ccc;\n\tbackground-color: #f8f8f8 !important;\n}\n\n/*单行大按钮*/\n.btn-main {\n\twidth: 600rpx;\n\tfont-size: 32rpx;\n\theight: 80rpx;\n\tline-height: 80rpx;\n\tborder-radius: 40rpx;\n\tbackground-color: #0E9489;\n\tcolor: #fff;\n\tfont-weight: bold;\n}\n\n.clearbtn {\n\tmargin: 0;\n\tpadding: 0;\n\tbackground-color: transparent;\n\ttext-align: center;\n\tfont-size: inherit;\n\tcolor: inherit;\n\tbox-sizing: border-box;\n\ttext-align: center;\n\ttext-decoration: none;\n\tline-height: unset;\n\tborder-radius: 0;\n\t-webkit-tap-highlight-color: transparent;\n\toverflow: hidden;\n\tfont-weight: normal;\n}\n\n.clearbtn::after {\n\tborder: none !important;\n\tborder-radius: 0;\n}\n\n\n/*非分包菜单*/\n.tab-bar-home {\n\tposition: fixed;\n\ttop: 50rpx;\n\tleft: 20rpx;\n\twidth: 150rpx;\n\theight: 150rpx;\n\tz-index: 999999;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\topacity: .8;\n\tdisplay: flex;\n\talign-items: flex-start;\n\tjustify-content: flex-start;\n}\n\n.tab-bar-home .tab-bar-home-text {\n\tbackground: #fff;\n\tborder-radius: 50%;\n\tfont-size: 36rpx;\n\twidth: 50rpx;\n\theight: 50rpx;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.tab-bar {\n\tposition: fixed;\n\tbottom: 0;\n\tleft: 0;\n\tright: 0;\n\tbackground: #fefefe;\n\tdisplay: flex;\n\tpadding-bottom: constant(safe-area-inset-bottom);\n\tpadding-bottom: env(safe-area-inset-bottom);\n\tz-index: 99999;\n}\n\n.tab-bar-border {\n\tbackground-color: rgba(0, 0, 0, 0.33);\n\tposition: absolute;\n\tleft: 0;\n\ttop: 0;\n\twidth: 100%;\n\theight: 1px;\n\ttransform: scaleY(0.5);\n}\n\n.tab-bar-item {\n\tflex: 1;\n\ttext-align: center;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\talign-items: center;\n\tflex-direction: column;\n\tposition: relative;\n\tpadding-top: 10rpx;\n}\n\n.tab-bar-item .tab-icon {\n\twidth: 48rpx;\n\theight: 48rpx;\n\tmargin-bottom: 2rpx;\n}\n\n.tab-bar-item .tab-text {\n\tfont-size: 24rpx !important;\n\tcolor: #999999;\n}\n\n/**分包距离底部 */\n.sub-margin-bottom {\n\tmargin-bottom: 100rpx;\n}\n\n.btn-base {\n\tpadding: 0 40rpx;\n\tfont-size: 32rpx;\n\theight: 80rpx;\n\tline-height: 80rpx;\n\tborder-radius: 14rpx;\n\twidth: 100%;\n\tcolor: #fff;\n\tbackground-color: var(--projectColor);\n\tfont-weight: bold;\n\tmargin-top: 10rpx;\n\tmargin-bottom: 20rpx;\n}\n\n.btn-base.button-hover {\n\topacity: .9;\n\ttransform: scale(0.95, 0.95);\n\tposition: relative;\n\ttop: 3rpx;\n\tleft: 3rpx;\n\tbox-shadow: 0px 0px 8px rgba(0, 0, 0, .1) inset;\n}\n\n.phone-button {\n\tcolor: #333 !important;\n\tbackground-color: var(--greyLight) !important;\n}\n\n\n/*cmpt-detail底部菜单*/\n.cmpt-biz-detail-mode2-btn {\n\twidth: 100%;\n\tborder-radius: 10rpx;\n\tbackground-color: var(--projectColor);\n\tline-height: 80rpx;\n\tcolor: #fff;\n\tz-index: 9991;\n\tfont-size: 32rpx;\n} "
  },
  {
    "path": "miniprogram/tpls/project/about_tpl.wxml",
    "content": "<view wx:if=\"{{isLoad===null}}\" class=\"margin-top load notexist text-l load-project\"></view>\n<view wx:if=\"{{isLoad===false}}\" class=\"margin-top load loading text-l load-project\"></view>\n\n<view wx:if=\"{{isLoad}}\" class=\"main padding-project\">\n\n\t<view class=\"article-box margin-top-xs\">\n\t\t<!-- article content begin -->\n\t\t<view class=\"article card-project shadow-project\"> \n\n\t\t\t<block wx:for=\"{{about}}\" wx:key=\"key\">\n\t\t\t\t<view class=\"content\" wx:if=\"{{item.type=='text'}}\">\n\t\t\t\t\t<text user-select>{{item.val}}</text>\n\t\t\t\t</view>\n\n\t\t\t\t<view class=\"pics\" wx:if=\"{{item.type=='img'}}\">\n\t\t\t\t\t<image bindtap=\"url\" data-type='img' data-url=\"{{item.val}}\" show-menu-by-longpress=\"{{true}}\" class=\"loading\" mode='widthFix' lazy-load=\"true\" src=\"{{item.val}}\">\n\t\t\t\t\t</image>\n\t\t\t\t</view>\n\t\t\t</block>\n\t\t\t<!-- article content end -->\n\n\n\n\n\t\t</view>\n\t\t<!-- article content end -->\n\n\n\t</view>\n\n\t<view wx:if=\"{{accountInfo}}\" class='text-center text-xs text-grey margin-top'>\n\t\tv{{accountInfo.miniProgram.version}} {{accountInfo.miniProgram.envVersion}}\n\t</view>\n\n</view>"
  },
  {
    "path": "miniprogram/tpls/project/my_fav_tpl.wxml",
    "content": "<cmpt-comm-list type=\"my-fav\" search=\"{{search||''}}\" _menus=\"{{sortMenus||[]}}\" _items=\"{{sortItems||[]}}\" route=\"fav/my_list\" isTotalMenu=\"{{false}}\" topBottom=\"120\" placeholder=\"搜索标题\" returnUrl='/pages/my/fav/my_fav' bind:list=\"myCommListListener\">\n\n\t<!-- List Begin -->\n\t<view class=\"text-pic-list-box\">\n\t\t<view wx:for=\"{{dataList.list}}\" wx:key=\"key\" class=\"item shadow item-simple\" bindtap=\"url\" data-url=\"{{item.FAV_PATH}}\">\n\t\t\t<view class=\"simple\">\n\t\t\t\t<view class=\"simple-right\">\n\t\t\t\t\t<view class=\"simple-title content-cut-one\">{{item.FAV_TITLE}}</view>\n\t\t\t\t\t<view class=\"simple-desc\">\n\t\t\t\t\t\t<text class=\"text-grey text-bold\">{{item.FAV_TYPE}}</text>\n\t\t\t\t\t\t<text class=\"margin-left-s\">{{item.FAV_ADD_TIME}}</text>\n\t\t\t\t\t\t<button catchtap=\"bindDelTap\" data-oid=\"{{item.FAV_OID}}\" class=\"margin-left btn mid bg-white text-red\"><text class=\"icon-delete\"></text>删除</button>\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\t\t\t</view>\n\n\t\t</view>\n\n\t\t<!--load begin-->\n\t\t<import src=\"../../tpls/public/list_load_tpl.wxml\" />\n\t\t<template is=\"listLoadTpl\" data=\"{{skin:'load-project',dataList}}\" />\n\t\t<!--load end-->\n\t</view>\n\t<!-- List END -->\n</cmpt-comm-list>"
  },
  {
    "path": "miniprogram/tpls/project/my_foot_tpl.wxml",
    "content": "<!-- List Begin -->\n<view class=\"text-pic-list-box\">\n\t<view class=\"simple text-center text-grey padding\" wx:if=\"{{!footList || footList.length==0}}\">暂无记录哦~</view>\n\t<view wx:for=\"{{footList}}\" wx:key=\"key\" class=\"item shadow item-simple\" bindtap=\"url\" data-url=\"{{item.path}}\">\n\t\t<view class=\"simple\">\n\t\t\t<view class=\"simple-right\">\n\t\t\t\t<view class=\"simple-title content-cut-one\">{{item.title}}</view>\n\t\t\t\t<view class=\"simple-desc\">\n\t\t\t\t\t<text class=\"text-grey text-bold\">{{item.type}}</text>\n\t\t\t\t\t<text class=\"margin-left-s\">{{item.time}}</text>\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t</view>\n\t</view>\n\n\n\n</view>\n<!-- List END -->"
  },
  {
    "path": "miniprogram/tpls/project/news_index_tpl.wxml",
    "content": "<template name=\"newsIndexTpl\">\n\t<view wx:if=\"{{!_params}}\" class=\"margin-top load loading text-l load-project\"></view>\n\t<block wx:else>\n\n\t\t<cmpt-comm-list type=\"news-list\" search=\"{{search}}\" _params=\"{{_params}}\" _menus=\"{{sortMenus}}\" _items=\"{{sortItems}}\" isTotalMenu=\"{{isTotalMenu}}\" route=\"news/list\" topBottom=\"120\" placeholder=\"搜索标题\" bind:list=\"bindCommListCmpt\">\n\t\t\t<view class=\"up-project\" wx:if=\"{{showUp}}\">\n\t\t\t\t<image wx:if=\"{{upImg}}\" mode=\"widthFix\" lazy-load src=\"{{upImg}}\" />\n\t\t\t</view>\n\n\t\t\t<!-- List Begin -->\n\t\t\t<import src=\"../../tpls/public/base_list_tpl.wxml\" />\n\t\t\t<template is=\"baseListTpl\" data=\"{{dataList:dataList.list,listMode:listMode||'leftpic'}}\" />\n\t\t\t<!-- List END -->\n\n\t\t\t<!--load begin-->\n\t\t\t<import src=\"../../tpls/public/list_load_tpl.wxml\" />\n\t\t\t<template is=\"listLoadTpl\" data=\"{{skin:'load-project',dataList}}\" />\n\t\t\t<!--load end-->\n\t\t</cmpt-comm-list>  \n\n\t</block>\n\n</template>"
  },
  {
    "path": "miniprogram/tpls/project/search_tpl.wxml",
    "content": "<view class=\"main main-search\">\n\t<view class=\"bar search bg-white\">\n\t\t<view class=\"search-form round\">\n\t\t\t<text class=\"icon-search\"></text>\n\t\t\t<input type=\"text\" model:value=\"{{search}}\" placeholder=\"请输入搜索内容\" confirm-type=\"search\" bindconfirm=\"bindSearchConfirm\" maxlength=\"20\"></input>\n\t\t\t<text wx:if=\"{{search.length > 0}}\" bindtap=\"bindClearKeyTap\" class=\"icon-roundclosefill text-l text-gray clear\"></text>\n\t\t</view>\n\t\t<view class=\"action\">\n\t\t\t<button bindtap=\"url\" data-type=\"back\" class=\"btn {{source=='admin'?'bg-admin':'bg-project'}} text-white shadow-blur round\">返回</button>\n\t\t</view>\n\t</view>\n\n\t<view class=\"his\">\n\t\t<view class=\"title\">\n\t\t\t<view class=\"tit\">历史记录</view> <text bindtap=\"bindDelHisTap\" class=\"del text-small icon-delete\"></text>\n\t\t</view>\n\n\t\t<view class=\"search-content\">\n\t\t\t<view wx:for=\"{{hisKeys}}\" bindtap=\"bindKeyTap\" wx:key=\"key\" data-key=\"{{item}}\" class=\"btn mid  round text-darkgreen\">{{item}}</view>\n\t\t</view>\n\t</view>\n\n</view>"
  },
  {
    "path": "miniprogram/tpls/public/admin_forms_detail_tpl.wxml",
    "content": "<template name=\"adminFormsDetailTpl\">\n\t<view class=\"admin-comm-list\">\n\t\t<view class=\"item\">\n\t\t\t<view class=\"info\">\n\t\t\t\t<view class=\"info-item info-item-solid\" wx:key=\"key\" wx:for=\"{{forms}}\">\n\t\t\t\t\t<view class=\"title\">{{item.title}}</view>\n\t\t\t\t\t<view class=\"mao\">：</view>\n\t\t\t\t\t<view wx:if=\"{{item.type=='image'}}\" class=\"content\">\n\t\t\t\t\t\t<image wx:for=\"{{item.val}}\" wx:for-item=\"itm\" wx:key=\"key1\" bindtap=\"url\" data-type=\"image\" data-url=\"{{itm}}\" src=\"{{itm}}\" mode=\"aspectFill\" class=\"loading\" show-menu-by-longpress=\"{{true}}\" />\n\t\t\t\t\t</view>\n\t\t\t\t\t<view wx:elif=\"{{item.type=='switch'}}\" class=\"content\">{{item.val===true?'是':'否'}} </view>\n\t\t\t\t\t<view wx:else class=\"content\">{{item.val}} </view>\n\t\t\t\t</view>\n\t\t\t</view>\n\n\t\t</view>\n\n\t</view>\n</template>"
  },
  {
    "path": "miniprogram/tpls/public/base_list_tpl.wxml",
    "content": "<template name=\"baseListTpl\">\n\t<!--横向拖动 Begin-->\n\t<scroll-view scroll-x=\"{{true}}\" wx:if=\"{{listMode=='scroll'}}\" class=\"comm-list-scroll\">\n\t\t<view class=\"item-scroll\" wx:for=\"{{dataList}}\" wx:key=\"key\" bindtap=\"url\" data-url=\"../../{{item.type}}/detail/{{item.type}}_detail?id={{item.id}}\">\n\t\t\t<image lazy-load=\"{{true}}\" class=\"loading\" src=\"{{item.pic}}\" mode=\"aspectFill\"></image>\n\t\t\t<view class=\"title text-cut\">{{item.title}}</view>\n\t\t</view>\n\t</scroll-view>\n\t<!--横向拖动 END-->\n\n\t<view wx:else class=\"sub-margin-bottom {{listMode=='flow'?'comm-list-flow':'comm-list-box'}}\">\n\t\t<block wx:for=\"{{dataList}}\" wx:key=\"key\">\n\n\t\t\t<!--文字条目 Begin-->\n\t\t\t<view wx:if=\"{{listMode=='line' || listMode=='line-order'}}\" class=\"item-line\" bindtap=\"url\" data-url=\"../../{{item.type}}/detail/{{item.type}}_detail?id={{item.id}}\">\n\t\t\t\t<view class=\"left\">\n\t\t\t\t\t<view wx:if=\"{{listMode=='line-order'}}\" class=\"order bg-gray bg-project\">{{index+1}}</view>\n\t\t\t\t\t<view class=\"title content-cut-one\">{{item.title}}</view>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"right\"><text class=\"icon-right\"></text></view>\n\t\t\t</view>\n\t\t\t<!--文字条目 END-->\n\n\t\t\t<!--瀑布流 Begin-->\n\t\t\t<view wx:if=\"{{listMode=='flow'}}\" class=\"item-flow\" bindtap=\"url\" data-url=\"../../{{item.type}}/detail/{{item.type}}_detail?id={{item.id}}\">\n\t\t\t\t<view class=\"item-flow-inner\">\n\t\t\t\t\t<image mode=\"aspectFill\" lazy-load=\"{{true}}\" class=\"loading shadow\" src=\"{{item.pic}}\" />\n\t\t\t\t\t<view class=\"title-flow content-cut-one\">{{item.title}}</view>\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t\t<!--瀑布流 END-->\n\n\t\t\t<!--上下图 Begin-->\n\t\t\t<view wx:if=\"{{listMode=='upimg'}}\" class=\"item card-project shadow-project item-upimg\" bindtap=\"url\" data-url=\"../../{{item.type}}/detail/{{item.type}}_detail?id={{item.id}}\">\n\t\t\t\t<image mode=\"widthFix\" lazy-load=\"{{true}}\" class=\"loading\" src=\"{{item.pic}}\" />\n\t\t\t\t<view class=\"upimg-title content-cut-two\">{{item.title}}</view>\n\t\t\t\t<view class=\"data-desc content-cut-two\">{{item.desc}}</view>\n\t\t\t\t<view class=\"data-status\">\n\t\t\t\t\t<text wx:if=\"{{item.type=='meet'}}\" class=\"icon-remind margin-right-xxs\"></text>{{item.ext}}\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t\t<!--上下图 END-->\n\n\t\t\t<!--右边图 Begin-->\n\t\t\t<view wx:elif=\"{{listMode=='rightpic'}}\" class=\"item card-project shadow-project item-rightpic\" bindtap=\"url\" data-url=\"../../{{item.type}}/detail/{{item.type}}_detail?id={{item.id}}\">\n\t\t\t\t<view class=\"title content-cut-two\">{{item.title}}</view>\n\t\t\t\t<view class=\"desc\">\n\t\t\t\t\t<text class=\"content-cut-three\">{{item.desc}}</text>\n\t\t\t\t\t<image class=\"pic loading\" lazy-load=\"{{true}}\" mode=\"aspectFill\" src=\"{{item.pic}}\">\n\t\t\t\t\t</image>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"data\">\n\t\t\t\t\t<text class=\"margin-right\">{{item.ext}}</text>\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t\t<!--右边图 END-->\n\n\t\t\t<!--左边图 Begin-->\n\t\t\t<view wx:elif=\"{{listMode=='leftpic'}}\" class=\"item card-project shadow-project item-leftpic\" bindtap=\"url\" data-url=\"../../{{item.type}}/detail/{{item.type}}_detail?id={{item.id}}\">\n\t\t\t\t<view class=\"title content-cut-two\">{{item.title}}</view>\n\t\t\t\t<view class=\"desc\">\n\t\t\t\t\t<image class=\"pic loading\" lazy-load=\"{{true}}\" mode=\"aspectFill\" src=\"{{item.pic}}\">\n\t\t\t\t\t</image>\n\t\t\t\t\t<text class=\"content-cut-three\">{{item.desc}}</text>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"data\">\n\t\t\t\t\t<text class=\"margin-right\">{{item.ext}}</text>\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t\t<!--左边图 END-->\n\n\t\t\t<!--左大图 Begin-->\n\t\t\t<view wx:elif=\"{{listMode=='leftbig'||listMode=='leftbig1'||listMode=='leftbig2' ||listMode=='leftbig3'}}\" class=\"item card-project shadow-project item-{{listMode}}\" bindtap=\"url\" data-url=\"../../{{item.type}}/detail/{{item.type}}_detail?id={{item.id}}\">\n\t\t\t\t<image mode=\"aspectFill\" lazy-load=\"{{true}}\" class=\"leftbig-left loading\" src=\"{{item.pic}}\">\n\t\t\t\t</image>\n\t\t\t\t<view class=\"leftbig-right\">\n\t\t\t\t\t<view class=\"leftbig-title content-cut-one\">{{item.title}}</view>\n\t\t\t\t\t<view class=\"leftbig-desc\">\n\t\t\t\t\t\t<text class=\"{{listMode=='leftbig1' || listMode=='leftbig3'?'content-cut-two':'content-cut-three'}}\">{{item.desc}} </text>\n\t\t\t\t\t</view>\n\t\t\t\t\t<view class=\"data\">\n\t\t\t\t\t\t<view class=\"bottom-tag-list text-cut\">\n\t\t\t\t\t\t</view>\n\t\t\t\t\t\t<view class=\"bottom-status\"><text wx:if=\"{{item.type=='meet'}}\" class=\"icon-remind margin-right-xxs\"></text>{{item.ext}}</view>\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t\t<!--左大图 END-->\n\n\t\t\t<!--大文字 Begin-->\n\t\t\t<view wx:elif=\"{{listMode=='bigtext'}}\" class=\"item card-project shadow-project item-bigtext\" bindtap=\"url\" data-url=\"../../{{item.type}}/detail/{{item.type}}_detail?id={{item.id}}\">\n\t\t\t\t<view class=\"left\">\n\t\t\t\t\t<image mode=\"aspectFill\" lazy-load=\"{{true}}\" class=\"{{item.pic?'loading':''}}\" src=\"{{item.pic}}\" />\n\t\t\t\t</view>\n\n\t\t\t\t<view class=\"right\">\n\t\t\t\t\t<view class=\"bigtext-title content-cut-one\">{{item.title}}</view>\n\t\t\t\t\t<view class=\"data-desc content-cut-one\">{{item.desc}}</view>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"data-status\">\n\t\t\t\t\t<text wx:if=\"{{item.type=='meet'}}\" class=\"icon-remind margin-right-xxs\"></text>{{item.ext}}\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t\t<!--大文字 END-->\n\n\t\t</block>\n\n\t</view>\n</template>"
  },
  {
    "path": "miniprogram/tpls/public/list_load_tpl.wxml",
    "content": "<template name=\"listLoadTpl\">\n\t<view wx:if=\"{{!dataList || (dataList && dataList.page < dataList.count)}}\"\n\t\tclass=\"load text-grey loading {{skin}}\"></view>\n\t<view wx:if=\"{{dataList && dataList.page > 1 && dataList.page == dataList.count }}\"\n\t\tclass=\"load text-grey over {{skin}}\"></view>\n\n\t<block wx:if=\"{{noHintImg}}\">\n\t\t<image style=\"height:500rpx\" mode=\"heightFix\" wx:if=\"{{dataList && dataList.total == 0}}\" src=\"{{noHintImg}}\" mode=\"aspectFit\" />\n\t</block>\n\n\t<block wx:else> \n\t\t<view wx:if=\"{{dataList && dataList.total == 0}}\" class=\"load text-grey {{skin}}\">{{noHint?noHint:'暂无记录哦~'}}</view>\n\t</block>\n\n\t<view style=\"height:200rpx;\"></view>\n\n</template>"
  },
  {
    "path": "miniprogram/tpls/public/top_tpl.wxml",
    "content": "<template name=\"topTpl\">\n\t<view wx:if=\"{{topBtnShow}}\" bindtap=\"top\" class=\"btn-fixed bg-gray btn-top\"\n\t\tstyle=\"color:#888!important;bottom:{{bottom||'200'}}rpx;right:{{right||'12'}}rpx\">\n\t\t<text class=\"icon-top\"></text>\n\t</view>\n</template>"
  },
  {
    "path": "miniprogram/tpls/wxs/tools.wxs",
    "content": " function indexOf(data, key) {\n \treturn data.indexOf(key);\n }\n\n function includes(data, key) {\n \treturn data.indexOf(key) > -1 ? true : false;\n }\n\n function split(str, chr) {\n \tvar arr = str.split(chr);\n \tif (arr.length == 0) return [];\n\n \treturn arr;\n } \n\n module.exports = {\n \tsplit: split,\n \tindexOf: indexOf,\n \tincludes: includes \n };\n module.exports.msg = \"hello tools\";"
  },
  {
    "path": "project.config.json",
    "content": "{\n\t\"miniprogramRoot\": \"miniprogram/\",\n\t\"cloudfunctionRoot\": \"cloudfunctions/\",\n\t\"setting\": {\n\t\t\"urlCheck\": false,\n\t\t\"es6\": true,\n\t\t\"enhance\": true,\n\t\t\"postcss\": true,\n\t\t\"preloadBackgroundData\": false,\n\t\t\"minified\": true,\n\t\t\"newFeature\": true,\n\t\t\"coverView\": true,\n\t\t\"nodeModules\": false,\n\t\t\"autoAudits\": false,\n\t\t\"showShadowRootInWxmlPanel\": true,\n\t\t\"scopeDataCheck\": false,\n\t\t\"uglifyFileName\": true,\n\t\t\"checkInvalidKey\": true,\n\t\t\"checkSiteMap\": true,\n\t\t\"uploadWithSourceMap\": true,\n\t\t\"compileHotReLoad\": false,\n\t\t\"lazyloadPlaceholderEnable\": false,\n\t\t\"useMultiFrameRuntime\": true,\n\t\t\"useApiHook\": true,\n\t\t\"useApiHostProcess\": true,\n\t\t\"babelSetting\": {\n\t\t\t\"ignore\": [],\n\t\t\t\"disablePlugins\": [],\n\t\t\t\"outputPath\": \"\"\n\t\t},\n\t\t\"useIsolateContext\": false,\n\t\t\"userConfirmedUseIsolateContext\": true,\n\t\t\"userConfirmedBundleSwitch\": false,\n\t\t\"packNpmManually\": false,\n\t\t\"packNpmRelationList\": [],\n\t\t\"minifyWXSS\": true,\n\t\t\"disableUseStrict\": false,\n\t\t\"minifyWXML\": true,\n\t\t\"showES6CompileOption\": false,\n\t\t\"useCompilerPlugins\": false,\n\t\t\"ignoreUploadUnusedFiles\": true,\n\t\t\"useStaticServer\": true\n\t},\n\t\"appid\": \"wxb100b44af794708e\",\n\t\"projectname\": \"Multi多功能平台\",\n\t\"libVersion\": \"2.17.0\",\n\t\"simulatorType\": \"wechat\",\n\t\"simulatorPluginLibVersion\": {},\n\t\"cloudfunctionTemplateRoot\": \"cloudfunctionTemplate/\",\n\t\"compileType\": \"miniprogram\",\n\t\"srcMiniprogramRoot\": \"miniprogram/\",\n\t\"packOptions\": {\n\t\t\"ignore\": [],\n\t\t\"include\": []\n\t},\n\t\"editorSetting\": {\n\t\t\"tabIndent\": \"tab\",\n\t\t\"tabSize\": 4\n\t},\n\t\"description\": \"项目配置文件，详见文档：https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html\",\n\t\"condition\": {}\n}"
  },
  {
    "path": "project.private.config.json",
    "content": "{\n\t\"setting\": {\n\t\t\"compileHotReLoad\": true,\n\t\t\"urlCheck\": false\n\t},\n\t\"description\": \"项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档：https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html\",\n\t\"projectname\": \"%E6%97%85%E6%B8%B8%E6%99%AF%E5%8C%BA1-github\",\n\t\"condition\": {},\n\t\"libVersion\": \"2.17.0\"\n}"
  }
]