@ -0,0 +1,3 @@ |
|||||
|
> 1% |
||||
|
last 2 versions |
||||
|
not dead |
@ -0,0 +1,8 @@ |
|||||
|
[*.{js,jsx,ts,tsx,vue}] |
||||
|
indent_style = space |
||||
|
indent_size = 2 |
||||
|
end_of_line = lf |
||||
|
trim_trailing_whitespace = true |
||||
|
insert_final_newline = true |
||||
|
max_line_length = 140 |
||||
|
root = true |
@ -0,0 +1,3 @@ |
|||||
|
VUE_APP_MODE=production |
||||
|
VUE_APP_PREVIEW=false |
||||
|
VUE_APP_URL=https://www.tall.wiki/ |
@ -0,0 +1,10 @@ |
|||||
|
VUE_APP_MODE=development |
||||
|
VUE_APP_NODE_ENV=development |
||||
|
VUE_APP_SCENE=flat-car |
||||
|
VUE_APP_BASE_URL=http://101.201.226.163 |
||||
|
VUE_APP_API_URL=http://101.201.226.163 |
||||
|
VUE_APP_PROXY_URL=http://101.201.226.163 |
||||
|
VUE_APP_PUBLIC_PATH=/carbasics |
||||
|
VUE_APP_MSG_URL=ws://101.201.226.163/websocket/message/v4.0/ws |
||||
|
VUE_APP_TITLE=暴风眼Typhoneye机构管理 |
||||
|
VUE_APP_DESCRIPTION=暴风眼Typhoneye机构管理 |
@ -0,0 +1,3 @@ |
|||||
|
VUE_APP_BASE_URL=http://127.0.0.1:3000 |
||||
|
VUE_APP_API_URL=http://127.0.0.1:3000 |
||||
|
VUE_APP_PROXY_URL= |
@ -0,0 +1,10 @@ |
|||||
|
VUE_APP_MODE=production |
||||
|
VUE_APP_NODE_ENV=production |
||||
|
VUE_APP_SCENE=flat-car |
||||
|
VUE_APP_BASE_URL=https://www.tall.wiki/ |
||||
|
VUE_APP_API_URL=https://www.tall.wiki |
||||
|
VUE_APP_PROXY_URL=https://www.tall.wiki |
||||
|
VUE_APP_PUBLIC_PATH=/carbasics |
||||
|
VUE_APP_MSG_URL=wss://www.tall.wiki/websocket/message/v4.0/ws |
||||
|
VUE_APP_TITLE=暴风眼Typhoneye机构管理 |
||||
|
VUE_APP_DESCRIPTION=暴风眼Typhoneye机构管理 |
@ -0,0 +1,47 @@ |
|||||
|
/* |
||||
|
* Copyright (c) 2019. |
||||
|
* author: wally |
||||
|
* email: 18603454788@163.com |
||||
|
*/ |
||||
|
|
||||
|
module.exports = { |
||||
|
root: true, |
||||
|
env: { browser: true, node: true }, |
||||
|
extends: ['plugin:vue/recommended', 'plugin:vue/essential'], |
||||
|
|
||||
|
rules: { |
||||
|
'vue/html-self-closing': 'off', |
||||
|
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', |
||||
|
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', |
||||
|
'no-param-reassign': ['error', { props: true, ignorePropertyModificationsFor: ['state'] }], |
||||
|
'max-len': ['error', { code: 140, tabWidth: 2 }], |
||||
|
'object-curly-newline': ['error', { multiline: true }], |
||||
|
'arrow-parens': ['error', 'as-needed'], |
||||
|
'linebreak-style': 'off', |
||||
|
'vue/attributes-order': 'off', |
||||
|
'no-param-reassign': 'off', |
||||
|
'vue/singleline-html-element-content-newline': 'off', |
||||
|
'vue/max-attributes-per-line': 'off', |
||||
|
'vue/multiline-html-element-content-newline': 'off', |
||||
|
'vue/html-indent': 'off', |
||||
|
}, |
||||
|
|
||||
|
parserOptions: { parser: 'babel-eslint' }, |
||||
|
|
||||
|
overrides: [ |
||||
|
{ |
||||
|
files: ['**/__tests__/*.{j,t}s?(x)'], |
||||
|
env: { jest: true }, |
||||
|
}, |
||||
|
], |
||||
|
|
||||
|
globals: { |
||||
|
Vue: true, |
||||
|
VueRouter: true, |
||||
|
Vuex: true, |
||||
|
axios: true, |
||||
|
_: true, |
||||
|
Vuetify: true, |
||||
|
vuetify: true, |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,23 @@ |
|||||
|
.DS_Store |
||||
|
node_modules |
||||
|
/dist |
||||
|
|
||||
|
|
||||
|
# local env files |
||||
|
.env.local |
||||
|
.env.*.local |
||||
|
|
||||
|
# Log files |
||||
|
npm-debug.log* |
||||
|
yarn-debug.log* |
||||
|
yarn-error.log* |
||||
|
pnpm-debug.log* |
||||
|
|
||||
|
# Editor directories and files |
||||
|
.idea |
||||
|
.vscode |
||||
|
*.suo |
||||
|
*.ntvs* |
||||
|
*.njsproj |
||||
|
*.sln |
||||
|
*.sw? |
@ -0,0 +1,13 @@ |
|||||
|
{ |
||||
|
"printWidth": 140, |
||||
|
"singleQuote": true, |
||||
|
"semi": true, |
||||
|
"trailingComma": "all", |
||||
|
"arrowParens": "avoid", |
||||
|
"tabWidth": 2, |
||||
|
"useTabs": false, |
||||
|
"bracketSpacing": true, |
||||
|
"jsxBracketSameLine": false, |
||||
|
"proseWrap": "always", |
||||
|
"endOfLine": "lf" |
||||
|
} |
@ -0,0 +1,24 @@ |
|||||
|
# 中医药大学课题数据库 |
||||
|
|
||||
|
## Project setup |
||||
|
``` |
||||
|
yarn install |
||||
|
``` |
||||
|
|
||||
|
### Compiles and hot-reloads for development |
||||
|
``` |
||||
|
yarn serve |
||||
|
``` |
||||
|
|
||||
|
### Compiles and minifies for production |
||||
|
``` |
||||
|
yarn build |
||||
|
``` |
||||
|
|
||||
|
### Lints and fixes files |
||||
|
``` |
||||
|
yarn lint |
||||
|
``` |
||||
|
|
||||
|
### Customize configuration |
||||
|
See [Configuration Reference](https://cli.vuejs.org/config/). |
@ -0,0 +1,13 @@ |
|||||
|
module.exports = { |
||||
|
presets: ["@vue/cli-plugin-babel/preset"], |
||||
|
plugins: [ |
||||
|
[ |
||||
|
"import", |
||||
|
{ |
||||
|
libraryName: "ant-design-vue", |
||||
|
libraryDirectory: "es", |
||||
|
style: true |
||||
|
} |
||||
|
] |
||||
|
] |
||||
|
}; |
@ -0,0 +1 @@ |
|||||
|
module.exports = {extends: ['./node_modules/vue-cli-plugin-commitlint/lib/lint']}; |
@ -0,0 +1,54 @@ |
|||||
|
{ |
||||
|
"name": "wisdom-mobile", |
||||
|
"version": "0.1.0", |
||||
|
"private": true, |
||||
|
"scripts": { |
||||
|
"serve": "vue-cli-service serve", |
||||
|
"serve-mock": "vue-cli-service serve --mode mock", |
||||
|
"build": "vue-cli-service build", |
||||
|
"lint": "vue-cli-service lint" |
||||
|
}, |
||||
|
"dependencies": { |
||||
|
"ant-design-vue": "^1.2.4", |
||||
|
"compression-webpack-plugin": "^6.1.1", |
||||
|
"core-js": "^3.6.5", |
||||
|
"echarts": "^4.8.0", |
||||
|
"echarts-gl": "^1.1.1", |
||||
|
"moment": "^2.29.1", |
||||
|
"register-service-worker": "^1.7.1", |
||||
|
"stylus": "^0.54.8", |
||||
|
"vconsole": "^3.9.1", |
||||
|
"vue": "^2.6.11", |
||||
|
"vue-dompurify-html": "^2.3.0", |
||||
|
"vue-quill-editor": "^3.0.6", |
||||
|
"vue-router": "^3.2.0", |
||||
|
"vuex": "^3.4.0" |
||||
|
}, |
||||
|
"devDependencies": { |
||||
|
"@vue/cli-plugin-babel": "~4.5.0", |
||||
|
"@vue/cli-plugin-eslint": "~4.5.0", |
||||
|
"@vue/cli-plugin-pwa": "~4.5.0", |
||||
|
"@vue/cli-plugin-router": "~4.5.0", |
||||
|
"@vue/cli-plugin-vuex": "~4.5.0", |
||||
|
"@vue/cli-service": "~4.5.0", |
||||
|
"@vue/eslint-config-prettier": "^6.0.0", |
||||
|
"axios": "^0.18.0", |
||||
|
"babel-eslint": "^10.1.0", |
||||
|
"babel-plugin-import": "^1.11.0", |
||||
|
"css-loader": "^5.0.1", |
||||
|
"eslint": "^6.7.2", |
||||
|
"eslint-plugin-prettier": "^3.1.3", |
||||
|
"eslint-plugin-vue": "^6.2.2", |
||||
|
"less": "^2.7.3", |
||||
|
"less-loader": "^4.1.0", |
||||
|
"prettier": "^1.19.1", |
||||
|
"sass": "^1.26.5", |
||||
|
"sass-loader": "^8.0.2", |
||||
|
"stylus": "^0.54.5", |
||||
|
"stylus-loader": "^3.0.2", |
||||
|
"svg-sprite-loader": "^5.0.0", |
||||
|
"vue-cli-plugin-ant-design": "^1.0.1", |
||||
|
"vue-cli-plugin-axios": "^0.0.4", |
||||
|
"vue-template-compiler": "^2.6.11" |
||||
|
} |
||||
|
} |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 9.2 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 6.3 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 215 B |
@ -0,0 +1,19 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html lang="en"> |
||||
|
<head> |
||||
|
<meta charset="utf-8"> |
||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0"> |
||||
|
<link rel="icon" href="./favicon.ico"> |
||||
|
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> |
||||
|
<title><%= webpackConfig.name %></title> |
||||
|
</head> |
||||
|
<body> |
||||
|
<noscript> |
||||
|
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> |
||||
|
</noscript> |
||||
|
<div id="app"></div> |
||||
|
<!-- built files will be auto injected --> |
||||
|
<script src="./sdk.js"></script> |
||||
|
</body> |
||||
|
</html> |
@ -0,0 +1,2 @@ |
|||||
|
User-agent: * |
||||
|
Disallow: |
@ -0,0 +1,99 @@ |
|||||
|
/* |
||||
|
* @Author: aBin |
||||
|
* @email: binbin0314@126.com |
||||
|
* @Date: 2021-04-19 10:23:19 |
||||
|
* @LastEditors: aBin |
||||
|
* @LastEditTime: 2021-06-09 09:50:31 |
||||
|
*/ |
||||
|
/** |
||||
|
* ccsens tall sdk.js |
||||
|
* v1.0.0 |
||||
|
* 父组件调用 TallPlugin.init()即可 |
||||
|
* 监听message消息, 如果是created消息 就把tall的参数传递过来 |
||||
|
*/ |
||||
|
|
||||
|
(function(window) { |
||||
|
// 单例局部变量
|
||||
|
var _instance = null; |
||||
|
// 对外暴露TallPlugin类
|
||||
|
window.TallPlugin = function(config) { |
||||
|
this.config = config; |
||||
|
this.props = null; |
||||
|
this.parent = '*'; |
||||
|
}; |
||||
|
|
||||
|
// 初始化并保证是单例
|
||||
|
TallPlugin.init = function(callback, config) { |
||||
|
if (!_instance) { |
||||
|
_instance = new TallPlugin(config); |
||||
|
_instance.config = config; |
||||
|
_instance.parent = window.parent.origin; |
||||
|
// DOM加载完成
|
||||
|
window.addEventListener('DOMContentLoaded', _instance.mounted, false); |
||||
|
// window onload
|
||||
|
window.addEventListener('load', _instance.loaded, false); |
||||
|
// destroy
|
||||
|
window.addEventListener('unload', _instance.destroy, false); |
||||
|
// error
|
||||
|
window.addEventListener('error', _instance.error, false); |
||||
|
_instance.onMessage(callback); |
||||
|
} |
||||
|
return _instance; |
||||
|
}; |
||||
|
|
||||
|
TallPlugin.prototype.onMessage = function(callback) { |
||||
|
var _this = this; |
||||
|
window.addEventListener( |
||||
|
'message', |
||||
|
function(event) { |
||||
|
try { |
||||
|
if (_this.parent === event.origin) { |
||||
|
// 是父窗体传来的消息
|
||||
|
console.log('event.data:', event.data); |
||||
|
var data = JSON.parse(event.data); |
||||
|
_this.props = data || null; |
||||
|
callback && typeof callback === 'function' && callback.call(_this, data); |
||||
|
} else { |
||||
|
_this.props = null; |
||||
|
} |
||||
|
} catch (e) { |
||||
|
// console.error(`TallPlugin warn: ${e}`)
|
||||
|
_this.props = null; |
||||
|
} |
||||
|
}, |
||||
|
false, |
||||
|
); |
||||
|
return this; |
||||
|
}; |
||||
|
|
||||
|
// DOMContentLoaded DOM加载完成触发
|
||||
|
TallPlugin.prototype.mounted = function(callback) { |
||||
|
var _this = this; |
||||
|
window.postMessage('created', _this.parent); |
||||
|
callback && typeof callback === 'function' && callback.call(this); |
||||
|
return this; |
||||
|
}; |
||||
|
// load window onload触发
|
||||
|
TallPlugin.prototype.loaded = function(callback) { |
||||
|
var _this = this; |
||||
|
window.postMessage('loaded', _this.parent); |
||||
|
callback && typeof callback === 'function' && callback.call(this); |
||||
|
return this; |
||||
|
}; |
||||
|
|
||||
|
// 子窗体销毁触发
|
||||
|
TallPlugin.prototype.destroy = function(callback) { |
||||
|
var _this = this; |
||||
|
window.postMessage('destroy', _this.parent); |
||||
|
callback && typeof callback === 'function' && callback.call(this); |
||||
|
return this; |
||||
|
}; |
||||
|
|
||||
|
// error触发
|
||||
|
TallPlugin.prototype.error = function(callback) { |
||||
|
var _this = this; |
||||
|
window.postMessage('error', _this.parent); |
||||
|
callback && typeof callback === 'function' && callback.call(this); |
||||
|
return this; |
||||
|
}; |
||||
|
})(window); |
@ -0,0 +1,15 @@ |
|||||
|
{ |
||||
|
"$shared": { |
||||
|
"version": "v1", |
||||
|
"identifier": "wally", |
||||
|
"credential": "111111" |
||||
|
}, |
||||
|
"dev": { |
||||
|
"name": "dev", |
||||
|
"url": "http://192.168.31.13/gateway" |
||||
|
}, |
||||
|
"local": { |
||||
|
"version": "v2", |
||||
|
"url": "http://192.168.31.13/gateway" |
||||
|
} |
||||
|
} |
@ -0,0 +1,56 @@ |
|||||
|
# @tall = {{url}}/tall3/v3.0 |
||||
|
|
||||
|
@tall = https://www.tall.wiki/gateway/tall3/v3.0 |
||||
|
@tcm = https://www.tall.wiki/gateway/tcm |
||||
|
@type = content-type: application/json;charset=utf-8 |
||||
|
|
||||
|
### login |
||||
|
|
||||
|
# @name login |
||||
|
POST {{tall}}/users/signin |
||||
|
{{type}} |
||||
|
|
||||
|
{ |
||||
|
"client": 1, |
||||
|
"type": 3, |
||||
|
"data": { |
||||
|
"identifier": "song", |
||||
|
"credential": "999999" |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
### send code |
||||
|
|
||||
|
GET {{tall}}/users/smscode?phone=16603418748 |
||||
|
|
||||
|
|
||||
|
### phone login |
||||
|
# @name phonelogin |
||||
|
POST {{tall}}/users/signin |
||||
|
{{type}} |
||||
|
|
||||
|
{ |
||||
|
"client": 1, |
||||
|
"type": 1, |
||||
|
"data": { |
||||
|
"identifier": "16603418748", |
||||
|
"credential": "1111" |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
### 根据团队id查看研发团队相关信息 |
||||
|
|
||||
|
POST {{tcm}}/patient/selSearchCriteriaList |
||||
|
{{type}} |
||||
|
Authorization: Bearer {{login.response.body.$.data.token}} |
||||
|
|
||||
|
# { |
||||
|
# "param": { |
||||
|
# "company": "", |
||||
|
# "researchDirection": "", |
||||
|
# "teamId": 0, |
||||
|
# "teamIntroduce": "", |
||||
|
# "teamLeaderName": "", |
||||
|
# "teamName": "" |
||||
|
# } |
||||
|
# } |
@ -0,0 +1,54 @@ |
|||||
|
<template> |
||||
|
<a-config-provider :locale="zh_CN"> |
||||
|
<div v-if="anyringToken" class="d-flex flex-column flex-wrap pt-46" id="app"> |
||||
|
<router-view class="flex-1 bg fill-width"></router-view> |
||||
|
</div> |
||||
|
</a-config-provider> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { mapState, mapActions, mapMutations } from 'vuex'; |
||||
|
import zh_CN from 'ant-design-vue/lib/locale-provider/zh_CN'; |
||||
|
export default { |
||||
|
name: 'App', |
||||
|
data() { |
||||
|
return { zh_CN }; |
||||
|
}, |
||||
|
computed: mapState('home', ['anyringToken']), |
||||
|
mounted() { |
||||
|
window.addEventListener('unload', this.saveState); |
||||
|
}, |
||||
|
async created() { |
||||
|
const userId = '1462629589099614208'; |
||||
|
const params = { userId }; |
||||
|
await this.getUserId(params); |
||||
|
await this.getToken(); |
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
...mapActions('home', ['getUserId']), |
||||
|
...mapMutations('home', ['getToken', 'setHistoryNum']), |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
html, |
||||
|
body, |
||||
|
#app { |
||||
|
min-height: 100%; |
||||
|
} |
||||
|
#app { |
||||
|
background: transparent; |
||||
|
} |
||||
|
body::-webkit-scrollbar { |
||||
|
width: 0; |
||||
|
} |
||||
|
/* .pt-46 { |
||||
|
padding-top: 46px; |
||||
|
} */ |
||||
|
</style> |
||||
|
|
||||
|
<style lang="stylus"> |
||||
|
@import './common/portrait.styl'; |
||||
|
</style> |
@ -0,0 +1,521 @@ |
|||||
|
// padding |
||||
|
.p-4{ |
||||
|
padding: 16px; |
||||
|
} |
||||
|
|
||||
|
.pa-3 { |
||||
|
padding: 12px; |
||||
|
} |
||||
|
|
||||
|
.pl-1{ |
||||
|
padding-left: 4px; |
||||
|
} |
||||
|
|
||||
|
.pl-2{ |
||||
|
padding-left: 8px; |
||||
|
} |
||||
|
|
||||
|
.pl-3{ |
||||
|
padding-left: 12px; |
||||
|
} |
||||
|
|
||||
|
.pl-4{ |
||||
|
padding-left: 16px; |
||||
|
} |
||||
|
|
||||
|
.pl-5{ |
||||
|
padding-left: 20px; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
.pr-1{ |
||||
|
padding-right: 4px; |
||||
|
} |
||||
|
|
||||
|
.pr-2{ |
||||
|
padding-right: 8px; |
||||
|
} |
||||
|
|
||||
|
.pr-3{ |
||||
|
padding-right: 12px; |
||||
|
} |
||||
|
|
||||
|
.pr-4{ |
||||
|
padding-right: 16px; |
||||
|
} |
||||
|
|
||||
|
.pr-5{ |
||||
|
padding-right: 20px; |
||||
|
} |
||||
|
|
||||
|
.px-1{ |
||||
|
padding-left: 4px; |
||||
|
padding-right: 4px; |
||||
|
} |
||||
|
|
||||
|
.px-2{ |
||||
|
padding-left: 8px; |
||||
|
padding-right: 8px; |
||||
|
} |
||||
|
|
||||
|
.px-3{ |
||||
|
padding-left: 12px; |
||||
|
padding-right: 12px; |
||||
|
} |
||||
|
|
||||
|
.px-4{ |
||||
|
padding-left: 16px; |
||||
|
padding-right: 16px; |
||||
|
} |
||||
|
|
||||
|
.px-10{ |
||||
|
padding-left: 30px; |
||||
|
padding-right: 30px; |
||||
|
} |
||||
|
|
||||
|
.py-1{ |
||||
|
padding-top: 4px; |
||||
|
padding-bottom: 4px; |
||||
|
} |
||||
|
|
||||
|
.py-2{ |
||||
|
padding-top: 8px; |
||||
|
padding-bottom: 8px; |
||||
|
} |
||||
|
|
||||
|
.py-3{ |
||||
|
padding-top: 12px; |
||||
|
padding-bottom: 12px; |
||||
|
} |
||||
|
|
||||
|
.pt-3 { |
||||
|
padding-top: 12px; |
||||
|
} |
||||
|
|
||||
|
.pb-3 { |
||||
|
padding-bottom: 12px; |
||||
|
} |
||||
|
|
||||
|
.pb-4 { |
||||
|
padding-bottom: 16px; |
||||
|
} |
||||
|
|
||||
|
.pb-5 { |
||||
|
padding-bottom: 20px; |
||||
|
} |
||||
|
|
||||
|
.pb-10 { |
||||
|
padding-bottom: 40px; |
||||
|
} |
||||
|
|
||||
|
// margin |
||||
|
.ma-2 { |
||||
|
margin: 8px; |
||||
|
} |
||||
|
|
||||
|
.ma-3 { |
||||
|
margin: 12px; |
||||
|
} |
||||
|
|
||||
|
.mx-2{ |
||||
|
margin-left: 8px; |
||||
|
margin-right: 8px; |
||||
|
} |
||||
|
|
||||
|
.mx-3{ |
||||
|
margin-left: 12px; |
||||
|
margin-right: 12px; |
||||
|
} |
||||
|
|
||||
|
.my-0{ |
||||
|
margin-top: 0px; |
||||
|
margin-bottom: 0px; |
||||
|
} |
||||
|
|
||||
|
.my-1{ |
||||
|
margin-top: 4px; |
||||
|
margin-bottom: 4px; |
||||
|
} |
||||
|
|
||||
|
.my-2{ |
||||
|
margin-top: 8px; |
||||
|
margin-bottom: 8px; |
||||
|
} |
||||
|
|
||||
|
.my-3{ |
||||
|
margin-top: 12px; |
||||
|
margin-bottom: 12px; |
||||
|
} |
||||
|
|
||||
|
.my-4{ |
||||
|
margin-top: 16px; |
||||
|
margin-bottom: 16px; |
||||
|
} |
||||
|
|
||||
|
.mt-1{ |
||||
|
margin-top: 4px; |
||||
|
} |
||||
|
|
||||
|
.mt-2{ |
||||
|
margin-top: 8px; |
||||
|
} |
||||
|
|
||||
|
.mt-3{ |
||||
|
margin-top: 12px; |
||||
|
} |
||||
|
|
||||
|
.mt-4{ |
||||
|
margin-top: 16px; |
||||
|
} |
||||
|
|
||||
|
.mb-0{ |
||||
|
margin-bottom: 0px; |
||||
|
} |
||||
|
|
||||
|
.mb-1{ |
||||
|
margin-bottom: 4px; |
||||
|
} |
||||
|
|
||||
|
.mb-2{ |
||||
|
margin-bottom: 8px; |
||||
|
} |
||||
|
|
||||
|
.mb-3{ |
||||
|
margin-bottom: 12px; |
||||
|
} |
||||
|
|
||||
|
.mb-4{ |
||||
|
margin-bottom: 16px; |
||||
|
} |
||||
|
|
||||
|
.mb-10{ |
||||
|
margin-bottom: 40px; |
||||
|
} |
||||
|
|
||||
|
.ml-1{ |
||||
|
margin-left: 4px; |
||||
|
} |
||||
|
|
||||
|
.ml-2{ |
||||
|
margin-left: 8px; |
||||
|
} |
||||
|
|
||||
|
.ml-3{ |
||||
|
margin-left: 12px; |
||||
|
} |
||||
|
|
||||
|
.ml-4{ |
||||
|
margin-left: 16px; |
||||
|
} |
||||
|
|
||||
|
.ml-5{ |
||||
|
margin-left: 20px; |
||||
|
} |
||||
|
|
||||
|
.ml-6{ |
||||
|
margin-left: 24px; |
||||
|
} |
||||
|
|
||||
|
.ml-7{ |
||||
|
margin-left: 28px; |
||||
|
} |
||||
|
|
||||
|
.ml-8{ |
||||
|
margin-left: 32px; |
||||
|
} |
||||
|
|
||||
|
.ml-9{ |
||||
|
margin-left: 36px; |
||||
|
} |
||||
|
|
||||
|
.ml-10{ |
||||
|
margin-left: 40px; |
||||
|
} |
||||
|
|
||||
|
.mr-1{ |
||||
|
margin-right: 4px; |
||||
|
} |
||||
|
|
||||
|
.mr-2{ |
||||
|
margin-right: 8px; |
||||
|
} |
||||
|
|
||||
|
.mr-3{ |
||||
|
margin-right: 12px; |
||||
|
} |
||||
|
|
||||
|
.mr-4{ |
||||
|
margin-right: 16px; |
||||
|
} |
||||
|
|
||||
|
.mr-5{ |
||||
|
margin-right: 20px; |
||||
|
} |
||||
|
|
||||
|
.mr-6{ |
||||
|
margin-right: 24px; |
||||
|
} |
||||
|
|
||||
|
// background |
||||
|
.white { |
||||
|
background: white; |
||||
|
} |
||||
|
|
||||
|
.green{ |
||||
|
background: #4CAF50; |
||||
|
} |
||||
|
|
||||
|
.blue{ |
||||
|
background: #1890ff; |
||||
|
} |
||||
|
|
||||
|
.gray{ |
||||
|
background: #CCCCCC; |
||||
|
} |
||||
|
|
||||
|
.white--text{ |
||||
|
color: #fff; |
||||
|
width: 100px; |
||||
|
margin: 0 auto |
||||
|
} |
||||
|
.bot-right-btn{ |
||||
|
position: fixed; |
||||
|
height: 40px; |
||||
|
right: 6px; |
||||
|
bottom: 20px; |
||||
|
} |
||||
|
.bot-right-tips { |
||||
|
position: fixed; |
||||
|
height: 40px; |
||||
|
font-size: 14px; |
||||
|
right: 18px; |
||||
|
top: 0; |
||||
|
} |
||||
|
// flex |
||||
|
.d-flex{ |
||||
|
display: flex; |
||||
|
} |
||||
|
|
||||
|
.flex-wrap{ |
||||
|
flex-wrap: wrap; |
||||
|
} |
||||
|
|
||||
|
.flex-nowrap{ |
||||
|
flex-wrap: nowrap; |
||||
|
} |
||||
|
|
||||
|
.flex-column{ |
||||
|
flex-direction: column; |
||||
|
} |
||||
|
|
||||
|
.flex-column-reverse{ |
||||
|
flex-direction: column-reverse; |
||||
|
} |
||||
|
|
||||
|
.flex-row{ |
||||
|
flex-direction: row; |
||||
|
} |
||||
|
|
||||
|
.flex-row-reverse{ |
||||
|
flex-direction: row-reverse; |
||||
|
} |
||||
|
|
||||
|
.justify-center{ |
||||
|
justify-content: center; |
||||
|
} |
||||
|
.justify-space-evenly{ |
||||
|
justify-content: space-evenly; |
||||
|
} |
||||
|
.justify-space-between{ |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
|
||||
|
.justify-flex-end{ |
||||
|
justify-content: flex-end; |
||||
|
} |
||||
|
|
||||
|
.align-center{ |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.align-left{ |
||||
|
align-items: start; |
||||
|
} |
||||
|
|
||||
|
.flex-1{ |
||||
|
display: flex; |
||||
|
flex: 1; |
||||
|
} |
||||
|
|
||||
|
.flex-2{ |
||||
|
display: flex; |
||||
|
flex: 2; |
||||
|
} |
||||
|
// other |
||||
|
.pointer{ |
||||
|
cursor:pointer; |
||||
|
} |
||||
|
|
||||
|
.pointerEdit { |
||||
|
font-size: 16px; |
||||
|
margin-right: 20px; |
||||
|
} |
||||
|
|
||||
|
.fill-height{ |
||||
|
height:100%; |
||||
|
} |
||||
|
|
||||
|
// font |
||||
|
.font-bold{ |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
.font-bold-24{ |
||||
|
font-size: 24px; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
.font-24{ |
||||
|
font-size: 24px; |
||||
|
} |
||||
|
|
||||
|
.font-bold-18{ |
||||
|
font-size: 18px; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
.font-18{ |
||||
|
font-size: 18px; |
||||
|
} |
||||
|
|
||||
|
.font-bold-16{ |
||||
|
font-size: 16px; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
.font-16{ |
||||
|
font-size: 16px; |
||||
|
} |
||||
|
|
||||
|
.font-bold-14{ |
||||
|
font-size: 14px; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
.font-14{ |
||||
|
font-size: 14px; |
||||
|
} |
||||
|
|
||||
|
.font-12{ |
||||
|
font-size: 12px; |
||||
|
} |
||||
|
|
||||
|
.icon-size{ |
||||
|
font-size: 20px; |
||||
|
} |
||||
|
|
||||
|
h2{ |
||||
|
font-size: 24px; |
||||
|
font-weight: bold; |
||||
|
color: rgba(0,0,0,.85) |
||||
|
} |
||||
|
|
||||
|
.textColor{ |
||||
|
color: rgba(0,0,0,.65) |
||||
|
} |
||||
|
|
||||
|
.text-white{ |
||||
|
color: #fff |
||||
|
} |
||||
|
|
||||
|
.text-red{ |
||||
|
color: #EB3527 |
||||
|
} |
||||
|
|
||||
|
.gray-text{ |
||||
|
color: #bbb |
||||
|
} |
||||
|
|
||||
|
.baseColor{ |
||||
|
color: #1890ff |
||||
|
} |
||||
|
|
||||
|
.bg{ |
||||
|
background: #EDEDED; |
||||
|
} |
||||
|
|
||||
|
.fill-width{ |
||||
|
width:100%; |
||||
|
} |
||||
|
|
||||
|
.fill-height{ |
||||
|
height:100%; |
||||
|
} |
||||
|
|
||||
|
// .ant-form-item-label { |
||||
|
// text-align: left; |
||||
|
// } |
||||
|
|
||||
|
// .ant-form-item-control { |
||||
|
// width:100% |
||||
|
// } |
||||
|
.ant-form-item-children(:only-child) { |
||||
|
display: flex; |
||||
|
flex-wrap: nowrap; |
||||
|
} |
||||
|
.ant-card-head-title { |
||||
|
font-weight: 600 !important; |
||||
|
font-size: 18px !important; |
||||
|
} |
||||
|
.ant-card-bordered { |
||||
|
border-radius: 10px; |
||||
|
} |
||||
|
|
||||
|
.ant-spin-nested-loading > div > .ant-spin .ant-spin-dot { |
||||
|
position: fixed; |
||||
|
top: 50%; |
||||
|
left: 50%; |
||||
|
margin: -10px; |
||||
|
} |
||||
|
|
||||
|
.ant-list-bordered { |
||||
|
border: none; |
||||
|
border-radius: 4px |
||||
|
} |
||||
|
|
||||
|
.ant-collapse { |
||||
|
background-color: none; |
||||
|
border: none |
||||
|
} |
||||
|
|
||||
|
.w-screen{ |
||||
|
width: 100vw; |
||||
|
} |
||||
|
|
||||
|
.h-screen{ |
||||
|
height: 100vh; |
||||
|
} |
||||
|
|
||||
|
.text-center{ |
||||
|
text-align: center; |
||||
|
} |
||||
|
.bg-white { |
||||
|
background-color:white; |
||||
|
} |
||||
|
.ant-list-item { |
||||
|
min-height: 54px; |
||||
|
} |
||||
|
.ant-list-bordered .ant-list-item { |
||||
|
padding-right: 16px; |
||||
|
padding-left: 16px; |
||||
|
border-bottom: 1px solid #e8e8e8; |
||||
|
} |
||||
|
.ant-list { |
||||
|
color: #3B3B3B; |
||||
|
} |
||||
|
.ant-list-empty-text { |
||||
|
display: none; |
||||
|
} |
||||
|
.ant-calendar { |
||||
|
margin: auto !important; |
||||
|
} |
@ -0,0 +1,101 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<a-modal title="增加医院" :visible="visible" @ok="handleOk" @cancel="handleCancel" :width="800"> |
||||
|
<a-form :form="form" :label-col="{ span: 5 }" :wrapper-col="{ span: 12 }"> |
||||
|
<a-form-item label="省"> |
||||
|
<a-select default-value="1"> |
||||
|
<a-select-option value="1"> 山西省 </a-select-option> |
||||
|
</a-select> |
||||
|
</a-form-item> |
||||
|
<a-form-item label="市/区"> |
||||
|
<a-cascader |
||||
|
:field-names="{ label: 'name', value: 'id', children: 'child' }" |
||||
|
:options="options" |
||||
|
placeholder="市/区" |
||||
|
@change="changeArea" |
||||
|
/> |
||||
|
</a-form-item> |
||||
|
<a-form-item label="医院等级"> |
||||
|
<a-select placeholder="医院等级" allow-clear @change="changeProvince"> |
||||
|
<a-select-option v-for="(item, index) in levelList" :value="item.levelId" :key="index"> {{ item.name }} </a-select-option> |
||||
|
</a-select> |
||||
|
</a-form-item> |
||||
|
<a-form-item label="医院名称"> |
||||
|
<a-input v-model="hospitalName" placeholder="医院名称" /> |
||||
|
</a-form-item> |
||||
|
</a-form> |
||||
|
</a-modal> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
import { addHospital } from 'config/api'; |
||||
|
|
||||
|
export default { |
||||
|
props: { |
||||
|
visible: { |
||||
|
default: true, |
||||
|
type: Boolean, |
||||
|
}, |
||||
|
options: { |
||||
|
default: () => [], |
||||
|
type: Array, |
||||
|
}, |
||||
|
levelList: { |
||||
|
default: () => [], |
||||
|
type: Array, |
||||
|
}, |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
formLayout: 'horizontal', |
||||
|
form: this.$form.createForm(this, { name: 'coordinated' }), |
||||
|
hospitalName: '', // 医院名称 |
||||
|
cityId: '', // 市id |
||||
|
countyId: '', // 区id |
||||
|
levelId: '', // 医院等级id |
||||
|
}; |
||||
|
}, |
||||
|
methods: { |
||||
|
// 点击确定按钮 |
||||
|
handleCancel() { |
||||
|
this.$emit('showModal'); |
||||
|
}, |
||||
|
// 点击了取消 |
||||
|
async handleOk() { |
||||
|
try { |
||||
|
const params = { |
||||
|
param: { |
||||
|
cityId: this.cityId, |
||||
|
countyId: this.countyId, |
||||
|
levelId: this.levelId, |
||||
|
name: this.hospitalName, |
||||
|
provinceId: '140000', |
||||
|
}, |
||||
|
}; |
||||
|
const res = await addHospital(params); |
||||
|
const { code, msg, data } = res.data; |
||||
|
if (code === 200) { |
||||
|
this.$message.success('添加成功'); |
||||
|
this.$emit('showModal'); |
||||
|
this.$emit('getHosList'); |
||||
|
} else { |
||||
|
this.$message.warning(msg); |
||||
|
} |
||||
|
} catch (error) { |
||||
|
this.$message.warning(error); |
||||
|
} |
||||
|
}, |
||||
|
// 选择市区 |
||||
|
changeArea(e) { |
||||
|
this.cityId = e[0]; |
||||
|
this.countyId = e[1]; |
||||
|
}, |
||||
|
// 选择医院等级 |
||||
|
changeProvince(e) { |
||||
|
this.levelId = e; |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
||||
|
<style scoped> |
||||
|
</style> |
@ -0,0 +1,192 @@ |
|||||
|
<template> |
||||
|
<div class="d-flex flex-column left-box white"> |
||||
|
<div class="shadow-box"> |
||||
|
<div class="px-4 d-flex justify-space-between mt-4"> |
||||
|
<a-select default-value="1" style="width: 120px"> |
||||
|
<a-select-option value="1"> 山西省 </a-select-option> |
||||
|
</a-select> |
||||
|
<a-cascader |
||||
|
:field-names="{ label: 'name', value: 'id', children: 'child' }" |
||||
|
:options="options" |
||||
|
style="width: 120px" |
||||
|
placeholder="市/区" |
||||
|
@change="changeArea" |
||||
|
/> |
||||
|
<a-select placeholder="医院等级" allow-clear style="width: 120px" @change="changeProvince"> |
||||
|
<a-select-option v-for="(item, index) in levalList" :value="item.levelId" :key="index"> {{ item.name }} </a-select-option> |
||||
|
</a-select> |
||||
|
</div> |
||||
|
<div class="d-flex px-4 mt-4"> |
||||
|
<a-input-search placeholder="请输入医院名称" style="width: 100%" @search="onSearch" /> |
||||
|
<a-button class="ml-8" type="primary" icon="plus" @click="showAdd">增加</a-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="flex-1 hospital-box" @scroll="scrollY"> |
||||
|
<a-list bordered :data-source="list" class="fill-width"> |
||||
|
<a-list-item :class="hospitalInfo.id === item.id ? 'active' : ''" slot="renderItem" slot-scope="item" @click="chooseHospital(item)"> |
||||
|
{{ item.name }} |
||||
|
</a-list-item> |
||||
|
</a-list> |
||||
|
</div> |
||||
|
<div class="go-top d-flex justify-center align-center flex-column" @click="gotTop" v-if="showToTop"> |
||||
|
<a-icon type="up" style="font-size: 24px" /> |
||||
|
<div>回到顶部</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
import { queryLevel, queryArea, queryHospitalList } from 'config/api'; |
||||
|
import { mapMutations, mapState } from 'vuex'; |
||||
|
|
||||
|
export default { |
||||
|
name: 'HospitalList', |
||||
|
data() { |
||||
|
return { |
||||
|
levalList: [{ levelId: '4', name: '特等' }], |
||||
|
list: [], |
||||
|
options: [], |
||||
|
showToTop: false, |
||||
|
cityId: '', |
||||
|
countyId: '', |
||||
|
levelId: '', |
||||
|
name: '', |
||||
|
}; |
||||
|
}, |
||||
|
computed: { ...mapState('home', ['hospitalInfo']) }, |
||||
|
created() { |
||||
|
this.getArea(); |
||||
|
this.getLevel(); |
||||
|
this.getHospitalList(); |
||||
|
}, |
||||
|
methods: { |
||||
|
...mapMutations('home', ['setHospitalInfo']), |
||||
|
// 选择医院 |
||||
|
chooseHospital(info) { |
||||
|
this.setHospitalInfo(info); |
||||
|
}, |
||||
|
// 修改地区 |
||||
|
changeArea(e) { |
||||
|
this.cityId = e[0]; |
||||
|
this.countyId = e[1]; |
||||
|
this.getHospitalList(); |
||||
|
}, |
||||
|
changeProvince(e) { |
||||
|
this.levelId = e; |
||||
|
this.getHospitalList(); |
||||
|
}, |
||||
|
onSearch(e) { |
||||
|
this.name = e; |
||||
|
this.getHospitalList(); |
||||
|
}, |
||||
|
// 回到医院列表的首页 |
||||
|
gotTop() { |
||||
|
var dom = document.getElementsByClassName('hospital-box')[0]; |
||||
|
dom.scrollTo(0, 0); |
||||
|
}, |
||||
|
// 医院列表滚动时 |
||||
|
scrollY() { |
||||
|
var dom = document.getElementsByClassName('hospital-box')[0]; |
||||
|
this.showToTop = dom.scrollTop > 200; |
||||
|
}, |
||||
|
// 显示增加医院弹框 |
||||
|
showAdd() { |
||||
|
this.$emit('showModal', this.options, this.levalList); |
||||
|
}, |
||||
|
// 获取地区信息 |
||||
|
async getArea() { |
||||
|
try { |
||||
|
const params = { param: { id: 140000 } }; |
||||
|
const res = await queryArea(params); |
||||
|
const { code, data, msg } = res.data; |
||||
|
if (code === 200) { |
||||
|
this.options = data; |
||||
|
} else { |
||||
|
console.error(msg); |
||||
|
} |
||||
|
} catch (error) { |
||||
|
this.$message.error('查询地区信息错误:', error); |
||||
|
} |
||||
|
}, |
||||
|
// 获取医院等级 |
||||
|
async getLevel() { |
||||
|
try { |
||||
|
const params = { param: {} }; |
||||
|
const res = await queryLevel(params); |
||||
|
const { code, data, msg } = res.data; |
||||
|
if (code === 200) { |
||||
|
this.levalList = data; |
||||
|
} else { |
||||
|
console.error(msg); |
||||
|
} |
||||
|
} catch (error) { |
||||
|
this.$message.error('查询医院等级错误:', error); |
||||
|
} |
||||
|
}, |
||||
|
// 获取医院列表 |
||||
|
async getHospitalList() { |
||||
|
try { |
||||
|
const params = { |
||||
|
param: { |
||||
|
cityId: this.cityId, |
||||
|
countyId: this.countyId, |
||||
|
levelId: this.levelId, |
||||
|
name: this.name, |
||||
|
provinceId: '', |
||||
|
}, |
||||
|
}; |
||||
|
const res = await queryHospitalList(params); |
||||
|
const { code, data, msg } = res.data; |
||||
|
if (code === 200) { |
||||
|
this.list = data; |
||||
|
} else { |
||||
|
console.error(msg); |
||||
|
} |
||||
|
} catch (error) { |
||||
|
this.$message.error('获取医院列表失败:', error); |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
||||
|
<style scoped> |
||||
|
.active { |
||||
|
background: rgba(64, 169, 255, 0.3) !important; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
/deep/ .ant-list-item { |
||||
|
cursor: pointer; |
||||
|
font-size: 16px; |
||||
|
} |
||||
|
/deep/ .ant-list-item:hover { |
||||
|
background: rgba(64, 169, 255, 0.1); |
||||
|
} |
||||
|
.go-top { |
||||
|
height: 60px; |
||||
|
width: 60px; |
||||
|
border-radius: 8px; |
||||
|
position: absolute; |
||||
|
bottom: 40px; |
||||
|
right: 16px; |
||||
|
background: #40a9ff; |
||||
|
font-size: 12px; |
||||
|
color: #fff; |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
.left-box { |
||||
|
position: relative; |
||||
|
width: 460px; |
||||
|
box-shadow: 0 0 20px rgba(0, 0, 0, 0.2); |
||||
|
max-height: 100vh; |
||||
|
} |
||||
|
.shadow-box { |
||||
|
box-shadow: 0 10px 10px rgba(0, 0, 0, 0.1); |
||||
|
padding-bottom: 16px; |
||||
|
} |
||||
|
.hospital-box { |
||||
|
overflow-y: scroll; |
||||
|
} |
||||
|
|
||||
|
.hospital-box::-webkit-scrollbar { |
||||
|
display: none; /* Chrome Safari */ |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,186 @@ |
|||||
|
<template> |
||||
|
<div class="d-flex flex-column p-4" style="max-height: 100vh"> |
||||
|
<div class="hos-name hos-shadow white mb-2">{{ hospitalInfo.name }}</div> |
||||
|
<div class="d-flex justify-space-between tree-title white"> |
||||
|
<div class="d-flex"> |
||||
|
<!-- <div class="mr-4 cursor-pointer"> |
||||
|
<a-checkbox @change="changeChooseAll"> 全选 </a-checkbox> |
||||
|
</div> --> |
||||
|
<div class="mr-4 cursor-pointer d-flex align-center" @click="fold"><a-icon class="mr-2" type="menu-unfold" />全部折叠</div> |
||||
|
<div class="cursor-pointer d-flex align-center" @click="open"><a-icon class="mr-2" type="menu-fold" />全部展开</div> |
||||
|
</div> |
||||
|
<div class="d-flex align-center"> |
||||
|
<a-input-search style="width: 260px" class="mr-4" placeholder="搜索部门/职位/角色" @change="onChange" /> |
||||
|
<a-button type="primary" icon="plus">新建部门</a-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="right-box flex-1 hos-box hos-shadow white"> |
||||
|
<TreeNode |
||||
|
ref="tree-node" |
||||
|
class="fill-width" |
||||
|
v-if="treeData.length" |
||||
|
:tree-data="treeData" |
||||
|
@showAddItem="showAddItem" |
||||
|
@showEditItem="showEditItem" |
||||
|
@showAddMember="showAddMember" |
||||
|
@showEditMember="showEditMember" |
||||
|
/> |
||||
|
</div> |
||||
|
<a-modal :visible="visible" title="添加部门/职位" @cancel="visible = false" @ok="handleOk"> |
||||
|
添加部门/职位 |
||||
|
{{ addId }} |
||||
|
</a-modal> |
||||
|
<a-modal :visible="visible2" title="修改部门信息" @cancel="visible2 = false" @ok="handleOk"> 修改部门信息 </a-modal> |
||||
|
<a-modal :visible="visible1" title="添加成员" @cancel="visible1 = false" @ok="handleOk"> |
||||
|
添加成员 |
||||
|
{{ addId }} |
||||
|
</a-modal> |
||||
|
<a-modal :visible="visible3" title="修改成员信息" @cancel="visible3 = false" @ok="handleOk"> 修改成员信息 </a-modal> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
import { mapState } from 'vuex'; |
||||
|
import { queryHospitalInfo } from 'config/api'; |
||||
|
import TreeNode from './TreeNode.vue'; |
||||
|
|
||||
|
export default { |
||||
|
components: { TreeNode }, |
||||
|
data() { |
||||
|
return { |
||||
|
treeData: [], |
||||
|
isSelect: '', |
||||
|
visible: false, |
||||
|
visible1: false, |
||||
|
visible2: false, |
||||
|
visible3: false, |
||||
|
addId: '', |
||||
|
}; |
||||
|
}, |
||||
|
computed: { ...mapState('home', ['hospitalInfo']) }, |
||||
|
watch: { |
||||
|
hospitalInfo() { |
||||
|
this.getHospitalInfo(); |
||||
|
}, |
||||
|
}, |
||||
|
created() { |
||||
|
this.getHospitalInfo(); |
||||
|
}, |
||||
|
methods: { |
||||
|
// 全选 |
||||
|
changeChooseAll(e) { |
||||
|
// console.log(e.target.checked); |
||||
|
var child = this.$refs['tree-node']; |
||||
|
child.chooseAll(e.target.checked); |
||||
|
}, |
||||
|
// 全部折叠 |
||||
|
fold() { |
||||
|
var child = this.$refs['tree-node']; |
||||
|
child.foldAll(); |
||||
|
}, |
||||
|
// 全部展开 |
||||
|
open() { |
||||
|
var child = this.$refs['tree-node']; |
||||
|
child.openAll(); |
||||
|
}, |
||||
|
// 获取医院详情 |
||||
|
async getHospitalInfo() { |
||||
|
try { |
||||
|
this.treeData = []; |
||||
|
const params = { param: { id: this.hospitalInfo.id } }; |
||||
|
const res = await queryHospitalInfo(params); |
||||
|
const { code, msg, data } = res.data; |
||||
|
if (code === 200) { |
||||
|
console.log(data); |
||||
|
this.treeData = data; |
||||
|
} else { |
||||
|
console.error(msg); |
||||
|
} |
||||
|
} catch (error) { |
||||
|
this.$message.error('医院详情查询失败:', error); |
||||
|
} |
||||
|
}, |
||||
|
// 添加职位/角色 |
||||
|
handleOk() { |
||||
|
this.visible = false; |
||||
|
}, |
||||
|
// 添加部门/职位modal框 |
||||
|
showAddItem(id) { |
||||
|
this.addId = id; |
||||
|
this.visible = true; |
||||
|
}, |
||||
|
// 修改部门/职位modal框 |
||||
|
showEditItem(item) { |
||||
|
console.log('item: ', item); |
||||
|
this.visible2 = true; |
||||
|
}, |
||||
|
// 添加成员modal框 |
||||
|
showAddMember(id) { |
||||
|
this.addId = id; |
||||
|
this.visible1 = true; |
||||
|
}, |
||||
|
// 修改成员modal框 |
||||
|
showEditMember(item) { |
||||
|
console.log('item: ', item); |
||||
|
this.visible3 = true; |
||||
|
}, |
||||
|
// 搜索部门/职位/角色 |
||||
|
onChange(e) { |
||||
|
const value = e.target.value; |
||||
|
const expandedKeys = dataList |
||||
|
.map(item => { |
||||
|
if (item.title.indexOf(value) > -1) { |
||||
|
return getParentKey(item.key, gData); |
||||
|
} |
||||
|
return null; |
||||
|
}) |
||||
|
.filter((item, i, self) => item && self.indexOf(item) === i); |
||||
|
Object.assign(this, { |
||||
|
expandedKeys, |
||||
|
searchValue: value, |
||||
|
autoExpandParent: true, |
||||
|
}); |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang="less" scoped> |
||||
|
.right-box { |
||||
|
overflow-y: scroll; |
||||
|
} |
||||
|
.right-box::-webkit-scrollbar { |
||||
|
width: 0; |
||||
|
} |
||||
|
/deep/.ant-tree li span.ant-tree-switcher, |
||||
|
.ant-tree li span.ant-tree-iconEle { |
||||
|
margin-top: 8px !important; |
||||
|
} |
||||
|
/deep/.ant-tree li { |
||||
|
min-height: 54px; |
||||
|
line-height: 40px; |
||||
|
} |
||||
|
/deep/.ant-tree li .ant-tree-node-content-wrapper { |
||||
|
min-height: 40px; |
||||
|
line-height: 40px; |
||||
|
} |
||||
|
.hos-name { |
||||
|
font-size: 20px; |
||||
|
font-weight: bold; |
||||
|
color: rgba(0, 0, 0, 0.85); |
||||
|
} |
||||
|
.hos-shadow { |
||||
|
border-radius: 4px; |
||||
|
padding: 8px 16px; |
||||
|
box-shadow: 0 0 6px rgba(0, 0, 0, 0.15); |
||||
|
} |
||||
|
.tree-title { |
||||
|
border-radius: 4px; |
||||
|
padding: 16px; |
||||
|
box-shadow: 0 0 6px rgba(0, 0, 0, 0.15); |
||||
|
color: rgba(0, 0, 0, 0.5); |
||||
|
font-size: 16px; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
.cursor-pointer { |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,202 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<a-tree |
||||
|
v-model="checkedKeys" |
||||
|
:expanded-keys="expandedKeys" |
||||
|
@expand="onExpand" |
||||
|
:auto-expand-parent="autoExpandParent" |
||||
|
class="fill-width" |
||||
|
:block-node="true" |
||||
|
@select="onSelect" |
||||
|
:checkable="false" |
||||
|
> |
||||
|
<a-tree-node v-for="item in treeData" :key="item.did"> |
||||
|
<a-tree-node v-for="itemA in item.positionInfoList" :key="item.did + itemA.pid"> |
||||
|
<a-tree-node v-for="itemB in itemA.memberInfoList" :key="itemA.pid + itemB.mid"> |
||||
|
<div class="d-flex flex-row justify-space-between align-center" slot="title"> |
||||
|
<div>{{ itemB.mname }},{{ itemB.phone }}</div> |
||||
|
</div> |
||||
|
</a-tree-node> |
||||
|
<div class="d-flex flex-row justify-space-between align-center" slot="title"> |
||||
|
<div> |
||||
|
{{ itemA.pname }} |
||||
|
<a-tag color="blue" class="ml-2" v-for="tag in itemA.roleList" :key="tag.rid"> |
||||
|
{{ tag.rname }} |
||||
|
</a-tag> |
||||
|
</div> |
||||
|
<div> |
||||
|
<a-icon |
||||
|
class="mr-2" |
||||
|
:style="{ fontSize: '20px' }" |
||||
|
v-if="isSelect === item.did + itemA.pid" |
||||
|
type="plus" |
||||
|
@click="showAddMember(itemA.did)" |
||||
|
></a-icon> |
||||
|
<a-icon |
||||
|
class="mr-2" |
||||
|
:style="{ fontSize: '20px' }" |
||||
|
v-if="isSelect === item.did + itemA.pid" |
||||
|
type="more" |
||||
|
@click="showEditMember(itemA)" |
||||
|
/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</a-tree-node> |
||||
|
<div class="d-flex flex-row justify-space-between align-center" slot="title"> |
||||
|
<div> |
||||
|
{{ item.departmentName }} |
||||
|
<a-tag color="#87d068" class="ml-2" style="border-radius: 10px"> |
||||
|
{{ (item.positionInfoList ? item.positionInfoList.length : 0) + (item.sonDepartment ? item.sonDepartment.length : 0) }} |
||||
|
</a-tag> |
||||
|
</div> |
||||
|
<div> |
||||
|
<a-icon |
||||
|
class="mr-2" |
||||
|
:style="{ fontSize: '20px' }" |
||||
|
v-if="isSelect === item.did" |
||||
|
type="plus" |
||||
|
@click="showAddItem(item.did)" |
||||
|
></a-icon> |
||||
|
<a-icon class="mr-2" :style="{ fontSize: '20px' }" v-if="isSelect === item.did" type="more" @click="showEditItem(item)" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
<TreeNode |
||||
|
ref="tree-node" |
||||
|
v-if="item.sonDepartment" |
||||
|
:tree-data="item.sonDepartment" |
||||
|
@showAddItem="showAddItem" |
||||
|
@showEditItem="showEditItem" |
||||
|
@showAddMember="showAddMember" |
||||
|
@showEditMember="showEditMember" |
||||
|
/> |
||||
|
</a-tree-node> |
||||
|
</a-tree> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
import TreeNode from './TreeNode.vue'; |
||||
|
|
||||
|
export default { |
||||
|
isTreeNode: true, |
||||
|
components: { TreeNode }, |
||||
|
props: { |
||||
|
treeData: { |
||||
|
default: () => [], |
||||
|
type: Array, |
||||
|
}, |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
isSelect: '', |
||||
|
expandedKeys: [], |
||||
|
autoExpandParent: true, |
||||
|
checkedKeys: [], |
||||
|
}; |
||||
|
}, |
||||
|
watch: { |
||||
|
treeData: { |
||||
|
handler() { |
||||
|
this.expandedKeys = []; |
||||
|
if (this.treeData.length) { |
||||
|
for (let i = 0; i < this.treeData.length; i++) { |
||||
|
this.expandedKeys.push(this.treeData[i].did); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
deep: true, |
||||
|
}, |
||||
|
}, |
||||
|
created() { |
||||
|
this.expandedKeys = []; |
||||
|
if (this.treeData.length) { |
||||
|
for (let i = 0; i < this.treeData.length; i++) { |
||||
|
this.expandedKeys.push(this.treeData[i].did); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
onSelect(selectedKeys, info) { |
||||
|
console.log('selected', selectedKeys, info); |
||||
|
this.isSelect = selectedKeys[0]; |
||||
|
}, |
||||
|
showAddItem(id) { |
||||
|
this.$emit('showAddItem', id); |
||||
|
}, |
||||
|
showEditItem(item) { |
||||
|
this.$emit('showEditItem', item); |
||||
|
}, |
||||
|
showAddMember(id) { |
||||
|
this.$emit('showAddMember', id); |
||||
|
}, |
||||
|
showEditMember(item) { |
||||
|
this.$emit('showEditMember', item); |
||||
|
}, |
||||
|
onExpand(expandedKeys) { |
||||
|
this.expandedKeys = expandedKeys; |
||||
|
this.autoExpandParent = false; |
||||
|
}, |
||||
|
// 全部折叠 |
||||
|
foldAll() { |
||||
|
this.expandedKeys = []; |
||||
|
}, |
||||
|
// 全部展开 |
||||
|
openAll() { |
||||
|
var expandedKeys = []; |
||||
|
if (this.treeData.length) { |
||||
|
for (let i = 0; i < this.treeData.length; i++) { |
||||
|
const item = this.treeData[i]; |
||||
|
expandedKeys.push(item.did); |
||||
|
for (let j = 0; j < item.positionInfoList.length; j++) { |
||||
|
const itemA = item.positionInfoList[j]; |
||||
|
expandedKeys.push(item.did + itemA.pid); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
this.expandedKeys = expandedKeys; |
||||
|
var child = this.$refs['tree-node']; |
||||
|
console.log('child: ', child); |
||||
|
if (child) { |
||||
|
child.foldAll(); |
||||
|
} |
||||
|
}, |
||||
|
// 全选/取消全选 |
||||
|
chooseAll(isTrue) { |
||||
|
if (isTrue) { |
||||
|
var checkedKeys = []; |
||||
|
if (this.treeData.length) { |
||||
|
for (let i = 0; i < this.treeData.length; i++) { |
||||
|
const item = this.treeData[i]; |
||||
|
checkedKeys.push(item.did); |
||||
|
for (let j = 0; j < item.positionInfoList.length; j++) { |
||||
|
const itemA = item.positionInfoList[j]; |
||||
|
checkedKeys.push(item.did + itemA.pid); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
this.checkedKeys = checkedKeys; |
||||
|
var child = this.$refs['tree-node']; |
||||
|
if (child) { |
||||
|
child.foldAll(); |
||||
|
} |
||||
|
} else { |
||||
|
this.checkedKeys = []; |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang="less" scoped> |
||||
|
/deep/.ant-tree li span.ant-tree-switcher, |
||||
|
.ant-tree li span.ant-tree-iconEle { |
||||
|
margin-top: 8px !important; |
||||
|
} |
||||
|
/deep/.ant-tree li { |
||||
|
min-height: 54px; |
||||
|
line-height: 40px; |
||||
|
font-size: 16px; |
||||
|
} |
||||
|
/deep/.ant-tree li .ant-tree-node-content-wrapper { |
||||
|
min-height: 40px; |
||||
|
line-height: 40px; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,20 @@ |
|||||
|
/* |
||||
|
* @Author: aBin |
||||
|
* @email: binbin0314@126.com |
||||
|
* @Date: 2021-05-31 17:25:39 |
||||
|
* @LastEditors: aBin |
||||
|
* @LastEditTime: 2021-06-02 15:27:56 |
||||
|
*/ |
||||
|
/* |
||||
|
* Copyright (c) 2020. |
||||
|
* author: wally |
||||
|
* email: 18603454788@163.com |
||||
|
*/ |
||||
|
import axios from 'axios'; |
||||
|
let { proxyUrl } = require('@/config/setting'); |
||||
|
|
||||
|
const tall = `${proxyUrl}/gateway/tall3/v3.0`; |
||||
|
const users = `${tall}/users`; |
||||
|
|
||||
|
// 查找用户详细信息
|
||||
|
export const getUserId = params => axios.get(`${users}/userId`, params); |
@ -0,0 +1,21 @@ |
|||||
|
import axios from 'axios'; |
||||
|
let { proxyUrl } = require('@/config/setting'); |
||||
|
|
||||
|
const qcp = `${proxyUrl}/gateway/carbasics/v4.0`; |
||||
|
const management = `${qcp}/management`; // 机构管理相关接口
|
||||
|
const questionnaire = `${qcp}/questionnaire`; // 查询问卷相关接口
|
||||
|
|
||||
|
// 查询医院列表
|
||||
|
export const queryHospitalList = params => axios.post(`${management}/queryHospitalList`, params); |
||||
|
|
||||
|
// 查询医院等级列表
|
||||
|
export const queryLevel = params => axios.post(`${management}/queryLevel`, params); |
||||
|
|
||||
|
// 查询地区
|
||||
|
export const queryArea = params => axios.post(`${questionnaire}/area`, params); |
||||
|
|
||||
|
// 添加医院
|
||||
|
export const addHospital = params => axios.post(`${management}/addHospital`, params); |
||||
|
|
||||
|
// 查询机构管理的医院详情
|
||||
|
export const queryHospitalInfo = params => axios.post(`${management}/queryHospitalInfo`, params); |
@ -0,0 +1,30 @@ |
|||||
|
const title = process.env.VUE_APP_TITLE; |
||||
|
const description = process.env.VUE_APP_DESCRIPTION; |
||||
|
const baseUrl = process.env.VUE_APP_BASE_URL; |
||||
|
const apiUrl = process.env.VUE_APP_API_URL; |
||||
|
const proxyUrl = process.env.VUE_APP_PROXY_URL; |
||||
|
const publicPath = process.env.VUE_APP_PUBLIC_PATH; |
||||
|
// const msgUrl = process.env.VUE_APP_MSG_URL;
|
||||
|
|
||||
|
module.exports = { |
||||
|
// 首页标题
|
||||
|
title, |
||||
|
|
||||
|
// 首页描述信息
|
||||
|
description, |
||||
|
|
||||
|
// 基础地址
|
||||
|
baseUrl, |
||||
|
|
||||
|
// api基础地址
|
||||
|
apiUrl, |
||||
|
|
||||
|
// 消息系统地址
|
||||
|
// msgUrl,
|
||||
|
|
||||
|
// api代理地址
|
||||
|
proxyUrl, |
||||
|
|
||||
|
// 生成文件目录 publicPath
|
||||
|
publicPath, |
||||
|
}; |
@ -0,0 +1,19 @@ |
|||||
|
/* |
||||
|
* Copyright (c) 2019. |
||||
|
* author: wally |
||||
|
* email: 18603454788@163.com |
||||
|
*/ |
||||
|
|
||||
|
// 用户登录client
|
||||
|
export const SIGN_IN_CLIENTS = { mp: 0, h5: 1, android: 2, ios: 3 }; |
||||
|
|
||||
|
// 用户登录类型
|
||||
|
export const SIGN_IN_TYPES = { |
||||
|
mp: 0, |
||||
|
phone: 1, |
||||
|
email: 2, |
||||
|
username: 3, |
||||
|
wx: 4, |
||||
|
wx_web: 5, |
||||
|
wb: 6, |
||||
|
}; |
@ -0,0 +1,36 @@ |
|||||
|
/* |
||||
|
* @Author: wally |
||||
|
* @email: 18603454788@163.com |
||||
|
* @Date: 2021-01-29 11:16:27 |
||||
|
* @LastEditors: Please set LastEditors |
||||
|
* @LastEditTime: 2021-07-29 09:51:17 |
||||
|
*/ |
||||
|
// @ts-ignore
|
||||
|
import Vue from 'vue'; |
||||
|
import './plugins/axios'; |
||||
|
import App from './App.vue'; |
||||
|
import './registerServiceWorker'; |
||||
|
import router from './router'; |
||||
|
import store from './store'; |
||||
|
import './plugins/ant-design-vue.js'; |
||||
|
import 'common/portrait.styl'; |
||||
|
import echarts from 'echarts'; |
||||
|
import 'echarts-gl'; |
||||
|
// import 'echarts/map/js/province/shanxi.js'; //对应的省份
|
||||
|
import './plugins/vue-quill-editor.js'; |
||||
|
// import VueDOMPurifyHTML from 'vue-dompurify-html';
|
||||
|
// import VConsole from 'vconsole';
|
||||
|
|
||||
|
// const vConsole = new VConsole();
|
||||
|
// console.log('Hello world');
|
||||
|
// vConsole.destroy();
|
||||
|
Vue.prototype.$echarts = echarts; |
||||
|
import moment from 'moment'; //导入文件
|
||||
|
Vue.prototype.$moment = moment; //赋值使用
|
||||
|
Vue.config.productionTip = false; |
||||
|
|
||||
|
window.vm = new Vue({ |
||||
|
router, |
||||
|
store, |
||||
|
render: h => h(App), |
||||
|
}).$mount('#app'); |
@ -0,0 +1,102 @@ |
|||||
|
/* |
||||
|
* @Author: wally |
||||
|
* @email: 18603454788@163.com |
||||
|
* @Date: 2021-01-29 11:16:27 |
||||
|
* @LastEditors: aBin |
||||
|
* @LastEditTime: 2021-06-02 10:10:30 |
||||
|
*/ |
||||
|
import Vue from 'vue'; |
||||
|
import { |
||||
|
Pagination, |
||||
|
Button, |
||||
|
Input, |
||||
|
InputNumber, |
||||
|
message, |
||||
|
notification, |
||||
|
Modal, |
||||
|
Tag, |
||||
|
Table, |
||||
|
Tabs, |
||||
|
Icon, |
||||
|
Empty, |
||||
|
Form, |
||||
|
Select, |
||||
|
Upload, |
||||
|
Badge, |
||||
|
Popconfirm, |
||||
|
DatePicker, |
||||
|
Switch, |
||||
|
Radio, |
||||
|
Dropdown, |
||||
|
Menu, |
||||
|
Row, |
||||
|
Col, |
||||
|
Timeline, |
||||
|
Checkbox, |
||||
|
BackTop, |
||||
|
Progress, |
||||
|
Carousel, |
||||
|
Spin, |
||||
|
Card, |
||||
|
List, |
||||
|
Collapse, |
||||
|
Cascader, |
||||
|
TimePicker, |
||||
|
Divider, |
||||
|
Tooltip, |
||||
|
Affix, |
||||
|
Drawer, |
||||
|
Tree, |
||||
|
} from 'ant-design-vue'; |
||||
|
import { ConfigProvider } from 'ant-design-vue'; |
||||
|
Vue.component(ConfigProvider.name, ConfigProvider); |
||||
|
Vue.use(Pagination); |
||||
|
Vue.use(Tooltip); |
||||
|
Vue.use(Button); |
||||
|
Vue.use(Input); |
||||
|
Vue.use(Modal); |
||||
|
Vue.use(Tag); |
||||
|
Vue.use(Table); |
||||
|
Vue.use(Tabs); |
||||
|
Vue.use(Icon); |
||||
|
Vue.use(Empty); |
||||
|
Vue.use(Form); |
||||
|
Vue.use(Select); |
||||
|
Vue.use(Upload); |
||||
|
Vue.use(Badge); |
||||
|
Vue.use(Popconfirm); |
||||
|
Vue.use(DatePicker); |
||||
|
Vue.use(Switch); |
||||
|
Vue.use(Radio); |
||||
|
Vue.use(Dropdown); |
||||
|
Vue.use(Menu); |
||||
|
Vue.use(Row); |
||||
|
Vue.use(Col); |
||||
|
Vue.use(Timeline); |
||||
|
Vue.use(Checkbox); |
||||
|
Vue.use(BackTop); |
||||
|
Vue.use(Progress); |
||||
|
Vue.use(Carousel); |
||||
|
Vue.use(Spin); |
||||
|
Vue.use(Card); |
||||
|
Vue.use(List); |
||||
|
Vue.use(Collapse); |
||||
|
Vue.use(Cascader); |
||||
|
Vue.use(InputNumber); |
||||
|
Vue.use(TimePicker); |
||||
|
Vue.use(Divider); |
||||
|
Vue.use(Affix); |
||||
|
Vue.use(Drawer); |
||||
|
Vue.use(Tree); |
||||
|
Vue.prototype.$message = message; |
||||
|
Vue.prototype.$notification = notification; |
||||
|
Vue.prototype.$info = Modal.info; |
||||
|
Vue.prototype.$success = Modal.success; |
||||
|
Vue.prototype.$error = Modal.error; |
||||
|
Vue.prototype.$warning = Modal.warning; |
||||
|
Vue.prototype.$confirm = Modal.confirm; |
||||
|
|
||||
|
message.config({ |
||||
|
duration: 3, |
||||
|
maxCount: 3, |
||||
|
}); |
@ -0,0 +1,83 @@ |
|||||
|
/* |
||||
|
* @Author: wally |
||||
|
* @email: 18603454788@163.com |
||||
|
* @Date: 2021-04-19 10:23:19 |
||||
|
* @LastEditors: wally |
||||
|
* @LastEditTime: 2021-05-06 11:42:20 |
||||
|
*/ |
||||
|
'use strict'; |
||||
|
|
||||
|
import Vue from 'vue'; |
||||
|
import axios from 'axios'; |
||||
|
import router from '../router/index'; |
||||
|
import store from '../store/index'; |
||||
|
|
||||
|
// Full config: https://github.com/axios/axios#request-config
|
||||
|
// axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || '';
|
||||
|
// axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
|
||||
|
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||
|
let config = { |
||||
|
// baseURL: process.env.baseURL || process.env.apiUrl || ""
|
||||
|
timeout: 60 * 1000, // Timeout
|
||||
|
// withCredentials: true, // Check cross-site Access-Control
|
||||
|
}; |
||||
|
|
||||
|
const _axios = axios.create(config); |
||||
|
axios.interceptors.request.use( |
||||
|
function(config) { |
||||
|
let token = store.state.anyringToken || sessionStorage.getItem('anyringToken'); |
||||
|
if (token) { |
||||
|
config.headers.Authorization = `Bearer ${token}`; |
||||
|
} |
||||
|
return config; |
||||
|
}, |
||||
|
function(error) { |
||||
|
// Do something with request error
|
||||
|
return Promise.reject(error); |
||||
|
}, |
||||
|
); |
||||
|
|
||||
|
// Add a response interceptor
|
||||
|
axios.interceptors.response.use( |
||||
|
function(response) { |
||||
|
if (response.data && response.data.code >= 400 && response.data.code < 500) { |
||||
|
store.commit('user/sign', ''); |
||||
|
router.replace({ |
||||
|
path: '/user/login', |
||||
|
query: { redirect: router.currentRoute.fullPath }, |
||||
|
}); |
||||
|
} |
||||
|
// Do something with response data
|
||||
|
return response; |
||||
|
}, |
||||
|
function(error) { |
||||
|
// Do something with response error
|
||||
|
return Promise.reject(error); |
||||
|
}, |
||||
|
); |
||||
|
|
||||
|
Plugin.install = function(Vue) { |
||||
|
Vue.axios = _axios; |
||||
|
window.axios = _axios; |
||||
|
Object.defineProperties(Vue.prototype, { |
||||
|
axios: { |
||||
|
get() { |
||||
|
return _axios; |
||||
|
}, |
||||
|
}, |
||||
|
$axios: { |
||||
|
get() { |
||||
|
return _axios; |
||||
|
}, |
||||
|
}, |
||||
|
$http: { |
||||
|
get() { |
||||
|
return _axios; |
||||
|
}, |
||||
|
}, |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
Vue.use(Plugin); |
||||
|
|
||||
|
export default Plugin; |
@ -0,0 +1,3 @@ |
|||||
|
import 'quill/dist/quill.core.css'; |
||||
|
import 'quill/dist/quill.snow.css'; |
||||
|
import 'quill/dist/quill.bubble.css'; |
@ -0,0 +1,34 @@ |
|||||
|
/* eslint-disable no-console */ |
||||
|
|
||||
|
import { register } from "register-service-worker"; |
||||
|
|
||||
|
if (process.env.NODE_ENV === "production") { |
||||
|
register(`${process.env.BASE_URL}service-worker.js`, { |
||||
|
ready() { |
||||
|
console.log( |
||||
|
"App is being served from cache by a service worker.\n" + |
||||
|
"For more details, visit https://goo.gl/AFskqB" |
||||
|
); |
||||
|
}, |
||||
|
registered() { |
||||
|
console.log("Service worker has been registered."); |
||||
|
}, |
||||
|
cached() { |
||||
|
console.log("Content has been cached for offline use."); |
||||
|
}, |
||||
|
updatefound() { |
||||
|
console.log("New content is downloading."); |
||||
|
}, |
||||
|
updated() { |
||||
|
console.log("New content is available; please refresh."); |
||||
|
}, |
||||
|
offline() { |
||||
|
console.log( |
||||
|
"No internet connection found. App is running in offline mode." |
||||
|
); |
||||
|
}, |
||||
|
error(error) { |
||||
|
console.error("Error during service worker registration:", error); |
||||
|
} |
||||
|
}); |
||||
|
} |
@ -0,0 +1,38 @@ |
|||||
|
import Vue from 'vue'; |
||||
|
import VueRouter from 'vue-router'; |
||||
|
import Home from 'views/Index/Index.vue'; |
||||
|
|
||||
|
Vue.use(VueRouter); |
||||
|
|
||||
|
const routes = [ |
||||
|
// 首页数据统计
|
||||
|
{ |
||||
|
path: '/', |
||||
|
name: 'Home', |
||||
|
component: Home, |
||||
|
}, |
||||
|
// // 基本信息界面
|
||||
|
// {
|
||||
|
// path: '/info',
|
||||
|
// name: 'Info',
|
||||
|
// component: () => import('@/views/Info/Info.vue'),
|
||||
|
// meta: { title: '基本信息' },
|
||||
|
// },
|
||||
|
]; |
||||
|
|
||||
|
const router = new VueRouter({ |
||||
|
mode: 'history', |
||||
|
base: process.env.BASE_URL, |
||||
|
routes, |
||||
|
}); |
||||
|
|
||||
|
router.beforeEach((to, from, next) => { |
||||
|
if (to.meta.title) { |
||||
|
document.title = to.meta.title; |
||||
|
} else { |
||||
|
document.title = '暴风眼Typhoneye机构管理'; |
||||
|
} |
||||
|
next(); |
||||
|
}); |
||||
|
|
||||
|
export default router; |
@ -0,0 +1,7 @@ |
|||||
|
import Vue from 'vue'; |
||||
|
import Vuex from 'vuex'; |
||||
|
import home from './modules/home/index'; |
||||
|
// import messages from './modules/messages/index';
|
||||
|
|
||||
|
Vue.use(Vuex); |
||||
|
export default new Vuex.Store({ modules: { home } }); |
@ -0,0 +1,29 @@ |
|||||
|
import axios from 'axios'; |
||||
|
import { getUserId } from 'config/api-user'; |
||||
|
import { message } from 'ant-design-vue'; |
||||
|
import { aidRecord, queryAidRecord, getDetail } from 'config/api'; |
||||
|
|
||||
|
const actions = { |
||||
|
/** |
||||
|
* 通过userId获取token |
||||
|
* @param {any} commit |
||||
|
* @param {object} params 提交的参数 |
||||
|
*/ |
||||
|
async getUserId({ commit }, params) { |
||||
|
try { |
||||
|
const res = await getUserId({ params }); |
||||
|
const { code, msg, data } = res.data; |
||||
|
if (code === 200) { |
||||
|
commit('sign', data.token); |
||||
|
commit('setUser', data); |
||||
|
return data; |
||||
|
} else { |
||||
|
throw msg; |
||||
|
} |
||||
|
} catch (error) { |
||||
|
throw error || '获取个人信息失败'; |
||||
|
} |
||||
|
}, |
||||
|
}; |
||||
|
|
||||
|
export default actions; |
@ -0,0 +1,26 @@ |
|||||
|
/* |
||||
|
* @Author: your name |
||||
|
* @Date: 2021-07-28 12:00:41 |
||||
|
* @LastEditTime: 2021-07-29 10:07:25 |
||||
|
* @LastEditors: your name |
||||
|
* @Description: In User Settings Edit |
||||
|
* @FilePath: \wisdomcar_mobile\src\store\modules\home\getters.js |
||||
|
*/ |
||||
|
const getters = { |
||||
|
// 获取用户的id
|
||||
|
userId({ user }) { |
||||
|
try { |
||||
|
if (!user) return ''; |
||||
|
return user.id; |
||||
|
} catch (error) { |
||||
|
console.warn("user's getters 获取userId失败", error); |
||||
|
return ''; |
||||
|
} |
||||
|
}, |
||||
|
}; |
||||
|
// 域定制导航展示形式
|
||||
|
// 0 -> 无特殊导航文字
|
||||
|
// 1 -> 横向定制导航
|
||||
|
// 2 -> 纵向定制导航
|
||||
|
|
||||
|
export default getters; |
@ -0,0 +1,6 @@ |
|||||
|
import mutations from './mutations'; |
||||
|
import actions from './actions'; |
||||
|
import getters from './getters'; |
||||
|
import state from './state'; |
||||
|
|
||||
|
export default { namespaced: true, state, getters, mutations, actions }; |
@ -0,0 +1,54 @@ |
|||||
|
/* |
||||
|
* @Author: aBin |
||||
|
* @email: binbin0314@126.com |
||||
|
* @Date: 2021-05-31 17:25:39 |
||||
|
* @LastEditors: Please set LastEditors |
||||
|
* @LastEditTime: 2021-07-29 11:48:32 |
||||
|
*/ |
||||
|
const mutations = { |
||||
|
/** |
||||
|
* 设置token |
||||
|
* @param { object } state |
||||
|
* @param { string } token |
||||
|
*/ |
||||
|
sign(state, token) { |
||||
|
state.anyringToken = token; |
||||
|
sessionStorage.setItem('anyringToken', token); |
||||
|
}, |
||||
|
/** |
||||
|
* 设置token |
||||
|
* @param { object } state |
||||
|
* @param { string } token |
||||
|
*/ |
||||
|
getToken(state, token) { |
||||
|
state.anyringToken = sessionStorage.getItem('anyringToken'); |
||||
|
}, |
||||
|
/** |
||||
|
* 设置user用户信息 |
||||
|
* @param {object} state |
||||
|
* @param {object} user {id, account, phone} |
||||
|
*/ |
||||
|
setUser(state, user) { |
||||
|
if (!user) return; |
||||
|
state.user = { ...user }; |
||||
|
sessionStorage.setItem('user', JSON.stringify(user)); |
||||
|
}, |
||||
|
/** |
||||
|
* 设置user用户信息 |
||||
|
* @param {object} state |
||||
|
* @param {Array} data |
||||
|
*/ |
||||
|
setControlGroups(state, data) { |
||||
|
state.controlGroups = data; |
||||
|
}, |
||||
|
/** |
||||
|
* 设置当前选择的医院信息 |
||||
|
* @param {object} state |
||||
|
* @param {object} data |
||||
|
*/ |
||||
|
setHospitalInfo(state, data) { |
||||
|
state.hospitalInfo = data; |
||||
|
}, |
||||
|
}; |
||||
|
|
||||
|
export default mutations; |
@ -0,0 +1,7 @@ |
|||||
|
const state = { |
||||
|
anyringToken: '', |
||||
|
user: { id: '', phone: '', account: '', wxInfo: { nickname: '' } }, |
||||
|
hospitalInfo: {}, |
||||
|
}; |
||||
|
|
||||
|
export default state; |
@ -0,0 +1,40 @@ |
|||||
|
<template> |
||||
|
<div class="d-flex flex-row"> |
||||
|
<LeftList ref="left-list" @showModal="showModal" /> |
||||
|
<AddHospital @showModal="showModal" @getHosList="getHosList" :visible="isShow" :options="options" :level-list="levelList" /> |
||||
|
<RightPage class="flex-1" v-if="hospitalInfo && hospitalInfo.name" /> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
import LeftList from 'components/LeftList/LeftList.vue'; |
||||
|
import AddHospital from 'components/AddHospital/AddHospital.vue'; |
||||
|
import RightPage from 'components/RightPage/RightPage.vue'; |
||||
|
import { mapState } from 'vuex'; |
||||
|
|
||||
|
export default { |
||||
|
name: 'Index', |
||||
|
components: { LeftList, AddHospital, RightPage }, |
||||
|
data() { |
||||
|
return { |
||||
|
isShow: false, |
||||
|
options: [], |
||||
|
levelList: [], |
||||
|
}; |
||||
|
}, |
||||
|
computed: { ...mapState('home', ['hospitalInfo']) }, |
||||
|
methods: { |
||||
|
showModal(options, levelList) { |
||||
|
this.options = options; |
||||
|
this.levelList = levelList; |
||||
|
this.isShow = !this.isShow; |
||||
|
}, |
||||
|
// 重新获取医院列表 |
||||
|
getHosList() { |
||||
|
const leftDom = this.$refs['left-list']; |
||||
|
leftDom.getHospitalList(); |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
||||
|
<style scoped> |
||||
|
</style> |
@ -0,0 +1,139 @@ |
|||||
|
/* |
||||
|
* Copyright (c) 2019. |
||||
|
* author: wally |
||||
|
* email: 18603454788@163.com |
||||
|
*/ |
||||
|
const path = require('path'); |
||||
|
const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg|ttf|woff|woff2)(\?.*)?$/i; |
||||
|
const CompressionWebpackPlugin = require('compression-webpack-plugin'); |
||||
|
|
||||
|
const resolve = dir => path.join(__dirname, dir); |
||||
|
const isPro = process.env.VUE_APP_NODE_ENV === 'production'; |
||||
|
const publicPath = process.env.VUE_APP_PUBLIC_PATH; |
||||
|
const proxyUrl = process.env.VUE_APP_PROXY_URL; |
||||
|
const apiUrl = process.env.VUE_APP_API_URL; |
||||
|
const title = process.env.VUE_APP_TITLE; |
||||
|
console.log('proxyUrl: ', proxyUrl); |
||||
|
console.log('apiUrl: ', apiUrl); |
||||
|
|
||||
|
// 本地环境是否需要使用cdn
|
||||
|
const devNeedCdn = true; |
||||
|
|
||||
|
// cdn 链接及配置
|
||||
|
const cdn = { |
||||
|
css: [ |
||||
|
'https://cdn.jsdelivr.net/npm/@mdi/font@5.x/css/materialdesignicons.min.css', |
||||
|
'https://cdn.bootcdn.net/ajax/libs/ant-design-vue/1.6.5/antd.min.css', |
||||
|
], |
||||
|
js: [ |
||||
|
isPro ? 'https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js' : 'https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.js', |
||||
|
'https://cdn.bootcdn.net/ajax/libs/vue-router/3.4.3/vue-router.min.js', |
||||
|
'https://cdn.bootcdn.net/ajax/libs/vuex/3.5.1/vuex.min.js', |
||||
|
'https://cdn.bootcdn.net/ajax/libs/moment.js/2.9.0/moment.min.js', |
||||
|
'https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.20/lodash.min.js', |
||||
|
'https://cdn.bootcdn.net/ajax/libs/axios/0.20.0/axios.min.js', |
||||
|
'https://cdn.bootcdn.net/ajax/libs/ant-design-vue/1.6.5/antd.min.js', |
||||
|
], |
||||
|
// externals: {
|
||||
|
// vue: 'Vue',
|
||||
|
// vuex: 'Vuex',
|
||||
|
// 'vue-router': 'VueRouter',
|
||||
|
// moment: 'moment',
|
||||
|
// axios: 'axios',
|
||||
|
// 'ant-design-vue': 'antd',
|
||||
|
// lodash: '_',
|
||||
|
// },
|
||||
|
}; |
||||
|
|
||||
|
module.exports = { |
||||
|
lintOnSave: true, |
||||
|
publicPath: isPro ? publicPath : '/', |
||||
|
devServer: { |
||||
|
open: true, |
||||
|
overlay: { |
||||
|
warnings: false, |
||||
|
errors: true, |
||||
|
}, |
||||
|
proxy: { |
||||
|
[proxyUrl]: { |
||||
|
target: apiUrl, // 代理接口
|
||||
|
changeOrigin: true, |
||||
|
pathRewrite: { [`^${proxyUrl}`]: '' }, |
||||
|
}, |
||||
|
}, |
||||
|
https: false, |
||||
|
}, |
||||
|
productionSourceMap: false, // 去掉生产环境的sourcemap 加快构建速度
|
||||
|
|
||||
|
configureWebpack: { |
||||
|
// provide the app's title in webpack's name field, so that
|
||||
|
// it can be accessed in index.html to inject the correct title.
|
||||
|
|
||||
|
name: title, |
||||
|
resolve: { |
||||
|
alias: { |
||||
|
'~': __dirname, |
||||
|
'@': resolve('src'), |
||||
|
assets: resolve('src/assets'), |
||||
|
views: resolve('src/views'), |
||||
|
components: resolve('src/components'), |
||||
|
common: resolve('src/common'), |
||||
|
config: resolve('src/config'), |
||||
|
router: resolve('src/router'), |
||||
|
store: resolve('src/store'), |
||||
|
util: resolve('src/util'), |
||||
|
request: resolve('src/request'), |
||||
|
}, |
||||
|
}, |
||||
|
plugins: isPro |
||||
|
? [ |
||||
|
new CompressionWebpackPlugin({ |
||||
|
test: productionGzipExtensions, |
||||
|
threshold: 10240, |
||||
|
deleteOriginalAssets: false, |
||||
|
}), |
||||
|
] |
||||
|
: [], |
||||
|
externals: isPro || devNeedCdn ? cdn.externals : {}, |
||||
|
}, |
||||
|
|
||||
|
chainWebpack(config) { |
||||
|
if (isPro) { |
||||
|
config.optimization |
||||
|
.runtimeChunk('single') |
||||
|
.minimize(true) |
||||
|
.splitChunks({ |
||||
|
chunks: 'all', |
||||
|
maxInitialRequests: Infinity, |
||||
|
minSize: 20000, // 依赖包超过20000bit将被单独打包
|
||||
|
cacheGroups: { |
||||
|
vendor: { |
||||
|
test: /[\\/]node_modules[\\/]/, |
||||
|
name(module) { |
||||
|
// get the name. E.g. node_modules/packageName/not/this/part.js
|
||||
|
// or node_modules/packageName
|
||||
|
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]; |
||||
|
// npm package names are URL-safe, but some servers don't like @ symbols
|
||||
|
return `npm.${packageName.replace('@', '')}`; |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
// set svg-sprite-loader
|
||||
|
// config.module
|
||||
|
// .rule('svg')
|
||||
|
// .exclude.add(resolve('src/icons'))
|
||||
|
// .end();
|
||||
|
// config.module
|
||||
|
// .rule('icons')
|
||||
|
// .test(/\.svg$/)
|
||||
|
// .include.add(resolve('src/icons'))
|
||||
|
// .end()
|
||||
|
// .use('svg-sprite-loader')
|
||||
|
// .loader('svg-sprite-loader')
|
||||
|
// .options({ symbolId: 'icon-[name]' })
|
||||
|
// .end();
|
||||
|
}, |
||||
|
}; |