BaseFormMeasure.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. <template>
  2. <a-card :bordered="false" v-show="visible" class="card">
  3. <a-row :gutter="48" style="position:fixed;bottom:150px;z-index:999;display:flex; justify-content: center;width: 90%;">
  4. <a-col :md="48" :sm="48">
  5. <a-space>
  6. <a-button type="primary" @click="save()">保存</a-button>
  7. <a-button
  8. type="primary"
  9. @click="$refs.sbSelect.base(null,{
  10. isMeasure:1,
  11. isSelf:0
  12. })">选择设备</a-button>
  13. <a-button type="default" @click="handleCancel()">返回</a-button>
  14. </a-space>
  15. </a-col>
  16. </a-row>
  17. <div>
  18. <div class="tables">
  19. <div style="text-align:center;padding-bottom:10px;font-size:32px;">时代思康检定表</div>
  20. <div style="display:flex; justify-content: space-between;">
  21. <div> 检定人:{{ username }}</div>
  22. </div>
  23. <table>
  24. <thead border="1px">
  25. <tr>
  26. <th width="100px">序号</th>
  27. <!-- <th width="150px">是否在库</th> -->
  28. <!-- <th width="150px">设备名称</th>
  29. <th width="150px">型号</th>
  30. <th width="150px">出厂编号</th> -->
  31. <!-- <th width="150px">是否是子设备</th>-->
  32. <!-- <th width="150px">设备位置</th> -->
  33. <!-- <th width="350px">选择父设备</th> -->
  34. <th width="150px">设备位号</th>
  35. <th width="150px">检定周期</th>
  36. <th width="150px">检定日期</th>
  37. <th width="150px">下次检定日期</th>
  38. <th width="150px">检定单号</th>
  39. <th width="150px">检定单位</th>
  40. <th width="150px">备注</th>
  41. <th width="150px">操作</th>
  42. </tr>
  43. </thead>
  44. <tbody v-if="ListForm.length>0">
  45. <tr v-for="(item,i) in ListForm" :key="item.id">
  46. <td>{{ i+1 }}</td>
  47. <!-- <td> <a-switch v-model="item.sbStatus" >
  48. <a-icon slot="checkedChildren" type="check" />
  49. <a-icon slot="unCheckedChildren" type="close" />
  50. </a-switch></td> -->
  51. <!-- <td>{{ item.sbName }}</td>
  52. <td>{{ item.sbModel }}</td>
  53. <td><div> {{ item.zzh }}</div></td> -->
  54. <!-- <td>
  55. <a-switch v-model="item.isChild" >
  56. <a-icon slot="checkedChildren" type="check" />
  57. <a-icon slot="unCheckedChildren" type="close" />
  58. </a-switch>
  59. </td>-->
  60. <!-- <td>
  61. <div v-if="item.sbStatus">{{ item.sbPositionName }}</div>
  62. <a-tree-select
  63. v-else
  64. style="width: 150px"
  65. :dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
  66. :treeData="treeData"
  67. :treeNodeFilterProp="'title'"
  68. :showSearch="true"
  69. v-model="item.sbPositionId"
  70. @change="handleSbPosition(item)"
  71. placeholder="请选择"
  72. >
  73. </a-tree-select>
  74. </td>
  75. <td>
  76. <div v-if="!item.sbStatus" style="width:250px">
  77. <a-input
  78. disabled
  79. style="width: 60%"
  80. v-model="item.parentSbName"/>
  81. <a-button type="primary" @click="handleSbSelect(item.sbPositionId,i)">选择</a-button>
  82. </div>
  83. <div v-else>无</div>
  84. </td> -->
  85. <td>
  86. <div > {{ item.sbPositionNo }}</div>
  87. <!-- <div v-if="item.sbStatus"> {{ item.sbPositionNo }}</div> -->
  88. <!-- <div v-else style="width:250px">
  89. <a-input
  90. style="width: 60%"
  91. v-model="item.sbPositionNo"/>
  92. <a-button v-if="item.isChild === 1" type="primary" @click="handleSbNoSelect(item.sbParentId,i)">选择</a-button>
  93. </div> -->
  94. </td>
  95. <td> {{ item.checkPeriod }}
  96. <!-- <a-input v-model="item.checkPeriod" suffix="月" /> -->
  97. </td>
  98. <td>
  99. <a-date-picker
  100. placeholder="日期"
  101. style="width: 150px"
  102. :format="BaseTool.Date.PICKER_NORM_DATE_PATTERN"
  103. v-model="item.lastDate" />
  104. <a-button type="primary" @click="handlePace(item.lastDate,'lastDate')">同步</a-button>
  105. </td>
  106. <td>{{ validity(item.lastDate,item.checkPeriod,item) }}</td>
  107. <!-- <td> <a-date-picker
  108. placeholder="日期"
  109. style="width: 150px"
  110. :format="BaseTool.Date.PICKER_NORM_DATE_PATTERN"
  111. v-model="item.youXiaoDate" />
  112. <a-button type="primary" @click="handlePace(item.youXiaoDate,'youXiaoDate')">同步</a-button></td> -->
  113. <td><a-input style="width: 150px" v-model="item.no" /><a-button type="primary" @click="handlePace(item.no,'no')">同步</a-button></td>
  114. <td><a-input style="width: 150px" v-model="item.requirement" /><a-button type="primary" @click="handlePace(item.requirement,'requirement')">同步</a-button></td>
  115. <td><a-input style="width: 150px" v-model="item.remark" /></td>
  116. <td>
  117. <a-button type="link" @click="uploadImg(item,i)">上传图片</a-button>
  118. <a-button type="link" @click="uploadFile(item,i)">上传文件</a-button>
  119. <a-modal v-model="uploadVisible" title="上传图片" :footer="null" @cancel="uploadVisible = false">
  120. <a-upload
  121. :action="uploadUrl"
  122. list-type="picture-card"
  123. :file-list="defaultApplicationFileList"
  124. @change="handleApplicationFileChange"
  125. @preview="handlePreview"
  126. accept="image/*"
  127. :headers="headers"
  128. >
  129. <div>
  130. <a-icon type="plus" />
  131. <div class="ant-upload-text">
  132. Upload
  133. </div>
  134. </div>
  135. </a-upload>
  136. </a-modal>
  137. <a-modal v-model="uploadFiledVisible" title="上传文件" :footer="null" @cancel="uploadFiledVisible = false">
  138. <a-upload
  139. :action="uploadUrl"
  140. :multiple="true"
  141. :file-list="defaultCheckFileList"
  142. @change="handleCheckFileChange"
  143. :headers="headers"
  144. >
  145. <a-button> <a-icon type="upload" /> 上传 </a-button>
  146. </a-upload>
  147. </a-modal>
  148. <a-modal :visible="previewVisible" :footer="null" @cancel="previewVisible = false" @ok="previewVisible = false">
  149. <img alt="example" style="width: 100%" :src="previewImage" />
  150. </a-modal>
  151. </td>
  152. </tr>
  153. </tbody>
  154. </table>
  155. </div>
  156. </div>
  157. <sb-info-select-modal ref="sbInfoSelectModal" @selected="handleSbSelectd"/>
  158. <sb-position-no-modal ref="sbPositionNoModal" @selected="handleSbNoSelectd"/>
  159. <SbInfoSelectModal2 ref="sbSelect" @selected="handleSelected" />
  160. </a-card>
  161. </template>
  162. <script>
  163. import { getSbPositionTree } from '@/api/sb/position'
  164. import SbInfoSelectModal from '@/views/sb/info/modules/SbInfoSelectModal'
  165. import SbPositionNoModal from '@/views/sb/location/modules/LocationSelectModal'
  166. import { importMeasureInStore } from '@/api/sb/info'
  167. import SbInfoSelectModal2 from './SbInfoSelectModal2.vue'
  168. import { uploadUrl } from '@/api/upms/file'
  169. import Vue from 'vue'
  170. import { ACCESS_TOKEN } from '@/store/mutation-types'
  171. export default {
  172. name: 'BaseFillGatherTask',
  173. components: {
  174. SbInfoSelectModal,
  175. SbInfoSelectModal2,
  176. SbPositionNoModal
  177. },
  178. data () {
  179. return {
  180. uploadUrl: uploadUrl,
  181. defaultApplicationFileList: [],
  182. defaultCheckFileList: [],
  183. checkFileList: [], // 文档
  184. applicationFileList: [],
  185. headers: {
  186. Authorization: 'Bearer ' + Vue.ls.get(ACCESS_TOKEN)
  187. },
  188. visible: false,
  189. username: this.$store.getters.userInfo.username,
  190. uploadVisible: false,
  191. uploadFiledVisible: false,
  192. previewVisible: false,
  193. previewImage: '',
  194. treeData: [],
  195. sbParentOPt: 0,
  196. model: {},
  197. listPage: {
  198. pageNum: 1,
  199. pageSize: 10,
  200. total: 0
  201. },
  202. pagination: {
  203. pageNum: 1,
  204. pageSize: 10,
  205. total: 0
  206. },
  207. imgId: '',
  208. fileId: '',
  209. ListForm: [],
  210. id: '',
  211. updatesInfo: []
  212. // 下拉框map
  213. }
  214. },
  215. props: {
  216. },
  217. created () {
  218. // 下拉框map
  219. },
  220. methods: {
  221. validity (lastDate, checkPeriod, record) {
  222. if (lastDate === '') return ''
  223. lastDate = this.BaseTool.Date.formatter(lastDate, this.BaseTool.Date.PICKER_NORM_DATE_PATTERN).split('-')
  224. lastDate[1] = (parseInt(lastDate[1]) + parseInt(checkPeriod)) % 12
  225. lastDate[0] = +lastDate[0] + Math.floor((parseInt(lastDate[1]) + parseInt(checkPeriod)) / 12)
  226. if (lastDate[1] === 0) {
  227. lastDate[1] = 12
  228. } else if (lastDate[1] > 0 && lastDate[1] < 10) {
  229. lastDate[1] = '0' + lastDate[1]
  230. }
  231. record.youXiaoDate = lastDate.join('-')
  232. return lastDate.join('-')
  233. },
  234. base (record, type) {
  235. this.visible = true
  236. this.model = record
  237. this.type = type
  238. this.ListForm = record.map(item => {
  239. const data = {
  240. sbName: item.name,
  241. sbModel: item.model,
  242. checkPeriod: item.checkPeriod || 0,
  243. isChild: item.isChild,
  244. parentSbName: item.parentSbName,
  245. sbParentId: item.parentId,
  246. sbPositionId: item.positionId,
  247. sbPositionName: item.positionName,
  248. no: '',
  249. lastDate: '',
  250. sbStatus: false,
  251. youXiaoDate: '',
  252. sbPositionNo: item.positionNo,
  253. requirement: '',
  254. remark: '',
  255. name: this.username,
  256. sbId: item.id,
  257. type,
  258. zzh: item.zzh,
  259. checkImgList: [],
  260. checkFileList: []
  261. }
  262. return data
  263. })
  264. getSbPositionTree().then(res => {
  265. this.treeData = res.data
  266. })
  267. },
  268. handleSbPosition (item) {
  269. item.parentSbName = ''
  270. item.sbParentId = ''
  271. },
  272. handleSbSelect (positionId, i) {
  273. if (positionId === '' || positionId === null) {
  274. this.$message.warning('请选择设备位置!')
  275. return
  276. }
  277. this.sbParentOPt = i
  278. this.$refs.sbInfoSelectModal.base({}, { isChild: this.DictCache.VALUE.SB_IS_CHILD.IS_PARENT, positionId })
  279. },
  280. handlePace (val, key) {
  281. if (key === 'lastDate') {
  282. val = this.BaseTool.Date.formatter(val, this.BaseTool.Date.PICKER_NORM_DATE_PATTERN)
  283. }
  284. console.log(this.ListForm, val, key)
  285. this.ListForm.forEach(item => {
  286. item[key] = val
  287. })
  288. },
  289. handleSbNoSelect (sbId, i) {
  290. if (sbId === '' || sbId === null) {
  291. this.$message.warning('请选择父设备!')
  292. return
  293. }
  294. this.sbParentOPt = i
  295. this.$refs.sbPositionNoModal.base({ sbId })
  296. },
  297. handleSbSelectd (keys, rows) {
  298. console.log(keys, rows)
  299. this.ListForm[ this.sbParentOPt ].sbParentId = keys[0]
  300. this.ListForm[ this.sbParentOPt ].parentSbName = rows[0].name
  301. },
  302. handleSbNoSelectd (keys, rows) {
  303. console.log(keys, rows)
  304. // this.ListForm[ this.sbParentOPt ].sbPositionNo = rows[0].no
  305. },
  306. uploadFile (val, i) {
  307. this.uploadFiledVisible = true
  308. this.fileId = i
  309. console.log(val)
  310. this.defaultCheckFileList = this.BaseTool.UPLOAD.transImg(val.checkFileList)
  311. },
  312. uploadImg (val, i) {
  313. this.uploadVisible = true
  314. console.log(val)
  315. this.imgId = i
  316. this.defaultApplicationFileList = this.BaseTool.UPLOAD.transImg(val.checkImgList)
  317. },
  318. getBase64 (file) {
  319. return new Promise((resolve, reject) => {
  320. const reader = new FileReader()
  321. reader.readAsDataURL(file)
  322. reader.onload = () => resolve(reader.result)
  323. reader.onerror = error => reject(error)
  324. })
  325. },
  326. async handlePreview (file) {
  327. if (!file.url && !file.preview) {
  328. file.preview = await this.getBase64(file.originFileObj)
  329. }
  330. this.previewImage = file.url || file.preview
  331. this.previewVisible = true
  332. },
  333. handleApplicationFileChange (info) {
  334. this.defaultApplicationFileList = info.fileList
  335. this.applicationFileList = this.setFileList(info, 11)
  336. this.ListForm[this.imgId].checkImgList = this.applicationFileList
  337. },
  338. handleCheckFileChange (info) {
  339. this.defaultCheckFileList = info.fileList
  340. this.checkFileList = this.setFileList(info, 32)
  341. this.ListForm[this.fileId].checkFileList = this.checkFileList
  342. console.log(this.checkFileList)
  343. },
  344. setFileList (info, type) {
  345. const file = info.file
  346. const fileList = info.fileList
  347. if (file.status === 'done') {
  348. return this.BaseTool.UPLOAD.getUploadFileDTO(fileList, type)
  349. } else if (file.status === 'removed') {
  350. return this.BaseTool.UPLOAD.getUploadFileDTO(fileList, type)
  351. } else if (file.status === 'error') {
  352. this.$message.error('上传失败')
  353. return []
  354. }
  355. },
  356. save () {
  357. let status = false
  358. this.ListForm.forEach(item => {
  359. switch (true) {
  360. case item.sbStatus || (item.requirement === '' && (item.lastDate === '' || item.lastDate === null)) :
  361. break
  362. case item.requirement === '':
  363. this.$message.warning(item.sbName + '的检定单位不能为空!')
  364. status = true
  365. break
  366. case item.lastDate === '' || item.lastDate === null:
  367. this.$message.warning(item.sbName + '的检定日期不能为空!')
  368. status = true
  369. break
  370. case item.youXiaoDate === '' || item.youXiaoDate === null:
  371. this.$message.warning(item.sbName + '的下次检定日期不能为空!')
  372. status = true
  373. break
  374. }
  375. item.lastDate = item.lastDate !== '' && item.lastDate !== null ? this.BaseTool.Date.formatter(item.lastDate, this.BaseTool.Date.PICKER_NORM_DATE_PATTERN) : ''
  376. item.youXiaoDate = item.youXiaoDate !== '' && item.youXiaoDate !== null ? this.BaseTool.Date.formatter(item.youXiaoDate, this.BaseTool.Date.PICKER_NORM_DATE_PATTERN) : ''
  377. item.checkFileList.forEach(item => {
  378. item.id = null
  379. })
  380. item.checkImgList.forEach(item => {
  381. item.id = null
  382. })
  383. })
  384. if (status) return
  385. const params = {
  386. sbMeasureLogDTOList: this.ListForm.filter(item => !(!item.sbStatus && item.requirement === '' && item.lastDate === ''))
  387. }
  388. console.log(params)
  389. importMeasureInStore(params).then(res => {
  390. if (params.sbMeasureLogDTOList.length > 0) {
  391. this.$message.success('检定完成!')
  392. } else {
  393. this.$message.error('数据不完整,检定失败!')
  394. }
  395. this.handleCancel()
  396. })
  397. },
  398. handleSelected (keys, rows) {
  399. rows.forEach((item) => {
  400. if (!this.ListForm.map((sb) => sb.sbId).includes(item.id)) {
  401. const data = {
  402. sbName: item.name,
  403. sbModel: item.model,
  404. checkPeriod: item.checkPeriod || 0,
  405. isChild: item.isChild,
  406. parentSbName: item.parentSbName,
  407. sbParentId: item.parentId,
  408. sbPositionId: item.positionId,
  409. sbPositionName: item.positionName,
  410. no: '',
  411. lastDate: '',
  412. youXiaoDate: '',
  413. sbStatus: false,
  414. sbPositionNo: item.positionNo,
  415. requirement: '',
  416. remark: '',
  417. name: this.username,
  418. sbId: item.id,
  419. type: this.type,
  420. zzh: item.zzh,
  421. checkImgList: [],
  422. checkFileList: []
  423. }
  424. this.ListForm.push(data)
  425. }
  426. })
  427. },
  428. handleCancel () {
  429. this.visible = false
  430. this.ListForm = []
  431. this.$emit('ok')
  432. }
  433. }
  434. }
  435. </script>
  436. <style lang="less" scoped>
  437. .tables{
  438. margin: 20px 0px;
  439. width: 100%;
  440. overflow-x:auto;
  441. table {
  442. min-width:100%;
  443. margin: 0 auto;
  444. border: 1px solid #D6D6D6;
  445. border-collapse: collapse;
  446. font-size: 16px;
  447. font-weight: 400;
  448. table-layout:fixed;
  449. }
  450. th{
  451. background: #fafafa;
  452. font-weight: 500;
  453. }
  454. th,
  455. td {
  456. border: 1px solid #D6D6D6;
  457. text-align: center;
  458. padding: 5px 10px;
  459. white-space: nowrap;
  460. }
  461. }
  462. </style>