uploadCost.vue 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828
  1. <template>
  2. <div class="uploadCost">
  3. <el-dialog
  4. v-loading="loading"
  5. :before-close="closeUpload"
  6. :close-on-click-modal="false"
  7. :close-on-press-escape="false"
  8. :title="importTitle"
  9. :visible.sync="dialogVisible"
  10. class="statistic_base"
  11. :append-to-body="true"
  12. :modal-append-to-body="true"
  13. custom-class="tagdialog"
  14. width="50%"
  15. >
  16. <!-- :title="isImport?'导入结果':'批量导入'"-->
  17. <div v-if="!isImport">
  18. <!-- <p v-for="(item, index) in uploadTitle" :key="index" class="uploadtitle">-->
  19. <!-- {{ item }}-->
  20. <!-- </p>-->
  21. <el-card style="padding-top: 10px;padding-bottom: 10px">
  22. <div style="width: 50%;float:left;">
  23. <p class="uploadtitle txtcenter">1.下载模板按要求填写</p>
  24. <img class="mtmb16 mgauto" src="@/assets/excelicon.png" width="50px">
  25. <div style="width: 100%">
  26. <el-button class="mtmb16 mgauto" size="small" type="primary" @click="downloadTemplate()">下载模板
  27. </el-button>
  28. </div>
  29. </div>
  30. <div style="width: 50%;float:left;">
  31. <p class="uploadtitle txtcenter">2.上传填写好的文件</p>
  32. <img class="mtmb16 mgauto" src="@/assets/excelicon.png" width="50px">
  33. <div class="mgauto2">
  34. <el-upload
  35. :file-list="fileUrlList"
  36. :http-request="uploadFile"
  37. :limit="1"
  38. accept=".xlsx"
  39. action="#"
  40. >
  41. <el-button class="mtmb16" size="small" style="margin-top: 0;height: 33px" type="primary">新增上传</el-button>
  42. <div slot="file" slot-scope="{file}">
  43. <a :href="file.url">{{ file.name }}</a>
  44. <span class="el-upload-list__item-actions">
  45. <i class="el-icon-delete" @click="handlePictureRemove(file,fileUrlList)" />
  46. </span>
  47. </div>
  48. </el-upload>
  49. </div>
  50. </div>
  51. </el-card>
  52. </div>
  53. <div v-if="isImport" style="margin:10px">
  54. <p>导入成功 <span>{{ successCount }} 条</span> ,失败 <span>{{ errorCount }}</span> 条 </p>
  55. <p>您可以下载失败记录,修改后重新上传。以下标红为校验失败项</p>
  56. <el-table
  57. :data="tableData"
  58. style="width: 100%;"
  59. >
  60. <el-table-column align="center" label="楼盘/小区名称" prop="groupName">
  61. <template v-slot="scope">
  62. <span>{{ scope.row.groupNameStr }}</span>
  63. </template>
  64. </el-table-column>
  65. <el-table-column align="center" label="分期名称" prop="discName">
  66. <template v-slot="scope">
  67. <span>{{ scope.row.discNameStr }}</span>
  68. </template>
  69. </el-table-column>
  70. <el-table-column align="center" label="单元/楼栋号" prop="buildNum">
  71. <template v-slot="scope">
  72. <span>{{ scope.row.buildNumStr }}</span>
  73. </template>
  74. </el-table-column>
  75. <el-table-column align="center" label="户室号" prop="roomNo">
  76. <template v-slot="scope">
  77. <span>{{ scope.row.roomNoStr }}</span>
  78. </template>
  79. </el-table-column>
  80. <el-table-column align="center" label="异常原因" prop="reason">
  81. <template v-slot="scope">
  82. <span style="color: red">{{ scope.row.reason }}</span>
  83. </template>
  84. </el-table-column>
  85. </el-table>
  86. </div>
  87. <span slot="footer" class="dialog-footer">
  88. <el-button @click="closeUpload()">取 消</el-button>
  89. <el-button
  90. v-if="!isImport"
  91. :disabled="fileUrlList.length===0"
  92. type="primary"
  93. class="ch-button-else"
  94. @click="importFile()"
  95. >导入</el-button>
  96. <el-button
  97. v-if="isImport"
  98. type="primary"
  99. :loading="excelFlag"
  100. @click="exportError()"
  101. >
  102. 下载失败记录
  103. </el-button>
  104. </span>
  105. </el-dialog>
  106. </div>
  107. </template>
  108. <script>
  109. // import XLSX from 'xlsx'
  110. // import XLSXStyle from 'xlsx-style-fixedver'
  111. import constant from '@/static/utils/constant'
  112. const XLSX = require('xlsx')
  113. const XLSXStyle = require('xlsx-style-fixedver')
  114. import axios from 'axios'
  115. import qs from 'qs'
  116. const defaultTitle = '批量导入'
  117. export default {
  118. props: {
  119. // 弹框状态
  120. dialogVisible: { type: Boolean, default: false },
  121. // 类型
  122. importType: { type: String, default: '' },
  123. // 上传说明
  124. uploadTitle: { type: Array, default: () => ([]) },
  125. // 名称
  126. importTitle: { type: String, default: '' }
  127. },
  128. data() {
  129. return {
  130. fileUrlList: [],
  131. tableData: [],
  132. title: defaultTitle.repeat(1),
  133. loading: false,
  134. isImport: false,
  135. file: null,
  136. successCount: 0,
  137. errorCount: '',
  138. excelFlag: false
  139. }
  140. },
  141. methods: {
  142. importFile() {
  143. if (this.importType === 'groupInsert') {
  144. this.importGroup()
  145. }
  146. if (this.importType === 'FQInsert') {
  147. this.importFQ()
  148. }
  149. if (this.importType === 'buildInsert') {
  150. this.importBuild()
  151. }
  152. if (this.importType === 'roomInsert') {
  153. this.importRoom()
  154. }
  155. },
  156. importGroup() {
  157. this.loading = true
  158. this.$axios({
  159. headers: {
  160. 'Content-Type': 'multipart/form-data'
  161. },
  162. method: 'post',
  163. url: this.$constant.BASE_URI + '/ParkInfoController/handleImport',
  164. data: this.file
  165. }).then((res) => {
  166. this.loading = false
  167. if (res.data.code === 200) {
  168. this.$message({
  169. message: '上传成功',
  170. type: 'success'
  171. })
  172. // this.$emit('cancelUpload', true)
  173. this.successCount = res.data.data.successCount
  174. this.errorCount = res.data.data.errorCount
  175. res.data.data.errorList.forEach(item => {
  176. const json = this.getItemJson(item)
  177. this.tableData.push(json)
  178. })
  179. this.isImport = true
  180. console.log('上传成功....')
  181. } else {
  182. this.$message({
  183. message: res.data.msg,
  184. type: 'error'
  185. })
  186. }
  187. }).catch((err, x) => {
  188. console.log('biz user list error', err, x)
  189. })
  190. },
  191. importFQ() {
  192. this.tableData = []
  193. this.loading = true
  194. this.$axios({
  195. headers: {
  196. 'Content-Type': 'multipart/form-data'
  197. },
  198. method: 'post',
  199. url: this.$constant.BASE_URI + '/ParkFloorDiscController/handleImport',
  200. data: this.file
  201. }).then((res) => {
  202. this.loading = false
  203. if (res.data.code === 200) {
  204. this.$message({
  205. message: '上传成功',
  206. type: 'success'
  207. })
  208. this.successCount = res.data.data.successCount
  209. this.errorCount = res.data.data.errorCount
  210. res.data.data.errorList.forEach(item => {
  211. const json = this.getItemJson(item)
  212. this.tableData.push(json)
  213. })
  214. this.isImport = true
  215. } else {
  216. this.$message({
  217. message: res.data.msg,
  218. type: 'error'
  219. })
  220. }
  221. }).catch((err, x) => {
  222. console.log('biz user list error', err, x)
  223. })
  224. },
  225. importBuild() {
  226. this.loading = true
  227. this.$axios({
  228. headers: {
  229. 'Content-Type': 'multipart/form-data'
  230. },
  231. method: 'post',
  232. url: this.$constant.BASE_URI + '/MnpBuildingController/handleImport',
  233. data: this.file
  234. }).then((res) => {
  235. this.loading = false
  236. if (res.data.code === 200) {
  237. this.$message({
  238. message: '上传成功',
  239. type: 'success'
  240. })
  241. // this.$emit('cancelUpload', true)
  242. this.successCount = res.data.data.successCount
  243. this.errorCount = res.data.data.errorCount
  244. res.data.data.errorList.forEach(item => {
  245. const json = this.getItemJson(item)
  246. this.tableData.push(json)
  247. })
  248. this.isImport = true
  249. console.log('上传成功....')
  250. } else {
  251. this.$message({
  252. message: res.data.msg,
  253. type: 'error'
  254. })
  255. }
  256. }).catch((err, x) => {
  257. console.log('biz user list error', err, x)
  258. })
  259. },
  260. importRoom() {
  261. this.loading = true
  262. this.$axios({
  263. headers: {
  264. 'Content-Type': 'multipart/form-data'
  265. },
  266. method: 'post',
  267. url: this.$constant.BASE_URI + '/ParkRoomController/handleImport',
  268. data: this.file
  269. }).then((res) => {
  270. this.loading = false
  271. if (res.data.code === 200) {
  272. this.$message({
  273. message: '上传成功',
  274. type: 'success'
  275. })
  276. // this.$emit('cancelUpload', true)
  277. this.successCount = res.data.data.successCount
  278. this.errorCount = res.data.data.errorCount
  279. res.data.data.errorList.forEach(item => {
  280. const json = this.getItemJson(item)
  281. this.tableData.push(json)
  282. })
  283. this.isImport = true
  284. console.log('上传成功....')
  285. } else {
  286. this.$message({
  287. message: res.data.msg,
  288. type: 'error'
  289. })
  290. }
  291. }).catch((err, x) => {
  292. console.log('biz user list error', err, x)
  293. })
  294. },
  295. closeUpload() {
  296. // 关闭弹窗
  297. this.$emit('cancelUpload')
  298. },
  299. uploadFile(param) {
  300. const formParam = new FormData()
  301. formParam.append('file', param.file)
  302. this.file = formParam
  303. this.fileUrlList.push({ name: param.file.name })
  304. },
  305. handlePictureRemove(file, fileUrlList) {
  306. const index = fileUrlList.indexOf(file)
  307. fileUrlList.splice(index, 1)
  308. this.file = null
  309. },
  310. exportError() {
  311. if (this.importType === 'groupInsert') {
  312. this.exportErrorGroup()
  313. }
  314. if (this.importType === 'FQInsert') {
  315. this.exportErrorFQ()
  316. }
  317. if (this.importType === 'buildInsert') {
  318. this.exportErrorBuild()
  319. }
  320. if (this.importType === 'roomInsert') {
  321. this.exportErrorRoom()
  322. }
  323. },
  324. exportErrorGroup() {
  325. const _this = this
  326. _this.excelFlag = true
  327. if (!this.tableData.length) {
  328. this.$message.error('失败记录为空!')
  329. return
  330. }
  331. axios({
  332. headers: {
  333. 'MVVM-Key': String(new Date().getTime()),
  334. xx: 'anything'
  335. },
  336. method: 'post',
  337. url: constant.BASE_URI + '/ParkInfoController/errorListExport',
  338. responseType: 'blob',
  339. data: this.tableData
  340. }).then(res => {
  341. this.downloadExcel(res.data, '失败记录.xlsx')
  342. _this.excelFlag = false
  343. }).catch((err) => {
  344. console.log(err)
  345. _this.excelFlag = false
  346. })
  347. },
  348. exportErrorFQ() {
  349. const _this = this
  350. _this.excelFlag = true
  351. if (!this.tableData.length) {
  352. this.$message.error('失败记录为空!')
  353. return
  354. }
  355. axios({
  356. headers: {
  357. 'MVVM-Key': String(new Date().getTime()),
  358. xx: 'anything'
  359. },
  360. method: 'post',
  361. url: constant.BASE_URI + '/ParkFloorDiscController/errorListExport',
  362. responseType: 'blob',
  363. data: this.tableData
  364. }).then(res => {
  365. this.downloadExcel(res.data, '失败记录.xlsx')
  366. _this.excelFlag = false
  367. }).catch((err) => {
  368. console.log(err)
  369. _this.excelFlag = false
  370. })
  371. },
  372. exportErrorBuild() {
  373. const _this = this
  374. _this.excelFlag = true
  375. if (!this.tableData.length) {
  376. this.$message.error('失败记录为空!')
  377. return
  378. }
  379. axios({
  380. headers: {
  381. 'MVVM-Key': String(new Date().getTime()),
  382. xx: 'anything'
  383. },
  384. method: 'post',
  385. url: constant.BASE_URI + '/MnpBuildingController/errorListExport',
  386. responseType: 'blob',
  387. data: this.tableData
  388. }).then(res => {
  389. this.downloadExcel(res.data, '失败记录.xlsx')
  390. _this.excelFlag = false
  391. }).catch((err) => {
  392. console.log(err)
  393. _this.excelFlag = false
  394. })
  395. },
  396. exportErrorRoom() {
  397. const _this = this
  398. _this.excelFlag = true
  399. if (!this.tableData.length) {
  400. this.$message.error('失败记录为空!')
  401. return
  402. }
  403. axios({
  404. headers: {
  405. 'MVVM-Key': String(new Date().getTime()),
  406. xx: 'anything'
  407. },
  408. method: 'post',
  409. url: constant.BASE_URI + '/ParkRoomController/errorListExport',
  410. responseType: 'blob',
  411. data: this.tableData
  412. }).then(res => {
  413. this.downloadExcel(res.data, '失败记录.xlsx')
  414. _this.excelFlag = false
  415. }).catch((err) => {
  416. console.log(err)
  417. _this.excelFlag = false
  418. })
  419. },
  420. s2ab(s) {
  421. var cuf
  422. var i
  423. if (typeof ArrayBuffer !== 'undefined') {
  424. cuf = new ArrayBuffer(s.length)
  425. var view = new Uint8Array(cuf)
  426. for (i = 0; i !== s.length; i++) {
  427. view[i] = s.charCodeAt(i) & 0xFF
  428. }
  429. return cuf
  430. } else {
  431. cuf = new Array(s.length)
  432. for (i = 0; i !== s.length; ++i) {
  433. cuf[i] = s.charCodeAt(i) & 0xFF
  434. }
  435. return cuf
  436. }
  437. },
  438. downloadTemplate() {
  439. if (this.importType === 'groupInsert') {
  440. this.downloadGroupTemplate()
  441. }
  442. if (this.importType === 'FQInsert') {
  443. this.downloadFQTemplate()
  444. }
  445. if (this.importType === 'buildInsert') {
  446. this.downloadBuildTemplate()
  447. }
  448. if (this.importType === 'roomInsert') {
  449. this.downloadRoomTemplate()
  450. }
  451. },
  452. downloadGroupTemplate() {
  453. // const outData = []
  454. // const title = []
  455. // title.push('楼盘/小区名称')
  456. // title.push('性质')
  457. // title.push('预销售许可证编号')
  458. // title.push('开发公司')
  459. // title.push('总建筑面积(㎡)')
  460. // title.push('总用地面积(㎡)')
  461. // title.push('立项批文')
  462. // title.push('工程规划许可证')
  463. // title.push('施工许可证')
  464. // title.push('土地证号')
  465. // title.push('用地许可证号')
  466. // title.push('容积率')
  467. // title.push('绿化率')
  468. // title.push('标准单价')
  469. // title.push('超标单价')
  470. // title.push('楼盘面积测绘状态')
  471. // title.push('楼盘销售状态')
  472. // title.push('行政区划')
  473. // title.push('详细地址')
  474. // title.push('备注')
  475. //
  476. // outData.push(title)
  477. // const outSize = []
  478. // title.forEach(item => {
  479. // if (item.length > 4) {
  480. // outSize.push({
  481. // wch: 30
  482. // })
  483. // } else {
  484. // outSize.push({
  485. // wch: 15
  486. // })
  487. // }
  488. // })
  489. // let fileName = '模板'
  490. // if (this.importTitle.includes('批量导入')) {
  491. // fileName = '楼盘导入模版'
  492. // }
  493. // // if (this.importTitle.includes('批量更新')) {
  494. // // fileName = '更新模板'
  495. // // }
  496. // const ws = XLSX.utils.aoa_to_sheet(outData)
  497. // ws['!cols'] = outSize
  498. // ws['!rows'] = []
  499. // const wb = XLSX.utils.book_new()
  500. // XLSX.utils.book_append_sheet(wb, ws, fileName)
  501. // const tmpDown = new Blob([
  502. // this.s2ab(
  503. // XLSXStyle.write(wb, {
  504. // bookType: 'xlsx',
  505. // bookSST: true,
  506. // type: 'binary',
  507. // cellStyles: true
  508. // })
  509. // )
  510. // ])
  511. // const elink = document.createElement('a')
  512. // elink.download = decodeURIComponent(fileName + '.xlsx')
  513. // elink.style.display = 'none'
  514. // elink.href = URL.createObjectURL(tmpDown)
  515. // document.body.appendChild(elink)
  516. // elink.click()
  517. // URL.revokeObjectURL(elink.href) // 释放URL 对象
  518. // document.body.removeChild(elink)
  519. axios({
  520. headers: {
  521. 'MVVM-Key': String(new Date().getTime()),
  522. xx: 'anything'
  523. },
  524. method: 'post',
  525. url: constant.BASE_URI + '/ParkInfoController/downLoadTemplate',
  526. responseType: 'blob',
  527. data: this.tableData
  528. }).then(res => {
  529. this.downloadExcel(res.data, '楼盘导入模版.xlsx')
  530. }).catch((err) => {
  531. console.log(err)
  532. })
  533. },
  534. downloadFQTemplate() {
  535. // const outData = []
  536. // const title = []
  537. // title.push('楼盘/小区名称')
  538. // title.push('分期名称')
  539. // title.push('房屋买卖单价(元/㎡)')
  540. // title.push('物业费单价(元/㎡)')
  541. // title.push('住宅专项维修资金(元/㎡)')
  542. // title.push('认购金(元)')
  543. // title.push('共持比例')
  544. // title.push('支付方式')
  545. // outData.push(title)
  546. // const outSize = []
  547. // title.forEach(item => {
  548. // if (item.length > 4) {
  549. // outSize.push({
  550. // wch: 30
  551. // })
  552. // } else {
  553. // outSize.push({
  554. // wch: 15
  555. // })
  556. // }
  557. // })
  558. // let fileName = '模板'
  559. // if (this.importTitle.includes('批量导入')) {
  560. // fileName = '楼盘分期导入'
  561. // }
  562. // // if (this.importTitle === '批量更新') {
  563. // // fileName = '更新模板'
  564. // // }
  565. // const ws = XLSX.utils.aoa_to_sheet(outData)
  566. // ws['!cols'] = outSize
  567. // ws['!rows'] = []
  568. // const wb = XLSX.utils.book_new()
  569. // XLSX.utils.book_append_sheet(wb, ws, fileName)
  570. // const tmpDown = new Blob([
  571. // this.s2ab(
  572. // XLSXStyle.write(wb, {
  573. // bookType: 'xlsx',
  574. // bookSST: true,
  575. // type: 'binary',
  576. // cellStyles: true
  577. // })
  578. // )
  579. // ])
  580. // const elink = document.createElement('a')
  581. // elink.download = decodeURIComponent(fileName + '.xlsx')
  582. // elink.style.display = 'none'
  583. // elink.href = URL.createObjectURL(tmpDown)
  584. // document.body.appendChild(elink)
  585. // elink.click()
  586. // URL.revokeObjectURL(elink.href) // 释放URL 对象
  587. // document.body.removeChild(elink)
  588. axios({
  589. headers: {
  590. 'MVVM-Key': String(new Date().getTime()),
  591. xx: 'anything'
  592. },
  593. method: 'post',
  594. url: constant.BASE_URI + '/ParkFloorDiscController/downLoadTemplate',
  595. responseType: 'blob',
  596. data: this.tableData
  597. }).then(res => {
  598. this.downloadExcel(res.data, '楼盘分期导入模版.xlsx')
  599. }).catch((err) => {
  600. console.log(err)
  601. })
  602. },
  603. downloadBuildTemplate() {
  604. // const outData = []
  605. // const title = []
  606. // title.push('楼盘/小区名称')
  607. // title.push('分期名称')
  608. // title.push('单元/楼栋号')
  609. // title.push('施工号')
  610. // title.push('总面积(㎡)')
  611. // title.push('住宅面积(㎡)')
  612. // title.push('非住宅面积(㎡)')
  613. // title.push('占地面积(㎡)')
  614. // title.push('地下面积(㎡)')
  615. // title.push('房号')
  616. // title.push('套数')
  617. // title.push('总层数')
  618. // title.push('地上层数')
  619. // title.push('地下层数')
  620. // title.push('结构')
  621. // title.push('行政区划')
  622. // title.push('地号')
  623. // title.push('备注')
  624. // title.push('标准价格参考层及差价系数备注说明')
  625. //
  626. // outData.push(title)
  627. // const outSize = []
  628. // title.forEach(item => {
  629. // if (item.length > 4) {
  630. // outSize.push({
  631. // wch: 30
  632. // })
  633. // } else {
  634. // outSize.push({
  635. // wch: 15
  636. // })
  637. // }
  638. // })
  639. // let fileName = '模板'
  640. // if (this.importTitle.includes('批量导入')) {
  641. // fileName = '楼栋管理模板'
  642. // }
  643. // // if (this.importTitle === '批量更新') {
  644. // // fileName = '更新模板'
  645. // // }
  646. // const ws = XLSX.utils.aoa_to_sheet(outData)
  647. // ws['!cols'] = outSize
  648. // ws['!rows'] = []
  649. // const wb = XLSX.utils.book_new()
  650. // XLSX.utils.book_append_sheet(wb, ws, fileName)
  651. // const tmpDown = new Blob([
  652. // this.s2ab(
  653. // XLSXStyle.write(wb, {
  654. // bookType: 'xlsx',
  655. // bookSST: true,
  656. // type: 'binary',
  657. // cellStyles: true
  658. // })
  659. // )
  660. // ])
  661. // const elink = document.createElement('a')
  662. // elink.download = decodeURIComponent(fileName + '.xlsx')
  663. // elink.style.display = 'none'
  664. // elink.href = URL.createObjectURL(tmpDown)
  665. // document.body.appendChild(elink)
  666. // elink.click()
  667. // URL.revokeObjectURL(elink.href) // 释放URL 对象
  668. // document.body.removeChild(elink)
  669. axios({
  670. headers: {
  671. 'MVVM-Key': String(new Date().getTime()),
  672. xx: 'anything'
  673. },
  674. method: 'post',
  675. url: constant.BASE_URI + '/MnpBuildingController/downLoadTemplate',
  676. responseType: 'blob',
  677. data: this.tableData
  678. }).then(res => {
  679. this.downloadExcel(res.data, '楼盘楼栋导入模版.xlsx')
  680. }).catch((err) => {
  681. console.log(err)
  682. })
  683. },
  684. downloadRoomTemplate() {
  685. const outData = []
  686. const title = []
  687. title.push('楼盘/小区名称')
  688. title.push('分期名称')
  689. title.push('单元/楼栋号')
  690. title.push('户室号')
  691. title.push('所在层')
  692. title.push('预测套内面积')
  693. title.push('预测分摊面积')
  694. title.push('预测建筑面积')
  695. title.push('预测土地面积')
  696. title.push('实测套内面积')
  697. title.push('实测分摊面积')
  698. title.push('实测建筑面积')
  699. title.push('实测土地面积')
  700. title.push('用途')
  701. title.push('户编号')
  702. title.push('装修情况')
  703. title.push('2.2M以')
  704. title.push('户型')
  705. title.push('备注')
  706. title.push('可售状态')
  707. outData.push(title)
  708. const outSize = []
  709. title.forEach(item => {
  710. if (item.length > 4) {
  711. outSize.push({
  712. wch: 30
  713. })
  714. } else {
  715. outSize.push({
  716. wch: 15
  717. })
  718. }
  719. })
  720. let fileName = '模板'
  721. if (this.importTitle.includes('批量导入')) {
  722. fileName = '房间管理导入'
  723. }
  724. // if (this.importTitle === '批量更新') {
  725. // fileName = '更新模板'
  726. // }
  727. const ws = XLSX.utils.aoa_to_sheet(outData)
  728. ws['!cols'] = outSize
  729. ws['!rows'] = []
  730. const wb = XLSX.utils.book_new()
  731. XLSX.utils.book_append_sheet(wb, ws, fileName)
  732. const tmpDown = new Blob([
  733. this.s2ab(
  734. XLSXStyle.write(wb, {
  735. bookType: 'xlsx',
  736. bookSST: true,
  737. type: 'binary',
  738. cellStyles: true
  739. })
  740. )
  741. ])
  742. const elink = document.createElement('a')
  743. elink.download = decodeURIComponent(fileName + '.xlsx')
  744. elink.style.display = 'none'
  745. elink.href = URL.createObjectURL(tmpDown)
  746. document.body.appendChild(elink)
  747. elink.click()
  748. URL.revokeObjectURL(elink.href) // 释放URL 对象
  749. document.body.removeChild(elink)
  750. },
  751. handleClose() {
  752. this.dialogVisible = false
  753. },
  754. downloadExcel(blobPart, filename) {
  755. const blob = new Blob([blobPart], {
  756. type: 'application/vnd.ms-excel'
  757. })
  758. // console.log('downloadExcel', blob.size)
  759. // 创建一个超链接,将文件流赋进去,然后实现这个超链接的单击事件
  760. const elink = document.createElement('a')
  761. elink.download = decodeURIComponent(filename)
  762. elink.style.display = 'none'
  763. elink.href = URL.createObjectURL(blob)
  764. document.body.appendChild(elink)
  765. elink.click()
  766. URL.revokeObjectURL(elink.href) // 释放URL 对象
  767. document.body.removeChild(elink)
  768. },
  769. getItemJson(item) {
  770. item.groupNameStr = item.groupName.replace('{', '').replace('}', '')
  771. item.discNameStr = item.discName ? item.discName.replace('{', '').replace('}', '') : ''
  772. item.buildNumStr = item.buildNum ? item.buildNum.replace('{', '').replace('}', '') : ''
  773. item.roomNoStr = item.roomNo ? item.roomNo.replace('{', '').replace('}', '') : ''
  774. return item
  775. }
  776. }
  777. }
  778. </script>
  779. <style lang="scss">
  780. .uploadCost {
  781. .el-card__body {
  782. padding: 0 !important;
  783. }
  784. .uploadtitle {
  785. color: #C5C5C5;
  786. }
  787. .el-dialog__body {
  788. padding: 15px !important;
  789. color: #606266 !important;
  790. font-size: 14px !important;
  791. word-break: break-all !important;
  792. }
  793. .el-upload {
  794. width: 100%;
  795. }
  796. .el-upload-list {
  797. li {
  798. text-align: center;
  799. }
  800. }
  801. .mgauto {
  802. display: block;
  803. margin: 0 auto;
  804. }
  805. .mtmb16 {
  806. margin-top: 16px;
  807. margin-bottom: 16px;
  808. }
  809. .txtcenter {
  810. text-align: center;
  811. }
  812. }
  813. </style>