zhang_li
7 months ago
77 changed files with 8988 additions and 8214 deletions
@ -0,0 +1,71 @@ |
|||
// @ts-check
|
|||
/** @type {import('cz-git').UserConfig} */ |
|||
module.exports = { |
|||
extends: ['@commitlint/config-conventional'], |
|||
rules: { |
|||
'body-leading-blank': [2, 'always'], |
|||
'footer-leading-blank': [1, 'always'], |
|||
'header-max-length': [2, 'always', 108], |
|||
'subject-empty': [2, 'never'], |
|||
'type-empty': [2, 'never'], |
|||
'subject-case': [0], |
|||
'type-enum': [ |
|||
2, |
|||
'always', |
|||
[ |
|||
'feat', |
|||
'fix', |
|||
'perf', |
|||
'style', |
|||
'docs', |
|||
'test', |
|||
'refactor', |
|||
'build', |
|||
'ci', |
|||
'chore', |
|||
'revert', |
|||
'wip', |
|||
'workflow', |
|||
'types', |
|||
'release' |
|||
] |
|||
] |
|||
}, |
|||
prompt: { |
|||
// 中英文对照版
|
|||
// messages: {
|
|||
// type: '选择你要提交的类型 :',
|
|||
// scope: '选择一个提交范围 (可选):',
|
|||
// customScope: '请输入自定义的提交范围 :',
|
|||
// subject: '填写简短精炼的变更描述 :\n',
|
|||
// body: '填写更加详细的变更描述 (可选)。使用 "|" 换行 :\n',
|
|||
// breaking: '列举非兼容性重大的变更 (可选)。使用 "|" 换行 :\n',
|
|||
// footerPrefixsSelect: '选择关联issue前缀 (可选):',
|
|||
// customFooterPrefixs: '输入自定义issue前缀 :',
|
|||
// footer: '列举关联issue (可选) 例如: #31, #I3244 :\n',
|
|||
// confirmCommit: '是否提交或修改commit ?'
|
|||
// },
|
|||
// types: [
|
|||
// { value: 'feat', name: 'feat: 新增功能' },
|
|||
// { value: 'fix', name: 'fix: 修复缺陷' },
|
|||
// { value: 'docs', name: 'docs: 文档变更' },
|
|||
// { value: 'style', name: 'style: 代码格式' },
|
|||
// { value: 'refactor', name: 'refactor: 代码重构' },
|
|||
// { value: 'perf', name: 'perf: 性能优化' },
|
|||
// { value: 'test', name: 'test: 添加疏漏测试或已有测试改动' },
|
|||
// {
|
|||
// value: 'build',
|
|||
// name: 'build: 构建流程、外部依赖变更 (如升级 npm 包、修改打包配置等)'
|
|||
// },
|
|||
// { value: 'ci', name: 'ci: 修改 CI 配置、脚本' },
|
|||
// { value: 'revert', name: 'revert: 回滚 commit' },
|
|||
// {
|
|||
// value: 'chore',
|
|||
// name: 'chore: 对构建过程或辅助工具和库的更改 (不影响源文件、测试用例)'
|
|||
// },
|
|||
// { value: 'wip', name: 'wip: 正在开发中' },
|
|||
// { value: 'workflow', name: 'workflow: 工作流程改进' },
|
|||
// { value: 'types', name: 'types: 类型定义文件修改' }
|
|||
// ]
|
|||
} |
|||
} |
@ -1,2 +1,4 @@ |
|||
VITE_BASE_URL=http://dev.ccwin-in.com:25300/api/admin-api |
|||
VITE_BASE_URL_IMAGE=http://dev.ccwin-in.com:25300/admin-api |
|||
|
|||
VITE_BASE_URL=http://localhost:12080/admin-api |
|||
#VITE_BASE_URL=http://dev.ccwin-in.com:25203/api/admin-api |
|||
VITE_BASE_URL_IMAGE=http://localhost:12080/admin-api |
@ -1,2 +0,0 @@ |
|||
VITE_BASE_URL=http://172.21.32.13:81/api/admin-api |
|||
VITE_BASE_URL_IMAGE=http://172.21.32.13:81/admin-api |
@ -1,2 +0,0 @@ |
|||
VITE_BASE_URL=http://172.21.32.14:81/api/admin-api |
|||
VITE_BASE_URL_IMAGE=http://172.21.32.14:81/admin-api |
@ -1,2 +0,0 @@ |
|||
VITE_BASE_URL=http://172.21.32.15:81/api/admin-api |
|||
VITE_BASE_URL_IMAGE=http://172.21.32.15:81/admin-api |
@ -1,2 +0,0 @@ |
|||
VITE_BASE_URL=http://172.21.32.16:81/api/admin-api |
|||
VITE_BASE_URL_IMAGE=http://172.21.32.16:81/admin-api |
@ -1,2 +0,0 @@ |
|||
VITE_BASE_URL=http://172.22.32.8:81/api/admin-api |
|||
VITE_BASE_URL_IMAGE=http://172.22.32.8:81/admin-api |
@ -1,2 +0,0 @@ |
|||
VITE_BASE_URL=http://172.22.32.9:81/api/admin-api |
|||
VITE_BASE_URL_IMAGE=http://172.22.32.9:81/admin-api |
@ -0,0 +1,4 @@ |
|||
# VITE_BASE_URL=http://dev.ccwin-in.com:23111/app |
|||
# VITE_BASE_URL_IMAGE=http://dev.ccwin-in.com:23111 |
|||
VITE_BASE_URL=https://tmsapp.hongxianggroup.com.cn |
|||
VITE_BASE_URL_IMAGE=https://tmsapp.hongxianggroup.com.cn |
@ -1,3 +1,2 @@ |
|||
|
|||
VITE_BASE_URL=http://dev.ccwin-in.com:25300/api/admin-api |
|||
VITE_BASE_URL_IMAGE=http://dev.ccwin-in.com:25300/admin-api |
|||
VITE_BASE_URL=http://dev.ccwin-in.com:25203/api/admin-api |
|||
VITE_BASE_URL_IMAGE=http://dev.ccwin-in.com:25203/api/admin-api |
@ -0,0 +1,2 @@ |
|||
dist |
|||
*.nvue |
@ -0,0 +1,49 @@ |
|||
{ |
|||
"parser": "vue-eslint-parser", |
|||
"env": { |
|||
"browser": true, |
|||
"commonjs": true, |
|||
"es2021": true |
|||
}, |
|||
"parserOptions": { |
|||
"ecmaVersion": 2021, |
|||
"parser": "@typescript-eslint/parser", |
|||
"sourceType": "module", |
|||
"ecmaFeatures": { |
|||
"jsx": true |
|||
} |
|||
}, |
|||
"extends": [ |
|||
"airbnb-base", |
|||
"eslint:recommended", |
|||
"plugin:prettier/recommended", |
|||
"plugin:vue/vue3-essential", |
|||
"plugin:@typescript-eslint/recommended" |
|||
], |
|||
"plugins": ["vue", "@typescript-eslint", "todo-ddl"], |
|||
"rules": { |
|||
"@typescript-eslint/ban-types": "off", |
|||
"@typescript-eslint/no-explicit-any": "off", |
|||
"@typescript-eslint/explicit-module-boundary-types": "off", |
|||
"import/extensions": "off", |
|||
"quotes": ["warn", "single"], |
|||
"semi": ["warn", "never"], |
|||
"import/no-unresolved": "off", |
|||
"todo-ddl/diy": "warn", |
|||
"import/prefer-default-export": "off", |
|||
"no-param-reassign": "warn", |
|||
"import/no-extraneous-dependencies": "off", |
|||
"max-len": "warn", |
|||
"no-restricted-syntax": "off", |
|||
"no-bitwise": "off", |
|||
"camelcase": "off", |
|||
"no-case-declarations": "off", |
|||
"@typescript-eslint/no-namespace": "off", |
|||
"no-undef": "off", |
|||
"no-promise-executor-return": "off", |
|||
"vue/multi-word-component-names": "off", |
|||
"@typescript-eslint/no-non-null-assertion": "off", |
|||
"@typescript-eslint/ban-ts-comment": "off", |
|||
"linebreak-style": "off" |
|||
} |
|||
} |
@ -1,21 +1,31 @@ |
|||
# Logs |
|||
logs |
|||
*.log |
|||
.DS_Store |
|||
node_modules/ |
|||
unpackage/ |
|||
dist/ |
|||
wxcomponents |
|||
|
|||
# local env files |
|||
.env.local |
|||
.env.*.local |
|||
|
|||
# Log files |
|||
npm-debug.log* |
|||
yarn-debug.log* |
|||
yarn-error.log* |
|||
pnpm-debug.log* |
|||
lerna-debug.log* |
|||
|
|||
node_modules |
|||
.DS_Store |
|||
dist |
|||
*.local |
|||
|
|||
# Editor directories and files |
|||
.project |
|||
.idea |
|||
.vscode |
|||
*.suo |
|||
*.ntvs* |
|||
*.njsproj |
|||
*.sln |
|||
*.sw? |
|||
*.sw* |
|||
.hbuilderx |
|||
|
|||
.gitee |
|||
.github |
|||
|
|||
package-lock.json |
|||
yarn.lock |
@ -1,4 +0,0 @@ |
|||
{ |
|||
"rootPathIndex": 1, |
|||
"webRoot": "${projectDir}" |
|||
} |
@ -1,24 +0,0 @@ |
|||
{ |
|||
// 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" : [ |
|||
{ |
|||
"app-plus" : { |
|||
"launchtype" : "local" |
|||
}, |
|||
"default" : { |
|||
"launchtype" : "local" |
|||
}, |
|||
"type" : "uniCloud" |
|||
}, |
|||
{ |
|||
"openVueDevtools" : true, |
|||
"type" : "uni-app:h5" |
|||
}, |
|||
{ |
|||
"playground" : "custom", |
|||
"type" : "uni-app:app-android" |
|||
} |
|||
] |
|||
} |
@ -0,0 +1,9 @@ |
|||
module.exports = { |
|||
printWidth: 700, // 一行的字符数,如果超过会进行换行,默认为80
|
|||
tabWidth: 2, // 一个 tab 代表几个空格数,默认为 2 个
|
|||
useTabs: false, //是否使用 tab 进行缩进,默认为false,表示用空格进行缩减
|
|||
singleQuote: true, // 字符串是否使用单引号,默认为 false,使用双引号
|
|||
semi: false, // 行尾是否使用分号,默认为true
|
|||
trailingComma: 'none', // 是否使用尾逗号
|
|||
bracketSpacing: true // 对象大括号直接是否有空格,默认为 true,效果:{ a: 1 }
|
|||
} |
@ -1,7 +1,7 @@ |
|||
# 设置基础镜像 |
|||
FROM win-nginx |
|||
|
|||
WORKDIR /opt/sfms3.0-uniapp |
|||
WORKDIR /opt/eam-pda |
|||
COPY nginx.conf /usr/local/nginx/conf/nginx.conf |
|||
# 将dist/build/h5/文件中的内容复制到 /opt/sfms3.0-uniapp 这个目录下面 |
|||
COPY dist/build/h5/ /opt/sfms3.0-uniapp |
|||
# 将dist/build/h5/文件中的内容复制到 /opt/eam-pda 这个目录下面 |
|||
COPY dist/build/h5/ /opt/eam-pda |
|||
|
@ -1,7 +0,0 @@ |
|||
# 设置基础镜像 |
|||
FROM win-nginx |
|||
|
|||
WORKDIR /opt/sfms3.0-uniapp |
|||
COPY nginx_prod.conf /usr/local/nginx/conf/nginx.conf |
|||
# 将dist/build/h5/文件中的内容复制到 /opt/sfms3.0-uniapp 这个目录下面 |
|||
COPY dist/build/h5/ /opt/sfms3.0-uniapp |
@ -0,0 +1,21 @@ |
|||
MIT License |
|||
|
|||
Copyright (c) 2021 sugar |
|||
|
|||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
of this software and associated documentation files (the "Software"), to deal |
|||
in the Software without restriction, including without limitation the rights |
|||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
copies of the Software, and to permit persons to whom the Software is |
|||
furnished to do so, subject to the following conditions: |
|||
|
|||
The above copyright notice and this permission notice shall be included in all |
|||
copies or substantial portions of the Software. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|||
SOFTWARE. |
@ -0,0 +1,260 @@ |
|||
# uni-vue3-ts-template |
|||
uni-app Vue3 + TypeScript + Vite + Pinia + Unocss 模板项目 |
|||
|
|||
支持小程序,H5,App |
|||
|
|||
![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzIxODc4OTk1OQ==653218789959) |
|||
|
|||
![Unocss](https://fastly.jsdelivr.net/gh/MellowCo/image-host/2022/202211121156442.png) |
|||
|
|||
| H5 | 微信小程序 | App(iOS) | App(Android) | |
|||
| :-------------------------------------------------------------------------: | :-------------------------------------------------------------------------: | :-------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------: | |
|||
| ![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzE5Mzc4MzUyMQ==653193783521) | ![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzE5Mzc1Mzk1MQ==653193753951) | ![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzIxMDc2NTcwNg==653210765706) | <img src="https://img.cdn.sugarat.top/mdImg/MTY1MzIxMzkyOTQxNg==653213929416" width="360"/> | |
|||
|
|||
其它模板 |
|||
* Vue3的uni-app 纯js模板:[uni-app-template](https://github.com/ATQQ/uni-app-template) |
|||
* Vue3的Web应用模板:[vite-vue3-template](https://github.com/ATQQ/vite-vue3-template) |
|||
|
|||
## Env Suggest |
|||
**Node >= 14.19** |
|||
|
|||
**pnpm 7** |
|||
|
|||
**Registry taobao - https://registry.npmmirror.com/** |
|||
|
|||
## Use This Template |
|||
```sh |
|||
npx degit atqq/uni-vue3-ts-template#main my-uni-vue3-ts-vite-project |
|||
``` |
|||
## Feature |
|||
### Prod |
|||
* [x] [Vue3](https://vuejs.org/) |
|||
* [x] [Pinia](https://pinia.vuejs.org/) - replace vuex |
|||
* [x] [Axios](https://github.com/axios/axios) |
|||
* UI/组件库 |
|||
* [x] [uView](https://vkuviewdoc.fsq.pub/) - vk-uview-ui |
|||
* [ ] [uni-ui](https://github.com/dcloudio/uni-ui) - 待接入 |
|||
### Dev |
|||
* [x] [Vite](https://github.com/vitejs/vite) |
|||
* [x] [TypeScript](https://github.com/microsoft/TypeScript/#readme) |
|||
* [x] [Sass](https://github.com/sass/sass) |
|||
* [x] [Less](https://github.com/less/less.js) |
|||
* [x] [Eslint](https://eslint.org/) |
|||
* [x] [Prettier](https://prettier.io/) |
|||
* [x] [Vitest](https://vitest.dev/) - replace jest |
|||
* [x] [unocss](https://github.com/unocss/unocss) - 即时按需原子 css 引擎 |
|||
* [x] GitHooks [simple-git-hooks](https://github.com/toplenboren/simple-git-hooks#readme) |
|||
* ~~LintStaged~~ |
|||
* ~~StyleLint~~ |
|||
|
|||
## 使用 |
|||
### 安装依赖 |
|||
**建议使用pnpm,依赖安装速度更快** |
|||
```sh |
|||
npm i -g pnpm |
|||
``` |
|||
|
|||
```sh |
|||
pnpm install |
|||
``` |
|||
|
|||
**MAC M1(ARM芯片),其它操作系统无需关注**,正常运行需要手动安装 `esbuild-darwin-64`即可 |
|||
```sh |
|||
pnpm add esbuild-darwin-64@0.15.13 -D |
|||
``` |
|||
|
|||
## 本地启动 |
|||
### 微信小程序 |
|||
```sh |
|||
# 构建出产物 |
|||
pnpm dev:mp-weixin |
|||
``` |
|||
|
|||
> **Q1:** 如果dev的时候发现报错,可以尝试删除`node_modules`之后再在命令行中运行`pnpm install --shamefully-hoist`重新安装依赖再`pnpm dev:mp-weixin` |
|||
> |
|||
> [详细参考文档](https://pnpm.io/zh/faq#%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%883) |
|||
|
|||
> **Q2:** 如果运行白屏,有报错信息 “app.js错误ReferenceError: regeneratorRuntime is not defined” |
|||
> |
|||
> 参考[解决方案](https://blog.csdn.net/FUFCY/article/details/125160828) 给微信小程序IDE开启**增强编译选项** |
|||
|
|||
然后将编译结果`dist/dev/mp-weixin`导入微信开发者工具即可运行 |
|||
|
|||
<details> |
|||
<summary>点击查看 导入详细步骤</summary> |
|||
|
|||
![图片](https://img.cdn.sugarat.top/mdImg/MTYzNzQxNjc3MjA4Mw==637416772083) |
|||
|
|||
![图片](https://img.cdn.sugarat.top/mdImg/MTYzNzQxNjg4MTUwNA==637416881504) |
|||
|
|||
![图片](https://img.cdn.sugarat.top/mdImg/MTYzNzQxNjY3OTY0NQ==637416679645) |
|||
|
|||
</details> |
|||
|
|||
### H5 |
|||
```sh |
|||
# CSR |
|||
pnpm dev:h5 |
|||
# SSR |
|||
pnpm dev:h5:ssr |
|||
``` |
|||
|
|||
根据提示,打开对应地址即可访问 |
|||
|
|||
![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzIxMTE0MDEzMg==653211140132) |
|||
|
|||
### App |
|||
>**Q1:** 如启动到App侧有报错? |
|||
>请更新至最新的HBuilderX-Alpha客户端 |
|||
#### 安装一些必要工具 |
|||
需要使用 `uni-app` 官方提供的 [HBuilderX](https://www.dcloud.io/hbuilderx.html) 启动项目 |
|||
|
|||
**Android模拟器在MacOSX、Windows上都可以安装;iOS模拟器只能在MacOSX上安装。** |
|||
|
|||
先安装相关模拟器,[详细参考文档](https://hx.dcloud.net.cn/Tutorial/App/installSimulator) |
|||
* 安卓:[夜神模拟器](https://www.yeshen.com/blog/) |
|||
* iOS:Mac上安装Xcode |
|||
|
|||
准备就绪后,使用 HBuilderX 打开项目 |
|||
#### iOS模拟器运行 |
|||
通过顶部菜单栏,找到运行入口 |
|||
|
|||
![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzIxMjk1MTgzNw==653212951837) |
|||
|
|||
选择一个目标设备,点击启动即可 |
|||
|
|||
![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzIxMjk3NDM0NQ==653212974345) |
|||
|
|||
#### Android模拟器运行 |
|||
这里以[夜神模拟器](https://www.yeshen.com/blog/)为例 |
|||
|
|||
<details> |
|||
<summary>点击查看 详细步骤</summary> |
|||
|
|||
先通过 HBuilderX 修改模拟器端口为 `62001` |
|||
|
|||
![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzIxNDAzMjIwNg==653214032206) |
|||
|
|||
打开夜神模拟器 |
|||
|
|||
![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzIxNDA5OTYxNg==653214099616) |
|||
|
|||
选择运行到 Android 基座 |
|||
|
|||
![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzIxNDEzMzI0OA==653214133248) |
|||
|
|||
选择已经打开的模拟器,点击运行即可 |
|||
![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzIxNDIxNjczNw==653214216737) |
|||
|
|||
![图片](https://img.cdn.sugarat.top/mdImg/MTY1MzIxMzkyOTQxNg==653213929416) |
|||
|
|||
</details> |
|||
|
|||
|
|||
## 打包构建 |
|||
### 微信小程序 |
|||
``` |
|||
pnpm build:mp-weixin |
|||
``` |
|||
### H5 |
|||
```sh |
|||
# CSR |
|||
pnpm build:h5 |
|||
# SSR |
|||
pnpm build:h5:ssr |
|||
``` |
|||
|
|||
### App |
|||
基于 `HBuilderX` 参考[官方文档](https://hx.dcloud.net.cn/Tutorial/App/SafePack)进行进一步的操作 |
|||
|
|||
其它更多运行脚本 查看 [package.json](./package.json)中的scripts |
|||
|
|||
## css预处理 |
|||
|
|||
### 已配置`scss`和`less`全局变量 |
|||
```typescript |
|||
// vite.config.ts |
|||
export default defineConfig({ |
|||
// ...... |
|||
css: { |
|||
preprocessorOptions: { |
|||
scss: { |
|||
additionalData: '@import "@/static/styles/variables.scss";' |
|||
}, |
|||
less: { |
|||
additionalData: '@import "@/static/styles/variables.less";' |
|||
} |
|||
} |
|||
} |
|||
}) |
|||
``` |
|||
|
|||
|
|||
|
|||
`additionalData`的值是文件的路径,可以按照自己业务需求去修改,**如果项目样式变量分的比较细,可以使用一个样式文件引入多个变量样式文件,然后在这里引入入口文件** |
|||
|
|||
|
|||
|
|||
## 别名配置 |
|||
|
|||
如果我们想要在`import`的时候 src 的路径简写成`@`,下面的就是配置 vite 的别名,[属性类型请查看vite文档](https://vitejs.cn/config/#resolve-alias) |
|||
|
|||
- `@` 代替 `./src` |
|||
- `@components`代替`./src/components` |
|||
|
|||
```typescript |
|||
// vite.config.ts |
|||
export default defineConfig({ |
|||
// ...... |
|||
resolve: { |
|||
alias: { |
|||
'@': path.resolve(__dirname, './src'), |
|||
'@components': path.resolve(__dirname, './src/components') |
|||
} |
|||
} |
|||
}) |
|||
``` |
|||
|
|||
例子: |
|||
|
|||
```diff |
|||
// pages/index/index.vue |
|||
- import Hello from '../../components/hello/index.vue' |
|||
+ import Hello from '@/components/hello/index.vue' |
|||
// 或者 |
|||
+ import Hello from '@components/hello/index.vue' |
|||
``` |
|||
|
|||
|
|||
|
|||
### ts |
|||
|
|||
如果是使用ts开发,这样还不够,ts不会识别路径的别名,显示找不到模块的报错,这个时候需要修改 `tsconfig.json` 文件,纠正下路径才可以。 |
|||
|
|||
|
|||
|
|||
```diff |
|||
// tsconfig.json |
|||
{ |
|||
// ...... |
|||
"compilerOptions": { |
|||
// ...... |
|||
+ "baseUrl": "./", |
|||
+ "paths": { |
|||
+ "@/*": ["src/*"], |
|||
+ "@components/*": ["src/components/*"] |
|||
} |
|||
}, |
|||
} |
|||
|
|||
``` |
|||
|
|||
添加 `baseUrl` 和 `paths` 参数,就可以完美解决编辑器的报错提示了! |
|||
|
|||
## 原子化css |
|||
* [unocss](https://github.com/unocss/unocss) - 即时按需原子 css 引擎 |
|||
* [unocss-preset-weapp](https://github.com/MellowCo/unocss-preset-weapp) - 兼容小程序 unocss 预设 |
|||
|
|||
> 支持小程序,h5,app |
|||
|
|||
![](https://fastly.jsdelivr.net/gh/MellowCo/image-host/2022/202211121156442.png) |
Binary file not shown.
Binary file not shown.
@ -1,35 +0,0 @@ |
|||
{ |
|||
|
|||
"name": "TestModule", |
|||
|
|||
"id": "TestModule", |
|||
|
|||
"version": "1.0.0", |
|||
|
|||
"description": "打印", |
|||
|
|||
"_dp_type": "nativeplugin", |
|||
|
|||
"_dp_nativeplugin": { |
|||
|
|||
"android": { |
|||
|
|||
"integrateType": "aar", |
|||
|
|||
"plugins": [ |
|||
|
|||
{ |
|||
|
|||
"type": "module", |
|||
"name": "TestModule", |
|||
"class": "io.dcloud.uniplugin.TestModule" |
|||
|
|||
} |
|||
|
|||
] |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
} |
@ -1,57 +0,0 @@ |
|||
user root; |
|||
worker_processes 2; |
|||
|
|||
events { |
|||
worker_connections 1024; |
|||
} |
|||
|
|||
http { |
|||
include mime.types; |
|||
charset utf-8,gbk; |
|||
default_type application/octet-stream; |
|||
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' |
|||
'$status $body_bytes_sent "$http_referer" ' |
|||
'"$http_user_agent" "$http_x_forwarded_for" "$request_time $upstream_response_time"'; |
|||
|
|||
proxy_cache_path /opt/nginx_cache/ levels=1:2 keys_zone=my_zone:10m inactive=300s max_size=5g; |
|||
access_log logs/access.log main; |
|||
sendfile on; |
|||
#tcp_nopush on; |
|||
keepalive_timeout 600s; |
|||
client_max_body_size 200m; |
|||
gzip on; |
|||
gzip_min_length 10k; |
|||
gzip_comp_level 9; |
|||
gzip_buffers 4 16k; |
|||
gzip_types text/plain application/javascript text/css application/xml text/javascript image/jpeg image/gif image/png; |
|||
gzip_vary on; |
|||
gzip_disable "MSIE [1-6]\."; |
|||
upstream sfms3.0 { |
|||
server localhost:90 weight=10 max_fails=3 fail_timeout=10s; |
|||
} |
|||
server { |
|||
listen 81; |
|||
server_name_in_redirect off; |
|||
server_name _; |
|||
location /api/ { |
|||
proxy_pass http://sfms3.0/; |
|||
proxy_next_upstream http_500 http_502 http_503 http_504 error timeout invalid_header; |
|||
proxy_set_header X-Forwared-For $proxy_add_x_forwarded_for; |
|||
proxy_set_header Host $http_host; |
|||
proxy_set_header X-Real-IP $remote_addr; |
|||
proxy_set_header X-Forwarded-For $http_x_forwarded_for; |
|||
} |
|||
location /profile/ { |
|||
alias /opt/profile/; |
|||
index index.html index.htm; |
|||
} |
|||
location / { |
|||
proxy_cache my_zone; |
|||
proxy_cache_valid 200 304 12h; |
|||
proxy_cache_key $host$uri$is_args$args; |
|||
try_files $uri $uri/ /index.html; |
|||
root /opt/sfms3.0-uniapp; |
|||
index index.html index.htm; |
|||
} |
|||
} |
|||
} |
File diff suppressed because it is too large
@ -1,50 +1,80 @@ |
|||
{ |
|||
"name": "uni-preset-vue", |
|||
"version": "0.0.0", |
|||
"name": "闻荫APP", |
|||
"version": "1.0.0", |
|||
"private": true, |
|||
"scripts": { |
|||
"dev:app": "uni -p app", |
|||
"dev:app-android": "uni -p app-android", |
|||
"dev:app-ios": "uni -p app-ios", |
|||
"dev": "uni", |
|||
"dev:h5:ssr": "uni --ssr", |
|||
"dev:mp-weixin": "uni -p mp-weixin", |
|||
"hella8:app": "uni build -p app --mode hella8", |
|||
"hella8:app-android": "uni build -p app-android --mode hella8", |
|||
"hella8:app-ios": "uni build -p app-ios --mode hella8", |
|||
"hella8:h5:ssr": "uni build --ssr --mode hella8", |
|||
"hella8:mp-weixin": "uni build -p mp-weixin --mode hella8", |
|||
"dev:app": "uni -p app", |
|||
"dev:custom": "uni -p", |
|||
"test": "uni build --mode test", |
|||
"hella8": "uni build --mode hella8", |
|||
"hella9": "uni build --mode hella9", |
|||
"hella13": "uni build --mode hella13", |
|||
"hella14": "uni build --mode hella14", |
|||
"hella15": "uni build --mode hella15", |
|||
"hella16": "uni build --mode hella16" |
|||
"test:mp-weixin": "uni build -p mp-weixin", |
|||
"test:app": "uni build -p app", |
|||
"test:custom": "uni build -p", |
|||
"prod": "uni build --mode production", |
|||
"prod:mp-weixin": "uni build -p mp-weixin --mode production", |
|||
"prod:app": "uni build -p app --mode production", |
|||
"prod:custom": "uni build -p --mode production" |
|||
}, |
|||
"dependencies": { |
|||
"@dcloudio/uni-app": "3.0.0-3090920231225001", |
|||
"@dcloudio/uni-app-plus": "3.0.0-3090920231225001", |
|||
"@dcloudio/uni-components": "3.0.0-3090920231225001", |
|||
"@dcloudio/uni-h5": "3.0.0-3090920231225001", |
|||
"@dcloudio/uni-mp-weixin": "3.0.0-3090920231225001", |
|||
"less": "^4.2.0", |
|||
"vue": "^3.2.45", |
|||
"@dcloudio/uni-app": "3.0.0-alpha-3060920221114001", |
|||
"@dcloudio/uni-app-plus": "3.0.0-alpha-3060920221114001", |
|||
"@dcloudio/uni-components": "3.0.0-alpha-3060920221114001", |
|||
"@dcloudio/uni-h5": "3.0.0-alpha-3060920221114001", |
|||
"@dcloudio/uni-mp-alipay": "3.0.0-alpha-3060920221114001", |
|||
"@dcloudio/uni-mp-baidu": "3.0.0-alpha-3060920221114001", |
|||
"@dcloudio/uni-mp-kuaishou": "3.0.0-alpha-3060920221114001", |
|||
"@dcloudio/uni-mp-lark": "3.0.0-alpha-3060920221114001", |
|||
"@dcloudio/uni-mp-qq": "3.0.0-alpha-3060920221114001", |
|||
"@dcloudio/uni-mp-toutiao": "3.0.0-alpha-3060920221114001", |
|||
"@dcloudio/uni-mp-weixin": "3.0.0-alpha-3060920221114001", |
|||
"@dcloudio/uni-quickapp-webview": "3.0.0-alpha-3060920221114001", |
|||
"axios": "^0.27.2", |
|||
"cz-git": "^1.4.1", |
|||
"decimal.js": "^10.4.3", |
|||
"or": "^0.2.0", |
|||
"pinia": "^2.0.35", |
|||
"vk-uview-ui": "^1.3.7", |
|||
"vue": "^3.2.41", |
|||
"vue-demi": "latest", |
|||
"vue-i18n": "^9.1.9", |
|||
"vuex": "^4.1.0" |
|||
"vuex": "^4.0.2" |
|||
}, |
|||
"devDependencies": { |
|||
"@dcloudio/types": "^3.3.2", |
|||
"@dcloudio/uni-automator": "3.0.0-3090920231225001", |
|||
"@dcloudio/uni-cli-shared": "3.0.0-3090920231225001", |
|||
"@dcloudio/uni-stacktracey": "3.0.0-3090920231225001", |
|||
"@dcloudio/vite-plugin-uni": "3.0.0-3090920231225001", |
|||
"@vue/runtime-core": "^3.2.45", |
|||
"axios": "^1.3.4", |
|||
"decimal.js": "^10.4.3", |
|||
"jwt-decode": "^3.1.2", |
|||
"sass": "^1.70.0", |
|||
"sass-loader": "^14.1.0", |
|||
"vite": "4.0.3", |
|||
"vue-clipboard2": "^0.3.3" |
|||
"@commitlint/cli": "^17.4.2", |
|||
"@commitlint/config-conventional": "^17.4.2", |
|||
"@dcloudio/types": "^3.0.16", |
|||
"@dcloudio/uni-automator": "3.0.0-alpha-3060920221114001", |
|||
"@dcloudio/uni-cli-shared": "3.0.0-alpha-3060920221114001", |
|||
"@dcloudio/uni-stacktracey": "3.0.0-alpha-3060920221114001", |
|||
"@dcloudio/vite-plugin-uni": "3.0.0-alpha-3060920221114001", |
|||
"@types/node": "^17.0.45", |
|||
"@typescript-eslint/eslint-plugin": "^5.30.3", |
|||
"@typescript-eslint/parser": "^5.30.3", |
|||
"@vitejs/plugin-vue": "^2.3.3", |
|||
"@vitest/ui": "^0.10.5", |
|||
"c8": "^7.11.3", |
|||
"czg": "^1.4.1", |
|||
"eslint": "^8.19.0", |
|||
"eslint-config-airbnb-base": "^15.0.0", |
|||
"eslint-config-prettier": "^8.5.0", |
|||
"eslint-plugin-import": "^2.26.0", |
|||
"eslint-plugin-prettier": "^4.2.1", |
|||
"eslint-plugin-todo-ddl": "^1.1.1", |
|||
"eslint-plugin-vue": "^9.1.1", |
|||
"jsdom": "^24.0.0", |
|||
"less": "^4.1.3", |
|||
"prettier": "^2.7.1", |
|||
"sass": "^1.53.0", |
|||
"simple-git-hooks": "^2.8.1", |
|||
"typescript": "^4.7.4", |
|||
"unocss": "^0.46.4", |
|||
"unocss-preset-weapp": "^0.2.1", |
|||
"vite": "^3.1.8", |
|||
"vite-plugin-eslint": "^1.6.1", |
|||
"vitest": "^0.16.0" |
|||
}, |
|||
"simple-git-hooks": { |
|||
"commit-msg": "npx --no-install commitlint --edit \"$1\"" |
|||
} |
|||
} |
|||
|
@ -1,2 +0,0 @@ |
|||
别名:testalias |
|||
密码: wms3.0 |
File diff suppressed because it is too large
@ -1,10 +0,0 @@ |
|||
/// <reference types='@dcloudio/types' />
|
|||
import 'vue' |
|||
|
|||
declare module '@vue/runtime-core' { |
|||
type Hooks = App.AppInstance & Page.PageInstance; |
|||
|
|||
interface ComponentCustomOptions extends Hooks { |
|||
|
|||
} |
|||
} |
@ -0,0 +1,114 @@ |
|||
import axios from 'axios' |
|||
|
|||
import { getFullURL } from '@/utils/http' |
|||
import { getAccessToken, removeToken } from '@/utils/auth' |
|||
|
|||
const instance = axios.create({ |
|||
baseURL: import.meta.env.VITE_BASE_URL, |
|||
adapter(config) { |
|||
const { url, method, data, params, headers, baseURL, paramsSerializer } = |
|||
config |
|||
return new Promise((resolve, reject) => { |
|||
uni.request({ |
|||
method: method!.toUpperCase() as any, |
|||
url: getFullURL(baseURL || '', url!, params, paramsSerializer), |
|||
header: headers, |
|||
data, |
|||
dataType: 'json', |
|||
responseType: config.responseType, |
|||
success: (res : any) => { |
|||
resolve(res) |
|||
}, |
|||
fail: (error : any) => { |
|||
reject(error) |
|||
} |
|||
}) |
|||
}) |
|||
} |
|||
}) |
|||
|
|||
|
|||
/** |
|||
* 请求拦截 |
|||
*/ |
|||
instance.interceptors.request.use((config) => { |
|||
const { method, params, url } = config |
|||
// 附带鉴权的token
|
|||
const tenantId = 1 |
|||
const headers : any = { |
|||
token: getAccessToken(), |
|||
"tenant-id":tenantId, |
|||
'Authorization': 'Bearer ' + getAccessToken() |
|||
} |
|||
if (uni.getStorageSync('openId')) { |
|||
headers['openId'] = uni.getStorageSync('openId') |
|||
} |
|||
// 不缓存get请求
|
|||
if (method === 'get') { |
|||
headers['Cache-Control'] = 'no-cache' |
|||
} |
|||
// delete请求参数放入body中
|
|||
if (method === 'delete') { |
|||
headers['Content-type'] = 'application/json;' |
|||
Object.assign(config, { |
|||
data: params, |
|||
params: {} |
|||
}) |
|||
} |
|||
|
|||
return { |
|||
...config, |
|||
headers |
|||
} |
|||
}) |
|||
|
|||
/** |
|||
* 响应拦截 |
|||
*/ |
|||
instance.interceptors.response.use((v) => { |
|||
const code = v.data?.code || 200 |
|||
if (code === 401) { |
|||
// alert('即将跳转登录页。。。', '登录过期')
|
|||
// setTimeout(redirectHome, 1500)
|
|||
removeToken() |
|||
uni.showModal({ |
|||
title: '系统提示', |
|||
content: '登录状态已过期,您可以继续留在该页面,或者重新登录', |
|||
cancelText: '关闭', |
|||
confirmText: '重新登录', |
|||
success: function (res) { |
|||
if (res.confirm) { |
|||
uni.reLaunch({ url: '/pages/login' }) |
|||
} |
|||
} |
|||
}) |
|||
return v.data |
|||
} else if (code === 500) { |
|||
uni.showToast({ |
|||
title: v.data.msg, |
|||
icon: 'none' |
|||
}) |
|||
return v.data |
|||
} else if (code !== 200) { |
|||
uni.showToast({ |
|||
title: v.data.msg, |
|||
icon: 'none' |
|||
}) |
|||
return v.data |
|||
} |
|||
|
|||
// @ts-ignore
|
|||
if ((v.status || v.statusCode) === 200) { |
|||
return v.data |
|||
}else{ |
|||
|
|||
} |
|||
return Promise.reject(v) |
|||
},error=>{ |
|||
console.log(error) |
|||
uni.showToast({ |
|||
title: '网络错误', |
|||
icon: 'none' |
|||
}) |
|||
}) |
|||
export default instance |
@ -1,66 +0,0 @@ |
|||
|
|||
import storage from '../common/utils/storage' |
|||
|
|||
function service(options = {}) { |
|||
var token = storage.getStorage(storage.constant.token) |
|||
var tenantId = 1 |
|||
// if(getApp()!=undefined){
|
|||
// tenantId = getApp().globalData.tenantId
|
|||
// }
|
|||
|
|||
// if(getApp()!=undefined){
|
|||
// requestUrl = getApp().globalData.request_url
|
|||
// }
|
|||
var requestUrl = "" |
|||
requestUrl = import.meta.env.VITE_BASE_URL |
|||
|
|||
options.header = { |
|||
"content-type": "application/json", |
|||
"Authorization": "Bearer "+token, |
|||
"dataType":"json", |
|||
"tenant-id":tenantId |
|||
}; |
|||
options.timeout = 10000 |
|||
|
|||
options.url = requestUrl+options.url |
|||
|
|||
return new Promise((resolve, reject) => { |
|||
options.success = (res) => { |
|||
if (res ) { |
|||
if(res.statusCode == 200){ |
|||
if(res.data.code==0){ |
|||
resolve(res.data); |
|||
}else { |
|||
reject("系统异常:"+res.data.msg) |
|||
console.log("系统异常",res.data.msg) |
|||
} |
|||
|
|||
}else { |
|||
reject("系统异常:"+ res.data.msg) |
|||
console.log("系统异常",res.data.msg) |
|||
} |
|||
|
|||
} else { |
|||
reject("系统异常:"+res.data.msg) |
|||
console.log("系统异常",res.data.msg) |
|||
} |
|||
}; |
|||
options.fail = (error) => { |
|||
var message = error.errMsg |
|||
if (message === 'Network Error') { |
|||
message = '接口连接异常' |
|||
} else if (message.includes('timeout')) { |
|||
message = '接口请求超时' |
|||
} else if (message.includes('Request failed with status code')) { |
|||
message = '接口' + message.substr(message.length - 3) + '异常' |
|||
} |
|||
reject("系统异常:"+message); |
|||
console.log("系统异常",message) |
|||
}; |
|||
uni.request(options); |
|||
}); |
|||
} |
|||
|
|||
|
|||
|
|||
export default service; |
@ -1,196 +0,0 @@ |
|||
function getLocalFilePath(path) { |
|||
if (path.indexOf('_www') === 0 || path.indexOf('_doc') === 0 || path.indexOf('_documents') === 0 || path.indexOf('_downloads') === 0) { |
|||
return path |
|||
} |
|||
if (path.indexOf('file://') === 0) { |
|||
return path |
|||
} |
|||
if (path.indexOf('/storage/emulated/0/') === 0) { |
|||
return path |
|||
} |
|||
if (path.indexOf('/') === 0) { |
|||
var localFilePath = plus.io.convertAbsoluteFileSystem(path) |
|||
if (localFilePath !== path) { |
|||
return localFilePath |
|||
} else { |
|||
path = path.substr(1) |
|||
} |
|||
} |
|||
return '_www/' + path |
|||
} |
|||
|
|||
function dataUrlToBase64(str) { |
|||
var array = str.split(',') |
|||
return array[array.length - 1] |
|||
} |
|||
|
|||
var index = 0 |
|||
function getNewFileId() { |
|||
return Date.now() + String(index++) |
|||
} |
|||
|
|||
function biggerThan(v1, v2) { |
|||
var v1Array = v1.split('.') |
|||
var v2Array = v2.split('.') |
|||
var update = false |
|||
for (var index = 0; index < v2Array.length; index++) { |
|||
var diff = v1Array[index] - v2Array[index] |
|||
if (diff !== 0) { |
|||
update = diff > 0 |
|||
break |
|||
} |
|||
} |
|||
return update |
|||
} |
|||
|
|||
export async function pathToBase64(path) { |
|||
return await new Promise(async function(resolve, reject) { |
|||
if (typeof window === 'object' && 'document' in window) { |
|||
if (typeof FileReader === 'function') { |
|||
var xhr =await new XMLHttpRequest() |
|||
xhr.open('GET', path, true) |
|||
xhr.responseType = 'blob' |
|||
xhr.onload = function() { |
|||
if (this.status === 200) { |
|||
let fileReader = new FileReader() |
|||
fileReader.onload = function(e) { |
|||
resolve(e.target.result) |
|||
} |
|||
fileReader.onerror = reject |
|||
fileReader.readAsDataURL(this.response) |
|||
} |
|||
} |
|||
xhr.onerror = reject |
|||
xhr.send() |
|||
return |
|||
} |
|||
var canvas = document.createElement('canvas') |
|||
var c2x = canvas.getContext('2d') |
|||
var img = new Image |
|||
img.onload = function() { |
|||
canvas.width = img.width |
|||
canvas.height = img.height |
|||
c2x.drawImage(img, 0, 0) |
|||
resolve(canvas.toDataURL()) |
|||
canvas.height = canvas.width = 0 |
|||
} |
|||
img.onerror = reject |
|||
img.src = path |
|||
return |
|||
} |
|||
if (typeof plus === 'object') { |
|||
plus.io.resolveLocalFileSystemURL(getLocalFilePath(path), function(entry) { |
|||
entry.file(function(file) { |
|||
var fileReader = new plus.io.FileReader() |
|||
fileReader.onload = function(data) { |
|||
resolve(data.target.result) |
|||
} |
|||
fileReader.onerror = function(error) { |
|||
reject(error) |
|||
} |
|||
fileReader.readAsDataURL(file) |
|||
}, function(error) { |
|||
reject(error) |
|||
}) |
|||
}, function(error) { |
|||
reject(error) |
|||
}) |
|||
return |
|||
} |
|||
if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) { |
|||
wx.getFileSystemManager().readFile({ |
|||
filePath: path, |
|||
encoding: 'base64', |
|||
success: function(res) { |
|||
resolve('data:image/png;base64,' + res.data) |
|||
}, |
|||
fail: function(error) { |
|||
reject(error) |
|||
} |
|||
}) |
|||
return |
|||
} |
|||
reject(new Error('not support')) |
|||
}) |
|||
} |
|||
|
|||
export function base64ToPath(base64) { |
|||
return new Promise(function(resolve, reject) { |
|||
if (typeof window === 'object' && 'document' in window) { |
|||
base64 = base64.split(',') |
|||
var type = base64[0].match(/:(.*?);/)[1] |
|||
var str = atob(base64[1]) |
|||
var n = str.length |
|||
var array = new Uint8Array(n) |
|||
while (n--) { |
|||
array[n] = str.charCodeAt(n) |
|||
} |
|||
return resolve((window.URL || window.webkitURL).createObjectURL(new Blob([array], { type: type }))) |
|||
} |
|||
var extName = base64.split(',')[0].match(/data\:\S+\/(\S+);/) |
|||
if (extName) { |
|||
extName = extName[1] |
|||
} else { |
|||
reject(new Error('base64 error')) |
|||
} |
|||
var fileName = getNewFileId() + '.' + extName |
|||
if (typeof plus === 'object') { |
|||
var basePath = '_doc' |
|||
var dirPath = 'uniapp_temp' |
|||
var filePath = basePath + '/' + dirPath + '/' + fileName |
|||
if (!biggerThan(plus.os.name === 'Android' ? '1.9.9.80627' : '1.9.9.80472', plus.runtime.innerVersion)) { |
|||
plus.io.resolveLocalFileSystemURL(basePath, function(entry) { |
|||
entry.getDirectory(dirPath, { |
|||
create: true, |
|||
exclusive: false, |
|||
}, function(entry) { |
|||
entry.getFile(fileName, { |
|||
create: true, |
|||
exclusive: false, |
|||
}, function(entry) { |
|||
entry.createWriter(function(writer) { |
|||
writer.onwrite = function() { |
|||
resolve(filePath) |
|||
} |
|||
writer.onerror = reject |
|||
writer.seek(0) |
|||
writer.writeAsBinary(dataUrlToBase64(base64)) |
|||
}, reject) |
|||
}, reject) |
|||
}, reject) |
|||
}, reject) |
|||
return |
|||
} |
|||
var bitmap = new plus.nativeObj.Bitmap(fileName) |
|||
bitmap.loadBase64Data(base64, function() { |
|||
bitmap.save(filePath, {}, function() { |
|||
bitmap.clear() |
|||
resolve(filePath) |
|||
}, function(error) { |
|||
bitmap.clear() |
|||
reject(error) |
|||
}) |
|||
}, function(error) { |
|||
bitmap.clear() |
|||
reject(error) |
|||
}) |
|||
return |
|||
} |
|||
if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) { |
|||
var filePath = wx.env.USER_DATA_PATH + '/' + fileName |
|||
wx.getFileSystemManager().writeFile({ |
|||
filePath: filePath, |
|||
data: dataUrlToBase64(base64), |
|||
encoding: 'base64', |
|||
success: function() { |
|||
resolve(filePath) |
|||
}, |
|||
fail: function(error) { |
|||
reject(error) |
|||
} |
|||
}) |
|||
return |
|||
} |
|||
reject(new Error('not support')) |
|||
}) |
|||
} |
@ -0,0 +1,41 @@ |
|||
import http from './http' |
|||
|
|||
// 登录方法
|
|||
export function login(username, password, captchaVerification, tenantName, rememberMe, code, uuid) { |
|||
const data = { |
|||
username, |
|||
password, |
|||
captchaVerification, |
|||
tenantName, |
|||
rememberMe, |
|||
code, |
|||
uuid, |
|||
} |
|||
return http.post('/system/auth/login', data) |
|||
} |
|||
|
|||
// 获取用户详细信息
|
|||
export function getInfo() { |
|||
return http.get('/system/user/profile/get') |
|||
} |
|||
// 获取权限
|
|||
export function getPermissionInfo() { |
|||
return http.get('/system/auth/get-permission-info') |
|||
} |
|||
// 退出方法
|
|||
export function logout() { |
|||
return http.post('/system/auth/logout') |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
File diff suppressed because it is too large
@ -0,0 +1,13 @@ |
|||
/// <reference types="vite/client" />
|
|||
|
|||
declare module '*.vue' { |
|||
import { DefineComponent } from 'vue' |
|||
|
|||
const component: DefineComponent<{}, {}, any> |
|||
export default component |
|||
} |
|||
|
|||
interface ImportMetaEnv { |
|||
VITE_TITLE: string |
|||
VITE_BASE_URL: string |
|||
} |
@ -1,74 +0,0 @@ |
|||
import App from './App' |
|||
import store from './store' |
|||
import './router/my_router.js'; //引入拦截
|
|||
import VueClipboard from 'vue-clipboard2' //复制粘贴
|
|||
import uView from './uni_modules/vk-uview-ui';// 引入 uView UI
|
|||
import comMessage from './mycomponents/common/comMessage.vue' |
|||
|
|||
// #ifndef VUE3
|
|||
import Vue from 'vue' |
|||
console.log("Vuew2222"); |
|||
Vue.config.productionTip = false |
|||
Vue.prototype.$store = store |
|||
Vue.prototype.$adpid = "1111111111" |
|||
Vue.prototype.$backgroundAudioData = { |
|||
playing: false, |
|||
playTime: 0, |
|||
formatedPlayTime: '00:00:00' |
|||
} |
|||
App.mpType = 'app' |
|||
const app = new Vue({ |
|||
store, |
|||
...App |
|||
}) |
|||
app.$mount() |
|||
// #endif
|
|||
|
|||
import { |
|||
createSSRApp |
|||
} from "vue"; |
|||
export function createApp() { |
|||
const app = createSSRApp(App); |
|||
app.use(store) |
|||
app.use(VueClipboard) |
|||
app.use(uView) |
|||
app.component('comMessage', comMessage) |
|||
console.log("网络22请求") |
|||
// startApp(app);
|
|||
return { |
|||
app, |
|||
}; |
|||
} |
|||
|
|||
export function startApp(app) { |
|||
uni.request({ |
|||
url: `./static/config.json?t=${new Date().getTime()}`, |
|||
method: 'get', |
|||
data: {}, |
|||
success: (res) => { |
|||
if (res.data != "") { |
|||
//在配置中读url,company等信息
|
|||
// app.config.globalProperties.$baseInfo = res.data.baseInfo;
|
|||
// getApp().globalData.dev_url = res.data.baseInfo.dev.value;
|
|||
// getApp().globalData.request_url = res.data.baseInfo.request_url.value;
|
|||
// getApp().globalData.tenantId = res.data.baseInfo.tenantId.value;
|
|||
// app.config.globalProperties.$recepit_configList = res.data.recepit_configList;
|
|||
// getApp().globalData.recepit_configList = res.data.recepit_configList;
|
|||
// getApp().globalData.feed_configList = res.data.feed_configList;
|
|||
// getApp().globalData.isDevelopment = res.data.baseInfo.isDevelopment.value
|
|||
// Vue.prototype.$dev_url = res.data.baseInfo.dev.value;
|
|||
// console.log("网络",res.data.baseInfo.request_url.value)
|
|||
// console.log("开发环境12",res.data.baseInfo.isDevelopment.value)
|
|||
// uni.setStorageSync("request_url",res.data.baseInfo.request_url.value)
|
|||
// uni.setStorageSync("isDevelopment",res.data.baseInfo.isDevelopment.value)
|
|||
} |
|||
}, |
|||
fail: (error) => { |
|||
|
|||
} |
|||
}) |
|||
|
|||
return { |
|||
startApp |
|||
}; |
|||
} |
@ -0,0 +1,41 @@ |
|||
import { createSSRApp } from 'vue' |
|||
import * as Pinia from 'pinia' |
|||
// @ts-ignore
|
|||
import uView from 'vk-uview-ui' |
|||
import App from './App.vue' |
|||
|
|||
|
|||
|
|||
import tab from './plugins/tab' |
|||
import modal from './plugins/modal' |
|||
import time from './plugins/time' |
|||
|
|||
|
|||
// unocss
|
|||
import 'uno.css' |
|||
|
|||
import { accessTimeInAnHour, getNowFormatDate } from "./utils/dateTime"; |
|||
export function createApp() { |
|||
const app = createSSRApp(App) |
|||
app.use(Pinia.createPinia()) |
|||
app.use(uView) |
|||
// 解决onLaunch和onLoad异步问题
|
|||
app.config.globalProperties.$onLaunched = new Promise(resolve => { |
|||
app.config.globalProperties.$isResolve = resolve |
|||
}) |
|||
|
|||
// 页签操作
|
|||
app.config.globalProperties.$tab = tab |
|||
// 模态框对象
|
|||
app.config.globalProperties.$modal = modal |
|||
// 时间对象
|
|||
app.config.globalProperties.$time = time |
|||
|
|||
|
|||
|
|||
return { |
|||
app, |
|||
// uni-app 官方文档示例 https://zh.uniapp.dcloud.io/tutorial/vue3-pinia.html#%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86-pinia
|
|||
Pinia // 此处必须将 Pinia 返回
|
|||
} |
|||
} |
@ -0,0 +1,60 @@ |
|||
import store from '@/store' |
|||
|
|||
function authPermission(permission) { |
|||
const all_permission = "*:*:*" |
|||
const permissions = store.getters && store.getters.permissions |
|||
if (permission && permission.length > 0) { |
|||
return permissions.some(v => { |
|||
return all_permission === v || v === permission |
|||
}) |
|||
} else { |
|||
return false |
|||
} |
|||
} |
|||
|
|||
function authRole(role) { |
|||
const super_admin = "admin" |
|||
const roles = store.getters && store.getters.roles |
|||
if (role && role.length > 0) { |
|||
return roles.some(v => { |
|||
return super_admin === v || v === role |
|||
}) |
|||
} else { |
|||
return false |
|||
} |
|||
} |
|||
|
|||
export default { |
|||
// 验证用户是否具备某权限
|
|||
hasPermi(permission) { |
|||
return authPermission(permission) |
|||
}, |
|||
// 验证用户是否含有指定权限,只需包含其中一个
|
|||
hasPermiOr(permissions) { |
|||
return permissions.some(item => { |
|||
return authPermission(item) |
|||
}) |
|||
}, |
|||
// 验证用户是否含有指定权限,必须全部拥有
|
|||
hasPermiAnd(permissions) { |
|||
return permissions.every(item => { |
|||
return authPermission(item) |
|||
}) |
|||
}, |
|||
// 验证用户是否具备某角色
|
|||
hasRole(role) { |
|||
return authRole(role) |
|||
}, |
|||
// 验证用户是否含有指定角色,只需包含其中一个
|
|||
hasRoleOr(roles) { |
|||
return roles.some(item => { |
|||
return authRole(item) |
|||
}) |
|||
}, |
|||
// 验证用户是否含有指定角色,必须全部拥有
|
|||
hasRoleAnd(roles) { |
|||
return roles.every(item => { |
|||
return authRole(item) |
|||
}) |
|||
} |
|||
} |
@ -0,0 +1,17 @@ |
|||
import tab from './tab' |
|||
// import auth from './auth'
|
|||
import modal from './modal' |
|||
import time from './time' |
|||
|
|||
export default { |
|||
install(app) { |
|||
// 页签操作
|
|||
app.config.globalProperties.$tab = tab |
|||
// 认证对象
|
|||
// Vue.prototype.$auth = auth
|
|||
// 模态框对象
|
|||
app.config.globalProperties.$modal = modal |
|||
// 时间对象
|
|||
app.config.globalProperties.$time = time |
|||
} |
|||
} |
@ -0,0 +1,73 @@ |
|||
export default { |
|||
// 消息提示
|
|||
msg(content) { |
|||
uni.showToast({ |
|||
title: content, |
|||
icon: 'none' |
|||
}) |
|||
}, |
|||
// 错误消息
|
|||
msgError(content) { |
|||
uni.showToast({ |
|||
title: content, |
|||
icon: 'error' |
|||
}) |
|||
}, |
|||
// 成功消息
|
|||
msgSuccess(content) { |
|||
uni.showToast({ |
|||
title: content, |
|||
icon: 'success' |
|||
}) |
|||
}, |
|||
// 隐藏消息
|
|||
hideMsg(content) { |
|||
uni.hideToast() |
|||
}, |
|||
// 弹出提示
|
|||
alert(content) { |
|||
uni.showModal({ |
|||
title: '提示', |
|||
content: content, |
|||
showCancel: false |
|||
}) |
|||
}, |
|||
// 确认窗体
|
|||
confirm(content,confirmText,cancelText) { |
|||
return new Promise((resolve, reject) => { |
|||
uni.showModal({ |
|||
title: '系统提示', |
|||
content: content, |
|||
cancelText: cancelText||'取消', |
|||
confirmText: confirmText || '确定', |
|||
success: function(res) { |
|||
if (res.confirm) { |
|||
resolve(res.confirm) |
|||
} |
|||
} |
|||
}) |
|||
}) |
|||
}, |
|||
// 提示信息
|
|||
showToast(option) { |
|||
if (typeof option === "object") { |
|||
uni.showToast(option) |
|||
} else { |
|||
uni.showToast({ |
|||
title: option, |
|||
icon: "none", |
|||
duration: 2500 |
|||
}) |
|||
} |
|||
}, |
|||
// 打开遮罩层
|
|||
loading(content) { |
|||
uni.showLoading({ |
|||
title: content, |
|||
}) |
|||
}, |
|||
// 关闭遮罩层
|
|||
closeLoading() { |
|||
uni.hideLoading() |
|||
} |
|||
} |
@ -0,0 +1,32 @@ |
|||
export default { |
|||
// 关闭所有页面,打开到应用内的某个页面
|
|||
reLaunch(url) { |
|||
return uni.reLaunch({ |
|||
url: url |
|||
}) |
|||
}, |
|||
// 跳转到tabBar页面,并关闭其他所有非tabBar页面
|
|||
switchTab(url) { |
|||
return uni.switchTab({ |
|||
url: url |
|||
}) |
|||
}, |
|||
// 关闭当前页面,跳转到应用内的某个页面
|
|||
redirectTo(url) { |
|||
return uni.redirectTo({ |
|||
url: url |
|||
}) |
|||
}, |
|||
// 保留当前页面,跳转到应用内的某个页面
|
|||
navigateTo(url) { |
|||
return uni.navigateTo({ |
|||
url: url |
|||
}) |
|||
}, |
|||
// 关闭当前页面,返回上一页面或多级页面
|
|||
navigateBack(level) { |
|||
return uni.navigateBack({ |
|||
delta:level |
|||
}) |
|||
} |
|||
} |
@ -0,0 +1,19 @@ |
|||
export default { |
|||
formatDate(timestamp){ |
|||
// 获取当前时间戳(单位:毫秒)
|
|||
// var timestamp = Date.now(); // 或者传入特定的时间戳值
|
|||
timestamp = timestamp ? timestamp :Date.now() |
|||
// 创建Date对象并设置时间戳
|
|||
var dateObj = new Date(timestamp); |
|||
|
|||
// 提取年份、月份、日期等信息
|
|||
var year = dateObj.getFullYear(); |
|||
var month = (dateObj.getMonth() + 1).toString().padStart(2, '0'); // 注意月份从0开始计数,所以需要加1
|
|||
var day = dateObj.getDate().toString().padStart(2, '0'); |
|||
var hour = dateObj.getHours().toString().padStart(2, '0'); |
|||
var minutes = dateObj.getMinutes().toString().padStart(2, '0'); |
|||
var seconds = dateObj.getSeconds().toString().padStart(2, '0'); |
|||
|
|||
return `${year}-${month}-${day} ${hour}:${minutes}:${seconds}` |
|||
} |
|||
} |
@ -1,117 +0,0 @@ |
|||
//只要是未登录状态,想要跳转到名单内的路径时,直接跳到登录页。
|
|||
// 页面白名单,不受拦截
|
|||
import versionTool from '@/libs/versionUpdate.js'; |
|||
|
|||
const whiteList = [ |
|||
'/pages/login/index' |
|||
] |
|||
let apages = getCurrentPages() |
|||
console.log("getCurrentPages",apages) |
|||
function hasPermission (url) { |
|||
console.log('url',url); |
|||
|
|||
var isLogin = uni.getStorageSync("hasLogin") |
|||
// let islogin = this.$store.state.hasLogin
|
|||
islogin = Boolean(Number(islogin));//返回布尔值
|
|||
// 在白名单中或有登录判断条件可以直接跳转
|
|||
if(whiteList.indexOf(url) !== -1 || islogin) { |
|||
return true |
|||
} |
|||
return true |
|||
} |
|||
|
|||
uni.addInterceptor('navigateTo', { |
|||
|
|||
// 页面跳转前进行拦截, invoke根据返回值进行判断是否继续执行跳转
|
|||
invoke (e) { |
|||
if(!hasPermission(e.url)){ |
|||
uni.reLaunch({ |
|||
url: '/pages/login/index' |
|||
}) |
|||
return false |
|||
} |
|||
return true |
|||
}, |
|||
success (e) { |
|||
versionTool.isNewVersion() |
|||
} |
|||
}) |
|||
|
|||
uni.addInterceptor('switchTab', { |
|||
// tabbar页面跳转前进行拦截
|
|||
invoke (e) { |
|||
if(!hasPermission(e.url)){ |
|||
uni.reLaunch({ |
|||
url: '/pages/login/index' |
|||
}) |
|||
return false |
|||
} |
|||
return true |
|||
}, |
|||
success (e) { |
|||
} |
|||
}) |
|||
|
|||
// import modules from './modules'
|
|||
// import Vue from 'vue'
|
|||
// //这里仅示范npm安装方式的引入,其它方式引入请看最上面【安装】部分
|
|||
// import Router from 'uni-simple-router'
|
|||
|
|||
// Vue.use(Router)
|
|||
// //初始化
|
|||
// const router = new Router({
|
|||
// routes: [...modules]//路由表
|
|||
// });
|
|||
|
|||
// //全局路由前置守卫
|
|||
// router.beforeEach((to, from, next) => {
|
|||
// next()
|
|||
// })
|
|||
// // 全局路由后置守卫
|
|||
// router.afterEach((to, from) => {
|
|||
// })
|
|||
// export default router;
|
|||
|
|||
// import Vue from 'vue'
|
|||
// import store from '../store/index.js'
|
|||
// import pages from '../pages.js'
|
|||
|
|||
// import Router, {
|
|||
// RouterMount
|
|||
// } from 'uni-simple-router'
|
|||
|
|||
|
|||
|
|||
// Vue.use(Router)
|
|||
|
|||
// const myRouter =
|
|||
// pages().pages.map(item => ({
|
|||
// path: `/${item.path}`,
|
|||
// meta: item.meta || {}
|
|||
// }))
|
|||
// //初始化
|
|||
// const router = new Router({
|
|||
// routes: myRouter
|
|||
// });
|
|||
|
|||
// //全局路由前置守卫
|
|||
// router.beforeEach((to, from, next) => {
|
|||
|
|||
// const isLogin = sessionStorage.getItem("isLogin")
|
|||
// console.log('路由前置守卫',isLogin)
|
|||
// // if (!isLogin && to.meta.needLogin) {
|
|||
// if (!isLogin ) {
|
|||
// next({
|
|||
// path: '/pages/login/index',
|
|||
// query: {
|
|||
// redirect: to.path
|
|||
// }
|
|||
// })
|
|||
// } else {
|
|||
// next()
|
|||
// }
|
|||
|
|||
// })
|
|||
// // 全局路由后置守卫
|
|||
// router.afterEach((to, from) => {console.log('路由后置守卫')})
|
|||
// export default router;
|
@ -1,29 +0,0 @@ |
|||
// router/modules/home.js
|
|||
const home = [ |
|||
{ |
|||
//注意:path必须跟pages.json中的地址对应,最前面别忘了加'/'哦
|
|||
path: '/pages/index/index', |
|||
aliasPath:'/', //对于h5端你必须在首页加上aliasPath并设置为/
|
|||
name: 'index', |
|||
meta: { |
|||
title: 'WMS仓库管理系统', |
|||
}, |
|||
}, |
|||
// {
|
|||
// path: '/pages/list/index',
|
|||
// aliasPath:'/'
|
|||
// name: 'list',
|
|||
// meta: {
|
|||
// title: '列表',
|
|||
// },
|
|||
// },
|
|||
{ |
|||
path: '/pages/login/index', |
|||
aliasPath:'/' |
|||
name: 'login', |
|||
meta: { |
|||
title: '登录', |
|||
}, |
|||
}, |
|||
] |
|||
export default home |
@ -1,11 +0,0 @@ |
|||
// router/modules/index.js
|
|||
const files = require.context('.', false, /\.js$/) |
|||
const modules = [] |
|||
|
|||
files.keys().forEach(key => { |
|||
if (key === './index.js') return |
|||
const item = files(key).default |
|||
modules.push(...item) |
|||
}) |
|||
|
|||
export default modules |
@ -1,46 +0,0 @@ |
|||
//只要是未登录状态,想要跳转到名单内的路径时,直接跳到登录页
|
|||
// 页面白名单,不受拦截
|
|||
const whiteList = [ |
|||
'/pages/login/index', |
|||
'/pages/config/config' |
|||
] |
|||
|
|||
function hasPermission(url) { |
|||
var isLogin = uni.getStorageSync("hasLogin") |
|||
if (isLogin == null) { |
|||
isLogin = false |
|||
} |
|||
|
|||
// 在白名单中或有登录判断条件可以直接跳转
|
|||
if (whiteList.indexOf(url) !== -1 || isLogin) { |
|||
return true |
|||
} |
|||
return false |
|||
} |
|||
uni.addInterceptor('navigateTo', { |
|||
// 页面跳转前进行拦截, invoke根据返回值进行判断是否继续执行跳转
|
|||
invoke(e) { |
|||
if (!hasPermission(e.url)) { |
|||
uni.reLaunch({ |
|||
url: '/pages/login/index' |
|||
}) |
|||
return false |
|||
} |
|||
return true |
|||
}, |
|||
success(e) {} |
|||
}) |
|||
|
|||
uni.addInterceptor('switchTab', { |
|||
// tabbar页面跳转前进行拦截
|
|||
invoke(e) { |
|||
if (!hasPermission(e.url)) { |
|||
uni.reLaunch({ |
|||
url: '/pages/login/index' |
|||
}) |
|||
return false |
|||
} |
|||
return true |
|||
}, |
|||
success(e) {} |
|||
}) |
@ -1,20 +0,0 @@ |
|||
// router.js
|
|||
import {RouterMount,createRouter} from 'uni-simple-router'; |
|||
|
|||
const router = createRouter({ |
|||
platform: process.env.VUE_APP_PLATFORM, |
|||
routes: [...ROUTES] |
|||
}); |
|||
//全局路由前置守卫
|
|||
router.beforeEach((to, from, next) => { |
|||
next(); |
|||
}); |
|||
// 全局路由后置守卫
|
|||
router.afterEach((to, from) => { |
|||
console.log('跳转结束') |
|||
}) |
|||
|
|||
export { |
|||
router, |
|||
RouterMount |
|||
} |
@ -1,6 +0,0 @@ |
|||
export {}; |
|||
|
|||
declare module "vue" { |
|||
type Hooks = App.AppInstance & Page.PageInstance; |
|||
interface ComponentCustomOptions extends Hooks {} |
|||
} |
@ -1,10 +0,0 @@ |
|||
const getters = { |
|||
id:id=>state.user.id, |
|||
token: state => state.user.token, |
|||
avatar: state => state.user.avatar, |
|||
name: state => state.user.name, |
|||
roles: state => state.user.roles, |
|||
permissions: state => state.user.permissions, |
|||
hasLogin:state=>state.user.hasLogin |
|||
} |
|||
export default getters |
@ -1,10 +0,0 @@ |
|||
import user from '@/store/modules/user' |
|||
import getters from './getters' |
|||
import { createStore } from "vuex"; |
|||
const store = createStore({ |
|||
modules: { |
|||
user |
|||
}, |
|||
getters |
|||
}); |
|||
export default store; |
@ -0,0 +1 @@ |
|||
export { default as useCountStore } from './modules/countStore' |
@ -0,0 +1,121 @@ |
|||
import { defineStore } from 'pinia' |
|||
import { |
|||
login, |
|||
logout, |
|||
getInfo, |
|||
getPermissionInfo |
|||
} from '@/api/login' |
|||
import { |
|||
setToken, |
|||
removeToken |
|||
} from '@/utils/auth' |
|||
const baseUrl = import.meta.env.VITE_BASE_URL |
|||
const useStore = defineStore('storeId', { |
|||
state: () => ({ |
|||
id: '', // 用户编号
|
|||
name: '', |
|||
avatar: '', |
|||
roles: [], |
|||
permissions: '', |
|||
role: '', |
|||
post: '', |
|||
dept: '', |
|||
menus1: [], |
|||
menus2: [], |
|||
}), |
|||
getters: { |
|||
// isEven: (state) => state.count % 2 === 0
|
|||
}, |
|||
actions: { |
|||
// 登录
|
|||
Login(userInfo) { |
|||
const username = userInfo.username.trim() |
|||
const password = userInfo.password |
|||
const captchaVerification = userInfo.captchaVerification |
|||
const tenantName = userInfo.tenantName |
|||
const rememberMe = userInfo.rememberMe |
|||
const code = userInfo.code |
|||
const uuid = userInfo.uuid |
|||
return new Promise((resolve, reject) => { |
|||
login(username, password, captchaVerification, tenantName, rememberMe, code, uuid).then( |
|||
res => { |
|||
res = res.data; |
|||
// 设置 token
|
|||
setToken(res) |
|||
resolve(res) |
|||
}).catch(error => { |
|||
reject(error) |
|||
}) |
|||
}) |
|||
}, |
|||
// 获取权限
|
|||
GetPermissionInfo() { |
|||
return new Promise((resolve, reject) => { |
|||
getPermissionInfo().then(res => { |
|||
res = res.data; // 读取 data 数据
|
|||
if (res.roles && res.roles.length > 0) { |
|||
this.roles = res.roles |
|||
this.role = res.roles.filter(item => item == 'all_approve' || item == 'normal_approve')[0] |
|||
this.permissions = res.permissions |
|||
let menus = [] |
|||
res.menus.forEach(item => { |
|||
if (item.path == '/pda') { |
|||
menus = item.children |
|||
} |
|||
}) |
|||
this.menus1 = menus.filter(item => item.path !== 'itemOut') |
|||
this.menus2 = menus.filter(item => item.path === 'itemOut') |
|||
} else { |
|||
this.roles = [] |
|||
this.role = '' |
|||
} |
|||
resolve(res) |
|||
}).catch(error => { |
|||
reject(error) |
|||
}) |
|||
}) |
|||
}, |
|||
// 获取权限
|
|||
GetInfo() { |
|||
return new Promise((resolve, reject) => { |
|||
getInfo().then(res => { |
|||
res = res.data; // 读取 data 数据
|
|||
this.avatar = res.avatar |
|||
this.name = res.nickname |
|||
this.id = res.id |
|||
this.avatar = res.avatar |
|||
this.dept = res.dept |
|||
if (res.posts && res.posts.length > 0) { |
|||
this.post = res.posts.filter(item => item.code == 'worker' || item.code == 'engineer')[0] |
|||
} else { |
|||
this.post = '' |
|||
} |
|||
resolve(res) |
|||
}).catch(error => { |
|||
reject(error) |
|||
}) |
|||
}) |
|||
}, |
|||
// 获取权限
|
|||
LogOut() { |
|||
return new Promise((resolve, reject) => { |
|||
logout().then(res => { |
|||
this.id = ''// 用户编号
|
|||
this.name = '' |
|||
this.avatar = '' |
|||
this.roles = '' |
|||
this.permissions = '' |
|||
this.role = '' |
|||
this.post = '' |
|||
this.dept = '' |
|||
removeToken() |
|||
resolve(res) |
|||
}).catch(error => { |
|||
reject(error) |
|||
}) |
|||
}) |
|||
}, |
|||
} |
|||
}) |
|||
|
|||
export default useStore |
@ -1,130 +0,0 @@ |
|||
import storage from '@/common/utils/storage.js' |
|||
import { |
|||
login, |
|||
logout, |
|||
getPermissionInfo, |
|||
getTenantInfo |
|||
} from '@/api/request2' |
|||
// import picUrl from "../../static/images/profile.jpg";
|
|||
|
|||
|
|||
const user = { |
|||
state: { |
|||
id: storage.getStorage(storage.constant.id), // 用户编号
|
|||
name: storage.getStorage(storage.constant.name), |
|||
avatar: storage.getStorage(storage.constant.avatar), |
|||
roles: storage.getStorage(storage.constant.roles), |
|||
permissions: storage.getStorage(storage.constant.permissions) |
|||
}, |
|||
|
|||
mutations: { |
|||
SET_ID: (state, id) => { |
|||
state.id = id |
|||
storage.setStorage(storage.constant.id, id) |
|||
}, |
|||
SET_NAME: (state, name) => { |
|||
state.name = name |
|||
storage.setStorage(storage.constant.name, name) |
|||
}, |
|||
SET_AVATAR: (state, avatar) => { |
|||
state.avatar = avatar |
|||
storage.setStorage(storage.constant.avatar, avatar) |
|||
}, |
|||
SET_ROLES: (state, roles) => { |
|||
state.roles = roles |
|||
storage.setStorage(storage.constant.roles, roles) |
|||
}, |
|||
SET_PERMISSIONS: (state, permissions) => { |
|||
state.permissions = permissions |
|||
storage.setStorage(storage.constant.permissions, permissions) |
|||
}, |
|||
|
|||
}, |
|||
|
|||
actions: { |
|||
// 登录
|
|||
Login({ |
|||
commit |
|||
}, userInfo) { |
|||
const username = userInfo.username |
|||
const password = userInfo.password |
|||
const code = userInfo.code |
|||
const uuid = userInfo.uuid |
|||
|
|||
return new Promise((resolve, reject) => { |
|||
login(username, password, code, uuid).then(res => { |
|||
if(res.data){ |
|||
res = res.data; |
|||
// 设置 token
|
|||
storage.setStorage(storage.constant.token,res.accessToken) |
|||
resolve(res) |
|||
}else { |
|||
uni.showToast({ |
|||
title:res.msg |
|||
}) |
|||
} |
|||
|
|||
}).catch(error => { |
|||
reject(error) |
|||
uni.showToast({ |
|||
title:error |
|||
}) |
|||
}) |
|||
}) |
|||
}, |
|||
|
|||
// 获取用户信息
|
|||
getPermissionInfo({ |
|||
commit, |
|||
state |
|||
}) { |
|||
return new Promise((resolve, reject) => { |
|||
getPermissionInfo().then(res => { |
|||
res = res.data; // 读取 data 数据
|
|||
const user = res.user |
|||
const avatar="" |
|||
// const avatar = (user == null || user.avatar == "" || user.avatar == null||user.avatar == undefined) ?
|
|||
// picUrl: user.avatar
|
|||
const nickname = (user == null || user.nickname === "" || user.nickname == |
|||
null) ? "" : user.nickname |
|||
if (res.roles && res.roles.length > 0) { |
|||
commit('SET_ROLES', res.roles) |
|||
commit('SET_PERMISSIONS', res.permissions) |
|||
} else { |
|||
commit('SET_ROLES', ['ROLE_DEFAULT']) |
|||
} |
|||
commit('SET_NAME', nickname) |
|||
commit('SET_AVATAR', avatar) |
|||
commit('SET_ID',user.id) |
|||
resolve(res) |
|||
}).catch(error => { |
|||
reject(error) |
|||
// uni.showToast({
|
|||
// title:"用户信息获取失败"
|
|||
// })
|
|||
}) |
|||
}) |
|||
}, |
|||
|
|||
// 退出系统
|
|||
LogOut({ |
|||
commit, |
|||
state |
|||
}) { |
|||
return new Promise((resolve, reject) => { |
|||
logout(state.token).then(() => { |
|||
commit('SET_ROLES', []) |
|||
commit('SET_PERMISSIONS', []) |
|||
commit('SET_ID',[]) |
|||
storage.removeStorage(storage.constant.token) |
|||
storage.clearStorage() |
|||
resolve() |
|||
}).catch(error => { |
|||
reject(error) |
|||
}) |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
|
|||
export default user |
@ -0,0 +1,2 @@ |
|||
@title-size: 40rpx; |
|||
@title-color: #47caff; |
@ -0,0 +1,2 @@ |
|||
$title-size: 40rpx; |
|||
$title-color: #bd34fe; |
@ -0,0 +1,22 @@ |
|||
const AccessTokenKey = 'ACCESS_TOKEN' |
|||
const RefreshTokenKey = 'REFRESH_TOKEN' |
|||
|
|||
// ========== Token 相关 ==========
|
|||
|
|||
export function getAccessToken() { |
|||
return uni.getStorageSync(AccessTokenKey) |
|||
} |
|||
|
|||
export function getRefreshToken() { |
|||
return uni.getStorageSync(RefreshTokenKey) |
|||
} |
|||
|
|||
export function setToken(token) { |
|||
uni.setStorageSync(AccessTokenKey, token.accessToken) |
|||
uni.setStorageSync(RefreshTokenKey, token.refreshToken) |
|||
} |
|||
|
|||
export function removeToken() { |
|||
uni.removeStorageSync(AccessTokenKey) |
|||
uni.removeStorageSync(RefreshTokenKey) |
|||
} |
@ -0,0 +1,138 @@ |
|||
|
|||
|
|||
const _dTo = function(url) { |
|||
if (!_getSync('isLogin')) { |
|||
_gTo('/pages/login/index') |
|||
return; |
|||
} |
|||
uni.navigateTo({ |
|||
url: url |
|||
}); |
|||
} |
|||
const _gTo = function(url) { |
|||
uni.navigateTo({ |
|||
url: url |
|||
}); |
|||
} |
|||
const _getSync = (i) => { |
|||
return uni.getStorageSync(i); |
|||
} |
|||
const _removeSync = (i) => { |
|||
return uni.removeStorageSync(i); |
|||
} |
|||
const _setSync = (i, data) => { |
|||
return uni.setStorageSync(i, data); |
|||
} |
|||
const _alert = (txt, cb) => { |
|||
uni.showModal({ |
|||
title: '温馨提示', |
|||
content: txt, |
|||
showCancel: false, |
|||
confirmColor: '#2979ff', |
|||
success: function() { |
|||
cb && cb(); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
const _confirm = function(txt, cb) { |
|||
uni.showModal({ |
|||
title: '温馨提示', |
|||
content: txt, |
|||
showCancel: true, |
|||
confirmColor: '#2979ff', |
|||
success: function(res) { |
|||
if (res.confirm) { |
|||
cb && cb(); |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
|
|||
const _toast = function(txt) { |
|||
uni.showToast({ |
|||
title: txt, |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}); |
|||
} |
|||
|
|||
|
|||
const _backT = function() { |
|||
uni.navigateBack(); |
|||
} |
|||
const _call = function(tel) { |
|||
uni.makePhoneCall({ |
|||
phoneNumber: tel |
|||
}); |
|||
} |
|||
|
|||
const _showLoading = (msg = '') => uni.showLoading({ |
|||
mask: true, |
|||
title: msg |
|||
}); |
|||
|
|||
/** |
|||
* 关闭loading |
|||
*/ |
|||
const _closeLoading = () => uni.hideLoading(); |
|||
|
|||
// 获取截图宽高
|
|||
const _screenshot = function(fromWhere, widthProp, proportion) { |
|||
var width = 0, |
|||
height = 0; |
|||
uni.getSystemInfo({ |
|||
//整个手机屏幕的高
|
|||
success: function(res) { |
|||
width = parseInt(res.screenWidth * widthProp) //宽等于屏幕款*百分比
|
|||
height = width * proportion |
|||
} |
|||
}); |
|||
_gTo('../u-avatar-cropper/u-avatar-cropper?destWidth=' + (width * 2) + '&destHeight=' + (height * 2) + |
|||
'&rectWidth=' + width + '&rectHeight=' + height + '&fileType=jpg' + '&fromWhere=' + |
|||
fromWhere) |
|||
} |
|||
// 复制
|
|||
const _copy = (data) => { |
|||
uni.setClipboardData({ |
|||
data: data, |
|||
success: function() { |
|||
} |
|||
}); |
|||
} |
|||
const _upLoad = function(tempFilePaths) { |
|||
return new Promise((resolve, reject) => { |
|||
uni.uploadFile({ |
|||
url: import.meta.env.VITE_BASE_URL + '/common/upload', //仅为示例,非真实的接口地址
|
|||
filePath: tempFilePaths, |
|||
name: 'file', |
|||
formData: { |
|||
'user': 'test' |
|||
}, |
|||
header: { "Content-Type": "multipart/form-data", 'openId': uni.getStorageSync('openId') }, |
|||
success: (uploadFileRes) => { |
|||
let item = JSON.parse(uploadFileRes.data.replace(/\ufeff/g, "")); |
|||
resolve(item) |
|||
}, |
|||
fail(err) { |
|||
} |
|||
}); |
|||
}) |
|||
} |
|||
export { |
|||
_dTo, |
|||
_gTo, |
|||
_toast, |
|||
_backT, |
|||
_call, |
|||
_confirm, |
|||
_alert, |
|||
_getSync, |
|||
_setSync, |
|||
_removeSync, |
|||
_showLoading, |
|||
_closeLoading, |
|||
_screenshot, |
|||
_copy, |
|||
_upLoad |
|||
}; |
@ -0,0 +1,50 @@ |
|||
const zeroPadd = function(date,seperator) { |
|||
var hours = date.getHours(); // 获取时
|
|||
var minutes = date.getMinutes(); // 获取分
|
|||
var second = date.getSeconds(); // 获取秒
|
|||
var seperator1 = seperator?seperator:"-"; // 自定义日期分隔符
|
|||
var year = date.getFullYear(); // 获取年
|
|||
var month = date.getMonth() + 1; // 获取月
|
|||
var strDate = date.getDate(); // 获取日
|
|||
|
|||
if (month >= 1 && month <= 9) { |
|||
month = "0" + month; |
|||
} |
|||
if (strDate >= 0 && strDate <= 9) { |
|||
strDate = "0" + strDate; |
|||
} |
|||
if (hours >= 0 && hours <= 9) { |
|||
hours = "0" + hours; |
|||
} |
|||
if (minutes >= 0 && minutes <= 9) { |
|||
minutes = "0" + minutes; |
|||
} |
|||
if (second >= 0 && second <= 9) { |
|||
second = "0" + second; |
|||
} |
|||
var time = hours + ":" + minutes + ":" + second; // 时分秒
|
|||
var currentdate = year + seperator1 + month + seperator1 + strDate; // 年月日
|
|||
var date = { |
|||
time, currentdate |
|||
} |
|||
return date; |
|||
} |
|||
|
|||
// 获取当前日期 时间
|
|||
const getNowFormatDate = function(date,seperator) { |
|||
return zeroPadd(date,seperator); |
|||
} |
|||
|
|||
//获取一小时后的日期 时间
|
|||
const accessTimeInAnHour = function(date, h,seperator) { |
|||
var date1 = date.getTime(); // 获取当前时间戳
|
|||
// 当前时间戳+3600s(一小时,其他时间通过计算时间戳进行相应加减),重新设置 Date 对象
|
|||
date.setTime(date1 + h * 3600000); |
|||
return zeroPadd(date,seperator); |
|||
} |
|||
|
|||
|
|||
export { |
|||
getNowFormatDate, |
|||
accessTimeInAnHour, |
|||
}; |
@ -0,0 +1,19 @@ |
|||
// @ts-ignore
|
|||
import buildURL from 'axios/lib/helpers/buildURL' |
|||
import type { AxiosRequestConfig } from 'axios' |
|||
|
|||
type ParamsSerializer = AxiosRequestConfig['paramsSerializer'] |
|||
|
|||
export function getFullURL( |
|||
baseURL: string, |
|||
url: string, |
|||
params: Record<string, any>, |
|||
paramsSerializer?: ParamsSerializer |
|||
) { |
|||
if (url.startsWith('http')) { |
|||
return buildURL(url, params, paramsSerializer) |
|||
} |
|||
baseURL = baseURL.endsWith('/') ? baseURL : `${baseURL}/` |
|||
url = url.startsWith('/') ? url.slice(1) : url |
|||
return buildURL(`${baseURL}${url}`, params, paramsSerializer) |
|||
} |
@ -0,0 +1,31 @@ |
|||
|
|||
|
|||
function compareVersion(v1, v2) { |
|||
v1 = v1.split('.') |
|||
v2 = v2.split('.') |
|||
const len = Math.max(v1.length, v2.length) |
|||
|
|||
while (v1.length < len) { |
|||
v1.push('0') |
|||
} |
|||
while (v2.length < len) { |
|||
v2.push('0') |
|||
} |
|||
|
|||
for (let i = 0; i < len; i++) { |
|||
const num1 = parseInt(v1[i]) |
|||
const num2 = parseInt(v2[i]) |
|||
|
|||
if (num1 > num2) { |
|||
return 1 |
|||
} else if (num1 < num2) { |
|||
return -1 |
|||
} |
|||
} |
|||
|
|||
return 0 |
|||
} |
|||
|
|||
export default { |
|||
compareVersion |
|||
} |
@ -0,0 +1,783 @@ |
|||
//校验学校编码 只能为数字
|
|||
export function validateCode(rule, value, callback) { |
|||
if (!value) { |
|||
return callback(new Error('学校编码不能为空')) |
|||
} else { |
|||
const codeReg = /^[0-9]+$/ |
|||
const codeMax = /^\d{0,5}$/ |
|||
if (codeReg.test(value)) { |
|||
if (codeMax.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('学校编码不能大于5位')) |
|||
} |
|||
|
|||
} else { |
|||
callback(new Error('请输入正确的学校编码,只能是数字')) |
|||
} |
|||
} |
|||
} |
|||
|
|||
//校验邮箱
|
|||
export function validateEmail(rule, value, callback) { |
|||
if (value) { |
|||
const mailReg = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/ |
|||
if (mailReg.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('请输入正确的邮箱格式')) |
|||
} |
|||
} else { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
//校验英文
|
|||
export function validateEng(rule, value, callback) { |
|||
if (value) { |
|||
const mailReg = /^[A-Za-z\-\&\(\)\Ⅰ\Ⅱ\Ⅲ\Ⅳ\Ⅴ\Ⅵ\Ⅶ\Ⅷ\Ⅸ\Ⅹ\s]+$/; |
|||
if (mailReg.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('请输入正确的英文名字')) |
|||
} |
|||
} else { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
//校验姓名拼音
|
|||
export function validateEngName(rule, value, callback) { |
|||
if (value) { |
|||
const EngNameReg = /^[A-Za-z \(\)\s]+$/ |
|||
if (EngNameReg.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('请输入正确的姓名拼音')) |
|||
} |
|||
} else { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
//校验手机号码
|
|||
export function validateHanset(rule, value, callback) { |
|||
if (value) { |
|||
// const regs =/^[1][3,4,5,6,7,8,9][0-9]{9}$/;
|
|||
// const regs = /^1[3|4|5|7|8][0-9]\d{8}$/
|
|||
const regs = /^1[3-9]\d{9}$/ |
|||
if (regs.test(value)) { |
|||
callback() |
|||
} else { |
|||
return callback(new Error('请输入正确的手机号')) |
|||
} |
|||
} else { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
//校验座机电话
|
|||
export function validatePhone(rule, value, callback) { |
|||
if (value) { |
|||
//const reg = /^1[3|4|5|7|8][0-9]\d{8}$/
|
|||
// const regs = /^([0-9]{3,4}-)?[0-9]{7,8}$/;
|
|||
const regs = /^((0\d{2,3}-\d{7,8}))$/; |
|||
if (regs.test(value)) { |
|||
callback() |
|||
} else { |
|||
return callback(new Error('请输入正确的座机号')) |
|||
} |
|||
} else { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
//校验家庭电话 手机或者座机
|
|||
export function validateFamilyPhone(rule, value, callback) { |
|||
if (value) { |
|||
const isPhone = /^([0-9]{3,4}-)?[0-9]{7,8}$/; |
|||
const isMob = /^((\+?86)|(\+86))?(13[0123456789][0-9]{8}|15[0123456789][0-9]{8}|17[0123456789][0-9]{8}|18[0123456789][0-9]{8}|147[0-9]{8}|1349[0-9]{7})$/; |
|||
if (isPhone.test(value) || isMob.test(value)) { |
|||
callback() |
|||
} else { |
|||
return callback(new Error('请输入正确的手机或者座机电话')) |
|||
} |
|||
} else { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
// 校验只能为中文
|
|||
export function validateChinese(rule, value, callback) { |
|||
if (value) { |
|||
const chineseReg = /^[\u4E00-\u9FA5]+$/ |
|||
if (chineseReg.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('请输入简介,只能为中文')) |
|||
} |
|||
} else { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
// 校验名称既能为中文也可以为英文
|
|||
export function validateName(rule, value, callback) { |
|||
if (value) { |
|||
const chineseReg = /^[\u4E00-\u9FA5]+$/ |
|||
const engLish = /^[A-Za-z]+$/ |
|||
if (chineseReg.test(value) || engLish.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('请输入正确的中文或者英文名称')) |
|||
} |
|||
} else { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
// 校验负责人既能为中文也可以为英文
|
|||
export function validateChargeperson(rule, value, callback) { |
|||
if (value) { |
|||
const chineseReg = /^[\u4E00-\u9FA5]+$/ |
|||
const engLish = /^[A-Za-z]+$/ |
|||
if (chineseReg.test(value) || engLish.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('请输入正确的负责人(中英文都可以)')) |
|||
} |
|||
} else { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
//校验学校名称不能为空
|
|||
export function validateXXMC(rule, value, callback) { |
|||
if (!value) { |
|||
return callback(new Error('案例名称不能为空')) |
|||
} else { |
|||
const chineseReg = /^[\u4E00-\u9FA5]+$/ |
|||
if (chineseReg.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('请输入正确的案例名称,只能是汉字')) |
|||
} |
|||
} |
|||
} |
|||
|
|||
//校验中英文数字和下划线都可以
|
|||
export function validateZYS(rule, value, callback) { |
|||
if (value) { |
|||
//const postReg =/^[\u4e00-\u9fa5_a-zA-Z0-9_]{4,10}+$/
|
|||
const Reg = /^[\u4e00-\u9fa5a-zA-Z0-9]+$/ |
|||
if (Reg.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('请输入正确的名称')) |
|||
} |
|||
} else { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
// 校验邮政编码
|
|||
export function validatePostCode(rule, value, callback) { |
|||
if (value) { |
|||
const postReg = /^[1-9]\d{5}$/ |
|||
if (postReg.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('请输入正确的邮政编码')) |
|||
} |
|||
} else { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
// 数字
|
|||
export function validateNum(rule, value, callback) { |
|||
if (value) { |
|||
const numReg = /^[\d]+$/ |
|||
if (numReg.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('请输入数字')) |
|||
} |
|||
} else { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
//数字和小数点
|
|||
export function validateNumDot(rule, value, callback) { |
|||
if (value) { |
|||
const numReg = /^\d+$|^\d+\.\d+$/g |
|||
if (numReg.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('请输入数字或小数点')) |
|||
} |
|||
} else { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
// 组织机构代码
|
|||
export function validateOrganization(rule, value, callback) { |
|||
if (value) { |
|||
const orgReg = /^[A-Za-z0-9]\w{14}$/g |
|||
if (orgReg.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('请输入组织机构代码')) |
|||
} |
|||
} else { |
|||
callback() |
|||
} |
|||
|
|||
} |
|||
|
|||
// 传真
|
|||
export function validateFax(rule, value, callback) { |
|||
if (value) { |
|||
const faxReg = /^(\d{3,4}-)?\d{7,8}$/ |
|||
if (faxReg.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('请输入正确的传真')) |
|||
} |
|||
} else { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
// 主页地址
|
|||
export function validateHome(rule, value, callback) { |
|||
if (value) { |
|||
const homeReg = /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\*\+,;=.]+$/ |
|||
if (homeReg.test(value)) { |
|||
callback() |
|||
} else { |
|||
return callback(new Error('请输入正确的主页地址')) |
|||
} |
|||
} else { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
// 学分 小数,且保留最多三位小数
|
|||
export function validateXf(rule, value, callback) { |
|||
if (!value) { |
|||
return callback(new Error('学分不能为空')) |
|||
} else { |
|||
const numReg = /^[0-9]+\.[0-9]{0,3}$/ |
|||
if (numReg.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('请输入小数,且小数点后最多三位')) |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 数字格式 小数点后一位
|
|||
export function validateOneNum(rule, value, callback) { |
|||
if (value) { |
|||
const numReg = /^\d+(\.\d+)?$/ |
|||
const numOneReg = /^\d*\.{0,1}\d{0,1}$/ |
|||
if (numReg.test(value)) { |
|||
if (numOneReg.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('小数点后最多1位')) |
|||
} |
|||
} else { |
|||
callback(new Error('请输入数字')) |
|||
} |
|||
} |
|||
callback() |
|||
} |
|||
|
|||
// 数字格式 小数点后两位
|
|||
export function validateTwoNum(rule, value, callback) { |
|||
if (value) { |
|||
const numReg = /^\d+(\.\d+)?$/ |
|||
const numTwoReg = /^\d*\.{0,2}\d{0,2}$/ |
|||
if (numReg.test(value)) { |
|||
if (numTwoReg.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('小数点后最多2位')) |
|||
} |
|||
} else { |
|||
callback(new Error('请输入数字')) |
|||
} |
|||
} |
|||
callback() |
|||
} |
|||
|
|||
// 数字格式 小数点后两位 小数点前保留五位
|
|||
export function validateTwoNumThree(rule, value, callback) { |
|||
if (value) { |
|||
if (Number(value) > 10000) {// 校验value值不能大于10000
|
|||
callback(new Error('数值过大,请重新输入')) |
|||
} const numReg = /^\d+(\.\d+)?$/ |
|||
const numTwoReg = /^\d*\.{0,2}\d{0,2}$/ |
|||
if (numReg.test(value)) { |
|||
if (numTwoReg.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('小数点后最多2位')) |
|||
} |
|||
} else { |
|||
callback(new Error('请输入数字')) |
|||
} |
|||
} |
|||
|
|||
callback() |
|||
} |
|||
|
|||
// 数字格式 小数点后三位
|
|||
export function validateThreeNum(rule, value, callback) { |
|||
if (value) { |
|||
const numReg = /^\d+(\.\d+)?$/ |
|||
const numTwoReg = /^\d*\.{0,3}\d{0,3}$/ |
|||
if (numReg.test(value)) { |
|||
if (numTwoReg.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('小数点后最多3位')) |
|||
} |
|||
} else { |
|||
callback(new Error('请输入数字')) |
|||
} |
|||
} |
|||
callback() |
|||
// if (!value) {
|
|||
// return callback(new Error('字段不能为空'))
|
|||
// } else {
|
|||
// const numReg = /^\d+(\.\d+)?$/
|
|||
// const numTwoReg = /^\d*\.{0,3}\d{0,3}$/
|
|||
// if (numReg.test(value)) {
|
|||
// if (numTwoReg.test(value)) {
|
|||
// callback()
|
|||
// } else {
|
|||
// callback(new Error('小数点后最多3位'))
|
|||
// }
|
|||
// } else {
|
|||
// callback(new Error('请输入数字'))
|
|||
// }
|
|||
// }
|
|||
} |
|||
|
|||
//校验年份必须为4位数字
|
|||
export function validateNF(rule, value, callback) { |
|||
if (value) { |
|||
const NFReg = /^\d{4}$/ |
|||
if (NFReg.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('请输入4位数字')) |
|||
} |
|||
} else { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
//校验年份必须为4位数字
|
|||
export function validateXQ(rule, value, callback) { |
|||
if (value) { |
|||
const NFReg = /^\d{5}$/ |
|||
if (NFReg.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('请输入5位数字')) |
|||
} |
|||
} else { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
//校验分数最大值
|
|||
export function validateMaxNumber(rule, value, callback) { |
|||
if (parseInt(value) <= 200) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('分数不能大于200')) |
|||
} |
|||
|
|||
} |
|||
|
|||
//校验正整数
|
|||
export function validateInteger(rule, value, callback) { |
|||
if (value) { |
|||
const integerReg = /^[+]{0,1}(\d+)$/ |
|||
if (integerReg.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('请输入正确的整数')) |
|||
} |
|||
} else { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
//校验整数
|
|||
export function validateroundNumber(rule, value, callback) { |
|||
if (value) { |
|||
const numReg = /^[1-9]\d*$/ |
|||
if (numReg.test(value)) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('请输入正确的整数')) |
|||
} |
|||
} else { |
|||
callback() |
|||
} |
|||
} |
|||
// 校验车牌号
|
|||
export function validateCarNumber(rule, value, callback) { |
|||
if (value) { |
|||
// 新能源
|
|||
const numReg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([A-HJ-K][A-HJ-NP-Z0-9][0-9]{4}$))/; |
|||
// 燃油车
|
|||
const numReg1 = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/; |
|||
if (value.length == 7) { |
|||
if (numReg1.test(value)) { |
|||
callback() |
|||
}else{ |
|||
callback(new Error('请输入正确的车牌号')) |
|||
} |
|||
} else if (value.length == 8) { |
|||
if (numReg.test(value)) { |
|||
callback() |
|||
}else{ |
|||
callback(new Error('请输入正确的车牌号')) |
|||
} |
|||
} else { |
|||
callback(new Error('请输入正确的车牌号')) |
|||
} |
|||
} else { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
//校验身份证号
|
|||
export function validateCard(rule, value, callback) { |
|||
if (value) { |
|||
let cardBoolean = IdCardValidate(value); |
|||
// const cardReg =/(^\d{18}$)|(^\d{17}(\d|X|x)$)/
|
|||
// if (cardReg.test(value)) {
|
|||
if (cardBoolean) { |
|||
callback() |
|||
} else { |
|||
callback(new Error('请输入正确的身份证号')) |
|||
} |
|||
} else { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
//身份证:身份证校验
|
|||
function IdCardValidate(code) { |
|||
var tip = ""; |
|||
if (code != "") { |
|||
var city = { |
|||
11: "北京", |
|||
12: "天津", |
|||
13: "河北", |
|||
14: "山西", |
|||
15: "内蒙古", |
|||
21: "辽宁", |
|||
22: "吉林", |
|||
23: "黑龙江 ", |
|||
31: "上海", |
|||
32: "江苏", |
|||
33: "浙江", |
|||
34: "安徽", |
|||
35: "福建", |
|||
36: "江西", |
|||
37: "山东", |
|||
41: "河南", |
|||
42: "湖北 ", |
|||
43: "湖南", |
|||
44: "广东", |
|||
45: "广西", |
|||
46: "海南", |
|||
50: "重庆", |
|||
51: "四川", |
|||
52: "贵州", |
|||
53: "云南", |
|||
54: "西藏 ", |
|||
61: "陕西", |
|||
62: "甘肃", |
|||
63: "青海", |
|||
64: "宁夏", |
|||
65: "新疆", |
|||
71: "台湾", |
|||
81: "香港", |
|||
82: "澳门", |
|||
91: "国外 " |
|||
}; |
|||
|
|||
var pass = true; |
|||
|
|||
//是否为空
|
|||
if (code === '') { |
|||
tip = "请输入身份证号,身份证号不能为空"; |
|||
pass = false; |
|||
} |
|||
//校验长度,类型
|
|||
else if (isCardNo(code) === false) { |
|||
tip = "您输入的身份证号码不正确,请重新输入"; |
|||
pass = false; |
|||
} |
|||
//检查省份
|
|||
else if (checkProvince(code, city) === false) { |
|||
tip = "您输入的身份证号码不正确,请重新输入"; |
|||
pass = false; |
|||
} |
|||
//校验生日
|
|||
else if (checkBirthday(code) === false) { |
|||
tip = "您输入的身份证号码生日不正确,请重新输入"; |
|||
pass = false; |
|||
} else { |
|||
//18位身份证需要验证最后一位校验位
|
|||
if (code.length == 18) { |
|||
code = code.split(''); |
|||
//∑(ai×Wi)(mod 11)
|
|||
//加权因子
|
|||
var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]; |
|||
//校验位
|
|||
var parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2]; |
|||
var sum = 0; |
|||
var ai = 0; |
|||
var wi = 0; |
|||
for (var i = 0; i < 17; i++) { |
|||
ai = code[i]; |
|||
wi = factor[i]; |
|||
sum += ai * wi; |
|||
} |
|||
var last = parity[sum % 11]; |
|||
if (parity[sum % 11] != code[17]) { |
|||
tip = "身份证格式错误"; |
|||
pass = false; |
|||
} |
|||
} |
|||
} |
|||
return pass; |
|||
} |
|||
} |
|||
|
|||
//身份证:检查身份证号码是否符合规范,包括长度,类型
|
|||
function isCardNo(card) { |
|||
//身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位是校验位,可能为数字或字符X
|
|||
var reg = /(^\d{15}$)|(^\d{17}(\d|X)$)/; |
|||
if (reg.test(card) === false) { |
|||
return false; |
|||
} |
|||
return true; |
|||
}; |
|||
|
|||
//身份证:取身份证前两位,校验省份
|
|||
function checkProvince(card, city) { |
|||
var province = card.substr(0, 2); |
|||
if (city[province] == undefined) { |
|||
return false; |
|||
} |
|||
return true; |
|||
}; |
|||
|
|||
//身份证:检查生日是否正确
|
|||
function checkBirthday(card) { |
|||
var len = card.length; |
|||
//身份证15位时,次序为省(3位)市(3位)年(2位)月(2位)日(2位)校验位(3位),皆为数字
|
|||
if (len == '15') { |
|||
var re_fifteen = /^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})$/; |
|||
var arr_data = card.match(re_fifteen); |
|||
var year = arr_data[2]; |
|||
var month = arr_data[3]; |
|||
var day = arr_data[4]; |
|||
var birthday = new Date('19' + year + '/' + month + '/' + day); |
|||
return verifyBirthday('19' + year, month, day, birthday); |
|||
} |
|||
//身份证18位时,次序为省(3位)市(3位)年(4位)月(2位)日(2位)校验位(4位),校验位末尾可能为X
|
|||
if (len == '18') { |
|||
var re_eighteen = /^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$/; |
|||
var arr_data = card.match(re_eighteen); |
|||
var year = arr_data[2]; |
|||
var month = arr_data[3]; |
|||
var day = arr_data[4]; |
|||
var birthday = new Date(year + '/' + month + '/' + day); |
|||
return verifyBirthday(year, month, day, birthday); |
|||
} |
|||
return false; |
|||
}; |
|||
|
|||
//身份证:校验日期
|
|||
function verifyBirthday(year, month, day, birthday) { |
|||
var now = new Date(); |
|||
var now_year = now.getFullYear(); |
|||
//年月日是否合理
|
|||
if (birthday.getFullYear() == year && (birthday.getMonth() + 1) == month && birthday.getDate() == day) { |
|||
//判断年份的范围(3岁到100岁之间)
|
|||
var time = now_year - year; |
|||
if (time >= 3 && time <= 100) { |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
return false; |
|||
}; |
|||
|
|||
/** |
|||
* 判断身份证号码为18位时最后的验证位是否正确 |
|||
* @param a_idCard 身份证号码数组 |
|||
* @return |
|||
*/ |
|||
function isTrueValidateCodeBy18IdCard(a_idCard) { |
|||
let By18Val = a_idCard[17].toLowerCase(); // 获取第十八位值
|
|||
const numReg = /^[1-9]\d*$/ |
|||
let numVal = false; // 校验第十八位是否为整数
|
|||
if (numReg.test(Number(By18Val))) { |
|||
numVal = true |
|||
} else { |
|||
numVal = false |
|||
} |
|||
if (By18Val == 'x' || By18Val == 'X' || numVal) { |
|||
return true |
|||
} else { |
|||
return false |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 验证身份证号码前两位,省级编码的准确性 |
|||
* @param AddressNum |
|||
* @constructor |
|||
*/ |
|||
function IdCardValidateAddress(AddressNum) { |
|||
var city = { |
|||
11: "北京", |
|||
12: "天津", |
|||
13: "河北", |
|||
14: "山西", |
|||
15: "内蒙古", |
|||
21: "辽宁", |
|||
22: "吉林", |
|||
23: "黑龙江 ", |
|||
31: "上海", |
|||
32: "江苏", |
|||
33: "浙江", |
|||
34: "安徽", |
|||
35: "福建", |
|||
36: "江西", |
|||
37: "山东", |
|||
41: "河南", |
|||
42: "湖北 ", |
|||
43: "湖南", |
|||
44: "广东", |
|||
45: "广西", |
|||
46: "海南", |
|||
50: "重庆", |
|||
51: "四川", |
|||
52: "贵州", |
|||
53: "云南", |
|||
54: "西藏 ", |
|||
61: "陕西", |
|||
62: "甘肃", |
|||
63: "青海", |
|||
64: "宁夏", |
|||
65: "新疆", |
|||
71: "台湾", |
|||
81: "香港", |
|||
82: "澳门", |
|||
91: "国外 " |
|||
}; |
|||
if (city[AddressNum.substr(0, 2)]) { |
|||
return true |
|||
} else { |
|||
return false |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 验证18位数身份证号码中的生日是否是有效生日 |
|||
* @param idCard 18位书身份证字符串 |
|||
* @return |
|||
*/ |
|||
function isValidityBrithBy18IdCard(idCard18) { |
|||
var year = idCard18.substring(6, 10); |
|||
var month = idCard18.substring(10, 12); |
|||
var day = idCard18.substring(12, 14); |
|||
var temp_date = new Date(year, parseFloat(month) - 1, parseFloat(day)); |
|||
// 这里用getFullYear()获取年份,避免千年虫问题
|
|||
if (temp_date.getFullYear() != parseFloat(year) |
|||
|| temp_date.getMonth() != parseFloat(month) - 1 |
|||
|| temp_date.getDate() != parseFloat(day)) { |
|||
return false; |
|||
} else { |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 验证15位数身份证号码中的生日是否是有效生日 |
|||
* @param idCard15 15位书身份证字符串 |
|||
* @return |
|||
*/ |
|||
function isValidityBrithBy15IdCard(idCard15) { |
|||
var year = idCard15.substring(6, 8); |
|||
var month = idCard15.substring(8, 10); |
|||
var day = idCard15.substring(10, 12); |
|||
var temp_date = new Date(year, parseFloat(month) - 1, parseFloat(day)); |
|||
// 对于老身份证中的你年龄则不需考虑千年虫问题而使用getYear()方法
|
|||
if (temp_date.getYear() != parseFloat(year) |
|||
|| temp_date.getMonth() != parseFloat(month) - 1 |
|||
|| temp_date.getDate() != parseFloat(day)) { |
|||
return false; |
|||
} else { |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 去掉字符串头尾空格 |
|||
* @param str |
|||
* @returns {*} |
|||
*/ |
|||
function trim(str) { |
|||
return str.replace(/(^\s*)|(\s*$)/g, ""); |
|||
} |
|||
|
|||
export default { |
|||
validateCode, |
|||
validateEmail, |
|||
validateEng, |
|||
validatePhone, |
|||
validateChinese, |
|||
validatePostCode, |
|||
validateNum, |
|||
validateNumDot, |
|||
validateZYS, |
|||
validateOrganization, |
|||
validateFax, |
|||
validateHome, |
|||
validateXXMC, |
|||
validateXf, |
|||
validateOneNum, |
|||
validateMaxNumber, |
|||
validateTwoNum, |
|||
validateTwoNumThree, |
|||
validateThreeNum, |
|||
validateInteger, |
|||
validateNF, |
|||
validateXQ, |
|||
validateroundNumber, |
|||
validateEngName, |
|||
validateCard, |
|||
validateHanset, |
|||
validateFamilyPhone, |
|||
validateName, |
|||
validateChargeperson, |
|||
validateCarNumber |
|||
} |
Binary file not shown.
@ -0,0 +1,26 @@ |
|||
{ |
|||
"compilerOptions": { |
|||
"target": "esnext", |
|||
"useDefineForClassFields": true, |
|||
"module": "esnext", |
|||
"moduleResolution": "node", |
|||
"strict": true, |
|||
"jsx": "preserve", |
|||
"sourceMap": true, |
|||
"resolveJsonModule": true, |
|||
"esModuleInterop": true, |
|||
"lib": ["esnext", "dom"], |
|||
"types": [ |
|||
"@dcloudio/types", |
|||
"vite/client", |
|||
"@types/node", |
|||
"vitest/globals" |
|||
], |
|||
"baseUrl": "./", |
|||
"paths": { |
|||
"@/*": ["src/*"], |
|||
"@components/*": ["src/components/*"] |
|||
} |
|||
}, |
|||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"] |
|||
} |
@ -0,0 +1,30 @@ |
|||
import presetWeapp from 'unocss-preset-weapp' |
|||
import { defineConfig } from 'unocss' |
|||
import { |
|||
transformerAttributify, |
|||
transformerClass |
|||
} from 'unocss-preset-weapp/transformer' |
|||
|
|||
export default defineConfig({ |
|||
presets: [ |
|||
// https://github.com/MellowCo/unocss-preset-weapp
|
|||
presetWeapp() |
|||
], |
|||
shortcuts: [ |
|||
{ |
|||
'border-base': 'border border-gray-500_10', |
|||
'flex-center': 'flex justify-center items-center', |
|||
'bg-base': 'bg-#f6f7fb', |
|||
'text-c1': 'color-#000/85', |
|||
'text-c2': 'color-#000/65', |
|||
'text-c3': 'color-#000/45', |
|||
'text-c4': 'color-#000/25' |
|||
} |
|||
], |
|||
transformers: [ |
|||
// https://github.com/MellowCo/unocss-preset-weapp/tree/main/src/transformer/transformerAttributify
|
|||
transformerAttributify(), |
|||
// https://github.com/MellowCo/unocss-preset-weapp/tree/main/src/transformer/transformerClass
|
|||
transformerClass() |
|||
] |
|||
}) |
@ -1,8 +0,0 @@ |
|||
import { defineConfig } from 'vite' |
|||
import uni from '@dcloudio/vite-plugin-uni' |
|||
// https://vitejs.dev/config/
|
|||
export default defineConfig({ |
|||
plugins: [ |
|||
uni(), |
|||
], |
|||
}) |
@ -0,0 +1,34 @@ |
|||
import { defineConfig } from 'vite' |
|||
import uni from '@dcloudio/vite-plugin-uni' |
|||
import path from 'path' |
|||
import Unocss from 'unocss/vite' |
|||
|
|||
// https://vitejs.dev/config/
|
|||
export default defineConfig({ |
|||
plugins: [ |
|||
uni(), |
|||
// https://github.com/antfu/unocss
|
|||
Unocss() |
|||
], |
|||
server: { |
|||
port: 81, |
|||
host: '0.0.0.0', |
|||
}, |
|||
resolve: { |
|||
alias: { |
|||
'@': path.resolve(__dirname, './src'), |
|||
'@components': path.resolve(__dirname, './src/components') |
|||
} |
|||
}, |
|||
css: { |
|||
// 配置`scss`和`less`全局变量
|
|||
preprocessorOptions: { |
|||
scss: { |
|||
additionalData: '@import "@/styles/vars/_base.scss";' |
|||
}, |
|||
less: { |
|||
additionalData: '@import "@/styles/vars/_base.less";' |
|||
} |
|||
} |
|||
} |
|||
}) |
@ -0,0 +1,7 @@ |
|||
import { defineConfig } from 'vitest/config' |
|||
|
|||
export default defineConfig({ |
|||
test: { |
|||
globals: true |
|||
} |
|||
}) |
Loading…
Reference in new issue