commit cb74b8b073385fff4f86df95ef8a0a8e32f828d9 Author: aBin Date: Fri Dec 31 15:42:43 2021 +0800 暴风眼 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 0000000..b02aa64 Binary files /dev/null and b/public/img/icons/android-chrome-192x192.png differ diff --git a/public/img/icons/android-chrome-512x512.png b/public/img/icons/android-chrome-512x512.png new file mode 100644 index 0000000..06088b0 Binary files /dev/null and b/public/img/icons/android-chrome-512x512.png differ diff --git a/public/img/icons/android-chrome-maskable-192x192.png b/public/img/icons/android-chrome-maskable-192x192.png new file mode 100644 index 0000000..791e9c8 Binary files /dev/null and b/public/img/icons/android-chrome-maskable-192x192.png differ diff --git a/public/img/icons/android-chrome-maskable-512x512.png b/public/img/icons/android-chrome-maskable-512x512.png new file mode 100644 index 0000000..5f2098e Binary files /dev/null and b/public/img/icons/android-chrome-maskable-512x512.png differ 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 0000000..1427cf6 Binary files /dev/null and b/public/img/icons/apple-touch-icon-120x120.png differ 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 0000000..f24d454 Binary files /dev/null and b/public/img/icons/apple-touch-icon-152x152.png differ diff --git a/public/img/icons/apple-touch-icon-180x180.png b/public/img/icons/apple-touch-icon-180x180.png new file mode 100644 index 0000000..404e192 Binary files /dev/null and b/public/img/icons/apple-touch-icon-180x180.png differ 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 0000000..cf10a56 Binary files /dev/null and b/public/img/icons/apple-touch-icon-60x60.png differ diff --git a/public/img/icons/apple-touch-icon-76x76.png b/public/img/icons/apple-touch-icon-76x76.png new file mode 100644 index 0000000..c500769 Binary files /dev/null and b/public/img/icons/apple-touch-icon-76x76.png differ diff --git a/public/img/icons/apple-touch-icon.png b/public/img/icons/apple-touch-icon.png new file mode 100644 index 0000000..03c0c5d Binary files /dev/null and b/public/img/icons/apple-touch-icon.png differ diff --git a/public/img/icons/favicon-16x16.png b/public/img/icons/favicon-16x16.png new file mode 100644 index 0000000..42af009 Binary files /dev/null and b/public/img/icons/favicon-16x16.png differ diff --git a/public/img/icons/favicon-32x32.png b/public/img/icons/favicon-32x32.png new file mode 100644 index 0000000..46ca04d Binary files /dev/null and b/public/img/icons/favicon-32x32.png differ diff --git a/public/img/icons/msapplication-icon-144x144.png b/public/img/icons/msapplication-icon-144x144.png new file mode 100644 index 0000000..7808237 Binary files /dev/null and b/public/img/icons/msapplication-icon-144x144.png differ diff --git a/public/img/icons/mstile-150x150.png b/public/img/icons/mstile-150x150.png new file mode 100644 index 0000000..3b37a43 Binary files /dev/null and b/public/img/icons/mstile-150x150.png differ diff --git a/public/img/icons/safari-pinned-tab.svg b/public/img/icons/safari-pinned-tab.svg new file mode 100644 index 0000000..e44c0d5 --- /dev/null +++ b/public/img/icons/safari-pinned-tab.svg @@ -0,0 +1,3 @@ + + + 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 0000000..11e6944 Binary files /dev/null and b/src/components/PatientList/icon/yanshi.png differ diff --git a/src/components/PrettyExchange/PrettyExchange.vue b/src/components/PrettyExchange/PrettyExchange.vue new file mode 100644 index 0000000..4fdae1f --- /dev/null +++ b/src/components/PrettyExchange/PrettyExchange.vue @@ -0,0 +1,520 @@ + + + + + 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 0000000..3e6d5ec Binary files /dev/null and b/src/components/Service/icon/tel-we.png differ diff --git a/src/components/TimeLine/TimeLine.vue b/src/components/TimeLine/TimeLine.vue new file mode 100644 index 0000000..a84939e --- /dev/null +++ b/src/components/TimeLine/TimeLine.vue @@ -0,0 +1,126 @@ + + + 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 0000000..684f6c7 Binary files /dev/null and b/src/pages/establish/icon/bottom.png differ diff --git a/src/pages/establish/icon/idcard.png b/src/pages/establish/icon/idcard.png new file mode 100644 index 0000000..9203830 Binary files /dev/null and b/src/pages/establish/icon/idcard.png differ 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 0000000..32b72d3 Binary files /dev/null and b/src/pages/patientLine/png/播放.png differ diff --git a/src/pages/phone-bind/phone-bind.vue b/src/pages/phone-bind/phone-bind.vue new file mode 100644 index 0000000..c3b2f6c --- /dev/null +++ b/src/pages/phone-bind/phone-bind.vue @@ -0,0 +1,192 @@ + + + + + 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, + // }, + }, +};