Files
gterFang/src/views/edit.vue
DESKTOP-RQ919RC\Pc c49df05594 feat(edit): 添加二维码上传配置并优化上传逻辑
- 新增uQrcodeConfigData用于存储二维码上传配置
- 重构二维码上传方法使用动态配置
- 分离二维码配置获取逻辑到独立方法uploadQrcodeConfig
2025-09-16 16:31:29 +08:00

3070 lines
127 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<page-top-bar></page-top-bar>
<map-component v-if="mapComponentState" :info="info" @choosingLocation="choosingLocation" />
<div class="content-box flexflex">
<!-- 左边的信息盒子 -->
<user-box :user="user" :type="type" :time="{ timestamp, updatetime, offshelftime }" :status="status" :allowpublishednum="allowpublishednum" :id="id" :intermediary="intermediary" :userIntermediary="userIntermediary" @handleAboutPopState="handleAboutPopState" :verified="verified"></user-box>
<div class="form-box shadow radius16 flex1">
<div class="form-header">发布{{ intermediary == 6 ? "求" : "出租" }}房源</div>
<div class="form-boxes">
<div class="form-item" v-for="item in fieldinfoBasic" :key="item.field">
<div class="form-title flexacenter">
{{ item.title }}
<div class="asterisk" v-if="item.required === 1">*</div>
</div>
<!--
方式一 两个选择框的 点击弹出 弹窗
方式二 两个选择框 但是第一个是居中 并且没有图标 现在只有 起租日期
方式三 三列选择框 多个 本页面操作
方式四 一条长长的款 点击弹窗
方式五 单行输入框 单位
-->
<!-- 出租方式 -->
<div v-if="item.field === 'type'" class="form-option modeOne flexacenter">
<el-popover placement="bottom" :width="640" v-model:visible="typePopState" :show-arrow="false" trigger="click" popper-style="padding:0; border-radius:16px;" popper-class="popover-leasetime">
<template #reference>
<div class="modeOne-item flexacenter wid640" ref="type">
<div class="modeOne-text flexacenter" v-if="info['type']">
{{ typeData[info["type"] >>> 0]["name"] }}
<img class="form-arrows" src="@/assets/img/edit/thin-arrow-disabled.svg" />
{{ typeValueUltimately }}
</div>
<div class="modeOne-text flexacenter" v-else style="color: #aaaaaa">请选择</div>
<img class="arrows-icon" src="@/assets/img/edit/arrows.svg" />
</div>
</template>
<div class="one-list" v-if="!typeValue">
<div class="item flexacenter" v-for="(item, index) in typeData" :key="index">
<div class="dot"></div>
<div class="content flex1 flexacenter" @click="handleType(index)">
<div class="text">{{ item["name"] }}</div>
<img class="icon" src="@/assets/img/edit/thin-arrow-disabled.svg" />
</div>
</div>
</div>
<div class="two-list flexflex" v-else>
<div class="left">
<div class="item flexacenter" v-for="(item, index) in typeData" :key="index">
<div class="dot"></div>
<div class="content flexacenter" :class="{ pitch: index == typeValue }" @click="handleType(index)">
<div class="text flex1">{{ item["name"] }}</div>
<img v-if="index == typeValue" class="icon" src="@/assets/img/edit/thin-arrow.svg" />
<img v-else class="icon" src="@/assets/img/edit/thin-arrow-disabled.svg" />
</div>
</div>
</div>
<div class="right flex1" v-if="typeData[typeValue]">
<div class="item flexacenter" :class="{ pitch: item.key == info['type'] }" v-for="(item, index) in typeData[typeValue].data" @click="handleType(item.key, item.value), (typePopState = false)" :key="index">
<div class="value">{{ item["value"] }}</div>
<img class="icom" src="@/assets/img/edit/blue-tick.svg" />
</div>
</div>
</div>
</el-popover>
</div>
<!-- 出租时长 -->
<div v-if="item.field === 'rentalduration'" class="form-option modeOne flexacenter">
<el-popover placement="bottom" :width="640" v-model:visible="rentaldurationPopState" :show-arrow="false" trigger="click" popper-style="padding:0; border-radius:16px;" popper-class="popover-leasetime">
<template #reference>
<div class="modeOne-item flexacenter wid640" ref="rentalduration">
<div class="modeOne-text flexacenter" v-if="info['rentalduration'] != null">
{{ rentaldurationObj[info["rentalduration"]] }}
</div>
<div class="modeOne-text flexacenter" v-else style="color: #aaaaaa">请选择</div>
<img class="arrows-icon" src="@/assets/img/edit/arrows.svg" />
</div>
</template>
<div class="one-list" v-if="!rentaldurationTwoState">
<div class="item flexacenter">
<div class="dot"></div>
<div class="content flex1 flexacenter" :class="{ pitch: info['rentalduration'] == 0 && info['rentalduration'] != null }" @click="setValue('rentalduration', 0), (rentaldurationPopState = false)">
<div class="text">不限</div>
<img class="icom" v-if="info['rentalduration'] == 0 && info['rentalduration'] != null" src="@/assets/img/edit/blue-tick.svg" />
</div>
</div>
<div class="item flexacenter">
<div class="dot"></div>
<div class="content flex1 flexacenter" @click="rentaldurationTwoState = true">
<div class="text">选择租期</div>
<img class="icon" src="@/assets/img/edit/thin-arrow-disabled.svg" />
</div>
</div>
</div>
<div class="two-list flexflex" v-else>
<div class="left">
<div class="item flexacenter" @click="rentaldurationTwoState = false">
<div class="dot"></div>
<div class="content flexacenter" @click="setValue('rentalduration', 0), (rentaldurationPopState = false)">
<div class="text flex1">不限</div>
</div>
</div>
<div class="item flexacenter">
<div class="dot"></div>
<div class="content flexacenter pitch" @click="handleType()">
<div class="text flex1">选择租期</div>
<img class="icon" src="@/assets/img/edit/thin-arrow.svg" />
</div>
</div>
</div>
<div class="right flex1 scrollbar" style="max-height: 360px; overflow: auto">
<div class="item flexacenter" :class="{ pitch: item.key == info['rentalduration'] }" v-for="(item, index) in item.choices" @click="setValue('rentalduration', item['key']), (rentaldurationPopState = false)" :key="index">
<div class="value">{{ item["value"] }}</div>
<img class="icom" src="@/assets/img/edit/blue-tick.svg" />
</div>
</div>
</div>
</el-popover>
</div>
<!-- 起租日期 -->
<div v-if="item.field === 'leasetime'" class="form-option modeOne flexacenter">
<el-popover placement="bottom" :width="640" :show-arrow="false" trigger="click" popper-style="padding:0; border-radius:16px;" popper-class="popover-leasetime" v-model:visible="leasetimePopState">
<template #reference>
<div class="modeOne-item flexacenter wid640">
<div class="modeOne-text flexacenter" v-if="info['leasetime'] != null" ref="leasetime">
{{ info["leasetime"] || "随时" }}
</div>
<div class="modeOne-text flexacenter" v-else style="color: #aaaaaa">请选择</div>
<img class="arrows-icon" src="@/assets/img/edit/arrows.svg" />
</div>
</template>
<div class="one-list" v-if="!leasetimeTwoState">
<div class="item flexacenter" @click="setValue('leasetime', 0), (leasetimePopState = false)">
<div class="dot"></div>
<div class="content flex1 flexacenter" :class="{ pitch: info['leasetime'] == 0 && info['leasetime'] != null }">
<div class="text">随时</div>
<img class="icom" v-if="info['leasetime'] == 0 && info['leasetime'] != null" src="@/assets/img/edit/blue-tick.svg" />
</div>
</div>
<div class="item flexacenter" @click="leasetimeTwoState = true">
<div class="dot"></div>
<div class="content flex1 flexacenter">
<div class="text">起租日期</div>
<img class="icon" src="@/assets/img/edit/thin-arrow-disabled.svg" />
</div>
</div>
</div>
<div class="two-list flexflex" v-else>
<div class="left">
<div class="item flexacenter" @click="setValue('leasetime', 0), (leasetimeTwoState = false), (leasetimePopState = false)">
<div class="dot"></div>
<div class="content flexacenter">
<div class="text">随时</div>
</div>
</div>
<div class="item flexacenter">
<div class="dot"></div>
<div class="content pitch flexacenter">
<div class="text flex1">起租日期</div>
<img class="icon" src="@/assets/img/edit/thin-arrow.svg" />
</div>
</div>
</div>
<div class="right flex1" style="height: 342px">
<el-config-provider :locale="locale">
<el-date-picker v-model="info.leasetime" :teleported="false" type="date" value-format="YYYY-MM-DD" popper-class="picker-leasetime" :disabled-date="disabledDate" @update:modelValue="leasetimePopState = false"> </el-date-picker>
</el-config-provider>
</div>
</div>
</el-popover>
</div>
<!-- 月租 -->
<div v-if="item.field == 'rent' && intermediary != 6" ref="rent" class="form-option modeFive flexacenter" :class="{ pitch: info.rent }">
<input class="modeFive-input flex1" v-model="info.rent" type="number" step="1" maxlength="9" min="0" placeholder="请输入数字" onkeyup="this.value= this.value.match(/\d+(\.\d{0,2})?/) ? this.value.match(/\d+(\.\d{0,2})?/)[0] : '';" />
<div class="modeFive-unit">{{ item.unit }}</div>
</div>
<div v-if="item.field == 'rent' && intermediary == 6" ref="rent" class="form-option modeSix flexacenter" :class="{ pitch: info.rent }">
<div class="modeSix-select flexacenter">
<el-select v-model="rent_min" placeholder="请选择" @visible-change="rentDropDown">
<el-option v-for="item in 491" :key="(item - 1) * 100 + 1000" :label="(item - 1) * 100 + 1000" :value="(item - 1) * 100 + 1000"> </el-option>
</el-select>
<img class="arrows-icon" src="@/assets/img/edit/arrows.svg" />
</div>
<div class="modeSix-tilde flexacenter">~</div>
<div class="modeSix-select flexacenter">
<el-select v-model="rent_max" placeholder="请选择" @visible-change="rentDropDown">
<el-option v-for="item in 491" :key="(item - 1) * 100 + 1000" :label="(item - 1) * 100 + 1000" :value="(item - 1) * 100 + 1000"> </el-option>
</el-select>
<img class="arrows-icon" src="@/assets/img/edit/arrows.svg" />
</div>
<div class="modeSix-unit">港元/</div>
</div>
<!-- 房屋类型 -->
<div v-if="item.field == 'property' && intermediary != 6" class="form-option modeThree flexacenter">
<div v-for="(item, index) in item.choices" :key="index" class="modeThree-item flexcenter" :class="{ pitch: info['property'] == item.key, noChoice: verified == 1 }" ref="property" @click="verified == 1 ? '' : setValue('property', item.key)">{{ item.value }}</div>
</div>
<div v-if="item.field == 'property' && intermediary == 6" class="form-option modeSeven flexflex">
<div class="modeSeven-unlimited flexacenter">
<div class="modeSeven-unlimited-item flexacenter" @click="setValueMultiple('property', [], true)">
<img v-show="info.property.length == 0" class="modeSeven-unlimited-circle-pitch" src="@/assets/img/edit/circle-pitch.svg" alt="" />
<div v-show="info.property.length != 0" class="modeSeven-unlimited-circle"></div>
不限
</div>
</div>
<div class="modeSeven-option-box flexflex">
<div class="modeSeven-option-item flexacenter" v-for="(item, index) in item.choices" :key="index" @click="setValueMultiple('property', item.key)">
<img v-show="info.property.includes(item.key)" class="modeSeven-option-icon" src="@/assets/img/edit/diamond-selected.svg" />
<img v-show="!info.property.includes(item.key)" class="modeSeven-option-icon" src="@/assets/img/edit/diamond-unselected.svg" />
{{ item.value }}
</div>
</div>
</div>
<!-- 所在楼层 -->
<div v-if="item.field == 'floor' && intermediary != 6" ref="floor" class="form-option modeFour flexacenter" :class="{ pitch: info.floor, disabled: verified == 1 }">
<el-select class="modeFour-select flex1" :disabled="verified == 1" v-model="info.floor" placeholder="请选择">
<div v-for="(item, index) in 104" :key="index">
<el-option v-if="item - 4 !== 0" :label="item - 4 + '楼'" :key="item - 4" :value="item - 4"></el-option>
</div>
</el-select>
<img class="modeFour-arrows" src="@/assets/img/edit/arrows.svg" />
<img class="modeFour-arrows disabled-arrows" src="@/assets/img/edit/disabled-icon.svg" />
</div>
<div v-if="item.field == 'floor' && intermediary == 6" ref="floor" class="form-option modeSeven flexflex">
<div class="modeSeven-unlimited flexacenter">
<div class="modeSeven-unlimited-item flexacenter" @click="setValueMultiple('floor', [], true)">
<img v-show="info.floor.length == 0" class="modeSeven-unlimited-circle-pitch" src="@/assets/img/edit/circle-pitch.svg" alt="" />
<div v-show="info.floor.length != 0" class="modeSeven-unlimited-circle"></div>
不限
</div>
</div>
<div class="modeSeven-option-box flexflex">
<div class="modeSeven-option-item flexacenter" v-for="(item, index) in item.choices" :key="index" @click="setValueMultiple('floor', item.key)">
<img v-show="info.floor.includes(item.key)" class="modeSeven-option-icon" src="@/assets/img/edit/diamond-selected.svg" />
<img v-show="!info.floor.includes(item.key)" class="modeSeven-option-icon" src="@/assets/img/edit/diamond-unselected.svg" />
{{ item.value }}
</div>
</div>
</div>
<!-- 电梯 -->
<div v-if="item.field == 'elevator'" class="form-option modeThree flexacenter">
<div v-for="(item, index) in item.choices" :key="index" class="modeThree-item flexcenter" :class="{ pitch: info['elevator'] == item.key }" ref="elevator" @click="setValue('elevator', item.key)">{{ item.value }}</div>
</div>
<!-- 晾晒区 -->
<div v-if="item.field == 'sunshinearea' && intermediary != 6" class="form-option modeThree flexacenter">
<div v-for="(item, index) in item.choices" :key="index" class="modeThree-item flexcenter" :class="{ pitch: info['sunshinearea'] == item.key }" ref="sunshinearea" @click="setValue('sunshinearea', item.key)">{{ item.value }}</div>
</div>
<div v-if="item.field == 'sunshinearea' && intermediary == 6" class="form-option modeSeven flexflex">
<div class="modeSeven-unlimited flexacenter">
<div class="modeSeven-unlimited-item flexacenter" @click="setValueMultiple('sunshinearea', [], true)">
<img v-show="info.sunshinearea.length == 0" class="modeSeven-unlimited-circle-pitch" src="@/assets/img/edit/circle-pitch.svg" alt="" />
<div v-show="info.sunshinearea.length != 0" class="modeSeven-unlimited-circle"></div>
不限
</div>
</div>
<div class="modeSeven-option-box flexflex">
<div class="modeSeven-option-item flexacenter" v-for="(item, i) in item.choices" :key="i" @click="setValueMultiple('sunshinearea', item.key)">
<img v-show="info.sunshinearea.includes(item.key)" class="modeSeven-option-icon" src="@/assets/img/edit/diamond-selected.svg" />
<img v-show="!info.sunshinearea.includes(item.key)" class="modeSeven-option-icon" src="@/assets/img/edit/diamond-unselected.svg" />
{{ item.value }}
</div>
</div>
</div>
<!-- 面积 -->
<div v-if="item.field == 'acreage' && intermediary != 6" class="form-option modeFive flexacenter" ref="acreage">
<input class="modeFive-input flex1" v-model="info.acreage" type="number" step="1" min="0" placeholder="请输入数字" onkeyup="this.value= this.value.match(/\d+(\.\d{0,2})?/) ? this.value.match(/\d+(\.\d{0,2})?/)[0] : ''" />
<div class="modeFive-unit">{{ item.unit }}</div>
</div>
<div v-if="item.field == 'acreage' && intermediary == 6" ref="acreage" class="form-option modeSix flexacenter" :class="{ pitch: info.rent }">
<div class="modeSix-select flexacenter">
<el-select :style="{ opacity: acreage_min ? '0' : '1' }" v-model="acreage_min" placeholder="请选择" @visible-change="acreageDropDown">
<el-option v-for="item in 300" :key="(item - 1) * 10 + 10" :label="(item - 1) * 10 + 10" :value="(item - 1) * 10 + 10"> </el-option>
</el-select>
<!-- 特殊处理 需要计算 -->
<div v-if="acreage_min" class="modeSix-select-value flexacenter">
{{ acreage_min }}
<div class="modeSix-select-m">{{ (acreage_min * 0.09290304).toFixed(2) }}</div>
</div>
<img class="arrows-icon" src="@/assets/img/edit/arrows.svg" />
</div>
<div class="modeSix-tilde flexacenter">~</div>
<div class="modeSix-select flexacenter">
<el-select :style="{ opacity: acreage_max ? '0' : '1' }" v-model="acreage_max" placeholder="请选择" @visible-change="acreageDropDown">
<el-option v-for="item in 300" :key="(item - 1) * 10 + 10" :label="(item - 1) * 10 + 10" :value="(item - 1) * 10 + 10"> </el-option>
</el-select>
<!-- 特殊处理 需要计算 -->
<div v-if="acreage_max" class="modeSix-select-value flexacenter">
{{ acreage_max }}
<div class="modeSix-select-m">{{ (acreage_max * 0.09290304).toFixed(2) }}</div>
</div>
<img class="arrows-icon" src="@/assets/img/edit/arrows.svg" />
</div>
<div class="modeSix-unit">平方呎</div>
</div>
</div>
<div class="halving-line"></div>
<div class="form-item" v-for="item in fieldinfoAddress" :key="item.type">
<div class="form-title flexacenter" v-if="item.field != 'address' || (item.field == 'address' && info['location'])">
{{ item.title }}
<div class="asterisk" v-if="item.required === 1">*</div>
</div>
<!-- 所在区域 -->
<div class="form-option modeOne flexacenter" v-if="intermediary != 6 && item.field == 'location'">
<el-popover v-model:visible="areaPopState" placement="bottom" :width="640" :show-arrow="false" trigger="click" popper-style="padding:0; border-radius:16px !important;" :disabled="verified == 1">
<template #reference>
<div ref="location" class="modeOne-item flexacenter" :class="{ disabled: verified == 1 }" style="width: 640px">
<div class="modeOne-text flexacenter" v-if="info['location'] && info['location'] !== '0'">
{{ locationData[Math.floor(info.location)]?.name }}
<img class="form-arrows form-arrows-disabled" src="@/assets/img/edit/thin-arrow-disabled.svg" />
{{ locationData[Math.floor(info.location)]?.data[info.location] }}
</div>
<div class="modeOne-text flexacenter" style="color: #aaaaaa" v-else>请选择</div>
<img class="arrows-icon" src="@/assets/img/edit/arrows.svg" />
<img class="arrows-icon arrows-disabled-icon" style="transform: rotate(0)" src="@/assets/img/edit/disabled-icon.svg" />
<img class="arrows-icon-pitch" src="@/assets/img/edit/blue-arrow.svg" />
</div>
</template>
<div class="pop area-pop-box radius16" style="">
<div class="area-box flexflex" style="height: 100%">
<div class="area-left">
<div class="area-item flexacenter" :class="{ pitchpitch: index == locationValue }" v-for="(item, index) in locationData" :key="index" @click.stop="handleArea(index)">
<div class="dot"></div>
{{ item.name }}
<div class="semicircle-outside"></div>
</div>
</div>
<div class="area-right flex1 scrollbar">
<div class="area-item flexacenter" :class="{ pitchpitch: info['location'] == index }" v-for="(item, index) in locationData[locationValue].data" :key="index" @click.stop="handleArea(index, item)">
<div class="area-item-name">{{ item }}</div>
<img class="area-item-pitch" src="@/assets/img/edit/blue-tick.svg" />
</div>
</div>
</div>
</div>
</el-popover>
</div>
<!-- 地址 -->
<div class="form-option modeOne flexacenter" v-if="intermediary != 6 && item.field == 'address' && info['location']">
<div class="modeOne-item flexacenter" :class="{ disabled: verified == 1 && info['address'] }" style="width: 640px" @click="verified == 1 && info['address'] ? '' : handleLocationData()">
<div class="modeOne-text flexacenter" v-if="info['address']">{{ info["address"] }}</div>
<div class="modeOne-text flexacenter" v-else style="color: #aaaaaa">请选择</div>
<img class="arrows-icon" src="@/assets/img/edit/arrows.svg" style="transform: rotate(0)" />
<img class="arrows-icon-pitch" src="@/assets/img/edit/blue-arrow.svg" style="transform: rotate(0)" />
<img class="arrows-icon arrows-disabled-icon" style="transform: rotate(0)" src="@/assets/img/edit/disabled-icon.svg" />
</div>
</div>
<!-- 目标区域 - 无数据 -->
<div v-if="item.field == 'location' && intermediary == 6 && info.location.length == 0" ref="location" class="form-option target-area-box-no flexacenter" @click="targetAreaState = true">
<div class="target-area-text flexacenter" style="color: #aaaaaa">请选择</div>
<img class="arrows-icon" src="@/assets/img/edit/arrows.svg" />
</div>
<!-- 目标区域 - 有数据 -->
<div v-if="item.field == 'location' && intermediary == 6 && info.location.length != 0" ref="location" class="form-option flexacenter target-area-box" style="border-color: rgb(235, 235, 235)">
<div class="target-area-item flexacenter" v-for="(item, index) in info.location" :key="index">
<div class="target-area-item-index flexcenter">{{ index + 1 }}</div>
{{ locationObj[item >>> 0] }} > {{ item >>> 0 == item ? "不限" : locationObj[item] }}
<img class="target-area-cross" @click.stop="deleteTargetArea(index)" src="@/assets/img/edit/cross.svg" />
</div>
<div class="modification-btn flexcenter" @click="targetAreaState = true">重选</div>
</div>
</div>
<!-- 所属小区 -->
<div class="form-item" v-if="info['address'] && verified == 0">
<div class="form-title flexacenter">所属小区</div>
<div class="form-option modeOne flexacenter">
<el-popover v-model:visible="residentialAreaState" placement="bottom" :width="640" :show-arrow="false" trigger="focus" popper-style="padding:0; border-radius:16px;" :disabled="verified == 1" :teleported="false">
<template #reference>
<div ref="communityname" class="modeOne-item flexacenter" :class="{ disabled: verified == 1 }" style="width: 640px" @click="handleResidentialArea()" v-if="!isCommunityListNoData">
<div class="modeOne-text ellipsis flex1" v-if="info['communityname']" style="padding-right: 10px">{{ info.communityname }}</div>
<div class="modeOne-text flexacenter" style="color: #aaaaaa" v-else>请选择</div>
<img class="arrows-icon" src="@/assets/img/edit/arrows.svg" />
<img class="arrows-icon arrows-disabled-icon" src="@/assets/img/edit/disabled-icon.svg" />
<img class="arrows-icon-pitch" src="@/assets/img/edit/blue-arrow.svg" />
</div>
</template>
<div class="residential-area scrollbar">
<div class="residential-item flexacenter" v-for="item in communityList" :key="item.id" @click="clickResidentialArea(item.id, item.name)">
<div class="residential-dot"></div>
<div class="residential-text flex1 flexacenter" :class="{ pitchpitch: item.id == info['communityid'] }">
<div class="">{{ item.name }}</div>
<img class="arrows-icon rotate0" v-if="item.id == info['communityid']" src="@/assets/img/edit/blue-tick.svg" />
</div>
</div>
<div class="residential-item flexacenter">
<div class="residential-dot"></div>
<div class="residential-text flex1 flexacenter">以上都不是</div>
</div>
<div class="residential-item flexacenter">
<div class="residential-dot" style="background-color: transparent"></div>
<div class="residential-text residential-input flex1 flexflex" style="padding-right: 0">
<input class="flex1" maxlength="150" v-model="communitynameEle" placeholder="请填写小区名称" />
<div class="btn flexcenter" @click="communitynameEleOk">OK</div>
</div>
</div>
</div>
</el-popover>
<div v-if="isCommunityListNoData" ref="communityname" class="modeOne-item flexacenter" :class="{ pitch: info['communityname'], disabled: verified == 1 }" style="width: 640px; border-color: rgb(170, 170, 170)">
<input class="communityname-input" v-model="info.communityname" placeholder="请填写" />
</div>
</div>
</div>
<div class="halving-line"></div>
<div class="form-item" v-for="(item, index) in fieldinfoIdentity" :key="index">
<template v-if="item.field != 'intermediary' && judgeGenderCohabitantsShow(item.field)">
<div class="form-title flexacenter">
{{ item.title }}
<div class="asterisk" v-if="item.required === 1">*</div>
</div>
<!-- 租客性别要求 同住人性别要求 -->
<div v-if="item.field == 'gender'" class="form-option modeThree flexacenter">
<div v-for="(item, index) in item.choices" :key="index" ref="gender" class="modeThree-item flexcenter" :class="{ pitch: info['gender'] == item.key }" @click="setValue('gender', item.key)">{{ item.value }}</div>
</div>
<!-- 发布者性别 -->
<div v-if="item.field == 'publishergender'" class="form-option modeThree flexacenter">
<div v-for="(item, index) in item.choices" :key="index" ref="publishergender" class="modeThree-item flexcenter" :class="{ pitch: info['publishergender'] == item.key }" @click="setValue('publishergender', item.key)">{{ item.value }}</div>
</div>
</template>
</div>
<div class="halving-line"></div>
<template v-if="intermediary != 6">
<div class="form-item" v-for="item in fieldinfoUpload" :key="item.field">
<div class="form-title flexacenter">{{ item.title }} ({{ item.placeholder }})</div>
<!-- 视频 -->
<div class="media-box flexflex" v-if="item.field == 'video'">
<div class="media-item flexcenter" v-for="(item, index) in info.video" :key="index">
<img class="media-cross-icon" @click.stop="deleteMedia('video', index)" src="@/assets/img/edit/cross-icon.png" />
<div class="media-item-box flexcenter">
<video class="media-img" preload="metadata" :src="item.image" :autoplay="false"></video>
</div>
<img class="media-play-icon" src="@/assets/img/edit/play-icon.svg" />
</div>
<div class="media-item flexcenter" style="position: relative" v-if="info.video.length < videoConfig.maxcount">
<div class="media-item-box flexcenter">
<img class="media-add-icon" src="@/assets/img/edit/media-add.svg" />
<input class="input-file" type="file" accept="video/*" @change="validateVideoFileType($event, 'video')" multiple />
</div>
</div>
</div>
<!-- 照片 -->
<div class="media-box flexflex" v-if="item.field == 'images'" ref="images">
<div class="media-item flexcenter" :class="{ pitch: item['aid'] == info['aid'] }" v-for="(item, index) in info.images" :key="index">
<div class="media-item-box flexcenter">
<img class="media-cross-icon" @click.stop="deleteMedia('image', index)" src="@/assets/img/edit/cross-icon.png" />
<img class="media-img" :src="item.image" />
</div>
<div class="media-cover-bnt flexcenter" v-if="info.images.length != 1" @click="info['aid'] = item['aid']">{{ item["aid"] == info["aid"] ? "已" : "" }}选为封面</div>
</div>
<div class="media-item flexcenter" style="position: relative" v-if="info.images.length < imagesConfig.maxcount">
<div class="media-item-box flexcenter">
<img class="media-add-icon" src="@/assets/img/edit/media-add.svg" />
<input class="input-file" type="file" accept="image/*" @change="validateVideoFileType($event, 'image')" multiple />
</div>
</div>
</div>
</div>
<div class="halving-line"></div>
</template>
<div class="form-item" v-for="(item, index) in fieldinfoIntroduce" :key="index">
<div class="form-title flexacenter">
{{ item.title }}
<div class="asterisk" v-if="item.required == 1">*</div>
</div>
<!-- 更多介绍 -->
<template v-if="item['field'] == 'introduction'">
<div class="introduce-hint">{{ item.placeholder }}</div>
<div class="introduce-input" ref="introduction">
<el-input :autosize="true" type="textarea" placeholder="请输入" v-model="info.introduction" resize="none" maxlength="500"> </el-input>
<div class="residue">{{ info.introduction ? 500 - info.introduction.length : 500 }}</div>
</div>
</template>
</div>
<div class="halving-line"></div>
<div class="contact-hint flexacenter"><img class="contact-icon" src="@/assets/img/edit/star-icon.png" />请至少提供其中一项联系方式这是对方联系你的唯一途径.</div>
<div class="form-item" v-for="(item, index) in fieldinfoContact" :key="index">
<div class="form-title flexacenter">
{{ item.title }}
<div class="asterisk" v-if="item.required == 1">*</div>
<div class="how" v-if="item.field == 'wechat'" @click="howBoxState = true">如何获取二维码</div>
</div>
<div v-if="item.field == 'wechat'" class="" ref="wechat">
<div class="contact-QRcode-box flexcenter" v-if="info.wechatdata['image']">
<img class="contact-QRcode-img" :src="info.wechatdata['image']" />
</div>
<div class="wechat-btn flexcenter">
<img class="wechat-icon" src="@/assets/img/edit/uploading-icon.svg" />
{{ info.wechatdata["url"] ? "重新上传" : "上传二维码" }}
<input type="file" @change="convertToBase64" accept="image/*" />
</div>
</div>
<el-input v-if="item.field == 'whatsapp'" maxlength="50" class="relation-input" :placeholder="item.placeholder" v-model="info.whatsapp"></el-input>
<el-input v-if="item.field == 'tel'" maxlength="50" class="relation-input" :placeholder="item.placeholder" v-model="info.tel"> </el-input>
</div>
<div class="halving-line"></div>
<div class="form-item" v-for="(item, index) in fieldinfoInfo" :key="index">
<div class="form-title flexacenter">
{{ item.title }}
<div class="asterisk" v-if="item.required == 1">*</div>
</div>
<!-- 标题 -->
<template v-if="item['field'] == 'subject'">
<div class="subject-input" ref="subject">
<el-input type="textarea" :placeholder="item.placeholder" v-model="info.subject" resize="none" maxlength="80"> </el-input>
<div class="residue">{{ info.subject ? 80 - info.subject.length : 80 }}</div>
</div>
</template>
</div>
<div class="halving-line"></div>
<!-- 最后的提示信息 -->
<div class="hint-box flexcenter">
<img class="hint-icon" src="@/assets/img/edit/hint-icon.png" />
请按真实身份发布请勿发布非寄托官方群/代看房信息违规发布将被永久禁言感谢合作
</div>
<div class="submit-btn-box flexacenter">
<div class="submit-btn-item flexcenter save" @click="submit(0)" v-if="status != 1">保存并退出</div>
<div class="submit-btn-item flexcenter submit" @click="submit(1)">马上发布</div>
</div>
</div>
</div>
</div>
<!-- 目标区域 - 弹窗 -->
<div class="flexcenter pop-mask" @click="targetAreaState = false" v-if="targetAreaState">
<div class="pop area-pop-box radius16 target-area" @click.stop="">
<div class="area-pop-header">目标区域</div>
<div class="area-box flexflex">
<div class="target-area-left flex1 scrollbar">
<div class="target-area-item" v-for="(item, index) in locationData" :key="index">
<div class="target-area-head">{{ item.name }}</div>
<div class="box flexflex">
<div class="item flexcenter" :class="{ pitch: info['location'].includes(index) }" @click.stop="handleTargetArea(index)">不限</div>
<div class="item flexcenter" :class="{ pitch: info['location'].includes(i) }" v-for="(it, i) in item.data" :key="i" @click.stop="handleTargetArea(i)">{{ it }}</div>
</div>
</div>
</div>
<div class="target-area-right flexflex">
<div class="target-area-title">已选区域</div>
<div class="target-area-hint flexacenter">
已选
<div class="target-area-num">{{ info.location && info.location.length }}</div>
个目标区域最多可选择6个
</div>
<div class="flex1 pitch-box flexflex">
<div class="pitch-box-item flexacenter" v-for="(item, index) in info.location" :key="index">
<div class="pitch-box-index flexcenter">{{ index + 1 }}</div>
{{ locationObj[item >>> 0] }} > {{ item >>> 0 == item ? "不限" : locationObj[item] }}
<img class="pitch-box-cross" @click.stop="deleteTargetArea(index)" src="@/assets/img/edit/cross.svg" />
</div>
</div>
<div class="target-area-btn flexcenter" :class="{ pitch: info.location && info.location.length > 0 }" @click.stop="closeTargetArea">选好了</div>
</div>
</div>
</div>
</div>
<!-- 发布成功 -->
<div class="flexcenter pop-mask" v-if="succeedPopState == 1">
<div class="pop succeed-box shadow radius16 flexflex" :style="{ backgroundImage: `url(${require('@/assets/img/edit/succeed-pop-bj2.svg')})` }" @click.stop="">
<div class="pop-close" @click="skipDetails()" style="position: static">
<img class="pop-close" src="@/assets/img/edit/close-icon.svg" />
</div>
<div class="succeed-title flexacenter" style="margin-bottom: 95px"><img class="succeed-icon" src="@/assets/img/edit/successfully-ticked.png" />发布成功</div>
<div class="QRCode-box flexcenter">
<img class="QRCode-img" :src="qrcodeBase64" />
</div>
<div class="succeed-hint flexacenter">
绑定
<div class="bold">寄托港校租小程序</div>
解锁以下操作
</div>
<div class="succeed-hint-list">
<div class="succeed-hint-item"><img class="succeed-hint-icon" src="@/assets/img/edit/black-tick.svg" />网页版与小程序版实现数据同步</div>
<div class="succeed-hint-item"><img class="succeed-hint-icon" src="@/assets/img/edit/black-tick.svg" />使用小程序一键转发房源让更多人看到</div>
<div class="succeed-hint-item"><img class="succeed-hint-icon" src="@/assets/img/edit/black-tick.svg" />随时随地使用小程序发布和管理房源</div>
</div>
<div class="succeed-examine" @click="skipDetails()">查看刚刚发布的{{ intermediary == 6 ? "" : "" }}房源</div>
</div>
</div>
<div class="flexcenter pop-mask" v-if="succeedPopState == 2">
<div class="pop succeed-box shadow radius16 flexflex" style="padding-bottom: 99px" @click.stop="">
<div class="pop-close" @click="skipDetails()" style="position: static">
<img class="pop-close" src="@/assets/img/edit/close-icon.svg" />
</div>
<div class="succeed-title flexacenter"><img class="succeed-icon" src="@/assets/img/edit/successfully-ticked.png" />发布成功</div>
<div class="QRCode-box flexcenter">
<img class="QRCode-img" :src="qrcodeBase64" />
</div>
<div class="succeed-hint flexacenter" style="margin-bottom: 58px">
欢迎使用
<div class="bold">寄托港校租小程序</div>
</div>
<div class="succeed-examine" @click="skipDetails()">查看刚刚发布的求房源</div>
</div>
</div>
<div class="flexcenter pop-mask" v-if="succeedPopState == 3">
<div class="pop succeed-box shadow radius16 flexflex" style="padding-bottom: 99px" @click.stop="">
<div class="pop-close" @click="skipDetails()" style="position: static">
<img class="pop-close" src="@/assets/img/edit/close-icon.svg" />
</div>
<div class="succeed-title flexacenter"><img class="succeed-icon" src="@/assets/img/edit/successfully-ticked.png" />发布成功</div>
<div class="QRCode-box flexcenter">
<img class="QRCode-img" :src="qrcodeBase64" />
</div>
<div class="succeed-hint flexacenter" style="margin-bottom: 29px">
欢迎使用
<div class="bold">寄托港校租小程序</div>
</div>
<div class="succeed-examine" style="margin-bottom: 29px" @click="skipUser()">管理我的房源</div>
<div class="succeed-examine" @click="skipDetails()">查看刚刚发布的求房源</div>
</div>
<div v-if="false" class="pop succeed-box shadow radius16 flexflex" style="padding-bottom: 58px" :style="{ backgroundImage: `url(${require('@/assets/img/edit/succeed-pop-bj1.svg')})` }" @click.stop="">
<div class="pop-close" @click="skipDetails()" style="position: static">
<img class="pop-close" src="@/assets/img/edit/close-icon.svg" />
</div>
<div class="succeed-title flexacenter"><img class="succeed-icon" src="@/assets/img/edit/successfully-ticked.png" />发布成功</div>
<div class="QRCode-box flexcenter">
<img class="QRCode-img" :src="qrcodeBase64" />
</div>
<div class="succeed-hint flexacenter" style="margin-bottom: 27px">
欢迎使用
<div class="bold">寄托港校租小程序</div>
</div>
<div class="personage-hint-list" style="margin-bottom: 40px">
<!-- <div class="personage-hint-item">一键顶上去让房源马上靠前</div>
<div class="personage-hint-item">一键切换房源上架/下架状态</div>
<div class="personage-hint-item">做房源认证不占用普通房源发布数</div> -->
<!-- <div class="personage-hint-item"></div> -->
<div class="succeed-examine">管理我的房源</div>
</div>
<div class="succeed-examine" @click="skipDetails()">查看刚刚发布的{{ intermediary == 6 ? "" : "" }}房源</div>
</div>
</div>
<!-- 提交失败 -->
<fail-pop @close="failPopState = false" :failPopState="failPopState"></fail-pop>
<!-- 了解更多弹窗 -->
<about-pop :popState="aboutPopState" :intermediary="intermediary" @close="handleAboutPopState"></about-pop>
<!-- 页面底部 -->
<page-footer></page-footer>
<!-- 如何获取微信二维码 -->
<how :howBoxState="howBoxState" @close="howBoxState = false"></how>
</template>
<script>
import aboutPop from "@/components/edit/about-pop.vue";
import mapComponent from "@/components/edit/map.vue";
import pageFooter from "@/components/footer/footer.vue";
import how from "@/components/edit/how-pop.vue";
import failPop from "@/components/edit/fail-pop.vue";
// import headerNav from '@/components/public/head.vue'
import pageTopBar from "@/components/pageTopBar/pageTopBar.vue";
import userBox from "@/components/edit/user-box.vue";
import { setSeoTitle } from "@/utils/util.js";
import zhCn from "element-plus/dist/locale/zh-cn.mjs";
import { inject } from "vue";
export default {
name: "ZufangEdit",
data() {
return {
pickerOptions: {
disabledDate: () => false,
},
locale: zhCn,
value: "",
user: {},
userIntermediary: 0, // 用户是否是 认证中介,需要全局获取
allowpublishednum: 0,
fieldinfo: {}, // 字段配置
fieldinfoBasic: [],
locationObj: {},
fieldinfoAddress: [],
fieldinfoIdentity: [],
fieldinfoIntroduce: [],
fieldinfoContact: [],
fieldinfoUpload: [],
fieldinfoInfo: [],
info: {},
uniqid: "",
token: "",
status: 0, // 发布 状态
intermediary: 3,
type: "", // 编辑类型
locationData: [],
locationValue: 1,
rentaldurationObj: [], // 起租日期的配置数据
typeData: [], // 单独拿出 第一步 的出租类型的数据
typeValue: 0, // 出租类型的临时值
typeValueUltimately: "", // 出租类型的最终值
typePopState: false, // 出租类型的弹窗状态
rentaldurationPopState: false, // 出租时长的弹窗状态
areaPopState: false, // 所在区域的弹窗状态
base64: "",
videoConfig: {
// 上传的文件配置
maxcount: 3, // 最大的文件数量
maxFileSize: 25 * 1024 * 1024, // 单位是字节
},
isformat: false, // 是否有格式问题
isMax: false, // 是否有大小问题
imagesConfig: {
// 上传的文件配置
maxcount: 9, // 最大的文件数量
maxFileSize: 5 * 1024 * 1024, // 单位是字节
},
mediaUploadIndex: 0, // 媒体上传的下标
selectedFiles: [], // 选中的文件
watchInfo: null, // 开启 info 监听
rent_min: null,
rent_max: null,
acreage_min: null,
acreage_max: null,
targetAreaState: false, // 目标区域弹窗的状态
howBoxState: false, // 如何获取微信二维码弹窗状态
succeedPopState: 0, // 1 是发布成功未绑定 2 是绑定 求房源 3 是绑定 个人、中介
failPopState: false, // 失败弹窗
aboutPopState: false, // 关于弹窗的展开状态
submitState: false, // 发布提交接口请求状态
isbindweixin: 0, // 是否绑定微信
mapComponentState: false, // 选择地址 的地图 弹窗状态
id: 0,
offshelftime: "",
offshelftime: "",
updatetime: "",
residentialAreaState: false, // 所属小区的弹窗的状态
isResidentialAreaUpdate: true, // 所属小区的数据是否需要更新
communityList: [], // 所属小区的列表
qrcodeBase64: "", // 提交发布后的二维码
skipUrl: "",
verified: 0, // 房源是否已经验证
rentaldurationTwoState: false, // 出租时长的二级显示状态
leasetimeTwoState: false, // 起租日期的二级显示状态
leasetimePopState: false, // 起租日期的弹窗状态
isCommunityListNoData: false, // 所属小区请求后是否是没有数据
communitynameEle: "", // 其他小区名称
loading: null, // 加载
uploadData: "", // 上传时 加入的
realname: 1,
uConfigData: {},
uQrcodeConfigData: {},
};
},
mounted() {
// 访问URL中的查询参数
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
this.uniqid = urlParams.get("uniqid");
this.token = urlParams.get("token");
this.intermediary = urlParams.get("intermediary") || 3; // 默认写房东吧
// this.verified = urlParams.get('verified') || 0;
this.userIntermediary = this.$store.state.user["intermediary"];
// https://api.gter.net/v1/config/upload?type=
this.init();
this.uploadConfig();
this.uploadQrcodeConfig();
},
components: {
aboutPop,
mapComponent,
pageFooter,
how,
failPop,
// headerNav,
pageTopBar,
userBox,
},
watch: {
targetAreaState(newVal) {
if (newVal) document.body.style.overflow = "hidden";
else document.body.style.overflow = "unset";
},
},
methods: {
require(url) {
return require(url);
},
init() {
this.loading = this.$loading({
lock: true,
text: "Loading",
background: "rgba(0, 0, 0, 0.7)",
});
this.$post("/tenement/pc/api/publish", {
intermediary: this.intermediary,
token: this.token,
uniqid: this.uniqid,
})
.then((res) => {
if (res.code !== 200) {
this.$message.error(res.message);
return;
}
let data = res.data;
let fieldinfo = data.fieldinfo;
let typeData = [];
let locationData = [];
let rentaldurationData = [];
for (const key in fieldinfo) {
fieldinfo[key].forEach((element) => {
if (element["field"] == "type") typeData = element["choices"] || [];
if (element["field"] == "location") locationData = element["choices"] || [];
if (element["field"] == "rentalduration") rentaldurationData = element["choices"];
});
}
let locationObj = {};
locationData.forEach((element) => {
locationObj[element["key"]] = element["value"];
});
this.locationObj = locationObj;
typeData = typeData.reduce(function (acc, item) {
var mainKey = item.key.split(".")[0];
var existingObj = acc[mainKey];
if (existingObj) existingObj.data.push(item);
else {
acc[mainKey] = {
name: item.value,
data: [],
};
}
return acc;
}, {});
locationData = locationData.reduce(function (acc, item) {
var mainKey = item.key.split(".")[0];
var existingObj = acc[mainKey];
if (existingObj) existingObj.data[item.key] = item.value;
else {
acc[mainKey] = {
name: item.value,
data: {},
};
}
return acc;
}, {});
let rentaldurationObj = {};
rentaldurationObj = rentaldurationData.reduce(function (acc, item) {
acc[item.key] = item.value;
return acc;
}, {});
rentaldurationObj[0] = "不限";
let info = data.info;
if (info["type"]) this.typeValue = info["type"] >>> 0;
let intermediary = data.intermediary;
if (data["type"] == "edit") {
if (!info["rentalduration"]) info["rentalduration"] = 0;
if (info["rentalduration"] != null && info["rentalduration"] != 0) this.rentaldurationTwoState = true;
if (info["leasetime"] != null && info["leasetime"] != 0) this.leasetimeTwoState = true;
if (info["communityname"] && info["communityid"] == 0) this.communitynameEle = info["communityname"];
}
if (intermediary == 6) {
if (info["rent"].length != 0) {
this.rent_min = info["rent"][0] ? Number(info["rent"][0]) : null;
this.rent_max = info["rent"][1] ? Number(info["rent"][1]) : null;
}
if (info["acreage"].length != 0) {
this.acreage_min = info["acreage"][0] ? Number(info["acreage"][0]) : null;
this.acreage_max = info["acreage"][0] ? Number(info["acreage"][1]) : null;
}
if (info["rentalduration"]) info["rentalduration"] = Number(info["rentalduration"]);
let arr = ["property", "floor", "sunshinearea"];
arr.forEach((element) => {
if (info[element] && info[element].length == 1 && info[element][0] == 0) info[element] = [];
if (info[element] && info[element].length != 0) {
info[element].forEach((ele, i) => {
info[element][i] = Number(ele);
});
}
});
} else {
if (info["floor"]) info["floor"] = Number(info["floor"]);
if (info["rentalduration"]) info["rentalduration"] = Number(info["rentalduration"]);
}
this.fieldinfo = fieldinfo;
this.typeData = typeData;
this.locationData = locationData;
this.rentaldurationObj = rentaldurationObj;
this.fieldinfoBasic = fieldinfo.basic;
this.fieldinfoAddress = fieldinfo.address;
this.fieldinfoIntroduce = fieldinfo.introduce;
this.fieldinfoUpload = fieldinfo.upload;
this.fieldinfoContact = fieldinfo.contact;
this.fieldinfoInfo = fieldinfo.info;
this.uploadData = data.uploadData;
this.fieldinfoBasic.forEach((element) => {
if (element["field"] == "type" && info["type"]) {
element["choices"].forEach((ele) => {
if (ele["key"] == info["type"]) this.typeValueUltimately = ele["value"];
});
}
});
this.info = info;
this.verified = data.verified;
// this.verified = 1
this.fieldinfoIdentity = fieldinfo.identity;
this.intermediary = intermediary;
this.status = data.status;
this.token = data.token;
this.type = data.type;
this.allowpublishednum = data.allowpublishednum;
this.user = data.user;
this.isbindweixin = data.isbindweixin;
this.id = data.id;
this.timestamp = data.timestamp;
this.offshelftime = data.offshelftime;
this.updatetime = data.updatetime;
let title = "";
if (data["type"] == "edit") title += "编辑";
else title += "发布";
if (intermediary == 6) title += "求房源";
else if (intermediary == 1) title += "中介房源";
else title += "个人房源";
setSeoTitle(title);
})
.catch((err) => {})
.finally((err) => {
this.loading.close();
});
},
// 处理出租方式
handleType(key, value) {
if (key >>> 0 == key) {
this.typeValue = key;
if (this.info["type"] >>> 0 != key) this.info["type"] = null;
} else {
this.info["type"] = key;
this.typeValueUltimately = value;
}
},
// 直接修改值
setValue(key, value) {
this.info[key] = value;
},
// 修改值多选的
setValueMultiple(key, value, isunlimited) {
if (isunlimited) this.info[key] = value;
else {
if (this.info[key].indexOf(value) != -1) this.info[key].splice(this.info[key].indexOf(value), 1);
else this.info[key].push(value);
}
},
// 处理所在区域的 左边 按钮
handleArea(key, value) {
if (key >>> 0 == key) {
this.locationValue = key;
} else {
this.info["location"] = key;
this.areaPopState = false;
}
},
// 将获取到的二维码转base64
convertToBase64(event) {
let type = event.target.files[0].type || "";
if (type.indexOf("image") == -1) {
this.$message.error("请上传图片");
return;
}
const file = event.target.files[0];
if (file["size"] / 1024 / 1024 > 10) {
this.$message.error("请大小小于10M");
return;
}
event.target.value = ""; // 去除值 使用户可以选中同一个
this.uploadQRCode(file);
// const formData = new FormData()
// formData.append("file", file)
return;
const reader = new FileReader();
reader.onload = () => {
const base64Image = e.target.result;
return;
this.myImage = reader.result;
const image = new Image();
image.onload = () => {
const canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
const context = canvas.getContext("2d");
context.drawImage(image, 0, 0);
const base64 = canvas.toDataURL();
this.base64 = base64;
this.uploadQRCode(base64);
this.loading = this.$loading({
lock: true,
text: "Loading",
background: "rgba(0, 0, 0, 0.7)",
});
};
image.src = this.myImage;
};
reader.readAsDataURL(file);
},
// 开始上传二维码
uploadQRCode(file) {
let config = this.uQrcodeConfigData;
const formData = new FormData();
formData.append(config.requestName, file); // 文件数据
formData.append("name", file.name); // 文件名
formData.append("type", "image"); // 文件名
formData.append("data", config.params.data); // 文件名
this.$axios
.post(config.url, formData)
.then((res) => {
res = res.data; //
this.loading.close();
if (res.code != 200) {
this.$message.error(res.message);
return;
}
this.info["wechatdata"] = res.data;
this.$message.success("上传成功!!!");
})
.catch((err) => {
err = err.data;
this.loading.close();
this.$message.error(err.message);
});
},
// 处理获取到的视频文件
validateVideoFileType(event, type) {
let files = event.target.files;
this.selectedFiles = files;
this.mediaUploadIndex = 0;
this.combingMedia(type);
event.target.value = ""; // 去除值 使用户可以选中同一个
},
// 梳理媒体的 格式
combingMedia(type) {
let target = this.selectedFiles[this.mediaUploadIndex];
if (!target) {
this.finallyHint();
return;
}
let allowedExtensions = ["mp4", "webm", "ogg"];
type == "image" ? (allowedExtensions = ["svg", "jpg", "jpeg", "png", "bmp", "webp"]) : "";
const fileExtension = target.name.split(".").pop().toLowerCase();
const isValidFile = allowedExtensions.includes(fileExtension);
if (!isValidFile) {
this.isformat = true;
this.mediaUploadIndex += 1;
this.combingMedia(type);
return;
}
if (target.size > this.videoConfig.maxFileSize) {
this.isMax = true;
this.mediaUploadIndex += 1;
this.combingMedia(type);
return;
}
if (type == "video" && this.info.video.length >= this.videoConfig.maxcount) {
this.finallyHint(type);
return;
} else if (type == "image" && this.info.images.length >= this.imagesConfig.maxcount) {
this.finallyHint(type);
return;
}
this.uploadVideo(type, target);
},
// 上传视频 和 图片
uploadVideo(type, target) {
let config = this.uConfigData;
const formData = new FormData();
formData.append(config.requestName, target); // 文件数据
formData.append("name", target.name); // 文件名
formData.append("type", type); // 文件名
formData.append("data", config.params.data); // 文件名
// this.$axios.post('/tenement/pc/api/publish/upload', formData).then(res => {
this.$axios
.post(config.url, formData)
.then((res) => {
res = res["data"];
if (res.code != 200) {
this.$message.error(res.message);
this.mediaUploadIndex += 1;
this.combingMedia(type);
return;
}
let data = res.data;
let obj = {
aid: data.aid,
image: data.url,
};
if (type == "video") this.info.video.push(obj);
else this.info.images.push(obj);
this.mediaUploadIndex += 1;
this.combingMedia(type);
})
.catch((error) => {
this.$message.error(`上传出错:${error.message}`);
});
},
// 删除媒体数据
deleteMedia(type, index) {
if (type == "video") this.info.video.splice(index, 1);
else this.info.images.splice(index, 1);
},
// 最后的提示
finallyHint(type) {
if (this.isformat) this.$message.error(`上传文件后缀不允许`);
if (this.isMax) this.$message.error(`上传文件大小不符!`);
this.isformat = false;
this.isMax = false;
},
// 提交
submit(status = 0) {
if (status == 1 && this.$store.state.realname == 0 && this.$store.state.userInfoWin?.uin > 0) this.$store.commit("openAttest");
let info = { ...this.info };
if (info["images"] && info["images"].length > 1 && !info["aid"]) {
this.$message.error("请选择封面");
let data = {
field: "images",
};
this.handleSubmitFailure(data);
return;
}
if (this.acreage_min) info["acreage"] = [this.acreage_min, this.acreage_max];
if (info["wechatdata"] && info["wechatdata"]["url"]) info["iswechattype"] = 2;
if (this.submitState) return;
this.submitState = true;
this.loading = this.$loading({
lock: true,
text: "Loading",
background: "rgba(0, 0, 0, 0.7)",
});
let intermediary = this.intermediary;
info["intermediary"] = intermediary;
if (intermediary == 6) {
if (this.rent_min) {
let rent = [this.rent_min, this.rent_max];
rent.sort();
info["rent"] = rent;
}
let arr = ["property", "floor", "sunshinearea"];
arr.forEach((element) => {
if (info[element] && info[element].length == 0) info[element] = [0];
});
}
this.$post("/tenement/pc/api/publish/submit", {
token: this.token,
info,
status,
})
.then((res) => {
let data = res.data || [];
if (res.code != 200) {
let rule = data["rule"] || 0;
this.$message.error(res.message);
if (rule == 3) {
this.failPopState = true;
return;
}
this.handleSubmitFailure(data);
return;
} else {
if (status == 0) {
this.$router.push("/user");
return;
}
this.qrcodeBase64 = data["qrcode"];
this.skipUrl = data["url"];
this.uniqid = data["uniqid"];
if (this.isbindweixin != 1) this.succeedPopState = 1;
else {
if (intermediary == 6) this.succeedPopState = 2;
else this.succeedPopState = 3;
}
}
this.$message.success(res.message);
})
.finally(() => {
this.loading.close();
this.submitState = false;
});
},
// 处理提交失败后的滚动和监听数据
handleSubmitFailure(data) {
// 获取 myRef 元素的位置信息
let targetElement = this.$refs[data.field];
if (!targetElement) return;
if (Array.isArray(targetElement)) {
targetElement.forEach((element) => {
element.style.borderColor = "rgba(249, 93, 93, 1)";
});
} else targetElement.style.borderColor = "rgba(249, 93, 93, 1)";
this.$watch(`info.${data.field}`, (newVal, oldVal) => {
if (newVal != null && newVal != undefined) {
if (Array.isArray(targetElement)) {
targetElement.forEach((element) => {
element.style.borderColor = "#aaaaaa";
});
} else targetElement.style.borderColor = "#aaaaaa";
}
});
// 设置滚动距离
let top = 0;
if (Array.isArray(targetElement)) top = targetElement[0].getBoundingClientRect().top + window.pageYOffset;
else top = targetElement.getBoundingClientRect().top + window.pageYOffsetp;
if (top) top -= 150;
else top = 300;
window.scrollTo({
top,
behavior: "smooth",
});
},
// 租金预算的 下拉框 展开隐藏事件
rentDropDown(callback) {
if (!callback || this.rent_min) return;
this.rent_min = 6000;
this.rent_max = 9000;
},
// 面积的 下拉框 展开隐藏事件
acreageDropDown(callback) {
if (!callback || this.acreage_min) return;
this.acreage_min = 10;
this.acreage_max = 3000;
},
// 这个专门处理 目标 选择
handleTargetArea(key) {
// 是否是 不限
let location = this.info.location;
let index = location.indexOf(key.toString());
// 存在的
if (index != -1) location.splice(index, 1);
else {
// 点击不限的
if (key >>> 0 == key) location = location.filter((item) => item && !item.startsWith(key.toString()));
else if (key >>> 0 != key && location.indexOf((key >>> 0).toString()) != -1) location.splice(location.indexOf((key >>> 0).toString()), 1);
location.push(key);
}
if (location.length > 6) location = location.slice(0, 6);
this.info.location = location;
},
// 删除已选目标区域
deleteTargetArea(index) {
let location = this.info.location;
location.splice(index, 1);
this.info.location = location;
},
// 关闭目标区域
closeTargetArea() {
if (this.info.location.length == 0) return;
this.targetAreaState = false;
},
// 处理关于弹窗状态
handleAboutPopState() {
this.aboutPopState = !this.aboutPopState;
},
// 点击选择地址弹窗 处理经纬度
handleLocationData() {
this.mapComponentState = true;
},
// 选择地点后
choosingLocation(value) {
if (!value) {
this.mapComponentState = false;
return;
}
let info = this.info;
info["address"] = value["poiname"];
info["latitude"] = value["latlng"]["lat"];
info["longitude"] = value["latlng"]["lng"];
this.mapComponentState = false;
this.isResidentialAreaUpdate = true;
},
// 初始化时判断所属小区是否需要获取列表
// 处理所属小区判断,并获取数据
handleResidentialArea() {
if (this.isResidentialAreaUpdate) {
let info = this.info;
let location = `${info["longitude"] || 114.160151},${info["latitu1de"] || 22.247117}`;
this.$post("/tenement/pc/api/publish/placeAround", {
location,
}).then((res) => {
if (res.code != 200) {
this.isCommunityListNoData = true;
this.$forceUpdate();
return;
}
let data = res.data;
this.communityList = data;
this.isResidentialAreaUpdate = false;
this.$nextTick(() => {
this.residentialAreaState = true;
});
});
} else this.residentialAreaState = true;
if (!this.info.communityid) this.communitynameEle = this.info.communityname;
},
// 点击所属小区选项
clickResidentialArea(id, name) {
let info = this.info;
info["communityid"] = id;
info["communityname"] = name;
this.communitynameEle = "";
this.info = info;
this.residentialAreaState = false;
},
// 判断 求房源的 同住人性别要求应不应该显示
judgeGenderCohabitantsShow(field) {
let type = this.info["type"];
let intermediary = this.intermediary;
if (intermediary != 6 || field != "gender") return true;
if (type >>> 0 == 1 && field == "gender") return true;
return false;
},
// 跳转
skipDetails() {
this.$router.push(`/detail?id=${this.uniqid}`);
},
skipUser() {
this.$router.push(`/user?tab=publish`);
},
// 起租日期的不选中判断
disabledDate(date) {
var currentDate = new Date();
currentDate.setDate(currentDate.getDate() - 1);
// 获取两年后的日期
var twoYearsLater = new Date(currentDate.getFullYear() + 2, currentDate.getMonth(), currentDate.getDate());
// 比较给定的日期是否在两年后之后
if (date > twoYearsLater) return true; // 返回 true 表示日期被禁用
if (date < currentDate) return true; // 返回 true 表示日期被禁用
return false; // 返回 false 表示日期未被禁用
},
// 其他所属小区的 其他按钮
communitynameEleOk() {
if (this.communitynameEle) {
this.info["communityid"] = 0;
this.info["communityname"] = this.communitynameEle;
}
this.residentialAreaState = false;
this.communitynameEle = "";
},
uploadConfig() {
this.$post("https://api.gter.net/v1/config/upload?type=tenement").then((res) => {
let data = res.data;
this.uConfigData = data;
});
},
uploadQrcodeConfig() {
this.$post("https://api.gter.net/v1/config/upload?type=qrcode").then((res) => {
let data = res.data;
this.uQrcodeConfigData = data;
});
},
},
};
</script>
<style lang="less" scoped>
.content-box {
width: 1200px;
margin: -36px auto 50px;
align-items: flex-start;
position: relative;
font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif;
.wid640 {
width: 640px !important;
}
.form-box {
background-color: #fff;
border: 1px solid rgba(235, 235, 235, 1);
.form-header {
color: #000;
font-size: 20px;
font-weight: 650;
padding: 36px 47px 25px;
border-bottom: 1px solid #ebebeb;
}
.form-boxes {
padding-bottom: 80px;
.halving-line {
width: 100%;
height: 1px;
border-bottom: 1px solid #ebebeb;
margin-top: 34px;
}
.arrows-icon,
.arrows-icon-pitch {
width: 14px;
height: 14px;
transform: rotate(90deg);
}
.arrows-icon-pitch,
.arrows-disabled-icon {
display: none;
}
.form-item {
margin-top: 31px;
margin-bottom: 10px;
padding-left: 48px;
.form-title {
font-size: 16px;
line-height: 30px;
height: 34px;
color: #555;
margin-bottom: 10px;
position: relative;
width: 640px;
.asterisk {
color: #f95d5d;
margin-left: 5px;
}
.how {
position: absolute;
right: 0;
font-size: 14px;
line-height: 30px;
color: #50e3c2;
cursor: pointer;
&:hover {
color: rgb(71, 202, 170);
}
}
}
.form-option {
width: 100%;
height: 50px;
position: relative;
.pitch {
color: #62b1ff !important;
border: 1px solid rgba(98, 177, 255, 1) !important;
.arrows-icon {
display: none;
}
.arrows-icon-pitch {
display: block;
}
.el-input__inner {
color: #62b1ff !important;
}
}
/deep/ .el-input__wrapper:hover,
/deep/ .el-input .el-input__wrapper,
/deep/ .el-input.is-focus .el-input__wrapper {
box-shadow: none !important;
}
/deep/ .el-input__suffix {
display: none;
}
/deep/ .select-trigger,
/deep/ .el-input {
font-size: 16px;
height: 100%;
}
/deep/ .el-input__inner {
border: none;
height: 100%;
}
&.modeOne {
.modeOne-item {
width: 310px;
height: 50px;
border-radius: 10px;
border: 1px solid rgba(235, 235, 235, 1);
margin-right: 20px;
font-size: 16px;
color: #555;
padding: 0 20px;
justify-content: space-between;
cursor: pointer;
&:hover {
border-color: #aaa;
}
&:last-of-type {
margin-right: 0;
}
.arrows-icon,
.arrows-icon-pitch {
transform: rotate(90deg);
}
&.disabled {
color: #aaaaaa !important;
border-color: rgba(170, 170, 170, 1) !important;
background-color: rgba(246, 246, 246, 1) !important;
cursor: no-drop;
.form-arrows {
display: none;
}
.arrows-icon,
.arrows-icon-pitch {
display: none;
}
.form-arrows-disabled,
.arrows-disabled-icon {
display: block;
}
}
}
}
&.modeTwo {
.modeTwo-item {
width: 310px;
height: 50px;
border-radius: 10px;
border: 1px solid rgba(235, 235, 235, 1);
margin-right: 20px;
font-size: 16px;
color: #555;
padding: 0 20px;
cursor: pointer;
&.pitch {
/deep/ .el-input {
.el-input__inner {
color: #62b1ff;
}
}
}
.el-icon-date:before {
content: "";
}
.modeTwo-select {
height: 100%;
}
/deep/ .el-input {
flex: 1;
width: 100%;
height: 100%;
.el-input__prefix {
display: none;
}
.el-input__wrapper,
.el-input__inner {
height: 100%;
border: none;
font-size: 16px;
color: #555;
// color: #62B1FF;
padding-left: 0;
/* 修改 FireFox 内核浏览器的输入框提示文本样式 */
&:-moz-placeholder,
&::-webkit-input-placeholder {
color: #555;
}
/* 修改旧版 FireFox 浏览器的输入框提示文本样式 */
&::-moz-placeholder {
color: #555;
opacity: 1;
}
&::placeholder {
color: #555;
opacity: 1;
}
}
}
&:last-of-type {
margin-right: 0;
}
}
}
&.modeThree {
flex-wrap: wrap;
height: auto;
.modeThree-item {
width: 150px;
height: 50px;
border-radius: 10px;
border: 1px solid rgba(235, 235, 235, 1);
margin-right: 20px;
font-size: 16px;
color: #555;
cursor: pointer;
margin-bottom: 10px;
&:hover {
border-color: rgba(170, 170, 170, 1);
}
&:nth-last-child(-n + 3) {
margin-bottom: 0;
}
&.noChoice {
cursor: no-drop;
color: #d7d7d7;
border: 1px solid rgba(235, 235, 235, 1);
}
}
}
&.modeFour {
width: 640px;
border: 1px solid #ebebeb;
border-radius: 10px;
overflow: hidden;
&:hover {
border-color: #aaa;
}
.modeFour-select {
height: 100%;
/deep/ .el-input__wrapper:hover,
/deep/ .el-input.is-focus .el-input__wrapper {
box-shadow: none !important;
}
/deep/ .el-input__suffix {
display: none;
}
/deep/ .select-trigger,
/deep/ .el-input {
font-size: 16px;
height: 100%;
}
/deep/ .el-input__inner {
border: none;
height: 100%;
}
}
.modeFour-arrows {
width: 14px;
height: 14px;
margin-right: 20px;
transform: rotate(90deg);
}
.disabled-arrows {
display: none;
}
&.disabled {
border-color: rgba(170, 170, 170, 1);
background-color: rgba(246, 246, 246, 1);
.modeFour-arrows {
display: none;
}
.disabled-arrows {
display: block;
transform: rotate(0);
}
}
}
&.modeFive {
border: 1px solid rgba(170, 170, 170, 1);
border-radius: 10px;
padding: 0 20px;
width: 640px;
.modeFive-input {
height: 100%;
font-size: 16px;
border: none;
outline: none;
}
.modeFive-unit {
color: #000;
font-size: 16px;
}
}
&.modeSix {
.modeSix-select {
border: 1px solid rgba(170, 170, 170, 1);
border-radius: 10px;
overflow: hidden;
width: 269px;
height: 50px;
position: relative;
.el-select {
width: 100%;
height: 100%;
position: relative;
z-index: 1;
.el-input {
height: 100%;
.el-input__inner {
border: none;
height: 100%;
color: #000;
font-size: 16px;
}
.el-input__suffix {
display: none;
}
}
}
.arrows-icon {
margin-right: 20px;
transform: rotate(90deg);
}
}
.modeSix-select-value {
position: absolute;
top: 50%;
left: 15px;
transform: translateY(-50%);
.modeSix-select-m {
color: #aaa;
}
}
.modeSix-tilde {
color: #555;
font-size: 20px;
margin: 0 13px;
}
.modeSix-unit {
margin-left: 11px;
color: #000000;
font-size: 16px;
}
}
&.modeSeven {
border-radius: 10px;
width: 640px;
font-size: 16px;
color: #000;
border: 1px solid rgba(235, 235, 235, 1);
flex-direction: column;
height: 100%;
.modeSeven-unlimited {
height: 60px;
padding-left: 20px;
border-bottom: 1px solid #ebebeb;
.modeSeven-unlimited-item {
cursor: pointer;
.modeSeven-unlimited-circle {
border-radius: 50%;
width: 20px;
height: 20px;
border: 2px solid #d7d7d7;
margin-right: 10px;
}
.modeSeven-unlimited-circle-pitch {
width: 20px;
height: 20px;
margin-right: 10px;
}
}
}
.modeSeven-option-box {
padding: 20px;
flex-wrap: wrap;
align-items: flex-start;
.modeSeven-option-item {
&:not(:last-child):not(:nth-last-child(-n + 4)) {
margin-bottom: 22px;
}
cursor: pointer;
width: 149px;
.modeSeven-option-icon {
width: 20px;
height: 20px;
margin-right: 10px;
}
}
}
}
&.target-area-box {
flex-direction: column;
width: 640px;
height: auto;
border-radius: 10px;
border: 1px solid rgba(235, 235, 235, 1);
align-items: flex-start;
font-size: 14px;
color: #000;
padding-left: 20px;
padding-top: 30px;
padding-bottom: 30px;
position: relative;
.modification-btn {
width: 80px;
height: 32px;
background: inherit;
background-color: rgba(51, 51, 51, 1);
border-radius: 200px;
font-size: 14px;
position: absolute;
bottom: 30px;
right: 20px;
color: #fff;
cursor: pointer;
}
.target-area-item {
margin-bottom: 20px;
&:last-of-type {
margin-bottom: 0;
}
.target-area-item-index {
width: 20px;
height: 20px;
font-size: 14px;
color: #62b1ff;
border-radius: 50%;
border: 1px solid #62b1ff;
margin-right: 10px;
}
.target-area-cross {
width: 12px;
height: 12px;
margin-left: 20px;
cursor: pointer;
}
}
}
&.target-area-box-no {
width: 640px;
height: 50px;
border: 1px solid #aaaaaa;
border-radius: 10px;
justify-content: space-between;
padding-left: 15px;
cursor: pointer;
.arrows-icon {
margin-right: 20px;
transform: rotate(90deg);
}
}
.communityname-input {
width: 100%;
height: 100%;
color: #62b1ff;
border: none;
outline: none;
font-size: 16px;
}
}
.form-arrows {
width: 7px;
height: 10px;
margin: 0 8px;
}
.form-arrows-disabled {
// display: none;
}
.media-box {
flex-wrap: wrap;
width: 640px;
align-items: flex-start;
.media-item {
width: 100px;
position: relative;
// cursor: pointer;
flex-direction: column;
&:not(:nth-last-child(-n + 5)) {
margin-bottom: 30px;
}
transition: transform 0.3s;
&:hover {
.media-add-icon {
width: 20px;
height: 20px;
// transform: scale(1.1);
}
}
&.pitch {
.media-cover-bnt {
background: rgba(98, 177, 255, 1);
border: none;
color: #fff;
}
.media-item-box {
border: 1px solid rgba(98, 177, 255, 1);
}
}
.media-item-box {
width: 100px;
height: 100px;
overflow: hidden;
border-radius: 10px;
margin-bottom: 10px;
height: 100px;
border-radius: 10px;
background-color: rgba(246, 246, 246, 1);
border: 1px solid rgba(235, 235, 235, 1);
}
&:not(:nth-of-type(5n)) {
margin-right: 35px;
}
.input-file {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
cursor: pointer;
}
.media-add-icon,
.media-cross-icon {
width: 16px;
height: 16px;
}
.media-cross-icon {
position: absolute;
top: 0;
right: 0;
z-index: 100;
transform: translate(50%, -50%);
cursor: pointer;
}
.media-img {
width: 100px;
position: relative;
// filter: brightness(0.5);
}
.media-cover-bnt {
width: 100px;
height: 30px;
border-radius: 8px;
font-size: 14px;
border: 1px solid rgba(215, 215, 215, 1);
color: #aaa;
font-weight: 400;
cursor: pointer;
}
.media-play-icon {
width: 20px;
height: 20px;
position: absolute;
top: calc(50% - 5px);
left: 50%;
transform: translate(-50%, -50%);
}
}
}
.introduce-hint {
width: 640px;
font-size: 14px;
color: #aaa;
line-height: 22px;
margin-bottom: 10px;
}
.introduce-input,
.subject-input {
width: 640px;
border-radius: 10px;
border: 1px solid rgba(170, 170, 170, 1);
outline: none;
font-size: 16px;
resize: none;
overflow: hidden;
position: relative;
.residue {
position: absolute;
right: 8px;
bottom: 0;
color: #aaa;
font-size: 14px;
line-height: 30px;
height: 34px;
}
.el-textarea__inner {
height: 100%;
border: none;
}
}
.introduce-input {
// height: 200px;
.el-textarea {
height: 100%;
/deep/ .el-textarea__inner {
box-shadow: none;
height: 100%;
min-height: 200px !important;
font-size: 16px;
}
}
}
.subject-input {
height: 100px;
.el-textarea {
height: 100%;
width: 100%;
/deep/ .el-textarea__inner {
height: 100%;
}
}
}
}
.hint-box {
width: 640px;
height: 40px;
border-radius: 7px;
background-color: rgba(98, 177, 255, 0.0666666666666667);
color: #555;
font-size: 14px;
line-height: 24px;
margin-top: 41px;
margin-left: 48px;
margin-bottom: 60px;
.hint-icon {
width: 20px;
height: 20px;
margin-right: 10px;
}
}
.submit-btn-box {
width: 696px;
justify-content: flex-end;
.submit-btn-item {
width: 200px;
height: 50px;
border-radius: 40px;
font-size: 18px;
margin-left: 20px;
cursor: pointer;
&.save {
color: #333;
border: 1px solid rgba(215, 215, 215, 1);
&:hover {
border-color: #aaa;
}
}
&.submit {
background-color: rgba(98, 177, 255, 1);
font-weight: 650;
color: #fff;
&:hover {
background-color: rgba(88, 162, 230, 1);
}
}
}
}
.relation-input {
width: 640px;
height: 50px;
border-radius: 10px;
border: 1px solid rgba(170, 170, 170, 1);
overflow: hidden;
.el-input__inner {
border: none;
height: 100%;
}
}
.contact-hint {
width: 640px;
height: 40px;
background-color: rgba(98, 177, 255, 0.0666666666666667);
border-radius: 7px;
line-height: 28px;
color: rgb(59, 50, 50);
font-size: 14px;
margin-top: 42px;
margin-left: 48px;
.contact-icon {
width: 28px;
height: 28px;
margin: 0 4px 0 10px;
}
}
.wechat-btn {
width: 640px;
height: 70px;
border-radius: 10px;
font-size: 16px;
color: #000;
background-color: rgba(246, 246, 246, 1);
cursor: pointer;
position: relative;
input {
width: 100%;
height: 100%;
opacity: 0;
position: absolute;
top: 0;
left: 0;
cursor: pointer;
}
&:hover {
background-color: rgba(242, 242, 242, 1);
}
.wechat-icon {
width: 18px;
height: 18px;
margin: 0 6px;
}
}
.contact-QRcode-box {
width: 640px;
height: 120px;
border-radius: 10px;
border: 1px solid rgba(235, 235, 235, 1);
margin-bottom: 20px;
.contact-QRcode-img {
width: 100px;
height: 100px;
}
}
}
}
/deep/ .el-input__wrapper,
/deep/ .el-textarea__inner {
box-shadow: none;
}
}
.pop-mask {
position: fixed;
top: 0;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.698039215686274);
z-index: 1000;
}
.pop {
font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif;
z-index: 2;
background-color: #fff;
.pop-close {
width: 14px;
height: 14px;
position: absolute;
top: 20px;
right: 20px;
cursor: pointer;
}
&.succeed-box {
padding: 63px 0 68px;
background-image: url("@/assets/img/edit/succeed-pop-bj.svg");
background-color: #fff;
background-repeat: no-repeat;
background-position: bottom;
width: 460px;
flex-direction: column;
align-items: center;
z-index: 100;
position: relative;
.succeed-title {
.succeed-icon {
width: 24px;
height: 24px;
margin-right: 12px;
}
margin: 0 auto 110px;
color: #333;
font-weight: 650;
font-size: 24px;
}
.QRCode-box {
width: 130px;
height: 130px;
border-radius: 50%;
overflow: hidden;
margin-bottom: 30px;
background-color: #fff;
-moz-box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.211764705882353);
-webkit-box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.211764705882353);
box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.211764705882353);
.QRCode-img {
width: 120px;
height: 120px;
}
}
.succeed-hint {
color: #555;
font-size: 16px;
margin-bottom: 27px;
.bold {
color: #000;
font-weight: 650;
margin: 0 5px;
}
}
.personage-hint-list {
color: #555;
font-size: 14px;
.personage-hint-item {
text-align: center;
&:not(:last-of-type) {
margin-bottom: 11px;
}
}
}
.succeed-hint-list {
margin-bottom: 29px;
.succeed-hint-item {
font-size: 14px;
color: #555;
margin-bottom: 11px;
.succeed-hint-icon {
width: 13px;
height: 10px;
margin-right: 10px;
}
}
}
.succeed-examine {
color: #333;
font-size: 14px;
text-decoration: underline;
cursor: pointer;
}
}
&.type-pop-box {
width: 640px;
height: 181px;
background-color: rgba(255, 255, 255, 1);
border: 1px solid rgba(235, 235, 235, 1);
-moz-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.0784313725490196);
-webkit-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.0784313725490196);
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.0784313725490196);
padding: 30px;
position: absolute;
top: 58px;
.type-pop-list {
flex-wrap: wrap;
.type-pop-item {
width: 179px;
height: 50px;
background-color: rgba(246, 246, 246, 1);
border-radius: 10px;
font-weight: 400;
font-size: 16px;
color: #555555;
margin-bottom: 20px;
cursor: pointer;
&.pitch {
border: 1px solid rgba(98, 177, 255, 1);
color: #62b1ff;
background-color: #fff;
}
&:not(:nth-of-type(3n)) {
margin-right: 20px;
}
}
}
}
&.area-pop-box {
height: 695px;
left: 0;
background-color: rgba(255, 255, 255, 1);
overflow: hidden;
z-index: 101;
.area-pop-header {
font-weight: 650;
font-size: 20px;
color: #000000;
height: 98px;
padding-left: 30px;
padding-top: 40px;
border-bottom: 1px solid #ebebeb;
}
.area-box {
height: calc(100% - 98px);
.area-left {
background-color: rgba(246, 246, 246, 1);
.area-item {
width: 200px;
height: 70px;
display: flex;
font-family: "PingFangSC-Regular", "PingFang SC", sans-serif;
font-weight: 400;
font-style: normal;
font-size: 18px;
color: #555555;
padding-left: 48px;
cursor: pointer;
&:first-of-type {
padding-top: 16px;
height: 86px;
.dot {
top: calc(50% + 8px);
}
}
&.pitchpitch {
position: relative;
background-color: #fff;
color: #000 !important;
font-weight: 650 !important;
border: none !important;
.semicircle-outside {
position: absolute;
right: 0;
top: -20px;
width: 20px;
height: 20px;
background: #fff;
&::after {
content: "";
position: absolute;
right: 0;
top: 0;
width: 20px;
height: 20px;
border-radius: 0 0 100% 0;
background: #f6f6f6;
}
}
&::after {
content: "";
position: absolute;
right: 0;
bottom: -20px;
width: 20px;
height: 20px;
border-radius: 0 100% 0 0;
background: #f6f6f6;
}
&::before {
content: "";
position: absolute;
right: 0;
bottom: -20px;
width: 20px;
height: 20px;
background: #fff;
}
.dot {
display: block;
}
}
.dot {
display: none;
position: absolute;
top: 50%;
left: 20px;
transform: translateY(-50%);
width: 6px;
height: 18px;
border-radius: 4px;
background-color: rgba(255, 215, 82, 1);
}
}
}
}
.area-right {
margin-left: 40px;
margin-right: 6px;
overflow: auto;
padding-top: 16px;
.area-item {
height: 70px;
cursor: pointer;
margin-right: 5px;
color: #555;
font-size: 16px;
justify-content: space-between;
&:not(:last-of-type) {
border-bottom: 1px solid rgba(242, 242, 242, 1);
}
.area-item-name {
&:hover {
color: rgb(98, 177, 255);
}
}
&.pitchpitch {
color: #62b1ff;
.area-item-pitch {
display: block;
}
}
.area-item-pitch {
width: 14px;
height: 14px;
display: none;
}
}
}
}
&.target-area {
width: 900px;
.area-box {
position: relative;
&::after {
content: "";
position: absolute;
left: 0;
bottom: 40px;
width: 560px;
height: 1px;
background-color: #ebebeb;
}
}
.target-area-left {
overflow: auto;
margin-top: 25px;
margin-bottom: 40px;
margin-right: 20px;
position: relative;
.target-area-bottom {
height: 40px;
width: 100%;
background-color: red;
}
.target-area-item {
margin-bottom: 20px;
.target-area-head {
font-size: 18px;
color: #000;
font-weight: 650;
padding-left: 58px;
position: relative;
&::after {
content: "";
position: absolute;
top: 50%;
left: 30px;
transform: translateY(-50%);
width: 6px;
height: 18px;
border-radius: 4px;
background-color: rgba(255, 215, 82, 1);
}
}
.box {
padding-left: 58px;
margin-top: 22px;
flex-wrap: wrap;
.item {
color: #7f7f7f;
font-size: 14px;
background-color: rgba(246, 246, 246, 1);
border-radius: 10px;
height: 40px;
padding: 0 16px;
margin-right: 10px;
margin-bottom: 10px;
cursor: pointer;
&:hover {
background-color: #efefef;
}
&.pitch {
color: #62b1ff;
border: 1px solid rgba(98, 177, 255, 1);
background-color: #fff;
}
}
}
}
}
.target-area-right {
width: 340px;
height: 100%;
background-color: rgba(246, 246, 246, 1);
border-left: 1px solid #ebebeb;
padding-top: 25px;
padding-left: 30px;
padding-right: 30px;
flex-direction: column;
.target-area-title {
color: #000;
font-size: 16px;
font-weight: 650;
margin-bottom: 10px;
}
.target-area-hint {
font-weight: 400;
color: #7f7f7f;
font-size: 14px;
font-family: "PingFangSC-Regular", "PingFang SC", sans-serif;
.target-area-num {
font-weight: 650;
color: #000000;
margin: 0 5px;
}
}
.pitch-box {
flex-direction: column;
padding-top: 30px;
.pitch-box-item {
.pitch-box-index {
width: 20px;
height: 20px;
font-size: 14px;
color: #62b1ff;
border-radius: 50%;
border: 1px solid #62b1ff;
margin-right: 10px;
}
font-size: 14px;
color: #000;
margin-bottom: 20px;
.pitch-box-cross {
width: 12px;
height: 12px;
margin-left: 20px;
cursor: pointer;
}
}
}
.target-area-btn {
width: 280px;
height: 50px;
border-radius: 40px;
font-size: 18px;
color: #aaa;
font-weight: 650;
background-color: rgba(215, 215, 215, 1);
margin-bottom: 40px;
cursor: pointer;
&.pitch {
color: #fff;
background-color: rgba(98, 177, 255, 1);
}
}
}
}
}
.residential-area {
width: 640px;
height: 500px;
background-color: rgba(255, 255, 255, 1);
box-sizing: border-box;
border: 1px solid rgba(235, 235, 235, 1);
border-radius: 16px;
-moz-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.0784313725490196);
-webkit-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.0784313725490196);
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.0784313725490196);
z-index: 101;
padding: 10px 30px;
overflow: auto;
.residential-item {
height: 60px;
cursor: pointer;
.residential-dot {
width: 6px;
height: 6px;
background: #62b1ff;
border-radius: 50%;
margin-right: 47px;
}
.residential-text {
height: 100%;
color: #555;
font-size: 16px;
justify-content: space-between;
&.pitchpitch {
color: #62b1ff;
}
.btn {
width: 50px;
height: 100%;
background-color: #aaaaaa;
color: #fff;
font-size: 20px;
// border-radius: 0 10px 10px 0;
}
&.residential-input {
border: 1px solid rgba(170, 170, 170, 1);
border-radius: 10px;
height: 50px;
padding: 0 20px;
outline: none;
overflow: hidden;
input {
height: 100%;
// background-color: #50e3c2;
border: none;
outline: none;
font-size: 16px;
// color: #aaa;
}
}
}
&:not(:nth-last-child(-n + 2)) {
border-bottom: 1px solid rgba(242, 242, 242, 1);
}
}
}
.el-popover.popover-leasetime {
background-color: #50e3c2;
.dot {
width: 6px;
height: 6px;
border-radius: 50%;
background-color: #62b1ff;
margin: 0 47px 0 30px;
}
.icon {
width: 7px;
height: 10px;
}
.one-list {
padding: 10px 0;
.item {
height: 60px;
cursor: pointer;
&:not(:last-of-type) .content {
border-bottom: 1px solid rgba(242, 242, 242, 1);
}
.content {
height: 100%;
font-size: 16px;
color: #555555;
margin-right: 26px;
justify-content: space-between;
&:hover {
color: #62b1ff;
}
&.pitch {
color: #62b1ff;
}
}
}
}
.two-list {
padding: 10px 0;
align-items: flex-start;
.left {
.item {
height: 60px;
cursor: pointer;
font-size: 16px;
color: #555555;
&:hover {
color: #62b1ff;
}
&.pitch {
color: #62b1ff;
}
.dot {
margin-right: 27px;
}
.content {
width: 160px;
height: 40px;
padding: 0 20px;
&.pitch {
color: #62b1ff;
background-color: rgba(246, 246, 246, 1);
border-radius: 80px;
}
}
}
}
.right {
margin: 0 30px;
/deep/ .picker-leasetime {
display: block !important;
inset: 15px 0 0 265px !important;
box-shadow: none;
border: none;
.el-date-table th {
text-align: center;
}
.el-popper__arrow {
display: none;
}
.el-date-picker {
box-shadow: none;
border: none;
}
.el-picker-panel__icon-btn {
margin-left: 10px;
margin-right: 10px;
}
}
/deep/ .el-input {
// color: transparent;
// border-color: transparent;
display: none;
.el-input__wrapper {
box-shadow: none;
}
}
.item {
height: 60px;
cursor: pointer;
font-size: 16px;
color: #555555;
justify-content: space-between;
&:not(:last-of-type) {
border-bottom: 1px solid rgba(235, 235, 235, 1);
}
&:hover {
color: #62b1ff;
}
&.pitch {
color: #62b1ff;
.icom {
display: block;
}
}
.icom {
display: none;
width: 14px;
height: 14px;
}
}
}
}
}
// .el-picker.picker-leasetime {
// display: block;
// }
.rotate0 {
transform: rotate(0deg) !important;
}
</style>