添加切换角色功能
continuous-integration/drone/push Build is passing Details

main
wangxiaoshuang 2025-03-28 09:29:32 +08:00
parent a0d32a77ec
commit 7b1fd033b9
11 changed files with 537 additions and 366 deletions

View File

@ -57,7 +57,7 @@
num = e.data num = e.data
} }
</script> </script>
<script src="./config.js"></script> <script src="/config.js"></script>
</head> </head>
<body> <body>
<noscript> <noscript>

View File

@ -160,4 +160,12 @@ export function GetObjectStoreToken(params) {
}) })
} }
export function loginSelectUserRole(params) {
return request({
url: `/user/loginSelectUserType`,
method: 'get',
params
})
}

View File

@ -0,0 +1,107 @@
<template>
<el-dialog v-if="visible" :visible.sync="visible" v-dialogDrag width="540px" :close-on-click-modal="false"
:close-on-press-escape="false" append-to-body :title="$t('toggleRole:tip:title')" center top="30vh"
:show-close="false" :before-close="cancel">
<template v-if="hasRole">
<el-radio-group v-model="form.userRoleId" class="roles">
<el-radio v-for="item in roles" :key="item.Id" :label="item.Id" :disabled="item.IsUserRoleDisabled"
style="margin-bottom: 10px">
{{ item.UserTypeShortName }}
</el-radio>
</el-radio-group>
</template>
<div v-else style="text-align: center">
{{ $t('toggleRole:tip:noRole') }}
</div>
<div slot="footer">
<!-- 取消 -->
<el-button size="small" @click="cancel()">
{{ $t('common:button:cancel') }}
</el-button>
<!-- 保存 -->
<el-button type="primary" size="small" @click="save" :disabled="saveDisabled" :loading="loading" v-if="hasRole">
{{ $t('common:button:confirm') }}
</el-button>
</div>
</el-dialog>
</template>
<script>
export default {
name: 'toggleRole',
props: {
visible: {
type: Boolean,
default: false,
},
loading: {
type: Boolean,
default: false,
},
},
data() {
return {
form: {
userRoleId: null,
},
}
},
created() {
this.form.userRoleId = zzSessionStorage.getItem('userId')
},
computed: {
roles() {
return this.$store.state.user.roles
},
hasRole() {
return this.roles && this.roles.length > 0
},
saveDisabled() {
return this.form.userRoleId === zzSessionStorage.getItem('userId')
},
},
methods: {
cancel() {
this.$emit('update:visible', false)
this.$emit('cancel')
},
async save() {
try {
if (!this.form.userRoleId)
return this.$message.warning(this.$t('toggleRole:ruleMessage:select'))
zzSessionStorage.removeItem('lastWorkbench')
this.$emit('save', {
UserId: this.form.userRoleId,
UserTypeId: this.roles.find(item => item.Id === this.form.userRoleId).UserTypeId
})
} catch (err) {
console.log(err)
}
},
},
}
</script>
<style lang="scss" scoped>
.roles {
max-width: 365px;
width: fit-content;
display: flex;
align-content: center;
// justify-content: center;
flex-wrap: wrap;
margin: auto;
}
::v-deep .el-radio__original {
display: none !important;
/* 隐藏原生 radio 输入,但仍然允许交互 */
}
::v-deep.el-radio:focus:not(.is-focus):not(:active):not(.is-disabled) .el-radio__inner {
box-shadow: none !important;
}
.el-radio {
width: 60px;
}
</style>

View File

@ -2,11 +2,7 @@
<div class="navbar navbar-flex-wrapper"> <div class="navbar navbar-flex-wrapper">
<div class="leftMenu"> <div class="leftMenu">
<div class="navbar-flex-wrapper"> <div class="navbar-flex-wrapper">
<hamburger <hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
:is-active="sidebar.opened"
class="hamburger-container"
@toggleClick="toggleSideBar"
/>
<breadcrumb class="breadcrumb-container" /> <breadcrumb class="breadcrumb-container" />
</div> </div>
@ -36,6 +32,12 @@
<!-- <el-dropdown-item> <!-- <el-dropdown-item>
<span style="display:block;" @click="account">Account</span> <span style="display:block;" @click="account">Account</span>
</el-dropdown-item> --> </el-dropdown-item> -->
<!-- 切换角色 -->
<el-dropdown-item divided v-if="hasRole">
<span style="display: block" @click="openToggleRole">{{
$t('system:navbar:button:toggleRole')
}}</span>
</el-dropdown-item>
<el-dropdown-item divided> <el-dropdown-item divided>
<span style="display: block" @click="logout">{{ <span style="display: block" @click="logout">{{
$t("trials:trials-myinfo:button:loginout") $t("trials:trials-myinfo:button:loginout")
@ -46,6 +48,8 @@
</div> </div>
</div> </div>
</div> </div>
<toggleRole v-if="toggleRoleVisible" :visible.sync="toggleRoleVisible" :loading="toggleRoleLoading"
@save="loginByRole" />
</div> </div>
</template> </template>
@ -54,27 +58,101 @@ import { mapGetters, mapMutations } from "vuex";
import Breadcrumb from "@/components/Breadcrumb"; import Breadcrumb from "@/components/Breadcrumb";
import Hamburger from "@/components/Hamburger"; import Hamburger from "@/components/Hamburger";
import Screenfull from "@/components/Screenfull"; import Screenfull from "@/components/Screenfull";
import { resetRouter } from '@/router'
import toggleRole from '@/components/toggleRole'
export default { export default {
components: { components: {
Breadcrumb, Breadcrumb,
Hamburger, Hamburger,
Screenfull, Screenfull,
toggleRole
}, },
data() { data() {
return { return {
isReviewer: false, isReviewer: false,
userTypeShortName: zzSessionStorage.getItem("userTypeShortName"), userTypeShortName: zzSessionStorage.getItem("userTypeShortName"),
toggleRoleVisible: false,
toggleRoleLoading: false
}; };
}, },
computed: { computed: {
...mapGetters(["sidebar", "name", "device"]), ...mapGetters(["sidebar", "name", "device"]),
roles() {
return this.$store.state.user.roles
},
hasRole() {
return this.roles && this.roles.length > 1
},
}, },
created() { created() {
this.isReviewer = JSON.parse(zzSessionStorage.getItem("IsReviewer")); this.isReviewer = JSON.parse(zzSessionStorage.getItem("IsReviewer"));
this.$store.dispatch('user/getUserInfo')
}, },
methods: { methods: {
...mapMutations({ setLanguage: "lang/setLanguage" }), ...mapMutations({ setLanguage: "lang/setLanguage" }),
openToggleRole() {
this.$store.dispatch('user/getUserInfo').then((res) => {
this.toggleRoleVisible = true
})
},
loginByRole(row) {
let { UserId, UserTypeId } = row
if (this.$store.state.user.userId === UserId) {
this.toggleRoleVisible = false
this.toggleRoleLoading = false
return false
}
this.toggleRoleLoading = true
this.$store
.dispatch('user/loginByRole', { UserId, UserTypeId })
.then((res) => {
if (res) {
this.$store
.dispatch('permission/generateRoutes')
.then(async (res) => {
if (res && res.length > 0) {
resetRouter()
await this.$store.dispatch('global/getNoticeList')
this.$router.addRoutes(res)
this.toggleRoleLoading = false
if (this.loginType === 'DevOps') {
this.$router.replace({ path: res[0].path })
return
}
if (this.hasPermi(['role:radmin'])) {
this.$router.replace({ path: res[0].path })
return
}
if (
this.hasPermi(['role:pm', 'role:oa', 'role:admin', 'role:dev'])
) {
history.replaceState(null, null, '/trials/trials-inspection')
history.go(0)
} else {
history.replaceState(null, null, '/trials/trials-list')
history.go(0)
}
this.toggleRoleVisible = false
this.toggleRoleLoading = false
this.$EventBus.$emit('reload')
} else {
//
this.toggleRoleLoading = false
this.$message.warning(this.$t('login:message:login2'))
}
})
.catch((err) => {
console.log(err)
this.toggleRoleLoading = false
})
} else {
this.toggleRoleLoading = false
}
})
.catch(() => {
this.toggleRoleLoading = false
})
},
toggleSideBar() { toggleSideBar() {
this.$store.dispatch("app/toggleSideBar"); this.$store.dispatch("app/toggleSideBar");
}, },
@ -106,12 +184,14 @@ export default {
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
} }
.navbar { .navbar {
height: 50px; height: 50px;
overflow: hidden; overflow: hidden;
// position: relative; // position: relative;
background: #fff; background: #fff;
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08); box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
.hamburger-container { .hamburger-container {
line-height: 46px; line-height: 46px;
height: 100%; height: 100%;
@ -133,6 +213,7 @@ export default {
// float: right; // float: right;
height: 100%; height: 100%;
line-height: 50px; line-height: 50px;
// position: relative; // position: relative;
&:focus { &:focus {
outline: none; outline: none;
@ -159,6 +240,7 @@ export default {
.avatar-container { .avatar-container {
display: inline-block; display: inline-block;
margin-right: 200px; margin-right: 200px;
.user-avatar { .user-avatar {
margin-top: 5px; margin-top: 5px;
width: 40px; width: 40px;
@ -166,16 +248,19 @@ export default {
border-radius: 10px; border-radius: 10px;
} }
} }
.dropdown-container { .dropdown-container {
// margin-left: 30px; // margin-left: 30px;
// position: absolute; // position: absolute;
// right: 20px; // right: 20px;
// top: 0px; // top: 0px;
cursor: pointer; cursor: pointer;
.el-icon-caret-bottom { .el-icon-caret-bottom {
font-size: 12px; font-size: 12px;
} }
} }
.el-dropdown-link { .el-dropdown-link {
color: #999c9e; color: #999c9e;
cursor: pointer; cursor: pointer;

View File

@ -101,7 +101,7 @@ Vue.prototype.resetForm = resetForm
Vue.prototype.selectDictLabel = selectDictLabel Vue.prototype.selectDictLabel = selectDictLabel
// Vue.prototype.download = download // Vue.prototype.download = download
Vue.prototype.handleTree = handleTree Vue.prototype.handleTree = handleTree
Vue.prototype.$EventBus = new Vue()
Vue.prototype.$getObjectName = (url) => { Vue.prototype.$getObjectName = (url) => {
// console.log(url,'url') // console.log(url,'url')
// console.log(Vue.prototype.OSSclientConfig.viewEndpoint,'url') // console.log(Vue.prototype.OSSclientConfig.viewEndpoint,'url')

View File

@ -1,6 +1,6 @@
import { getToken, setToken, removeToken, setName, removeName } from '@/utils/auth' import { getToken, setToken, removeToken, setName, removeName } from '@/utils/auth'
import { login, getUserMenuTree, getUserPermissions } from '@/api/user' import { login, getUserMenuTree, getUserPermissions, loginSelectUserRole } from '@/api/user'
import { getUser } from '@/api/admin'
import { resetRouter } from '@/router' import { resetRouter } from '@/router'
import md5 from 'js-md5' import md5 from 'js-md5'
const getDefaultState = () => { const getDefaultState = () => {
@ -16,13 +16,17 @@ const getDefaultState = () => {
TotalNeedSignSystemDocCount: eval(process.env.VUE_APP_WORD_FOR_PERMISSION) ? null : 0, TotalNeedSignSystemDocCount: eval(process.env.VUE_APP_WORD_FOR_PERMISSION) ? null : 0,
TotalNeedSignTrialDocCount: eval(process.env.VUE_APP_WORD_FOR_PERMISSION) ? null : 0, TotalNeedSignTrialDocCount: eval(process.env.VUE_APP_WORD_FOR_PERMISSION) ? null : 0,
TrialStatusStr: null, TrialStatusStr: null,
isTestUser: false isTestUser: false,
roles: []
} }
} }
const state = getDefaultState() const state = getDefaultState()
const mutations = { const mutations = {
SET_ROLES: (state, roles) => {
state.roles = roles
},
RESET_STATE: (state) => { RESET_STATE: (state) => {
Object.assign(state, getDefaultState()) Object.assign(state, getDefaultState())
}, },
@ -78,6 +82,9 @@ const mutations = {
} }
const actions = { const actions = {
setRoles({ commit }, roles) {
commit('SET_ROLES', roles)
},
// user login // user login
login({ commit }, userInfo) { login({ commit }, userInfo) {
const { username, password } = userInfo const { username, password } = userInfo
@ -135,6 +142,49 @@ const actions = {
}) })
}) })
}, },
loginByRole({ commit }, userInfo) {
const { UserId, UserTypeId } = userInfo
let params = {
UserId, UserTypeId
}
return new Promise((resolve, reject) => {
loginSelectUserRole(params).then(async response => {
if (response.IsSuccess) {
const data = response.Result.JWTStr
try {
commit('SET_TOKEN', data)
setToken(data)
commit('SET_USERID', UserId)
zzSessionStorage.setItem('userId', UserId)
const userString = decodeURIComponent(escape(window.atob(data.split('.')[1].replace(/-/g, '+').replace(/_/g, '/'))))
const user = JSON.parse(userString)
zzSessionStorage.setItem('userTypeShortName', user.userTypeShortName)
// commit('SET_USERTYPESHORTNAME', user.userTypeShortName)
commit('SET_NAME', user.fullName)
setName(user.fullName)
zzSessionStorage.setItem('userTypeEnumInt', user.userTypeEnumInt)
var permissions = await getUserPermissions()
var menuTree = await getUserMenuTree()
commit('SET_TREE', menuTree.Result)
commit('SET_PERMISSIONS', permissions.Result)
zzSessionStorage.setItem('newTree', JSON.stringify(menuTree.Result))
zzSessionStorage.setItem('permissions', JSON.stringify(permissions.Result))
zzSessionStorage.removeItem('lastWorkbench')
} catch (e) {
console.log(e)
}
resolve(response.Result)
} else {
reject(response.ErrorMessage)
}
}).catch(() => {
reject()
})
})
},
setTree({ commit }, tree) { setTree({ commit }, tree) {
commit('SET_TREE', tree) commit('SET_TREE', tree)
}, },
@ -186,7 +236,19 @@ const actions = {
setToken({ commit }, token) { setToken({ commit }, token) {
commit('SET_TOKEN', token) commit('SET_TOKEN', token)
}, },
// 获取用户信息
getUserInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getUser(state.userId).then(res => {
if (res.Result) {
commit('SET_ROLES', res.Result.AccountList)
}
resolve(res.Result)
}).catch(err => {
reject(err)
})
})
},
// remove token // remove token
resetToken({ commit }) { resetToken({ commit }) {
return new Promise(resolve => { return new Promise(resolve => {

View File

@ -122,6 +122,7 @@ import Img1 from '@/assets/pic-1.png'
import logoImg from '@/assets/zzlogo2.png' import logoImg from '@/assets/zzlogo2.png'
import { getHospital } from '@/api/hospital.js' import { getHospital } from '@/api/hospital.js'
import { getHIRHospitalList, updateDefaultHospital } from '@/api/admin' import { getHIRHospitalList, updateDefaultHospital } from '@/api/admin'
// import config from '/public/config.js' // import config from '/public/config.js'
export default { export default {
name: 'Login', name: 'Login',

View File

@ -342,6 +342,11 @@ export default {
this.selectPatient = item this.selectPatient = item
}, },
}, },
mounted() {
this.$EventBus.$on("reload", (data) => {
window.location.reload()
});
}
} }
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>

View File

@ -1,13 +1,9 @@
<template> <template>
<div class="trials-navbar" style="position: relative"> <div class="trials-navbar" style="position: relative">
<div class="leftMenu"> <div class="leftMenu">
<img <img v-if="language === 'zh' && hospital.HospitalLogoPath"
v-if="language === 'zh' && hospital.HospitalLogoPath" :src="OSSclientConfig.basePath + hospital.HospitalLogoPath" crossOrigin="anonymous" alt=""
:src="OSSclientConfig.basePath + hospital.HospitalLogoPath" style="min-width: 170px;" />
crossOrigin="anonymous"
alt=""
style="min-width: 170px;"
/>
<div v-else style="width: 170px;"></div> <div v-else style="width: 170px;"></div>
<!-- <img v-else src="@/assets/zzlogo3.png" alt="" /> --> <!-- <img v-else src="@/assets/zzlogo3.png" alt="" /> -->
<span style="white-space: nowrap"> <span style="white-space: nowrap">
@ -19,50 +15,34 @@
<NoticeMarquee /> <NoticeMarquee />
</div> </div>
<div class="right-menu"> <div class="right-menu">
<el-menu <el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" size="mini" @select="handleSelect">
:default-active="activeIndex"
class="el-menu-demo"
mode="horizontal"
size="mini"
@select="handleSelect"
>
<!-- <el-menu-item v-if="!hasPermi(['role:air', 'role:rpm', 'role:radmin', 'role:rcrc', 'role:rir'])" index="1"> <!-- <el-menu-item v-if="!hasPermi(['role:air', 'role:rpm', 'role:radmin', 'role:rcrc', 'role:rir'])" index="1">
<i class="el-icon-odometer" /> --> <i class="el-icon-odometer" /> -->
<!-- 工作台 --> <!-- 工作台 -->
<!-- <span slot="title">{{ $t('trials:menuTitle:workbench') }}</span> <!-- <span slot="title">{{ $t('trials:menuTitle:workbench') }}</span>
</el-menu-item> --> </el-menu-item> -->
<el-menu-item <el-menu-item v-if="hasPermi(['role:pm', 'role:oa', 'role:admin', 'role:dev'])" index="1">
v-if="hasPermi(['role:pm', 'role:oa', 'role:admin', 'role:dev'])"
index="1"
>
<i class="el-icon-odometer" /> <i class="el-icon-odometer" />
<!-- 检查 --> <!-- 检查 -->
<span slot="title">{{ $t('trials:menuTitle:inspection') }}</span> <span slot="title">{{ $t('trials:menuTitle:inspection') }}</span>
</el-menu-item> </el-menu-item>
<el-menu-item <el-menu-item v-if="!hasPermi(['role:zys'])" index="2" :disabled="TotalNeedSignSystemDocCount !== 0">
v-if="!hasPermi(['role:zys'])"
index="2"
:disabled="TotalNeedSignSystemDocCount !== 0"
>
<i class="el-icon-box" /> <i class="el-icon-box" />
<!-- 我的项目 --> <!-- 我的项目 -->
<span slot="title"> <span slot="title">
{{ $t('trials:tab:trials') }} {{ $t('trials:tab:trials') }}
</span> </span>
</el-menu-item> </el-menu-item>
<el-menu-item <el-menu-item v-if="
v-if=" !hasPermi([
!hasPermi([ 'role:air',
'role:air', 'role:rpm',
'role:rpm', 'role:radmin',
'role:radmin', 'role:rcrc',
'role:rcrc', 'role:rir',
'role:rir', 'role:zys',
'role:zys', ])
]) " index="3">
"
index="3"
>
<i class="el-icon-chat-dot-square" /> <i class="el-icon-chat-dot-square" />
<!-- 通知消息 --> <!-- 通知消息 -->
<span slot="title">{{ $t('trials:tab:notice') }}</span> <span slot="title">{{ $t('trials:tab:notice') }}</span>
@ -80,11 +60,12 @@
$t('trials:trials-myinfo:title:accountInfo') $t('trials:trials-myinfo:title:accountInfo')
}}</el-menu-item> }}</el-menu-item>
<!-- 管理后台 --> <!-- 管理后台 -->
<el-menu-item <el-menu-item v-if="hasPermi(['role:dev', 'role:oa', 'role:admin'])" index="4-4">{{
v-if="hasPermi(['role:dev', 'role:oa', 'role:admin'])" $t('trials:trials-myinfo:title:system') }}</el-menu-item>
index="4-4" <!-- 切换角色 -->
>{{ $t('trials:trials-myinfo:title:system') }}</el-menu-item <el-menu-item index="4-5" v-if="hasRole">{{
> $t('trials:trials-myinfo:title:toggleRole')
}}</el-menu-item>
<!-- 退出 --> <!-- 退出 -->
<el-menu-item index="4-3">{{ <el-menu-item index="4-3">{{
$t('trials:trials-myinfo:button:loginout') $t('trials:trials-myinfo:button:loginout')
@ -92,6 +73,8 @@
</el-submenu> </el-submenu>
</el-menu> </el-menu>
<!-- <TopLang />--> <!-- <TopLang />-->
<toggleRole v-if="toggleRoleVisible" :visible.sync="toggleRoleVisible" :loading="toggleRoleLoading" :roles="roles"
@save="loginByRole" />
</div> </div>
</div> </div>
</template> </template>
@ -103,8 +86,10 @@ import TopLang from './topLang'
import NoticeMarquee from './noticeMarquee' import NoticeMarquee from './noticeMarquee'
import { getHospital } from '@/api/hospital.js' import { getHospital } from '@/api/hospital.js'
import logoImg from '@/assets/zzlogo2.png' import logoImg from '@/assets/zzlogo2.png'
import { resetRouter } from '@/router'
import toggleRole from '@/components/toggleRole'
export default { export default {
components: { TopLang, NoticeMarquee }, components: { TopLang, NoticeMarquee, toggleRole },
data() { data() {
return { return {
logoImg, logoImg,
@ -116,6 +101,8 @@ export default {
HospitalLogoPath: null, HospitalLogoPath: null,
HospitalName: null, HospitalName: null,
}, },
toggleRoleVisible: false,
toggleRoleLoading: false,
} }
}, },
computed: { computed: {
@ -127,6 +114,16 @@ export default {
'TotalNeedSignSystemDocCount', 'TotalNeedSignSystemDocCount',
'language', 'language',
]), ]),
roles() {
return this.$store.state.user.roles
},
hasRole() {
return (
this.roles &&
this.roles.length > 1 &&
this.roles.filter((item) => !item.IsUserRoleDisabled).length > 1
)
},
}, },
watch: { watch: {
$route(v) { $route(v) {
@ -137,9 +134,67 @@ export default {
this.isReviewer = JSON.parse(zzSessionStorage.getItem('IsReviewer')) this.isReviewer = JSON.parse(zzSessionStorage.getItem('IsReviewer'))
this.changeRoute(this.$route) this.changeRoute(this.$route)
this.getInfo() this.getInfo()
this.$store.dispatch('user/getUserInfo')
}, },
methods: { methods: {
...mapMutations({ setLanguage: 'lang/setLanguage' }), ...mapMutations({ setLanguage: 'lang/setLanguage' }),
loginByRole(row) {
let { UserId, UserTypeId } = row
if (this.$store.state.user.userId === UserId) {
this.toggleRoleVisible = false
this.toggleRoleLoading = false
return false
}
this.toggleRoleLoading = true
this.$store
.dispatch('user/loginByRole', { UserId, UserTypeId })
.then((res) => {
if (res) {
this.$store
.dispatch('permission/generateRoutes')
.then(async (res) => {
if (res && res.length > 0) {
resetRouter()
await this.$store.dispatch('global/getNoticeList')
this.$router.addRoutes(res)
this.toggleRoleLoading = false
if (this.loginType === 'DevOps') {
this.$router.replace({ path: res[0].path })
return
}
if (this.hasPermi(['role:radmin'])) {
this.$router.replace({ path: res[0].path })
return
}
if (
this.hasPermi(['role:pm', 'role:oa', 'role:admin', 'role:dev'])
) {
history.replaceState(null, null, '/trials/trials-inspection')
history.go(0)
} else {
history.replaceState(null, null, '/trials/trials-list')
history.go(0)
}
this.toggleRoleVisible = false
this.toggleRoleLoading = false
this.$EventBus.$emit('reload')
} else {
//
this.toggleRoleLoading = false
this.$message.warning(this.$t('login:message:login2'))
}
})
.catch((err) => {
this.toggleRoleLoading = false
})
} else {
this.toggleRoleLoading = false
}
})
.catch(() => {
this.toggleRoleLoading = false
})
},
// //
async getInfo() { async getInfo() {
try { try {
@ -180,6 +235,12 @@ export default {
break break
case '4-4': case '4-4':
this.go('/system') this.go('/system')
break
case '4-5':
this.$store.dispatch('user/getUserInfo').then((res) => {
this.toggleRoleVisible = true
})
break break
case '1': case '1':
this.go('/trials/trials-inspection') this.go('/trials/trials-inspection')
@ -230,33 +291,40 @@ export default {
overflow: hidden; overflow: hidden;
background: #fff; background: #fff;
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08); box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
.el-breadcrumb__item { .el-breadcrumb__item {
font-size: 16px; font-size: 16px;
} }
.leftMenu { .leftMenu {
display: flex; display: flex;
align-items: center; align-items: center;
padding-left: 20px; padding-left: 20px;
img { img {
height: 28px; height: 28px;
margin-right: 10px; margin-right: 10px;
} }
span { span {
font-size: 20px; font-size: 20px;
position: relative; position: relative;
top: -1px; top: -1px;
} }
} }
.right-menu, .right-menu,
.center-menu { .center-menu {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
height: 100%; height: 100%;
// line-height: 70px; // line-height: 70px;
&:focus { &:focus {
outline: none; outline: none;
} }
.right-menu-item { .right-menu-item {
display: inline-block; display: inline-block;
padding: 0 8px; padding: 0 8px;
@ -274,9 +342,11 @@ export default {
} }
} }
} }
.avatar-container { .avatar-container {
display: inline-block; display: inline-block;
margin-right: 200px; margin-right: 200px;
.user-avatar { .user-avatar {
margin-top: 5px; margin-top: 5px;
width: 40px; width: 40px;
@ -284,12 +354,15 @@ export default {
border-radius: 10px; border-radius: 10px;
} }
} }
.dropdown-container { .dropdown-container {
cursor: pointer; cursor: pointer;
.el-icon-caret-bottom { .el-icon-caret-bottom {
font-size: 12px; font-size: 12px;
} }
} }
.el-dropdown-link { .el-dropdown-link {
color: #999c9e; color: #999c9e;
cursor: pointer; cursor: pointer;
@ -298,7 +371,7 @@ export default {
} }
</style> </style>
<style> <style>
.el-menu--horizontal > .my_info.el-submenu .el-submenu__icon-arrow { .el-menu--horizontal>.my_info.el-submenu .el-submenu__icon-arrow {
margin-top: 0; margin-top: 0;
} }
</style> </style>

View File

@ -5,51 +5,26 @@
<el-form :inline="true"> <el-form :inline="true">
<!-- 项目类型 --> <!-- 项目类型 -->
<el-form-item :label="$t('trials:trials-list:form:trialType')"> <el-form-item :label="$t('trials:trials-list:form:trialType')">
<el-select <el-select v-model="searchData.trialType" style="width: 150px" clearable>
v-model="searchData.trialType" <el-option v-for="item in $d.TrialType" :key="item.id" :label="item.label" :value="item.value" />
style="width: 150px"
clearable
>
<el-option
v-for="item in $d.TrialType"
:key="item.id"
:label="item.label"
:value="item.value"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 项目编号 --> <!-- 项目编号 -->
<el-form-item :label="$t('trials:trials-list:table:trialId')"> <el-form-item :label="$t('trials:trials-list:table:trialId')">
<el-input <el-input v-model="searchData.TrialCode" style="width: 100px" clearable />
v-model="searchData.TrialCode"
style="width: 100px"
clearable
/>
</el-form-item> </el-form-item>
<!-- 研究方案号 --> <!-- 研究方案号 -->
<el-form-item :label="$t('trials:trials-list:table:researchNumber')"> <el-form-item :label="$t('trials:trials-list:table:researchNumber')">
<el-input <el-input v-model="searchData.ResearchProgramNo" style="width: 100px" clearable />
v-model="searchData.ResearchProgramNo"
style="width: 100px"
clearable
/>
</el-form-item> </el-form-item>
<!-- 试验名称 --> <!-- 试验名称 -->
<el-form-item :label="$t('trials:trials-list:table:experimentName')"> <el-form-item :label="$t('trials:trials-list:table:experimentName')">
<el-input <el-input v-model="searchData.ExperimentName" style="width: 100px" clearable />
v-model="searchData.ExperimentName"
style="width: 100px"
clearable
/>
</el-form-item> </el-form-item>
<!-- Sponsor --> <!-- Sponsor -->
<el-form-item :label="$t('trials:trials-list:table:sponsor')"> <el-form-item :label="$t('trials:trials-list:table:sponsor')">
<el-input <el-input v-model="searchData.SponsorName" style="width: 100px" clearable />
v-model="searchData.SponsorName"
style="width: 100px"
clearable
/>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
@ -58,11 +33,7 @@
{{ $t("common:button:search") }} {{ $t("common:button:search") }}
</el-button> </el-button>
<!-- Reset --> <!-- Reset -->
<el-button <el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">
type="primary"
icon="el-icon-refresh-left"
@click="handleReset"
>
{{ $t("common:button:reset") }} {{ $t("common:button:reset") }}
</el-button> </el-button>
<!-- Export --> <!-- Export -->
@ -79,12 +50,7 @@
</el-form> </el-form>
<span style="margin-left: auto"> <span style="margin-left: auto">
<!-- New --> <!-- New -->
<el-button <el-button v-hasPermi="['trials:trials-list:new']" icon="el-icon-plus" type="primary" @click="handleNew">
v-hasPermi="['trials:trials-list:new']"
icon="el-icon-plus"
type="primary"
@click="handleNew"
>
{{ $t("common:button:new") }} {{ $t("common:button:new") }}
</el-button> </el-button>
</span> </span>
@ -92,123 +58,59 @@
<!-- 项目列表 --> <!-- 项目列表 -->
<template slot="main-container"> <template slot="main-container">
<el-table <el-table v-adaptive="{ bottomOffset: 60 }" v-loading="listLoading" :data="list" stripe height="100"
v-adaptive="{ bottomOffset: 60 }" @sort-change="handleSortChange" @row-click="handleDetail"
v-loading="listLoading" :default-sort="{ prop: 'createTime', order: 'descending' }">
:data="list"
stripe
height="100"
@sort-change="handleSortChange"
@row-click="handleDetail"
:default-sort="{ prop: 'createTime', order: 'descending' }"
>
<!-- <el-table-column type="selection" align="left" width="45" /> --> <!-- <el-table-column type="selection" align="left" width="45" /> -->
<el-table-column width="40"> <el-table-column width="40">
<template slot-scope="scope"> <template slot-scope="scope">
<i <i v-if="!scope.row.AuthorizationEncrypt" class="el-icon-warning-outline"
v-if="!scope.row.AuthorizationEncrypt" :title="$t('trials:trials-list:tipMessage:tipOne')" style="color: red; font-size: 20px"></i>
class="el-icon-warning-outline" <i v-if="
:title="$t('trials:trials-list:tipMessage:tipOne')" scope.row.AuthorizationEncrypt &&
style="color: red; font-size: 20px" scope.row.AuthorizationDate &&
></i> !trialExpired(scope.row.AuthorizationDate, 15)
<i " class="el-icon-warning-outline" :title="$t('trials:trials-list:tipMessage:tipTwo')"
v-if=" style="color: #e6a23c; font-size: 20px"></i>
scope.row.AuthorizationEncrypt && <i v-if="
scope.row.AuthorizationDate && scope.row.AuthorizationEncrypt &&
!trialExpired(scope.row.AuthorizationDate, 15) scope.row.AuthorizationDate &&
" !trialExpired(scope.row.AuthorizationDate)
class="el-icon-warning-outline" " class="el-icon-warning-outline" :title="$t('trials:trials-list:tipMessage:tipThree')"
:title="$t('trials:trials-list:tipMessage:tipTwo')" style="color: red; font-size: 20px"></i>
style="color: #e6a23c; font-size: 20px"
></i>
<i
v-if="
scope.row.AuthorizationEncrypt &&
scope.row.AuthorizationDate &&
!trialExpired(scope.row.AuthorizationDate)
"
class="el-icon-warning-outline"
:title="$t('trials:trials-list:tipMessage:tipThree')"
style="color: red; font-size: 20px"
></i>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column prop="trialType" :label="$t('trials:trials-list:form:trialType')" show-overflow-tooltip>
prop="trialType"
:label="$t('trials:trials-list:form:trialType')"
show-overflow-tooltip
>
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ $fd("TrialType", scope.row.TrialType) }}</span> <span>{{ $fd("TrialType", scope.row.TrialType) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column prop="TrialCode" :label="$t('trials:trials-list:table:trialId')" show-overflow-tooltip
prop="TrialCode" min-width="100" sortable="custom" />
:label="$t('trials:trials-list:table:trialId')" <el-table-column prop="ResearchProgramNo" :label="$t('trials:trials-list:table:researchNumber')"
show-overflow-tooltip show-overflow-tooltip min-width="120" sortable="custom" />
min-width="100"
sortable="custom"
/>
<el-table-column
prop="ResearchProgramNo"
:label="$t('trials:trials-list:table:researchNumber')"
show-overflow-tooltip
min-width="120"
sortable="custom"
/>
<el-table-column <el-table-column prop="ExperimentName" :label="$t('trials:trials-list:table:experimentName')"
prop="ExperimentName" show-overflow-tooltip min-width="120" sortable="custom" />
:label="$t('trials:trials-list:table:experimentName')"
show-overflow-tooltip
min-width="120"
sortable="custom"
/>
<el-table-column <el-table-column prop="Sponsor" :label="$t('trials:trials-list:table:sponsor')" min-width="90"
prop="Sponsor" show-overflow-tooltip sortable="custom" />
:label="$t('trials:trials-list:table:sponsor')" <el-table-column prop="TrialStatusStr" :label="$t('trials:trials-list:table:status')" show-overflow-tooltip
min-width="90" sortable="custom">
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="TrialStatusStr"
:label="$t('trials:trials-list:table:status')"
show-overflow-tooltip
sortable="custom"
>
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag <el-tag v-if="scope.row.TrialStatusStr === 'Initializing'" type="info">{{ $fd("TrialStatusEnum",
v-if="scope.row.TrialStatusStr === 'Initializing'" scope.row.TrialStatusStr) }}</el-tag>
type="info" <el-tag v-if="scope.row.TrialStatusStr === 'Ongoing'" type="primary">{{ $fd("TrialStatusEnum",
>{{ $fd("TrialStatusEnum", scope.row.TrialStatusStr) }}</el-tag scope.row.TrialStatusStr) }}</el-tag>
> <el-tag v-if="scope.row.TrialStatusStr === 'Completed'" type="warning">{{ $fd("TrialStatusEnum",
<el-tag scope.row.TrialStatusStr) }}</el-tag>
v-if="scope.row.TrialStatusStr === 'Ongoing'" <el-tag v-if="scope.row.TrialStatusStr === 'Stopped'" type="danger">{{ $fd("TrialStatusEnum",
type="primary" scope.row.TrialStatusStr) }}</el-tag>
>{{ $fd("TrialStatusEnum", scope.row.TrialStatusStr) }}</el-tag
>
<el-tag
v-if="scope.row.TrialStatusStr === 'Completed'"
type="warning"
>{{ $fd("TrialStatusEnum", scope.row.TrialStatusStr) }}</el-tag
>
<el-tag
v-if="scope.row.TrialStatusStr === 'Stopped'"
type="danger"
>{{ $fd("TrialStatusEnum", scope.row.TrialStatusStr) }}</el-tag
>
</template> </template>
</el-table-column> </el-table-column>
<!--阅片标准--> <!--阅片标准-->
<el-table-column <el-table-column prop="CriterionTypeList" :label="$t('trials:trials-list:table:CriterionTypeList')"
prop="CriterionTypeList" show-overflow-tooltip v-if="hasPermi(['role:pm', 'role:pi', 'role:sr'])" min-width="130">
:label="$t('trials:trials-list:table:CriterionTypeList')"
show-overflow-tooltip
v-if="hasPermi(['role:pm', 'role:pi', 'role:sr'])"
min-width="130"
>
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ <span>{{
scope.row.CriterionTypeList.map((item) => scope.row.CriterionTypeList.map((item) =>
@ -218,38 +120,16 @@
</template> </template>
</el-table-column> </el-table-column>
<!--待提交访视数量--> <!--待提交访视数量-->
<el-table-column <el-table-column prop="UnSubmitCount" :label="$t('trials:trials-list:table:UnSubmitCount')"
prop="UnSubmitCount" show-overflow-tooltip min-width="90" v-if="hasPermi(['role:pm'])" sortable="custom" />
:label="$t('trials:trials-list:table:UnSubmitCount')"
show-overflow-tooltip
min-width="90"
v-if="hasPermi(['role:pm'])"
sortable="custom"
/>
<!--待阅片数量--> <!--待阅片数量-->
<el-table-column <el-table-column prop="UnReadCount" :label="$t('trials:trials-list:table:UnReadCount')" show-overflow-tooltip
prop="UnReadCount" min-width="90" v-if="hasPermi(['role:pm', 'role:pi', 'role:sr'])" sortable="custom" />
:label="$t('trials:trials-list:table:UnReadCount')" <el-table-column prop="CreateTime" :label="$t('trials:trials-list:table:createDate')" show-overflow-tooltip
show-overflow-tooltip min-width="170" sortable="custom" />
min-width="90"
v-if="hasPermi(['role:pm', 'role:pi', 'role:sr'])"
sortable="custom"
/>
<el-table-column
prop="CreateTime"
:label="$t('trials:trials-list:table:createDate')"
show-overflow-tooltip
min-width="170"
sortable="custom"
/>
<!--到期日--> <!--到期日-->
<el-table-column <el-table-column prop="AuthorizationDate" :label="$t('trials:trials-list:table:dateAuthorized')"
prop="AuthorizationDate" show-overflow-tooltip min-width="170" sortable="custom" />
:label="$t('trials:trials-list:table:dateAuthorized')"
show-overflow-tooltip
min-width="170"
sortable="custom"
/>
<!--授权时长--> <!--授权时长-->
<!-- <el-table-column <!-- <el-table-column
prop="AuthorizationDuration" prop="AuthorizationDuration"
@ -260,122 +140,53 @@
<el-table-column label="" min-width="200" align="left" fixed="right"> <el-table-column label="" min-width="200" align="left" fixed="right">
<template slot-scope="scope"> <template slot-scope="scope">
<!-- 详情 --> <!-- 详情 -->
<el-button <el-button v-hasPermi="['trials:trials-list:panel']" circle icon="el-icon-info"
v-hasPermi="['trials:trials-list:panel']" :disabled="scope.row.IsDeleted" :title="$t('trials:trials-list:action:panel')"
circle @click.stop="handleDetail(scope.row)" />
icon="el-icon-info"
:disabled="scope.row.IsDeleted"
:title="$t('trials:trials-list:action:panel')"
@click.stop="handleDetail(scope.row)"
/>
<!-- 编辑项目基本信息 --> <!-- 编辑项目基本信息 -->
<el-button <el-button v-hasPermi="['trials:trials-list:edit']" circle icon="el-icon-edit-outline"
v-hasPermi="['trials:trials-list:edit']" :disabled="scope.row.IsDeleted" :title="$t('trials:trials-list:action:edit')"
circle @click.stop="handleEdit(scope.row)" />
icon="el-icon-edit-outline"
:disabled="scope.row.IsDeleted"
:title="$t('trials:trials-list:action:edit')"
@click.stop="handleEdit(scope.row)"
/>
<!-- 修改项目状态 --> <!-- 修改项目状态 -->
<el-button <el-button v-hasPermi="['trials:trials-list:status']" circle icon="el-icon-edit"
v-hasPermi="['trials:trials-list:status']" :disabled="scope.row.IsDeleted" :title="$t('trials:trials-list:action:status')"
circle @click.stop="handleStatus(scope.row)" />
icon="el-icon-edit"
:disabled="scope.row.IsDeleted"
:title="$t('trials:trials-list:action:status')"
@click.stop="handleStatus(scope.row)"
/>
<!-- 废除项目 --> <!-- 废除项目 -->
<el-button <el-button v-hasPermi="['trials:trials-list:abolish']" circle icon="el-icon-delete" :disabled="scope.row.IsDeleted ||
v-hasPermi="['trials:trials-list:abolish']" scope.row.TrialStatusStr !== 'Initializing'
circle " :title="$t('trials:trials-list:action:abolition')" @click.stop="handleAbandon(scope.row)" />
icon="el-icon-delete"
:disabled="
scope.row.IsDeleted ||
scope.row.TrialStatusStr !== 'Initializing'
"
:title="$t('trials:trials-list:action:abolition')"
@click.stop="handleAbandon(scope.row)"
/>
<!-- 激活 --> <!-- 激活 -->
<el-button <el-button v-if="!scope.row.AuthorizationEncrypt" v-hasPermi="['trials:trials-list:activate']" circle
v-if="!scope.row.AuthorizationEncrypt" icon="el-icon-key" :title="$t('trials:trials-list:action:activate')"
v-hasPermi="['trials:trials-list:activate']" @click.stop="handleActivate(scope.row)" />
circle
icon="el-icon-key"
:title="$t('trials:trials-list:action:activate')"
@click.stop="handleActivate(scope.row)"
/>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!-- 分页组件 --> <!-- 分页组件 -->
<pagination <pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
class="page" @pagination="getList" />
:total="total"
:page.sync="searchData.PageIndex"
:limit.sync="searchData.PageSize"
@pagination="getList"
/>
</template> </template>
<!-- 新增/编辑项目 --> <!-- 新增/编辑项目 -->
<el-dialog <el-dialog v-if="dialogVisible" :visible.sync="dialogVisible" :title="title" :fullscreen="true" append-to-body
v-if="dialogVisible" custom-class="base-dialog-wrapper">
:visible.sync="dialogVisible" <TrialForm :trial-id="currentId" @getList="getList" @closeDialog="closeDialog" />
:title="title"
:fullscreen="true"
append-to-body
custom-class="base-dialog-wrapper"
>
<TrialForm
:trial-id="currentId"
@getList="getList"
@closeDialog="closeDialog"
/>
</el-dialog> </el-dialog>
<!-- 修改项目状态 --> <!-- 修改项目状态 -->
<el-dialog <el-dialog v-dialogDrag v-if="statusVisible" :visible.sync="statusVisible" :close-on-click-modal="false"
v-dialogDrag :title="$t('trials:trials-list:dialogTitle:changeStatus')" width="700px" custom-class="base-dialog-wrapper"
v-if="statusVisible" append-to-body>
:visible.sync="statusVisible" <TrialStatusForm :data="currentRow" @close="closeStatusDialog" @getList="getList" />
:close-on-click-modal="false"
:title="$t('trials:trials-list:dialogTitle:changeStatus')"
width="700px"
custom-class="base-dialog-wrapper"
append-to-body
>
<TrialStatusForm
:data="currentRow"
@close="closeStatusDialog"
@getList="getList"
/>
</el-dialog> </el-dialog>
<el-dialog <el-dialog v-if="doneDialogVisible" :visible.sync="doneDialogVisible" :title="doneTitle" :fullscreen="true"
v-if="doneDialogVisible" append-to-body custom-class="base-dialog-wrapper">
:visible.sync="doneDialogVisible" <DoneList :trial-id="currentId" @getList="getList" @closeDialog="doneDialogVisible = false" />
:title="doneTitle"
:fullscreen="true"
append-to-body
custom-class="base-dialog-wrapper"
>
<DoneList
:trial-id="currentId"
@getList="getList"
@closeDialog="doneDialogVisible = false"
/>
</el-dialog> </el-dialog>
<!--项目激活--> <!--项目激活-->
<activateProject <activateProject v-if="activateVisible" :visible.sync="activateVisible" :data="currentRow" @getList="getList" />
v-if="activateVisible"
:visible.sync="activateVisible"
:data="currentRow"
@getList="getList"
/>
</BaseContainer> </BaseContainer>
</template> </template>
<script> <script>
@ -479,6 +290,11 @@ export default {
created() { created() {
this.initPage(); this.initPage();
}, },
mounted() {
this.$EventBus.$on('reload', (data) => {
window.location.reload()
})
},
methods: { methods: {
// //
moment(data) { moment(data) {
@ -592,7 +408,7 @@ export default {
this.currentRow = { ...row }; this.currentRow = { ...row };
this.abandonTrial(); this.abandonTrial();
}) })
.catch(() => {}); .catch(() => { });
}, },
// //
abandonTrial() { abandonTrial() {

View File

@ -14,25 +14,25 @@
<!-- </div>--> <!-- </div>-->
<!-- 一致性核查 --> <!-- 一致性核查 -->
<div v-if="hasPermi(['trials:trials-workbench:consistencyCheck'])" class="item"> <div v-if="hasPermi(['trials:trials-workbench:consistencyCheck'])" class="item">
<el-card :body-style="{ padding: '10px'}" style="height:100%"> <el-card :body-style="{ padding: '10px' }" style="height:100%">
<consistencyCheck /> <consistencyCheck />
</el-card> </el-card>
</div> </div>
<!-- 重阅审批 --> <!-- 重阅审批 -->
<div v-if="hasPermi(['trials:trials-workbench:rereadApproval'])" class="item"> <div v-if="hasPermi(['trials:trials-workbench:rereadApproval'])" class="item">
<el-card :body-style="{ padding: '10px'}" style="height:100%"> <el-card :body-style="{ padding: '10px' }" style="height:100%">
<RereadApproval /> <RereadApproval />
</el-card> </el-card>
</div> </div>
<!-- 阅片人筛选 --> <!-- 阅片人筛选 -->
<div v-if="hasPermi(['trials:trials-workbench:reviewerScreen'])" class="item"> <div v-if="hasPermi(['trials:trials-workbench:reviewerScreen'])" class="item">
<el-card :body-style="{ padding: '10px'}" style="height:100%"> <el-card :body-style="{ padding: '10px' }" style="height:100%">
<ReviewerScreen /> <ReviewerScreen />
</el-card> </el-card>
</div> </div>
<!-- 中心调研 --> <!-- 中心调研 -->
<div v-hasPermi="['trials:trials-workbench:attachments:site-research']" class="item"> <div v-hasPermi="['trials:trials-workbench:attachments:site-research']" class="item">
<el-card :body-style="{ padding: '10px'}" style="height:100%"> <el-card :body-style="{ padding: '10px' }" style="height:100%">
<SiteResearch /> <SiteResearch />
</el-card> </el-card>
</div> </div>
@ -40,13 +40,13 @@
<!-- SPM/CPM --> <!-- SPM/CPM -->
<!-- 阅片人审批 --> <!-- 阅片人审批 -->
<div v-if="hasPermi(['trials:trials-workbench:reviewerApproval'])" class="item"> <div v-if="hasPermi(['trials:trials-workbench:reviewerApproval'])" class="item">
<el-card :body-style="{ padding: '10px'}" style="height:100%"> <el-card :body-style="{ padding: '10px' }" style="height:100%">
<ReviewerApproval /> <ReviewerApproval />
</el-card> </el-card>
</div> </div>
<!-- 重阅审批 --> <!-- 重阅审批 -->
<div v-if="hasPermi(['trials:trials-workbench:spmRereadApproval'])" class="item"> <div v-if="hasPermi(['trials:trials-workbench:spmRereadApproval'])" class="item">
<el-card :body-style="{ padding: '10px'}" style="height:100%"> <el-card :body-style="{ padding: '10px' }" style="height:100%">
<SpmRereadApproval /> <SpmRereadApproval />
</el-card> </el-card>
</div> </div>
@ -54,83 +54,83 @@
<!-- CRC --> <!-- CRC -->
<!-- 临床数据录入 --> <!-- 临床数据录入 -->
<div v-if="hasPermi(['trials:trials-workbench:clinicalDataEntry'])" class="item"> <div v-if="hasPermi(['trials:trials-workbench:clinicalDataEntry'])" class="item">
<el-card :body-style="{ padding: '10px'}" style="height:100%"> <el-card :body-style="{ padding: '10px' }" style="height:100%">
<clinicalData /> <clinicalData />
</el-card> </el-card>
</div> </div>
<!-- 临床数据确认 --> <!-- 临床数据确认 -->
<div v-if="hasPermi(['trials:trials-workbench:clinicalDataEntry'])" class="item"> <div v-if="hasPermi(['trials:trials-workbench:clinicalDataEntry'])" class="item">
<el-card :body-style="{ padding: '10px'}" style="height:100%"> <el-card :body-style="{ padding: '10px' }" style="height:100%">
<clinicalDataConfirm /> <clinicalDataConfirm />
</el-card> </el-card>
</div> </div>
<!-- 影像质疑 --> <!-- 影像质疑 -->
<div v-if="hasPermi(['trials:trials-workbench:imageQuestion'])" class="item"> <div v-if="hasPermi(['trials:trials-workbench:imageQuestion'])" class="item">
<el-card :body-style="{ padding: '10px'}" style="height:100%"> <el-card :body-style="{ padding: '10px' }" style="height:100%">
<ImageQuestion /> <ImageQuestion />
</el-card> </el-card>
</div> </div>
<!-- 核查质疑 --> <!-- 核查质疑 -->
<div v-if="hasPermi(['trials:trials-workbenck:imageVerification'])" class="item"> <div v-if="hasPermi(['trials:trials-workbenck:imageVerification'])" class="item">
<el-card :body-style="{ padding: '10px'}" style="height:100%"> <el-card :body-style="{ padding: '10px' }" style="height:100%">
<ImageVerification /> <ImageVerification />
</el-card> </el-card>
</div> </div>
<!-- 影像重传 --> <!-- 影像重传 -->
<div v-if="hasPermi(['trials:trials-workbenck:imageReupload'])" class="item"> <div v-if="hasPermi(['trials:trials-workbenck:imageReupload'])" class="item">
<el-card :body-style="{ padding: '10px'}" style="height:100%"> <el-card :body-style="{ padding: '10px' }" style="height:100%">
<ImageReupload /> <ImageReupload />
</el-card> </el-card>
</div> </div>
<!-- 加急影像提交 --> <!-- 加急影像提交 -->
<div v-if="hasPermi(['trials:trials-workbenck:imageSubmission'])" class="item"> <div v-if="hasPermi(['trials:trials-workbenck:imageSubmission'])" class="item">
<el-card :body-style="{ padding: '10px'}" style="height:100%"> <el-card :body-style="{ padding: '10px' }" style="height:100%">
<ImageSubmission /> <ImageSubmission />
</el-card> </el-card>
</div> </div>
<!-- IQC --> <!-- IQC -->
<!-- 影像质控 --> <!-- 影像质控 -->
<div v-if="hasPermi(['trials:trials-workbenck:imageQC'])" class="item"> <div v-if="hasPermi(['trials:trials-workbenck:imageQC'])" class="item">
<el-card :body-style="{ padding: '10px'}" style="height:100%"> <el-card :body-style="{ padding: '10px' }" style="height:100%">
<ImageQualityControl /> <ImageQualityControl />
</el-card> </el-card>
</div> </div>
<!-- QC质疑 --> <!-- QC质疑 -->
<div v-if="hasPermi(['trials:trials-workbenck:qcQuestion'])" class="item"> <div v-if="hasPermi(['trials:trials-workbenck:qcQuestion'])" class="item">
<el-card :body-style="{ padding: '10px'}" style="height:100%"> <el-card :body-style="{ padding: '10px' }" style="height:100%">
<QcQuestion /> <QcQuestion />
</el-card> </el-card>
</div> </div>
<!-- IR --> <!-- IR -->
<!-- 影像待阅 --> <!-- 影像待阅 -->
<div v-if="hasPermi(['trials:trials-workbenck:imagesToRead'])" class="item"> <div v-if="hasPermi(['trials:trials-workbenck:imagesToRead'])" class="item">
<el-card :body-style="{ padding: '10px'}" style="height:100%"> <el-card :body-style="{ padding: '10px' }" style="height:100%">
<ImagesToRead /> <ImagesToRead />
</el-card> </el-card>
</div> </div>
<!-- 医学反馈 --> <!-- 医学反馈 -->
<div v-if="hasPermi(['trials:trials-workbenck:medicalFeedback'])" class="item"> <div v-if="hasPermi(['trials:trials-workbenck:medicalFeedback'])" class="item">
<el-card :body-style="{ padding: '10px'}" style="height:100%"> <el-card :body-style="{ padding: '10px' }" style="height:100%">
<MedicalFeedback /> <MedicalFeedback />
</el-card> </el-card>
</div> </div>
<!-- MIM --> <!-- MIM -->
<!-- 医学审核 --> <!-- 医学审核 -->
<div v-if="hasPermi(['trials:trials-workbenck:medicalAudit'])" class="item"> <div v-if="hasPermi(['trials:trials-workbenck:medicalAudit'])" class="item">
<el-card :body-style="{ padding: '10px'}" style="height:100%"> <el-card :body-style="{ padding: '10px' }" style="height:100%">
<MedicalAudit /> <MedicalAudit />
</el-card> </el-card>
</div> </div>
<div v-if="!hasPermi(['role:zys'])" class="item"> <div v-if="!hasPermi(['role:zys'])" class="item">
<el-card :body-style="{ padding: '10px'}" style="height:100%"> <el-card :body-style="{ padding: '10px' }" style="height:100%">
<NeedSignTrialDoc /> <NeedSignTrialDoc />
</el-card> </el-card>
</div> </div>
<div v-if="isSignSystemDoc || hasPermi(['role:zys'])" class="item"> <div v-if="isSignSystemDoc || hasPermi(['role:zys'])" class="item">
<el-card :body-style="{ padding: '10px'}" style="height:100%"> <el-card :body-style="{ padding: '10px' }" style="height:100%">
<NeedSignSysDoc @refreshStats="refreshStats" /> <NeedSignSysDoc @refreshStats="refreshStats" />
</el-card> </el-card>
</div> </div>
@ -181,15 +181,17 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
.workbench-container{ .workbench-container {
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 7px; width: 7px;
height: 7px; height: 7px;
} }
::-webkit-scrollbar-thumb { ::-webkit-scrollbar-thumb {
border-radius: 10px; border-radius: 10px;
background: #d0d0d0; background: #d0d0d0;
} }
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 100%; width: 100%;
@ -197,29 +199,34 @@ export default {
background-color: #fff; background-color: #fff;
overflow-x: hidden; overflow-x: hidden;
.workbench-stats{ .workbench-stats {
height: 120px; height: 120px;
} }
.workbench-content{
.workbench-content {
flex: 1; flex: 1;
overflow-y: auto; overflow-y: auto;
.content-wrapper{
.content-wrapper {
width: 100%; width: 100%;
height: 100%; height: 100%;
display: flex; display: flex;
flex-flow: wrap; flex-flow: wrap;
padding: 5px; padding: 5px;
.item{
.item {
width: 50%; width: 50%;
height: 500px; height: 500px;
padding: 5px; padding: 5px;
box-sizing: border-box; box-sizing: border-box;
.el-card__body{
.el-card__body {
height: 100%; height: 100%;
} }
} }
} }
} }
.table-row__p { .table-row__p {
color: #53646f; color: #53646f;
font-size: 13px; font-size: 13px;
@ -227,17 +234,20 @@ export default {
line-height: 18px; line-height: 18px;
margin-bottom: 0px; margin-bottom: 0px;
} }
.table-row__span { .table-row__span {
color: #9eabb4; color: #9eabb4;
font-weight: 300; font-weight: 300;
font-size: 12px; font-size: 12px;
} }
.el-row{
.el-col{ .el-row {
padding:5px; .el-col {
padding: 5px;
} }
} }
.status:before{
.status:before {
content: ''; content: '';
margin-bottom: 0; margin-bottom: 0;
width: 9px; width: 9px;
@ -246,43 +256,47 @@ export default {
margin-right: 7px; margin-right: 7px;
border-radius: 50%; border-radius: 50%;
} }
.status--red:before{
.status--red:before {
background-color: #e36767; background-color: #e36767;
} }
.status--red{ .status--red {
color: #e36767; color: #e36767;
} }
.status--blue:before{ .status--blue:before {
background-color: #3fd2ea; background-color: #3fd2ea;
} }
.status--blue{ .status--blue {
color: #3fd2ea; color: #3fd2ea;
} }
.status--yellow:before{ .status--yellow:before {
background-color: #ecce4e; background-color: #ecce4e;
} }
.status--yellow{ .status--yellow {
color: #ecce4e; color: #ecce4e;
} }
.status--green{ .status--green {
color: #6cdb56; color: #6cdb56;
} }
.status--green:before{
.status--green:before {
background-color: #6cdb56; background-color: #6cdb56;
} }
.status--grey{ .status--grey {
color: #9eabb4; color: #9eabb4;
} }
.status--grey:before{
.status--grey:before {
background-color: #9eabb4; background-color: #9eabb4;
} }
.chart-wrapper { .chart-wrapper {
background: #fff; background: #fff;
padding: 16px 16px 0; padding: 16px 16px 0;