@ -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: 类型定义文件修改' }
|
|||
// ]
|
|||
} |
|||
} |
@ -0,0 +1,4 @@ |
|||
|
|||
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://192.168.0.106:12080/admin-api |
@ -0,0 +1,2 @@ |
|||
VITE_BASE_URL=http://dev.ccwin-in.com:25210/admin-api |
|||
VITE_BASE_URL_IMAGE=http://dev.ccwin-in.com:25210/admin-api |
@ -0,0 +1,2 @@ |
|||
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" |
|||
} |
|||
} |
@ -0,0 +1,31 @@ |
|||
.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* |
|||
|
|||
# Editor directories and files |
|||
.project |
|||
.idea |
|||
.vscode |
|||
*.suo |
|||
*.ntvs* |
|||
*.njsproj |
|||
*.sln |
|||
*.sw* |
|||
.hbuilderx |
|||
|
|||
.gitee |
|||
.github |
|||
|
|||
package-lock.json |
|||
yarn.lock |
@ -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 }
|
|||
} |
@ -0,0 +1,7 @@ |
|||
# 设置基础镜像 |
|||
FROM win-nginx |
|||
|
|||
WORKDIR /opt/eam-pda |
|||
COPY nginx.conf /usr/local/nginx/conf/nginx.conf |
|||
# 将dist/build/h5/文件中的内容复制到 /opt/eam-pda 这个目录下面 |
|||
COPY dist/build/h5/ /opt/eam-pda |
@ -0,0 +1,7 @@ |
|||
# 设置基础镜像 |
|||
FROM win-nginx |
|||
|
|||
WORKDIR /opt/eam-pda |
|||
COPY nginx_prod.conf /usr/local/nginx/conf/nginx.conf |
|||
# 将dist/build/h5/文件中的内容复制到 /opt/eam-pda 这个目录下面 |
|||
COPY dist/build/h5/ /opt/eam-pda |
@ -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 |
|||
|
|||
 |
|||
|
|||
 |
|||
|
|||
| H5 | 微信小程序 | App(iOS) | App(Android) | |
|||
| :-------------------------------------------------------------------------: | :-------------------------------------------------------------------------: | :-------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------: | |
|||
|  |  |  | <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> |
|||
|
|||
 |
|||
|
|||
 |
|||
|
|||
 |
|||
|
|||
</details> |
|||
|
|||
### H5 |
|||
```sh |
|||
# CSR |
|||
pnpm dev:h5 |
|||
# SSR |
|||
pnpm dev:h5:ssr |
|||
``` |
|||
|
|||
根据提示,打开对应地址即可访问 |
|||
|
|||
 |
|||
|
|||
### 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模拟器运行 |
|||
通过顶部菜单栏,找到运行入口 |
|||
|
|||
 |
|||
|
|||
选择一个目标设备,点击启动即可 |
|||
|
|||
 |
|||
|
|||
#### Android模拟器运行 |
|||
这里以[夜神模拟器](https://www.yeshen.com/blog/)为例 |
|||
|
|||
<details> |
|||
<summary>点击查看 详细步骤</summary> |
|||
|
|||
先通过 HBuilderX 修改模拟器端口为 `62001` |
|||
|
|||
 |
|||
|
|||
打开夜神模拟器 |
|||
|
|||
 |
|||
|
|||
选择运行到 Android 基座 |
|||
|
|||
 |
|||
|
|||
选择已经打开的模拟器,点击运行即可 |
|||
 |
|||
|
|||
 |
|||
|
|||
</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 |
|||
|
|||
 |
@ -0,0 +1,8 @@ |
|||
证书名称:pdatest.keystore |
|||
证书别名:pdatestalias |
|||
证书密码:092134 |
|||
SHA1: 53:30:B7:A6:0B:10:FA:0A:5A:3A:2F:4A:E5:21:96:EC:79:5B:41:C1 |
|||
SHA256: C4:85:45:66:D5:FC:6E:FB:C8:45:5D:FA:41:8D:94:6D:E5:C1:41:CE:D0:E3:4D:B3:F9:3B:68:6A:1B:E2:43:86 |
|||
Android 包名:com.eampda.uniapp |
|||
Android 应用签名:aa65e187685c2088b82d1a8c143bbabe//还没弄 |
|||
ios 包名:com.eam.bundleld//还没弄 |
@ -0,0 +1,25 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="en"> |
|||
|
|||
<head> |
|||
<meta charset="UTF-8" /> |
|||
<script> |
|||
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || |
|||
CSS.supports('top: constant(a)')) |
|||
document.write( |
|||
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + |
|||
(coverSupport ? ', viewport-fit=cover' : '') + '" />') |
|||
</script> |
|||
<title></title> |
|||
<!--preload-links--> |
|||
<!--app-context--> |
|||
</head> |
|||
|
|||
<body> |
|||
<div id="app"> |
|||
<!--app-html--> |
|||
</div> |
|||
<script type="module" src="/src/main.ts"></script> |
|||
</body> |
|||
|
|||
</html> |
@ -0,0 +1,53 @@ |
|||
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 eam { |
|||
server localhost:90 weight=10 max_fails=3 fail_timeout=10s; |
|||
} |
|||
server { |
|||
listen 82; |
|||
server_name_in_redirect off; |
|||
server_name dev.ccwin-in.com; |
|||
location /api/ { |
|||
proxy_pass http://eam/; |
|||
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 / { |
|||
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/eam-pda; |
|||
index index.html index.htm; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,60 @@ |
|||
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 eam { |
|||
server localhost:90 weight=10 max_fails=3 fail_timeout=10s; |
|||
} |
|||
server { |
|||
listen 82; |
|||
server_name_in_redirect off; |
|||
server_name _; |
|||
location /api/ { |
|||
proxy_pass http://eam/; |
|||
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/ { |
|||
proxy_cache my_zone; |
|||
proxy_cache_valid 200 304 12h; |
|||
proxy_cache_key $host$uri$is_args$args; |
|||
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/eam-pda; |
|||
index index.html index.htm; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,79 @@ |
|||
{ |
|||
"name": "闻荫APP", |
|||
"version": "1.0.0", |
|||
"private": true, |
|||
"scripts": { |
|||
"dev": "uni", |
|||
"dev:mp-weixin": "uni -p mp-weixin", |
|||
"dev:app": "uni -p app", |
|||
"dev:custom": "uni -p", |
|||
"test": "uni build --mode test", |
|||
"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-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", |
|||
"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.0.2" |
|||
}, |
|||
"devDependencies": { |
|||
"@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\"" |
|||
} |
|||
} |
@ -0,0 +1,100 @@ |
|||
<script setup lang="ts"> |
|||
import { |
|||
onLaunch, |
|||
onShow, |
|||
onHide |
|||
} from '@dcloudio/uni-app' |
|||
import { |
|||
getCurrentInstance |
|||
} from 'vue' |
|||
import { |
|||
getAccessToken |
|||
} from '@/utils/auth' |
|||
const { proxy } = getCurrentInstance() |
|||
|
|||
import { storeToRefs } from 'pinia' |
|||
import { useCountStore } from '@/store' |
|||
|
|||
|
|||
// 获取自定义的store |
|||
const store = useCountStore() |
|||
|
|||
onLaunch(async () => { |
|||
// #ifdef MP-WEIXIN |
|||
if (uni.canIUse('getUpdateManager')) { |
|||
const updateManager = uni.getUpdateManager() |
|||
updateManager.onCheckForUpdate(function (res) { |
|||
if (res.hasUpdate) { |
|||
updateManager.onUpdateReady(function () { |
|||
uni.showModal({ |
|||
title: '更新提示', |
|||
content: '新版本已经准备好,是否重启应用?', |
|||
success: function (res) { |
|||
if (res.confirm) { |
|||
updateManager.applyUpdate() |
|||
} |
|||
} |
|||
}) |
|||
}) |
|||
updateManager.onUpdateFailed(function () { |
|||
uni.showModal({ |
|||
title: '已经有新版本了哟~', |
|||
content: '新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~' |
|||
}) |
|||
}) |
|||
} |
|||
}) |
|||
} else { |
|||
uni.showModal({ |
|||
title: '提示', |
|||
content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。' |
|||
}) |
|||
} |
|||
// #endif |
|||
// plus.runtime.getProperty(plus.runtime.appid, function(widgetInfo) { |
|||
// _this.$post('common/upApp', { |
|||
// version: widgetInfo.version, |
|||
// }).then(res => { |
|||
// if (res.status == 0) { |
|||
// if (res.data.code == 0) { |
|||
// uni.downloadFile({ |
|||
// url: res.data.download, |
|||
// success: (downloadResult) => { |
|||
// if (downloadResult.statusCode === 200) { |
|||
// plus.runtime.install(downloadResult |
|||
// .tempFilePath, { |
|||
// force: true |
|||
// }, |
|||
// function() { |
|||
// plus.runtime.restart(); |
|||
// }, |
|||
// function(e) { |
|||
|
|||
|
|||
// }); |
|||
// } |
|||
// } |
|||
// }); |
|||
// } |
|||
// } |
|||
// }) |
|||
// }); |
|||
if (getAccessToken()) { |
|||
await store.GetPermissionInfo().then(res => { |
|||
uni.setStorageSync('permissionInfo',res.permissions) |
|||
uni.setStorageSync('roles',res.roles) |
|||
}).catch(() => { }) |
|||
await store.GetInfo().then(res => { |
|||
}).catch(() => { }) |
|||
} |
|||
// 解决onLaunch和onLoad异步问题 |
|||
proxy.$isResolve(); |
|||
}) |
|||
onShow(() => { |
|||
}) |
|||
onHide(() => { |
|||
}) |
|||
</script> |
|||
<style lang="scss"> |
|||
@import 'vk-uview-ui/index.scss'; |
|||
</style> |
@ -0,0 +1,111 @@ |
|||
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 headers : any = { |
|||
token: getAccessToken(), |
|||
'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=>{ |
|||
uni.showToast({ |
|||
title: '网络错误', |
|||
icon: 'none' |
|||
}) |
|||
}) |
|||
export default instance |
@ -0,0 +1,13 @@ |
|||
import http from './http' |
|||
// 获取采购订单分页列表
|
|||
export function getInLocationPage(params) { |
|||
return http.get('/eam/item-order-main/getPdaPage',{params}) |
|||
} |
|||
// 获取采购订单分页列表
|
|||
export function getInLocationDetail(id) { |
|||
return http.get('/eam/item-order-main/getPdaDetailsById?id='+id) |
|||
} |
|||
// 入库新增
|
|||
export function inLocationCreat(data) { |
|||
return http.post('/eam/item-order-main/inOperation',data) |
|||
} |
@ -0,0 +1,14 @@ |
|||
|
|||
import http from './http' |
|||
// 获取库位
|
|||
export function getLocation(number) { |
|||
return http.get('/eam/location/scanCodeByNumber?number='+number) |
|||
} |
|||
// 出库获取库位
|
|||
export function getOutLocation(data) { |
|||
return http.post('/eam/location/outScanCodeByNumber',data) |
|||
} |
|||
// 首页扫码获取详情
|
|||
export function pdaItemAndLocation(number) { |
|||
return http.get('/eam/location/pdaItemAndLocation?number='+number) |
|||
} |
@ -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') |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
@ -0,0 +1,13 @@ |
|||
import http from './http' |
|||
// 获取领用出库分页列表
|
|||
export function getOutLocationPage(params) { |
|||
return http.get('/eam/item-apply-request-main/getAppOutOperaPage',{params}) |
|||
} |
|||
// 获取领用出库详情
|
|||
export function getOutLocationDetail(params) { |
|||
return http.get('/eam/item-apply-request-main/appGetByNumber',{params}) |
|||
} |
|||
// 出库新增
|
|||
export function outLocationCreat(data) { |
|||
return http.post('/eam/item-apply-request-main/outOperation',data) |
|||
} |
@ -0,0 +1,10 @@ |
|||
import http from './http' |
|||
|
|||
// 获取备件信息
|
|||
export function getSparePartsInfo(params) { |
|||
return http.get('/eam/item/inScanCodeByNumber',{params}) |
|||
} |
|||
// 备件归还获取备件信息
|
|||
export function getSparePartsReturnInfo(params) { |
|||
return http.get('/eam/item/scanCodeByNumber',{params}) |
|||
} |
@ -0,0 +1,5 @@ |
|||
import http from './http' |
|||
// 归还
|
|||
export function sparePartsReturn(data) { |
|||
return http.post('/eam/item-apply-request-main/inOperation',data) |
|||
} |
@ -0,0 +1,11 @@ |
|||
import upload from '@/api/uploadHttp' |
|||
// import request from '@/utils/request'
|
|||
// 上传
|
|||
export function uploadFile(data) { |
|||
return upload({ |
|||
url: '/infra/file/upload', |
|||
method: 'post', |
|||
filePath:data.filePath, |
|||
name: data.name |
|||
}) |
|||
} |
@ -0,0 +1,85 @@ |
|||
import axios from 'axios' |
|||
|
|||
import { getFullURL } from '@/utils/http' |
|||
import { getAccessToken } from '@/utils/auth' |
|||
|
|||
// const baseURL1 = import.meta.env.VITE_BASE_URL
|
|||
const upload = axios.create({ |
|||
baseURL: import.meta.env.VITE_BASE_URL, |
|||
adapter(config) { |
|||
const { url, method, data, params, headers, baseURL, paramsSerializer, filePath } = |
|||
config |
|||
headers['tenant-id'] = '1'; |
|||
return new Promise((resolve, reject) => { |
|||
uni.uploadFile({ |
|||
url: getFullURL(baseURL || '', url!, params, paramsSerializer), |
|||
filePath: filePath, |
|||
name: 'file', |
|||
header: headers, |
|||
formData: { |
|||
'user': 'test' |
|||
}, |
|||
success: (res) => { |
|||
resolve(res) |
|||
}, |
|||
fail: (error) => { |
|||
reject(error) |
|||
} |
|||
}) |
|||
|
|||
}) |
|||
} |
|||
}) |
|||
|
|||
|
|||
/** |
|||
* 请求拦截 |
|||
*/ |
|||
upload.interceptors.request.use((config) => { |
|||
const { method, params, url } = config |
|||
// 附带鉴权的token
|
|||
const headers : any = { |
|||
token: getAccessToken(), |
|||
'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 |
|||
} |
|||
}) |
|||
|
|||
/** |
|||
* 响应拦截 |
|||
*/ |
|||
upload.interceptors.response.use((v) => { |
|||
if (v.data?.code === 401) { |
|||
// alert('即将跳转登录页。。。', '登录过期')
|
|||
// setTimeout(redirectHome, 1500)
|
|||
return v.data |
|||
} |
|||
|
|||
// @ts-ignore
|
|||
if ((v.status || v.statusCode) === 200) { |
|||
return v.data |
|||
} |
|||
// alert(v.statusText, '网络错误')
|
|||
return Promise.reject(v) |
|||
}) |
|||
|
|||
export default upload |
@ -0,0 +1,6 @@ |
|||
import http from './http' |
|||
|
|||
// 归还人员
|
|||
export function getReverterUser() { |
|||
return http.get('/system/user/list-all-simple') |
|||
} |
@ -0,0 +1,85 @@ |
|||
<template> |
|||
<view class="content"> |
|||
<view class="screen-input"> |
|||
<u-search |
|||
v-model='keyWord' |
|||
:show-action='false' |
|||
:bg-color="searchData.bgBolor ||'white'" |
|||
:border-color="searchData.borderColor ||'#E4E4E4'" |
|||
:shape="searchData.shape ||'square'" |
|||
:height="searchData.height || 80" |
|||
:placeholder="searchData.placeholder ||'请输入设备名称'" |
|||
:clearabled="true" |
|||
@search='search' |
|||
@clear='clear' |
|||
> |
|||
</u-search> |
|||
</view> |
|||
<view class="screen-btn" @click="screen" v-if="isShowScreen"> |
|||
<image src="../../static/icon/screen.png" mode="widthFix"></image> |
|||
<view>筛选</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
props: { |
|||
searchData:{ |
|||
type: Object, |
|||
default:()=>{return {}}, |
|||
require:false |
|||
}, |
|||
isShowScreen: { |
|||
type: Boolean, |
|||
default:()=>{return true}, |
|||
require:false |
|||
}, |
|||
}, |
|||
data() { |
|||
return { |
|||
keyWord: '', |
|||
} |
|||
}, |
|||
methods: { |
|||
// 搜索 |
|||
search() { |
|||
this.$emit('search', this.keyWord) |
|||
}, |
|||
// 搜索 |
|||
clear() { |
|||
this.$emit('search', '') |
|||
}, |
|||
// 筛选 |
|||
screen() { |
|||
this.$emit('screen') |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.content { |
|||
padding: 20rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
background: white; |
|||
|
|||
.screen-input { |
|||
flex: 1; |
|||
width: 0px; |
|||
} |
|||
|
|||
.screen-btn { |
|||
display: flex; |
|||
align-items: center; |
|||
margin-left:20rpx; |
|||
|
|||
image { |
|||
width: 30rpx; |
|||
margin-right: 6rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
</style> |
@ -0,0 +1,14 @@ |
|||
import CryptoJS from 'crypto-js' |
|||
/** |
|||
* @word 要加密的内容 |
|||
* @keyWord String 服务器随机返回的关键字 |
|||
* */ |
|||
export function aesEncrypt(word, keyWord = "XwKsGlMcdPMEhR1B") { |
|||
var key = CryptoJS.enc.Utf8.parse(keyWord); |
|||
var srcs = CryptoJS.enc.Utf8.parse(word); |
|||
var encrypted = CryptoJS.AES.encrypt(srcs, key, { |
|||
mode: CryptoJS.mode.ECB, |
|||
padding: CryptoJS.pad.Pkcs7 |
|||
}); |
|||
return encrypted.toString(); |
|||
} |
@ -0,0 +1,17 @@ |
|||
import config from '@/config' |
|||
const baseUrl = config.baseUrl |
|||
export const myRequest = (option = {}) => { |
|||
return new Promise((reslove, reject) => { |
|||
uni.request({ |
|||
url: baseUrl + option.url, |
|||
data: option.data, |
|||
method: option.method || "GET", |
|||
success: (result) => { |
|||
reslove(result) |
|||
}, |
|||
fail: (error) => { |
|||
reject(error) |
|||
} |
|||
}) |
|||
}) |
|||
} |
@ -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 |
|||
} |
@ -0,0 +1,43 @@ |
|||
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' |
|||
import auth from './plugins/auth' |
|||
|
|||
|
|||
// 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 |
|||
app.config.globalProperties.$auth = auth |
|||
|
|||
|
|||
|
|||
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,85 @@ |
|||
{ |
|||
"name" : "富维汽车镜", |
|||
"appid" : "__UNI__0DC0349", |
|||
"description" : "", |
|||
"versionName" : "1.0.0", |
|||
"versionCode" : "100", |
|||
"transformPx" : false, |
|||
/* 5+App特有相关 */ |
|||
"app-plus" : { |
|||
"usingComponents" : true, |
|||
"nvueStyleCompiler" : "uni-app", |
|||
"compilerVersion" : 3, |
|||
"splashscreen" : { |
|||
"alwaysShowBeforeRender" : true, |
|||
"waiting" : true, |
|||
"autoclose" : true, |
|||
"delay" : 0 |
|||
}, |
|||
"compatible" : { |
|||
"ignoreVersion" : true |
|||
}, |
|||
/* 模块配置 */ |
|||
"modules" : {}, |
|||
/* 应用发布信息 */ |
|||
"distribute" : { |
|||
/* android打包配置 */ |
|||
"android" : { |
|||
"permissions" : [ |
|||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>", |
|||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>", |
|||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>", |
|||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>", |
|||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>", |
|||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>", |
|||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>", |
|||
"<uses-permission android:name=\"android.permission.CAMERA\"/>", |
|||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>", |
|||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>", |
|||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>", |
|||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>", |
|||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>", |
|||
"<uses-feature android:name=\"android.hardware.camera\"/>", |
|||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>" |
|||
] |
|||
}, |
|||
/* ios打包配置 */ |
|||
"ios" : { |
|||
"dSYMs" : false |
|||
}, |
|||
/* SDK配置 */ |
|||
"sdkConfigs" : { |
|||
"ad" : {} |
|||
} |
|||
} |
|||
}, |
|||
/* 快应用特有相关 */ |
|||
"quickapp" : {}, |
|||
/* 小程序特有相关 */ |
|||
"mp-weixin" : { |
|||
"appid" : "wx6176535b0b0153f0", |
|||
"setting" : { |
|||
"urlCheck" : false |
|||
}, |
|||
"usingComponents" : true |
|||
}, |
|||
"mp-alipay" : { |
|||
"usingComponents" : true |
|||
}, |
|||
"mp-baidu" : { |
|||
"usingComponents" : true |
|||
}, |
|||
"mp-toutiao" : { |
|||
"usingComponents" : true |
|||
}, |
|||
"uniStatistics" : { |
|||
"enable" : false |
|||
}, |
|||
"vueVersion" : "3", |
|||
"h5" : { |
|||
"template" : "index.html", |
|||
"devServer" : { |
|||
"port" : 9020 |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,68 @@ |
|||
{ |
|||
"pages": [{ |
|||
"path": "pages/index", |
|||
"style": { |
|||
"navigationBarTitleText": "首页", |
|||
"navigationStyle": "custom" |
|||
} |
|||
}, { |
|||
"path": "pages/login", |
|||
"style": { |
|||
"navigationStyle": "custom" |
|||
} |
|||
}, { |
|||
"path": "pages/inLocation/index", |
|||
"style": { |
|||
"navigationStyle": "custom", |
|||
"navigationBarBackgroundColor": "#409eff", |
|||
"navigationBarTextStyle": "white" |
|||
} |
|||
}, { |
|||
"path": "pages/inLocation/addForm", |
|||
"style": { |
|||
"navigationBarTitleText": "入库信息", |
|||
"navigationBarBackgroundColor": "#409eff", |
|||
"navigationBarTextStyle": "white" |
|||
} |
|||
}, { |
|||
"path": "pages/sparePartsReturn/addForm", |
|||
"style": { |
|||
"navigationBarTitleText": "备件归还", |
|||
"navigationBarBackgroundColor": "#409eff", |
|||
"navigationBarTextStyle": "white" |
|||
} |
|||
}, { |
|||
"path": "pages/outLocation/index", |
|||
"style": { |
|||
"navigationBarTitleText": "领用出库", |
|||
"navigationBarBackgroundColor": "#409eff", |
|||
"navigationBarTextStyle": "white" |
|||
} |
|||
}, { |
|||
"path": "pages/outLocation/addForm", |
|||
"style": { |
|||
"navigationBarTitleText": "出库信息", |
|||
"navigationBarBackgroundColor": "#409eff", |
|||
"navigationBarTextStyle": "white" |
|||
} |
|||
}, { |
|||
"path": "pages/scanCode/scanCode", |
|||
"style": { |
|||
"navigationBarTitleText": "扫码详情", |
|||
"navigationBarBackgroundColor": "#409eff", |
|||
"navigationBarTextStyle": "white" |
|||
} |
|||
}], |
|||
|
|||
"globalStyle": { |
|||
"navigationBarTextStyle": "black", |
|||
"navigationBarTitleText": "", |
|||
"navigationBarBackgroundColor": "#fff", |
|||
"backgroundColorBottom": "#f5f5f5" |
|||
}, |
|||
"easycom": { |
|||
"custom": { |
|||
"^u-(.*)": "vk-uview-ui/components/u-$1/u-$1.vue" |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,526 @@ |
|||
<template> |
|||
<!-- 添加维修工单 --> |
|||
<view class="add-form-container"> |
|||
<u-form :model="form" ref="formRef" label-width="160rpx"> |
|||
<u-form-item label="批次号" prop="number"> |
|||
<u-input v-model="form.number" placeholder="请输入批次号" /> |
|||
</u-form-item> |
|||
<u-form-item label="供应商" prop="supplierName"> |
|||
<u-input v-model="form.supplierName" placeholder="请输入供应商" /> |
|||
</u-form-item> |
|||
</u-form> |
|||
<view class="list"> |
|||
<view class="title"> |
|||
<span>*</span>订单信息 |
|||
</view> |
|||
<view class="item " v-for="(item,index) in orderList" :key="index"> |
|||
<view class="item-box"> |
|||
<view class="spare-title"> |
|||
<view class="title-txt"> |
|||
备件名称:{{item.itemName}} |
|||
</view> |
|||
</view> |
|||
<u-row gutter="16"> |
|||
<!-- <u-col :span="24"> |
|||
<view class="dec"> |
|||
库位:{{item.locationNumber}} |
|||
</view> |
|||
</u-col> --> |
|||
|
|||
<u-col :span="24"> |
|||
<view class="dec"> |
|||
已入库数量:{{item.deliveryQty}} |
|||
</view> |
|||
</u-col> |
|||
<u-col :span="24"> |
|||
<view class="dec"> |
|||
采购数量:{{item.qty}} |
|||
</view> |
|||
</u-col> |
|||
</u-row> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="list"> |
|||
<view class="title"> |
|||
<span>*</span>申请备件 |
|||
</view> |
|||
<view class="item " v-for="(item,index) in form.itemNumbers" :key="index"> |
|||
<view class="item-box"> |
|||
<view class="spare-title"> |
|||
<view class="title-txt"> |
|||
备件名称:{{item.itemName}} |
|||
</view> |
|||
</view> |
|||
<u-row gutter="16"> |
|||
<u-col :span="24"> |
|||
<view class="dec"> |
|||
入库数量:{{item.qty}} |
|||
</view> |
|||
</u-col> |
|||
<u-col :span="24"> |
|||
<view class="dec"> |
|||
采购数量:{{item.applyQty}} |
|||
</view> |
|||
</u-col> |
|||
</u-row> |
|||
</view> |
|||
<u-icon name="minus-circle" color="#aaaaaa" size="60" @click="delSpareParts(index)"></u-icon> |
|||
</view> |
|||
<view class="add-btn"> |
|||
<u-button type="primary" @click="open"><u-icon name="plus-circle" color="#ffffff" |
|||
size="36"></u-icon>添加备件</u-button> |
|||
</view> |
|||
</view> |
|||
<view class="footer"> |
|||
<view class="btns"> |
|||
<button class="reset" @click="reset">重置</button> |
|||
<button class="sure" @click="submit" :loading='loading' :disabled='loading'>确定</button> |
|||
</view> |
|||
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view> |
|||
</view> |
|||
<!-- 添加备件 --> |
|||
<u-popup v-model="isPopupShow" mode="center" border-radius="14"> |
|||
<view class="popup-title">添加备件</view> |
|||
<scroll-view scroll-y="true" style="max-height:60vh;"> |
|||
<view class="popup"> |
|||
<u-form :model="form1" ref="form1Ref" label-width="160rpx"> |
|||
<u-form-item :label="`备件编号`" prop="itemNumber" required> |
|||
<view class="select"> |
|||
<u-input v-model="form1.itemNumber" placeholder="请选择备件" @blur='blur1()' |
|||
@confirm="handelScanMsg1" :focus='isFocus' /> |
|||
</view> |
|||
</u-form-item> |
|||
<u-form-item :label="`备件名称`" prop="itemName" required class="disabled"> |
|||
<view class="select"> |
|||
<u-input v-model="form1.itemName" placeholder="根据备件编号获取" disabled /> |
|||
</view> |
|||
</u-form-item> |
|||
<u-form-item label="库位" prop="locationNumber" required v-if="isShow"> |
|||
<u-input v-model="form1.locationNumber" placeholder="请输入库位" @blur='blur()' |
|||
@confirm="handelScanMsg" /> |
|||
|
|||
</u-form-item> |
|||
<u-form-item label="采购数量" prop="applyQty" required class="disabled"> |
|||
<u-input v-model="form1.applyQty" type="number" disabled placeholder="请输入采购数量" /> |
|||
</u-form-item> |
|||
<u-form-item label="已入库数量" prop="deliveryQty" required class="disabled"> |
|||
<u-input v-model="form1.deliveryQty" type="number" disabled placeholder="请输入已入库数量" /> |
|||
</u-form-item> |
|||
<u-form-item label="入库数量" prop="qty" required> |
|||
<u-input v-model="form1.qty" type="number" placeholder="请输入入库数量" /> |
|||
</u-form-item> |
|||
<u-form-item label="描述" prop="qty"> |
|||
<u-input v-model="form1.describes" placeholder="请输入描述" /> |
|||
</u-form-item> |
|||
</u-form> |
|||
</view> |
|||
</scroll-view> |
|||
<view class="popup-footer"> |
|||
<view @click="isPopupShow = false">取消</view> |
|||
<view class="sure" @click="addSpare">确认</view> |
|||
</view> |
|||
</u-popup> |
|||
</view> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { |
|||
onLoad |
|||
} from '@dcloudio/uni-app' |
|||
import { |
|||
ref, |
|||
getCurrentInstance |
|||
} from 'vue' |
|||
import * as inLocationApi from "@/api/inLocation" |
|||
import * as sparePartsApi from "@/api/spareParts" |
|||
import * as locationApi from "@/api/location" |
|||
const { proxy } = getCurrentInstance() |
|||
|
|||
const loading = ref(false) |
|||
const orderList = ref([])//订单信息 |
|||
// 备件弹窗 |
|||
const isPopupShow = ref(false) |
|||
const form = ref({ |
|||
id: '', |
|||
number: '', |
|||
itemNumbers: [], |
|||
supplierName:'' |
|||
}) |
|||
const form1 = ref({ |
|||
itemNumber: "", |
|||
itemName: '', |
|||
locationNumber: '', |
|||
applyQty: '', |
|||
deliveryQty: '', |
|||
qty: '' |
|||
}) |
|||
const itemNumber = ref() |
|||
const isShow = ref(false) |
|||
const locationList = ref([])//备件的库位列表 |
|||
const locationItem = ref('')//备件账内库 |
|||
const isFocus = ref(false) |
|||
const msg = ref('') |
|||
function submit() { |
|||
if (form.value.itemNumbers.length === 0) { |
|||
proxy.$modal.showToast('请选择备件') |
|||
return; |
|||
} |
|||
proxy.$modal.confirm('是否添加入库信息').then(() => { |
|||
proxy.$modal.loading('加载中') |
|||
loading.value = true |
|||
inLocationApi.inLocationCreat(form.value).then((res) => { |
|||
proxy.$modal.closeLoading() |
|||
if (res.data) { |
|||
proxy.$modal.showToast('添加成功') |
|||
setTimeout(() => { |
|||
proxy.$tab.navigateBack() |
|||
loading.value = false |
|||
}, 1500) |
|||
} else { |
|||
proxy.$modal.showToast('添加失败') |
|||
loading.value = false |
|||
} |
|||
}).catch(() => { |
|||
proxy.$modal.closeLoading() |
|||
loading.value = false |
|||
}) |
|||
}) |
|||
|
|||
} |
|||
// 重置 |
|||
function reset() { |
|||
form.value.supplierName = '' |
|||
form.value.itemNumbers = [] |
|||
} |
|||
// 获取订单信息详情 |
|||
async function getInLocationDetail() { |
|||
await inLocationApi.getInLocationDetail(form.value.id).then(res => { |
|||
orderList.value = res.data |
|||
}).catch((err) => { }) |
|||
} |
|||
// 打开弹窗 |
|||
function open() { |
|||
form1.value = { |
|||
itemNumber: "", |
|||
itemName: '', |
|||
locationNumber: '', |
|||
applyQty: '', |
|||
deliveryQty: '', |
|||
qty: '' |
|||
} |
|||
isPopupShow.value = true |
|||
isShow.value = false |
|||
isFocus.value = true |
|||
} |
|||
// 添加备件 |
|||
function addSpare() { |
|||
// 校验 |
|||
if (!form1.value.itemNumber) { |
|||
proxy.$modal.showToast('请选择备件') |
|||
return; |
|||
} |
|||
if (!form1.value.itemName) { |
|||
proxy.$modal.showToast(msg.value) |
|||
return; |
|||
} |
|||
if (!form1.value.locationNumber) { |
|||
proxy.$modal.showToast('请选择库位') |
|||
return; |
|||
} |
|||
if (!locationItem.value || locationItem.value.isInAccount === 'FALSE') { |
|||
proxy.$modal.showToast('该库位属于帐外库,请选择帐内库') |
|||
return; |
|||
} |
|||
if (itemNumber.value) { |
|||
proxy.$modal.showToast('该库位已绑定过备件') |
|||
return; |
|||
} |
|||
if (!form1.value.qty) { |
|||
proxy.$modal.showToast(`请输入数量`) |
|||
return; |
|||
} |
|||
if (Number(form1.value.qty) + Number(form1.value.deliveryQty) > Number(form1.value.applyQty)) { |
|||
proxy.$modal.showToast('已入库数量和入库数量不可大于采购数量') |
|||
return; |
|||
} |
|||
if (form.value.itemNumbers && form.value.itemNumbers.length > 0) { |
|||
let arr = form.value.itemNumbers.filter(item => item.itemNumber == form1.value.itemNumber) |
|||
if (arr && arr.length > 0) { |
|||
proxy.$modal.showToast('该备件已添加') |
|||
return; |
|||
} |
|||
let arr1 = orderList.value.filter(item => item.itemNumber == form1.value.itemNumber) |
|||
if (!arr1 || (arr1 && arr1.length == 0)) { |
|||
proxy.$modal.showToast('订单信息没有该备件') |
|||
return; |
|||
} |
|||
} |
|||
form.value.itemNumbers.push(form1.value) |
|||
isPopupShow.value = false |
|||
} |
|||
// 删除备件 |
|||
function delSpareParts(index) { |
|||
form.value.itemNumbers.splice(index, 1) |
|||
} |
|||
function getLocation() { |
|||
locationApi.getLocation(form1.value.locationNumber).then(res => { |
|||
if (!res.data) { |
|||
msg.value = res.msg |
|||
proxy.$modal.showToast(res.msg) |
|||
return; |
|||
} |
|||
locationItem.value = res.data |
|||
form1.value.areaNumber = locationItem.value.areaNumber |
|||
itemNumber.value = res.data.itemNumber || '' |
|||
// 判断该库位在之前添加的列表里有没有被绑定过 |
|||
if (form.value.itemNumbers && form.value.itemNumbers.length > 0) { |
|||
let arr = form.value.itemNumbers.filter(item => item.locationNumber == form1.value |
|||
.locationNumber) |
|||
if (arr && arr.length > 0) { |
|||
itemNumber.value = 1 |
|||
} else { |
|||
itemNumber.value = res.data.itemNumber || '' |
|||
} |
|||
} else { |
|||
itemNumber.value = res.data.itemNumber || '' |
|||
} |
|||
}).catch((err) => { }) |
|||
} |
|||
function blur() { |
|||
if (form1.value.locationNumber) { |
|||
getLocation() |
|||
} |
|||
|
|||
} |
|||
// 扫描设备条码 |
|||
function handelScanMsg() { |
|||
getLocation() |
|||
} |
|||
// 获取备件信息 |
|||
function getSparePartsInfo() { |
|||
sparePartsApi.getSparePartsInfo({ |
|||
number: form1.value.itemNumber, |
|||
id: form.value.id |
|||
}).then(res => { |
|||
if (!res.data) { |
|||
itemNumber.value = '' |
|||
form1.value.areaNumber = '' |
|||
form1.value.locationNumber = ''; |
|||
form1.value.itemName = '' |
|||
return; |
|||
} |
|||
itemNumber.value = '' |
|||
form1.value.itemName = res.data.itemName |
|||
form1.value.deliveryQty = res.data.deliveryQty |
|||
form1.value.applyQty = res.data.applyQty |
|||
// 判断是否有帐内库 |
|||
locationItem.value = res.data.list.filter(item => item.isInAccount === 'TRUE')[0] |
|||
if (locationItem.value) { |
|||
form1.value.areaNumber = locationItem.value.areaNumber |
|||
form1.value.locationNumber = locationItem.value.locationNumber |
|||
isShow.value = false |
|||
} else { |
|||
form1.value.areaNumber = '' |
|||
form1.value.locationNumber = '' |
|||
isShow.value = true |
|||
} |
|||
|
|||
}).catch((err) => { |
|||
itemNumber.value = '' |
|||
form1.value.areaNumber = '' |
|||
form1.value.itemName = '' |
|||
form1.value.applyQty = '' |
|||
form1.value.deliveryQty = '' |
|||
locationList.value = []; |
|||
}) |
|||
} |
|||
function blur1() { |
|||
if (form1.value.itemNumber) { |
|||
getSparePartsInfo() |
|||
} |
|||
} |
|||
// 扫描设备条码 |
|||
function handelScanMsg1() { |
|||
getSparePartsInfo() |
|||
} |
|||
onLoad(async(option) => { |
|||
// if (option.id) this.form.id = option.id; |
|||
// if (option.number) this.form.number = option.number; |
|||
if (option.data && JSON.parse(decodeURIComponent(option.data)) && JSON.parse(decodeURIComponent(option |
|||
.data)).id) { |
|||
let formData = JSON.parse(decodeURIComponent(option.data)) |
|||
form.value.supplierName = formData.supplierName |
|||
form.value.number = formData.number |
|||
form.value.id =formData.id |
|||
} |
|||
await getInLocationDetail() |
|||
}) |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.add-form-container { |
|||
min-height: calc(100vh - 140rpx); |
|||
background: white; |
|||
padding: 0px 0rpx 140rpx; |
|||
} |
|||
|
|||
.u-form-item { |
|||
padding: 20rpx 30rpx; |
|||
} |
|||
|
|||
.disabled { |
|||
background: #f5f5f5; |
|||
} |
|||
|
|||
.footer { |
|||
position: fixed; |
|||
bottom: 0px; |
|||
left: 0px; |
|||
width: 100%; |
|||
z-index: 22; |
|||
} |
|||
|
|||
.btns { |
|||
display: flex; |
|||
|
|||
|
|||
button { |
|||
flex: 1; |
|||
} |
|||
|
|||
.sure { |
|||
background: #409eff; |
|||
color: white; |
|||
border-radius: 0px; |
|||
|
|||
&::after { |
|||
border: 1px solid #409eff; |
|||
border-radius: 0px; |
|||
} |
|||
} |
|||
|
|||
.reset { |
|||
background: #F5F5F5; |
|||
border-radius: 0px; |
|||
|
|||
&::after { |
|||
border-radius: 0px; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.right-button { |
|||
background: #409eff; |
|||
color: white; |
|||
padding: 0rpx 30rpx; |
|||
border-radius: 16rpx; |
|||
text-align: center; |
|||
font-size: 28rpx; |
|||
} |
|||
|
|||
.select { |
|||
display: flex; |
|||
align-items: center; |
|||
height: 72rpx; |
|||
width: 100%; |
|||
|
|||
.input { |
|||
flex: 1; |
|||
font-size: 28rpx; |
|||
color: #000000; |
|||
} |
|||
|
|||
.placeholder { |
|||
flex: 1; |
|||
font-size: 28rpx; |
|||
color: rgb(192, 196, 204); |
|||
|
|||
} |
|||
} |
|||
|
|||
.title { |
|||
padding: 32rpx 0rpx; |
|||
position: relative; |
|||
|
|||
span { |
|||
position: absolute; |
|||
left: -16rpx; |
|||
color: #fa3534; |
|||
top: 19px; |
|||
} |
|||
} |
|||
|
|||
.list { |
|||
padding: 0rpx 30rpx; |
|||
|
|||
.item { |
|||
display: flex; |
|||
margin-bottom: 20rpx; |
|||
|
|||
.item-box { |
|||
background: #F5F5F5; |
|||
border-radius: 12rpx; |
|||
flex: 1; |
|||
width: 0rpx; |
|||
} |
|||
|
|||
.spare-title { |
|||
padding: 20rpx 30rpx; |
|||
border-bottom: 1px solid #e4e4e4; |
|||
|
|||
.title-txt { |
|||
color: #409eff; |
|||
font-size: 30rpx; |
|||
font-weight: bold; |
|||
} |
|||
} |
|||
|
|||
.dec { |
|||
color: #9c9c9c; |
|||
padding: 20rpx 30rpx 20rpx; |
|||
} |
|||
|
|||
} |
|||
} |
|||
|
|||
.add-btn { |
|||
display: flex; |
|||
justify-content: flex-start; |
|||
align-items: center; |
|||
} |
|||
|
|||
.popup-title { |
|||
text-align: center; |
|||
font-size: 32rpx; |
|||
font-weight: bold; |
|||
color: #409eff; |
|||
padding: 30rpx 30rpx 0px |
|||
} |
|||
|
|||
.popup { |
|||
width: 600rpx; |
|||
padding: 30rpx 0rpx 30rpx; |
|||
|
|||
} |
|||
|
|||
.popup-footer { |
|||
display: flex; |
|||
border-top: 1px solid #e4e4e4; |
|||
|
|||
view { |
|||
line-height: 100rpx; |
|||
flex: 1; |
|||
text-align: center; |
|||
|
|||
&.sure { |
|||
color: #409eff; |
|||
} |
|||
} |
|||
} |
|||
|
|||
::v-deep .u-checkbox-group { |
|||
display: grid !important; |
|||
} |
|||
</style> |
@ -0,0 +1,148 @@ |
|||
<template> |
|||
<!-- 采购入库 --> |
|||
<view class="container"> |
|||
<u-navbar back-icon-color='#fff' :background="{ background: '#409eff'}" back-text="" title-color='#fff' |
|||
title="采购入库"> |
|||
</u-navbar> |
|||
<!-- <Search @search='search' @screen='screen' /> --> |
|||
<view class="list"> |
|||
<view class="item" v-for="(item,index) in list" :key="index" @click="openDetail(item)"> |
|||
<view class="title"> |
|||
<view class="title-txt"> |
|||
{{item.number}} |
|||
</view> |
|||
<view class="time"> |
|||
{{`${$time.formatDate(item.createTime)}`}} |
|||
</view> |
|||
</view> |
|||
<view class="dec"> |
|||
采购人:<span>{{item.purchaser}}</span> |
|||
</view> |
|||
<view class="dec" v-if="item.date&&item.date.length>0"> |
|||
采购时间:<span>{{`${item.date[0]}-${item.date[1]>=10?item.date[1]:'0'+item.date[1]}-${item.date[2]>=10?item.date[2]:'0'+item.date[2]}`}}</span> |
|||
</view> |
|||
<view class="bottom"> |
|||
<view class="status"> |
|||
<u-tag text="未完成" v-if="item.status=='INCOMPLETE'" bg-color='rgba(255,255,255,0)' color='#e01f54' |
|||
border-color='#e01f54' type="success" shape='circle' /> |
|||
<u-tag text="已完成" v-else-if="item.status=='COMPLETE'" bg-color='rgba(255,255,255,0)' color='#2ba471' |
|||
border-color='#2ba471' type="info" shape='circle' /> |
|||
</view> |
|||
|
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { |
|||
onLoad, |
|||
onShow, |
|||
onReachBottom |
|||
} from '@dcloudio/uni-app' |
|||
import { |
|||
ref, |
|||
getCurrentInstance |
|||
} from 'vue' |
|||
import * as inLocationApi from "@/api/inLocation" |
|||
|
|||
const { proxy } = getCurrentInstance() |
|||
const params = ref({ |
|||
pageNo: 1, |
|||
pageSize: 10, |
|||
}) |
|||
const status = ref('loadmore') //是否显示没有更多了 |
|||
const list = ref([]) |
|||
function openDetail(item){ |
|||
if(!proxy.$auth.hasPermiOr(['eam:item-order-main:inOperation']))return; |
|||
proxy.$tab.navigateTo(`/pages/inLocation/addForm?data=${encodeURIComponent(JSON.stringify(item))}`) |
|||
} |
|||
async function getList() { |
|||
if (status.value == 'nomore') return; |
|||
status.value = 'loading'; |
|||
proxy.$modal.loading('加载中') |
|||
await inLocationApi.getInLocationPage(params.value).then((res) => { |
|||
proxy.$modal.closeLoading() |
|||
if (res.data.list.length > 0) { |
|||
list.value = list.value.concat(res.data.list); |
|||
params.value.pageNo++; |
|||
status.value = 'loadmore' |
|||
} else { |
|||
status.value = 'nomore' |
|||
} |
|||
}).catch(() => { }) |
|||
} |
|||
onLoad((option) => { |
|||
if (option.type) params.value.type = option.type; |
|||
}) |
|||
onShow(() => { |
|||
params.value.pageNo = 1 |
|||
list.value = [] |
|||
status.value = 'loadmore' |
|||
getList() |
|||
}) |
|||
onReachBottom(() => { |
|||
getList() |
|||
}) |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.container{ |
|||
background: #f5f5f5; |
|||
min-height: 100vh; |
|||
} |
|||
.list { |
|||
background: #f5f5f5; |
|||
margin-top: 20rpx; |
|||
|
|||
.item { |
|||
padding: 30rpx 30rpx 0px 30rpx; |
|||
margin-top: 20rpx; |
|||
background: white; |
|||
position: relative; |
|||
|
|||
.title { |
|||
display: flex; |
|||
align-items: center; |
|||
padding-bottom: 20rpx; |
|||
|
|||
.title-txt { |
|||
color: #409eff; |
|||
font-weight: bold; |
|||
font-size: 36rpx; |
|||
width: 0px; |
|||
flex: 1; |
|||
} |
|||
|
|||
.time { |
|||
color: #919191; |
|||
|
|||
} |
|||
} |
|||
|
|||
.dec { |
|||
padding-bottom: 20rpx; |
|||
|
|||
span { |
|||
color: #999999; |
|||
} |
|||
} |
|||
|
|||
.last { |
|||
padding-bottom: 30rpx; |
|||
} |
|||
|
|||
.bottom { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
border-top: 1px solid #E4E4E4; |
|||
padding: 20rpx 0px; |
|||
height: 90rpx; |
|||
|
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,274 @@ |
|||
<template> |
|||
<view class="index-content"> |
|||
<u-navbar back-icon-color='#fff' back-icon-name='' |
|||
:background="{ background: 'rgba(64, 158,255,'+bgOpacity+')'}" back-text="" title-color='#fff' |
|||
:immersive='true' :border-bottom='false' title="首页"> |
|||
</u-navbar> |
|||
<view class="top"> |
|||
<image src="../static/images/mobile_bg.png" class="bg" mode=""></image> |
|||
<view class="top-box" v-if="getAccessToken()"> |
|||
<view class="info"> |
|||
<image :src="store.avatar" class="cu-avatar" mode="" v-if="store.avatar"></image> |
|||
<view class="cu-avatar" v-else> |
|||
<u-icon name="account-fill" color="#ababab" size="100"></u-icon> |
|||
</view> |
|||
|
|||
<view class="user-info"> |
|||
<view class="name">{{store.name}} |
|||
<!-- <span v-if="store.post">{{store.post.name}}</span> --> |
|||
</view> |
|||
<!-- <view class="tips">{{store.dept.name}}</view> --> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="top-box" v-else> |
|||
<view class="info"> |
|||
<view class="cu-avatar"> |
|||
<u-icon name="account-fill" color="#ababab" size="100"></u-icon> |
|||
</view> |
|||
|
|||
<view class="user-info" @click="handleLogin"> |
|||
<view class="name">点击登录</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="box"> |
|||
<view class="" v-for="(item,index) in meaus" :key='index'> |
|||
<view class="title">{{item.name}}</view> |
|||
<u-row gutter="16" style="padding:0px 20rpx ;"> |
|||
<u-col span="3" v-for="(cur,key) in item.children" :key='key'> |
|||
<view class="icon-item" @click="open(cur.path)"> |
|||
<!-- 扫码图标 --> |
|||
<image src="../static/images/icon8.png" mode="" v-if="cur.componentName == 'scanCodeMeau'"></image> |
|||
<!-- 采购入库图标 --> |
|||
<image src="../static/images/icon1.png" mode="" v-else-if="cur.componentName == 'inLocation'"></image> |
|||
<!-- 备件归还图标 --> |
|||
<image src="../static/images/icon3.png" mode="" v-else-if="cur.componentName == 'sparePartsReturn'"></image> |
|||
<!-- 采购出库图标 --> |
|||
<image src="../static/images/icon2.png" mode="" v-else-if="cur.componentName == 'outLocation'"></image> |
|||
<view>{{cur.name}}</view> |
|||
</view> |
|||
</u-col> |
|||
</u-row> |
|||
|
|||
</view> |
|||
|
|||
|
|||
<!-- <view class=""> |
|||
<view class="title">扫码</view> |
|||
<u-row gutter="16" style="padding:0px 20rpx ;"> |
|||
<u-col span="3"> |
|||
<view class="icon-item" @click="open('/pages/scanCode/scanCode')"> |
|||
<image src="../static/images/icon8.png" mode=""></image> |
|||
<view>扫码</view> |
|||
</view> |
|||
</u-col> |
|||
</u-row> |
|||
</view> --> |
|||
<!-- <view class="" v-if="menus1&&menus1.length>0"> |
|||
<view class="title">采购入库</view> |
|||
<u-row gutter="16" style="padding:0px 20rpx ;"> |
|||
<block v-for="(item,index) in menus1" :key="index"> |
|||
<u-col span="3" v-if="item.path == 'purchaseIn'"> |
|||
<view class="icon-item" @click="open('/pages/inLocation/index')"> |
|||
<image src="../static/images/icon1.png" mode=""></image> |
|||
<view>{{item.name}}</view> |
|||
</view> |
|||
</u-col> |
|||
<u-col span="3" v-else-if="item.path == 'itemIn'"> |
|||
<view class="icon-item" @click="open('/pages/sparePartsReturn/addForm')"> |
|||
<image src="../static/images/icon3.png" mode=""></image> |
|||
<view>{{item.name}}</view> |
|||
</view> |
|||
</u-col> |
|||
</block> |
|||
</u-row> |
|||
</view> |
|||
|
|||
<view class="" v-if="menus2&&menus2.length>0"> |
|||
<view class="title">出库</view> |
|||
<u-row gutter="16"> |
|||
<block v-for="(item,index) in menus2" :key="index"> |
|||
<u-col span="3" v-if="item.path == 'itemOut'"> |
|||
<view class="icon-item" @click="open('/pages/outLocation/index')"> |
|||
<image src="../static/images/icon2.png" mode=""></image> |
|||
<view>{{item.name}}</view> |
|||
</view> |
|||
</u-col> |
|||
</block> |
|||
</u-row> |
|||
</view> --> |
|||
</view> |
|||
<view class="btn" @click="handleLogout" v-if="getAccessToken()">退出登录</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { |
|||
onPageScroll, |
|||
onLoad |
|||
} from '@dcloudio/uni-app' |
|||
import { |
|||
ref, |
|||
getCurrentInstance |
|||
} from 'vue' |
|||
import { |
|||
getAccessToken |
|||
} from '@/utils/auth' |
|||
|
|||
import { useCountStore } from '@/store' |
|||
|
|||
const { proxy } = getCurrentInstance() |
|||
// 获取自定义的store |
|||
const store = useCountStore() |
|||
const bgOpacity = ref(0) |
|||
const meaus = ref([]) |
|||
// const menus2 = ref([]) |
|||
function open(url) { |
|||
if (!getAccessToken()) { |
|||
proxy.$tab.navigateTo('/pages/login') |
|||
return |
|||
} |
|||
proxy.$tab.navigateTo("/" + url) |
|||
} |
|||
function handleLogout() { |
|||
proxy.$modal.confirm('确定注销并退出系统吗?').then(() => { |
|||
store.LogOut().then(() => { |
|||
proxy.$tab.reLaunch('/pages/login') |
|||
}).catch(() => { }) |
|||
}).catch(() => { }) |
|||
} |
|||
function handleLogin() { |
|||
proxy.$tab.navigateTo('/pages/login') |
|||
} |
|||
onLoad(async () => { |
|||
await proxy.$onLaunched; |
|||
// menus1.value = store.menus1 |
|||
// menus2.value = store.menus2 |
|||
meaus.value = store.meaus |
|||
console.log(meaus.value ) |
|||
}) |
|||
onPageScroll((e) => { |
|||
if (e.scrollTop > 0) { |
|||
bgOpacity.value = e.scrollTop / 200; |
|||
} else { |
|||
bgOpacity.value = 0 |
|||
} |
|||
}) |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
.index-content { |
|||
background-color: white; |
|||
min-height: 100vh; |
|||
padding-bottom: 20rpx; |
|||
} |
|||
|
|||
.bg { |
|||
width: 100%; |
|||
} |
|||
|
|||
.top { |
|||
position: relative; |
|||
|
|||
image { |
|||
height: calc(var(--status-bar-height) + 310rpx); |
|||
} |
|||
} |
|||
|
|||
.info { |
|||
position: absolute; |
|||
top: calc(var(--status-bar-height) + 110rpx); |
|||
left: 80rpx; |
|||
right: 80rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
|
|||
.cu-avatar { |
|||
border: 4rpx solid #eaeaea; |
|||
width: 140rpx; |
|||
height: 140rpx; |
|||
border-radius: 50%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
background: white; |
|||
|
|||
|
|||
.icon { |
|||
font-size: 80rpx; |
|||
color: #f5f5f5; |
|||
} |
|||
} |
|||
|
|||
.user-info { |
|||
margin-left: 30rpx; |
|||
flex: 1; |
|||
|
|||
.name { |
|||
line-height: 60rpx; |
|||
font-size: 36rpx; |
|||
font-weight: bold; |
|||
line-height: 60rpx; |
|||
margin-right: 20rpx; |
|||
color: white; |
|||
|
|||
span { |
|||
font-weight: normal; |
|||
font-size: 28rpx; |
|||
padding-left: 20rpx; |
|||
} |
|||
} |
|||
|
|||
.tips { |
|||
padding: 10rpx 20rpx; |
|||
background: #3952ae; |
|||
color: white; |
|||
border-radius: 50rpx; |
|||
font-size: 24rpx; |
|||
display: inline-block; |
|||
|
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
.box { |
|||
.title { |
|||
font-size: 32rpx; |
|||
font-weight: bold; |
|||
padding: 50rpx 50rpx 30rpx; |
|||
} |
|||
|
|||
.icon-item { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
flex-direction: column; |
|||
margin: 20rpx 0px; |
|||
|
|||
image { |
|||
width: 80rpx; |
|||
height: 80rpx; |
|||
} |
|||
|
|||
view { |
|||
margin-top: 20rpx; |
|||
color: #999999; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.btn { |
|||
width: calc(100vw - 60rpx); |
|||
margin: 30rpx auto; |
|||
background-color: rgb(64, 158, 255); |
|||
color: #FFFFFF; |
|||
height: 90rpx; |
|||
line-height: 90rpx; |
|||
text-align: center; |
|||
border-radius: 10rpx; |
|||
font-size: 32rpx; |
|||
} |
|||
</style> |
@ -0,0 +1,232 @@ |
|||
<template> |
|||
<view class="normal-login-container"> |
|||
<view class="logo-img"> |
|||
<u-icon name="close" size="40" class="icon" @click="$tab.reLaunch('/pages/index')"></u-icon> |
|||
<view class="logo-title"> |
|||
<view>智慧设备管理综合系统</view> |
|||
<view>让设备管理更智能、更高效</view> |
|||
</view> |
|||
<image src="../static/images/banner/logo-banner.png" mode="widthFix"></image> |
|||
</view> |
|||
<view class="box"> |
|||
<view class="box-shadow"> |
|||
|
|||
</view> |
|||
<view class="logo-content"> |
|||
<text class="title">您好,欢迎登录</text> |
|||
</view> |
|||
<view class="login-form-content"> |
|||
<view class="input-item-label">登录账号</view> |
|||
<view class="input-item flex align-center"> |
|||
<input v-model="loginForm.username" class="input" type="text" placeholder="请输入账号" maxlength="30" |
|||
style="height: 100%;" /> |
|||
</view> |
|||
<view class="input-item-label">登录密码</view> |
|||
<view class="input-item flex align-center"> |
|||
<input v-model="loginForm.password" type="password" class="input" placeholder="请输入密码" maxlength="20" |
|||
style="height: 100%;" /> |
|||
</view> |
|||
<view class="action-btn"> |
|||
<button @click="handleLogin" class="login-btn cu-btn block bg-blue lg ">登录</button> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="xieyi text-center"> |
|||
<text class="text-grey1">登录即代表同意</text> |
|||
<text @click="handleUserAgrement" class="text-blue">《用户协议》</text> |
|||
<text @click="handlePrivacy" class="text-blue">《隐私协议》</text> |
|||
</view> |
|||
|
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import * as loginApi from "@/api/login" |
|||
import { |
|||
ref, |
|||
getCurrentInstance |
|||
} from 'vue' |
|||
const { proxy } = getCurrentInstance() |
|||
let loginForm = ref({ |
|||
tenantName: "闻荫源码", |
|||
username: "", |
|||
password: "", |
|||
captchaVerification: "", |
|||
rememberMe: false, |
|||
code: '1', |
|||
uuid: "APP" |
|||
}) |
|||
|
|||
import { storeToRefs } from 'pinia' |
|||
import { useCountStore } from '@/store' |
|||
|
|||
// 获取自定义的store |
|||
const store = useCountStore() |
|||
if( import.meta.env.VITE_USER_NODE_ENV == 'development'){ |
|||
loginForm.value = { |
|||
tenantName: "闻荫源码", |
|||
username: "admin", |
|||
password: "123456", |
|||
captchaVerification: "", |
|||
rememberMe: false, |
|||
code: '1', |
|||
uuid: "APP", |
|||
cid:uni.getStorageSync('cid') |
|||
} |
|||
} |
|||
async function handleLogin(params) { |
|||
if (loginForm.value.username === "") { |
|||
proxy.$modal.msgError("请输入您的账号") |
|||
} else if (loginForm.value.password === "") { |
|||
proxy.$modal.msgError("请输入您的密码") |
|||
} else { |
|||
await pwdLogin() |
|||
} |
|||
} |
|||
async function pwdLogin() { |
|||
proxy.$modal.loading("登录中,请耐心等待...") |
|||
// 执行登录 |
|||
store.Login(loginForm.value).then(async (res) => { |
|||
proxy.$modal.closeLoading() |
|||
await loginSuccess() |
|||
}).catch(() => { }) |
|||
} |
|||
// 登录成功后,处理函数 |
|||
async function loginSuccess(result) { |
|||
await store.GetPermissionInfo().then(res => { |
|||
}).catch(() => {}) |
|||
await store.GetInfo().then(res => { |
|||
proxy.$tab.reLaunch('/pages/index') |
|||
}).catch(() => {}) |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
page { |
|||
background-color: #ffffff; |
|||
} |
|||
|
|||
.normal-login-container { |
|||
width: 100%; |
|||
|
|||
.logo-content { |
|||
width: 100%; |
|||
font-size: 40rpx; |
|||
padding: 50rpx 80rpx 0rpx; |
|||
|
|||
.title { |
|||
font-weight: bold; |
|||
color: #000000; |
|||
|
|||
} |
|||
} |
|||
|
|||
.box { |
|||
position: relative; |
|||
} |
|||
|
|||
.box-shadow { |
|||
box-shadow: 0px -10rpx 16rpx rgba(64, 158, 254, 0.5); |
|||
width: 100%; |
|||
position: absolute; |
|||
height: 30rpx; |
|||
border-radius: 30rpx 30rpx 0px 0px; |
|||
} |
|||
|
|||
.logo-img { |
|||
background-color: #fafcff; |
|||
height: calc(var(--status-bar-height) + 400rpx); |
|||
position: relative; |
|||
|
|||
.icon { |
|||
position: absolute; |
|||
top: calc(var(--status-bar-height) + 20rpx); |
|||
left: 40rpx; |
|||
} |
|||
|
|||
.logo-title { |
|||
position: absolute; |
|||
left: 50rpx; |
|||
top: calc(var(--status-bar-height) + 80rpx); |
|||
z-index: 11; |
|||
|
|||
view { |
|||
&:nth-child(1) { |
|||
color: #409eff; |
|||
font-weight: bold; |
|||
font-size: 36rpx; |
|||
} |
|||
|
|||
&:nth-child(2) { |
|||
color: #999999; |
|||
font-size: 24rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
image { |
|||
width: 75%; |
|||
display: block; |
|||
position: absolute; |
|||
bottom: 0px; |
|||
right: 0px; |
|||
} |
|||
} |
|||
|
|||
.login-form-content { |
|||
margin: 40rpx auto; |
|||
width: 80%; |
|||
|
|||
.input-item-label { |
|||
font-size: 30rpx; |
|||
// font-weight: bold; |
|||
color: #888888; |
|||
} |
|||
|
|||
.input-item { |
|||
margin: 20rpx auto 40rpx; |
|||
border: 1px solid #E4E4E4; |
|||
padding: 0px 20rpx; |
|||
height: 90rpx; |
|||
|
|||
.icon { |
|||
font-size: 38rpx; |
|||
margin-left: 20rpx; |
|||
color: #999; |
|||
} |
|||
|
|||
.input { |
|||
width: 100%; |
|||
font-size: 28rpx; |
|||
line-height: 40rpx; |
|||
text-align: left; |
|||
} |
|||
|
|||
} |
|||
|
|||
.login-btn { |
|||
margin-top: 80rpx; |
|||
height: 80rpx; |
|||
background: #409eff; |
|||
color: white; |
|||
} |
|||
|
|||
} |
|||
|
|||
.xieyi { |
|||
color: #333; |
|||
margin-top: 40rpx; |
|||
font-size: 24rpx; |
|||
} |
|||
|
|||
.easyinput { |
|||
width: 100%; |
|||
} |
|||
} |
|||
|
|||
.login-code-img { |
|||
height: 90rpx; |
|||
} |
|||
</style> |
@ -0,0 +1,531 @@ |
|||
<template> |
|||
<!-- 添加维修工单 --> |
|||
<view class="add-form-container"> |
|||
<u-form :model="form" ref="formRef" label-width="160rpx"> |
|||
<u-form-item label="申请人" prop="applyName" required class='disabled'> |
|||
<u-input v-model="form.applyName" placeholder="请输入申请人" disabled /> |
|||
</u-form-item> |
|||
<u-form-item label="申请部门" prop="applyDeptName" required class='disabled'> |
|||
<u-input v-model="form.applyDeptName" placeholder="请输入申请部门" disabled /> |
|||
</u-form-item> |
|||
<u-form-item label="审批人" prop="approveName" required class='disabled'> |
|||
<u-input v-model="form.approveName" placeholder="请输入审批人" disabled /> |
|||
</u-form-item> |
|||
</u-form> |
|||
<view class="list"> |
|||
<view class="title"> |
|||
<span>*</span>申领信息 |
|||
</view> |
|||
<view class="item " v-for="(item,index) in form.subList" :key="index"> |
|||
<view class="item-box"> |
|||
<view class="spare-title"> |
|||
<view class="title-txt"> |
|||
备件名称:{{item.itemName}} |
|||
</view> |
|||
</view> |
|||
<u-row gutter="16"> |
|||
<!-- <u-col :span="24"> |
|||
<view class="dec"> |
|||
库位:{{item.locationNumber}} |
|||
</view> |
|||
</u-col> --> |
|||
|
|||
<u-col :span="24"> |
|||
<view class="dec"> |
|||
已出库数量:{{item.receiveQty}} |
|||
</view> |
|||
</u-col> |
|||
<u-col :span="24"> |
|||
<view class="dec"> |
|||
申请数量:{{item.qty}} |
|||
</view> |
|||
</u-col> |
|||
</u-row> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="list"> |
|||
<view class="title"> |
|||
<span>*</span>出库信息 |
|||
</view> |
|||
<view class="item " v-for="(item,index) in form.itemNumbers" :key="index"> |
|||
<view class="item-box"> |
|||
<view class="spare-title"> |
|||
<view class="title-txt"> |
|||
备件名称:{{item.itemName}} |
|||
</view> |
|||
</view> |
|||
<u-row gutter="16"> |
|||
<u-col :span="24"> |
|||
<view class="dec"> |
|||
出库数量:{{item.qty}} |
|||
</view> |
|||
</u-col> |
|||
<u-col :span="24"> |
|||
<view class="dec"> |
|||
申请数量:{{item.applyQty}} |
|||
</view> |
|||
</u-col> |
|||
<u-col :span="24"> |
|||
<view class="dec"> |
|||
库位编码:{{item.locationNumber}} |
|||
</view> |
|||
</u-col> |
|||
<!-- <u-col :span="24"> |
|||
<view class="dec"> |
|||
库位名称:{{item.locationName}} |
|||
</view> |
|||
</u-col> --> |
|||
<u-col :span="24"> |
|||
<view class="dec"> |
|||
库位类型:{{item.isInAccount == 'FALSE'?'帐外库' :'帐内库'}} |
|||
</view> |
|||
</u-col> |
|||
</u-row> |
|||
</view> |
|||
<u-icon name="minus-circle" color="#aaaaaa" size="60" @click="delSpareParts(item,index)"></u-icon> |
|||
</view> |
|||
<view class="add-btn"> |
|||
<u-button type="primary" @click="open"><u-icon name="plus-circle" color="#ffffff" |
|||
size="36"></u-icon>添加备件</u-button> |
|||
</view> |
|||
</view> |
|||
<view class="footer"> |
|||
<view class="btns"> |
|||
<button class="reset" @click="reset">重置</button> |
|||
<button class="sure" @click="submit" :loading='loading' :disabled='loading'>确定</button> |
|||
</view> |
|||
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view> |
|||
</view> |
|||
<!-- 添加备件 --> |
|||
<u-popup v-model="isPopupShow" mode="center" border-radius="14"> |
|||
<view class="popup-title">添加备件</view> |
|||
<scroll-view scroll-y="true" style="max-height:60vh;"> |
|||
<view class="popup"> |
|||
<u-form :model="form1" ref="form1Ref" label-width="180rpx"> |
|||
<u-form-item label="库位" prop="locationNumber" required> |
|||
<u-input v-model="form1.locationNumber" placeholder="请输入库位" @blur="blur()" |
|||
@confirm="handelScanMsg" :focus='isFocus' /> |
|||
|
|||
</u-form-item> |
|||
<u-form-item :label="`备件名称`" prop="itemNumber" required class="disabled"> |
|||
<view class="select"> |
|||
<u-input v-model="form1.itemName" placeholder="请选择备件" disabled /> |
|||
</view> |
|||
</u-form-item> |
|||
<u-form-item label="申请数量" prop="applyQty" required class="disabled"> |
|||
<u-input v-model="form1.applyQty" type="number" disabled placeholder="请输入申请数量" /> |
|||
</u-form-item> |
|||
<u-form-item label="已出库数量" prop="receiveQty" required class="disabled"> |
|||
<u-input v-model="form1.receiveQty" type="number" disabled placeholder="请输入已出库数量" /> |
|||
</u-form-item> |
|||
<u-form-item label="库存数量" prop="stockQty" required class="disabled"> |
|||
<u-input v-model="form1.stockQty" type="number" disabled placeholder="请输入库存数量" /> |
|||
</u-form-item> |
|||
<u-form-item label="剩余出库数量" prop="totalReception" required class="disabled"> |
|||
<u-input v-model="form1.totalReception" type="number" disabled placeholder="请输入出库数量" /> |
|||
</u-form-item> |
|||
<u-form-item label="出库数量" prop="qty" required> |
|||
<u-input v-model="form1.qty" type="number" placeholder="请输入出库数量" /> |
|||
</u-form-item> |
|||
<u-form-item label="描述" prop="describes"> |
|||
<u-input v-model="form1.describes" placeholder="请输入描述" /> |
|||
</u-form-item> |
|||
</u-form> |
|||
</view> |
|||
</scroll-view> |
|||
<view class="popup-footer"> |
|||
<view @click="isPopupShow = false">取消</view> |
|||
<view class="sure" @click="addSpare">确认</view> |
|||
</view> |
|||
</u-popup> |
|||
</view> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { |
|||
onLoad |
|||
} from '@dcloudio/uni-app' |
|||
import { |
|||
ref, |
|||
getCurrentInstance |
|||
} from 'vue' |
|||
import * as outLocationApi from "@/api/outLocation" |
|||
import * as locationApi from "@/api/location" |
|||
const { proxy } = getCurrentInstance() |
|||
|
|||
const loading = ref(false) |
|||
const orderList = ref([])//订单信息 |
|||
// 备件弹窗 |
|||
const isPopupShow = ref(false) |
|||
const form = ref({ |
|||
id: '', |
|||
number: '', |
|||
supplierName: '', |
|||
itemNumbers: [], |
|||
subList: [] |
|||
}) |
|||
const form1 = ref({ |
|||
itemNumber: "", |
|||
itemName: '', |
|||
locationNumber: '', |
|||
applyQty: '', |
|||
receiveQty: '', |
|||
stockQty: '', |
|||
totalReception:'', |
|||
qty: '' |
|||
}) |
|||
const isShow = ref(false) |
|||
const isInAccount = ref('FALSE') |
|||
|
|||
const isFocus = ref(false) |
|||
const msg = ref('') |
|||
// 触发提交表单 |
|||
function submit() { |
|||
if (form.value.itemNumbers.length === 0) { |
|||
proxy.$modal.showToast('请添加出库信息') |
|||
return; |
|||
} |
|||
proxy.$modal.confirm('是否添加出库信息').then(() => { |
|||
proxy.$modal.loading('加载中') |
|||
loading.value = true |
|||
outLocationApi.outLocationCreat(form.value).then((res) => { |
|||
proxy.$modal.closeLoading() |
|||
if (res.data) { |
|||
proxy.$modal.showToast('添加成功') |
|||
setTimeout(() => { |
|||
proxy.$tab.navigateBack() |
|||
loading.value = false |
|||
}, 1500) |
|||
} else { |
|||
proxy.$modal.showToast('添加失败') |
|||
loading.value = false |
|||
} |
|||
}).catch(() => { |
|||
proxy.$modal.closeLoading() |
|||
loading.value = false |
|||
}) |
|||
}) |
|||
|
|||
} |
|||
// 重置 |
|||
function reset() { |
|||
form.value.itemNumbers = [] |
|||
} |
|||
// 获取订单信息详情 |
|||
async function getInLocationDetail() { |
|||
// let itemNumbers = form.value.itemNumbers.map(item=>{ |
|||
// return { |
|||
// itemNumber:item.itemNumber, |
|||
// qty:item.qty, |
|||
// locationNumber:item.locationNumber, |
|||
// } |
|||
// }) |
|||
await outLocationApi.getOutLocationDetail({ |
|||
id: form.value.id, |
|||
number: form.value.number, |
|||
// itemNumbers:itemNumbers || [] |
|||
}).then(res => { |
|||
form.value.applyName = res.data.applyName |
|||
form.value.approveName = res.data.approveName |
|||
form.value.applyDeptName = res.data.applyDeptName |
|||
form.value.subList = res.data.subList |
|||
}).catch(() => { }) |
|||
} |
|||
// 打开弹窗 |
|||
function open() { |
|||
form1.value = { |
|||
itemNumber: "", |
|||
itemName: '', |
|||
locationNumber: '', |
|||
applyQty: '', |
|||
receiveQty: '', |
|||
stockQty: '', |
|||
qty: '' |
|||
} |
|||
isPopupShow.value = true |
|||
isShow.value = false |
|||
isFocus.value = true |
|||
} |
|||
// 添加备件 |
|||
function addSpare() { |
|||
// 校验 |
|||
if (!form1.value.locationNumber) { |
|||
proxy.$modal.showToast('请选择库位') |
|||
return; |
|||
} |
|||
if (!form1.value.itemNumber) { |
|||
proxy.$modal.showToast(msg.value) |
|||
return; |
|||
} |
|||
|
|||
if (!form1.value.qty) { |
|||
proxy.$modal.showToast(`请输入数量`) |
|||
return; |
|||
} |
|||
if (Number(form1.value.qty) + Number(form1.value.receiveQty) > Number(form1.value.applyQty)) { |
|||
proxy.$modal.showToast('已出库数量和出库数量不可大于申请数量') |
|||
return; |
|||
} |
|||
if (Number(form1.value.qty) > Number(form1.value.totalReception)) { |
|||
proxy.$modal.showToast('出库数量不可大于剩余出库数量') |
|||
return; |
|||
} |
|||
if (form.value.itemNumbers && form.value.itemNumbers.length > 0) { |
|||
let arr = form.value.itemNumbers.filter(item => item.locationNumber == form1.value.locationNumber) |
|||
if (arr && arr.length > 0) { |
|||
proxy.$modal.showToast('该库位已添加') |
|||
return; |
|||
} |
|||
let arr1 = form.value.subList.filter(item => item.itemNumber == form1.value.itemNumber) |
|||
if (!arr1 || (arr1 && arr1.length == 0)) { |
|||
proxy.$modal.showToast('申领信息没有该备件') |
|||
return; |
|||
} |
|||
} |
|||
form.value.itemNumbers.push(form1.value) |
|||
isPopupShow.value = false |
|||
} |
|||
// 删除备件 |
|||
function delSpareParts(item,index) { |
|||
let bol = form.value.itemNumbers.some(cur=>cur.itemNumber == item.itemNumber&&item.isInAccount == 'FALSE'&&cur.isInAccount == 'TRUE') |
|||
if(bol){ |
|||
proxy.$modal.showToast('请先删除该备件得帐内库') |
|||
return; |
|||
} |
|||
form.value.itemNumbers.splice(index, 1) |
|||
} |
|||
function getLocation() { |
|||
let itemNumbers = form.value.itemNumbers.map(item=>{ |
|||
return { |
|||
itemNumber:item.itemNumber, |
|||
qty:item.qty, |
|||
locationNumber:item.locationNumber, |
|||
} |
|||
}) |
|||
locationApi.getOutLocation({ |
|||
number: form1.value.locationNumber, |
|||
id: form.value.id, |
|||
itemNumbers:itemNumbers |
|||
}).then(res => { |
|||
if (!res.data) { |
|||
msg.value = res.msg |
|||
form1.value.areaNumber = ''; |
|||
form1.value.itemName = ''; |
|||
form1.value.itemNumber = ''; |
|||
form1.value.receiveQty =''; |
|||
form1.value.applyQty =''; |
|||
form1.value.stockQty = ''; |
|||
form1.value.totalReception =''; |
|||
form1.value.isInAccount =''; |
|||
isInAccount.value =''; |
|||
return; |
|||
} |
|||
form1.value.areaNumber = res.data.areaNumber; |
|||
form1.value.itemName = res.data.itemName; |
|||
form1.value.itemNumber = res.data.itemNumber; |
|||
form1.value.receiveQty = res.data.receiveQty || 0; |
|||
form1.value.applyQty = res.data.applyQty || 0; |
|||
form1.value.stockQty = res.data.qty || 0; |
|||
form1.value.totalReception = res.data.totalReception || 0; |
|||
form1.value.isInAccount = res.data.isInAccount; |
|||
isInAccount.value = res.data.isInAccount || '' |
|||
|
|||
// this.itemNumber = res.data.itemNumber || '' |
|||
}).catch((error) => { |
|||
msg.value = error.msg |
|||
form1.value.areaNumber = ''; |
|||
form1.value.itemName = ''; |
|||
form1.value.itemNumber = ''; |
|||
form1.value.receiveQty = ''; |
|||
form1.value.applyQty = ''; |
|||
form1.value.stockQty = ''; |
|||
isInAccount.value = ''; |
|||
}) |
|||
} |
|||
function blur() { |
|||
if (form1.value.locationNumber) { |
|||
getLocation() |
|||
} |
|||
} |
|||
function handelScanMsg() { |
|||
getLocation() |
|||
} |
|||
onLoad(async (option) => { |
|||
if (option.data && JSON.parse(decodeURIComponent(option.data)) && JSON.parse(decodeURIComponent(option |
|||
.data)).id) { |
|||
let formData = JSON.parse(decodeURIComponent(option.data)) |
|||
form.value.supplierName = formData.supplierName |
|||
form.value.number = formData.number |
|||
form.value.id = formData.id |
|||
} |
|||
await getInLocationDetail() |
|||
}) |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.add-form-container { |
|||
min-height: calc(100vh - 140rpx); |
|||
background: white; |
|||
padding: 0px 0rpx 140rpx; |
|||
} |
|||
|
|||
.u-form-item { |
|||
padding: 20rpx 30rpx; |
|||
} |
|||
|
|||
.disabled { |
|||
background: #f5f5f5; |
|||
} |
|||
|
|||
.footer { |
|||
position: fixed; |
|||
bottom: 0px; |
|||
left: 0px; |
|||
width: 100%; |
|||
z-index: 22; |
|||
} |
|||
|
|||
.btns { |
|||
display: flex; |
|||
|
|||
|
|||
button { |
|||
flex: 1; |
|||
} |
|||
|
|||
.sure { |
|||
background: #409eff; |
|||
color: white; |
|||
border-radius: 0px; |
|||
|
|||
&::after { |
|||
border: 1px solid #409eff; |
|||
border-radius: 0px; |
|||
} |
|||
} |
|||
|
|||
.reset { |
|||
background: #F5F5F5; |
|||
border-radius: 0px; |
|||
|
|||
&::after { |
|||
border-radius: 0px; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.right-button { |
|||
background: #409eff; |
|||
color: white; |
|||
padding: 0rpx 30rpx; |
|||
border-radius: 16rpx; |
|||
text-align: center; |
|||
font-size: 28rpx; |
|||
} |
|||
|
|||
.select { |
|||
display: flex; |
|||
align-items: center; |
|||
height: 72rpx; |
|||
width: 100%; |
|||
|
|||
.input { |
|||
flex: 1; |
|||
font-size: 28rpx; |
|||
color: #000000; |
|||
} |
|||
|
|||
.placeholder { |
|||
flex: 1; |
|||
font-size: 28rpx; |
|||
color: rgb(192, 196, 204); |
|||
|
|||
} |
|||
} |
|||
|
|||
.title { |
|||
padding: 32rpx 0rpx; |
|||
position: relative; |
|||
|
|||
span { |
|||
position: absolute; |
|||
left: -16rpx; |
|||
color: #fa3534; |
|||
top: 19px; |
|||
} |
|||
} |
|||
|
|||
.list { |
|||
padding: 0rpx 30rpx; |
|||
|
|||
.item { |
|||
display: flex; |
|||
margin-bottom: 20rpx; |
|||
|
|||
.item-box { |
|||
background: #F5F5F5; |
|||
border-radius: 12rpx; |
|||
flex: 1; |
|||
width: 0rpx; |
|||
} |
|||
|
|||
.spare-title { |
|||
padding: 20rpx 30rpx; |
|||
border-bottom: 1px solid #e4e4e4; |
|||
|
|||
.title-txt { |
|||
color: #409eff; |
|||
font-size: 30rpx; |
|||
font-weight: bold; |
|||
} |
|||
} |
|||
|
|||
.dec { |
|||
color: #9c9c9c; |
|||
padding: 20rpx 30rpx 20rpx; |
|||
} |
|||
|
|||
} |
|||
} |
|||
|
|||
.add-btn { |
|||
display: flex; |
|||
justify-content: flex-start; |
|||
align-items: center; |
|||
} |
|||
|
|||
.popup-title { |
|||
text-align: center; |
|||
font-size: 32rpx; |
|||
font-weight: bold; |
|||
color: #409eff; |
|||
padding: 30rpx 30rpx 0px |
|||
} |
|||
|
|||
.popup { |
|||
width: 600rpx; |
|||
padding: 30rpx 0rpx 30rpx; |
|||
|
|||
} |
|||
|
|||
.popup-footer { |
|||
display: flex; |
|||
border-top: 1px solid #e4e4e4; |
|||
|
|||
view { |
|||
line-height: 100rpx; |
|||
flex: 1; |
|||
text-align: center; |
|||
|
|||
&.sure { |
|||
color: #409eff; |
|||
} |
|||
} |
|||
} |
|||
|
|||
::v-deep .u-checkbox-group { |
|||
display: grid !important; |
|||
} |
|||
</style> |
@ -0,0 +1,166 @@ |
|||
<template> |
|||
<!-- 领用入库 --> |
|||
<view class="container"> |
|||
<!-- <u-navbar back-icon-color='#fff' :background="{ background: '#409eff'}" back-text="" title-color='#fff' |
|||
title="领用入库"> |
|||
</u-navbar> --> |
|||
<!-- <Search @search='search' @screen='screen' /> --> |
|||
<view class="list"> |
|||
<view class="item" v-for="(item,index) in list" :key="index" @click="openDetail(item)"> |
|||
<view class="title"> |
|||
<view class="title-txt"> |
|||
{{item.number}} |
|||
</view> |
|||
<!-- <view class="time"> |
|||
{{`${$time.formatDate(item.createTime)}`}} |
|||
</view> --> |
|||
</view> |
|||
<view class="dec"> |
|||
申请人:<span>{{item.applyName}}</span> |
|||
</view> |
|||
<view class="dec"> |
|||
申请时间:<span>{{`${$time.formatDate(item.createTime)}`}}</span> |
|||
</view> |
|||
<view class="dec"> |
|||
申请部门:<span>{{item.applyDeptName}}</span> |
|||
</view> |
|||
<view class="dec"> |
|||
审批人:<span>{{item.approveName}}</span> |
|||
</view> |
|||
<view class="dec"> |
|||
审批时间:<span>{{`${$time.formatDate(item.approveTime)}`}}</span> |
|||
</view> |
|||
<view class="bottom"> |
|||
<view class="status"> |
|||
<u-tag text="待审批" v-if="item.status==0" bg-color='rgba(255,255,255,0)' color='#fe8463' |
|||
border-color='#fe8463' type="primary" shape='circle' /> |
|||
<u-tag text="审批通过" v-else-if="item.status==1" bg-color='rgba(255,255,255,0)' color='#2EC7C9' |
|||
border-color='#2EC7C9' type="info" shape='circle' /> |
|||
<u-tag text="审批驳回" v-else-if="item.status==2" bg-color='rgba(255,255,255,0)' color='#e01f54' |
|||
border-color='#e01f54' type="success" shape='circle' /> |
|||
<u-tag text="出库中" v-else-if="item.status==3" bg-color='rgba(255,255,255,0)' color='#005eaa' |
|||
border-color='#005eaa ' type="error" shape='circle' /> |
|||
<u-tag text="完成" v-else-if="item.status==4" bg-color='rgba(255,255,255,0)' color='#2ba471' |
|||
border-color='#2ba471' type="info" shape='circle' /> |
|||
<u-tag text="撤单" v-else-if="item.status==5" bg-color='rgba(255,255,255,0)' color='#d7d7d7' |
|||
border-color='#d7d7d7 ' type="warning" shape='circle' /> |
|||
</view> |
|||
|
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { |
|||
onLoad, |
|||
onShow, |
|||
onReachBottom |
|||
} from '@dcloudio/uni-app' |
|||
import { |
|||
ref, |
|||
getCurrentInstance |
|||
} from 'vue' |
|||
import * as outLocationApi from "@/api/outLocation" |
|||
import auth from '@/plugins/auth' |
|||
const { proxy } = getCurrentInstance() |
|||
const params = ref({ |
|||
pageNo: 1, |
|||
pageSize: 10, |
|||
}) |
|||
const status = ref('loadmore') //是否显示没有更多了 |
|||
const list = ref([]) |
|||
|
|||
function openDetail(item){ |
|||
if(!proxy.$auth.hasPermiOr(['eam:item-apply-record-main:outOperation']))return; |
|||
proxy.$tab.navigateTo(`/pages/outLocation/addForm?data=${encodeURIComponent(JSON.stringify(item))}`) |
|||
} |
|||
async function getList() { |
|||
if (status.value == 'nomore') return; |
|||
status.value = 'loading'; |
|||
proxy.$modal.loading('加载中') |
|||
await outLocationApi.getOutLocationPage(params.value).then((res) => { |
|||
proxy.$modal.closeLoading() |
|||
if (res.data.list.length > 0) { |
|||
list.value = list.value.concat(res.data.list); |
|||
params.value.pageNo++; |
|||
status.value = 'loadmore' |
|||
} else { |
|||
status.value = 'nomore' |
|||
} |
|||
}).catch(() => { }) |
|||
} |
|||
onLoad((option) => { |
|||
if (option.type) params.value.type = option.type; |
|||
}) |
|||
onShow(() => { |
|||
params.value.pageNo = 1 |
|||
list.value = [] |
|||
status.value = 'loadmore' |
|||
getList() |
|||
}) |
|||
onReachBottom(() => { |
|||
getList() |
|||
}) |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.container{ |
|||
background: #f5f5f5; |
|||
min-height: 100vh; |
|||
} |
|||
.list { |
|||
background: #f5f5f5; |
|||
margin-top: 20rpx; |
|||
|
|||
.item { |
|||
padding: 30rpx 30rpx 0px 30rpx; |
|||
margin-top: 20rpx; |
|||
background: white; |
|||
position: relative; |
|||
|
|||
.title { |
|||
display: flex; |
|||
align-items: center; |
|||
padding-bottom: 20rpx; |
|||
|
|||
.title-txt { |
|||
color: #409eff; |
|||
font-weight: bold; |
|||
font-size: 36rpx; |
|||
width: 0px; |
|||
flex: 1; |
|||
} |
|||
|
|||
.time { |
|||
color: #919191; |
|||
|
|||
} |
|||
} |
|||
|
|||
.dec { |
|||
padding-bottom: 20rpx; |
|||
|
|||
span { |
|||
color: #999999; |
|||
} |
|||
} |
|||
|
|||
.last { |
|||
padding-bottom: 30rpx; |
|||
} |
|||
|
|||
.bottom { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
border-top: 1px solid #E4E4E4; |
|||
padding: 20rpx 0px; |
|||
height: 90rpx; |
|||
|
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,188 @@ |
|||
<template> |
|||
<!-- 添加维修工单 --> |
|||
<view class="add-form-container"> |
|||
<view class="screen-input"> |
|||
<u-search v-model='number' :show-action='false' :bg-color="'white'" :border-color="'#E4E4E4'" |
|||
:shape="'square'" :height="80" :placeholder="'请扫描设备或者库位'" :clearabled="true" @blur="blur()" |
|||
@confirm="handelScanMsg"> |
|||
</u-search> |
|||
</view> |
|||
<view class="title"> |
|||
<view class=""> |
|||
详细信息 |
|||
</view> |
|||
</view> |
|||
<view class="list"> |
|||
<view class="item " v-for="(item,index) in list" :key="index"> |
|||
<view class="item-box"> |
|||
<view class="spare-title"> |
|||
<view class="title-txt"> |
|||
库位名称:{{item.name}} |
|||
</view> |
|||
</view> |
|||
<view class="dec"> |
|||
<view>库位编码:</view> |
|||
<view>{{item.locationNumber}}</view> |
|||
</view> |
|||
<view class="dec"> |
|||
<view>库位名称:</view> |
|||
<view>{{item.name}}</view> |
|||
</view> |
|||
<view class="dec"> |
|||
<view>库区编码:</view> |
|||
<view>{{item.areaNumber}}</view> |
|||
</view> |
|||
<view class="dec"> |
|||
<view>库区名称:</view> |
|||
<view>{{item.areaName}}</view> |
|||
</view> |
|||
|
|||
<view class="dec"> |
|||
<view>库位类型:</view> |
|||
<view>{{item.isInAccount == 'TRUE'?'帐内库' :'帐外库'}}</view> |
|||
</view> |
|||
<view class="dec"> |
|||
<view>设备编码:</view> |
|||
<view>{{item.itemNumber}}</view> |
|||
</view> |
|||
<view class="dec"> |
|||
<view>设备名称:</view> |
|||
<view>{{item.itemName}}</view> |
|||
</view> |
|||
<view class="dec"> |
|||
<view>库存:</view> |
|||
<view>{{item.qty}}</view> |
|||
</view> |
|||
|
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
|
|||
</view> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { |
|||
onLoad |
|||
} from '@dcloudio/uni-app' |
|||
import { |
|||
ref, |
|||
getCurrentInstance |
|||
} from 'vue' |
|||
import * as locationApi from "@/api/location" |
|||
const { proxy } = getCurrentInstance() |
|||
const number = ref('LN0000000001') |
|||
const list = ref([]) |
|||
function getPdaItemAndLocation() { |
|||
locationApi.pdaItemAndLocation(number.value).then((res) => { |
|||
if(!res.data||res.data.length==0){ |
|||
list.value = [] |
|||
if(res.msg){ |
|||
proxy.$modal.showToast(res.msg) |
|||
} |
|||
return; |
|||
} |
|||
list.value = res.data |
|||
}).catch((err)=>{ |
|||
list.value = [] |
|||
proxy.$modal.showToast(err.msg) |
|||
}) |
|||
} |
|||
function blur() { |
|||
if (number.value) { |
|||
getPdaItemAndLocation() |
|||
} |
|||
} |
|||
// 扫描设备条码 |
|||
function handelScanMsg() { |
|||
getPdaItemAndLocation() |
|||
} |
|||
onLoad(async (option) => { |
|||
getPdaItemAndLocation() |
|||
|
|||
}) |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.add-form-container { |
|||
min-height: 100vh; |
|||
background: white; |
|||
} |
|||
|
|||
.u-form-item { |
|||
padding: 20rpx 30rpx; |
|||
} |
|||
|
|||
.screen-input { |
|||
margin: 30rpx; |
|||
} |
|||
|
|||
.title { |
|||
display: flex; |
|||
align-items: center; |
|||
padding: 0px 30rpx; |
|||
// background: #f5f5f5; |
|||
margin-top: 10px; |
|||
font-weight: bold; |
|||
font-size: 32rpx; |
|||
|
|||
view { |
|||
&:nth-child(1) { |
|||
flex: 1; |
|||
border-left: 10rpx solid #409eff; |
|||
padding-left: 20rpx; |
|||
font-weight: bold; |
|||
color: #409eff; |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
.list { |
|||
padding: 30rpx; |
|||
|
|||
.item { |
|||
display: flex; |
|||
margin-bottom: 20rpx; |
|||
|
|||
.item-box { |
|||
background: #F5F5F5; |
|||
border-radius: 12rpx; |
|||
flex: 1; |
|||
width: 0rpx; |
|||
} |
|||
|
|||
.spare-title { |
|||
padding: 20rpx 30rpx; |
|||
border-bottom: 1px solid #e4e4e4; |
|||
|
|||
.title-txt { |
|||
color: #409eff; |
|||
font-size: 30rpx; |
|||
font-weight: bold; |
|||
} |
|||
} |
|||
|
|||
.dec { |
|||
color: #9c9c9c; |
|||
padding: 20rpx 30rpx 20rpx; |
|||
display: flex; |
|||
|
|||
view { |
|||
&:nth-child(1) { |
|||
width: 150rpx; |
|||
} |
|||
|
|||
&:nth-child(2) { |
|||
flex: 1; |
|||
word-wrap: break-word; |
|||
width: 0px; |
|||
} |
|||
|
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,530 @@ |
|||
<template> |
|||
<!-- 添加维修工单 --> |
|||
<view class="add-form-container"> |
|||
<u-form :model="form" ref="formRef" label-width="160rpx"> |
|||
<!-- <u-form-item label="入库原因" prop="res" required> |
|||
<u-input v-model="form.number" placeholder="请输入入库原因" /> |
|||
</u-form-item> --> |
|||
|
|||
<u-form-item label="归还人员" prop="reverterName" required> |
|||
<view class="select" @click="openSingleColumn('reverterId',form.reverterId,reverterUser)"> |
|||
<view class="input" v-if='form.reverterId'> |
|||
{{selectFormat(form.reverterId,reverterUser)}} |
|||
</view> |
|||
<view class="placeholder" v-else> |
|||
{{`请选择归还人员`}} |
|||
</view> |
|||
<u-icon name="arrow-right" color="#aaaaaa" size="28"></u-icon> |
|||
</view> |
|||
</u-form-item> |
|||
</u-form> |
|||
<view class="list"> |
|||
<view class="title"> |
|||
<span>*</span>归还备件 |
|||
</view> |
|||
<view class="item " v-for="(item,index) in form.itemNumbers" :key="index"> |
|||
<view class="item-box"> |
|||
<view class="spare-title"> |
|||
<view class="title-txt"> |
|||
备件名称:{{item.itemName}} |
|||
</view> |
|||
</view> |
|||
<u-row gutter="16"> |
|||
<u-col :span="24"> |
|||
<view class="dec"> |
|||
数量:{{item.qty}} |
|||
</view> |
|||
</u-col> |
|||
</u-row> |
|||
</view> |
|||
<u-icon name="minus-circle" color="#aaaaaa" size="60" @click="delSpareParts(index)"></u-icon> |
|||
</view> |
|||
<view class="add-btn"> |
|||
<u-button type="primary" @click="open"><u-icon name="plus-circle" color="#ffffff" |
|||
size="36"></u-icon>添加备件</u-button> |
|||
</view> |
|||
</view> |
|||
<view class="footer"> |
|||
<view class="btns"> |
|||
<button class="reset" @click="reset">重置</button> |
|||
<button class="sure" @click="submit" :loading='loading' :disabled='loading'>确定</button> |
|||
</view> |
|||
<view style="height: constant(safe-area-inset-bottom); height: env(safe-area-inset-bottom);"></view> |
|||
</view> |
|||
<!-- 添加备件 --> |
|||
<u-popup v-model="isPopupShow" mode="center" border-radius="14"> |
|||
<view class="popup-title">添加备件</view> |
|||
<scroll-view scroll-y="true" style="max-height:60vh;"> |
|||
<view class="popup"> |
|||
<u-form :model="form1" ref="form1Ref" label-width="160rpx"> |
|||
<u-form-item :label="`备件编号`" prop="itemNumber" required> |
|||
<view class="select"> |
|||
<u-input v-model="form1.itemNumber" placeholder="请输入备件" @blur='blur1()' @confirm="handelScanMsg1" :focus='isFocus'/> |
|||
</view> |
|||
</u-form-item> |
|||
<u-form-item :label="`备件名称`" prop="itemNumber" required class="disabled"> |
|||
<view class="select"> |
|||
<u-input v-model="form1.itemName" placeholder="根据备件编号获取" disabled /> |
|||
</view> |
|||
</u-form-item> |
|||
<u-form-item label="库位" prop="locationNumber" required v-if="isShow"> |
|||
<u-input v-model="form1.locationNumber" placeholder="请输入库位" @blur="blur()" @confirm="handelScanMsg"/> |
|||
<view class="right-button" @click="chickRightButton"> |
|||
扫描 |
|||
</view> |
|||
</u-form-item> |
|||
<u-form-item label="数量" prop="qty" required> |
|||
<u-input v-model="form1.qty" type="number" placeholder="请输入数量" /> |
|||
</u-form-item> |
|||
<u-form-item label="描述" prop="describes" required> |
|||
<u-input v-model="form1.describes" placeholder="请输入描述" /> |
|||
</u-form-item> |
|||
</u-form> |
|||
</view> |
|||
</scroll-view> |
|||
<view class="popup-footer"> |
|||
<view @click="isPopupShow = false">取消</view> |
|||
<view class="sure" @click="addSpare">确认</view> |
|||
</view> |
|||
</u-popup> |
|||
<u-select v-model="singleColumnShow" mode="single-column" :default-value='singleColumnDefaultValue' |
|||
:list="singleColumnList" @confirm="chooseSingleColumn"></u-select> |
|||
</view> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { |
|||
onLoad |
|||
} from '@dcloudio/uni-app' |
|||
import { |
|||
ref, |
|||
getCurrentInstance |
|||
} from 'vue' |
|||
import * as userApi from "@/api/user" |
|||
import * as sparePartsReturnApi from "@/api/sparePartsReturn" |
|||
import * as sparePartsApi from "@/api/spareParts" |
|||
import * as locationApi from "@/api/location" |
|||
|
|||
const { proxy } = getCurrentInstance() |
|||
const loading = ref(false) |
|||
// 备件弹窗 |
|||
const isPopupShow = ref(false) |
|||
const singleColumnShow = ref(false) |
|||
const singleColumnDefaultValue = ref([]) |
|||
const singleColumnList = ref([]) |
|||
const field = ref('') |
|||
const reverterUser = ref([]) |
|||
const form = ref({ |
|||
id: '', |
|||
number: '', |
|||
itemNumbers: [] |
|||
}) |
|||
const form1 = ref({ |
|||
itemNumber: "", |
|||
itemName: '', |
|||
locationNumber: '', |
|||
qty: '' |
|||
}) |
|||
const isShow = ref(false) |
|||
const locationList = ref([])//备件的库位列表 |
|||
const locationItem = ref('')//备件账内库 |
|||
const isFocus = ref(false) |
|||
|
|||
const choosesingleColumnItem = ref() |
|||
const itemNumber = ref() |
|||
const msg = ref() |
|||
|
|||
// 触发提交表单 |
|||
function submit() { |
|||
// 校验 |
|||
if (!form.value.reverterId) { |
|||
proxy.$modal.showToast('请选择归还人员') |
|||
return; |
|||
} |
|||
if (form.value.itemNumbers.length === 0) { |
|||
proxy.$modal.showToast('请选择备件') |
|||
return; |
|||
} |
|||
proxy.$modal.confirm('是否归还备件').then(() => { |
|||
proxy.$modal.loading('加载中') |
|||
loading.value = true |
|||
sparePartsReturnApi.sparePartsReturn(form.value).then((res) => { |
|||
proxy.$modal.closeLoading() |
|||
if (res.data) { |
|||
proxy.$modal.showToast('归还成功') |
|||
setTimeout(() => { |
|||
proxy.$tab.navigateBack() |
|||
loading.value = false |
|||
}, 1500) |
|||
} else { |
|||
proxy.$modal.showToast('归还失败') |
|||
loading.value = false |
|||
} |
|||
}).catch(() => { |
|||
proxy.$modal.closeLoading() |
|||
loading.value = false |
|||
}) |
|||
}) |
|||
|
|||
} |
|||
// 重置 |
|||
function reset() { |
|||
if (form.value.id) { |
|||
form.value.reverterId = ''; |
|||
form.value.itemNumbers = [] |
|||
} else { |
|||
form.value.reverterId = ''; |
|||
form.value.itemNumbers = [] |
|||
} |
|||
} |
|||
|
|||
function selectFormat(val, array) { |
|||
let str = array.filter(item => item.value == val)[0].label |
|||
return str |
|||
} |
|||
// 单列模式 |
|||
function openSingleColumn(fieldName, val, list) { |
|||
singleColumnList.value = list |
|||
field.value = fieldName |
|||
if (val) { |
|||
singleColumnDefaultValue.value = [list.findIndex(item => item.value == val)] |
|||
} else { |
|||
singleColumnDefaultValue.value = [] |
|||
} |
|||
singleColumnShow.value = true |
|||
} |
|||
// 单列模式点击确定之后 |
|||
function chooseSingleColumn(e) { |
|||
form.value[field.value] = e[0].value |
|||
if(field.value == 'reverterId'){ |
|||
choosesingleColumnItem.value = singleColumnList.value.filter(item => item.id == e[0].value) |
|||
form.value.reverterName = choosesingleColumnItem.value[0].name |
|||
} |
|||
singleColumnShow.value = false |
|||
} |
|||
// 获取归还人员列表 |
|||
async function getReverterUser() { |
|||
await userApi.getReverterUser().then(res => { |
|||
res.data.map(item => { |
|||
item.value = item.id |
|||
item.label = item.nickname |
|||
}) |
|||
reverterUser.value = res.data |
|||
}) |
|||
} |
|||
// 打开弹窗 |
|||
function open() { |
|||
form1.value = { |
|||
itemNumber: "", |
|||
itemName: '', |
|||
locationNumber: '', |
|||
qty: '' |
|||
} |
|||
isPopupShow.value = true |
|||
isShow.value= false |
|||
isFocus.value = true |
|||
} |
|||
// 添加备件 |
|||
function addSpare() { |
|||
// 校验 |
|||
if (!form1.value.itemNumber) { |
|||
proxy.$modal.showToast('请选择备件') |
|||
return; |
|||
} |
|||
if (!form1.value.itemName) { |
|||
proxy.$modal.showToast(msg.value) |
|||
return; |
|||
} |
|||
if (!form1.value.locationNumber) { |
|||
proxy.$modal.showToast('请选择库位') |
|||
return; |
|||
} |
|||
if (!locationItem.value || locationItem.value.isInAccount === 'TRUE') { |
|||
proxy.$modal.showToast('该库位属于帐内库,请选择帐外库') |
|||
return; |
|||
} |
|||
if (itemNumber.value) { |
|||
proxy.$modal.showToast('该库位已绑定过其他备件') |
|||
return; |
|||
} |
|||
if (!form1.value.qty) { |
|||
proxy.$modal.showToast(`请输入数量`) |
|||
return; |
|||
} |
|||
|
|||
if (!form1.value.describes) { |
|||
proxy.$modal.showToast(`请输入描述`) |
|||
return; |
|||
} |
|||
|
|||
if (form.value.itemNumbers && form.value.itemNumbers.length > 0) { |
|||
let arr =form.value.itemNumbers.filter(item => item.itemNumber == form1.value.itemNumber) |
|||
if (arr && arr.length > 0) { |
|||
proxy.$modal.showToast('该备件已添加') |
|||
return; |
|||
} |
|||
} |
|||
|
|||
form.value.itemNumbers.push(form1.value) |
|||
isPopupShow.value = false |
|||
} |
|||
// 删除备件 |
|||
function delSpareParts(index) { |
|||
form.value.itemNumbers.splice(index, 1) |
|||
} |
|||
function getLocation() { |
|||
locationApi.getLocation(form1.value.locationNumber).then(res => { |
|||
if(!res.data){ |
|||
if(res.msg){ |
|||
proxy.$modal.showToast(res.msg) |
|||
msg.value = res.msg |
|||
}else{ |
|||
proxy.$modal.showToast('找不到该库位') |
|||
} |
|||
return; |
|||
} |
|||
locationItem.value = res.data |
|||
form1.value.areaNumber = locationItem.value.areaNumber |
|||
// 判断该库位在之前添加的列表里有没有被绑定过 |
|||
if (form.value.itemNumbers && form.value.itemNumbers.length > 0) { |
|||
let arr = form.value.itemNumbers.filter(item => item.locationNumber == form1.value.locationNumber) |
|||
if (arr && arr.length > 0) { |
|||
itemNumber.value = 1 |
|||
}else{ |
|||
itemNumber.value = res.data.itemNumber || '' |
|||
} |
|||
}else{ |
|||
itemNumber.value = res.data.itemNumber || '' |
|||
} |
|||
}).catch(()=>{ |
|||
|
|||
}) |
|||
} |
|||
function blur() { |
|||
if (form1.value.locationNumber) { |
|||
getLocation() |
|||
} |
|||
} |
|||
// 扫描设备条码 |
|||
function handelScanMsg() { |
|||
getLocation() |
|||
} |
|||
// 获取备件信息 |
|||
function getSparePartsInfo() { |
|||
sparePartsApi.getSparePartsReturnInfo({ |
|||
number: form1.value.itemNumber, |
|||
}).then(res => { |
|||
if(!res.data){ |
|||
proxy.$modal.showToast(res.msg) |
|||
msg.value = res.msg |
|||
itemNumber.value = '' |
|||
form1.value.areaNumber = '' |
|||
form1.value.locationNumber = ''; |
|||
form1.value.itemName = '' |
|||
return; |
|||
} |
|||
itemNumber.value = '' |
|||
form1.value.itemName = res.data.itemName |
|||
form1.value.deliveryQty = res.data.deliveryQty |
|||
form1.value.applyQty = res.data.applyQty |
|||
// 判断是否有帐外库 |
|||
locationItem.value = res.data.list.filter(item=>item.isInAccount==='FALSE')[0] |
|||
if(locationItem.value){ |
|||
form1.value.areaNumber = locationItem.value.areaNumber |
|||
form1.value.locationNumber = locationItem.value.locationNumber |
|||
isShow.value =false |
|||
}else{ |
|||
form1.value.areaNumber = '' |
|||
form1.value.locationNumber = '' |
|||
isShow.value =true |
|||
} |
|||
}).catch((err)=>{ |
|||
msg.value = err.msg |
|||
itemNumber.value = '' |
|||
form1.value.areaNumber = '' |
|||
form1.value.itemName = '' |
|||
form1.value.applyQty = '' |
|||
form1.value.deliveryQty = '' |
|||
locationList.value = []; |
|||
}) |
|||
} |
|||
function blur1() { |
|||
if (form1.value.itemNumber) { |
|||
getSparePartsInfo() |
|||
} |
|||
} |
|||
// 扫描设备条码 |
|||
function handelScanMsg1() { |
|||
getSparePartsInfo() |
|||
} |
|||
onLoad(async(option) => { |
|||
getReverterUser() |
|||
}) |
|||
|
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.add-form-container { |
|||
min-height: calc(100vh - 140rpx); |
|||
background: white; |
|||
padding: 0px 0rpx 140rpx; |
|||
} |
|||
|
|||
.u-form-item { |
|||
padding: 20rpx 30rpx; |
|||
} |
|||
|
|||
.disabled { |
|||
background: #f5f5f5; |
|||
} |
|||
|
|||
.footer { |
|||
position: fixed; |
|||
bottom: 0px; |
|||
left: 0px; |
|||
width: 100%; |
|||
z-index: 22; |
|||
} |
|||
|
|||
.btns { |
|||
display: flex; |
|||
|
|||
|
|||
button { |
|||
flex: 1; |
|||
} |
|||
|
|||
.sure { |
|||
background: #409eff; |
|||
color: white; |
|||
border-radius: 0px; |
|||
|
|||
&::after { |
|||
border: 1px solid #409eff; |
|||
border-radius: 0px; |
|||
} |
|||
} |
|||
|
|||
.reset { |
|||
background: #F5F5F5; |
|||
border-radius: 0px; |
|||
|
|||
&::after { |
|||
border-radius: 0px; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.right-button { |
|||
background: #409eff; |
|||
color: white; |
|||
padding: 0rpx 30rpx; |
|||
border-radius: 16rpx; |
|||
text-align: center; |
|||
font-size: 28rpx; |
|||
} |
|||
|
|||
.select { |
|||
display: flex; |
|||
align-items: center; |
|||
height: 72rpx; |
|||
width: 100%; |
|||
|
|||
.input { |
|||
flex: 1; |
|||
font-size: 28rpx; |
|||
color: #000000; |
|||
} |
|||
|
|||
.placeholder { |
|||
flex: 1; |
|||
font-size: 28rpx; |
|||
color: rgb(192, 196, 204); |
|||
|
|||
} |
|||
} |
|||
|
|||
.title { |
|||
padding: 32rpx 0rpx; |
|||
position: relative; |
|||
|
|||
span { |
|||
position: absolute; |
|||
left: -16rpx; |
|||
color: #fa3534; |
|||
top: 19px; |
|||
} |
|||
} |
|||
|
|||
.list { |
|||
padding: 0rpx 30rpx; |
|||
|
|||
.item { |
|||
display: flex; |
|||
margin-bottom: 20rpx; |
|||
|
|||
.item-box { |
|||
background: #F5F5F5; |
|||
border-radius: 12rpx; |
|||
flex: 1; |
|||
width: 0rpx; |
|||
} |
|||
|
|||
.spare-title { |
|||
padding: 20rpx 30rpx; |
|||
border-bottom: 1px solid #e4e4e4; |
|||
|
|||
.title-txt { |
|||
color: #409eff; |
|||
font-size: 30rpx; |
|||
font-weight: bold; |
|||
} |
|||
} |
|||
|
|||
.dec { |
|||
color: #9c9c9c; |
|||
padding: 20rpx 30rpx 20rpx; |
|||
} |
|||
|
|||
} |
|||
} |
|||
|
|||
.add-btn { |
|||
display: flex; |
|||
justify-content: flex-start; |
|||
align-items: center; |
|||
} |
|||
|
|||
.popup-title { |
|||
text-align: center; |
|||
font-size: 32rpx; |
|||
font-weight: bold; |
|||
color: #409eff; |
|||
padding: 30rpx 30rpx 0px |
|||
} |
|||
|
|||
.popup { |
|||
width: 600rpx; |
|||
padding: 30rpx 0rpx 30rpx; |
|||
|
|||
} |
|||
|
|||
.popup-footer { |
|||
display: flex; |
|||
border-top: 1px solid #e4e4e4; |
|||
|
|||
view { |
|||
line-height: 100rpx; |
|||
flex: 1; |
|||
text-align: center; |
|||
|
|||
&.sure { |
|||
color: #409eff; |
|||
} |
|||
} |
|||
} |
|||
|
|||
::v-deep .u-checkbox-group { |
|||
display: grid !important; |
|||
} |
|||
</style> |
@ -0,0 +1,60 @@ |
|||
|
|||
|
|||
function authPermission(permission) { |
|||
const all_permission = "*:*:*" |
|||
const permissions =uni.getStorageSync('permissionInfo') |
|||
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 = uni.getStorageSync('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}` |
|||
} |
|||
} |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 24 KiB |
@ -0,0 +1,12 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="47px" height="66px" xmlns="http://www.w3.org/2000/svg"> |
|||
<defs> |
|||
<linearGradient gradientUnits="userSpaceOnUse" x1="5.63807152481269" y1="62.1175381975164" x2="43.4328694937704" y2="1.76792360964131" id="LinearGradient40"> |
|||
<stop id="Stop41" stop-color="#09005d" offset="0" /> |
|||
<stop id="Stop42" stop-color="#1a0f91" offset="1" /> |
|||
</linearGradient> |
|||
</defs> |
|||
<g transform="matrix(1 0 0 1 -97 -106 )"> |
|||
<path d="M 36.7877623440973 1.59223308620249 C 37.7932710870804 0.0521044544140052 39.8698652301974 -0.408494762569467 41.450991297062 0.55588484798968 L 45.378304430887 2.95244014885682 C 46.9594304977516 3.91681975941597 47.4694711644821 5.96072878478014 46.5222527834112 7.54403859316083 L 11.8977778076482 65.9393830713469 L 0.95376235865917 59.2534975623212 C 0.0648343395002736 58.7137328549186 -0.197472289103991 57.5550379496946 0.37814503477759 56.6914144178506 L 36.7877623440973 1.59223308620249 Z " fill-rule="nonzero" fill="url(#LinearGradient40)" stroke="none" transform="matrix(1 0 0 1 97 106 )" /> |
|||
</g> |
|||
</svg> |
After Width: | Height: | Size: 106 KiB |
@ -0,0 +1,6 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="37px" height="37px" xmlns="http://www.w3.org/2000/svg"> |
|||
<g transform="matrix(1 0 0 1 -200 -131 )"> |
|||
<path d="M 1.8705291643251 26.4306710705829 C 0.0206628251877919 22.5581882283421 -0.41841050822613 18.2538299761859 0.58210085807772 14.1438156584916 C 0.733257251548091 13.5319921611116 0.91320533901281 12.9273665872301 1.12194512047189 12.3299389368472 C 1.1867264319592 12.1427929258839 1.25870566694509 11.9556469149206 1.33068490193098 11.7685009039573 C 1.69058107686042 10.8471666961379 2.12245648677576 9.95462418231291 2.6191132081784 9.11246713297802 C 2.62631113167697 9.09807128598083 2.63350905517557 9.09087336248225 2.64070697867417 9.07647751548507 C 2.66230074916992 9.04048789799212 2.67669659616711 9.01169620399777 2.69829036666286 8.97570658650483 C 2.73427998415581 8.91092527501753 2.77746752514735 8.84614396353023 2.81345714264029 8.78856057554152 C 2.91422807162054 8.62300833507397 3.10857200608242 8.55102910008808 3.28852009354714 8.59421664107961 C 3.33170763453868 8.6014145645782 3.37489517553022 8.62300833507396 3.41808271652174 8.64460210556974 C 3.62682249798082 8.77416472854433 3.68440588596954 9.04048789799212 3.56204118649352 9.2492276794512 C 2.90703014812193 10.3073224337438 2.36718588572777 11.4445943465208 1.9497063228096 12.6250538002894 C -0.130493568282595 18.4985593751379 1.1147471969733 24.7535548954117 4.69211517577197 29.3314342405142 C 6.67874206138249 31.8794991590147 9.39235922035051 33.9093135856167 12.6602164887099 35.060981345391 C 13.236050368597 35.2625232033514 13.8118842484841 35.4352733673176 14.3949160518698 35.5792318372894 C 18.3105864351022 36.5365556626017 22.4062049057992 36.1190760996835 26.0987396605753 34.3555848425293 C 30.3383166012442 32.3329683394258 33.5341946346176 28.7843920546214 35.0961440338114 24.3576691029893 C 38.3280116846779 15.2163062597814 33.5269967111191 5.15360920875412 24.3856338679112 1.9217415578877 C 23.8241958350213 1.72019969992721 23.2483619551341 1.55464745945966 22.672528075247 1.41068898948788 C 20.1748486212367 0.798865492107825 17.5692003147475 0.748480027617699 15.0427291667428 1.25953259601752 C 14.9779478552555 1.27392844301469 14.9131665437682 1.27392844301469 14.8555831557795 1.25233467251892 C 14.6972288388105 1.21634505502598 14.5676662158359 1.08678243205138 14.531676598343 0.914032268085244 C 14.4812911338529 0.676500792631811 14.6396454508218 0.446167240676965 14.8771769262753 0.395781776186839 C 17.526012773756 -0.144062486207328 20.2612237032198 -0.0864790982186222 22.8884657802047 0.554136093155797 C 23.4930913540862 0.698094563127572 24.090519004469 0.8780426505923 24.6879466548519 1.08678243205138 C 34.2827786784709 4.47700439988675 39.3213251274832 15.0507540193138 35.9311031596477 24.6383881194342 C 34.2899766019695 29.2882466995226 30.9285463281285 33.0095731482931 26.4802296060006 35.1329605803768 C 22.6077467637597 36.9828269195142 18.3105864351022 37.4219002529281 14.1933741939093 36.4213888866243 C 13.5815506965292 36.2702324931539 12.9769251226478 36.0902844056892 12.3722995487663 35.8815446242301 C 7.7224409686779 34.2404180665518 3.99391659640884 30.8789877927108 1.8705291643251 26.4306710705829 Z " fill-rule="nonzero" fill="#ffffff" stroke="none" transform="matrix(1 0 0 1 200 131 )" /> |
|||
</g> |
|||
</svg> |
@ -0,0 +1,6 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="26px" height="30px" xmlns="http://www.w3.org/2000/svg"> |
|||
<g transform="matrix(1 0 0 1 -47 -440 )"> |
|||
<path d="M 0 5.43375 C 0 4.39821609406726 0.831471178885669 3.55875 1.85714285714286 3.55875 L 4.667 3.55875 L 4.667 9 L 20.6142857142857 9 L 20.6142857142857 3.55875 L 24.1428571428571 3.55875 C 25.1685288211143 3.55875 26 4.39821609406726 26 5.43375 L 26 28.125 C 26 29.1605339059327 25.1685288211143 30 24.1428571428571 30 L 1.85714285714286 30 C 0.831471178885669 30 0 29.1605339059327 0 28.125 L 0 5.43375 Z M 6.68571428571429 7.213125 L 6.68571428571429 2.638125 L 8.54657142857143 2.638125 C 8.54657142857143 1.18125 9.71657142857143 0 11.1614285714286 0 L 14.1328571428571 0 C 15.5758571428571 0 16.7458571428571 1.18125 16.7458571428571 2.638125 L 18.5714285714286 2.638125 L 18.5714285714286 7.213125 L 6.68571428571429 7.213125 Z M 10.8958571428571 3.178125 C 10.8958571428571 4.231875 11.726 5.085 12.753 5.085 C 13.7781428571429 5.085 14.6101428571429 4.231875 14.6101428571429 3.178125 C 14.6101428571429 2.124375 13.7781428571429 1.27125 12.753 1.27125 C 11.726 1.27125 10.8958571428571 2.124375 10.8958571428571 3.178125 Z M 21.7898571428571 12 L 4.21014285714286 12 L 4.21014285714286 14 L 21.7898571428571 14 L 21.7898571428571 12 Z M 4.21014285714286 15.76125 L 4.21014285714286 15.763125 L 4.21014285714286 17.5425 L 8.17142857142857 17.5425 L 8.17142857142857 15.76125 L 4.21014285714286 15.76125 Z M 4.21014285714286 19.83 L 4.21014285714286 19.831875 L 4.21014285714286 21.609375 L 8.17142857142857 21.609375 L 8.17142857142857 19.83 L 4.21014285714286 19.83 Z M 4.21014285714286 23.896875 L 4.21014285714286 23.89875 L 4.21014285714286 25.678125 L 9.16128571428571 25.678125 L 9.16128571428571 23.896875 L 4.21014285714286 23.896875 Z M 19.1007142857143 22.936875 C 18.6304250353497 23.601697854168 18.054348350795 24.1833137376127 17.3958571428571 24.658125 C 17.3499258944188 24.6907879240536 17.3226001725233 24.743965009545 17.3226001725233 24.800686363582 C 17.3226001725233 24.8471234159694 17.3409461471698 24.8916424010547 17.3735714285714 24.924375 L 19.955 27.530625 C 20.0943364195914 27.6714577822726 20.2834102728407 27.7505899923118 20.4805714285714 27.7505899923118 C 20.6777325843022 27.7505899923118 20.8668064375515 27.6714577822726 21.0061428571429 27.530625 L 21.9495714285714 26.578125 C 22.0890629462509 26.4374488071433 22.1674415161946 26.2465569360743 22.1674415161946 26.0475 C 22.1674415161946 25.8484430639257 22.0890629462509 25.6575511928567 21.9495714285714 25.516875 L 19.3718571428571 22.914375 C 19.3384169107129 22.8805790204336 19.2930418828892 22.8615897586197 19.2457262895471 22.8615897586197 C 19.1881881961978 22.8615897586197 19.1341869943616 22.8896253240047 19.1007142857143 22.936875 Z M 14.759255467994 24.5140374791424 C 15.8204396264006 24.5140374791424 16.8379731597654 24.0875460419895 17.5871428571429 23.32875 C 18.3393810181837 22.5713714085468 18.7621586915612 21.5428888032805 18.7621586915612 20.4703129946648 C 18.7621586915612 19.4014123902587 18.3422653206105 18.3761442986165 17.5945714285714 17.619375 C 16.4639051022835 16.4793931723658 14.7689506313882 16.1297666636769 13.286 16.730625 C 13.2322852506052 16.7522006308877 13.1970325664254 16.804665558827 13.1970325664254 16.8630310876505 C 13.1970325664254 16.9004978712548 13.2116477538362 16.9364572975827 13.2377142857143 16.963125 L 14.4857142857143 18.223125 C 14.702965366557 18.4427381600805 14.702965366557 18.7985118399195 14.4857142857143 19.018125 L 13.2637142857143 20.251875 C 13.1592443813362 20.3572532390508 13.017609951532 20.4164460384021 12.8699345449049 20.4164460384021 C 12.7186473849234 20.4164460384021 12.5738649451232 20.3543311831856 12.4688571428571 20.244375 L 11.2524285714286 18.97125 C 11.228278977567 18.9459814310735 11.1949935626667 18.9317087237978 11.160214266276 18.9317087237978 C 11.1072954788903 18.9317087237978 11.0598197467671 18.9645509214797 11.0407142857143 19.014375 C 10.8594350431001 19.4823089185733 10.7663983251369 19.9803341788901 10.7663983251369 20.4827874791424 C 10.7663983251369 22.7091853768978 12.5540613597411 24.5140374791424 14.759255467994 24.5140374791424 Z M 21.0771333988002 25.9865625 C 21.0771333988002 26.1605123044669 21.0088694902987 26.3273761781034 20.8872857142857 26.450625 C 20.7650596956061 26.5745248598445 20.5989889589728 26.6441731430195 20.4257857142857 26.6441731430195 C 20.0660563212907 26.6441731430195 19.7744380297712 26.3497508294661 19.7744380297712 25.9865625 C 19.7744380297712 25.8126126955331 19.8427019382728 25.6457488218966 19.9642857142857 25.5225 C 20.0865117329653 25.3986001401555 20.2525824695986 25.3289518569805 20.4257857142857 25.3289518569805 C 20.7855151072807 25.3289518569805 21.0771333988002 25.6233741705339 21.0771333988002 25.9865625 Z " fill-rule="nonzero" fill="#9bca63" stroke="none" transform="matrix(1 0 0 1 47 440 )" /> |
|||
</g> |
|||
</svg> |
@ -0,0 +1,6 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="20px" height="18px" xmlns="http://www.w3.org/2000/svg"> |
|||
<g transform="matrix(1 0 0 1 -30 -16 )"> |
|||
<path d="M 19.7374790983607 8.04830870454546 C 19.9665962704918 7.76331261818182 19.9137230737705 7.351651575 19.6317327254098 7.12646946818182 L 11.2566194672131 0.571559031818182 C 10.5410689754098 0.00508528636363643 9.42015733606558 0.00508528636363643 8.70460684426229 0.571559031818182 L 0.392941434426229 7.12998793636364 C 0.107426209016393 7.35517004318182 0.0616027868852459 7.76683108636364 0.28367018442623 8.048308725 C 0.505737581967213 8.32978636363636 0.921673340163934 8.37904493863636 1.20366368852459 8.1573813 L 1.47155450819672 7.94627306590909 L 1.47155450819672 15.8733869727273 C 1.47155450819672 16.9957790386364 2.63828956967213 17.8366934863636 3.68165383196721 17.8366934863636 L 16.7942048770492 17.8366934863636 C 17.8234696311475 17.8366934863636 18.5178708606557 17.0485561022727 18.5178708606557 15.8733869727273 L 18.5178708606557 7.92516225681818 L 18.8139607172131 8.1573813 C 18.9338066188525 8.25238000227273 19.0748017827869 8.29812010909091 19.2193218442623 8.29812010909091 C 19.413190204918 8.29812010909091 19.6070585655738 8.21367681136364 19.7374790983607 8.04830870454546 Z M 11.9651202254098 15.1591374818182 L 11.9651202254098 16.5243040159091 L 10.6538651229508 16.5243040159091 L 9.3426100204918 16.5243040159091 L 8.03135491803279 16.5243040159091 L 8.03135491803279 15.1591374818182 L 8.03135491803279 12.8615762863636 C 8.03135491803279 12.1015866681818 8.64820879098361 11.28178305 9.99823758196722 11.28178305 C 11.3517912295082 11.28178305 11.9651202459016 12.1015866681818 11.9651202459016 12.8615762863636 L 11.9651202254098 15.1591374818182 Z " fill-rule="nonzero" fill="#0052d9" stroke="none" transform="matrix(1 0 0 1 30 16 )" /> |
|||
</g> |
|||
</svg> |
After Width: | Height: | Size: 172 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 7.1 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 196 KiB |
After Width: | Height: | Size: 9.2 KiB |
After Width: | Height: | Size: 79 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 16 KiB |
@ -0,0 +1 @@ |
|||
export { default as useCountStore } from './modules/countStore' |
@ -0,0 +1,124 @@ |
|||
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: '', |
|||
meaus: [], |
|||
}), |
|||
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 |
|||
|
|||
uni.setStorageSync('permissionInfo',res.permissions) |
|||
uni.setStorageSync('roles',res.roles) |
|||
let menus = [] |
|||
res.menus.forEach(item => { |
|||
if (item.path == '/pda') { |
|||
menus = item.children |
|||
} |
|||
}) |
|||
this.meaus = menus |
|||
} 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() |
|||
uni.removeStorageSync('permissionInfo') |
|||
uni.removeStorageSync('roles') |
|||
resolve(res) |
|||
}).catch(error => { |
|||
reject(error) |
|||
}) |
|||
}) |
|||
}, |
|||
} |
|||
}) |
|||
|
|||
export default useStore |
@ -0,0 +1,2 @@ |
|||
@title-size: 40rpx; |
|||
@title-color: #47caff; |
@ -0,0 +1,2 @@ |
|||
$title-size: 40rpx; |
|||
$title-color: #bd34fe; |
@ -0,0 +1,77 @@ |
|||
/** |
|||
* 这里是uni-app内置的常用样式变量 |
|||
* |
|||
* uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量 |
|||
* 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App |
|||
* |
|||
*/ |
|||
|
|||
/** |
|||
* 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能 |
|||
* |
|||
* 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件 |
|||
*/ |
|||
|
|||
@import 'vk-uview-ui/theme.scss'; |
|||
/* 颜色变量 */ |
|||
|
|||
/* 行为相关颜色 */ |
|||
$uni-color-primary: #007aff; |
|||
$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; |
|||
|
|||
/* 背景颜色 */ |
|||
$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-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; |