From cb74b8b073385fff4f86df95ef8a0a8e32f828d9 Mon Sep 17 00:00:00 2001 From: aBin Date: Fri, 31 Dec 2021 15:42:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9A=B4=E9=A3=8E=E7=9C=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .editorconfig | 8 + .env | 0 .env.development | 8 + .env.mock | 2 + .env.production | 8 + .eslintignore | 13 + .eslintrc.js | 48 + .gitignore | 27 + .hbuilderx/launch.json | 11 + .npmrc | 1 + .prettierignore | 9 + .prettierrc | 13 + CHANGELOG.md | 243 + README.md | 101 + babel.config.js | 57 + commitlint.config.js | 1 + jest.config.js | 52 + package.json | 114 + postcss.config.js | 21 + public/img/icons/android-chrome-192x192.png | Bin 0 -> 9416 bytes public/img/icons/android-chrome-512x512.png | Bin 0 -> 29808 bytes .../icons/android-chrome-maskable-192x192.png | Bin 0 -> 6401 bytes .../icons/android-chrome-maskable-512x512.png | Bin 0 -> 23038 bytes public/img/icons/apple-touch-icon-120x120.png | Bin 0 -> 3369 bytes public/img/icons/apple-touch-icon-152x152.png | Bin 0 -> 4046 bytes public/img/icons/apple-touch-icon-180x180.png | Bin 0 -> 4678 bytes public/img/icons/apple-touch-icon-60x60.png | Bin 0 -> 1491 bytes public/img/icons/apple-touch-icon-76x76.png | Bin 0 -> 1823 bytes public/img/icons/apple-touch-icon.png | Bin 0 -> 4678 bytes public/img/icons/favicon-16x16.png | Bin 0 -> 799 bytes public/img/icons/favicon-32x32.png | Bin 0 -> 1271 bytes .../img/icons/msapplication-icon-144x144.png | Bin 0 -> 1169 bytes public/img/icons/mstile-150x150.png | Bin 0 -> 4282 bytes public/img/icons/safari-pinned-tab.svg | 3 + public/index.html | 28 + public/robots.txt | 2 + src/App.vue | 159 + src/apis/carbasics.js | 67 + src/apis/project.js | 19 + src/apis/role.js | 49 + src/apis/tall.js | 109 + src/apis/task.js | 17 + src/apis/wbs.js | 7 + src/common/styles/app.scss | 7 + src/common/styles/iconfont.css | 257 + src/common/styles/iconfont.scss | 257 + src/common/styles/tailwind.scss | 4509 +++++++++++++++++ src/components/Calendar/Calendar.vue | 473 ++ src/components/Calendar/generateDates.js | 136 + src/components/Globals/Globals.vue | 86 + src/components/ImageCode/ImageCode.vue | 37 + src/components/PatientList/PatientList.vue | 467 ++ src/components/PatientList/icon/yanshi.png | Bin 0 -> 2695 bytes .../PrettyExchange/PrettyExchange.vue | 520 ++ src/components/Projects/ProjectItem.vue | 161 + src/components/Projects/Projects.vue | 65 + src/components/Roles/Roles.vue | 264 + src/components/Service/Service.vue | 33 + src/components/Service/icon/tel-we.png | Bin 0 -> 6928 bytes src/components/TimeLine/TimeLine.vue | 126 + src/components/TimeLine/component/Barrier.vue | 42 + .../TimeLine/component/TaskTools.vue | 185 + src/components/TimeLine/component/TimeBox.vue | 142 + .../TimeLine/component/TimeStatus.vue | 231 + src/components/TimeLine/component/Title.vue | 7 + src/components/Title/Title.vue | 235 + .../Title/components/CreateTask.vue | 460 ++ .../Title/components/ShareProject.vue | 210 + src/components/Upload/Upload.vue | 201 + src/components/select-lay/select-lay.vue | 418 ++ src/config/app.js | 6 + src/config/db.js | 3 + src/config/plugin.js | 97 + src/config/task.js | 2 + src/config/time.js | 17 + src/config/user copy.js | 43 + src/config/user.js | 44 + src/config/zIndex.js | 5 + src/main.js | 52 + src/manifest.json | 81 + src/mixins/userAuth.js | 48 + src/pages.json | 78 + src/pages/camera/camera.vue | 71 + src/pages/establish/establish.vue | 444 ++ src/pages/establish/icon/bottom.png | Bin 0 -> 8173 bytes src/pages/establish/icon/idcard.png | Bin 0 -> 4185 bytes src/pages/get-phone-power/get-phone-power.vue | 156 + src/pages/index/index.vue | 170 + src/pages/inner/inner.vue | 36 + src/pages/patientLine/patientLine.vue | 181 + src/pages/patientLine/png/播放.png | Bin 0 -> 9428 bytes src/pages/phone-bind/phone-bind.vue | 192 + src/pages/project-webview/project-webview.vue | 41 + .../questionnaire-webview.vue | 31 + src/pages/task-page/task-page.vue | 319 ++ src/registerServiceWorker.js | 29 + src/store/carbasics/actions.js | 3 + src/store/carbasics/getters.js | 3 + src/store/carbasics/index.js | 12 + src/store/carbasics/mutations.js | 35 + src/store/carbasics/state.js | 12 + src/store/db/actions.js | 3 + src/store/db/getters.js | 3 + src/store/db/index.js | 12 + src/store/db/mutations.js | 3 + src/store/db/state.js | 7 + src/store/index.js | 52 + src/store/messages/getters.js | 3 + src/store/messages/index.js | 4 + src/store/messages/mutations.js | 86 + src/store/messages/state.js | 8 + src/store/project/actions.js | 3 + src/store/project/getters.js | 11 + src/store/project/index.js | 12 + src/store/project/mutations.js | 71 + src/store/project/state.js | 9 + src/store/role/actions.js | 17 + src/store/role/getters.js | 13 + src/store/role/index.js | 12 + src/store/role/mutations.js | 48 + src/store/role/state.js | 9 + src/store/socket/actions.js | 151 + src/store/socket/index.js | 5 + src/store/socket/mutations.js | 26 + src/store/socket/state.js | 7 + src/store/task/actions.js | 33 + src/store/task/getters.js | 23 + src/store/task/index.js | 12 + src/store/task/mutations.js | 206 + src/store/task/state.js | 25 + src/store/user/actions.js | 19 + src/store/user/getters.js | 14 + src/store/user/index.js | 12 + src/store/user/mutations.js | 24 + src/store/user/state.js | 5 + src/uni.scss | 76 + src/utils/cache.js | 176 + src/utils/cacheAndRequest.js | 190 + src/utils/indexedDB.js | 163 + src/utils/request.js | 54 + src/utils/storage.js | 112 + src/utils/tall.js | 38 + src/utils/time.js | 366 ++ src/utils/ui.js | 56 + src/utils/upload.js | 110 + tsconfig.json | 9 + vue.config.js | 36 + 147 files changed, 15271 insertions(+) create mode 100644 .editorconfig create mode 100644 .env create mode 100644 .env.development create mode 100644 .env.mock create mode 100644 .env.production create mode 100644 .eslintignore create mode 100644 .eslintrc.js create mode 100644 .gitignore create mode 100644 .hbuilderx/launch.json create mode 100644 .npmrc create mode 100644 .prettierignore create mode 100644 .prettierrc create mode 100644 CHANGELOG.md create mode 100644 README.md create mode 100644 babel.config.js create mode 100644 commitlint.config.js create mode 100644 jest.config.js create mode 100644 package.json create mode 100644 postcss.config.js create mode 100644 public/img/icons/android-chrome-192x192.png create mode 100644 public/img/icons/android-chrome-512x512.png create mode 100644 public/img/icons/android-chrome-maskable-192x192.png create mode 100644 public/img/icons/android-chrome-maskable-512x512.png create mode 100644 public/img/icons/apple-touch-icon-120x120.png create mode 100644 public/img/icons/apple-touch-icon-152x152.png create mode 100644 public/img/icons/apple-touch-icon-180x180.png create mode 100644 public/img/icons/apple-touch-icon-60x60.png create mode 100644 public/img/icons/apple-touch-icon-76x76.png create mode 100644 public/img/icons/apple-touch-icon.png create mode 100644 public/img/icons/favicon-16x16.png create mode 100644 public/img/icons/favicon-32x32.png create mode 100644 public/img/icons/msapplication-icon-144x144.png create mode 100644 public/img/icons/mstile-150x150.png create mode 100644 public/img/icons/safari-pinned-tab.svg create mode 100644 public/index.html create mode 100644 public/robots.txt create mode 100644 src/App.vue create mode 100644 src/apis/carbasics.js create mode 100644 src/apis/project.js create mode 100644 src/apis/role.js create mode 100644 src/apis/tall.js create mode 100644 src/apis/task.js create mode 100644 src/apis/wbs.js create mode 100644 src/common/styles/app.scss create mode 100644 src/common/styles/iconfont.css create mode 100644 src/common/styles/iconfont.scss create mode 100644 src/common/styles/tailwind.scss create mode 100644 src/components/Calendar/Calendar.vue create mode 100644 src/components/Calendar/generateDates.js create mode 100644 src/components/Globals/Globals.vue create mode 100644 src/components/ImageCode/ImageCode.vue create mode 100644 src/components/PatientList/PatientList.vue create mode 100644 src/components/PatientList/icon/yanshi.png create mode 100644 src/components/PrettyExchange/PrettyExchange.vue create mode 100644 src/components/Projects/ProjectItem.vue create mode 100644 src/components/Projects/Projects.vue create mode 100644 src/components/Roles/Roles.vue create mode 100644 src/components/Service/Service.vue create mode 100644 src/components/Service/icon/tel-we.png create mode 100644 src/components/TimeLine/TimeLine.vue create mode 100644 src/components/TimeLine/component/Barrier.vue create mode 100644 src/components/TimeLine/component/TaskTools.vue create mode 100644 src/components/TimeLine/component/TimeBox.vue create mode 100644 src/components/TimeLine/component/TimeStatus.vue create mode 100644 src/components/TimeLine/component/Title.vue create mode 100644 src/components/Title/Title.vue create mode 100644 src/components/Title/components/CreateTask.vue create mode 100644 src/components/Title/components/ShareProject.vue create mode 100644 src/components/Upload/Upload.vue create mode 100644 src/components/select-lay/select-lay.vue create mode 100644 src/config/app.js create mode 100644 src/config/db.js create mode 100644 src/config/plugin.js create mode 100644 src/config/task.js create mode 100644 src/config/time.js create mode 100644 src/config/user copy.js create mode 100644 src/config/user.js create mode 100644 src/config/zIndex.js create mode 100644 src/main.js create mode 100644 src/manifest.json create mode 100644 src/mixins/userAuth.js create mode 100644 src/pages.json create mode 100644 src/pages/camera/camera.vue create mode 100644 src/pages/establish/establish.vue create mode 100644 src/pages/establish/icon/bottom.png create mode 100644 src/pages/establish/icon/idcard.png create mode 100644 src/pages/get-phone-power/get-phone-power.vue create mode 100644 src/pages/index/index.vue create mode 100644 src/pages/inner/inner.vue create mode 100644 src/pages/patientLine/patientLine.vue create mode 100644 src/pages/patientLine/png/播放.png create mode 100644 src/pages/phone-bind/phone-bind.vue create mode 100644 src/pages/project-webview/project-webview.vue create mode 100644 src/pages/questionnaire-webview/questionnaire-webview.vue create mode 100644 src/pages/task-page/task-page.vue create mode 100644 src/registerServiceWorker.js create mode 100644 src/store/carbasics/actions.js create mode 100644 src/store/carbasics/getters.js create mode 100644 src/store/carbasics/index.js create mode 100644 src/store/carbasics/mutations.js create mode 100644 src/store/carbasics/state.js create mode 100644 src/store/db/actions.js create mode 100644 src/store/db/getters.js create mode 100644 src/store/db/index.js create mode 100644 src/store/db/mutations.js create mode 100644 src/store/db/state.js create mode 100644 src/store/index.js create mode 100644 src/store/messages/getters.js create mode 100644 src/store/messages/index.js create mode 100644 src/store/messages/mutations.js create mode 100644 src/store/messages/state.js create mode 100644 src/store/project/actions.js create mode 100644 src/store/project/getters.js create mode 100644 src/store/project/index.js create mode 100644 src/store/project/mutations.js create mode 100644 src/store/project/state.js create mode 100644 src/store/role/actions.js create mode 100644 src/store/role/getters.js create mode 100644 src/store/role/index.js create mode 100644 src/store/role/mutations.js create mode 100644 src/store/role/state.js create mode 100644 src/store/socket/actions.js create mode 100644 src/store/socket/index.js create mode 100644 src/store/socket/mutations.js create mode 100644 src/store/socket/state.js create mode 100644 src/store/task/actions.js create mode 100644 src/store/task/getters.js create mode 100644 src/store/task/index.js create mode 100644 src/store/task/mutations.js create mode 100644 src/store/task/state.js create mode 100644 src/store/user/actions.js create mode 100644 src/store/user/getters.js create mode 100644 src/store/user/index.js create mode 100644 src/store/user/mutations.js create mode 100644 src/store/user/state.js create mode 100644 src/uni.scss create mode 100644 src/utils/cache.js create mode 100644 src/utils/cacheAndRequest.js create mode 100644 src/utils/indexedDB.js create mode 100644 src/utils/request.js create mode 100644 src/utils/storage.js create mode 100644 src/utils/tall.js create mode 100644 src/utils/time.js create mode 100644 src/utils/ui.js create mode 100644 src/utils/upload.js create mode 100644 tsconfig.json create mode 100644 vue.config.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..ab4c0eb --- /dev/null +++ b/.editorconfig @@ -0,0 +1,8 @@ +[*.{js,jsx,ts,tsx,vue}] +indent_style = space +indent_size = 2 +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true +max_line_length = 140 +root = true diff --git a/.env b/.env new file mode 100644 index 0000000..e69de29 diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..a5db629 --- /dev/null +++ b/.env.development @@ -0,0 +1,8 @@ +VUE_APP_NODE_ENV=development +VUE_APP_BASE_URL=https://test.tall.wiki +VUE_APP_API_URL=https://test.tall.wiki/gateway +VUE_APP_MSG_URL=ws://101.201.226.163/websocket/message/v4.0/ws +VUE_APP_PROJECT_PATH=https://test.tall.wiki/carBasicTall +VUE_APP_QUESTION_PATH=https://test.tall.wiki/carbasics +VUE_APP_VERSION=v3.1.0 +VUE_APP_PUBLIC_PATH=/carBasicCalendar/ diff --git a/.env.mock b/.env.mock new file mode 100644 index 0000000..5dd5931 --- /dev/null +++ b/.env.mock @@ -0,0 +1,2 @@ +VUE_APP_BASE_URL=http://127.0.0.1:8080 +VUE_APP_API_URL=http://127.0.0.1:8080 diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..e719192 --- /dev/null +++ b/.env.production @@ -0,0 +1,8 @@ +VUE_APP_NODE_ENV=production +VUE_APP_BASE_URL=https://test.tall.wiki +VUE_APP_API_URL=https://test.tall.wiki/gateway +VUE_APP_MSG_URL=ws://101.201.226.163/websocket/message/v4.0/ws +VUE_APP_PROJECT_PATH=https://test.tall.wiki/carBasicTall +VUE_APP_QUESTION_PATH=https://test.tall.wiki/carbasics +VUE_APP_VERSION=v3.1.0 +VUE_APP_PUBLIC_PATH=/carBasicCalendar/ diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..7ac19f0 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,13 @@ +node_modules +dist/ +test +build/ +unpackage/ +babel.config.js +package.json +postcss.config.js +.eslint.js +vue.config.js +src/common/styles/index.css +src/pages.json +manifest.json diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..d1d7b97 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,48 @@ +module.exports = { + root: true, + env: { + node: true, + browser: true, + }, + extends: ['plugin:vue/essential', 'eslint:recommended', '@vue/prettier'], + rules: { + 'vue/html-self-closing': 'off', + 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', + 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', + 'no-param-reassign': 'off', + 'max-len': ['error', { code: 140, tabWidth: 2 }], + 'object-curly-newline': ['error', { multiline: true }], + 'arrow-parens': ['error', 'as-needed'], + 'linebreak-style': 'off', + 'vue/attributes-order': 'off', + 'vue/singleline-html-element-content-newline': 'off', + 'vue/max-attributes-per-line': 'off', + 'vue/multiline-html-element-content-newline': 'off', + 'vue/html-indent': 'off', + 'vue/html-closing-bracket-newline': [ + 'error', + { + singleline: 'never', + multiline: 'always', + }, + ], + }, + + parserOptions: { parser: 'babel-eslint' }, + + overrides: [ + { + files: ['**/__tests__/*.{j,t}s?(x)'], + env: { jest: true }, + }, + ], + + globals: { + Vue: true, + VueRouter: true, + Vuex: true, + _: true, + uni: true, + wx: true, + }, +}; diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ccf2ca7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +.DS_Store +node_modules/ +unpackage/ +dist/ + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +yarn.lock +package-lock.json + +# Editor directories and files +.project +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw* +.eslintcache diff --git a/.hbuilderx/launch.json b/.hbuilderx/launch.json new file mode 100644 index 0000000..e5aaa3e --- /dev/null +++ b/.hbuilderx/launch.json @@ -0,0 +1,11 @@ +{ // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/ + // launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数 + "version": "0.0", + "configurations": [{ + "type": "uniCloud", + "default": { + "launchtype": "local" + } + } + ] +} diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..b98d8c8 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +registry=https://registry.npm.taobao.org diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..8967f13 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,9 @@ +node_modules +dist/ +test +build/ +unpackage/ +babel.config.js +package.json +postcss.config.js +.eslint.js diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..ae624c3 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,13 @@ +{ + "printWidth": 140, + "singleQuote": true, + "semi": true, + "trailingComma": "all", + "arrowParens": "avoid", + "tabWidth": 2, + "useTabs": false, + "bracketSpacing": true, + "jsxBracketSameLine": false, + "proseWrap": "always", + "endOfLine": "lf" +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..ef95098 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,243 @@ +# 0.1.0 (2021-11-22) + +### 🌟 新功能 +范围|描述|commitId +--|--|-- + - | 绑定手机号 | [52e0352](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/52e0352) + - | 暴风眼相关小程序修改 | [8947ea8](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/8947ea8) + - | 标题栏变化 | [3898cfe](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/3898cfe) + - | 标题栏变化 | [c0fcd9d](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/c0fcd9d) + - | 标题栏角色栏全局任务组件新建 | [0500cb4](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/0500cb4) + - | 插件参数处理调整 | [a3e68d3](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/a3e68d3) + - | 插件数据获取 | [5b91bdc](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/5b91bdc) + - | 存token | [b8a178d](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/b8a178d) + - | 导入项目,更新项目 | [5e06adf](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/5e06adf) + - | 导入项目后提示并打开项目详情页 | [410f527](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/410f527) + - | 导入wbs | [1224fcb](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/1224fcb) + - | 点击日历日期查询项目列表 | [c458385](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/c458385) + - | 定期任务面板骨架屏添加 | [b2698c0](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/b2698c0) + 富文本插件 | 富文本插件demo测试 | [ed3d644](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/ed3d644) + - | 缓存修改 | [63e1f0d](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/63e1f0d) + - | 获取用户收取那,提交用户信息 | [a3c54f1](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/a3c54f1) + - | 角色栏实现 | [94cd671](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/94cd671) + - | 进入项目默认打开项目列表第一个项目 | [f666730](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/f666730) + - | 距调整pc端 | [5069aa1](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/5069aa1) + - | 客服加分享 | [ccae107](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/ccae107) + - | 客服位置更改及首页分享功能 | [239a6ba](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/239a6ba) + - | 面变化首页变化 | [5e860f1](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/5e860f1) + - | 模拟接口测试 | [69e7931](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/69e7931) + - | 配置默认插件接口 | [f0c177d](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/f0c177d) + - | 全局插件及默认插件位置修改 | [6c80d08](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/6c80d08) + - | 任务进行中状态数字 | [27b7326](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/27b7326) + - | 任务状态时间显示 | [56f5183](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/56f5183) + - | 日常任务插件调整 | [c1881f9](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/c1881f9) + - | 日历定位;合并 | [ea3f937](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/ea3f937) + - | 删除项目 | [00b886c](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/00b886c) + - | 上传逻辑变化 | [3ff1dc2](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/3ff1dc2) + - | 设置小红点 | [9316bcb](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/9316bcb) + - | 升级版本v3.1.0;tailwindcss添加class | [9ef05e1](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/9ef05e1) + - | 时间基准线,默认插件 | [a33ba1e](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/a33ba1e) + - | 时间轴界面 | [33927e9](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/33927e9) + - | 时间轴修改状态时提示框增加 | [e841392](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/e841392) + - | 适配小程序;小程序登录 | [cefc0eb](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/cefc0eb) + - | 首页项目样式改变 | [8514c85](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/8514c85) + - | 提交到本地 | [9cbe411](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/9cbe411) + - | 添加 环境变量,动态控制webview project的path | [8a40481](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/8a40481) + - | 添加时间轴上下滚动 | [2b81bbc](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/2b81bbc) + - | 添加项目排序 | [a0b491b](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/a0b491b) + - | 添加子任务插件 子项目插件 | [7bda7e2](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/7bda7e2) + - | 问卷功能取消,排名查看功能新增 | [f405a38](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/f405a38) + - | 细节调整,添加project-webview | [4d9050b](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/4d9050b) + - | 向右箭头图标变化 | [8e9ca55](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/8e9ca55) + - | 项目列表, 项目url | [32e005b](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/32e005b) + - | 项目列表排序 | [224c58b](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/224c58b) + - | 项目api url设置 | [6cd5245](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/6cd5245) + - | 修改小程序id | [4206bf2](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/4206bf2) + - | 引入dayjs | [29b8b93](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/29b8b93) + - | 字体大小更改 | [82cfdd4](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/82cfdd4) + - | api封装 | [7d4edfc](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/7d4edfc) + bind phone | 图形验证码;短信验证码;绑定手机号 | [93ffea2](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/93ffea2) + - | cache indexedDB处理 | [3388967](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/3388967) + calendar, tall.js | 上下滑动切换日历的模式,tall.js中domain根据环境变量切换 | [364e25d](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/364e25d) + - | db store | [6414c4f](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/6414c4f) + default plugin | 添加默认插件;项目列表;全局项目最大高度设置 | [ed1d87b](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/ed1d87b) + - | indexedDB | [687394e](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/687394e) + modules update;network | npm包升级;网络判断,网络不好才开启本地存储 | [ebf7bdc](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/ebf7bdc) + mp | 兼容小程序,去除window,document等 | [9178255](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/9178255) + phone-bind | 验证码validate | [a427250](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/a427250) + pinch | alloy finger实现图片的pinch放大缩小 | [de01343](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/de01343) + plugin | 插件添加了token及param参数 | [aeb0292](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/aeb0292) + - | post 封装 | [da52e94](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/da52e94) + - | tailwindcss添加部分属性 | [5b46b6d](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/5b46b6d) + - | tall插件封装 | [1bcb920](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/1bcb920) + task status | 任务状态切换未完 | [7ffd135](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/7ffd135) + - | ws storage | [21b3a06](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/21b3a06) + + +### 🎨 代码样式 +范围|描述|commitId +--|--|-- + - | 代码格式细节调整 | [cb2532b](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/cb2532b) + - | 代码审查 | [d75134c](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/d75134c) + - | 格式细节调整 | [b907a03](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/b907a03) + - | 更新代码 | [8c27e68](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/8c27e68) + - | 更新代码 | [1f40a76](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/1f40a76) + - | 任务快捷方式图标增加 | [4aba872](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/4aba872) + - | 日常任务修改 | [dfa7ee2](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/dfa7ee2) + - | 删除插件携带的多余文件 | [0f392bb](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/0f392bb) + - | 删除多余字段 | [5ae3973](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/5ae3973) + - | 删除没用代码 | [34b20e1](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/34b20e1) + - | 删除calendar中多余的console | [e339eec](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/e339eec) + - | 删除console.log | [5064a38](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/5064a38) + - | 删除index中没用的alert代码 | [9c9eec7](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/9c9eec7) + - | 删除mock,console;upload添加loading | [99d42e2](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/99d42e2) + - | 添加插件数据 | [2f11b42](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/2f11b42) + - | 图标修改 | [54bca09](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/54bca09) + - | 无基本变化 | [21ac4bb](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/21ac4bb) + - | 细节调整 | [2cfc09a](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/2cfc09a) + - | 修改角色样式 | [73e268e](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/73e268e) + - | 组件新建 | [89c0035](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/89c0035) + - | calendar注释 | [a2ec112](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/a2ec112) + - | indexedDB.js格式整理 | [b0d3a36](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/b0d3a36) + + +### 🐛 Bug 修复 +范围|描述|commitId +--|--|-- + - | 1.时间轴数据渲染 2.时间基准线 | [d643af2](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/d643af2) + - | 插件bug解决 | [41257eb](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/41257eb) + - | 初始展示角色修改 | [2ac4053](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/2ac4053) + - | 定期任务本地缓存和api赋值,未完成 | [5a10856](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/5a10856) + 定期任务本地缓存和api赋值,未完成 | 定期任务本地缓存和api赋值,未完成 | [b22a366](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/b22a366) + - | 定期任务插件 | [92b3254](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/92b3254) + - | 定期任务骨架屏修改 | [8ff72dd](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/8ff72dd) + - | 定期任务接口 | [aa4981c](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/aa4981c) + - | 定期任务未加载时,显示空的时间轴并能上下滑动 | [ce38093](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/ce38093) + - | 定期任务key值修改 | [c6688db](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/c6688db) + - | 骨架屏替换 | [e9fdd71](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/e9fdd71) + - | 监听时间基本点 | [033fca0](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/033fca0) + - | 角色栏修改 | [19228d6](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/19228d6) + - | 角色显示状态修改 | [7d3b906](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/7d3b906) + - | 解决时间轴报错 | [da1eece](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/da1eece) + - | 平车演示临时去掉项目快捷方式的toast提示 | [e0b2c23](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/e0b2c23) + - | 切换到默认项目角色没有激活状态的bug | [438d448](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/438d448) + - | 切换日历时查询小红点 | [7091789](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/7091789) + - | 任务开始时间延迟插件 | [992a313](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/992a313) + - | 日常任务插件遍历时的key值修改 | [cd26285](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/cd26285) + - | 日常任务插件面板高度修改 | [249f9e4](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/249f9e4) + - | 日常任务html数据查验 | [880ce5c](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/880ce5c) + - | 日历无任务时添加小绿点,时间轴刻度无任务不显示时分 | [0f90868](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/0f90868) + - | 上下滚动时间轴 | [d533a01](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/d533a01) + - | 上下滑动加载定期任务 | [4090d89](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/4090d89) + - | 设置时间轴自动滚动到当前位置 | [a3474f8](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/a3474f8) + - | 时间轴插件 | [225d3cc](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/225d3cc) + - | 时间轴骨架屏修改 | [ca78d02](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/ca78d02) + - | 时间轴滚动位置修改 | [551da63](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/551da63) + - | 时间轴上下滚动数据加载bug修改 | [e82ede4](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/e82ede4) + - | 时间轴上下滑动 | [4d0ae46](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/4d0ae46) + - | 时间轴无任务时时间刻度加载修改 | [4921672](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/4921672) + - | 收到消息修改任务状态 | [c378063](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/c378063) + - | 手动展开日常任务 | [0a4a622](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/0a4a622) + - | 提示信息显示bug及日常任务收缩问题 | [f2f06c5](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/f2f06c5) + - | 跳转详情页返回路径修改 | [c5e17c0](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/c5e17c0) + - | 下拉加载定期任务传参,时间格式化修改 | [0b95a0e](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/0b95a0e) + 项目列表排序 | 项目列表排序 | [402c563](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/402c563) + - | 项目列表排序修改 | [fd3c3ac](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/fd3c3ac) + - | 项目列表排序修改 | [59f4c21](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/59f4c21) + - | 修改报错 | [531c14d](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/531c14d) + - | 修改定期任务状态0和4时不加载圆圈 | [30e352f](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/30e352f) + - | 修改角色栏组件 | [a54c601](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/a54c601) + - | 修改接口路径 | [df6acf2](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/df6acf2) + - | 修改小红点传参 | [87b20fd](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/87b20fd) + - | 修改样式 | [f0ddc90](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/f0ddc90) + - | 修改main | [749ae9a](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/749ae9a) + - | api 存storage | [81032ba](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/81032ba) + ID1000343 | 解决向下预加载查询参数时间没+1颗粒度;以及滚动加载颗粒度写死的问题 | [940603a](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/940603a), closes [#ID1000343](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/issues/ID1000343) + plugin | 插件解析机制完善 | [0f5a27d](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/0f5a27d) + project title | 项目标题修改; 切换角色移除script | [5c20017](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/5c20017) + role | 切换角色的逻辑修正完善 | [4ae534f](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/4ae534f) + roles | 修复默认显示不是我的角色的问题 | [b69f94f](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/b69f94f) + task任务逻辑完善 | 减少初始global及regular的不必要请求 | [bd4bd38](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/bd4bd38) + - | title.vue根据页面栈显示返回按钮;标题文本超出显示... | [0cbacf4](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/0cbacf4) + + +### 📝 文档 +范围|描述|commitId +--|--|-- + - | README.md | [ab0eb05](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/ab0eb05) + + +### 🔧 测试 +范围|描述|commitId +--|--|-- + - | 禁用任务开始操作 | [b5425db](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/b5425db) + - | 添加测试,测试utils/time.js的computeDurationText | [e758010](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/e758010) + - | 暂时移除了jest浏览器配置 | [5088d01](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/5088d01) + + +### 🔨 代码重构 +范围|描述|commitId +--|--|-- + - | 界面样式调整 | [4367249](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/4367249) + - | 去掉tailwindcss | [4bed47e](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/4bed47e) + - | 任务状态重构 | [4693655](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/4693655) + - | 删除多余的技术验证界面 | [542ae5b](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/542ae5b) + - | 删除多余的weekmode store里的东西 | [0841fe0](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/0841fe0) + - | 下滑时间轴添加备注 | [4fd20e3](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/4fd20e3) + - | 修改utils/upload 兼容小程序选择客户端文件上传WBS | [8f49129](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/8f49129) + - | 重构store分层 | [5f6fff8](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/5f6fff8) + calendar | 日历细节调整 | [1a8d6bf](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/1a8d6bf) + - | project 代码健壮性完善 | [a3202c5](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/a3202c5) + store/home | 删除store/home | [db8a3b4](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/db8a3b4) + task beginTime | 格式化任务开始时间 | [fbc0301](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/fbc0301) + template | eslint prettier sass uview tailwindcss | [9c966a1](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/9c966a1) + tip | 任务状态显示及tip组件数据的重构 | [78a5750](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/78a5750) + tips | 修改任务状态方法重构 | [b57d3ac](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/b57d3ac) + title.vue | 移除测试的repeat; 样式细节调整 | [c32d2bd](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/c32d2bd) + + +### 🚀 性能优化 +范围|描述|commitId +--|--|-- + - | 1.时间轴筛选相同的时间替换数据 2.整理代码 | [e082ccb](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/e082ccb) + - | 测试接口 | [215e074](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/215e074) + - | 插件查询及展示 | [4dba770](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/4dba770) + - | 角色栏文字颜色修改 | [215c6b3](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/215c6b3) + - | 解决警告 | [c932b09](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/c932b09) + - | 日历的更改 | [7353ac8](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/7353ac8) + - | 数据存储,避免重复调用接口 | [d22308a](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/d22308a) + - | 提交本地代码 | [e0cf2ed](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/e0cf2ed) + - | 小红点api缓存修改 | [e992343](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/e992343) + - | 修改代码格式 | [14123d7](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/14123d7) + - | 修改定期任务骨架屏高度 | [909a734](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/909a734) + - | 整理代码 | [7a55315](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/7a55315) + - | 组件文件夹新建 | [22bfe7b](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/22bfe7b) + - | 组件文件夹新建 | [17bb8c9](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/17bb8c9) + - | 组件文件夹新建 | [1421504](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/1421504) + + +### chore +范围|描述|commitId +--|--|-- + - | 删除多余的构建的命令 | [3f4eb2f](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/3f4eb2f) + - | 添加mp-weixin的构建命令 | [3776a67](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/3776a67) + 信息配置 | 配置eslint等配置 | [7421443](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/7421443) + - | 修复不能build的问题 | [0b7b91e](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/0b7b91e) + - | api 封装 | [8dcb8a2](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/8dcb8a2) + - | dart-sass替换node-sass;删除多余的uni平台包 | [519f28b](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/519f28b) + - | env host修改 | [a79a4a5](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/a79a4a5) + - | merge globals | [b0957cc](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/b0957cc) + - | merge wrr | [5ccc7a5](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/5ccc7a5) + - | mock | [51c24a5](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/51c24a5) + package manifest | 去掉了摇树 | [f7c1dd4](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/f7c1dd4) + pwa 小程序 | 移除了pwa,alloyFinger添加平台判断 | [875fab4](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/875fab4) + - | uview-ui | [a9ea34b](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/a9ea34b) + v3.0.1 | tall api 地址从1.0改成了3.0 | [db5afd5](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/db5afd5) + + +范围|描述|commitId +--|--|-- + - | style:index | [978f272](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/978f272) + - | !2 基础模板v1.1.0 | [f5e61dd](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/f5e61dd) + - | init | [c0f1deb](https://dd.tall.wiki/gitea/jiawei/tall-qcp2.0/commits/c0f1deb) + diff --git a/README.md b/README.md new file mode 100644 index 0000000..4b64710 --- /dev/null +++ b/README.md @@ -0,0 +1,101 @@ +# tall-mui-cli + +## 发布注意事项 + +环境变量里的`VUE_APP_VERSION=v3.0.1` 如果project路径变了 或者版本升级了, 发行之前一定要跟着改 + +本项目, TALL程序主体框架升级, 或者服务端路径变化, 要修改`manifest.json` 下的 `h5.router.base` + +--- + +## 项目运行 + +### 安装依赖 +``` +yarn +``` + +### 本地环境运行 ++ h5 +``` +yarn dev:h5 +``` + +浏览器输入网址: +http://localhost:8080/tall/v3.0.1/#/?u=1217647686598135808&p=1420652719055839232 + - u: userId + - p: projectId + - r: roleId + - pn: projectName + - t: taskId + ++ 微信小程序 +``` +yarn dev:mp-weixin +``` + ++ app +``` +yarn dev:app-plus +``` + +### 生产环境构建 + ++ h5 +``` +yarn build:h5 +``` + ++ app +``` +yarn build:app-plus +``` + ++ 微信小程序 +``` +yarn build:mp-weixin +``` + +### Customize configuration +See [Configuration Reference](https://cli.vuejs.org/config/). + +## 代码提交 + ++ 项目设置了commit lint, commit信息验证;运行`yarn cz` 命令依次填写commit信息即可 ++ 以及pre-commit钩子执行eslint代码格式检测, 代码格式不符合规则无法提交 + +``` +yarn cz +``` + +## 技术栈 + +### UI及工具库 ++ uni-app的cli构建版本 ++ vuex vue官方状态管理库 ++ tailwindcss 公共样式库(注意这个版本不是最新版本, 最新版本安装后报错) ++ uview-ui uni-app组件库 ++ alloyfinger 移动端手势库 ++ dayjs 时间处理库 ++ pwa 处理缓存, 构建离线应用 + + +### 构建相关 ++ sass node-sass ++ prettier 自动格式化代码 ++ eslint 代码可是校验 ++ commitlint git commit信息校验 ++ husky lint-staged git钩子处理commit校验及eslint代码检测 ++ vue-cli-plugin-mock mock数据 + +## H5 indexedDB +### 设计概要 + +db挂载到全局的store上,store存放的数据: +```js +{ + db: null, // object + name: 'TALL_indexedDB', // string + version: 1, // number +} +``` diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 0000000..99108aa --- /dev/null +++ b/babel.config.js @@ -0,0 +1,57 @@ +const plugins = []; + +if (process.env.UNI_OPT_TREESHAKINGNG) { + plugins.push(require('@dcloudio/vue-cli-plugin-uni-optimize/packages/babel-plugin-uni-api/index.js')); +} + +if ( + (process.env.UNI_PLATFORM === 'app-plus' && process.env.UNI_USING_V8) || + (process.env.UNI_PLATFORM === 'h5' && process.env.UNI_H5_BROWSER === 'builtin') +) { + const path = require('path'); + + const isWin = /^win/.test(process.platform); + + const normalizePath = path => (isWin ? path.replace(/\\/g, '/') : path); + + const input = normalizePath(process.env.UNI_INPUT_DIR); + try { + plugins.push([ + require('@dcloudio/vue-cli-plugin-hbuilderx/packages/babel-plugin-console'), + { + file(file) { + file = normalizePath(file); + if (file.indexOf(input) === 0) { + return path.relative(input, file); + } + return false; + }, + }, + ]); + } catch (e) {} +} + +process.UNI_LIBRARIES = process.UNI_LIBRARIES || ['@dcloudio/uni-ui']; +process.UNI_LIBRARIES.forEach(libraryName => { + plugins.push([ + 'import', + { + libraryName: libraryName, + customName: name => { + return `${libraryName}/lib/${name}/${name}`; + }, + }, + ]); +}); +module.exports = { + presets: [ + [ + '@vue/app', + { + modules: 'commonjs', + useBuiltIns: process.env.UNI_PLATFORM === 'h5' ? 'usage' : 'entry', + }, + ], + ], + plugins, +}; diff --git a/commitlint.config.js b/commitlint.config.js new file mode 100644 index 0000000..2086441 --- /dev/null +++ b/commitlint.config.js @@ -0,0 +1 @@ +module.exports = { extends: ['./node_modules/vue-cli-plugin-commitlint/lib/lint'] }; diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..1fe3e29 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,52 @@ +module.exports = { + globalTeardown: '@dcloudio/uni-automator/dist/teardown.js', + // testEnvironment: '@dcloudio/uni-automator/dist/environment.js', + testEnvironmentOptions: { + compile: true, + h5: { + // 为了节省测试时间,可以指定一个 H5 的 url 地址,若不指定,每次运行测试,会先 npm run dev:h5 + url: 'http://localhost:8080/tall/v3.0.1/#/h5', + options: { + headless: true, // 配置是否显示 puppeteer 测试窗口 + args: ['--no-sandbox'], + }, + }, + 'app-plus': { + // 需要安装 HBuilderX + android: { + executablePath: 'HBuilderX/plugins/launcher/base/android_base.apk', // apk 目录 + }, + ios: { + // uuid 必须配置,目前仅支持模拟器,可以(xcrun simctl list)查看要使用的模拟器 uuid + id: '', + executablePath: 'HBuilderX/plugins/launcher/base/Pandora_simulator.app', // ipa 目录 + }, + }, + 'mp-weixin': { + port: 9420, // 默认 9420 + account: '', // 测试账号 + args: '', // 指定开发者工具参数 + cwd: '', // 指定开发者工具工作目录 + launch: true, // 是否主动拉起开发者工具 + teardown: 'disconnect', // 可选值 "disconnect"|"close" 运行测试结束后,断开开发者工具或关闭开发者工具 + remote: false, // 是否真机自动化测试 + executablePath: '', // 开发者工具cli路径,默认会自动查找, windows: C:/Program Files (x86)/Tencent/微信web开发者工具/cli.bat", mac: /Applications/wechatwebdevtools.app/Contents/MacOS/cli + }, + 'mp-baidu': { + port: 9430, // 默认 9430 + args: '', // 指定开发者工具参数 + cwd: '', // 指定开发者工具工作目录 + launch: true, // 是否主动拉起开发者工具 + teardown: 'disconnect', // 可选值 "disconnect"|"close" 运行测试结束后,断开开发者工具或关闭开发者工具 + remote: false, // 是否真机自动化测试 + executablePath: '', // 开发者工具cli路径,默认会自动查找 + }, + }, + testTimeout: 15000, + reporters: ['default'], + watchPathIgnorePatterns: ['/node_modules/', '/dist/', '/.git/'], + moduleFileExtensions: ['js', 'json'], + rootDir: __dirname, + testMatch: ['/src/test/**/*test.[jt]s?(x)'], // 测试文件目录 + testPathIgnorePatterns: ['/node_modules/'], +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..e337545 --- /dev/null +++ b/package.json @@ -0,0 +1,114 @@ +{ + "name": "TALL", + "version": "0.1.0", + "private": true, + "scripts": { + "serve": "npm run dev:h5", + "build": "npm run build:h5", + "lint": "vue-cli-service lint", + "fix": "vue-cli-service lint --fix", + "test": "npm run test:h5", + "dev:h5": "cross-env NODE_ENV=development UNI_PLATFORM=h5 vue-cli-service uni-serve --mode development", + "dev:h5-pro": "cross-env NODE_ENV=development UNI_PLATFORM=h5 vue-cli-service uni-serve --mode production", + "build:h5-test": "cross-env NODE_ENV=production UNI_PLATFORM=h5 vue-cli-service uni-build --mode development", + "build:h5": "cross-env NODE_ENV=production UNI_PLATFORM=h5 vue-cli-service uni-build --mode production", + "build:app-plus": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build --mode production", + "build:mp-weixin": "cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build --mode production", + "cz": "npm run log && git add . && git cz", + "dev:app-plus": "cross-env NODE_ENV=development UNI_PLATFORM=app-plus vue-cli-service uni-build --watch", + "dev:custom": "cross-env NODE_ENV=development uniapp-cli custom", + "dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch", + "info": "node node_modules/@dcloudio/vue-cli-plugin-uni/commands/info.js", + "log": "conventional-changelog --config ./node_modules/vue-cli-plugin-commitlint/lib/log -i CHANGELOG.md -s -r 0", + "test:android": "cross-env UNI_PLATFORM=app-plus UNI_OS_NAME=android jest -i", + "test:h5": "cross-env UNI_PLATFORM=h5 jest -i", + "test:ios": "cross-env UNI_PLATFORM=app-plus UNI_OS_NAME=ios jest -i", + "test:mp-weixin": "cross-env UNI_PLATFORM=mp-weixin jest -i" + }, + "dependencies": { + "@dcloudio/uni-h5": "^2.0.0-32220210818002", + "@dcloudio/uni-helper-json": "*", + "@dcloudio/uni-i18n": "^2.0.0-32220210818002", + "@dcloudio/uni-mp-vue": "^2.0.0-32220210818002", + "@dcloudio/uni-mp-weixin": "^2.0.0-32220210818002", + "@dcloudio/uni-stat": "^2.0.0-32220210818002", + "@vue/shared": "^3.2.6", + "dayjs": "^1.10.6", + "flyio": "^0.6.2", + "lodash": "^4.17.21", + "regenerator-runtime": "^0.12.1", + "uview-ui": "^1.8.5", + "vue": "^2.6.11", + "vuex": "^3.2.0" + }, + "devDependencies": { + "@babel/runtime": "~7.12.0", + "@dcloudio/types": "^2.5.1", + "@dcloudio/uni-automator": "^2.0.0-32220210818002", + "@dcloudio/uni-cli-shared": "^2.0.0-32220210818002", + "@dcloudio/uni-migration": "^2.0.0-32220210818002", + "@dcloudio/uni-template-compiler": "^2.0.0-32220210818002", + "@dcloudio/vue-cli-plugin-hbuilderx": "^2.0.0-32220210818002", + "@dcloudio/vue-cli-plugin-uni": "^2.0.0-32220210818002", + "@dcloudio/vue-cli-plugin-uni-optimize": "^2.0.0-32220210818002", + "@dcloudio/webpack-uni-mp-loader": "^2.0.0-32220210818002", + "@dcloudio/webpack-uni-pages-loader": "^2.0.0-32220210818002", + "@vue/cli-plugin-babel": "~4.5.0", + "@vue/cli-plugin-eslint": "~4.5.0", + "@vue/cli-plugin-vuex": "~4.5.0", + "@vue/cli-service": "~4.5.0", + "@vue/eslint-config-prettier": "^6.0.0", + "autoprefixer": "^9.8.6", + "babel-eslint": "^10.1.0", + "babel-plugin-import": "^1.11.0", + "commitizen": "^4.0.3", + "commitlint": "^8.2.0", + "compression-webpack-plugin": "^5.0.2", + "conventional-changelog-cli": "^2.0.28", + "core-js": "^3.16.3", + "cross-env": "^7.0.3", + "eslint": "^6.7.2", + "eslint-plugin-prettier": "^3.4.1", + "eslint-plugin-vue": "^6.2.2", + "husky": "^3.0.9", + "jest": "^25.4.0", + "lint-staged": "^11.1.2", + "mini-types": "*", + "miniprogram-api-typings": "^3.4.3", + "postcss": "^7.0.36", + "postcss-class-rename": "^1.0.1", + "postcss-comment": "^2.0.0", + "prettier": "^2.2.1", + "puppeteer": "^10.2.0", + "right-pad": "^1.0.1", + "sass": "^1.38.2", + "sass-loader": "^8.0.2", + "vue-cli-plugin-commitlint": "~1.0.12", + "vue-template-compiler": "^2.6.11" + }, + "browserslist": [ + "Android >= 4", + "ios >= 8" + ], + "config": { + "commitizen": { + "path": "./node_modules/vue-cli-plugin-commitlint/lib/cz" + } + }, + "husky": { + "hooks": { + "commit-msg": "commitlint -E HUSKY_GIT_PARAMS", + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "src/**/*.{js,json,css,vue}": [ + "eslint --fix", + "git add" + ], + "*.js": "eslint --cache --fix" + }, + "uni-app": { + "scripts": {} + } +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..f46b6a1 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,21 @@ +const path = require('path'); + +module.exports = { + parser: require('postcss-comment'), + plugins: [ + require('postcss-import')({ + resolve(id, basedir, importOptions) { + if (id.startsWith('~@/')) { + return path.resolve(process.env.UNI_INPUT_DIR, id.substr(3)); + } else if (id.startsWith('@/')) { + return path.resolve(process.env.UNI_INPUT_DIR, id.substr(2)); + } else if (id.startsWith('/') && !id.startsWith('//')) { + return path.resolve(process.env.UNI_INPUT_DIR, id.substr(1)); + } + return id; + }, + }), + require('autoprefixer')({ remove: process.env.UNI_PLATFORM !== 'h5' }), + require('@dcloudio/vue-cli-plugin-uni/packages/postcss'), + ], +}; diff --git a/public/img/icons/android-chrome-192x192.png b/public/img/icons/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..b02aa64d97167ad649e496908b35f14c603d9249 GIT binary patch literal 9416 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 literal 0 HcmV?d00001 diff --git a/public/img/icons/apple-touch-icon-120x120.png b/public/img/icons/apple-touch-icon-120x120.png new file mode 100644 index 0000000000000000000000000000000000000000..1427cf62752646ad7217df0a61aa01fdef7475d1 GIT binary patch literal 3369 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 ROru=^AazZ3N)e9H{|11FNXq~K literal 0 HcmV?d00001 diff --git a/public/img/icons/apple-touch-icon-152x152.png b/public/img/icons/apple-touch-icon-152x152.png new file mode 100644 index 0000000000000000000000000000000000000000..f24d454a2ecb8851bb893192b64ee09386d30e24 GIT binary patch literal 4046 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 cK^5JQ0?3d{m_4Kdj*!1;003@kYpI!lw*K!+ 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�MrHbYR_buu=L>f*wO=Er8~{qfkYT+HoHag8)VqJoC-#@ zNT})4xRE%sP-B9?xmL5!2Y8VLa?yj@Y@r1C)6o~9GF9nWG!SI2VJ$>ejtUE%Qv&r_ zYLgZ0h3iIrw7{TyurC(g^$XT%PP5`FB3aFpP&fM-8!J#3I_ujG?;7(Xv5ni%BjYP4 z^+oydy=)_&bdxYJx`X%G5PFkUB%3h6RiOs^F?#ojsB%DbfhqzGhuv4)S1%vw@PDyE z3xWF{Y^0>+=Wg! z{>z@$rD6ej*V- z^$zKIOWOfdN4~7@ndhru01+3cxwD&_Muyja({*O;-5VnF(e$WDALNStE{1{F#ts+VR{o zSlQ*@U=Du8fgKW$lU~)O)b6FS?H1SSnKVIC=DOvbo8IUvM zVf+U4YxG%qLGd%ew7Jp8>@U`ew+A#Q=2oJHNH@_f!WadS20$KZEZ+BHAvU@FB zzRCYN5r+Z#g`C^hrH$yW7ABstwjvMM*CHGzY41bbo2zy$6E8DAOPn zUnHG?e7?u7pQ}Kqbu1jEd+=mcGea4aL6V4g(m*b7x}z|ijsjb3e|tf-3&^JK{=sWz z8sqIu9jy)#J}n}cXqtXmkb-NDVPcAKn=G9uX42zYvufu_OCr>xJ=oTNp8WA5wEqvM z{r~m8;7_C>U68iRr@|rd7UYhON#(-S_+Uf>s)hhPU{{exlxc&eD literal 0 HcmV?d00001 diff --git a/public/img/icons/apple-touch-icon-60x60.png b/public/img/icons/apple-touch-icon-60x60.png new file mode 100644 index 0000000000000000000000000000000000000000..cf10a5602e653bb126332934e2b7f34081c19a01 GIT binary patch literal 1491 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

aZW9cb|x>1jZDoAu$NpeWiVk@{x{! zmmBmDgx|qNN?LyIrl9$qmj{KjZ8zpa=4edK3FuFS$KFl}bWPoO*Ax#Z1c2#3JAN(O zYhi>`%H9fSnLkAq|5vs>+?U*bdfMc6TmDu+QqnN9xgfZsG25($^;v7U1nBl9Q^o*i z)&?UaYZ=~7XZa75xPKB1s~MB1m<*dN08pqiy*q!)_Kc|;EZs3&nNdMQ5#LFu+J z?*($vO)$hkMOVc16f-ep;K@_~&Y6t?0t9I0(lBkZBfic|u)3pK$Xv=A@jUQnB2sC` zbI)L9m;VNkWOao}2c3b4_u4+bg zuf-@d1$?asdD1~mORQ02#!&1Xm#41*xz}wETNqKb;kueQ*~OpcAXTpJFYUYcKoA&Z z8Ke=2Vh~cu_uTb&6AH75L!k8zo~&wRsDLs^3YkD2!~;%u6sFrzV2A5(FQ|3}+0-K- zWX)W2yq%?^)iKhyMGPB5*DnWBaLqAHLJ47;r5nvkeq3u_?J{Xaf_}6I+xpLwKS7NC z|KYU%zup)8i85jc)^Yt*I0W8;+zHUI3V7@o;3DUYasdq>DFK%im4J)F?;|B-<=}8R z>HESGa5)KyCnGII|E+YX&h4Y+xCRvyX@oGhhG4 j58+{W$RJv~NLLKlV4)8v^7hU(R-4l(}$teLl` literal 0 HcmV?d00001 diff --git a/public/img/icons/favicon-16x16.png b/public/img/icons/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..42af00963d81b8e39a30435c60ac482d1f8756e0 GIT binary patch literal 799 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>WRE8{w#)hawXn|-Xp4{E;v!=;4B^%-x&;Cm1 zP>^*#n_J!T^1SBMI!C4h-R53dN8`?ylD}d{L%(vZvUKT)~-CgWFQy3lt zIqW5#zOL*K8HL%o&D;R|TePl5?VWhq^wrj^qed%lKKkpp-FogeyEi+p zE?K8rW7E1fuEJ{5jaaAp0~aIt+keS?T)@vXM=*X}V#VGMCm1~v-+0wr{w3CJ-R8wG zS@XVpzqP-5Mf0H?y-zh=XVL>S6E;rKnDmrMQlmoKbK9p$evXN`oe{6g>lvi)-+#c) zb+Al&$zRqtWk1@VTt6MPmq9d7^!kmXZn8k{sFt`!l%ynwlArU1(iRB6fMfqu& zIjIUIl?AB^nFS@u3=9=>9)IHDC=AokIOTu(jOWuJ24-b$y<~1-Wnu5hBFw@HE)6D! wQ<#-EhbWxBaplC3Ge=~Ou%B-5Sm33{@Jd{;RG<|Mp00i_>zopr0DGh}-~a#s literal 0 HcmV?d00001 diff --git a/public/img/icons/favicon-32x32.png b/public/img/icons/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..46ca04dee251a4fa85a2891a145fbe20cc619d96 GIT binary patch literal 1271 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 + + diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..37ae61b --- /dev/null +++ b/public/index.html @@ -0,0 +1,28 @@ + + + + + + + + <%= htmlWebpackPlugin.options.title %> + + + + + + + +

+ + + + diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..eb05362 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..ddfcacd --- /dev/null +++ b/src/App.vue @@ -0,0 +1,159 @@ + + + diff --git a/src/apis/carbasics.js b/src/apis/carbasics.js new file mode 100644 index 0000000..7a395c0 --- /dev/null +++ b/src/apis/carbasics.js @@ -0,0 +1,67 @@ +const apiUrl = process.env.VUE_APP_API_URL; +export const carbasics = `${apiUrl}/carbasics/v4.0`; +const patient = `${carbasics}/patient`; // 患者相关接口 +const firstAid = `${carbasics}/firstAid`; // 急救数据相关接口 + +// 获取急救/出院数据列表 +export const querySelf = { + async index(params) { + let timer = null; + timer = setTimeout(() => { + uni.$t.ui.showLoading('正在努力查询...'); + timer = null; + }, 10); + try { + const data = await uni.$u.http.post(`${patient}/querySelf`, params); + clearTimeout(timer); + return data; + } catch (error) { + clearTimeout(timer); + throw new Error(error); + } + }, +}; + +/** + * 批量提交急救信息 + * @param {object} param 提交的参数 + * 提交信息 + * @param { Array } codeAndAnswerList code和答案 + * @param { String } firstAidId 项目id + * @param { Number } userType 提交人类型(0平车 1人) + */ +export const setRecord = { + async index(params) { + try { + const param = { + ...params, + userType: 1, + }; + const data = await uni.$u.http.post(`${patient}/aidRecord`, { param }); + return data; + } catch (error) { + uni.$t.ui.showToast(error); + throw new Error(error); + } + }, +}; + +const install = (Vue, vm) => { + vm.$u.api = { ...vm.$u.api } || {}; + // 存储患者病况信息 + vm.$u.api.setRecord = params => setRecord.index(params); + // 获取急救/出院数据列表 + vm.$u.api.querySelf = params => querySelf.index(params); + // 患者加入急救 + vm.$u.api.joinAid = params => vm.$u.post(`${firstAid}/join`, params); + // 患者退出急救 + vm.$u.api.quitAid = params => vm.$u.post(`${firstAid}/quit`, params); + // 删除演示的急救患者数据 + vm.$u.api.delDemo = params => vm.$u.post(`${firstAid}/delDemo`, params); + // 删除演示的急救患者数据 + vm.$u.api.savePatient = params => vm.$u.post(`${patient}/savePatient`, params); + // 上传身份证图像识别 + vm.$u.api.identifyWords = `${carbasics}/ocr/identifyWords`; +}; + +export default { install }; diff --git a/src/apis/project.js b/src/apis/project.js new file mode 100644 index 0000000..f5b9910 --- /dev/null +++ b/src/apis/project.js @@ -0,0 +1,19 @@ +const install = (Vue, vm) => { + vm.$u.api = { ...vm.$u.api } || {}; + //根据id获取项目信息 + vm.$u.api.findProjectById = param => vm.$u.post(`${uni.$t.domain}/project/findProjectById`, param); + + //创建分享连接 + vm.$u.api.createShare = param => vm.$u.post(`${uni.$t.domain}/share/create`, param); + + //点击分享连接 + vm.$u.api.clickShare = param => vm.$u.post(`${uni.$t.domain}/share/click`, param); + + //查询医院是否填写了调查问卷 + vm.$u.api.queryNotWrite = param => vm.$u.post(`${uni.$t.domain}/questionnaire/queryNotWrite`, param); + + // 根据项目id查询当前项目是不是 医院体验项目 + vm.$u.api.getByProject = param => vm.$u.post(`${uni.$t.domain}/organization/getByProject`, param); +}; + +export default { install }; diff --git a/src/apis/role.js b/src/apis/role.js new file mode 100644 index 0000000..7d2454c --- /dev/null +++ b/src/apis/role.js @@ -0,0 +1,49 @@ +const url = process.env.VUE_APP_API_URL; +// 查询首页按钮的名称及跳转 +export const queryMustShow = { + async index(params) { + try { + const data = await uni.$u.http.post(`${url}/carbasics/v4.0/role/queryMustShow`, params); + return data; + } catch (error) { + throw new Error(error); + } + }, +}; + +export const queryLastRoleChoose = { + async index(params) { + try { + const data = await uni.$u.http.post(`${url}/carbasics/v4.0/role/queryLastRoleChoose`, params); + return data; + } catch (error) { + throw new Error(error); + } + }, +}; + +export const saveRoleRecord = { + async index(params) { + try { + await uni.$u.http.post(`${url}/carbasics/v4.0/role/saveRoleRecord`, params); + } catch (error) { + throw new Error(error); + } + }, +}; + +const install = (Vue, vm) => { + vm.$u.api = { ...vm.$u.api } || {}; + // 根据项目id查找所有体验角色 + vm.$u.api.queryMustShow = params => queryMustShow.index(params); + // 根据项目id查找上次退出项目时所选择的角色 + vm.$u.api.queryLastRoleChoose = params => queryLastRoleChoose.index(params); + // 保存当前用户在当前项目最后一次选择的角色 + vm.$u.api.saveRoleRecord = params => saveRoleRecord.index(params); + // 根据项目id查找角色 + vm.$u.api.findShowRole = param => vm.$u.post(`${uni.$t.domain}/role/show`, param); + // 根据项目id查找所有成员 + vm.$u.api.queryChecker = param => vm.$u.post(`${uni.$t.domain}/deliver/queryChecker`, param); +}; + +export default { install }; diff --git a/src/apis/tall.js b/src/apis/tall.js new file mode 100644 index 0000000..8681a17 --- /dev/null +++ b/src/apis/tall.js @@ -0,0 +1,109 @@ +const apiUrl = process.env.VUE_APP_API_URL; +export const tall = `${apiUrl}/tall3/v3.0`; +export const carbasics = `${apiUrl}/carbasics/v4.0`; + +import { mp } from '@/config/user.js'; + +// 登录 +export const login = { + async index(params) { + try { + /* #ifdef MP-WEIXIN */ + params = await mp(); + /* #endif */ + const data = await uni.$u.http.post(`${tall}/users/signin`, params); + return data; + } catch (error) { + throw new Error(error); + } + }, +}; + +// 获取手机号 +export const bindPhone = { + async index(params) { + try { + /* #endif */ + const data = await uni.$u.http.post(`${tall}/users/bindingNoCode`, params); + return data; + } catch (error) { + throw new Error(error); + } + }, +}; + +// 绑定手机号(合并或者替换) +export const bindNowPhone = { + async index(params) { + try { + /* #endif */ + const data = await uni.$u.http.post(`${tall}/users/merge`, params); + return data; + } catch (error) { + throw new Error(error); + } + }, +}; + +// 查询首页按钮的名称及跳转 +export const getQueryButton = { + async index(params) { + try { + /* #endif */ + const data = await uni.$u.http.post(`${carbasics}/questionnaire/queryButton`, params); + return data; + } catch (error) { + return null; + } + }, +}; + +// 查询当前用户是否展示宣传页 +export const queryIsShow = { + async index(params) { + try { + /* #endif */ + const data = await uni.$u.http.post(`${carbasics}/questionnaire/queryIsShow`, params); + return data; + } catch (error) { + throw new Error(error); + } + }, +}; + +const install = (Vue, vm) => { + vm.$u.api = { ...vm.$u.api } || {}; + // 登录 + vm.$u.api.signin = params => login.index(params); + // 绑定手机号无需验证码 + vm.$u.api.bindPhone = params => bindPhone.index(params); + // 手机号已被注册,是否合并 + vm.$u.api.bindNowPhone = params => bindNowPhone.index(params); + // 获取图片验证码 + vm.$u.api.getImageCode = () => vm.$u.get(`${tall}/users/code`); + // 获取短信验证码 + vm.$u.api.getSmsCode = params => vm.$u.get(`${tall}/users/smscode`, params); + // 根据userId获取token + vm.$u.api.getToken = userId => vm.$u.get(`${tall}/users/userId`, { userId }); + // 绑定手机号 + vm.$u.api.phoneBind = (phone, smsCode) => vm.$u.http.post(`${tall}/users/binding`, { phone, smsCode }); + // 修改用户信息 + vm.$u.api.updateUserInfo = params => vm.$u.http.post(`${tall}/users/userInfo`, params); + + // 获取项目列表 + vm.$u.api.getProjects = (startTime, endTime) => vm.$u.post(`${tall}/project/query`, { startTime, endTime }); + // 查询首页的按钮展示及跳转 + vm.$u.api.getQueryButton = params => getQueryButton.index(params); + // 查询当前用户是否展示宣传页按钮 + vm.$u.api.queryIsShow = params => queryIsShow.index(params); + // 查询日历是否有小红点 + vm.$u.api.findRedPoint = (startTime, endTime) => vm.$u.post(`${tall}/project/day`, { startTime, endTime }); + // 设置项目顺序 + vm.$u.api.setProjectSort = params => vm.$u.post(`${tall}/project/setProjectSort`, params); + // 设置项目父子结构 + vm.$u.api.setProjectRelation = params => vm.$u.post(`${tall}/project/setProjectRelation`, params); + // 删除某个项目 + vm.$u.api.delProject = projectId => vm.$u.post(`${tall}/project/deleteProject`, { projectId }); +}; + +export default { install }; diff --git a/src/apis/task.js b/src/apis/task.js new file mode 100644 index 0000000..b11d0a3 --- /dev/null +++ b/src/apis/task.js @@ -0,0 +1,17 @@ +const install = (Vue, vm) => { + vm.$u.api = { ...vm.$u.api } || {}; + vm.$u.api.getGlobal = param => vm.$u.post(`${uni.$t.domain}/task/global`, param); + vm.$u.api.getPermanent = param => vm.$u.post(`${uni.$t.domain}/task/permanent`, param); + //根据时间基准点和角色查找定期任务 + vm.$u.api.getRegularTask = param => vm.$u.post(`${uni.$t.domain}/task/regular`, param); + //修改任务状态 + vm.$u.api.updateTaskType = param => vm.$u.post(`${uni.$t.domain}/task/type`, param); + //新建任务 + vm.$u.api.saveTask = param => vm.$u.post(`${uni.$t.domain}/task/save`, param); + //克隆任务 + vm.$u.api.cloneTask = param => vm.$u.post(`${uni.$t.domain}/task/clone`, param); + //模糊查询 查找项目下的任务 + vm.$u.api.queryTaskOfProject = param => vm.$u.post(`${uni.$t.domain}/task/queryTaskOfProject`, param); +}; + +export default { install }; diff --git a/src/apis/wbs.js b/src/apis/wbs.js new file mode 100644 index 0000000..e9a13a5 --- /dev/null +++ b/src/apis/wbs.js @@ -0,0 +1,7 @@ +const install = (Vue, vm) => { + vm.$u.api = { ...vm.$u.api } || {}; + // 导入wbs + vm.$u.api.import = formData => vm.$t.chooseAndUpload(`${uni.$t.domain}/wbs`, formData); +}; + +export default { install }; diff --git a/src/common/styles/app.scss b/src/common/styles/app.scss new file mode 100644 index 0000000..4305d6f --- /dev/null +++ b/src/common/styles/app.scss @@ -0,0 +1,7 @@ +.min-0 { + min-width: 0; +} + +.flex-shrink-0 { + flex-shrink: 0; +} \ No newline at end of file diff --git a/src/common/styles/iconfont.css b/src/common/styles/iconfont.css new file mode 100644 index 0000000..69b157e --- /dev/null +++ b/src/common/styles/iconfont.css @@ -0,0 +1,257 @@ +@font-face { + font-family: 'custom-icon'; /* Project id 2470633 */ + src: url('data:application/x-font-woff2;charset=utf-8;base64,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') + format('woff2'); +} + +.custom-icon { + font-family: 'custom-icon' !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.custom-icon-xuanzhong2:before { + content: '\e63a'; +} + +.custom-icon-xuanzhong21:before { + content: '\e714'; +} + +.custom-icon-shuaxin1:before { + content: '\e6a8'; +} + +.custom-icon-xuanxiang:before { + content: '\e611'; +} + +.custom-icon-cluster:before { + content: '\e7d7'; +} + +.custom-icon-moneycollect:before { + content: '\e7cd'; +} + +.custom-icon-C-shangchuan:before { + content: '\e6c5'; +} + +.custom-icon-C-integral:before { + content: '\e6f9'; +} + +.custom-icon-calendar1:before { + content: '\e746'; +} + +.custom-icon-C-suggest:before { + content: '\e767'; +} + +.custom-icon-usercenter:before { + content: '\e773'; +} + +.custom-icon-play-circle:before { + content: '\e782'; +} + +.custom-icon-message:before { + content: '\e78a'; +} + +.custom-icon-plus-circle:before { + content: '\e781'; +} + +.custom-icon-smile:before { + content: '\e783'; +} + +.custom-icon-C-yuyin:before { + content: '\e79a'; +} + +.custom-icon-doubleleft:before { + content: '\e7ef'; +} + +.custom-icon-doubleright:before { + content: '\e7f0'; +} + +.custom-icon-ellipsis:before { + content: '\e7fe'; +} + +.custom-icon-C-L:before { + content: '\e601'; +} + +.custom-icon-C-kaiguanguan:before { + content: '\e66c'; +} + +.custom-icon-C-kaiguanguan1:before { + content: '\e60c'; +} + +.custom-icon-close-circle:before { + content: '\e77d'; +} + +.custom-icon-time-circle:before { + content: '\e784'; +} + +.custom-icon-warning-circle:before { + content: '\e785'; +} + +.custom-icon-sync:before { + content: '\e786'; +} + +.custom-icon-reloadtime:before { + content: '\e789'; +} + +.custom-icon-edit-square:before { + content: '\e791'; +} + +.custom-icon-export:before { + content: '\e792'; +} + +.custom-icon-Import:before { + content: '\e793'; +} + +.custom-icon-check-square:before { + content: '\e7a8'; +} + +.custom-icon-border:before { + content: '\e7a9'; +} + +.custom-icon-user:before { + content: '\e7ae'; +} + +.custom-icon-delete:before { + content: '\e7c3'; +} + +.custom-icon-home:before { + content: '\e7c6'; +} + +.custom-icon-accountbook:before { + content: '\e7d3'; +} + +.custom-icon-carryout:before { + content: '\e7d4'; +} + +.custom-icon-calendar:before { + content: '\e7d5'; +} + +.custom-icon-cloud-upload:before { + content: '\e7d9'; +} + +.custom-icon-attachment:before { + content: '\e7e1'; +} + +.custom-icon-edit:before { + content: '\e7e2'; +} + +.custom-icon-tag:before { + content: '\e7e4'; +} + +.custom-icon-right:before { + content: '\e7eb'; +} + +.custom-icon-left:before { + content: '\e7ec'; +} + +.custom-icon-up:before { + content: '\e7ed'; +} + +.custom-icon-down:before { + content: '\e7ee'; +} + +.custom-icon-check:before { + content: '\e7fc'; +} + +.custom-icon-close:before { + content: '\e7fd'; +} + +.custom-icon-apartment:before { + content: '\e897'; +} + +.custom-icon-rili1:before { + content: '\e617'; +} + +.custom-icon-caret-right:before { + content: '\e8ec'; +} + +.custom-icon-search:before { + content: '\e8ef'; +} + +.custom-icon-C-naozhong_huabanfuben:before { + content: '\e655'; +} + +.custom-icon-plus:before { + content: '\e8fe'; +} + +.custom-icon-C-filter:before { + content: '\e667'; +} + +.custom-icon-C-tongji1:before { + content: '\e69b'; +} + +.custom-icon-genderless:before { + content: '\e888'; +} + +.custom-icon-C-zujian251:before { + content: '\e61e'; +} + +.custom-icon-user-avatar:before { + content: '\e61d'; +} + +.custom-icon-C-bxl-redux:before { + content: '\e608'; +} + +.custom-icon-shoucangfuben:before { + content: '\e600'; +} diff --git a/src/common/styles/iconfont.scss b/src/common/styles/iconfont.scss new file mode 100644 index 0000000..69b157e --- /dev/null +++ b/src/common/styles/iconfont.scss @@ -0,0 +1,257 @@ +@font-face { + font-family: 'custom-icon'; /* Project id 2470633 */ + src: url('data:application/x-font-woff2;charset=utf-8;base64,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') + format('woff2'); +} + +.custom-icon { + font-family: 'custom-icon' !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.custom-icon-xuanzhong2:before { + content: '\e63a'; +} + +.custom-icon-xuanzhong21:before { + content: '\e714'; +} + +.custom-icon-shuaxin1:before { + content: '\e6a8'; +} + +.custom-icon-xuanxiang:before { + content: '\e611'; +} + +.custom-icon-cluster:before { + content: '\e7d7'; +} + +.custom-icon-moneycollect:before { + content: '\e7cd'; +} + +.custom-icon-C-shangchuan:before { + content: '\e6c5'; +} + +.custom-icon-C-integral:before { + content: '\e6f9'; +} + +.custom-icon-calendar1:before { + content: '\e746'; +} + +.custom-icon-C-suggest:before { + content: '\e767'; +} + +.custom-icon-usercenter:before { + content: '\e773'; +} + +.custom-icon-play-circle:before { + content: '\e782'; +} + +.custom-icon-message:before { + content: '\e78a'; +} + +.custom-icon-plus-circle:before { + content: '\e781'; +} + +.custom-icon-smile:before { + content: '\e783'; +} + +.custom-icon-C-yuyin:before { + content: '\e79a'; +} + +.custom-icon-doubleleft:before { + content: '\e7ef'; +} + +.custom-icon-doubleright:before { + content: '\e7f0'; +} + +.custom-icon-ellipsis:before { + content: '\e7fe'; +} + +.custom-icon-C-L:before { + content: '\e601'; +} + +.custom-icon-C-kaiguanguan:before { + content: '\e66c'; +} + +.custom-icon-C-kaiguanguan1:before { + content: '\e60c'; +} + +.custom-icon-close-circle:before { + content: '\e77d'; +} + +.custom-icon-time-circle:before { + content: '\e784'; +} + +.custom-icon-warning-circle:before { + content: '\e785'; +} + +.custom-icon-sync:before { + content: '\e786'; +} + +.custom-icon-reloadtime:before { + content: '\e789'; +} + +.custom-icon-edit-square:before { + content: '\e791'; +} + +.custom-icon-export:before { + content: '\e792'; +} + +.custom-icon-Import:before { + content: '\e793'; +} + +.custom-icon-check-square:before { + content: '\e7a8'; +} + +.custom-icon-border:before { + content: '\e7a9'; +} + +.custom-icon-user:before { + content: '\e7ae'; +} + +.custom-icon-delete:before { + content: '\e7c3'; +} + +.custom-icon-home:before { + content: '\e7c6'; +} + +.custom-icon-accountbook:before { + content: '\e7d3'; +} + +.custom-icon-carryout:before { + content: '\e7d4'; +} + +.custom-icon-calendar:before { + content: '\e7d5'; +} + +.custom-icon-cloud-upload:before { + content: '\e7d9'; +} + +.custom-icon-attachment:before { + content: '\e7e1'; +} + +.custom-icon-edit:before { + content: '\e7e2'; +} + +.custom-icon-tag:before { + content: '\e7e4'; +} + +.custom-icon-right:before { + content: '\e7eb'; +} + +.custom-icon-left:before { + content: '\e7ec'; +} + +.custom-icon-up:before { + content: '\e7ed'; +} + +.custom-icon-down:before { + content: '\e7ee'; +} + +.custom-icon-check:before { + content: '\e7fc'; +} + +.custom-icon-close:before { + content: '\e7fd'; +} + +.custom-icon-apartment:before { + content: '\e897'; +} + +.custom-icon-rili1:before { + content: '\e617'; +} + +.custom-icon-caret-right:before { + content: '\e8ec'; +} + +.custom-icon-search:before { + content: '\e8ef'; +} + +.custom-icon-C-naozhong_huabanfuben:before { + content: '\e655'; +} + +.custom-icon-plus:before { + content: '\e8fe'; +} + +.custom-icon-C-filter:before { + content: '\e667'; +} + +.custom-icon-C-tongji1:before { + content: '\e69b'; +} + +.custom-icon-genderless:before { + content: '\e888'; +} + +.custom-icon-C-zujian251:before { + content: '\e61e'; +} + +.custom-icon-user-avatar:before { + content: '\e61d'; +} + +.custom-icon-C-bxl-redux:before { + content: '\e608'; +} + +.custom-icon-shoucangfuben:before { + content: '\e600'; +} diff --git a/src/common/styles/tailwind.scss b/src/common/styles/tailwind.scss new file mode 100644 index 0000000..de27983 --- /dev/null +++ b/src/common/styles/tailwind.scss @@ -0,0 +1,4509 @@ +.fixed { + position: fixed; +} + +.absolute { + position: absolute; +} + +.relative { + position: relative; +} + +.sticky { + position: sticky; +} + +.max-h-full { + max-height: 100%; +} + +.col-auto { + grid-column: auto; +} + +.col-span-1 { + grid-column: span 1 / span 1; +} + +.col-span-2 { + grid-column: span 2 / span 2; +} + +.col-span-3 { + grid-column: span 3 / span 3; +} + +.col-span-4 { + grid-column: span 4 / span 4; +} + +.col-span-5 { + grid-column: span 5 / span 5; +} + +.col-span-6 { + grid-column: span 6 / span 6; +} + +.col-span-7 { + grid-column: span 7 / span 7; +} + +.col-span-8 { + grid-column: span 8 / span 8; +} + +.col-span-9 { + grid-column: span 9 / span 9; +} + +.col-span-10 { + grid-column: span 10 / span 10; +} + +.col-span-11 { + grid-column: span 11 / span 11; +} + +.col-span-12 { + grid-column: span 12 / span 12; +} + +.col-span-full { + grid-column: 1 / -1; +} + +.col-start-1 { + grid-column-start: 1; +} + +.col-start-2 { + grid-column-start: 2; +} + +.col-start-3 { + grid-column-start: 3; +} + +.col-start-4 { + grid-column-start: 4; +} + +.col-start-5 { + grid-column-start: 5; +} + +.col-start-6 { + grid-column-start: 6; +} + +.col-start-7 { + grid-column-start: 7; +} + +.col-start-8 { + grid-column-start: 8; +} + +.col-start-9 { + grid-column-start: 9; +} + +.col-start-10 { + grid-column-start: 10; +} + +.col-start-11 { + grid-column-start: 11; +} + +.col-start-12 { + grid-column-start: 12; +} + +.col-start-13 { + grid-column-start: 13; +} + +.col-start-auto { + grid-column-start: auto; +} + +.col-end-1 { + grid-column-end: 1; +} + +.col-end-2 { + grid-column-end: 2; +} + +.col-end-3 { + grid-column-end: 3; +} + +.col-end-4 { + grid-column-end: 4; +} + +.col-end-5 { + grid-column-end: 5; +} + +.col-end-6 { + grid-column-end: 6; +} + +.col-end-7 { + grid-column-end: 7; +} + +.col-end-8 { + grid-column-end: 8; +} + +.col-end-9 { + grid-column-end: 9; +} + +.col-end-10 { + grid-column-end: 10; +} + +.col-end-11 { + grid-column-end: 11; +} + +.col-end-12 { + grid-column-end: 12; +} + +.col-end-13 { + grid-column-end: 13; +} + +.col-end-auto { + grid-column-end: auto; +} + +.row-auto { + grid-row: auto; +} + +.row-span-1 { + grid-row: span 1 / span 1; +} + +.row-span-2 { + grid-row: span 2 / span 2; +} + +.row-span-3 { + grid-row: span 3 / span 3; +} + +.row-span-4 { + grid-row: span 4 / span 4; +} + +.row-span-5 { + grid-row: span 5 / span 5; +} + +.row-span-6 { + grid-row: span 6 / span 6; +} + +.row-span-full { + grid-row: 1 / -1; +} + +.row-start-1 { + grid-row-start: 1; +} + +.row-start-2 { + grid-row-start: 2; +} + +.row-start-3 { + grid-row-start: 3; +} + +.row-start-4 { + grid-row-start: 4; +} + +.row-start-5 { + grid-row-start: 5; +} + +.row-start-6 { + grid-row-start: 6; +} + +.row-start-7 { + grid-row-start: 7; +} + +.row-start-auto { + grid-row-start: auto; +} + +.row-end-1 { + grid-row-end: 1; +} + +.row-end-2 { + grid-row-end: 2; +} + +.row-end-3 { + grid-row-end: 3; +} + +.row-end-4 { + grid-row-end: 4; +} + +.row-end-5 { + grid-row-end: 5; +} + +.row-end-6 { + grid-row-end: 6; +} + +.row-end-7 { + grid-row-end: 7; +} + +.row-end-auto { + grid-row-end: auto; +} + +.float-right { + float: right; +} + +.float-left { + float: left; +} + +.float-none { + float: none; +} + +.clear-left { + clear: left; +} + +.clear-right { + clear: right; +} + +.clear-both { + clear: both; +} + +.clear-none { + clear: none; +} + +.m-0 { + margin: 0px; +} + +.m-1 { + margin: 0.25rem; +} + +.m-2 { + margin: 0.5rem; +} + +.m-3 { + margin: 0.75rem; +} + +.m-4 { + margin: 1rem; +} + +.m-5 { + margin: 1.25rem; +} + +.m-6 { + margin: 1.5rem; +} + +.m-7 { + margin: 1.75rem; +} + +.m-8 { + margin: 2rem; +} + +.m-9 { + margin: 2.25rem; +} + +.m-10 { + margin: 2.5rem; +} + +.m-11 { + margin: 2.75rem; +} + +.m-12 { + margin: 3rem; +} + +.m-14 { + margin: 3.5rem; +} + +.m-16 { + margin: 4rem; +} + +.m-20 { + margin: 5rem; +} + +.m-24 { + margin: 6rem; +} + +.m-28 { + margin: 7rem; +} + +.m-32 { + margin: 8rem; +} + +.m-36 { + margin: 9rem; +} + +.m-40 { + margin: 10rem; +} + +.m-44 { + margin: 11rem; +} + +.m-48 { + margin: 12rem; +} + +.m-52 { + margin: 13rem; +} + +.m-56 { + margin: 14rem; +} + +.m-60 { + margin: 15rem; +} + +.m-64 { + margin: 16rem; +} + +.m-72 { + margin: 18rem; +} + +.m-80 { + margin: 20rem; +} + +.m-96 { + margin: 24rem; +} + +.m-auto { + margin: auto; +} + +.m-px { + margin: 1px; +} + +.-m-0 { + margin: 0px; +} + +.-m-1 { + margin: -0.25rem; +} + +.-m-2 { + margin: -0.5rem; +} + +.-m-3 { + margin: -0.75rem; +} + +.-m-4 { + margin: -1rem; +} + +.-m-5 { + margin: -1.25rem; +} + +.-m-6 { + margin: -1.5rem; +} + +.-m-7 { + margin: -1.75rem; +} + +.-m-8 { + margin: -2rem; +} + +.-m-9 { + margin: -2.25rem; +} + +.-m-10 { + margin: -2.5rem; +} + +.-m-11 { + margin: -2.75rem; +} + +.-m-12 { + margin: -3rem; +} + +.-m-14 { + margin: -3.5rem; +} + +.-m-16 { + margin: -4rem; +} + +.-m-20 { + margin: -5rem; +} + +.-m-24 { + margin: -6rem; +} + +.-m-28 { + margin: -7rem; +} + +.-m-32 { + margin: -8rem; +} + +.-m-36 { + margin: -9rem; +} + +.-m-40 { + margin: -10rem; +} + +.-m-44 { + margin: -11rem; +} + +.-m-48 { + margin: -12rem; +} + +.-m-52 { + margin: -13rem; +} + +.-m-56 { + margin: -14rem; +} + +.-m-60 { + margin: -15rem; +} + +.-m-64 { + margin: -16rem; +} + +.-m-72 { + margin: -18rem; +} + +.-m-80 { + margin: -20rem; +} + +.-m-96 { + margin: -24rem; +} + +.-m-px { + margin: -1px; +} + +.mx-0 { + margin-left: 0px; + margin-right: 0px; +} + +.mx-1 { + margin-left: 0.25rem; + margin-right: 0.25rem; +} + +.mx-2 { + margin-left: 0.5rem; + margin-right: 0.5rem; +} + +.mx-3 { + margin-left: 0.75rem; + margin-right: 0.75rem; +} + +.mx-4 { + margin-left: 1rem; + margin-right: 1rem; +} + +.mx-5 { + margin-left: 1.25rem; + margin-right: 1.25rem; +} + +.mx-6 { + margin-left: 1.5rem; + margin-right: 1.5rem; +} + +.mx-7 { + margin-left: 1.75rem; + margin-right: 1.75rem; +} + +.mx-8 { + margin-left: 2rem; + margin-right: 2rem; +} + +.mx-9 { + margin-left: 2.25rem; + margin-right: 2.25rem; +} + +.mx-10 { + margin-left: 2.5rem; + margin-right: 2.5rem; +} + +.mx-11 { + margin-left: 2.75rem; + margin-right: 2.75rem; +} + +.mx-12 { + margin-left: 3rem; + margin-right: 3rem; +} + +.mx-14 { + margin-left: 3.5rem; + margin-right: 3.5rem; +} + +.mx-16 { + margin-left: 4rem; + margin-right: 4rem; +} + +.mx-20 { + margin-left: 5rem; + margin-right: 5rem; +} + +.mx-24 { + margin-left: 6rem; + margin-right: 6rem; +} + +.mx-28 { + margin-left: 7rem; + margin-right: 7rem; +} + +.mx-32 { + margin-left: 8rem; + margin-right: 8rem; +} + +.mx-36 { + margin-left: 9rem; + margin-right: 9rem; +} + +.mx-40 { + margin-left: 10rem; + margin-right: 10rem; +} + +.mx-44 { + margin-left: 11rem; + margin-right: 11rem; +} + +.mx-48 { + margin-left: 12rem; + margin-right: 12rem; +} + +.mx-52 { + margin-left: 13rem; + margin-right: 13rem; +} + +.mx-56 { + margin-left: 14rem; + margin-right: 14rem; +} + +.mx-60 { + margin-left: 15rem; + margin-right: 15rem; +} + +.mx-64 { + margin-left: 16rem; + margin-right: 16rem; +} + +.mx-72 { + margin-left: 18rem; + margin-right: 18rem; +} + +.mx-80 { + margin-left: 20rem; + margin-right: 20rem; +} + +.mx-96 { + margin-left: 24rem; + margin-right: 24rem; +} + +.mx-auto { + margin-left: auto; + margin-right: auto; +} + +.mx-px { + margin-left: 1px; + margin-right: 1px; +} + +.-mx-0 { + margin-left: 0px; + margin-right: 0px; +} + +.-mx-1 { + margin-left: -0.25rem; + margin-right: -0.25rem; +} + +.-mx-2 { + margin-left: -0.5rem; + margin-right: -0.5rem; +} + +.-mx-3 { + margin-left: -0.75rem; + margin-right: -0.75rem; +} + +.-mx-4 { + margin-left: -1rem; + margin-right: -1rem; +} + +.-mx-5 { + margin-left: -1.25rem; + margin-right: -1.25rem; +} + +.-mx-6 { + margin-left: -1.5rem; + margin-right: -1.5rem; +} + +.-mx-7 { + margin-left: -1.75rem; + margin-right: -1.75rem; +} + +.-mx-8 { + margin-left: -2rem; + margin-right: -2rem; +} + +.-mx-9 { + margin-left: -2.25rem; + margin-right: -2.25rem; +} + +.-mx-10 { + margin-left: -2.5rem; + margin-right: -2.5rem; +} + +.-mx-11 { + margin-left: -2.75rem; + margin-right: -2.75rem; +} + +.-mx-12 { + margin-left: -3rem; + margin-right: -3rem; +} + +.-mx-14 { + margin-left: -3.5rem; + margin-right: -3.5rem; +} + +.-mx-16 { + margin-left: -4rem; + margin-right: -4rem; +} + +.-mx-20 { + margin-left: -5rem; + margin-right: -5rem; +} + +.-mx-24 { + margin-left: -6rem; + margin-right: -6rem; +} + +.-mx-28 { + margin-left: -7rem; + margin-right: -7rem; +} + +.-mx-32 { + margin-left: -8rem; + margin-right: -8rem; +} + +.-mx-36 { + margin-left: -9rem; + margin-right: -9rem; +} + +.-mx-40 { + margin-left: -10rem; + margin-right: -10rem; +} + +.-mx-44 { + margin-left: -11rem; + margin-right: -11rem; +} + +.-mx-48 { + margin-left: -12rem; + margin-right: -12rem; +} + +.-mx-52 { + margin-left: -13rem; + margin-right: -13rem; +} + +.-mx-56 { + margin-left: -14rem; + margin-right: -14rem; +} + +.-mx-60 { + margin-left: -15rem; + margin-right: -15rem; +} + +.-mx-64 { + margin-left: -16rem; + margin-right: -16rem; +} + +.-mx-72 { + margin-left: -18rem; + margin-right: -18rem; +} + +.-mx-80 { + margin-left: -20rem; + margin-right: -20rem; +} + +.-mx-96 { + margin-left: -24rem; + margin-right: -24rem; +} + +.-mx-px { + margin-left: -1px; + margin-right: -1px; +} + +.my-0 { + margin-top: 0px; + margin-bottom: 0px; +} + +.my-1 { + margin-top: 0.25rem; + margin-bottom: 0.25rem; +} + +.my-2 { + margin-top: 0.5rem; + margin-bottom: 0.5rem; +} + +.my-3 { + margin-top: 0.75rem; + margin-bottom: 0.75rem; +} + +.my-4 { + margin-top: 1rem; + margin-bottom: 1rem; +} + +.my-5 { + margin-top: 1.25rem; + margin-bottom: 1.25rem; +} + +.my-6 { + margin-top: 1.5rem; + margin-bottom: 1.5rem; +} + +.my-7 { + margin-top: 1.75rem; + margin-bottom: 1.75rem; +} + +.my-8 { + margin-top: 2rem; + margin-bottom: 2rem; +} + +.my-9 { + margin-top: 2.25rem; + margin-bottom: 2.25rem; +} + +.my-10 { + margin-top: 2.5rem; + margin-bottom: 2.5rem; +} + +.my-11 { + margin-top: 2.75rem; + margin-bottom: 2.75rem; +} + +.my-12 { + margin-top: 3rem; + margin-bottom: 3rem; +} + +.my-14 { + margin-top: 3.5rem; + margin-bottom: 3.5rem; +} + +.my-16 { + margin-top: 4rem; + margin-bottom: 4rem; +} + +.my-20 { + margin-top: 5rem; + margin-bottom: 5rem; +} + +.my-24 { + margin-top: 6rem; + margin-bottom: 6rem; +} + +.my-28 { + margin-top: 7rem; + margin-bottom: 7rem; +} + +.my-32 { + margin-top: 8rem; + margin-bottom: 8rem; +} + +.my-36 { + margin-top: 9rem; + margin-bottom: 9rem; +} + +.my-40 { + margin-top: 10rem; + margin-bottom: 10rem; +} + +.my-44 { + margin-top: 11rem; + margin-bottom: 11rem; +} + +.my-48 { + margin-top: 12rem; + margin-bottom: 12rem; +} + +.my-52 { + margin-top: 13rem; + margin-bottom: 13rem; +} + +.my-56 { + margin-top: 14rem; + margin-bottom: 14rem; +} + +.my-60 { + margin-top: 15rem; + margin-bottom: 15rem; +} + +.my-64 { + margin-top: 16rem; + margin-bottom: 16rem; +} + +.my-72 { + margin-top: 18rem; + margin-bottom: 18rem; +} + +.my-80 { + margin-top: 20rem; + margin-bottom: 20rem; +} + +.my-96 { + margin-top: 24rem; + margin-bottom: 24rem; +} + +.my-auto { + margin-top: auto; + margin-bottom: auto; +} + +.my-px { + margin-top: 1px; + margin-bottom: 1px; +} + +.-my-0 { + margin-top: 0px; + margin-bottom: 0px; +} + +.-my-1 { + margin-top: -0.25rem; + margin-bottom: -0.25rem; +} + +.-my-2 { + margin-top: -0.5rem; + margin-bottom: -0.5rem; +} + +.-my-3 { + margin-top: -0.75rem; + margin-bottom: -0.75rem; +} + +.-my-4 { + margin-top: -1rem; + margin-bottom: -1rem; +} + +.-my-5 { + margin-top: -1.25rem; + margin-bottom: -1.25rem; +} + +.-my-6 { + margin-top: -1.5rem; + margin-bottom: -1.5rem; +} + +.-my-7 { + margin-top: -1.75rem; + margin-bottom: -1.75rem; +} + +.-my-8 { + margin-top: -2rem; + margin-bottom: -2rem; +} + +.-my-9 { + margin-top: -2.25rem; + margin-bottom: -2.25rem; +} + +.-my-10 { + margin-top: -2.5rem; + margin-bottom: -2.5rem; +} + +.-my-11 { + margin-top: -2.75rem; + margin-bottom: -2.75rem; +} + +.-my-12 { + margin-top: -3rem; + margin-bottom: -3rem; +} + +.-my-14 { + margin-top: -3.5rem; + margin-bottom: -3.5rem; +} + +.-my-16 { + margin-top: -4rem; + margin-bottom: -4rem; +} + +.-my-20 { + margin-top: -5rem; + margin-bottom: -5rem; +} + +.-my-24 { + margin-top: -6rem; + margin-bottom: -6rem; +} + +.-my-28 { + margin-top: -7rem; + margin-bottom: -7rem; +} + +.-my-32 { + margin-top: -8rem; + margin-bottom: -8rem; +} + +.-my-36 { + margin-top: -9rem; + margin-bottom: -9rem; +} + +.-my-40 { + margin-top: -10rem; + margin-bottom: -10rem; +} + +.-my-44 { + margin-top: -11rem; + margin-bottom: -11rem; +} + +.-my-48 { + margin-top: -12rem; + margin-bottom: -12rem; +} + +.-my-52 { + margin-top: -13rem; + margin-bottom: -13rem; +} + +.-my-56 { + margin-top: -14rem; + margin-bottom: -14rem; +} + +.-my-60 { + margin-top: -15rem; + margin-bottom: -15rem; +} + +.-my-64 { + margin-top: -16rem; + margin-bottom: -16rem; +} + +.-my-72 { + margin-top: -18rem; + margin-bottom: -18rem; +} + +.-my-80 { + margin-top: -20rem; + margin-bottom: -20rem; +} + +.-my-96 { + margin-top: -24rem; + margin-bottom: -24rem; +} + +.-my-px { + margin-top: -1px; + margin-bottom: -1px; +} + +.mt-0 { + margin-top: 0px; +} + +.mt-1 { + margin-top: 0.25rem; +} + +.mt-2 { + margin-top: 0.5rem; +} + +.mt-3 { + margin-top: 0.75rem; +} + +.mt-4 { + margin-top: 1rem; +} + +.mt-5 { + margin-top: 1.25rem; +} + +.mt-6 { + margin-top: 1.5rem; +} + +.mt-7 { + margin-top: 1.75rem; +} + +.mt-8 { + margin-top: 2rem; +} + +.mt-9 { + margin-top: 2.25rem; +} + +.mt-10 { + margin-top: 2.5rem; +} + +.mt-11 { + margin-top: 2.75rem; +} + +.mt-12 { + margin-top: 3rem; +} + +.mt-14 { + margin-top: 3.5rem; +} + +.mt-16 { + margin-top: 4rem; +} + +.mt-20 { + margin-top: 5rem; +} + +.mt-24 { + margin-top: 6rem; +} + +.mt-28 { + margin-top: 7rem; +} + +.mt-32 { + margin-top: 8rem; +} + +.mt-36 { + margin-top: 9rem; +} + +.mt-40 { + margin-top: 10rem; +} + +.mt-44 { + margin-top: 11rem; +} + +.mt-48 { + margin-top: 12rem; +} + +.mt-52 { + margin-top: 13rem; +} + +.mt-56 { + margin-top: 14rem; +} + +.mt-60 { + margin-top: 15rem; +} + +.mt-64 { + margin-top: 16rem; +} + +.mt-72 { + margin-top: 18rem; +} + +.mt-80 { + margin-top: 20rem; +} + +.mt-96 { + margin-top: 24rem; +} + +.mt-auto { + margin-top: auto; +} + +.mt-px { + margin-top: 1px; +} + +.-mt-0 { + margin-top: 0px; +} + +.-mt-1 { + margin-top: -0.25rem; +} + +.-mt-2 { + margin-top: -0.5rem; +} + +.-mt-3 { + margin-top: -0.75rem; +} + +.-mt-4 { + margin-top: -1rem; +} + +.-mt-5 { + margin-top: -1.25rem; +} + +.-mt-6 { + margin-top: -1.5rem; +} + +.-mt-7 { + margin-top: -1.75rem; +} + +.-mt-8 { + margin-top: -2rem; +} + +.-mt-9 { + margin-top: -2.25rem; +} + +.-mt-10 { + margin-top: -2.5rem; +} + +.-mt-11 { + margin-top: -2.75rem; +} + +.-mt-12 { + margin-top: -3rem; +} + +.-mt-14 { + margin-top: -3.5rem; +} + +.-mt-16 { + margin-top: -4rem; +} + +.-mt-20 { + margin-top: -5rem; +} + +.-mt-24 { + margin-top: -6rem; +} + +.-mt-28 { + margin-top: -7rem; +} + +.-mt-32 { + margin-top: -8rem; +} + +.-mt-36 { + margin-top: -9rem; +} + +.-mt-40 { + margin-top: -10rem; +} + +.-mt-44 { + margin-top: -11rem; +} + +.-mt-48 { + margin-top: -12rem; +} + +.-mt-52 { + margin-top: -13rem; +} + +.-mt-56 { + margin-top: -14rem; +} + +.-mt-60 { + margin-top: -15rem; +} + +.-mt-64 { + margin-top: -16rem; +} + +.-mt-72 { + margin-top: -18rem; +} + +.-mt-80 { + margin-top: -20rem; +} + +.-mt-96 { + margin-top: -24rem; +} + +.-mt-px { + margin-top: -1px; +} + +.mr-0 { + margin-right: 0px; +} + +.mr-1 { + margin-right: 0.25rem; +} + +.mr-2 { + margin-right: 0.5rem; +} + +.mr-3 { + margin-right: 0.75rem; +} + +.mr-4 { + margin-right: 1rem; +} + +.mr-5 { + margin-right: 1.25rem; +} + +.mr-6 { + margin-right: 1.5rem; +} + +.mr-7 { + margin-right: 1.75rem; +} + +.mr-8 { + margin-right: 2rem; +} + +.mr-9 { + margin-right: 2.25rem; +} + +.mr-10 { + margin-right: 2.5rem; +} + +.mr-11 { + margin-right: 2.75rem; +} + +.mr-12 { + margin-right: 3rem; +} + +.mr-14 { + margin-right: 3.5rem; +} + +.mr-16 { + margin-right: 4rem; +} + +.mr-20 { + margin-right: 5rem; +} + +.mr-24 { + margin-right: 6rem; +} + +.mr-28 { + margin-right: 7rem; +} + +.mr-32 { + margin-right: 8rem; +} + +.mr-36 { + margin-right: 9rem; +} + +.mr-40 { + margin-right: 10rem; +} + +.mr-44 { + margin-right: 11rem; +} + +.mr-48 { + margin-right: 12rem; +} + +.mr-52 { + margin-right: 13rem; +} + +.mr-56 { + margin-right: 14rem; +} + +.mr-60 { + margin-right: 15rem; +} + +.mr-64 { + margin-right: 16rem; +} + +.mr-72 { + margin-right: 18rem; +} + +.mr-80 { + margin-right: 20rem; +} + +.mr-96 { + margin-right: 24rem; +} + +.mr-auto { + margin-right: auto; +} + +.mr-px { + margin-right: 1px; +} + +.-mr-0 { + margin-right: 0px; +} + +.-mr-1 { + margin-right: -0.25rem; +} + +.-mr-2 { + margin-right: -0.5rem; +} + +.-mr-3 { + margin-right: -0.75rem; +} + +.-mr-4 { + margin-right: -1rem; +} + +.-mr-5 { + margin-right: -1.25rem; +} + +.-mr-6 { + margin-right: -1.5rem; +} + +.-mr-7 { + margin-right: -1.75rem; +} + +.-mr-8 { + margin-right: -2rem; +} + +.-mr-9 { + margin-right: -2.25rem; +} + +.-mr-10 { + margin-right: -2.5rem; +} + +.-mr-11 { + margin-right: -2.75rem; +} + +.-mr-12 { + margin-right: -3rem; +} + +.-mr-14 { + margin-right: -3.5rem; +} + +.-mr-16 { + margin-right: -4rem; +} + +.-mr-20 { + margin-right: -5rem; +} + +.-mr-24 { + margin-right: -6rem; +} + +.-mr-28 { + margin-right: -7rem; +} + +.-mr-32 { + margin-right: -8rem; +} + +.-mr-36 { + margin-right: -9rem; +} + +.-mr-40 { + margin-right: -10rem; +} + +.-mr-44 { + margin-right: -11rem; +} + +.-mr-48 { + margin-right: -12rem; +} + +.-mr-52 { + margin-right: -13rem; +} + +.-mr-56 { + margin-right: -14rem; +} + +.-mr-60 { + margin-right: -15rem; +} + +.-mr-64 { + margin-right: -16rem; +} + +.-mr-72 { + margin-right: -18rem; +} + +.-mr-80 { + margin-right: -20rem; +} + +.-mr-96 { + margin-right: -24rem; +} + +.-mr-px { + margin-right: -1px; +} + +.mb-0 { + margin-bottom: 0px; +} + +.mb-1 { + margin-bottom: 0.25rem; +} + +.mb-2 { + margin-bottom: 0.5rem; +} + +.mb-3 { + margin-bottom: 0.75rem; +} + +.mb-4 { + margin-bottom: 1rem; +} + +.mb-5 { + margin-bottom: 1.25rem; +} + +.mb-6 { + margin-bottom: 1.5rem; +} + +.mb-7 { + margin-bottom: 1.75rem; +} + +.mb-8 { + margin-bottom: 2rem; +} + +.mb-9 { + margin-bottom: 2.25rem; +} + +.mb-10 { + margin-bottom: 2.5rem; +} + +.mb-11 { + margin-bottom: 2.75rem; +} + +.mb-12 { + margin-bottom: 3rem; +} + +.mb-14 { + margin-bottom: 3.5rem; +} + +.mb-16 { + margin-bottom: 4rem; +} + +.mb-20 { + margin-bottom: 5rem; +} + +.mb-24 { + margin-bottom: 6rem; +} + +.mb-28 { + margin-bottom: 7rem; +} + +.mb-32 { + margin-bottom: 8rem; +} + +.mb-36 { + margin-bottom: 9rem; +} + +.mb-40 { + margin-bottom: 10rem; +} + +.mb-44 { + margin-bottom: 11rem; +} + +.mb-48 { + margin-bottom: 12rem; +} + +.mb-52 { + margin-bottom: 13rem; +} + +.mb-56 { + margin-bottom: 14rem; +} + +.mb-60 { + margin-bottom: 15rem; +} + +.mb-64 { + margin-bottom: 16rem; +} + +.mb-72 { + margin-bottom: 18rem; +} + +.mb-80 { + margin-bottom: 20rem; +} + +.mb-96 { + margin-bottom: 24rem; +} + +.mb-auto { + margin-bottom: auto; +} + +.mb-px { + margin-bottom: 1px; +} + +.-mb-0 { + margin-bottom: 0px; +} + +.-mb-1 { + margin-bottom: -0.25rem; +} + +.-mb-2 { + margin-bottom: -0.5rem; +} + +.-mb-3 { + margin-bottom: -0.75rem; +} + +.-mb-4 { + margin-bottom: -1rem; +} + +.-mb-5 { + margin-bottom: -1.25rem; +} + +.-mb-6 { + margin-bottom: -1.5rem; +} + +.-mb-7 { + margin-bottom: -1.75rem; +} + +.-mb-8 { + margin-bottom: -2rem; +} + +.-mb-9 { + margin-bottom: -2.25rem; +} + +.-mb-10 { + margin-bottom: -2.5rem; +} + +.-mb-11 { + margin-bottom: -2.75rem; +} + +.-mb-12 { + margin-bottom: -3rem; +} + +.-mb-14 { + margin-bottom: -3.5rem; +} + +.-mb-16 { + margin-bottom: -4rem; +} + +.-mb-20 { + margin-bottom: -5rem; +} + +.-mb-24 { + margin-bottom: -6rem; +} + +.-mb-28 { + margin-bottom: -7rem; +} + +.-mb-32 { + margin-bottom: -8rem; +} + +.-mb-36 { + margin-bottom: -9rem; +} + +.-mb-40 { + margin-bottom: -10rem; +} + +.-mb-44 { + margin-bottom: -11rem; +} + +.-mb-48 { + margin-bottom: -12rem; +} + +.-mb-52 { + margin-bottom: -13rem; +} + +.-mb-56 { + margin-bottom: -14rem; +} + +.-mb-60 { + margin-bottom: -15rem; +} + +.-mb-64 { + margin-bottom: -16rem; +} + +.-mb-72 { + margin-bottom: -18rem; +} + +.-mb-80 { + margin-bottom: -20rem; +} + +.-mb-96 { + margin-bottom: -24rem; +} + +.-mb-px { + margin-bottom: -1px; +} + +.ml-0 { + margin-left: 0px; +} + +.ml-1 { + margin-left: 0.25rem; +} + +.ml-2 { + margin-left: 0.5rem; +} + +.ml-3 { + margin-left: 0.75rem; +} + +.ml-4 { + margin-left: 1rem; +} + +.ml-5 { + margin-left: 1.25rem; +} + +.ml-6 { + margin-left: 1.5rem; +} + +.ml-7 { + margin-left: 1.75rem; +} + +.ml-8 { + margin-left: 2rem; +} + +.ml-9 { + margin-left: 2.25rem; +} + +.ml-10 { + margin-left: 2.5rem; +} + +.ml-11 { + margin-left: 2.75rem; +} + +.ml-12 { + margin-left: 3rem; +} + +.ml-14 { + margin-left: 3.5rem; +} + +.ml-16 { + margin-left: 4rem; +} + +.ml-20 { + margin-left: 5rem; +} + +.ml-24 { + margin-left: 6rem; +} + +.ml-28 { + margin-left: 7rem; +} + +.ml-32 { + margin-left: 8rem; +} + +.ml-36 { + margin-left: 9rem; +} + +.ml-40 { + margin-left: 10rem; +} + +.ml-44 { + margin-left: 11rem; +} + +.ml-48 { + margin-left: 12rem; +} + +.ml-52 { + margin-left: 13rem; +} + +.ml-56 { + margin-left: 14rem; +} + +.ml-60 { + margin-left: 15rem; +} + +.ml-64 { + margin-left: 16rem; +} + +.ml-72 { + margin-left: 18rem; +} + +.ml-80 { + margin-left: 20rem; +} + +.ml-96 { + margin-left: 24rem; +} + +.ml-auto { + margin-left: auto; +} + +.ml-px { + margin-left: 1px; +} + +.-ml-0 { + margin-left: 0px; +} + +.-ml-1 { + margin-left: -0.25rem; +} + +.-ml-2 { + margin-left: -0.5rem; +} + +.-ml-3 { + margin-left: -0.75rem; +} + +.-ml-4 { + margin-left: -1rem; +} + +.-ml-5 { + margin-left: -1.25rem; +} + +.-ml-6 { + margin-left: -1.5rem; +} + +.-ml-7 { + margin-left: -1.75rem; +} + +.-ml-8 { + margin-left: -2rem; +} + +.-ml-9 { + margin-left: -2.25rem; +} + +.-ml-10 { + margin-left: -2.5rem; +} + +.-ml-11 { + margin-left: -2.75rem; +} + +.-ml-12 { + margin-left: -3rem; +} + +.-ml-14 { + margin-left: -3.5rem; +} + +.-ml-16 { + margin-left: -4rem; +} + +.-ml-20 { + margin-left: -5rem; +} + +.-ml-24 { + margin-left: -6rem; +} + +.-ml-28 { + margin-left: -7rem; +} + +.-ml-32 { + margin-left: -8rem; +} + +.-ml-36 { + margin-left: -9rem; +} + +.-ml-40 { + margin-left: -10rem; +} + +.-ml-44 { + margin-left: -11rem; +} + +.-ml-48 { + margin-left: -12rem; +} + +.-ml-52 { + margin-left: -13rem; +} + +.-ml-56 { + margin-left: -14rem; +} + +.-ml-60 { + margin-left: -15rem; +} + +.-ml-64 { + margin-left: -16rem; +} + +.-ml-72 { + margin-left: -18rem; +} + +.-ml-80 { + margin-left: -20rem; +} + +.-ml-96 { + margin-left: -24rem; +} + +.-ml-px { + margin-left: -1px; +} + +.box-border { + box-sizing: border-box; +} + +.box-content { + box-sizing: content-box; +} + +.block { + display: block; +} + +.inline-block { + display: inline-block; +} + +.inline { + display: inline; +} + +.flex { + display: flex; +} + +.inline-flex { + display: inline-flex; +} + +.grid { + display: grid; +} + +.inline-grid { + display: inline-grid; +} + +.contents { + display: contents; +} + +.list-item { + display: list-item; +} + +.hidden { + display: none; +} + +.flex-1 { + flex: 1 1 0%; +} + +.flex-auto { + flex: 1 1 auto; +} + +.flex-initial { + flex: 0 1 auto; +} + +.flex-none { + flex: none; +} + +.flex-shrink-0 { + flex-shrink: 0; +} + +.flex-shrink { + flex-shrink: 1; +} + +.flex-grow-0 { + flex-grow: 0; +} + +.flex-grow { + flex-grow: 1; +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +@keyframes ping { + 75%, + 100% { + transform: scale(2); + opacity: 0; + } +} + +@keyframes pulse { + 50% { + opacity: 0.5; + } +} + +@keyframes bounce { + 0%, + 100% { + transform: translateY(-25%); + animation-timing-function: cubic-bezier(0.8, 0, 1, 1); + } + + 50% { + transform: none; + animation-timing-function: cubic-bezier(0, 0, 0.2, 1); + } +} + +.animate-none { + animation: none; +} + +.animate-spin { + animation: spin 1s linear infinite; +} + +.animate-ping { + animation: ping 1s cubic-bezier(0, 0, 0.2, 1) infinite; +} + +.animate-pulse { + animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; +} + +.animate-bounce { + animation: bounce 1s infinite; +} + +.cursor-auto { + cursor: auto; +} + +.cursor-default { + cursor: default; +} + +.cursor-pointer { + cursor: pointer; +} + +.cursor-wait { + cursor: wait; +} + +.cursor-text { + cursor: text; +} + +.cursor-move { + cursor: move; +} + +.cursor-help { + cursor: help; +} + +.cursor-not-allowed { + cursor: not-allowed; +} + +.select-none { + -webkit-user-select: none; + user-select: none; +} + +.select-text { + -webkit-user-select: text; + user-select: text; +} + +.select-all { + -webkit-user-select: all; + user-select: all; +} + +.select-auto { + -webkit-user-select: auto; + user-select: auto; +} + +.auto-cols-auto { + grid-auto-columns: auto; +} + +.auto-cols-min { + grid-auto-columns: min-content; +} + +.auto-cols-max { + grid-auto-columns: max-content; +} + +.auto-cols-fr { + grid-auto-columns: minmax(0, 1fr); +} + +.grid-flow-row { + grid-auto-flow: row; +} + +.grid-flow-col { + grid-auto-flow: column; +} + +.grid-flow-row-dense { + grid-auto-flow: row dense; +} + +.grid-flow-col-dense { + grid-auto-flow: column dense; +} + +.auto-rows-auto { + grid-auto-rows: auto; +} + +.auto-rows-min { + grid-auto-rows: min-content; +} + +.auto-rows-max { + grid-auto-rows: max-content; +} + +.auto-rows-fr { + grid-auto-rows: minmax(0, 1fr); +} + +.grid-cols-1 { + grid-template-columns: repeat(1, minmax(0, 1fr)); +} + +.grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); +} + +.grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); +} + +.grid-cols-4 { + grid-template-columns: repeat(4, minmax(0, 1fr)); +} + +.grid-cols-5 { + grid-template-columns: repeat(5, minmax(0, 1fr)); +} + +.grid-cols-6 { + grid-template-columns: repeat(6, minmax(0, 1fr)); +} + +.grid-cols-7 { + grid-template-columns: repeat(7, minmax(0, 1fr)); +} + +.grid-cols-8 { + grid-template-columns: repeat(8, minmax(0, 1fr)); +} + +.grid-cols-9 { + grid-template-columns: repeat(9, minmax(0, 1fr)); +} + +.grid-cols-10 { + grid-template-columns: repeat(10, minmax(0, 1fr)); +} + +.grid-cols-11 { + grid-template-columns: repeat(11, minmax(0, 1fr)); +} + +.grid-cols-12 { + grid-template-columns: repeat(12, minmax(0, 1fr)); +} + +.grid-cols-none { + grid-template-columns: none; +} + +.grid-rows-1 { + grid-template-rows: repeat(1, minmax(0, 1fr)); +} + +.grid-rows-2 { + grid-template-rows: repeat(2, minmax(0, 1fr)); +} + +.grid-rows-3 { + grid-template-rows: repeat(3, minmax(0, 1fr)); +} + +.grid-rows-4 { + grid-template-rows: repeat(4, minmax(0, 1fr)); +} + +.grid-rows-5 { + grid-template-rows: repeat(5, minmax(0, 1fr)); +} + +.grid-rows-6 { + grid-template-rows: repeat(6, minmax(0, 1fr)); +} + +.grid-rows-none { + grid-template-rows: none; +} + +.flex-row { + flex-direction: row; +} + +.flex-row-reverse { + flex-direction: row-reverse; +} + +.flex-col { + flex-direction: column; +} + +.flex-col-reverse { + flex-direction: column-reverse; +} + +.flex-wrap { + flex-wrap: wrap; +} + +.flex-wrap-reverse { + flex-wrap: wrap-reverse; +} + +.flex-nowrap { + flex-wrap: nowrap; +} + +.content-center { + align-content: center; +} + +.content-start { + align-content: flex-start; +} + +.content-end { + align-content: flex-end; +} + +.content-between { + align-content: space-between; +} + +.content-around { + align-content: space-around; +} + +.content-evenly { + align-content: space-evenly; +} + +.items-start { + align-items: flex-start; +} + +.items-end { + align-items: flex-end; +} + +.items-center { + align-items: center; +} + +.items-baseline { + align-items: baseline; +} + +.items-stretch { + align-items: stretch; +} + +.justify-start { + justify-content: flex-start; +} + +.justify-end { + justify-content: flex-end; +} + +.justify-center { + justify-content: center; +} + +.justify-between { + justify-content: space-between; +} + +.justify-around { + justify-content: space-around; +} + +.justify-evenly { + justify-content: space-evenly; +} + +.justify-items-start { + justify-items: start; +} + +.justify-items-end { + justify-items: end; +} + +.justify-items-center { + justify-items: center; +} + +.justify-items-stretch { + justify-items: stretch; +} + +.self-auto { + align-self: auto; +} + +.self-start { + align-self: flex-start; +} + +.self-end { + align-self: flex-end; +} + +.self-center { + align-self: center; +} + +.self-stretch { + align-self: stretch; +} + +.self-baseline { + align-self: baseline; +} + +.justify-self-auto { + justify-self: auto; +} + +.justify-self-start { + justify-self: start; +} + +.justify-self-end { + justify-self: end; +} + +.justify-self-center { + justify-self: center; +} + +.justify-self-stretch { + justify-self: stretch; +} + +.overflow-auto { + overflow: auto; +} + +.overflow-hidden { + overflow: hidden; +} + +.overflow-visible { + overflow: visible; +} + +.overflow-scroll { + overflow: scroll; +} + +.overflow-x-auto { + overflow-x: auto; +} + +.overflow-y-auto { + overflow-y: auto; +} + +.overflow-x-hidden { + overflow-x: hidden; +} + +.overflow-y-hidden { + overflow-y: hidden; +} + +.overflow-x-visible { + overflow-x: visible; +} + +.overflow-y-visible { + overflow-y: visible; +} + +.overflow-x-scroll { + overflow-x: scroll; +} + +.overflow-y-scroll { + overflow-y: scroll; +} +.truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.overflow-ellipsis { + text-overflow: ellipsis; +} + +.p-0 { + padding: 0px; +} + +.p-1 { + padding: 0.25rem; +} + +.p-2 { + padding: 0.5rem; +} + +.p-3 { + padding: 0.75rem; +} + +.p-4 { + padding: 1rem; +} + +.p-5 { + padding: 1.25rem; +} + +.p-6 { + padding: 1.5rem; +} + +.p-7 { + padding: 1.75rem; +} + +.p-8 { + padding: 2rem; +} + +.p-9 { + padding: 2.25rem; +} + +.p-10 { + padding: 2.5rem; +} + +.p-11 { + padding: 2.75rem; +} + +.p-12 { + padding: 3rem; +} + +.p-14 { + padding: 3.5rem; +} + +.p-16 { + padding: 4rem; +} + +.p-20 { + padding: 5rem; +} + +.p-24 { + padding: 6rem; +} + +.p-28 { + padding: 7rem; +} + +.p-32 { + padding: 8rem; +} + +.p-36 { + padding: 9rem; +} + +.p-40 { + padding: 10rem; +} + +.p-44 { + padding: 11rem; +} + +.p-48 { + padding: 12rem; +} + +.p-52 { + padding: 13rem; +} + +.p-56 { + padding: 14rem; +} + +.p-60 { + padding: 15rem; +} + +.p-64 { + padding: 16rem; +} + +.p-72 { + padding: 18rem; +} + +.p-80 { + padding: 20rem; +} + +.p-96 { + padding: 24rem; +} + +.p-px { + padding: 1px; +} + +.px-0 { + padding-left: 0px; + padding-right: 0px; +} + +.px-1 { + padding-left: 0.25rem; + padding-right: 0.25rem; +} + +.px-2 { + padding-left: 0.5rem; + padding-right: 0.5rem; +} + +.px-3 { + padding-left: 0.75rem; + padding-right: 0.75rem; +} + +.px-4 { + padding-left: 1rem; + padding-right: 1rem; +} + +.px-5 { + padding-left: 1.25rem; + padding-right: 1.25rem; +} + +.px-6 { + padding-left: 1.5rem; + padding-right: 1.5rem; +} + +.px-7 { + padding-left: 1.75rem; + padding-right: 1.75rem; +} + +.px-8 { + padding-left: 2rem; + padding-right: 2rem; +} + +.px-9 { + padding-left: 2.25rem; + padding-right: 2.25rem; +} + +.px-10 { + padding-left: 2.5rem; + padding-right: 2.5rem; +} + +.px-11 { + padding-left: 2.75rem; + padding-right: 2.75rem; +} + +.px-12 { + padding-left: 3rem; + padding-right: 3rem; +} + +.px-14 { + padding-left: 3.5rem; + padding-right: 3.5rem; +} + +.px-16 { + padding-left: 4rem; + padding-right: 4rem; +} + +.px-20 { + padding-left: 5rem; + padding-right: 5rem; +} + +.px-24 { + padding-left: 6rem; + padding-right: 6rem; +} + +.px-28 { + padding-left: 7rem; + padding-right: 7rem; +} + +.px-32 { + padding-left: 8rem; + padding-right: 8rem; +} + +.px-36 { + padding-left: 9rem; + padding-right: 9rem; +} + +.px-40 { + padding-left: 10rem; + padding-right: 10rem; +} + +.px-44 { + padding-left: 11rem; + padding-right: 11rem; +} + +.px-48 { + padding-left: 12rem; + padding-right: 12rem; +} + +.px-52 { + padding-left: 13rem; + padding-right: 13rem; +} + +.px-56 { + padding-left: 14rem; + padding-right: 14rem; +} + +.px-60 { + padding-left: 15rem; + padding-right: 15rem; +} + +.px-64 { + padding-left: 16rem; + padding-right: 16rem; +} + +.px-72 { + padding-left: 18rem; + padding-right: 18rem; +} + +.px-80 { + padding-left: 20rem; + padding-right: 20rem; +} + +.px-96 { + padding-left: 24rem; + padding-right: 24rem; +} + +.px-px { + padding-left: 1px; + padding-right: 1px; +} + +.py-0 { + padding-top: 0px; + padding-bottom: 0px; +} + +.py-1 { + padding-top: 0.25rem; + padding-bottom: 0.25rem; +} + +.py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.py-3 { + padding-top: 0.75rem; + padding-bottom: 0.75rem; +} + +.py-4 { + padding-top: 1rem; + padding-bottom: 1rem; +} + +.py-5 { + padding-top: 1.25rem; + padding-bottom: 1.25rem; +} + +.py-6 { + padding-top: 1.5rem; + padding-bottom: 1.5rem; +} + +.py-7 { + padding-top: 1.75rem; + padding-bottom: 1.75rem; +} + +.py-8 { + padding-top: 2rem; + padding-bottom: 2rem; +} + +.py-9 { + padding-top: 2.25rem; + padding-bottom: 2.25rem; +} + +.py-10 { + padding-top: 2.5rem; + padding-bottom: 2.5rem; +} + +.py-11 { + padding-top: 2.75rem; + padding-bottom: 2.75rem; +} + +.py-12 { + padding-top: 3rem; + padding-bottom: 3rem; +} + +.py-14 { + padding-top: 3.5rem; + padding-bottom: 3.5rem; +} + +.py-16 { + padding-top: 4rem; + padding-bottom: 4rem; +} + +.py-20 { + padding-top: 5rem; + padding-bottom: 5rem; +} + +.py-24 { + padding-top: 6rem; + padding-bottom: 6rem; +} + +.py-28 { + padding-top: 7rem; + padding-bottom: 7rem; +} + +.py-32 { + padding-top: 8rem; + padding-bottom: 8rem; +} + +.py-36 { + padding-top: 9rem; + padding-bottom: 9rem; +} + +.py-40 { + padding-top: 10rem; + padding-bottom: 10rem; +} + +.py-44 { + padding-top: 11rem; + padding-bottom: 11rem; +} + +.py-48 { + padding-top: 12rem; + padding-bottom: 12rem; +} + +.py-52 { + padding-top: 13rem; + padding-bottom: 13rem; +} + +.py-56 { + padding-top: 14rem; + padding-bottom: 14rem; +} + +.py-60 { + padding-top: 15rem; + padding-bottom: 15rem; +} + +.py-64 { + padding-top: 16rem; + padding-bottom: 16rem; +} + +.py-72 { + padding-top: 18rem; + padding-bottom: 18rem; +} + +.py-80 { + padding-top: 20rem; + padding-bottom: 20rem; +} + +.py-96 { + padding-top: 24rem; + padding-bottom: 24rem; +} + +.py-px { + padding-top: 1px; + padding-bottom: 1px; +} + +.pt-0 { + padding-top: 0px; +} + +.pt-1 { + padding-top: 0.25rem; +} + +.pt-2 { + padding-top: 0.5rem; +} + +.pt-3 { + padding-top: 0.75rem; +} + +.pt-4 { + padding-top: 1rem; +} + +.pt-5 { + padding-top: 1.25rem; +} + +.pt-6 { + padding-top: 1.5rem; +} + +.pt-7 { + padding-top: 1.75rem; +} + +.pt-8 { + padding-top: 2rem; +} + +.pt-9 { + padding-top: 2.25rem; +} + +.pt-10 { + padding-top: 2.5rem; +} + +.pt-11 { + padding-top: 2.75rem; +} + +.pt-12 { + padding-top: 3rem; +} + +.pt-14 { + padding-top: 3.5rem; +} + +.pt-16 { + padding-top: 4rem; +} + +.pt-20 { + padding-top: 5rem; +} + +.pt-24 { + padding-top: 6rem; +} + +.pt-28 { + padding-top: 7rem; +} + +.pt-32 { + padding-top: 8rem; +} + +.pt-36 { + padding-top: 9rem; +} + +.pt-40 { + padding-top: 10rem; +} + +.pt-44 { + padding-top: 11rem; +} + +.pt-48 { + padding-top: 12rem; +} + +.pt-52 { + padding-top: 13rem; +} + +.pt-56 { + padding-top: 14rem; +} + +.pt-60 { + padding-top: 15rem; +} + +.pt-64 { + padding-top: 16rem; +} + +.pt-72 { + padding-top: 18rem; +} + +.pt-80 { + padding-top: 20rem; +} + +.pt-96 { + padding-top: 24rem; +} + +.pt-px { + padding-top: 1px; +} + +.pr-0 { + padding-right: 0px; +} + +.pr-1 { + padding-right: 0.25rem; +} + +.pr-2 { + padding-right: 0.5rem; +} + +.pr-3 { + padding-right: 0.75rem; +} + +.pr-4 { + padding-right: 1rem; +} + +.pr-5 { + padding-right: 1.25rem; +} + +.pr-6 { + padding-right: 1.5rem; +} + +.pr-7 { + padding-right: 1.75rem; +} + +.pr-8 { + padding-right: 2rem; +} + +.pr-9 { + padding-right: 2.25rem; +} + +.pr-10 { + padding-right: 2.5rem; +} + +.pr-11 { + padding-right: 2.75rem; +} + +.pr-12 { + padding-right: 3rem; +} + +.pr-14 { + padding-right: 3.5rem; +} + +.pr-16 { + padding-right: 4rem; +} + +.pr-20 { + padding-right: 5rem; +} + +.pr-24 { + padding-right: 6rem; +} + +.pr-28 { + padding-right: 7rem; +} + +.pr-32 { + padding-right: 8rem; +} + +.pr-36 { + padding-right: 9rem; +} + +.pr-40 { + padding-right: 10rem; +} + +.pr-44 { + padding-right: 11rem; +} + +.pr-48 { + padding-right: 12rem; +} + +.pr-52 { + padding-right: 13rem; +} + +.pr-56 { + padding-right: 14rem; +} + +.pr-60 { + padding-right: 15rem; +} + +.pr-64 { + padding-right: 16rem; +} + +.pr-72 { + padding-right: 18rem; +} + +.pr-80 { + padding-right: 20rem; +} + +.pr-96 { + padding-right: 24rem; +} + +.pr-px { + padding-right: 1px; +} + +.pb-0 { + padding-bottom: 0px; +} + +.pb-1 { + padding-bottom: 0.25rem; +} + +.pb-2 { + padding-bottom: 0.5rem; +} + +.pb-3 { + padding-bottom: 0.75rem; +} + +.pb-4 { + padding-bottom: 1rem; +} + +.pb-5 { + padding-bottom: 1.25rem; +} + +.pb-6 { + padding-bottom: 1.5rem; +} + +.pb-7 { + padding-bottom: 1.75rem; +} + +.pb-8 { + padding-bottom: 2rem; +} + +.pb-9 { + padding-bottom: 2.25rem; +} + +.pb-10 { + padding-bottom: 2.5rem; +} + +.pb-11 { + padding-bottom: 2.75rem; +} + +.pb-12 { + padding-bottom: 3rem; +} + +.pb-14 { + padding-bottom: 3.5rem; +} + +.pb-16 { + padding-bottom: 4rem; +} + +.pb-20 { + padding-bottom: 5rem; +} + +.pb-24 { + padding-bottom: 6rem; +} + +.pb-28 { + padding-bottom: 7rem; +} + +.pb-32 { + padding-bottom: 8rem; +} + +.pb-36 { + padding-bottom: 9rem; +} + +.pb-40 { + padding-bottom: 10rem; +} + +.pb-44 { + padding-bottom: 11rem; +} + +.pb-48 { + padding-bottom: 12rem; +} + +.pb-52 { + padding-bottom: 13rem; +} + +.pb-56 { + padding-bottom: 14rem; +} + +.pb-60 { + padding-bottom: 15rem; +} + +.pb-64 { + padding-bottom: 16rem; +} + +.pb-72 { + padding-bottom: 18rem; +} + +.pb-80 { + padding-bottom: 20rem; +} + +.pb-96 { + padding-bottom: 24rem; +} + +.pb-px { + padding-bottom: 1px; +} + +.pl-0 { + padding-left: 0px; +} + +.pl-1 { + padding-left: 0.25rem; +} + +.pl-2 { + padding-left: 0.5rem; +} + +.pl-3 { + padding-left: 0.75rem; +} + +.pl-4 { + padding-left: 1rem; +} + +.pl-5 { + padding-left: 1.25rem; +} + +.pl-6 { + padding-left: 1.5rem; +} + +.pl-7 { + padding-left: 1.75rem; +} + +.pl-8 { + padding-left: 2rem; +} + +.pl-9 { + padding-left: 2.25rem; +} + +.pl-10 { + padding-left: 2.5rem; +} + +.pl-11 { + padding-left: 2.75rem; +} + +.pl-12 { + padding-left: 3rem; +} + +.pl-14 { + padding-left: 3.5rem; +} + +.pl-16 { + padding-left: 4rem; +} + +.pl-20 { + padding-left: 5rem; +} + +.pl-24 { + padding-left: 6rem; +} + +.pl-28 { + padding-left: 7rem; +} + +.pl-32 { + padding-left: 8rem; +} + +.pl-36 { + padding-left: 9rem; +} + +.pl-40 { + padding-left: 10rem; +} + +.pl-44 { + padding-left: 11rem; +} + +.pl-48 { + padding-left: 12rem; +} + +.pl-52 { + padding-left: 13rem; +} + +.pl-56 { + padding-left: 14rem; +} + +.pl-60 { + padding-left: 15rem; +} + +.pl-64 { + padding-left: 16rem; +} + +.pl-72 { + padding-left: 18rem; +} + +.pl-80 { + padding-left: 20rem; +} + +.pl-96 { + padding-left: 24rem; +} + +.pl-px { + padding-left: 1px; +} + +.text-left { + text-align: left; +} + +.text-center { + text-align: center; +} + +.text-right { + text-align: right; +} + +.text-justify { + text-align: justify; +} + +.align-baseline { + vertical-align: baseline; +} + +.align-top { + vertical-align: top; +} + +.align-middle { + vertical-align: middle; +} + +.align-bottom { + vertical-align: bottom; +} + +.align-text-top { + vertical-align: text-top; +} + +.align-text-bottom { + vertical-align: text-bottom; +} + +.font-sans { + font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', + sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; +} + +.font-serif { + font-family: ui-serif, Georgia, Cambria, 'Times New Roman', Times, serif; +} + +.font-mono { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; +} + +.text-xs { + font-size: 0.75rem; + line-height: 1rem; +} + +.text-sm { + font-size: 0.875rem; + line-height: 1.25rem; +} + +.text-base { + font-size: 1rem; + line-height: 1.5rem; +} + +.text-lg { + font-size: 1.125rem; + line-height: 1.75rem; +} + +.text-xl { + font-size: 1.25rem; + line-height: 1.75rem; +} + +.text-2xl { + font-size: 1.5rem; + line-height: 2rem; +} + +.text-3xl { + font-size: 1.875rem; + line-height: 2.25rem; +} + +.text-4xl { + font-size: 2.25rem; + line-height: 2.5rem; +} + +.text-5xl { + font-size: 3rem; + line-height: 1; +} + +.text-6xl { + font-size: 3.75rem; + line-height: 1; +} + +.text-7xl { + font-size: 4.5rem; + line-height: 1; +} + +.text-8xl { + font-size: 6rem; + line-height: 1; +} + +.text-9xl { + font-size: 8rem; + line-height: 1; +} + +.font-thin { + font-weight: 100; +} + +.font-extralight { + font-weight: 200; +} + +.font-light { + font-weight: 300; +} + +.font-normal { + font-weight: 400; +} + +.font-medium { + font-weight: 500; +} + +.font-semibold { + font-weight: 600; +} + +.font-bold { + font-weight: 700; +} + +.font-extrabold { + font-weight: 800; +} + +.font-black { + font-weight: 900; +} + +.uppercase { + text-transform: uppercase; +} + +.lowercase { + text-transform: lowercase; +} + +.capitalize { + text-transform: capitalize; +} + +.normal-case { + text-transform: none; +} + +.italic { + font-style: italic; +} + +.not-italic { + font-style: normal; +} + +.text-transparent { + color: transparent; +} + +.text-current { + color: currentColor; +} + +.text-black { + --tw-text-opacity: 1; + color: rgba(0, 0, 0, var(--tw-text-opacity)); +} + +.text-white { + --tw-text-opacity: 1; + color: rgba(255, 255, 255, var(--tw-text-opacity)); +} + +.text-gray-50 { + --tw-text-opacity: 1; + color: rgba(249, 250, 251, var(--tw-text-opacity)); +} + +.text-gray-100 { + --tw-text-opacity: 1; + color: rgba(243, 244, 246, var(--tw-text-opacity)); +} + +.text-gray-200 { + --tw-text-opacity: 1; + color: rgba(229, 231, 235, var(--tw-text-opacity)); +} + +.text-gray-300 { + --tw-text-opacity: 1; + color: rgba(209, 213, 219, var(--tw-text-opacity)); +} + +.text-gray-400 { + --tw-text-opacity: 1; + color: rgba(156, 163, 175, var(--tw-text-opacity)); +} + +.text-gray-500 { + --tw-text-opacity: 1; + color: rgba(107, 114, 128, var(--tw-text-opacity)); +} + +.text-gray-600 { + --tw-text-opacity: 1; + color: rgba(75, 85, 99, var(--tw-text-opacity)); +} + +.text-gray-700 { + --tw-text-opacity: 1; + color: rgba(55, 65, 81, var(--tw-text-opacity)); +} + +.text-gray-800 { + --tw-text-opacity: 1; + color: rgba(31, 41, 55, var(--tw-text-opacity)); +} + +.text-gray-900 { + --tw-text-opacity: 1; + color: rgba(17, 24, 39, var(--tw-text-opacity)); +} + +.text-red-50 { + --tw-text-opacity: 1; + color: rgba(254, 242, 242, var(--tw-text-opacity)); +} + +.text-red-100 { + --tw-text-opacity: 1; + color: rgba(254, 226, 226, var(--tw-text-opacity)); +} + +.text-red-200 { + --tw-text-opacity: 1; + color: rgba(254, 202, 202, var(--tw-text-opacity)); +} + +.text-red-300 { + --tw-text-opacity: 1; + color: rgba(252, 165, 165, var(--tw-text-opacity)); +} + +.text-red-400 { + --tw-text-opacity: 1; + color: rgba(248, 113, 113, var(--tw-text-opacity)); +} + +.text-red-500 { + --tw-text-opacity: 1; + color: rgba(239, 68, 68, var(--tw-text-opacity)); +} + +.text-red-600 { + --tw-text-opacity: 1; + color: rgba(220, 38, 38, var(--tw-text-opacity)); +} + +.text-red-700 { + --tw-text-opacity: 1; + color: rgba(185, 28, 28, var(--tw-text-opacity)); +} + +.text-red-800 { + --tw-text-opacity: 1; + color: rgba(153, 27, 27, var(--tw-text-opacity)); +} + +.text-red-900 { + --tw-text-opacity: 1; + color: rgba(127, 29, 29, var(--tw-text-opacity)); +} + +.text-yellow-50 { + --tw-text-opacity: 1; + color: rgba(255, 251, 235, var(--tw-text-opacity)); +} + +.text-yellow-100 { + --tw-text-opacity: 1; + color: rgba(254, 243, 199, var(--tw-text-opacity)); +} + +.text-yellow-200 { + --tw-text-opacity: 1; + color: rgba(253, 230, 138, var(--tw-text-opacity)); +} + +.text-yellow-300 { + --tw-text-opacity: 1; + color: rgba(252, 211, 77, var(--tw-text-opacity)); +} + +.text-yellow-400 { + --tw-text-opacity: 1; + color: rgba(251, 191, 36, var(--tw-text-opacity)); +} + +.text-yellow-500 { + --tw-text-opacity: 1; + color: rgba(245, 158, 11, var(--tw-text-opacity)); +} + +.text-yellow-600 { + --tw-text-opacity: 1; + color: rgba(217, 119, 6, var(--tw-text-opacity)); +} + +.text-yellow-700 { + --tw-text-opacity: 1; + color: rgba(180, 83, 9, var(--tw-text-opacity)); +} + +.text-yellow-800 { + --tw-text-opacity: 1; + color: rgba(146, 64, 14, var(--tw-text-opacity)); +} + +.text-yellow-900 { + --tw-text-opacity: 1; + color: rgba(120, 53, 15, var(--tw-text-opacity)); +} + +.text-green-50 { + --tw-text-opacity: 1; + color: rgba(236, 253, 245, var(--tw-text-opacity)); +} + +.text-green-100 { + --tw-text-opacity: 1; + color: rgba(209, 250, 229, var(--tw-text-opacity)); +} + +.text-green-200 { + --tw-text-opacity: 1; + color: rgba(167, 243, 208, var(--tw-text-opacity)); +} + +.text-green-300 { + --tw-text-opacity: 1; + color: rgba(110, 231, 183, var(--tw-text-opacity)); +} + +.text-green-400 { + --tw-text-opacity: 1; + color: rgba(52, 211, 153, var(--tw-text-opacity)); +} + +.text-green-500 { + --tw-text-opacity: 1; + color: rgba(16, 185, 129, var(--tw-text-opacity)); +} + +.text-green-600 { + --tw-text-opacity: 1; + color: rgba(5, 150, 105, var(--tw-text-opacity)); +} + +.text-green-700 { + --tw-text-opacity: 1; + color: rgba(4, 120, 87, var(--tw-text-opacity)); +} + +.text-green-800 { + --tw-text-opacity: 1; + color: rgba(6, 95, 70, var(--tw-text-opacity)); +} + +.text-green-900 { + --tw-text-opacity: 1; + color: rgba(6, 78, 59, var(--tw-text-opacity)); +} + +.text-blue-50 { + --tw-text-opacity: 1; + color: rgba(239, 246, 255, var(--tw-text-opacity)); +} + +.text-blue-100 { + --tw-text-opacity: 1; + color: rgba(219, 234, 254, var(--tw-text-opacity)); +} + +.text-blue-200 { + --tw-text-opacity: 1; + color: rgba(191, 219, 254, var(--tw-text-opacity)); +} + +.text-blue-300 { + --tw-text-opacity: 1; + color: rgba(147, 197, 253, var(--tw-text-opacity)); +} + +.text-blue-400 { + --tw-text-opacity: 1; + color: rgba(96, 165, 250, var(--tw-text-opacity)); +} + +.text-blue-500 { + --tw-text-opacity: 1; + color: rgba(59, 130, 246, var(--tw-text-opacity)); +} + +.text-blue-600 { + --tw-text-opacity: 1; + color: rgba(37, 99, 235, var(--tw-text-opacity)); +} + +.text-blue-700 { + --tw-text-opacity: 1; + color: rgba(29, 78, 216, var(--tw-text-opacity)); +} + +.text-blue-800 { + --tw-text-opacity: 1; + color: rgba(30, 64, 175, var(--tw-text-opacity)); +} + +.text-blue-900 { + --tw-text-opacity: 1; + color: rgba(30, 58, 138, var(--tw-text-opacity)); +} + +.text-indigo-50 { + --tw-text-opacity: 1; + color: rgba(238, 242, 255, var(--tw-text-opacity)); +} + +.text-indigo-100 { + --tw-text-opacity: 1; + color: rgba(224, 231, 255, var(--tw-text-opacity)); +} + +.text-indigo-200 { + --tw-text-opacity: 1; + color: rgba(199, 210, 254, var(--tw-text-opacity)); +} + +.text-indigo-300 { + --tw-text-opacity: 1; + color: rgba(165, 180, 252, var(--tw-text-opacity)); +} + +.text-indigo-400 { + --tw-text-opacity: 1; + color: rgba(129, 140, 248, var(--tw-text-opacity)); +} + +.text-indigo-500 { + --tw-text-opacity: 1; + color: rgba(99, 102, 241, var(--tw-text-opacity)); +} + +.text-indigo-600 { + --tw-text-opacity: 1; + color: rgba(79, 70, 229, var(--tw-text-opacity)); +} + +.text-indigo-700 { + --tw-text-opacity: 1; + color: rgba(67, 56, 202, var(--tw-text-opacity)); +} + +.text-indigo-800 { + --tw-text-opacity: 1; + color: rgba(55, 48, 163, var(--tw-text-opacity)); +} + +.text-indigo-900 { + --tw-text-opacity: 1; + color: rgba(49, 46, 129, var(--tw-text-opacity)); +} + +.text-purple-50 { + --tw-text-opacity: 1; + color: rgba(245, 243, 255, var(--tw-text-opacity)); +} + +.text-purple-100 { + --tw-text-opacity: 1; + color: rgba(237, 233, 254, var(--tw-text-opacity)); +} + +.text-purple-200 { + --tw-text-opacity: 1; + color: rgba(221, 214, 254, var(--tw-text-opacity)); +} + +.text-purple-300 { + --tw-text-opacity: 1; + color: rgba(196, 181, 253, var(--tw-text-opacity)); +} + +.text-purple-400 { + --tw-text-opacity: 1; + color: rgba(167, 139, 250, var(--tw-text-opacity)); +} + +.text-purple-500 { + --tw-text-opacity: 1; + color: rgba(139, 92, 246, var(--tw-text-opacity)); +} + +.text-purple-600 { + --tw-text-opacity: 1; + color: rgba(124, 58, 237, var(--tw-text-opacity)); +} + +.text-purple-700 { + --tw-text-opacity: 1; + color: rgba(109, 40, 217, var(--tw-text-opacity)); +} + +.text-purple-800 { + --tw-text-opacity: 1; + color: rgba(91, 33, 182, var(--tw-text-opacity)); +} + +.text-purple-900 { + --tw-text-opacity: 1; + color: rgba(76, 29, 149, var(--tw-text-opacity)); +} + +.text-pink-50 { + --tw-text-opacity: 1; + color: rgba(253, 242, 248, var(--tw-text-opacity)); +} + +.text-pink-100 { + --tw-text-opacity: 1; + color: rgba(252, 231, 243, var(--tw-text-opacity)); +} + +.text-pink-200 { + --tw-text-opacity: 1; + color: rgba(251, 207, 232, var(--tw-text-opacity)); +} + +.text-pink-300 { + --tw-text-opacity: 1; + color: rgba(249, 168, 212, var(--tw-text-opacity)); +} + +.text-pink-400 { + --tw-text-opacity: 1; + color: rgba(244, 114, 182, var(--tw-text-opacity)); +} + +.text-pink-500 { + --tw-text-opacity: 1; + color: rgba(236, 72, 153, var(--tw-text-opacity)); +} + +.text-pink-600 { + --tw-text-opacity: 1; + color: rgba(219, 39, 119, var(--tw-text-opacity)); +} + +.text-pink-700 { + --tw-text-opacity: 1; + color: rgba(190, 24, 93, var(--tw-text-opacity)); +} + +.text-pink-800 { + --tw-text-opacity: 1; + color: rgba(157, 23, 77, var(--tw-text-opacity)); +} + +.text-pink-900 { + --tw-text-opacity: 1; + color: rgba(131, 24, 67, var(--tw-text-opacity)); +} + +.opacity-0 { + opacity: 0; +} + +.opacity-5 { + opacity: 0.05; +} + +.opacity-10 { + opacity: 0.1; +} + +.opacity-20 { + opacity: 0.2; +} + +.opacity-25 { + opacity: 0.25; +} + +.opacity-30 { + opacity: 0.3; +} + +.opacity-40 { + opacity: 0.4; +} + +.opacity-50 { + opacity: 0.5; +} + +.opacity-60 { + opacity: 0.6; +} + +.opacity-70 { + opacity: 0.7; +} + +.opacity-75 { + opacity: 0.75; +} + +.opacity-80 { + opacity: 0.8; +} + +.opacity-90 { + opacity: 0.9; +} + +.opacity-95 { + opacity: 0.95; +} + +.opacity-100 { + opacity: 1; +} +.h-full { + height: 100%; +} +.h-screen { + height: 100vh !important; +} +.bg-gray-50 { + --tw-bg-opacity: 1; + background-color: rgba(249, 250, 251, var(--tw-bg-opacity)); +} +.bg-gray-100 { + --tw-bg-opacity: 1; + background-color: rgba(243, 244, 246, var(--tw-bg-opacity)); +} +.w-12 { + width: 3rem; +} +.min-w-16 { + min-width: 4rem; +} +.w-full { + width: 100%; +} + +.w-screen { + width: 100vw; +} + +.w-min { + width: min-content; +} + +.w-max { + width: max-content; +} + +.h-12 { + height: 3rem; +} +.h-4 { + height: 1rem; +} +.bg-white { + --tw-bg-opacity: 1; + background-color: rgba(255, 255, 255, var(--tw-bg-opacity)); +} +.bg-blue-100 { + --tw-bg-opacity: 1; + background-color: rgba(219, 234, 254, var(--tw-bg-opacity)); +} +.bg-blue-500 { + --tw-bg-opacity: 1; + background-color: rgba(59, 130, 246, var(--tw-bg-opacity)); +} +.text-green-400 { + --tw-text-opacity: 1; + color: rgba(52, 211, 153, var(--tw-text-opacity)); +} +.text-black { + --tw-text-opacity: 1; + color: rgba(0, 0, 0, var(--tw-text-opacity)); +} + +.text-white { + --tw-text-opacity: 1; + color: rgba(255, 255, 255, var(--tw-text-opacity)); +} + +.text-gray-50 { + --tw-text-opacity: 1; + color: rgba(249, 250, 251, var(--tw-text-opacity)); +} + +.text-gray-100 { + --tw-text-opacity: 1; + color: rgba(243, 244, 246, var(--tw-text-opacity)); +} + +.text-gray-200 { + --tw-text-opacity: 1; + color: rgba(229, 231, 235, var(--tw-text-opacity)); +} + +.text-gray-300 { + --tw-text-opacity: 1; + color: rgba(209, 213, 219, var(--tw-text-opacity)); +} + +.text-gray-400 { + --tw-text-opacity: 1; + color: rgba(156, 163, 175, var(--tw-text-opacity)); +} + +.text-gray-500 { + --tw-text-opacity: 1; + color: rgba(107, 114, 128, var(--tw-text-opacity)); +} + +.text-gray-600 { + --tw-text-opacity: 1; + color: rgba(75, 85, 99, var(--tw-text-opacity)); +} + +.text-gray-700 { + --tw-text-opacity: 1; + color: rgba(55, 65, 81, var(--tw-text-opacity)); +} + +.text-gray-800 { + --tw-text-opacity: 1; + color: rgba(31, 41, 55, var(--tw-text-opacity)); +} + +.text-gray-900 { + --tw-text-opacity: 1; + color: rgba(17, 24, 39, var(--tw-text-opacity)); +} + +.bg-green-100 { + --tw-bg-opacity: 1; + background-color: rgba(209, 250, 229, var(--tw-bg-opacity)); +} +.bg-green-300 { + --tw-bg-opacity: 1; + background-color: rgba(110, 231, 183, var(--tw-bg-opacity)); +} +.bg-green-400 { + --tw-bg-opacity: 1; + background-color: rgba(52, 211, 153, var(--tw-bg-opacity)); +} +.bg-green-400 { + --tw-bg-opacity: 1; + background-color: rgba(52, 211, 153, var(--tw-bg-opacity)); +} +.bg-blue-50 { + --tw-bg-opacity: 1; + background-color: rgba(239, 246, 255, var(--tw-bg-opacity)); +} +.rounded-full { + border-radius: 9999px; +} +.shadow-sm { + --tw-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow { + --tw-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-md { + --tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-lg { + --tw-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-xl { + --tw-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-2xl { + --tw-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-inner { + --tw-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-none { + --tw-shadow: 0 0 #0000; + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.border-gray-300 { + --tw-border-opacity: 1; + border-color: rgba(209, 213, 219, var(--tw-border-opacity)); +} + +.border-solid { + border-style: solid; +} + +.border-r-2 { + border-right-width: 2px; + border-top-width: 0; + border-left-width: 0; + border-bottom-width: 0; +} diff --git a/src/components/Calendar/Calendar.vue b/src/components/Calendar/Calendar.vue new file mode 100644 index 0000000..57afd47 --- /dev/null +++ b/src/components/Calendar/Calendar.vue @@ -0,0 +1,473 @@ + + + + + diff --git a/src/components/Calendar/generateDates.js b/src/components/Calendar/generateDates.js new file mode 100644 index 0000000..c08fc6a --- /dev/null +++ b/src/components/Calendar/generateDates.js @@ -0,0 +1,136 @@ +/* + *此函数的作用是根据传入的一个日期,返回这一周的日期或者这一个月的日期, + * 如果是月的话注意还包含上个月和下个月的日期,月的话总共数据有 6 * 7 = 42个 + * + */ +/* + * 时间格式化函数 + * 重要提示,微信小程序new Date('2020-04-16')在ios中无法获取时间对象 + * 解决方式: 建议将时间都格式化成'2020/04/16 00:00:00'的格式 + * 函数示例: formatDate(new Date(), 'YYYY/MM/dd hh:mm:ss') + */ +export const formatDate = (date, fmt) => { + if (/(y+)/.test(fmt)) { + fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)); + } + let o = { + 'M+': date.getMonth() + 1, + 'd+': date.getDate(), + 'h+': date.getHours(), + 'm+': date.getMinutes(), + 's+': date.getSeconds(), + }; + for (let k in o) { + if (new RegExp(`(${k})`).test(fmt)) { + let str = o[k] + ''; + fmt = fmt.replace(RegExp.$1, RegExp.$1.length === 1 ? str : padLeftZero(str)); + } + } + return fmt; +}; +const padLeftZero = str => { + return ('00' + str).substr(str.length); +}; + +// 判断是不是date对象 +export const judgeType = s => { + // 函数返回数据的具体类型 + return Object.prototype.toString.call(s).slice(8, -1); +}; + +export const equalDate = (d1, d2) => { + let result = false; + if (d1.getFullYear() === d2.getFullYear() && d1.getMonth() === d2.getMonth() && d1.getDate() === d2.getDate()) { + result = true; + } + return result; +}; + +/* 比较时间,时间格式为2020-04-04 + */ +export const dateEqual = (before, after) => { + before = new Date(before.replace('-', '/').replace('-', '/')); + after = new Date(after.replace('-', '/').replace('-', '/')); + if (before.getTime() - after.getTime() === 0) { + return true; + } else { + return false; + } +}; + +export const gegerateDates = (date = new Date(), type = 'week') => { + const result = []; + if (judgeType(date) === 'Date') { + // 年,月,日 + const y = date.getFullYear(); + const m = date.getMonth(); + const d = date.getDate(); + const days = new Date(y, m + 1, 0).getDate(); + // 获取日期是星期几 + // let weekIndex = date.getDay() === 0 ? 7 : date.getDay(); + let weekIndex = date.getDay(); + if (type === 'month') { + const dobj = new Date(y, m, 1); + // weekIndex = dobj.getDay() === 0 ? 7 : dobj.getDay(); + weekIndex = dobj.getDay(); + } + if (type === 'week') { + for (let i = weekIndex; i > 0; i--) { + const dtemp = new Date(y, m, d); + dtemp.setDate(dtemp.getDate() - i); + result.push({ + time: dtemp, + show: true, + fullDate: formatDate(dtemp, 'yyyy-MM-dd'), + isToday: equalDate(new Date(), dtemp), + }); + } + for (let i = 0; i <= 7 - weekIndex; i++) { + const dtemp = new Date(y, m, d); + dtemp.setDate(dtemp.getDate() + i); + result.push({ + time: dtemp, + show: true, + fullDate: formatDate(dtemp, 'yyyy-MM-dd'), + isToday: equalDate(new Date(), dtemp), + }); + } + } else if (type === 'month') { + // 上个月 + for (let i = weekIndex; i > 0; i--) { + const dtemp = new Date(y, m, 1); + dtemp.setDate(dtemp.getDate() - i); + result.push({ + time: dtemp, + show: false, + fullDate: formatDate(dtemp, 'yyyy-MM-dd'), + isToday: equalDate(new Date(), dtemp), + }); + } + // 这个月的日期 + for (let i = 0; i < days; i++) { + const dtemp = new Date(y, m, 1); + dtemp.setDate(dtemp.getDate() + i); + result.push({ + time: dtemp, + show: true, + fullDate: formatDate(dtemp, 'yyyy-MM-dd'), + isToday: equalDate(new Date(), dtemp), + }); + } + const len = 42 - result.length; + // 下个月的日期 + for (let i = 1; i <= len; i++) { + const dtemp = new Date(y, m + 1, 0); + dtemp.setDate(dtemp.getDate() + i); + result.push({ + time: dtemp, + show: false, + fullDate: formatDate(dtemp, 'yyyy-MM-dd'), + isToday: equalDate(new Date(), dtemp), + }); + } + } + } + return result; +}; diff --git a/src/components/Globals/Globals.vue b/src/components/Globals/Globals.vue new file mode 100644 index 0000000..2719a1e --- /dev/null +++ b/src/components/Globals/Globals.vue @@ -0,0 +1,86 @@ + + + + + diff --git a/src/components/ImageCode/ImageCode.vue b/src/components/ImageCode/ImageCode.vue new file mode 100644 index 0000000..c8a67b8 --- /dev/null +++ b/src/components/ImageCode/ImageCode.vue @@ -0,0 +1,37 @@ + + + + + diff --git a/src/components/PatientList/PatientList.vue b/src/components/PatientList/PatientList.vue new file mode 100644 index 0000000..b218abe --- /dev/null +++ b/src/components/PatientList/PatientList.vue @@ -0,0 +1,467 @@ + + + + + diff --git a/src/components/PatientList/icon/yanshi.png b/src/components/PatientList/icon/yanshi.png new file mode 100644 index 0000000000000000000000000000000000000000..11e6944d38130bf4281273b7ecf1ca47cb9817e8 GIT binary patch literal 2695 zcmV;23V8L2P)4586+ZXPc$tZ_fD%A#b|I}zYoSyv1xg_Mvts+5}v1m)E z&#Rni#%-Hs__Gic!{1DNn#K-B#MxpkLo8KL({5R5C#lA=sK!{hU$NuZgqRhi(Se=f znBRxZ@dX2FcvMzl0re23G*QHB92*oJ+9hIz$n*_}fsjS(p^+;0gp$n(rbLpC;qy5E zK69SVYLjZ}k(WUe<;vs&RLPqGv#ZIpaF}L{Y&zr@m@hyLU9#Q^&`st77=#Sah&@Zk zhC9S)A-lS%Q`T6eR4G!lPFVAR^@R<1Yp7jBy~_0j2+m#(XK&76UL$boC^VoPeW{l- z51a8im#lHj)8}QLynxtDAbhLo@KVxfBCdceVkgCPrC_=ey4Tt>)h{qdNjz8oK&w!uobAd9i2Vg7uyuhMNO}cAN8AGI zJLRn)iCPFO#cyK?N&gN=N(5$T>NwF9kH3njB2|t*L7|YKkKn6n_}h6~(mOD#-@9ct zcFUVEH)~8?%Dipr&*fKH0kLMFiDnHZn=m!0pbcQA1JKHQ!!6>ZAJf~^D=)E#uEj!b z7jv|KphNu0e4hO)5TLuwbzr`}Y?{glNZE3j9xx9?>?CU@t?oM>k(ZVRX){3oYiNe{ zQAF5&fVjtQeqIKqW3&4Z42Rp`YU-5_=!aP| z?j339mDj^RJ{w5Tv%ijr_)>tlpS?38!*e0p295uA_+jym3Cgq>d_O+WBKEqUUj(RO zH>g>DK+O=`XWDFixBLv$f5lLX_*F51xMe{r_wso*&?f$(e`E6tmVls~%NC&YoeL>_ z0U+n}XL@$La3KLO7})#OgKgrM7ZQw?-OwX9!~9~{(6{w>ZlVC_y{0QH1k^2?bp*iF zJlHDw)52k9_q8U{*sr5z4reeRIn*KE^fS3Rmd_P7)wxZlL7uwD0uDuOsey(Qi0oJii_rQj5*{uVe2cNsIm# zOwpGpKrapK5dZW8N=FRlfePRMu9m?>CQM#8sagRIQ!_aJF+Y=1(ncitO+NGt%J6X2Bzt?$qEYl^&{o)J+cY1PwB%JfY#$os^j0Fkb?}U z8KF)Ue_@6>h}Z5pZ_|G zL?hx%t_hjNk|DYtb%m8yiY~#fPoxlkA&04EfF)D(yV-L3Xn^Pr5W#ZR((n#(T${RS z=3ao+|3F@hdA>NzC zIO8k>n0?UBI%s8u@-0E9>;Rp#lJp5=wNH8_h>u5PX;p}Jfc76vuhn3>q5)z}rIyo` zrcWq`CAt}m_CqFtuuWe8kSo}EaX=o@{^mzZ`2iV+Y9S_<-X(_&)V-wl;kd7|X(|7j zzg9C4Wtuk13#cWq4`~+kY6W>sE*s1FAq8_W91(<4v=+haKiG`47T9;nCh4?u4t-J* zy~&_JxwXn9!GgFyk&h%)=^3FM5<8VLcxE}KZEKDWqiEslG}qvi|0Jo7Lmc?&7Uet8 zl0JtRtQtcU($6G`60Fr++S<@9uPZ^dC>L#~Q*P6iIXevqy10;ol^3LZY8kaK(Wp2M z{sS|N25q{T+0UIido?*eSV8$Gb!xuoV9gf#Z0M3JOD)>Al+cG6RMRvsSZTzjufzpC zUPzR{GT@UB1tmT8YMYqk`$eHouHY1Y^ffH#r9y+#rY`wy?et1xVY=V8=-ooKql*1R zcMY|QpJbwJ6`VS#Go}w9jL#t)vWMHnAHAA{IgS}FWz*ZycJX&7maEO@^ttANHf~A6 z(e`!ZNFNka%Nf6rM8b_b21@lV56uNi0;&o5<>UZ3TK zBNcgfc$fHV8jP!Fl(Q7IjybZ5L5Cs5jK{w)P0u3)zT5;qR ze(^c8<{WK=302LZ;iUOnqB+wi}6#QPkrmh>Z+IenC3TQk@ z`_0w~k1a||QcvoqY0Op4667{$0EhAXSQ1U+(m9GFew#c#;WUj`P({F|<)Gkj5KUuf zw;Hk8bP6n{!xal0KxLm%Adsj zB*Oo*s4JX6E;Od2W)sK-YwPPtK2$GWm^ + + + + + + + + + + + + + + + + + + + {{ item.name }} + + 进行中 + + + + {{ $moment(+item.startTime).format('MM-DD HH:mm') }} + 至 + {{ $moment(+item.endTime).format('MM-DD HH:mm') }} + + + + + + + + + + + + + + + + + + + + {{ subItem.name }} + + + {{ subItem.status === 0 ? '未开始' : subItem.status === 1 ? '进行中' : subItem.status === 2 ? '暂停' : '已完成' }} + + + + + + + + + + + + + + + + v1.7.1 + + + + + + + + + + + + + + diff --git a/src/components/Projects/ProjectItem.vue b/src/components/Projects/ProjectItem.vue new file mode 100644 index 0000000..249140f --- /dev/null +++ b/src/components/Projects/ProjectItem.vue @@ -0,0 +1,161 @@ + + + + + diff --git a/src/components/Projects/Projects.vue b/src/components/Projects/Projects.vue new file mode 100644 index 0000000..1a3c49e --- /dev/null +++ b/src/components/Projects/Projects.vue @@ -0,0 +1,65 @@ + + + diff --git a/src/components/Roles/Roles.vue b/src/components/Roles/Roles.vue new file mode 100644 index 0000000..406e41e --- /dev/null +++ b/src/components/Roles/Roles.vue @@ -0,0 +1,264 @@ + + + + + diff --git a/src/components/Service/Service.vue b/src/components/Service/Service.vue new file mode 100644 index 0000000..7892314 --- /dev/null +++ b/src/components/Service/Service.vue @@ -0,0 +1,33 @@ + + + diff --git a/src/components/Service/icon/tel-we.png b/src/components/Service/icon/tel-we.png new file mode 100644 index 0000000000000000000000000000000000000000..3e6d5ec7cf55d398e8ffcd95bdddddce3431abfa GIT binary patch literal 6928 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 aCw%Hy8YH0~Q*(y6AZT4 + + + + + + + + + + + + diff --git a/src/components/TimeLine/component/Barrier.vue b/src/components/TimeLine/component/Barrier.vue new file mode 100644 index 0000000..590e4f9 --- /dev/null +++ b/src/components/TimeLine/component/Barrier.vue @@ -0,0 +1,42 @@ + + + + diff --git a/src/components/TimeLine/component/TaskTools.vue b/src/components/TimeLine/component/TaskTools.vue new file mode 100644 index 0000000..a5d31fb --- /dev/null +++ b/src/components/TimeLine/component/TaskTools.vue @@ -0,0 +1,185 @@ + + + + + diff --git a/src/components/TimeLine/component/TimeBox.vue b/src/components/TimeLine/component/TimeBox.vue new file mode 100644 index 0000000..9ce1ac0 --- /dev/null +++ b/src/components/TimeLine/component/TimeBox.vue @@ -0,0 +1,142 @@ + + + + + diff --git a/src/components/TimeLine/component/TimeStatus.vue b/src/components/TimeLine/component/TimeStatus.vue new file mode 100644 index 0000000..7055166 --- /dev/null +++ b/src/components/TimeLine/component/TimeStatus.vue @@ -0,0 +1,231 @@ + + + + + diff --git a/src/components/TimeLine/component/Title.vue b/src/components/TimeLine/component/Title.vue new file mode 100644 index 0000000..fafec0b --- /dev/null +++ b/src/components/TimeLine/component/Title.vue @@ -0,0 +1,7 @@ + diff --git a/src/components/Title/Title.vue b/src/components/Title/Title.vue new file mode 100644 index 0000000..a995bc4 --- /dev/null +++ b/src/components/Title/Title.vue @@ -0,0 +1,235 @@ + + + + + diff --git a/src/components/Title/components/CreateTask.vue b/src/components/Title/components/CreateTask.vue new file mode 100644 index 0000000..536c360 --- /dev/null +++ b/src/components/Title/components/CreateTask.vue @@ -0,0 +1,460 @@ + + + + + diff --git a/src/components/Title/components/ShareProject.vue b/src/components/Title/components/ShareProject.vue new file mode 100644 index 0000000..ddb9a4b --- /dev/null +++ b/src/components/Title/components/ShareProject.vue @@ -0,0 +1,210 @@ + + + + + diff --git a/src/components/Upload/Upload.vue b/src/components/Upload/Upload.vue new file mode 100644 index 0000000..7fbde34 --- /dev/null +++ b/src/components/Upload/Upload.vue @@ -0,0 +1,201 @@ + + + + + diff --git a/src/components/select-lay/select-lay.vue b/src/components/select-lay/select-lay.vue new file mode 100644 index 0000000..d42107e --- /dev/null +++ b/src/components/select-lay/select-lay.vue @@ -0,0 +1,418 @@ + + + + + diff --git a/src/config/app.js b/src/config/app.js new file mode 100644 index 0000000..7e2500c --- /dev/null +++ b/src/config/app.js @@ -0,0 +1,6 @@ +export default { + V: process.env.VUE_APP_VERSION, + version: process.env.VUE_APP_VERSION, + theme: [], + tokenKey: 'anyringToken', // storage token key +}; diff --git a/src/config/db.js b/src/config/db.js new file mode 100644 index 0000000..2f0d965 --- /dev/null +++ b/src/config/db.js @@ -0,0 +1,3 @@ +export const db = null; // indexedDB 对象 +export const name = 'TALL_indexedDB'; // indexDB name +export const version = 1; // indexDB version diff --git a/src/config/plugin.js b/src/config/plugin.js new file mode 100644 index 0000000..a12856b --- /dev/null +++ b/src/config/plugin.js @@ -0,0 +1,97 @@ +// 定义插件相关信息 +/* eslint-disable */ +export default { + defaults: [ + { + id: 1, + name: 'TASK_NAME', + description: '任务名插件', + component: 'p-task-title', + }, + { + id: 2, + name: 'TASK_DESCRIPTION', + description: '任务描述插件', + component: 'p-task-description', + }, + { + id: 3, + name: 'TASK_DURATION_DELAY', + description: '任务时长延迟插件(+-1min)时间格式可设置', + component: 'p-task-duration-delay', + }, + { + id: 4, + name: 'TASK_START_TIME_DELAY', + description: '任务开始时间延迟插件(+-1hour)', + component: 'p-task-start-time-delay', + }, + { + id: 5, + name: 'DELIVERABLE', + description: '交付物插件(人 + 交付物)可配置【仅人】 or 【仅交付物】 or 【人+交付物】', + component: 'p-deliverable', + }, + { + id: 6, + name: 'SUBTASKS', + description: '子任务插件:显示子任务', + component: 'p-subtasks', + }, + { + id: 7, + name: 'SUB_PROJECT', + description: '子项目插件:显示子项目', + component: 'p-sub-project', + }, + { + id: 8, + name: 'TASK_COUNTDOWN', + description: '任务倒计时插件', + component: 'p-task-countdown', + }, + { + id: 9, + name: 'MANAGE_PROJECT', + description: '项目信息管理插件', + component: 'p-manage-project', + }, + + { + id: 10, + name: 'MANAGE_ROLE', + description: '角色信息管理插件', + component: 'p-manage-role', + }, + { + id: 11, + name: 'MANAGE_MEMBER', + description: '成员信息管理插件', + component: 'p-manage-member', + }, + { + id: 12, + name: 'MANAGE_TASK', + description: '任务信息管理插件', + component: 'p-manage-task', + }, + { + id: 13, + name: 'WBS_IMPORT', + description: '导入WBS新建项目', + component: 'p-wbs-import', + }, + { + id: 14, + name: 'WBS_IMPORT_UPDATE', + description: '导入WBS更新项目', + component: 'p-wbs-update', + }, + { + id: 15, + name: 'DELIVER_CHECK', + description: '交付物检查', + component: 'p-deliver-check', + }, + ], // 默认插件id列表 +}; diff --git a/src/config/task.js b/src/config/task.js new file mode 100644 index 0000000..95327d7 --- /dev/null +++ b/src/config/task.js @@ -0,0 +1,2 @@ +// 每页加载颗粒度的个数 +export default { pageCount: 10 }; diff --git a/src/config/time.js b/src/config/time.js new file mode 100644 index 0000000..27e412e --- /dev/null +++ b/src/config/time.js @@ -0,0 +1,17 @@ +export default { + timeUnits: [ + // 时间颗粒度 + { id: 0, value: '毫秒', format: 'x', cycle: 'YY-M-D HH:mm:ss', granularity: 'millisecond' }, + { id: 1, value: '秒', format: 'x', cycle: 'YY-M-D HH:mm:ss', granularity: 'second' }, + { id: 2, value: '分', format: 'ss', cycle: 'YY-M-D HH:mm', granularity: 'minute' }, + { id: 3, value: '时', format: 'mm', cycle: 'YY-M-D HH时', granularity: 'hour' }, + { id: 4, value: '天', format: 'D日 HH:mm', cycle: 'YY-M-D', granularity: 'day' }, + { id: 5, value: '周', format: 'D日 HH:mm', cycle: '', granularity: 'week' }, + { id: 6, value: '月', format: 'D日 H:m', cycle: 'YYYY年', granularity: 'month' }, + { id: 7, value: '季度', format: '', cycle: 'YYYY年', granularity: 'quarter' }, + { id: 8, value: '年', format: 'YYYY', cycle: '', granularity: 'year' }, + { id: 9, value: '年代', format: '', cycle: '', granularity: '' }, + { id: 10, value: '世纪', format: '', cycle: '', granularity: '' }, + { id: 11, value: '千年', format: '', cycle: '', granularity: '' }, + ], +}; diff --git a/src/config/user copy.js b/src/config/user copy.js new file mode 100644 index 0000000..a27a905 --- /dev/null +++ b/src/config/user copy.js @@ -0,0 +1,43 @@ +// 用户登录client +export const clients = { mp: 0, h5: 1, android: 2, ios: 3 }; + +// 用户登录类型 +export const types = { + mp: 0, + phone: 1, + email: 2, + username: 3, + wx: 4, + wx_web: 5, + wb: 6, +}; + +// 小程序获取参数 +export const mp = () => { + return new Promise((resolve, reject) => { + uni.login({ + provider: 'weixin', + success(res) { + if (res.code) { + const params = { + client: uni.$t.user.clients['mp'], + type: uni.$t.user.types['mp'], + data: { identifier: res.code }, + }; + resolve(params); + } else { + reject(res.errMsg); + } + }, + fail() { + console.log('fail'); + reject('微信登录失败'); + }, + }); + }); +}; + +export default { + clients, + types, +}; diff --git a/src/config/user.js b/src/config/user.js new file mode 100644 index 0000000..4e2d829 --- /dev/null +++ b/src/config/user.js @@ -0,0 +1,44 @@ +// 用户登录client +export const clients = { mp: 0, h5: 1, android: 2, ios: 3 }; + +// 用户登录类型 +export const types = { + mp: 0, + phone: 1, + email: 2, + username: 3, + wx: 4, + wx_web: 5, + wb: 6, +}; + +// 小程序获取参数 +export const mp = () => { + return new Promise((resolve, reject) => { + uni.login({ + provider: 'weixin', + success(res) { + if (res.code) { + const params = { + client: uni.$t.user.clients['mp'], + type: uni.$t.user.types['mp'], + data: { identifier: res.code, credential: 'basicCar' }, + // data: { identifier: res.code, credential: 'tall' }, + }; + resolve(params); + } else { + reject(res.errMsg); + } + }, + fail() { + console.log('fail'); + reject('微信登录失败'); + }, + }); + }); +}; + +export default { + clients, + types, +}; diff --git a/src/config/zIndex.js b/src/config/zIndex.js new file mode 100644 index 0000000..4d1dab2 --- /dev/null +++ b/src/config/zIndex.js @@ -0,0 +1,5 @@ +// 定义项目中定位的元素的层级 +/* eslint-disable */ +export default { + roleBar: 999, // 角色栏成绩 +}; diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..9318d85 --- /dev/null +++ b/src/main.js @@ -0,0 +1,52 @@ +import App from './App'; +import Tall from '@/utils/tall'; +import Vue from 'vue'; +import request from '@/utils/request.js'; +import dayjs from 'dayjs'; +import project from '@/apis/project.js'; +import role from '@/apis/role.js'; +import store from './store'; +import tall from '@/apis/tall.js'; +import task from '@/apis/task.js'; +import carbasics from '@/apis/carbasics.js'; +import uView from 'uview-ui'; +import wbs from '@/apis/wbs.js'; + +//#ifdef H5 +// import './registerServiceWorker'; +// import AlloyFinger from 'alloyfinger'; +// import AlloyFingerPlugin from 'alloyfinger/vue/alloy_finger_vue'; +// Vue.use(AlloyFingerPlugin, { AlloyFinger }); +// indexedDB +// import indexedDB from '@/utils/indexedDB'; +// Vue.use(indexedDB); +//#endif + +Vue.config.productionTip = false; +Vue.prototype.$moment = dayjs; +Vue.use(uView); +Vue.use(Tall); + +uni.$moment = dayjs; + +dayjs.locale('zh-cn'); + +App.mpType = 'app'; + +const app = new Vue({ ...App, store }); + +const obj = { title: '暴风眼Typhoneye' }; +uni.showShareMenu(obj); +uni.onShareAppMessage = function () { + return { title: '暴风眼Typhoneye', path: '/pages/index/index' }; +}; + +Vue.use(request, app); +Vue.use(tall, app); +Vue.use(project, app); +Vue.use(role, app); +Vue.use(carbasics, app); +Vue.use(task, app); +Vue.use(wbs, app); + +app.$mount(); diff --git a/src/manifest.json b/src/manifest.json new file mode 100644 index 0000000..0930470 --- /dev/null +++ b/src/manifest.json @@ -0,0 +1,81 @@ +{ + "name": "暴风眼Typhoneye", + "appid": "wx3190e3f68dd4d068", + "description": "", + "versionName": "1.0.0", + "versionCode": "100", + "transformPx": false, + "app-plus": { + /* 5+App特有相关 */ "usingComponents": true, + "splashscreen": { + "alwaysShowBeforeRender": true, + "waiting": true, + "autoclose": true, + "delay": 0 + }, + "modules": { + /* 模块配置 */ + }, + "distribute": { + /* 应用发布信息 */ + "android": { + /* android打包配置 */ + "permissions": [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ] + }, + "ios": { + /* ios打包配置 */ + }, + "sdkConfigs": { + /* SDK配置 */ + } + } + }, + "quickapp": { + /* 快应用特有相关 */ + }, + "mp-weixin": { + "appid": "wx3190e3f68dd4d068", + "setting": { + "urlCheck": false + }, + "usingComponents": true + }, + + "h5": { + "router": { + "base": "/carBasicCalendar" + }, + "title": "暴风眼Typhoneye", + "sdkConfigs": { + "maps": {} + }, + "optimization": { + "treeShaking": { + "enable": false + } + } + } +} diff --git a/src/mixins/userAuth.js b/src/mixins/userAuth.js new file mode 100644 index 0000000..ec24bb2 --- /dev/null +++ b/src/mixins/userAuth.js @@ -0,0 +1,48 @@ +import { mapMutations, mapState } from 'vuex'; + +import { waitTokenRequest } from '@/utils/cacheAndRequest'; + +export default { + computed: mapState('user', ['token', 'user']), + methods: { + ...mapMutations('user', ['setUser']), + // 获取授权 + openAuth() { + if (this.user && this.user.wxInfo && this.user.wxInfo.nickname) return; // 用户信息里有微信信息就不用再获取了 + if (this.token) { + this.updateUserInfo(); + } else { + waitTokenRequest(this.updateUserInfo); + } + }, + + // 弹出授权框 + // 用户允许后 提交微信用户信息 + updateUserInfo() { + /* #ifdef MP-WEIXIN */ + uni.getUserProfile({ + desc: '仅需要获取您的基本用户信息', + success: async res => { + const { avatarUrl, city, country, gender, language, nickName, province } = res.userInfo; + const data = await this.$u.api.updateUserInfo({ + city, + country, + headImgUrl: avatarUrl, + language, + nickname: nickName, + province, + sex: gender, + }); + console.log('data: ', data); + const { user } = this; + user.wxInfo = data; + this.setUser(user); + }, + fail: error => { + console.log('error: ', error); + }, + }); + /* #endif */ + }, + }, +}; diff --git a/src/pages.json b/src/pages.json new file mode 100644 index 0000000..9e7aadf --- /dev/null +++ b/src/pages.json @@ -0,0 +1,78 @@ +{ + "pages": [ + { + "path": "pages/index/index", + "style": { + "navigationBarText": "暴风眼Typhoneye" + } + }, + { + "path": "pages/get-phone-power/get-phone-power", + "style": { + "navigationBarTitleText": "宣传页" + } + }, + { + "path": "pages/phone-bind/phone-bind", + "style": { + "navigationBarTitleText": "绑定手机号" + } + }, + { + "path": "pages/project-webview/project-webview", + "style": { + "navigationStyle": "custom", + "navigationBarTitleText": "暴风眼Typhoneye" + } + }, + { + "path": "pages/questionnaire-webview/questionnaire-webview", + "style": { + "navigationBarTitleText": "详情" + } + }, + { + "path": "pages/camera/camera", + "style": { + "navigationBarTitleText": "拍照" + } + }, + { + "path": "pages/task-page/task-page", + "style": { + "navigationBarTitleText": "项目详情页" + } + }, + { + "path": "pages/patientLine/patientLine", + "style": { + "navigationBarTitleText": "病例填写目录" + } + }, + { + "path": "pages/establish/establish", + "style": { + "navigationBarTitleText": "创建病例" + } + }, + { + "path": "pages/inner/inner", + "style": { + "navigationBarTitleText": "信息录入" + } + } + ], + "globalStyle": { + "navigationBarTextStyle": "black", + "navigationBarTitleText": "暴风眼Typhoneye", + "navigationBarBackgroundColor": "#F8F8F8", + "backgroundColor": "#F8F8F8" + }, + "easycom": { + "autoscan": true, + "custom": { + "^u-(.*)": "uview-ui/components/u-$1/u-$1.vue", + "^p-(.*)": "@/plugins/p-$1/p-$1.vue" + } + } +} diff --git a/src/pages/camera/camera.vue b/src/pages/camera/camera.vue new file mode 100644 index 0000000..5b65abd --- /dev/null +++ b/src/pages/camera/camera.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/src/pages/establish/establish.vue b/src/pages/establish/establish.vue new file mode 100644 index 0000000..05b2b8a --- /dev/null +++ b/src/pages/establish/establish.vue @@ -0,0 +1,444 @@ + + + + + diff --git a/src/pages/establish/icon/bottom.png b/src/pages/establish/icon/bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..684f6c7ef65f53c3a5062057e16bb5bfe917f0b3 GIT binary patch literal 8173 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 literal 0 HcmV?d00001 diff --git a/src/pages/establish/icon/idcard.png b/src/pages/establish/icon/idcard.png new file mode 100644 index 0000000000000000000000000000000000000000..9203830353f7b98cf0a134c6786d448f61d0caf7 GIT binary patch literal 4185 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 literal 0 HcmV?d00001 diff --git a/src/pages/get-phone-power/get-phone-power.vue b/src/pages/get-phone-power/get-phone-power.vue new file mode 100644 index 0000000..68704b7 --- /dev/null +++ b/src/pages/get-phone-power/get-phone-power.vue @@ -0,0 +1,156 @@ + + + + + diff --git a/src/pages/index/index.vue b/src/pages/index/index.vue new file mode 100644 index 0000000..6548e55 --- /dev/null +++ b/src/pages/index/index.vue @@ -0,0 +1,170 @@ + + + + + diff --git a/src/pages/inner/inner.vue b/src/pages/inner/inner.vue new file mode 100644 index 0000000..90f7fb7 --- /dev/null +++ b/src/pages/inner/inner.vue @@ -0,0 +1,36 @@ + + + + + diff --git a/src/pages/patientLine/patientLine.vue b/src/pages/patientLine/patientLine.vue new file mode 100644 index 0000000..8c9602f --- /dev/null +++ b/src/pages/patientLine/patientLine.vue @@ -0,0 +1,181 @@ + + + + diff --git a/src/pages/patientLine/png/播放.png b/src/pages/patientLine/png/播放.png new file mode 100644 index 0000000000000000000000000000000000000000..32b72d3aa319f043f04961e807255311af0ccec0 GIT binary patch literal 9428 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 D + + + + + + + + + + + + + + + {{ codeTips }} + + + + + 提交 + + + + + + + + + + diff --git a/src/pages/project-webview/project-webview.vue b/src/pages/project-webview/project-webview.vue new file mode 100644 index 0000000..5ac04d3 --- /dev/null +++ b/src/pages/project-webview/project-webview.vue @@ -0,0 +1,41 @@ + + + diff --git a/src/pages/questionnaire-webview/questionnaire-webview.vue b/src/pages/questionnaire-webview/questionnaire-webview.vue new file mode 100644 index 0000000..48402c8 --- /dev/null +++ b/src/pages/questionnaire-webview/questionnaire-webview.vue @@ -0,0 +1,31 @@ + + + diff --git a/src/pages/task-page/task-page.vue b/src/pages/task-page/task-page.vue new file mode 100644 index 0000000..029e296 --- /dev/null +++ b/src/pages/task-page/task-page.vue @@ -0,0 +1,319 @@ + + + + + diff --git a/src/registerServiceWorker.js b/src/registerServiceWorker.js new file mode 100644 index 0000000..9e1e418 --- /dev/null +++ b/src/registerServiceWorker.js @@ -0,0 +1,29 @@ +/* eslint-disable no-console */ + +import { register } from 'register-service-worker'; + +if (process.env.NODE_ENV === 'production') { + register(`${process.env.BASE_URL}service-worker.js`, { + ready() { + console.log('App is being served from cache by a service worker.\n' + 'For more details, visit https://goo.gl/AFskqB'); + }, + registered() { + console.log('Service worker has been registered.'); + }, + cached() { + console.log('Content has been cached for offline use.'); + }, + updatefound() { + console.log('New content is downloading.'); + }, + updated() { + console.log('New content is available; please refresh.'); + }, + offline() { + console.log('No internet connection found. App is running in offline mode.'); + }, + error(error) { + console.error('Error during service worker registration:', error); + }, + }); +} diff --git a/src/store/carbasics/actions.js b/src/store/carbasics/actions.js new file mode 100644 index 0000000..5dfa3d4 --- /dev/null +++ b/src/store/carbasics/actions.js @@ -0,0 +1,3 @@ +const actions = {}; + +export default actions; diff --git a/src/store/carbasics/getters.js b/src/store/carbasics/getters.js new file mode 100644 index 0000000..56c8c75 --- /dev/null +++ b/src/store/carbasics/getters.js @@ -0,0 +1,3 @@ +const getters = {}; + +export default getters; diff --git a/src/store/carbasics/index.js b/src/store/carbasics/index.js new file mode 100644 index 0000000..d22f64a --- /dev/null +++ b/src/store/carbasics/index.js @@ -0,0 +1,12 @@ +import state from './state'; +import getters from './getters'; +import mutations from './mutations'; +import actions from './actions'; + +export default { + namespaced: true, + state, + getters, + mutations, + actions, +}; diff --git a/src/store/carbasics/mutations.js b/src/store/carbasics/mutations.js new file mode 100644 index 0000000..00b1440 --- /dev/null +++ b/src/store/carbasics/mutations.js @@ -0,0 +1,35 @@ +const mutations = { + /** + * 存储当前正在进行的患者的急救id + * @param { object } state + * @param { string } id + */ + setFirstAidId(state, id) { + state.firstAidId = id; + }, + /** + * 存储当前插件的param参数,包括url和其他具体参数 + * @param { object } state + * @param { object } data + */ + setGlobalData(state, data) { + state.globalData = { ...data }; + }, + /** + * 监听refreshList变化,重新请求病例列表数据 + * @param { object } state + */ + setRefreshList(state) { + state.refreshList = state.refreshList + 1; + }, + /** + * 信息录入界面默认为 RYPG(入院评估),当进入患者目录选择时,切换此code + * @param { object } state + * @param { string } data + */ + setInputCode(state, data) { + state.InputCode = data; + }, +}; + +export default mutations; diff --git a/src/store/carbasics/state.js b/src/store/carbasics/state.js new file mode 100644 index 0000000..341037f --- /dev/null +++ b/src/store/carbasics/state.js @@ -0,0 +1,12 @@ +const state = { + detailsData: { + valueType: 1, // 是否是演示模式 0:正式,1:演示 + type: 0, // 急救类型: 0:神内,1:神外 + }, // 当前项目在暴风眼内的信息 + firstAidId: '', // 当前正在进行数据录入的患者的急救id + globalData: null, // 插件的跳转路径及参数 + refreshList: 0, // 依据此值去重新请求病例列表(当从创建病例界面 创建了病例之后,修改此值,并且返回病例列表界面,病例列表重新查询数据) + InputCode: 'RYPG', +}; + +export default state; diff --git a/src/store/db/actions.js b/src/store/db/actions.js new file mode 100644 index 0000000..5dfa3d4 --- /dev/null +++ b/src/store/db/actions.js @@ -0,0 +1,3 @@ +const actions = {}; + +export default actions; diff --git a/src/store/db/getters.js b/src/store/db/getters.js new file mode 100644 index 0000000..56c8c75 --- /dev/null +++ b/src/store/db/getters.js @@ -0,0 +1,3 @@ +const getters = {}; + +export default getters; diff --git a/src/store/db/index.js b/src/store/db/index.js new file mode 100644 index 0000000..d22f64a --- /dev/null +++ b/src/store/db/index.js @@ -0,0 +1,12 @@ +import state from './state'; +import getters from './getters'; +import mutations from './mutations'; +import actions from './actions'; + +export default { + namespaced: true, + state, + getters, + mutations, + actions, +}; diff --git a/src/store/db/mutations.js b/src/store/db/mutations.js new file mode 100644 index 0000000..ea2bcc2 --- /dev/null +++ b/src/store/db/mutations.js @@ -0,0 +1,3 @@ +const mutations = {}; + +export default mutations; diff --git a/src/store/db/state.js b/src/store/db/state.js new file mode 100644 index 0000000..51d33c8 --- /dev/null +++ b/src/store/db/state.js @@ -0,0 +1,7 @@ +const state = { + db: null, // indexedDB对象 + name: 'TALL_indexedDB', + version: 1, +}; + +export default state; diff --git a/src/store/index.js b/src/store/index.js new file mode 100644 index 0000000..d23c7f6 --- /dev/null +++ b/src/store/index.js @@ -0,0 +1,52 @@ +import Vue from 'vue'; +import Vuex from 'vuex'; +import messages from './messages/index'; +import project from './project/index'; +import socket from './socket/index'; +import role from './role/index'; +import task from './task/index'; +import user from './user/index'; +import carbasics from './carbasics/index'; + +// 不属于具体模块的 应用级的 store内容 +const state = { + networkConnected: true, // 网络是否连接 + forceUseStorage: false, // 强制启用storage + systemInfo: null, // 系统设备信息 +}; + +const getters = { + // 是否启用本地存储 + // 设置了强制启用本地存储 或者 没有网络连接的时候 + useStorage({ networkConnected, forceUseStorage }) { + return forceUseStorage || !networkConnected; + }, + + // 是不是微信平台 + isWeChat({ systemInfo }) { + return !(!systemInfo || !systemInfo.host || systemInfo.host.env !== 'WeChat'); + }, +}; + +const mutations = { + /** + * 设置网络是否连接的变量 + * @param {*} state + * @param {boolean} networkConnected + */ + setNetworkConnected(state, networkConnected) { + state.networkConnected = networkConnected; + }, + + /** + * 设置系统信息的数据 + * @param {object} state + * @param {object | null} data 获取到的数据 + */ + setSystemInfo(state, data) { + state.systemInfo = data; + }, +}; + +Vue.use(Vuex); +export default new Vuex.Store({ state, getters, mutations, modules: { user, messages, socket, project, role, task, carbasics } }); diff --git a/src/store/messages/getters.js b/src/store/messages/getters.js new file mode 100644 index 0000000..56c8c75 --- /dev/null +++ b/src/store/messages/getters.js @@ -0,0 +1,3 @@ +const getters = {}; + +export default getters; diff --git a/src/store/messages/index.js b/src/store/messages/index.js new file mode 100644 index 0000000..48fb83c --- /dev/null +++ b/src/store/messages/index.js @@ -0,0 +1,4 @@ +import state from './state'; +import mutations from './mutations'; + +export default { namespaced: true, state, mutations }; diff --git a/src/store/messages/mutations.js b/src/store/messages/mutations.js new file mode 100644 index 0000000..52b6620 --- /dev/null +++ b/src/store/messages/mutations.js @@ -0,0 +1,86 @@ +import storage from '@/utils/storage'; + +const { setStorageSync, getStorageSync, removeStorageSync } = storage; + +const mutations = { + /** + * 初始化消息栈 + * @param {object} state + * @param {string} type + * type: + * syncMessages 同步消息栈 + * faultMessages 故障消息 未处理消息栈 + * faults 所有的故障消息栈 + */ + messagesInit(state, type) { + const messages = getStorageSync(type) ? JSON.parse(getStorageSync(type)) : []; + state[type] = messages; + }, + + /** + * 将新 消息添加到 消息栈 最前边 + * @param { object } state + * @param { object } data + * data: message, type + * message 消息对象 + * type: + * syncMessages 同步消息栈 + * faultMessages 故障消息 未处理消息栈 + * faults 所有的故障消息栈 + * game 游戏的消息 + * + * cache: boolean true 本地存储 false 不存储 + */ + messagesAdd(state, data) { + const messages = state[data.type]; + if (messages.length > 0) { + const result = messages.find(msg => msg.id === data.message.id); + if (result) return; + } + messages.unshift(data.message); + // eslint-disable-next-line no-param-reassign + state[data.type] = messages; + if (data.cache) { + setStorageSync(data.type, JSON.stringify(messages)); + } + }, + + /** + * 通过消息id移除指定 同步 消息 + * @param { object } state + * @param { object } data + * data: messageId, type + * messageId: 要移除的消息的messageId + * type: + * syncMessages 同步消息栈 + * faultMessages 故障消息 未处理消息栈 + * faults 所有的故障消息栈 + * cache: boolean true 本地存储 false 不存储 + */ + messagesRemoveById(state, data) { + const messages = state[data.type]; + const index = messages.findIndex(msg => msg.id === data.messageId); + if (index < 0) return; + messages.splice(index, 1); + // eslint-disable-next-line no-param-reassign + state[data.type] = messages; + if (data.cache) { + setStorageSync(data.type, JSON.stringify(messages)); + } + }, + + /** + * 清除指定type的消息 + * @param {any} state + * @param {object} data + * data: type, cache + */ + messagesClear(state, data) { + state[data.type] = []; + if (data.cache) { + removeStorageSync(data.type); + } + }, +}; + +export default mutations; diff --git a/src/store/messages/state.js b/src/store/messages/state.js new file mode 100644 index 0000000..de25201 --- /dev/null +++ b/src/store/messages/state.js @@ -0,0 +1,8 @@ +const state = { + syncMessages: [], // 同步消息 + faultMessages: [], // 新收到的未处理的 故障消息 + faults: [], // 所有的故障消息 + game: [], // 游戏的消息 +}; + +export default state; diff --git a/src/store/project/actions.js b/src/store/project/actions.js new file mode 100644 index 0000000..5dfa3d4 --- /dev/null +++ b/src/store/project/actions.js @@ -0,0 +1,3 @@ +const actions = {}; + +export default actions; diff --git a/src/store/project/getters.js b/src/store/project/getters.js new file mode 100644 index 0000000..39b22a7 --- /dev/null +++ b/src/store/project/getters.js @@ -0,0 +1,11 @@ +const getters = { + /** + * 当前项目的id + * @param {object} project + */ + projectId({ project }) { + return project.id; + }, +}; + +export default getters; diff --git a/src/store/project/index.js b/src/store/project/index.js new file mode 100644 index 0000000..d22f64a --- /dev/null +++ b/src/store/project/index.js @@ -0,0 +1,12 @@ +import state from './state'; +import getters from './getters'; +import mutations from './mutations'; +import actions from './actions'; + +export default { + namespaced: true, + state, + getters, + mutations, + actions, +}; diff --git a/src/store/project/mutations.js b/src/store/project/mutations.js new file mode 100644 index 0000000..3556aac --- /dev/null +++ b/src/store/project/mutations.js @@ -0,0 +1,71 @@ +const mutations = { + /** + * 设置state projects书籍 + * @param {object} state + * @param {array} projects 项目列表 + */ + setProjects(state, projects) { + if (!projects || !projects.length) { + state.projects = []; + } else { + state.projects = [...projects]; + } + }, + + /** + * 设置子项目收缩展开 + * @param { object } state + * @param { object } options options:{ index,show } + */ + setProjectItemShow(state, options) { + if (options.show) { + for (var i = 0; i < state.projects.length; i++) { + if (i === options.index) { + state.projects[i].show = true; + } else { + state.projects[i].show = false; + } + } + } else { + state.projects[options.index].show = false; + } + }, + + /** + * 设置当前项目信息 + * @param { object } state + * @param { object } data + */ + setProject(state, data) { + state.project = data || { name: '加载中...' }; + }, + + /** + * 设置当前项目名称 + * @param { object } state + * @param { string } data + */ + setProjectName(state, data) { + state.project.name = data; + }, + + /** + * 设置小红点 + * @param { object } state + * @param { string } data + */ + setDotList(state, data) { + state.dotList = data; + }, + + /** + * 设置当前项目的配置信息 + * @param { object } state + * @param { string } data + */ + setOrganData(state, data) { + state.organData = data; + }, +}; + +export default mutations; diff --git a/src/store/project/state.js b/src/store/project/state.js new file mode 100644 index 0000000..62240f5 --- /dev/null +++ b/src/store/project/state.js @@ -0,0 +1,9 @@ +/* eslint-disable */ +const state = { + project: { name: '加载中...' }, // 当前项目信息 + projects: [], // 项目列表 + dotList: [], // 小红点 + organData: null, +}; + +export default state; diff --git a/src/store/role/actions.js b/src/store/role/actions.js new file mode 100644 index 0000000..6d279b0 --- /dev/null +++ b/src/store/role/actions.js @@ -0,0 +1,17 @@ +const actions = { + /** + * 根据项目id查找所有成员信息 + * @param {*} commit + * @param {object} params + */ + async getAllMembers({ commit }, params) { + try { + const data = await uni.$u.api.queryChecker(params); + commit('setMembers', data); + } catch (error) { + uni.$t.ui.showToast(error.msg || '成员查询失败'); + } + }, +}; + +export default actions; diff --git a/src/store/role/getters.js b/src/store/role/getters.js new file mode 100644 index 0000000..6552b4a --- /dev/null +++ b/src/store/role/getters.js @@ -0,0 +1,13 @@ +const getters = { + // 是不是负责人 + isMine({ roleId, invisibleRoles, visibleRoles }) { + if (!visibleRoles || !visibleRoles.length) return false; + const visible = visibleRoles.find(visible => visible.id === roleId); + if (visible) return visible.mine; + const invisible = invisibleRoles.find(invisible => invisible.id === roleId); + if (invisible) return visible.mine; + return false; + }, +}; + +export default getters; diff --git a/src/store/role/index.js b/src/store/role/index.js new file mode 100644 index 0000000..d22f64a --- /dev/null +++ b/src/store/role/index.js @@ -0,0 +1,12 @@ +import state from './state'; +import getters from './getters'; +import mutations from './mutations'; +import actions from './actions'; + +export default { + namespaced: true, + state, + getters, + mutations, + actions, +}; diff --git a/src/store/role/mutations.js b/src/store/role/mutations.js new file mode 100644 index 0000000..fe26277 --- /dev/null +++ b/src/store/role/mutations.js @@ -0,0 +1,48 @@ +const mutations = { + /** + * 设置不展示的角色信息 + * @param {Object} state + * @param {Array} data 服务端返回的模板数组 + */ + setInvisibleRoles(state, data) { + state.invisibleRoles = data || []; + }, + + /** + * 设置展示的角色信息 + * @param {Object} state + * @param {Array} data 服务端返回的模板数组 + */ + setVisibleRoles(state, data) { + state.visibleRoles = data || []; + }, + + /** + * 设置当前角色信息 + * @param {Object} state + * @param {string} roleId 当前正在展示的角色的id + */ + setRoleId(state, roleId) { + state.roleId = roleId; + }, + + /** + * 设置项目下所有成员信息 + * @param {Object} state + * @param {Array} data 服务端返回的模板数组 + */ + setMembers(state, data) { + state.members = data || []; + }, + + /** + * 设置项目下所有体验橘色 + * @param {Object} state + * @param {Array} data 服务端返回的模板数组 + */ + setExperienceRole(state, data) { + state.experienceRole = data || []; + }, +}; + +export default mutations; diff --git a/src/store/role/state.js b/src/store/role/state.js new file mode 100644 index 0000000..ca9845f --- /dev/null +++ b/src/store/role/state.js @@ -0,0 +1,9 @@ +const state = { + invisibleRoles: [], // 不展示的角色信息 + visibleRoles: [], // 展示的角色信息 + roleId: '', // 当前展示查看的角色id + members: [], // 项目下所有成员 + experienceRole: [], // 所有体验项目的角色 +}; + +export default state; diff --git a/src/store/socket/actions.js b/src/store/socket/actions.js new file mode 100644 index 0000000..3e6e37e --- /dev/null +++ b/src/store/socket/actions.js @@ -0,0 +1,151 @@ +const WS_BASE_URL = process.env.VUE_APP_MSG_URL; + +let prevTime = 0; +let socketMsgQueue = []; // socket消息队列 +let sendHeartTimer = null; + +const actions = { + // 初始化socket + initSocket({ commit, dispatch, state, rootState }) { + if (state.lockSocket) return; + const { token } = rootState.user; + if (!token) return; + commit('setLockSocket', true); + commit('setSocket', uni.connectSocket({ url: WS_BASE_URL, complete: () => {} })); + dispatch('onSocketOpen'); + dispatch('onSocketMessage'); + dispatch('onSocketClose'); + state.socket.onError(errMsg => console.error(errMsg)); + commit('setLockSocket', false); + }, + + // 监听ws打开 + onSocketOpen({ dispatch, commit, state }) { + // eslint-disable-next-line no-unused-vars + state.socket.onOpen(res => { + // console.log('ws open: ', res); + commit('setConnected', true); + prevTime = Date.now(); + // this.auth(); + dispatch('auth'); + for (let i = 0; i < socketMsgQueue.length; i++) { + dispatch('sendSocketMessage', socketMsgQueue[i]); + } + socketMsgQueue = []; + }); + }, + + // 监听收到的ws消息 + onSocketMessage({ dispatch, state }) { + state.socket.onMessage(res => { + // console.log('收到消息:', res); + prevTime = Date.now(); + if (!res || !res.data || !JSON.parse(res.data)) return; + const resData = JSON.parse(res.data); + const { messageSet, ackId } = resData; + // 处理消息体对象 + messageSet.forEach(item => dispatch('handleMessagesData', item)); + ackId && dispatch('sendSocketMessage', { type: 'Ack', data: { ackId } }); + }); + }, + + /** + * 处理收到的消息内容 + * @param {object} item 单个消息体对象 + */ + handleMessagesData({ dispatch, commit }, item) { + const data = JSON.parse(item.data); + switch (data.type) { + case 'Sync': // 开始某个节点 + commit('messages/messagesAdd', { message: data, type: 'syncMessages' }, { root: true }); + break; + // case 'taskStatus': // 任务状态修改相关消息 + // commit('task/setTaskStatus', data.data, { root: true }); + // break; + // case 'Chrome': // !收到开始游戏的消息 + // console.log('handleMessagesData', data); + // // @ts-ignore + // util.openGameApp({ + // type: data.data.type, + // projectId: data.data.projectId, + // id: data.data.recordId, + // token: rootState.user.token, + // }); + // break; + // case 'Deliver': // 交付物相关消息 + // commit('messages/messagesAdd', { type: 'checkMessages', message: data }, { root: true }); + // break; + case 'ChannelStatus': + dispatch('handleAuthMessage', data); + break; + // case 'switchoverProject': // 康复相关消息 + // dispatch('home/getProjectById', data.data.projectId, { root: true }); + // break; + // case 'startDrill': // 康复开始训练相关消息 + // console.log('setStartDrillInfo', data.data); + // commit('home/setStartDrillMessages', data.data, { root: true }); + // break; + default: + break; + } + }, + + // 发送消息 + sendSocketMessage({ state }, data) { + if (state.connected) { + const msg = JSON.stringify({ toDomain: 'Server', data: JSON.stringify(data) }); + state.socket.send({ data: msg }); + } else { + socketMsgQueue.push(data); + } + }, + + // 监听关闭事件 + onSocketClose({ dispatch, commit, state }) { + // console.log('onSocketClose'); + state.socket.onClose(() => { + commit('setConnected', false); + if (sendHeartTimer) clearInterval(sendHeartTimer); + setTimeout(() => { + dispatch('initSocket'); + }, 300); + }); + }, + + // websocket发送channelId进行认证 + auth({ dispatch, rootState }) { + const { token } = rootState.user; + if (!token) return; + const data = { type: 'Auth', data: { token } }; + dispatch('sendSocketMessage', data); + }, + + // 心跳检测 + sendHeart({ dispatch, state }) { + if (sendHeartTimer) clearInterval(sendHeartTimer); + sendHeartTimer = setInterval(() => { + if (Date.now() - prevTime >= 15000) { + dispatch('sendSocketMessage', { type: 'Ping' }); + if (Date.now() - prevTime >= 20000) { + state.socket.close(); + } + } + }, 5000); + }, + + /** + * 处理auth认证返回的ChannelStatus消息 + * @param {object} data 消息内容对象 + */ + handleAuthMessage({ commit, dispatch }, data) { + if (data.data.authed) { + dispatch('sendHeart'); + } else { + uni.$u.toast('消息系统认证失败, 请退出重新登录'); + uni.$t.removeStorageSync('anyringToken'); + commit('setSocket', null); + } + }, +}; + +export default actions; diff --git a/src/store/socket/index.js b/src/store/socket/index.js new file mode 100644 index 0000000..f5a4ee5 --- /dev/null +++ b/src/store/socket/index.js @@ -0,0 +1,5 @@ +import state from './state'; +import mutations from './mutations'; +import actions from './actions'; + +export default { namespaced: true, state, mutations, actions }; diff --git a/src/store/socket/mutations.js b/src/store/socket/mutations.js new file mode 100644 index 0000000..7e53b1b --- /dev/null +++ b/src/store/socket/mutations.js @@ -0,0 +1,26 @@ +const mutations = { + // 设置socket实例 + setSocket(state, socket) { + state.socket = socket; + }, + + /** + * 设置socket连接状态 + * @param {Object} state + * @param {boolean} connected 是否连接 true -> 连接 + */ + setConnected(state, connected) { + state.connected = connected; + }, + + /** + * 设置连接锁 正在连接中 锁上 避免多个连接同时发出 + * @param {Object} state + * @param {boolean} lockSocket 是否正在连接的过程中 + */ + setLockSocket(state, lockSocket) { + state.lockSocket = lockSocket; + }, +}; + +export default mutations; diff --git a/src/store/socket/state.js b/src/store/socket/state.js new file mode 100644 index 0000000..d4aa6e3 --- /dev/null +++ b/src/store/socket/state.js @@ -0,0 +1,7 @@ +const state = { + socket: null, // websocket实例 + connected: false, // 是否处于连接状态 + lockSocket: false, // 是否正在连接状态 +}; + +export default state; diff --git a/src/store/task/actions.js b/src/store/task/actions.js new file mode 100644 index 0000000..40cdb31 --- /dev/null +++ b/src/store/task/actions.js @@ -0,0 +1,33 @@ +const actions = { + /** + * 根据角色查找永久的日常任务 + * @param {*} commit + * @param {string} roleId 角色id + */ + getPermanent({ commit }, param) { + uni.$t.$q.getPermanent(param, (err, data) => { + if (err) { + console.error('err: ', err); + } else { + commit('setPermanents', data); + } + }); + }, + + /** + * 根据时间和角色查找日常任务 + * @param {*} commit + * @param {object} param 请求参数 roleId, timeNode, timeUnit + */ + getGlobal({ commit }, param) { + uni.$t.$q.getGlobal(param, (err, data) => { + if (err) { + console.error('err: ', err); + } else { + commit('setDailyTasks', data); + } + }); + }, +}; + +export default actions; diff --git a/src/store/task/getters.js b/src/store/task/getters.js new file mode 100644 index 0000000..dcd7982 --- /dev/null +++ b/src/store/task/getters.js @@ -0,0 +1,23 @@ +const getters = { + // 所有的日常任务 永久 + 可变 日常任务 + globals({ dailyTasks, permanents }) { + return [...permanents, ...dailyTasks]; + }, + + unitConfig({ timeUnit }) { + const target = uni.$t.timeConfig.timeUnits.find(item => item.id === timeUnit); + return target; + }, + + // 计算任务开始时间的格式 + startTimeFormat(state, { unitConfig }) { + return unitConfig.format || 'D日 HH:mm'; + }, + + // 计算颗粒度 对应的 dayjs add 的单位 + timeGranularity(state, { unitConfig }) { + return unitConfig.granularity; + }, +}; + +export default getters; diff --git a/src/store/task/index.js b/src/store/task/index.js new file mode 100644 index 0000000..d22f64a --- /dev/null +++ b/src/store/task/index.js @@ -0,0 +1,12 @@ +import state from './state'; +import getters from './getters'; +import mutations from './mutations'; +import actions from './actions'; + +export default { + namespaced: true, + state, + getters, + mutations, + actions, +}; diff --git a/src/store/task/mutations.js b/src/store/task/mutations.js new file mode 100644 index 0000000..e465507 --- /dev/null +++ b/src/store/task/mutations.js @@ -0,0 +1,206 @@ +const mutations = { + /** + * 记录时间轴向上滚动的距离 + * @param { object } state + * @param { number } num + */ + setScrollTop(state, num) { + state.scrollTop = num; + }, + + /** + * 记录时间轴向上滚动的距离 + * @param { object } state + * @param {string} taskId + */ + setScrollToTaskId(state, taskId) { + state.scrollToTaskId = taskId; + }, + + /** + * 设置日常任务当前是否应该处于收缩状态 + * @param { object } state + * @param { boolean } data + */ + setShrink(state, data) { + state.isShrink = data; + }, + + /** + * 设置tip的值 + * @param {object} state + * @param {object} data + */ + setTip(state, data) { + if (!data) return; + state.tip = { ...data }; + }, + + /** + * 是否显示tips + * @param { object } state + * @param { boolean } show + */ + setTipShow(state, show) { + state.tip.show = show; + }, + + /** + * 是否显示tips + * @param { object } state + * @param { number } status + */ + setStatus(state, status) { + state.tip.status = status; + }, + + /** + * 设置时间基准点 + * @param { object } state + * @param { number } data + */ + setTimeNode(state, data) { + state.timeNode = data; + }, + + /** + * 设置时间颗粒度 + * @param { object } state + * @param { number } data + */ + setTimeUnit(state, data) { + state.timeUnit = data; + }, + + /** + * 设置向上查到的定期任务数据 + * @param {Object} state + * @param {Array} data 服务端返回的模板数组 + */ + setUpTasks(state, data) { + if (!state.tasks.length) { + state.tasks = [...data]; // 原来没有数据 + } else { + state.tasks = [...data, ...state.tasks]; + // state.tasks = [...data.concat(state.tasks)]; + } + }, + + /** + * 设置向下查到的定期任务数据 + * @param {Object} state + * @param {Array} data 服务端返回的模板数组 + */ + setDownTasks(state, data) { + if (!state.tasks && !state.tasks.length) { + state.tasks = [...data]; + } else { + state.tasks = [...state.tasks, ...data]; + // state.tasks = [...state.tasks.concat(data)]; + } + }, + + /** + * 添加任务后更新tasks + * @param {Object} state + * @param {Array} data 新添加的task + */ + updateTasks(state, data) { + state.tasks = [...data]; + }, + + /** + * 设置添加任务的位置 + * @param {*} state + * @param {*} data + */ + setAddPosition(state, data) { + console.log('data: ', data); + }, + + /** + * 设置日常任务数据 + * @param {Object} state + * @param {Array} data 服务端返回的模板数组 + */ + setDailyTasks(state, data) { + state.dailyTasks = data || []; + }, + + /** + * 设置永久固定任务 + * @param {object} state + * @param {array} tasks 服务端查询到的永久日常任务书籍 + */ + setPermanents(state, tasks) { + state.permanents = tasks || []; + }, + + /** + * 设置时间轴是否继续向上查任务 + * @param {Object} state + * @param {Boolean} show + */ + setTopEnd(state, show) { + state.topEnd = show; + }, + + /** + * 设置时间轴是否继续向下查任务 + * @param {Object} state + * @param {Boolean} show + */ + setBottomEnd(state, show) { + state.bottomEnd = show; + }, + + // 清空标志位 如切换角色等使用 + clearEndFlag(state) { + state.topEnd = false; + state.bottomEnd = false; + }, + + // 清空定期任务 + clearTasks(state) { + state.tasks = []; + }, + + /** + * 收到消息设置任务状态 + * @param {Object} state + * @param {Array} data 服务端返回的模板数组 + */ + setTaskStatus(state, data) { + const item = state.tasks.find(i => i.id === data.id); + item.process = data.taskStatus; + }, + + /** + * 收到打开新项目消息状态 + * @param {Object} state + * @param {Array} data 服务端返回的模板数组 + */ + setNewProjectInfo(state, data) { + state.newProjectInfo = data; + }, + + /** + * 设置骨架屏是否显示 + * @param {Object} state + * @param {Boolean} show + */ + setShowSkeleton(state, show) { + state.showSkeleton = show; + }, + + /** + * 是否设置时间轴自动滚动的位置 + * @param {Object} state + * @param {Boolean} show + */ + setShowScrollTo(state, show) { + state.showScrollTo = show; + }, +}; + +export default mutations; diff --git a/src/store/task/state.js b/src/store/task/state.js new file mode 100644 index 0000000..023378d --- /dev/null +++ b/src/store/task/state.js @@ -0,0 +1,25 @@ +const state = { + scrollTop: 0, + scrollToTaskId: '', // 时间轴自动滚动的位置 + isShrink: false, // true: 收起, false:展开 + tip: { + taskId: '', // 当前正在修改状态的任务的id + show: false, + status: 0, // 所点击任务的当前状态码 + text: '', + left: 0, // 鼠标点击位置距离左边的距离 + top: 0, // 鼠标点击位置距离上边的距离 + }, + timeNode: new Date().getTime(), // 时间基准点 + timeUnit: 4, // 时间颗粒度 + topEnd: false, // 时间轴向上查任务到顶了 + bottomEnd: false, // 时间轴向下查任务到底了 + permanents: [], // 永久日常任务 + dailyTasks: [], // 日常任务 + tasks: [], // 所有的定期任务 + showSkeleton: false, // 定期任务骨架屏 + newProjectInfo: {}, + showScrollTo: false, // 是否可以设置时间轴自动滚动的位置 +}; + +export default state; diff --git a/src/store/user/actions.js b/src/store/user/actions.js new file mode 100644 index 0000000..cdb2ca0 --- /dev/null +++ b/src/store/user/actions.js @@ -0,0 +1,19 @@ +const actions = { + /** + * 通过userId获取token + * @param {any} commit + * @param {string} userId 用户id + */ + async getToken({ commit }, userId) { + try { + const data = await uni.$u.api.getToken(userId); + commit('setToken', data.token); + commit('setUser', data); + return data; + } catch (error) { + uni.$t.ui.showToast(error.msg || '获取个人信息失败'); + } + }, +}; + +export default actions; diff --git a/src/store/user/getters.js b/src/store/user/getters.js new file mode 100644 index 0000000..f7988ce --- /dev/null +++ b/src/store/user/getters.js @@ -0,0 +1,14 @@ +const getters = { + // 获取用户的id + userId({ user }) { + try { + if (!user) return ''; + return user.id; + } catch (error) { + console.warn("user's getters 获取userId失败", error); + return ''; + } + }, +}; + +export default getters; diff --git a/src/store/user/index.js b/src/store/user/index.js new file mode 100644 index 0000000..d22f64a --- /dev/null +++ b/src/store/user/index.js @@ -0,0 +1,12 @@ +import state from './state'; +import getters from './getters'; +import mutations from './mutations'; +import actions from './actions'; + +export default { + namespaced: true, + state, + getters, + mutations, + actions, +}; diff --git a/src/store/user/mutations.js b/src/store/user/mutations.js new file mode 100644 index 0000000..6073c99 --- /dev/null +++ b/src/store/user/mutations.js @@ -0,0 +1,24 @@ +const mutations = { + /** + * 设置存储token + * @param {object} state + * @param {string} token + */ + setToken(state, token) { + state.token = token || ''; + uni.$t.storage.setStorageSync(uni.$t.app.tokenKey, token || ''); + }, + + /** + * 设置user数据 + * @param {object} state + * @param {object} user + */ + setUser(state, user) { + if (!user) return; + state.user = { ...user }; + uni.$t.storage.setStorageSync('user', JSON.stringify(user)); + }, +}; + +export default mutations; diff --git a/src/store/user/state.js b/src/store/user/state.js new file mode 100644 index 0000000..39f592e --- /dev/null +++ b/src/store/user/state.js @@ -0,0 +1,5 @@ +const state = { + token: '', + user: null, +}; +export default state; diff --git a/src/uni.scss b/src/uni.scss new file mode 100644 index 0000000..a0afbc8 --- /dev/null +++ b/src/uni.scss @@ -0,0 +1,76 @@ +/** + * 这里是uni-app内置的常用样式变量 + * + * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量 + * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App + * + */ + +/** + * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能 + * + * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件 + */ +@import 'uview-ui/theme.scss'; +/* 颜色变量 */ /* 行为相关颜色 */ +$uni-color-primary: #0284c7; +$uni-color-success: #4cd964; +$uni-color-warning: #f0ad4e; +$uni-color-error: #dd524d; + +/* 文字基本颜色 */ +$uni-text-color: #333; //基本色 +$uni-text-color-inverse: #fff; //反色 +$uni-text-color-grey: #999; //辅助灰色,如加载更多的提示信息 +$uni-text-color-placeholder: #808080; +$uni-text-color-disable: #c0c0c0; +$roleChoiceColor: #f59e0b; + +/* 背景颜色 */ +$uni-bg-color: #ffffff; +$uni-bg-color-grey: #f8f8f8; +$uni-bg-color-hover: #f1f1f1; //点击状态颜色 +$uni-bg-color-mask: rgba(0, 0, 0, 0.4); //遮罩颜色 +$uni-bg-color-transparent: rgba(255, 255, 255, 0); //透明色 + +/* 边框颜色 */ +$uni-border-color: #c8c7cc; + +/* 尺寸变量 */ + +/* 文字尺寸 */ +$uni-font-size-sm: 24rpx; +$uni-font-size-base: 28rpx; +$uni-font-size-lg: 32rpx; + +/* 图片尺寸 */ +$uni-img-size-sm: 40rpx; +$uni-img-size-base: 52rpx; +$uni-img-size-lg: 80rpx; + +/* Border Radius */ +$uni-border-radius-sm: 4rpx; +$uni-border-radius-base: 6rpx; +$uni-border-radius-lg: 12rpx; +$uni-border-radius-circle: 50%; + +/* 水平间距 */ +$uni-spacing-row-sm: 10px; +$uni-spacing-row-base: 20rpx; +$uni-spacing-row-lg: 30rpx; + +/* 垂直间距 */ +$uni-spacing-col-sm: 8rpx; +$uni-spacing-col-base: 16rpx; +$uni-spacing-col-lg: 24rpx; + +/* 透明度 */ +$uni-opacity-disabled: 0.3; // 组件禁用态的透明度 + +/* 文章场景相关 */ +$uni-color-title: #2c405a; // 文章标题颜色 +$uni-font-size-title: 40rpx; +$uni-color-subtitle: #555555; // 二级标题颜色 +$uni-font-size-subtitle: 36rpx; +$uni-color-paragraph: #3f536e; // 文章段落颜色 +$uni-font-size-paragraph: 30rpx; diff --git a/src/utils/cache.js b/src/utils/cache.js new file mode 100644 index 0000000..b59f5f0 --- /dev/null +++ b/src/utils/cache.js @@ -0,0 +1,176 @@ +export const filter = { + /** + * 角色 过滤获取到的数据 根据开始截止时间 + * @param {object} data 缓存拿到的数据 + * @returns + */ + roles(data) { + if (!data || !data.length) return []; + return data; + }, + + /** + * 过滤获取到的数据 根据开始截止时间 + * @param {object} data 缓存拿到的数据 + * @param {number} start ms + * @param {number} end ms + * @returns + */ + projects(data, start, end) { + if (!data || !data.length) return []; + return data.filter(item => start <= +item.endTime && end >= +item.startTime); + }, +}; + +export default { + /** + * 当前显示的角色信息 获取 + * @param {object} params + * @returns + */ + async getShowRole(projectId) { + try { + const data = await uni.$t.storage.getStorage(`roles_${projectId}`); + return filter.roles(JSON.parse(data)); + } catch (error) { + return null; + } + }, + + /** + * 当前显示的角色信息 存 + * @param {array} data + */ + putShowRole(projectId, data) { + try { + if (!data || !data.visibleList || !data.visibleList.length) return; // 服务端没数据不做操作 + let value = uni.$t.storage.getStorageSync(`roles_${projectId}`); + let locals = value ? JSON.parse(value) : null; + if (!locals || !locals.length) { + // 本地没数据 + locals = data || null; + } else { + // 本地有数据 + data.invisibleList.forEach(item => { + let invisibleListLocalData = locals.invisibleList.find(local => item.id === local.id); + if (invisibleListLocalData) { + // 有相同数据 就用新的data里的数据 + invisibleListLocalData = item; + } else { + // 没有就直接存本地 + locals.invisibleList.push(item); + } + }); + data.visibleList.forEach(item => { + let localData = locals.visibleList.find(local => item.id === local.id); + if (localData) { + // 有相同数据 就用新的data里的数据 + localData = item; + } else { + // 没有就直接存本地 + locals.visibleList.push(item); + } + }); + } + uni.$t.storage.setStorage(`roles_${projectId}`, locals); + } catch (error) { + console.error('error: ', error); + uni.$t.storage.setStorage(`roles_${projectId}`, []); + } + }, + + /** + * 永久的日常任务 获取 + * @param {number} startTime + * @param {number} endTime + * @returns + */ + async getStoragePermanent(params) { + try { + const data = await uni.$t.storage.getStorage(`fixed_tasks_${params.projectId}_${params.roleId}`); + return filter.fixedTasks(JSON.parse(data)); + } catch (error) { + return []; + } + }, + + /** + * 永久的日常任务 存 + * @param {array} data + */ + putStoragePermanent(params, data) { + try { + if (!data || !data.length) return; // 服务端没数据不做操作 + let value = uni.$t.storage.getStorageSync(`fixed_tasks_${params.projectId}_${params.roleId}`); + let locals = value ? JSON.parse(value) : []; + if (!locals || !locals.length) { + // 本地没数据 + locals = data || []; + } else { + // 本地有数据 + data.forEach((item, index) => { + let localData = locals.find(local => item.detailId === local.detailId); + if (localData) { + // 有相同数据 就用新的data里的数据 + localData = item; + } else { + locals.splice(index, 1); + // 没有就直接存本地 + locals.push(item); + } + }); + } + uni.$t.storage.setStorage(`fixed_tasks_${params.projectId}_${params.roleId}`, locals); + } catch (error) { + console.error('error: ', error); + uni.$t.storage.setStorage(`fixed_tasks_${params.projectId}_${params.roleId}`, []); + } + }, + + /** + * 项目列表某天的 获取 + * @param {number} startTime + * @param {number} endTime + * @returns + */ + async getProjectsByDay(startTime, endTime) { + try { + const data = await uni.$t.storage.getStorage('projects'); + return filter.projects(JSON.parse(data), startTime, endTime); + } catch (error) { + return []; + } + }, + + /** + * 项目列表 存 + * @param {array} data + */ + putProjects(data) { + try { + if (!data || !data.length) return; // 服务端没数据不做操作 + let value = uni.$t.storage.getStorageSync('projects'); + let locals = value ? JSON.parse(value) : []; + if (!locals || !locals.length) { + // 本地没数据 + locals = data || []; + } else { + // 本地有数据 + data.forEach(item => { + let localData = locals.find(local => item.id === local.id); + if (localData) { + // 有相同数据 就用新的data里的数据 + localData = item; + } else { + // 没有就直接存本地 + locals.push(item); + } + }); + } + uni.$t.storage.setStorage('projects', locals); + } catch (error) { + console.error('error: ', error); + uni.$t.storage.setStorage('projects', []); + } + }, +}; diff --git a/src/utils/cacheAndRequest.js b/src/utils/cacheAndRequest.js new file mode 100644 index 0000000..32aa0f7 --- /dev/null +++ b/src/utils/cacheAndRequest.js @@ -0,0 +1,190 @@ +import store from '@/store/index'; + +/** + * 等待token执行api + * 没有token 就延时执行自己 直到有了token在请求 + * @param {function} requestFn 执行请求的函数 + */ +export const waitTokenRequest = requestFn => { + if (!requestFn || typeof requestFn !== 'function') throw new Error(`requestFn must be a function`); + if (uni.$t.storage.getStorageSync(uni.$t.app.tokenKey)) { + requestFn(); + } else { + setTimeout(() => waitTokenRequest(requestFn), 10); + } +}; + +export default { + /** + * 获取项目列表 + * @param {number} startTime 起始时间 + * @param {number} endTime 截止时间 + */ + getProjects(startTime, endTime, fn) { + let remote = false; + if (store.getters.useStorage) { + // 有缓存 且 服务端数据未返回 就先返回缓存 + uni.$t.cache + .getProjectsByDay(startTime, endTime) + .then(data => { + !remote && fn(null, data); + }) + .catch(err => !remote && fn(err)); + } + waitTokenRequest(() => { + // 拿到api数据后 再用api的数据 + uni.$u.api + .getProjects(startTime, endTime) + .then(data => { + remote = true; + fn(null, data); + // 存api到cache里 + uni.$t.cache.putProjects(data); + }) + .catch(err => fn(err)); + }); + }, + + /** + * 通过项目id获取角色信息 + * @param {object} params 提交的参数 + */ + findShowRole(params, fn) { + let remote = false; + // 有缓存 且 服务端数据未返回 就先返回缓存 + uni.$t.cache + .getShowRole(params.projectId) + .then(data => { + !remote && fn(null, data); + }) + .catch(err => !remote && fn(err)); + + waitTokenRequest(() => { + // 拿到api数据后 再用api的数据 + uni.$u.api + .findShowRole(params) + .then(data => { + remote = true; + fn(null, data); + // 存api到cache里 + uni.$t.cache.putShowRole(params.projectId, data); + }) + .catch(err => fn(err)); + }); + }, + + /** + * 根据时间基准点和角色查找定期任务 + * @param {object} params 提交的参数 + */ + getRegularTask(params, fn) { + let remote = false; + // 有缓存 且 服务端数据未返回 就先返回缓存 + uni.$t.cache + .getStorageRegularTask(params) + .then(data => { + console.log('cache data: ', data); + !remote && fn(null, data); + }) + .catch(err => !remote && fn(err)); + + waitTokenRequest(() => { + // 拿到api数据后 再用api的数据 + uni.$u.api + .getRegularTask(params) + .then(data => { + console.log('api data: ', uni.$u.deepClone(data)); + remote = true; + + fn(null, uni.$u.deepClone(data)); + // 存api到cache里 + uni.$t.cache.putStorageRegularTask(params, data); + }) + .catch(err => fn(err)); + }); + }, + + /** + * 根据角色查找永久的日常任务 + * @param {object} params 提交的参数 + */ + getPermanent(params, fn) { + let remote = false; + // 有缓存 且 服务端数据未返回 就先返回缓存 + uni.$t.cache + .getStoragePermanent(params) + .then(data => { + !remote && fn(null, data); + }) + .catch(err => !remote && fn(err)); + + waitTokenRequest(() => { + // 拿到api数据后 再用api的数据 + uni.$u.api + .getPermanent(params) + .then(data => { + remote = true; + fn(null, data); + // 存api到cache里 + uni.$t.cache.putStoragePermanent(params, data); + }) + .catch(err => fn(err)); + }); + }, + + /** + * 根据时间和角色查找日常任务 + * @param {object} params 提交的参数 + */ + getGlobal(params, fn) { + let remote = false; + // 有缓存 且 服务端数据未返回 就先返回缓存 + uni.$t.cache + .getDailyTask(params) + .then(data => { + !remote && fn(null, data); + }) + .catch(err => !remote && fn(err)); + + waitTokenRequest(() => { + // 拿到api数据后 再用api的数据 + uni.$u.api + .getGlobal(params) + .then(data => { + remote = true; + fn(null, data); + // 存api到cache里 + uni.$t.cache.putDailyTask(params, data); + }) + .catch(err => fn(err)); + }); + }, + + /** + * 获取插件信息 + * @param {object} params 提交的参数 + */ + getOtherPlugin(params, fn) { + let remote = false; + // 有缓存 且 服务端数据未返回 就先返回缓存 + uni.$t.cache + .getPlugin(params.pluginId) + .then(data => { + !remote && fn(null, data); + }) + .catch(err => !remote && fn(err)); + + waitTokenRequest(() => { + // 拿到api数据后 再用api的数据 + uni.$u.api + .getOtherPlugin(params) + .then(data => { + remote = true; + fn(null, data); + // 存api到cache里 + uni.$t.cache.putPlugin(params.pluginId, data); + }) + .catch(err => fn(err)); + }); + }, +}; diff --git a/src/utils/indexedDB.js b/src/utils/indexedDB.js new file mode 100644 index 0000000..30a0e90 --- /dev/null +++ b/src/utils/indexedDB.js @@ -0,0 +1,163 @@ +import { name } from '@/config/db'; +import { curry } from 'lodash'; + +// 创建表 +const createCollection = (Vue, db) => { + // projects项目表 + !db.objectStoreNames.contains('projects') && db.createObjectStore('projects', { keyPath: 'id' }); + // roles 角色表 + !db.objectStoreNames.contains('roles') && db.createObjectStore('roles', { keyPath: 'id' }); + // plan_tasks 定期任务 + !db.objectStoreNames.contains('plan_tasks') && db.createObjectStore('plan_tasks', { keyPath: 'id' }); + // fixed_tasks 固定全局任务 + Vue.prototype.$db.fixed_tasks = !db.objectStoreNames.contains('fixed_tasks') && db.createObjectStore('fixed_tasks', { keyPath: 'id' }); + // variable_tasks 可变全局任务 + Vue.prototype.$db.variable_tasks = + !db.objectStoreNames.contains('variable_tasks') && db.createObjectStore('variable_tasks', { keyPath: 'id' }); + // plugins 插件表 + Vue.prototype.$db.plugins = !db.objectStoreNames.contains('plugins') && db.createObjectStore('plugins', { keyPath: 'id' }); +}; + +/** + * 新增数据 + * + * @param {object} db 数据库database + * @param {string} collection 集合/表 + * @param {object} data 数据 + */ +const create = (db, collection, data) => { + return new Promise((resolve, reject) => { + const request = db.transaction([collection], 'readwrite').objectStore(collection).add(data); + request.onsuccess = () => resolve(); + + request.onerror = event => { + const { name, message } = event.target.error; + if (name === 'ConstraintError') { + reject('数据已存在'); + } else { + reject(message); + } + }; + }); +}; + +/** + * 找到1条数据 + * + * @param {object} db 数据库database + * @param {string} collection 集合/表 + * @param {string} key 索引关键字 一般是id + */ +const findOne = (db, collection, key) => { + return new Promise((resolve, reject) => { + const request = db.transaction([collection]).objectStore(collection).get(key); + request.onerror = event => reject(event.target.error.message); + request.onsuccess = event => resolve(event.target.result); + }); +}; + +/** + * 找到所有数据 + * + * @param {object} db 数据库database + * @param {string} collection 集合/表 + */ +const find = (db, collection) => { + return new Promise((resolve, reject) => { + const request = db.transaction(collection).objectStore(collection).openCursor(); + let result = []; + + request.onerror = event => reject(event.target.error.message); + request.onsuccess = event => { + const cursor = event.target.result; + if (cursor) { + result.push(cursor.value); + cursor.continue(); + } else { + resolve(result); + } + }; + }); +}; + +/** + * 更新数据 + * + * @param {object} db 数据库database + * @param {string} collection 集合/表 + * @param {object} newData 新数据 + */ +const update = (db, collection, newData) => { + return new Promise((resolve, reject) => { + const request = db.transaction([collection], 'readwrite').objectStore(collection).put(newData); + request.onerror = event => reject(event.target.error.message); + request.onsuccess = () => resolve(newData); + }); +}; + +/** + * 移除数据 通过关键字 + * + * @param {object} db 数据库database + * @param {string} collection 集合/表 + * @param {string} key 关键字 + */ +const remove = (db, collection, key) => { + return new Promise((resolve, reject) => { + const request = db.transaction([collection], 'readwrite').objectStore(collection).delete(key); + request.onerror = event => reject(event.target.error.message); + request.onsuccess = () => resolve(); + }); +}; + +/** + * 创建索引 + * + * @param {object} db 数据库database + * @param {string} collection 集合/表 + * @param {string} field 创建索引的字段名称 + * @param {string} key 关键字 + */ +const createIndexAndFind = (db, collection, field, key) => { + return new Promise((resolve, reject) => { + const store = db.transaction([collection], 'readonly').objectStore(collection); + store.createIndex(field, field); + const index = store.index(field); + const request = index.get(key); + request.onerror = event => reject(event.target.error.message); + request.onsuccess = event => resolve(event.target.result); + }); +}; + +const curriedCreate = curry(create); +export const curriedFindOne = curry(findOne); +export const curriedFind = curry(find); +export const curriedRemove = curry(remove); +export const curriedUpdate = curry(update); +export const curriedIndex = curry(createIndexAndFind); + +const install = Vue => { + uni.$db = Vue.prototype.$db = {}; + Vue.prototype.$db.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; + const request = Vue.prototype.$db.indexedDB.open(name, Date.now()); // IDBRequest 对象 + request.onerror = error => console.error('打开数据库失败', error); + request.onsuccess = event => { + console.log('INDEXED_DB OPEN SUCCESS'); + Vue.prototype.$db.db = event.target.result; + }; + request.onupgradeneeded = event => { + console.log('INDEXED_DB OPEN onupgradeneeded'); + Vue.prototype.$db.db = event.target.result; + // 创建表 + createCollection(Vue, Vue.prototype.$db.db); + + Vue.prototype.$db.create = curriedCreate(Vue.prototype.$db.db); // create 新增数据,颗粒化以后就不用再传db数据了 + Vue.prototype.$db.findOne = curriedFindOne(Vue.prototype.$db.db); // 查一条 + Vue.prototype.$db.find = curriedFind(Vue.prototype.$db.db); // 查集合里的所有数据 + Vue.prototype.$db.update = curriedUpdate(Vue.prototype.$db.db); // 更新某条数据 + Vue.prototype.$db.remove = curriedRemove(Vue.prototype.$db.db); // 删除某条数据 + // Vue.prototype.$db.createIndex = curriedIndex(Vue.prototype.$db.db); // 创建索引 + }; +}; + +export default { install }; diff --git a/src/utils/request.js b/src/utils/request.js new file mode 100644 index 0000000..2cf5374 --- /dev/null +++ b/src/utils/request.js @@ -0,0 +1,54 @@ +const install = (Vue, vm) => { + Vue.prototype.$u.http.setConfig({ + baseUrl: '', + showLoading: true, // 是否显示请求中的loading + loadingText: '玩命加载中...', + loadingTime: 800, + loadingMask: true, // 展示loading的时候,是否给一个透明的蒙层,防止触摸穿透 + // 配置请求头信息 + header: { 'content-type': 'application/json;charset=UTF-8' }, + }); + + // 请求拦截部分,如配置,每次请求前都会执行 + Vue.prototype.$u.http.interceptor.request = config => { + const token = vm.$store.state.user.token || uni.$t.storage.getStorageSync(uni.$t.app.tokenKey); + if (token) { + config.header.Authorization = `Bearer ${token}`; + } + + return config; + }; + + // 响应拦截,如配置,每次请求结束都会执行本方法 + Vue.prototype.$u.http.interceptor.response = res => { + if (res.code === 200) { + // res为服务端返回值,可能有code,result等字段 + // 这里对res.result进行返回,将会在this.$u.post(url).then(res => {})的then回调中的res的到 + // 如果配置了originalData为true,请留意这里的返回值 + return res.data; + } else if (res.code === 401) { + // 假设201为token失效,这里跳转登录 + vm.$u.toast('验证失败,请重新登录'); + setTimeout(() => { + // 此为uView的方法,详见路由相关文档 + vm.$u.route('/pages/user/login'); + }, 1500); + return false; + } else { + // 如果返回false,则会调用Promise的reject回调, + // 并将进入this.$u.post(url).then().catch(res=>{})的catch回调中,res为服务端的返回值 + return false; + } + }; + + Vue.prototype.$u.post = (url, param = {}, header = {}) => { + return Vue.prototype.$u.http.request({ + url, + method: 'POST', + header, + data: { param }, + }); + }; +}; + +export default { install }; diff --git a/src/utils/storage.js b/src/utils/storage.js new file mode 100644 index 0000000..ea672d6 --- /dev/null +++ b/src/utils/storage.js @@ -0,0 +1,112 @@ +export default { + /** + * 设置本地存储 同步 + * @param {string} key + * @param {*} data + */ + setStorageSync(key, data) { + const value = typeof data === 'string' ? data : JSON.stringify(data); + uni.setStorageSync(key, value); + }, + + /** + * 获取本地存储的信息 根据key + * @param {string} key + * @return {string} + */ + getStorageSync(key) { + return uni.getStorageSync(key); + }, + + /** + * 根据key移除某条数据 同步 + * @param {string} key + */ + removeStorageSync(key) { + uni.removeStorageSync(key); + }, + + /** + * 清楚全部数据 同步 + */ + clearStorageSync() { + uni.clearStorageSync(); + }, + + /** + * 设置本地存储 异步 + * @param {string} key + * @param {*} data + */ + setStorage(key, data) { + uni.$t.storage.checkCapacity(); + return new Promise((resolve, reject) => { + const value = typeof data === 'string' ? data : JSON.stringify(data); + uni.setStorage({ + key, + data: value, + success() { + resolve(`数据${key}存储成功`); + }, + fail() { + reject(`数据${key}存储失败`); + }, + }); + }); + }, + + /** + * 获取本地存储的信息 根据key 异步 + * @param {string} key + * @return {string} + */ + getStorage(key) { + return new Promise((resolve, reject) => { + uni.getStorage({ + key, + success(res) { + resolve(res.data); + }, + fail(error) { + reject(`数据${key}获取失败, error: ${error.errMsg}`); + }, + }); + }); + }, + + /** + * 根据key移除某条数据 异步 + * @param {string} key + */ + removeStorage(key) { + return new Promise((resolve, reject) => { + uni.removeStorage({ + key, + success(res) { + resolve(res); + }, + fail(error) { + reject(`数据${key}删除失败, error: ${error}`); + }, + }); + }); + }, + + /** + * 清楚全部数据 异步 + */ + clearStorage() { + uni.clearStorage(); + }, + + // 检测local Storage容量 超出容量清空数据缓存 + checkCapacity() { + /* #ifdef H5 */ + const capacity = JSON.stringify(localStorage).length; + let max = 1024 * 1024 * 4; + if (capacity >= max) { + uni.$t.storage.clearStorage(); + } + /* #endif */ + }, +}; diff --git a/src/utils/tall.js b/src/utils/tall.js new file mode 100644 index 0000000..19c5b17 --- /dev/null +++ b/src/utils/tall.js @@ -0,0 +1,38 @@ +import app from '@/config/app.js'; +import cache from '@/utils/cache.js'; +import cacheAndRequest from '@/utils/cacheAndRequest.js'; +import plugin from '@/config/plugin.js'; +import storage from '@/utils/storage.js'; +import time from '@/utils/time.js'; +import timeConfig from '@/config/time'; +import ui from '@/utils/ui.js'; +import upload from '@/utils/upload.js'; +import user from '@/config/user.js'; +import zIndex from '@/config/zIndex.js'; +import task from '@/config/task.js'; + +const gateway = process.env.VUE_APP_API_URL; + +const $t = { + zIndex, // 定位元素层级 + app, // app级别的相关配置 + plugin, // 插件相关配置信息 + storage, // 本地存储storage封装 + time, // 时间处理 + timeConfig, // 时间相关配置 + ui, // ui界面提示相关 + chooseAndUpload: upload.chooseAndUpload, // 选择并上传单个文件相关的封装 + domain: `${gateway}/defaultwbs`, + cache, // 本地存储相关 + $q: cacheAndRequest, + user, // 用户相关配置 + task, // 任务相关配置 +}; + +uni.$t = $t; + +const install = Vue => { + Vue.prototype.$t = $t; +}; + +export default { install }; diff --git a/src/utils/time.js b/src/utils/time.js new file mode 100644 index 0000000..c20cd2b --- /dev/null +++ b/src/utils/time.js @@ -0,0 +1,366 @@ +import dayjs from 'dayjs'; + +const advancedFormat = require('dayjs/plugin/advancedFormat'); +const weekOfYear = require('dayjs/plugin/weekOfYear'); +const duration = require('dayjs/plugin/duration'); + +dayjs.extend(advancedFormat); +dayjs.extend(weekOfYear); +dayjs.extend(duration); + +/** + * 格式化数字 + * @param {*} n + */ +const formatNumber = n => { + const str = n.toString(); + return str[1] ? str : `0${str}`; +}; + +/** + * 格式化时间 + * @param {number} beginTime + */ +const formatTime = beginTime => { + const date = new Date(beginTime); + const year = date.getFullYear(); + const month = date.getMonth() + 1; + const day = date.getDate(); + const hour = date.getHours(); + const minute = date.getMinutes(); + const second = date.getSeconds(); + + return `${[year, month, day].map(formatNumber).join('/')} ${[hour, minute, second].map(formatNumber).join(':')}`; +}; + +/** + * 添加一定时间的时长 + * @param {number | date} time + * @param {number} num + * @param {string} cycle + */ +const add = (time, num, cycle) => { + const str = dayjs(time).add(num, cycle); + return str; +}; + +/** + * 时间转换 08:00 转换成8小时0分钟 + * @param {string} time + * @returns {{hours: number, minutes: number}} + */ +const convertTime = time => { + const arr = time.split(':'); + return { + hours: parseInt(arr[0], 10), + minutes: parseInt(arr[1], 10), + }; +}; + +/** + * 将秒 -> 分 秒 + * @param {number} seconds + */ +const secondToMinute = seconds => { + const minute = formatNumber(Math.floor(seconds / 60)); + const second = formatNumber(parseInt(seconds % 60, 10)); + return { + minute, + second, + }; +}; + +/** + * 将时间戳 -> 时:分 + * @param {Number} timestamp 时间戳 + * @return date:2018/10/09 time: 12:59 + */ +const setTimestampToStr = timestamp => { + const timeObj = new Date(timestamp); + const year = timeObj.getFullYear(); + const month = formatNumber(timeObj.getMonth() + 1); + const day = formatNumber(timeObj.getDate()); + const hour = formatNumber(timeObj.getHours()); + const minute = formatNumber(timeObj.getMinutes()); + const date = `${year}-${month}-${day}`; + const time = `${hour}:${minute}`; + return { + date, + time, + }; +}; + +/** + * 检测时间(ms)是不是今天 + * @param {Number} time 时间戳 + */ +const validateTimeIsToday = time => { + const timeDate = new Date(time); + const date = new Date(); + return timeDate.getFullYear() === date.getFullYear() && timeDate.getMonth() === date.getMonth() && timeDate.getDate() === date.getDate(); +}; + +/** + * 检测两个日期是否相同 + * @param {number | date} time + * @param {number | date} value + * @param {string} cycle 传入 day 将会比较 day、 month和 year + */ +const isSame = (time, value, cycle) => { + const str = dayjs(time).isSame(value, cycle); + return str; +}; + +/** + * 格式化开始时间 + * @param {Number} timestamp 时间戳 + * @return + * 如果是今天 -> 时:分 + * 如果不是今年 -> 年/月/日 时:分 + * 否则 *月*日 时:分 + */ +const formatBeginTime = timestamp => { + const timeObj = new Date(timestamp); + const year = timeObj.getFullYear(); + const month = formatNumber(timeObj.getMonth() + 1); + const day = formatNumber(timeObj.getDate()); + const hour = formatNumber(timeObj.getHours()); + const minute = formatNumber(timeObj.getMinutes()); + const date = `${year}/${month}/${day}`; + const time = `${hour}:${minute}`; + const currentYear = new Date().getFullYear(); + + if (validateTimeIsToday(timestamp)) { + // 今天 + return `今天 ${time}`; + } else if (currentYear !== year) { + // 不是今年 + return `${date} ${time}`; + } else { + return `${month}月${day}日 ${time}`; + } +}; + +/** + * 格式化时长 + * @param {Number} duration 时长 + * 超过24小时( 24 * 60 * 60 * 1000 ms) 转换成天数 + 小时 + 分钟 + * 小于1分钟( 60 * 1000 ms) 转换成秒钟 + * 其余的显示分钟 + * 超过2小时( 2 * 60 * 60 * 1000 ms) 转换成小时 + 分钟数 + */ +const formatDuration = duration => { + const minuteTime = 60 * 1000; + const hourTime = 60 * minuteTime; + const dayTime = 24 * hourTime; + const days = Math.floor(duration / dayTime); + const hours = Math.floor((duration % dayTime) / hourTime); + const minutes = Math.floor((duration % hourTime) / minuteTime); + if (duration <= 60 * 1000) { + // 小于1分钟 返回几秒 + return `${Math.floor(duration / 1000)}秒`; + } else if (duration > dayTime) { + // 大于1天 + if (minutes === 0) { + if (hours === 0) { + // 分钟数是0 和 小时数是0 返回 几天 + return `${days}天`; + } else { + // 分钟是0 小时不是0 返回 几天几小时 + return `${days}天${hours}小时`; + } + } else { + // 分钟不是0 返回几天几时几分 + return `${days}天${hours}时${minutes}分`; + } + } else if (duration > 2 * hourTime) { + // 大于2h + if (minutes === 0) { + // 分钟是0 返回几小时 + return `${hours}小时`; + } else { + // 分钟不是0 返回几小时几分钟 + return `${hours}小时${minutes}分钟`; + } + } else { + // 其余情况 返回 几分钟 + return `${parseInt(duration / minuteTime)}分钟`; + } +}; + +/** + * 格式化时长 转换成对象格式 + * @param {Number} duration 时长 + * 超过24小时( 24 * 60 * 60 * 1000 ms) 转换成{days, hours, minutes, seconds: 0} + * 小于1分钟( 60 * 1000 ms) 转换成秒钟 { days: 0, hours: 0, minutes: 0, seconds } + * 其余的显示分钟 { days: 0, hours: 0, minutes, seconds: 0 } + * 超过2小时( 2 * 60 * 60 * 1000 ms) 转换成{ days: 0, hours, minutes, seconds: 0 } + */ +const formatDurationToObject = duration => { + const minuteTime = 60 * 1000; + const hourTime = 60 * minuteTime; + const dayTime = 24 * hourTime; + const days = Math.floor(duration / dayTime); + const hours = Math.floor((duration % dayTime) / hourTime); + const minutes = Math.floor((duration % hourTime) / minuteTime); + const result = { + days: 0, + hours: 0, + minutes: 0, + seconds: 0, + }; + if (duration <= 60 * 1000) { + // 小于1分钟 返回几秒 + result.seconds = Math.floor(duration / 1000); + } else if (duration > dayTime) { + // 大于1天 + if (minutes === 0) { + if (hours === 0) { + // 分钟数是0 和 小时数是0 返回 几天 + result.days = days; + } else { + // 分钟是0 小时不是0 返回 几天几小时 + result.days = days; + result.hours = hours; + } + } else { + // 分钟不是0 返回几天几时几分 + result.days = days; + result.hours = hours; + result.minutes = minutes; + } + } else if (duration > 2 * hourTime) { + // 大于2h + if (minutes === 0) { + // 分钟是0 返回几小时 + result.hours = hours; + } else { + // 分钟不是0 返回几小时几分钟 + result.hours = hours; + result.minutes = minutes; + } + } else { + // 其余情况 返回 几分钟 + result.minutes = minutes; + } + return result; +}; + +/** + * 将对象格式的时间转换成时间戳 + * @param {obj} 对象格式的时间 days, hours, minutes, seconds + * @return 时长的ms + */ +const formatObjectTimeToMs = (days = 0, hours = 0, minutes = 0, seconds = 0) => { + return days * 24 * 60 * 60 * 1000 + hours * 60 * 60 * 1000 + minutes * 60 * 1000 + seconds * 1000; +}; + +/** + * 计算过滤 周期 + * @param {string} time 周期字符串 + * @return {string} cycle 周期英文字符串 + */ +const computeCycle = time => { + // 加载下一个周期的任务 + let cycle = 'day'; + switch (time) { + case '天': + cycle = 'day'; + break; + case '周': + cycle = 'week'; + break; + case '月': + cycle = 'month'; + break; + default: + cycle = '日程'; + break; + } + return cycle; +}; + +/** + * 将时间按周期语义化 + * @param {string} cycle 周期 + * @param {number|string} time 时间 + */ +const formatStartTimeToCycleTime = (cycle, time) => { + let result = ''; + const _time = dayjs(+time); + switch (cycle) { + case '天': + result = _time.format('YYYY年M月D日'); + break; + case '周': + result = _time.format('YYYY年w周'); + break; + case '月': + result = _time.format('YYYY年M月'); + break; + case '日程': + result = _time.format('YYYY年M月D日 HH:mm'); + break; + default: + result = _time.format('YYYY年M月D日'); + break; + } + return result; +}; + +/** + * 计算进行中状态剩余时间 显示数字 + * @param {number} leftTime 剩余时间ms + * @returns { num: 显示的数字, time: 演示器演示时长 } + */ +const computeDurationText = leftTime => { + try { + if (leftTime < 0) return { num: 0, time: null }; + const { years, months, days, hours, minutes, seconds, milliseconds } = dayjs.duration(leftTime).$d; + let num = 0; + let time = 1000; + + if (years > 0) { + num = years; + time = 60 * 60 * 1000; // 按小时 + } else if (months > 0) { + num = months; + time = 60 * 60 * 1000; // 按小时 + } else if (days > 0) { + num = days; + time = 60 * 60 * 1000; // 按小时 + } else if (hours > 0) { + num = hours; + } else if (minutes > 0) { + num = minutes; + } else if (seconds > 0) { + num = seconds; + } else if (milliseconds > 0) { + num = milliseconds; + time = 16; + } else { + time = null; + } + return { num, time }; + } catch (error) { + console.log('🚀 ~ file: time.js ~ line 335 ~ computeDurationText ~ error', error); + return { num: 0, time: null }; + } +}; + +export default { + formatNumber, + formatTime, + add, + convertTime, + secondToMinute, + setTimestampToStr, + isSame, + formatBeginTime, + formatDuration, + formatDurationToObject, + formatObjectTimeToMs, + computeCycle, + formatStartTimeToCycleTime, + computeDurationText, +}; diff --git a/src/utils/ui.js b/src/utils/ui.js new file mode 100644 index 0000000..1de1476 --- /dev/null +++ b/src/utils/ui.js @@ -0,0 +1,56 @@ +export default { + /** + * 显示toast + * @param {string} title 提示内容 + * @param {number} duration 显示时间 默认2000 + */ + showToast(title, duration = 2000) { + return uni.showToast({ + title, + icon: 'none', + duration, + mask: true, + }); + }, + + // 隐藏toast + hideToast() { + return uni.hideToast(); + }, + + /** + * 显示加载雪花 + * @param {string} title + */ + showLoading(title = '玩命加载中...') { + return uni.showLoading({ + title, + mask: true, + }); + }, + + // 隐藏loading + hideLoading() { + return uni.hideLoading(); + }, + + /** + * 显示modal弹出框 + * @param {string} title 标题 + * @param {string} content 内容 + * @param {boolean} showCancel 是否显示取消按钮 默认true + */ + showModal(title, content, showCancel = true) { + return new Promise(function (resolve, reject) { + uni.showModal({ + title, + content, + showCancel, + success: ({ confirm, cancel }) => { + confirm && resolve(); + cancel && reject(); + }, + }); + }); + }, +}; diff --git a/src/utils/upload.js b/src/utils/upload.js new file mode 100644 index 0000000..bd3de1d --- /dev/null +++ b/src/utils/upload.js @@ -0,0 +1,110 @@ +// H5选择文件 +const chooseFileH5 = (extension = ['.xls', '.xlsx']) => { + return new Promise((resolve, reject) => { + uni.chooseFile({ + count: 1, //默认100 + extension, + success(res) { + resolve(res.tempFilePaths[0]); + }, + fail() { + reject('上传失败'); + }, + }); + }); +}; + +// 微信选择文件 从客户端会话选择文件。 +const chooseFileWeixin = (extension = ['.xls', '.xlsx']) => { + return new Promise((resolve, reject) => { + wx.chooseMessageFile({ + count: 1, + extension, + type: 'file', + success(res) { + resolve(res.tempFiles[0].path); + }, + fail() { + reject('上传失败'); + }, + }); + }); +}; + +// 选择文件 +const chooseFile = (extension = ['.xls', '.xlsx']) => { + let fn = null; + /* #ifdef H5 */ + fn = chooseFileH5(extension); + /* #endif */ + + /* #ifdef MP-WEIXIN */ + fn = chooseFileWeixin(extension); + /* #endif */ + return fn; +}; + +export default { + /** + * 上传单个文件 + * @param {string} url 服务器地址 + * @param {object} formData 上传的其他字段 + * @param {array} extension 上传文件类型 扩展名数组 + * @param {string} name + * @returns + */ + chooseAndUpload(url, formData = {}, extension = ['.xls', '.xlsx'], name = 'param') { + uni.hideLoading(); + clearTimeout(timer); + let timer = null; + return new Promise((resolve, reject) => { + const token = uni.$t.storage.getStorageSync(uni.$t.app.tokenKey); + if (!token) { + return reject('用户未登录,请登录后重试'); + } + chooseFile(extension) + .then(filePath => { + console.log('filePath: ', filePath); + if (!timer) { + timer = setTimeout(() => { + uni.$t.ui.showLoading('正在上传...'); + timer = null; + }, 800); + } + // 开始上传 + uni.uploadFile({ + url, + filePath, + name, + formData, + header: { Authorization: `Bearer ${token}` }, + success: ({ data, statusCode }) => { + clearTimeout(timer); + uni.hideLoading(); + + if (statusCode === 200 && data) { + const { code, msg } = JSON.parse(data); + if (code !== 200) { + reject(msg); + } else { + resolve(JSON.parse(data).data); + } + } else { + reject('上传失败'); + } + }, + fail: error => { + clearTimeout(timer); + uni.hideLoading(); + reject(error); + }, + }); + }) + .catch(error => { + clearTimeout(timer); + uni.hideLoading(); + reject(error); + }); + }); + }, +}; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..730626d --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "types": [ + "@dcloudio/types", + "miniprogram-api-typings", + "mini-types" + ] + } +} diff --git a/vue.config.js b/vue.config.js new file mode 100644 index 0000000..602c368 --- /dev/null +++ b/vue.config.js @@ -0,0 +1,36 @@ +const path = require('path'); +// const CopyWebpackPlugin = require('copy-webpack-plugin'); // 最新版本copy-webpack-plugin插件暂不兼容,推荐v5.0.0 +const CompressionWebpackPlugin = require('compression-webpack-plugin'); +const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg|ttf|woff|woff2)(\?.*)?$/i; +const isPro = process.env.NODE_ENV === 'production'; + +module.exports = { + lintOnSave: process.env.NODE_ENV !== 'production', + productionSourceMap: false, + devServer: { + // open: true, + // host: '127.0.0.1', + overlay: { warnings: false, errors: true }, + // proxy: {} + }, + configureWebpack: { + plugins: isPro + ? [ + new CompressionWebpackPlugin({ + filename: '[path].gz[query]', + algorithm: 'gzip', + test: productionGzipExtensions, + threshold: 10240, + minRatio: 0.8, + deleteOriginalAssets: false, + }), + ] + : [], + }, + pluginOptions: { + // mock: { entry: './src/mock/mock.js', debug: true, disable: true }, + // webpackBundleAnalyzer: { + // openAnalyzer: isPro, + // }, + }, +};