Index.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. <template>
  2. <div class="component-box-wrapper__half-transparent" :style="{ zIndex }">
  3. <div class="component-content-box__dialog-like box-width">
  4. <div class="component-header-box">
  5. <div class="component-header__title">{{ title }}</div>
  6. <div class="component-header__close-button">
  7. <el-button plain icon="Close" circle title="关闭" @click="close"></el-button>
  8. </div>
  9. </div>
  10. <div v-if="tip" style="margin: -8px 0 8px 0; color: red">
  11. {{tip}}
  12. </div>
  13. <div style="display: flex;align-items: center;">
  14. <div>检索依据:</div>
  15. <div>
  16. <el-select v-model="params.method" style="width: 70px">
  17. <el-option
  18. v-for="item in allMethods"
  19. :key="item.code"
  20. :label="item.name"
  21. :value="item.code"
  22. ></el-option>
  23. </el-select>
  24. </div>
  25. <div v-if="showMallType" style="margin-left: 4px">
  26. 项目类别:
  27. </div>
  28. <div v-if="showMallType">
  29. <el-select v-model="params.target" style="width: 60px">
  30. <el-option label="检验" value="JY" />
  31. <el-option label="检查" value="JC" />
  32. <el-option label="诊疗" value="ZL" />
  33. </el-select>
  34. </div>
  35. <div>
  36. <el-input
  37. ref="inputRef"
  38. v-model="params.content"
  39. clearable
  40. placeholder="请输入检索内容"
  41. style="width: 180px;margin-left: 4px"
  42. ></el-input>
  43. </div>
  44. </div>
  45. <div class="data-box">
  46. <el-table
  47. ref="resultRef"
  48. :data="data.list"
  49. stripe height="360px"
  50. highlight-current-row
  51. @row-click="clickItem"
  52. >
  53. <el-table-column prop="code" label="编码"></el-table-column>
  54. <el-table-column prop="name" label="名称"></el-table-column>
  55. <el-table-column v-if="showEmpDept" prop="deptName" label="科室"></el-table-column>
  56. <el-table-column v-if="showYbCode" prop="ybCode" label="医保赋码"></el-table-column>
  57. <el-table-column v-if="showOpScale" prop="opScale" label="手术/操作级别" align="center"></el-table-column>
  58. <el-table-column v-if="showOpType" prop="opTypeName" label="手术/操作类型"></el-table-column>
  59. </el-table>
  60. <el-pagination
  61. @current-change="handleCurrentChange"
  62. :current-page="params.page"
  63. :page-size="params.pageSize"
  64. layout="total, pager, next"
  65. :total="data.totalSize"
  66. ></el-pagination>
  67. </div>
  68. </div>
  69. <el-dialog title="请确认诊断类别" v-model="showDiagType" width="360px">
  70. <div style="margin-top: 8px">
  71. 诊断编码:
  72. <el-input v-model="diagItem.icdCode" disabled style="width: 220px"></el-input>
  73. </div>
  74. <div style="margin-top: 8px">
  75. 诊断名称:
  76. <el-input v-model="diagItem.icdText" disabled style="width: 220px"></el-input>
  77. </div>
  78. <div style="margin-top: 8px">
  79. 诊断类别:
  80. <el-select v-model="diagItem.diagType" style="width: 220px">
  81. <el-option v-for="item in diagTypes" :key="item.code" :value="item.code" :label="item.name"></el-option>
  82. </el-select>
  83. </div>
  84. <div style="margin-top: 8px; width: 100%; text-align: right; padding: 8px 20px 8px 0">
  85. <el-button type="primary" icon="Check" @click="confirmDiaginfo">确定</el-button>
  86. </div>
  87. </el-dialog>
  88. </div>
  89. </template>
  90. <script setup>
  91. import { reactive, ref, watch } from 'vue'
  92. import { searchFromServer } from '@/api/inpatient/dictionary'
  93. import { diagTypes } from '@/data'
  94. import Sleep from '@/utils/sleep'
  95. import {useZIndex} from "element-plus";
  96. const props = defineProps({
  97. width: {
  98. type: String,
  99. default: '420px'
  100. },
  101. title: {
  102. type: String,
  103. required: true,
  104. },
  105. tip: {
  106. type: String,
  107. required: false,
  108. },
  109. target: {
  110. type: String,
  111. required: true,
  112. },
  113. zyType: {
  114. type: String,
  115. default: 'B'
  116. },
  117. medType: {
  118. type: String,
  119. default: '',
  120. },
  121. showEmpDept: {
  122. type: Boolean,
  123. default: false
  124. },
  125. showYbCode: {
  126. type: Boolean,
  127. default: false
  128. },
  129. showOpScale: {
  130. type: Boolean,
  131. default: false
  132. },
  133. showOpType: {
  134. type: Boolean,
  135. default: false
  136. },
  137. showMallType: {
  138. type: Boolean,
  139. default: false
  140. }
  141. })
  142. const emits = defineEmits(['close', 'clickItem'])
  143. const width = props.width
  144. const inputRef = ref(null)
  145. const resultRef = ref(null)
  146. const allMethods = [
  147. { code: 'alpha', name: '拼音' },
  148. { code: 'code', name: '编码' },
  149. { code: 'name', name: '名称' },
  150. ]
  151. const params = reactive({
  152. method: 'alpha',
  153. target: props.target,
  154. medType: props.medType,
  155. zyType: props.zyType,
  156. page: 1,
  157. pageSize: 10,
  158. content: '',
  159. })
  160. const data = reactive({
  161. list: [],
  162. totalSize: 0,
  163. })
  164. const showDiagType = ref(false)
  165. const diagItem = reactive({
  166. icdCode: null,
  167. icdText: null,
  168. diagType: null,
  169. })
  170. const executeSearch = () => {
  171. if (params.content.trim().length > 1) {
  172. searchFromServer(params).then((res) => {
  173. data.list = res.list
  174. data.totalSize = res.totalSize
  175. currentIndex.value = currentIndex.value > data.list.length - 1 ? data.list.length - 1 : currentIndex.value
  176. resultRef.value.setCurrentRow(data.list[currentIndex.value])
  177. })
  178. } else {
  179. data.list = []
  180. data.totalSize = 0
  181. }
  182. }
  183. const currentIndex = ref(0)
  184. const handleCurrentChange = (val) => {
  185. params.page = val
  186. executeSearch()
  187. }
  188. const confirmDiaginfo = () => {
  189. emits('clickItem', diagItem)
  190. }
  191. const clickItem = (item) => {
  192. if (props.target === 'diag' || props.target === 'injurydiag') {
  193. diagItem.icdCode = item.code
  194. diagItem.icdText = item.name
  195. diagItem.diagType = '1'
  196. showDiagType.value = true
  197. } else {
  198. if (props.showMallType) {
  199. item.type = params.target
  200. }
  201. emits('clickItem', item)
  202. }
  203. }
  204. const close = () => {
  205. emits('close')
  206. }
  207. watch(
  208. () => params.content,
  209. () => {
  210. executeSearch()
  211. }
  212. )
  213. const zIndex = ref(0)
  214. onMounted(async () => {
  215. zIndex.value = useZIndex().nextZIndex()
  216. await Sleep(100)
  217. inputRef.value.focus()
  218. document.onkeydown = (e) => {
  219. switch (e.code) {
  220. case 'ArrowUp':
  221. resultRef.value.setCurrentRow(data.list[currentIndex.value === 0 ? 0 : --currentIndex.value])
  222. return false
  223. case 'ArrowDown':
  224. resultRef.value.setCurrentRow(data.list[currentIndex.value === data.list.length - 1 ? data.list.length - 1 : ++currentIndex.value])
  225. return false
  226. case 'ArrowLeft':
  227. if (params.page > 1) {
  228. handleCurrentChange(params.page - 1)
  229. }
  230. return false
  231. case 'ArrowRight':
  232. if (params.page * params.pageSize < data.totalSize) {
  233. handleCurrentChange(params.page + 1)
  234. }
  235. return false
  236. case 'Enter':
  237. clickItem(data.list[currentIndex.value])
  238. break
  239. case 'Escape':
  240. close()
  241. break
  242. }
  243. }
  244. })
  245. </script>
  246. <style scoped>
  247. .box-width {
  248. width: v-bind(width);
  249. }
  250. .data-box {
  251. margin-top: 16px;
  252. overflow-y: auto;
  253. border-top: 1px solid rgb(231, 231, 231);
  254. }
  255. </style>