Browse Source

Merge pull request 'calender-1105' (#15) from calender-1105 into master

Reviewed-on: #15
master
超级管理员 3 weeks ago
parent
commit
4d7b55109e
  1. 31
      package-lock.json
  2. 1
      src/assets/site/prompt-icon-1.svg
  3. 1
      src/assets/site/prompt-icon-2.svg
  4. 1
      src/assets/site/prompt-icon-3.svg
  5. 6
      src/components/GroupFormBtns.vue
  6. 97
      src/components/PromptText.vue
  7. 17
      src/store/index.js
  8. 202
      src/views/DoctorInformation.vue
  9. 2384
      src/views/HosInformation.vue
  10. 553
      src/views/conflictDialog.vue

31
package-lock.json

@ -17,7 +17,6 @@
"vue-clickaway": "^2.2.2",
"vue-qr": "^4.0.9",
"vue-router": "^3.5.1",
"vue-wxlogin": "^1.0.5",
"vuex": "^3.6.2"
},
"devDependencies": {
@ -4994,7 +4993,6 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
"license": "MIT",
"dependencies": {
"mimic-response": "^3.1.0"
},
@ -7393,8 +7391,7 @@
"node_modules/js-binary-schema-parser": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/js-binary-schema-parser/-/js-binary-schema-parser-2.0.3.tgz",
"integrity": "sha512-xezGJmOb4lk/M1ZZLTR/jaBHQ4gG/lqQnJqdIv4721DMggsa1bDVlHXNeHYogaIEHD9vCRv0fcL4hMA+Coarkg==",
"license": "MIT"
"integrity": "sha512-xezGJmOb4lk/M1ZZLTR/jaBHQ4gG/lqQnJqdIv4721DMggsa1bDVlHXNeHYogaIEHD9vCRv0fcL4hMA+Coarkg=="
},
"node_modules/js-message": {
"version": "1.0.7",
@ -7977,7 +7974,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
"license": "MIT",
"engines": {
"node": ">=10"
},
@ -8574,8 +8570,7 @@
"node_modules/parenthesis": {
"version": "3.1.8",
"resolved": "https://registry.npmjs.org/parenthesis/-/parenthesis-3.1.8.tgz",
"integrity": "sha512-KF/U8tk54BgQewkJPvB4s/US3VQY68BRDpH638+7O/n58TpnwiwnOtGIOsT2/i+M78s61BBpeC83STB88d8sqw==",
"license": "MIT"
"integrity": "sha512-KF/U8tk54BgQewkJPvB4s/US3VQY68BRDpH638+7O/n58TpnwiwnOtGIOsT2/i+M78s61BBpeC83STB88d8sqw=="
},
"node_modules/parse-json": {
"version": "5.2.0",
@ -10324,8 +10319,7 @@
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT"
]
},
"node_modules/simple-get": {
"version": "4.0.1",
@ -10345,7 +10339,6 @@
"url": "https://feross.org/support"
}
],
"license": "MIT",
"dependencies": {
"decompress-response": "^6.0.0",
"once": "^1.3.1",
@ -10544,7 +10537,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/string-split-by/-/string-split-by-1.0.0.tgz",
"integrity": "sha512-KaJKY+hfpzNyet/emP81PJA9hTVSfxNLS9SFTWxdCnnW1/zOOwiV248+EfoX7IQFcBaOp4G5YE6xTJMF+pLg6A==",
"license": "MIT",
"dependencies": {
"parenthesis": "^3.1.5"
}
@ -11303,7 +11295,6 @@
"version": "4.0.9",
"resolved": "https://registry.npmjs.org/vue-qr/-/vue-qr-4.0.9.tgz",
"integrity": "sha512-pAISV94T0MNEYA3NGjykUpsXRE2QfaNxlu9ZhEL6CERgqNc21hJYuP3hRVzAWfBQlgO18DPmZTbrFerJC3+Ikw==",
"license": "MIT",
"dependencies": {
"glob": "^8.0.1",
"js-binary-schema-parser": "^2.0.2",
@ -11315,7 +11306,6 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
@ -11325,7 +11315,6 @@
"resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
"integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
"deprecated": "Glob versions prior to v9 are no longer supported",
"license": "ISC",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@ -11344,7 +11333,6 @@
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
@ -11416,19 +11404,6 @@
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
"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": {
"version": "3.6.2",
"resolved": "https://registry.npmmirror.com/vuex/-/vuex-3.6.2.tgz",

1
src/assets/site/prompt-icon-1.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="16" height="16" viewBox="0 0 16 16"><defs><clipPath id="master_svg0_217_60685"><rect x="0" y="0" width="16" height="16" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_217_60685)"><g><path d="M8,1C9.97933,1.052,11.6278,1.7368329999999998,12.9455,3.0545C14.2632,4.372170000000001,14.948,6.02067,15,8C14.948,9.97933,14.2632,11.6278,12.9455,12.9455C11.6278,14.2632,9.97933,14.948,8,15C6.02067,14.948,4.372170000000001,14.2632,3.0545,12.9455C1.7368329999999998,11.6278,1.052,9.97933,1,8C1.052,6.02067,1.7368329999999998,4.372170000000001,3.0545,3.0545C4.372170000000001,1.7368329999999998,6.02067,1.052,8,1C8,1,8,1,8,1C8,1,8,1,8,1ZM9.047,5.297C9.318,5.297,9.542,5.21633,9.719,5.055C9.896,4.89367,9.9845,4.6775,9.9845,4.406499999999999C9.9845,4.1355,9.896,3.91933,9.719,3.758C9.542,3.59667,9.32067,3.516,9.055,3.516C8.78933,3.516,8.568,3.59667,8.391,3.758C8.214,3.91933,8.125499999999999,4.1355,8.125499999999999,4.406499999999999C8.125499999999999,4.6775,8.214,4.89367,8.391,5.055C8.568,5.21633,8.78683,5.297,9.0475,5.297C9.0475,5.297,9.047,5.297,9.047,5.297C9.047,5.297,9.047,5.297,9.047,5.297ZM9.2345,10.922C9.2345,10.85933,9.23967,10.776,9.25,10.672C9.26033,10.568,9.26033,10.469,9.25,10.375C9.25,10.375,8.422,11.328,8.422,11.328C8.33867,11.4217,8.25267,11.4947,8.164,11.547C8.075330000000001,11.5993,7.99983,11.615,7.9375,11.594C7.84383,11.5523,7.80217,11.4793,7.8125,11.375C7.8125,11.375,9.1875,7.047,9.1875,7.047C9.2395,6.75533,9.19267,6.50533,9.047,6.297C8.90133,6.08867,8.667,5.96367,8.344000000000001,5.922C7.97933,5.93233,7.58083,6.086,7.1485,6.383C6.71617,6.68,6.3385,7.05767,6.0155,7.516C6.0155,7.516,6.0155,7.7505,6.0155,7.7505C6.00517,7.85483,6.00517,7.95383,6.0155,8.0475C6.0155,8.0475,6.8435,7.0945,6.8435,7.0945C6.92683,7.00083,7.01283,6.92783,7.1015,6.8755C7.19017,6.82317,7.2605,6.8075,7.3125,6.8285C7.41683,6.8805,7.45333,6.96383,7.422,7.0785C7.422,7.0785,6.0625,11.391,6.0625,11.391C5.9895,11.6513,6.026,11.8832,6.172,12.0865C6.318,12.2898,6.57317,12.4278,6.9375,12.5005C7.4585,12.4902,7.896,12.3392,8.25,12.0475C8.604,11.7558,8.93217,11.3808,9.2345,10.9225C9.2345,10.9225,9.2345,10.922,9.2345,10.922C9.2345,10.922,9.2345,10.922,9.2345,10.922Z" fill="#006AFF" fill-opacity="1"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

1
src/assets/site/prompt-icon-2.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="16" height="16" viewBox="0 0 16 16"><defs><clipPath id="master_svg0_354_94660/23_30613"><rect x="0" y="0" width="16" height="16" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_354_94660/23_30613)"><g><path d="M8,1C9.97933,1.052,11.6278,1.7368329999999998,12.9455,3.0545C14.2632,4.372170000000001,14.948,6.02067,15,8C14.948,9.97933,14.2632,11.6278,12.9455,12.9455C11.6278,14.2632,9.97933,14.948,8,15C6.02067,14.948,4.372170000000001,14.2632,3.0545,12.9455C1.7368329999999998,11.6278,1.052,9.97933,1,8C1.052,6.02067,1.7368329999999998,4.372170000000001,3.0545,3.0545C4.372170000000001,1.7368329999999998,6.02067,1.052,8,1C8,1,8,1,8,1C8,1,8,1,8,1ZM9.047,5.297C9.318,5.297,9.542,5.21633,9.719,5.055C9.896,4.89367,9.9845,4.6775,9.9845,4.406499999999999C9.9845,4.1355,9.896,3.91933,9.719,3.758C9.542,3.59667,9.32067,3.516,9.055,3.516C8.78933,3.516,8.568,3.59667,8.391,3.758C8.214,3.91933,8.125499999999999,4.1355,8.125499999999999,4.406499999999999C8.125499999999999,4.6775,8.214,4.89367,8.391,5.055C8.568,5.21633,8.78683,5.297,9.0475,5.297C9.0475,5.297,9.047,5.297,9.047,5.297C9.047,5.297,9.047,5.297,9.047,5.297ZM9.2345,10.922C9.2345,10.85933,9.23967,10.776,9.25,10.672C9.26033,10.568,9.26033,10.469,9.25,10.375C9.25,10.375,8.422,11.328,8.422,11.328C8.33867,11.4217,8.25267,11.4947,8.164,11.547C8.075330000000001,11.5993,7.99983,11.615,7.9375,11.594C7.84383,11.5523,7.80217,11.4793,7.8125,11.375C7.8125,11.375,9.1875,7.047,9.1875,7.047C9.2395,6.75533,9.19267,6.50533,9.047,6.297C8.90133,6.08867,8.667,5.96367,8.344000000000001,5.922C7.97933,5.93233,7.58083,6.086,7.1485,6.383C6.71617,6.68,6.3385,7.05767,6.0155,7.516C6.0155,7.516,6.0155,7.7505,6.0155,7.7505C6.00517,7.85483,6.00517,7.95383,6.0155,8.0475C6.0155,8.0475,6.8435,7.0945,6.8435,7.0945C6.92683,7.00083,7.01283,6.92783,7.1015,6.8755C7.19017,6.82317,7.2605,6.8075,7.3125,6.8285C7.41683,6.8805,7.45333,6.96383,7.422,7.0785C7.422,7.0785,6.0625,11.391,6.0625,11.391C5.9895,11.6513,6.026,11.8832,6.172,12.0865C6.318,12.2898,6.57317,12.4278,6.9375,12.5005C7.4585,12.4902,7.896,12.3392,8.25,12.0475C8.604,11.7558,8.93217,11.3808,9.2345,10.9225C9.2345,10.9225,9.2345,10.922,9.2345,10.922C9.2345,10.922,9.2345,10.922,9.2345,10.922Z" fill="#FF8C00" fill-opacity="1"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

1
src/assets/site/prompt-icon-3.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="16" height="16" viewBox="0 0 16 16"><defs><clipPath id="master_svg0_242_77707/23_30613"><rect x="0" y="0" width="16" height="16" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_242_77707/23_30613)"><g><path d="M8,1C9.97933,1.052,11.6278,1.7368329999999998,12.9455,3.0545C14.2632,4.372170000000001,14.948,6.02067,15,8C14.948,9.97933,14.2632,11.6278,12.9455,12.9455C11.6278,14.2632,9.97933,14.948,8,15C6.02067,14.948,4.372170000000001,14.2632,3.0545,12.9455C1.7368329999999998,11.6278,1.052,9.97933,1,8C1.052,6.02067,1.7368329999999998,4.372170000000001,3.0545,3.0545C4.372170000000001,1.7368329999999998,6.02067,1.052,8,1C8,1,8,1,8,1C8,1,8,1,8,1ZM9.047,5.297C9.318,5.297,9.542,5.21633,9.719,5.055C9.896,4.89367,9.9845,4.6775,9.9845,4.406499999999999C9.9845,4.1355,9.896,3.91933,9.719,3.758C9.542,3.59667,9.32067,3.516,9.055,3.516C8.78933,3.516,8.568,3.59667,8.391,3.758C8.214,3.91933,8.125499999999999,4.1355,8.125499999999999,4.406499999999999C8.125499999999999,4.6775,8.214,4.89367,8.391,5.055C8.568,5.21633,8.78683,5.297,9.0475,5.297C9.0475,5.297,9.047,5.297,9.047,5.297C9.047,5.297,9.047,5.297,9.047,5.297ZM9.2345,10.922C9.2345,10.85933,9.23967,10.776,9.25,10.672C9.26033,10.568,9.26033,10.469,9.25,10.375C9.25,10.375,8.422,11.328,8.422,11.328C8.33867,11.4217,8.25267,11.4947,8.164,11.547C8.075330000000001,11.5993,7.99983,11.615,7.9375,11.594C7.84383,11.5523,7.80217,11.4793,7.8125,11.375C7.8125,11.375,9.1875,7.047,9.1875,7.047C9.2395,6.75533,9.19267,6.50533,9.047,6.297C8.90133,6.08867,8.667,5.96367,8.344000000000001,5.922C7.97933,5.93233,7.58083,6.086,7.1485,6.383C6.71617,6.68,6.3385,7.05767,6.0155,7.516C6.0155,7.516,6.0155,7.7505,6.0155,7.7505C6.00517,7.85483,6.00517,7.95383,6.0155,8.0475C6.0155,8.0475,6.8435,7.0945,6.8435,7.0945C6.92683,7.00083,7.01283,6.92783,7.1015,6.8755C7.19017,6.82317,7.2605,6.8075,7.3125,6.8285C7.41683,6.8805,7.45333,6.96383,7.422,7.0785C7.422,7.0785,6.0625,11.391,6.0625,11.391C5.9895,11.6513,6.026,11.8832,6.172,12.0865C6.318,12.2898,6.57317,12.4278,6.9375,12.5005C7.4585,12.4902,7.896,12.3392,8.25,12.0475C8.604,11.7558,8.93217,11.3808,9.2345,10.9225C9.2345,10.9225,9.2345,10.922,9.2345,10.922C9.2345,10.922,9.2345,10.922,9.2345,10.922Z" fill="#FF4D4F" fill-opacity="1"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

6
src/components/GroupFormBtns.vue

@ -2,8 +2,8 @@
<template>
<div class="btns-wrap flex">
<GuipButton type="ignore" @click="cancelClick">取消</GuipButton>
<GuipButton type="primary" @click="confirmClick">保存</GuipButton>
<GuipButton type="ignore" @click="cancelClick">{{cancelText || '取消'}}</GuipButton>
<GuipButton type="primary" @click="confirmClick">{{confirmText ||'保存'}}</GuipButton>
</div>
</template>
<script>
@ -11,7 +11,7 @@ import GuipButton from '@/components/GuipButton.vue';
export default {
name: '',
props: [''],
props: ['cancelText','confirmText'],
components: {
GuipButton
},

97
src/components/PromptText.vue

@ -0,0 +1,97 @@
<template>
<div class="prompt-text" :class="typeClass">
<div class="flex-text">
<div class="flex">
<img class="prompt-icon" :src="typeIcon" alt="">
<span class="prompt-desc">{{text}}</span>
</div>
<div class="flex">
<slot name="next_desc" />
</div>
</div>
<div class="prompt-extra">
<slot name="desc" />
</div>
</div>
</template>
<script>
export default {
name: 'PromptText',
props: {
text: {
type: String,
required: true
},
type: {
type: [Number, String],
default: 2
},
},
components: {
},
data(){
return{}
},
computed: {
typeClass() {
switch (parseInt(this.type)) {
case 1: return 'info';
case 2: return 'notice';
case 3: return 'warning';
default: return 'notice';
}
},
typeIcon() {
switch (parseInt(this.type)) {
case 1: return require('@/assets/site/prompt-icon-1.svg');
case 2: return require('@/assets/site/prompt-icon-2.svg');
case 3: return require('@/assets/site/prompt-icon-3.svg');
default: return require('@/assets/site/prompt-icon-2.svg');
}
}
},
methods:{
}
}
</script>
<style scoped lang="scss">
.prompt-text{
padding: 8px 13px;
border-radius: 4px;
text-align: justify;
}
.flex-text{
display: flex;
align-items: center;
align-self: stretch;
justify-content: space-between;
z-index: 1;
}
.info{
background: #F2F7FF;
border: 1px solid #BFDAFF;
}
.notice{
background: #FEFCE8;
border: 1px solid rgba(255, 140, 0, 0.3);
}
.warning{
background: #FFF1F0;
border: 1px solid #FFA39E;
}
.prompt-icon{
width: 16px;
height: 16px;;
margin-right: 8px;
}
.prompt-desc{
color: #1E2226;
letter-spacing: 0.08em;
}
.prompt-extra{
}
</style>

17
src/store/index.js

@ -54,6 +54,23 @@ export default new Vuex.Store({
]
},
{
name: '出诊公告',
path: '',
noToPath:true,
img: 'menu/Totalprofit1.svg',
imgActive: require('@/assets/menu/Totalprofit.svg'),
list: [
{
name: '公告设置',
desc: 'siteMessage8'
},
{
name: '出诊日历预览',
desc: 'siteMessage9'
},
]
},
{
name: '项目管理',
path: '',
noToPath:true,

202
src/views/DoctorInformation.vue

@ -18,23 +18,17 @@
<div class="qqCode-wrap right">
<div class="avator-wrapper flex">
<img v-if="doctorAvatorUrl" :src="doctorAvatorUrl" alt="" class="uploadImg">
<hover-button :button-text="doctorAvatorUrl?'重新上传':'开始上传'" :default-icon="require('../assets/upLoad_grey.svg')"
:hover-icon="require('../assets/upLoad_active.svg')"
default-text-color="#23242B" hover-text-color="#006AFF">
<hover-button :button-text="doctorAvatorUrl ? '重新上传' : '开始上传'"
:default-icon="require('../assets/upLoad_grey.svg')"
:hover-icon="require('../assets/upLoad_active.svg')"
default-text-color="#23242B" hover-text-color="#006AFF">
</hover-button>
<div class="info-upload-wrapper" @click="clearDocotorAvatorFiles">
<el-upload
:on-change="handleAvatarChange"
action="#"
list-type="picture-card"
:multiple="false"
:http-request="setDoctorBaseInfoUpload"
:limit="Number(1)"
ref="avatorUpload"
:auto-upload="false"
>
<i slot="default" class="el-icon-plus"></i>
<el-upload :on-change="handleAvatarChange" action="#" list-type="picture-card"
:multiple="false" :http-request="setDoctorBaseInfoUpload" :limit="Number(1)"
ref="avatorUpload" :auto-upload="false">
<i slot="default" class="el-icon-plus"></i>
</el-upload>
</div>
</div>
@ -46,8 +40,8 @@
</el-form-item>
<GuipInput ref="GuipInput" column="column" :required="true" label="医生姓名"
v-model="siteForm.name" prop="name" placeholder="请输入" />
<GuipInput ref="GuipInput" column="column" :required="true" label="医生姓名" v-model="siteForm.name"
prop="name" placeholder="请输入" />
</div>
<div class="flex-line"></div>
<div class="flex-right">
@ -62,6 +56,27 @@
</div>
<div class="siteMessage flex-common" id="siteMessage2">
<p class="littleTitle mb32">出诊设置</p>
<el-form :model="siteForm" :rules="siteFormrules3" ref="siteForm3">
<div class="flex-wrap">
<div class="flex-left">
<p class="coincideTip mb24">您有多个出诊医院时允许不同医院排班时段重合吗</p>
<div class="flex">
<div class="coincideWrap">
<el-radio v-model="siteForm.is_allow_coincide" :label="1">允许时段重合</el-radio>
<p>适用于可由助理代为坐诊</p>
</div>
<div class="coincideWrap">
<el-radio v-model="siteForm.is_allow_coincide" :label="0">禁止时段重合</el-radio>
<p>避免时段冲突造成患者错误预约</p>
</div>
</div>
</div>
</div>
</el-form>
<GroupFormBtns @cancel="cancelClick" @confirm="submitCoincideSet" />
</div>
<div class="siteMessage flex-common" id="siteMessage2">
<p class="littleTitle mb32">初诊审批</p>
<el-form :model="siteForm" :rules="siteFormrules2" ref="siteForm2">
<div class="flex-wrap">
@ -80,27 +95,24 @@
<div class="avator-wrapper">
<div class="flex" style="position: relative;">
<img v-if="approverWechatUrl" :src="approverWechatUrl" class="uploadImg">
<hover-button :button-text="(approverWechatUrl ? '重新上传':'微信二维码')" :default-icon="require('../assets/upLoad_grey.svg')"
:hover-icon="require('../assets/upLoad_active.svg')"
default-text-color="#23242B" hover-text-color="#006AFF" />
<div class="info-upload-wrapper" @click="clearApproverWechatFiles" style="width: 177px;left: 0;display: flex;justify-content: flex-start;overflow: hidden;">
<el-upload
:on-change="handleApproverWechatChange"
action="#"
list-type="picture-card"
:multiple="false"
:http-request="setApproverWechatUpload"
:limit="Number(1)"
ref="approverWechatUpload"
:auto-upload="false"
>
<hover-button :button-text="(approverWechatUrl ? '重新上传' : '微信二维码')"
:default-icon="require('../assets/upLoad_grey.svg')"
:hover-icon="require('../assets/upLoad_active.svg')"
default-text-color="#23242B" hover-text-color="#006AFF" />
<div class="info-upload-wrapper" @click="clearApproverWechatFiles"
style="width: 177px;left: 0;display: flex;justify-content: flex-start;overflow: hidden;">
<el-upload :on-change="handleApproverWechatChange" action="#"
list-type="picture-card" :multiple="false"
:http-request="setApproverWechatUpload" :limit="Number(1)"
ref="approverWechatUpload" :auto-upload="false">
<i slot="default" class="el-icon-plus"></i>
</el-upload>
</div>
</div>
<div slot="tip" class="el-upload__tip desc" style="margin-top:8px;">批人微信二维码大小2M以内</div>
<div slot="tip" class="el-upload__tip desc" style="margin-top:8px;">批人微信二维码大小2M以内
</div>
</div>
</div>
</GuipFormItem>
@ -121,13 +133,16 @@
</div>
<div class="flex-line"></div>
<div class="flex-right">
<GuipInput ref="GuipInput" column="column" label="个人标签"
v-model="siteForm.label" prop="name" placeholder="请输入" />
<GuipInput ref="GuipInput" column="column" label="个人标签" v-model="siteForm.label" prop="name"
placeholder="请输入" />
</div>
</div>
</el-form>
<GroupFormBtns @cancel="cancelClick('siteForm1')" @confirm="setDoctorDesc" />
</div>
<ConflictDialog :isDoctorSet="true" ref="conflictDialog" :cancelBtnShow="'0'" :doctor_id="doctorId"
title="已有出诊安排冲突,请先修改!" :confirmText="'我知道了'"/>
</div>
</template>
<script>
@ -138,6 +153,8 @@ import GuipInput from '@/components/GuipInput.vue';
import GuipTextarea from '@/components/GuipTextarea.vue';
import GroupFormBtns from '@/components/GroupFormBtns.vue';
import GuipRadio from '@/components/GuipRadio.vue';
import ConflictDialog from './conflictDialog.vue';
export default {
//
name: '',
@ -148,19 +165,22 @@ export default {
GuipRadio,
GuipInput,
GuipTextarea,
GroupFormBtns
GroupFormBtns,
ConflictDialog
},
data() {
return {
doctorId: '',
is_allow_coincide: true,//
hasConflictresult:[],
fileList: [
// { name: 'image.jpeg', url: 'http://jasonyizherenxin.checkcopy.com/user_avatar/1.png?v=93940df0b596961c42de23ef1f2d3257' }
],
fileList1:[],
doctorAvatoFile:[],
fileList1: [],
doctorAvatoFile: [],
doctorAvatorUrl: '',
approverWechatUrl:'',
approverWechatFile:[],
approverWechatUrl: '',
approverWechatFile: [],
options_payword: [],
groupOptions: [
{ label: '需审批', value: '1' },
@ -168,7 +188,7 @@ export default {
],
formData: null,
siteForm: {
did:0,
did: 0,
name: '',
idcard: ' ',
phone: '',
@ -176,9 +196,10 @@ export default {
doctor_desc: '',
doctor_detail: '',
label: '',
approver_phone:'',
approver_wechat:'',
approver_phone: '',
approver_wechat: '',
first_visit_audit: '',
is_allow_coincide: ''//
},
oldForm: {},
siteFormrules2: {
@ -186,6 +207,11 @@ export default {
{ required: true, message: '请选择初诊审批设置', trigger: 'change' }
]
},
siteFormrules3: {
coincide: [
{ required: true, message: '请选择出诊设置', trigger: 'change' }
]
},
siteFormrules: {
name: [
{ required: true, message: '请输入姓名', trigger: 'blur' }
@ -231,7 +257,7 @@ export default {
},
methods: {
setDoctorDesc() {
if(!this.doctorId) {
if (!this.doctorId) {
this.$message.error('请先设置医生基础信息')
return;
}
@ -253,7 +279,7 @@ export default {
})
},
getDoctorData(doctor_id) {
this.$http('POST', '/api/admin/get_doctor_baseinfo', {did:doctor_id}).then(response => {
this.$http('POST', '/api/admin/get_doctor_baseinfo', { did: doctor_id }).then(response => {
if (response.code != 0) {
this.$message.error(response.msg)
return;
@ -277,9 +303,9 @@ export default {
this.$message.success(response.msg)
var data = response.data
if(this.doctorId) return;
if (this.doctorId) return;
setTimeout(() => {
location.href = location.href+'?doctor_id='+data.doctor_id
location.href = location.href + '?doctor_id=' + data.doctor_id
}, 800);
}).catch(error => {
console.error(error, 'error')
@ -299,8 +325,8 @@ export default {
this.setDoctorInfo(fd)
},
submitDoctorBaseInfo() {
if(this.doctorAvatoFile.length == 0) {
if(this.doctorId) {
if (this.doctorAvatoFile.length == 0) {
if (this.doctorId) {
this.setDoctorInfo(this.siteForm)
return;
}
@ -310,12 +336,12 @@ export default {
this.$refs.avatorUpload.submit();
},
clearDocotorAvatorFiles(){
clearDocotorAvatorFiles() {
this.doctorAvatorUrl = '';
this.doctorAvatoFile = []
this.$refs.avatorUpload.clearFiles();
},
clearApproverWechatFiles(){
clearApproverWechatFiles() {
this.approverWechatUrl = '';
this.approverWechatFile = []
this.$refs.approverWechatUpload.clearFiles();
@ -340,9 +366,9 @@ export default {
this.$message.success(response.msg)
var data = response.data
if(this.doctorId) return;
if (this.doctorId) return;
setTimeout(() => {
location.href = location.href+'?doctor_id='+data.doctor_id
location.href = location.href + '?doctor_id=' + data.doctor_id
}, 800);
}).catch(error => {
console.error(error, 'error')
@ -350,18 +376,48 @@ export default {
})
},
submitApproverWechat() {
if(!this.doctorId) {
if (!this.doctorId) {
this.$message.error('请先设置医生基础信息')
return;
}
if(this.approverWechatFile.length == 0) {
if (this.approverWechatFile.length == 0) {
this.setApproverWechat(this.siteForm)
return;
}
this.$refs.approverWechatUpload.submit();
},
//
submitCoincideSet() {
if (!this.doctorId) {
this.$message.error('请先设置医生基础信息')
return;
}
//
if (this.siteForm.is_allow_coincide == 0) {
this.$refs.conflictDialog.open()
return
}
this.$http('POST', '/api/admin/set_allow_coincide', {
is_allow_coincide:this.siteForm.is_allow_coincide,
did: this.doctorId
}).then(response => {
if (response.code != 0) {
this.$message.error(response.msg)
return;
}
this.$message.success(response.msg)
if (this.doctorId) return;
}).catch(error => {
console.error(error, 'error')
this.$message.error('设置失败')
})
},
handleApproverWechatChange(file, fileList) {
console.log(file, fileList)
this.approverWechatFile = file
@ -382,8 +438,33 @@ export default {
}
</script>
<style lang="scss" scoped>
.coincideWrap {
margin-right: 24px;
text-align: left;
.info-upload-wrapper ::v-deep .el-upload-list.el-upload-list--picture-card{
p {
font-family: Microsoft YaHei UI;
font-size: 12px;
font-weight: normal;
line-height: 24px;
letter-spacing: 0.08em;
color: #8A9099;
padding-left: 22px;
}
}
.coincideTip {
font-family: Microsoft YaHei UI;
font-size: 14px;
font-weight: normal;
line-height: normal;
letter-spacing: 0.08em;
color: #1E2226;
text-align: left;
}
.info-upload-wrapper ::v-deep .el-upload-list.el-upload-list--picture-card {
display: none;
}
@ -393,11 +474,12 @@ export default {
border: 1px solid transparent;
}
.uploadImg{
.uploadImg {
width: 150px;
margin-right: 20px;
}
.special-form-item ::v-deep .el-form-item__label{
.special-form-item ::v-deep .el-form-item__label {
margin-bottom: 12px;
}
@ -421,9 +503,11 @@ export default {
display: flex;
width: 100%;
justify-content: flex-start;
.avator-wrapper{
.avator-wrapper {
position: relative;
.info-upload-wrapper{
.info-upload-wrapper {
position: absolute;
display: flex;
justify-content: flex-end;

2384
src/views/HosInformation.vue

File diff suppressed because it is too large

553
src/views/conflictDialog.vue

@ -0,0 +1,553 @@
<template>
<GuipDialog :dialogVisible="visitDialogVisible" :title="visitDialogTitle" :show-close-button="true" width="699px"
:show-cancel-button="visitShowCancelBtn" @confirm="handleVisitConfirm" :confirmText="visitConfirmText"
@cancel="handleVisitCancel" @close="handleVisitClose">
<div class="flex conflictTitle" v-if="is_allow_coincide && !isDoctorSet">
您设置的 <b>{{ h_realname }} </b>每周排班与以下现有出诊安排重叠请确定是否正确
</div>
<div class="flex conflictTitle" v-if="!is_allow_coincide && !isDoctorSet">
您设置的 <b>{{ h_realname }} </b>每周排班与以下现有出诊安排冲突请调整后再保存
</div>
<div class="visitContent mt24">
<div class="hosPlanItem mb24" v-for="(conflict, index) in hasConflictresult" :key="index">
<p>{{ conflict.date }} {{ conflict.dayOfWeek ? `${conflict.dayOfWeek}` : '' }}{{ conflict.conflictShift }}</p>
<div class="flex">
<span class="conflictTip">{{!is_allow_coincide ?'冲突':'重叠' }}</span>
<div>{{ conflict.hospital }}({{ conflict.type === 'fixed' ?
'固定排班' :
'临时出诊' }})</div>
</div>
</div>
</div>
<p v-if="hasConflictresultLength > 3" style="color: #FF4D4F;">等共{{hasConflictresultLength}}条出诊安排冲突请修改后再进行设置</p>
</GuipDialog>
</template>
<script>
import GuipDialog from '@/components/GuipDialog.vue';
export default {
props: {
is_allow_coincide: [Boolean, Number],
oldWorktimes: Object,
h_realname: String,
doctor_id: [Number, String],
depart_id: [Number, String],
houseCallSettingForm: Object,
rawScheduleDataProp: Object,
isDoctorSet:Boolean,
cancelText: String,
confirmText: String,
cancelBtnShow: String,
title: String,
// houseCallSettingForm: Object,
// getDoctorHosPreview: Function,
// formatWorktimesArray: Function,
},
components: {
GuipDialog,
},
data(){
return {
visitDialogTitle: '出诊安排重叠,请确认',//
visitDialogVisible: false,//
visitShowCancelBtn: true,//
visitConfirmText: '确定并保存',//
hasConflictresult: [],
rawScheduleData1:null,
weekPlan: {
'1': '周一',
'2': '周二',
'3': '周三',
'4': '周四',
'5': '周五',
'6': '周六',
'7': '周日',
},
weekDaysDesc: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
hasConflictresultLength:0
}
},
created() {
this.rawScheduleData1 = this.rawScheduleDataProp;
},
watch: {
// props
rawScheduleDataProp(newVal) {
this.rawScheduleData1 = newVal
},
} ,
mounted() {
if(this.cancelBtnShow == '0'){
this.visitShowCancelBtn = false;
}
if(this.cancelText){
this.visitConfirmText = this.cancelText;
}
if(this.confirmText){
this.visitConfirmText = this.confirmText;
}
if(this.title){
this.visitDialogTitle = this.title;
}
},
methods: {
open(){
this.visitDialogVisible = true;
this.getDoctorHosPreview();
},
handleVisitClose() {
this.visitDialogVisible = false;
},
handleVisitCancel() {
this.visitDialogVisible = false;
},
handleVisitConfirm() {
if (this.is_allow_coincide) {
this.saveWorkTimeDirect();
}
this.visitDialogVisible = false;
},
// ...start
async getDoctorHosPreview() {
await this.$http('POST', '/api/admin/get_departs_worktimes', {
doctor_id: this.doctor_id,
}).then(response => {
const list = response.msg;
if (response.code == 0) {
//
this.rawScheduleData1 = JSON.parse(JSON.stringify(list));
const data = this.analyzeCurrentMonthConflicts();
this.hasConflictresultLength = data.length;
this.hasConflictresult = data.length > 3 ? data.slice(0, 3) : data;
// console.log(this.hasConflictresult, 'this.hasConflictresult');
}
}).catch(error => {
console.error(error, 'error')
})
},
// YYYY-MM-DD
formatDate(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
},
//
analyzeCurrentMonthConflicts() {
const conflicts = [];
const today = new Date();
const currentYear = today.getFullYear();
const currentMonth = today.getMonth();
//
const lastDay = new Date(currentYear, currentMonth + 1, 0).getDate();
//
for (let day = today.getDate(); day <= lastDay; day++) {
const date = new Date(currentYear, currentMonth, day);
const dateStr = this.formatDate(date);
const dayOfWeek = date.getDay() === 0 ? 7 : date.getDay();
const dayConflicts = this.checkDayConflictsWithType(dateStr, dayOfWeek, this.rawScheduleData1, Object.keys(this.rawScheduleData1));
if (dayConflicts.length > 0) {
conflicts.push(...dayConflicts);
}
}
return conflicts;
},
//
checkDayConflictsWithType(dateStr, dayOfWeek, hospitals, hospitalIds) {
const conflicts = [];
const timeSlots = {
morning: [],
afternoon: []
};
//
hospitalIds.forEach(hid => {
const hospital = hospitals[hid];
let plan = "0";
let isTempAdjust = false;
let originalPlan = "0";
//
if (hospital.worktime_no_fixed === 0) {
//
const weeklyPlan = hospital.worktime_list && hospital.worktime_list[dayOfWeek];
originalPlan = weeklyPlan ? weeklyPlan.plan.toString() : "0";
} else {
//
const datePlan = hospital.worktime_list && hospital.worktime_list[dateStr];
originalPlan = datePlan ? datePlan.plan.toString() : "0";
}
//
if (hospital.temp_change_worktime && hospital.temp_change_worktime[dateStr]) {
const tempPlan = hospital.temp_change_worktime[dateStr];
plan = tempPlan.plan.toString();
isTempAdjust = true;
} else {
plan = originalPlan;
}
if (plan !== "0") {
const hospitalInfo = {
hid,
name: hospital.h_depart_name,
plan,
originalPlan,
isTempAdjust,
scheduleType: isTempAdjust ? '临时出诊' : '固定排班'
};
if (plan === "1" || plan === "3") {
timeSlots.morning.push(hospitalInfo);
}
if (plan === "2" || plan === "3") {
timeSlots.afternoon.push(hospitalInfo);
}
}
});
//
if (timeSlots.morning.length > 1) {
conflicts.push(this.createConflictInfoWithType(
dateStr,
timeSlots.morning,
'上午'
));
}
if (timeSlots.afternoon.length > 1) {
conflicts.push(this.createConflictInfoWithType(
dateStr,
timeSlots.afternoon,
'下午'
));
}
return conflicts;
},
//
createConflictInfoWithType(date, hospitals, timeSlot) {
const dateObj = new Date(date);
const dayOfWeek = this.weekDaysDesc[dateObj.getDay()];
//
const hospitalGroups = {
fixed: hospitals.filter(h => !h.isTempAdjust).map(h => h.name),
temp: hospitals.filter(h => h.isTempAdjust).map(h => h.name)
};
let hospitalDisplay = '';
if (hospitalGroups.fixed.length > 0) {
hospitalDisplay += hospitalGroups.fixed.join('、') + '固定排班';
}
if (hospitalGroups.temp.length > 0) {
if (hospitalDisplay) hospitalDisplay += '、';
hospitalDisplay += hospitalGroups.temp.join('、') + '临时出诊';
}
return {
date: date,
hospital: hospitalDisplay,
conflictShift: timeSlot,
type: hospitalGroups.temp.length > 0 ? 'mixed' : 'fixed',
dayOfWeek: dayOfWeek,
hospitals: hospitals,
displayText: `${date}${dayOfWeek}${timeSlot}班:${hospitalDisplay}`
};
},
// ..end
async setDepartWorkTime() {
const { display_work_days, planDays, worktime_no_fixed,worktimes } = this.houseCallSettingForm;
const params = {
doctor_id: this.doctor_id,
depart_id: this.depart_id,
worktime_no_fixed: worktime_no_fixed,
week_visit_plan: JSON.stringify(this.formatWorktimesArray(worktimes))
}
if (display_work_days == 1 && planDays > 0) {
params.display_work_days = planDays
}
// vs
const conflictResults = this.checkScheduleConflict(worktimes, worktime_no_fixed);
//
if (conflictResults.hasConflict && worktime_no_fixed == 0) {
this.visitDialogVisible = true;
this.hasConflictresult = conflictResults.conflicts;
if(this.is_allow_coincide){
this.visitDialogTitle = '出诊安排重叠,请确认';
this.visitConfirmText = '确定并保存';
this.visitShowCancelBtn = true;
}else{
this.visitDialogTitle = '出诊安排冲突,请确认';
this.visitConfirmText = '知道了';
this.visitShowCancelBtn = false;
}
return;
}
},
async saveWorkTimeDirect() {
const { display_work_days, planDays, worktime_no_fixed, worktimes } = this.houseCallSettingForm;
var worktimesArray = this.formatWorktimesArray(worktimes)
const params = {
doctor_id: this.doctor_id,
depart_id: this.depart_id,
worktime_no_fixed: worktime_no_fixed,
week_visit_plan: JSON.stringify(worktimesArray)
}
if (display_work_days == 1 && planDays > 0) {
params.display_work_days = planDays
}
await this.$http('POST', '/api/admin/set_depart_worktime', {
...params
}).then(response => {
if (response.code == 0) {
this.$Message.success(response.msg || '设置成功')
// this.form.worktimes = worktimes;
this.getDoctorHosPreview();
}
}).catch(error => {
console.error(error, 'error')
})
},
//
checkScheduleConflict(newWorktimes, worktime_no_fixed) {
const conflicts = [];
let hasConflict = false;
if (!this.rawScheduleData1) {
return { hasConflict: false, conflicts: [] };
}
//
Object.keys(this.rawScheduleData1).forEach(hospitalId => {
// (depart_id=4)
if (hospitalId === this.depart_id.toString()) {
console.log('跳过当前医院:', hospitalId);
return;
}
const hospital = this.rawScheduleData1[hospitalId];
//
const hospitalConflicts = this.checkHospitalConflict(newWorktimes, hospital, worktime_no_fixed);
if (hospitalConflicts.length > 0) {
conflicts.push(...hospitalConflicts);
hasConflict = true;
}
});
console.log('最终冲突结果:', { hasConflict, conflicts });
return { hasConflict, conflicts };
},
//
checkHospitalConflict(newWorktimes, hospital) {
const conflicts = [];
if (hospital.worktime_no_fixed === 0) {
//
conflicts.push(...this.checkVsFixedHospital(newWorktimes, hospital));
} else {
//
conflicts.push(...this.checkVsNonFixedHospital(newWorktimes, hospital));
}
return conflicts;
},
//
checkVsFixedHospital(newWorktimes, hospital) {
const conflicts = [];
//
Object.keys(newWorktimes).forEach(weekDay => {
const newPlan = newWorktimes[weekDay].plan;
if (newPlan === '0') {
return; //
}
//
const hospitalPlan = hospital.worktime_list && hospital.worktime_list[weekDay];
if (hospitalPlan && hospitalPlan.plan !== '0') {
//
const conflictShift = this.getConflictShift(newPlan, hospitalPlan.plan);
if (conflictShift) {
conflicts.push(this.createConflictInfo(
`${this.getWeekDayName(parseInt(weekDay))}`,
hospital.h_depart_name,
newPlan,
conflictShift, //
'固定排班',
hospitalPlan.work_paln_desc,
));
}
}
});
return conflicts;
},
//
checkVsNonFixedHospital(newWorktimes, hospital) {
const conflicts = [];
if (!hospital.worktime_list) return conflicts;
//
Object.keys(hospital.worktime_list).forEach(dateStr => {
const hospitalPlan = hospital.worktime_list[dateStr];
if (!hospitalPlan || hospitalPlan.plan === '0') return;
//
const date = new Date(dateStr);
const dayOfWeek = date.getDay() === 0 ? 7 : date.getDay();
const weekDayKey = dayOfWeek.toString();
//
const newSchedule = newWorktimes[weekDayKey];
if (!newSchedule || newSchedule.plan === '0') return;
//
const conflictShift = this.getConflictShift(newSchedule.plan, hospitalPlan.plan);
if (conflictShift) {
conflicts.push(this.createConflictInfo(
dateStr,
hospital.h_depart_name,
newSchedule.plan,
conflictShift, //
'非固定排班',
hospitalPlan.work_paln_desc,
this.weekPlan[dayOfWeek],//
));
}
});
return conflicts;
},
createConflictInfo(date, hospitalName, newPlan, conflictShift, scheduleType, workDesc, dayOfWeek) {
const planMap = {
'0': '休息',
'1': '上午班',
'2': '下午班',
'3': '全天班'
};
const conflict = {
date: date,
hospital: hospitalName,
newPlan: planMap[newPlan],
conflictShift: conflictShift, //
scheduleType: scheduleType,
workDesc: workDesc,
dayOfWeek
// displayText: `${date} ${planMap[newPlan]} ${hospitalName} ${conflictShift} `
};
console.log('创建冲突信息:', conflict);
return conflict;
},
getWeekDayName(weekDay) {
const weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
return weekDays[weekDay - 1] || `${weekDay}`;
},
getConflictShift(newPlan, existingPlan) {
const planMap = {
'0': '休息',
'1': '上午',
'2': '下午',
'3': '全天班'
};
//
if (newPlan === '3') {
return planMap[existingPlan]; //
}
if (existingPlan === '3') {
return planMap[newPlan]; //
}
//
if (newPlan === existingPlan) {
return planMap[newPlan];
}
return null; //
},
formatWorktimesArray(worktimes) {
return Object.entries(worktimes).map(([key, value]) => ({
type: parseInt(key),
plan: value.plan
}));
},
}
}
</script>
<style scoped lang="scss">
.visitContent {
max-height: 300px;
overflow-y: auto;
}
.conflictTitle {
display: flex;
margin-bottom: 24px;
font-size: 14px;
color: #333;
line-height: 1.5;
flex-wrap: wrap;
word-wrap: break-word;
word-break: break-word;
white-space: normal;
}
.conflictTitle b {
color: #1890ff;
font-weight: 600;
margin: 0 4px;
word-break: break-all;
}
.hosPlanItem {
p {
color: #1E2226;
margin-bottom: 14px;
}
div {
color: #8A9099;
}
}
.conflictTip {
height: 22px;
display: flex;
justify-content: center;
align-items: center;
padding: 2px 10px;
gap: 6px;
border-radius: 4px;
background: #FFF1F0;
box-sizing: border-box;
border: 1px solid #FFA39E;
font-size: 14px;
font-weight: normal;
line-height: normal;
text-align: center;
letter-spacing: 0.08em;
color: #FF4D4F;
box-sizing: border-box;
margin-right: 6px;
}
</style>
Loading…
Cancel
Save