Commit f5728be4 authored by wangjiankun's avatar wangjiankun

feat:新增楼盘详情-下载技术资料,展示文件列表 下载时展示下载进度

feat: 新增楼盘详情-户型图一览模块,当切换到户型图时先展示户型列表 点击任意卡片跳转到该户型的详细信息
fix: 将路由中的天佑户型库改为弹出新窗口
parent 89b07b24
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1596610371757" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5226" width="48" height="48" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M504.32 46.08C244.58752 46.08 33.28 257.38752 33.28 517.12s211.30752 471.04 471.04 471.04 471.04-211.30752 471.04-471.04S764.05248 46.08 504.32 46.08z m0 842.38848c-204.76416 0-371.34848-166.58688-371.34848-371.34848S299.55584 145.77152 504.32 145.77152 875.66848 312.35584 875.66848 517.12 709.08416 888.46848 504.32 888.46848z" p-id="5227" fill="#1296db"></path><path d="M638.4256 492.3648L555.52 575.2704V291.84c0-28.27776-22.92224-51.2-51.2-51.2s-51.2 22.92224-51.2 51.2v280.8704l-80.3456-80.3456c-19.99616-19.99104-52.416-19.99104-72.4096 0-19.9936 19.99616-19.9936 52.416 0 72.4096l166.5408 166.5408a51.05152 51.05152 0 0 0 36.20608 14.99392c0.832 0 1.65888-0.07936 2.49088-0.11776 0.82944 0.04096 1.65888 0.11776 2.49088 0.11776a51.06176 51.06176 0 0 0 36.20608-14.99392l166.5408-166.5408c19.9936-19.99616 19.9936-52.416 0-72.4096-20.00128-19.99104-52.42112-19.99104-72.41472 0z" p-id="5228" fill="#1296db"></path></svg>
\ No newline at end of file
import requestFiles from "../../../plugins/axios/requestFiles";
const axios = require('axios')
import xhr from '@utils/http'
export function downloadFiles(url, that, processCall, cancelTokenFlag) {
return requestFiles({
url,
method: 'get',
cancelToken: new axios.CancelToken(function executor (c) { // 设置 cancel token
if (that) {
that.sourceCnacle[cancelTokenFlag] = c
}
}),
onDownloadProgress: (processEvent) => {
processCall && processCall(processEvent)
}
})
}
export function downFilesWithProcess(params, progressCall) {
return xhr.downloadFileWithProcess('bnsproject/bns-project/downloadTyFile', params, processEvent => {
progressCall(processEvent)
})
}
......@@ -2,11 +2,16 @@
<div v-if="!item.hidden" class="menu-wrapper">
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
<app-link :to="resolvePath(onlyOneChild.path)">
<app-link :to="resolvePath(onlyOneChild.path)" v-if="onlyOneChild.path !== '/tenioStore'">
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">
<item :meta="Object.assign({},item.meta,onlyOneChild.meta)" />
</el-menu-item>
</app-link>
<a v-else @click="toTenioStore">
<el-menu-item>
<item :meta="Object.assign({},item.meta,onlyOneChild.meta)" />
</el-menu-item>
</a>
</template>
<el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
......@@ -56,6 +61,9 @@ export default {
return {}
},
methods: {
toTenioStore() {
window.open('http://yanfa.tenio.com:2020', '_blank')
},
hasOneShowingChild(children = [], parent) {
const showingChildren = children.filter(item => {
if (item.hidden) {
......@@ -120,7 +128,7 @@ export default {
.svg-icon {
margin-right: 12px;
}
.submenu-title-noDropdown{
li {
padding 8px 0
line-height 40px
i {
......
<template class="fileListCon">
<div class="fileList">
<div class="fileCover">
<img :src="fileTypeSrc" alt="" width="100%" height="100%">
</div>
<div class="fileName">
<span :title="fileName">{{ fileName}}</span>
</div>
<div class="fileOptions">
<svg-icon icon-class="download" @click="downloadEmit" style="width: 20px;height: 20px" v-if="!process || process == -1"></svg-icon>
<i v-else-if="process == 0" class="el-icon-loading" />
<span v-else>{{process + '%'}}</span>
</div>
<div class="processBar" v-if="process && Number(process) > 0">
<el-progress :percentage="Number(process)" :show-text="false" :stroke-width="4"></el-progress>
</div>
</div>
</template>
<script>
export default {
name: 'FileList',
props: {
typeSrc: {
type: String
},
fileName: {
type: String
},
process: {
type: [Number,String],
default() {
return -1
}
}
},
data() {
return {
}
},
watch: {
process(val) {
console.log(val)
}
},
computed: {
fileTypeSrc() {
switch (this.typeSrc) {
case 'doc':
case 'docx':
return require('@assets/img/word.png')
case 'jpg':
case 'jpeg':
case 'gif':
case 'png':
case 'bmp':
return require('@assets/img/picture.png')
case 'pdf':
return require('@assets/img/pdf.png')
case 'xls':
case 'xlsx':
return require('@assets/img/excel.png')
case 'zip':
case 'rar':
case 'gz':
return require('@assets/img/zip.png')
case 'ppt':
case 'pptx':
return require('@assets/img/ppt.png')
case 'txt':
return require('@assets/img/text.png')
}
}
},
methods: {
downloadEmit() {
this.$emit('downLoadSingleFile')
},
delHide() {
this.isShow = false
},
delShow() {
this.isShow = true
}
}
}
</script>
<!--<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">-->
<style scoped>
.fileList{
width: 395px;
height: 40px;
display: flex;
align-items: center;
position: relative;
flex-direction: row;
}
.fileList .fileCover {
width: 28px;
height: 30px;
}
.fileList .fileOptions {
text-align: center;
width: 60px;
height: 40px;
line-height: 40px;
}
.fileList .fileName {
width: 100%;
padding-left: 15px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
height: 40px;
line-height: 40px;
}
.fileList:hover{
cursor: pointer;
background:rgba(236,244,253,1);
}
.fileList .processBar {
position: absolute;
bottom: 0;
width: 100%;
left: 0;
}
</style>
<template>
<div class="unitCard">
<div class="unitCard" @click="$emit('cardClick')">
<div class="imgContainer">
<viewer :images="getImgListUrl(imgList)" style="width: 100%;height: 100%">
<img
......
import axios from 'axios'
const requestFiles = axios.create({
baseURL: '', // api 的 base_url
timeout: 30000, // 请求超时时间
withCredentials: true,
headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' },
responseType: 'arraybuffer'
})
requestFiles.interceptors.request.use(
)
// response 拦截器
requestFiles.interceptors.response.use(
)
export default requestFiles
......@@ -53,3 +53,15 @@ exports.downloadFile = function (api, data) {
data
})
}
exports.downloadFileWithProcess = function (api, params, processCall,) {
return xhr({
url: api,
method: 'get',
responseType: 'blob',
params,
timeout: 0,
onDownloadProgress: (processEvent) => {
processCall(processEvent)
}
})
}
<template>
<el-card :body-style="{ padding: '5px 0 10px 0' }">
<section class="propertiesMain" v-loading.body="propertyLoading">
<section class="propertiesMain" :loading="propertyLoading">
<header class="header">
<div class="headerMain" id="propertyDetailHeader">
<div class="back">
......@@ -10,6 +10,7 @@
{{propertyData.projectInformation.name}}
</div>
<div class="bannerOptions">
<el-button class="downloadPropertyData" :disabled="propertyData.fileList.length === 0" @click="downloadDataFlag = true" type="" >下载技术资料</el-button>
<el-radio-group v-model="bannerType" @change="scorllTop">
<el-radio-button :label="0">总图</el-radio-button>
<el-radio-button :label="1">立面</el-radio-button>
......@@ -22,20 +23,52 @@
<!-- banner图划分-->
<div :class="{'banner': true, 'unitInfo': bannerType === 2 }">
<div v-if="bannerType === 0">
<banner :bannerType="'zt'" :height="'600px'" :auto-play="true" :banner-data="propertyData.propertyBanner.ztBanner"/>
<banner :bannerType="'zt'"
:height="'600px'"
:auto-play="true"
:banner-data="propertyData.propertyBanner.ztBanner"/>
</div>
<div v-if="bannerType === 1">
<banner :bannerType="'lm'" :height="'600px'" :auto-play="true" :banner-data="propertyData.propertyBanner.lmBanner"/>
<banner :bannerType="'lm'"
:height="'600px'"
:auto-play="true"
:banner-data="propertyData.propertyBanner.lmBanner"/>
</div>
<div v-if="bannerType === 2" class="unitBannerContainer">
<banner ref="unitBanner" :bannerType="'unit'" height="'100%'" :auto-play="false" class="unitPicture" :img-width="100" @bannerChange="saleingChange" :banner-data="propertyData.propertyBanner.hxBanner" />
<div v-if="bannerType === 2 && unitDetailShowFlag" class="unitBannerContainer">
<el-button type="primary" size="small" @click="unitDetailShowFlag = false" class="backToUnitList">返回产品列表</el-button>
<banner ref="unitBanner"
:bannerType="'unit'"
height="'100%'"
:auto-play="false"
class="unitPicture"
:img-width="100"
@bannerChange="saleingChange"
:banner-data="propertyData.propertyBanner.hxBanner" />
</div>
<!-- 户型信息 只在banner类型为户型时才显示-->
<div class="unitInformation" v-if="bannerType === 2">
<div class="unitInformation" v-if="bannerType === 2 && unitDetailShowFlag">
<div style="padding: 15px 5px;width: 98%;margin: 0 auto" align="center">
<multi-header-table :zoom="0.65" :header-width="60" :body-width="40" :header-data="multiHeader" :table-data="hxObjectData"></multi-header-table>
<multi-header-table
:zoom="0.65"
:header-width="60"
:body-width="40"
:header-data="multiHeader"
:table-data="hxObjectData"></multi-header-table>
</div>
</div>
<div class="unitList" v-if="bannerType === 2 && !unitDetailShowFlag">
<el-row>
<el-col :span="8" v-for="(item,index) in propertyData.propertyBanner.hxBanner" :key="index">
<unit-card
style="cursor:pointer;"
@cardClick="toUnitDetail(item.businessId)"
:unit-name="item.projectTypeName || '产品类型'"
:unit-area="item.unitArea"
:img-list="item.imgList"
:unit-info="item.roomNumber + '-' + item.hallNumber + '-' + item.toiletNumber"></unit-card>
</el-col>
</el-row>
</div>
</div>
<!-- 规划信息-->
<div class="planningInformation" v-if="bannerType !== 2">
......@@ -164,7 +197,7 @@
<th>卫生间数</th>
</tr>
<tr v-for="item in houseUnitTable">
<td><el-link @click="toUnitDetail(item)" :underline="false">{{item.production || '--'}}</el-link></td>
<td><el-link @click="toUnitDetail(item.productId)" :underline="false">{{item.production || '--'}}</el-link></td>
<td>{{item.kjNum || '--'}}</td>
<td>{{item.jsNum || '--'}}</td>
<td>{{item.tingNum || '--'}}</td>
......@@ -190,7 +223,7 @@
<th>客卧面宽</th>
</tr>
<tr v-for="item in houseWidthTable">
<td><el-link @click="toUnitDetail(item)" :underline="false">{{item.production || '--'}}</el-link></td>
<td><el-link @click="toUnitDetail(item.productId)" :underline="false">{{item.production || '--'}}</el-link></td>
<td>{{item.nxmk ? item.nxmk.toFixed(1) : '0'}}</td>
<td>{{item.qjsmk ? item.qjsmk.toFixed(1) : '0'}}</td>
<td>{{item.zwmk ? item.zwmk.toFixed(1) : '0'}}</td>
......@@ -204,6 +237,17 @@
</div>
</main>
</section>
<el-dialog :close-on-click-modal="false" title="下载技术资料" :visible.sync="downloadDataFlag" custom-class="customDialogStyle">
<div >
<file-list v-for="(item,index) in propertyData.fileList"
:file-name="item.fileName"
:key="index"
:process="downloadDataProcessArray[index]"
:type-src="item.fileName.split('.')[item.fileName.split('.').length -1]"
@downLoadSingleFile="downloadsingleFile(item, index)">
</file-list>
</div>
</el-dialog>
</el-card>
</template>
......@@ -218,9 +262,12 @@
import {queryLandInfoById, queryPropertyDetail, queryPropertySupplyData, queryAnalysisById, getJsonForProduction, exportPropertyAnalysis} from "@assets/js/api/unitManage";
import { areaRangeMap } from "../plateSupplyData/areaRangeMap";
import { downloadFile } from "../../assets/js/public";
import UnitCard from '@comp/unitCard'
import fileList from '@comp/filelist'
import { downFilesWithProcess} from "../../assets/js/api/downloadFIleWithProgress";
export default {
name: "propertiesDetail",
components: {banner, multiHeaderTable},
components: { banner, multiHeaderTable, UnitCard, fileList },
data () {
return {
bannerType: 0,
......@@ -302,6 +349,8 @@
houseWidthTable: [],
colorArr: colors,
hxObjectData: {}, // 户型信息多级表头数据
downloadDataFlag: false, // 下载技术资料弹框控制
downloadDataProcessArray: [], // 下载技术资料 进度条控制数组
// 楼盘详情数据
propertyData: {
projectInformation: {
......@@ -313,8 +362,11 @@
hxBanner: []
},
propertyPlaningInfo: [],
propertySoildInfo: []
propertySoildInfo: [],
fileList: []
},
// 户型详情
unitDetailShowFlag: false,
// loading
propertyLoading: false,
// 规划信息map匹配
......@@ -394,11 +446,57 @@
}
},
methods: {
toUnitDetail(production) {
if(production.productId) {
this.bannerType = 2
downloadsingleFile(file,index) {
const temp = {
path: file.fileUrl,
fileName: file.fileName
}
this.$set(this.downloadDataProcessArray, index, 0)
downFilesWithProcess(temp, processEvent => {
if(processEvent.total !== 0) {
const process = (processEvent.loaded / file.fileSize) * 100
this.$set(this.downloadDataProcessArray, index, Number(process.toFixed(1)))
if(this.downloadDataProcessArray[index] >= 100) {
setTimeout(() => {
this.$set(this.downloadDataProcessArray, index, -1)
},500)
this.$message({
type: 'success',
message: '下载成功'
})
}
} else {
const process = (processEvent.loaded / file.fileSize) * 100
this.$set(this.downloadDataProcessArray, index, Number(process.toFixed(1)))
if(this.downloadDataProcessArray[index] >= 100) {
setTimeout(() => {
this.$set(this.downloadDataProcessArray, index, -1)
},500)
this.$message({
type: 'success',
message: '下载成功'
})
}
}
}).then(res => {
const url = window.URL.createObjectURL(res)
const link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', file.fileName) // 自定义下载文件名
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
})
},
toUnitDetail(productId) {
if(productId) {
if(this.bannerType !== 2) {
this.bannerType = 2
}
this.unitDetailShowFlag = true
setTimeout(() => {
this.$refs['unitBanner'].acitveBanner(production.productId)
this.$refs['unitBanner'].acitveBanner(productId)
},100)
}
},
......@@ -455,6 +553,15 @@
queryPropertyDetail(this.propertyId).then(res => {
this.propertyLoading = true
if(res.data) {
// 技术资料
if(res.data.fileTyList && res.data.fileTyList.length > 0) {
this.propertyData.fileList = res.data.fileTyList.filter(item => { return item.fileUrl })
let processarr = []
res.data.fileTyList.forEach(() => {
processarr.push(-1)
})
this.downloadDataProcessArray = processarr
}
// 总图
this.propertyData.projectInformation = res.data.bnsProject
this.propertyData.projectInformation.productTypeName = res.data.productTypeName
......@@ -490,6 +597,7 @@
let propertyProjectInfoArr = []
res.data.bnsProductList.forEach(propertySinle => {
const singleData = {}
singleData.projectTypeName = propertySinle.projectTypeName
singleData.businessId = propertySinle.bnsProduct.businessId
singleData.unitArea = propertySinle.bnsProduct.unitArea
singleData.bayNumber = propertySinle.bnsProduct.bayNumber
......@@ -690,13 +798,14 @@
mounted(){
let scorll = document.getElementById('htmlMain')
if(scorll) {
const header = document.getElementById('propertyDetailHeader')
scorll.addEventListener('scroll', () => {
if(scorll.scrollTop > 0) {
document.getElementById('propertyDetailHeader').style.opacity = 0.5
document.getElementById('propertyDetailHeader').style.background = 'transparent'
header.style.opacity = 0.5
header.style.background = 'transparent'
} else {
document.getElementById('propertyDetailHeader').style.opacity = 1
document.getElementById('propertyDetailHeader').style.background = '#ffffff'
header.style.opacity = 1
header.style.background = '#ffffff'
}
})
}
......@@ -744,6 +853,12 @@
}
.bannerOptions {
float right
.downloadPropertyData{
margin-right 15px
background-color #F08967
border-color #F08967
color white
}
}
}
}
......@@ -759,11 +874,23 @@
.unitBannerContainer {
min-width 600px
width: 65.6%;
position relative
padding: 0 15px;
border: 2px solid rgb(222, 235, 247);
border-right: none
display flex
align-items center
.backToUnitList{
position absolute
top 10px
left 10px
}
}
.unitList {
width 100%
.el-col{
margin-bottom 20px
}
}
}
.unitInformation{
......@@ -911,6 +1038,36 @@
}
}
}
.customDialogStyle {
width 40%
border-radius: 8px;
.el-dialog__header {
display: flex;
align-items: center;
justify-content: center;
width:100%;
height:50px;
padding: 0;
background:rgba(237,240,245,1);
border-radius:10px 10px 0px 0px;
}
.el-dialog {
border-radius: 10px 10px 10px 10px;
}
.el-dialog__body {
min-height: 120px;
max-height: 60vh;
position: relative;
padding: 35px 35px 30px 25px;
.fileList {
margin 0 auto
}
.fileList:nth-child(2n) {
margin 8px auto
}
}
}
.viewer-prev {
display: inline-block;
}
......
<template>
<section class="storeMain">
<iframe src="http://yanfa.tenio.com:2020" @load="loading = false"></iframe>
<section class="storeMain" id="loadingMain">
<iframe src="http://yanfa.tenio.com:2020" id="iframe-tenioStore" @load="loadingDisppare"></iframe>
</section>
</template>
......@@ -11,17 +11,23 @@
return {
loading: true
}
},
beforeMount() {
}
}
</script>
<style scoped>
<style lang="stylus">
.storeMain{
width: 100%;
height: 100%;
}
iframe {
width: 100%;
height: 100%;
iframe {
width: 100%;
height: 100%;
}
.loginTop {
display none
}
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment