smallEquipmentImport.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771
  1. <template>
  2. <el-dialog
  3. :title="labelTitle"
  4. :visible.sync="dialogVisible"
  5. :close-on-click-modal="false"
  6. :close-on-press-escape="false"
  7. :show-close="false"
  8. append-to-body
  9. width="40%"
  10. custom-class="monthly-stat-dialog"
  11. class="dialog"
  12. top="15vh"
  13. @close="closeDialog"
  14. >
  15. <el-alert
  16. title="提示:请先下载导入模板填写设备信息;相关附件可打包为 ZIP 一并上传(非必填),每个类型仅支持上传 1 个文件。"
  17. type="info"
  18. :closable="false"
  19. show-icon
  20. class="import-tip"
  21. />
  22. <el-form
  23. ref="form"
  24. :label-width="formLabelWidth"
  25. :model="paramForm"
  26. class="dialog-form"
  27. @submit.native.prevent
  28. >
  29. <el-form-item label="压缩包:" class="upload-form-item">
  30. <div class="upload-row">
  31. <el-upload
  32. ref="zipUpload"
  33. class="upload-trigger"
  34. action="#"
  35. accept=".zip"
  36. :show-file-list="false"
  37. :file-list="paramForm.zipFileList"
  38. :on-change="handleZipChange"
  39. :on-exceed="handleZipExceed"
  40. :auto-upload="false"
  41. :limit="1"
  42. :multiple="false"
  43. >
  44. <el-button
  45. v-if="!paramForm.zipFile"
  46. class="upload-btn"
  47. type="primary"
  48. icon="el-icon-upload"
  49. style="width: 140px"
  50. >选择ZIP文件</el-button
  51. >
  52. </el-upload>
  53. <div v-if="paramForm.zipFile" class="upload-filename">
  54. <i class="el-icon-document" />
  55. <span :title="paramForm.zipFile.name">{{
  56. paramForm.zipFile.name
  57. }}</span>
  58. <i class="el-icon-close" @click="handleZipRemove" />
  59. </div>
  60. </div>
  61. <div class="el-upload__tip">
  62. 请上传 *.zip 压缩包文件(设备相关附件打包,非必填)
  63. </div>
  64. </el-form-item>
  65. <el-form-item label="Excel文件:" required class="upload-form-item">
  66. <div class="upload-row">
  67. <el-upload
  68. ref="xlsxUpload"
  69. class="upload-trigger"
  70. action="#"
  71. accept=".xlsx,.xls"
  72. :show-file-list="false"
  73. :file-list="paramForm.xlsxFileList"
  74. :on-change="handleXlsxChange"
  75. :on-exceed="handleXlsxExceed"
  76. :auto-upload="false"
  77. :limit="1"
  78. :multiple="false"
  79. >
  80. <el-button
  81. v-if="!paramForm.xlsxFile"
  82. class="upload-btn"
  83. type="primary"
  84. icon="el-icon-upload"
  85. style="width: 140px"
  86. >选择Excel文件</el-button
  87. >
  88. </el-upload>
  89. <div v-if="paramForm.xlsxFile" class="upload-filename">
  90. <i class="el-icon-document" />
  91. <span :title="paramForm.xlsxFile.name">{{
  92. paramForm.xlsxFile.name
  93. }}</span>
  94. <i class="el-icon-close" @click="handleXlsxRemove" />
  95. </div>
  96. </div>
  97. <div class="el-upload__tip">
  98. 请上传 *.xlsx 或 *.xls 格式的设备导入模板文件(必填)
  99. </div>
  100. </el-form-item>
  101. </el-form>
  102. <div slot="footer" class="el-dialog--center">
  103. <ibps-toolbar :actions="toolbars" @action-event="handleActionEvent" />
  104. </div>
  105. </el-dialog>
  106. </template>
  107. <script>
  108. import request from '@/utils/request'
  109. import { uploadFile } from '@/api/platform/file/attachment'
  110. import IbpsImport from '@/plugins/import'
  111. export default {
  112. components: {
  113. IbpsCustomDialog: () =>
  114. import('@/business/platform/data/templaterender/custom-dialog'),
  115. IbpsLinkData: () =>
  116. import('@/business/platform/data/templaterender/link-data')
  117. },
  118. props: {
  119. fields: {
  120. type: Array,
  121. default: () => []
  122. },
  123. visible: {
  124. type: Boolean,
  125. default: false
  126. },
  127. labelTitle: {
  128. type: String,
  129. default: '导入'
  130. }
  131. },
  132. data() {
  133. return {
  134. formLabelWidth: '100px',
  135. level: '',
  136. paramForm: {
  137. zipFile: null,
  138. zipFileList: [],
  139. zipAttachmentId: '',
  140. zipList: [],
  141. xlsxFile: null,
  142. xlsxFileList: [],
  143. xlsxAttachmentId: '',
  144. xlsxList: []
  145. },
  146. dialogVisible: this.visible,
  147. maxHeight: '400px',
  148. title: '导入',
  149. toolbars: [
  150. {
  151. key: 'save',
  152. icon: 'ibps-icon-save',
  153. label: '确定',
  154. type: 'primary'
  155. },
  156. {
  157. key: 'cancel',
  158. icon: 'el-icon-close',
  159. label: '关闭',
  160. type: 'danger'
  161. }
  162. ]
  163. }
  164. },
  165. watch: {
  166. visible: {
  167. handler(val) {
  168. this.dialogVisible = val
  169. if (val) {
  170. this.resetUpload()
  171. }
  172. },
  173. immediate: true
  174. }
  175. },
  176. mounted() {
  177. const level = this.$store.getters.level || {}
  178. this.level = level.second || level.first || ''
  179. // 增加默认值属性
  180. this.fields.forEach((item) => {
  181. if (item.default) {
  182. this.$set(this.paramForm, item.key, item.default)
  183. }
  184. })
  185. },
  186. methods: {
  187. handleActionEvent({ key }) {
  188. switch (key) {
  189. case 'save':
  190. this.handleSave()
  191. break
  192. case 'cancel':
  193. this.closeDialog()
  194. break
  195. default:
  196. break
  197. }
  198. },
  199. handleZipChange(file, fileList) {
  200. const name = (file.name || '').toLowerCase()
  201. if (!name.endsWith('.zip')) {
  202. this.$message.warning('请选择 *.zip 文件进行上传!')
  203. this.clearZipData()
  204. return
  205. }
  206. const latest = fileList.slice(-1)
  207. this.paramForm.zipFileList = latest
  208. this.paramForm.zipFile = latest[0] ? latest[0].raw : null
  209. if (this.paramForm.zipFile) {
  210. this.uploadZipAndUnzip(this.paramForm.zipFile)
  211. }
  212. },
  213. uploadZipAndUnzip(file) {
  214. uploadFile(file, {})
  215. .then((response) => {
  216. const attachmentId = response && response.data ? response.data.id : ''
  217. if (this.$utils.isEmpty(attachmentId)) {
  218. this.$message.error('压缩包上传失败,未获取到附件ID!')
  219. this.clearZipData()
  220. return Promise.reject(new Error('attachmentId empty'))
  221. }
  222. this.paramForm.zipAttachmentId = attachmentId
  223. return request({
  224. url:
  225. '/platform/v3/file/unCalibrationZip?attachmentId=' + attachmentId,
  226. method: 'GET',
  227. isLoading: true
  228. })
  229. })
  230. .then((res) => {
  231. this.paramForm.zipList =
  232. res && res.variables && res.variables.data ? res.variables.data : []
  233. console.log(this.paramForm.zipList, 'this.paramForm.zipList')
  234. this.$message.success('压缩包上传并解析成功!')
  235. })
  236. .catch((err) => {
  237. console.error(err)
  238. this.clearZipData()
  239. })
  240. },
  241. handleZipRemove() {
  242. this.clearZipData()
  243. },
  244. clearZipData() {
  245. this.paramForm.zipFileList = []
  246. this.paramForm.zipFile = null
  247. this.paramForm.zipAttachmentId = ''
  248. this.paramForm.zipList = []
  249. },
  250. handleZipExceed() {
  251. this.$message.warning(
  252. 'ZIP 压缩包仅支持上传 1 个文件,请先删除后再重新选择!'
  253. )
  254. },
  255. handleXlsxChange(file, fileList) {
  256. const name = (file.name || '').toLowerCase()
  257. if (!name.endsWith('.xlsx') && !name.endsWith('.xls')) {
  258. this.$message.warning('请选择 *.xlsx 或 *.xls 文件进行上传!')
  259. this.clearXlsxData()
  260. return
  261. }
  262. const latest = fileList.slice(-1)
  263. this.paramForm.xlsxFileList = latest
  264. this.paramForm.xlsxFile = latest[0] ? latest[0].raw : null
  265. if (this.paramForm.xlsxFile) {
  266. this.uploadXlsx(this.paramForm.xlsxFile)
  267. }
  268. },
  269. // 同 template.handleImport(this.getField("import")) 的字段映射解析
  270. getKeys(data) {
  271. return Array.isArray(data)
  272. ? data.reduce((acc, item) => {
  273. if (item && item.label && item.name) {
  274. acc[item.label] = item.name
  275. }
  276. return acc
  277. }, {})
  278. : {}
  279. },
  280. setValue(data) {
  281. return Object.values(data).reduce((obj, item) => {
  282. obj[item] = ''
  283. return obj
  284. }, {})
  285. },
  286. uploadXlsx(file) {
  287. uploadFile(file, {})
  288. .then((response) => {
  289. const attachmentId = response && response.data ? response.data.id : ''
  290. if (this.$utils.isEmpty(attachmentId)) {
  291. this.$message.error('Excel 上传失败,未获取到附件ID!')
  292. this.clearXlsxData()
  293. return
  294. }
  295. this.paramForm.xlsxAttachmentId = attachmentId
  296. // xlsx 上传成功后调用解析
  297. this.handleImport(this.getField('import'))
  298. })
  299. .catch((err) => {
  300. console.error(err)
  301. this.clearXlsxData()
  302. })
  303. },
  304. handleImport(importFields, options = { raw: false }) {
  305. if (this.$utils.isEmpty(importFields)) {
  306. this.$message.warning('未获取到导入字段配置!')
  307. this.clearXlsxData()
  308. return
  309. }
  310. const file = this.paramForm.xlsxFile
  311. if (this.$utils.isEmpty(file)) {
  312. this.$message.warning('请选择 Excel 文件!')
  313. return
  314. }
  315. const importValue = this.getKeys(importFields)
  316. const formData = this.setValue(importValue)
  317. IbpsImport.xlsx(file, options)
  318. .then(({ results }) => {
  319. const list = []
  320. ;(results || []).forEach((item) => {
  321. const data = JSON.parse(JSON.stringify(formData))
  322. for (const key in item) {
  323. if (importValue[key]) {
  324. data[importValue[key]] = item[key]
  325. }
  326. }
  327. if (data.yuan_she_bei_bian) {
  328. data.yuan_she_bei_bian = String(data.yuan_she_bei_bian).replace(/\s/g, '')
  329. }
  330. if (data.she_bei_ming_chen) {
  331. data.she_bei_ming_chen = String(data.she_bei_ming_chen).replace(/\s/g, '')
  332. }
  333. list.push(data)
  334. })
  335. console.log(list, 'llllll')
  336. this.paramForm.xlsxList = list
  337. this.$message.success(`Excel 解析成功,共 ${list.length} 条数据`)
  338. })
  339. .catch((err) => {
  340. console.error(err)
  341. this.$message.error('Excel 解析失败,请检查文件格式!')
  342. this.clearXlsxData()
  343. })
  344. },
  345. handleXlsxRemove() {
  346. this.clearXlsxData()
  347. },
  348. clearXlsxData() {
  349. this.paramForm.xlsxFileList = []
  350. this.paramForm.xlsxFile = null
  351. this.paramForm.xlsxAttachmentId = ''
  352. this.paramForm.xlsxList = []
  353. },
  354. handleXlsxExceed() {
  355. this.$message.warning(
  356. 'Excel 文件仅支持上传 1 个文件,请先删除后再重新选择!'
  357. )
  358. },
  359. resetUpload() {
  360. this.clearZipData()
  361. this.clearXlsxData()
  362. },
  363. /**
  364. * 根据 xlsx 行的 fu_jian_ 匹配 zipList 中的 name,将对应 id 用英文逗号拼接写入 bei_zhu_
  365. */
  366. bindZipIdsToXlsxList() {
  367. const xlsxList = this.paramForm.xlsxList || []
  368. const zipList = this.paramForm.zipList || []
  369. if (this.$utils.isEmpty(xlsxList) || this.$utils.isEmpty(zipList)) {
  370. return
  371. }
  372. xlsxList.forEach((row) => {
  373. const fuJian = row.fu_jian_
  374. if (this.$utils.isEmpty(fuJian)) {
  375. this.$set(row, 'bei_zhu_', '')
  376. return
  377. }
  378. const fileNames = String(fuJian)
  379. .split(/[,,;;|、\s]+/)
  380. .map((name) => name.trim())
  381. .filter((name) => name)
  382. const ids = []
  383. zipList.forEach((zipItem) => {
  384. const zipName =
  385. zipItem && zipItem.name ? String(zipItem.name).trim() : ''
  386. if (!zipName) return
  387. const matched = fileNames.some(
  388. (name) =>
  389. name === zipName ||
  390. fuJian.indexOf(zipName) !== -1 ||
  391. zipName.indexOf(name) !== -1
  392. )
  393. if (matched && zipItem.id != null && zipItem.id !== '') {
  394. ids.push(zipItem.id)
  395. }
  396. })
  397. this.$set(row, 'bei_zhu_', ids.join(','))
  398. })
  399. },
  400. handleSave() {
  401. if (
  402. this.fields.some(
  403. (i) =>
  404. i.required !== false && this.$utils.isEmpty(this.paramForm[i.key])
  405. )
  406. ) {
  407. return this.$message.warning('请填写所有必填项!')
  408. }
  409. // zip 非必填:若已选择则必须上传成功
  410. if (
  411. this.$utils.isNotEmpty(this.paramForm.zipFile) &&
  412. this.$utils.isEmpty(this.paramForm.zipAttachmentId)
  413. ) {
  414. return this.$message.warning('压缩包尚未上传成功,请重新上传或清除!')
  415. }
  416. if (this.$utils.isEmpty(this.paramForm.xlsxFile)) {
  417. return this.$message.warning('请上传 Excel 导入文件!')
  418. }
  419. if (this.$utils.isEmpty(this.paramForm.xlsxAttachmentId)) {
  420. return this.$message.warning('Excel 尚未上传成功,请重新上传!')
  421. }
  422. if (this.$utils.isEmpty(this.paramForm.xlsxList)) {
  423. return this.$message.warning('Excel 尚未解析出数据,请重新上传!')
  424. }
  425. if (this.$utils.isNotEmpty(this.paramForm.zipList)) {
  426. this.bindZipIdsToXlsxList()
  427. }
  428. this.handleImportData(() => {
  429. this.closeDialog()
  430. }, this.paramForm.xlsxList)
  431. },
  432. closeDialog() {
  433. this.resetUpload()
  434. this.$emit('close', false)
  435. },
  436. getField(type = 'export') {
  437. const fields = {
  438. bian_zhi_bu_men_: '部门',
  439. she_bei_ming_chen: '设备名称',
  440. yuan_she_bei_bian: '设备编号',
  441. she_bei_lei_xing_: '设备类型',
  442. chang_jia_pin_pai: '厂家品牌',
  443. xing_hao_gui_ge_: '规格型号',
  444. jian_ding_dan_wei: '检定/校准单位',
  445. yi_jian_xiao_ri_q: '上次检定/校准日期',
  446. shi_shi_ri_qi_: '实施日期',
  447. jian_ding_zhou_qi: '检定/校准周期(月)',
  448. chu_chang_bian_ha: '检定/校准有效期至',
  449. fu_ze_ren_: '负责人',
  450. jing_ban_ren_: '经办人',
  451. zhun_que_du_: '证书编号',
  452. fu_jian_: '附件名称'
  453. }
  454. const fieldMap = {
  455. export: [
  456. 'bian_zhi_bu_men_',
  457. 'she_bei_ming_chen',
  458. 'yuan_she_bei_bian',
  459. 'she_bei_lei_xing_',
  460. 'chang_jia_pin_pai',
  461. 'xing_hao_gui_ge_',
  462. 'jian_ding_dan_wei',
  463. 'yi_jian_xiao_ri_q',
  464. 'shi_shi_ri_qi_',
  465. 'jian_ding_zhou_qi',
  466. 'chu_chang_bian_ha',
  467. 'fu_ze_ren_',
  468. 'jing_ban_ren_',
  469. 'zhun_que_du_',
  470. 'fu_jian_'
  471. ],
  472. import: [
  473. 'bian_zhi_bu_men_',
  474. 'she_bei_ming_chen',
  475. 'yuan_she_bei_bian',
  476. 'jian_ding_dan_wei',
  477. 'yi_jian_xiao_ri_q',
  478. 'shi_shi_ri_qi_',
  479. 'jian_ding_zhou_qi',
  480. 'jing_ban_ren_',
  481. 'zhun_que_du_',
  482. 'fu_jian_'
  483. ]
  484. }
  485. const requireField = [
  486. 'bian_zhi_bu_men_',
  487. 'she_bei_ming_chen',
  488. 'yuan_she_bei_bian',
  489. 'jian_ding_dan_wei',
  490. 'shi_shi_ri_qi_',
  491. 'jian_ding_zhou_qi',
  492. 'jing_ban_ren_'
  493. ]
  494. return fieldMap[type].map((i) => ({
  495. field_name: i,
  496. //label: fields[i] + (type === 'import' ? requireField.includes(i) ? '(必填)' : '' : ''),
  497. label: fields[i],
  498. name: i
  499. }))
  500. },
  501. getTransformData(type = 'user') {
  502. const keyMap = {
  503. user: 'sbjdxzjlryzh',
  504. supplier: 'sbjdxzjlgyszh',
  505. device: 'sbjdxzjlsbzh'
  506. }
  507. const paramMap = {
  508. user: [null],
  509. supplier: [this.level],
  510. device: [this.level]
  511. }
  512. return new Promise((resolve, reject) => {
  513. this.$common
  514. .request('query', {
  515. key: keyMap[type],
  516. params: paramMap[type]
  517. })
  518. .then((res) => {
  519. resolve(res.variables.data || [])
  520. })
  521. .catch((error) => {
  522. reject(error)
  523. })
  524. })
  525. },
  526. async handleImportData(callback, data) {
  527. const userInfo = await this.getTransformData()
  528. const deviceList = await this.getTransformData('device')
  529. const supplierList = await this.getTransformData('supplier')
  530. const defaultData = {
  531. bian_zhi_shi_jian: this.$common.getDateNow(16),
  532. di_dian_: this.level,
  533. marks_: 'record',
  534. shi_fou_guo_shen_: '已完成',
  535. bian_zhi_ren_: this.$store.getters?.userId
  536. }
  537. const list = data.map((item) => {
  538. const device =
  539. deviceList.find(
  540. (d) => d.yuan_she_bei_bian === item.yuan_she_bei_bian
  541. ) || {}
  542. const userId = this.dataTransfer(
  543. userInfo,
  544. item.jing_ban_ren_,
  545. 'name_',
  546. 'id_'
  547. )
  548. const deptList = this.$store.getters?.deptList || []
  549. const { fu_jian_, ...restItem } = item
  550. return {
  551. ...defaultData,
  552. ...restItem,
  553. bian_zhi_bu_men_: this.dataTransfer(
  554. deptList,
  555. item.bian_zhi_bu_men_,
  556. 'positionName',
  557. 'positionId'
  558. ),
  559. bian_zhi_ren_: userId,
  560. jing_ban_ren_: userId,
  561. yi_jian_xiao_ri_q: item.yi_jian_xiao_ri_q?.trim(),
  562. shi_shi_ri_qi_: item.shi_shi_ri_qi_?.trim(),
  563. dan_wei_id: this.dataTransfer(
  564. supplierList,
  565. item.jian_ding_dan_wei,
  566. 'gong_ying_shang_m',
  567. 'id_'
  568. ),
  569. // 计算检定校准有效期至
  570. you_xiao_qi_zhi_: this.getExpireDate(
  571. item.shi_shi_ri_qi_,
  572. item.jian_ding_zhou_qi
  573. ),
  574. chu_chang_bian_ha: this.getExpireDate(
  575. item.shi_shi_ri_qi_,
  576. item.jian_ding_zhou_qi
  577. ),
  578. // 设备档案-ID
  579. she_bei_bian_hao_: device.id_ || '',
  580. // 设备档案-设备识别号
  581. bian_hao_zhong_we: device.she_bei_shi_bie_h || '',
  582. // 设备档案-设备类型
  583. she_bei_lei_xing_: device.she_bei_lei_xing_ || '',
  584. // 设备档案-规格型号
  585. xing_hao_gui_ge_: device.gui_ge_xing_hao_ || '',
  586. // 设备档案-厂商
  587. chang_jia_pin_pai: device.chang_shang_ || '',
  588. // 设备档案-保管人
  589. fu_ze_ren_: device.guan_li_ren_ || '',
  590. // 设备档案-检定校准参数
  591. can_shu_: device.jian_ding_xiao_ || '',
  592. // 设备档案-测量工作范围
  593. liang_cheng_: device.ce_liang_gong_zuo || '',
  594. // 设备档案-修正因子
  595. xiu_zheng_yin_zi_: device.xiu_zheng_zhi_xiu || '',
  596. // 附件ID(zip 匹配结果优先)
  597. bei_zhu_: item.bei_zhu_ || device.bei_zhu_ || '',
  598. shu_ju_lai_yuan_: device.id_
  599. ? 'importAssociation'
  600. : 'importNotAssociation'
  601. }
  602. })
  603. console.log('处理后导入数据:\n', list)
  604. // 数据校验
  605. let index = 0
  606. let isError = false
  607. let errorMsg = ''
  608. for (const item of list) {
  609. index++
  610. if (!item.bian_zhi_bu_men_) {
  611. isError = true
  612. errorMsg = `第【${index}】行,部门信息无法匹配系统数据,请检查!`
  613. break
  614. }
  615. if (
  616. !item.she_bei_bian_hao_ &&
  617. !this.$utils.isNotEmpty(this.paramForm.zipList)
  618. ) {
  619. isError = true
  620. errorMsg = `第【${index}】行,设备编号【${item.yuan_she_bei_bian}】无法匹配系统数据,请检查!`
  621. break
  622. }
  623. if (!this.isValidDate(item.yi_jian_xiao_ri_q)) {
  624. isError = true
  625. errorMsg = `第【${index}】行,上次检定/校准日期格式错误,请严格按【YYYY-MM-DD】日期格式填写!`
  626. break
  627. }
  628. if (!this.isValidDate(item.shi_shi_ri_qi_)) {
  629. isError = true
  630. errorMsg = `第【${index}】行,实施日期格式错误,请严格按【YYYY-MM-DD】日期格式填写!`
  631. break
  632. }
  633. if (!item.chu_chang_bian_ha) {
  634. isError = true
  635. errorMsg = `第【${index}】行,实施日期或检定校准周期错误,请检查!`
  636. break
  637. }
  638. if (!item.jing_ban_ren_) {
  639. isError = true
  640. errorMsg = `第【${index}】行,经办人信息无法匹配系统数据,请检查!`
  641. break
  642. }
  643. }
  644. if (isError) {
  645. return this.$message.warning(errorMsg)
  646. }
  647. const params = {
  648. tableName: 't_mjsbjdxzjhzb',
  649. paramWhere: list
  650. }
  651. this.$common.request('add', params).then(() => {
  652. this.$message.success('导入成功')
  653. if (typeof callback === 'function') {
  654. callback(list)
  655. }
  656. this.$emit('confirm', this.paramForm)
  657. })
  658. },
  659. dataTransfer(dataset, data, from = 'id_', to = 'name_') {
  660. const list = data ? data.split(',') : []
  661. const names = list.map((item) => {
  662. const temp = dataset.find((i) => i[from] === item.trim())
  663. return temp ? temp[to] : ''
  664. })
  665. return names.filter((i) => i).join(',')
  666. },
  667. getExpireDate(date, cycle) {
  668. if (
  669. this.$common.Utils.isEmpty(date) ||
  670. this.$common.Utils.isEmpty(cycle)
  671. ) {
  672. return null
  673. }
  674. // 获取指定周期后的前一天
  675. const expiredDate = this.$common.getFormatDate(
  676. 'string',
  677. 10,
  678. this.$common.getDate('month', parseInt(cycle), date)
  679. )
  680. return this.$common.getFormatDate(
  681. 'string',
  682. 10,
  683. this.$common.getDate('day', -1, expiredDate)
  684. )
  685. },
  686. isValidDate(dateString) {
  687. const regex =
  688. /^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$/
  689. return regex.test(dateString)
  690. }
  691. }
  692. }
  693. </script>
  694. <style lang="scss" scoped>
  695. .dialog-form {
  696. padding: 20px;
  697. ::v-deep {
  698. .el-input {
  699. width: calc(100% - 100px);
  700. }
  701. .el-select {
  702. width: 100%;
  703. }
  704. .el-range-editor--small.el-input__inner {
  705. width: calc(100% - 100px);
  706. }
  707. .upload-form-item {
  708. .el-form-item__content {
  709. line-height: 32px;
  710. }
  711. }
  712. }
  713. .upload-row {
  714. display: flex;
  715. align-items: center;
  716. min-height: 32px;
  717. }
  718. .upload-trigger {
  719. display: inline-block;
  720. }
  721. .upload-filename {
  722. display: inline-flex;
  723. align-items: center;
  724. max-width: 100%;
  725. color: #606266;
  726. .el-icon-document {
  727. margin-right: 6px;
  728. color: #909399;
  729. }
  730. span {
  731. max-width: 280px;
  732. overflow: hidden;
  733. text-overflow: ellipsis;
  734. white-space: nowrap;
  735. }
  736. .el-icon-close {
  737. margin-left: 8px;
  738. cursor: pointer;
  739. color: #909399;
  740. &:hover {
  741. color: #f56c6c;
  742. }
  743. }
  744. }
  745. .el-upload__tip {
  746. margin-top: 4px;
  747. line-height: 1.4;
  748. }
  749. }
  750. .import-tip {
  751. }
  752. .toolbar {
  753. text-align: right;
  754. }
  755. </style>
  756. <style lang="scss">
  757. .monthly-stat-dialog {
  758. .upload-btn.el-button {
  759. width: 140px !important;
  760. box-sizing: border-box;
  761. }
  762. }
  763. </style>