Full Code of nanbouking/WeTravel for AI

master 3d07a91e98bc cached
509 files
1.3 MB
533.6k tokens
1014 symbols
1 requests
Download .txt
Showing preview only (1,534K chars total). Download the full file or copy to clipboard to get everything.
Repository: nanbouking/WeTravel
Branch: master
Commit: 3d07a91e98bc
Files: 509
Total size: 1.3 MB

Directory structure:
gitextract_4tbgnvos/

├── .gitignore
├── README.md
├── cloudfunctions/
│   └── mcloud/
│       ├── config/
│       │   └── config.js
│       ├── config.json
│       ├── framework/
│       │   ├── cloud/
│       │   │   ├── cloud_base.js
│       │   │   └── cloud_util.js
│       │   ├── core/
│       │   │   ├── app_code.js
│       │   │   ├── app_error.js
│       │   │   ├── app_other.js
│       │   │   ├── app_util.js
│       │   │   └── application.js
│       │   ├── database/
│       │   │   ├── db_util.js
│       │   │   ├── model.js
│       │   │   └── multi_model.js
│       │   ├── lib/
│       │   │   ├── faker_lib.js
│       │   │   ├── md5_lib.js
│       │   │   └── mini_lib.js
│       │   ├── platform/
│       │   │   ├── controller/
│       │   │   │   ├── base_admin_controller.js
│       │   │   │   └── base_controller.js
│       │   │   ├── model/
│       │   │   │   ├── admin_model.js
│       │   │   │   ├── base_model.js
│       │   │   │   └── log_model.js
│       │   │   └── service/
│       │   │       ├── base_admin_service.js
│       │   │       └── base_service.js
│       │   ├── utils/
│       │   │   ├── constant.js
│       │   │   ├── data_util.js
│       │   │   ├── export_util.js
│       │   │   ├── log_util.js
│       │   │   ├── math_util.js
│       │   │   ├── setup/
│       │   │   │   ├── setup_model.js
│       │   │   │   └── setup_util.js
│       │   │   ├── time_util.js
│       │   │   └── util.js
│       │   └── validate/
│       │       ├── content_check.js
│       │       └── data_check.js
│       ├── index.js
│       ├── package.json
│       └── project/
│           └── TRIP1/
│               ├── controller/
│               │   ├── admin/
│               │   │   ├── admin_album_controller.js
│               │   │   ├── admin_home_controller.js
│               │   │   ├── admin_meet_controller.js
│               │   │   ├── admin_mgr_controller.js
│               │   │   ├── admin_news_controller.js
│               │   │   ├── admin_product_controller.js
│               │   │   ├── admin_setup_controller.js
│               │   │   ├── admin_user_controller.js
│               │   │   └── base_project_admin_controller.js
│               │   ├── album_controller.js
│               │   ├── base_project_controller.js
│               │   ├── check_controller.js
│               │   ├── fav_controller.js
│               │   ├── home_controller.js
│               │   ├── meet_controller.js
│               │   ├── my_controller.js
│               │   ├── news_controller.js
│               │   ├── passport_controller.js
│               │   ├── product_controller.js
│               │   └── test/
│               │       └── test_controller.js
│               ├── model/
│               │   ├── album_model.js
│               │   ├── base_project_model.js
│               │   ├── day_model.js
│               │   ├── fav_model.js
│               │   ├── join_model.js
│               │   ├── meet_model.js
│               │   ├── news_model.js
│               │   ├── product_model.js
│               │   └── user_model.js
│               ├── public/
│               │   ├── constants.js
│               │   ├── project_config.js
│               │   └── route.js
│               └── service/
│                   ├── admin/
│                   │   ├── admin_album_service.js
│                   │   ├── admin_home_service.js
│                   │   ├── admin_meet_service.js
│                   │   ├── admin_mgr_service.js
│                   │   ├── admin_news_service.js
│                   │   ├── admin_product_service.js
│                   │   ├── admin_setup_service.js
│                   │   ├── admin_user_service.js
│                   │   └── base_project_admin_service.js
│                   ├── album_service.js
│                   ├── base_project_service.js
│                   ├── fav_service.js
│                   ├── home_service.js
│                   ├── meet_service.js
│                   ├── news_service.js
│                   ├── passport_service.js
│                   └── product_service.js
├── miniprogram/
│   ├── app.js
│   ├── app.json
│   ├── app.wxss
│   ├── cmpts/
│   │   ├── biz/
│   │   │   ├── detail/
│   │   │   │   ├── detail_cmpt.js
│   │   │   │   ├── detail_cmpt.json
│   │   │   │   ├── detail_cmpt.wxml
│   │   │   │   └── detail_cmpt.wxss
│   │   │   └── foot/
│   │   │       ├── foot_cmpt.js
│   │   │       ├── foot_cmpt.json
│   │   │       ├── foot_cmpt.wxml
│   │   │       └── foot_cmpt.wxss
│   │   └── public/
│   │       ├── calendar/
│   │       │   ├── calendar_comm/
│   │       │   │   ├── calendar_comm_cmpt.js
│   │       │   │   ├── calendar_comm_cmpt.json
│   │       │   │   ├── calendar_comm_cmpt.wxml
│   │       │   │   ├── calendar_comm_cmpt.wxss
│   │       │   │   └── din.wxss
│   │       │   ├── calendar_lib.js
│   │       │   ├── calendar_meet/
│   │       │   │   ├── calendar_meet_cmpt.js
│   │       │   │   ├── calendar_meet_cmpt.json
│   │       │   │   ├── calendar_meet_cmpt.wxml
│   │       │   │   └── calendar_meet_cmpt.wxss
│   │       │   ├── date_select/
│   │       │   │   ├── date_select_cmpt.js
│   │       │   │   ├── date_select_cmpt.json
│   │       │   │   ├── date_select_cmpt.wxml
│   │       │   │   └── date_select_cmpt.wxss
│   │       │   └── time_select/
│   │       │       ├── time_select_cmpt.js
│   │       │       ├── time_select_cmpt.json
│   │       │       ├── time_select_cmpt.wxml
│   │       │       └── time_select_cmpt.wxss
│   │       ├── checkbox/
│   │       │   ├── checkbox_cmpt.js
│   │       │   ├── checkbox_cmpt.json
│   │       │   ├── checkbox_cmpt.wxml
│   │       │   └── checkbox_cmpt.wxss
│   │       ├── editor/
│   │       │   ├── editor_cmpt.js
│   │       │   ├── editor_cmpt.json
│   │       │   ├── editor_cmpt.wxml
│   │       │   └── editor_cmpt.wxss
│   │       ├── form/
│   │       │   ├── form_set/
│   │       │   │   ├── field/
│   │       │   │   │   ├── form_set_field.js
│   │       │   │   │   ├── form_set_field.json
│   │       │   │   │   ├── form_set_field.wxml
│   │       │   │   │   └── form_set_field.wxss
│   │       │   │   ├── form_set_cmpt.js
│   │       │   │   ├── form_set_cmpt.json
│   │       │   │   ├── form_set_cmpt.wxml
│   │       │   │   └── form_set_cmpt.wxss
│   │       │   ├── form_set_helper.js
│   │       │   └── form_show/
│   │       │       ├── content/
│   │       │       │   ├── form_show_content.js
│   │       │       │   ├── form_show_content.json
│   │       │       │   ├── form_show_content.wxml
│   │       │       │   └── form_show_content.wxss
│   │       │       ├── form_show_cmpt.js
│   │       │       ├── form_show_cmpt.json
│   │       │       ├── form_show_cmpt.wxml
│   │       │       └── form_show_cmpt.wxss
│   │       ├── img/
│   │       │   ├── img_upload_cmpt.js
│   │       │   ├── img_upload_cmpt.json
│   │       │   ├── img_upload_cmpt.wxml
│   │       │   └── img_upload_cmpt.wxss
│   │       ├── list/
│   │       │   ├── comm_list_cmpt.js
│   │       │   ├── comm_list_cmpt.json
│   │       │   ├── comm_list_cmpt.wxml
│   │       │   └── comm_list_cmpt.wxss
│   │       ├── modal/
│   │       │   ├── modal_cmpt.js
│   │       │   ├── modal_cmpt.json
│   │       │   ├── modal_cmpt.wxml
│   │       │   └── modal_cmpt.wxss
│   │       ├── picker/
│   │       │   ├── picker_cmpt.js
│   │       │   ├── picker_cmpt.json
│   │       │   ├── picker_cmpt.wxml
│   │       │   └── picker_cmpt.wxss
│   │       ├── picker_multi/
│   │       │   ├── picker_multi_cmpt.js
│   │       │   ├── picker_multi_cmpt.json
│   │       │   ├── picker_multi_cmpt.wxml
│   │       │   └── picker_multi_cmpt.wxss
│   │       ├── picker_time/
│   │       │   ├── datetime_picker.js
│   │       │   ├── picker_time_cmpt.js
│   │       │   ├── picker_time_cmpt.json
│   │       │   ├── picker_time_cmpt.wxml
│   │       │   └── picker_time_cmpt.wxss
│   │       ├── poster/
│   │       │   ├── poster_cmpt.js
│   │       │   ├── poster_cmpt.json
│   │       │   ├── poster_cmpt.wxml
│   │       │   ├── poster_cmpt.wxss
│   │       │   ├── poster_cmpt_helper.js
│   │       │   └── wxa-plugin-canvas/
│   │       │       ├── index/
│   │       │       │   ├── index.js
│   │       │       │   ├── index.json
│   │       │       │   ├── index.wxml
│   │       │       │   └── index.wxss
│   │       │       └── poster/
│   │       │           ├── index.js
│   │       │           ├── index.json
│   │       │           ├── index.wxml
│   │       │           ├── index.wxss
│   │       │           └── poster.js
│   │       ├── radio/
│   │       │   ├── radio_cmpt.js
│   │       │   ├── radio_cmpt.json
│   │       │   ├── radio_cmpt.wxml
│   │       │   └── radio_cmpt.wxss
│   │       ├── swiper/
│   │       │   ├── swiper_cmpt.js
│   │       │   ├── swiper_cmpt.json
│   │       │   ├── swiper_cmpt.wxml
│   │       │   └── swiper_cmpt.wxss
│   │       └── table/
│   │           ├── table_cmpt.js
│   │           ├── table_cmpt.json
│   │           ├── table_cmpt.wxml
│   │           └── table_cmpt.wxss
│   ├── comm/
│   │   ├── behavior/
│   │   │   ├── about_bh.js
│   │   │   ├── my_fav_bh.js
│   │   │   ├── my_foot_bh.js
│   │   │   ├── news_index_bh.js
│   │   │   └── search_bh.js
│   │   ├── biz/
│   │   │   ├── admin_biz.js
│   │   │   ├── base_biz.js
│   │   │   ├── fav_biz.js
│   │   │   ├── foot_biz.js
│   │   │   ├── passport_biz.js
│   │   │   ├── public_biz.js
│   │   │   └── search_biz.js
│   │   └── constants.js
│   ├── helper/
│   │   ├── cache_helper.js
│   │   ├── cloud_helper.js
│   │   ├── content_check_helper.js
│   │   ├── data_helper.js
│   │   ├── file_helper.js
│   │   ├── form_helper.js
│   │   ├── helper.js
│   │   ├── mini_helper.js
│   │   ├── page_helper.js
│   │   ├── pic_helper.js
│   │   ├── time_helper.js
│   │   └── validate.js
│   ├── lib/
│   │   └── tools/
│   │       ├── base64_lib.js
│   │       ├── lunar_lib.js
│   │       └── qrcode_lib.js
│   ├── pages/
│   │   └── test1/
│   │       ├── test1.js
│   │       └── test1.wxml
│   ├── projects/
│   │   └── TRIP1/
│   │       ├── biz/
│   │       │   ├── admin_album_biz.js
│   │       │   ├── admin_meet_biz.js
│   │       │   ├── admin_news_biz.js
│   │       │   ├── admin_product_biz.js
│   │       │   ├── album_biz.js
│   │       │   ├── meet_biz.js
│   │       │   ├── news_biz.js
│   │       │   ├── product_biz.js
│   │       │   └── project_biz.js
│   │       ├── pages/
│   │       │   ├── about/
│   │       │   │   ├── index/
│   │       │   │   │   ├── about_index.js
│   │       │   │   │   ├── about_index.json
│   │       │   │   │   ├── about_index.wxml
│   │       │   │   │   └── about_index.wxss
│   │       │   │   └── service/
│   │       │   │       ├── about_service.js
│   │       │   │       ├── about_service.json
│   │       │   │       ├── about_service.wxml
│   │       │   │       └── about_service.wxss
│   │       │   ├── admin/
│   │       │   │   ├── album/
│   │       │   │   │   ├── add/
│   │       │   │   │   │   ├── admin_album_add.js
│   │       │   │   │   │   ├── admin_album_add.json
│   │       │   │   │   │   ├── admin_album_add.wxml
│   │       │   │   │   │   └── admin_album_add.wxss
│   │       │   │   │   ├── admin_album_form_tpl.wxml
│   │       │   │   │   ├── edit/
│   │       │   │   │   │   ├── admin_album_edit.js
│   │       │   │   │   │   ├── admin_album_edit.json
│   │       │   │   │   │   ├── admin_album_edit.wxml
│   │       │   │   │   │   └── admin_album_edit.wxss
│   │       │   │   │   └── list/
│   │       │   │   │       ├── admin_album_list.js
│   │       │   │   │       ├── admin_album_list.json
│   │       │   │   │       ├── admin_album_list.wxml
│   │       │   │   │       └── admin_album_list.wxss
│   │       │   │   ├── content/
│   │       │   │   │   ├── admin_content.js
│   │       │   │   │   ├── admin_content.json
│   │       │   │   │   ├── admin_content.wxml
│   │       │   │   │   └── admin_content.wxss
│   │       │   │   ├── index/
│   │       │   │   │   ├── home/
│   │       │   │   │   │   ├── admin_home.js
│   │       │   │   │   │   ├── admin_home.json
│   │       │   │   │   │   ├── admin_home.wxml
│   │       │   │   │   │   └── admin_home.wxss
│   │       │   │   │   └── login/
│   │       │   │   │       ├── admin_login.js
│   │       │   │   │       ├── admin_login.json
│   │       │   │   │       ├── admin_login.wxml
│   │       │   │   │       └── admin_login.wxss
│   │       │   │   ├── meet/
│   │       │   │   │   ├── cover/
│   │       │   │   │   │   ├── admin_meet_cover.js
│   │       │   │   │   │   ├── admin_meet_cover.json
│   │       │   │   │   │   ├── admin_meet_cover.wxml
│   │       │   │   │   │   └── admin_meet_cover.wxss
│   │       │   │   │   ├── edit/
│   │       │   │   │   │   ├── admin_meet_edit.js
│   │       │   │   │   │   ├── admin_meet_edit.json
│   │       │   │   │   │   ├── admin_meet_edit.wxml
│   │       │   │   │   │   └── admin_meet_edit.wxss
│   │       │   │   │   ├── export/
│   │       │   │   │   │   ├── admin_join_export.js
│   │       │   │   │   │   ├── admin_join_export.json
│   │       │   │   │   │   ├── admin_join_export.wxml
│   │       │   │   │   │   └── admin_join_export.wxss
│   │       │   │   │   ├── join/
│   │       │   │   │   │   ├── admin_meet_join.js
│   │       │   │   │   │   ├── admin_meet_join.json
│   │       │   │   │   │   ├── admin_meet_join.wxml
│   │       │   │   │   │   └── admin_meet_join.wxss
│   │       │   │   │   ├── list/
│   │       │   │   │   │   ├── admin_meet_list.js
│   │       │   │   │   │   ├── admin_meet_list.json
│   │       │   │   │   │   ├── admin_meet_list.wxml
│   │       │   │   │   │   └── admin_meet_list.wxss
│   │       │   │   │   ├── record/
│   │       │   │   │   │   ├── admin_record_list.js
│   │       │   │   │   │   ├── admin_record_list.json
│   │       │   │   │   │   ├── admin_record_list.wxml
│   │       │   │   │   │   └── admin_record_list.wxss
│   │       │   │   │   ├── scan/
│   │       │   │   │   │   ├── admin_meet_scan.js
│   │       │   │   │   │   ├── admin_meet_scan.json
│   │       │   │   │   │   ├── admin_meet_scan.wxml
│   │       │   │   │   │   └── admin_meet_scan.wxss
│   │       │   │   │   ├── self/
│   │       │   │   │   │   ├── admin_meet_self.js
│   │       │   │   │   │   ├── admin_meet_self.json
│   │       │   │   │   │   ├── admin_meet_self.wxml
│   │       │   │   │   │   └── admin_meet_self.wxss
│   │       │   │   │   ├── temp/
│   │       │   │   │   │   ├── admin_temp_select.js
│   │       │   │   │   │   ├── admin_temp_select.json
│   │       │   │   │   │   ├── admin_temp_select.wxml
│   │       │   │   │   │   └── admin_temp_select.wxss
│   │       │   │   │   └── time/
│   │       │   │   │       ├── admin_meet_time.js
│   │       │   │   │       ├── admin_meet_time.json
│   │       │   │   │       ├── admin_meet_time.wxml
│   │       │   │   │       └── admin_meet_time.wxss
│   │       │   │   ├── mgr/
│   │       │   │   │   ├── add/
│   │       │   │   │   │   ├── admin_mgr_add.js
│   │       │   │   │   │   ├── admin_mgr_add.json
│   │       │   │   │   │   ├── admin_mgr_add.wxml
│   │       │   │   │   │   └── admin_mgr_add.wxss
│   │       │   │   │   ├── edit/
│   │       │   │   │   │   ├── admin_mgr_edit.js
│   │       │   │   │   │   ├── admin_mgr_edit.json
│   │       │   │   │   │   ├── admin_mgr_edit.wxml
│   │       │   │   │   │   └── admin_mgr_edit.wxss
│   │       │   │   │   ├── list/
│   │       │   │   │   │   ├── admin_mgr_list.js
│   │       │   │   │   │   ├── admin_mgr_list.json
│   │       │   │   │   │   ├── admin_mgr_list.wxml
│   │       │   │   │   │   └── admin_mgr_list.wxss
│   │       │   │   │   ├── log/
│   │       │   │   │   │   ├── admin_log_list.js
│   │       │   │   │   │   ├── admin_log_list.json
│   │       │   │   │   │   ├── admin_log_list.wxml
│   │       │   │   │   │   └── admin_log_list.wxss
│   │       │   │   │   └── pwd/
│   │       │   │   │       ├── admin_mgr_pwd.js
│   │       │   │   │       ├── admin_mgr_pwd.json
│   │       │   │   │       ├── admin_mgr_pwd.wxml
│   │       │   │   │       └── admin_mgr_pwd.wxss
│   │       │   │   ├── news/
│   │       │   │   │   ├── add/
│   │       │   │   │   │   ├── admin_news_add.js
│   │       │   │   │   │   ├── admin_news_add.json
│   │       │   │   │   │   ├── admin_news_add.wxml
│   │       │   │   │   │   └── admin_news_add.wxss
│   │       │   │   │   ├── admin_news_form_tpl.wxml
│   │       │   │   │   ├── edit/
│   │       │   │   │   │   ├── admin_news_edit.js
│   │       │   │   │   │   ├── admin_news_edit.json
│   │       │   │   │   │   ├── admin_news_edit.wxml
│   │       │   │   │   │   └── admin_news_edit.wxss
│   │       │   │   │   └── list/
│   │       │   │   │       ├── admin_news_list.js
│   │       │   │   │       ├── admin_news_list.json
│   │       │   │   │       ├── admin_news_list.wxml
│   │       │   │   │       └── admin_news_list.wxss
│   │       │   │   ├── product/
│   │       │   │   │   ├── add/
│   │       │   │   │   │   ├── admin_product_add.js
│   │       │   │   │   │   ├── admin_product_add.json
│   │       │   │   │   │   ├── admin_product_add.wxml
│   │       │   │   │   │   └── admin_product_add.wxss
│   │       │   │   │   ├── admin_product_form_tpl.wxml
│   │       │   │   │   ├── edit/
│   │       │   │   │   │   ├── admin_product_edit.js
│   │       │   │   │   │   ├── admin_product_edit.json
│   │       │   │   │   │   ├── admin_product_edit.wxml
│   │       │   │   │   │   └── admin_product_edit.wxss
│   │       │   │   │   └── list/
│   │       │   │   │       ├── admin_product_list.js
│   │       │   │   │       ├── admin_product_list.json
│   │       │   │   │       ├── admin_product_list.wxml
│   │       │   │   │       └── admin_product_list.wxss
│   │       │   │   ├── setup/
│   │       │   │   │   ├── about/
│   │       │   │   │   │   ├── admin_setup_about.js
│   │       │   │   │   │   ├── admin_setup_about.json
│   │       │   │   │   │   ├── admin_setup_about.wxml
│   │       │   │   │   │   └── admin_setup_about.wxss
│   │       │   │   │   ├── about_list/
│   │       │   │   │   │   ├── admin_setup_about_list.js
│   │       │   │   │   │   ├── admin_setup_about_list.json
│   │       │   │   │   │   ├── admin_setup_about_list.wxml
│   │       │   │   │   │   └── admin_setup_about_list.wxss
│   │       │   │   │   └── qr/
│   │       │   │   │       ├── admin_setup_qr.js
│   │       │   │   │       ├── admin_setup_qr.json
│   │       │   │   │       ├── admin_setup_qr.wxml
│   │       │   │   │       └── admin_setup_qr.wxss
│   │       │   │   └── user/
│   │       │   │       ├── detail/
│   │       │   │       │   ├── admin_user_detail.js
│   │       │   │       │   ├── admin_user_detail.json
│   │       │   │       │   ├── admin_user_detail.wxml
│   │       │   │       │   └── admin_user_detail.wxss
│   │       │   │       ├── export/
│   │       │   │       │   ├── admin_user_export.js
│   │       │   │       │   ├── admin_user_export.json
│   │       │   │       │   ├── admin_user_export.wxml
│   │       │   │       │   └── admin_user_export.wxss
│   │       │   │       └── list/
│   │       │   │           ├── admin_user_list.js
│   │       │   │           ├── admin_user_list.json
│   │       │   │           ├── admin_user_list.wxml
│   │       │   │           └── admin_user_list.wxss
│   │       │   ├── album/
│   │       │   │   ├── detail/
│   │       │   │   │   ├── album_detail.js
│   │       │   │   │   ├── album_detail.json
│   │       │   │   │   ├── album_detail.wxml
│   │       │   │   │   └── album_detail.wxss
│   │       │   │   └── index/
│   │       │   │       ├── album_index.js
│   │       │   │       ├── album_index.json
│   │       │   │       ├── album_index.wxml
│   │       │   │       └── album_index.wxss
│   │       │   ├── default/
│   │       │   │   └── index/
│   │       │   │       ├── default_index.js
│   │       │   │       ├── default_index.json
│   │       │   │       ├── default_index.wxml
│   │       │   │       └── default_index.wxss
│   │       │   ├── meet/
│   │       │   │   ├── calendar/
│   │       │   │   │   ├── meet_calendar.js
│   │       │   │   │   ├── meet_calendar.json
│   │       │   │   │   ├── meet_calendar.wxml
│   │       │   │   │   └── meet_calendar.wxss
│   │       │   │   ├── detail/
│   │       │   │   │   ├── meet_detail.js
│   │       │   │   │   ├── meet_detail.json
│   │       │   │   │   ├── meet_detail.wxml
│   │       │   │   │   └── meet_detail.wxss
│   │       │   │   ├── index/
│   │       │   │   │   ├── meet_index.js
│   │       │   │   │   ├── meet_index.json
│   │       │   │   │   ├── meet_index.wxml
│   │       │   │   │   └── meet_index.wxss
│   │       │   │   ├── join/
│   │       │   │   │   ├── meet_join.js
│   │       │   │   │   ├── meet_join.json
│   │       │   │   │   ├── meet_join.wxml
│   │       │   │   │   └── meet_join.wxss
│   │       │   │   ├── my_join_detail/
│   │       │   │   │   ├── meet_my_join_detail.js
│   │       │   │   │   ├── meet_my_join_detail.json
│   │       │   │   │   ├── meet_my_join_detail.wxml
│   │       │   │   │   └── meet_my_join_detail.wxss
│   │       │   │   ├── my_join_list/
│   │       │   │   │   ├── meet_my_join_list.js
│   │       │   │   │   ├── meet_my_join_list.json
│   │       │   │   │   ├── meet_my_join_list.wxml
│   │       │   │   │   └── meet_my_join_list.wxss
│   │       │   │   └── self/
│   │       │   │       ├── meet_self.js
│   │       │   │       ├── meet_self.json
│   │       │   │       ├── meet_self.wxml
│   │       │   │       └── meet_self.wxss
│   │       │   ├── my/
│   │       │   │   ├── edit/
│   │       │   │   │   ├── my_edit.js
│   │       │   │   │   ├── my_edit.json
│   │       │   │   │   ├── my_edit.wxml
│   │       │   │   │   ├── my_edit.wxss
│   │       │   │   │   └── user_form.wxml
│   │       │   │   ├── fav/
│   │       │   │   │   ├── my_fav.js
│   │       │   │   │   ├── my_fav.json
│   │       │   │   │   ├── my_fav.wxml
│   │       │   │   │   └── my_fav.wxss
│   │       │   │   ├── foot/
│   │       │   │   │   ├── my_foot.js
│   │       │   │   │   ├── my_foot.json
│   │       │   │   │   ├── my_foot.wxml
│   │       │   │   │   └── my_foot.wxss
│   │       │   │   ├── index/
│   │       │   │   │   ├── my_index.js
│   │       │   │   │   ├── my_index.json
│   │       │   │   │   ├── my_index.wxml
│   │       │   │   │   └── my_index.wxss
│   │       │   │   └── reg/
│   │       │   │       ├── my_reg.js
│   │       │   │       ├── my_reg.json
│   │       │   │       ├── my_reg.wxml
│   │       │   │       └── my_reg.wxss
│   │       │   ├── news/
│   │       │   │   ├── cate1/
│   │       │   │   │   ├── news_cate1.js
│   │       │   │   │   ├── news_cate1.json
│   │       │   │   │   ├── news_cate1.wxml
│   │       │   │   │   └── news_cate1.wxss
│   │       │   │   ├── cate2/
│   │       │   │   │   ├── news_cate2.js
│   │       │   │   │   ├── news_cate2.json
│   │       │   │   │   ├── news_cate2.wxml
│   │       │   │   │   └── news_cate2.wxss
│   │       │   │   ├── detail/
│   │       │   │   │   ├── news_detail.js
│   │       │   │   │   ├── news_detail.json
│   │       │   │   │   ├── news_detail.wxml
│   │       │   │   │   └── news_detail.wxss
│   │       │   │   └── index/
│   │       │   │       ├── news_index.js
│   │       │   │       ├── news_index.json
│   │       │   │       ├── news_index.wxml
│   │       │   │       └── news_index.wxss
│   │       │   ├── product/
│   │       │   │   ├── detail/
│   │       │   │   │   ├── product_detail.js
│   │       │   │   │   ├── product_detail.json
│   │       │   │   │   ├── product_detail.wxml
│   │       │   │   │   └── product_detail.wxss
│   │       │   │   └── index/
│   │       │   │       ├── product_index.js
│   │       │   │       ├── product_index.json
│   │       │   │       ├── product_index.wxml
│   │       │   │       └── product_index.wxss
│   │       │   ├── search/
│   │       │   │   ├── search.js
│   │       │   │   ├── search.json
│   │       │   │   ├── search.wxml
│   │       │   │   └── search.wxss
│   │       │   └── tpls/
│   │       │       └── menu_tpl.wxml
│   │       ├── public/
│   │       │   └── project_setting.js
│   │       └── style/
│   │           └── skin.wxss
│   ├── setting/
│   │   └── setting.js
│   ├── sitemap.json
│   ├── style/
│   │   ├── base/
│   │   │   ├── animation.wxss
│   │   │   ├── avatar.wxss
│   │   │   ├── background.wxss
│   │   │   ├── bar.wxss
│   │   │   ├── base.wxss
│   │   │   ├── border.wxss
│   │   │   ├── button.wxss
│   │   │   ├── comm.wxss
│   │   │   ├── form.wxss
│   │   │   ├── icon.wxss
│   │   │   ├── image.wxss
│   │   │   ├── layout.wxss
│   │   │   ├── list.wxss
│   │   │   ├── load.wxss
│   │   │   ├── modal.wxss
│   │   │   ├── nav.wxss
│   │   │   ├── shadow.wxss
│   │   │   ├── table.wxss
│   │   │   ├── tag.wxss
│   │   │   └── text.wxss
│   │   ├── project/
│   │   │   ├── admin_list_style.wxss
│   │   │   ├── my_fav_style.wxss
│   │   │   ├── my_foot_style.wxss
│   │   │   └── search_style.wxss
│   │   └── public/
│   │       ├── admin.wxss
│   │       ├── article_list.wxss
│   │       ├── comm_box_list.wxss
│   │       ├── detail.wxss
│   │       └── project.wxss
│   └── tpls/
│       ├── project/
│       │   ├── about_tpl.wxml
│       │   ├── my_fav_tpl.wxml
│       │   ├── my_foot_tpl.wxml
│       │   ├── news_index_tpl.wxml
│       │   └── search_tpl.wxml
│       ├── public/
│       │   ├── admin_forms_detail_tpl.wxml
│       │   ├── base_list_tpl.wxml
│       │   ├── list_load_tpl.wxml
│       │   └── top_tpl.wxml
│       └── wxs/
│           └── tools.wxs
├── project.config.json
├── project.private.config.json
└── 旅游景区门户小程序安装使用手册.docx

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Windows
[Dd]esktop.ini
Thumbs.db
$RECYCLE.BIN/

# macOS
.DS_Store
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes

# Node.js
node_modules/


================================================
FILE: README.md
================================================
## 功能 介绍 

 旅游景区门户小程序是一个为游客朋友提供多元化服务的一站式数字文旅平台,提供“吃、住、游、购、娱”等旅游行程中的多种服务,全面支持景区介绍,景点攻略,景点预约,停车预约、景区导览等功能,游客可以在小程序中了解旅游度假区的景点信息、历史文化、各类活动等。前后端代码完整,采用腾讯提供的小程序云开发解决方案,无须服务器和域名。
 
- 景点预约管理:开始/截止时间/人数均可灵活设置,可以自定义客户预约填写的数据项
- 景点预约凭证:支持线下到场后校验签到/核销/二维码自助签到等多种方式
- 详尽的预约数据:支持预约名单数据导出Excel,打印

![image](https://user-images.githubusercontent.com/96864248/189519239-7707dfcc-5fe8-4ad1-9e07-e7bf73adb076.png)
![image](https://user-images.githubusercontent.com/96864248/189519246-c5b61c34-958b-473a-b9ac-c3a2ff08fdb1.png)



## 技术运用
- 本项目使用微信小程序平台进行开发。
- 使用腾讯专门的小程序云开发技术,云资源包含云函数,数据库,带宽,存储空间,定时器等,资源配额价格低廉,无需域名和服务器即可搭建。
- 小程序本身的即用即走,适合小工具的使用场景,也适合快速开发迭代。
- 云开发技术采用腾讯内部链路,没有被黑客攻击的风险,安全性高且免维护。
- 资源承载力可根据业务发展需要随时弹性扩展。  



## 作者
- 如有疑问,欢迎骚扰联系我:开发交流,技术分享,问题答疑,功能建议收集,版本更新通知,安装部署协助,小程序开发定制等。
- 俺的微信: 
 ![image](https://user-images.githubusercontent.com/96864248/189519251-86ee2260-a55d-4158-b3ce-06c170f1ece4.png)




## 演示 
 ![image](https://user-images.githubusercontent.com/96864248/189519248-5532edd2-e763-40d6-9fea-c69edca87287.png)


## 安装

- 安装手册见源码包里的word文档

![image](https://user-images.githubusercontent.com/96864248/189519252-b69954c6-caf5-4800-9800-d4251ffa4011.png)
![image](https://user-images.githubusercontent.com/96864248/189519255-c82f58e7-f790-4f42-8ea2-9d44ecfcacc4.png)
![image](https://user-images.githubusercontent.com/96864248/189519258-0f46606e-35e2-4b4b-8760-1497419eac10.png)
![image](https://user-images.githubusercontent.com/96864248/189519261-db1daaa2-1433-4b65-b3c6-efabb62bf047.png)
![image](https://user-images.githubusercontent.com/96864248/189519265-24fd846c-466d-4257-b9c5-f5d0b4d00687.png)
![image](https://user-images.githubusercontent.com/96864248/189519268-784bd0f0-009e-446b-81ce-a6b83cf9bcff.png)
![image](https://user-images.githubusercontent.com/96864248/189519271-6e2a223e-8d88-43f8-aa30-eb2bc056274a.png)

![image](https://user-images.githubusercontent.com/96864248/189519273-4aa22512-69bc-4a02-9b35-59e2be029aa9.png)
![image](https://user-images.githubusercontent.com/96864248/189519278-64310e7e-321f-4f36-8a35-5918de0583fc.png)
![image](https://user-images.githubusercontent.com/96864248/189519281-da759fef-9404-402d-8ae8-0e8ef1cd4706.png)


## 截图
 

## 后台管理系统截图 
- 后台超级管理员默认账号:admin,密码123456,请登录后台后及时修改密码和创建普通管理员。

![image](https://user-images.githubusercontent.com/96864248/189519285-09317ce4-779a-4ffb-a26d-bfe9e947ffd4.png)

![image](https://user-images.githubusercontent.com/96864248/189519287-b4f08489-abe7-4395-84dd-0de6060d065b.png)
![image](https://user-images.githubusercontent.com/96864248/189519290-56b56e45-ac29-48b7-b3ab-2de853657f97.png)
![image](https://user-images.githubusercontent.com/96864248/189519293-dd9164cc-3235-42e0-98d9-aabbf0bafa99.png)
![image](https://user-images.githubusercontent.com/96864248/189519296-a6255dd9-80b0-4091-a08a-ec1ded16c2dd.png)

![image](https://user-images.githubusercontent.com/96864248/189519299-50e99c08-21e5-4587-ab3e-86feade044c3.png)
![image](https://user-images.githubusercontent.com/96864248/189519302-5ed8d472-8a6e-4b41-9b24-24ae94280d54.png)





================================================
FILE: cloudfunctions/mcloud/config/config.js
================================================
module.exports = {

	//### 环境相关 
	CLOUD_ID: 'init-5go8b8pdc98ea814', //你的云环境id   

	// ##################################################################   
	COLLECTION_PRFIX: 'bx_',

	IS_DEMO: false, //是否演示版 (后台不可操作提交动作)  
	// ##################################################################
	// #### 调试相关 
	TEST_MODE: false, // 测试模式 涉及小程序码生成路径, 用以下 TEST_TOKEN_ID openid.. 
	TEST_TOKEN_ID: 'oD58U5Ej-gK0BjqSspqjQEPgXuQQ',
 

	// #### 内容安全
	CLIENT_CHECK_CONTENT: false, //前台图片文字是否校验
	ADMIN_CHECK_CONTENT: false, //后台图片文字是否校验     

	// ### 后台业务相关
	ADMIN_LOGIN_EXPIRE: 86400, //管理员token过期时间 (秒) 
}

================================================
FILE: cloudfunctions/mcloud/config.json
================================================
{
	"permissions": {
		"openapi": ["wxacode.getUnlimited", "security.imgSecCheck", "security.msgSecCheck","serviceMarket.invokeService"]
	}
}

================================================
FILE: cloudfunctions/mcloud/framework/cloud/cloud_base.js
================================================
/**
 * Notes: 云初始化实例
 * Ver : CCMiniCloud Framework 2.2.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2020-09-05 04:00:00 
 */

const config = require('../../config/config.js');

/**
 * 获得云实例
 */
function getCloud() {
	const cloud = require('wx-server-sdk');
	cloud.init({
		env: config.CLOUD_ID
	});
	return cloud;
}

module.exports = {
	getCloud
}

================================================
FILE: cloudfunctions/mcloud/framework/cloud/cloud_util.js
================================================
/**
 * Notes: 云基本操作模块
 * Ver : CCMiniCloud Framework 2.3.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2020-09-05 04:00:00 
 */
const cloudBase = require('./cloud_base.js');

function log(method, err, level = 'error') {
	const cloud = cloudBase.getCloud();
	const log = cloud.logger();
	log.error({
		method: method,
		errCode: err.code,
		errMsg: err.message,
		errStack: err.stack
	});
}

async function getTempFileURLOne(fileID) {
	if (!fileID) return '';

	const cloud = cloudBase.getCloud();
	let result = await cloud.getTempFileURL({
		fileList: [fileID],
	})
	if (result && result.fileList && result.fileList[0] && result.fileList[0].tempFileURL)
		return result.fileList[0].tempFileURL;
	return '';
}

async function getTempFileURL(tempFileList, isValid = false) {
	if (!tempFileList || tempFileList.length == 0) return [];

	const cloud = cloudBase.getCloud();
	let result = await cloud.getTempFileURL({
		fileList: tempFileList,
	})
	console.log(result);

	let list = result.fileList;
	let outList = [];
	for (let i = 0; i < list.length; i++) {
		let pic = {};
		if (list[i].status == 0) {
			//获取到地址的
			pic.url = list[i].tempFileURL;
			pic.cloudId = list[i].fileID;
			outList.push(pic)
		} else {
			//未获取到地址的(已经转换过的)
			if (!isValid) {
				pic.url = list[i].fileID; // fileID为URL, tempFileURL为空
				pic.cloudId = list[i].fileID;
				outList.push(pic)
			}
		}
	}
	return outList;
}

async function handlerCloudFilesForForms(oldForms, newsForms) {
	let oldFiles = [];
	let newFiles = [];

	for (let k = 0; k < oldForms.length; k++) {
		if (oldForms[k].type == 'image')
			oldFiles = oldFiles.concat(oldForms[k].val);
		else if (oldForms[k].type == 'content') {
			let contentVal = oldForms[k].val;
			for (let n in contentVal) {
				if (contentVal[n].type == 'img')
					oldFiles.push(contentVal[n].val);
			}

		}
	}

	for (let j in newsForms) {
		if (newsForms[j].type == 'image')
			newFiles = newFiles.concat(newsForms[j].val);
		else if (newsForms[j].type == 'content') {
			let contentVal = newsForms[j].val;
			for (let m in contentVal) {
				if (contentVal[m].type == 'img')
					newFiles.push(contentVal[m].val);
			}

		}
	}

	await handlerCloudFiles(oldFiles, newFiles);
}

async function handlerCloudFiles(oldFiles, newFiles) {
	//if (oldFiles.length == 0 && newFiles.length == 0) return [];

	const cloud = cloudBase.getCloud();
	for (let i = 0; i < oldFiles.length; i++) {
		let isDel = true;
		for (let j = 0; j < newFiles.length; j++) {
			if (oldFiles[i] == newFiles[j]) {
				// 从旧文件数组里 找到 新组 还存在的文件 ,则不删除
				isDel = false;
				break;
			}
		}
		// 新组里不存在,直接删除
		if (isDel && oldFiles[i]) {
			let result = await cloud.deleteFile({
				fileList: [oldFiles[i]],
			});
			console.log(result);
		}

	}

	return newFiles;
}


async function handlerCloudFilesByRichEditor(oldFiles, newFiles) {
	const cloud = cloudBase.getCloud();
	for (let i = 0; i < oldFiles.length; i++) {
		let isDel = true;
		for (let j = 0; j < newFiles.length; j++) {
			if (oldFiles[i].type == 'img' && newFiles[j].type == 'img' && oldFiles[i].val == newFiles[j].val) {
				// 从旧文件数组里 找到 新组 还存在的图片文件, 保存cloudID
				//newFiles[j].cloudId = oldFiles[i].cloudId;
				isDel = false;
				break;
			}
		}
		// 新组里不存在,直接删除
		if (isDel && oldFiles[i].type == 'img' && oldFiles[i].val) {

			let result = await cloud.deleteFile({
				fileList: [oldFiles[i].val],
			});
		}

	}

	return newFiles;
}

async function deleteFiles(list) {
	if (!list) return;
	if (!Array.isArray(list)) list = [list];
	if (list.length == 0) return;

	const cloud = cloudBase.getCloud();
	await cloud.deleteFile({
		fileList: list,
	});
}

module.exports = {
	log,
	getTempFileURL,
	getTempFileURLOne,
	deleteFiles,
	handlerCloudFiles,
	handlerCloudFilesByRichEditor,
	handlerCloudFilesForForms
}

================================================
FILE: cloudfunctions/mcloud/framework/core/app_code.js
================================================
/**
 * Notes: 错误代码定义
 * Ver : CCMiniCloud Framework 2.4.1 ALL RIGHTS RESERVED BY Cclinux0730 (wechat)
 * Date: 2020-09-05 04:00:00 
 */
module.exports = {
	SUCC: 200,
	SVR: 500, // 服务器错误  
	LOGIC: 1600, //逻辑错误 
	DATA: 1301, // 数据校验错误 
	HEADER: 1302, // header 校验错误  


	//2000开始为业务错误代码,

	ADMIN_ERROR: 2401 //管理员错误
}

================================================
FILE: cloudfunctions/mcloud/framework/core/app_error.js
================================================
/**
 * Notes: 应用异常处理类
 * Ver : CCMiniCloud Framework 2.5.1 ALL RIGHTS RESERVED BY cClinux0730 (wechat)
 * Date: 2020-09-05 04:00:00 
 */


const appCode = require('./app_code.js');

class AppError extends Error {
    constructor(message, code = appCode.LOGIC) {
      super(message);  
	  this.name = 'AppError';  
	  this.code = code;
    }
  }

  module.exports = AppError;

================================================
FILE: cloudfunctions/mcloud/framework/core/app_other.js
================================================
/**
 * Notes: 云函数非标业务处理
 * Ver : CCMiniCloud Framework 2.6.1 ALL RIGHTS RESERVED BY ccLinux@qq.com
 * Date: 2021-10-21 04:00:00 
 */

function handlerOther(event) {
	let isOther = false;

	if (!event) return {
		isOther,
		eventX
	};

	// 公众号事件处理
	if (event['FromUserName'] && event['MsgType']) {
		console.log('公众号事件处理');
		let ret = {
			route: 'oa/serve',
			params: event
		}
		return {
			isOther: true,
			eventX: ret
		};
	}

	return {
		isOther,
		eventX: event
	};
}


module.exports = {
	handlerOther,
}

================================================
FILE: cloudfunctions/mcloud/framework/core/app_util.js
================================================
/**
 * Notes: 云函数业务主逻辑函数
 * Ver : CCMiniCloud Framework 2.7.1 ALL RIGHTS RESERVED BY cclinuX0730 (wechat)
 * Date: 2021-02-09 04:00:00 
 */

const appCode = require('./app_code.js');

function handlerBasic(code, msg = '', data = {}) {

	switch (code) {
		case appCode.SUCC:
			msg = (msg) ? msg + ':ok' : 'ok';
			break;
		case appCode.SVR:
			msg = '服务器繁忙,请稍后再试';
			break;
		case appCode.LOGIC:
			break;
		case appCode.DATA:
			break;

			/*
			default:
				msg = '服务器开小差了,请稍后再试';
				break;*/
	}

	return {
		code: code,
		msg: msg,
		data: data
	}

}

function handlerSvrErr(msg = '') {
	return handlerBasic(appCode.SVR, msg);
}

function handlerSucc(msg = '') {
	return handlerBasic(appCode.SUCC, msg);
}

function handlerAppErr(msg = '', code = appCode.LOGIC) {
	return handlerBasic(code, msg);
}


function handlerData(data, msg = '') {
	return handlerBasic(appCode.SUCC, msg, data);
}

module.exports = {
	handlerBasic,
	handlerData,
	handlerSucc,
	handlerSvrErr,
	handlerAppErr
}

================================================
FILE: cloudfunctions/mcloud/framework/core/application.js
================================================
/**
 * Notes: 云函数业务主逻辑
 * Ver : CCMiniCloud Framework 2.8.1 ALL RIGHTS RESERVED BY cclinUX0730 (wechat)
 * Date: 2020-09-05 04:00:00 
 */
const util = require('../utils/util.js');
const cloudBase = require('../cloud/cloud_base.js');
const timeUtil = require('../utils/time_util.js');
const appUtil = require('./app_util.js');
const appCode = require('./app_code.js');
const appOther = require('./app_other.js');
const config = require('../../config/config.js');
global.PID = 'unknown';

async function app(event, context) {

	// 非标业务处理
	let {
		eventX,
		isOther
	} = appOther.handlerOther(event);
	event = eventX;

	// 取得openid
	const cloud = cloudBase.getCloud();
	const wxContext = cloud.getWXContext();
	let r = '';
	let PID = '';
	try {

		if (!util.isDefined(event.route)) {
			showEvent(event);
			console.error('Route Not Defined');
			return appUtil.handlerSvrErr();
		}

		r = event.route.toLowerCase();
		if (!r.includes('/')) {
			showEvent(event);
			console.error('Route Format error[' + r + ']');
			return appUtil.handlerSvrErr();
		}

		PID = event.PID.trim();
		if (!PID) {
			showEvent(event);
			console.error('PID Is NULL]');
			return appUtil.handlerSvrErr();
		}
		global.PID = PID;

		// 路由不存在
		routes = require('project/' + PID + '/public/route.js');
		if (!util.isDefined(routes[r])) {
			showEvent(event);
			console.error('Route [' + r + '] Is Not Exist');
			return appUtil.handlerSvrErr();
		}

		let routesArr = routes[r].split('@');

		let controllerName = routesArr[0];
		let actionName = routesArr[1];

		// 事前处理
		if (actionName.includes('#')) {
			let actionNameArr = actionName.split('#');
			actionName = actionNameArr[0];
			if (actionNameArr[1] && config.IS_DEMO) {
				console.log('### APP Before = ' + actionNameArr[1]);
				return beforeApp(actionNameArr[1]);
			}
		}

		console.log('');
		console.log('');
		let time = timeUtil.time('Y-M-D h:m:s');
		let timeTicks = timeUtil.time();
		let openId = wxContext.OPENID;

		console.log('▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤');
		console.log(`【↘${time} ENV (${config.CLOUD_ID})】【Request Base↘↘↘】\n【↘Route =***${r}】\n【↘Controller = ${controllerName}】\n【↘Action = ${actionName}】\n【↘OPENID = ${openId}】\n【↘PID = ${global.PID}】`);

		// 测试模式
		if (config.TEST_MODE)
			openId = config.TEST_TOKEN_ID; 

		if (!openId) {
			console.error('OPENID is unfined');
			return appUtil.handlerSvrErr();
		}

		// 引入逻辑controller 
		controllerName = controllerName.toLowerCase().trim();
		const ControllerClass = require('project/'+PID +'/controller/' + controllerName + '.js');
		const controller = new ControllerClass(r, PID + '^^^' + openId, event);
 
		// 调用方法    
		await controller['initSetup']();
		let result = await controller[actionName]();

		// 返回值处理
		if (isOther) {
			// 非标处理
			return result;
		} else {
			if (!result)
				result = appUtil.handlerSucc(r); // 无数据返回
			else
				result = appUtil.handlerData(result, r); // 有数据返回
		}


		console.log('------');
		time = timeUtil.time('Y-M-D h:m:s');
		timeTicks = timeUtil.time() - timeTicks;
		console.log(`【${time}】【Return Base↗↗↗】\n【↗Route =***${r}】\n【↗Duration = ${timeTicks}ms】\n【↗↗OUT DATA】= `, result);
		console.log('▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦');
		console.log('');
		console.log('');

		return result;


	} catch (ex) {
		const log = cloud.logger();

		console.log('------');
		time = timeUtil.time('Y-M-D h:m:s');
		console.error(`【${time}】【Return Base↗↗↗】\n【↗Route = ${r}】\Exception MSG = ${ex.message}, CODE=${ex.code}`);

		// 系统级错误定位调试
		if (config.TEST_MODE && ex.name != 'AppError') throw ex;

		console.log('▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦');
		console.log('');
		console.log('');

		if (ex.name == 'AppError') {
			log.warn({
				route: r,
				errCode: ex.code,
				errMsg: ex.message
			});
			// 自定义error处理
			return appUtil.handlerAppErr(ex.message, ex.code);
		} else {
			//console.log(ex); 
			log.error({
				route: r,
				errCode: ex.code,
				errMsg: ex.message,
				errStack: ex.stack
			});


			// 系统error
			return appUtil.handlerSvrErr();
		}
	}
}

// 事前处理
function beforeApp(method) {
	switch (method) {
		case 'demo': {
			return appUtil.handlerAppErr('本系统仅为用户体验演示,后台提交的操作均不生效!如有需要请联系作者微信cclinux0730', appCode.LOGIC);
		}
	}
	console.error('事前处理, Method Not Find = ' + method);
}

// 展示当前输入数据
function showEvent(event) {
	console.log(event);
}

module.exports = {
	app
}

================================================
FILE: cloudfunctions/mcloud/framework/database/db_util.js
================================================
/**
 * Notes: 数据库基本操作
 * Ver : CCMiniCloud Framework 2.9.1 ALL RIGHTS RESERVED BY CClinux0730 (wechat)
 * Date: 2020-09-05 04:00:00 
 */

const util = require('../utils/util.js');
const dataUtil = require('../utils/data_util.js');

const cloudBase = require('../cloud/cloud_base.js');
const MAX_RECORD_SIZE = 1000;
const DEFAULT_RECORD_SIZE = 20;

const cloud = cloudBase.getCloud();
const db = cloud.database();
const dbCmd = db.command;
const dbAggr = dbCmd.aggregate;


// 获得一个命令操作
function getCmd() {
	return dbCmd;
}


async function insertBatch(collectionName, data, size = 1000) {

	let dataArr = dataUtil.spArr(data, size);
	for (let k = 0; k < dataArr.length; k++) {
		await db.collection(collectionName).add({
			data: dataArr[k]
		});
	}

	//return query._id;
}

async function insert(collectionName, data) {

	let query = await db.collection(collectionName).add({
		data
	});
	return query._id;
}

async function edit(collectionName, where, data) {

	let query = await db.collection(collectionName);

	// 查询条件
	if (util.isDefined(where)) {
		if (typeof (where) == 'string' || typeof (where) == 'number')
			query = await query.doc(where);
		else
			query = await query.where(fmtWhere(where));
	}

	query = await query.update({
		data
	});

	return query.stats.updated;
}

async function inc(collectionName, where, field, val = 1) {
	let query = await db.collection(collectionName);

	// 查询条件
	if (util.isDefined(where)) {
		if (typeof (where) == 'string' || typeof (where) == 'number')
			query = await query.doc(where);
		else
			query = await query.where(fmtWhere(where));
	}

	query = await query.update({
		data: {
			[field]: dbCmd.inc(val)
		}
	});

	return query.stats.updated;
}

async function mul(collectionName, where, field, val = 1) {
	let query = await db.collection(collectionName);

	// 查询条件
	if (util.isDefined(where)) {
		if (typeof (where) == 'string' || typeof (where) == 'number')
			query = await query.doc(where);
		else
			query = await query.where(fmtWhere(where));
	}

	query = await query.update({
		data: {
			[field]: dbCmd.mul(val)
		}
	});

	return query.stats.updated;
}

async function del(collectionName, where) {
	let query = await db.collection(collectionName);

	// 查询条件
	if (util.isDefined(where)) {
		if (typeof (where) == 'string' || typeof (where) == 'number')
			query = await query.doc(where);
		else
			query = await query.where(fmtWhere(where));
	}

	query = await query.remove();
	return query.stats.removed;
}

async function count(collectionName, where) {
	let query = await db.collection(collectionName);

	// 查询条件
	if (typeof (where) == 'string' || typeof (where) == 'number')
		query = await query.doc(where);
	else
		query = await query.where(fmtWhere(where));

	query = await query.count();
	return query.total;
}

async function distinct(collectionName, where, field) {
	let query = await db.collection(collectionName);
	query = await query.aggregate();

	// 查询条件
	query = await query.match(fmtWhere(where));

	query = await query.group({
		_id: null,
		'uniqueValues': dbAggr.addToSet('$' + field)

	}).end();

	if (query && query.list && query.list[0] && query.list[0]['uniqueValues']) {
		return query.list[0]['uniqueValues'];
	} else
		return [];
}

async function distinctCnt(collectionName, where, field) {
	let data = await distinct(collectionName, where, field);
	return data.length;
}

async function groupSum(collectionName, where, groupField, fields) {

	let query = await db.collection(collectionName);
	query = await query.aggregate();

	// 查询条件
	query = await query.match(fmtWhere(where));

	if (!Array.isArray(fields)) {
		fields = [fields];
	}
	let node = {};
	for (let k = 0; k < fields.length; k++) {
		node[fields[k]] = dbAggr.sum('$' + fields[k]);
	}

	query = await query.group({
		_id: {
			[groupField]: '$' + groupField
		},
		...node

	}).end();

	if (query && query.list) {
		let list = query.list;
		for (let k = 0; k < list.length; k++) {
			list[k][groupField] = list[k]['_id'][groupField];
			delete list[k]['_id'];
		}
		return list;
	} else
		return [];
}

async function groupCount(collectionName, where, groupField) {

	let query = await db.collection(collectionName);
	query = await query.aggregate();

	// 查询条件
	query = await query.match(fmtWhere(where));

	query = await query.group({
		_id: '$' + groupField,
		total: dbAggr.sum(1)

	}).end();

	if (query && query.list) {
		let list = query.list;
		let ret = {};
		for (let k = 0; k < list.length; k++) {
			ret[groupField + '_' + list[k]['_id']] = list[k].total;
		}
		return ret;
	} else
		return null;
}

async function sum(collectionName, where, field) {
	// TODO 可扩展为支持多个字段同时统计
	let query = await db.collection(collectionName);
	query = await query.aggregate();

	// 查询条件
	query = await query.match(fmtWhere(where));

	query = await query.group({
		_id: null,
		'summ': dbAggr.sum('$' + field)

	}).end();

	if (query && query.list && query.list[0] && query.list[0]['summ']) {
		return query.list[0]['summ'];
	} else
		return 0;
}

async function max(collectionName, where, field) {
	let query = await db.collection(collectionName);
	query = await query.aggregate();

	// 查询条件
	query = await query.match(fmtWhere(where));

	query = await query.group({
		_id: null,
		'maxx': dbAggr.max('$' + field)

	}).end();

	if (query && query.list && query.list[0] && query.list[0]['maxx']) {
		return query.list[0]['maxx'];
	} else
		return 0;
}

async function min(collectionName, where, field) {
	let query = await db.collection(collectionName);
	query = await query.aggregate();

	// 查询条件
	query = await query.match(fmtWhere(where));

	query = await query.group({
		_id: null,
		'minx': dbAggr.min('$' + field)

	}).end();

	if (query && query.list && query.list[0] && query.list[0]['minx']) {
		return query.list[0]['minx'];
	} else
		return 0;
}

async function clear(collectionName) {
	await db.collection(collectionName).where({
		_id: dbCmd.neq(1)
	}).remove().then(res => {

	});
}

async function isExistCollection(collectionName) {
	try {
		await getOne(collectionName, {});
		return true;

	} catch (err) {
		return false;
	}
}

async function createCollection(collectionName) {
	try {
		await db.createCollection(collectionName);

		console.log('>> Create New Collection [' + collectionName + '] Succ, OVER.');
		return true;

	} catch (err) {
		console.error('>> Create New Collection [' + collectionName + '] Failed, Code=' + err.errCode + '|' + err.errMsg);
		return false;
	}

}

async function rand(collectionName, where = {}, fields = '*', size = 1) {

	size = Number(size);

	if (size > MAX_RECORD_SIZE) size = MAX_RECORD_SIZE;


	let query = await db.collection(collectionName)
		.aggregate();

	if (util.isDefined(where))
		query = await query.match(fmtWhere(where));

	if (util.isDefined(fields) && fields != '*')
		query = await query.project(fmtFields(fields));


	query = await query.sample({
		size
	});

	query = await query.end();

	if (size == 1) {
		if (query.list.length == 1)
			return query.list[0];
		else
			return null;
	} else
		return query.list;

}

async function getListByArray(collectionName, arrField, where, fields, orderBy, page = 1, size = DEFAULT_RECORD_SIZE, isTotal = true, oldTotal = 0) {

	if (typeof (where) == 'string' || typeof (where) == 'number') {
		where = {
			_id: where,
		};
	}

	page = Number(page);
	size = Number(size);

	if (size > MAX_RECORD_SIZE) size = MAX_RECORD_SIZE;

	data = {
		page: page,
		size: size
	}

	let offset = 0; //记录偏移量 防止新增数据列表重复 

	// 计算总页数
	if (isTotal) {
		// 联表
		let queryCnt = await db.collection(collectionName)
			.aggregate();

		// 查询条件
		if (util.isDefined(where))
			queryCnt = await queryCnt.match(fmtWhere(where));

		let total = await queryCnt.count('total').end();
		if (!total.list.length)
			total = 0;
		else
			total = total.list[0].total;

		data.total = total;
		data.count = Math.ceil(total / size);

		if (page > 1 && oldTotal > 0) {
			offset = data.total - oldTotal
			if (offset < 0) offset = 0;
		}
	}

	// 拆分查询
	let query = await db.collection(collectionName)
		.aggregate()
		.unwind('$' + arrField);

	// 查询条件
	if (util.isDefined(where))
		query = await query.match(fmtWhere(where));

	// 取出特定字段
	if (util.isDefined(fields) && fields != '*')
		query = await query.project(fmtFields(fields));

	// 排序   
	if (util.isDefined(orderBy)) {
		query = await query.sort(fmtJoinSort(orderBy));
	}

	// 分页
	query = await query.skip((page - 1) * size + offset).limit(size);

	// 取数据
	query = await query.end();
	data.list = query.list;

	return data;
}

async function getListJoin(collectionName, joinParams, where, fields, orderBy, page = 1, size = DEFAULT_RECORD_SIZE, isTotal = true, oldTotal = 0, is2Many = false) {

	if (typeof (where) == 'string' || typeof (where) == 'number') {
		where = {
			_id: where,
		};
	}

	page = Number(page);
	size = Number(size);

	if (size > MAX_RECORD_SIZE) size = MAX_RECORD_SIZE;

	data = {
		page: page,
		size: size
	}

	let offset = 0; //记录偏移量 防止新增数据列表重复 

	// 计算总页数
	if (isTotal) {
		// 联表
		let queryCnt = await db.collection(collectionName)
			.aggregate()
			.lookup(joinParams);

		// 查询条件
		if (util.isDefined(where))
			queryCnt = await queryCnt.match(fmtWhere(where));

		let total = await queryCnt.count('total').end();
		if (!total.list.length)
			total = 0;
		else
			total = total.list[0].total;

		data.total = total;
		data.count = Math.ceil(total / size);

		if (page > 1 && oldTotal > 0) {
			offset = data.total - oldTotal
			if (offset < 0) offset = 0;
		}
	}

	// 联表
	let query = await db.collection(collectionName)
		.aggregate()
		.lookup(joinParams);

	/*
	query = await query.replaceRoot({
	newRoot: $.mergeObjects([ $.arrayElemAt(['$USER_DETAIL', 0]), '$$ROOT' ])
	})*/

	// 查询条件
	if (util.isDefined(where))
		query = await query.match(fmtWhere(where));

	// 取出特定字段
	if (util.isDefined(fields) && fields != '*')
		query = await query.project(fmtFields(fields));

	// 排序   
	if (util.isDefined(orderBy)) {
		query = await query.sort(fmtJoinSort(orderBy));
	}

	// 分页
	query = await query.skip((page - 1) * size + offset).limit(size);


	// 取数据
	query = await query.end();
	data.list = query.list;

	if (!is2Many) {
		for (let k = 0; k < data.list.length; k++) {
			if (util.isDefined(data.list[k][joinParams.as])) {
				if (Array.isArray(data.list[k][joinParams.as]) &&
					data.list[k][joinParams.as].length > 0)
					data.list[k][joinParams.as] = data.list[k][joinParams.as][0];
				else {
					data.list[k][joinParams.as] = {};
				}
			}
		}
	}

	return data;
}

async function getListJoinCount(collectionName, joinParams, where) {

	if (typeof (where) == 'string' || typeof (where) == 'number') {
		where = {
			_id: where,
		};
	}

	// 联表
	let queryCnt = await db.collection(collectionName)
		.aggregate()
		.lookup(joinParams);

	// 查询条件
	if (util.isDefined(where))
		queryCnt = await queryCnt.match(fmtWhere(where));

	let total = await queryCnt.count('total').end();
	if (!total.list.length)
		total = 0;
	else
		total = total.list[0].total;

	return total;

}

async function getList(collectionName, where, fields = '*', orderBy = {}, page = 1, size = DEFAULT_RECORD_SIZE, isTotal = true, oldTotal = 0) {
	page = Number(page);
	size = Number(size);

	if (size > MAX_RECORD_SIZE || size == 0) size = MAX_RECORD_SIZE;

	let data = {
		page: page,
		size: size
	}

	let offset = 0;
	// 计算总页数
	if (isTotal) {
		let total = await count(collectionName, where);
		data.total = total;
		data.count = Math.ceil(total / size);

		if (page > 1 && oldTotal > 0) {
			offset = data.total - oldTotal
			if (offset < 0) offset = 0;

		}
	}

	// 分页 
	let query = await db.collection(collectionName)
		.skip((page - 1) * size + offset)
		.limit(size);

	// 查询条件  
	if (util.isDefined(where) && where)
		query = await query.where(fmtWhere(where));

	// 取出特定字段
	if (util.isDefined(fields) && fields != '*')
		query = await query.field(fmtFields(fields));

	// 排序  
	if (util.isDefined(orderBy)) {
		query = await fmtOrderBy(query, orderBy);
	}

	// 取数据
	query = await query.get();

	data.list = query.data;

	return data;
}

async function getAllBig(collectionName, where, fields = '*', orderBy, size = MAX_RECORD_SIZE) {
	size = Number(size);
	if (size > MAX_RECORD_SIZE) size = MAX_RECORD_SIZE;

	// 计算总数
	let total = await await count(collectionName, where);

	// 页数
	let page = Math.ceil(total / size);

	let list = [];
	for (let i = 1; i <= page; i++) {
		let data = await getList(collectionName, where, fields, orderBy, i, size, false);

		if (data && data.list)
			list = list.concat(data.list);
	}

	return list;
}


async function getAll(collectionName, where, fields = '*', orderBy, size = MAX_RECORD_SIZE) {
	size = Number(size);
	if (size > MAX_RECORD_SIZE) size = MAX_RECORD_SIZE;

	let query = await db.collection(collectionName).limit(size);

	// 查询条件
	if (where)
		query = await query.where(fmtWhere(where));

	// 取出特定字段
	if (fields && fields != '*')
		query = await query.field(fmtFields(fields));

	// 排序 
	if (orderBy) {
		query = await fmtOrderBy(query, orderBy);
	}

	// 取数据
	query = await query.get();
	return query.data;
}

async function getAllByArray(collectionName, arrField, where, fields = '*', orderBy, size = MAX_RECORD_SIZE) {
	size = Number(size);
	if (size > MAX_RECORD_SIZE) size = MAX_RECORD_SIZE;

	// 拆分
	let query = await db.collection(collectionName).aggregate()
		.unwind('$' + arrField);

	// 查询条件
	if (util.isDefined(where))
		query = await query.match(fmtWhere(where));

	// 取出特定字段
	if (util.isDefined(fields) && fields != '*')
		query = await query.project(fmtFields(fields));

	// 排序 
	if (util.isDefined(orderBy)) {
		query = await query.sort(fmtJoinSort(orderBy));
	}

	// 取数据
	query = await query.limit(size).end();
	return query.list;
}

async function getOne(collectionName, where, fields = '*', orderBy = {}) {
	if (typeof (where) == 'string' || typeof (where) == 'number') {
		where = {
			_id: where
		};
	}

	// 查询条件 
	let query = await db.collection(collectionName)
		.where(fmtWhere(where))
		.limit(1);

	// 取出特定字段 
	if (fields != '*')
		query = await query.field(fmtFields(fields));

	// 排序
	if (orderBy)
		query = await fmtOrderBy(query, orderBy);

	// 取数据
	query = await query.get();

	if (query && query.data.length > 0) {
		return query.data[0];
	} else
		return null;
}

async function fmtOrderBy(query, orderBy) {
	for (let key in orderBy) {
		query = await query.orderBy(key, orderBy[key].toLowerCase())
	}
	return query;
}

function fmtJoinSort(sort) {
	for (let key in sort) {
		let v = sort[key];
		if (typeof (v) == 'string') {
			v = v.toLowerCase();
			if (v === 'asc')
				v = 1;
			else
				v = -1;
		}
		sort[key] = v;
	}
	return sort;
}


function fmtFields(fields) {
	if (typeof (fields) == 'string') {
		let obj = {};
		fields = fields.replace(/,/g, ",");
		let arr = fields.split(',');
		for (let i = 0; i < arr.length; i++) {
			if (arr[i].trim().length > 0)
				obj[arr[i].trim()] = true;
		}
		return obj;
	}

	return fields;
}


function fmtWhere(where) {
	if (util.isDefined(where.and) || util.isDefined(where.or)) {
		let whereEx = null;
		if (util.isDefined(where.and))
			whereEx = dbCmd.and(fmtWhere(where.and));

		if (util.isDefined(where.or)) {
			if (whereEx)
				whereEx = whereEx.and(dbCmd.or(fmtWhere(where.or)));
			else
				whereEx = dbCmd.or(fmtWhere(where.or));
		}
		//console.log(whereEx);
		return whereEx;
	}

	if (Array.isArray(where)) {
		for (let i = 0; i < where.length; i++)
			where[i] = fmtWhere(where[i]);
	}

	for (let key in where) {
		/* 判断是否有条件数组  
			INFO_EXPIRE_TIME: [
				['>=', 3], 
				['<=', 8],
				['<>', 5],
				['in', '6,7']
				],
		*/
		if (Array.isArray(where[key])) {
			let w = null;
			if (!Array.isArray(where[key][0]) && where[key][0].toLowerCase().trim() == 'between') {
				// 条件查询特殊处理
				where[key] = [
					['>=', where[key][1]],
					['<=', where[key][2]]
				];
			}

			if (!Array.isArray(where[key][0])) {
				// 一维数组 
				w = fmtWhereSimple(where[key]);
			} else {
				// 二维数组 
				for (let i = 0; i < where[key].length; i++) {
					let wTemp = fmtWhereSimple(where[key][i]);
					w = (w) ? w.and(wTemp) : wTemp;
				}
			}

			where[key] = w;

		}
	}
	return where;
}

function fmtWhereSimple(arr) {
	let sql = '';

	let op = arr[0].toLowerCase().trim();
	let val = arr[1];
	let where = {};
	switch (op) {
		case '=':
			where = dbCmd.eq(val);
			break;
		case '!=':
		case '<>':
			where = dbCmd.neq(val);
			break;
		case '<':
			where = dbCmd.lt(val);
			break;
		case '<=':
			where = dbCmd.lte(val);
			break;
		case '>':
			where = dbCmd.gt(val);
			break;
		case '>=':
			where = dbCmd.gte(val);
			break;
		case 'like':
			if (!util.isDefined(val) || !val) break; //无条件不搜索
			where = {
				$regex: val,
				$options: 'i'
			}
			break;
		case 'in':
			val = dataUtil.str2Arr(val);
			where = dbCmd.in(val);
			break;
		case 'not in':
			val = dataUtil.str2Arr(val);
			where = dbCmd.nin(val);
			break;
		default:
			console.error('error where oprt=' + op);
			break;
	}
	return where;
}

module.exports = {
	getCmd,

	insert,
	insertBatch,
	edit,
	del,

	count,
	inc,
	sum,
	groupCount,
	groupSum,
	distinct,
	distinctCnt,
	max,
	min,
	mul,

	isExistCollection,
	createCollection,
	clear,
	rand,
	getOne,
	getAll,
	getAllBig,

	getAllByArray,
	getList,
	getListJoin,
	getListJoinCount,
	getListByArray,
	MAX_RECORD_SIZE,
	DEFAULT_RECORD_SIZE
}

================================================
FILE: cloudfunctions/mcloud/framework/database/model.js
================================================
/**
 * Notes: 数据持久化与操作模块
 * Ver : CCMiniCloud Framework 2.11.1 ALL RIGHTS RESERVED BY ccLinux0730 (wechat)
 * Date: 2020-09-04 04:00:00 
 */

const dbUtil = require('./db_util.js');
const util = require('../utils/util.js');
const timeUtil = require('../utils/time_util.js');
const dataUtil = require('../utils/data_util.js');
const AppError = require('../core/app_error.js');
const cloudBase = require('../cloud/cloud_base.js');

class Model {

	static async getOne(where, fields = '*', orderBy = {}) {
		return await dbUtil.getOne(this.CL, where, fields, orderBy);
	}

	static async edit(where, data) {

		if (this.UPDATE_TIME) {
			let editField = this.FIELD_PREFIX + 'EDIT_TIME';
			if (!util.isDefined(data[editField])) data[editField] = timeUtil.time();
		}

		if (this.UPDATE_IP) {
			let cloud = cloudBase.getCloud();
			let ip = cloud.getWXContext().CLIENTIP;


			let editField = this.FIELD_PREFIX + 'EDIT_IP';
			if (!util.isDefined(data[editField])) data[editField] = ip;
		}

		data = this.clearEditData(data);

		return await dbUtil.edit(this.CL, where, data);
	}

	static async count(where) {
		return await dbUtil.count(this.CL, where);
	}

	static async insert(data) {
		// 自动ID
		if (this.ADD_ID) {
			let idField = this.FIELD_PREFIX + 'ID';
			if (!util.isDefined(data[idField])) data[idField] = dataUtil.makeID();
		}

		// 更新时间
		if (this.UPDATE_TIME) {
			let timestamp = timeUtil.time();
			let addField = this.FIELD_PREFIX + 'ADD_TIME';
			if (!util.isDefined(data[addField])) data[addField] = timestamp;

			let editField = this.FIELD_PREFIX + 'EDIT_TIME';
			if (!util.isDefined(data[editField])) data[editField] = timestamp;
		}

		// 更新IP
		if (this.UPDATE_IP) {
			let cloud = cloudBase.getCloud();
			let ip = cloud.getWXContext().CLIENTIP;

			let addField = this.FIELD_PREFIX + 'ADD_IP';
			if (!util.isDefined(data[addField])) data[addField] = ip;

			let editField = this.FIELD_PREFIX + 'EDIT_IP';
			if (!util.isDefined(data[editField])) data[editField] = ip;
		}

		// 数据清洗
		data = this.clearCreateData(data);

		return await dbUtil.insert(this.CL, data);
	}

	static async insertOrUpdate(where, data) {
		let model = await dbUtil.getOne(this.CL, where, '_id');
		if (model) {
			await this.edit(model._id, data);
			return model._id;
		} else {
			return await this.insert(Object.assign(data, where));
		}
	}

	static async insertBatch(data = [], size = 1000) {
		if (this.ADD_ID) {
			let idField = this.FIELD_PREFIX + 'ID';
			for (let k = 0; k < data.length; k++) {
				if (!util.isDefined(data[k][idField])) data[k][idField] = dataUtil.makeID();
			}
		}

		if (this.UPDATE_TIME) {
			let timestamp = timeUtil.time();
			let addField = this.FIELD_PREFIX + 'ADD_TIME';
			let editField = this.FIELD_PREFIX + 'EDIT_TIME';

			for (let k = 0; k < data.length; k++) {
				if (!util.isDefined(data[k][addField])) data[k][addField] = timestamp;
				if (!util.isDefined(data[k][editField])) data[k][editField] = timestamp;
			}

		}

		if (this.UPDATE_IP) {
			let cloud = cloudBase.getCloud();
			let ip = cloud.getWXContext().CLIENTIP;

			let addField = this.FIELD_PREFIX + 'ADD_IP';
			let editField = this.FIELD_PREFIX + 'EDIT_IP';

			for (let k = 0; k < data.length; k++) {
				if (!util.isDefined(data[k][addField])) data[k][addField] = ip;
				if (!util.isDefined(data[k][editField])) data[k][editField] = ip;
			}

		}

		for (let k = 0; k < data.length; k++) {
			data[k] = this.clearCreateData(data[k]);
		}

		return await dbUtil.insertBatch(this.CL, data, size);
	}

	static async del(where) {
		return await dbUtil.del(this.CL, where);
	}

	static async inc(where, field, val = 1) {
		return await dbUtil.inc(this.CL, where, field, val);
	}

	static async mul(where, field, val = 1) {
		return await dbUtil.mul(this.CL, where, field, val);
	}

	static async groupSum(where, groupField, field) {
		return await dbUtil.groupSum(this.CL, where, groupField, field);
	}

	static async groupCount(where, groupField) {
		return await dbUtil.groupCount(this.CL, where, groupField);
	}

	static async sum(where, field) {
		return await dbUtil.sum(this.CL, where, field);
	}

	static async distinct(where, field) {
		return await dbUtil.distinct(this.CL, where, field);
	}

	static async distinctCnt(where, field) {
		return await dbUtil.distinctCnt(this.CL, where, field);
	}

	static async max(where, field) {
		return await dbUtil.max(this.CL, where, field);
	}

	static async min(where, field) {
		return await dbUtil.min(this.CL, where, field);
	}

	static async clear() {
		return await dbUtil.clear(this.CL);
	}

	static async rand(where = {}, fields = '*', size = 1) {
		return await dbUtil.rand(this.CL, where, fields, size);
	}

	static async getAll(where, fields, orderBy, size = 100) {
		return await dbUtil.getAll(this.CL, where, fields, orderBy, size);
	}

	static async getAllBig(where, fields, orderBy, size = 1000) {
		return await dbUtil.getAllBig(this.CL, where, fields, orderBy, size);
	}

	static async getAllByArray(arrField, where, fields, orderBy, size = 100) {
		return await dbUtil.getAllByArray(this.CL, arrField, where, fields, orderBy, size);
	}

	static async getList(where, fields, orderBy, page, size, isTotal, oldTotal) {
		return await dbUtil.getList(this.CL, where, fields, orderBy, page, size, isTotal, oldTotal);
	}

	static async getListJoin(joinParams, where, fields, orderBy, page = 1, size, isTotal = true, oldTotal = 0, is2Many = false) {
		return await dbUtil.getListJoin(this.CL, joinParams, where, fields, orderBy, page, size, isTotal, oldTotal, is2Many);
	}

	static async getListJoinCount(joinParams, where) {
		return await dbUtil.getListJoinCount(this.CL, joinParams, where);
	}

	static async getListByArray(arrField, where, fields, orderBy, page = 1, size, isTotal = true, oldTotal = 0) {
		return await dbUtil.getListByArray(this.CL, arrField, where, fields, orderBy, page, size, isTotal, oldTotal);
	}

	static converDBStructure(stru) {
		let newStru = {};
		for (let key in stru) {
			newStru[key] = {};

			let arr = stru[key].split('|');
			for (let k = 0; k < arr.length; k++) {

				// 类型
				let val = arr[k].toLowerCase().trim();
				let orginal = arr[k];

				let type = 'string';
				if (val === 'float' || val === 'int' || val === 'string' || val === 'array' || val === 'object' || val === 'bool') {
					type = val;
					newStru[key]['type'] = type;
					continue;
				}

				// 是否必填
				if (val === 'true' || val === 'false') {
					let required = (val === 'true') ? true : false;
					newStru[key]['required'] = required;
					continue;
				}

				// 默认值
				if (val.startsWith('default=') && util.isDefined(newStru[key]['type'])) {
					let defVal = orginal.replace('default=', '');
					switch (newStru[key]['type']) {
						case 'int':
						case 'float':
							defVal = Number(defVal);
							break;
						case 'bool':
							defVal = defVal.toLowerCase();
							defVal = defVal == 'true' ? true : false;
							break;
						case 'object':
							defVal = defVal.replace('{', '');
							defVal = defVal.replace('}', '').trim();
							if (!defVal)
								defVal = {};
							else {
								let arr = defVal.split(',');
								defVal = {};
								for (let m = 0; m < arr.length; m++) {
									if (arr[m]) defVal[arr[m]] = '';
								}
							}

							break;
						case 'array':
							defVal = defVal.replace('[', '');
							defVal = defVal.replace(']', '').trim();
							if (!defVal)
								defVal = [];
							else
								defVal = defVal.split(',');
							break;
						default:
							defVal = String(defVal);
					}
					newStru[key]['defVal'] = defVal;
					continue;
				}

				// 注释
				if (val.startsWith('comment=')) {
					let comment = orginal.replace('comment=', '');
					newStru[key]['comment'] = comment;
					continue;
				}

				// 长度
				if (val.startsWith('length=')) {
					let length = orginal.replace('length=', '');
					length = Number(length);
					newStru[key]['length'] = length;
					continue;
				}

			}

			// 如果非必填字段没有默认值,则主动赋予一个
			if (!newStru[key]['required'] && !util.isDefined(newStru[key]['defVal'])) {
				let defVal = '';
				switch (newStru[key]['type']) {
					case 'bool':
						defVal = false;
						break;
					case 'int':
					case 'float':
						defVal = Number(0);
						break;
					case 'array':
						defVal = [];
						break;
					case 'object':
						defVal = {};
						break;
					default:
						defVal = String('');
				}
				newStru[key]['defVal'] = defVal;
			}

			// 如果没有长度
			if (!util.isDefined(newStru[key]['length'])) {
				let length = 20;
				switch (newStru[key]['type']) {
					case 'int':
					case 'float':
						length = 30;
						break;
					case 'array':
					case 'object':
						length = 1500;
						break;
					default:
						length = 300;
				}
				newStru[key]['length'] = length;
			}
		}
		return newStru;
	}

	static clearDirtyData(data) {
		for (let key in data) {
			if (!this.DB_STRUCTURE.hasOwnProperty(key) && !key.includes('.')) {
				console.error('脏数据:' + key);
				throw new AppError('脏数据');
			}
		}
	}

	static converDataType(data, dbStructure) {
		for (let key in data) {
			if (dbStructure.hasOwnProperty(key)) {
				let type = dbStructure[key].type.toLowerCase();
				// 字段类型转换
				switch (type) {
					case 'string':
						data[key] = String(data[key]);
						break;
					case 'bool':
						//data[key] = data[key];
						break;
					case 'float':
					case 'int':
						data[key] = Number(data[key]);
						break;
					case 'array':
						if (data[key].constructor != Array)
							data[key] = [];
						break;
					case 'object':
						if (data[key] === undefined || data[key] === null) {
							data[key] = {};
						}
						else if (data[key].constructor != Object)
							data[key] = {};

						//data[key] = dbUtil.getCmd().set(data[key]); // 指定字段等于一个对象 TODO
						break;
					default:
						console.error('字段类型错误:' + key + dbStructure[key].type);
						throw new AppError("字段类型错误");
				}
			}
		}

		return data;
	}


	static clearCreateData(data) {

		let dbStructure = Model.converDBStructure(this.DB_STRUCTURE);

		for (let key in dbStructure) {

			// 数据类型
			if (!util.isDefined(dbStructure[key].type)) {
				console.log('[数据填写错误1]字段类型未定义:' + key);
				throw new AppError('数据填写错误1');
			}

			// 是否定义必填 
			if (!util.isDefined(dbStructure[key].required)) {
				console.log('[数据填写错误2]required未定义:' + key);
				throw new AppError('数据填写错误2');
			}

			//  键值未赋值情况
			if (!data.hasOwnProperty(key)) {
				// 必填
				if (dbStructure[key].required) {
					if (util.isDefined(dbStructure[key].defVal))
						// 必填且有缺省值
						data[key] = dbStructure[key].defVal;
					else {
						// 必填且无缺省值 
						console.log('[数据填写错误3]字段未填写:' + key);
						throw new AppError('数据填写错误3 ' + key);
					}
				} else {
					// 非必填字段必须有缺省值
					if (!util.isDefined(dbStructure[key].defVal)) {
						console.log('[数据填写错误4]非必填字段必须有缺省值:' + key);
						throw new AppError('数据填写错误4');
					}
					data[key] = dbStructure[key].defVal;
				}
			}
		}

		// 去掉脏数据
		this.clearDirtyData(data, dbStructure);

		data = this.converDataType(data, dbStructure);

		return data;
	}

	static clearEditData(data) {
		let dbStructure = Model.converDBStructure(this.DB_STRUCTURE);

		// 去掉脏数据
		this.clearDirtyData(data, dbStructure);

		data = this.converDataType(data, dbStructure);

		return data;
	}

	static getDesc(enumName, val) {
		let baseEnum = this[enumName];
		let descEnum = this[enumName + '_DESC']
		let enumKey = '';

		// 先找出KEY
		for (let key in baseEnum) {
			if (baseEnum[key] === val) {
				enumKey = key;
				break;
			}
		}
		if (enumKey == '') return 'unknown';

		// 再从Desc里找出描述
		return descEnum[enumKey];
	}

}

// 集合名 collection
Model.CL = 'no-collection';

// 集合结构
Model.DB_STRUCTURE = 'no-dbStructure';

// 字段前缀
Model.FIELD_PREFIX = 'NO_';

// 开关自带更新ADD_TIME,EDIT_TIME,DEL_TIME的操作 
Model.UPDATE_TIME = true;

// 开关自带更新ADD_IP,EDIT_IP,DEL_IP的操作 
Model.UPDATE_IP = true;

// 开关添加ID
Model.ADD_ID = true;

// 默认排序
Model.ORDER_BY = {
	_id: 'desc'
}

module.exports = Model;

================================================
FILE: cloudfunctions/mcloud/framework/database/multi_model.js
================================================
/**
 * Notes: 实体基类 
 * Date: 2021-03-15 19:20:00 
 * Ver : CCMiniCloud Framework 2.12.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 */


const Model = require('./model.js');
const util = require('../utils/util.js');
const dataUtil = require('../utils/data_util.js');
const config = require('../../config/config.js');

class MultiModel extends Model {

	static C(cl) {
		return config.COLLECTION_PRFIX + cl;
	}

	static _getWhere(where, mustPID = true) {
		if (mustPID) {
			if (typeof (where) == 'string' || typeof (where) == 'number') {
				where = {
					_id: where,
					_pid: util.getProjectId()
				};
			} else
				where._pid = util.getProjectId();
		}
		return where;
	}

	static async getOneField(where, field, mustPID = true) {
		where = MultiModel._getWhere(where, mustPID);
		let one = await super.getOne(where, field);
		if (!one)
			return null;
		else {
			let ret = one[field];
			if (ret === undefined)
				return '';
			else
				return one[field];
		}
	}

	static async getOne(where, fields = '*', orderBy = {}, mustPID = true) {
		where = MultiModel._getWhere(where, mustPID);
		return await super.getOne(where, fields, orderBy);
	}

	static async edit(where, data, mustPID = true) {
		where = MultiModel._getWhere(where, mustPID);
		return await super.edit(where, data);
	}

	static async editForms(where, formName, objName, hasImageForms, mustPID = true) {
		where = MultiModel._getWhere(where, mustPID);

		let forms = await this.getOneField(where, formName, mustPID);
		if (!forms) return;


		// 赋值
		for (let k = 0; k < hasImageForms.length; k++) {
			for (let j in forms) {
				if ((forms[j].type == 'image' || forms[j].type == 'content')
					&& forms[j].mark == hasImageForms[k].mark
					&& forms[j].type == hasImageForms[k].type) {
					forms[j].val = hasImageForms[k].val;
					break;
				}
			}
		}

		let data = {
			[formName]: forms,
			[objName]: dataUtil.dbForms2Obj(forms)
		};

		return await super.edit(where, data);
	}

	static async count(where, mustPID = true) {
		where = MultiModel._getWhere(where, mustPID);
		return await super.count(where);
	}

	static async insert(data, mustPID = true) {
		if (mustPID) data._pid = util.getProjectId();
		return await super.insert(data);
	}

	static async insertBatch(data = [], size = 1000, mustPID = true) {
		if (mustPID) {
			for (let k = 0; k < data.length; k++) {
				data[k]._pid = util.getProjectId();
			}
		}

		return await super.insertBatch(data, size);
	}

	static async insertOrUpdate(where, data, mustPID = true) {
		if (mustPID) {
			where._pid = util.getProjectId();
		}
		return await super.insertOrUpdate(where, data);
	}

	static async del(where, mustPID = true) {
		where = MultiModel._getWhere(where, mustPID);
		return await super.del(where);
	}

	static async clear() {
		return await super.clear();
	}

	static async inc(where, field, val = 1, mustPID = true) {
		where = MultiModel._getWhere(where, mustPID);
		return await super.inc(where, field, val);
	}

	static async mul(where, field, val = 1, mustPID = true) {
		where = MultiModel._getWhere(where, mustPID);
		return await super.mul(where, field, val);
	}

	static async groupSum(where, groupField, field, mustPID = true) {
		if (mustPID) where._pid = util.getProjectId();
		return await super.groupSum(where, groupField, field);
	}

	static async groupCount(where, groupField, mustPID = true) {
		where = MultiModel._getWhere(where, mustPID);
		return await super.groupCount(where, groupField);
	}

	static async sum(where, field, mustPID = true) {
		where = MultiModel._getWhere(where, mustPID);
		return await super.sum(where, field);
	}

	static async distinct(where, field, mustPID = true) {
		where = MultiModel._getWhere(where, mustPID);
		return await super.distinct(where, field);
	}

	static async distinctCnt(where, field, mustPID = true) {
		where = MultiModel._getWhere(where, mustPID);
		return await super.distinctCnt(where, field);
	}

	static async max(where, field, mustPID = true) {
		where = MultiModel._getWhere(where, mustPID);
		return await super.max(where, field);
	}

	static async min(where, field, mustPID = true) {
		where = MultiModel._getWhere(where, mustPID);
		return await super.min(where, field);
	}

	static async rand(where, field, size = 1, mustPID = true) {
		where = MultiModel._getWhere(where, mustPID);
		return await super.rand(where, field, size);
	}

	static async getAll(where, fields, orderBy, size = 100, mustPID = true) {
		where = MultiModel._getWhere(where, mustPID);
		return await super.getAll(where, fields, orderBy, size);
	}

	static async getAllBig(where, fields, orderBy, size = 1000, mustPID = true) {
		where = MultiModel._getWhere(where, mustPID);
		return await super.getAllBig(where, fields, orderBy, size);
	}

	static async getAllByArray(arrField, where, fields, orderBy, size = 100, mustPID = true) {
		where = MultiModel._getWhere(where, mustPID);
		return await super.getAllByArray(arrField, where, fields, orderBy, size);
	}

	static async getList(where, fields, orderBy, page, size, isTotal, oldTotal, mustPID = true) {
		where = MultiModel._getWhere(where, mustPID);
		return await super.getList(where, fields, orderBy, page, size, isTotal, oldTotal);
	}

	static async getListJoin(joinParams, where, fields, orderBy, page = 1, size, isTotal = true, oldTotal = 0, is2Many = false, mustPID = true) {
		where = MultiModel._getWhere(where, mustPID);
		return await super.getListJoin(joinParams, where, fields, orderBy, page, size, isTotal, oldTotal, is2Many);
	}

	static async getListJoinCount(joinParams, where, mustPID = true) {
		where = MultiModel._getWhere(where, mustPID);
		return await super.getListJoinCount(joinParams, where);
	}

}

module.exports = MultiModel;

================================================
FILE: cloudfunctions/mcloud/framework/lib/faker_lib.js
================================================
/**
 * Notes: 测试数据构造类
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2021-05-26 14:00:00 
 */ 
const timeUtil = require('../utils/time_util.js');


/** 随机获取数据 */
function getRnd(arr, isNullable = false, ex = '') {

	if (isNullable) { // 允许为空
		let rd = getIntBetween(0, 1);
		if (rd % 2 == 0) return '';
	}


	if (!Array.isArray(arr)) {
		arr = arr.replace(/ /g, '').replace(/,/g, ',').split(',');
	}

	let exArr = ex.replace(/ /g, '').replace(/,/g, ',').split(',');
	let ret = '';

	let i = 0;
	while (true) {
		i++;
		if (i > 1000) return '';

		ret = arr[Math.floor((Math.random() * arr.length))];
		if (!exArr.includes(ret))
			return ret;
	}

}

/** 省份 */
function getProvince(isNullable = false, ex = '') {
	let data = ['北京市', '天津市', '河北省', '山西省',
		'内蒙古自治区', '辽宁省', '吉林省',
		'黑龙江省', '上海市', '江苏省',
		'浙江省', '安徽省', '福建省', '江西省',
		'山东省', '河南省', '湖北省', '湖南省',
		'广东省', '广西壮族自治区', '海南省',
		'重庆市', '四川省', '贵州省', '云南省',
		'西藏自治区', '陕西省', '甘肃省', '青海省',
		'宁夏回族自治区', '新疆维吾尔自治区',
		'香港特别行政区', '澳门特别行政区', '台湾省'
	];
	return getRnd(data, isNullable, ex);
}


function getProvinceAbbr(isNullable = false, ex = '') {
	let data = ['京', '皖', '渝', '闽',
		'甘', '粤', '桂', '黔',
		'琼', '冀', '豫', '黑',
		'鄂', '湘', '吉', '苏',
		'赣', '辽', '蒙', '宁',
		'青', '鲁', '晋', '陕',
		'沪', '川', '津', '藏',
		'新', '滇', '浙', '港',
		'澳', '台'
	];
	return getRnd(data, isNullable, ex);
}

/** 城市 */
function getCity(isNullable = false, ex = '') {
	let data = ['北京', '上海', '天津', '重庆',
		'哈尔滨', '长春', '沈阳', '呼和浩特',
		'石家庄', '乌鲁木齐', '兰州', '西宁',
		'西安', '银川', '郑州', '济南',
		'太原', '合肥', '武汉', '长沙',
		'南京', '成都', '贵阳', '昆明',
		'南宁', '拉萨', '杭州', '南昌',
		'广州', '福州', '海口',
		'香港', '澳门'
	];
	return getRnd(data, isNullable, ex);
}

/** 地区 */
function getArea(isNullable = false, ex = '') {
	let data = ['西夏区', '永川区', '秀英区', '高港区',
		'清城区', '兴山区', '锡山区', '清河区',
		'龙潭区', '华龙区', '海陵区', '滨城区',
		'东丽区', '高坪区', '沙湾区', '平山区',
		'城北区', '海港区', '沙市区', '双滦区',
		'长寿区', '山亭区', '南湖区', '浔阳区',
		'南长区', '友好区', '安次区', '翔安区',
		'沈河区', '魏都区', '西峰区', '萧山区',
		'金平区', '沈北新区', '孝南区', '上街区',
		'城东区', '牧野区', '大东区', '白云区',
		'花溪区', '吉利区', '新城区', '怀柔区',
		'六枝特区', '涪城区', '清浦区', '南溪区',
		'淄川区', '高明区', '金水区', '中原区',
		'高新开发区', '经济开发新区', '新区'
	];
	return getRnd(data, isNullable, ex);
}

/** 街道 */
function getStreet(isNullable = false, ex = '') {
	let data = '朱雀大街,太乙路,太白路,太华路,长乐坊,长樱路,案板街,竹笆市,骡马市,东木头市,西木头市,安仁坊,端履门,德福巷,洒金桥,冰窖巷,菊花园,下马陵,粉巷,索罗巷,后宰门,书院门,炭市街,马厂子,景龙池,甜水井,柏树林,桃花坞,人民路,解放路,黄河路,长江路,中山路,抚顺街,天津街,上海路,胜利路,西安路,长春路,太原街,沈阳路,鞍山路,五四路,唐山街,武汉街,延安路,朝阳街,鲁迅路,八一路,东北路,华南路,华北路,山东路,松江路,东方路,南沙街';
	return getRnd(data, isNullable, ex);
}

/**  门牌地址 */
function getAddress() {
	return getProvince() + '' + getCity() + '市' + getArea() + '' + getStreet() + getIntBetween(1, 100) + '号';
}

/** 国家 */
function getCountry(isNullable = false, ex = '') {
	let data = ['阿富汗', '阿拉斯加', '阿尔巴尼亚', '阿尔及利亚',
		'安道尔', '安哥拉', '安圭拉岛英', '安提瓜和巴布达',
		'阿根廷', '亚美尼亚', '阿鲁巴岛', '阿森松', '澳大利亚',
		'奥地利', '阿塞拜疆', '巴林', '孟加拉国', '巴巴多斯',
		'白俄罗斯', '比利时', '伯利兹', '贝宁', '百慕大群岛',
		'不丹', '玻利维亚', '波斯尼亚和黑塞哥维那', '博茨瓦纳',
		'巴西', '保加利亚', '布基纳法索', '布隆迪', '喀麦隆',
		'加拿大', '加那利群岛', '佛得角', '开曼群岛', '中非',
		'乍得', '智利', '圣诞岛', '科科斯岛', '哥伦比亚',
		'巴哈马国', '多米尼克国', '科摩罗', '刚果', '科克群岛',
		'哥斯达黎加', '克罗地亚', '古巴', '塞浦路斯', '捷克',
		'丹麦', '迪戈加西亚岛', '吉布提', '多米尼加共和国',
		'厄瓜多尔', '埃及', '萨尔瓦多', '赤道几内亚',
		'厄立特里亚', '爱沙尼亚', '埃塞俄比亚', '福克兰群岛',
		'法罗群岛', '斐济', '芬兰', '法国', '法属圭亚那',
		'法属波里尼西亚', '加蓬', '冈比亚', '格鲁吉亚', '德国',
		'加纳', '直布罗陀', '希腊', '格陵兰岛', '格林纳达',
		'瓜德罗普岛', '关岛', '危地马拉', '几内亚', '几内亚比绍',
		'圭亚那', '海地', '夏威夷', '洪都拉斯', '匈牙利', '冰岛',
		'印度', '印度尼西亚', '伊郎', '伊拉克', '爱尔兰', '以色列',
		'意大利', '科特迪瓦', '牙买加', '日本', '约旦', '柬埔塞',
		'哈萨克斯坦', '肯尼亚', '基里巴斯', '朝鲜', '韩国', '科威特',
		'吉尔吉斯斯坦', '老挝', '拉脱维亚', '黎巴嫩', '莱索托',
		'利比里亚', '利比亚', '列支敦士登', '立陶宛', '卢森堡',
		'马其顿', '马达加斯加', '马拉维', '马来西亚', '马尔代夫',
		'马里', '马耳他', '马里亚纳群岛', '马绍尔群岛', '马提尼克',
		'毛里塔尼亚', '毛里求斯', '马约特岛', '墨西哥', '密克罗尼西亚',
		'中途岛', '摩尔多瓦', '摩纳哥', '蒙古', '蒙特塞拉特岛',
		'摩洛哥', '莫桑比克', '缅甸', '纳米比亚', '瑙鲁', '尼泊尔',
		'荷兰', '荷属安的列斯群岛', '新喀里多尼亚群岛', '新西兰',
		'尼加拉瓜', '尼日尔', '尼日利亚', '纽埃岛', '诺福克岛',
		'挪威', '阿曼', '帕劳', '巴拿马', '巴布亚新几内亚', '巴拉圭',
		'秘鲁', '菲律宾', '波兰', '葡萄牙', '巴基斯坦', '波多黎各',
		'卡塔尔', '留尼汪岛', '罗马尼亚', '俄罗斯', '卢旺达',
		'东萨摩亚', '西萨摩亚', '圣马力诺', '圣皮埃尔岛及密克隆岛',
		'圣多美和普林西比', '沙特阿拉伯', '塞内加尔', '塞舌尔',
		'新加坡', '斯洛伐克', '斯洛文尼亚', '所罗门群岛', '索马里',
		'南非', '西班牙', '斯里兰卡', '圣克里斯托弗和尼维斯',
		'圣赫勒拿', '圣卢西亚', '圣文森特岛', '苏丹', '苏里南',
		'斯威士兰', '瑞典', '瑞士', '叙利亚', '塔吉克斯坦', '坦桑尼亚',
		'泰国', '阿拉伯联合酋长国', '多哥', '托克劳群岛', '汤加',
		'特立尼达和多巴哥', '突尼斯', '土耳其', '土库曼斯坦',
		'特克斯和凯科斯群岛(', '图瓦卢', '美国', '乌干达', '乌克兰',
		'英国', '乌拉圭', '乌兹别克斯坦', '瓦努阿图', '梵蒂冈',
		'委内瑞拉', '越南', '维尔京群岛', '维尔京群岛和圣罗克伊',
		'威克岛', '瓦里斯和富士那群岛', '西撒哈拉', '也门', '南斯拉夫',
		'扎伊尔', '赞比亚', '桑给巴尔', '津巴布韦', '中华人民共和国', '中国'
	];
	return getRnd(data, isNullable, ex);
}


/** 公司简称 */
function getCompanyPrefix(isNullable = false, ex = '') {
	let data = ['超艺', '和泰', '九方', '鑫博腾飞', '戴硕电子',
		'济南亿次元', '海创', '创联世纪', '凌云', '泰麒麟',
		'彩虹', '兰金电子', '晖来计算机', '天益', '恒聪百汇',
		'菊风公司', '惠派国际公司', '创汇', '思优', '时空盒数字',
		'易动力', '飞海科技', '华泰通安', '盟新', '商软冠联',
		'图龙信息', '易动力', '华远软件', '创亿', '时刻',
		'开发区世创', '明腾', '良诺', '天开', '毕博诚', '快讯',
		'凌颖信息', '黄石金承', '恩悌', '雨林木风计算机',
		'双敏电子', '维旺明', '网新恒天', '数字100', '飞利信',
		'立信电子', '联通时科', '中建创业', '新格林耐特',
		'新宇龙信息', '浙大万朋', 'MBP软件', '昂歌信息',
		'万迅电脑', '方正科技', '联软', '七喜', '南康', '银嘉',
		'巨奥', '佳禾', '国讯', '信诚致远', '浦华众城', '迪摩',
		'太极', '群英', '合联电子', '同兴万点', '襄樊地球村',
		'精芯', '艾提科信', '昊嘉', '鸿睿思博', '四通', '富罳',
		'商软冠联', '诺依曼软件', '东方峻景', '华成育卓', '趋势',
		'维涛', '通际名联'
	];
	return getRnd(data, isNullable, ex);
}

/** 公司类型 */
function getCompanyType(isNullable = false, ex = '') {
	let data = ['科技', '网络', '信息', '传媒', '集团', '控股', '投资', '制造'];
	return getRnd(data, isNullable, ex);
}

/** 公司名 */
function getCompany(isNullable = false, ex = '') {
	if (getNullable(isNullable)) return '';

	return getCompanyPrefix(false, ex) + getCompanyType() + '有限公司';
}

/** 内容 */
function getContent(size = 1, isNullable = false, ex = '') {
	if (getNullable(isNullable)) return '';

	let data = [
		'燕舞,燕舞,一曲歌来一片情。',
		'康师傅方便面,好吃看得见。',
		'不要太潇洒!',
		'让一亿人先聪明起来。',
		'共创美的前程,共度美的人生。',
		'省优,部优,葛优?',
		'喝孔府宴酒,做天下文章。',
		'健康成就未来。',
		'牙好,胃口就好,身体倍儿棒,吃嘛嘛香。',
		'永远的绿色,永远的秦池。',
		'坐红旗车,走中国路。',
		'要想皮肤好,早晚用大宝。',
		'孔府家酒,叫人想家。',
		'补钙新观念,吸收是要害。',
		'喝汇源果汁,走健康之路。',
		'爱的就是你!',
		'一种可以世袭的古典浪漫',
		'实力创造价值',
		'爱生活,爱拉芳!',
		'人类失去联想,世界将会怎样?',
		'做女人挺好!',
		'世界在你眼中?',
		'今天你有否亿唐?',
		'只溶在口,不溶在手。',
		'三千烦恼丝,健康新开始。',
		'维维豆奶,欢乐开怀。',
		'我们的光彩来自你的风采。',
		'钻石恒久远,一颗永流传。',
		'放我的真心在你的手心。',
		'小身材,大味道。',
		'牛奶香浓,丝般感受。',
		'聆听并不代表沉默,有时安静也是一种力量。',
		'滴滴香浓,意犹未尽。',
		'水晶之恋,一生不变。',
		'中国移动通信,沟通从心开始!',
		'网易,网聚人的力量!',
		'科技以人为本,诺基亚',
		'我们一直在努力!',
		'阳光总在风雨后',
		'男人对西服的要求,就是女人对男人的要求',
		'晚报,不晚报',
		'原来生活可以更美的',
		'明天的明天,你还会送我“水晶之恋”吗?',
		'卫浴出出进进的快感',
		'有家就有联合利华',
		'减脂减肥,其实是一种生活态度',
		'人头马一开,好事自然来。',
		'假如五指一样长,怎能满足用户不同需求?',
		'新飞广告做的好,不好新飞冰箱好',
		'传奇品质,百年张裕',
		'李宁:把出色留给自己',
		'一旦拥有,别无选择',
		'科技让你更轻松',
		'情系中国结,联通四海心',
		'海尔,中国造',
		'SOHU:足迹生活每一天',
		'果冻我要喜之郎',
		'国宝大熊猫,心纯天自高',
		'世界因为不同',
		'放低偏见,你会有出色发现!',
		'Just',
		'创意似金,敬业如牛',
		'不要让男人一手把握',
		'如同情人的手',
		'金窝银窝,不如自己的安乐窝。',
		'没有什么大不了的',
		'时间因我存在',
		'只要有梦想',
		'南方周末',
		'时间改变一切',
		'地球人都知道了',
		'众里寻他千百度,想要几度就几度',
		'您身边的银行,可信赖的银行',
		'三叶钢琴:学琴的孩子不会变坏',
		'柯达:串起生活每一刻',
		'大众甲克虫汽车:想想还是小的好',
		'一直被模拟,从未被超越',
		'幸福生活',
		'朗讯的创造力科技的原动力',
		'事事因你而出色',
		'运动之美,世界共享',
		'鹤舞白沙',
		'想知道“清嘴”的味道吗?',
		'弹指一挥间,世界皆互联',
		'更多选择、更多欢笑',
		'方太,让家的感觉更好',
		'世上仅此一件,今生与你结缘!',
		'白里透红与众不同',
		'没有蛀牙-佳洁士',
		'有线的价值',
		'享受快乐科技',
		'四海一家的解决之道',
		'娃哈哈纯净水:爱你等于爱自己',
		'农民山泉:有点甜',
		'博大精深,西门子',
		'一切尽在把握',
		'声声百思特,遥遥两相知',
		'一呼天下应',
		'让我们做得更好!',
		'暖和亲情,金龙鱼的大家庭。',
		'自然最健康,绿色好心情',
		'支起网络世界',
		'立邦漆:处处放光彩!',
		'fm365:真情互动!',
		'庄重一生,吉祥一生。',
		'人人都为礼品愁,我送北极海狗油。',
		'假如说人生的离合是一场戏,那么百年的好合更是早有安排!',
		'一品黄山天高云淡',
		'上上下下的享受!',
		'我是、我行、我素',
		'让无力者有力,让悲观者前行',
		'金利来—-男人的世界!',
		'百衣百顺',
		'聪明何必绝顶,慧根长留',
		'水往高处流',
		'大石化小,小石化了!',
		'“闲”妻良母',
		'“口服”,“心服”!',
		'盛满青春的秘密!',
		'三十六计走为上',
		'为了她的节日,献上您纯金般的心!',
		'用我们的钓线,你可以在鱼儿发现你之前先找到它',
		'生活就是一场运动,喝下它。',
		'选择维聚阿尔,已经表明你心明眼亮。',
		'佳能,我们看得见你想表达什么。',
		'天天都是春天',
		'假如你不来,广告明星就是他',
		'享受黑夜中偷拍的快感!',
		'彩信发送动人一刻',
		'灵感点亮生活!',
		'聪明演绎,无处不在!',
		'事业我一定争取,对你我从未放弃!',
		'波导手机,手机中的战斗机',
		'鄂尔多斯羊绒衫暖和全世界',
		'洁婷245再大的动作也不要紧',
		'做光明的牛,产光明的奶',
		'假如你的汽车会游泳的话,请照直开,不必刹车。',
		'永远要让驾驶执照比你自己先到期。',
		'请记住,上帝并不是十全十美的,它给汽车预备了备件,而人没有。',
		'小别意酸酸,欢聚心甜甜。',
		'除钞票外,承印一切。',
		'更多欢乐,更多选择',
		'美由你做主',
		'由我天地宽',
		'Sun是太阳,Java是月亮。',
		'不断创新,因为专心',
		'趁早下『斑』,请勿『痘』留。',
		'创新就是生活',
		'有一个漂亮的地方,万科四季花城',
		'建筑无限生活',
		'臭名远扬,香飘万里',
		'尝尝欢笑,经常麦当劳',
		'深入成就深度',
		'出色湖南,红网了然!',
		'因为网络,地球如村!',
		'一种质感',
		'恒久期盼',
		'繁荣民族文化',
		'不信,死给你看!',
		'天生的,强生的',
		'雪津啤酒,真情的味道!',
		'听世界,打天下',
		'雅芳比女人更了解女人',
		'Sun是太阳,Java是月亮。',
		'中国网通',
		'无线你的无限',
		'家有三洋,冬暖夏凉',
		'倾诉冬日暖语',
		'谁让我心动?',
		'灵活,让篮球场不再是一个平面',
		'别吻我,我怕修。',
		'一呼四应!',
		'无所不包!',
		'当之无愧',
		'以帽取人!',
		'一毛不拔!',
		'自讨苦吃!',
		'成功与科技共辉映',
		'没有最',
	];

	if (size == 1)
		return getRnd(data, false, ex);
	else {
		ret = '';
		for (let i = 0; i < size; i++) {
			ret += getRnd(data, false, ex) + ', ';
		}
		return ret;
	}
}

/** 获得一句话 */
function getWord(isNullable = false, ex = '') {
	if (getNullable(isNullable)) return '';

	let ret = getContent(1, false, ex);
	ret = ret.replace('。', '').replace('!', '').replace('?', '').replace('“', '”').replace(':', '');
	return ret;
}

/** 星期 */
function getWeek(isNullable = false, ex = '') {
	let data = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
	return getRnd(data, isNullable, ex);
}

/** 月份 */
function getMonth(isNullable = false, ex = '') {
	let data = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];
	return getRnd(data, isNullable, ex);
}

/** 获得姓名 */
function getFirstName(isNullable = false, ex = '') {
	let data = ['李', '王', '张', '刘', '陈', '杨', '赵', '黄', '周', '吴',
		'徐', '孙', '胡', '朱', '高', '林', '何', '郭', '马', '罗',
		'梁', '宋', '郑', '谢', '韩', '唐', '冯', '于', '董', '萧',
		'程', '曹', '袁', '邓', '许', '傅', '沉', '曾', '彭', '吕',
		'苏', '卢', '蒋', '蔡', '贾', '丁', '林', '薛', '叶', '阎',
		'余', '潘', '杜', '戴', '夏', '钟', '汪', '田', '任', '姜',
		'范', '方', '石', '姚', '谭', '廖', '邹', '熊', '金', '陆',
		'郝', '孔', '白', '崔', '康', '毛', '邱', '秦', '江', '史',
		'顾', '侯', '邵', '孟', '龙', '万', '段', '雷', '钱', '汤',
		'尹', '黎', '易', '常', '武', '乔', '贺', '赖', '龚', '文',
		'庞', '樊', '兰', '殷', '施', '陶', '洪', '翟', '安', '颜',
		'倪', '严', '牛', '温', '芦', '季', '俞', '章', '鲁', '葛',
		'伍', '韦', '申', '尤', '毕', '聂', '丛', '焦', '向', '柳',
		'邢', '路', '岳', '齐', '沿', '梅', '莫', '庄', '辛', '管',
		'祝', '左', '涂', '谷', '祁', '时', '舒', '耿', '牟', '卜',
		'路', '詹', '关', '苗', '凌', '费', '纪', '靳', '盛', '童',
		'欧', '甄', '项', '曲', '成', '游', '阳', '裴', '席', '卫',
		'查', '屈', '鲍', '位', '覃', '霍', '翁', '隋', '植', '甘',
		'景', '薄', '单', '包', '司', '柏', '宁', '柯', '阮', '桂',
		'闵', '欧阳', '解', '强', '柴', '华', '车', '冉', '房', '边',
		'辜', '吉', '饶', '刁', '瞿', '戚', '丘', '古', '米', '池',
		'滕', '晋', '苑', '邬', '臧', '畅', '宫', '来', '嵺', '苟',
		'全', '褚', '廉', '简', '娄', '盖', '符', '奚', '木', '穆',
		'党', '燕', '郎', '邸', '冀', '谈', '姬', '屠', '连', '郜',
		'晏', '栾', '郁', '商', '蒙', '计', '喻', '揭', '窦', '迟',
		'宇', '敖', '糜', '鄢', '冷', '卓', '花', '仇', '艾', '蓝',
		'都', '巩', '稽', '井', '练', '仲', '乐', '虞', '卞', '封',
		'竺', '冼', '原', '官', '衣', '楚', '佟', '栗', '匡', '宗',
		'应', '台', '巫', '鞠', '僧', '桑', '荆', '谌', '银', '扬',
		'明', '沙', '薄', '伏', '岑', '习', '胥', '保', '和', '蔺'
	];
	return getRnd(data, isNullable, ex);
}


/** 女生名 */
function getFemaleName(isNullable = false, ex = '') {
	if (getNullable(isNullable)) return '';

	let data = ['芳', '娜', '敏', '静', '敏静', '秀英', '丽', '洋', '艳', '娟',
		'文娟', '君', '文君', '珺', '霞', '明霞', '秀兰', '燕', '芬', '桂芬',
		'玲', '桂英', '丹', '萍', '华', '红', '玉兰', '桂兰', '英', '梅',
		'莉', '秀珍', '雪', '依琳', '旭', '宁', '婷', '馨予', '玉珍', '凤英',
		'晶', '欢', '玉英', '颖', '红梅', '佳', '倩', '琴', '兰英', '云',
		'洁', '爱华', '淑珍', '春梅', '海燕', '晨', '冬梅', '秀荣', '瑞', '桂珍',
		'莹', '秀云', '桂荣', '秀梅', '丽娟', '婷婷', '玉华', '琳', '雪梅', '淑兰',
		'丽丽', '玉', '秀芳', '欣', '淑英', '桂芳', '丽华', '丹丹', '桂香', '淑华',
		'秀华', '桂芝', '小红', '金凤', '文', '利', '楠', '红霞', '瑜', '桂花',
		'璐', '凤兰', '腊梅', '瑶', '嘉', '怡', '冰冰', '玉梅', '慧', '婕'
	];
	return getFirstName(false, ex) + getRnd(data, false, ex);
}

/** 男生名 */
function getMaleName(isNullable = false, ex = '') {
	if (getNullable(isNullable)) return '';

	let data = ['伟', '强', '磊', '洋', '勇', '军', '杰', '涛', '超', '明',
		'刚', '平', '辉', '鹏', '华', '飞', '鑫', '波', '斌', '宇',
		'浩', '凯', '健', '俊', '帆', '帅', '旭', '宁', '龙', '林',
		'欢', '阳', '建华', '亮', '成', '畅', '建', '峰', '建国', '建军',
		'晨', '瑞', '志强', '兵', '雷', '东', '欣', '博', '彬', '坤',
		'全安', '荣', '岩', '杨', '文', '利', '楠', '建平', '嘉俊', '晧',
		'建明', '子安', '新华', '鹏程', '学明', '博涛', '捷', '文彬', '楼', '鹰',
		'松', '伦', '超', '钟', '瑜', '振国', '洪', '毅', '昱然', '哲',
		'翔', '翼', '祥', '国庆', '哲彦', '正诚', '正豪', '正平', '正业', '志诚',
		'志新', '志勇', '志明', '志强', '志文', '致远', '智明', '智勇', '智敏', '智渊'
	];
	return getFirstName(false, ex) + getRnd(data, false, ex);
}

/** 随机获得姓名 */
function getName(isNullable = false, ex = '') {
	if (getNullable(isNullable)) return '';

	let rd = Math.round(Math.random());
	return (rd % 2 == 0) ? getFemaleName(false, ex) : getMaleName(false, ex);
}

/** 身份证号码 */
function getIdCard(birthday = '', isNullable = false) {
	if (getNullable(isNullable)) return '';

	let coefficientArray = ["7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2"]; // 加权因子
	let lastNumberArray = ["1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"]; // 校验码
	let address = "420101"; // 住址

	if (!birthday)
		birthday = "19810101"; // 生日

	let s = Math.floor(Math.random() * 10).toString() + Math.floor(Math.random() * 10).toString() + Math.floor(Math.random() * 10).toString();
	let array = (address + birthday + s).split("");
	let total = 0;
	for (i in array) {
		total = total + parseInt(array[i]) * parseInt(coefficientArray[i]);
	}
	let lastNumber = lastNumberArray[parseInt(total % 11)];
	let str = address + birthday + s + lastNumber;
	return str;

}

/** 手机号码 */
function getMobile(isNullable = false, ex = '') {

	if (getNullable(isNullable)) return '';

	let 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'];

	return getRnd(data, false, ex) + getInt(8);
}

/** 电话号码 */
function getPhone(isNullable = false, ex = '') {

	if (getNullable(isNullable)) return '';

	let data = ['010', '021', '022', '023', '020', '024', '025', '027', '028', '029', '0755', '0731', '0769'];

	return getRnd(data, false, ex) + '-' + getInt(8);
}

/** 常用英文单词 */
function getEnWord(isNullable = false, ex = '') {
	let 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';

	return getRnd(data, isNullable, ex);
}

/** 常用域名 */
function getDomain(isNullable = false, ex = '') {

	if (getNullable(isNullable)) return '';

	let data = 'com,net,org,cn,hk,us,uk,jp,kr';

	return '.' + getRnd(data, false, ex);
}

/** 常用邮箱 */
function getEmail(isNullable = false, ex = '') {
	if (getNullable(isNullable)) return '';

	let 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';

	return getEnWord() + '@' + getRnd(data, false, ex);
}

/** 获取时间戳 step 秒 */
function getTimestamp(step = 0) {
	return timeUtil.time() + step * 1000;
}

/**
 * 以当天为基点,获取随机时间戳,默认为当天
 * @param {*} min  起始天
 * @param {*} max  终止天
 */
function getAddTimestamp(min = 0, max = 1) {
	let now = timeUtil.timestamp2Time(timeUtil.time(), 'Y-M-D'); //转为当天0点
	now = timeUtil.time2Timestamp(now);
	return now + getIntBetween(min * 86400 * 1000, max * 86400 * 1000);
}

/** 生日 */
function getDate(start = 1900, end = 2020) {

	start = start + '-01-01 00:00:00';
	start = timeUtil.time2Timestamp(start);

	end = end + '-12-31 23:59:59';
	end = timeUtil.time2Timestamp(end);

	let time = getIntBetween(start, end);

	return timeUtil.timestamp2Time(time, 'Y-M-D');
}

/** 整数 */
function getInt(size) {
	let t = '';
	for (var i = 0; i < size; i++) {
		t += Math.floor(Math.random() * 10);
	}
	return t;
}

/** 随机数组 */
function getRdArr(arr) {
	return getRnd(arr);
}

/** 随机数 */
function getIntBetween(min, max) {
	return min + Math.floor(Math.random() * (max - min + 1));
}

/** 随机字符串 */
function getStr(size) {

	let text = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
	let rdmIndex = text => Math.random() * text.length | 0;
	let rdmString = '';
	for (; rdmString.length < size; rdmString += text.charAt(rdmIndex(text)));
	return rdmString;

}

/** 随机数字字符串 */
function getIntStr(size) {

	let text = '0123456789';
	let rdmIndex = text => Math.random() * text.length | 0;
	let rdmString = '';
	for (; rdmString.length < size; rdmString += text.charAt(rdmIndex(text)));
	return String(rdmString);

}

/** 随机字符串小写 */
function getStrLower(size) {
	return getStr(size).toLowerCase();
}

/** 随机字符串大写 */
function getStrUpper(size) {
	return getStr(size).toUpperCase();
}

function getUuid() {
	let s = [];
	let hexDigits = "0123456789abcdef";
	for (var i = 0; i < 36; i++) {
		s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
	}
	s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
	s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
	s[8] = s[13] = s[18] = s[23] = "-";

	let uuid = s.join("");
	return uuid;
}

/** 学院 */
function getCollege(isNullable = false, ex = '') {
	let data = '地球科学学院,环境科学与工程学院,化学与生物工程学院,材料科学与工程学院,土木与建筑工程学院,测绘地理信息学院,信息科学与工程学院,机械与控制工程学院,珠宝学院,马克思主义学院,公共管理与传媒学院,商学院,旅游与风景园林学院,艺术学院,外国语学院,理学院,文学与新闻传播学院,外国语学院,建筑与艺术学院,商学院,法学院,马克思主义学院,公共管理学院,数学与统计学院,物理与电子学院,化学化工学院,文学系,法学系,哲学系,医学系,力学系,理学系,数学系,物理系,化学系,计算机系,自动化系,口腔医学系,英语系,外语系,法语系,德语系,日语系,西班牙语系';

	return getRnd(data, isNullable, ex);
}

/** 专业 */
function getItem(isNullable = false, ex = '') {
	let data = '音乐表演,音乐学,作曲与作曲技术理论,舞蹈表演,舞蹈学,舞蹈编导,舞蹈教育,航空服务艺术与管理,流行音乐,音乐治疗,流行舞蹈,表演,戏剧学,电影学,戏剧影视文学,广播电视编导,戏剧影视导演,戏剧影视美术设计,录音艺术,播音与主持艺术,动画,美术学,绘画,雕塑,摄影,书法学,中国画,实验艺术,跨媒体艺术,文物保护与修复,漫画,艺术设计学,视觉传达设计,环境设计,产品设计,服装与服饰设计,公共艺术,工艺美术,数字媒体艺术,艺术与科技,陶瓷艺术设计,新媒体设计,包装设计,教育学,科学教育,人文教育,教育技术学,艺术教育,学前教育,小学教育,特殊教育,华文教育,教育康复学,卫生教育,法学,知识产权,监狱学,信用风险管理与法律防控,国际经贸规则,司法警察学,社区矫正,工商管理,市场营销,会计学,财务管理,国际商务,人力资源管理,审计学,资产评估,物业管理,文化产业管理,劳动关系,体育经济与管理,财务会计教育,市场营销教育,零售业管理,农林经济管理,农村区域发展 ,公共事业管理,行政管理,劳动与社会保障,土地资源管理,城市管理,海关管理,交通管理,海事管理,公共关系学,健康服务与管理,海警后勤管理,数学与应用数学,信息与计算科学,数理基础科学,数据计算及应用 ,物理学,应用物理学,核物理,声学,系统科学与工程,地理科学,自然地理与资源环境,人文地理与城乡规划,地理信息科学 ,机械设计制造及其自动化,材料成型及控制工程,机械电子工程,工业设计,过程装备与控制工程,车辆工程,汽车服务工程,机械工艺技术,微机电系统工程,机电技术教育,汽车维修工程教育,智能制造工程,材料科学与工程材料物理,材料化学,冶金工程,金属材料工程,无机非金属材料工程,高分子材料与工程,复合材料与工程,粉体材料科学与工程,宝石及材料工艺学,焊接技术与工程,功能材料,纳米材料与技术,新能源材料与器件,材料设计科学与工程,光电信息科学与工程,信息工程,广播电视工程,水声工程,电子封装技术,集成电路设计与集成系统,医学信息工程,电磁场与无线技术,电波传播与天线,电子信息科学与技术,电信工程及管理,应用电子技术教育,数字媒体技术,智能科学与技术,空间信息与数字技术,电子与计算机工程,数据科学与大数据技术,网络空间安全,新媒体技术,电影制作,保密技术,服务科学与工程,虚拟现实技术,区块链工程,建筑环境与能源应用工程,给排水科学与工程,建筑电气与智能化,城市地下空间工程,道路桥梁与渡河工程,铁道工程,智能建造,土木、水利与海洋工程,土木、水利与交通工程,采矿工程,石油工程,矿物加工工程,油气储运工程,矿物资源工程,海洋油气工程 ,纺织工程,服装设计与工程,非织造材料与工程,服装设计与工艺教育,丝绸设计与工程';

	return getRnd(data, isNullable, ex);
}

/** 行业 */
function getTrade(isNullable = false, ex = '') {
	let data = ['经营', '销售', '市场营销', '公关', '客户服务', '人力资源', '行政HR', '财务/审计/统计', '文职', '翻译', '计算机/IT', '电子/通讯', '设计', '工业/工厂', '金融/经济', '法律', '机械', '技工', '房地产/土建', '咨询/顾问', '医疗/护理/保健', '服务业', '政府机关', '事业单位', '学生/研究生', '化工', '冶金/地质'];

	return getRnd(data, isNullable, ex);
}

/** 学历 */
function getEdu(isNullable = false, ex = '') {
	let data = '中学,高职,大专,本科,硕士,博士,博士后,其他';

	return getRnd(data, isNullable, ex);
}

/** 职位 */
function getDuty(isNullable = false, ex = '') {
	let data = 'CTO,CEO,CFO,研发,销售,采购,董事长,老板,自由自由者,中层领导,部门经理,大区经理';

	return getRnd(data, isNullable, ex);
}

/** 资源 */
function getResource(isNullable = false, ex = '') {
	let data = '法律咨询,管理咨询,企业辅导,上市辅导,创业交流,投资融资,医疗咨询,教育交流,开发技术交流,研发交流,未来探讨,大宗商品,销售网络共享,艺术品鉴赏,供应链共享,进修交流,财会督导,审计辅导,企业治理,工程监理,硬件生产,小商品生产,电商,二类电商,早教,公考,艺术设计,人力资源,地质勘探,招工招聘,游戏开发,销售采购,市场营销,电子通讯,经济探讨,机械制造,产业经理,轻工业,化工化学,海外电商,企业出海,翻译,心理咨询,餐饮酒店,民宿,旅游自驾,服务业,租车,自媒体新媒体行业,文职人员,军迷,学习共勉,体育活动,打球约饭,户外旅行,文艺青年,小镇青年,斜杠青年,交通运输,民航机票,系统集成,售前服务,维修';

	return getRnd(data, isNullable, ex);
}

/** 自我介绍 */
function getMotto(isNullable = false, ex = '') {
	let data = '生无一锥土,常有四海心 ,志在山顶的人,不会贪念山腰的风景 ,人之所以能,是相信能 ,卒子过河,意在吃帅 ,心志要坚,意趣要乐 ,贫困教会贫困者一切 ,欲望以提升热忱,毅力以磨平高山 ,人生不得行胸怀,虽寿百岁犹为无也 ,人之所以异于禽者,唯志而已矣!,每一发奋努力的背后,必有加倍的赏赐 ,治天下者必先立其志 ,以天下为己任 ,一人立志,万夫莫敌 ,志高山峰矮,路从脚下伸 ,鹰爱高飞,鸦栖一枝 ,莫为一身之谋,而有天下之志 ,人之所以能,是相信能,励志短语,没有天生的信心,只有不断培养的信心 ,世上没有绝望的处境,只有对处境绝望的人 ,人格的完善是本,财富的确立是末 ,在年轻人的颈项上,没有什么东西能比事业心这颗灿烂的宝珠 ,壮志与毅力是事业的双翼 ,心有多大,舞台就有多大 ,志正则众邪不生 ,母鸡的理想不过是一把糠 ,死犹未肯输心去,贫亦其能奈我何!,鸟贵有翼,人贵有志 ,有志登山顶,无志站山脚 ,没有一种不通过蔑视忍受和奋斗就可以征服的命运 ,远大的希望造就伟大的人物 ,志不立,天下无可成之事 ,有志者能使石头长出青草来 ,莫找借口失败,只找理由成功 ,男子千年志,吾生未有涯 ,鱼跳龙门往上游 ,有志者,事竟成  ,强行者有志 ,心随朗月高,志与秋霜洁 ,与其当一辈子乌鸦,莫如当一次鹰 ,石看纹理山看脉,人看志气树看材 ,志当存高远 ,任何的限制,都是从自己的内心开始的 ,志,气之帅也 ,一个人如果胸无大志,既使再有壮丽的举动也称不上是伟人  ,立志是事业的大门,工作是登门入室的旅程 ,志气和贫困是患难兄弟,世人常见他们伴在一起 ,失败是成功之母 ,对的,坚持;错的,放弃!,丈夫志不大,何以佐乾坤 ,鸭仔无娘也长大,几多白手也成家  ,我走得很慢,但是我从来不会后退,面对太阳,阴影将落在你的背后,困境之中,饱含机遇,执着于理想,纯粹于当下,不要轻言放弃,否则对不起自己,含泪播种的人一定能含笑收获,日益努力,而后风生水起,若要梦想实现,先从梦中醒来,今天比昨天好,就是希望,希望叫醒你的不是闹钟而是理想,坚定信念的人都是英雄,欲戴皇冠,必承其重,昨日之深渊,来日之浅谈,天越黑,星星越亮,岂能尽如人意,但求无愧我心,世上没什么运气,只有努力去挑战,日出之美便在于它脱胎于最深的黑暗,不要等待机会,而要创造机会,成功的秘诀在于对目标的执着追求,我把苦难挫折当作自己生存的最好导师,黑夜无论怎样悠长,白昼总会到来,海到无边天作岸,山登绝顶我为峰,除了放弃尝试以外没有失败,有梦就别怕痛,想赢就别喊停, 与其羡慕别人,不如自己努力,努力就能成功,坚持确保胜利,永不言败,是成功者的最佳品格,人生没有彩排,每天都是现场直播,火把倒下,火焰依然向上,低头哭过别忘了抬头继续走,有种脾气叫不放弃,风乍起,合当奋意向人生,莫问收获,但问耕耘,即使身在生活,也要做你理想的卧底,我只身前行,却仿佛带着一万雄兵,熬过一切,星光璀璨,没有人帮你,说明你一个人可以,让理想生活的样子清晰可见,趁我们头脑发热,我们要不顾一切,念念不忘,必有回响,一生很短,你要大胆,容易走的路,一般都很拥挤,那些杀不死我们的,终将让我们更强大,你利用时间的方式,就是塑造自己的方式,每一个不曾起舞的日子,都是对生命的辜负,猛兽总是独行,牛羊才成群结队,你迷茫的原因在于读书太少而想的太多,对未来真正的慷慨,是把一切献给现在,没有一点儿疯狂,生活就不值得过,生活在阴沟里,但仍有人仰望星空,怕输的人已经输了,不要忘记人生是要战斗到死, 抱怨身处黑暗,不如提灯前行,患难困苦,是磨炼人格之高等学校,失败不是悲剧,放弃才是,画工须画云中龙,为人须为人中雄,博观而约取,厚积而薄发,志在山顶的人,不会贪恋山腰的风景,别为失败找理由,要为成功找方法,迷失的时候,选择更艰辛的那条路,命是弱者的借口,运是强者的谦词,如果今天不走的话,明天就要跑,今天度过的一天明天就找不回来了,生活绝不会因为你胆小怯懦而饶过你,最可怕的敌人,就是没有坚强的信念,梦想一旦被付诸行动,就会变得神圣,寄言燕雀莫相唣,自有云霄万里高,人若有志,万事可为,志不可一日坠,人不可一日放,苦难,是化了妆的祝福,没有实力的愤怒毫无意义,在避风的港湾里,找不到昂扬的帆,大胆的尝试只等于成功了一半,天才就是无止境刻苦勤奋的能力,你是自己人生的设计师,苦想没盼头,苦干有奔头,世界会向那些有目标和远见的人让路,挫折其实就是迈向成功所应缴的学费,欲望以提升热忱,毅力以磨平高山,用行动祈祷比用言语更能够使上帝了解,志不立,天下无可成之事,志向和热爱是伟大行为的双翼,水激石则鸣,人激志则宏,雄心壮志是茫茫黑夜中的北斗星,贫而懒惰乃真穷,贱而无志乃真贱,目标越接近,困难越增加,绳锯木断,水滴石穿,男儿不展风云志,空负天生八尺躯,天才就是无止境刻苦勤奋的能力,苦难是人生的老师,成功的秘诀,在永不改变既定的目的,平凡的脚步也可以走完伟大的行程,如果你有梦想的话,就要去捍卫它,永远要面对眼前的这些困境,如果我放弃,就是向那些错看我的人屈服,运气,就是机会碰巧撞到了你的努力,哪有什么胜利可言,挺住就意味着一切,过去属于死神,未来属于你自己,失败是坚忍的最后考验,流水在碰到底处时才会释放活力';

	return getRnd(data, isNullable, ex);
}

/** 用户头像 */
function getAvatar(isNullable) {
	if (getNullable(isNullable)) return '';

	return 'https://7265-release-7g51ulsq6451a0a6-1304820041.tcb.qcloud.la/mini/user_pic/' + getIntBetween(1, 200) + '.jpg';
}


/** 是否为空 */
function getNullable(isNullable) {
	if (!isNullable) return false;

	let rd = getIntBetween(0, 1);
	if (rd % 2 == 0)
		return true;
	else
		return false;
}





module.exports = {
	getUuid,
	getRnd,

	getIdCard,

	getProvince,
	getProvinceAbbr,

	getCity,
	getArea,
	getCountry,
	getStreet,
	getAddress,

	getCompany,
	getCompanyPrefix,
	getResource,
	getMotto,

	getContent,
	getWord,

	getWeek,
	getMonth,
	getTimestamp,
	getAddTimestamp,

	getFirstName,
	getFemaleName,
	getMaleName,
	getName,

	getInt,
	getRdArr,
	getIntBetween,
	getIntStr,
	getStr,
	getStrLower,
	getStrUpper,

	getMobile,
	getPhone,

	getEnWord,
	getEmail,
	getDomain,

	getDate,

	getItem,
	getCollege,
	getTrade,
	getEdu,
	getDuty,

	getAvatar
}

================================================
FILE: cloudfunctions/mcloud/framework/lib/md5_lib.js
================================================
/**
 * Notes: MD5类库
 * Ver : CCMiniCloud Framework 2.15.1 ALL RIGHTS RESERVED BY cClinux0730 (wechat)
 * Date: 2021-03-01 14:00:00 
 */

function safe_add(x, y) {
	var lsw = (x & 0xFFFF) + (y & 0xFFFF)
	var msw = (x >> 16) + (y >> 16) + (lsw >> 16)
	return (msw << 16) | (lsw & 0xFFFF)
}

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function rol(num, cnt) {
	return (num << cnt) | (num >>> (32 - cnt))
}

/*
 * These functions implement the four basic operations the algorithm uses.
 */
function cmn(q, a, b, x, s, t) {
	return safe_add(rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b)
}

function ff(a, b, c, d, x, s, t) {
	return cmn((b & c) | ((~b) & d), a, b, x, s, t)
}

function gg(a, b, c, d, x, s, t) {
	return cmn((b & d) | (c & (~d)), a, b, x, s, t)
}

function hh(a, b, c, d, x, s, t) {
	return cmn(b ^ c ^ d, a, b, x, s, t)
}

function ii(a, b, c, d, x, s, t) {
	return cmn(c ^ (b | (~d)), a, b, x, s, t)
}

/*
 * Calculate the MD5 of an array of little-endian words, producing an array
 * of little-endian words.
 */
function coreMD5(x) {
	var a = 1732584193
	var b = -271733879
	var c = -1732584194
	var d = 271733878

	for (var i = 0; i < x.length; i += 16) {
		var olda = a
		var oldb = b
		var oldc = c
		var oldd = d

		a = ff(a, b, c, d, x[i + 0], 7, -680876936)
		d = ff(d, a, b, c, x[i + 1], 12, -389564586)
		c = ff(c, d, a, b, x[i + 2], 17, 606105819)
		b = ff(b, c, d, a, x[i + 3], 22, -1044525330)
		a = ff(a, b, c, d, x[i + 4], 7, -176418897)
		d = ff(d, a, b, c, x[i + 5], 12, 1200080426)
		c = ff(c, d, a, b, x[i + 6], 17, -1473231341)
		b = ff(b, c, d, a, x[i + 7], 22, -45705983)
		a = ff(a, b, c, d, x[i + 8], 7, 1770035416)
		d = ff(d, a, b, c, x[i + 9], 12, -1958414417)
		c = ff(c, d, a, b, x[i + 10], 17, -42063)
		b = ff(b, c, d, a, x[i + 11], 22, -1990404162)
		a = ff(a, b, c, d, x[i + 12], 7, 1804603682)
		d = ff(d, a, b, c, x[i + 13], 12, -40341101)
		c = ff(c, d, a, b, x[i + 14], 17, -1502002290)
		b = ff(b, c, d, a, x[i + 15], 22, 1236535329)

		a = gg(a, b, c, d, x[i + 1], 5, -165796510)
		d = gg(d, a, b, c, x[i + 6], 9, -1069501632)
		c = gg(c, d, a, b, x[i + 11], 14, 643717713)
		b = gg(b, c, d, a, x[i + 0], 20, -373897302)
		a = gg(a, b, c, d, x[i + 5], 5, -701558691)
		d = gg(d, a, b, c, x[i + 10], 9, 38016083)
		c = gg(c, d, a, b, x[i + 15], 14, -660478335)
		b = gg(b, c, d, a, x[i + 4], 20, -405537848)
		a = gg(a, b, c, d, x[i + 9], 5, 568446438)
		d = gg(d, a, b, c, x[i + 14], 9, -1019803690)
		c = gg(c, d, a, b, x[i + 3], 14, -187363961)
		b = gg(b, c, d, a, x[i + 8], 20, 1163531501)
		a = gg(a, b, c, d, x[i + 13], 5, -1444681467)
		d = gg(d, a, b, c, x[i + 2], 9, -51403784)
		c = gg(c, d, a, b, x[i + 7], 14, 1735328473)
		b = gg(b, c, d, a, x[i + 12], 20, -1926607734)

		a = hh(a, b, c, d, x[i + 5], 4, -378558)
		d = hh(d, a, b, c, x[i + 8], 11, -2022574463)
		c = hh(c, d, a, b, x[i + 11], 16, 1839030562)
		b = hh(b, c, d, a, x[i + 14], 23, -35309556)
		a = hh(a, b, c, d, x[i + 1], 4, -1530992060)
		d = hh(d, a, b, c, x[i + 4], 11, 1272893353)
		c = hh(c, d, a, b, x[i + 7], 16, -155497632)
		b = hh(b, c, d, a, x[i + 10], 23, -1094730640)
		a = hh(a, b, c, d, x[i + 13], 4, 681279174)
		d = hh(d, a, b, c, x[i + 0], 11, -358537222)
		c = hh(c, d, a, b, x[i + 3], 16, -722521979)
		b = hh(b, c, d, a, x[i + 6], 23, 76029189)
		a = hh(a, b, c, d, x[i + 9], 4, -640364487)
		d = hh(d, a, b, c, x[i + 12], 11, -421815835)
		c = hh(c, d, a, b, x[i + 15], 16, 530742520)
		b = hh(b, c, d, a, x[i + 2], 23, -995338651)

		a = ii(a, b, c, d, x[i + 0], 6, -198630844)
		d = ii(d, a, b, c, x[i + 7], 10, 1126891415)
		c = ii(c, d, a, b, x[i + 14], 15, -1416354905)
		b = ii(b, c, d, a, x[i + 5], 21, -57434055)
		a = ii(a, b, c, d, x[i + 12], 6, 1700485571)
		d = ii(d, a, b, c, x[i + 3], 10, -1894986606)
		c = ii(c, d, a, b, x[i + 10], 15, -1051523)
		b = ii(b, c, d, a, x[i + 1], 21, -2054922799)
		a = ii(a, b, c, d, x[i + 8], 6, 1873313359)
		d = ii(d, a, b, c, x[i + 15], 10, -30611744)
		c = ii(c, d, a, b, x[i + 6], 15, -1560198380)
		b = ii(b, c, d, a, x[i + 13], 21, 1309151649)
		a = ii(a, b, c, d, x[i + 4], 6, -145523070)
		d = ii(d, a, b, c, x[i + 11], 10, -1120210379)
		c = ii(c, d, a, b, x[i + 2], 15, 718787259)
		b = ii(b, c, d, a, x[i + 9], 21, -343485551)

		a = safe_add(a, olda)
		b = safe_add(b, oldb)
		c = safe_add(c, oldc)
		d = safe_add(d, oldd)
	}
	return [a, b, c, d]
}

/*
 * Convert an array of little-endian words to a hex string.
 */
function binl2hex(binarray) {
	var hex_tab = "0123456789abcdef"
	var str = ""
	for (var i = 0; i < binarray.length * 4; i++) {
		str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF) +
			hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF)
	}
	return str
}

/*
 * Convert an array of little-endian words to a base64 encoded string.
 */
function binl2b64(binarray) {
	var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
	var str = ""
	for (var i = 0; i < binarray.length * 32; i += 6) {
		str += tab.charAt(((binarray[i >> 5] << (i % 32)) & 0x3F) |
			((binarray[i >> 5 + 1] >> (32 - i % 32)) & 0x3F))
	}
	return str
}

/*
 * Convert an 8-bit character string to a sequence of 16-word blocks, stored
 * as an array, and append appropriate padding for MD4/5 calculation.
 * If any of the characters are >255, the high byte is silently ignored.
 */
function str2binl(str) {
	var nblk = ((str.length + 8) >> 6) + 1 // number of 16-word blocks
	var blks = new Array(nblk * 16)
	for (var i = 0; i < nblk * 16; i++) blks[i] = 0
	for (var i = 0; i < str.length; i++)
		blks[i >> 2] |= (str.charCodeAt(i) & 0xFF) << ((i % 4) * 8)
	blks[i >> 2] |= 0x80 << ((i % 4) * 8)
	blks[nblk * 16 - 2] = str.length * 8
	return blks
}

/*
 * Convert a wide-character string to a sequence of 16-word blocks, stored as
 * an array, and append appropriate padding for MD4/5 calculation.
 */
function strw2binl(str) {
	var nblk = ((str.length + 4) >> 5) + 1 // number of 16-word blocks
	var blks = new Array(nblk * 16)
	for (var i = 0; i < nblk * 16; i++) blks[i] = 0
	for (var i = 0; i < str.length; i++)
		blks[i >> 1] |= str.charCodeAt(i) << ((i % 2) * 16)
	blks[i >> 1] |= 0x80 << ((i % 2) * 16)
	blks[nblk * 16 - 2] = str.length * 16
	return blks
}

/*
 * External interface
 */
function hexMD5(str) {
	return binl2hex(coreMD5(str2binl(str)))
}

function hexMD5w(str) {
	return binl2hex(coreMD5(strw2binl(str)))
}

function b64MD5(str) {
	return binl2b64(coreMD5(str2binl(str)))
}

function b64MD5w(str) {
	return binl2b64(coreMD5(strw2binl(str)))
}
/* Backward compatibility */
function calcMD5(str) {
	return binl2hex(coreMD5(str2binl(str)))
}
module.exports = {
	md5: hexMD5
}

================================================
FILE: cloudfunctions/mcloud/framework/lib/mini_lib.js
================================================
/**
 * Notes: 小程序封装类库
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cClinux0730 (wechat)
 * Date: 2020-09-06 14:00:00 
 */
const cloudBase = require('../cloud/cloud_base.js');
const cloudUtil = require('../cloud/cloud_util.js');
const config = require('../../config/config');


// 消息长度截取
function fmtThing(str) { //20个以内字符,可汉字、数字、字母或符号组合
	return str.substr(0, 20);
}

function fmtCharacterString(str) { //32位以内数字、字母或符号
	return str.substr(0, 32);
}

function fmtPhrase(str) { //5个以内汉字
	return str.substr(0, 5);
} 

/**
 * 发送一次性消息
 * @param {*} body 
 * @param {*} key 
 */
async function sendMiniOnceTempMsg(body, key = '') {
	//	console.log('##sendOnceTempMsg[' + key + ']', body);
	let cloud = cloudBase.getCloud();
	try {
		// 默认参数
		body.lang = 'zh_CN';
		body.miniprogramState = 'formal';

		await cloud.openapi.subscribeMessage.send(body);
	} catch (err) {
		cloudUtil.log('##sendOnceTempMsg[' + key + ']', err);
	}
}
module.exports = {
	sendMiniOnceTempMsg,

	fmtThing,
	fmtCharacterString,
	fmtPhrase
}

================================================
FILE: cloudfunctions/mcloud/framework/platform/controller/base_admin_controller.js
================================================
/**
 * Notes: 后台管理控制器模块
 * Ver : CCMiniCloud Framework 2.0.3 ALL RIGHTS RESERVED BY cclinuX0730 (wechat)
 * Date: 2022-05-26 19:20:00 
 */

const BaseController = require('./base_controller.js');
const BaseAdminService = require('../service/base_admin_service.js');
const LogModel = require('../model/log_model.js');

const timeUtil = require('../../../framework/utils/time_util.js');

class BaseAdminController extends BaseController {

	constructor(route, openId, event) {
		super(route, openId, event);

		// 当前时间戳
		this._timestamp = timeUtil.time();

		this._admin = null;
		this._adminId = '0';

	}

	/** 是否管理员  */
	async isAdmin() {
		// 判断是否管理员
		let service = new BaseAdminService();
		let admin = await service.isAdmin(this._token);
		this._admin = admin;
		this._adminId = admin._id;
	}

	/** 是否超级管理员  */
	async isSuperAdmin() {
		// 判断是否管理员
		let service = new BaseAdminService();
		let admin = await service.isSuperAdmin(this._token);
		this._admin = admin;
		this._adminId = admin._id;
	}

	/** 记录日志 */
	async log(content, type) {
		let service = new BaseAdminService();
		await service.insertLog(content, this._admin, type);
	}

	async logSys(content) {
		await this.log(content, LogModel.TYPE.SYS);
	}

	async logUser(content) {
		await this.log(content, LogModel.TYPE.USER);
	}

	async logOther(content) {
		await this.log(content, LogModel.TYPE.OTHER);
	}

	async logNews(content) {
		await this.log(content, LogModel.TYPE.NEWS);
	}

}

module.exports = BaseAdminController;

================================================
FILE: cloudfunctions/mcloud/framework/platform/controller/base_controller.js
================================================
/**
 * Notes: 基础控制器
 * Ver : CCMiniCloud Framework 2.0.4 ALL RIGHTS RESERVED BY cclinUx0730 (wechat)
 * Date: 2020-09-05 04:00:00 
 */

const config = require('../../../config/config.js');
const timeUtil = require('../../utils/time_util.js');
const util = require('../../utils/util.js');
const dataCheck = require('../../validate/data_check.js');

const AppError = require('../../core/app_error.js');
const appCode = require('../../core/app_code.js');

class BaseController {

	constructor(route, openId, event) {

		this._route = route; // 路由
		this._openId = openId; //用户身份
		this._event = event; // 所有参数   
		this._request = event.params; //数据参数

		if (!openId) {
			console.error('OPENID is unfined');
			throw new AppError('OPENID is unfined', appCode.SVR);
		}

		let userId = openId;

		this._token = event.token || '';
		this._userId = userId;

		// 当前时间戳
		this._timestamp = timeUtil.time();
		let time = timeUtil.time('Y-M-D h:m:s');

		console.log('------------------------');
		console.log(`【${time}】【Request -- ↘↘↘】\n【↘Token = ${this._token}】\n【↘USER-ID = ${userId}】\n【↘↘IN DATA】=\n`, JSON.stringify(this._request, null, 4));

	}

	/**
	 * 数据校验
	 * @param {*} rules 
	 */
	validateData(rules = {}) {
		let input = this._request;
		return dataCheck.check(input, rules);
	}

	// 取得某个具体的参数值
	getParameter(name) {
		let input = this._request;
		if (util.isDefined(input[name]))
			return input[name];
		else
			return '';
	}
}

module.exports = BaseController;

================================================
FILE: cloudfunctions/mcloud/framework/platform/model/admin_model.js
================================================
/**
 * Notes: 系统管理员实体 
 * Date: 2021-03-15 19:20:00 
 * Ver : CCMiniCloud Framework 2.0.5 ALL RIGHTS RESERVED BY CCLINUX0730 (wechat)
 */


const BaseModel = require('./base_model.js');

class AdminModel extends BaseModel {

}

// 集合名
AdminModel.CL = BaseModel.C('admin');

AdminModel.DB_STRUCTURE = {
	_pid: 'string|true',
	ADMIN_ID: 'string|true',
	ADMIN_NAME: 'string|true', 
	ADMIN_DESC: 'string|true',
	ADMIN_PHONE: 'string|false|comment=手机',
	ADMIN_PASSWORD: 'string|true|comment=密码',
	ADMIN_STATUS: 'int|true|default=1|comment=状态:0=禁用 1=启用',

	ADMIN_LOGIN_CNT: 'int|true|default=0|comment=登录次数',
	ADMIN_LOGIN_TIME: 'int|true|default=0|comment=最后登录时间',
	ADMIN_TYPE: 'int|true|default=0|comment=类型 0=普通管理员 1=超级管理员',

	ADMIN_TOKEN: 'string|false|comment=当前登录token',
	ADMIN_TOKEN_TIME: 'int|true|default=0|comment=当前登录token time',

	ADMIN_ADD_TIME: 'int|true',
	ADMIN_EDIT_TIME: 'int|true',
	ADMIN_ADD_IP: 'string|false',
	ADMIN_EDIT_IP: 'string|false',
};

// 字段前缀
AdminModel.FIELD_PREFIX = "ADMIN_";






module.exports = AdminModel;

================================================
FILE: cloudfunctions/mcloud/framework/platform/model/base_model.js
================================================
/**
 * Notes: 实体基类 
 * Date: 2021-03-15 19:20:00 
 * Ver : CCMiniCloud Framework 2.0.6 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 */


const MultiModel = require('../../../framework/database/multi_model.js');

class BaseModel extends MultiModel {

}

module.exports = BaseModel;

================================================
FILE: cloudfunctions/mcloud/framework/platform/model/log_model.js
================================================
/**
 * Notes: 后台操作日志实体
 * Ver : CCMiniCloud Framework 2.0.7 ALL RIGHTS RESERVED BY cclinuX0730 (wechat)
 * Date: 2020-10-16 19:20:00 
 */


const BaseModel = require('./base_model.js');

class LogModel extends BaseModel {

}

// 集合名
LogModel.CL = BaseModel.C('log');

LogModel.DB_STRUCTURE = {
	_pid: 'string|true',
	LOG_ID: 'string|true',

	LOG_ADMIN_ID: 'string|true|comment=管理员',
	LOG_ADMIN_DESC: 'string|false',
	LOG_ADMIN_NAME: 'string|true',

	LOG_CONTENT: 'string|true',

	LOG_TYPE: 'int|true|comment=日志类型 ',

	LOG_ADD_TIME: 'int|true',
	LOG_EDIT_TIME: 'int|true',
	LOG_ADD_IP: 'string|false',
	LOG_EDIT_IP: 'string|false',
};

// 字段前缀
LogModel.FIELD_PREFIX = "LOG_";

LogModel.TYPE = {
	SYS: 0,
	USER: 1,
	NEWS: 2,
	OTHER: 99,

}
LogModel.TYPE_DESC = {
	SYS: '系统',
	USER: '用户',
	NEWS: '文章',
	OTHER: '其他',
}

module.exports = LogModel;

================================================
FILE: cloudfunctions/mcloud/framework/platform/service/base_admin_service.js
================================================
/**
 * Notes: 后台管理模块业务基类
 * Date: 2021-03-15 07:48:00 
 * Ver : CCMiniCloud Framework 2.0.8 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 */

const BaseService = require('./base_service.js');

const timeUtil = require('../../../framework/utils/time_util.js');
const appCode = require('../../../framework/core/app_code.js');

const config = require('../../../config/config.js');

const AdminModel = require('../model/admin_model.js');
const LogModel = require('../model/log_model.js'); 

class BaseAdminService extends BaseService {


	/** 是否管理员 */
	async isAdmin(token) {

		if (config.IS_DEMO) { // 演示版本
			let admin = {};
			admin.ADMIN_NAME = 'demo-admin';
			admin.ADMIN_DESC = '体验用户';
			admin.ADMIN_ID = '1';
			admin.ADMIN_PHONE = '13900000000';
			admin.ADMIN_LOGIN_CNT = 0;
			admin.ADMIN_LOGIN_TIME = '';
			admin.ADMIN_TYPE = 0;
			admin.ADMIN_STATUS = 1;
			return admin;
		}

		let where = {
			ADMIN_TOKEN: token,
			ADMIN_TOKEN_TIME: ['>', timeUtil.time() - config.ADMIN_LOGIN_EXPIRE * 1000], // token有效时间
			ADMIN_STATUS: 1,
		}
		let admin = await AdminModel.getOne(where, 'ADMIN_ID,ADMIN_PHONE,ADMIN_NAME,ADMIN_TYPE,ADMIN_DESC');
		if (!admin)
			this.AppError('管理员不存在', appCode.ADMIN_ERROR);

		return admin;
	}

	/** 是否超级管理员 */
	async isSuperAdmin(token) {

		let where = {
			ADMIN_TOKEN: token,
			ADMIN_TOKEN_TIME: ['>', timeUtil.time() - config.ADMIN_LOGIN_EXPIRE * 1000], // token有效时间
			ADMIN_STATUS: 1,
			ADMIN_TYPE: 1
		}
		let admin = await AdminModel.getOne(where, 'ADMIN_ID,ADMIN_PHONE,ADMIN_NAME,ADMIN_TYPE');
		if (!admin)
			this.AppError('超级管理员不存在', appCode.ADMIN_ERROR);

		return admin;
	}

	/** 写入日志 */
	async insertLog(content, admin, type) {
		if (!admin) return;

		let data = {
			LOG_CONTENT: content,
			LOG_ADMIN_ID: admin._id,
			LOG_ADMIN_NAME: admin.ADMIN_NAME,
			LOG_ADMIN_DESC: admin.ADMIN_DESC,
			LOG_TYPE: type
		}
		await LogModel.insert(data);
	} 

}

module.exports = BaseAdminService;

================================================
FILE: cloudfunctions/mcloud/framework/platform/service/base_service.js
================================================
/**
 * Notes: 基础业务逻辑
 * Ver : CCMiniCloud Framework 2.0.9 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2022-04-24 04:00:00 
 */

const AppError = require('../../core/app_error.js');
const appCode = require('../../core/app_code.js');
const timeUtil = require('../../utils/time_util.js');

class BaseService {
	constructor() {
		// 当前时间戳
		this._timestamp = timeUtil.time();

	}

	/**
	 * 抛出异常
	 * @param {*} msg 
	 * @param {*} code 
	 */
	AppError(msg, code = appCode.LOGIC) {
		throw new AppError(msg, code);
	}

	/** 时期范围处理 */
	fmtSearchDate(where, search, field) {
		if (!search || search.length != 21 || !search.includes('#')) return where;

		let arr = search.split('#');
		let start = arr[0];
		let end = arr[1];
		where[field] = ['between', start, end];
		return where;
	}

	/* 数据库字段排序处理 */
	fmtOrderBySort(sortVal, defaultSort) {
		let orderBy = {
			[defaultSort]: 'desc'
		};

		if (sortVal.includes('|')) {
			let field = sortVal.split('|')[0];
			let order = sortVal.split('|')[1];
			orderBy = {
				[field]: order,
			};
			if (defaultSort != field) orderBy[defaultSort] = 'desc';
		}
		return orderBy;
	}

}

module.exports = BaseService;

================================================
FILE: cloudfunctions/mcloud/framework/utils/constant.js
================================================
 /**
 * Notes: 通用常量定义
 * Ver : CCMiniCloud Framework 2.32.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2020-09-05 04:00:00 
 */
module.exports = {
 
}

================================================
FILE: cloudfunctions/mcloud/framework/utils/data_util.js
================================================
/**
 * Notes: 字符相关操作函数
* Ver : CCMiniCloud Framework 2.33.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2020-09-05 04:00:00 
 */

const timeUtil = require('./time_util.js');

/**
 * 生成一个特定范围内的随机数
 */
const genRandomNum = (min, max) => (Math.random() * (max - min + 1) | 0) + min;

// 生成一个随机的数字字母字符串
const genRandomString = len => {
	const text = 'abcdefghijklmnopqrstuvwxyz0123456789';
	const rdmIndex = text => Math.random() * text.length | 0;
	let rdmString = '';
	for (; rdmString.length < len; rdmString += text.charAt(rdmIndex(text)));
	return rdmString;
}

// 生成一个随机的数字字符串
const genRandomIntString = len => {
	const text = '0123456789';
	const rdmIndex = text => Math.random() * text.length | 0;
	let rdmString = '';
	for (; rdmString.length < len; rdmString += text.charAt(rdmIndex(text)));
	return rdmString;
}

// 生成一个随机的字母字符串
const genRandomAlpha = len => {
	const text = 'abcdefghijklmnopqrstuvwxyz';
	const rdmIndex = text => Math.random() * text.length | 0;
	let rdmString = '';
	for (; rdmString.length < len; rdmString += text.charAt(rdmIndex(text)));
	return rdmString;
}

// 根据数据库自定义表单提取导出表格标题
function getTitleByForm(arr) {
	let formTitle = [];
	for (let k = 0; k < arr.length; k++) {
		if (arr.type == 'image' || arr.type == 'content') continue;

		formTitle.push({
			column: arr[k].title,
			wch: 30
		});
	}
	return formTitle;
}


// 根据数据库自定义表单提取数据
function getValByForm(arr, mark, title) {
	for (let k = 0; k < arr.length; k++) {

		if (arr[k].mark == mark || arr[k].title == title) {
			if (arr[k].type == 'image') return '图片';
			if (arr[k].type == 'content') return '图文内容';

			if (arr[k].type == 'switch') {
				if (arr[k].val === true)
					return '是';
				else
					return '否';
			}

			return arr[k].val;
		}

	}

	return '';
}

// 数据库自定义表单forms值修正
function dbFormsFix(forms) {
	for (let k = 0; k < forms.length; k++) {
		if (forms[k].type == 'number' || forms[k].type == 'digit') {
			forms[k].val = Number(forms[k].val);
			if (isNaN(forms[k].val)) forms[k].val = null;
		}
	}
	return forms;
}

// 数据库自定义表单forms转为obj
function dbForms2Obj(forms, excludeContent = false) {
	forms = dbFormsFix(forms); //数据类型修正

	if (forms.length == 0) return { 'no': 'none' };

	let obj = {};
	for (let k = 0; k < forms.length; k++) {
		if (excludeContent && forms[k].type == 'content') continue;
		obj[forms[k].mark] = forms[k].val;
	}
	return obj;
}

// 构造当前ID 
function makeID() {
	let id = timeUtil.time('YMDhms') + ''; //秒

	//毫秒3位
	let miss = timeUtil.time() % 1000 + '';
	if (miss.length == 0)
		miss = '000';
	else if (miss.length == 1)
		miss = '00' + miss;
	else if (miss.length == 2)
		miss = '0' + miss;

	return id + miss;
}

// 拆分一维数组为二维数组
function spArr(arr, size) {
	if (!arr || !Array.isArray(arr) || arr.length == 0) return arr;

	let newArray = [];
	let index = 0;
	while (index < arr.length) {
		newArray.push(arr.slice(index, index += size));
	}
	return newArray;
}

/**
 * 把字符串格式化为数组
 * @param {*} str 
 * @param {*} sp 
 */
function str2Arr(str, sp = ',') {
	if (str && Array.isArray(str)) return str;

	str = str.replace(/,/g, sp);
	let arr = str.split(sp);
	for (let i = 0; i < arr.length; i++) {
		arr[i] = arr[i].trim();

		if (isNumber(arr[i])) {
			arr[i] = Number(arr[i]);
		}

	}
	return arr;
}

/**
 *  校验只要是数字(包含正负整数,0以及正负浮点数)就返回true 
 * @param {*} val 
 * @returns bool
 */
function isNumber(val) {
	var reg = /^[0-9]+.?[0-9]*$/;
	if (reg.test(val)) {
		return true;
	} else {
		return false;
	}
}

/**
 * 提取对象数组的某个属性数组,如[{'x':1},{'x':2}] 提取 x得到[1,2]
 * @param {*} arr 
 * @param {*} key 
 * @returns []
 */
function getArrByKey(arr, key) {
	if (!Array.isArray(arr)) return;
	return arr.map((item) => {
		return item[key]
	});
}

/**
 * 提取对象数组的多个属性数组, 
 * 如 [{'x':1,'y':11,'z':111},{'x':2,'y':22,'z':222}] 
 * 提取 ['x','y'] 得到[{'x':1,'y':11},{'x':2,'y':22}]
 * @param {*} arr 
 * @param {*} keys 
 * @returns []
 */
function getArrByKeyMulti(arr, keys = []) {
	if (!Array.isArray(arr)) return;
	if (!Array.isArray(keys)) return;

	let ret = [];
	for (let k = 0; k < arr.length; k++) {
		let node = {};
		for (let j in keys) {
			node[keys[j]] = arr[k][keys[j]];
		}
		ret.push(node);
	}

	return ret;
}

/**
 * 提取对象数组某个键值等于某值的对象数据
 * @param {*} arr 
 * @param {*} key  
 * @param {*} val 
 * @returns object {}
 */
function getDataByKey(arr, key, val) {
	if (!Array.isArray(arr)) return null;

	for (let k = 0; k < arr.length; k++) {
		if (arr[k][key] == val)
			return arr[k];
	}

	return null;
}

/**
 * 文本内容格式化处理
 * @param {*} content 
 * @param {*} len 截取长度 -1不截取
 */
function fmtText(content, len = -1) {
	if (!content) return content;
	let str = content.replace(/[\r\n]/g, ""); //去掉回车换行
	if (len > 0) {
		str = str.substr(0, len);
	}
	return str.trim();
}

// 下划线转换驼峰
function toHump(name) {
	name = name.replace(/\_(\w)/g, function (all, letter) {
		return letter.toUpperCase();
	});

	// 首字母大写 
	let firstChar = name.charAt(0).toUpperCase();
	return firstChar + name.slice(1);
}

// 驼峰转换下划线
function toLine(name) {
	name = name.replace(/([A-Z])/g, "_$1").toLowerCase();

	//如果首字符为下划线,干掉
	if (name.charAt(0) === '_')
		return name.slice(1);
	else
		return name;
}

// 金额格式化 dot为金额每隔三位用","或" "间隔
function fmtMoney(s, dot = ',', prefix = '¥') {
	if (s === '' || s === null || s === undefined) s = 0;

	s = parseFloat((s + "").replace(/[^\d\.-]/g, "")).toFixed(2) + "";
	var l = s.split(".")[0].split("").reverse(),
		r = s.split(".")[1];
	t = "";
	for (i = 0; i < l.length; i++) {
		t += l[i] + ((i + 1) % 3 == 0 && (i + 1) != l.length ? dot : "");
	}
	return prefix + t.split("").reverse().join("") + "." + r;
}
/**
 *简单数组转对象数组
 * @param {*} arr [1,2,3]
 * @param {*} key [x1,x2,x3]
 * @returns [{x1:1,x2:1,x3:1},{x1:2,x2:2,x3:2},{x1:3,x2:3,x3:3}]
 */
function arr2ObjectArr(arr, key1, key2, key3) {
	let ret = [];
	for (let k = 0; k < arr.length; k++) {
		let obj = {};
		if (key1) obj[key1] = arr[k];
		if (key2) obj[key2] = arr[k];
		if (key3) obj[key3] = arr[k];
		ret.push(obj);
	}
	return ret;
}

/**
 * property
 * @param {*} property 排序属性
 * @returns 排序好的数组 
 * 用法 arr.sort(compare('age'))
 */
function objArrSortAsc(property) {
	return function (a, b) {
		var value1 = a[property];
		var value2 = b[property];
		if (value1 < value2)
			return -1;
		else if (value1 > value2)
			return 1;
		else return 0;
	}
}

/**
 * property
 * @param {*} property 排序属性
 * @returns 排序好的数组 
 * 用法 arr.sort(compare('age'))
 */
function objArrSortDesc(property) {
	return function (a, b) {
		var value1 = a[property];
		var value2 = b[property];
		if (value1 < value2)
			return 1;
		else if (value1 > value2)
			return -1;
		else return 0;
	}
}

/**
 * 数组有则减少,无则增加
 * @param {*} arr 
 * @param {*} data 
 * @param {*} sort 排序方式 asc/desc
 */
function arrAddDel(arr, data, sort = 'asc') {
	if (!arr) return arr;
	if (!Array.isArray(arr)) return arr;

	let idx = arr.indexOf(data);
	if (idx > -1)
		arr.splice(idx, 1);
	else
		arr.push(data)

	if (sort == 'asc')
		return arr.sort();
	else
		return arr.reverse();
}  

//数据深度拷贝
function deepClone(data) {
	if (data === null || typeof data === 'string' || typeof data === 'number' || typeof data === 'boolean' || typeof data === 'undefined') {
		return data;
	}

	return JSON.parse(JSON.stringify(data));
}

function padLeft(str, len, charStr) {
	if (!str)
		str = '';
	else
		str = str + '';
	return new Array(len - str.length + 1).join(charStr || '') + str;
}

function padRight(str, len, charStr) {
	if (!str)
		str = '';
	else
		str = str + '';
	return str + new Array(len - str.length + 1).join(charStr || '');
}


// 选项表单处理
function getSelectOptions(str) {
	if (!str)
		return [];
	else if (str.includes('=')) {
		let arr = str.split(',');
		for (let k = 0; k < arr.length; k++) {
			let node = arr[k].split('=');
			arr[k] = {};
			arr[k].label = node[1];
			arr[k].val = node[0];
		}
		return arr;
	} else {
		return str.split(',');
	}
}

// 数组元素交换位置 index1和index2分别是两个数组的索引值
function arraySwap(arr, index1, index2) {
	arr[index1] = arr.splice(index2, 1, arr[index1])[0];
	return arr;
}

// 数组置顶
function arrayTop(arr, idx) {
	let node = arr.splice(idx, 1)[0];
	arr.unshift(node);
	return arr;
}

// 数组置底
function arrayBottom(arr, idx) {
	let node = arr.splice(idx, 1)[0];
	arr.push(node);
	return arr;
}

/**
 * 把某个值/对象按key插到某个对象数组
 * @param {*} arr  目标数组
 * @param {*} key  键
 * @param {*} val  判断值
 * @param {*} obj  插入对象{}
 */
function insertObjArrByKey(arr, key, val, obj) {
	if (!arr) return arr;

	for (let k = 0; k < arr.length; k++) {
		if (arr[k][key] == val) {
			// 发现存在
			arr[k].list.push(obj);
			return arr;
		}
	}

	// 不存在
	let newObj = {
		[key]: val,
		list: [obj]
	}
	arr.push(newObj);
	return arr;
}

/**
 * 从对象数组中, 根据某个键值 获取满足的对象
 * @param {*} arr 
 * @param {*} key 
 * @param {*} val 
 */
function getValFromArr(arr, key = 'val', val = '') {
	if (!Array.isArray(arr)) return null;
	for (let k = 0; k < arr.length; k++) {
		if (arr[k][key] == val)
			return arr[k];
	}

	return null;
}

// 把字符串按关键字转为数组
function splitTextByKey(txt, key) {
	if (txt === null || txt === undefined) return [];
	if (key === null || key === undefined || key.trim() == '') return [String(txt)];

	key = String(key).trim();
	txt = String(txt);
	let arr = txt.split(key);
	let ret = [];
	for (let i = 0; i < arr.length; i++) {
		if (arr[i] !== '') ret.push(arr[i]);
		if (i != (arr.length - 1)) ret.push(key);
	}
	return ret;
}

module.exports = {
	arrayTop,
	arraySwap,
	arrayBottom,

	getTitleByForm,
	getValByForm,
	dbForms2Obj,
	dbFormsFix,

	getValFromArr,
	getArrByKey,
	getArrByKeyMulti, //提取对象数组的多个属性数组
	spArr, //拆分一维数组为二维
	getDataByKey,
	str2Arr,
	arr2ObjectArr,
	insertObjArrByKey,
	arrAddDel,
	objArrSortAsc,
	objArrSortDesc,
	splitTextByKey,

	arrAddDel,
	isNumber,

	padLeft,
	padRight,

	makeID,

	genRandomString, // 随机字符串
	genRandomIntString,
	genRandomAlpha,
	genRandomNum, // 随机数字 
	fmtText, // 文本内容格式化处理
	fmtMoney, //金额格式化

	toHump,
	toLine,

	getSelectOptions, //选项表单处理

	deepClone

}

================================================
FILE: cloudfunctions/mcloud/framework/utils/export_util.js
================================================
/**
 * Notes: 导出相关函数
 * Ver : CCMiniCloud Framework 2.0.14 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2022-05-25 04:00:00 
 */

const cloudBase = require('../../framework/cloud/cloud_base.js');
const cloudUtil = require('../../framework/cloud/cloud_util.js');
const timeUtil = require('../../framework/utils/time_util.js');
const util = require('../../framework/utils/util.js');
const md5Lib = require('../../framework/lib/md5_lib.js');
const config = require('../../config/config.js');
const setupUtil = require('../utils/setup/setup_util.js');

// 获得当前导出链接
async function getExportDataURL(key) {

	let url = '';
	let time = '';
	let expData = await setupUtil.get(key);
	if (!expData)
		url = '';
	else {
		url = expData.EXPORT_CLOUD_ID;
		url = await cloudUtil.getTempFileURLOne(url) + '?rd=' + timeUtil.time();
		time = timeUtil.timestamp2Time(expData.EXPORT_ADD_TIME);
	}

	return {
		url,
		time
	}
}

// 删除数据文件
async function deleteDataExcel(key) {
	console.log('[deleteExcel]  BEGIN... , key=' + key)

	// 取出数据  
	let expData = await setupUtil.get(key);
	if (!expData) return;

	// 文件路径
	let xlsPath = expData.EXPORT_CLOUD_ID;

	console.log('[deleteExcel]  path = ' + xlsPath);

	const cloud = cloudBase.getCloud();
	await cloud.deleteFile({
		fileList: [xlsPath],
	}).then(async res => {
		console.log(res.fileList);
		if (res.fileList && res.fileList[0] && res.fileList[0].status == -503003) {
			console.log('[deleteUserExcel]  ERROR = ', res.fileList[0].status + ' >> ' + res.fileList[0].errMsg);
			this.AppError('文件不存在或者已经删除');
		}

		// 删除导出数据记录
		await setupUtil.remove(key);

		console.log('[deleteExcel]  OVER.');

	}).catch(error => {
		if (error.name != 'AppError') {
			console.log('[deleteExcel]  ERROR = ', error);
			this.AppError('操作失败,请重新删除');
		} else
			throw error;
	});


}

// 导出数据  
async function exportDataExcel(key, title, total, data, options = {}) {
	// 删除导出表

	await setupUtil.remove(key);

	let fileName = key + '_' + md5Lib.md5(key + config.CLOUD_ID);
	let xlsPath = util.getProjectId() + '/' + 'export/' + fileName + '.xlsx';

	// 操作excel用的类库
	const xlsx = require('node-xlsx');

	// 把数据保存到excel里
	let buffer = await xlsx.build([{
		name: title + timeUtil.time('Y-M-D'),
		data,
		options
	}]);

	// 把excel文件保存到云存储里
	console.log('[ExportData]  Save to ' + xlsPath);
	const cloud = cloudBase.getCloud();
	let upload = await cloud.uploadFile({
		cloudPath: xlsPath,
		fileContent: buffer, //excel二进制文件
	});
	if (!upload || !upload.fileID) return;

	// 入导出表 
	let dataExport = {
		EXPORT_ADD_TIME: timeUtil.time(),
		EXPORT_KEY: key,
		EXPORT_CLOUD_ID: upload.fileID
	}
	//console.log(dataExport)
	await setupUtil.set(key, dataExport, 'export');

	console.log('[ExportData]  OVER.')

	return {
		total
	}
}

module.exports = {
	getExportDataURL,
	deleteDataExcel,
	exportDataExcel
}

================================================
FILE: cloudfunctions/mcloud/framework/utils/log_util.js
================================================
 /**
  * Notes: 日志操作函数
  * Ver : CCMiniCloud Framework 2.34.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
  * Date: 2021-06-12 04:00:00 
  */
 const timeUtil = require('./time_util.js');

 class LogUtil {

 	constructor(level = 'info') {
 		this.logOut = ''; // 输出日志内容

 		level = level.toLowerCase();
 		if (level == 'err') level = 'error';

 		switch (level) {
 			case 'debug':
 				level = LogUtil.LEVEL.DEBUG;
 				break;
 			case 'info':
 				level = LogUtil.LEVEL.INFO;
 				break;
 			case 'warn':
 				level = LogUtil.LEVEL.WARN;
 				break;
 			case 'error':
 				level = LogUtil.LEVEL.ERROR;
 				break;
 			case 'fatal':
 				level = LogUtil.LEVEL.FATAL;
 				break;
 			case 'none':
 				level = LogUtil.LEVEL.NONE;
 				break;
 			default:
 				level = LogUtil.LEVEL.INFO;
 		}
 		this.level = level;
 	}

 	debug(str, ex = '') {
 		if (this.level > LogUtil.LEVEL.DEBUG) return;

 		console.debug('[' + this._getTime() + '] DEBUG: ' + str, ex);
 		this.logOut += "######" + '[' + this._getTime() + '] DEBUG: ' + str + (ex ? JSON.stringify(ex) : '');
 	}

 	info(str, ex = '') {
 		if (this.level > LogUtil.LEVEL.INFO) return;

 		console.log('[' + this._getTime() + '] INFO: ' + str, ex);

 		this.logOut += "######" + '[' + this._getTime() + '] INFO: ' + str + (ex ? JSON.stringify(ex) : '');
 	}

 	warn(str, ex = '') {
 		if (this.level > LogUtil.LEVEL.WARN) return;

 		console.warn('[' + this._getTime() + '] WARN: ' + str, ex);
 		this.logOut += "######" + '[' + this._getTime() + '] WARN: ' + str + (ex ? JSON.stringify(ex) : '');
 	}

 	error(str, ex = '') {
 		if (this.level > LogUtil.LEVEL.ERROR) return;

 		console.error('[' + this._getTime() + '] ERROR: ' + str, ex);
 		this.logOut += "######" + '[' + this._getTime() + '] ERROR: ' + str + (ex ? JSON.stringify(ex) : '');
 	}

 	fatal(str, ex = '') {
 		if (this.level > LogUtil.LEVEL.FATAL) return;
 		console.error('[' + this._getTime() + '] FATAL: ' + str, ex);
 		this.logOut += "######" + '[' + this._getTime() + '] FATAL: ' + str + (ex ? JSON.stringify(ex) : '');
 	}


 	_getTime() {
 		return timeUtil.time('Y-M-D h:m:s');
 	}

 	err(str) {
 		error(str);
 	}

 	getLogOut() {
 		return this.logOut;
 	}

 }

 LogUtil.LEVEL = {
 	DEBUG: 10,
 	INFO: 20,
 	WARN: 30,
 	ERROR: 40,
 	FATAL: 50,
 	NONE: 100,
 };

 module.exports = LogUtil;

================================================
FILE: cloudfunctions/mcloud/framework/utils/math_util.js
================================================
 /**
  * Notes: 数学计算相关操作函数
  * Ver : CCMiniCloud Framework 2.35.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
  * Date: 2021-10-04 04:00:00 
  */


 /** 获取百分比, 保留2位小数 */
 function percent(num1, num2) {
 	return Math.round(num1 / num2 * 10000) / 100.00;
 }

 /** 数组对象排序 */
 function arrayObjecSortAsc(property) {
 	return function (a, b) {
 		var value1 = a[property];
 		var value2 = b[property];
 		return value1 - value2;
 	}
 }

 /** 数组对象排序 */
 function arrayObjecSortDesc(property) {
 	return function (a, b) {
 		var value1 = a[property];
 		var value2 = b[property];
 		return value2 - value1;
 	}
 }

 module.exports = {
 	percent, // 百分比,保留2位小数 
 	arrayObjecSortAsc, // 数组对象排序
 	arrayObjecSortDesc, // 数组对象排序
 }

================================================
FILE: cloudfunctions/mcloud/framework/utils/setup/setup_model.js
================================================
/**
 * Notes: 系统设置实体
 * Ver : CCMiniCloud Framework 2.0.15 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2020-11-05 19:20:00 
 */


const MultiModel = require('../../database/multi_model.js');

class SetupModel extends MultiModel {

}

// 集合名
SetupModel.CL = MultiModel.C('setup');

SetupModel.DB_STRUCTURE = {
	_pid: 'string|true',
	SETUP_ID: 'string|true',

	SETUP_TYPE: 'string|false', //content/cache/vouch
	SETUP_KEY: 'string|true',
	SETUP_VALUE: 'object|true', // {val:}
 
	SETUP_ADD_TIME: 'int|true',
	SETUP_EDIT_TIME: 'int|true',
	SETUP_ADD_IP: 'string|false',
	SETUP_EDIT_IP: 'string|false',
};

// 字段前缀
SetupModel.FIELD_PREFIX = "SETUP_"; 


module.exports = SetupModel;

/* 
### 富文本
[{"type":"text","val":"xxx"},{"type":"img","val":"cloudId://xxxx"}]

### 导出
{"EXPORT_CLOUD_ID":"","EXPORT_EDIT_TIME":""}
*/

================================================
FILE: cloudfunctions/mcloud/framework/utils/setup/setup_util.js
================================================
/**
 * Notes: 系统设置相关函数
 * Ver : CCMiniCloud Framework 2.31.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2022-05-25 04:00:00 
 */

const SetupModel = require('./setup_model.js');

/**
 * 设置
 * key 键key
 * val 值value
 * t 秒
 */
async function set(key, val, type = '') {
	if (!key) return null;

	let where = {
		SETUP_KEY: key
	}

	let data = {
		SETUP_TYPE: type,
		SETUP_VALUE: {
			val
		}, 
	}
	 
	await SetupModel.insertOrUpdate(where, data);

}

/**
 * 获取
 * k 键key
 * def 默认值
 */
async function get(key) {

	if (!key) return null;

	let where = {
		SETUP_KEY: key
	}

	let setup = await SetupModel.getOne(where, 'SETUP_VALUE');
	if (!setup) return null;


	let res = setup.SETUP_VALUE.val;

	if (res === undefined) {
		return null;
	} else {
		return res;
	}
}

async function get(key) {

	if (!key) return null;

	let where = {
		SETUP_KEY: key
	}

	let setup = await SetupModel.getOne(where, 'SETUP_VALUE');
	if (!setup) return null;


	let res = setup.SETUP_VALUE.val;

	if (res === undefined) {
		return null;
	} else {
		return res;
	}
}

async function remove(key, fuzzy = false) {
	if (!key) return;

	let where = {
		SETUP_KEY: key
	}

	if (fuzzy) {
		where.SETUP_KEY = {
			$regex: '.*' + key,
			$options: 'i'
		};
	}

	await SetupModel.del(where);
}

module.exports = {
	set,
	get,
	remove
}

================================================
FILE: cloudfunctions/mcloud/framework/utils/time_util.js
================================================
/**
 * Notes: 时间相关函数
 * Ver : CCMiniCloud Framework 2.36.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2020-09-05 04:00:00 
 */

const util = require('./util.js');

/** 日期简化,去掉多余的前缀0 */
function simpleDate(date) {
	let arr = date.split('-');
	if (arr.length < 3) return date;
	let month = arr[1];
	if (month.indexOf('0') == 0)
		month = month.replace('0', '');

	let day = arr[2];
	if (day.indexOf('0') == 0)
		day = day.replace('0', '');

	return arr[0] + '-' + month + '-' + day;
}

/** 时间格式化为年月日点分 */
function fmtDateCHN(date, fmt = 'Y-M-D') {
	if (!date) return '';
	if (fmt == 'hh:mm' && date.includes(':')) {
		if (date.includes(' ')) date = date.split(' ')[1];
		let arr = date.split(':');
		return Number(arr[0]) + '点' + arr[1] + '分';
	} else if (fmt == 'Y-M-D hh:mm') {
		let arr = date.split(' ');
		if (arr.length != 2) return date;
		return fmtDateCHN(arr[0], 'Y-M-D') + fmtDateCHN(arr[1], 'hh:mm');
	} else if (fmt == 'M-D hh:mm') {
		let arr = date.split(' ');
		if (arr.length != 2) return date;
		return fmtDateCHN(arr[0], 'M-D') + ' ' + fmtDateCHN(arr[1], 'hh:mm');
	} else {
		if (date.includes(' ')) date = date.split(' ')[0];

		let arr = date.split('-');
		if (fmt == 'Y-M') //年月
			return arr[0] + '年' + Number(arr[1]) + '月';
		else if (fmt == 'M-D') //月日
			return arr[1] + '月' + Number(arr[2]) + '日';
		else if (fmt == 'Y') //年
			return arr[0] + '年';
		else
			return arr[0] + '年' +Number(arr[1]) + '月' + Number(arr[2]) + '日';
	}


}

/**
 * 毫秒时间戳转时间格式
 * @param {*} unixtime  毫秒
 * @param {*} format  Y-M-D h:m:s
 * @param {*} diff  时区差异 毫秒
 */
function timestamp2Time(unixtime, format = 'Y-M-D h:m:s', diff = 0) {
	unixtime = Number(unixtime);
	let formateArr = ['Y', 'M', 'D', 'h', 'm', 's'];
	let returnArr = [];
	let date = new Date(unixtime + diff);
	returnArr.push(date.getFullYear());
	returnArr.push(formatNumber(date.getMonth() + 1));
	returnArr.push(formatNumber(date.getDate()));
	returnArr.push(formatNumber(date.getHours()));
	returnArr.push(formatNumber(date.getMinutes()));
	returnArr.push(formatNumber(date.getSeconds()));
	for (let i in returnArr) {
		format = format.replace(formateArr[i], returnArr[i]);
	}
	return format;
}


function timestame2Ago(dateTimeStamp, fmt = 'Y-M-D', diff = 0) { //dateTimeStamp是一个时间毫秒,注意时间戳是秒的形式,在这个毫秒的基础上除以1000,就是十位数的时间戳。13位数的都是时间毫秒。
	let minute = 1000 * 60; //把分,时,天,周,半个月,一个月用毫秒表示
	let hour = minute * 60;
	let day = hour * 24;
	let week = day * 7;
	let month = day * 30;
	let now = new Date().getTime(); //获取当前时间毫秒

	let diffValue = now - dateTimeStamp; //时间差

	if (diffValue < 0) {
		return;
	}
	let minC = diffValue / minute; //计算时间差的分,时,天,周,月
	let hourC = diffValue / hour;
	let dayC = diffValue / day;

	let result = '';

	let weekC = diffValue / week;
	let monthC = diffValue / month;
	if (monthC >= 1 && monthC <= 3) {
		result = ' ' + parseInt(monthC) + '月前'
	} else if (weekC >= 1 && weekC <= 3) {
		result = ' ' + parseInt(weekC) + '周前'
	} else if (dayC >= 1 && dayC <= 6) {
		result = ' ' + parseInt(dayC) + '天前'
	} else if (hourC >= 1 && hourC <= 23) {
		result = ' ' + parseInt(hourC) + '小时前'
	} else if (minC >= 1 && minC <= 59) {
		result = ' ' + parseInt(minC) + '分钟前'
	} else if (diffValue >= 0 && diffValue <= minute) {
		result = '刚刚'
	} else {
		result = timestamp2Time(dateTimeStamp, fmt, diff);

	}
	return result;
}

function formatNumber(n) {
	n = n.toString()
	return n[1] ? n : '0' + n
}


/**
 * 时间转时间戳 
 * @param {*} date  支持 Y-M-D h:m:s / Y-M-D  
 */
function time2Timestamp(date) {
	if (date.length < 10) {
		let arr = date.split('-');
		if (arr[1].length == 1) arr[1] = '0' + arr[1];
		if (arr[2].length == 1) arr[2] = '0' + arr[2];
		date = arr[0] + '-' + arr[1] + '-' + arr[2];
	}
	if (date.length == 10) date = date + ' 00:00:00';
	let d = new Date(date.replace(/-/g, '/'));
	return d.getTime();
}

/**
 *  获取当前时间戳/时间Y-M-D h:m:s
 * @param {*} 时间格式 Y-M-D h:m:s
 * @param {int} 时间步长 (秒)
 */
function time(fmt, step = 0) {
	let t = 0;
	if (util.isDefined(fmt)) {
		let t = new Date().getTime() + step * 1000;
		return timestamp2Time(t, fmt);
	}
	return new Date().getTime() + t * 1000;
}

// 获取某天0点
function getDayFirstTimestamp(timestamp) {
	if (!timestamp) timestamp = time();
	return time2Timestamp(timestamp2Time(timestamp, 'Y-M-D'));
}

/**
 * 根据出生日期计算年龄周岁 传参格式为1996-06-08
 * @param {*} birth 
 */
function getAge(birth, isMonth = false) {
	var returnAge = '';
	var mouthAge = '';
	var arr = birth.split('-');
	var birthYear = arr[0];
	var birthMonth = arr[1];
	var birthDay = arr[2];
	var d = new Date();
	var nowYear = d.getFullYear();
	var nowMonth = d.getMonth() + 1;
	var nowDay = d.getDate();
	if (nowYear == birthYear) {
		// returnAge = 0; //同年 则为0岁
		var monthDiff = nowMonth - birthMonth; //月之差 
		if (monthDiff < 0) {} else {
			mouthAge = monthDiff + '个月';
		}
	} else {
		var ageDiff = nowYear - birthYear; //年之差
		if (ageDiff > 0) {
			if (nowMonth == birthMonth) {
				var dayDiff = nowDay - birthDay; //日之差 
				if (dayDiff < 0) {
					returnAge = ageDiff - 1 + '岁';
				} else {
					returnAge = ageDiff + '岁';
				}
			} else {
				var monthDiff = nowMonth - birthMonth; //月之差 
				if (monthDiff < 0) {
					returnAge = ageDiff - 1 + '岁';
				} else {
					mouthAge = monthDiff + '个月';
					returnAge = ageDiff + '岁';
				}
			}
		} else {
			returnAge = -1; //返回-1 表示出生日期输入错误 晚于今天
		}
	}
	if (isMonth)
		return returnAge + mouthAge; //返回周岁年龄+月份
	else
		return returnAge;
}

/**
 * 日期计算周几
 * @param {*} day  日期为输入日期,格式为 2013-03-10
 */
function week(day) { 
	if (!day || !day.includes('-')) return '';
	let arys1 = new Array();
	arys1 = day.split('-');
	let ssdate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]);
	let week1 = String(ssdate.getDay()).replace("0", "日").replace("1", "一").replace("2", "二").replace("3", "三").replace("4", "四").replace("5", "五").replace("6", "六") //就是你要的星期几
	return "周" + week1; //就是你要的星期几 
}

/** 获取某天所在某月第一天时间戳 */
function getMonthFirstTimestamp(timestamp) {
	let inDate = new Date(timestamp);
	let year = inDate.getFullYear();
	let month = inDate.getMonth();
	return new Date(year, month, 1).getTime();
}

/** 获取某天所在某月最后一天时间戳 */
function getMonthLastTimestamp(timestamp) {
	let inDate = new Date(timestamp);
	let year = inDate.getFullYear();
	let month = inDate.getMonth();
	return new Date(year, month + 1, 1).getTime() - 1;
}

// 取得分钟时间戳
function getNowMinTimestamp() {
	let min = time('Y-M-D h:m') + ':00';
	let timestamp = time2Timestamp(min);
	return {
		min,
		timestamp
	}
}


// 获取当前日期所在周一 输入和返回格式=yyyy-mm-dd
function getFirstOfWeek(date) {
	let now = new Date(date);
	let nowTime = now.getTime();
	let day = now.getDay();
	if (day == 0) day = 7;
	let oneDayTime = 24 * 60 * 60 * 1000;
	let mondayTime = nowTime - (day - 1) * oneDayTime;
	return timestamp2Time(mondayTime, 'Y-M-D');
}

// 获取当前日期所在周一 输入和返回格式=yyyy-mm-dd
function getLastOfWeek(date) {
	let now = new Date(date);
	let nowTime = now.getTime();
	let day = now.getDay();
	if (day == 0) day = 7;
	let oneDayTime = 24 * 60 * 60 * 1000;
	let sundayTime = nowTime + (7 - day) * oneDayTime;
	return timestamp2Time(sundayTime, 'Y-M-D');
}

// 获取当前日期所在月第一天 输入和返回格式=yyyy-mm-dd
function getFirstOfMonth(date) {
	let arr = date.split('-');
	return arr[0] + '-' + arr[1] + '-01';
}

// 获取当前日期所在月最后一天 输入和返回格式=yyyy-mm-dd
function getLastOfMonth(date) {
	let now = new Date(date);
	let y = now.getFullYear();
	let m = now.getMonth();
	let lastDay = new Date(y, m + 1, 0).getTime();
	return timestamp2Time(lastDay, 'Y-M-D');
}

/**
 * 取倒计时(天时分秒) 支持时间戳或者Y-M-D/Y-M-D h:m:s
 * @param {*} datetimeTo 
 * @param {*} flag 1=正 -1=负
 */
function getTimeLeft(datetimeTo, flag = 1) {
	let time1 = datetimeTo;

	if (String(datetimeTo).includes('-')) {
		datetimeTo = String(datetimeTo);
		if (!datetimeTo.includes(':'))
			datetimeTo += ' 00:00:00';
		time1 = new Date(datetimeTo).getTime();
	}

	let time2 = new Date().getTime();
	let mss = time1 - time2;

	// 将时间差(毫秒)格式为:天时分秒
	let days = parseInt(mss / (1000 * 60 * 60 * 24));
	let hours = parseInt((mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
	let minutes = parseInt((mss % (1000 * 60 * 60)) / (1000 * 60));
	let seconds = parseInt((mss % (1000 * 60)) / 1000);

	if (mss < 0 && mss < -86400 * 1000) {
		(days != 0) ? days = -flag * days + "天": days = '';
		return days + "前";
	} else if (mss < 0) {
		return "今天";
	} else {
		(days != 0) ? days = flag * days + "天": days = '';
		(hours != 0) ? hours = flag * hours + "时": hours = '';
		(minutes != 0) ? minutes = flag * minutes + "分": minutes = '';
		return days + hours + minutes + flag * seconds + "秒"
	}

}


module.exports = {
	fmtDateCHN,
	simpleDate,

	getTimeLeft,

	getNowMinTimestamp,

	getMonthFirstTimestamp,
	getMonthLastTimestamp,

	getDayFirstTimestamp,

	timestamp2Time,
	timestame2Ago,
	time2Timestamp,
	time,
	getAge,
	week, //星期

	getFirstOfWeek,
	getLastOfWeek,
	getFirstOfMonth,
	getLastOfMonth
}

================================================
FILE: cloudfunctions/mcloud/framework/utils/util.js
================================================
/**
 * Notes: 通用工具函数
 * Ver : CCMiniCloud Framework 2.38.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2020-09-05 04:00:00 
 */

function getProjectId() {
	if (global.PID)
		return global.PID;
	else
		return 'ONE';
}

/**
 * 判断变量,参数,对象属性是否定义
 * @param {*} val 
 */
function isDefined(val) {
	// ==  不能判断是否为null
	if (val === undefined)
		return false;
	else
		return true;
}

/**
 * 判断对象是否为空
 * @param {*} obj 
 */
function isObjectNull(obj) {
	return (Object.keys(obj).length == 0);
}



/**
 * 休眠时间,配合await使用 
 * @param {*} time 毫秒
 */
function sleep(time) {
	return new Promise((resolve) => setTimeout(resolve, time));
};




module.exports = {
	getProjectId,
	isDefined, //判断变量,参数,对象属性是否定义  
	sleep,
	isObjectNull,

}

================================================
FILE: cloudfunctions/mcloud/framework/validate/content_check.js
================================================
/**
 * Notes: 内容审核
 * Ver : CCMiniCloud Framework 2.39.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2020-09-05 04:00:00 
 */

const AppError = require('../core/app_error.js');
const cloudBase = require('../cloud/cloud_base.js');
const config = require('../../config/config.js');

/**
 * 前台校验
 * @param {*} imgData 
 * @param {*} mine 
 */
async function checkImgClient(imgData, mine) {
	if (!config.CLIENT_CHECK_CONTENT) return;
	return await checkImg(imgData, mine);
}

/**
 * 后台校验
 * @param {*} imgData 
 * @param {*} mine 
 */
async function checkImgAdmin(imgData, mine) {
	if (!config.ADMIN_CHECK_CONTENT) return;
	return await checkImg(imgData, mine);
}
/**
 * 校验图片信息
 * @param {*} 图片流buffer 
 */
async function checkImg(imgData, mine) {


	let cloud = cloudBase.getCloud();
	try {
		const result = await cloud.openapi.security.imgSecCheck({
			media: {
				contentType: 'image/' + mine,
				value: Buffer.from(imgData, 'base64') // 这里必须要将小程序端传过来的进行Buffer转化,否则就会报错,接口异常
			}

		})
		console.log('imgcheck', result);
		if (!result || result.errCode !== 0) {
			throw new AppError('图片内容不合适,请修改');
		}

	} catch (err) {
		console.log('imgcheck ex', err);
		throw new AppError('图片内容不合适,请修改');
	}

}

/**
 * 后台把输入数据里的文本数据提交内容审核
 * @param {*} input 
 */
async function checkTextMultiAdmin(input) {
	if (!config.ADMIN_CHECK_CONTENT) return;
	return checkTextMulti(input);
}

/**
 * 前台把输入数据里的文本数据提交内容审核
 * @param {*} input 
 */
async function checkTextMultiClient(input) {
	if (!config.CLIENT_CHECK_CONTENT) return;
	return checkTextMulti(input);
}

/**
 * 把输入数据里的文本数据提交内容审核
 * @param {*} input 
 */
async function checkTextMulti(input) {

	let txt = '';
	for (let key in input) {
		if (typeof (input[key]) === 'string')
			txt += input[key];
		else if (typeof (input[key]) === 'object') //包括数组和对象
			txt += JSON.stringify(input[key]);
	}

	await checkText(txt);
}
/**
 * 后台校验文字信息
 * @param {*}  
 */
async function checkTextAdmin(txt) {
	if (!config.ADMIN_CHECK_CONTENT) return;
	return checkText(txt);
}

/**
 * 前台校验文字信息
 * @param {*}  
 */
async function checkTextClient(txt) {
	if (!config.CLIENT_CHECK_CONTENT) return;
	return checkText(txt);
}

/**
 * 校验文字信息
 * @param {*}  
 */
async function checkText(txt) { 
	if (!txt) return; 
	let cloud = cloudBase.getCloud();
	try { 
		const result = await cloud.openapi.security.msgSecCheck({
			content: txt

		})
		if (!result || result.errCode !== 0) {
			throw new AppError('文字内容不合适,请修改或者重试');
		}

	} catch (err) {
		console.log('checkText ex', err);
		throw new AppError('文字内容不合适,请修改或者重试');
	}

}

module.exports = {
	checkImg,
	checkImgClient,
	checkImgAdmin,
	checkTextMulti,
	checkTextMultiClient,
	checkTextMultiAdmin,
	checkText,
	checkTextClient,
	checkTextAdmin
}

================================================
FILE: cloudfunctions/mcloud/framework/validate/data_check.js
================================================
/**
  * Notes: 数据校验类库
 * Ver : CCMiniCloud Framework 2.21.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
  * Date: 2021-01-07 07:48:00 
  *  
 */
const AppError = require('../core/app_error.js');
const appCode = require('../core/app_code.js');

const CHECK_OPEN = true;
const CHECK_SOURCE = 'admin'; //client/admin

/**
 * 判断变量,参数,对象属性是否定义
 * @param {*} val 
 */
function isDefined(val) {
	// ==  不能判断是否为null
	if (val === undefined)
		return false;
	else
		return true;
}

function isNull(value) {
	if (value === null || value === undefined) return true;
	if (getDataType(value) == String && value === '') return true;
	return false;
}

function isStrAndArrNull(value) {
	if (value === null || value === undefined) return true;

	let type = getDataType(value);
	if (type == String && value === '') return true;
	if (type == Array && value.length == 0) return true;

	return false;
}

function isRealNull(value) {
	if (value === null || value === undefined) return true;

	let type = getDataType(value);
	if (type == String && value === '') return true;
	if (type == Array && value.length == 0) return true;
	if (type == Object && JSON.stringify(value) == '{}') return true;

	return false;
}

function getDataType(value) {
	if (value === null || value === undefined) return value;
	return value.constructor;
}

// 是否必填
function checkRequired(value, desc = '') {
	switch (getDataType(value)) {
		case Object:
			if (JSON.stringify(value) == '{}')
				return desc + '不能为空obj';
			break;
		case Array:
			if (value.length == 0)
				return desc + '不能为空arr';
			break;
		case String:
			if (value.length == 0)
				return desc + '不能为空';
			break;
		case null:
		case undefined:
			return desc + '不能为空';
	}
}

// 校验字符/数组长度,校验数字大小
function checkMin(value, min, desc = '') {
	if (isStrAndArrNull(value)) return;

	min = Number(min);
	switch (getDataType(value)) {
		case Array:
			if (value.length < min)
				return desc + '不能少于' + min + '项';
			break;
		case String:
			if (value.length < min)
				return desc + '不能少于' + min + '位';
			break;
		case Number:
			if (value < min)
				return desc + '不能小于' + min;
			break;
	}
};

// 校验字符/数组长度,校验数字大小
function checkMax(value, max, desc = '') {
	if (isStrAndArrNull(value)) return;

	max = Number(max);
	switch (getDataType(value)) {
		case Array:
			if (value.length > max)
				return desc + '不能多于' + max + '项';
			break;
		case String:
			if (value.length > max)
				return desc + '不能多于' + max + '位';
			break;
		case Number:
			if (value > max)
				return desc + '不能大于' + max;
			break;
	}
};

// 校验字符/数组长度 
function checkLen(value, len, desc = '') {
	if (isStrAndArrNull(value)) return;

	len = Number(len);
	switch (getDataType(value)) {
		case Array:
			if (value.length != len)
				return desc + '必须为' + len + '项';
			break;
		case String:
			if (value.length != len)
				return desc + '必须为' + len + '位';
			break;
	}
};

function checkMobile(value, desc = '') {
	if (isNull(value)) return;

	if (!/(^1[1|2|3|4|5|6|7|8|9][0-9]{9}$)/.test(value))
		return desc + '格式不正确';
}

function checkInt(value, desc = '') {
	if (isNull(value)) return;

	if (!/^[0-9]+$/.test(value))
		return desc + '必须为数字';
}

function checkDigit(value, desc = '') {
	if (isNull(value)) return;

	if (!/^\d+(\.\d+)?$/.test(value))
		return desc + '必须为数字或小数';
}

function checkLetter(value, desc = '') {
	if (isNull(value)) return;

	if (!/^[A-Za-z]+$/.test(value))
		return desc + '必须为字母';
}

function checkMoney(value, desc = '') {
	if (isNull(value)) return;

	if (!/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/.test(value))
		return desc + '必须为金额格式,例如2.00';
}


function checkLetterNum(value, desc = '') {
	if (isNull(value)) return;

	if (!/^\w+$/.test(value))
		return desc + '必须为字母,数字和下划线';
}

function checkId(value, desc = '', min = 1, max = 100) {
	if (isNull(value)) return;

	min = Number(min);
	max = Number(max);

	if (getDataType(value) != String) return desc + '必须为ID字符串格式';

	if (value.length < min || value.length > max) return desc + '必须为ID格式';
	/*if (!/^\w+$/.test(value))
		return desc + '必须为ID格式';*/
}

//  邮箱
function checkEmail(value, desc = '') {
	if (isNull(value)) return;

	let reg = /^[A-Za-z0-9+]+[A-Za-z0-9\.\_\-+]*@([A-Za-z0-9\-]+\.)+[A-Za-z0-9]+$/;
	if (!reg.test(value)) return desc + '必须为邮箱格式';
}

// 短日期,形如 (yyyy-mm-dd 2008-07-22)
function checkDate(value, desc = '') {
	if (isNull(value)) return;

	let hint = '请选择' + desc;
	if (value.length != 10) return hint;
	let r = value.match(/^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/);
	if (r == null) return hint;
	let d = new Date(r[1], r[3] - 1, r[4]);
	let chk = d.getFullYear() == r[1] && (d.getMonth() + 1) == r[3] && d.getDate() == r[4];
	if (!chk) return hint;
}

// 年份,形如 (yyyy 2008)
function checkYear(value, desc = '') {
	if (isNull(value)) return;

	let hint = '请选择' + desc;
	if (value.length != 4) return hint;
	value += '-01-01';
	return checkDate(value, desc);
}

// 年月,形如 (yyyy-mm 2008-01)
function checkYearMonth(value, desc = '') {
	if (isNull(value)) return;

	let hint = '请选择' + desc;
	if (value.length != 7) return hint;

	value += '-01';
	return checkDate(value, desc);
}

// 短时间(时分秒),形如 (13:04:06)
function checkTime(value, desc = '') {
	if (isNull(value)) return;

	let hint = desc + '必须为时间格式';
	if (value.length != 8) return hint;

	let a = value.match(/^(\d{1,2})(:)?(\d{1,2})\2(\d{1,2})$/);
	if (a == null) return hint;
	if (a[1] > 23 || a[3] > 59 || a[4] > 59) return hint;
}

// 短时间(时分),形如 (hh:mm 13:04)
function checkHourMinute(value, desc = '') {
	if (isNull(value)) return;

	let hint = desc + '必须为时分时间格式';
	if (value.length != 5) return hint;

	value += ':01';
	return checkTime(value, desc);
}

// 长时间,形如 (2008-07-22 13:04:06)
function checkDatimeTime(value, desc = '') {
	if (isNull(value)) return;

	let hint = desc + '必须为完整时间格式';
	if (value.length != 19) return hint;

	var reg = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2}) (\d{1,2}):(\d{1,2}):(\d{1,2})$/;
	var r = value.match(reg);
	if (r == null) return hint;
	var d = new Date(r[1], r[3] - 1, r[4], r[5], r[6], r[7]);
	let 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];
	if (!chk) return hint;
}

function checkArray(value, desc = '') {
	if (!Array.isArray(value))
		return desc + '填写错误arr';
}

function checkObject(value, desc = '') {
	if (value.constructor != Object)
		return desc + '填写错误obj';
}

function checkBoolean(value, desc = '') {
	if (value.constructor != Boolean)
		return desc + '填写错误bool';
}

// 枚举 ref=1,2,3,4格式
function checkIn(value, ref, desc = '') {
	if (isNull(value)) return;

	let type = getDataType(value);
	if (type != String && type != Number) return desc + '填写范围错误';

	let arr = String(ref).split(',');
	if (!arr.includes(value) && !arr.includes(value + ''))
		return desc + '填写范围错误';
}

function checkIds(value, desc) {}

function checkString(value, desc) {
	if (value.constructor != String)
		return desc + '填写错误';
}


function check(data, rules, that) {
	let returnData = {};
	for (let key in rules) {
		let arr = rules[key].split('|');

		let desc = key; // 字段说明
		let defVal = undefined; // 缺省值
		let dataType = 'String'; //数据类型   

		if (!CHECK_OPEN) { // 不校验
			// 取值
			let val = data[formName];
			returnData[key] = val;
			continue;
		}

		// 小循环获取规则
		for (let i = 0; i < arr.length; i++) {
			// 数据项说明  
			if (arr[i].startsWith('name=')) {
				desc = '「' + arr[i].replace('name=', '') + '」';
				continue;
			}

			// 缺省值 
			if (arr[i].startsWith('default=')) {
				defVal = arr[i].replace('default=', '').trim();
				continue;
			}

			// 数据类型 
			switch (arr[i].toLowerCase()) {
				case 'int':
				case 'digit':
					dataType = 'Number';
					break;
				case 'array':
				case 'arr':
					dataType = 'Array';
					break;
				case 'object':
				case 'obj':
					dataType = 'Object';
					break;
				case 'bool':
				case 'boolean':
					dataType = 'Boolean';
					break;
			}
		}

		// 校验 
		let formName = (CHECK_SOURCE == 'admin') ? key : arr[0]; // 表单名  admin/client

		// 取值
		let val = data[formName];

		switch (dataType) {
			case 'Array': {
				if (defVal !== undefined) {
					try {
						defVal = JSON.parse(defVal);

						if (getDataType(defVal) != Array)
							return _showError(desc + '默认值数组格式错误', formName, that);
					} catch (ex) {
						return _showError(desc + '默认值数组格式错误', formName, that);
					}
				}
				if (val === null || val === undefined) val = defVal;

				if (val !== undefined && getDataType(val) != Array)
					return _showError(desc + '数组格式错误', formName, that);

				break;
			}
			case 'Object': {
				if (defVal !== undefined) {
					try {
						defVal = JSON.parse(defVal);

						if (getDataType(defVal) != Object)
							return _showError(desc + '默认值对象格式错误', formName, that);
					} catch (ex) {
						return _showError(desc + '默认值对象格式错误', formName, that);
					}
				}
				if (val === null || val === undefined) val = defVal;

				if (val !== undefined && getDataType(val) != Object)
					return _showError(desc + '对象格式错误', formName, that);

				break;
			}
			case 'Boolean': {
				if (defVal !== undefined) {
					try {
						defVal = JSON.parse(defVal);

						if (getDataType(defVal) != Boolean)
							return _showError(desc + '默认值布尔格式错误', formName, that);
					} catch (ex) {
						return _showError(desc + '默认值布尔格式错误');
					}
				}
				if (val === null || val === undefined) val = defVal;

				if (val !== undefined && getDataType(val) != Boolean)
					return _showError(desc + '布尔格式错误', formName, that);

				break;
			}
			case 'Number': {
				if (checkDigit(defVal, desc + '默认值'))
					return _showError(desc + '默认值格式错误', formName, that);

				if (val === null || val === undefined) val = defVal;

				if (val === undefined) break;

				if (val === '') //数字不能为空
					return _showError(desc + '不能为空', formName, that);

				let dataType = getDataType(val);
				if (dataType == Object || dataType == Boolean || dataType == Array)
					return _showError(desc + '必须为数字格式', formName, that);

				// 数字格式校验
				let result = checkDigit(val, desc);
				if (result) return _showError(result, formName, that);

				val = Number(val);

				break;
			}
			case 'String': {
				let dataType = getDataType(val);
				if (dataType == Object || dataType == Boolean || dataType == Array)
					return _showError(desc + '必须为字符串格式', formName, that);

				if (val === null || val === undefined) val = defVal;

				if (val === undefined) break;

				try {
					val = String(val).trim(); // 数字会被转为字符串
				} catch (ex) {
					return _showError(desc + '必须为字符串格式', formName, that);
				}
				break;
			}
		}

		returnData[key] = val;

		let fromStep = (CHECK_SOURCE == 'admin') ? 0 : 1; //admin/client
		for (let i = fromStep; i < arr.length; i++) {
			let result = '';

			let rules = arr[i].split(':');
			let ruleName = rules[0];

			// 空 且非必填的 不校验 
			if (ruleName != 'must' && val === undefined) continue;

			switch (ruleName) {
				case 'must':
					result = checkRequired(val, desc);
					break;
				case 'str':
				case 'string':
					result = checkString(val, desc);
					break;
				case 'arr':
				case 'array':
					result = checkArray(val, desc);
					break;
				case 'obj':
				case 'object':
					result = checkObject(val, desc);
					break;
				case 'bool':
				case 'boolean':
					result = checkBoolean(val, desc);
					break;
				case 'money':
					result = checkMoney(val, desc);
					break;
				case 'year':
					result = checkYear(val, desc);
					break;
				case 'yearmonth':
					result = checkYearMonth(val, desc);
					break;
				case 'date':
					result = checkDate(val, desc);
					break;
				case 'time':
					result = checkTime(val, desc);
					break;
				case 'hourminute':
					result = checkHourMinute(val, desc);
					break;
				case 'datetime':
					result = checkDatimeTime(val, desc);
					break;
				case 'min':
					result = checkMin(val, Number(rules[1]), desc);
					break;
				case 'max':
					result = checkMax(val, Number(rules[1]), desc);
					break;
				case 'len':
					result = checkLen(val, Number(rules[1]), desc);
					break;
				case 'in':
					result = checkIn(val, rules[1], desc);
					break;
				case 'email':
					result = checkEmail(val, desc);
					break;
				case 'mobile':
					result = checkMobile(val, desc);
					break;
				case 'int': // 正整数  
					result = checkInt(val, desc);
					break;
				case 'digit': // 正小整数
					result = checkDigit(val, desc);
					break;
				case 'id':
					result = checkId(val, desc);
					break;
				case 'letter':
					result = checkLetter(val, desc);
					break;
				case 'letter_num':
					result = checkLetterNum(val, desc);
					break;
			}

			if (result) {
				_showError(result, formName, that);
				return false;
			} else {

				if (that) {
					if (CHECK_SOURCE == 'client') {
						// 删除原有的自动聚焦 //admin/client
						if (isDefined(that.data[formName + 'Focus'])) {
							that.setData({ //TODO delete?
								[formName + 'Focus']: false
							});
						}
					}
				}
			}

		}
	}
	return returnData;
}

function _showError(result, formName, that) { //admin/client
	if (CHECK_SOURCE == 'client') {
		wx.showModal({
			title: '温馨提示',
			content: result,
			showCancel: false,
			success(res) {
				// 自动聚焦
				if (that) {
					pageHelper.anchor(formName, that);

					that.setData({
						[formName + 'Focus']: result,
					});
				}

			}
		});
	} else {
		throw new AppError(result, appCode.DATA);
	}

}

module.exports = {
	check,

	checkString,
	checkArray,
	checkObject,
	checkMoney,
	checkYear,
	checkYearMonth,
	checkDate,
	checkTime,
	checkHourMinute,
	checkDatimeTime,
	checkMin,
	checkMax,
	checkLen,
	checkIn,
	checkEmail,
	checkMobile,
	checkInt, // 正小整数
	checkDigit,
	checkId,
	checkLetter,
	checkLetterNum,

}

================================================
FILE: cloudfunctions/mcloud/index.js
================================================
const application = require('./framework/core/application.js');

// 云函数入口函数
exports.main = async (event, context) => {
	return await application.app(event, context);
}

================================================
FILE: cloudfunctions/mcloud/package.json
================================================
{
    "name": "cloud",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "",
    "license": "ISC",
    "dependencies": {
        "date-utils": "^1.2.21",
        "mysql": "^2.18.1",
        "node-xlsx": "^0.16.1",
        "wx-server-sdk": "~2.1.2"
    }
}


================================================
FILE: cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_album_controller.js
================================================
/**
 * Notes: 相册模块后台管理-控制器
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2021-07-11 10:20:00 
 */

const BaseProjectAdminController = require('./base_project_admin_controller.js');

const AdminAlbumService = require('../../service/admin/admin_album_service.js');

const timeUtil = require('../../../../framework/utils/time_util.js');
const contentCheck = require('../../../../framework/validate/content_check.js');
const AlbumModel = require('../../model/album_model.js');

class AdminAlbumController extends BaseProjectAdminController {

	/** 置顶与排序设定 */
	async sortAlbum() {
		await this.isAdmin();

		let rules = {
			id: 'must|id',
			sort: 'must|int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminAlbumService();
		await service.sortAlbum(input.id, input.sort);
	}

	/** 首页设定 */
	async vouchAlbum() {
		await this.isAdmin();

		let rules = {
			id: 'must|id',
			vouch: 'must|int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminAlbumService();
		await service.vouchAlbum(input.id, input.vouch);
	}

	/** 状态修改 */
	async statusAlbum() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
			status: 'must|int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminAlbumService();
		await service.statusAlbum(input.id, input.status);

	}

	/** 列表 */
	async getAdminAlbumList() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			search: 'string|min:1|max:30|name=搜索条件',
			sortType: 'string|name=搜索类型',
			sortVal: 'name=搜索类型值',
			orderBy: 'object|name=排序',
			whereEx: 'object|name=附加查询条件',
			page: 'must|int|default=1',
			size: 'int',
			isTotal: 'bool',
			oldTotal: 'int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminAlbumService();
		let result = await service.getAdminAlbumList(input);

		// 数据格式化
		let list = result.list;
		for (let k = 0; k < list.length; k++) {
			list[k].ALBUM_ADD_TIME = timeUtil.timestamp2Time(list[k].ALBUM_ADD_TIME, 'Y-M-D h:m:s');

			if (list[k].ALBUM_OBJ && list[k].ALBUM_OBJ.detail)
				delete list[k].ALBUM_OBJ.detail;
		}
		result.list = list;

		return result;

	}


	/** 发布 */
	async insertAlbum() {
		await this.isAdmin();

		// 数据校验 
		let rules = {
			title: 'must|string|min:2|max:50|name=标题',
			cateId: 'must|string|name=分类',
			cateName: 'must|string|name=分类名称',
			order: 'must|int|min:0|max:9999|name=排序号',
			forms: 'array|name=表单',
		};


		// 取得数据
		let input = this.validateData(rules);

		// 内容审核
		await contentCheck.checkTextMultiAdmin(input);

		let service = new AdminAlbumService();
		let result = await service.insertAlbum(input);

		this.logOther('添加了《' + input.title + '》');

		return result;

	}


	/** 获取信息用于编辑修改 */
	async getAlbumDetail() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminAlbumService();
		return await service.getAlbumDetail(input.id);

	}

	/** 编辑 */
	async editAlbum() {
		await this.isAdmin();

		let rules = {
			id: 'must|id',
			title: 'must|string|min:2|max:50|name=标题',
			cateId: 'must|string|name=分类',
			cateName: 'must|string|name=分类名称',
			order: 'must|int|min:0|max:9999|name=排序号',
			forms: 'array|name=表单',
		};

		// 取得数据
		let input = this.validateData(rules);

		// 内容审核
		await contentCheck.checkTextMultiAdmin(input);

		let service = new AdminAlbumService();
		let result = service.editAlbum(input);

		this.logOther('修改了《' + input.title + '》');

		return result;
	}

	/** 删除 */
	async delAlbum() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
		};

		// 取得数据
		let input = this.validateData(rules);

		let title = await AlbumModel.getOneField(input.id, 'ALBUM_TITLE');

		let service = new AdminAlbumService();
		await service.delAlbum(input.id);

		if (title)
			this.logOther('删除了《' + title + '》');

	}

	/** 更新图片信息 */
	async updateAlbumForms() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
			hasImageForms: 'array'
		};

		// 取得数据
		let input = this.validateData(rules);

		// 内容审核
		await contentCheck.checkTextMultiAdmin(input);

		let service = new AdminAlbumService();
		return await service.updateAlbumForms(input);
	}

}

module.exports = AdminAlbumController;

================================================
FILE: cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_home_controller.js
================================================
/**
 * Notes: 后台登录与首页模块
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2021-03-15 19:20:00 
 */

const BaseProjectAdminController = require('./base_project_admin_controller.js');
const AdminHomeService = require('../../service/admin/admin_home_service.js');

class AdminHomeController extends BaseProjectAdminController {


	// 管理首页 
	async adminHome() {
		await this.isAdmin();

		// 数据校验
		let rules = {

		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminHomeService();
		return await service.adminHome();
	}


	// 清除首页推荐
	async clearVouchData() {
		await this.isAdmin();

		// 数据校验
		let rules = {

		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminHomeService();
		return await service.clearVouchData();
	}

}

module.exports = AdminHomeController;

================================================
FILE: cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_meet_controller.js
================================================
/**
 * Notes: 预约模块后台管理-控制器
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2021-12-08 10:20:00 
 */

const BaseProjectAdminController = require('./base_project_admin_controller.js');
const AdminMeetService = require('../../service/admin/admin_meet_service.js');
const timeUtil = require('../../../../framework/utils/time_util.js');
const dataUtil = require('../../../../framework/utils/data_util.js'); 
const MeetModel = require('../../model/meet_model.js');
const contentCheck = require('../../../../framework/validate/content_check.js');

class AdminMeetController extends BaseProjectAdminController {

	// 计算可约天数
	_getLeaveDay(days) {
		let now = timeUtil.time('Y-M-D');
		let count = 0;
		for (let k = 0; k < days.length; k++) {
			if (days[k] >= now) count++;
		}
		return count;
	}

	async getDayList() {
		await this.isAdmin();

		let rules = {
			meetId: 'must|id',
			start: 'must|date',
			end: 'must|date',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMeetService();
		return await service.getDayList(input.meetId, input.start, input.end);
	}

	/** 生成自助签到码 */
	async genSelfCheckinQr() {
		await this.isAdmin();

		let rules = {
			page: 'must|string',
			timeMark: 'must|string',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMeetService();
		return await service.genSelfCheckinQr(input.page, input.timeMark);
	}

	/** 管理员按钮核销 */
	async checkinJoin() {
		await this.isAdmin();

		let rules = {
			joinId: 'must|id',
			flag: 'must|in:0,1'
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMeetService();
		await service.checkinJoin(input.joinId, input.flag);
	}

	/** 管理员扫码核验 */
	async scanJoin() {
		await this.isAdmin();

		let rules = {
			meetId: 'must|id',
			code: 'must|string|len:15',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMeetService();
		await service.scanJoin(input.meetId, input.code);
	}

	/** 预约排序 */
	async sortMeet() { // 数据校验
		await this.isAdmin();

		let rules = {
			meetId: 'must|id',
			sort: 'must|int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMeetService();
		await service.sortMeet(input.meetId, input.sort);
	}

	/** 首页设定 */
	async vouchMeet() {
		await this.isAdmin();

		let rules = {
			id: 'must|id',
			vouch: 'must|int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMeetService();
		await service.vouchMeet(input.id, input.vouch);
	}

	/** 预约状态修改 */
	async statusMeet() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			meetId: 'must|id',
			status: 'must|int|in:0,1,9,10',
		};

		// 取得数据
		let input = this.validateData(rules);

		let title = await MeetModel.getOneField(input.meetId, 'MEET_TITLE');

		let service = new AdminMeetService();
		await service.statusMeet(input.meetId, input.status);

		if (title)
			this.logOther('修改了预约《' + title + '》的状态为:' + MeetModel.getDesc('STATUS', input.status));
	}


	/** 报名状态修改 */
	async statusJoin() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			joinId: 'must|id',
			status: 'must|int|in:0,1,8,9,10,98,99',
			reason: 'string|max:200',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMeetService();
		return await service.statusJoin(this._admin, input.joinId, input.status, input.reason);
	}

	/** 报名删除 */
	async delJoin() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			joinId: 'must|id'
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMeetService();
		return await service.delJoin(input.joinId);
	}

	/** 预约项目列表 */
	async getAdminMeetList() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			search: 'string|min:1|max:30|name=搜索条件',
			sortType: 'string|name=搜索类型',
			sortVal: 'name=搜索类型值',
			orderBy: 'object|name=排序',
			whereEx: 'object|name=附加查询条件',
			page: 'must|int|default=1',
			size: 'int|default=10',
			isTotal: 'bool',
			oldTotal: 'int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMeetService();
		let result = await service.getAdminMeetList(input);

		// 数据格式化
		let list = result.list;
		for (let k = 0; k < list.length; k++) {

			list[k].MEET_ADD_TIME = timeUtil.timestamp2Time(list[k].MEET_ADD_TIME);
			list[k].MEET_EDIT_TIME = timeUtil.timestamp2Time(list[k].MEET_EDIT_TIME);
			list[k].leaveDay = this._getLeaveDay(list[k].MEET_DAYS);

		}
		result.list = list;

		return result;

	}

	/** 预约名单列表 */
	async getJoinList() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			search: 'string|min:1|max:30|name=搜索条件',
			sortType: 'string|name=搜索类型',
			sortVal: 'name=搜索类型值',
			orderBy: 'object|name=排序',
			meetId: 'must|id',
			mark: 'must|string',
			page: 'must|int|default=1',
			size: 'int|default=10',
			isTotal: 'bool',
			oldTotal: 'int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMeetService();
		let result = await service.getJoinList(input);

		// 数据格式化
		let list = result.list;
		for (let k = 0; k < list.length; k++) {
			list[k].JOIN_EDIT_TIME = timeUtil.timestamp2Time(list[k].JOIN_EDIT_TIME);

			//分解成数组,高亮显示
			let forms = list[k].JOIN_FORMS;
			for (let j in forms) {
				forms[j].valArr = dataUtil.splitTextByKey(forms[j].val, input.search);
			}

		}
		result.list = list;

		return result;

	}

	/** 发布 */
	async insertMeet() {
		await this.isAdmin();

		let rules = {
			title: 'must|string|min:2|max:50|name=标题',
			typeId: 'must|id|name=分类',
			typeName: 'must|string|name=分类',
			order: 'must|int|min:0|max:9999|name=排序号',
			daysSet: 'must|array|name=预约时间设置',
			isShowLimit: 'must|int|in:0,1|name=是否显示可预约人数',

			formSet: 'must|array|name=用户资料设置',
		};

		// 取得数据
		let input = this.validateData(rules);

		// 内容审核
		await contentCheck.checkTextMultiAdmin(input);

		let service = new AdminMeetService();
		let result = await service.insertMeet(this._adminId, input);
 

		this.logOther('创建了新预约《' + input.title + '》');

		return result;

	}


	/** 获取预约信息用于编辑修改 */
	async getMeetDetail() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMeetService();
		let detail = await service.getMeetDetail(input.id);
		return detail;
	}

	/** 编辑预约 */
	async editMeet() {
		await this.isAdmin();

		let rules = {
			id: 'must|id',
			title: 'must|string|min:2|max:50|name=标题',
			typeId: 'must|id|name=分类',
			typeName: 'must|string|name=分类',
			order: 'must|int|min:0|max:9999|name=排序号',
			daysSet: 'must|array|name=预约时间设置',

			isShowLimit: 'must|int|in:0,1|name=是否显示可预约人数',

			formSet: 'must|array|name=用户资料设置',
		};

		// 取得数据
		let input = this.validateData(rules);

		// 内容审核
		await contentCheck.checkTextMultiAdmin(input);

		let service = new AdminMeetService();
		let result = service.editMeet(input);
 

		this.logOther('修改了预约《' + input.title + '》');

		return result;
	}

	/** 删除预约 */
	async delMeet() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			meetId: 'must|id',
		};

		// 取得数据
		let input = this.validateData(rules);

		let title = await MeetModel.getOneField(input.meetId, 'MEET_TITLE');

		let service = new AdminMeetService();
		await service.delMeet(input.meetId);
 

		if (title)
			this.logOther('删除了预约《' + title + '》');
	}

	/**
	 * 更新富文本信息
	 * @returns 返回 urls数组 [url1, url2, url3, ...]
	 */
	async updateMeetContent() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
			content: 'array'
		};

		// 取得数据
		let input = this.validateData(rules);

		// 内容审核
		await contentCheck.checkTextMultiAdmin(input);

		let service = new AdminMeetService();
		return await service.updateMeetContent(input);
	}


	/**
	 * 更新封面设置
	 * @returns 返回 urls数组 [url1, url2, url3, ...]
	 */
	async updateMeetStyleSet() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			meetId: 'must|id',
			styleSet: 'object'
		};

		// 取得数据
		let input = this.validateData(rules);

		// 内容审核
		await contentCheck.checkTextMultiAdmin(input);
 

		let service = new AdminMeetService();
		return await service.updateMeetStyleSet(input);
	}

	// 删除某时段预约记录
	async cancelJoinByTimeMark() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			meetId: 'must|id',
			timeMark: 'must|string',
			reason: 'string'
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMeetService();
		return await service.cancelJoinByTimeMark(this._admin, input.meetId, input.timeMark, input.reason);
	}

	/** 创建模板 */
	async insertMeetTemp() {
		await this.isAdmin();

		let rules = {
			name: 'must|string|min:1|max:20|name=名称',
			times: 'must|array|name=模板时段',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMeetService();
		let result = await service.insertMeetTemp(input);

		return result;

	}

	/** 编辑模板 */
	async editMeetTemp() {
		await this.isAdmin();

		let rules = {
			id: 'must|id',
			isLimit: 'must|bool|name=是否限制',
			limit: 'must|int|name=人数上限',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMeetService();
		let result = service.editMeetTemp(input);

		return result;
	}

	/** 模板列表 */
	async getMeetTempList() {
		await this.isAdmin();

		let service = new AdminMeetService();
		let result = await service.getMeetTempList();

		return result;
	}

	/** 删除模板 */
	async delMeetTemp() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMeetService();
		await service.delMeetTemp(input.id);

	}


	/**************报名数据导出 BEGIN ********************* */
	/** 当前是否有导出文件生成 */
	async joinDataGet() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			isDel: 'int|must', //是否删除已有记录
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMeetService();

		if (input.isDel === 1)
			await service.deleteJoinDataExcel(); //先删除

		return await service.getJoinDataURL();
	}

	/** 导出数据 */
	async joinDataExport() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			meetId: 'id|must',
			startDay: 'date|must',
			endDay: 'date|must',
			status: 'int|must|default=1'
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMeetService();
		return await service.exportJoinDataExcel(input);
	}

	/** 删除导出的报名数据文件 */
	async joinDataDel() {
		await this.isAdmin();

		// 数据校验
		let rules = {};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMeetService();
		return await service.deleteJoinDataExcel();
	}


}

module.exports = AdminMeetController;

================================================
FILE: cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_mgr_controller.js
================================================
/**
 * Notes: 管理员控制模块
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2021-07-11 10:20:00 
 */

const BaseProjectAdminController = require('./base_project_admin_controller.js');
const LogModel = require('../../../../framework/platform/model/log_model.js');

const AdminMgrService = require('../../service/admin/admin_mgr_service.js');
const timeUtil = require('../../../../framework/utils/time_util.js');
const contentCheck = require('../../../../framework/validate/content_check.js');

class AdminMgrController extends BaseProjectAdminController {
	// 管理员登录  
	async adminLogin() {

		// 数据校验
		let rules = {
			name: 'must|string|min:5|max:30|name=管理员名',
			pwd: 'must|string|min:5|max:30|name=密码',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMgrService();
		return await service.adminLogin(input.name, input.pwd);
	}

	/** 删除管理员 */
	async delMgr() {
		await this.isSuperAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMgrService();
		await service.delMgr(input.id, this._adminId);

	}

	/** 管理员状态修改 */
	async statusMgr() {
		await this.isSuperAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
			status: 'must|int|in:0,1',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMgrService();
		await service.statusMgr(input.id, input.status, this._admin.ADMIN_PHONE);
	}

	/** 管理员列表 */
	async getMgrList() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			search: 'string|min:1|max:30|name=搜索条件',
			sortType: 'string|name=搜索类型',
			sortVal: 'name=搜索类型值',
			orderBy: 'object|name=排序',
			whereEx: 'object|name=附加查询条件',
			page: 'must|int|default=1',
			size: 'int|default=10',
			isTotal: 'bool',
			oldTotal: 'int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMgrService();
		let result = await service.getMgrList(input);

		// 数据格式化
		let list = result.list;
		for (let k = 0; k < list.length; k++) {
			list[k].ADMIN_EDIT_TIME = timeUtil.timestamp2Time(list[k].ADMIN_EDIT_TIME);
			list[k].ADMIN_LOGIN_TIME = (list[k].ADMIN_LOGIN_TIME == 0) ? '未登录' : timeUtil.timestamp2Time(list[k].ADMIN_LOGIN_TIME);
		}
		result.list = list;
		return result;
	}

	/** 添加管理员 */
	async insertMgr() {
		await this.isSuperAdmin();

		// 数据校验
		let rules = {
			name: 'must|string|min:5|max:30|name=账号',
			desc: 'must|string|max:30|name=姓名',
			phone: 'string|len:11|name=手机',
			password: 'must|string|min:6|max:30|name=密码',
		};

		// 取得数据
		let input = this.validateData(rules);

		// 内容审核
		await contentCheck.checkTextMultiAdmin(input);

		let service = new AdminMgrService();
		await service.insertMgr(input);
	}

	/** 修改管理员 */
	async editMgr() {
		await this.isSuperAdmin();

		// 数据校验
		let rules = {
			id: 'must|id|name=id',
			name: 'must|string|min:5|max:30|name=账号',
			desc: 'must|string|max:30|name=姓名',
			phone: 'string|len:11|name=手机',
			password: 'string|min:6|max:30|name=新密码',

		};

		// 取得数据
		let input = this.validateData(rules);

		// 内容审核
		await contentCheck.checkTextMultiAdmin(input);

		let service = new AdminMgrService();
		await service.editMgr(input.id, input);
	}

	/** 修改自己的密码 */
	async pwdMgr() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			oldPassword: 'must|string|min:6|max:30|name=旧密码',
			password: 'must|string|min:6|max:30|name=新密码',
			password2: 'must|string|min:6|max:30|name=新密码再次填写',

		};

		// 取得数据
		let input = this.validateData(rules);

		// 内容审核
		await contentCheck.checkTextMultiAdmin(input);

		let service = new AdminMgrService();
		await service.pwdtMgr(this._adminId, input.oldPassword, input.password);
	}

	/** 获取管理员信息用于编辑修改 */
	async getMgrDetail() {
		await this.isSuperAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMgrService();
		return await service.getMgrDetail(input.id);

	} 

	async clearLog() {
		await this.isAdmin();

		let service = new AdminMgrService();
		return await service.clearLog();

	}

	async getLogList() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			search: 'string|min:1|max:30|name=搜索条件',
			sortType: 'string|name=搜索类型',
			sortVal: 'name=搜索类型值',
			orderBy: 'object|name=排序',
			whereEx: 'object|name=附加查询条件',
			page: 'must|int|default=1',
			size: 'int',
			isTotal: 'bool',
			oldTotal: 'int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminMgrService();
		let result = await service.getLogList(input);

		// 数据格式化
		let list = result.list;
		for (let k = 0; k < list.length; k++) {
			list[k].LOG_TYPE_DESC = LogModel.getDesc('TYPE', list[k].LOG_TYPE);
			list[k].LOG_ADD_TIME = timeUtil.timestamp2Time(list[k].LOG_ADD_TIME);
		}
		result.list = list;

		return result;

	}
}

module.exports = AdminMgrController;

================================================
FILE: cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_news_controller.js
================================================
/**
 * Notes: 资讯模块后台管理-控制器
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2021-07-11 10:20:00 
 */

const BaseProjectAdminController = require('./base_project_admin_controller.js');

const AdminNewsService = require('../../service/admin/admin_news_service.js');

const timeUtil = require('../../../../framework/utils/time_util.js');
const contentCheck = require('../../../../framework/validate/content_check.js');
const NewsModel = require('../../model/news_model.js');

class AdminNewsController extends BaseProjectAdminController {

	/** 置顶与排序设定 */
	async sortNews() {
		await this.isAdmin();

		let rules = {
			id: 'must|id',
			sort: 'must|int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminNewsService();
		await service.sortNews(input.id, input.sort);
	}

	/** 首页设定 */
	async vouchNews() {
		await this.isAdmin();

		let rules = {
			id: 'must|id',
			vouch: 'must|int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminNewsService();
		await service.vouchNews(input.id, input.vouch);
	}

	/** 资讯状态修改 */
	async statusNews() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
			status: 'must|int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminNewsService();
		await service.statusNews(input.id, input.status);

	}

	/** 资讯列表 */
	async getAdminNewsList() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			search: 'string|min:1|max:30|name=搜索条件',
			sortType: 'string|name=搜索类型',
			sortVal: 'name=搜索类型值',
			orderBy: 'object|name=排序',
			whereEx: 'object|name=附加查询条件',
			page: 'must|int|default=1',
			size: 'int',
			isTotal: 'bool',
			oldTotal: 'int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminNewsService();
		let result = await service.getAdminNewsList(input);

		// 数据格式化
		let list = result.list;
		for (let k = 0; k < list.length; k++) {
			list[k].NEWS_ADD_TIME = timeUtil.timestamp2Time(list[k].NEWS_ADD_TIME, 'Y-M-D h:m');
			list[k].NEWS_EDIT_TIME = timeUtil.timestamp2Time(list[k].NEWS_EDIT_TIME, 'Y-M-D h:m');

			if (list[k].NEWS_OBJ && list[k].NEWS_OBJ.desc)
				delete list[k].NEWS_OBJ.desc;
		}
		result.list = list;

		return result;

	}

	/**
	 * 更新富文本信息
	 */
	async updateNewsContent() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
			content: 'array'
		};

		// 取得数据
		let input = this.validateData(rules);

			// 内容审核
			await contentCheck.checkTextMultiAdmin(input);

		let service = new AdminNewsService();
		return await service.updateNewsContent(input);
	}


	/** 发布资讯信息 */
	async insertNews() {
		await this.isAdmin();

		// 数据校验 
		let rules = {
			title: 'must|string|min:4|max:50|name=标题',
			cateId: 'must|string|name=分类',
			cateName: 'must|string|name=分类名',
			order: 'must|int|min:0|max:9999|name=排序号',
			desc: 'must|string|min:10|max:200|name=简介',
			forms: 'array|name=表单',
		};


		// 取得数据
		let input = this.validateData(rules);

		// 内容审核
		await contentCheck.checkTextMultiAdmin(input);

		let service = new AdminNewsService();
		let result = await service.insertNews(input);

		this.logNews('添加了文章《' + input.title + '》');

		return result;

	}


	/** 获取资讯信息用于编辑修改 */
	async getNewsDetail() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
		};

		// 取得数据
		let input = this.validateData(rules);

		// 内容审核
		await contentCheck.checkTextMultiAdmin(input);

		let service = new AdminNewsService();
		return await service.getNewsDetail(input.id);

	}

	/** 编辑资讯 */
	async editNews() {
		await this.isAdmin();

		let rules = {
			id: 'must|id',
			title: 'must|string|min:4|max:50|name=标题',
			cateId: 'must|string|name=分类',
			cateName: 'must|string|name=分类',
			order: 'must|int|min:0|max:9999|name=排序号',
			desc: 'string|min:10|max:200|name=简介',
			forms: 'array|name=表单',
		};

		// 取得数据
		let input = this.validateData(rules);

		// 内容审核
		await contentCheck.checkTextMultiAdmin(input);

		let service = new AdminNewsService();
		let result = service.editNews(input);

		this.logNews('修改了文章《' + input.title + '》');

		return result;
	}

	/** 删除资讯 */
	async delNews() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
		};

		// 取得数据
		let input = this.validateData(rules);

		let title = await NewsModel.getOneField(input.id, 'NEWS_TITLE');

		let service = new AdminNewsService();
		await service.delNews(input.id);

		if (title)
			this.logNews('删除了文章《' + title + '》');

	}

	/**
	 * 更新图片信息
	 * @returns 返回 urls数组 [url1, url2, url3, ...]
	 */
	async updateNewsPic() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
			imgList: 'array'
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminNewsService();
		return await service.updateNewsPic(input);
	}

	/** 更新图片信息 */
	async updateNewsForms() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
			hasImageForms: 'array'
		};

		// 取得数据
		let input = this.validateData(rules);

		// 内容审核
		await contentCheck.checkTextMultiAdmin(input);

		let service = new AdminNewsService();
		return await service.updateNewsForms(input);
	}

}

module.exports = AdminNewsController;

================================================
FILE: cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_product_controller.js
================================================
/**
 * Notes: 产品模块后台管理-控制器
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2021-07-11 10:20:00 
 */

const BaseProjectAdminController = require('./base_project_admin_controller.js');

const AdminProductService = require('../../service/admin/admin_product_service.js');

const timeUtil = require('../../../../framework/utils/time_util.js');
const dataUtil = require('../../../../framework/utils/data_util.js');
const contentCheck = require('../../../../framework/validate/content_check.js');
const ProductModel = require('../../model/product_model.js');

class AdminProductController extends BaseProjectAdminController {

	/** 置顶与排序设定 */
	async sortProduct() {
		await this.isAdmin();

		let rules = {
			id: 'must|id',
			sort: 'must|int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminProductService();
		await service.sortProduct(input.id, input.sort);
	}

	/** 首页设定 */
	async vouchProduct() {
		await this.isAdmin();

		let rules = {
			id: 'must|id',
			vouch: 'must|int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminProductService();
		await service.vouchProduct(input.id, input.vouch);
	}

	/** 状态修改 */
	async statusProduct() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
			status: 'must|int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminProductService();
		await service.statusProduct(input.id, input.status);

	}

	/** 列表 */
	async getAdminProductList() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			search: 'string|min:1|max:30|name=搜索条件',
			sortType: 'string|name=搜索类型',
			sortVal: 'name=搜索类型值',
			orderBy: 'object|name=排序',
			whereEx: 'object|name=附加查询条件',
			page: 'must|int|default=1',
			size: 'int',
			isTotal: 'bool',
			oldTotal: 'int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminProductService();
		let result = await service.getAdminProductList(input);

		// 数据格式化
		let list = result.list;
		for (let k = 0; k < list.length; k++) {
			list[k].PRODUCT_ADD_TIME = timeUtil.timestamp2Time(list[k].PRODUCT_ADD_TIME, 'Y-M-D h:m:s');   

			if (list[k].PRODUCT_OBJ && list[k].PRODUCT_OBJ.desc)
				delete list[k].PRODUCT_OBJ.desc;
		}
		result.list = list;

		return result;

	}


	/** 发布 */
	async insertProduct() {
		await this.isAdmin();

		// 数据校验 
		let rules = {
			title: 'must|string|min:2|max:50|name=标题',
			cateId: 'must|string|name=分类',
			cateName: 'must|string|name=分类名称',
			order: 'must|int|min:0|max:9999|name=排序号',
			forms: 'array|name=表单',
		};


		// 取得数据
		let input = this.validateData(rules);

		// 内容审核
		await contentCheck.checkTextMultiAdmin(input);

		let service = new AdminProductService();
		let result = await service.insertProduct(input);

		this.logOther('添加了《' + input.title + '》');

		return result;

	}


	/** 获取信息用于编辑修改 */
	async getProductDetail() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminProductService();
		return await service.getProductDetail(input.id);

	}

	/** 编辑 */
	async editProduct() {
		await this.isAdmin();

		let rules = {
			id: 'must|id',
			title: 'must|string|min:2|max:50|name=标题',
			cateId: 'must|string|name=分类',
			cateName: 'must|string|name=分类名称',
			order: 'must|int|min:0|max:9999|name=排序号',
			forms: 'array|name=表单',
		};

		// 取得数据
		let input = this.validateData(rules);

		// 内容审核
		await contentCheck.checkTextMultiAdmin(input);

		let service = new AdminProductService();
		let result = service.editProduct(input);

		this.logOther('修改了《' + input.title + '》');

		return result;
	}

	/** 删除 */
	async delProduct() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
		};

		// 取得数据
		let input = this.validateData(rules);

		let title = await ProductModel.getOneField(input.id, 'PRODUCT_TITLE');

		let service = new AdminProductService();
		await service.delProduct(input.id);

		if (title)
			this.logOther('删除了《' + title + '》');

	}

	/** 更新图片信息 */
	async updateProductForms() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
			hasImageForms: 'array'
		};

		// 取得数据
		let input = this.validateData(rules);

		// 内容审核
		await contentCheck.checkTextMultiAdmin(input);

		let service = new AdminProductService();
		return await service.updateProductForms(input);
	}

}

module.exports = AdminProductController;

================================================
FILE: cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_setup_controller.js
================================================
/**
 * Notes: 设置控制模块
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2021-07-11 10:20:00 
 */

const BaseProjectAdminController = require('./base_project_admin_controller.js');
const AdminSetupService = require('../../service/admin/admin_setup_service.js');
const contentCheck = require('../../../../framework/validate/content_check.js');

class AdminSetupController extends BaseProjectAdminController {

	// 通用setup
	async setSetup() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			key: 'must|string|name=KEY',
			content: 'name=内容',
		};

		// 取得数据
		let input = this.validateData(rules);

		// 内容审核
		await contentCheck.checkTextMultiAdmin(input);

		let service = new AdminSetupService();
		await service.setSetup(input.key, input.content);
	}

	// 富文本setup
	async setContentSetup() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			id: 'must|string|name=KEY',
			content: 'must|array|name=内容'
		};

		// 取得数据
		let input = this.validateData(rules);

		// 内容审核
		await contentCheck.checkTextMultiAdmin(input);

		let service = new AdminSetupService();
		await service.setSetup(input.id, input.content, 'content');
	}

	async genMiniQr() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			path: 'must|string',
			sc: 'string',
		};

		// 取得数据
		let input = this.validateData(rules);


		let service = new AdminSetupService();
		return await service.genMiniQr(input.path, input.sc);
	}
}

module.exports = AdminSetupController;

================================================
FILE: cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_user_controller.js
================================================
/**
 * Notes: 用户控制模块
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2022-01-22 10:20:00 
 */

const BaseProjectAdminController = require('./base_project_admin_controller.js');

const UserModel = require('../../model/user_model.js');
const AdminUserService = require('../../service/admin/admin_user_service.js');
const timeUtil = require('../../../../framework/utils/time_util.js');

class AdminUserController extends BaseProjectAdminController {


	/** 用户信息 */
	async getUserDetail() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminUserService();
		let user = await service.getUser({
			userId: input.id
		});

		if (user) {
			// 显示转换  
			user.USER_ADD_TIME = timeUtil.timestamp2Time(user.USER_ADD_TIME);
			user.USER_LOGIN_TIME = user.USER_LOGIN_TIME ? timeUtil.timestamp2Time(user.USER_LOGIN_TIME) : '未登录';
		}

		return user;
	}


	/** 用户列表 */
	async getUserList() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			search: 'string|min:1|max:30|name=搜索条件',
			sortType: 'string|name=搜索类型',
			sortVal: 'name=搜索类型值',
			orderBy: 'object|name=排序',
			whereEx: 'object|name=附加查询条件',
			page: 'must|int|default=1',
			size: 'int',
			isTotal: 'bool',
			oldTotal: 'int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminUserService();
		let result = await service.getUserList(input);

		// 数据格式化
		let list = result.list;
		for (let k = 0; k < list.length; k++) {
			list[k].USER_STATUS_DESC = UserModel.getDesc('STATUS', list[k].USER_STATUS);
			list[k].USER_ADD_TIME = timeUtil.timestamp2Time(list[k].USER_ADD_TIME);
			list[k].USER_LOGIN_TIME = list[k].USER_LOGIN_TIME ? timeUtil.timestamp2Time(list[k].USER_LOGIN_TIME) : '未登录';

		}
		result.list = list;
		return result;
	}

	/** 删除用户 */
	async delUser() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
		};

		// 取得数据
		let input = this.validateData(rules);

		let title = await UserModel.getOneField({ USER_MINI_OPENID: input.id }, 'USER_NAME');

		let service = new AdminUserService();
		await service.delUser(input.id);

		if (title)
			this.logUser('删除了用户「' + title + '」');

	}

	async statusUser() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			id: 'must|id',
			status: 'must|int',
			reason: 'string'
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminUserService();
		await service.statusUser(input.id, input.status, input.reason);
	}

	/************** 用户数据导出 BEGIN ********************* */
	/** 当前是否有导出文件生成 */
	async userDataGet() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			isDel: 'int|must', //是否删除已有记录
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminUserService();

		if (input.isDel === 1)
			await service.deleteUserDataExcel(); //先删除 

		return await service.getUserDataURL();
	}

	/** 导出数据 */
	async userDataExport() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			condition: 'string|name=导出条件',
			fields: 'array',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminUserService();
		return await service.exportUserDataExcel(input.condition, input.fields);
	}

	/** 删除导出的用户数据 */
	async userDataDel() {
		await this.isAdmin();

		// 数据校验
		let rules = {};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminUserService();
		return await service.deleteUserDataExcel();
	}
}

module.exports = AdminUserController;

================================================
FILE: cloudfunctions/mcloud/project/TRIP1/controller/admin/base_project_admin_controller.js
================================================
/**
 * Notes: 后台管理控制模块
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2021-03-15 19:20:00 
 */

const BaseAdminController = require('../../../../framework/platform/controller/base_admin_controller.js');
const BaseProjectService = require('../../service/base_project_service.js');

class BaseProjectAdminController extends BaseAdminController {
	// TODO
	async initSetup() {
		let service = new BaseProjectService();
		await service.initSetup();
	}

}

module.exports = BaseProjectAdminController;

================================================
FILE: cloudfunctions/mcloud/project/TRIP1/controller/album_controller.js
================================================
/**
 * Notes: 相册模块控制器
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2022-06-07 04:00:00 
 */

const BaseProjectController = require('./base_project_controller.js');
const AlbumService = require('../service/album_service.js');
const timeUtil = require('../../../framework/utils/time_util.js');

class AlbumController extends BaseProjectController { 

	/** 列表 */
	async getAlbumList() {

		// 数据校验
		let rules = {
			search: 'string|min:1|max:30|name=搜索条件',
			sortType: 'string|name=搜索类型',
			sortVal: 'name=搜索类型值',
			orderBy: 'object|name=排序', 
			page: 'must|int|default=1',
			size: 'int',
			isTotal: 'bool',
			oldTotal: 'int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AlbumService();
		let result = await service.getAlbumList(input);

		// 数据格式化
		let list = result.list;

		for (let k = 0; k < list.length; k++) {
			list[k].ALBUM_ADD_TIME = timeUtil.timestamp2Time(list[k].ALBUM_ADD_TIME, 'Y-M-D');

			if (list[k].ALBUM_OBJ && list[k].ALBUM_OBJ.detail)
			delete list[k].ALBUM_OBJ.detail;
		} 

		return result;

	}


	/** 浏览详细 */
	async viewAlbum() {
		// 数据校验
		let rules = {
			id: 'must|id',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AlbumService();
		let album = await service.viewAlbum(input.id);

		if (album) {
			// 显示转换 
			album.ALBUM_ADD_TIME = timeUtil.timestamp2Time(album.ALBUM_ADD_TIME, 'Y-M-D');
		}

		return album;
	} 

}

module.exports = AlbumController;

================================================
FILE: cloudfunctions/mcloud/project/TRIP1/controller/base_project_controller.js
================================================
/**
 * Notes: 本业务基本控制器
 * Date: 2021-03-15 19:20:00 
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 */

const BaseController = require('../../../framework/platform/controller/base_controller.js');
const BaseProjectService = require('../service/base_project_service.js');

class BaseProjectController extends BaseController {

	// TODO
	async initSetup() {
		let service = new BaseProjectService();
		await service.initSetup();
	}
}

module.exports = BaseProjectController;

================================================
FILE: cloudfunctions/mcloud/project/TRIP1/controller/check_controller.js
================================================
/**
 * Notes: 内容检测控制器
 * Date: 2021-03-15 19:20:00 
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 */

const BaseProjectController = require('./base_project_controller.js');
const contentCheck = require('../../framework/validate/content_check.js');

class CheckController extends BaseProjectController {

	/**
	 * 图片校验 
	 */
	async checkImg() {

		// 数据校验
		let rules = {
			img: 'name=img',
			mine: 'must|default=jpg',
		};

		// 取得数据
		let input = this.validateData(rules);

		return await contentCheck.checkImg(input.img, 'jpg');

	}

}

module.exports = CheckController;

================================================
FILE: cloudfunctions/mcloud/project/TRIP1/controller/fav_controller.js
================================================
/**
 * Notes: 预约模块控制器
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2021-12-10 04:00:00 
 */

const BaseProjectController = require('./base_project_controller.js');
const FavService = require('../service/fav_service.js');
const timeUtil = require('../../../framework/utils/time_util.js');

class FavController extends BaseProjectController {

	/** 更新某人收藏 */
	async updateFav() {
		// 数据校验
		let rules = {
			oid: 'id|must',
			title: 'string|must',
			type: 'string|must',
			path: 'string|must',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new FavService();
		return await service.updateFav(this._userId, input.oid, input.title, input.type, input.path);
	}


	/** 删除收藏 */
	async delFav() {
		// 数据校验
		let rules = {
			oid: 'id|must'
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new FavService();
		return await service.updateFav(this._userId, input.oid);
	}


	/** 是否收藏 */
	async isFav() {
		// 数据校验
		let rules = {
			oid: 'id|must',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new FavService();
		return await service.isFav(this._userId, input.oid);
	}

	/** 我的收藏列表 */
	async getMyFavList() {

		// 数据校验
		let rules = {
			search: 'string|min:1|max:30|name=搜索条件',
			sortType: 'string|name=搜索类型',
			sortVal: 'name=搜索类型值',
			orderBy: 'object|name=排序',
			page: 'must|int|default=1',
			size: 'int',
			isTotal: 'bool',
			oldTotal: 'int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new FavService();
		let result = await service.getMyFavList(this._userId, input);

		// 数据格式化
		let list = result.list;
		// 显示转换
		for (let k = 0; k < list.length; k++) {
			list[k].FAV_ADD_TIME = timeUtil.timestamp2Time(list[k].FAV_ADD_TIME);
		}
		result.list = list;

		return result;

	}

}

module.exports = FavController;

================================================
FILE: cloudfunctions/mcloud/project/TRIP1/controller/home_controller.js
================================================
/**
 * Notes: 全局或者主页模块控制器 
 * Date: 2020-11-05 10:20:00 
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 */

const BaseProjectController = require('./base_project_controller.js');
const HomeService = require('../service/home_service.js');

class HomeController extends BaseProjectController {

	async getSetup() {
		// 数据校验
		let rules = {
			key: 'must|string|name=KEY',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new HomeService();
		return await service.getSetup(input.key);

	}


	/** 首页推荐列表 */
	async getHomeList() {
		let service = new HomeService();
		return await service.getHomeList(); 
	}

}

module.exports = HomeController;

================================================
FILE: cloudfunctions/mcloud/project/TRIP1/controller/meet_controller.js
================================================
/**
 * Notes: 预约模块控制器
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2021-12-10 04:00:00 
 */

const BaseProjectController = require('./base_project_controller.js');
const MeetService = require('../service/meet_service.js');
const timeUtil = require('../../../framework/utils/time_util.js');
const JoinModel = require('../model/join_model.js');

class MeetController extends BaseProjectController {


	// 把列表转换为显示模式
	transMeetList(list) {
		let ret = [];
		for (let k = 0; k < list.length; k++) {
			let node = {};
			node.type = 'meet';
			node.id = list[k]._id;
			node.title = list[k].MEET_TITLE;
			node.desc = list[k].MEET_STYLE_SET.desc;
			node.ext = list[k].openRule;
			node.pic = list[k].MEET_STYLE_SET.pic;
			ret.push(node);
		}
		return ret;
	}


	/** 按天获取预约项目 */
	async getMeetListByDay() {

		// 数据校验
		let rules = {
			day: 'must|date|name=日期',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new MeetService();
		let list = await service.getMeetListByDay(input.day);
		return list;


	}

	/** 获取从某天开始可预约的日期 */
	async getHasDaysFromDay() {

		// 数据校验
		let rules = {
			day: 'must|date|name=日期',
		};

		// 取得数据
		let input = this.validateData(rules);


		let service = new MeetService();
		let list = await service.getHasDaysFromDay(input.day);
		return list;

	}

	/** 预约列表 */
	async getMeetList() {

		// 数据校验
		let rules = {
			search: 'string|min:1|max:30|name=搜索条件',
			sortType: 'string|name=搜索类型',
			sortVal: 'name=搜索类型值',
			orderBy: 'object|name=排序',
			typeId: 'string',
			page: 'must|int|default=1',
			size: 'int',
			isTotal: 'bool',
			oldTotal: 'int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new MeetService();
		let result = await service.getMeetList(input);

		// 数据格式化
		let list = result.list;

		for (let k = 0; k < list.length; k++) {
			list[k].openRule = this._getLeaveDay(list[k].MEET_DAYS) + '天可预约';
		}

		result.list = this.transMeetList(list);

		return result;

	}

	/** 我的预约列表 */
	async getMyJoinList() {

		// 数据校验
		let rules = {
			search: 'string|min:1|max:30|name=搜索条件',
			sortType: 'string|name=搜索类型',
			sortVal: 'name=搜索类型值',
			orderBy: 'object|name=排序',
			page: 'must|int|default=1',
			size: 'int',
			isTotal: 'bool',
			oldTotal: 'int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new MeetService();
		let result = await service.getMyJoinList(this._userId, input);

		// 数据格式化
		let list = result.list;

		let now = timeUtil.time('Y-M-D h:m');

		for (let k = 0; k < list.length; k++) {
			if (now > (list[k].JOIN_MEET_DAY + ' ' + list[k].JOIN_MEET_TIME_END))
				list[k].isTimeout = 1;
			else
				list[k].isTimeout = 0;

			list[k].JOIN_MEET_DAY = timeUtil.fmtDateCHN(list[k].JOIN_MEET_DAY) + ' (' + timeUtil.week(list[k].JOIN_MEET_DAY) + ')';

			list[k].JOIN_ADD_TIME = timeUtil.timestamp2Time(list[k].JOIN_ADD_TIME, 'Y-M-D h:m');
		}

		result.list = list;

		return result;

	}

	/** 我的某日预约列表 */
	async getMyJoinSomeday() {
		// 数据校验
		let rules = {
			day: 'must|date|name=日期',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new MeetService();
		let list = await service.getMyJoinSomeday(this._userId, input.day);

		// 数据格式化  
		for (let k = 0; k < list.length; k++) {

		}

		return list;

	}

	/** 我的预约详情 */
	async getMyJoinDetail() {
		// 数据校验
		let rules = {
			joinId: 'must|id',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new MeetService();
		let join = await service.getMyJoinDetail(this._userId, input.joinId);
		if (join) {
			join.JOIN_STATUS_DESC = JoinModel.getDesc('STATUS', join.JOIN_STATUS);
			join.JOIN_ADD_TIME = timeUtil.timestamp2Time(join.JOIN_ADD_TIME);
		}
		return join;

	}

	/** 用户预约取消 */
	async cancelMyJoin() {

		// 数据校验
		let rules = {
			joinId: 'must|id',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new MeetService();
		return await service.cancelMyJoin(this._userId, input.joinId);
	}

	/** 用户自助签到 */
	async userSelfCheckin() {

		// 数据校验
		let rules = {
			timeMark: 'must|string',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new MeetService();
		return await service.userSelfCheckin(this._userId, input.timeMark);
	}


	/**  预约前获取关键信息 */
	async detailForJoin() {
		// 数据校验
		let rules = {
			meetId: 'must|meetId',
			timeMark: 'must|string',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new MeetService();
		let meet = await service.detailForJoin(this._userId, input.meetId, input.timeMark);

		if (meet) {
			// 显示转换  
		}

		return meet;
	}

	/** 浏览预约信息 */
	async viewMeet() {
		// 数据校验
		let rules = {
			id: 'must|id',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new MeetService();
		let meet = await service.viewMeet(input.id);

		if (meet) {
			// 显示转换  
		}

		return meet;
	}

	/** 预约前检测 */
	async beforeJoin() {
		// 数据校验
		let rules = {
			meetId: 'must|id',
			timeMark: 'must|string',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new MeetService();
		return await service.beforeJoin(this._userId, input.meetId, input.timeMark);
	}

	/** 预约提交 */
	async join() {
		// 数据校验
		let rules = {
			meetId: 'must|id',
			timeMark: 'must|string',
			forms: 'must|array',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new MeetService();
		return await service.join(this._userId, input.meetId, input.timeMark, input.forms);
	}


	// 计算可约天数
	_getLeaveDay(days) {
		let now = timeUtil.time('Y-M-D');
		let count = 0;
		for (let k = 0; k < days.length; k++) {
			if (days[k] >= now) count++;
		}
		return count;
	}

}

module.exports = MeetController;

================================================
FILE: cloudfunctions/mcloud/project/TRIP1/controller/my_controller.js
================================================
/**
 * Notes: 用户中心模块控制器
 * Date: 2021-03-15 19:20:00 
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 */

const BaseProjectController = require('./base_project_controller.js');

class MyController extends BaseProjectController { 

}

module.exports = MyController;

================================================
FILE: cloudfunctions/mcloud/project/TRIP1/controller/news_controller.js
================================================
/**
 * Notes: 资讯模块控制器
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2020-09-29 04:00:00 
 */

const BaseProjectController = require('./base_project_controller.js');
const NewsService = require('../service/news_service.js');
const timeUtil = require('../../../framework/utils/time_util.js');

class NewsController extends BaseProjectController {

	// 把列表转换为显示模式
	transNewsList(list) {
		let ret = [];
		for (let k = 0; k < list.length; k++) {
			let node = {};
			node.type = 'news';
			node.id = list[k]._id;
			node.title = list[k].NEWS_TITLE;
			node.desc = list[k].NEWS_DESC;
			node.ext = list[k].NEWS_ADD_TIME;
			node.pic = list[k].NEWS_PIC[0];
			ret.push(node);
		}
		return ret;
	} 

	/** 资讯列表 */
	async getNewsList() {

		// 数据校验
		let rules = {
			search: 'string|min:1|max:30|name=搜索条件',
			sortType: 'string|name=搜索类型',
			sortVal: 'name=搜索类型值',
			orderBy: 'object|name=排序',
			cateId: 'string',
			page: 'must|int|default=1',
			size: 'int',
			isTotal: 'bool',
			oldTotal: 'int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new NewsService();
		let result = await service.getNewsList(input);

		// 数据格式化
		let list = result.list;

		for (let k = 0; k < list.length; k++) {
			list[k].NEWS_ADD_TIME = timeUtil.timestamp2Time(list[k].NEWS_ADD_TIME, 'Y-M-D');

			if (list[k].NEWS_OBJ && list[k].NEWS_OBJ.desc)
				delete list[k].NEWS_OBJ.desc;
		}
		result.list = this.transNewsList(list);

		return result;

	}


	/** 浏览资讯信息 */
	async viewNews() {
		// 数据校验
		let rules = {
			id: 'must|id',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new NewsService();
		let news = await service.viewNews(input.id);

		if (news) {
			// 显示转换 
			news.NEWS_ADD_TIME = timeUtil.timestamp2Time(news.NEWS_ADD_TIME, 'Y-M-D');
		}

		return news;
	}



}

module.exports = NewsController;

================================================
FILE: cloudfunctions/mcloud/project/TRIP1/controller/passport_controller.js
================================================
/**
 * Notes: passport模块控制器
 * Date: 2021-03-15 19:20:00 
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 */

const BaseProjectController = require('./base_project_controller.js');
const PassportService = require('../service/passport_service.js');
const contentCheck = require('../../../framework/validate/content_check.js');

class PassportController extends BaseProjectController {

	/** 取得我的用户信息 */
	async getMyDetail() {
		let service = new PassportService();
		return await service.getMyDetail(this._userId);
	}

	/** 获取手机号码 */
	async getPhone() {

		// 数据校验
		let rules = {
			cloudID: 'must|string|min:1|max:200|name=cloudID',
		};

		// 取得数据
		let input = this.validateData(rules);


		let service = new PassportService();
		return await service.getPhone(input.cloudID);
	}


	/** 注册 */
	async register() {
		// 数据校验
		let rules = {
			name: 'must|string|min:1|max:30|name=昵称',
			mobile: 'must|mobile|name=手机',
			forms: 'array|name=表单',
			status: 'int|default=1'
		};

		// 取得数据
		let input = this.validateData(rules);

		// 内容审核
		await contentCheck.checkTextMultiClient(input);

		let service = new PassportService();
		return await service.register(this._userId, input);
	}

	/** 修改用户资料 */
	async editBase() {
		// 数据校验
		let rules = {
			name: 'must|string|min:1|max:30|name=昵称',
			mobile: 'must|mobile|name=手机',
			forms: 'array|name=表单',
		};

		// 取得数据
		let input = this.validateData(rules);

		// 内容审核
		await contentCheck.checkTextMultiClient(input);

		let service = new PassportService();
		return await service.editBase(this._userId, input);
	}

	/** 登录 */
	async login() {
		// 数据校验
		let rules = {};

		// 取得数据
		let input = this.validateData(rules);

		let service = new PassportService();
		return await service.login(this._userId);
	}

}

module.exports = PassportController;

================================================
FILE: cloudfunctions/mcloud/project/TRIP1/controller/product_controller.js
================================================
/**
 * Notes: 产品模块控制器
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2022-06-08 04:00:00 
 */

const BaseProjectController = require('./base_project_controller.js');
const ProductService = require('../service/product_service.js');
const timeUtil = require('../../../framework/utils/time_util.js');
const dataUtil = require('../../../framework/utils/data_util.js');

class ProductController extends BaseProjectController {

	/** 列表 */
	async getProductList() {

		// 数据校验
		let rules = {
			search: 'string|min:1|max:30|name=搜索条件',
			sortType: 'string|name=搜索类型',
			sortVal: 'name=搜索类型值',
			orderBy: 'object|name=排序',
			page: 'must|int|default=1',
			size: 'int',
			isTotal: 'bool',
			oldTotal: 'int',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new ProductService();
		let result = await service.getProductList(input);

		// 数据格式化
		let list = result.list;

		for (let k = 0; k < list.length; k++) {
			list[k].PRODUCT_ADD_TIME = timeUtil.timestamp2Time(list[k].PRODUCT_ADD_TIME, 'Y-M-D');
			list[k].PRODUCT_OBJ.desc = dataUtil.fmtText(list[k].PRODUCT_OBJ.desc, 100);
			list[k].PRODUCT_OBJ.star =  (list[k].PRODUCT_OBJ.star);
		}

		return result;

	}


	/** 浏览详细 */
	async viewProduct() {
		// 数据校验
		let rules = {
			id: 'must|id',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new ProductService();
		let product = await service.viewProduct(input.id);

		if (product) {
			// 显示转换 
			product.PRODUCT_ADD_TIME = timeUtil.timestamp2Time(product.PRODUCT_ADD_TIME, 'Y-M-D');
		}

		return product;
	}

}

module.exports = ProductController;

================================================
FILE: cloudfunctions/mcloud/project/TRIP1/controller/test/test_controller.js
================================================
/**
 * Notes: 测试模块控制器
 * Date: 2021-03-15 19:20:00 
 */

const BaseController = require('../../controller/base_project_controller.js');
const fakerLib = require('../../../../framework/lib/faker_lib.js');

const VoteModel = require('../../model/vote_model.js');
const VoteJoinModel = require('../../model/vote_join_model.js');
const VoteService = require('../../service/vote_service.js');

const EnrollModel = require('../../model/enroll_model.js');
const EnrollJoinModel = require('../../model/enroll_join_model.js');

const ActivityModel = require('../../model/activity_model.js');
const ActivityJoinModel = require('../../model/activity_join_model.js');

class TestController extends BaseController {

	async test() {
		console.log('TEST>>>>>>>');

		//this.mockEnrollJoin();
		//this.mockActivityJoin();
		this.mockVoteJoin();

	}

	async mockEnrollJoin() {
		console.log('mockEnrollJoin >>>>>>> Begin....');
		let ENROLL_ID = 'b69f67c062d7d46b0bc4d2985c084775';

		let enroll = await EnrollModel.getOne(ENROLL_ID);
		if (!enroll) return console.error('no enroll');

		let join = {};
		join.ENROLL_JOIN_ENROLL_ID = ENROLL_ID;
		join.ENROLL_JOIN_STATUS = 1;

		console.log('>>>>delete');
		let delCnt = await EnrollJoinModel.del({ ENROLL_JOIN_ENROLL_ID: ENROLL_ID });
		console.log('>>>>delete=' + delCnt);

		for (let k = 1; k <= 10; k++) {
			console.log('>>>>insert >' + k);
			join.ENROLL_JOIN_USER_ID = fakerLib.getUuid();

			join.ENROLL_JOIN_LAST_TIME = fakerLib.getAddTimestamp();
			join.ENROLL_JOIN_ADD_TIME = fakerLib.getAddTimestamp();

			join.ENROLL_JOIN_FORMS = [
				{ mark: 'name', title: '姓名', type: 'text', val: fakerLib.getName() },
				{ mark: 'phone', title: '手机', type: 'mobile', val: fakerLib.getMobile() }
			];

			await EnrollJoinModel.insert(join);
		}

		console.log('>>>> STAT');
		let cnt = await EnrollJoinModel.count({
			ENROLL_JOIN_ENROLL_ID: ENROLL_ID
		});

		await EnrollModel.edit(ENROLL_ID, { ENROLL_JOIN_CNT: cnt, ENROLL_MAX_CNT: cnt + 10 });

		console.log('mockEnrollJoin >>>>>>> END');
	}

	async mockActivityJoin() {
		console.log('mockActivityJoin >>>>>>> Begin....');
		let ACTIVITY_ID = '0a4ec1f962d867481158b94f6441f613';

		let activity = await ActivityModel.getOne(ACTIVITY_ID);
		if (!activity) return console.error('no activity');

		let join = {};
		join.ACTIVITY_JOIN_ACTIVITY_ID = ACTIVITY_ID;
		join.ACTIVITY_JOIN_STATUS = 1;

		console.log('>>>>delete');
		let delCnt = await ActivityJoinModel.del({ ACTIVITY_JOIN_ACTIVITY_ID: ACTIVITY_ID });
		console.log('>>>>delete=' + delCnt);

		for (let k = 1; k <= 10; k++) {
			console.log('>>>>insert >' + k);
			join.ACTIVITY_JOIN_USER_ID = fakerLib.getUuid();

			join.ACTIVITY_JOIN_CODE = fakerLib.getStr(15);
			join.ACTIVITY_JOIN_ADD_TIME = fakerLib.getAddTimestamp();

			join.ACTIVITY_JOIN_FORMS = [
				{ mark: 'name', title: '姓名', type: 'text', val: fakerLib.getName() },
				{ mark: 'phone', title: '手机', type: 'mobile', val: fakerLib.getMobile() }
			];

			await ActivityJoinModel.insert(join);
		}

		console.log('>>>> STAT');
		let cnt = await ActivityJoinModel.count({
			ACTIVITY_JOIN_ACTIVITY_ID: ACTIVITY_ID
		});

		await ActivityModel.edit(ACTIVITY_ID, { ACTIVITY_JOIN_CNT: cnt, ACTIVITY_MAX_CNT: cnt + 10 });

		console.log('mockActivityJoin >>>>>>> END');
	}


	async mockVoteJoin() {
		console.log('mockVoteJoin >>>>>>> Begin....');
		let VOTE_ID = 'b69f67c062c3a2b209da6ef133c9d874';

		let vote = await VoteModel.getOne(VOTE_ID);
		if (!vote) return console.error('no vote');

		let join = {};
		join.VOTE_JOIN_VOTE_ID = VOTE_ID;

		console.log('>>>>delete');
		let delCnt = await VoteJoinModel.del({ VOTE_JOIN_VOTE_ID: VOTE_ID });
		console.log('>>>>delete=' + delCnt);


		for (let k = 1; k <= 10; k++) {
			console.log('>>>>insert >' + k);
			join.VOTE_JOIN_USER_ID = fakerLib.getUuid(); 
			join.VOTE_JOIN_ADD_TIME = fakerLib.getAddTimestamp();

			
			join
Download .txt
gitextract_4tbgnvos/

├── .gitignore
├── README.md
├── cloudfunctions/
│   └── mcloud/
│       ├── config/
│       │   └── config.js
│       ├── config.json
│       ├── framework/
│       │   ├── cloud/
│       │   │   ├── cloud_base.js
│       │   │   └── cloud_util.js
│       │   ├── core/
│       │   │   ├── app_code.js
│       │   │   ├── app_error.js
│       │   │   ├── app_other.js
│       │   │   ├── app_util.js
│       │   │   └── application.js
│       │   ├── database/
│       │   │   ├── db_util.js
│       │   │   ├── model.js
│       │   │   └── multi_model.js
│       │   ├── lib/
│       │   │   ├── faker_lib.js
│       │   │   ├── md5_lib.js
│       │   │   └── mini_lib.js
│       │   ├── platform/
│       │   │   ├── controller/
│       │   │   │   ├── base_admin_controller.js
│       │   │   │   └── base_controller.js
│       │   │   ├── model/
│       │   │   │   ├── admin_model.js
│       │   │   │   ├── base_model.js
│       │   │   │   └── log_model.js
│       │   │   └── service/
│       │   │       ├── base_admin_service.js
│       │   │       └── base_service.js
│       │   ├── utils/
│       │   │   ├── constant.js
│       │   │   ├── data_util.js
│       │   │   ├── export_util.js
│       │   │   ├── log_util.js
│       │   │   ├── math_util.js
│       │   │   ├── setup/
│       │   │   │   ├── setup_model.js
│       │   │   │   └── setup_util.js
│       │   │   ├── time_util.js
│       │   │   └── util.js
│       │   └── validate/
│       │       ├── content_check.js
│       │       └── data_check.js
│       ├── index.js
│       ├── package.json
│       └── project/
│           └── TRIP1/
│               ├── controller/
│               │   ├── admin/
│               │   │   ├── admin_album_controller.js
│               │   │   ├── admin_home_controller.js
│               │   │   ├── admin_meet_controller.js
│               │   │   ├── admin_mgr_controller.js
│               │   │   ├── admin_news_controller.js
│               │   │   ├── admin_product_controller.js
│               │   │   ├── admin_setup_controller.js
│               │   │   ├── admin_user_controller.js
│               │   │   └── base_project_admin_controller.js
│               │   ├── album_controller.js
│               │   ├── base_project_controller.js
│               │   ├── check_controller.js
│               │   ├── fav_controller.js
│               │   ├── home_controller.js
│               │   ├── meet_controller.js
│               │   ├── my_controller.js
│               │   ├── news_controller.js
│               │   ├── passport_controller.js
│               │   ├── product_controller.js
│               │   └── test/
│               │       └── test_controller.js
│               ├── model/
│               │   ├── album_model.js
│               │   ├── base_project_model.js
│               │   ├── day_model.js
│               │   ├── fav_model.js
│               │   ├── join_model.js
│               │   ├── meet_model.js
│               │   ├── news_model.js
│               │   ├── product_model.js
│               │   └── user_model.js
│               ├── public/
│               │   ├── constants.js
│               │   ├── project_config.js
│               │   └── route.js
│               └── service/
│                   ├── admin/
│                   │   ├── admin_album_service.js
│                   │   ├── admin_home_service.js
│                   │   ├── admin_meet_service.js
│                   │   ├── admin_mgr_service.js
│                   │   ├── admin_news_service.js
│                   │   ├── admin_product_service.js
│                   │   ├── admin_setup_service.js
│                   │   ├── admin_user_service.js
│                   │   └── base_project_admin_service.js
│                   ├── album_service.js
│                   ├── base_project_service.js
│                   ├── fav_service.js
│                   ├── home_service.js
│                   ├── meet_service.js
│                   ├── news_service.js
│                   ├── passport_service.js
│                   └── product_service.js
├── miniprogram/
│   ├── app.js
│   ├── app.json
│   ├── app.wxss
│   ├── cmpts/
│   │   ├── biz/
│   │   │   ├── detail/
│   │   │   │   ├── detail_cmpt.js
│   │   │   │   ├── detail_cmpt.json
│   │   │   │   ├── detail_cmpt.wxml
│   │   │   │   └── detail_cmpt.wxss
│   │   │   └── foot/
│   │   │       ├── foot_cmpt.js
│   │   │       ├── foot_cmpt.json
│   │   │       ├── foot_cmpt.wxml
│   │   │       └── foot_cmpt.wxss
│   │   └── public/
│   │       ├── calendar/
│   │       │   ├── calendar_comm/
│   │       │   │   ├── calendar_comm_cmpt.js
│   │       │   │   ├── calendar_comm_cmpt.json
│   │       │   │   ├── calendar_comm_cmpt.wxml
│   │       │   │   ├── calendar_comm_cmpt.wxss
│   │       │   │   └── din.wxss
│   │       │   ├── calendar_lib.js
│   │       │   ├── calendar_meet/
│   │       │   │   ├── calendar_meet_cmpt.js
│   │       │   │   ├── calendar_meet_cmpt.json
│   │       │   │   ├── calendar_meet_cmpt.wxml
│   │       │   │   └── calendar_meet_cmpt.wxss
│   │       │   ├── date_select/
│   │       │   │   ├── date_select_cmpt.js
│   │       │   │   ├── date_select_cmpt.json
│   │       │   │   ├── date_select_cmpt.wxml
│   │       │   │   └── date_select_cmpt.wxss
│   │       │   └── time_select/
│   │       │       ├── time_select_cmpt.js
│   │       │       ├── time_select_cmpt.json
│   │       │       ├── time_select_cmpt.wxml
│   │       │       └── time_select_cmpt.wxss
│   │       ├── checkbox/
│   │       │   ├── checkbox_cmpt.js
│   │       │   ├── checkbox_cmpt.json
│   │       │   ├── checkbox_cmpt.wxml
│   │       │   └── checkbox_cmpt.wxss
│   │       ├── editor/
│   │       │   ├── editor_cmpt.js
│   │       │   ├── editor_cmpt.json
│   │       │   ├── editor_cmpt.wxml
│   │       │   └── editor_cmpt.wxss
│   │       ├── form/
│   │       │   ├── form_set/
│   │       │   │   ├── field/
│   │       │   │   │   ├── form_set_field.js
│   │       │   │   │   ├── form_set_field.json
│   │       │   │   │   ├── form_set_field.wxml
│   │       │   │   │   └── form_set_field.wxss
│   │       │   │   ├── form_set_cmpt.js
│   │       │   │   ├── form_set_cmpt.json
│   │       │   │   ├── form_set_cmpt.wxml
│   │       │   │   └── form_set_cmpt.wxss
│   │       │   ├── form_set_helper.js
│   │       │   └── form_show/
│   │       │       ├── content/
│   │       │       │   ├── form_show_content.js
│   │       │       │   ├── form_show_content.json
│   │       │       │   ├── form_show_content.wxml
│   │       │       │   └── form_show_content.wxss
│   │       │       ├── form_show_cmpt.js
│   │       │       ├── form_show_cmpt.json
│   │       │       ├── form_show_cmpt.wxml
│   │       │       └── form_show_cmpt.wxss
│   │       ├── img/
│   │       │   ├── img_upload_cmpt.js
│   │       │   ├── img_upload_cmpt.json
│   │       │   ├── img_upload_cmpt.wxml
│   │       │   └── img_upload_cmpt.wxss
│   │       ├── list/
│   │       │   ├── comm_list_cmpt.js
│   │       │   ├── comm_list_cmpt.json
│   │       │   ├── comm_list_cmpt.wxml
│   │       │   └── comm_list_cmpt.wxss
│   │       ├── modal/
│   │       │   ├── modal_cmpt.js
│   │       │   ├── modal_cmpt.json
│   │       │   ├── modal_cmpt.wxml
│   │       │   └── modal_cmpt.wxss
│   │       ├── picker/
│   │       │   ├── picker_cmpt.js
│   │       │   ├── picker_cmpt.json
│   │       │   ├── picker_cmpt.wxml
│   │       │   └── picker_cmpt.wxss
│   │       ├── picker_multi/
│   │       │   ├── picker_multi_cmpt.js
│   │       │   ├── picker_multi_cmpt.json
│   │       │   ├── picker_multi_cmpt.wxml
│   │       │   └── picker_multi_cmpt.wxss
│   │       ├── picker_time/
│   │       │   ├── datetime_picker.js
│   │       │   ├── picker_time_cmpt.js
│   │       │   ├── picker_time_cmpt.json
│   │       │   ├── picker_time_cmpt.wxml
│   │       │   └── picker_time_cmpt.wxss
│   │       ├── poster/
│   │       │   ├── poster_cmpt.js
│   │       │   ├── poster_cmpt.json
│   │       │   ├── poster_cmpt.wxml
│   │       │   ├── poster_cmpt.wxss
│   │       │   ├── poster_cmpt_helper.js
│   │       │   └── wxa-plugin-canvas/
│   │       │       ├── index/
│   │       │       │   ├── index.js
│   │       │       │   ├── index.json
│   │       │       │   ├── index.wxml
│   │       │       │   └── index.wxss
│   │       │       └── poster/
│   │       │           ├── index.js
│   │       │           ├── index.json
│   │       │           ├── index.wxml
│   │       │           ├── index.wxss
│   │       │           └── poster.js
│   │       ├── radio/
│   │       │   ├── radio_cmpt.js
│   │       │   ├── radio_cmpt.json
│   │       │   ├── radio_cmpt.wxml
│   │       │   └── radio_cmpt.wxss
│   │       ├── swiper/
│   │       │   ├── swiper_cmpt.js
│   │       │   ├── swiper_cmpt.json
│   │       │   ├── swiper_cmpt.wxml
│   │       │   └── swiper_cmpt.wxss
│   │       └── table/
│   │           ├── table_cmpt.js
│   │           ├── table_cmpt.json
│   │           ├── table_cmpt.wxml
│   │           └── table_cmpt.wxss
│   ├── comm/
│   │   ├── behavior/
│   │   │   ├── about_bh.js
│   │   │   ├── my_fav_bh.js
│   │   │   ├── my_foot_bh.js
│   │   │   ├── news_index_bh.js
│   │   │   └── search_bh.js
│   │   ├── biz/
│   │   │   ├── admin_biz.js
│   │   │   ├── base_biz.js
│   │   │   ├── fav_biz.js
│   │   │   ├── foot_biz.js
│   │   │   ├── passport_biz.js
│   │   │   ├── public_biz.js
│   │   │   └── search_biz.js
│   │   └── constants.js
│   ├── helper/
│   │   ├── cache_helper.js
│   │   ├── cloud_helper.js
│   │   ├── content_check_helper.js
│   │   ├── data_helper.js
│   │   ├── file_helper.js
│   │   ├── form_helper.js
│   │   ├── helper.js
│   │   ├── mini_helper.js
│   │   ├── page_helper.js
│   │   ├── pic_helper.js
│   │   ├── time_helper.js
│   │   └── validate.js
│   ├── lib/
│   │   └── tools/
│   │       ├── base64_lib.js
│   │       ├── lunar_lib.js
│   │       └── qrcode_lib.js
│   ├── pages/
│   │   └── test1/
│   │       ├── test1.js
│   │       └── test1.wxml
│   ├── projects/
│   │   └── TRIP1/
│   │       ├── biz/
│   │       │   ├── admin_album_biz.js
│   │       │   ├── admin_meet_biz.js
│   │       │   ├── admin_news_biz.js
│   │       │   ├── admin_product_biz.js
│   │       │   ├── album_biz.js
│   │       │   ├── meet_biz.js
│   │       │   ├── news_biz.js
│   │       │   ├── product_biz.js
│   │       │   └── project_biz.js
│   │       ├── pages/
│   │       │   ├── about/
│   │       │   │   ├── index/
│   │       │   │   │   ├── about_index.js
│   │       │   │   │   ├── about_index.json
│   │       │   │   │   ├── about_index.wxml
│   │       │   │   │   └── about_index.wxss
│   │       │   │   └── service/
│   │       │   │       ├── about_service.js
│   │       │   │       ├── about_service.json
│   │       │   │       ├── about_service.wxml
│   │       │   │       └── about_service.wxss
│   │       │   ├── admin/
│   │       │   │   ├── album/
│   │       │   │   │   ├── add/
│   │       │   │   │   │   ├── admin_album_add.js
│   │       │   │   │   │   ├── admin_album_add.json
│   │       │   │   │   │   ├── admin_album_add.wxml
│   │       │   │   │   │   └── admin_album_add.wxss
│   │       │   │   │   ├── admin_album_form_tpl.wxml
│   │       │   │   │   ├── edit/
│   │       │   │   │   │   ├── admin_album_edit.js
│   │       │   │   │   │   ├── admin_album_edit.json
│   │       │   │   │   │   ├── admin_album_edit.wxml
│   │       │   │   │   │   └── admin_album_edit.wxss
│   │       │   │   │   └── list/
│   │       │   │   │       ├── admin_album_list.js
│   │       │   │   │       ├── admin_album_list.json
│   │       │   │   │       ├── admin_album_list.wxml
│   │       │   │   │       └── admin_album_list.wxss
│   │       │   │   ├── content/
│   │       │   │   │   ├── admin_content.js
│   │       │   │   │   ├── admin_content.json
│   │       │   │   │   ├── admin_content.wxml
│   │       │   │   │   └── admin_content.wxss
│   │       │   │   ├── index/
│   │       │   │   │   ├── home/
│   │       │   │   │   │   ├── admin_home.js
│   │       │   │   │   │   ├── admin_home.json
│   │       │   │   │   │   ├── admin_home.wxml
│   │       │   │   │   │   └── admin_home.wxss
│   │       │   │   │   └── login/
│   │       │   │   │       ├── admin_login.js
│   │       │   │   │       ├── admin_login.json
│   │       │   │   │       ├── admin_login.wxml
│   │       │   │   │       └── admin_login.wxss
│   │       │   │   ├── meet/
│   │       │   │   │   ├── cover/
│   │       │   │   │   │   ├── admin_meet_cover.js
│   │       │   │   │   │   ├── admin_meet_cover.json
│   │       │   │   │   │   ├── admin_meet_cover.wxml
│   │       │   │   │   │   └── admin_meet_cover.wxss
│   │       │   │   │   ├── edit/
│   │       │   │   │   │   ├── admin_meet_edit.js
│   │       │   │   │   │   ├── admin_meet_edit.json
│   │       │   │   │   │   ├── admin_meet_edit.wxml
│   │       │   │   │   │   └── admin_meet_edit.wxss
│   │       │   │   │   ├── export/
│   │       │   │   │   │   ├── admin_join_export.js
│   │       │   │   │   │   ├── admin_join_export.json
│   │       │   │   │   │   ├── admin_join_export.wxml
│   │       │   │   │   │   └── admin_join_export.wxss
│   │       │   │   │   ├── join/
│   │       │   │   │   │   ├── admin_meet_join.js
│   │       │   │   │   │   ├── admin_meet_join.json
│   │       │   │   │   │   ├── admin_meet_join.wxml
│   │       │   │   │   │   └── admin_meet_join.wxss
│   │       │   │   │   ├── list/
│   │       │   │   │   │   ├── admin_meet_list.js
│   │       │   │   │   │   ├── admin_meet_list.json
│   │       │   │   │   │   ├── admin_meet_list.wxml
│   │       │   │   │   │   └── admin_meet_list.wxss
│   │       │   │   │   ├── record/
│   │       │   │   │   │   ├── admin_record_list.js
│   │       │   │   │   │   ├── admin_record_list.json
│   │       │   │   │   │   ├── admin_record_list.wxml
│   │       │   │   │   │   └── admin_record_list.wxss
│   │       │   │   │   ├── scan/
│   │       │   │   │   │   ├── admin_meet_scan.js
│   │       │   │   │   │   ├── admin_meet_scan.json
│   │       │   │   │   │   ├── admin_meet_scan.wxml
│   │       │   │   │   │   └── admin_meet_scan.wxss
│   │       │   │   │   ├── self/
│   │       │   │   │   │   ├── admin_meet_self.js
│   │       │   │   │   │   ├── admin_meet_self.json
│   │       │   │   │   │   ├── admin_meet_self.wxml
│   │       │   │   │   │   └── admin_meet_self.wxss
│   │       │   │   │   ├── temp/
│   │       │   │   │   │   ├── admin_temp_select.js
│   │       │   │   │   │   ├── admin_temp_select.json
│   │       │   │   │   │   ├── admin_temp_select.wxml
│   │       │   │   │   │   └── admin_temp_select.wxss
│   │       │   │   │   └── time/
│   │       │   │   │       ├── admin_meet_time.js
│   │       │   │   │       ├── admin_meet_time.json
│   │       │   │   │       ├── admin_meet_time.wxml
│   │       │   │   │       └── admin_meet_time.wxss
│   │       │   │   ├── mgr/
│   │       │   │   │   ├── add/
│   │       │   │   │   │   ├── admin_mgr_add.js
│   │       │   │   │   │   ├── admin_mgr_add.json
│   │       │   │   │   │   ├── admin_mgr_add.wxml
│   │       │   │   │   │   └── admin_mgr_add.wxss
│   │       │   │   │   ├── edit/
│   │       │   │   │   │   ├── admin_mgr_edit.js
│   │       │   │   │   │   ├── admin_mgr_edit.json
│   │       │   │   │   │   ├── admin_mgr_edit.wxml
│   │       │   │   │   │   └── admin_mgr_edit.wxss
│   │       │   │   │   ├── list/
│   │       │   │   │   │   ├── admin_mgr_list.js
│   │       │   │   │   │   ├── admin_mgr_list.json
│   │       │   │   │   │   ├── admin_mgr_list.wxml
│   │       │   │   │   │   └── admin_mgr_list.wxss
│   │       │   │   │   ├── log/
│   │       │   │   │   │   ├── admin_log_list.js
│   │       │   │   │   │   ├── admin_log_list.json
│   │       │   │   │   │   ├── admin_log_list.wxml
│   │       │   │   │   │   └── admin_log_list.wxss
│   │       │   │   │   └── pwd/
│   │       │   │   │       ├── admin_mgr_pwd.js
│   │       │   │   │       ├── admin_mgr_pwd.json
│   │       │   │   │       ├── admin_mgr_pwd.wxml
│   │       │   │   │       └── admin_mgr_pwd.wxss
│   │       │   │   ├── news/
│   │       │   │   │   ├── add/
│   │       │   │   │   │   ├── admin_news_add.js
│   │       │   │   │   │   ├── admin_news_add.json
│   │       │   │   │   │   ├── admin_news_add.wxml
│   │       │   │   │   │   └── admin_news_add.wxss
│   │       │   │   │   ├── admin_news_form_tpl.wxml
│   │       │   │   │   ├── edit/
│   │       │   │   │   │   ├── admin_news_edit.js
│   │       │   │   │   │   ├── admin_news_edit.json
│   │       │   │   │   │   ├── admin_news_edit.wxml
│   │       │   │   │   │   └── admin_news_edit.wxss
│   │       │   │   │   └── list/
│   │       │   │   │       ├── admin_news_list.js
│   │       │   │   │       ├── admin_news_list.json
│   │       │   │   │       ├── admin_news_list.wxml
│   │       │   │   │       └── admin_news_list.wxss
│   │       │   │   ├── product/
│   │       │   │   │   ├── add/
│   │       │   │   │   │   ├── admin_product_add.js
│   │       │   │   │   │   ├── admin_product_add.json
│   │       │   │   │   │   ├── admin_product_add.wxml
│   │       │   │   │   │   └── admin_product_add.wxss
│   │       │   │   │   ├── admin_product_form_tpl.wxml
│   │       │   │   │   ├── edit/
│   │       │   │   │   │   ├── admin_product_edit.js
│   │       │   │   │   │   ├── admin_product_edit.json
│   │       │   │   │   │   ├── admin_product_edit.wxml
│   │       │   │   │   │   └── admin_product_edit.wxss
│   │       │   │   │   └── list/
│   │       │   │   │       ├── admin_product_list.js
│   │       │   │   │       ├── admin_product_list.json
│   │       │   │   │       ├── admin_product_list.wxml
│   │       │   │   │       └── admin_product_list.wxss
│   │       │   │   ├── setup/
│   │       │   │   │   ├── about/
│   │       │   │   │   │   ├── admin_setup_about.js
│   │       │   │   │   │   ├── admin_setup_about.json
│   │       │   │   │   │   ├── admin_setup_about.wxml
│   │       │   │   │   │   └── admin_setup_about.wxss
│   │       │   │   │   ├── about_list/
│   │       │   │   │   │   ├── admin_setup_about_list.js
│   │       │   │   │   │   ├── admin_setup_about_list.json
│   │       │   │   │   │   ├── admin_setup_about_list.wxml
│   │       │   │   │   │   └── admin_setup_about_list.wxss
│   │       │   │   │   └── qr/
│   │       │   │   │       ├── admin_setup_qr.js
│   │       │   │   │       ├── admin_setup_qr.json
│   │       │   │   │       ├── admin_setup_qr.wxml
│   │       │   │   │       └── admin_setup_qr.wxss
│   │       │   │   └── user/
│   │       │   │       ├── detail/
│   │       │   │       │   ├── admin_user_detail.js
│   │       │   │       │   ├── admin_user_detail.json
│   │       │   │       │   ├── admin_user_detail.wxml
│   │       │   │       │   └── admin_user_detail.wxss
│   │       │   │       ├── export/
│   │       │   │       │   ├── admin_user_export.js
│   │       │   │       │   ├── admin_user_export.json
│   │       │   │       │   ├── admin_user_export.wxml
│   │       │   │       │   └── admin_user_export.wxss
│   │       │   │       └── list/
│   │       │   │           ├── admin_user_list.js
│   │       │   │           ├── admin_user_list.json
│   │       │   │           ├── admin_user_list.wxml
│   │       │   │           └── admin_user_list.wxss
│   │       │   ├── album/
│   │       │   │   ├── detail/
│   │       │   │   │   ├── album_detail.js
│   │       │   │   │   ├── album_detail.json
│   │       │   │   │   ├── album_detail.wxml
│   │       │   │   │   └── album_detail.wxss
│   │       │   │   └── index/
│   │       │   │       ├── album_index.js
│   │       │   │       ├── album_index.json
│   │       │   │       ├── album_index.wxml
│   │       │   │       └── album_index.wxss
│   │       │   ├── default/
│   │       │   │   └── index/
│   │       │   │       ├── default_index.js
│   │       │   │       ├── default_index.json
│   │       │   │       ├── default_index.wxml
│   │       │   │       └── default_index.wxss
│   │       │   ├── meet/
│   │       │   │   ├── calendar/
│   │       │   │   │   ├── meet_calendar.js
│   │       │   │   │   ├── meet_calendar.json
│   │       │   │   │   ├── meet_calendar.wxml
│   │       │   │   │   └── meet_calendar.wxss
│   │       │   │   ├── detail/
│   │       │   │   │   ├── meet_detail.js
│   │       │   │   │   ├── meet_detail.json
│   │       │   │   │   ├── meet_detail.wxml
│   │       │   │   │   └── meet_detail.wxss
│   │       │   │   ├── index/
│   │       │   │   │   ├── meet_index.js
│   │       │   │   │   ├── meet_index.json
│   │       │   │   │   ├── meet_index.wxml
│   │       │   │   │   └── meet_index.wxss
│   │       │   │   ├── join/
│   │       │   │   │   ├── meet_join.js
│   │       │   │   │   ├── meet_join.json
│   │       │   │   │   ├── meet_join.wxml
│   │       │   │   │   └── meet_join.wxss
│   │       │   │   ├── my_join_detail/
│   │       │   │   │   ├── meet_my_join_detail.js
│   │       │   │   │   ├── meet_my_join_detail.json
│   │       │   │   │   ├── meet_my_join_detail.wxml
│   │       │   │   │   └── meet_my_join_detail.wxss
│   │       │   │   ├── my_join_list/
│   │       │   │   │   ├── meet_my_join_list.js
│   │       │   │   │   ├── meet_my_join_list.json
│   │       │   │   │   ├── meet_my_join_list.wxml
│   │       │   │   │   └── meet_my_join_list.wxss
│   │       │   │   └── self/
│   │       │   │       ├── meet_self.js
│   │       │   │       ├── meet_self.json
│   │       │   │       ├── meet_self.wxml
│   │       │   │       └── meet_self.wxss
│   │       │   ├── my/
│   │       │   │   ├── edit/
│   │       │   │   │   ├── my_edit.js
│   │       │   │   │   ├── my_edit.json
│   │       │   │   │   ├── my_edit.wxml
│   │       │   │   │   ├── my_edit.wxss
│   │       │   │   │   └── user_form.wxml
│   │       │   │   ├── fav/
│   │       │   │   │   ├── my_fav.js
│   │       │   │   │   ├── my_fav.json
│   │       │   │   │   ├── my_fav.wxml
│   │       │   │   │   └── my_fav.wxss
│   │       │   │   ├── foot/
│   │       │   │   │   ├── my_foot.js
│   │       │   │   │   ├── my_foot.json
│   │       │   │   │   ├── my_foot.wxml
│   │       │   │   │   └── my_foot.wxss
│   │       │   │   ├── index/
│   │       │   │   │   ├── my_index.js
│   │       │   │   │   ├── my_index.json
│   │       │   │   │   ├── my_index.wxml
│   │       │   │   │   └── my_index.wxss
│   │       │   │   └── reg/
│   │       │   │       ├── my_reg.js
│   │       │   │       ├── my_reg.json
│   │       │   │       ├── my_reg.wxml
│   │       │   │       └── my_reg.wxss
│   │       │   ├── news/
│   │       │   │   ├── cate1/
│   │       │   │   │   ├── news_cate1.js
│   │       │   │   │   ├── news_cate1.json
│   │       │   │   │   ├── news_cate1.wxml
│   │       │   │   │   └── news_cate1.wxss
│   │       │   │   ├── cate2/
│   │       │   │   │   ├── news_cate2.js
│   │       │   │   │   ├── news_cate2.json
│   │       │   │   │   ├── news_cate2.wxml
│   │       │   │   │   └── news_cate2.wxss
│   │       │   │   ├── detail/
│   │       │   │   │   ├── news_detail.js
│   │       │   │   │   ├── news_detail.json
│   │       │   │   │   ├── news_detail.wxml
│   │       │   │   │   └── news_detail.wxss
│   │       │   │   └── index/
│   │       │   │       ├── news_index.js
│   │       │   │       ├── news_index.json
│   │       │   │       ├── news_index.wxml
│   │       │   │       └── news_index.wxss
│   │       │   ├── product/
│   │       │   │   ├── detail/
│   │       │   │   │   ├── product_detail.js
│   │       │   │   │   ├── product_detail.json
│   │       │   │   │   ├── product_detail.wxml
│   │       │   │   │   └── product_detail.wxss
│   │       │   │   └── index/
│   │       │   │       ├── product_index.js
│   │       │   │       ├── product_index.json
│   │       │   │       ├── product_index.wxml
│   │       │   │       └── product_index.wxss
│   │       │   ├── search/
│   │       │   │   ├── search.js
│   │       │   │   ├── search.json
│   │       │   │   ├── search.wxml
│   │       │   │   └── search.wxss
│   │       │   └── tpls/
│   │       │       └── menu_tpl.wxml
│   │       ├── public/
│   │       │   └── project_setting.js
│   │       └── style/
│   │           └── skin.wxss
│   ├── setting/
│   │   └── setting.js
│   ├── sitemap.json
│   ├── style/
│   │   ├── base/
│   │   │   ├── animation.wxss
│   │   │   ├── avatar.wxss
│   │   │   ├── background.wxss
│   │   │   ├── bar.wxss
│   │   │   ├── base.wxss
│   │   │   ├── border.wxss
│   │   │   ├── button.wxss
│   │   │   ├── comm.wxss
│   │   │   ├── form.wxss
│   │   │   ├── icon.wxss
│   │   │   ├── image.wxss
│   │   │   ├── layout.wxss
│   │   │   ├── list.wxss
│   │   │   ├── load.wxss
│   │   │   ├── modal.wxss
│   │   │   ├── nav.wxss
│   │   │   ├── shadow.wxss
│   │   │   ├── table.wxss
│   │   │   ├── tag.wxss
│   │   │   └── text.wxss
│   │   ├── project/
│   │   │   ├── admin_list_style.wxss
│   │   │   ├── my_fav_style.wxss
│   │   │   ├── my_foot_style.wxss
│   │   │   └── search_style.wxss
│   │   └── public/
│   │       ├── admin.wxss
│   │       ├── article_list.wxss
│   │       ├── comm_box_list.wxss
│   │       ├── detail.wxss
│   │       └── project.wxss
│   └── tpls/
│       ├── project/
│       │   ├── about_tpl.wxml
│       │   ├── my_fav_tpl.wxml
│       │   ├── my_foot_tpl.wxml
│       │   ├── news_index_tpl.wxml
│       │   └── search_tpl.wxml
│       ├── public/
│       │   ├── admin_forms_detail_tpl.wxml
│       │   ├── base_list_tpl.wxml
│       │   ├── list_load_tpl.wxml
│       │   └── top_tpl.wxml
│       └── wxs/
│           └── tools.wxs
├── project.config.json
├── project.private.config.json
└── 旅游景区门户小程序安装使用手册.docx
Download .txt
SYMBOL INDEX (1014 symbols across 132 files)

FILE: cloudfunctions/mcloud/framework/cloud/cloud_base.js
  function getCloud (line 12) | function getCloud() {

FILE: cloudfunctions/mcloud/framework/cloud/cloud_util.js
  function log (line 8) | function log(method, err, level = 'error') {
  function getTempFileURLOne (line 19) | async function getTempFileURLOne(fileID) {
  function getTempFileURL (line 31) | async function getTempFileURL(tempFileList, isValid = false) {
  function handlerCloudFilesForForms (line 61) | async function handlerCloudFilesForForms(oldForms, newsForms) {
  function handlerCloudFiles (line 94) | async function handlerCloudFiles(oldFiles, newFiles) {
  function handlerCloudFilesByRichEditor (line 121) | async function handlerCloudFilesByRichEditor(oldFiles, newFiles) {
  function deleteFiles (line 146) | async function deleteFiles(list) {

FILE: cloudfunctions/mcloud/framework/core/app_error.js
  class AppError (line 10) | class AppError extends Error {
    method constructor (line 11) | constructor(message, code = appCode.LOGIC) {

FILE: cloudfunctions/mcloud/framework/core/app_other.js
  function handlerOther (line 7) | function handlerOther(event) {

FILE: cloudfunctions/mcloud/framework/core/app_util.js
  function handlerBasic (line 9) | function handlerBasic(code, msg = '', data = {}) {
  function handlerSvrErr (line 37) | function handlerSvrErr(msg = '') {
  function handlerSucc (line 41) | function handlerSucc(msg = '') {
  function handlerAppErr (line 45) | function handlerAppErr(msg = '', code = appCode.LOGIC) {
  function handlerData (line 50) | function handlerData(data, msg = '') {

FILE: cloudfunctions/mcloud/framework/core/application.js
  function app (line 15) | async function app(event, context) {
  function beforeApp (line 164) | function beforeApp(method) {
  function showEvent (line 174) | function showEvent(event) {

FILE: cloudfunctions/mcloud/framework/database/db_util.js
  constant MAX_RECORD_SIZE (line 11) | const MAX_RECORD_SIZE = 1000;
  constant DEFAULT_RECORD_SIZE (line 12) | const DEFAULT_RECORD_SIZE = 20;
  function getCmd (line 21) | function getCmd() {
  function insertBatch (line 26) | async function insertBatch(collectionName, data, size = 1000) {
  function insert (line 38) | async function insert(collectionName, data) {
  function edit (line 46) | async function edit(collectionName, where, data) {
  function inc (line 65) | async function inc(collectionName, where, field, val = 1) {
  function mul (line 85) | async function mul(collectionName, where, field, val = 1) {
  function del (line 105) | async function del(collectionName, where) {
  function count (line 120) | async function count(collectionName, where) {
  function distinct (line 133) | async function distinct(collectionName, where, field) {
  function distinctCnt (line 152) | async function distinctCnt(collectionName, where, field) {
  function groupSum (line 157) | async function groupSum(collectionName, where, groupField, fields) {
  function groupCount (line 192) | async function groupCount(collectionName, where, groupField) {
  function sum (line 217) | async function sum(collectionName, where, field) {
  function max (line 237) | async function max(collectionName, where, field) {
  function min (line 256) | async function min(collectionName, where, field) {
  function clear (line 275) | async function clear(collectionName) {
  function isExistCollection (line 283) | async function isExistCollection(collectionName) {
  function createCollection (line 293) | async function createCollection(collectionName) {
  function rand (line 307) | async function rand(collectionName, where = {}, fields = '*', size = 1) {
  function getListByArray (line 340) | async function getListByArray(collectionName, arrField, where, fields, o...
  function getListJoin (line 413) | async function getListJoin(collectionName, joinParams, where, fields, or...
  function getListJoinCount (line 506) | async function getListJoinCount(collectionName, joinParams, where) {
  function getList (line 533) | async function getList(collectionName, where, fields = '*', orderBy = {}...
  function getAllBig (line 584) | async function getAllBig(collectionName, where, fields = '*', orderBy, s...
  function getAll (line 606) | async function getAll(collectionName, where, fields = '*', orderBy, size...
  function getAllByArray (line 630) | async function getAllByArray(collectionName, arrField, where, fields = '...
  function getOne (line 656) | async function getOne(collectionName, where, fields = '*', orderBy = {}) {
  function fmtOrderBy (line 685) | async function fmtOrderBy(query, orderBy) {
  function fmtJoinSort (line 692) | function fmtJoinSort(sort) {
  function fmtFields (line 708) | function fmtFields(fields) {
  function fmtWhere (line 724) | function fmtWhere(where) {
  function fmtWhereSimple (line 782) | function fmtWhereSimple(arr) {

FILE: cloudfunctions/mcloud/framework/database/model.js
  class Model (line 14) | class Model {
    method getOne (line 16) | static async getOne(where, fields = '*', orderBy = {}) {
    method edit (line 20) | static async edit(where, data) {
    method count (line 41) | static async count(where) {
    method insert (line 45) | static async insert(data) {
    method insertOrUpdate (line 80) | static async insertOrUpdate(where, data) {
    method insertBatch (line 90) | static async insertBatch(data = [], size = 1000) {
    method del (line 131) | static async del(where) {
    method inc (line 135) | static async inc(where, field, val = 1) {
    method mul (line 139) | static async mul(where, field, val = 1) {
    method groupSum (line 143) | static async groupSum(where, groupField, field) {
    method groupCount (line 147) | static async groupCount(where, groupField) {
    method sum (line 151) | static async sum(where, field) {
    method distinct (line 155) | static async distinct(where, field) {
    method distinctCnt (line 159) | static async distinctCnt(where, field) {
    method max (line 163) | static async max(where, field) {
    method min (line 167) | static async min(where, field) {
    method clear (line 171) | static async clear() {
    method rand (line 175) | static async rand(where = {}, fields = '*', size = 1) {
    method getAll (line 179) | static async getAll(where, fields, orderBy, size = 100) {
    method getAllBig (line 183) | static async getAllBig(where, fields, orderBy, size = 1000) {
    method getAllByArray (line 187) | static async getAllByArray(arrField, where, fields, orderBy, size = 10...
    method getList (line 191) | static async getList(where, fields, orderBy, page, size, isTotal, oldT...
    method getListJoin (line 195) | static async getListJoin(joinParams, where, fields, orderBy, page = 1,...
    method getListJoinCount (line 199) | static async getListJoinCount(joinParams, where) {
    method getListByArray (line 203) | static async getListByArray(arrField, where, fields, orderBy, page = 1...
    method converDBStructure (line 207) | static converDBStructure(stru) {
    method clearDirtyData (line 335) | static clearDirtyData(data) {
    method converDataType (line 344) | static converDataType(data, dbStructure) {
    method clearCreateData (line 384) | static clearCreateData(data) {
    method clearEditData (line 433) | static clearEditData(data) {
    method getDesc (line 444) | static getDesc(enumName, val) {

FILE: cloudfunctions/mcloud/framework/database/multi_model.js
  class MultiModel (line 13) | class MultiModel extends Model {
    method C (line 15) | static C(cl) {
    method _getWhere (line 19) | static _getWhere(where, mustPID = true) {
    method getOneField (line 32) | static async getOneField(where, field, mustPID = true) {
    method getOne (line 46) | static async getOne(where, fields = '*', orderBy = {}, mustPID = true) {
    method edit (line 51) | static async edit(where, data, mustPID = true) {
    method editForms (line 56) | static async editForms(where, formName, objName, hasImageForms, mustPI...
    method count (line 83) | static async count(where, mustPID = true) {
    method insert (line 88) | static async insert(data, mustPID = true) {
    method insertBatch (line 93) | static async insertBatch(data = [], size = 1000, mustPID = true) {
    method insertOrUpdate (line 103) | static async insertOrUpdate(where, data, mustPID = true) {
    method del (line 110) | static async del(where, mustPID = true) {
    method clear (line 115) | static async clear() {
    method inc (line 119) | static async inc(where, field, val = 1, mustPID = true) {
    method mul (line 124) | static async mul(where, field, val = 1, mustPID = true) {
    method groupSum (line 129) | static async groupSum(where, groupField, field, mustPID = true) {
    method groupCount (line 134) | static async groupCount(where, groupField, mustPID = true) {
    method sum (line 139) | static async sum(where, field, mustPID = true) {
    method distinct (line 144) | static async distinct(where, field, mustPID = true) {
    method distinctCnt (line 149) | static async distinctCnt(where, field, mustPID = true) {
    method max (line 154) | static async max(where, field, mustPID = true) {
    method min (line 159) | static async min(where, field, mustPID = true) {
    method rand (line 164) | static async rand(where, field, size = 1, mustPID = true) {
    method getAll (line 169) | static async getAll(where, fields, orderBy, size = 100, mustPID = true) {
    method getAllBig (line 174) | static async getAllBig(where, fields, orderBy, size = 1000, mustPID = ...
    method getAllByArray (line 179) | static async getAllByArray(arrField, where, fields, orderBy, size = 10...
    method getList (line 184) | static async getList(where, fields, orderBy, page, size, isTotal, oldT...
    method getListJoin (line 189) | static async getListJoin(joinParams, where, fields, orderBy, page = 1,...
    method getListJoinCount (line 194) | static async getListJoinCount(joinParams, where, mustPID = true) {

FILE: cloudfunctions/mcloud/framework/lib/faker_lib.js
  function getRnd (line 10) | function getRnd(arr, isNullable = false, ex = '') {
  function getProvince (line 38) | function getProvince(isNullable = false, ex = '') {
  function getProvinceAbbr (line 54) | function getProvinceAbbr(isNullable = false, ex = '') {
  function getCity (line 69) | function getCity(isNullable = false, ex = '') {
  function getArea (line 84) | function getArea(isNullable = false, ex = '') {
  function getStreet (line 104) | function getStreet(isNullable = false, ex = '') {
  function getAddress (line 110) | function getAddress() {
  function getCountry (line 115) | function getCountry(isNullable = false, ex = '') {
  function getCompanyPrefix (line 169) | function getCompanyPrefix(isNullable = false, ex = '') {
  function getCompanyType (line 192) | function getCompanyType(isNullable = false, ex = '') {
  function getCompany (line 198) | function getCompany(isNullable = false, ex = '') {
  function getContent (line 205) | function getContent(size = 1, isNullable = false, ex = '') {
  function getWord (line 402) | function getWord(isNullable = false, ex = '') {
  function getWeek (line 411) | function getWeek(isNullable = false, ex = '') {
  function getMonth (line 417) | function getMonth(isNullable = false, ex = '') {
  function getFirstName (line 423) | function getFirstName(isNullable = false, ex = '') {
  function getFemaleName (line 460) | function getFemaleName(isNullable = false, ex = '') {
  function getMaleName (line 478) | function getMaleName(isNullable = false, ex = '') {
  function getName (line 496) | function getName(isNullable = false, ex = '') {
  function getIdCard (line 504) | function getIdCard(birthday = '', isNullable = false) {
  function getMobile (line 527) | function getMobile(isNullable = false, ex = '') {
  function getPhone (line 537) | function getPhone(isNullable = false, ex = '') {
  function getEnWord (line 547) | function getEnWord(isNullable = false, ex = '') {
  function getDomain (line 554) | function getDomain(isNullable = false, ex = '') {
  function getEmail (line 564) | function getEmail(isNullable = false, ex = '') {
  function getTimestamp (line 573) | function getTimestamp(step = 0) {
  function getAddTimestamp (line 582) | function getAddTimestamp(min = 0, max = 1) {
  function getDate (line 589) | function getDate(start = 1900, end = 2020) {
  function getInt (line 603) | function getInt(size) {
  function getRdArr (line 612) | function getRdArr(arr) {
  function getIntBetween (line 617) | function getIntBetween(min, max) {
  function getStr (line 622) | function getStr(size) {
  function getIntStr (line 633) | function getIntStr(size) {
  function getStrLower (line 644) | function getStrLower(size) {
  function getStrUpper (line 649) | function getStrUpper(size) {
  function getUuid (line 653) | function getUuid() {
  function getCollege (line 668) | function getCollege(isNullable = false, ex = '') {
  function getItem (line 675) | function getItem(isNullable = false, ex = '') {
  function getTrade (line 682) | function getTrade(isNullable = false, ex = '') {
  function getEdu (line 689) | function getEdu(isNullable = false, ex = '') {
  function getDuty (line 696) | function getDuty(isNullable = false, ex = '') {
  function getResource (line 703) | function getResource(isNullable = false, ex = '') {
  function getMotto (line 710) | function getMotto(isNullable = false, ex = '') {
  function getAvatar (line 717) | function getAvatar(isNullable) {
  function getNullable (line 725) | function getNullable(isNullable) {

FILE: cloudfunctions/mcloud/framework/lib/md5_lib.js
  function safe_add (line 7) | function safe_add(x, y) {
  function rol (line 16) | function rol(num, cnt) {
  function cmn (line 23) | function cmn(q, a, b, x, s, t) {
  function ff (line 27) | function ff(a, b, c, d, x, s, t) {
  function gg (line 31) | function gg(a, b, c, d, x, s, t) {
  function hh (line 35) | function hh(a, b, c, d, x, s, t) {
  function ii (line 39) | function ii(a, b, c, d, x, s, t) {
  function coreMD5 (line 47) | function coreMD5(x) {
  function binl2hex (line 138) | function binl2hex(binarray) {
  function binl2b64 (line 151) | function binl2b64(binarray) {
  function str2binl (line 166) | function str2binl(str) {
  function strw2binl (line 181) | function strw2binl(str) {
  function hexMD5 (line 195) | function hexMD5(str) {
  function hexMD5w (line 199) | function hexMD5w(str) {
  function b64MD5 (line 203) | function b64MD5(str) {
  function b64MD5w (line 207) | function b64MD5w(str) {
  function calcMD5 (line 211) | function calcMD5(str) {

FILE: cloudfunctions/mcloud/framework/lib/mini_lib.js
  function fmtThing (line 12) | function fmtThing(str) { //20个以内字符,可汉字、数字、字母或符号组合
  function fmtCharacterString (line 16) | function fmtCharacterString(str) { //32位以内数字、字母或符号
  function fmtPhrase (line 20) | function fmtPhrase(str) { //5个以内汉字
  function sendMiniOnceTempMsg (line 29) | async function sendMiniOnceTempMsg(body, key = '') {

FILE: cloudfunctions/mcloud/framework/platform/controller/base_admin_controller.js
  class BaseAdminController (line 13) | class BaseAdminController extends BaseController {
    method constructor (line 15) | constructor(route, openId, event) {
    method isAdmin (line 27) | async isAdmin() {
    method isSuperAdmin (line 36) | async isSuperAdmin() {
    method log (line 45) | async log(content, type) {
    method logSys (line 50) | async logSys(content) {
    method logUser (line 54) | async logUser(content) {
    method logOther (line 58) | async logOther(content) {
    method logNews (line 62) | async logNews(content) {

FILE: cloudfunctions/mcloud/framework/platform/controller/base_controller.js
  class BaseController (line 15) | class BaseController {
    method constructor (line 17) | constructor(route, openId, event) {
    method validateData (line 47) | validateData(rules = {}) {
    method getParameter (line 53) | getParameter(name) {

FILE: cloudfunctions/mcloud/framework/platform/model/admin_model.js
  class AdminModel (line 10) | class AdminModel extends BaseModel {

FILE: cloudfunctions/mcloud/framework/platform/model/base_model.js
  class BaseModel (line 10) | class BaseModel extends MultiModel {

FILE: cloudfunctions/mcloud/framework/platform/model/log_model.js
  class LogModel (line 10) | class LogModel extends BaseModel {

FILE: cloudfunctions/mcloud/framework/platform/service/base_admin_service.js
  class BaseAdminService (line 17) | class BaseAdminService extends BaseService {
    method isAdmin (line 21) | async isAdmin(token) {
    method isSuperAdmin (line 49) | async isSuperAdmin(token) {
    method insertLog (line 65) | async insertLog(content, admin, type) {

FILE: cloudfunctions/mcloud/framework/platform/service/base_service.js
  class BaseService (line 11) | class BaseService {
    method constructor (line 12) | constructor() {
    method AppError (line 23) | AppError(msg, code = appCode.LOGIC) {
    method fmtSearchDate (line 28) | fmtSearchDate(where, search, field) {
    method fmtOrderBySort (line 39) | fmtOrderBySort(sortVal, defaultSort) {

FILE: cloudfunctions/mcloud/framework/utils/data_util.js
  function getTitleByForm (line 42) | function getTitleByForm(arr) {
  function getValByForm (line 57) | function getValByForm(arr, mark, title) {
  function dbFormsFix (line 80) | function dbFormsFix(forms) {
  function dbForms2Obj (line 91) | function dbForms2Obj(forms, excludeContent = false) {
  function makeID (line 105) | function makeID() {
  function spArr (line 121) | function spArr(arr, size) {
  function str2Arr (line 137) | function str2Arr(str, sp = ',') {
  function isNumber (line 158) | function isNumber(val) {
  function getArrByKey (line 173) | function getArrByKey(arr, key) {
  function getArrByKeyMulti (line 188) | function getArrByKeyMulti(arr, keys = []) {
  function getDataByKey (line 211) | function getDataByKey(arr, key, val) {
  function fmtText (line 227) | function fmtText(content, len = -1) {
  function toHump (line 237) | function toHump(name) {
  function toLine (line 248) | function toLine(name) {
  function fmtMoney (line 259) | function fmtMoney(s, dot = ',', prefix = '¥') {
  function arr2ObjectArr (line 277) | function arr2ObjectArr(arr, key1, key2, key3) {
  function objArrSortAsc (line 295) | function objArrSortAsc(property) {
  function objArrSortDesc (line 313) | function objArrSortDesc(property) {
  function arrAddDel (line 331) | function arrAddDel(arr, data, sort = 'asc') {
  function deepClone (line 348) | function deepClone(data) {
  function padLeft (line 356) | function padLeft(str, len, charStr) {
  function padRight (line 364) | function padRight(str, len, charStr) {
  function getSelectOptions (line 374) | function getSelectOptions(str) {
  function arraySwap (line 392) | function arraySwap(arr, index1, index2) {
  function arrayTop (line 398) | function arrayTop(arr, idx) {
  function arrayBottom (line 405) | function arrayBottom(arr, idx) {
  function insertObjArrByKey (line 418) | function insertObjArrByKey(arr, key, val, obj) {
  function getValFromArr (line 444) | function getValFromArr(arr, key = 'val', val = '') {
  function splitTextByKey (line 455) | function splitTextByKey(txt, key) {

FILE: cloudfunctions/mcloud/framework/utils/export_util.js
  function getExportDataURL (line 16) | async function getExportDataURL(key) {
  function deleteDataExcel (line 36) | async function deleteDataExcel(key) {
  function exportDataExcel (line 75) | async function exportDataExcel(key, title, total, data, options = {}) {

FILE: cloudfunctions/mcloud/framework/utils/log_util.js
  class LogUtil (line 8) | class LogUtil {
    method constructor (line 10) | constructor(level = 'info') {
    method debug (line 41) | debug(str, ex = '') {
    method info (line 48) | info(str, ex = '') {
    method warn (line 56) | warn(str, ex = '') {
    method error (line 63) | error(str, ex = '') {
    method fatal (line 70) | fatal(str, ex = '') {
    method _getTime (line 77) | _getTime() {
    method err (line 81) | err(str) {
    method getLogOut (line 85) | getLogOut() {

FILE: cloudfunctions/mcloud/framework/utils/math_util.js
  function percent (line 9) | function percent(num1, num2) {
  function arrayObjecSortAsc (line 14) | function arrayObjecSortAsc(property) {
  function arrayObjecSortDesc (line 23) | function arrayObjecSortDesc(property) {

FILE: cloudfunctions/mcloud/framework/utils/setup/setup_model.js
  class SetupModel (line 10) | class SetupModel extends MultiModel {

FILE: cloudfunctions/mcloud/framework/utils/setup/setup_util.js
  function set (line 15) | async function set(key, val, type = '') {
  function get (line 38) | async function get(key) {
  function get (line 59) | async function get(key) {
  function remove (line 80) | async function remove(key, fuzzy = false) {

FILE: cloudfunctions/mcloud/framework/utils/time_util.js
  function simpleDate (line 10) | function simpleDate(date) {
  function fmtDateCHN (line 25) | function fmtDateCHN(date, fmt = 'Y-M-D') {
  function timestamp2Time (line 62) | function timestamp2Time(unixtime, format = 'Y-M-D h:m:s', diff = 0) {
  function timestame2Ago (line 80) | function timestame2Ago(dateTimeStamp, fmt = 'Y-M-D', diff = 0) { //dateT...
  function formatNumber (line 120) | function formatNumber(n) {
  function time2Timestamp (line 130) | function time2Timestamp(date) {
  function time (line 147) | function time(fmt, step = 0) {
  function getDayFirstTimestamp (line 157) | function getDayFirstTimestamp(timestamp) {
  function getAge (line 166) | function getAge(birth, isMonth = false) {
  function week (line 216) | function week(day) {
  function getMonthFirstTimestamp (line 226) | function getMonthFirstTimestamp(timestamp) {
  function getMonthLastTimestamp (line 234) | function getMonthLastTimestamp(timestamp) {
  function getNowMinTimestamp (line 242) | function getNowMinTimestamp() {
  function getFirstOfWeek (line 253) | function getFirstOfWeek(date) {
  function getLastOfWeek (line 264) | function getLastOfWeek(date) {
  function getFirstOfMonth (line 275) | function getFirstOfMonth(date) {
  function getLastOfMonth (line 281) | function getLastOfMonth(date) {
  function getTimeLeft (line 294) | function getTimeLeft(datetimeTo, flag = 1) {

FILE: cloudfunctions/mcloud/framework/utils/util.js
  function getProjectId (line 7) | function getProjectId() {
  function isDefined (line 18) | function isDefined(val) {
  function isObjectNull (line 30) | function isObjectNull(obj) {
  function sleep (line 40) | function sleep(time) {

FILE: cloudfunctions/mcloud/framework/validate/content_check.js
  function checkImgClient (line 16) | async function checkImgClient(imgData, mine) {
  function checkImgAdmin (line 26) | async function checkImgAdmin(imgData, mine) {
  function checkImg (line 34) | async function checkImg(imgData, mine) {
  function checkTextMultiAdmin (line 62) | async function checkTextMultiAdmin(input) {
  function checkTextMultiClient (line 71) | async function checkTextMultiClient(input) {
  function checkTextMulti (line 80) | async function checkTextMulti(input) {
  function checkTextAdmin (line 96) | async function checkTextAdmin(txt) {
  function checkTextClient (line 105) | async function checkTextClient(txt) {
  function checkText (line 114) | async function checkText(txt) {

FILE: cloudfunctions/mcloud/framework/validate/data_check.js
  constant CHECK_OPEN (line 10) | const CHECK_OPEN = true;
  constant CHECK_SOURCE (line 11) | const CHECK_SOURCE = 'admin';
  function isDefined (line 17) | function isDefined(val) {
  function isNull (line 25) | function isNull(value) {
  function isStrAndArrNull (line 31) | function isStrAndArrNull(value) {
  function isRealNull (line 41) | function isRealNull(value) {
  function getDataType (line 52) | function getDataType(value) {
  function checkRequired (line 58) | function checkRequired(value, desc = '') {
  function checkMin (line 79) | function checkMin(value, min, desc = '') {
  function checkMax (line 100) | function checkMax(value, max, desc = '') {
  function checkLen (line 121) | function checkLen(value, len, desc = '') {
  function checkMobile (line 137) | function checkMobile(value, desc = '') {
  function checkInt (line 144) | function checkInt(value, desc = '') {
  function checkDigit (line 151) | function checkDigit(value, desc = '') {
  function checkLetter (line 158) | function checkLetter(value, desc = '') {
  function checkMoney (line 165) | function checkMoney(value, desc = '') {
  function checkLetterNum (line 173) | function checkLetterNum(value, desc = '') {
  function checkId (line 180) | function checkId(value, desc = '', min = 1, max = 100) {
  function checkEmail (line 194) | function checkEmail(value, desc = '') {
  function checkDate (line 202) | function checkDate(value, desc = '') {
  function checkYear (line 215) | function checkYear(value, desc = '') {
  function checkYearMonth (line 225) | function checkYearMonth(value, desc = '') {
  function checkTime (line 236) | function checkTime(value, desc = '') {
  function checkHourMinute (line 248) | function checkHourMinute(value, desc = '') {
  function checkDatimeTime (line 259) | function checkDatimeTime(value, desc = '') {
  function checkArray (line 273) | function checkArray(value, desc = '') {
  function checkObject (line 278) | function checkObject(value, desc = '') {
  function checkBoolean (line 283) | function checkBoolean(value, desc = '') {
  function checkIn (line 289) | function checkIn(value, ref, desc = '') {
  function checkIds (line 300) | function checkIds(value, desc) {}
  function checkString (line 302) | function checkString(value, desc) {
  function check (line 308) | function check(data, rules, that) {
  function _showError (line 571) | function _showError(result, formName, that) { //admin/client

FILE: cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_album_controller.js
  class AdminAlbumController (line 15) | class AdminAlbumController extends BaseProjectAdminController {
    method sortAlbum (line 18) | async sortAlbum() {
    method vouchAlbum (line 34) | async vouchAlbum() {
    method statusAlbum (line 50) | async statusAlbum() {
    method getAdminAlbumList (line 68) | async getAdminAlbumList() {
    method insertAlbum (line 106) | async insertAlbum() {
    method getAlbumDetail (line 136) | async getAlbumDetail() {
    method editAlbum (line 153) | async editAlbum() {
    method delAlbum (line 180) | async delAlbum() {
    method updateAlbumForms (line 202) | async updateAlbumForms() {

FILE: cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_home_controller.js
  class AdminHomeController (line 10) | class AdminHomeController extends BaseProjectAdminController {
    method adminHome (line 14) | async adminHome() {
    method clearVouchData (line 31) | async clearVouchData() {

FILE: cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_meet_controller.js
  class AdminMeetController (line 14) | class AdminMeetController extends BaseProjectAdminController {
    method _getLeaveDay (line 17) | _getLeaveDay(days) {
    method getDayList (line 26) | async getDayList() {
    method genSelfCheckinQr (line 43) | async genSelfCheckinQr() {
    method checkinJoin (line 59) | async checkinJoin() {
    method scanJoin (line 75) | async scanJoin() {
    method sortMeet (line 91) | async sortMeet() { // 数据校验
    method vouchMeet (line 107) | async vouchMeet() {
    method statusMeet (line 123) | async statusMeet() {
    method statusJoin (line 146) | async statusJoin() {
    method delJoin (line 164) | async delJoin() {
    method getAdminMeetList (line 180) | async getAdminMeetList() {
    method getJoinList (line 218) | async getJoinList() {
    method insertMeet (line 260) | async insertMeet() {
    method getMeetDetail (line 292) | async getMeetDetail() {
    method editMeet (line 309) | async editMeet() {
    method delMeet (line 341) | async delMeet() {
    method updateMeetContent (line 366) | async updateMeetContent() {
    method updateMeetStyleSet (line 390) | async updateMeetStyleSet() {
    method cancelJoinByTimeMark (line 411) | async cancelJoinByTimeMark() {
    method insertMeetTemp (line 429) | async insertMeetTemp() {
    method editMeetTemp (line 448) | async editMeetTemp() {
    method getMeetTempList (line 467) | async getMeetTempList() {
    method delMeetTemp (line 477) | async delMeetTemp() {
    method joinDataGet (line 496) | async joinDataGet() {
    method joinDataExport (line 516) | async joinDataExport() {
    method joinDataDel (line 535) | async joinDataDel() {

FILE: cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_mgr_controller.js
  class AdminMgrController (line 14) | class AdminMgrController extends BaseProjectAdminController {
    method adminLogin (line 16) | async adminLogin() {
    method delMgr (line 32) | async delMgr() {
    method statusMgr (line 49) | async statusMgr() {
    method getMgrList (line 66) | async getMgrList() {
    method insertMgr (line 99) | async insertMgr() {
    method editMgr (line 121) | async editMgr() {
    method pwdMgr (line 145) | async pwdMgr() {
    method getMgrDetail (line 167) | async getMgrDetail() {
    method clearLog (line 183) | async clearLog() {
    method getLogList (line 191) | async getLogList() {

FILE: cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_news_controller.js
  class AdminNewsController (line 15) | class AdminNewsController extends BaseProjectAdminController {
    method sortNews (line 18) | async sortNews() {
    method vouchNews (line 34) | async vouchNews() {
    method statusNews (line 50) | async statusNews() {
    method getAdminNewsList (line 68) | async getAdminNewsList() {
    method updateNewsContent (line 108) | async updateNewsContent() {
    method insertNews (line 129) | async insertNews() {
    method getNewsDetail (line 160) | async getNewsDetail() {
    method editNews (line 180) | async editNews() {
    method delNews (line 208) | async delNews() {
    method updateNewsPic (line 233) | async updateNewsPic() {
    method updateNewsForms (line 250) | async updateNewsForms() {

FILE: cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_product_controller.js
  class AdminProductController (line 16) | class AdminProductController extends BaseProjectAdminController {
    method sortProduct (line 19) | async sortProduct() {
    method vouchProduct (line 35) | async vouchProduct() {
    method statusProduct (line 51) | async statusProduct() {
    method getAdminProductList (line 69) | async getAdminProductList() {
    method insertProduct (line 107) | async insertProduct() {
    method getProductDetail (line 137) | async getProductDetail() {
    method editProduct (line 154) | async editProduct() {
    method delProduct (line 181) | async delProduct() {
    method updateProductForms (line 203) | async updateProductForms() {

FILE: cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_setup_controller.js
  class AdminSetupController (line 11) | class AdminSetupController extends BaseProjectAdminController {
    method setSetup (line 14) | async setSetup() {
    method setContentSetup (line 34) | async setContentSetup() {
    method genMiniQr (line 53) | async genMiniQr() {

FILE: cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_user_controller.js
  class AdminUserController (line 13) | class AdminUserController extends BaseProjectAdminController {
    method getUserDetail (line 17) | async getUserDetail() {
    method getUserList (line 44) | async getUserList() {
    method delUser (line 79) | async delUser() {
    method statusUser (line 100) | async statusUser() {
    method userDataGet (line 119) | async userDataGet() {
    method userDataExport (line 139) | async userDataExport() {
    method userDataDel (line 156) | async userDataDel() {

FILE: cloudfunctions/mcloud/project/TRIP1/controller/admin/base_project_admin_controller.js
  class BaseProjectAdminController (line 10) | class BaseProjectAdminController extends BaseAdminController {
    method initSetup (line 12) | async initSetup() {

FILE: cloudfunctions/mcloud/project/TRIP1/controller/album_controller.js
  class AlbumController (line 11) | class AlbumController extends BaseProjectController {
    method getAlbumList (line 14) | async getAlbumList() {
    method viewAlbum (line 50) | async viewAlbum() {

FILE: cloudfunctions/mcloud/project/TRIP1/controller/base_project_controller.js
  class BaseProjectController (line 10) | class BaseProjectController extends BaseController {
    method initSetup (line 13) | async initSetup() {

FILE: cloudfunctions/mcloud/project/TRIP1/controller/check_controller.js
  class CheckController (line 10) | class CheckController extends BaseProjectController {
    method checkImg (line 15) | async checkImg() {

FILE: cloudfunctions/mcloud/project/TRIP1/controller/fav_controller.js
  class FavController (line 11) | class FavController extends BaseProjectController {
    method updateFav (line 14) | async updateFav() {
    method delFav (line 32) | async delFav() {
    method isFav (line 47) | async isFav() {
    method getMyFavList (line 61) | async getMyFavList() {

FILE: cloudfunctions/mcloud/project/TRIP1/controller/home_controller.js
  class HomeController (line 10) | class HomeController extends BaseProjectController {
    method getSetup (line 12) | async getSetup() {
    method getHomeList (line 28) | async getHomeList() {

FILE: cloudfunctions/mcloud/project/TRIP1/controller/meet_controller.js
  class MeetController (line 12) | class MeetController extends BaseProjectController {
    method transMeetList (line 16) | transMeetList(list) {
    method getMeetListByDay (line 33) | async getMeetListByDay() {
    method getHasDaysFromDay (line 51) | async getHasDaysFromDay() {
    method getMeetList (line 69) | async getMeetList() {
    method getMyJoinList (line 104) | async getMyJoinList() {
    method getMyJoinSomeday (line 147) | async getMyJoinSomeday() {
    method getMyJoinDetail (line 169) | async getMyJoinDetail() {
    method cancelMyJoin (line 189) | async cancelMyJoin() {
    method userSelfCheckin (line 204) | async userSelfCheckin() {
    method detailForJoin (line 220) | async detailForJoin() {
    method viewMeet (line 241) | async viewMeet() {
    method beforeJoin (line 261) | async beforeJoin() {
    method join (line 276) | async join() {
    method _getLeaveDay (line 293) | _getLeaveDay(days) {

FILE: cloudfunctions/mcloud/project/TRIP1/controller/my_controller.js
  class MyController (line 9) | class MyController extends BaseProjectController {

FILE: cloudfunctions/mcloud/project/TRIP1/controller/news_controller.js
  class NewsController (line 11) | class NewsController extends BaseProjectController {
    method transNewsList (line 14) | transNewsList(list) {
    method getNewsList (line 30) | async getNewsList() {
    method viewNews (line 68) | async viewNews() {

FILE: cloudfunctions/mcloud/project/TRIP1/controller/passport_controller.js
  class PassportController (line 11) | class PassportController extends BaseProjectController {
    method getMyDetail (line 14) | async getMyDetail() {
    method getPhone (line 20) | async getPhone() {
    method register (line 37) | async register() {
    method editBase (line 57) | async editBase() {
    method login (line 76) | async login() {

FILE: cloudfunctions/mcloud/project/TRIP1/controller/product_controller.js
  class ProductController (line 12) | class ProductController extends BaseProjectController {
    method getProductList (line 15) | async getProductList() {
    method viewProduct (line 50) | async viewProduct() {

FILE: cloudfunctions/mcloud/project/TRIP1/controller/test/test_controller.js
  class TestController (line 19) | class TestController extends BaseController {
    method test (line 21) | async test() {
    method mockEnrollJoin (line 30) | async mockEnrollJoin() {
    method mockActivityJoin (line 70) | async mockActivityJoin() {
    method mockVoteJoin (line 111) | async mockVoteJoin() {

FILE: cloudfunctions/mcloud/project/TRIP1/model/album_model.js
  class AlbumModel (line 10) | class AlbumModel extends BaseProjectModel {

FILE: cloudfunctions/mcloud/project/TRIP1/model/base_project_model.js
  class BaseProjectModel (line 10) | class BaseProjectModel extends BaseModel {

FILE: cloudfunctions/mcloud/project/TRIP1/model/day_model.js
  class DayModel (line 10) | class DayModel extends BaseProjectModel {

FILE: cloudfunctions/mcloud/project/TRIP1/model/fav_model.js
  class FavModel (line 10) | class FavModel extends BaseProjectModel {

FILE: cloudfunctions/mcloud/project/TRIP1/model/join_model.js
  class JoinModel (line 10) | class JoinModel extends BaseProjectModel {

FILE: cloudfunctions/mcloud/project/TRIP1/model/meet_model.js
  class MeetModel (line 10) | class MeetModel extends BaseProjectModel {

FILE: cloudfunctions/mcloud/project/TRIP1/model/news_model.js
  class NewsModel (line 10) | class NewsModel extends BaseProjectModel {

FILE: cloudfunctions/mcloud/project/TRIP1/model/product_model.js
  class ProductModel (line 10) | class ProductModel extends BaseProjectModel {

FILE: cloudfunctions/mcloud/project/TRIP1/model/user_model.js
  class UserModel (line 9) | class UserModel extends BaseProjectModel { }

FILE: cloudfunctions/mcloud/project/TRIP1/service/admin/admin_album_service.js
  class AdminAlbumService (line 16) | class AdminAlbumService extends BaseProjectAdminService {
    method vouchAlbumSetup (line 19) | async vouchAlbumSetup(id, vouch) {
    method insertAlbum (line 24) | async insertAlbum({
    method delAlbum (line 37) | async delAlbum(id) {
    method getAlbumDetail (line 43) | async getAlbumDetail(id) {
    method updateAlbumForms (line 56) | async updateAlbumForms({
    method editAlbum (line 65) | async editAlbum({
    method getAdminAlbumList (line 78) | async getAdminAlbumList({
    method statusAlbum (line 136) | async statusAlbum(id, status) {
    method sortAlbum (line 141) | async sortAlbum(id, sort) {
    method vouchAlbum (line 146) | async vouchAlbum(id, vouch) {

FILE: cloudfunctions/mcloud/project/TRIP1/service/admin/admin_home_service.js
  class AdminHomeService (line 16) | class AdminHomeService extends BaseProjectAdminService {
    method adminHome (line 21) | async adminHome() {
    method clearUserData (line 39) | async clearUserData(userId) {
    method clearVouchData (line 46) | async clearVouchData() {
    method updateHomeVouch (line 58) | async updateHomeVouch(node) {
    method delHomeVouch (line 81) | async delHomeVouch(id) {

FILE: cloudfunctions/mcloud/project/TRIP1/service/admin/admin_meet_service.js
  constant SETUP_MEET_TEMP_KEY (line 23) | const SETUP_MEET_TEMP_KEY = 'SETUP_MEET_TEMP';
  constant EXPORT_JOIN_DATA_KEY (line 26) | const EXPORT_JOIN_DATA_KEY = 'EXPORT_JOIN_DATA';
  class AdminMeetService (line 28) | class AdminMeetService extends BaseProjectAdminService {
    method vouchMeetSetup (line 31) | async vouchMeetSetup(id, vouch) {
    method getDayList (line 37) | async getDayList(meetId, start, end) {
    method statJoinCntByMeet (line 49) | async statJoinCntByMeet(meetId) {
    method genSelfCheckinQr (line 70) | async genSelfCheckinQr(page, timeMark) {
    method checkinJoin (line 75) | async checkinJoin(joinId, flag) {
    method scanJoin (line 80) | async scanJoin(meetId, code) {
    method checkHasJoinCnt (line 88) | checkHasJoinCnt(times) {
    method getCanModifyDaysSet (line 97) | getCanModifyDaysSet(daysSet) {
    method cancelJoinByTimeMark (line 109) | async cancelJoinByTimeMark(admin, meetId, timeMark, reason) {
    method insertMeet (line 116) | async insertMeet(adminId, {
    method delMeet (line 130) | async delMeet(id) {
    method getMeetDetail (line 135) | async getMeetDetail(id) {
    method updateMeetContent (line 154) | async updateMeetContent({
    method updateMeetStyleSet (line 167) | async updateMeetStyleSet({
    method _editDays (line 177) | async _editDays(meetId, nowDay, daysSetData) {
    method editMeet (line 183) | async editMeet({
    method getJoinList (line 198) | async getJoinList({
    method getAdminMeetList (line 252) | async getAdminMeetList({
    method delJoin (line 304) | async delJoin(joinId) {
    method statusJoin (line 312) | async statusJoin(admin, joinId, status, reason = '') {
    method statusMeet (line 317) | async statusMeet(id, status) {
    method sortMeet (line 322) | async sortMeet(id, sort) {
    method vouchMeet (line 327) | async vouchMeet(id, vouch) {
    method insertMeetTemp (line 333) | async insertMeetTemp({
    method editMeetTemp (line 343) | async editMeetTemp({
    method delMeetTemp (line 354) | async delMeetTemp(id) {
    method getMeetTempList (line 361) | async getMeetTempList() {
    method getJoinDataURL (line 369) | async getJoinDataURL() {
    method deleteJoinDataExcel (line 374) | async deleteJoinDataExcel() {
    method exportJoinDataExcel (line 379) | async exportJoinDataExcel({

FILE: cloudfunctions/mcloud/project/TRIP1/service/admin/admin_mgr_service.js
  class AdminMgrService (line 15) | class AdminMgrService extends BaseProjectAdminService {
    method adminLogin (line 18) | async adminLogin(name, password) {
    method clearLog (line 60) | async clearLog() {
    method getLogList (line 66) | async getLogList({
    method getMgrList (line 108) | async getMgrList({
    method delMgr (line 157) | async delMgr(id, myAdminId) {
    method insertMgr (line 162) | async insertMgr({
    method statusMgr (line 173) | async statusMgr(id, status, myAdminId) {
    method getMgrDetail (line 179) | async getMgrDetail(id) {
    method editMgr (line 192) | async editMgr(id, {
    method pwdtMgr (line 203) | async pwdtMgr(adminId, oldPassword, password) {

FILE: cloudfunctions/mcloud/project/TRIP1/service/admin/admin_news_service.js
  class AdminNewsService (line 16) | class AdminNewsService extends BaseProjectAdminService {
    method vouchNewsSetup (line 19) | async vouchNewsSetup(id, vouch) {
    method insertNews (line 24) | async insertNews({
    method delNews (line 38) | async delNews(id) {
    method getNewsDetail (line 43) | async getNewsDetail(id) {
    method updateNewsForms (line 56) | async updateNewsForms({
    method updateNewsContent (line 68) | async updateNewsContent({
    method updateNewsPic (line 81) | async updateNewsPic({
    method editNews (line 92) | async editNews({
    method getAdminNewsList (line 106) | async getAdminNewsList({
    method statusNews (line 165) | async statusNews(id, status) {
    method sortNews (line 170) | async sortNews(id, sort) {
    method vouchNews (line 175) | async vouchNews(id, vouch) {

FILE: cloudfunctions/mcloud/project/TRIP1/service/admin/admin_product_service.js
  class AdminProductService (line 15) | class AdminProductService extends BaseProjectAdminService {
    method vouchProductSetup (line 18) | async vouchProductSetup(id, vouch) {
    method insertProduct (line 23) | async insertProduct({
    method delProduct (line 36) | async delProduct(id) {
    method getProductDetail (line 42) | async getProductDetail(id) {
    method updateProductForms (line 55) | async updateProductForms({
    method editProduct (line 64) | async editProduct({
    method getAdminProductList (line 77) | async getAdminProductList({
    method statusProduct (line 135) | async statusProduct(id, status) {
    method sortProduct (line 140) | async sortProduct(id, sort) {
    method vouchProduct (line 146) | async vouchProduct(id, vouch) {

FILE: cloudfunctions/mcloud/project/TRIP1/service/admin/admin_setup_service.js
  class AdminSetupService (line 14) | class AdminSetupService extends BaseProjectAdminService {
    method setSetup (line 17) | async setSetup(key, val, type = '') {
    method genMiniQr (line 22) | async genMiniQr(page, sc = 'qr') {

FILE: cloudfunctions/mcloud/project/TRIP1/service/admin/admin_user_service.js
  constant EXPORT_USER_DATA_KEY (line 17) | const EXPORT_USER_DATA_KEY = 'EXPORT_USER_DATA';
  class AdminUserService (line 19) | class AdminUserService extends BaseProjectAdminService {
    method getUser (line 23) | async getUser({
    method getUserList (line 34) | async getUserList({
    method statusUser (line 97) | async statusUser(id, status, reason) {
    method delUser (line 102) | async delUser(id) {
    method getUserDataURL (line 110) | async getUserDataURL() {
    method deleteUserDataExcel (line 115) | async deleteUserDataExcel() {
    method exportUserDataExcel (line 120) | async exportUserDataExcel(condition, fields) {

FILE: cloudfunctions/mcloud/project/TRIP1/service/admin/base_project_admin_service.js
  class BaseProjectAdminService (line 12) | class BaseProjectAdminService extends BaseAdminService {
    method getProjectId (line 14) | getProjectId() {
    method genDetailQr (line 18) | async genDetailQr(type, id) {

FILE: cloudfunctions/mcloud/project/TRIP1/service/album_service.js
  class AlbumService (line 11) | class AlbumService extends BaseProjectService {
    method viewAlbum (line 14) | async viewAlbum(id) {
    method getAlbumList (line 32) | async getAlbumList({

FILE: cloudfunctions/mcloud/project/TRIP1/service/base_project_service.js
  class BaseProjectService (line 15) | class BaseProjectService extends BaseService {
    method getProjectId (line 16) | getProjectId() {
    method initSetup (line 20) | async initSetup() {

FILE: cloudfunctions/mcloud/project/TRIP1/service/fav_service.js
  class FavService (line 11) | class FavService extends BaseProjectService {
    method isFav (line 14) | async isFav(userId, oid) {
    method updateFav (line 31) | async updateFav(userId, oid, title, type, path, cancelIfExist = true) {
    method delFav (line 66) | async delFav(userId, oid) {
    method getMyFavList (line 79) | async getMyFavList(userId, {

FILE: cloudfunctions/mcloud/project/TRIP1/service/home_service.js
  class HomeService (line 12) | class HomeService extends BaseProjectService {
    method getSetup (line 14) | async getSetup(key) {
    method getHomeList (line 19) | async getHomeList() {

FILE: cloudfunctions/mcloud/project/TRIP1/service/meet_service.js
  constant MEET_LOG_LEVEL (line 16) | const MEET_LOG_LEVEL = 'debug';
  class MeetService (line 18) | class MeetService extends BaseProjectService {
    method constructor (line 20) | constructor() {
    method AppError (line 30) | AppError(msg) {
    method _meetLog (line 35) | _meetLog(meet, func = '', msg = '') {
    method getMeetOneDay (line 42) | async getMeetOneDay(meetId, day, where, fields = '*') {
    method getDaysSet (line 52) | async getDaysSet(meetId, startDay, endDay = null) {
    method statJoinCnt (line 78) | async statJoinCnt(meetId, timeMark) {
    method beforeJoin (line 113) | async beforeJoin(userId, meetId, timeMark) {
    method join (line 118) | async join(userId, meetId, timeMark, forms) {
    method getDaySetByDay (line 186) | getDaySetByDay(meet, day) {
    method getDayByTimeMark (line 195) | getDayByTimeMark(timeMark) {
    method getDaySetByTimeMark (line 200) | getDaySetByTimeMark(meet, timeMark) {
    method getTimeSetByTimeMark (line 211) | getTimeSetByTimeMark(meet, timeMark) {
    method checkMeetTimeControll (line 226) | async checkMeetTimeControll(meet, timeMark) {
    method checkMeetRules (line 256) | async checkMeetRules(userId, meetId, timeMark) {
    method checkMeetLimitSet (line 280) | async checkMeetLimitSet(userId, meet, timeMark) {
    method checkMeetEndSet (line 306) | async checkMeetEndSet(meet, timeMark) {
    method viewMeet (line 328) | async viewMeet(meetId) {
    method userSelfCheckin (line 395) | async userSelfCheckin(userId, timeMark) {
    method detailForJoin (line 446) | async detailForJoin(userId, meetId, timeMark) {
    method getUsefulTimesByDaysSet (line 505) | async getUsefulTimesByDaysSet(meetId, day) {
    method getMeetListByDay (line 528) | async getMeetListByDay(day) {
    method getHasDaysFromDay (line 561) | async getHasDaysFromDay(day) {
    method getMeetList (line 582) | async getMeetList({
    method cancelMyJoin (line 638) | async cancelMyJoin(userId, joinId) {
    method getMyJoinDetail (line 683) | async getMyJoinDetail(userId, joinId) {
    method getMyJoinList (line 695) | async getMyJoinList(userId, {
    method getMyJoinSomeday (line 767) | async getMyJoinSomeday(userId, day) {

FILE: cloudfunctions/mcloud/project/TRIP1/service/news_service.js
  class NewsService (line 11) | class NewsService extends BaseProjectService {
    method viewNews (line 14) | async viewNews(id) {
    method getNewsList (line 32) | async getNewsList({

FILE: cloudfunctions/mcloud/project/TRIP1/service/passport_service.js
  class PassportService (line 12) | class PassportService extends BaseProjectService {
    method register (line 15) | async register(userId, {
    method getPhone (line 50) | async getPhone(cloudID) {
    method getMyDetail (line 65) | async getMyDetail(userId) {
    method editBase (line 74) | async editBase(userId, {
    method login (line 108) | async login(userId) {

FILE: cloudfunctions/mcloud/project/TRIP1/service/product_service.js
  class ProductService (line 11) | class ProductService extends BaseProjectService {
    method viewProduct (line 14) | async viewProduct(id) {
    method getProductList (line 32) | async getProductList({

FILE: miniprogram/cmpts/public/calendar/calendar_comm/calendar_comm_cmpt.js
  method attached (line 79) | attached() {
  method bindNextTap (line 96) | bindNextTap(e) { // 下月
  method bindLastTap (line 100) | bindLastTap(e) { // 上月
  method bindDayOneTap (line 104) | bindDayOneTap(e) { // 单个天点击
  method bindDayMultiTap (line 113) | bindDayMultiTap(e) { // 多选天点击
  method listTouchStart (line 131) | listTouchStart(e) {
  method listTouchMove (line 136) | listTouchMove(e) {

FILE: miniprogram/cmpts/public/calendar/calendar_lib.js
  function isHoliday (line 12) | function isHoliday(day) {
  function weekIndexInMonth (line 24) | function weekIndexInMonth(year = null, month = null, today = null) {
  function fmtDate (line 47) | function fmtDate(str) {
  function getNowTime (line 56) | function getNowTime(that) {
  function getMonthCnt (line 90) | function getMonthCnt(year, month) {
  function getLastMonthCnt (line 99) | function getLastMonthCnt(year, month) {
  function getLastMonthArr (line 109) | function getLastMonthArr(that, year, month) {
  function getNextMonthArr (line 148) | function getNextMonthArr(that, year, month, hasDayLen) {
  function createDay (line 217) | function createDay(that) {
  function listTouchEnd (line 278) | function listTouchEnd(that) {
  function bindToNowTap (line 309) | function bindToNowTap(that) {
  function bindDayMultiTap (line 340) | function bindDayMultiTap(e, that) {
  function bindDayOneTap (line 370) | function bindDayOneTap(e, that) {
  function bindNextTap (line 391) | function bindNextTap(that) {
  function bindLastTap (line 416) | function bindLastTap(that) {
  function bindFoldTap (line 441) | function bindFoldTap(that) {

FILE: miniprogram/cmpts/public/calendar/calendar_meet/calendar_meet_cmpt.js
  method attached (line 80) | attached() {
  method bindNextTap (line 97) | bindNextTap(e) { // 下月
  method bindLastTap (line 112) | bindLastTap(e) { // 上月
  method bindDayOneTap (line 126) | bindDayOneTap(e) { // 单个天点击
  method bindDayMultiTap (line 130) | bindDayMultiTap(e) { // 多选天点击
  method listTouchStart (line 154) | listTouchStart(e) {
  method listTouchMove (line 159) | listTouchMove(e) {

FILE: miniprogram/cmpts/public/checkbox/checkbox_cmpt.js
  method _fixDefaultVal (line 60) | _fixDefaultVal() { //传入数据不匹配的时候,修正父页面传入的的数组默认值

FILE: miniprogram/cmpts/public/editor/editor_cmpt.js
  method setGlow (line 63) | setGlow(cur) {

FILE: miniprogram/cmpts/public/form/form_set/form_set_cmpt.js
  method setGlow (line 48) | setGlow(cur) {

FILE: miniprogram/cmpts/public/form/form_set_helper.js
  function initFieldOne (line 20) | function initFieldOne(field) {
  function initFields (line 24) | function initFields(defaultFields = null) {
  function checkIDCard (line 120) | function checkIDCard(idcode) {
  function getMustHint (line 167) | function getMustHint(type) {
  function checkForm (line 178) | function checkForm(fields, forms, that) {
  function mark (line 333) | function mark() {
  function getTypeOptions (line 337) | function getTypeOptions() {
  function getOnlySetOptions (line 344) | function getOnlySetOptions() {
  function getOnlySetDesc (line 379) | function getOnlySetDesc(rule) {

FILE: miniprogram/cmpts/public/form/form_show/form_show_cmpt.js
  constant CACHE_FORM_SHOW_KEY (line 9) | const CACHE_FORM_SHOW_KEY = 'FORM_SHOW_CMPT';
  constant CACHE_FORM_SHOW_TIME (line 10) | const CACHE_FORM_SHOW_TIME = 86400 * 365;
  method getOneFormVal (line 456) | getOneFormVal(formName) {
  method setOneFormVal (line 468) | setOneFormVal(formName, val) {

FILE: miniprogram/cmpts/public/list/comm_list_cmpt.js
  method show (line 199) | async show() {
  method hide (line 207) | hide() {
  method resize (line 210) | resize(size) {
  method bindDateStartChange (line 470) | bindDateStartChange(e) {
  method bindDateEndChange (line 475) | bindDateEndChange(e) {

FILE: miniprogram/cmpts/public/picker_multi/picker_multi_cmpt.js
  function isExist (line 14) | function isExist(field) {

FILE: miniprogram/cmpts/public/picker_time/datetime_picker.js
  function withData (line 3) | function withData(param, unit = '') {
  function getLoopArray (line 8) | function getLoopArray(start, end, unit = '', step = 1) {
  function getMonthDay (line 28) | function getMonthDay(year, month, unit = '') {
  function getNewDateArry (line 57) | function getNewDateArry() {
  function dateTimePicker (line 70) | function dateTimePicker(startYear, endYear, date, minuStep = 1) {

FILE: miniprogram/cmpts/public/poster/poster_cmpt.js
  method bindPosterSuccessListener (line 145) | bindPosterSuccessListener(e) {
  method bindPosterFailListener (line 158) | bindPosterFailListener(e) {

FILE: miniprogram/cmpts/public/poster/poster_cmpt_helper.js
  function config1 (line 3) | async function config1({

FILE: miniprogram/cmpts/public/poster/wxa-plugin-canvas/index/index.js
  method drawBlock (line 6) | drawBlock({
  method drawText (line 88) | drawText(params) {
  method drawImage (line 126) | drawImage({
  method drawLine (line 188) | drawLine({
  method downloadResource (line 206) | downloadResource({
  method initCanvas (line 218) | initCanvas(w, h, debug) {
  method _drawRadiusRect (line 250) | _drawRadiusRect(x, y, w, h, r) {
  method _getTextWidth (line 279) | _getTextWidth(text) {
  method _drawSingleText (line 302) | _drawSingleText({
  method _downloadImageAndInfo (line 406) | _downloadImageAndInfo(image, index) {
  method _downImage (line 466) | _downImage(imageUrl) {
  method _getImageInfo (line 498) | _getImageInfo(imgPath, index) {
  method toPx (line 515) | toPx(rpx, int) {
  method toRpx (line 521) | toRpx(px, int) {
  method _mapHttpToHttps (line 531) | _mapHttpToHttps(rawUrl) {
  method created (line 547) | created() {
  method getHeight (line 561) | getHeight(config) {
  method create (line 611) | async create(config) {
  method initCtx (line 692) | initCtx() {

FILE: miniprogram/cmpts/public/poster/wxa-plugin-canvas/poster/index.js
  method ready (line 16) | ready() {
  method trigger (line 30) | trigger(event, data) {
  method once (line 35) | once(event, fun) {
  method downloadResource (line 41) | downloadResource(reset) {
  method onCreate (line 64) | onCreate(reset = false) {
  method onCreateSuccess (line 84) | onCreateSuccess(e) {
  method onCreateFail (line 90) | onCreateFail(err) {

FILE: miniprogram/cmpts/public/poster/wxa-plugin-canvas/poster/poster.js
  function Poster (line 5) | function Poster(options = {}, that) {

FILE: miniprogram/comm/behavior/news_index_bh.js
  method _setCate (line 58) | _setCate(cateList, options, cateId = 0) {

FILE: miniprogram/comm/biz/admin_biz.js
  class AdminBiz (line 14) | class AdminBiz extends BaseBiz {
    method setContentDesc (line 17) | static setContentDesc(that) {
    method adminLogin (line 35) | static async adminLogin(that, name, pwd) {
    method clearAdminToken (line 79) | static clearAdminToken() {
    method getAdminToken (line 86) | static getAdminToken() {
    method getAdminName (line 93) | static getAdminName() {
    method isSuperAdmin (line 102) | static isSuperAdmin() {
    method isAdmin (line 109) | static isAdmin(that, isSuper = false) {

FILE: miniprogram/comm/biz/base_biz.js
  class BaseBiz (line 9) | class BaseBiz {
    method getCateName (line 11) | static getCateName(cateId, cateList) {
    method getCateList (line 20) | static getCateList(cateList) {
    method setCateTitle (line 35) | static setCateTitle(cateList) {

FILE: miniprogram/comm/biz/fav_biz.js
  class FavBiz (line 11) | class FavBiz extends BaseBiz {
    method isFav (line 13) | static async isFav(that, oid) {
    method updateFav (line 31) | static async updateFav(that, oid, isFav, type, title) {

FILE: miniprogram/comm/biz/foot_biz.js
  constant CACHE_FOOT (line 11) | const CACHE_FOOT = 'CACHE_FOOT';
  class FootBiz (line 13) | class FootBiz extends BaseBiz {
    method getFootList (line 15) | static getFootList() {
    method addFoot (line 38) | static addFoot(type, title, size = 60, expire = 86400 * 365 * 3) {

FILE: miniprogram/comm/biz/passport_biz.js
  class PassportBiz (line 14) | class PassportBiz extends BaseBiz {
    method loginSilence (line 17) | static async loginSilence(that) {
    method loginSilenceMust (line 22) | static async loginSilenceMust(that) {
    method loginMustCancelWin (line 27) | static async loginMustCancelWin(that) {
    method loginMustBackWin (line 32) | static async loginMustBackWin(that) {
    method getToken (line 37) | static getToken() {
    method setToken (line 43) | static setToken(token) {
    method getUserId (line 49) | static getUserId() {
    method getUserName (line 56) | static getUserName() {
    method getStatus (line 62) | static getStatus() {
    method isLogin (line 69) | static isLogin() {
    method loginStatusHandler (line 74) | static loginStatusHandler(method, status) {
    method loginCheck (line 102) | static async loginCheck(mustLogin = false, method = 'back', title = ''...
    method clearToken (line 209) | static clearToken() {
    method getPhone (line 214) | static async getPhone(e, that) {

FILE: miniprogram/comm/biz/public_biz.js
  class PublicBiz (line 12) | class PublicBiz extends BaseBiz {
    method initPageBase (line 18) | static initPageBase(that, { skin, isSetNavColor = true }) {
    method getRichEditorDesc (line 42) | static getRichEditorDesc(desc, content) {
    method isCacheList (line 52) | static isCacheList(key) {
    method removeCacheList (line 60) | static removeCacheList(key) {
    method setCacheList (line 66) | static setCacheList(key, time = setting.CACHE_LIST_TIME) {

FILE: miniprogram/comm/biz/search_biz.js
  class SearchBiz (line 13) | class SearchBiz extends BaseBiz {
    method clearHistory (line 15) | static clearHistory(key){
    method getHistory (line 19) | static getHistory(key)
    method addHistory (line 32) | static addHistory(key, val, size = 20, expire = 86400 * 30)  {

FILE: miniprogram/helper/cache_helper.js
  constant TIME_SUFFIX (line 8) | const TIME_SUFFIX = "_deadtime"
  function set (line 16) | function set(k, v, t = 86400 * 30) {
  function get (line 36) | function get(k, def = null) {
  function remove (line 65) | function remove(k) {
  function clear (line 75) | function clear() {

FILE: miniprogram/helper/cloud_helper.js
  constant CODE (line 16) | const CODE = {
  function callCloudSumbitAsync (line 26) | function callCloudSumbitAsync(route, params = {}, options) {
  function callCloudSumbit (line 34) | async function callCloudSumbit(route, params = {}, options = { title: '提...
  function callCloudData (line 42) | async function callCloudData(route, params = {}, options) {
  function callCloud (line 64) | function callCloud(route, params = {}, options) {
  function dataList (line 193) | async function dataList(that, listName, route, params, options, isRevers...
  function getTempFileURLOne (line 270) | async function getTempFileURLOne(fileID) {
  function transTempPics (line 281) | async function transTempPics(imgList, dir, id, prefix = '') {
  function transRichEditorTempPics (line 314) | async function transRichEditorTempPics(content, dir, id, route) {
  function transCoverTempPics (line 351) | async function transCoverTempPics(imgList, dir, id, route) {
  function transFormsTempPics (line 369) | async function transFormsTempPics(forms, dir, id, route) {
  function transTempPicOne (line 407) | async function transTempPicOne(img, dir, id, isCheck = true) {

FILE: miniprogram/helper/content_check_helper.js
  function imgTypeCheck (line 16) | function imgTypeCheck(path, type = ['jpg', 'jpeg', 'png','JPG','JPEG','P...
  function imgSizeCheck (line 29) | function imgSizeCheck(size, maxSize) {
  function imgCheckCloud (line 33) | async function imgCheckCloud(path, opt) {
  function imgCheck (line 75) | async function imgCheck(imgData) {

FILE: miniprogram/helper/data_helper.js
  function fmtTag (line 36) | function fmtTag(tag) {
  function spArr (line 51) | function spArr(arr, size) {
  function str2Arr (line 67) | function str2Arr(str, sp = ',') {
  function isNumber (line 88) | function isNumber(val) {
  function getArrByKey (line 103) | function getArrByKey(arr, key) {
  function getArrByKeyMulti (line 118) | function getArrByKeyMulti(arr, keys = []) {
  function getDataByKey (line 141) | function getDataByKey(arr, key, val) {
  function fmtText (line 157) | function fmtText(content, len = -1) {
  function toHump (line 168) | function toHump(name) {
  function toLine (line 179) | function toLine(name) {
  function fmtMoney (line 190) | function fmtMoney(s, dot = ',', prefix = '¥') {
  function arr2ObjectArr (line 209) | function arr2ObjectArr(arr, key1, key2, key3) {
  function objArrSortAsc (line 227) | function objArrSortAsc(property) {
  function objArrSortDesc (line 245) | function objArrSortDesc(property) {
  function arrAddDel (line 263) | function arrAddDel(arr, data, sort = 'asc') {
  function deepClone (line 280) | function deepClone(data) {
  function padLeft (line 288) | function padLeft(str, len, charStr) {
  function padRight (line 296) | function padRight(str, len, charStr) {
  function getSelectOptions (line 306) | function getSelectOptions(str) {
  function arraySwap (line 329) | function arraySwap(arr, index1, index2) {
  function arrayTop (line 335) | function arrayTop(arr, idx) {
  function arrayBottom (line 342) | function arrayBottom(arr, idx) {
  function insertObjArrByKey (line 355) | function insertObjArrByKey(arr, key, val, obj) {
  function getValFromArr (line 381) | function getValFromArr(arr, key = 'val', val = '') {

FILE: miniprogram/helper/file_helper.js
  function openDoc (line 9) | function openDoc(name, url, ext = '.xlsx') {

FILE: miniprogram/helper/form_helper.js
  function model2Form (line 12) | function model2Form(model) {
  function setOptions (line 29) | function setOptions(that, options, name, val) {

FILE: miniprogram/helper/helper.js
  function isDefined (line 11) | function isDefined(val) {
  function isObjectNull (line 23) | function isObjectNull(obj) {
  function sleep (line 28) | function sleep(time) {
  function formatNumber (line 33) | function formatNumber(n) {
  function getOptionsIdx (line 47) | function getOptionsIdx(options, val) {

FILE: miniprogram/helper/mini_helper.js
  function getAuth (line 8) | function getAuth(auth, authName, callback) {

FILE: miniprogram/helper/page_helper.js
  function addPhoneCalendar (line 13) | function addPhoneCalendar(title, startTime, endTime, alarmOffset = 3600) {
  function getCustomNavHeight (line 37) | function getCustomNavHeight() {
  function getCurrentPageURL (line 44) | function getCurrentPageURL() {
  function getCurrentPageUrlWithArgs (line 51) | function getCurrentPageUrlWithArgs() {
  function getPID (line 67) | function getPID() {
  function fmtURLByPID (line 75) | function fmtURLByPID(url, PID = '') {
  function clearTimer (line 86) | function clearTimer(that, timerName = 'timer') {
  function getPrevPage (line 96) | function getPrevPage(deep = 2) {
  function modifyListNode (line 110) | function modifyListNode(id, list, valName, val, idName = '_id') {
  function modifyPrevPageListNode (line 130) | function modifyPrevPageListNode(id, valName, val, deep = 2, listName = '...
  function modifyPrevPageListNodeObject (line 154) | function modifyPrevPageListNodeObject(id, vals, deep = 2, listName = 'da...
  function delListNode (line 178) | function delListNode(id, list, idName = '_id') {
  function delPrevPageListNode (line 196) | function delPrevPageListNode(id, deep = 2, listName = 'dataList', idName...
  function refreshPrevListNode (line 218) | async function refreshPrevListNode(deep = 2, listName = 'dataList', list...
  function scrollTop (line 228) | function scrollTop(e, that) {
  function delImage (line 247) | function delImage(that, idx, imgListName = 'imgList') {
  function previewImage (line 263) | function previewImage(that, url, imgListName = 'imgList') {
  function dataset (line 277) | function dataset(e, name, child = false) {
  function model (line 285) | function model(that, e) {
  function switchModel (line 293) | function switchModel(that, e, mode = 'int') {
  function showNoneToast (line 307) | function showNoneToast(title = '操作完成', duration = 1500, callback) {
  function showNoneToastReturn (line 322) | function showNoneToastReturn(title = '操作完成', duration = 2000) {
  function showErrToast (line 330) | function showErrToast(title = '操作失败', duration = 1500, callback) {
  function showLoadingToast (line 345) | function showLoadingToast(title = '加载中', duration = 1500, callback) {
  function showSuccToast (line 360) | function showSuccToast(title = '操作成功', duration = 1500, callback) {
  function showSuccToastReturn (line 375) | function showSuccToastReturn(title = '操作成功', duration = 1500) {
  function formClearFocus (line 383) | function formClearFocus(that) {
  function formHint (line 396) | function formHint(that, formName, hint) {
  function showConfirm (line 404) | function showConfirm(title = '确定要删除吗?', yes, no) {
  function showModal (line 420) | function showModal(content, title = '温馨提示', callback = null, confirmText...
  function setPageData (line 437) | function setPageData(that, data) {
  function commListListener (line 448) | function commListListener(that, e) {
  function bindShowModalTap (line 466) | function bindShowModalTap(e) {
  function bindHideModalTap (line 472) | function bindHideModalTap(e) {
  function showTopBtn (line 483) | function showTopBtn(e, that) {
  function top (line 498) | function top() {
  function anchor (line 505) | function anchor(id, that) {
  function url (line 529) | function url(e, that) {
  function getOptions (line 667) | function getOptions(that, options, idName = 'id') {
  function hint (line 682) | function hint(msg, type = 'redirect') {
  function toURL (line 695) | function toURL(url) {
  function listTouchStart (line 713) | function listTouchStart(e, that) {
  function listTouchMove (line 720) | function listTouchMove(e, that, precision = 50) {
  function listTouchEnd (line 734) | function listTouchEnd(e, that) {
  function queryMulti (line 759) | function queryMulti(that, e, key, val, def) {
  function cacheListExist (line 786) | function cacheListExist(key, that, listKey = 'list') {
  function cacheListRemove (line 794) | function cacheListRemove(key) {
  function cacheListSet (line 800) | function cacheListSet(key, time = setting.CACHE_LIST_TIME) {

FILE: miniprogram/helper/pic_helper.js
  function getWritePhotosAlbum (line 8) | function getWritePhotosAlbum(callback) {

FILE: miniprogram/helper/time_helper.js
  function simpleDate (line 11) | function simpleDate(date) {
  function fmtDateCHN (line 26) | function fmtDateCHN(date, fmt = 'Y-M-D') {
  function timestamp2Time (line 63) | function timestamp2Time(unixtime, format = 'Y-M-D h:m:s', diff = 0) {
  function timestame2Ago (line 80) | function timestame2Ago(dateTimeStamp, fmt = 'Y-M-D', diff = 0) { //dateT...
  function formatNumber (line 120) | function formatNumber(n) {
  function time2Timestamp (line 130) | function time2Timestamp(date) {
  function time (line 147) | function time(fmt, step = 0) {
  function getDayFirstTimestamp (line 157) | function getDayFirstTimestamp(timestamp) {
  function getAge (line 166) | function getAge(birth, isMonth = false) {
  function week (line 216) | function week(day) {
  function getMonthFirstTimestamp (line 225) | function getMonthFirstTimestamp(timestamp) {
  function getMonthLastTimestamp (line 233) | function getMonthLastTimestamp(timestamp) {
  function getNowMinTimestamp (line 241) | function getNowMinTimestamp() {
  function getFirstOfWeek (line 252) | function getFirstOfWeek(date) {
  function getLastOfWeek (line 263) | function getLastOfWeek(date) {
  function getFirstOfMonth (line 274) | function getFirstOfMonth(date) {
  function getLastOfMonth (line 280) | function getLastOfMonth(date) {
  function getTimeLeft (line 293) | function getTimeLeft(datetimeTo, flag = 1) {

FILE: miniprogram/helper/validate.js
  constant CHECK_OPEN (line 9) | const CHECK_OPEN = true;
  constant CHECK_SOURCE (line 10) | const CHECK_SOURCE = 'client';
  function isDefined (line 16) | function isDefined(val) {
  function isNull (line 24) | function isNull(value) {
  function isStrAndArrNull (line 30) | function isStrAndArrNull(value) {
  function isRealNull (line 40) | function isRealNull(value) {
  function getDataType (line 51) | function getDataType(value) {
  function checkRequired (line 57) | function checkRequired(value, desc = '') {
  function checkMin (line 78) | function checkMin(value, min, desc = '') {
  function checkMax (line 99) | function checkMax(value, max, desc = '') {
  function checkLen (line 120) | function checkLen(value, len, desc = '') {
  function checkMobile (line 136) | function checkMobile(value, desc = '') {
  function checkInt (line 143) | function checkInt(value, desc = '') {
  function checkDigit (line 150) | function checkDigit(value, desc = '') {
  function checkLetter (line 157) | function checkLetter(value, desc = '') {
  function checkMoney (line 164) | function checkMoney(value, desc = '') {
  function checkLetterNum (line 172) | function checkLetterNum(value, desc = '') {
  function checkId (line 179) | function checkId(value, desc = '', min = 1, max = 100) {
  function checkEmail (line 193) | function checkEmail(value, desc = '') {
  function checkDate (line 201) | function checkDate(value, desc = '') {
  function checkYear (line 214) | function checkYear(value, desc = '') {
  function checkYearMonth (line 224) | function checkYearMonth(value, desc = '') {
  function checkTime (line 235) | function checkTime(value, desc = '') {
  function checkHourMinute (line 247) | function checkHourMinute(value, desc = '') {
  function checkDatimeTime (line 258) | function checkDatimeTime(value, desc = '') {
  function checkArray (line 272) | function checkArray(value, desc = '') {
  function checkObject (line 277) | function checkObject(value, desc = '') {
  function checkBoolean (line 282) | function checkBoolean(value, desc = '') {
  function checkIn (line 288) | function checkIn(value, ref, desc = '') {
  function checkIds (line 299) | function checkIds(value, desc) {}
  function checkString (line 301) | function checkString(value, desc) {
  function check (line 307) | function check(data, rules, that) {
  function _showError (line 570) | function _showError(result, formName, that) { //admin/client

FILE: miniprogram/lib/tools/base64_lib.js
  function Base64 (line 7) | function Base64() {
  function encode (line 114) | function encode(str) {
  function decode (line 118) | function decode(str) {
  function safeEncode (line 122) | function safeEncode(str) {

FILE: miniprogram/lib/tools/lunar_lib.js
  constant LUNAR_HOLIDAY (line 11) | const LUNAR_HOLIDAY = {
  constant PUBLIC_HOLIDAY (line 24) | const PUBLIC_HOLIDAY = {
  constant SOLAR_STERM (line 53) | const SOLAR_STERM = ['小寒', '大寒', '立春', '雨水', '惊蛰', '春分', '清明', '谷雨', '立夏...
  constant SOLAR_STERM_INFO (line 56) | const SOLAR_STERM_INFO = [0, 1272480000, 2548020000, 3830160000, 5120220...
  constant LUNAR_YEAR_ARR (line 63) | const LUNAR_YEAR_ARR = [
  constant LUNAR_MONTH (line 82) | const LUNAR_MONTH = ['正', '二', '三', '四', '五', '六', '七', '八', '九', '十', '...
  constant LUNAR_DAY (line 83) | const LUNAR_DAY = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '初'...
  constant TIAN_GAN (line 84) | const TIAN_GAN = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸'];
  constant DIZHI (line 85) | const DIZHI = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥'];
  function sloarToLunar (line 89) | function sloarToLunar(sy, sm, sd) {
  function hasLeapMonth (line 204) | function hasLeapMonth(ly) {
  function leapMonthDays (line 215) | function leapMonthDays(ly) {
  function lunarYearDays (line 226) | function lunarYearDays(ly) {
  function lunarYearMonths (line 245) | function lunarYearMonths(ly) {
  function getTianGan (line 262) | function getTianGan(ly) {
  function getDiZhi (line 269) | function getDiZhi(ly) {
  function getSolarTerm (line 281) | function getSolarTerm(sy, sm, sd) {

FILE: miniprogram/lib/tools/qrcode_lib.js
  function qrPolynomial (line 897) | function qrPolynomial(num, shift) {

FILE: miniprogram/pages/test1/test1.js
  method onLoad (line 14) | onLoad(options) {
  method onReady (line 21) | onReady() {
  method onShow (line 28) | onShow() {
  method onHide (line 35) | onHide() {
  method onUnload (line 42) | onUnload() {
  method onPullDownRefresh (line 49) | onPullDownRefresh() {
  method onReachBottom (line 56) | onReachBottom() {
  method onShareAppMessage (line 63) | onShareAppMessage() {

FILE: miniprogram/projects/TRIP1/biz/admin_album_biz.js
  class AdminAlbumBiz (line 11) | class AdminAlbumBiz extends BaseBiz {
    method initFormData (line 13) | static initFormData(id = '') {

FILE: miniprogram/projects/TRIP1/biz/admin_meet_biz.js
  constant TIME_NODE (line 14) | const TIME_NODE = {
  class AdminMeetBiz (line 29) | class AdminMeetBiz extends BaseBiz {
    method getTypeList (line 32) | static getTypeList() {
    method getTypeName (line 46) | static getTypeName(typeId) {
    method getLeaveDay (line 56) | static getLeaveDay(days) {
    method getNewTimeNode (line 65) | static getNewTimeNode(day) {
    method getDaysTimeOptions (line 72) | static getDaysTimeOptions() {
    method getEndBeforeSetOptions (line 102) | static getEndBeforeSetOptions() {
    method getEndYesterdaySetOptions (line 125) | static getEndYesterdaySetOptions() {
    method getEndTodaySetOptions (line 139) | static getEndTodaySetOptions() {
    method getEndAfterSetOptions (line 153) | static getEndAfterSetOptions() {
    method getBeginDaySetOptions (line 171) | static getBeginDaySetOptions() {
    method getCancelSetOptions (line 205) | static getCancelSetOptions() {
    method getLimitSetOptions (line 254) | static getLimitSetOptions() {
    method getLimitSetDesc (line 287) | static getLimitSetDesc(rule) {
    method getEndSetDesc (line 310) | static getEndSetDesc(rule) {
    method getCancelSetDesc (line 342) | static getCancelSetDesc(rule) {
    method getBeginSetDesc (line 375) | static getBeginSetDesc(rule) {
    method initFormData (line 395) | static async initFormData() {
    method updateMeetStyleSet (line 428) | static async updateMeetStyleSet(that, meetId, styleSet) {
    method updateMeetCotnentPic (line 461) | static async updateMeetCotnentPic(that, meetId, content) {

FILE: miniprogram/projects/TRIP1/biz/admin_news_biz.js
  class AdminNewsBiz (line 11) | class AdminNewsBiz extends BaseBiz {
    method initFormData (line 15) | static initFormData(id = '') {
    method getCateName (line 43) | static getCateName(cateId) {

FILE: miniprogram/projects/TRIP1/biz/admin_product_biz.js
  class AdminProductBiz (line 11) | class AdminProductBiz extends BaseBiz {
    method initFormData (line 13) | static initFormData(id = '') {

FILE: miniprogram/projects/TRIP1/biz/album_biz.js
  class AlbumBiz (line 10) | class AlbumBiz extends BaseBiz {
    method getCateName (line 13) | static getCateName(cateId) {
    method getCateList (line 17) | static getCateList() {
    method setCateTitle (line 21) | static setCateTitle() {
    method getSearchMenu (line 27) | static async getSearchMenu() {

FILE: miniprogram/projects/TRIP1/biz/meet_biz.js
  class MeetBiz (line 12) | class MeetBiz extends BaseBiz {
    method subscribeMessageMeet (line 14) | static async subscribeMessageMeet(callback) {
    method setTypeTitle (line 18) | static setTypeTitle(that, typeId = null) {

FILE: miniprogram/projects/TRIP1/biz/news_biz.js
  class NewsBiz (line 11) | class NewsBiz extends BaseBiz {
    method getCateList (line 14) | static getCateList() {
    method setCateTitle (line 30) | static setCateTitle(cateId = null, that) {
    method getSearchMenu (line 63) | static async getSearchMenu() {

FILE: miniprogram/projects/TRIP1/biz/product_biz.js
  class ProductBiz (line 10) | class ProductBiz extends BaseBiz {
    method getCateName (line 12) | static getCateName(cateId) {
    method getCateList (line 16) | static getCateList() {
    method setCateTitle (line 20) | static setCateTitle() {
    method getSearchMenu (line 26) | static async getSearchMenu() {

FILE: miniprogram/projects/TRIP1/biz/project_biz.js
  class ProjectBiz (line 12) | class ProjectBiz extends BaseBiz {
    method initPage (line 18) | static initPage(that, { isSetNavColor = true } = {}) {

FILE: miniprogram/projects/TRIP1/pages/about/service/about_service.js
  method onLoad (line 16) | onLoad(options) {
  method onReady (line 23) | onReady() {
  method onShow (line 30) | onShow() {
  method onHide (line 37) | onHide() {
  method onUnload (line 44) | onUnload() {
  method onPullDownRefresh (line 51) | onPullDownRefresh() {
  method onReachBottom (line 58) | onReachBottom() {
  method onShareAppMessage (line 65) | onShareAppMessage() {

FILE: miniprogram/projects/TRIP1/pages/admin/meet/edit/admin_meet_edit.js
  method formSetBarTitleByAddEdit (line 75) | formSetBarTitleByAddEdit(id, title) {

FILE: miniprogram/projects/TRIP1/pages/admin/meet/join/admin_meet_join.js
  constant CACHE_CANCEL_REASON (line 7) | const CACHE_CANCEL_REASON = 'JOIN_CANCEL_REASON';
  constant CACHE_REFUSE_REASON (line 8) | const CACHE_REFUSE_REASON = 'JOIN_REFUSE_REASON';
  method success (line 164) | success(res) {

FILE: miniprogram/projects/TRIP1/pages/admin/meet/scan/admin_meet_scan.js
  method success (line 63) | async success(res) {
  method fail (line 88) | fail(err) {

FILE: miniprogram/projects/TRIP1/pages/admin/setup/about_list/admin_setup_about_list.js
  method onLoad (line 17) | onLoad(options) {
  method onReady (line 28) | onReady() {
  method onShow (line 35) | onShow() {
  method onHide (line 42) | onHide() {
  method onUnload (line 49) | onUnload() {
  method onPullDownRefresh (line 56) | onPullDownRefresh() {
  method onReachBottom (line 63) | onReachBottom() {

FILE: miniprogram/projects/TRIP1/pages/admin/user/detail/admin_user_detail.js
  method onLoad (line 17) | async onLoad(options) {
  method onReady (line 27) | onReady() {
  method onShow (line 34) | onShow() {
  method onHide (line 41) | onHide() {
  method onUnload (line 48) | onUnload() {
  method onPullDownRefresh (line 55) | async onPullDownRefresh() {
  method onReachBottom (line 63) | onReachBottom() {
  method onShareAppMessage (line 70) | onShareAppMessage() {
  method url (line 99) | url(e) {

FILE: miniprogram/projects/TRIP1/pages/admin/user/list/admin_user_list.js
  constant CACHE_USER_CHECK_REASON (line 7) | const CACHE_USER_CHECK_REASON = 'CACHE_USER_CHECK_REASON';

FILE: miniprogram/projects/TRIP1/pages/meet/join/meet_join.js
  method success (line 132) | success() {
Condensed preview — 509 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,592K chars).
[
  {
    "path": ".gitignore",
    "chars": 145,
    "preview": "# 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"
  },
  {
    "path": "README.md",
    "chars": 3035,
    "preview": "## 功能 介绍 \n\n 旅游景区门户小程序是一个为游客朋友提供多元化服务的一站式数字文旅平台,提供“吃、住、游、购、娱”等旅游行程中的多种服务,全面支持景区介绍,景点攻略,景点预约,停车预约、景区导览等功能,游客可以在小程序中了解旅游度假区"
  },
  {
    "path": "cloudfunctions/mcloud/config/config.js",
    "chars": 597,
    "preview": "module.exports = {\n\n\t//### 环境相关 \n\tCLOUD_ID: 'init-5go8b8pdc98ea814', //你的云环境id   \n\n\t// #################################"
  },
  {
    "path": "cloudfunctions/mcloud/config.json",
    "chars": 140,
    "preview": "{\n\t\"permissions\": {\n\t\t\"openapi\": [\"wxacode.getUnlimited\", \"security.imgSecCheck\", \"security.msgSecCheck\",\"serviceMarket."
  },
  {
    "path": "cloudfunctions/mcloud/framework/cloud/cloud_base.js",
    "chars": 358,
    "preview": "/**\n * Notes: 云初始化实例\n * Ver : CCMiniCloud Framework 2.2.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-09-0"
  },
  {
    "path": "cloudfunctions/mcloud/framework/cloud/cloud_util.js",
    "chars": 3778,
    "preview": "/**\n * Notes: 云基本操作模块\n * Ver : CCMiniCloud Framework 2.3.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-09-"
  },
  {
    "path": "cloudfunctions/mcloud/framework/core/app_code.js",
    "chars": 316,
    "preview": "/**\n * Notes: 错误代码定义\n * Ver : CCMiniCloud Framework 2.4.1 ALL RIGHTS RESERVED BY Cclinux0730 (wechat)\n * Date: 2020-09-0"
  },
  {
    "path": "cloudfunctions/mcloud/framework/core/app_error.js",
    "chars": 375,
    "preview": "/**\n * Notes: 应用异常处理类\n * Ver : CCMiniCloud Framework 2.5.1 ALL RIGHTS RESERVED BY cClinux0730 (wechat)\n * Date: 2020-09-"
  },
  {
    "path": "cloudfunctions/mcloud/framework/core/app_other.js",
    "chars": 513,
    "preview": "/**\n * Notes: 云函数非标业务处理\n * Ver : CCMiniCloud Framework 2.6.1 ALL RIGHTS RESERVED BY ccLinux@qq.com\n * Date: 2021-10-21 0"
  },
  {
    "path": "cloudfunctions/mcloud/framework/core/app_util.js",
    "chars": 989,
    "preview": "/**\n * Notes: 云函数业务主逻辑函数\n * Ver : CCMiniCloud Framework 2.7.1 ALL RIGHTS RESERVED BY cclinuX0730 (wechat)\n * Date: 2021-"
  },
  {
    "path": "cloudfunctions/mcloud/framework/core/application.js",
    "chars": 4397,
    "preview": "/**\n * Notes: 云函数业务主逻辑\n * Ver : CCMiniCloud Framework 2.8.1 ALL RIGHTS RESERVED BY cclinUX0730 (wechat)\n * Date: 2020-09"
  },
  {
    "path": "cloudfunctions/mcloud/framework/database/db_util.js",
    "chars": 17313,
    "preview": "/**\n * Notes: 数据库基本操作\n * Ver : CCMiniCloud Framework 2.9.1 ALL RIGHTS RESERVED BY CClinux0730 (wechat)\n * Date: 2020-09-"
  },
  {
    "path": "cloudfunctions/mcloud/framework/database/model.js",
    "chars": 11979,
    "preview": "/**\n * Notes: 数据持久化与操作模块\n * Ver : CCMiniCloud Framework 2.11.1 ALL RIGHTS RESERVED BY ccLinux0730 (wechat)\n * Date: 2020"
  },
  {
    "path": "cloudfunctions/mcloud/framework/database/multi_model.js",
    "chars": 5707,
    "preview": "/**\n * Notes: 实体基类 \n * Date: 2021-03-15 19:20:00 \n * Ver : CCMiniCloud Framework 2.12.1 ALL RIGHTS RESERVED BY cclinux07"
  },
  {
    "path": "cloudfunctions/mcloud/framework/lib/faker_lib.js",
    "chars": 24001,
    "preview": "/**\n * Notes: 测试数据构造类\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-05-"
  },
  {
    "path": "cloudfunctions/mcloud/framework/lib/md5_lib.js",
    "chars": 6652,
    "preview": "/**\n * Notes: MD5类库\n * Ver : CCMiniCloud Framework 2.15.1 ALL RIGHTS RESERVED BY cClinux0730 (wechat)\n * Date: 2021-03-0"
  },
  {
    "path": "cloudfunctions/mcloud/framework/lib/mini_lib.js",
    "chars": 1023,
    "preview": "/**\n * Notes: 小程序封装类库\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cClinux0730 (wechat)\n * Date: 2020-09-"
  },
  {
    "path": "cloudfunctions/mcloud/framework/platform/controller/base_admin_controller.js",
    "chars": 1492,
    "preview": "/**\n * Notes: 后台管理控制器模块\n * Ver : CCMiniCloud Framework 2.0.3 ALL RIGHTS RESERVED BY cclinuX0730 (wechat)\n * Date: 2022-0"
  },
  {
    "path": "cloudfunctions/mcloud/framework/platform/controller/base_controller.js",
    "chars": 1469,
    "preview": "/**\n * Notes: 基础控制器\n * Ver : CCMiniCloud Framework 2.0.4 ALL RIGHTS RESERVED BY cclinUx0730 (wechat)\n * Date: 2020-09-05"
  },
  {
    "path": "cloudfunctions/mcloud/framework/platform/model/admin_model.js",
    "chars": 1039,
    "preview": "/**\n * Notes: 系统管理员实体 \n * Date: 2021-03-15 19:20:00 \n * Ver : CCMiniCloud Framework 2.0.5 ALL RIGHTS RESERVED BY CCLINUX"
  },
  {
    "path": "cloudfunctions/mcloud/framework/platform/model/base_model.js",
    "chars": 280,
    "preview": "/**\n * Notes: 实体基类 \n * Date: 2021-03-15 19:20:00 \n * Ver : CCMiniCloud Framework 2.0.6 ALL RIGHTS RESERVED BY cclinux073"
  },
  {
    "path": "cloudfunctions/mcloud/framework/platform/model/log_model.js",
    "chars": 842,
    "preview": "/**\n * Notes: 后台操作日志实体\n * Ver : CCMiniCloud Framework 2.0.7 ALL RIGHTS RESERVED BY cclinuX0730 (wechat)\n * Date: 2020-10"
  },
  {
    "path": "cloudfunctions/mcloud/framework/platform/service/base_admin_service.js",
    "chars": 1942,
    "preview": "/**\n * Notes: 后台管理模块业务基类\n * Date: 2021-03-15 07:48:00 \n * Ver : CCMiniCloud Framework 2.0.8 ALL RIGHTS RESERVED BY cclin"
  },
  {
    "path": "cloudfunctions/mcloud/framework/platform/service/base_service.js",
    "chars": 1161,
    "preview": "/**\n * Notes: 基础业务逻辑\n * Ver : CCMiniCloud Framework 2.0.9 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-04-2"
  },
  {
    "path": "cloudfunctions/mcloud/framework/utils/constant.js",
    "chars": 160,
    "preview": " /**\n * Notes: 通用常量定义\n * Ver : CCMiniCloud Framework 2.32.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-09"
  },
  {
    "path": "cloudfunctions/mcloud/framework/utils/data_util.js",
    "chars": 9909,
    "preview": "/**\n * Notes: 字符相关操作函数\n* Ver : CCMiniCloud Framework 2.33.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-09"
  },
  {
    "path": "cloudfunctions/mcloud/framework/utils/export_util.js",
    "chars": 2829,
    "preview": "/**\n * Notes: 导出相关函数\n * Ver : CCMiniCloud Framework 2.0.14 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-05-"
  },
  {
    "path": "cloudfunctions/mcloud/framework/utils/log_util.js",
    "chars": 2322,
    "preview": " /**\n  * Notes: 日志操作函数\n  * Ver : CCMiniCloud Framework 2.34.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n  * Date: 2021"
  },
  {
    "path": "cloudfunctions/mcloud/framework/utils/math_util.js",
    "chars": 719,
    "preview": " /**\n  * Notes: 数学计算相关操作函数\n  * Ver : CCMiniCloud Framework 2.35.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n  * Date: "
  },
  {
    "path": "cloudfunctions/mcloud/framework/utils/setup/setup_model.js",
    "chars": 824,
    "preview": "/**\n * Notes: 系统设置实体\n * Ver : CCMiniCloud Framework 2.0.15 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-11-"
  },
  {
    "path": "cloudfunctions/mcloud/framework/utils/setup/setup_util.js",
    "chars": 1317,
    "preview": "/**\n * Notes: 系统设置相关函数\n * Ver : CCMiniCloud Framework 2.31.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-0"
  },
  {
    "path": "cloudfunctions/mcloud/framework/utils/time_util.js",
    "chars": 8849,
    "preview": "/**\n * Notes: 时间相关函数\n * Ver : CCMiniCloud Framework 2.36.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-09-"
  },
  {
    "path": "cloudfunctions/mcloud/framework/utils/util.js",
    "chars": 729,
    "preview": "/**\n * Notes: 通用工具函数\n * Ver : CCMiniCloud Framework 2.38.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-09-"
  },
  {
    "path": "cloudfunctions/mcloud/framework/validate/content_check.js",
    "chars": 2731,
    "preview": "/**\n * Notes: 内容审核\n * Ver : CCMiniCloud Framework 2.39.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-09-05"
  },
  {
    "path": "cloudfunctions/mcloud/framework/validate/data_check.js",
    "chars": 13709,
    "preview": "/**\n  * Notes: 数据校验类库\n * Ver : CCMiniCloud Framework 2.21.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n  * Date: 2021-0"
  },
  {
    "path": "cloudfunctions/mcloud/index.js",
    "chars": 167,
    "preview": "const application = require('./framework/core/application.js');\n\n// 云函数入口函数\nexports.main = async (event, context) => {\n\t"
  },
  {
    "path": "cloudfunctions/mcloud/package.json",
    "chars": 377,
    "preview": "{\n    \"name\": \"cloud\",\n    \"version\": \"1.0.0\",\n    \"description\": \"\",\n    \"main\": \"index.js\",\n    \"scripts\": {\n        \""
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_album_controller.js",
    "chars": 4338,
    "preview": "/**\n * Notes: 相册模块后台管理-控制器\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 202"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_home_controller.js",
    "chars": 859,
    "preview": "/**\n * Notes: 后台登录与首页模块\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-0"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_meet_controller.js",
    "chars": 10620,
    "preview": "/**\n * Notes: 预约模块后台管理-控制器\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 202"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_mgr_controller.js",
    "chars": 4888,
    "preview": "/**\n * Notes: 管理员控制模块\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-07-"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_news_controller.js",
    "chars": 5225,
    "preview": "/**\n * Notes: 资讯模块后台管理-控制器\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 202"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_product_controller.js",
    "chars": 4487,
    "preview": "/**\n * Notes: 产品模块后台管理-控制器\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 202"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_setup_controller.js",
    "chars": 1490,
    "preview": "/**\n * Notes: 设置控制模块\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-07-1"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/admin/admin_user_controller.js",
    "chars": 3543,
    "preview": "/**\n * Notes: 用户控制模块\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-01-2"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/admin/base_project_admin_controller.js",
    "chars": 539,
    "preview": "/**\n * Notes: 后台管理控制模块\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-03"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/album_controller.js",
    "chars": 1499,
    "preview": "/**\n * Notes: 相册模块控制器\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-06-"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/base_project_controller.js",
    "chars": 507,
    "preview": "/**\n * Notes: 本业务基本控制器\n * Date: 2021-03-15 19:20:00 \n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/check_controller.js",
    "chars": 610,
    "preview": "/**\n * Notes: 内容检测控制器\n * Date: 2021-03-15 19:20:00 \n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/fav_controller.js",
    "chars": 1875,
    "preview": "/**\n * Notes: 预约模块控制器\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-12-"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/home_controller.js",
    "chars": 699,
    "preview": "/**\n * Notes: 全局或者主页模块控制器 \n * Date: 2020-11-05 10:20:00 \n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY ccl"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/meet_controller.js",
    "chars": 5713,
    "preview": "/**\n * Notes: 预约模块控制器\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-12-"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/my_controller.js",
    "chars": 298,
    "preview": "/**\n * Notes: 用户中心模块控制器\n * Date: 2021-03-15 19:20:00 \n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinu"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/news_controller.js",
    "chars": 1886,
    "preview": "/**\n * Notes: 资讯模块控制器\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-09-"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/passport_controller.js",
    "chars": 1839,
    "preview": "/**\n * Notes: passport模块控制器\n * Date: 2021-03-15 19:20:00 \n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cc"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/product_controller.js",
    "chars": 1647,
    "preview": "/**\n * Notes: 产品模块控制器\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-06-"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/controller/test/test_controller.js",
    "chars": 4188,
    "preview": "/**\n * Notes: 测试模块控制器\n * Date: 2021-03-15 19:20:00 \n */\n\nconst BaseController = require('../../controller/base_project_c"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/model/album_model.js",
    "chars": 1126,
    "preview": "/**\n * Notes:  相册实体\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-06-05"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/model/base_project_model.js",
    "chars": 301,
    "preview": "/**\n * Notes: 实体ORM基类 \n * Date: 2022-03-15 19:20:00 \n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/model/day_model.js",
    "chars": 948,
    "preview": "/**\n * Notes: 预约日期设置实体\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-01"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/model/fav_model.js",
    "chars": 733,
    "preview": "/**\n * Notes: 收藏实体\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-05-24 "
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/model/join_model.js",
    "chars": 1733,
    "preview": "/**\n * Notes: 报名实体\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-12-30 "
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/model/meet_model.js",
    "chars": 1416,
    "preview": "/**\n * Notes: 预约实体\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-12-07 "
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/model/news_model.js",
    "chars": 1153,
    "preview": "/**\n * Notes: 资讯实体\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-10-28 "
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/model/product_model.js",
    "chars": 1120,
    "preview": "/**\n * Notes:  套系实体\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-06-08"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/model/user_model.js",
    "chars": 1196,
    "preview": "/**\n * Notes: 用户实体\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-10-14 "
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/public/constants.js",
    "chars": 81,
    "preview": "module.exports = {    \n\t// 首页推荐\n\tSETUP_HOME_VOUCH_KEY : 'SETUP_HOME_VOUCH_KEY',\n}"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/public/project_config.js",
    "chars": 80,
    "preview": "module.exports = {\n\t// ## 缓存相关  \n\tCACHE_CALENDAR_TIME: 60 * 30, //日历缓存      \n \n}"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/public/route.js",
    "chars": 7021,
    "preview": "/**\n * Notes: 路由配置文件\n  * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * User: CC\n * Da"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/admin/admin_album_service.js",
    "chars": 3034,
    "preview": "/**\n * Notes: 相册后台管理\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-07-1"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/admin/admin_home_service.js",
    "chars": 2438,
    "preview": "/**\n * Notes: 后台HOME/登录模块 \n * Date: 2021-06-15 07:48:00 \n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY ccl"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/admin/admin_meet_service.js",
    "chars": 8038,
    "preview": "/**\n * Notes: 预约后台管理\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-12-0"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/admin/admin_mgr_service.js",
    "chars": 4509,
    "preview": "/**\n * Notes: 管理员管理\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-07-11"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/admin/admin_news_service.js",
    "chars": 3431,
    "preview": "/**\n * Notes: 资讯后台管理\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-07-1"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/admin/admin_product_service.js",
    "chars": 3109,
    "preview": "/**\n * Notes: 产品后台管理\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-06-0"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/admin/admin_setup_service.js",
    "chars": 2416,
    "preview": "/**\n * Notes: 设置管理\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-07-11 "
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/admin/admin_user_service.js",
    "chars": 2626,
    "preview": "/**\n * Notes: 用户管理\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-01-22 "
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/admin/base_project_admin_service.js",
    "chars": 1151,
    "preview": "/**\n * Notes: 后台管理模块 基类\n * Date: 2021-03-15 07:48:00 \n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinu"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/album_service.js",
    "chars": 1693,
    "preview": "/**\n * Notes: 相册模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-06"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/base_project_service.js",
    "chars": 4395,
    "preview": "/**\n * Notes: 业务基类 \n * Date: 2021-03-15 04:00:00 \n */\n\nconst dbUtil = require('../../../framework/database/db_util.js');"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/fav_service.js",
    "chars": 1929,
    "preview": "/**\n * Notes: 收藏模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-05"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/home_service.js",
    "chars": 1266,
    "preview": "/**\n * Notes: 全局/首页模块业务逻辑\n * Date: 2021-03-15 04:00:00 \n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY ccli"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/meet_service.js",
    "chars": 18689,
    "preview": "/**\n * Notes: 预约模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-12"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/news_service.js",
    "chars": 1526,
    "preview": "/**\n * Notes: 资讯模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-10"
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/passport_service.js",
    "chars": 2954,
    "preview": "/**\n * Notes: passport模块业务逻辑 \n * Date: 2020-10-14 07:48:00 \n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY "
  },
  {
    "path": "cloudfunctions/mcloud/project/TRIP1/service/product_service.js",
    "chars": 1753,
    "preview": "/**\n * Notes: 产品模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2022-06"
  },
  {
    "path": "miniprogram/app.js",
    "chars": 835,
    "preview": "const setting = require('./setting/setting.js');\n\nApp({\n\tonLaunch: function (options) {\n\n\t\tif (!wx.cloud) {\n\t\t\tconsole.e"
  },
  {
    "path": "miniprogram/app.json",
    "chars": 5037,
    "preview": "{\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"
  },
  {
    "path": "miniprogram/app.wxss",
    "chars": 70,
    "preview": "@import \"style/base/comm.wxss\";\n@import \"style/public/project.wxss\"; \n"
  },
  {
    "path": "miniprogram/cmpts/biz/detail/detail_cmpt.js",
    "chars": 2575,
    "preview": "const pageHelper = require('../../../helper/page_helper');\nconst posterCmptHelper = require('../../public/poster/poster_"
  },
  {
    "path": "miniprogram/cmpts/biz/detail/detail_cmpt.json",
    "chars": 100,
    "preview": "{\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",
    "chars": 3286,
    "preview": "<view style=\"height:200rpx\"></view>\n\n<view wx:if=\"{{doHome&&mode!='right'}}\" bindtap=\"bindHomeTap\" class=\"cmpt-fixed-hom"
  },
  {
    "path": "miniprogram/cmpts/biz/detail/detail_cmpt.wxss",
    "chars": 2803,
    "preview": ".cmpt-fixed-home-btn {\n\tposition: fixed;\n\tbottom: 180rpx;\n\tleft: 10rpx;\n\tfont-size: 45rpx;\n\theight: 80rpx;\n\twidth: 80rpx"
  },
  {
    "path": "miniprogram/cmpts/biz/foot/foot_cmpt.js",
    "chars": 892,
    "preview": "const pageHelper = require('../../../helper/page_helper');\nconst setting = require('../../../setting/setting.js');\n\nComp"
  },
  {
    "path": "miniprogram/cmpts/biz/foot/foot_cmpt.json",
    "chars": 46,
    "preview": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/biz/foot/foot_cmpt.wxml",
    "chars": 247,
    "preview": "<view class=\"site-footer\" bindtap=\"url\" data-type=\"mini\" data-app=\"wx1a3ad7903d85f33a\" data-url=\"/pages/home/index/home_"
  },
  {
    "path": "miniprogram/cmpts/biz/foot/foot_cmpt.wxss",
    "chars": 244,
    "preview": "@import \"../../../style/public/project.wxss\";\n\n.site-footer {\n\twidth: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tju"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/calendar_comm/calendar_comm_cmpt.js",
    "chars": 2609,
    "preview": "const timeHelper = require('../../../../helper/time_helper.js');\nconst pageHelper = require('../../../../helper/page_hel"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/calendar_comm/calendar_comm_cmpt.json",
    "chars": 46,
    "preview": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/calendar_comm/calendar_comm_cmpt.wxml",
    "chars": 3062,
    "preview": "<wxs src=\"../../../../tpls/wxs/tools.wxs\" module=\"tools\" />\n<wxs module=\"utils\">\n\t// 比较操作日期所在月是否当前显示的月\n\tfunction compare"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/calendar_comm/calendar_comm_cmpt.wxss",
    "chars": 3442,
    "preview": "@import \"./din.wxss\";\n\npage {\n\t/*#### 父组件日历颜色定义*/\n\t/* 整体颜色 */\n\t--calendarPageColor: #fff;\n\t/* 加重颜色*/\n\t--calendarMainColo"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/calendar_comm/din.wxss",
    "chars": 204510,
    "preview": "@font-face {\n    font-family: 'din';\n    src: url('data:font/ttf;charset=utf-8;base64,AAEAAAAPAIAAAwBwRkZUTYgLMMEAAlaAAA"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/calendar_lib.js",
    "chars": 9610,
    "preview": "/**\n * Notes: 日历组件通用方法\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux@qq.com\n * Date: 2021-01-01 07"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/calendar_meet/calendar_meet_cmpt.js",
    "chars": 2821,
    "preview": "const timeHelper = require('../../../../helper/time_helper.js');\nconst pageHelper = require('../../../../helper/page_hel"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/calendar_meet/calendar_meet_cmpt.json",
    "chars": 46,
    "preview": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/calendar_meet/calendar_meet_cmpt.wxml",
    "chars": 2365,
    "preview": "<wxs src=\"../../../../tpls/wxs/tools.wxs\" module=\"tools\" />\n<wxs module=\"utils\">\n\t// 比较操作日期所在月是否当前显示的月\n\tfunction compare"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/calendar_meet/calendar_meet_cmpt.wxss",
    "chars": 3932,
    "preview": "page {\n\n\t/*#### 父组件日历颜色定义*/\n\t/* 整体颜色 */\n\t--calendarPageColor: #F0F4FF;\n\t/* 加重颜色*/\n\t--calendarMainColor: #1F6ED4;\n\t/* 加重的"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/date_select/date_select_cmpt.js",
    "chars": 2246,
    "preview": "const dataHelper = require('../../../../helper/data_helper.js');\nconst pageHelper = require('../../../../helper/page_hel"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/date_select/date_select_cmpt.json",
    "chars": 46,
    "preview": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/date_select/date_select_cmpt.wxml",
    "chars": 474,
    "preview": "<view class=\"date-cmpt\">\n\t<view class=\"month\">{{month||'2022年'}}</view>\n\t<scroll-view scroll-x class=\"date-select\" scrol"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/date_select/date_select_cmpt.wxss",
    "chars": 800,
    "preview": "@import \"../calendar_comm/din.wxss\";\n\n.date-cmpt {\n\twidth: 100%;\n}\n\n.date-cmpt .month {\n\twidth: 100%;\n\tpadding: 10rpx 15"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/time_select/time_select_cmpt.js",
    "chars": 4697,
    "preview": "const dataHelper = require('../../../../helper/data_helper.js');\nconst pageHelper = require('../../../../helper/page_hel"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/time_select/time_select_cmpt.json",
    "chars": 46,
    "preview": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/time_select/time_select_cmpt.wxml",
    "chars": 763,
    "preview": "<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"
  },
  {
    "path": "miniprogram/cmpts/public/calendar/time_select/time_select_cmpt.wxss",
    "chars": 2175,
    "preview": "@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"
  },
  {
    "path": "miniprogram/cmpts/public/checkbox/checkbox_cmpt.js",
    "chars": 1350,
    "preview": "Component({\n\texternalClasses: ['outside-picker-multi-class'],\n\n\t/**\n\t * 组件的属性列表\n\t */\n\tproperties: {\n\t\tsourceData: { //源数"
  },
  {
    "path": "miniprogram/cmpts/public/checkbox/checkbox_cmpt.json",
    "chars": 46,
    "preview": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/checkbox/checkbox_cmpt.wxml",
    "chars": 396,
    "preview": "<wxs src=\"../../../tpls/wxs/tools.wxs\" module=\"tools\" /> \n<checkbox-group bindchange=\"bindChange\" class=\"checkbox-group\""
  },
  {
    "path": "miniprogram/cmpts/public/checkbox/checkbox_cmpt.wxss",
    "chars": 728,
    "preview": ".checkbox-group {\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: center;\n\tflex-direction: column;\n\talign-items: center;"
  },
  {
    "path": "miniprogram/cmpts/public/editor/editor_cmpt.js",
    "chars": 4892,
    "preview": "const pageHelper = require('../../../helper/page_helper.js');\nconst dataHelper = require('../../../helper/data_helper.js"
  },
  {
    "path": "miniprogram/cmpts/public/editor/editor_cmpt.json",
    "chars": 46,
    "preview": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/editor/editor_cmpt.wxml",
    "chars": 2106,
    "preview": "<view class=\"editor-tab\" wx:if=\"{{viewMode}}\">\n\t<button catchtap=\"url\" data-type=\"bool\" data-url=\"isView\" class=\"btn rou"
  },
  {
    "path": "miniprogram/cmpts/public/editor/editor_cmpt.wxss",
    "chars": 2440,
    "preview": ".editor-tab {\n\twidth: 100%;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tposition: fixed;\n\ttop: 0;\n\t"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_set/field/form_set_field.js",
    "chars": 6284,
    "preview": "const pageHelper = require('../../../../../helper/page_helper.js');\nconst dataHelper = require('../../../../../helper/da"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_set/field/form_set_field.json",
    "chars": 281,
    "preview": "{\n\t\"usingComponents\": { \n\t\t\"cmpt-picker-multi\": \"/cmpts/public/picker_multi/picker_multi_cmpt\"\n\t},\n\t\"navigationBarBackgr"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_set/field/form_set_field.wxml",
    "chars": 3261,
    "preview": "<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\">字"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_set/field/form_set_field.wxss",
    "chars": 443,
    "preview": ".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"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_set/form_set_cmpt.js",
    "chars": 1684,
    "preview": "const pageHelper = require('../../../../helper/page_helper.js');\nconst dataHelper = require('../../../../helper/data_hel"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_set/form_set_cmpt.json",
    "chars": 46,
    "preview": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_set/form_set_cmpt.wxml",
    "chars": 1755,
    "preview": "<view class=\"form-group arrow {{cur==index?'cur':''}}\" hoverClass=\"form-group-active\" wx:for=\"{{fields}}\" wx:key=\"key\" s"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_set/form_set_cmpt.wxss",
    "chars": 940,
    "preview": ".picker-set {\n\tline-height: 100rpx;\n\tfont-size: 24rpx;\n\twidth: 100%;\n\ttext-align: right;\n\tcolor: #999;\n\twidth: 210rpx;\n}"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_set_helper.js",
    "chars": 10265,
    "preview": "/**\n * 配置格式\n * mark\n * title:\n * type:\n * desc: \n * min:\n * max:\n * must:\n * checkBoxLimit:2\n * onlySet:{mode:'all',cnt:"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_show/content/form_show_content.js",
    "chars": 1680,
    "preview": "const pageHelper = require('../../../../../helper/page_helper.js');\n\nPage({\n\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t\tformConten"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_show/content/form_show_content.json",
    "chars": 117,
    "preview": "{\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",
    "chars": 411,
    "preview": "<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-edit"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_show/content/form_show_content.wxss",
    "chars": 524,
    "preview": "@import '../../../../../style/public/admin.wxss';\n\n.main-admin {\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tpadding: 30rpx "
  },
  {
    "path": "miniprogram/cmpts/public/form/form_show/form_show_cmpt.js",
    "chars": 10301,
    "preview": "const pageHelper = require('../../../../helper/page_helper.js');\nconst helper = require('../../../../helper/helper.js');"
  },
  {
    "path": "miniprogram/cmpts/public/form/form_show/form_show_cmpt.json",
    "chars": 214,
    "preview": "{\n\t\"component\": true,\n\t\"usingComponents\": {\n\t\t\"cmpt-checkbox\": \"/cmpts/public/checkbox/checkbox_cmpt\",\n\t\t\"cmpt-radio\": \""
  },
  {
    "path": "miniprogram/cmpts/public/form/form_show/form_show_cmpt.wxml",
    "chars": 12393,
    "preview": "<view wx:if=\"{{isLoad===null}}\" class=\"margin-top load notexist text-l text-darkgreen load-project\"></view>\n<view wx:if="
  },
  {
    "path": "miniprogram/cmpts/public/form/form_show/form_show_cmpt.wxss",
    "chars": 1679,
    "preview": ".form-group .picker-base {\n\tflex: 1;\n\ttext-align: right;\n\theight: 60rpx;\n\tline-height: 60rpx;\n}\n\n.form-group .picker-sel"
  },
  {
    "path": "miniprogram/cmpts/public/img/img_upload_cmpt.js",
    "chars": 2945,
    "preview": "const pageHelper = require('../../../helper/page_helper.js');\nconst contentCheckHelper = require('../../../helper/conten"
  },
  {
    "path": "miniprogram/cmpts/public/img/img_upload_cmpt.json",
    "chars": 46,
    "preview": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/img/img_upload_cmpt.wxml",
    "chars": 936,
    "preview": "<view class=\"form-group\">\n\t<view class=\"title\"><text wx:if=\"{{must}}\" class=\"text-red\">*</text>{{title}} <text wx:if=\"{{"
  },
  {
    "path": "miniprogram/cmpts/public/img/img_upload_cmpt.wxss",
    "chars": 274,
    "preview": "@import \"../../../style/base/comm.wxss\"; \n@import \"../../../style/public/project.wxss\";  \n\n.form-group .upload-img .img-"
  },
  {
    "path": "miniprogram/cmpts/public/list/comm_list_cmpt.js",
    "chars": 9880,
    "preview": "const cloudHelper = require('../../../helper/cloud_helper.js');\nconst helper = require('../../../helper/helper.js');\ncon"
  },
  {
    "path": "miniprogram/cmpts/public/list/comm_list_cmpt.json",
    "chars": 46,
    "preview": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/list/comm_list_cmpt.wxml",
    "chars": 5723,
    "preview": "<view class=\"top_bar bar search fixed flex-direction\" wx:if=\"{{isTotalMenu}}\">\n\t<!-- search form BEGIN -->\n\t<view class="
  },
  {
    "path": "miniprogram/cmpts/public/list/comm_list_cmpt.wxss",
    "chars": 2131,
    "preview": "/*sort*/\n.tabs {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-start;\n\tfont-size: 28rpx;\n\tcolor: #aaa;\n\th"
  },
  {
    "path": "miniprogram/cmpts/public/modal/modal_cmpt.js",
    "chars": 981,
    "preview": "// cmpts/public/modal/modal.js\nComponent({\n\toptions: {\n\t\taddGlobalClass: true,\n\t\tmultipleSlots: true\n\t},\n\n\texternalClass"
  },
  {
    "path": "miniprogram/cmpts/public/modal/modal_cmpt.json",
    "chars": 46,
    "preview": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/modal/modal_cmpt.wxml",
    "chars": 2817,
    "preview": "<!-- 普通窗口 begin -->\n<view wx:if=\"{{type=='comm'}}\" class=\"modal {{show?'show':''}}\">\n\t<view class=\"dialog\">\n\t\t<view clas"
  },
  {
    "path": "miniprogram/cmpts/public/modal/modal_cmpt.wxss",
    "chars": 943,
    "preview": ".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: abs"
  },
  {
    "path": "miniprogram/cmpts/public/picker/picker_cmpt.js",
    "chars": 5951,
    "preview": "const helper = require('../../../helper/helper.js');\nconst dataHelper = require('../../../helper/data_helper.js');\nconst"
  },
  {
    "path": "miniprogram/cmpts/public/picker/picker_cmpt.json",
    "chars": 46,
    "preview": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/picker/picker_cmpt.wxml",
    "chars": 785,
    "preview": "<picker class=\"{{disabled?'disabled':''}}\" wx:if=\"{{steps==1}}\" mode=\"selector\" value=\"{{idx==-1?0:idx}}\" range=\"{{optio"
  },
  {
    "path": "miniprogram/cmpts/public/picker/picker_cmpt.wxss",
    "chars": 586,
    "preview": ".picker-cmpt {\n\tline-height: 100rpx;\n\tfont-size: 28rpx;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n\toverflow: hidde"
  },
  {
    "path": "miniprogram/cmpts/public/picker_multi/picker_multi_cmpt.js",
    "chars": 8028,
    "preview": "/* 参考文档: https://github.com/IceApriler/miniprogram-picker */\n/*\n[{\n\tlabel:'ddd' // 展示数据的字段名称\n\tval:'v1',\n},\n{\n\tlabel:'ccc"
  },
  {
    "path": "miniprogram/cmpts/public/picker_multi/picker_multi_cmpt.json",
    "chars": 46,
    "preview": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/picker_multi/picker_multi_cmpt.wxml",
    "chars": 979,
    "preview": "<picker class=\"multi-picker picker-class\" mode=\"multiSelector\" bindchange=\"pickerChange\" bindcolumnchange=\"pickerColumnC"
  },
  {
    "path": "miniprogram/cmpts/public/picker_multi/picker_multi_cmpt.wxss",
    "chars": 158,
    "preview": ".picker-cmpt {\n\tline-height: 100rpx;\n\tfont-size: 28rpx;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n\toverflow: hidde"
  },
  {
    "path": "miniprogram/cmpts/public/picker_time/datetime_picker.js",
    "chars": 3079,
    "preview": "const timeHelper = require('../../../helper/time_helper.js');\n\nfunction withData(param, unit = '') {\n\tif (unit) return p"
  },
  {
    "path": "miniprogram/cmpts/public/picker_time/picker_time_cmpt.js",
    "chars": 4201,
    "preview": "const timeHelper = require('../../../helper/time_helper.js');\nconst dateTimePicker = require('./datetime_picker.js');\n\nC"
  },
  {
    "path": "miniprogram/cmpts/public/picker_time/picker_time_cmpt.json",
    "chars": 46,
    "preview": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/picker_time/picker_time_cmpt.wxml",
    "chars": 260,
    "preview": "<picker \n  class=\"multi-picker picker-class\"\n  mode=\"multiSelector\"\n  bindchange=\"pickerChange\"\n  bindcolumnchange=\"pick"
  },
  {
    "path": "miniprogram/cmpts/public/picker_time/picker_time_cmpt.wxss",
    "chars": 52,
    "preview": "/* cmpts/public/picker_time/picker_time_cmpt.wxss */"
  },
  {
    "path": "miniprogram/cmpts/public/poster/poster_cmpt.js",
    "chars": 3042,
    "preview": "/*\nhttps://github.com/jasondu/wxa-plugin-canvas\n### 标准尺寸:\nwidth: 375, // rpx\nheight: 670,\n\n### 父页面分享按钮取值\nonShareAppMessa"
  },
  {
    "path": "miniprogram/cmpts/public/poster/poster_cmpt.json",
    "chars": 89,
    "preview": "{\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",
    "chars": 1248,
    "preview": "<poster wx:if=\"{{posterConfig}}\" id=\"poster\" hide-loading=\"{{true}}\" preload=\"{{false}}\" config=\"{{posterConfig}}\" bind:"
  },
  {
    "path": "miniprogram/cmpts/public/poster/poster_cmpt.wxss",
    "chars": 1456,
    "preview": ".main-poster .poster-share {\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: space-around;\n\talign-items: center;\n\tpaddin"
  },
  {
    "path": "miniprogram/cmpts/public/poster/poster_cmpt_helper.js",
    "chars": 1341,
    "preview": "const cloudHelper = require('../../../helper/cloud_helper.js');\n\nasync function config1({\n\tcover,\n\ttitle,\n\tdesc,\n\tqr,\n\tb"
  },
  {
    "path": "miniprogram/cmpts/public/poster/wxa-plugin-canvas/index/index.js",
    "chars": 15804,
    "preview": "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\tpadd"
  },
  {
    "path": "miniprogram/cmpts/public/poster/wxa-plugin-canvas/index/index.json",
    "chars": 25,
    "preview": "{\n    \"component\": true\n}"
  },
  {
    "path": "miniprogram/cmpts/public/poster/wxa-plugin-canvas/index/index.wxml",
    "chars": 191,
    "preview": "<!--index.wxml-->\n<view class=\"container\">\n  <canvas id='canvasid' type=\"2d\" class=\"canvas {{debug ? 'debug' : 'pro'}}\" "
  },
  {
    "path": "miniprogram/cmpts/public/poster/wxa-plugin-canvas/index/index.wxss",
    "chars": 261,
    "preview": ".canvas {\n    width: 750rpx;\n    height: 750rpx;\n}\n.canvas.pro {\n    position: absolute;\n    bottom: 0;\n    left: 0;\n   "
  },
  {
    "path": "miniprogram/cmpts/public/poster/wxa-plugin-canvas/poster/index.js",
    "chars": 2252,
    "preview": "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"
  },
  {
    "path": "miniprogram/cmpts/public/poster/wxa-plugin-canvas/poster/index.json",
    "chars": 95,
    "preview": "{\n    \"component\": true,\n    \"usingComponents\": {\n        \"we-canvas\": \"../index/index\"\n    }\n}"
  },
  {
    "path": "miniprogram/cmpts/public/poster/wxa-plugin-canvas/poster/index.wxml",
    "chars": 126,
    "preview": "<view bindtap='onCreate'>\n    <slot/>\n</view>\n<we-canvas id=\"poster\" bind:success=\"onCreateSuccess\" bind:fail=\"onCreateF"
  },
  {
    "path": "miniprogram/cmpts/public/poster/wxa-plugin-canvas/poster/index.wxss",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "miniprogram/cmpts/public/poster/wxa-plugin-canvas/poster/poster.js",
    "chars": 615,
    "preview": "const defaultOptions = {\n    selector: '#poster'\n};\n\nfunction Poster(options = {}, that) {\n    options = {\n        ...de"
  },
  {
    "path": "miniprogram/cmpts/public/radio/radio_cmpt.js",
    "chars": 1457,
    "preview": "Component({\n\texternalClasses: ['outside-picker-multi-class'],\n\n\t/**\n\t * 组件的属性列表\n\t */\n\tproperties: {\n\t\tsourceData: { //源数"
  },
  {
    "path": "miniprogram/cmpts/public/radio/radio_cmpt.json",
    "chars": 46,
    "preview": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/radio/radio_cmpt.wxml",
    "chars": 326,
    "preview": "<radio-group bindchange=\"bindChange\" class=\"radio-group\">\n\t<view class=\"item\" wx:for=\"{{options}}\" wx:key=\"key\"> \n\t\t<lab"
  },
  {
    "path": "miniprogram/cmpts/public/radio/radio_cmpt.wxss",
    "chars": 707,
    "preview": ".radio-group {\n\twidth: 100%;\n\tdisplay: flex;\n\tjustify-content: center;\n\tflex-direction: column;\n\talign-items: center;\n\tp"
  },
  {
    "path": "miniprogram/cmpts/public/swiper/swiper_cmpt.js",
    "chars": 923,
    "preview": "const pageHelper = require('../../../helper/page_helper.js');\nComponent({\n\toptions: {\n\t\taddGlobalClass: true,\n\t},\n\n\t/**\n"
  },
  {
    "path": "miniprogram/cmpts/public/swiper/swiper_cmpt.json",
    "chars": 46,
    "preview": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/swiper/swiper_cmpt.wxml",
    "chars": 634,
    "preview": "<swiper wx:if=\"{{images.length>0}}\" class=\"swiper\" style=\"height:{{height}}rpx\" indicator-active-color=\"{{indicatorActiv"
  },
  {
    "path": "miniprogram/cmpts/public/swiper/swiper_cmpt.wxss",
    "chars": 66,
    "preview": ".swiper {\n\twidth: 100%; \n}\n.swiper-item-images {\n\twidth: 100%; \n} "
  },
  {
    "path": "miniprogram/cmpts/public/table/table_cmpt.js",
    "chars": 1052,
    "preview": "/**\n * \n */\nComponent({\n\t/**\n\t * 外部样式类\n\t */\n\texternalClasses: ['header-row-class-name', 'row-class-name', 'cell-class-na"
  },
  {
    "path": "miniprogram/cmpts/public/table/table_cmpt.json",
    "chars": 46,
    "preview": "{\n\t\"component\": true,\n\t\"usingComponents\": {}\n}"
  },
  {
    "path": "miniprogram/cmpts/public/table/table_cmpt.wxml",
    "chars": 865,
    "preview": "<view scroll-x=\"{{true}}\" scroll-y=\"{{true}}\" scroll-anchoring=\"{{true}}\" enhanced=\"{{true}}\" bounces=\"{{false}}\" class="
  },
  {
    "path": "miniprogram/cmpts/public/table/table_cmpt.wxss",
    "chars": 1604,
    "preview": ".reset {\n    background: white;\n} \n\n.other {\n    font-size: 20px;\n} \n\n.table {\n  position: relative;\n  font-size: 28rpx;"
  },
  {
    "path": "miniprogram/comm/behavior/about_bh.js",
    "chars": 1394,
    "preview": "const pageHelper = require('../../helper/page_helper.js');\nconst cloudHelper = require('../../helper/cloud_helper.js'); "
  },
  {
    "path": "miniprogram/comm/behavior/my_fav_bh.js",
    "chars": 1300,
    "preview": "const pageHelper = require('../../helper/page_helper.js');\nconst cloudHelper = require('../../helper/cloud_helper.js');\n"
  },
  {
    "path": "miniprogram/comm/behavior/my_foot_bh.js",
    "chars": 925,
    "preview": "const FootBiz = require('../biz/foot_biz.js');\nconst pageHelper = require('../../helper/page_helper.js');\n\nmodule.export"
  },
  {
    "path": "miniprogram/comm/behavior/news_index_bh.js",
    "chars": 1241,
    "preview": "const pageHelper = require('../../helper/page_helper.js');\nmodule.exports = Behavior({\n\t/**\n\t * 页面的初始数据\n\t */\n\tdata: {\n\t}"
  },
  {
    "path": "miniprogram/comm/behavior/search_bh.js",
    "chars": 1951,
    "preview": "const SearchBiz = require('../../comm/biz/search_biz.js');\nconst pageHelper = require('../../helper/page_helper.js');\n\nm"
  },
  {
    "path": "miniprogram/comm/biz/admin_biz.js",
    "chars": 3841,
    "preview": "/**\n * Notes: 后台管理模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-"
  },
  {
    "path": "miniprogram/comm/biz/base_biz.js",
    "chars": 1078,
    "preview": "/**\n * Notes: 基础模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2020-11"
  },
  {
    "path": "miniprogram/comm/biz/fav_biz.js",
    "chars": 1123,
    "preview": "/**\n * Notes: 预约模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)\n * Date: 2021-12"
  },
  {
    "path": "miniprogram/comm/biz/foot_biz.js",
    "chars": 1425,
    "preview": "/**\n * Notes: 足迹模块业务逻辑\n * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY www.code942.com\n * Date: 2020-11-14 0"
  }
]

// ... and 309 more files (download for full content)

About this extraction

This page contains the full source code of the nanbouking/WeTravel GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 509 files (1.3 MB), approximately 533.6k tokens, and a symbol index with 1014 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!