Browse Source

管理员登录后台相关

pull/14/head
longchao 1 month ago
parent
commit
d56edd7df4
  1. 14
      package-lock.json
  2. 1
      package.json
  3. 52
      src/components/Header.vue
  4. 7
      src/main.js
  5. 2
      src/router/index.js
  6. 38
      src/utils/request.js
  7. 27
      src/views/HomeView.vue
  8. 9
      src/views/HosInformation.vue
  9. 172
      src/views/adminLogin.vue
  10. 25
      src/views/paymentMethod.vue

14
package-lock.json

@ -17,6 +17,7 @@
"vue-clickaway": "^2.2.2", "vue-clickaway": "^2.2.2",
"vue-qr": "^4.0.9", "vue-qr": "^4.0.9",
"vue-router": "^3.5.1", "vue-router": "^3.5.1",
"vue-wxlogin": "^1.0.5",
"vuex": "^3.6.2" "vuex": "^3.6.2"
}, },
"devDependencies": { "devDependencies": {
@ -11415,6 +11416,19 @@
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==", "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
"dev": true "dev": true
}, },
"node_modules/vue-wxlogin": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/vue-wxlogin/-/vue-wxlogin-1.0.5.tgz",
"integrity": "sha512-JJTL9qwROH7c/OWU8mube6Yd6kwUTItCg4tyjZQVby1MKWNuNz/f0eeRd0bhOdFyPSFmVazTF3nw+Jhfo4FzVA==",
"license": "MIT",
"dependencies": {
"vue": "^2.4.2"
},
"engines": {
"node": ">= 4.0.0",
"npm": ">= 3.0.0"
}
},
"node_modules/vuex": { "node_modules/vuex": {
"version": "3.6.2", "version": "3.6.2",
"resolved": "https://registry.npmmirror.com/vuex/-/vuex-3.6.2.tgz", "resolved": "https://registry.npmmirror.com/vuex/-/vuex-3.6.2.tgz",

1
package.json

@ -17,6 +17,7 @@
"vue-clickaway": "^2.2.2", "vue-clickaway": "^2.2.2",
"vue-qr": "^4.0.9", "vue-qr": "^4.0.9",
"vue-router": "^3.5.1", "vue-router": "^3.5.1",
"vue-wxlogin": "^1.0.5",
"vuex": "^3.6.2" "vuex": "^3.6.2"
}, },
"devDependencies": { "devDependencies": {

52
src/components/Header.vue

@ -33,27 +33,36 @@ export default {
user: '', user: '',
headerShow:false, headerShow:false,
doctor_id:'', doctor_id:'',
authtoken:false,
currentPath:'', currentPath:'',
routerNavList:[ routerNavList:[
{ // {
name:'个人信息', // name:'',
path:'/doctorInformation' // path:'/doctorInformation'
}, // },
{ // {
name:'医院管理', // name:'',
path:'/hospitalManage' // path:'/hospitalManage'
}, // },
{ // {
name:'收款管理', // name:'',
path:'/paymentMethod' // path:'/paymentMethod'
}, // },
] ]
} }
}, },
mounted(){ mounted(){
this.user = localStorage.getItem('nick') this.user = localStorage.getItem('user_name')
var user_type = localStorage.getItem('user_type')
if(!user_type || user_type == 'undefined') {
this.user = '超级管理员'
}else{
if(user_type && user_type != 'undefined') this.user = (user_type == 1?'医生':'助手') + this.user
}
this.doctor_id = localStorage.getItem('doctor_id') this.doctor_id = localStorage.getItem('doctor_id')
if(this.user){ this.authtoken = localStorage.getItem('authtoken')
if(this.authtoken){
this.headerShow = true this.headerShow = true
// //
this.updateCurrentPath() this.updateCurrentPath()
@ -76,21 +85,12 @@ export default {
}) })
}, },
loginOut(){ loginOut(){
// 退
this.$http('POST', '/login_out', {}).then(response => {
if(response.status){
// ---
localStorage.removeItem('token'); localStorage.removeItem('token');
localStorage.removeItem('nick'); localStorage.removeItem('user_name');
localStorage.removeItem('authtoken');
localStorage.removeItem('user_type');
localStorage.removeItem('doctor_id'); localStorage.removeItem('doctor_id');
// 退
this.$router.push('/login'); this.$router.push('/login');
}else{
this.$message.error(response.data.info)
}
}).catch(error => {
console.error(error, 'error')
})
}, },
// //
updateCurrentPath() { updateCurrentPath() {

7
src/main.js

@ -25,6 +25,13 @@ Vue.directive('clickaway', clickaway);
Vue.mixin(HeaderIcon) Vue.mixin(HeaderIcon)
Vue.use(PositionMessage) Vue.use(PositionMessage)
window.issuper = true;
var user_type = localStorage.getItem('user_type')
if(user_type && user_type != 'undefined') window.issuper = false;
window.doctor_id = localStorage.getItem('doctor_id');
new Vue({ new Vue({
router, router,
store, store,

2
src/router/index.js

@ -11,7 +11,7 @@ const routes = [
{ {
path: '/login', path: '/login',
name: '登录', name: '登录',
component: () => import('../views/login.vue'), component: () => import('../views/adminLogin.vue'),
meta: { meta: {
hideBreadcrumb: true, // 首页不显示面包屑 hideBreadcrumb: true, // 首页不显示面包屑
requiresAuth:false requiresAuth:false

38
src/utils/request.js

@ -17,18 +17,19 @@ service.interceptors.request.use(
// 在发送请求之前做一些处理,例如添加 token // 在发送请求之前做一些处理,例如添加 token
// const token = localStorage.getItem("token"); // const token = localStorage.getItem("token");
const token = localStorage.getItem("authtoken"); const token = localStorage.getItem("authtoken");
const doctor_id = localStorage.getItem("doctor_id");
// 检查是否存在 token,如果不存在则跳转到登录页 // 检查是否存在 token,如果不存在则跳转到登录页
if (!token) { if (!token && location.pathname != '/login' && location.href.indexOf('/login') == -1) {
// 可以根据需要决定是否提示用户 // 可以根据需要决定是否提示用户
console.warn("未检测到登录信息,请重新登录"); console.warn("未检测到登录信息,请重新登录");
window.location.href = "/login"; window.location.href = "/login";
return Promise.reject(new Error("未登录")); return Promise.reject(new Error("未登录"));
} }
if (token) { if (token) config.headers["Auth"] = `${token}`;
config.headers["Auth"] = `${token}`; if (doctor_id) config.headers["DID"] = `${doctor_id}`;
}
return config; return config;
}, },
(error) => { (error) => {
@ -68,10 +69,19 @@ service.interceptors.response.use(
console.error("请求失败", error.message); console.error("请求失败", error.message);
} }
} }
return Promise.reject(error); return Promise.reject(error);
} }
); );
function logout() {
localStorage.removeItem('authtoken')
localStorage.removeItem('doctor_id')
localStorage.removeItem('user_name')
localStorage.removeItem('user_type')
location.href = '/login'
}
/** /**
* 封装请求方法 * 封装请求方法
* @param {string} method 请求方法 (GET, POST, PUT, DELETE ) * @param {string} method 请求方法 (GET, POST, PUT, DELETE )
@ -91,9 +101,13 @@ const request = (method, url, data = {}, config = {}) => {
...config, ...config,
}); });
res.then(response => { res.then(response => {
if(response && response.msg && response.msg.indexOf('非法操作') > -1) { if(response && response.msg && response.msg.indexOf('您没有访问权限~~~') > -1) {
localStorage.removeItem('authtoken') location.href = '/'
location.href = '/ErrorAccess' return;
}
if(response && response.msg && (response.msg.indexOf('非法操作') > -1 || response.code == 40002)) {
logout()
return; return;
} }
}).catch(error => { }).catch(error => {
@ -111,9 +125,13 @@ const request = (method, url, data = {}, config = {}) => {
}); });
respost.then(response => { respost.then(response => {
if(response && response.msg && response.msg.indexOf('非法操作') > -1) { if(response && response.msg && response.msg.indexOf('您没有访问权限~~~') > -1) {
localStorage.removeItem('authtoken') location.href = '/'
location.href = '/ErrorAccess' return;
}
if(response && response.msg && (response.msg.indexOf('非法操作') > -1 || response.code == 40002)) {
logout()
return; return;
} }
}).catch(error => { }).catch(error => {

27
src/views/HomeView.vue

@ -1,7 +1,7 @@
<template> <template>
<div class="min-width pagePadding " style="background: #F5F7FA;" v-if="pageShow"> <div class="min-width pagePadding " style="background: #F5F7FA;" v-if="pageShow">
<div class="doctor-list-wrap "> <div class="doctor-list-wrap ">
<p class="pageTitle">{{onlyHosFlag ? '医院管理' :'医生列表'}}</p> <p class="pageTitle">{{issuper ? '医院管理' :'医生列表'}}</p>
<el-form> <el-form>
<div class="selectAllTable-wrap flex-between mt32"> <div class="selectAllTable-wrap flex-between mt32">
<div class="left flex"> <div class="left flex">
@ -16,8 +16,8 @@
@click="batchOperate('1')"> @click="batchOperate('1')">
批量启用</GuipButton> 批量启用</GuipButton>
</div> </div>
<div class="right" v-if="onlyHosFlag"> <div class="right" v-if="!issuper">
<GuipButton type="system" size="form" @click="addHospitalUser">添加医院</GuipButton> <GuipButton type="system" size="form" @click="addHospital(false)">添加医院</GuipButton>
</div> </div>
<div class="right flex" v-else> <div class="right flex" v-else>
<span>搜索医生</span> <span>搜索医生</span>
@ -29,7 +29,7 @@
</div> </div>
<div class="tableList mt32" v-for="(item, index) in doctorList" :key="index"> <div class="tableList mt32" v-for="(item, index) in doctorList" :key="index">
<div class="top flex-between mb24" v-if="!onlyHosFlag"> <div class="top flex-between mb24" v-if="issuper">
<div class="left left1 flex"> <div class="left left1 flex">
<el-checkbox @change="handleCheckAllChange(index)" v-model="item.checked"></el-checkbox> <el-checkbox @change="handleCheckAllChange(index)" v-model="item.checked"></el-checkbox>
<el-avatar :src="item.avator" v-if="item.avator"></el-avatar> <el-avatar :src="item.avator" v-if="item.avator"></el-avatar>
@ -147,7 +147,8 @@ export default {
allChecked: false, allChecked: false,
pageShow:false, pageShow:false,
doctorIds:[], doctorIds:[],
payList:false payList:false,
issuper:false
} }
}, },
components: { components: {
@ -162,16 +163,20 @@ export default {
// CustomDropdown // CustomDropdown
}, },
created() { created() {
console.log(this.onlyHosFlag,'onlyHosFlag==='); const { authtoken, did, type, name} = this.$route.query;
const { authtoken } = this.$route.query;
if(authtoken) { if(authtoken) {
localStorage.setItem('authtoken', authtoken); localStorage.setItem('authtoken', decodeURIComponent(authtoken));
localStorage.setItem('doctor_id', did);
localStorage.setItem('user_type', type);
localStorage.setItem('user_name', name);
location.href = '/' location.href = '/'
return; return;
} }
store.commit('SET_PAGENAME', '医生管理'); // store.commit('SET_PAGENAME', '医生管理'); //
}, },
mounted() { mounted() {
this.issuper = window.issuper
store.commit('SET_CUSTOMIZE', false); store.commit('SET_CUSTOMIZE', false);
store.commit('SET_SLIDER_MENU', 'menuData'); store.commit('SET_SLIDER_MENU', 'menuData');
this.getInitData() this.getInitData()
@ -397,9 +402,13 @@ export default {
}) })
}, },
addHospital(item) { addHospital(item) {
var docotr_id = window.doctor_id
if(item) {
docotr_id = item.id
}
this.$router.push({ this.$router.push({
name: '医院信息', name: '医院信息',
query: { doctor_id: item.id } query: { doctor_id: docotr_id }
}) })
}, },
addHospitalUser(){ addHospitalUser(){

9
src/views/HosInformation.vue

@ -712,7 +712,6 @@ export default {
this.depart_id = depart_id; this.depart_id = depart_id;
this.doctor_id = doctor_id; this.doctor_id = doctor_id;
await this.fetchDoctorData() await this.fetchDoctorData()
console.log(this.doctor_id)
await this.getAreaData() await this.getAreaData()
this.fetchPackData() this.fetchPackData()
this.fetchProjectData() this.fetchProjectData()
@ -730,12 +729,14 @@ export default {
this.doctor_id = newVal.doctor_id; this.doctor_id = newVal.doctor_id;
this.depart_id = newVal.depart_id; this.depart_id = newVal.depart_id;
this.getAreaData(); this.getAreaData();
if(this.depart_id) {
this.fetchDoctorData(); this.fetchDoctorData();
this.fetchPackData(); this.fetchPackData();
this.fetchProjectData(); this.fetchProjectData();
this.geHosAdress(); this.geHosAdress();
} }
} }
}
}, },
computed: { computed: {
selectedCount() { selectedCount() {
@ -1027,6 +1028,12 @@ export default {
depart_id: this.depart_id, depart_id: this.depart_id,
doctor_id: this.doctor_id doctor_id: this.doctor_id
}).then(response => { }).then(response => {
if(response.code != 0) {
this.$Message.error(response.msg);
// location.href = '/'
return;
}
this.form = { this.form = {
...this.form, ...response.data, ...this.form, ...response.data,
'morning_worktime': response.data.morning_worktime ? response.data.morning_worktime.split('-') : '', 'morning_worktime': response.data.morning_worktime ? response.data.morning_worktime.split('-') : '',

172
src/views/adminLogin.vue

@ -4,15 +4,22 @@
<div class="index_rootContainer"> <div class="index_rootContainer">
<b class="title">扫码登录</b> <b class="title">扫码登录</b>
<p class="sub_title mt32">打开 <b>微信</b> 扫码登录</p> <p class="sub_title mt32">打开 <b>微信</b> 扫码登录</p>
<div class=" mb32" v-if="status == 'waiting'"> <div class="wxlogin-qrcode-box mb32" v-if="status == 'waiting'">
<vue-qr :text="qrCodeUrl" :size="192" :dot-scale="1"></vue-qr> <Wxlogin
v-if="appid && redirect_uri"
:appid="appid"
:redirect_uri="redirect_uri"
scope="snsapi_login"
:state="state"
height="186px"
href="data:text/css;base64,LmltcG93ZXJCb3ggLnFyY29kZSB7d2lkdGg6IDE4OHB4O2JvcmRlcjpub25lO21hcmdpbi10b3A6MHB4O30KLmltcG93ZXJCb3ggLnRpdGxlIHtkaXNwbGF5OiBub25lO30KLmltcG93ZXJCb3ggLmluZm8ge3dpZHRoOiAxODhweDtkaXNwbGF5Om5vbmU7fQouc3RhdHVzX2ljb24ge2Rpc3BsYXk6IG5vbmV9Ci5pbXBvd2VyQm94IC5zdGF0dXMge3RleHQtYWxpZ246IGNlbnRlcjt9Ci53ZWJfcXJjb2RlX3R5cGVfaWZyYW1le2hlaWdodDoxODZweDt9Ci53ZWJfcXJjb2RlX3N3aXRjaF93cnAuanNfc3dpdGNoVG9GYXN0X3dycHttYXJnaW4tdG9wOjBweCAhaW1wb3J0YW50O2NvbG9yOiAjOEE5MDk5ICFpbXBvcnRhbnQ7fQoud2ViX3FyY29kZV9zd2l0Y2hfd3JwLmpzX3N3aXRjaFRvRmFzdF93cnAgYnV0dG9ue2NvbG9yOiAjOEE5MDk5ICFpbXBvcnRhbnQ7Y3Vyc29yOnBvaW50ZXI7fQoud2ViX3FyY29kZV9zd2l0Y2hfd3JwLmpzX3N3aXRjaFRvTm9ybWFsX3dycCBidXR0b257Y29sb3I6ICM4QTkwOTkgIWltcG9ydGFudDtjdXJzb3I6cG9pbnRlcjt9"
></Wxlogin>
</div> </div>
<div class="refreshCode" v-if="status == 'expired'" @click="refreshCode"> <div class="refreshCode" v-if="status == 'expired'" @click="refreshCode">
<i class="el-icon-refresh"></i> <i class="el-icon-refresh"></i>
刷新二维码 刷新二维码
</div> </div>
<!-- :logo-src="logoUrl"
:logo-scale="0.2" -->
<div class="attention gap10"> <div class="attention gap10">
<el-checkbox v-model="checked"></el-checkbox> <el-checkbox v-model="checked"></el-checkbox>
<b>登录即代表同意 <a @click="jumpDoc">用户协议</a> <a @click="jumpDoc">隐私条款</a></b> <b>登录即代表同意 <a @click="jumpDoc">用户协议</a> <a @click="jumpDoc">隐私条款</a></b>
@ -40,123 +47,44 @@
</div> </div>
</template> </template>
<script> <script>
import VueQr from 'vue-qr' import Wxlogin from 'vue-wxlogin';
export default { export default {
components: { components: {
VueQr Wxlogin
}, },
data() { data() {
return { return {
checked: true, checked: true,
qrCodeUrl: 'https://example.com', qrCodeUrl: 'https://example.com',
token: '', token: '',
status: 'expired', // waiting, scanned, confirmed, expired, error status: 'expired',
loginTime:'', loginTime:'',
appid:false,
redirectUri:false,
state:'zjadmin'
} }
}, },
created(){ created(){
// this.generateQRCode() this.getLoginConfig()
},
beforeDestroy() {
this.clearTimers();
}, },
methods: { methods: {
jumpDoc() { async getLoginConfig() {
},
//
refreshCode() {
},
async generateQRCode() {
this.status = 'waiting'; this.status = 'waiting';
this.qrCodeUrl = ''; this.redirect_uri = '';
return this.appid = '';
// try { try {
// await this.$http('POST', '/api/admin/generate_qrcode', { await this.$http('POST', '/api/callback/get_admin_login_config').then(response => {
// device_type: 'web', this.appid = response.data.appid
// timestamp: Date.now() this.redirect_uri = response.data.redirect_uri
// }).then(response => { }).catch(error => {
// this.token = response.data.token; console.error('生成二维码失败:', error);
// this.qrCodeUrl = response.data.qr_code_url; this.status = 'error';
});
// // } catch (error) {
// this.startPolling(); console.error('生成二维码失败:', error);
this.status = 'error';
// // 5 }
// this.setExpireTimer();
// }).catch(error => {
// console.error(':', error);
// this.status = 'error';
// });
// } catch (error) {
// console.error(':', error);
// this.status = 'error';
// }
},
//
startPolling() {
this.clearTimers();
// this.pollInterval = setInterval(async () => {
// if (this.status === 'confirmed' || this.status === 'expired' || this.status === 'error') {
// this.clearTimers();
// return;
// }
// try {
// await this.$http('POST', '/api/admin/check_scan_status', {
// token: this.token
// }).then(response => {
// this.status = response.data.status;
// if (response.data.status === 'scanned') {
// //
// setTimeout(() => {
// this.handleLoginConfirm();
// }, 2000);
// } else if (response.data.status === 'confirmed') {
// this.handleLoginSuccess(response.data);
// } else if (response.data.status === 'expired') {
// this.status = 'expired';
// this.clearTimers();
// }
// }).catch(error => {
// console.error(':', error);
// this.status = 'error';
// this.clearTimers();
// });
// } catch (error) {
// console.error(':', error);
// this.status = 'error';
// this.clearTimers();
// }
// }, 2000);
},
//
async handleLoginConfirm() {
// try {
// await this.$http('POST', '/api/admin/confirm_login', {
// token: this.token
// }).then(response => {
// if (response.data.success) {
// this.handleLoginSuccess(response.data);
// } else {
// this.status = 'expired';
// }
// }).catch(error => {
// console.error(':', error);
// this.status = 'error';
// });
// } catch (error) {
// console.error(':', error);
// this.status = 'error';
// }
}, },
//
handleLoginSuccess(data) { handleLoginSuccess(data) {
this.status = 'confirmed'; this.status = 'confirmed';
this.userInfo = data.user_info; this.userInfo = data.user_info;
@ -172,30 +100,6 @@ export default {
this.$emit('login-success', data); this.$emit('login-success', data);
}, 1000); }, 1000);
}, },
//
setExpireTimer() {
this.expireTimer = setTimeout(() => {
if (this.status !== 'confirmed') {
this.status = 'expired';
this.clearTimers();
}
}, 5 * 60 * 1000); // 5
},
//
clearTimers() {
if (this.pollInterval) {
clearInterval(this.pollInterval);
this.pollInterval = null;
}
if (this.expireTimer) {
clearTimeout(this.expireTimer);
this.expireTimer = null;
}
},
} }
} }
</script> </script>
@ -246,6 +150,10 @@ export default {
color: #626573; color: #626573;
margin-top: 32px; margin-top: 32px;
margin-bottom: 12px; margin-bottom: 12px;
b{
font-weight: bold;
color: #1E2226;
}
} }
.img { .img {
@ -379,4 +287,10 @@ export default {
#ecomLoginForm { #ecomLoginForm {
height: 280px; height: 280px;
} }
.wxlogin-qrcode-box{
div:first-of-type{
height: 214px;
}
}
</style> </style>

25
src/views/paymentMethod.vue

@ -21,7 +21,13 @@
</el-table-column> </el-table-column>
<el-table-column prop="company_short_name" label="公司简称" min-width="160px"></el-table-column> <el-table-column prop="company_short_name" label="公司简称" min-width="160px"></el-table-column>
<el-table-column prop="appid" label="账号" min-width="288px"></el-table-column> <el-table-column prop="appid" label="账号" min-width="288px"></el-table-column>
<el-table-column prop="expires_time_desc" label="有效期" min-width="260px"></el-table-column> <el-table-column prop="expires_time_desc" label="有效期" min-width="260px">
<template slot-scope="scope">
<div :class="scope.row.expires_time_desc=='已过期' || scope.row.expires_time_desc=='未授权'?' error':''">
{{scope.row.expires_time_desc}}
</div>
</template>
</el-table-column>
<el-table-column prop="status" label="上传证书" min-width="258px"> <el-table-column prop="status" label="上传证书" min-width="258px">
<template slot-scope="scope"> <template slot-scope="scope">
<div :class="'flex'+(scope.row.have_cert?'':' error')" v-if="scope.row.type == 2"> <div :class="'flex'+(scope.row.have_cert?'':' error')" v-if="scope.row.type == 2">
@ -104,7 +110,6 @@ export default {
}, },
watch:{ watch:{
list: { list: {
deep: true, deep: true,
handler(newVal) { handler(newVal) {
@ -126,23 +131,7 @@ export default {
this.doctorId =doctor_id; this.doctorId =doctor_id;
} }
}, },
mounted() {
if(this.doctor_id){
this.getBindpayList()
}
},
methods: { methods: {
async getBindpayList() {
await this.$http('POST', '/api/admin/get_pay_list', {
doctor_id: this.doctor_id,
depart_id: this.depart_id,
index:1
}).then(response => {
this.payList = response.data;
}).catch(error => {
console.error(error, 'error')
})
},
handleEvent(data) { handleEvent(data) {
this.isShowAddPay = data; this.isShowAddPay = data;
}, },

Loading…
Cancel
Save