index.vue 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064
  1. <template>
  2. <div class="app-container subject">
  3. <div class="page-container subject-page" v-if="pageType == 1">
  4. <div class="left-subject-list">
  5. <div class="page-form-title-box">
  6. <el-form :model="queryParams" ref="queryForm" :inline="true">
  7. <el-form-item label="" prop="searchValue">
  8. <el-input
  9. v-model="queryParams.searchValue"
  10. placeholder="实验室/房间号"
  11. clearable
  12. maxlength="10"
  13. style="width:150px;"
  14. />
  15. </el-form-item>
  16. <el-form-item label="" prop="deptId">
  17. <el-select v-model="queryParams.deptId" placeholder="二级单位" style="width:140px;">
  18. <el-option
  19. v-for="dict in deptOptions"
  20. :key="dict.deptId"
  21. :label="dict.deptName"
  22. :value="dict.deptId"
  23. ></el-option>
  24. </el-select>
  25. </el-form-item>
  26. <el-form-item label="" prop="buildId">
  27. <el-select v-model="queryParams.buildId" placeholder="楼栋" style="width:140px;">
  28. <el-option
  29. v-for="dict in buildOptions"
  30. :key="dict.id"
  31. :label="dict.name"
  32. :value="dict.id"
  33. ></el-option>
  34. </el-select>
  35. </el-form-item>
  36. <el-form-item label="" prop="typeId">
  37. <el-select v-model="queryParams.typeId" placeholder="安全分类" style="width:140px;">
  38. <el-option
  39. v-for="dict in typeList"
  40. :key="dict.typeId"
  41. :label="dict.typeName"
  42. :value="dict.typeId"
  43. ></el-option>
  44. </el-select>
  45. </el-form-item>
  46. <el-form-item label="" prop="levelId">
  47. <el-select v-model="queryParams.levelId" placeholder="安全分级" style="width:140px;">
  48. <el-option
  49. v-for="dict in levelList"
  50. :key="dict.levelId"
  51. :label="dict.levelName"
  52. :value="dict.levelId"
  53. ></el-option>
  54. </el-select>
  55. </el-form-item>
  56. <p class="page-inquire-common-style-button" @click="handleQuery">查询</p>
  57. <p class="page-reset-common-style-button" @click="resetQuery">重置</p>
  58. <el-dropdown @command="commandButton" style="float: right;">
  59. <p class="page-submit-common-style-button" style="width:105px;"
  60. >操作<span class="el-icon-arrow-down" style="margin-left:10px;"></span></p>
  61. <el-dropdown-menu slot="dropdown">
  62. <el-dropdown-item :command="{command:1}" v-hasPermiRouter="['system:subject:add']">新增</el-dropdown-item>
  63. <!--<el-dropdown-item :command="{command:2}">关联配置</el-dropdown-item>-->
  64. <!--<el-dropdown-item :command="{command:3}">准入配置</el-dropdown-item>-->
  65. <el-dropdown-item :command="{command:4}">下载二维码</el-dropdown-item>
  66. </el-dropdown-menu>
  67. </el-dropdown>
  68. <el-form-item v-hasPermiRouter="['system:subject:import']" style="float: right;">
  69. <import-component :importConfig="importConfig"></import-component>
  70. </el-form-item>
  71. </el-form>
  72. </div>
  73. <div class="page-content-box">
  74. <el-table class="table-box" ref="table-box" border :data="dataList" highlight-current-row
  75. @select-all="handleSelectionChange" @select="handleSelectionChange" :row-key="getRowKeys"
  76. @current-change="handleCurrentChange">
  77. <el-table-column type="selection" width="50" :reserve-selection="true" align="center"/>
  78. <el-table-column label="排序" align="left" prop="orderNum" width="75">
  79. <template slot-scope="scope">
  80. <el-input maxlength="4" type="text" oninput="value=value.replace(/[^0-9.]/g,'')"
  81. v-model="scope.row.orderNum" @focus="liveSort(scope.row)"
  82. @blur="editSort(scope.row)">
  83. </el-input>
  84. </template>
  85. </el-table-column>
  86. <el-table-column label="实验室名称" align="left" prop="subName" show-overflow-tooltip/>
  87. <el-table-column label="房间号" align="left" prop="roomName" width="100" show-overflow-tooltip>
  88. <template slot-scope="scope">
  89. <span>{{scope.row.roomName?scope.row.roomName:'未绑定'}}</span>
  90. </template>
  91. </el-table-column>
  92. <el-table-column label="学院" align="left" prop="deptName" width="130" show-overflow-tooltip/>
  93. <el-table-column label="楼栋/楼层" align="left" prop="buildName" width="130" show-overflow-tooltip>
  94. <template slot-scope="scope">
  95. <span>{{scope.row.buildName}}/{{scope.row.floorName}}</span>
  96. </template>
  97. </el-table-column>
  98. <el-table-column label="分类/分级" align="left" prop="levelName" width="150" show-overflow-tooltip>
  99. <template slot-scope="scope">
  100. <span>{{scope.row.typeName}}/</span>
  101. <span :style="'color:'+scope.row.levelColor+';'">{{scope.row.levelName}}</span>
  102. </template>
  103. </el-table-column>
  104. <el-table-column label="实验室责任人" align="left" prop="adminName" width="120" show-overflow-tooltip/>
  105. <el-table-column label="安全员" align="left" prop="safeUserNames" width="120" show-overflow-tooltip/>
  106. <el-table-column label="操作" align="left" width="140">
  107. <template slot-scope="scope">
  108. <div class="table-button-box">
  109. <p class="table-button-null"></p>
  110. <p class="table-button-p" v-hasPermiRouter="['system:subject:detail']"
  111. @click.stop="clickPage(7,scope.row)">详情</p>
  112. <el-dropdown trigger="click" size="mini" @command="(command) => handleCommand(command, scope.row)">
  113. <p class="table-button-p">更多>></p>
  114. <el-dropdown-menu slot="dropdown" style="margin:0!important;">
  115. <el-dropdown-item style="height:36px;line-height:36px;width:90px;text-align: center" command="1"
  116. v-hasPermiRouter="['system:subject:edit']">关联配置
  117. </el-dropdown-item>
  118. <el-dropdown-item style="height:36px;line-height:36px;width:90px;text-align: center" command="2"
  119. v-hasPermiRouter="['system:subject:edit']">准入配置
  120. </el-dropdown-item>
  121. <el-dropdown-item style="height:36px;line-height:36px;width:90px;text-align: center" command="3"
  122. v-hasPermiRouter="['system:subject:edit']">编辑
  123. </el-dropdown-item>
  124. <el-dropdown-item style="height:36px;line-height:36px;width:90px;text-align: center" command="5"
  125. v-hasPermiRouter="['system:subject:edit']">信息牌下载
  126. </el-dropdown-item>
  127. </el-dropdown-menu>
  128. </el-dropdown>
  129. <p class="table-button-null"></p>
  130. </div>
  131. </template>
  132. </el-table-column>
  133. </el-table>
  134. <pagination
  135. v-show="total>0"
  136. :total="total"
  137. :page.sync="queryParams.page"
  138. :limit.sync="queryParams.pageSize"
  139. @pagination="getList"
  140. />
  141. </div>
  142. </div>
  143. <index-right-page ref="indexRightPage"></index-right-page>
  144. </div>
  145. <!--电子信息牌导出-->
  146. <el-dialog class="subject-dialog" title='' width="1354px" append-to-body
  147. :visible.sync="dialogType" v-if="dialogType" @close="dialogOff()"
  148. :close-on-click-modal="false" :close-on-press-escape="false">
  149. <div class="subject-dialog-button-box">
  150. <p @click="dialogOff">取消</p>
  151. <p @click="downloadImg">下载</p>
  152. </div>
  153. <div id="subject-dialog-print-box" ref="canvasImg">
  154. <div class="subject-dialog-print-big-box">
  155. <!--信息栏-->
  156. <div class="subject-dialog-print-top-box">
  157. <div class="subject-dialog-print-top-left-box">
  158. <div class="subject-dialog-print-top-left-top-box">
  159. <!--实验室名称-->
  160. <div class="subject-dialog-name-box">
  161. <div class="title-box-1">
  162. <div class="title-box-2" :style="'background-color:'+dialogData.filedColor+';'">
  163. <div class="title-box-3">
  164. <p :style="'background-color:'+dialogData.filedColor+';'">{{dialogData.levelName}}丨{{dialogData.typeName}}</p>
  165. </div>
  166. </div>
  167. </div>
  168. <p class="title-p">实验室安全信息牌</p>
  169. </div>
  170. <!--实验室信息-->
  171. <div class="subject-dialog-info-box">
  172. <div class="subject-dialog-info-left-box">
  173. <p>实验室名称:{{dialogData.subjectName}} - {{dialogData.room}}</p>
  174. <p>责 任 单 位:{{dialogData.deptName}}</p>
  175. <p>实验室负责人:{{dialogData.adminName}}|{{dialogData.adminPhone}}</p>
  176. <p>安全责任人:<span v-for="(item,index) in dialogData.safeUserVoList" :key="index">{{item.safeUserName}}|{{item.safeUserPhone}}{{index==0?' 、':''}}</span></p>
  177. </div>
  178. <div class="subject-dialog-info-right-box">
  179. <img :src="dialogData.qrCodeUrl">
  180. </div>
  181. </div>
  182. </div>
  183. <div class="subject-dialog-print-top-left-bottom-box">
  184. <!--1号右侧信息栏-->
  185. <div class="subject-dialog-print-top-left-bottom-left-box" v-if="dialogData.dataOne">
  186. <p class="data-title" :style="'background-color:'+dialogData.dataOne.showColour+';'">{{dialogData.dataOne.classifyName}}</p>
  187. <div class="data-for-text" v-if="dialogData.dataOne.classifyType == 1">
  188. <p v-for="(item,index) in dialogData.dataOne.classifyList" :key="index">{{index+1}}、{{item}}</p>
  189. </div>
  190. <div class="data-for-img" v-if="dialogData.dataOne.classifyType == 2">
  191. <img v-for="(item,index) in dialogData.dataOne.classifyList" :key="index" :src="item">
  192. </div>
  193. </div>
  194. <!--2号右侧信息栏-->
  195. <div class="subject-dialog-print-top-left-bottom-right-box" v-if="dialogData.dataTwo">
  196. <p class="data-title" :style="'background-color:'+dialogData.dataTwo.showColour+';'">{{dialogData.dataTwo.classifyName}}</p>
  197. <div class="data-for-text" v-if="dialogData.dataTwo.classifyType == 1">
  198. <p v-for="(item,index) in dialogData.dataTwo.classifyList" :key="index">{{index+1}}、{{item}}</p>
  199. </div>
  200. <div class="data-for-img" v-if="dialogData.dataTwo.classifyType == 2">
  201. <img v-for="(item,index) in dialogData.dataTwo.classifyList" :key="index" :src="item">
  202. </div>
  203. </div>
  204. </div>
  205. </div>
  206. <!--3号右侧信息栏-->
  207. <div class="subject-dialog-print-top-right-box" v-if="dialogData.dataThree">
  208. <p class="data-title" :style="'background-color:'+dialogData.dataThree.showColour+';'">{{dialogData.dataThree.classifyName}}</p>
  209. <div class="data-for-text" v-if="dialogData.dataThree.classifyType == 1">
  210. <p v-for="(item,index) in dialogData.dataThree.classifyList" :key="index">{{index+1}}、{{item}}</p>
  211. </div>
  212. <div class="data-for-img" v-if="dialogData.dataThree.classifyType == 2">
  213. <img v-for="(item,index) in dialogData.dataThree.classifyList" :key="index" :src="item">
  214. </div>
  215. </div>
  216. </div>
  217. <!--特殊类目-->
  218. <div class="subject-dialog-print-button-box" :style="'background:'+dialogData.specialBrandInfo.showColour+';'">
  219. <span v-for="(item,index) in dialogData.specialBrandInfo.classifyList" :key="index">{{item}}</span>
  220. </div>
  221. </div>
  222. </div>
  223. <div class="subject-dialog-shade" v-if="dialogShadeType"></div>
  224. </el-dialog>
  225. <!--新增/编辑-->
  226. <add-subject v-if="pageType == 2" :subjectData="subjectData"></add-subject>
  227. <!--准入配置-->
  228. <admission-configuration v-if="pageType == 4" :subjectData="subjectData"></admission-configuration>
  229. <!--关联配置-->
  230. <association-configuration v-if="pageType == 5" :subjectData="subjectData"></association-configuration>
  231. <!--详情-->
  232. <info-page v-if="pageType == 6" :subjectData="subjectData"></info-page>
  233. <!--批量二维码-->
  234. <batchQrCodeDialog ref="batchQrCodeDialog" :batchQrCodeDialogData="batchQrCodeDialogData"></batchQrCodeDialog>
  235. </div>
  236. </template>
  237. <script>
  238. /********************** V3 **********************/
  239. import html2canvas from 'html2canvas'
  240. import importComponent from "@/components/importComponent/importComponent.vue";
  241. import batchQrCodeDialog from "@/components/batchQrCodeDialog/batchQrCodeDialog.vue";
  242. import {
  243. getDeptDropList,
  244. systemBuildingGetTreeList,
  245. laboratoryClassTypeGetList,
  246. laboratoryClassLevelGetList,
  247. } from '@/api/commonality/permission'
  248. import {
  249. laboratorySubRelInfoList,
  250. laboratorySubRelInfoGetDetailInfo,
  251. laboratorySubRelInfoGetHazardSubRelInfo,
  252. laboratorySubRelInfoUpdateBySort,
  253. laboratorySubRelInfoUpdateByControl,
  254. laboratoryBoardExportBoardInfo,
  255. } from '@/api/integratedManagement/index'
  256. import indexRightPage from './indexRightPage/indexRightPage.vue'
  257. import addSubject from './addSubject.vue'
  258. import admissionConfiguration from './admissionConfiguration.vue'
  259. import associationConfiguration from './associationConfiguration.vue'
  260. import infoPage from './infoPage.vue'
  261. export default {
  262. name: 'subject',
  263. components: {
  264. importComponent,
  265. addSubject,
  266. admissionConfiguration,
  267. associationConfiguration,
  268. infoPage,
  269. indexRightPage,
  270. batchQrCodeDialog
  271. },
  272. data() {
  273. return {
  274. //批量二维码
  275. batchQrCodeDialogData:{},
  276. //电子信息牌
  277. dialogType:false,
  278. dialogData:{},
  279. dialogShadeType:false,
  280. //导入数据
  281. importConfig:{
  282. upLoadApi:'/laboratory/subRelInfo/importSubData', //上传接口地址
  283. downloadApi:'/laboratory/subRelInfo/exportSubTemplate', //下载模板接口地址
  284. loseApi:'/laboratory/subRelInfo/exportProblemData', //失败报表接口地址
  285. fileName:'实验室导入模板', //下载模板命名
  286. },
  287. //页面状态
  288. pageType: 1,
  289. // 查询参数
  290. queryParams: {
  291. page: 1,
  292. pageSize: 20,
  293. searchValue: '',
  294. deptId: '',
  295. typeId: '',
  296. levelId: ''
  297. },
  298. // 实验室表格数据
  299. dataList: [],
  300. // 楼栋
  301. buildOptions:[],
  302. // 总条数
  303. total: 0,
  304. //学院列表
  305. deptOptions: [],
  306. //实验室数据
  307. subjectData: {},
  308. // 临时保存排序
  309. orderNum: '',
  310. //分类数据
  311. typeList: [],
  312. //分级数据
  313. levelList: [],
  314. //二维码勾选数据
  315. codeList:'',
  316. }
  317. },
  318. created() {
  319. },
  320. mounted() {
  321. //获取院系列表
  322. this.getDeptDropList()
  323. //获取楼栋列表
  324. this.systemBuildingGetTreeList()
  325. //获取分类列表
  326. this.laboratoryClassTypeGetList()
  327. //获取分级列表
  328. this.laboratoryClassLevelGetList()
  329. //获取列表数据
  330. this.getList()
  331. },
  332. methods: {
  333. //操作按钮
  334. commandButton(item){
  335. if(item.command == 1){
  336. this.clickPage(2);
  337. }else if(item.command == 2){
  338. }else if(item.command == 3){
  339. }else if(item.command == 4){
  340. if(this.codeList.length>0){
  341. let list = [];
  342. this.codeList.forEach((item)=>{
  343. list.push({
  344. code:item.infoId+'&subId='+item.subId,
  345. name:item.subName
  346. })
  347. })
  348. this.$set(this,'batchQrCodeDialogData',{
  349. title:'实验室二维码批量下载', //弹窗名称(非必传)
  350. type:'5', //二维码类型 用于区分二维码功能类型
  351. codeList:list
  352. });
  353. this.$nextTick(function () {
  354. this.$refs['batchQrCodeDialog'].initialize();
  355. })
  356. }else{
  357. this.msgError('请勾选实验室')
  358. }
  359. }
  360. },
  361. // 页面切换
  362. clickPage(type, row) {
  363. if (this.pageType != type) {
  364. if (type == 1) {
  365. //列表页面
  366. this.pageType = type
  367. this.getList()
  368. this.$set(this, 'subjectData', {})
  369. } else if (type == 2) {
  370. //新增页面
  371. this.pageType = type
  372. }else if (type == 7) {
  373. //实验室详情
  374. this.getSubInfo(row,1)
  375. }
  376. }
  377. },
  378. //更多按钮
  379. handleCommand(command, row) {
  380. let self = this
  381. switch (command) {
  382. case '1':
  383. //关联配置
  384. laboratorySubRelInfoGetHazardSubRelInfo({ infoId: row.infoId }).then(response => {
  385. this.$set(this, 'subjectData', response.data)
  386. this.$set(this, 'pageType', 5)
  387. })
  388. break
  389. case '2':
  390. //准入配置
  391. this.pageType = 4
  392. this.$set(this, 'subjectData', row)
  393. break
  394. case '3':
  395. //编辑页面
  396. this.getSubInfo(row,2)
  397. break
  398. case '4':
  399. let text = row.accessControl?'关闭':'开启'
  400. //开启/关闭门禁权限
  401. self.$confirm('是否确认'+text+'实验室准入?', '', {
  402. confirmButtonText: '确定',
  403. cancelButtonText: '取消',
  404. type: 'warning'
  405. }).then(function() {
  406. laboratorySubRelInfoUpdateByControl({
  407. infoId: row.infoId,
  408. accessControl:!row.accessControl
  409. }).then(response => {
  410. self.msgSuccess(response.message)
  411. self.getList()
  412. })
  413. }).then(() => {
  414. }).catch(() => {
  415. })
  416. break
  417. case '5':
  418. laboratoryBoardExportBoardInfo({
  419. labId: row.subId,
  420. }).then(response => {
  421. let textLength = 0;
  422. let textIndex = null;
  423. for(let i=0;i<response.data.nonspecialBrandList.length;i++){
  424. if(response.data.nonspecialBrandList[i].classifyType == 1){
  425. response.data.nonspecialBrandList[i].length = 0;
  426. for(let o=0;o<response.data.nonspecialBrandList[i].classifyList.length;o++){
  427. response.data.nonspecialBrandList[i].length = response.data.nonspecialBrandList[i].length + response.data.nonspecialBrandList[i].classifyList[o].length;
  428. }
  429. if(response.data.nonspecialBrandList[i].length>textLength){
  430. textLength = response.data.nonspecialBrandList[i].length
  431. textIndex = i
  432. }
  433. }
  434. }
  435. if(textIndex != null){
  436. for(let i=0;i<response.data.nonspecialBrandList.length;i++){
  437. if(textIndex == i){
  438. response.data.dataThree = response.data.nonspecialBrandList[i]
  439. }else{
  440. if(!response.data.dataOne){
  441. response.data.dataOne = response.data.nonspecialBrandList[i]
  442. }else if(!response.data.dataTwo){
  443. response.data.dataTwo = response.data.nonspecialBrandList[i]
  444. }
  445. }
  446. }
  447. }else{
  448. if (response.data.nonspecialBrandList[0]){
  449. response.data.dataOne = response.data.nonspecialBrandList[0];
  450. }
  451. if (response.data.nonspecialBrandList[1]){
  452. response.data.dataTwo = response.data.nonspecialBrandList[1];
  453. }
  454. if (response.data.nonspecialBrandList[2]){
  455. response.data.dataThree = response.data.nonspecialBrandList[2];
  456. }
  457. }
  458. this.$nextTick(() => {
  459. this.$set(this,'dialogData',response.data);
  460. this.$set(this,'dialogType',true);
  461. this.$set(this,'dialogShadeType',false);
  462. })
  463. })
  464. break
  465. default:
  466. break
  467. }
  468. },
  469. //电子信息牌导出关闭按钮
  470. dialogOff(){
  471. this.$set(this,'dialogType',false);
  472. this.$set(this,'dialogData',{});
  473. },
  474. downloadImg(){
  475. if(!this.dialogShadeType){
  476. this.$set(this,'dialogShadeType',true);
  477. this.$nextTick(() => {
  478. this.createImage();
  479. })
  480. }
  481. },
  482. //下载电子信息牌
  483. async createImage() {
  484. try {
  485. const canvas = await html2canvas(this.$refs.canvasImg) // 在这里,将需要转换成图片的部分作为参数传入html2canvas
  486. const image = canvas.toDataURL() // 将生成的canvas转换为DataURL格式
  487. console.log(image) // 可以将image自行存储
  488. this.$nextTick(() => {
  489. this.downloadQrCode(image);
  490. })
  491. } catch (e) {
  492. throw new Error(e)
  493. }
  494. },
  495. //下载BASE64图片
  496. downloadQrCode(image) {
  497. const blob = this.base64ToBlob(image, 'image/png')
  498. const url = URL.createObjectURL(blob)
  499. const link = document.createElement('a')
  500. link.href = url
  501. link.download = this.dialogData.subjectName+' - '+this.dialogData.room
  502. document.body.appendChild(link)
  503. link.click()
  504. // 清理
  505. document.body.removeChild(link)
  506. URL.revokeObjectURL(url)
  507. this.$nextTick(() => {
  508. this.msgSuccess('下载成功')
  509. this.$set(this,'dialogType',false);
  510. this.$set(this,'dialogData',{});
  511. })
  512. },
  513. base64ToBlob(base64Str, contentType, sliceSize) {
  514. contentType = contentType || ''
  515. sliceSize = sliceSize || 512
  516. const byteCharacters = atob(base64Str.split(',')[1])
  517. const byteArrays = []
  518. for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
  519. const slice = byteCharacters.slice(offset, offset + sliceSize)
  520. const byteNumbers = new Array(slice.length)
  521. for (let i = 0; i < slice.length; i++) {
  522. byteNumbers[i] = slice.charCodeAt(i)
  523. }
  524. const byteArray = new Uint8Array(byteNumbers)
  525. byteArrays.push(byteArray)
  526. }
  527. const blob = new Blob(byteArrays, { type: contentType })
  528. return blob
  529. },
  530. //获取实验室详情 type:1.详情 2.编辑
  531. getSubInfo(row,type){
  532. laboratorySubRelInfoGetDetailInfo({ infoId: row.infoId }).then(response => {
  533. let classifyList = [];
  534. for(let i=0;i<response.data.labInfoBrandModels.length;i++){
  535. if(response.data.labInfoBrandModels[i].privateList.length>0 && (response.data.labInfoBrandModels[i].brandType==1||response.data.labInfoBrandModels[i].brandType==2)){
  536. classifyList.push(response.data.labInfoBrandModels[i]);
  537. }
  538. }
  539. response.data.classifyList = classifyList;
  540. if(response.data.safeUserList[0]){
  541. response.data.safeUserId = [];
  542. response.data.safeUserList.forEach((item)=>{
  543. response.data.safeUserId.push(item.safeUserId);
  544. })
  545. }
  546. this.$set(this, 'subjectData', response.data)
  547. if(type == 1){
  548. //详情
  549. this.$set(this, 'pageType', 6)
  550. }else if(type == 2){
  551. //编辑
  552. this.$set(this, 'pageType', 2)
  553. }
  554. })
  555. },
  556. //保存当前排序
  557. liveSort(row) {
  558. let obj = {
  559. orderNum: row.orderNum
  560. }
  561. this.orderNum = JSON.parse(JSON.stringify(obj))
  562. },
  563. //编辑排序
  564. editSort(row) {
  565. let self = this
  566. if (row.orderNum != this.orderNum.orderNum) {
  567. self.$confirm('是否确认修改排序?', '', {
  568. confirmButtonText: '确定',
  569. cancelButtonText: '取消',
  570. type: 'warning'
  571. }).then(function() {
  572. let obj = {
  573. infoId: row.infoId,
  574. orderNum: row.orderNum
  575. }
  576. laboratorySubRelInfoUpdateBySort(obj).then(response => {
  577. self.msgSuccess('修改成功')
  578. self.getList()
  579. })
  580. }).then(() => {
  581. }).catch(() => {
  582. let obj = JSON.parse(JSON.stringify(self.orderNum))
  583. row.orderNum = obj.orderNum
  584. })
  585. }
  586. },
  587. /** 搜索按钮操作 */
  588. handleQuery() {
  589. this.$set(this.queryParams,'page',1);
  590. this.$set(this,'codeList','');
  591. this.$refs['table-box'].clearSelection();
  592. this.getList()
  593. },
  594. /** 重置按钮操作 */
  595. resetQuery() {
  596. this.$set(this, 'queryParams', {
  597. page: 1,
  598. pageSize: 20,
  599. searchValue: '',
  600. deptId: '',
  601. buildId: '',
  602. typeId: '',
  603. levelId: ''
  604. })
  605. this.$set(this,'codeList','');
  606. this.$refs['table-box'].clearSelection();
  607. this.getList()
  608. },
  609. //选中实验室
  610. handleCurrentChange(val) {
  611. this.$refs.indexRightPage.initialize(val);
  612. },
  613. /** 查询实验室列表 */
  614. getList() {
  615. laboratorySubRelInfoList(this.queryParams).then(response => {
  616. this.$set(this,'dataList',response.data.records);
  617. this.$set(this,'total',response.data.total);
  618. if (response.data.records[0]) {
  619. this.$refs['table-box'].setCurrentRow(response.data.records[0])
  620. }
  621. })
  622. },
  623. /** 查询学院列表 */
  624. getDeptDropList() {
  625. getDeptDropList({ deptName: '', level: 2, deptType: 1 }).then(response => {
  626. this.$set(this, 'deptOptions', response.data)
  627. })
  628. },
  629. //查询楼栋楼层
  630. systemBuildingGetTreeList(){
  631. systemBuildingGetTreeList({}).then(response => {
  632. let newList = [];
  633. if (response.data[0]) {
  634. let list = this.forBuildFloor(response.data);
  635. for(let i=0;i<list.length;i++){
  636. if(list[i].buildFloorVoList){
  637. for(let o=0;o<list[i].buildFloorVoList.length;o++){
  638. if(list[i].buildFloorVoList[o].buildFloorVoList){
  639. newList.push(list[i].buildFloorVoList[o])
  640. }
  641. }
  642. }
  643. }
  644. }
  645. this.$set(this, 'buildOptions', newList)
  646. })
  647. },
  648. //处理楼栋楼层数据
  649. forBuildFloor(list){
  650. let self = this;
  651. for(let i=0;i<list.length;i++){
  652. if(list[i].buildFloorVoList){
  653. if(list[i].buildFloorVoList[0]){
  654. list[i].buildFloorVoList = self.forBuildFloor(list[i].buildFloorVoList);
  655. }else{
  656. delete list[i].buildFloorVoList;
  657. }
  658. }else{
  659. delete list[i].buildFloorVoList;
  660. }
  661. }
  662. return list
  663. },
  664. //查询安全分级
  665. laboratoryClassLevelGetList() {
  666. laboratoryClassLevelGetList({}).then(response => {
  667. this.$set(this, 'levelList', response.data)
  668. })
  669. },
  670. //查询安全分类
  671. laboratoryClassTypeGetList() {
  672. laboratoryClassTypeGetList({}).then(response => {
  673. this.$set(this, 'typeList', response.data)
  674. })
  675. },
  676. //****************************************导入功能**************************************
  677. // 多选框选中数据
  678. handleSelectionChange(selection) {
  679. let self = this;
  680. if(selection[40]){
  681. this.$refs['table-box'].clearSelection();
  682. this.$nextTick(()=>{
  683. let ids = [];
  684. for(let i=0;i<selection.length;i++){
  685. if(i<40){
  686. ids.push(selection[i]);
  687. self.$refs['table-box'].toggleRowSelection(selection[i],true);
  688. }
  689. }
  690. self.$set(self,'codeList',ids);
  691. })
  692. this.msgError('最多勾选40条')
  693. }else{
  694. this.$set(this,'codeList',selection.map(item => item));
  695. }
  696. },
  697. /*===记录勾选数据===
  698. 需要再el-table 添加 :row-key="getRowKeys"
  699. 需要在selection 添加 :reserve-selection="true"
  700. */
  701. getRowKeys(row) {
  702. return row.subId
  703. },
  704. },
  705. }
  706. </script>
  707. <style scoped lang="scss">
  708. .subject {
  709. flex:1;
  710. display: flex!important;
  711. flex-direction: column;
  712. overflow: hidden;
  713. box-shadow: none;
  714. margin:0;
  715. .subject-page {
  716. flex:1;
  717. display: flex;
  718. flex-direction: row;
  719. overflow: hidden;
  720. .left-subject-list {
  721. flex: 1;
  722. width: 1143px;
  723. display: flex;
  724. flex-direction: column;
  725. overflow: hidden;
  726. box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2);
  727. border-radius: 10px 10px 10px 10px;
  728. margin: 5px 7px 20px 10px;
  729. .page-content-box {
  730. .table-box{
  731. ::v-deep .el-input--medium .el-input__inner {
  732. height: 26px;
  733. line-height: 26px;
  734. width: 55px;
  735. text-align: center;
  736. padding: 0 10px;
  737. }
  738. }
  739. }
  740. }
  741. }
  742. ::v-deep .el-table__row {
  743. td:nth-child(1) {
  744. padding: 0;
  745. }
  746. }
  747. ::v-deep .el-table__row{
  748. cursor: pointer;
  749. }
  750. }
  751. </style>
  752. <style lang="scss">
  753. .subject-dialog{
  754. .el-dialog__header{
  755. display: none;
  756. }
  757. .el-dialog__body{
  758. height:839px;
  759. position: relative;
  760. padding:0;
  761. margin:0;
  762. overflow: hidden;
  763. .subject-dialog-button-box{
  764. position: absolute;
  765. right:67px;
  766. top:50px;
  767. display: flex;
  768. p{
  769. cursor: pointer;
  770. width: 70px;
  771. height: 30px;
  772. font-size:14px;
  773. text-align: center;
  774. line-height:30px;
  775. }
  776. p:nth-child(1){
  777. border-radius: 6px 6px 6px 6px;
  778. border: 1px solid #E0E0E0;
  779. margin-right:9px;
  780. }
  781. p:nth-child(2){
  782. background: #0045AF;
  783. color: #fff;
  784. border-radius: 6px 6px 6px 6px;
  785. }
  786. }
  787. }
  788. #subject-dialog-print-box{
  789. width:1268px;
  790. height:739px;
  791. /*background-color: red;*/
  792. margin:98px 43px 0;
  793. overflow: hidden;
  794. .subject-dialog-print-big-box{
  795. z-index:5;
  796. width:1228px;
  797. height:699px;
  798. margin:20px;
  799. /*background-color: blue;*/
  800. display: flex;
  801. flex-direction: column;
  802. overflow: hidden;
  803. .subject-dialog-print-top-box{
  804. flex:1;
  805. display: flex;
  806. overflow: hidden;
  807. .subject-dialog-print-top-left-box{
  808. flex:1;
  809. display: flex;
  810. flex-direction: column;
  811. overflow: hidden;
  812. .subject-dialog-print-top-left-top-box{
  813. .subject-dialog-name-box{
  814. height:60px;
  815. display: flex;
  816. overflow: hidden;
  817. background-color: #0045AF;
  818. border-top-right-radius: 10px;
  819. border-bottom-right-radius: 10px;
  820. position: relative;
  821. .title-box-1{
  822. position: absolute;
  823. left:0;
  824. top:-10px;
  825. width:174px;
  826. height:80px;
  827. background-color: #fff;
  828. border-top-right-radius: 100px;
  829. border-bottom-right-radius: 100px;
  830. overflow: hidden;
  831. .title-box-2{
  832. margin-top:10px;
  833. width:170px;
  834. height:60px;
  835. border-radius: 100px;
  836. overflow: hidden;
  837. .title-box-3{
  838. margin:3px;
  839. width: 164px;
  840. height: 54px;
  841. background-color: #fff;
  842. border-radius: 100px;
  843. overflow: hidden;
  844. p{
  845. margin:3px;
  846. width: 158px;
  847. height: 48px;
  848. line-height:48px;
  849. text-align: center;
  850. border-radius: 100px;
  851. overflow: hidden;
  852. font-size:20px;
  853. color:#fff;
  854. }
  855. }
  856. }
  857. }
  858. .title-p{
  859. margin-left:204px;
  860. line-height: 60px;
  861. font-size:30px;
  862. color:#fff;
  863. }
  864. }
  865. .subject-dialog-info-box{
  866. margin-top:12px;
  867. height: 159px;
  868. background: #F5F5F5;
  869. border-radius: 10px 10px 10px 10px;
  870. display: flex;
  871. overflow: hidden;
  872. .subject-dialog-info-left-box{
  873. flex:1;
  874. padding-top:9px;
  875. p{
  876. color:#333;
  877. margin:7px 29px 11px 29px;
  878. height:24px;
  879. line-height:24px;
  880. font-size:18px;
  881. overflow: hidden;
  882. }
  883. }
  884. .subject-dialog-info-right-box{
  885. height:110px;
  886. width:110px;
  887. margin:24px 18px 0 0;
  888. img{
  889. display: block;
  890. height:110px;
  891. width:110px;
  892. }
  893. }
  894. }
  895. }
  896. .subject-dialog-print-top-left-bottom-box{
  897. flex:1;
  898. display: flex;
  899. overflow: hidden;
  900. .subject-dialog-print-top-left-bottom-left-box{
  901. margin-top:17px;
  902. flex:1;
  903. display: flex;
  904. flex-direction: column;
  905. overflow: hidden;
  906. .data-title{
  907. height:60px;
  908. line-height:60px;
  909. color:#fff;
  910. text-align: center;
  911. font-size:24px;
  912. border-top-left-radius: 10px;
  913. border-top-right-radius: 10px;
  914. }
  915. .data-for-text{
  916. flex:1;
  917. border: 2px solid #E0E0E0;
  918. border-top:none;
  919. overflow: hidden;
  920. border-bottom-left-radius: 10px;
  921. border-bottom-right-radius: 10px;
  922. padding:12px 14px;
  923. p{
  924. font-size:12px;
  925. color:#3D3D3D;
  926. line-height:18px;
  927. }
  928. }
  929. .data-for-img{
  930. flex:1;
  931. border: 2px solid #E0E0E0;
  932. border-top:none;
  933. overflow: hidden;
  934. border-bottom-left-radius: 10px;
  935. border-bottom-right-radius: 10px;
  936. img{
  937. display: inline-block;
  938. height:80px;
  939. width:80px;
  940. margin:10px 0 0 6px;
  941. }
  942. }
  943. }
  944. .subject-dialog-print-top-left-bottom-right-box{
  945. margin-left:20px;
  946. margin-top:17px;
  947. flex:1;
  948. display: flex;
  949. flex-direction: column;
  950. overflow: hidden;
  951. .data-title{
  952. height:60px;
  953. line-height:60px;
  954. color:#fff;
  955. text-align: center;
  956. font-size:24px;
  957. border-top-left-radius: 10px;
  958. border-top-right-radius: 10px;
  959. }
  960. .data-for-text{
  961. flex:1;
  962. border: 2px solid #E0E0E0;
  963. border-top:none;
  964. overflow: hidden;
  965. border-bottom-left-radius: 10px;
  966. border-bottom-right-radius: 10px;
  967. padding:12px 14px;
  968. p{
  969. font-size:12px;
  970. color:#3D3D3D;
  971. line-height:18px;
  972. }
  973. }
  974. .data-for-img{
  975. flex:1;
  976. border: 2px solid #E0E0E0;
  977. border-top:none;
  978. overflow: hidden;
  979. border-bottom-left-radius: 10px;
  980. border-bottom-right-radius: 10px;
  981. img{
  982. display: inline-block;
  983. height:80px;
  984. width:80px;
  985. margin:10px 0 0 6px;
  986. }
  987. }
  988. }
  989. }
  990. }
  991. .subject-dialog-print-top-right-box{
  992. margin-left:20px;
  993. width:308px;
  994. display: flex;
  995. flex-direction: column;
  996. overflow: hidden;
  997. .data-title{
  998. height:60px;
  999. line-height:60px;
  1000. color:#fff;
  1001. text-align: center;
  1002. font-size:24px;
  1003. border-top-left-radius: 10px;
  1004. border-top-right-radius: 10px;
  1005. }
  1006. .data-for-text{
  1007. flex:1;
  1008. border: 2px solid #E0E0E0;
  1009. border-top:none;
  1010. overflow: hidden;
  1011. border-bottom-left-radius: 10px;
  1012. border-bottom-right-radius: 10px;
  1013. padding:12px 14px;
  1014. p{
  1015. font-size:12px;
  1016. color:#3D3D3D;
  1017. line-height:18px;
  1018. }
  1019. }
  1020. .data-for-img{
  1021. flex:1;
  1022. border: 2px solid #E0E0E0;
  1023. border-top:none;
  1024. overflow: hidden;
  1025. border-bottom-left-radius: 10px;
  1026. border-bottom-right-radius: 10px;
  1027. img{
  1028. display: inline-block;
  1029. height:80px;
  1030. width:80px;
  1031. margin:16px 0 0 16px;
  1032. }
  1033. }
  1034. }
  1035. }
  1036. .subject-dialog-print-button-box{
  1037. margin-top:20px;
  1038. width: 1228px;
  1039. height: 50px;
  1040. border-radius: 10px 10px 10px 10px;
  1041. padding:0 28px;
  1042. overflow: hidden;
  1043. span{
  1044. font-size:18px;
  1045. line-height:50px;
  1046. margin-right:10px;
  1047. color:#fff;
  1048. }
  1049. }
  1050. }
  1051. }
  1052. }
  1053. </style>