|
@@ -0,0 +1,527 @@
|
|
|
+<template>
|
|
|
+ <div class="uploadCost">
|
|
|
+ <el-dialog
|
|
|
+ v-loading="loading"
|
|
|
+ :before-close="closeUpload"
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ :close-on-press-escape="false"
|
|
|
+ :title="importTitle"
|
|
|
+ :visible.sync="dialogVisible"
|
|
|
+ append-to-body
|
|
|
+ width="50%"
|
|
|
+ >
|
|
|
+ <!-- :title="isImport?'导入结果':'批量导入'"-->
|
|
|
+ <div v-if="!isImport">
|
|
|
+ <p v-for="(item, index) in uploadTitle" :key="index" class="uploadtitle">
|
|
|
+ {{ item }}
|
|
|
+ </p>
|
|
|
+ <el-card style="padding-top: 10px;padding-bottom: 10px">
|
|
|
+
|
|
|
+ <div style="width: 50%;float:left;">
|
|
|
+ <p class="uploadtitle txtcenter">1.下载模板按要求填写</p>
|
|
|
+ <img class="mtmb16 mgauto" src="@/assets/excelicon.png" width="50px">
|
|
|
+ <div style="width: 100%">
|
|
|
+ <el-button class="mtmb16 mgauto" size="small" type="primary" @click="downloadTemplate()">下载模板
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div style="width: 50%;float:left;">
|
|
|
+ <p class="uploadtitle txtcenter">2.上传填写好的文件</p>
|
|
|
+ <img class="mtmb16 mgauto" src="@/assets/excelicon.png" width="50px">
|
|
|
+ <div class="mgauto2">
|
|
|
+ <el-upload
|
|
|
+ :file-list="fileUrlList"
|
|
|
+ :http-request="uploadFile"
|
|
|
+ :limit="1"
|
|
|
+ accept=".xlsx"
|
|
|
+ action="#"
|
|
|
+ >
|
|
|
+ <el-button class="mtmb16" size="small" style="margin-top: 0;height: 33px" type="primary">上传文件</el-button>
|
|
|
+ <div slot="file" slot-scope="{file}">
|
|
|
+ <a :href="file.url">{{ file.name }}</a>
|
|
|
+ <span class="el-upload-list__item-actions">
|
|
|
+ <i class="el-icon-delete" @click="handlePictureRemove(file,fileUrlList)" />
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </el-upload>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </el-card>
|
|
|
+ </div>
|
|
|
+ <div v-if="isImport" style="margin:10px">
|
|
|
+ <p>导入成功 <span>{{ successCount }} 条</span> ,失败 <span>{{ errorCount }}</span> 条 </p>
|
|
|
+ <p>您可以下载失败记录,修改后重新上传。以下标红为校验失败项</p>
|
|
|
+ <el-table
|
|
|
+ :data="tableData"
|
|
|
+ style="width: 100%;"
|
|
|
+ >
|
|
|
+ <el-table-column align="center" label="企业名称" prop="companyName">
|
|
|
+ <template v-slot="scope">
|
|
|
+ <span>{{ scope.row.qymc }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column align="center" label="统一信用代码" prop="unifiedCreditCode">
|
|
|
+ <template v-slot="scope">
|
|
|
+ <span>{{ scope.row.shxydm }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column align="center" label="注册资金" prop="taxation">
|
|
|
+ <template v-slot="scope">
|
|
|
+ <span>{{ scope.row.zczj }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column align="center" label="入驻类型" prop="revenue">
|
|
|
+ <template v-slot="scope">
|
|
|
+ <span>{{ scope.row.settleInType }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column align="center" label="异常原因" prop="reason">
|
|
|
+ <template v-slot="scope">
|
|
|
+ <span style="color: red">{{ scope.row.reason }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ <span slot="footer" class="dialog-footer">
|
|
|
+ <el-button @click="closeUpload()">取 消</el-button>
|
|
|
+ <el-button
|
|
|
+ v-if="!isImport"
|
|
|
+ :disabled="fileUrlList.length===0"
|
|
|
+ type="primary"
|
|
|
+ @click="importFile()"
|
|
|
+ class="ch-button-else"
|
|
|
+ >导入</el-button>
|
|
|
+ <el-button
|
|
|
+ v-if="isImport"
|
|
|
+ type="primary"
|
|
|
+ @click="exportError()"
|
|
|
+ >
|
|
|
+ 下载失败记录
|
|
|
+ </el-button>
|
|
|
+ </span>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+// import XLSX from 'xlsx'
|
|
|
+// import XLSXStyle from 'xlsx-style-fixedver'
|
|
|
+const XLSX = require('xlsx')
|
|
|
+const XLSXStyle = require('xlsx-style-fixedver')
|
|
|
+
|
|
|
+const defaultTitle = '批量导入'
|
|
|
+export default {
|
|
|
+ props: {
|
|
|
+ // 弹框状态
|
|
|
+ dialogVisible: { type: Boolean, default: false },
|
|
|
+ // 类型
|
|
|
+ importType: { type: String, default: '' },
|
|
|
+ // 上传说明
|
|
|
+ uploadTitle: { type: Array, default: () => ([]) },
|
|
|
+ // 名称
|
|
|
+ importTitle: { type: String, default: '' }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ fileUrlList: [],
|
|
|
+ tableData: [],
|
|
|
+ title: defaultTitle.repeat(1),
|
|
|
+ loading: false,
|
|
|
+ isImport: false,
|
|
|
+ file: null,
|
|
|
+ successCount: 0,
|
|
|
+ errorCount: ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ importFile() {
|
|
|
+ if (this.importType === 'groupInsert') {
|
|
|
+ this.importGroup()
|
|
|
+ }
|
|
|
+ if (this.importType === 'FQInsert') {
|
|
|
+ this.importFQ()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ importGroup() {
|
|
|
+ this.loading = true
|
|
|
+ this.$axios({
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'multipart/form-data'
|
|
|
+ },
|
|
|
+ method: 'post',
|
|
|
+ url: this.$constant.BASE_URI + '/ParkInfoController/handleImport',
|
|
|
+ data: this.file
|
|
|
+ }).then((res) => {
|
|
|
+ this.loading = false
|
|
|
+ if (res.data.code === 200) {
|
|
|
+ this.$message({
|
|
|
+ message: '上传成功',
|
|
|
+ type: 'success'
|
|
|
+ })
|
|
|
+ // this.$emit('cancelUpload', true)
|
|
|
+ this.successCount = res.data.data.successCount
|
|
|
+ this.errorCount = res.data.data.errorCount
|
|
|
+ this.tableData = res.data.data.errorList || []
|
|
|
+ this.isImport = true
|
|
|
+ console.log('上传成功....')
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ message: res.data.msg,
|
|
|
+ type: 'error'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }).catch((err, x) => {
|
|
|
+ console.log('biz user list error', err, x)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ importFQ() {
|
|
|
+ this.loading = true
|
|
|
+ this.$axios({
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'multipart/form-data'
|
|
|
+ },
|
|
|
+ method: 'post',
|
|
|
+ url: this.$constant.BASE_URI + '/ParkFloorDiscController/handleImport',
|
|
|
+ data: this.file
|
|
|
+ }).then((res) => {
|
|
|
+ this.loading = false
|
|
|
+ if (res.data.code === 200) {
|
|
|
+ this.$message({
|
|
|
+ message: '上传成功',
|
|
|
+ type: 'success'
|
|
|
+ })
|
|
|
+ // this.$emit('cancelUpload', true)
|
|
|
+ this.successCount = res.data.data.successCount
|
|
|
+ this.errorCount = res.data.data.errorCount
|
|
|
+ this.tableData = res.data.data.errorList || []
|
|
|
+ this.isImport = true
|
|
|
+ console.log('上传成功....')
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ message: res.data.msg,
|
|
|
+ type: 'error'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }).catch((err, x) => {
|
|
|
+ console.log('biz user list error', err, x)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ closeUpload() {
|
|
|
+ // 关闭弹窗
|
|
|
+ this.$emit('cancelUpload')
|
|
|
+ },
|
|
|
+ uploadFile(param) {
|
|
|
+ const formParam = new FormData()
|
|
|
+ formParam.append('file', param.file)
|
|
|
+ this.file = formParam
|
|
|
+ this.fileUrlList.push({ name: param.file.name })
|
|
|
+ },
|
|
|
+ handlePictureRemove(file, fileUrlList) {
|
|
|
+ const index = fileUrlList.indexOf(file)
|
|
|
+ fileUrlList.splice(index, 1)
|
|
|
+ this.file = null
|
|
|
+ },
|
|
|
+ exportError() {
|
|
|
+ if (this.importType === 'FQInsert') {
|
|
|
+ this.exportErrorFQ()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ exportErrorFQ() {
|
|
|
+ if (!this.tableData.length) {
|
|
|
+ this.$message.error('失败记录为空!')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const outData = []
|
|
|
+ const title = []
|
|
|
+ title.push('楼盘/小区名称')
|
|
|
+ title.push('分期名称')
|
|
|
+ title.push('房屋买卖单价(元/㎡)')
|
|
|
+ title.push('物业费单价(元/㎡)')
|
|
|
+ title.push('住宅专项维修资金(元/㎡)')
|
|
|
+ title.push('认购金(元)')
|
|
|
+ title.push('共持比例')
|
|
|
+ title.push('支付方式')
|
|
|
+ outData.push(title)
|
|
|
+ const errorFiled = []
|
|
|
+ this.tableData.forEach((item, index) => {
|
|
|
+ const jsonArray = []
|
|
|
+ jsonArray.push(item.groupName)
|
|
|
+ jsonArray.push(item.name)
|
|
|
+ jsonArray.push(item.unitPrice)
|
|
|
+ jsonArray.push(item.propertyUnitPrice)
|
|
|
+ jsonArray.push(item.maintenanceFunds)
|
|
|
+ jsonArray.push(item.subscriptionFunds)
|
|
|
+ jsonArray.push(item.proportion)
|
|
|
+ jsonArray.push(item.reason)
|
|
|
+ outData.push(jsonArray)
|
|
|
+ })
|
|
|
+ const outSize = []
|
|
|
+ title.forEach(item => {
|
|
|
+ if (item.length > 4) {
|
|
|
+ outSize.push({
|
|
|
+ wch: 30
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ outSize.push({
|
|
|
+ wch: 15
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ const fileName = '失败记录导出 ' + new Date().Format('yyyy-MM-dd hh:mm')
|
|
|
+ const ws = XLSX.utils.aoa_to_sheet(outData)
|
|
|
+ ws['!cols'] = outSize
|
|
|
+ ws['!rows'] = []
|
|
|
+ if (errorFiled.length) {
|
|
|
+ errorFiled.forEach(item => {
|
|
|
+ if (!ws[item]) {
|
|
|
+ ws[item] = {
|
|
|
+ v: '',
|
|
|
+ t: 's',
|
|
|
+ s: {
|
|
|
+ fill: {
|
|
|
+ bgColor: { indexed: 64 }, fgColor: { rgb: 'FF0000' }
|
|
|
+ },
|
|
|
+ font: {
|
|
|
+ color: { rgb: 'FFFFFF' }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ ws[item].s = {
|
|
|
+ fill: {
|
|
|
+ bgColor: { indexed: 64 }, fgColor: { rgb: 'FF0000' }
|
|
|
+ },
|
|
|
+ font: {
|
|
|
+ color: { rgb: 'FFFFFF' }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ const wb = XLSX.utils.book_new()
|
|
|
+ XLSX.utils.book_append_sheet(wb, ws, fileName)
|
|
|
+ const tmpDown = new Blob([
|
|
|
+ this.s2ab(
|
|
|
+ XLSXStyle.write(wb, {
|
|
|
+ bookType: 'xlsx',
|
|
|
+ bookSST: true,
|
|
|
+ type: 'binary',
|
|
|
+ cellStyles: true
|
|
|
+ })
|
|
|
+ )
|
|
|
+ ])
|
|
|
+ const elink = document.createElement('a')
|
|
|
+ elink.download = decodeURIComponent(fileName + '.xlsx')
|
|
|
+ elink.style.display = 'none'
|
|
|
+ elink.href = URL.createObjectURL(tmpDown)
|
|
|
+ document.body.appendChild(elink)
|
|
|
+ elink.click()
|
|
|
+ URL.revokeObjectURL(elink.href) // 释放URL 对象
|
|
|
+ document.body.removeChild(elink)
|
|
|
+ },
|
|
|
+ s2ab(s) {
|
|
|
+ var cuf
|
|
|
+ var i
|
|
|
+ if (typeof ArrayBuffer !== 'undefined') {
|
|
|
+ cuf = new ArrayBuffer(s.length)
|
|
|
+ var view = new Uint8Array(cuf)
|
|
|
+ for (i = 0; i !== s.length; i++) {
|
|
|
+ view[i] = s.charCodeAt(i) & 0xFF
|
|
|
+ }
|
|
|
+ return cuf
|
|
|
+ } else {
|
|
|
+ cuf = new Array(s.length)
|
|
|
+ for (i = 0; i !== s.length; ++i) {
|
|
|
+ cuf[i] = s.charCodeAt(i) & 0xFF
|
|
|
+ }
|
|
|
+ return cuf
|
|
|
+ }
|
|
|
+ },
|
|
|
+ downloadTemplate() {
|
|
|
+ if (this.importType === 'groupInsert') {
|
|
|
+ this.downloadGroupTemplate()
|
|
|
+ }
|
|
|
+ if (this.importType === 'FQInsert') {
|
|
|
+ this.downloadFQTemplate()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ downloadGroupTemplate() {
|
|
|
+ const outData = []
|
|
|
+ const title = []
|
|
|
+ title.push('楼盘/小区名称')
|
|
|
+ title.push('性质')
|
|
|
+ title.push('预销售许可证编号')
|
|
|
+ title.push('开发公司')
|
|
|
+ title.push('总建筑面积(㎡)')
|
|
|
+ title.push('总用地面积(㎡)')
|
|
|
+ title.push('立项批文')
|
|
|
+ title.push('工程规划许可证')
|
|
|
+ title.push('施工许可证')
|
|
|
+ title.push('土地证号')
|
|
|
+ title.push('用地许可证号')
|
|
|
+ title.push('容积率')
|
|
|
+ title.push('绿化率')
|
|
|
+ title.push('标准单价')
|
|
|
+ title.push('超标单价')
|
|
|
+ title.push('楼盘面积测绘状态')
|
|
|
+ title.push('楼盘销售状态')
|
|
|
+ title.push('行政区划')
|
|
|
+ title.push('详细地址')
|
|
|
+ title.push('备注')
|
|
|
+
|
|
|
+ outData.push(title)
|
|
|
+ const outSize = []
|
|
|
+ title.forEach(item => {
|
|
|
+ if (item.length > 4) {
|
|
|
+ outSize.push({
|
|
|
+ wch: 30
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ outSize.push({
|
|
|
+ wch: 15
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ let fileName = '模板'
|
|
|
+ if (this.importTitle.includes('批量导入')) {
|
|
|
+ fileName = '导入模板'
|
|
|
+ }
|
|
|
+ if (this.importTitle.includes('批量更新')) {
|
|
|
+ fileName = '更新模板'
|
|
|
+ }
|
|
|
+ const ws = XLSX.utils.aoa_to_sheet(outData)
|
|
|
+ ws['!cols'] = outSize
|
|
|
+ ws['!rows'] = []
|
|
|
+ const wb = XLSX.utils.book_new()
|
|
|
+ XLSX.utils.book_append_sheet(wb, ws, fileName)
|
|
|
+ const tmpDown = new Blob([
|
|
|
+ this.s2ab(
|
|
|
+ XLSXStyle.write(wb, {
|
|
|
+ bookType: 'xlsx',
|
|
|
+ bookSST: true,
|
|
|
+ type: 'binary',
|
|
|
+ cellStyles: true
|
|
|
+ })
|
|
|
+ )
|
|
|
+ ])
|
|
|
+ const elink = document.createElement('a')
|
|
|
+ elink.download = decodeURIComponent(fileName + '.xlsx')
|
|
|
+ elink.style.display = 'none'
|
|
|
+ elink.href = URL.createObjectURL(tmpDown)
|
|
|
+ document.body.appendChild(elink)
|
|
|
+ elink.click()
|
|
|
+ URL.revokeObjectURL(elink.href) // 释放URL 对象
|
|
|
+ document.body.removeChild(elink)
|
|
|
+ },
|
|
|
+ downloadFQTemplate() {
|
|
|
+ const outData = []
|
|
|
+ const title = []
|
|
|
+ title.push('楼盘/小区名称')
|
|
|
+ title.push('分期名称')
|
|
|
+ title.push('房屋买卖单价(元/㎡)')
|
|
|
+ title.push('物业费单价(元/㎡)')
|
|
|
+ title.push('住宅专项维修资金(元/㎡)')
|
|
|
+ title.push('认购金(元)')
|
|
|
+ title.push('共持比例')
|
|
|
+ title.push('支付方式')
|
|
|
+ outData.push(title)
|
|
|
+ const outSize = []
|
|
|
+ title.forEach(item => {
|
|
|
+ if (item.length > 4) {
|
|
|
+ outSize.push({
|
|
|
+ wch: 30
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ outSize.push({
|
|
|
+ wch: 15
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ let fileName = '模板'
|
|
|
+ if (this.importTitle === '批量导入') {
|
|
|
+ fileName = '导入模板'
|
|
|
+ }
|
|
|
+ if (this.importTitle === '批量更新') {
|
|
|
+ fileName = '更新模板'
|
|
|
+ }
|
|
|
+ const ws = XLSX.utils.aoa_to_sheet(outData)
|
|
|
+ ws['!cols'] = outSize
|
|
|
+ ws['!rows'] = []
|
|
|
+ const wb = XLSX.utils.book_new()
|
|
|
+ XLSX.utils.book_append_sheet(wb, ws, fileName)
|
|
|
+ const tmpDown = new Blob([
|
|
|
+ this.s2ab(
|
|
|
+ XLSXStyle.write(wb, {
|
|
|
+ bookType: 'xlsx',
|
|
|
+ bookSST: true,
|
|
|
+ type: 'binary',
|
|
|
+ cellStyles: true
|
|
|
+ })
|
|
|
+ )
|
|
|
+ ])
|
|
|
+ const elink = document.createElement('a')
|
|
|
+ elink.download = decodeURIComponent(fileName + '.xlsx')
|
|
|
+ elink.style.display = 'none'
|
|
|
+ elink.href = URL.createObjectURL(tmpDown)
|
|
|
+ document.body.appendChild(elink)
|
|
|
+ elink.click()
|
|
|
+ URL.revokeObjectURL(elink.href) // 释放URL 对象
|
|
|
+ document.body.removeChild(elink)
|
|
|
+ },
|
|
|
+ handleClose() {
|
|
|
+ this.dialogVisible = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+<style lang="scss">
|
|
|
+.uploadCost {
|
|
|
+ .el-card__body {
|
|
|
+ padding: 0 !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ .uploadtitle {
|
|
|
+ //color: #C5C5C5;
|
|
|
+ color: #303133;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-dialog__body {
|
|
|
+ padding: 15px !important;
|
|
|
+ color: #606266 !important;
|
|
|
+ font-size: 14px !important;
|
|
|
+ word-break: break-all !important;
|
|
|
+ }
|
|
|
+ .el-upload {
|
|
|
+ //width: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-upload-list {
|
|
|
+ li {
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .mgauto {
|
|
|
+ display: block;
|
|
|
+ margin: 0 auto;
|
|
|
+ }
|
|
|
+
|
|
|
+ .mgauto2 {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ margin: 0 auto;
|
|
|
+ }
|
|
|
+
|
|
|
+ .mtmb16 {
|
|
|
+ margin-top: 16px;
|
|
|
+ margin-bottom: 16px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .txtcenter {
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+</style>
|