index.vue 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. <template>
  2. <div class="content-container">
  3. <el-row class="tool-bar">
  4. <el-col :span="12" class="left">
  5. <div class="content-title">
  6. 医生管理
  7. </div>
  8. </el-col>
  9. <el-col :span="12" class="right">
  10. <el-input v-model="conditions.keywords" class="search-input m-right-15" size="mini" placeholder="请输入内容">
  11. <el-button slot="append" icon="el-icon-search" size="mini" @click="getData()" />
  12. </el-input>
  13. <el-button type="primary" size="mini" icon="el-icon-plus" @click="handleAdd">添加</el-button>
  14. <el-button type="primary" size="mini" :disabled="!(exportItems&&exportItems.length>0)" @click="downloadQrcode">下载二维码</el-button>
  15. </el-col>
  16. </el-row>
  17. <el-row class="content-body">
  18. <el-table v-loading="listLoading" class="page-table" border :data="dataList" height="calc(100vh - 240px)" @selection-change="changeSelection">
  19. <el-table-column type="selection" />
  20. <el-table-column type="index" label="序号" align="center" header-align="center" width="80" />
  21. <el-table-column width="60" align="center" label="头像">
  22. <template v-slot="{row}">
  23. <el-avatar :size="30" :src="row.doctorAvatar" />
  24. </template>
  25. </el-table-column>
  26. <el-table-column label="姓名" align="center" header-align="center" min-width="120">
  27. <template v-slot="{row}">
  28. <span>{{ row.doctorName }}</span>
  29. </template>
  30. </el-table-column>
  31. <el-table-column label="职称" align="center" header-align="center" min-width="120">
  32. <template v-slot="{row}">
  33. <span>{{ row.doctorProfessionalId | doctorProfessionalIdFilter }}</span>
  34. </template>
  35. </el-table-column>
  36. <el-table-column label="所属部门" align="center" header-align="center" min-width="160">
  37. <template v-slot="{row}">
  38. <span>{{ row.groupName }}</span>
  39. </template>
  40. </el-table-column>
  41. <el-table-column label="岗位" align="center" header-align="center" min-width="120">
  42. <template v-slot="{row}">
  43. <span>{{ row.positionName }}</span>
  44. </template>
  45. </el-table-column>
  46. <el-table-column label="其它" align="left" header-align="left">
  47. <template v-slot="{row}">
  48. <span>{{ row.doctorDesc }}</span>
  49. </template>
  50. </el-table-column>
  51. <el-table-column label="二维码" header-align="center" align="center" width="100">
  52. <template v-slot="{row}">
  53. <span class="icon iconfont icon-erweima" @click="showQrcode(row)" />
  54. </template>
  55. </el-table-column>
  56. <el-table-column label="小程序" align="center" header-align="center" width="120">
  57. <template v-slot="{row}">
  58. <el-link>
  59. <span v-if="row.miniNum> 0" @click="handleMini(row)"><i class="el-icon-apple" /></span>
  60. <span v-else @click="handleMini(row)">绑定</span>
  61. </el-link>
  62. </template>
  63. </el-table-column>
  64. <el-table-column label="操作" align="center" width="180" class-name="small-padding fixed-width">
  65. <template v-slot="{row}">
  66. <el-button size="mini" type="primary" @click="handleEdit(row)">修改</el-button>
  67. <el-button size="mini" type="danger" @click="handleDelete(row)">删除</el-button>
  68. </template>
  69. </el-table-column>
  70. </el-table>
  71. <div class="pagination-container">
  72. <pagination v-show="total>0" :total="total" :page.sync="conditions.page" :limit.sync="conditions.limit" @pagination="getData" />
  73. </div>
  74. </el-row>
  75. <Doctor ref="AddDoctor" title="添加" @formSuccess="getData" />
  76. <Doctor ref="EditDoctor" title="编辑" @formSuccess="getData" />
  77. <qrcode ref="qrcode" />
  78. <div id="qrcode" ref="qrcodeModal" style="position:fixed;top:-9999px;" />
  79. <MiniProgramTargetConfig ref="MiniTargetConfig" :target-type="targetType" @formSuccess="getData" />
  80. </div>
  81. </template>
  82. <script>
  83. import QRCode from 'qrcodejs2'
  84. import html2canvas from 'html2canvas'
  85. import JSZip from 'jszip'
  86. import saveAs from 'file-saver'
  87. import Doctor from './components/Doctor'
  88. import Pagination from '@/components/Pagination'
  89. import qrcodeComponents from '@/views/hos/components/qrcode.vue'
  90. import MiniProgramTargetConfig from '@/components/MiniProgramTargetConfig/index.vue'
  91. import { getDoctorByPage, deleteDoctorById } from '@/api/hos/doctorApi'
  92. import { getSettingById } from '@/api/system/settingApi'
  93. import { getUserData } from '@/utils/auth'
  94. let zip = new JSZip()
  95. export default {
  96. name: 'DoctorIndex',
  97. components: {
  98. Pagination,
  99. Doctor,
  100. MiniProgramTargetConfig,
  101. qrcode: qrcodeComponents
  102. },
  103. filters: {
  104. doctorProfessionalIdFilter(val) {
  105. const professionalMap = ['主任医师', '副主任医师', '主治医师', '医师', '医士']
  106. return professionalMap[val]
  107. }
  108. },
  109. data() {
  110. return {
  111. dataList: null,
  112. listLoading: false,
  113. total: 0,
  114. targetType: 3,
  115. conditions: {
  116. page: 1,
  117. limit: 10,
  118. keywords: ''
  119. },
  120. ocId: undefined,
  121. miniUrl: '',
  122. exportItems: []
  123. }
  124. },
  125. mounted() {
  126. const userData = getUserData()
  127. this.ocId = userData.ocId
  128. this.getMiniUrl()
  129. this.getData()
  130. },
  131. methods: {
  132. // 获取小程序地址
  133. getMiniUrl() {
  134. const settingId = 1
  135. this.listLoading = true
  136. getSettingById(settingId).then((resp) => {
  137. const { code, msg, data } = resp
  138. this.listLoading = false
  139. if (code === 200) {
  140. this.miniUrl = data.settingValue
  141. } else {
  142. this.$message.error(msg)
  143. }
  144. }).catch((error) => {
  145. console.log(error)
  146. })
  147. },
  148. // 初始化数据
  149. getData() {
  150. this.listLoading = true
  151. getDoctorByPage(this.conditions).then((resp) => {
  152. const { data, total } = resp
  153. this.listLoading = false
  154. this.total = total
  155. this.dataList = data
  156. }).catch((error) => {
  157. console.log(error)
  158. })
  159. },
  160. // 添加
  161. handleAdd() {
  162. this.$refs['AddDoctor'].showAddModel()
  163. },
  164. // 修改
  165. handleEdit(data) {
  166. const { doctorId } = data
  167. this.$refs['EditDoctor'].showEditModel(doctorId)
  168. },
  169. // 删除
  170. handleDelete(data) {
  171. const { doctorId, doctorName } = data
  172. this.$confirm(`此操作将删除该数据${doctorName}, 是否继续?`, '提示', {
  173. confirmButtonText: '确定',
  174. cancelButtonText: '取消',
  175. type: 'warning'
  176. }).then(() => {
  177. deleteDoctorById(doctorId).then((resp) => {
  178. const { msg } = resp
  179. this.getData()
  180. this.$message.success(msg)
  181. }).catch((error) => {
  182. console.log(error)
  183. })
  184. }).catch(() => {
  185. this.$message({ type: 'info', message: '已取消删除' })
  186. })
  187. },
  188. changeSelection(selection) {
  189. const len = selection.length
  190. this.hanleModal = (len > 0)
  191. this.exportItems = selection
  192. },
  193. showQrcode(row) {
  194. const code = this.miniUrl + '?ocId=' + this.ocId + '&code=' + row.doctorCode
  195. this.$refs.qrcode.draw(code)
  196. },
  197. downloadQrcode() {
  198. if (this.exportItems && this.exportItems.length > 0) {
  199. var content = JSON.parse(JSON.stringify(this.exportItems))
  200. this.downloadMaterial(content)
  201. } else { this.$message.error('没有可下载的数据!') }
  202. },
  203. downloadMaterial(content) { // 下载物料
  204. this.batch(content, '医生管理')
  205. },
  206. async batch(arr, fileName) {
  207. var self = this
  208. window.loading = this.$loading({
  209. lock: true,
  210. text: '制作二维码中!',
  211. spinner: 'el-icon-loading',
  212. background: 'rgba(0, 0, 0, 0.7)'
  213. })
  214. zip = new JSZip()
  215. for (var i = 0; i < arr.length; i++) {
  216. var item = arr[i]
  217. const code = this.miniUrl + '?ocId=' + this.ocId + '&code=' + item.doctorCode
  218. await self.drawQrcode(code).catch(() => {
  219. window.loading.close()
  220. this.$message.error('导出失败')
  221. })
  222. await self.packMaterial(item.doctorName).catch(() => {
  223. window.loading.close()
  224. this.$message.error('导出失败')
  225. })
  226. }
  227. zip.generateAsync({
  228. type: 'blob'
  229. }).then((blob) => {
  230. saveAs(blob, fileName + '二维码物料.zip')
  231. window.loading.close()
  232. })
  233. },
  234. drawQrcode(url, sleep = 300) { // 绘制二维码
  235. this.$refs.qrcodeModal.innerHTML = ''
  236. return new Promise((resolve, reject) => {
  237. new QRCode('qrcode', {
  238. width: 400,
  239. height: 400,
  240. text: url.toString()
  241. })
  242. setTimeout(function() {
  243. resolve()
  244. }, sleep)
  245. })
  246. },
  247. packMaterial(name) { // 打包处理
  248. if (!name) name = 'xxx'
  249. return new Promise((resolve, reject) => {
  250. html2canvas(document.getElementById('qrcode'), {
  251. backgroundColor: null,
  252. useCORS: true,
  253. dpi: 500,
  254. scale: 5
  255. }).then((canvas) => {
  256. let dataURL = canvas.toDataURL('photo/png')
  257. dataURL = dataURL.replace(/^data:image\/(png|jpg);base64,/, '')
  258. zip.file(name + '.jpg', dataURL, { base64: true })
  259. resolve()
  260. }).catch((e) => {
  261. reject(e)
  262. })
  263. })
  264. },
  265. // 显示App绑定配置
  266. handleMini(data) {
  267. const { gridId } = data
  268. this.$refs['MiniTargetConfig'].showModel(gridId)
  269. }
  270. }
  271. }
  272. </script>
  273. <style scoped>
  274. .content-container {
  275. height: calc(100vh - 90px);
  276. }
  277. </style>